Commit c601d6f8 authored by Tiago Sarmento's avatar Tiago Sarmento

restructured update alarms

parent 33ce0ace
......@@ -203,20 +203,25 @@ class NativeUI(HEVClient, QMainWindow):
for button in self.widgets.page_buttons.buttons:
button.PageButtonPressed.connect(self.change_page)
#self.widgets.tab_modeswitch.
##### Mode:
# When mode is switched from mode page, various other locations must respond
self.widgets.mode_handler.modeSwitched.connect(lambda i: self.set_current_mode(i))
self.widgets.mode_handler.modeSwitched.connect(lambda i: self.widgets.tab_modeswitch.update_mode(i))
self.widgets.mode_handler.modeSwitched.connect(self.widgets.mode_handler.refresh_button_colour)
# when mode is switched from modeSwitch button, other locations must respond
self.widgets.tab_modeswitch.modeSwitched.connect(lambda i: self.set_current_mode(i))
self.widgets.tab_modeswitch.modeSwitched.connect(self.widgets.mode_handler.refresh_button_colour)
#spinList = any("abc" in s for s in some_list):
# mode_handler should respond to manual spin box changes
for key, spinWidget in self.widgets.mode_handler.spinDict.items():
spinWidget.simpleSpin.manualChanged.connect(lambda i=key: self.widgets.mode_handler.handle_manual_change(i))
# mode_handler should respond to user selection of radio button
for key, radioWidget in self.widgets.mode_handler.radioDict.items():
radioWidget.toggled.connect(lambda i, j=key: self.widgets.mode_handler.handle_radio_toggled(i, j))
# mode_handler should respond to ok, send, or cancel presses
for key, buttonWidget in self.widgets.mode_handler.buttonDict.items():
if isinstance(buttonWidget,OkButtonWidget) or isinstance(buttonWidget,OkSendButtonWidget):
buttonWidget.pressed.connect(lambda i=key: self.widgets.mode_handler.handle_okbutton_click(i))
......@@ -224,9 +229,12 @@ class NativeUI(HEVClient, QMainWindow):
mode = self.widgets.mode_handler.get_mode(key)
buttonWidget.pressed.connect(lambda i=mode: self.widgets.mode_handler.commandSent(i))
##### Expert Settings:
# Expert handler should respond to manual value changes
for key, spinWidget in self.widgets.expert_handler.spinDict.items():
spinWidget.simpleSpin.manualChanged.connect(lambda i=key: self.widgets.expert_handler.handle_manual_change(i))
# mode_handler should respond to ok, send, or cancel presses
for key, buttonWidget in self.widgets.expert_handler.buttonDict.items():
if isinstance(buttonWidget, OkButtonWidget) or isinstance(buttonWidget, OkSendButtonWidget):
buttonWidget.pressed.connect(lambda i=key: self.widgets.expert_handler.handle_okbutton_click(i))
......@@ -234,8 +242,8 @@ class NativeUI(HEVClient, QMainWindow):
buttonWidget.pressed.connect(lambda: self.widgets.expert_handler.commandSent())
# Lines displayed on the charts page should update when the corresponding
# buttons are toggled.
#Lines displayed on the charts page should update when the corresponding
#buttons are toggled.
for button in self.widgets.chart_buttons_widget.buttons:
button.ToggleButtonPressed.connect(self.widgets.charts_widget.show_line)
button.ToggleButtonReleased.connect(self.widgets.charts_widget.hide_line)
......@@ -245,12 +253,11 @@ class NativeUI(HEVClient, QMainWindow):
# Plot data and measurements should update on a timer
self.timer = QtCore.QTimer()
self.timer.setInterval(16) # just faster than 60Hz
self.timer.timeout.connect(self.widgets.detailed_measurements.update_value)
self.timer.timeout.connect(self.__emit_plots_signal)
self.timer.timeout.connect(self.__emit_measurements_signal)
self.timer.timeout.connect(self.widgets.alarm_handler.update_alarms)
self.timer.timeout.connect(self.widgets.mode_handler.update_values)
self.timer.timeout.connect(self.widgets.expert_handler.update_values)
self.timer.timeout.connect(self.__emit_plots_signal)
self.timer.timeout.connect(self.__emit_measurements_signal)
self.timer.start()
# When plot data is updated, plots should update
......@@ -410,12 +417,16 @@ class NativeUI(HEVClient, QMainWindow):
if payload["type"] == "DATA":
self.__set_db("data", payload["DATA"])
self.__set_plots_db(payload["DATA"])
old = self.ongoingAlarms
self.ongoingAlarms = payload["alarms"]
#if self.ongoingAlarms != old:
# print(self.ongoingAlarms)
if payload["type"] == "BATTERY":
self.__set_db("battery", payload["BATTERY"])
self.BatterySignal.emit(self.get_db("battery"))
if payload["type"] == "ALARM":
self.__set_db("alarms", payload["ALARM"])
# print(payload["ALARM"])
if payload["type"] == "TARGET":
self.__set_db("targets", payload["TARGET"])
if payload["type"] == "READBACK":
......
......@@ -13,9 +13,7 @@ __email__ = "tiago.sarmento@stfc.ac.uk"
__status__ = "Prototype"
import sys
from alarm_widgets.alarm_popup import AbstractAlarm
#from alarm_widgets.alarm_list import alarmList
from datetime import datetime
from PySide2 import QtCore, QtGui, QtWidgets
......@@ -24,48 +22,39 @@ class AlarmHandler(QtWidgets.QWidget):
super(AlarmHandler, self).__init__(*args, **kwargs)
self.NativeUI = NativeUI
# # self.alarmDict = {}
# self.popup = alarmPopup(NativeUI, self)
# self.popup.show()
# self.list = alarmList(NativeUI)
# vlayout = QtWidgets.QVBoxLayout()
# vlayout.addWidget(self.list)
# self.acknowledgeButton = QtWidgets.QPushButton()
# self.acknowledgeButton.pressed.connect(self.acknowledge_pressed)
# vlayout.addWidget(self.acknowledgeButton)
# self.setLayout(vlayout)
self.alarmDict = {}
# fdd
# self.timer = QtCore.QTimer()
# self.timer.setInterval(160)
# self.timer.timeout.connect(self.updateAlarms)
# self.timer.start()
self.oldAlarms = []
def acknowledge_pressed(self):
self.popup.clearAlarms()
self.list.acknowledge_all()
def update_alarms(self):
newAlarmPayload = self.NativeUI.get_db("alarms")
if newAlarmPayload == []:
return
if newAlarmPayload["alarm_code"] in self.alarmDict:
a = 1
self.alarmDict[newAlarmPayload["alarm_code"]].resetTimer()
self.alarmDict[newAlarmPayload["alarm_code"]].calculateDuration()
else:
newAbstractAlarm = AbstractAlarm(self.NativeUI, newAlarmPayload)
self.alarmDict[newAlarmPayload["alarm_code"]] = newAbstractAlarm
newAbstractAlarm.alarmExpired.connect(
lambda i=newAbstractAlarm: self.handleAlarmExpiry(i)
)
self.NativeUI.widgets.alarm_popup.addAlarm(newAbstractAlarm)
self.NativeUI.widgets.alarm_list.addAlarm(newAbstractAlarm)
self.NativeUI.widgets.alarm_table.addAlarmRow(newAbstractAlarm)
currentAlarms = self.NativeUI.ongoingAlarms # instead of getting database at a particular frequency, this should be triggered when a new alarm arrives
if self.oldAlarms != currentAlarms:
if len(self.oldAlarms) != len(currentAlarms):
print('not the same length!')
print(len(self.oldAlarms))
print(len(currentAlarms))
self.oldAlarms = currentAlarms
for alarm in currentAlarms:
alarmCode = alarm["alarm_code"]
if alarmCode in self.alarmDict:
self.alarmDict[alarmCode].resetTimer()
self.alarmDict[alarmCode].calculateDuration()
else:
newAbstractAlarm = AbstractAlarm(self.NativeUI, alarm)
self.alarmDict[alarmCode] = newAbstractAlarm
newAbstractAlarm.alarmExpired.connect(
lambda i=newAbstractAlarm: self.handleAlarmExpiry(i)
)
self.NativeUI.widgets.alarm_popup.addAlarm(newAbstractAlarm)
self.NativeUI.widgets.alarm_list.addAlarm(newAbstractAlarm)
self.NativeUI.widgets.alarm_table.addAlarmRow(newAbstractAlarm)
def handleAlarmExpiry(self, abstractAlarm):
abstractAlarm.freezeTimer()
......@@ -73,3 +62,43 @@ class AlarmHandler(QtWidgets.QWidget):
self.NativeUI.widgets.alarm_list.removeAlarm(abstractAlarm)
self.alarmDict.pop(abstractAlarm.alarmPayload["alarm_code"])
abstractAlarm.recordFinishTime()
class AbstractAlarm(QtWidgets.QWidget):
alarmExpired = QtCore.Signal()
def __init__(self, NativeUI, alarmPayload, *args, **kwargs):
super(AbstractAlarm, self).__init__(*args, **kwargs)
self.NativeUI = NativeUI
self.alarmPayload = alarmPayload
self.startTime = datetime.now()
self.duration = datetime.now() - self.startTime
self.finishTime = -1
self.timer = QtCore.QTimer()
self.timer.setInterval(100) # just faster than 60Hz
self.timer.timeout.connect(self.timeoutDelete)
self.timer.start()
def timeoutDelete(self):
# """Check alarm still exists in ongoingAlarms object. If present do nothing, otherwise delete."""
self.alarmExpired.emit()
self.setParent(None) # delete self
return 0
def resetTimer(self):
self.timer.start()
return 0
def freezeTimer(self):
self.timer.stop()
return 0
def recordFinishTime(self):
self.finishTime = datetime.now()
self.duration = self.finishTime - self.startTime
def calculateDuration(self):
self.duration = datetime.now() - self.startTime
......@@ -17,46 +17,6 @@ from PySide2 import QtCore, QtGui, QtWidgets
from datetime import datetime
class AbstractAlarm(QtWidgets.QWidget):
alarmExpired = QtCore.Signal()
def __init__(self, NativeUI, alarmPayload, *args, **kwargs):
super(AbstractAlarm, self).__init__(*args, **kwargs)
self.NativeUI = NativeUI
self.alarmPayload = alarmPayload
self.startTime = datetime.now()
self.duration = datetime.now() - self.startTime
self.finishTime = -1
self.timer = QtCore.QTimer()
self.timer.setInterval(1500) # just faster than 60Hz
self.timer.timeout.connect(self.timeoutDelete)
self.timer.start()
def timeoutDelete(self):
# """Check alarm still exists in ongoingAlarms object. If present do nothing, otherwise delete."""
self.alarmExpired.emit()
self.setParent(None) # delete self
return 0
def resetTimer(self):
self.timer.start()
return 0
def freezeTimer(self):
self.timer.stop()
return 0
def recordFinishTime(self):
self.finishTime = datetime.now()
self.duration = self.finishTime - self.startTime
def calculateDuration(self):
self.duration = datetime.now() - self.startTime
class AlarmWidget(QtWidgets.QWidget):
"""Object containing information particular to one alarm.
Created when alarm received from microcontroller, timeout after alarm signal stops.
......@@ -162,11 +122,15 @@ class AlarmPopup(QtWidgets.QDialog):
self.alarmDict[abstractAlarm.alarmPayload["alarm_code"]] = AlarmWidget(
self.NativeUI, abstractAlarm, self
)
self.layout.addWidget(self.alarmDict[abstractAlarm.alarmPayload["alarm_code"]])
return 0
def removeAlarm(self, abstractAlarm):
"""Creates a new alarmWidget and adds it to the container"""
print('remove ' + abstractAlarm.alarmPayload["alarm_code"])
print(abstractAlarm)
print(self.alarmDict.keys())
self.alarmDict[abstractAlarm.alarmPayload["alarm_code"]].setParent(None)
self.alarmDict.pop(abstractAlarm.alarmPayload["alarm_code"])
......
......@@ -223,7 +223,7 @@ class Layout:
# Create the stack
page_settings = SwitchableStackWidget(
self.NativeUI,
[self.layout_settings_expert(), QtWidgets.QWidget()],#self.widgets.settings_chart_tab],
[self.layout_settings_expert(), tab_charts],
["Expert", "Charts"],
)
page_settings.setFont(self.NativeUI.text_font)
......@@ -341,6 +341,9 @@ class Layout:
return tab_alarm_table
def layout_mode_settings(self) -> QtWidgets.QWidget:
"""
Construct the layout for the mode pages
"""
mode_pages = [] # enableDict may need to go elsewhere
enableDict = {'PC/AC':[1, 0, 1, 1, 0, 1, 0, 1], 'PC/AC-PRVC':[1, 1, 0, 1, 0, 1, 1, 1], 'PC-PSV':[1, 1, 0, 1, 0, 1, 0, 1], 'CPAP':[1, 0, 1, 1, 0, 1, 0, 1]}
for mode in self.NativeUI.modeList:
......@@ -355,6 +358,9 @@ class Layout:
return page_modes
def layout_mode_tab(self, mode:str, enableList:list) -> QtWidgets.QWidget:
"""
Construct the layout for an individual mode setting tab
"""
spinList = [ self.NativeUI.widgets.get_widget(attrName) for attrName in dir(self.NativeUI.widgets) if ('spin_' + mode + '_') in attrName]
# consider subclassing labelledspinbox to have modespinbox with attribute mode
if len(spinList) != len(enableList):
......@@ -382,18 +388,11 @@ class Layout:
mode_tab = QtWidgets.QWidget()
mode_tab.setLayout(vLayout)
return mode_tab
# if "IE Ratio" in key:
# tab.radioButtonRat = QtWidgets.QRadioButton()
# tab.radioButtonRat.setChecked(bool(enable[2]))
# tab.radioButtonRat.toggled.connect(
# lambda i=tab.radioButtonRat, j=tab.spinDict[
# labelledSpin
# ], k=tab.mode: self.radioPressed(i, j, k)
# )
# tab.spinDict[labelledSpin].insertWidget(tab.radioButtonRat, 1)
# tab.buttonGroup.addButton(tab.radioButtonRat)
def layout_mode_personal(self):
"""
Construct the layout for the personal settings page
"""
personalList = [self.NativeUI.widgets.get_widget(attrName) for attrName in dir(self.NativeUI.widgets) if 'personal_edit' in attrName]
# consider subclassing labelledspinbox to have modespinbox with attribute mode
......@@ -413,12 +412,14 @@ class Layout:
return personal_tab
def layout_settings_expert(self):
"""
Construct the layout for the expert settings page, reads controlDict.json to do so
"""
vlayout = QtWidgets.QVBoxLayout()
i = 0
with open('NativeUI/config/controlDict.json') as json_file:
controlDict = json.load(json_file)
for key in controlDict.keys():
titleLabel = self.NativeUI.widgets.get_widget('expert_label_' + key)
titleLabel.setStyleSheet(
"background-color:"
......@@ -447,9 +448,6 @@ class Layout:
j = -1
for boxInfo in controlDict[key]:
j = j + 1
#self.spinDict[boxInfo[0]] = labelledSpin(self.NativeUI, boxInfo)
grid.addWidget(
self.NativeUI.widgets.get_widget('expert_spin_' + boxInfo[2]), i + 1 + int(j / 3), 2 * (j % 3), 1, 2
)
......
......@@ -36,7 +36,7 @@ from widget_library.plot_widget import (
TimePlotsWidget,
)
from widget_library.spin_buttons_widget import SpinButtonsWidget
from widget_library.tab_expert import TabExpert
#from widget_library.tab_expert import TabExpert
from widget_library.ventilator_start_stop_buttons_widget import (
VentilatorStartStopButtonsWidget,
)
......@@ -91,7 +91,6 @@ class Widgets:
self.detailed_measurements = ExpertMeasurementsBloackWidget(NativeUI)
# Alarm Page Widgets
self.alarm_handler = AlarmHandler(NativeUI)
self.alarm_popup = AlarmPopup(NativeUI)
self.alarm_list = AlarmList(NativeUI)
......@@ -101,18 +100,12 @@ class Widgets:
self.alarm_table = AlarmTable(NativeUI)
self.clinical_tab = QWidget()#TabClinical(NativeUI)
# Settings Page Widgets
self.settings_expert_tab = TabExpert(NativeUI)
self.charts_widget = ChartsPlotWidget(colors=NativeUI.colors)
self.chart_buttons_widget = ChartButtonsWidget(colors=NativeUI.colors)
# self.settings_chart_tab = TabChart(NativeUI)
#self.settings_expert_tab = TabExpert(NativeUI)
#self.settings_chart_tab = TabChart(NativeUI)
#### Mode settings tab: Mode (x4), Personal
# Modes Page Widgets
self.mode_confirm_popup = SetConfirmPopup(NativeUI)
self.mode_handler = ModeHandler(NativeUI, self.mode_confirm_popup)
# Modes Page Widgets
modeSettingsList = [
["Respiratory Rate","/min","respiratory_rate","SET_TARGET_","RESPIRATORY_RATE",],
["Inhale Time", "s", "inhale_time", "SET_TARGET_", "INHALE_TIME"],
......@@ -126,10 +119,8 @@ class Widgets:
modes = NativeUI.modeList
radioSettings = ['Inhale Time', 'IE Ratio']
self.groupDict = {}
#self.mode_ok_cancel_buttons = {}
for mode in modes:
self.groupDict[mode] = QButtonGroup()
#self.groupDict[mode].buttonClicked.connect(lambda i: print(i))
for setting in modeSettingsList:
attrName = mode + '_' + setting[2]
targettedSetting =[ target.replace("SET_TARGET_", "SET_TARGET_" + mode.replace("/", "_").replace("-", "_")) for target in setting]
......@@ -144,6 +135,8 @@ class Widgets:
self.add_handled_widget(OkSendButtonWidget(NativeUI),'ok_send_button_' + mode, self.mode_handler)
self.add_handled_widget(CancelButtonWidget(NativeUI),'cancel_button_' + mode, self.mode_handler)
# Personal tab widgets
self.personal_confirm_popup = SetConfirmPopup(NativeUI)
self.personal_handler = PersonalHandler(NativeUI, self.personal_confirm_popup)
personalSettingsList = [
......@@ -166,7 +159,9 @@ class Widgets:
self.add_handled_widget(OkSendButtonWidget(NativeUI), 'ok_send_button_personal', self.personal_handler)
self.add_handled_widget(CancelButtonWidget(NativeUI), 'cancel_button_personal', self.personal_handler)
##### Settings Tab: Expert and Charts tabs
# Expert Tab
self.expert_confirm_popup = SetConfirmPopup(NativeUI)
self.expert_handler = ExpertHandler(NativeUI, self.expert_confirm_popup)
print(os.listdir())
......@@ -184,12 +179,11 @@ class Widgets:
self.add_handled_widget(OkSendButtonWidget(NativeUI), 'ok_send_button_expert', self.expert_handler)
self.add_handled_widget(CancelButtonWidget(NativeUI), 'cancel_button_expert', self.expert_handler)
# Chart Tab
self.charts_widget = ChartsPlotWidget(colors=NativeUI.colors)
self.chart_buttons_widget = ChartButtonsWidget(colors=NativeUI.colors)
#self.mode_settings_tab = TabModes(NativeUI)
#self.mode_personal_tab = TabPersonal(NativeUI)
def add_widget(self, widget, name) -> int:
setattr(self, name, widget)
return 0
......
......@@ -19,11 +19,9 @@ from PySide2.QtCore import QSize, Signal, Slot
class ChartButtonsWidget(QtWidgets.QWidget):
def __init__(self, *args, colors: dict = {}, **kwargs):
super().__init__(*args, **kwargs)
self.pressureButton = ToggleButtonWidget("Pressure", signal_value="pressure")
self.flow_button = ToggleButtonWidget("Flow", signal_value="flow")
self.buttons = [
self.pressureButton,
self.flow_button,
ToggleButtonWidget("Pressure", signal_value="pressure"),
ToggleButtonWidget("Flow", signal_value="flow"),
]
stylesheet = (
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment