Index: leahi_dialin/ro/modules/boost_pump.py =================================================================== diff -u -r335b74eca8126497ed23462e21c06f83c6fc90c2 -r3c967e5acc6286c6334d2708600e3317988f87f1 --- leahi_dialin/ro/modules/boost_pump.py (.../boost_pump.py) (revision 335b74eca8126497ed23462e21c06f83c6fc90c2) +++ leahi_dialin/ro/modules/boost_pump.py (.../boost_pump.py) (revision 3c967e5acc6286c6334d2708600e3317988f87f1) @@ -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 blood_flow.py +# @file boost_pump.py # # @author (last) Micahel Garthwaite # @date (last) 17-Aug-2023 Index: leahi_dialin/ro/modules/conductivity.py =================================================================== diff -u --- leahi_dialin/ro/modules/conductivity.py (revision 0) +++ leahi_dialin/ro/modules/conductivity.py (revision 3c967e5acc6286c6334d2708600e3317988f87f1) @@ -0,0 +1 @@ \ No newline at end of file Index: leahi_dialin/ro/modules/flow_sensors.py =================================================================== diff -u --- leahi_dialin/ro/modules/flow_sensors.py (revision 0) +++ leahi_dialin/ro/modules/flow_sensors.py (revision 3c967e5acc6286c6334d2708600e3317988f87f1) @@ -0,0 +1,177 @@ +########################################################################### +# +# Copyright (c) 2020-2024 Diality Inc. - All Rights Reserved. +# +# 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 flow_sensors.py +# +# @author (last) Micahel Garthwaite +# @date (last) 17-Aug-2023 +# @author (original) Peter Lucia +# @date (original) 02-Apr-2020 +# +############################################################################ +import struct +from enum import unique +from logging import Logger + +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, 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 ROFlowSensorNames(DialinEnum): + FLOW_SENSOR_WATER_INLET = 0 # Water inlet flow sensor (FMS P7) + FLOW_SENSOR_RO_OUTLET = 1 # RO outlet flow sensor (FMP P16) + + +class ROFlowSensors(AbstractSubSystem): + """ + + Reverse Osmosis (RO) Dialin API sub-class for flow sensor related commands. + """ + + def __init__(self, can_interface, logger: Logger): + """ + + @param can_interface: Denali CAN Messenger object + """ + + super().__init__() + + self.can_interface = can_interface + self.logger = logger + + if self.can_interface is not None: + channel_id = DenaliChannels.ro_sync_broadcast_ch_id + msg_id = MsgIds.MSG_ID_RO_FLOW_DATA.value + self.can_interface.register_receiving_publication_function(channel_id, msg_id, self._handler_levels_sync) + + + self.flowFMS = 0.0 + self.flowFMP = 0.0 + self.tempFMS = 0.0 + self.tempFMP = 0.0 + + self.ro_flow_timestamp = 0 + + @publish(["ro_levels_timestamp", + "flowFMS", "flowFMP", + "tempFMS", "tempFMP"]) + def _handler_flow_sensor_sync(self, message, timestamp=0.0): + """ + Handles published flow sensor message + + @param message: published levels data message + @returns none + """ + self.flowFMS = struct.unpack('f', bytearray( + message['message'][MsgFieldPositions.START_POS_FIELD_1:MsgFieldPositions.END_POS_FIELD_1]))[0] + self.flowFMP = struct.unpack('f', bytearray( + message['message'][MsgFieldPositions.START_POS_FIELD_2:MsgFieldPositions.END_POS_FIELD_2]))[0] + self.tempFMS = struct.unpack('f', bytearray( + message['message'][MsgFieldPositions.START_POS_FIELD_3:MsgFieldPositions.END_POS_FIELD_3]))[0] + self.tempFMP = struct.unpack('f', bytearray( + message['message'][MsgFieldPositions.START_POS_FIELD_4:MsgFieldPositions.END_POS_FIELD_4]))[0] + + self.ro_levels_timestamp = timestamp + + def cmd_flow_sensor_broadcast_interval_override(self, ms: int, reset: int = NO_RESET) -> int: + """ + Constructs and sends broadcast time interval. + Constraints: + Must be logged into RO. + Given interval must be non-zero and a multiple of the RO general task interval (50 ms). + + @param ms: (int) Publish time interval in ms + @param reset: (int) 1 to reset a previous override, 0 to override + @returns 1 if successful, zero otherwise + """ + if not check_broadcast_interval_override_ms(ms): + return False + + reset_value = integer_to_bytearray(reset) + interval_value = integer_to_bytearray(ms) + payload = reset_value + interval_value + + message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_ro_ch_id, + message_id=MsgIds.MSG_ID_RO_FLOWS_PUBLISH_INTERVAL_OVERRIDE_REQUEST.value, + payload=payload) + + self.logger.debug("Sending {} ms publish interval to the flow sensor module".format(ms)) + # Send message + received_message = self.can_interface.send(message) + + # If there is content in message + if received_message is not None: + # Response payload is OK or not + return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] + else: + self.logger.debug("Timeout!!!!") + return False + + def cmd_flow_rate_override(self, flow_sensor: int, rate: int, reset: int = NO_RESET) -> int: + """ + Constructs and sends flow rate override command + Must be logged into RO + + + @param flow_sensor the sensor to override its value + @param rate the rate value to override + @param reset: (int) 1 to reset a previous override, 0 to override + @returns 1 if successful, zero otherwise + """ + reset_value = integer_to_bytearray(reset) + lvl = integer_to_bytearray(flow_sensor) + sts = float_to_bytearray(rate) + payload = reset_value + sts + lvl + message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_ro_ch_id, + message_id=MsgIds.MSG_ID_RO_FLOW_RATE_OVERRIDE_REQUEST.value, + payload=payload) + + # Send message + received_message = self.can_interface.send(message) + + # If there is content in message + if received_message is not None: + # Response payload is OK or not + return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] + else: + self.logger.debug("Timeout!!!!") + return False + + def cmd_flow_temp_override(self, flow_sensor: int, temp: int, reset: int = NO_RESET) -> int: + """ + Constructs and sends flow temp override command + Must be logged into RO + + + @param flow_sensor the sensor to override its value + @param temp the rate value to override + @param reset: (int) 1 to reset a previous override, 0 to override + @returns 1 if successful, zero otherwise + """ + reset_value = integer_to_bytearray(reset) + lvl = integer_to_bytearray(flow_sensor) + sts = float_to_bytearray(temp) + payload = reset_value + sts + lvl + message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_ro_ch_id, + message_id=MsgIds.MSG_ID_RO_FLOW_TEMP_OVERRIDE_REQUEST.value, + payload=payload) + + # Send message + received_message = self.can_interface.send(message) + + # If there is content in message + if received_message is not None: + # Response payload is OK or not + return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] + else: + self.logger.debug("Timeout!!!!") + return False \ No newline at end of file Index: leahi_dialin/ro/modules/levels.py =================================================================== diff -u -r8c0c7ee456674a5b9c7c407cc03deee0c23993f2 -r3c967e5acc6286c6334d2708600e3317988f87f1 --- leahi_dialin/ro/modules/levels.py (.../levels.py) (revision 8c0c7ee456674a5b9c7c407cc03deee0c23993f2) +++ leahi_dialin/ro/modules/levels.py (.../levels.py) (revision 3c967e5acc6286c6334d2708600e3317988f87f1) @@ -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 heaters.py +# @file levels.py # # @author (last) Michael Garthwaite # @date (last) 28-Oct-2024 @@ -100,7 +100,7 @@ def cmd_level_status_override(self, level_sensor: int, status: int, reset: int = NO_RESET) -> int: """ - Constructs and sends heater duty cycle override command + Constructs and sends level status override command Must be logged into RO Index: leahi_dialin/ro/modules/pressure_sensors.py =================================================================== diff -u -r8c0c7ee456674a5b9c7c407cc03deee0c23993f2 -r3c967e5acc6286c6334d2708600e3317988f87f1 --- leahi_dialin/ro/modules/pressure_sensors.py (.../pressure_sensors.py) (revision 8c0c7ee456674a5b9c7c407cc03deee0c23993f2) +++ leahi_dialin/ro/modules/pressure_sensors.py (.../pressure_sensors.py) (revision 3c967e5acc6286c6334d2708600e3317988f87f1) @@ -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 pressure_occlusion.py +# @file pressure_sensors.py # # @author (last) Vinayakam Mani # @date (last) 02-May-2024 @@ -14,16 +14,27 @@ # ############################################################################ import struct +from enum import unique from logging import Logger 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 ROPressureSensorNames(DialinEnum): + PRESSURE_SENSOR_WATER_INLET_PRE_REG = 0 + PRESSURE_SENSOR_WATER_INLET_POST_REG = 1 + PRESSURE_SENSOR_WATER_INLET_PRE_COND = 2 + PRESSURE_SENSOR_PRE_RO_FILTER = 3 + PRESSURE_SENSOR_POST_RO_FILTER = 4 + PRESSURE_SENSOR_PRE_RO_PUMP = 5 + + class ROPressureSensors(AbstractSubSystem): """ Reverse Osmosis (RO) Dialin API sub-class for pressure related commands.