Index: dialin/dg/chemical_disinfect.py =================================================================== diff -u -r7fe939e59e034a80456d9f865c6fda428c2ae861 -rcadb919bce9140638cae552306f374961833dafc --- dialin/dg/chemical_disinfect.py (.../chemical_disinfect.py) (revision 7fe939e59e034a80456d9f865c6fda428c2ae861) +++ dialin/dg/chemical_disinfect.py (.../chemical_disinfect.py) (revision cadb919bce9140638cae552306f374961833dafc) @@ -49,6 +49,8 @@ self.r1_level = 0 self.r2_level = 0 self.chemical_disinfect_ui_state = 0 + self.dg_chem_disinfect_data_timestamp = 0.0 + self.dg_chem_disinfect_time_timestamp = 0.0 if self.can_interface is not None: channel_id = DenaliChannels.dg_sync_broadcast_ch_id @@ -61,6 +63,7 @@ self.can_interface.register_receiving_publication_function(channel_id, msg_id, self._handler_chemical_disinfect_to_ui_sync) + def clear_chem_disinfect_info(self) -> None: """ Clears public class properties that are updated by the handler. @@ -78,8 +81,8 @@ self.r2_level = 0 self.chemical_disinfect_ui_state = 0 - @publish(["chemical_disinfect_elapsed_time", "chemical_disinfect_target_time"]) - def _handler_chemical_disinfect_to_ui_sync(self, message): + @publish(["dg_chem_disinfect_time_timestamp","chemical_disinfect_elapsed_time", "chemical_disinfect_target_time"]) + def _handler_chemical_disinfect_to_ui_sync(self, message, timestamp = 0.0): """ Handles published chemical disinfect message @@ -94,10 +97,11 @@ self.chemical_disinfect_target_time = int(disinfect_target_time / 1000) self.chemical_disinfect_elapsed_time = int(disinfect_elapsed_time / 1000) + self.dg_chem_disinfect_time_timestamp = timestamp - @publish(["chemical_disinfect_state", "overall_elapsed_time", "state_elapsed_time", "cancellation_mode", - "r1_level", "r2_level", "chemical_disinfect_ui_state"]) - def _handler_chemical_disinfect_sync(self, message): + @publish(["dg_chem_disinfect_data_timestamp", "chemical_disinfect_state", "overall_elapsed_time", "state_elapsed_time", + "cancellation_mode", "r1_level", "r2_level", "chemical_disinfect_ui_state"]) + def _handler_chemical_disinfect_sync(self, message, timestamp = 0.0): """ Handles published chemical disinfect message @@ -124,6 +128,7 @@ self.r1_level = r1 self.r2_level = r2 self.chemical_disinfect_ui_state = chem_ui_state + self.dg_chem_disinfect_data_timestamp = timestamp def get_chem_disinfect_target_time(self) -> int: """ Index: dialin/dg/dialysate_fill.py =================================================================== diff -u -rfffd9904004bd37161ce4c5ca0f5ff6fe0ebed28 -rcadb919bce9140638cae552306f374961833dafc --- dialin/dg/dialysate_fill.py (.../dialysate_fill.py) (revision fffd9904004bd37161ce4c5ca0f5ff6fe0ebed28) +++ dialin/dg/dialysate_fill.py (.../dialysate_fill.py) (revision cadb919bce9140638cae552306f374961833dafc) @@ -54,13 +54,15 @@ self.used_acid = 0.0 self.used_bicarb = 0.0 self.total_volume = 0.0 + self.dg_fill_mode_timestamp = 0.0 if self.can_interface is not None: channel_id = DenaliChannels.dg_sync_broadcast_ch_id msg_id = MsgIds.MSG_ID_DG_FILL_MODE_DATA.value self.can_interface.register_receiving_publication_function(channel_id, msg_id, self._handler_fill_mode_monitor_sync) + def get_fill_mode_data(self): """ Gets the current concentrate pump data value @@ -72,8 +74,8 @@ return [self.avg_acid, self.avg_bicarb, self.first_fill, self.pctDiffConduct, self.used_acid, self.used_bicarb, self.total_volume] - @publish(["avg_acid", "avg_bicarb", "first_fill", "pctDiffConduct", "used_acid", "used_bicarb", "total_volume"]) - def _handler_fill_mode_monitor_sync(self, message): + @publish(["dg_fill_mode_timestamp","avg_acid", "avg_bicarb", "first_fill", "pctDiffConduct", "used_acid", "used_bicarb", "total_volume"]) + def _handler_fill_mode_monitor_sync(self, message, timestamp=0.0): """ Handles published dialysate fill mode data' data messages. Dialysate fill data are captured for reference. @@ -95,6 +97,7 @@ message['message'][MsgFieldPositions.START_POS_FIELD_6:MsgFieldPositions.END_POS_FIELD_6]))[0] self.total_volume = struct.unpack(' int: """ Index: dialin/dg/dialysate_generator.py =================================================================== diff -u -rff18efc549b1029e3c4b76946c83d544e063b2d8 -rcadb919bce9140638cae552306f374961833dafc --- dialin/dg/dialysate_generator.py (.../dialysate_generator.py) (revision ff18efc549b1029e3c4b76946c83d544e063b2d8) +++ dialin/dg/dialysate_generator.py (.../dialysate_generator.py) (revision cadb919bce9140638cae552306f374961833dafc) @@ -160,6 +160,8 @@ self.dg_logged_in = False self.dg_set_logged_in_status(False) self.dg_no_transmit_msg_list = [0,0,0,0,0,0,0,0] + self.dg_op_mode_timestamp = 0.0 + self.dg_version_response_timestamp = 0.0 # Create command groups self.accel = DGAccelerometer(self.can_interface, self.logger) @@ -257,8 +259,8 @@ """ self.dg_logged_in = logged_in - @publish(["dg_version", "fpga_version"]) - def _handler_dg_version(self, message): + @publish(["dg_version_response_timestamp","dg_version", "fpga_version"]) + def _handler_dg_version(self, message,timestamp): """ Handler for response from DG regarding its version. @@ -291,9 +293,10 @@ if all([len(each) > 0 for each in [fpga_major, fpga_minor, fpga_id, fpga_lab]]): self.fpga_version = f"ID: {fpga_id[0]} v{fpga_major[0]}.{fpga_minor[0]}.{fpga_lab[0]}" self.logger.debug(f"DG FPGA VERSION: {self.fpga_version}") + self.dg_version_response_timestamp = timestamp - @publish(["dg_operation_mode", "dg_operation_sub_mode"]) - def _handler_dg_op_mode_sync(self, message): + @publish(["dg_op_mode_timestamp","dg_operation_mode", "dg_operation_sub_mode"]) + def _handler_dg_op_mode_sync(self, message, timestamp=0.0): """ Handles published DG operation mode messages. Current DG operation mode is captured for reference. @@ -309,6 +312,7 @@ self.dg_operation_mode = mode[0] self.dg_operation_sub_mode = smode[0] + self.dg_op_mode_timestamp = timestamp def cmd_log_in_to_dg(self, resend: bool = False) -> int: """ Index: dialin/dg/drain_pump.py =================================================================== diff -u -r32001abdfb62770761771b563eb6ff517152fc76 -rcadb919bce9140638cae552306f374961833dafc --- dialin/dg/drain_pump.py (.../drain_pump.py) (revision 32001abdfb62770761771b563eb6ff517152fc76) +++ dialin/dg/drain_pump.py (.../drain_pump.py) (revision cadb919bce9140638cae552306f374961833dafc) @@ -60,6 +60,7 @@ self.target_drain_pump_outlet_flow_lpm = 0.0 self.drain_pump_current_A = 0.0 self.drain_pump_direction = 0 + self.dg_drain_pump_timestamp = 0.0 def get_target_drain_pump_rpm(self): """ @@ -93,9 +94,9 @@ """ return self.current_drain_pump_rpm - @publish(["target_drain_pump_rpm", "dac_value", "drain_pump_state", "current_drain_pump_rpm", + @publish(["dg_drain_pump_timestamp","target_drain_pump_rpm", "dac_value", "drain_pump_state", "current_drain_pump_rpm", "drain_pump_current_A", "drain_pump_direction", "target_drain_pump_outlet_flow_lpm"]) - def _handler_drain_pump_sync(self, message): + def _handler_drain_pump_sync(self, message, timestamp=0.0): """ Handles published drain pump data messages. Drain pump data are captured for reference. @@ -117,6 +118,7 @@ message['message'][MsgFieldPositions.START_POS_FIELD_6:MsgFieldPositions.END_POS_FIELD_6]))[0] self.drain_pump_direction = struct.unpack('i', bytearray( message['message'][MsgFieldPositions.START_POS_FIELD_7:MsgFieldPositions.END_POS_FIELD_7]))[0] + self.dg_drain_pump_timestamp = timestamp def cmd_drain_pump_set_outlet_target_flow_lpm(self, flow: float) -> int: """ Index: dialin/dg/heat_disinfect.py =================================================================== diff -u -ra994d47d279b23603de37a19bf947b8212527190 -rcadb919bce9140638cae552306f374961833dafc --- dialin/dg/heat_disinfect.py (.../heat_disinfect.py) (revision a994d47d279b23603de37a19bf947b8212527190) +++ dialin/dg/heat_disinfect.py (.../heat_disinfect.py) (revision cadb919bce9140638cae552306f374961833dafc) @@ -91,6 +91,8 @@ self.cancellation_mode = 0 self.r1_level = 0 self.r2_level = 0 + self.dg_heat_disinfection_time_timestamp = 0.0 + self.dg_heat_disinfection_data_timestamp = 0.0 if self.can_interface is not None: channel_id = DenaliChannels.dg_sync_broadcast_ch_id @@ -120,8 +122,8 @@ self.r2_level = 0 self.heat_disinfect_ui_state = 0 - @publish(["heat_disinfect_target_time", "heat_disinfect_count_down_time"]) - def _handler_heat_disinfect_to_ui_sync(self, message): + @publish(["dg_heat_disinfection_time_timestamp","heat_disinfect_target_time", "heat_disinfect_count_down_time"]) + def _handler_heat_disinfect_to_ui_sync(self, message, timestamp=0.0): """ Handles published heat disinfect message @@ -149,10 +151,11 @@ self.disinfect_ro_82_time_s = ro_82 self.disinfect_r_77_time_s = r_77 self.disinfect_r_82_time_s = r_82 + self.dg_heat_disinfection_time_timestamp = timestamp - @publish(["heat_disinfect_state", "overall_elapsed_time", "state_elapsed_time", "cancellation_mode", "r1_level", - "r2_level", "heat_disinfect_ui_state"]) - def _handler_heat_disinfect_sync(self, message): + @publish(["dg_heat_disinfection_data_timestamp","heat_disinfect_state", "overall_elapsed_time", + "state_elapsed_time", "cancellation_mode", "r1_level", "r2_level", "heat_disinfect_ui_state"]) + def _handler_heat_disinfect_sync(self, message, timestamp): """ Handles published heat disinfect message @@ -176,7 +179,8 @@ self.cancellation_mode = cancellation_mode self.r1_level = r1 self.r2_level = r2 - self.heat_disinfect_ui_state = ui_state + self.heat_disinfect_ui_state = ui + self.dg_heat_disinfection_data_timestamp = timestamp def get_heat_disinfect_state(self) -> int: """ Index: dialin/dg/reservoirs.py =================================================================== diff -u -rdc07ecb63eed240b6d3b47dd96743f93014c564c -rcadb919bce9140638cae552306f374961833dafc --- dialin/dg/reservoirs.py (.../reservoirs.py) (revision dc07ecb63eed240b6d3b47dd96743f93014c564c) +++ dialin/dg/reservoirs.py (.../reservoirs.py) (revision cadb919bce9140638cae552306f374961833dafc) @@ -64,6 +64,7 @@ self.temp_avg_fill = 0.0 self.temp_last_fill = 0.0 self.time_rsrvr_fill = 0.0 + self.dg_reservoirs_timestamp = 0.0 def get_active_reservoir(self): """ @@ -165,10 +166,10 @@ self.logger.debug("Timeout!!!!") return False - @publish(["active_reservoir", "fill_to_vol_ml", "drain_to_vol_ml", "time_reservoir_cycle", + @publish(["dg_reservoirs_timestamp","active_reservoir", "fill_to_vol_ml", "drain_to_vol_ml", "time_reservoir_cycle", "time_reservoir_fill_2_switch", "time_uf_decay", "temp_uf_fill", "temp_reservoir_use_actual", "temp_reservoir_end_fill", "temp_avg_fill", "temp_last_fill", "time_rsrvr_fill"]) - def _handler_reservoirs_sync(self, message): + def _handler_reservoirs_sync(self, message, timestamp=0.0): """ Handles published reservoir data messages. Reservoir data are captured for reference. @@ -201,3 +202,4 @@ message['message'][MsgFieldPositions.START_POS_FIELD_11:MsgFieldPositions.END_POS_FIELD_11]))[0] self.time_rsrvr_fill = struct.unpack('f', bytearray( message['message'][MsgFieldPositions.START_POS_FIELD_12:MsgFieldPositions.END_POS_FIELD_12]))[0] + self.dg_reservoirs_timestamp = timestamp Index: dialin/dg/temperatures.py =================================================================== diff -u -r32001abdfb62770761771b563eb6ff517152fc76 -rcadb919bce9140638cae552306f374961833dafc --- dialin/dg/temperatures.py (.../temperatures.py) (revision 32001abdfb62770761771b563eb6ff517152fc76) +++ dialin/dg/temperatures.py (.../temperatures.py) (revision cadb919bce9140638cae552306f374961833dafc) @@ -59,6 +59,7 @@ self.can_interface = can_interface self.logger = logger # Dictionary of the temperature sensors + self.dg_temperatures_timestamp = 0.0 self.temperatures = {DGTemperaturesNames.INLET_PRIMARY_HEATER.name: 0.0, DGTemperaturesNames.HEAT_DISINFECT.name: 0.0, DGTemperaturesNames.OUTLET_PRIMARY_HEATER.name: 0.0, @@ -96,8 +97,8 @@ """ return self.temperatures[DGTemperaturesNames(sensor).name] - @publish(["temperatures"]) - def _handler_temperature_sensors_sync(self, message): + @publish(["dg_temperatures_timestamp","temperatures"]) + def _handler_temperature_sensors_sync(self, message,timestamp=0.0): """ Handles published temperature sensors message @@ -167,6 +168,8 @@ self.temperatures[DGTemperaturesNames.BARO_TEMP_SENSOR.name] = struct.unpack('f', bytearray( message['message'][MsgFieldPositions.START_POS_FIELD_21:MsgFieldPositions.END_POS_FIELD_21]))[0] + self.dg_temperatures_timestamp = timestamp + def cmd_temperatures_data_broadcast_interval_override(self, ms: int, reset: int = NO_RESET) -> int: """ Constructs and sends broadcast time interval. Index: dialin/hd/alarms.py =================================================================== diff -u -r095ca3226b2c95e8a2135f99bea8d57a03274536 -rcadb919bce9140638cae552306f374961833dafc --- dialin/hd/alarms.py (.../alarms.py) (revision 095ca3226b2c95e8a2135f99bea8d57a03274536) +++ dialin/hd/alarms.py (.../alarms.py) (revision cadb919bce9140638cae552306f374961833dafc) @@ -84,7 +84,7 @@ channel_id = DenaliChannels.hd_alarm_broadcast_ch_id msg_id = MsgIds.MSG_ID_ALARM_TRIGGERED.value self.can_interface.register_receiving_publication_function(channel_id, msg_id, - self._handler_alarm_activate) + self._handler_alarm_trigger) msg_id = MsgIds.MSG_ID_ALARM_CLEARED.value self.can_interface.register_receiving_publication_function(channel_id, msg_id, self._handler_alarm_clear) @@ -96,6 +96,11 @@ self.can_interface.register_receiving_publication_function(channel_id, msg_id, self._handler_alarm_information_sync) + self.hd_alarm_status_timestamp = 0.0 + self.hd_alarm_triggered_timestamp = 0.0 + self.hd_alarm_cleared_timestamp = 0.0 + self.hd_alarm_clr_condition_timestamp = 0.0 + self.hd_alarm_information_timestamp = 0.0 # composite alarm status based on latest HD alarm status broadcast message self.alarms_priority_state = 0 self.alarm_top = 0 @@ -437,8 +442,8 @@ for x in range(500): self.alarm_states[x] = False - @publish(["alarms_state", "alarm_top", "alarms_silence_expires_in", "alarms_escalates_in", "alarms_flags"]) - def _handler_alarms_status_sync(self, message): + @publish(["hd_alarm_status_timestamp", "alarms_state", "alarm_top", "alarms_silence_expires_in", "alarms_escalates_in", "alarms_flags"]) + def _handler_alarms_status_sync(self, message, timestamp=0.0): """ Handles published alarms status messages. alarms status data are captured for reference. @@ -462,8 +467,10 @@ message['message'][self.START_POS_ALARMS_FLAGS:self.END_POS_ALARMS_FLAGS]), byteorder=DenaliMessage.BYTE_ORDER) - @publish(["alarm_states", "alarm_conditions", "alarm_priorities", "alarm_ranks", "alarm_clear_top_only_flags"]) - def _handler_alarm_activate(self, message): + self.hd_alarm_status_timestamp = timestamp + + @publish(["hd_alarm_triggered_timestamp", "alarm_states", "alarm_conditions", "alarm_priorities", "alarm_ranks", "alarm_clear_top_only_flags"]) + def _handler_alarm_trigger(self, message, timestamp=0.0): """ Handles published HD alarm activation messages. @@ -495,9 +502,10 @@ self.alarm_priorities[alarm_id[0]] = priority[0] self.alarm_ranks[alarm_id[0]] = rank[0] self.alarm_clear_top_only_flags[alarm_id[0]] = clr_top_only[0] + self.hd_alarm_triggered_timestamp = timestamp - @publish(["alarm_states", "alarm_conditions"]) - def _handler_alarm_clear(self, message): + @publish(["hd_alarm_cleared_timestamp", "alarm_states", "alarm_conditions"]) + def _handler_alarm_clear(self, message, timestamp=0.0): """ Handles published HD alarm clear messages. @@ -507,9 +515,10 @@ alarm_id = struct.unpack('i', bytearray(message['message'][MsgFieldPositions.START_POS_FIELD_1:MsgFieldPositions.END_POS_FIELD_1])) self.alarm_states[alarm_id[0]] = False self.alarm_conditions[alarm_id[0]] = False + self.hd_alarm_cleared_timestamp = timestamp - @publish(["alarm_conditions", "alarm_conditions"]) - def _handler_alarm_condition_clear(self, message): + @publish(["hd_alarm_clr_condition_timestamp", "alarm_conditions", "alarm_conditions"]) + def _handler_alarm_condition_clear(self, message, timestamp=0.0): """ Handles published HD alarm clear alarm condition messages. @@ -518,10 +527,11 @@ """ alarm_id = struct.unpack('i', bytearray(message['message'][MsgFieldPositions.START_POS_FIELD_1:MsgFieldPositions.END_POS_FIELD_1])) self.alarm_conditions[alarm_id[0]] = False + self.hd_alarm_clr_condition_timestamp = timestamp - @publish(["alarm_volume", "alarm_audio_curr_hg", "alarm_audio_curr_lg", "alarm_backup_audio_curr", + @publish(["hd_alarm_information_timestamp", "alarm_volume", "alarm_audio_curr_hg", "alarm_audio_curr_lg", "alarm_backup_audio_curr", "safety_shutdown_active", "alarm_table_button_blockers", "alarm_state_button_blockers"]) - def _handler_alarm_information_sync(self, message): + def _handler_alarm_information_sync(self, message, timestamp=0.0): """ Handles published HD alarm information broadcast messages. @@ -563,6 +573,7 @@ self.alarm_state_button_blockers[self.AlarmResponseButtons.HD_ALARM_RESPONSE_BUTTON_RESUME.value] = True if srs[0] else False self.alarm_state_button_blockers[self.AlarmResponseButtons.HD_ALARM_RESPONSE_BUTTON_RINSEBACK.value] = True if srb[0] else False self.alarm_state_button_blockers[self.AlarmResponseButtons.HD_ALARM_RESPONSE_BUTTON_END_TREATMENT.value] = True if set[0] else False + self.hd_alarm_information_timestamp = timestamp def cmd_clear_all_alarms(self) -> int: """ Index: dialin/hd/battery.py =================================================================== diff -u -rd11307392af7f97f34edefaee1c6e9969468f7d1 -rcadb919bce9140638cae552306f374961833dafc --- dialin/hd/battery.py (.../battery.py) (revision d11307392af7f97f34edefaee1c6e9969468f7d1) +++ dialin/hd/battery.py (.../battery.py) (revision cadb919bce9140638cae552306f374961833dafc) @@ -47,7 +47,9 @@ self.can_interface.register_receiving_publication_function(channel_id, msg_id, self._handler_battery_manager_sync) msg_id = MsgIds.MSG_ID_HD_BATTERY_STATUS_DATA.value self.can_interface.register_receiving_publication_function(channel_id, msg_id, self._handler_battery_status_sync) - + + self.hd_battery_management_timestamp = 0.0 + self.hd_battery_status_timestamp = 0.0 # values from battery status message self.RemainingCapacity = 0 self.BatteryStatus = 0 @@ -146,8 +148,8 @@ """ return self.manager_values - @publish(['RemainingCapacity', 'BatteryStatus', 'BatteryChargerStatus', 'BatteryCommStatus']) - def _handler_battery_status_sync(self, message): + @publish(["hd_battery_status_timestamp", 'RemainingCapacity', 'BatteryStatus', 'BatteryChargerStatus', 'BatteryCommStatus']) + def _handler_battery_status_sync(self, message, timestamp=0.0): """ Handles published battery data messages. Battery data are captured for reference. @@ -183,14 +185,16 @@ # convert integer to string representing bits temp = struct.unpack('HH', value[0])[0] value[0] = format(temp, 'b') + self.hd_battery_status_timestamp = timestamp - @publish(['RemainingCapacityAlarm', 'RemainingTimeAlarm', 'BatteryMode', 'AtRate', 'AtRateTimeToFull', + @publish(['hd_battery_management_timestamp', + 'RemainingCapacityAlarm', 'RemainingTimeAlarm', 'BatteryMode', 'AtRate', 'AtRateTimeToFull', 'AtRateTimeToEmpty', 'AtRateOK', 'Temperature', 'Voltage', 'Current', 'AverageCurrent', 'MaxError', 'RelativeStateOfCharge', 'AbsoluteStateOfCharge', 'FullChargeCapacity', 'RunTimeToEmpty', 'AverageTimeToEmpty', 'AverageTimeToFull', 'ChargingCurrent', 'ChargingVoltage', 'CycleCount', 'DesignCapacity', 'DesignVoltage', 'SpecificationInfo', 'ManufactureDate', 'SerialNumber', 'ManufacturerName', 'DeviceName', 'DeviceChemistry']) - def _handler_battery_manager_sync(self, message): + def _handler_battery_manager_sync(self, message, timestamp=0.0): """ Handles published battery data messages. Battery data are captured for reference. @@ -226,6 +230,7 @@ # convert integer to string representing bits temp = struct.unpack('HH', value[0])[0] value[0] = format(temp, 'b') + self.hd_battery_management_timestamp = timestamp def cmd_battery_remaining_capacity_override(self, mWh: float, reset: int = NO_RESET) -> int: """ Index: dialin/hd/blood_flow.py =================================================================== diff -u -rcf1dab9c15c4171412e6f532202b305475720f0c -rcadb919bce9140638cae552306f374961833dafc --- dialin/hd/blood_flow.py (.../blood_flow.py) (revision cf1dab9c15c4171412e6f532202b305475720f0c) +++ dialin/hd/blood_flow.py (.../blood_flow.py) (revision cadb919bce9140638cae552306f374961833dafc) @@ -43,7 +43,7 @@ msg_id = MsgIds.MSG_ID_BLOOD_FLOW_DATA.value self.can_interface.register_receiving_publication_function(channel_id, msg_id, self._handler_blood_flow_sync) - + self.hd_blood_flow_timestamp = 0.0 self.target_blood_flow_rate = 0 self.measured_blood_flow_rate = 0.0 self.measured_blood_pump_rotor_speed = 0.0 @@ -126,7 +126,7 @@ """ return self.pres_blood_flow_rate - @publish(["target_blood_flow_rate", "measured_blood_flow_rate", "measured_blood_pump_rotor_speed", + @publish(["hd_blood_flow_timestamp", "target_blood_flow_rate", "measured_blood_flow_rate", "measured_blood_pump_rotor_speed", "measured_blood_pump_speed", "measured_blood_pump_mc_speed", "measured_blood_pump_mc_current", "pwm_duty_cycle_pct", "rotor_count", "pres_blood_flow_rate"]) def _handler_blood_flow_sync(self, message): @@ -166,6 +166,7 @@ self.pwm_duty_cycle_pct = pwm[0] self.rotor_count = rot[0] self.pres_blood_flow_rate = pres[0] + self.hd_blood_flow_timestamp = timestamp def cmd_blood_flow_set_point_override(self, flow: int, mode: int = PUMP_CONTROL_MODE_CLOSED_LOOP, reset: int = NO_RESET) -> int: Index: dialin/hd/dialysate_inlet_flow.py =================================================================== diff -u -rcf1dab9c15c4171412e6f532202b305475720f0c -rcadb919bce9140638cae552306f374961833dafc --- dialin/hd/dialysate_inlet_flow.py (.../dialysate_inlet_flow.py) (revision cf1dab9c15c4171412e6f532202b305475720f0c) +++ dialin/hd/dialysate_inlet_flow.py (.../dialysate_inlet_flow.py) (revision cadb919bce9140638cae552306f374961833dafc) @@ -55,6 +55,7 @@ self.pwm_duty_cycle_pct = 0.0 self.rotor_count = 0 self.pres_dialysate_flow_rate = 0 + self.hd_dial_inlet_flow_timestamp = 0.0 def get_target_dialysate_inlet_flow_rate(self): """ @@ -129,6 +130,7 @@ return self.pres_dialysate_flow_rate @publish([ + "hd_dial_inlet_flow_timestamp", "target_dialysate_inlet_flow_rate", "measured_dialysate_inlet_flow_rate", "measured_dialysate_inlet_pump_rotor_speed", @@ -137,7 +139,7 @@ "measured_dialysate_inlet_pump_mc_current", "pwm_duty_cycle_pct", "rotor_count", "pres_dialysate_flow_rate" ]) - def _handler_dialysate_inlet_flow_sync(self, message): + def _handler_dialysate_inlet_flow_sync(self, message, timestamp=0.0): """ Handles published dialysate inlet flow data messages. Dialysate flow data are captured for reference. @@ -174,6 +176,7 @@ self.pwm_duty_cycle_pct = pwm[0] self.rotor_count = rot[0] self.pres_dialysate_flow_rate = pres[0] + self.hd_dial_inlet_flow_timestamp = timestamp def cmd_dialysate_inlet_flow_set_point_override(self, flow: int, Index: dialin/hd/fans.py =================================================================== diff -u -r32001abdfb62770761771b563eb6ff517152fc76 -rcadb919bce9140638cae552306f374961833dafc --- dialin/hd/fans.py (.../fans.py) (revision 32001abdfb62770761771b563eb6ff517152fc76) +++ dialin/hd/fans.py (.../fans.py) (revision cadb919bce9140638cae552306f374961833dafc) @@ -57,6 +57,7 @@ self.target_rpm = 0.0 self.inlet_1_rpm = 0.0 self.rpm_alarm_time = 0 + self.hd_fans_data_timestamp = 0.0 self.remove = 0 @@ -92,8 +93,8 @@ """ return self.rpm_alarm_time - @publish(['duty_cycle', 'target_rpm', 'inlet_1_rpm', 'rpm_alarm_time']) - def _handler_fans_sync(self, message): + @publish(["hd_fans_data_timestamp", 'duty_cycle', 'target_rpm', 'inlet_1_rpm', 'rpm_alarm_time']) + def _handler_fans_sync(self, message,timestamp=0.0): """ Handles published thermistors message. @@ -108,6 +109,7 @@ message['message'][MsgFieldPositions.START_POS_FIELD_3:MsgFieldPositions.END_POS_FIELD_3]))[0] self.rpm_alarm_time = struct.unpack('i', bytearray( message['message'][MsgFieldPositions.START_POS_FIELD_4:MsgFieldPositions.END_POS_FIELD_4]))[0] + self.hd_fans_data_timestamp = timestamp self.remove = struct.unpack('i', bytearray( message['message'][MsgFieldPositions.START_POS_FIELD_5:MsgFieldPositions.END_POS_FIELD_5]))[0] Index: dialin/hd/hemodialysis_device.py =================================================================== diff -u -rff18efc549b1029e3c4b76946c83d544e063b2d8 -rcadb919bce9140638cae552306f374961833dafc --- dialin/hd/hemodialysis_device.py (.../hemodialysis_device.py) (revision ff18efc549b1029e3c4b76946c83d544e063b2d8) +++ dialin/hd/hemodialysis_device.py (.../hemodialysis_device.py) (revision cadb919bce9140638cae552306f374961833dafc) @@ -122,6 +122,9 @@ self._handler_ui_version_response_sync) # create properties + self.hd_op_mode_timestamp = 0.0 + self.hd_debug_events_timestamp = 0.0 + self.ui_version_info_response_timestamp = 0.0 self.hd_operation_mode = HDOpModes.MODE_INIT.value self.hd_operation_sub_mode = 0 self.hd_logged_in = False @@ -203,8 +206,8 @@ """ return self.ui_version - @publish(["hd_debug_events"]) - def _handler_hd_debug_event_sync(self, message): + @publish(["hd_debug_events_timestamp","hd_debug_events"]) + def _handler_hd_debug_event_sync(self, message, timestamp = 0.0): payload = message['message'] message_length = payload[self._HD_DEBUG_EVENT_MSG_LEN_INDEX] @@ -217,6 +220,7 @@ char, char_index = bytearray_to_byte(payload, index + i, False) temp_message += chr(char) + self.hd_debug_events_timestamp = timestamp self.hd_debug_events.insert(self.hd_debug_event_index, temp_message) self.hd_last_debug_event = temp_message @@ -233,8 +237,8 @@ """ self.hd_logged_in = logged_in - @publish(["hd_operation_mode"]) - def _handler_hd_op_mode_sync(self, message): + @publish(["hd_op_mode_timestamp","hd_operation_mode", "hd_operation_sub_mode"]) + def _handler_hd_op_mode_sync(self, message, timestamp = 0.0): """ Handles published HD operation mode messages. Current HD operation mode is captured for reference. @@ -249,8 +253,10 @@ self.hd_operation_mode = mode[0] self.hd_operation_sub_mode = smode[0] + self.hd_op_mode_timestamp = timestamp - def _handler_ui_version_response_sync(self,message): + + def _handler_ui_version_response_sync(self,message, timestamp = 0.0): """ Handler for response from HD regarding its version. @@ -274,6 +280,8 @@ compatibility = struct.unpack(' 0 for each in [major, minor, micro, build, compatibility]]): self.ui_version = f"v{major[0]}.{minor[0]}.{micro[0]}-{build[0]}.{compatibility[0]}" self.logger.debug(f"UI VERSION: {self.ui_version}") Index: dialin/hd/pretreatment.py =================================================================== diff -u -r32001abdfb62770761771b563eb6ff517152fc76 -rcadb919bce9140638cae552306f374961833dafc --- dialin/hd/pretreatment.py (.../pretreatment.py) (revision 32001abdfb62770761771b563eb6ff517152fc76) +++ dialin/hd/pretreatment.py (.../pretreatment.py) (revision cadb919bce9140638cae552306f374961833dafc) @@ -75,6 +75,10 @@ MsgIds.MSG_ID_HD_PRIMING_STATUS_DATA.value, self._handler_prime_progress_sync) + self.hd_pre_treatment_state_timestamp = 0.0 + self.hd_no_cart_st_timestamp = 0.0 + self.hd_dry_st_timestamp = 0.0 + self.hd_priming_timestamp = 0.0 self.pre_treatment_submode = 0 self.pre_treatment_sample_water_state = 0 self.pre_treatment_consumable_self_test_state = 0 @@ -225,6 +229,7 @@ return self.pre_treatment_wet_self_test_state @publish([ + "hd_pre_treatment_state_timestamp", "pre_treatment_submode", "pre_treatment_sample_water_state", "pre_treatment_consumable_self_test_state", @@ -237,7 +242,7 @@ "pre_treatment_wet_self_test_state", "pre_treatment_reservoir_state" ]) - def _handler_pre_treatment_state_sync(self, message): + def _handler_pre_treatment_state_sync(self, message, timestamp=0.0): """ Handles published pre-treatment state data messages. @@ -268,13 +273,15 @@ # Yes, I know we should do the new way, but we we need a task to cover all these in one shot! self.pre_treatment_reservoir_state = struct.unpack('i', bytearray( message['message'][MsgFieldPositions.START_POS_FIELD_11:MsgFieldPositions.END_POS_FIELD_11]))[0] + self.hd_pre_treatment_state_timestamp = timestamp @publish([ + "hd_no_cart_st_timestamp", "no_cart_self_test_timeout", "no_cart_self_test_time_countdown" ]) - def _handler_no_cart_self_test_progress_sync(self, message): + def _handler_no_cart_self_test_progress_sync(self, message, timestamp=0.0): """ Handles published no cartridge self-test progress data messages. @@ -285,12 +292,14 @@ message['message'][MsgFieldPositions.START_POS_FIELD_1:MsgFieldPositions.END_POS_FIELD_1]))[0] self.no_cart_self_test_time_countdown = struct.unpack('i', bytearray( message['message'][MsgFieldPositions.START_POS_FIELD_2:MsgFieldPositions.END_POS_FIELD_2]))[0] + self.hd_no_cart_st_timestamp = timestamp @publish([ + "hd_dry_st_timestamp", "dry_self_test_timeout", "dry_self_test_time_countdown" ]) - def _handler_dry_self_test_progress_sync(self, message): + def _handler_dry_self_test_progress_sync(self, message, timestamp=0.0): """ Handles published dry self-test progress data messages. @@ -302,12 +311,14 @@ message['message'][MsgFieldPositions.START_POS_FIELD_1:MsgFieldPositions.END_POS_FIELD_1]))[0] self.dry_self_test_time_countdown = struct.unpack('i', bytearray( message['message'][MsgFieldPositions.START_POS_FIELD_2:MsgFieldPositions.END_POS_FIELD_2]))[0] + self.hd_dry_st_timestamp = timestamp @publish([ + "hd_priming_timestamp", "prime_timeout", "prime_time_countdown" ]) - def _handler_prime_progress_sync(self, message): + def _handler_prime_progress_sync(self, message, timestamp=0.0): """ Handles published prime progress data messages. @@ -319,3 +330,4 @@ message['message'][MsgFieldPositions.START_POS_FIELD_1:MsgFieldPositions.END_POS_FIELD_1]))[0] self.prime_time_countdown = struct.unpack('i', bytearray( message['message'][MsgFieldPositions.START_POS_FIELD_2:MsgFieldPositions.END_POS_FIELD_2]))[0] + self.hd_priming_timestamp = timestamp \ No newline at end of file Index: dialin/hd/rtc.py =================================================================== diff -u -r095ca3226b2c95e8a2135f99bea8d57a03274536 -rcadb919bce9140638cae552306f374961833dafc --- dialin/hd/rtc.py (.../rtc.py) (revision 095ca3226b2c95e8a2135f99bea8d57a03274536) +++ dialin/hd/rtc.py (.../rtc.py) (revision cadb919bce9140638cae552306f374961833dafc) @@ -45,6 +45,8 @@ channel_id = DenaliChannels.hd_sync_broadcast_ch_id msg_id = MsgIds.MSG_ID_RTC_EPOCH.value self.can_interface.register_receiving_publication_function(channel_id, msg_id, self._handler_rtc_epoch) + + self.hd_rtc_timestamp = 0.0 self.rtc_epoch = 0 def get_rtc_epoch(self): @@ -55,8 +57,8 @@ """ return self.rtc_epoch - @publish(["rtc_epoch"]) - def _handler_rtc_epoch(self, message): + @publish(["hd_rtc_timestamp","rtc_epoch"]) + def _handler_rtc_epoch(self, message, timestamp=0.0): """ Publishes the rtc time in epoch @@ -66,6 +68,7 @@ epoch = struct.unpack('i', bytearray( message['message'][MsgFieldPositions.START_POS_FIELD_1:MsgFieldPositions.END_POS_FIELD_1]))[0] self.rtc_epoch = epoch + self.hd_rtc_timestamp = timestamp def cmd_stop_rtc(self): """ Index: dialin/hd/treatment.py =================================================================== diff -u -r32001abdfb62770761771b563eb6ff517152fc76 -rcadb919bce9140638cae552306f374961833dafc --- dialin/hd/treatment.py (.../treatment.py) (revision 32001abdfb62770761771b563eb6ff517152fc76) +++ dialin/hd/treatment.py (.../treatment.py) (revision cadb919bce9140638cae552306f374961833dafc) @@ -117,6 +117,14 @@ self.can_interface.register_receiving_publication_function(DenaliChannels.hd_to_dialin_ch_id, msg_id, self._handler_treatment_current_parameters) + self.hd_treatment_time_timestamp = 0.0 + self.hd_treatment_state_timestamp = 0.0 + self.hd_saline_bolus_timestamp = 0.0 + self.hd_rinseback_progress_timestamp = 0.0 + self.hd_blood_prime_progress_timestamp = 0.0 + self.hd_recirc_progress_timestamp = 0.0 + self.hd_treatment_stop_timer_data_timestamp = 0.0 + self.hd_res_current_treatment_parameters_timestamp = 0.0 # treatment duration data self.treatment_time_prescribed = 0 self.treatment_time_elapsed = 0 @@ -464,11 +472,12 @@ @publish([ + "hd_treatment_time_timestamp", "treatment_time_prescribed", "treatment_time_elapsed", "treatment_time_remaining" ]) - def _handler_treatment_time_sync(self, message): + def _handler_treatment_time_sync(self, message, timestamp=0.0): """ Handles published treatment time data messages. treatment time data are captured for reference. @@ -487,8 +496,10 @@ self.treatment_time_prescribed = tot[0] self.treatment_time_elapsed = ela[0] self.treatment_time_remaining = rem[0] + self.hd_treatment_time_timestamp = timestamp @publish([ + "hd_treatment_state_timestamp", "treatment_state", "treatment_uf_state", "saline_bolus_state", @@ -500,7 +511,7 @@ "treatment_stop_state", "dialysis_state" ]) - def _handler_treatment_state_sync(self, message): + def _handler_treatment_state_sync(self, message, timestamp=0.0): """ Handles published treatment state data messages. treatment state data are captured for reference. @@ -540,13 +551,15 @@ self.treatment_end_state = txe[0] self.treatment_stop_state = txs[0] self.dialysis_state = dia[0] + self.hd_treatment_state_timestamp = timestamp @publish([ + "hd_saline_bolus_timestamp", "saline_bolus_max_vol", "saline_bolus_cum_vol", "saline_bolus_bol_vol" ]) - def _handler_saline_bolus_data_sync(self, message): + def _handler_saline_bolus_data_sync(self, message, timestamp=0.0): """ Handles published saline bolus data messages. Saline bolus data are captured for reference. @@ -565,15 +578,17 @@ self.saline_bolus_max_vol = mxm[0] self.saline_bolus_cum_vol = cum[0] self.saline_bolus_bol_vol = bol[0] + self.hd_saline_bolus_timestamp = timestamp @publish([ + "hd_rinseback_progress_timestamp", "rinseback_tgt_vol", "rinseback_cum_vol", "rinseback_cur_rate", "rinseback_timeout_secs", "rinseback_countdown_secs" ]) - def _handler_rinseback_data_sync(self, message): + def _handler_rinseback_data_sync(self, message, timestamp=0.0): """ Handles published rinseback data (progress) messages. Rinseback data are captured for reference. @@ -598,12 +613,14 @@ self.rinseback_cur_rate = rat[0] self.rinseback_timeout_secs = tmo[0] self.rinseback_countdown_secs = cdn[0] + self.hd_rinseback_progress_timestamp = timestamp @publish([ + "hd_blood_prime_progress_timestamp", "blood_prime_tgt_vol", "blood_prime_cum_vol" ]) - def _handler_blood_prime_data_sync(self, message): + def _handler_blood_prime_data_sync(self, message, timestamp=0.0): """ Handles published blood prime data (progress) messages. Blood prime data are captured for reference. @@ -619,12 +636,14 @@ self.blood_prime_tgt_vol = tgt[0] self.blood_prime_cum_vol = cum[0] + self.hd_blood_prime_progress_timestamp = timestamp @publish([ + "hd_recirc_progress_timestamp", "recirc_timeout_secs", "recirc_countdown_secs" ]) - def _handler_recirculate_data_sync(self, message): + def _handler_recirculate_data_sync(self, message, timestamp=0.0): """ Handles published recirculate data (progress) messages. Recirculate data are captured for reference. @@ -640,9 +659,10 @@ self.recirc_timeout_secs = tmo[0] self.recirc_countdown_secs = cdn[0] + self.hd_recirc_progress_timestamp = timestamp - @publish(["treatment_stop_timeout_secs", "treatment_stop_timeout_countdown_secs"]) - def _handler_treatment_stop_timer_data_sync(self, message) -> None: + @publish(["hd_treatment_stop_timer_data_timestamp","treatment_stop_timeout_secs", "treatment_stop_timeout_countdown_secs"]) + def _handler_treatment_stop_timer_data_sync(self, message, timestamp=0.0) -> None: """ Handles published treatment stop progress data messages. @@ -657,15 +677,16 @@ self.treatment_stop_timeout_secs = tmo[0] self.treatment_stop_timeout_countdown_secs = cnd[0] + self.hd_treatment_stop_timer_data_timestamp = timestamp - @publish(["accepted", "current_blood_flow", "current_dialysate_flow", + @publish(["hd_res_current_treatment_parameters_timestamp", "accepted", "current_blood_flow", "current_dialysate_flow", "current_treatment_duration", "current_heparin_pre_stop", "current_saline_bolus_volume", "current_acid_concentrate", "current_bicarb_concentrate", "current_dialyzer_type", "current_heparin_type", "current_blood_pressure_measurement_interval", "current_rinseback_flow_rate", "current_arterial_low", "current_arterial_high", "current_venous_low", "current_venous_high", "current_heparin_bolus", "current_heparin_dispense", "current_dialysate_temp", "current_uf_volume"]) - def _handler_treatment_current_parameters(self, message) -> None: + def _handler_treatment_current_parameters(self, message, timestamp=0.0) -> None: """ Handles published current treatment parameters messages. @@ -733,6 +754,7 @@ self.current_heparin_dispense = hepdispense[0] self.current_dialysate_temp = dialtemp[0] self.current_uf_volume = ufvol[0] + self.hd_res_current_treatment_parameters_timestamp = timestamp def cmd_set_treatment_param_blood_flow_rate(self, flow: int) -> int: """ Index: dialin/hd/ui_proxy.py =================================================================== diff -u -r32001abdfb62770761771b563eb6ff517152fc76 -rcadb919bce9140638cae552306f374961833dafc --- dialin/hd/ui_proxy.py (.../ui_proxy.py) (revision 32001abdfb62770761771b563eb6ff517152fc76) +++ dialin/hd/ui_proxy.py (.../ui_proxy.py) (revision cadb919bce9140638cae552306f374961833dafc) @@ -159,6 +159,21 @@ MsgIds.MSG_ID_HD_DISINFECT_STANDBY_DATA.value, self._handler_disinfects_data_publish) + + self.hd_uf_settings_change_res_timestamp = 0.0 + self.hd_uf_settings_change_confirm_res_timestamp = 0.0 + self.hd_treatment_time_change_res_timestamp = 0.0 + self.hd_blood_dial_rate_change_res_timestamp = 0.0 + self.hd_treatment_param_change_ranges_res_timestamp = 0.0 + self.hd_version_res_timestamp = 0.0 + self.hd_new_treatment_params_timestamp = 0.0 + self.hd_new_treatment_params_res_timestamp = 0.0 + self.hd_saline_bolus_res_timestamp = 0.0 + self.hd_set_uf_volume_parameter_res_timestamp = 0.0 + self.hd_rinseback_cmd_res_timestamp = 0.0 + self.hd_recirc_res_timestamp = 0.0 + self.hd_tx_end_cmd_res_timestamp = 0.0 + self.hd_disinfection_standby_timestamp = 0.0 # initialize variables that will be populated by HD version response self.hd_version = None self.fpga_version = None @@ -445,10 +460,11 @@ return self.saline_bolus_request_bolus_volume @publish([ + "hd_version_res_timestamp" "hd_version", "fpga_version" ]) - def _handler_hd_version(self, message): + def _handler_hd_version(self, message, timestamp=0.0): """ Handler for response from HD regarding its version. @@ -485,11 +501,13 @@ if all([len(each) > 0 for each in [fpga_major, fpga_minor, fpga_id, fpga_lab]]): self.fpga_version = f"ID: {fpga_id[0]} v{fpga_major[0]}.{fpga_minor[0]}.{fpga_lab[0]}" self.logger.debug(f"HD FPGA VERSION: {self.fpga_version}") + self.hd_version_res_timestamp = timestamp @publish([ + "hd_new_treatment_params_timestamp", "treatment_parameters" ]) - def _handler_treatment_param_settings(self, message): + def _handler_treatment_param_settings(self, message, timestamp): """ Handler for UI msg containing user set treatment parameters. @@ -570,11 +588,13 @@ self.treatment_parameters[TreatmentParameters.TREATMENT_PARAM_HEPARIN_DISPENSE_RATE_ML_HR.value] = hdr[0] self.treatment_parameters[TreatmentParameters.TREATMENT_PARAM_HEPARIN_BOLUS_VOLUME_ML.value] = hbv[0] self.treatment_parameters[TreatmentParameters.TREATMENT_PARAM_DIALYSATE_TEMPERATURE_C.value] = tmp[0] + self.hd_new_treatment_params_timestamp = timestamp @publish([ + "hd_set_uf_volume_parameter_res_timestamp" "treatment_parameters" ]) - def _handler_uf_volume_setting_response(self, message): + def _handler_uf_volume_setting_response(self, message, timestamp=0.0): """ Handler for UI msg containing user set ultrafiltration volume parameter. @@ -586,12 +606,14 @@ tmp = struct.unpack('f', bytearray( message['message'][MsgFieldPositions.START_POS_FIELD_1:MsgFieldPositions.END_POS_FIELD_1])) self.treatment_parameters[TreatmentParameters.TREATMENT_PARAM_UF_VOLUME_L.value] = tmp[0] / 1000.0 + self.hd_set_uf_volume_parameter_res_timestamp = timestamp @publish([ + "hd_new_treatment_params_res_timestamp" "treatment_parameters_valid", "treatment_parameters_reject_reasons" ]) - def _handler_treatment_param_settings_response(self, message): + def _handler_treatment_param_settings_response(self, message, timestamp=0.0): """ Handler for response from HD regarding validation of treatment parameters. @@ -679,16 +701,18 @@ self.treatment_parameters_reject_reasons[TreatmentParameters.TREATMENT_PARAM_HEPARIN_DISPENSE_RATE_ML_HR.value] = hdr[0] self.treatment_parameters_reject_reasons[TreatmentParameters.TREATMENT_PARAM_HEPARIN_BOLUS_VOLUME_ML.value] = hbv[0] self.treatment_parameters_reject_reasons[TreatmentParameters.TREATMENT_PARAM_DIALYSATE_TEMPERATURE_C.value] = tmp[0] + self.hd_new_treatment_params_res_timestamp = timestamp @publish([ + "hd_treatment_param_change_ranges_res_timestamp", "min_treatment_duration_min", "max_treatment_duration_min", "min_uf_volume_ml", "max_uf_volume_ml", "min_dialysate_flow_rate_ml_min", "max_dialysate_flow_rate_ml_min" ]) - def _handler_treatment_param_ranges(self, message): + def _handler_treatment_param_ranges(self, message, timestamp=0.0): """ Handler for response from HD regarding valid treatment parameter ranges. @@ -721,13 +745,15 @@ self.max_uf_volume_ml = maxufvol[0] self.min_dialysate_flow_rate_ml_min = mindialrt[0] self.max_dialysate_flow_rate_ml_min = maxdialrt[0] + self.hd_treatment_param_change_ranges_res_timestamp = timestamp @publish([ + "hd_saline_bolus_res_timestamp", "saline_bolus_request_succeeded", "saline_bolus_request_reject_reason", "saline_bolus_request_bolus_volume" ]) - def _handler_saline_bolus_response(self, message): + def _handler_saline_bolus_response(self, message, timestamp=0.0): """ Handler for response from HD regarding saline bolus request. @@ -752,14 +778,16 @@ if RequestRejectReasons.has_value(rea[0]): self.saline_bolus_request_reject_reason = RequestRejectReasons(rea[0]) self.saline_bolus_request_bolus_volume = vol[0] + self.hd_saline_bolus_res_timestamp = timestamp @publish([ + "hd_treatment_time_change_res_timestamp", "duration_change_succeeded", "duration_change_reject_reason", "duration_change_time_min", "duration_change_uf_vol_ml" ]) - def _handler_treatment_duration_change_response(self, message): + def _handler_treatment_duration_change_response(self, message, timestamp=0.0): """ Handler for response from HD regarding treatment duration change request. @@ -785,14 +813,16 @@ self.duration_change_reject_reason = RequestRejectReasons(rea[0]) self.duration_change_time_min = tim[0] self.duration_change_uf_vol_ml = vol[0] + self.hd_treatment_time_change_res_timestamp = timestamp @publish([ + "hd_blood_dial_rate_change_res_timestamp", "blood_and_dialysate_flow_rate_change_succeeded", "blood_and_dialysate_flow_rate_change_reject_reason", "target_blood_flow_rate", "target_dialysate_flow_rate" ]) - def _handler_blood_and_dialysate_change_response(self, message): + def _handler_blood_and_dialysate_change_response(self, message, timestamp=0.0): """ Handler for response from HD regarding blood & dialysate flow rate change request. @@ -822,8 +852,10 @@ self.blood_and_dialysate_flow_rate_change_reject_reason = RequestRejectReasons(rea[0]) self.target_blood_flow_rate = bld[0] self.target_dialysate_flow_rate = dil[0] + self.hd_blood_dial_rate_change_res_timestamp = timestamp @publish([ + "hd_uf_settings_change_res_timestamp", "uf_change_succeeded", "uf_change_reject_reason", "uf_change_volume_ml", @@ -832,7 +864,7 @@ "uf_change_rate_ml_min", "uf_change_rate_diff" ]) - def _handler_uf_change_response(self, message): + def _handler_uf_change_response(self, message, timestamp=0.0): """ Handler for response from HD regarding UF change request. @@ -880,13 +912,15 @@ self.uf_change_rate_diff = rtd[0] self.uf_old_rate_ml_min = ort[0] + self.hd_uf_settings_change_res_timestamp = timestamp - @publish(["uf_change_succeeded", + @publish(["hd_uf_settings_change_confirm_res_timestamp", + "uf_change_succeeded", "uf_change_reject_reason", "uf_change_volume_ml", "uf_change_time_min", "uf_change_rate_ml_min"]) - def _handler_uf_change_confirm_response(self, message): + def _handler_uf_change_confirm_response(self, message, timestamp=0.0): """ Handler for response from HD regarding UF change confirmation. @@ -920,12 +954,14 @@ self.uf_change_volume_ml = vol[0] / self.LITER_TO_ML_CONVERSION_FACTOR self.uf_change_time_min = tim[0] self.uf_change_rate_ml_min = rat[0] + self.hd_uf_settings_change_confirm_res_timestamp = timestamp @publish([ + "hd_rinseback_cmd_res_timestamp", "rinseback_cmd_succeeded", "rinseback_cmd_reject_reason", ]) - def _handler_rinseback_cmd_response(self, message): + def _handler_rinseback_cmd_response(self, message, timestamp=0.0): """ Handler for response from HD regarding rinseback user command. @@ -946,12 +982,14 @@ self.rinseback_cmd_succeeded = False if RequestRejectReasons.has_value(rea[0]): self.rinseback_cmd_reject_reason = RequestRejectReasons(rea[0]) + self.hd_rinseback_cmd_res_timestamp = timestamp @publish([ + "hd_recirc_res_timestamp", "recirc_cmd_succeeded", "recirc_cmd_reject_reason", ]) - def _handler_recirc_cmd_response(self, message): + def _handler_recirc_cmd_response(self, message, timestamp=0.0): """ Handler for response from HD regarding recirculate user command. @@ -972,12 +1010,14 @@ self.recirc_cmd_succeeded = False if RequestRejectReasons.has_value(rea[0]): self.recirc_cmd_reject_reason = RequestRejectReasons(rea[0]) + self.hd_recirc_res_timestamp = timestamp @publish([ + "hd_tx_end_cmd_res_timestamp", "treatment_end_cmd_succeeded", "treatment_end_cmd_reject_reason", ]) - def _handler_treatment_end_cmd_response(self, message: dict) -> None: + def _handler_treatment_end_cmd_response(self, message: dict, timestamp=0.0) -> None: """ Handler for response from HD regarding treatment end user command. @@ -998,6 +1038,7 @@ self.treatment_end_cmd_succeeded = False if RequestRejectReasons.has_value(rea[0]): self.treatment_end_cmd_reject_reason = RequestRejectReasons(rea[0]) + self.hd_tx_end_cmd_res_timestamp = timestamp def cmd_ui_checkin_with_hd(self) -> None: """ @@ -1681,8 +1722,8 @@ self.logger.debug("Setting DG service time.") self.can_interface.send(message, 0) - @publish(["disinfects_hd_submode", "disinfects_dg_mode"]) - def _handler_disinfects_data_publish(self, message: dict) -> None: + @publish(["hd_disinfection_standby_timestamp","disinfects_hd_submode", "disinfects_dg_mode"]) + def _handler_disinfects_data_publish(self, message: dict, timestamp=0.0) -> None: """ Handles published disinfect mode and submode that is published to UI @@ -1697,3 +1738,4 @@ self.disinfects_hd_submode = hd_state self.disinfects_dg_mode = dg_submode + self.hd_disinfection_standby_timestamp = timestamp