Index: HemodialysisDevice.py =================================================================== diff -u -r2726aefcda8b4efc3a263b0561ea6bae1526b6a2 -rc460fdd776add82105b0688371e2929dcbaf3d57 --- HemodialysisDevice.py (.../HemodialysisDevice.py) (revision 2726aefcda8b4efc3a263b0561ea6bae1526b6a2) +++ HemodialysisDevice.py (.../HemodialysisDevice.py) (revision c460fdd776add82105b0688371e2929dcbaf3d57) @@ -251,21 +251,93 @@ # UI message IDs MSG_ID_UI_CHECKIN_WITH_HD = 0x0007 + MSG_ID_HD_UF_PAUSE_RESUME_REQUEST = 0x0010 + MSG_ID_UF_SETTINGS_CHANGE_REQUEST_BY_USER = 0x0011 + MSG_ID_UF_SETTINGS_CHANGE_RESPONSE_FROM_HD = 0x0013 + MSG_ID_UF_SETTINGS_CHANGE_CONFIRMED_BY_USER = 0x0015 - def __init__(self, outer_instance): + LITER_TO_ML_CONVERSION_FACTOR = 1000.0 + UF_CMD_PAUSE = 0 + UF_CMD_RESUME = 1 + UF_CMD_CHANGE_TIME_TO_ADJUST = 0 + UF_CMD_CHANGE_RATE_TO_ADJUST = 1 + RESPONSE_REJECTED = 0 + RESPONSE_ACCEPTED = 1 + + # HD response to UF change request message field positions + START_POS_UF_CHG_RSP_RESP = DenaliMessage.PAYLOAD_START_INDEX + END_POS_UF_CHG_RSP_RESP = START_POS_UF_CHG_RSP_RESP + 4 + START_POS_UF_CHG_RSP_VOL = END_POS_UF_CHG_RSP_RESP + END_POS_UF_CHG_RSP_VOL = START_POS_UF_CHG_RSP_VOL + 4 + START_POS_UF_CHG_RSP_TIME = END_POS_UF_CHG_RSP_VOL + END_POS_UF_CHG_RSP_TIME = START_POS_UF_CHG_RSP_TIME + 4 + START_POS_UF_CHG_RSP_RATE = END_POS_UF_CHG_RSP_TIME + END_POS_UF_CHG_RSP_RATE = START_POS_UF_CHG_RSP_RATE + 4 + START_POS_UF_CHG_RSP_TIME_DIFF = END_POS_UF_CHG_RSP_RATE + END_POS_UF_CHG_RSP_TIME_DIFF = START_POS_UF_CHG_RSP_TIME_DIFF + 4 + START_POS_UF_CHG_RSP_RATE_DIFF = END_POS_UF_CHG_RSP_TIME_DIFF + END_POS_UF_CHG_RSP_RATE_DIFF = START_POS_UF_CHG_RSP_RATE_DIFF + 4 + + def __init__(self, outer_instance, can_interface=None): self.outer_instance = outer_instance + """ + HD_UI constructor + + \param outer_instance: reference to the HD (outer) class. + \can_interface: interface to can device. + + \returns HD_UI object. + """ - """ - HD_UI constructor + # register function to handle HD response to UF change requests + if can_interface is not None: + channel_id = DenaliChannels.hd_to_ui_ch_id + msg_id = self.MSG_ID_UF_SETTINGS_CHANGE_RESPONSE_FROM_HD + can_interface.registerReceivingPublicationFunction(channel_id, msg_id, + self.handlerUFChangeResponseFunction) + # initialize variables that will be populated by response from HD to UF change request + self.UFChangeResponse = False + self.UFChangeVolumeMl = 0 + self.UFChangeTimeMin = 0 + self.UFChangeRateMlMin = 0.0 + self.UFChangeTimeDiff = 0 + self.UFChangeRateDiff = 0.0 - \param outer_instance: reference to the HD (outer) class. + def handlerUFChangeResponseFunction(self, message): + """ + Handler for response from HD regarding UF change request. - \returns HD_UI object. - """ + \param message: published blood flow data message + \returns none + """ + rsp = struct.unpack('i',bytearray( + message['message'][self.START_POS_UF_CHG_RSP_RESP:self.END_POS_UF_CHG_RSP_RESP])) + vol = struct.unpack('f',bytearray( + message['message'][self.START_POS_UF_CHG_RSP_VOL:self.END_POS_UF_CHG_RSP_VOL])) + tim = struct.unpack('i',bytearray( + message['message'][self.START_POS_UF_CHG_RSP_TIME:self.END_POS_UF_CHG_RSP_TIME])) + rat = struct.unpack('f', bytearray( + message['message'][self.START_POS_UF_CHG_RSP_RATE:self.END_POS_UF_CHG_RSP_RATE])) + tmd = struct.unpack('i',bytearray( + message['message'][self.START_POS_UF_CHG_RSP_TIME_DIFF:self.END_POS_UF_CHG_RSP_TIME_DIFF])) + rtd = struct.unpack('f', bytearray( + message['message'][self.START_POS_UF_CHG_RSP_RATE_DIFF:self.END_POS_UF_CHG_RSP_RATE_DIFF])) + + if rsp[0] == self.RESPONSE_REJECTED: + resp = False + else: + resp = True + self.UFChangeResponse = resp + self.UFChangeVolumeL = vol[0] / self.LITER_TO_ML_CONVERSION_FACTOR + self.UFChangeTimeMin = tim[0] + self.UFChangeRateMlMin = rat[0] + self.UFChangeTimeDiff = tmd[0] + self.UFChangeRateDifff = rtd[0] + def CmdUICheckinWithHD(self): """ - Constructs and sends the UI checkin message + Constructs and sends the UI check-in message \returns none """ @@ -282,6 +354,86 @@ return 0 + def CmdUIUFPauseResume(self, cmd=UF_CMD_PAUSE): + """ + Constructs and sends a UI UF command message + + \param cmd: 0 for pause, 1 for resume + + \returns none + """ + + payload = self.outer_instance.integer2ByteArray(cmd) + message = DenaliMessage.buildMessage(channel_id=DenaliChannels.dialin_to_hd_ch_id, + message_id=self.MSG_ID_HD_UF_PAUSE_RESUME_REQUEST, + payload=payload) + + if cmd == self.UF_CMD_PAUSE: + str_cmd = "pause" + else: + str_cmd = "resume" + print("Sending UF " + str_cmd + " command.") + + # Send message + received_message = self.outer_instance.can_interface.send(message, 0) + + return 0 + + def CmdUIUFSettingsChangeRequest(self, vol=0.0, adj=UF_CMD_CHANGE_TIME_TO_ADJUST): + """ + Constructs and sends a UI UF change settings command message + + \param vol (float): new ultrafiltration volume setting (in L) + \param adj (int): 0 for adjust time, 1 for adjust rate + + \returns none + """ + + # reset response to this command so we can tell when response is received + self.UFChangeResponse = None + # build command message + volume = self.outer_instance.float2ByteArray(vol * self.LITER_TO_ML_CONVERSION_FACTOR) + adjust = self.outer_instance.integer2ByteArray(adj) + payload = volume + adjust + message = DenaliMessage.buildMessage(channel_id=DenaliChannels.dialin_to_hd_ch_id, + message_id=self.MSG_ID_UF_SETTINGS_CHANGE_REQUEST_BY_USER, + payload=payload) + + print("Sending UF settings change request.") + + # Send message + received_message = self.outer_instance.can_interface.send(message, 0) + + return 0 + + def CmdUIUFChangeSettingsConfirmedByUser(self, response=RESPONSE_REJECTED, vol=0.0, tm=0, rate=0.0): + """ + Constructs and sends a UI UF change settings confirmed by user message + + \param response (int): 0 for rejected, 1 for confirmed + \param vol (float): volume (in L) that was confirmed + \param tm (int): treatment time (in min) that was confirmed + \param rate (float): ultrafiltration rate (in mL/min) that was confirmed + + \returns none + """ + + resp = self.outer_instance.integer2ByteArray(response) + volume = self.outer_instance.float2ByteArray(vol * self.LITER_TO_ML_CONVERSION_FACTOR) + min = self.outer_instance.integer2ByteArray(tm) + ufRate = self.outer_instance.float2ByteArray(rate) + payload = resp + volume + min + ufRate + message = DenaliMessage.buildMessage(channel_id=DenaliChannels.dialin_to_hd_ch_id, + message_id=self.MSG_ID_UF_SETTINGS_CHANGE_CONFIRMED_BY_USER, + payload=payload) + + print("Sending UF settings change confirmation.") + + # Send message + received_message = self.outer_instance.can_interface.send(message, 0) + + return 0 + class HD_Watchdog: """ \class HD_Watchdog @@ -565,7 +717,7 @@ payload = rst + pat message = DenaliMessage.buildMessage(channel_id=DenaliChannels.dialin_to_hd_ch_id, - message_id=self.CmdAlarmLampPatternOverride(), + message_id=self.MSG_ID_HD_ALARM_LAMP_OVERRIDE, payload=payload) print("override alarm lamp pattern") @@ -2205,55 +2357,10 @@ \param val: float to convert to byte array \returns byte array """ - #s = hex(struct.unpack('