diff --git a/pykirdy/driver/kirdy.py b/pykirdy/driver/kirdy.py index 7767dd3..876f5ca 100644 --- a/pykirdy/driver/kirdy.py +++ b/pykirdy/driver/kirdy.py @@ -44,6 +44,7 @@ class CmdList: SetI = _dt.f32 SetPdResponsitivity = _dt.f32 SetPdDarkCurrent = _dt.f32 + ApplyPdParams = _dt.none SetLdPwrLimit = _dt.f32 ClearAlarm = _dt.none @@ -266,15 +267,19 @@ class Device: 'msg_type': 'Settings', # Indicate it is a 'Settings' json object 'laser': { 'default_pwr_on': False, # Power On Laser Diode at Startup - 'ld_drive_current': { # Laser Diode Output Current(A) + 'ld_drive_current': { # Laser Diode Output Current (A) 'value': 0.0, # Value Set 'max': 0.3 # Max Value Settable }, - 'pd_mon_params': { # Laser Diode Software Current Limit(A) - 'responsitivity': None, # Value Set - 'i_dark': 0.0 # Max Value Settable - }, - 'ld_pwr_limit': 0.0, # Laser Diode Power Limit(W) + 'pd_mon_params': { # Photodiode Parameters + 'transconductance': 0.000115258765 # Board Specific Transconductance (1/ohm) + 'responsitivity': 0.0141, # Responsitivity (A/W) + 'i_dark': 0.0 # Max Value Settable (A) + }, + 'ld_pwr_limit': { # Laser Diode Power Limit (W) + 'value': 0.00975, # Value Set + 'max': 0.023321507 # Max Value Settable + }, 'ld_terms_short: False, # Is Laser Diode Terminals short? (True/False) }, 'thermostat': { @@ -282,19 +287,19 @@ class Device: 'pid_engaged': True, # True: PID Control Mode | False Constant Current Mode 'temperature_setpoint': 25.0, # Temperature Setpoint (Degree Celsius) 'tec_settings': { - 'i_set': { # Current TEC Current Set by PID Controller/User + 'i_set': { # Current TEC Current Set by PID Controller/User (A) 'value': 0.04330516, # Value Set 'max': 1.0 # Max Value Settable }, - 'max_v': { # Max Voltage Across Tec Terminals + 'max_v': { # Max Voltage Across Tec Terminals (V) 'value': 4.990857, # Value Set 'max': 5.0 # Max Value Settable }, - 'max_i_pos': { # Max Cooling Current Across Tec Terminals + 'max_i_pos': { # Max Cooling Current Across Tec Terminals (A) 'value': 0.99628574, # Value Set 'max': 1.0 # Max Value Settable }, - 'max_i_neg': { # Max Heating Current Across Tec Terminals + 'max_i_neg': { # Max Heating Current Across Tec Terminals (A) 'value': 0.99628574, # Value Set 'max': 1.0 # Max Value Settable } @@ -396,6 +401,7 @@ class Laser: async def set_pd_mon_responsitivity(self, responsitivity): """ Configure the photodiode monitor responsitivity parameter. + The value is only effective if ApplyPdParams cmd is issued. - responsitivity: A/W """ return await self._send_cmd(self._cmd._target, self._cmd.SetPdResponsitivity, responsitivity) @@ -403,16 +409,29 @@ class Laser: async def set_pd_mon_dark_current(self, dark_current): """ Configure the photodiode monitor dark current parameter. + The value is only effective if ApplyPdParams cmd is issued. - dark_current: A """ return await self._send_cmd(self._cmd._target, self._cmd.SetPdDarkCurrent, dark_current) + async def apply_pd_params(self): + """ + Evaluate and apply photodiode monitor parameters that are set with SetPdDarkCurrent and SetPdResponsitivity cmd. + After Kirdy receives the cmd, it will check if the current power limit is within the newly calculated + power limit range. If it is out of range, the photodiode monitor parameters remains unchanged and Kirdy + sends out a "InvalidSettings" message along with an error message. + """ + return await self._send_cmd(self._cmd._target, self._cmd.ApplyPdParams) + async def set_ld_pwr_limit(self, pwr_limit): """ Set the power limit for the power excursion monitor. + If the power limit settings is out of range, power limit remains unchanged and Kirdy + sends out a "InvalidSettings" message along with an error message. + If the calculated power with the params of pd_mon > pwr_limit, overpower protection is triggered. - - pwr_limit: W + - pwr_limit: W """ return await self._send_cmd(self._cmd._target, self._cmd.SetLdPwrLimit, pwr_limit) @@ -875,20 +894,21 @@ class Kirdy: response = raw_response.decode('utf-8', errors='ignore').split("\n") return json.loads(response[0]) + def _response_handling(self, msg, msg_type, sig=None): + if msg["msg_type"] in ["InvalidCmd", "InvalidDatatype"]: + raise InvalidCmd + elif msg["msg_type"] == msg_type: + if sig is not None: + sig.emit(msg) + return msg + async def _send_raw_cmd(self, cmd, msg_type="Acknowledge", sig=None): if self.connected(): async with self._lock: self._writer.write(bytes(json.dumps(cmd), "UTF-8")) await self._writer.drain() msg = await asyncio.wait_for(self._int_msg_queue.get(), self._timeout) - - if msg["msg_type"] == msg_type: - if sig is not None: - sig.emit(msg) - return {"msg_type": "Acknowledge"} - return msg - else: - raise InvalidCmd + return self._response_handling(msg, msg_type, sig) else: raise ConnectionError @@ -919,12 +939,4 @@ class Kirdy: msg = await asyncio.wait_for(self._int_msg_queue.get(), self._timeout) if isinstance(msg, Exception): raise msg - - if msg['msg_type'] == msg_type: - if sig is not None: - sig.emit(msg) - return {"msg_type": "Acknowledge"} - else: - return msg - else: - raise InvalidCmd + return self._response_handling(msg, msg_type, sig)