Ejemplo n.º 1
0
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
Ejemplo n.º 2
0
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
Ejemplo n.º 3
0
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
Ejemplo n.º 4
0
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
Ejemplo n.º 5
0
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
Ejemplo n.º 6
0
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)
Ejemplo n.º 7
0
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})
Ejemplo n.º 8
0
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
Ejemplo n.º 9
0
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
Ejemplo n.º 10
0
    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')
Ejemplo n.º 11
0
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
Ejemplo n.º 12
0
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)
Ejemplo n.º 13
0
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
Ejemplo n.º 14
0
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)
Ejemplo n.º 15
0
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
Ejemplo n.º 16
0
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)
Ejemplo n.º 17
0
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
Ejemplo n.º 18
0
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
Ejemplo n.º 19
0
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
Ejemplo n.º 20
0
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
Ejemplo n.º 21
0
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
Ejemplo n.º 22
0
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
Ejemplo n.º 23
0
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
Ejemplo n.º 24
0
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
Ejemplo n.º 25
0
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)
Ejemplo n.º 26
0
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
Ejemplo n.º 27
0
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
Ejemplo n.º 28
0
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
Ejemplo n.º 29
0
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
Ejemplo n.º 30
0
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
Ejemplo n.º 31
0
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
Ejemplo n.º 32
0
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
Ejemplo n.º 33
0
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
Ejemplo n.º 34
0
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