Index: DialityCoreCanProtocol.py =================================================================== diff -u -re0254e59354475c1e7c95ac4c0ff033a33d98fd7 -r678ba7efb2e019c266a119500e572ae5c27b369c --- DialityCoreCanProtocol.py (.../DialityCoreCanProtocol.py) (revision e0254e59354475c1e7c95ac4c0ff033a33d98fd7) +++ DialityCoreCanProtocol.py (.../DialityCoreCanProtocol.py) (revision 678ba7efb2e019c266a119500e572ae5c27b369c) @@ -338,6 +338,7 @@ class DenaliCanMessenger: START_BYTE = DenaliMessage.START_BYTE + DIALIN_MSG_RESP_TO = 1 # number of seconds to wait for a response to a sent command def __init__(self, can_interface='can0'): """ @@ -496,7 +497,7 @@ else: self.__sync_response_dictionary[channel_id] = {message_id: function} - def send(self, built_message, time_out=1): + def send(self, built_message, time_out=DIALIN_MSG_RESP_TO): """ sends can_packet to channel_id. @@ -547,6 +548,8 @@ if self.__dialinCommandResponseMessage is not None: msg_sent = True + elif time_out == 0: + msg_sent = True else: print("No response. Re-sending message.") Index: HemodialysisDevice.py =================================================================== diff -u -re0254e59354475c1e7c95ac4c0ff033a33d98fd7 -r678ba7efb2e019c266a119500e572ae5c27b369c --- HemodialysisDevice.py (.../HemodialysisDevice.py) (revision e0254e59354475c1e7c95ac4c0ff033a33d98fd7) +++ HemodialysisDevice.py (.../HemodialysisDevice.py) (revision 678ba7efb2e019c266a119500e572ae5c27b369c) @@ -55,6 +55,7 @@ self.RTC = HD.HD_RTC(self, self.can_interface) self.DialysateInletFlow = HD.HD_DialysateInletFlow(self, self.can_interface) self.DialysateOutletFlow = HD.HD_DialysateOutletFlow(self, self.can_interface) + self.Treatment = HD.HD_Treatment(self, self.can_interface) self.Watchdog = HD.HD_Watchdog(self) ## DialOut is an HD_DialOutFlow object # self.DialOut = HD_DialOut(self.can_interface) @@ -1309,6 +1310,7 @@ # DialysateFlow message IDs MSG_ID_HD_DIAL_OUT_FLOW_PUBLISHED_DATA = 0x000B + MSG_ID_HD_LOAD_CELL_READINGS = 0x000C MSG_ID_HD_DIAL_OUT_FLOW_PUBLISH_INTERVAL_OVERRIDE = 0x801E MSG_ID_HD_DIAL_OUT_UF_REF_VOLUME_OVERRIDE = 0x801F MSG_ID_HD_DIAL_OUT_UF_MEAS_VOLUME_OVERRIDE = 0x8020 @@ -1360,10 +1362,10 @@ def handlerDialysateOutletFlowSyncFunction(self, message): """ - Handles published dialysate inlet flow data messages. Dialysate flow data are captured + Handles published dialysate outlet flow data messages. Dialysate flow data are captured for reference. - \param message: published dialysate flow data message + \param message: published dialysate outlet flow data message \returns none """ @@ -1428,7 +1430,7 @@ print("Timeout!!!!") return False - def CmdDialysateInletMeasuredUFVolumeOverride(self, reset, measVol): + def CmdDialysateOutletMeasuredUFVolumeOverride(self, reset, measVol): """ Constructs and sends the measured UF volume override command @@ -1465,7 +1467,7 @@ print("Timeout!!!!") return False - def CmdDialysateInletPumpMCMeasuredSpeedOverride(self, reset, speed): + def CmdDialysateOutletPumpMCMeasuredSpeedOverride(self, reset, speed): """ Constructs and sends the measured dialysate outlet pump motor controller speed \n override command. @@ -1495,15 +1497,15 @@ str_res = "reset back to normal. " else: str_res = "overridden to " + str(speed) + " RPM. " - print("Dialysate pump MC speed (measured) " + str_res + + print("Dialysate outlet pump MC speed (measured) " + 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 - def CmdDialysateInletPumpMeasuredCurrentOverride(self, reset, curr): + def CmdDialysateOutletPumpMeasuredCurrentOverride(self, reset, curr): """ Constructs and sends the measured dialysate outlet pump motor current override command @@ -1520,7 +1522,7 @@ message_id=self.MSG_ID_HD_DIAL_OUT_PUMP_MC_MEAS_CURRENT_OVERRIDE, payload=payload) - print("override measured dialysate inlet pump motor controller current") + print("override measured dialysate outlet pump motor controller current") # Send message received_message = self.outer_instance.can_interface.send(message) @@ -1532,7 +1534,7 @@ str_res = "reset back to normal. " else: str_res = "overridden to " + str(curr) + " mA. " - print("Dialysate inlet pump MC current (measured) " + str_res + + print("Dialysate outlet pump MC current (measured) " + 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] @@ -1570,7 +1572,7 @@ str_res = "reset back to normal. " else: str_res = "overridden to " + str(speed) + " RPM. " - print("Dialysate inlet pump speed (measured) " + str_res + + print("Dialysate outlet pump speed (measured) " + 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] @@ -1608,7 +1610,7 @@ str_res = "reset back to normal. " else: str_res = "overridden to " + str(speed) + " RPM. " - print("Dialysate inlet pump rotor speed (measured) " + str_res + + print("Dialysate outlet pump rotor speed (measured) " + 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] @@ -1645,96 +1647,146 @@ str_res = "reset back to normal. " else: str_res = "overridden to " + str(ms) + " ms. " - print("Dialysate inlet flow broadcast interval " + str_res + + print("Dialysate outlet flow broadcast interval " + 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 - def CmdDialysateOutletPumpLoadCellWeightOverride(self, reset, weight, sensor): - """ - Constructs and sends the measured load cell weight override command. + def CmdDialysateOutletPumpLoadCellWeightOverride(self, reset, weight, sensor): + """ + Constructs and sends the measured load cell weight override command. - \param reset: integer - 1 to reset a previous override, 0 to override - \param weight: float - weight (in g) to override with - \param sensor: integer - ID of load cell to override - \returns 1 if successful, zero otherwise + \param reset: integer - 1 to reset a previous override, 0 to override + \param weight: float - weight (in g) to override with + \param sensor: integer - ID of load cell to override + \returns 1 if successful, zero otherwise - \details Load Cells: \n - 0 = reservoir 1 primary \n - 1 = reservoir 1 backup \n - 2 = reservoir 2 primary \n - 3 = reservoir 2 backup \n - """ + \details Load Cells: \n + 0 = reservoir 1 primary \n + 1 = reservoir 1 backup \n + 2 = reservoir 2 primary \n + 3 = reservoir 2 backup \n + """ - rst = self.outer_instance.integer2ByteArray(reset) - spd = self.outer_instance.float2ByteArray(weight) - sen = self.outer_instance.integer2ByteArray(sensor) - payload = rst + spd + sen + rst = self.outer_instance.integer2ByteArray(reset) + spd = self.outer_instance.float2ByteArray(weight) + sen = self.outer_instance.integer2ByteArray(sensor) + payload = rst + spd + sen - message = DenaliMessage.buildMessage(channel_id=DenaliChannels.dialin_to_hd_ch_id, - message_id=self.MSG_ID_HD_DIAL_OUT_LOAD_CELL_WEIGHT_OVERRIDE, - payload=payload) + message = DenaliMessage.buildMessage(channel_id=DenaliChannels.dialin_to_hd_ch_id, + message_id=self.MSG_ID_HD_DIAL_OUT_LOAD_CELL_WEIGHT_OVERRIDE, + payload=payload) - print("override measured load cell weight to " + str(weight) + " grams for load cell # " + str(sensor)) + print("override measured load cell weight to " + str(weight) + " grams for load cell # " + str(sensor)) - # Send message - received_message = self.outer_instance.can_interface.send(message) + # Send message + received_message = self.outer_instance.can_interface.send(message) - # If there is content... - if received_message is not None: - # print(received_message) - if reset == HD.RESET: - str_res = "reset back to normal. " + # If there is content... + if received_message is not None: + # print(received_message) + if reset == HD.RESET: + str_res = "reset back to normal. " + else: + str_res = "overridden to " + str(weight) + " grams. " + print("Load cell # " + str(sensor) + " " + 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: - str_res = "overridden to " + str(weight) + " grams. " - print("Load cell # " + str(sensor) + " " + 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 + print("Timeout!!!!") + return False - def CmdSetLoadCellWeights(self, r1p, r1b, r2p, r2b): + def CmdSetLoadCellWeights(self, r1p, r1b, r2p, r2b): + """ + Constructs and sends the set load cell weights command. + + \param r1p: float - weight (in g) for reservoir 1 primary load cell + \param r1b: float - weight (in g) for reservoir 1 backup load cell + \param r2p: float - weight (in g) for reservoir 2 primary load cell + \param r2b: float - weight (in g) for reservoir 2 backup load cell + \returns 0 - no response will come from HD for this message + """ + + r1pb = self.outer_instance.float2ByteArray(r1p) + r1bb = self.outer_instance.float2ByteArray(r1b) + r2pb = self.outer_instance.float2ByteArray(r2p) + r2bb = self.outer_instance.float2ByteArray(r2b) + payload = r1pb + r1bb + r2pb + r2bb + + message = DenaliMessage.buildMessage(channel_id=DenaliChannels.dialin_to_hd_ch_id, + message_id=self.MSG_ID_HD_LOAD_CELL_READINGS, + payload=payload) + + print("measured load cell weights set.") + + # Send message + received_message = self.outer_instance.can_interface.send(message, 0) + + return 0 + + class HD_Treatment: """ - Constructs and sends the set load cell weights command. + \class HD_Treatment - \param r1p: float - weight (in g) for reservoir 1 primary load cell - \param r1b: float - weight (in g) for reservoir 1 backup load cell - \param r2p: float - weight (in g) for reservoir 2 primary load cell - \param r2b: float - weight (in g) for reservoir 2 backup load cell - \returns 1 if successful, zero otherwise + \brief Hemodialysis Device (HD) Dialin API sub-class for treatment related commands. + """ - r1pb = self.outer_instance.float2ByteArray(r1p) - r1bb = self.outer_instance.float2ByteArray(r1b) - r2pb = self.outer_instance.float2ByteArray(r2p) - r2bb = self.outer_instance.float2ByteArray(r2b) - payload = r1pb + r1bb + r2pb + r2bb + # BloodFlow message IDs + MSG_ID_HD_TREATMENT_TIME_PUBLISHED_DATA = 0x000D - message = DenaliMessage.buildMessage(channel_id=DenaliChannels.dialin_to_hd_ch_id, - message_id=self.MSG_ID_HD_DIAL_OUT_FLOW_PUBLISHED_DATA, - payload=payload) + # BloodFlow broadcast message field positions + START_POS_TIME_PRES = DenaliMessage.PAYLOAD_START_INDEX + END_POS_TIME_PRES = START_POS_TIME_PRES + 4 + START_POS_TIME_ELAPSED = END_POS_TIME_PRES + END_POS_TIME_ELAPSED = START_POS_TIME_ELAPSED + 4 + START_POS_TIME_REMAINING = END_POS_TIME_ELAPSED + END_POS_TIME_REMAINING = START_POS_TIME_REMAINING + 4 - print("measured load cell weights set.") + def __init__(self, outer_instance, can_interface=None): + """ + HD_Treatment constructor - # Send message - received_message = self.outer_instance.can_interface.send(message) + \param outer_instance: reference to the HD (outer) class. - # If there is content... - if received_message is not None: - # print(received_message) - print("setting of load cells response = " + - 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 + \returns HD_Treatment object. + """ + self.outer_instance = outer_instance + if can_interface is not None: + channel_id = DenaliChannels.hd_sync_broadcast_ch_id + msg_id = self.MSG_ID_HD_TREATMENT_TIME_PUBLISHED_DATA + can_interface.registerReceivingPublicationFunction(channel_id, msg_id, + self.handlerTreatmentTimeSyncFunction) + + self.TreatmentTimePrescribed = 0 + self.TreatmentTimeElapsed = 0 + self.TreatmentTimeRemaining = 0 + + def handlerTreatmentTimeSyncFunction(self, message): + """ + Handles published treatment time data messages. Treatment time data are captured + for reference. + + \param message: published treatment time data message + \returns none + """ + + tot = struct.unpack('i',bytearray( + message['message'][self.START_POS_TIME_PRES:self.END_POS_TIME_PRES])) + ela = struct.unpack('i',bytearray( + message['message'][self.START_POS_TIME_ELAPSED:self.END_POS_TIME_ELAPSED])) + rem = struct.unpack('i',bytearray( + message['message'][self.START_POS_TIME_REMAINING:self.END_POS_TIME_REMAINING])) + + self.TreatmentTimePrescribed = tot[0] + self.TreatmentTimeElapsed = ela[0] + self.TreatmentTimeRemaining = rem[0] + def integer2ByteArray(self, val): """ Converts an integer value into a byte array (little endian) @@ -1754,10 +1806,11 @@ \param val: float to convert to byte array \returns byte array """ - s = hex(struct.unpack('