Conversation
c058128 to
27272fe
Compare
Codecov Report❌ Patch coverage is 📢 Thoughts on this report? Let us know! |
ead6d60 to
1880347
Compare
1880347 to
9385ee8
Compare
ca71022 to
ee406b9
Compare
e352932 to
67eba1b
Compare
There was a problem hiding this comment.
Pull request overview
This PR migrates the beamline checking system from the old client-side bl_checks and bl_conditions modules to a new server-side beamline states architecture. This change addresses issue #406 by moving beamline state monitoring from the iPython client to the scan server, providing a foundation for the upcoming Actors feature.
Changes:
- Replaces
bl_checksandbl_conditionswith a newbl_statesmodule featuringBeamlineStatebase class and derived state types (ShutterState, DeviceWithinLimitsState) - Adds
BeamlineStateManagerclasses on both client and server sides to manage state lifecycle and synchronization via Redis - Introduces new message types (
BeamlineStateMessage,BeamlineStateConfig,AvailableBeamlineStatesMessage) and endpoints for state communication
Reviewed changes
Copilot reviewed 12 out of 12 changed files in this pull request and generated 17 comments.
Show a summary per file
| File | Description |
|---|---|
| bec_lib/bec_lib/bl_states.py | New module implementing BeamlineState classes and client-side BeamlineStateManager for state registration and management |
| bec_lib/bec_lib/messages.py | Adds BeamlineStateMessage, BeamlineStateConfig, and AvailableBeamlineStatesMessage for state communication |
| bec_lib/bec_lib/endpoints.py | Adds beamline_state() and available_beamline_states() endpoints for state messaging |
| bec_lib/bec_lib/client.py | Integrates BeamlineStateManager into BECClient, replacing the old bl_checks |
| bec_lib/bec_lib/bl_checks.py | Removed - functionality migrated to bl_states |
| bec_lib/bec_lib/bl_conditions.py | Removed - functionality migrated to bl_states |
| bec_server/bec_server/scan_server/beamline_state_manager.py | Server-side BeamlineStateManager that listens for state updates and instantiates state monitors |
| bec_server/bec_server/scan_server/scan_server.py | Integrates server-side BeamlineStateManager into ScanServer |
| bec_lib/tests/test_beamline_conditions.py | Comprehensive tests for BeamlineState classes and BeamlineStateManager |
| bec_lib/tests/test_bl_conditions.py | Removed - old tests for removed modules |
| bec_lib/tests/test_beamline_checks.py | Removed - old tests for removed modules |
| bec_server/tests/tests_scan_server/test_beamline_state_manager.py | Tests for server-side BeamlineStateManager state synchronization |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
b129dde to
995dcf5
Compare
995dcf5 to
45311ce
Compare
bec_lib/bec_lib/bl_states.py
Outdated
| raise RuntimeError( | ||
| f"Device {device} not found in device manager. Cannot add state {state.name}." | ||
| ) | ||
| if signal is not None: |
There was a problem hiding this comment.
I tried adding a new state following the code below. For both of them, the syntax raises within this check. I think we should inpractice accept both syntax forms? The last syntax worked.
# First attemp, raises
shutter_state = ShutterState(name="shutter")
shutter_state.update_parameters(device=dev.samx, signal=dev.samx.motor_is_moving)
## Second attempt, raises
shutter_state = ShutterState(name="shutter")
shutter_state.update_parameters(device=dev.samx.name, signal=dev.samx.motor_is_moving.name)
##Final attempt, which worked
shutter_state = ShutterState(name="shutter")
shutter_state.update_parameters(device=dev.samx, signal="samx_motor_is_moving")
bec_lib/bec_lib/bl_states.py
Outdated
| """ | ||
|
|
||
| def evaluate(self, msg: messages.DeviceMessage, **kwargs) -> messages.BeamlineStateMessage: | ||
| val = msg.signals.get(self.signal, {}).get("value", "").lower() |
There was a problem hiding this comment.
There was a problem hiding this comment.
depending on how the device is integrated, you may need a custom beamline state. I don't think we should try and generalize the beamline state if the underlying devices are not generalized. The current implementation is a demo implementation for a shutter device. We have to see what the device reports in real operation and adjust it accordingly but I would be in favor of implementing the shutter devices consistently, rather than trying to patch it here.
Regarding the second part of your question, yes, the signal selection can be removed.
bec_lib/bec_lib/bl_states.py
Outdated
| ) | ||
| return params | ||
|
|
||
| def update_parameters(self, **kwargs) -> None: |
There was a problem hiding this comment.
If I am missing a parameter, then I will only know about this when I add the state to the beamline manager because this checked in configure.
It might be nice to maybe have a way to inspect this beforehands. One option is that update_parameters requires all needed parameters. As parameters may change in the future.
A valid alternative could be to add a method init_parameter which requires all input parameters to make it a valid state. Could be an abstractmethod in the ABC, which is required to be implemented similar to evaluate.
bec_lib/bec_lib/bl_states.py
Outdated
| ) | ||
|
|
||
|
|
||
| class DeviceWithinLimitsState(DeviceBeamlineState): |
There was a problem hiding this comment.
I tried using the DeviceWithinLimitState, and checked the endpoint in REDIS. Somehow, I only saw invalid and warning updates. After some iterations, I realized that this is due to me setting tolerance to 1, which resulted in a broad tolerance region, essentially no valid region. I am wondering if absolute tolerance might be more intuitiv.
03e0419 to
c0d42dc
Compare

This PR migrates to the new beamline states. It builds the foundation for
Actors(coming in a follow-up PR). A similar PR is in preparation for BEC Widgets to allow users to display the state of their beamline through small indicatorscloses #406