示例#1
0
def admin_dependencies(device):
    """ Display Dependency page """
    form_dependencies = forms_dependencies.Dependencies()

    if device != '0':
        # Only loading a single dependency page
        device_unmet_dependencies, _ = utils_general.return_dependencies(
            device)
    elif form_dependencies.device.data:
        device_unmet_dependencies, _ = utils_general.return_dependencies(
            form_dependencies.device.data)
    else:
        device_unmet_dependencies = []

    unmet_dependencies = OrderedDict()
    unmet_exist = False
    met_dependencies = []
    met_exist = False
    unmet_list = {}
    install_in_progress = False
    device_name = None

    # Read from the dependency status file created by the upgrade script
    # to indicate if the upgrade is running.
    try:
        with open(DEPENDENCY_INIT_FILE) as f:
            dep = int(f.read(1))
    except (IOError, ValueError):
        try:
            with open(DEPENDENCY_INIT_FILE, 'w') as f:
                f.write('0')
        finally:
            dep = 0

    if dep:
        install_in_progress = True

    list_dependencies = [
        parse_function_information(),
        parse_input_information(),
        parse_output_information(),
        CALIBRATION_INFO,
        CAMERA_INFO,
        FUNCTION_ACTION_INFO,
        FUNCTION_INFO,
        LCD_INFO,
        MATH_INFO,
        METHOD_INFO,
    ]
    for each_section in list_dependencies:
        for each_device in each_section:

            if device in each_section:
                for each_device_, each_val in each_section[device].items():
                    if each_device_ in ['name', 'input_name']:
                        device_name = each_val

            # Only get all dependencies when not loading a single dependency page
            if device == '0':
                # Determine if there are any unmet dependencies for every device
                dep_unmet, dep_met = utils_general.return_dependencies(
                    each_device)

                unmet_dependencies.update({each_device: dep_unmet})
                if dep_unmet:
                    unmet_exist = True

                # Determine if there are any met dependencies
                if dep_met:
                    if each_device not in met_dependencies:
                        met_dependencies.append(each_device)
                        met_exist = True

                # Find all the devices that use each unmet dependency
                if unmet_dependencies[each_device]:
                    for each_dep in unmet_dependencies[each_device]:
                        if each_dep not in unmet_list:
                            unmet_list[each_dep] = []
                        if each_device not in unmet_list[each_dep]:
                            unmet_list[each_dep].append(each_device)

    if request.method == 'POST':
        if not utils_general.user_has_permission('edit_controllers'):
            return redirect(
                url_for('routes_admin.admin_dependencies', device=device))

        if form_dependencies.install.data:
            with open(DEPENDENCY_INIT_FILE, 'w') as f:
                f.write('1')
            install_deps = threading.Thread(target=install_dependencies,
                                            args=(device_unmet_dependencies, ))
            install_deps.start()

        return redirect(
            url_for('routes_admin.admin_dependencies', device=device))

    return render_template('admin/dependencies.html',
                           measurements=parse_input_information(),
                           unmet_list=unmet_list,
                           device=device,
                           device_name=device_name,
                           install_in_progress=install_in_progress,
                           unmet_dependencies=unmet_dependencies,
                           unmet_exist=unmet_exist,
                           met_dependencies=met_dependencies,
                           met_exist=met_exist,
                           form_dependencies=form_dependencies,
                           device_unmet_dependencies=device_unmet_dependencies)
示例#2
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)
from mycodo.config import INSTALL_DIRECTORY
from mycodo.scripts.generate_doc_output import generate_controller_doc
from mycodo.utils.functions import parse_function_information

save_path = os.path.join(INSTALL_DIRECTORY, "docs/Supported-Functions.md")

functions_info = OrderedDict()
mycodo_info = OrderedDict()


def repeat_to_length(s, wanted):
    return (s * (wanted//len(s) + 1))[:wanted]


if __name__ == "__main__":
    for function_id, function_data in parse_function_information(exclude_custom=True).items():
        name_str = ""
        if 'function_name' in function_data and function_data['function_name']:
            name_str += ": {}".format(function_data['function_name'])
        if 'function_library' in function_data and function_data['function_library']:
            name_str += ": {}".format(function_data['function_library'])

        if name_str in functions_info and 'dependencies_module' in functions_info[name_str]:
            # Multiple sets of dependencies, append library
            functions_info[name_str]['dependencies_module'].append(function_data['dependencies_module'])
        else:
            # Only one set of dependencies
            functions_info[name_str] = function_data
            if 'dependencies_module' in function_data:
                functions_info[name_str]['dependencies_module'] = [function_data['dependencies_module']]  # turn into list
示例#4
0
def controller_mod(form_mod, request_form):
    """Modify a Custom Function"""
    messages = {
        "success": [],
        "info": [],
        "warning": [],
        "error": [],
        "name": None
    }
    page_refresh = False

    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:
            messages["error"].append(
                gettext("Deactivate controller before modifying its settings"))

        mod_controller.name = form_mod.name.data
        messages["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

                            messages[
                                "error"], custom_options = custom_channel_options_return_json(
                                    messages["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
        messages[
            "error"], custom_options_json_postsave = custom_options_return_json(
                messages["error"],
                dict_controllers,
                request_form=request_form,
                mod_dev=mod_controller,
                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:
            messages[
                "error"], custom_options_channels_json_postsave_tmp = custom_channel_options_return_json(
                    messages["error"],
                    dict_controllers,
                    request_form,
                    form_mod.function_id.data,
                    each_channel.channel,
                    device=mod_controller.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_controllers[
                mod_controller.device]:
            # pass custom options to module prior to saving to database
            (allow_saving, page_refresh, 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:
                messages["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 messages["error"]:
            db.session.commit()
            messages["success"].append('{action} {controller}'.format(
                action=TRANSLATIONS['modify']['title'],
                controller=TRANSLATIONS['controller']['title']))

    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, page_refresh
示例#5
0
def function_add(form_add_func):
    action = '{action} {controller}'.format(
        action=TRANSLATIONS['add']['title'],
        controller=TRANSLATIONS['function']['title'])
    error = []

    function_name = form_add_func.function_type.data

    dict_controllers = parse_function_information()

    if current_app.config['TESTING']:
        dep_unmet = False
    else:
        dep_unmet, _ = return_dependencies(function_name)
        if dep_unmet:
            list_unmet_deps = []
            for each_dep in dep_unmet:
                list_unmet_deps.append(each_dep[0])
            error.append(
                "The {dev} device you're trying to add has unmet "
                "dependencies: {dep}".format(
                    dev=function_name, dep=', '.join(list_unmet_deps)))

    new_func = None

    try:
        if function_name == 'conditional_conditional':
            new_func = Conditional()
            new_func.conditional_statement = '''
# Example code for learning how to use a Conditional. See the manual for more information.

self.logger.info("This INFO log entry will appear in the Daemon Log")
self.logger.error("This ERROR log entry will appear in the Daemon Log")

# Replace "asdf1234" with a Condition ID
measurement = self.condition("{asdf1234}")
self.logger.info("Check this measurement in the Daemon Log. The value is {val}".format(val=measurement))

if measurement is not None:  # If a measurement exists
    self.message += "This message appears in email alerts and notes.\\n"

    if measurement < 23:  # If the measurement is less than 23
        self.message += "Measurement is too Low! Measurement is {meas}\\n".format(meas=measurement)
        self.run_all_actions(message=self.message)  # Run all actions sequentially

    elif measurement > 27:  # Else If the measurement is greater than 27
        self.message += "Measurement is too High! Measurement is {meas}\\n".format(meas=measurement)
        # Replace "qwer5678" with an Action ID
        self.run_action("{qwer5678}", message=self.message)  # Run a single specific Action'''

            if not error:
                new_func.save()
                save_conditional_code(
                    error,
                    new_func.conditional_statement,
                    new_func.unique_id,
                    ConditionalConditions.query.all(),
                    Actions.query.all(),
                    test=False)

        elif function_name == 'pid_pid':
            new_func = PID().save()

            for each_channel, measure_info in PID_INFO['measure'].items():
                new_measurement = DeviceMeasurements()

                if 'name' in measure_info:
                    new_measurement.name = measure_info['name']
                if 'measurement_type' in measure_info:
                    new_measurement.measurement_type = measure_info['measurement_type']

                new_measurement.device_id = new_func.unique_id
                new_measurement.measurement = measure_info['measurement']
                new_measurement.unit = measure_info['unit']
                new_measurement.channel = each_channel
                if not error:
                    new_measurement.save()

        elif function_name in ['trigger_edge',
                               'trigger_output',
                               'trigger_output_pwm',
                               'trigger_timer_daily_time_point',
                               'trigger_timer_daily_time_span',
                               'trigger_timer_duration',
                               'trigger_run_pwm_method',
                               'trigger_sunrise_sunset']:
            new_func = Trigger()
            new_func.name = '{}'.format(FUNCTION_INFO[function_name]['name'])
            new_func.trigger_type = function_name
            if not error:
                new_func.save()

        elif function_name in ['function_spacer',
                               'function_actions']:
            new_func = Function()
            if function_name == 'function_spacer':
                new_func.name = 'Spacer'
            new_func.function_type = function_name
            if not error:
                new_func.save()

        elif function_name in dict_controllers:
            # Custom Function Controller
            new_func = CustomController()
            new_func.device = function_name

            if 'function_name' in dict_controllers[function_name]:
                new_func.name = dict_controllers[function_name]['function_name']
            else:
                new_func.name = 'Function Name'

            # TODO: Switch to JSON function
            list_options = []
            if 'custom_options' in dict_controllers[function_name]:
                for each_option in dict_controllers[function_name]['custom_options']:
                    if 'id' not in each_option:
                        continue

                    if each_option['default_value'] is False:
                        default_value = ''
                    else:
                        default_value = each_option['default_value']
                    option = '{id},{value}'.format(
                        id=each_option['id'],
                        value=default_value)
                    list_options.append(option)
            new_func.custom_options = ';'.join(list_options)
            if not error:
                new_func.save()

        elif function_name == '':
            error.append("Must select a function type")
        else:
            error.append("Unknown function type: '{}'".format(
                function_name))

        if not error:
            display_order = csv_to_list_of_str(
                DisplayOrder.query.first().function)
            DisplayOrder.query.first().function = add_display_order(
                display_order, new_func.unique_id)
            db.session.commit()


            if function_name in dict_controllers:
                #
                # Add measurements defined in the Function Module
                #

                if ('measurements_dict' in dict_controllers[function_name] and
                        dict_controllers[function_name]['measurements_dict']):
                    for each_channel in dict_controllers[function_name]['measurements_dict']:
                        measure_info = dict_controllers[function_name]['measurements_dict'][each_channel]
                        new_measurement = DeviceMeasurements()
                        new_measurement.device_id = new_func.unique_id
                        if 'name' in measure_info:
                            new_measurement.name = measure_info['name']
                        else:
                            new_measurement.name = ""
                        if 'measurement' in measure_info:
                            new_measurement.measurement = measure_info['measurement']
                        else:
                            new_measurement.measurement = ""
                        if 'unit' in measure_info:
                            new_measurement.unit = measure_info['unit']
                        else:
                            new_measurement.unit = ""
                        new_measurement.channel = each_channel
                        new_measurement.save()

                #
                # If there are a variable number of measurements
                #

                elif ('measurements_variable_amount' in dict_controllers[function_name] and
                        dict_controllers[function_name]['measurements_variable_amount']):
                    # Add first default measurement with empty unit and measurement
                    new_measurement = DeviceMeasurements()
                    new_measurement.name = ""
                    new_measurement.device_id = new_func.unique_id
                    new_measurement.measurement = ""
                    new_measurement.unit = ""
                    new_measurement.channel = 0
                    new_measurement.save()

                #
                # Add channels defined in the Function Module
                #

                if 'channels_dict' in dict_controllers[function_name]:
                    for each_channel, channel_info in dict_controllers[function_name]['channels_dict'].items():
                        new_channel = FunctionChannel()
                        new_channel.channel = each_channel
                        new_channel.function_id = new_func.unique_id

                        # Generate string to save from custom options
                        error, custom_options = custom_channel_options_return_json(
                            error, dict_controllers, None,
                            new_func.unique_id, each_channel,
                            device=new_func.device, use_defaults=True)
                        new_channel.custom_options = custom_options

                        new_channel.save()

    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:
        logger.exception("Add Function")
        error.append(except_msg)

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

    if dep_unmet:
        return 1
示例#6
0
def function_add(form_add_func):
    messages = {"success": [], "info": [], "warning": [], "error": []}
    new_function_id = None
    dep_name = None

    function_name = form_add_func.function_type.data

    dict_controllers = parse_function_information()

    if current_app.config['TESTING']:
        dep_unmet = False
    else:
        dep_unmet, _ = return_dependencies(function_name)
        if dep_unmet:
            list_unmet_deps = []
            for each_dep in dep_unmet:
                list_unmet_deps.append(each_dep[0])
            messages["error"].append(
                "{dev} has unmet dependencies. They must be installed before the Function can be added."
                .format(dev=function_name))
            if function_name in dict_controllers:
                dep_name = dict_controllers[function_name]['function_name']
            else:
                messages["error"].append(
                    "Function not found: {}".format(function_name))

            return messages, dep_name, list_unmet_deps, None

    new_func = None

    try:
        if function_name == 'conditional_conditional':
            new_func = Conditional()
            new_func.position_y = 999
            new_func.conditional_statement = '''
# Example code for learning how to use a Conditional. See the manual for more information.

self.logger.info("This INFO log entry will appear in the Daemon Log")
self.logger.error("This ERROR log entry will appear in the Daemon Log")

if not hasattr(self, "loop_count"):  # Initialize objects saved across executions
    self.loop_count = 1
else:
    self.loop_count += 1

# Replace "asdf1234" with a Condition ID
measurement = self.condition("{asdf1234}") 
self.logger.info("Check this measurement in the Daemon Log. The value is {val}".format(val=measurement))

if measurement is not None:  # If a measurement exists
    self.message += "This message appears in email alerts and notes.\\n"

    if measurement < 23:  # If the measurement is less than 23
        self.message += "Measurement is too Low! Measurement is {meas}\\n".format(meas=measurement)
        self.run_all_actions(message=self.message)  # Run all actions sequentially

    elif measurement > 27:  # Else If the measurement is greater than 27
        self.message += "Measurement is too High! Measurement is {meas}\\n".format(meas=measurement)
        # Replace "qwer5678" with an Action ID
        self.run_action("{qwer5678}", message=self.message)  # Run a single specific Action'''

            new_func.conditional_status = '''
# Example code to provide a return status for other controllers and widgets.
status_dict = {
    'string_status': "This is the demo status of the conditional controller. "
                     "The controller has looped {} times".format(self.loop_count),
    'loop_count': self.loop_count,
    'error': []
}
return status_dict'''

            if not messages["error"]:
                new_func.save()
                new_function_id = new_func.unique_id
                if not current_app.config['TESTING']:
                    save_conditional_code(messages["error"],
                                          new_func.conditional_statement,
                                          new_func.conditional_status,
                                          new_func.unique_id,
                                          ConditionalConditions.query.all(),
                                          Actions.query.all(),
                                          test=False)

        elif function_name == 'pid_pid':
            new_func = PID()
            new_func.position_y = 999
            new_func.save()
            new_function_id = new_func.unique_id

            for each_channel, measure_info in PID_INFO['measure'].items():
                new_measurement = DeviceMeasurements()

                if 'name' in measure_info:
                    new_measurement.name = measure_info['name']
                if 'measurement_type' in measure_info:
                    new_measurement.measurement_type = measure_info[
                        'measurement_type']

                new_measurement.device_id = new_func.unique_id
                new_measurement.measurement = measure_info['measurement']
                new_measurement.unit = measure_info['unit']
                new_measurement.channel = each_channel
                if not messages["error"]:
                    new_measurement.save()

        elif function_name in [
                'trigger_edge', 'trigger_output', 'trigger_output_pwm',
                'trigger_timer_daily_time_point',
                'trigger_timer_daily_time_span', 'trigger_timer_duration',
                'trigger_run_pwm_method', 'trigger_sunrise_sunset'
        ]:
            new_func = Trigger()
            new_func.name = '{}'.format(FUNCTION_INFO[function_name]['name'])
            new_func.trigger_type = function_name
            new_func.position_y = 999

            if not messages["error"]:
                new_func.save()
                new_function_id = new_func.unique_id

        elif function_name == 'function_actions':
            new_func = Function()
            new_func.position_y = 999
            new_func.function_type = function_name
            if not messages["error"]:
                new_func.save()
                new_function_id = new_func.unique_id

        elif function_name in dict_controllers:
            # Custom Function Controller
            new_func = CustomController()
            new_func.device = function_name
            new_func.position_y = 999

            if 'function_name' in dict_controllers[function_name]:
                new_func.name = dict_controllers[function_name][
                    'function_name']
            else:
                new_func.name = 'Function Name'

            # Generate string to save from custom options
            messages["error"], custom_options = custom_options_return_json(
                messages["error"],
                dict_controllers,
                device=function_name,
                use_defaults=True)
            new_func.custom_options = custom_options

            new_func.unique_id = set_uuid()

            if ('execute_at_creation' in dict_controllers[new_func.device]
                    and not current_app.config['TESTING']):
                messages["error"], new_func = dict_controllers[
                    new_func.device]['execute_at_creation'](
                        messages["error"], new_func,
                        dict_controllers[new_func.device])

            if not messages["error"]:
                new_func.save()
                new_function_id = new_func.unique_id

        elif function_name == '':
            messages["error"].append("Must select a function type")
        else:
            messages["error"].append(
                "Unknown function type: '{}'".format(function_name))

        if not messages["error"]:
            if function_name in dict_controllers:
                #
                # Add measurements defined in the Function Module
                #

                if ('measurements_dict' in dict_controllers[function_name] and
                        dict_controllers[function_name]['measurements_dict']):
                    for each_channel in dict_controllers[function_name][
                            'measurements_dict']:
                        measure_info = dict_controllers[function_name][
                            'measurements_dict'][each_channel]
                        new_measurement = DeviceMeasurements()
                        new_measurement.device_id = new_func.unique_id
                        if 'name' in measure_info:
                            new_measurement.name = measure_info['name']
                        else:
                            new_measurement.name = ""
                        if 'measurement' in measure_info:
                            new_measurement.measurement = measure_info[
                                'measurement']
                        else:
                            new_measurement.measurement = ""
                        if 'unit' in measure_info:
                            new_measurement.unit = measure_info['unit']
                        else:
                            new_measurement.unit = ""
                        new_measurement.channel = each_channel
                        new_measurement.save()

                #
                # If there are a variable number of measurements
                #

                elif ('measurements_variable_amount'
                      in dict_controllers[function_name]
                      and dict_controllers[function_name]
                      ['measurements_variable_amount']):
                    # Add first default measurement with empty unit and measurement
                    new_measurement = DeviceMeasurements()
                    new_measurement.name = ""
                    new_measurement.device_id = new_func.unique_id
                    new_measurement.measurement = ""
                    new_measurement.unit = ""
                    new_measurement.channel = 0
                    new_measurement.save()

                #
                # Add channels defined in the Function Module
                #

                if 'channels_dict' in dict_controllers[function_name]:
                    for each_channel, channel_info in dict_controllers[
                            function_name]['channels_dict'].items():
                        new_channel = FunctionChannel()
                        new_channel.channel = each_channel
                        new_channel.function_id = new_func.unique_id

                        # Generate string to save from custom options
                        messages[
                            "error"], custom_options = custom_channel_options_return_json(
                                messages["error"],
                                dict_controllers,
                                None,
                                new_func.unique_id,
                                each_channel,
                                device=new_func.device,
                                use_defaults=True)
                        new_channel.custom_options = custom_options

                        new_channel.save()

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

    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:
        logger.exception("Add Function")
        messages["error"].append(str(except_msg))

    return messages, dep_name, dep_unmet, new_function_id
示例#7
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'))
示例#8
0
def page_function_submit():
    """ Submit form for Data page """
    messages = {"success": [], "info": [], "warning": [], "error": []}
    page_refresh = False
    action_id = None
    condition_id = None
    function_id = None
    dep_unmet = ''
    dep_name = ''
    dep_list = []

    if not utils_general.user_has_permission('edit_controllers'):
        messages["error"].append("Your permissions do not allow this action")

    form_actions = forms_function.Actions()
    form_add_function = forms_function.FunctionAdd()
    form_conditional = forms_conditional.Conditional()
    form_conditional_conditions = forms_conditional.ConditionalConditions()
    form_function = forms_custom_controller.CustomController()
    form_function_base = forms_function.FunctionMod()
    form_mod_pid_base = forms_pid.PIDModBase()
    form_mod_pid_output_raise = forms_pid.PIDModRelayRaise()
    form_mod_pid_output_lower = forms_pid.PIDModRelayLower()
    form_mod_pid_pwm_raise = forms_pid.PIDModPWMRaise()
    form_mod_pid_pwm_lower = forms_pid.PIDModPWMLower()
    form_mod_pid_value_raise = forms_pid.PIDModValueRaise()
    form_mod_pid_value_lower = forms_pid.PIDModValueLower()
    form_mod_pid_volume_raise = forms_pid.PIDModVolumeRaise()
    form_mod_pid_volume_lower = forms_pid.PIDModVolumeLower()
    form_trigger = forms_trigger.Trigger()

    if not messages["error"]:
        if form_add_function.function_add.data:
            (messages, dep_name, dep_list,
             function_id) = utils_function.function_add(form_add_function)
            if dep_list:
                dep_unmet = form_add_function.function_type.data
        else:
            function_id = form_function_base.function_id.data
            controller_type = determine_controller_type(function_id)
            if form_function_base.function_mod.data:
                if controller_type == "Conditional":
                    messages = utils_conditional.conditional_mod(
                        form_conditional)
                elif controller_type == "PID":
                    messages, page_refresh = utils_pid.pid_mod(
                        form_mod_pid_base, form_mod_pid_pwm_raise,
                        form_mod_pid_pwm_lower, form_mod_pid_output_raise,
                        form_mod_pid_output_lower, form_mod_pid_value_raise,
                        form_mod_pid_value_lower, form_mod_pid_volume_raise,
                        form_mod_pid_volume_lower)
                elif controller_type == "Trigger":
                    messages = utils_trigger.trigger_mod(form_trigger)
                elif controller_type == "Function":
                    messages = utils_function.function_mod(form_function_base)
                elif controller_type == "Function_Custom":
                    messages, page_refresh = utils_controller.controller_mod(
                        form_function, request.form)
            elif form_function_base.function_delete.data:
                if controller_type == "Conditional":
                    messages = utils_conditional.conditional_del(function_id)
                elif controller_type == "PID":
                    messages = utils_pid.pid_del(function_id)
                elif controller_type == "Trigger":
                    messages = utils_trigger.trigger_del(function_id)
                elif controller_type == "Function":
                    messages = utils_function.function_del(function_id)
                elif controller_type == "Function_Custom":
                    messages = utils_controller.controller_del(function_id)
            elif form_function_base.function_activate.data:
                if controller_type == "Conditional":
                    messages = utils_conditional.conditional_activate(
                        function_id)
                elif controller_type == "PID":
                    messages = utils_pid.pid_activate(function_id)
                elif controller_type == "Trigger":
                    messages = utils_trigger.trigger_activate(function_id)
                elif controller_type == "Function_Custom":
                    messages = utils_controller.controller_activate(
                        function_id)
            elif form_function_base.function_deactivate.data:
                if controller_type == "Conditional":
                    messages = utils_conditional.conditional_deactivate(
                        function_id)
                elif controller_type == "PID":
                    messages = utils_pid.pid_deactivate(function_id)
                elif controller_type == "Trigger":
                    messages = utils_trigger.trigger_deactivate(function_id)
                elif controller_type == "Function_Custom":
                    messages = utils_controller.controller_deactivate(
                        function_id)
            elif form_function_base.execute_all_actions.data:
                if controller_type == "Conditional":
                    messages = utils_function.action_execute_all(
                        form_conditional)
                elif controller_type == "Trigger":
                    messages = utils_function.action_execute_all(
                        form_conditional)
                elif controller_type == "Function":
                    messages = utils_function.action_execute_all(
                        form_conditional)

            # PID
            elif form_mod_pid_base.pid_hold.data:
                messages = utils_pid.pid_manipulate(
                    form_mod_pid_base.function_id.data, 'Hold')
            elif form_mod_pid_base.pid_pause.data:
                messages = utils_pid.pid_manipulate(
                    form_mod_pid_base.function_id.data, 'Pause')
            elif form_mod_pid_base.pid_resume.data:
                messages = utils_pid.pid_manipulate(
                    form_mod_pid_base.function_id.data, 'Resume')

            # Actions
            elif form_function_base.add_action.data:
                (messages, dep_name, dep_list, action_id,
                 page_refresh) = utils_function.action_add(form_function_base)
            elif form_actions.save_action.data:
                messages = utils_function.action_mod(form_actions,
                                                     request.form)
            elif form_actions.delete_action.data:
                messages = utils_function.action_del(form_actions)
                page_refresh = True
                action_id = form_actions.function_action_id.data

            # Conditions
            elif form_conditional.add_condition.data:
                (messages,
                 condition_id) = utils_conditional.conditional_condition_add(
                     form_conditional)
                page_refresh = True
                function_id = form_actions.function_id.data
            elif form_conditional_conditions.save_condition.data:
                messages = utils_conditional.conditional_condition_mod(
                    form_conditional_conditions)
            elif form_conditional_conditions.delete_condition.data:
                messages = utils_conditional.conditional_condition_del(
                    form_conditional_conditions)
                page_refresh = True
                condition_id = form_conditional_conditions.conditional_condition_id.data

            # Custom action
            else:
                custom_button = False
                for key in request.form.keys():
                    if key.startswith('custom_button_'):
                        custom_button = True
                        break
                if custom_button:
                    messages = utils_general.custom_action(
                        "Function_Custom", parse_function_information(),
                        form_function.function_id.data, request.form)
                else:
                    messages["error"].append("Unknown function directive")

    return jsonify(
        data={
            'action_id': action_id,
            'condition_id': condition_id,
            'function_id': function_id,
            'dep_name': dep_name,
            'dep_list': dep_list,
            'dep_unmet': dep_unmet,
            'messages': messages,
            "page_refresh": page_refresh
        })
示例#9
0
def page_function():
    """ Display Function page options """
    function_type = request.args.get('function_type', None)
    function_id = request.args.get('function_id', None)
    action_id = request.args.get('action_id', None)
    condition_id = request.args.get('condition_id', None)
    each_function = None
    each_action = None
    each_condition = None
    function_page_entry = None
    function_page_options = None

    if function_type in ['entry', 'options', 'conditions', 'actions'
                         ] and function_id != '0':
        controller_type = determine_controller_type(function_id)
        if controller_type == "Conditional":
            each_function = Conditional.query.filter(
                Conditional.unique_id == function_id).first()
            function_page_entry = 'pages/function_options/conditional_entry.html'
            function_page_options = 'pages/function_options/conditional_options.html'
        elif controller_type == "PID":
            each_function = PID.query.filter(
                PID.unique_id == function_id).first()
            function_page_entry = 'pages/function_options/pid_entry.html'
            function_page_options = 'pages/function_options/pid_options.html'
        elif controller_type == "Trigger":
            each_function = Trigger.query.filter(
                Trigger.unique_id == function_id).first()
            function_page_entry = 'pages/function_options/trigger_entry.html'
            function_page_options = 'pages/function_options/trigger_options.html'
        elif controller_type == "Function":
            each_function = Function.query.filter(
                Function.unique_id == function_id).first()
            function_page_entry = 'pages/function_options/function_entry.html'
            function_page_options = 'pages/function_options/function_options.html'
        elif controller_type == "Function_Custom":
            each_function = CustomController.query.filter(
                CustomController.unique_id == function_id).first()
            function_page_entry = 'pages/function_options/custom_function_entry.html'
            function_page_options = 'pages/function_options/custom_function_options.html'

        if function_type == 'actions':
            if action_id:
                each_action = Actions.query.filter(
                    Actions.unique_id == action_id).first()

        if function_type == 'conditions':
            if condition_id:
                each_condition = ConditionalConditions.query.filter(
                    ConditionalConditions.unique_id == condition_id).first()

    camera = Camera.query.all()
    conditional = Conditional.query.all()
    conditional_conditions = ConditionalConditions.query.all()
    function = CustomController.query.all()
    function_channel = FunctionChannel.query.all()
    function_dev = Function.query.all()
    actions = Actions.query.all()
    input_dev = Input.query.all()
    lcd = LCD.query.all()
    math = Math.query.all()
    measurement = Measurement.query.all()
    method = Method.query.all()
    tags = NoteTags.query.all()
    output = Output.query.all()
    output_channel = OutputChannel.query.all()
    pid = PID.query.all()
    trigger = Trigger.query.all()
    unit = Unit.query.all()
    user = User.query.all()

    display_order_function = csv_to_list_of_str(
        DisplayOrder.query.first().function)

    form_add_function = forms_function.FunctionAdd()
    form_mod_pid_base = forms_pid.PIDModBase()
    form_mod_pid_output_raise = forms_pid.PIDModRelayRaise()
    form_mod_pid_output_lower = forms_pid.PIDModRelayLower()
    form_mod_pid_pwm_raise = forms_pid.PIDModPWMRaise()
    form_mod_pid_pwm_lower = forms_pid.PIDModPWMLower()
    form_mod_pid_value_raise = forms_pid.PIDModValueRaise()
    form_mod_pid_value_lower = forms_pid.PIDModValueLower()
    form_mod_pid_volume_raise = forms_pid.PIDModVolumeRaise()
    form_mod_pid_volume_lower = forms_pid.PIDModVolumeLower()
    form_function_base = forms_function.FunctionMod()
    form_trigger = forms_trigger.Trigger()
    form_conditional = forms_conditional.Conditional()
    form_conditional_conditions = forms_conditional.ConditionalConditions()
    form_function = forms_custom_controller.CustomController()
    form_actions = forms_function.Actions()

    dict_controllers = parse_function_information()

    # Generate all measurement and units used
    dict_measurements = add_custom_measurements(Measurement.query.all())
    dict_units = add_custom_units(Unit.query.all())

    dict_outputs = parse_output_information()

    custom_options_values_controllers = parse_custom_option_values(
        function, dict_controller=dict_controllers)
    custom_options_values_function_channels = parse_custom_option_values_function_channels_json(
        function_channel,
        dict_controller=function,
        key_name='custom_channel_options')

    # TODO: Update actions to use single-file modules and be consistent with other custom_options
    custom_options_values_actions = {}
    for each_action in actions:
        try:
            custom_options_values_actions[each_action.unique_id] = json.loads(
                each_action.custom_options)
        except:
            custom_options_values_actions[each_action.unique_id] = {}

    # Create lists of built-in and custom functions
    choices_functions = []
    for choice_function in FUNCTIONS:
        choices_functions.append({
            'value': choice_function[0],
            'item': choice_function[1]
        })
    choices_custom_functions = utils_general.choices_custom_functions()
    # Combine function lists
    choices_functions_add = choices_functions + choices_custom_functions
    # Sort combined list
    choices_functions_add = sorted(choices_functions_add,
                                   key=lambda i: i['item'])

    custom_actions = {}
    for choice_function in function:
        if 'custom_actions' in dict_controllers[choice_function.device]:
            custom_actions[choice_function.device] = True

    choices_function = utils_general.choices_functions(function, dict_units,
                                                       dict_measurements)
    choices_input = utils_general.choices_inputs(input_dev, dict_units,
                                                 dict_measurements)
    choices_input_devices = utils_general.choices_input_devices(input_dev)
    choices_math = utils_general.choices_maths(math, dict_units,
                                               dict_measurements)
    choices_method = utils_general.choices_methods(method)
    choices_output = utils_general.choices_outputs(output, dict_units,
                                                   dict_measurements)
    choices_output_channels = utils_general.choices_outputs_channels(
        output, output_channel, dict_outputs)
    choices_output_channels_measurements = utils_general.choices_outputs_channels_measurements(
        output, OutputChannel, dict_outputs, dict_units, dict_measurements)
    choices_pid = utils_general.choices_pids(pid, dict_units,
                                             dict_measurements)
    choices_measurements_units = utils_general.choices_measurements_units(
        measurement, unit)

    choices_controller_ids = utils_general.choices_controller_ids()

    actions_dict = {'conditional': {}, 'trigger': {}}
    for each_action in actions:
        if (each_action.function_type == 'conditional'
                and each_action.unique_id not in actions_dict['conditional']):
            actions_dict['conditional'][each_action.function_id] = True
        if (each_action.function_type == 'trigger'
                and each_action.unique_id not in actions_dict['trigger']):
            actions_dict['trigger'][each_action.function_id] = True

    conditions_dict = {}
    for each_cond in conditional_conditions:
        if each_cond.unique_id not in conditions_dict:
            conditions_dict[each_cond.conditional_id] = True

    controllers = []
    controllers_all = [('Input', input_dev), ('Conditional', conditional),
                       ('Function', function), ('LCD', lcd), ('Math', math),
                       ('PID', pid), ('Trigger', trigger)]
    for each_controller in controllers_all:
        for each_cont in each_controller[1]:
            controllers.append((each_controller[0], each_cont.unique_id,
                                each_cont.id, each_cont.name))

    # Create dict of Function names
    names_function = {}
    all_elements = [conditional, pid, trigger, function_dev, function]
    for each_element in all_elements:
        for each_func_name in each_element:
            names_function[each_func_name.unique_id] = '[{id}] {name}'.format(
                id=each_func_name.unique_id.split('-')[0],
                name=each_func_name.name)

    # Calculate sunrise/sunset times if conditional controller is set up properly
    sunrise_set_calc = {}
    for each_trigger in trigger:
        if each_trigger.trigger_type == 'trigger_sunrise_sunset':
            sunrise_set_calc[each_trigger.unique_id] = {}
            try:
                sun = Sun(latitude=each_trigger.latitude,
                          longitude=each_trigger.longitude,
                          zenith=each_trigger.zenith)
                sunrise = sun.get_sunrise_time()['time_local']
                sunset = sun.get_sunset_time()['time_local']

                # Adjust for date offset
                new_date = datetime.datetime.now() + datetime.timedelta(
                    days=each_trigger.date_offset_days)

                sun = Sun(latitude=each_trigger.latitude,
                          longitude=each_trigger.longitude,
                          zenith=each_trigger.zenith,
                          day=new_date.day,
                          month=new_date.month,
                          year=new_date.year,
                          offset_minutes=each_trigger.time_offset_minutes)
                offset_rise = sun.get_sunrise_time()['time_local']
                offset_set = sun.get_sunset_time()['time_local']

                sunrise_set_calc[each_trigger.unique_id]['sunrise'] = (
                    sunrise.strftime("%Y-%m-%d %H:%M"))
                sunrise_set_calc[each_trigger.unique_id]['sunset'] = (
                    sunset.strftime("%Y-%m-%d %H:%M"))
                sunrise_set_calc[each_trigger.unique_id]['offset_sunrise'] = (
                    offset_rise.strftime("%Y-%m-%d %H:%M"))
                sunrise_set_calc[each_trigger.unique_id]['offset_sunset'] = (
                    offset_set.strftime("%Y-%m-%d %H:%M"))
            except:
                logger.exception(1)
                sunrise_set_calc[each_trigger.unique_id]['sunrise'] = None
                sunrise_set_calc[each_trigger.unique_id]['sunrise'] = None
                sunrise_set_calc[
                    each_trigger.unique_id]['offset_sunrise'] = None
                sunrise_set_calc[
                    each_trigger.unique_id]['offset_sunset'] = None

    if not function_type:
        return render_template(
            'pages/function.html',
            and_=and_,
            actions=actions,
            actions_dict=actions_dict,
            camera=camera,
            choices_controller_ids=choices_controller_ids,
            choices_custom_functions=choices_custom_functions,
            choices_function=choices_function,
            choices_functions=choices_functions,
            choices_functions_add=choices_functions_add,
            choices_input=choices_input,
            choices_input_devices=choices_input_devices,
            choices_math=choices_math,
            choices_measurements_units=choices_measurements_units,
            choices_method=choices_method,
            choices_output=choices_output,
            choices_output_channels=choices_output_channels,
            choices_output_channels_measurements=
            choices_output_channels_measurements,
            choices_pid=choices_pid,
            conditional_conditions_list=CONDITIONAL_CONDITIONS,
            conditional=conditional,
            conditional_conditions=conditional_conditions,
            conditions_dict=conditions_dict,
            controllers=controllers,
            function=function,
            function_channel=function_channel,
            custom_actions=custom_actions,
            custom_options_values_actions=custom_options_values_actions,
            custom_options_values_controllers=custom_options_values_controllers,
            custom_options_values_function_channels=
            custom_options_values_function_channels,
            dict_controllers=dict_controllers,
            dict_measurements=dict_measurements,
            dict_outputs=dict_outputs,
            dict_units=dict_units,
            display_order_function=display_order_function,
            form_conditional=form_conditional,
            form_conditional_conditions=form_conditional_conditions,
            form_function=form_function,
            form_actions=form_actions,
            form_add_function=form_add_function,
            form_function_base=form_function_base,
            form_mod_pid_base=form_mod_pid_base,
            form_mod_pid_pwm_raise=form_mod_pid_pwm_raise,
            form_mod_pid_pwm_lower=form_mod_pid_pwm_lower,
            form_mod_pid_output_raise=form_mod_pid_output_raise,
            form_mod_pid_output_lower=form_mod_pid_output_lower,
            form_mod_pid_value_raise=form_mod_pid_value_raise,
            form_mod_pid_value_lower=form_mod_pid_value_lower,
            form_mod_pid_volume_raise=form_mod_pid_volume_raise,
            form_mod_pid_volume_lower=form_mod_pid_volume_lower,
            form_trigger=form_trigger,
            function_action_info=FUNCTION_ACTION_INFO,
            function_dev=function_dev,
            function_types=FUNCTIONS,
            input=input_dev,
            lcd=lcd,
            math=math,
            method=method,
            names_function=names_function,
            output=output,
            output_types=output_types(),
            pid=pid,
            sunrise_set_calc=sunrise_set_calc,
            table_conversion=Conversion,
            table_device_measurements=DeviceMeasurements,
            table_input=Input,
            table_output=Output,
            tags=tags,
            trigger=trigger,
            units=MEASUREMENTS,
            user=user)
    elif function_type == 'entry':
        return render_template(
            function_page_entry,
            and_=and_,
            actions=actions,
            actions_dict=actions_dict,
            camera=camera,
            choices_controller_ids=choices_controller_ids,
            choices_custom_functions=choices_custom_functions,
            choices_function=choices_function,
            choices_functions=choices_functions,
            choices_functions_add=choices_functions_add,
            choices_input=choices_input,
            choices_input_devices=choices_input_devices,
            choices_math=choices_math,
            choices_measurements_units=choices_measurements_units,
            choices_method=choices_method,
            choices_output=choices_output,
            choices_output_channels=choices_output_channels,
            choices_output_channels_measurements=
            choices_output_channels_measurements,
            choices_pid=choices_pid,
            conditional_conditions_list=CONDITIONAL_CONDITIONS,
            conditional=conditional,
            conditional_conditions=conditional_conditions,
            conditions_dict=conditions_dict,
            controllers=controllers,
            function=function,
            function_channel=function_channel,
            custom_actions=custom_actions,
            custom_options_values_actions=custom_options_values_actions,
            custom_options_values_controllers=custom_options_values_controllers,
            custom_options_values_function_channels=
            custom_options_values_function_channels,
            dict_controllers=dict_controllers,
            dict_measurements=dict_measurements,
            dict_outputs=dict_outputs,
            dict_units=dict_units,
            display_order_function=display_order_function,
            each_function=each_function,
            form_conditional=form_conditional,
            form_conditional_conditions=form_conditional_conditions,
            form_function=form_function,
            form_actions=form_actions,
            form_add_function=form_add_function,
            form_function_base=form_function_base,
            form_mod_pid_base=form_mod_pid_base,
            form_mod_pid_pwm_raise=form_mod_pid_pwm_raise,
            form_mod_pid_pwm_lower=form_mod_pid_pwm_lower,
            form_mod_pid_output_raise=form_mod_pid_output_raise,
            form_mod_pid_output_lower=form_mod_pid_output_lower,
            form_mod_pid_value_raise=form_mod_pid_value_raise,
            form_mod_pid_value_lower=form_mod_pid_value_lower,
            form_mod_pid_volume_raise=form_mod_pid_volume_raise,
            form_mod_pid_volume_lower=form_mod_pid_volume_lower,
            form_trigger=form_trigger,
            function_action_info=FUNCTION_ACTION_INFO,
            function_dev=function_dev,
            function_types=FUNCTIONS,
            input=input_dev,
            lcd=lcd,
            math=math,
            method=method,
            names_function=names_function,
            output=output,
            output_types=output_types(),
            pid=pid,
            sunrise_set_calc=sunrise_set_calc,
            table_conversion=Conversion,
            table_device_measurements=DeviceMeasurements,
            table_input=Input,
            table_output=Output,
            tags=tags,
            trigger=trigger,
            units=MEASUREMENTS,
            user=user)
    elif function_type == 'options':
        return render_template(
            function_page_options,
            and_=and_,
            actions=actions,
            actions_dict=actions_dict,
            camera=camera,
            choices_controller_ids=choices_controller_ids,
            choices_custom_functions=choices_custom_functions,
            choices_function=choices_function,
            choices_functions=choices_functions,
            choices_functions_add=choices_functions_add,
            choices_input=choices_input,
            choices_input_devices=choices_input_devices,
            choices_math=choices_math,
            choices_measurements_units=choices_measurements_units,
            choices_method=choices_method,
            choices_output=choices_output,
            choices_output_channels=choices_output_channels,
            choices_output_channels_measurements=
            choices_output_channels_measurements,
            choices_pid=choices_pid,
            conditional_conditions_list=CONDITIONAL_CONDITIONS,
            conditional=conditional,
            conditional_conditions=conditional_conditions,
            conditions_dict=conditions_dict,
            controllers=controllers,
            each_function=each_function,
            function=function,
            function_channel=function_channel,
            custom_actions=custom_actions,
            custom_options_values_actions=custom_options_values_actions,
            custom_options_values_controllers=custom_options_values_controllers,
            custom_options_values_function_channels=
            custom_options_values_function_channels,
            dict_controllers=dict_controllers,
            dict_measurements=dict_measurements,
            dict_outputs=dict_outputs,
            dict_units=dict_units,
            display_order_function=display_order_function,
            form_conditional=form_conditional,
            form_conditional_conditions=form_conditional_conditions,
            form_function=form_function,
            form_actions=form_actions,
            form_add_function=form_add_function,
            form_function_base=form_function_base,
            form_mod_pid_base=form_mod_pid_base,
            form_mod_pid_pwm_raise=form_mod_pid_pwm_raise,
            form_mod_pid_pwm_lower=form_mod_pid_pwm_lower,
            form_mod_pid_output_raise=form_mod_pid_output_raise,
            form_mod_pid_output_lower=form_mod_pid_output_lower,
            form_mod_pid_value_raise=form_mod_pid_value_raise,
            form_mod_pid_value_lower=form_mod_pid_value_lower,
            form_mod_pid_volume_raise=form_mod_pid_volume_raise,
            form_mod_pid_volume_lower=form_mod_pid_volume_lower,
            form_trigger=form_trigger,
            function_action_info=FUNCTION_ACTION_INFO,
            function_dev=function_dev,
            function_types=FUNCTIONS,
            input=input_dev,
            lcd=lcd,
            math=math,
            method=method,
            names_function=names_function,
            output=output,
            output_types=output_types(),
            pid=pid,
            sunrise_set_calc=sunrise_set_calc,
            table_conversion=Conversion,
            table_device_measurements=DeviceMeasurements,
            table_input=Input,
            table_output=Output,
            tags=tags,
            trigger=trigger,
            units=MEASUREMENTS,
            user=user)
    elif function_type == 'actions':
        return render_template(
            'pages/function_options/actions.html',
            and_=and_,
            actions=actions,
            actions_dict=actions_dict,
            camera=camera,
            choices_controller_ids=choices_controller_ids,
            choices_custom_functions=choices_custom_functions,
            choices_function=choices_function,
            choices_functions=choices_functions,
            choices_functions_add=choices_functions_add,
            choices_input=choices_input,
            choices_input_devices=choices_input_devices,
            choices_math=choices_math,
            choices_measurements_units=choices_measurements_units,
            choices_method=choices_method,
            choices_output=choices_output,
            choices_output_channels=choices_output_channels,
            choices_output_channels_measurements=
            choices_output_channels_measurements,
            choices_pid=choices_pid,
            conditional_conditions_list=CONDITIONAL_CONDITIONS,
            conditional=conditional,
            conditional_conditions=conditional_conditions,
            conditions_dict=conditions_dict,
            controllers=controllers,
            each_action=each_action,
            each_function=each_function,
            function=function,
            function_channel=function_channel,
            custom_actions=custom_actions,
            custom_options_values_actions=custom_options_values_actions,
            custom_options_values_controllers=custom_options_values_controllers,
            custom_options_values_function_channels=
            custom_options_values_function_channels,
            dict_controllers=dict_controllers,
            dict_measurements=dict_measurements,
            dict_outputs=dict_outputs,
            dict_units=dict_units,
            display_order_function=display_order_function,
            form_conditional=form_conditional,
            form_conditional_conditions=form_conditional_conditions,
            form_function=form_function,
            form_actions=form_actions,
            form_add_function=form_add_function,
            form_function_base=form_function_base,
            form_mod_pid_base=form_mod_pid_base,
            form_mod_pid_pwm_raise=form_mod_pid_pwm_raise,
            form_mod_pid_pwm_lower=form_mod_pid_pwm_lower,
            form_mod_pid_output_raise=form_mod_pid_output_raise,
            form_mod_pid_output_lower=form_mod_pid_output_lower,
            form_mod_pid_value_raise=form_mod_pid_value_raise,
            form_mod_pid_value_lower=form_mod_pid_value_lower,
            form_mod_pid_volume_raise=form_mod_pid_volume_raise,
            form_mod_pid_volume_lower=form_mod_pid_volume_lower,
            form_trigger=form_trigger,
            function_action_info=FUNCTION_ACTION_INFO,
            function_dev=function_dev,
            function_types=FUNCTIONS,
            input=input_dev,
            lcd=lcd,
            math=math,
            method=method,
            names_function=names_function,
            output=output,
            output_types=output_types(),
            pid=pid,
            sunrise_set_calc=sunrise_set_calc,
            table_conversion=Conversion,
            table_device_measurements=DeviceMeasurements,
            table_input=Input,
            table_output=Output,
            tags=tags,
            trigger=trigger,
            units=MEASUREMENTS,
            user=user)
    elif function_type == 'conditions':
        return render_template(
            'pages/function_options/conditional_condition.html',
            and_=and_,
            actions=actions,
            actions_dict=actions_dict,
            camera=camera,
            choices_controller_ids=choices_controller_ids,
            choices_custom_functions=choices_custom_functions,
            choices_function=choices_function,
            choices_functions=choices_functions,
            choices_functions_add=choices_functions_add,
            choices_input=choices_input,
            choices_input_devices=choices_input_devices,
            choices_math=choices_math,
            choices_measurements_units=choices_measurements_units,
            choices_method=choices_method,
            choices_output=choices_output,
            choices_output_channels=choices_output_channels,
            choices_output_channels_measurements=
            choices_output_channels_measurements,
            choices_pid=choices_pid,
            conditional_conditions_list=CONDITIONAL_CONDITIONS,
            conditional=conditional,
            conditional_conditions=conditional_conditions,
            conditions_dict=conditions_dict,
            controllers=controllers,
            each_action=each_action,
            each_condition=each_condition,
            each_function=each_function,
            function=function,
            function_channel=function_channel,
            custom_actions=custom_actions,
            custom_options_values_actions=custom_options_values_actions,
            custom_options_values_controllers=custom_options_values_controllers,
            custom_options_values_function_channels=
            custom_options_values_function_channels,
            dict_controllers=dict_controllers,
            dict_measurements=dict_measurements,
            dict_outputs=dict_outputs,
            dict_units=dict_units,
            display_order_function=display_order_function,
            form_conditional=form_conditional,
            form_conditional_conditions=form_conditional_conditions,
            form_function=form_function,
            form_actions=form_actions,
            form_add_function=form_add_function,
            form_function_base=form_function_base,
            form_mod_pid_base=form_mod_pid_base,
            form_mod_pid_pwm_raise=form_mod_pid_pwm_raise,
            form_mod_pid_pwm_lower=form_mod_pid_pwm_lower,
            form_mod_pid_output_raise=form_mod_pid_output_raise,
            form_mod_pid_output_lower=form_mod_pid_output_lower,
            form_mod_pid_value_raise=form_mod_pid_value_raise,
            form_mod_pid_value_lower=form_mod_pid_value_lower,
            form_mod_pid_volume_raise=form_mod_pid_volume_raise,
            form_mod_pid_volume_lower=form_mod_pid_volume_lower,
            form_trigger=form_trigger,
            function_action_info=FUNCTION_ACTION_INFO,
            function_dev=function_dev,
            function_types=FUNCTIONS,
            input=input_dev,
            lcd=lcd,
            math=math,
            method=method,
            names_function=names_function,
            output=output,
            output_types=output_types(),
            pid=pid,
            sunrise_set_calc=sunrise_set_calc,
            table_conversion=Conversion,
            table_device_measurements=DeviceMeasurements,
            table_input=Input,
            table_output=Output,
            tags=tags,
            trigger=trigger,
            units=MEASUREMENTS,
            user=user)
    else:
        return "Could not determine template"