Live data in dashboards
A dashboard shows plant data by reading parameter values and changes equipment by writing them. It never sends Modbus addresses: it names parameters by ID, and the parameter’s source and value type decide which register is read and how its bytes become a value. Moving a value to another register changes the parameter, not every dashboard that shows it.
@overvis/hmi-workspace-ui provides the live-value hooks on top of the host’s API client, and the
same hooks serve Setup’s live values. Dashboards, Setup, the assistant, and integrations all read
and write through the same procedures, described in
Live value procedures. For the steps, see
Show live values in a dashboard and
Write parameter values from a dashboard. The components
for a dashboard made for one device model are in
Device dashboard components, and the device API hooks call
an MC252 or MC261L’s own API without parameters.
Live-value API
Section titled “Live-value API”Every loaded dashboard is wrapped in one ParameterValuesProvider. It makes no request until a
useParameterValues call registers demand.
| API | Responsibility |
|---|---|
useParameterValues | Register demand, cadence, aggregate status, and Retry |
useParameterValue | Subscribe to one value state; it creates no network demand |
useParameterValueActions | Batch writes and perform explicit refreshes |
useParameterValueHistory | Keep recent numeric samples for this mount; it never queries stored readings |
useParameterValueHistories | The same for a list of parameters, in list order, for a chart of several lines |
useStoredParameterHistory | Load stored readings over a window |
useParameterMetadata | Names, units, and other metadata of parameters |
ParameterDiagnostics | Show grouped problems with the corrective action, Setup links, and Retry |
ParameterValueDisplay | Show one value with its loading, unavailable, and stale presentation |
ParameterValuesProvider | Isolate the scheduling of a complex part of the dashboard |
useParameterValues takes parameterIds and intervalMs; an empty list registers no demand. The
parameters of one call form a cohort. A parameter requested by several cohorts is read once, at the
fastest cadence, and results arrive progressively as the device answers. A nested
ParameterValuesProvider has its own schedule and demand.
Choose a cadence
Section titled “Choose a cadence”For plant HMIs, an interval of 1 to 5 seconds suits most processes, depending on how fast the process moves and how loaded the endpoint is. Put slow-changing identity and settings values in a slower cohort than the fast readings. The provider deduplicates IDs, batches what is due, pauses hidden tabs, and backs off per parameter, so a dashboard declares what it needs instead of running a timer per tile.
Value states
Section titled “Value states”useParameterValue(id) returns one of:
idle: no demand, or the demand is disabled.loading: requested, with no value or failure yet.value:snapshot,freshness(freshorstale),refreshing,saving, and an optional current diagnosis.error: a failure before any value arrived.
A timeout or a lost connection says nothing about the value itself, so a failed refresh keeps the
last value, marks it stale, and adds the diagnosis. Only a Reading unavailable answer, where
the device reports that it has no value, replaces the last value.
snapshot.receivedAt is when the device was read, in milliseconds. A reading shared with another
request keeps its original time, so a repeated delivery never looks newly read. formatAppDateTime
formats it as YYYY-MM-DD HH:mm:ss in the browser time zone.
useParameterValues also returns an aggregate state: idle, loading, partial, ready,
degraded, error, or paused. It counts states; it is not a device diagnosis. All requested
parameters failing does not prove that the device is offline.
Reading typed values
Section titled “Reading typed values”parameterValueNumber(state)andparameterValueBoolean(state)return the typed value, ornullfor an absent, pending, failed, or differently typed state. They never parse the localized display string.parameterValueFlag(state)reads a device flag that may arrive as a boolean or a numeric register: zero isfalse, nonzero istrue.parameterValueComparable(state)is the value a numeric condition compares: a number, or a boolean as 0 or 1.parameterValueTime(state)reads a date-time value, such as a maintenance date, as epoch milliseconds.
isCurrentParameterValue(state) holds when a value is fresh and nothing has failed since it was
read. Every reader above takes { current: true } to return null for a kept value, as in
parameterValueNumber(state, { current: true }). isParameterValuePending(state) holds until the
first value or failure arrives. parameterStatesStaleSince(states) is when the oldest kept value
was read, for a “stale since” note, or null.
Parameter metadata
Section titled “Parameter metadata”useParameterMetadata(parameterIds, locale) returns a lookup by ID: loading, missing
(deleted), error, or ready with parameter (name and unit in locale, branchId,
valueType, writable, and recorded). Names and units edited in Setup then apply without
editing the dashboard. parameterMetadata(parameter, locale) builds the same object from a
parameter.get result. isParameterRecorded(parameter) is true when the parameter’s readings are
stored: it has a background reading period, or an MC252 program records it on the device.
Diagnostics
Section titled “Diagnostics”View-only members can read live values. Writing requires the Operator role or higher. A permission problem is an access failure, not a device error, and an API request deadline is not a device timeout. Diagnoses come from the structured error code and reason; the runtime error codes list them all.
| Diagnosis | Examples |
|---|---|
| Endpoint | Missing or disabled endpoint, connection refused or lost |
| Device timeout | The device did not answer in time; gateway exception 10 or 11 |
| Configuration | Unknown or disabled parameter, invalid source or value type |
| Protocol | Other Modbus exceptions, malformed or mismatched response |
| Capacity | The service is busy or not ready |
| Permission | The workspace role cannot read or write live values |
| Unavailable | The device reports no value or timestamp for the reading |
| Internal | Unexpected request failure that has no safer diagnosis |
demand.diagnostics has one entry per problem on a device, not per register: when one device fails
several registers the same way, such as a unit behind a gateway that stopped answering, the entry
lists every affected parameter in parameterIds, and requests holds each failed request.
Different endpoints, units, or Modbus exception codes stay separate entries.
combineParameterValuesDemands groups the diagnostics of several cohorts the same way.
ParameterDiagnostics shows each entry as one NoticeCard. Its title names the device when it is
known, such as Unit 7 on Campus North is not answering, and below it says what to check: for a
device timeout, the device’s power, wiring, Modbus unit ID, and the serial settings behind a
gateway. Technical details list the error, the number of affected parameters, and the
addresses, such as hold 100-102, 140. With workspaceId, it shows endpoint names. Endpoint and
device-timeout notices are warnings; configuration, protocol, and internal faults are errors; an
unavailable value, a busy service, and missing read permission are information. With onRetry,
Retry is the main button, unless a Setup change fixes the problem: editors then get the
endpoint, parameter, or dashboard settings link first.
Reads and request load
Section titled “Reads and request load”The provider reads values in repeated requests; there is no server push of values.
- Hidden tabs pause reading and refresh immediately when shown again.
enabled: falsepauses a demand; values already read stay available.- Endpoint failures, timeouts, and temporary capacity failures back off automatically per parameter. Configuration failures are retried slowly, so a Setup correction is eventually picked up. Permission failures stop until access changes.
retry()clears the backoff of that demand and reads at once.
One failing parameter does not slow its healthy neighbors. Requests for the same parameter share one device read, and a reading taken a moment earlier can answer another request, so ten screens watching one temperature cost one device read. Writes and relevant configuration changes discard such shared readings. Each device read is stored once in the parameter’s history, also when it was requested by a live view; a shared reading adds nothing.
Writes
Section titled “Writes”writeValues from useParameterValueActions() sends several writes in one request:
const { writeValues } = useParameterValueActions();
const output = await writeValues({ items: [ { paramId: setpointId, value: "21.5" }, { paramId: hysteresisId, value: "1.0" }, ],});isParameterValueWritable(parameter) checks parameter metadata: it rejects disabled parameters,
calculated sources, constants without write access, and read-only Modbus sources. Workspace
permissions and server checks apply in addition.
A write acknowledges, it does not observe. The result says which bytes were sent, not what the
device now holds: a device can clamp a value, a command register can clear itself after it runs,
and some devices report a command’s effect in another register. So a later read can differ without
the write having failed, and an acknowledgement does not prove a physical result; show the
equipment’s own feedback parameter where it has one. While a write is in flight, the written
parameters are marked saving. After it settles, the provider reads them again, and until that
read completes, the last observed value stays on screen as stale. A write timeout is ambiguous,
because the device may have applied it, so that read matters most.
Writes are not a transaction. output.results[paramId] holds each write’s own result, and a failed
write does not undo the others, because rolling back would undo real device writes. Apply the
successful values, show the failed ones with their errors, and check per-item results rather than
only whether the call threw. Writes come from the open dashboard: after it closes, a request
already sent completes, and nothing more is sent.
writeValues(input, { writeOnly: [passwordId] })writes a parameter that is never read back, such as a device’s unlock password.runSequence(sequence)runs an ordered sequence of writes after any other sequence on the page has finished, so the steps of two sequences never interleave.
Stored history
Section titled “Stored history”useStoredParameterHistory({ workspaceId, parameterIds, window, cadence, refetchMs, enabled })
loads stored readings over the window milliseconds that end at each load, as closed buckets of
cadence (1m, 15m, 1h, …): averages for num parameters, latest values for others. Only
numbers are returned: text, date-time, and geo parameters have an empty series. It loads again
every refetchMs, and not at all while enabled is false.
series(parameterId) returns status (loading, ready, empty, or error), points
({ at, value } at each bucket’s start), and recorded (whether the parameter’s readings are
stored at all). The open bucket at the end of the window is not included.
withLiveTail(points, live, cadenceMs) appends the live values from useParameterValueHistory
received after the last bucket, and liveTailPoints(window, fastestRefreshMs) is the maxPoints
that holds a whole open bucket. ParameterTrendChart and Sparkline draw these points directly.
These points describe a trend, not the last reading: a num point is its bucket’s average, which
may never have been read. For actual stored readings with the time each was read, query
readings.segments through trpc.
storedHistoryWindows has the usual 1h, 24h, and 7d windows with their cadence and reload
interval. useStoredWindowExtremes({ workspaceId, parameterId, sourceValueType, window, live })
returns the minimum and maximum over a window that ends now.
useDistinctParameterNames(parameters, locale) names parameters shown together, adding the branch
where two names would read the same.
API client
Section titled “API client”trpc from the package root is the host’s typed React Query client. Do not create a second one.
import { trpc } from "@overvis/hmi-workspace-ui";Typical direct calls are parameter.listInventory for a picker, report procedures for embedded
reports, or dashboard-specific queries. Entity procedures, such as parameter reads and writes, take
entity IDs; workspace procedures, such as parameter.listInventory, take workspaceId from the
dashboard props. The dashboard’s configuration is already in its props,
and the workspace is available through useWorkspace(). Queries are considered fresh for 30
seconds and are not retried automatically. When the workspace’s setup changes, the host refreshes
the queries made through trpc, including the dashboard’s own configuration.
endpoint.watchStatus reports endpoint connection state, separately from parameter values: a
connected endpoint can still have parameters that fail.
trpc.endpoint.watchStatus.useSubscription( { workspaceId: props.workspaceId }, { onData: (event) => applyEndpointStatus(event) },);The first event is a snapshot of every endpoint, followed by one change event (endpointId,
status) per change. status is null until the endpoint has reported. The event types
(EndpointStatusEvent, EndpointStatus) come from @overvis/hmi-shared/endpoint.
Labeled readings
Section titled “Labeled readings”ParameterMetric shows a value state with a caller-supplied label, optional icon, engineering
unit, and locale; compact is the dense variant for summaries. ParameterReading shows just
the value and unit for tables, settings rows, and map popups: as the parameter formats it, or at
exactly fractionDigits places, with an optional unavailable text such as ”—” and a
skeletonClassName sized to the place it fills. Both keep the loading, unavailable, and stale
presentation of ParameterValueDisplay.
When Setup and a dashboard disagree
Section titled “When Setup and a dashboard disagree”Setup’s live values and dashboards read through the same provider and procedures. When a value
works in Setup but not on a dashboard, the difference is in the dashboard: other parameter IDs,
another principal (a workspace API key of another workspace gets param_not_found), or a dashboard
that hides per-parameter errors. See Troubleshooting.