Index: dialin/dg/conductivity_sensors.py =================================================================== diff -u -raf31e009599d36b73b3d2b2453d4cc5cc82118eb -rcc425128f399de5414b0aee1942986653ca42c92 --- dialin/dg/conductivity_sensors.py (.../conductivity_sensors.py) (revision af31e009599d36b73b3d2b2453d4cc5cc82118eb) +++ dialin/dg/conductivity_sensors.py (.../conductivity_sensors.py) (revision cc425128f399de5414b0aee1942986653ca42c92) @@ -81,13 +81,13 @@ cpi = struct.unpack('f', bytearray(message['message'][MsgFieldPositions.START_POS_FIELD_2:MsgFieldPositions.END_POS_FIELD_2])) cpo = struct.unpack('f', bytearray(message['message'][MsgFieldPositions.START_POS_FIELD_3:MsgFieldPositions.END_POS_FIELD_3])) cd1 = struct.unpack('f', bytearray(message['message'][MsgFieldPositions.START_POS_FIELD_4:MsgFieldPositions.END_POS_FIELD_4])) - cd2 = struct.unpack('f', bytearray(message['message'][MsgFieldPositions.START_POS_FIELD_5:MsgFieldPositions.END_POS_FIELD_5])) + #cd2 = struct.unpack('f', bytearray(message['message'][MsgFieldPositions.START_POS_FIELD_5:MsgFieldPositions.END_POS_FIELD_5])) self.ro_rejection_ratio = ro_rejection_ratio[0] self.conductivity_sensor_cpi = cpi[0] self.conductivity_sensor_cpo = cpo[0] self.conductivity_sensor_cd1 = cd1[0] - self.conductivity_sensor_cd2 = cd2[0] + #self.conductivity_sensor_cd2 = cd2[0] def cmd_conductivity_sensor_override(self, conductivity, sensor, reset=NO_RESET): """ Index: dialin/dg/drain_pump.py =================================================================== diff -u -r363867c876456821000c189f86fbb55b4d583c50 -rcc425128f399de5414b0aee1942986653ca42c92 --- dialin/dg/drain_pump.py (.../drain_pump.py) (revision 363867c876456821000c189f86fbb55b4d583c50) +++ dialin/dg/drain_pump.py (.../drain_pump.py) (revision cc425128f399de5414b0aee1942986653ca42c92) @@ -18,46 +18,31 @@ from ..common.msg_defs import MsgIds, MsgFieldPositions from .constants import RESET, NO_RESET from ..protocols.CAN import (DenaliMessage, DenaliChannels) -from ..utils.base import _AbstractSubSystem, _publish +from ..utils.base import _AbstractSubSystem, _publish, DialinEnum from logging import Logger -import enum +from enum import unique -class DrainPumpStates(enum.Enum): +@unique +class DrainPumpStates(DialinEnum): + DRAIN_PUMP_OFF_STATE = 0 DRAIN_PUMP_CONTROL_TO_TARGET_STATE = 1 DRAIN_PUMP_OPEN_LOOP_STATE = 2 - @classmethod - def has_value(cls, value): - return value in cls._value2member_map_ class DGDrainPump(_AbstractSubSystem): """ Dialysate Generator (DG) Dialin API sub-class for drain pump related commands. """ - # Drain pump message IDs - MSG_ID_DG_DRAIN_PUMP_PUBLISHED_DATA = 0x0024 - MSG_ID_DG_DRAIN_PUMP_SET_SPEED_OVERRIDE = 0xA00B - MSG_ID_DG_DRAIN_PUMP_BROADAST_INTERVAL_OVERRIDE = 0xA00C - - # Drain pump broadcast message field positions - START_POS_SET_SPD = DenaliMessage.PAYLOAD_START_INDEX - END_POS_SET_SPD = START_POS_SET_SPD + 4 - START_POS_DAC = END_POS_SET_SPD - END_POS_DAC = START_POS_DAC + 4 - START_POS_PRESS_DIFF = END_POS_DAC - END_POS_PRESS_DIFF = START_POS_PRESS_DIFF + 4 - START_POS_PUMP_STATE = END_POS_PRESS_DIFF - END_POS_PUMP_STATE = START_POS_PUMP_STATE + 4 - def __init__(self, can_interface, logger: Logger): """ DGDrainPump constructor """ super().__init__() + self.can_interface = can_interface self.logger = logger @@ -67,27 +52,44 @@ self.can_interface.register_receiving_publication_function(channel_id, msg_id, self._handler_drain_pump_sync) - self.target_drain_pump_RPM = 0 + self.target_drain_pump_rpm = 0 self.dac_value = 0 - self.pressure_difference = 0 self.drain_pump_state = 0 + self.current_drain_pump_rpm = 0 - def get_target_drain_pump_speed(self): + def get_target_drain_pump_rpm(self): """ - Gets the target drain pump speed + Gets the target drain pump RPM - @return: The target drain pump speed (RPM) + @return: The target drain pump RPM """ - return self.target_drain_pump_RPM + return self.target_drain_pump_rpm def get_dac_value(self): """ Gets the dac value + @return: The dac value (int) """ return self.dac_value - @_publish(["target_drain_pump_RPM", "dac_value", "pressure_difference", "drain_pump_state"]) + def get_drain_pump_state(self): + """ + Gets the drain pump state + + @return: Drain pump state + """ + return self.drain_pump_state + + def gete_drain_pump_current_rpm(self): + """ + Gets the drain pump current RPM + + @return: Drain pump current RPM + """ + return self.current_drain_pump_rpm + + @_publish(["target_drain_pump_rpm", "dac_value", "drain_pump_state", "current_drain_pump_rpm"]) def _handler_drain_pump_sync(self, message): """ Handles published drain pump data messages. Drain pump data are captured @@ -96,20 +98,19 @@ @param message: published drain pump data message @return: none """ - - tgt = struct.unpack('i', bytearray( - message['message'][self.START_POS_SET_SPD:self.END_POS_SET_SPD]))[0] + tgt_rpm = struct.unpack('i', bytearray( + message['message'][MsgFieldPositions.START_POS_FIELD_1:MsgFieldPositions.END_POS_FIELD_1]))[0] dac = struct.unpack('i', bytearray( - message['message'][self.START_POS_DAC:self.END_POS_DAC]))[0] - diff = struct.unpack('f', bytearray( - message['message'][self.START_POS_PRESS_DIFF:self.END_POS_PRESS_DIFF]))[0] + message['message'][MsgFieldPositions.START_POS_FIELD_2:MsgFieldPositions.END_POS_FIELD_2]))[0] state = struct.unpack('i', bytearray( - message['message'][self.START_POS_PUMP_STATE:self.END_POS_PUMP_STATE]))[0] + message['message'][MsgFieldPositions.START_POS_FIELD_3:MsgFieldPositions.END_POS_FIELD_3]))[0] + curr_rpm = struct.unpack('i', bytearray( + message['message'][MsgFieldPositions.START_POS_FIELD_4:MsgFieldPositions.END_POS_FIELD_4]))[0] - self.target_drain_pump_RPM = tgt + self.target_drain_pump_rpm = tgt_rpm self.dac_value = dac - self.pressure_difference = diff self.drain_pump_state = state + self.current_drain_pump_rpm = curr_rpm def cmd_drain_pump_speed_set_point_override(self, speed, reset=NO_RESET): """ @@ -137,7 +138,7 @@ # If there is content... if received_message is not None: - # self.logger.debug(received_message) + if reset == RESET: str_res = "reset back to normal" else: Index: dialin/dg/fans.py =================================================================== diff -u -r6b7fe9b82f599b521d8e5d53922bc59841acd899 -rcc425128f399de5414b0aee1942986653ca42c92 --- dialin/dg/fans.py (.../fans.py) (revision 6b7fe9b82f599b521d8e5d53922bc59841acd899) +++ dialin/dg/fans.py (.../fans.py) (revision cc425128f399de5414b0aee1942986653ca42c92) @@ -2,14 +2,15 @@ import struct from ..utils.conversions import integer_to_bytearray from .constants import NO_RESET, RESET -from ..common.msg_defs import MsgIds +from ..common.msg_defs import MsgIds, MsgFieldPositions from ..protocols.CAN import (DenaliMessage, DenaliChannels) -from ..utils.base import _AbstractSubSystem, _publish +from ..utils.base import _AbstractSubSystem, _publish, DialinEnum from logging import Logger -import enum +from enum import unique -class FansNames(enum.Enum): +@unique +class FansNames(DialinEnum): FAN_INLET_1 = 0 FAN_INLET_2 = 1 @@ -18,32 +19,12 @@ FAN_OUTLET_2 = 4 FAN_OUTLET_3 = 5 - @classmethod - def has_value(cls, value): - return value in cls._value2member_map_ - class Fans(_AbstractSubSystem): """ Dialysate Generator (DG) Dialin API sub-class for fans related commands. """ - START_POS_TARGET_PWM = DenaliMessage.PAYLOAD_START_INDEX - END_POS_TARGET_PWM = START_POS_TARGET_PWM + 4 - START_POS_INLET_1_RPM = END_POS_TARGET_PWM - END_POS_INLET_1_RPM = START_POS_INLET_1_RPM + 4 - START_POS_INLET_2_RPM = END_POS_INLET_1_RPM - END_POS_INLET_2_RPM = START_POS_INLET_2_RPM + 4 - START_POS_INLET_3_RPM = END_POS_INLET_2_RPM - END_POS_INLET_3_RPM = START_POS_INLET_3_RPM + 4 - - START_POS_OUTLET_1_RPM = END_POS_INLET_3_RPM - END_POS_OUTLET_1_RPM = START_POS_OUTLET_1_RPM + 4 - START_POS_OUTLET_2_RPM = END_POS_OUTLET_1_RPM - END_POS_OUTLET_2_RPM = START_POS_OUTLET_2_RPM + 4 - START_POS_OUTLET_3_RPM = END_POS_OUTLET_2_RPM - END_POS_OUTLET_3_RPM = START_POS_OUTLET_3_RPM + 4 - def __init__(self, can_interface, logger: Logger): """ @@ -60,15 +41,71 @@ self.can_interface.register_receiving_publication_function(channel_id, msg_id, self._handler_fans_sync) # Publish variables - self.target_pwm = 0 - self.inlet_1_rpm = 0 - self.inlet_2_rpm = 0 - self.inlet_3_rpm = 0 - self.outlet_1_rpm = 0 - self.outlet_2_rpm = 0 - self.outlet_3_rpm = 0 + self.target_duty_cycle = 0.0 + self.inlet_1_rpm = 0.0 + self.inlet_2_rpm = 0.0 + self.inlet_3_rpm = 0.0 + self.outlet_1_rpm = 0.0 + self.outlet_2_rpm = 0.0 + self.outlet_3_rpm = 0.0 - @_publish(['target_pwm', 'inlet_1_rpm', 'inlet_2_rpm', 'inlet_3_rpm', 'outlet_1_rpm', 'outlet_2_rpm', + def get_fans_target_duty_cycle(self): + """ + Gets the fans target duty cycle + + @return: Fans target duty cycle + """ + return self.target_duty_cycle + + def get_fan_inlet_1_rpm(self): + """ + Gets the inlet 1 fan RPM + + @return: Fan inlet 1 RPM + """ + return self.inlet_1_rpm + + def get_fan_inlet_2_rpm(self): + """ + Gets the inlet 2 fan RPM + + @return: Fan inlet 2 RPM + """ + return self.inlet_2_rpm + + def get_fan_inlet_3_rpm(self): + """ + Gets the inlet 3 fan RPM + + @return: Fan inlet 3 RPM + """ + return self.inlet_3_rpm + + def get_fan_outlet_1_rpm(self): + """ + Gets the outlet 1 fan RPM + + @return: Fan outlet 1 RPM + """ + return self.outlet_1_rpm + + def get_fan_outlet_2_rpm(self): + """ + Gets the outlet 2 fan RPM + + @return: Fan outlet 2 RPM + """ + return self.outlet_2_rpm + + def get_fan_outlet_3_rpm(self): + """ + Gets the outlet 3 fan RPM + + @return: Fan outlet 3 RPM + """ + return self.outlet_3_rpm + + @_publish(['target_duty_cycle', 'inlet_1_rpm', 'inlet_2_rpm', 'inlet_3_rpm', 'outlet_1_rpm', 'outlet_2_rpm', 'outlet_3_rpm']) def _handler_fans_sync(self, message): """ @@ -78,21 +115,21 @@ @return: none """ tgt_pwm = struct.unpack('f', bytearray( - message['message'][self.START_POS_TARGET_PWM:self.END_POS_TARGET_PWM]))[0] + message['message'][MsgFieldPositions.START_POS_FIELD_1:MsgFieldPositions.END_POS_FIELD_1]))[0] inlet_1_rpm = struct.unpack('f', bytearray( - message['message'][self.START_POS_INLET_1_RPM:self.END_POS_INLET_1_RPM]))[0] + message['message'][MsgFieldPositions.START_POS_FIELD_2:MsgFieldPositions.END_POS_FIELD_2]))[0] inlet_2_rpm = struct.unpack('f', bytearray( - message['message'][self.START_POS_INLET_2_RPM:self.END_POS_INLET_2_RPM]))[0] + message['message'][MsgFieldPositions.START_POS_FIELD_3:MsgFieldPositions.END_POS_FIELD_3]))[0] inlet_3_rpm = struct.unpack('f', bytearray( - message['message'][self.START_POS_INLET_3_RPM:self.END_POS_INLET_3_RPM]))[0] + message['message'][MsgFieldPositions.START_POS_FIELD_4:MsgFieldPositions.END_POS_FIELD_4]))[0] outlet_1_rpm = struct.unpack('f', bytearray( - message['message'][self.START_POS_OUTLET_1_RPM:self.END_POS_OUTLET_1_RPM]))[0] + message['message'][MsgFieldPositions.START_POS_FIELD_5:MsgFieldPositions.END_POS_FIELD_5]))[0] outlet_2_rpm = struct.unpack('f', bytearray( - message['message'][self.START_POS_OUTLET_2_RPM:self.END_POS_OUTLET_2_RPM]))[0] + message['message'][MsgFieldPositions.START_POS_FIELD_6:MsgFieldPositions.END_POS_FIELD_6]))[0] outlet_3_rpm = struct.unpack('f', bytearray( - message['message'][self.START_POS_OUTLET_3_RPM:self.END_POS_OUTLET_3_RPM]))[0] + message['message'][MsgFieldPositions.START_POS_FIELD_7:MsgFieldPositions.END_POS_FIELD_7]))[0] - self.target_pwm = tgt_pwm + self.target_duty_cycle = tgt_pwm self.inlet_1_rpm = inlet_1_rpm self.inlet_2_rpm = inlet_2_rpm self.inlet_3_rpm = inlet_3_rpm Index: dialin/dg/heaters.py =================================================================== diff -u -r812bbf1e5b3b2f1c4f5cfbef1264787e18afb5c3 -rcc425128f399de5414b0aee1942986653ca42c92 --- dialin/dg/heaters.py (.../heaters.py) (revision 812bbf1e5b3b2f1c4f5cfbef1264787e18afb5c3) +++ dialin/dg/heaters.py (.../heaters.py) (revision cc425128f399de5414b0aee1942986653ca42c92) @@ -20,122 +20,147 @@ from ..common.msg_defs import MsgIds, MsgFieldPositions from .constants import NO_RESET from ..protocols.CAN import (DenaliMessage, DenaliChannels) -from ..utils.base import _AbstractSubSystem, _publish +from ..utils.base import _AbstractSubSystem, _publish, DialinEnum from logging import Logger +from enum import unique +@unique +class HeatersStartStop(DialinEnum): + + STOP = 0 + START = 1 + + class Heaters(_AbstractSubSystem): + """ + Dialysate Generator (DG) Dialin API sub-class for heaters related commands. + """ + def __init__(self, can_interface, logger: Logger): + """ + @param can_interface: Denali CAN Messenger object + """ + super().__init__() + self.can_interface = can_interface self.logger = logger - self.main_primary_heater_pwm = 0 - self.small_primary_heater_pwm = 0 - self.trimmer_heater_pwm = 0 + self.main_primary_heater_duty_cycle = 0 + self.small_primary_heater_duty_cycle = 0 + self.trimmer_heater_duty_cycle = 0 if self.can_interface is not None: channel_id = DenaliChannels.dg_sync_broadcast_ch_id msg_id = MsgIds.MSG_ID_DG_HEATERS_DATA.value self.can_interface.register_receiving_publication_function(channel_id, msg_id, self._handler_heaters_sync) - @_publish(["main_primary_heater_pwm", "small_primary_heater_pwm", "trimmer_heater_pwm"]) + def get_main_primary_heater_duty_cycle(self): + """ + Gets the main primary heater duty cycle + + @return: Main primary heater duty cycle + """ + return self.main_primary_heater_duty_cycle + + def get_small_primary_heater_duty_cycle(self): + """ + Gets the small primary heater duty cycle + + @return: Small primary heater duty cycle + """ + return self.small_primary_heater_duty_cycle + + def get_trimmer_heater_duty_cycle(self): + """ + Gets the trimmer heater duty cycle + + @return: Trimmer primary heater duty cycle + """ + return self.trimmer_heater_duty_cycle + + @_publish(["main_primary_heater_duty_cycle", "small_primary_heater_duty_cycle", "trimmer_heater_duty_cycle"]) def _handler_heaters_sync(self, message): """ Handles published heaters message @param message: published heaters data message @returns none """ - main_primary_heater_pwm = struct.unpack('i', bytearray( + main_primary_heater_pwm = struct.unpack('f', bytearray( message['message'][MsgFieldPositions.START_POS_FIELD_1:MsgFieldPositions.END_POS_FIELD_1])) - small_primary_heater_pwm = struct.unpack('i', bytearray( + small_primary_heater_pwm = struct.unpack('f', bytearray( message['message'][MsgFieldPositions.START_POS_FIELD_2:MsgFieldPositions.END_POS_FIELD_2])) - trimmer_heater_pwm = struct.unpack('i', bytearray( + trimmer_heater_pwm = struct.unpack('f', bytearray( message['message'][MsgFieldPositions.START_POS_FIELD_3:MsgFieldPositions.END_POS_FIELD_3])) - self.main_primary_heater_pwm = main_primary_heater_pwm[0] - self.small_primary_heater_pwm = small_primary_heater_pwm[0] - self.trimmer_heater_pwm = trimmer_heater_pwm[0] + self.main_primary_heater_duty_cycle = main_primary_heater_pwm[0] + self.small_primary_heater_duty_cycle = small_primary_heater_pwm[0] + self.trimmer_heater_duty_cycle = trimmer_heater_pwm[0] - def cmd_start_primary_heater(self): + def cmd_start_stop_primary_heater(self, state=HeatersStartStop.STOP.name): """ - Constructs and sends start primary heater command + Constructs and sends a start/stop primary heater command Constraints: A target temperature for primary heater between 10 and 90 deg C must have been given to DG previously. @returns none """ + if state == HeatersStartStop.START.name: + payload = integer_to_bytearray(1) + operation = 'Turning on ' + else: + payload = integer_to_bytearray(0) + operation = 'Turning off ' - # 1 is to start the primary heater - payload = integer_to_bytearray(1) message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_dg_ch_id, message_id=MsgIds.MSG_ID_START_STOP_PRIMARY_HEATER.value, payload=payload) - self.logger.debug("Starting the Primary heater") - self.can_interface.send(message, 0) - def cmd_stop_primary_heater(self): - """ - Constructs and sends stop primary heater command - - @returns none - """ - # 0 is to stop the primary heater - payload = integer_to_bytearray(0) - message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_dg_ch_id, - message_id=MsgIds.MSG_ID_START_STOP_PRIMARY_HEATER.value, - payload=payload) - self.logger.debug("Stopping the Primary heater") + self.logger.debug(operation + " the Primary heater") self.can_interface.send(message, 0) - def cmd_start_trimmer_heater(self): + def cmd_start_stop_trimmer_heater(self, state=HeatersStartStop.STOP.name): """ Constructs and sends start trimmer heater command Constraints: A target temperature for trimmer heater between 10 and 90 deg C must have been given to DG previously. @returns none """ - # 1 is to start the primary heater - payload = integer_to_bytearray(1) - message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_dg_ch_id, - message_id=MsgIds.MSG_ID_DG_START_STOP_TRIMMER_HEATER_CMD.value, - payload=payload) - self.logger.debug("Starting the Trimmer heater") - self.can_interface.send(message, 0) + if state == HeatersStartStop.START.name: + payload = integer_to_bytearray(1) + operation = 'Turning on ' + else: + payload = integer_to_bytearray(0) + operation = 'Turning off' - def cmd_stop_trimmer_heater(self): - """ - Constructs and sends stop trimmer heater command - - @returns none - """ - # 1 is to start the primary heater - payload = integer_to_bytearray(0) message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_dg_ch_id, message_id=MsgIds.MSG_ID_DG_START_STOP_TRIMMER_HEATER_CMD.value, payload=payload) - self.logger.debug("Stopping the Trimmer heater") + + self.logger.debug(operation + " the Primary heater") self.can_interface.send(message, 0) - def cmd_set_dialysate_target_temperature(self, pirmary_target_temp=37.0, trimmer_target_temp=38.0): + def cmd_set_dialysate_target_temperature(self, primary_target_temp=37.0, trimmer_target_temp=38.0): """ Constructs and sends primary and trimmer heater target temperature @param pirmary_target_temp: Primary heater target temperature @param trimmer_target_temp: Trimmer heater target temperature @returns none """ - primary_target = float_to_bytearray(pirmary_target_temp) + primary_target = float_to_bytearray(primary_target_temp) trimmer_target = float_to_bytearray(trimmer_target_temp) payload = primary_target + trimmer_target message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_dg_ch_id, message_id=MsgIds.MSG_ID_SET_DG_DIALYSATE_TEMP_TARGETS.value, payload=payload) - self.logger.debug("Setting Primary Heater to {} C and Trimmer Heater to {} C".format(pirmary_target_temp, trimmer_target_temp)) + self.logger.debug("Setting Primary Heater to {} C and Trimmer Heater to {} C".format(primary_target_temp, + trimmer_target_temp)) self.can_interface.send(message, 0) def cmd_heaters_broadcast_interval_override(self, ms, reset=NO_RESET): Index: dialin/dg/ro_pump.py =================================================================== diff -u -r363867c876456821000c189f86fbb55b4d583c50 -rcc425128f399de5414b0aee1942986653ca42c92 --- dialin/dg/ro_pump.py (.../ro_pump.py) (revision 363867c876456821000c189f86fbb55b4d583c50) +++ dialin/dg/ro_pump.py (.../ro_pump.py) (revision cc425128f399de5414b0aee1942986653ca42c92) @@ -18,47 +18,26 @@ from ..common.msg_defs import MsgIds, MsgFieldPositions from .constants import RESET, NO_RESET from ..protocols.CAN import (DenaliMessage, DenaliChannels) -from ..utils.base import _AbstractSubSystem, _publish +from ..utils.base import _AbstractSubSystem, _publish, DialinEnum from logging import Logger -import enum +from enum import unique -class ROPumpStates(enum.Enum): +@unique +class ROPumpStates(DialinEnum): RO_PUMP_OFF_STATE = 0 RO_PUMP_RAMP_UP_STATE = 1 RO_PUMP_VERIFY_FLOW_STATE = 2 RO_PUMP_CONTROL_TO_TARGET_STATE = 3 RO_PUMP_OPEN_LOOP_STATE = 4 - @classmethod - def has_value(cls, value): - return value in cls._value2member_map_ - class DGROPump(_AbstractSubSystem): """ DGROPump Dialysate Generator (DG) Dialin API sub-class for RO pump related commands. """ - - # RO pump message IDs - MSG_ID_DG_RO_PUMP_PUBLISHED_DATA = 0x1F - MSG_ID_DG_RO_PUMP_PRESSURE_SET_PT_OVERRIDE = 0xA008 - #MSG_ID_DG_RO_FLOW_RATE_OVERRIDE = 0xA009 - MSG_ID_DG_RO_PUMP_BROADCAST_INTERVAL_OVERRIDE = 0xA00A - MSG_ID_RO_PUMP_SET_PT_OVERRIDE = 0xA008 - - # RO pump broadcast message field positions - START_POS_PRES_SET_PT = DenaliMessage.PAYLOAD_START_INDEX - END_POS_PRES_SET_PT = START_POS_PRES_SET_PT + 4 - START_POS_MEAS_FLOW = END_POS_PRES_SET_PT - END_POS_MEAS_FLOW = START_POS_MEAS_FLOW + 4 - START_POS_PWM = END_POS_MEAS_FLOW - END_POS_PWM = START_POS_PWM + 4 - START_POS_STATE = END_POS_PWM - END_POS_STATE = START_POS_STATE + 4 - def __init__(self, can_interface, logger: Logger): """ DGROPump constructor @@ -82,24 +61,35 @@ def get_target_pressure(self): """ Gets the target pressure + @return: the target pressure (PSI) """ return self.target_pressure_psi def get_measured_flow_rate(self): """ Gets the measured flow rate (lpm) + @return: The measured flow rate (float) """ return self.measured_flow_rate_lpm def get_pwm_duty_cycle_pct(self): """ Gets the PWM duty cycle pct + @return: The PWM duty cycle pct (float) """ return self.pwm_duty_cycle_pct + def get_ro_pump_state(self): + """ + Gets the RO pump state + + @return: The state of the RO pump + """ + return self.ro_pump_state + @_publish(["target_pressure_psi", "measured_flow_rate_lpm", "pwm_duty_cycle_pct", "ro_pump_state"]) def _handler_ro_pump_sync(self, message): """ @@ -110,10 +100,14 @@ @return: None """ - tgt = struct.unpack('f', bytearray(message['message'][self.START_POS_PRES_SET_PT:self.END_POS_PRES_SET_PT]))[0] - flow = struct.unpack('f', bytearray(message['message'][self.START_POS_MEAS_FLOW:self.END_POS_MEAS_FLOW]))[0] - pwm = struct.unpack('f', bytearray(message['message'][self.START_POS_PWM:self.END_POS_PWM]))[0] - ro_state = struct.unpack('i', bytearray(message['message'][self.START_POS_STATE:self.END_POS_STATE]))[0] + tgt = struct.unpack('f', bytearray( + message['message'][MsgFieldPositions.START_POS_FIELD_1:MsgFieldPositions.END_POS_FIELD_1]))[0] + flow = struct.unpack('f', bytearray( + message['message'][MsgFieldPositions.START_POS_FIELD_2:MsgFieldPositions.END_POS_FIELD_2]))[0] + pwm = struct.unpack('f', bytearray( + message['message'][MsgFieldPositions.START_POS_FIELD_3:MsgFieldPositions.END_POS_FIELD_3]))[0] + ro_state = struct.unpack('i', bytearray( + message['message'][MsgFieldPositions.START_POS_FIELD_4:MsgFieldPositions.END_POS_FIELD_4]))[0] self.target_pressure_psi = tgt self.measured_flow_rate_lpm = flow @@ -139,7 +133,7 @@ message_id=MsgIds.MSG_ID_RO_PUMP_SET_PT_OVERRIDE.value, payload=payload) - self.logger.debug("override RO pump pressure set point") + self.logger.debug("Override RO pump pressure set point") # Send message received_message = self.can_interface.send(message) @@ -220,7 +214,7 @@ message_id=MsgIds.MSG_ID_RO_PUMP_SEND_INTERVAL_OVERRIDE.value, payload=payload) - self.logger.debug("override RO pump data broadcast interval") + self.logger.debug("Override RO pump data broadcast interval") # Send message received_message = self.can_interface.send(message) Index: dialin/dg/temperature_sensors.py =================================================================== diff -u -r812bbf1e5b3b2f1c4f5cfbef1264787e18afb5c3 -rcc425128f399de5414b0aee1942986653ca42c92 --- dialin/dg/temperature_sensors.py (.../temperature_sensors.py) (revision 812bbf1e5b3b2f1c4f5cfbef1264787e18afb5c3) +++ dialin/dg/temperature_sensors.py (.../temperature_sensors.py) (revision cc425128f399de5414b0aee1942986653ca42c92) @@ -19,24 +19,31 @@ from ..common.msg_defs import MsgIds, MsgFieldPositions from .constants import NO_RESET from ..protocols.CAN import (DenaliMessage, DenaliChannels) -from ..utils.base import _AbstractSubSystem, _publish +from ..utils.base import _AbstractSubSystem, _publish, DialinEnum from logging import Logger -import enum +from enum import unique +@unique +class TemperatureSensorsNames(DialinEnum): -class TemperatureSensorsEnum(enum.Enum): - PRIMARY_HEATER_INLET = 0 - PRIMARY_HEATER_OUTLET = 1 + INLET_PRIMARY_HEATER = 0 + OUTLET_PRIMARY_HEATER = 1 CONDUCTIVITY_SENSOR_1 = 2 CONDUCTIVITY_SENSOR_2 = 3 - DIALYSATE_REDUNDANT = 4 - DIALYSATE = 5 + OUTLET_DIALYSATE_REDUNDANT = 4 + INLET_DIALYSATE = 5 PRIMARY_HEATER_THERMOCOUPLE = 6 TRIMMER_HEATER_THERMOCOUPLE = 7 PRIMARY_HEATER_COLD_JUNCTION = 8 TRIMMER_HEATER_COLD_JUNCTION = 9 PRIMARY_HEATER_INTERNAL = 10 TRIMMER_HEATER_INTERNAL = 11 + FPGA_BOARD_SENSOR = 12 + LOAD_CELL_A1_B1 = 13 + LOAD_CELL_A2_B2 = 14 + INTERNAL_THDO_RTD = 15 + INTERNAL_TDI_RTD = 16 + INTERNAL_COND_TEMP_SENSOR = 17 class TemperatureSensors(_AbstractSubSystem): @@ -47,26 +54,41 @@ self.can_interface = can_interface self.logger = logger - self.inlet_primary = 0.0 - self.outlet_primary = 0.0 - self.cd1 = 0.0 - self.cd2 = 0.0 - self.outlet_redundancy = 0.0 - self.inlet_dialysate = 0.0 - self.primary_tc = 0.0 - self.trimmer_tc = 0.0 - self.primary_cj = 0.0 - self.trimmer_cj = 0.0 - self.primary_internal = 0.0 - self.trimmer_internal = 0.0 + # Dictionary of the temperature sensors + self.temperature_sensors = {TemperatureSensorsNames.INLET_PRIMARY_HEATER.name: {}, + TemperatureSensorsNames.OUTLET_PRIMARY_HEATER.name: {}, + TemperatureSensorsNames.CONDUCTIVITY_SENSOR_1.name: {}, + TemperatureSensorsNames.CONDUCTIVITY_SENSOR_2.name: {}, + TemperatureSensorsNames.OUTLET_DIALYSATE_REDUNDANT.name: {}, + TemperatureSensorsNames.INLET_DIALYSATE.name: {}, + TemperatureSensorsNames.PRIMARY_HEATER_THERMOCOUPLE.name: {}, + TemperatureSensorsNames.TRIMMER_HEATER_THERMOCOUPLE.name: {}, + TemperatureSensorsNames.PRIMARY_HEATER_COLD_JUNCTION.name: {}, + TemperatureSensorsNames.TRIMMER_HEATER_COLD_JUNCTION.name: {}, + TemperatureSensorsNames.PRIMARY_HEATER_INTERNAL.name: {}, + TemperatureSensorsNames.TRIMMER_HEATER_INTERNAL.name: {}, + TemperatureSensorsNames.FPGA_BOARD_SENSOR.name: {}, + TemperatureSensorsNames.LOAD_CELL_A1_B1.name: {}, + TemperatureSensorsNames.LOAD_CELL_A2_B2.name: {}, + TemperatureSensorsNames.INTERNAL_THDO_RTD.name: {}, + TemperatureSensorsNames.INTERNAL_TDI_RTD.name: {}, + TemperatureSensorsNames.INTERNAL_COND_TEMP_SENSOR.name: {}} if self.can_interface is not None: channel_id = DenaliChannels.dg_sync_broadcast_ch_id msg_id = MsgIds.MSG_ID_DG_TEMPERATURE_DATA.value - self.can_interface.register_receiving_publication_function(channel_id, msg_id, self._handler_temperature_sensors_sync) + self.can_interface.register_receiving_publication_function(channel_id, msg_id, + self._handler_temperature_sensors_sync) - @_publish(["inlet_primary", "outlet_primary", "cd1", "cd2","outlet_redundancy", "inlet_dialysate", "primary_tc", - "trimmer_tc", "primary_cj", "trimmer_cj", "primary_internal", "trimmer_internal"]) + def get_temperature(self, sensor): + """ + Gets a temperature sensor's value + + @return: The temperature of a temperature sensor + """ + return self.temperature_sensors[sensor] + + @_publish(['temperature_sensors']) def _handler_temperature_sensors_sync(self, message): """ Handles published temperature sensors message @@ -75,53 +97,77 @@ @returns none """ sensors_data = struct.unpack('f', bytearray( - message['message'][MsgFieldPositions.START_POS_FIELD_1:MsgFieldPositions.END_POS_FIELD_1])) - self.inlet_primary = sensors_data[0] + message['message'][MsgFieldPositions.START_POS_FIELD_1:MsgFieldPositions.END_POS_FIELD_1]))[0] + self.temperature_sensors[TemperatureSensorsNames.INLET_PRIMARY_HEATER.name] = sensors_data sensors_data = struct.unpack('f', bytearray( - message['message'][MsgFieldPositions.START_POS_FIELD_2:MsgFieldPositions.END_POS_FIELD_2])) - self.outlet_primary = sensors_data[0] + message['message'][MsgFieldPositions.START_POS_FIELD_2:MsgFieldPositions.END_POS_FIELD_2]))[0] + self.temperature_sensors[TemperatureSensorsNames.OUTLET_PRIMARY_HEATER.name] = sensors_data sensors_data = struct.unpack('f', bytearray( - message['message'][MsgFieldPositions.START_POS_FIELD_3:MsgFieldPositions.END_POS_FIELD_3])) - self.cd1 = sensors_data[0] + message['message'][MsgFieldPositions.START_POS_FIELD_3:MsgFieldPositions.END_POS_FIELD_3]))[0] + self.temperature_sensors[TemperatureSensorsNames.CONDUCTIVITY_SENSOR_1.name] = sensors_data sensors_data = struct.unpack('f', bytearray( - message['message'][MsgFieldPositions.START_POS_FIELD_4:MsgFieldPositions.END_POS_FIELD_4])) - self.cd2 = sensors_data[0] + message['message'][MsgFieldPositions.START_POS_FIELD_4:MsgFieldPositions.END_POS_FIELD_4]))[0] + self.temperature_sensors[TemperatureSensorsNames.CONDUCTIVITY_SENSOR_2.name] = sensors_data sensors_data = struct.unpack('f', bytearray( - message['message'][MsgFieldPositions.START_POS_FIELD_5:MsgFieldPositions.END_POS_FIELD_5])) - self.outlet_redundancy = sensors_data[0] + message['message'][MsgFieldPositions.START_POS_FIELD_5:MsgFieldPositions.END_POS_FIELD_5]))[0] + self.temperature_sensors[TemperatureSensorsNames.OUTLET_DIALYSATE_REDUNDANT.name] = sensors_data sensors_data = struct.unpack('f', bytearray( - message['message'][MsgFieldPositions.START_POS_FIELD_6:MsgFieldPositions.END_POS_FIELD_6])) - self.inlet_dialysate = sensors_data[0] + message['message'][MsgFieldPositions.START_POS_FIELD_6:MsgFieldPositions.END_POS_FIELD_6]))[0] + self.temperature_sensors[TemperatureSensorsNames.INLET_DIALYSATE.name] = sensors_data sensors_data = struct.unpack('f', bytearray( - message['message'][MsgFieldPositions.START_POS_FIELD_7:MsgFieldPositions.END_POS_FIELD_7])) - self.primary_tc = sensors_data[0] + message['message'][MsgFieldPositions.START_POS_FIELD_7:MsgFieldPositions.END_POS_FIELD_7]))[0] + self.temperature_sensors[TemperatureSensorsNames.PRIMARY_HEATER_THERMOCOUPLE.name] = sensors_data sensors_data = struct.unpack('f', bytearray( - message['message'][MsgFieldPositions.START_POS_FIELD_8:MsgFieldPositions.END_POS_FIELD_8])) - self.trimmer_tc = sensors_data[0] + message['message'][MsgFieldPositions.START_POS_FIELD_8:MsgFieldPositions.END_POS_FIELD_8]))[0] + self.temperature_sensors[TemperatureSensorsNames.TRIMMER_HEATER_THERMOCOUPLE.name] = sensors_data sensors_data = struct.unpack('f', bytearray( - message['message'][MsgFieldPositions.START_POS_FIELD_9:MsgFieldPositions.END_POS_FIELD_9])) - self.primary_cj = sensors_data[0] + message['message'][MsgFieldPositions.START_POS_FIELD_9:MsgFieldPositions.END_POS_FIELD_9]))[0] + self.temperature_sensors[TemperatureSensorsNames.PRIMARY_HEATER_COLD_JUNCTION.name] = sensors_data sensors_data = struct.unpack('f', bytearray( - message['message'][MsgFieldPositions.START_POS_FIELD_10:MsgFieldPositions.END_POS_FIELD_10])) - self.trimmer_cj = sensors_data[0] + message['message'][MsgFieldPositions.START_POS_FIELD_10:MsgFieldPositions.END_POS_FIELD_10]))[0] + self.temperature_sensors[TemperatureSensorsNames.TRIMMER_HEATER_COLD_JUNCTION.name] = sensors_data sensors_data = struct.unpack('f', bytearray( - message['message'][MsgFieldPositions.START_POS_FIELD_11:MsgFieldPositions.END_POS_FIELD_11])) - self.primary_internal = sensors_data[0] + message['message'][MsgFieldPositions.START_POS_FIELD_11:MsgFieldPositions.END_POS_FIELD_11]))[0] + self.temperature_sensors[TemperatureSensorsNames.PRIMARY_HEATER_INTERNAL.name] = sensors_data sensors_data = struct.unpack('f', bytearray( - message['message'][MsgFieldPositions.START_POS_FIELD_12:MsgFieldPositions.END_POS_FIELD_12])) - self.trimmer_internal = sensors_data[0] + message['message'][MsgFieldPositions.START_POS_FIELD_12:MsgFieldPositions.END_POS_FIELD_12]))[0] + self.temperature_sensors[TemperatureSensorsNames.TRIMMER_HEATER_INTERNAL.name] = sensors_data + sensors_data = struct.unpack('f', bytearray( + message['message'][MsgFieldPositions.START_POS_FIELD_13:MsgFieldPositions.END_POS_FIELD_13]))[0] + self.temperature_sensors[TemperatureSensorsNames.FPGA_BOARD_SENSOR.name] = sensors_data + + sensors_data = struct.unpack('f', bytearray( + message['message'][MsgFieldPositions.START_POS_FIELD_14:MsgFieldPositions.END_POS_FIELD_14]))[0] + self.temperature_sensors[TemperatureSensorsNames.LOAD_CELL_A1_B1.name] = sensors_data + + sensors_data = struct.unpack('f', bytearray( + message['message'][MsgFieldPositions.START_POS_FIELD_15:MsgFieldPositions.END_POS_FIELD_15]))[0] + self.temperature_sensors[TemperatureSensorsNames.LOAD_CELL_A2_B2.name] = sensors_data + + sensors_data = struct.unpack('f', bytearray( + message['message'][MsgFieldPositions.START_POS_FIELD_16:MsgFieldPositions.END_POS_FIELD_16]))[0] + self.temperature_sensors[TemperatureSensorsNames.INTERNAL_THDO_RTD.name] = sensors_data + + sensors_data = struct.unpack('f', bytearray( + message['message'][MsgFieldPositions.START_POS_FIELD_17:MsgFieldPositions.END_POS_FIELD_17]))[0] + self.temperature_sensors[TemperatureSensorsNames.INTERNAL_TDI_RTD.name] = sensors_data + + sensors_data = struct.unpack('f', bytearray( + message['message'][MsgFieldPositions.START_POS_FIELD_18:MsgFieldPositions.END_POS_FIELD_18]))[0] + self.temperature_sensors[TemperatureSensorsNames.INTERNAL_COND_TEMP_SENSOR.name] = sensors_data + def cmd_temperature_sensors_broadcast_interval_override(self, ms, reset=NO_RESET): """ Constructs and sends broadcast time interval. @@ -153,7 +199,7 @@ self.logger.debug("Timeout!!!!") return False - def cmd_temperature_sensors_override_value(self, sensor_index, sensor_value, reset=NO_RESET): + def cmd_temperature_sensors_override_value(self, sensor_value, sensor_index, reset=NO_RESET): """ Constructs and sends the value override of a temperature sensor. Constraints: @@ -177,6 +223,12 @@ 9 = Trimmer Heater Cold Junction 10= Primary Heater Internal 11= Trimmer Heater Internal + 12= FPGA board + 13= Load cell A1/B1 + 14= Load cell A2/B2 + 15= Internal THDO RTD + 16= Internal TDI RTD + 17= Internal conductivity temp sensor """ rst = integer_to_bytearray(reset) value = float_to_bytearray(sensor_value) Index: dialin/dg/thermistors.py =================================================================== diff -u -r6b7fe9b82f599b521d8e5d53922bc59841acd899 -rcc425128f399de5414b0aee1942986653ca42c92 --- dialin/dg/thermistors.py (.../thermistors.py) (revision 6b7fe9b82f599b521d8e5d53922bc59841acd899) +++ dialin/dg/thermistors.py (.../thermistors.py) (revision cc425128f399de5414b0aee1942986653ca42c92) @@ -1,83 +1,55 @@ import struct -from ..common.msg_defs import MsgIds +from ..common.msg_defs import MsgIds, MsgFieldPositions from ..protocols.CAN import (DenaliMessage, DenaliChannels) -from ..utils.base import _AbstractSubSystem, _publish -from ..utils.conversions import integer_to_bytearray +from ..utils.base import _AbstractSubSystem, _publish, DialinEnum +from ..utils.conversions import integer_to_bytearray, float_to_bytearray from .constants import RESET, NO_RESET from logging import Logger -import enum +from enum import unique +@unique +class ThermistorsNames(DialinEnum): -class ThermistorsNames(enum.Enum): - THERMISTOR_ONBOARD_NTC = 0 - TEMPSENSOR_FPGA_SENSOR = 1 - TEMPSENSOR_LOAD_CELL_A1_B1 = 2 - TEMPSENSOR_LOAD_CELL_A2_B2 = 3 - TEMPSENSOR_INTERNAL_THDO_RTD = 4 - TEMPSENSOR_INTERNAL_TDI_RTD = 5 - TEMPSENSOR_INTERNAL_CONDUCTIVITY = 6 - THERMISTOR_POWER_SUPPLY_1 = 7 - THERMISTOR_POWER_SUPPLY_2 = 8 + THERMISTOR_POWER_SUPPLY_1 = 1 + THERMISTOR_POWER_SUPPLY_2 = 2 - @classmethod - def has_value(cls, value): - return value in cls._value2member_map_ - class Thermistors(_AbstractSubSystem): """ Dialysate Generation (DG) interface for thermistors and board temperature sensors related commands. """ - # Publish message field positions - START_POS_ONBOARD_TEMP = DenaliMessage.PAYLOAD_START_INDEX - END_POS_ONBOARD_TEMP = START_POS_ONBOARD_TEMP + 4 - START_POS_FPGA_SENSOR = END_POS_ONBOARD_TEMP - END_POS_FPGA_SENSOR = START_POS_FPGA_SENSOR + 4 - START_POS_LOAD_CELL_A1_B1 = END_POS_FPGA_SENSOR - END_POS_LOAD_CELL_A1_B1 = START_POS_LOAD_CELL_A1_B1 + 4 - START_POS_LOAD_CELL_A2_B2 = END_POS_LOAD_CELL_A1_B1 - END_POS_LOAD_CELL_A2_B2 = START_POS_LOAD_CELL_A2_B2 + 4 - START_POS_THDO_RTD = END_POS_LOAD_CELL_A2_B2 - END_POS_THDO_RTD = START_POS_THDO_RTD + 4 - START_POS_TDI_RTD = END_POS_THDO_RTD - END_POS_TDI_RTD = START_POS_TDI_RTD + 4 - START_POS_INTRNL_CONDUCTIVITY = END_POS_TDI_RTD - END_POS_INTRNL_CONDUCTIVITY = START_POS_INTRNL_CONDUCTIVITY + 4 - START_POS_PWR_SUPPLY_1 = END_POS_INTRNL_CONDUCTIVITY - END_POS_PWR_SUPPLY_1 = START_POS_PWR_SUPPLY_1 + 4 - START_POS_PWR_SUPPLY_2 = END_POS_PWR_SUPPLY_1 - END_POS_PWR_SUPPLY_2 = START_POS_PWR_SUPPLY_2 + 4 - def __init__(self, can_interface, logger: Logger): """ @param can_interface: Denali CAN Messenger object """ super().__init__() + self.can_interface = can_interface self.logger = logger + # Dictionary of the thermistors + self.thermistors = {ThermistorsNames.THERMISTOR_ONBOARD_NTC.name: {}, + ThermistorsNames.THERMISTOR_POWER_SUPPLY_1.name: {}, + ThermistorsNames.THERMISTOR_POWER_SUPPLY_2.name: {}} if self.can_interface is not None: channel_id = DenaliChannels.dg_sync_broadcast_ch_id msg_id = MsgIds.MSG_ID_DG_THERMISTORS_DATA.value self.can_interface.register_receiving_publication_function(channel_id, msg_id, self._handler_thermistors_sync) - # Dictionary of the thermistors - self.thermistors = {ThermistorsNames.THERMISTOR_ONBOARD_NTC.name: {}, - ThermistorsNames.TEMPSENSOR_FPGA_SENSOR.name: {}, - ThermistorsNames.TEMPSENSOR_LOAD_CELL_A1_B1.name: {}, - ThermistorsNames.TEMPSENSOR_LOAD_CELL_A2_B2.name: {}, - ThermistorsNames.TEMPSENSOR_INTERNAL_THDO_RTD.name: {}, - ThermistorsNames.TEMPSENSOR_INTERNAL_TDI_RTD.name: {}, - ThermistorsNames.TEMPSENSOR_INTERNAL_CONDUCTIVITY.name: {}, - ThermistorsNames.THERMISTOR_POWER_SUPPLY_1.name: {}, - ThermistorsNames.THERMISTOR_POWER_SUPPLY_2.name: {}} + def get_temperature(self, thermistor): + """ + Gets a thermistor's value + @return: The temperature of a thermistor + """ + return self.thermistors[thermistor] + @_publish(['thermistors']) def _handler_thermistors_sync(self, message): """ @@ -87,47 +59,31 @@ @return: none """ onboard_temp = struct.unpack('f', bytearray( - message['message'][self.START_POS_ONBOARD_TEMP:self.END_POS_ONBOARD_TEMP]))[0] - fpga_temp = struct.unpack('f', bytearray( - message['message'][self.START_POS_FPGA_SENSOR:self.END_POS_FPGA_SENSOR]))[0] - ld_cell_a1 = struct.unpack('f', bytearray( - message['message'][self.START_POS_LOAD_CELL_A1_B1:self.END_POS_LOAD_CELL_A1_B1]))[0] - ld_cell_a2 = struct.unpack('f', bytearray( - message['message'][self.START_POS_LOAD_CELL_A2_B2:self.END_POS_LOAD_CELL_A2_B2]))[0] - thdo_rtd = struct.unpack('f', bytearray( - message['message'][self.START_POS_THDO_RTD:self.END_POS_THDO_RTD]))[0] - tdi_rtd = struct.unpack('f', bytearray( - message['message'][self.START_POS_TDI_RTD:self.END_POS_TDI_RTD]))[0] - conductivity = struct.unpack('f', bytearray( - message['message'][self.START_POS_INTRNL_CONDUCTIVITY:self.END_POS_INTRNL_CONDUCTIVITY]))[0] + message['message'][MsgFieldPositions.START_POS_FIELD_1:MsgFieldPositions.END_POS_FIELD_1]))[0] pwr_supply_1 = struct.unpack('f', bytearray( - message['message'][self.START_POS_PWR_SUPPLY_1:self.END_POS_PWR_SUPPLY_1]))[0] + message['message'][MsgFieldPositions.START_POS_FIELD_2:MsgFieldPositions.END_POS_FIELD_2]))[0] pwr_supply_2 = struct.unpack('f', bytearray( - message['message'][self.START_POS_PWR_SUPPLY_2:self.END_POS_PWR_SUPPLY_2]))[0] + message['message'][MsgFieldPositions.START_POS_FIELD_3:MsgFieldPositions.END_POS_FIELD_3]))[0] self.thermistors[ThermistorsNames.THERMISTOR_ONBOARD_NTC.name] = onboard_temp - self.thermistors[ThermistorsNames.TEMPSENSOR_FPGA_SENSOR.name] = fpga_temp - self.thermistors[ThermistorsNames.TEMPSENSOR_LOAD_CELL_A1_B1.name] = ld_cell_a1 - self.thermistors[ThermistorsNames.TEMPSENSOR_LOAD_CELL_A2_B2.name] = ld_cell_a2 - self.thermistors[ThermistorsNames.TEMPSENSOR_INTERNAL_THDO_RTD.name] = thdo_rtd - self.thermistors[ThermistorsNames.TEMPSENSOR_INTERNAL_TDI_RTD.name] = tdi_rtd - self.thermistors[ThermistorsNames.TEMPSENSOR_INTERNAL_CONDUCTIVITY.name] = conductivity self.thermistors[ThermistorsNames.THERMISTOR_POWER_SUPPLY_1.name] = pwr_supply_1 self.thermistors[ThermistorsNames.THERMISTOR_POWER_SUPPLY_2.name] = pwr_supply_2 - def cmd_thermistors_value_override(self, thermistor, value, reset=NO_RESET): + def cmd_thermistors_value_override(self, value, thermistor, reset=NO_RESET): """ Constructs and sends the thermistors value override command + Constraints: + Must be logged into DG. - @param thermistor: integer - thermistor index + @param thermistor: integer - thermistor index @param value: float the temperature to be set """ reset_value = integer_to_bytearray(reset) + vlu = float_to_bytearray(value) thr = integer_to_bytearray(thermistor) - vlu = integer_to_bytearray(value) - payload = reset_value + thr + vlu + payload = reset_value + vlu + thr - message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_hd_ch_id, + message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_dg_ch_id, message_id=MsgIds.MSG_ID_DG_THERMISTORS_VALUE_OVERRIDE.value, payload=payload) # Send message Index: dialin/dg/uv_reactors.py =================================================================== diff -u -r6b7fe9b82f599b521d8e5d53922bc59841acd899 -rcc425128f399de5414b0aee1942986653ca42c92 --- dialin/dg/uv_reactors.py (.../uv_reactors.py) (revision 6b7fe9b82f599b521d8e5d53922bc59841acd899) +++ dialin/dg/uv_reactors.py (.../uv_reactors.py) (revision cc425128f399de5414b0aee1942986653ca42c92) @@ -2,56 +2,41 @@ import struct from ..utils.conversions import integer_to_bytearray from .constants import NO_RESET, RESET -from ..common.msg_defs import MsgIds +from ..common.msg_defs import MsgIds, MsgFieldPositions from ..protocols.CAN import (DenaliMessage, DenaliChannels) -from ..utils.base import _AbstractSubSystem, _publish +from ..utils.base import _AbstractSubSystem, _publish, DialinEnum from logging import Logger -import enum +from enum import unique -class ReactorsNames(enum.Enum): +@unique +class ReactorsNames(DialinEnum): INLET_UV_REACTOR = 0 OUTLET_UV_REACTOR = 1 - @classmethod - def has_value(cls, value): - return value in cls._value2member_map_ +@unique +class ReactorsStates(DialinEnum): -class ReactorsStates(enum.Enum): - UV_REACTOR_STATE_OFF = 0 UV_REACTOR_STATE_ON = 1 - @classmethod - def has_value(cls, value): - return value in cls._value2member_map_ - class UVReactors(_AbstractSubSystem): """ + Dialysate Generator (DG) Dialin API sub-class for UV reactors related commands. """ - START_POS_INLET_REACTOR_HEALTH = DenaliMessage.PAYLOAD_START_INDEX - END_POS_INLET_REACTOR_HEALTH = START_POS_INLET_REACTOR_HEALTH + 4 - START_POS_OUTLET_REACTOR_HEALTH = END_POS_INLET_REACTOR_HEALTH - END_POS_OUTLET_REACTOR_HEALTH = START_POS_OUTLET_REACTOR_HEALTH + 4 - - START_POS_INLET_REACTOR_STATE = END_POS_OUTLET_REACTOR_HEALTH - END_POS_INLET_REACTOR_STATE = START_POS_INLET_REACTOR_STATE + 4 - - START_POS_OUTLET_REACTOR_STATE = END_POS_INLET_REACTOR_STATE - END_POS_OUTLET_REACTOR_STATE = START_POS_OUTLET_REACTOR_STATE + 4 - def __init__(self, can_interface, logger: Logger): """ @param can_interface: Denali CAN Messenger object """ super().__init__() + self.can_interface = can_interface self.logger = logger @@ -66,6 +51,38 @@ self.inlet_uv_reactor_state = 0.0 self.outlet_uv_reactor_state = 0.0 + def get_inlet_uv_reactor_health(self): + """ + Gets the inlet UV reactor health + + @return: Inlet UV reactor health + """ + return self.inlet_uv_reactor_health + + def get_outlet_uv_reactor_health(self): + """ + Gets the outlet UV reactor health + + @return: Outlet UV reactor health + """ + return self.outlet_uv_reactor_health + + def get_inlet_uv_reactor_state(self): + """ + Gets the inlet UV reactor state + + @return: Inlet UV reactor state + """ + return self.inlet_uv_reactor_state + + def get_outlet_uv_reactor_state(self): + """ + Gets the outlet UV reactor state + + @return: Outlet UV reactor state + """ + return self.outlet_uv_reactor_state + @_publish(['inlet_uv_reactor_health', 'outlet_uv_reactor_health', 'inlet_uv_reactor_state', 'outlet_uv_reactor_state']) def _handler_uv_reactors_sync(self, message): @@ -76,13 +93,13 @@ @return: none """ inlet_health = struct.unpack('f', bytearray( - message['message'][self.START_POS_INLET_REACTOR_HEALTH:self.END_POS_INLET_REACTOR_HEALTH]))[0] + message['message'][MsgFieldPositions.START_POS_FIELD_1:MsgFieldPositions.END_POS_FIELD_1]))[0] outlet_health = struct.unpack('f', bytearray( - message['message'][self.START_POS_OUTLET_REACTOR_HEALTH:self.END_POS_OUTLET_REACTOR_HEALTH]))[0] + message['message'][MsgFieldPositions.START_POS_FIELD_2:MsgFieldPositions.END_POS_FIELD_2]))[0] inlet_state = struct.unpack('f', bytearray( - message['message'][self.START_POS_INLET_REACTOR_STATE:self.END_POS_INLET_REACTOR_STATE]))[0] + message['message'][MsgFieldPositions.START_POS_FIELD_3:MsgFieldPositions.END_POS_FIELD_3]))[0] outlet_state = struct.unpack('f', bytearray( - message['message'][self.START_POS_OUTLET_REACTOR_STATE:self.END_POS_OUTLET_REACTOR_STATE]))[0] + message['message'][MsgFieldPositions.START_POS_FIELD_4:MsgFieldPositions.END_POS_FIELD_4]))[0] self.inlet_uv_reactor_health = inlet_health self.outlet_uv_reactor_health = outlet_health @@ -135,9 +152,11 @@ self.logger.debug("Timeout!!!!") return False - def cmd_uv_reactors_health_override(self, reactor, health, reset=NO_RESET): + def cmd_uv_reactors_health_override(self, health, reactor, reset=NO_RESET): """ - Constructs and sends the UV reactors' health override command + Constructs and sends the UV reactors' health override command. + Constraints: + Must be logged into DG. @param reactor: integer - UV reactor index @param health: integer - health to be set ot @@ -167,14 +186,14 @@ \returns 1 if successful, zero otherwise """ - if state == ReactorsStates.UV_REACTOR_STATE_ON: + if state == ReactorsStates.UV_REACTOR_STATE_ON.name: payload = integer_to_bytearray(1) operation = 'Turning on ' else: payload = integer_to_bytearray(0) operation = 'Turning off ' - message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_hd_ch_id, + message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_dg_ch_id, message_id=MsgIds.MSG_ID_DG_START_STOP_INLET_UV_REACTOR.value, payload=payload) # Send message Index: tests/dg_heat_disinfect_test.py =================================================================== diff -u -r363867c876456821000c189f86fbb55b4d583c50 -rcc425128f399de5414b0aee1942986653ca42c92 --- tests/dg_heat_disinfect_test.py (.../dg_heat_disinfect_test.py) (revision 363867c876456821000c189f86fbb55b4d583c50) +++ tests/dg_heat_disinfect_test.py (.../dg_heat_disinfect_test.py) (revision cc425128f399de5414b0aee1942986653ca42c92) @@ -8,20 +8,25 @@ from dialin.dg.drain_pump import DrainPumpStates from dialin.dg.thermistors import Thermistors from dialin.dg.uv_reactors import ReactorsStates +from dialin.dg.thermistors import ThermistorsNames from time import sleep - if __name__ == "__main__": dg = DG(log_level='DEBUG') dg.cmd_log_in_to_dg() - dg.uv_reactors.cmd_start_stop_inlet_uv_reactor(state=ReactorsStates.UV_REACTOR_STATE_ON.name) + #dg.uv_reactors.cmd_start_stop_inlet_uv_reactor(state=ReactorsStates.UV_REACTOR_STATE_ON.name) + #sleep(1) + dg.thermistors.cmd_thermistors_value_override(52.2, ThermistorsNames.THERMISTOR_ONBOARD_NTC.value, reset=1) + sleep(2) while True: - sleep(1) - print(dg.thermistors.onboard_temperature) + print(dg.thermistors.thermistors[ThermistorsNames.THERMISTOR_ONBOARD_NTC.name], + dg.fans.target_duty_cycle, dg.fans.inlet_1_rpm, dg.fans.inlet_2_rpm) + sleep(0.5) + f = open("Heat_disinfection.txt", "w") #dg.drain_pump.cmd_drain_pump_speed_set_point_override(2800) Index: tests/test_uf.py =================================================================== diff -u -rfbe3580dfcda2338d9fa33d09bee85099ea7b801 -rcc425128f399de5414b0aee1942986653ca42c92 --- tests/test_uf.py (.../test_uf.py) (revision fbe3580dfcda2338d9fa33d09bee85099ea7b801) +++ tests/test_uf.py (.../test_uf.py) (revision cc425128f399de5414b0aee1942986653ca42c92) @@ -57,7 +57,7 @@ pumpSetPts = ", B.s, " + '{:4d}'.format(hd.bloodflow.target_blood_flow_rate) + \ ", DI.s, " + '{:4d}'.format(hd.dialysate_inlet_flow.target_dialysate_inlet_flow_rate) + \ ", RO.s, " + '{:4d}'.format(dg.ro_pump.target_pressure_psi) + \ - ", DR.s, " + '{:5d}'.format(dg.drain_pump.target_drain_pump_RPM) + ", DR.s, " + '{:5d}'.format(dg.drain_pump.target_drain_pump_rpm) pumpMeasSpds = ", B.m, " + '{:7.1f}'.format(hd.bloodflow.measured_blood_pump_speed) + \ ", B.r, " + '{:6.1f}'.format(hd.bloodflow.measured_blood_pump_rotor_speed) + \ ", B.f, " + '{:7.1f}'.format(hd.bloodflow.measured_blood_flow_rate) + \