Example #1
0
    def setup_lcd_line(self, display_id, line, device_id, measurement):
        self.lcd_line[display_id][line]['setup'] = False
        self.lcd_line[display_id][line]['id'] = device_id
        self.lcd_line[display_id][line]['name'] = None
        self.lcd_line[display_id][line]['unit'] = None
        self.lcd_line[display_id][line]['measure'] = measurement
        if 'time' in measurement:
            self.lcd_line[display_id][line]['measure'] = 'time'
        if not device_id:
            return

        # Determine the unit
        if measurement == 'setpoint':
            pid = db_retrieve_table_daemon(PID, unique_id=device_id)
            if pid:
                if pid.measurement.split(',')[1] in self.list_inputs:
                    self.lcd_line[display_id][line]['unit'] = self.list_inputs[
                        pid.measurement.split(',')[1]]['unit']
                else:
                    self.lcd_line[display_id][line]['unit'] = ''
        elif measurement in self.list_inputs:
            # Get what each measurement uses for a unit
            input_dev = db_retrieve_table_daemon(Input)
            use_unit = use_unit_generate(input_dev)
            if (device_id in use_unit and measurement in use_unit[device_id]
                    and use_unit[device_id][measurement] is not None):
                self.lcd_line[display_id][line]['unit'] = UNITS[
                    use_unit[device_id][measurement]]['unit']
            else:
                self.lcd_line[display_id][line]['unit'] = self.list_inputs[
                    measurement]['unit']
        else:
            self.lcd_line[display_id][line]['unit'] = ''

        # Determine the name
        controllers = [Output, PID, Input, Math]
        for each_controller in controllers:
            controller_found = db_retrieve_table_daemon(each_controller,
                                                        unique_id=device_id)
            if controller_found:
                self.lcd_line[display_id][line]['name'] = controller_found.name

        if (self.lcd_line[display_id][line]['measure'] == 'time'
                or None not in [
                    self.lcd_line[display_id][line]['name'],
                    self.lcd_line[display_id][line]['unit']
                ]):
            self.lcd_line[display_id][line]['setup'] = True
Example #2
0
def check_func(all_devices, unique_id, y_axes, measurement, dict_measurements,
               input_dev):
    """
    Generate a list of y-axes for Live and Asynchronous Graphs
    :param all Input, Math, Output, and PID SQL entries of a table
    :param unique_id: The ID of the measurement
    :param y_axes: empty list to populate
    :param measurement:
    :param dict_measurements:
    :param input_dev:
    :return: None
    """
    # Iterate through each device entry
    for each_device in all_devices:

        # If the ID saved to the dashboard element matches the table entry ID
        if each_device.unique_id == unique_id:

            use_unit = use_unit_generate(input_dev)

            # Add duration_sec
            if measurement == 'duration_sec':
                if 'duration_sec' not in y_axes:
                    y_axes.append('duration_sec')

            # Use Linux Command measurement
            elif (all_devices == input_dev and each_device.cmd_measurement
                  and each_device.cmd_measurement != ''
                  and each_device.cmd_measurement == measurement
                  and each_device.cmd_measurement not in y_axes):
                y_axes.append(each_device.cmd_measurement)

            # Use custom-converted units
            elif (unique_id in use_unit and measurement in use_unit[unique_id]
                  and use_unit[unique_id][measurement]):
                measure_short = use_unit[unique_id][measurement]
                if measure_short not in y_axes:
                    y_axes.append(measure_short)

            # Find the y-axis the setpoint or bands apply to
            elif measurement in [
                    'setpoint', 'setpoint_band_min', 'setpoint_band_max'
            ]:
                for each_input in input_dev:
                    if each_input.unique_id == each_device.measurement.split(
                            ',')[0]:
                        pid_measurement = each_device.measurement.split(',')[1]

                        # If PID uses input with custom conversion, use custom unit
                        if (each_input.unique_id in use_unit
                                and pid_measurement
                                in use_unit[each_input.unique_id] and use_unit[
                                    each_input.unique_id][pid_measurement]):
                            measure_short = use_unit[
                                each_input.unique_id][pid_measurement]
                            if measure_short not in y_axes:
                                y_axes.append(measure_short)
                        # Else use default unit for input measurement
                        else:
                            if pid_measurement in dict_measurements:
                                measure_short = dict_measurements[
                                    pid_measurement]['meas']
                                if measure_short not in y_axes:
                                    y_axes.append(measure_short)

            # Append all other measurements if they don't already exist
            elif measurement in dict_measurements:
                measure_short = dict_measurements[measurement]['meas']
                if measure_short not in y_axes:
                    y_axes.append(measure_short)

    return y_axes
Example #3
0
def check_func(all_devices,
               unique_id,
               y_axes,
               measurement,
               dict_measurements,
               device_measurements,
               input_dev,
               output,
               math,
               function,
               unit=None):
    """
    Generate a list of y-axes for Live and Asynchronous Graphs
    :param all_devices: Input, Math, Output, and PID SQL entries of a table
    :param unique_id: The ID of the measurement
    :param y_axes: empty list to populate
    :param measurement:
    :param dict_measurements:
    :param device_measurements:
    :param input_dev:
    :param output:
    :param math:
    :param function
    :param unit:
    :return: None
    """
    # Iterate through each device entry
    for each_device in all_devices:

        # If the ID saved to the dashboard element matches the table entry ID
        if each_device.unique_id == unique_id:

            use_unit = use_unit_generate(
                device_measurements, input_dev, output, math, function)

            # Add duration
            if measurement == 'duration_time':
                if 'second' not in y_axes:
                    y_axes.append('second')

            # Add duty cycle
            elif measurement == 'duty_cycle':
                if 'percent' not in y_axes:
                    y_axes.append('percent')

            # Use custom-converted units
            elif (unique_id in use_unit and
                    measurement in use_unit[unique_id] and
                    use_unit[unique_id][measurement]):
                measure_short = use_unit[unique_id][measurement]
                if measure_short not in y_axes:
                    y_axes.append(measure_short)

            # Find the y-axis the setpoint or bands apply to
            elif measurement in ['setpoint', 'setpoint_band_min', 'setpoint_band_max']:
                for each_input in input_dev:
                    if each_input.unique_id == each_device.measurement.split(',')[0]:
                        pid_measurement = each_device.measurement.split(',')[1]

                        # If PID uses input with custom conversion, use custom unit
                        if (each_input.unique_id in use_unit and
                                pid_measurement in use_unit[each_input.unique_id] and
                                use_unit[each_input.unique_id][pid_measurement]):
                            measure_short = use_unit[each_input.unique_id][pid_measurement]
                            if measure_short not in y_axes:
                                y_axes.append(measure_short)
                        # Else use default unit for input measurement
                        else:
                            if pid_measurement in dict_measurements:
                                measure_short = dict_measurements[pid_measurement]['meas']
                                if measure_short not in y_axes:
                                    y_axes.append(measure_short)

            # Append all other measurements if they don't already exist
            elif measurement in dict_measurements and not unit:
                measure_short = dict_measurements[measurement]['meas']
                if measure_short not in y_axes:
                    y_axes.append(measure_short)

            # use custom y-axis
            elif measurement not in dict_measurements or unit not in dict_measurements[measurement]['units']:
                meas_name = '{meas}_{un}'.format(meas=measurement, un=unit)
                if meas_name not in y_axes and unit:
                    y_axes.append(meas_name)

    return y_axes
Example #4
0
def check_func(all_devices,
               unique_id,
               y_axes,
               measurement,
               dict_measurements,
               device_measurements,
               input_dev,
               output,
               math,
               unit=None):
    """
    Generate a list of y-axes for Live and Asynchronous Graphs
    :param all_devices: Input, Math, Output, and PID SQL entries of a table
    :param unique_id: The ID of the measurement
    :param y_axes: empty list to populate
    :param measurement:
    :param dict_measurements:
    :param device_measurements:
    :param input_dev:
    :param output:
    :param math:
    :param unit:
    :return: None
    """
    # Iterate through each device entry
    for each_device in all_devices:

        # If the ID saved to the dashboard element matches the table entry ID
        if each_device.unique_id == unique_id:

            use_unit = use_unit_generate(
                device_measurements, input_dev, output, math)

            # Add duration
            if measurement == 'duration_time':
                if 'second' not in y_axes:
                    y_axes.append('second')

            # Add duty cycle
            elif measurement == 'duty_cycle':
                if 'percent' not in y_axes:
                    y_axes.append('percent')

            # Use custom-converted units
            elif (unique_id in use_unit and
                    measurement in use_unit[unique_id] and
                    use_unit[unique_id][measurement]):
                measure_short = use_unit[unique_id][measurement]
                if measure_short not in y_axes:
                    y_axes.append(measure_short)

            # Find the y-axis the setpoint or bands apply to
            elif measurement in ['setpoint', 'setpoint_band_min', 'setpoint_band_max']:
                for each_input in input_dev:
                    if each_input.unique_id == each_device.measurement.split(',')[0]:
                        pid_measurement = each_device.measurement.split(',')[1]

                        # If PID uses input with custom conversion, use custom unit
                        if (each_input.unique_id in use_unit and
                                pid_measurement in use_unit[each_input.unique_id] and
                                use_unit[each_input.unique_id][pid_measurement]):
                            measure_short = use_unit[each_input.unique_id][pid_measurement]
                            if measure_short not in y_axes:
                                y_axes.append(measure_short)
                        # Else use default unit for input measurement
                        else:
                            if pid_measurement in dict_measurements:
                                measure_short = dict_measurements[pid_measurement]['meas']
                                if measure_short not in y_axes:
                                    y_axes.append(measure_short)

            # Append all other measurements if they don't already exist
            elif measurement in dict_measurements and not unit:
                measure_short = dict_measurements[measurement]['meas']
                if measure_short not in y_axes:
                    y_axes.append(measure_short)

            # use custom y-axis
            elif measurement not in dict_measurements or unit not in dict_measurements[measurement]['units']:
                meas_name = '{meas}_{un}'.format(meas=measurement, un=unit)
                if meas_name not in y_axes and unit:
                    y_axes.append(meas_name)

    return y_axes
Example #5
0
def add_custom_measurements(inputs, maths, measurement_units):
    """
    Returns the measurement dictionary appended with
    input, ADC, and command measurements/units
    """
    return_measurements = measurement_units

    use_unit = use_unit_generate(inputs)

    for each_input in inputs:
        # Add command measurements/units to measurements dictionary
        if (each_input.cmd_measurement and each_input.cmd_measurement_units
                and each_input.cmd_measurement not in measurement_units):
            return_measurements.update({
                each_input.cmd_measurement: {
                    'meas': each_input.cmd_measurement,
                    'unit': each_input.cmd_measurement_units,
                    'name': each_input.cmd_measurement
                }
            })

        # Add ADC measurements/units to measurements dictionary
        elif (each_input.adc_measure and each_input.adc_measure_units
              and each_input.adc_measure not in measurement_units):
            return_measurements.update({
                each_input.adc_measure: {
                    'meas': each_input.adc_measure,
                    'unit': each_input.adc_measure_units,
                    'name': each_input.adc_measure
                }
            })

        # Add converted measurements/units to measurements dictionary
        elif each_input.unique_id in use_unit:
            for each_measure in use_unit[each_input.unique_id]:
                if (use_unit[each_input.unique_id][each_measure] is not None
                        and use_unit[each_input.unique_id][each_measure]
                        in UNITS):
                    return_measurements.update({
                        use_unit[each_input.unique_id][each_measure]: {
                            'meas':
                            use_unit[each_input.unique_id][each_measure],
                            'unit':
                            UNITS[use_unit[each_input.unique_id]
                                  [each_measure]]['unit'],
                            'name':
                            UNITS[use_unit[each_input.unique_id][each_measure]]
                            ['name']
                        }
                    })

    for each_math in maths:
        # Add Math measurements/units to measurements dictionary
        if (each_math.measure and each_math.measure_units
                and each_math.measure not in measurement_units):
            return_measurements.update({
                each_math.measure: {
                    'meas': each_math.measure,
                    'unit': each_math.measure_units,
                    'name': each_math.measure
                }
            })

    return return_measurements
Example #6
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)
Example #7
0
    def setup_lcd_line(self, display_id, line, device_id, measurement):
        self.lcd_line[display_id][line]['setup'] = False
        self.lcd_line[display_id][line]['id'] = device_id
        self.lcd_line[display_id][line]['name'] = None
        self.lcd_line[display_id][line]['unit'] = None
        self.lcd_line[display_id][line]['measure'] = measurement

        if 'time' in measurement:
            self.lcd_line[display_id][line]['measure'] = 'time'
        if not device_id:
            return

        # Determine the unit of the PID setpoint
        if measurement == 'setpoint':
            pid = db_retrieve_table_daemon(PID, unique_id=device_id)
            if pid:
                if pid.measurement.split(',')[1] in self.list_inputs:
                    # Determine if the PID input is a math or input controller
                    pid_math = db_retrieve_table_daemon(
                        Math, unique_id=pid.measurement.split(',')[0])
                    pid_input = db_retrieve_table_daemon(
                        Input, unique_id=pid.measurement.split(',')[0])

                    list_measure_units = []
                    setpoint_unit = ''
                    if pid_math:
                        list_measure_units = pid_math.measure_units.split(';')
                    if pid_input:
                        list_measure_units = pid_input.convert_to_unit.split(
                            ';')

                    for each_measure_unit in list_measure_units:
                        if (len(each_measure_unit.split(',')) == 2
                                and each_measure_unit.split(',')[0]
                                == pid.measurement.split(',')[1]):
                            setpoint_unit = self.dict_units[
                                each_measure_unit.split(',')[1]]['unit']
                    self.lcd_line[display_id][line]['unit'] = setpoint_unit
                else:
                    self.lcd_line[display_id][line]['unit'] = ''

        elif measurement in self.list_inputs:
            # Get what each measurement uses for a unit
            input_dev = db_retrieve_table_daemon(Input)
            output = db_retrieve_table_daemon(Output)
            math = db_retrieve_table_daemon(Math)
            use_unit = use_unit_generate(input_dev, output, math)
            if (device_id in use_unit and measurement in use_unit[device_id]
                    and use_unit[device_id][measurement] is not None):
                self.lcd_line[display_id][line]['unit'] = UNITS[
                    use_unit[device_id][measurement]]['unit']
            elif 'unit' in self.list_inputs[measurement]:
                self.lcd_line[display_id][line]['unit'] = self.list_inputs[
                    measurement]['unit']
            else:
                self.lcd_line[display_id][line]['unit'] = ''
        else:
            self.lcd_line[display_id][line]['unit'] = ''

        # Determine the name
        controllers = [Output, PID, Input, Math]
        for each_controller in controllers:
            controller_found = db_retrieve_table_daemon(each_controller,
                                                        unique_id=device_id)
            if controller_found:
                self.lcd_line[display_id][line]['name'] = controller_found.name

        if (self.lcd_line[display_id][line]['measure'] in ['IP', 'time']
                or None not in [
                    self.lcd_line[display_id][line]['name'],
                    self.lcd_line[display_id][line]['unit']
                ]):
            self.lcd_line[display_id][line]['setup'] = True