Index: dialin/dg/flush.py =================================================================== diff -u --- dialin/dg/flush.py (revision 0) +++ dialin/dg/flush.py (revision 01db18a18769df2048346f868412fc8a12631fc0) @@ -0,0 +1,98 @@ + +import struct +from ..utils.conversions import integer_to_bytearray +from ..common.msg_defs import MsgIds, MsgFieldPositions +from ..protocols.CAN import (DenaliMessage, DenaliChannels) +from ..utils.base import _AbstractSubSystem, _publish, DialinEnum +from logging import Logger +from enum import unique + + +@unique +class FlushStates(DialinEnum): + + DG_FLUSH_STATE_START = 0 + DG_FLUSH_STATE_DRAIN_R1 = 1 + DG_FLUSH_STATE_DRAIN_R2 = 2 + DG_FLUSH_STATE_FLUSH_DRAIN = 3 + DG_FLUSH_STATE_FLUSH_DIALYSATE = 4 + DG_FLUSH_STATE_FLUSH_CONCENTRATE_STRAWS = 5 + DG_FLUSH_STATE_FLUSH_R1_TO_R2 = 6 + DG_FLUSH_STATE_FLUSH_R2_AND_DRAIN_R1 = 7 + DG_FLUSH_STATE_FLUSH_CIRCULATION = 8 + DG_FLUSH_STATE_CANCEL_BASIC_PATH = 9 + DG_FLUSH_STATE_CANCEL_WATER_PATH = 10 + DG_FLUSH_STATE_COMPLETE = 11 + + +class FlushMode(_AbstractSubSystem): + """ + \class Flush Mode + + \brief Flush mode class with APIs to set the timing of each of the stages. + """ + def __init__(self, can_interface, logger: Logger): + + super().__init__() + + self.can_interface = can_interface + self.logger = logger + + self.flush_state = 0 + self.overall_elapsed_time = 0 + self.state_elapsed_time = 0 + + if self.can_interface is not None: + channel_id = DenaliChannels.dg_sync_broadcast_ch_id + msg_id = MsgIds.MSG_ID_DG_FLUSH_DATA.value + self.can_interface.register_receiving_publication_function(channel_id, msg_id, self._handler_flush_sync) + + @_publish(["flush_state", "overall_elapsed_time", "state_elapsed_time"]) + def _handler_flush_sync(self, message): + """ + Handles published flush message + + @param message: published flush data message + @returns none + """ + state = struct.unpack('i', bytearray( + message['message'][MsgFieldPositions.START_POS_FIELD_1:MsgFieldPositions.END_POS_FIELD_1]))[0] + elapsed_time = struct.unpack('i', bytearray( + 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] + + self.flush_state = FlushStates(state).name + self.overall_elapsed_time = int(elapsed_time / 1000) + self.state_elapsed_time = int(state_elapsed_time / 1000) + + def cmd_start_stop_flush(self, start=True): + """ + Constructs and sends the start/stop DG flush command + + @param start: (bool) True = start flush, False = stop flush. + @return: non-zero integer if successful, False otherwise + """ + # 1 is to start + if start: + cmd = 1 + str = "Starting" + else: + cmd = 0 + str = "Stopping" + payload = integer_to_bytearray(cmd) + message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_dg_ch_id, + message_id=MsgIds.MSG_ID_DG_START_STOP_FLUSH.value, + payload=payload) + + self.logger.debug(str + " DG flush mode") + + received_message = self.can_interface.send(message) + + # If there is content... + if received_message is not None: + # response payload is OK or not OK + return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] + else: + self.logger.debug("Timeout!!!!") + return False Index: dialin/dg/hd_proxy.py =================================================================== diff -u -r300390c34a81a42b5eb606e4f4499a1439bfc432 -r01db18a18769df2048346f868412fc8a12631fc0 --- dialin/dg/hd_proxy.py (.../hd_proxy.py) (revision 300390c34a81a42b5eb606e4f4499a1439bfc432) +++ dialin/dg/hd_proxy.py (.../hd_proxy.py) (revision 01db18a18769df2048346f868412fc8a12631fc0) @@ -275,3 +275,33 @@ self.logger.debug("Sending sample water command") self.can_interface.send(message, 0) + def cmd_start_stop_heat_disinfect(self, start=True): + """ + Constructs and sends the start/stop DG heat disinfection command + + @param start: (bool) True = start heat disinfection, False = stop heat disinfection. + @return: non-zero integer if successful, False otherwise + """ + # 1 is to start + if start: + cmd = 1 + str = "Starting" + else: + cmd = 0 + str = "Stopping" + payload = integer_to_bytearray(cmd) + message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_dg_ch_id, + message_id=MsgIds.MSG_ID_DG_START_STOP_HEAT_DISINFECT.value, + payload=payload) + + self.logger.debug(str + " DG heat disinfect") + + received_message = self.can_interface.send(message) + + # If there is content... + if received_message is not None: + # response payload is OK or not OK + return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] + else: + self.logger.debug("Timeout!!!!") + return False Index: dialin/dg/heat_disinfect.py =================================================================== diff -u -r41b8ceb850aca652c0e060e8738027fc7aeb473c -r01db18a18769df2048346f868412fc8a12631fc0 --- dialin/dg/heat_disinfect.py (.../heat_disinfect.py) (revision 41b8ceb850aca652c0e060e8738027fc7aeb473c) +++ dialin/dg/heat_disinfect.py (.../heat_disinfect.py) (revision 01db18a18769df2048346f868412fc8a12631fc0) @@ -105,34 +105,4 @@ 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 - @param start: (bool) True = start heat disinfection, False = stop heat disinfection. - @return: non-zero integer if successful, False otherwise - """ - # 1 is to start - if start: - cmd = 1 - str = "Starting" - else: - cmd = 0 - str = "Stopping" - payload = integer_to_bytearray(cmd) - message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_dg_ch_id, - message_id=MsgIds.MSG_ID_DG_START_STOP_HEAT_DISINFECT.value, - payload=payload) - - self.logger.debug(str + " DG heat disinfect") - - received_message = self.can_interface.send(message) - - # If there is content... - if received_message is not None: - # response payload is OK or not OK - return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] - else: - self.logger.debug("Timeout!!!!") - return False - Index: tests/dg_heat_disinfect_test.py =================================================================== diff -u -r41b8ceb850aca652c0e060e8738027fc7aeb473c -r01db18a18769df2048346f868412fc8a12631fc0 --- tests/dg_heat_disinfect_test.py (.../dg_heat_disinfect_test.py) (revision 41b8ceb850aca652c0e060e8738027fc7aeb473c) +++ tests/dg_heat_disinfect_test.py (.../dg_heat_disinfect_test.py) (revision 01db18a18769df2048346f868412fc8a12631fc0) @@ -132,7 +132,7 @@ complete_counter = 1 f = open("/home/fw/projects/dialin/tests/Heat_disinfect.log", "w") - dg.heat_disinfect.cmd_start_stop_heat_disinfect() + dg.hd_proxy.cmd_start_stop_heat_disinfect() try: while True: @@ -155,7 +155,7 @@ if dg.dg_operation_mode == 3 or dg.dg_operation_mode == 4: # If it is the first call, stop heat disinfect if complete_counter == 1: - dg.heat_disinfect.cmd_start_stop_heat_disinfect(start=False) + dg.hd_proxy.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() @@ -164,7 +164,7 @@ complete_counter += 1 except KeyboardInterrupt: - dg.heat_disinfect.cmd_start_stop_heat_disinfect(start=False) + dg.hd_proxy.cmd_start_stop_heat_disinfect(start=False) f.close() Index: tests/test_flush.py =================================================================== diff -u --- tests/test_flush.py (revision 0) +++ tests/test_flush.py (revision 01db18a18769df2048346f868412fc8a12631fc0) @@ -0,0 +1,101 @@ + +import sys +sys.path.append("..") +from dialin.dg.dialysate_generator import DG +from dialin.dg.drain_pump import DrainPumpStates +from time import sleep + + +def get_flush_mode_info(): + + info = ('State, {}, Overall_elapsed_time, {}, State_elapsed_time, {}, ' + .format(dg.flush.flush_state, dg.flush.overall_elapsed_time, dg.flush.state_elapsed_time)) + return info + + +def get_dg_valves_states(): + + info = ('VPi, {}, VSP, {}, VPd, {}, VBf, {}, VPo, {}, VDr, {}, VRc, {}, VRo, {}, VRd, {}, VRi, {}, VRf, {}, ' + .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], + dg.valves.valve_states_enum[dg.valves.VALVE_BYPASS_FILTER], + dg.valves.valve_states_enum[dg.valves.VALVE_PRESSURE_OUTLET], + dg.valves.valve_states_enum[dg.valves.VALVE_DRAIN], + dg.valves.valve_states_enum[dg.valves.VALVE_RECIRCULATE], + 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])) + 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, + dg.pressures.drain_pump_inlet_pressure, + dg.pressures.drain_pump_outlet_pressure)) + return info + + +def get_load_cells_info(): + + 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_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 run_flush_mode(): + + complete_counter = 1 + f = open("/home/fw/projects/dialin/tests/Flush_mode.log", "w") + #dg.flush.cmd_start_stop_flush() + try: + while True: + flush = get_flush_mode_info() + load_cell = get_load_cells_info() + drain = get_drain_states_info() + ro = get_ro_info() + valves = get_dg_valves_states() + + var = flush + load_cell + drain + ro + valves + '\r' + + print(var) + 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 + if complete_counter == 1: + dg.flush.cmd_start_stop_flush(start=False) + pass + # Write a few more complete states to make sure the complete state items are recorded + elif complete_counter == 3: + f.close() + break + + except KeyboardInterrupt: + dg.flush.cmd_start_stop_flush(start=False) + f.close() + + +if __name__ == "__main__": + + dg = DG(log_level='DEBUG') + dg.cmd_log_in_to_dg() + sleep(1) + + run_flush_mode()