Example #1
0
    def read(self, logicname=None):
        """
        return an object with type info about all logics
        """
        # create a list of dicts, where each dict contains the information for one logic
        self.logger.info("LogicsController.read()")

        if self.plugins is None:
            self.plugins = Plugins.get_instance()
        if self.scheduler is None:
            self.scheduler = Scheduler.get_instance()

        self.logics_initialize()
        if self.logics is None:
            # SmartHomeNG has not yet initialized the logics module (still starting up)
            raise cherrypy.NotFound

        if logicname is None:
            return self.get_logics_info()
        else:
            return self.get_logic_info(logicname)
Example #2
0
    def handle_plugin_action(self, id, action):

        if self.plugins is None:
            self.plugins = Plugins.get_instance()
        plugin = self.plugins.return_plugin(id)
        if plugin is None:
            response = {'result': 'error', 'description': "No running plugin instance found for '{}'".format(id)}
            return response

        response = {}
        if action == 'start':
            self.logger.info("PluginController.handle_plugin_action(): Starting plugin '{}'".format(id))
            plugin.run()
            response = {'result': 'ok'}

        elif action == 'stop':
            self.logger.info("PluginController.handle_plugin_action(): Stopping plugin '{}'".format(id))
            plugin.stop()
            response = {'result': 'ok'}

        return response
Example #3
0
    def read(self, id=None):
        """
        return a list of all configured plugin instances
        """
        self.logger.info("PluginsAPIController (index)")

        if self.plugins == None:
            self.plugins = Plugins.get_instance()
        self.plugin_list = []
        for x in self.plugins.return_plugins():
            if isinstance(x, SmartPlugin):
                plugin_config_name = x.get_configname()
                if x.metadata is not None:
                    api = x.metadata.get_plugin_function_defstrings(
                        with_type=True, with_default=True)
                    if api is not None:
                        for function in api:
                            self.plugin_list.append(plugin_config_name + "." +
                                                    function)

        return json.dumps(self.plugin_list)
Example #4
0
    def __init__(self, smarthome, userlogicconf, envlogicconf):
        logger.info('Start Logics')
        self.shtime = Shtime.get_instance()
        self.items = Items.get_instance()
        self.plugins = Plugins.get_instance()
        self.scheduler = Scheduler.get_instance()

        self._sh = smarthome
        self._userlogicconf = userlogicconf
        self._env_dir = smarthome._env_dir
        self._envlogicconf = envlogicconf
        self._etc_dir = smarthome._etc_dir
        self._logic_dir = smarthome._logic_dir
        self._workers = []
        self._logics = {}
        self._bytecode = {}
        self.alive = True

        global _logics_instance
        if _logics_instance is not None:
            import inspect
            curframe = inspect.currentframe()
            calframe = inspect.getouterframes(curframe, 4)
            logger.critical(
                "A second 'logics' object has been created. There should only be ONE instance of class 'Logics'!!! Called from: {} ({})"
                .format(calframe[1][1], calframe[1][3]))

        _logics_instance = self

        self.scheduler = Scheduler.get_instance()

        _config = {}
        self._systemlogics = self._read_logics(envlogicconf, self._env_dir)
        _config.update(self._systemlogics)
        self._userlogics = self._read_logics(userlogicconf, self._logic_dir)
        _config.update(self._userlogics)

        for name in _config:
            self._load_logic(name, _config)
Example #5
0
    def __init__(self, module):
        self._sh = module._sh
        self.module = module
        self.base_dir = self._sh.get_basedir()
        self.logger = logging.getLogger(__name__)

        self.etc_dir = self._sh._etc_dir

        self.logics_dir = os.path.join(self.base_dir, 'logics')
        self.logics = Logics.get_instance()
        self.logger.info("__init__ self.logics = {}".format(self.logics))
        self.plugins = Plugins.get_instance()
        self.logger.info("__init__ self.plugins = {}".format(str(
            self.plugins)))
        self.scheduler = Scheduler.get_instance()
        self.logger.info("__init__ self.scheduler = {}".format(self.scheduler))

        self.blockly_plugin_loaded = None
        self.logics_data = {}

        self.logics = Logics.get_instance()
        return
Example #6
0
    def update(self, logicname='', action='', filename=''):
        """
        Handle PUT requests for logics API
        """
        self.logger.info(
            "LogicsController.update(logicname='{}', action='{}')".format(
                logicname, action))

        if self.plugins is None:
            self.plugins = Plugins.get_instance()
        if self.scheduler is None:
            self.scheduler = Scheduler.get_instance()

        self.logics_initialize()
        if self.logics is None:
            return json.dumps({
                'result':
                'Error',
                'description':
                "SmartHomeNG is still initializing"
            })

        if (action == 'saveparameters') and (logicname != ''):
            return self.save_logic_parameters(logicname)
        elif not action in ['create', 'load', 'delete']:
            mylogic = self.logics.return_logic(logicname)
            if mylogic is None:
                return json.dumps({
                    'result':
                    'Error',
                    'description':
                    "No logic with name '" + logicname + "' found"
                })

        if logicname != '':
            return self.set_logic_state(logicname, action, filename)

        return None
Example #7
0
    def __init__(self, module, shng_url_root):
        self._sh = module._sh
        self.module = module
        self.shng_url_root = shng_url_root

        self.base_dir = self._sh.get_basedir()
        self.plugins_dir = os.path.join(self.base_dir, 'plugins')
        self.logger = logging.getLogger(__name__)

        self.plugins = Plugins.get_instance()

        self.plugin_data = {}

        self.blog_urls = {}
        self._update_bloglinks_active = True
        self._update_bloglinks_thread = threading.Thread(target=self._test_for_blog_articles,
                                                         name="Admin: Update blog links").start()

        try:
            module.add_stop_method(self.stop, self.__class__.__name__)
        except Exception as e:
            self.logger.exception("__init__: Exception {}".format(e))
        return
Example #8
0
    def __init__(self, smarthome, userlogicconf, envlogicconf):
        logger.info('Start Logics')
        self.shtime = Shtime.get_instance()
        self.items = Items.get_instance()
        self.plugins = Plugins.get_instance()
        self.scheduler = Scheduler.get_instance()

        self._sh = smarthome
        self._userlogicconf = userlogicconf
        self._env_dir = smarthome._env_dir
        self._envlogicconf = envlogicconf
        self._etc_dir = smarthome._etc_dir
        self._logic_dir = smarthome._logic_dir
        self._workers = []
        self._logics = {}
        self._bytecode = {}
        self.alive = True

        global _logics_instance
        if _logics_instance is not None:
            import inspect
            curframe = inspect.currentframe()
            calframe = inspect.getouterframes(curframe, 4)
            logger.critical("A second 'logics' object has been created. There should only be ONE instance of class 'Logics'!!! Called from: {} ({})".format(calframe[1][1], calframe[1][3]))

        _logics_instance = self

        self.scheduler = Scheduler.get_instance()
        
        _config = {}
        self._systemlogics = self._read_logics(envlogicconf, self._env_dir)
        _config.update(self._systemlogics)
        self._userlogics = self._read_logics(userlogicconf, self._logic_dir)
        _config.update(self._userlogics)

        for name in _config:
            self._load_logic(name, _config)
Example #9
0
    def __init__(self, module, shng_url_root):
        self._sh = module._sh
        self.module = module
        self.shng_url_root = shng_url_root

        self.base_dir = self._sh.get_basedir()
        self.plugins_dir = os.path.join(self.base_dir, 'plugins')
        self.logger = logging.getLogger(__name__)

        self.plugins = Plugins.get_instance()

        self.plugin_data = {}

        self.blog_urls = {}
        self._update_bloglinks_active = True

        # Start scheduler
        self._blog_task_name = 'modules.admin.update_blog_links'
        self._sh.scheduler.add(self._blog_task_name, self._test_for_blog_articles_task, cycle=60, offset=0)
        try:
            module.add_stop_method(self.stop, self.__class__.__name__)
        except Exception as e:
            self.logger.exception("__init__: Exception {}".format(e))
        return
Example #10
0
    def get_config_filename(self):

        if self.plugins is None:
            self.plugins = Plugins.get_instance()

        return self.plugins._get_plugin_conf_filename()
Example #11
0
    def __init__(self):

        self.plugins = Plugins.get_instance()
        self.logger.info("BackendPlugins __init__ self.plugins = {}".format(
            str(self.plugins)))
Example #12
0
 def read(self, id=None):
     """
     return an object with data about the logic parameters of all configured plugins
     """
     self.plugins = Plugins.get_instance()
     return json.dumps(self.plugins.get_logic_parameters())
Example #13
0
    def read(self, id=None):
        """
        return a list of all configured plugin instances
        """
        self.logger.info("PluginsInfoController (index)")
        if self.plugins == None:
            self.plugins = Plugins.get_instance()

        # get data for display of page
        conf_plugins = {}
        _conf = lib.config.parse(self.plugins._get_plugin_conf_filename())

        for plugin in _conf:
            conf_plugins[plugin] = {}
            conf_plugins[plugin] = _conf[plugin]

        #self._test_for_blog_articles()
        plugin_list = []
        for x in self.plugins.return_plugins():
            plugin = dict()
            plugin['metadata'] = {}

            plugin['stopped'] = False
            # Update(s) triggered by < strong > {{p.instance._itemlist | length}} < / strong > items
            plugin['triggers'] = str(x._itemlist)

            if isinstance(x, SmartPlugin):
                plugin['pluginname'] = x.get_shortname()
                plugin['configname'] = x.get_configname()
                plugin['version'] = x.get_version()
                plugin['smartplugin'] = True
                plugin['multiinstance'] = x.is_multi_instance_capable()
                plugin['instancename'] = x.get_instance_name()

                plugin['webif_url'] = ''
                if self.module.mod_http.get_webifs_for_plugin(
                        x.get_shortname()) != []:
                    for webif in self.module.mod_http.get_webifs_for_plugin(
                            x.get_shortname()):
                        if webif['Instance'] == plugin['instancename']:
                            # plugin['webif_url'] = self.shng_url_root + webif['Mount']  # don't specify full path (for docker installations reletive path is needed)
                            plugin['webif_url'] = webif['Mount']

                plugin['blog_url'] = self.blog_urls.get(
                    plugin['pluginname'], '')

                plugin['parameters'] = []
                if bool(x._parameters):
                    #                    for p in x._parameters:
                    for p in x._metadata.get_parameterlist():
                        p_dict = {}
                        p_dict['name'] = str(p)
                        p_dict[
                            'type'] = x._metadata.get_parameter_type_with_subtype(
                                p)
                        p_dict['value'] = str(x._parameters[p])
                        p_dict[
                            'default'] = x._metadata.get_parameter_defaultvalue(
                                p)
                        plugin['parameters'].append(p_dict)

                plugin['attributes'] = []
                for a in x._metadata.get_itemdefinitionlist():
                    a_dict = {}
                    a_dict['name'] = str(a)
                    a_dict[
                        'type'] = x._metadata.get_itemdefinition_type_with_subtype(
                            a)
                    plugin['attributes'].append(a_dict)

                plugin['metadata']['classpath'] = x._classpath  # str
                plugin['metadata']['classname'] = x.get_classname()
            else:
                plugin['pluginname'] = x._shortname
                plugin['configname'] = x._configname
                plugin['version'] = ''
                plugin['smartplugin'] = False
                plugin['multiinstance'] = False
                plugin['instancename'] = ''
                plugin['webif_url'] = ''
                plugin['parameters'] = []
                plugin['attributes'] = []

                plugin['metadata']['classpath'] = str(x._classpath)  # str
                plugin['metadata']['classname'] = str(x._classname)  # str
                plugin['stopped'] = False

            plugin['metadata']['type'] = x._metadata.get_string('type')
            plugin['metadata']['state'] = x._metadata.get_string('state')
            plugin['metadata']['description'] = x._metadata.get_mlstring(
                'description')
            plugin['metadata']['description_long'] = x._metadata.get_mlstring(
                'description_long')
            plugin['metadata']['keywords'] = x._metadata.get_string('keywords')
            plugin['metadata']['documentation'] = x._metadata.get_string(
                'documentation')
            plugin['metadata']['support'] = x._metadata.get_string('support')
            plugin['metadata']['maintainer'] = x._metadata.get_string(
                'maintainer')
            plugin['metadata']['tester'] = x._metadata.get_string('tester')

            try:
                plugin['stopped'] = not x.alive
                plugin['stoppable'] = True
            except:
                plugin['stopped'] = False
                plugin['stoppable'] = False
            if plugin['pluginname'] == 'backend':
                plugin['stoppable'] = False

            plugin_list.append(plugin)
        #        plugins_sorted = sorted(plugin_list, key=lambda k: k['classpath'])
        plugins_sorted = sorted(
            plugin_list, key=lambda k: k['pluginname'] + k['instancename'])

        return json.dumps(plugins_sorted)
Example #14
0
    def _test_for_blog_articles_task(self):
        """
        Scheduler task to test if blog articles for the loaded plugins exist
        :return:
        """

        if self.plugins == None:
            self.plugins = Plugins.get_instance()
        if self.plugins != None and self._sh.shng_status.get(
                'code', 0) == 20:  # Running
            self._sh.scheduler._scheduler[self._blog_task_name]['cycle'] = {
                120 * 60: None
            }  # set scheduler cycle to test every 2 hours
            start = time.time()
            temp_blog_urls = {}

            try:
                for plugin in self.plugins.return_plugins():
                    if not self._update_bloglinks_active:
                        break
                    if isinstance(plugin, SmartPlugin):
                        plugin_name = plugin.get_shortname()
                        if temp_blog_urls.get(plugin_name, None) is None:
                            # add link to blog, if articles exist, that have the pluginname as a tag
                            #   example: Blog articles with tag 'backend'
                            #   - https://www.smarthomeng.de/tag/backend
                            #   alternative example: Blog articles with category 'plugins' and tag 'backend'
                            #   - https://www.smarthomeng.de/category/plugins?tag=backend
                            temp_blog_urls[
                                plugin_name] = 'https://www.smarthomeng.de/tag/' + plugin_name
                            r = requests.get(temp_blog_urls[plugin_name])
                            if r.status_code == 404:
                                temp_blog_urls[plugin_name] = ''
                            elif r.status_code != 200:
                                self.logger.error(
                                    "Received status_code {} for get-request to {}"
                                    .format(r.status_code,
                                            temp_blog_urls[plugin_name]))
                                temp_blog_urls[plugin_name] = ''
                        else:
                            pass
            except OSError as e:
                if str(e).find(
                        '[Errno 101]'
                ) > -1:  # [Errno 101] Das Netzwerk ist nicht erreichbar
                    pass
                else:
                    self.logger.error(
                        "_test_for_blog_articles: OSError {}".format(e))
            except Exception as e:
                self.logger.error(
                    "_test_for_blog_articles: Exception {}".format(e))
            self.blog_urls = temp_blog_urls
            end = time.time()
            self.logger.info(
                "_test_for_blog_articles_task: Used time: {} - blog_urls = {}".
                format(end - start, self.blog_urls))
        else:
            self.logger.debug(
                "_test_for_blog_articles: Plugin initialization not finished")
        return
Example #15
0
    def read(self, id=None):
        """
        return an object with data about all configured plugins
        """
        if self.plugins is None:
            self.plugins = Plugins.get_instance()

        config_filename = self.plugins._get_plugin_conf_filename()
        _etc_dir = os.path.dirname(config_filename)

        info = {}
        # make it 'readonly', if plugin.conf is used
        info['readonly'] = not (os.path.splitext(config_filename)[1].lower()
                                == '.yaml')

        if not info['readonly']:
            # for beta-testing: create a backup of ../etc/plugin.yaml
            if not os.path.isfile(
                    os.path.join(_etc_dir, 'plugin_before_admin_config.yaml')):
                shutil.copy2(
                    config_filename,
                    os.path.join(_etc_dir, 'plugin_before_admin_config.yaml'))
                self.logger.warning(
                    'Created a backup copy of plugin.yaml ({})'.format(
                        os.path.join(_etc_dir,
                                     'plugin_before_admin_config.yaml')))

        # get path to plugin configuration file, withou extension
        _conf = lib.config.parse_basename(os.path.splitext(config_filename)[0],
                                          configtype='plugin')

        for confplg in _conf:
            plg = _conf[confplg].get('plugin_name', '?')
            if plg == '?':
                plg = _conf[confplg].get('class_path', '?')
            plginstance = self.plugins.return_plugin(confplg)
            typ = '?'
            if plginstance != None:
                # self.logger.warning("confplg {}: type(plginstance) = {}".format(confplg, type(plginstance)))
                # self.logger.warning("confplg {}: type(plginstance.metadata) = {}".format(confplg, type(plginstance.metadata)))
                try:
                    typ = plginstance.metadata.get_string('type')
                    _conf[confplg]['_meta'] = plginstance.metadata.meta
                    _conf[confplg]['_description'] = plginstance.metadata.meta[
                        'plugin']['description']
                except:
                    self.logger.warning(
                        'confplg {}: Passed for plginstance = {}'.format(
                            confplg, plginstance))
            else:
                # nicht geladene Plugins
                # self.logger.warning("confplg {}: type(plginstance) = None".format(confplg))
                plugin_name, metadata = self._get_pluginname_and_metadata(
                    confplg, _conf[confplg])
                # self.logger.warning("plugin_name = {}, meta = {}".format(plugin_name, metadata.meta))

                typ = metadata.get_string('type')
                _conf[confplg]['_meta'] = metadata.meta
                try:
                    _conf[confplg]['_description'] = metadata.meta['plugin'][
                        'description']
                except:
                    _conf[confplg]['_description'] = {}
                    _conf[confplg]['_description']['de'] = ''
                    _conf[confplg]['_description']['en'] = ''

        info['plugin_config'] = _conf

        return json.dumps(info)
Example #16
0
    def __init__(self):

        self.plugins = Plugins.get_instance()

        return