Index: dialin/common/msg_defs.py =================================================================== diff -u -r96006d22aa13f0287e2697a7cac7604201633263 -r0a5edee793018705c54562d73a9a1d5ee648cb41 --- dialin/common/msg_defs.py (.../msg_defs.py) (revision 96006d22aa13f0287e2697a7cac7604201633263) +++ dialin/common/msg_defs.py (.../msg_defs.py) (revision 0a5edee793018705c54562d73a9a1d5ee648cb41) @@ -78,8 +78,8 @@ MSG_ID_HD_START_TREATMENT_RESPONSE = 0x39 # HD response to user request to initiate a treatment MSG_ID_HD_VALVES_DATA = 0x3A # HD broadcast of valves data MSG_ID_UI_USER_CONFIRM_TREATMENT_PARAMS = 0x3B # UI user confirmation of treatment parameters - MSG_ID_UI_TREATMENT_END_REQUEST = 0x3C # UI user treatment end request - MSG_ID_HD_TREATMENT_END_RESPONSE = 0x3D # HD response to user request to end treatment + MSG_ID___AVAILABLE_1 = 0x3C # NOT used - available + MSG_ID___AVAILABLE_2 = 0x3D # NOT used - available MSG_ID_HD_AIR_TRAP_DATA = 0x003E # HD broadcast of air trap data MSG_ID_ALARM_CONDITION_CLEARED = 0x3F # Broadcast that the alarm condition has been cleared MSG_ID_UI_ALARM_USER_ACTION = 0x40 # UI user has requested an alarm action @@ -99,13 +99,17 @@ MSG_ID_UI_SET_ALARM_AUDIO_VOLUME_LEVEL_CMD = 0x4E # UI command to set alarm audio volume level MSG_ID_UI_PRE_TREATMENT_UF_REQUEST = 0x4F # UI UF Initialization Request MSG_ID_HD_PRE_TREATMENT_UF_RESPONSE = 0x50 # HD response to user request to adjust the ultrafiltration in pre-treatment + MSG_ID_DG_COMMAND_RESPONSE = 0x51 # DG response to command from HD + MSG_ID_UI_RINSEBACK_CMD = 0x52 # UI rinseback request MSG_ID_HD_RINSEBACK_CMD_RESPONSE = 0x53 # HD rinseback request response + MSG_ID_UI_RECIRC_CMD = 0x54 # UI re-circ request MSG_ID_HD_RECIRC_CMD_RESPONSE = 0x55 # HD re-circ request response MSG_ID_HD_RINSEBACK_PROGRESS = 0x56 # HD broadcast of rinseback progress - MSG_ID_HD_RECIRCULATE_PROGRESS = 0x5A # HD broadcast of recirculate progress - MSG_ID_HD_BLOOD_PRIME_PROGRESS = 0x59 # HD broadcast of blood prime progress MSG_ID_UI_TX_END_CMD = 0x57 # UI end treatment sub-mode user request MSG_ID_HD_TX_END_CMD_RESPONSE = 0x58 # HD end treatment sub-mode user request response + MSG_ID_HD_BLOOD_PRIME_PROGRESS = 0x59 # HD broadcast of blood prime progress + MSG_ID_HD_RECIRC_PROGRESS = 0x5A # HD broadcast of treatment re-circulate progress + MSG_ID_DG_CHANGE_VALVE_SETTING_CMD = 0x5B # HD request to DG to change valve setting MSG_ID_CAN_ERROR_COUNT = 0x999 # test code in support of EMC testing @@ -123,7 +127,7 @@ MSG_ID_BLOOD_PUMP_MC_MEAS_SPEED_OVERRIDE = 0x800A # Blood pump motor controller speed override request MSG_ID_BLOOD_PUMP_MC_MEAS_CURR_OVERRIDE = 0x800B # Blood pump motor controller current override request MSG_ID_BLOOD_FLOW_SEND_INTERVAL_OVERRIDE = 0x800C # Blood flow broadcast interval override request - MSG_ID___AVAILABLE_1 = 0x800D # This msg ID is available for use + MSG_ID_TREATMENT_TIME_REMAINING_OVERRIDE = 0x800D # This msg ID is available for use MSG_ID_BLOOD_PUMP_MEAS_SPEED_OVERRIDE = 0x800E # Blood pump measured motor speed override request MSG_ID_BLOOD_PUMP_MEAS_ROTOR_SPEED_OVERRIDE = 0x800F # Blood pump measured rotor speed override request MSG_ID_DIAL_IN_FLOW_SET_PT_OVERRIDE = 0x8010 # Dialysate inlet flow set point override request @@ -171,6 +175,16 @@ MSG_ID_SUPER_CLEAR_ALARMS_CMD = 0x803A # Clears all alarms (even if non-recoverable or fault) MSG_ID_HD_REQUEST_CALIBRATION_DATA = 0x803B # Requests calibration data from HD MSG_ID_HD_ERASE_CALIBRATION_DATA = 0x803C # Requests calibration data on HD be erased + MSG_ID_HD_SET_CALIBRATION_RECORD = 0x803D # HD set calibration record that is received from Dialin + MSG_ID_HD_GET_CALIBRATION_RECORD = 0x803E # HD get calibration record that is requested from Dialin + MSG_ID_HD_SEND_CALIBRATION_RECORD = 0x803F # HD send calibration record to CAN bus to be received in Dialin (equivalent to publish) + MSG_ID_HD_SET_SYSTEM_RECORD = 0x8040 # HD set system record that is received from Dialin + MSG_ID_HD_GET_SYSTEM_RECORD = 0x8041 # HD get system record that is requested from Dialin + MSG_ID_HD_SEND_SYSTEM_RECORD = 0x8042 # HD send system record to CAN bus to be received in Dialin (equivalent to publish) + MSG_ID_HD_GET_SERVICE_RECORD = 0x8043 # HD get service record that is requested from Dialin + MSG_ID_HD_SET_SERVICE_RECORD = 0x8044 # HD set service record that is received from Dialin + MSG_ID_HD_SEND_SERVICE_RECORD = 0x8045 # HD send service record to CAN bus to be received in Dialin (equivalent to publish) + MSG_ID_HD_SET_OP_MODE_REQUEST = 0x8046 # HD set operation mode request MSG_ID_DG_TESTER_LOGIN_REQUEST = 0XA000 # DG tester log-in MSG_ID_DG_ALARM_STATE_OVERRIDE = 0xA001 # DG alarm state override message ID Index: dialin/hd/hemodialysis_device.py =================================================================== diff -u -r0cab9b7a747d7e2dfc36698ea2481b62971ec786 -r0a5edee793018705c54562d73a9a1d5ee648cb41 --- dialin/hd/hemodialysis_device.py (.../hemodialysis_device.py) (revision 0cab9b7a747d7e2dfc36698ea2481b62971ec786) +++ dialin/hd/hemodialysis_device.py (.../hemodialysis_device.py) (revision 0a5edee793018705c54562d73a9a1d5ee648cb41) @@ -51,8 +51,7 @@ HD_OP_MODE_SERVICE = 1 HD_OP_MODE_INIT_POST = 2 HD_OP_MODE_STANDBY = 3 - HD_OP_MODE_PRESCRIPTION = 4 - HD_OP_MODE_OP_PARAMS = 5 + HD_OP_MODE_TREATMENT_PARAMS = 4 HD_OP_MODE_PRE_TREATMENT = 6 HD_OP_MODE_TREATMENT = 7 HD_OP_MODE_POST_TREATMENT = 8 @@ -278,6 +277,48 @@ self.logger.debug("Timeout!!!!") return False + def cmd_hd_set_operation_mode(self, newMode=0): + """ + Constructs and sends a set operation mode request command via CAN bus. + Constraints: + Must be logged into HD. + Transition from current to requested op mode must be legal. + + @param newMode: ID of operation mode to transition to + HD_OP_MODE_FAULT = 0 + HD_OP_MODE_SERVICE = 1 + HD_OP_MODE_INIT_POST = 2 + HD_OP_MODE_STANDBY = 3 + HD_OP_MODE_TREATMENT_PARAMS = 4 + HD_OP_MODE_PRE_TREATMENT = 6 + HD_OP_MODE_TREATMENT = 7 + HD_OP_MODE_POST_TREATMENT = 8 + + @return: 1 if successful, zero otherwise + + """ + + payload = integer_to_bytearray(newMode) + + message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_hd_ch_id, + message_id=MsgIds.MSG_ID_HD_SET_OP_MODE_REQUEST.value, + payload=payload) + + self.logger.debug("Requesting HD mode change to " + str(newMode)) + + # Send message + received_message = self.can_interface.send(message) + + if received_message is not None: + if received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] == 1: + self.logger.debug("Success: Mode change accepted") + else: + self.logger.debug("Failure: Mode change rejected.") + return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] + else: + self.logger.debug("HD mode change request Timeout!!!!") + return False + def cmd_hd_safety_shutdown_override(self, active=True, reset=NO_RESET): """ Constructs and sends an HD safety shutdown override command via CAN bus. Index: dialin/hd/ui_proxy.py =================================================================== diff -u -r08a4b1100acd24702f1e8e6355c154aaef41f6d2 -r0a5edee793018705c54562d73a9a1d5ee648cb41 --- dialin/hd/ui_proxy.py (.../ui_proxy.py) (revision 08a4b1100acd24702f1e8e6355c154aaef41f6d2) +++ dialin/hd/ui_proxy.py (.../ui_proxy.py) (revision 0a5edee793018705c54562d73a9a1d5ee648cb41) @@ -182,7 +182,7 @@ self._handler_treatment_param_settings_response) self.can_interface.register_receiving_publication_function(DenaliChannels.hd_to_ui_ch_id, MsgIds.MSG_ID_USER_SALINE_BOLUS_RESPONSE.value, self._handler_saline_bolus_response) - self.can_interface.register_receiving_publication_function(DenaliChannels.ui_to_hd_ch_id, MsgIds.MSG_ID_UI_SET_UF_VOLUME_PARAMETER.value, + self.can_interface.register_receiving_publication_function(DenaliChannels.ui_to_hd_ch_id, MsgIds.MSG_ID_UI_PRE_TREATMENT_UF_REQUEST.value, self._handler_uf_volume_setting_response) self.can_interface.register_receiving_publication_function(DenaliChannels.hd_to_ui_ch_id, MsgIds.MSG_ID_HD_RINSEBACK_CMD_RESPONSE.value, self._handler_rinseback_cmd_response) Index: dialin/ui/hd_simulator.py =================================================================== diff -u -r3cfd47dcddb9ca34212ed9b7d29a76124c23044c -r0a5edee793018705c54562d73a9a1d5ee648cb41 --- dialin/ui/hd_simulator.py (.../hd_simulator.py) (revision 3cfd47dcddb9ca34212ed9b7d29a76124c23044c) +++ dialin/ui/hd_simulator.py (.../hd_simulator.py) (revision 0a5edee793018705c54562d73a9a1d5ee648cb41) @@ -21,14 +21,14 @@ import subprocess from . import utils, messageBuilder -from .hd_simulator_alarms import HDProxyAlarms +from .hd_simulator_alarms import HDAlarmsSimulator from ..common.msg_defs import RequestRejectReasons, MsgIds from ..common.hd_defs import HDDefs from ..protocols.CAN import (DenaliMessage, 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,69 @@ 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 + TREATMENT_START_STATE = 0 + TREATMENT_BLOOD_PRIME_STATE = 1 + TREATMENT_DIALYSIS_STATE = 2 + TREATMENT_STOP_STATE = 3 + TREATMENT_RINSEBACK_STATE = 4 + TREATMENT_RECIRC_STATE = 5 + TREATMENT_END_STATE = 6 # 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 +195,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: @@ -185,10 +224,16 @@ self.can_interface.register_receiving_publication_function(channel_id, MsgIds.MSG_ID_UI_USER_CONFIRM_TREATMENT_PARAMS.value, self._handler_ui_confirm_treatment) - self.alarms_simulator = HDProxyAlarms(self.can_interface, self.logger) + self.can_interface.register_receiving_publication_function(channel_id, + MsgIds.MSG_ID_UI_TREATMENT_END_REQUEST.value, + self._handler_ui_end_treatment) + self.alarms_simulator = HDAlarmsSimulator(self.can_interface, self.logger) self.treatment_parameter_rejections = TreatmentParameterRejections() + def alarm(self) : + return self.alarms_simulator + def cmd_send_treatment_parameter_validation_response(self, rejections: List[RequestRejectReasons]): """ Sends a treatment parameter validation response @@ -352,31 +397,10 @@ uf_volume = struct.unpack('f', bytearray( message['message'][START_POS:END_POS]))[0] - print("Received UF Volume: {0} mL".format(uf_volume)) + self.logger.debug("Received UF Volume: {0} mL".format(uf_volume)) - self.cmd_send_acknowledge(message) self.cmd_send_uf_treatment_response(1, 0, uf_volume) - def cmd_send_acknowledge(self, message: dict): - """ - Sends a generic acknowledge - - @param message: (dict) The message that was sent we need to ACK - @return: None - """ - seq = struct.unpack('h', bytearray( - message['message'][DenaliMessage.MSG_SEQ_INDEX:DenaliMessage.MSG_ID_INDEX]))[0] - - # send back empty payload since this is an ACK - payload = bytearray() - - message = DenaliMessage.build_message(channel_id=DenaliChannels.hd_to_ui_ch_id, - message_id=MsgIds.MSG_ID_ACK_MESSAGE_THAT_REQUIRES_ACK.value, - payload=payload, - seq=-seq) - - self.can_interface.send(message, 0) - def _handler_ui_start_treatment(self, message): """ Handler function to start a treatment @@ -706,13 +730,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 @@ -721,6 +745,7 @@ :param vMCSpd: (float) MC Speed :param vMCCurr: (float) MC Current :param vPWM: (float) PWM + :param vSigStrength: (float) Signal strength in percent :return: None """ @@ -731,20 +756,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 @@ -753,6 +779,7 @@ :param vMCSpd: (float) MC Speed :param vMCCurr: (float) MC Current :param vPWM: (float) PWM + :param vSigStrength: (float) Signal strength in percent :return: None """ @@ -763,6 +790,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, @@ -864,6 +892,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): """ @@ -1267,23 +1319,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, @@ -1424,7 +1502,7 @@ payload = float_to_bytearray(vCumulative) message = DenaliMessage.build_message(channel_id=DenaliChannels.hd_sync_broadcast_ch_id, - message_id=MsgIds.MSG_ID_HD_HEPARIN_DATA.value, + message_id=MsgIds.MSG_ID_HD_HEPARIN_DATA_BROADCAST.value, payload=payload) self.can_interface.send(message, 0) @@ -1481,3 +1559,287 @@ payload=payload) 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) Index: version.py =================================================================== diff -u -r812bbf1e5b3b2f1c4f5cfbef1264787e18afb5c3 -r0a5edee793018705c54562d73a9a1d5ee648cb41 --- version.py (.../version.py) (revision 812bbf1e5b3b2f1c4f5cfbef1264787e18afb5c3) +++ version.py (.../version.py) (revision 0a5edee793018705c54562d73a9a1d5ee648cb41) @@ -1,69 +1 @@ -########################################################################### -# -# Copyright (c) 2019-2020 Diality Inc. - All Rights Reserved. -# -# THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN -# WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. -# -# @file version.py -# -# @author (last) Peter Lucia -# @date (last) 10-Nov-2020 -# @author (original) Peter Lucia -# @date (original) 16-Jun-2020 -# -############################################################################ -import subprocess - -VERSION = "0.8.1" - - -def get_branch(): - """ - Gets the current branch name in the current git repository - - @return: The current branch name, None if it can't be determined - """ - - try: - return subprocess.check_output("git rev-parse --abbrev-ref HEAD", shell=True).decode("utf-8").strip() - except subprocess.CalledProcessError: - return None - - -def get_last_commit(): - """ - Gets the latest commit in the current git repository - - @return: (str) the latest commit in the current git repository, None if it can't be determined - """ - try: - return subprocess.check_output("git rev-parse --short=7 HEAD", shell=True).decode("utf-8").strip() - except subprocess.CalledProcessError: - return None - - -def check_if_git_repo(): - """ - Checks if we're in a git repo or not to know if we can get the git branch and commit - - @return: True if in a git repo, False otherwise - """ - - return subprocess.call(["git", "branch"], stderr=subprocess.DEVNULL, stdout=subprocess.DEVNULL) == 0 - - -branch = None -commit = None - -DEV_VERSION = VERSION - -if check_if_git_repo(): - branch = get_branch() - commit = get_last_commit() - DEV_VERSION += "-{0}".format(branch) - DEV_VERSION += "-{0}".format(commit) - - -if __name__ == '__main__': - print(VERSION) +dialin/version.py \ No newline at end of file