Index: .gitignore =================================================================== diff -u -rd66e924d16e5b5f62570f57a483acd3f10c50dcc -r74148a933061455b10101e4eb58144ca9d2f3cd2 --- .gitignore (.../.gitignore) (revision d66e924d16e5b5f62570f57a483acd3f10c50dcc) +++ .gitignore (.../.gitignore) (revision 74148a933061455b10101e4eb58144ca9d2f3cd2) @@ -22,4 +22,5 @@ docs/source/dialin.utils.rst docs/source/dialin.squish.rst docs/source/modules.rst +*.swp Index: dialin/dg/conductivity_sensors.py =================================================================== diff -u --- dialin/dg/conductivity_sensors.py (revision 0) +++ dialin/dg/conductivity_sensors.py (revision 74148a933061455b10101e4eb58144ca9d2f3cd2) @@ -0,0 +1,170 @@ +########################################################################### +# +# Copyright (c) 2019-2020 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 conductivity_sensors.py +# +# @date 20-Jul-2020 +# @author Q. Nguyen +# +# @brief +# +# +############################################################################ +import struct +from .constants import RESET,NO_RESET +from ..utils.conversions import integer_to_bytearray, float_to_bytearray +from ..protocols.CAN import (DenaliMessage, DenaliChannels) +from ..utils.base import _AbstractSubSystem, _publish + + +class ConductivitySensors(_AbstractSubSystem): + """ + DGConductivitySensors + + Dialysate Generator (DG) Dialin API sub-class for conductivity sensors related commands. + """ + + # Override message IDs + MSG_ID_DG_CONDUCTIVITY_SENSORS_DATA = 0x0031 + MSG_ID_DG_CONDUCTIVITY_SENSORS_OVERRIDE = 0xA015 + MSG_ID_DG_CONDUCTIVITY_SENSORS_DATA_BROADCAST_INTERVAL_OVERRIDE = 0xA016 + + # Conductivity sensor broadcast message field positions + START_POS_CS_CPI = DenaliMessage.PAYLOAD_START_INDEX + END_POS_CS_CPI = START_POS_CS_CPI + 4 + START_POS_CS_CPO = END_POS_CS_CPI + END_POS_CS_CPO = START_POS_CS_CPO + 4 + START_POS_CS_CD1 = END_POS_CS_CPO + END_POS_CS_CD1 = START_POS_CS_CD1 + 4 + START_POS_CS_CD2 = END_POS_CS_CD1 + END_POS_CS_CD2 = START_POS_CS_CD2 + 4 + + def __init__(self, can_interface=None): + """ + + @param can_interface: Denali Can Messenger object + """ + super().__init__() + + self.can_interface = can_interface + + if self.can_interface is not None: + channel_id = DenaliChannels.dg_sync_broadcast_ch_id + msg_id = self.MSG_ID_DG_CONDUCTIVITY_SENSORS_DATA + self.can_interface.register_receiving_publication_function(channel_id, msg_id, + self._handler_conductivity_sensors_sync) + + self.cpi = 0.0 + self.cpo = 0.0 + self.cd1 = 0.0 + self.cd2 = 0.0 + + def get_conductivity_sensors(self): + """ + Gets the current conductivity value + + @return: List containing conductivity values: [CPI, CPO, CD1, CD2] + """ + return [self.cpi, self.cpo, self.cd1, self.cd2] + + @_publish(["conductivity_sensor_cpi", "conductivity_sensor_cpo", "conductivity_sensor_cd1", "conductivity_sensor_cd2"]) + def _handler_conductivity_sensors_sync(self, message): + """ + Handles published conductivity sensor data messages. Conductivity sensor data are captured + for reference. + + @param message: published conductivity sensor data message + @return: None + """ + + cpi = struct.unpack('f', bytearray(message['message'][self.START_POS_CS_CPI:self.END_POS_CS_CPI])) + cpo = struct.unpack('f', bytearray(message['message'][self.START_POS_CS_CPO:self.END_POS_CS_CPO])) + cd1 = struct.unpack('f', bytearray(message['message'][self.START_POS_CS_CD1:self.END_POS_CS_CD1])) + cd2 = struct.unpack('f', bytearray(message['message'][self.START_POS_CS_CD2:self.END_POS_CS_CD2])) + + self.cpi = cpi[0] + self.cpo = cpo[0] + self.cd1 = cd1[0] + self.cd2 = cd2[0] + + def cmd_conductivity_sensor_override(self, conductivity, sensor, reset=NO_RESET): + """ + Constructs and sends the conductivity value override command + + @param conductivity: float - conductivity value to override sensor with + @param sensor: unsigned int - sensor ID + @param reset: integer - 1 to reset a previous override, 0 to override + @return: 1 if successful, zero otherwise + + Conductivity sensor IDs: \n + 0 = CPI \n + 1 = CPO \n + 2 = CD1 \n + 3 = CD2 \n + """ + + rst = integer_to_bytearray(reset) + cond = float_to_bytearray(conductivity) + idx = integer_to_bytearray(sensor) + payload = rst + cond + idx + + message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_dg_ch_id, + message_id=self.MSG_ID_DG_CONDUCTIVITY_SENSORS_OVERRIDE, + payload=payload) + + if reset == RESET: + str_res = "reset back to normal" + else: + str_res = str(conductivity) + " microsemens/cm" + print("override conductivity sensor value for sensor " + str(sensor) + ": " + str_res) + + # Send message + 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: + print("Timeout!!!!") + return False + + def cmd_conductivity_sensor_data_broadcast_interval_override(self, ms, reset=NO_RESET): + """ + Constructs and sends the conductivity sensor data broadcast interval override command + + @param ms: integer - interval (in ms) to override with + @param reset: integer - 1 to reset a previous override, 0 to override + @return: 1 if successful, zero otherwise + """ + + rst = integer_to_bytearray(reset) + mis = integer_to_bytearray(ms) + payload = rst + mis + + message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_dg_ch_id, + message_id=self.MSG_ID_DG_CONDUCTIVITY_SENSORS_DATA_BROADCAST_INTERVAL_OVERRIDE, + payload=payload) + + print("override DG conductivity sensor broadcast interval") + + # Send message + received_message = self.can_interface.send(message) + + # If there is content... + if received_message is not None: + if reset == RESET: + str_res = "reset back to normal: " + else: + str_res = str(ms) + " ms: " + print("Conductivity sensor data broadcast interval overridden to " + str_res + + str(received_message['message'][DenaliMessage.PAYLOAD_START_INDEX])) + # response payload is OK or not OK + return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] + else: + print("Timeout!!!!") + return False Index: dialin/dg/dialysate_generator.py =================================================================== diff -u -r919980c660e89393848ffc6af4ef25c8309a05dd -r74148a933061455b10101e4eb58144ca9d2f3cd2 --- dialin/dg/dialysate_generator.py (.../dialysate_generator.py) (revision 919980c660e89393848ffc6af4ef25c8309a05dd) +++ dialin/dg/dialysate_generator.py (.../dialysate_generator.py) (revision 74148a933061455b10101e4eb58144ca9d2f3cd2) @@ -23,6 +23,7 @@ from .ro_pump import DGROPump from .heaters import Heaters from .temperature_sensors import TemperatureSensors +from .conductivity_sensors import ConductivitySensors from ..protocols.CAN import (DenaliCanMessenger, DenaliMessage, DenaliChannels) @@ -127,6 +128,7 @@ self.drain_pump = DGDrainPump(self.can_interface) self.heaters = Heaters(self.can_interface) self.temperature_sensors = TemperatureSensors(self.can_interface) + self.conductivity_sensors = ConductivitySensors(self.can_interface) def get_version(self): """