Commit 7c9e20ea authored by Benjamin Mummery's avatar Benjamin Mummery 💻

merged localisation POC into ui_dev

parent fe8049f4
...@@ -12,13 +12,13 @@ __pycache__ ...@@ -12,13 +12,13 @@ __pycache__
*.csv *.csv
raspberry-dataserver/foo raspberry-dataserver/foo
env/ env/
BM_SCRATCH
.cache .cache
.pylintrc .pylintrc
.pre-commit-config.yaml .pre-commit-config.yaml
.env .env
ansible/playbooks/hosts ansible/playbooks/hosts
.idea .idea
scratch_*
# python virtual env created using ansible # python virtual env created using ansible
.hev_env .hev_env
...@@ -167,4 +167,3 @@ dmypy.json ...@@ -167,4 +167,3 @@ dmypy.json
.prof .prof
# End of https://www.toptal.com/developers/gitignore/api/python # End of https://www.toptal.com/developers/gitignore/api/python
...@@ -9,6 +9,9 @@ repos: ...@@ -9,6 +9,9 @@ repos:
- id: end-of-file-fixer - id: end-of-file-fixer
- id: check-yaml - id: check-yaml
- id: check-added-large-files - id: check-added-large-files
- id: check-json
# - id: pretty-format-json
- id: requirements-txt-fixer
- repo: https://github.com/psf/black - repo: https://github.com/psf/black
rev: 19.3b0 rev: 19.3b0
hooks: hooks:
......
...@@ -52,52 +52,47 @@ class NativeUI(HEVClient, QMainWindow): ...@@ -52,52 +52,47 @@ class NativeUI(HEVClient, QMainWindow):
super(NativeUI, self).__init__(*args, **kwargs) super(NativeUI, self).__init__(*args, **kwargs)
self.setWindowTitle("HEV NativeUI") self.setWindowTitle("HEV NativeUI")
config_path = self.__find_configs()
# self.setFixedSize(1920, 1080) # self.setFixedSize(1920, 1080)
self.modeList = ["PC/AC", "PC/AC-PRVC", "PC-PSV", "CPAP"] self.modeList = ["PC/AC", "PC/AC-PRVC", "PC-PSV", "CPAP"]
self.currentMode = self.modeList[0] self.currentMode = self.modeList[0]
self.colors = { # colorblind friendly ref: https://i.stack.imgur.com/zX6EV.png self.localisation_files = ["text_english.json", "text_portuguese.json"]
"page_background": QColor.fromRgb(30, 30, 30), self.localisation_files = [
"page_foreground": QColor.fromRgb(200, 200, 200), os.path.join(config_path, file) for file in self.localisation_files
"button_background_enabled": QColor.fromRgb(50, 50, 50), ]
"button_background_disabled": QColor.fromRgb(100, 100, 100),
"button_foreground_enabled": QColor.fromRgb(200, 200, 200), # Import settings from config files
"button_foreground_disabled": QColor.fromRgb(30, 30, 30), with open(os.path.join(config_path, "colors.json")) as f:
"label_background": QColor.fromRgb(0, 0, 0), # colorblind friendly ref: https://i.stack.imgur.com/zX6EV.png
"label_foreground": QColor.fromRgb(200, 200, 200), self.colors = json.load(f)
"display_background": QColor.fromRgb(200, 200, 200),
"display_foreground": QColor.fromRgb(0, 0, 0), with open(os.path.join(config_path, "text_english.json")) as f:
"baby_blue": QColor.fromRgb(144, 231, 211), self.text = json.load(f)
"red": QColor.fromRgb(200, 0, 0),
"green": QColor.fromRgb(0, 200, 0), # convert colours to a PySide2-readble form
"pressure_plot": QColor.fromRgb(0, 114, 178), for key in self.colors:
"volume_plot": QColor.fromRgb(0, 158, 115), self.colors[key] = QColor.fromRgb(*self.colors[key])
"flow_plot": QColor.fromRgb(240, 228, 66),
"pressure_flow_plot": QColor.fromRgb(230, 159, 0),
"flow_volume_plot": QColor.fromRgb(204, 121, 167),
"volume_pressure_plot": QColor.fromRgb(86, 180, 233),
"red": QColor.fromRgb(255, 0, 0),
"green": QColor.fromRgb(0, 255, 0),
"baby-blue": QColor.fromRgb(0, 0, 200),
}
self.text_font = QFont("Sans Serif", 20) self.text_font = QFont("Sans Serif", 20)
self.value_font = QFont("Sans Serif", 40) self.value_font = QFont("Sans Serif", 40)
self.text_size = "20pt" # TODO: remove in favour of self.text_font self.text_size = "20pt" # TODO: remove in favour of self.text_font
self.text = { # self.text = {
"plot_axis_label_pressure": "Pressure [cmH<sub>2</sub>O]", # "plot_axis_label_pressure": "Pressure [cmH<sub>2</sub>O]",
"plot_axis_label_flow": "Flow [L/min]", # "plot_axis_label_flow": "Flow [L/min]",
"plot_axis_label_volume": "Volume [mL]", # "plot_axis_label_volume": "Volume [mL]",
"plot_axis_label_time": "Time [s]", # "plot_axis_label_time": "Time [s]",
"plot_line_label_pressure": "Airway Pressure", # "plot_line_label_pressure": "Airway Pressure",
"plot_line_label_flow": "Flow", # "plot_line_label_flow": "Flow",
"plot_line_label_volume": "Volume", # "plot_line_label_volume": "Volume",
"plot_line_label_pressure_flow": "Airway Pressure - Flow", # "plot_line_label_pressure_flow": "Airway Pressure - Flow",
"plot_line_label_flow_volume": "Flow - Volume", # "plot_line_label_flow_volume": "Flow - Volume",
"plot_line_label_volume_pressure": "Volume - Airway Pressure", # "plot_line_label_volume_pressure": "Volume - Airway Pressure",
"layout_label_measurements": "Measurements", # "layout_label_measurements": "Measurements",
"button_label_main_normal": "Normal", # "button_label_main_normal": "Normal",
"button_label_main_detailed": "Detailed", # "button_label_main_detailed": "Detailed",
} # }
self.icons = { self.icons = {
"button_main_page": "user-md-solid", "button_main_page": "user-md-solid",
"button_alarms_page": "exclamation-triangle-solid", "button_alarms_page": "exclamation-triangle-solid",
...@@ -250,6 +245,11 @@ class NativeUI(HEVClient, QMainWindow): ...@@ -250,6 +245,11 @@ class NativeUI(HEVClient, QMainWindow):
self.MeasurementSignal.connect(self.widgets.normal_measurements.update_value) self.MeasurementSignal.connect(self.widgets.normal_measurements.update_value)
self.MeasurementSignal.connect(self.widgets.detailed_measurements.update_value) self.MeasurementSignal.connect(self.widgets.detailed_measurements.update_value)
# Localisation needs to update widgets
self.widgets.localisation_button.SetLocalisation.connect(
self.widgets.normal_measurements.localise_text
)
return 0 return 0
def __emit_plots_signal(self) -> int: def __emit_plots_signal(self) -> int:
...@@ -473,7 +473,7 @@ class NativeUI(HEVClient, QMainWindow): ...@@ -473,7 +473,7 @@ class NativeUI(HEVClient, QMainWindow):
def __find_icons(self, iconext: str) -> str: def __find_icons(self, iconext: str) -> str:
""" """
Locate the icons firectory and return its path. Locate the icons directory and return its path.
Assumes that the cwd is in a git repo, and that the path of the icons folder Assumes that the cwd is in a git repo, and that the path of the icons folder
relative to the root of the repo is "hev-display/assets/png/". relative to the root of the repo is "hev-display/assets/png/".
...@@ -488,6 +488,23 @@ class NativeUI(HEVClient, QMainWindow): ...@@ -488,6 +488,23 @@ class NativeUI(HEVClient, QMainWindow):
return icondir return icondir
def __find_configs(self) -> str:
"""
Locate the config files directory and return its path.
Assumes that the cwd is in a git repo, and that the path of the icons folder
relative to the root of the repo is "NativeUI/configs".
"""
# Find the root of the git repo
rootdir = git.Repo(os.getcwd(), search_parent_directories=True).git.rev_parse(
"--show-toplevel"
)
configdir = os.path.join(rootdir, "NativeUI", "configs")
if not os.path.isdir(configdir):
raise FileNotFoundError("Could not find icon directory at %s" % configdir)
return configdir
# from PySide2.QtQml import QQmlApplicationEngine # from PySide2.QtQml import QQmlApplicationEngine
......
{
"language_name": "English",
"plot_axis_label_pressure": "Pressure [cmH<sub>2</sub>O]",
"plot_axis_label_flow": "Flow [L/min]",
"plot_axis_label_volume": "Volume [mL]",
"plot_axis_label_time": "Time [s]",
"plot_line_label_pressure": "Airway Pressure",
"plot_line_label_flow": "Flow",
"plot_line_label_volume": "Volume",
"plot_line_label_pressure_flow": "Airway Pressure - Flow",
"plot_line_label_flow_volume": "Flow - Volume",
"plot_line_label_volume_pressure": "Volume - Airway Pressure",
"layout_label_measurements": "Measurements",
"button_label_main_normal": "Normal",
"button_label_main_detailed": "Detailed",
"ui_window_title": "HEV NativeUI",
"measurement_label_plateau_pressure": "P<sub>PLATEAU</sub> [cmH<sub>2</sub>O]",
"measurement_label_respiratory_rate": "RR",
"measurement_label_fio2_percent": "FIO<sub>2</sub> [%]",
"measurement_label_exhaled_tidal_volume": "VTE [mL]",
"measurement_label_exhaled_minute_volume": "MVE [<sup>L</sup>/<sub>min</sub>]",
"measurement_label_peep": "PEEP [cmH<sub>2</sub>O]",
"measurement_label_inhale_exhale_ratio": "I:E",
"measurement_label_mean_airway_pressure": "P<sub>MEAN</sub> [cmH<sub>2</sub>O]",
"measurement_label_inhaled_tidal_volume": "VTI [mL]",
"measurement_label_inhaled_minute_volume": "MVI [L/min]",
"measurement_label_peak_inspiratory_pressure": "P<sub>PEAK</sub> [cmH<sub>2</sub>O]"
}
{
"language_name": "Português",
"plot_axis_label_pressure": "Pressure [cmH<sub>2</sub>O]",
"plot_axis_label_flow": "Flow [L/min]",
"plot_axis_label_volume": "Volume [mL]",
"plot_axis_label_time": "Time [s]",
"plot_line_label_pressure": "Airway Pressure",
"plot_line_label_flow": "Flow",
"plot_line_label_volume": "Volume",
"plot_line_label_pressure_flow": "Airway Pressure - Flow",
"plot_line_label_flow_volume": "Flow - Volume",
"plot_line_label_volume_pressure": "Volume - Airway Pressure",
"layout_label_measurements": "Measurements",
"button_label_main_normal": "Normal",
"button_label_main_detailed": "Detailed",
"ui_window_title": "HEV NativeUI",
"measurement_label_plateau_pressure": "TRANSLATE",
"measurement_label_respiratory_rate": "TRANSLATE",
"measurement_label_fio2_percent": "TRANSLATE",
"measurement_label_exhaled_tidal_volume": "TRANSLATE",
"measurement_label_exhaled_minute_volume": "TRANSLATE",
"measurement_label_peep": "PEEP [cmH<sub>2</sub>O]",
"measurement_label_inhale_exhale_ratio": "I:E",
"measurement_label_mean_airway_pressure": "P<sub>MEAN</sub> [cmH<sub>2</sub>O]",
"measurement_label_inhaled_tidal_volume": "VTI [mL]",
"measurement_label_inhaled_minute_volume": "MVI [L/min]",
"measurement_label_peak_inspiratory_pressure": "P<sub>PEAK</sub> [cmH<sub>2</sub>O]"
}
...@@ -100,7 +100,8 @@ class Layout: ...@@ -100,7 +100,8 @@ class Layout:
self.layout_top_bar( self.layout_top_bar(
[ [
self.widgets.tab_modeswitch, self.widgets.tab_modeswitch,
self.widgets.tab_personal, self.widgets.personal_display,
self.widgets.localisation_button,
self.widgets.battery_display, self.widgets.battery_display,
] ]
) )
......
...@@ -13,6 +13,7 @@ __maintainer__ = "Benjamin Mummery" ...@@ -13,6 +13,7 @@ __maintainer__ = "Benjamin Mummery"
__email__ = "benjamin.mummery@stfc.ac.uk" __email__ = "benjamin.mummery@stfc.ac.uk"
__status__ = "Prototype" __status__ = "Prototype"
from widget_library.localisation_button_widget import LocalisationButtonWidget
from alarm_widgets.tab_alarm_table import TabAlarmTable from alarm_widgets.tab_alarm_table import TabAlarmTable
from alarm_widgets.tab_alarms import TabAlarm from alarm_widgets.tab_alarms import TabAlarm
from alarm_widgets.tab_clinical import TabClinical from alarm_widgets.tab_clinical import TabClinical
...@@ -56,7 +57,8 @@ class Widgets: ...@@ -56,7 +57,8 @@ class Widgets:
# Top bar widgets # Top bar widgets
self.tab_modeswitch = TabModeswitchButton(NativeUI) self.tab_modeswitch = TabModeswitchButton(NativeUI)
self.battery_display = BatteryDisplayWidget(NativeUI) self.battery_display = BatteryDisplayWidget(NativeUI)
self.tab_personal = PersonalDisplayWidget(NativeUI) self.personal_display = PersonalDisplayWidget(NativeUI)
self.localisation_button = LocalisationButtonWidget(NativeUI.localisation_files)
# Left Bar widgets # Left Bar widgets
self.page_buttons = PageButtonsWidget(NativeUI) self.page_buttons = PageButtonsWidget(NativeUI)
......
#!/usr/bin/.hev_env python3
"""
localisation_button_widget.py
Part of NativeUI. Defines the LocalisationButtonWidget class to allow the user to set
the language for the interface.
"""
__author__ = "Benjamin Mummery"
__credits__ = ["Benjamin Mummery", "Dónal Murray", "Tim Powell", "Tiago Sarmento"]
__license__ = "GPL"
__version__ = "0.0.1"
__maintainer__ = "Benjamin Mummery"
__email__ = "benjamin.mummery@stfc.ac.uk"
__status__ = "Development"
from PySide2 import QtWidgets
import json
import os
from PySide2.QtCore import Signal
class LocalisationButtonWidget(QtWidgets.QPushButton):
"""
TODO BM: add set_size and setFont
"""
SetLocalisation = Signal(dict)
def __init__(self, localisation_config_file_paths: list, *args, **kwargs):
super().__init__(*args, **kwargs)
self.__localisation_dict: dict = {}
self.__localisation_files_list: list = localisation_config_file_paths
self.__current_localisation_index: int = -1
self.set_localisation(0)
self.pressed.connect(self.on_press)
def on_press(self) -> int:
"""
When the button is pressed, update the localisation.
"""
index = self.__current_localisation_index + 1
if index >= len(self.__localisation_files_list):
index = 0
self.set_localisation(index)
return 0
def set_localisation(self, index: int) -> int:
"""
Set the current localisation parameters to those of the the specified index,
then emit the SetLocalisation signal to propogate that change.
"""
if index == self.__current_localisation_index:
return 0
self.__current_localisation_index = index
self.__import_localisation_config()
self.setText(self.__localisation_dict["language_name"])
self.SetLocalisation.emit(self.__localisation_dict)
return 0
def __import_localisation_config(self) -> int:
"""
Read in the current configuration
"""
with open(
self.__localisation_files_list[self.__current_localisation_index]
) as infile:
self.__localisation_dict = json.load(infile)
return 0
...@@ -37,7 +37,7 @@ class MeasurementsBlockWidget(QtWidgets.QWidget): ...@@ -37,7 +37,7 @@ class MeasurementsBlockWidget(QtWidgets.QWidget):
layout = QtWidgets.QGridLayout(self) layout = QtWidgets.QGridLayout(self)
# Create "Measurements" Title # Create "Measurements" Title
self.title_label = QtWidgets.QLabel(NativeUI.text["layout_label_measurements"]) self.title_label = QtWidgets.QLabel()
self.title_label.setStyleSheet( self.title_label.setStyleSheet(
# "font-size:" + NativeUI.text_size + ";" # "font-size:" + NativeUI.text_size + ";"
"color:" + NativeUI.colors["page_foreground"].name() + ";" "color:" + NativeUI.colors["page_foreground"].name() + ";"
...@@ -55,7 +55,7 @@ class MeasurementsBlockWidget(QtWidgets.QWidget): ...@@ -55,7 +55,7 @@ class MeasurementsBlockWidget(QtWidgets.QWidget):
self.widget_list.append( self.widget_list.append(
MeasurementWidget( MeasurementWidget(
NativeUI, NativeUI,
measurement[0], # Label measurement[0], # Label key
measurement[2], # Keydir measurement[2], # Keydir
measurement[1], # Key measurement[1], # Key
measurement[3], # Format measurement[3], # Format
...@@ -65,7 +65,7 @@ class MeasurementsBlockWidget(QtWidgets.QWidget): ...@@ -65,7 +65,7 @@ class MeasurementsBlockWidget(QtWidgets.QWidget):
self.widget_list.append( self.widget_list.append(
MeasurementWidget( MeasurementWidget(
NativeUI, NativeUI,
measurement[0], # Label measurement[0], # Label key
measurement[2], # Keydir measurement[2], # Keydir
measurement[1], # Key measurement[1], # Key
) )
...@@ -95,6 +95,7 @@ class MeasurementsBlockWidget(QtWidgets.QWidget): ...@@ -95,6 +95,7 @@ class MeasurementsBlockWidget(QtWidgets.QWidget):
layout.setAlignment(QtCore.Qt.AlignHCenter) layout.setAlignment(QtCore.Qt.AlignHCenter)
self.setLayout(layout) self.setLayout(layout)
self.localise_text(NativeUI.text)
def set_size( def set_size(
self, x: int, y: int, spacing: int = 10, widget_size_ratio: float = 2.5 self, x: int, y: int, spacing: int = 10, widget_size_ratio: float = 2.5
...@@ -158,6 +159,20 @@ class MeasurementsBlockWidget(QtWidgets.QWidget): ...@@ -158,6 +159,20 @@ class MeasurementsBlockWidget(QtWidgets.QWidget):
widget.value_display.setFont(font) widget.value_display.setFont(font)
return 0 return 0
@QtCore.Slot(dict)
def localise_text(self, text: dict) -> int:
"""
Update the text displayed on the title and all measurement labels.
"""
# set the text for the title label
self.title_label.setText(text["layout_label_measurements"])
# Set the text for each of the measurement widgets
for widget in self.widget_list:
widget.localise_text(text)
return 0
@QtCore.Slot(dict, dict) @QtCore.Slot(dict, dict)
def update_value(self, cycle: dict, readback: dict) -> int: def update_value(self, cycle: dict, readback: dict) -> int:
for widget in self.widget_list: for widget in self.widget_list:
...@@ -187,7 +202,7 @@ class MeasurementWidget(QtWidgets.QWidget): ...@@ -187,7 +202,7 @@ class MeasurementWidget(QtWidgets.QWidget):
def __init__( def __init__(
self, self,
NativeUI, NativeUI,
label: str, label_key: str,
keydir: str, keydir: str,
key: str, key: str,
format: str = "{:.1f}", format: str = "{:.1f}",
...@@ -197,6 +212,7 @@ class MeasurementWidget(QtWidgets.QWidget): ...@@ -197,6 +212,7 @@ class MeasurementWidget(QtWidgets.QWidget):
super(MeasurementWidget, self).__init__(*args, **kwargs) super(MeasurementWidget, self).__init__(*args, **kwargs)
self.NativeUI = NativeUI self.NativeUI = NativeUI
self.label_key = label_key
self.keydir = keydir self.keydir = keydir
self.key = key self.key = key
self.format = format self.format = format
...@@ -204,7 +220,7 @@ class MeasurementWidget(QtWidgets.QWidget): ...@@ -204,7 +220,7 @@ class MeasurementWidget(QtWidgets.QWidget):
# Layout and widgets # Layout and widgets
layout = QtWidgets.QVBoxLayout() layout = QtWidgets.QVBoxLayout()
self.name_display = QtWidgets.QLabel(label) self.name_display = QtWidgets.QLabel()
self.value_display = QtWidgets.QLabel() self.value_display = QtWidgets.QLabel()
layout.addWidget(self.name_display) layout.addWidget(self.name_display)
...@@ -261,11 +277,24 @@ class MeasurementWidget(QtWidgets.QWidget): ...@@ -261,11 +277,24 @@ class MeasurementWidget(QtWidgets.QWidget):
return self.format.format(number) return self.format.format(number)
def set_size(self, x: int, y: int) -> int: def set_size(self, x: int, y: int) -> int:
"""
Set the size of the widget to the specified x and y values in pixels.
The overall widget size is fixed to x by y pixels. Name and value displays have
width x, and height y/3 and 2y/3 respectively.
"""
self.setFixedSize(x, y) self.setFixedSize(x, y)
self.name_display.setFixedSize(x, int(y / 3)) self.name_display.setFixedSize(x, int(y / 3))
self.value_display.setFixedSize(x, int(2 * y / 3)) self.value_display.setFixedSize(x, int(2 * y / 3))
return 0 return 0
def localise_text(self, text: dict) -> int:
"""
Set the name display text the relevent entry in the provided dictionary.
"""
self.name_display.setText(text[self.label_key])
return 0
class NormalMeasurementsBlockWidget(MeasurementsBlockWidget): class NormalMeasurementsBlockWidget(MeasurementsBlockWidget):
""" """
...@@ -276,17 +305,17 @@ class NormalMeasurementsBlockWidget(MeasurementsBlockWidget): ...@@ -276,17 +305,17 @@ class NormalMeasurementsBlockWidget(MeasurementsBlockWidget):
def __init__(self, NativeUI, *args, **kwargs): def __init__(self, NativeUI, *args, **kwargs):
measurements = [ measurements = [
("P<sub>PLATEAU</sub> [cmH<sub>2</sub>O]", "plateau_pressure", "cycle"), ("measurement_label_plateau_pressure", "plateau_pressure", "cycle"),
("RR", "respiratory_rate", "cycle"), ("measurement_label_respiratory_rate", "respiratory_rate", "cycle"),
("FIO<sub>2</sub> [%]", "fiO2_percent", "cycle"), ("measurement_label_fio2_percent", "fiO2_percent", "cycle"),
("VTE [mL]", "exhaled_tidal_volume", "cycle"), ("measurement_label_exhaled_tidal_volume", "exhaled_tidal_volume", "cycle"),
( (
"MVE [<sup>L</sup>/<sub>min</sub>]", "measurement_label_exhaled_minute_volume",
"exhaled_minute_volume", "exhaled_minute_volume",
"cycle", "cycle",
"{:.0f}", "{:.0f}",
), ),
("PEEP [cmH<sub>2</sub>O]", "peep", "readback"), ("measurement_label_peep", "peep", "readback"),
] ]
super().__init__( super().__init__(
...@@ -303,20 +332,34 @@ class ExpertMeasurementsBloackWidget(MeasurementsBlockWidget): ...@@ -303,20 +332,34 @@ class ExpertMeasurementsBloackWidget(MeasurementsBlockWidget):
def __init__(self, NativeUI, *args, **kwargs): def __init__(self, NativeUI, *args, **kwargs):
measurements = [ measurements = [
("FIO<sub>2</sub> [%]", "fiO2_percent", "cycle"), ("measurement_label_fio2_percent", "fiO2_percent", "cycle"),
("I:E", "inhale_exhale_ratio", "readback", "ratio"), (
"measurement_label_inhale_exhale_ratio",
"inhale_exhale_ratio",
"readback",
"ratio",
),
( (
"P<sub>PEAK</sub> [cmH<sub>2</sub>O]", "measurement_label_peak_inspiratory_pressure",
"peak_inspiratory_pressure", "peak_inspiratory_pressure",
"cycle", "cycle",
), ),
("P<sub>PLATEAU</sub> [cmH<sub>2</sub>O]", "plateau_pressure", "cycle"), ("measurement_label_plateau_pressure", "plateau_pressure", "cycle"),
("P<sub>MEAN</sub> [cmH<sub>2</sub>O]", "mean_airway_pressure", "cycle"), ("measurement_label_mean_airway_pressure", "mean_airway_pressure", "cycle"),
("PEEP [cmH<sub>2</sub>O]", "peep", "readback"), ("measurement_label_peep", "peep", "readback"),
("VTI [mL]", "inhaled_tidal_volume", "cycle"), ("measurement_label_inhaled_tidal_volume", "inhaled_tidal_volume", "cycle"),
("VTE [mL]", "exhaled_tidal_volume", "cycle"), ("measurement_label_exhaled_tidal_volume", "exhaled_tidal_volume", "cycle"),
("MVI [L/min]", "inhaled_minute_volume", "cycle"), (
("MVE [L/min]", "exhaled_minute_volume", "cycle", "{:.0f}"), "measurement_label_inhaled_minute_volume",
"inhaled_minute_volume",
"cycle",
),
(
"measurement_label_exhaled_minute_volume",
"exhaled_minute_volume",
"cycle",
"{:.0f}",
),
] ]
super().__init__( super().__init__(
......
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