def widget_add(form_base, form_object): """Add a widget to the dashboard""" action = '{action} {controller}'.format( action=TRANSLATIONS['add']['title'], controller=TRANSLATIONS['widget']['title']) error = [] new_widget = Widget() new_widget.dashboard_id = form_base.dashboard_id.data 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 # 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 # Spacer if form_base.widget_type.data == 'spacer': widget_type = 'Spacer' new_widget.graph_type = form_base.widget_type.data new_widget.width = 20 new_widget.height = 1 # Graph elif (form_base.widget_type.data == 'graph' and (form_base.name.data and form_object.xaxis_duration.data and form_base.refresh_duration.data)): widget_type = 'Graph' error = graph_error_check(form_object, error) new_widget.graph_type = form_base.widget_type.data if form_object.math_ids.data: new_widget.math_ids = ";".join(form_object.math_ids.data) if form_object.pid_ids.data: new_widget.pid_ids = ";".join(form_object.pid_ids.data) if form_object.output_ids.data: new_widget.output_ids = ";".join(form_object.output_ids.data) if form_object.input_ids.data: new_widget.input_ids_measurements = ";".join( form_object.input_ids.data) if form_object.note_tag_ids.data: new_widget.note_tag_ids = ";".join(form_object.note_tag_ids.data) new_widget.refresh_duration = form_base.refresh_duration.data new_widget.enable_header_buttons = form_object.enable_header_buttons.data new_widget.x_axis_duration = form_object.xaxis_duration.data new_widget.enable_auto_refresh = form_object.enable_auto_refresh.data new_widget.enable_xaxis_reset = form_object.enable_xaxis_reset.data new_widget.enable_title = form_object.enable_title.data new_widget.enable_navbar = form_object.enable_navbar.data new_widget.enable_rangeselect = form_object.enable_rangeselect.data new_widget.enable_export = form_object.enable_export.data new_widget.enable_manual_y_axis = form_object.enable_manual_y_axis.data new_widget.width = 20 new_widget.height = 9 # Gauge elif form_base.widget_type.data == 'gauge': widget_type = 'Gauge' error = gauge_error_check(form_object, error) new_widget.graph_type = form_object.gauge_type.data new_widget.refresh_duration = form_base.refresh_duration.data new_widget.max_measure_age = form_object.max_measure_age.data new_widget.y_axis_min = form_object.y_axis_min.data new_widget.y_axis_max = form_object.y_axis_max.data new_widget.input_ids_measurements = form_object.input_ids.data new_widget.enable_timestamp = form_object.enable_timestamp.data new_widget.stops = form_object.stops.data new_widget.width = 4 if form_object.gauge_type.data == 'gauge_solid': new_widget.height = 4 elif form_object.gauge_type.data == 'gauge_angular': new_widget.height = 5 if form_object.stops.data < 2: error.append("Must be at least 2 stops") else: new_widget.range_colors = gauge_reformat_stops( form_object.gauge_type.data, 4, new_widget.stops, current_colors=None) # Indicator elif form_base.widget_type.data == 'indicator': widget_type = 'Indicator' error = measurement_error_check(form_object, error) new_widget.graph_type = 'indicator' new_widget.refresh_duration = form_base.refresh_duration.data new_widget.max_measure_age = form_object.max_measure_age.data new_widget.font_em_timestamp = form_object.font_em_timestamp.data new_widget.input_ids_measurements = form_object.measurement_id.data new_widget.enable_timestamp = form_object.enable_timestamp.data new_widget.width = 3 new_widget.height = 4 # Measurement elif form_base.widget_type.data == 'measurement': widget_type = 'Measurement' error = measurement_error_check(form_object, error) new_widget.graph_type = 'measurement' new_widget.max_measure_age = form_object.max_measure_age.data new_widget.refresh_duration = form_base.refresh_duration.data new_widget.font_em_value = form_object.font_em_value.data new_widget.font_em_timestamp = form_object.font_em_timestamp.data new_widget.decimal_places = form_object.decimal_places.data new_widget.input_ids_measurements = form_object.measurement_id.data new_widget.enable_name = form_object.enable_name.data new_widget.enable_unit = form_object.enable_unit.data new_widget.enable_measurement = form_object.enable_measurement.data new_widget.enable_channel = form_object.enable_channel.data new_widget.enable_timestamp = form_object.enable_timestamp.data new_widget.width = 4 new_widget.height = 5 # Output elif form_base.widget_type.data == 'output': widget_type = 'Output' error = output_error_check(form_object, error) new_widget.graph_type = 'output' new_widget.max_measure_age = form_object.max_measure_age.data new_widget.refresh_duration = form_base.refresh_duration.data new_widget.font_em_value = form_object.font_em_value.data new_widget.font_em_timestamp = form_object.font_em_timestamp.data new_widget.enable_output_controls = form_object.enable_output_controls.data new_widget.decimal_places = form_object.decimal_places.data new_widget.output_ids = form_object.output_id.data new_widget.enable_status = form_object.enable_status.data new_widget.enable_value = form_object.enable_value.data new_widget.enable_unit = form_object.enable_unit.data new_widget.enable_timestamp = form_object.enable_timestamp.data new_widget.width = 5 new_widget.height = 4 # Output Range Slider elif form_base.widget_type.data == 'output_pwm_slider': widget_type = 'Output Range Slider' error = output_error_check(form_object, error) new_widget.graph_type = 'output_pwm_slider' new_widget.max_measure_age = form_object.max_measure_age.data new_widget.refresh_duration = form_base.refresh_duration.data new_widget.font_em_value = form_object.font_em_value.data new_widget.font_em_timestamp = form_object.font_em_timestamp.data new_widget.enable_output_controls = form_object.enable_output_controls.data new_widget.decimal_places = form_object.decimal_places.data new_widget.output_ids = form_object.output_id.data new_widget.enable_status = form_object.enable_status.data new_widget.enable_value = form_object.enable_value.data new_widget.enable_unit = form_object.enable_unit.data new_widget.enable_timestamp = form_object.enable_timestamp.data new_widget.width = 5 new_widget.height = 4 # PID Control elif form_base.widget_type.data == 'pid_control': widget_type = 'PID Control' error = pid_error_check(form_object, error) new_widget.graph_type = 'pid_control' new_widget.max_measure_age = form_object.max_measure_age.data new_widget.refresh_duration = form_base.refresh_duration.data new_widget.font_em_value = form_object.font_em_value.data new_widget.font_em_timestamp = form_object.font_em_timestamp.data new_widget.decimal_places = form_object.decimal_places.data new_widget.show_pid_info = form_object.show_pid_info.data new_widget.enable_status = form_object.enable_status.data new_widget.enable_timestamp = form_object.enable_timestamp.data new_widget.show_set_setpoint = form_object.show_set_setpoint.data new_widget.pid_ids = form_object.pid_id.data new_widget.width = 6 new_widget.height = 5 # Camera elif form_base.widget_type.data == 'camera': widget_type = 'Camera' camera = Camera.query.filter( Camera.unique_id == form_object.camera_id.data).first() if not camera: error.append("Invalid Camera ID.") elif (form_object.camera_image_type.data == 'stream' and camera.library not in ['opencv', 'picamera']): error.append("Only cameras that use the 'picamera' or " "'opencv' library may be used for streaming") new_widget.graph_type = form_base.widget_type.data new_widget.refresh_duration = form_base.refresh_duration.data new_widget.camera_max_age = form_object.camera_max_age.data new_widget.camera_id = form_object.camera_id.data new_widget.camera_image_type = form_object.camera_image_type.data new_widget.width = 7 new_widget.height = 8 # Python code elif form_base.widget_type.data == 'python_code': widget_type = 'Python Code' new_widget.graph_type = form_base.widget_type.data new_widget.refresh_duration = form_base.refresh_duration.data new_widget.font_em_value = form_object.font_em_value.data new_widget.code_execute_loop = form_object.code_execute_loop.data new_widget.code_execute_single = form_object.code_execute_single.data new_widget.width = 4 new_widget.height = 4 new_widget.save() pre_statement_loop = """import os import sys sys.path.append(os.path.abspath('/var/mycodo-root')) from mycodo.mycodo_client import DaemonControl control = DaemonControl() class PythonRun: def __init__(self, logger, unique_id): self.logger = logger self.unique_id = unique_id def python_code_loop(self): """ pre_statement_single = """ def python_code_refresh(self): """ indented_code_loop = textwrap.indent( form_object.code_execute_loop.data, ' ' * 8) indented_code_single = textwrap.indent( form_object.code_execute_single.data, ' ' * 8) input_python_code_run = pre_statement_loop + indented_code_loop + pre_statement_single + indented_code_single file_run = '{}/python_code_{}.py'.format(PATH_PYTHON_CODE_USER, new_widget.unique_id) create_python_file(input_python_code_run, file_run) successes, errors = test_python_code(input_python_code_run, file_run) for each_error in errors: flash(each_error, "error") for each_success in successes: flash(each_success, "success") else: flash_form_errors(form_base) return try: if not error: new_widget.save() if form_base.widget_type.data == 'python_code': control = DaemonControl() control.widget_add_refresh(new_widget.unique_id) flash( gettext("{dev} with ID %(id)s successfully added".format( dev=widget_type), 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) flash_success_errors( error, action, url_for('routes_page.page_dashboard', dashboard_id=form_base.dashboard_id.data))
def widget_add(form_base, form_object): """Add a widget to the dashboard""" action = '{action} {controller}'.format( action=TRANSLATIONS['add']['title'], controller=TRANSLATIONS['widget']['title']) error = [] new_widget = Widget() new_widget.dashboard_id = form_base.dashboard_id.data 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 # 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 # Spacer if form_base.widget_type.data == 'spacer': widget_type = 'Spacer' new_widget.graph_type = form_base.widget_type.data new_widget.width = 20 new_widget.height = 1 # Graph elif (form_base.widget_type.data == 'graph' and (form_base.name.data and form_object.xaxis_duration.data and form_base.refresh_duration.data)): widget_type = 'Graph' error = graph_error_check(form_object, error) new_widget.graph_type = form_base.widget_type.data if form_object.math_ids.data: new_widget.math_ids = ";".join(form_object.math_ids.data) if form_object.pid_ids.data: new_widget.pid_ids = ";".join(form_object.pid_ids.data) if form_object.output_ids.data: new_widget.output_ids = ";".join(form_object.output_ids.data) if form_object.input_ids.data: new_widget.input_ids_measurements = ";".join( form_object.input_ids.data) if form_object.note_tag_ids.data: new_widget.note_tag_ids = ";".join(form_object.note_tag_ids.data) new_widget.refresh_duration = form_base.refresh_duration.data new_widget.enable_header_buttons = form_object.enable_header_buttons.data new_widget.x_axis_duration = form_object.xaxis_duration.data new_widget.enable_auto_refresh = form_object.enable_auto_refresh.data new_widget.enable_xaxis_reset = form_object.enable_xaxis_reset.data new_widget.enable_title = form_object.enable_title.data new_widget.enable_navbar = form_object.enable_navbar.data new_widget.enable_rangeselect = form_object.enable_rangeselect.data new_widget.enable_export = form_object.enable_export.data new_widget.enable_graph_shift = form_object.enable_graph_shift.data new_widget.enable_manual_y_axis = form_object.enable_manual_y_axis.data new_widget.width = 20 new_widget.height = 9 # Gauge elif form_base.widget_type.data == 'gauge': widget_type = 'Gauge' error = gauge_error_check(form_object, error) new_widget.graph_type = form_object.gauge_type.data new_widget.refresh_duration = form_base.refresh_duration.data new_widget.max_measure_age = form_object.max_measure_age.data new_widget.y_axis_min = form_object.y_axis_min.data new_widget.y_axis_max = form_object.y_axis_max.data new_widget.input_ids_measurements = form_object.input_ids.data new_widget.enable_timestamp = form_object.enable_timestamp.data new_widget.stops = form_object.stops.data new_widget.width = 4 if form_object.gauge_type.data == 'gauge_solid': new_widget.height = 4 elif form_object.gauge_type.data == 'gauge_angular': new_widget.height = 5 if form_object.stops.data < 2: error.append("Must be at least 2 stops") else: new_widget.range_colors = gauge_reformat_stops( form_object.gauge_type.data, 4, new_widget.stops, current_colors=None) # Indicator elif form_base.widget_type.data == 'indicator': widget_type = 'Indicator' error = measurement_error_check(form_object, error) new_widget.graph_type = 'indicator' new_widget.refresh_duration = form_base.refresh_duration.data new_widget.max_measure_age = form_object.max_measure_age.data new_widget.font_em_timestamp = form_object.font_em_timestamp.data new_widget.input_ids_measurements = form_object.measurement_id.data new_widget.enable_timestamp = form_object.enable_timestamp.data new_widget.width = 3 new_widget.height = 4 # Measurement elif form_base.widget_type.data == 'measurement': widget_type = 'Measurement' error = measurement_error_check(form_object, error) new_widget.graph_type = 'measurement' new_widget.max_measure_age = form_object.max_measure_age.data new_widget.refresh_duration = form_base.refresh_duration.data new_widget.font_em_value = form_object.font_em_value.data new_widget.font_em_timestamp = form_object.font_em_timestamp.data new_widget.decimal_places = form_object.decimal_places.data new_widget.input_ids_measurements = form_object.measurement_id.data new_widget.enable_name = form_object.enable_name.data new_widget.enable_unit = form_object.enable_unit.data new_widget.enable_measurement = form_object.enable_measurement.data new_widget.enable_channel = form_object.enable_channel.data new_widget.enable_timestamp = form_object.enable_timestamp.data new_widget.width = 4 new_widget.height = 5 # Output elif form_base.widget_type.data == 'output': widget_type = 'Output' error = output_error_check(form_object, error) new_widget.graph_type = 'output' new_widget.max_measure_age = form_object.max_measure_age.data new_widget.refresh_duration = form_base.refresh_duration.data new_widget.font_em_value = form_object.font_em_value.data new_widget.font_em_timestamp = form_object.font_em_timestamp.data new_widget.enable_output_controls = form_object.enable_output_controls.data new_widget.decimal_places = form_object.decimal_places.data new_widget.output_ids = form_object.output_id.data new_widget.enable_status = form_object.enable_status.data new_widget.enable_value = form_object.enable_value.data new_widget.enable_unit = form_object.enable_unit.data new_widget.enable_timestamp = form_object.enable_timestamp.data new_widget.width = 5 new_widget.height = 4 # Output Range Slider elif form_base.widget_type.data == 'output_pwm_slider': widget_type = 'Output Range Slider' error = output_error_check(form_object, error) new_widget.graph_type = 'output_pwm_slider' new_widget.max_measure_age = form_object.max_measure_age.data new_widget.refresh_duration = form_base.refresh_duration.data new_widget.font_em_value = form_object.font_em_value.data new_widget.font_em_timestamp = form_object.font_em_timestamp.data new_widget.enable_output_controls = form_object.enable_output_controls.data new_widget.decimal_places = form_object.decimal_places.data new_widget.output_ids = form_object.output_id.data new_widget.enable_status = form_object.enable_status.data new_widget.enable_value = form_object.enable_value.data new_widget.enable_unit = form_object.enable_unit.data new_widget.enable_timestamp = form_object.enable_timestamp.data new_widget.width = 5 new_widget.height = 4 # PID Control elif form_base.widget_type.data == 'pid_control': widget_type = 'PID Control' error = pid_error_check(form_object, error) new_widget.graph_type = 'pid_control' new_widget.max_measure_age = form_object.max_measure_age.data new_widget.refresh_duration = form_base.refresh_duration.data new_widget.font_em_value = form_object.font_em_value.data new_widget.font_em_timestamp = form_object.font_em_timestamp.data new_widget.decimal_places = form_object.decimal_places.data new_widget.show_pid_info = form_object.show_pid_info.data new_widget.enable_status = form_object.enable_status.data new_widget.enable_timestamp = form_object.enable_timestamp.data new_widget.show_set_setpoint = form_object.show_set_setpoint.data new_widget.pid_ids = form_object.pid_id.data new_widget.width = 6 new_widget.height = 5 # Camera elif form_base.widget_type.data == 'camera': widget_type = 'Camera' camera = Camera.query.filter( Camera.unique_id == form_object.camera_id.data).first() if not camera: error.append("Invalid Camera ID.") elif (form_object.camera_image_type.data == 'stream' and camera.library not in ['opencv', 'picamera']): error.append("Only cameras that use the 'picamera' or " "'opencv' library may be used for streaming") new_widget.graph_type = form_base.widget_type.data new_widget.refresh_duration = form_base.refresh_duration.data new_widget.camera_max_age = form_object.camera_max_age.data new_widget.camera_id = form_object.camera_id.data new_widget.camera_image_type = form_object.camera_image_type.data new_widget.width = 7 new_widget.height = 8 else: flash_form_errors(form_base) return try: if not error: new_widget.save() flash( gettext("{dev} with ID %(id)s successfully added".format( dev=widget_type), 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) flash_success_errors( error, action, url_for('routes_page.page_dashboard', dashboard_id=form_base.dashboard_id.data))