def __init__(self): __config = Config() self.__host = __config.get('MySQL','Host') self.__user = __config.get('MySQL','User') self.__password = __config.get('MySQL','Pass') self.__database = __config.get('MySQL','Base') try: self.__conn = MySQLdb.connect(self.__host, self.__user, self.__password, self.__database) except MySQLdb.Error as e: print "Error %d: %s" % (e.args[0],e.args[1]) sys.exit(1)
def __init__(self): __config = Config() self.__host = __config.get('MySQL', 'Host') self.__user = __config.get('MySQL', 'User') self.__password = __config.get('MySQL', 'Pass') self.__database = __config.get('MySQL', 'Base') try: self.__conn = MySQLdb.connect(self.__host, self.__user, self.__password, self.__database) except MySQLdb.Error as e: print "Error %d: %s" % (e.args[0], e.args[1]) sys.exit(1)
def sql_filter(sql, db_type): """ 过滤SQL 是否符合 :param sql: SQL语句 :param db_type: 数据库类型 :return: 返回一个字典 """ ret = { "status": True, "message": "", } conf = Config() filter_classes = conf.get("%s_filter" % db_type, "filter_class") # 获取配置文件中配置的所有的filter_class if filter_classes: filter_classes = filter_classes.split(",") imp_module = importlib.import_module( 'db_query.backends.%s.sql_filter' % db_type) for filter_class in filter_classes: # 循环所有的过滤器,如果发现有一个过滤失败,那么就返回 try: db_filter_class = getattr(imp_module, filter_class) db_filter = db_filter_class() if not db_filter.sql_passes(sql): ret["message"] = db_filter.filter_description() ret["status"] = False break except Exception as e: ret["message"] = str(e) ret["status"] = False break return ret
def setup(logger: Logger, config: Config): """ Configure a passed logger using standardized parameters from configuration. :param logger: logger to manipulate :param config: configuration object :raises OSError: if folder or file creation fails :return: """ # Set formatting from logging import Formatter formatter = Formatter('%(asctime)s : %(levelname)s : %(name)s : %(message)s') # Get log types and initialize the associated log handlers log_types = config.get('webapi', 'log_types').upper().replace(',', ' ').replace(' ', ' ').split(' ') if 'STREAM' in log_types: from logging import StreamHandler stream_handler = StreamHandler() stream_handler.setFormatter(formatter) logger.addHandler(stream_handler) if 'FILE' in log_types: from logging.handlers import RotatingFileHandler from os.path import dirname log_fp = config.get('webapi', 'log_fp') create_folder(dirname(log_fp)) file_handler = RotatingFileHandler(filename=log_fp, encoding='utf-8', mode='w', maxBytes=10240, backupCount=10) file_handler.setFormatter(formatter) logger.addHandler(file_handler) # Set log level log_level = config.get('webapi', 'log_level').upper() log_mapping = {'CRITICAL': 50, 'ERROR': 40, 'WARNING': 30, 'INFO': 20, 'DEBUG': 10, 'NOTSET': 0, 'INVALID': 10} if log_level not in log_mapping: log_level = 'INVALID' logger.setLevel(log_mapping[log_level]) if log_level == 'INVALID': logger.warning('Invalid log level set. Select from ' + ', '.join(list(log_mapping.keys())[:-1]))
def get_projects(): # print("获取projects") # todo 修改为 缓存方式的 try: conf = Config() url = conf.get('project_info', 'url') url = quote(url, safe='?|/|=|&|:') res = requests.get(url, timeout=5) ret = res.json()['data'] ret_tuple = tuple( map(lambda x: (x['project']['en_name'], x['project']['ch_name']), ret)) except Exception as e: print('连接失败') ret_tuple = [] return ret_tuple
config = Config() # Install python packages from libs.basics.network import is_up if is_up("8.8.8.8") or is_up("1.1.1.1"): from sys import executable from subprocess import check_call from os import listdir from os.path import isfile, join check_call( [executable, '-m', 'pip', 'install', '--upgrade', 'pip', 'wheel']) check_call([ executable, '-m', 'pip', 'install', '--upgrade', '-r', 'requirements.txt' ]) blueprint_path = config.get('webapi', 'plugin_path') for blueprint in listdir(blueprint_path): requirements_path = join(blueprint_path, blueprint, 'requirements.txt') if isfile(requirements_path): check_call([ executable, '-m', 'pip', 'install', '--upgrade', '-r', requirements_path ]) macro_path = config.get('webapi', 'macro_path') for macro in listdir(macro_path): requirements_path = join(macro_path, macro, 'requirements.txt') if isfile(requirements_path): check_call([ executable, '-m', 'pip', 'install', '--upgrade', '-r', requirements_path
self.log(logging.ERROR, "Error while looping MQTT (%s)" % e) if __name__ == "__main__": def resolve_path(path): return path if path[0] == '/' else os.path.join(os.path.dirname(os.path.realpath(__file__)), path) config_file = resolve_path('config/MQTT2SQLite.yaml'); config = Config(config_file) handler = logging.StreamHandler() formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s') handler.setFormatter(formatter) logger = logging.getLogger() logger.setLevel(config.get('general', 'logging_level', logging.INFO)) logger.addHandler(handler) mqtt = MosquittoWrapper.ConfigureNewWrapper(config) sqlite = SQLiteWrapper.ConfigureNewWrapper(config, resolve_path('database.db')) MQTT2SQLite = MQTT2SQLite(resolve_path(config.get('general', 'pidfile', '/tmp/MQTT2SQLite.pid'))) MQTT2SQLite.stdout = MQTT2SQLite.stderr = resolve_path(config.get('general', 'stdout', '/dev/null')) MQTT2SQLite.duplicate_check_window = config.get('general', 'duplicate_check_window', 5) MQTT2SQLite.default_topic_pattern = config.get('general', 'default_topic_pattern', '/raw/sqlite/{id}') MQTT2SQLite.publish_undefined_topics = config.get('general', 'publish_undefined_topics', True) MQTT2SQLite.load(config.get('general', 'routes', {})) MQTT2SQLite.logger = logger MQTT2SQLite.mqtt = mqtt MQTT2SQLite.sqlite = sqlite MQTT2SQLite.config_file = config_file
self.log(logging.ERROR, "Error while looping MQTT (%s)" % e) if __name__ == "__main__": def resolve_path(path): return path if path[0] == '/' else os.path.join(os.path.dirname(os.path.realpath(__file__)), path) config_file = resolve_path('config/xbee2mqtt.yaml'); config = Config(config_file) handler = logging.StreamHandler() formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s') handler.setFormatter(formatter) logger = logging.getLogger() logger.setLevel(config.get('general', 'logging_level', logging.DEBUG)) logger.addHandler(handler) mqtt = MosquittoWrapper(config.get('mqtt', 'client_id', None)) mqtt.host = config.get('mqtt', 'host', 'localhost') mqtt.port = config.get('mqtt', 'port', 1883) mqtt.username = config.get('mqtt', 'username', None) mqtt.password = config.get('mqtt', 'password', None) mqtt.keepalive = config.get('mqtt', 'keepalive', 60) mqtt.clean_session = config.get('mqtt', 'clean_session', False) mqtt.qos = config.get('mqtt', 'qos', 0) mqtt.retain = config.get('mqtt', 'retain', True) mqtt.set_will = config.get('mqtt', 'set_will', True) serial = Serial( config.get('radio', 'port', '/dev/ttyUSB0'),
self.log(logging.ERROR, "Error while looping MQTT (%s)" % e) if __name__ == "__main__": def resolve_path(path): return path if path[0] == '/' else os.path.join(os.path.dirname(os.path.realpath(__file__)), path) config_file = resolve_path('config/GPIO2MQTT.yaml'); config = Config(config_file) handler = logging.StreamHandler() formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s') handler.setFormatter(formatter) logger = logging.getLogger() logger.setLevel(config.get('general', 'logging_level', logging.INFO)) logger.addHandler(handler) mqtt = MosquittoWrapper.ConfigureNewWrapper(config) gpio = GPIOWrapper.ConfigureNewWrapper(config) processor = Processor(config.get('processor', 'filters', [])) GPIO2MQTT = GPIO2MQTT(resolve_path(config.get('general', 'pidfile', '/tmp/GPIO2MQTT.pid'))) GPIO2MQTT.stdout = GPIO2MQTT.stderr = resolve_path(config.get('general', 'stdout', '/dev/null')) GPIO2MQTT.duplicate_check_window = config.get('general', 'duplicate_check_window', 5) GPIO2MQTT.default_topic_pattern = config.get('general', 'default_topic_pattern', '/raw/gpio/{id}') GPIO2MQTT.publish_undefined_topics = config.get('general', 'publish_undefined_topics', True) GPIO2MQTT.load(config.get('general', 'routes', {})) GPIO2MQTT.logger = logger GPIO2MQTT.mqtt = mqtt GPIO2MQTT.gpio = gpio
def load_macros(config: Config, logger: Logger): """ Loads all macros. Any folder located in config.get('webapi', 'macro_path') is tried to import as module except of __pycache__. If a module is loaded as macro and the name of it's folder starts with 'streamhelper-' (case insensitive), this part will be removed in the macro name. All macros need to have the attribute use_module. If it is true, the module itself will be loaded as the macro. Otherwise, it needs to have the attribute provides_macros, which is a list. If an element in the list is a string, it is assumed to be the name of a class inside the module, and module.class is tried to initialize. If it is a class, it will be initialized directly both times without arguments. Otherwise, the object will be assumed to be the macro and will be set. Within the process, multiple attributes will be set: name (always for modules, only if missing otherwise), config, logger. After execution, post_load() will be executed if it is a function. :param config: the global config object :param logger: the global logging object """ global c c = config from os import listdir from os.path import isdir, join, isfile, dirname, basename from importlib import import_module from sys import path macro_path = config.get('webapi', 'macro_path') path.append(dirname(macro_path.rstrip('/'))) modules = import_module(basename(macro_path.rstrip('/'))) logger.info(f'Searching macros in {macro_path}') for d in listdir(macro_path): if d == '__pycache__' or d == '__init__.py': continue fp = join(macro_path, d) if not isfile(fp) and not isdir(fp): continue if isfile(fp) and not fp.endswith('.py'): continue name = d.lower() if name.startswith('streamhelper-'): name = name[13:] logger.debug(f'Loading macros from {name}') try: macro = import_module(f'.{d.rstrip(".py")}', package=modules.__package__) _check_attributes(macro, [('use_module', bool)], name) if macro.use_module: macro.name = name macro.config = config macro.logger = logger macros[name] = macro if hasattr(macro, 'post_actions'): macro.post_actions() else: from inspect import isclass _check_attributes(macro, [('provides_macros', list)], name) for cl in macro.provides_macros: if type(cl) == str: logger.debug( ' -> Loading macro by initializing a object from given class name' ) if not isclass(getattr(macro, cl)): raise AttributeError( f' -> Passed class name {cl} for macro {name} but class was not ' f'found.') macro_object = getattr(macro, cl)() elif isclass(cl): logger.debug( ' -> Loading macro by initializing a object from given class' ) macro_object = cl() else: logger.debug( ' -> Loading macro by setting object directly') macro_object = cl macro_object.logger = logger macro_object.config = config if not hasattr(macro_object, 'name'): macro_object.name = cl.__name__ if type( cl) != str else cl.lower() logger.debug( f' -> Name assumed to be \'{macro_object.name}\'') macros[macro_object.name] = macro_object if hasattr(macro_object, 'post_load'): logger.debug(' -> Post actions') macro_object.post_load() logger.debug(' -> Finished') except Exception as e: logger.warning(f' -> Loading macro {name} has failed: {e}')
if __name__ == "__main__": def resolve_path(path): return path if path[0] == '/' else os.path.join( os.path.dirname(os.path.realpath(__file__)), path) config_file = resolve_path('config/xbee2mqtt.yaml') config = Config(config_file) handler = logging.StreamHandler() formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s') handler.setFormatter(formatter) logger = logging.getLogger() logger.setLevel(config.get('daemon', 'logging_level', logging.INFO)) logger.addHandler(handler) mqtt = MosquittoWrapper(config.get('mqtt', 'client_id', None)) mqtt.host = config.get('mqtt', 'host', 'localhost') mqtt.port = config.get('mqtt', 'port', 1883) mqtt.keepalive = config.get('mqtt', 'keepalive', 60) mqtt.clean_session = config.get('mqtt', 'clean_session', False) mqtt.qos = config.get('mqtt', 'qos', 0) mqtt.retain = config.get('mqtt', 'retain', True) mqtt.set_will = config.get('mqtt', 'set_will', True) serial = Serial(config.get('radio', 'port', '/dev/ttyUSB0'), config.get('radio', 'baudrate', 9600)) xbee = XBeeWrapper() xbee.serial = serial
if __name__ == "__main__": def resolve_path(path): return path if path[0] == '/' else os.path.join(os.path.dirname(os.path.realpath(__file__)), path) config_file = resolve_path('config/smsnode2mqtt.yaml'); config = Config(config_file) handler = logging.StreamHandler() formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s') handler.setFormatter(formatter) logger = logging.getLogger() logger.setLevel(config.get('general', 'logging_level', logging.INFO)) logger.addHandler(handler) mqtt = MosquittoWrapper(config.get('mqtt', 'client_id', None)) mqtt.host = config.get('mqtt', 'host', 'localhost') mqtt.port = config.get('mqtt', 'port', 1883) mqtt.keepalive = config.get('mqtt', 'keepalive', 60) mqtt.clean_session = config.get('mqtt', 'clean_session', False) mqtt.qos = config.get('mqtt', 'qos', 0) mqtt.retain = config.get('mqtt', 'retain', True) mqtt.set_will = config.get('mqtt', 'set_will', True) smsnode2mqtt = SmsNode2MQTT(resolve_path(config.get('general', 'pidfile', '/tmp/smsnode2mqtt.pid'))) smsnode2mqtt.stdout = smsnode2mqtt.stderr = resolve_path(config.get('general', 'stdout', '/dev/null')) smsnode2mqtt.debug = config.get('general', 'debug', False) smsnode2mqtt.duplicate_check_window = config.get('general', 'duplicate_check_window', 5)
logging.exception("Error while looping MQTT (%s)" % e) if __name__ == "__main__": def resolve_path(path): return path if path[0] == '/' else os.path.join(os.path.dirname(os.path.realpath(__file__)), path) config_file = resolve_path('config/xbee2mqtt.yaml'); config = Config(config_file) handler = logging.StreamHandler() formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s') handler.setFormatter(formatter) logger = logging.getLogger() logger.setLevel(config.get('daemon', 'logging_level', logging.INFO)) logger.addHandler(handler) mqtt = MosquittoWrapper(config.get('mqtt', 'client_id', None)) mqtt.host = config.get('mqtt', 'host', 'localhost') mqtt.port = config.get('mqtt', 'port', 1883) mqtt.username = config.get('mqtt', 'username', None) mqtt.password = config.get('mqtt', 'password', None) mqtt.keepalive = config.get('mqtt', 'keepalive', 60) mqtt.clean_session = config.get('mqtt', 'clean_session', False) mqtt.qos = config.get('mqtt', 'qos', 0) mqtt.retain = config.get('mqtt', 'retain', True) mqtt.set_will = config.get('mqtt', 'set_will', True) try: serial = Serial(
class Core(object): VERSION = 0.06 def __init__(self): # Configure logger logFormatter = logging.Formatter(fmt="[%(asctime)-15s][%(levelname)s] %(message)s", datefmt='%d.%m.%Y %H:%M:%S') log = logging.getLogger() log.setLevel(logging.DEBUG) fileName = "logs/"+"sensorshub_{}_".format(datetime.datetime.now().strftime("%d-%m-%Y"))+"{}.log" fileNum = 0 if not os.path.isdir("logs"): os.mkdir("logs") while os.path.isfile(fileName.format(fileNum)): fileNum += 1 fileHandler = logging.FileHandler(fileName.format(fileNum)) fileHandler.setFormatter(logFormatter) log.addHandler(fileHandler) consoleHandler = logging.StreamHandler(sys.stdout) consoleHandler.setFormatter(logFormatter) log.addHandler(consoleHandler) logging.info("Starting SensorsHub version {}".format(self.VERSION)) # Create databse and tables with sqlite3.connect("db.sqlite") as conn: # # SENSORS # Table for sensors, each sensor has one row. conn.execute( "CREATE TABLE IF NOT EXISTS sensors(" "sid INTEGER PRIMARY KEY AUTOINCREMENT, " # Sensor ID, must be unique "token TEXT, " # Generated string for authentication "title TEXT, " # Title of the sensor, f.eg. Outside "description TEXT, " # Description of the sensor, f.eg. ESP8266 temperature sensor "updated INTEGER, " # Timestamp updated when new reading is received "status INTEGER DEFAULT 0" # Current status (enabled, disabled) ")") # FIELDS conn.execute( "CREATE TABLE IF NOT EXISTS fields(" "fid INTEGER PRIMARY KEY AUTOINCREMENT, " # Field ID, must be unique "sid INTEGER, " # Sensor ID to which this field belong "parent INTEGER" # Parent fid, default None "type INTEGER" # Field type "updated INTEGER, " # Updated time in timestamp format "value FLOAT, " # Current field value "name TEXT, " # Name of the field, f.eg. temperature "display_name TEXT, " # Human friendly name of the field, f.eg. Temperature "color TEXT, " # Color (HEX) of the field without hashtag, f.eg. FF00AA "icon TEXT" # Font awesome icon f.eg. fa-sun-o "unit TEXT)") # Unit of the field, f.eg. °C # # READINGS # Table for readings, each reding must specify field and sensor # # sid - Sensor ID to which this reading belong # fid - Field ID to which this reading belong # updated - When reading has been created in timestamp format # value - New value of the field conn.execute( """CREATE TABLE IF NOT EXISTS readings(sid INTEGER, fid INTEGER, updated INT, value FLOAT)""") # # ACCOUNTS # Table for accounts # # uid - User ID, must be unique # session - Generated string for sessions # user - Unique user login # password - Hashed password using hashlib # lastlogin - Timestamp updated when user logged in # email - User email conn.execute( """CREATE TABLE IF NOT EXISTS accounts(uid INTEGER PRIMARY KEY, session TEXT, user TEXT UNIQUE , password TEXT, lastlogin INTEGER, email TEXT)""") # Load config self.config = Config() self.config.load() # Load lang self.lang = Lang(self) self.lang.load() # Load updater self.updater = Updater(self) if self.updater.check_updates(): if "update" in self.config.args: logging.info("Starting auto update") self.updater.update() else: logging.info("No updates available") # Create and read sensors from database self.sensors = Sensors() self.sensors.load() # Create and load accounts self.accounts = Accounts(self) # Load statistics self.statistics = Statistics(self) # Configure web template engine env = Environment(loader=FileSystemLoader('templates')) env.filters["to_json"] = lambda value: json.dumps(value) def format_datetime(value, format="%d.%m.%Y %H:%M"): if value == None: return "Never" else: try: return datetime.datetime.fromtimestamp(value).strftime(format) except TypeError: return value.strftime(format) env.filters["strftime"] = format_datetime # Configure web server cherrypy_config = { "server.socket_port": self.config.get("port"), "server.socket_host": self.config.get("host"), "checker.check_skipped_app_config": False, "log.screen": False, "log.access_file": '', "log.error_file": '' } cherrypy.config.update(cherrypy_config) cherrypy.tree.mount(WebRoot(self,env),"/", { "/static": { "tools.staticdir.root": os.getcwd(), "tools.staticdir.on": True, "tools.staticdir.dir": "static" } }) cherrypy.tree.mount(WebSettings(self, env), "/settings", { }) # Disable cherrypy loggers logging.info("Starting up web server at {}:{}".format(cherrypy_config["server.socket_host"], cherrypy_config["server.socket_port"])) logging.getLogger("cherrypy").propagate = False #logging.getLogger("cherrypy.error").propagate = False logging.getLogger("cherrypy.access").propagate = False cherrypy.engine.signals.subscribe() cherrypy.engine.start() logging.info("Done loading") Statistics.snooper(1) cherrypy.engine.block() def get_client_ip(self): headers = cherrypy.request.headers if "X-Forwarded-For" in headers and headers["X-Forwarded-For"] != "127.0.0.1": return headers["X-Forwarded-For"] if "X-Forwarded" in headers and headers["X-Forwarded"] != "127.0.0.1": return headers["X-Forwarded"] if "Remote-Addr" in headers and headers["Remote-Addr"] != "127.0.0.1": return headers["Remote-Addr"] return "0.0.0.0"
""" Main application. """ from typing import Callable from flask import Flask, Request, redirect, url_for, send_from_directory from flask.templating import Environment from flask_bootstrap import Bootstrap from libs.config import Config from libs.log import setup_webapi as setup, Logger from libs.basics.text import camel_case # Config loading config = Config() template_folder = config.get('flask', 'template_path') static_folder = config.get('flask', 'static_path') # Pre-init flask extensions bootstrap = Bootstrap() logger: Logger = None jinja_env: Environment = None first_run = True def create_app(): """ Factory method for creating the flask application and all other substantial parts of the application. This includes the flask extensions, the framework-specific plugins and macros and the core logger. :return: the flask application object
self.xbee.disconnect() self.log(logging.INFO, "Exiting") if __name__ == "__main__": config = Config('config/xbee2mqtt.yaml') handler = logging.StreamHandler() formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s') handler.setFormatter(formatter) logger = logging.getLogger() logger.setLevel(logging.DEBUG) logger.addHandler(handler) serial = Serial(config.get('radio', 'port', '/dev/ttyUSB0'), config.get('radio', 'baudrate', 9600)) # Sample data when using SerialMock # serial.feed('920013a200406bfd090123010110008010000B00') # IO Sample DIO12:1, ADC7(Supply Voltage):2816 xbee = XBeeWrapper() xbee.serial = serial xbee.default_port_name = config.get('radio', 'default_port_name', 'serial') manager = Xbee2Console() manager.xbee = xbee manager.logger = logger manager.run()
if __name__ == "__main__": def resolve_path(path): return path if path[0] == '/' else os.path.join(os.path.dirname(os.path.realpath(__file__)), path) config_file = resolve_path('config/teleinfo2mqtt.yaml'); config = Config(config_file) handler = logging.StreamHandler() formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s') handler.setFormatter(formatter) logger = logging.getLogger() logger.setLevel(config.get('general', 'logging_level', logging.INFO)) logger.addHandler(handler) mqtt = MosquittoWrapper(config.get('mqtt', 'client_id', None)) mqtt.host = config.get('mqtt', 'host', 'localhost') mqtt.port = config.get('mqtt', 'port', 1883) mqtt.keepalive = config.get('mqtt', 'keepalive', 60) mqtt.clean_session = config.get('mqtt', 'clean_session', False) mqtt.qos = config.get('mqtt', 'qos', 0) mqtt.retain = config.get('mqtt', 'retain', True) mqtt.set_will = config.get('mqtt', 'set_will', True) serialPort = config.get('general', 'serial_port', '/dev/ttyS0') ser = serial.Serial(port=serialPort, baudrate=1200, bytesize=7, parity='E', stopbits=1, timeout=None, xonxoff=0, rtscts=0) telinf = TeleinfoWrapper(ser)
if __name__ == "__main__": def resolve_path(path): return path if path[0] == '/' else os.path.join(os.path.dirname(os.path.realpath(__file__)), path) config_file = resolve_path('config/mqttaverage.yaml'); config = Config(config_file) handler = logging.StreamHandler() formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s') handler.setFormatter(formatter) logger = logging.getLogger() logger.setLevel(config.get('general', 'logging_level', logging.INFO)) logger.addHandler(handler) mqtt = MosquittoWrapper(config.get('mqtt', 'client_id', None)) mqtt.host = config.get('mqtt', 'host', 'localhost') mqtt.port = config.get('mqtt', 'port', 1883) mqtt.keepalive = config.get('mqtt', 'keepalive', 60) mqtt.clean_session = config.get('mqtt', 'clean_session', False) mqtt.qos = config.get('mqtt', 'qos', 0) mqtt.retain = config.get('mqtt', 'retain', True) mqtt.set_will = config.get('mqtt', 'set_will', True) avgmqtt = MQTTAverage(resolve_path(config.get('general', 'pidfile', '/tmp/mqttaverage.pid'))) avgmqtt.stdout = avgmqtt.stderr = resolve_path(config.get('general', 'stdout', '/dev/null')) avgmqtt.debug = config.get('general', 'debug', False) avgmqtt.load(config.get('general', 'avg_routes', {}))
self.log(logging.INFO, "Exiting") if __name__ == "__main__": config = Config('config/xbee2mqtt.yaml') handler = logging.StreamHandler() formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s') handler.setFormatter(formatter) logger = logging.getLogger() logger.setLevel(logging.DEBUG) logger.addHandler(handler) serial = Serial( config.get('radio', 'port', '/dev/ttyUSB0'), config.get('radio', 'baudrate', 9600) ) # Sample data when using SerialMock # serial.feed('920013a200406bfd090123010110008010000B00') # IO Sample DIO12:1, ADC7(Supply Voltage):2816 xbee = XBeeWrapper() xbee.serial = serial xbee.default_port_name = config.get('radio', 'default_port_name', 'serial') manager = Xbee2Console() manager.xbee = xbee manager.logger = logger manager.run()
def load_plugins(webapi, config: Config, logger: Logger): """ Loads all plugins. Any folder located in config.get('webapi', 'plugin_path') is tried to import as module except of __pycache__. If a plugin's folder starts with 'streamhelper-' (case insensitive), this part will be removed in the plugin name. All plugins need to have a set_blueprint(blueprint: flask.Blueprint) function, which should be responsible for setting the blueprint. Routes and other things shall not be defined before the blueprint is set. Within the process, multiple attributes will be set: name, config, logger. The given blueprint will have the static and templates folder set at the root of the module, the name is the folder name in lowercase (the prefix 'streamhelper-' will be stripped, see above) and the url_prefix will be the name, so a plugin called 'test' will have it routes below '/test'. After execution, plugin.exec_post_actions() may be called, which invokes the function post_loading_actions() on all plugins if available. No order implied. :param webapi: the applications flask object :param config: the global config object :param logger:the global logging object """ global c, log c = config log = logger from os import listdir from os.path import isdir, join, basename, dirname from importlib import import_module from sys import path blueprint_path = config.get('webapi', 'plugin_path') path.append(dirname(blueprint_path.rstrip('/'))) blueprints = import_module(basename(blueprint_path.rstrip('/'))) logger.info(f'Searching plugins in {blueprint_path}') for d in listdir(blueprint_path): if not isdir(join(blueprint_path, d)) or d == '__pycache__': continue name = d.lower() if name.startswith('streamhelper-'): name = name[13:] logger.debug(f'Loading plugin {name}') try: plugin = import_module(f'.{d}', package=blueprints.__package__) attr = 'set_blueprint' if not hasattr(plugin, attr): raise AttributeError( f'Plugin {name} misses the attribute {attr}.') from inspect import isfunction if not isfunction(getattr(plugin, attr)): raise AttributeError( f'Plugin {name} has the attribute {attr}, but it\'s not a function.' ) plugin.name = name plugin.config = config plugin.logger = logger blueprint = Blueprint(name, name, template_folder=join(blueprint_path, d, 'templates'), static_folder=join(blueprint_path, d, 'static'), url_prefix=f'/{name}') plugin.set_blueprint(blueprint) plugins[name] = plugin webapi.register_blueprint(blueprint) if hasattr(plugin, 'provides_pages'): for page in plugin.provides_pages: plugin_pages.append( (page[0], f'{plugin.name}.{page[1]}', page[2] if len(page) > 2 else 1000, name)) logger.debug(' -> Finished') except Exception as e: logger.warning(f' -> Loading plugin {name} has failed: {e}') # Load active plugin list and remove unavailable plugins _load_activated_plugins() for plugin in active_plugins.copy(): if plugin not in list(plugins.keys()): _deactivate_plugin(plugin) @webapi.route('/activate_plugin') def activate_plugin(): """ Activates a plugin. At the time, activation and deactivation of plugins only affects the active_plugin() method used by the frontend, and does not unload the plugin. TODO Real load/unload Arguments: - name :return: redirect if redirect_url was passed, otherwise response """ plugin_name = param('name') if not is_set(plugin_name): return redirect_or_response(400, 'Missing parameter name') _activate_plugin(plugin_name) return redirect_or_response(200, 'Success') @webapi.route('/deactivate_plugin', methods=['GET', 'POST']) def deactivate_plugin(): """ Deactivates a plugin. At the time, activation and deactivation of plugins only affects the active_plugin() method used by the frontend, and does not unload the plugin. TODO Real load/unload Takes name as an argument. 400 response if missing. :return: redirect or response """ plugin_name = param('name') if not is_set(plugin_name): return redirect_or_response(400, 'Missing parameter name') _deactivate_plugin(plugin_name) return redirect_or_response(200, 'Success') @webapi.route('/remove_plugin') def remove_plugin(): """ Removes a plugin completely. If flask does not auto reload, the application may need to be restarted for the changes to take effect. Arguments: - name :return: redirect if redirect_url was passed, otherwise response """ plugin_name = param('name') if not is_set(plugin_name): return redirect_or_response(400, 'Missing parameter name') _remove_plugin(plugin_name) return redirect_or_response(200, 'Success')
""" Message received from a subscribed topic """ print "Message received" print("%s %s %s" % (time.asctime(), msg.topic, msg.payload)) if __name__ == "__main__": def resolve_path(path): return path if path[0] == '/' else os.path.join(os.path.dirname(os.path.realpath(__file__)), path) config_file = resolve_path('config/xbee2mqtt.yaml'); config = Config(config_file) host = config.get('mqtt', 'host', 'localhost') port = config.get('mqtt', 'port', 1883) username = config.get('mqtt', 'username', None) password = config.get('mqtt', 'password', None) client = mqtt.Client() client.on_message = on_message if username: client.username_pw_set(username, password) client.connect(host, port, 60) client.subscribe('#', qos=0) while True: try: client.loop()
def do_reload(self): self.log(logging.INFO, "Reloading") config = Config(config_file) self.load(config.get('general', 'routes', {})) self.mqtt.subscribe(self._actions.keys())
if __name__ == "__main__": def resolve_path(path): return path if path[0] == '/' else os.path.join(os.path.dirname(os.path.realpath(__file__)), path) config_file = resolve_path('config/Ripcord.yaml'); config = Config(config_file) handler = logging.StreamHandler() formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s') handler.setFormatter(formatter) logger = logging.getLogger() logger.setLevel(config.get('general', 'logging_level', logging.INFO)) logger.addHandler(handler) BottledTornado = BottledTornado(resolve_path(config.get('general', 'pidfile', '/tmp/BottledTornado.pid'))) BottledTornado.stdout = BottledTornado.stderr = resolve_path(config.get('general', 'stdout', '/dev/null')) BottledTornado.logger = logger BottledTornado.config_file = config_file BottledTornado.ssl_privatekey_file = resolve_path(config.get('app', 'ssl_privatekey_file', '')) BottledTornado.ssl_certificate_file = resolve_path(config.get('app', 'ssl_certificate_file', '')) BottledTornado.port = config.get('app', 'port', 5000) if len(sys.argv) == 2: if 'start' == sys.argv[1]: BottledTornado.start() elif 'stop' == sys.argv[1]: BottledTornado.stop()
Message received from a subscribed topic """ print "Message received" print("%s %s %s" % (time.asctime(), msg.topic, msg.payload)) if __name__ == "__main__": def resolve_path(path): return path if path[0] == '/' else os.path.join( os.path.dirname(os.path.realpath(__file__)), path) config_file = resolve_path('config/xbee2mqtt.yaml') config = Config(config_file) host = config.get('mqtt', 'host', 'localhost') port = config.get('mqtt', 'port', 1883) username = config.get('mqtt', 'username', None) password = config.get('mqtt', 'password', None) client = mqtt.Client() client.on_message = on_message if username: client.username_pw_set(username, password) client.connect(host, port, 60) client.subscribe('#', qos=0) while True: try: client.loop()