Beispiel #1
0
    def __init__(self, output, testing=False, name=__name__):
        if not testing:
            super(AbstractOutput, self).__init__(output.unique_id,
                                                 testing=testing,
                                                 name=__name__)
        else:
            super(AbstractOutput, self).__init__(None,
                                                 testing=testing,
                                                 name=__name__)

        self.output_setup = False
        self.startup_timer = timeit.default_timer()
        self.control = DaemonControl()

        self.logger = None
        self.setup_logger(testing=testing, name=name, output_dev=output)

        self.OUTPUT_INFORMATION = None
        self.output_time_turned_on = {}
        self.output_on_duration = {}
        self.output_last_duration = {}
        self.output_on_until = {}
        self.output_off_until = {}
        self.output_off_triggered = {}
        self.output_states = {}

        self.output = output
        self.running = True

        if not testing:
            self.output_types = output_types()
            self.unique_id = output.unique_id
            self.output_name = self.output.name
            self.output_type = self.output.output_type
            self.output_force_command = self.output.force_command
Beispiel #2
0
    def all_outputs_initialize(self, outputs):
        """ Initialize all output variables and classes """
        self.dict_outputs = parse_output_information()
        self.output_types = output_types()

        for each_output in outputs:
            try:
                self.output_type[each_output.unique_id] = each_output.output_type
                self.output_unique_id[each_output.unique_id] = {}

                if 'channels_dict' in self.dict_outputs[each_output.output_type]:
                    for each_channel in self.dict_outputs[each_output.output_type]['channels_dict']:
                        self.output_unique_id[each_output.unique_id][each_channel] = None
                else:
                    self.output_unique_id[each_output.unique_id][0] = None

                if each_output.output_type in self.dict_outputs:
                    output_loaded = load_module_from_file(
                        self.dict_outputs[each_output.output_type]['file_path'],
                        'outputs')
                    self.output[each_output.unique_id] = output_loaded.OutputModule(each_output)
                    self.output[each_output.unique_id].setup_output()
                    self.output[each_output.unique_id].init_post()

                self.logger.debug("{id} ({name}) Initialized".format(
                    id=each_output.unique_id.split('-')[0], name=each_output.name))
            except:
                self.logger.exception("Could not initialize output {}".format(
                    each_output.unique_id))
Beispiel #3
0
    def all_outputs_initialize(self, outputs):
        """ Initialize all output variables and classes """
        self.dict_outputs = parse_output_information()
        self.output_types = output_types()

        for each_output in outputs:
            try:
                self.output_unique_id[
                    each_output.unique_id] = each_output.unique_id
                self.output_type[
                    each_output.unique_id] = each_output.output_type
                self.output_name[each_output.unique_id] = each_output.name
                self.output_amps[each_output.unique_id] = each_output.amps
                self.output_state_startup[
                    each_output.unique_id] = each_output.state_startup
                self.output_startup_value[
                    each_output.unique_id] = each_output.startup_value
                self.output_state_shutdown[
                    each_output.unique_id] = each_output.state_shutdown
                self.output_shutdown_value[
                    each_output.unique_id] = each_output.shutdown_value
                self.output_on_until[
                    each_output.unique_id] = datetime.datetime.now()
                self.output_last_duration[each_output.unique_id] = 0
                self.output_on_duration[each_output.unique_id] = False
                self.output_off_triggered[each_output.unique_id] = False
                self.output_time_turned_on[each_output.unique_id] = None
                self.output_force_command[
                    each_output.unique_id] = each_output.force_command
                self.trigger_functions_at_start[
                    each_output.
                    unique_id] = each_output.trigger_functions_at_start

                if each_output.output_type in self.dict_outputs:
                    output_loaded = load_module_from_file(
                        self.dict_outputs[each_output.output_type]
                        ['file_path'], 'outputs')
                    self.output[
                        each_output.unique_id] = output_loaded.OutputModule(
                            each_output)
                    self.output[each_output.unique_id].setup_output()
                    self.output[each_output.unique_id].init_post()

                self.logger.debug("{id} ({name}) Initialized".format(
                    id=each_output.unique_id.split('-')[0],
                    name=each_output.name))
            except:
                self.logger.exception("Could not initialize output {}".format(
                    each_output.unique_id))
Beispiel #4
0
    def all_outputs_initialize(self, outputs):
        """Initialize all output variables and classes."""
        self.dict_outputs = parse_output_information()
        self.output_types = output_types()

        for each_output in outputs:
            if each_output.output_type not in self.dict_outputs:
                self.logger.error(
                    f"'{each_output.output_type}' not found in Output dictionary. Not starting Output."
                )
                continue

            try:
                self.output_type[
                    each_output.unique_id] = each_output.output_type
                self.output_unique_id[each_output.unique_id] = {}

                if 'channels_dict' in self.dict_outputs[
                        each_output.output_type]:
                    for each_channel in self.dict_outputs[
                            each_output.output_type]['channels_dict']:
                        self.output_unique_id[
                            each_output.unique_id][each_channel] = None
                else:
                    self.output_unique_id[each_output.unique_id][0] = None

                if each_output.output_type in self.dict_outputs:
                    if ('no_run' in self.dict_outputs[each_output.output_type]
                            and self.dict_outputs[
                                each_output.output_type]['no_run']):
                        continue

                    output_loaded, status = load_module_from_file(
                        self.dict_outputs[each_output.output_type]
                        ['file_path'], 'outputs')

                    if output_loaded:
                        self.output[each_output.
                                    unique_id] = output_loaded.OutputModule(
                                        each_output)
                        self.output[each_output.unique_id].try_initialize()
                        self.output[each_output.unique_id].init_post()

                self.logger.debug(
                    f"{each_output.unique_id.split('-')[0]} ({each_output.name}) Initialized"
                )
            except:
                self.logger.exception(
                    f"Could not initialize output {each_output.unique_id}")
Beispiel #5
0
def page_output():
    """Display Output page options."""
    output_type = request.args.get('output_type', None)
    output_id = request.args.get('output_id', None)
    each_output = None
    if output_type in ['entry', 'options'] and output_id != '0':
        each_output = Output.query.filter(
            Output.unique_id == output_id).first()

    camera = Camera.query.all()
    function = CustomController.query.all()
    input_dev = Input.query.all()
    method = Method.query.all()
    misc = Misc.query.first()
    output = Output.query.all()
    output_channel = OutputChannel
    pid = PID.query.all()
    user = User.query.all()

    dict_outputs = parse_output_information()

    form_add_output = forms_output.OutputAdd()
    form_mod_output = forms_output.OutputMod()

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

    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_method = utils_general.choices_methods(method)
    choices_output = utils_general.choices_outputs(output, OutputChannel,
                                                   dict_outputs, dict_units,
                                                   dict_measurements)
    choices_output_channels = utils_general.choices_outputs_channels(
        output, output_channel.query.all(), dict_outputs)
    choices_pid = utils_general.choices_pids(pid, dict_units,
                                             dict_measurements)

    custom_options_values_outputs = parse_custom_option_values_json(
        output, dict_controller=dict_outputs)
    custom_options_values_output_channels = parse_custom_option_values_output_channels_json(
        output_channel.query.all(),
        dict_controller=dict_outputs,
        key_name='custom_channel_options')

    custom_commands = {}
    for each_output_dev in output:
        if 'custom_commands' in dict_outputs[each_output_dev.output_type]:
            custom_commands[each_output_dev.output_type] = True

    # Create dict of Input names
    names_output = {}
    all_elements = output
    for each_element in all_elements:
        names_output[each_element.unique_id] = '[{id}] {name}'.format(
            id=each_element.unique_id.split('-')[0], name=each_element.name)

    # Create list of file names from the output_options directory
    # Used in generating the correct options for each output/device
    output_templates = []
    output_path = os.path.join(
        INSTALL_DIRECTORY,
        'mycodo/mycodo_flask/templates/pages/output_options')
    for (_, _, file_names) in os.walk(output_path):
        output_templates.extend(file_names)
        break

    display_order_output = csv_to_list_of_str(
        DisplayOrder.query.first().output)

    output_variables = {}
    for each_output_dev in output:
        output_variables[each_output_dev.unique_id] = {}
        for each_channel in dict_outputs[
                each_output_dev.output_type]['channels_dict']:
            output_variables[each_output_dev.unique_id][each_channel] = {}
            output_variables[
                each_output_dev.unique_id][each_channel]['amps'] = None
            output_variables[each_output_dev.
                             unique_id][each_channel]['trigger_startup'] = None

    # Find FTDI devices
    ftdi_devices = []
    if not current_app.config['TESTING']:
        for each_output_dev in output:
            if each_output_dev.interface == "FTDI":
                from mycodo.devices.atlas_scientific_ftdi import get_ftdi_device_list
                ftdi_devices = get_ftdi_device_list()
                break

    if not output_type:
        return render_template(
            'pages/output.html',
            camera=camera,
            choices_function=choices_function,
            choices_input=choices_input,
            choices_input_devices=choices_input_devices,
            choices_method=choices_method,
            choices_output=choices_output,
            choices_output_channels=choices_output_channels,
            choices_pid=choices_pid,
            custom_commands=custom_commands,
            custom_options_values_outputs=custom_options_values_outputs,
            custom_options_values_output_channels=
            custom_options_values_output_channels,
            dict_outputs=dict_outputs,
            display_order_output=display_order_output,
            form_add_output=form_add_output,
            form_mod_output=form_mod_output,
            ftdi_devices=ftdi_devices,
            misc=misc,
            names_output=names_output,
            output=output,
            output_channel=output_channel,
            output_types=output_types(),
            output_templates=output_templates,
            output_variables=output_variables,
            user=user)
    elif output_type == 'entry':
        return render_template(
            'pages/output_entry.html',
            camera=camera,
            choices_function=choices_function,
            choices_input=choices_input,
            choices_input_devices=choices_input_devices,
            choices_method=choices_method,
            choices_output=choices_output,
            choices_output_channels=choices_output_channels,
            choices_pid=choices_pid,
            custom_commands=custom_commands,
            custom_options_values_outputs=custom_options_values_outputs,
            custom_options_values_output_channels=
            custom_options_values_output_channels,
            dict_outputs=dict_outputs,
            display_order_output=display_order_output,
            each_output=each_output,
            form_add_output=form_add_output,
            form_mod_output=form_mod_output,
            ftdi_devices=ftdi_devices,
            misc=misc,
            names_output=names_output,
            output=output,
            output_channel=output_channel,
            output_types=output_types(),
            output_templates=output_templates,
            output_variables=output_variables,
            user=user)
    elif output_type == 'options':
        return render_template(
            'pages/output_options.html',
            camera=camera,
            choices_function=choices_function,
            choices_input=choices_input,
            choices_input_devices=choices_input_devices,
            choices_method=choices_method,
            choices_output=choices_output,
            choices_output_channels=choices_output_channels,
            choices_pid=choices_pid,
            custom_commands=custom_commands,
            custom_options_values_outputs=custom_options_values_outputs,
            custom_options_values_output_channels=
            custom_options_values_output_channels,
            dict_outputs=dict_outputs,
            display_order_output=display_order_output,
            each_output=each_output,
            form_add_output=form_add_output,
            form_mod_output=form_mod_output,
            ftdi_devices=ftdi_devices,
            misc=misc,
            names_output=names_output,
            output=output,
            output_channel=output_channel,
            output_types=output_types(),
            output_templates=output_templates,
            output_variables=output_variables,
            user=user)
Beispiel #6
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', '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_measurement = forms_measurement.MeasurementMod()
    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_measurement=form_mod_measurement,
            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_measurement=form_mod_measurement,
            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_measurement=form_mod_measurement,
            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_measurement=form_mod_measurement,
            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_measurement=form_mod_measurement,
            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"
Beispiel #7
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
    controller_type = 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' and action_id:
            each_action = Actions.query.filter(
                Actions.unique_id == action_id).first()
            if each_action:
                controller_type = determine_controller_type(each_action.function_id)

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

    action = Actions.query.all()
    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()
    input_dev = Input.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_action.Actions()

    dict_controllers = parse_function_information()
    dict_actions = parse_action_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')

    custom_options_values_actions = {}
    for each_action_dev in action:
        try:
            custom_options_values_actions[each_action_dev.unique_id] = json.loads(each_action_dev.custom_options)
        except:
            custom_options_values_actions[each_action_dev.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_commands = {}
    for choice_function in function:
        if 'custom_commands' in dict_controllers[choice_function.device]:
            custom_commands[choice_function.device] = True

    # Generate Action dropdown for use with Inputs
    choices_actions = []
    list_actions_sorted = generate_form_action_list(dict_actions, application=["functions"])
    for name in list_actions_sorted:
        choices_actions.append((name, dict_actions[name]['name']))

    # Create list of choices to be used in dropdown menus
    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_method = utils_general.choices_methods(method)
    choices_output = utils_general.choices_outputs(
        output, OutputChannel, dict_outputs, 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_tag = utils_general.choices_tags(tags)
    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_dev in action:
        if (each_action_dev.function_type == 'conditional' and
                each_action_dev.unique_id not in actions_dict['conditional']):
            actions_dict['conditional'][each_action_dev.function_id] = True
        if (each_action_dev.function_type == 'trigger' and
                each_action_dev.unique_id not in actions_dict['trigger']):
            actions_dict['trigger'][each_action_dev.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),
                       ('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] = {}
            if not current_app.config['TESTING']:
                try:
                    sunrise = suntime_calculate_next_sunrise_sunset_epoch(
                        each_trigger.latitude, each_trigger.longitude, 0, 0, "sunrise", return_dt=True)
                    sunset = suntime_calculate_next_sunrise_sunset_epoch(
                        each_trigger.latitude, each_trigger.longitude, 0, 0, "sunset", return_dt=True)

                    # Adjust for date offset
                    offset_rise = suntime_calculate_next_sunrise_sunset_epoch(
                        each_trigger.latitude, each_trigger.longitude, each_trigger.date_offset_days,
                        each_trigger.time_offset_minutes, "sunrise", return_dt=True)
                    offset_set = suntime_calculate_next_sunrise_sunset_epoch(
                        each_trigger.latitude, each_trigger.longitude, each_trigger.date_offset_days,
                        each_trigger.time_offset_minutes, "sunset", return_dt=True)

                    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'] = "ERROR"
                    sunrise_set_calc[each_trigger.unique_id]['sunrise'] = "ERROR"
                    sunrise_set_calc[each_trigger.unique_id]['offset_sunrise'] = "ERROR"
                    sunrise_set_calc[each_trigger.unique_id]['offset_sunset'] = "ERROR"

    if not function_type:
        return render_template('pages/function.html',
                               and_=and_,
                               action=action,
                               actions_dict=actions_dict,
                               camera=camera,
                               choices_actions=choices_actions,
                               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_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,
                               choices_tag=choices_tag,
                               conditional_conditions_list=CONDITIONAL_CONDITIONS,
                               conditional=conditional,
                               conditional_conditions=conditional_conditions,
                               conditions_dict=conditions_dict,
                               controllers=controllers,
                               controller_type=controller_type,
                               function=function,
                               function_channel=function_channel,
                               custom_commands=custom_commands,
                               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_actions=dict_actions,
                               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_dev=function_dev,
                               function_types=FUNCTIONS,
                               input=input_dev,
                               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_,
                               action=action,
                               actions_dict=actions_dict,
                               camera=camera,
                               choices_actions=choices_actions,
                               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_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,
                               choices_tag=choices_tag,
                               conditional_conditions_list=CONDITIONAL_CONDITIONS,
                               conditional=conditional,
                               conditional_conditions=conditional_conditions,
                               conditions_dict=conditions_dict,
                               controllers=controllers,
                               controller_type=controller_type,
                               function=function,
                               function_channel=function_channel,
                               custom_commands=custom_commands,
                               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_actions=dict_actions,
                               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_dev=function_dev,
                               function_types=FUNCTIONS,
                               input=input_dev,
                               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_,
                               action=action,
                               actions_dict=actions_dict,
                               camera=camera,
                               choices_actions=choices_actions,
                               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_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,
                               choices_tag=choices_tag,
                               conditional_conditions_list=CONDITIONAL_CONDITIONS,
                               conditional=conditional,
                               conditional_conditions=conditional_conditions,
                               conditions_dict=conditions_dict,
                               controllers=controllers,
                               controller_type=controller_type,
                               each_function=each_function,
                               function=function,
                               function_channel=function_channel,
                               custom_commands=custom_commands,
                               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_actions=dict_actions,
                               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_dev=function_dev,
                               function_types=FUNCTIONS,
                               input=input_dev,
                               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/actions.html',
                               and_=and_,
                               action=action,
                               actions_dict=actions_dict,
                               camera=camera,
                               choices_actions=choices_actions,
                               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_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,
                               choices_tag=choices_tag,
                               conditional_conditions_list=CONDITIONAL_CONDITIONS,
                               conditional=conditional,
                               conditional_conditions=conditional_conditions,
                               conditions_dict=conditions_dict,
                               controllers=controllers,
                               controller_type=controller_type,
                               each_action=each_action,
                               each_function=each_function,
                               function=function,
                               function_channel=function_channel,
                               custom_commands=custom_commands,
                               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_actions=dict_actions,
                               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_dev=function_dev,
                               function_types=FUNCTIONS,
                               input=input_dev,
                               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_,
                               action=action,
                               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_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,
                               choices_tag=choices_tag,
                               conditional_conditions_list=CONDITIONAL_CONDITIONS,
                               conditional=conditional,
                               conditional_conditions=conditional_conditions,
                               conditions_dict=conditions_dict,
                               controllers=controllers,
                               controller_type=controller_type,
                               each_condition=each_condition,
                               each_function=each_function,
                               function=function,
                               function_channel=function_channel,
                               custom_commands=custom_commands,
                               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_actions=dict_actions,
                               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_dev=function_dev,
                               function_types=FUNCTIONS,
                               input=input_dev,
                               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"
Beispiel #8
0
def output_add(form_add):
    action = '{action} {controller}'.format(
        action=TRANSLATIONS['add']['title'],
        controller=TRANSLATIONS['output']['title'])
    error = []

    dict_outputs = parse_output_information()
    output_types_dict = output_types()

    # only one comma should be in the output_type string
    if form_add.output_type.data.count(',') > 1:
        error.append("Invalid output module formatting. It appears there is "
                     "a comma in either 'output_name_unique' or 'interfaces'.")

    if form_add.output_type.data.count(',') == 1:
        output_type = form_add.output_type.data.split(',')[0]
        output_interface = form_add.output_type.data.split(',')[1]
    else:
        output_type = ''
        output_interface = ''
        error.append(
            "Invalid output string (must be a comma-separated string)")

    if current_app.config['TESTING']:
        dep_unmet = False
    else:
        dep_unmet, _ = return_dependencies(
            form_add.output_type.data.split(',')[0])
        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=form_add.output_type.data,
                               dep=', '.join(list_unmet_deps)))

    if not is_int(form_add.output_quantity.data, check_range=[1, 20]):
        error.append("{error}. {accepted_values}: 1-20".format(
            error=gettext("Invalid quantity"),
            accepted_values=gettext("Acceptable values")))

    if not error:
        for _ in range(0, form_add.output_quantity.data):
            try:
                new_output = Output()

                try:
                    from RPi import GPIO
                    if GPIO.RPI_INFO['P1_REVISION'] == 1:
                        new_output.i2c_bus = 0
                    else:
                        new_output.i2c_bus = 1
                except:
                    logger.error(
                        "RPi.GPIO and Raspberry Pi required for this action")

                new_output.name = "Name"
                new_output.output_type = output_type
                new_output.interface = output_interface

                #
                # Set default values for new input being added
                #

                # input add options
                if output_type in dict_outputs:

                    def dict_has_value(key):
                        if (key in dict_outputs[output_type] and
                                dict_outputs[output_type][key] is not None):
                            return True

                    #
                    # Interfacing options
                    #

                    if output_interface == 'I2C':
                        if dict_has_value('i2c_address_default'):
                            new_output.i2c_location = dict_outputs[
                                output_type]['i2c_address_default']
                        elif dict_has_value('i2c_location'):
                            new_output.i2c_location = dict_outputs[
                                output_type]['i2c_location'][
                                    0]  # First list entry

                    if output_interface == 'FTDI':
                        if dict_has_value('ftdi_location'):
                            new_output.ftdi_location = dict_outputs[
                                output_type]['ftdi_location']

                    if output_interface == 'UART':
                        if dict_has_value('uart_location'):
                            new_output.uart_location = dict_outputs[
                                output_type]['uart_location']

                    # UART options
                    if dict_has_value('uart_baud_rate'):
                        new_output.baud_rate = dict_outputs[output_type][
                            'uart_baud_rate']
                    if dict_has_value('pin_cs'):
                        new_output.pin_cs = dict_outputs[output_type]['pin_cs']
                    if dict_has_value('pin_miso'):
                        new_output.pin_miso = dict_outputs[output_type][
                            'pin_miso']
                    if dict_has_value('pin_mosi'):
                        new_output.pin_mosi = dict_outputs[output_type][
                            'pin_mosi']
                    if dict_has_value('pin_clock'):
                        new_output.pin_clock = dict_outputs[output_type][
                            'pin_clock']

                    # Bluetooth (BT) options
                    elif output_interface == 'BT':
                        if dict_has_value('bt_location'):
                            new_output.location = dict_outputs[output_type][
                                'bt_location']
                        if dict_has_value('bt_adapter'):
                            new_output.bt_adapter = dict_outputs[output_type][
                                'bt_adapter']

                    # GPIO options
                    elif output_interface == 'GPIO':
                        if dict_has_value('gpio_pin'):
                            new_output.pin = dict_outputs[output_type][
                                'gpio_pin']

                    # Custom location location
                    elif dict_has_value('location'):
                        new_output.location = dict_outputs[output_type][
                            'location']['options'][0][0]  # First entry in list

                #
                # Custom Options
                #

                list_options = []
                if 'custom_options' in dict_outputs[output_type]:
                    for each_option in dict_outputs[output_type][
                            'custom_options']:
                        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_output.custom_options = ';'.join(list_options)

                if output_type in output_types_dict['pwm']:
                    new_output.pwm_hertz = 22000
                    new_output.pwm_library = 'pigpio_any'

                if output_type in output_types_dict['volume']:
                    new_output.output_mode = 'fastest_flow_rate'
                    new_output.flow_rate = 10
                    if output_type == 'atlas_ezo_pmp':
                        if output_interface == 'FTDI':
                            new_output.location = '/dev/ttyUSB0'
                        elif output_interface == 'I2C':
                            new_output.location = '0x67'
                            new_output.i2c_bus = 1
                        elif output_interface == 'UART':
                            new_output.location = '/dev/ttyAMA0'
                            new_output.baud_rate = 9600

                if output_type == 'wired':
                    new_output.state_startup = '0'
                    new_output.state_shutdown = '0'

                elif output_type == 'wireless_rpi_rf':
                    new_output.pin = None
                    new_output.protocol = 1
                    new_output.pulse_length = 189
                    new_output.on_command = '22559'
                    new_output.off_command = '22558'
                    new_output.force_command = True

                elif output_type == 'command':
                    new_output.linux_command_user = '******'
                    new_output.on_command = '/home/pi/script_on.sh'
                    new_output.off_command = '/home/pi/script_off.sh'
                    new_output.force_command = True

                elif output_type == 'command_pwm':
                    new_output.linux_command_user = '******'
                    new_output.pwm_command = '/home/pi/script_pwm.sh ((duty_cycle))'

                elif output_type == 'python':
                    new_output.on_command = """
import datetime
timestamp = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
log_string = "{ts}: ID: {id}: ON".format(id=output_id, ts=timestamp)
self.logger.info(log_string)"""
                    new_output.off_command = """
import datetime
timestamp = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
log_string = "{ts}: ID: {id}: OFF".format(id=output_id, ts=timestamp)
self.logger.info(log_string)"""
                    new_output.force_command = True

                elif output_type == 'python_pwm':
                    new_output.pwm_command = """
import datetime
timestamp = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
log_string = "{ts}: ID: {id}: {dc} % Duty Cycle".format(
    dc=duty_cycle, id=output_id, ts=timestamp)
self.logger.info(log_string)"""

                if not error:
                    new_output.save()
                    display_order = csv_to_list_of_str(
                        DisplayOrder.query.first().output)
                    DisplayOrder.query.first().output = add_display_order(
                        display_order, new_output.unique_id)

                    #
                    # If measurements defined in the Output Module
                    #

                    if ('measurements_dict' in dict_outputs[output_type]
                            and dict_outputs[output_type]['measurements_dict']
                            != []):
                        for each_channel in dict_outputs[output_type][
                                'measurements_dict']:
                            measure_info = dict_outputs[output_type][
                                'measurements_dict'][each_channel]
                            new_measurement = DeviceMeasurements()
                            if 'name' in measure_info:
                                new_measurement.name = measure_info['name']
                            new_measurement.device_id = new_output.unique_id
                            new_measurement.measurement = measure_info[
                                'measurement']
                            new_measurement.unit = measure_info['unit']
                            new_measurement.channel = each_channel
                            new_measurement.save()

                    db.session.commit()

                    if not current_app.config['TESTING']:
                        manipulate_output('Add', new_output.unique_id)
            except sqlalchemy.exc.OperationalError as except_msg:
                error.append(except_msg)
            except sqlalchemy.exc.IntegrityError as except_msg:
                error.append(except_msg)

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

    if dep_unmet:
        return 1
Beispiel #9
0
def page_input():
    """Display Data page options."""
    input_type = request.args.get('input_type', None)
    input_id = request.args.get('input_id', None)
    action_id = request.args.get('action_id', None)

    each_input = None
    each_action = None

    if input_type in ['entry', 'options', 'actions']:
        each_input = Input.query.filter(Input.unique_id == input_id).first()

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

    action = Actions.query.all()
    function = CustomController.query.all()
    input_dev = Input.query.all()
    input_channel = InputChannel.query.all()
    method = Method.query.all()
    measurement = Measurement.query.all()
    output = Output.query.all()
    output_channel = OutputChannel.query.all()
    pid = PID.query.all()
    user = User.query.all()
    unit = Unit.query.all()

    display_order_input = csv_to_list_of_str(DisplayOrder.query.first().inputs)

    form_add_input = forms_input.InputAdd()
    form_mod_input = forms_input.InputMod()
    form_actions = forms_action.Actions()

    dict_inputs = parse_input_information()
    dict_actions = parse_action_information()

    custom_options_values_inputs = parse_custom_option_values(
        input_dev, dict_controller=dict_inputs)
    custom_options_values_input_channels = parse_custom_option_values_input_channels_json(
        input_channel, dict_controller=dict_inputs, key_name='custom_channel_options')

    custom_options_values_actions = {}
    for each_action_dev in action:
        try:
            custom_options_values_actions[each_action_dev.unique_id] = json.loads(each_action_dev.custom_options)
        except:
            custom_options_values_actions[each_action_dev.unique_id] = {}

    custom_commands = {}
    for each_input_dev in input_dev:
        if each_input_dev.device in dict_inputs and 'custom_commands' in dict_inputs[each_input_dev.device]:
            custom_commands[each_input_dev.device] = True

    # Generate dict that incorporate user-added measurements/units
    dict_outputs = parse_output_information()
    dict_units = add_custom_units(unit)
    dict_measurements = add_custom_measurements(measurement)

    # Generate Action dropdown for use with Inputs
    choices_actions = []
    list_actions_sorted = generate_form_action_list(dict_actions, application=["inputs"])
    for name in list_actions_sorted:
        choices_actions.append((name, dict_actions[name]['name']))

    # Create list of choices to be used in dropdown menus
    choices_function = utils_general.choices_functions(
        function, dict_units, dict_measurements)
    choices_input = utils_general.choices_inputs(
        input_dev, dict_units, dict_measurements)
    choices_method = utils_general.choices_methods(method)
    choices_output = utils_general.choices_outputs(
        output, OutputChannel, dict_outputs, 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_pid_devices = utils_general.choices_pids_devices(pid)
    choices_unit = utils_general.choices_units(unit)
    choices_measurement = utils_general.choices_measurements(measurement)
    choices_measurements_units = utils_general.choices_measurements_units(measurement, unit)

    # Create dict of Input names
    names_input = {}
    all_elements = input_dev
    for each_element in all_elements:
        names_input[each_element.unique_id] = '[{id:02d}] ({uid}) {name}'.format(
            id=each_element.id,
            uid=each_element.unique_id.split('-')[0],
            name=each_element.name)

    # Create list of file names from the input_options directory
    # Used in generating the correct options for each input controller
    input_templates = []
    input_path = os.path.join(
        INSTALL_DIRECTORY,
        'mycodo/mycodo_flask/templates/pages/data_options/input_options')
    for (_, _, file_names) in os.walk(input_path):
        input_templates.extend(file_names)
        break

    # Compile a list of 1-wire devices
    devices_1wire = []
    if os.path.isdir(PATH_1WIRE):
        for each_name in os.listdir(PATH_1WIRE):
            if 'bus' not in each_name and '-' in each_name:
                devices_1wire.append(
                    {'name': each_name, 'value': each_name.split('-')[1]}
                )

    # Compile a list of 1-wire devices (using ow-shell)
    devices_1wire_ow_shell = []
    if not Input.query.filter(Input.device == "DS18B20_OWS").count():
        pass
    elif current_app.config['TESTING']:
        logger.debug("Testing: Skipping testing for 'ow-shell'")
    elif not dpkg_package_exists('ow-shell'):
        logger.debug("Package 'ow-shell' not found")
    else:
        logger.debug("Package 'ow-shell' found")
        try:
            test_cmd = subprocess.check_output(['owdir']).splitlines()
            for each_ow in test_cmd:
                str_ow = re.sub("\ |\/|\'", "", each_ow.decode("utf-8"))  # Strip / and '
                if '.' in str_ow and len(str_ow) == 15:
                    devices_1wire_ow_shell.append(str_ow)
        except Exception:
            logger.error("Error finding 1-wire devices with 'owdir'")

    # Find FTDI devices
    ftdi_devices = []
    if not current_app.config['TESTING']:
        for each_input_dev in input_dev:
            if each_input_dev.interface == "FTDI":
                from mycodo.devices.atlas_scientific_ftdi import get_ftdi_device_list
                ftdi_devices = get_ftdi_device_list()
                break

    if not input_type:
        return render_template('pages/input.html',
                               and_=and_,
                               action=action,
                               choices_actions=choices_actions,
                               choices_function=choices_function,
                               choices_input=choices_input,
                               choices_output=choices_output,
                               choices_measurement=choices_measurement,
                               choices_measurements_units=choices_measurements_units,
                               choices_method=choices_method,
                               choices_output_channels=choices_output_channels,
                               choices_output_channels_measurements=choices_output_channels_measurements,
                               choices_pid=choices_pid,
                               choices_pid_devices=choices_pid_devices,
                               choices_unit=choices_unit,
                               custom_commands=custom_commands,
                               custom_options_values_actions=custom_options_values_actions,
                               custom_options_values_inputs=custom_options_values_inputs,
                               custom_options_values_input_channels=custom_options_values_input_channels,
                               dict_actions=dict_actions,
                               dict_inputs=dict_inputs,
                               dict_measurements=dict_measurements,
                               dict_units=dict_units,
                               display_order_input=display_order_input,
                               form_actions=form_actions,
                               form_add_input=form_add_input,
                               form_mod_input=form_mod_input,
                               ftdi_devices=ftdi_devices,
                               input_channel=input_channel,
                               input_templates=input_templates,
                               names_input=names_input,
                               output=output,
                               output_types=output_types(),
                               pid=pid,
                               table_conversion=Conversion,
                               table_device_measurements=DeviceMeasurements,
                               table_input=Input,
                               user=user,
                               devices_1wire_ow_shell=devices_1wire_ow_shell,
                               devices_1wire=devices_1wire)
    elif input_type == 'entry':
        return render_template('pages/data_options/input_entry.html',
                               and_=and_,
                               action=action,
                               choices_actions=choices_actions,
                               choices_function=choices_function,
                               choices_input=choices_input,
                               choices_output=choices_output,
                               choices_measurement=choices_measurement,
                               choices_measurements_units=choices_measurements_units,
                               choices_method=choices_method,
                               choices_output_channels=choices_output_channels,
                               choices_output_channels_measurements=choices_output_channels_measurements,
                               choices_pid=choices_pid,
                               choices_pid_devices=choices_pid_devices,
                               choices_unit=choices_unit,
                               custom_commands=custom_commands,
                               custom_options_values_actions=custom_options_values_actions,
                               custom_options_values_inputs=custom_options_values_inputs,
                               custom_options_values_input_channels=custom_options_values_input_channels,
                               dict_actions=dict_actions,
                               dict_inputs=dict_inputs,
                               dict_measurements=dict_measurements,
                               dict_units=dict_units,
                               display_order_input=display_order_input,
                               each_input=each_input,
                               form_actions=form_actions,
                               form_add_input=form_add_input,
                               form_mod_input=form_mod_input,
                               ftdi_devices=ftdi_devices,
                               input_channel=input_channel,
                               input_templates=input_templates,
                               names_input=names_input,
                               output=output,
                               output_types=output_types(),
                               pid=pid,
                               table_conversion=Conversion,
                               table_device_measurements=DeviceMeasurements,
                               table_input=Input,
                               user=user,
                               devices_1wire_ow_shell=devices_1wire_ow_shell,
                               devices_1wire=devices_1wire)
    elif input_type == 'options':
        return render_template('pages/data_options/input_options.html',
                               and_=and_,
                               action=action,
                               choices_actions=choices_actions,
                               choices_function=choices_function,
                               choices_input=choices_input,
                               choices_output=choices_output,
                               choices_measurement=choices_measurement,
                               choices_measurements_units=choices_measurements_units,
                               choices_method=choices_method,
                               choices_output_channels=choices_output_channels,
                               choices_output_channels_measurements=choices_output_channels_measurements,
                               choices_pid=choices_pid,
                               choices_pid_devices=choices_pid_devices,
                               choices_unit=choices_unit,
                               custom_commands=custom_commands,
                               custom_options_values_actions=custom_options_values_actions,
                               custom_options_values_inputs=custom_options_values_inputs,
                               custom_options_values_input_channels=custom_options_values_input_channels,
                               dict_actions=dict_actions,
                               dict_inputs=dict_inputs,
                               dict_measurements=dict_measurements,
                               dict_units=dict_units,
                               display_order_input=display_order_input,
                               each_input=each_input,
                               form_actions=form_actions,
                               form_add_input=form_add_input,
                               form_mod_input=form_mod_input,
                               ftdi_devices=ftdi_devices,
                               input_channel=input_channel,
                               input_templates=input_templates,
                               names_input=names_input,
                               output=output,
                               output_types=output_types(),
                               pid=pid,
                               table_conversion=Conversion,
                               table_device_measurements=DeviceMeasurements,
                               table_input=Input,
                               user=user,
                               devices_1wire_ow_shell=devices_1wire_ow_shell,
                               devices_1wire=devices_1wire)
    elif input_type == 'actions':
        return render_template('pages/actions.html',
                               and_=and_,
                               action=action,
                               choices_actions=choices_actions,
                               choices_function=choices_function,
                               choices_input=choices_input,
                               choices_output=choices_output,
                               choices_measurement=choices_measurement,
                               choices_measurements_units=choices_measurements_units,
                               choices_method=choices_method,
                               choices_output_channels=choices_output_channels,
                               choices_output_channels_measurements=choices_output_channels_measurements,
                               choices_pid=choices_pid,
                               choices_pid_devices=choices_pid_devices,
                               choices_unit=choices_unit,
                               custom_commands=custom_commands,
                               custom_options_values_actions=custom_options_values_actions,
                               custom_options_values_inputs=custom_options_values_inputs,
                               custom_options_values_input_channels=custom_options_values_input_channels,
                               dict_actions=dict_actions,
                               dict_inputs=dict_inputs,
                               dict_measurements=dict_measurements,
                               dict_units=dict_units,
                               display_order_input=display_order_input,
                               each_action=each_action,
                               each_input=each_input,
                               form_actions=form_actions,
                               form_add_input=form_add_input,
                               form_mod_input=form_mod_input,
                               ftdi_devices=ftdi_devices,
                               input_channel=input_channel,
                               input_templates=input_templates,
                               names_input=names_input,
                               output=output,
                               output_types=output_types(),
                               pid=pid,
                               table_conversion=Conversion,
                               table_device_measurements=DeviceMeasurements,
                               table_input=Input,
                               user=user,
                               devices_1wire_ow_shell=devices_1wire_ow_shell,
                               devices_1wire=devices_1wire)
Beispiel #10
0
def page_input():
    """ Display Data page options """
    input_type = request.args.get('input_type', None)
    input_id = request.args.get('input_id', None)
    each_input = None
    if input_type in ['entry', 'options']:
        each_input = Input.query.filter(Input.unique_id == input_id).first()

    function = CustomController.query.all()
    input_dev = Input.query.all()
    input_channel = InputChannel.query.all()
    math = Math.query.all()
    method = Method.query.all()
    measurement = Measurement.query.all()
    output = Output.query.all()
    output_channel = OutputChannel.query.all()
    pid = PID.query.all()
    user = User.query.all()
    unit = Unit.query.all()

    display_order_input = csv_to_list_of_str(DisplayOrder.query.first().inputs)
    display_order_math = csv_to_list_of_str(DisplayOrder.query.first().math)

    form_add_input = forms_input.InputAdd()
    form_mod_input = forms_input.InputMod()

    form_mod_math = forms_math.MathMod()
    form_mod_math_measurement = forms_math.MathMeasurementMod()
    form_mod_average_single = forms_math.MathModAverageSingle()
    form_mod_sum_single = forms_math.MathModSumSingle()
    form_mod_redundancy = forms_math.MathModRedundancy()
    form_mod_difference = forms_math.MathModDifference()
    form_mod_equation = forms_math.MathModEquation()
    form_mod_humidity = forms_math.MathModHumidity()
    form_mod_verification = forms_math.MathModVerification()
    form_mod_misc = forms_math.MathModMisc()

    dict_inputs = parse_input_information()

    if request.method == 'POST':  # TODO: Remove entire POST section and remove Math controllers
        if not utils_general.user_has_permission('edit_controllers'):
            return redirect(url_for('routes_input.page_input'))

        # Mod Math Measurement
        if form_mod_math_measurement.math_measurement_mod.data:
            utils_math.math_measurement_mod(form_mod_math_measurement)

        # Mod other Math settings
        elif form_mod_math.math_mod.data:
            math_type = Math.query.filter(
                Math.unique_id == form_mod_math.math_id.data).first().math_type
            if math_type == 'humidity':
                utils_math.math_mod(form_mod_math, form_mod_humidity)
            elif math_type == 'average_single':
                utils_math.math_mod(form_mod_math, form_mod_average_single)
            elif math_type == 'sum_single':
                utils_math.math_mod(form_mod_math, form_mod_sum_single)
            elif math_type == 'redundancy':
                utils_math.math_mod(form_mod_math, form_mod_redundancy)
            elif math_type == 'difference':
                utils_math.math_mod(form_mod_math, form_mod_difference)
            elif math_type == 'equation':
                utils_math.math_mod(form_mod_math, form_mod_equation)
            elif math_type == 'verification':
                utils_math.math_mod(form_mod_math, form_mod_verification)
            elif math_type == 'vapor_pressure_deficit':
                utils_math.math_mod(form_mod_math, form_mod_misc)
            else:
                utils_math.math_mod(form_mod_math)
        elif form_mod_math.math_delete.data:
            utils_math.math_del(form_mod_math)
        elif form_mod_math.math_order_up.data:
            utils_math.math_reorder(form_mod_math.math_id.data,
                                    display_order_math, 'up')
        elif form_mod_math.math_order_down.data:
            utils_math.math_reorder(form_mod_math.math_id.data,
                                    display_order_math, 'down')
        elif form_mod_math.math_activate.data:
            utils_math.math_activate(form_mod_math)
        elif form_mod_math.math_deactivate.data:
            utils_math.math_deactivate(form_mod_math)

        return redirect(url_for('routes_input.page_input'))

    custom_options_values_inputs = parse_custom_option_values(
        input_dev, dict_controller=dict_inputs)
    custom_options_values_input_channels = parse_custom_option_values_input_channels_json(
        input_channel,
        dict_controller=dict_inputs,
        key_name='custom_channel_options')

    custom_actions = {}
    for each_input in input_dev:
        if 'custom_actions' in dict_inputs[each_input.device]:
            custom_actions[each_input.device] = True

    # Generate dict that incorporate user-added measurements/units
    dict_outputs = parse_output_information()
    dict_units = add_custom_units(unit)
    dict_measurements = add_custom_measurements(measurement)

    # Create list of choices to be used in dropdown menus
    choices_function = utils_general.choices_functions(function, dict_units,
                                                       dict_measurements)
    choices_input = utils_general.choices_inputs(input_dev, dict_units,
                                                 dict_measurements)
    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_pid_devices = utils_general.choices_pids_devices(pid)
    choices_unit = utils_general.choices_units(unit)
    choices_measurement = utils_general.choices_measurements(measurement)
    choices_measurements_units = utils_general.choices_measurements_units(
        measurement, unit)

    # Create dict of Input names
    names_input = {}
    all_elements = input_dev
    for each_element in all_elements:
        names_input[
            each_element.unique_id] = '[{id:02d}] ({uid}) {name}'.format(
                id=each_element.id,
                uid=each_element.unique_id.split('-')[0],
                name=each_element.name)

    # Create dict of Math names
    names_math = {}
    all_elements = math
    for each_element in all_elements:
        names_math[
            each_element.unique_id] = '[{id:02d}] ({uid}) {name}'.format(
                id=each_element.id,
                uid=each_element.unique_id.split('-')[0],
                name=each_element.name)

    # Create list of file names from the math_options directory
    # Used in generating the correct options for each math controller
    math_templates = []
    math_path = os.path.join(
        INSTALL_DIRECTORY,
        'mycodo/mycodo_flask/templates/pages/data_options/math_options')
    for (_, _, file_names) in os.walk(math_path):
        math_templates.extend(file_names)
        break

    # Create list of file names from the input_options directory
    # Used in generating the correct options for each input controller
    input_templates = []
    input_path = os.path.join(
        INSTALL_DIRECTORY,
        'mycodo/mycodo_flask/templates/pages/data_options/input_options')
    for (_, _, file_names) in os.walk(input_path):
        input_templates.extend(file_names)
        break

    # If DS18B20 inputs added, compile a list of detected inputs
    devices_1wire_w1thermsensor = []
    if os.path.isdir(PATH_1WIRE):
        for each_name in os.listdir(PATH_1WIRE):
            if 'bus' not in each_name and '-' in each_name:
                devices_1wire_w1thermsensor.append({
                    'name':
                    each_name,
                    'value':
                    each_name.split('-')[1]
                })

    # Add 1-wire devices from ow-shell (if installed)
    devices_1wire_ow_shell = []
    if current_app.config['TESTING']:
        logger.debug("Testing: Skipping testing for 'ow-shell'")
    elif not dpkg_package_exists('ow-shell'):
        logger.debug("Package 'ow-shell' not found")
    else:
        logger.debug("Package 'ow-shell' found")
        try:
            test_cmd = subprocess.check_output(['owdir']).splitlines()
            for each_ow in test_cmd:
                str_ow = re.sub("\ |\/|\'", "",
                                each_ow.decode("utf-8"))  # Strip / and '
                if '.' in str_ow and len(str_ow) == 15:
                    devices_1wire_ow_shell.append(str_ow)
        except Exception:
            logger.error("Error finding 1-wire devices with 'owdir'")

    # Find FTDI devices
    ftdi_devices = []
    if not current_app.config['TESTING']:
        for each_input in input_dev:
            if each_input.interface == "FTDI":
                from mycodo.devices.atlas_scientific_ftdi import get_ftdi_device_list
                ftdi_devices = get_ftdi_device_list()
                break

    if not input_type:
        return render_template(
            'pages/input.html',
            and_=and_,
            choices_function=choices_function,
            choices_input=choices_input,
            choices_math=choices_math,
            choices_output=choices_output,
            choices_measurement=choices_measurement,
            choices_measurements_units=choices_measurements_units,
            choices_method=choices_method,
            choices_output_channels=choices_output_channels,
            choices_output_channels_measurements=
            choices_output_channels_measurements,
            choices_pid=choices_pid,
            choices_pid_devices=choices_pid_devices,
            choices_unit=choices_unit,
            custom_actions=custom_actions,
            custom_options_values_inputs=custom_options_values_inputs,
            custom_options_values_input_channels=
            custom_options_values_input_channels,
            dict_inputs=dict_inputs,
            dict_measurements=dict_measurements,
            dict_units=dict_units,
            display_order_input=display_order_input,
            display_order_math=display_order_math,
            form_add_input=form_add_input,
            form_mod_input=form_mod_input,
            form_mod_average_single=form_mod_average_single,
            form_mod_sum_single=form_mod_sum_single,
            form_mod_redundancy=form_mod_redundancy,
            form_mod_difference=form_mod_difference,
            form_mod_equation=form_mod_equation,
            form_mod_humidity=form_mod_humidity,
            form_mod_math=form_mod_math,
            form_mod_math_measurement=form_mod_math_measurement,
            form_mod_verification=form_mod_verification,
            form_mod_misc=form_mod_misc,
            ftdi_devices=ftdi_devices,
            input_channel=input_channel,
            input_templates=input_templates,
            math_info=MATH_INFO,
            math_templates=math_templates,
            names_input=names_input,
            names_math=names_math,
            output=output,
            output_types=output_types(),
            pid=pid,
            table_conversion=Conversion,
            table_device_measurements=DeviceMeasurements,
            table_input=Input,
            table_math=Math,
            user=user,
            devices_1wire_ow_shell=devices_1wire_ow_shell,
            devices_1wire_w1thermsensor=devices_1wire_w1thermsensor)
    elif input_type == 'entry':
        return render_template(
            'pages/data_options/input_entry.html',
            and_=and_,
            choices_function=choices_function,
            choices_input=choices_input,
            choices_math=choices_math,
            choices_output=choices_output,
            choices_measurement=choices_measurement,
            choices_measurements_units=choices_measurements_units,
            choices_method=choices_method,
            choices_output_channels=choices_output_channels,
            choices_output_channels_measurements=
            choices_output_channels_measurements,
            choices_pid=choices_pid,
            choices_pid_devices=choices_pid_devices,
            choices_unit=choices_unit,
            custom_actions=custom_actions,
            custom_options_values_inputs=custom_options_values_inputs,
            custom_options_values_input_channels=
            custom_options_values_input_channels,
            dict_inputs=dict_inputs,
            dict_measurements=dict_measurements,
            dict_units=dict_units,
            display_order_input=display_order_input,
            display_order_math=display_order_math,
            each_input=each_input,
            form_add_input=form_add_input,
            form_mod_input=form_mod_input,
            form_mod_average_single=form_mod_average_single,
            form_mod_sum_single=form_mod_sum_single,
            form_mod_redundancy=form_mod_redundancy,
            form_mod_difference=form_mod_difference,
            form_mod_equation=form_mod_equation,
            form_mod_humidity=form_mod_humidity,
            form_mod_math=form_mod_math,
            form_mod_math_measurement=form_mod_math_measurement,
            form_mod_verification=form_mod_verification,
            form_mod_misc=form_mod_misc,
            ftdi_devices=ftdi_devices,
            input_channel=input_channel,
            input_templates=input_templates,
            math_info=MATH_INFO,
            math_templates=math_templates,
            names_input=names_input,
            names_math=names_math,
            output=output,
            output_types=output_types(),
            pid=pid,
            table_conversion=Conversion,
            table_device_measurements=DeviceMeasurements,
            table_input=Input,
            table_math=Math,
            user=user,
            devices_1wire_ow_shell=devices_1wire_ow_shell,
            devices_1wire_w1thermsensor=devices_1wire_w1thermsensor)
    elif input_type == 'options':
        return render_template(
            'pages/data_options/input_options.html',
            and_=and_,
            choices_function=choices_function,
            choices_input=choices_input,
            choices_math=choices_math,
            choices_output=choices_output,
            choices_measurement=choices_measurement,
            choices_measurements_units=choices_measurements_units,
            choices_method=choices_method,
            choices_output_channels=choices_output_channels,
            choices_output_channels_measurements=
            choices_output_channels_measurements,
            choices_pid=choices_pid,
            choices_pid_devices=choices_pid_devices,
            choices_unit=choices_unit,
            custom_actions=custom_actions,
            custom_options_values_inputs=custom_options_values_inputs,
            custom_options_values_input_channels=
            custom_options_values_input_channels,
            dict_inputs=dict_inputs,
            dict_measurements=dict_measurements,
            dict_units=dict_units,
            display_order_input=display_order_input,
            display_order_math=display_order_math,
            each_input=each_input,
            form_add_input=form_add_input,
            form_mod_input=form_mod_input,
            form_mod_average_single=form_mod_average_single,
            form_mod_sum_single=form_mod_sum_single,
            form_mod_redundancy=form_mod_redundancy,
            form_mod_difference=form_mod_difference,
            form_mod_equation=form_mod_equation,
            form_mod_humidity=form_mod_humidity,
            form_mod_math=form_mod_math,
            form_mod_math_measurement=form_mod_math_measurement,
            form_mod_verification=form_mod_verification,
            form_mod_misc=form_mod_misc,
            ftdi_devices=ftdi_devices,
            input_channel=input_channel,
            input_templates=input_templates,
            math_info=MATH_INFO,
            math_templates=math_templates,
            names_input=names_input,
            names_math=names_math,
            output=output,
            output_types=output_types(),
            pid=pid,
            table_conversion=Conversion,
            table_device_measurements=DeviceMeasurements,
            table_input=Input,
            table_math=Math,
            user=user,
            devices_1wire_ow_shell=devices_1wire_ow_shell,
            devices_1wire_w1thermsensor=devices_1wire_w1thermsensor)
Beispiel #11
0
def method_builder(method_id):
    """
    Page to edit the details of each method
    This includes the (time, setpoint) data sets
    """
    if not utils_general.user_has_permission('edit_controllers'):
        return redirect(url_for('routes_method.method_list'))

    form_create_method = forms_method.MethodCreate()
    form_add_method = forms_method.MethodAdd()
    form_mod_method = forms_method.MethodMod()

    form_fail = None

    # Used in software tests to verify function is executing as admin
    if method_id == '-1':
        return 'admin logged in'

    # Create new method
    elif method_id == '0':
        form_fail = utils_method.method_create(form_create_method)
        new_method = Method.query.order_by(Method.id.desc()).first()
        if not form_fail:
            return redirect('/method-build/{method_id}'.format(
                method_id=new_method.unique_id))
        else:
            return redirect('/method')
    elif not method_id:
        flash("Invalid method ID", "error")
        return redirect('/method')

    # First method column with general information about method
    method = Method.query.filter(Method.unique_id == method_id).first()

    if method.method_type == 'Cascade':
        method_data = MethodData.query.filter(
            MethodData.method_id == method.unique_id)

        cascade_method = Method.query.filter(
            Method.unique_id != method_id).all()

        if request.method == 'POST':
            form_name = request.form['form-name']
            if form_name == 'addMethod':
                form_fail = utils_method.method_add(form_add_method)
            elif form_name in ['modMethod', 'renameMethod']:
                form_fail = utils_method.method_mod(form_mod_method)
            if (form_name in ['addMethod', 'modMethod', 'renameMethod']
                    and not form_fail):
                return redirect('/method-build/{method_id}'.format(
                    method_id=method.unique_id))

        if not method_data:
            method_data = []

        return render_template('pages/method-build.html',
                               method=method,
                               method_data=method_data,
                               method_id=method_id,
                               output_types=output_types(),
                               cascade_method=cascade_method,
                               form_create_method=form_create_method,
                               form_add_method=form_add_method,
                               form_mod_method=form_mod_method)

    if method.method_type in [
            'Date', 'Duration', 'Daily', 'DailySine', 'DailyBezier'
    ]:

        # Retrieve the order to display method data lines
        display_order = csv_to_list_of_str(method.method_order)

        method_data = MethodData.query.filter(
            MethodData.method_id == method.unique_id)
        setpoint_method_data = MethodData.query.filter(
            MethodData.setpoint_start.isnot(None))
        sine_method_data = MethodData.query.filter(
            MethodData.amplitude.isnot(None))
        bezier_method_data = MethodData.query.filter(MethodData.x0.isnot(None))
        if display_order:
            last_setpoint_method = setpoint_method_data.filter(
                MethodData.unique_id == display_order[-1]).first()
            last_sine_method = sine_method_data.filter(
                MethodData.unique_id == display_order[-1]).first()
            last_bezier_method = bezier_method_data.filter(
                MethodData.unique_id == display_order[-1]).first()
        else:
            last_setpoint_method = None
            last_sine_method = None
            last_bezier_method = None

        last_end_time = ''
        last_setpoint = ''
        if method.method_type in ['Daily', 'Date', 'Duration']:
            method_data = method_data.all()

            # Get last entry end time and setpoint to populate the form
            if last_setpoint_method is None:
                last_end_time = ''
                last_setpoint = ''
            else:
                last_end_time = last_setpoint_method.time_end
                if last_setpoint_method.setpoint_end is not None:
                    last_setpoint = last_setpoint_method.setpoint_end
                else:
                    last_setpoint = last_setpoint_method.setpoint_start

        if request.method == 'POST':
            form_name = request.form['form-name']
            if form_name == 'addMethod':
                form_fail = utils_method.method_add(form_add_method)
            elif form_name in ['modMethod', 'renameMethod']:
                form_fail = utils_method.method_mod(form_mod_method)
            if (form_name in ['addMethod', 'modMethod', 'renameMethod']
                    and not form_fail):
                return redirect('/method-build/{method_id}'.format(
                    method_id=method.unique_id))

        if not method_data:
            method_data = []

        return render_template('pages/method-build.html',
                               method=method,
                               method_data=method_data,
                               method_id=method_id,
                               last_end_time=last_end_time,
                               last_bezier_method=last_bezier_method,
                               last_sine_method=last_sine_method,
                               last_setpoint_method=last_setpoint_method,
                               last_setpoint=last_setpoint,
                               output_types=output_types(),
                               form_create_method=form_create_method,
                               form_add_method=form_add_method,
                               form_mod_method=form_mod_method)

    return redirect('/method')
Beispiel #12
0
def page_dashboard(dashboard_id):
    """ Generate custom dashboard with various data """
    # Retrieve tables from SQL database
    camera = Camera.query.all()
    conditional = Conditional.query.all()
    function = CustomController.query.all()
    widget = Widget.query.all()
    this_dashboard = Dashboard.query.filter(
        Dashboard.unique_id == dashboard_id).first()
    input_dev = Input.query.all()
    device_measurements = DeviceMeasurements.query.all()
    math = Math.query.all()
    method = Method.query.all()
    misc = Misc.query.first()
    output = Output.query.all()
    output_channel = OutputChannel.query.all()
    pid = PID.query.all()
    tags = NoteTags.query.all()

    # Create form objects
    form_base = forms_dashboard.DashboardBase()
    form_dashboard = forms_dashboard.DashboardConfig()

    if request.method == 'POST':
        unmet_dependencies = None
        if not utils_general.user_has_permission('edit_controllers'):
            return redirect(url_for('routes_general.home'))

        # Dashboard
        if form_dashboard.dash_modify.data:
            utils_dashboard.dashboard_mod(form_dashboard)
        elif form_dashboard.dash_duplicate.data:
            utils_dashboard.dashboard_copy(form_dashboard)
        elif form_dashboard.lock.data:
            utils_dashboard.dashboard_lock(form_dashboard.dashboard_id.data,
                                           True)
        elif form_dashboard.unlock.data:
            utils_dashboard.dashboard_lock(form_dashboard.dashboard_id.data,
                                           False)
        elif form_dashboard.dash_delete.data:
            utils_dashboard.dashboard_del(form_dashboard)
            return redirect(url_for('routes_dashboard.page_dashboard_default'))

        # Widget
        elif form_base.create.data:
            unmet_dependencies = utils_dashboard.widget_add(
                form_base, request.form)
        elif form_base.modify.data:
            utils_dashboard.widget_mod(form_base, request.form)
        elif form_base.delete.data:
            utils_dashboard.widget_del(form_base)

        if unmet_dependencies:
            return redirect(
                url_for('routes_admin.admin_dependencies',
                        device=form_base.graph_type.data))

        return redirect(
            url_for('routes_dashboard.page_dashboard',
                    dashboard_id=dashboard_id))

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

    # Generate dictionary of each measurement ID with the correct measurement/unit used with it
    dict_measure_measurements = {}
    dict_measure_units = {}

    for each_measurement in device_measurements:
        # If the measurement is a PID setpoint, set unit to PID measurement.
        measurement = None
        unit = None
        if each_measurement.measurement_type == 'setpoint':
            setpoint_pid = PID.query.filter(
                PID.unique_id == each_measurement.device_id).first()
            if setpoint_pid and ',' in setpoint_pid.measurement:
                pid_measurement = setpoint_pid.measurement.split(',')[1]
                setpoint_measurement = DeviceMeasurements.query.filter(
                    DeviceMeasurements.unique_id == pid_measurement).first()
                if setpoint_measurement:
                    conversion = Conversion.query.filter(
                        Conversion.unique_id ==
                        setpoint_measurement.conversion_id).first()
                    _, unit, measurement = return_measurement_info(
                        setpoint_measurement, conversion)
        else:
            conversion = Conversion.query.filter(
                Conversion.unique_id ==
                each_measurement.conversion_id).first()
            _, unit, measurement = return_measurement_info(
                each_measurement, conversion)
        if unit:
            dict_measure_measurements[each_measurement.unique_id] = measurement
            dict_measure_units[each_measurement.unique_id] = unit

    dict_outputs = parse_output_information()
    dict_widgets = parse_widget_information()

    custom_options_values_widgets = parse_custom_option_values_json(
        widget, dict_controller=dict_widgets)

    custom_options_values_output_channels = parse_custom_option_values_output_channels_json(
        output_channel,
        dict_controller=dict_outputs,
        key_name='custom_channel_options')

    widget_types_on_dashboard = []
    custom_widget_variables = {}
    widgets_dash = Widget.query.filter(
        Widget.dashboard_id == dashboard_id).all()
    for each_widget in widgets_dash:
        # Make list of widget types on this particular dashboard
        if each_widget.graph_type not in widget_types_on_dashboard:
            widget_types_on_dashboard.append(each_widget.graph_type)

        # Generate dictionary of returned values from widget modules on this particular dashboard
        if 'generate_page_variables' in dict_widgets[each_widget.graph_type]:
            custom_widget_variables[each_widget.unique_id] = dict_widgets[
                each_widget.graph_type]['generate_page_variables'](
                    each_widget.unique_id,
                    custom_options_values_widgets[each_widget.unique_id])

    # generate lists of html files to include in dashboard template
    list_html_files_body = {}
    list_html_files_title_bar = {}
    list_html_files_head = {}
    list_html_files_configure_options = {}
    list_html_files_js = {}
    list_html_files_js_ready = {}
    list_html_files_js_ready_end = {}

    for each_widget_type in widget_types_on_dashboard:
        file_html_head = "widget_template_{}_head.html".format(
            each_widget_type)
        path_html_head = os.path.join(PATH_HTML_USER, file_html_head)
        if os.path.exists(path_html_head):
            list_html_files_head[each_widget_type] = file_html_head

        file_html_title_bar = "widget_template_{}_title_bar.html".format(
            each_widget_type)
        path_html_title_bar = os.path.join(PATH_HTML_USER, file_html_title_bar)
        if os.path.exists(path_html_title_bar):
            list_html_files_title_bar[each_widget_type] = file_html_title_bar

        file_html_body = "widget_template_{}_body.html".format(
            each_widget_type)
        path_html_body = os.path.join(PATH_HTML_USER, file_html_body)
        if os.path.exists(path_html_body):
            list_html_files_body[each_widget_type] = file_html_body

        file_html_configure_options = "widget_template_{}_configure_options.html".format(
            each_widget_type)
        path_html_configure_options = os.path.join(
            PATH_HTML_USER, file_html_configure_options)
        if os.path.exists(path_html_configure_options):
            list_html_files_configure_options[
                each_widget_type] = file_html_configure_options

        file_html_js = "widget_template_{}_js.html".format(each_widget_type)
        path_html_js = os.path.join(PATH_HTML_USER, file_html_js)
        if os.path.exists(path_html_js):
            list_html_files_js[each_widget_type] = file_html_js

        file_html_js_ready = "widget_template_{}_js_ready.html".format(
            each_widget_type)
        path_html_js_ready = os.path.join(PATH_HTML_USER, file_html_js_ready)
        if os.path.exists(path_html_js_ready):
            list_html_files_js_ready[each_widget_type] = file_html_js_ready

        file_html_js_ready_end = "widget_template_{}_js_ready_end.html".format(
            each_widget_type)
        path_html_js_ready_end = os.path.join(PATH_HTML_USER,
                                              file_html_js_ready_end)
        if os.path.exists(path_html_js_ready_end):
            list_html_files_js_ready_end[
                each_widget_type] = file_html_js_ready_end

    # Retrieve all choices to populate form drop-down menu
    choices_camera = utils_general.choices_id_name(camera)
    choices_function = utils_general.choices_functions(function, dict_units,
                                                       dict_measurements)
    choices_input = utils_general.choices_inputs(input_dev, dict_units,
                                                 dict_measurements)
    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_measurements = utils_general.choices_outputs_channels_measurements(
        output, OutputChannel, dict_outputs, dict_units, dict_measurements)
    choices_output_pwm = utils_general.choices_outputs_pwm(
        output, dict_units, dict_measurements, dict_outputs)
    choices_pid = utils_general.choices_pids(pid, dict_units,
                                             dict_measurements)
    choices_pid_devices = utils_general.choices_pids_devices(pid)
    choices_tag = utils_general.choices_tags(tags)

    device_measurements_dict = {}
    for meas in device_measurements:
        device_measurements_dict[meas.unique_id] = meas

    # Get what each measurement uses for a unit
    use_unit = utils_general.use_unit_generate(device_measurements, input_dev,
                                               output, math, function)

    return render_template(
        'pages/dashboard.html',
        conditional=conditional,
        custom_options_values_output_channels=
        custom_options_values_output_channels,
        custom_options_values_widgets=custom_options_values_widgets,
        custom_widget_variables=custom_widget_variables,
        table_conversion=Conversion,
        table_function=CustomController,
        table_widget=Widget,
        table_input=Input,
        table_math=Math,
        table_output=Output,
        table_pid=PID,
        table_device_measurements=DeviceMeasurements,
        choices_camera=choices_camera,
        choices_function=choices_function,
        choices_input=choices_input,
        choices_math=choices_math,
        choices_method=choices_method,
        choices_output=choices_output,
        choices_output_channels_measurements=
        choices_output_channels_measurements,
        choices_output_pwm=choices_output_pwm,
        choices_pid=choices_pid,
        choices_pid_devices=choices_pid_devices,
        choices_tag=choices_tag,
        dashboard_id=dashboard_id,
        device_measurements_dict=device_measurements_dict,
        dict_measure_measurements=dict_measure_measurements,
        dict_measure_units=dict_measure_units,
        dict_measurements=dict_measurements,
        dict_units=dict_units,
        dict_widgets=dict_widgets,
        list_html_files_head=list_html_files_head,
        list_html_files_title_bar=list_html_files_title_bar,
        list_html_files_body=list_html_files_body,
        list_html_files_configure_options=list_html_files_configure_options,
        list_html_files_js=list_html_files_js,
        list_html_files_js_ready=list_html_files_js_ready,
        list_html_files_js_ready_end=list_html_files_js_ready_end,
        camera=camera,
        function=function,
        math=math,
        misc=misc,
        pid=pid,
        output=output,
        output_types=output_types(),
        input=input_dev,
        tags=tags,
        this_dashboard=this_dashboard,
        use_unit=use_unit,
        form_base=form_base,
        form_dashboard=form_dashboard,
        widget=widget)