Skip to content

Rewrite Mettler Toledo SICS scale backend with I0 command discovery, protocol simulator, and tests#979

Open
BioCam wants to merge 49 commits intoPyLabRobot:mainfrom
BioCam:create-mettler-toledo-SICS-scale-sytem
Open

Rewrite Mettler Toledo SICS scale backend with I0 command discovery, protocol simulator, and tests#979
BioCam wants to merge 49 commits intoPyLabRobot:mainfrom
BioCam:create-mettler-toledo-SICS-scale-sytem

Conversation

@BioCam
Copy link
Copy Markdown
Collaborator

@BioCam BioCam commented Mar 30, 2026

Hi everyone,

PyLabRobot currently only has one programmatically controllable scale integrated - the "Mettler Toledo scale".

But in reality this is an oversimplification: Mettler Toledo manufactures a whole array of programmable scales, known as "Automated Precision Weighing Modules". The one we typically refer to is the WX series APW Module, which is the one sold in Hamilton's Liquid Verification Kit.

However, this scale is only one of many that uses the Mettler Toledo Standard Interface Command Set (MT-SICS), a serial protocol shared across Mettler Toledo's Automated Precision Weigh Modules (WXS, WMS, WX series). These devices range from 0.1 mg analytical balances to multi-kilogram industrial weigh modules, but they all speak the same serial command protocol.

This PR rewrites the PLR backend based on the MT-SICS spec and hardware validation on a physical WXS205SDU WXA-Bridge (firmware: 1.10). A single backend now handles any MT-SICS device - during .setup(), it queries the device to discover exactly which commands that specific model supports, and gates methods accordingly. No hardcoded model assumptions.


The Problems

  • No command discovery: The old backend hardcoded which commands to use. Commands like ZC and TC were sent to devices that don't support them, causing silent failures (ES syntax errors with a mystery comment "For some reason, this will always return a syntax error").
  • Broken response parsing: Responses were split on whitespace, breaking on quoted strings with spaces (e.g. I2 response). DAT/TIM returned only the first field.
  • No multi-response handling: send_command returned a single line. Multi-line commands (I0, I50, M27) could not be used.
  • No simulator: Testing required a physical device. The ScaleChatterboxBackend returned a fixed dummy weight with no physics.
  • No cleanup on interrupt: Pressing the Jupyter stop button or Ctrl+C left stale data in the serial buffer, corrupting the next command.
  • Missing methods: Only ~10 commands implemented out of the 194 in the MT-SICS spec.

PR Content / Solutions

Core architecture:

  • I0 command discovery at setup. Methods decorated with @requires_mt_sics_command are gated at runtime against the device's actual command list.
  • shlex.split parsing with MettlerToledoResponse dataclass replacing raw List[str].
  • Multi-response send_command reads until status A, handling B-status continuation lines.
  • Interrupt-safe: on interrupt, sends C (cancel) if available, flushes the buffer. Never clears zero/tare state.
  • Firmware version tracking in confirmed_firmware_versions.py with setup-time warnings for untested versions.

Simulator (evolution of the Chatterbox pattern):

  • MettlerToledoSICSSimulator inherits from the backend, overrides send_command with mock responses. Where a Chatterbox returns fixed dummy values, the Simulator maintains physics state (weight, tare, temperature) as settable instance variables. All 55 commands handled.

Coverage:

  • 54 active commands (49 of the 62 on WXS205SDU), 27 write/physical commands commented out with safety docs.
  • 44 tests covering parsing, error handling, physics simulation, command gating, and workflows.
  • Protocol docs (protocol.md) and full 194-command reference (mt_sics_commands.md).
  • Tutorial notebook with simulation/execution toggle and request_supported_methods() discovery.
  • Backward-compatible import shims for old paths (removal 2026-09).

Future Work for MT-SICS

This PR covers the WXS205SDU thoroughly. For other MT-SICS devices:

  • SIR/SR streaming: on the device but needs async iterator architecture.
  • E01/E02/E03 error monitoring and SIX1 (gross+net+tare): not on WXS205SDU, need other hardware.
  • ~113 remaining spec commands: require physical access to devices that support them. Pattern for adding new commands documented in mt_sics_commands.md.

Happy to discuss any of the design decisions - especially around the Simulator pattern and interrupt safety, as those could be useful templates for other PLR device drivers.

BioCam and others added 30 commits March 27, 2026 18:10
… validation, device discovery, and chatterbox simulator
A valid response arriving just past the timeout threshold was being
discarded because the timeout check preceded the non-empty check.
Sleep moved to only occur between empty reads.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…n, gate execution-only code; round chatterbox to 0.01mg
… measure_temperature, robust stop, rename chatterbox to simulator, remove deprecated methods
@BioCam BioCam requested a review from rickwierenga March 30, 2026 23:31
@BioCam
Copy link
Copy Markdown
Collaborator Author

BioCam commented Mar 30, 2026

Note: I would like to rename the backend to MTSICSDriver in PLR v1.0.0-beta to account for its real scope but didn't want to introduce any breaking changes in the current, soon-to-be legacy PLR :)

Comment thread pylabrobot/scales/mettler_toledo/confirmed_firmware_versions.py
Comment thread pylabrobot/scales/mettler_toledo/simulator.py Outdated
BioCam and others added 5 commits March 31, 2026 11:00
- Delete MettlerToledoSICSSimulator and its tests (keep generic ScaleSimulator)
- Update tutorial notebook to use MettlerToledoWXS205SDUBackend directly
- Remove simulation/execution toggle and all simulator conditionals
- Clean up simulator references in docs and mt_sics_commands.md
- Change deprecation dates to "remove in v1"

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…mand

Move the supported-command gate into send_command itself. Delete the
decorator, the registry, request_supported_methods, and all hasattr
checks. _supported_commands is initialized as an empty set in __init__
so the check is skipped during setup() and enforced after I0 discovery.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@rickwierenga rickwierenga force-pushed the create-mettler-toledo-SICS-scale-sytem branch from 0613d5a to 1fdeef0 Compare April 9, 2026 05:40
rickwierenga and others added 4 commits April 8, 2026 22:40
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The chatterbox module re-exports ScaleSimulator as ScaleChatterboxBackend,
which causes a docutils warning when autosummary processes it with :recursive:.
Reference simulator.ScaleSimulator directly instead.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants