Index: DialityCoreCanProtocol.py =================================================================== diff -u -r65448aafb518b3e8a7cb5de5ca115666cec839d1 -re0254e59354475c1e7c95ac4c0ff033a33d98fd7 --- DialityCoreCanProtocol.py (.../DialityCoreCanProtocol.py) (revision 65448aafb518b3e8a7cb5de5ca115666cec839d1) +++ DialityCoreCanProtocol.py (.../DialityCoreCanProtocol.py) (revision e0254e59354475c1e7c95ac4c0ff033a33d98fd7) @@ -359,6 +359,7 @@ self.__longMsgChannelIDSet = set() self.__dialinMessageList = None + self.__lastSentMessage = None self.__dialinCommandResponseMessage = None self.__dialinResponseChannelID = -1 @@ -505,42 +506,53 @@ \returns: Diality Packet, it it times out it returns None """ - channel_id = DenaliMessage.getChannelID(built_message) + msg_sent = False - padded_can_message_array = built_message['message'] + # keep trying to send message until we get a response + while msg_sent is not True: + self.__lastSentMessage = built_message - self.__sendPacketRequestID = DenaliMessage.getMessageID(built_message) + channel_id = DenaliMessage.getChannelID(built_message) - # A message can be longer than 8 bytes, so we need to split it - # into 8 bytes packets. + padded_can_message_array = built_message['message'] - number_of_packets = DenaliMessage.getTotalPackets(padded_can_message_array) + self.__sendPacketRequestID = DenaliMessage.getMessageID(built_message) - # We are sending one message at a time on CAN + # A message can be longer than 8 bytes, so we need to split it + # into 8 bytes packets. - for n in range(number_of_packets): - packet = padded_can_message_array[n * DenaliMessage.PACKET_LENGTH: - (n + 1) * DenaliMessage.PACKET_LENGTH] + number_of_packets = DenaliMessage.getTotalPackets(padded_can_message_array) - # Sending one packet at a time - packet = can.Message(arbitration_id=channel_id, - data=packet, - is_extended_id=False) + # We are sending one message at a time on CAN - self.__bus.send(packet) + for n in range(number_of_packets): + packet = padded_can_message_array[n * DenaliMessage.PACKET_LENGTH: + (n + 1) * DenaliMessage.PACKET_LENGTH] - # Sending - self.__dialinCommandResponseMessage = None + # Sending one packet at a time + packet = can.Message(arbitration_id=channel_id, + data=packet, + is_extended_id=False) - # After all message has been sent, we clear a flag - self.__sendEvent.clear() + self.__bus.send(packet) - # At this point, we sleep until the system times out or flag is set - self.__sendEvent.wait(time_out) + # Sending + self.__dialinCommandResponseMessage = None - # We are ready to send again. Reset request ID appropriately - self.__sendPacketRequestID = -1 + # After all message has been sent, we clear a flag + self.__sendEvent.clear() + # At this point, we sleep until the system times out or flag is set + self.__sendEvent.wait(time_out) + + if self.__dialinCommandResponseMessage is not None: + msg_sent = True + else: + print("No response. Re-sending message.") + + # We are ready to send again. Reset request ID appropriately + self.__sendPacketRequestID = -1 + # This value is None or it has a message depending of the listener return self.__dialinCommandResponseMessage Index: HD_DialOutFlow.py =================================================================== diff -u -r55ee2778e43810b13382aed3a287edb06f332f69 -re0254e59354475c1e7c95ac4c0ff033a33d98fd7 --- HD_DialOutFlow.py (.../HD_DialOutFlow.py) (revision 55ee2778e43810b13382aed3a287edb06f332f69) +++ HD_DialOutFlow.py (.../HD_DialOutFlow.py) (revision e0254e59354475c1e7c95ac4c0ff033a33d98fd7) @@ -44,19 +44,20 @@ function=self.receiveDialysateUFDataHandler) ## DialOutBroadcast a dictionary storing latest broadcast values of the following keys: # state, target_volume, measured_volume, pwm, motor_current, motor_speed. - self.DialOutBroadcast = {'state': 'None', - 'target_volume': 0, + self.DialOutBroadcast = {'target_volume': 0, 'measured_volume': 0, - 'pwm': 0, - 'motor_current': 0, - 'motor_speed': 0} + 'motor_rotor_speed': 0, + 'motor_speed': 0, + 'motor_mc_speed': 0, + 'motor_mc_current': 0, + 'pwm': 0} - self.__BroadCastSignals = {'time': [], - 'state': [], - 'target_volume': [], - 'measured_volume': [], - 'pwm': []} - self.__time = 0 + #self.__BroadCastSignals = {'time': [], + # 'state': [], + # 'target_volume': [], + # 'measured_volume': [], + # 'pwm': []} + #self.__time = 0 def setUFState(self, new_state): """ @@ -136,12 +137,12 @@ self.DialOutBroadcast['motor_speed'] = np.int16(int.from_bytes(bytearray(payload[10:12]), byteorder=DenaliMessage.BYTE_ORDER, signed=True)) - self.__BroadCastSignals['time'].append(self.__time) - self.__BroadCastSignals['state'].append(state_num * 100) - self.__BroadCastSignals['target_volume'].append(self.DialOutBroadcast['target_volume']) - self.__BroadCastSignals['measured_volume'].append(self.DialOutBroadcast['measured_volume']) - self.__BroadCastSignals['pwm'].append(self.DialOutBroadcast['pwm']) - self.__time += 1 + #self.__BroadCastSignals['time'].append(self.__time) + #self.__BroadCastSignals['state'].append(state_num * 100) + #self.__BroadCastSignals['target_volume'].append(self.DialOutBroadcast['target_volume']) + #self.__BroadCastSignals['measured_volume'].append(self.DialOutBroadcast['measured_volume']) + #self.__BroadCastSignals['pwm'].append(self.DialOutBroadcast['pwm']) + #self.__time += 1 def plotBroadCastSignals(self): """ Index: HemodialysisDevice.py =================================================================== diff -u -r519260ce5bc660d7d44c612848412ea4e50ca662 -re0254e59354475c1e7c95ac4c0ff033a33d98fd7 --- HemodialysisDevice.py (.../HemodialysisDevice.py) (revision 519260ce5bc660d7d44c612848412ea4e50ca662) +++ HemodialysisDevice.py (.../HemodialysisDevice.py) (revision e0254e59354475c1e7c95ac4c0ff033a33d98fd7) @@ -53,7 +53,8 @@ self.Buttons = HD.HD_Buttons(self) self.BloodFlow = HD.HD_BloodFlow(self, self.can_interface) self.RTC = HD.HD_RTC(self, self.can_interface) - #self.DialysateInletFlow = HD.HD_DialysateInletFlow(self, self.can_interface) + self.DialysateInletFlow = HD.HD_DialysateInletFlow(self, self.can_interface) + self.DialysateOutletFlow = HD.HD_DialysateOutletFlow(self, self.can_interface) self.Watchdog = HD.HD_Watchdog(self) ## DialOut is an HD_DialOutFlow object # self.DialOut = HD_DialOut(self.can_interface) @@ -588,8 +589,6 @@ print("Timeout!!!!") return False - - class HD_BloodFlow: """ \class HD_BloodFlow @@ -732,7 +731,7 @@ """ rst = self.outer_instance.integer2ByteArray(reset) - flo = self.outer_instance.integer2ByteArray(flow) + flo = self.outer_instance.float2ByteArray(flow) payload = rst + flo message = DenaliMessage.buildMessage(channel_id=DenaliChannels.dialin_to_hd_ch_id, @@ -770,7 +769,7 @@ """ rst = self.outer_instance.integer2ByteArray(reset) - spd = self.outer_instance.integer2ByteArray(speed) + spd = self.outer_instance.float2ByteArray(speed) payload = rst + spd message = DenaliMessage.buildMessage(channel_id=DenaliChannels.dialin_to_hd_ch_id, @@ -802,12 +801,12 @@ Constructs and sends the measured blood pump motor current override command \param reset: integer - 1 to reset a previous override, 0 to override - \param curr: integer - current (in mA) to override with + \param curr: float - current (in mA) to override with \returns 1 if successful, zero otherwise """ rst = self.outer_instance.integer2ByteArray(reset) - cur = self.outer_instance.integer2ByteArray(curr) + cur = self.outer_instance.float2ByteArray(curr) payload = rst + cur message = DenaliMessage.buildMessage(channel_id=DenaliChannels.dialin_to_hd_ch_id, @@ -845,7 +844,7 @@ """ rst = self.outer_instance.integer2ByteArray(reset) - spd = self.outer_instance.integer2ByteArray(speed) + spd = self.outer_instance.float2ByteArray(speed) payload = rst + spd message = DenaliMessage.buildMessage(channel_id=DenaliChannels.dialin_to_hd_ch_id, @@ -883,7 +882,7 @@ """ rst = self.outer_instance.integer2ByteArray(reset) - spd = self.outer_instance.integer2ByteArray(speed) + spd = self.outer_instance.float2ByteArray(speed) payload = rst + spd message = DenaliMessage.buildMessage(channel_id=DenaliChannels.dialin_to_hd_ch_id, @@ -1085,7 +1084,7 @@ """ rst = self.outer_instance.integer2ByteArray(reset) - flo = self.outer_instance.integer2ByteArray(flow) + flo = self.outer_instance.float2ByteArray(flow) payload = rst + flo message = DenaliMessage.buildMessage(channel_id=DenaliChannels.dialin_to_hd_ch_id, @@ -1123,7 +1122,7 @@ """ rst = self.outer_instance.integer2ByteArray(reset) - spd = self.outer_instance.integer2ByteArray(speed) + spd = self.outer_instance.float2ByteArray(speed) payload = rst + spd message = DenaliMessage.buildMessage(channel_id=DenaliChannels.dialin_to_hd_ch_id, @@ -1160,7 +1159,7 @@ """ rst = self.outer_instance.integer2ByteArray(reset) - cur = self.outer_instance.integer2ByteArray(curr) + cur = self.outer_instance.float2ByteArray(curr) payload = rst + cur message = DenaliMessage.buildMessage(channel_id=DenaliChannels.dialin_to_hd_ch_id, @@ -1198,7 +1197,7 @@ """ rst = self.outer_instance.integer2ByteArray(reset) - spd = self.outer_instance.integer2ByteArray(speed) + spd = self.outer_instance.float2ByteArray(speed) payload = rst + spd message = DenaliMessage.buildMessage(channel_id=DenaliChannels.dialin_to_hd_ch_id, @@ -1236,7 +1235,7 @@ """ rst = self.outer_instance.integer2ByteArray(reset) - spd = self.outer_instance.integer2ByteArray(speed) + spd = self.outer_instance.float2ByteArray(speed) payload = rst + spd message = DenaliMessage.buildMessage(channel_id=DenaliChannels.dialin_to_hd_ch_id, @@ -1300,6 +1299,442 @@ print("Timeout!!!!") return False + class HD_DialysateOutletFlow: + """ + \class HD_DialysateOutletFlow + + \brief Hemodialysis Device (HD) Dialin API sub-class for dialysate outlet pump related commands. + + """ + + # DialysateFlow message IDs + MSG_ID_HD_DIAL_OUT_FLOW_PUBLISHED_DATA = 0x000B + 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 + MSG_ID_HD_DIAL_OUT_PUMP_MC_MEAS_SPEED_OVERRIDE = 0x8021 + MSG_ID_HD_DIAL_OUT_PUMP_MC_MEAS_CURRENT_OVERRIDE = 0x8022 + MSG_ID_HD_DIAL_OUT_PUMP_MEAS_SPEED_OVERRIDE = 0x8023 + MSG_ID_HD_DIAL_OUT_PUMP_ROTOR_MEAS_SPEED_OVERRIDE = 0x8024 + MSG_ID_HD_DIAL_OUT_LOAD_CELL_WEIGHT_OVERRIDE = 0x8025 + + # BloodFlow broadcast message field positions + START_POS_REF_VOL = DenaliMessage.PAYLOAD_START_INDEX + END_POS_REF_VOL = START_POS_REF_VOL + 4 + START_POS_MEAS_VOL = END_POS_REF_VOL + END_POS_MEAS_VOL = START_POS_MEAS_VOL + 4 + START_POS_MEAS_ROT_SPEED = END_POS_MEAS_VOL + END_POS_MEAS_ROT_SPEED = START_POS_MEAS_ROT_SPEED + 4 + START_POS_MEAS_SPEED = END_POS_MEAS_ROT_SPEED + END_POS_MEAS_SPEED = START_POS_MEAS_SPEED + 4 + START_POS_MEAS_MC_SPEED = END_POS_MEAS_SPEED + END_POS_MEAS_MC_SPEED = START_POS_MEAS_MC_SPEED + 4 + START_POS_MEAS_MC_CURR = END_POS_MEAS_MC_SPEED + END_POS_MEAS_MC_CURR = START_POS_MEAS_MC_CURR + 4 + START_POS_PWM_DC = END_POS_MEAS_MC_CURR + END_POS_PWM_DC = START_POS_PWM_DC + 4 + + def __init__(self, outer_instance, can_interface=None): + """ + HD_DialysateFlow constructor + + \param outer_instance: reference to the HD (outer) class. + + \returns HD_DialysateFlow 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_DIAL_OUT_FLOW_PUBLISHED_DATA + can_interface.registerReceivingPublicationFunction(channel_id, msg_id, + self.handlerDialysateOutletFlowSyncFunction) + + self.ReferenceDialysateOutletUFVolume = 0.0 + self.MeasuredDialysateOutletUFVolume = 0.0 + self.MeasuredDialysateOutletPumpRotorSpeed = 0.0 + self.MeasuredDialysateOutletPumpSpeed = 0.0 + self.MeasuredDialysateOutletPumpMCSpeed = 0.0 + self.MeasuredDialysateOutletPumpMCCurrent = 0.0 + self.PWMDutyCyclePct = 0.0 + + def handlerDialysateOutletFlowSyncFunction(self, message): + """ + Handles published dialysate inlet flow data messages. Dialysate flow data are captured + for reference. + + \param message: published dialysate flow data message + \returns none + """ + + refVol = struct.unpack('f', bytearray( + message['message'][self.START_POS_REF_VOL:self.END_POS_REF_VOL])) + measVol = struct.unpack('f', bytearray( + message['message'][self.START_POS_MEAS_VOL:self.END_POS_MEAS_VOL])) + rotor = struct.unpack('f', bytearray( + message['message'][self.START_POS_MEAS_ROT_SPEED:self.END_POS_MEAS_ROT_SPEED])) + speed = struct.unpack('f', bytearray( + message['message'][self.START_POS_MEAS_SPEED:self.END_POS_MEAS_SPEED])) + mcspeed = struct.unpack('f', bytearray( + message['message'][self.START_POS_MEAS_MC_SPEED:self.END_POS_MEAS_MC_SPEED])) + mccurr = struct.unpack('f', bytearray( + message['message'][self.START_POS_MEAS_MC_CURR:self.END_POS_MEAS_MC_CURR])) + pwm = struct.unpack('f', bytearray( + message['message'][self.START_POS_PWM_DC:self.END_POS_PWM_DC])) + + self.ReferenceDialysateOutletUFVolume = refVol[0] + self.MeasuredDialysateOutletUFVolume = measVol[0] + self.MeasuredDialysateOutletPumpRotorSpeed = rotor[0] + self.MeasuredDialysateOutletPumpSpeed = speed[0] + self.MeasuredDialysateOutletPumpMCSpeed = mcspeed[0] + self.MeasuredDialysateOutletPumpMCCurrent = mccurr[0] + self.PWMDutyCyclePct = pwm[0] + + def CmdDialysateOutletReferenceUFVolumeOverride(self, reset, refVol): + """ + Constructs and sends the UF reference volume override command + + \param reset: integer - 1 to reset a previous override, 0 to override + \param refVol: float - reference UF volume (in mL) to override with + \returns 1 if successful, zero otherwise + """ + + rst = self.outer_instance.integer2ByteArray(reset) + vol = self.outer_instance.float2ByteArray(refVol) + payload = rst + vol + + message = DenaliMessage.buildMessage(channel_id=DenaliChannels.dialin_to_hd_ch_id, + message_id=self.MSG_ID_HD_DIAL_OUT_UF_REF_VOLUME_OVERRIDE, + payload=payload) + + print("override UF reference volume with " + str(refVol) + "mL.") + + # 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. " + else: + str_res = "overridden to " + str(refVol) + " mL. " + print( + "UF reference volume " + 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 CmdDialysateInletMeasuredUFVolumeOverride(self, reset, measVol): + """ + Constructs and sends the measured UF volume override command + + \param reset: integer - 1 to reset a previous override, 0 to override + \param measVol: float - measured UF volume (in mL) to override with + \returns 1 if successful, zero otherwise + """ + + rst = self.outer_instance.integer2ByteArray(reset) + vol = self.outer_instance.float2ByteArray(measVol) + payload = rst + vol + + message = DenaliMessage.buildMessage(channel_id=DenaliChannels.dialin_to_hd_ch_id, + message_id=self.MSG_ID_HD_DIAL_OUT_UF_MEAS_VOLUME_OVERRIDE, + payload=payload) + + print("override measured UF volume with " + str(measVol) + " mL.") + + # 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. " + else: + str_res = "overridden to " + str(measVol) + " mL. " + print("UF measured volume " + 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 CmdDialysateInletPumpMCMeasuredSpeedOverride(self, reset, speed): + """ + Constructs and sends the measured dialysate outlet pump motor controller speed \n + override command. + + \param reset: integer - 1 to reset a previous override, 0 to override + \param speed: float - speed (in RPM) to override with + \returns 1 if successful, zero otherwise + """ + + rst = self.outer_instance.integer2ByteArray(reset) + spd = self.outer_instance.float2ByteArray(speed) + payload = rst + spd + + message = DenaliMessage.buildMessage(channel_id=DenaliChannels.dialin_to_hd_ch_id, + message_id=self.MeasuredDialysateOutletPumpMCSpeed, + payload=payload) + + print("override measured dialysate outlet pump motor controller speed to " + str(spd) + " RPM.") + + # 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. " + else: + str_res = "overridden to " + str(speed) + " RPM. " + print("Dialysate 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): + """ + Constructs and sends the measured dialysate outlet pump motor current override command + + \param reset: integer - 1 to reset a previous override, 0 to override + \param curr: float - current (in mA) to override with + \returns 1 if successful, zero otherwise + """ + + rst = self.outer_instance.integer2ByteArray(reset) + cur = self.outer_instance.float2ByteArray(curr) + payload = rst + cur + + message = DenaliMessage.buildMessage(channel_id=DenaliChannels.dialin_to_hd_ch_id, + message_id=self.MSG_ID_HD_DIAL_OUT_PUMP_MC_MEAS_CURRENT_OVERRIDE, + payload=payload) + + print("override measured dialysate inlet pump motor controller current") + + # 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. " + else: + str_res = "overridden to " + str(curr) + " mA. " + print("Dialysate inlet 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] + else: + print("Timeout!!!!") + return False + + def CmdDialysateOutletPumpMeasuredSpeedOverride(self, reset, speed): + """ + Constructs and sends the measured dialysate outlet pump motor speed override \n + command. + + \param reset: integer - 1 to reset a previous override, 0 to override + \param speed: float - speed (in RPM) to override with + \returns 1 if successful, zero otherwise + """ + + rst = self.outer_instance.integer2ByteArray(reset) + spd = self.outer_instance.float2ByteArray(speed) + payload = rst + spd + + message = DenaliMessage.buildMessage(channel_id=DenaliChannels.dialin_to_hd_ch_id, + message_id=self.MSG_ID_HD_DIAL_OUT_PUMP_MEAS_SPEED_OVERRIDE, + payload=payload) + + print("override measured dialysate outlet pump speed to " + str(speed) + " RPM.") + + # 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. " + else: + str_res = "overridden to " + str(speed) + " RPM. " + print("Dialysate inlet 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] + else: + print("Timeout!!!!") + return False + + def CmdDialysateOutletPumpRotorMeasuredSpeedOverride(self, reset, speed): + """ + Constructs and sends the measured dialysate outlet pump rotor speed override \n + command. + + \param reset: integer - 1 to reset a previous override, 0 to override + \param speed: float - speed (in RPM) to override with + \returns 1 if successful, zero otherwise + """ + + rst = self.outer_instance.integer2ByteArray(reset) + spd = self.outer_instance.float2ByteArray(speed) + payload = rst + spd + + message = DenaliMessage.buildMessage(channel_id=DenaliChannels.dialin_to_hd_ch_id, + message_id=self.MSG_ID_HD_DIAL_OUT_PUMP_ROTOR_MEAS_SPEED_OVERRIDE, + payload=payload) + + print("override measured dialysate outlet pump rotor speed to " + str(speed) + " RPM.") + + # 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. " + else: + str_res = "overridden to " + str(speed) + " RPM. " + print("Dialysate inlet 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] + else: + print("Timeout!!!!") + return False + + def CmdDialysateOutletFlowBroadcastIntervalOverride(self, reset, ms): + """ + Constructs and sends the measured dialysate outlet flow broadcast interval override command + + \param reset: integer - 1 to reset a previous override, 0 to override + \param ms: integer - interval (in ms) to override with + \returns 1 if successful, zero otherwise + """ + + rst = self.outer_instance.integer2ByteArray(reset) + mis = self.outer_instance.integer2ByteArray(ms) + payload = rst + mis + + message = DenaliMessage.buildMessage(channel_id=DenaliChannels.dialin_to_hd_ch_id, + message_id=self.MSG_ID_HD_DIAL_OUT_FLOW_PUBLISH_INTERVAL_OVERRIDE, + payload=payload) + + print("override dialysate outlet flow broadcast interval to " + str(ms) + " ms.") + + # 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. " + else: + str_res = "overridden to " + str(ms) + " ms. " + print("Dialysate inlet 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. + + \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 + """ + + 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) + + 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) + + # 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: + print("Timeout!!!!") + return False + + 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 1 if successful, zero otherwise + """ + + 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_DIAL_OUT_FLOW_PUBLISHED_DATA, + payload=payload) + + print("measured load cell weights set.") + + # Send message + received_message = self.outer_instance.can_interface.send(message) + + # 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 + def integer2ByteArray(self, val): """ Converts an integer value into a byte array (little endian) @@ -1312,15 +1747,19 @@ b = b[::-1] # little endian byte order return b -# def registerAsyncReceiver(self, message_id, method): -# t1 = method -# t2 = message_id + def float2ByteArray(self, val): + """ + Converts a float value into a byte array (little endian) -# def registerSyncReceiver(self, message_id, method): -# t1 = method -# t2 = message_id + \param val: float to convert to byte array + \returns byte array + """ + s = hex(struct.unpack('