Index: leahi_dialin/ui/td_messaging.py =================================================================== diff -u -r78a66378ef0f284406cfcf12085a2c23e224ac05 -r38ac866ee708b59f6ae0078604a60a48d9e7e996 --- leahi_dialin/ui/td_messaging.py (.../td_messaging.py) (revision 78a66378ef0f284406cfcf12085a2c23e224ac05) +++ leahi_dialin/ui/td_messaging.py (.../td_messaging.py) (revision 38ac866ee708b59f6ae0078604a60a48d9e7e996) @@ -1,9 +1,10 @@ #!/bin/python3 -from dialin.ui.utils import singleton_threadsafe -from dialin.utils import conversions -from dialin.protocols import CAN -from dialin.common import msg_ids +# Adjusting the dialin folder for the new leahi_dialin. +from leahi_dialin.ui.utils import singleton_threadsafe +from leahi_dialin.utils import conversions +from leahi_dialin.protocols import CAN +from leahi_dialin.common import msg_ids @singleton_threadsafe @@ -32,23 +33,427 @@ def td_operation_mode(self, op_mode: int, sub_mode: int = 0): + """Broadcasts the current TD operation mode + Args: + op_mode (int ): operation mode + sub_mode (int, optional ): operation sub-mode. Defaults to 0. + """ + if not self.can_enabled: + raise ValueError("CAN Interface is not enabled") + + + payload = conversions.integer_to_bytearray(op_mode ) + payload += conversions.integer_to_bytearray(sub_mode) + + message = CAN.DenaliMessage.build_message( + channel_id=CAN.DenaliChannels.td_sync_broadcast_ch_id, + message_id=msg_ids.MsgIds.MSG_ID_TD_OP_MODE_DATA.value, + payload=payload) + + self.can_interface.send(message, 0) + + def td_temperatures(self, board_temp: float): + """ + Broadcasts the current TD Temperatures Data + @param board_temp : TD Board temperature + @return: None + """ + # TODO: replace with proper payload and message ID once message is defined + if not self.can_enabled: + raise ValueError("CAN Interface is not enabled") + + payload = conversions.float_to_bytearray(board_temp) + + message = CAN.DenaliMessage.build_message( + channel_id=CAN.DenaliChannels.td_sync_broadcast_ch_id, + message_id=msg_ids.MsgIds.MSG_ID_TD_TEMPERATURE_DATA.value, + payload=payload) + + self.can_interface.send(message, 0) + + def td_blood_pump(self, set_flow: int, meas_flow: float, rot_speed: float, mot_speed: float, curr_motor: float, set_rpm: float, rot_count: int, pres_flow: int, rot_hall_state: int): + """ + Broadcasts the current TD Blood Pump Data + @param set_flow : set flow rate + @param meas_flow : meaured speed + @param rot_speed : measured rotor speed + @param mot_speed : measured blood pump speed + @param curr_motor : current motor + @param set_rpm : set rpm + @param pres_flow : pres_flow + @param rot_count : rotation count + @param rot_hall_state : rotor hall state + @return: None + """ + + if not self.can_enabled: + raise ValueError("CAN Interface is not enabled") + + + payload = conversions.integer_to_bytearray (set_flow ) + payload += conversions.float_to_bytearray (meas_flow ) + payload += conversions.float_to_bytearray (rot_speed ) + payload += conversions.float_to_bytearray (mot_speed ) + payload += conversions.float_to_bytearray (curr_motor ) + payload += conversions.float_to_bytearray (set_rpm ) + payload += conversions.unsigned_integer_to_bytearray(rot_count ) + payload += conversions.unsigned_integer_to_bytearray(pres_flow ) + payload += conversions.unsigned_integer_to_bytearray(rot_hall_state ) + + message = CAN.DenaliMessage.build_message( + channel_id=CAN.DenaliChannels.td_sync_broadcast_ch_id, + message_id=msg_ids.MsgIds.MSG_ID_TD_BLOOD_PUMP_DATA.value, + payload=payload) + + self.can_interface.send(message, 0) + + def td_air_trap(self, low_level: int, upper_level: int, lower_level_raw: int, upper_level_raw: int, valve_state: int, controlling: int): + """ + Broadcasts the current TD air trap data + @param low_level : lower level value + @param upper_level : upper level value + @param low_level_raw : lower level raw value + @param upper_level_raw : upper level raw value + @param valve_state : air valve state + @param controlling : air control + @return: None + """ + + if not self.can_enabled: + raise ValueError("CAN Interface is not enabled") + + + payload = conversions.unsigned_integer_to_bytearray(low_level ) + payload += conversions.unsigned_integer_to_bytearray(upper_level ) + payload += conversions.unsigned_integer_to_bytearray(lower_level_raw ) + payload += conversions.unsigned_integer_to_bytearray(upper_level_raw ) + payload += conversions.unsigned_integer_to_bytearray(valve_state ) + payload += conversions.unsigned_integer_to_bytearray(controlling ) + + message = CAN.DenaliMessage.build_message( + channel_id=CAN.DenaliChannels.td_sync_broadcast_ch_id, + message_id=msg_ids.MsgIds.MSG_ID_TD_AIR_TRAP_DATA.value, + payload=payload) + + self.can_interface.send(message, 0) + + def td_ejector(self, state: int, set_speed: float): + """ Broadcasts the current TD operation mode - @param op_mode : operation mode - @param sub_mode : operation sub-mode + @param state : ejector state + @param set_speed : ejector set speed @return: None """ + if not self.can_enabled: + raise ValueError("CAN Interface is not enabled") + + payload = conversions.integer_to_bytearray(state ) + payload += conversions.float_to_bytearray (set_speed) + + message = CAN.DenaliMessage.build_message( + channel_id=CAN.DenaliChannels.td_sync_broadcast_ch_id, + message_id=msg_ids.MsgIds.MSG_ID_TD_EJECTOR_DATA.value, + payload=payload) + + self.can_interface.send(message, 0) + + def td_switches(self, door: int): + """ + Broadcasts the current TD switch Data + @param door : door status + @return: None + """ if not self.can_enabled: raise ValueError("CAN Interface is not enabled") - payload = conversions.integer_to_bytearray(op_mode ) - payload += conversions.integer_to_bytearray(sub_mode) + payload = conversions.integer_to_bytearray(door ) message = CAN.DenaliMessage.build_message( channel_id=CAN.DenaliChannels.td_sync_broadcast_ch_id, - message_id=msg_ids.MsgIds.MSG_ID_TD_OP_MODE_DATA.value, + message_id=msg_ids.MsgIds.MSG_ID_TD_SWITCHES_DATA.value, payload=payload) self.can_interface.send(message, 0) + + def td_battery(self, capacity: int, ac_power: int): + """ + Broadcasts the current TD Battery Data + @param capacity : battery capacity + @param ac_power : a/c power status + @return: None + """ + # TODO: replace with proper payload and message ID once message is defined + if not self.can_enabled: + raise ValueError("CAN Interface is not enabled") + + + payload = conversions.integer_to_bytearray(capacity) + payload += conversions.integer_to_bytearray(ac_power) + + message = CAN.DenaliMessage.build_message( + channel_id=CAN.DenaliChannels.td_sync_broadcast_ch_id, + message_id=msg_ids.MsgIds.MSG_ID_TD_BATTERY_DATA.value, + payload=payload) + + self.can_interface.send(message, 0) + + def td_valves(self, valve_id: int, state: int, pos_name: int, pos_count: int, next_pos: int): + """ + Broadcasts the current TD Battery Data + @param valve_id : Valve ID + @param state : Valve State + @param pos_name : Position Name + @param pos_count : Position Count + @param next_pos : Next Position + @return: None + """ + + if not self.can_enabled: + raise ValueError("CAN Interface is not enabled") + + + payload = conversions.unsigned_integer_to_bytearray(valve_id ) + payload += conversions.unsigned_integer_to_bytearray(state ) + payload += conversions.unsigned_integer_to_bytearray(pos_name ) + payload += conversions.short_to_bytearray (pos_count ) + payload += conversions.short_to_bytearray (next_pos ) + + message = CAN.DenaliMessage.build_message( + channel_id=CAN.DenaliChannels.td_sync_broadcast_ch_id, + message_id=msg_ids.MsgIds.MSG_ID_TD_VALVES_DATA.value, + payload=payload) + + self.can_interface.send(message, 0) + + def td_voltages(self, line_1_2v: float, line_3_3v: float, line_logic_5v: float, + line_sensors_5v: float, line_24v: float, line_regen_24v: float, + fpga_adc_ref: float, res_ref: float, fpga_vcc: float, + fpga_vaux: float, fpga_vpvn: float): + """ + Broadcasts the current TD voltage data + @param line_1_2v : 1.2V line + @param line_3_3v : 3.3V line + @param line_logic_5v : Logic voltage (5V) + @param line_sensors_5v : Sensors voltage (5V) + @param line_24v : Actuators voltage (24V) + @param line_regen_24v : Actuators regen voltage (24V) + @param fpga_adc_ref : FPGA ADC reference voltage (1V) + @param res_ref : PBA ADC reference voltage (3V) + @param fpga_vcc : FPGA Vcc (3V) + @param fpga_vaux : FPGA Vaux (3V) + @param fpga_vpvn : FPGA Vpvn (1V) + @return: None + """ + + if not self.can_enabled: + raise ValueError("CAN Interface is not enabled") + + + payload = conversions.float_to_bytearray(line_1_2v ) + payload += conversions.float_to_bytearray(line_3_3v ) + payload += conversions.float_to_bytearray(line_logic_5v ) + payload += conversions.float_to_bytearray(line_sensors_5v ) + payload += conversions.float_to_bytearray(line_24v ) + payload += conversions.float_to_bytearray(line_regen_24v ) + payload += conversions.float_to_bytearray(fpga_adc_ref ) + payload += conversions.float_to_bytearray(res_ref ) + payload += conversions.float_to_bytearray(fpga_vcc ) + payload += conversions.float_to_bytearray(fpga_vaux ) + payload += conversions.float_to_bytearray(fpga_vpvn ) + + message = CAN.DenaliMessage.build_message( + channel_id=CAN.DenaliChannels.td_sync_broadcast_ch_id, + message_id=msg_ids.MsgIds.MSG_ID_TD_VOLTAGES_DATA.value, + payload=payload) + + self.can_interface.send(message, 0) + + def td_versions(self, major: int, minor: int, micro: int, build: int, + fpga_id: int, fpga_major: int, fpga_minor: int, fpga_lab: int, + compatibility_rev: int): + """ + Broadcasts the current TD Version Data + @param major: (uint) - Major version number + @param minor: (uint) - Minor version number + @param micro: (uint) - Micro version number + @param build: (uint) - Build version number + @param fpga_id: (int) - FPGA id version number + @param fpga_major: (int) - FPGA Major version number + @param fpga_minor: (int) - FPGA Minor version number + @param fpga_lab: (int) - FPGA Lab version number + @param compatibility_rev: (uint) - The FWs/UI compatibility revision + @return: None + """ + if not self.can_enabled: + raise ValueError("CAN Interface is not enabled") + + payload = conversions.unsigned_byte_to_bytearray (major ) + payload += conversions.unsigned_byte_to_bytearray (minor ) + payload += conversions.unsigned_byte_to_bytearray (micro ) + payload += conversions.unsigned_short_to_bytearray (build ) + payload += conversions.unsigned_byte_to_bytearray (fpga_id ) + payload += conversions.unsigned_byte_to_bytearray (fpga_major ) + payload += conversions.unsigned_byte_to_bytearray (fpga_minor ) + payload += conversions.unsigned_byte_to_bytearray (fpga_lab ) + payload += conversions.unsigned_integer_to_bytearray(compatibility_rev) + + message = CAN.DenaliMessage.build_message( + channel_id=CAN.DenaliChannels.td_sync_broadcast_ch_id, + message_id=msg_ids.MsgIds.MSG_ID_TD_VERSION_REPONSE.value, + payload=payload) + + self.can_interface.send(message, 0) + + + def td_serial(self, serial: str): + """ + the td version serial response message method + @param serial: serial number + @return: None + """ + # TODO: replace with proper payload and message ID once message is defined + payload = bytes(serial, 'ascii') + b'\x00' + + message = CAN.DenaliMessage.build_message( + channel_id=CAN.DenaliChannels.td_to_ui_ch_id, + message_id=msg_ids.MsgIds.MSG_ID_TD_SERIAL_RESPONSE.value, + payload=payload) + + self.can_interface.send(message, 0) + + def td_request_ui_versions(self): + """ + the td request UI versions + + @return: None + """ + message = CAN.DenaliMessage.build_message( + channel_id=CAN.DenaliChannels.td_to_ui_ch_id, + message_id=msg_ids.MsgIds.MSG_ID_TD_UI_VERSION_INFO_REQUEST.value) + + self.can_interface.send(message, 0) + + def td_Treatment_Parameters_CreateRx(self, vRejectionReason: int): + if not self.can_enabled: + raise ValueError("CAN Interface is not enabled") + + payload = conversions.integer_to_bytearray(1 if vRejectionReason == 0 else 0) + payload += conversions.integer_to_bytearray(vRejectionReason) + + message = CAN.DenaliMessage.build_message( + channel_id=CAN.DenaliChannels.td_to_ui_ch_id, + message_id=msg_ids.MsgIds.MSG_ID_TD_RESP_INITIATE_TREATMENT_WORKFLOW.value, + payload=payload) + self.can_interface.send(message, 0) + + + def td_Treatment_Parameters_Validation( self, + vAccepted : int = 1, + vBloodFlowRateRejectReason : int = 0, + vDialysateFlowRateRejectReason : int = 0, + vTreatmentDurationRejectReason : int = 0, + vSalineBolusVolumeRejectReason : int = 0, + vHeparinStopTimeRejectReason : int = 0, + vHeparinTypeRejectReason : int = 0, + vAcidConcentrateRejectReason : int = 0, + vBicarbonateConcentrateRejectReason : int = 0, + vDialyzerTypeRejectReason : int = 0, + vBloodPressureMeasureIntervalRejectReason : int = 0, + vRinsebackFlowRateRejectReason : int = 0, + vRinsebackVolumeRejectReason : int = 0, + vArterialPressureLimitWindowRejectReason : int = 0, + vVenousPressureLimitWindowRejectReason : int = 0, + vVenousPressureLimitAsymtrcRejectReason : int = 0, + vTrancembrncPressureLimitWindowRejectReason : int = 0, + vDialysateTempRejectReason : int = 0, + vHeparinDispensingRateRejectReason : int = 0, + vHeparinBolusVolumeRejectReason : int = 0 + ): + """TD Treatment Parameter Validation Response to the SW validation request with sent values of the same parameters. + Args: + vAccepted (int, optional): Zero value if rejected. Defaults to 1. + vBloodFlowRateRejectReason (int, optional): None zero value of rejection reason. Defaults to 0. + vDialysateFlowRateRejectReason (int, optional): None zero value of rejection reason. Defaults to 0. + vTreatmentDurationRejectReason (int, optional): None zero value of rejection reason. Defaults to 0. + vSalineBolusVolumeRejectReason (int, optional): None zero value of rejection reason. Defaults to 0. + vHeparinStopTimeRejectReason (int, optional): None zero value of rejection reason. Defaults to 0. + vHeparinTypeRejectReason (int, optional): None zero value of rejection reason. Defaults to 0. + vAcidConcentrateRejectReason (int, optional): None zero value of rejection reason. Defaults to 0. + vBicarbonateConcentrateRejectReason (int, optional): None zero value of rejection reason. Defaults to 0. + vDialyzerTypeRejectReason (int, optional): None zero value of rejection reason. Defaults to 0. + vBloodPressureMeasureIntervalRejectReason (int, optional): None zero value of rejection reason. Defaults to 0. + vRinsebackFlowRateRejectReason (int, optional): None zero value of rejection reason. Defaults to 0. + vRinsebackVolumeRejectReason (int, optional): None zero value of rejection reason. Defaults to 0. + vArterialPressureLimitWindowRejectReason (int, optional): None zero value of rejection reason. Defaults to 0. + vVenousPressureLimitWindowRejectReason (int, optional): None zero value of rejection reason. Defaults to 0. + vVenousPressureLimitAsymtrcRejectReason (int, optional): None zero value of rejection reason. Defaults to 0. + vTrancembrncPressureLimitWindowRejectReason (int, optional): None zero value of rejection reason. Defaults to 0. + vDialysateTempRejectReason (int, optional): None zero value of rejection reason. Defaults to 0. + vHeparinDispensingRateRejectReason (int, optional): None zero value of rejection reason. Defaults to 0. + vHeparinBolusVolumeRejectReason (int, optional): None zero value of rejection reason. Defaults to 0. + """ + + if not self.can_enabled: + raise ValueError("CAN Interface is not enabled") + + payload = conversions.integer_to_bytearray(vAccepted ) + payload += conversions.integer_to_bytearray(vBloodFlowRateRejectReason ) + payload += conversions.integer_to_bytearray(vDialysateFlowRateRejectReason ) + payload += conversions.integer_to_bytearray(vTreatmentDurationRejectReason ) + payload += conversions.integer_to_bytearray(vSalineBolusVolumeRejectReason ) + payload += conversions.integer_to_bytearray(vHeparinStopTimeRejectReason ) + payload += conversions.integer_to_bytearray(vHeparinTypeRejectReason ) + payload += conversions.integer_to_bytearray(vAcidConcentrateRejectReason ) + payload += conversions.integer_to_bytearray(vBicarbonateConcentrateRejectReason ) + payload += conversions.integer_to_bytearray(vDialyzerTypeRejectReason ) + payload += conversions.integer_to_bytearray(vBloodPressureMeasureIntervalRejectReason ) + payload += conversions.integer_to_bytearray(vRinsebackFlowRateRejectReason ) + payload += conversions.integer_to_bytearray(vRinsebackVolumeRejectReason ) + payload += conversions.integer_to_bytearray(vArterialPressureLimitWindowRejectReason ) + payload += conversions.integer_to_bytearray(vVenousPressureLimitWindowRejectReason ) + payload += conversions.integer_to_bytearray(vVenousPressureLimitAsymtrcRejectReason ) + payload += conversions.integer_to_bytearray(vTrancembrncPressureLimitWindowRejectReason ) + payload += conversions.integer_to_bytearray(vDialysateTempRejectReason ) + payload += conversions.integer_to_bytearray(vHeparinDispensingRateRejectReason ) + payload += conversions.integer_to_bytearray(vHeparinBolusVolumeRejectReason ) + + message = CAN.DenaliMessage.build_message( + channel_id=CAN.DenaliChannels.td_to_ui_ch_id, + message_id=msg_ids.MsgIds.MSG_ID_TD_RESP_TREATMENT_PARAMS_TO_VALIDATE.value, + payload=payload) + self.can_interface.send(message, 0) + + + def cmd_send_general_response(self, message_id: int, accepted: int, reason: int, + is_pure_data: bool = False, + has_parameters: bool = False, + parameters_payload: any = 0x00, + channel_id=CAN.DenaliChannels.td_to_ui_ch_id) -> None: + """A general method to send any standard response message, by it's id and list of parameters. + Args: + message_id (int ): the id of the message + accepted (int ): the standard accepted parameter of any response message + reason (int ): the standard rejection reason parameter of any response message + is_pure_data (bool, optional ): The message only has data. Defaults to False. + has_parameters (bool, optional ): if the message has parameter this needs to be true. Defaults to False. + parameters_payload (any, optional ): the list of parameters pre-converted and ready to be concatenated to the payload. Defaults to 0x00. + channel_id (_type_, optional ): indicates the channel. Defaults to CAN.DenaliChannels.td_to_ui_ch_id. + """ + payload = "" + if not is_pure_data: + payload = conversions.integer_to_bytearray(accepted) + payload += conversions.integer_to_bytearray(reason ) + + if has_parameters: + payload = parameters_payload + + message = CAN.DenaliMessage.build_message( + channel_id, + message_id, + payload + ) + + self.can_interface.send(message, 0)