Index: dialin/dg/heat_disinfect.py =================================================================== diff -u -r8b1cfa3f0a1be1130d7ffd5761df7c0a1c3a5164 -r46d493e1025a7262f51e227319fc2a60b89bbe54 --- dialin/dg/heat_disinfect.py (.../heat_disinfect.py) (revision 8b1cfa3f0a1be1130d7ffd5761df7c0a1c3a5164) +++ dialin/dg/heat_disinfect.py (.../heat_disinfect.py) (revision 46d493e1025a7262f51e227319fc2a60b89bbe54) @@ -26,15 +26,24 @@ DG_HEAT_DISINFECT_STATE_DISINFECT_R2_TO_R1 = 12 DG_HEAT_DISINFECT_STATE_MIX_DRAIN_R1 = 13 DG_HEAT_DISINFECT_STATE_MIX_DRAIN_R2 = 14 - DG_HEAT_DISINFECT_STATE_RINSE_R1_TO_R2 = 15 - DG_HEAT_DISINFECT_STATE_RINSE_R2_TO_R1_AND_DRAIN_R1 = 16 - DG_HEAT_DISINFECT_STATE_RINSE_CIRCULATION = 17 - DG_HEAT_DISINFECT_STATE_CANCEL_MODE_BASIC_PATH = 18 - DG_HEAT_DISINFECT_STATE_CANCEL_MODE_COLD_WATER_PATH = 19 - DG_HEAT_DISINFECT_STATE_CANCEL_MODE_HOT_WATER_PATH = 20 + DG_HEAT_DISINFECT_STATE_COOL_DOWN_RO_FILTER = 15 + DG_HEAT_DISINFECT_STATE_RINSE_R1_TO_R2 = 16 + DG_HEAT_DISINFECT_STATE_RINSE_R2_TO_R1_AND_DRAIN_R1 = 17 + DG_HEAT_DISINFECT_STATE_RINSE_CIRCULATION = 18 + DG_HEAT_DISINFECT_STATE_CANCEL_BASIC_PATH = 19 + DG_HEAT_DISINFECT_STATE_CANCEL_WATER_PATH = 20 DG_HEAT_DISINFECT_STATE_COMPLETE = 21 +@unique +class CancellationModes(DialinEnum): + + CANCELLATION_MODE_NONE = 0 + CANCELLATION_MODE_BASIC = 1 + CANCELLATION_MODE_HOT = 2 + CANCELLATION_MODE_COLD = 3 + + class HeatDisinfect(_AbstractSubSystem): """ \class HeatDisinfect @@ -49,18 +58,22 @@ self.can_interface = can_interface self.logger = logger - self.current_state = 0 + self.heat_disinfect_state = 0 self.overall_elapsed_time = 0 self.state_elapsed_time = 0 - self.current_cycle_count = 0 #TODO remove? + self.disinfect_elapsed_time = 0 + self.cancellation_mode = 0 + self.r1_level = 0 + self.r2_level = 0 if self.can_interface is not None: channel_id = DenaliChannels.dg_sync_broadcast_ch_id msg_id = MsgIds.MSG_ID_DG_HEAT_DISINFECT_DATA.value self.can_interface.register_receiving_publication_function(channel_id, msg_id, self._handler_heat_disinfect_sync) - @_publish(["current_state", "overall_elapsed_time", "state_elapsed_time"]) + @_publish(["heat_disinfect_state", "overall_elapsed_time", "state_elapsed_time", "cancellation_mode", "r1_level", + "r2_level"]) def _handler_heat_disinfect_sync(self, message): """ Handles published heat disinfection message @@ -74,12 +87,24 @@ message['message'][MsgFieldPositions.START_POS_FIELD_2:MsgFieldPositions.END_POS_FIELD_2]))[0] state_elapsed_time = struct.unpack('i', bytearray( message['message'][MsgFieldPositions.START_POS_FIELD_3:MsgFieldPositions.END_POS_FIELD_3]))[0] + disinfect_elapsed_time = struct.unpack('i', bytearray( + message['message'][MsgFieldPositions.START_POS_FIELD_4:MsgFieldPositions.END_POS_FIELD_4]))[0] + cancellation_mode = struct.unpack('i', bytearray( + message['message'][MsgFieldPositions.START_POS_FIELD_5:MsgFieldPositions.END_POS_FIELD_5]))[0] + r1 = struct.unpack('f', bytearray( + message['message'][MsgFieldPositions.START_POS_FIELD_6:MsgFieldPositions.END_POS_FIELD_6]))[0] + r2 = struct.unpack('f', bytearray( + message['message'][MsgFieldPositions.START_POS_FIELD_7:MsgFieldPositions.END_POS_FIELD_7]))[0] - #TODO remove - self.current_state = state#HeatDisinfectStates(state).name if HeatDisinfectStates.has_value(state) else 'Unknown' + self.heat_disinfect_state = state self.overall_elapsed_time = int(elapsed_time / 1000) self.state_elapsed_time = int(state_elapsed_time / 1000) + self.disinfect_elapsed_time = int(disinfect_elapsed_time / 1000) + self.cancellation_mode = cancellation_mode + self.r1_level = r1 + self.r2_level = r2 + def cmd_start_stop_heat_disinfect(self, start=True): """ Constructs and sends the start/stop DG heat disinfection command Index: tests/dg_heat_disinfect_test.py =================================================================== diff -u -r8b1cfa3f0a1be1130d7ffd5761df7c0a1c3a5164 -r46d493e1025a7262f51e227319fc2a60b89bbe54 --- tests/dg_heat_disinfect_test.py (.../dg_heat_disinfect_test.py) (revision 8b1cfa3f0a1be1130d7ffd5761df7c0a1c3a5164) +++ tests/dg_heat_disinfect_test.py (.../dg_heat_disinfect_test.py) (revision 46d493e1025a7262f51e227319fc2a60b89bbe54) @@ -5,11 +5,8 @@ from dialin.dg.dialysate_generator import DG from dialin.hd.hemodialysis_device import HD from dialin.dg.hd_proxy import DGHDProxy -from dialin.dg.heat_disinfect import HeatDisinfectStates +from dialin.dg.heat_disinfect import HeatDisinfectStates, CancellationModes from dialin.dg.drain_pump import DrainPumpStates -from dialin.dg.ro_pump import ROPumpStates -from dialin.dg.thermistors import Thermistors -from dialin.dg.uv_reactors import ReactorsStates from dialin.dg.thermistors import ThermistorsNames from dialin.dg.temperature_sensors import TemperatureSensorsNames from time import sleep @@ -41,9 +38,14 @@ def get_heat_disinfect_mode_info(): - info = ('State, {}, Overall_time, {}, State_elapsed_time, {}, ' - .format(HeatDisinfectStates(dg.heat_disinfect.current_state).name, dg.heat_disinfect.overall_elapsed_time, - dg.heat_disinfect.state_elapsed_time)) + info = ('State, {}, Overall_elapsed_time, {}, State_elapsed_time, {}, Disinfect_elapsed_time {}, ' + 'Cancellation_mode, {}, R1_level, {:5.3f}, R1_drift, {:5.3f}, R2_level, {:5.3f}, R2_drift, {:5.3f} ' + .format(HeatDisinfectStates(dg.heat_disinfect.heat_disinfect_state).name, + dg.heat_disinfect.overall_elapsed_time, dg.heat_disinfect.state_elapsed_time, + dg.heat_disinfect.disinfect_elapsed_time, + CancellationModes(dg.heat_disinfect.cancellation_mode).name, dg.heat_disinfect.r1_level, + (dg.heat_disinfect.r1_level - dg.load_cells.load_cell_A1), dg.heat_disinfect.r2_level, + (dg.heat_disinfect.r2_level - dg.load_cells.load_cell_B1))) return info @@ -66,49 +68,69 @@ def get_drain_states_info(): - info = ('Drain, {}, DAC, {}, PRd, {:5.3f}, PDr, {:5.3f} '. + info = ('Drain, {}, DAC, {}, RPM, {}, PRd, {:5.3f}, PDr, {:5.3f}, '. format(DrainPumpStates(dg.drain_pump.drain_pump_state).name, - dg.drain_pump.dac_value, dg.pressures.drain_pump_inlet_pressure, dg.pressures.drain_pump_outlet_pressure)) + dg.drain_pump.dac_value, dg.drain_pump.current_drain_pump_rpm, + dg.pressures.drain_pump_inlet_pressure, + dg.pressures.drain_pump_outlet_pressure)) return info def get_load_cells_info(): - info = ('Primary_A1, {:5.3f}, Primary_B1, {:5.3f}, '.format(dg.load_cells.load_cell_A1, dg.load_cells.load_cell_B1)) + info = ('A1, {:5.3f}, A2, {:5.3f}, B1, {:5.3f}, B2, {:5.3f}, '. + format(dg.load_cells.load_cell_A1, dg.load_cells.load_cell_A2, dg.load_cells.load_cell_B1, + dg.load_cells.load_cell_B2)) return info def get_ro_info(): info = ('RO, {}, PPi, {:5.3f}, PPo, {:5.3f}, PWM, {:5.3f}, Flow, {:5.3f}, ' - .format(dg.ro_pump.ro_pump_state, dg.pressures.ro_pump_outlet_pressure, + .format(dg.ro_pump.ro_pump_state, dg.pressures.ro_pump_inlet_pressure, dg.pressures.ro_pump_outlet_pressure, dg.ro_pump.pwm_duty_cycle_pct, dg.ro_pump.measured_flow_rate_lpm)) return info def get_heaters_info(): - info = ('Pri_main_DC, {:5.3f}, Pri_small_DC, {:5.3f}, Trimmer_DC, {:5.3f}, '. + info = ('Pri_main_DC, {:5.3f}, Pri_small_DC, {:5.3f}, Pri_int_temp, {:5.3f}, Trimmer_DC, {:5.3f}, '. format(dg.heaters.main_primary_heater_duty_cycle, dg.heaters.small_primary_heater_duty_cycle, + dg.temperature_sensors.temperature_sensors[TemperatureSensorsNames.PRIMARY_HEATER_INTERNAL.name], dg.heaters.trimmer_heater_duty_cycle)) return info def get_temperature_sensors_info(): info = ('TPi, {:5.3f}, TPo, {:5.3f}, TD1, {:5.3f}, TD2, {:5.3f}, TRo, {:5.3f}, TDi, {:5.3f}, ' - .format(dg.temperature_sensors.temperature_sensors(TemperatureSensorsNames.INLET_PRIMARY_HEATER.name), - dg.temperature_sensors.temperature_sensors(TemperatureSensorsNames.OUTLET_PRIMARY_HEATER.name), - dg.temperature_sensors.temperature_sensors(TemperatureSensorsNames.CONDUCTIVITY_SENSOR_1.name), - dg.temperature_sensors.temperature_sensors(TemperatureSensorsNames.CONDUCTIVITY_SENSOR_2.name), - dg.temperature_sensors.temperature_sensors(TemperatureSensorsNames.OUTLET_DIALYSATE_REDUNDANT.name), - dg.temperature_sensors.temperature_sensors(TemperatureSensorsNames.INLET_DIALYSATE.name))) + .format(dg.temperature_sensors.temperature_sensors[TemperatureSensorsNames.INLET_PRIMARY_HEATER.name], + dg.temperature_sensors.temperature_sensors[TemperatureSensorsNames.OUTLET_PRIMARY_HEATER.name], + dg.temperature_sensors.temperature_sensors[TemperatureSensorsNames.CONDUCTIVITY_SENSOR_1.name], + dg.temperature_sensors.temperature_sensors[TemperatureSensorsNames.CONDUCTIVITY_SENSOR_2.name], + dg.temperature_sensors.temperature_sensors[TemperatureSensorsNames.OUTLET_DIALYSATE_REDUNDANT.name], + dg.temperature_sensors.temperature_sensors[TemperatureSensorsNames.INLET_DIALYSATE.name])) return info +def get_fans_info(): + + info = ('Target_fans_DC, {:5.3f}, Inlet1_RPM, {:5.3f}, Outlet1_RPM, {:5.3f}, ' + 'Inlet2_RPM, {:5.3f}, Outlet2_RPM, {:5.3f}, Inlet3_RPM, {:5.3f}, Outlet3_RPM, {:5.3f}, Board_temp, {:5.3f},' + ' FPGA_temp, {:5.3f}, Load_cell_A1_B1, {:5.3f}, Load_cell_A2_B2, {:5.3f}, ' + .format(dg.fans.target_duty_cycle, dg.fans.inlet_1_rpm, dg.fans.inlet_2_rpm, dg.fans.inlet_2_rpm, + dg.fans.outlet_2_rpm, dg.fans.inlet_3_rpm, dg.fans.outlet_3_rpm, + dg.thermistors.thermistors[ThermistorsNames.THERMISTOR_ONBOARD_NTC.name], + dg.temperature_sensors.temperature_sensors[TemperatureSensorsNames.FPGA_BOARD_SENSOR.name], + dg.temperature_sensors.temperature_sensors[TemperatureSensorsNames.LOAD_CELL_A1_B1.name], + dg.temperature_sensors.temperature_sensors[TemperatureSensorsNames.LOAD_CELL_A2_B2.name])) + return info + + def run_heat_disinfect(): + complete_counter = 1 f = open("Heat_disinfect.log", "w") dg.heat_disinfect.cmd_start_stop_heat_disinfect() try: @@ -121,13 +143,26 @@ ro = get_ro_info() temp = get_temperature_sensors_info() heaters = get_heaters_info() + fans = get_fans_info() - var = disinfect + load_cell + drain + ro + temp + heaters + valves + '\r' + var = disinfect + load_cell + drain + ro + temp + heaters + fans + valves + '\r' print(var) f.write(var) sleep(1) + # If the state is complete + if HeatDisinfectStates(dg.heat_disinfect.heat_disinfect_state).name == 'DG_HEAT_DISINFECT_STATE_COMPLETE': + # If it is the first call, stop heat disinfect + if complete_counter == 1: + dg.heat_disinfect.cmd_start_stop_heat_disinfect(start=False) + # Write a few more complete states to make sure the complete state items are recorded + elif complete_counter == 3: + f.close() + break + + complete_counter += 1 + except KeyboardInterrupt: dg.heat_disinfect.cmd_start_stop_heat_disinfect(start=False) f.close()