42 """Connection to a Spectra III Light Engine.
44 This module makes checks for Spectra III light engine and it was
45 only tested for it. But it should work with other lumencor light
46 engines with little work though, if only we got access to them.
61 self.
_serial.write(b
"GET MODEL\n")
62 answer = self.
_serial.readline()
63 if not answer.startswith(b
"A MODEL Spectra III"):
65 "Not a Lumencor Spectra III Light Engine"
68 def command_and_answer(self, *TX_tokens: bytes) -> bytes:
73 assert len(TX_tokens) >= 2,
"invalid command with less than two tokens"
74 assert TX_tokens[0]
in (
77 ),
"invalid command (not SET/GET)"
79 TX_command = b
" ".join(TX_tokens) + b
"\n"
82 answer = self.
_serial.readline()
83 RX_tokens = answer.split(maxsplit=2)
89 or RX_tokens[0] != b
"A"
90 or RX_tokens[1] != TX_tokens[1]
93 "command %s failed: %s" % (TX_command, answer)
97 def get_command(self, command: bytes, *args: bytes) -> bytes:
102 return answer[3 + len(command) : -2]
104 def set_command(self, command: bytes, *args: bytes) ->
None:
107 def get_channel_map(self) -> typing.List[typing.Tuple[int, str]]:
109 return list(enumerate(answer.decode().split()))
151 """Spectra III Light Engine.
154 port: port name (Windows) or path to port (everything else) to
155 connect to. For example, `/dev/ttyS1`, `COM1`, or
158 The names used on the devices dict are the ones provided by the
159 Spectra engine. These are the colour names in capitals such as
160 `'BLUE'`, `'NIR'`, or `'VIOLET'`.
162 Not all sources may be turned on simultaneously. To prevent
163 exceeding the capacity of the DC power supply, power consumption
164 is tracked by the Spectra onboard computer. If a set limit is
165 exceeded, either by increasing intensity settings for sources that
166 are already on, or by turning on additional sources, commands will
167 be rejected. To clear the error condition, reduce intensities of
168 sources that are on or turn off additional sources.
172 def __init__(self, port: str, **kwargs) ->
None:
173 super().__init__(**kwargs)
177 serial_conn = serial.Serial(
181 bytesize=serial.EIGHTBITS,
182 stopbits=serial.STOPBITS_ONE,
183 parity=serial.PARITY_NONE,
191 for index, name
in connection.get_channel_map():
194 ),
"light with name '%s' already mapped"
198 def devices(self) -> typing.Mapping[str, microscope.abc.Device]: