Index: dialin/dg/heaters.py =================================================================== diff -u -r59cde4f29ed4a5f31caf00ca7687ee7c531ba2c5 -refdf22298708b66820df4084023381f8409634bc --- dialin/dg/heaters.py (.../heaters.py) (revision 59cde4f29ed4a5f31caf00ca7687ee7c531ba2c5) +++ dialin/dg/heaters.py (.../heaters.py) (revision efdf22298708b66820df4084023381f8409634bc) @@ -15,36 +15,159 @@ # ############################################################################ - - import struct -#from ..utils.conversions import integer_to_bytearray +from ..utils.conversions import integer_to_bytearray +from ..utils.conversions import float_to_bytearray from .constants import NO_RESET from ..protocols.CAN import (DenaliMessage, DenaliChannels) class Heaters: MSG_ID_DG_HEATERS_DATA = 0x2C + MSG_ID_START_STOP_PRIMARY_HEATER = 0xA011 + MSG_ID_DG_START_STOP_TRIMMER_HEATER_CMD = 0x2B + MSG_ID_SET_DG_DIALYSATE_TEMP_TARGETS = 0x19 + MSG_ID_HEATERS_PUBLISH_INTERVAL_ORVERRIDE = 0xA013 - START_POS_HEATER_STATES = DenaliMessage.PAYLOAD_START_INDEX - END_POS_HEATER_STATES = START_POS_HEATER_STATES + 2 #3 duty cycles are published each are 32bits so 12 bytes + START_POS_MAIN_PRI_HEATER = DenaliMessage.PAYLOAD_START_INDEX + END_POS_MAIN_PRI_HEATER = START_POS_MAIN_PRI_HEATER + 4 + START_POS_SMALL_PRI_HEATER = END_POS_MAIN_PRI_HEATER + END_POS_SMALL_PRI_HEATER = START_POS_SMALL_PRI_HEATER + 4 + START_POS_TRIMMER_HEATER = END_POS_SMALL_PRI_HEATER + END_POS_TRIMMER_HEATER = START_POS_TRIMMER_HEATER + 4 def __init__(self, can_interface=None): self.can_interface = can_interface + self.mainPrimaryHeaterPWM = 0 + self.smallPrimaryHeaterPWM = 0 + self.trimmerHeaterPWM = 0 - self.heatersData = 0.0 - if self.can_interface is not None: channel_id = DenaliChannels.dg_sync_broadcast_ch_id msg_id = self.MSG_ID_DG_HEATERS_DATA self.can_interface.register_receiving_publication_function(channel_id, msg_id, self.handler_heaters_sync) def handler_heaters_sync(self, message): + """ + Handles published heaters message - heatersData = struct.unpack('H', bytearray(message['message'][self.START_POS_HEATER_STATES:self.END_POS_HEATER_STATES])) - self.heatersData = heatersData[0] - print(heatersData[0]) + \param message: published heaters data message + \returns none + """ + mainPriHeaterPWM = struct.unpack('i', bytearray( + message['message'][self.START_POS_MAIN_PRI_HEATER:self.END_POS_MAIN_PRI_HEATER])) + smallPriHeaterPWM = struct.unpack('i', bytearray( + message['message'][self.START_POS_SMALL_PRI_HEATER:self.END_POS_SMALL_PRI_HEATER])) + trimmerHeaterPWM = struct.unpack('i', bytearray( + message['message'][self.START_POS_TRIMMER_HEATER:self.END_POS_TRIMMER_HEATER])) + self.mainPrimaryHeaterPWM = mainPriHeaterPWM[0] + self.smallPrimaryHeaterPWM = smallPriHeaterPWM[0] + self.trimmerHeaterPWM = trimmerHeaterPWM[0] + def cmd_start_primary_heater(self): + """ + Constructs and sends start primary heater command + \returns none + """ + + # 1 is to start the primary heater + payload = integer_to_bytearray(1) + message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_dg_ch_id, + message_id=self.MSG_ID_START_STOP_PRIMARY_HEATER, + payload=payload) + print("Starting the Primary heater") + self.can_interface.send(message, 0) + + def cmd_stop_primary_heater(self): + """ + Constructs and sends stop primary heater command + + \returns none + """ + # 0 is to stop the primary heater + payload = integer_to_bytearray(0) + message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_dg_ch_id, + message_id=self.MSG_ID_START_STOP_PRIMARY_HEATER, + payload=payload) + print("Stopping the Primary heater") + self.can_interface.send(message, 0) + + def cmd_start_trimmer_heater(self): + """ + Constructs and sends start trimmer heater command + + \returns none + """ + # 1 is to start the primary heater + payload = integer_to_bytearray(1) + message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_dg_ch_id, + message_id=self.MSG_ID_DG_START_STOP_TRIMMER_HEATER_CMD, + payload=payload) + print("Starting the Trimmer heater") + self.can_interface.send(message, 0) + + def cmd_stop_trimmer_heater(self): + """ + Constructs and sends stop trimmer heater command + + \returns none + """ + # 1 is to start the primary heater + payload = integer_to_bytearray(0) + message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_dg_ch_id, + message_id=self.MSG_ID_DG_START_STOP_TRIMMER_HEATER_CMD, + payload=payload) + print("Stopping the Trimmer heater") + self.can_interface.send(message, 0) + + def cmd_set_dialysate_target_temperature(self, pirmaryTargetTemp=37.0, trimmerTargetTemp=38.0): + """ + Constructs and sends primary and trimmer heater target temperature + + \param pirmaryTargetTemp: Primary heater target temperature + \param trimmerTargetTemp: Trimmer heater target temperature + \returns none + """ + primaryTarget = float_to_bytearray(pirmaryTargetTemp) + trimmerTarget = float_to_bytearray(trimmerTargetTemp) + payload = primaryTarget + trimmerTarget + message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_dg_ch_id, + message_id=self.MSG_ID_SET_DG_DIALYSATE_TEMP_TARGETS, + payload=payload) + print("Setting Primary Heater to {} C and Trimmer Heater to {} C".format(pirmaryTargetTemp, trimmerTargetTemp)) + self.can_interface.send(message, 0) + + def cmd_heaters_broadcast_interval_override(self, ms, reset=NO_RESET): + """ + Constructs and sends broadcast time interval + + \param ms: Publish time interval in ms + \param reset: integer - 1 to reset a previous override, 0 to override + \returns 1 if successful, zero otherwise + """ + resetValue = integer_to_bytearray(reset) + intervalValue = integer_to_bytearray(ms) + payload = resetValue + intervalValue + + message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_dg_ch_id, + message_id=self.MSG_ID_HEATERS_PUBLISH_INTERVAL_ORVERRIDE, + payload=payload) + + print("Sending {} ms publish interval to the Heaters 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: + print("Timeout!!!!") + return False + + + + Index: dialin/dg/temperature_sensors.py =================================================================== diff -u -r59cde4f29ed4a5f31caf00ca7687ee7c531ba2c5 -refdf22298708b66820df4084023381f8409634bc --- dialin/dg/temperature_sensors.py (.../temperature_sensors.py) (revision 59cde4f29ed4a5f31caf00ca7687ee7c531ba2c5) +++ dialin/dg/temperature_sensors.py (.../temperature_sensors.py) (revision efdf22298708b66820df4084023381f8409634bc) @@ -15,28 +15,153 @@ # ############################################################################ import struct +from ..utils.conversions import integer_to_bytearray +from .constants import NO_RESET from ..protocols.CAN import (DenaliMessage, DenaliChannels) class TemperatureSensors: MSG_ID_DG_TEMPERATURE_DATA = 0x2D + MSG_ID_TEMPERATURE_SENSORS_PUBLISH_INTERVAL_OVERRIDE = 0xA012 - START_POS_HEATER_STATES = DenaliMessage.PAYLOAD_START_INDEX - END_POS_HEATER_STATES = START_POS_HEATER_STATES + 2 #3 duty cycles are published each are 32bits so 12 bytes + # Inlet primary temperature sensor + START_POS_INLET_PRIMARY_TEMP = DenaliMessage.PAYLOAD_START_INDEX + END_POS_INLET_PRIMARY_TEMP = START_POS_INLET_PRIMARY_TEMP + 4 + # Outlet primary temperature sensor + START_POS_OUTLET_PRIMARY_TEMP = END_POS_INLET_PRIMARY_TEMP + END_POS_OUTLET_PRIMARY_TEMP = START_POS_OUTLET_PRIMARY_TEMP + 4 + # Conductivity sensor 1 temperature sensor + START_POS_CD1_TEMP = END_POS_OUTLET_PRIMARY_TEMP + END_POS_CD1_TEMP = START_POS_CD1_TEMP + 4 + # Conductivity sensor 2 temperature sensor + START_POS_CD2_TEMP = END_POS_CD1_TEMP + END_POS_CD2_TEMP = START_POS_CD2_TEMP + 4 + # Outlet redundancy temperature sensor + START_POS_OUTLET_REDUNDANCY_TEMP = END_POS_CD2_TEMP + END_POS_OUTLET_REDUNDANCY_TEMP = START_POS_OUTLET_REDUNDANCY_TEMP + 4 + # Dialysate inlet temperature sensor + START_POS_INLET_DIALYSATE_TEMP = END_POS_OUTLET_REDUNDANCY_TEMP + END_POS_INLET_DIALYSATE_TEMP = START_POS_INLET_DIALYSATE_TEMP + 4 + # Primary heater thermocouple temperature sensor + START_POS_PRI_TC_TEMP = END_POS_INLET_DIALYSATE_TEMP + END_POS_PRI_TC_TEMP = START_POS_PRI_TC_TEMP + 4 + # Trimmer heater thermocouple temperature sensor + START_POS_TRI_TC_TEMP = END_POS_PRI_TC_TEMP + END_POS_TRI_TC_TEMP = START_POS_TRI_TC_TEMP + 4 + # Primary heater cold junction temperature sensor + START_POS_PRI_CJ_TEMP = END_POS_TRI_TC_TEMP + END_POS_PRI_CJ_TEMP = START_POS_PRI_CJ_TEMP + 4 + # Trimmer heater cold junction temperature sensor + START_POS_TRI_CJ_TEMP = END_POS_PRI_CJ_TEMP + END_POS_TRI_CJ_TEMP = START_POS_TRI_CJ_TEMP + 4 + # Primary heater internal temperature + START_POS_PRI_INTERNAL_TEMP = END_POS_TRI_CJ_TEMP + END_POS_PRI_INTERNAL_TEMP = START_POS_PRI_INTERNAL_TEMP + 4 + # Trimmer heater internal temperature + START_POS_TRI_INTERNAL_TEMP = END_POS_PRI_INTERNAL_TEMP + END_POS_TRI_INTERNAL_TEMP = START_POS_TRI_INTERNAL_TEMP + 4 def __init__(self, can_interface=None): self.can_interface = can_interface - self.temperatureSensorsData = 0.0 + self.inletPrimary = 0.0 + self.outletPrimary = 0.0 + self.cd1 = 0.0 + self.cd2 = 0.0 + self.outletRedundancy = 0.0 + self.inletDialysate = 0.0 + self.primaryTC = 0.0 + self.trimmerTC = 0.0 + self.primaryCJ = 0.0 + self.trimmerCJ = 0.0 + self.primaryInternal = 0.0 + self.trimmerInternal = 0.0 if self.can_interface is not None: channel_id = DenaliChannels.dg_sync_broadcast_ch_id msg_id = self.MSG_ID_DG_TEMPERATURE_DATA self.can_interface.register_receiving_publication_function(channel_id, msg_id, self.handler_temperature_sensors_sync) def handler_temperature_sensors_sync(self, message): + """ + Handles published temperature sensors message - sensorsData = struct.unpack('H', bytearray(message['message'][self.START_POS_HEATER_STATES:self.END_POS_HEATER_STATES])) - self.temperatureSensorsData = sensorsData[0] - print("Sensor {}".format(sensorsData[0])) \ No newline at end of file + \param message: published temperature sensors data message + \returns none + """ + sensorsData = struct.unpack('f', bytearray( + message['message'][self.START_POS_INLET_PRIMARY_TEMP:self.END_POS_INLET_PRIMARY_TEMP])) + self.inletPrimary = sensorsData[0] + + sensorsData = struct.unpack('i', bytearray( + message['message'][self.START_POS_OUTLET_PRIMARY_TEMP:self.END_POS_OUTLET_PRIMARY_TEMP])) + self.outletPrimary = sensorsData[0] + + sensorsData = struct.unpack('i', bytearray( + message['message'][self.START_POS_CD1_TEMP:self.END_POS_CD1_TEMP])) + self.cd1 = sensorsData[0] + + sensorsData = struct.unpack('i', bytearray( + message['message'][self.START_POS_CD2_TEMP:self.END_POS_CD2_TEMP])) + self.cd2 = sensorsData[0] + + sensorsData = struct.unpack('i', bytearray( + message['message'][self.START_POS_OUTLET_REDUNDANCY_TEMP:self.END_POS_OUTLET_REDUNDANCY_TEMP])) + self.outletRedundancy = sensorsData[0] + + sensorsData = struct.unpack('i', bytearray( + message['message'][self.START_POS_INLET_DIALYSATE_TEMP:self.END_POS_INLET_DIALYSATE_TEMP])) + self.inletDialysate = sensorsData[0] + + sensorsData = struct.unpack('i', bytearray( + message['message'][self.START_POS_PRI_TC_TEMP:self.END_POS_PRI_TC_TEMP])) + self.primaryTC = sensorsData[0] + + sensorsData = struct.unpack('i', bytearray( + message['message'][self.START_POS_TRI_TC_TEMP:self.END_POS_TRI_TC_TEMP])) + self.trimmerTC = sensorsData[0] + + sensorsData = struct.unpack('i', bytearray( + message['message'][self.START_POS_PRI_CJ_TEMP:self.END_POS_PRI_CJ_TEMP])) + self.primaryCJ = sensorsData[0] + + sensorsData = struct.unpack('i', bytearray( + message['message'][self.START_POS_TRI_CJ_TEMP:self.END_POS_TRI_CJ_TEMP])) + self.trimmerCJ = sensorsData[0] + + sensorsData = struct.unpack('i', bytearray( + message['message'][self.START_POS_PRI_INTERNAL_TEMP:self.END_POS_PRI_INTERNAL_TEMP])) + self.primaryInternal = sensorsData[0] + + sensorsData = struct.unpack('i', bytearray( + message['message'][self.START_POS_TRI_INTERNAL_TEMP:self.END_POS_TRI_INTERNAL_TEMP])) + self.trimmerInternal = sensorsData[0] + + def cmd_temperature_sensors_broadcast_interval_override(self, ms, reset=NO_RESET): + """ + Constructs and sends broadcast time interval + + \param ms: Publish time interval in ms + \param reset: integer - 1 to reset a previous override, 0 to override + \returns 1 if successful, zero otherwise + """ + resetValue = integer_to_bytearray(reset) + intervalValue = integer_to_bytearray(ms) + payload = resetValue + intervalValue + + message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_dg_ch_id, + message_id=self.MSG_ID_TEMPERATURE_SENSORS_PUBLISH_INTERVAL_OVERRIDE, + payload=payload) + + print("Sending {} ms publish interval to the Temperature Sensors 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: + print("Timeout!!!!") + return False