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) new_output.custom_options = custom_options # # Execute at Creation # new_output.unique_id = set_uuid() if 'execute_at_creation' in dict_outputs[ output_type] and not current_app.config['TESTING']: dict_outputs[output_type]['execute_at_creation']( new_output, dict_outputs[output_type]) if not error: new_output.save() display_order = csv_to_list_of_str( DisplayOrder.query.first().output) DisplayOrder.query.first().output = add_display_order( display_order, new_output.unique_id) db.session.commit() # # If measurements defined in the Output Module # if ('measurements_dict' in dict_outputs[output_type] and dict_outputs[output_type]['measurements_dict'] != []): for each_measurement in dict_outputs[output_type][ 'measurements_dict']: measure_info = dict_outputs[output_type][ 'measurements_dict'][each_measurement] new_measurement = DeviceMeasurements() if 'name' in measure_info: new_measurement.name = measure_info['name'] new_measurement.device_id = new_output.unique_id new_measurement.measurement = measure_info[ 'measurement'] new_measurement.unit = measure_info['unit'] new_measurement.channel = each_measurement new_measurement.save() for each_channel, channel_info in dict_outputs[ output_type]['channels_dict'].items(): new_channel = OutputChannel() new_channel.channel = each_channel new_channel.output_id = new_output.unique_id # Generate string to save from custom options error, custom_options = custom_channel_options_return_json( error, dict_outputs, request_form, new_output.unique_id, each_channel, device=output_type, use_defaults=True) new_channel.custom_options = custom_options new_channel.save() # Refresh output settings if not current_app.config['TESTING']: manipulate_output('Add', new_output.unique_id) flash( gettext( "{dev} with ID %(id)s successfully added".format( dev=dict_outputs[output_type]['output_name']), id=new_output.id), "success") except sqlalchemy.exc.OperationalError as except_msg: error.append(except_msg) except sqlalchemy.exc.IntegrityError as except_msg: error.append(except_msg) except Exception: logger.exception(1) return dep_unmet
def output_add(form_add): action = '{action} {controller}'.format( action=TRANSLATIONS['add']['title'], controller=TRANSLATIONS['output']['title']) error = [] dict_outputs = parse_output_information() # 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() 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] or dict_outputs[output_type][key] == 0)): return True # # Interfacing options # if output_interface == 'I2C': if 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 'on_off' in dict_outputs[output_type]['output_types']: 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.pwm_hertz = 22000 new_output.pwm_library = 'pigpio_any' 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' 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)""" elif output_type == 'atlas_ezo_pmp': new_output.output_mode = 'fastest_flow_rate' new_output.flow_rate = 10 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 not error: new_output.save() display_order = csv_to_list_of_str( DisplayOrder.query.first().output) DisplayOrder.query.first().output = add_display_order( display_order, new_output.unique_id) # # If measurements defined in the Output Module # if ('measurements_dict' in dict_outputs[output_type] and dict_outputs[output_type]['measurements_dict'] != []): for each_channel in dict_outputs[output_type][ 'measurements_dict']: measure_info = dict_outputs[output_type][ 'measurements_dict'][each_channel] new_measurement = DeviceMeasurements() if 'name' in measure_info: new_measurement.name = measure_info['name'] new_measurement.device_id = new_output.unique_id new_measurement.measurement = measure_info[ 'measurement'] new_measurement.unit = measure_info['unit'] new_measurement.channel = each_channel new_measurement.save() db.session.commit() if not current_app.config['TESTING']: manipulate_output('Add', new_output.unique_id) except sqlalchemy.exc.OperationalError as except_msg: error.append(except_msg) except sqlalchemy.exc.IntegrityError as except_msg: error.append(except_msg) flash_success_errors(error, action, url_for('routes_page.page_output')) if dep_unmet: return 1
def 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