def math_add(form_add_math): action = '{action} {controller}'.format( action=TRANSLATIONS['add']['title'], controller=TRANSLATIONS['math']['title']) error = [] dep_unmet, _ = return_dependencies(form_add_math.math_type.data) if dep_unmet: list_unmet_deps = [] for each_dep in dep_unmet: list_unmet_deps.append(each_dep[0]) error.append("The {dev} device you're trying to add has unmet dependencies: {dep}".format( dev=form_add_math.math_type.data, dep=', '.join(list_unmet_deps))) if form_add_math.validate(): new_math = Math() new_math.name = str(MATH_INFO[form_add_math.math_type.data]['name']) new_math.math_type = form_add_math.math_type.data try: new_math.save() display_order = csv_to_list_of_str( DisplayOrder.query.first().math) DisplayOrder.query.first().math = add_display_order( display_order, new_math.unique_id) db.session.commit() if not MATH_INFO[form_add_math.math_type.data]['measure']: new_measurement = DeviceMeasurements() new_measurement.device_id = new_math.unique_id new_measurement.channel = 0 new_measurement.save() else: for each_channel, measure_info in MATH_INFO[form_add_math.math_type.data]['measure'].items(): new_measurement = DeviceMeasurements() if 'name' in measure_info and measure_info['name']: new_measurement.name = measure_info['name'] new_measurement.device_id = new_math.unique_id new_measurement.measurement = measure_info['measurement'] new_measurement.unit = measure_info['unit'] new_measurement.channel = each_channel new_measurement.save() flash(gettext( "%(type)s Math with ID %(id)s (%(uuid)s) successfully added", type=form_add_math.math_type.data, id=new_math.id, uuid=new_math.unique_id), "success") except sqlalchemy.exc.OperationalError as except_msg: error.append(except_msg) except sqlalchemy.exc.IntegrityError as except_msg: error.append(except_msg) flash_success_errors(error, action, url_for('routes_page.page_data')) else: flash_form_errors(form_add_math) if dep_unmet: return 1
def function_add(form_add_func): action = '{action} {controller}'.format( action=TRANSLATIONS['add']['title'], controller=TRANSLATIONS['function']['title']) error = [] dep_unmet, _ = return_dependencies(form_add_func.function_type.data) if dep_unmet: list_unmet_deps = [] for each_dep in dep_unmet: list_unmet_deps.append(each_dep[0]) error.append( "The {dev} device you're trying to add has unmet dependencies: " "{dep}".format(dev=form_add_func.function_type.data, dep=', '.join(list_unmet_deps))) new_func = None try: if form_add_func.function_type.data.startswith('conditional_'): new_func = Conditional() new_func.conditional_statement = ''' # Replace "asdf1234" with a Condition ID, "qwer5678" with an Action ID. measurement = measure("{asdf1234}") message += "Measure: {meas}".format(meas=measurement) if measurement is not None: # If a measurement exists if measurement < 23: # If the measurement is less than 23 run_all_actions(message=message) # Run all actions else: # If the measurement is greater or equal to 23 run_action("{qwer5678}", message=message) # Run a single Action''' new_func.save() elif form_add_func.function_type.data.startswith('pid_'): new_func = PID().save() for each_channel, measure_info in PID_INFO['measure'].items(): new_measurement = DeviceMeasurements() if 'name' in measure_info: new_measurement.name = measure_info['name'] if 'measurement_type' in measure_info: new_measurement.measurement_type = measure_info[ 'measurement_type'] new_measurement.device_id = new_func.unique_id new_measurement.measurement = measure_info['measurement'] new_measurement.unit = measure_info['unit'] new_measurement.channel = each_channel new_measurement.save() elif form_add_func.function_type.data.startswith('trigger_'): new_func = Trigger() new_func.name = '{}'.format( FUNCTION_INFO[form_add_func.function_type.data]['name']) new_func.trigger_type = form_add_func.function_type.data new_func.save() elif form_add_func.function_type.data.startswith('function_'): new_func = Function() if form_add_func.function_type.data == 'function_spacer': new_func.name = 'Spacer' new_func.function_type = form_add_func.function_type.data new_func.save() elif form_add_func.function_type.data == '': error.append("Must select a function type") else: error.append("Unknown function type: '{}'".format( form_add_func.function_type.data)) if not error: display_order = csv_to_list_of_str( DisplayOrder.query.first().function) DisplayOrder.query.first().function = add_display_order( display_order, new_func.unique_id) db.session.commit() except sqlalchemy.exc.OperationalError as except_msg: error.append(except_msg) except sqlalchemy.exc.IntegrityError as except_msg: error.append(except_msg) except Exception as except_msg: error.append(except_msg) flash_success_errors(error, action, url_for('routes_page.page_function')) if dep_unmet: return 1
def function_add(form_add_func): messages = {"success": [], "info": [], "warning": [], "error": []} new_function_id = None list_unmet_deps = [] dep_name = None dep_message = '' function_name = form_add_func.function_type.data dict_controllers = parse_function_information() if not current_app.config['TESTING']: dep_unmet, _, dep_message = return_dependencies(function_name) if dep_unmet: for each_dep in dep_unmet: list_unmet_deps.append(each_dep[3]) messages["error"].append( f"{function_name} has unmet dependencies. " "They must be installed before the Function can be added.") if function_name in dict_controllers: dep_name = dict_controllers[function_name]['function_name'] else: messages["error"].append( f"Function not found: {function_name}") return messages, dep_name, list_unmet_deps, dep_message, None new_func = None try: if function_name == 'conditional_conditional': new_func = Conditional() new_func.position_y = 999 new_func.conditional_statement = ''' # Example code for learning how to use a Conditional. See the manual for more information. self.logger.info("This INFO log entry will appear in the Daemon Log") self.logger.error("This ERROR log entry will appear in the Daemon Log") if not hasattr(self, "loop_count"): # Initialize objects saved across executions self.loop_count = 1 else: self.loop_count += 1 # Replace "asdf1234" with a Condition ID measurement = self.condition("{asdf1234}") self.logger.info(f"Check this measurement in the Daemon Log. The value is {measurement}") if measurement is not None: # If a measurement exists self.message += "This message appears in email alerts and notes.\\n" if measurement < 23: # If the measurement is less than 23 self.message += f"Measurement is too Low! Measurement is {measurement}\\n" self.run_all_actions(message=self.message) # Run all actions sequentially elif measurement > 27: # Else If the measurement is greater than 27 self.message += f"Measurement is too High! Measurement is {measurement}\\n" # Replace "qwer5678" with an Action ID self.run_action("{qwer5678}", message=self.message) # Run a single specific Action''' new_func.conditional_status = ''' # Example code to provide a return status for other controllers and widgets. status_dict = { 'string_status': f"This is the demo status of the conditional controller. " f"The controller has looped {self.loop_count} times", 'loop_count': self.loop_count, 'error': [] } return status_dict''' if not messages["error"]: new_func.save() new_function_id = new_func.unique_id if not current_app.config['TESTING']: save_conditional_code(messages["error"], new_func.conditional_statement, new_func.conditional_status, new_func.unique_id, ConditionalConditions.query.all(), Actions.query.all(), test=False) elif function_name == 'pid_pid': new_func = PID() new_func.position_y = 999 new_func.save() new_function_id = new_func.unique_id for each_channel, measure_info in PID_INFO['measure'].items(): new_measurement = DeviceMeasurements() if 'name' in measure_info: new_measurement.name = measure_info['name'] if 'measurement_type' in measure_info: new_measurement.measurement_type = measure_info[ 'measurement_type'] new_measurement.device_id = new_func.unique_id new_measurement.measurement = measure_info['measurement'] new_measurement.unit = measure_info['unit'] new_measurement.channel = each_channel if not messages["error"]: new_measurement.save() elif function_name in [ 'trigger_edge', 'trigger_output', 'trigger_output_pwm', 'trigger_timer_daily_time_point', 'trigger_timer_daily_time_span', 'trigger_timer_duration', 'trigger_run_pwm_method', 'trigger_sunrise_sunset' ]: new_func = Trigger() new_func.name = '{}'.format(FUNCTION_INFO[function_name]['name']) new_func.trigger_type = function_name new_func.position_y = 999 if not messages["error"]: new_func.save() new_function_id = new_func.unique_id elif function_name == 'function_actions': new_func = Function() new_func.position_y = 999 new_func.function_type = function_name if not messages["error"]: new_func.save() new_function_id = new_func.unique_id elif function_name in dict_controllers: # Custom Function Controller new_func = CustomController() new_func.device = function_name new_func.position_y = 999 if 'function_name' in dict_controllers[function_name]: new_func.name = dict_controllers[function_name][ 'function_name'] else: new_func.name = 'Function Name' # Generate string to save from custom options messages["error"], custom_options = custom_options_return_json( messages["error"], dict_controllers, device=function_name, use_defaults=True) new_func.custom_options = custom_options new_func.unique_id = set_uuid() if ('execute_at_creation' in dict_controllers[new_func.device] and not current_app.config['TESTING']): messages["error"], new_func = dict_controllers[ new_func.device]['execute_at_creation']( messages["error"], new_func, dict_controllers[new_func.device]) if not messages["error"]: new_func.save() new_function_id = new_func.unique_id elif function_name == '': messages["error"].append("Must select a function type") else: messages["error"].append( f"Unknown function type: '{function_name}'") if not messages["error"]: if function_name in dict_controllers: # # Add measurements defined in the Function Module # if ('measurements_dict' in dict_controllers[function_name] and dict_controllers[function_name]['measurements_dict']): for each_channel in dict_controllers[function_name][ 'measurements_dict']: measure_info = dict_controllers[function_name][ 'measurements_dict'][each_channel] new_measurement = DeviceMeasurements() new_measurement.device_id = new_func.unique_id if 'name' in measure_info: new_measurement.name = measure_info['name'] else: new_measurement.name = "" if 'measurement' in measure_info: new_measurement.measurement = measure_info[ 'measurement'] else: new_measurement.measurement = "" if 'unit' in measure_info: new_measurement.unit = measure_info['unit'] else: new_measurement.unit = "" new_measurement.channel = each_channel new_measurement.save() # # If there are a variable number of measurements # elif ('measurements_variable_amount' in dict_controllers[function_name] and dict_controllers[function_name] ['measurements_variable_amount']): # Add first default measurement with empty unit and measurement new_measurement = DeviceMeasurements() new_measurement.name = "" new_measurement.device_id = new_func.unique_id new_measurement.measurement = "" new_measurement.unit = "" new_measurement.channel = 0 new_measurement.save() # # Add channels defined in the Function Module # if 'channels_dict' in dict_controllers[function_name]: for each_channel, channel_info in dict_controllers[ function_name]['channels_dict'].items(): new_channel = FunctionChannel() new_channel.channel = each_channel new_channel.function_id = new_func.unique_id # Generate string to save from custom options messages[ "error"], custom_options = custom_channel_options_return_json( messages["error"], dict_controllers, None, new_func.unique_id, each_channel, device=new_func.device, use_defaults=True) new_channel.custom_options = custom_options new_channel.save() messages["success"].append( f"{TRANSLATIONS['add']['title']} {TRANSLATIONS['function']['title']}" ) except sqlalchemy.exc.OperationalError as except_msg: messages["error"].append(str(except_msg)) except sqlalchemy.exc.IntegrityError as except_msg: messages["error"].append(str(except_msg)) except Exception as except_msg: logger.exception("Add Function") messages["error"].append(str(except_msg)) return messages, dep_name, list_unmet_deps, dep_message, new_function_id
def input_add(form_add): action = '{action} {controller}'.format( action=TRANSLATIONS['add']['title'], controller=TRANSLATIONS['input']['title']) error = [] dict_inputs = parse_input_information() # only one comma should be in the input_type string if form_add.input_type.data.count(',') > 1: error.append("Invalid input module formatting. It appears there is " "a comma in either 'input_name_unique' or 'interfaces'.") if form_add.input_type.data.count(',') == 1: input_name = form_add.input_type.data.split(',')[0] input_interface = form_add.input_type.data.split(',')[1] else: input_name = '' input_interface = '' error.append("Invalid input string (must be a comma-separated string)") if current_app.config['TESTING']: dep_unmet = False else: dep_unmet, _ = return_dependencies(input_name) if dep_unmet: list_unmet_deps = [] for each_dep in dep_unmet: list_unmet_deps.append(each_dep[0]) error.append("The {dev} device you're trying to add has unmet dependencies: {dep}".format( dev=input_name, dep=', '.join(list_unmet_deps))) if form_add.validate(): new_input = Input() new_input.device = input_name if input_interface: new_input.interface = input_interface if GPIO.RPI_INFO['P1_REVISION'] in [2, 3]: new_input.i2c_bus = 1 else: new_input.i2c_bus = 0 if 'input_name' in dict_inputs[input_name]: new_input.name = dict_inputs[input_name]['input_name'] else: new_input.name = 'Input Name' # # Set default values for new input being added # # input add options if input_name in dict_inputs: def dict_has_value(key): if (key in dict_inputs[input_name] and (dict_inputs[input_name][key] or dict_inputs[input_name][key] == 0)): return True # # Interfacing options # # I2C options if input_interface == 'I2C': if dict_has_value('i2c_location'): new_input.i2c_location = dict_inputs[input_name]['i2c_location'][0] # First entry in list # UART options if dict_has_value('uart_location'): new_input.uart_location = dict_inputs[input_name]['uart_location'] if dict_has_value('ftdi_location'): new_input.uart_location = dict_inputs[input_name]['ftdi_location'] if dict_has_value('uart_baud_rate'): new_input.baud_rate = dict_inputs[input_name]['uart_baud_rate'] if dict_has_value('pin_cs'): new_input.pin_cs = dict_inputs[input_name]['pin_cs'] if dict_has_value('pin_miso'): new_input.pin_miso = dict_inputs[input_name]['pin_miso'] if dict_has_value('pin_mosi'): new_input.pin_mosi = dict_inputs[input_name]['pin_mosi'] if dict_has_value('pin_clock'): new_input.pin_clock = dict_inputs[input_name]['pin_clock'] # Bluetooth (BT) options elif input_interface == 'BT': if dict_has_value('bt_location'): new_input.location = dict_inputs[input_name]['bt_location'] if dict_has_value('bt_adapter'): new_input.bt_adapter = dict_inputs[input_name]['bt_adapter'] # GPIO options elif input_interface == 'GPIO': if dict_has_value('gpio_location'): new_input.gpio_location = dict_inputs[input_name]['gpio_location'] # Custom location location elif dict_has_value('location'): new_input.location = dict_inputs[input_name]['location']['options'][0][0] # First entry in list # # General options # if dict_has_value('period'): new_input.period = dict_inputs[input_name]['period'] # Server Ping options if dict_has_value('times_check'): new_input.times_check = dict_inputs[input_name]['times_check'] if dict_has_value('deadline'): new_input.deadline = dict_inputs[input_name]['deadline'] if dict_has_value('port'): new_input.port = dict_inputs[input_name]['port'] # Signal options if dict_has_value('weighting'): new_input.weighting = dict_inputs[input_name]['weighting'] if dict_has_value('sample_time'): new_input.sample_time = dict_inputs[input_name]['sample_time'] # Analog-to-digital converter options if dict_has_value('adc_gain'): if len(dict_inputs[input_name]['adc_gain']) == 1: new_input.adc_gain = dict_inputs[input_name]['adc_gain'][0] elif len(dict_inputs[input_name]['adc_gain']) > 1: new_input.adc_gain = dict_inputs[input_name]['adc_gain'][0][0] if dict_has_value('adc_resolution'): if len(dict_inputs[input_name]['adc_resolution']) == 1: new_input.adc_resolution = dict_inputs[input_name]['adc_resolution'][0] elif len(dict_inputs[input_name]['adc_resolution']) > 1: new_input.adc_resolution = dict_inputs[input_name]['adc_resolution'][0][0] if dict_has_value('adc_sample_speed'): if len(dict_inputs[input_name]['adc_sample_speed']) == 1: new_input.adc_sample_speed = dict_inputs[input_name]['adc_sample_speed'][0] elif len(dict_inputs[input_name]['adc_sample_speed']) > 1: new_input.adc_sample_speed = dict_inputs[input_name]['adc_sample_speed'][0][0] # Linux command if dict_has_value('cmd_command'): new_input.cmd_command = dict_inputs[input_name]['cmd_command'] # Misc options if dict_has_value('resolution'): if len(dict_inputs[input_name]['resolution']) == 1: new_input.resolution = dict_inputs[input_name]['resolution'][0] elif len(dict_inputs[input_name]['resolution']) > 1: new_input.resolution = dict_inputs[input_name]['resolution'][0][0] if dict_has_value('resolution_2'): if len(dict_inputs[input_name]['resolution_2']) == 1: new_input.resolution_2 = dict_inputs[input_name]['resolution_2'][0] elif len(dict_inputs[input_name]['resolution_2']) > 1: new_input.resolution_2 = dict_inputs[input_name]['resolution_2'][0][0] if dict_has_value('sensitivity'): if len(dict_inputs[input_name]['sensitivity']) == 1: new_input.sensitivity = dict_inputs[input_name]['sensitivity'][0] elif len(dict_inputs[input_name]['sensitivity']) > 1: new_input.sensitivity = dict_inputs[input_name]['sensitivity'][0][0] if dict_has_value('thermocouple_type'): if len(dict_inputs[input_name]['thermocouple_type']) == 1: new_input.thermocouple_type = dict_inputs[input_name]['thermocouple_type'][0] elif len(dict_inputs[input_name]['thermocouple_type']) > 1: new_input.thermocouple_type = dict_inputs[input_name]['thermocouple_type'][0][0] if dict_has_value('sht_voltage'): if len(dict_inputs[input_name]['sht_voltage']) == 1: new_input.sht_voltage = dict_inputs[input_name]['sht_voltage'][0] elif len(dict_inputs[input_name]['sht_voltage']) > 1: new_input.sht_voltage = dict_inputs[input_name]['sht_voltage'][0][0] if dict_has_value('ref_ohm'): new_input.ref_ohm = dict_inputs[input_name]['ref_ohm'] # # Custom Options # list_options = [] if 'custom_options' in dict_inputs[input_name]: for each_option in dict_inputs[input_name]['custom_options']: if each_option['default_value'] is False: default_value = '' else: default_value = each_option['default_value'] option = '{id},{value}'.format( id=each_option['id'], value=default_value) list_options.append(option) new_input.custom_options = ';'.join(list_options) try: if not error: new_input.save() display_order = csv_to_list_of_str( DisplayOrder.query.first().inputs) DisplayOrder.query.first().inputs = add_display_order( display_order, new_input.unique_id) db.session.commit() if ('measurements_dict' in dict_inputs[input_name] and dict_inputs[input_name]['measurements_dict'] != []): for each_channel in dict_inputs[input_name]['measurements_dict']: measure_info = dict_inputs[input_name]['measurements_dict'][each_channel] new_measurement = DeviceMeasurements() if 'name' in measure_info: new_measurement.name = measure_info['name'] new_measurement.device_id = new_input.unique_id new_measurement.measurement = measure_info['measurement'] new_measurement.unit = measure_info['unit'] new_measurement.channel = each_channel new_measurement.save() flash(gettext( "%(type)s Input with ID %(id)s (%(uuid)s) successfully added", type=input_name, id=new_input.id, uuid=new_input.unique_id), "success") except sqlalchemy.exc.OperationalError as except_msg: error.append(except_msg) except sqlalchemy.exc.IntegrityError as except_msg: error.append(except_msg) flash_success_errors(error, action, url_for('routes_page.page_data')) else: flash_form_errors(form_add) if dep_unmet: return 1
def 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
# Set the output_type for PID controller outputs print("Executing post-alembic code for revision {}".format( each_revision)) try: from mycodo.utils.outputs import parse_output_information from mycodo.databases.models import DeviceMeasurements from mycodo.databases.models import Output from mycodo.databases.models import PID dict_outputs = parse_output_information() with session_scope(MYCODO_DB_PATH) as session: for each_pid in session.query(PID).all(): try: new_measurement = DeviceMeasurements() new_measurement.name = "Output (Volume)" new_measurement.device_id = each_pid.unique_id new_measurement.measurement = 'volume' new_measurement.unit = 'ml' new_measurement.channel = 8 session.add(new_measurement) if each_pid.raise_output_id: output_raise = session.query(Output).filter( Output.unique_id == each_pid.raise_output_id).first() if output_raise: # Use first output type listed (default) each_pid.raise_output_type = dict_outputs[output_raise.output_type]['output_types'][0] if each_pid.lower_output_id: output_lower = session.query(Output).filter( Output.unique_id == each_pid.lower_output_id).first() if output_lower: # Use first output type listed (default)
def input_add(form_add): action = '{action} {controller}'.format( action=TRANSLATIONS['add']['title'], controller=TRANSLATIONS['input']['title']) error = [] dict_inputs = parse_input_information() # only one comma should be in the input_type string if form_add.input_type.data.count(',') > 1: error.append("Invalid input module formatting. It appears there is " "a comma in either 'input_name_unique' or 'interfaces'.") if form_add.input_type.data.count(',') == 1: input_name = form_add.input_type.data.split(',')[0] input_interface = form_add.input_type.data.split(',')[1] else: input_name = '' input_interface = '' error.append("Invalid input string (must be a comma-separated string)") if current_app.config['TESTING']: dep_unmet = False else: dep_unmet, _ = return_dependencies(input_name) if dep_unmet: list_unmet_deps = [] for each_dep in dep_unmet: list_unmet_deps.append(each_dep[0]) error.append( "The {dev} device you're trying to add has unmet dependencies: {dep}" .format(dev=input_name, dep=', '.join(list_unmet_deps))) if form_add.validate(): new_input = Input() new_input.device = input_name if input_interface: new_input.interface = input_interface try: from RPi import GPIO if GPIO.RPI_INFO['P1_REVISION'] == 1: new_input.i2c_bus = 0 else: new_input.i2c_bus = 1 except: logger.error("RPi.GPIO and Raspberry Pi required for this action") if 'input_name' in dict_inputs[input_name]: new_input.name = dict_inputs[input_name]['input_name'] else: new_input.name = 'Name' # # Set default values for new input being added # # input add options if input_name in dict_inputs: def dict_has_value(key): if (key in dict_inputs[input_name] and (dict_inputs[input_name][key] or dict_inputs[input_name][key] == 0)): return True # # Interfacing options # if input_interface == 'I2C': if dict_has_value('i2c_location'): new_input.i2c_location = dict_inputs[input_name][ 'i2c_location'][0] # First entry in list if input_interface == 'FTDI': if dict_has_value('ftdi_location'): new_input.ftdi_location = dict_inputs[input_name][ 'ftdi_location'] if input_interface == 'UART': if dict_has_value('uart_location'): new_input.uart_location = dict_inputs[input_name][ 'uart_location'] # UART options if dict_has_value('uart_baud_rate'): new_input.baud_rate = dict_inputs[input_name]['uart_baud_rate'] if dict_has_value('pin_cs'): new_input.pin_cs = dict_inputs[input_name]['pin_cs'] if dict_has_value('pin_miso'): new_input.pin_miso = dict_inputs[input_name]['pin_miso'] if dict_has_value('pin_mosi'): new_input.pin_mosi = dict_inputs[input_name]['pin_mosi'] if dict_has_value('pin_clock'): new_input.pin_clock = dict_inputs[input_name]['pin_clock'] # Bluetooth (BT) options elif input_interface == 'BT': if dict_has_value('bt_location'): new_input.location = dict_inputs[input_name]['bt_location'] if dict_has_value('bt_adapter'): new_input.bt_adapter = dict_inputs[input_name][ 'bt_adapter'] # GPIO options elif input_interface == 'GPIO': if dict_has_value('gpio_location'): new_input.gpio_location = dict_inputs[input_name][ 'gpio_location'] # Custom location location elif dict_has_value('location'): new_input.location = dict_inputs[input_name]['location'][ 'options'][0][0] # First entry in list # # General options # if dict_has_value('period'): new_input.period = dict_inputs[input_name]['period'] # Server Ping options if dict_has_value('times_check'): new_input.times_check = dict_inputs[input_name]['times_check'] if dict_has_value('deadline'): new_input.deadline = dict_inputs[input_name]['deadline'] if dict_has_value('port'): new_input.port = dict_inputs[input_name]['port'] # Signal options if dict_has_value('weighting'): new_input.weighting = dict_inputs[input_name]['weighting'] if dict_has_value('sample_time'): new_input.sample_time = dict_inputs[input_name]['sample_time'] # Analog-to-digital converter options if dict_has_value('adc_gain'): if len(dict_inputs[input_name]['adc_gain']) == 1: new_input.adc_gain = dict_inputs[input_name]['adc_gain'][0] elif len(dict_inputs[input_name]['adc_gain']) > 1: new_input.adc_gain = dict_inputs[input_name]['adc_gain'][ 0][0] if dict_has_value('adc_resolution'): if len(dict_inputs[input_name]['adc_resolution']) == 1: new_input.adc_resolution = dict_inputs[input_name][ 'adc_resolution'][0] elif len(dict_inputs[input_name]['adc_resolution']) > 1: new_input.adc_resolution = dict_inputs[input_name][ 'adc_resolution'][0][0] if dict_has_value('adc_sample_speed'): if len(dict_inputs[input_name]['adc_sample_speed']) == 1: new_input.adc_sample_speed = dict_inputs[input_name][ 'adc_sample_speed'][0] elif len(dict_inputs[input_name]['adc_sample_speed']) > 1: new_input.adc_sample_speed = dict_inputs[input_name][ 'adc_sample_speed'][0][0] # Linux command if dict_has_value('cmd_command'): new_input.cmd_command = dict_inputs[input_name]['cmd_command'] # Misc options if dict_has_value('resolution'): if len(dict_inputs[input_name]['resolution']) == 1: new_input.resolution = dict_inputs[input_name][ 'resolution'][0] elif len(dict_inputs[input_name]['resolution']) > 1: new_input.resolution = dict_inputs[input_name][ 'resolution'][0][0] if dict_has_value('resolution_2'): if len(dict_inputs[input_name]['resolution_2']) == 1: new_input.resolution_2 = dict_inputs[input_name][ 'resolution_2'][0] elif len(dict_inputs[input_name]['resolution_2']) > 1: new_input.resolution_2 = dict_inputs[input_name][ 'resolution_2'][0][0] if dict_has_value('sensitivity'): if len(dict_inputs[input_name]['sensitivity']) == 1: new_input.sensitivity = dict_inputs[input_name][ 'sensitivity'][0] elif len(dict_inputs[input_name]['sensitivity']) > 1: new_input.sensitivity = dict_inputs[input_name][ 'sensitivity'][0][0] if dict_has_value('thermocouple_type'): if len(dict_inputs[input_name]['thermocouple_type']) == 1: new_input.thermocouple_type = dict_inputs[input_name][ 'thermocouple_type'][0] elif len(dict_inputs[input_name]['thermocouple_type']) > 1: new_input.thermocouple_type = dict_inputs[input_name][ 'thermocouple_type'][0][0] if dict_has_value('sht_voltage'): if len(dict_inputs[input_name]['sht_voltage']) == 1: new_input.sht_voltage = dict_inputs[input_name][ 'sht_voltage'][0] elif len(dict_inputs[input_name]['sht_voltage']) > 1: new_input.sht_voltage = dict_inputs[input_name][ 'sht_voltage'][0][0] if dict_has_value('ref_ohm'): new_input.ref_ohm = dict_inputs[input_name]['ref_ohm'] # # Custom Options # # Generate string to save from custom options error, custom_options = custom_options_return_json(error, dict_inputs, device=input_name, use_defaults=True) new_input.custom_options = custom_options # # Execute at Creation # new_input.unique_id = set_uuid() if ('execute_at_creation' in dict_inputs[new_input.device] and not current_app.config['TESTING']): new_input = dict_inputs[new_input.device]['execute_at_creation']( new_input, dict_inputs[new_input.device]) try: if not error: new_input.save() display_order = csv_to_list_of_str( DisplayOrder.query.first().inputs) DisplayOrder.query.first().inputs = add_display_order( display_order, new_input.unique_id) db.session.commit() # # If there are a variable number of measurements # if ('measurements_variable_amount' in dict_inputs[input_name] and dict_inputs[input_name] ['measurements_variable_amount']): # Add first default measurement with empty unit and measurement new_measurement = DeviceMeasurements() new_measurement.name = "" new_measurement.device_id = new_input.unique_id new_measurement.measurement = "" new_measurement.unit = "" new_measurement.channel = 0 new_measurement.save() # # If measurements defined in the Input Module # elif ('measurements_dict' in dict_inputs[input_name] and dict_inputs[input_name]['measurements_dict'] != []): for each_channel in dict_inputs[input_name][ 'measurements_dict']: measure_info = dict_inputs[input_name][ 'measurements_dict'][each_channel] new_measurement = DeviceMeasurements() if 'name' in measure_info: new_measurement.name = measure_info['name'] new_measurement.device_id = new_input.unique_id new_measurement.measurement = measure_info[ 'measurement'] new_measurement.unit = measure_info['unit'] new_measurement.channel = each_channel new_measurement.save() flash( gettext( "%(type)s Input with ID %(id)s (%(uuid)s) successfully added", type=input_name, id=new_input.id, uuid=new_input.unique_id), "success") except sqlalchemy.exc.OperationalError as except_msg: error.append(except_msg) except sqlalchemy.exc.IntegrityError as except_msg: error.append(except_msg) flash_success_errors(error, action, url_for('routes_page.page_data')) else: flash_form_errors(form_add) if dep_unmet: return 1
def output_add(form_add, request_form): action = '{action} {controller}'.format( action=TRANSLATIONS['add']['title'], controller=TRANSLATIONS['output']['title']) error = [] dict_outputs = parse_output_information() if current_app.config['TESTING']: dep_unmet = False else: dep_unmet, _ = return_dependencies(form_add.output_type.data.split(',')[0]) if dep_unmet: list_unmet_deps = [] for each_dep in dep_unmet: list_unmet_deps.append(each_dep[0]) error.append("The {dev} device you're trying to add has unmet dependencies: {dep}".format( dev=form_add.output_type.data.split(',')[0], dep=', '.join(list_unmet_deps))) if not is_int(form_add.output_quantity.data, check_range=[1, 20]): error.append("{error}. {accepted_values}: 1-20".format( error=gettext("Invalid quantity"), accepted_values=gettext("Acceptable values") )) if form_add.output_type.data.count(',') == 1: output_type = form_add.output_type.data.split(',')[0] output_interface = form_add.output_type.data.split(',')[1] else: output_type = '' output_interface = '' error.append("Invalid output string (must be a comma-separated string)") if not error: for _ in range(0, form_add.output_quantity.data): try: new_output = Output() try: from RPi import GPIO if GPIO.RPI_INFO['P1_REVISION'] == 1: new_output.i2c_bus = 0 else: new_output.i2c_bus = 1 except: logger.error( "RPi.GPIO and Raspberry Pi required for this action") new_output.name = "Name" new_output.output_type = output_type new_output.interface = output_interface # # Set default values for new input being added # # input add options if output_type in dict_outputs: def dict_has_value(key): if (key in dict_outputs[output_type] and dict_outputs[output_type][key] is not None): return True # # Interfacing options # if output_interface == 'I2C': if dict_has_value('i2c_address_default'): new_output.i2c_location = dict_outputs[output_type]['i2c_address_default'] elif dict_has_value('i2c_location'): new_output.i2c_location = dict_outputs[output_type]['i2c_location'][0] # First list entry if output_interface == 'FTDI': if dict_has_value('ftdi_location'): new_output.ftdi_location = dict_outputs[output_type]['ftdi_location'] if output_interface == 'UART': if dict_has_value('uart_location'): new_output.uart_location = dict_outputs[output_type]['uart_location'] # UART options if dict_has_value('uart_baud_rate'): new_output.baud_rate = dict_outputs[output_type]['uart_baud_rate'] if dict_has_value('pin_cs'): new_output.pin_cs = dict_outputs[output_type]['pin_cs'] if dict_has_value('pin_miso'): new_output.pin_miso = dict_outputs[output_type]['pin_miso'] if dict_has_value('pin_mosi'): new_output.pin_mosi = dict_outputs[output_type]['pin_mosi'] if dict_has_value('pin_clock'): new_output.pin_clock = dict_outputs[output_type]['pin_clock'] # Bluetooth (BT) options elif output_interface == 'BT': if dict_has_value('bt_location'): new_output.location = dict_outputs[output_type]['bt_location'] if dict_has_value('bt_adapter'): new_output.bt_adapter = dict_outputs[output_type]['bt_adapter'] # GPIO options elif output_interface == 'GPIO': if dict_has_value('gpio_pin'): new_output.pin = dict_outputs[output_type]['gpio_pin'] # Custom location location elif dict_has_value('location'): new_output.location = dict_outputs[output_type]['location']['options'][0][0] # First entry in list # Generate string to save from custom options error, custom_options = custom_options_return_json( error, dict_outputs, request_form, device=output_type, use_defaults=True) new_output.custom_options = custom_options # # Execute at Creation # new_output.unique_id = set_uuid() if 'execute_at_creation' in dict_outputs[output_type] and not current_app.config['TESTING']: dict_outputs[output_type]['execute_at_creation']( new_output, dict_outputs[output_type]) if not error: new_output.save() display_order = csv_to_list_of_str( DisplayOrder.query.first().output) DisplayOrder.query.first().output = add_display_order( display_order, new_output.unique_id) db.session.commit() # # If measurements defined in the Output Module # if ('measurements_dict' in dict_outputs[output_type] and dict_outputs[output_type]['measurements_dict'] != []): for each_measurement in dict_outputs[output_type]['measurements_dict']: measure_info = dict_outputs[output_type]['measurements_dict'][each_measurement] new_measurement = DeviceMeasurements() if 'name' in measure_info: new_measurement.name = measure_info['name'] new_measurement.device_id = new_output.unique_id new_measurement.measurement = measure_info['measurement'] new_measurement.unit = measure_info['unit'] new_measurement.channel = each_measurement new_measurement.save() for each_channel, channel_info in dict_outputs[output_type]['channels_dict'].items(): new_channel = OutputChannel() new_channel.channel = each_channel new_channel.output_id = new_output.unique_id # Generate string to save from custom options error, custom_options = custom_channel_options_return_json( error, dict_outputs, request_form, new_output.unique_id, each_channel, device=output_type, use_defaults=True) new_channel.custom_options = custom_options new_channel.save() # Refresh output settings if not current_app.config['TESTING']: manipulate_output('Add', new_output.unique_id) flash(gettext("{dev} with ID %(id)s successfully added".format( dev=dict_outputs[output_type]['output_name']), id=new_output.id), "success") except sqlalchemy.exc.OperationalError as except_msg: error.append(except_msg) except sqlalchemy.exc.IntegrityError as except_msg: error.append(except_msg) except Exception: logger.exception(1) return dep_unmet
def math_add(form_add_math): action = '{action} {controller}'.format( action=TRANSLATIONS['add']['title'], controller=TRANSLATIONS['math']['title']) error = [] dep_unmet, _ = return_dependencies(form_add_math.math_type.data) if dep_unmet: list_unmet_deps = [] for each_dep in dep_unmet: list_unmet_deps.append(each_dep[0]) error.append( "The {dev} device you're trying to add has unmet dependencies: {dep}" .format(dev=form_add_math.math_type.data, dep=', '.join(list_unmet_deps))) if form_add_math.validate(): new_math = Math() new_math.name = str(MATH_INFO[form_add_math.math_type.data]['name']) new_math.math_type = form_add_math.math_type.data try: new_math.save() display_order = csv_to_list_of_str(DisplayOrder.query.first().math) DisplayOrder.query.first().math = add_display_order( display_order, new_math.unique_id) db.session.commit() if not MATH_INFO[form_add_math.math_type.data]['measure']: new_measurement = DeviceMeasurements() new_measurement.device_id = new_math.unique_id new_measurement.channel = 0 new_measurement.save() else: for each_channel, measure_info in MATH_INFO[ form_add_math.math_type.data]['measure'].items(): new_measurement = DeviceMeasurements() if 'name' in measure_info and measure_info['name']: new_measurement.name = measure_info['name'] new_measurement.device_id = new_math.unique_id new_measurement.measurement = measure_info['measurement'] new_measurement.unit = measure_info['unit'] new_measurement.channel = each_channel new_measurement.save() flash( gettext( "%(type)s Math with ID %(id)s (%(uuid)s) successfully added", type=form_add_math.math_type.data, id=new_math.id, uuid=new_math.unique_id), "success") except sqlalchemy.exc.OperationalError as except_msg: error.append(except_msg) except sqlalchemy.exc.IntegrityError as except_msg: error.append(except_msg) flash_success_errors(error, action, url_for('routes_page.page_data')) else: flash_form_errors(form_add_math) if dep_unmet: return 1
def controller_mod(form_mod, request_form): """Modify a Custom Function""" error = [] action = '{action} {controller}'.format( action=TRANSLATIONS['modify']['title'], controller=TRANSLATIONS['controller']['title']) dict_controllers = parse_function_information() try: mod_controller = CustomController.query.filter( CustomController.unique_id == form_mod.function_id.data).first() if mod_controller.is_activated: error.append( gettext("Deactivate controller before modifying its settings")) mod_controller.name = form_mod.name.data mod_controller.log_level_debug = form_mod.log_level_debug.data # Enable/disable Channels measurements = DeviceMeasurements.query.filter( DeviceMeasurements.device_id == form_mod.function_id.data).all() if form_mod.measurements_enabled.data: for each_measurement in measurements: if each_measurement.unique_id in form_mod.measurements_enabled.data: each_measurement.is_enabled = True else: each_measurement.is_enabled = False channels = FunctionChannel.query.filter( FunctionChannel.function_id == form_mod.function_id.data) # Add or delete channels for variable measurement Inputs if ('measurements_variable_amount' in dict_controllers[mod_controller.device] and dict_controllers[ mod_controller.device]['measurements_variable_amount']): measurements = DeviceMeasurements.query.filter( DeviceMeasurements.device_id == form_mod.function_id.data) if measurements.count() != form_mod.num_channels.data: # Delete measurements/channels if form_mod.num_channels.data < measurements.count(): for index, each_channel in enumerate(measurements.all()): if index + 1 >= measurements.count(): delete_entry_with_id(DeviceMeasurements, each_channel.unique_id) if ('channel_quantity_same_as_measurements' in dict_controllers[mod_controller.device] and dict_controllers[mod_controller.device] ["channel_quantity_same_as_measurements"]): if form_mod.num_channels.data < channels.count(): for index, each_channel in enumerate( channels.all()): if index + 1 >= channels.count(): delete_entry_with_id( FunctionChannel, each_channel.unique_id) # Add measurements/channels elif form_mod.num_channels.data > measurements.count(): start_number = measurements.count() for index in range(start_number, form_mod.num_channels.data): new_measurement = DeviceMeasurements() new_measurement.name = "" new_measurement.device_id = mod_controller.unique_id new_measurement.measurement = "" new_measurement.unit = "" new_measurement.channel = index new_measurement.save() if ('channel_quantity_same_as_measurements' in dict_controllers[mod_controller.device] and dict_controllers[mod_controller.device] ["channel_quantity_same_as_measurements"]): new_channel = FunctionChannel() new_channel.name = "" new_channel.function_id = mod_controller.unique_id new_measurement.channel = index error, custom_options = custom_channel_options_return_json( error, dict_controllers, request_form, mod_controller.unique_id, index, device=mod_controller.device, use_defaults=True) new_channel.custom_options = custom_options new_channel.save() # Generate string to save from custom options error, custom_options = custom_options_return_json( error, dict_controllers, request_form=request_form, device=mod_controller.device, use_defaults=True) mod_controller.custom_options = custom_options if not error: 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'))
def controller_mod(form_mod, request_form): """Modify a Custom Function""" error = [] action = '{action} {controller}'.format( action=TRANSLATIONS['modify']['title'], controller=TRANSLATIONS['controller']['title']) dict_controllers = parse_function_information() try: channels = FunctionChannel.query.filter( FunctionChannel.function_id == form_mod.function_id.data).all() mod_controller = CustomController.query.filter( CustomController.unique_id == form_mod.function_id.data).first() if mod_controller.is_activated: error.append( gettext("Deactivate controller before modifying its settings")) mod_controller.name = form_mod.name.data mod_controller.log_level_debug = form_mod.log_level_debug.data # Enable/disable Channels measurements = DeviceMeasurements.query.filter( DeviceMeasurements.device_id == form_mod.function_id.data).all() if form_mod.measurements_enabled.data: for each_measurement in measurements: if each_measurement.unique_id in form_mod.measurements_enabled.data: each_measurement.is_enabled = True else: each_measurement.is_enabled = False # Add or delete channels for variable measurement Inputs if ('measurements_variable_amount' in dict_controllers[mod_controller.device] and dict_controllers[ mod_controller.device]['measurements_variable_amount']): measurements = DeviceMeasurements.query.filter( DeviceMeasurements.device_id == form_mod.function_id.data) if measurements.count() != form_mod.num_channels.data: # Delete measurements/channels if form_mod.num_channels.data < measurements.count(): for index, each_channel in enumerate(measurements.all()): if index + 1 >= measurements.count(): delete_entry_with_id(DeviceMeasurements, each_channel.unique_id) if ('channel_quantity_same_as_measurements' in dict_controllers[mod_controller.device] and dict_controllers[mod_controller.device] ["channel_quantity_same_as_measurements"]): if form_mod.num_channels.data < channels.count(): for index, each_channel in enumerate( channels.all()): if index + 1 >= channels.count(): delete_entry_with_id( FunctionChannel, each_channel.unique_id) # Add measurements/channels elif form_mod.num_channels.data > measurements.count(): start_number = measurements.count() for index in range(start_number, form_mod.num_channels.data): new_measurement = DeviceMeasurements() new_measurement.name = "" new_measurement.device_id = mod_controller.unique_id new_measurement.measurement = "" new_measurement.unit = "" new_measurement.channel = index new_measurement.save() if ('channel_quantity_same_as_measurements' in dict_controllers[mod_controller.device] and dict_controllers[mod_controller.device] ["channel_quantity_same_as_measurements"]): new_channel = FunctionChannel() new_channel.name = "" new_channel.function_id = mod_controller.unique_id new_channel.channel = index error, custom_options = custom_channel_options_return_json( error, dict_controllers, request_form, mod_controller.unique_id, index, device=mod_controller.device, use_defaults=True) new_channel.custom_options = custom_options new_channel.save() # Parse pre-save custom options for function device and its channels try: custom_options_dict_presave = json.loads( mod_controller.custom_options) except: logger.error("Malformed JSON") custom_options_dict_presave = {} custom_options_channels_dict_presave = {} for each_channel in channels: if each_channel.custom_options and each_channel.custom_options != "{}": custom_options_channels_dict_presave[ each_channel.channel] = json.loads( each_channel.custom_options) else: custom_options_channels_dict_presave[each_channel.channel] = {} # Parse post-save custom options for function device and its channels error, custom_options_json_postsave = custom_options_return_json( error, dict_controllers, request_form=request_form, device=mod_controller.device, use_defaults=True) custom_options_dict_postsave = json.loads(custom_options_json_postsave) custom_options_channels_dict_postsave = {} for each_channel in channels: error, custom_options_channels_json_postsave_tmp = custom_channel_options_return_json( error, dict_controllers, request_form, form_mod.function_id.data, each_channel.channel, device=mod_controller.device, use_defaults=True) custom_options_channels_dict_postsave[ each_channel.channel] = json.loads( custom_options_channels_json_postsave_tmp) if 'execute_at_modification' in dict_controllers[ mod_controller.device]: # pass custom options to module prior to saving to database (allow_saving, mod_controller, custom_options_dict, custom_options_channels_dict) = dict_controllers[ mod_controller.device]['execute_at_modification']( mod_controller, request_form, custom_options_dict_presave, custom_options_channels_dict_presave, custom_options_dict_postsave, custom_options_channels_dict_postsave) custom_options = json.dumps( custom_options_dict) # Convert from dict to JSON string custom_channel_options = custom_options_channels_dict if not allow_saving: error.append( "execute_at_modification() would not allow function options to be saved" ) else: # Don't pass custom options to module custom_options = json.dumps(custom_options_dict_postsave) custom_channel_options = custom_options_channels_dict_postsave # Finally, save custom options for both function and channels mod_controller.custom_options = custom_options for each_channel in channels: if 'name' in custom_channel_options[each_channel.channel]: each_channel.name = custom_channel_options[ each_channel.channel]['name'] each_channel.custom_options = json.dumps( custom_channel_options[each_channel.channel]) if not error: 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'))
def output_add(form_add, request_form): messages = { "success": [], "info": [], "warning": [], "error": [] } output_id = None dep_name = None size_y = None dict_outputs = parse_output_information() if form_add.output_type.data.count(',') == 1: output_type = form_add.output_type.data.split(',')[0] output_interface = form_add.output_type.data.split(',')[1] else: output_type = '' output_interface = '' messages["error"].append("Invalid output string (must be a comma-separated string)") if current_app.config['TESTING']: dep_unmet = False else: dep_unmet, _ = return_dependencies(form_add.output_type.data.split(',')[0]) if dep_unmet: list_unmet_deps = [] for each_dep in dep_unmet: list_unmet_deps.append(each_dep[0]) messages["error"].append( "{dev} has unmet dependencies. They must be installed before the Output can be added.".format( dev=output_type)) if output_type in dict_outputs: dep_name = dict_outputs[output_type]["output_name"] else: messages["error"].append("Output not found: {}".format(output_type)) return messages, dep_name, list_unmet_deps, None, None if not is_int(form_add.output_quantity.data, check_range=[1, 20]): messages["error"].append("{error}. {accepted_values}: 1-20".format( error=gettext("Invalid quantity"), accepted_values=gettext("Acceptable values") )) if not messages["error"]: for _ in range(0, form_add.output_quantity.data): try: new_output = Output() try: from RPi import GPIO if GPIO.RPI_INFO['P1_REVISION'] == 1: new_output.i2c_bus = 0 else: new_output.i2c_bus = 1 except: logger.error( "RPi.GPIO and Raspberry Pi required for this action") new_output.name = "Name" new_output.interface = output_interface size_y = len(dict_outputs[output_type]['channels_dict']) + 1 new_output.size_y = len(dict_outputs[output_type]['channels_dict']) + 1 new_output.output_type = output_type new_output.position_y = 999 # # Set default values for new input being added # # input add options if output_type in dict_outputs: def dict_has_value(key): if (key in dict_outputs[output_type] and dict_outputs[output_type][key] is not None): return True # # Interfacing options # if output_interface == 'I2C': if dict_has_value('i2c_address_default'): new_output.i2c_location = dict_outputs[output_type]['i2c_address_default'] elif dict_has_value('i2c_location'): new_output.i2c_location = dict_outputs[output_type]['i2c_location'][0] # First list entry if output_interface == 'FTDI': if dict_has_value('ftdi_location'): new_output.ftdi_location = dict_outputs[output_type]['ftdi_location'] if output_interface == 'UART': if dict_has_value('uart_location'): new_output.uart_location = dict_outputs[output_type]['uart_location'] # UART options if dict_has_value('uart_baud_rate'): new_output.baud_rate = dict_outputs[output_type]['uart_baud_rate'] if dict_has_value('pin_cs'): new_output.pin_cs = dict_outputs[output_type]['pin_cs'] if dict_has_value('pin_miso'): new_output.pin_miso = dict_outputs[output_type]['pin_miso'] if dict_has_value('pin_mosi'): new_output.pin_mosi = dict_outputs[output_type]['pin_mosi'] if dict_has_value('pin_clock'): new_output.pin_clock = dict_outputs[output_type]['pin_clock'] # Bluetooth (BT) options elif output_interface == 'BT': if dict_has_value('bt_location'): new_output.location = dict_outputs[output_type]['bt_location'] if dict_has_value('bt_adapter'): new_output.bt_adapter = dict_outputs[output_type]['bt_adapter'] # GPIO options elif output_interface == 'GPIO': if dict_has_value('gpio_pin'): new_output.pin = dict_outputs[output_type]['gpio_pin'] # Custom location location elif dict_has_value('location'): new_output.location = dict_outputs[output_type]['location']['options'][0][0] # First entry in list # Generate string to save from custom options messages["error"], custom_options = custom_options_return_json( messages["error"], dict_outputs, request_form, device=output_type, use_defaults=True) new_output.custom_options = custom_options # # Execute at Creation # new_output.unique_id = set_uuid() if 'execute_at_creation' in dict_outputs[output_type] and not current_app.config['TESTING']: messages["error"], new_output = dict_outputs[output_type]['execute_at_creation']( messages["error"], new_output, dict_outputs[output_type]) if not messages["error"]: new_output.save() output_id = new_output.unique_id db.session.commit() messages["success"].append('{action} {controller}'.format( action=TRANSLATIONS['add']['title'], controller=TRANSLATIONS['output']['title'])) # # If measurements defined in the Output Module # if ('measurements_dict' in dict_outputs[output_type] and dict_outputs[output_type]['measurements_dict'] != []): for each_measurement in dict_outputs[output_type]['measurements_dict']: measure_info = dict_outputs[output_type]['measurements_dict'][each_measurement] new_measurement = DeviceMeasurements() if 'name' in measure_info: new_measurement.name = measure_info['name'] new_measurement.device_id = new_output.unique_id new_measurement.measurement = measure_info['measurement'] new_measurement.unit = measure_info['unit'] new_measurement.channel = each_measurement new_measurement.save() for each_channel, channel_info in dict_outputs[output_type]['channels_dict'].items(): new_channel = OutputChannel() new_channel.channel = each_channel new_channel.output_id = new_output.unique_id # Generate string to save from custom options messages["error"], custom_options = custom_channel_options_return_json( messages["error"], dict_outputs, request_form, new_output.unique_id, each_channel, device=output_type, use_defaults=True) new_channel.custom_options = custom_options new_channel.save() # Refresh output settings if not current_app.config['TESTING']: new_messages = manipulate_output( 'Add', new_output.unique_id) messages["error"].extend(new_messages["error"]) messages["success"].extend(new_messages["success"]) except sqlalchemy.exc.OperationalError as except_msg: messages["error"].append(str(except_msg)) except sqlalchemy.exc.IntegrityError as except_msg: messages["error"].append(str(except_msg)) except Exception as except_msg: messages["error"].append(str(except_msg)) logger.exception(1) return messages, dep_unmet, None, output_id, size_y
def function_add(form_add_func): action = '{action} {controller}'.format( action=TRANSLATIONS['add']['title'], controller=TRANSLATIONS['function']['title']) error = [] new_func = None try: if form_add_func.func_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.func_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.func_type.data.startswith('trigger_'): new_func = Trigger() for name_id, name, _ in FUNCTION_TYPES: if form_add_func.func_type.data == name_id: new_func.name = '{}'.format(name) new_func.trigger_type = form_add_func.func_type.data new_func.save() elif form_add_func.func_type.data.startswith('function_'): new_func = Function() if form_add_func.func_type.data == 'function_spacer': new_func.name = 'Spacer' new_func.function_type = form_add_func.func_type.data new_func.save() elif form_add_func.func_type.data == '': error.append("Must select a function type") else: error.append("Unknown function type: '{}'".format( form_add_func.func_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'))
DeviceMeasurements.device_id == each_output.unique_id).first(): # No output device measurements exist. Need to create them. if ('measurements_dict' in dict_outputs[each_output.output_type] and dict_outputs[each_output.output_type] ['measurements_dict'] != []): for each_channel in dict_outputs[ each_output. output_type]['measurements_dict']: measure_info = dict_outputs[ each_output.output_type][ 'measurements_dict'][each_channel] new_measurement = DeviceMeasurements() if 'name' in measure_info: new_measurement.name = measure_info[ 'name'] new_measurement.device_id = each_output.unique_id new_measurement.measurement = measure_info[ 'measurement'] new_measurement.unit = measure_info['unit'] new_measurement.channel = each_channel session.add(new_measurement) session.commit() except Exception: msg = "ERROR: post-alembic revision {}: {}".format( each_revision, traceback.format_exc()) error.append(msg) print(msg) elif each_revision == '61a0d0568d24':
def function_add(form_add_func): action = '{action} {controller}'.format( action=TRANSLATIONS['add']['title'], controller=TRANSLATIONS['function']['title']) error = [] function_name = form_add_func.function_type.data dict_controllers = parse_function_information() if current_app.config['TESTING']: dep_unmet = False else: dep_unmet, _ = return_dependencies(function_name) if dep_unmet: list_unmet_deps = [] for each_dep in dep_unmet: list_unmet_deps.append(each_dep[0]) error.append( "The {dev} device you're trying to add has unmet " "dependencies: {dep}".format(dev=function_name, dep=', '.join(list_unmet_deps))) new_func = None try: if function_name == 'conditional_conditional': new_func = Conditional() new_func.conditional_statement = ''' # Example code for learning how to use a Conditional. See the manual for more information. self.logger.info("This INFO log entry will appear in the Daemon Log") self.logger.error("This ERROR log entry will appear in the Daemon Log") # Replace "asdf1234" with a Condition ID measurement = self.condition("{asdf1234}") self.logger.info("Check this measurement in the Daemon Log. The value is {val}".format(val=measurement)) if measurement is not None: # If a measurement exists self.message += "This message appears in email alerts and notes.\\n" if measurement < 23: # If the measurement is less than 23 self.message += "Measurement is too Low! Measurement is {meas}\\n".format(meas=measurement) self.run_all_actions(message=self.message) # Run all actions sequentially elif measurement > 27: # Else If the measurement is greater than 27 self.message += "Measurement is too High! Measurement is {meas}\\n".format(meas=measurement) # Replace "qwer5678" with an Action ID self.run_action("{qwer5678}", message=self.message) # Run a single specific Action''' if not error: new_func.save() save_conditional_code(error, new_func.conditional_statement, new_func.unique_id, ConditionalConditions.query.all(), Actions.query.all(), test=False) elif function_name == 'pid_pid': new_func = PID().save() for each_channel, measure_info in PID_INFO['measure'].items(): new_measurement = DeviceMeasurements() if 'name' in measure_info: new_measurement.name = measure_info['name'] if 'measurement_type' in measure_info: new_measurement.measurement_type = measure_info[ 'measurement_type'] new_measurement.device_id = new_func.unique_id new_measurement.measurement = measure_info['measurement'] new_measurement.unit = measure_info['unit'] new_measurement.channel = each_channel if not error: new_measurement.save() elif function_name in [ 'trigger_edge', 'trigger_output', 'trigger_output_pwm', 'trigger_timer_daily_time_point', 'trigger_timer_daily_time_span', 'trigger_timer_duration', 'trigger_infrared_remote_input', 'trigger_run_pwm_method', 'trigger_sunrise_sunset' ]: new_func = Trigger() new_func.name = '{}'.format(FUNCTION_INFO[function_name]['name']) new_func.trigger_type = function_name if not error: new_func.save() elif function_name in ['function_spacer', 'function_actions']: new_func = Function() if function_name == 'function_spacer': new_func.name = 'Spacer' new_func.function_type = function_name if not error: new_func.save() elif function_name in dict_controllers: # Custom Function Controller new_func = CustomController() new_func.device = function_name if 'function_name' in dict_controllers[function_name]: new_func.name = dict_controllers[function_name][ 'function_name'] else: new_func.name = 'Function Name' # TODO: Switch to JSON function list_options = [] if 'custom_options' in dict_controllers[function_name]: for each_option in dict_controllers[function_name][ 'custom_options']: if 'id' not in each_option: continue if each_option['default_value'] is False: default_value = '' else: default_value = each_option['default_value'] option = '{id},{value}'.format(id=each_option['id'], value=default_value) list_options.append(option) new_func.custom_options = ';'.join(list_options) if not error: new_func.save() elif function_name == '': error.append("Must select a function type") else: error.append("Unknown function type: '{}'".format(function_name)) if not error: display_order = csv_to_list_of_str( DisplayOrder.query.first().function) DisplayOrder.query.first().function = add_display_order( display_order, new_func.unique_id) db.session.commit() except sqlalchemy.exc.OperationalError as except_msg: error.append(except_msg) except sqlalchemy.exc.IntegrityError as except_msg: error.append(except_msg) except Exception as except_msg: error.append(except_msg) flash_success_errors(error, action, url_for('routes_page.page_function')) if dep_unmet: return 1
def input_add(form_add): messages = {"success": [], "info": [], "warning": [], "error": []} new_input_id = None list_unmet_deps = [] dep_name = None dep_message = '' dict_inputs = parse_input_information() # only one comma should be in the input_type string if form_add.input_type.data.count(',') > 1: messages["error"].append( "Invalid input module formatting. It appears there is " "a comma in either 'input_name_unique' or 'interfaces'.") if form_add.input_type.data.count(',') == 1: input_name = form_add.input_type.data.split(',')[0] input_interface = form_add.input_type.data.split(',')[1] else: input_name = '' input_interface = '' messages["error"].append( "Invalid input string (must be a comma-separated string)") if not current_app.config['TESTING']: dep_unmet, _, dep_message = return_dependencies(input_name) if dep_unmet: for each_dep in dep_unmet: list_unmet_deps.append(each_dep[3]) messages["error"].append( f"{input_name} has unmet dependencies. They must be installed before the Input can be added." ) if input_name in dict_inputs: dep_name = dict_inputs[input_name]['input_name'] else: messages["error"].append(f"Input not found: {input_name}") return messages, dep_name, list_unmet_deps, dep_message, None if form_add.validate(): new_input = Input() new_input.device = input_name new_input.position_y = 999 if input_interface: new_input.interface = input_interface new_input.i2c_bus = 1 if 'input_name_short' in dict_inputs[input_name]: new_input.name = dict_inputs[input_name]['input_name_short'] elif 'input_name' in dict_inputs[input_name]: new_input.name = dict_inputs[input_name]['input_name'] else: new_input.name = 'Name' # # Set default values for new input being added # # input add options if input_name in dict_inputs: def dict_has_value(key): if (key in dict_inputs[input_name] and (dict_inputs[input_name][key] or dict_inputs[input_name][key] == 0)): return True # # Interfacing options # if input_interface == 'I2C': if dict_has_value('i2c_location'): new_input.i2c_location = dict_inputs[input_name][ 'i2c_location'][0] # First entry in list if input_interface == 'FTDI': if dict_has_value('ftdi_location'): new_input.ftdi_location = dict_inputs[input_name][ 'ftdi_location'] if input_interface == 'UART': if dict_has_value('uart_location'): new_input.uart_location = dict_inputs[input_name][ 'uart_location'] # UART options if dict_has_value('uart_baud_rate'): new_input.baud_rate = dict_inputs[input_name]['uart_baud_rate'] if dict_has_value('pin_cs'): new_input.pin_cs = dict_inputs[input_name]['pin_cs'] if dict_has_value('pin_miso'): new_input.pin_miso = dict_inputs[input_name]['pin_miso'] if dict_has_value('pin_mosi'): new_input.pin_mosi = dict_inputs[input_name]['pin_mosi'] if dict_has_value('pin_clock'): new_input.pin_clock = dict_inputs[input_name]['pin_clock'] # Bluetooth (BT) options elif input_interface == 'BT': if dict_has_value('bt_location'): if not re.match( "[0-9a-fA-F]{2}([:]?)[0-9a-fA-F]{2}(\\1[0-9a-fA-F]{2}){4}$", dict_inputs[input_name]['bt_location']): messages["error"].append( "Please specify device MAC-Address in format AA:BB:CC:DD:EE:FF" ) else: new_input.location = dict_inputs[input_name][ 'bt_location'] if dict_has_value('bt_adapter'): new_input.bt_adapter = dict_inputs[input_name][ 'bt_adapter'] # GPIO options elif input_interface == 'GPIO': if dict_has_value('gpio_location'): new_input.gpio_location = dict_inputs[input_name][ 'gpio_location'] # Custom location location elif dict_has_value('location'): new_input.location = dict_inputs[input_name]['location'][ 'options'][0][0] # First entry in list # # General options # if dict_has_value('period'): new_input.period = dict_inputs[input_name]['period'] # Server Ping options if dict_has_value('times_check'): new_input.times_check = dict_inputs[input_name]['times_check'] if dict_has_value('deadline'): new_input.deadline = dict_inputs[input_name]['deadline'] if dict_has_value('port'): new_input.port = dict_inputs[input_name]['port'] # Signal options if dict_has_value('weighting'): new_input.weighting = dict_inputs[input_name]['weighting'] if dict_has_value('sample_time'): new_input.sample_time = dict_inputs[input_name]['sample_time'] # Analog-to-digital converter options if dict_has_value('adc_gain'): if len(dict_inputs[input_name]['adc_gain']) == 1: new_input.adc_gain = dict_inputs[input_name]['adc_gain'][0] elif len(dict_inputs[input_name]['adc_gain']) > 1: new_input.adc_gain = dict_inputs[input_name]['adc_gain'][ 0][0] if dict_has_value('adc_resolution'): if len(dict_inputs[input_name]['adc_resolution']) == 1: new_input.adc_resolution = dict_inputs[input_name][ 'adc_resolution'][0] elif len(dict_inputs[input_name]['adc_resolution']) > 1: new_input.adc_resolution = dict_inputs[input_name][ 'adc_resolution'][0][0] if dict_has_value('adc_sample_speed'): if len(dict_inputs[input_name]['adc_sample_speed']) == 1: new_input.adc_sample_speed = dict_inputs[input_name][ 'adc_sample_speed'][0] elif len(dict_inputs[input_name]['adc_sample_speed']) > 1: new_input.adc_sample_speed = dict_inputs[input_name][ 'adc_sample_speed'][0][0] # Linux command if dict_has_value('cmd_command'): new_input.cmd_command = dict_inputs[input_name]['cmd_command'] # Misc options if dict_has_value('resolution'): if len(dict_inputs[input_name]['resolution']) == 1: new_input.resolution = dict_inputs[input_name][ 'resolution'][0] elif len(dict_inputs[input_name]['resolution']) > 1: new_input.resolution = dict_inputs[input_name][ 'resolution'][0][0] if dict_has_value('resolution_2'): if len(dict_inputs[input_name]['resolution_2']) == 1: new_input.resolution_2 = dict_inputs[input_name][ 'resolution_2'][0] elif len(dict_inputs[input_name]['resolution_2']) > 1: new_input.resolution_2 = dict_inputs[input_name][ 'resolution_2'][0][0] if dict_has_value('sensitivity'): if len(dict_inputs[input_name]['sensitivity']) == 1: new_input.sensitivity = dict_inputs[input_name][ 'sensitivity'][0] elif len(dict_inputs[input_name]['sensitivity']) > 1: new_input.sensitivity = dict_inputs[input_name][ 'sensitivity'][0][0] if dict_has_value('thermocouple_type'): if len(dict_inputs[input_name]['thermocouple_type']) == 1: new_input.thermocouple_type = dict_inputs[input_name][ 'thermocouple_type'][0] elif len(dict_inputs[input_name]['thermocouple_type']) > 1: new_input.thermocouple_type = dict_inputs[input_name][ 'thermocouple_type'][0][0] if dict_has_value('sht_voltage'): if len(dict_inputs[input_name]['sht_voltage']) == 1: new_input.sht_voltage = dict_inputs[input_name][ 'sht_voltage'][0] elif len(dict_inputs[input_name]['sht_voltage']) > 1: new_input.sht_voltage = dict_inputs[input_name][ 'sht_voltage'][0][0] if dict_has_value('ref_ohm'): new_input.ref_ohm = dict_inputs[input_name]['ref_ohm'] # # Custom Options # # Generate string to save from custom options messages["error"], custom_options = custom_options_return_json( messages["error"], dict_inputs, device=input_name, use_defaults=True) new_input.custom_options = custom_options # # Execute at Creation # new_input.unique_id = set_uuid() if ('execute_at_creation' in dict_inputs[new_input.device] and not current_app.config['TESTING']): messages["error"], new_input = dict_inputs[ new_input.device]['execute_at_creation']( messages["error"], new_input, dict_inputs[new_input.device]) try: if not messages["error"]: new_input.save() new_input_id = new_input.unique_id # # If there are a variable number of measurements # if ('measurements_variable_amount' in dict_inputs[input_name] and dict_inputs[input_name] ['measurements_variable_amount']): # Add first default measurement with empty unit and measurement new_measurement = DeviceMeasurements() new_measurement.name = "" new_measurement.device_id = new_input.unique_id new_measurement.measurement = "" new_measurement.unit = "" new_measurement.channel = 0 new_measurement.save() # # If measurements defined in the Input Module # elif ('measurements_dict' in dict_inputs[input_name] and dict_inputs[input_name]['measurements_dict']): for each_channel in dict_inputs[input_name][ 'measurements_dict']: measure_info = dict_inputs[input_name][ 'measurements_dict'][each_channel] new_measurement = DeviceMeasurements() if 'name' in measure_info: new_measurement.name = measure_info['name'] new_measurement.device_id = new_input.unique_id new_measurement.measurement = measure_info[ 'measurement'] new_measurement.unit = measure_info['unit'] new_measurement.channel = each_channel new_measurement.save() if 'channels_dict' in dict_inputs[new_input.device]: for each_channel, channel_info in dict_inputs[ new_input.device]['channels_dict'].items(): new_channel = InputChannel() new_channel.channel = each_channel new_channel.input_id = new_input.unique_id # Generate string to save from custom options messages[ "error"], custom_options = custom_channel_options_return_json( messages["error"], dict_inputs, None, new_input.unique_id, each_channel, device=new_input.device, use_defaults=True) new_channel.custom_options = custom_options new_channel.save() messages["success"].append( f"{TRANSLATIONS['add']['title']} {TRANSLATIONS['input']['title']}" ) except sqlalchemy.exc.OperationalError as except_msg: messages["error"].append(except_msg) except sqlalchemy.exc.IntegrityError as except_msg: messages["error"].append(except_msg) else: for field, errors in form_add.errors.items(): for error in errors: messages["error"].append( gettext("Error in the %(field)s field - %(err)s", field=getattr(form_add, field).label.text, err=error)) return messages, dep_name, list_unmet_deps, dep_message, new_input_id
def input_mod(form_mod, request_form): action = '{action} {controller}'.format( action=TRANSLATIONS['modify']['title'], controller=TRANSLATIONS['input']['title']) error = [] dict_inputs = parse_input_information() try: mod_input = Input.query.filter( Input.unique_id == form_mod.input_id.data).first() if mod_input.is_activated: error.append( gettext("Deactivate controller before modifying its settings")) if (mod_input.device == 'AM2315' and form_mod.period.data < 7): error.append( gettext("Choose a Read Period equal to or greater than 7. The " "AM2315 may become unresponsive if the period is " "below 7.")) if (mod_input.device != 'EDGE' and (mod_input.pre_output_duration and form_mod.period.data < mod_input.pre_output_duration)): error.append( gettext("The Read Period cannot be less than the Pre Output " "Duration")) if (form_mod.uart_location.data and not os.path.exists(form_mod.uart_location.data)): error.append( gettext( "Invalid device or improper permissions to read device")) if ('gpio_location' in dict_inputs[mod_input.device]['options_enabled'] and form_mod.gpio_location.data is None): error.append(gettext("Pin (GPIO) must be set")) mod_input.name = form_mod.name.data if form_mod.location.data: mod_input.location = form_mod.location.data if form_mod.i2c_location.data: mod_input.i2c_location = form_mod.i2c_location.data if form_mod.ftdi_location.data: mod_input.ftdi_location = form_mod.ftdi_location.data if form_mod.uart_location.data: mod_input.uart_location = form_mod.uart_location.data if form_mod.gpio_location.data and form_mod.gpio_location.data is not None: mod_input.gpio_location = form_mod.gpio_location.data if form_mod.power_output_id.data: mod_input.power_output_id = form_mod.power_output_id.data else: mod_input.power_output_id = None if form_mod.pre_output_id.data: mod_input.pre_output_id = form_mod.pre_output_id.data else: mod_input.pre_output_id = None # Enable/disable Channels measurements = DeviceMeasurements.query.filter( DeviceMeasurements.device_id == form_mod.input_id.data).all() if form_mod.measurements_enabled.data: for each_measurement in measurements: if each_measurement.unique_id in form_mod.measurements_enabled.data: each_measurement.is_enabled = True else: each_measurement.is_enabled = False mod_input.log_level_debug = form_mod.log_level_debug.data mod_input.i2c_bus = form_mod.i2c_bus.data mod_input.baud_rate = form_mod.baud_rate.data mod_input.pre_output_duration = form_mod.pre_output_duration.data mod_input.pre_output_during_measure = form_mod.pre_output_during_measure.data if form_mod.period.data: mod_input.period = form_mod.period.data mod_input.resolution = form_mod.resolution.data mod_input.resolution_2 = form_mod.resolution_2.data mod_input.sensitivity = form_mod.sensitivity.data mod_input.calibrate_sensor_measure = form_mod.calibrate_sensor_measure.data mod_input.cmd_command = form_mod.cmd_command.data mod_input.thermocouple_type = form_mod.thermocouple_type.data mod_input.ref_ohm = form_mod.ref_ohm.data # Serial options mod_input.pin_clock = form_mod.pin_clock.data mod_input.pin_cs = form_mod.pin_cs.data mod_input.pin_mosi = form_mod.pin_mosi.data mod_input.pin_miso = form_mod.pin_miso.data # Bluetooth options mod_input.bt_adapter = form_mod.bt_adapter.data mod_input.adc_gain = form_mod.adc_gain.data mod_input.adc_resolution = form_mod.adc_resolution.data mod_input.adc_sample_speed = form_mod.adc_sample_speed.data # Switch options mod_input.switch_edge = form_mod.switch_edge.data mod_input.switch_bouncetime = form_mod.switch_bouncetime.data mod_input.switch_reset_period = form_mod.switch_reset_period.data # PWM and RPM options mod_input.weighting = form_mod.weighting.data mod_input.rpm_pulses_per_rev = form_mod.rpm_pulses_per_rev.data mod_input.sample_time = form_mod.sample_time.data # Server options mod_input.port = form_mod.port.data mod_input.times_check = form_mod.times_check.data mod_input.deadline = form_mod.deadline.data # SHT sensor options if form_mod.sht_voltage.data: mod_input.sht_voltage = form_mod.sht_voltage.data if 'test_before_saving' in dict_inputs[mod_input.device]: (constraints_pass, constraints_errors, mod_input) = dict_inputs[mod_input.device]['test_before_saving']( mod_input, request_form) if constraints_pass: pass elif constraints_errors: for each_error in constraints_errors: flash(each_error, 'error') # Custom options list_options = [] if 'custom_options' in dict_inputs[mod_input.device]: for each_option in dict_inputs[mod_input.device]['custom_options']: null_value = True for key in request_form.keys(): if each_option['id'] == key: constraints_pass = True constraints_errors = [] value = None if each_option['type'] == 'float': if str_is_float(request_form.get(key)): if 'constraints_pass' in each_option: (constraints_pass, constraints_errors, mod_input ) = each_option['constraints_pass']( mod_input, float(request_form.get(key))) if constraints_pass: value = float(request_form.get(key)) else: error.append( "{name} must represent a float/decimal value " "(submitted '{value}')".format( name=each_option['name'], value=request_form.get(key))) elif each_option['type'] == 'integer': if is_int(request_form.get(key)): if 'constraints_pass' in each_option: (constraints_pass, constraints_errors, mod_input ) = each_option['constraints_pass']( mod_input, int(request_form.get(key))) if constraints_pass: value = int(request_form.get(key)) else: error.append( "{name} must represent an integer value " "(submitted '{value}')".format( name=each_option['name'], value=request_form.get(key))) elif each_option['type'] in ['text', 'select']: if 'constraints_pass' in each_option: (constraints_pass, constraints_errors, mod_input) = each_option['constraints_pass']( mod_input, request_form.get(key)) if constraints_pass: value = request_form.get(key) elif each_option['type'] == 'bool': value = bool(request_form.get(key)) for each_error in constraints_errors: error.append("Error: {name}: {error}".format( name=each_option['name'], error=each_error)) if value is not None: null_value = False option = '{id},{value}'.format(id=key, value=value) list_options.append(option) if null_value: option = '{id},'.format(id=each_option['id']) list_options.append(option) mod_input.custom_options = ';'.join(list_options) if not error: # Add or delete channels for variable measurement Inputs if ('measurements_variable_amount' in dict_inputs[mod_input.device] and dict_inputs[ mod_input.device]['measurements_variable_amount']): channels = DeviceMeasurements.query.filter( DeviceMeasurements.device_id == form_mod.input_id.data) if channels.count() != form_mod.num_channels.data: # Delete channels if form_mod.num_channels.data < channels.count(): for index, each_channel in enumerate(channels.all()): if index + 1 >= channels.count(): delete_entry_with_id(DeviceMeasurements, each_channel.unique_id) # Add channels elif form_mod.num_channels.data > channels.count(): start_number = channels.count() for index in range(start_number, form_mod.num_channels.data): new_measurement = DeviceMeasurements() new_measurement.name = "" new_measurement.device_id = mod_input.unique_id new_measurement.measurement = "" new_measurement.unit = "" new_measurement.channel = index new_measurement.save() db.session.commit() except Exception as except_msg: error.append(except_msg) flash_success_errors(error, action, url_for('routes_page.page_data'))
def input_mod(form_mod, request_form): messages = { "success": [], "info": [], "warning": [], "error": [], "name": None, "return_text": [] } page_refresh = False dict_inputs = parse_input_information() try: mod_input = Input.query.filter( Input.unique_id == form_mod.input_id.data).first() if mod_input.is_activated: messages["error"].append( gettext("Deactivate controller before modifying its settings")) if (mod_input.device == 'AM2315' and form_mod.period.data < 7): messages["error"].append( gettext("Choose a Read Period equal to or greater than 7. The " "AM2315 may become unresponsive if the period is " "below 7.")) if (form_mod.period.data and form_mod.pre_output_duration.data and form_mod.pre_output_id.data and form_mod.period.data < form_mod.pre_output_duration.data): messages["error"].append( gettext( "The Read Period cannot be less than the Pre Output Duration" )) if (form_mod.uart_location.data and not os.path.exists(form_mod.uart_location.data)): messages["warning"].append( gettext( "Invalid device or improper permissions to read device")) if ('options_enabled' in dict_inputs[mod_input.device] and 'gpio_location' in dict_inputs[mod_input.device]['options_enabled'] and form_mod.gpio_location.data is None): messages["error"].append(gettext("Pin (GPIO) must be set")) mod_input.name = form_mod.name.data messages["name"] = form_mod.name.data if form_mod.location.data: mod_input.location = form_mod.location.data if form_mod.i2c_location.data: mod_input.i2c_location = form_mod.i2c_location.data if form_mod.ftdi_location.data: mod_input.ftdi_location = form_mod.ftdi_location.data if form_mod.uart_location.data: mod_input.uart_location = form_mod.uart_location.data if form_mod.gpio_location.data and form_mod.gpio_location.data is not None: mod_input.gpio_location = form_mod.gpio_location.data if form_mod.power_output_id.data: mod_input.power_output_id = form_mod.power_output_id.data else: mod_input.power_output_id = None if form_mod.pre_output_id.data: mod_input.pre_output_id = form_mod.pre_output_id.data else: mod_input.pre_output_id = None # Enable/disable Channels measurements = DeviceMeasurements.query.filter( DeviceMeasurements.device_id == form_mod.input_id.data).all() if form_mod.measurements_enabled.data: for each_measurement in measurements: if each_measurement.unique_id in form_mod.measurements_enabled.data: each_measurement.is_enabled = True else: each_measurement.is_enabled = False mod_input.log_level_debug = form_mod.log_level_debug.data mod_input.i2c_bus = form_mod.i2c_bus.data mod_input.baud_rate = form_mod.baud_rate.data mod_input.pre_output_duration = form_mod.pre_output_duration.data mod_input.pre_output_during_measure = form_mod.pre_output_during_measure.data if form_mod.period.data: mod_input.period = form_mod.period.data if form_mod.start_offset.data: mod_input.start_offset = form_mod.start_offset.data mod_input.resolution = form_mod.resolution.data mod_input.resolution_2 = form_mod.resolution_2.data mod_input.sensitivity = form_mod.sensitivity.data mod_input.calibrate_sensor_measure = form_mod.calibrate_sensor_measure.data mod_input.cmd_command = form_mod.cmd_command.data mod_input.thermocouple_type = form_mod.thermocouple_type.data mod_input.ref_ohm = form_mod.ref_ohm.data # Serial options mod_input.pin_clock = form_mod.pin_clock.data mod_input.pin_cs = form_mod.pin_cs.data mod_input.pin_mosi = form_mod.pin_mosi.data mod_input.pin_miso = form_mod.pin_miso.data # Bluetooth options mod_input.bt_adapter = form_mod.bt_adapter.data mod_input.adc_gain = form_mod.adc_gain.data mod_input.adc_resolution = form_mod.adc_resolution.data mod_input.adc_sample_speed = form_mod.adc_sample_speed.data # Switch options mod_input.switch_edge = form_mod.switch_edge.data mod_input.switch_bouncetime = form_mod.switch_bouncetime.data mod_input.switch_reset_period = form_mod.switch_reset_period.data # PWM and RPM options mod_input.weighting = form_mod.weighting.data mod_input.rpm_pulses_per_rev = form_mod.rpm_pulses_per_rev.data mod_input.sample_time = form_mod.sample_time.data # Server options mod_input.port = form_mod.port.data mod_input.times_check = form_mod.times_check.data mod_input.deadline = form_mod.deadline.data # SHT sensor options if form_mod.sht_voltage.data: mod_input.sht_voltage = form_mod.sht_voltage.data channels = InputChannel.query.filter( InputChannel.input_id == form_mod.input_id.data) # Save Measurement settings messages, page_refresh = utils_measurement.measurement_mod_form( messages, page_refresh, request_form) # Add or delete channels for variable measurement Inputs if ('measurements_variable_amount' in dict_inputs[mod_input.device] and dict_inputs[mod_input.device]['measurements_variable_amount']): measurements = DeviceMeasurements.query.filter( DeviceMeasurements.device_id == form_mod.input_id.data) if measurements.count() != form_mod.num_channels.data: page_refresh = True # Delete measurements/channels if form_mod.num_channels.data < measurements.count(): for index, each_channel in enumerate(measurements.all()): if index + 1 > form_mod.num_channels.data: delete_entry_with_id(DeviceMeasurements, each_channel.unique_id, flash_message=False) if ('channel_quantity_same_as_measurements' in dict_inputs[mod_input.device] and dict_inputs[mod_input.device] ["channel_quantity_same_as_measurements"]): if form_mod.num_channels.data < channels.count(): for index, each_channel in enumerate( channels.all()): if index + 1 > form_mod.num_channels.data: delete_entry_with_id( InputChannel, each_channel.unique_id, flash_message=False) # Add measurements/channels elif form_mod.num_channels.data > measurements.count(): start_number = measurements.count() for index in range(start_number, form_mod.num_channels.data): new_measurement = DeviceMeasurements() new_measurement.name = "" new_measurement.device_id = mod_input.unique_id new_measurement.measurement = "" new_measurement.unit = "" new_measurement.channel = index new_measurement.save() if ('channel_quantity_same_as_measurements' in dict_inputs[mod_input.device] and dict_inputs[mod_input.device] ["channel_quantity_same_as_measurements"]): new_channel = InputChannel() new_channel.name = "" new_channel.input_id = mod_input.unique_id new_channel.channel = index messages[ "error"], custom_options = custom_channel_options_return_json( messages["error"], dict_inputs, request_form, mod_input.unique_id, index, device=mod_input.device, use_defaults=True) new_channel.custom_options = custom_options new_channel.save() # Parse pre-save custom options for output device and its channels try: custom_options_dict_presave = json.loads(mod_input.custom_options) except: logger.error("Malformed JSON") custom_options_dict_presave = {} custom_options_channels_dict_presave = {} for each_channel in channels.all(): if each_channel.custom_options and each_channel.custom_options != "{}": custom_options_channels_dict_presave[ each_channel.channel] = json.loads( each_channel.custom_options) else: custom_options_channels_dict_presave[each_channel.channel] = {} # Parse post-save custom options for output device and its channels messages[ "error"], custom_options_json_postsave = custom_options_return_json( messages["error"], dict_inputs, request_form, mod_dev=mod_input, device=mod_input.device) custom_options_dict_postsave = json.loads(custom_options_json_postsave) custom_options_channels_dict_postsave = {} for each_channel in channels.all(): messages[ "error"], custom_options_channels_json_postsave_tmp = custom_channel_options_return_json( messages["error"], dict_inputs, request_form, form_mod.input_id.data, each_channel.channel, device=mod_input.device, use_defaults=False) custom_options_channels_dict_postsave[ each_channel.channel] = json.loads( custom_options_channels_json_postsave_tmp) if 'execute_at_modification' in dict_inputs[mod_input.device]: # pass custom options to module prior to saving to database (messages, mod_input, custom_options_dict, custom_options_channels_dict ) = dict_inputs[mod_input.device]['execute_at_modification']( messages, mod_input, request_form, custom_options_dict_presave, custom_options_channels_dict_presave, custom_options_dict_postsave, custom_options_channels_dict_postsave) custom_options = json.dumps( custom_options_dict) # Convert from dict to JSON string custom_channel_options = custom_options_channels_dict else: # Don't pass custom options to module custom_options = json.dumps(custom_options_dict_postsave) custom_channel_options = custom_options_channels_dict_postsave # Finally, save custom options for both output and channels mod_input.custom_options = custom_options for each_channel in channels: if 'name' in custom_channel_options[each_channel.channel]: each_channel.name = custom_channel_options[ each_channel.channel]['name'] each_channel.custom_options = json.dumps( custom_channel_options[each_channel.channel]) if not messages["error"]: db.session.commit() messages["success"].append( f"{TRANSLATIONS['modify']['title']} {TRANSLATIONS['input']['title']}" ) except Exception as except_msg: logger.exception("input_mod") messages["error"].append(str(except_msg)) return messages, page_refresh
def input_mod(form_mod, request_form): action = '{action} {controller}'.format( action=TRANSLATIONS['modify']['title'], controller=TRANSLATIONS['input']['title']) error = [] dict_inputs = parse_input_information() try: mod_input = Input.query.filter( Input.unique_id == form_mod.input_id.data).first() if mod_input.is_activated: error.append( gettext("Deactivate controller before modifying its settings")) if (mod_input.device == 'AM2315' and form_mod.period.data < 7): error.append( gettext("Choose a Read Period equal to or greater than 7. The " "AM2315 may become unresponsive if the period is " "below 7.")) if (mod_input.device != 'EDGE' and (mod_input.pre_output_duration and form_mod.period.data < mod_input.pre_output_duration)): error.append( gettext("The Read Period cannot be less than the Pre Output " "Duration")) if (form_mod.uart_location.data and not os.path.exists(form_mod.uart_location.data)): error.append( gettext( "Invalid device or improper permissions to read device")) if ('gpio_location' in dict_inputs[mod_input.device]['options_enabled'] and form_mod.gpio_location.data is None): error.append(gettext("Pin (GPIO) must be set")) mod_input.name = form_mod.name.data if form_mod.location.data: mod_input.location = form_mod.location.data if form_mod.i2c_location.data: mod_input.i2c_location = form_mod.i2c_location.data if form_mod.ftdi_location.data: mod_input.ftdi_location = form_mod.ftdi_location.data if form_mod.uart_location.data: mod_input.uart_location = form_mod.uart_location.data if form_mod.gpio_location.data and form_mod.gpio_location.data is not None: mod_input.gpio_location = form_mod.gpio_location.data if form_mod.power_output_id.data: mod_input.power_output_id = form_mod.power_output_id.data else: mod_input.power_output_id = None if form_mod.pre_output_id.data: mod_input.pre_output_id = form_mod.pre_output_id.data else: mod_input.pre_output_id = None # Enable/disable Channels measurements = DeviceMeasurements.query.filter( DeviceMeasurements.device_id == form_mod.input_id.data).all() if form_mod.measurements_enabled.data: for each_measurement in measurements: if each_measurement.unique_id in form_mod.measurements_enabled.data: each_measurement.is_enabled = True else: each_measurement.is_enabled = False mod_input.log_level_debug = form_mod.log_level_debug.data mod_input.i2c_bus = form_mod.i2c_bus.data mod_input.baud_rate = form_mod.baud_rate.data mod_input.pre_output_duration = form_mod.pre_output_duration.data mod_input.pre_output_during_measure = form_mod.pre_output_during_measure.data if form_mod.period.data: mod_input.period = form_mod.period.data if form_mod.start_offset.data: mod_input.start_offset = form_mod.start_offset.data mod_input.resolution = form_mod.resolution.data mod_input.resolution_2 = form_mod.resolution_2.data mod_input.sensitivity = form_mod.sensitivity.data mod_input.calibrate_sensor_measure = form_mod.calibrate_sensor_measure.data mod_input.cmd_command = form_mod.cmd_command.data mod_input.thermocouple_type = form_mod.thermocouple_type.data mod_input.ref_ohm = form_mod.ref_ohm.data # Serial options mod_input.pin_clock = form_mod.pin_clock.data mod_input.pin_cs = form_mod.pin_cs.data mod_input.pin_mosi = form_mod.pin_mosi.data mod_input.pin_miso = form_mod.pin_miso.data # Bluetooth options mod_input.bt_adapter = form_mod.bt_adapter.data mod_input.adc_gain = form_mod.adc_gain.data mod_input.adc_resolution = form_mod.adc_resolution.data mod_input.adc_sample_speed = form_mod.adc_sample_speed.data # Switch options mod_input.switch_edge = form_mod.switch_edge.data mod_input.switch_bouncetime = form_mod.switch_bouncetime.data mod_input.switch_reset_period = form_mod.switch_reset_period.data # PWM and RPM options mod_input.weighting = form_mod.weighting.data mod_input.rpm_pulses_per_rev = form_mod.rpm_pulses_per_rev.data mod_input.sample_time = form_mod.sample_time.data # Server options mod_input.port = form_mod.port.data mod_input.times_check = form_mod.times_check.data mod_input.deadline = form_mod.deadline.data # SHT sensor options if form_mod.sht_voltage.data: mod_input.sht_voltage = form_mod.sht_voltage.data # Custom options try: custom_options_json_presave = json.loads(mod_input.custom_options) except: logger.error("Malformed JSON") custom_options_json_presave = {} # Generate string to save from custom options error, custom_options_json_postsave = custom_options_return_json( error, dict_inputs, request_form, device=mod_input.device) if 'execute_at_modification' in dict_inputs[mod_input.device]: (allow_saving, mod_input, custom_options ) = dict_inputs[mod_input.device]['execute_at_modification']( mod_input, request_form, custom_options_json_presave, json.loads(custom_options_json_postsave)) custom_options = json.dumps( custom_options) # Convert from dict to JSON string if not allow_saving: error.append( "execute_at_modification() would not allow widget options to be saved" ) else: custom_options = custom_options_json_postsave mod_input.custom_options = custom_options if not error: # Add or delete channels for variable measurement Inputs if ('measurements_variable_amount' in dict_inputs[mod_input.device] and dict_inputs[ mod_input.device]['measurements_variable_amount']): channels = DeviceMeasurements.query.filter( DeviceMeasurements.device_id == form_mod.input_id.data) if channels.count() != form_mod.num_channels.data: # Delete channels if form_mod.num_channels.data < channels.count(): for index, each_channel in enumerate(channels.all()): if index + 1 >= channels.count(): delete_entry_with_id(DeviceMeasurements, each_channel.unique_id) # Add channels elif form_mod.num_channels.data > channels.count(): start_number = channels.count() for index in range(start_number, form_mod.num_channels.data): new_measurement = DeviceMeasurements() new_measurement.name = "" new_measurement.device_id = mod_input.unique_id new_measurement.measurement = "" new_measurement.unit = "" new_measurement.channel = index new_measurement.save() db.session.commit() except Exception as except_msg: error.append(except_msg) flash_success_errors(error, action, url_for('routes_page.page_data'))
from mycodo.config import OUTPUT_INFO output_unique_id = {} # Go through each output to get output unique_id with session_scope(MYCODO_DB_PATH) as output_sess: for each_output in output_sess.query(Output).all(): output_unique_id[each_output.unique_id] = [] # Create measurements in device_measurements table for measurement, measure_data in OUTPUT_INFO[ each_output.output_type]['measure'].items(): for unit, unit_data in measure_data.items(): for channel, channel_data in unit_data.items(): new_measurement = DeviceMeasurements() new_measurement.device_id = each_output.unique_id new_measurement.name = '' new_measurement.is_enabled = True new_measurement.measurement = measurement new_measurement.unit = unit new_measurement.channel = channel output_sess.add(new_measurement) output_sess.commit() output_unique_id[ each_output.unique_id].append( new_measurement.unique_id) # Update all outputs in Dashboard elements to new unique_ids for each_dash in output_sess.query(Dashboard).all(): each_dash.output_ids = each_dash.output_ids.replace( ',output', '')
def output_add(form_add): action = '{action} {controller}'.format( action=TRANSLATIONS['add']['title'], controller=TRANSLATIONS['output']['title']) error = [] dep_unmet, _ = return_dependencies(form_add.output_type.data.split(',')[0]) if dep_unmet: list_unmet_deps = [] for each_dep in dep_unmet: list_unmet_deps.append(each_dep[0]) error.append( "The {dev} device you're trying to add has unmet dependencies: " "{dep}".format(dev=form_add.output_type.data, dep=', '.join(list_unmet_deps))) if len(form_add.output_type.data.split(',')) < 2: error.append("Must select an Output type") if not is_int(form_add.output_quantity.data, check_range=[1, 20]): error.append("{error}. {accepted_values}: 1-20".format( error=gettext("Invalid quantity"), accepted_values=gettext("Acceptable values"))) if not error: for _ in range(0, form_add.output_quantity.data): try: output_type = form_add.output_type.data.split(',')[0] interface = form_add.output_type.data.split(',')[1] new_output = Output() new_output.name = str(OUTPUT_INFO[output_type]['name']) new_output.output_type = output_type new_output.interface = interface if output_type in [ 'wired', 'wireless_rpi_rf', 'command', 'python' ]: new_output.measurement = 'duration_time' new_output.unit = 's' elif output_type in OUTPUTS_PWM: new_output.measurement = 'duty_cycle' new_output.unit = 'percent' new_output.channel = 0 if output_type == 'wired': new_output.state_startup = '0' new_output.state_shutdown = '0' elif output_type == 'wireless_rpi_rf': new_output.pin = None new_output.protocol = 1 new_output.pulse_length = 189 new_output.on_command = '22559' new_output.off_command = '22558' elif output_type == 'command': new_output.on_command = '/home/pi/script_on.sh' new_output.off_command = '/home/pi/script_off.sh' elif output_type == 'command_pwm': new_output.pwm_command = '/home/pi/script_pwm.sh ((duty_cycle))' elif output_type == 'pwm': new_output.pwm_hertz = 22000 new_output.pwm_library = 'pigpio_any' elif output_type == 'python': new_output.on_command = """ timestamp = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") write_string = "{ts}: ID: {id}: ON\\n".format(id=output_id, ts=timestamp) with open("/home/pi/Mycodo/OutputTest.txt", "a") as myfile: myfile.write(write_string)""" new_output.off_command = """ timestamp = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") write_string = "{ts}: ID: {id}: OFF\\n".format(id=output_id, ts=timestamp) with open("/home/pi/Mycodo/OutputTest.txt", "a") as myfile: myfile.write(write_string)""" elif output_type == 'python_pwm': new_output.pwm_command = """ timestamp = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") write_string = "{ts}: ID: {id}: Duty Cycle: ((duty_cycle)) %\\n".format( id=output_id, ts=timestamp) with open("/home/pi/Mycodo/OutputTest.txt", "a") as myfile: myfile.write(write_string)""" elif output_type == 'atlas_ezo_pmp': new_output.output_mode = 'fastest_flow_rate' new_output.flow_rate = 10 if interface == 'FTDI': new_output.location = '/dev/ttyUSB0' elif interface == 'I2C': new_output.location = '0x67' new_output.i2c_bus = 1 elif interface == 'UART': new_output.location = '/dev/ttyAMA0' new_output.baud_rate = 9600 if not error: new_output.save() display_order = csv_to_list_of_str( DisplayOrder.query.first().output) DisplayOrder.query.first().output = add_display_order( display_order, new_output.unique_id) db.session.commit() # Add device measurements for measurement, measure_data in OUTPUT_INFO[ new_output.output_type]['measure'].items(): for unit, unit_data in measure_data.items(): for channel, _ in unit_data.items(): new_measurement = DeviceMeasurements() new_measurement.device_id = new_output.unique_id new_measurement.name = '' new_measurement.is_enabled = True new_measurement.measurement = measurement new_measurement.unit = unit new_measurement.channel = channel new_measurement.save() manipulate_output('Add', new_output.unique_id) except sqlalchemy.exc.OperationalError as except_msg: error.append(except_msg) except sqlalchemy.exc.IntegrityError as except_msg: error.append(except_msg) flash_success_errors(error, action, url_for('routes_page.page_output')) if dep_unmet: return 1
def 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_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' # Generate string to save from custom options error, custom_options = custom_options_return_json( 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']): error, new_func = dict_controllers[new_func.device]['execute_at_creation']( error, new_func, dict_controllers[new_func.device]) 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() 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 error, custom_options = custom_channel_options_return_json( 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() flash(gettext( "%(type)s Function with ID %(id)s (%(uuid)s) successfully added", type=new_func.name, id=new_func.id, uuid=new_func.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) except Exception as except_msg: logger.exception("Add Function") error.append(except_msg) flash_success_errors(error, action, url_for('routes_page.page_function')) if dep_unmet: return 1