Exemple #1
0
    def ok_worker(self, mode):
        '''
        The callback function called when the alarm 
        or warning pop up window is closed by clicking
        on the Ok button.

        arguments:
        - mode: what this is closing, an 'alarm' or a 'warning'
        '''

        if mode not in ['alarm', 'warning']:
            raise Exception('mode must be alarm or warning.')

        if mode == 'alarm':
            self._alarm_raised = False
        else:
            self._warning_raised = False

        # Reset the alarms/warnings in the ESP
        # If the ESP connection fails at this
        # time, raise an error box
        try:
            if mode == 'alarm':
                self._esp32.reset_alarms()
            else:
                self._esp32.reset_warnings()
        except Exception as error:
            msg = MessageBox()
            fn = msg.critical("Critical",
                              "Severe hardware communication error",
                              str(error), "Communication error", {
                                  msg.Retry: lambda: self.ok_worker(mode),
                                  msg.Abort: lambda: None
                              })
            fn()
Exemple #2
0
    def _on_click_snooze(self):
        '''
        The callback function called when the alarm
        snooze button is clicked.
        '''

        if self._mode not in [WARNING, ERROR]:
            raise Exception('mode must be alarm or warning.')

        # Reset the alarms/warnings in the ESP
        # If the ESP connection fails at this
        # time, raise an error box
        try:
            if self._mode == ERROR:
                self._esp32.snooze_hw_alarm(self._code)
                self._alarm_h.snooze_alarm(self._code)
            else:
                self._esp32.reset_warnings()
                self._alarm_h.snooze_warning(self._code)
        except Exception as error:
            msg = MessageBox()
            fn = msg.critical("Critical",
                              "Severe hardware communication error",
                              str(error), "Communication error", {
                                  msg.Retry: lambda: self.ok_worker(mode),
                                  msg.Abort: lambda: None
                              })
            fn()
Exemple #3
0
    def toggle_lung_recruit(self):
        if self._lung_recruit:
            self._lung_recruit = False
            self._esp32.set("pause_lg", 0)
            self._lung_recruit_timer.stop()
            self.button_lung_recruit.setText("Lung\nRecruitment")
        else:
            msg = MessageBox()
            fn = msg.question(
                "Please confirm",
                "Do you want to start the Lung Recruitment procedure?", None,
                "Confirmation required", {
                    msg.Yes: lambda: True,
                    msg.No: lambda: False
                })
            answer = fn()
            if not answer:
                return

            self._lung_recruit = True
            lr_time = self._config["lung_recruit_time"]["current"]
            lr_pres = self._config["lung_recruit_pres"]["current"]
            self.button_lung_recruit.setText("Stop\nLung Recruitment\n %d" %
                                             lr_time)

            self._esp32.set("pause_lg_p", lr_pres)
            self._esp32.set("pause_lg_time", lr_time)
            self._esp32.set("pause_lg", 1)

            self._lung_recruit_timer = QtCore.QTimer()
            self._lung_recruit_timer.timeout.connect(
                self._get_lung_recruit_eta)
            self._lung_recruit_timer.start(500)
Exemple #4
0
    def thread_complete(self):
        '''
        Called when a thread ends.
        '''

        if self._running:
            print(
                "\033[91mERROR: The I/O thread finished! Going to start a new one...\033[0m"
            )
            self._n_attempts += 1
            self._running = False

            if self._n_attempts > 10:
                self._n_attempts = 0
                msg = MessageBox()

                # TODO: find a good exit point
                callbacks = {
                    msg.Retry: self.start_io_thread,
                    msg.Abort: lambda: sys.exit(-1)
                }

                fn = msg.critical("COMMUNICATION ERROR",
                                  "CANNOT COMMUNICATE WITH THE HARDWARE",
                                  "Check cable connections then click retry.",
                                  "COMMUNICATION ERROR", callbacks)
                fn()

            time.sleep(0.05)
            self.start_io_thread()
Exemple #5
0
    def set_run(self, run):
        '''
        Sets the run variable directly.
        Usually called at start up, when reading
        the run value from the ESP.

        arguments:
        - run: the run value (0 or 1) to set
        '''
        if self._run == run:
            return

        self._run = run

        if run == self.DONOT_RUN:
            # TODO: this should be an alarm
            msg = MessageBox()
            msg.critical(
                'STOPPING VENTILATION',
                'The hardware has stopped the ventilation.',
                'The microcontroller has stopped the ventilation by sending run = '
                + str(run),
                'The microcontroller has stopped the ventilation by sending run = '
                + str(run), {msg.Ok: self.show_start_button})()

        else:
            self.show_stop_button()
Exemple #6
0
    def handle_alarms(self):
        '''
        The callback method which is called periodically
        to check if the ESP raised any alarm or warning.
        If an alarm or warning is raised, a pop up
        window appears, showing the list of alarms and
        warnings. If more alarms or warnings add up, the
        window is updated automatically showing the latest
        errors.
        '''

        # Retrieve alarms and warnings from the ESP
        try:
            esp32alarm = self._esp32.get_alarms()
            esp32warning = self._esp32.get_warnings()
        except Exception as error:
            esp32alarm = None
            esp32warning = None
            err_msg = "Severe hardware communication error. "
            err_msg += "Cannot retrieve alarm and warning statuses from hardware."
            msg = MessageBox()
            fn = msg.critical("Critical", err_msg, str(error),
                              "Communication error", {
                                  msg.Retry: lambda: None,
                                  msg.Abort: lambda: None
                              })
            fn()

        #
        # ALARMS
        #
        if esp32alarm:
            errors = esp32alarm.strerror_all()
            errors_full = esp32alarm.strerror_all(append_err_no=True)

            alarm_codes = esp32alarm.get_alarm_codes()

            for alarm_code, err_str in zip(alarm_codes, errors):
                if alarm_code not in self._err_buttons:
                    btn = AlarmButton(ERROR, alarm_code, err_str,
                                      self._alarmlabel, self._snooze_btn)
                    self._alarmstack.addWidget(btn)
                    self._err_buttons[alarm_code] = btn

        #
        # WARNINGS
        #
        if esp32warning:
            errors = esp32warning.strerror_all()
            errors_full = esp32warning.strerror_all(append_err_no=True)

            warning_codes = esp32warning.get_alarm_codes()

            for warning_code, err_str in zip(warning_codes, errors):
                if warning_code not in self._war_buttons:
                    btn = AlarmButton(WARNING, warning_code, err_str,
                                      self._alarmlabel, self._snooze_btn)
                    self._alarmstack.addWidget(btn)
                    self._war_buttons[warning_code] = btn
    def _raise_comm_error(self, message):
        """
        Opens an error window with 'message'.
        """

        # TODO: find a good exit point
        msg = MessageBox()
        msg.critical('COMMUNICATION ERROR',
                     'Error communicating with the hardware', message,
                     '** COMMUNICATION ERROR **',
                     {msg.Ok: lambda: sys.exit(-1)})()
    def __init__(self, config, esp32):
        '''
        Constructor

        arguments:
        - config: the dictionary storing the configuration
        - esp32: the esp32serial object
        '''

        self._config = config
        self._esp32 = esp32

        self._alarm_raised = False
        self._warning_raised = False

        self._msg_err = MessageBox()
        self._msg_war = MessageBox()

        self._alarm_timer = QtCore.QTimer()
        self._alarm_timer.timeout.connect(self.handle_alarms)
        self._alarm_timer.start(config["alarminterval"] * 1000)
Exemple #9
0
    def _open_backup_warning(self):
        '''
        Opens a warning message if the ventilator
        changed from PSV to PCV ventilation.
        '''
        msg = MessageBox()

        callbacks = {msg.Ok: self._acknowlege_backup}

        msg.warning("CHANGE OF MODE",
                    "The ventilator changed from PSV to PCV mode.",
                    "The microcontroller raised the backup flag.", "",
                    callbacks)()
 def confirm_stop_pressed(self):
     '''
     Opens a window which asks for confirmation
     when the Stop button is pressed.
     '''
     self.button_autoassist.setDown(False)
     currentMode = self.mode_text.upper()
     msg = MessageBox()
     ok = msg.question("**STOPPING %s MODE**" % currentMode,
                       "Are you sure you want to STOP %s MODE?" %
                        currentMode,
                        None, "IMPORTANT", { msg.Yes: lambda: True,
                        msg.No: lambda: False })()
     return ok
Exemple #11
0
def test_MessageBox_Question(qtbot):
    msg = MessageBox()

    def foo():
        pass

    callbacks = {msg.Ok: foo}

    msg.question("CHANGE OF MODE",
                 "The ventilator changed from PSV to PCV mode.",
                 "The microcontroller raised the backup flag.", "", callbacks,
                 True)

    assert msg is not None
Exemple #12
0
 def send_signal(self, mode, pause):
     '''
     Sends signal the appropriate signal the ESP
     to pause inpiration or expiration.
     '''
     try:
         if not self._data_h.set_data(mode, int(pause)):
             raise Exception('Call to set_data failed.')
     except Exception as error:
         msg = MessageBox()
         fn = msg.critical("Critical",
                           "Severe hardware communication error",
                           str(error), "Communication error",
                           {msg.Ok: lambda: self.stop_timer()})
         fn()
Exemple #13
0
def start_gui():
    """
    Launch the MVM GUI
    """
    base_dir = os.path.dirname(__file__)
    settings_file = os.path.join(base_dir, 'default_settings.yaml')

    with open(settings_file) as mvm_settings:
        config = yaml.load(mvm_settings, Loader=yaml.FullLoader)
    print('Config:', yaml.dump(config), sep='\n')

    app = QtWidgets.QApplication(sys.argv)

    esp32 = None
    if 'fakeESP32' in sys.argv:
        print('******* Simulating communication with ESP32')
        esp32 = FakeESP32Serial(config)
    else:
        while True:
            try:
                err_msg = "Cannot communicate with port %s" % config['port']
                esp32 = ESP32Serial(config)
                break
            except SerialException as error:
                msg = MessageBox()
                retry = msg.critical("Do you want to retry?",
                                     "Severe hardware communication error",
                                     str(error) + err_msg, "Communication error",
                                     {msg.Retry: lambda: True,
                                      msg.Abort: lambda: sys.exit(-1)})
                if not retry():
                    break

    if esp32 is None:
        exit(-1)

    esp32.set("wdenable", 1)

    watchdog = QtCore.QTimer()
    watchdog.timeout.connect(esp32.set_watchdog)
    watchdog.start(config["wdinterval"] * 1000)

    window = MainWindow(config, esp32)
    window.show()
    app.exec_()
    esp32.set("wdenable", 0)
    def open_comm_error(self, error):
        '''
        Opens a message window if there is a communication error.
        '''
        msg = MessageBox()

        # TODO: find a good exit point
        callbacks = {
            msg.Retry: self._restart_timer,
            msg.Abort: lambda: sys.exit(-1)
        }

        fn = msg.critical(
            "COMMUNICATION ERROR", "CANNOT COMMUNICATE WITH THE HARDWARE",
            "Check cable connections then click retry.\n" + error,
            "COMMUNICATION ERROR", callbacks)
        fn()
    def send_signal(self, mode, pause):
        """
        Sends signal the appropriate signal the ESP
        to pause inpiration or expiration.

        arguments:
        - mode: The pause mode (either 'pause_exhale' or 'pause_inhale')
        - pause: Boolean for paused or not paused
        """
        try:
            if not self._data_h.set_data(mode, int(pause)):
                raise Exception('Call to set_data failed.')
        except Exception as error:
            msg = MessageBox()
            confirm_func = msg.critical(
                "Critical", "Severe hardware communication error", str(error),
                "Communication error", {msg.Ok: lambda: self.stop_timer(mode)})
            confirm_func()
    def set_run(self, run):
        '''
        Sets the run variable directly.
        Usually called at start up, when reading
        the run value from the ESP.
        '''
        if self.run == run:
            return

        if self.run == self.DO_RUN:
            msg = MessageBox()
            msg.critical('STOPPING VENTILATION',
                         'The hardware has stopped the ventilation.',
                         'The microcontroller has stopped the ventilation by sending run = '+str(run),
                         'The microcontroller has stopped the ventilation by sending run = '+str(run),
                         {msg.Ok: self._stop_abruptly})()

        else:
            self.toggle_start_stop()
Exemple #17
0
    def __init__(self, screen, data):
        self.screen = screen
        self.data = data

        self.stage_num = 1
        self.select_num = 0
        self.option_num = 0
        self.path = glob('stage/*/')
        self.new_path = []

        for i in range(len(self.path)):
            self.new_path.append(self.path[i].strip('stage\/'))

        StageSelect_font = pygame.font.Font("font/freesansbold.ttf", 55)
        Arrow_font = pygame.font.Font("font/freesansbold.ttf", 100)
        self.Stage_font = pygame.font.Font("font/freesansbold.ttf", 45)

        self.StageSelect_text = StageSelect_font.render("Stage Select", True, (255,255,255)) 
        self.RightArrow_text = Arrow_font.render(">", True, (255,255,255))
        self.LeftArrow_text = Arrow_font.render("<", True, (255,255,255))
        self.RightArrow_text = pygame.transform.rotate(self.RightArrow_text, 90)
        self.LeftArrow_text = pygame.transform.rotate(self.LeftArrow_text, 90)
        # ステージのテキスト情報をリストにする
        self.stage_text = [None]
        '''for i in range(3):
            text = "Stage" + str(i+1)
            self.stage_text.append(Stage_font.render(text, True, (255,255,255)))
'''
        # リストボックスの設定
        self.option_listbox = ListBox(self.screen, 50, 80, 250, 200, ['Back', 'Shop', 'Equip'], font_size=55, title="Menu")
        self.option_listbox.set_selectable([True, True, True])
        self.file_listbox = ListBox(self.screen, 940, 80, 120, 400, self.new_path, title="File")
    
        self.file_listbox.set_selectable([True, True])
        self.file_listbox()
        self.file_id = None

        # メッセージボックスの設定
        self.messagebox = MessageBox(self.screen, 130, 540, 900,  outline_color=(180,180,180), select='random')
        with open('data/message.txt', 'r', encoding='utf-8') as fp:
            self.messagebox += fp.readlines()

        self.clock = pygame.time.Clock()
def connect_esp32(config):
    try:
        if 'fakeESP32' in sys.argv:
            print('******* Simulating communication with ESP32')
            err_msg = "Cannot setup FakeESP32Serial"
            esp32 = FakeESP32Serial(config)
            esp32.set("wdenable", 1)
        else:
            err_msg = "Cannot communicate with port %s" % config['port']
            esp32 = ESP32Serial(config)
            esp32.set("wdenable", 1)
    except Exception as error:
        msg = MessageBox()
        fn = msg.critical("Do you want to retry?",
                          "Severe hardware communication error",
                          str(error) + err_msg, "Communication error",
                          { msg.Retry: lambda: connect_esp32(config),
                            msg.Abort: lambda: None})
        return fn()

    return esp32
def processComplet(document):
    bdd = getSheetByName(document, "base de données")
    config = getSheetByName(document, "configuration")

    blanc = config.getCellByPosition(0, 0).getPropertyValue('CellBackColor')
    plantation = config.getCellByPosition(1,
                                          0).getPropertyValue('CellBackColor')
    croissance = config.getCellByPosition(1,
                                          1).getPropertyValue('CellBackColor')
    recolte = config.getCellByPosition(1, 2).getPropertyValue('CellBackColor')
    erreur = config.getCellByPosition(1, 3).getPropertyValue('CellBackColor')

    pcSheet = Sheet(getSheetByName(document, "PC"), erreur)
    saSheet = Sheet(getSheetByName(document, "SA"), erreur)

    dicoLegume = dictionnaireLegumes(bdd)

    if dicoLegume is None:
        MessageBox(
            document,
            'Completer la feuille «base de données». Un filtre sur la croissance et la récolte = 0 peut aider',
            'Erreur bdd')
        document.getCurrentController().setActiveSheet(bdd)
        return None

    MessageBox(document, 'Lecture de la BDD fait', 'Step 1')

    def coloriser(sheet: Sheet, dicoLegumes):
        oosheet = sheet.oosheet
        typeDeSol = oosheet.Name
        erreurs = {"placePrise": [], "légume inexistant": [], 'ajout': {}}

        for cell in sheet.getValideCell():
            colonne = cell.CellAddress.Column
            year = sheet.convertColonneToYear(colonne)
            week = sheet.convertColonneToSemaine(colonne)
            ligne = cell.CellAddress.Row
            currentLegume = dicoLegumes.getInfos(
                cell.String, typeDeSol, sheet.convertColonneToSemaine(colonne))

            failed = False
            if currentLegume is None:
                erreurs["légume inexistant"].append(
                    (cell.String, typeDeSol,
                     convertSemaineToTrimestre(
                         sheet.convertColonneToSemaine(colonne))))
                failed = True
            else:
                for i in range(1, currentLegume.aColoriser() + 1):
                    if oosheet.getCellByPosition(
                            colonne + i,
                            ligne).getPropertyValue('CellBackColor') != blanc:
                        erreurs["placePrise"].append(cell)
                        failed = True
                        cell.setPropertyValue("CellBackColor", erreur)
                        break

            if failed == False:
                cell.setPropertyValue("CellBackColor", plantation)
                dureeCroissance = currentLegume.croissance
                dureeRecolte = currentLegume.recolte
                for i in range(1, currentLegume.croissance + 1):
                    oosheet.getCellByPosition(colonne + i,
                                              ligne).setPropertyValue(
                                                  'CellBackColor', croissance)
                for i in range(dureeCroissance + 1,
                               dureeCroissance + dureeRecolte + 1):
                    oosheet.getCellByPosition(colonne + i,
                                              ligne).setPropertyValue(
                                                  'CellBackColor', recolte)

                if year not in erreurs['ajout']:
                    erreurs['ajout'][year] = {}
                if currentLegume not in erreurs['ajout'][year]:
                    erreurs['ajout'][year][currentLegume] = {}
                if week not in erreurs['ajout'][year][currentLegume]:
                    erreurs['ajout'][year][currentLegume][week] = 0
                erreurs['ajout'][year][currentLegume][week] += 1

        erreurs["légume inexistant"] = set(erreurs["légume inexistant"])
        return erreurs

    def completeSemis(bilan, document):
        for site in bilan:
            for year in bilan[site]:
                semisDoc = getSheetByName(document,
                                          "Semis " + str(year % 2000))
                emptyLine = 1
                while semisDoc.getCellByPosition(0, emptyLine).String != "":
                    emptyLine += 1
                emptyLine += 1
                for legume in bilan[site][year]:
                    for week in bilan[site][year][legume]:
                        quantite = bilan[site][year][legume][week]
                        semisDoc.getCellRangeByName("A" +
                                                    str(emptyLine)).setFormula(
                                                        legume.nom)
                        semisDoc.getCellRangeByName(
                            "C" + str(emptyLine)).setFormula(site)
                        semisDoc.getCellRangeByName(
                            "D" + str(emptyLine)).setFormula(week -
                                                             legume.elevage)
                        semisDoc.getCellRangeByName(
                            "F" + str(emptyLine)).setFormula(week)
                        semisDoc.getCellRangeByName(
                            "J" + str(emptyLine)).setFormula(quantite)
                        semisDoc.getCellRangeByName("K" +
                                                    str(emptyLine)).setFormula(
                                                        legume.densite)
                        semisDoc.getCellRangeByName("N" +
                                                    str(emptyLine)).setFormula(
                                                        legume.nbCaisse *
                                                        quantite)
                        semisDoc.getCellRangeByName("H" +
                                                    str(emptyLine)).setFormula(
                                                        legume.croissance +
                                                        week)
                        emptyLine += 1

    bilanPC = coloriser(pcSheet, dicoLegume)
    MessageBox(document, 'Feuille PC : traitée', 'Step 2')

    bilanSA = coloriser(saSheet, dicoLegume)

    bilanAjout = {'PC': bilanPC['ajout'], 'SA': bilanSA['ajout']}
    completeSemis(bilanAjout, document)
    MessageBox(document, 'Feuille SA : traitée', 'Step 3')

    missingLegumes = bilanSA["légume inexistant"].union(
        bilanPC["légume inexistant"])
    if len(missingLegumes) > 0:
        addMissingLegumes(bdd, missingLegumes)
        MessageBox(document,
                   str(len(missingLegumes)) + ' légumes rajoutés à la feuille',
                   'Ajout légumes')
        document.getCurrentController().setActiveSheet(bdd)

    if (len(bilanSA["placePrise"]) + len(bilanPC["placePrise"])) > 0:
        MessageBox(
            document,
            str(len(bilanSA["placePrise"]) + len(bilanPC["placePrise"])) +
            ' légumes n\'ont pas assez de places et ont été mis en rouge',
            'Soucis planning')

    MessageBox(document, 'Fini', 'Fini')

    return None
Exemple #20
0
    logfile = open(logfilename, 'w').close() # Clear log file
    logging.basicConfig(format='%(asctime)s %(message)s', filename=logfilename, 
            level=logging.ERROR)

    text = open(filename, 'r')
    url = text.read()
    url = convertURL(url)

    seen_posts = [] # Store which posts we've already marked as potential signups
    checkpoint = 1 # 1 to ignore OP post

    startup_delay_thread = Thread(target=delaySignUpNotifications, args=())
    startup_delay_thread.daemon = True
    startup_delay_thread.start()

    messageBox = MessageBox()

    # Initialise Pushover Client
    client = None
    if SEND_PUSH_NOTIFICATIONS:
        try:
            client = Client(getenv("USER_KEY"), api_token=getenv("API_TOKEN"), device=getenv("DEVICE"))
            print("Pushover client initialised successfully")
        except:
            logging.exception("An exception occured. Stack trace below")

    while True:
        try:
            response = requests.get(url)
            parsed_json = json.loads(response.text)
            if not thread_limit_reached_message_displayed:
    def handle_alarms(self):
        '''
        The callback method which is called periodically
        to check if the ESP raised any alarm or warning.
        If an alarm or warning is raised, a pop up
        window appears, showing the list of alarms and
        warnings. If more alarms or warnings add up, the
        window is updated automatically showing the latest
        errors.
        '''

        # Retrieve alarms and warnings from the ESP
        try:
            esp32alarm = self._esp32.get_alarms()
            esp32warning = self._esp32.get_warnings()
        except Exception as error:
            esp32alarm = None
            esp32warning = None
            err_msg = "Severe hardware communication error. "
            err_msg += "Cannot retrieve alarm and warning statuses from hardware."
            msg = MessageBox()
            fn = msg.critical("Critical",
                              err_msg,
                              str(error),
                              "Communication error",
                              { msg.Retry: lambda: None,
                                msg.Abort: lambda: None })
            fn()

        #
        # ALARMS
        #
        if esp32alarm:
            errors = esp32alarm.strerror_all()
            errors_full = esp32alarm.strerror_all(append_err_no=True)

            if not self._alarm_raised:
                self._alarm_raised = True
                self._msg_err.critical("ALARM",
                             " - ".join(errors),
                             "\n".join(errors_full),
                             "Alarm received.",
                             { self._msg_err.Ignore: lambda:
                                 self.ok_worker('alarm', esp32alarm) },
                             do_not_block=True)
                self._msg_err.move(0, 100)
                self._msg_err.open()
            else:
                # If the window is already opened, just change the text
                self._msg_err.setInformativeText(" - ".join(errors))
                self._msg_err.setDetailedText("\n".join(errors_full))
                self._msg_err.raise_()


        #
        # WARNINGS
        #
        if esp32warning:
            errors = esp32warning.strerror_all()
            errors_full = esp32warning.strerror_all(append_err_no=True)

            if not self._warning_raised:
                self._warning_raised = True
                self._msg_war.warning("WARNING",
                             " - ".join(errors),
                             "\n".join(errors_full),
                             "Warning received.",
                             { self._msg_war.Ok: lambda:
                                 self.ok_worker('warning', esp32warning) },
                             do_not_block=True)
                self._msg_war.move(0, 300)
                self._msg_war.open()
            else:
                # If the window is already opened, just change the text
                self._msg_war.setInformativeText(" - ".join(errors))
                self._msg_war.setDetailedText("\n".join(errors_full))
                self._msg_war.raise_()
 def setUp(self):
     text = open("fixtures.json", 'r')
     self.parsed_json = json.loads(text.read())
     self.messageBoxMock = MessageBox()
     self.messageBoxMock.displayMessageBox = MagicMock()
     text.close()
    def send_values_to_hardware(self):
        '''
        Sends the currently set values to the ESP
        '''

        settings_to_file = {}
        for param, btn in self._all_spinboxes.items():
            settings_to_file[param] = self._current_values[param]

            # value is the variable to be sent to the hardware,
            # so possibly converted from the settings
            if param in ['enable_backup', 'pcv_trigger_enable']:
                value = int(self._current_values[param])
            elif param == 'insp_expir_ratio':
                i_over_e = 1. / self._current_values[param]
                value = 1. / (i_over_e + 1)
            else:
                value = self._current_values[param]

            if 'conversion' in self._config[param]:
                value = value * self._config[param]['conversion']
                if self._debug:
                    print('Converting value for', param, 'from',
                          value / self._config[param].get('conversion', 1.),
                          'to', value)

            if self._debug: print('Setting value of', param, ':', value)

            # Update the value in the config file
            self._config[param]['current'] = self._current_values[param]

            # Set color to red until we know the value has been set.
            btn.setStyleSheet("color: red")

            esp_param_name = self._config['esp_settable_param'][param]

            # Finally, try to set the value to the ESP
            # Raise an error message if this fails.
            try:
                if self._data_h.set_data(esp_param_name, value):
                    # Now set the color to green, as we know it has been set
                    btn.setStyleSheet("color: green")
            except Exception as error:
                msg = MessageBox()
                msg.critical(
                    "Critical", "Severe Hardware Communication Error",
                    str(error), "Communication error", {
                        msg.Retry: lambda: self.send_values_to_hardware,
                        msg.Abort: lambda: sys.exit(-1)
                    })()

            if param == 'respiratory_rate':
                self.toolsettings_lookup["respiratory_rate"].update(value)
            elif param == 'insp_expir_ratio':
                self.toolsettings_lookup["insp_expir_ratio"].update(
                    self._current_values[param])
            elif param == 'insp_pressure':
                self.toolsettings_lookup["insp_pressure"].update(value)

        settings_file = SettingsFile(self._config["settings_file_path"])
        settings_file.store(settings_to_file)