Skip to content

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

Open
BioCam wants to merge 41 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 41 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 :)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why does this need its own file?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In theory it doesn't, but I wanted to highlight how PLR is currently not systematically capturing what firmware versions for integrated devices are supported.
It could live in the backend (future driver).
But for discoverability it might still be worth considering adding it as a separate file -> if a backend/driver folder doesn't have a file with the PLR-standardised name, we know we are not tracking supported firmware versions.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is a firmware level simulator useful?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because it enables complete in silico runs of the actual device, rather than an abstract class above it.

This is very useful for running the exact commands and responses e.g. in a closed-loop experimental systems that might depend on specific responses.
With this specific one we can after (1) generate synthetic data for the simulation, (2) run e.g. a Bayesian optimisation process for liquid transfer optimisation completely in silico while generating and testing real hardware/firmware responses, minimising the risk of something breaking midway in a multi-day experiment.

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