def all_outputs_initialize(self, outputs): """ Initialize all output variables and classes """ self.dict_outputs = parse_output_information() self.outputs_pwm = outputs_pwm() for each_output in outputs: try: self.output_unique_id[ each_output.unique_id] = each_output.unique_id self.output_type[ each_output.unique_id] = each_output.output_type self.output_name[each_output.unique_id] = each_output.name self.output_amps[each_output.unique_id] = each_output.amps self.output_state_startup[ each_output.unique_id] = each_output.state_startup self.output_startup_value[ each_output.unique_id] = each_output.startup_value self.output_state_shutdown[ each_output.unique_id] = each_output.state_shutdown self.output_shutdown_value[ each_output.unique_id] = each_output.shutdown_value self.output_on_until[ each_output.unique_id] = datetime.datetime.now() self.output_last_duration[each_output.unique_id] = 0 self.output_on_duration[each_output.unique_id] = False self.output_off_triggered[each_output.unique_id] = False self.output_time_turned_on[each_output.unique_id] = None self.output_force_command[ each_output.unique_id] = each_output.force_command self.trigger_functions_at_start[ each_output. unique_id] = each_output.trigger_functions_at_start if each_output.output_type in self.dict_outputs: output_loaded = load_module_from_file( self.dict_outputs[each_output.output_type] ['file_path'], 'outputs') self.output[ each_output.unique_id] = output_loaded.OutputModule( each_output) self.output[each_output.unique_id].setup_output() self.output[each_output.unique_id].init_post() except: self.logger.error("Could not initialize output {}".format( each_output.unique_id)) self.logger.debug("{id} ({name}) Initialized".format( id=each_output.unique_id.split('-')[0], name=each_output.name))
def output_mod(output_id, state, out_type, amount): """ Manipulate output (using non-unique ID) """ if not utils_general.user_has_permission('edit_controllers'): return 'Insufficient user permissions to manipulate outputs' daemon = DaemonControl() if (state in ['on', 'off'] and out_type == 'sec' and (str_is_float(amount) and float(amount) >= 0)): out_status = daemon.output_on_off( output_id, state, amount=float(amount)) if out_status[0]: return 'ERROR: {}'.format(out_status[1]) else: return 'SUCCESS: {}'.format(out_status[1]) elif (state == 'on' and out_type in outputs_pwm() and (str_is_float(amount) and float(amount) >= 0)): out_status = daemon.output_on( output_id, duty_cycle=float(amount)) if out_status[0]: return 'ERROR: {}'.format(out_status[1]) else: return 'SUCCESS: {}'.format(out_status[1])
def output_add(form_add): action = '{action} {controller}'.format( action=TRANSLATIONS['add']['title'], controller=TRANSLATIONS['output']['title']) error = [] dict_outputs = parse_output_information() # only one comma should be in the output_type string if form_add.output_type.data.count(',') > 1: error.append("Invalid output module formatting. It appears there is " "a comma in either 'output_name_unique' or 'interfaces'.") if form_add.output_type.data.count(',') == 1: output_type = form_add.output_type.data.split(',')[0] output_interface = form_add.output_type.data.split(',')[1] else: output_type = '' output_interface = '' error.append( "Invalid output string (must be a comma-separated string)") if current_app.config['TESTING']: dep_unmet = False else: dep_unmet, _ = return_dependencies( form_add.output_type.data.split(',')[0]) if dep_unmet: list_unmet_deps = [] for each_dep in dep_unmet: list_unmet_deps.append(each_dep[0]) error.append( "The {dev} device you're trying to add has unmet dependencies: " "{dep}".format(dev=form_add.output_type.data, dep=', '.join(list_unmet_deps))) if not is_int(form_add.output_quantity.data, check_range=[1, 20]): error.append("{error}. {accepted_values}: 1-20".format( error=gettext("Invalid quantity"), accepted_values=gettext("Acceptable values"))) if not error: for _ in range(0, form_add.output_quantity.data): try: new_output = Output() new_output.name = "Name" new_output.output_type = output_type new_output.interface = output_interface # # Set default values for new input being added # # input add options if output_type in dict_outputs: def dict_has_value(key): if (key in dict_outputs[output_type] and (dict_outputs[output_type][key] or dict_outputs[output_type][key] == 0)): return True # # Interfacing options # if output_interface == 'I2C': if dict_has_value('i2c_location'): new_output.i2c_location = dict_outputs[ output_type]['i2c_location'][ 0] # First list entry if output_interface == 'FTDI': if dict_has_value('ftdi_location'): new_output.ftdi_location = dict_outputs[ output_type]['ftdi_location'] if output_interface == 'UART': if dict_has_value('uart_location'): new_output.uart_location = dict_outputs[ output_type]['uart_location'] # UART options if dict_has_value('uart_baud_rate'): new_output.baud_rate = dict_outputs[output_type][ 'uart_baud_rate'] if dict_has_value('pin_cs'): new_output.pin_cs = dict_outputs[output_type]['pin_cs'] if dict_has_value('pin_miso'): new_output.pin_miso = dict_outputs[output_type][ 'pin_miso'] if dict_has_value('pin_mosi'): new_output.pin_mosi = dict_outputs[output_type][ 'pin_mosi'] if dict_has_value('pin_clock'): new_output.pin_clock = dict_outputs[output_type][ 'pin_clock'] # Bluetooth (BT) options elif output_interface == 'BT': if dict_has_value('bt_location'): new_output.location = dict_outputs[output_type][ 'bt_location'] if dict_has_value('bt_adapter'): new_output.bt_adapter = dict_outputs[output_type][ 'bt_adapter'] # GPIO options elif output_interface == 'GPIO': if dict_has_value('gpio_pin'): new_output.pin = dict_outputs[output_type][ 'gpio_pin'] # Custom location location elif dict_has_value('location'): new_output.location = dict_outputs[output_type][ 'location']['options'][0][0] # First entry in list # # Custom Options # list_options = [] if 'custom_options' in dict_outputs[output_type]: for each_option in dict_outputs[output_type][ 'custom_options']: if each_option['default_value'] is False: default_value = '' else: default_value = each_option['default_value'] option = '{id},{value}'.format(id=each_option['id'], value=default_value) list_options.append(option) new_output.custom_options = ';'.join(list_options) if 'on_off' in dict_outputs[output_type]['output_types']: new_output.measurement = 'duration_time' new_output.unit = 's' elif output_type in outputs_pwm(): new_output.measurement = 'duty_cycle' new_output.unit = 'percent' new_output.pwm_hertz = 22000 new_output.pwm_library = 'pigpio_any' new_output.channel = 0 if output_type == 'wired': new_output.state_startup = '0' new_output.state_shutdown = '0' elif output_type == 'wireless_rpi_rf': new_output.pin = None new_output.protocol = 1 new_output.pulse_length = 189 new_output.on_command = '22559' new_output.off_command = '22558' new_output.force_command = True elif output_type == 'command': new_output.linux_command_user = '******' new_output.on_command = '/home/pi/script_on.sh' new_output.off_command = '/home/pi/script_off.sh' new_output.force_command = True elif output_type == 'command_pwm': new_output.linux_command_user = '******' new_output.pwm_command = '/home/pi/script_pwm.sh ((duty_cycle))' elif output_type == 'python': new_output.on_command = """ import datetime timestamp = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") log_string = "{ts}: ID: {id}: ON".format(id=output_id, ts=timestamp) self.logger.info(log_string)""" new_output.off_command = """ import datetime timestamp = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") log_string = "{ts}: ID: {id}: OFF".format(id=output_id, ts=timestamp) self.logger.info(log_string)""" new_output.force_command = True elif output_type == 'python_pwm': new_output.pwm_command = """ import datetime timestamp = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") log_string = "{ts}: ID: {id}: {dc} % Duty Cycle".format( dc=duty_cycle, id=output_id, ts=timestamp) self.logger.info(log_string)""" elif output_type == 'atlas_ezo_pmp': new_output.output_mode = 'fastest_flow_rate' new_output.flow_rate = 10 if output_interface == 'FTDI': new_output.location = '/dev/ttyUSB0' elif output_interface == 'I2C': new_output.location = '0x67' new_output.i2c_bus = 1 elif output_interface == 'UART': new_output.location = '/dev/ttyAMA0' new_output.baud_rate = 9600 if not error: new_output.save() display_order = csv_to_list_of_str( DisplayOrder.query.first().output) DisplayOrder.query.first().output = add_display_order( display_order, new_output.unique_id) # # If measurements defined in the Output Module # if ('measurements_dict' in dict_outputs[output_type] and dict_outputs[output_type]['measurements_dict'] != []): for each_channel in dict_outputs[output_type][ 'measurements_dict']: measure_info = dict_outputs[output_type][ 'measurements_dict'][each_channel] new_measurement = DeviceMeasurements() if 'name' in measure_info: new_measurement.name = measure_info['name'] new_measurement.device_id = new_output.unique_id new_measurement.measurement = measure_info[ 'measurement'] new_measurement.unit = measure_info['unit'] new_measurement.channel = each_channel new_measurement.save() db.session.commit() if not current_app.config['TESTING']: manipulate_output('Add', new_output.unique_id) except sqlalchemy.exc.OperationalError as except_msg: error.append(except_msg) except sqlalchemy.exc.IntegrityError as except_msg: error.append(except_msg) flash_success_errors(error, action, url_for('routes_page.page_output')) if dep_unmet: return 1
def method_builder(method_id): """ Page to edit the details of each method This includes the (time, setpoint) data sets """ if not utils_general.user_has_permission('edit_controllers'): return redirect(url_for('routes_method.method_list')) output = Output.query.all() form_create_method = forms_method.MethodCreate() form_add_method = forms_method.MethodAdd() form_mod_method = forms_method.MethodMod() form_fail = None # Used in software tests to verify function is executing as admin if method_id == '-1': return 'admin logged in' # Create new method elif method_id == '0': form_fail = utils_method.method_create(form_create_method) new_method = Method.query.order_by(Method.id.desc()).first() if not form_fail: return redirect('/method-build/{method_id}'.format( method_id=new_method.unique_id)) else: return redirect('/method') elif not method_id: flash("Invalid method ID", "error") return redirect('/method') # First method column with general information about method method = Method.query.filter(Method.unique_id == method_id).first() if method.method_type in [ 'Date', 'Duration', 'Daily', 'DailySine', 'DailyBezier' ]: # Retrieve the order to display method data lines display_order = csv_to_list_of_str(method.method_order) method_data = MethodData.query.filter( MethodData.method_id == method.unique_id) setpoint_method_data = MethodData.query.filter( MethodData.setpoint_start != None) sine_method_data = MethodData.query.filter( MethodData.amplitude != None) bezier_method_data = MethodData.query.filter(MethodData.x0 != None) if display_order: last_setpoint_method = setpoint_method_data.filter( MethodData.unique_id == display_order[-1]).first() last_sine_method = sine_method_data.filter( MethodData.unique_id == display_order[-1]).first() last_bezier_method = bezier_method_data.filter( MethodData.unique_id == display_order[-1]).first() else: last_setpoint_method = None last_sine_method = None last_bezier_method = None last_end_time = '' last_setpoint = '' if method.method_type in ['Daily', 'Date', 'Duration']: method_data = method_data.all() # Get last entry end time and setpoint to populate the form if last_setpoint_method is None: last_end_time = '' last_setpoint = '' else: last_end_time = last_setpoint_method.time_end if last_setpoint_method.setpoint_end is not None: last_setpoint = last_setpoint_method.setpoint_end else: last_setpoint = last_setpoint_method.setpoint_start if request.method == 'POST': form_name = request.form['form-name'] if form_name == 'addMethod': form_fail = utils_method.method_add(form_add_method) elif form_name in ['modMethod', 'renameMethod']: form_fail = utils_method.method_mod(form_mod_method) if (form_name in ['addMethod', 'modMethod', 'renameMethod'] and not form_fail): return redirect('/method-build/{method_id}'.format( method_id=method.unique_id)) if not method_data: method_data = [] return render_template('pages/method-build.html', method=method, output=output, method_data=method_data, method_id=method_id, last_end_time=last_end_time, last_bezier_method=last_bezier_method, last_sine_method=last_sine_method, last_setpoint_method=last_setpoint_method, last_setpoint=last_setpoint, outputs_pwm=outputs_pwm(), form_create_method=form_create_method, form_add_method=form_add_method, form_mod_method=form_mod_method) return redirect('/method')