# BMCLI Modbus Methodology

Use this reference only for an explicitly BMCLI-backed Modbus task. BMCLI is a
Modbus master/client; it does not emulate a slave/server.

## Resolve the contract and endpoint

Query runtime JSON Help for the exact `modbus`, `database`, and `bench import`
commands before composing an operation. Never guess the transport, COM/tty
path or host, serial format, Unit ID, EdgeX profile, device, resource, command,
or zero-based protocol address. Collect all missing endpoint facts in one
question before transmission.

Modbus commands intentionally require `--format=json` or `--format=jsonl`;
prefer one bounded JSON document unless consuming an event stream. Do not
request text or CSV and do not parse human-readable diagnostics.

For a one-off investigation, use raw `modbus read`, `write`, `file-record`, or
`fifo` operations. For a maintainable project, load a Linux Foundation EdgeX
Modbus Device Profile as a typed database resource and import the matching
EdgeX Device Definition into the bench. Prefer the resulting logical network,
resource, and command names over repeated numeric register expressions.

BMCLI uses zero-based protocol addresses, not human display references such as
40001. Confirm the vendor's address convention before converting it. Preserve
EdgeX value type, scale, offset, unit, byte/word order, readable/writable flags,
range, and mappings. Reject unsupported attributes instead of silently treating
them as holding registers.

## Choose bounded reads or polling

Use a bounded read for inspection and a daemon-owned poll job for Dashboard
curves, gauges, state cards, and alarm inputs. Polling retains bounded runtime
history and exposes freshness, quality, gaps, errors, and missed deadlines.
Choose an interval the device and serial line can sustain; UI refresh need not
equal acquisition rate. Stop only jobs created by the current workflow.

Writes are active device operations. Confirm the exact resource/address and
value, respect EdgeX access/range rules, and inspect readback only when the
resource supports it. A write-only (`W`) EdgeX resource deliberately has no
readback; a read/write (`RW`) resource is verified. A multi-resource command
can partially complete, so inspect `failed_resource`, `completed_operations`,
and `write_may_have_completed` before deciding whether any retry is safe.
For an EdgeX deviceCommand, use either the raw mapping key or its published
mapping label; BMCLI resolves an unambiguous label back to the raw value.
BMCLI never automatically retries a write because a timeout can leave
completion ambiguous. Do not add an application-layer write retry unless the device
operation is proven idempotent and the user accepts the risk.

## Dashboard boundary

BMCLI owns Modbus transport, transactions, EdgeX decoding, bounded polling, and
typed REST/SSE data. In a composed Web system, keep durable storage and
databases, authentication, uploads, reports, business rules, reverse proxying, and other
general Web concerns in surrounding services. A small read-only Dashboard may
connect directly to BMCLI Web; a larger system should treat it as one protocol
service among several. Always show stale/bad quality and communication errors,
not only the last numeric value.

For curves, consume history with its `after` sequence cursor and resume SSE
with `Last-Event-ID`. Process every event in order; if BMCLI reports an expired
cursor or emits a `gap` event, make the discontinuity visible rather than
drawing it as continuous data. The daemon serializes poll, CLI, and Web
transactions through one persistent session per physical Modbus endpoint.
Do not open the same COM/tty endpoint independently in another process while
BMCLI owns it.
