2222an :mod:`Adapter <lewis.adapters>`).
2323"""
2424
25+ from collections .abc import Collection , Sequence
2526from datetime import datetime
2627from threading import Thread
2728from time import sleep
29+ from typing import Any
2830
29- from lewis .core .adapters import AdapterCollection
31+ from lewis .core .adapters import Adapter , AdapterCollection
3032from lewis .core .control_server import ControlServer , ExposedObject
31- from lewis .core .devices import DeviceRegistry
33+ from lewis .core .devices import DeviceBuilder , DeviceRegistry
3234from lewis .core .logging import has_log
3335from lewis .core .utils import seconds_since
36+ from lewis .devices import Device
3437
3538
3639@has_log
@@ -81,7 +84,13 @@ class Simulation:
8184 :param control_server: 'host:port'-string to construct control server or None.
8285 """
8386
84- def __init__ (self , device , adapters = (), device_builder = None , control_server = None ) -> None :
87+ def __init__ (
88+ self ,
89+ device : Device ,
90+ adapters : Sequence [Adapter ] = (),
91+ device_builder : DeviceBuilder | None = None ,
92+ control_server : str | None = None ,
93+ ) -> None :
8594 super (Simulation , self ).__init__ ()
8695
8796 self ._device_builder = device_builder
@@ -102,7 +111,9 @@ def __init__(self, device, adapters=(), device_builder=None, control_server=None
102111
103112 # Constructing the control server must be deferred until the end,
104113 # because the construction is not complete at this point
105- self ._control_server = None # Just initialize to None and use property setter afterwards
114+ self ._control_server : ControlServer | None = (
115+ None # Just initialize to None and use property setter afterwards
116+ )
106117 self ._control_server_thread = None
107118 self .control_server = control_server
108119
@@ -115,7 +126,7 @@ def __init__(self, device, adapters=(), device_builder=None, control_server=None
115126 control_server ,
116127 )
117128
118- def _create_control_server (self , control_server ) :
129+ def _create_control_server (self , control_server : str | None ) -> ControlServer | None :
119130 if control_server is None :
120131 return None
121132
@@ -147,14 +158,14 @@ def _create_control_server(self, control_server):
147158 )
148159
149160 @property
150- def setups (self ):
161+ def setups (self ) -> list [ str ] :
151162 """
152163 A list of setups that are available. Use :meth:`switch_setup` to
153164 change the setup.
154165 """
155166 return list (self ._device_builder .setups .keys ()) if self ._device_builder is not None else []
156167
157- def switch_setup (self , new_setup ) -> None :
168+ def switch_setup (self , new_setup : str ) -> None :
158169 """
159170 This method switches the setup, which means that it replaces the currently
160171 simulated device with a new device, as defined by the setup.
@@ -164,7 +175,7 @@ def switch_setup(self, new_setup) -> None:
164175 :param new_setup: Name of the new setup to load.
165176 """
166177 try :
167- self ._device = self ._device_builder .create_device (new_setup )
178+ self ._device = self ._device_builder .create_device (new_setup ) # pyright: ignore reportOptionalMemberAccess
168179 self ._adapters .set_device (self ._device )
169180 self .log .info ("Switched setup to '%s'" , new_setup )
170181 except Exception as e :
@@ -204,13 +215,14 @@ def start(self) -> None:
204215 self .log .info ("Simulation has ended." )
205216
206217 def _start_control_server (self ) -> None :
207- if self ._control_server is not None and self ._control_server_thread is None :
218+ control_server = self ._control_server
219+ if control_server is not None and self ._control_server_thread is None :
208220
209221 def control_server_loop () -> None :
210- self . _control_server .start_server ()
222+ control_server .start_server ()
211223
212224 while not self ._stop_commanded :
213- self . _control_server .process (blocking = True )
225+ control_server .process (blocking = True )
214226
215227 self .log .info ("Stopped processing control server commands, ending thread." )
216228
@@ -222,7 +234,7 @@ def _wait_for_control_server_to_stop(self) -> None:
222234 self ._control_server_thread .join (timeout = 1.0 )
223235 self ._control_server_thread = None
224236
225- def _process_cycle (self , delta ) :
237+ def _process_cycle (self , delta : float ) -> float :
226238 """
227239 Processes one cycle, which consists of one simulation cycle and processing
228240 of control server commands. The method measures how long all this takes
@@ -239,7 +251,7 @@ def _process_cycle(self, delta):
239251
240252 return delta
241253
242- def _process_simulation_cycle (self , delta ) -> None :
254+ def _process_simulation_cycle (self , delta : float ) -> None :
243255 """
244256 If the simulation is not paused, the device's process-method is
245257 called with the supplied delta, multiplied by the simulation speed.
@@ -263,15 +275,15 @@ def _process_simulation_cycle(self, delta) -> None:
263275 self ._runtime += delta_simulation
264276
265277 @property
266- def cycle_delay (self ):
278+ def cycle_delay (self ) -> float :
267279 """
268280 Desired time between simulation cycles, this can not be negative.
269281 Use 0 for highest possible processing rate.
270282 """
271283 return self ._cycle_delay
272284
273285 @cycle_delay .setter
274- def cycle_delay (self , delay ) -> None :
286+ def cycle_delay (self , delay : float ) -> None :
275287 if delay < 0.0 :
276288 raise ValueError ("Cycle delay can not be negative." )
277289
@@ -280,14 +292,14 @@ def cycle_delay(self, delay) -> None:
280292 self .log .info ("Changed cycle delay to %s" , self ._cycle_delay )
281293
282294 @property
283- def cycles (self ):
295+ def cycles (self ) -> int :
284296 """
285297 Simulation cycles processed since start has been called.
286298 """
287299 return self ._cycles
288300
289301 @property
290- def uptime (self ):
302+ def uptime (self ) -> float :
291303 """
292304 Elapsed time in seconds since the simulation has been started.
293305 """
@@ -296,7 +308,7 @@ def uptime(self):
296308 return seconds_since (self ._start_time )
297309
298310 @property
299- def speed (self ):
311+ def speed (self ) -> float :
300312 """
301313 Simulation speed. Actual elapsed time is multiplied with this property
302314 to determine simulated time. Values greater than 1 increase the simulation
@@ -306,7 +318,7 @@ def speed(self):
306318 return self ._speed
307319
308320 @speed .setter
309- def speed (self , new_speed ) -> None :
321+ def speed (self , new_speed : float ) -> None :
310322 if new_speed < 0 :
311323 raise ValueError ("Speed can not be negative." )
312324
@@ -315,14 +327,14 @@ def speed(self, new_speed) -> None:
315327 self .log .info ("Changed speed to %s" , self ._speed )
316328
317329 @property
318- def runtime (self ):
330+ def runtime (self ) -> float :
319331 """
320332 The accumulated simulation time. Whenever speed is different from 1, this
321333 progresses at a different rate than uptime.
322334 """
323335 return self ._runtime
324336
325- def set_device_parameters (self , parameters ) -> None :
337+ def set_device_parameters (self , parameters : dict [ str , Any ] ) -> None :
326338 """
327339 Set multiple parameters of the simulated device "simultaneously". The passed
328340 parameter is assumed to be device parameter/value dict.
@@ -382,21 +394,21 @@ def stop(self) -> None:
382394 self ._adapters .disconnect ()
383395
384396 @property
385- def is_started (self ):
397+ def is_started (self ) -> bool :
386398 """
387399 This property is true if the simulation has been started.
388400 """
389401 return self ._started
390402
391403 @property
392- def is_paused (self ):
404+ def is_paused (self ) -> bool :
393405 """
394406 True if the simulation is paused (implies that the simulation has been started).
395407 """
396408 return self ._started and not self ._running
397409
398410 @property
399- def control_server (self ):
411+ def control_server (self ) -> ControlServer | None :
400412 """
401413 ControlServer-instance that exposes the object to remote machines. Can only
402414 be set before start has been called or on a running simulation if no
@@ -406,7 +418,7 @@ def control_server(self):
406418 return self ._control_server
407419
408420 @control_server .setter
409- def control_server (self , control_server ) -> None :
421+ def control_server (self , control_server : str | None ) -> None :
410422 if self .is_started and self ._control_server :
411423 raise RuntimeError ("Can not replace control server while simulation is running." )
412424
@@ -437,19 +449,25 @@ class SimulationFactory:
437449 .. warning:: This class is meant for internal use at the moment and may change frequently.
438450 """
439451
440- def __init__ (self , devices_package ) -> None :
452+ def __init__ (self , devices_package : str ) -> None :
441453 self ._reg = DeviceRegistry (devices_package )
442454
443455 @property
444- def devices (self ):
456+ def devices (self ) -> Collection [ str ] :
445457 """Names of available devices."""
446458 return self ._reg .devices
447459
448- def get_protocols (self , device ) :
460+ def get_protocols (self , device : str ) -> list [ str ] :
449461 """Returns a list of available protocols for the specified device."""
450462 return self ._reg .device_builder (device ).protocols
451463
452- def create (self , device , setup = None , protocols = None , control_server = None ):
464+ def create (
465+ self ,
466+ device : str ,
467+ setup : str | None = None ,
468+ protocols : dict [str , dict [str , Any ]] | None = None ,
469+ control_server : str | None = None ,
470+ ) -> Simulation :
453471 """
454472 Creates a :class:`Simulation` according to the supplied parameters.
455473
@@ -463,22 +481,22 @@ def create(self, device, setup=None, protocols=None, control_server=None):
463481 """
464482
465483 device_builder = self ._reg .device_builder (device )
466- device = device_builder .create_device (setup )
484+ device_instance = device_builder .create_device (setup )
467485
468486 adapters = []
469487
470488 if protocols is not None :
471489 for protocol , options in protocols .items ():
472490 interface = device_builder .create_interface (protocol )
473- interface .device = device
491+ interface .device = device_instance
474492
475493 adapter = interface .adapter (options = options or {})
476494 adapter .interface = interface
477495
478496 adapters .append (adapter )
479497
480498 return Simulation (
481- device = device ,
499+ device = device_instance ,
482500 adapters = adapters ,
483501 device_builder = device_builder ,
484502 control_server = control_server ,
0 commit comments