Index: dialin/dg/chemical_disinfect.py =================================================================== diff -u -r1261e3824e07dc805e6bf3d73c5ee340bb88fc15 -r597b213629a8243dd0d76ee5fe16f7b83e64483f --- dialin/dg/chemical_disinfect.py (.../chemical_disinfect.py) (revision 1261e3824e07dc805e6bf3d73c5ee340bb88fc15) +++ dialin/dg/chemical_disinfect.py (.../chemical_disinfect.py) (revision 597b213629a8243dd0d76ee5fe16f7b83e64483f) @@ -23,15 +23,16 @@ DG_CHEM_DISINFECT_STATE_DISINFECT_R1_TO_R2 = 10 DG_CHEM_DISINFECT_STATE_FILL_R2_WITH_DISINFECTANT = 11 DG_CHEM_DISINFECT_STATE_DISINFECT_R2_TO_R1 = 12 - DG_CHEM_DISINFECT_STATE_DISINFECTANT_DRAIN_R1 = 13 - DG_CHEM_DISINFECT_STATE_DISINFECTANT_DRAIN_R2 = 14 - DG_CHEM_DISINFECT_STATE_RINSE_R1_TO_R2 = 15 - DG_CHEM_DISINFECT_STATE_RINSE_R2_TO_R1_AND_DRAIN_R1 = 16 - DG_CHEM_DISINFECT_STATE_RINSE_R1_TO_R2_AND_DRAIN_R2 = 17 - DG_CHEM_DISINFECT_STATE_RINSE_CIRCULATION = 18 - DG_CHEM_DISINFECT_STATE_CANCEL_BASIC_PATH = 19 - DG_CHEM_DISINFECT_STATE_CANCEL_WATER_PATH = 20 - DG_CHEM_DISINFECT_STATE_COMPLETE = 21 + DG_CHEM_DISINFECT_STATE_COOL_DOWN_HEATERS = 13 + DG_CHEM_DISINFECT_STATE_DISINFECTANT_DRAIN_R1 = 14 + DG_CHEM_DISINFECT_STATE_DISINFECTANT_DRAIN_R2 = 15 + DG_CHEM_DISINFECT_STATE_RINSE_R1_TO_R2 = 16 + DG_CHEM_DISINFECT_STATE_RINSE_R2_TO_R1_AND_DRAIN_R1 = 17 + DG_CHEM_DISINFECT_STATE_RINSE_R1_TO_R2_AND_DRAIN_R2 = 18 + DG_CHEM_DISINFECT_STATE_RINSE_CIRCULATION = 19 + DG_CHEM_DISINFECT_STATE_CANCEL_BASIC_PATH = 20 + DG_CHEM_DISINFECT_STATE_CANCEL_WATER_PATH = 21 + DG_CHEM_DISINFECT_STATE_COMPLETE = 22 @unique @@ -64,6 +65,8 @@ self.cancellation_mode = 0 self.r1_level = 0 self.r2_level = 0 + self.target_post_rinse_count = 0 + self.current_post_rinse_count = 0 if self.can_interface is not None: channel_id = DenaliChannels.dg_sync_broadcast_ch_id @@ -72,7 +75,7 @@ self._handler_chemical_disinfect_sync) @_publish(["chemical_disinfect_state", "overall_elapsed_time", "state_elapsed_time", "cancellation_mode", - "r1_level", "r2_level"]) + "r1_level", "r2_level", "target_post_rinse_count", "current_post_rinse_count"]) def _handler_chemical_disinfect_sync(self, message): """ Handles published chemical disinfect message @@ -94,12 +97,17 @@ 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] + target_post_rinse_cnt = struct.unpack('i', bytearray( + message['message'][MsgFieldPositions.START_POS_FIELD_8:MsgFieldPositions.END_POS_FIELD_8]))[0] + current_post_rinse_cnt = struct.unpack('i', bytearray( + message['message'][MsgFieldPositions.START_POS_FIELD_9:MsgFieldPositions.END_POS_FIELD_9]))[0] self.chemical_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 \ No newline at end of file + self.r2_level = r2 + self.target_post_rinse_count = target_post_rinse_cnt + self.current_post_rinse_count = current_post_rinse_cnt \ No newline at end of file Index: dialin/dg/dialysate_generator.py =================================================================== diff -u -rf876b77eab64261c89b8928b038e18de8125742a -r597b213629a8243dd0d76ee5fe16f7b83e64483f --- dialin/dg/dialysate_generator.py (.../dialysate_generator.py) (revision f876b77eab64261c89b8928b038e18de8125742a) +++ dialin/dg/dialysate_generator.py (.../dialysate_generator.py) (revision 597b213629a8243dd0d76ee5fe16f7b83e64483f) @@ -41,12 +41,29 @@ from .valves import DGValves from ..utils.conversions import integer_to_bytearray from ..protocols.CAN import (DenaliCanMessenger, DenaliMessage, DenaliChannels) -from ..utils.base import _AbstractSubSystem, _publish, _LogManager +from ..utils.base import _AbstractSubSystem, _publish, _LogManager, DialinEnum from ..common.msg_defs import MsgIds, MsgFieldPositions from .flush import FlushMode from .chemical_disinfect import ChemicalDisinfect +from enum import unique +@unique +class DGOperationModes(DialinEnum): + # DG operation modes + DG_OP_MODE_FAULT = 0 + DG_OP_MODE_SERVICE = 1 + DG_OP_MODE_INIT_POST = 2 + DG_OP_MODE_STANDBY = 3 + DG_OP_MODE_STANDBY_SOLO = 4 + DG_OP_MODE_RECIRCULATE = 5 + DG_OP_MODE_FILL = 6 + DG_OP_MODE_DRAIN = 7 + DG_OP_MODE_FLUSH = 8 + DG_OP_MODE_DISINFECT = 9 + DG_OP_MODE_CHEMICAL_DISINFECT = 10 + + class DG(_AbstractSubSystem): """ Dialysate Generator (DG) Dialin object API. It provides the basic interface to communicate with @@ -76,19 +93,6 @@ START_POS_FPGA_LAB = END_POS_FPGA_MINOR END_POS_FPGA_LAB = START_POS_FPGA_LAB + 1 - # DG operation modes - DG_OP_MODE_FAULT = 0 - DG_OP_MODE_SERVICE = 1 - DG_OP_MODE_INIT_POST = 2 - DG_OP_MODE_STANDBY = 3 - DG_OP_MODE_STANDBY_SOLO = 4 - DG_OP_MODE_RECIRCULATE = 5 - DG_OP_MODE_FILL = 6 - DG_OP_MODE_DRAIN = 7 - DG_OP_MODE_FLUSH = 8 - DG_OP_MODE_DISINFECT = 9 - DG_OP_MODE_CHEMICAL_DISINFECT = 10 - # DG sub_modes DG_POST_STATE_START = 0 # Start initialize & POST mode state DG_POST_STATE_FPGA = 1 # FPGA POST test state @@ -137,7 +141,7 @@ self.dg_version = None self.fpga_version = None # create properties - self.dg_operation_mode = self.DG_OP_MODE_INIT_POST + self.dg_operation_mode = 0 #self.DG_OP_MODE_INIT_POST self.dg_operation_sub_mode = 0 # Create command groups Index: dialin/dg/hd_proxy.py =================================================================== diff -u -rf876b77eab64261c89b8928b038e18de8125742a -r597b213629a8243dd0d76ee5fe16f7b83e64483f --- dialin/dg/hd_proxy.py (.../hd_proxy.py) (revision f876b77eab64261c89b8928b038e18de8125742a) +++ dialin/dg/hd_proxy.py (.../hd_proxy.py) (revision 597b213629a8243dd0d76ee5fe16f7b83e64483f) @@ -105,20 +105,20 @@ self.logger.debug("Timeout!!!!") return False - def cmd_drain(self, volume:int=200, tareLoadCell:bool=False) -> int: + def cmd_drain(self, volume:int=200, tare_load_cell:bool=False) -> int: """ Constructs and sends the drain command. Constraints: DG must be in re-circulate mode. Given drain to volume must be between 0 and 1950 mL. @param volume: unsigned int - volume (in mL) to drain the inactive reservoir to. - @param tareLoadCell: bool - flag indicates to tare loadcell. + @param tare_load_cell: bool - flag indicates to tare loadcell. @return: 1 if successful, zero otherwise """ vol = integer_to_bytearray(volume) - tare = integer_to_bytearray(tareLoadCell) + tare = integer_to_bytearray(tare_load_cell) payload = vol + tare message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_dg_ch_id, Index: dialin/hd/valves.py =================================================================== diff -u -r1261e3824e07dc805e6bf3d73c5ee340bb88fc15 -r597b213629a8243dd0d76ee5fe16f7b83e64483f --- dialin/hd/valves.py (.../valves.py) (revision 1261e3824e07dc805e6bf3d73c5ee340bb88fc15) +++ dialin/hd/valves.py (.../valves.py) (revision 597b213629a8243dd0d76ee5fe16f7b83e64483f) @@ -401,4 +401,4 @@ 'PosA': pos_a, 'PosB': pos_b, 'PosC': pos_c, 'PWM': pwm} if AirTrapState.has_value(air_trap): - self.hd_air_trap_status = AirTrapState(air_trap).name + self.hd_air_trap_status = AirTrapState(air_trap).value Index: tests/dg_heat_and_chemical_disinfect_test.py =================================================================== diff -u -r1261e3824e07dc805e6bf3d73c5ee340bb88fc15 -r597b213629a8243dd0d76ee5fe16f7b83e64483f --- tests/dg_heat_and_chemical_disinfect_test.py (.../dg_heat_and_chemical_disinfect_test.py) (revision 1261e3824e07dc805e6bf3d73c5ee340bb88fc15) +++ tests/dg_heat_and_chemical_disinfect_test.py (.../dg_heat_and_chemical_disinfect_test.py) (revision 597b213629a8243dd0d76ee5fe16f7b83e64483f) @@ -8,18 +8,21 @@ from dialin.dg.drain_pump import DrainPumpStates from dialin.dg.thermistors import ThermistorsNames from dialin.dg.temperature_sensors import TemperatureSensorsNames +from dialin.dg.dialysate_generator import DGOperationModes from time import sleep def get_chemical_disinfect_mode_info(): 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} ' + 'Cancellation_mode, {}, R1_level, {:5.3f}, R1_drift, {:5.3f}, R2_level, {:5.3f}, R2_drift, {:5.3f}, ' + 'Current_rinse_count, {}, Total_rinse_count, {}, ' .format(ChemicalDisinfectStates(dg.chemical_disinfect.chemical_disinfect_state).name, dg.chemical_disinfect.overall_elapsed_time, dg.chemical_disinfect.state_elapsed_time, dg.chemical_disinfect.disinfect_elapsed_time, CancellationModes(dg.chemical_disinfect.cancellation_mode).name, dg.chemical_disinfect.r1_level, (dg.chemical_disinfect.r1_level - dg.load_cells.load_cell_A1), dg.chemical_disinfect.r2_level, - (dg.chemical_disinfect.r2_level - dg.load_cells.load_cell_B1))) + (dg.chemical_disinfect.r2_level - dg.load_cells.load_cell_B1), + dg.chemical_disinfect.current_post_rinse_count, dg.chemical_disinfect.target_post_rinse_count)) return info @@ -41,9 +44,17 @@ return info +def get_dg_run_info(): + + info = ('DG_op_mode, {}, DG_sub_mode, {}, '.format(DGOperationModes(dg.dg_operation_mode).name, + dg.dg_operation_sub_mode)) + return info + + def get_dg_valves_states(): info = ('VPi, {}, VSP, {}, VPd, {}, VBf, {}, VPo, {}, VDr, {}, VRc, {}, VRo, {}, VRd, {}, VRi, {}, VRf, {}, ' + 'VRD1, {}, VRD2, {}, ' .format(dg.valves.valve_states_enum[dg.valves.VALVE_PRESSURE_INLET], dg.valves.valve_states_enum[dg.valves.VALVE_SAMPLING_PORT], dg.valves.valve_states_enum[dg.valves.VALVE_PRODUCTION_DRAIN], @@ -54,15 +65,17 @@ dg.valves.valve_states_enum[dg.valves.VALVE_RESERVOIR_OUTLET], dg.valves.valve_states_enum[dg.valves.VALVE_RESERVOIR_DRAIN], dg.valves.valve_states_enum[dg.valves.VALVE_RESERVOIR_INLET], - dg.valves.valve_states_enum[dg.valves.VALVE_RESERVOIR_FILL])) + dg.valves.valve_states_enum[dg.valves.VALVE_RESERVOIR_FILL], + dg.valves.valve_states_enum[dg.valves.VALVE_RESERVOIR_DRAIN_1], + dg.valves.valve_states_enum[dg.valves.VALVE_RESERVOIR_DRAIN_2])) return info def get_drain_states_info(): - 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.drain_pump.current_drain_pump_rpm, + info = ('Drain, {}, DAC, {}, Tgt_RPM, {}, Curr_RPM, {}, PRd, {:5.3f}, PDr, {:5.3f}, '. + format(DrainPumpStates(dg.drain_pump.drain_pump_state).name, dg.drain_pump.dac_value, + dg.drain_pump.target_drain_pump_rpm, dg.drain_pump.current_drain_pump_rpm, dg.pressures.drain_pump_inlet_pressure, dg.pressures.drain_pump_outlet_pressure)) return info @@ -131,17 +144,67 @@ return info +def run_dg(): + + counter = 1 + f = open("/home/fw/projects/dialin/tests/run_dg.log", "w") + dg.hd_proxy.cmd_start_stop_dg() + sleep(0.2) + + try: + while True: + + dg_run = get_dg_run_info() + load_cell = get_load_cells_info() + drain = get_drain_states_info() + ro = get_ro_info() + valves = get_dg_valves_states() + + var = dg_run + load_cell + drain + ro + valves + '\r' + + print(var) + f.write(var) + + if DGOperationModes(dg.dg_operation_mode).name == DGOperationModes.DG_OP_MODE_RECIRCULATE.name and\ + dg.dg_operation_sub_mode == 2 and counter == 1: + dg.hd_proxy.cmd_switch_reservoirs(reservoirID=1) + sleep(3) + dg.hd_proxy.cmd_drain(tare_load_cell=True) + counter += 1 + sleep(0.15) + + if DGOperationModes(dg.dg_operation_mode).name == DGOperationModes.DG_OP_MODE_RECIRCULATE.name and\ + dg.dg_operation_sub_mode == 2 and counter == 2: + dg.hd_proxy.cmd_fill(volume=1200) + counter += 1 + sleep(0.15) + + if DGOperationModes(dg.dg_operation_mode).name == DGOperationModes.DG_OP_MODE_RECIRCULATE.name and\ + dg.dg_operation_sub_mode == 2 and counter == 3: + #dg.hd_proxy.cmd_switch_reservoirs(reservoirID=0) + dg.ro_pump.cmd_ro_pump_duty_cycle_pct(0) + sleep(3) + dg.hd_proxy.cmd_drain() + counter += 1 + sleep(0.15) + + sleep(1) + + except KeyboardInterrupt: + dg.hd_proxy.cmd_start_stop_dg(start=False) + f.close() + + def run_heat_disinfect(): complete_counter = 1 f = open("/home/fw/projects/dialin/tests/Heat_disinfect.log", "w") dg.hd_proxy.cmd_start_stop_heat_disinfect() - #dg.hd_proxy.cmd_start_stop_dg() try: while True: - disinfect = get_heat_disinfect_mode_info() + disinfect = get_dg_run_info() drain = get_drain_states_info() load_cell = get_load_cells_info() valves = get_dg_valves_states() @@ -156,7 +219,6 @@ f.write(var) sleep(1) - # If the mode came back to standby or standby solo if dg.dg_operation_mode == 3 or dg.dg_operation_mode == 4: # If it is the first call, stop heat disinfect @@ -171,10 +233,8 @@ complete_counter += 1 - except KeyboardInterrupt: dg.hd_proxy.cmd_start_stop_heat_disinfect(start=False) - #dg.hd_proxy.cmd_start_stop_dg(start=False) f.close() @@ -226,8 +286,10 @@ dg.cmd_log_in_to_dg() sleep(1) - run_heat_disinfect() + #run_heat_disinfect() #run_chemical_disinfect() + run_dg() +