Skip to content

Readings

Both wire protocols decode into the same frozen, slots=True dataclasses. That parity is the whole point of the dual-protocol seam — a caller asks for poll() and gets a Reading regardless of whether the active protocol is xBPI or SBI. See Design §4 and §7.

This page surveys the public types returned by the Balance facade and notes which fields are protocol-specific (i.e. None on one side).

Reading

Reading is the canonical weight-reading shape. xBPI 0x1E decodes a measurement-frame body; SBI's + 0.00 g \r\n autoprint or ESC P reply parses the same fields.

Field Type Notes
value float \| None None on the off-scale sentinel. The measurement body alone cannot disambiguate overload from underload — call Balance.status() for that.
unit Unit Decoded from the xBPI unit byte or the SBI trailing token (g, kg, etc.). Unit.UNKNOWN preserves unrecognised values.
sign Sign POSITIVE / NEGATIVE / ZERO / UNKNOWN.
stable bool From the universal measurement-frame flag bit 0x40 — portable across MSE/WZA/BCE without a separate status round-trip.
overload bool xBPI: from the off-scale sentinel + sign byte. SBI: parsed from +H / -H notation when present.
underload bool Same source as overload.
decimals int \| None xBPI: byte[5] >> 4. SBI: parsed from the formatting in the line. None when not derivable.
sequence int \| None xBPI status-block sequence counter; None on SBI (no equivalent signal).
status_flags Mapping[str, bool] Protocol-specific flags: "stable", "off_scale", plus "isocal_due" / "adc_trusted" on xBPI long frames.
protocol ProtocolKind XBPI or SBI. Lets callers cross-check the source.
received_at datetime Wall-clock receive time. For logs.
monotonic_ns int Monotonic clock — for jitter analysis.
raw bytes Original frame or line. SBI lines are stored as raw bytes (not str) for byte-exact replay.

Reading implements __format__ so f"{r:.4f}" works:

reading = await bal.poll()
print(f"{reading:.3f} {reading.unit}")  # "199.995 g"

Off-scale readings (value is None) format as "None" for any non-empty numeric spec rather than raising — settling windows during a tare or zero commonly emit None values and an f-string crash there is a surprising failure mode.

Reading.as_dict() flattens to a row-shaped dict for tabular sinks. Booleans render as 0/1 so SQLite picks INTEGER affinity and CSV/JSONL round-trip cleanly.

BalanceStatus

BalanceStatus is the status-block snapshot from xBPI 0x30 or the SBI equivalent.

Field Type Notes
stable bool \| None None when the protocol can't surface stability separately from the measurement frame.
state BalanceState STABLE / UNSTABLE / OVERLOAD / UNDERLOAD / OFF / UNKNOWN.
isocal_due bool \| None MSE-only signal; None on WZA/BCE/SBI.
adc_trusted bool \| None MSE-only; None on other families.
sequence int \| None xBPI sequence counter; None on SBI.
raw_state int \| str \| None Raw state byte for cross-checking against protocol.md §8.
raw_status int \| str \| None Raw status byte.
raw bytes \| str Whole status block or line, untouched.

DeviceInfo

DeviceInfo is the identity snapshot produced by Balance.identify().

Field Type Notes
manufacturer str \| None xBPI 0x07.
model str xBPI 0x02 or SBI x1_. Drives family classification.
serial str \| None xBPI 0x05 (OEM text) or SBI x3_.
factory_number str \| bytes \| None xBPI 0x01 raw blob; preserved as bytes when not ASCII.
software str \| None xBPI 0x00 / SBI x2_.
firmware FirmwareVersion \| None Parsed from software.
family BalanceFamily CUBIS / OEM_WEIGH_CELL / BASIC_LAB / UNKNOWN.
protocol ProtocolKind The protocol the session opened with.
capacity Quantity \| None xBPI 0x0C when available.
increment Quantity \| None xBPI 0x0D.
sbn int \| None xBPI bus address.
serial_settings SerialSettings Active serial config.
capabilities Capability Bitmap of currently SUPPORTED capabilities.
probe_report Mapping[Capability, ProbeOutcome] Full availability state per capability — see Balances.
temperature_sensor_indices tuple[int, ...] \| None None until Balance.discover_temperature_sensors() has run. Some firmwares expose sparse indices (0, 1, 3 on MSE1203S, with the 7f ff ff ff sentinel at index 2).

Other public types

Type Returned by Notes
Quantity Balance.capacity(), Balance.increment() value: float, unit: Unit.
TemperatureReading Balance.temperature(sensor) celsius is None when the sensor index returns the 7f ff ff ff sentinel.
ParameterEntry Balance.read_parameter(index) Raw (current, max, raw). Typed accessors decode through the registry.
CalRecord Balance.last_cal_record() has_metadata distinguishes "never recorded" (post cold boot) from "valid record".
ProbeOutcome per-capability entry on DeviceInfo.probe_report Availability + ProbeSource + timestamp + human-readable detail.
Sample recorder yield Wraps a Reading with device name, requested timestamp, elapsed time, error. See Logging.

Enums

Enum Module Values
Unit registry/units.py G, KG, MG, LB, OZ, CT, N, ... plus UNKNOWN.
Sign registry/units.py POSITIVE, NEGATIVE, ZERO, UNKNOWN.
BalanceState devices/models.py STABLE, UNSTABLE, OVERLOAD, UNDERLOAD, OFF, UNKNOWN.
ProtocolKind protocol/base.py XBPI, SBI, AUTO.
BalanceFamily devices/kind.py CUBIS, OEM_WEIGH_CELL, BASIC_LAB, UNKNOWN.
Capability devices/capability.py Flag bitmap — see Balances.
Availability devices/capability.py UNKNOWN, SUPPORTED, UNSUPPORTED, INAPPLICABLE.
ProbeSource devices/capability.py FAMILY_TABLE, TARGETED_PROBE, LIVE_CALL, USER_OVERRIDE.
SafetyTier devices/capability.py READ_ONLY, STATEFUL, PERSISTENT, DANGEROUS.

Every enum that decodes protocol data carries an UNKNOWN member or otherwise preserves raw values so the library stays forward-compatible with firmware revisions we have not yet captured.

See also

  • BalancesBalance facade.
  • Commands — what produces these readings.
  • StreamingSample (wraps Reading) and AcquisitionSummary.
  • Wire protocol — frame layouts behind these decoded shapes.
  • Design §7 — full type catalogue.