Exemple #1
0
    def set_config_section_key(self, section, key, value):
        """
        Sets the value of key for a given logic (section)

        :param section: logic to set the key for
        :param key: key for which the value should be set
        :param value: value to set

        """
        # load /etc/logic.yaml
        conf_filename = os.path.join(self._get_etc_dir(), 'logic')
        conf = shyaml.yaml_load_roundtrip(conf_filename)

        logger.info(
            "set_config_section_key: section={}, key={}, value={}".format(
                section, key, str(value)))
        if value == None:
            if conf[section].get(key, None) != None:
                del conf[section][key]
        else:
            conf[section][key] = value

        # save /etc/logic.yaml
        shyaml.yaml_save_roundtrip(conf_filename, conf, True)

        # activate visu_acl without reloading the logic
        if key == 'visu_acl':
            mylogic = self.return_logic(section)
            if mylogic is not None:
                logger.info(" - key={}, value={}".format(key, value))
                #                if value is None:
                #                    value = 'false'
                mylogic.visu_acl = str(value)

        return
Exemple #2
0
    def read_config_section(self, section):
        """
        Read a section from /etc/logic.yaml

        This funtion returns the data from one section of the configuration file as a list of
        configuration entries. A configuration entry is a list with three items:
        - key      configuration key
        - value    configuration value (string or list)
        - comment  comment for the value (string or list)

        :param section: Name of the logic (section)
        :type section: str

        :return: config_list: list of configuration entries. Each entry of this list is a list with three string entries: ['key', 'value', 'comment']
        :rtype: list of lists
        """
        if self.return_config_type() != YAML_FILE:
            logger.error("read_config_section: Editing of configuration only possible with new (yaml) config format")
            return False

        # load /etc/logic.yaml
        conf_filename = os.path.join(self._get_etc_dir(), 'logic')
        conf = shyaml.yaml_load_roundtrip(conf_filename)

        config_list = []
        if conf is not None:
            section_dict = conf.get(section, {})
#            logger.warning("read_config_section: read_config_section('{}') = {}".format(section, str(section_dict) ))
            for key in section_dict:
                if isinstance(section_dict[key], list):
                    value = section_dict[key]
                    comment = []            # 'Comment 6: ' + loaded['a']['c'].ca.items[0][0].value      'Comment 7: ' + loaded['a']['c'].ca.items[1][0].value
                    for i in range(len(value)):
                        if i in section_dict[key].ca.items:
                            try:
                                c = section_dict[key].ca.items[i][0].value
                            except:
                                logger.info("c: {}, Key: {}".format(c, key))
                                c = ''
                            if len(c) > 0 and c[0] == '#':
                                c = c[1:]
                        else:
                            c = ''

                        comment.append(c.strip())
                else:
                    value = section_dict[key]
                    c = ''
                    if key in section_dict.ca.items:
                        try:
                            c = section_dict.ca.items[key][2].value    # if not list: loaded['a'].ca.items['b'][2].value
                        except:
                            logger.info("c2: {}, Key: {}".format(c, key))
                        if len(c) > 0 and c[0] == '#':
                            c = c[1:]
                    comment = c.strip()

#                logger.warning("-> read_config_section: section_dict['{}'] = {}, comment = '{}'".format(key, str(section_dict[key]), comment ))
                config_list.append([key, value, comment])
        return config_list
Exemple #3
0
    def add(self, id=None):
        self.logger.info("PluginController(): add('{}')".format(id))

        params = self.get_body()
        if params is None:
            self.logger.warning("PluginController(): add(): section '{}': Bad, add request".format(id))
            raise cherrypy.HTTPError(status=411)
        self.logger.info("PluginController(): add(): section '{}' = {}".format(id, params))

        config_filename = self.get_config_filename()

        if self.test_for_old_config(config_filename):
            # make it 'readonly', if plugin.conf is used
            response = {'result': 'error', 'description': 'Updateing .CONF files is not supported'}
        else:
            response = {}
            plugin_conf = shyaml.yaml_load_roundtrip(config_filename)
            sect = plugin_conf.get(id)
            if sect is not None:
                response = {'result': 'error', 'description': "Configuration section '{}' already exists".format(id)}
            else:
                plugin_conf[id] = params.get('config', {})
                shyaml.yaml_save_roundtrip(config_filename, plugin_conf, False)
                response = {'result': 'ok'}

        self.logger.info("PluginController(): add(): response = {}".format(response))
        return json.dumps(response)
Exemple #4
0
    def read_config_section(self, section):
        """
        Read a section from /etc/logic.yaml
        
        This funtion returns the data from one section of the configuration file as a list of
        configuration entries. A configuration entry is a list with three items:
        - key      configuration key
        - value    configuration value (string or list)
        - comment  comment for the value (string or list)
          
        :param section: Name of the logic (section)
        :type section: str
        
        :return: config_list: list of configuration entries. Each entry of this list is a list with three string entries: ['key', 'value', 'comment']
        :rtype: list of lists
        """
        if self.return_config_type() != YAML_FILE:
            logger.error("read_config_section: Editing of configuration only possible with new (yaml) config format")
            return False
            
        # load /etc/logic.yaml
        conf_filename = os.path.join(self._get_etc_dir(), 'logic') 
        conf = shyaml.yaml_load_roundtrip(conf_filename)

        config_list = []
        if conf is not None:
            section_dict = conf.get(section, {})
#            logger.warning("read_config_section: read_config_section('{}') = {}".format(section, str(section_dict) ))
            for key in section_dict:
                if isinstance(section_dict[key], list):
                    value = section_dict[key]
                    comment = []            # 'Comment 6: ' + loaded['a']['c'].ca.items[0][0].value      'Comment 7: ' + loaded['a']['c'].ca.items[1][0].value
                    for i in range(len(value)):
                        if i in section_dict[key].ca.items:
                            try:
                                c = section_dict[key].ca.items[i][0].value
                            except:
                                logger.info("c: {}, Key: {}".format(c, key)) 
                                c = ''
                            if len(c) > 0 and c[0] == '#':
                                c = c[1:]
                        else:
                            c = ''
                    
                        comment.append(c.strip())
                else:
                    value = section_dict[key]
                    c = ''
                    if key in section_dict.ca.items:
                        try:
                            c = section_dict.ca.items[key][2].value    # if not list: loaded['a'].ca.items['b'][2].value 
                        except:
                            logger.info("c2: {}, Key: {}".format(c, key)) 
                        if len(c) > 0 and c[0] == '#':
                            c = c[1:]
                    comment = c.strip()
            
#                logger.warning("-> read_config_section: section_dict['{}'] = {}, comment = '{}'".format(key, str(section_dict[key]), comment ))
                config_list.append([key, value, comment])
        return config_list
Exemple #5
0
    def set_config_section_key(self, section, key, value):
        """
        Sets the value of key for a given logic (section)
        
        :param section: logic to set the key for
        :param key: key for which the value should be set
        :param value: value to set
        
        """
        # load /etc/logic.yaml
        conf_filename = os.path.join(self._get_etc_dir(), 'logic') 
        conf = shyaml.yaml_load_roundtrip(conf_filename)
        
        logger.info("set_config_section_key: section={}, key={}, value={}".format(section, key, str(value)))
        if value == None:
            del conf[section][key]
        else:
            conf[section][key] = value

        # save /etc/logic.yaml
        shyaml.yaml_save_roundtrip(conf_filename, conf, True)
        
        # activate visu_acl without reloading the logic
        if key == 'visu_acl':
            mylogic = self.return_logic(section)
            if mylogic is not None:
                logger.info(" - key={}, value={}".format(key, value))
#                if value is None:
#                    value = 'false'
                mylogic.visu_acl = str(value)

        return
Exemple #6
0
    def update(self, id=None):
        """
        Handle PUT requests
        """
        self.logger.info("ConfigController() update: config {}".format(id))
        if id in ['common', 'http', 'admin', 'mqtt', 'core']:

            # get http headers
            cl = cherrypy.request.headers.get('Content-Length', 0)
            if cl == 0:
                raise cherrypy.HTTPError(status=411)
            rawbody = cherrypy.request.body.read(int(cl))
            data = json.loads(rawbody.decode('utf-8'))
            self.logger.info("  - update: data = {}".format(data))

            # update holidays and remove keys from self.core_confdata
            self.update_holidays(data)

            # update etc/smarthome.yaml with data from admin frontend
            self.core_confdata = shyaml.yaml_load_roundtrip(os.path.join(self.etc_dir, 'smarthome.yaml'))
            self.update_configdict(self.core_confdata, data, 'common')
            shyaml.yaml_save_roundtrip(os.path.join(self.etc_dir, 'smarthome.yaml'), self.core_confdata, create_backup=True)

            # update etc/module.yaml with data from admin frontend
            self.module_confdata = shyaml.yaml_load_roundtrip(os.path.join(self.etc_dir, 'module.yaml'))
            self.update_configdict(self.module_confdata['http'], data, 'http')
            self.update_configdict(self.module_confdata['admin'], data, 'admin')

            if self.module_confdata.get('mqtt', None) is None:
                self.module_confdata['mqtt'] = {}
                self.module_confdata['mqtt']['module_name'] = 'mqtt'
            self.update_configdict(self.module_confdata['mqtt'], data, 'mqtt')
            self.logger.warning("Update: self.mqtt_conf = {}".format(self.mqtt_conf))
            if self.module_confdata['mqtt'].get('enabled', None) is None:
                self.module_confdata['mqtt']['enabled'] = False
            if self.module_confdata['mqtt']['enabled']:
                self.module_confdata['mqtt'].pop('enabled', None)
            self.logger.warning("Update: ['mqtt'] = {}".format(self.module_confdata['mqtt']))
            self.logger.warning("Update: enabled = {}".format(self.module_confdata['mqtt'].get('enabled', None)))

            shyaml.yaml_save_roundtrip(os.path.join(self.etc_dir, 'module.yaml'), self.module_confdata, create_backup=True)

            result = {"result": "ok"}
            return json.dumps(result)

        result = {"result": "error"}
        return json.dumps(result)
    def delete_logic(self, name):
        """
        Deletes a complete logic
        
        The python code and the section from the configuration file /etc/logic.yaml are
        removed. If it is a blockly logic, the blockly code is removed too.
        
        If a code file is references by more than the logic that is being deleted, the code
        file will not be deleted. It will only be deleted when the last logic referencing
        this code file is being deleted.
        
        :param name: name of the logic
        :type name: str
        
        :return: True, if deletion fas successful
        :rtype: bool
        """
        logger.warning("delete_logic: This routineimplements the deletion of logic '{}' (still in testing)".format(name))
        
        # Logik entladen
        if self.is_logic_loaded(name):
            logger.warning("delete_logic: Logic '{}' unloaded".format(name))
            self.unload_logic( name)

        # load /etc/logic.yaml
        conf_filename = os.path.join(self._get_etc_dir(), 'logic') 
        conf = shyaml.yaml_load_roundtrip(conf_filename)

        section = conf.get(name, None)
        if section is None:
            logger.warning("delete_logic: Section '{}' not found in logic configuration.".format(name))
            return False

        filename = section.get('filename', None)
        if filename is None:
            logger.warning("delete_logic: Filename of logic is not defined in section '{}' of logic configuration.".format(name))
        else:
            count = self._count_filename_uses(conf, filename)
            blocklyname = os.path.join(self.get_logics_dir(), os.path.splitext(os.path.basename(filename))[0]+'.blockly')
            filename = os.path.join(self._logic_dir, filename)

            if count < 2:
                # Deletion of the parts of the logic
                if os.path.isfile(blocklyname):
                    os.remove(blocklyname)
                    logger.warning("delete_logic: Blockly-Logic file '{}' deleted".format(blocklyname))
                if os.path.isfile(filename):
                    os.remove(filename)
                    logger.warning("delete_logic: Logic file '{}' deleted".format(filename))
            else:
                logger.warning("delete_logic: Skipped deletion of logic file '{}' because it is used by {} other logic(s)".format(filename, count-1))
        
        del conf[name]
        logger.warning("delete_logic: Section '{}' from configuration deleted".format(name))
        
        # save /etc/logic.yaml
        shyaml.yaml_save_roundtrip(conf_filename, conf, True)
        return True
Exemple #8
0
    def update_holidays(self, data):
        filename = os.path.join(self.etc_dir, 'holidays.yaml')
        self.holidays_confdata = shyaml.yaml_load_roundtrip(filename)
        self.logger.info(
            "update_holidays: self.holidays_confdata = '{}'".format(
                self.holidays_confdata))
        self.logger.info(
            "update_holidays: data['common']['data'] = '{}'".format(
                data['common']['data']))

        if self.holidays_confdata.get('location', None) is None:
            self.holidays_confdata['location'] = {}

        self.holidays_confdata['location']['country'] = data['common']['data'][
            'holidays_country']
        self.holidays_confdata['location']['province'] = data['common'][
            'data']['holidays_province']
        self.holidays_confdata['location']['state'] = data['common']['data'][
            'holidays_state']
        del data['common']['data']['holidays_country']
        del data['common']['data']['holidays_province']
        del data['common']['data']['holidays_state']

        if self.holidays_confdata.get('custom', None) is None:
            self.holidays_confdata['custom'] = []

        try:
            if len(self.holidays_confdata['custom']) > 5:
                for i in range(1, 6):
                    custom = data['common']['data']['holidays_custom' + str(i)]
                    if custom is not None and custom != '':
                        self.holidays_confdata['custom'][i - 1] = custom
            else:
                self.holidays_confdata['custom'] = []
                for i in range(1, 6):
                    custom = data['common']['data']['holidays_custom' + str(i)]
                    if custom is not None and custom != '':
                        self.holidays_confdata['custom'].append(custom)

            for i in range(1, 6):
                del data['common']['data']['holidays_custom' + str(i)]
        except Exception as e:
            self.logger.critical("update_holidays: Exception {}".format(e))

        if self.holidays_confdata['custom'] == []:
            #self.holidays_confdata['custom'] = None
            del self.holidays_confdata['custom']

        if self.holidays_confdata['location']['state'] is None:
            del self.holidays_confdata['location']['state']

        self.logger.info(
            "update_holidays: self.holidays_confdata = '{}'".format(
                self.holidays_confdata))
        shyaml.yaml_save_roundtrip(filename,
                                   self.holidays_confdata,
                                   create_backup=True)
        return
Exemple #9
0
    def delete_logic(self, name):
        """
        Deletes a complete logic
        
        The python code and the section from the configuration file /etc/logic.yaml are
        removed. If it is a blockly logic, the blockly code is removed too.
        
        If a code file is references by more than the logic that is being deleted, the code
        file will not be deleted. It will only be deleted when the last logic referencing
        this code file is being deleted.
        
        :param name: name of the logic
        :type name: str
        
        :return: True, if deletion fas successful
        :rtype: bool
        """
        logger.warning("delete_logic: This routineimplements the deletion of logic '{}' (still in testing)".format(name))
        
        # Logik entladen
        if self.is_logic_loaded(name):
            logger.warning("delete_logic: Logic '{}' unloaded".format(name))
            self.unload_logic( name)

        # load /etc/logic.yaml
        conf_filename = os.path.join(self._get_etc_dir(), 'logic') 
        conf = shyaml.yaml_load_roundtrip(conf_filename)

        section = conf.get(name, None)
        if section is None:
            logger.warning("delete_logic: Section '{}' not found in logic configuration.".format(name))
            return False

        filename = section.get('filename', None)
        if filename is None:
            logger.warning("delete_logic: Filename of logic is not defined in section '{}' of logic configuration.".format(name))
        else:
            count = self._count_filename_uses(conf, filename)
            blocklyname = os.path.join(self.get_logics_dir(), os.path.splitext(os.path.basename(filename))[0]+'.blockly')
            filename = os.path.join(self._logic_dir, filename)

            if count < 2:
                # Deletion of the parts of the logic
                if os.path.isfile(blocklyname):
                    os.remove(blocklyname)
                    logger.warning("delete_logic: Blockly-Logic file '{}' deleted".format(blocklyname))
                if os.path.isfile(filename):
                    os.remove(filename)
                    logger.warning("delete_logic: Logic file '{}' deleted".format(filename))
            else:
                logger.warning("delete_logic: Skipped deletion of logic file '{}' because it is used by {} other logic(s)".format(filename, count-1))
        
        del conf[name]
        logger.warning("delete_logic: Section '{}' from configuration deleted".format(name))
        
        # save /etc/logic.yaml
        shyaml.yaml_save_roundtrip(conf_filename, conf, True)
        return True
Exemple #10
0
    def update(self, id=None):
        """
        Handle PUT requests
        """
        self.logger.info("ConfigController() update: config {}".format(id))
        if id in ['common', 'http', 'admin', 'core']:

            # get http headers
            cl = cherrypy.request.headers.get('Content-Length', 0)
            if cl == 0:
                raise cherrypy.HTTPError(status=411)
            rawbody = cherrypy.request.body.read(int(cl))
            data = json.loads(rawbody.decode('utf-8'))
            self.logger.info("  - update: data = {}".format(data))

            # update etc/smarthome.yaml with data from admin frontend
            self.core_confdata = shyaml.yaml_load_roundtrip(
                os.path.join(self.etc_dir, 'smarthome.yaml'))
            self.update_configdict(self.core_confdata, data, 'common')
            shyaml.yaml_save_roundtrip(os.path.join(self.etc_dir,
                                                    'smarthome.yaml'),
                                       self.core_confdata,
                                       create_backup=True)

            # update etc/module.yaml with data from admin frontend
            self.module_confdata = shyaml.yaml_load_roundtrip(
                os.path.join(self.etc_dir, 'module.yaml'))
            self.update_configdict(self.module_confdata['http'], data, 'http')
            self.update_configdict(self.module_confdata['admin'], data,
                                   'admin')
            shyaml.yaml_save_roundtrip(os.path.join(self.etc_dir,
                                                    'module.yaml'),
                                       self.module_confdata,
                                       create_backup=True)

            result = {"result": "ok"}
            return json.dumps(result)

        result = {"result": "error"}
        return json.dumps(result)
Exemple #11
0
    def return_logictype(self, name):
        """
        Returns the type of a specified logic (Python, Blockly, None)

        :param name: Name of the logic (name of the configuration section)
        :type name: str

        :return: Logic type ('Python', 'Blockly' or None)
        :rtype: str or None
        """

        logic_type = 'None'
        filename = ''
        if name in self._userlogics:
            try:
                filename = self._userlogics[name].get('filename', '')
            except:
                logger.warning(
                    "return_logictype: self._userlogics[name] = '{}'".format(
                        str(self._userlogics[name])))
                logger.warning(
                    "return_logictype: self._userlogics = '{}'".format(
                        str(self._userlogics)))
        elif name in self._systemlogics:
            filename = self._systemlogics[name].get('filename', '')
            logic_type = 'Python'
        else:
            logger.info("return_logictype: name {} is not loaded".format(name))
            # load /etc/logic.yaml if logic is not in the loaded logics
            conf_filename = os.path.join(self._get_etc_dir(), 'logic')
            config = shyaml.yaml_load_roundtrip(conf_filename)
            if config is not None:
                if name in config:
                    filename = config[name].get('filename', '')

        if filename != '':
            blocklyname = os.path.splitext(
                os.path.basename(filename))[0] + '.blockly'
            if os.path.isfile(os.path.join(self.get_logics_dir(), filename)):
                logic_type = 'Python'
                if os.path.isfile(
                        os.path.join(self.get_logics_dir(), blocklyname)):
                    logic_type = 'Blockly'

        logger.debug(
            "return_logictype: name '{}', filename '{}', logic_type '{}'".
            format(name, filename, logic_type))
        return logic_type
Exemple #12
0
    def load_logging_config_for_edit(self):
        """
        Load config from logging.yaml to a dict

        If logging.yaml does not contain a 'shng_version' key, a backup is created
        """
        conf_filename = os.path.join(self.etc_dir, 'logging')
        self.logging_config = shyaml.yaml_load_roundtrip(conf_filename)
        self.logger.warning("load_logging_config: shng_version={}".format(
            self.logging_config.get('shng_version', None)))

        if self.logging_config.get('shng_version', None) is None:
            self.create_backupfile(conf_filename)
            self.logging_config['shng_version'] = 'x'
            self.save_logging_config()

        return
Exemple #13
0
    def return_defined_logics(self, withtype=False):
        """
        Returns the names of defined logics from file /etc/logic.yaml as a list

        If ``withtype`` is specified and set to True, the function returns a dict with names and
        logictypes ('Python', 'Blockly')

        :param withtype: If specified and set to True, the function will additionally return the logic types
        :type withtype: bool

        :return: list of defined logics or dict of defined logics with type
        :rtype: list or dict
        """
        if withtype:
            logic_list = {}
        else:
            logic_list = []

        # load /etc/logic.yaml
        conf_filename = os.path.join(self._get_etc_dir(), 'logic')
        config = shyaml.yaml_load_roundtrip(conf_filename)

        if config is not None:
            for section in config:
                logic_dict = {}
                filename = config[section]['filename']
                blocklyname = os.path.splitext(
                    os.path.basename(filename))[0] + '.xml'
                logic_type = 'None'
                if os.path.isfile(os.path.join(self.get_logics_dir(),
                                               filename)):
                    logic_type = 'Python'
                    if os.path.isfile(
                            os.path.join(self.get_logics_dir(), blocklyname)):
                        logic_type = 'Blockly'
                logger.debug(
                    "return_defined_logics: section '{}', logic_type '{}'".
                    format(section, logic_type))

                if withtype:
                    logic_list[section] = logic_type
                else:
                    logic_list.append(section)

        return logic_list
Exemple #14
0
    def save_logic_parameters(self, logicname):
        params = self.get_body()
        self.logger.info(
            "LogicsController.save_logic_parameters: logic = {}, params = {}".
            format(logicname, params))

        config_filename = os.path.join(self.etc_dir, 'logic')
        logic_conf = shyaml.yaml_load_roundtrip(config_filename)
        sect = logic_conf.get(logicname)
        if sect is None:
            response = {
                'result':
                'error',
                'description':
                "Configuration section '{}' does not exist".format(logicname)
            }
        else:
            self.logger.info(
                "LogicsController.save_logic_parameters: logic = {}, alte params = {}"
                .format(logicname, dict(sect)))
            for param, value in params.items():
                if value == None:
                    sect.pop(param, None)
                else:
                    self.logger.info(
                        "- param = {}, value = {}, type(value) = {}".format(
                            param, value, Utils.get_type(value)))
                    if (Utils.get_type(value) == 'str') and (value == ''):
                        sect.pop(param, None)
                    elif (Utils.get_type(value) == 'list') and (value == []):
                        sect.pop(param, None)
                    elif (Utils.get_type(value) == 'dict') and (value == {}):
                        sect.pop(param, None)
                    else:
                        sect[param] = value

            self.logger.info(
                "LogicsController.save_logic_parameters: logic = {}, neue params = {}"
                .format(logicname, dict(sect)))

            shyaml.yaml_save_roundtrip(config_filename, logic_conf, False)
            response = {'result': 'ok'}

        return json.dumps(response)
Exemple #15
0
    def delete(self, id=None):
        self.logger.info("PluginController(): delete('{}')".format(id))

        config_filename = self.get_config_filename()

        if self.test_for_old_config(config_filename):
            # make it 'readonly', if plugin.conf is used
            response = {'result': 'error', 'description': 'Updateing .CONF files is not supported'}
        else:
            response = {}
            plugin_conf = shyaml.yaml_load_roundtrip(config_filename)
            sect = plugin_conf.pop(id, None)
            if sect is None:
                response = {'result': 'error', 'description': "Configuration section '{}' does not exist".format(id)}
            else:
                shyaml.yaml_save_roundtrip(config_filename, plugin_conf, False)
                response = {'result': 'ok'}

        self.logger.info("PluginController(): delete(): response = {}".format(response))
        return json.dumps(response)
Exemple #16
0
    def return_defined_logics(self, withtype=False):
        """
        Returns the names of defined logics from file /etc/logic.yaml as a list
        
        If ``withtype`` is specified and set to True, the function returns a dict with names and
        logictypes ('Python', 'Blockly')

        :param withtype: If specified and set to True, the function will additionally return the logic types
        :type withtype: bool
        
        :return: list of defined logics or dict of defined logics with type
        :rtype: list or dict
        """
        if withtype:
            logic_list = {}
        else:
            logic_list = []
        
        # load /etc/logic.yaml
        conf_filename = os.path.join(self._get_etc_dir(), 'logic') 
        config = shyaml.yaml_load_roundtrip(conf_filename)

        if config is not None:
            for section in config:
                logic_dict = {}
                filename = config[section]['filename']
                blocklyname = os.path.splitext(os.path.basename(filename))[0]+'.xml'
                logic_type = 'None'
                if os.path.isfile(os.path.join(self.get_logics_dir(), filename)):
                    logic_type = 'Python'
                    if os.path.isfile(os.path.join(self.get_logics_dir(), blocklyname)):
                        logic_type = 'Blockly'
                logger.debug("return_defined_logics: section '{}', logic_type '{}'".format(section, logic_type))
            
                if withtype:
                    logic_list[section] = logic_type
                else:
                    logic_list.append(section)

        return logic_list
Exemple #17
0
    def return_logictype(self, name):
        """
        Returns the type of a specified logic (Python, Blockly, None)
        
        :param name: Name of the logic (name of the configuration section)
        :type name: str
        
        :return: Logic type ('Python', 'Blockly' or None)
        :rtype: str or None
        """

        logic_type = 'None'
        filename = ''
        if name in self._userlogics:
            try:
                filename = self._userlogics[name].get('filename', '')
            except:
                logger.warning("return_logictype: self._userlogics[name] = '{}'".format(str(self._userlogics[name])))
                logger.warning("return_logictype: self._userlogics = '{}'".format(str(self._userlogics)))
        elif name in self._systemlogics:
            filename = self._systemlogics[name].get('filename', '')
            logic_type = 'Python'
        else:
            logger.info("return_logictype: name {} is not loaded".format(name))
            # load /etc/logic.yaml if logic is not in the loaded logics
            conf_filename = os.path.join(self._get_etc_dir(), 'logic') 
            config = shyaml.yaml_load_roundtrip(conf_filename)
            if config is not None:
                if name in config:
                    filename = config[name].get('filename', '')

        if filename != '':
            blocklyname = os.path.splitext(os.path.basename(filename))[0]+'.blockly'
            if os.path.isfile(os.path.join(self.get_logics_dir(), filename)):
                logic_type = 'Python'
                if os.path.isfile(os.path.join(self.get_logics_dir(), blocklyname)):
                    logic_type = 'Blockly'
                    
        logger.debug("return_logictype: name '{}', filename '{}', logic_type '{}'".format(name, filename, logic_type))
        return logic_type
Exemple #18
0
    def update_config_section(self, param_dict):
        """
        Update the config section of ../etc/plugin.yaml

        :param param_dict: dict with the pareters that should be updated

        :return:
        """
        param_names = list(self.metadata.parameters.keys())
        self.logger.debug("update_config_section: Beginning to update section '{}' of ../etc/plugin.yaml".format(self._configname))
        self.logger.debug("update_config_section: valid parameter names to update = {}".format(param_names))
        self.logger.info("update_config_section: Config file = '{}', update data = {}".format(self._configfilename, param_dict))

        # read plugin.yaml
        plugin_conf = shyaml.yaml_load_roundtrip(self._configfilename)
        sect = plugin_conf.get(self._configname)
        if sect is None:
            self.logger.error("update_config_section: Config section '{}' not found in ../etc/plugin.yaml".format(self._configname))
            return

        parameters_changed = False
        for param in param_dict:
            if param in param_names:
                self.logger.info("update_config_section: Changing Parameter '{}' -> type = '{}' from '{}' to '{}'".format(param, self.metadata.parameters[param]['type'], sect.get(param, None), param_dict[param]))
                if param_dict[param] == '' or param_dict[param] == {} or param_dict[param] == []:
                    del sect[param]
                else:
                    sect[param] = param_dict[param]
                parameters_changed = True
            else:
                self.logger.error("update_config_section: Invalid parameter '{}' specified for update".format(param, param_dict[param]))

        self.logger.debug("update_config_section: Config section content = '{}'".format(sect))
        # write plugin.yaml
        if parameters_changed:
            shyaml.yaml_save_roundtrip(self._configfilename, plugin_conf, True)
        self.logger.debug("update_config_section: Finished updating section '{}' of ../etc/plugin.yaml".format(self._configname))
        return
Exemple #19
0
    def update(self, id='', action=''):
        self.logger.info("PluginController.update(id='{}', action='{}')".format(id, action))

        if action == '':
            # Update section for plugin in etc/plugin.yaml
            params = self.get_body()
            if params is None:
                self.logger.warning("PluginController.update(): section '{}': Bad, add request".format(id))
                raise cherrypy.HTTPError(status=411)
            self.logger.info("PluginController.update(): section '{}' = {}".format(id, params))

            config_filename = self.get_config_filename()

            if self.test_for_old_config(config_filename):
                # make it 'readonly', if plugin.conf is used
                response = {'result': 'error', 'description': 'Updateing .CONF files is not supported'}
            else:
                response = {}
                plugin_conf = shyaml.yaml_load_roundtrip(config_filename)
                sect = plugin_conf.get(id)
                if sect is None:
                    response = {'result': 'error', 'description': "Configuration section '{}' does not exist".format(id)}
                else:
                    self.logger.debug("update: params = {}".format(params))
                    if params.get('config', {}).get('plugin_enabled', None) == True:
                        del params['config']['plugin_enabled']
                    plugin_conf[id] = params.get('config', {})
                    shyaml.yaml_save_roundtrip(config_filename, plugin_conf, False)
                    response = {'result': 'ok'}
        elif action in ['start','stop']:
            response = self.handle_plugin_action(id, action)
        else:
            response = {'result': 'error', 'description': "Plugin '{}': unknown action '{}'".format(id, action)}
            self.logger.warning("PluginController.update(): " + response['description'])

        self.logger.info("PluginController.update(): response = {}".format(response))
        return json.dumps(response)
Exemple #20
0
    def update_config_section(self, active, section, config_list):
        """
        Update file /etc/logic.yaml

        This method creates/updates a section in /etc/logic.yaml. If the section exist, it is cleared
        before new configuration imformation is written to the section

        :param active: True: logic is/should be active, False: Triggers are not written to /etc/logic.yaml
        :param section: name of section to configure in logics configurationfile
        :param config_list: list of configuration entries. Each entry of this list is a list with three string entries: ['key', 'value', 'comment']
        :type active: bool
        :type section: str
        :type config_list: list of lists
        """
        if section == '':
            logger.error(
                "update_config_section: No section name specified. Not updatind logics configuration."
            )
            return False

        if self.return_config_type() != YAML_FILE:
            logger.error(
                "update_config_section: Editing of configuration only possible with new (yaml) config format"
            )
            return False

        # load /etc/logic.yaml
        conf_filename = os.path.join(self._get_etc_dir(), 'logic')
        conf = shyaml.yaml_load_roundtrip(conf_filename)
        if conf is None:
            conf = shyaml.get_emptynode()

        # empty section
        if conf.get(section, None) == None:
            conf[section] = shyaml.get_emptynode()
        if conf[section].get('filename', None) != None:
            del conf[section]['filename']
        if conf[section].get('cycle', None) != None:
            del conf[section]['cycle']
        if conf[section].get('crontab', None) != None:
            del conf[section]['crontab']
        if conf[section].get('watch_item', None) != None:
            del conf[section]['watch_item']

        # add entries to section
        logger.info("update_config_section: section {}".format(section))
        for c in config_list:
            # process config entries
            key = c[0].strip()
            value = c[1]
            comment = c[2]
            logger.info(" - key={}, value={}, comment={}".format(
                key, str(value), str(comment)))
            if isinstance(value, str):
                value = value.strip()
                comment = comment.strip()
                if value != '' and value[0] == '[' and value[-1] == ']':
                    # convert a list of triggers to list, if given as a string
                    value = ast.literal_eval(value)
                    if comment != '':
                        comment = ast.literal_eval(comment)
                else:
                    # process single trigger
                    if active or (key == 'filename'):
                        conf[section][key] = value
                        if comment != '':
                            conf[section].yaml_add_eol_comment(comment,
                                                               key,
                                                               column=50)
            elif isinstance(value, int) or isinstance(
                    value, bool) or isinstance(value, float):
                comment = comment.strip()
                # process single trigger
                if active:
                    conf[section][key] = value
                    if comment != '':
                        conf[section].yaml_add_eol_comment(comment,
                                                           key,
                                                           column=50)
            else:
                logger.warning(
                    "update_config_section: unsupported datatype for key '{}'".
                    format(key))

            if active:
                if isinstance(value, list):
                    # process a list of triggers
                    conf[section][key] = shyaml.get_commentedseq(value)
                    listvalue = True
                    for i in range(len(value)):
                        if comment != '':
                            if comment[i] != '':
                                conf[section][key].yaml_add_eol_comment(
                                    comment[i], i, column=50)

        if conf[section] == shyaml.get_emptynode():
            conf[section] = None
        shyaml.yaml_save_roundtrip(conf_filename, conf, True)
Exemple #21
0
    def update_config_section(self, active, section, config_list):
        """
        Update file /etc/logic.yaml
    
        This method creates/updates a section in /etc/logic.yaml. If the section exist, it is cleared
        before new configuration imformation is written to the section
    
        :param active: True: logic is/should be active, False: Triggers are not written to /etc/logic.yaml
        :param section: name of section to configure in logics configurationfile
        :param config_list: list of configuration entries. Each entry of this list is a list with three string entries: ['key', 'value', 'comment']
        :type active: bool
        :type section: str
        :type config_list: list of lists
        """
        if section == '':
            logger.error("update_config_section: No section name specified. Not updatind logics configuration.")
            return False
            
        if self.return_config_type() != YAML_FILE:
            logger.error("update_config_section: Editing of configuration only possible with new (yaml) config format")
            return False
                        
        # load /etc/logic.yaml
        conf_filename = os.path.join(self._get_etc_dir(), 'logic') 
        conf = shyaml.yaml_load_roundtrip(conf_filename)
        if conf is None:
            conf = shyaml.get_emptynode()
            
        # empty section
        if conf.get(section, None) == None:
            conf[section] = shyaml.get_emptynode()
        del conf[section]['filename']
        del conf[section]['cycle']
        del conf[section]['crontab']
        del conf[section]['watch_item']

        # add entries to section
        logger.info("update_config_section: section {}".format(section))
        for c in config_list:
            # process config entries
            key = c[0].strip()
            value = c[1]
            comment = c[2]
            logger.info(" - key={}, value={}, comment={}".format(key, str(value), str(comment)))
            if isinstance(value, str):
                value = value.strip()
                comment = comment.strip()
                if value != '' and value[0] == '[' and value[-1] == ']':
                    # convert a list of triggers to list, if given as a string
                    value = ast.literal_eval(value)
                    if comment != '':
                        comment = ast.literal_eval(comment)
                else:
                    # process single trigger
                    if active or (key == 'filename'):
                        conf[section][key] = value
                        if comment != '':
                            conf[section].yaml_add_eol_comment(comment, key, column=50)
            elif isinstance(value, int) or isinstance(value, bool) or isinstance(value, float):
                comment = comment.strip()
                # process single trigger
                if active:
                    conf[section][key] = value
                    if comment != '':
                        conf[section].yaml_add_eol_comment(comment, key, column=50)
            else:
                logger.warning("update_config_section: unsupported datatype for key '{}'".format(key))
                
            if active:
                if isinstance(value, list):
                    # process a list of triggers
                    conf[section][key] = shyaml.get_commentedseq(value)
                    listvalue = True
                    for i in range(len(value)):
                        if comment != '':
                            if comment[i] != '':
                                conf[section][key].yaml_add_eol_comment(comment[i], i, column=50)

        if conf[section] == shyaml.get_emptynode():
            conf[section] = None
        shyaml.yaml_save_roundtrip(conf_filename, conf, True)
Exemple #22
0
    def plugin_set_config_html(self, plugin_section='', config=''):
        """
        Is called by items.html when an item value has been changed

        plugin_set_config.html?plugin_section=' + pluginsection + '&config=' + configstr;
        """
        if config == '':
            self.logger.error("plugin_set_config_html: 'config' not specified")
            return 'false'
        if plugin_section == '':
            self.logger.error(
                "plugin_set_config_html: 'plugin_section' not specified")
            return 'false'

        self.logger.warning(
            "plugin_set_config_html: pluginconfig '{}' set to '{}'".format(
                plugin_section, config))

        # to do:
        # - load etc/plugin.yaml for round-trip
        config_filename = self.plugins._get_plugin_conf_filename()
        self.logger.warning(
            'Loading config_filename: {}'.format(config_filename))
        plugin_yaml = shyaml.yaml_load_roundtrip(config_filename)
        self.logger.warning('plugin_yaml: {}'.format(plugin_yaml))

        # - remove all entries of the section that don't start with plugin_ (all beside plugin_name)
        self.logger.warning('1: plugin_yaml[{}]: {}'.format(
            plugin_section, dict(plugin_yaml[plugin_section])))
        key_list = list(plugin_yaml[plugin_section].keys())
        for key in key_list:
            if key != 'plugin_name':
                del plugin_yaml[plugin_section][key]
        self.logger.warning('2: plugin_yaml[{}]: {}'.format(
            plugin_section, dict(plugin_yaml[plugin_section])))

        # - add all entries to the section which just were received from the admin backend
        self.logger.warning('- {}:'.format(plugin_section))
        config_dict = json.loads(config)

        # change class_path to plugin_name
        if 'class_path' in config_dict.keys():
            if config_dict['class_path'].startswith('plugins.'):
                plugin_yaml[plugin_section]['plugin_name'] = config_dict[
                    'class_path'][8:]
                del config_dict['class_path']

        # handle plugin_enabled
        if 'plugin_enabled' in config_dict.keys():
            if str(config_dict['plugin_enabled']).lower() == 'false':
                plugin_yaml[plugin_section]['plugin_enabled'] = False
            else:
                del config_dict['plugin_enabled']

        # save the rest of the parameters to plugin.yaml
        for key in config_dict:
            self.logger.warning('-     {}: {}'.format(key, config_dict[key]))
            plugin_yaml[plugin_section][key] = config_dict[key]
        self.logger.warning('3: plugin_yaml[{}]: {}'.format(
            plugin_section, dict(plugin_yaml[plugin_section])))

        # - save etc/plugin.yaml
        self.logger.warning(
            'Saving config_filename: {}'.format(config_filename))
        shyaml.yaml_save_roundtrip(config_filename,
                                   plugin_yaml,
                                   create_backup=True)
        # self.logger.warning("Config-Information not saved to etc/plugin.yaml")

        # item_data = []
        # item = self.items.return_item(item_path)
        # if 'num' in item.type():
        #     if "." in value or "," in value:
        #         value = float(value)
        #     else:
        #         value = int(value)
        # item(value, caller='admin')

        return '{"result": "true"}'