class InputAdd(FlaskForm): choices_inputs = [('', lazy_gettext('Select Input to Add'))] dict_inputs = parse_input_information() list_inputs_sorted = generate_form_input_list(dict_inputs) for each_input in list_inputs_sorted: if 'interfaces' not in dict_inputs[each_input]: choices_inputs.append( ('{inp},'.format(inp=each_input), '{manuf}: {name}: {meas}'.format( manuf=dict_inputs[each_input]['input_manufacturer'], name=dict_inputs[each_input]['input_name'], meas=dict_inputs[each_input]['measurements_name']))) else: for each_interface in dict_inputs[each_input]['interfaces']: choices_inputs.append( ('{inp},{int}'.format(inp=each_input, int=each_interface), '{manuf}: {name}: {meas} ({int})'.format( manuf=dict_inputs[each_input]['input_manufacturer'], name=dict_inputs[each_input]['input_name'], meas=dict_inputs[each_input]['measurements_name'], int=each_interface))) input_type = SelectField(choices=choices_inputs, validators=[DataRequired()]) input_add = SubmitField(lazy_gettext('Add Input'))
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
class InputAdd(FlaskForm): choices_inputs = [] dict_inputs = parse_input_information() list_inputs_sorted = generate_form_input_list(dict_inputs) for each_input in list_inputs_sorted: value = '{inp},'.format(inp=each_input) name = '{manuf}: {name}'.format( manuf=dict_inputs[each_input]['input_manufacturer'], name=dict_inputs[each_input]['input_name']) if 'input_library' in dict_inputs[each_input]: name += ' ({lib})'.format(lib=dict_inputs[each_input]['input_library']) name += ': {meas}'.format(meas=dict_inputs[each_input]['measurements_name']) if 'interfaces' in dict_inputs[each_input]: for each_interface in dict_inputs[each_input]['interfaces']: tmp_value = '{val}{int}'.format(val=value, int=each_interface) tmp_name = '{name} ({int})'.format(name=name, int=each_interface) choices_inputs.append((tmp_value, tmp_name)) else: choices_inputs.append((value, name)) input_type = SelectField( choices=choices_inputs, validators=[DataRequired()] ) input_add = SubmitField(TRANSLATIONS['add']['title'])
def get_installed_dependencies(): met_deps = [] dict_inputs = parse_input_information() list_dependencies = [ dict_inputs, MATH_INFO, METHOD_INFO, OUTPUT_INFO ] for each_section in list_dependencies: for device_type in each_section: for each_device, each_dict in each_section[device_type].items(): if each_device == 'dependencies_module': for (install_type, package, install_id) in each_dict: entry = '{0} {1}'.format(install_type, install_id) if install_type in ['pip-pypi', 'pip-git']: try: module = importlib.util.find_spec(package) if module is not None and entry not in met_deps: met_deps.append(entry) except Exception: logger.error( 'Exception while checking python dependency: ' '{dep}'.format(dep=package)) elif install_type == 'apt': cmd = 'dpkg -l {}'.format(package) _, _, stat = cmd_output(cmd) if not stat and entry not in met_deps: met_deps.append(entry) return met_deps
def get_installed_dependencies(): met_deps = [] list_dependencies = [ parse_function_information(), parse_input_information(), parse_output_information(), CAMERA_INFO, FUNCTION_ACTION_INFO, FUNCTION_INFO, LCD_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: entry = '{0} {1}'.format(install_type, install_id) if install_type in ['pip-pypi', 'pip-git']: try: module = importlib.util.find_spec(package) if module is not None and entry not in met_deps: met_deps.append(entry) except Exception: logger.error( 'Exception checking python dependency: ' '{dep}'.format(dep=package)) elif 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 entry not in met_deps: met_deps.append(entry) return met_deps
def test_add_all_input_devices_logged_in_as_admin(_, testapp): """ Verifies adding all inputs as a logged in admin user """ print("\nTest: test_add_all_input_devices_logged_in_as_admin") login_user(testapp, 'admin', '53CR3t_p4zZW0rD') # Add All Inputs input_count = 0 dict_inputs = parse_input_information() list_inputs_sorted = generate_form_input_list(dict_inputs) choices_input = [] for each_input in list_inputs_sorted: if 'interfaces' not in dict_inputs[each_input]: choices_input.append('{inp},'.format(inp=each_input)) else: for each_interface in dict_inputs[each_input]['interfaces']: choices_input.append('{inp},{int}'.format(inp=each_input, int=each_interface)) for index, each_input in enumerate(choices_input): choice_name = each_input.split(',')[0] print("test_add_all_input_devices_logged_in_as_admin: Adding, saving, and deleting Input ({}/{}): {}".format( index + 1, len(choices_input), each_input)) response = add_data(testapp, input_type=each_input) assert 'data' in response.json assert 'messages' in response.json['data'] assert 'error' in response.json['data']['messages'] assert response.json['data']['messages']['error'] == [] assert 'success' in response.json['data']['messages'] assert len(response.json['data']['messages']['success']) == 1 # Verify data was entered into the database input_count += 1 assert Input.query.count() == input_count, "Number of Inputs doesn't match: In DB {}, Should be: {}".format( Input.query.count(), input_count) input_dev = Input.query.filter(Input.id == input_count).first() assert choice_name == input_dev.device, "Input name doesn't match: {}".format(choice_name) # Save input response = save_data(testapp, 'input', device_dev=input_dev) assert 'data' in response.json assert 'messages' in response.json['data'] assert 'error' in response.json['data']['messages'] assert response.json['data']['messages']['error'] == [] assert 'success' in response.json['data']['messages'] assert len(response.json['data']['messages']['success']) == 1 # Delete input (speeds up further input addition checking) response = delete_data(testapp, 'input', device_dev=input_dev) assert 'data' in response.json assert 'messages' in response.json['data'] assert 'error' in response.json['data']['messages'] assert response.json['data']['messages']['error'] == [] assert 'success' in response.json['data']['messages'] assert len(response.json['data']['messages']['success']) == 1 input_count -= 1 assert Input.query.count() == input_count, "Number of Inputs doesn't match: In DB {}, Should be: {}".format( Input.query.count(), input_count)
def input_activate(form_mod): action = '{action} {controller}'.format( action=TRANSLATIONS['activate']['title'], controller=TRANSLATIONS['input']['title']) error = [] dict_inputs = parse_input_information() input_id = form_mod.input_id.data input_dev = Input.query.filter(Input.unique_id == input_id).first() device_measurements = DeviceMeasurements.query.filter( DeviceMeasurements.device_id == input_dev.unique_id) custom_options_values = parse_custom_option_values(input_dev) # # General Input checks # if not input_dev.period: error.append("Period must be set") if (input_dev.pre_output_id and len(input_dev.pre_output_id) > 1 and not input_dev.pre_output_duration): error.append( "Pre Output Duration must be > 0 if Pre Output is enabled") if not device_measurements.filter( DeviceMeasurements.is_enabled == True).count(): error.append("At least one measurement must be enabled") # # Check if required custom options are set # if 'custom_options' in dict_inputs[input_dev.device]: for each_option in dict_inputs[input_dev.device]['custom_options']: value = custom_options_values[input_dev.unique_id][ each_option['id']] if ('required' in each_option and each_option['required'] and not value): error.append("{} is required to be set".format( each_option['name'])) # # Input-specific checks # if input_dev.device == 'LinuxCommand' and not input_dev.cmd_command: error.append("Cannot activate Command Input without a Command set") elif ('measurements_variable_amount' in dict_inputs[input_dev.device] and dict_inputs[input_dev.device]['measurements_variable_amount']): measure_set = True for each_channel in device_measurements.all(): if (not each_channel.name or not each_channel.measurement or not each_channel.unit): measure_set = False if not measure_set: error.append( "All measurements must have a name and unit/measurement set") if not error: controller_activate_deactivate('activate', 'Input', input_id) flash_success_errors(error, action, url_for('routes_page.page_data'))
def choices_inputs(inputs): """ populate form multi-select choices from Input entries """ choices = OrderedDict() dict_inputs = parse_input_information() for each_input in inputs: choices = form_input_choices(choices, each_input, dict_inputs) return choices
def test_add_all_data_devices_logged_in_as_admin(_, testapp): """ Verifies adding all inputs as a logged in admin user """ login_user(testapp, 'admin', '53CR3t_p4zZW0rD') # Add All Inputs input_count = 0 dict_inputs = parse_input_information() list_inputs_sorted = generate_form_input_list(dict_inputs) choices_input = [] for each_input in list_inputs_sorted: if 'interfaces' not in dict_inputs[each_input]: choices_input.append('{inp},'.format(inp=each_input)) else: for each_interface in dict_inputs[each_input]['interfaces']: choices_input.append('{inp},{int}'.format(inp=each_input, int=each_interface)) for each_input in choices_input: choice_name = each_input.split(',')[0] print("Testing {}".format(each_input)) response = add_data(testapp, data_type='input', input_type=each_input) # Verify success message flashed assert "{} Input with ID".format(choice_name) in response assert "successfully added" in response # Verify data was entered into the database input_count += 1 assert Input.query.count( ) == input_count, "Number of Inputs doesn't match: In DB {}, Should be: {}".format( Input.query.count(), input_count) input_dev = Input.query.filter(Input.id == input_count).first() assert dict_inputs[choice_name][ 'input_name'] in input_dev.name, "Input name doesn't match: {}".format( choice_name) # Add All Maths math_count = 0 for each_math in MATH_INFO.keys(): response = add_data(testapp, data_type='math', input_type=each_math) # Verify success message flashed assert "{} Math with ID".format(each_math) in response assert "successfully added" in response # Verify data was entered into the database math_count += 1 actual_count = Math.query.count() assert actual_count == math_count, "Number of Maths don't match: In DB {}, Should be: {}".format( actual_count, math_count) math_dev = Math.query.filter(Math.id == math_count).first() assert each_math in math_dev.math_type, "Math type doesn't match: {}".format( each_math)
def measurement_mod(form): action = '{action} {controller}'.format( action=TRANSLATIONS['modify']['title'], controller=TRANSLATIONS['measurement']['title']) error = [] try: mod_meas = DeviceMeasurements.query.filter( DeviceMeasurements.unique_id == form.input_measurement_id.data).first() mod_input = Input.query.filter(Input.unique_id == mod_meas.device_id).first() if mod_input.is_activated: error.append(gettext( "Deactivate controller before modifying its settings")) mod_meas.name = form.name.data if form.input_type.data == 'measurement_select': mod_meas.measurement = form.select_measurement_unit.data.split(',')[0] mod_meas.unit = form.select_measurement_unit.data.split(',')[1] elif form.input_type.data == 'measurement_convert': input_info = parse_input_information() if ('enable_channel_unit_select' in input_info[mod_input.device] and input_info[mod_input.device]['enable_channel_unit_select']): if ',' in form.select_measurement_unit.data: mod_meas.measurement = form.select_measurement_unit.data.split(',')[0] mod_meas.unit = form.select_measurement_unit.data.split(',')[1] else: mod_meas.measurement = '' mod_meas.unit = '' if form.rescaled_measurement_unit.data != '' and ',' in form.rescaled_measurement_unit.data: mod_meas.rescaled_measurement = form.rescaled_measurement_unit.data.split(',')[0] mod_meas.rescaled_unit = form.rescaled_measurement_unit.data.split(',')[1] elif form.rescaled_measurement_unit.data == '': mod_meas.rescaled_measurement = '' mod_meas.rescaled_unit = '' mod_meas.scale_from_min = form.scale_from_min.data mod_meas.scale_from_max = form.scale_from_max.data mod_meas.scale_to_min = form.scale_to_min.data mod_meas.scale_to_max = form.scale_to_max.data mod_meas.invert_scale = form.invert_scale.data mod_meas.conversion_id = form.convert_to_measurement_unit.data if not error: db.session.commit() except Exception as except_msg: logger.exception(1) error.append(except_msg) flash_success_errors(error, action, url_for('routes_page.page_data'))
def test_add_all_data_devices_logged_in_as_admin(_, testapp): """ Verifies adding all inputs as a logged in admin user """ login_user(testapp, 'admin', '53CR3t_p4zZW0rD') # Add All Inputs input_count = 0 dict_inputs = parse_input_information() list_inputs_sorted = generate_form_input_list(dict_inputs) choices_input = [] for each_input in list_inputs_sorted: if 'interfaces' not in dict_inputs[each_input]: choices_input.append('{inp},'.format(inp=each_input)) else: for each_interface in dict_inputs[each_input]['interfaces']: choices_input.append('{inp},{int}'.format(inp=each_input, int=each_interface)) for each_input in choices_input: choice_name = each_input.split(',')[0] print("Testing {}".format(each_input)) response = add_data(testapp, data_type='input', input_type=each_input) # Verify success message flashed assert "{} Input with ID".format(choice_name) in response assert "successfully added" in response # Verify data was entered into the database input_count += 1 assert Input.query.count() == input_count, "Number of Inputs doesn't match: In DB {}, Should be: {}".format(Input.query.count(), input_count) input_dev = Input.query.filter(Input.id == input_count).first() assert dict_inputs[choice_name]['input_name'] in input_dev.name, "Input name doesn't match: {}".format(choice_name) # Add All Maths math_count = 0 for each_math in MATH_INFO.keys(): response = add_data(testapp, data_type='math', input_type=each_math) # Verify success message flashed assert "{} Math with ID".format(each_math) in response assert "successfully added" in response # Verify data was entered into the database math_count += 1 actual_count = Math.query.count() assert actual_count == math_count, "Number of Maths don't match: In DB {}, Should be: {}".format(actual_count, math_count) math_dev = Math.query.filter(Math.id == math_count).first() assert each_math in math_dev.math_type, "Math type doesn't match: {}".format(each_math)
def choices_lcd(inputs, maths, pids, outputs): choices = OrderedDict() dict_inputs = parse_input_information() # Display IP address value = '0000,IP' display = 'IP Address of Raspberry Pi' choices.update({value: display}) # Inputs for each_input in inputs: value = '{id},input_time'.format( id=each_input.unique_id) display = '[Input {id:02d}] {name} (Timestamp)'.format( id=each_input.id, name=each_input.name) choices.update({value: display}) choices = form_input_choices(choices, each_input, dict_inputs) # Maths for each_math in maths: value = '{id},math_time'.format( id=each_math.unique_id) display = '[Math {id:02d}] {name} (Timestamp)'.format( id=each_math.id, name=each_math.name) choices.update({value: display}) choices = form_math_choices(choices, each_math) # PIDs for each_pid in pids: value = '{id},pid_time'.format( id=each_pid.unique_id) display = '[PID {id:02d}] {name} (Timestamp)'.format( id=each_pid.id, name=each_pid.name) choices.update({value: display}) choices = form_pid_choices(choices, each_pid) # Outputs for each_output in outputs: value = '{id},pid_time'.format( id=each_output.unique_id) display = '[Output {id:02d}] {name} (Timestamp)'.format( id=each_output.id, name=each_output.name) choices.update({value: display}) choices = form_output_choices(choices, each_output) return choices
def measurement_mod(form): action = '{action} {controller}'.format( action=TRANSLATIONS['modify']['title'], controller=TRANSLATIONS['measurement']['title']) error = [] try: mod_meas = DeviceMeasurements.query.filter( DeviceMeasurements.unique_id == form.input_measurement_id.data).first() mod_input = Input.query.filter(Input.unique_id == mod_meas.device_id).first() if mod_input.is_activated: error.append(gettext( "Deactivate controller before modifying its settings")) mod_meas.name = form.name.data input_info = parse_input_information() if ('enable_channel_unit_select' in input_info[mod_input.device] and input_info[mod_input.device]['enable_channel_unit_select']): if ',' in form.select_measurement_unit.data: mod_meas.measurement = form.select_measurement_unit.data.split(',')[0] mod_meas.unit = form.select_measurement_unit.data.split(',')[1] else: mod_meas.measurement = '' mod_meas.unit = '' if form.rescaled_measurement_unit.data != '' and ',' in form.rescaled_measurement_unit.data: mod_meas.rescaled_measurement = form.rescaled_measurement_unit.data.split(',')[0] mod_meas.rescaled_unit = form.rescaled_measurement_unit.data.split(',')[1] elif form.rescaled_measurement_unit.data == '': mod_meas.rescaled_measurement = '' mod_meas.rescaled_unit = '' mod_meas.scale_from_min = form.scale_from_min.data mod_meas.scale_from_max = form.scale_from_max.data mod_meas.scale_to_min = form.scale_to_min.data mod_meas.scale_to_max = form.scale_to_max.data mod_meas.invert_scale = form.invert_scale.data mod_meas.conversion_id = form.convert_to_measurement_unit.data if not error: db.session.commit() except Exception as except_msg: logger.exception(1) error.append(except_msg) flash_success_errors(error, action, url_for('routes_page.page_data'))
def setup_atlas_flow(): """ Step-by-step tool for calibrating the Atlas Scientific RGB sensor """ if not utils_general.user_has_permission('edit_controllers'): return redirect(url_for('routes_general.home')) form_flow_calibrate = forms_calibration.CalibrationAtlasFlow() input_dev = Input.query.filter(Input.device == 'ATLAS_FLOW').all() ui_stage = 'start' selected_input = None input_device_name = None complete_with_error = None # Begin calibration from Selected input if form_flow_calibrate.clear_calibration.data: selected_input = Input.query.filter_by( unique_id=form_flow_calibrate.selected_input_id.data).first() dict_inputs = parse_input_information() list_inputs_sorted = generate_form_input_list(dict_inputs) if not selected_input: flash( 'Input not found: {}'.format( form_flow_calibrate.selected_input_id.data), 'error') else: for each_input in list_inputs_sorted: if selected_input.device == each_input[0]: input_device_name = each_input[1] if selected_input.is_activated: control = DaemonControl() return_status, return_string = control.input_atlas_flow_clear_total_volume( selected_input.unique_id) else: atlas_command = AtlasScientificCommand(selected_input) return_status, return_string = atlas_command.send_command('Clear') if return_status: complete_with_error = return_string ui_stage = 'complete' return render_template('tools/calibration_options/atlas_flow.html', complete_with_error=complete_with_error, form_flow_calibrate=form_flow_calibrate, input=input_dev, input_device_name=input_device_name, selected_input=selected_input, ui_stage=ui_stage)
def test_add_all_data_devices_logged_in_as_admin(_, testapp): """ Verifies adding all inputs as a logged in admin user """ login_user(testapp, 'admin', '53CR3t_p4zZW0rD') # Add All Inputs input_count = 0 for each_input, each_data in parse_input_information().items(): for each_interface in each_data['interfaces']: response = add_data(testapp, data_type='input', input_type='{},{}'.format( each_input, each_interface)) # Verify success message flashed assert "{} Input with ID".format(each_input) in response assert "successfully added" in response # Verify data was entered into the database input_count += 1 assert Input.query.count( ) == input_count, "Number of Inputs doesn't match: In DB {}, Should be: {}".format( Input.query.count(), input_count) input_dev = Input.query.filter(Input.id == input_count).first() assert each_data[ 'input_name'] in input_dev.name, "Input name doesn't match: {}".format( each_input) # Add All Maths math_count = 0 for each_math, each_data in MATH_INFO.items(): response = add_data(testapp, data_type='math', input_type=each_math) # Verify success message flashed assert "{} Math with ID".format(each_math) in response assert "successfully added" in response # Verify data was entered into the database math_count += 1 actual_count = Math.query.count() assert actual_count == math_count, "Number of Maths doesn't match: In DB {}, Should be: {}".format( actual_count, math_count) math_dev = Math.query.filter(Math.id == math_count).first() assert each_data[ 'name'] in math_dev.name, "Math name doesn't match: {}".format( each_math)
def get_installed_dependencies(): met_deps = [] list_dependencies = [ parse_controller_information(), parse_input_information(), parse_output_information(), CALIBRATION_INFO, CAMERA_INFO, FUNCTION_ACTION_INFO, FUNCTION_INFO, LCD_INFO, MATH_INFO, METHOD_INFO, ] for each_section in list_dependencies: for 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: entry = '{0} {1}'.format(install_type, install_id) if install_type in ['pip-pypi', 'pip-git']: try: module = importlib.util.find_spec(package) if module is not None and entry not in met_deps: met_deps.append(entry) except Exception: logger.error( 'Exception checking python dependency: ' '{dep}'.format(dep=package)) elif install_type == 'apt': cmd = 'dpkg -l {}'.format(package) _, _, status = cmd_output(cmd, user='******') if not status and entry not in met_deps: met_deps.append(entry) return met_deps
def setup_atlas_ec(): """ Step-by-step tool for calibrating the Atlas Scientific EC sensor """ if not utils_general.user_has_permission('edit_controllers'): return redirect(url_for('routes_general.home')) form_ec_calibrate = forms_calibration.CalibrationAtlasEC() input_dev = Input.query.filter(Input.device == 'ATLAS_EC').all() ui_stage = 'start' backend_stage = None next_stage = None selected_input = None selected_point_calibration = None input_device_name = None complete_with_error = None if form_ec_calibrate.hidden_current_stage.data: backend_stage = form_ec_calibrate.hidden_current_stage.data if form_ec_calibrate.hidden_selected_point_calibration.data: selected_point_calibration = form_ec_calibrate.hidden_selected_point_calibration.data elif form_ec_calibrate.point_calibration.data: selected_point_calibration = form_ec_calibrate.point_calibration.data if selected_point_calibration: list_point_calibrations = selected_point_calibration.split(',') else: list_point_calibrations = [] if form_ec_calibrate.point_low_uS.data: point_low_uS = form_ec_calibrate.point_low_uS.data else: point_low_uS = form_ec_calibrate.hidden_point_low_uS.data if form_ec_calibrate.point_high_uS.data: point_high_uS = form_ec_calibrate.point_high_uS.data else: point_high_uS = form_ec_calibrate.hidden_point_high_uS.data # Begin calibration from Selected input if form_ec_calibrate.start_calibration.data: ui_stage = 'point_enter_uS' selected_input = Input.query.filter_by( unique_id=form_ec_calibrate.selected_input_id.data).first() dict_inputs = parse_input_information() list_inputs_sorted = generate_form_input_list(dict_inputs) if not selected_input: flash( 'Input not found: {}'.format( form_ec_calibrate.selected_input_id.data), 'error') else: for each_input in list_inputs_sorted: if selected_input.device == each_input[0]: input_device_name = each_input[1] # Continue calibration from selected input elif (form_ec_calibrate.go_to_next_stage.data or form_ec_calibrate.go_to_last_stage.data or (backend_stage is not None and backend_stage not in ['start', 'point_enter_uS'])): selected_input = Input.query.filter_by( unique_id=form_ec_calibrate.hidden_input_id.data).first() dict_inputs = parse_input_information() list_inputs_sorted = generate_form_input_list(dict_inputs) for each_input in list_inputs_sorted: if selected_input.device == each_input[0]: input_device_name = each_input[1] if backend_stage in ['point_enter_uS', 'dry', 'low', 'high']: time.sleep(2) # Sleep makes querying sensor more stable # Determine next ui_stage if backend_stage == 'point_enter_uS': next_stage = 'dry' logger.error("next_stage: {}".format(next_stage)) elif backend_stage == 'dry': next_stage = list_point_calibrations[0] logger.error("next_stage: {}".format(next_stage)) else: current_stage_index = list_point_calibrations.index(backend_stage) if current_stage_index == len(list_point_calibrations) - 1: next_stage = 'complete' else: next_stage = list_point_calibrations[current_stage_index + 1] if backend_stage == 'point_enter_uS': ui_stage = next_stage complete_with_error = None elif backend_stage == 'dry': ui_stage, complete_with_error = dual_commands_to_sensor( selected_input, 'ec_dry', None, 'continuous', current_stage='dry', next_stage=next_stage) elif backend_stage == 'low': ui_stage, complete_with_error = dual_commands_to_sensor( selected_input, 'ec_low', point_low_uS, 'continuous', current_stage='low', next_stage=next_stage) elif backend_stage == 'high': ui_stage, complete_with_error = dual_commands_to_sensor( selected_input, 'ec_high', point_high_uS, 'end', current_stage='high', next_stage=next_stage) return render_template( 'tools/calibration_options/atlas_ec.html', complete_with_error=complete_with_error, form_ec_calibrate=form_ec_calibrate, input=input_dev, input_device_name=input_device_name, point_high_uS=point_high_uS, point_low_uS=point_low_uS, selected_input=selected_input, selected_point_calibration=selected_point_calibration, ui_stage=ui_stage)
def measurement_mod(form): messages = {"success": [], "info": [], "warning": [], "error": []} mod_device = None device_info = None try: mod_meas = DeviceMeasurements.query.filter( DeviceMeasurements.unique_id == form.measurement_id.data).first() if not mod_meas: messages["error"].append("Count not found measurement") controller_type = determine_controller_type(mod_meas.device_id) if controller_type == "Input": mod_device = Input.query.filter( Input.unique_id == mod_meas.device_id).first() device_info = parse_input_information() elif controller_type == "Function_Custom": mod_device = CustomController.query.filter( CustomController.unique_id == mod_meas.device_id).first() device_info = parse_function_information() if not mod_device or not device_info: logger.error("Could not find mod_device or device_info") return if mod_device.is_activated: messages["error"].append( gettext("Deactivate controller before modifying its settings")) mod_meas.name = form.name.data if form.device_type.data == 'measurement_select': if not form.select_measurement_unit.data: messages["error"].append("Must select a measurement unit") else: mod_meas.measurement = form.select_measurement_unit.data.split( ',')[0] mod_meas.unit = form.select_measurement_unit.data.split(',')[1] elif form.device_type.data == 'measurement_convert': if ('enable_channel_unit_select' in device_info[mod_device.device] and device_info[ mod_device.device]['enable_channel_unit_select']): if ',' in form.select_measurement_unit.data: mod_meas.measurement = form.select_measurement_unit.data.split( ',')[0] mod_meas.unit = form.select_measurement_unit.data.split( ',')[1] else: mod_meas.measurement = '' mod_meas.unit = '' if form.rescaled_measurement_unit.data != '' and ',' in form.rescaled_measurement_unit.data: mod_meas.rescaled_measurement = form.rescaled_measurement_unit.data.split( ',')[0] mod_meas.rescaled_unit = form.rescaled_measurement_unit.data.split( ',')[1] elif form.rescaled_measurement_unit.data == '': mod_meas.rescaled_measurement = '' mod_meas.rescaled_unit = '' mod_meas.rescale_method = form.rescale_method.data mod_meas.rescale_equation = form.rescale_equation.data mod_meas.scale_from_min = form.scale_from_min.data mod_meas.scale_from_max = form.scale_from_max.data mod_meas.scale_to_min = form.scale_to_min.data mod_meas.scale_to_max = form.scale_to_max.data mod_meas.invert_scale = form.invert_scale.data mod_meas.conversion_id = form.convert_to_measurement_unit.data if not messages["error"]: db.session.commit() messages["success"].append("Measurement settings saved") except Exception as except_msg: logger.exception(1) messages["error"].append(str(except_msg)) return messages
def return_dependencies(device_type): unmet_deps = [] met_deps = False dict_inputs = parse_input_information() list_dependencies = [ dict_inputs, FUNCTION_ACTION_INFO, FUNCTION_INFO, LCD_INFO, MATH_INFO, METHOD_INFO, OUTPUT_INFO, CALIBRATION_INFO ] for each_section in list_dependencies: if device_type in each_section: for each_device, each_dict in each_section[device_type].items(): if not each_dict: met_deps = True elif each_device == 'dependencies_module': for (install_type, package, install_id) in each_dict: entry = ( package, '{0} {1}'.format(install_type, install_id), install_type, install_id ) if install_type in ['pip-pypi', 'pip-git']: try: module = importlib.util.find_spec(package) if module is None: if entry not in unmet_deps: unmet_deps.append(entry) else: met_deps = True except ImportError: if entry not in unmet_deps: unmet_deps.append(entry) elif install_type == 'apt': if (not dpkg_package_exists(package) and entry not in unmet_deps): unmet_deps.append(entry) else: met_deps = True elif install_type == 'internal': if package.startswith('file-exists'): filepath = package.split(' ', 1)[1] if not os.path.isfile(filepath): if entry not in unmet_deps: unmet_deps.append(entry) else: met_deps = True elif package.startswith('pip-exists'): py_module = package.split(' ', 1)[1] try: module = importlib.util.find_spec(py_module) if module is None: if entry not in unmet_deps: unmet_deps.append(entry) else: met_deps = True except ImportError: if entry not in unmet_deps: unmet_deps.append(entry) elif package.startswith('apt'): if (not dpkg_package_exists(package) and entry not in unmet_deps): unmet_deps.append(entry) else: met_deps = True return unmet_deps, met_deps
def input_mod(form_mod, request_form): action = '{action} {controller}'.format( action=TRANSLATIONS['modify']['title'], controller=TRANSLATIONS['input']['title']) error = [] dict_inputs = parse_input_information() try: mod_input = Input.query.filter( Input.unique_id == form_mod.input_id.data).first() if mod_input.is_activated: error.append(gettext( "Deactivate controller before modifying its settings")) if (mod_input.device == 'AM2315' and form_mod.period.data < 7): error.append(gettext( "Choose a Read Period equal to or greater than 7. The " "AM2315 may become unresponsive if the period is " "below 7.")) if (mod_input.device != 'EDGE' and (mod_input.pre_output_duration and form_mod.period.data < mod_input.pre_output_duration)): error.append(gettext( "The Read Period cannot be less than the Pre Output " "Duration")) if (form_mod.uart_location.data and not os.path.exists(form_mod.uart_location.data)): error.append(gettext( "Invalid device or improper permissions to read device")) mod_input.name = form_mod.name.data if form_mod.location.data: mod_input.location = form_mod.location.data if form_mod.i2c_location.data: mod_input.i2c_location = form_mod.i2c_location.data if form_mod.ftdi_location.data: mod_input.ftdi_location = form_mod.ftdi_location.data if form_mod.uart_location.data: mod_input.uart_location = form_mod.uart_location.data if form_mod.gpio_location.data: mod_input.gpio_location = form_mod.gpio_location.data if form_mod.power_output_id.data: mod_input.power_output_id = form_mod.power_output_id.data else: mod_input.power_output_id = None if form_mod.pre_output_id.data: mod_input.pre_output_id = form_mod.pre_output_id.data else: mod_input.pre_output_id = None # Enable/disable Channels measurements = DeviceMeasurements.query.filter( DeviceMeasurements.device_id == form_mod.input_id.data).all() if form_mod.measurements_enabled.data: for each_measurement in measurements: if each_measurement.unique_id in form_mod.measurements_enabled.data: each_measurement.is_enabled = True else: each_measurement.is_enabled = False mod_input.i2c_bus = form_mod.i2c_bus.data mod_input.baud_rate = form_mod.baud_rate.data mod_input.pre_output_duration = form_mod.pre_output_duration.data mod_input.pre_output_during_measure = form_mod.pre_output_during_measure.data mod_input.period = form_mod.period.data mod_input.resolution = form_mod.resolution.data mod_input.resolution_2 = form_mod.resolution_2.data mod_input.sensitivity = form_mod.sensitivity.data mod_input.calibrate_sensor_measure = form_mod.calibrate_sensor_measure.data mod_input.cmd_command = form_mod.cmd_command.data mod_input.thermocouple_type = form_mod.thermocouple_type.data mod_input.ref_ohm = form_mod.ref_ohm.data # Serial options mod_input.pin_clock = form_mod.pin_clock.data mod_input.pin_cs = form_mod.pin_cs.data mod_input.pin_mosi = form_mod.pin_mosi.data mod_input.pin_miso = form_mod.pin_miso.data # Bluetooth options mod_input.bt_adapter = form_mod.bt_adapter.data mod_input.adc_gain = form_mod.adc_gain.data mod_input.adc_resolution = form_mod.adc_resolution.data mod_input.adc_sample_speed = form_mod.adc_sample_speed.data # Switch options mod_input.switch_edge = form_mod.switch_edge.data mod_input.switch_bouncetime = form_mod.switch_bouncetime.data mod_input.switch_reset_period = form_mod.switch_reset_period.data # PWM and RPM options mod_input.weighting = form_mod.weighting.data mod_input.rpm_pulses_per_rev = form_mod.rpm_pulses_per_rev.data mod_input.sample_time = form_mod.sample_time.data # Server options mod_input.port = form_mod.port.data mod_input.times_check = form_mod.times_check.data mod_input.deadline = form_mod.deadline.data # SHT sensor options if form_mod.sht_voltage.data: mod_input.sht_voltage = form_mod.sht_voltage.data # Custom options list_options = [] if 'custom_options' in dict_inputs[mod_input.device]: for each_option in dict_inputs[mod_input.device]['custom_options']: null_value = True for key in request_form.keys(): if each_option['id'] == key: constraints_pass = True constraints_errors = [] value = None if each_option['type'] == 'float': if str_is_float(request_form.get(key)): if 'constraints_pass' in each_option: (constraints_pass, constraints_errors, mod_input) = each_option['constraints_pass']( mod_input, float(request_form.get(key))) if constraints_pass: value = float(request_form.get(key)) else: error.append( "{name} must represent a float/decimal value " "(submitted '{value}')".format( name=each_option['name'], value=request_form.get(key))) elif each_option['type'] == 'integer': if is_int(request_form.get(key)): if 'constraints_pass' in each_option: (constraints_pass, constraints_errors, mod_input) = each_option['constraints_pass']( mod_input, int(request_form.get(key))) if constraints_pass: value = int(request_form.get(key)) else: error.append( "{name} must represent an integer value " "(submitted '{value}')".format( name=each_option['name'], value=request_form.get(key))) elif each_option['type'] in ['text', 'select']: if 'constraints_pass' in each_option: (constraints_pass, constraints_errors, mod_input) = each_option['constraints_pass']( mod_input, request_form.get(key)) if constraints_pass: value = request_form.get(key) elif each_option['type'] == 'bool': value = bool(request_form.get(key)) for each_error in constraints_errors: error.append( "Error: {name}: {error}".format( name=each_option['name'], error=each_error)) if value: null_value = False option = '{id},{value}'.format( id=key, value=value) list_options.append(option) if null_value: option = '{id},'.format(id=each_option['id']) list_options.append(option) mod_input.custom_options = ';'.join(list_options) if not error: db.session.commit() except Exception as except_msg: error.append(except_msg) flash_success_errors(error, action, url_for('routes_page.page_data'))
def input_add(form_add): action = '{action} {controller}'.format( action=TRANSLATIONS['add']['title'], controller=TRANSLATIONS['input']['title']) error = [] dict_inputs = parse_input_information() # only one comma should be in the input_type string if form_add.input_type.data.count(',') > 1: error.append("Invalid input module formatting. It appears there is " "a comma in either 'input_name_unique' or 'interfaces'.") if form_add.input_type.data.count(',') == 1: input_name = form_add.input_type.data.split(',')[0] input_interface = form_add.input_type.data.split(',')[1] else: input_name = '' input_interface = '' error.append("Invalid input string (must be a comma-separated string)") if current_app.config['TESTING']: dep_unmet = False else: dep_unmet, _ = return_dependencies(input_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=input_name, dep=', '.join(list_unmet_deps))) if form_add.validate(): new_input = Input() new_input.device = input_name if input_interface: new_input.interface = input_interface if GPIO.RPI_INFO['P1_REVISION'] in [2, 3]: new_input.i2c_bus = 1 else: new_input.i2c_bus = 0 if 'input_name' in dict_inputs[input_name]: new_input.name = dict_inputs[input_name]['input_name'] else: new_input.name = 'Input Name' # # Set default values for new input being added # # input add options if input_name in dict_inputs: def dict_has_value(key): if (key in dict_inputs[input_name] and (dict_inputs[input_name][key] or dict_inputs[input_name][key] == 0)): return True # # Interfacing options # # I2C options if input_interface == 'I2C': if dict_has_value('i2c_location'): new_input.i2c_location = dict_inputs[input_name]['i2c_location'][0] # First entry in list # UART options if dict_has_value('uart_location'): new_input.uart_location = dict_inputs[input_name]['uart_location'] if dict_has_value('ftdi_location'): new_input.uart_location = dict_inputs[input_name]['ftdi_location'] if dict_has_value('uart_baud_rate'): new_input.baud_rate = dict_inputs[input_name]['uart_baud_rate'] if dict_has_value('pin_cs'): new_input.pin_cs = dict_inputs[input_name]['pin_cs'] if dict_has_value('pin_miso'): new_input.pin_miso = dict_inputs[input_name]['pin_miso'] if dict_has_value('pin_mosi'): new_input.pin_mosi = dict_inputs[input_name]['pin_mosi'] if dict_has_value('pin_clock'): new_input.pin_clock = dict_inputs[input_name]['pin_clock'] # Bluetooth (BT) options elif input_interface == 'BT': if dict_has_value('bt_location'): new_input.location = dict_inputs[input_name]['bt_location'] if dict_has_value('bt_adapter'): new_input.bt_adapter = dict_inputs[input_name]['bt_adapter'] # GPIO options elif input_interface == 'GPIO': if dict_has_value('gpio_location'): new_input.gpio_location = dict_inputs[input_name]['gpio_location'] # Custom location location elif dict_has_value('location'): new_input.location = dict_inputs[input_name]['location']['options'][0][0] # First entry in list # # General options # if dict_has_value('period'): new_input.period = dict_inputs[input_name]['period'] # Server Ping options if dict_has_value('times_check'): new_input.times_check = dict_inputs[input_name]['times_check'] if dict_has_value('deadline'): new_input.deadline = dict_inputs[input_name]['deadline'] if dict_has_value('port'): new_input.port = dict_inputs[input_name]['port'] # Signal options if dict_has_value('weighting'): new_input.weighting = dict_inputs[input_name]['weighting'] if dict_has_value('sample_time'): new_input.sample_time = dict_inputs[input_name]['sample_time'] # Analog-to-digital converter options if dict_has_value('adc_gain'): if len(dict_inputs[input_name]['adc_gain']) == 1: new_input.adc_gain = dict_inputs[input_name]['adc_gain'][0] elif len(dict_inputs[input_name]['adc_gain']) > 1: new_input.adc_gain = dict_inputs[input_name]['adc_gain'][0][0] if dict_has_value('adc_resolution'): if len(dict_inputs[input_name]['adc_resolution']) == 1: new_input.adc_resolution = dict_inputs[input_name]['adc_resolution'][0] elif len(dict_inputs[input_name]['adc_resolution']) > 1: new_input.adc_resolution = dict_inputs[input_name]['adc_resolution'][0][0] if dict_has_value('adc_sample_speed'): if len(dict_inputs[input_name]['adc_sample_speed']) == 1: new_input.adc_sample_speed = dict_inputs[input_name]['adc_sample_speed'][0] elif len(dict_inputs[input_name]['adc_sample_speed']) > 1: new_input.adc_sample_speed = dict_inputs[input_name]['adc_sample_speed'][0][0] # Linux command if dict_has_value('cmd_command'): new_input.cmd_command = dict_inputs[input_name]['cmd_command'] # Misc options if dict_has_value('resolution'): if len(dict_inputs[input_name]['resolution']) == 1: new_input.resolution = dict_inputs[input_name]['resolution'][0] elif len(dict_inputs[input_name]['resolution']) > 1: new_input.resolution = dict_inputs[input_name]['resolution'][0][0] if dict_has_value('resolution_2'): if len(dict_inputs[input_name]['resolution_2']) == 1: new_input.resolution_2 = dict_inputs[input_name]['resolution_2'][0] elif len(dict_inputs[input_name]['resolution_2']) > 1: new_input.resolution_2 = dict_inputs[input_name]['resolution_2'][0][0] if dict_has_value('sensitivity'): if len(dict_inputs[input_name]['sensitivity']) == 1: new_input.sensitivity = dict_inputs[input_name]['sensitivity'][0] elif len(dict_inputs[input_name]['sensitivity']) > 1: new_input.sensitivity = dict_inputs[input_name]['sensitivity'][0][0] if dict_has_value('thermocouple_type'): if len(dict_inputs[input_name]['thermocouple_type']) == 1: new_input.thermocouple_type = dict_inputs[input_name]['thermocouple_type'][0] elif len(dict_inputs[input_name]['thermocouple_type']) > 1: new_input.thermocouple_type = dict_inputs[input_name]['thermocouple_type'][0][0] if dict_has_value('sht_voltage'): if len(dict_inputs[input_name]['sht_voltage']) == 1: new_input.sht_voltage = dict_inputs[input_name]['sht_voltage'][0] elif len(dict_inputs[input_name]['sht_voltage']) > 1: new_input.sht_voltage = dict_inputs[input_name]['sht_voltage'][0][0] if dict_has_value('ref_ohm'): new_input.ref_ohm = dict_inputs[input_name]['ref_ohm'] # # Custom Options # list_options = [] if 'custom_options' in dict_inputs[input_name]: for each_option in dict_inputs[input_name]['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_input.custom_options = ';'.join(list_options) try: if not error: new_input.save() display_order = csv_to_list_of_str( DisplayOrder.query.first().inputs) DisplayOrder.query.first().inputs = add_display_order( display_order, new_input.unique_id) db.session.commit() if ('measurements_dict' in dict_inputs[input_name] and dict_inputs[input_name]['measurements_dict'] != []): for each_channel in dict_inputs[input_name]['measurements_dict']: measure_info = dict_inputs[input_name]['measurements_dict'][each_channel] new_measurement = DeviceMeasurements() if 'name' in measure_info: new_measurement.name = measure_info['name'] new_measurement.device_id = new_input.unique_id new_measurement.measurement = measure_info['measurement'] new_measurement.unit = measure_info['unit'] new_measurement.channel = each_channel new_measurement.save() flash(gettext( "%(type)s Input with ID %(id)s (%(uuid)s) successfully added", type=input_name, id=new_input.id, uuid=new_input.unique_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_data')) else: flash_form_errors(form_add) if dep_unmet: return 1
def initialize_variables(self): self.dict_inputs = parse_input_information() self.sample_rate = db_retrieve_table_daemon( Misc, entry='first').sample_rate_controller_input input_dev = db_retrieve_table_daemon(Input, unique_id=self.unique_id) self.device_measurements = db_retrieve_table_daemon( DeviceMeasurements).filter( DeviceMeasurements.device_id == self.unique_id) self.conversions = db_retrieve_table_daemon(Conversion) self.input_dev = input_dev self.input_name = input_dev.name self.unique_id = input_dev.unique_id self.log_level_debug = input_dev.log_level_debug self.gpio_location = input_dev.gpio_location self.device = input_dev.device self.interface = input_dev.interface self.period = input_dev.period self.start_offset = input_dev.start_offset # Edge detection self.switch_edge = input_dev.switch_edge self.switch_bouncetime = input_dev.switch_bouncetime self.switch_reset_period = input_dev.switch_reset_period # Pre-Output: Activates prior to input measurement self.pre_output_id = input_dev.pre_output_id self.pre_output_duration = input_dev.pre_output_duration self.pre_output_during_measure = input_dev.pre_output_during_measure self.pre_output_setup = False self.last_measurement = 0 self.next_measurement = time.time() + self.start_offset self.get_new_measurement = False self.trigger_cond = False self.measurement_acquired = False self.pre_output_activated = False self.pre_output_locked = False self.pre_output_timer = time.time() self.set_log_level_debug(self.log_level_debug) # Check if Pre-Output ID actually exists output = db_retrieve_table_daemon(Output, entry='all') for each_output in output: if (each_output.unique_id == self.pre_output_id and self.pre_output_duration): self.pre_output_setup = True smtp = db_retrieve_table_daemon(SMTP, entry='first') self.smtp_max_count = smtp.hourly_max self.email_count = 0 self.allowed_to_send_notice = True # Set up input lock self.input_lock = None self.lock_file = '/var/lock/input_pre_output_{id}'.format( id=self.pre_output_id) # Convert string I2C address to base-16 int if self.interface == 'I2C': self.i2c_address = int(str(self.input_dev.i2c_location), 16) # Set up edge detection of a GPIO pin if self.device == 'EDGE': if self.switch_edge == 'rising': self.switch_edge_gpio = GPIO.RISING elif self.switch_edge == 'falling': self.switch_edge_gpio = GPIO.FALLING else: self.switch_edge_gpio = GPIO.BOTH self.device_recognized = True if self.device in self.dict_inputs: input_loaded = load_module_from_file( self.dict_inputs[self.device]['file_path'], 'inputs') if self.device == 'EDGE': # Edge detection handled internally, no module to load self.measure_input = None else: self.measure_input = input_loaded.InputModule(self.input_dev) else: self.device_recognized = False self.logger.debug( "Device '{device}' not recognized".format(device=self.device)) raise Exception("'{device}' is not a valid device type.".format( device=self.device)) self.edge_reset_timer = time.time() self.input_timer = time.time() self.lastUpdate = None # Set up edge detection if self.device == 'EDGE': GPIO.setmode(GPIO.BCM) GPIO.setup(int(self.gpio_location), GPIO.IN) GPIO.add_event_detect(int(self.gpio_location), self.switch_edge_gpio, callback=self.edge_detected, bouncetime=self.switch_bouncetime) # Set up MQTT listener elif ('listener' in self.dict_inputs[self.device] and self.dict_inputs[self.device]['listener']): input_listener = threading.Thread( target=self.measure_input.listener()) input_listener.daemon = True input_listener.start()
def __init__(self, ready, input_id): threading.Thread.__init__(self) self.logger = logging.getLogger( "mycodo.input_{id}".format(id=input_id.split('-')[0])) self.stop_iteration_counter = 0 self.thread_startup_timer = timeit.default_timer() self.thread_shutdown_timer = 0 self.ready = ready self.lock = {} self.measurement = None self.measurement_success = False self.control = DaemonControl() self.pause_loop = False self.verify_pause_loop = True self.force_measurements_trigger = False self.dict_inputs = parse_input_information() self.sample_rate = db_retrieve_table_daemon( Misc, entry='first').sample_rate_controller_input self.input_id = input_id input_dev = db_retrieve_table_daemon( Input, unique_id=self.input_id) self.device_measurements = db_retrieve_table_daemon( DeviceMeasurements).filter( DeviceMeasurements.device_id == self.input_id) self.conversions = db_retrieve_table_daemon(Conversion) self.input_dev = input_dev self.input_name = input_dev.name self.unique_id = input_dev.unique_id self.gpio_location = input_dev.gpio_location self.device = input_dev.device self.interface = input_dev.interface self.period = input_dev.period # Edge detection self.switch_edge = input_dev.switch_edge self.switch_bouncetime = input_dev.switch_bouncetime self.switch_reset_period = input_dev.switch_reset_period # Pre-Output: Activates prior to input measurement self.pre_output_id = input_dev.pre_output_id self.pre_output_duration = input_dev.pre_output_duration self.pre_output_during_measure = input_dev.pre_output_during_measure self.pre_output_setup = False self.next_measurement = time.time() self.get_new_measurement = False self.trigger_cond = False self.measurement_acquired = False self.pre_output_activated = False self.pre_output_locked = False self.pre_output_timer = time.time() # Check if Pre-Output ID actually exists output = db_retrieve_table_daemon(Output, entry='all') for each_output in output: if each_output.unique_id == self.pre_output_id and self.pre_output_duration: self.pre_output_setup = True smtp = db_retrieve_table_daemon(SMTP, entry='first') self.smtp_max_count = smtp.hourly_max self.email_count = 0 self.allowed_to_send_notice = True # Set up input lock self.input_lock = None self.lock_file = '/var/lock/input_pre_output_{id}'.format(id=self.pre_output_id) # Convert string I2C address to base-16 int if self.interface == 'I2C': self.i2c_address = int(str(self.input_dev.i2c_location), 16) # Set up edge detection of a GPIO pin if self.device == 'EDGE': if self.switch_edge == 'rising': self.switch_edge_gpio = GPIO.RISING elif self.switch_edge == 'falling': self.switch_edge_gpio = GPIO.FALLING else: self.switch_edge_gpio = GPIO.BOTH self.device_recognized = True if self.device in self.dict_inputs: input_loaded = load_module_from_file(self.dict_inputs[self.device]['file_path']) if self.device == 'EDGE': # Edge detection handled internally, no module to load self.measure_input = None else: self.measure_input = input_loaded.InputModule(self.input_dev) else: self.device_recognized = False self.logger.debug("Device '{device}' not recognized".format( device=self.device)) raise Exception("'{device}' is not a valid device type.".format( device=self.device)) self.edge_reset_timer = time.time() self.input_timer = time.time() self.running = False self.lastUpdate = None
def input_mod(form_mod, request_form): messages = { "success": [], "info": [], "warning": [], "error": [], "name": None, "return_text": [] } page_refresh = False dict_inputs = parse_input_information() try: mod_input = Input.query.filter( Input.unique_id == form_mod.input_id.data).first() if mod_input.is_activated: messages["error"].append( gettext("Deactivate controller before modifying its settings")) if (mod_input.device == 'AM2315' and form_mod.period.data < 7): messages["error"].append( gettext("Choose a Read Period equal to or greater than 7. The " "AM2315 may become unresponsive if the period is " "below 7.")) if (form_mod.period.data and form_mod.pre_output_duration.data and form_mod.pre_output_id.data and form_mod.period.data < form_mod.pre_output_duration.data): messages["error"].append( gettext( "The Read Period cannot be less than the Pre Output Duration" )) if (form_mod.uart_location.data and not os.path.exists(form_mod.uart_location.data)): messages["warning"].append( gettext( "Invalid device or improper permissions to read device")) if ('options_enabled' in dict_inputs[mod_input.device] and 'gpio_location' in dict_inputs[mod_input.device]['options_enabled'] and form_mod.gpio_location.data is None): messages["error"].append(gettext("Pin (GPIO) must be set")) mod_input.name = form_mod.name.data messages["name"] = form_mod.name.data if form_mod.location.data: mod_input.location = form_mod.location.data if form_mod.i2c_location.data: mod_input.i2c_location = form_mod.i2c_location.data if form_mod.ftdi_location.data: mod_input.ftdi_location = form_mod.ftdi_location.data if form_mod.uart_location.data: mod_input.uart_location = form_mod.uart_location.data if form_mod.gpio_location.data and form_mod.gpio_location.data is not None: mod_input.gpio_location = form_mod.gpio_location.data if form_mod.power_output_id.data: mod_input.power_output_id = form_mod.power_output_id.data else: mod_input.power_output_id = None if form_mod.pre_output_id.data: mod_input.pre_output_id = form_mod.pre_output_id.data else: mod_input.pre_output_id = None # Enable/disable Channels measurements = DeviceMeasurements.query.filter( DeviceMeasurements.device_id == form_mod.input_id.data).all() if form_mod.measurements_enabled.data: for each_measurement in measurements: if each_measurement.unique_id in form_mod.measurements_enabled.data: each_measurement.is_enabled = True else: each_measurement.is_enabled = False mod_input.log_level_debug = form_mod.log_level_debug.data mod_input.i2c_bus = form_mod.i2c_bus.data mod_input.baud_rate = form_mod.baud_rate.data mod_input.pre_output_duration = form_mod.pre_output_duration.data mod_input.pre_output_during_measure = form_mod.pre_output_during_measure.data if form_mod.period.data: mod_input.period = form_mod.period.data if form_mod.start_offset.data: mod_input.start_offset = form_mod.start_offset.data mod_input.resolution = form_mod.resolution.data mod_input.resolution_2 = form_mod.resolution_2.data mod_input.sensitivity = form_mod.sensitivity.data mod_input.calibrate_sensor_measure = form_mod.calibrate_sensor_measure.data mod_input.cmd_command = form_mod.cmd_command.data mod_input.thermocouple_type = form_mod.thermocouple_type.data mod_input.ref_ohm = form_mod.ref_ohm.data # Serial options mod_input.pin_clock = form_mod.pin_clock.data mod_input.pin_cs = form_mod.pin_cs.data mod_input.pin_mosi = form_mod.pin_mosi.data mod_input.pin_miso = form_mod.pin_miso.data # Bluetooth options mod_input.bt_adapter = form_mod.bt_adapter.data mod_input.adc_gain = form_mod.adc_gain.data mod_input.adc_resolution = form_mod.adc_resolution.data mod_input.adc_sample_speed = form_mod.adc_sample_speed.data # Switch options mod_input.switch_edge = form_mod.switch_edge.data mod_input.switch_bouncetime = form_mod.switch_bouncetime.data mod_input.switch_reset_period = form_mod.switch_reset_period.data # PWM and RPM options mod_input.weighting = form_mod.weighting.data mod_input.rpm_pulses_per_rev = form_mod.rpm_pulses_per_rev.data mod_input.sample_time = form_mod.sample_time.data # Server options mod_input.port = form_mod.port.data mod_input.times_check = form_mod.times_check.data mod_input.deadline = form_mod.deadline.data # SHT sensor options if form_mod.sht_voltage.data: mod_input.sht_voltage = form_mod.sht_voltage.data channels = InputChannel.query.filter( InputChannel.input_id == form_mod.input_id.data) # Save Measurement settings messages, page_refresh = utils_measurement.measurement_mod_form( messages, page_refresh, request_form) # Add or delete channels for variable measurement Inputs if ('measurements_variable_amount' in dict_inputs[mod_input.device] and dict_inputs[mod_input.device]['measurements_variable_amount']): measurements = DeviceMeasurements.query.filter( DeviceMeasurements.device_id == form_mod.input_id.data) if measurements.count() != form_mod.num_channels.data: page_refresh = True # Delete measurements/channels if form_mod.num_channels.data < measurements.count(): for index, each_channel in enumerate(measurements.all()): if index + 1 > form_mod.num_channels.data: delete_entry_with_id(DeviceMeasurements, each_channel.unique_id, flash_message=False) if ('channel_quantity_same_as_measurements' in dict_inputs[mod_input.device] and dict_inputs[mod_input.device] ["channel_quantity_same_as_measurements"]): if form_mod.num_channels.data < channels.count(): for index, each_channel in enumerate( channels.all()): if index + 1 > form_mod.num_channels.data: delete_entry_with_id( InputChannel, each_channel.unique_id, flash_message=False) # Add measurements/channels elif form_mod.num_channels.data > measurements.count(): start_number = measurements.count() for index in range(start_number, form_mod.num_channels.data): new_measurement = DeviceMeasurements() new_measurement.name = "" new_measurement.device_id = mod_input.unique_id new_measurement.measurement = "" new_measurement.unit = "" new_measurement.channel = index new_measurement.save() if ('channel_quantity_same_as_measurements' in dict_inputs[mod_input.device] and dict_inputs[mod_input.device] ["channel_quantity_same_as_measurements"]): new_channel = InputChannel() new_channel.name = "" new_channel.input_id = mod_input.unique_id new_channel.channel = index messages[ "error"], custom_options = custom_channel_options_return_json( messages["error"], dict_inputs, request_form, mod_input.unique_id, index, device=mod_input.device, use_defaults=True) new_channel.custom_options = custom_options new_channel.save() # Parse pre-save custom options for output device and its channels try: custom_options_dict_presave = json.loads(mod_input.custom_options) except: logger.error("Malformed JSON") custom_options_dict_presave = {} custom_options_channels_dict_presave = {} for each_channel in channels.all(): if each_channel.custom_options and each_channel.custom_options != "{}": custom_options_channels_dict_presave[ each_channel.channel] = json.loads( each_channel.custom_options) else: custom_options_channels_dict_presave[each_channel.channel] = {} # Parse post-save custom options for output device and its channels messages[ "error"], custom_options_json_postsave = custom_options_return_json( messages["error"], dict_inputs, request_form, mod_dev=mod_input, device=mod_input.device) custom_options_dict_postsave = json.loads(custom_options_json_postsave) custom_options_channels_dict_postsave = {} for each_channel in channels.all(): messages[ "error"], custom_options_channels_json_postsave_tmp = custom_channel_options_return_json( messages["error"], dict_inputs, request_form, form_mod.input_id.data, each_channel.channel, device=mod_input.device, use_defaults=False) custom_options_channels_dict_postsave[ each_channel.channel] = json.loads( custom_options_channels_json_postsave_tmp) if 'execute_at_modification' in dict_inputs[mod_input.device]: # pass custom options to module prior to saving to database (messages, mod_input, custom_options_dict, custom_options_channels_dict ) = dict_inputs[mod_input.device]['execute_at_modification']( messages, mod_input, request_form, custom_options_dict_presave, custom_options_channels_dict_presave, custom_options_dict_postsave, custom_options_channels_dict_postsave) custom_options = json.dumps( custom_options_dict) # Convert from dict to JSON string custom_channel_options = custom_options_channels_dict else: # Don't pass custom options to module custom_options = json.dumps(custom_options_dict_postsave) custom_channel_options = custom_options_channels_dict_postsave # Finally, save custom options for both output and channels mod_input.custom_options = custom_options for each_channel in channels: if 'name' in custom_channel_options[each_channel.channel]: each_channel.name = custom_channel_options[ each_channel.channel]['name'] each_channel.custom_options = json.dumps( custom_channel_options[each_channel.channel]) if not messages["error"]: db.session.commit() messages["success"].append( f"{TRANSLATIONS['modify']['title']} {TRANSLATIONS['input']['title']}" ) except Exception as except_msg: logger.exception("input_mod") messages["error"].append(str(except_msg)) return messages, page_refresh
def input_add(form_add): messages = {"success": [], "info": [], "warning": [], "error": []} new_input_id = None list_unmet_deps = [] dep_name = None dep_message = '' dict_inputs = parse_input_information() # only one comma should be in the input_type string if form_add.input_type.data.count(',') > 1: messages["error"].append( "Invalid input module formatting. It appears there is " "a comma in either 'input_name_unique' or 'interfaces'.") if form_add.input_type.data.count(',') == 1: input_name = form_add.input_type.data.split(',')[0] input_interface = form_add.input_type.data.split(',')[1] else: input_name = '' input_interface = '' messages["error"].append( "Invalid input string (must be a comma-separated string)") if not current_app.config['TESTING']: dep_unmet, _, dep_message = return_dependencies(input_name) if dep_unmet: for each_dep in dep_unmet: list_unmet_deps.append(each_dep[3]) messages["error"].append( f"{input_name} has unmet dependencies. They must be installed before the Input can be added." ) if input_name in dict_inputs: dep_name = dict_inputs[input_name]['input_name'] else: messages["error"].append(f"Input not found: {input_name}") return messages, dep_name, list_unmet_deps, dep_message, None if form_add.validate(): new_input = Input() new_input.device = input_name new_input.position_y = 999 if input_interface: new_input.interface = input_interface new_input.i2c_bus = 1 if 'input_name_short' in dict_inputs[input_name]: new_input.name = dict_inputs[input_name]['input_name_short'] elif 'input_name' in dict_inputs[input_name]: new_input.name = dict_inputs[input_name]['input_name'] else: new_input.name = 'Name' # # Set default values for new input being added # # input add options if input_name in dict_inputs: def dict_has_value(key): if (key in dict_inputs[input_name] and (dict_inputs[input_name][key] or dict_inputs[input_name][key] == 0)): return True # # Interfacing options # if input_interface == 'I2C': if dict_has_value('i2c_location'): new_input.i2c_location = dict_inputs[input_name][ 'i2c_location'][0] # First entry in list if input_interface == 'FTDI': if dict_has_value('ftdi_location'): new_input.ftdi_location = dict_inputs[input_name][ 'ftdi_location'] if input_interface == 'UART': if dict_has_value('uart_location'): new_input.uart_location = dict_inputs[input_name][ 'uart_location'] # UART options if dict_has_value('uart_baud_rate'): new_input.baud_rate = dict_inputs[input_name]['uart_baud_rate'] if dict_has_value('pin_cs'): new_input.pin_cs = dict_inputs[input_name]['pin_cs'] if dict_has_value('pin_miso'): new_input.pin_miso = dict_inputs[input_name]['pin_miso'] if dict_has_value('pin_mosi'): new_input.pin_mosi = dict_inputs[input_name]['pin_mosi'] if dict_has_value('pin_clock'): new_input.pin_clock = dict_inputs[input_name]['pin_clock'] # Bluetooth (BT) options elif input_interface == 'BT': if dict_has_value('bt_location'): if not re.match( "[0-9a-fA-F]{2}([:]?)[0-9a-fA-F]{2}(\\1[0-9a-fA-F]{2}){4}$", dict_inputs[input_name]['bt_location']): messages["error"].append( "Please specify device MAC-Address in format AA:BB:CC:DD:EE:FF" ) else: new_input.location = dict_inputs[input_name][ 'bt_location'] if dict_has_value('bt_adapter'): new_input.bt_adapter = dict_inputs[input_name][ 'bt_adapter'] # GPIO options elif input_interface == 'GPIO': if dict_has_value('gpio_location'): new_input.gpio_location = dict_inputs[input_name][ 'gpio_location'] # Custom location location elif dict_has_value('location'): new_input.location = dict_inputs[input_name]['location'][ 'options'][0][0] # First entry in list # # General options # if dict_has_value('period'): new_input.period = dict_inputs[input_name]['period'] # Server Ping options if dict_has_value('times_check'): new_input.times_check = dict_inputs[input_name]['times_check'] if dict_has_value('deadline'): new_input.deadline = dict_inputs[input_name]['deadline'] if dict_has_value('port'): new_input.port = dict_inputs[input_name]['port'] # Signal options if dict_has_value('weighting'): new_input.weighting = dict_inputs[input_name]['weighting'] if dict_has_value('sample_time'): new_input.sample_time = dict_inputs[input_name]['sample_time'] # Analog-to-digital converter options if dict_has_value('adc_gain'): if len(dict_inputs[input_name]['adc_gain']) == 1: new_input.adc_gain = dict_inputs[input_name]['adc_gain'][0] elif len(dict_inputs[input_name]['adc_gain']) > 1: new_input.adc_gain = dict_inputs[input_name]['adc_gain'][ 0][0] if dict_has_value('adc_resolution'): if len(dict_inputs[input_name]['adc_resolution']) == 1: new_input.adc_resolution = dict_inputs[input_name][ 'adc_resolution'][0] elif len(dict_inputs[input_name]['adc_resolution']) > 1: new_input.adc_resolution = dict_inputs[input_name][ 'adc_resolution'][0][0] if dict_has_value('adc_sample_speed'): if len(dict_inputs[input_name]['adc_sample_speed']) == 1: new_input.adc_sample_speed = dict_inputs[input_name][ 'adc_sample_speed'][0] elif len(dict_inputs[input_name]['adc_sample_speed']) > 1: new_input.adc_sample_speed = dict_inputs[input_name][ 'adc_sample_speed'][0][0] # Linux command if dict_has_value('cmd_command'): new_input.cmd_command = dict_inputs[input_name]['cmd_command'] # Misc options if dict_has_value('resolution'): if len(dict_inputs[input_name]['resolution']) == 1: new_input.resolution = dict_inputs[input_name][ 'resolution'][0] elif len(dict_inputs[input_name]['resolution']) > 1: new_input.resolution = dict_inputs[input_name][ 'resolution'][0][0] if dict_has_value('resolution_2'): if len(dict_inputs[input_name]['resolution_2']) == 1: new_input.resolution_2 = dict_inputs[input_name][ 'resolution_2'][0] elif len(dict_inputs[input_name]['resolution_2']) > 1: new_input.resolution_2 = dict_inputs[input_name][ 'resolution_2'][0][0] if dict_has_value('sensitivity'): if len(dict_inputs[input_name]['sensitivity']) == 1: new_input.sensitivity = dict_inputs[input_name][ 'sensitivity'][0] elif len(dict_inputs[input_name]['sensitivity']) > 1: new_input.sensitivity = dict_inputs[input_name][ 'sensitivity'][0][0] if dict_has_value('thermocouple_type'): if len(dict_inputs[input_name]['thermocouple_type']) == 1: new_input.thermocouple_type = dict_inputs[input_name][ 'thermocouple_type'][0] elif len(dict_inputs[input_name]['thermocouple_type']) > 1: new_input.thermocouple_type = dict_inputs[input_name][ 'thermocouple_type'][0][0] if dict_has_value('sht_voltage'): if len(dict_inputs[input_name]['sht_voltage']) == 1: new_input.sht_voltage = dict_inputs[input_name][ 'sht_voltage'][0] elif len(dict_inputs[input_name]['sht_voltage']) > 1: new_input.sht_voltage = dict_inputs[input_name][ 'sht_voltage'][0][0] if dict_has_value('ref_ohm'): new_input.ref_ohm = dict_inputs[input_name]['ref_ohm'] # # Custom Options # # Generate string to save from custom options messages["error"], custom_options = custom_options_return_json( messages["error"], dict_inputs, device=input_name, use_defaults=True) new_input.custom_options = custom_options # # Execute at Creation # new_input.unique_id = set_uuid() if ('execute_at_creation' in dict_inputs[new_input.device] and not current_app.config['TESTING']): messages["error"], new_input = dict_inputs[ new_input.device]['execute_at_creation']( messages["error"], new_input, dict_inputs[new_input.device]) try: if not messages["error"]: new_input.save() new_input_id = new_input.unique_id # # If there are a variable number of measurements # if ('measurements_variable_amount' in dict_inputs[input_name] and dict_inputs[input_name] ['measurements_variable_amount']): # Add first default measurement with empty unit and measurement new_measurement = DeviceMeasurements() new_measurement.name = "" new_measurement.device_id = new_input.unique_id new_measurement.measurement = "" new_measurement.unit = "" new_measurement.channel = 0 new_measurement.save() # # If measurements defined in the Input Module # elif ('measurements_dict' in dict_inputs[input_name] and dict_inputs[input_name]['measurements_dict']): for each_channel in dict_inputs[input_name][ 'measurements_dict']: measure_info = dict_inputs[input_name][ 'measurements_dict'][each_channel] new_measurement = DeviceMeasurements() if 'name' in measure_info: new_measurement.name = measure_info['name'] new_measurement.device_id = new_input.unique_id new_measurement.measurement = measure_info[ 'measurement'] new_measurement.unit = measure_info['unit'] new_measurement.channel = each_channel new_measurement.save() if 'channels_dict' in dict_inputs[new_input.device]: for each_channel, channel_info in dict_inputs[ new_input.device]['channels_dict'].items(): new_channel = InputChannel() new_channel.channel = each_channel new_channel.input_id = new_input.unique_id # Generate string to save from custom options messages[ "error"], custom_options = custom_channel_options_return_json( messages["error"], dict_inputs, None, new_input.unique_id, each_channel, device=new_input.device, use_defaults=True) new_channel.custom_options = custom_options new_channel.save() messages["success"].append( f"{TRANSLATIONS['add']['title']} {TRANSLATIONS['input']['title']}" ) except sqlalchemy.exc.OperationalError as except_msg: messages["error"].append(except_msg) except sqlalchemy.exc.IntegrityError as except_msg: messages["error"].append(except_msg) else: for field, errors in form_add.errors.items(): for error in errors: messages["error"].append( gettext("Error in the %(field)s field - %(err)s", field=getattr(form_add, field).label.text, err=error)) return messages, dep_name, list_unmet_deps, dep_message, new_input_id
def input_add(form_add): action = '{action} {controller}'.format( action=TRANSLATIONS['add']['title'], controller=TRANSLATIONS['input']['title']) error = [] dict_inputs = parse_input_information() # only one comma should be in the input_type string if form_add.input_type.data.count(',') > 1: error.append("Invalid input module formatting. It appears there is " "a comma in either 'input_name_unique' or 'interfaces'.") if form_add.input_type.data.count(',') == 1: input_name = form_add.input_type.data.split(',')[0] input_interface = form_add.input_type.data.split(',')[1] else: input_name = '' input_interface = '' error.append("Invalid input string (must be a comma-separated string)") if current_app.config['TESTING']: dep_unmet = False else: dep_unmet, _ = return_dependencies(input_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=input_name, dep=', '.join(list_unmet_deps))) if form_add.validate(): new_input = Input() new_input.device = input_name if input_interface: new_input.interface = input_interface try: from RPi import GPIO if GPIO.RPI_INFO['P1_REVISION'] == 1: new_input.i2c_bus = 0 else: new_input.i2c_bus = 1 except: logger.error("RPi.GPIO and Raspberry Pi required for this action") if 'input_name' in dict_inputs[input_name]: new_input.name = dict_inputs[input_name]['input_name'] else: new_input.name = 'Name' # # Set default values for new input being added # # input add options if input_name in dict_inputs: def dict_has_value(key): if (key in dict_inputs[input_name] and (dict_inputs[input_name][key] or dict_inputs[input_name][key] == 0)): return True # # Interfacing options # if input_interface == 'I2C': if dict_has_value('i2c_location'): new_input.i2c_location = dict_inputs[input_name][ 'i2c_location'][0] # First entry in list if input_interface == 'FTDI': if dict_has_value('ftdi_location'): new_input.ftdi_location = dict_inputs[input_name][ 'ftdi_location'] if input_interface == 'UART': if dict_has_value('uart_location'): new_input.uart_location = dict_inputs[input_name][ 'uart_location'] # UART options if dict_has_value('uart_baud_rate'): new_input.baud_rate = dict_inputs[input_name]['uart_baud_rate'] if dict_has_value('pin_cs'): new_input.pin_cs = dict_inputs[input_name]['pin_cs'] if dict_has_value('pin_miso'): new_input.pin_miso = dict_inputs[input_name]['pin_miso'] if dict_has_value('pin_mosi'): new_input.pin_mosi = dict_inputs[input_name]['pin_mosi'] if dict_has_value('pin_clock'): new_input.pin_clock = dict_inputs[input_name]['pin_clock'] # Bluetooth (BT) options elif input_interface == 'BT': if dict_has_value('bt_location'): new_input.location = dict_inputs[input_name]['bt_location'] if dict_has_value('bt_adapter'): new_input.bt_adapter = dict_inputs[input_name][ 'bt_adapter'] # GPIO options elif input_interface == 'GPIO': if dict_has_value('gpio_location'): new_input.gpio_location = dict_inputs[input_name][ 'gpio_location'] # Custom location location elif dict_has_value('location'): new_input.location = dict_inputs[input_name]['location'][ 'options'][0][0] # First entry in list # # General options # if dict_has_value('period'): new_input.period = dict_inputs[input_name]['period'] # Server Ping options if dict_has_value('times_check'): new_input.times_check = dict_inputs[input_name]['times_check'] if dict_has_value('deadline'): new_input.deadline = dict_inputs[input_name]['deadline'] if dict_has_value('port'): new_input.port = dict_inputs[input_name]['port'] # Signal options if dict_has_value('weighting'): new_input.weighting = dict_inputs[input_name]['weighting'] if dict_has_value('sample_time'): new_input.sample_time = dict_inputs[input_name]['sample_time'] # Analog-to-digital converter options if dict_has_value('adc_gain'): if len(dict_inputs[input_name]['adc_gain']) == 1: new_input.adc_gain = dict_inputs[input_name]['adc_gain'][0] elif len(dict_inputs[input_name]['adc_gain']) > 1: new_input.adc_gain = dict_inputs[input_name]['adc_gain'][ 0][0] if dict_has_value('adc_resolution'): if len(dict_inputs[input_name]['adc_resolution']) == 1: new_input.adc_resolution = dict_inputs[input_name][ 'adc_resolution'][0] elif len(dict_inputs[input_name]['adc_resolution']) > 1: new_input.adc_resolution = dict_inputs[input_name][ 'adc_resolution'][0][0] if dict_has_value('adc_sample_speed'): if len(dict_inputs[input_name]['adc_sample_speed']) == 1: new_input.adc_sample_speed = dict_inputs[input_name][ 'adc_sample_speed'][0] elif len(dict_inputs[input_name]['adc_sample_speed']) > 1: new_input.adc_sample_speed = dict_inputs[input_name][ 'adc_sample_speed'][0][0] # Linux command if dict_has_value('cmd_command'): new_input.cmd_command = dict_inputs[input_name]['cmd_command'] # Misc options if dict_has_value('resolution'): if len(dict_inputs[input_name]['resolution']) == 1: new_input.resolution = dict_inputs[input_name][ 'resolution'][0] elif len(dict_inputs[input_name]['resolution']) > 1: new_input.resolution = dict_inputs[input_name][ 'resolution'][0][0] if dict_has_value('resolution_2'): if len(dict_inputs[input_name]['resolution_2']) == 1: new_input.resolution_2 = dict_inputs[input_name][ 'resolution_2'][0] elif len(dict_inputs[input_name]['resolution_2']) > 1: new_input.resolution_2 = dict_inputs[input_name][ 'resolution_2'][0][0] if dict_has_value('sensitivity'): if len(dict_inputs[input_name]['sensitivity']) == 1: new_input.sensitivity = dict_inputs[input_name][ 'sensitivity'][0] elif len(dict_inputs[input_name]['sensitivity']) > 1: new_input.sensitivity = dict_inputs[input_name][ 'sensitivity'][0][0] if dict_has_value('thermocouple_type'): if len(dict_inputs[input_name]['thermocouple_type']) == 1: new_input.thermocouple_type = dict_inputs[input_name][ 'thermocouple_type'][0] elif len(dict_inputs[input_name]['thermocouple_type']) > 1: new_input.thermocouple_type = dict_inputs[input_name][ 'thermocouple_type'][0][0] if dict_has_value('sht_voltage'): if len(dict_inputs[input_name]['sht_voltage']) == 1: new_input.sht_voltage = dict_inputs[input_name][ 'sht_voltage'][0] elif len(dict_inputs[input_name]['sht_voltage']) > 1: new_input.sht_voltage = dict_inputs[input_name][ 'sht_voltage'][0][0] if dict_has_value('ref_ohm'): new_input.ref_ohm = dict_inputs[input_name]['ref_ohm'] # # Custom Options # # Generate string to save from custom options error, custom_options = custom_options_return_json(error, dict_inputs, device=input_name, use_defaults=True) new_input.custom_options = custom_options # # Execute at Creation # new_input.unique_id = set_uuid() if ('execute_at_creation' in dict_inputs[new_input.device] and not current_app.config['TESTING']): new_input = dict_inputs[new_input.device]['execute_at_creation']( new_input, dict_inputs[new_input.device]) try: if not error: new_input.save() display_order = csv_to_list_of_str( DisplayOrder.query.first().inputs) DisplayOrder.query.first().inputs = add_display_order( display_order, new_input.unique_id) db.session.commit() # # If there are a variable number of measurements # if ('measurements_variable_amount' in dict_inputs[input_name] and dict_inputs[input_name] ['measurements_variable_amount']): # Add first default measurement with empty unit and measurement new_measurement = DeviceMeasurements() new_measurement.name = "" new_measurement.device_id = new_input.unique_id new_measurement.measurement = "" new_measurement.unit = "" new_measurement.channel = 0 new_measurement.save() # # If measurements defined in the Input Module # elif ('measurements_dict' in dict_inputs[input_name] and dict_inputs[input_name]['measurements_dict'] != []): for each_channel in dict_inputs[input_name][ 'measurements_dict']: measure_info = dict_inputs[input_name][ 'measurements_dict'][each_channel] new_measurement = DeviceMeasurements() if 'name' in measure_info: new_measurement.name = measure_info['name'] new_measurement.device_id = new_input.unique_id new_measurement.measurement = measure_info[ 'measurement'] new_measurement.unit = measure_info['unit'] new_measurement.channel = each_channel new_measurement.save() flash( gettext( "%(type)s Input with ID %(id)s (%(uuid)s) successfully added", type=input_name, id=new_input.id, uuid=new_input.unique_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_data')) else: flash_form_errors(form_add) if dep_unmet: return 1
def input_information_update(self): try: self.dict_input_information = parse_input_information() except Exception: self.logger.exception("Exception while parsing inputs")
def setup_atlas_ph(): """ Step-by-step tool for calibrating the Atlas Scientific pH sensor """ if not utils_general.user_has_permission('edit_controllers'): return redirect(url_for('routes_general.home')) form_ph_calibrate = forms_calibration.CalibrationAtlasph() input_dev = Input.query.filter(Input.device == 'ATLAS_PH').all() ui_stage = 'start' backend_stage = None next_stage = None selected_input = None selected_point_calibration = None input_device_name = None complete_with_error = None if form_ph_calibrate.hidden_current_stage.data: backend_stage = form_ph_calibrate.hidden_current_stage.data if form_ph_calibrate.hidden_selected_point_calibration.data: selected_point_calibration = form_ph_calibrate.hidden_selected_point_calibration.data elif form_ph_calibrate.point_calibration.data: selected_point_calibration = form_ph_calibrate.point_calibration.data if selected_point_calibration: list_point_calibrations = selected_point_calibration.split(',') else: list_point_calibrations = [] # Clear Calibration memory if form_ph_calibrate.clear_calibration.data: selected_input = Input.query.filter_by( unique_id=form_ph_calibrate.selected_input_id.data).first() atlas_command = AtlasScientificCommand(selected_input) status, message = atlas_command.calibrate('clear_calibration') sensor_measurement = atlas_command.get_sensor_measurement() if isinstance(message, tuple): message_status = message[0] message_info = message[1] message = "Calibration command returned from sensor: {}".format( message_status) if message_info: message += ": {}".format(message_info) else: message = "Calibration command returned from sensor: {}".format( message) if sensor_measurement != 'NA': message = "{} {}".format(sensor_measurement, message) if status: flash(message, "error") else: flash(message, "success") # Begin calibration from Selected input elif form_ph_calibrate.start_calibration.data: ui_stage = 'temperature' selected_input = Input.query.filter_by( unique_id=form_ph_calibrate.selected_input_id.data).first() dict_inputs = parse_input_information() list_inputs_sorted = generate_form_input_list(dict_inputs) if not selected_input: flash( 'Input not found: {}'.format( form_ph_calibrate.selected_input_id.data), 'error') else: for each_input in list_inputs_sorted: if selected_input.device == each_input[0]: input_device_name = each_input[1] # Continue calibration from selected input elif (form_ph_calibrate.go_to_next_stage.data or form_ph_calibrate.go_to_last_stage.data or (backend_stage is not None and backend_stage not in ['start', 'temperature'])): selected_input = Input.query.filter_by( unique_id=form_ph_calibrate.hidden_input_id.data).first() dict_inputs = parse_input_information() list_inputs_sorted = generate_form_input_list(dict_inputs) for each_input in list_inputs_sorted: if selected_input.device == each_input[0]: input_device_name = each_input[1] if backend_stage in ['temperature', 'low', 'mid', 'high']: time.sleep(2) # Sleep makes querying sensor more stable # Determine next ui_stage if backend_stage == 'temperature': next_stage = list_point_calibrations[0] logger.error("next_stage: {}".format(next_stage)) else: current_stage_index = list_point_calibrations.index(backend_stage) if current_stage_index == len(list_point_calibrations) - 1: next_stage = 'complete' else: next_stage = list_point_calibrations[current_stage_index + 1] if form_ph_calibrate.clear_calibration.data: pass elif backend_stage == 'temperature': if form_ph_calibrate.temperature.data is None: flash( gettext( "A valid temperature is required: %(temp)s is invalid.", temp=form_ph_calibrate.temperature.data), "error") ui_stage = 'start' else: temp = '{temp:.2f}'.format( temp=float(form_ph_calibrate.temperature.data)) ui_stage, complete_with_error = dual_commands_to_sensor( selected_input, 'temperature', temp, 'continuous', current_stage='temperature', next_stage=next_stage) elif backend_stage == 'low': ui_stage, complete_with_error = dual_commands_to_sensor( selected_input, 'low', '4.0', 'continuous', current_stage='low', next_stage=next_stage) elif backend_stage == 'mid': ui_stage, complete_with_error = dual_commands_to_sensor( selected_input, 'mid', '7.0', 'continuous', current_stage='mid', next_stage=next_stage) elif backend_stage == 'high': ui_stage, complete_with_error = dual_commands_to_sensor( selected_input, 'high', '10.0', 'end', current_stage='high', next_stage=next_stage) return render_template( 'tools/calibration_options/atlas_ph.html', complete_with_error=complete_with_error, form_ph_calibrate=form_ph_calibrate, input=input_dev, input_device_name=input_device_name, selected_input=selected_input, selected_point_calibration=selected_point_calibration, ui_stage=ui_stage)
def input_activate(form_mod): messages = {"success": [], "info": [], "warning": [], "error": []} dict_inputs = parse_input_information() input_id = form_mod.input_id.data input_dev = Input.query.filter(Input.unique_id == input_id).first() device_measurements = DeviceMeasurements.query.filter( DeviceMeasurements.device_id == input_dev.unique_id) custom_options_values_inputs = parse_custom_option_values( input_dev, dict_controller=dict_inputs) # # General Input checks # if not input_dev.period: messages["error"].append("Period must be set") if (input_dev.pre_output_id and len(input_dev.pre_output_id) > 1 and not input_dev.pre_output_duration): messages["error"].append( "Pre Output Duration must be > 0 if Pre Output is enabled") if not device_measurements.filter( DeviceMeasurements.is_enabled.is_(True)).count(): messages["error"].append("At least one measurement must be enabled") # # Check if required custom options are set # if 'custom_options' in dict_inputs[input_dev.device]: for each_option in dict_inputs[input_dev.device]['custom_options']: if 'id' not in each_option: continue if each_option['id'] not in custom_options_values_inputs[ input_dev.unique_id]: if 'required' in each_option and each_option['required']: messages["error"].append( f"{each_option['name']} not found and is required to be set. " "Set option and save Input.") else: value = custom_options_values_inputs[input_dev.unique_id][ each_option['id']] if ('required' in each_option and each_option['required'] and value != 0 and not value): messages["error"].append( f"{each_option['name']} is required to be set. " f"Current value: {value}") # # Input-specific checks # if input_dev.device == 'LinuxCommand' and not input_dev.cmd_command: messages["error"].append( "Cannot activate Command Input without a Command set") elif ('measurements_variable_amount' in dict_inputs[input_dev.device] and dict_inputs[input_dev.device]['measurements_variable_amount']): measure_set = True for each_channel in device_measurements.all(): if (not each_channel.name or not each_channel.measurement or not each_channel.unit): measure_set = False if not measure_set: messages["error"].append( "All measurements must have a name and unit/measurement set") messages = controller_activate_deactivate(messages, 'activate', 'Input', input_id, flash_message=False) if not messages["error"]: messages["success"].append( f"{TRANSLATIONS['activate']['title']} {TRANSLATIONS['input']['title']}" ) return messages
def input_mod(form_mod, request_form): action = '{action} {controller}'.format( action=TRANSLATIONS['modify']['title'], controller=TRANSLATIONS['input']['title']) error = [] dict_inputs = parse_input_information() try: mod_input = Input.query.filter( Input.unique_id == form_mod.input_id.data).first() if mod_input.is_activated: error.append( gettext("Deactivate controller before modifying its settings")) if (mod_input.device == 'AM2315' and form_mod.period.data < 7): error.append( gettext("Choose a Read Period equal to or greater than 7. The " "AM2315 may become unresponsive if the period is " "below 7.")) if (mod_input.device != 'EDGE' and (mod_input.pre_output_duration and form_mod.period.data < mod_input.pre_output_duration)): error.append( gettext("The Read Period cannot be less than the Pre Output " "Duration")) if (form_mod.uart_location.data and not os.path.exists(form_mod.uart_location.data)): error.append( gettext( "Invalid device or improper permissions to read device")) if ('gpio_location' in dict_inputs[mod_input.device]['options_enabled'] and form_mod.gpio_location.data is None): error.append(gettext("Pin (GPIO) must be set")) mod_input.name = form_mod.name.data if form_mod.location.data: mod_input.location = form_mod.location.data if form_mod.i2c_location.data: mod_input.i2c_location = form_mod.i2c_location.data if form_mod.ftdi_location.data: mod_input.ftdi_location = form_mod.ftdi_location.data if form_mod.uart_location.data: mod_input.uart_location = form_mod.uart_location.data if form_mod.gpio_location.data and form_mod.gpio_location.data is not None: mod_input.gpio_location = form_mod.gpio_location.data if form_mod.power_output_id.data: mod_input.power_output_id = form_mod.power_output_id.data else: mod_input.power_output_id = None if form_mod.pre_output_id.data: mod_input.pre_output_id = form_mod.pre_output_id.data else: mod_input.pre_output_id = None # Enable/disable Channels measurements = DeviceMeasurements.query.filter( DeviceMeasurements.device_id == form_mod.input_id.data).all() if form_mod.measurements_enabled.data: for each_measurement in measurements: if each_measurement.unique_id in form_mod.measurements_enabled.data: each_measurement.is_enabled = True else: each_measurement.is_enabled = False mod_input.log_level_debug = form_mod.log_level_debug.data mod_input.i2c_bus = form_mod.i2c_bus.data mod_input.baud_rate = form_mod.baud_rate.data mod_input.pre_output_duration = form_mod.pre_output_duration.data mod_input.pre_output_during_measure = form_mod.pre_output_during_measure.data if form_mod.period.data: mod_input.period = form_mod.period.data mod_input.resolution = form_mod.resolution.data mod_input.resolution_2 = form_mod.resolution_2.data mod_input.sensitivity = form_mod.sensitivity.data mod_input.calibrate_sensor_measure = form_mod.calibrate_sensor_measure.data mod_input.cmd_command = form_mod.cmd_command.data mod_input.thermocouple_type = form_mod.thermocouple_type.data mod_input.ref_ohm = form_mod.ref_ohm.data # Serial options mod_input.pin_clock = form_mod.pin_clock.data mod_input.pin_cs = form_mod.pin_cs.data mod_input.pin_mosi = form_mod.pin_mosi.data mod_input.pin_miso = form_mod.pin_miso.data # Bluetooth options mod_input.bt_adapter = form_mod.bt_adapter.data mod_input.adc_gain = form_mod.adc_gain.data mod_input.adc_resolution = form_mod.adc_resolution.data mod_input.adc_sample_speed = form_mod.adc_sample_speed.data # Switch options mod_input.switch_edge = form_mod.switch_edge.data mod_input.switch_bouncetime = form_mod.switch_bouncetime.data mod_input.switch_reset_period = form_mod.switch_reset_period.data # PWM and RPM options mod_input.weighting = form_mod.weighting.data mod_input.rpm_pulses_per_rev = form_mod.rpm_pulses_per_rev.data mod_input.sample_time = form_mod.sample_time.data # Server options mod_input.port = form_mod.port.data mod_input.times_check = form_mod.times_check.data mod_input.deadline = form_mod.deadline.data # SHT sensor options if form_mod.sht_voltage.data: mod_input.sht_voltage = form_mod.sht_voltage.data if 'test_before_saving' in dict_inputs[mod_input.device]: (constraints_pass, constraints_errors, mod_input) = dict_inputs[mod_input.device]['test_before_saving']( mod_input, request_form) if constraints_pass: pass elif constraints_errors: for each_error in constraints_errors: flash(each_error, 'error') # Custom options list_options = [] if 'custom_options' in dict_inputs[mod_input.device]: for each_option in dict_inputs[mod_input.device]['custom_options']: null_value = True for key in request_form.keys(): if each_option['id'] == key: constraints_pass = True constraints_errors = [] value = None if each_option['type'] == 'float': if str_is_float(request_form.get(key)): if 'constraints_pass' in each_option: (constraints_pass, constraints_errors, mod_input ) = each_option['constraints_pass']( mod_input, float(request_form.get(key))) if constraints_pass: value = float(request_form.get(key)) else: error.append( "{name} must represent a float/decimal value " "(submitted '{value}')".format( name=each_option['name'], value=request_form.get(key))) elif each_option['type'] == 'integer': if is_int(request_form.get(key)): if 'constraints_pass' in each_option: (constraints_pass, constraints_errors, mod_input ) = each_option['constraints_pass']( mod_input, int(request_form.get(key))) if constraints_pass: value = int(request_form.get(key)) else: error.append( "{name} must represent an integer value " "(submitted '{value}')".format( name=each_option['name'], value=request_form.get(key))) elif each_option['type'] in ['text', 'select']: if 'constraints_pass' in each_option: (constraints_pass, constraints_errors, mod_input) = each_option['constraints_pass']( mod_input, request_form.get(key)) if constraints_pass: value = request_form.get(key) elif each_option['type'] == 'bool': value = bool(request_form.get(key)) for each_error in constraints_errors: error.append("Error: {name}: {error}".format( name=each_option['name'], error=each_error)) if value is not None: null_value = False option = '{id},{value}'.format(id=key, value=value) list_options.append(option) if null_value: option = '{id},'.format(id=each_option['id']) list_options.append(option) mod_input.custom_options = ';'.join(list_options) if not error: # Add or delete channels for variable measurement Inputs if ('measurements_variable_amount' in dict_inputs[mod_input.device] and dict_inputs[ mod_input.device]['measurements_variable_amount']): channels = DeviceMeasurements.query.filter( DeviceMeasurements.device_id == form_mod.input_id.data) if channels.count() != form_mod.num_channels.data: # Delete channels if form_mod.num_channels.data < channels.count(): for index, each_channel in enumerate(channels.all()): if index + 1 >= channels.count(): delete_entry_with_id(DeviceMeasurements, each_channel.unique_id) # Add channels elif form_mod.num_channels.data > channels.count(): start_number = channels.count() for index in range(start_number, form_mod.num_channels.data): new_measurement = DeviceMeasurements() new_measurement.name = "" new_measurement.device_id = mod_input.unique_id new_measurement.measurement = "" new_measurement.unit = "" new_measurement.channel = index new_measurement.save() db.session.commit() except Exception as except_msg: error.append(except_msg) flash_success_errors(error, action, url_for('routes_page.page_data'))
def admin_dependencies(device): """ Display Dependency page """ form_dependencies = forms_dependencies.Dependencies() if device != '0': 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 dict_inputs = parse_input_information() list_dependencies = [ dict_inputs, LCD_INFO, MATH_INFO, METHOD_INFO, OUTPUT_INFO, CALIBRATION_INFO ] for each_section in list_dependencies: for each_device in each_section: if device in each_section: for each_device, each_val in each_section[device].items(): if each_device in ['name', 'input_name']: device_name = each_val # Determine if there are any unmet dependencies 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: install_in_progress = True 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)
MYCODO_DB_PATH = 'sqlite:///' + SQL_DATABASE_MYCODO save_path = os.path.join(INSTALL_DIRECTORY, "docs/Supported-Inputs-By-Measurement.md") inputs_info = OrderedDict() mycodo_info = OrderedDict() def repeat_to_length(s, wanted): return (s * (wanted // len(s) + 1))[:wanted] if __name__ == "__main__": for input_id, input_data in parse_input_information( exclude_custom=True).items(): name_str = "" if 'input_manufacturer' in input_data and input_data[ 'input_manufacturer']: name_str += "{}".format(input_data['input_manufacturer']) if 'input_name' in input_data and input_data['input_name']: name_str += ": {}".format(input_data['input_name']) if 'measurements_name' in input_data and input_data[ 'measurements_name']: name_str += ": {}".format(input_data['measurements_name']) if 'input_library' in input_data and input_data['input_library']: name_str += ": {}".format(input_data['input_library']) if name_str in inputs_info and 'dependencies_module' in inputs_info[ name_str]: # Multiple sets of dependencies, append library
def initialize_variables(self): input_dev = db_retrieve_table_daemon(Input, unique_id=self.unique_id) self.log_level_debug = input_dev.log_level_debug self.set_log_level_debug(self.log_level_debug) self.dict_inputs = parse_input_information() self.sample_rate = db_retrieve_table_daemon( Misc, entry='first').sample_rate_controller_input self.device_measurements = db_retrieve_table_daemon( DeviceMeasurements).filter( DeviceMeasurements.device_id == self.unique_id) self.conversions = db_retrieve_table_daemon(Conversion) self.input_dev = input_dev self.input_name = input_dev.name self.unique_id = input_dev.unique_id self.gpio_location = input_dev.gpio_location self.device = input_dev.device self.interface = input_dev.interface self.period = input_dev.period self.start_offset = input_dev.start_offset # Pre-Output (activates output prior to and/or during input measurement) self.pre_output_setup = False if self.input_dev.pre_output_id and "," in self.input_dev.pre_output_id: try: self.pre_output_id = input_dev.pre_output_id.split(",")[0] self.pre_output_channel_id = input_dev.pre_output_id.split( ",")[1] self.pre_output_duration = input_dev.pre_output_duration self.pre_output_during_measure = input_dev.pre_output_during_measure self.pre_output_activated = False self.pre_output_timer = time.time() self.pre_output_lock_file = '/var/lock/input_pre_output_{id}_{ch}'.format( id=self.pre_output_id, ch=self.pre_output_channel_id) # Check if Pre Output and channel IDs exists output = db_retrieve_table_daemon(Output, unique_id=self.pre_output_id) output_channel = db_retrieve_table_daemon( OutputChannel, unique_id=self.pre_output_channel_id) if output and output_channel and self.pre_output_duration: self.pre_output_channel = output_channel.channel self.logger.debug("Pre output successfully set up") self.pre_output_setup = True except: self.logger.exception("Could not set up pre-output") self.last_measurement = 0 self.next_measurement = time.time() + self.start_offset self.get_new_measurement = False self.trigger_cond = False self.measurement_acquired = False smtp = db_retrieve_table_daemon(SMTP, entry='first') self.smtp_max_count = smtp.hourly_max self.email_count = 0 self.allowed_to_send_notice = True # Convert string I2C address to base-16 int if self.interface == 'I2C' and self.input_dev.i2c_location: self.i2c_address = int(str(self.input_dev.i2c_location), 16) self.device_recognized = True if self.device in self.dict_inputs: input_loaded = load_module_from_file( self.dict_inputs[self.device]['file_path'], 'inputs') self.measure_input = input_loaded.InputModule(self.input_dev) else: self.device_recognized = False self.logger.debug( "Device '{device}' not recognized".format(device=self.device)) raise Exception("'{device}' is not a valid device type.".format( device=self.device)) self.input_timer = time.time() self.lastUpdate = None # Set up listener (e.g. MQTT, EDGE) if ('listener' in self.dict_inputs[self.device] and self.dict_inputs[self.device]['listener']): self.logger.debug( "Detected as listener. Starting listener thread.") input_listener = threading.Thread( target=self.measure_input.listener()) input_listener.daemon = True input_listener.start()
def input_mod(form_mod, request_form): action = '{action} {controller}'.format( action=TRANSLATIONS['modify']['title'], controller=TRANSLATIONS['input']['title']) error = [] dict_inputs = parse_input_information() try: mod_input = Input.query.filter( Input.unique_id == form_mod.input_id.data).first() if mod_input.is_activated: error.append( gettext("Deactivate controller before modifying its settings")) if (mod_input.device == 'AM2315' and form_mod.period.data < 7): error.append( gettext("Choose a Read Period equal to or greater than 7. The " "AM2315 may become unresponsive if the period is " "below 7.")) if (mod_input.device != 'EDGE' and (mod_input.pre_output_duration and form_mod.period.data < mod_input.pre_output_duration)): error.append( gettext("The Read Period cannot be less than the Pre Output " "Duration")) if (form_mod.uart_location.data and not os.path.exists(form_mod.uart_location.data)): error.append( gettext( "Invalid device or improper permissions to read device")) if ('gpio_location' in dict_inputs[mod_input.device]['options_enabled'] and form_mod.gpio_location.data is None): error.append(gettext("Pin (GPIO) must be set")) mod_input.name = form_mod.name.data if form_mod.location.data: mod_input.location = form_mod.location.data if form_mod.i2c_location.data: mod_input.i2c_location = form_mod.i2c_location.data if form_mod.ftdi_location.data: mod_input.ftdi_location = form_mod.ftdi_location.data if form_mod.uart_location.data: mod_input.uart_location = form_mod.uart_location.data if form_mod.gpio_location.data and form_mod.gpio_location.data is not None: mod_input.gpio_location = form_mod.gpio_location.data if form_mod.power_output_id.data: mod_input.power_output_id = form_mod.power_output_id.data else: mod_input.power_output_id = None if form_mod.pre_output_id.data: mod_input.pre_output_id = form_mod.pre_output_id.data else: mod_input.pre_output_id = None # Enable/disable Channels measurements = DeviceMeasurements.query.filter( DeviceMeasurements.device_id == form_mod.input_id.data).all() if form_mod.measurements_enabled.data: for each_measurement in measurements: if each_measurement.unique_id in form_mod.measurements_enabled.data: each_measurement.is_enabled = True else: each_measurement.is_enabled = False mod_input.log_level_debug = form_mod.log_level_debug.data mod_input.i2c_bus = form_mod.i2c_bus.data mod_input.baud_rate = form_mod.baud_rate.data mod_input.pre_output_duration = form_mod.pre_output_duration.data mod_input.pre_output_during_measure = form_mod.pre_output_during_measure.data if form_mod.period.data: mod_input.period = form_mod.period.data if form_mod.start_offset.data: mod_input.start_offset = form_mod.start_offset.data mod_input.resolution = form_mod.resolution.data mod_input.resolution_2 = form_mod.resolution_2.data mod_input.sensitivity = form_mod.sensitivity.data mod_input.calibrate_sensor_measure = form_mod.calibrate_sensor_measure.data mod_input.cmd_command = form_mod.cmd_command.data mod_input.thermocouple_type = form_mod.thermocouple_type.data mod_input.ref_ohm = form_mod.ref_ohm.data # Serial options mod_input.pin_clock = form_mod.pin_clock.data mod_input.pin_cs = form_mod.pin_cs.data mod_input.pin_mosi = form_mod.pin_mosi.data mod_input.pin_miso = form_mod.pin_miso.data # Bluetooth options mod_input.bt_adapter = form_mod.bt_adapter.data mod_input.adc_gain = form_mod.adc_gain.data mod_input.adc_resolution = form_mod.adc_resolution.data mod_input.adc_sample_speed = form_mod.adc_sample_speed.data # Switch options mod_input.switch_edge = form_mod.switch_edge.data mod_input.switch_bouncetime = form_mod.switch_bouncetime.data mod_input.switch_reset_period = form_mod.switch_reset_period.data # PWM and RPM options mod_input.weighting = form_mod.weighting.data mod_input.rpm_pulses_per_rev = form_mod.rpm_pulses_per_rev.data mod_input.sample_time = form_mod.sample_time.data # Server options mod_input.port = form_mod.port.data mod_input.times_check = form_mod.times_check.data mod_input.deadline = form_mod.deadline.data # SHT sensor options if form_mod.sht_voltage.data: mod_input.sht_voltage = form_mod.sht_voltage.data # Custom options try: custom_options_json_presave = json.loads(mod_input.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_inputs, request_form, device=mod_input.device) if 'execute_at_modification' in dict_inputs[mod_input.device]: (allow_saving, mod_input, custom_options ) = dict_inputs[mod_input.device]['execute_at_modification']( mod_input, 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_input.custom_options = custom_options if not error: # Add or delete channels for variable measurement Inputs if ('measurements_variable_amount' in dict_inputs[mod_input.device] and dict_inputs[ mod_input.device]['measurements_variable_amount']): channels = DeviceMeasurements.query.filter( DeviceMeasurements.device_id == form_mod.input_id.data) if channels.count() != form_mod.num_channels.data: # Delete channels if form_mod.num_channels.data < channels.count(): for index, each_channel in enumerate(channels.all()): if index + 1 >= channels.count(): delete_entry_with_id(DeviceMeasurements, each_channel.unique_id) # Add channels elif form_mod.num_channels.data > channels.count(): start_number = channels.count() for index in range(start_number, form_mod.num_channels.data): new_measurement = DeviceMeasurements() new_measurement.name = "" new_measurement.device_id = mod_input.unique_id new_measurement.measurement = "" new_measurement.unit = "" new_measurement.channel = index new_measurement.save() db.session.commit() except Exception as except_msg: error.append(except_msg) flash_success_errors(error, action, url_for('routes_page.page_data'))
def measurement_mod(form, return_url): action = '{action} {controller}'.format( action=TRANSLATIONS['modify']['title'], controller=TRANSLATIONS['measurement']['title']) error = [] mod_device = None device_info = None try: mod_meas = DeviceMeasurements.query.filter( DeviceMeasurements.unique_id == form.measurement_id.data).first() controller_type = determine_controller_type(mod_meas.device_id) if controller_type == "Input": mod_device = Input.query.filter( Input.unique_id == mod_meas.device_id).first() device_info = parse_input_information() elif controller_type == "Function": mod_device = CustomController.query.filter( CustomController.unique_id == mod_meas.device_id).first() device_info = parse_function_information() if not mod_device or not device_info: logger.error("Could not find mod_device or device_info") return if mod_device.is_activated: error.append( gettext("Deactivate controller before modifying its settings")) mod_meas.name = form.name.data if form.device_type.data == 'measurement_select': if not form.select_measurement_unit.data: error.append("Must select a measurement unit") else: mod_meas.measurement = form.select_measurement_unit.data.split( ',')[0] mod_meas.unit = form.select_measurement_unit.data.split(',')[1] elif form.device_type.data == 'measurement_convert': if ('enable_channel_unit_select' in device_info[mod_device.device] and device_info[ mod_device.device]['enable_channel_unit_select']): if ',' in form.select_measurement_unit.data: mod_meas.measurement = form.select_measurement_unit.data.split( ',')[0] mod_meas.unit = form.select_measurement_unit.data.split( ',')[1] else: mod_meas.measurement = '' mod_meas.unit = '' if form.rescaled_measurement_unit.data != '' and ',' in form.rescaled_measurement_unit.data: mod_meas.rescaled_measurement = form.rescaled_measurement_unit.data.split( ',')[0] mod_meas.rescaled_unit = form.rescaled_measurement_unit.data.split( ',')[1] elif form.rescaled_measurement_unit.data == '': mod_meas.rescaled_measurement = '' mod_meas.rescaled_unit = '' mod_meas.rescale_method = form.rescale_method.data mod_meas.rescale_equation = form.rescale_equation.data mod_meas.scale_from_min = form.scale_from_min.data mod_meas.scale_from_max = form.scale_from_max.data mod_meas.scale_to_min = form.scale_to_min.data mod_meas.scale_to_max = form.scale_to_max.data mod_meas.invert_scale = form.invert_scale.data mod_meas.conversion_id = form.convert_to_measurement_unit.data if not error: db.session.commit() except Exception as except_msg: logger.exception(1) error.append(except_msg) flash_success_errors(error, action, return_url)
def admin_dependencies(device): """ Display Dependency page """ form_dependencies = forms_dependencies.Dependencies() if device != '0': 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 dict_inputs = parse_input_information() list_dependencies = [ dict_inputs, FUNCTION_ACTION_INFO, FUNCTION_INFO, LCD_INFO, MATH_INFO, METHOD_INFO, OUTPUT_INFO, CALIBRATION_INFO ] for each_section in list_dependencies: for each_device in each_section: if device in each_section: for each_device_, each_val in each_section[device].items(): if each_device_ in ['name', 'input_name']: device_name = each_val # Determine if there are any unmet dependencies 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: install_in_progress = True 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 return_dependencies(device_type): unmet_deps = [] met_deps = False dict_inputs = parse_input_information() list_dependencies = [ dict_inputs, LCD_INFO, MATH_INFO, METHOD_INFO, OUTPUT_INFO, CALIBRATION_INFO ] for each_section in list_dependencies: if device_type in each_section: for each_device, each_dict in each_section[device_type].items(): if not each_dict: met_deps = True elif each_device == 'dependencies_module': for (install_type, package, install_id) in each_dict: entry = ( package, '{0} {1}'.format(install_type, install_id), install_type, install_id ) if install_type in ['pip-pypi', 'pip-git']: try: module = importlib.util.find_spec(package) if module is None: if entry not in unmet_deps: unmet_deps.append(entry) else: met_deps = True except ImportError: if entry not in unmet_deps: unmet_deps.append(entry) elif install_type == 'apt': if (not dpkg_package_exists(package) and entry not in unmet_deps): unmet_deps.append(entry) else: met_deps = True elif install_type == 'internal': if package.startswith('file-exists'): filepath = package.split(' ', 1)[1] if not os.path.isfile(filepath): if entry not in unmet_deps: unmet_deps.append(entry) else: met_deps = True elif package.startswith('pip-exists'): py_module = package.split(' ', 1)[1] try: module = importlib.util.find_spec(py_module) if module is None: if entry not in unmet_deps: unmet_deps.append(entry) else: met_deps = True except ImportError: if entry not in unmet_deps: unmet_deps.append(entry) elif package.startswith('apt'): if (not dpkg_package_exists(package) and entry not in unmet_deps): unmet_deps.append(entry) else: met_deps = True return unmet_deps, met_deps