Index: leahi_dialin/dd/modules/piston_pump.py =================================================================== diff -u -r4e60dc04a4526be59962b3be2cb149b9bf536623 -rdfbb4f080638b65d9836b22bd5c76d46d53abba5 --- leahi_dialin/dd/modules/piston_pump.py (.../piston_pump.py) (revision 4e60dc04a4526be59962b3be2cb149b9bf536623) +++ leahi_dialin/dd/modules/piston_pump.py (.../piston_pump.py) (revision dfbb4f080638b65d9836b22bd5c76d46d53abba5) @@ -5,7 +5,7 @@ # THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN # WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. # -# @file piston_pumps.py +# @file piston_pump.py # # @author (last) Micahel Garthwaite # @date (last) 07-Mar-2023 @@ -20,13 +20,20 @@ from .constants import RESET, NO_RESET from leahi_dialin.common.msg_defs import MsgIds, MsgFieldPositions from leahi_dialin.protocols.CAN import DenaliMessage, DenaliChannels -from leahi_dialin.utils.base import AbstractSubSystem, publish +from leahi_dialin.utils.base import AbstractSubSystem, publish, DialinEnum from leahi_dialin.utils.checks import check_broadcast_interval_override_ms from leahi_dialin.utils.conversions import integer_to_bytearray, float_to_bytearray +@unique +class DDPistonPumpsEnum(DialinEnum): + ACID = 0 # Acid piston pump + BICARB = 1 # Bicarbonate piston pump + UF = 2 # Ultrafilteration piston pump + NUM_OF_PISTON_PUMPS = 3 # Number of piston pumps + class DDPistonPumps(AbstractSubSystem): """ - PistonPumps + DDPistonPumps Dialysate Delivery (DD) Dialin API sub-class for piston pumps related commands. """ @@ -126,14 +133,14 @@ self.logger.error("Timeout!!!!") return False - def cmd_piston_set_start_stop(self, pump_id: int, command: int, count: int, speed: float, volume: float ) -> int: + def cmd_piston_set_start_stop_override(self, pump_id: int, command: int, count: int, flow_rate: float, volume: float ) -> int: """ Constructs and sends the piston pump start stop command @param pump_id: unsigned int - concentrate pump ID @param command: int - value to command the concentrate pump @param count: int - vale to set the cycle count to - @param speed: float - ml/min to set the speed to + @param flow_rate: float - ml/min to set the speed to @param volume: float - the volume to set to @return: 1 if successful, zero otherwise @@ -142,7 +149,7 @@ pmp = integer_to_bytearray(pump_id) cmd = integer_to_bytearray(command) cyc = integer_to_bytearray(count) - spd = float_to_bytearray(speed) + spd = float_to_bytearray(flow_rate) vlm = float_to_bytearray(volume) payload = pmp + cmd + cyc + vlm + spd Index: leahi_dialin/dd/proxies/td_proxy.py =================================================================== diff -u -r1c9f9429a04e8fddcb102ef955eccb288dcf113f -rdfbb4f080638b65d9836b22bd5c76d46d53abba5 --- leahi_dialin/dd/proxies/td_proxy.py (.../td_proxy.py) (revision 1c9f9429a04e8fddcb102ef955eccb288dcf113f) +++ leahi_dialin/dd/proxies/td_proxy.py (.../td_proxy.py) (revision dfbb4f080638b65d9836b22bd5c76d46d53abba5) @@ -5,7 +5,7 @@ # THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN # WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. # -# @file buttons.py +# @file td_proxy.py # # @author (last) Micahel Garthwaite # @date (last) 18-Aug-2023 @@ -29,7 +29,7 @@ def __init__(self, can_interface: DenaliCanMessenger, logger: Logger): """ - HD_Buttons constructor + TDProxy constructor @param can_interface: the Denali CAN interface object """ @@ -60,6 +60,12 @@ "dialysate_delivery_request_bicarb", ]) def _handler_dialysate_delivery_request_response(self, message, timestamp=0.0): + """ + Handles published dialysate delivery request response data messages. + + @param message: published dialysate delivery request response data message + @return: None + """ self.dialysate_delivery_request_start = struct.unpack('i', bytearray( message['message'][MsgFieldPositions.START_POS_FIELD_1:MsgFieldPositions.END_POS_FIELD_1]))[0] self.dialysate_delivery_request_dial_rate = struct.unpack('f', bytearray( Index: leahi_dialin/ro/modules/boost_pump.py =================================================================== diff -u -rbfb64f60f01b65c3acbead5608acba277bab7d0e -rdfbb4f080638b65d9836b22bd5c76d46d53abba5 --- leahi_dialin/ro/modules/boost_pump.py (.../boost_pump.py) (revision bfb64f60f01b65c3acbead5608acba277bab7d0e) +++ leahi_dialin/ro/modules/boost_pump.py (.../boost_pump.py) (revision dfbb4f080638b65d9836b22bd5c76d46d53abba5) @@ -28,13 +28,13 @@ @unique class ROPumpNames(DialinEnum): - PUMP_RO = 0 - PUMP_BOOSTER = 1 + P12_PUMP_RO = 0 + P40_PUMP_BOOSTER = 1 class ROPumps(AbstractSubSystem): """ - TReverse Osmosis (RO) Dialin API sub-class for blood-flow related commands. + Dialin API sub-class for RO pump related commands. """ def __init__(self, can_interface, logger: Logger): @@ -51,25 +51,25 @@ self.can_interface.register_receiving_publication_function(channel_id, msg_id, self._handler_boost_pump_sync) self.ro_pump_timestamp = 0.0 - self.ro_pump_state = 0 - self.ro_pump_duty_cycle = 0.0 - self.ro_pump_fb_duty_cycle = 0.0 - self.ro_pump_speed = 0.0 - self.boost_pump_state = 0 - self.boost_pump_duty_cycle = 0.0 - self.boost_pump_fb_duty_cycle = 0.0 - self.boost_pump_speed = 0.0 + self.p12_ro_pump_state = 0 + self.p12_ro_pump_duty_cycle = 0.0 + self.p12_ro_pump_fb_duty_cycle = 0.0 + self.p12_ro_pump_speed = 0.0 + self.p40_boost_pump_state = 0 + self.p40_boost_pump_duty_cycle = 0.0 + self.p40_boost_pump_fb_duty_cycle = 0.0 + self.p40_boost_pump_speed = 0.0 - @publish(["ro_pump_timestamp", "ro_pump_state", "ro_pump_duty_cycle", "ro_pump_fb_duty_cycle", - "ro_pump_speed", "boost_pump_state", "boost_pump_duty_cycle", - "boost_pump_fb_duty_cycle", "boost_pump_speed"]) + @publish(["ro_pump_timestamp", "p12_ro_pump_state", "p12_ro_pump_duty_cycle", "p12_ro_pump_fb_duty_cycle", + "p12_ro_pump_speed", "p40_boost_pump_state", "p40_boost_pump_duty_cycle", + "p40_boost_pump_fb_duty_cycle", "p40_boost_pump_speed"]) def _handler_boost_pump_sync(self, message, timestamp=0.0): """ - Handles published blood flow data messages. Blood flow data are captured + Handles published RO pump data messages. RO pump data is captured for reference. - @param message: published blood flow data message + @param message: published RO pump data message @return: none """ @@ -91,14 +91,14 @@ message['message'][MsgFieldPositions.START_POS_FIELD_8:MsgFieldPositions.END_POS_FIELD_8])) self.ro_pump_timestamp = timestamp - self.ro_pump_state = rps[0] - self.ro_pump_duty_cycle = rpdc[0] - self.ro_pump_fb_duty_cycle = rpfbdc[0] - self.ro_pump_speed = rprpm[0] - self.boost_pump_state = bps[0] - self.boost_pump_duty_cycle = bpdc[0] - self.boost_pump_fb_duty_cycle = bpfbdc[0] - self.boost_pump_speed = bprpm[0] + self.p12_ro_pump_state = rps[0] + self.p12_ro_pump_duty_cycle = rpdc[0] + self.p12_ro_pump_fb_duty_cycle = rpfbdc[0] + self.p12_ro_pump_speed = rprpm[0] + self.p40_boost_pump_state = bps[0] + self.p40_boost_pump_duty_cycle = bpdc[0] + self.p40_boost_pump_fb_duty_cycle = bpfbdc[0] + self.p40_boost_pump_speed = bprpm[0] @@ -127,7 +127,6 @@ # 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: @@ -160,15 +159,15 @@ message_id=MsgIds.MSG_ID_RO_BOOST_PUMP_SET_PWM_REQUEST.value, payload=payload) - self.logger.debug("override measured boost pump speed") + self.logger.debug("setting pump {} to pwm count {}".format(pump,pwm)) # Send message received_message = self.can_interface.send(message) # If there is content... if received_message is not None: - self.logger.debug("pwm overridden to " + str(pwm)) + self.logger.debug("pwm set to " + str(pwm)) # response payload is OK or not OK return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] else: @@ -177,7 +176,7 @@ def cmd_boost_pump_read_pwm_override(self, pump: int, pwm: float, reset: int = NO_RESET) -> int: """ - Constructs and sends the read pwm override \n + Constructs and sends the read pwm override for the RO pumps \n command. Constraints: Must be logged into RO. @@ -196,14 +195,13 @@ message_id=MsgIds.MSG_ID_RO_BOOST_PUMP_READ_PWM_OVERRIDE_REQUEST.value, payload=payload) - self.logger.debug("override measured blood pump rotor speed") + self.logger.debug("override read pwm for pump".format(pump)) # 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: @@ -218,7 +216,7 @@ def cmd_boost_pump_broadcast_interval_override(self, ms: int, reset: int = NO_RESET) -> int: """ - Constructs and sends the measured blood flow broadcast interval override command + Constructs and sends the RO pump broadcast interval override command Constraints: Must be logged into RO. Given interval must be non-zero and a multiple of the RO general task interval (50 ms). @@ -239,7 +237,7 @@ message_id=MsgIds.MSG_ID_RO_BOOST_PUMPS_PUBLISH_INTERVAL_OVERRIDE_REQUEST.value, payload=payload) - self.logger.debug("override boost pump broadcast interval") + self.logger.debug("override RO pump broadcast interval") # Send message received_message = self.can_interface.send(message) Index: leahi_dialin/ro/modules/levels.py =================================================================== diff -u -r270356fb1edd1ea15b16cb322d36f5558e84cc47 -rdfbb4f080638b65d9836b22bd5c76d46d53abba5 --- leahi_dialin/ro/modules/levels.py (.../levels.py) (revision 270356fb1edd1ea15b16cb322d36f5558e84cc47) +++ leahi_dialin/ro/modules/levels.py (.../levels.py) (revision dfbb4f080638b65d9836b22bd5c76d46d53abba5) @@ -36,7 +36,7 @@ class ROLevels(AbstractSubSystem): """ - Reverse Osmosis (RO) Dialin API sub-class for levels related commands. + Dialin API sub-class for levels related commands. """ def __init__(self, can_interface, logger: Logger): @@ -50,7 +50,7 @@ self.can_interface = can_interface self.logger = logger - self.floater = 0 + self.p25_level = 0 self.ro_levels_timestamp = 0 if self.can_interface is not None: @@ -59,22 +59,22 @@ self.can_interface.register_receiving_publication_function(channel_id, msg_id, self._handler_levels_sync) @publish(["ro_levels_timestamp", - "floater",]) + "p25_level",]) def _handler_levels_sync(self, message, timestamp=0.0): """ Handles published levels message @param message: published levels data message @returns none """ - self.floater = struct.unpack('i', bytearray( + self.p25_level = struct.unpack('i', bytearray( message['message'][MsgFieldPositions.START_POS_FIELD_1:MsgFieldPositions.END_POS_FIELD_1]))[0] self.ro_levels_timestamp = timestamp def cmd_levels_broadcast_interval_override(self, ms: int, reset: int = NO_RESET) -> int: """ - Constructs and sends RO level data broadcast time interval override message. + Constructs and sends an RO levels data broadcast interval override command message. Constraints: Must be logged into RO. Given interval must be non-zero and a multiple of the RO general task interval (50 ms). @@ -94,7 +94,7 @@ message_id=MsgIds.MSG_ID_RO_LEVELS_PUBLISH_INTERVAL_OVERRIDE_REQUEST.value, payload=payload) - self.logger.debug("Sending {} ms publish interval override for floater level data".format(ms)) + self.logger.debug("Sending {} ms publish interval to the RO Levels module".format(ms)) # Send message received_message = self.can_interface.send(message) @@ -108,10 +108,11 @@ def cmd_level_state_override(self, level: int, reset: int = NO_RESET) -> int: """ - Constructs and sends level state override command - Must be logged into RO + Constructs and sends level status override command. + Must be logged into RO. - @param level the floater level value to override (0=low, 1=high, 2=medium) + @param level_sensor: integer - the level sensor to override its value + @param status: integer - the status value to override @param reset: (int) 1 to reset a previous override, 0 to override @returns 1 if successful, zero otherwise """ Index: leahi_dialin/ro/modules/valves.py =================================================================== diff -u -r78c301b165b516b33d087cdc67fbcf39156515dc -rdfbb4f080638b65d9836b22bd5c76d46d53abba5 --- leahi_dialin/ro/modules/valves.py (.../valves.py) (revision 78c301b165b516b33d087cdc67fbcf39156515dc) +++ leahi_dialin/ro/modules/valves.py (.../valves.py) (revision dfbb4f080638b65d9836b22bd5c76d46d53abba5) @@ -39,20 +39,19 @@ @unique class ROValveNames(DialinEnum): - VWI = 0 # Valve (M4 VWi) - VROD = 1 # Valve (P39 VROd) - VFF = 2 # Valve (P6 VFF) - VPI = 3 # Valve (P11 VPi) - VCR = 4 # Valve (P33 VCr) - VCB = 5 # Valve (P34 VCb) - VCD = 6 # Valve (P37 VCd) - VFB = 7 # Valve (M7 VFB) - SPP = 8 # Valve (P20 SPP) + M4_VWI = 0 # Valve (M4 VWi) + P39_VROD = 1 # Valve (P39 VROd) + P6_VFF = 2 # Valve (P6 VFF) + P11_VPI = 3 # Valve (P11 VPi) + P33_VCR = 4 # Valve (P33 VCr) + P34_VCB = 5 # Valve (P34 VCb) + P37_VCD = 6 # Valve (P37 VCd) + M7_VFB = 7 # Valve (M7 VFB) + P20_SPP = 8 # Valve (P20 SPP) class ROValves(AbstractSubSystem): """ - Reverse Osmosis (RO) interface for valve related commands. - + Dialin API sub-class for RO valve related commands. """ # Valves states publish message field positions @@ -77,15 +76,15 @@ self.can_interface.register_receiving_publication_function(channel_id, msg_id, self._handler_valves_sync) self.valve_states_all = 0x0000 - self.valve_state_VWI = {"id": ROValveNames.VWI.value, "state": DEENERGIZED} - self.valve_state_VFB = {"id": ROValveNames.VFB.value, "state": DEENERGIZED} - self.valve_state_VFF = {"id": ROValveNames.VFF.value, "state": DEENERGIZED} - self.valve_state_VPI = {"id": ROValveNames.VPI.value, "state": DEENERGIZED} - self.valve_state_VCR = {"id": ROValveNames.VCR.value, "state": DEENERGIZED} - self.valve_state_VCB = {"id": ROValveNames.VCB.value, "state": DEENERGIZED} - self.valve_state_VCD = {"id": ROValveNames.VCD.value, "state": DEENERGIZED} - self.valve_state_VROD = {"id": ROValveNames.VROD.value, "state": DEENERGIZED} - self.valve_state_SPP = {"id": ROValveNames.SPP.value, "state": DEENERGIZED} + self.m4_vwi_state= {"id": ROValveNames.M4_VWI.value, "state": DEENERGIZED} + self.p39_vrod_state = {"id": ROValveNames.P39_VROD.value, "state": DEENERGIZED} + self.p6_vff_state = {"id": ROValveNames.P6_VFF.value, "state": DEENERGIZED} + self.p11_vpi_state = {"id": ROValveNames.P11_VPI.value, "state": DEENERGIZED} + self.p33_vcr_state = {"id": ROValveNames.P33_VCR.value, "state": DEENERGIZED} + self.p34_vcb_state = {"id": ROValveNames.P34_VCB.value, "state": DEENERGIZED} + self.p37_vcd_state = {"id": ROValveNames.P37_VCD.value, "state": DEENERGIZED} + self.m7_vfb_state = {"id": ROValveNames.M7_VFB.value, "state": DEENERGIZED} + self.p20_spp_state = {"id": ROValveNames.P20_SPP.value, "state": DEENERGIZED} # NOTE: The len function counts the enums with the same number only once. This is not the case in the DG valves # class because each valve must have a unique ID. @@ -101,15 +100,15 @@ @return: All valve states """ return [ - self.valve_state_VWI.get("state"), - self.valve_state_VROD.get("state"), - self.valve_state_VFF.get("state"), - self.valve_state_VPI.get("state"), - self.valve_state_VCR.get("state"), - self.valve_state_VCB.get("state"), - self.valve_state_VCD.get("state"), - self.valve_state_VFB.get("state"), - self.valve_state_SPP.get("state") + self.m4_vwi_state.get("state"), + self.p39_vrod_state.get("state"), + self.p6_vff_state.get("state"), + self.p11_vpi_state.get("state"), + self.p33_vcr_state.get("state"), + self.p34_vcb_state.get("state"), + self.p37_vcd_state.get("state"), + self.m7_vfb_state.get("state"), + self.p20_spp_state.get("state") ] @staticmethod @@ -145,36 +144,37 @@ @publish([ "ro_valves_states_timestamp", "valve_states_all", - "valve_state_VWI", - "valve_state_VROD", - "valve_state_VFF", - "valve_state_VPI", - "valve_state_VCR", - "valve_state_VCB", - "valve_state_VCD", - "valve_state_SPP", + "m4_vwi_state", + "p39_vrod_state", + "p6_vff_state", + "p11_vpi_state", + "p33_vcr_state", + "p34_vcb_state", + "p37_vcd_state", + "m7_vfb_state", + "p20_spp_state", "valve_states_enum" ]) def _handler_valves_sync(self, message, timestamp=0.0): """ - Handles published valves states message. + Handles published RO valves states message. - @param message: published valves states message + @param message: published RO valves states message @return: none """ vst = struct.unpack('H', bytearray(message['message'][self.START_POS_VALVES_STATES:self.END_POS_VALVES_STATES])) self.valve_states_all = vst[0] # Extract each valve state from U16 valves states using bit-masking - self.valve_state_VWI["state"] = self._binary_to_valve_state(vst[0] & 1) - self.valve_state_VROD["state"] = self._binary_to_valve_state(vst[0] & 2) - self.valve_state_VFF["state"] = self._binary_to_valve_state(vst[0] & 4) - self.valve_state_VPI["state"] = self._binary_to_valve_state(vst[0] & 8) - self.valve_state_VCR["state"] = self._binary_to_valve_state(vst[0] & 16) - self.valve_state_VCB["state"] = self._binary_to_valve_state(vst[0] & 32) - self.valve_state_VCD["state"] = self._binary_to_valve_state(vst[0] & 64) - self.valve_state_VFB["state"] = self._binary_to_valve_state(vst[0] & 128) - self.valve_state_SPP["state"] = self._binary_to_valve_state(vst[0] & 256) + self.m4_vwi_state["state"] = self._binary_to_valve_state(vst[0] & 1) + self.p39_vrod_state["state"] = self._binary_to_valve_state(vst[0] & 2) + self.p6_vff_state["state"] = self._binary_to_valve_state(vst[0] & 4) + self.p11_vpi_state["state"] = self._binary_to_valve_state(vst[0] & 8) + self.p33_vcr_state["state"] = self._binary_to_valve_state(vst[0] & 16) + self.p34_vcb_state["state"] = self._binary_to_valve_state(vst[0] & 32) + self.p37_vcd_state["state"] = self._binary_to_valve_state(vst[0] & 64) + self.m7_vfb_state["state"] = self._binary_to_valve_state(vst[0] & 128) + self.p20_spp_state["state"] = self._binary_to_valve_state(vst[0] & 256) start = self.END_POS_VALVES_STATES end = start + 1 @@ -190,7 +190,7 @@ """ Constructs and sends the valve sensed state override command. Constraints: - Must be logged into DG. + Must be logged into RO. Given valve ID must be one of the valve IDs listed below. @param valve: unsigned int - valve ID @@ -223,7 +223,7 @@ def cmd_valve_override(self, valve: int, state: int, reset: int = NO_RESET) -> int: """ - Constructs and sends the valve state override command. + Constructs and sends the RO valve state override command. Constraints: Must be logged into RO. Given valve ID must be one of the valve IDs listed below. @@ -258,10 +258,10 @@ def cmd_valve_broadcast_interval_override(self, ms: int, reset: int = NO_RESET) -> int: """ - Constructs and sends the valve state override command. + Constructs and sends the RO valve state override command. Constraints: - Must be logged into DG. - Given interval must be non-zero and a multiple of the DG general task interval (50 ms). + Must be logged into RO. + Given interval must be non-zero and a multiple of the RO general task interval (50 ms). @param ms: unsigned int - broadcast interval (in ms) @param reset: integer - 1 to reset a previous override, 0 to override @@ -280,7 +280,7 @@ message_id=MsgIds.MSG_ID_RO_VALVE_PUBLISH_INTERVAL_OVERRIDE_REQUEST.value, payload=payload) - self.logger.debug("override valves states publish interval") + self.logger.debug("override RO valves states publish interval") # Send message received_message = self.can_interface.send(message) Index: leahi_dialin/ro/reverse_osmosis.py =================================================================== diff -u -r2bb54c406eebc4e090a0e70e9b62eb55ccd92f1b -rdfbb4f080638b65d9836b22bd5c76d46d53abba5 --- leahi_dialin/ro/reverse_osmosis.py (.../reverse_osmosis.py) (revision 2bb54c406eebc4e090a0e70e9b62eb55ccd92f1b) +++ leahi_dialin/ro/reverse_osmosis.py (.../reverse_osmosis.py) (revision dfbb4f080638b65d9836b22bd5c76d46d53abba5) @@ -5,7 +5,7 @@ # THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN # WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. # -# @file treatment_delivery.py +# @file filtration_purification.py # # @author (last) Dara Navaei # @date (last) 26-Feb-2024 @@ -34,7 +34,7 @@ class RO(AbstractSubSystem): """ - Treatment Delivery (RO) Dialin object API. + Reverse Osmosis ( RO aka IOFP ) Dialin object API. It provides the basic interface to communicate with the RO firmware. """ # RO debug event max count @@ -105,7 +105,7 @@ # Create command groups self.conductivity = ROConductivitySensors(self.can_interface, self.logger) - self.flow = ROFlowSensors(self.can_interface, self.logger) + self.flows = ROFlowSensors(self.can_interface, self.logger) self.pumps = ROPumps(self.can_interface, self.logger) self.flows = ROFlowSensors(self.can_interface, self.logger) self.levels = ROLevels(self.can_interface, self.logger)