Index: dialin/protocols/CAN.py =================================================================== diff -u -r91dc90bd009bdbf5621dcaa1bc12ab3d691673f7 -rf3ea3f9a7864df4f448b60a3192ca83c51c4e881 --- dialin/protocols/CAN.py (.../CAN.py) (revision 91dc90bd009bdbf5621dcaa1bc12ab3d691673f7) +++ dialin/protocols/CAN.py (.../CAN.py) (revision f3ea3f9a7864df4f448b60a3192ca83c51c4e881) @@ -516,7 +516,7 @@ msg_sent = False # keep trying to send message until we get a response - while msg_sent is not True: + while not msg_sent: self.last_sent_message = built_message channel_id = DenaliMessage.get_channel_id(built_message) Index: dialin/ui/hd_simulator.py =================================================================== diff -u -r3a4a3ca071c818acd40918e5d7a2400461e7cedb -rf3ea3f9a7864df4f448b60a3192ca83c51c4e881 --- dialin/ui/hd_simulator.py (.../hd_simulator.py) (revision 3a4a3ca071c818acd40918e5d7a2400461e7cedb) +++ dialin/ui/hd_simulator.py (.../hd_simulator.py) (revision f3ea3f9a7864df4f448b60a3192ca83c51c4e881) @@ -27,7 +27,7 @@ DenaliCanMessenger, DenaliChannels) from ..utils.base import _AbstractSubSystem, _LogManager -from ..utils.conversions import integer_to_bytearray +from ..utils.conversions import integer_to_bytearray, float_to_bytearray YES = 1 NO = 0 @@ -74,7 +74,7 @@ self.__dict__[attr] = RequestRejectReasons.REQUEST_REJECT_REASON_NOT_ALLOWED_IN_CURRENT_MODE -class txStates: +class TXStates: # Saline states SALINE_BOLUS_STATE_IDLE = 0 # No saline bolus delivery is in progress SALINE_BOLUS_STATE_WAIT_FOR_PUMPS_STOP = 1 # Wait for pumps to stop before starting bolus @@ -548,309 +548,204 @@ subprocess.call(['cansend', 'can0', '070#{}'.format(frame)]) HDSimulator.waitForMessageToBeSent() - @staticmethod - def buildSetTreatmentParamRanges(vMinTreatmentDuration, vMaxTreatmentDuration, vMinUFVolume, vMaxUFVolume, - vMinDialysateFlowRate, vMaxDialysateFlowRate): + def cmd_set_treatment_parameter_ranges(self, vMinTreatmentDuration, vMaxTreatmentDuration, vMinUFVolume, vMaxUFVolume, + vMinDialysateFlowRate, vMaxDialysateFlowRate): """ - the Treatment adjustment param ranges data message builder method + The Treatment adjustment parameter ranges data message setter/sender method + | MSG | CAN ID | Box | Type | Ack | Src | Dst | Description | #1:(U32) | #2:(U32) | #3:(F32) | #4:(F32) | #5:(U32) | #6:(U32) | |:----:|:------:|:---:|:------:|:---:|:---:|:---:|:-----------: |:--: |:--: |:--: |:--: |:--: |:--: | |0x1A00| 0x020 | 6 | 1/60 Hz| Y | HD | UI | Treatment adjustment param ranges Data | \ref Data::mDuration_Min | \ref Data::mDuration_Max | \ref Data::mUltrafiltration_Volume_Min | \ref Data::mUltrafiltration_Volume_Max | \ref Data::mDialysate_Flow_Min | \ref Data::mDialysate_Flow_Max | - :param vMinTreatmentDuration: (int) Min Treatment Duration - :param vMaxTreatmentDuration: (int) Max Treatment Duration - :param vMinUFVolume: (float) Min UF Volume - :param vMaxUFVolume: (float) Max UF Volume - :param vMinDialysateFlowRate: (int) Min Dialysate Flow Rate - :param vMaxDialysateFlowRate: (int) Max Dialysate Flow Rate - :return: (str) built message frame(s) - """ - msg = messageBuilder.buildMessage(GuiActionType.TreatmentRanges, 4 * 6, True, - utils.toI32(vMinTreatmentDuration), - utils.toI32(vMaxTreatmentDuration), - utils.toF32(vMinUFVolume), - utils.toF32(vMaxUFVolume), - utils.toI32(vMinDialysateFlowRate), - utils.toI32(vMaxDialysateFlowRate) - ) - return messageBuilder.toFrames(msg) - @staticmethod - def setTreatmentParamRanges(vMinTreatmentDuration, vMaxTreatmentDuration, vMinUFVolume, vMaxUFVolume, - vMinDialysateFlowRate, vMaxDialysateFlowRate): - """ - the Treatment adjustment param ranges data message setter/sender method :param vMinTreatmentDuration: (int) Min Treatment Duration :param vMaxTreatmentDuration: (int) Max Treatment Duration :param vMinUFVolume: (float) Min UF Volume :param vMaxUFVolume: (float) Max UF Volume :param vMinDialysateFlowRate: (int) Min Dialysate Flow Rate :param vMaxDialysateFlowRate: (int) Max Dialysate Flow Rate - :return: none + :return: None """ - frames = HDSimulator.buildSetTreatmentParamRanges(vMinTreatmentDuration, vMaxTreatmentDuration, vMinUFVolume, vMaxUFVolume, - vMinDialysateFlowRate, vMaxDialysateFlowRate) - frames = messageBuilder.toCandumpFormat(frames) - for frame in frames: - subprocess.call(['cansend', 'can0', '020#{}'.format(frame)]) - HDSimulator.waitForMessageToBeSent() - @staticmethod - def buildSetTreatmentBloodFlowRate(vFlowSetPt, vMeasFlow, vRotSpd, vMotSpd, vMCSpd, vMCCurr, vPWM): + payload = integer_to_bytearray(vMinTreatmentDuration) + payload += integer_to_bytearray(vMaxTreatmentDuration) + payload += float_to_bytearray(vMinUFVolume) + payload += float_to_bytearray(vMaxUFVolume) + payload += integer_to_bytearray(vMinDialysateFlowRate) + payload += integer_to_bytearray(vMaxDialysateFlowRate) + + message = DenaliMessage.build_message(channel_id=DenaliChannels.hd_to_ui_ch_id, + message_id=MsgIds.MSG_ID_TREATMENT_PARAM_CHANGE_RANGES.value, + payload=payload) + + self.can_interface.send(message, 0) + + def cmd_set_treatment_blood_flow_rate(self, vFlowSetPt, vMeasFlow, vRotSpd, vMotSpd, vMCSpd, vMCCurr, vPWM): """ - the Blood Flow Data message builder method + The Blood Flow Data message setter/sender method + | MSG | CAN ID | Box | Type | Ack | Src | Dst | Description | #1:(S32) | #2:(F32) | #3:(F32) | #4:(F32) | #5:(F32) | #6:(F32) | #7:(F32) | |:----:|:------:|:---:|:------:|:---:|:---:|:---:|:-----------: |:--: |:--: |:--: |:--: |:--: |:--: |:--: | |0x0500| 0x040 | 7 | 1 Hz | N | HD | All | Blood Flow Data | \ref Data::mFlowSetPoint | \ref Data::mMeasuredFlow | \ref Data::mRotorSpeed | \ref Data::mMotorSpeed | \ref Data::mMotorCtlSpeed | \ref Data::mMotorCtlCurrent | \ref Data::mPWMDutyCycle | - :param vFlowSetPt: (signed int) Flow Set Point - :param vMeasFlow: (float) Measured Flow - :param vRotSpd: (float) Rot Speed - :param vMotSpd: (float) Motor Speed - :param vMCSpd: (float) MC Speed - :param vMCCurr: (float) MC Current - :param vPWM: (float) PWM - :return: (str) built message frame(s) - """ - msg = messageBuilder.buildMessage(GuiActionType.BloodFlow, 4 * 7, False, - utils.toI32(vFlowSetPt), - utils.toF32(vMeasFlow), - utils.toF32(vRotSpd), - utils.toF32(vMotSpd), - utils.toF32(vMCSpd), - utils.toF32(vMCCurr), - utils.toF32(vPWM) - ) - return messageBuilder.toFrames(msg) - @staticmethod - def setTreatmentBloodFlowRate(vFlowSetPt, vMeasFlow, vRotSpd, vMotSpd, vMCSpd, vMCCurr, vPWM): - """ - the Blood Flow Data message setter/sender method :param vFlowSetPt: (signed int) Flow Set Point :param vMeasFlow: (float) Measured Flow :param vRotSpd: (float) Rot Speed :param vMotSpd: (float) Motor Speed :param vMCSpd: (float) MC Speed :param vMCCurr: (float) MC Current :param vPWM: (float) PWM - :return: none + :return: None """ - frames = HDSimulator.buildSetTreatmentBloodFlowRate(vFlowSetPt, vMeasFlow, vRotSpd, vMotSpd, vMCSpd, vMCCurr, vPWM) - frames = messageBuilder.toCandumpFormat(frames) - for frame in frames: - subprocess.call(['cansend', 'can0', '040#{}'.format(frame)]) - HDSimulator.waitForMessageToBeSent() - @staticmethod - def buildSetTreatmentDialysateFlowRate(vFlowSetPt, vMeasFlow, vRotSpd, vMotSpd, vMCSpd, vMCCurr, vPWM): + payload = integer_to_bytearray(vFlowSetPt) + payload += float_to_bytearray(vMeasFlow) + payload += float_to_bytearray(vRotSpd) + payload += float_to_bytearray(vMotSpd) + payload += float_to_bytearray(vMCSpd) + payload += float_to_bytearray(vMCCurr) + payload += float_to_bytearray(vPWM) + + message = DenaliMessage.build_message(channel_id=DenaliChannels.hd_sync_broadcast_ch_id, + message_id=MsgIds.MSG_ID_BLOOD_FLOW_DATA.value, + payload=payload) + + self.can_interface.send(message, 0) + + def cmd_set_treatment_dialysate_flow_rate(self, vFlowSetPt, vMeasFlow, vRotSpd, vMotSpd, vMCSpd, vMCCurr, vPWM): """ - the Dialysate Flow Data message builder method + The Dialysate Flow Data message setter/sender method + | MSG | CAN ID | Box | Type | Ack | Src | Dst | Description | #1:(S32) | #2:(F32) | #3:(F32) | #4:(F32) | #5:(F32) | #6:(F32) | #7:(F32) | |:----:|:------:|:---:|:------:|:---:|:---:|:---:|:-----------: |:--: |:--: |:--: |:--: |:--: |:--: |:--: | |0x0800| 0x040 | 7 | 1 Hz | N | HD | All | Dialysate Flow Data | mFlowSetPoint | mMeasuredFlow | mRotorSpeed | mMotorSpeed | mMotorCtlSpeed | mMotorCtlCurrent | mPWMDutyCycle | - :param vFlowSetPt: (signed int) Flow Set Point - :param vMeasFlow: (float) Measured Flow - :param vRotSpd: (float) Rot Speed - :param vMotSpd: (float) Motor Speed - :param vMCSpd: (float) MC Speed - :param vMCCurr: (float) MC Current - :param vPWM: (float) PWM - :return: (str) built message frame(s) - """ - msg = messageBuilder.buildMessage(GuiActionType.DialysateInletFlow, 4 * 7, False, - utils.toI32(vFlowSetPt), - utils.toF32(vMeasFlow), - utils.toF32(vRotSpd), - utils.toF32(vMotSpd), - utils.toF32(vMCSpd), - utils.toF32(vMCCurr), - utils.toF32(vPWM) - ) - return messageBuilder.toFrames(msg) - @staticmethod - def setTreatmentDialysateFlowRate(vFlowSetPt, vMeasFlow, vRotSpd, vMotSpd, vMCSpd, vMCCurr, vPWM): - """ - the Dialysate Flow Data message setter/sender method :param vFlowSetPt: (signed int) Flow Set Point :param vMeasFlow: (float) Measured Flow :param vRotSpd: (float) Rot Speed :param vMotSpd: (float) Motor Speed :param vMCSpd: (float) MC Speed :param vMCCurr: (float) MC Current :param vPWM: (float) PWM - :return: none + :return: None """ - frames = HDSimulator.buildSetTreatmentDialysateFlowRate(vFlowSetPt, vMeasFlow, vRotSpd, vMotSpd, vMCSpd, vMCCurr, vPWM) - frames = messageBuilder.toCandumpFormat(frames) - for frame in frames: - subprocess.call(['cansend', 'can0', '040#{}'.format(frame)]) - HDSimulator.waitForMessageToBeSent() - @staticmethod - def buildTreatmentAdjustBloodDialysateResponse(vAccepted, vReason, vBloodRate, vDialysate): + payload = integer_to_bytearray(vFlowSetPt) + payload += float_to_bytearray(vMeasFlow) + payload += float_to_bytearray(vRotSpd) + payload += float_to_bytearray(vMotSpd) + payload += float_to_bytearray(vMCSpd) + payload += float_to_bytearray(vMCCurr) + payload += float_to_bytearray(vPWM) + + message = DenaliMessage.build_message(channel_id=DenaliChannels.hd_sync_broadcast_ch_id, + message_id=MsgIds.MSG_ID_DIALYSATE_FLOW_DATA.value, + payload=payload) + + self.can_interface.send(message, 0) + + def cmd_send_treatment_adjust_blood_dialysate_response(self, accepted, reason, blood_rate, dialysate_flow_rate): """ - the Blood/dialysate rate change Response message builder method + The Blood/dialysate rate change Response message setter/sender method + | MSG | CAN ID | Box | Type | Ack | Src | Dst | Description | #1:(U32) | #2:(U32) | #3:(U32) | #4:(U32) | |:----:|:------:|:---:|:------:|:---:|:---:|:---:|:-----------: |:--: |:--: |:--: |:--: | |0x1800| 0x020 | 6 | Rsp | Y | HD | UI | Blood/dialysate rate change Response | \ref Data::mAccepted | \ref Data::mReason | \ref Data::mBloodRate | \ref Data::mDialysateRate | - :param vAccepted: (int) boolean accept/reject response - :param vReason: (int) rejection reason - :param vBloodRate: (int) Blood Flow Rate - :param vDialysate: (int) Dialysate Flow Rate - :return: (str) built message frame(s) - """ - msg = messageBuilder.buildMessage(GuiActionType.AdjustBloodDialysateRsp, 4 * 4, True, - utils.toI32(vAccepted), - utils.toI32(vReason), - utils.toI32(vBloodRate), - utils.toI32(vDialysate) - ) - return messageBuilder.toFrames(msg) - @staticmethod - def sendTreatmentAdjustBloodDialysateResponse(vAccepted, vReason, vBloodRate, vDialysate): + :param accepted: (int) boolean accept/reject response + :param reason: (int) rejection reason + :param blood_rate: (int) Blood Flow Rate + :param dialysate_flow_rate: (int) Dialysate Flow Rate + :return: None """ - the Blood/dialysate rate change Response message setter/sender method - :param vAccepted: (int) boolean accept/reject response - :param vReason: (int) rejection reason - :param vBloodRate: (int) Blood Flow Rate - :param vDialysate: (int) Dialysate Flow Rate - :return: none - """ - frames = HDSimulator.buildTreatmentAdjustBloodDialysateResponse(vAccepted, vReason, vBloodRate, vDialysate) - frames = messageBuilder.toCandumpFormat(frames) - for frame in frames: - subprocess.call(['cansend', 'can0', '020#{}'.format(frame)]) - HDSimulator.waitForMessageToBeSent() + + if not isinstance(accepted, int): + accepted = int(accepted) + if not isinstance(reason, int): + reason = int(reason) + if not isinstance(blood_rate, int): + blood_rate = int(blood_rate) + if not isinstance(dialysate_flow_rate, int): + dialysate_flow_rate = int(dialysate_flow_rate) - @staticmethod - def buildTreatmentAdjustDurationResponse(vAccepted, vReason, vDuration, vUltrafiltration): + payload = integer_to_bytearray(accepted) + payload += integer_to_bytearray(reason) + payload += integer_to_bytearray(blood_rate) + payload += integer_to_bytearray(dialysate_flow_rate) + + message = DenaliMessage.build_message(channel_id=DenaliChannels.hd_to_ui_ch_id, + message_id=MsgIds.MSG_ID_USER_BLOOD_DIAL_RATE_CHANGE_RESPONSE.value, + payload=payload) + + self.can_interface.send(message, 0) + + def cmd_send_treatment_adjust_duration_response(self, vAccepted, vReason, vDuration, vUltrafiltration): """ - the Treatment Duration change Response message builder method + The Treatment Duration change Response message setter/sender method + | MSG | CAN ID | Box | Type | Ack | Src | Dst | Description | #1:(U32) | #2:(U32) | #3:(U32) | #5:(F32) | |:----:|:------:|:---:|:------:|:---:|:---:|:---:|:-----------: |:--: |:--: |:--: |:--: | |0x1B00| 0x020 | 6 | Rsp | Y | HD | UI | Treatment Duration change Response | \ref Data::mAccepted | \ref Data::mReason | \ref Data::mDuration | \ref Data::mUFVolume | - :param vAccepted: (int) boolean accept/reject response - :param vReason: (int) rejection reason - :param vDuration: (int) Treatment Duration - :param vUltrafiltration: (float) Ultrafiltration Volume - :return: (str) built message frame(s) - """ - msg = messageBuilder.buildMessage(GuiActionType.AdjustDurationRsp, 4 * 4, True, - utils.toI32(vAccepted), - utils.toI32(vReason), - utils.toI32(vDuration), - utils.toF32(vUltrafiltration) - ) - return messageBuilder.toFrames(msg) - @staticmethod - def sendTreatmentAdjustDurationResponse(vAccepted, vReason, vDuration, vUltrafiltration): - """ - the Treatment Duration change Response message setter/sender method :param vAccepted: (int) boolean accept/reject response :param vReason: (int) rejection reason :param vDuration: (int) Treatment Duration :param vUltrafiltration: (float) Ultrafiltration Volume :return: none """ - frames = HDSimulator.buildTreatmentAdjustDurationResponse(vAccepted, vReason, vDuration, vUltrafiltration) - frames = messageBuilder.toCandumpFormat(frames) - for frame in frames: - subprocess.call(['cansend', 'can0', '020#{}'.format(frame)]) - HDSimulator.waitForMessageToBeSent() - @staticmethod - def buildTreatmentAdjustUltrafiltrationStateResponse(vAccepted, vReason, vState): - """ - the Treatment ultrafiltration adjustment response message builder method - | MSG | CAN ID | M.Box | Type | Ack | Src | Dest | Description | - |:---:|:------:|:-----:|:----:|:---:|:---:|:----:|:------------------------:| - | 65 | 0x020 | 6 | Rsp | Y | HD | UI | UF Pause/Resume Response | + payload = integer_to_bytearray(vAccepted) + payload += integer_to_bytearray(vReason) + payload += integer_to_bytearray(vDuration) + payload += float_to_bytearray(vUltrafiltration) - | Payload || - | || - | #1:(U32) | \ref Data::mAccepted | - | #2:(U32) | \ref Data::mReason | - | #3:(U32) | \ref Data::mState | - :param vAccepted: (int) boolean accept/reject response - :param vReason: (int) rejection reason - :param vState: (int) Ultrafiltration State - :return: (str) built message frame(s) - """ - msg = messageBuilder.buildMessage(GuiActionType.AdjustUltrafiltrationStateRsp, 3 * 4, False, - utils.toI32(vAccepted), - utils.toI32(vReason), - utils.toI32(vState) - ) - return messageBuilder.toFrames(msg) + message = DenaliMessage.build_message(channel_id=DenaliChannels.hd_to_ui_ch_id, + message_id=MsgIds.MSG_ID_USER_TREATMENT_TIME_CHANGE_RESPONSE.value, + payload=payload) - @staticmethod - def setTreatmentAdjustUltrafiltrationStateResponse(vAccepted, vReason, vState): + self.can_interface.send(message, 0) + + def cmd_set_treatment_adjust_ultrafiltration_state_response(self, vAccepted, vReason, vState): """ the Treatment ultrafiltration adjustment response message setter/sender method :param vAccepted: (int) boolean accept/reject response :param vReason: (int) rejection reason :param vState: (int) Ultrafiltration State :return: none """ - frames = HDSimulator.buildTreatmentAdjustUltrafiltrationStateResponse(vAccepted, vReason, vState) - frames = messageBuilder.toCandumpFormat(frames) - for frame in frames: - subprocess.call(['cansend', 'can0', '020#{}'.format(frame)]) - HDSimulator.waitForMessageToBeSent() - @staticmethod - def setTreatmentAdjustUltrafiltrationAccepted(vState): + payload = integer_to_bytearray(vAccepted) + payload += integer_to_bytearray(vReason) + payload += integer_to_bytearray(vState) + + message = DenaliMessage.build_message(channel_id=DenaliChannels.hd_to_ui_ch_id, + message_id=MsgIds.MSG_ID_USER_UF_PAUSE_RESUME_RESPONSE.value, + payload=payload) + + self.can_interface.send(message, 0) + + def cmd_set_treatment_adjust_ultrafiltration_accepted(self, vState): """ - a convenient method for setTreatmentAdjustUltrafiltrationStateResponse which sends accept true + a convenient method for cmd_set_treatment_adjust_ultrafiltration_state_response which sends accept true :return: none """ - HDSimulator.setTreatmentAdjustUltrafiltrationStateResponse(EResponse.Accepted, 0, vState) + self.cmd_set_treatment_adjust_ultrafiltration_state_response(EResponse.Accepted, 0, vState) - @staticmethod - def setTreatmentAdjustUltrafiltrationRejected(vReason, vState): + def cmd_set_treatment_adjust_ultrafiltration_rejected(self, vReason, vState): """ - a convenient method for setTreatmentAdjustUltrafiltrationStateResponse which sends accept false + a convenient method for cmd_set_treatment_adjust_ultrafiltration_state_response which sends accept false :return: none """ - HDSimulator.setTreatmentAdjustUltrafiltrationStateResponse(EResponse.Rejected, vReason, vState) + self.cmd_set_treatment_adjust_ultrafiltration_state_response(EResponse.Rejected, vReason, vState) - @staticmethod - def buildTreatmentAdjustUltrafiltrationEditResponse(vAccepted, vReason, vVolume, vDuration, vDurationDiff, vRate, - vRateDiff, vRateOld): + def cmd_set_treatment_adjust_ultrafiltration_edit_response(self, vAccepted, vReason, vVolume, vDuration, vDurationDiff, + vRate, vRateDiff, vRateOld): """ - the ultrafiltration volume change response message builder method + the ultrafiltration volume change response message setter/sender method + | MSG | CAN ID | Box | Type | Ack | Src | Dst | Description | #1:(U32) | #2:(U32) | #1:(U32) | #2:(U32) | #3:(F32) | #4:(U32) | #5:(F32) | #6:(U32) | #7:(U32) | #8:(F32) | |:----:|:------:|:---:|:------:|:---:|:---:|:---:|:-----------: |:--: |:--: |:--: |:--: |:--: |:--: |:--: |:--: |:--: |:--: | |0x1300| 0x020 | 6 | Rsp | Y | HD | UI | UF Vol. Change Response | \ref Data::mAccepted | \ref Data::mReason | \ref Data::mAccepted | \ref Data::mReason | \ref Data::mVolume | \ref Data::mDuration | \ref Data::mRate | \ref Data::mDurationDiff | \ref Data::mRateDiff | \ref Data::mRateOld | - :param vAccepted: (int) boolean accept/reject response - :param vReason: (int) rejection reason - :param vVolume: (float) Ultrafiltration Volume - :param vDuration: (int) Treatment Duration - :param vDurationDiff: (int) Duration Difference - :param vRate: (float) Ultrafiltration Rate - :param vRateDiff: (float) Ultrafiltration Rate Difference - :param vRateOld: (float) Ultrafiltration Rate Old - :return: (str) built message frame(s) - """ - msg = messageBuilder.buildMessage(GuiActionType.AdjustUltrafiltrationEditRsp, 8 * 4, True, - utils.toI32(vAccepted), - utils.toI32(vReason), - utils.toF32(vVolume), - utils.toI32(vDuration), - utils.toI32(vDurationDiff), - utils.toF32(vRate), - utils.toF32(vRateDiff), - utils.toF32(vRateOld) - ) - return messageBuilder.toFrames(msg) - @staticmethod - def setTreatmentAdjustUltrafiltrationEditResponse(vAccepted, vReason, vVolume, vDuration, vDurationDiff, vRate, - vRateDiff, vRateOld): - """ - the ultrafiltration volume change response message setter/sender method :param vAccepted: (int) boolean accept/reject response :param vReason: (int) rejection reason :param vVolume: (float) Ultrafiltration Volume @@ -861,148 +756,103 @@ :param vRateOld: (float) Ultrafiltration Rate Old :return: none """ - frames = HDSimulator.buildTreatmentAdjustUltrafiltrationEditResponse(vAccepted, vReason, vVolume, vDuration, vDurationDiff, - vRate, vRateDiff, vRateOld) - frames = messageBuilder.toCandumpFormat(frames) - for frame in frames: - subprocess.call(['cansend', 'can0', '020#{}'.format(frame)]) - HDSimulator.waitForMessageToBeSent() - @staticmethod - def setTreatmentAdjustUltrafiltrationEditRejected(vReason): + payload = integer_to_bytearray(vAccepted) + payload += integer_to_bytearray(vReason) + payload += float_to_bytearray(vVolume) + payload += integer_to_bytearray(vDuration) + payload += integer_to_bytearray(vDurationDiff) + payload += float_to_bytearray(vRate) + payload += float_to_bytearray(vRateDiff) + payload += float_to_bytearray(vRateOld) + + message = DenaliMessage.build_message(channel_id=DenaliChannels.hd_to_ui_ch_id, + message_id=MsgIds.MSG_ID_USER_UF_SETTINGS_CHANGE_RESPONSE.value, + payload=payload) + + self.can_interface.send(message, 0) + + def cmd_set_treatment_adjust_ultrafiltration_edit_rejected(self, vReason): """ - a convenient method for setTreatmentAdjustUltrafiltrationEditResponse which only sends a rejection reason + a convenient method for cmd_set_treatment_adjust_ultrafiltration_edit_response which only sends a rejection reason and sends other values all as zero :param vReason: (int) rejection reason :return: none """ - frames = HDSimulator.buildTreatmentAdjustUltrafiltrationEditResponse(0, vReason, 0, 0, 0, 0, 0, 0) - frames = messageBuilder.toCandumpFormat(frames) - for frame in frames: - subprocess.call(['cansend', 'can0', '020#{}'.format(frame)]) - HDSimulator.waitForMessageToBeSent() + self.cmd_set_treatment_adjust_ultrafiltration_edit_response(0, vReason, 0, 0, 0, 0, 0, 0) - @staticmethod - def buildTreatmentAdjustUltrafiltrationConfirmResponse(vAccepted, vReason, vVolume, vDuration, vRate): + def cmd_set_treatment_adjust_ultrafiltration_confirm_response(self, vAccepted, vReason, vVolume, vDuration, vRate): """ - the ultrafiltratin volume Change Confirmation Response message builder method + the ultrafiltration volume Change Confirmation Response message setter/sender method + | MSG | CAN ID | Box | Type | Ack | Src | Dst | Description | #1:(U32) | #2:(U32) | #3:(F32) | #4:(U32) | #5:(F32) | |:----:|:------:|:---:|:------:|:---:|:---:|:---:|:-----------: |:--: |:--: |:--: |:--: |:--: | |0x2E00| 0x020 | 6 | Rsp | Y | HD | UI | UF Vol. Change Confirmation Response | \ref Data::mAccepted | \ref Data::mReason | \ref Data::mVolume | \ref Data::mDuration | \ref Data::mRate | - :param vAccepted: (int) boolean accept/reject response - :param vReason: (int) rejection reason - :param vVolume: (float) Ultrafiltration Volume - :param vDuration: (int) Treatment Duration - :param vRate: (float) Ultrafiltration Rate - :return: built message frame(s) - """ - msg = messageBuilder.buildMessage(GuiActionType.AdjustUltrafiltrationConfirmRsp, 5 * 4, True, - utils.toI32(vAccepted), - utils.toI32(vReason), - utils.toF32(vVolume), - utils.toI32(vDuration), - utils.toF32(vRate) - ) - return messageBuilder.toFrames(msg) - @staticmethod - def setTreatmentAdjustUltrafiltrationConfirmResponse(vAccepted, vReason, vVolume, vDuration, vRate): - """ - the ultrafiltration volume Change Confirmation Response message setter/sender method :param vAccepted: (int) boolean accept/reject response :param vReason: (int) rejection reason :param vVolume: (float) Ultrafiltration Volume :param vDuration: (int) Treatment Duration :param vRate: (float) Ultrafiltration Rate :return: none """ - frames = HDSimulator.buildTreatmentAdjustUltrafiltrationConfirmResponse(vAccepted, vReason, vVolume, vDuration, vRate) - frames = messageBuilder.toCandumpFormat(frames) - for frame in frames: - subprocess.call(['cansend', 'can0', '020#{}'.format(frame)]) - HDSimulator.waitForMessageToBeSent() - @staticmethod - def setTreatmentAdjustUltrafiltrationConfirmRejected(vReason): + payload = integer_to_bytearray(vAccepted) + payload += integer_to_bytearray(vReason) + payload += float_to_bytearray(vVolume) + payload += integer_to_bytearray(vDuration) + payload += float_to_bytearray(vRate) + + message = DenaliMessage.build_message(channel_id=DenaliChannels.hd_to_ui_ch_id, + message_id=MsgIds.MSG_ID_USER_UF_SETTINGS_CHANGE_CONFIRMATION_RESPONSE.value, + payload=payload) + + self.can_interface.send(message, 0) + + def cmd_set_treatment_adjust_ultrafiltration_confirm_rejected(self, vReason): """ - a convenient method for setTreatmentAdjustUltrafiltrationConfirmResponse which only sends a rejection reason + a convenient method for cmd_set_treatment_adjust_ultrafiltration_confirm_response which only sends a rejection reason and sends other values all as zero + :param vReason: (int) rejection reason :return: none """ - frames = HDSimulator.buildTreatmentAdjustUltrafiltrationConfirmResponse(0, vReason, 0, 0, 0) - frames = messageBuilder.toCandumpFormat(frames) - for frame in frames: - subprocess.call(['cansend', 'can0', '020#{}'.format(frame)]) - HDSimulator.waitForMessageToBeSent() + self.cmd_set_treatment_adjust_ultrafiltration_confirm_response(0, vReason, 0, 0, 0) - @staticmethod - def buildTreatmentTime(vSecsTotal, vSecsElap, vSecsRem): + def cmd_set_treatment_time(self, vSecsTotal, vSecsElap, vSecsRem=None): """ - the Treatment Time Data message builder method + the Treatment Time Data message setter/sender method + | MSG | CAN ID | Box | Type | Ack | Src | Dst | Description | #1:(U32) | #2:(U32) | #3:(U32) | |:----:|:------:|:---:|:------:|:---:|:---:|:---:|:-----------: |:--: |:--: |:--: | |0x0D00| 0x040 | 7 | 1 Hz | N | HD | All | Treatment Time Data | \ref Data::mTotal | \ref Data::mElapsed | \ref Data::mRemaining | - :param vSecsTotal: (int) Treatment Total Duration in Seconds - :param vSecsElap: (int) Treatment Total Elapsed Time in Seconds - :param vSecsRem: (int) Treatment Remaining Time in Seconds - :return: (str) built message frame(s) - """ - msg = messageBuilder.buildMessage(GuiActionType.TreatmentTime, 3 * 4, False, - utils.toI32(vSecsTotal), - utils.toI32(vSecsElap), - utils.toI32(vSecsRem) - ) - return messageBuilder.toFrames(msg) - @staticmethod - def setTreatmentTime(vSecsTotal, vSecsElap, vSecsRem=None): - """ - the Treatment Time Data message setter/sender method :param vSecsTotal: (int) Treatment Total Duration in Seconds :param vSecsElap: (int) Treatment Total Elapsed Time in Seconds :param vSecsRem: (int) Treatment Remaining Time in Seconds :return: none """ if vSecsRem is None: vSecsRem = vSecsTotal - vSecsElap - frames = HDSimulator.buildTreatmentTime(vSecsTotal, vSecsElap, vSecsRem) - frames = messageBuilder.toCandumpFormat(frames) - for frame in frames: - subprocess.call(['cansend', 'can0', '040#{}'.format(frame)]) - HDSimulator.waitForMessageToBeSent() - @staticmethod - def buildSetTreatmentUltrafiltration(vRefUFVol, vMeasUFVol, vRotSpd, vMotSpd, vMCSpd, vMCCurr, vPWM): + payload = integer_to_bytearray(vSecsTotal) + payload += integer_to_bytearray(vSecsElap) + payload += integer_to_bytearray(vSecsRem) + + message = DenaliMessage.build_message(channel_id=DenaliChannels.hd_sync_broadcast_ch_id, + message_id=MsgIds.MSG_ID_TREATMENT_TIME.value, + payload=payload) + + self.can_interface.send(message, 0) + + def cmd_set_treatment_ultrafiltration_outlet_flow_data(self, vRefUFVol, vMeasUFVol, vRotSpd, vMotSpd, vMCSpd, vMCCurr, vPWM): """ - the Outlet Flow Data message builder method + the Outlet Flow Data message setter/sender method + | MSG | CAN ID | Box | Type | Ack | Src | Dst | Description | #1:(F32) | #2:(F32) | #3:(F32) | #4:(F32) | #5:(F32) | #6:(F32) | #7:(F32) | |:----:|:------:|:---:|:------:|:---:|:---:|:---:|:-----------: |:--: |:--: |:--: |:--: |:--: |:--: |:--: | |0x0B00| 0x040 | 7 | 1 Hz | N | HD | All | Outlet Flow Data | \ref Data::mRefUFVol | \ref Data::mMeasUFVol | \ref Data::mRotorSpeed | \ref Data::mMotorSpeed | \ref Data::mMotorCtlSpeed | \ref Data::mMotorCtlCurrent | \ref Data::mPWMDtCycle | - :param vRefUFVol: (float) Ref UF Volume - :param vMeasUFVol: (float) Measured UF Volume - :param vRotSpd: (float) Rot Speed - :param vMotSpd: (float) Motor Speed - :param vMCSpd: (float) MC Speed - :param vMCCurr: (float) MC Current - :param vPWM: (float) PWM - :return: (str) built message frame(s) - """ - msg = messageBuilder.buildMessage(GuiActionType.DialysateOutletFlow, 4 * 7, False, - utils.toF32(vRefUFVol), - utils.toF32(vMeasUFVol), - utils.toF32(vRotSpd), - utils.toF32(vMotSpd), - utils.toF32(vMCSpd), - utils.toF32(vMCCurr), - utils.toF32(vPWM) - ) - return messageBuilder.toFrames(msg) - @staticmethod - def setTreatmentUltrafiltration(vRefUFVol, vMeasUFVol, vRotSpd, vMotSpd, vMCSpd, vMCCurr, vPWM): - """ - the Outlet Flow Data message setter/sender method :param vRefUFVol: (float) Ref UF Volume :param vMeasUFVol: (float) Measured UF Volume :param vRotSpd: (float) Rot Speed @@ -1012,316 +862,241 @@ :param vPWM: (float) PWM :return: none """ - frames = HDSimulator.buildSetTreatmentUltrafiltration(vRefUFVol, vMeasUFVol, vRotSpd, vMotSpd, vMCSpd, vMCCurr, vPWM) - frames = messageBuilder.toCandumpFormat(frames) - for frame in frames: - subprocess.call(['cansend', 'can0', '040#{}'.format(frame)]) - HDSimulator.waitForMessageToBeSent() - @staticmethod - def buildPressureOcclusionData(vArterialPressure, vVenousPressure, vBloodPumpOcclusion, vDialysateInletPumpOcclusion, - vDialysateOutletPumpOcclusion): + payload = float_to_bytearray(vRefUFVol) + payload += float_to_bytearray(vMeasUFVol) + payload += float_to_bytearray(vRotSpd) + payload += float_to_bytearray(vMotSpd) + payload += float_to_bytearray(vMCSpd) + payload += float_to_bytearray(vMCCurr) + payload += float_to_bytearray(vPWM) + + message = DenaliMessage.build_message(channel_id=DenaliChannels.hd_sync_broadcast_ch_id, + message_id=MsgIds.MSG_ID_DIALYSATE_OUT_FLOW_DATA.value, + payload=payload) + + self.can_interface.send(message, 0) + + + def cmd_set_pressure_occlusion_data(self, vArterialPressure, vVenousPressure, vBloodPumpOcclusion, vDialysateInletPumpOcclusion, + vDialysateOutletPumpOcclusion): """ - the Pressure/Occlusion Data messages builder mehtod + the Pressure/Occlusion Data messages setter/sender method + | MSG | CAN ID | Box | Type | Ack | Src | Dst | Description | #1:(F32) | #2:(F32) | #3:(U32) | #4:(U32) | #5:(U32) | |:----:|:------:|:---:|:------:|:---:|:---:|:---:|:-----------: |:--: |:--: |:--: |:--: |:--: | |0x0900| 0x040 | 7 | 1 Hz | N | HD | All | PressureOcclusion Data | \ref Data::mArterialPressure | \ref Data::mVenousPressure | \ref Data::mBloodPumpOcclusion | \ref Data::mDialysateInletPumpOcclusion | \ref Data::mDialysateOutletPumpOcclusion | - :param vArterialPressure: (float) Arterial Pressure - :param vVenousPressure: (float) Venous Pressure - :param vBloodPumpOcclusion: (uint) Blood Pump Occlusion - :param vDialysateInletPumpOcclusion: (uint) Dialysate Inlet Pump Occlusion - :param vDialysateOutletPumpOcclusion: (uint) Dialysate Outlet Pump Occlusion - :return: (str) built message frame(s) - """ - msg = messageBuilder.buildMessage(0x0009, 4 + 4 + 4 + 4 + 4, False, - utils.toF32(vArterialPressure), - utils.toF32(vVenousPressure), - utils.toI32(vBloodPumpOcclusion), - utils.toI32(vDialysateInletPumpOcclusion), - utils.toI32(vDialysateOutletPumpOcclusion)) - return messageBuilder.toFrames(msg) - @staticmethod - def setPressureOcclusionData(vArterialPressure, vVenousPressure, vBloodPumpOcclusion, vDialysateInletPumpOcclusion, - vDialysateOutletPumpOcclusion): - """ - the Pressure/Occlusion Data messages setter/sender mehtod :param vArterialPressure: (float) Arterial Pressure :param vVenousPressure: (float) Venous Pressure :param vBloodPumpOcclusion: (uint) Blood Pump Occlusion :param vDialysateInletPumpOcclusion: (uint) Dialysate Inlet Pump Occlusion :param vDialysateOutletPumpOcclusion: (uint) Dialysate Outlet Pump Occlusion :return: none """ - frames = HDSimulator.buildPressureOcclusionData(vArterialPressure, vVenousPressure, vBloodPumpOcclusion, - vDialysateInletPumpOcclusion, vDialysateOutletPumpOcclusion) - frames = messageBuilder.toCandumpFormat(frames) - for frame in frames: - subprocess.call(['cansend', 'can0', '040#{}'.format(frame)]) - HDSimulator.waitForMessageToBeSent() - @staticmethod - def buildDGROPumpData(vSetPtPressure, vFlowRate, vPWM): + payload = float_to_bytearray(vArterialPressure) + payload += float_to_bytearray(vVenousPressure) + payload += integer_to_bytearray(vBloodPumpOcclusion) + payload += integer_to_bytearray(vDialysateInletPumpOcclusion) + payload += integer_to_bytearray(vDialysateOutletPumpOcclusion) + + message = DenaliMessage.build_message(channel_id=DenaliChannels.hd_sync_broadcast_ch_id, + message_id=MsgIds.MSG_ID_PRESSURE_OCCLUSION_DATA.value, + payload=payload) + + self.can_interface.send(message, 0) + + def cmd_set_dg_ro_pump_data(self, vSetPtPressure, vFlowRate, vPWM): """ - the DG RO Pump Data message builder method + the DG RO Pump Data message setter/sender method + | MSG | CAN ID | Box | Type | Ack | Src | Dst | Description | #1:(U32) | #2:(F32) | #3:(F32) | |:----:|:------:|:---:|:------:|:---:|:---:|:---:|:-----------: |:--: |:--: |:--: | |0x1F00| 0x080 | 8 | 1 Hz | N | DG | All | DG RO Pump Data | \ref Data::mPressure | \ref Data::mFlowRate | \ref Data::mPWM | :param vSetPtPressure: - :param vSetPtPressure: (int) set Point Pressure - :param vFlowRate: (float) Flow Rate - :param vPWM: (float) PWM - :return: (str) built message frame(s) - """ - msg = messageBuilder.buildMessage(0x001F, 4 + 4 + 4, False, - utils.toI32(vSetPtPressure), - utils.toF32(vFlowRate), - utils.toF32(vPWM)) - return messageBuilder.toFrames(msg) - @staticmethod - def setDGROPumpData(vSetPtPressure, vFlowRate, vPWM): - """ - the DG RO Pump Data message setter/sender method :param vSetPtPressure: (int) set Point Pressure :param vFlowRate: (float) Flow Rate :param vPWM: (float) PWM :return: none """ - frames = HDSimulator.buildDGROPumpData(vSetPtPressure, vFlowRate, vPWM) - frames = messageBuilder.toCandumpFormat(frames) - for frame in frames: - subprocess.call(['cansend', 'can0', '080#{}'.format(frame)]) - HDSimulator.waitForMessageToBeSent() - @staticmethod - def buildDGPressuresData(vROInletPSI, vROOutletPSI, vDrainInletPSI, vDrainOutletPSI): + payload = integer_to_bytearray(vSetPtPressure) + payload += float_to_bytearray(vFlowRate) + payload += float_to_bytearray(vPWM) + + message = DenaliMessage.build_message(channel_id=DenaliChannels.dg_sync_broadcast_ch_id, + message_id=MsgIds.MSG_ID_RO_PUMP_DATA.value, + payload=payload) + + self.can_interface.send(message, 0) + + def cmd_set_dg_pressures_data(self, vROInletPSI, vROOutletPSI, vDrainInletPSI, vDrainOutletPSI): """ - the DG Pressures Data message builder method + the DG Pressures Data message setter/sender method + | MSG | CAN ID | Box | Type | Ack | Src | Dst | Description | #1:(F32) | #2:(F32) | #3:(F32) | #4:(F32) | |:----:|:------:|:---:|:------:|:---:|:---:|:---:|:-----------: |:--: |:--: |:--: |:--: | |0x2000| 0x080 | 8 | 1 Hz | N | DG | All | DG Pressures Data | \ref Data::mROInletPSI | \ref Data::mROOutletPSI | \ref Data::mDrainInletPSI | \ref Data::mDrainOutletPSI | - :param vROInletPSI: (float) RO Inlet PSI - :param vROOutletPSI: (float) RO Outlet PSI - :param vDrainInletPSI: (float) Drain Inlet PSI - :param vDrainOutletPSI: (float) Drain Outlet PSI - :return: (str) built message frame(s) - """ - msg = messageBuilder.buildMessage(0x0020, 4 + 4 + 4 + 4, False, - utils.toF32(vROInletPSI), - utils.toF32(vROOutletPSI), - utils.toF32(vDrainInletPSI), - utils.toF32(vDrainOutletPSI)) - return messageBuilder.toFrames(msg) - @staticmethod - def setDGPressuresData(vROInletPSI, vROOutletPSI, vDrainInletPSI, vDrainOutletPSI): - """ - the DG Pressures Data message setter/sender method :param vROInletPSI: (float) RO Inlet PSI :param vROOutletPSI: (float) RO Outlet PSI :param vDrainInletPSI: (float) Drain Inlet PSI :param vDrainOutletPSI: (float) Drain Outlet PSI :return: none """ - frames = HDSimulator.buildDGPressuresData(vROInletPSI, vROOutletPSI, vDrainInletPSI, vDrainOutletPSI) - frames = messageBuilder.toCandumpFormat(frames) - for frame in frames: - subprocess.call(['cansend', 'can0', '080#{}'.format(frame)]) - HDSimulator.waitForMessageToBeSent() - @staticmethod - def buildDGDrainPumpData(vSetPtRPM, vDACValue): + payload = float_to_bytearray(vROInletPSI) + payload += float_to_bytearray(vROOutletPSI) + payload += float_to_bytearray(vDrainInletPSI) + payload += float_to_bytearray(vDrainOutletPSI) + + message = DenaliMessage.build_message(channel_id=DenaliChannels.dg_sync_broadcast_ch_id, + message_id=MsgIds.MSG_ID_DG_PRESSURES_DATA.value, + payload=payload) + + self.can_interface.send(message, 0) + + def cmd_set_dg_drain_pump_data(self, vSetPtRPM, vDACValue): """ - the DG Drain Pump Data message builder method + the DG Drain Pump Data message setter/sender method + | MSG | CAN ID | Box | Type | Ack | Src | Dst | Description | #1:(U32) | #2:(U32) | |:----:|:------:|:---:|:------:|:---:|:---:|:---:|:-----------: |:--: |:--: | |0x2400| 0x080 | 8 | 1 Hz | N | DG | All | DG Drain Pump Data | \ref Data::mRPM | \ref Data::mDAC | - :param vSetPtRPM: (int) Set Point RPM - :param vDACValue: (int) DAC Value - :return: (str) built message frame(s) - """ - msg = messageBuilder.buildMessage(0x0024, 4 + 4, False, - utils.toI32(vSetPtRPM), - utils.toI32(vDACValue)) - return messageBuilder.toFrames(msg) - @staticmethod - def setDGDrainPumpData(vSetPtRPM, vDACValue): - """ - the DG Drain Pump Data message setter/sender method :param vSetPtRPM: (int) Set Point RPM :param vDACValue: (int) DAC Value :return: none """ - frames = HDSimulator.buildDGDrainPumpData(vSetPtRPM, vDACValue) - frames = messageBuilder.toCandumpFormat(frames) - for frame in frames: - subprocess.call(['cansend', 'can0', '080#{}'.format(frame)]) - HDSimulator.waitForMessageToBeSent() - @staticmethod - def buildDGOperationMode(vDGOpMode): + payload = integer_to_bytearray(vSetPtRPM) + payload += integer_to_bytearray(vDACValue) + + message = DenaliMessage.build_message(channel_id=DenaliChannels.dg_sync_broadcast_ch_id, + message_id=MsgIds.MSG_ID_DRAIN_PUMP_DATA.value, + payload=payload) + + self.can_interface.send(message, 0) + + def cmd_set_dg_operation_mode(self, vDGOpMode): """ - the DG Operation Mode Data message builder method + the DG Operation Mode Data message setter/sender method + | MSG | CAN ID | Box | Type | Ack | Src | Dst | Description | #1:(U32) | |:----:|:------:|:---:|:------:|:---:|:---:|:---:|:-----------: |:--: | |0x2700| 0x080 | 8 | 1 Hz | N | DG | All | DG Operation Mode Data | \ref Data::mOpMode | - :param vDGOpMode: (int) DG Operation Mode - :return: (str) built message frame(s) - """ - msg = messageBuilder.buildMessage(0x0027, 4, False, - utils.toI32(vDGOpMode)) - return messageBuilder.toFrames(msg) - @staticmethod - def setDGOperationMode(vDGOpMode): - """ - the DG Operation Mode Data message setter/sender method :param vDGOpMode: (int) DG Operation Mode :return: none """ - frames = HDSimulator.buildDGOperationMode(vDGOpMode) - frames = messageBuilder.toCandumpFormat(frames) - for frame in frames: - subprocess.call(['cansend', 'can0', '080#{}'.format(frame)]) - HDSimulator.waitForMessageToBeSent() - @staticmethod - def buildDGReservoirData(vActiveReservoir, vFillToVolML, vDrainToVolML): + payload = integer_to_bytearray(vDGOpMode) + + message = DenaliMessage.build_message(channel_id=DenaliChannels.dg_sync_broadcast_ch_id, + message_id=MsgIds.MSG_ID_DG_OP_MODE.value, + payload=payload) + + self.can_interface.send(message, 0) + + def cmd_set_dg_reservoir_data(self, vActiveReservoir, vFillToVolML, vDrainToVolML): """ - the DG Reservoir Data message builder method + the DG Reservoir Data message setter/sender method + | MSG | CAN ID | Box | Type | Ack | Src | Dst | Description | #1:(U32) | #2:(U32) | #3:(U32) | |:----:|:------:|:---:|:------:|:---:|:---:|:---:|:-----------: |:--: |:--: |:--: | |0x2800| 0x080 | 8 | 1 Hz | N | DG | All | DG Reservoir Data | \ref Data::mActiveReservoir | \ref Data::mFillToVol | \ref Data::mDrainToVol | - :param vActiveReservoir: (int) Active Reservoir - :param vFillToVolML: (int) Fill To Volume ML - :param vDrainToVolML: (int) Drain To Vol ML - :return: (str) built message frame(s) - """ - msg = messageBuilder.buildMessage(0x0028, 4 + 4 + 4, False, - utils.toI32(vActiveReservoir), - utils.toI32(vFillToVolML), - utils.toI32(vDrainToVolML)) - return messageBuilder.toFrames(msg) - @staticmethod - def setDGReservoirData(vActiveReservoir, vFillToVolML, vDrainToVolML): - """ - the DG Reservoir Data message setter/sender method :param vActiveReservoir: (int) Active Reservoir :param vFillToVolML: (int) Fill To Volume ML :param vDrainToVolML: (int) Drain To Vol ML :return: none """ - frames = HDSimulator.buildDGReservoirData(vActiveReservoir, vFillToVolML, vDrainToVolML) - frames = messageBuilder.toCandumpFormat(frames) - for frame in frames: - subprocess.call(['cansend', 'can0', '080#{}'.format(frame)]) - HDSimulator.waitForMessageToBeSent() - @staticmethod - def buildDGValvesStates(vValvesStates): + payload = integer_to_bytearray(vActiveReservoir) + payload += integer_to_bytearray(vFillToVolML) + payload += integer_to_bytearray(vDrainToVolML) + + message = DenaliMessage.build_message(channel_id=DenaliChannels.dg_sync_broadcast_ch_id, + message_id=MsgIds.MSG_ID_DG_RESERVOIR_DATA.value, + payload=payload) + + self.can_interface.send(message, 0) + + def cmd_set_dg_valves_states(self, vValvesStates): """ - the DG Valves States Data message builder method + the DG Valves States Data message setter/sender method + | MSG | CAN ID | Box | Type | Ack | Src | Dst | Description | #1:(U16) | |:----:|:------:|:---:|:------:|:---:|:---:|:---:|:-----------: |:--: | |0x2A00| 0x080 | 8 | 2 Hz | N | DG | All | DG Valves States Data | \ref Data::mStates | - :param vValvesStates: (int)Valves states - :return: (str) built message frame(s) - """ - msg = messageBuilder.buildMessage(0x002A, 2, False, - utils.toI16(vValvesStates)) - return messageBuilder.toFrames(msg) - @staticmethod - def setDGValvesStates(vValvesStates): - """ - the DG Valves States Data message setter/sender method :param vValvesStates: (int)Valves states :return: none """ - frames = HDSimulator.buildDGValvesStates(vValvesStates) - frames = messageBuilder.toCandumpFormat(frames) - for frame in frames: - subprocess.call(['cansend', 'can0', '080#{}'.format(frame)]) - HDSimulator.waitForMessageToBeSent() - @staticmethod - def buildDGHeatersData(vMainPriMaryDC, vSmallPrimaryDC, vTrimmerDC): + payload = integer_to_bytearray(vValvesStates) + + message = DenaliMessage.build_message(channel_id=DenaliChannels.dg_sync_broadcast_ch_id, + message_id=MsgIds.MSG_ID_DG_VALVES_STATES.value, + payload=payload) + + self.can_interface.send(message, 0) + + def cmd_set_dg_heaters_data(self, vMainPriMaryDC, vSmallPrimaryDC, vTrimmerDC): """ - the DG Heaters Data message builder method + the DG Heaters Data message setter/sender method | MSG | CAN ID | Box | Type | Ack | Src | Dst | Description | #1:(U32) | #2:(U32) | #3:(U32) | |:----:|:------:|:---:|:------:|:---:|:---:|:---:|:-----------: |:--: |:--: |:--: | |0x2C00| 0x080 | 8 | 2 Hz | N | DG | All | DG Heaters Data | \ref Data::mMainPrimaryDC | \ref Data::mSmallPrimaryDC | \ref Data::mTrimmerDC | - :param vMainPriMaryDC: (int) Main PriMary DC - :param vSmallPrimaryDC: (int) Small Primary DC - :param vTrimmerDC: (int) Trimmer DC - :return: (str) built message frame(s) - """ - msg = messageBuilder.buildMessage(0x002C, 4 + 4 + 4, False, - utils.toI32(vMainPriMaryDC), - utils.toI32(vSmallPrimaryDC), - utils.toI32(vTrimmerDC)) - return messageBuilder.toFrames(msg) - @staticmethod - def setDGHeatersData(vMainPriMaryDC, vSmallPrimaryDC, vTrimmerDC): - """ - the DG Heaters Data message setter/sender method :param vMainPriMaryDC: (int) Main PriMary DC :param vSmallPrimaryDC: (int) Small Primary DC :param vTrimmerDC: (int) Trimmer DC :return: none """ - frames = HDSimulator.buildDGHeatersData(vMainPriMaryDC, vSmallPrimaryDC, vTrimmerDC) - frames = messageBuilder.toCandumpFormat(frames) - for frame in frames: - subprocess.call(['cansend', 'can0', '080#{}'.format(frame)]) - HDSimulator.waitForMessageToBeSent() - @staticmethod - def buildDGLoadCellReadingsData(vRs1Prim, vRs1Bkup, vRs2Prim, vRs2Bkup): + payload = integer_to_bytearray(vMainPriMaryDC) + payload += integer_to_bytearray(vSmallPrimaryDC) + payload += integer_to_bytearray(vTrimmerDC) + + message = DenaliMessage.build_message(channel_id=DenaliChannels.dg_sync_broadcast_ch_id, + message_id=MsgIds.MSG_ID_DG_HEATERS_DATA.value, + payload=payload) + + self.can_interface.send(message, 0) + + + def cmd_set_dg_load_cell_readings_data(self, vRs1Prim, vRs1Bkup, vRs2Prim, vRs2Bkup): """ - the DG Load Cell Readings Data message builder method + The DG Load Cell Readings Data message setter/sender method | MSG | CAN ID | Box | Type | Ack | Src | Dst | Description | #1:(F32) | #2:(F32) | #3:(F32) | #4:(F32) | |:----:|:------:|:---:|:------:|:---:|:---:|:---:|:-----------: |:--: |:--: |:--: |:--: | |0x0C00| 0x080 | 8 | 10 Hz | N | DG | All | DG Load Cell Readings Data | \ref Data::mReservoir1Prim | \ref Data::mReservoir1Bkup | \ref Data::mReservoir2Prim | \ref Data::mReservoir2Bkup | :param vRs1Prim: (float) Reservoir 1 Primary :param vRs1Bkup: (float) Reservoir 1 Backup :param vRs2Prim: (float) Reservoir 2 Primary :param vRs2Bkup: (float) Reservoir 2 Backup - :return: (str) built message frame(s) - """ - msg = messageBuilder.buildMessage(0x000C, 4 + 4 + 4 + 4, False, - utils.toF32(vRs1Prim), - utils.toF32(vRs1Bkup), - utils.toF32(vRs2Prim), - utils.toF32(vRs2Bkup)) - return messageBuilder.toFrames(msg) - - @staticmethod - def setDGLoadCellReadingsData(vRs1Prim, vRs1Bkup, vRs2Prim, vRs2Bkup): - """ - the DG Load Cell Readings Data message setter/sender method - :param vRs1Prim: (float) Reservoir 1 Primary - :param vRs1Bkup: (float) Reservoir 1 Backup - :param vRs2Prim: (float) Reservoir 2 Primary - :param vRs2Bkup: (float) Reservoir 2 Backup :return: none """ - frames = HDSimulator.buildDGLoadCellReadingsData(vRs1Prim, vRs1Bkup, vRs2Prim, vRs2Bkup) - frames = messageBuilder.toCandumpFormat(frames) - for frame in frames: - subprocess.call(['cansend', 'can0', '080#{}'.format(frame)]) - HDSimulator.waitForMessageToBeSent() - @staticmethod - def buildDGTemperaturesData(vInletPrimaryHeater, vOutletPrimaryHeater, vConductivitySensor1, vConductivitySensor2, - vOutletRedundancy, vInletDialysate, vPrimaryHeaterThermocouple, vTrimmerHeaterThermocouple, - vPrimaryHeaterColdJunction, vTrimmerHeaterColdJunction, vPrimaryHeaterInternalTemperature, - vTrimmerHeaterInternalTemperature): + payload = float_to_bytearray(vRs1Prim) + payload += float_to_bytearray(vRs1Bkup) + payload += float_to_bytearray(vRs2Prim) + payload += float_to_bytearray(vRs2Bkup) + + message = DenaliMessage.build_message(channel_id=DenaliChannels.dg_sync_broadcast_ch_id, + message_id=MsgIds.MSG_ID_LOAD_CELL_READINGS.value, + payload=payload) + + self.can_interface.send(message, 0) + + def cmd_set_dg_temperatures_data(self, vInletPrimaryHeater, vOutletPrimaryHeater, vConductivitySensor1, vConductivitySensor2, + vOutletRedundancy, vInletDialysate, vPrimaryHeaterThermocouple, vTrimmerHeaterThermocouple, + vPrimaryHeaterColdJunction, vTrimmerHeaterColdJunction, vPrimaryHeaterInternalTemperature, + vTrimmerHeaterInternalTemperature): """ - the DG Temperatures Data message builder method + the DG Temperatures Data message setter/sender method | MSG | CAN ID | Box | Type | Ack | Src | Dst | Description | #1:(F32) | #2:(F32) | #3:(F32) | |:----:|:------:|:---:|:------:|:---:|:---:|:---:|:-----------: |:--: |:--: |:--: | |0x2D00| 0x080 | 8 | 2 Hz | N | DG | All | DG Temperatures Data | \ref Data::mInletPrimaryHeater | \ref Data::mOutletPrimaryHeater | \ref Data::mConductivitySensor1 | @@ -1345,191 +1120,123 @@ :param vTrimmerHeaterColdJunction: (float) Trimmer Heater ColdJunction :param vPrimaryHeaterInternalTemperature: (float) Primary Heater Internal Temperature :param vTrimmerHeaterInternalTemperature: (float) Trimmer HeaterInternal Temperature - :return: (str) built message frame(s) - """ - msg = messageBuilder.buildMessage(0x002D, 4 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + 4, False, - utils.toF32(vInletPrimaryHeater), - utils.toF32(vOutletPrimaryHeater), - utils.toF32(vConductivitySensor1), - utils.toF32(vConductivitySensor2), - utils.toF32(vOutletRedundancy), - utils.toF32(vInletDialysate), - utils.toF32(vPrimaryHeaterThermocouple), - utils.toF32(vTrimmerHeaterThermocouple), - utils.toF32(vPrimaryHeaterColdJunction), - utils.toF32(vTrimmerHeaterColdJunction), - utils.toF32(vPrimaryHeaterInternalTemperature), - utils.toF32(vTrimmerHeaterInternalTemperature)) - return messageBuilder.toFrames(msg) - - @staticmethod - def setDGTemperaturesData(vInletPrimaryHeater, vOutletPrimaryHeater, vConductivitySensor1, vConductivitySensor2, - vOutletRedundancy, vInletDialysate, vPrimaryHeaterThermocouple, vTrimmerHeaterThermocouple, - vPrimaryHeaterColdJunction, vTrimmerHeaterColdJunction, vPrimaryHeaterInternalTemperature, - vTrimmerHeaterInternalTemperature): - """ - the DG Temperatures Data message setter/sender method - :param vInletPrimaryHeater: (float) Inlet Primary Heater - :param vOutletPrimaryHeater: (float) Outlet Primary Heater - :param vConductivitySensor1: (float) Conductivity Sensor 1 - :param vConductivitySensor2: (float) Conductivity Sensor 2 - :param vOutletRedundancy: (float) Outlet Redundancy - :param vInletDialysate: (float) Inlet Dialysate - :param vPrimaryHeaterThermocouple: (float) Primary Heater Thermocouple - :param vTrimmerHeaterThermocouple: (float) Trimmer Heater Thermocouple - :param vPrimaryHeaterColdJunction: (float) Primary Heater ColdJunction - :param vTrimmerHeaterColdJunction: (float) Trimmer Heater ColdJunction - :param vPrimaryHeaterInternalTemperature: (float) Primary Heater Internal Temperature - :param vTrimmerHeaterInternalTemperature: (float) Trimmer HeaterInternal Temperature :return: none """ - frames = HDSimulator.buildDGTemperaturesData(vInletPrimaryHeater, vOutletPrimaryHeater, vConductivitySensor1, - vConductivitySensor2, vOutletRedundancy, vInletDialysate, - vPrimaryHeaterThermocouple, vTrimmerHeaterThermocouple, vPrimaryHeaterColdJunction, - vTrimmerHeaterColdJunction, vPrimaryHeaterInternalTemperature, - vTrimmerHeaterInternalTemperature) - frames = messageBuilder.toCandumpFormat(frames) - for frame in frames: - subprocess.call(['cansend', 'can0', '080#{}'.format(frame)]) - HDSimulator.waitForMessageToBeSent() - @staticmethod - def buildTreatmentStatesData(vSubMode, vUFState, vSalineState): + payload = float_to_bytearray(vInletPrimaryHeater) + payload += float_to_bytearray(vOutletPrimaryHeater) + payload += float_to_bytearray(vConductivitySensor1) + payload += float_to_bytearray(vConductivitySensor2) + payload += float_to_bytearray(vOutletRedundancy) + payload += float_to_bytearray(vInletDialysate) + payload += float_to_bytearray(vPrimaryHeaterThermocouple) + payload += float_to_bytearray(vTrimmerHeaterThermocouple) + payload += float_to_bytearray(vPrimaryHeaterColdJunction) + payload += float_to_bytearray(vTrimmerHeaterColdJunction) + payload += float_to_bytearray(vPrimaryHeaterInternalTemperature) + payload += float_to_bytearray(vTrimmerHeaterInternalTemperature) + + message = DenaliMessage.build_message(channel_id=DenaliChannels.dg_sync_broadcast_ch_id, + message_id=MsgIds.MSG_ID_DG_TEMPERATURE_DATA.value, + payload=payload) + + self.can_interface.send(message, 0) + + def cmd_set_treatment_states_data(self, vSubMode, vUFState, vSalineState): """ - the Treatment States Data message builder method + the Treatment States Data message setter/sender method | MSG | CAN ID | Box | Type | Ack | Src | Dst | Description | #1:(U32) | #2:(U32) | #3:(U32) | |:----:|:------:|:---:|:------:|:---:|:---:|:---:|:-----------: |:--: |:--: |:--: | |0x0F00| 0x040 | 7 | 1 Hz | N | HD | All | Treatment States Data | \ref Data::mSubMode | \ref Data::mUFState | \ref Data::mSalineState | :param vSubMode: (int) Sub-Mode :param vUFState: (int) UF State :param vSalineState: (int) Saline Bolus State - :return: (str) built message frame(s) - """ - msg = messageBuilder.buildMessage(0x000F, 4 + 4 + 4, False, - utils.toI32(vSubMode), - utils.toI32(vUFState), - utils.toI32(vSalineState)) - return messageBuilder.toFrames(msg) - - @staticmethod - def setTreatmentStatesData(vSubMode, vUFState, vSalineState): - """ - the Treatment States Data message setter/sender method - :param vSubMode: (int) Sub-Mode - :param vUFState: (int) UF State - :param vSalineState: (int) Saline Bolus State :return: none """ - frames = HDSimulator.buildTreatmentStatesData(vSubMode, vUFState, vSalineState) - frames = messageBuilder.toCandumpFormat(frames) - for frame in frames: - subprocess.call(['cansend', 'can0', '040#{}'.format(frame)]) - HDSimulator.waitForMessageToBeSent() - @staticmethod - def setTreatmentStartState(): + payload = integer_to_bytearray(vSubMode) + payload += integer_to_bytearray(vUFState) + payload += integer_to_bytearray(vSalineState) + + message = DenaliMessage.build_message(channel_id=DenaliChannels.hd_sync_broadcast_ch_id, + message_id=MsgIds.MSG_ID_TREATMENT_STATE.value, + payload=payload) + + self.can_interface.send(message, 0) + + def cmd_set_treatment_start_state(self): """ starting the treatment for user convenience since Tx is not by default running :return: none """ - HDSimulator.setTreatmentStatesData(txStates.TREATMENT_DIALYSIS_STATE, txStates.UF_OFF_STATE, txStates.SALINE_BOLUS_STATE_IDLE) + self.cmd_set_treatment_states_data(TXStates.TREATMENT_DIALYSIS_STATE, TXStates.UF_OFF_STATE, TXStates.SALINE_BOLUS_STATE_IDLE) - @staticmethod - def buildHDOperationModeData(vOpMode): + def cmd_set_hd_operation_mode_data(self, operation_mode): """ - the HD Operation Mode Data message builder method + The HD Operation Mode Data message setter/sender method | MSG | CAN ID | Box | Type | Ack | Src | Dst | Description | #1:(U32) | |:----:|:------:|:---:|:------:|:---:|:---:|:---:|:-----------: |:--: | |0x2500| 0x040 | 7 | 1 Hz | N | HD | All | HD Operation Mode Data | \ref Data::mOpMode | - :param vOpMode: (int) Operation Mode - :return: (str) built message frame(s) - """ - msg = messageBuilder.buildMessage(0x0025, 4, False, - utils.toI32(vOpMode)) - return messageBuilder.toFrames(msg) - - @staticmethod - def setHDOperationModeData(vOpMode): - """ - the HD Operation Mode Data message setter/sender method - :param vOpMode: (int) Operation Mode + :param operation_mode: (int) Operation Mode :return: none """ - frames = HDSimulator.buildHDOperationModeData(vOpMode) - frames = messageBuilder.toCandumpFormat(frames) - for frame in frames: - subprocess.call(['cansend', 'can0', '040#{}'.format(frame)]) - HDSimulator.waitForMessageToBeSent() - @staticmethod - def buildTreatmentSalineBolusData(vTarget, vCumulative, vDelivered): + payload = integer_to_bytearray(operation_mode) + + message = DenaliMessage.build_message(channel_id=DenaliChannels.hd_sync_broadcast_ch_id, + message_id=MsgIds.MSG_ID_HD_OP_MODE.value, + payload=payload) + + self.can_interface.send(message, 0) + + def cmd_set_treatment_saline_bolus_data(self, vTarget, vCumulative, vDelivered): """ - the Treatment Saline Bolus Data message builder method + the Treatment Saline Bolus Data message sender method | MSG | CAN ID | Box | Type | Ack | Src | Dst | Description | #1:(U32) | #2:(F32) | #3:(F32) | |:----:|:------:|:---:|:------:|:---:|:---:|:---:|:-----------: |:--: |:--: |:--: | |0x2F00| 0x040 | 7 | 1 Hz | N | HD | All | Treatment Saline Bolus Data | \ref Data::mTarget | \ref Data::mCumulative | \ref Data::mDelivered | - :param vTarget: (int) Saline Bolus Target Volume - :param vCumulative: (float) Saline Bolus Cumulative Volume - :param vDelivered: (float) Saline Bolus Delivered Volume - :return: (str) built message frame(s) - """ - msg = messageBuilder.buildMessage(0x002F, 4 + 4 + 4, False, - utils.toI32(vTarget), - utils.toF32(vCumulative), - utils.toF32(vDelivered)) - return messageBuilder.toFrames(msg) - @staticmethod - def setTreatmentSalineBolusData(vTarget, vCumulative, vDelivered): - """ - the Treatment Saline Bolus Data message setter/sender method :param vTarget: (int) Saline Bolus Target Volume :param vCumulative: (float) Saline Bolus Cumulative Volume :param vDelivered: (float) Saline Bolus Delivered Volume :return: none """ - frames = HDSimulator.buildTreatmentSalineBolusData(vTarget, vCumulative, vDelivered) - frames = messageBuilder.toCandumpFormat(frames) - for frame in frames: - subprocess.call(['cansend', 'can0', '040#{}'.format(frame)]) - HDSimulator.waitForMessageToBeSent() - @staticmethod - def buildSalineBolusResponse(vAccepted, vReason, vTarget, vState): + payload = integer_to_bytearray(vTarget) + payload += float_to_bytearray(vCumulative) + payload += float_to_bytearray(vDelivered) + + message = DenaliMessage.build_message(channel_id=DenaliChannels.hd_sync_broadcast_ch_id, + message_id=MsgIds.MSG_ID_SALINE_BOLUS_DATA.value, + payload=payload) + + self.can_interface.send(message, 0) + + def cmd_set_saline_bolus_response(self, vAccepted, vReason, vTarget, vState): """ - the Saline Bolus Response message builder method + the Saline Bolus Response message sender method | MSG | CAN ID | M.Box | Type | Ack | Src | Dest | Description | #1:(U32) | #2:(U32) | #3:(U32) | #3:(U32) | |:---:|:------:|:-----:|:----:|:---:|:---:|:----:|:---------------------:|:--------------------:|:-------------------:|:-------------------:|:-------------------:| | 20 | 0x020 | 6 | Rsp | Y | HD | UI | Saline Bolus Response | \ref Data::mAccepted | \ref Data::mReason | \ref Data::mTarget | \ref Data::mState | - :param vAccepted: (int) boolean accept/reject response - :param vReason: (int) rejection reason - :param vTarget: (int) Saline Bolus Target Volume - :param vState: (int) Saline Bolus current State - :return: (str) built message frame(s) - """ - msg = messageBuilder.buildMessage(0x0014, 4 + 4 + 4 + 4, True, - utils.toI32(vAccepted), - utils.toI32(vReason), - utils.toI32(vTarget), - utils.toI32(vState)) - return messageBuilder.toFrames(msg) - @staticmethod - def setSalineBolusResponse(vAccepted, vReason, vTarget, vState): - """ - the Saline Bolus Response message setter/sender method :param vAccepted: (int) boolean accept/reject response :param vReason: (int) rejection reason :param vTarget: (int) Saline Bolus Target Volume :param vState: (int) Saline Bolus current State :return: none """ - frames = HDSimulator.buildSalineBolusResponse(vAccepted, vReason, vTarget, vState) - frames = messageBuilder.toCandumpFormat(frames) - for frame in frames: - subprocess.call(['cansend', 'can0', '020#{}'.format(frame)]) - HDSimulator.waitForMessageToBeSent() + payload = integer_to_bytearray(vAccepted) + payload += integer_to_bytearray(vReason) + payload += integer_to_bytearray(vTarget) + payload += integer_to_bytearray(vState) + + message = DenaliMessage.build_message(channel_id=DenaliChannels.hd_to_ui_ch_id, + message_id=MsgIds.MSG_ID_USER_SALINE_BOLUS_RESPONSE.value, + payload=payload) + + self.can_interface.send(message, 0) + @staticmethod def buildCanBUSFaultCount(vCount): """ Index: dialin/ui/utils.py =================================================================== diff -u -re5b68dd61c18dd97545d5e527a7f0a8f84061cb6 -rf3ea3f9a7864df4f448b60a3192ca83c51c4e881 --- dialin/ui/utils.py (.../utils.py) (revision e5b68dd61c18dd97545d5e527a7f0a8f84061cb6) +++ dialin/ui/utils.py (.../utils.py) (revision f3ea3f9a7864df4f448b60a3192ca83c51c4e881) @@ -82,6 +82,7 @@ """ return '{:08X}'.format(struct.unpack('f', vValue))[0],'X') + def partition(vString, vPart, vRightDirection=True): """ splits the given string into sections of vPart long @@ -95,6 +96,7 @@ """ return [vString[i: i + vPart] for i in range(0, len(vString), vPart)][::-1 if vRightDirection else 1] + def padding(vString, vLen): """ added zero at the right side of the string to be of length of vLen @@ -106,6 +108,7 @@ lPad = int(lStr / vLen) * vLen + ( vLen * (1 if lStr % vLen else 0) ) return vString.ljust(lPad, "0") + def tstStart(vTestName): """ test case start print out with time @@ -114,21 +117,24 @@ """ print(time.strftime("%H:%M:%S Start", time.localtime()) + " - " + vTestName) + def tstDone(): """ test case end print out with time :return: none - prints out on the console """ print(time.strftime("%H:%M:%S Done ", time.localtime())) + def l2ml(vValue): """ converts liter to mili liter :param (int) vValue: the value in liter. :return: (int) vValue converted to miliiliter. """ return int(round (vValue, 3) * 1000) - + + def ml2l(vValue): """ converts mili liter to liter @@ -137,3 +143,17 @@ """ return vValue / 1000 + +def dict_update(obj: dict, key: str, value): + """ + Adds a key and value to a dictionary object without updating the original + dictionary + + @param obj: (dict) the object to update + @param key: (str) the key name + @param value: the new value of the field + @return: (dict) the updated dictionary object + """ + obj = obj.copy() + obj[key] = value + return obj