Index: .gitignore =================================================================== diff -u -r908be8a294b5ff1216e02dcdfd0128e8037a1107 -rf8d379027a25b5497de67aabfb1e11b5e4fd6cbc --- .gitignore (.../.gitignore) (revision 908be8a294b5ff1216e02dcdfd0128e8037a1107) +++ .gitignore (.../.gitignore) (revision f8d379027a25b5497de67aabfb1e11b5e4fd6cbc) @@ -4,6 +4,7 @@ document/latex/ .idea/ venv/ +.eggs/ .cache tags tags.* Index: dialin/common/msg_ids.py =================================================================== diff -u -r82f60d6de5414db96b1c44c3d6fdb12a56e39880 -rf8d379027a25b5497de67aabfb1e11b5e4fd6cbc --- dialin/common/msg_ids.py (.../msg_ids.py) (revision 82f60d6de5414db96b1c44c3d6fdb12a56e39880) +++ dialin/common/msg_ids.py (.../msg_ids.py) (revision f8d379027a25b5497de67aabfb1e11b5e4fd6cbc) @@ -334,7 +334,7 @@ MSG_ID_DG_THERMISTORS_VALUE_OVERRIDE = 0XA02E MSG_ID_DG_RO_PUMP_DUTY_CYCLE_OVERRIDE = 0XA02F MSG_ID_DG_RO_FLOW_RATE_OVERRIDE = 0XA030 - MSG_ID_DG_RO_PUMP_TARGET_FLOW_OVERRIDE = 0XA031 + MSG_ID_DG_SET_RO_PUMP_TARGET_FLOW = 0XA031 MSG_ID_DG_RO_PUMP_TARGET_PRESSURE_OVERRIDE = 0XA032 MSG_ID_DG_SET_CALIBRATION_RECORD = 0XA033 MSG_ID_DG_GET_CALIBRATION_RECORD = 0XA034 Index: dialin/dg/concentrate_pumps.py =================================================================== diff -u -r6e20f4690ce887c351d8c65546f93311e5df6ad1 -rf8d379027a25b5497de67aabfb1e11b5e4fd6cbc --- dialin/dg/concentrate_pumps.py (.../concentrate_pumps.py) (revision 6e20f4690ce887c351d8c65546f93311e5df6ad1) +++ dialin/dg/concentrate_pumps.py (.../concentrate_pumps.py) (revision f8d379027a25b5497de67aabfb1e11b5e4fd6cbc) @@ -19,7 +19,7 @@ from ..utils.checks import check_broadcast_interval_override_ms from ..protocols.CAN import (DenaliMessage, DenaliChannels) from ..utils.base import _AbstractSubSystem, _publish, DialinEnum -from ..common.msg_defs import MsgIds +from ..common.msg_defs import MsgIds, MsgFieldPositions from logging import Logger class ConcentratePumpsEnum(DialinEnum): @@ -86,15 +86,19 @@ @return: None """ - cp1_current = struct.unpack('f', bytearray(message['message'][self.START_POS_CP1_TARGET:self.END_POS_CP1_TARGET])) - cp1_measured = struct.unpack('f', bytearray(message['message'][self.START_POS_CP1:self.END_POS_CP1])) - cp2_current = struct.unpack('f', bytearray(message['message'][self.START_POS_CP2_TARGET:self.END_POS_CP2_TARGET])) - cp2_measured = struct.unpack('f', bytearray(message['message'][self.START_POS_CP2:self.END_POS_CP2])) + cp1_current = struct.unpack('f', bytearray( + message['message'][MsgFieldPositions.START_POS_FIELD_1:MsgFieldPositions.END_POS_FIELD_1]))[0] + cp1_measured = struct.unpack('f', bytearray( + message['message'][MsgFieldPositions.START_POS_FIELD_2:MsgFieldPositions.END_POS_FIELD_2]))[0] + cp2_current = struct.unpack('f', bytearray( + message['message'][MsgFieldPositions.START_POS_FIELD_3:MsgFieldPositions.END_POS_FIELD_3]))[0] + cp2_measured = struct.unpack('f', bytearray( + message['message'][MsgFieldPositions.START_POS_FIELD_4:MsgFieldPositions.END_POS_FIELD_4]))[0] - self.concentrate_pump_cp1_current_set_speed = cp1_current[0] - self.concentrate_pump_cp1_measured_speed = cp1_measured[0] - self.concentrate_pump_cp2_current_set_speed = cp2_current[0] - self.concentrate_pump_cp2_measured_speed = cp2_measured[0] + self.concentrate_pump_cp1_current_set_speed = cp1_current + self.concentrate_pump_cp1_measured_speed = cp1_measured + self.concentrate_pump_cp2_current_set_speed = cp2_current + self.concentrate_pump_cp2_measured_speed = cp2_measured def cmd_concentrate_pump_state_change_request(self, pump_id: int, on: bool = False) -> int: """ Index: dialin/dg/ro_pump.py =================================================================== diff -u -r6e20f4690ce887c351d8c65546f93311e5df6ad1 -rf8d379027a25b5497de67aabfb1e11b5e4fd6cbc --- dialin/dg/ro_pump.py (.../ro_pump.py) (revision 6e20f4690ce887c351d8c65546f93311e5df6ad1) +++ dialin/dg/ro_pump.py (.../ro_pump.py) (revision f8d379027a25b5497de67aabfb1e11b5e4fd6cbc) @@ -119,112 +119,106 @@ self.ro_pump_state = ROPumpStates(ro_state).name if ROPumpStates.has_value(ro_state) else 'State Unknown' self.target_flow_lpm = tgt_flow - def cmd_ro_pump_set_point_override(self, pressure: int, reset: int = NO_RESET) -> int: + def cmd_ro_pump_duty_cycle_pct(self, duty: float) -> int: """ - Constructs and sends the RO pump set point override command. + Constructs and sends the set RO pump duty cycle message Constraints: Must be logged into DG. - @param pressure: integer - pressure set point (in PSI) to override with - @param reset: integer - 1 to reset a previous override, 0 to override + @param duty: integer - 1 percentage for duty cycle between 0 and 100 @return: 1 if successful, zero otherwise """ + dc = float_to_bytearray(duty/100) + payload = dc - rst = integer_to_bytearray(reset) - prs = integer_to_bytearray(pressure) - payload = rst + prs - message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_dg_ch_id, - message_id=MsgIds.MSG_ID_RO_PUMP_SEND_INTERVAL_OVERRIDE.value, + message_id=MsgIds.MSG_ID_DG_RO_PUMP_DUTY_CYCLE_OVERRIDE.value, payload=payload) - self.logger.debug("Override RO pump pressure set point") + self.logger.debug("RO pump duty cycle set") # Send message received_message = self.can_interface.send(message) # 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: - str_res = str(pressure) + self.logger.debug( - "RO pump pressure set point overridden to " + str_res + " PSI: " + + "RO pump duty cycle set to " + str(duty) + " %" + str(received_message['message'][DenaliMessage.PAYLOAD_START_INDEX])) # response payload is OK or not OK return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] else: self.logger.debug("Timeout!!!!") return False - def cmd_ro_pump_duty_cycle_pct(self, duty: float) -> int: + def cmd_ro_pump_measured_flow_rate_override(self, flow: float, reset: int = NO_RESET) -> int: """ - Constructs and sends the set RO pump duty cycle message + Constructs and sends the RO flow rate override command. Constraints: Must be logged into DG. - @param duty: integer - 1 percentage for duty cycle between 0 and 100 + @param flow: float - flow rate (in L/min) to override with + @param reset: integer - 1 to reset a previous override, 0 to override @return: 1 if successful, zero otherwise """ - dc = float_to_bytearray(duty/100) - payload = dc + rst = integer_to_bytearray(reset) + flo = float_to_bytearray(flow) + payload = rst + flo + message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_dg_ch_id, - message_id=MsgIds.MSG_ID_DG_RO_PUMP_DUTY_CYCLE_OVERRIDE.value, + message_id=MsgIds.MSG_ID_DG_RO_FLOW_RATE_OVERRIDE.value, payload=payload) - self.logger.debug("RO pump duty cycle set") + self.logger.debug("Override RO pump measured flow rate") # Send message received_message = self.can_interface.send(message) # 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: + str_res = str(flo) self.logger.debug( - "RO pump duty cycle set to " + str(duty) + " %" + + "Measured RO flow rate overridden to " + str_res + " L/min: " + str(received_message['message'][DenaliMessage.PAYLOAD_START_INDEX])) # response payload is OK or not OK return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] else: self.logger.debug("Timeout!!!!") return False - def cmd_ro_flow_rate_override(self, flow: float, reset: int = NO_RESET) -> int: + def cmd_set_ro_flow_rate(self, flow: float) -> int: """ - Constructs and sends the RO rate override command. + Constructs and sends the RO rate set command. Constraints: Must be logged into DG. - @param flow: float - flow rate (in L/min) to override with - @param reset: integer - 1 to reset a previous override, 0 to override + @param flow: float - flow rate (in L/min) to set @return: 1 if successful, zero otherwise """ - rst = integer_to_bytearray(reset) flo = float_to_bytearray(flow) - payload = rst + flo + payload = flo message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_dg_ch_id, - message_id=MsgIds.MSG_ID_DG_RO_PUMP_TARGET_FLOW_OVERRIDE.value, + message_id=MsgIds.MSG_ID_DG_SET_RO_PUMP_TARGET_FLOW.value, payload=payload) - self.logger.debug("override RO pump pressure set point") + self.logger.debug("Set RO pump target flow rate") # Send message received_message = self.can_interface.send(message) # 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: - str_res = str(flo) + str_res = str(flo) self.logger.debug( - "RO flow rate overridden to " + str_res + " L/min: " + + "Target RO flow rate set to " + str_res + " L/min: " + str(received_message['message'][DenaliMessage.PAYLOAD_START_INDEX])) # response payload is OK or not OK return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] Index: dialin/hd/valves.py =================================================================== diff -u -r6b5600f056eff25cbb365fa6a5eefc4f5fad9360 -rf8d379027a25b5497de67aabfb1e11b5e4fd6cbc --- dialin/hd/valves.py (.../valves.py) (revision 6b5600f056eff25cbb365fa6a5eefc4f5fad9360) +++ dialin/hd/valves.py (.../valves.py) (revision f8d379027a25b5497de67aabfb1e11b5e4fd6cbc) @@ -368,7 +368,7 @@ return False @_publish(["valves_status", "hd_air_trap_status"]) - def _handler_hd_valves_sync(self, message:dict) -> None: + def _handler_hd_valves_sync(self, message: dict) -> None: """ Handles published HD valves data messages. HD valves data are captured for reference. Index: tests/dg_heat_and_chemical_disinfect_test.py =================================================================== diff -u -r6b5600f056eff25cbb365fa6a5eefc4f5fad9360 -rf8d379027a25b5497de67aabfb1e11b5e4fd6cbc --- tests/dg_heat_and_chemical_disinfect_test.py (.../dg_heat_and_chemical_disinfect_test.py) (revision 6b5600f056eff25cbb365fa6a5eefc4f5fad9360) +++ tests/dg_heat_and_chemical_disinfect_test.py (.../dg_heat_and_chemical_disinfect_test.py) (revision f8d379027a25b5497de67aabfb1e11b5e4fd6cbc) @@ -12,6 +12,7 @@ from dialin.dg.dialysate_generator import DGOperationModes from dialin.hd.temperatures import HDTemperaturesNames from time import sleep +from datetime import datetime import sys sys.path.append("..") @@ -257,21 +258,9 @@ timer = 0.1 sleep_time = 1 run_number = 1 + recirc_delay = 1 f = open("/home/fw/projects/dialin/tests/run_dg.log", "w") - - # Set the broadcast to the fastest for studying a phenomenon - #dg.heaters.cmd_heaters_broadcast_interval_override(50) - #sleep(0.25) - """ - dg.pressures.cmd_pressure_broadcast_interval_override(50) - sleep(0.25) - dg.drain_pump.cmd_drain_pump_data_broadcast_interval_override(50) - sleep(0.25) - dg.ro_pump.cmd_ro_pump_data_broadcast_interval_override(50) - sleep(0.25) - """ - dg.hd_proxy.cmd_start_stop_dg() sleep(0.1) @@ -286,13 +275,12 @@ fans = get_dg_fans_info() valves = get_dg_valves_states() - var = str(run_number) + ', ' + str(timer) + ', ' + dg_run + temperature + heaters + load_cell + drain + \ - ro + fans + valves + '\r' + var = str(datetime.now()) + ', ' + str(run_number) + ', ' + str(recirc_delay) + ', ' + dg_run + \ + temperature + heaters + load_cell + drain + ro + fans + valves + '\r' print(var) f.write(var) - tpo = dg.temperature_sensors.temperature_sensors[TemperatureSensorsNames.OUTLET_PRIMARY_HEATER.name] if run_number > 5 and dg.dg_operation_sub_mode == 2: dg.hd_proxy.cmd_start_stop_dg(start=False) f.close() @@ -301,22 +289,107 @@ elif DGOperationModes(dg.dg_operation_mode).name == DGOperationModes.DG_OP_MODE_RECIRCULATE.name and\ dg.dg_operation_sub_mode == 2 and counter == 1: - if timer == 1: - dg.hd_proxy.cmd_switch_reservoirs(reservoirID=1) - timer += 1 + if recirc_delay < 5: + recirc_delay += 1 + else: + if timer == 1: + dg.hd_proxy.cmd_switch_reservoirs(reservoirID=1) + timer += 1 - if timer > ((1/sleep_time) * 1): - timer = 1 + if timer > ((1/sleep_time) * 1): + timer = 1 + recirc_delay = 1 + counter += 1 + + elif 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_drain(tare_load_cell=True) + counter += 1 + timer = 1 + + elif DGOperationModes(dg.dg_operation_mode).name == DGOperationModes.DG_OP_MODE_RECIRCULATE.name and\ + dg.dg_operation_sub_mode == 2 and counter == 3: + + timer += 1 + if timer > 4: + dg.hd_proxy.cmd_fill(volume=1700) counter += 1 elif DGOperationModes(dg.dg_operation_mode).name == DGOperationModes.DG_OP_MODE_RECIRCULATE.name and\ + dg.dg_operation_sub_mode == 2 and counter == 4: + counter = 1 + run_number += 1 + + sleep(sleep_time) + + except KeyboardInterrupt: + dg.hd_proxy.cmd_start_stop_dg(start=False) + f.close() + pass + + +def run_ro_pump_duty_cycles(): + + counter = 1 + timer = 0.1 + sleep_time = 1 + run_number = 1 + recirc_delay = 1 + ro_dc = 10 + ro_dc_step = 5 + f = open("/home/fw/projects/dialin/tests/run_ro_pump.log", "w") + + dg.hd_proxy.cmd_start_stop_dg() + sleep(0.1) + dg.ro_pump.cmd_ro_pump_duty_cycle_pct(ro_dc) + sleep(0.1) + + try: + while True: + dg_run = get_dg_run_info() + temperature = get_temperature_sensors_info() + heaters = get_heaters_with_no_temp_info() + load_cell = get_load_cells_info() + drain = get_drain_states_info() + ro = get_ro_info() + fans = get_dg_fans_info() + valves = get_dg_valves_states() + + var = str(datetime.now()) + ', ' + str(run_number) + ', ' + str(ro_dc) + ', ' + dg_run + \ + temperature + heaters + load_cell + drain + ro + fans + valves + '\r' + + print(var) + f.write(var) + + if ro_dc > 95 and dg.dg_operation_sub_mode == 2: + dg.hd_proxy.cmd_start_stop_dg(start=False) + f.close() + break + + elif DGOperationModes(dg.dg_operation_mode).name == DGOperationModes.DG_OP_MODE_RECIRCULATE.name and\ + dg.dg_operation_sub_mode == 2 and counter == 1: + + if recirc_delay < 1: + recirc_delay += 1 + else: + if timer == 1: + dg.hd_proxy.cmd_switch_reservoirs(reservoirID=1) + + timer += 1 + + if timer > ((1/sleep_time) * 1): + timer = 1 + recirc_delay = 1 + counter += 1 + + elif 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_drain(tare_load_cell=True) counter += 1 timer = 1 elif DGOperationModes(dg.dg_operation_mode).name == DGOperationModes.DG_OP_MODE_RECIRCULATE.name and\ - dg.dg_operation_sub_mode == 2 and counter == 3: #and tpo > 39.0: + dg.dg_operation_sub_mode == 2 and counter == 3: timer += 1 if timer > 4: @@ -327,6 +400,8 @@ dg.dg_operation_sub_mode == 2 and counter == 4: counter = 1 run_number += 1 + ro_dc += ro_dc_step + dg.ro_pump.cmd_ro_pump_duty_cycle_pct(ro_dc) sleep(sleep_time) @@ -445,9 +520,9 @@ #run_chemical_disinfect() - run_dg() + #run_dg() - #run_heaters() + run_ro_pump_duty_cycles() #cmd_set_disinfect_ui_screen() @@ -457,4 +532,6 @@ #sleep(0.1) #dg.concentrate_pumps.cmd_concentrate_pump_state_change_request(1, 0) + #dg.valves.cmd_valve_override(4, 0) + Index: tests/hd_valves_test.py =================================================================== diff -u -r6b5600f056eff25cbb365fa6a5eefc4f5fad9360 -rf8d379027a25b5497de67aabfb1e11b5e4fd6cbc --- tests/hd_valves_test.py (.../hd_valves_test.py) (revision 6b5600f056eff25cbb365fa6a5eefc4f5fad9360) +++ tests/hd_valves_test.py (.../hd_valves_test.py) (revision f8d379027a25b5497de67aabfb1e11b5e4fd6cbc) @@ -86,20 +86,30 @@ def change_valves_position(): - valve = ValvesEnum.VDI.value - valves.cmd_home_hd_valve(valve) - sleep(0.25) + valve = ValvesEnum.VDI + valves.cmd_home_hd_valve(valve.value) + sleep(0.5) - valves.cmd_set_hd_valve_position(valve, ValvesPositions.VALVE_POSITION_B_OPEN.value) + valves.cmd_set_hd_valve_position(valve.value, ValvesPositions.VALVE_POSITION_B_OPEN.value) sleep(0.05) - valves.cmd_set_hd_valve_position(valve, ValvesPositions.VALVE_POSITION_A_INSERT_EJECT.value) + valves.cmd_set_hd_valve_position(valve.value, ValvesPositions.VALVE_POSITION_A_INSERT_EJECT.value) while True: - print("Pos, {}, Cmd, {}, Curr, {}, PosA, {}, PosB, {}, PosC, {}, State, {}, PWM, {}" - .format(valves.hd_valve_fast_pos, valves.hd_valves_fast_cmd, valves.hd_valve_fast_current, - valves.hd_valves_pos_a, valves.hd_valves_pos_b, valves.hd_valves_pos_c, valves.hd_valve_state, - valves.hd_valves_pwm)) + try: + status = ('ID, {}, Pos, {}, PosCnt, {}, Cmd, {}, State, {}, Current, {}, PosA, {}, PosB, {}, PosC, {} \r' + .format(valves.valves_status[valve.name]['Valve'], + valves.valves_status[valve.name]['PosID'], + valves.valves_status[valve.name]['PosCnt'], + valves.valves_status[valve.name]['Cmd'], + valves.valves_status[valve.name]['State'], + valves.valves_status[valve.name]['Current'], + valves.valves_status[valve.name]['PosA'], + valves.valves_status[valve.name]['PosB'], + valves.valves_status[valve.name]['PosC'])) + print(status) + except: + pass sleep(1) Index: tests/test_flush.py =================================================================== diff -u -r6b5600f056eff25cbb365fa6a5eefc4f5fad9360 -rf8d379027a25b5497de67aabfb1e11b5e4fd6cbc --- tests/test_flush.py (.../test_flush.py) (revision 6b5600f056eff25cbb365fa6a5eefc4f5fad9360) +++ tests/test_flush.py (.../test_flush.py) (revision f8d379027a25b5497de67aabfb1e11b5e4fd6cbc) @@ -17,9 +17,12 @@ def get_concentrate_pumps_info(): - info = ('Bicarb_tgt_speed, {:5.3f}, Bicarb_speed, {:5.3f}, CPo, {:5.3f}, CD1, {:5.3f}, CD2, {:5.3f}, ' + info = ('Bicarb_tgt_speed, {:5.3f}, Bicarb_speed, {:5.3f}, Acid_tgt_speed, {:5.3f}, Acid_speed, {:5.3f}, ' + 'CPo, {:5.3f}, CD1, {:5.3f}, CD2, {:5.3f}, ' .format(dg.concentrate_pumps.concentrate_pump_cp2_current_set_speed, dg.concentrate_pumps.concentrate_pump_cp2_measured_speed, + dg.concentrate_pumps.concentrate_pump_cp1_current_set_speed, + dg.concentrate_pumps.concentrate_pump_cp1_measured_speed, dg.conductivity_sensors.conductivity_sensor_cpo, dg.conductivity_sensors.conductivity_sensor_cd1, dg.conductivity_sensors.conductivity_sensor_cd2)) return info