def output_add(form_add): action = '{action} {controller}'.format(action=gettext("Add"), controller=gettext("Output")) error = [] dep_unmet, _ = return_dependencies(form_add.output_type.data) if dep_unmet: list_unmet_deps = [] for each_dep in dep_unmet: list_unmet_deps.append(each_dep[0]) error.append( "The {dev} device you're trying to add has unmet dependencies: {dep}" .format(dev=form_add.output_type.data, dep=', '.join(list_unmet_deps))) if is_int(form_add.output_quantity.data, check_range=[1, 20]): for _ in range(0, form_add.output_quantity.data): try: new_output = Output() new_output.name = OUTPUT_INFO[ form_add.output_type.data]['name'] new_output.output_type = form_add.output_type.data if form_add.output_type.data == 'wired': new_output.on_at_start = False elif form_add.output_type.data == 'wireless_433MHz_pi_switch': new_output.pin = None new_output.protocol = 1 new_output.pulse_length = 189 new_output.on_command = '22559' new_output.off_command = '22558' elif form_add.output_type.data == 'command': new_output.on_command = '/home/pi/script_on.sh' new_output.off_command = '/home/pi/script_off.sh' elif form_add.output_type.data == 'command_pwm': new_output.pwm_command = '/home/pi/script_pwm.sh ((duty_cycle))' elif form_add.output_type.data == 'pwm': new_output.pwm_hertz = 22000 new_output.pwm_library = 'pigpio_any' if not error: new_output.save() display_order = csv_to_list_of_str( DisplayOrder.query.first().output) DisplayOrder.query.first().output = add_display_order( display_order, new_output.unique_id) db.session.commit() manipulate_output('Add', new_output.unique_id) except sqlalchemy.exc.OperationalError as except_msg: error.append(except_msg) except sqlalchemy.exc.IntegrityError as except_msg: error.append(except_msg) else: error_msg = "{error}. {accepted_values}: 1-20".format( error=gettext("Invalid quantity"), accepted_values=gettext("Acceptable values")) error.append(error_msg) flash_success_errors(error, action, url_for('routes_page.page_output')) if dep_unmet: return 1
def math_add(form_add_math): action = '{action} {controller}'.format( action=TRANSLATIONS['add']['title'], controller=TRANSLATIONS['math']['title']) error = [] dep_unmet, _ = return_dependencies(form_add_math.math_type.data) if dep_unmet: list_unmet_deps = [] for each_dep in dep_unmet: list_unmet_deps.append(each_dep[0]) error.append("The {dev} device you're trying to add has unmet dependencies: {dep}".format( dev=form_add_math.math_type.data, dep=', '.join(list_unmet_deps))) if form_add_math.validate(): new_math = Math() new_math.name = str(MATH_INFO[form_add_math.math_type.data]['name']) new_math.math_type = form_add_math.math_type.data try: new_math.save() display_order = csv_to_list_of_str( DisplayOrder.query.first().math) DisplayOrder.query.first().math = add_display_order( display_order, new_math.unique_id) db.session.commit() if not MATH_INFO[form_add_math.math_type.data]['measure']: new_measurement = DeviceMeasurements() new_measurement.device_id = new_math.unique_id new_measurement.channel = 0 new_measurement.save() else: for each_channel, measure_info in MATH_INFO[form_add_math.math_type.data]['measure'].items(): new_measurement = DeviceMeasurements() if 'name' in measure_info and measure_info['name']: new_measurement.name = measure_info['name'] new_measurement.device_id = new_math.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 Math with ID %(id)s (%(uuid)s) successfully added", type=form_add_math.math_type.data, id=new_math.id, uuid=new_math.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_math) if dep_unmet: return 1
def action_add(form): """Add a function Action""" error = [] action = '{action} {controller}'.format( action=TRANSLATIONS['add']['title'], controller='{} {}'.format(TRANSLATIONS['conditional']['title'], TRANSLATIONS['actions']['title'])) dep_unmet, _ = return_dependencies(form.action_type.data) if dep_unmet: list_unmet_deps = [] for each_dep in dep_unmet: list_unmet_deps.append(each_dep[0]) error.append( "The {dev} device you're trying to add has unmet dependencies: " "{dep}".format(dev=form.function_type.data, dep=', '.join(list_unmet_deps))) if form.function_type.data == 'conditional': func = Conditional.query.filter( Conditional.unique_id == form.function_id.data).first() elif form.function_type.data == 'trigger': func = Trigger.query.filter( Trigger.unique_id == form.function_id.data).first() elif form.function_type.data == 'function_actions': func = Function.query.filter( Function.unique_id == form.function_id.data).first() else: func = None error.append("Invalid Function type: {}".format(form.function_type.data)) if form.function_type.data != 'function_actions' and func and func.is_activated: error.append("Deactivate before adding an Action") if form.action_type.data == '': error.append("Must select an action") try: new_action = Actions() new_action.function_id = form.function_id.data new_action.function_type = form.function_type.data new_action.action_type = form.action_type.data if form.action_type.data == 'command': new_action.do_output_state = 'mycodo' # user to execute shell command as if not error: new_action.save() except sqlalchemy.exc.OperationalError as except_msg: error.append(except_msg) except sqlalchemy.exc.IntegrityError as except_msg: error.append(except_msg) except Exception as except_msg: error.append(except_msg) flash_success_errors(error, action, url_for('routes_page.page_function')) if dep_unmet: return 1
def lcd_add(form): action = '{action} {controller}'.format( action=TRANSLATIONS['add']['title'], controller=TRANSLATIONS['lcd']['title']) error = [] if current_app.config['TESTING']: dep_unmet = False else: dep_unmet, _ = return_dependencies(form.lcd_type.data) if dep_unmet: list_unmet_deps = [] for each_dep in dep_unmet: list_unmet_deps.append(each_dep[0]) error.append("The {dev} device you're trying to add has unmet dependencies: {dep}".format( dev=form.lcd_type.data, dep=', '.join(list_unmet_deps))) try: new_lcd = LCD() new_lcd_data = LCDData() if GPIO.RPI_REVISION == 2 or GPIO.RPI_REVISION == 3: new_lcd.i2c_bus = 1 else: new_lcd.i2c_bus = 0 new_lcd.lcd_type = form.lcd_type.data new_lcd.name = str(LCD_INFO[form.lcd_type.data]['name']) if form.lcd_type.data == '128x32_pioled': new_lcd.location = '0x3c' new_lcd.x_characters = 21 new_lcd.y_lines = 4 elif form.lcd_type.data == '128x64_pioled': new_lcd.location = '0x3c' new_lcd.x_characters = 21 new_lcd.y_lines = 8 elif form.lcd_type.data == '16x2_generic': new_lcd.location = '0x27' new_lcd.x_characters = 16 new_lcd.y_lines = 2 elif form.lcd_type.data == '16x4_generic': new_lcd.location = '0x27' new_lcd.x_characters = 16 new_lcd.y_lines = 4 if not error: new_lcd.save() new_lcd_data.lcd_id = new_lcd.unique_id new_lcd_data.save() display_order = csv_to_list_of_str(DisplayOrder.query.first().lcd) DisplayOrder.query.first().lcd = add_display_order( display_order, new_lcd.unique_id) db.session.commit() except sqlalchemy.exc.OperationalError as except_msg: error.append(except_msg) except sqlalchemy.exc.IntegrityError as except_msg: error.append(except_msg) flash_success_errors(error, action, url_for('routes_page.page_lcd')) if dep_unmet: return 1
def camera_add(form_camera): action = '{action} {controller}'.format( action=TRANSLATIONS['add']['title'], controller=TRANSLATIONS['camera']['title']) error = [] dep_unmet, _ = return_dependencies(form_camera.library.data) if dep_unmet: list_unmet_deps = [] for each_dep in dep_unmet: list_unmet_deps.append(each_dep[0]) error.append( "The {dev} device you're trying to add has unmet dependencies: " "{dep}".format(dev=form_camera.library.data, dep=', '.join(list_unmet_deps))) new_camera = Camera() if Camera.query.filter(Camera.name == form_camera.name.data).count(): flash("You must choose a unique name", "error") new_camera.name = form_camera.name.data new_camera.library = form_camera.library.data if form_camera.library.data == 'fswebcam': new_camera.device = '/dev/video0' new_camera.brightness = 50 elif form_camera.library.data == 'raspistill': new_camera.brightness = 50 new_camera.contrast = 0.0 new_camera.saturation = 0.0 new_camera.picamera_sharpness = 0 new_camera.picamera_iso = 0 new_camera.picamera_awb = "auto" elif form_camera.library.data == 'picamera': new_camera.brightness = 50 new_camera.contrast = 0.0 new_camera.exposure = 0.0 new_camera.saturation = 0.0 elif form_camera.library.data == 'opencv': new_camera.device = '0' new_camera.brightness = 0.6 new_camera.contrast = 0.15 new_camera.exposure = 0.0 new_camera.gain = 0 new_camera.hue = -1.0 new_camera.saturation = 0.1 new_camera.white_balance = 0.0 elif form_camera.library.data == 'http_address': new_camera.url_still = 'http://s.w-x.co/staticmaps/wu/wu/wxtype1200_cur/uscsg/current.png' new_camera.url_stream = '' if not error: try: new_camera.save() 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_camera')) if dep_unmet: return 1
def setup_ds_resolution(): """ Set DS Sensor resolution """ form_ds = forms_calibration.SetupDS18B20() inputs = Input.query.all() # Check if w1thermsensor library is installed dep_unmet, _ = return_dependencies('CALIBRATE_DS_TYPE') if dep_unmet: list_unmet_deps = [] for each_dep in dep_unmet: list_unmet_deps.append(each_dep[0]) flash( "The device you're trying to calibrate has unmet dependencies: {dep}" .format(dep=', '.join(list_unmet_deps))) return redirect( url_for('routes_admin.admin_dependencies', device='CALIBRATE_DS_TYPE')) # If DS18B20 inputs added, compile a list of detected inputs ds_inputs = [] try: from w1thermsensor import W1ThermSensor for each_input in W1ThermSensor.get_available_sensors(): ds_inputs.append(each_input.id) except OSError: flash( "Unable to detect DS18B20 Inputs in '/sys/bus/w1/devices'. " "Make 1-wire support is enabled with 'sudo raspi-config'.", "error") if form_ds.set_resolution.data and form_ds.device_id.data: try: from w1thermsensor import W1ThermSensor sensor = W1ThermSensor(input_id=form_ds.device_id.data) # sensor = W1ThermSensor(W1ThermSensor.THERM_SENSOR_DS18B20, "00000588806a") sensor.set_precision(form_ds.set_resolution.data, persist=True) flash( "Successfully set sensor {id} resolution to " "{bit}-bit".format(id=form_ds.device_id.data, bit=form_ds.set_resolution.data), "success") except Exception as msg: flash( "Error while setting resolution of sensor with ID {id}: " "{err}".format(id=form_ds.device_id.data, err=msg), "error") return render_template('tools/calibration_options/ds_resolution.html', ds_inputs=ds_inputs, form_ds=form_ds, inputs=inputs)
def admin_dependency_install(device): """ Install Dependencies """ messages = {"success": [], "info": [], "warning": [], "error": []} try: device_unmet_dependencies, _ = utils_general.return_dependencies( device) 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() messages["success"].append("Dependency install initiated") except Exception as err: messages["error"].append("Error: {}".format(err)) return jsonify(data={'messages': messages})
def math_add(form_add_math): action = '{action} {controller}'.format( action=gettext("Add"), controller=gettext("Math")) error = [] unmet_deps = return_dependencies(form_add_math.math_type.data) if unmet_deps: error.append("The {dev} device you're trying to add has unmet dependencies: {dep}".format( dev=form_add_math.math_type.data, dep=unmet_deps)) if form_add_math.validate(): new_math = Math() new_math.name = '' new_math.math_type = form_add_math.math_type.data if form_add_math.math_type.data in MATH_INFO: new_math.name += '{name}'.format(name=MATH_INFO[form_add_math.math_type.data]['name']) new_math.measure = ",".join(MATH_INFO[form_add_math.math_type.data]['measure']) try: new_math.save() display_order = csv_to_list_of_str( DisplayOrder.query.first().math) DisplayOrder.query.first().math = add_display_order( display_order, new_math.unique_id) db.session.commit() flash(gettext( "%(type)s Math with ID %(id)s (%(uuid)s) successfully added", type=form_add_math.math_type.data, id=new_math.id, uuid=new_math.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_math) if unmet_deps: return 1
def input_add(form_add): action = '{action} {controller}'.format( action=gettext("Add"), controller=gettext("Input")) error = [] if current_app.config['TESTING']: unmet_deps = False else: unmet_deps = return_dependencies(form_add.input_type.data) if unmet_deps: error.append("The {dev} device you're trying to add has unmet dependencies: {dep}".format( dev=form_add.input_type.data, dep=unmet_deps)) if form_add.validate(): new_sensor = Input() new_sensor.device = form_add.input_type.data if GPIO.RPI_INFO['P1_REVISION'] in [2, 3]: new_sensor.i2c_bus = 1 else: new_sensor.i2c_bus = 0 if form_add.input_type.data in DEVICE_INFO: new_sensor.name = DEVICE_INFO[form_add.input_type.data]['name'] new_sensor.measurements = ",".join(DEVICE_INFO[form_add.input_type.data]['measure']) else: new_sensor.name = 'Name' # # Set default values for new Inputs # # Linux command as sensor if form_add.input_type.data == 'LinuxCommand': new_sensor.cmd_command = 'shuf -i 50-70 -n 1' new_sensor.cmd_measurement = 'Condition' new_sensor.cmd_measurement_units = 'unit' # Server is up or down elif form_add.input_type.data in ['SERVER_PING', 'SERVER_PORT_OPEN']: new_sensor.location = '127.0.0.1' new_sensor.period = 3600 # Process monitors elif form_add.input_type.data == 'MYCODO_RAM': new_sensor.location = 'Mycodo_daemon' elif form_add.input_type.data == 'RPi': new_sensor.location = 'RPi' elif form_add.input_type.data == 'RPiCPULoad': new_sensor.location = 'RPi' elif form_add.input_type.data == 'RPiFreeSpace': new_sensor.location = '/' # Environmental Inputs # Electrical Conductivity elif form_add.input_type.data == 'ATLAS_EC_I2C': new_sensor.location = '0x01' new_sensor.interface = 'I2C' elif form_add.input_type.data == 'ATLAS_EC_UART': new_sensor.location = 'Tx/Rx' new_sensor.interface = 'UART' new_sensor.baud_rate = 9600 if GPIO.RPI_INFO['P1_REVISION'] == 3: new_sensor.device_loc = "/dev/ttyS0" else: new_sensor.device_loc = "/dev/ttyAMA0" # Temperature if form_add.input_type.data == 'TMP006': new_sensor.location = '0x40' elif form_add.input_type.data == 'ATLAS_PT1000_I2C': new_sensor.interface = 'I2C' new_sensor.location = '0x66' elif form_add.input_type.data == 'ATLAS_PT1000_UART': new_sensor.location = 'Tx/Rx' new_sensor.interface = 'UART' new_sensor.baud_rate = 9600 if GPIO.RPI_INFO['P1_REVISION'] == 3: new_sensor.device_loc = "/dev/ttyS0" else: new_sensor.device_loc = "/dev/ttyAMA0" elif form_add.input_type.data in ['MAX31855', 'MAX31856', 'MAX31865']: new_sensor.pin_cs = 8 new_sensor.pin_miso = 9 new_sensor.pin_mosi = 10 new_sensor.pin_clock = 11 if form_add.input_type.data == 'MAX31856': new_sensor.thermocouple_type = 'K' elif form_add.input_type.data == 'MAX31865': new_sensor.thermocouple_type = 'PT100' new_sensor.ref_ohm = 0 # Temperature/Humidity elif form_add.input_type.data in ['AM2315', 'DHT11', 'DHT22', 'HTU21D', 'SHT1x_7x', 'SHT2x']: if form_add.input_type.data == 'AM2315': new_sensor.location = '0x5c' elif form_add.input_type.data == 'HTU21D': new_sensor.location = '0x40' elif form_add.input_type.data == 'SHT2x': new_sensor.location = '0x40' # Chirp moisture sensor elif form_add.input_type.data == 'CHIRP': new_sensor.location = '0x20' # CO2 elif form_add.input_type.data == 'MH_Z16_I2C': new_sensor.location = '0x63' new_sensor.interface = 'I2C' elif form_add.input_type.data in ['K30_UART', 'MH_Z16_UART', 'MH_Z19_UART']: new_sensor.location = 'Tx/Rx' new_sensor.interface = 'UART' new_sensor.baud_rate = 9600 if GPIO.RPI_INFO['P1_REVISION'] == 3: new_sensor.device_loc = "/dev/ttyS0" else: new_sensor.device_loc = "/dev/ttyAMA0" # pH elif form_add.input_type.data == 'ATLAS_PH_I2C': new_sensor.location = '0x63' new_sensor.interface = 'I2C' elif form_add.input_type.data == 'ATLAS_PH_UART': new_sensor.location = 'Tx/Rx' new_sensor.interface = 'UART' new_sensor.baud_rate = 9600 if GPIO.RPI_INFO['P1_REVISION'] == 3: new_sensor.device_loc = "/dev/ttyS0" else: new_sensor.device_loc = "/dev/ttyAMA0" # Pressure if form_add.input_type.data == 'BME280': new_sensor.location = '0x76' elif form_add.input_type.data in ['BMP180', 'BMP280']: new_sensor.location = '0x77' # Light elif form_add.input_type.data in ['BH1750', 'TSL2561', 'TSL2591']: if form_add.input_type.data == 'BH1750': new_sensor.location = '0x23' new_sensor.resolution = 0 # 0=Low, 1=High, 2=High2 new_sensor.sensitivity = 69 elif form_add.input_type.data == 'TSL2561': new_sensor.location = '0x39' elif form_add.input_type.data == 'TSL2591': new_sensor.location = '0x29' # Analog to Digital Converters elif form_add.input_type.data in LIST_DEVICES_ADC: new_sensor.adc_measure = 'Condition' new_sensor.adc_measure_units = 'units' if form_add.input_type.data == 'ADS1x15': new_sensor.location = '0x48' new_sensor.adc_volts_min = -4.096 new_sensor.adc_volts_max = 4.096 elif form_add.input_type.data == 'MCP342x': new_sensor.location = '0x68' new_sensor.adc_volts_min = -2.048 new_sensor.adc_volts_max = 2.048 elif form_add.input_type.data == 'MCP3008': new_sensor.pin_cs = 8 new_sensor.pin_miso = 9 new_sensor.pin_mosi = 10 new_sensor.pin_clock = 11 new_sensor.adc_volts_min = 0 new_sensor.adc_volts_max = 3.3 try: if not error: new_sensor.save() display_order = csv_to_list_of_str( DisplayOrder.query.first().inputs) DisplayOrder.query.first().inputs = add_display_order( display_order, new_sensor.unique_id) db.session.commit() flash(gettext( "%(type)s Input with ID %(id)s (%(uuid)s) successfully added", type=form_add.input_type.data, id=new_sensor.id, uuid=new_sensor.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 unmet_deps: return 1
for each_dev in function: if each_dev.function_type not in devices: devices.append(each_dev.function_type) actions = db_retrieve_table_daemon(Actions) for each_dev in actions: if each_dev.action_type not in devices: devices.append(each_dev.action_type) custom = db_retrieve_table_daemon(CustomController) for each_dev in custom: if each_dev.device not in devices: devices.append(each_dev.device) for each_device in devices: device_unmet_dependencies, _ = return_dependencies(each_device) for each_dep in device_unmet_dependencies: if each_dep not in dependencies: dependencies.append(each_dep) if dependencies: print("Unmet dependencies found: {}".format(dependencies)) # Install unmet dependencies for each_dep in dependencies: intsall_cmd = "{pth}/mycodo/scripts/dependencies.sh {dep}".format( pth=INSTALL_DIRECTORY, dep=each_dep[1]) output, err, stat = cmd_output(intsall_cmd, user='******') formatted_output = output.decode("utf-8").replace('\\n', '\n')
def input_add(form_add): action = '{action} {controller}'.format(action=gettext("Add"), controller=gettext("Input")) error = [] unmet_deps = None if form_add.validate(): new_sensor = Input() new_sensor.device = form_add.input_type.data new_sensor.name = '{name} Input'.format(name=form_add.input_type.data) if GPIO.RPI_INFO['P1_REVISION'] in [2, 3]: new_sensor.i2c_bus = 1 new_sensor.multiplexer_bus = 1 else: new_sensor.i2c_bus = 0 new_sensor.multiplexer_bus = 0 unmet_deps = return_dependencies(form_add.input_type.data) if unmet_deps: error.append( "The {dev} device you're trying to add has unmet dependencies: {dep}" .format(dev=form_add.input_type.data, dep=unmet_deps)) # Linux command as sensor if form_add.input_type.data == 'LinuxCommand': new_sensor.cmd_command = 'shuf -i 50-70 -n 1' new_sensor.cmd_measurement = 'Condition' new_sensor.cmd_measurement_units = 'unit' # Server is up or down elif form_add.input_type.data in ['SERVER_PING', 'SERVER_PORT_OPEN']: new_sensor.measurements = 'boolean' new_sensor.location = '127.0.0.1' new_sensor.period = 3600 # Process monitors elif form_add.input_type.data == 'MYCODO_RAM': new_sensor.measurements = 'disk_space' new_sensor.location = 'Mycodo_daemon' elif form_add.input_type.data == 'RPi': new_sensor.measurements = 'temperature' new_sensor.location = 'RPi' elif form_add.input_type.data == 'RPiCPULoad': new_sensor.measurements = 'cpu_load_1m,' \ 'cpu_load_5m,' \ 'cpu_load_15m' new_sensor.location = 'RPi' elif form_add.input_type.data == 'RPiFreeSpace': new_sensor.measurements = 'disk_space' new_sensor.location = '/' elif form_add.input_type.data == 'EDGE': new_sensor.measurements = 'edge' elif form_add.input_type.data == 'GPIO_STATE': new_sensor.measurements = 'gpio_state' # Signal measuremnt (PWM and RPM) elif form_add.input_type.data == 'SIGNAL_PWM': new_sensor.measurements = 'frequency,pulse_width,duty_cycle' elif form_add.input_type.data == 'SIGNAL_RPM': new_sensor.measurements = 'rpm' # Environmental Inputs # Temperature elif form_add.input_type.data in [ 'ATLAS_PT1000_I2C', 'ATLAS_PT1000_UART', 'DS18B20', 'TMP006' ]: new_sensor.measurements = 'temperature' if form_add.input_type.data == 'ATLAS_PT1000_I2C': new_sensor.interface = 'I2C' new_sensor.location = '0x66' elif form_add.input_type.data == 'ATLAS_PT1000_UART': new_sensor.location = 'Tx/Rx' new_sensor.interface = 'UART' new_sensor.baud_rate = 9600 if GPIO.RPI_INFO['P1_REVISION'] == 3: new_sensor.device_loc = "/dev/ttyS0" else: new_sensor.device_loc = "/dev/ttyAMA0" elif form_add.input_type.data == 'TMP006': new_sensor.measurements = 'temperature_object,' \ 'temperature_die' new_sensor.location = '0x40' # Temperature/Humidity elif form_add.input_type.data in [ 'AM2315', 'DHT11', 'DHT22', 'HTU21D', 'SHT1x_7x', 'SHT2x' ]: new_sensor.measurements = 'temperature,humidity,dewpoint' if form_add.input_type.data == 'AM2315': new_sensor.location = '0x5c' elif form_add.input_type.data == 'HTU21D': new_sensor.location = '0x40' elif form_add.input_type.data == 'SHT2x': new_sensor.location = '0x40' # Chirp moisture sensor elif form_add.input_type.data == 'CHIRP': new_sensor.measurements = 'lux,moisture,temperature' new_sensor.location = '0x20' # CO2 elif form_add.input_type.data == 'MH_Z16_I2C': new_sensor.measurements = 'co2' new_sensor.location = '0x63' new_sensor.interface = 'I2C' elif form_add.input_type.data in [ 'K30_UART', 'MH_Z16_UART', 'MH_Z19_UART' ]: new_sensor.measurements = 'co2' new_sensor.location = 'Tx/Rx' new_sensor.interface = 'UART' new_sensor.baud_rate = 9600 if GPIO.RPI_INFO['P1_REVISION'] == 3: new_sensor.device_loc = "/dev/ttyS0" else: new_sensor.device_loc = "/dev/ttyAMA0" # pH elif form_add.input_type.data == 'ATLAS_PH_I2C': new_sensor.measurements = 'ph' new_sensor.location = '0x63' new_sensor.interface = 'I2C' elif form_add.input_type.data == 'ATLAS_PH_UART': new_sensor.measurements = 'ph' new_sensor.location = 'Tx/Rx' new_sensor.interface = 'UART' new_sensor.baud_rate = 9600 if GPIO.RPI_INFO['P1_REVISION'] == 3: new_sensor.device_loc = "/dev/ttyS0" else: new_sensor.device_loc = "/dev/ttyAMA0" # Pressure elif form_add.input_type.data in ['BME280', 'BMP180', 'BMP280']: if form_add.input_type.data == 'BME280': new_sensor.measurements = 'temperature,humidity,' \ 'dewpoint,pressure,altitude' new_sensor.location = '0x76' elif form_add.input_type.data in ['BMP180', 'BMP280']: new_sensor.measurements = 'temperature,pressure,altitude' new_sensor.location = '0x77' # Light elif form_add.input_type.data in ['BH1750', 'TSL2561', 'TSL2591']: new_sensor.measurements = 'lux' if form_add.input_type.data == 'BH1750': new_sensor.location = '0x23' new_sensor.resolution = 0 # 0=Low, 1=High, 2=High2 new_sensor.sensitivity = 69 elif form_add.input_type.data == 'TSL2561': new_sensor.location = '0x39' elif form_add.input_type.data == 'TSL2591': new_sensor.location = '0x29' # Analog to Digital Converters elif form_add.input_type.data in LIST_DEVICES_ADC: new_sensor.measurements = 'voltage' new_sensor.adc_measure = 'Condition' new_sensor.adc_measure_units = 'units' if form_add.input_type.data == 'ADS1x15': new_sensor.location = '0x48' new_sensor.adc_volts_min = -4.096 new_sensor.adc_volts_max = 4.096 elif form_add.input_type.data == 'MCP342x': new_sensor.location = '0x68' new_sensor.adc_volts_min = -2.048 new_sensor.adc_volts_max = 2.048 elif form_add.input_type.data == 'MCP3008': new_sensor.pin_clock = 11 new_sensor.pin_cs = 8 new_sensor.pin_mosi = 10 new_sensor.pin_miso = 9 new_sensor.adc_volts_min = 0 new_sensor.adc_volts_max = 3.3 try: if not error: new_sensor.save() display_order = csv_to_list_of_int( DisplayOrder.query.first().sensor) DisplayOrder.query.first().sensor = add_display_order( display_order, new_sensor.id) db.session.commit() flash( gettext( "%(type)s Input with ID %(id)s (%(uuid)s) successfully added", type=form_add.input_type.data, id=new_sensor.id, uuid=new_sensor.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 unmet_deps: return 1
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 input_add(form_add, request_form): action = '{action} {controller}'.format(action=gettext("Add"), controller=gettext("Input")) 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' if ('measurements_list' in dict_inputs[input_name] and dict_inputs[input_name]['measurements_list'] != []): new_input.measurements = ",".join( dict_inputs[input_name]['measurements_list']) elif input_name == 'LinuxCommand': pass else: error.append("No measurements defined for this input.") # # Set default values for new input being added # # Set the default measurement values list_units = [] if 'measurements_list' in dict_inputs[input_name]: for each_measurement in dict_inputs[input_name][ 'measurements_list']: if each_measurement in MEASUREMENTS: entry = '{measure},{unit}'.format( measure=each_measurement, unit=MEASUREMENTS[each_measurement]['units'][0]) list_units.append(entry) else: error.append( "Measurement '{measure}' not recognized.".format( measure=each_measurement)) new_input.convert_to_unit = ";".join(list_units) # 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('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_channel'): if len(dict_inputs[input_name]['adc_channel']) == 1: new_input.adc_channel = dict_inputs[input_name][ 'adc_channel'][0] elif len(dict_inputs[input_name]['adc_channel']) > 1: new_input.adc_channel = dict_inputs[input_name][ 'adc_channel'][0][0] 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] if dict_has_value('adc_volts_min'): new_input.adc_volts_min = dict_inputs[input_name][ 'adc_volts_min'] if dict_has_value('adc_volts_max'): new_input.adc_volts_max = dict_inputs[input_name][ 'adc_volts_max'] if dict_has_value('adc_units_min'): new_input.adc_units_min = dict_inputs[input_name][ 'adc_units_min'] if dict_has_value('adc_units_max'): new_input.adc_units_max = dict_inputs[input_name][ 'adc_units_max'] if dict_has_value('adc_inverse_unit_scale'): new_input.adc_inverse_unit_scale = dict_inputs[input_name][ 'adc_inverse_unit_scale'] # 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']: option = '{id},{value}'.format( id=each_option['id'], value=each_option['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() 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 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 # 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: try: with open(DEPENDENCY_INIT_FILE, 'w') as f: f.write('0') finally: dep = 0 if dep: install_in_progress = True list_dependencies = [DEVICE_INFO, MATH_INFO] for each_section in list_dependencies: for each_device in each_section: # Determine if there are any unmet dependencies unmet_dependencies.update( {each_device: utils_general.return_dependencies(each_device)}) if utils_general.return_dependencies(each_device) != []: unmet_exist = True # Determine if there are any met dependencies if utils_general.return_dependencies(each_device, dep_type='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=DEVICE_INFO, unmet_list=unmet_list, device=device, 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 function_add(form_add_func): action = '{action} {controller}'.format( action=TRANSLATIONS['add']['title'], controller=TRANSLATIONS['function']['title']) error = [] dep_unmet, _ = return_dependencies(form_add_func.function_type.data) if dep_unmet: list_unmet_deps = [] for each_dep in dep_unmet: list_unmet_deps.append(each_dep[0]) error.append( "The {dev} device you're trying to add has unmet dependencies: " "{dep}".format(dev=form_add_func.function_type.data, dep=', '.join(list_unmet_deps))) new_func = None try: if form_add_func.function_type.data.startswith('conditional_'): new_func = Conditional() new_func.conditional_statement = ''' # Replace "asdf1234" with a Condition ID, "qwer5678" with an Action ID. measurement = measure("{asdf1234}") message += "Measure: {meas}".format(meas=measurement) if measurement is not None: # If a measurement exists if measurement < 23: # If the measurement is less than 23 run_all_actions(message=message) # Run all actions else: # If the measurement is greater or equal to 23 run_action("{qwer5678}", message=message) # Run a single Action''' new_func.save() elif form_add_func.function_type.data.startswith('pid_'): new_func = PID().save() for each_channel, measure_info in PID_INFO['measure'].items(): new_measurement = DeviceMeasurements() if 'name' in measure_info: new_measurement.name = measure_info['name'] if 'measurement_type' in measure_info: new_measurement.measurement_type = measure_info[ 'measurement_type'] new_measurement.device_id = new_func.unique_id new_measurement.measurement = measure_info['measurement'] new_measurement.unit = measure_info['unit'] new_measurement.channel = each_channel new_measurement.save() elif form_add_func.function_type.data.startswith('trigger_'): new_func = Trigger() new_func.name = '{}'.format( FUNCTION_INFO[form_add_func.function_type.data]['name']) new_func.trigger_type = form_add_func.function_type.data new_func.save() elif form_add_func.function_type.data.startswith('function_'): new_func = Function() if form_add_func.function_type.data == 'function_spacer': new_func.name = 'Spacer' new_func.function_type = form_add_func.function_type.data new_func.save() elif form_add_func.function_type.data == '': error.append("Must select a function type") else: error.append("Unknown function type: '{}'".format( form_add_func.function_type.data)) if not error: display_order = csv_to_list_of_str( DisplayOrder.query.first().function) DisplayOrder.query.first().function = add_display_order( display_order, new_func.unique_id) db.session.commit() except sqlalchemy.exc.OperationalError as except_msg: error.append(except_msg) except sqlalchemy.exc.IntegrityError as except_msg: error.append(except_msg) except Exception as except_msg: error.append(except_msg) flash_success_errors(error, action, url_for('routes_page.page_function')) if dep_unmet: return 1
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)
def action_add(form): """Add a function Action""" error = [] action = '{action} {controller}'.format( action=TRANSLATIONS['add']['title'], controller='{} {}'.format(TRANSLATIONS['conditional']['title'], TRANSLATIONS['actions']['title'])) dep_unmet, _ = return_dependencies(form.action_type.data) if dep_unmet: list_unmet_deps = [] for each_dep in dep_unmet: list_unmet_deps.append(each_dep[0]) error.append( "The {dev} device you're trying to add has unmet dependencies: " "{dep}".format(dev=form.function_type.data, dep=', '.join(list_unmet_deps))) if form.function_type.data == 'conditional': func = Conditional.query.filter( Conditional.unique_id == form.function_id.data).first() elif form.function_type.data == 'trigger': func = Trigger.query.filter( Trigger.unique_id == form.function_id.data).first() elif form.function_type.data == 'function_actions': func = Function.query.filter( Function.unique_id == form.function_id.data).first() else: func = None error.append("Invalid Function type: {}".format(form.function_type.data)) if form.function_type.data != 'function_actions' and func and func.is_activated: error.append("Deactivate before adding an Action") if form.action_type.data == '': error.append("Must select an action") try: new_action = Actions() new_action.function_id = form.function_id.data new_action.function_type = form.function_type.data new_action.action_type = form.action_type.data if form.action_type.data == 'command': new_action.do_output_state = 'mycodo' # user to execute shell command as elif form.action_type.data == 'mqtt_publish': # Fill in default values # TODO: Future improvements to actions will be single-file modules, making this obsolete custom_options = { "hostname": "localhost", "port": 1883, "topic": "paho/test/single", "keepalive": 60, "clientid": "mycodo_mqtt_client", "login": False, "username": "******", "password": "" } new_action.custom_options = json.dumps(custom_options) if not error: new_action.save() except sqlalchemy.exc.OperationalError as except_msg: error.append(except_msg) except sqlalchemy.exc.IntegrityError as except_msg: error.append(except_msg) except Exception as except_msg: error.append(except_msg) flash_success_errors(error, action, url_for('routes_page.page_function')) if dep_unmet: return 1
def output_add(form_add, request_form): messages = { "success": [], "info": [], "warning": [], "error": [] } output_id = None dep_name = None size_y = None dict_outputs = parse_output_information() if form_add.output_type.data.count(',') == 1: output_type = form_add.output_type.data.split(',')[0] output_interface = form_add.output_type.data.split(',')[1] else: output_type = '' output_interface = '' messages["error"].append("Invalid output string (must be a comma-separated string)") if current_app.config['TESTING']: dep_unmet = False else: dep_unmet, _ = return_dependencies(form_add.output_type.data.split(',')[0]) if dep_unmet: list_unmet_deps = [] for each_dep in dep_unmet: list_unmet_deps.append(each_dep[0]) messages["error"].append( "{dev} has unmet dependencies. They must be installed before the Output can be added.".format( dev=output_type)) if output_type in dict_outputs: dep_name = dict_outputs[output_type]["output_name"] else: messages["error"].append("Output not found: {}".format(output_type)) return messages, dep_name, list_unmet_deps, None, None if not is_int(form_add.output_quantity.data, check_range=[1, 20]): messages["error"].append("{error}. {accepted_values}: 1-20".format( error=gettext("Invalid quantity"), accepted_values=gettext("Acceptable values") )) if not messages["error"]: for _ in range(0, form_add.output_quantity.data): try: new_output = Output() try: from RPi import GPIO if GPIO.RPI_INFO['P1_REVISION'] == 1: new_output.i2c_bus = 0 else: new_output.i2c_bus = 1 except: logger.error( "RPi.GPIO and Raspberry Pi required for this action") new_output.name = "Name" new_output.interface = output_interface size_y = len(dict_outputs[output_type]['channels_dict']) + 1 new_output.size_y = len(dict_outputs[output_type]['channels_dict']) + 1 new_output.output_type = output_type new_output.position_y = 999 # # Set default values for new input being added # # input add options if output_type in dict_outputs: def dict_has_value(key): if (key in dict_outputs[output_type] and dict_outputs[output_type][key] is not None): return True # # Interfacing options # if output_interface == 'I2C': if dict_has_value('i2c_address_default'): new_output.i2c_location = dict_outputs[output_type]['i2c_address_default'] elif dict_has_value('i2c_location'): new_output.i2c_location = dict_outputs[output_type]['i2c_location'][0] # First list entry if output_interface == 'FTDI': if dict_has_value('ftdi_location'): new_output.ftdi_location = dict_outputs[output_type]['ftdi_location'] if output_interface == 'UART': if dict_has_value('uart_location'): new_output.uart_location = dict_outputs[output_type]['uart_location'] # UART options if dict_has_value('uart_baud_rate'): new_output.baud_rate = dict_outputs[output_type]['uart_baud_rate'] if dict_has_value('pin_cs'): new_output.pin_cs = dict_outputs[output_type]['pin_cs'] if dict_has_value('pin_miso'): new_output.pin_miso = dict_outputs[output_type]['pin_miso'] if dict_has_value('pin_mosi'): new_output.pin_mosi = dict_outputs[output_type]['pin_mosi'] if dict_has_value('pin_clock'): new_output.pin_clock = dict_outputs[output_type]['pin_clock'] # Bluetooth (BT) options elif output_interface == 'BT': if dict_has_value('bt_location'): new_output.location = dict_outputs[output_type]['bt_location'] if dict_has_value('bt_adapter'): new_output.bt_adapter = dict_outputs[output_type]['bt_adapter'] # GPIO options elif output_interface == 'GPIO': if dict_has_value('gpio_pin'): new_output.pin = dict_outputs[output_type]['gpio_pin'] # Custom location location elif dict_has_value('location'): new_output.location = dict_outputs[output_type]['location']['options'][0][0] # First entry in list # Generate string to save from custom options messages["error"], custom_options = custom_options_return_json( messages["error"], dict_outputs, request_form, device=output_type, use_defaults=True) new_output.custom_options = custom_options # # Execute at Creation # new_output.unique_id = set_uuid() if 'execute_at_creation' in dict_outputs[output_type] and not current_app.config['TESTING']: messages["error"], new_output = dict_outputs[output_type]['execute_at_creation']( messages["error"], new_output, dict_outputs[output_type]) if not messages["error"]: new_output.save() output_id = new_output.unique_id db.session.commit() messages["success"].append('{action} {controller}'.format( action=TRANSLATIONS['add']['title'], controller=TRANSLATIONS['output']['title'])) # # If measurements defined in the Output Module # if ('measurements_dict' in dict_outputs[output_type] and dict_outputs[output_type]['measurements_dict'] != []): for each_measurement in dict_outputs[output_type]['measurements_dict']: measure_info = dict_outputs[output_type]['measurements_dict'][each_measurement] new_measurement = DeviceMeasurements() if 'name' in measure_info: new_measurement.name = measure_info['name'] new_measurement.device_id = new_output.unique_id new_measurement.measurement = measure_info['measurement'] new_measurement.unit = measure_info['unit'] new_measurement.channel = each_measurement new_measurement.save() for each_channel, channel_info in dict_outputs[output_type]['channels_dict'].items(): new_channel = OutputChannel() new_channel.channel = each_channel new_channel.output_id = new_output.unique_id # Generate string to save from custom options messages["error"], custom_options = custom_channel_options_return_json( messages["error"], dict_outputs, request_form, new_output.unique_id, each_channel, device=output_type, use_defaults=True) new_channel.custom_options = custom_options new_channel.save() # Refresh output settings if not current_app.config['TESTING']: new_messages = manipulate_output( 'Add', new_output.unique_id) messages["error"].extend(new_messages["error"]) messages["success"].extend(new_messages["success"]) except sqlalchemy.exc.OperationalError as except_msg: messages["error"].append(str(except_msg)) except sqlalchemy.exc.IntegrityError as except_msg: messages["error"].append(str(except_msg)) except Exception as except_msg: messages["error"].append(str(except_msg)) logger.exception(1) return messages, dep_unmet, None, output_id, size_y
def output_add(form_add): action = '{action} {controller}'.format( action=TRANSLATIONS['add']['title'], controller=TRANSLATIONS['output']['title']) error = [] dict_outputs = parse_output_information() output_types_dict = output_types() # only one comma should be in the output_type string if form_add.output_type.data.count(',') > 1: error.append("Invalid output module formatting. It appears there is " "a comma in either 'output_name_unique' or 'interfaces'.") if form_add.output_type.data.count(',') == 1: output_type = form_add.output_type.data.split(',')[0] output_interface = form_add.output_type.data.split(',')[1] else: output_type = '' output_interface = '' error.append( "Invalid output string (must be a comma-separated string)") if current_app.config['TESTING']: dep_unmet = False else: dep_unmet, _ = return_dependencies( form_add.output_type.data.split(',')[0]) if dep_unmet: list_unmet_deps = [] for each_dep in dep_unmet: list_unmet_deps.append(each_dep[0]) error.append( "The {dev} device you're trying to add has unmet dependencies: " "{dep}".format(dev=form_add.output_type.data, dep=', '.join(list_unmet_deps))) if not is_int(form_add.output_quantity.data, check_range=[1, 20]): error.append("{error}. {accepted_values}: 1-20".format( error=gettext("Invalid quantity"), accepted_values=gettext("Acceptable values"))) if not error: for _ in range(0, form_add.output_quantity.data): try: new_output = Output() try: from RPi import GPIO if GPIO.RPI_INFO['P1_REVISION'] == 1: new_output.i2c_bus = 0 else: new_output.i2c_bus = 1 except: logger.error( "RPi.GPIO and Raspberry Pi required for this action") new_output.name = "Name" new_output.output_type = output_type new_output.interface = output_interface # # Set default values for new input being added # # input add options if output_type in dict_outputs: def dict_has_value(key): if (key in dict_outputs[output_type] and dict_outputs[output_type][key] is not None): return True # # Interfacing options # if output_interface == 'I2C': if dict_has_value('i2c_address_default'): new_output.i2c_location = dict_outputs[ output_type]['i2c_address_default'] elif dict_has_value('i2c_location'): new_output.i2c_location = dict_outputs[ output_type]['i2c_location'][ 0] # First list entry if output_interface == 'FTDI': if dict_has_value('ftdi_location'): new_output.ftdi_location = dict_outputs[ output_type]['ftdi_location'] if output_interface == 'UART': if dict_has_value('uart_location'): new_output.uart_location = dict_outputs[ output_type]['uart_location'] # UART options if dict_has_value('uart_baud_rate'): new_output.baud_rate = dict_outputs[output_type][ 'uart_baud_rate'] if dict_has_value('pin_cs'): new_output.pin_cs = dict_outputs[output_type]['pin_cs'] if dict_has_value('pin_miso'): new_output.pin_miso = dict_outputs[output_type][ 'pin_miso'] if dict_has_value('pin_mosi'): new_output.pin_mosi = dict_outputs[output_type][ 'pin_mosi'] if dict_has_value('pin_clock'): new_output.pin_clock = dict_outputs[output_type][ 'pin_clock'] # Bluetooth (BT) options elif output_interface == 'BT': if dict_has_value('bt_location'): new_output.location = dict_outputs[output_type][ 'bt_location'] if dict_has_value('bt_adapter'): new_output.bt_adapter = dict_outputs[output_type][ 'bt_adapter'] # GPIO options elif output_interface == 'GPIO': if dict_has_value('gpio_pin'): new_output.pin = dict_outputs[output_type][ 'gpio_pin'] # Custom location location elif dict_has_value('location'): new_output.location = dict_outputs[output_type][ 'location']['options'][0][0] # First entry in list # # Custom Options # list_options = [] if 'custom_options' in dict_outputs[output_type]: for each_option in dict_outputs[output_type][ 'custom_options']: if each_option['default_value'] is False: default_value = '' else: default_value = each_option['default_value'] option = '{id},{value}'.format(id=each_option['id'], value=default_value) list_options.append(option) new_output.custom_options = ';'.join(list_options) if output_type in output_types_dict['pwm']: new_output.pwm_hertz = 22000 new_output.pwm_library = 'pigpio_any' if output_type in output_types_dict['volume']: new_output.output_mode = 'fastest_flow_rate' new_output.flow_rate = 10 if output_type == 'atlas_ezo_pmp': if output_interface == 'FTDI': new_output.location = '/dev/ttyUSB0' elif output_interface == 'I2C': new_output.location = '0x67' new_output.i2c_bus = 1 elif output_interface == 'UART': new_output.location = '/dev/ttyAMA0' new_output.baud_rate = 9600 if output_type == 'wired': new_output.state_startup = '0' new_output.state_shutdown = '0' elif output_type == 'wireless_rpi_rf': new_output.pin = None new_output.protocol = 1 new_output.pulse_length = 189 new_output.on_command = '22559' new_output.off_command = '22558' new_output.force_command = True elif output_type == 'command': new_output.linux_command_user = '******' new_output.on_command = '/home/pi/script_on.sh' new_output.off_command = '/home/pi/script_off.sh' new_output.force_command = True elif output_type == 'command_pwm': new_output.linux_command_user = '******' new_output.pwm_command = '/home/pi/script_pwm.sh ((duty_cycle))' elif output_type == 'python': new_output.on_command = """ import datetime timestamp = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") log_string = "{ts}: ID: {id}: ON".format(id=output_id, ts=timestamp) self.logger.info(log_string)""" new_output.off_command = """ import datetime timestamp = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") log_string = "{ts}: ID: {id}: OFF".format(id=output_id, ts=timestamp) self.logger.info(log_string)""" new_output.force_command = True elif output_type == 'python_pwm': new_output.pwm_command = """ import datetime timestamp = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") log_string = "{ts}: ID: {id}: {dc} % Duty Cycle".format( dc=duty_cycle, id=output_id, ts=timestamp) self.logger.info(log_string)""" if not error: new_output.save() display_order = csv_to_list_of_str( DisplayOrder.query.first().output) DisplayOrder.query.first().output = add_display_order( display_order, new_output.unique_id) # # If measurements defined in the Output Module # if ('measurements_dict' in dict_outputs[output_type] and dict_outputs[output_type]['measurements_dict'] != []): for each_channel in dict_outputs[output_type][ 'measurements_dict']: measure_info = dict_outputs[output_type][ 'measurements_dict'][each_channel] new_measurement = DeviceMeasurements() if 'name' in measure_info: new_measurement.name = measure_info['name'] new_measurement.device_id = new_output.unique_id new_measurement.measurement = measure_info[ 'measurement'] new_measurement.unit = measure_info['unit'] new_measurement.channel = each_channel new_measurement.save() db.session.commit() if not current_app.config['TESTING']: manipulate_output('Add', new_output.unique_id) except sqlalchemy.exc.OperationalError as except_msg: error.append(except_msg) except sqlalchemy.exc.IntegrityError as except_msg: error.append(except_msg) flash_success_errors(error, action, url_for('routes_page.page_output')) if dep_unmet: return 1
def lcd_add(form): action = '{action} {controller}'.format( action=TRANSLATIONS['add']['title'], controller=TRANSLATIONS['lcd']['title']) error = [] if current_app.config['TESTING']: dep_unmet = False else: dep_unmet, _ = return_dependencies(form.lcd_type.data) if dep_unmet: list_unmet_deps = [] for each_dep in dep_unmet: list_unmet_deps.append(each_dep[0]) error.append("The {dev} device you're trying to add has unmet " "dependencies: {dep}".format( dev=form.lcd_type.data, dep=', '.join(list_unmet_deps))) try: new_lcd = LCD() new_lcd_data = LCDData() try: from RPi import GPIO if GPIO.RPI_REVISION == 2 or GPIO.RPI_REVISION == 3: new_lcd.i2c_bus = 1 else: new_lcd.i2c_bus = 0 except: logger.error("RPi.GPIO and Raspberry Pi required for this action") lcd_id = form.lcd_type.data.split(",")[0] lcd_interface = form.lcd_type.data.split(",")[1] new_lcd.lcd_type = lcd_id new_lcd.interface = lcd_interface new_lcd.name = str(LCD_INFO[lcd_id]['name']) if lcd_id in ['128x32_pioled', '128x64_pioled' ] and lcd_interface == 'I2C': new_lcd.location = '0x3c' new_lcd.pin_reset = 19 elif lcd_id in ['16x2_generic', '20x4_generic' ] and lcd_interface == 'I2C': new_lcd.location = '0x27' elif lcd_interface == 'SPI': new_lcd.pin_reset = 19 new_lcd.pin_dc = 16 new_lcd.spi_device = 0 new_lcd.spi_bus = 0 if lcd_id == '128x32_pioled': new_lcd.x_characters = 21 new_lcd.y_lines = 4 elif lcd_id == '128x64_pioled': new_lcd.x_characters = 21 new_lcd.y_lines = 8 elif lcd_id == '16x2_generic': new_lcd.x_characters = 16 new_lcd.y_lines = 2 elif lcd_id == '20x4_generic': new_lcd.x_characters = 20 new_lcd.y_lines = 4 if not error: new_lcd.save() new_lcd_data.lcd_id = new_lcd.unique_id new_lcd_data.save() display_order = csv_to_list_of_str(DisplayOrder.query.first().lcd) DisplayOrder.query.first().lcd = add_display_order( display_order, new_lcd.unique_id) db.session.commit() except sqlalchemy.exc.OperationalError as except_msg: error.append(except_msg) except sqlalchemy.exc.IntegrityError as except_msg: error.append(except_msg) flash_success_errors(error, action, url_for('routes_page.page_lcd')) if dep_unmet: return 1
def output_add(form_add): action = '{action} {controller}'.format( action=TRANSLATIONS['add']['title'], controller=TRANSLATIONS['output']['title']) error = [] dep_unmet, _ = return_dependencies(form_add.output_type.data.split(',')[0]) if dep_unmet: list_unmet_deps = [] for each_dep in dep_unmet: list_unmet_deps.append(each_dep[0]) error.append( "The {dev} device you're trying to add has unmet dependencies: " "{dep}".format(dev=form_add.output_type.data, dep=', '.join(list_unmet_deps))) if len(form_add.output_type.data.split(',')) < 2: error.append("Must select an Output type") if not is_int(form_add.output_quantity.data, check_range=[1, 20]): error.append("{error}. {accepted_values}: 1-20".format( error=gettext("Invalid quantity"), accepted_values=gettext("Acceptable values") )) if not error: for _ in range(0, form_add.output_quantity.data): try: output_type = form_add.output_type.data.split(',')[0] interface = form_add.output_type.data.split(',')[1] new_output = Output() new_output.name = str(OUTPUT_INFO[output_type]['name']) new_output.output_type = output_type new_output.interface = interface if output_type in ['wired', 'wireless_rpi_rf', 'command', 'python']: new_output.measurement = 'duration_time' new_output.unit = 's' elif output_type in ['command_pwm', 'pwm', 'python_pwm']: new_output.measurement = 'duty_cycle' new_output.unit = 'percent' elif output_type == 'atlas_ezo_pmp': new_output.measurement = 'volume' new_output.unit = 'ml' new_output.channel = 0 if output_type == 'wired': new_output.on_at_start = False elif output_type == 'wireless_rpi_rf': new_output.pin = None new_output.protocol = 1 new_output.pulse_length = 189 new_output.on_command = '22559' new_output.off_command = '22558' elif output_type == 'command': new_output.on_command = '/home/pi/script_on.sh' new_output.off_command = '/home/pi/script_off.sh' elif output_type == 'command_pwm': new_output.pwm_command = '/home/pi/script_pwm.sh ((duty_cycle))' elif output_type == 'pwm': new_output.pwm_hertz = 22000 new_output.pwm_library = 'pigpio_any' elif output_type == 'python': new_output.on_command = """ timestamp = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") write_string = "{ts}: ID: {id}: ON\\n".format(id=output_id, ts=timestamp) with open("/home/pi/Mycodo/OutputTest.txt", "a") as myfile: myfile.write(write_string)""" new_output.off_command = """ timestamp = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") write_string = "{ts}: ID: {id}: OFF\\n".format(id=output_id, ts=timestamp) with open("/home/pi/Mycodo/OutputTest.txt", "a") as myfile: myfile.write(write_string)""" elif output_type == 'python_pwm': new_output.pwm_command = """ timestamp = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") write_string = "{ts}: ID: {id}: Duty Cycle: ((duty_cycle)) %\\n".format( id=output_id, ts=timestamp) with open("/home/pi/Mycodo/OutputTest.txt", "a") as myfile: myfile.write(write_string)""" elif output_type == 'atlas_ezo_pmp': new_output.flow_rate = 10 if interface == 'I2C': new_output.location = '0x67' new_output.i2c_bus = 1 elif interface == 'UART': new_output.location = '/dev/ttyAMA0' new_output.baud_rate = 9600 if not error: new_output.save() display_order = csv_to_list_of_str( DisplayOrder.query.first().output) DisplayOrder.query.first().output = add_display_order( display_order, new_output.unique_id) db.session.commit() manipulate_output('Add', new_output.unique_id) except sqlalchemy.exc.OperationalError as except_msg: error.append(except_msg) except sqlalchemy.exc.IntegrityError as except_msg: error.append(except_msg) flash_success_errors(error, action, url_for('routes_page.page_output')) if dep_unmet: return 1
def action_add(form): """Add an Action.""" messages = { "success": [], "info": [], "warning": [], "error": [] } action_id = None list_unmet_deps = [] dep_name = "" page_refresh = False if not current_app.config['TESTING']: dep_unmet, _, dep_message = return_dependencies(form.action_type.data) if dep_unmet: for each_dep in dep_unmet: list_unmet_deps.append(each_dep[3]) messages["error"].append( f"{form.action_type.data} has unmet dependencies. " "They must be installed before the Action can be added.") dep_name = form.action_type.data return messages, dep_name, list_unmet_deps, dep_message, None dict_actions = parse_action_information() controller_type, controller_table, _ = which_controller(form.device_id.data) if controller_type not in ['Conditional', 'Trigger', 'Function', 'Input']: messages["error"].append(f"Invalid controller type: {controller_type}") if controller_type: controller = controller_table.query.filter( controller_table.unique_id == form.device_id.data).first() try: if controller and controller.is_activated: messages["error"].append("Deactivate controller before adding an Action") except: pass # is_activated doesn't exist if form.action_type.data == '': messages["error"].append("Must select an action") try: new_action = Actions() new_action.function_id = form.device_id.data new_action.function_type = form.function_type.data new_action.action_type = form.action_type.data # # Custom Options # # Generate string to save from custom options messages["error"], custom_options = custom_options_return_json( messages["error"], dict_actions, device=form.action_type.data, use_defaults=True) new_action.custom_options = custom_options if not messages["error"]: new_action.save() action_id = new_action.unique_id page_refresh = True messages["success"].append(f"{TRANSLATIONS['add']['title']} {TRANSLATIONS['actions']['title']}") except sqlalchemy.exc.OperationalError as except_msg: messages["error"].append(str(except_msg)) except sqlalchemy.exc.IntegrityError as except_msg: messages["error"].append(str(except_msg)) except Exception as except_msg: messages["error"].append(str(except_msg)) return messages, dep_name, list_unmet_deps, action_id, page_refresh
def function_add(form_add_func): messages = {"success": [], "info": [], "warning": [], "error": []} new_function_id = None list_unmet_deps = [] dep_name = None dep_message = '' function_name = form_add_func.function_type.data dict_controllers = parse_function_information() if not current_app.config['TESTING']: dep_unmet, _, dep_message = return_dependencies(function_name) if dep_unmet: for each_dep in dep_unmet: list_unmet_deps.append(each_dep[3]) messages["error"].append( f"{function_name} has unmet dependencies. " "They must be installed before the Function can be added.") if function_name in dict_controllers: dep_name = dict_controllers[function_name]['function_name'] else: messages["error"].append( f"Function not found: {function_name}") return messages, dep_name, list_unmet_deps, dep_message, None new_func = None try: if function_name == 'conditional_conditional': new_func = Conditional() new_func.position_y = 999 new_func.conditional_statement = ''' # Example code for learning how to use a Conditional. See the manual for more information. self.logger.info("This INFO log entry will appear in the Daemon Log") self.logger.error("This ERROR log entry will appear in the Daemon Log") if not hasattr(self, "loop_count"): # Initialize objects saved across executions self.loop_count = 1 else: self.loop_count += 1 # Replace "asdf1234" with a Condition ID measurement = self.condition("{asdf1234}") self.logger.info(f"Check this measurement in the Daemon Log. The value is {measurement}") if measurement is not None: # If a measurement exists self.message += "This message appears in email alerts and notes.\\n" if measurement < 23: # If the measurement is less than 23 self.message += f"Measurement is too Low! Measurement is {measurement}\\n" self.run_all_actions(message=self.message) # Run all actions sequentially elif measurement > 27: # Else If the measurement is greater than 27 self.message += f"Measurement is too High! Measurement is {measurement}\\n" # Replace "qwer5678" with an Action ID self.run_action("{qwer5678}", message=self.message) # Run a single specific Action''' new_func.conditional_status = ''' # Example code to provide a return status for other controllers and widgets. status_dict = { 'string_status': f"This is the demo status of the conditional controller. " f"The controller has looped {self.loop_count} times", 'loop_count': self.loop_count, 'error': [] } return status_dict''' if not messages["error"]: new_func.save() new_function_id = new_func.unique_id if not current_app.config['TESTING']: save_conditional_code(messages["error"], new_func.conditional_statement, new_func.conditional_status, new_func.unique_id, ConditionalConditions.query.all(), Actions.query.all(), test=False) elif function_name == 'pid_pid': new_func = PID() new_func.position_y = 999 new_func.save() new_function_id = new_func.unique_id for each_channel, measure_info in PID_INFO['measure'].items(): new_measurement = DeviceMeasurements() if 'name' in measure_info: new_measurement.name = measure_info['name'] if 'measurement_type' in measure_info: new_measurement.measurement_type = measure_info[ 'measurement_type'] new_measurement.device_id = new_func.unique_id new_measurement.measurement = measure_info['measurement'] new_measurement.unit = measure_info['unit'] new_measurement.channel = each_channel if not messages["error"]: new_measurement.save() elif function_name in [ 'trigger_edge', 'trigger_output', 'trigger_output_pwm', 'trigger_timer_daily_time_point', 'trigger_timer_daily_time_span', 'trigger_timer_duration', 'trigger_run_pwm_method', 'trigger_sunrise_sunset' ]: new_func = Trigger() new_func.name = '{}'.format(FUNCTION_INFO[function_name]['name']) new_func.trigger_type = function_name new_func.position_y = 999 if not messages["error"]: new_func.save() new_function_id = new_func.unique_id elif function_name == 'function_actions': new_func = Function() new_func.position_y = 999 new_func.function_type = function_name if not messages["error"]: new_func.save() new_function_id = new_func.unique_id elif function_name in dict_controllers: # Custom Function Controller new_func = CustomController() new_func.device = function_name new_func.position_y = 999 if 'function_name' in dict_controllers[function_name]: new_func.name = dict_controllers[function_name][ 'function_name'] else: new_func.name = 'Function Name' # Generate string to save from custom options messages["error"], custom_options = custom_options_return_json( messages["error"], dict_controllers, device=function_name, use_defaults=True) new_func.custom_options = custom_options new_func.unique_id = set_uuid() if ('execute_at_creation' in dict_controllers[new_func.device] and not current_app.config['TESTING']): messages["error"], new_func = dict_controllers[ new_func.device]['execute_at_creation']( messages["error"], new_func, dict_controllers[new_func.device]) if not messages["error"]: new_func.save() new_function_id = new_func.unique_id elif function_name == '': messages["error"].append("Must select a function type") else: messages["error"].append( f"Unknown function type: '{function_name}'") if not messages["error"]: if function_name in dict_controllers: # # Add measurements defined in the Function Module # if ('measurements_dict' in dict_controllers[function_name] and dict_controllers[function_name]['measurements_dict']): for each_channel in dict_controllers[function_name][ 'measurements_dict']: measure_info = dict_controllers[function_name][ 'measurements_dict'][each_channel] new_measurement = DeviceMeasurements() new_measurement.device_id = new_func.unique_id if 'name' in measure_info: new_measurement.name = measure_info['name'] else: new_measurement.name = "" if 'measurement' in measure_info: new_measurement.measurement = measure_info[ 'measurement'] else: new_measurement.measurement = "" if 'unit' in measure_info: new_measurement.unit = measure_info['unit'] else: new_measurement.unit = "" new_measurement.channel = each_channel new_measurement.save() # # If there are a variable number of measurements # elif ('measurements_variable_amount' in dict_controllers[function_name] and dict_controllers[function_name] ['measurements_variable_amount']): # Add first default measurement with empty unit and measurement new_measurement = DeviceMeasurements() new_measurement.name = "" new_measurement.device_id = new_func.unique_id new_measurement.measurement = "" new_measurement.unit = "" new_measurement.channel = 0 new_measurement.save() # # Add channels defined in the Function Module # if 'channels_dict' in dict_controllers[function_name]: for each_channel, channel_info in dict_controllers[ function_name]['channels_dict'].items(): new_channel = FunctionChannel() new_channel.channel = each_channel new_channel.function_id = new_func.unique_id # Generate string to save from custom options messages[ "error"], custom_options = custom_channel_options_return_json( messages["error"], dict_controllers, None, new_func.unique_id, each_channel, device=new_func.device, use_defaults=True) new_channel.custom_options = custom_options new_channel.save() messages["success"].append( f"{TRANSLATIONS['add']['title']} {TRANSLATIONS['function']['title']}" ) except sqlalchemy.exc.OperationalError as except_msg: messages["error"].append(str(except_msg)) except sqlalchemy.exc.IntegrityError as except_msg: messages["error"].append(str(except_msg)) except Exception as except_msg: logger.exception("Add Function") messages["error"].append(str(except_msg)) return messages, dep_name, list_unmet_deps, dep_message, new_function_id
def function_add(form_add_func): action = '{action} {controller}'.format( action=TRANSLATIONS['add']['title'], controller=TRANSLATIONS['function']['title']) error = [] function_name = form_add_func.function_type.data dict_controllers = parse_function_information() if current_app.config['TESTING']: dep_unmet = False else: dep_unmet, _ = return_dependencies(function_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=function_name, dep=', '.join(list_unmet_deps))) new_func = None try: if function_name == 'conditional_conditional': new_func = Conditional() new_func.conditional_statement = ''' # Example code for learning how to use a Conditional. See the manual for more information. self.logger.info("This INFO log entry will appear in the Daemon Log") self.logger.error("This ERROR log entry will appear in the Daemon Log") # Replace "asdf1234" with a Condition ID measurement = self.condition("{asdf1234}") self.logger.info("Check this measurement in the Daemon Log. The value is {val}".format(val=measurement)) if measurement is not None: # If a measurement exists self.message += "This message appears in email alerts and notes.\\n" if measurement < 23: # If the measurement is less than 23 self.message += "Measurement is too Low! Measurement is {meas}\\n".format(meas=measurement) self.run_all_actions(message=self.message) # Run all actions sequentially elif measurement > 27: # Else If the measurement is greater than 27 self.message += "Measurement is too High! Measurement is {meas}\\n".format(meas=measurement) # Replace "qwer5678" with an Action ID self.run_action("{qwer5678}", message=self.message) # Run a single specific Action''' if not error: new_func.save() save_conditional_code(error, new_func.conditional_statement, new_func.unique_id, ConditionalConditions.query.all(), Actions.query.all(), test=False) elif function_name == 'pid_pid': new_func = PID().save() for each_channel, measure_info in PID_INFO['measure'].items(): new_measurement = DeviceMeasurements() if 'name' in measure_info: new_measurement.name = measure_info['name'] if 'measurement_type' in measure_info: new_measurement.measurement_type = measure_info[ 'measurement_type'] new_measurement.device_id = new_func.unique_id new_measurement.measurement = measure_info['measurement'] new_measurement.unit = measure_info['unit'] new_measurement.channel = each_channel if not error: new_measurement.save() elif function_name in [ 'trigger_edge', 'trigger_output', 'trigger_output_pwm', 'trigger_timer_daily_time_point', 'trigger_timer_daily_time_span', 'trigger_timer_duration', 'trigger_infrared_remote_input', 'trigger_run_pwm_method', 'trigger_sunrise_sunset' ]: new_func = Trigger() new_func.name = '{}'.format(FUNCTION_INFO[function_name]['name']) new_func.trigger_type = function_name if not error: new_func.save() elif function_name in ['function_spacer', 'function_actions']: new_func = Function() if function_name == 'function_spacer': new_func.name = 'Spacer' new_func.function_type = function_name if not error: new_func.save() elif function_name in dict_controllers: # Custom Function Controller new_func = CustomController() new_func.device = function_name if 'function_name' in dict_controllers[function_name]: new_func.name = dict_controllers[function_name][ 'function_name'] else: new_func.name = 'Function Name' # TODO: Switch to JSON function list_options = [] if 'custom_options' in dict_controllers[function_name]: for each_option in dict_controllers[function_name][ 'custom_options']: if 'id' not in each_option: continue 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_func.custom_options = ';'.join(list_options) if not error: new_func.save() elif function_name == '': error.append("Must select a function type") else: error.append("Unknown function type: '{}'".format(function_name)) if not error: display_order = csv_to_list_of_str( DisplayOrder.query.first().function) DisplayOrder.query.first().function = add_display_order( display_order, new_func.unique_id) db.session.commit() except sqlalchemy.exc.OperationalError as except_msg: error.append(except_msg) except sqlalchemy.exc.IntegrityError as except_msg: error.append(except_msg) except Exception as except_msg: error.append(except_msg) flash_success_errors(error, action, url_for('routes_page.page_function')) if dep_unmet: return 1
def setup_ds_resolution(): """ Set Maxim DS Sensor resolution """ if not utils_general.user_has_permission('edit_settings'): return redirect(url_for('routes_general.home')) form_ds = forms_calibration.SetupDS18B20() inputs = Input.query.all() # Check if w1thermsensor library is installed if not current_app.config['TESTING']: dep_unmet, _ = return_dependencies('CALIBRATE_DS_TYPE') if dep_unmet: list_unmet_deps = [] for each_dep in dep_unmet: list_unmet_deps.append(each_dep[0]) flash( "The device you're trying to calibrate has unmet " "dependencies: {dep}".format(dep=', '.join(list_unmet_deps)), 'error') return redirect( url_for('routes_admin.admin_dependencies', device='CALIBRATE_DS_TYPE')) # If DS inputs exist, compile a list of detected inputs ds_inputs = [] try: if os.path.isdir(PATH_1WIRE): for each_name in os.listdir(PATH_1WIRE): if 'bus' not in each_name: input_dev = Input.query.filter( Input.location == each_name).first() if input_dev: ds_inputs.append((input_dev.device, each_name)) except OSError: flash( "Unable to detect 1-wire devices in '/sys/bus/w1/devices'. " "Make 1-wire support is enabled with 'sudo raspi-config'.", "error") if (not current_app.config['TESTING'] and form_ds.set_resolution.data and form_ds.device_id.data): try: from w1thermsensor import W1ThermSensor device_name = form_ds.device_id.data.split(',')[0] device_id = form_ds.device_id.data.split(',')[1] input_type = None if device_name == 'DS18B20': input_type = W1ThermSensor.THERM_SENSOR_DS18B20 if device_name == 'DS18S20': input_type = W1ThermSensor.THERM_SENSOR_DS18S20 if device_name == 'DS1822': input_type = W1ThermSensor.THERM_SENSOR_DS1822 if device_name == 'DS28EA00': input_type = W1ThermSensor.THERM_SENSOR_DS28EA00 if device_name == 'DS1825': input_type = W1ThermSensor.THERM_SENSOR_DS1825 if device_name == 'MAX31850K': input_type = W1ThermSensor.THERM_SENSOR_MAX31850K else: flash("Unknown input type: {}".format(device_name), "error") if input_type: sensor = W1ThermSensor(sensor_type=input_type, sensor_id=device_id) sensor.set_resolution(form_ds.set_resolution.data, persist=True) flash( "Successfully set sensor {id} resolution to " "{bit}-bit".format(id=form_ds.device_id.data, bit=form_ds.set_resolution.data), "success") except Exception as msg: flash( "Error while setting resolution of sensor with ID {id}: " "{err}".format(id=form_ds.device_id.data, err=msg), "error") return render_template('tools/calibration_options/ds_resolution.html', ds_inputs=ds_inputs, form_ds=form_ds, inputs=inputs)
def action_add(form): """Add an Action""" messages = {"success": [], "info": [], "warning": [], "error": []} action_id = None dep_name = "" page_refresh = False dep_unmet, _ = return_dependencies(form.action_type.data) if dep_unmet: list_unmet_deps = [] for each_dep in dep_unmet: list_unmet_deps.append(each_dep[0]) messages["error"].append( "{dev} has unmet dependencies. They must be installed before the Action can be added." .format(dev=form.action_type.data)) dep_name = form.action_type.data return messages, dep_name, list_unmet_deps, None if form.function_type.data == 'conditional': func = Conditional.query.filter( Conditional.unique_id == form.function_id.data).first() elif form.function_type.data == 'trigger': func = Trigger.query.filter( Trigger.unique_id == form.function_id.data).first() elif form.function_type.data == 'function': func = Function.query.filter( Function.unique_id == form.function_id.data).first() else: func = None messages["error"].append("Invalid Function type: {}".format( form.function_type.data)) if form.function_type.data != 'function' and func and func.is_activated: messages["error"].append("Deactivate before adding an Action") if form.action_type.data == '': messages["error"].append("Must select an action") try: new_action = Actions() new_action.function_id = form.function_id.data new_action.function_type = form.function_type.data new_action.action_type = form.action_type.data if form.action_type.data == 'command': new_action.do_output_state = 'mycodo' # user to execute shell command as elif form.action_type.data == 'mqtt_publish': # Fill in default values # TODO: Future improvements to actions will be single-file modules, making this obsolete custom_options = { "hostname": "localhost", "port": 1883, "topic": "paho/test/single", "keepalive": 60, "clientid": "mycodo_mqtt_client", "login": False, "username": "******", "password": "" } new_action.custom_options = json.dumps(custom_options) if not messages["error"]: new_action.save() action_id = new_action.unique_id page_refresh = True messages["success"].append('{action} {controller}'.format( action=TRANSLATIONS['add']['title'], controller=TRANSLATIONS['actions']['title'])) except sqlalchemy.exc.OperationalError as except_msg: messages["error"].append(str(except_msg)) except sqlalchemy.exc.IntegrityError as except_msg: messages["error"].append(str(except_msg)) except Exception as except_msg: messages["error"].append(str(except_msg)) return messages, dep_name, dep_unmet, action_id, page_refresh
def widget_add(form_base, request_form): """Add a widget to the dashboard""" action = '{action} {controller}'.format( action=TRANSLATIONS['add']['title'], controller=TRANSLATIONS['widget']['title']) error = [] dict_widgets = parse_widget_information() if form_base.widget_type.data: widget_name = form_base.widget_type.data else: widget_name = '' error.append("Missing widget name") if current_app.config['TESTING']: dep_unmet = False else: dep_unmet, _ = return_dependencies(widget_name) if dep_unmet: list_unmet_deps = [] for each_dep in dep_unmet: list_unmet_deps.append(each_dep[0]) error.append("The {dev} device you're trying to add has unmet dependencies: {dep}".format( dev=widget_name, dep=', '.join(list_unmet_deps))) new_widget = Widget() new_widget.dashboard_id = form_base.dashboard_id.data new_widget.graph_type = widget_name new_widget.name = form_base.name.data new_widget.font_em_name = form_base.font_em_name.data new_widget.enable_drag_handle = form_base.enable_drag_handle.data new_widget.refresh_duration = form_base.refresh_duration.data # Find where the next widget should be placed on the grid # Finds the lowest position to create as the new Widget's starting position position_y_start = 0 for each_widget in Widget.query.filter( Widget.dashboard_id == form_base.dashboard_id.data).all(): highest_position = each_widget.position_y + each_widget.height if highest_position > position_y_start: position_y_start = highest_position new_widget.position_y = position_y_start # widget add options if widget_name in dict_widgets: def dict_has_value(key): if (key in dict_widgets[widget_name] and (dict_widgets[widget_name][key] or dict_widgets[widget_name][key] == 0)): return True if dict_has_value('widget_width'): new_widget.width = dict_widgets[widget_name]['widget_width'] if dict_has_value('widget_height'): new_widget.height = dict_widgets[widget_name]['widget_height'] # Generate string to save from custom options error, custom_options = custom_options_return_json( error, dict_widgets, request_form, device=widget_name, use_defaults=True) new_widget.custom_options = custom_options # # Execute at Creation # if ('execute_at_creation' in dict_widgets[widget_name] and not current_app.config['TESTING']): dict_widgets[widget_name]['execute_at_creation']( new_widget, dict_widgets[widget_name]) try: if not error: new_widget.save() # Refresh widget settings control = DaemonControl() control.widget_add_refresh(new_widget.unique_id) flash(gettext( "{dev} with ID %(id)s successfully added".format( dev=dict_widgets[form_base.widget_type.data]['widget_name']), id=new_widget.id), "success") except sqlalchemy.exc.OperationalError as except_msg: error.append(except_msg) except sqlalchemy.exc.IntegrityError as except_msg: error.append(except_msg) return dep_unmet
def output_add(form_add, request_form): action = '{action} {controller}'.format( action=TRANSLATIONS['add']['title'], controller=TRANSLATIONS['output']['title']) error = [] dict_outputs = parse_output_information() if current_app.config['TESTING']: dep_unmet = False else: dep_unmet, _ = return_dependencies(form_add.output_type.data.split(',')[0]) if dep_unmet: list_unmet_deps = [] for each_dep in dep_unmet: list_unmet_deps.append(each_dep[0]) error.append("The {dev} device you're trying to add has unmet dependencies: {dep}".format( dev=form_add.output_type.data.split(',')[0], dep=', '.join(list_unmet_deps))) if not is_int(form_add.output_quantity.data, check_range=[1, 20]): error.append("{error}. {accepted_values}: 1-20".format( error=gettext("Invalid quantity"), accepted_values=gettext("Acceptable values") )) if form_add.output_type.data.count(',') == 1: output_type = form_add.output_type.data.split(',')[0] output_interface = form_add.output_type.data.split(',')[1] else: output_type = '' output_interface = '' error.append("Invalid output string (must be a comma-separated string)") if not error: for _ in range(0, form_add.output_quantity.data): try: new_output = Output() try: from RPi import GPIO if GPIO.RPI_INFO['P1_REVISION'] == 1: new_output.i2c_bus = 0 else: new_output.i2c_bus = 1 except: logger.error( "RPi.GPIO and Raspberry Pi required for this action") new_output.name = "Name" new_output.output_type = output_type new_output.interface = output_interface # # Set default values for new input being added # # input add options if output_type in dict_outputs: def dict_has_value(key): if (key in dict_outputs[output_type] and dict_outputs[output_type][key] is not None): return True # # Interfacing options # if output_interface == 'I2C': if dict_has_value('i2c_address_default'): new_output.i2c_location = dict_outputs[output_type]['i2c_address_default'] elif dict_has_value('i2c_location'): new_output.i2c_location = dict_outputs[output_type]['i2c_location'][0] # First list entry if output_interface == 'FTDI': if dict_has_value('ftdi_location'): new_output.ftdi_location = dict_outputs[output_type]['ftdi_location'] if output_interface == 'UART': if dict_has_value('uart_location'): new_output.uart_location = dict_outputs[output_type]['uart_location'] # UART options if dict_has_value('uart_baud_rate'): new_output.baud_rate = dict_outputs[output_type]['uart_baud_rate'] if dict_has_value('pin_cs'): new_output.pin_cs = dict_outputs[output_type]['pin_cs'] if dict_has_value('pin_miso'): new_output.pin_miso = dict_outputs[output_type]['pin_miso'] if dict_has_value('pin_mosi'): new_output.pin_mosi = dict_outputs[output_type]['pin_mosi'] if dict_has_value('pin_clock'): new_output.pin_clock = dict_outputs[output_type]['pin_clock'] # Bluetooth (BT) options elif output_interface == 'BT': if dict_has_value('bt_location'): new_output.location = dict_outputs[output_type]['bt_location'] if dict_has_value('bt_adapter'): new_output.bt_adapter = dict_outputs[output_type]['bt_adapter'] # GPIO options elif output_interface == 'GPIO': if dict_has_value('gpio_pin'): new_output.pin = dict_outputs[output_type]['gpio_pin'] # Custom location location elif dict_has_value('location'): new_output.location = dict_outputs[output_type]['location']['options'][0][0] # First entry in list # Generate string to save from custom options error, custom_options = custom_options_return_json( error, dict_outputs, request_form, device=output_type, use_defaults=True) new_output.custom_options = custom_options # # Execute at Creation # new_output.unique_id = set_uuid() if 'execute_at_creation' in dict_outputs[output_type] and not current_app.config['TESTING']: dict_outputs[output_type]['execute_at_creation']( new_output, dict_outputs[output_type]) if not error: new_output.save() display_order = csv_to_list_of_str( DisplayOrder.query.first().output) DisplayOrder.query.first().output = add_display_order( display_order, new_output.unique_id) db.session.commit() # # If measurements defined in the Output Module # if ('measurements_dict' in dict_outputs[output_type] and dict_outputs[output_type]['measurements_dict'] != []): for each_measurement in dict_outputs[output_type]['measurements_dict']: measure_info = dict_outputs[output_type]['measurements_dict'][each_measurement] new_measurement = DeviceMeasurements() if 'name' in measure_info: new_measurement.name = measure_info['name'] new_measurement.device_id = new_output.unique_id new_measurement.measurement = measure_info['measurement'] new_measurement.unit = measure_info['unit'] new_measurement.channel = each_measurement new_measurement.save() for each_channel, channel_info in dict_outputs[output_type]['channels_dict'].items(): new_channel = OutputChannel() new_channel.channel = each_channel new_channel.output_id = new_output.unique_id # Generate string to save from custom options error, custom_options = custom_channel_options_return_json( error, dict_outputs, request_form, new_output.unique_id, each_channel, device=output_type, use_defaults=True) new_channel.custom_options = custom_options new_channel.save() # Refresh output settings if not current_app.config['TESTING']: manipulate_output('Add', new_output.unique_id) flash(gettext("{dev} with ID %(id)s successfully added".format( dev=dict_outputs[output_type]['output_name']), id=new_output.id), "success") except sqlalchemy.exc.OperationalError as except_msg: error.append(except_msg) except sqlalchemy.exc.IntegrityError as except_msg: error.append(except_msg) except Exception: logger.exception(1) return dep_unmet
def method_create(form_create_method): """Create new method table entry (all data stored in method_data table)""" action = '{action} {controller}'.format( action=TRANSLATIONS['add']['title'], controller=TRANSLATIONS['method']['title']) error = [] dep_unmet, _, _ = return_dependencies(form_create_method.method_type.data) if dep_unmet: list_unmet_deps = [] for each_dep in dep_unmet: list_unmet_deps.append(each_dep[3]) error.append( "The {dev} device you're trying to add has unmet dependencies: " "{dep}".format(dev=form_create_method.method_type.data, dep=', '.join(list_unmet_deps))) try: # Create method new_method = Method() new_method.name = form_create_method.name.data new_method.method_type = form_create_method.method_type.data if not error: db.session.add(new_method) db.session.commit() # Add new method line id to method display order method_order = DisplayOrder.query.first() display_order = csv_to_list_of_str(method_order.method) method_order.method = add_display_order(display_order, new_method.unique_id) db.session.commit() # Add new method data line id to method_data display order if new_method.method_type in ['DailyBezier', 'DailySine']: # For tables that require only one entry to configure, # create that single entry now with default values new_method_data = MethodData() new_method_data.method_id = new_method.unique_id if new_method.method_type == 'DailySine': new_method_data.amplitude = 1.0 new_method_data.frequency = 1.0 new_method_data.shift_angle = 0 new_method_data.shift_y = 1.0 elif new_method.method_type == 'DailyBezier': new_method_data = MethodData() new_method_data.method_id = new_method.unique_id new_method_data.shift_angle = 0.0 new_method_data.x0 = 20.0 new_method_data.y0 = 20.0 new_method_data.x1 = 10.0 new_method_data.y1 = 13.5 new_method_data.x2 = 22.5 new_method_data.y2 = 30.0 new_method_data.x3 = 0.0 new_method_data.y3 = 20.0 if not error: db.session.add(new_method_data) db.session.commit() display_order = csv_to_list_of_str(new_method.method_order) method = Method.query.filter( Method.unique_id == new_method.unique_id).first() method.method_order = add_display_order( display_order, new_method_data.unique_id) db.session.commit() except Exception as except_msg: error.append(except_msg) flash_success_errors(error, action, url_for('routes_method.method_list')) if dep_unmet: return 1
def math_add(form_add_math): action = '{action} {controller}'.format( action=TRANSLATIONS['add']['title'], controller=TRANSLATIONS['math']['title']) error = [] dep_unmet, _ = return_dependencies(form_add_math.math_type.data) if dep_unmet: list_unmet_deps = [] for each_dep in dep_unmet: list_unmet_deps.append(each_dep[0]) error.append( "The {dev} device you're trying to add has unmet dependencies: {dep}" .format(dev=form_add_math.math_type.data, dep=', '.join(list_unmet_deps))) if form_add_math.validate(): new_math = Math() new_math.name = str(MATH_INFO[form_add_math.math_type.data]['name']) new_math.math_type = form_add_math.math_type.data try: new_math.save() display_order = csv_to_list_of_str(DisplayOrder.query.first().math) DisplayOrder.query.first().math = add_display_order( display_order, new_math.unique_id) db.session.commit() if not MATH_INFO[form_add_math.math_type.data]['measure']: new_measurement = DeviceMeasurements() new_measurement.device_id = new_math.unique_id new_measurement.channel = 0 new_measurement.save() else: for each_channel, measure_info in MATH_INFO[ form_add_math.math_type.data]['measure'].items(): new_measurement = DeviceMeasurements() if 'name' in measure_info and measure_info['name']: new_measurement.name = measure_info['name'] new_measurement.device_id = new_math.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 Math with ID %(id)s (%(uuid)s) successfully added", type=form_add_math.math_type.data, id=new_math.id, uuid=new_math.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_math) if dep_unmet: return 1
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_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 output_add(form_add): action = '{action} {controller}'.format( action=TRANSLATIONS['add']['title'], controller=TRANSLATIONS['output']['title']) error = [] dep_unmet, _ = return_dependencies(form_add.output_type.data.split(',')[0]) if dep_unmet: list_unmet_deps = [] for each_dep in dep_unmet: list_unmet_deps.append(each_dep[0]) error.append( "The {dev} device you're trying to add has unmet dependencies: " "{dep}".format(dev=form_add.output_type.data, dep=', '.join(list_unmet_deps))) if len(form_add.output_type.data.split(',')) < 2: error.append("Must select an Output type") if not is_int(form_add.output_quantity.data, check_range=[1, 20]): error.append("{error}. {accepted_values}: 1-20".format( error=gettext("Invalid quantity"), accepted_values=gettext("Acceptable values"))) if not error: for _ in range(0, form_add.output_quantity.data): try: output_type = form_add.output_type.data.split(',')[0] interface = form_add.output_type.data.split(',')[1] new_output = Output() new_output.name = str(OUTPUT_INFO[output_type]['name']) new_output.output_type = output_type new_output.interface = interface if output_type in [ 'wired', 'wireless_rpi_rf', 'command', 'python' ]: new_output.measurement = 'duration_time' new_output.unit = 's' elif output_type in OUTPUTS_PWM: new_output.measurement = 'duty_cycle' new_output.unit = 'percent' new_output.channel = 0 if output_type == 'wired': new_output.state_startup = '0' new_output.state_shutdown = '0' elif output_type == 'wireless_rpi_rf': new_output.pin = None new_output.protocol = 1 new_output.pulse_length = 189 new_output.on_command = '22559' new_output.off_command = '22558' elif output_type == 'command': new_output.on_command = '/home/pi/script_on.sh' new_output.off_command = '/home/pi/script_off.sh' elif output_type == 'command_pwm': new_output.pwm_command = '/home/pi/script_pwm.sh ((duty_cycle))' elif output_type == 'pwm': new_output.pwm_hertz = 22000 new_output.pwm_library = 'pigpio_any' elif output_type == 'python': new_output.on_command = """ timestamp = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") write_string = "{ts}: ID: {id}: ON\\n".format(id=output_id, ts=timestamp) with open("/home/pi/Mycodo/OutputTest.txt", "a") as myfile: myfile.write(write_string)""" new_output.off_command = """ timestamp = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") write_string = "{ts}: ID: {id}: OFF\\n".format(id=output_id, ts=timestamp) with open("/home/pi/Mycodo/OutputTest.txt", "a") as myfile: myfile.write(write_string)""" elif output_type == 'python_pwm': new_output.pwm_command = """ timestamp = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") write_string = "{ts}: ID: {id}: Duty Cycle: ((duty_cycle)) %\\n".format( id=output_id, ts=timestamp) with open("/home/pi/Mycodo/OutputTest.txt", "a") as myfile: myfile.write(write_string)""" elif output_type == 'atlas_ezo_pmp': new_output.output_mode = 'fastest_flow_rate' new_output.flow_rate = 10 if interface == 'FTDI': new_output.location = '/dev/ttyUSB0' elif interface == 'I2C': new_output.location = '0x67' new_output.i2c_bus = 1 elif interface == 'UART': new_output.location = '/dev/ttyAMA0' new_output.baud_rate = 9600 if not error: new_output.save() display_order = csv_to_list_of_str( DisplayOrder.query.first().output) DisplayOrder.query.first().output = add_display_order( display_order, new_output.unique_id) db.session.commit() # Add device measurements for measurement, measure_data in OUTPUT_INFO[ new_output.output_type]['measure'].items(): for unit, unit_data in measure_data.items(): for channel, _ in unit_data.items(): new_measurement = DeviceMeasurements() new_measurement.device_id = new_output.unique_id new_measurement.name = '' new_measurement.is_enabled = True new_measurement.measurement = measurement new_measurement.unit = unit new_measurement.channel = channel new_measurement.save() manipulate_output('Add', new_output.unique_id) except sqlalchemy.exc.OperationalError as except_msg: error.append(except_msg) except sqlalchemy.exc.IntegrityError as except_msg: error.append(except_msg) flash_success_errors(error, action, url_for('routes_page.page_output')) if dep_unmet: return 1
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