Index: Trends/interface.ui =================================================================== diff -u --- Trends/interface.ui (revision 0) +++ Trends/interface.ui (revision 6b323acc7945c5d5b672d61d8a5d1633fa3aac64) @@ -0,0 +1,1423 @@ + + + ui_interface + + + + 0 + 0 + 981 + 550 + + + + + 100000 + 100000 + + + + &Trends/&1 Trends + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 2 + + + 2 + + + 2 + + + 2 + + + + + + + + 10 + + + + color: rgb(238, 238, 236); +background-color: rgb(92, 53, 102); + + + 100 : [0x6400] : Vitals Response + + + Qt::AlignCenter + + + + + + + Send + + + + + + + Reset + + + + + + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + Response + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 10 + + + 5 + + + 2 + + + 5 + + + 2 + + + + + + 10 + + + + Accept + + + true + + + + + + + + 10 + + + + Reject + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + Reject Reason + + + + + + + Qt::AlignCenter + + + + + + + Req : 99 : [0x6300] + + + + + + + QFrame::Box + + + QFrame::Raised + + + -- + + + Qt::AlignCenter + + + + + + + + + Qt::Vertical + + + + 20 + 0 + + + + + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 2 + + + 2 + + + 2 + + + 2 + + + + + + + + 10 + + + + color: rgb(238, 238, 236); +background-color: rgb(92, 53, 102); + + + + Trends Data + + + 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 + + + + + Target Rate (L/Hr) + + + + + + + + + + 0 + 0 + + + + + 200 + 0 + + + + 1000 + + + Qt::Horizontal + + + + + + + + 0 + 0 + + + + + 40 + 0 + + + + + 10 + + + + 0.00 + + + Qt::AlignCenter + + + + + + + + + Volume Delivered (L) + + + + + + + + + + 0 + 0 + + + + + 200 + 0 + + + + 800 + + + Qt::Horizontal + + + + + + + + 0 + 0 + + + + + 40 + 0 + + + + + 10 + + + + 0.00 + + + 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); + + + 36 : [0x2400] : Pressure Data + + + Qt::AlignCenter + + + + + + + Send + + + + + + + Reset + + + + + + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + Arterial (mmHg) + + + + + + + + + + 200 + 0 + + + + -400 + + + 200 + + + Qt::Horizontal + + + + + + + + 0 + 0 + + + + + 50 + 0 + + + + + 10 + + + + 0 + + + Qt::AlignCenter + + + + + + + + + Venous (mmHg) + + + + + + + + + + 200 + 0 + + + + -100 + + + 500 + + + Qt::Horizontal + + + + + + + + 0 + 0 + + + + + 50 + 0 + + + + + 10 + + + + 0 + + + Qt::AlignCenter + + + + + + + + + TMP (mmHg) + + + + + + + + + + 200 + 0 + + + + -640 + + + 250 + + + Qt::Horizontal + + + + + + + + 0 + 0 + + + + + 50 + 0 + + + + + 10 + + + + 0 + + + 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); + + + 31 : [0x1F00] : DD Conductivity + + + Qt::AlignCenter + + + + + + + Send + + + + + + + Reset + + + + + + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + (D29) Acid & Bicarb +Cond 2 (mS/cm) + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + 250 + 0 + + + + 10000 + + + Qt::Horizontal + + + + + + + + 40 + 0 + + + + + 10 + + + + 0.0 + + + 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); + + + 101 : [0x6500] : Blood Pressure Data + + + Qt::AlignCenter + + + + + + + Send + + + + + + + Reset + + + + + + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + Systolic (mmHg) + + + + + + + Qt::AlignCenter + + + 300 + + + + + + + Diastolic (mmHg) + + + + + + + Qt::AlignCenter + + + 200 + + + + + + + Heart Rate (bpm) + + + + + + + Qt::AlignCenter + + + 300 + + + + + + + + + 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); + + + 61 : [0x3D00] : Saline Bolus + + + Qt::AlignCenter + + + + + + + Send + + + + + + + Reset + + + + + + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + Cumulative Fluid +Delivered (mL) + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + 200 + 0 + + + + 10000 + + + Qt::Horizontal + + + + + + + + 0 + 0 + + + + + 40 + 0 + + + + + 10 + + + + 0 + + + Qt::AlignCenter + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 2 + + + 2 + + + 2 + + + 2 + + + 2 + + + + + + + color: rgb(238, 238, 236); +background-color: rgb(92, 53, 102); + + + 79 : [0x4F00] : Set Point Data + + + Qt::AlignCenter + + + + + + + Send + + + + + + + Reset + + + + + + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + Blood Flow (mL/min) + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + 250 + 0 + + + + 900 + + + Qt::Horizontal + + + + + + + + 40 + 0 + + + + + 10 + + + + 0 + + + Qt::AlignCenter + + + + + + + + + Dialysate Flow (mL/min) + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + 250 + 0 + + + + 900 + + + Qt::Horizontal + + + + + + + + 40 + 0 + + + + + 10 + + + + 0 + + + Qt::AlignCenter + + + + + + + + + Dialysate Temp(°C) + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + 250 + 0 + + + + 1000 + + + Qt::Horizontal + + + + + + + + 40 + 0 + + + + + 10 + + + + 0.0 + + + Qt::AlignCenter + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + + + + tbTrendsDataSend + tbTrendsDataReset + + + + Index: Trends/loader.py =================================================================== diff -u --- Trends/loader.py (revision 0) +++ Trends/loader.py (revision 6b323acc7945c5d5b672d61d8a5d1633fa3aac64) @@ -0,0 +1,377 @@ +""" + Trends UI Loader +""" +# Python +import os +import can +import struct + +# Qt +from PySide2 import QtCore, QtWidgets +from PySide2.QtCore import Slot, QTime + +# 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 + +# td simulator +from leahi_dialin.ui.td_messaging import TD_Messaging + +# dd simulator +from leahi_dialin.ui.dd_messaging import DD_Messaging + +class Loader(DynamicLoader): + """ + Trends UI Loader + """ + + def __init__(self): + self.td_interface = TD_Messaging() + self.dd_interface = DD_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_BLOOD_PRESSURE_REQUEST.value, + self.handle_vitals_request) + + + def _init_loader(self): + """ + finds and creates widgets + :return: none + """ + self.vitalsRspSend = self.find_widget(QtWidgets.QToolButton , 'tbVitalsRspSend' ) + self.vitalsRspReset = self.find_widget(QtWidgets.QToolButton , 'tbVitalsRspReset' ) + self.vitalsReqTime = self.find_widget(QtWidgets.QLabel , 'lbVitalsReqTime' ) + self.vitalsRspAccept = self.find_widget(QtWidgets.QRadioButton , 'rbVitalsRspAccept' ) + self.vitalsRspReject = self.find_widget(QtWidgets.QRadioButton , 'rbVitalsRspReject' ) + self.vitalsRspRejectReason = self.find_widget(QtWidgets.QSpinBox , 'sbVitalsRspRejectReason' ) + + self.trendsSend = self.find_widget(QtWidgets.QToolButton, 'tbTrendsDataSend' ) + self.trendsReset = self.find_widget(QtWidgets.QToolButton, 'tbTrendsDataReset' ) + + self.vitalsSend = self.find_widget(QtWidgets.QToolButton , 'tbVitalsDataSend' ) + self.vitalsReset = self.find_widget(QtWidgets.QToolButton , 'tbVitalsDataReset' ) + self.vitalsSystolic = self.find_widget(QtWidgets.QSpinBox , 'sbVitalsSystolic' ) + self.vitalsDiastolic = self.find_widget(QtWidgets.QSpinBox , 'sbVitalsDiastolic' ) + self.vitalsHeartRate = self.find_widget(QtWidgets.QSpinBox , 'sbVitalsHeartRate' ) + + self.ufSend = self.find_widget(QtWidgets.QToolButton, 'tbUfSend' ) + self.ufReset = self.find_widget(QtWidgets.QToolButton, 'tbUfReset' ) + self.ufTargetRate = self.find_widget(QtWidgets.QSlider , 'slUfTargetRate' ) + self.ufVolumeDelivered = self.find_widget(QtWidgets.QSlider , 'slUfVolumeDelivered' ) + self.ufTargetRateLabel = self.find_widget(QtWidgets.QLabel , 'lbUfTargetRate' ) + self.ufVolumeDeliveredLabel = self.find_widget(QtWidgets.QLabel , 'lbUfVolumeDelivered' ) + + self.pressureSend = self.find_widget(QtWidgets.QToolButton, 'tbPressureSend' ) + self.pressureReset = self.find_widget(QtWidgets.QToolButton, 'tbPressureReset' ) + self.pressureArterial = self.find_widget(QtWidgets.QSlider , 'slPressureArterial' ) + self.pressureArterialLabel = self.find_widget(QtWidgets.QLabel , 'lbPressureArterial' ) + self.pressureVenous = self.find_widget(QtWidgets.QSlider , 'slPressureVenous' ) + self.pressureVenousLabel = self.find_widget(QtWidgets.QLabel , 'lbPressureVenous' ) + self.pressureTMP = self.find_widget(QtWidgets.QSlider , 'slPressureTMP' ) + self.pressureTMPLabel = self.find_widget(QtWidgets.QLabel , 'lbPressureTMP' ) + + self.salineSend = self.find_widget(QtWidgets.QToolButton, 'tbSalineSend' ) + self.salineReset = self.find_widget(QtWidgets.QToolButton, 'tbSalineReset' ) + self.salineCumulative = self.find_widget(QtWidgets.QSlider , 'slSalineCumulative' ) + self.salineCumulativeLabel = self.find_widget(QtWidgets.QLabel , 'lbSalineCumulative' ) + + self.setPointSend = self.find_widget(QtWidgets.QToolButton , 'tbSetPointSend' ) + self.setPointReset = self.find_widget(QtWidgets.QToolButton , 'tbSetPointReset' ) + self.setPointBloodFlow = self.find_widget(QtWidgets.QSlider , 'slSetPointBloodFlow' ) + self.setPointBloodFlowLabel = self.find_widget(QtWidgets.QLabel , 'lbSetPointBloodFlow' ) + self.setPointDialFlow = self.find_widget(QtWidgets.QSlider , 'slSetPointDialFlow' ) + self.setPointDialFlowLabel = self.find_widget(QtWidgets.QLabel , 'lbSetPointDialFlow' ) + self.setPointDialTemp = self.find_widget(QtWidgets.QSlider , 'slSetPointDialTemp' ) + self.setPointDialTempLabel = self.find_widget(QtWidgets.QLabel , 'lbSetPointDialTemp' ) + + self.conductivitySend = self.find_widget(QtWidgets.QToolButton , 'tbConductivitySend' ) + self.conductivityReset = self.find_widget(QtWidgets.QToolButton , 'tbConductivityReset' ) + self.conductivityD29 = self.find_widget(QtWidgets.QSlider , 'slConductivityD29' ) + self.conductivityD29Label = self.find_widget(QtWidgets.QLabel , 'lbConductivityD29' ) + + def _init_connections(self): + """ + initializes the widgets connections + :return: none + """ + self.vitalsRspSend .clicked.connect(self.do_vitals_response) + self.vitalsRspReset .clicked.connect(self.init_vitals_response) + + self.trendsReset .clicked.connect(self.init_trends_data) + self.trendsSend .clicked.connect(self.do_trends_data) + + self.vitalsReset .clicked.connect(self.init_vitals_data) + self.vitalsSend .clicked.connect(self.do_vitals_data) + self.vitalsSystolic .valueChanged.connect(self.do_vitals_data) + self.vitalsDiastolic .valueChanged.connect(self.do_vitals_data) + self.vitalsHeartRate .valueChanged.connect(self.do_vitals_data) + + self.ufReset .clicked.connect(self.init_uf_data) + self.ufSend .clicked.connect(self.do_uf_data) + self.ufTargetRate .valueChanged.connect(self.do_uf_data) + self.ufTargetRate .valueChanged.connect(lambda value: self.ufTargetRateLabel.setText(f"{value/100:.2f}")) + self.ufVolumeDelivered .valueChanged.connect(self.do_uf_data) + self.ufVolumeDelivered .valueChanged.connect(lambda value: self.ufVolumeDeliveredLabel.setText(f"{value/100:.2f}")) + + self.pressureReset .clicked.connect(self.init_pressure_data) + self.pressureSend .clicked.connect(self.do_pressure_data) + self.pressureArterial .valueChanged.connect(self.do_pressure_data) + self.pressureArterial .valueChanged.connect(lambda value: self.pressureArterialLabel.setText(f"{value}")) + self.pressureVenous .valueChanged.connect(self.do_pressure_data) + self.pressureVenous .valueChanged.connect(lambda value: self.pressureVenousLabel.setText(f"{value}")) + self.pressureTMP .valueChanged.connect(self.do_pressure_data) + self.pressureTMP .valueChanged.connect(lambda value: self.pressureTMPLabel.setText(f"{value}")) + + self.salineReset .clicked.connect(self.init_saline_data) + self.salineSend .clicked.connect(self.do_saline_data) + self.salineCumulative .valueChanged.connect(self.do_saline_data) + self.salineCumulative .valueChanged.connect(lambda value: self.salineCumulativeLabel.setText(f"{value}")) + + self.setPointReset .clicked.connect(self.init_set_point_data) + self.setPointSend .clicked.connect(self.do_set_point_data) + self.setPointBloodFlow .valueChanged.connect(self.do_set_point_data) + self.setPointBloodFlow .valueChanged.connect(lambda value: self.setPointBloodFlowLabel.setText(f"{value}")) + self.setPointDialFlow .valueChanged.connect(self.do_set_point_data) + self.setPointDialFlow .valueChanged.connect(lambda value: self.setPointDialFlowLabel.setText(f"{value}")) + self.setPointDialTemp .valueChanged.connect(self.do_set_point_data) + self.setPointDialTemp .valueChanged.connect(lambda value: self.setPointDialTempLabel.setText(f"{value/10:.1f}")) + + self.conductivityReset .clicked.connect(self.init_conductivity_data) + self.conductivitySend .clicked.connect(self.do_conductivity_data) + self.conductivityD29 .valueChanged.connect(self.do_conductivity_data) + self.conductivityD29 .valueChanged.connect(lambda value: self.conductivityD29Label.setText(f"{value/10:.1f}")) + + + @Slot() + def _init_widgets(self): + """ + initializes the widgets' properties + :return: none + """ + self.init_vitals_response() + self.init_trends_data() + + + @Slot() + def init_vitals_response(self): + """ + slot for initializing vitals response + :return: none + """ + self.vitalsReqTime .setText("--") + self.vitalsRspAccept .setChecked(True) + self.vitalsRspRejectReason .setValue(0) + + + @Slot() + def handle_vitals_request(self, message, timestamp = 0.0): + """ + Called when the user requests pause/resume to firmware from UI + @return: None + """ + message = message['message'] + self.prRequestLabel.setText(QTime.currentTime().toString("hh:mm:ss")) + + + @Slot() + def do_vitals_response(self): + """ + the slot for UF Data + :return: none + """ + self.td_interface.cmd_send_general_response( + message_id = MsgIds.MSG_ID_TD_BLOOD_PRESSURE_RESPONSE.value, + accepted = 1 if self.vitalsRspAccept.isChecked() else 0, + reason = self.vitalsRspRejectReason.value() + ) + + + @Slot() + def init_trends_data(self): + """ + slot for initializing all trends data + :return: none + """ + self.init_vitals_data() + self.init_uf_data() + self.init_pressure_data() + self.init_saline_data() + self.init_set_point_data() + self.init_conductivity_data() + + @Slot() + def do_trends_data(self): + """ + slot for initializing all trends data + :return: none + """ + self.do_vitals_data() + self.do_uf_data() + self.do_pressure_data() + self.do_saline_data() + self.do_set_point_data() + self.do_conductivity_data() + + + @Slot() + def init_vitals_data(self): + """ + slot for initializing vitals data + :return: none + """ + self.vitalsSystolic .setValue(120) + self.vitalsDiastolic .setValue(80) + self.vitalsHeartRate .setValue(70) + + + @Slot() + def do_vitals_data(self): + """ + the slot for vitals data + :return: none + """ + self.td_interface.td_vitals( + self.vitalsSystolic .value(), + self.vitalsDiastolic.value(), + self.vitalsHeartRate.value() + ) + + + @Slot() + def init_uf_data(self): + """ + slot for initializing UF data + :return: none + """ + self.ufTargetRate .setValue(0) + self.ufVolumeDelivered .setValue(0) + + + @Slot() + def do_uf_data(self): + """ + the slot for UF data + :return: none + """ + self.td_interface.td_ultrafiltration( + 0, + self.ufTargetRate .value() / 100, + self.ufVolumeDelivered.value() / 100, + 0 + ) + + + @Slot() + def init_pressure_data(self): + """ + slot for initializing pressure data + :return: none + """ + self.pressureArterial .setValue(0) + self.pressureVenous .setValue(0) + self.pressureTMP .setValue(0) + + + @Slot() + def do_pressure_data(self): + """ + the slot for pressure data + :return: none + """ + self.td_interface.td_pressure( + self.pressureArterial.value(), + self.pressureArterial.value(), + 0, + 0, + 0, + 0, + 0, + 0, + 0, + self.pressureTMP.value(), + 0, + 0 + ) + + + @Slot() + def init_saline_data(self): + """ + slot for initializing saline data + :return: none + """ + self.salineCumulative.setValue(0) + + + @Slot() + def do_saline_data(self): + """ + the slot for saline data + :return: none + """ + self.td_interface.td_saline( + 0, + self.salineCumulative.value(), + 0, + 0 + ) + + + @Slot() + def init_set_point_data(self): + """ + slot for initializing set point data + :return: none + """ + self.setPointBloodFlow .setValue(0) + self.setPointDialFlow .setValue(0) + self.setPointDialTemp .setValue(0) + + + @Slot() + def do_set_point_data(self): + """ + the slot for set point data + :return: none + """ + self.td_interface.td_treatment_set_points( + self.setPointBloodFlow .value(), + self.setPointDialFlow .value(), + self.setPointDialTemp .value() / 10 + ) + + + @Slot() + def init_conductivity_data(self): + """ + slot for initializing conductivity data + :return: none + """ + self.conductivityD29.setValue(0) + + + @Slot() + def do_conductivity_data(self): + """ + the slot for conductivity data + :return: none + """ + self.dd_interface.dd_conductivity( + 0, + 0, + self.conductivityD29.value() / 10, + 0, + 0 + )