Fisheye: Tag 3a57fe707c4cba4a4f3e3b2d4d22e43e38b562d1 refers to a dead (removed) revision in file `TD_TreatmentAdjustmentDuration/interface.ui'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 3a57fe707c4cba4a4f3e3b2d4d22e43e38b562d1 refers to a dead (removed) revision in file `TD_TreatmentAdjustmentDuration/loader.py'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 3a57fe707c4cba4a4f3e3b2d4d22e43e38b562d1 refers to a dead (removed) revision in file `TD_TreatmentAdjustmentSetPoints/interface.ui'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 3a57fe707c4cba4a4f3e3b2d4d22e43e38b562d1 refers to a dead (removed) revision in file `TD_TreatmentAdjustmentSetPoints/loader.py'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 3a57fe707c4cba4a4f3e3b2d4d22e43e38b562d1 refers to a dead (removed) revision in file `TD_TreatmentAdjustmentUltrafiltration/interface.ui'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 3a57fe707c4cba4a4f3e3b2d4d22e43e38b562d1 refers to a dead (removed) revision in file `TD_TreatmentAdjustmentUltrafiltration/loader.py'. Fisheye: No comparison available. Pass `N' to diff? Index: TD_TreatmentAdjustmentsBolusVolume/interface.ui =================================================================== diff -u -rf130aeba8b9749645bf7c1f8b00c68268ad3bbc0 -r3a57fe707c4cba4a4f3e3b2d4d22e43e38b562d1 --- TD_TreatmentAdjustmentsBolusVolume/interface.ui (.../interface.ui) (revision f130aeba8b9749645bf7c1f8b00c68268ad3bbc0) +++ TD_TreatmentAdjustmentsBolusVolume/interface.ui (.../interface.ui) (revision 3a57fe707c4cba4a4f3e3b2d4d22e43e38b562d1) @@ -22,7 +22,7 @@ - &3 Treatment/&6 Bolus Adjustments + &3 Treatment/Adjustments/&2 Bolus @@ -97,7 +97,7 @@ - 122 : [0x8000] : Bolus Volume Adjustments Req + 116 : [0x7400] : Bolus Volume Adjustments Req Qt::AlignCenter @@ -235,7 +235,7 @@ - 123 : [0x8100] : Bolus Volume Adjustments Rsp + 117 : [0x7500] : Bolus Volume Adjustments Rsp Qt::AlignCenter Index: TD_TreatmentAdjustmentsDuration/interface.ui =================================================================== diff -u --- TD_TreatmentAdjustmentsDuration/interface.ui (revision 0) +++ TD_TreatmentAdjustmentsDuration/interface.ui (revision 3a57fe707c4cba4a4f3e3b2d4d22e43e38b562d1) @@ -0,0 +1,801 @@ + + + ui_interface + + + + 0 + 0 + 428 + 411 + + + + + 100000 + 100000 + + + + + 10 + + + + &3 Treatment/Adjustments/&1 Duration + + + + 5 + + + 5 + + + 5 + + + 5 + + + 5 + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 2 + + + 2 + + + 2 + + + 2 + + + 2 + + + + + + + + 0 + 0 + + + + + 352 + 0 + + + + + 16777215 + 16777215 + + + + + 10 + + + + color: rgb(238, 238, 236); +background-color: rgb(92, 53, 102); + + + + 118 : [0x7600] : Duration Edit Request + + + Qt::AlignCenter + + + + + + + + 10 + + + + Reset + + + + + + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + 0 + 0 + + + + + 10 + + + + QFrame::Box + + + QFrame::Raised + + + -- + + + Qt::AlignCenter + + + + + + + Duration (min) + + + + + + + + + Qt::Vertical + + + + 0 + 0 + + + + + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 2 + + + 2 + + + 2 + + + 2 + + + 2 + + + + + + + color: rgb(238, 238, 236); +background-color: rgb(92, 53, 102); + + + + 120 : [0x7800] : Duration Confirm Request + + + Qt::AlignCenter + + + + + + + Reset + + + + + + + + + + + Duration (min) + + + + + + + + 0 + 0 + + + + QFrame::Box + + + QFrame::Sunken + + + -- + + + Qt::AlignCenter + + + + + + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 2 + + + 2 + + + 2 + + + 2 + + + 2 + + + + + + + color: rgb(238, 238, 236); +background-color: rgb(92, 53, 102); + + + + 121 : [0x7900] : Duration Confirm Response + + + Qt::AlignCenter + + + + + + + Send + + + + + + + Copy + + + + + + + Reset + + + + + + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + Rejection Reason + + + + + + + Qt::AlignCenter + + + 100 + + + + + + + Duration (min) + + + + + + + + + 540 + + + Qt::Horizontal + + + + + + + + 40 + 0 + + + + -- + + + Qt::AlignCenter + + + + + + + + + UF Volume Goal (mL) + + + + + + + + + 8000 + + + 10 + + + 100 + + + Qt::Horizontal + + + + + + + + 40 + 0 + + + + -- + + + Qt::AlignCenter + + + + + + + + + UF Rate (L/hr) + + + + + + + + + 2000 + + + 10 + + + 100 + + + Qt::Horizontal + + + + + + + + 40 + 0 + + + + -- + + + Qt::AlignCenter + + + + + + + + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 2 + + + 2 + + + 2 + + + 2 + + + 2 + + + + + + + + 10 + + + + color: rgb(238, 238, 236); +background-color: rgb(92, 53, 102); + + + + 119 : [0x7700] : Duration Edit Response + + + Qt::AlignCenter + + + + + + + + 10 + + + + Send + + + + + + + + 10 + + + + Copy + + + + + + + + 10 + + + + Reset + + + + + + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + 2 + + + 2 + + + + + + 10 + + + + Rejection Reason + + + + + + + + 10 + + + + Qt::AlignCenter + + + 100 + + + + + + + + 10 + + + + Duration (min) + + + + + + + UF Volume Goal (mL) + + + + + + + + + 8000 + + + 10 + + + 100 + + + Qt::Horizontal + + + + + + + + 0 + 0 + + + + + 40 + 0 + + + + -- + + + Qt::AlignCenter + + + + + + + + + + + 540 + + + Qt::Horizontal + + + + + + + + 40 + 0 + + + + -- + + + Qt::AlignCenter + + + + + + + + + UF Rate (L/hr) + + + + + + + + + 2000 + + + 10 + + + 100 + + + Qt::Horizontal + + + + + + + + 0 + 0 + + + + + 40 + 0 + + + + -- + + + Qt::AlignCenter + + + + + + + + + + + Qt::Vertical + + + + 0 + 0 + + + + + + + + + + + Qt::Vertical + + + + 0 + 0 + + + + + + + + + + color: rgb(238, 238, 236); +background-color: rgb(92, 53, 102); + + + + Duration Adjustment + + + Qt::AlignCenter + + + + + + + Reset + + + + + + + + + + Index: TD_TreatmentAdjustmentsDuration/loader.py =================================================================== diff -u --- TD_TreatmentAdjustmentsDuration/loader.py (revision 0) +++ TD_TreatmentAdjustmentsDuration/loader.py (revision 3a57fe707c4cba4a4f3e3b2d4d22e43e38b562d1) @@ -0,0 +1,217 @@ +""" + Treatment Adjustment Pressure Limits UI Loader +""" +# Python +import os +import can +import struct + +# Qt +from PySide2 import QtCore, QtWidgets +from PySide2.QtCore import Slot + +# parent +from engine.dynamicloader import DynamicLoader + +# plugin specific +from leahi_dialin.common.msg_defs import MsgIds, MsgFieldPositions +from leahi_dialin.protocols import CAN +from leahi_dialin.utils import conversions + +# TD simulator +from leahi_dialin.ui.td_messaging import TD_Messaging + +class Loader(DynamicLoader): + """ + Treatment Adjustment Pressure Limits UI Loader + """ + + def __init__(self): + self.td_interface = TD_Messaging() + self.can_interface = self.td_interface.can_interface + super().__init__(os.path.dirname(__file__)) + + if self.can_interface is not None: + self.can_interface.register_receiving_publication_function( + CAN.DenaliChannels.ui_to_td_ch_id, + MsgIds.MSG_ID_UI_DURATION_VALIDATE_REQUEST.value, + self.handle_duration_edit_request) + self.can_interface.register_receiving_publication_function( + CAN.DenaliChannels.ui_to_td_ch_id, + MsgIds.MSG_ID_UI_DURATION_CONFIRM_REQUEST.value, + self.handle_duration_confirm_request) + + + def _init_loader(self): + """ + finds and creates widgets + :return: none + """ + self.tbReset = self.find_widget(QtWidgets.QToolButton , 'tbReset' ) + + self.tbEditReqReset = self.find_widget(QtWidgets.QToolButton , 'tbEditReqReset' ) + self.lbEditReqDuration = self.find_widget(QtWidgets.QLabel , 'lbEditReqDuration' ) + self.tbEditRspSend = self.find_widget(QtWidgets.QToolButton , 'tbEditRspSend' ) + self.tbEditRspCopy = self.find_widget(QtWidgets.QToolButton , 'tbEditRspCopy' ) + self.tbEditRspReset = self.find_widget(QtWidgets.QToolButton , 'tbEditRspReset' ) + self.sbEditRspRejectionReason = self.find_widget(QtWidgets.QSpinBox , 'sbEditRspRejectionReason' ) + self.slEditRspDuration = self.find_widget(QtWidgets.QSlider , 'slEditRspDuration' ) + self.lbEditRspDuration = self.find_widget(QtWidgets.QLabel , 'lbEditRspDuration' ) + self.slEditRspUfVolumeGoal = self.find_widget(QtWidgets.QSlider , 'slEditRspUfVolumeGoal' ) + self.lbEditRspUfVolumeGoal = self.find_widget(QtWidgets.QLabel , 'lbEditRspUfVolumeGoal' ) + self.slEditRspUfRate = self.find_widget(QtWidgets.QSlider , 'slEditRspUfRate' ) + self.lbEditRspUfRate = self.find_widget(QtWidgets.QLabel , 'lbEditRspUfRate' ) + + self.tbConfirmReqReset = self.find_widget(QtWidgets.QToolButton , 'tbConfirmReqReset' ) + self.lbConfirmReqDuration = self.find_widget(QtWidgets.QLabel , 'lbConfirmReqDuration' ) + self.tbConfirmRspSend = self.find_widget(QtWidgets.QToolButton , 'tbConfirmRspSend' ) + self.tbConfirmRspCopy = self.find_widget(QtWidgets.QToolButton , 'tbConfirmRspCopy' ) + self.tbConfirmRspReset = self.find_widget(QtWidgets.QToolButton , 'tbConfirmRspReset' ) + self.sbConfirmRspRejectionReason = self.find_widget(QtWidgets.QSpinBox , 'sbConfirmRspRejectionReason' ) + self.slConfirmRspDuration = self.find_widget(QtWidgets.QSlider , 'slConfirmRspDuration' ) + self.lbConfirmRspDuration = self.find_widget(QtWidgets.QLabel , 'lbConfirmRspDuration' ) + self.slConfirmRspUfVolumeGoal = self.find_widget(QtWidgets.QSlider , 'slConfirmRspUfVolumeGoal' ) + self.lbConfirmRspUfVolumeGoal = self.find_widget(QtWidgets.QLabel , 'lbConfirmRspUfVolumeGoal' ) + self.slConfirmRspUfRate = self.find_widget(QtWidgets.QSlider , 'slConfirmRspUfRate' ) + self.lbConfirmRspUfRate = self.find_widget(QtWidgets.QLabel , 'lbConfirmRspUfRate' ) + + + def _init_connections(self): + """ + initializes the widgets connections + :return: none + """ + self.tbReset .clicked .connect(self._init_widgets ) + + self.tbEditReqReset .clicked .connect(self.init_edit_request ) + self.tbEditRspSend .clicked .connect(self.do_send_edit_response ) + self.tbEditRspCopy .clicked .connect(self.do_copy_edit_response ) + self.tbEditRspReset .clicked .connect(self.init_edit_response ) + self.slEditRspDuration .valueChanged .connect(lambda value: self.lbEditRspDuration.setText(f"{value}") ) + self.slEditRspUfVolumeGoal .valueChanged .connect(lambda value: self.lbEditRspUfVolumeGoal.setText(f"{value/1000:.2f}") ) + self.slEditRspUfRate .valueChanged .connect(lambda value: self.lbEditRspUfRate.setText(f"{value/1000:.2f}") ) + + self.tbConfirmReqReset .clicked .connect(self.init_confirm_request ) + self.tbConfirmRspSend .clicked .connect(self.do_send_confirm_response ) + self.tbConfirmRspCopy .clicked .connect(self.do_copy_confirm_response ) + self.tbConfirmRspReset .clicked .connect(self.init_confirm_response ) + self.slConfirmRspDuration .valueChanged .connect(lambda value: self.lbConfirmRspDuration.setText(f"{value}") ) + self.slConfirmRspUfVolumeGoal .valueChanged .connect(lambda value: self.lbConfirmRspUfVolumeGoal.setText(f"{value/1000:.2f}") ) + self.slConfirmRspUfRate .valueChanged .connect(lambda value: self.lbConfirmRspUfRate.setText(f"{value/1000:.2f}") ) + + + def _init_widgets(self): + """ + initializes the widgets' properties + :return: none + """ + self.init_edit_request() + self.init_edit_response() + self.init_confirm_request() + self.init_confirm_response() + + + @Slot() + def init_edit_request(self): + self.lbEditReqDuration.setText("--") + + + @Slot() + def handle_duration_edit_request(self, message, timestamp = 0.0): + """ + Called when the user requests duration edit from UI + @return: None + """ + message = message['message'] + index = MsgFieldPositions.START_POS_FIELD_1 + value,index = conversions.bytearray_to_integer(message, index) + self.lbEditReqDuration.setText(f"{value}") + + + @Slot() + def init_edit_response(self): + self.sbEditRspRejectionReason .setValue(0) + + self.slEditRspDuration .setValue(0) + self.lbEditRspDuration .setText("{0}".format(self.slEditRspDuration.value())) + self.slEditRspUfVolumeGoal .setValue(0) + self.lbEditRspUfVolumeGoal .setText("{0:.2f}".format(self.slEditRspUfVolumeGoal.value() / 1000)) + self.slEditRspUfRate .setValue(0) + self.lbEditRspUfRate .setText("{0:.2f}".format(self.slEditRspUfRate.value() / 1000)) + + + @Slot() + def do_send_edit_response(self): + """ + the slot for sending duration edit response + :return: none + """ + self.td_interface.td_duration_validate_response( + self.sbEditRspRejectionReason .value(), + self.slEditRspDuration .value(), + self.slEditRspUfVolumeGoal .value(), + self.slEditRspUfRate .value() / 1000 + ) + + + @Slot() + def do_copy_edit_response(self): + """ + the slot for copying duration edit request data to edit response + :return: none + """ + convert_to_int = lambda value : int(value) if value.isdigit() else 0 + self.slEditRspDuration.setValue(convert_to_int(self.lbEditReqDuration.text())) + + + @Slot() + def init_confirm_request(self): + self.lbConfirmReqDuration.setText("--") + + + @Slot() + def handle_duration_confirm_request(self, message, timestamp = 0.0): + """ + Called when the user requests duration confirm from UI + @return: None + """ + message = message['message'] + index = MsgFieldPositions.START_POS_FIELD_1 + value,index = conversions.bytearray_to_integer(message, index) + self.lbConfirmReqDuration.setText(f"{value}") + + + @Slot() + def init_confirm_response(self): + self.sbConfirmRspRejectionReason .setValue(0) + + self.slConfirmRspDuration .setValue(0) + self.lbConfirmRspDuration .setText("{0}".format(self.slConfirmRspDuration.value())) + self.slConfirmRspUfVolumeGoal .setValue(0) + self.lbConfirmRspUfVolumeGoal .setText("{0:.2f}".format(self.slConfirmRspUfVolumeGoal.value() / 1000)) + self.slConfirmRspUfRate .setValue(0) + self.lbConfirmRspUfRate .setText("{0:.2f}".format(self.slConfirmRspUfRate.value() / 1000)) + + + @Slot() + def do_send_confirm_response(self): + """ + the slot for sending duration confirm response + :return: none + """ + self.td_interface.td_duration_confirm_response( + self.sbConfirmRspRejectionReason .value(), + self.slConfirmRspDuration .value(), + self.slConfirmRspUfVolumeGoal .value(), + self.slConfirmRspUfRate .value() / 1000 + ) + + + @Slot() + def do_copy_confirm_response(self): + """ + the slot for copying duration confirm request data to confirm response + :return: none + """ + convert_to_int = lambda value : int(value) if value.isdigit() else 0 + self.slConfirmRspDuration.setValue(convert_to_int(self.lbConfirmReqDuration.text())) Index: TD_TreatmentAdjustmentsPressures/interface.ui =================================================================== diff -u -r99e021f300fcbdbd20a79762f9b94d234244b70f -r3a57fe707c4cba4a4f3e3b2d4d22e43e38b562d1 --- TD_TreatmentAdjustmentsPressures/interface.ui (.../interface.ui) (revision 99e021f300fcbdbd20a79762f9b94d234244b70f) +++ TD_TreatmentAdjustmentsPressures/interface.ui (.../interface.ui) (revision 3a57fe707c4cba4a4f3e3b2d4d22e43e38b562d1) @@ -22,7 +22,7 @@ - &3 Treatment/&7 Pressure Adjustments + &3 Treatment/Adjustments/&3 Pressure @@ -82,7 +82,7 @@ - 120 : [0x7800] : Pressure Adjustments Req + 114 : [0x7200] : Pressure Adjustments Req Qt::AlignCenter @@ -346,7 +346,7 @@ - 121 : [0x7900] : Pressure Adjustments Rsp + 115 : [0x7300] : Pressure Adjustments Rsp Qt::AlignCenter Index: TD_TreatmentAdjustmentsSetPoints/interface.ui =================================================================== diff -u --- TD_TreatmentAdjustmentsSetPoints/interface.ui (revision 0) +++ TD_TreatmentAdjustmentsSetPoints/interface.ui (revision 3a57fe707c4cba4a4f3e3b2d4d22e43e38b562d1) @@ -0,0 +1,1416 @@ + + + ui_interface + + + + 0 + 0 + 822 + 461 + + + + + 100000 + 100000 + + + + + 10 + + + + &3 Treatment/Adjustments/&5 Set Points + + + + 5 + + + 5 + + + 5 + + + 5 + + + 5 + + + + + 2 + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 2 + + + 2 + + + 2 + + + 2 + + + 2 + + + + + + + + 11 + + + + color: rgb(238, 238, 236); +background-color: rgb(92, 53, 102); + + + + Set Points + + + Qt::AlignCenter + + + + + + + Reset + + + + + + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + Blood Flow Rate + + + + + + + + + + 0 + 0 + + + + + 200 + 0 + + + + 600 + + + Qt::Horizontal + + + + + + + + 40 + 0 + + + + -- + + + Qt::AlignCenter + + + + + + + + + Dialysate Flow Rate + + + + + + + + + + 0 + 0 + + + + + 200 + 0 + + + + 700 + + + Qt::Horizontal + + + + + + + + 40 + 0 + + + + -- + + + Qt::AlignCenter + + + + + + + + + Dialysate Temperature + + + + + + + Acid Concentrate + + + + + + + Bicarb Concentrate + + + + + + + Qt::AlignCenter + + + + + + + Qt::AlignCenter + + + + + + + + + + 0 + 0 + + + + + 200 + 0 + + + + 400 + + + 1 + + + Qt::Horizontal + + + + + + + + 40 + 0 + + + + -- + + + Qt::AlignCenter + + + + + + + + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 2 + + + 2 + + + 2 + + + 2 + + + 2 + + + + + + + color: rgb(238, 238, 236); +background-color: rgb(92, 53, 102); + + + + 122 : [0x7A00] : Set Points Request + + + Qt::AlignCenter + + + + + + + Copy + + + + + + + Reset + + + + + + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + Blood Flow Rate (mL/min) + + + + + + + QFrame::Box + + + QFrame::Sunken + + + -- + + + Qt::AlignCenter + + + + + + + Dialysate Flow Rate (mL/min) + + + + + + + Dialysate Temperature (°C) + + + + + + + Acid Concentrate + + + + + + + Bicarb Concentrate + + + + + + + QFrame::Box + + + QFrame::Sunken + + + -- + + + Qt::AlignCenter + + + + + + + QFrame::Box + + + QFrame::Sunken + + + -- + + + Qt::AlignCenter + + + + + + + QFrame::Box + + + QFrame::Sunken + + + -- + + + Qt::AlignCenter + + + + + + + QFrame::Box + + + QFrame::Sunken + + + -- + + + Qt::AlignCenter + + + + + + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 2 + + + 2 + + + 2 + + + 2 + + + 2 + + + + + + + color: rgb(238, 238, 236); +background-color: rgb(92, 53, 102); + + + + 123 : [0x7B00] : Set Points Response + + + Qt::AlignCenter + + + + + + + Send + + + + + + + Reset + + + + + + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + Rejection Reason + + + + + + + Qt::AlignCenter + + + + + + + + + + + + Qt::Vertical + + + QSizePolicy::MinimumExpanding + + + + 0 + 0 + + + + + + + + + + 2 + + + + + + 0 + 0 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 2 + + + 2 + + + 2 + + + 2 + + + 2 + + + + + + + + 0 + 25 + + + + + 11 + + + + color: rgb(238, 238, 236); +background-color: rgb(92, 53, 102); + + + + Blood Flow Rate + + + Qt::AlignCenter + + + + + + + Reset + + + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 2 + + + 2 + + + 2 + + + 2 + + + 2 + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 2 + + + 2 + + + 2 + + + 2 + + + 2 + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + + 16777215 + 16777215 + + + + + 10 + + + + color: rgb(238, 238, 236); +background-color: rgb(92, 53, 102); + + + + 124 : [0x7C00] : Blood Flow Rate Request + + + Qt::AlignCenter + + + + + + + Copy + + + + + + + + 10 + + + + Reset + + + + + + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + 0 + 0 + + + + + 10 + + + + QFrame::Box + + + QFrame::Raised + + + -- + + + Qt::AlignCenter + + + + + + + Blood Flow Rate (mL/min) + + + + + + + + + + + + + + color: rgb(238, 238, 236); +background-color: rgb(92, 53, 102); + + + + 125 : [0x7D00] : Blood Flow Rate Response + + + Qt::AlignCenter + + + + + + + Send + + + + + + + Reset + + + + + + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + Rejection Reason + + + + + + + + 0 + 0 + + + + Qt::AlignCenter + + + 100 + + + + + + + + + + + + + + + + 0 + 0 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 2 + + + 2 + + + 2 + + + 2 + + + 2 + + + + + + + + 0 + 25 + + + + + 11 + + + + color: rgb(238, 238, 236); +background-color: rgb(92, 53, 102); + + + + Dialysate Flow Rate + + + Qt::AlignCenter + + + + + + + Reset + + + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 2 + + + 2 + + + 2 + + + 2 + + + 2 + + + + + + + color: rgb(238, 238, 236); +background-color: rgb(92, 53, 102); + + + + 126 : [0x7E00] : Dialysate Flow Rate Request + + + Qt::AlignCenter + + + + + + + Copy + + + + + + + Reset + + + + + + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + Dialysate Flow Rate (mL/min) + + + + + + + + 0 + 0 + + + + QFrame::Box + + + QFrame::Sunken + + + -- + + + Qt::AlignCenter + + + + + + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 2 + + + 2 + + + 2 + + + 2 + + + 2 + + + + + + + color: rgb(238, 238, 236); +background-color: rgb(92, 53, 102); + + + + 127 : [0x7F00] : Dialysate Flow Rate Response + + + Qt::AlignCenter + + + + + + + Send + + + + + + + Reset + + + + + + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + Rejection Reason + + + + + + + + 0 + 0 + + + + Qt::AlignCenter + + + + + + + + + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 2 + + + 2 + + + 2 + + + 2 + + + 2 + + + + + + + + 0 + 25 + + + + + 11 + + + + color: rgb(238, 238, 236); +background-color: rgb(92, 53, 102); + + + + Dialysate Temperature + + + Qt::AlignCenter + + + + + + + Reset + + + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 2 + + + 2 + + + 2 + + + 2 + + + 2 + + + + + + + color: rgb(238, 238, 236); +background-color: rgb(92, 53, 102); + + + + 128 : [0x8000] : Dialysate Temperature Request + + + Qt::AlignCenter + + + + + + + Copy + + + + + + + Reset + + + + + + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + Dialysate Temperature (°C) + + + + + + + + 0 + 0 + + + + QFrame::Box + + + QFrame::Sunken + + + -- + + + Qt::AlignCenter + + + + + + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 2 + + + 2 + + + 2 + + + 2 + + + 2 + + + + + + + color: rgb(238, 238, 236); +background-color: rgb(92, 53, 102); + + + + 129 : [0x8100] : Dialysate Temperature Response + + + Qt::AlignCenter + + + + + + + Send + + + + + + + Reset + + + + + + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + Rejection Reason + + + + + + + + 0 + 0 + + + + Qt::AlignCenter + + + + + + + + + + + + Qt::Vertical + + + QSizePolicy::MinimumExpanding + + + + 0 + 0 + + + + + + + + + + + Qt::Vertical + + + QSizePolicy::MinimumExpanding + + + + 0 + 0 + + + + + + + + + + + Index: TD_TreatmentAdjustmentsSetPoints/loader.py =================================================================== diff -u --- TD_TreatmentAdjustmentsSetPoints/loader.py (revision 0) +++ TD_TreatmentAdjustmentsSetPoints/loader.py (revision 3a57fe707c4cba4a4f3e3b2d4d22e43e38b562d1) @@ -0,0 +1,362 @@ +""" + Treatment Adjustment Pressure Limits UI Loader +""" +# Python +import os +import can +import struct + +# Qt +from PySide2 import QtCore, QtWidgets +from PySide2.QtCore import Slot + +# parent +from engine.dynamicloader import DynamicLoader + +# plugin specific +from leahi_dialin.common.msg_defs import MsgIds, MsgFieldPositions +from leahi_dialin.protocols import CAN +from leahi_dialin.utils import conversions + +# TD simulator +from leahi_dialin.ui.td_messaging import TD_Messaging + +class Loader(DynamicLoader): + """ + Treatment Adjustment Pressure Limits UI Loader + """ + + def __init__(self): + self.td_interface = TD_Messaging() + self.can_interface = self.td_interface.can_interface + super().__init__(os.path.dirname(__file__)) + + if self.can_interface is not None: + self.can_interface.register_receiving_publication_function( + CAN.DenaliChannels.ui_to_td_ch_id, + MsgIds.MSG_ID_UI_TREATMENT_SET_POINTS_CHANGE_REQUEST.value, + self.handle_set_points_change_request) + self.can_interface.register_receiving_publication_function( + CAN.DenaliChannels.ui_to_td_ch_id, + MsgIds.MSG_ID_UI_TREATMENT_SET_POINT_BLOOD_FLOW_CHANGE_REQUEST.value, + self.handle_blood_flow_change_request) + self.can_interface.register_receiving_publication_function( + CAN.DenaliChannels.ui_to_td_ch_id, + MsgIds.MSG_ID_UI_TREATMENT_SET_POINT_DIALYSATE_FLOW_CHANGE_REQUEST.value, + self.handle_dialysate_flow_change_request) + self.can_interface.register_receiving_publication_function( + CAN.DenaliChannels.ui_to_td_ch_id, + MsgIds.MSG_ID_UI_TREATMENT_SET_POINT_DIALYSATE_TEMPERATURE_CHANGE_REQUEST.value, + self.handle_dialysate_temperature_change_request) + + + def _init_loader(self): + """ + finds and creates widgets + :return: none + """ + self.tbSetPointsReset = self.find_widget(QtWidgets.QToolButton , 'tbSetPointsReset' ) + self.slSetPointsBloodFlowRate = self.find_widget(QtWidgets.QSlider , 'slSetPointsBloodFlowRate' ) + self.lbSetPointsBloodFlowRate = self.find_widget(QtWidgets.QLabel , 'lbSetPointsBloodFlowRate' ) + self.slSetPointsDialysateFlowRate = self.find_widget(QtWidgets.QSlider , 'slSetPointsDialysateFlowRate' ) + self.lbSetPointsDialysateFlowRate = self.find_widget(QtWidgets.QLabel , 'lbSetPointsDialysateFlowRate' ) + self.slSetPointsDialysateTemperature = self.find_widget(QtWidgets.QSlider , 'slSetPointsDialysateTemperature' ) + self.lbSetPointsDialysateTemperature = self.find_widget(QtWidgets.QLabel , 'lbSetPointsDialysateTemperature' ) + self.sbSetPointsAcidConcentrate = self.find_widget(QtWidgets.QSpinBox , 'sbSetPointsAcidConcentrate' ) + self.sbSetPointsBicarbConcentrate = self.find_widget(QtWidgets.QSpinBox , 'sbSetPointsBicarbConcentrate' ) + + self.tbSetPointsReqCopy = self.find_widget(QtWidgets.QToolButton , 'tbSetPointsReqCopy' ) + self.tbSetPointsReqReset = self.find_widget(QtWidgets.QToolButton , 'tbSetPointsReqReset' ) + self.lbSetPointsReqBloodFlowRate = self.find_widget(QtWidgets.QLabel , 'lbSetPointsReqBloodFlowRate' ) + self.lbSetPointsReqDialysateFlowRate = self.find_widget(QtWidgets.QLabel , 'lbSetPointsReqDialysateFlowRate' ) + self.lbSetPointsReqDialysateTemperature = self.find_widget(QtWidgets.QLabel , 'lbSetPointsReqDialysateTemperature' ) + self.lbSetPointsReqAcidConcentrate = self.find_widget(QtWidgets.QLabel , 'lbSetPointsReqAcidConcentrate' ) + self.lbSetPointsReqBicarbConcentrate = self.find_widget(QtWidgets.QLabel , 'lbSetPointsReqBicarbConcentrate' ) + + self.tbSetPointsRspSend = self.find_widget(QtWidgets.QToolButton , 'tbSetPointsRspSend' ) + self.tbSetPointsRspReset = self.find_widget(QtWidgets.QToolButton , 'tbSetPointsRspReset' ) + self.sbSetPointsRspRejectionReason = self.find_widget(QtWidgets.QSpinBox , 'sbSetPointsRspRejectionReason' ) + + self.tbBloodFlowRateReset = self.find_widget(QtWidgets.QToolButton , 'tbBloodFlowRateReset' ) + + self.tbBloodFlowRateReqCopy = self.find_widget(QtWidgets.QToolButton , 'tbBloodFlowRateReqCopy' ) + self.tbBloodFlowRateReqReset = self.find_widget(QtWidgets.QToolButton , 'tbBloodFlowRateReqReset' ) + self.lbBloodFlowRateReq = self.find_widget(QtWidgets.QLabel , 'lbBloodFlowRateReq' ) + + self.tbBloodFlowRateRspSend = self.find_widget(QtWidgets.QToolButton , 'tbBloodFlowRateRspSend' ) + self.tbBloodFlowRateRspReset = self.find_widget(QtWidgets.QToolButton , 'tbBloodFlowRateRspReset' ) + self.sbBloodFlowRateRspRejectionReason = self.find_widget(QtWidgets.QSpinBox , 'sbBloodFlowRateRspRejectionReason' ) + + self.tbDialysateFlowRateReset = self.find_widget(QtWidgets.QToolButton , 'tbDialysateFlowRateReset' ) + + self.tbDialysateFlowRateReqCopy = self.find_widget(QtWidgets.QToolButton , 'tbDialysateFlowRateReqCopy' ) + self.tbDialysateFlowRateReqReset = self.find_widget(QtWidgets.QToolButton , 'tbDialysateFlowRateReqReset' ) + self.lbDialysateFlowRateReq = self.find_widget(QtWidgets.QLabel , 'lbDialysateFlowRateReq' ) + + self.tbDialysateFlowRateRspSend = self.find_widget(QtWidgets.QToolButton , 'tbDialysateFlowRateRspSend' ) + self.tbDialysateFlowRateRspReset = self.find_widget(QtWidgets.QToolButton , 'tbDialysateFlowRateRspReset' ) + self.sbDialysateFlowRateRspRejectionReason = self.find_widget(QtWidgets.QSpinBox , 'sbDialysateFlowRateRspRejectionReason' ) + + self.tbDialysateTemperatureReset = self.find_widget(QtWidgets.QToolButton , 'tbDialysateTemperatureReset' ) + + self.tbDialysateTemperatureReqCopy = self.find_widget(QtWidgets.QToolButton , 'tbDialysateTemperatureReqCopy' ) + self.tbDialysateTemperatureReqReset = self.find_widget(QtWidgets.QToolButton , 'tbDialysateTemperatureReqReset' ) + self.lbDialysateTemperatureReq = self.find_widget(QtWidgets.QLabel , 'lbDialysateTemperatureReq' ) + + self.tbDialysateTemperatureRspSend = self.find_widget(QtWidgets.QToolButton , 'tbDialysateTemperatureRspSend' ) + self.tbDialysateTemperatureRspReset = self.find_widget(QtWidgets.QToolButton , 'tbDialysateTemperatureRspReset' ) + self.sbDialysateTemperatureRspRejectionReason = self.find_widget(QtWidgets.QSpinBox , 'sbDialysateTemperatureRspRejectionReason') + + + def _init_connections(self): + """ + initializes the widgets connections + :return: none + """ + self.tbSetPointsReset .clicked .connect(self.do_set_points_reset ) + self.slSetPointsBloodFlowRate .valueChanged .connect(lambda value: self.lbSetPointsBloodFlowRate.setText(f"{value}") ) + self.slSetPointsDialysateFlowRate .valueChanged .connect(lambda value: self.lbSetPointsDialysateFlowRate.setText(f"{value}") ) + self.slSetPointsDialysateTemperature .valueChanged .connect(lambda value: self.lbSetPointsDialysateTemperature.setText(f"{value/10:.1f}") ) + + self.tbSetPointsReqCopy .clicked .connect(self.do_set_points_request_copy ) + self.tbSetPointsReqReset .clicked .connect(self.do_set_points_request_reset ) + + self.tbSetPointsRspSend .clicked .connect(self.do_set_points_response_send ) + self.tbSetPointsRspReset .clicked .connect(self.do_set_points_response_reset ) + + self.tbBloodFlowRateReset .clicked .connect(self.do_blood_flow_rate_reset ) + + self.tbBloodFlowRateReqCopy .clicked .connect(self.do_blood_flow_rate_request_copy ) + self.tbBloodFlowRateReqReset .clicked .connect(self.do_blood_flow_rate_request_reset ) + + self.tbBloodFlowRateRspSend .clicked .connect(self.do_blood_flow_rate_response_send ) + self.tbBloodFlowRateRspReset .clicked .connect(self.do_blood_flow_rate_response_reset ) + + self.tbDialysateFlowRateReset .clicked .connect(self.do_dialysate_flow_rate_reset ) + + self.tbDialysateFlowRateReqCopy .clicked .connect(self.do_dialysate_flow_rate_request_copy ) + self.tbDialysateFlowRateReqReset .clicked .connect(self.do_dialysate_flow_rate_request_reset ) + + self.tbDialysateFlowRateRspSend .clicked .connect(self.do_dialysate_flow_rate_response_send ) + self.tbDialysateFlowRateRspReset .clicked .connect(self.do_dialysate_flow_rate_response_reset ) + + self.tbDialysateTemperatureReset .clicked .connect(self.do_dialysate_temperature_reset ) + + self.tbDialysateTemperatureReqCopy .clicked .connect(self.do_dialysate_temperature_request_copy ) + self.tbDialysateTemperatureReqReset .clicked .connect(self.do_dialysate_temperature_request_reset ) + + self.tbDialysateTemperatureRspSend .clicked .connect(self.do_dialysate_temperature_response_send ) + self.tbDialysateTemperatureRspReset .clicked .connect(self.do_dialysate_temperature_response_reset ) + + + def _init_widgets(self): + """ + initializes the widgets' properties + :return: none + """ + self.do_set_points_reset() + + + @Slot() + def do_set_points_reset(self): + self.slSetPointsBloodFlowRate .setValue ( 0 ) + self.lbSetPointsBloodFlowRate .setText ( "--" ) + self.slSetPointsDialysateFlowRate .setValue ( 0 ) + self.lbSetPointsDialysateFlowRate .setText ( "--" ) + self.slSetPointsDialysateTemperature .setValue ( 0 ) + self.lbSetPointsDialysateTemperature .setText ( "--" ) + self.sbSetPointsAcidConcentrate .setValue ( 0 ) + self.sbSetPointsBicarbConcentrate .setValue ( 0 ) + + self.do_set_points_request_reset() + self.do_set_points_response_reset() + + @Slot() + def do_set_points_request_copy(self): + self.slSetPointsBloodFlowRate .setValue ( self.convert_to_int ( self.lbSetPointsReqBloodFlowRate.text() ) ) + self.slSetPointsDialysateFlowRate .setValue ( self.convert_to_int ( self.lbSetPointsReqDialysateFlowRate.text() ) ) + self.slSetPointsDialysateTemperature .setValue ( self.convert_to_float ( self.lbSetPointsReqDialysateTemperature.text() ) * 10 ) + self.sbSetPointsAcidConcentrate .setValue ( self.convert_to_int ( self.lbSetPointsReqAcidConcentrate.text() ) ) + self.sbSetPointsBicarbConcentrate .setValue ( self.convert_to_int ( self.lbSetPointsReqBicarbConcentrate.text() ) ) + + @Slot() + def do_set_points_request_reset(self): + self.lbSetPointsReqBloodFlowRate .setText("--") + self.lbSetPointsReqDialysateFlowRate .setText("--") + self.lbSetPointsReqDialysateTemperature .setText("--") + self.lbSetPointsReqAcidConcentrate .setText("--") + self.lbSetPointsReqBicarbConcentrate .setText("--") + + + @Slot() + def handle_set_points_change_request(self, message, timestamp = 0.0): + """ + Called when the user requests set points change from UI + @return: None + """ + message = message['message'] + index = MsgFieldPositions.START_POS_FIELD_1 + param1,index = conversions.bytearray_to_integer (message, index) + param2,index = conversions.bytearray_to_integer (message, index) + param3,index = conversions.bytearray_to_float (message, index) + param4,index = conversions.bytearray_to_integer (message, index) + param5,index = conversions.bytearray_to_integer (message, index) + + self.lbSetPointsReqBloodFlowRate .setText( f"{param1}" ) + self.lbSetPointsReqDialysateFlowRate .setText( f"{param2}" ) + self.lbSetPointsReqDialysateTemperature .setText( f"{param3:.1f}" ) + self.lbSetPointsReqAcidConcentrate .setText( f"{param4}" ) + self.lbSetPointsReqBicarbConcentrate .setText( f"{param5}" ) + + + @Slot() + def do_set_points_response_send(self): + self.td_interface.td_treatment_set_points_change_response( + self.sbSetPointsRspRejectionReason .value() , + self.slSetPointsBloodFlowRate .value() , + self.slSetPointsDialysateFlowRate .value() , + self.slSetPointsDialysateTemperature .value() / 10 , + self.sbSetPointsAcidConcentrate .value() , + self.sbSetPointsBicarbConcentrate .value() + ) + + + @Slot() + def do_set_points_response_reset(self): + self.sbSetPointsRspRejectionReason .setValue(0) + + + @Slot() + def do_blood_flow_rate_reset(self): + self.do_blood_flow_rate_request_reset() + self.do_blood_flow_rate_response_reset() + + + @Slot() + def do_blood_flow_rate_request_copy(self): + self.slSetPointsBloodFlowRate.setValue(self.convert_to_int(self.lbBloodFlowRateReq.text())) + + + @Slot() + def do_blood_flow_rate_request_reset(self): + self.lbBloodFlowRateReq.setText("--") + + + @Slot() + def handle_blood_flow_change_request(self, message, timestamp = 0.0): + """ + Called when the user requests blood flow rate change from UI + @return: None + """ + message = message['message'] + index = MsgFieldPositions.START_POS_FIELD_1 + value,index = conversions.bytearray_to_integer(message, index) + self.lbBloodFlowRateReq.setText(f"{value}") + + + @Slot() + def do_blood_flow_rate_response_send(self): + self.td_interface.td_treatment_set_point_blood_flow_rate_change_response( + self.sbBloodFlowRateRspRejectionReason .value(), + self.slSetPointsBloodFlowRate .value() + ) + + + @Slot() + def do_blood_flow_rate_response_reset(self): + self.sbBloodFlowRateRspRejectionReason.setValue(0) + + + @Slot() + def do_dialysate_flow_rate_reset(self): + self.do_dialysate_flow_rate_request_reset() + self.do_dialysate_flow_rate_response_reset() + + + @Slot() + def do_dialysate_flow_rate_request_copy(self): + self.slSetPointsDialysateFlowRate.setValue(self.convert_to_int(self.lbDialysateFlowRateReq.text())) + + + @Slot() + def do_dialysate_flow_rate_request_reset(self): + self.lbDialysateFlowRateReq.setText("--") + + + @Slot() + def handle_dialysate_flow_change_request(self, message, timestamp = 0.0): + """ + Called when the user requests dialysate flow rate change from UI + @return: None + """ + message = message['message'] + index = MsgFieldPositions.START_POS_FIELD_1 + value,index = conversions.bytearray_to_integer (message, index) + self.lbDialysateFlowRateReq.setText(f"{value}") + + + @Slot() + def do_dialysate_flow_rate_response_send(self): + self.td_interface.td_treatment_set_point_dialysate_flow_rate_change_response( + self.sbDialysateFlowRateRspRejectionReason .value(), + self.slSetPointsDialysateFlowRate .value() + ) + + + @Slot() + def do_dialysate_flow_rate_response_reset(self): + self.sbDialysateFlowRateRspRejectionReason.setValue(0) + + + @Slot() + def do_dialysate_temperature_reset(self): + self.do_dialysate_temperature_request_reset() + self.do_dialysate_temperature_response_reset() + + + @Slot() + def do_dialysate_temperature_request_copy(self): + self.slSetPointsDialysateTemperature.setValue(self.convert_to_int(self.lbDialysateTemperatureReq.text()) * 10) + + + @Slot() + def do_dialysate_temperature_request_reset(self): + self.lbDialysateTemperatureReq.setText("--") + + + @Slot() + def handle_dialysate_temperature_change_request(self, message, timestamp = 0.0): + """ + Called when the user requests dialysate temperature change from UI + @return: None + """ + message = message['message'] + index = MsgFieldPositions.START_POS_FIELD_1 + value,index = conversions.bytearray_to_float(message, index) + self.lbDialysateTemperatureReq.setText(f"{value:.1f}") + + + @Slot() + def do_dialysate_temperature_response_send(self): + self.td_interface.td_treatment_set_point_dialysate_temperature_change_response( + self.sbDialysateTemperatureRspRejectionReason .value(), + self.slSetPointsDialysateTemperature .value() / 10 + ) + + + @Slot() + def do_dialysate_temperature_response_reset(self): + self.sbDialysateTemperatureRspRejectionReason.setValue(0) + + + def convert_to_float(self, value): + try: + return float(value) + except ValueError: + return 0.0 + + def convert_to_int(self, value): + try: + return int(value) + except ValueError: + return 0 Index: TD_TreatmentAdjustmentsUltrafiltration/interface.ui =================================================================== diff -u --- TD_TreatmentAdjustmentsUltrafiltration/interface.ui (revision 0) +++ TD_TreatmentAdjustmentsUltrafiltration/interface.ui (revision 3a57fe707c4cba4a4f3e3b2d4d22e43e38b562d1) @@ -0,0 +1,1450 @@ + + + ui_interface + + + + 0 + 0 + 920 + 467 + + + + + 100000 + 100000 + + + + &3 Treatment/Adjustments/&4 Ultrafiltration + + + + + + + + + 10 + + + + color: rgb(238, 238, 236); +background-color: rgb(92, 53, 102); + + + + Ultrafiltration + + + Qt::AlignCenter + + + + + + + Send + + + + + + + Reset + + + + + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 2 + + + 2 + + + 2 + + + 2 + + + 2 + + + + + + + + 0 + 0 + + + + + 352 + 0 + + + + + 10 + + + + color: rgb(238, 238, 236); +background-color: rgb(92, 53, 102); + + + 62 : [0x3E00] : Ultrafiltration Data + + + Qt::AlignCenter + + + + + + + Send + + + + + + + Reset + + + + + + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + Set Volume (L) + + + + + + + + + + 0 + 0 + + + + + 250 + 0 + + + + 1000 + + + Qt::Horizontal + + + + + + + + 0 + 0 + + + + + 40 + 0 + + + + + 10 + + + + 0.00 + + + Qt::AlignCenter + + + + + + + + + Target Rate (L/Hr) + + + + + + + + + + 0 + 0 + + + + + 250 + 0 + + + + 1000 + + + Qt::Horizontal + + + + + + + + 0 + 0 + + + + + 40 + 0 + + + + + 10 + + + + 0.00 + + + Qt::AlignCenter + + + + + + + + + Volume Delivered (L) + + + + + + + + + + 0 + 0 + + + + + 250 + 0 + + + + 800 + + + Qt::Horizontal + + + + + + + + 0 + 0 + + + + + 40 + 0 + + + + + 10 + + + + 0.00 + + + Qt::AlignCenter + + + + + + + + + State + + + + + + + + 0 + 0 + + + + Qt::AlignCenter + + + + + + + + + Qt::Vertical + + + + 0 + 0 + + + + + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 2 + + + 2 + + + 2 + + + 2 + + + 2 + + + + + + + + 10 + + + + color: rgb(238, 238, 236); +background-color: rgb(92, 53, 102); + + + 66: [0x4200]: Settings Change Response + + + Qt::AlignCenter + + + + + + + Send + + + + + + + Reset + + + + + + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + Req [0x4100] +Volume (mL) + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 10 + + + + QFrame::Box + + + QFrame::Raised + + + -- + + + Qt::AlignCenter + + + + + + + Response + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 10 + + + 5 + + + 2 + + + 5 + + + 2 + + + + + + 10 + + + + Accept + + + true + + + + + + + + 10 + + + + Reject + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + Reject Reason + + + + + + + Qt::AlignCenter + + + + + + + Volume (mL) + + + + + + + + + + 250 + 0 + + + + 8000 + + + Qt::Horizontal + + + + + + + + 0 + 0 + + + + + 50 + 0 + + + + + 10 + + + + 0.00 + + + Qt::AlignCenter + + + + + + + + + Duration (min) + + + + + + + + + + 250 + 0 + + + + 4800 + + + Qt::Horizontal + + + + + + + + 0 + 0 + + + + + 50 + 0 + + + + + 10 + + + + 0.00 + + + Qt::AlignCenter + + + + + + + + + Time Diff + + + + + + + + + + 250 + 0 + + + + 4800 + + + Qt::Horizontal + + + + + + + + 0 + 0 + + + + + 50 + 0 + + + + + 10 + + + + 0.00 + + + Qt::AlignCenter + + + + + + + + + Rate (L/Hr) + + + + + + + + + 2000 + + + Qt::Horizontal + + + + + + + + 0 + 0 + + + + + 50 + 0 + + + + + 10 + + + + 0.00 + + + Qt::AlignCenter + + + + + + + + + Rate Diff (L/Hr) + + + + + + + + + 2000 + + + Qt::Horizontal + + + + + + + + 0 + 0 + + + + + 50 + 0 + + + + + 10 + + + + 0.00 + + + Qt::AlignCenter + + + + + + + + + Old Rate (L/Hr) + + + + + + + + + 2000 + + + Qt::Horizontal + + + + + + + + 0 + 0 + + + + + 50 + 0 + + + + + 10 + + + + 0.00 + + + Qt::AlignCenter + + + + + + + + + + + Qt::Vertical + + + + 0 + 0 + + + + + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 2 + + + 2 + + + 2 + + + 2 + + + 2 + + + + + + + + 0 + 0 + + + + + 10 + + + + color: rgb(238, 238, 236); +background-color: rgb(92, 53, 102); + + + 72: [0x4800]: Pause/Resume Response + + + Qt::AlignCenter + + + + + + + Send + + + + + + + Reset + + + + + + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + Req [0x4700] + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 10 + + + + QFrame::Box + + + QFrame::Raised + + + -- + + + Qt::AlignCenter + + + + + + + Response + + + + + + + + 0 + 0 + + + + + 10 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 10 + + + 5 + + + 2 + + + 5 + + + 2 + + + + + + 10 + + + + Accept + + + true + + + + + + + + 10 + + + + Reject + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + Reject Reason + + + + + + + Qt::AlignCenter + + + + + + + + + Qt::Vertical + + + + 0 + 0 + + + + + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 2 + + + 2 + + + 2 + + + 2 + + + 2 + + + + + + + + 10 + + + + color: rgb(238, 238, 236); +background-color: rgb(92, 53, 102); + + + 103: [0x6700]: Confirm Response + + + Qt::AlignCenter + + + + + + + Send + + + + + + + Reset + + + + + + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + Req [0x6600] +Volume (mL) + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 10 + + + + QFrame::Box + + + QFrame::Raised + + + -- + + + Qt::AlignCenter + + + + + + + Response + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 10 + + + 5 + + + 2 + + + 5 + + + 2 + + + + + + 10 + + + + Accept + + + true + + + + + + + + 10 + + + + Reject + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + Reject Reason + + + + + + + Qt::AlignCenter + + + + + + + Volume (mL) + + + + + + + + + + 250 + 0 + + + + Qt::Horizontal + + + + + + + + 50 + 0 + + + + + 10 + + + + 0.00 + + + Qt::AlignCenter + + + + + + + + + Duration (min) + + + + + + + + + + 250 + 0 + + + + Qt::Horizontal + + + + + + + + 50 + 0 + + + + + 10 + + + + 0.00 + + + Qt::AlignCenter + + + + + + + + + Rate (L/Hr) + + + + + + + + + + 250 + 0 + + + + Qt::Horizontal + + + + + + + + 50 + 0 + + + + + 10 + + + + 0.00 + + + Qt::AlignCenter + + + + + + + + + + + Qt::Vertical + + + + 0 + 0 + + + + + + + + + + + + + allSendButton + allResetButton + + + + Index: TD_TreatmentAdjustmentsUltrafiltration/loader.py =================================================================== diff -u --- TD_TreatmentAdjustmentsUltrafiltration/loader.py (revision 0) +++ TD_TreatmentAdjustmentsUltrafiltration/loader.py (revision 3a57fe707c4cba4a4f3e3b2d4d22e43e38b562d1) @@ -0,0 +1,322 @@ +""" + TD Ultrafiltration UI Loader +""" +# Python +import os +import can +import struct + +# Qt +from PySide2 import QtCore, QtWidgets +from PySide2.QtCore import Slot + +# parent +from engine.dynamicloader import DynamicLoader + +# plugin specific +from leahi_dialin.common.msg_defs import MsgIds, MsgFieldPositions +from leahi_dialin.protocols import CAN +from leahi_dialin.utils import conversions + +from leahi_dialin.common.td_defs import TDOpModes +from leahi_dialin.common.td_defs import TDStandbyStates + +# hd Simulator +from leahi_dialin.ui.td_messaging import TD_Messaging + +class Loader(DynamicLoader): + """ + TD Ultrafiltration UI Loader + """ + + def __init__(self): + self.td_interface = TD_Messaging() + self.can_interface = self.td_interface.can_interface + super().__init__(os.path.dirname(__file__)) + + if self.can_interface is not None: + self.can_interface.register_receiving_publication_function( + CAN.DenaliChannels.ui_to_td_ch_id, + MsgIds.MSG_ID_UI_UF_PAUSE_RESUME_REQUEST.value, + self.handle_pause_resume_request) + self.can_interface.register_receiving_publication_function( + CAN.DenaliChannels.ui_to_td_ch_id, + MsgIds.MSG_ID_UI_ULTRAFILTRATION_VOLUME_TO_VALIDATE.value, + self.handle_settings_change_request) + self.can_interface.register_receiving_publication_function( + CAN.DenaliChannels.ui_to_td_ch_id, + MsgIds.MSG_ID_USER_CONFIRM_UF_SETTINGS_CHANGE_REQUEST.value, + self.handle_confirm_request) + + def _init_loader(self): + """ + finds and creates widgets + :return: none + """ + self.uf_scaling = 100.00 # UF Scaling factor to be 2 decimal places + + self.allSend = self.find_widget(QtWidgets.QToolButton , 'allSendButton' ) + self.allReset = self.find_widget(QtWidgets.QToolButton , 'allResetButton' ) + + self.ufDataSend = self.find_widget(QtWidgets.QToolButton, 'ufDataSendButton' ) + self.ufDataReset = self.find_widget(QtWidgets.QToolButton, 'ufDataResetButton' ) + self.ufSetVolume = self.find_widget(QtWidgets.QSlider , 'ufSetVolumeSlider' ) + self.ufTargetRate = self.find_widget(QtWidgets.QSlider , 'ufTargetRateSlider' ) + self.ufVolumeDelivered = self.find_widget(QtWidgets.QSlider , 'ufVolumeDeliveredSlider' ) + self.ufState = self.find_widget(QtWidgets.QSpinBox , 'ufStateSpinBox' ) + self.ufSetVolumeLabel = self.find_widget(QtWidgets.QLabel , 'ufSetVolumeLabel' ) + self.ufTargetRateLabel = self.find_widget(QtWidgets.QLabel , 'ufTargetRateLabel' ) + self.ufVolumeDeliveredLabel = self.find_widget(QtWidgets.QLabel , 'ufVolumeDeliveredLabel' ) + + self.prSend = self.find_widget(QtWidgets.QToolButton , 'prSendButton' ) + self.prReset = self.find_widget(QtWidgets.QToolButton , 'prResetButton' ) + self.prRequestLabel = self.find_widget(QtWidgets.QLabel , 'prRequestLabel' ) + self.prAccepted = self.find_widget(QtWidgets.QRadioButton , 'prAcceptRadioButton' ) + self.prRejectReason = self.find_widget(QtWidgets.QSpinBox , 'prRejectReasonSpinBox' ) + + self.changeSend = self.find_widget(QtWidgets.QToolButton , 'changeSendButton' ) + self.changeReset = self.find_widget(QtWidgets.QToolButton , 'changeResetButton' ) + self.changeRequestLabel = self.find_widget(QtWidgets.QLabel , 'changeRequestLabel' ) + self.changeAccepted = self.find_widget(QtWidgets.QRadioButton , 'changeAcceptRadioButton' ) + self.changeRejectReason = self.find_widget(QtWidgets.QSpinBox , 'changeRejectReasonSpinBox' ) + self.changeVolume = self.find_widget(QtWidgets.QSlider , 'changeVolumeSlider' ) + self.changeVolumeLabel = self.find_widget(QtWidgets.QLabel , 'changeVolumeLabel' ) + self.changeDuration = self.find_widget(QtWidgets.QSlider , 'changeDurationSlider' ) + self.changeDurationLabel = self.find_widget(QtWidgets.QLabel , 'changeDurationLabel' ) + self.changeTimeDiff = self.find_widget(QtWidgets.QSlider , 'changeTimeDiffSlider' ) + self.changeTimeDiffLabel = self.find_widget(QtWidgets.QLabel , 'changeTimeDiffLabel' ) + self.changeRate = self.find_widget(QtWidgets.QSlider , 'changeRateSlider' ) + self.changeRateLabel = self.find_widget(QtWidgets.QLabel , 'changeRateLabel' ) + self.changeRateDiff = self.find_widget(QtWidgets.QSlider , 'changeRateDiffSlider' ) + self.changeRateDiffLabel = self.find_widget(QtWidgets.QLabel , 'changeRateDiffLabel' ) + self.changeOldRate = self.find_widget(QtWidgets.QSlider , 'changeOldRateSlider' ) + self.changeOldRateLabel = self.find_widget(QtWidgets.QLabel , 'changeOldRateLabel' ) + + self.confirmSend = self.find_widget(QtWidgets.QToolButton , 'confirmSendButton' ) + self.confirmReset = self.find_widget(QtWidgets.QToolButton , 'confirmResetButton' ) + self.confirmRequestLabel = self.find_widget(QtWidgets.QLabel , 'confirmRequestLabel' ) + self.confirmAccepted = self.find_widget(QtWidgets.QRadioButton , 'confirmAcceptRadioButton' ) + self.confirmRejectReason = self.find_widget(QtWidgets.QSpinBox , 'confirmRejectReasonSpinBox' ) + self.confirmVolume = self.find_widget(QtWidgets.QSlider , 'confirmVolumeSlider' ) + self.confirmVolumeLabel = self.find_widget(QtWidgets.QLabel , 'confirmVolumeLabel' ) + self.confirmDuration = self.find_widget(QtWidgets.QSlider , 'confirmDurationSlider' ) + self.confirmDurationLabel = self.find_widget(QtWidgets.QLabel , 'confirmDurationLabel' ) + self.confirmRate = self.find_widget(QtWidgets.QSlider , 'confirmRateSlider' ) + self.confirmRateLabel = self.find_widget(QtWidgets.QLabel , 'confirmRateLabel' ) + + def _init_connections(self): + """ + initializes the widgets connections + :return: none + """ + self.allReset .clicked.connect(self._init_widgets) + self.allSend .clicked.connect(self.do_all_tx_data) + + self.ufDataSend .clicked.connect(self.do_uf_data) + self.ufDataReset .clicked.connect(self.init_uf_data) + self.ufSetVolume .valueChanged.connect(self.do_uf_data) + self.ufTargetRate .valueChanged.connect(self.do_uf_data) + self.ufVolumeDelivered .valueChanged.connect(self.do_uf_data) + self.ufState .valueChanged.connect(self.do_uf_data) + + self.prSend.clicked.connect(self.do_pause_resume) + self.prReset.clicked.connect(self.init_pause_resume) + + self.changeSend.clicked.connect(self.do_settings_change) + self.changeReset.clicked.connect(self.init_settings_change) + self.changeVolume.valueChanged.connect(lambda value: self.changeVolumeLabel.setText(f"{value/1000:.2f}")) + self.changeDuration.valueChanged.connect(lambda value: self.changeDurationLabel.setText(f"{value}")) + self.changeTimeDiff.valueChanged.connect(lambda value: self.changeTimeDiffLabel.setText(f"{value}")) + self.changeRate.valueChanged.connect(lambda value: self.changeRateLabel.setText(f"{value/1000:.2f}")) + self.changeRateDiff.valueChanged.connect(lambda value: self.changeRateDiffLabel.setText(f"{value/1000:.2f}")) + self.changeOldRate.valueChanged.connect(lambda value: self.changeOldRateLabel.setText(f"{value/1000:.2f}")) + + self.confirmSend.clicked.connect(self.do_confirm) + self.confirmReset.clicked.connect(self.init_confirm) + self.confirmVolume.valueChanged.connect(lambda value: self.confirmVolumeLabel.setText(f"{value/1000:.2f}")) + self.confirmDuration.valueChanged.connect(lambda value: self.confirmDurationLabel.setText(f"{value}")) + self.confirmRate.valueChanged.connect(lambda value: self.confirmRateLabel.setText(f"{value/1000:.2f}")) + + @Slot() + def _init_widgets(self): + """ + initializes the widgets' properties + :return: none + """ + self.init_uf_data() + self.init_settings_change() + self.init_pause_resume() + self.init_confirm() + + @Slot() + def init_uf_data(self): + """ + slot for initializing UF settings change + :return: none + """ + self.ufSetVolume .setValue(0) + self.ufTargetRate .setValue(0) + self.ufVolumeDelivered .setValue(0) + self.ufState .setValue(0) + + @Slot() + def do_uf_data(self): + """ + the slot for UF Data + :return: none + """ + set_volume = self.ufSetVolume .value() / self.uf_scaling + target_rate = self.ufTargetRate .value() / self.uf_scaling + volume_delivered = self.ufVolumeDelivered.value() / self.uf_scaling + state = self.ufState .value() + + self.ufSetVolumeLabel .setText(f"{set_volume:.2f}" ) + self.ufTargetRateLabel .setText(f"{target_rate:.2f}" ) + self.ufVolumeDeliveredLabel .setText(f"{volume_delivered:.2f}" ) + + self.td_interface.td_ultrafiltration( + set_volume , + target_rate , + volume_delivered , + state + ) + + @Slot() + def init_settings_change(self): + """ + slot for initializing UF settings change + :return: none + """ + self.changeRequestLabel .setText("--") + self.changeAccepted .setChecked(True) + self.changeRejectReason .setValue(0) + self.changeVolume .setValue(0) + self.changeDuration .setValue(0) + self.changeTimeDiff .setValue(0) + self.changeRate .setValue(0) + self.changeRateDiff .setValue(0) + self.changeOldRate .setValue(0) + + @Slot() + def handle_settings_change_request(self, message, timestamp = 0.0): + """ + Called when the user requests UF settings change to firmware from UI + @return: None + """ + message = message['message'] + index = MsgFieldPositions.START_POS_FIELD_1 + value,index = conversions.bytearray_to_float(message, index) + self.changeRequestLabel.setText(f"{value:.0f}") + + @Slot() + def do_settings_change(self): + """ + slot for UF settings change + :return: none + """ + payload = conversions.integer_to_bytearray(int(1 if self.changeAccepted.isChecked() else 0)) + payload += conversions.integer_to_bytearray(self.changeRejectReason.value()) + payload += conversions.float_to_bytearray(self.changeVolume.value()) + payload += conversions.integer_to_bytearray(self.changeDuration.value()) + payload += conversions.integer_to_bytearray(self.changeTimeDiff.value()) + payload += conversions.float_to_bytearray(self.changeRate.value()/1000) + payload += conversions.float_to_bytearray(self.changeRateDiff.value()/1000) + payload += conversions.float_to_bytearray(self.changeOldRate.value()/1000) + + self.td_interface.cmd_send_general_response( + message_id = MsgIds.MSG_ID_TD_RESP_ULTRAFILTRATION_VOLUME_TO_VALIDATE.value, + accepted = 1 if self.changeAccepted.isChecked() else 0, + reason = self.changeRejectReason.value(), + is_pure_data = False, + has_parameters = True, + parameters_payload = payload + ) + + @Slot() + def init_pause_resume(self): + """ + slot for initializing UF pause/resume + :return: none + """ + self.prRequestLabel .setText("--") + self.prAccepted .setChecked(True) + self.prRejectReason .setValue(0) + + @Slot() + def handle_pause_resume_request(self, message, timestamp = 0.0): + """ + Called when the user requests pause/resume to firmware from UI + @return: None + """ + message = message['message'] + index = MsgFieldPositions.START_POS_FIELD_1 + state,index = conversions.bytearray_to_integer(message, index) + self.prRequestLabel.setText(f"Resume({state})" if state else f"Pause({state})") + + @Slot() + def do_pause_resume(self): + """ + slot for UF pause/resume + :return: none + """ + self.td_interface.cmd_send_general_response( + message_id = MsgIds.MSG_ID_TD_UF_PAUSE_RESUME_RESPONSE.value, + accepted = 1 if self.prAccepted.isChecked() else 0, + reason = self.prRejectReason.value() + ) + + @Slot() + def init_confirm(self): + """ + slot for initializing UF confirm + :return: none + """ + self.confirmRequestLabel .setText("--") + self.confirmAccepted .setChecked(True) + self.confirmRejectReason .setValue(0) + self.confirmVolume .setValue(0) + self.confirmDuration .setValue(0) + self.confirmRate .setValue(0) + + @Slot() + def handle_confirm_request(self, message, timestamp = 0.0): + """ + Called when the user requests confirm to firmware from UI + @return: None + """ + message = message['message'] + index = MsgFieldPositions.START_POS_FIELD_1 + value,index = conversions.bytearray_to_float(message, index) + self.confirmRequestLabel.setText(f"{value:.0f}") + + @Slot() + def do_confirm(self): + """ + slot for UF confirm + :return: none + """ + payload = conversions.integer_to_bytearray(int(1 if self.confirmAccepted.isChecked() else 0)) + payload += conversions.integer_to_bytearray(self.confirmRejectReason.value()) + payload += conversions.float_to_bytearray(self.confirmVolume.value()) + payload += conversions.integer_to_bytearray(self.confirmDuration.value()) + payload += conversions.float_to_bytearray(self.confirmRate.value()/1000) + + self.td_interface.cmd_send_general_response( + message_id = MsgIds.MSG_ID_USER_UF_SETTINGS_CHANGE_CONFIRMATION_RESPONSE.value, + accepted = 1 if self.confirmAccepted.isChecked() else 0, + reason = self.confirmRejectReason.value(), + is_pure_data = False, + has_parameters = True, + parameters_payload = payload + ) + + @Slot() + def do_all_tx_data(self): + """ + slot for treatment set point Data + :return: none + """ + self.do_uf_data() + self.do_settings_change() + self.do_pause_resume() + self.do_confirm()