Index: dialin/common/hd_defs.py =================================================================== diff -u -r4c196bf0092414737023812b5bda5defab3f5ba4 -rd78c6ab981079603365e5b62fac433183aa3e03a --- dialin/common/hd_defs.py (.../hd_defs.py) (revision 4c196bf0092414737023812b5bda5defab3f5ba4) +++ dialin/common/hd_defs.py (.../hd_defs.py) (revision d78c6ab981079603365e5b62fac433183aa3e03a) @@ -249,17 +249,18 @@ @unique class PreTreatmentDrySelfTestsStates(DialinEnum): - DRY_SELF_TESTS_START_STATE = 0 # Dry self-tests starting state - DRY_SELF_TESTS_WAIT_FOR_DOOR_CLOSE_STATE = 1 # Wait for door to close before executing self-tests - DRY_SELF_TESTS_USED_CARTRIDGE_CHECK_STATE = 2 # Used cartridge check dry self-test state - DRY_SELF_TESTS_OCCLUSION_SENSORS_STATE = 3 # Occlusion sensors dry self-test state - DRY_SELF_TESTS_PRESSURE_SENSORS_SETUP_STATE = 4 # Pressure sensors dry self-test setup valves and pump state - DRY_SELF_TESTS_PRESSURE_SENSORS_STATE = 5 # Pressure sensors verify pressure readings state - DRY_SELF_TESTS_PRESSURE_SENSORS_NORMAL_STATE = 6 # Pressure sensors verify normal pressure readings state - DRY_SELF_TESTS_SYRINGE_PUMP_PRIME_STATE = 7 # Prime syringe pump state - DRY_SELF_TESTS_STOPPED_STATE = 8 # Dry self-test stopped state - DRY_SELF_TESTS_COMPLETE_STATE = 9 # Dry self-test complete state - NUM_OF_DRY_SELF_TESTS_STATES = 10 # Number of dry self-tests states + DRY_SELF_TESTS_START_STATE = 0 # Dry self-tests starting state + DRY_SELF_TESTS_WAIT_FOR_DOOR_CLOSE_STATE = 1 # Wait for door to close before executing self-tests + DRY_SELF_TESTS_USED_CARTRIDGE_CHECK_STATE = 2 # Used cartridge check dry self-test state + DRY_SELF_TESTS_OCCLUSION_SENSORS_STATE = 3 # Occlusion sensors dry self-test state + DRY_SELF_TESTS_PRESSURE_SENSORS_SETUP_STATE = 4 # Pressure sensors dry self-test setup valves and pump state + DRY_SELF_TESTS_PRESSURE_SENSORS_STATE = 5 # Pressure sensors verify pressure readings state + DRY_SELF_TESTS_PRESSURE_SENSORS_NORMAL_STATE = 6 # Pressure sensors verify normal pressure readings state + DRY_SELF_TESTS_SYRINGE_PUMP_PRIME_STATE = 7 # Prime syringe pump state + DRY_SELF_TESTS_SYRINGE_PUMP_OCCLUSION_DETECTION_STATE = 8 # Occlusion detection state + DRY_SELF_TESTS_STOPPED_STATE = 9 # Dry self-test stopped state + DRY_SELF_TESTS_COMPLETE_STATE = 10 # Dry self-test complete state + NUM_OF_DRY_SELF_TESTS_STATES = 11 # Number of dry self-tests states @unique @@ -276,8 +277,8 @@ HD_PRIME_RESERVOIR_TWO_FILL_COMPLETE_STATE = 9 # Wait for reservoir 2 fill complete HD_PRIME_DIALYSATE_BYPASS_STATE = 10 # Dialysate bypass fluid path state HD_PRIME_WET_SELF_TESTS_STATE = 11 # Perform wet self-tests after priming complete - HD_PRIME_PAUSE = 12 # Prime pause state = waits to be resumed - HD_PRIME_COMPLETE = 13 # Prime complete state + HD_PRIME_PAUSE_STATE = 12 # Prime pause state = waits to be resumed + HD_PRIME_COMPLETE_STATE = 13 # Prime complete state NUM_OF_HD_PRIME_STATES = 14 # Number of prime sub-mode states Index: dialin/common/msg_ids.py =================================================================== diff -u -r197d6e71147426b2c0a7e37bbaf7469a96a75e95 -rd78c6ab981079603365e5b62fac433183aa3e03a --- dialin/common/msg_ids.py (.../msg_ids.py) (revision 197d6e71147426b2c0a7e37bbaf7469a96a75e95) +++ dialin/common/msg_ids.py (.../msg_ids.py) (revision d78c6ab981079603365e5b62fac433183aa3e03a) @@ -328,6 +328,7 @@ MSG_ID_LOAD_CELL_OVERRIDE = 0xA005 MSG_ID_PRESSURE_OVERRIDE = 0xA006 MSG_ID_PRESSURE_SEND_INTERVAL_OVERRIDE = 0xA007 + MSG_ID_DG_HD_COMMUNICATION_STATUS_OVERRIDE = 0xA008 MSG_ID_RO_MEASURED_FLOW_OVERRIDE = 0xA009 MSG_ID_RO_PUMP_SEND_INTERVAL_OVERRIDE = 0xA00A MSG_ID_DRAIN_PUMP_SET_RPM = 0xA00B @@ -396,8 +397,8 @@ MSG_ID_DG_SET_SW_CONFIG_RECORD = 0xA04B MSG_ID_DG_SEND_SW_CONFIG_RECORD = 0xA04C MSG_ID_DG_FANS_DUTY_CYCLE_OVERRIDE = 0xA04D - MSG_ID_DG_HD_COMMUNICATION_STATUS_OVERRIDE = 0xA04E + MSG_ID_HD_DEBUG_EVENT = 0xFFF1 MSG_ID_DG_DEBUG_EVENT = 0xFFF2 MSG_ID_ACK_MESSAGE_THAT_REQUIRES_ACK = 0xFFFF Index: dialin/dg/hd_proxy.py =================================================================== diff -u -r432896b385b825d693619b761f4d3e1fa38999a5 -rd78c6ab981079603365e5b62fac433183aa3e03a --- dialin/dg/hd_proxy.py (.../hd_proxy.py) (revision 432896b385b825d693619b761f4d3e1fa38999a5) +++ dialin/dg/hd_proxy.py (.../hd_proxy.py) (revision d78c6ab981079603365e5b62fac433183aa3e03a) @@ -335,20 +335,19 @@ self.logger.debug("Timeout!!!!") return False - def cmd_hd_communication_status_override(self, reset: int = NO_RESET) -> int: + def cmd_hd_communication_status_override(self, status: bool, reset: int = NO_RESET) -> int: """ Constructs and sends the HD communication status override command. Constraints: Must be logged into DG. - Method only sets HD Communication status to True on NO_RESET. Therefore, when this message - is called when the HD and DG are communicating, there will be no noticeable effect. - - @param reset: integer - 1 to reset a previous override, 0 to override - @return: 1 if successful, zero otherwise + @param reset: (int) - 1 to reset a previous override, 0 to override + @param status: (int) - HD status communication. 0 for no comm, 1 for comm + @return: (int) 1 if successful, zero otherwise """ - reset_byte_array = integer_to_bytearray(reset) - payload = reset_byte_array + reset = integer_to_bytearray(reset) + hd_status = integer_to_bytearray(status) + payload = reset + hd_status message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_dg_ch_id, message_id=MsgIds.MSG_ID_DG_HD_COMMUNICATION_STATUS_OVERRIDE.value, Index: dialin/hd/post_treatment.py =================================================================== diff -u -r39a6a491a48545b1dd6c39a72a13d8ca55f941cf -rd78c6ab981079603365e5b62fac433183aa3e03a --- dialin/hd/post_treatment.py (.../post_treatment.py) (revision 39a6a491a48545b1dd6c39a72a13d8ca55f941cf) +++ dialin/hd/post_treatment.py (.../post_treatment.py) (revision d78c6ab981079603365e5b62fac433183aa3e03a) @@ -19,13 +19,11 @@ from ..common.msg_defs import MsgIds, MsgFieldPositions from ..protocols.CAN import DenaliChannels from ..utils.base import AbstractSubSystem, publish +from ..utils.conversions import bytearray_to_integer - class HDPostTreatment(AbstractSubSystem): """ - Hemodialysis Delivery (HD) Dialin API sub-class for post treatment related commands. - """ def __init__(self, can_interface, logger: Logger): @@ -46,7 +44,7 @@ def get_post_treatment_sub_mode(self) -> int: """ - Returns post treatment submode (in int) + @return: (int) post treatment submode """ return self.post_treatment_sub_mode @@ -55,8 +53,12 @@ """ Handles published post treatment sub mode data messages. Sub mode data is also captured for reference. - @param message: published post treatment sub mode broadcast message + @param message: published post treatment sub mode broadcast message + U32 sub-mode + @return: none """ - self.post_treatment_sub_mode = struct.unpack(' None: + """ + A simulated DG broadcast message of conductivity data. + @param ro_rejection_ratio: (float) RO Pump rejection ratio + @param cpi_conductivity: (float) CPi conductivity + @param cpo_conductivity: (float) CPo conductivity + @param cd1_conductivity: (float) CD1 conductivity + @param cd2_conductivity: (float) CD2 conductivity + @return: None + """ + payload = float_to_bytearray(ro_rejection_ratio) + payload += float_to_bytearray(cpi_conductivity) + payload += float_to_bytearray(cpo_conductivity) + payload += float_to_bytearray(cd1_conductivity) + payload += float_to_bytearray(cd2_conductivity) + + message = DenaliMessage.build_message(channel_id=DenaliChannels.dg_sync_broadcast_ch_id, + message_id=MsgIds.MSG_ID_DG_CONDUCTIVITY_DATA.value, + payload=payload) + + self.can_interface.send(message, 0) Index: dialin/ui/hd_simulator.py =================================================================== diff -u -r5774d8c42cd71211a5b62ed54e60d490bcb90cad -rd78c6ab981079603365e5b62fac433183aa3e03a --- dialin/ui/hd_simulator.py (.../hd_simulator.py) (revision 5774d8c42cd71211a5b62ed54e60d490bcb90cad) +++ dialin/ui/hd_simulator.py (.../hd_simulator.py) (revision d78c6ab981079603365e5b62fac433183aa3e03a) @@ -997,7 +997,7 @@ self.can_interface.send(message, 0) - def cmd_set_treatment_states_data(self, sub_mode: int, uf_state: int, saline_state: int, heparing_state: int, + def cmd_set_treatment_states_data(self, sub_mode: int, uf_state: int, saline_state: int, heparin_state: int, rinseback_state: int, recirculate_state: int, blood_prime_state: int, treatment_end_state: int, treatment_stop_state: int, dialysis_state: int) -> None: """ @@ -1014,26 +1014,30 @@ |:--: |:--: ||| | \ref Data::mRinsebackState | \ref Data::mRecirculateState ||| |||| - | #7:(U32) | #8:(U32) | #9:(U32) || - |:--: |:--: |:--: || - | \ref Data::vBloodPrimeState | \ref Data::mTreatmentEndState | \ref Data::vTreammentStopState || + | #7:(U32) | #8:(U32) | #9:(U32) | + |:--: |:--: |:--: | + | \ref Data::vBloodPrimeState | \ref Data::mTreatmentEndState | \ref Data::mTreammentStopState | + | #9:(U32) || + |:--: || + | \ref Data::mDialysisState || @param sub_mode: (int) Sub-Mode @param uf_state: (int) UF State @param saline_state: (int) Saline Bolus State - @param heparing_state: (int) Saline Bolus State + @param heparin_state: (int) Saline Bolus State @param rinseback_state: (int) Rinseback State @param recirculate_state: (int) Recirculate State @param blood_prime_state: (int) Blood Prime State @param treatment_end_state: (int) Treatment End State - @param treamment_stop_state: (int) Treatment Stop State + @param treatment_stop_state: (int) Treatment Stop State + @param dialysis_state: (int) Dialysis State @return: none """ payload = integer_to_bytearray(sub_mode) payload += integer_to_bytearray(uf_state) payload += integer_to_bytearray(saline_state) - payload += integer_to_bytearray(heparing_state) + payload += integer_to_bytearray(heparin_state) payload += integer_to_bytearray(rinseback_state) payload += integer_to_bytearray(recirculate_state) payload += integer_to_bytearray(blood_prime_state) @@ -1105,12 +1109,12 @@ self.can_interface.send(message, 0) - def cmd_set_saline_bolus_response(self, accepted: int, reason: int, target: int, state: int) -> None: + def cmd_set_saline_bolus_response(self, accepted: int, reason: int, target: int) -> None: """ 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 | + | MSG | CAN ID | M.Box | Type | Ack | Src | Dest | Description | #1:(U32) | #2:(U32) | #3:(U32) | + |:---:|:------:|:-----:|:----:|:---:|:---:|:----:|:---------------------:|:--------------------:|:-------------------:|:-------------------:| + | 20 | 0x020 | 6 | Rsp | Y | HD | UI | Saline Bolus Response | \ref Data::mAccepted | \ref Data::mReason | \ref Data::mTarget | @param accepted: (int) boolean accept/reject response @param reason: (int) rejection reason @@ -1177,16 +1181,15 @@ self.can_interface.send(message, 0) - def cmd_set_heparin_pause_resume_response(self, accepted: int, reason: int, state: int) -> None: + def cmd_set_heparin_pause_resume_response(self, accepted: int, reason: int) -> None: """ the Heparin Response message setter/sender method - | MSG | CAN ID | M.Box | Type | Ack | Src | Dest | Description | #1:(U32) | #2:(U32) | #3:(U32) | - |:----:|:------:|:-----:|:----:|:---:|:---:|:----:|:----------------:|:--------------------:|:-------------------:|:-------------------:| - |0x4C00| 0x020 | 6 | Rsp | Y | HD | UI | Heparin Response | \ref Data::mAccepted | \ref Data::mReason | \ref Data::mState | + | MSG | CAN ID | M.Box | Type | Ack | Src | Dest | Description | #1:(U32) | #2:(U32) | + |:----:|:------:|:-----:|:----:|:---:|:---:|:----:|:----------------:|:--------------------:|:-------------------:| + |0x4C00| 0x020 | 6 | Rsp | Y | HD | UI | Heparin Response | \ref Data::mAccepted | \ref Data::mReason | @param accepted: (int) boolean accept/reject response @param reason: (int) rejection reason - @param state: (int) Heparin current State @return: none """ payload = integer_to_bytearray(accepted) @@ -1251,20 +1254,20 @@ self.can_interface.send(message, 0) def cmd_send_treatment_rinseback_data(self, target_vol: float, current_vol: float, flow_rate: int, timeout: int, - timeout_countdown: int, is_completed: int) -> None: + timeout_countdown: int, is_completed: bool) -> None: """ 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) | #5:(U32) | - |:----:|:------:|:---:|:------:|:---:|:---:|:---:|:-----------: |:--: |:--: |:--: |:--: |:--: |:--: | + | MSG | CAN ID | Box | Type | Ack | Src | Dst | Description | #1:(F32) | #2:(F32) | #3:(U32) | #4:(U32) | #5:(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 | \ref Data::is_completed | - :param target_vol : (float) the target volume in mL - :param current_vol : (float) the current volume in mL - :param flow_rate : (uint ) the current flow rate in mL/min - :param timeout : (uint ) Total Timeout - :param timeout_countdown : (uint ) Current Timeout count down - :param is_completed : (bool ) Is Rinseback completed. - :return: None + @param target_vol : (float) the target volume in mL + @param current_vol : (float) the current volume in mL + @param flow_rate : (uint ) the current flow rate in mL/min + @param timeout : (uint ) Total Timeout + @param timeout_countdown : (uint ) Current Timeout count down + @param is_completed : (bool ) Is Rinseback completed. + @return: None """ payload = float_to_bytearray(target_vol) @@ -1462,14 +1465,15 @@ fpga_id: int, fpga_major: int, fpga_minor: int, fpga_lab: int, compatibility_rev: int) -> None: """ the hd version response message method - @param major: integer - Major version number - @param minor: integer - Minor version number - @param micro: integer - Micro version number - @param build: integer - Build version number - @param fpga_id: integer - FPGA id version number - @param fpga_major: integer - FPGA Major version number - @param fpga_minor: integer - FPGA Minor version number - @param fpga_lab: integer - FPGA Lab version number + @param major: (integer) - Major version number + @param minor: (integer) - Minor version number + @param micro: (integer) - Micro version number + @param build: (integer) - Build version number + @param fpga_id: (integer) - FPGA id version number + @param fpga_major: (integer) - FPGA Major version number + @param fpga_minor: (integer) - FPGA Minor version number + @param fpga_lab: (integer) - FPGA Lab version number + @param compatibility_rev: (integer) - Compatibility revision @return: None """ @@ -2042,3 +2046,74 @@ "Build: {3} " "Compat: {4} " .format(ui_major, ui_minor, ui_micro, ui_build, ui_compatibility)) + + def cmd_send_hd_blood_leak_data(self, blood_leak_status: int, blood_leak_state: int, + blood_leak_zero_status_counter: int, blood_leak_counter: int, + blood_leak_zeroed_status: int, blood_leak_detect_set_point: int, + blood_leak_detect_level: int, blood_leak_st_count: int, + blood_leak_led_intensity: int, blood_leak_register_counter: int) -> None: + """ + A simulated HD broadcast message of blood leak data. + @param blood_leak_status: (int) Blood leak status + @param blood_leak_state: (int) Blood leak state + @param blood_leak_zero_status_counter: (int) Blood leak zero status counter + @param blood_leak_counter: (int) Blood leak counter + @param blood_leak_zeroed_status: (int) Blood leak zeroed status + @param blood_leak_detect_set_point: (int) Blood leak detect set point + @param blood_leak_detect_level: (int) Blood leak detect level + @param blood_leak_st_count: (int) Blood leak st count + @param blood_leak_led_intensity: (int) Blood leak LED intensity + @param blood_leak_register_counter: (int) Blood leak register counter + @return: None + """ + + payload = unsigned_to_bytearray(blood_leak_status) + payload += unsigned_to_bytearray(blood_leak_state) + payload += unsigned_to_bytearray(blood_leak_zero_status_counter) + payload += unsigned_to_bytearray(blood_leak_counter) + payload += unsigned_to_bytearray(blood_leak_zeroed_status) + payload += unsigned_to_bytearray(blood_leak_detect_set_point) + payload += unsigned_to_bytearray(blood_leak_detect_level) + payload += unsigned_to_bytearray(blood_leak_st_count) + payload += unsigned_to_bytearray(blood_leak_led_intensity) + payload += unsigned_to_bytearray(blood_leak_register_counter) + + message = DenaliMessage.build_message(channel_id=DenaliChannels.hd_sync_broadcast_ch_id, + message_id=MsgIds.MSG_ID_HD_BLOOD_LEAK_DATA.value, + payload=payload) + + self.can_interface.send(message, 0) + + def cmd_send_hd_air_trap_data(self, lower_level: int, upper_level: int) -> None: + """ + A simulated HD broadcast message of air trap data. + @param lower_level: (int) Air trap lower level + @param upper_level: (int) Air trap upper level + @return: None + """ + + payload = unsigned_to_bytearray(lower_level) + payload += unsigned_to_bytearray(upper_level) + + message = DenaliMessage.build_message(channel_id=DenaliChannels.hd_sync_broadcast_ch_id, + message_id=MsgIds.MSG_ID_HD_AIR_TRAP_DATA.value, + payload=payload) + + self.can_interface.send(message, 0) + + def cmd_send_hd_air_bubble_data(self, venous_air_bubble_status: int, venous_air_bubble_state: int) -> None: + """ + A simulated HD broadcast message of air bubble data. + @param venous_air_bubble_status: (int) Venous air bubble status + @param venous_air_bubble_state: (int) Venous air bubble state + @return: None + """ + + payload = unsigned_to_bytearray(venous_air_bubble_status) + payload += unsigned_to_bytearray(venous_air_bubble_state) + + message = DenaliMessage.build_message(channel_id=DenaliChannels.hd_sync_broadcast_ch_id, + message_id=MsgIds.MSG_ID_HD_BUBBLES_DATA.value, + payload=payload) + + self.can_interface.send(message, 0)