Index: dialin/protocols/CAN.py =================================================================== diff -u -ref9b75f5db31f12a46fe9b509385fbd222cd2bf4 -rcdf1c02e39d16c42fcb04a93f7ff180a8533d491 --- dialin/protocols/CAN.py (.../CAN.py) (revision ef9b75f5db31f12a46fe9b509385fbd222cd2bf4) +++ dialin/protocols/CAN.py (.../CAN.py) (revision cdf1c02e39d16c42fcb04a93f7ff180a8533d491) @@ -432,7 +432,7 @@ START_BYTE = DenaliMessage.START_BYTE DIALIN_MSG_RESP_TO = 0.1 # number of seconds to wait for a response to a sent command - def __init__(self, can_interface: str, logger: Logger, log_can=False, passive_mode=False): + def __init__(self, can_interface: str, logger: Logger, log_can=False, passive_mode=False, console_out=False): """ DenaliCanMessenger constructor @@ -442,12 +442,29 @@ """ super().__init__() - self.bus = can.interfaces.socketcan.SocketcanBus(channel=can_interface) self.logger = logger self.log_can = log_can + + # try to setup can bus and exit if the can bus has not ben setup to use. + try: + self.bus = can.interfaces.socketcan.SocketcanBus(channel=can_interface) + if self.bus is not None: + self.serial_listener_thread = threading.Thread(target=self.listener, daemon=True) + else: + self.serial_listener_thread = None + s = "Can connection is not valid" + self.logger.debug(s) + sys.exit(s) + self.listener_buffer = can.BufferedReader() + self.notifier = can.Notifier(self.bus, [self.listener_buffer]) + except Exception as e: + s = str(e) + self.logger.debug(s) + print(s) + sys.exit(19) + self.passive_mode = passive_mode - self.listener_buffer = can.BufferedReader() - self.notifier = can.Notifier(self.bus, [self.listener_buffer]) + self.console_out = console_out self.send_packet_request_id = -1 self.send_event = threading.Event() self.long_message_builders = {} @@ -459,13 +476,6 @@ self.run = False self.sync_response_dictionary = {} - if self.bus is not None: - self.serial_listener_thread = threading.Thread(target=self.listener, daemon=True) - - else: - self.serial_listener_thread = None - self.logger.debug("Can connection is not valid") - def start(self): """ starts listening to the can interface. @@ -563,6 +573,8 @@ DenaliMessage.crc8(self.messages))) if message_valid: + if self.console_out: + print(complete_dialin_message) # Send an ack if required if DenaliMessage.get_sequence_number(complete_dialin_message) < 0: # ACK required. Send back the received message with the sequence sign bit flipped Index: dialin/ui/hd_simulator.py =================================================================== diff -u -ref9b75f5db31f12a46fe9b509385fbd222cd2bf4 -rcdf1c02e39d16c42fcb04a93f7ff180a8533d491 --- dialin/ui/hd_simulator.py (.../hd_simulator.py) (revision ef9b75f5db31f12a46fe9b509385fbd222cd2bf4) +++ dialin/ui/hd_simulator.py (.../hd_simulator.py) (revision cdf1c02e39d16c42fcb04a93f7ff180a8533d491) @@ -28,7 +28,7 @@ DenaliCanMessenger, DenaliChannels) from ..utils.base import _AbstractSubSystem, _LogManager -from ..utils.conversions import integer_to_bytearray, float_to_bytearray +from ..utils.conversions import integer_to_bytearray, float_to_bytearray, byte_to_bytearray, short_to_bytearray YES = 1 NO = 0 @@ -76,33 +76,60 @@ class TXStates: + # Sub Mode + TREATMENT_START_STATE = 0 # Start treatment - initialize treatment and go to blood prime state + TREATMENT_BLOOD_PRIME_STATE = 1 # Prime blood-side of dialyzer with gradual ramp for 1 min. while dialyzer is bypassed. No dialysis or UF taking place. No treatment time. + TREATMENT_DIALYSIS_STATE = 2 # Perform dialysis. Deliver Heparin as prescribed. Deliver UF as prescribed. Handle saline boluses as requested + TREATMENT_STOP_STATE = 3 # Treatment stopped. All pumps off. Dializer bypassed + TREATMENT_RINSEBACK_STATE = 4 # Perform rinseback with saline. Dialyzer bypassed. Dialysate recirculating + TREATMENT_RECIRC_STATE = 5 # Recirculate saline and dialysate while patient disconnected. Blood lines open and shunted. Dialyzer is bypassed + TREATMENT_END_STATE = 6 # Dialysis has ended. Blood pump slowed. Dialyzer is bypassed. Dialysate is recirculated. User can rinseback + # 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 - SALINE_BOLUS_STATE_IN_PROGRESS = 2 # A saline bolus delivery is in progress - SALINE_BOLUS_STATE_MAX_DELIVERED = 3 # Maximum saline bolus volume reached - no more saline bolus deliveries allowed + 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 + SALINE_BOLUS_STATE_IN_PROGRESS = 2 # A saline bolus delivery is in progress + SALINE_BOLUS_STATE_MAX_DELIVERED = 3 # Maximum saline bolus volume reached - no more saline bolus deliveries allowed # UF states - UF_START_STATE = 0 # Start state of the ultrafiltration state machine - UF_PAUSED_STATE = 1 # Paused state of the ultrafiltration state machine - UF_RUNNING_STATE = 2 # Running state of the ultrafiltration state machine - UF_OFF_STATE = 3 # Completed/off state of the ultrafiltration state machine - UF_COMPLETED_STATE = 4 # Completed state of ultrafiltration state machine + UF_START_STATE = 0 # Start state of the ultrafiltration state machine + UF_PAUSED_STATE = 1 # Paused state of the ultrafiltration state machine + UF_RUNNING_STATE = 2 # Running state of the ultrafiltration state machine + UF_OFF_STATE = 3 # Completed/off state of the ultrafiltration state machine + UF_COMPLETED_STATE = 4 # Completed state of ultrafiltration state machine - # Sub Mode - # UI only cares about the actual state and _NOT could be any other state - TREATMENT_DIALYSIS_STATE_NOT = 0 - TREATMENT_DIALYSIS_STATE = 1 # Heparin states - HEPARIN_STATE_OFF = 0 # No heparin delivery is in progress - HEPARIN_STATE_PAUSED = 1 # Heparin delivery paused + HEPARIN_STATE_OFF = 0 # No heparin delivery is in progress + HEPARIN_STATE_PAUSED = 1 # Heparin delivery paused HEPARIN_STATE_INITIAL_BOLUS = 2 # Initial heparin bolus delivery in progress - HEPARIN_STATE_DISPENSING = 3 # Gradual heparin dispensing in progress - HEPARIN_STATE_COMPLETED = 4 # Heparin delivery stopped due to the set stop time before treatment end - HEPARIN_STATE_EMPTY = 5 # Heparin Syringe empty + HEPARIN_STATE_DISPENSING = 3 # Gradual heparin dispensing in progress + HEPARIN_STATE_COMPLETED = 4 # Heparin delivery stopped due to the set stop time before treatment end + HEPARIN_STATE_EMPTY = 5 # Heparin Syringe empty + # Rinseback states + RINSEBACK_STOP_INIT_STATE = 0 # Start state (stopped) of the rinseback sub-mode state machine + RINSEBACK_RUN_STATE = 1 # Rinseback running state of the rinseback sub-mode state machine + RINSEBACK_PAUSED_STATE = 2 # Rinseback paused state of the rinseback sub-mode state machine + RINSEBACK_STOP_STATE = 3 # Rinseback stopped (done) state of the rinseback sub-mode state machine + RINSEBACK_RUN_ADDITIONAL_STATE = 4 # Additional rinseback volume (10 mL) state of the rinseback sub-mode state machine + # Recirculate + TREATMENT_RECIRC_RECIRC_STATE = 0 # Re-circulate state of the treatment re-circulate sub-mode state machine + TREATMENT_RECIRC_STOPPED_STATE = 1 # Stopped state of the treatment re-circulate sub-mode state machine + + # Blood Prime + BLOOD_PRIME_RAMP_STATE = 0 # Ramp state of the blood prime sub-mode state machine + + # Treatment End + TREATMENT_END_WAIT_FOR_RINSEBACK_STATE = 0 # Wait for rinseback state of the treatment end sub-mode state machine + TREATMENT_END_PAUSED_STATE = 1 # Paused state of the treatment end sub-mode state machine + + # Treatment Stop + TREATMENT_STOP_RECIRC_STATE = 0 # Dialysate re-circulation state of the treatment stop sub-mode state machine + TREATMENT_STOP_NO_RECIRC_STATE = 1 # No dialysate re-circulation state of the treatment stop sub-mode state machine + + class EResponse: Rejected = 0 Accepted = 1 @@ -159,16 +186,19 @@ class HDSimulator(_AbstractSubSystem): NUM_TREATMENT_PARAMETERS = 18 + instanceCount = 0 - def __init__(self, can_interface="can0", log_level=None): - + def __init__(self, can_interface="can0", log_level=None, console_out=False): super().__init__() + HDSimulator.instanceCount = HDSimulator.instanceCount + 1 self._log_manager = _LogManager(log_level=log_level, log_filepath=self.__class__.__name__ + ".log") self.logger = self._log_manager.logger + self.console_out = console_out self.can_interface = DenaliCanMessenger(can_interface=can_interface, logger=self.logger, - log_can=self._log_manager.log_level == "CAN_ONLY") + log_can=self._log_manager.log_level == "CAN_ONLY", + console_out=console_out) self.can_interface.start() if self.can_interface is not None: @@ -697,13 +727,13 @@ self.can_interface.send(message, 0) - def cmd_set_treatment_blood_flow_rate(self, vFlowSetPt, vMeasFlow, vRotSpd, vMotSpd, vMCSpd, vMCCurr, vPWM): + def cmd_set_treatment_blood_flow_rate(self, vFlowSetPt, vMeasFlow, vRotSpd, vMotSpd, vMCSpd, vMCCurr, vPWM, vSigStrength): """ 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 | + | MSG | CAN ID | Box | Type | Ack | Src | Dst | Description | #1:(S32) | #2:(F32) | #3:(F32) | #4:(F32) | #5:(F32) | #6:(F32) | #7:(F32) | #8:(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 | \ref Data::mSigStrenght | :param vFlowSetPt: (signed int) Flow Set Point :param vMeasFlow: (float) Measured Flow @@ -712,6 +742,7 @@ :param vMCSpd: (float) MC Speed :param vMCCurr: (float) MC Current :param vPWM: (float) PWM + :param vSigStrength: (float) Signal strength in percent :return: None """ @@ -722,20 +753,21 @@ payload += float_to_bytearray(vMCSpd) payload += float_to_bytearray(vMCCurr) payload += float_to_bytearray(vPWM) + payload += float_to_bytearray(vSigStrength) 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): + def cmd_set_treatment_dialysate_flow_rate(self, vFlowSetPt, vMeasFlow, vRotSpd, vMotSpd, vMCSpd, vMCCurr, vPWM, vSigStrength): """ 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 | + | MSG | CAN ID | Box | Type | Ack | Src | Dst | Description | #1:(S32) | #2:(F32) | #3:(F32) | #4:(F32) | #5:(F32) | #6:(F32) | #7:(F32) | #8:(F32) | + |:----:|:------:|:---:|:------:|:---:|:---:|:---:|:-----------: |:--: |:--: |:--: |:--: |:--: |:--: |:--: |:--: | + |0x0800| 0x040 | 7 | 1 Hz | N | HD | All | Dialysate Flow Data | mFlowSetPoint | mMeasuredFlow | mRotorSpeed | mMotorSpeed | mMotorCtlSpeed | mMotorCtlCurrent | mPWMDutyCycle | \ref Data::mSigStrenght | :param vFlowSetPt: (signed int) Flow Set Point :param vMeasFlow: (float) Measured Flow @@ -744,6 +776,7 @@ :param vMCSpd: (float) MC Speed :param vMCCurr: (float) MC Current :param vPWM: (float) PWM + :param vSigStrength: (float) Signal strength in percent :return: None """ @@ -754,6 +787,7 @@ payload += float_to_bytearray(vMCSpd) payload += float_to_bytearray(vMCCurr) payload += float_to_bytearray(vPWM) + payload += float_to_bytearray(vSigStrength) message = DenaliMessage.build_message(channel_id=DenaliChannels.hd_sync_broadcast_ch_id, message_id=MsgIds.MSG_ID_DIALYSATE_FLOW_DATA.value, @@ -855,6 +889,30 @@ """ self.cmd_set_treatment_adjust_ultrafiltration_state_response(EResponse.Rejected, vReason, vState) + def cmd_set_treatment_adjust_ultrafiltration_init_response(self, vAccepted, vReason, vVolume): + """ + the ultrafiltration volume change response message setter/sender method + + | MSG | CAN ID | Box | Type | Ack | Src | Dst | Description | #1:(U32) | #2:(U32) | #3:(F32) + |:----:|:------:|:---:|:------:|:---:|:---:|:---:|:-----------: |:--: |:--: |:--: + |0x5000| 0x020 | 6 | Rsp | Y | HD | UI | Pre UF Volume Adjustment Response | \ref Data::mAccepted | \ref Data::mReason | \ref Data::mVolume + + :param vAccepted: (int) boolean accept/reject response + :param vReason: (int) rejection reason + :param vVolume: (float) Ultrafiltration Volume + :return: none + """ + + payload = integer_to_bytearray(vAccepted) + payload += integer_to_bytearray(vReason) + payload += float_to_bytearray(vVolume) + + message = DenaliMessage.build_message(channel_id=DenaliChannels.hd_to_ui_ch_id, + message_id=MsgIds.MSG_ID_HD_PRE_TREATMENT_UF_RESPONSE.value, + payload=payload) + + self.can_interface.send(message, 0) + def cmd_set_treatment_adjust_ultrafiltration_edit_response(self, vAccepted, vReason, vVolume, vDuration, vDurationDiff, vRate, vRateDiff, vRateOld): """ @@ -1258,23 +1316,49 @@ self.can_interface.send(message, 0) - def cmd_set_treatment_states_data(self, vSubMode, vUFState, vSalineState, vHeparingState): + def cmd_set_treatment_states_data(self, + vSubMode, vUFState, vSalineState, vHeparingState, + vRinsebackState, vRecirculateState, + vBloodPrimeState, vTreatmentEndState, vTreammentStopState): """ the Treatment States Data message setter/sender method - | MSG | CAN ID | Box | Type | Ack | Src | Dst | Description | #1:(U32) | #2:(U32) | #3:(U32) | #4:(U32) | - |:----:|:------:|:---:|:------:|:---:|:---:|:---:|:-----------: |:--: |:--: |:--: |:--: | - |0x0F00| 0x040 | 7 | 1 Hz | N | HD | All | Treatment States Data | \ref Data::mSubMode | \ref Data::mUFState | \ref Data::mSalineState | \ref Data::mHeparinState| + | MSG | CAN ID | Box | Type | Ack | Src | Dst | Description | + |:----:|:------:|:---:|:------:|:---:|:---:|:---:|:-----------: | + |0x0F00| 0x040 | 7 | 1 Hz | N | HD | All | Treatment States Data | + + | #1:(U32) | #2:(U32) | #3:(U32) | #4:(U32) | + |:--: |:--: |:--: |:--: | + | \ref Data::mSubMode | \ref Data::mUFState | \ref Data::mSalineState | \ref Data::mHeparinState | + |||| + | #5:(U32) | #6:(U32) ||| + |:--: |:--: ||| + | \ref Data::mRinsebackState | \ref Data::mRecirculateState ||| + |||| + | #7:(U32) | #8:(U32) | #9:(U32) || + |:--: |:--: |:--: || + | \ref Data::vBloodPrimeState | \ref Data::mTreatmentEndState | \ref Data::vTreammentStopState || + :param vSubMode: (int) Sub-Mode :param vUFState: (int) UF State :param vSalineState: (int) Saline Bolus State :param vHeparingState: (int) Saline Bolus State + :param vRinsebackState: (int) Rinseback State + :param vRecirculateState: (int) Recirculate State + :param vBloodPrimeState: (int) Blood Prime State + :param vTreatmentEndState: (int) Treatment End State + :param vTreammentStopState: (int) Treatment Stop State :return: none """ - payload = integer_to_bytearray(vSubMode) + payload = integer_to_bytearray(vSubMode) payload += integer_to_bytearray(vUFState) payload += integer_to_bytearray(vSalineState) payload += integer_to_bytearray(vHeparingState) + payload += integer_to_bytearray(vRinsebackState) + payload += integer_to_bytearray(vRecirculateState) + payload += integer_to_bytearray(vBloodPrimeState) + payload += integer_to_bytearray(vTreatmentEndState) + payload += integer_to_bytearray(vTreammentStopState) message = DenaliMessage.build_message(channel_id=DenaliChannels.hd_sync_broadcast_ch_id, message_id=MsgIds.MSG_ID_TREATMENT_STATE.value, @@ -1473,7 +1557,286 @@ self.can_interface.send(message, 0) + def cmd_send_treatment_adjust_rinseback_response(self, vAccepted, vReason): + """ + the rinseback state change Response message method + | MSG | CAN ID | Box | Type | Ack | Src | Dst | Description | #1:(U32) | #2:(U32) | + |:----:|:------:|:---:|:------:|:---:|:---:|:---:|:-----------: |:--: |:--: | + |0x5300| 0x020 | 6 | Rsp | Y | HD | UI | Rinseback State Change Response | \ref Data::mAccepted | \ref Data::mReason | + :param vAccepted: (int) boolean accept/reject response + :param vReason : (int) rejection reason + :return: None + """ + payload = integer_to_bytearray(vAccepted) + payload += integer_to_bytearray(vReason) + message = DenaliMessage.build_message(channel_id=DenaliChannels.hd_to_ui_ch_id, + message_id=MsgIds.MSG_ID_HD_RINSEBACK_CMD_RESPONSE.value, + payload=payload) + self.can_interface.send(message, 0) + + def cmd_send_treatment_rinseback_data(self, vTarget, vCurrent, vRate, vTimeoutTotal, vTimeoutCountDown): + """ + the rinseback state change Response message method + | MSG | CAN ID | Box | Type | Ack | Src | Dst | Description | #1:(F32) | #2:(F32) | #3:(U32) | #4:(U32) | #5:(U32) | + |:----:|:------:|:---:|:------:|:---:|:---:|:---:|:-----------: |:--: |:--: |:--: |:--: |:--: | + |0x5600| 0x020 | 6 | 1Hz | N | HD | UI | Rinseback progress data | \ref Data::mTarget | \ref Data::mCurrent | \ref Data::mRate | \ref Data::mTimeoutTotal | \ref Data::mTimeoutCountDown | + + :param vTarget : (float) the target volume in mL + :param vCurrent : (float) the current volume in mL + :param vRate : (uint ) the current flow rate in mL/min + :param vTimeoutTotal : (uint ) Total Timeout + :param vTimeoutCountDown: (uint ) Current Timeout count down + :return: None + """ + + payload = float_to_bytearray(vTarget) + payload += float_to_bytearray(vCurrent) + payload += integer_to_bytearray(vRate) + payload += integer_to_bytearray(vTimeoutTotal) + payload += integer_to_bytearray(vTimeoutCountDown) + + message = DenaliMessage.build_message(channel_id=DenaliChannels.hd_to_ui_ch_id, + message_id=MsgIds.MSG_ID_HD_RINSEBACK_PROGRESS.value, + payload=payload) + + self.can_interface.send(message, 0) + + def cmd_send_treatment_recirculate_data(self,vTimeoutTotal, vTimeoutCountDown): + """ + the rinseback state change Response message method + | MSG | CAN ID | Box | Type | Ack | Src | Dst | Description | #1:(U32) | #2:(U32) | + |:----:|:------:|:---:|:------:|:---:|:---:|:---:|:-----------: |:--: |:--: | + |0x5A00| 0x020 | 6 | 1Hz | N | HD | UI | Rinseback progress data | \ref Data::mTimeoutTotal | \ref Data::mTimeoutCountDown | + + :param vTimeoutTotal : (uint ) Total Timeout + :param vTimeoutCountDown: (uint ) Current Timeout count down + :return: None + """ + + payload = integer_to_bytearray(vTimeoutTotal) + payload += integer_to_bytearray(vTimeoutCountDown) + + message = DenaliMessage.build_message(channel_id=DenaliChannels.hd_to_ui_ch_id, + message_id=MsgIds.MSG_ID_HD_RECIRCULATE_PROGRESS.value, + payload=payload) + + self.can_interface.send(message, 0) + + def cmd_send_treatment_blood_prime_data(self, vTarget, vCurrent): + """ + the bloodprime state change Response message method + | MSG | CAN ID | Box | Type | Ack | Src | Dst | Description | #1:(F32) | #2:(F32) | #2:(U32) | + |:----:|:------:|:---:|:------:|:---:|:---:|:---:|:-----------: |:--: |:--: |:--: | + |0x5900| 0x020 | 6 | 1Hz | N | HD | UI | bloodprime progress data | \ref Data::mTarget | \ref Data::mCurrent | \ref Data::mRate | + + :param vTarget : (float) the target volume in mL + :param vCurrent : (float) the current volume in mL + :return: None + """ + + payload = float_to_bytearray(vTarget) + payload += float_to_bytearray(vCurrent) + + message = DenaliMessage.build_message(channel_id=DenaliChannels.hd_to_ui_ch_id, + message_id=MsgIds.MSG_ID_HD_BLOOD_PRIME_PROGRESS.value, + payload=payload) + + self.can_interface.send(message, 0) + + def cmd_send_treatment_adjust_recirculate_response(self, vAccepted, vReason): + """ + the recirculate state change Response message method + | MSG | CAN ID | Box | Type | Ack | Src | Dst | Description | #1:(U32) | #2:(U32) | + |:----:|:------:|:---:|:------:|:---:|:---:|:---:|:-----------: |:--: |:--: | + |0x5500| 0x020 | 6 | Rsp | Y | HD | UI | Recirculate State Change Response | \ref Data::mAccepted | \ref Data::mReason | + + :param vAccepted: (int) boolean accept/reject response + :param vReason : (int) rejection reason + :return: None + """ + + payload = integer_to_bytearray(vAccepted) + payload += integer_to_bytearray(vReason) + + message = DenaliMessage.build_message(channel_id=DenaliChannels.hd_to_ui_ch_id, + message_id=MsgIds.MSG_ID_HD_RECIRC_CMD_RESPONSE.value, + payload=payload) + + self.can_interface.send(message, 0) + + def cmd_send_treatment_adjust_end_response(self, vAccepted, vReason): + """ + the treatment end state change Response message method + | MSG | CAN ID | Box | Type | Ack | Src | Dst | Description | #1:(U32) | #2:(U32) | + |:----:|:------:|:---:|:------:|:---:|:---:|:---:|:-----------: |:--: |:--: | + |0x5800| 0x020 | 6 | Rsp | Y | HD | UI | Treatment End State Change Response | \ref Data::mAccepted | \ref Data::mReason | + + :param vAccepted: (int) boolean accept/reject response + :param vReason : (int) rejection reason + :return: None + """ + + payload = integer_to_bytearray(vAccepted) + payload += integer_to_bytearray(vReason) + + message = DenaliMessage.build_message(channel_id=DenaliChannels.hd_to_ui_ch_id, + message_id=MsgIds.MSG_ID_HD_TX_END_CMD_RESPONSE.value, + payload=payload) + + self.can_interface.send(message, 0) + + def cmd_send_accelerometer_hd_data(self, vX, vY, vZ, vXMax, vYMax, vZMax, vXTilt, vYTilt, vZTilt ): + """ + the accelerometer hd data message method + | MSG | CAN ID | Box | Type | Ack | Src | Dst | Description | + |:----:|:------:|:---:|:------:|:---:|:---:|:---:|:-----------: | + |0x3300| 0x040 | 7 | 1Hz | N | HD | UI | HD Accelerometer data | + + | #1:(F32) | #2:(F32) | #3:(U32) | + |:--: |:--: |:--: | + | \ref Data::mX | \ref Data::mY | \ref Data::mX | + + | #4:(F32) | #5:(F32) | #6:(U32) | + |:--: |:--: |:--: | + | \ref Data::mXMax | \ref Data::mYMax | \ref Data::mXMax | + + | #7:(F32) | #8:(F32) | #9:(U32) | + |:--: |:--: |:--: | + | \ref Data::mXTilt | \ref Data::mYTilt | \ref Data::mXTilt | + + :param vX: x axis + :param vY: y axis + :param vZ: z axis + :param vXMax: x axis max + :param vYMax: y axis max + :param vZMax: z axis max + :param vXTilt: x axis tilt + :param vYTilt: y axis tilt + :param vZTilt: z axis tilt + :return: None + """ + + payload = float_to_bytearray(vX) + payload += float_to_bytearray(vY) + payload += float_to_bytearray(vZ) + payload += float_to_bytearray(vXMax) + payload += float_to_bytearray(vYMax) + payload += float_to_bytearray(vZMax) + payload += float_to_bytearray(vXTilt) + payload += float_to_bytearray(vYTilt) + payload += float_to_bytearray(vZTilt) + + message = DenaliMessage.build_message(channel_id=DenaliChannels.hd_to_ui_ch_id, + message_id=MsgIds.MSG_ID_HD_ACCELEROMETER_DATA.value, + payload=payload) + + self.can_interface.send(message, 0) + + def cmd_send_accelerometer_dg_data(self, vX, vY, vZ, vXMax, vYMax, vZMax, vXTilt, vYTilt, vZTilt ): + """ + the accelerometer dg data message method + | MSG | CAN ID | Box | Type | Ack | Src | Dst | Description | + |:----:|:------:|:---:|:------:|:---:|:---:|:---:|:-----------: | + |0x3400| 0x080 | 8 | 1Hz | N | HD | UI | DG Accelerometer data | + + | #1:(F32) | #2:(F32) | #3:(U32) | + |:--: |:--: |:--: | + | \ref Data::mX | \ref Data::mY | \ref Data::mX | + + | #4:(F32) | #5:(F32) | #6:(U32) | + |:--: |:--: |:--: | + | \ref Data::mXMax | \ref Data::mYMax | \ref Data::mXMax | + + | #7:(F32) | #8:(F32) | #9:(U32) | + |:--: |:--: |:--: | + | \ref Data::mXTilt | \ref Data::mYTilt | \ref Data::mXTilt | + + :param vX: x axis + :param vY: y axis + :param vZ: z axis + :param vXMax: x axis max + :param vYMax: y axis max + :param vZMax: z axis max + :param vXTilt: x axis tilt + :param vYTilt: y axis tilt + :param vZTilt: z axis tilt + :return: None + """ + + payload = float_to_bytearray(vX) + payload += float_to_bytearray(vY) + payload += float_to_bytearray(vZ) + payload += float_to_bytearray(vXMax) + payload += float_to_bytearray(vYMax) + payload += float_to_bytearray(vZMax) + payload += float_to_bytearray(vXTilt) + payload += float_to_bytearray(vYTilt) + payload += float_to_bytearray(vZTilt) + + message = DenaliMessage.build_message(channel_id=DenaliChannels.dg_to_ui_ch_id, + message_id=MsgIds.MSG_ID_DG_ACCELEROMETER_DATA.value, + payload=payload) + + self.can_interface.send(message, 0) + + def cmd_send_version_hd_data(self, vMajor, vMinor, vMicro, vBuild, vFPGA_id, vFPGA_Major, vFPGA_Minor, vFPGA_Lab ): + """ + the hd version response message method + :param vMajor: Major version number + :param vMinor: Minor version number + :param vMicro: Micro version number + :param vBuild: Build version number + :param vFPGA_id: FPGA id version number + :param vFPGA_Major: FPGA Major version number + :param vFPGA_Minor: FPGA Minor version number + :param vFPGA_Lab: FPGA Lab version number + :return: None + """ + + payload = byte_to_bytearray(vMajor) + payload += byte_to_bytearray(vMinor) + payload += byte_to_bytearray(vMicro) + payload += short_to_bytearray(vBuild) + payload += byte_to_bytearray(vFPGA_id) + payload += byte_to_bytearray(vFPGA_Major) + payload += byte_to_bytearray(vFPGA_Minor) + payload += byte_to_bytearray(vFPGA_Lab) + + message = DenaliMessage.build_message(channel_id=DenaliChannels.hd_to_ui_ch_id, + message_id=MsgIds.MSG_ID_HD_VERSION.value, + payload=payload) + + self.can_interface.send(message, 0) + + def cmd_send_version_dg_data(self, vMajor, vMinor, vMicro, vBuild, vFPGA_id, vFPGA_Major, vFPGA_Minor, vFPGA_Lab ): + """ + the dg version response message method + :param vMajor: Major version number + :param vMinor: Minor version number + :param vMicro: Micro version number + :param vBuild: Build version number + :param vFPGA_id: FPGA id version number + :param vFPGA_Major: FPGA Major version number + :param vFPGA_Minor: FPGA Minor version number + :param vFPGA_Lab: FPGA Lab version number + :return: None + """ + + payload = byte_to_bytearray(vMajor) + payload += byte_to_bytearray(vMinor) + payload += byte_to_bytearray(vMicro) + payload += short_to_bytearray(vBuild) + payload += byte_to_bytearray(vFPGA_id) + payload += byte_to_bytearray(vFPGA_Major) + payload += byte_to_bytearray(vFPGA_Minor) + payload += byte_to_bytearray(vFPGA_Lab) + + message = DenaliMessage.build_message(channel_id=DenaliChannels.dg_to_ui_ch_id, + message_id=MsgIds.MSG_ID_DG_VERSION.value, + payload=payload) + + self.can_interface.send(message, 0)