Skip to content

Comments

Feature/beamline states#676

Open
wakonig wants to merge 4 commits intomainfrom
feature/beamline_states
Open

Feature/beamline states#676
wakonig wants to merge 4 commits intomainfrom
feature/beamline_states

Conversation

@wakonig
Copy link
Member

@wakonig wakonig commented Dec 3, 2025

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 indicators

image

closes #406

@wakonig wakonig force-pushed the feature/beamline_states branch from c058128 to 27272fe Compare December 5, 2025 13:42
@codecov
Copy link

codecov bot commented Dec 5, 2025

Codecov Report

❌ Patch coverage is 87.45645% with 36 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
bec_lib/bec_lib/bl_states.py 85.45% 8 Missing and 8 partials ⚠️
...r/bec_server/scan_server/beamline_state_manager.py 75.00% 7 Missing and 4 partials ⚠️
bec_lib/bec_lib/bl_state_manager.py 91.34% 5 Missing and 4 partials ⚠️

📢 Thoughts on this report? Let us know!

@wakonig wakonig force-pushed the feature/beamline_states branch 3 times, most recently from ead6d60 to 1880347 Compare December 5, 2025 19:00
@wakonig wakonig force-pushed the feature/beamline_states branch from 1880347 to 9385ee8 Compare December 8, 2025 12:54
@wakonig wakonig force-pushed the feature/beamline_states branch 2 times, most recently from ca71022 to ee406b9 Compare December 17, 2025 12:39
@wakonig wakonig force-pushed the feature/beamline_states branch 4 times, most recently from e352932 to 67eba1b Compare February 5, 2026 10:18
@wakonig wakonig marked this pull request as ready for review February 5, 2026 10:21
Copilot AI review requested due to automatic review settings February 5, 2026 10:21
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

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_checks and bl_conditions with a new bl_states module featuring BeamlineState base class and derived state types (ShutterState, DeviceWithinLimitsState)
  • Adds BeamlineStateManager classes 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.

@wakonig wakonig force-pushed the feature/beamline_states branch 5 times, most recently from b129dde to 995dcf5 Compare February 6, 2026 09:38
@wakonig wakonig requested review from cappel89 and d-perl February 6, 2026 09:44
@wakonig wakonig self-assigned this Feb 6, 2026
@wakonig wakonig force-pushed the feature/beamline_states branch from 995dcf5 to 45311ce Compare February 17, 2026 09:48
raise RuntimeError(
f"Device {device} not found in device manager. Cannot add state {state.name}."
)
if signal is not None:
Copy link
Contributor

Choose a reason for hiding this comment

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

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")

"""

def evaluate(self, msg: messages.DeviceMessage, **kwargs) -> messages.BeamlineStateMessage:
val = msg.signals.get(self.signal, {}).get("value", "").lower()
Copy link
Contributor

@cappel89 cappel89 Feb 17, 2026

Choose a reason for hiding this comment

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

Depending on how the device is integrated, the value can be a string or an integer. The current implementation assumes the return to be of type string, for which it would only work for a specific integration. If that's the case, why can i choose device & signal.

image

Copy link
Member Author

Choose a reason for hiding this comment

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

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.

)
return params

def update_parameters(self, **kwargs) -> None:
Copy link
Contributor

Choose a reason for hiding this comment

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

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.

)


class DeviceWithinLimitsState(DeviceBeamlineState):
Copy link
Contributor

Choose a reason for hiding this comment

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

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.

@wakonig wakonig force-pushed the feature/beamline_states branch from 03e0419 to c0d42dc Compare February 21, 2026 15:06
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.

Move beamline checks from the client to the server

3 participants