33import sys
44from typing import Any
55
6- from bec_lib import bl_states
6+ from bec_lib import bl_states , messages
77from bec_lib .endpoints import MessageEndpoints
88from bec_qthemes import material_icon
9- from pydantic import BaseModel
109from qtpy .QtCore import QAbstractListModel , QModelIndex , QSize , Qt
1110from qtpy .QtWidgets import (
1211 QAbstractItemView ,
@@ -48,7 +47,7 @@ def __init__(self, parent: QWidget | None = None) -> None:
4847 super ().__init__ (parent )
4948 self ._state_order : list [str ] = []
5049 self ._state_rows : dict [str , int ] = {}
51- self ._state_configs : dict [str , dict [ str , Any ] ] = {}
50+ self ._state_configs : dict [str , messages . BeamlineStateConfig ] = {}
5251
5352 def rowCount (self , parent : QModelIndex = QModelIndex ()) -> int : # noqa: N802
5453 return 0 if parent .isValid () else len (self ._state_order )
@@ -60,17 +59,17 @@ def data(self, index: QModelIndex, role: int = Qt.ItemDataRole.DisplayRole) -> A
6059 if role in (Qt .ItemDataRole .DisplayRole , self .NameRole ):
6160 return name
6261 if role == self .ConfigRole :
63- return self ._state_configs .get (name , {} )
62+ return self ._state_configs .get (name )
6463 return None
6564
6665 def flags (self , index : QModelIndex ) -> Qt .ItemFlag :
6766 if not index .isValid ():
6867 return Qt .ItemFlag .NoItemFlags
6968 return Qt .ItemFlag .ItemIsEnabled | Qt .ItemFlag .ItemIsSelectable
7069
71- def set_states (self , state_configs : list [dict [ str , Any ] ]) -> None :
72- new_order = [str ( state [ " name" ]) for state in state_configs if state . get ( "name" ) ]
73- new_configs = {str ( state [ " name" ]) : state for state in state_configs if state . get ( "name" ) }
70+ def set_states (self , state_configs : list [messages . BeamlineStateConfig ]) -> None :
71+ new_order = [state . name for state in state_configs ]
72+ new_configs = {state . name : state for state in state_configs }
7473
7574 for row in reversed (
7675 [row for row , name in enumerate (self ._state_order ) if name not in new_configs ]
@@ -129,11 +128,8 @@ def createEditor( # noqa: N802
129128 self , parent : QWidget , _option : QStyleOptionViewItem , index : QModelIndex
130129 ) -> QWidget :
131130 name = index .data (_BeamlineStateListModel .NameRole )
132- state_config = index .data (_BeamlineStateListModel .ConfigRole ) or {}
133- title = state_config .get ("title" ) or name
134- pill = BeamlineStatePill (
135- parent = parent , state_name = name , title = title , client = self ._manager .client
136- )
131+ state_config = index .data (_BeamlineStateListModel .ConfigRole )
132+ pill = BeamlineStatePill (parent = parent , state_name = name , client = self ._manager .client )
137133 pill .idle_card_background = self ._manager .idle_card_background
138134 pill .set_state_config (state_config )
139135 pill .state_changed .connect (self ._manager ._on_pill_state_changed )
@@ -147,9 +143,8 @@ def setEditorData(self, editor: QWidget, index: QModelIndex) -> None: # noqa: N
147143 if not isinstance (editor , BeamlineStatePill ):
148144 return
149145 name = index .data (_BeamlineStateListModel .NameRole )
150- state_config = index .data (_BeamlineStateListModel .ConfigRole ) or {}
151- title = state_config .get ("title" ) or name
152- editor .set_state_name (str (name ), title = str (title ))
146+ state_config = index .data (_BeamlineStateListModel .ConfigRole )
147+ editor .set_state_name (str (name ))
153148 editor .idle_card_background = self ._manager .idle_card_background
154149 editor .set_state_config (state_config )
155150
@@ -229,7 +224,7 @@ def __init__(
229224 )
230225 self .setSizePolicy (QSizePolicy .Policy .Expanding , QSizePolicy .Policy .Expanding )
231226 self ._state_pills : dict [str , BeamlineStatePill ] = {}
232- self ._state_configs : dict [str , dict [ str , Any ] ] = {}
227+ self ._state_configs : dict [str , messages . BeamlineStateConfig ] = {}
233228 self ._state_order : list [str ] = []
234229 self ._selected_statuses : set [str ] | None = None
235230 self ._selected_devices : set [str ] | None = None
@@ -414,14 +409,12 @@ def update_available_states(
414409 ) -> None :
415410 """Update the displayed pills from ``AvailableBeamlineStatesMessage`` content."""
416411 expanded_names = {name for name , pill in self ._state_pills .items () if pill .is_expanded ()}
417- states = content .get ("states" , [])
418- state_configs = [self ._state_config_to_dict (state ) for state in states ]
419- state_configs = [state for state in state_configs if state .get ("name" )]
412+ state_configs : list [messages .BeamlineStateConfig ] = content .get ("states" , [])
420413 if state_configs == list (self ._state_configs .values ()):
421414 self ._apply_filters ()
422415 return
423- self ._state_configs = {str ( state [ " name" ]) : state for state in state_configs }
424- self ._state_order = [str ( state [ " name" ]) for state in state_configs ]
416+ self ._state_configs = {state . name : state for state in state_configs }
417+ self ._state_order = [state . name for state in state_configs ]
425418 self ._model .set_states (state_configs )
426419 self ._open_persistent_editors (expanded_names )
427420 self ._apply_filters ()
@@ -472,7 +465,7 @@ def _is_state_visible(self, name: str) -> bool:
472465 ):
473466 return False
474467
475- device = self ._state_device (self ._state_configs .get (name , {} ))
468+ device = self ._state_device (self ._state_configs .get (name ))
476469 if self ._selected_devices is not None and device not in self ._selected_devices :
477470 return False
478471
@@ -505,14 +498,13 @@ def _update_state_parameters(
505498 )
506499 return
507500 try :
508- parameters = config .model_dump (exclude = {"name" })
509- state_client .update_parameters (** parameters )
501+ state_client .update_parameters (** config .model_dump (exclude = {"name" }))
510502 except Exception as exc :
511503 QMessageBox .warning (self , "Cannot Update State" , str (exc ))
512504 return
513505 pill = self ._state_pills .get (state_name )
514506 if pill is not None :
515- pill .mark_current_settings_clean (config )
507+ pill .mark_current_settings_clean ()
516508
517509 @SafeSlot (str )
518510 def _remove_state_requested (self , state_name : str ) -> None :
@@ -551,27 +543,10 @@ def _refresh_hidden_summary(self, hidden_count: int | None = None) -> None:
551543 )
552544
553545 @staticmethod
554- def _state_device (state : dict [str , Any ]) -> str | None :
555- parameters = state .get ("parameters" )
556- if isinstance (parameters , dict ):
557- device = parameters .get ("device" )
558- else :
559- device = state .get ("device" )
546+ def _state_device (state : messages .BeamlineStateConfig | None ) -> str | None :
547+ device = state .parameters .get ("device" ) if state is not None else None
560548 return str (device ) if device else None
561549
562- @staticmethod
563- def _state_config_to_dict (state : dict [str , Any ] | BaseModel ) -> dict [str , Any ]:
564- if isinstance (state , dict ):
565- return state
566- state_dict = state .model_dump ()
567- state_type = getattr (state , "state_type" , None )
568- if state_type is not None :
569- state_dict .setdefault ("state_type" , state_type )
570- title = getattr (state , "title" , None )
571- if title is not None and not state_dict .get ("title" ):
572- state_dict ["title" ] = title
573- return state_dict
574-
575550 def cleanup (self ) -> None :
576551 self .bec_dispatcher .disconnect_slot (
577552 self .update_available_states , MessageEndpoints .available_beamline_states ()
0 commit comments