Agilent plateloc serial control, target v1b1#1040
Open
alexjamesgodfrey wants to merge 6 commits into
Open
Conversation
Comment on lines
+27
to
+38
| DEFAULT_PLATELOC_COMMANDS: Mapping[str, str] = { | ||
| "set_sealing_temperature": "ST", | ||
| "set_sealing_time": "SS", | ||
| "move_stage_out": "SO", | ||
| "move_stage_in": "SI", | ||
| "start_cycle": "GO", | ||
| "stop_cycle": "AC", | ||
| "apply_seal": "AS", | ||
| "clear_error": "CL", | ||
| "check_cycle_complete": "CC", | ||
| } | ||
|
|
Member
There was a problem hiding this comment.
does this need to be parameterized? does it change between machines? why not have the methods send the command directly?
Comment on lines
+134
to
+135
| serial_cls=Serial, | ||
| ) -> None: |
Member
There was a problem hiding this comment.
why does serial_cls need to be parameterized?
Comment on lines
+198
to
+199
| if hasattr(self.io, "reset_input_buffer"): | ||
| await self.io.reset_input_buffer() |
Comment on lines
+398
to
+408
| async def set_sealing_temperature(self, temperature: float): | ||
| return await self.driver.set_sealing_temperature(temperature) | ||
|
|
||
| async def set_sealing_time(self, duration: float): | ||
| return await self.driver.set_sealing_time(duration) | ||
|
|
||
| def status_snapshot(self, cycle_complete: Optional[bool] = None) -> PlateLocStatus: | ||
| return self.driver.status_snapshot(cycle_complete=cycle_complete) | ||
|
|
||
| async def request_status(self, query_cycle_complete: bool = True) -> PlateLocStatus: | ||
| return await self.driver.request_status(query_cycle_complete=query_cycle_complete) |
Member
There was a problem hiding this comment.
the pattern in v1b1 is to just have the driver/capabilities have these methods rather than duplicating them on the Device layer
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Member
|
converted the hello world from a markdown to notebook so people can easily just download and run it! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR adds v1b1-style support for the Agilent PlateLoc Thermal Microplate Sealer through PLR's standard
Sealercapability plus PlateLoc-specific setpoint/status helpers.The implementation talks directly to the PlateLoc over RS-232 using PLR's
pylabrobot.io.Serialwrapper aroundpyserial. It does not require Agilent ActiveX, VWorks, a vendor HTTP server, Windows-only binaries, or bundled native code. Users install the optional PLR serial extra (pylabrobot[serial]) when they want to use the hardware.What changed
pylabrobot.agilent.PlateLoc, aDeviceexposingsealeras the user-facing capability.PlateLocDriver, a direct serial driver for PlateLoc firmware commands.PlateLocSealerBackend, mapping PLR sealer operations to direct hardware commands.set_sealing_temperature()andset_sealing_time()on bothPlateLocandPlateLocDriver.PlateLocStatusplusstatus_snapshot()andrequest_status()for the target temperature, sealing time, stage position, cycle-complete state, and last serial response.PlateLocSerialProfile, so serial settings and command codes stay configurable without changing the PLR frontend.docs/user_guide/agilent/plateloc/hello-world.mdand linked PlateLoc from the Agilent docs index and sealer docs.Protocol shape
The live instrument tested here uses
19200 8N1and carriage-return-terminated ASCII frames:ST 0.{temperature_celsius:03d}\rSS 0.{seconds_x10:02d}\rGO 00\rAC 00\rSO 00\rSI 00\rAS 00\rCL 00\rCC 00\rThe setpoint payloads use the firmware's fractional convention:
ST 0.175\rmeans 175 C,ST 0.030\rmeans 30 C, andSS 0.12\rmeans 1.2 s. Acknowledgements such asSTAK\r,SOAK\r, andSIAK\rare accepted. Negative acknowledgements such asSTNK(Desired Temperature is Out of Range)are raised asPlateLocError.request_status()issues the liveCC 00\rcycle-complete query and combines that result with PLR's best-known local state. The decoded direct protocol does not expose actual block-temperature reads or stored-time reads, so target temperature and sealing time are the last successfully written setpoints.Agilent documents the PlateLoc as supporting robotic integration with an RS-232 serial port and ActiveX control; this PR keeps PLR on the serial side and avoids taking a runtime dependency on the ActiveX layer. See the official PlateLoc ActiveX user guide for the vendor automation context.
Example
Custom serial settings or command codes can be supplied through
PlateLocSerialProfilewhile the frontend remains the same.Validation
python3 -m unittest pylabrobot.agilent.plateloc.plateloc_testsuvx ruff==0.15.4 check pylabrobot/agilent/plateloc pylabrobot/agilent/__init__.py