def widget_del(form_base): """Delete a widget from a dashboard""" action = '{action} {controller}'.format( action=TRANSLATIONS['delete']['title'], controller=TRANSLATIONS['widget']['title']) error = [] dict_widgets = parse_widget_information() widget = Widget.query.filter( Widget.unique_id == form_base.widget_id.data).first() try: if 'execute_at_deletion' in dict_widgets[widget.graph_type]: dict_widgets[widget.graph_type]['execute_at_deletion'](form_base.widget_id.data) except Exception as except_msg: error.append(except_msg) try: delete_entry_with_id(Widget, form_base.widget_id.data) control = DaemonControl() control.widget_remove(form_base.widget_id.data) except Exception as except_msg: error.append(except_msg) flash_success_errors( error, action, url_for('routes_page.page_dashboard', dashboard_id=form_base.dashboard_id.data))
class DashboardBase(FlaskForm): choices_widgets = [] dict_widgets = parse_widget_information() list_widgets_sorted = generate_form_widget_list(dict_widgets) choices_widgets.append(('', lazy_gettext('Add Dashboard Widget'))) for each_widget in list_widgets_sorted: choices_widgets.append( (each_widget, dict_widgets[each_widget]['widget_name'])) widget_type = SelectField('Dashboard Widget Type', choices=choices_widgets, validators=[DataRequired()]) dashboard_id = StringField('Dashboard ID', widget=widgets.HiddenInput()) widget_id = StringField('Widget ID', widget=widgets.HiddenInput()) name = StringField(TRANSLATIONS['name']['title'], validators=[DataRequired()]) font_em_name = DecimalField(TRANSLATIONS['font_em_name']['title']) refresh_duration = IntegerField( TRANSLATIONS['refresh_duration']['title'], validators=[ validators.NumberRange( min=1, message=TRANSLATIONS['refresh_duration']['title']) ], widget=NumberInput()) enable_drag_handle = BooleanField(lazy_gettext('Enable Drag Handle')) widget_add = SubmitField(TRANSLATIONS['create']['title']) widget_mod = SubmitField(TRANSLATIONS['save']['title']) widget_delete = SubmitField(TRANSLATIONS['delete']['title'])
def initialize_variables(self): """ Begin initializing widget parameters """ self.dict_widgets = parse_widget_information() self.sample_rate = db_retrieve_table_daemon( Misc, entry='first').sample_rate_controller_widget self.logger.debug("Initializing Widgets") try: widgets = db_retrieve_table_daemon(Widget, entry='all') for each_widget in widgets: if each_widget.graph_type in self.dict_widgets: self.widget_add_refresh(each_widget.unique_id) else: self.logger.debug( "Widget '{device}' not recognized".format( device=each_widget.graph_type)) raise Exception( "'{device}' is not a valid widget type.".format( device=each_widget.graph_type)) self.logger.debug("Widgets Initialized") except Exception as except_msg: self.logger.exception( "Problem initializing widgets: {err}".format(err=except_msg))
def initialize_variables(self): """Begin initializing widget parameters.""" self.dict_widgets = parse_widget_information() self.sample_rate = db_retrieve_table_daemon( Misc, entry='first').sample_rate_controller_widget self.logger.debug("Initializing Widgets") try: widgets = db_retrieve_table_daemon(Widget, entry='all') for each_widget in widgets: if each_widget.graph_type in self.dict_widgets: self.widget_add_refresh(each_widget.unique_id) else: self.logger.error( f"'{each_widget.graph_type}' is not a valid widget type" ) self.logger.debug("Widgets Initialized") except Exception: self.logger.exception("Problem initializing widgets") self.ready.set() self.running = True
def register_widget_endpoints(app=current_app): try: if app.config[ 'TESTING']: # TODO: Add pytest endpoint test and remove this return dict_widgets = parse_widget_information() with session_scope( app.config['SQLALCHEMY_DATABASE_URI']) as new_session: widget = new_session.query(Widget).all() widget_types = [] for each_widget in widget: if each_widget.graph_type not in widget_types: widget_types.append(each_widget.graph_type) for each_widget_type in widget_types: if each_widget_type in dict_widgets and 'endpoints' in dict_widgets[ each_widget_type]: for rule, endpoint, view_func, methods in dict_widgets[ each_widget_type]['endpoints']: if endpoint in app.view_functions: logger.info( "Endpoint {} ({}) already exists. Not adding.". format(endpoint, rule)) else: logger.info("Adding endpoint {} ({}).".format( endpoint, rule)) app.add_url_rule(rule, endpoint, view_func, methods=methods) except: logger.exception("Adding Widget Endpoints")
def get_installed_apt_dependencies(): met_deps = [] list_dependencies = [ parse_function_information(), parse_action_information(), parse_input_information(), parse_output_information(), parse_widget_information(), CAMERA_INFO, FUNCTION_INFO, METHOD_INFO, DEPENDENCIES_GENERAL ] for each_section in list_dependencies: for device_type in each_section: if 'dependencies_module' in each_section[device_type]: dep_mod = each_section[device_type]['dependencies_module'] for (install_type, package, install_id) in dep_mod: if install_type == 'apt': start = "dpkg-query -W -f='${Status}'" end = '2>/dev/null | grep -c "ok installed"' cmd = "{} {} {}".format(start, package, end) _, _, status = cmd_output(cmd, user='******') if not status and install_id not in met_deps: met_deps.append(install_id) return met_deps
def widget_mod(form_base, request_form): """Modify the settings of an item on the dashboard""" action = '{action} {controller}'.format( action=TRANSLATIONS['modify']['title'], controller=TRANSLATIONS['widget']['title']) error = [] dict_widgets = parse_widget_information() mod_widget = Widget.query.filter( Widget.unique_id == form_base.widget_id.data).first() mod_widget.name = form_base.name.data mod_widget.font_em_name = form_base.font_em_name.data mod_widget.enable_drag_handle = form_base.enable_drag_handle.data mod_widget.refresh_duration = form_base.refresh_duration.data try: custom_options_json_presave = json.loads(mod_widget.custom_options) except: logger.error("Malformed JSON") custom_options_json_presave = {} # Generate string to save from custom options error, custom_options_json_postsave = custom_options_return_json( error, dict_widgets, request_form, device=mod_widget.graph_type) if 'execute_at_modification' in dict_widgets[mod_widget.graph_type]: (allow_saving, mod_input, custom_options ) = dict_widgets[mod_widget.graph_type]['execute_at_modification']( mod_widget, request_form, custom_options_json_presave, json.loads(custom_options_json_postsave)) custom_options = json.dumps( custom_options) # Convert from dict to JSON string if not allow_saving: error.append( "execute_at_modification() would not allow widget options to be saved" ) else: custom_options = custom_options_json_postsave mod_widget.custom_options = custom_options if not error: try: db.session.commit() except sqlalchemy.exc.OperationalError as except_msg: error.append(except_msg) except sqlalchemy.exc.IntegrityError as except_msg: error.append(except_msg) control = DaemonControl() control.widget_add_refresh(mod_widget.unique_id) flash_success_errors( error, action, url_for('routes_page.page_dashboard', dashboard_id=form_base.dashboard_id.data))
def widget_add_refresh(self, unique_id): self.dict_widgets = parse_widget_information() widget = db_retrieve_table_daemon(Widget, unique_id=unique_id) if ('no_class' in self.dict_widgets[widget.graph_type] and self.dict_widgets[widget.graph_type]['no_class']): return try: timer = timeit.default_timer() input_loaded = load_module_from_file( self.dict_widgets[widget.graph_type]['file_path'], 'widgets') widget = db_retrieve_table_daemon(Widget, unique_id=unique_id) self.widget_loaded[unique_id] = input_loaded.WidgetModule(widget) self.widget_loaded[unique_id].initialize_variables() self.widget_ready[unique_id] = True self.logger.info( "Widget {id} created/refreshed in {time:.1f} ms".format( id=widget.unique_id.split('-')[0], time=(timeit.default_timer() - timer) * 1000)) except Exception: self.logger.exception("Widget create/refresh")
def test_add_all_widgets_logged_in_as_admin(_, testapp): """Verifies adding all widgets as a logged in admin user.""" print("\nTest: test_add_all_widgets_logged_in_as_admin") login_user(testapp, 'admin', '53CR3t_p4zZW0rD') # Add All Widgets widget_count = 0 dict_widgets = parse_widget_information() list_widgets_sorted = generate_form_widget_list(dict_widgets) choices_widget = [] for each_widget in list_widgets_sorted: choices_widget.append(each_widget) first_dashboard = Dashboard.query.first() if not first_dashboard: print("Error: Could not find a Dashboard, cannot test Widgets.") return for index, each_widget in enumerate(choices_widget): choice_name = each_widget.split(',')[0] print("test_add_all_widget_devices_logged_in_as_admin: Adding, saving, and deleting Widget ({}/{}): {}".format( index + 1, len(choices_widget), each_widget)) add_widget(testapp, dashboard_id=first_dashboard.unique_id, widget_type=each_widget) # Verify data was entered into the database widget_count += 1 assert Widget.query.count() == widget_count, "Number of Widgets doesn't match: In DB {}, Should be: {}".format( Widget.query.count(), widget_count) widget_dev = Widget.query.filter(Widget.id == widget_count).first() assert choice_name == widget_dev.graph_type, "Widget name doesn't match: {}".format(choice_name) # Delete widget (speeds up further widget addition checking) delete_data(testapp, 'widget', device_dev=widget_dev, dashboard_id=first_dashboard.unique_id) widget_count -= 1 assert Widget.query.count() == widget_count, "Number of Widgets doesn't match: In DB {}, Should be: {}".format( Widget.query.count(), widget_count)
def widget_add(form_base, request_form): """Add a widget to the dashboard""" action = '{action} {controller}'.format( action=TRANSLATIONS['add']['title'], controller=TRANSLATIONS['widget']['title']) error = [] dict_widgets = parse_widget_information() if form_base.widget_type.data: widget_name = form_base.widget_type.data else: widget_name = '' error.append("Missing widget name") if current_app.config['TESTING']: dep_unmet = False else: dep_unmet, _ = return_dependencies(widget_name) if dep_unmet: list_unmet_deps = [] for each_dep in dep_unmet: list_unmet_deps.append(each_dep[0]) error.append("The {dev} device you're trying to add has unmet dependencies: {dep}".format( dev=widget_name, dep=', '.join(list_unmet_deps))) new_widget = Widget() new_widget.dashboard_id = form_base.dashboard_id.data new_widget.graph_type = widget_name new_widget.name = form_base.name.data new_widget.font_em_name = form_base.font_em_name.data new_widget.enable_drag_handle = form_base.enable_drag_handle.data new_widget.refresh_duration = form_base.refresh_duration.data # Find where the next widget should be placed on the grid # Finds the lowest position to create as the new Widget's starting position position_y_start = 0 for each_widget in Widget.query.filter( Widget.dashboard_id == form_base.dashboard_id.data).all(): highest_position = each_widget.position_y + each_widget.height if highest_position > position_y_start: position_y_start = highest_position new_widget.position_y = position_y_start # widget add options if widget_name in dict_widgets: def dict_has_value(key): if (key in dict_widgets[widget_name] and (dict_widgets[widget_name][key] or dict_widgets[widget_name][key] == 0)): return True if dict_has_value('widget_width'): new_widget.width = dict_widgets[widget_name]['widget_width'] if dict_has_value('widget_height'): new_widget.height = dict_widgets[widget_name]['widget_height'] # Generate string to save from custom options error, custom_options = custom_options_return_json( error, dict_widgets, request_form, device=widget_name, use_defaults=True) new_widget.custom_options = custom_options # # Execute at Creation # if ('execute_at_creation' in dict_widgets[widget_name] and not current_app.config['TESTING']): dict_widgets[widget_name]['execute_at_creation']( new_widget, dict_widgets[widget_name]) try: if not error: new_widget.save() # Refresh widget settings control = DaemonControl() control.widget_add_refresh(new_widget.unique_id) flash(gettext( "{dev} with ID %(id)s successfully added".format( dev=dict_widgets[form_base.widget_type.data]['widget_name']), id=new_widget.id), "success") except sqlalchemy.exc.OperationalError as except_msg: error.append(except_msg) except sqlalchemy.exc.IntegrityError as except_msg: error.append(except_msg) return dep_unmet
def generate_widget_html(): """Generate all HTML files for all widgets.""" dict_widgets = parse_widget_information() assure_path_exists(PATH_HTML_USER) for widget_name in dict_widgets: try: filename_head = "widget_template_{}_head.html".format(widget_name) path_head = os.path.join(PATH_HTML_USER, filename_head) with open(path_head, 'w') as fw: if 'widget_dashboard_head' in dict_widgets[widget_name]: html_head = dict_widgets[widget_name]['widget_dashboard_head'] else: html_head = "" fw.write(html_head) fw.close() set_user_grp(path_head, 'mycodo', 'mycodo') filename_title_bar = "widget_template_{}_title_bar.html".format(widget_name) path_title_bar = os.path.join(PATH_HTML_USER, filename_title_bar) with open(path_title_bar, 'w') as fw: if 'widget_dashboard_title_bar' in dict_widgets[widget_name]: html_title_bar = dict_widgets[widget_name]['widget_dashboard_title_bar'] else: html_title_bar = "" fw.write(html_title_bar) fw.close() set_user_grp(path_title_bar, 'mycodo', 'mycodo') filename_body = "widget_template_{}_body.html".format(widget_name) path_body = os.path.join(PATH_HTML_USER, filename_body) with open(path_body, 'w') as fw: if 'widget_dashboard_body' in dict_widgets[widget_name]: html_body = dict_widgets[widget_name]['widget_dashboard_body'] else: html_body = "" fw.write(html_body) fw.close() set_user_grp(path_body, 'mycodo', 'mycodo') filename_configure_options = "widget_template_{}_configure_options.html".format(widget_name) path_configure_options = os.path.join(PATH_HTML_USER, filename_configure_options) with open(path_configure_options, 'w') as fw: if 'widget_dashboard_configure_options' in dict_widgets[widget_name]: html_configure_options = dict_widgets[widget_name]['widget_dashboard_configure_options'] else: html_configure_options = "" fw.write(html_configure_options) fw.close() set_user_grp(path_configure_options, 'mycodo', 'mycodo') filename_js = "widget_template_{}_js.html".format(widget_name) path_js = os.path.join(PATH_HTML_USER, filename_js) with open(path_js, 'w') as fw: if 'widget_dashboard_js' in dict_widgets[widget_name]: html_js = dict_widgets[widget_name]['widget_dashboard_js'] else: html_js = "" fw.write(html_js) fw.close() set_user_grp(path_js, 'mycodo', 'mycodo') filename_js_ready = "widget_template_{}_js_ready.html".format(widget_name) path_js_ready = os.path.join(PATH_HTML_USER, filename_js_ready) with open(path_js_ready, 'w') as fw: if 'widget_dashboard_js_ready' in dict_widgets[widget_name]: html_js_ready = dict_widgets[widget_name]['widget_dashboard_js_ready'] else: html_js_ready = "" fw.write(html_js_ready) fw.close() set_user_grp(path_js_ready, 'mycodo', 'mycodo') filename_js_ready_end = "widget_template_{}_js_ready_end.html".format(widget_name) path_js_ready_end = os.path.join(PATH_HTML_USER, filename_js_ready_end) with open(path_js_ready_end, 'w') as fw: if 'widget_dashboard_js_ready_end' in dict_widgets[widget_name]: html_js_ready_end = dict_widgets[widget_name]['widget_dashboard_js_ready_end'] else: html_js_ready_end = "" fw.write(html_js_ready_end) fw.close() set_user_grp(path_js_ready_end, 'mycodo', 'mycodo') except Exception: logger.exception("Generating widget HTML for widget: {}".format(widget_name))
def admin_dependencies(device): """ Display Dependency page """ form_dependencies = forms_dependencies.Dependencies() if device != '0': # Only loading a single dependency page device_unmet_dependencies, _ = utils_general.return_dependencies(device) elif form_dependencies.device.data: device_unmet_dependencies, _ = utils_general.return_dependencies(form_dependencies.device.data) else: device_unmet_dependencies = [] unmet_dependencies = OrderedDict() unmet_exist = False met_dependencies = [] met_exist = False unmet_list = {} install_in_progress = False device_name = None # Read from the dependency status file created by the upgrade script # to indicate if the upgrade is running. try: with open(DEPENDENCY_INIT_FILE) as f: dep = int(f.read(1)) except (IOError, ValueError): try: with open(DEPENDENCY_INIT_FILE, 'w') as f: f.write('0') finally: dep = 0 if dep: install_in_progress = True list_dependencies = [ parse_function_information(), parse_input_information(), parse_output_information(), parse_widget_information(), CAMERA_INFO, FUNCTION_ACTION_INFO, FUNCTION_INFO, LCD_INFO, MATH_INFO, METHOD_INFO, DEPENDENCIES_GENERAL ] for each_section in list_dependencies: for each_device in each_section: if device in each_section: for each_device_, each_val in each_section[device].items(): if each_device_ in ['name', 'input_name', 'output_name', 'function_name', 'widget_name']: device_name = each_val break # Only get all dependencies when not loading a single dependency page if device == '0': # Determine if there are any unmet dependencies for every device dep_unmet, dep_met = utils_general.return_dependencies(each_device) unmet_dependencies.update({ each_device: dep_unmet }) if dep_unmet: unmet_exist = True # Determine if there are any met dependencies if dep_met: if each_device not in met_dependencies: met_dependencies.append(each_device) met_exist = True # Find all the devices that use each unmet dependency if unmet_dependencies[each_device]: for each_dep in unmet_dependencies[each_device]: if each_dep not in unmet_list: unmet_list[each_dep] = [] if each_device not in unmet_list[each_dep]: unmet_list[each_dep].append(each_device) if request.method == 'POST': if not utils_general.user_has_permission('edit_controllers'): return redirect(url_for('routes_admin.admin_dependencies', device=device)) if form_dependencies.install.data: with open(DEPENDENCY_INIT_FILE, 'w') as f: f.write('1') install_deps = threading.Thread( target=install_dependencies, args=(device_unmet_dependencies,)) install_deps.start() return redirect(url_for('routes_admin.admin_dependencies', device=device)) return render_template('admin/dependencies.html', measurements=parse_input_information(), unmet_list=unmet_list, device=device, device_name=device_name, install_in_progress=install_in_progress, unmet_dependencies=unmet_dependencies, unmet_exist=unmet_exist, met_dependencies=met_dependencies, met_exist=met_exist, form_dependencies=form_dependencies, device_unmet_dependencies=device_unmet_dependencies)
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)
from mycodo.config import INSTALL_DIRECTORY from mycodo.utils.widgets import parse_widget_information save_path = os.path.join(INSTALL_DIRECTORY, "docs/Supported-Widgets.md") widgets_info = OrderedDict() mycodo_info = OrderedDict() def repeat_to_length(s, wanted): return (s * (wanted // len(s) + 1))[:wanted] if __name__ == "__main__": for widget_id, widget_data in parse_widget_information( exclude_custom=True).items(): name_str = "" if 'widget_name' in widget_data and widget_data['widget_name']: name_str += ": {}".format(widget_data['widget_name']) if name_str in widgets_info and 'dependencies_module' in widgets_info[ name_str]: # Multiple sets of dependencies, append library widgets_info[name_str]['dependencies_module'].append( widget_data['dependencies_module']) else: # Only one set of dependencies widgets_info[name_str] = widget_data if 'dependencies_module' in widget_data: widgets_info[name_str]['dependencies_module'] = [ widget_data['dependencies_module']