Esempio n. 1
0
def pid_del(pid_id):
    action = '{action} {controller}'.format(
        action=TRANSLATIONS['delete']['title'],
        controller=TRANSLATIONS['pid']['title'])
    error = []

    try:
        pid = PID.query.filter(
            PID.unique_id == pid_id).first()
        if pid.is_activated:
            pid_deactivate(pid_id)

        device_measurements = DeviceMeasurements.query.filter(
            DeviceMeasurements.device_id == pid_id).all()

        for each_measurement in device_measurements:
            delete_entry_with_id(DeviceMeasurements, each_measurement.unique_id)

        delete_entry_with_id(PID, pid_id)
        try:
            display_order = csv_to_list_of_str(DisplayOrder.query.first().math)
            display_order.remove(pid_id)
            DisplayOrder.query.first().function = list_to_csv(display_order)
        except Exception:  # id not in list
            pass
        db.session.commit()
    except Exception as except_msg:
        error.append(except_msg)

    flash_success_errors(error, action, url_for('routes_page.page_function'))
Esempio n. 2
0
def input_del(input_id):
    action = '{action} {controller}'.format(
        action=TRANSLATIONS['delete']['title'],
        controller=TRANSLATIONS['input']['title'])
    error = []

    try:
        input_dev = Input.query.filter(
            Input.unique_id == input_id).first()

        if input_dev.is_activated:
            input_deactivate_associated_controllers(input_id)
            controller_activate_deactivate('deactivate', 'Input', input_id)

        device_measurements = DeviceMeasurements.query.filter(
            DeviceMeasurements.device_id == input_id).all()

        for each_measurement in device_measurements:
            delete_entry_with_id(DeviceMeasurements, each_measurement.unique_id)

        delete_entry_with_id(Input, input_id)
        try:
            display_order = csv_to_list_of_str(
                DisplayOrder.query.first().inputs)
            display_order.remove(input_id)
            DisplayOrder.query.first().inputs = list_to_csv(display_order)
        except Exception:  # id not in list
            pass
        db.session.commit()
    except Exception as except_msg:
        error.append(except_msg)

    flash_success_errors(error, action, url_for('routes_page.page_data'))
Esempio n. 3
0
def action_del(form):
    """Delete a Conditional Action"""
    error = []
    action = '{action} {controller}'.format(
        action=TRANSLATIONS['delete']['title'],
        controller='{} {}'.format(TRANSLATIONS['conditional']['title'], TRANSLATIONS['actions']['title']))

    conditional = Conditional.query.filter(
        Conditional.unique_id == form.function_id.data).first()

    trigger = Trigger.query.filter(
        Trigger.unique_id == form.function_id.data).first()

    if ((conditional and conditional.is_activated) or
            (trigger and trigger.is_activated)):
        error.append("Deactivate the Conditional before deleting an Action")

    try:
        if not error:
            function_action_id = Actions.query.filter(
                Actions.unique_id == form.function_action_id.data).first().unique_id
            delete_entry_with_id(Actions, function_action_id)

    except sqlalchemy.exc.OperationalError as except_msg:
        error.append(except_msg)
    except sqlalchemy.exc.IntegrityError as except_msg:
        error.append(except_msg)
    except Exception as except_msg:
        error.append(except_msg)

    flash_success_errors(error, action, url_for('routes_page.page_function'))
Esempio n. 4
0
def lcd_del(lcd_id):
    action = '{action} {controller}'.format(
        action=TRANSLATIONS['delete']['title'],
        controller=TRANSLATIONS['lcd']['title'])
    error = []

    lcd = LCD.query.filter(
        LCD.unique_id == lcd_id).first()
    if lcd.is_activated:
        error.append(gettext("Deactivate LCD controller before modifying "
                             "its settings."))

    if not error:
        try:
            # Delete all LCD Displays
            lcd_displays = LCDData.query.filter(
                LCDData.lcd_id == lcd_id).all()
            for each_lcd_display in lcd_displays:
                lcd_display_del(each_lcd_display.unique_id, delete_last=True)

            # Delete LCD
            delete_entry_with_id(LCD, lcd_id)
            display_order = csv_to_list_of_str(DisplayOrder.query.first().lcd)
            display_order.remove(lcd_id)
            DisplayOrder.query.first().lcd = list_to_csv(display_order)
            db.session.commit()
        except Exception as except_msg:
            error.append(except_msg)
    flash_success_errors(error, action, url_for('routes_page.page_lcd'))
Esempio n. 5
0
def math_del(form_mod_math):
    action = '{action} {controller}'.format(
        action=TRANSLATIONS['delete']['title'],
        controller=TRANSLATIONS['math']['title'])
    error = []

    math_id = form_mod_math.math_id.data

    try:
        math = Math.query.filter(
            Math.unique_id == math_id).first()
        if math.is_activated:
            controller_activate_deactivate(
                'deactivate',
                'Math',
                form_mod_math.math_id.data)

        device_measurements = DeviceMeasurements.query.filter(
            DeviceMeasurements.device_id == math_id).all()

        for each_measurement in device_measurements:
            delete_entry_with_id(DeviceMeasurements, each_measurement.unique_id)

        delete_entry_with_id(Math, math_id)
        try:
            display_order = csv_to_list_of_str(DisplayOrder.query.first().math)
            display_order.remove(math_id)
            DisplayOrder.query.first().math = list_to_csv(display_order)
        except Exception:  # id not in list
            pass
        db.session.commit()
    except Exception as except_msg:
        error.append(except_msg)

    flash_success_errors(error, action, url_for('routes_page.page_data'))
Esempio n. 6
0
def lcd_display_del(lcd_data_id, delete_last=False):
    action = '{action} {controller}'.format(
        action=TRANSLATIONS['delete']['title'],
        controller=TRANSLATIONS['display']['title'])
    error = []

    lcd_data_this = LCDData.query.filter(
        LCDData.unique_id == lcd_data_id).first()
    lcd_data_all = LCDData.query.filter(
        LCDData.lcd_id == lcd_data_this.lcd_id).all()
    lcd = LCD.query.filter(
        LCD.unique_id == lcd_data_this.lcd_id).first()

    if lcd.is_activated:
        error.append(gettext("Deactivate LCD controller before modifying"
                             " its settings"))
    if not delete_last and len(lcd_data_all) < 2:
        error.append(gettext("The last display cannot be deleted"))

    if not error:
        try:
            delete_entry_with_id(LCDData,
                                 lcd_data_id)
            db.session.commit()
        except Exception as except_msg:
            error.append(except_msg)
    flash_success_errors(error, action, url_for('routes_page.page_lcd'))
Esempio n. 7
0
def function_del(function_id):
    """Delete a Function"""
    action = '{action} {controller}'.format(
        action=TRANSLATIONS['delete']['title'],
        controller=TRANSLATIONS['function']['title'])
    error = []

    try:
        # Delete Actions
        actions = Actions.query.filter(
            Actions.function_id == function_id).all()
        for each_action in actions:
            delete_entry_with_id(Actions,
                                 each_action.unique_id)

        delete_entry_with_id(Function, function_id)

        display_order = csv_to_list_of_str(DisplayOrder.query.first().function)
        display_order.remove(function_id)
        DisplayOrder.query.first().function = list_to_csv(display_order)
        db.session.commit()
    except Exception as except_msg:
        error.append(except_msg)

    flash_success_errors(error, action, url_for('routes_page.page_function'))
Esempio n. 8
0
def conditional_condition_del(form):
    """Delete a Conditional Condition"""
    error = []
    action = '{action} {controller}'.format(
        action=TRANSLATIONS['delete']['title'],
        controller='{} {}'.format(TRANSLATIONS['conditional']['title'],
                                  gettext("Condition")))

    cond = Conditional.query.filter(
        Conditional.unique_id == form.conditional_id.data).first()
    if cond.is_activated:
        error.append("Deactivate the Conditional before deleting a Condition")

    try:
        if not error:
            cond_condition_id = ConditionalConditions.query.filter(
                ConditionalConditions.unique_id == form.conditional_condition_id.data).first().unique_id
            delete_entry_with_id(ConditionalConditions, cond_condition_id)

    except sqlalchemy.exc.OperationalError as except_msg:
        error.append(except_msg)
    except sqlalchemy.exc.IntegrityError as except_msg:
        error.append(except_msg)
    except Exception as except_msg:
        error.append(except_msg)

    flash_success_errors(error, action, url_for('routes_page.page_function'))
Esempio n. 9
0
def method_del(method_id):
    action = '{action} {controller}'.format(
        action=TRANSLATIONS['delete']['title'],
        controller=TRANSLATIONS['method']['title'])
    error = []

    try:
        delete_entry_with_id(Method,
                             method_id)
    except Exception as except_msg:
        error.append(except_msg)
    flash_success_errors(error, action, url_for('routes_method.method_list'))
Esempio n. 10
0
def energy_usage_delete(energy_usage_id):
    action = '{action} {controller}'.format(
        action=TRANSLATIONS['delete']['title'],
        controller=TRANSLATIONS['energy_usage']['title'])
    error = []

    try:
        delete_entry_with_id(EnergyUsage, energy_usage_id)
    except Exception as except_msg:
        error.append(except_msg)

    flash_success_errors(error, action, url_for('routes_page.page_data'))
Esempio n. 11
0
def tag_del(form):
    action = '{action} {controller}'.format(
        action=TRANSLATIONS['delete']['title'],
        controller=TRANSLATIONS['tag']['title'])
    error = []

    if Notes.query.filter(Notes.tags.ilike("%{0}%".format(form.tag_unique_id.data))).first():
        error.append("Cannot delete tag because it's currently assicuated with at least one note")

    if not error:
        delete_entry_with_id(NoteTags, form.tag_unique_id.data)

    flash_success_errors(error, action, url_for('routes_page.page_notes'))
Esempio n. 12
0
def output_del(form_output):
    action = '{action} {controller}'.format(
        action=TRANSLATIONS['delete']['title'],
        controller=TRANSLATIONS['output']['title'])
    error = []

    try:
        delete_entry_with_id(Output,
                             form_output.output_id.data)
        display_order = csv_to_list_of_str(DisplayOrder.query.first().output)
        display_order.remove(form_output.output_id.data)
        DisplayOrder.query.first().output = list_to_csv(display_order)
        db.session.commit()
        manipulate_output('Delete', form_output.output_id.data)
    except Exception as except_msg:
        error.append(except_msg)
    flash_success_errors(error, action, url_for('routes_page.page_output'))
Esempio n. 13
0
def dashboard_del(form_base):
    """Delete an item on the dashboard"""
    action = '{action} {controller}'.format(
        action=TRANSLATIONS['delete']['title'],
        controller=TRANSLATIONS['dashboard']['title'])
    error = []

    try:
        delete_entry_with_id(Dashboard,
                             form_base.dashboard_id.data)
        display_order = csv_to_list_of_str(DisplayOrder.query.first().dashboard)
        display_order.remove(form_base.dashboard_id.data)
        DisplayOrder.query.first().dashboard = list_to_csv(display_order)
        db.session.commit()
    except Exception as except_msg:
        error.append(except_msg)
    flash_success_errors(error, action, url_for('routes_page.page_dashboard'))
Esempio n. 14
0
def note_del(form):
    action = '{action} {controller}'.format(
        action=TRANSLATIONS['delete']['title'],
        controller=TRANSLATIONS['note']['title'])
    error = []

    if not form.note_unique_id.data:
        error.append("Unique id is empty")

    note = Notes.query.filter(
        Notes.unique_id == form.note_unique_id.data).first()

    if note.files:
        delete_string = "{dir}/{id}*".format(
            dir=PATH_NOTE_ATTACHMENTS, id=form.note_unique_id.data)
        for filename in glob.glob(delete_string):
            os.remove(filename)

    if not error:
        delete_entry_with_id(Notes, form.note_unique_id.data)

    flash_success_errors(error, action, url_for('routes_page.page_notes'))
Esempio n. 15
0
def trigger_del(trigger_id):
    """Delete a Trigger"""
    error = []
    action = '{action} {controller}'.format(
        action=TRANSLATIONS['delete']['title'],
        controller=TRANSLATIONS['trigger']['title'])

    trigger = Trigger.query.filter(
        Trigger.unique_id == trigger_id).first()

    # Deactivate trigger if active
    if trigger.is_activated:
        trigger_deactivate(trigger_id)

    try:
        if not error:
            # Delete Actions
            actions = Actions.query.filter(
                Actions.function_id == trigger_id).all()
            for each_action in actions:
                delete_entry_with_id(Actions,
                                     each_action.unique_id)

            delete_entry_with_id(Trigger, trigger_id)

            display_order = csv_to_list_of_str(DisplayOrder.query.first().function)
            display_order.remove(trigger_id)
            DisplayOrder.query.first().function = list_to_csv(display_order)
            db.session.commit()
    except sqlalchemy.exc.OperationalError as except_msg:
        error.append(except_msg)
    except sqlalchemy.exc.IntegrityError as except_msg:
        error.append(except_msg)
    except Exception as except_msg:
        error.append(except_msg)

    flash_success_errors(error, action, url_for('routes_page.page_function'))
Esempio n. 16
0
def trigger_del(trigger_id):
    """Delete a Trigger"""
    error = []
    action = '{action} {controller}'.format(
        action=TRANSLATIONS['delete']['title'],
        controller=TRANSLATIONS['trigger']['title'])

    trigger = Trigger.query.filter(Trigger.unique_id == trigger_id).first()

    # Deactivate trigger if active
    if trigger.is_activated:
        trigger_deactivate(trigger_id)

    try:
        if not error:
            # Delete Actions
            actions = Actions.query.filter(
                Actions.function_id == trigger_id).all()
            for each_action in actions:
                delete_entry_with_id(Actions, each_action.unique_id)

            delete_entry_with_id(Trigger, trigger_id)

            display_order = csv_to_list_of_str(
                DisplayOrder.query.first().function)
            display_order.remove(trigger_id)
            DisplayOrder.query.first().function = list_to_csv(display_order)
            db.session.commit()
    except sqlalchemy.exc.OperationalError as except_msg:
        error.append(except_msg)
    except sqlalchemy.exc.IntegrityError as except_msg:
        error.append(except_msg)
    except Exception as except_msg:
        error.append(except_msg)

    flash_success_errors(error, action, url_for('routes_page.page_function'))
Esempio n. 17
0
def function_del(function_id):
    """Delete a Function"""
    action = '{action} {controller}'.format(
        action=TRANSLATIONS['delete']['title'],
        controller=TRANSLATIONS['function']['title'])
    error = []

    try:
        # Delete Actions
        actions = Actions.query.filter(
            Actions.function_id == function_id).all()
        for each_action in actions:
            delete_entry_with_id(Actions, each_action.unique_id)

        delete_entry_with_id(Function, function_id)

        display_order = csv_to_list_of_str(DisplayOrder.query.first().function)
        display_order.remove(function_id)
        DisplayOrder.query.first().function = list_to_csv(display_order)
        db.session.commit()
    except Exception as except_msg:
        error.append(except_msg)

    flash_success_errors(error, action, url_for('routes_page.page_function'))
Esempio n. 18
0
def conditional_condition_del(form):
    """Delete a Conditional Condition"""
    messages = {
        "success": [],
        "info": [],
        "warning": [],
        "error": []
    }

    condition = ConditionalConditions.query.filter(
        ConditionalConditions.unique_id == form.conditional_condition_id.data).first()
    if not condition:
        messages["error"].append("Condition not found")

    conditional = Conditional.query.filter(
        Conditional.unique_id == condition.conditional_id).first()
    if conditional.is_activated:
        messages["error"].append("Deactivate the Conditional before deleting a Condition")

    try:
        if not messages["error"]:
            delete_entry_with_id(
                ConditionalConditions, condition.unique_id, flash_message=False)
            messages["success"].append('{action} {controller}'.format(
                action=TRANSLATIONS['delete']['title'],
                controller='{} {}'.format(TRANSLATIONS['conditional']['title'],
                                          gettext("Condition"))))

    except sqlalchemy.exc.OperationalError as except_msg:
        messages["error"].append(str(except_msg))
    except sqlalchemy.exc.IntegrityError as except_msg:
        messages["error"].append(str(except_msg))
    except Exception as except_msg:
        messages["error"].append(str(except_msg))

    return messages
Esempio n. 19
0
def lcd_display_del(lcd_data_id, delete_last=False):
    action = u'{action} {controller}'.format(action=gettext(u"Delete"),
                                             controller=gettext(u"Display"))
    error = []

    lcd_data_this = LCDData.query.filter(LCDData.id == lcd_data_id).first()
    lcd_data_all = LCDData.query.filter(
        LCDData.lcd_id == lcd_data_this.lcd_id).all()
    lcd = LCD.query.filter(LCD.id == lcd_data_this.lcd_id).first()

    if lcd.is_activated:
        error.append(
            gettext(u"Deactivate LCD controller before modifying"
                    u" its settings"))
    if not delete_last and len(lcd_data_all) < 2:
        error.append(gettext(u"The last display cannot be deleted"))

    if not error:
        try:
            delete_entry_with_id(LCDData, lcd_data_id)
            db.session.commit()
        except Exception as except_msg:
            error.append(except_msg)
    flash_success_errors(error, action, url_for('page_routes.page_lcd'))
Esempio n. 20
0
def math_del(form_mod_math):
    action = '{action} {controller}'.format(action=gettext("Delete"),
                                            controller=gettext("Math"))
    error = []

    try:
        math = Math.query.filter(
            Math.unique_id == form_mod_math.math_id.data).first()
        if math.is_activated:
            controller_activate_deactivate('deactivate', 'Math',
                                           form_mod_math.math_id.data)

        delete_entry_with_id(Math, form_mod_math.math_id.data)
        try:
            display_order = csv_to_list_of_str(DisplayOrder.query.first().math)
            display_order.remove(form_mod_math.math_id.data)
            DisplayOrder.query.first().math = list_to_csv(display_order)
        except Exception:  # id not in list
            pass
        db.session.commit()
    except Exception as except_msg:
        error.append(except_msg)

    flash_success_errors(error, action, url_for('routes_page.page_data'))
Esempio n. 21
0
def conditional_del(cond_id):
    """Delete a Conditional"""
    error = []
    action = '{action} {controller}'.format(
        action=TRANSLATIONS['delete']['title'],
        controller=TRANSLATIONS['conditional']['title'])

    cond = Conditional.query.filter(
        Conditional.unique_id == cond_id).first()

    # Deactivate conditional if active
    if cond.is_activated:
        conditional_deactivate(cond_id)

    try:
        if not error:
            # Delete conditions
            conditions = ConditionalConditions.query.filter(
                ConditionalConditions.conditional_id == cond_id).all()
            for each_condition in conditions:
                delete_entry_with_id(ConditionalConditions,
                                     each_condition.unique_id)

            # Delete Actions
            actions = Actions.query.filter(
                Actions.function_id == cond_id).all()
            for each_action in actions:
                delete_entry_with_id(Actions,
                                     each_action.unique_id)

            delete_entry_with_id(Conditional, cond_id)

            display_order = csv_to_list_of_str(DisplayOrder.query.first().function)
            display_order.remove(cond_id)
            DisplayOrder.query.first().function = list_to_csv(display_order)

            try:
                file_path = os.path.join(
                    PATH_PYTHON_CODE_USER, 'conditional_{}.py'.format(
                        cond.unique_id))
                os.remove(file_path)
            except:
                pass

            db.session.commit()
    except sqlalchemy.exc.OperationalError as except_msg:
        error.append(except_msg)
    except sqlalchemy.exc.IntegrityError as except_msg:
        error.append(except_msg)
    except Exception as except_msg:
        error.append(except_msg)

    flash_success_errors(error, action, url_for('routes_page.page_function'))
Esempio n. 22
0
def controller_del(cond_id):
    """Delete a custom Function"""
    messages = {"success": [], "info": [], "warning": [], "error": []}

    cond = CustomController.query.filter(
        CustomController.unique_id == cond_id).first()

    # Deactivate controller if active
    if cond.is_activated:
        controller_deactivate(cond_id)

    try:
        if not messages["error"]:
            device_measurements = DeviceMeasurements.query.filter(
                DeviceMeasurements.device_id == cond_id).all()
            for each_measurement in device_measurements:
                delete_entry_with_id(DeviceMeasurements,
                                     each_measurement.unique_id,
                                     flash_message=False)

            delete_entry_with_id(CustomController,
                                 cond_id,
                                 flash_message=False)

            channels = FunctionChannel.query.filter(
                FunctionChannel.function_id == cond_id).all()
            for each_channel in channels:
                delete_entry_with_id(FunctionChannel,
                                     each_channel.unique_id,
                                     flash_message=False)

            messages["success"].append('{action} {controller}'.format(
                action=TRANSLATIONS['delete']['title'],
                controller=TRANSLATIONS['controller']['title']))

            try:
                file_path = os.path.join(
                    PATH_PYTHON_CODE_USER,
                    'conditional_{}.py'.format(cond.unique_id))
                os.remove(file_path)
            except:
                pass

            db.session.commit()
    except sqlalchemy.exc.OperationalError as except_msg:
        messages["error"].append(str(except_msg))
    except sqlalchemy.exc.IntegrityError as except_msg:
        messages["error"].append(str(except_msg))
    except Exception as except_msg:
        messages["error"].append(str(except_msg))

    return messages
Esempio n. 23
0
def conditional_del(cond_id):
    """Delete a Conditional."""
    messages = {"success": [], "info": [], "warning": [], "error": []}

    cond = Conditional.query.filter(Conditional.unique_id == cond_id).first()

    # Deactivate conditional if active
    if cond.is_activated:
        conditional_deactivate(cond_id)

    try:
        if not messages["error"]:
            # Delete conditions
            conditions = ConditionalConditions.query.filter(
                ConditionalConditions.conditional_id == cond_id).all()
            for each_condition in conditions:
                delete_entry_with_id(ConditionalConditions,
                                     each_condition.unique_id,
                                     flash_message=False)

            # Delete Actions
            actions = Actions.query.filter(
                Actions.function_id == cond_id).all()
            for each_action in actions:
                delete_entry_with_id(Actions,
                                     each_action.unique_id,
                                     flash_message=False)

            delete_entry_with_id(Conditional, cond_id, flash_message=False)

            messages["success"].append('{action} {controller}'.format(
                action=TRANSLATIONS['delete']['title'],
                controller=TRANSLATIONS['conditional']['title']))

            try:
                file_path = os.path.join(
                    PATH_PYTHON_CODE_USER,
                    'conditional_{}.py'.format(cond.unique_id))
                os.remove(file_path)
            except:
                pass

            db.session.commit()
    except sqlalchemy.exc.OperationalError as except_msg:
        messages["error"].append(str(except_msg))
    except sqlalchemy.exc.IntegrityError as except_msg:
        messages["error"].append(str(except_msg))
    except Exception as except_msg:
        messages["error"].append(str(except_msg))

    return messages
Esempio n. 24
0
def controller_del(cond_id):
    """Delete a Conditional"""
    error = []
    action = '{action} {controller}'.format(
        action=TRANSLATIONS['delete']['title'],
        controller=TRANSLATIONS['controller']['title'])

    cond = CustomController.query.filter(
        CustomController.unique_id == cond_id).first()

    # Deactivate controller if active
    if cond.is_activated:
        controller_deactivate(cond_id)

    try:
        if not error:
            device_measurements = DeviceMeasurements.query.filter(
                DeviceMeasurements.device_id == cond_id).all()
            for each_measurement in device_measurements:
                delete_entry_with_id(DeviceMeasurements,
                                     each_measurement.unique_id)

            delete_entry_with_id(CustomController, cond_id)

            channels = FunctionChannel.query.filter(
                FunctionChannel.function_id == cond_id).all()
            for each_channel in channels:
                delete_entry_with_id(FunctionChannel, each_channel.unique_id)

            display_order = csv_to_list_of_str(
                DisplayOrder.query.first().function)
            display_order.remove(cond_id)
            DisplayOrder.query.first().function = list_to_csv(display_order)

            try:
                file_path = os.path.join(
                    PATH_PYTHON_CODE_USER,
                    'conditional_{}.py'.format(cond.unique_id))
                os.remove(file_path)
            except:
                pass

            db.session.commit()
    except sqlalchemy.exc.OperationalError as except_msg:
        error.append(except_msg)
    except sqlalchemy.exc.IntegrityError as except_msg:
        error.append(except_msg)
    except Exception as except_msg:
        error.append(except_msg)

    flash_success_errors(error, action, url_for('routes_page.page_function'))
Esempio n. 25
0
def input_del(input_id):
    messages = {"success": [], "info": [], "warning": [], "error": []}

    try:
        input_dev = Input.query.filter(Input.unique_id == input_id).first()

        if input_dev.is_activated:
            input_deactivate_associated_controllers(input_id)
            controller_activate_deactivate('deactivate', 'Input', input_id)

        device_measurements = DeviceMeasurements.query.filter(
            DeviceMeasurements.device_id == input_id).all()

        for each_measurement in device_measurements:
            delete_entry_with_id(DeviceMeasurements,
                                 each_measurement.unique_id,
                                 flash_message=False)

        delete_entry_with_id(Input, input_id, flash_message=False)

        channels = InputChannel.query.filter(
            InputChannel.input_id == input_id).all()
        for each_channel in channels:
            delete_entry_with_id(InputChannel,
                                 each_channel.unique_id,
                                 flash_message=False)

        try:
            display_order = csv_to_list_of_str(
                DisplayOrder.query.first().inputs)
            display_order.remove(input_id)
            DisplayOrder.query.first().inputs = list_to_csv(display_order)
        except Exception:  # id not in list
            pass

        try:
            file_path = os.path.join(
                PATH_PYTHON_CODE_USER,
                'input_python_code_{}.py'.format(input_dev.unique_id))
            os.remove(file_path)
        except:
            pass

        db.session.commit()
        messages["success"].append('{action} {controller}'.format(
            action=TRANSLATIONS['delete']['title'],
            controller=TRANSLATIONS['input']['title']))
    except Exception as except_msg:
        messages["error"].append(str(except_msg))

    return messages
Esempio n. 26
0
def input_del(input_id):
    action = '{action} {controller}'.format(
        action=TRANSLATIONS['delete']['title'],
        controller=TRANSLATIONS['input']['title'])
    error = []

    try:
        input_dev = Input.query.filter(Input.unique_id == input_id).first()

        if input_dev.is_activated:
            input_deactivate_associated_controllers(input_id)
            controller_activate_deactivate('deactivate', 'Input', input_id)

        device_measurements = DeviceMeasurements.query.filter(
            DeviceMeasurements.device_id == input_id).all()

        for each_measurement in device_measurements:
            delete_entry_with_id(DeviceMeasurements,
                                 each_measurement.unique_id)

        delete_entry_with_id(Input, input_id)

        channels = InputChannel.query.filter(
            InputChannel.input_id == input_id).all()
        for each_channel in channels:
            delete_entry_with_id(InputChannel, each_channel.unique_id)

        try:
            display_order = csv_to_list_of_str(
                DisplayOrder.query.first().inputs)
            display_order.remove(input_id)
            DisplayOrder.query.first().inputs = list_to_csv(display_order)
        except Exception:  # id not in list
            pass

        try:
            file_path = os.path.join(
                PATH_PYTHON_CODE_USER,
                'input_python_code_{}.py'.format(input_dev.unique_id))
            os.remove(file_path)
        except:
            pass

        db.session.commit()
    except Exception as except_msg:
        error.append(except_msg)

    flash_success_errors(error, action, url_for('routes_page.page_input'))
Esempio n. 27
0
def output_del(form_output):
    messages = {
        "success": [],
        "info": [],
        "warning": [],
        "error": []
    }

    try:
        device_measurements = DeviceMeasurements.query.filter(
            DeviceMeasurements.device_id == form_output.output_id.data).all()

        for each_measurement in device_measurements:
            delete_entry_with_id(
                DeviceMeasurements,
                each_measurement.unique_id,
                flash_message=False)

        delete_entry_with_id(
            Output,
            form_output.output_id.data,
            flash_message=False)

        channels = OutputChannel.query.filter(
            OutputChannel.output_id == form_output.output_id.data).all()
        for each_channel in channels:
            delete_entry_with_id(
                OutputChannel,
                each_channel.unique_id,
                flash_message=False)

        db.session.commit()
        messages["success"].append('{action} {controller}'.format(
            action=TRANSLATIONS['delete']['title'],
            controller=TRANSLATIONS['output']['title']))

        if not current_app.config['TESTING']:
            new_messages = manipulate_output(
                'Delete', form_output.output_id.data)
            messages["error"].extend(new_messages["error"])
            messages["success"].extend(new_messages["success"])
    except Exception as except_msg:
        messages["error"].append(str(except_msg))

    return messages
Esempio n. 28
0
def input_mod(form_mod, request_form):
    action = '{action} {controller}'.format(
        action=TRANSLATIONS['modify']['title'],
        controller=TRANSLATIONS['input']['title'])
    error = []

    dict_inputs = parse_input_information()

    try:
        mod_input = Input.query.filter(
            Input.unique_id == form_mod.input_id.data).first()

        if mod_input.is_activated:
            error.append(
                gettext("Deactivate controller before modifying its settings"))

        if (mod_input.device == 'AM2315' and form_mod.period.data < 7):
            error.append(
                gettext("Choose a Read Period equal to or greater than 7. The "
                        "AM2315 may become unresponsive if the period is "
                        "below 7."))

        if (mod_input.device != 'EDGE' and
            (mod_input.pre_output_duration
             and form_mod.period.data < mod_input.pre_output_duration)):
            error.append(
                gettext("The Read Period cannot be less than the Pre Output "
                        "Duration"))

        if (form_mod.uart_location.data
                and not os.path.exists(form_mod.uart_location.data)):
            error.append(
                gettext(
                    "Invalid device or improper permissions to read device"))

        if ('gpio_location' in dict_inputs[mod_input.device]['options_enabled']
                and form_mod.gpio_location.data is None):
            error.append(gettext("Pin (GPIO) must be set"))

        mod_input.name = form_mod.name.data

        if form_mod.location.data:
            mod_input.location = form_mod.location.data
        if form_mod.i2c_location.data:
            mod_input.i2c_location = form_mod.i2c_location.data
        if form_mod.ftdi_location.data:
            mod_input.ftdi_location = form_mod.ftdi_location.data
        if form_mod.uart_location.data:
            mod_input.uart_location = form_mod.uart_location.data
        if form_mod.gpio_location.data and form_mod.gpio_location.data is not None:
            mod_input.gpio_location = form_mod.gpio_location.data

        if form_mod.power_output_id.data:
            mod_input.power_output_id = form_mod.power_output_id.data
        else:
            mod_input.power_output_id = None

        if form_mod.pre_output_id.data:
            mod_input.pre_output_id = form_mod.pre_output_id.data
        else:
            mod_input.pre_output_id = None

        # Enable/disable Channels
        measurements = DeviceMeasurements.query.filter(
            DeviceMeasurements.device_id == form_mod.input_id.data).all()
        if form_mod.measurements_enabled.data:
            for each_measurement in measurements:
                if each_measurement.unique_id in form_mod.measurements_enabled.data:
                    each_measurement.is_enabled = True
                else:
                    each_measurement.is_enabled = False

        mod_input.log_level_debug = form_mod.log_level_debug.data
        mod_input.i2c_bus = form_mod.i2c_bus.data
        mod_input.baud_rate = form_mod.baud_rate.data
        mod_input.pre_output_duration = form_mod.pre_output_duration.data
        mod_input.pre_output_during_measure = form_mod.pre_output_during_measure.data

        if form_mod.period.data:
            mod_input.period = form_mod.period.data
        if form_mod.start_offset.data:
            mod_input.start_offset = form_mod.start_offset.data

        mod_input.resolution = form_mod.resolution.data
        mod_input.resolution_2 = form_mod.resolution_2.data
        mod_input.sensitivity = form_mod.sensitivity.data
        mod_input.calibrate_sensor_measure = form_mod.calibrate_sensor_measure.data
        mod_input.cmd_command = form_mod.cmd_command.data
        mod_input.thermocouple_type = form_mod.thermocouple_type.data
        mod_input.ref_ohm = form_mod.ref_ohm.data
        # Serial options
        mod_input.pin_clock = form_mod.pin_clock.data
        mod_input.pin_cs = form_mod.pin_cs.data
        mod_input.pin_mosi = form_mod.pin_mosi.data
        mod_input.pin_miso = form_mod.pin_miso.data
        # Bluetooth options
        mod_input.bt_adapter = form_mod.bt_adapter.data

        mod_input.adc_gain = form_mod.adc_gain.data
        mod_input.adc_resolution = form_mod.adc_resolution.data
        mod_input.adc_sample_speed = form_mod.adc_sample_speed.data

        # Switch options
        mod_input.switch_edge = form_mod.switch_edge.data
        mod_input.switch_bouncetime = form_mod.switch_bouncetime.data
        mod_input.switch_reset_period = form_mod.switch_reset_period.data
        # PWM and RPM options
        mod_input.weighting = form_mod.weighting.data
        mod_input.rpm_pulses_per_rev = form_mod.rpm_pulses_per_rev.data
        mod_input.sample_time = form_mod.sample_time.data
        # Server options
        mod_input.port = form_mod.port.data
        mod_input.times_check = form_mod.times_check.data
        mod_input.deadline = form_mod.deadline.data
        # SHT sensor options
        if form_mod.sht_voltage.data:
            mod_input.sht_voltage = form_mod.sht_voltage.data

        # Custom options
        try:
            custom_options_json_presave = json.loads(mod_input.custom_options)
        except:
            logger.error("Malformed JSON")
            custom_options_json_presave = {}

        # Generate string to save from custom options
        error, custom_options_json_postsave = custom_options_return_json(
            error, dict_inputs, request_form, device=mod_input.device)

        if 'execute_at_modification' in dict_inputs[mod_input.device]:
            (allow_saving, mod_input, custom_options
             ) = dict_inputs[mod_input.device]['execute_at_modification'](
                 mod_input, request_form, custom_options_json_presave,
                 json.loads(custom_options_json_postsave))
            custom_options = json.dumps(
                custom_options)  # Convert from dict to JSON string
            if not allow_saving:
                error.append(
                    "execute_at_modification() would not allow widget options to be saved"
                )
        else:
            custom_options = custom_options_json_postsave

        mod_input.custom_options = custom_options

        if not error:
            # Add or delete channels for variable measurement Inputs
            if ('measurements_variable_amount' in dict_inputs[mod_input.device]
                    and dict_inputs[
                        mod_input.device]['measurements_variable_amount']):
                channels = DeviceMeasurements.query.filter(
                    DeviceMeasurements.device_id == form_mod.input_id.data)

                if channels.count() != form_mod.num_channels.data:
                    # Delete channels
                    if form_mod.num_channels.data < channels.count():
                        for index, each_channel in enumerate(channels.all()):
                            if index + 1 >= channels.count():
                                delete_entry_with_id(DeviceMeasurements,
                                                     each_channel.unique_id)

                    # Add channels
                    elif form_mod.num_channels.data > channels.count():
                        start_number = channels.count()
                        for index in range(start_number,
                                           form_mod.num_channels.data):
                            new_measurement = DeviceMeasurements()
                            new_measurement.name = ""
                            new_measurement.device_id = mod_input.unique_id
                            new_measurement.measurement = ""
                            new_measurement.unit = ""
                            new_measurement.channel = index
                            new_measurement.save()

            db.session.commit()

    except Exception as except_msg:
        error.append(except_msg)

    flash_success_errors(error, action, url_for('routes_page.page_data'))
Esempio n. 29
0
def method_mod(form_mod_method):
    action = '{action} {controller}'.format(action=gettext("Modify"),
                                            controller=gettext("Method"))
    error = []

    method = Method.query.filter(
        Method.unique_id == form_mod_method.method_id.data).first()
    method_data = MethodData.query.filter(
        MethodData.unique_id == form_mod_method.method_data_id.data).first()
    display_order = csv_to_list_of_str(method.method_order)

    try:
        if form_mod_method.Delete.data:
            delete_entry_with_id(MethodData,
                                 form_mod_method.method_data_id.data)
            if form_mod_method.method_select.data != 'output':
                method_order = Method.query.filter(
                    Method.unique_id == method.unique_id).first()
                display_order = csv_to_list_of_str(method_order.method_order)
                display_order.remove(method_data.unique_id)
                method_order.method_order = list_to_csv(display_order)
                db.session.commit()
            return 0

        if form_mod_method.rename.data:
            method.name = form_mod_method.name.data
            db.session.commit()
            return 0

        # Ensure data is valid
        if validate_method_data(form_mod_method, method):
            return 1

        if form_mod_method.method_select.data == 'setpoint':
            if method.method_type == 'Date':
                start_time = datetime.strptime(form_mod_method.time_start.data,
                                               '%Y-%m-%d %H:%M:%S')
                end_time = datetime.strptime(form_mod_method.time_end.data,
                                             '%Y-%m-%d %H:%M:%S')

                # Ensure the start time comes after the previous entry's end time
                # and the end time comes before the next entry's start time
                # method_id_set is the id given to all method entries, 'method_id', not 'id'
                previous_method = None
                next_method = None
                for index, each_order in enumerate(display_order):
                    if each_order == method_data.unique_id:
                        if len(display_order) > 1 and index > 0:
                            previous_method = MethodData.query.filter(
                                MethodData.unique_id == display_order[
                                    index - 1]).first()
                        if len(display_order) > index + 1:
                            next_method = MethodData.query.filter(
                                MethodData.unique_id == display_order[
                                    index + 1]).first()

                if previous_method is not None and previous_method.time_end is not None:
                    previous_end_time = datetime.strptime(
                        previous_method.time_end, '%Y-%m-%d %H:%M:%S')
                    if previous_end_time is not None and start_time < previous_end_time:
                        error.append(
                            gettext(
                                "The entry start time (%(st)s) cannot "
                                "overlap the previous entry's end time "
                                "(%(et)s)",
                                st=start_time,
                                et=previous_end_time))

                if next_method is not None and next_method.time_start is not None:
                    next_start_time = datetime.strptime(
                        next_method.time_start, '%Y-%m-%d %H:%M:%S')
                    if next_start_time is not None and end_time > next_start_time:
                        error.append(
                            gettext(
                                "The entry end time (%(et)s) cannot "
                                "overlap the next entry's start time "
                                "(%(st)s)",
                                et=end_time,
                                st=next_start_time))

                method_data.time_start = start_time.strftime(
                    '%Y-%m-%d %H:%M:%S')
                method_data.time_end = end_time.strftime('%Y-%m-%d %H:%M:%S')

            elif method.method_type == 'Duration':
                if method_data.duration_sec == 0:
                    method_data.duration_end = form_mod_method.duration_end.data
                else:
                    method_data.duration_sec = form_mod_method.duration.data

            elif method.method_type == 'Daily':
                method_data.time_start = form_mod_method.daily_time_start.data
                method_data.time_end = form_mod_method.daily_time_end.data

            method_data.setpoint_start = form_mod_method.setpoint_start.data
            method_data.setpoint_end = form_mod_method.setpoint_end.data

        elif form_mod_method.method_select.data == 'output':
            if method.method_type == 'Date':
                method_data.time_start = form_mod_method.output_time.data
            elif method.method_type == 'Duration':
                method_data.duration_sec = form_mod_method.duration.data
                if form_mod_method.duration_sec.data == 0:
                    method_data.duration_end = form_mod_method.duration_end.data
            if form_mod_method.output_id.data == '':
                method_data.output_id = None
            else:
                method_data.output_id = form_mod_method.output_id.data
            method_data.output_state = form_mod_method.output_state.data
            method_data.output_duration = form_mod_method.output_duration.data

        elif method.method_type == 'DailySine':
            if form_mod_method.method_select.data == 'output':
                method_data.time_start = form_mod_method.output_time.data
                if form_mod_method.output_id.data == '':
                    method_data.output_id = None
                else:
                    method_data.output_id = form_mod_method.output_id.data
                method_data.output_state = form_mod_method.output_state.data
                method_data.output_duration = form_mod_method.output_duration.data

        if not error:
            db.session.commit()

    except Exception as except_msg:
        error.append(except_msg)
    flash_success_errors(error, action, url_for('routes_method.method_list'))
Esempio n. 30
0
def execute_at_modification(mod_function, request_form,
                            custom_options_dict_presave,
                            custom_options_channels_dict_presave,
                            custom_options_dict_postsave,
                            custom_options_channels_dict_postsave):
    """
    This function allows you to view and modify the output and channel settings when the user clicks
    save on the user interface. Both the output and channel settings are passed to this function, as
    dictionaries. Additionally, both the pre-saved and post-saved options are available, as it's
    sometimes useful to know what settings changed and from what values. You can modify the post-saved
    options and these will be stored in the database.
    :param mod_output: The post-saved output database entry, minus the custom_options settings
    :param request_form: The requests.form object the user submitted
    :param custom_options_dict_presave: dict of pre-saved custom output options
    :param custom_options_channels_dict_presave: dict of pre-saved custom output channel options
    :param custom_options_dict_postsave: dict of post-saved custom output options
    :param custom_options_channels_dict_postsave: dict of post-saved custom output channel options
    :return:
    """
    allow_saving = True
    page_refresh = False
    success = []
    error = []

    try:
        dict_controllers = parse_function_information()

        channels = FunctionChannel.query.filter(
            FunctionChannel.function_id == mod_function.unique_id)

        # Ensure name doesn't get overwritten
        selector_set = 0
        selector_line = 0
        for channel in range(channels.count()):
            custom_options_channels_dict_postsave[channel][
                "name"] = "Set {} Line {}".format(selector_set, selector_line)
            selector_line += 1
            if selector_line == lcd_lines:
                selector_set += 1
                selector_line = 0

        end_channel = custom_options_dict_postsave[
            'number_line_sets'] * lcd_lines

        # Increase number of channels
        if (custom_options_dict_postsave['number_line_sets'] >
                custom_options_dict_presave['number_line_sets']):

            page_refresh = True
            start_channel = channels.count()

            for index in range(start_channel, end_channel):
                new_channel = FunctionChannel()
                new_channel.name = "Set {} Line {}".format(
                    math.trunc(index / lcd_lines),
                    index - (math.trunc(index / lcd_lines) * lcd_lines))
                new_channel.function_id = mod_function.unique_id
                new_channel.channel = index

                error, custom_options = custom_channel_options_return_json(
                    error,
                    dict_controllers,
                    request_form,
                    mod_function.unique_id,
                    index,
                    device=mod_function.device,
                    use_defaults=False)
                custom_options_dict = json.loads(custom_options)
                custom_options_dict["name"] = new_channel.name
                new_channel.custom_options = json.dumps(custom_options_dict)

                new_channel.save()

        # Decrease number of channels
        elif (custom_options_dict_postsave['number_line_sets'] <
              custom_options_dict_presave['number_line_sets']):

            page_refresh = True
            for index, each_channel in enumerate(channels.all()):
                if index >= end_channel:
                    delete_entry_with_id(FunctionChannel,
                                         each_channel.unique_id)

    except Exception:
        error.append("execute_at_modification() Error: {}".format(
            traceback.print_exc()))
        allow_saving = False

    for each_error in error:
        flash(each_error, 'error')
    for each_success in success:
        flash(each_success, 'success')
    return (allow_saving, page_refresh, mod_function,
            custom_options_dict_postsave,
            custom_options_channels_dict_postsave)
Esempio n. 31
0
def input_mod(form_mod, request_form):
    action = '{action} {controller}'.format(
        action=TRANSLATIONS['modify']['title'],
        controller=TRANSLATIONS['input']['title'])
    error = []

    dict_inputs = parse_input_information()

    try:
        mod_input = Input.query.filter(
            Input.unique_id == form_mod.input_id.data).first()

        if mod_input.is_activated:
            error.append(
                gettext("Deactivate controller before modifying its settings"))

        if (mod_input.device == 'AM2315' and form_mod.period.data < 7):
            error.append(
                gettext("Choose a Read Period equal to or greater than 7. The "
                        "AM2315 may become unresponsive if the period is "
                        "below 7."))

        if (mod_input.device != 'EDGE' and
            (mod_input.pre_output_duration
             and form_mod.period.data < mod_input.pre_output_duration)):
            error.append(
                gettext("The Read Period cannot be less than the Pre Output "
                        "Duration"))

        if (form_mod.uart_location.data
                and not os.path.exists(form_mod.uart_location.data)):
            error.append(
                gettext(
                    "Invalid device or improper permissions to read device"))

        if ('gpio_location' in dict_inputs[mod_input.device]['options_enabled']
                and form_mod.gpio_location.data is None):
            error.append(gettext("Pin (GPIO) must be set"))

        mod_input.name = form_mod.name.data

        if form_mod.location.data:
            mod_input.location = form_mod.location.data
        if form_mod.i2c_location.data:
            mod_input.i2c_location = form_mod.i2c_location.data
        if form_mod.ftdi_location.data:
            mod_input.ftdi_location = form_mod.ftdi_location.data
        if form_mod.uart_location.data:
            mod_input.uart_location = form_mod.uart_location.data
        if form_mod.gpio_location.data and form_mod.gpio_location.data is not None:
            mod_input.gpio_location = form_mod.gpio_location.data

        if form_mod.power_output_id.data:
            mod_input.power_output_id = form_mod.power_output_id.data
        else:
            mod_input.power_output_id = None

        if form_mod.pre_output_id.data:
            mod_input.pre_output_id = form_mod.pre_output_id.data
        else:
            mod_input.pre_output_id = None

        # Enable/disable Channels
        measurements = DeviceMeasurements.query.filter(
            DeviceMeasurements.device_id == form_mod.input_id.data).all()
        if form_mod.measurements_enabled.data:
            for each_measurement in measurements:
                if each_measurement.unique_id in form_mod.measurements_enabled.data:
                    each_measurement.is_enabled = True
                else:
                    each_measurement.is_enabled = False

        mod_input.log_level_debug = form_mod.log_level_debug.data
        mod_input.i2c_bus = form_mod.i2c_bus.data
        mod_input.baud_rate = form_mod.baud_rate.data
        mod_input.pre_output_duration = form_mod.pre_output_duration.data
        mod_input.pre_output_during_measure = form_mod.pre_output_during_measure.data

        if form_mod.period.data:
            mod_input.period = form_mod.period.data

        mod_input.resolution = form_mod.resolution.data
        mod_input.resolution_2 = form_mod.resolution_2.data
        mod_input.sensitivity = form_mod.sensitivity.data
        mod_input.calibrate_sensor_measure = form_mod.calibrate_sensor_measure.data
        mod_input.cmd_command = form_mod.cmd_command.data
        mod_input.thermocouple_type = form_mod.thermocouple_type.data
        mod_input.ref_ohm = form_mod.ref_ohm.data
        # Serial options
        mod_input.pin_clock = form_mod.pin_clock.data
        mod_input.pin_cs = form_mod.pin_cs.data
        mod_input.pin_mosi = form_mod.pin_mosi.data
        mod_input.pin_miso = form_mod.pin_miso.data
        # Bluetooth options
        mod_input.bt_adapter = form_mod.bt_adapter.data

        mod_input.adc_gain = form_mod.adc_gain.data
        mod_input.adc_resolution = form_mod.adc_resolution.data
        mod_input.adc_sample_speed = form_mod.adc_sample_speed.data

        # Switch options
        mod_input.switch_edge = form_mod.switch_edge.data
        mod_input.switch_bouncetime = form_mod.switch_bouncetime.data
        mod_input.switch_reset_period = form_mod.switch_reset_period.data
        # PWM and RPM options
        mod_input.weighting = form_mod.weighting.data
        mod_input.rpm_pulses_per_rev = form_mod.rpm_pulses_per_rev.data
        mod_input.sample_time = form_mod.sample_time.data
        # Server options
        mod_input.port = form_mod.port.data
        mod_input.times_check = form_mod.times_check.data
        mod_input.deadline = form_mod.deadline.data
        # SHT sensor options
        if form_mod.sht_voltage.data:
            mod_input.sht_voltage = form_mod.sht_voltage.data

        if 'test_before_saving' in dict_inputs[mod_input.device]:
            (constraints_pass, constraints_errors,
             mod_input) = dict_inputs[mod_input.device]['test_before_saving'](
                 mod_input, request_form)
            if constraints_pass:
                pass
            elif constraints_errors:
                for each_error in constraints_errors:
                    flash(each_error, 'error')

        # Custom options
        list_options = []
        if 'custom_options' in dict_inputs[mod_input.device]:
            for each_option in dict_inputs[mod_input.device]['custom_options']:
                null_value = True
                for key in request_form.keys():
                    if each_option['id'] == key:
                        constraints_pass = True
                        constraints_errors = []
                        value = None
                        if each_option['type'] == 'float':
                            if str_is_float(request_form.get(key)):
                                if 'constraints_pass' in each_option:
                                    (constraints_pass, constraints_errors,
                                     mod_input
                                     ) = each_option['constraints_pass'](
                                         mod_input,
                                         float(request_form.get(key)))
                                if constraints_pass:
                                    value = float(request_form.get(key))
                            else:
                                error.append(
                                    "{name} must represent a float/decimal value "
                                    "(submitted '{value}')".format(
                                        name=each_option['name'],
                                        value=request_form.get(key)))

                        elif each_option['type'] == 'integer':
                            if is_int(request_form.get(key)):
                                if 'constraints_pass' in each_option:
                                    (constraints_pass, constraints_errors,
                                     mod_input
                                     ) = each_option['constraints_pass'](
                                         mod_input, int(request_form.get(key)))
                                if constraints_pass:
                                    value = int(request_form.get(key))
                            else:
                                error.append(
                                    "{name} must represent an integer value "
                                    "(submitted '{value}')".format(
                                        name=each_option['name'],
                                        value=request_form.get(key)))

                        elif each_option['type'] in ['text', 'select']:
                            if 'constraints_pass' in each_option:
                                (constraints_pass, constraints_errors,
                                 mod_input) = each_option['constraints_pass'](
                                     mod_input, request_form.get(key))
                            if constraints_pass:
                                value = request_form.get(key)

                        elif each_option['type'] == 'bool':
                            value = bool(request_form.get(key))

                        for each_error in constraints_errors:
                            error.append("Error: {name}: {error}".format(
                                name=each_option['name'], error=each_error))

                        if value is not None:
                            null_value = False
                            option = '{id},{value}'.format(id=key, value=value)
                            list_options.append(option)

                if null_value:
                    option = '{id},'.format(id=each_option['id'])
                    list_options.append(option)

        mod_input.custom_options = ';'.join(list_options)

        if not error:
            # Add or delete channels for variable measurement Inputs
            if ('measurements_variable_amount' in dict_inputs[mod_input.device]
                    and dict_inputs[
                        mod_input.device]['measurements_variable_amount']):
                channels = DeviceMeasurements.query.filter(
                    DeviceMeasurements.device_id == form_mod.input_id.data)

                if channels.count() != form_mod.num_channels.data:
                    # Delete channels
                    if form_mod.num_channels.data < channels.count():
                        for index, each_channel in enumerate(channels.all()):
                            if index + 1 >= channels.count():
                                delete_entry_with_id(DeviceMeasurements,
                                                     each_channel.unique_id)

                    # Add channels
                    elif form_mod.num_channels.data > channels.count():
                        start_number = channels.count()
                        for index in range(start_number,
                                           form_mod.num_channels.data):
                            new_measurement = DeviceMeasurements()
                            new_measurement.name = ""
                            new_measurement.device_id = mod_input.unique_id
                            new_measurement.measurement = ""
                            new_measurement.unit = ""
                            new_measurement.channel = index
                            new_measurement.save()

            db.session.commit()

    except Exception as except_msg:
        error.append(except_msg)

    flash_success_errors(error, action, url_for('routes_page.page_data'))
Esempio n. 32
0
def controller_mod(form_mod, request_form):
    """Modify a Custom Function"""
    error = []
    action = '{action} {controller}'.format(
        action=TRANSLATIONS['modify']['title'],
        controller=TRANSLATIONS['controller']['title'])

    dict_controllers = parse_function_information()

    try:
        mod_controller = CustomController.query.filter(
            CustomController.unique_id == form_mod.function_id.data).first()

        if mod_controller.is_activated:
            error.append(
                gettext("Deactivate controller before modifying its settings"))

        mod_controller.name = form_mod.name.data
        mod_controller.log_level_debug = form_mod.log_level_debug.data

        # Enable/disable Channels
        measurements = DeviceMeasurements.query.filter(
            DeviceMeasurements.device_id == form_mod.function_id.data).all()
        if form_mod.measurements_enabled.data:
            for each_measurement in measurements:
                if each_measurement.unique_id in form_mod.measurements_enabled.data:
                    each_measurement.is_enabled = True
                else:
                    each_measurement.is_enabled = False

        channels = FunctionChannel.query.filter(
            FunctionChannel.function_id == form_mod.function_id.data)

        # Add or delete channels for variable measurement Inputs
        if ('measurements_variable_amount'
                in dict_controllers[mod_controller.device]
                and dict_controllers[
                    mod_controller.device]['measurements_variable_amount']):

            measurements = DeviceMeasurements.query.filter(
                DeviceMeasurements.device_id == form_mod.function_id.data)

            if measurements.count() != form_mod.num_channels.data:
                # Delete measurements/channels
                if form_mod.num_channels.data < measurements.count():
                    for index, each_channel in enumerate(measurements.all()):
                        if index + 1 >= measurements.count():
                            delete_entry_with_id(DeviceMeasurements,
                                                 each_channel.unique_id)

                    if ('channel_quantity_same_as_measurements'
                            in dict_controllers[mod_controller.device]
                            and dict_controllers[mod_controller.device]
                        ["channel_quantity_same_as_measurements"]):
                        if form_mod.num_channels.data < channels.count():
                            for index, each_channel in enumerate(
                                    channels.all()):
                                if index + 1 >= channels.count():
                                    delete_entry_with_id(
                                        FunctionChannel,
                                        each_channel.unique_id)

                # Add measurements/channels
                elif form_mod.num_channels.data > measurements.count():
                    start_number = measurements.count()
                    for index in range(start_number,
                                       form_mod.num_channels.data):
                        new_measurement = DeviceMeasurements()
                        new_measurement.name = ""
                        new_measurement.device_id = mod_controller.unique_id
                        new_measurement.measurement = ""
                        new_measurement.unit = ""
                        new_measurement.channel = index
                        new_measurement.save()

                        if ('channel_quantity_same_as_measurements'
                                in dict_controllers[mod_controller.device]
                                and dict_controllers[mod_controller.device]
                            ["channel_quantity_same_as_measurements"]):
                            new_channel = FunctionChannel()
                            new_channel.name = ""
                            new_channel.function_id = mod_controller.unique_id
                            new_measurement.channel = index

                            error, custom_options = custom_channel_options_return_json(
                                error,
                                dict_controllers,
                                request_form,
                                mod_controller.unique_id,
                                index,
                                device=mod_controller.device,
                                use_defaults=True)
                            new_channel.custom_options = custom_options

                            new_channel.save()

        # Generate string to save from custom options
        error, custom_options = custom_options_return_json(
            error,
            dict_controllers,
            request_form=request_form,
            device=mod_controller.device,
            use_defaults=True)
        mod_controller.custom_options = custom_options

        if not error:
            db.session.commit()

    except sqlalchemy.exc.OperationalError as except_msg:
        error.append(except_msg)
    except sqlalchemy.exc.IntegrityError as except_msg:
        error.append(except_msg)
    except Exception as except_msg:
        error.append(except_msg)

    flash_success_errors(error, action, url_for('routes_page.page_function'))
Esempio n. 33
0
def method_mod(form_mod_method):
    action = '{action} {controller}'.format(
        action=TRANSLATIONS['modify']['title'],
        controller=TRANSLATIONS['method']['title'])
    error = []

    method = Method.query.filter(
        Method.unique_id == form_mod_method.method_id.data).first()
    method_data = MethodData.query.filter(
        MethodData.unique_id == form_mod_method.method_data_id.data).first()
    display_order = csv_to_list_of_str(method.method_order)

    try:
        if form_mod_method.delete.data:
            delete_entry_with_id(MethodData,
                                 form_mod_method.method_data_id.data)
            if form_mod_method.method_select.data != 'output':
                method_order = Method.query.filter(
                    Method.unique_id == method.unique_id).first()
                display_order = csv_to_list_of_str(method_order.method_order)
                display_order.remove(method_data.unique_id)
                method_order.method_order = list_to_csv(display_order)
                db.session.commit()
            return 0

        if form_mod_method.rename.data:
            method.name = form_mod_method.name.data
            db.session.commit()
            return 0

        # Ensure data is valid
        if validate_method_data(form_mod_method, method):
            return 1

        if form_mod_method.method_select.data == 'setpoint':
            if method.method_type == 'Date':
                start_time = datetime.strptime(form_mod_method.time_start.data, '%Y-%m-%d %H:%M:%S')
                end_time = datetime.strptime(form_mod_method.time_end.data, '%Y-%m-%d %H:%M:%S')

                # Ensure the start time comes after the previous entry's end time
                # and the end time comes before the next entry's start time
                # method_id_set is the id given to all method entries, 'method_id', not 'id'
                previous_method = None
                next_method = None
                for index, each_order in enumerate(display_order):
                    if each_order == method_data.unique_id:
                        if len(display_order) > 1 and index > 0:
                            previous_method = MethodData.query.filter(
                                MethodData.unique_id == display_order[index-1]).first()
                        if len(display_order) > index+1:
                            next_method = MethodData.query.filter(
                                MethodData.unique_id == display_order[index+1]).first()

                if previous_method is not None and previous_method.time_end is not None:
                    previous_end_time = datetime.strptime(
                        previous_method.time_end, '%Y-%m-%d %H:%M:%S')
                    if previous_end_time is not None and start_time < previous_end_time:
                        error.append(
                            gettext("The entry start time (%(st)s) cannot "
                                    "overlap the previous entry's end time "
                                    "(%(et)s)",
                                    st=start_time, et=previous_end_time))

                if next_method is not None and next_method.time_start is not None:
                    next_start_time = datetime.strptime(
                        next_method.time_start, '%Y-%m-%d %H:%M:%S')
                    if next_start_time is not None and end_time > next_start_time:
                        error.append(
                            gettext("The entry end time (%(et)s) cannot "
                                    "overlap the next entry's start time "
                                    "(%(st)s)",
                                    et=end_time, st=next_start_time))

                method_data.time_start = start_time.strftime('%Y-%m-%d %H:%M:%S')
                method_data.time_end = end_time.strftime('%Y-%m-%d %H:%M:%S')

            elif method.method_type == 'Duration':
                if method_data.duration_sec == 0:
                    method_data.duration_end = form_mod_method.duration_end.data
                else:
                    method_data.duration_sec = form_mod_method.duration.data

            elif method.method_type == 'Daily':
                method_data.time_start = form_mod_method.daily_time_start.data
                method_data.time_end = form_mod_method.daily_time_end.data

            method_data.setpoint_start = form_mod_method.setpoint_start.data
            method_data.setpoint_end = form_mod_method.setpoint_end.data

        elif form_mod_method.method_select.data == 'output':
            if method.method_type == 'Date':
                method_data.time_start = form_mod_method.output_time.data
            elif method.method_type == 'Duration':
                method_data.duration_sec = form_mod_method.duration.data
            if form_mod_method.output_id.data == '':
                method_data.output_id = None
            else:
                method_data.output_id = form_mod_method.output_id.data
            method_data.output_state = form_mod_method.output_state.data
            method_data.output_duration = form_mod_method.output_duration.data

        elif method.method_type == 'DailySine':
            if form_mod_method.method_select.data == 'output':
                method_data.time_start = form_mod_method.output_time.data
                if form_mod_method.output_id.data == '':
                    method_data.output_id = None
                else:
                    method_data.output_id = form_mod_method.output_id.data
                method_data.output_state = form_mod_method.output_state.data
                method_data.output_duration = form_mod_method.output_duration.data

        if not error:
            db.session.commit()

    except Exception as except_msg:
        logger.exception(1)
        error.append(except_msg)
    flash_success_errors(error, action, url_for('routes_method.method_list'))
Esempio n. 34
0
def input_mod(form_mod, request_form):
    messages = {
        "success": [],
        "info": [],
        "warning": [],
        "error": [],
        "name": None,
        "return_text": []
    }
    page_refresh = False

    dict_inputs = parse_input_information()

    try:
        mod_input = Input.query.filter(
            Input.unique_id == form_mod.input_id.data).first()

        if mod_input.is_activated:
            messages["error"].append(
                gettext("Deactivate controller before modifying its settings"))

        if (mod_input.device == 'AM2315' and form_mod.period.data < 7):
            messages["error"].append(
                gettext("Choose a Read Period equal to or greater than 7. The "
                        "AM2315 may become unresponsive if the period is "
                        "below 7."))

        if (form_mod.period.data and form_mod.pre_output_duration.data
                and form_mod.pre_output_id.data
                and form_mod.period.data < form_mod.pre_output_duration.data):
            messages["error"].append(
                gettext(
                    "The Read Period cannot be less than the Pre Output Duration"
                ))

        if (form_mod.uart_location.data
                and not os.path.exists(form_mod.uart_location.data)):
            messages["warning"].append(
                gettext(
                    "Invalid device or improper permissions to read device"))

        if ('options_enabled' in dict_inputs[mod_input.device]
                and 'gpio_location'
                in dict_inputs[mod_input.device]['options_enabled']
                and form_mod.gpio_location.data is None):
            messages["error"].append(gettext("Pin (GPIO) must be set"))

        mod_input.name = form_mod.name.data
        messages["name"] = form_mod.name.data

        if form_mod.location.data:
            mod_input.location = form_mod.location.data
        if form_mod.i2c_location.data:
            mod_input.i2c_location = form_mod.i2c_location.data
        if form_mod.ftdi_location.data:
            mod_input.ftdi_location = form_mod.ftdi_location.data
        if form_mod.uart_location.data:
            mod_input.uart_location = form_mod.uart_location.data
        if form_mod.gpio_location.data and form_mod.gpio_location.data is not None:
            mod_input.gpio_location = form_mod.gpio_location.data

        if form_mod.power_output_id.data:
            mod_input.power_output_id = form_mod.power_output_id.data
        else:
            mod_input.power_output_id = None

        if form_mod.pre_output_id.data:
            mod_input.pre_output_id = form_mod.pre_output_id.data
        else:
            mod_input.pre_output_id = None

        # Enable/disable Channels
        measurements = DeviceMeasurements.query.filter(
            DeviceMeasurements.device_id == form_mod.input_id.data).all()
        if form_mod.measurements_enabled.data:
            for each_measurement in measurements:
                if each_measurement.unique_id in form_mod.measurements_enabled.data:
                    each_measurement.is_enabled = True
                else:
                    each_measurement.is_enabled = False

        mod_input.log_level_debug = form_mod.log_level_debug.data
        mod_input.i2c_bus = form_mod.i2c_bus.data
        mod_input.baud_rate = form_mod.baud_rate.data
        mod_input.pre_output_duration = form_mod.pre_output_duration.data
        mod_input.pre_output_during_measure = form_mod.pre_output_during_measure.data

        if form_mod.period.data:
            mod_input.period = form_mod.period.data
        if form_mod.start_offset.data:
            mod_input.start_offset = form_mod.start_offset.data

        mod_input.resolution = form_mod.resolution.data
        mod_input.resolution_2 = form_mod.resolution_2.data
        mod_input.sensitivity = form_mod.sensitivity.data
        mod_input.calibrate_sensor_measure = form_mod.calibrate_sensor_measure.data
        mod_input.cmd_command = form_mod.cmd_command.data
        mod_input.thermocouple_type = form_mod.thermocouple_type.data
        mod_input.ref_ohm = form_mod.ref_ohm.data
        # Serial options
        mod_input.pin_clock = form_mod.pin_clock.data
        mod_input.pin_cs = form_mod.pin_cs.data
        mod_input.pin_mosi = form_mod.pin_mosi.data
        mod_input.pin_miso = form_mod.pin_miso.data
        # Bluetooth options
        mod_input.bt_adapter = form_mod.bt_adapter.data

        mod_input.adc_gain = form_mod.adc_gain.data
        mod_input.adc_resolution = form_mod.adc_resolution.data
        mod_input.adc_sample_speed = form_mod.adc_sample_speed.data

        # Switch options
        mod_input.switch_edge = form_mod.switch_edge.data
        mod_input.switch_bouncetime = form_mod.switch_bouncetime.data
        mod_input.switch_reset_period = form_mod.switch_reset_period.data
        # PWM and RPM options
        mod_input.weighting = form_mod.weighting.data
        mod_input.rpm_pulses_per_rev = form_mod.rpm_pulses_per_rev.data
        mod_input.sample_time = form_mod.sample_time.data
        # Server options
        mod_input.port = form_mod.port.data
        mod_input.times_check = form_mod.times_check.data
        mod_input.deadline = form_mod.deadline.data
        # SHT sensor options
        if form_mod.sht_voltage.data:
            mod_input.sht_voltage = form_mod.sht_voltage.data

        channels = InputChannel.query.filter(
            InputChannel.input_id == form_mod.input_id.data)

        # Save Measurement settings
        messages, page_refresh = utils_measurement.measurement_mod_form(
            messages, page_refresh, request_form)

        # Add or delete channels for variable measurement Inputs
        if ('measurements_variable_amount' in dict_inputs[mod_input.device] and
                dict_inputs[mod_input.device]['measurements_variable_amount']):
            measurements = DeviceMeasurements.query.filter(
                DeviceMeasurements.device_id == form_mod.input_id.data)

            if measurements.count() != form_mod.num_channels.data:
                page_refresh = True

                # Delete measurements/channels
                if form_mod.num_channels.data < measurements.count():
                    for index, each_channel in enumerate(measurements.all()):
                        if index + 1 > form_mod.num_channels.data:
                            delete_entry_with_id(DeviceMeasurements,
                                                 each_channel.unique_id,
                                                 flash_message=False)

                    if ('channel_quantity_same_as_measurements'
                            in dict_inputs[mod_input.device]
                            and dict_inputs[mod_input.device]
                        ["channel_quantity_same_as_measurements"]):
                        if form_mod.num_channels.data < channels.count():
                            for index, each_channel in enumerate(
                                    channels.all()):
                                if index + 1 > form_mod.num_channels.data:
                                    delete_entry_with_id(
                                        InputChannel,
                                        each_channel.unique_id,
                                        flash_message=False)

                # Add measurements/channels
                elif form_mod.num_channels.data > measurements.count():
                    start_number = measurements.count()
                    for index in range(start_number,
                                       form_mod.num_channels.data):
                        new_measurement = DeviceMeasurements()
                        new_measurement.name = ""
                        new_measurement.device_id = mod_input.unique_id
                        new_measurement.measurement = ""
                        new_measurement.unit = ""
                        new_measurement.channel = index
                        new_measurement.save()

                        if ('channel_quantity_same_as_measurements'
                                in dict_inputs[mod_input.device]
                                and dict_inputs[mod_input.device]
                            ["channel_quantity_same_as_measurements"]):
                            new_channel = InputChannel()
                            new_channel.name = ""
                            new_channel.input_id = mod_input.unique_id
                            new_channel.channel = index

                            messages[
                                "error"], custom_options = custom_channel_options_return_json(
                                    messages["error"],
                                    dict_inputs,
                                    request_form,
                                    mod_input.unique_id,
                                    index,
                                    device=mod_input.device,
                                    use_defaults=True)
                            new_channel.custom_options = custom_options

                            new_channel.save()

        # Parse pre-save custom options for output device and its channels
        try:
            custom_options_dict_presave = json.loads(mod_input.custom_options)
        except:
            logger.error("Malformed JSON")
            custom_options_dict_presave = {}

        custom_options_channels_dict_presave = {}
        for each_channel in channels.all():
            if each_channel.custom_options and each_channel.custom_options != "{}":
                custom_options_channels_dict_presave[
                    each_channel.channel] = json.loads(
                        each_channel.custom_options)
            else:
                custom_options_channels_dict_presave[each_channel.channel] = {}

        # Parse post-save custom options for output device and its channels
        messages[
            "error"], custom_options_json_postsave = custom_options_return_json(
                messages["error"],
                dict_inputs,
                request_form,
                mod_dev=mod_input,
                device=mod_input.device)
        custom_options_dict_postsave = json.loads(custom_options_json_postsave)

        custom_options_channels_dict_postsave = {}
        for each_channel in channels.all():
            messages[
                "error"], custom_options_channels_json_postsave_tmp = custom_channel_options_return_json(
                    messages["error"],
                    dict_inputs,
                    request_form,
                    form_mod.input_id.data,
                    each_channel.channel,
                    device=mod_input.device,
                    use_defaults=False)
            custom_options_channels_dict_postsave[
                each_channel.channel] = json.loads(
                    custom_options_channels_json_postsave_tmp)

        if 'execute_at_modification' in dict_inputs[mod_input.device]:
            # pass custom options to module prior to saving to database
            (messages, mod_input, custom_options_dict,
             custom_options_channels_dict
             ) = dict_inputs[mod_input.device]['execute_at_modification'](
                 messages, mod_input, request_form,
                 custom_options_dict_presave,
                 custom_options_channels_dict_presave,
                 custom_options_dict_postsave,
                 custom_options_channels_dict_postsave)
            custom_options = json.dumps(
                custom_options_dict)  # Convert from dict to JSON string
            custom_channel_options = custom_options_channels_dict
        else:
            # Don't pass custom options to module
            custom_options = json.dumps(custom_options_dict_postsave)
            custom_channel_options = custom_options_channels_dict_postsave

        # Finally, save custom options for both output and channels
        mod_input.custom_options = custom_options
        for each_channel in channels:
            if 'name' in custom_channel_options[each_channel.channel]:
                each_channel.name = custom_channel_options[
                    each_channel.channel]['name']
            each_channel.custom_options = json.dumps(
                custom_channel_options[each_channel.channel])

        if not messages["error"]:
            db.session.commit()
            messages["success"].append(
                f"{TRANSLATIONS['modify']['title']} {TRANSLATIONS['input']['title']}"
            )

    except Exception as except_msg:
        logger.exception("input_mod")
        messages["error"].append(str(except_msg))

    return messages, page_refresh
Esempio n. 35
0
def controller_mod(form_mod, request_form):
    """Modify a Custom Function"""
    error = []
    action = '{action} {controller}'.format(
        action=TRANSLATIONS['modify']['title'],
        controller=TRANSLATIONS['controller']['title'])

    dict_controllers = parse_function_information()

    try:
        channels = FunctionChannel.query.filter(
            FunctionChannel.function_id == form_mod.function_id.data).all()
        mod_controller = CustomController.query.filter(
            CustomController.unique_id == form_mod.function_id.data).first()

        if mod_controller.is_activated:
            error.append(
                gettext("Deactivate controller before modifying its settings"))

        mod_controller.name = form_mod.name.data
        mod_controller.log_level_debug = form_mod.log_level_debug.data

        # Enable/disable Channels
        measurements = DeviceMeasurements.query.filter(
            DeviceMeasurements.device_id == form_mod.function_id.data).all()
        if form_mod.measurements_enabled.data:
            for each_measurement in measurements:
                if each_measurement.unique_id in form_mod.measurements_enabled.data:
                    each_measurement.is_enabled = True
                else:
                    each_measurement.is_enabled = False

        # Add or delete channels for variable measurement Inputs
        if ('measurements_variable_amount'
                in dict_controllers[mod_controller.device]
                and dict_controllers[
                    mod_controller.device]['measurements_variable_amount']):

            measurements = DeviceMeasurements.query.filter(
                DeviceMeasurements.device_id == form_mod.function_id.data)

            if measurements.count() != form_mod.num_channels.data:
                # Delete measurements/channels
                if form_mod.num_channels.data < measurements.count():
                    for index, each_channel in enumerate(measurements.all()):
                        if index + 1 >= measurements.count():
                            delete_entry_with_id(DeviceMeasurements,
                                                 each_channel.unique_id)

                    if ('channel_quantity_same_as_measurements'
                            in dict_controllers[mod_controller.device]
                            and dict_controllers[mod_controller.device]
                        ["channel_quantity_same_as_measurements"]):
                        if form_mod.num_channels.data < channels.count():
                            for index, each_channel in enumerate(
                                    channels.all()):
                                if index + 1 >= channels.count():
                                    delete_entry_with_id(
                                        FunctionChannel,
                                        each_channel.unique_id)

                # Add measurements/channels
                elif form_mod.num_channels.data > measurements.count():
                    start_number = measurements.count()
                    for index in range(start_number,
                                       form_mod.num_channels.data):
                        new_measurement = DeviceMeasurements()
                        new_measurement.name = ""
                        new_measurement.device_id = mod_controller.unique_id
                        new_measurement.measurement = ""
                        new_measurement.unit = ""
                        new_measurement.channel = index
                        new_measurement.save()

                        if ('channel_quantity_same_as_measurements'
                                in dict_controllers[mod_controller.device]
                                and dict_controllers[mod_controller.device]
                            ["channel_quantity_same_as_measurements"]):
                            new_channel = FunctionChannel()
                            new_channel.name = ""
                            new_channel.function_id = mod_controller.unique_id
                            new_channel.channel = index

                            error, custom_options = custom_channel_options_return_json(
                                error,
                                dict_controllers,
                                request_form,
                                mod_controller.unique_id,
                                index,
                                device=mod_controller.device,
                                use_defaults=True)
                            new_channel.custom_options = custom_options

                            new_channel.save()

        # Parse pre-save custom options for function device and its channels
        try:
            custom_options_dict_presave = json.loads(
                mod_controller.custom_options)
        except:
            logger.error("Malformed JSON")
            custom_options_dict_presave = {}

        custom_options_channels_dict_presave = {}
        for each_channel in channels:
            if each_channel.custom_options and each_channel.custom_options != "{}":
                custom_options_channels_dict_presave[
                    each_channel.channel] = json.loads(
                        each_channel.custom_options)
            else:
                custom_options_channels_dict_presave[each_channel.channel] = {}

        # Parse post-save custom options for function device and its channels
        error, custom_options_json_postsave = custom_options_return_json(
            error,
            dict_controllers,
            request_form=request_form,
            device=mod_controller.device,
            use_defaults=True)
        custom_options_dict_postsave = json.loads(custom_options_json_postsave)

        custom_options_channels_dict_postsave = {}
        for each_channel in channels:
            error, custom_options_channels_json_postsave_tmp = custom_channel_options_return_json(
                error,
                dict_controllers,
                request_form,
                form_mod.function_id.data,
                each_channel.channel,
                device=mod_controller.device,
                use_defaults=True)
            custom_options_channels_dict_postsave[
                each_channel.channel] = json.loads(
                    custom_options_channels_json_postsave_tmp)

        if 'execute_at_modification' in dict_controllers[
                mod_controller.device]:
            # pass custom options to module prior to saving to database
            (allow_saving, mod_controller, custom_options_dict,
             custom_options_channels_dict) = dict_controllers[
                 mod_controller.device]['execute_at_modification'](
                     mod_controller, request_form, custom_options_dict_presave,
                     custom_options_channels_dict_presave,
                     custom_options_dict_postsave,
                     custom_options_channels_dict_postsave)
            custom_options = json.dumps(
                custom_options_dict)  # Convert from dict to JSON string
            custom_channel_options = custom_options_channels_dict
            if not allow_saving:
                error.append(
                    "execute_at_modification() would not allow function options to be saved"
                )
        else:
            # Don't pass custom options to module
            custom_options = json.dumps(custom_options_dict_postsave)
            custom_channel_options = custom_options_channels_dict_postsave

        # Finally, save custom options for both function and channels
        mod_controller.custom_options = custom_options
        for each_channel in channels:
            if 'name' in custom_channel_options[each_channel.channel]:
                each_channel.name = custom_channel_options[
                    each_channel.channel]['name']
            each_channel.custom_options = json.dumps(
                custom_channel_options[each_channel.channel])

        if not error:
            db.session.commit()

    except sqlalchemy.exc.OperationalError as except_msg:
        error.append(except_msg)
    except sqlalchemy.exc.IntegrityError as except_msg:
        error.append(except_msg)
    except Exception as except_msg:
        error.append(except_msg)

    flash_success_errors(error, action, url_for('routes_page.page_function'))