def __init__(self): """ Initialization Routine for the mqtt extension class to SmartPlugin """ SmartPlugin.__init__(self) # get instance of MQTT module try: self.mod_mqtt = Modules.get_instance().get_module('mqtt') # try/except to handle running in a core version that does not support modules except: self.mod_mqtt = None if self.mod_mqtt == None: self.logger.error("Module 'mqtt' not loaded. The plugin is not starting") self._init_complete = False return False self._subscribed_topics_lock = threading.Lock() self._subscribed_topics = {} # subscribed topics (a dict of dicts) self._subscribe_current_number = 0 # current number of the subscription entry self._subscriptions_started = False # get broker configuration (for display in web interface) self.broker_config = self.mod_mqtt.get_broker_config() return True
def init_webinterface(self): """" Initialize the web interface for this plugin This method is only needed if the plugin is implementing a web interface """ try: self.mod_http = Modules.get_instance().get_module( 'http') # try/except to handle running in a core version that does not support modules except: self.mod_http = None if self.mod_http == None: self.logger.error("Plugin '{}': Not initializing the web interface".format(self.get_shortname())) return False # set application configuration for cherrypy webif_dir = self.path_join(self.get_plugin_dir(), 'webif') config = { '/': { 'tools.staticdir.root': webif_dir, }, '/static': { 'tools.staticdir.on': True, 'tools.staticdir.dir': 'static' } } # Register the web interface as a cherrypy app self.mod_http.register_webif(WebInterface(webif_dir, self), self.get_shortname(), config, self.get_classname(), self.get_instance_name(), description='') return True
def init_webinterface(self): """" Initialize the web interface for this plugin This method is only needed if the plugin is implementing a web interface """ try: self.mod_http = Modules.get_instance().get_module('http') # try/except to handle running in a core version that does not support modules except: self.mod_http = None if self.mod_http == None: self.logger.error("Plugin '{}': Not initializing the web interface".format(self.get_shortname())) return False # set application configuration for cherrypy webif_dir = self.path_join(self.get_plugin_dir(), 'webif') config = { '/': { 'tools.staticdir.root': webif_dir, }, '/static': { 'tools.staticdir.on': True, 'tools.staticdir.dir': 'static' } } # Register the web interface as a cherrypy app self.mod_http.register_webif(WebInterface(webif_dir, self), self.get_shortname(), config, self.get_classname(), self.get_instance_name(), description='Blockly graphical logics editor for SmartHomeNG', webifname='') return True
def init_webinterfaces(self): try: self.mod_http = Modules.get_instance().get_module( 'http' ) # try/except to handle running in a core version that does not support modules except: self.mod_http = None if self.mod_http == None: self.logger.error( "Plugin '{}': Not initializing the web interface".format( self.get_fullname())) return False webif_dir = self.path_join(self.get_plugin_dir(), 'webif') config = { '/': { 'tools.staticdir.root': webif_dir, }, '/static': { 'tools.staticdir.on': True, 'tools.staticdir.dir': 'static' } } config_callback_rest = {'/': {}} config_callback_ws = {'/': {}} # Register the REST interface as a cherrypy app self.mod_http.register_service( RESTWebServicesInterface(webif_dir, self), self.get_shortname(), config_callback_rest, self.get_classname(), self.get_instance_name(), description='WebService Plugin für SmartHomeNG (REST)', servicename='rest', use_global_basic_auth=self._use_service_auth) # Register the simple WebService interface as a cherrypy app self.mod_http.register_service( SimpleWebServiceInterface(webif_dir, self), self.get_shortname(), config_callback_ws, self.get_classname(), self.get_instance_name(), description='Webservice-Plugin für SmartHomeNG (simple)', servicename='ws', use_global_basic_auth=self._use_service_auth) # Register the web overview of the webservices interfaces as a cherrypy app self.mod_http.register_webif( WebInterface(webif_dir, self), self.get_shortname(), config, self.get_classname(), self.get_instance_name(), description='Webservice-Plugin für SmartHomeNG (Frontend)') return True
def get_module(self, modulename): """ Test if module http is loaded and if loaded, return a handle to the module """ try: mymod = Modules.get_instance().get_module(modulename) except: mymod = None if mymod == None: self.logger.error("Module '{}' not loaded".format(modulename)) else: self.logger.info("Using module '{}'".format(str(mymod._shortname))) return mymod
def get_module(self, modulename): """ Test if module http is loaded and if loaded, return a handle to the module """ try: mymod = Modules.get_instance().get_module(modulename) except: mymod = None if mymod == None: self.logger.error("Module '{}' not loaded".format(modulename)) else: self.logger.info("Using module '{}'".format(str( mymod._shortname ) ) ) return mymod
def init_webinterfaces(self): """" Initialize the web interface for this plugin This method is only needed if the plugin is implementing a web interface """ try: self.mod_http = Modules.get_instance().get_module( 'http' ) # try/except to handle running in a core version that does not support modules except: self.mod_http = None if self.mod_http is None: self.logger.error( "Plugin '{}': Not initializing the web interface. If not already done so, please configure " "http module in etc/module.yaml.".format(self.get_fullname())) return False webif_dir = self.path_join(self.get_plugin_dir(), 'webif') config = { '/': { 'tools.staticdir.root': webif_dir, }, '/static': { 'tools.staticdir.on': True, 'tools.staticdir.dir': 'static' } } config_callback_ws = {'/': {}} # Register the web interface as a cherrypy app self.mod_http.register_webif(WebInterface(webif_dir, self), self.get_shortname(), config, self.get_classname(), self.get_instance_name(), description='Nuki Web Interface') # Register the callback interface as a cherrypy app self.mod_http.register_service(NukiWebServiceInterface( webif_dir, self), self.get_shortname(), config_callback_ws, self.get_classname(), self.get_instance_name(), description='', servicename='nuki_callback', use_global_basic_auth=False) return True
def init_webinterface(self): """" Initialize the web interface for this plugin This method is only needed if the plugin is implementing a web interface """ try: self.mod_http = Modules.get_instance().get_module( 'http' ) # try/except to handle running in a core version that does not support modules except: self.mod_http = None if self.mod_http == None: if self.logger.isEnabledFor(logging.ERROR): self.logger.error("Not initializing the web interface") return False import sys if not "SmartPluginWebIf" in list( sys.modules['lib.model.smartplugin'].__dict__): if self.logger.isEnabledFor(logging.WARNING): self.logger.warning( "Web interface needs SmartHomeNG v1.5 and up. Not initializing the web interface" ) return False # set application configuration for cherrypy webif_dir = self.path_join(self.get_plugin_dir(), 'webif') config = { '/': { 'tools.staticdir.root': webif_dir, }, '/static': { 'tools.staticdir.on': True, 'tools.staticdir.dir': 'static' } } # Register the web interface as a cherrypy app self.mod_http.register_webif(WebInterface(webif_dir, self), self.get_shortname(), config, self.get_classname(), self.get_instance_name(), description='') return True
def init_webinterface(self, WebInterface=None): """" Initialize the web interface for this plugin This method is only needed if the plugin is implementing a web interface """ if WebInterface is None: return False try: # try/except to handle running in a core version that does not support modules self.mod_http = Modules.get_instance().get_module('http') except: self.mod_http = None if self.mod_http == None: self.logger.warning( "Module 'http' not loaded. Not initializing the web interface for the plugin" ) return False # set application configuration for cherrypy webif_dir = self.path_join(self.get_plugin_dir(), 'webif') config = { '/': { 'tools.staticdir.root': webif_dir, }, '/static': { 'tools.staticdir.on': True, 'tools.staticdir.dir': 'static' } } # Register the web interface as a cherrypy app self.mod_http.register_webif(WebInterface(webif_dir, self), self.get_shortname(), config, self.get_classname(), self.get_instance_name(), description='') return True
def init_webinterface(self): """" Initialize the web interface for this plugin This method is only needed if the plugin is implementing a web interface """ try: self.mod_http = Modules.get_instance().get_module('http') except Exception: self.mod_http = None if self.mod_http is None: self.logger.error( "Plugin '{}': Not initializing the web interface".format( self.get_shortname())) return False # set application configuration for cherrypy webif_dir = self.path_join(self.get_plugin_dir(), 'webif') config = { '/': { 'tools.staticdir.root': webif_dir, }, '/static': { 'tools.staticdir.on': True, 'tools.staticdir.dir': 'static' } } self.logger.debug("Plugin '{0}': {1}, {2}, {3}, {4}, {5}".format( self.get_shortname(), webif_dir, self.get_shortname(), config, self.get_classname(), self.get_instance_name())) # Register the web interface as a cherrypy app self.mod_http.register_webif(WebInterface(webif_dir, self), self.get_shortname(), config, self.get_classname(), self.get_instance_name(), description='') return True
def _task(self, name, obj, by, source, dest, value): threading.current_thread().name = name logger = logging.getLogger(name) if obj.__class__.__name__ == 'Logic': source_details = None if isinstance(source, dict): source_details = source.get('details', '') source = source.get('item', '') trigger = { 'by': by, 'source': source, 'source_details': source_details, 'dest': dest, 'value': value } # noqa #following variables are assigned to be available during logic execution sh = self._sh # noqa shtime = self.shtime items = self.items # set the logic environment here (for use within functions in logics): logic = obj # noqa logic.sh = sh logic.logger = logger logic.shtime = shtime logic.items = items logic.trigger_dict = trigger # logic.trigger has naming conflict with method logic.trigger of lib.item logics = obj._logics if not self.mqtt: if _lib_modules_found: self.mqtt = Modules.get_instance().get_module('mqtt') mqtt = self.mqtt logic.mqtt = mqtt try: if logic.enabled: exec(obj.bytecode) # store timestamp of last run obj.set_last_run() for method in logic.get_method_triggers(): try: method(logic, by, source, dest) except Exception as e: logger.exception( "Logic: Trigger {} for {} failed: {}".format( method, logic.name, e)) except SystemExit: # ignore exit() call from logic. pass except Exception as e: tb = sys.exc_info()[2] tb = traceback.extract_tb(tb)[-1] logger.exception( "Logic: {0}, File: {1}, Line: {2}, Method: {3}, Exception: {4}" .format(name, tb[0], tb[1], tb[2], e)) elif obj.__class__.__name__ == 'Item': try: if value is not None: obj(value, caller="Scheduler") except Exception as e: logger.exception("Item {0} exception: {1}".format(name, e)) else: # method try: if value is None: obj() else: obj(**value) except Exception as e: logger.exception("Method {0} exception: {1}".format(name, e)) threading.current_thread().name = 'idle'
def __init__(self, sh, testparam=''): """ Initialization Routine for the module """ # TO DO: Shortname anders setzen (oder warten bis der Plugin Loader es beim Laden setzt self._shortname = self.__class__.__name__ self._shortname = self._shortname.lower() self.logger = logging.getLogger(__name__) self._sh = sh self.shtime = Shtime.get_instance() self.logger.debug("Module '{}': Initializing".format(self._shortname)) self.logger.debug("Module '{}': Parameters = '{}'".format( self._shortname, str(self._parameters))) # for authentication self.send_hash = 'shNG0160$' self.jwt_secret = 'SmartHomeNG$0815' try: self.mod_http = Modules.get_instance().get_module( 'http' ) # try/except to handle running in a core version that does not support modules except: self.mod_http = None if self.mod_http == None: self.logger.error( "Module '{}': Not initializing - Module 'http' has to be loaded BEFORE this module" .format(self._shortname)) self._init_complete = False return self._showtraceback = self.mod_http._showtraceback try: self.login_expiration = self._parameters['login_expiration'] self.login_autorenew = self._parameters['login_autorenew'] self.pypi_timeout = self._parameters['pypi_timeout'] self.itemtree_fullpath = self._parameters['itemtree_fullpath'] self.itemtree_searchstart = self._parameters[ 'itemtree_searchstart'] self.websocket_host = self._parameters['websocket_host'] self.websocket_port = self._parameters['websocket_port'] self.log_chunksize = self._parameters['log_chunksize'] except: self.logger.critical( "Module '{}': Inconsistent module (invalid metadata definition)" .format(self._shortname)) self._init_complete = False return mysuburl = '' if suburl != '': mysuburl = '/' + suburl ip = get_local_ipv4_address() self.port = self.mod_http._port # self.logger.warning('port = {}'.format(self.port)) self.shng_url_root = 'http://' + ip + ':' + str( self.port) # for links mto plugin webinterfaces self.url_root = self.shng_url_root + mysuburl self.api_url_root = self.shng_url_root + 'api' self.api2_url_root = self.shng_url_root + 'api2'
def _execute_logic_task(self, logic, by, source, dest, value): """ Execute a logic from _task method :param logic: :return: """ name = 'logics.' + logic.name logger = logging.getLogger(name) source_details = None if isinstance(source, dict): source_details = source.get('details', '') src = source.get('item', '') if src == '': # get source ('cron' or 'cycle') src = source.get('source', '') source = src trigger = {'by': by, 'source': source, 'source_details': source_details, 'dest': dest, 'value': value} # noqa # following variables are assigned to be available during logic execution sh = self._sh # noqa shtime = self.shtime items = self.items # set the logic environment here (for use within functions in logics): #logic = obj # noqa logic.sh = sh logic.logger = logger logic.shtime = shtime logic.items = items logic.trigger_dict = trigger # logic.trigger has naming conflict with method logic.trigger of lib.item logics = logic._logics if not self.mqtt: if _lib_modules_found: self.mqtt = Modules.get_instance().get_module('mqtt') mqtt = self.mqtt logic.mqtt = mqtt try: if logic.enabled: if sh.shng_status['code'] < 20: logger.warning(f"Logik ignoriert, SmartHomeNG ist noch nicht vollständig initialisiert - Logik wurde getriggert durch {trigger}") else: logger.debug(f"Getriggert durch: {trigger}") exec(logic.bytecode) # store timestamp of last run logic.set_last_run() for method in logic.get_method_triggers(): try: method(logic, by, source, dest) except Exception as e: logger.exception("Logic: Trigger {} for {} failed: {}".format(method, logic.name, e)) except LeaveLogic as e: # 'LeaveLogic' is no error if str(e) != '': logger.info(f"Die Logik '{logic.name}' wurde verlassen. Grund: {e}") except SystemExit: # ignore exit() call from logic. pass except Exception as e: tb = sys.exc_info()[2] tb = traceback.extract_tb(tb)[-1] if tb[2] == '<module>': logic_method = 'Hauptroutine der Logik' else: logic_method = 'function ' + tb[2] + '()' logger.error(f"In der Logik ist ein Fehler aufgetreten:\n Logik '{logic.name}', Datei '{tb[0]}', Zeile {tb[1]}\n {logic_method}, Exception: {e}") #logger.exception(f"In der Logik ist ein Fehler aufgetreten:\n Logik '{logic.name}', Datei '{tb[0]}', Zeile {tb[1]}\n {logic_method}, Exception: '{e}'\n ") return
def __init__(self, sh): #self.logger = logging.getLogger(__name__) self._sh = sh self.default_acl = self.get_parameter_value('default_acl') self.smartvisu_dir = self.get_parameter_value('smartvisu_dir') self._generate_pages = self.get_parameter_value('generate_pages') self.overwrite_templates = self.get_parameter_value( 'overwrite_templates') self.visu_style = self.get_parameter_value('visu_style').lower() if not self.visu_style in ['std', 'blk']: self.visu_style = 'std' self.logger.error( "smartVISU: Invalid value '" + self.get_parameter_value('visu_style') + "' configured for attribute visu_style in plugin.conf, using '" + str(self.visu_style) + "' instead") self._handle_widgets = self.get_parameter_value('handle_widgets') self.list_deprecated_warnings = self.get_parameter_value( 'list_deprecated_warnings') self.smartvisu_version = self.get_smartvisu_version() if self.smartvisu_version == '': self.logger.error("Could not determine smartVISU version!") self.smartvisu_is_configured = self.sv_is_configured() self.logger.info( f"sv version={self.smartvisu_version}, sv_is_configured={self.smartvisu_is_configured}" ) self.deprecated_widgets = [] self.removed_widgets = [] self.deprecated_plugin_widgets = [ ] # List of plugin-widgets that use deprecated widgets self.removed_plugin_widgets = [ ] # List of plugin-widgets that use removed widgets self.d_usage = {} self.r_usage = {} self.read_visu_definition() self.load_deprecated_info() # get instance of websocket module (to enable sv-protocol support) try: self.mod_websocket = Modules.get_instance().get_module('websocket') except: self.mod_websocket = None if self.mod_websocket == None: self.logger.info("Module 'websocket' could not be initialized.") else: self.mod_websocket.set_smartvisu_support( protocol_enabled=True, default_acl=self.default_acl, query_definitions=False, series_updatecycle=0) self.port = '' self.tls_port = '' if self.mod_websocket is not None: self.port = str(self.mod_websocket.get_port()) if self.mod_websocket.get_use_tls(): self.tls_port = self.mod_websocket.get_tls_port() self.init_webinterface(WebInterface) return
def __init__(self, sh, *args, **kwargs): """ Initalizes the plugin. The parameters describe for this method are pulled from the entry in plugin.conf. If sh object is needed at all, ``self.get_sh()`` can be used to get it. There should be almost no need for a reference to the sh object any more. The parameters *args and **kwargs are the old way of passing parameters. They are deprecated. They are implemented to support older plugins. Plugins for SmartHomeNG v1.4 and beyond should use the new way of getting parameter values: use the SmartPlugin method `get_parameter_value(parameter_name)` instead. Anywhere within the Plugin you can get the configured (and checked) value for a parameter by calling `self.get_parameter_value(parameter_name)`. It returns the value in the datatype that is defined in the metadata. """ from bin.smarthome import VERSION if '.'.join(VERSION.split('.', 2)[:2]) <= '1.5': self.logger = logging.getLogger(__name__) self.logger.debug("init {}".format(__name__)) self._init_complete = False # get the parameters for the plugin (as defined in metadata plugin.yaml): # self.param1 = self.get_parameter_value('param1') self.ip = self.get_parameter_value('ip') self.port = self.get_parameter_value('port') self.tls = self.get_parameter_value('tls') self.acl = self.get_parameter_value('acl') self.wsproto = self.get_parameter_value('wsproto') self.querydef = self.get_parameter_value('querydef') if self.acl in ('true', 'yes'): self.acl = 'rw' # get instance of websocket module (to check for port use collision) try: self.mod_websocket = Modules.get_instance().get_module('websocket') except: self.mod_websocket = None if self.mod_websocket is None: self.logger.warning( "The new websocket module is not configured/loaded.") self.logger.warning( "You should configure the websocket module and disable this plugin (visu_websocket)" ) else: module_port = self.mod_websocket.get_port() module_tls_port = self.mod_websocket.get_tls_port() if (self.port == module_port) or (self.port == module_tls_port): self.logger.warning( f"Websocket module is configured to use the same port ({self.port})" ) self.logger.warning( "Disable this plugin (visu_smartvisu), you don't need it any more" ) self._init_complete = False return self.websocket = _websocket(self.get_sh(), self, self.ip, self.port, self.tls, self.wsproto, self.querydef) self.init_webinterface() self.logger.debug("init done") self._init_complete = True