예제 #1
0
파일: scene.py 프로젝트: ThomasCr/smarthome
    def __init__(self, smarthome):
        self._sh = smarthome
        
        global _scenes_instance
        if _scenes_instance is not None:
            import inspect
            curframe = inspect.currentframe()
            calframe = inspect.getouterframes(curframe, 2)
            logger.critical("A second 'scenes' object has been created. There should only be ONE instance of class 'Scenes'!!! Called from: {} ({})".format(calframe[1][1], calframe[1][3]))

        _scenes_instance = self

        self.items = Items.get_instance()

        self._scenes = {}
        self._learned_values = {}
        self._scenes_dir = smarthome.base_dir + '/scenes/'
        if not os.path.isdir(self._scenes_dir):
            logger.warning("Directory scenes not found. Ignoring scenes.".format(self._scenes_dir))
            return

     #   for item in smarthome.return_items():
        for item in self.items.return_items():
            if item.type() == 'scene':
                scene_file = os.path.join(self._scenes_dir, item.id())

                scene_file_yaml = yaml.yaml_load(scene_file+'.yaml', ordered=False, ignore_notfound=True)
                if scene_file_yaml is not None:
                    # Reading yaml file with scene definition
                    for state in scene_file_yaml:
                        actions = scene_file_yaml[state]['actions']
                        if isinstance(actions, dict):
                            actions = [ actions ]
                        if isinstance( actions, list ):
                            for action in actions:
                                if isinstance(action, dict):
                                    self._add_scene_entry(item, str(state), 
                                                          action.get('item', ''), str(action.get('value', '')), 
                                                          action.get('learn', ''), scene_file_yaml[state].get('name', ''))
                                else:
                                    logger.warning("Scene {}, state {}: action '{}' is not a dict".format(item, state, action))
                        else:
                            logger.warning("Scene {}, state {}: actions are not a list".format(item, state))
                    self._load_learned_values(str(item.id()))
                else:
                    # Trying to read conf file with scene definition
                    scene_conf_file = scene_file + '.conf'
                    try:
                        with open(scene_conf_file, 'r', encoding='UTF-8') as f:
                            reader = csv.reader(f, delimiter=' ')
                            for row in reader:
                                if row == []:  # ignore empty lines
                                    continue
                                if row[0][0] == '#':  # ignore comments
                                    continue
                                self._add_scene_entry(item, row[0], row[1], row[2])
                    except Exception as e:
                        logger.warning("Problem reading scene file {0}: {1}".format(scene_file, e))
                        continue
                item.add_method_trigger(self._trigger)
예제 #2
0
    def __init__(self, webif_dir, plugin):
        """
        Initialization of instance of class WebInterface

        :param webif_dir: directory where the webinterface of the plugin resides
        :param plugin: instance of the plugin
        :type webif_dir: str
        :type plugin: object
        """
        self.logger = logging.getLogger(__name__)
        self.webif_dir = webif_dir
        self.plugin = plugin
        self.tplenv = self.init_template_environment()
        self.logger.debug("Plugin : Init Webif")
        self.items = Items.get_instance()
예제 #3
0
    def read(self, id=None):
        """
        Handle GET requests for scenes API
        """
        if self.items == None:
            self.items = Items.get_instance()

        from lib.userfunctions import reload
        from lib.userfunctions import reload_all

        get_param_func = getattr(Scenes, "get_instance", None)
        if callable(get_param_func):
            supported = True
            self.scenes = Scenes.get_instance()
            scene_list = []
            if self.scenes is not None:
                scene_list = self.scenes.get_loaded_scenes()

            disp_scene_list = []
            for scene in scene_list:
                scene_dict = {}
                scene_dict['path'] = scene
                #                scene_dict['name'] = str(self._sh.return_item(scene))
                scene_dict['name'] = str(self.items.return_item(scene))

                action_list = self.scenes.get_scene_actions(scene)
                scene_dict['value_list'] = action_list
                #                scene_dict[scene] = action_list

                disp_action_list = []
                for value in action_list:
                    action_dict = {}
                    action_dict['action'] = value
                    action_dict['action_name'] = self.scenes.get_scene_action_name(scene, value)
                    action_list = self.scenes.return_scene_value_actions(scene, value)
                    for action in action_list:
                        if not isinstance(action[0], str):
                            action[0] = action[0].id()
                    action_dict['action_list'] = action_list

                    disp_action_list.append(action_dict)
                scene_dict['values'] = disp_action_list
                self.logger.debug("scenes_html: disp_action_list for scene {} = {}".format(scene, disp_action_list))

                disp_scene_list.append(scene_dict)
        else:
            supported = False
        return json.dumps(disp_scene_list)
예제 #4
0
    def __init__(self, sh):
        """
        Initalizes the plugin.

        If the sh object is needed at all, the method self.get_sh() should be used to get it.
        There should be almost no need for a reference to the sh object any more.

        Plugins have to use the new way of getting parameter values:
        use the SmartPlugin method get_parameter_value(parameter_name). 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.
        """

        # Call init code of parent class (SmartPlugin)
        super().__init__()

        self.items = Items.get_instance()

        self.updates_allowed = self.get_parameter_value('update')
        self.ip = self.get_parameter_value('ip')
        self.port = self.get_parameter_value('port')
        self.hashed_password = self.get_parameter_value('hashed_password')
        if self.hashed_password is None or self.hashed_password == '':
            self.logger.warning(
                "CLI: You should set a password for this plugin.")
            self.hashed_password = None
        elif self.hashed_password.lower() == 'none':
            self.hashed_password = None
        elif not Utils.is_hash(self.hashed_password):
            self.logger.error(
                "CLI: Value given for 'hashed_password' is not a valid hash value. Login will not be possible"
            )

        name = 'plugins.' + self.get_fullname()
        self.server = Tcp_server(host=self.ip,
                                 port=self.port,
                                 name=name,
                                 mode=Tcp_server.MODE_TEXT_LINE)
        self.server.set_callbacks(incoming_connection=self.handle_connection)
        self.commands = CLICommands(self.get_sh(), self.updates_allowed, self)
        self.alive = False

        # On initialization error use:
        #   self._init_complete = False
        #   return

        # if plugin should start even without web interface
        self.init_webinterface(WebInterface)
예제 #5
0
    def read(self, id=None):
        """
        Handle GET requests
        """

        if self.items is None:
            self.items = Items.get_instance()

        items_sorted = sorted(self.items.return_items(),
                              key=lambda k: str.lower(k['_path']),
                              reverse=False)

        item_list = []
        for item in items_sorted:
            item_list.append(item._path)
        return json.dumps(item_list)
예제 #6
0
    def __init__(self, webif_dir, plugin):
        """
        Initialization of instance of class WebInterface

        :param webif_dir: directory where the webinterface of the plugin resides
        :param plugin: instance of the plugin
        :type webif_dir: str
        :type plugin: object
        """
        self.logger = plugin.logger
        self.webif_dir = webif_dir
        self.plugin = plugin
        self.tplenv = self.init_template_environment()
        self.tplenv.filters['dateformat'] = self.dateformat
        self.tplenv.filters['timeformat'] = self.timeformat
        self.items = Items.get_instance()
예제 #7
0
    def cachecheck(self):
        """
        returns a list of items as json structure
        """
        unused_cache_files = []

        if self._sh.shng_status['code'] == 20:
            # {'code': 20, 'text': 'Running'}
            cache_path = os.path.join(self.base_dir, 'var', 'cache')
            onlyfiles = [
                f for f in os.listdir(cache_path)
                if os.path.isfile(os.path.join(cache_path, f))
            ]

            for file in onlyfiles:
                if not file.find(".") == 0:  # filter .gitignore etc.
                    self.items = Items.get_instance()
                    item = self.items.return_item(file)
                    no_cache_file = False
                    if item is None:
                        self.logger.debug(
                            "cachecheck: no item {}".format(file))
                        no_cache_file = True
                    elif not item._cache:
                        self.logger.debug(
                            "cachecheck: item {}, no _cache".format(file))
                        no_cache_file = True

                    if no_cache_file:
                        file_data = {}
                        file_data[
                            'last_modified'] = datetime.datetime.fromtimestamp(
                                int(
                                    os.path.getmtime(
                                        os.path.join(cache_path,
                                                     file)))).strftime(
                                                         '%Y-%m-%d %H:%M:%S')
                        file_data['created'] = datetime.datetime.fromtimestamp(
                            int(
                                os.path.getctime(os.path.join(
                                    cache_path,
                                    file)))).strftime('%Y-%m-%d %H:%M:%S')
                        file_data['filename'] = file
                        file_data['filename'] = file
                        unused_cache_files.append(file_data)

        return json.dumps(unused_cache_files)
예제 #8
0
    def __init__(self, plugin_instance, visu_definition=None):
        self.items = Items.get_instance()

        self.plugin_instance = plugin_instance
        self.logger = plugin_instance.logger
        self._sh = plugin_instance._sh

        self.smartvisu_dir = plugin_instance.smartvisu_dir
        self.smartvisu_version = plugin_instance.smartvisu_version
        self.overwrite_templates = plugin_instance.overwrite_templates
        self.visu_style = plugin_instance.visu_style.lower()
        if not self.visu_style in ['std', 'blk']:
            self.visu_style = 'std'
            self.logger.warning(
                "SmartVisuGenerator: visu_style '{}' unknown, using visu_style '{1}'"
                .format(plugin_instance.visu_style, self.visu_style))
        self.list_deprecated_warnings = plugin_instance.list_deprecated_warnings

        self.logger.info("Generating pages for smartVISU v{}".format(
            self.smartvisu_version))

        self.thisplg_dir = os.path.dirname(os.path.abspath(__file__))
        self.shng_tpldir = os.path.join(self.thisplg_dir, 'tplNG')

        self.sv_tpldir = os.path.join(self.smartvisu_dir, 'pages', '_template')
        self.gen_tpldir = os.path.join(self.smartvisu_dir, 'pages', 'base',
                                       'tplNG')
        if self.smartvisu_version >= '2.9':
            self.gen_tpldir = os.path.join(self.smartvisu_dir, 'dropins')

        self.tmpdir = os.path.join(self.smartvisu_dir, 'temp')
        self.pages_dir = os.path.join(self.smartvisu_dir, 'pages', 'smarthome')

        self.copy_templates()

        self.navigation = {
            'room': [],
            'category': [],
            'room_lite': []
        }  # dict of list of dicts
        if visu_definition is not None:
            self.initialize_visu_navigation(
                visu_definition.get('navigation', None))

        self.pages()
        self.logger.info("Generating pages for smartVISU v{} End".format(
            self.smartvisu_version))
예제 #9
0
    def __init__(self, sh):
        """
        Initalizes the plugin. The parameters describe for this method are pulled from the entry in plugin.conf.

        :param sh:  **Deprecated**: The instance of the smarthome object. For SmartHomeNG versions 1.4 and up: **Don't use it**!
        :param *args: **Deprecated**: Old way of passing parameter values. For SmartHomeNG versions 1.4 and up: **Don't use it**!
        :param **kwargs:**Deprecated**: Old way of passing parameter values. For SmartHomeNG versions 1.4 and up: **Don't use it**!
        """

        # Call init code of parent class (SmartPlugin)
        super().__init__()

        from bin.smarthome import VERSION
        if '.'.join(VERSION.split('.', 2)[:2]) <= '1.5':
            self.logger = logging.getLogger(__name__)

        self.logger.debug("rtr: init method called")

        self.alive = None
        sh = self.get_sh()
        self.path = sh.base_dir + '/var/rtr/timer/'
        self._items = Items.get_instance()

        # preset the controller defaults
        self._defaults['Tlast'] = time.time()
        self._defaults['Kp'] = self.get_parameter_value('default_Kp')
        self._defaults['Ki'] = self.get_parameter_value('default_Ki')
        self._defaults['tempBoostTime'] = self.get_parameter_value(
            'defaultBoostTime')
        self._defaults['valveProtect'] = self.get_parameter_value(
            'defaultValveProtect')
        self._cycle_time = self.get_parameter_value('cycle_time')
        self._defaultOnExpiredTimer = self.get_parameter_value(
            'defaultOnExpiredTimer')

        # On initialization error use:
        #   self._init_complete = False
        #   return

        # if plugin should start even without web interface
        self.init_webinterface(WebInterface)
        # if plugin should not start without web interface
        # if not self.init_webinterface():
        #     self._init_complete = False

        return
예제 #10
0
    def __init__(self, sh, *args, **kwargs):
        self.logger = logging.getLogger(__name__)
        self.logger.info('Init Simulation release %s' % self.PLUGIN_VERSION)
        self.shtime = Shtime.get_instance()
        self._datafile = self.get_parameter_value('data_file')
        self.lastday = ''
        self.items = Items.get_instance()
        self.scheduler = Scheduler.get_instance()
        if len(self.get_parameter_value('callers')) == 0:
            self._callers = None
        else:
            self._callers = self.get_parameter_value('callers')
        self._items = []
        self.scheduler_add('midnight', self._midnight, cron='0 0 * *', prio=3)

        if not self.init_webinterface():
            self._init_complete = False
예제 #11
0
파일: scene.py 프로젝트: stoepf/smarthome
    def __init__(self, smarthome):
        self._sh = smarthome

        global _scenes_instance
        if _scenes_instance is not None:
            import inspect
            curframe = inspect.currentframe()
            calframe = inspect.getouterframes(curframe, 2)
            logger.critical(translate("A second 'scenes' object has been created. There should only be ONE instance of class 'Scenes'!!! Called from: {frame1} ({frame2})", {'frame1': calframe[1][1], 'frame2': calframe[1][3]}))

        _scenes_instance = self

        self.items = Items.get_instance()
        self.logics = Logics.get_instance()

        self._load_scenes()
        return
예제 #12
0
    def __init__(self, sh):
        super().__init__()
        StateEngineDefaults.logger = self.logger
        self.itemsApi = Items.get_instance()
        self.__items = self.abitems = {}
        self.mod_http = None
        self.__sh = sh
        self.alive = False
        self.__cli = None
        self.init_webinterface(WebInterface)
        self.__log_directory = self.get_parameter_value("log_directory")
        try:
            log_level = self.get_parameter_value("log_level")
            StateEngineDefaults.log_level = log_level
            log_directory = self.__log_directory
            self.logger.info("Init StateEngine (log_level={0}, log_directory={1})".format(log_level, log_directory))

            StateEngineDefaults.startup_delay = self.get_parameter_value("startup_delay_default")
            StateEngineDefaults.suspend_time = self.get_parameter_value("suspend_time_default")
            StateEngineDefaults.instant_leaveaction = self.get_parameter_value("instant_leaveaction")
            StateEngineDefaults.suntracking_offset = self.get_parameter_value("lamella_offset")
            StateEngineDefaults.lamella_open_value = self.get_parameter_value("lamella_open_value")
            StateEngineDefaults.write_to_log(self.logger)
            self.get_sh().stateengine_plugin_functions = StateEngineFunctions.SeFunctions(self.get_sh(), self.logger)
            StateEngineCurrent.init(self.get_sh())

            base = self.get_sh().get_basedir()
            log_directory = SeLogger.create_logdirectory(base, log_directory)

            if log_level > 0:
                text = "StateEngine extended logging is active. Logging to '{0}' with log level {1}."
                self.logger.info(text.format(log_directory, log_level))
            log_maxage = self.get_parameter_value("log_maxage")
            if log_maxage > 0:
                self.logger.info("StateEngine extended log files will be deleted after {0} days.".format(log_maxage))
                SeLogger.set_logmaxage(log_maxage)
                cron = ['init', '30 0 * *']
                self.scheduler_add('StateEngine: Remove old logfiles', SeLogger.remove_old_logfiles, cron=cron, offset=0)
            SeLogger.set_loglevel(log_level)
            SeLogger.set_logdirectory(log_directory)

        except Exception as ex:
            self._init_complete = False
            self.logger.warning("Problem loading Stateengine plugin: {}".format(ex))
            return
예제 #13
0
    def __init__(self, smarthome):
        threading.Thread.__init__(self, name='Scheduler')
        logger.info('Init Scheduler')
        self._sh = smarthome
        self._lock = threading.Lock()
        self._runc = threading.Condition()
        
        global _scheduler_instance
        if _scheduler_instance is not None:
            import inspect
            curframe = inspect.currentframe()
            calframe = inspect.getouterframes(curframe, 4)
            logger.critical("A second 'scheduler' object has been created. There should only be ONE instance of class 'Scheduler'!!! Called from: {} ({})".format(calframe[1][1], calframe[1][3]))

        _scheduler_instance = self
        
        self.shtime = Shtime.get_instance()
        self.items = Items.get_instance()
예제 #14
0
    def __init__(self, sh):

        if '.'.join(VERSION.split('.', 2)[:2]) <= '1.5':
            self.logger = logging.getLogger(__name__)
        self.items = Items.get_instance()
        self.__items = self.abitems = {}
        self.__sh = sh
        self.alive = False
        self.__cli = None
        self.init_webinterface()
        try:
            log_level = self.get_parameter_value("log_level")
            log_directory = self.get_parameter_value("log_directory")
            self.logger.info("Init StateEngine (log_level={0}, log_directory={1})".format(log_level, log_directory))

            StateEngineDefaults.startup_delay = self.get_parameter_value("startup_delay_default")
            StateEngineDefaults.suspend_time = self.get_parameter_value("suspend_time_default")
            StateEngineDefaults.instant_leaveaction = self.get_parameter_value("instant_leaveaction")
            StateEngineDefaults.write_to_log(self.logger)

            StateEngineCurrent.init(self.get_sh())

            if log_level > 0:
                if log_directory[0] != "/":
                    base = self.get_sh().get_basedir()
                    if base[-1] != "/":
                        base += "/"
                    log_directory = base + log_directory
                if not os.path.exists(log_directory):
                    os.makedirs(log_directory)
                text = "StateEngine extended logging is active. Logging to '{0}' with loglevel {1}."
                self.logger.info(text.format(log_directory, log_level))
            log_maxage = self.get_parameter_value("log_maxage")
            if log_level > 0 and log_maxage > 0:
                self.logger.info("StateEngine extended log files will be deleted after {0} days.".format(log_maxage))
                SeLogger.set_logmaxage(log_maxage)
                cron = ['init', '30 0 * *']
                self.scheduler_add('StateEngine: Remove old logfiles', SeLogger.remove_old_logfiles, cron=cron, offset=0)
            SeLogger.set_loglevel(log_level)
            SeLogger.set_logdirectory(log_directory)
            self.get_sh().stateengine_plugin_functions = StateEngineFunctions.SeFunctions(self.get_sh(), self.logger)
        except Exception:
            self._init_complete = False
            return
예제 #15
0
 def __init__(self, abitem, name: str):
     super().__init__(abitem)
     self._se_plugin = abitem.se_plugin
     self._parent = self._abitem.id
     self._caller = StateEngineDefaults.plugin_identification
     self.shtime = Shtime.get_instance()
     self.itemsApi = Items.get_instance()
     self._name = name
     self.__delay = StateEngineValue.SeValue(self._abitem, "delay")
     self.__repeat = None
     self.__instanteval = None
     self.conditionset = StateEngineValue.SeValue(self._abitem, "conditionset", True, "str")
     self.__mode = StateEngineValue.SeValue(self._abitem, "mode", True, "str")
     self.__order = StateEngineValue.SeValue(self._abitem, "order", False, "num")
     self._scheduler_name = None
     self.__function = None
     self.__template = None
     self._state = None
     self.__queue = abitem.queue
예제 #16
0
    def __init__(self, sh, *args, **kwargs):
        # Call init code of parent class (SmartPlugin or MqttPlugin)
        super().__init__()

        self.shtime = Shtime.get_instance()
        self.items = Items.get_instance()
        # driver, connect, prefix="", cycle=60, precision=2
        self._dump_cycle = self.get_parameter_value('cycle')
        self._precision = self.get_parameter_value('precision')
        self._name = self.get_instance_name()
        self._replace = {
            table: table if (self.get_parameter_value('prefix') == ""
                             or self.get_parameter_value('prefix') is None)
            else self.get_parameter_value('prefix') + "_" + table
            for table in ["log", "item"]
        }
        self._replace['item_columns'] = ", ".join(COL_ITEM)
        self._replace['log_columns'] = ", ".join(COL_LOG)
        self._buffer = {}
        self._buffer_lock = threading.Lock()
        self._dump_lock = threading.Lock()

        self._db = lib.db.Database(
            ("" if (self.get_parameter_value('prefix') == ""
                    or self.get_parameter_value('prefix') is None) else
             self.get_parameter_value('prefix').capitalize() + "_") +
            "Database", self.get_parameter_value('driver'),
            Utils.string_to_list(self.get_parameter_value('connect')))
        self._initialized = False
        self._initialize()

        self.scheduler_add(
            'Database dump ' + self._name +
            ("" if (self.get_parameter_value('prefix') == ""
                    or self.get_parameter_value('prefix') is None) else " [" +
             self.get_parameter_value('prefix') + "]"),
            self._dump,
            cycle=self._dump_cycle,
            prio=5)

        self.init_webinterface()
        return
예제 #17
0
    def read(self, id=None):
        """
        Handle GET requests
        """

        if self.items is None:
            self.items = Items.get_instance()

        if id == 'structs':
            # /api/items/structs
            self.logger.info(
                "ItemsController.root(): item_name = {}".format(id))
            result = self.items.return_struct_definitions(all=False)
            return json.dumps(result)

            #raise cherrypy.NotFound
            #self.logger.info("LogController (GET): logfiles = {}".format(logs))
            #return json.dumps({'logs':logs, 'default': self.root_logname})

        return None
예제 #18
0
    def __init__(self, smarthome):
        threading.Thread.__init__(self, name='Scheduler')
        logger.info('Init Scheduler')
        self._sh = smarthome
        self._lock = threading.Lock()
        self._runc = threading.Condition()

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

        _scheduler_instance = self

        self.shtime = Shtime.get_instance()
        self.items = Items.get_instance()
        self.crontabs = TriggerTimes.get_instance()
        self.mqtt = None
예제 #19
0
    def item_change_value_html(self, item_path, value):
        """
        Is called by items.html when an item value has been changed
        """
        if self.items is None:
            self.items = Items.get_instance()
        self.logger.info("item_change_value_html: item '{}' set to value '{}'".format(item_path, value))
        item_data = []
        try:
            item = self.items.return_item(item_path)
        except Exception as e:
            self.logger.error("item_change_value_html: item '{}' set to value '{}' - Exception {}".format(item_path, value, e))
            return
        if 'num' in item.type():
            if "." in value or "," in value:
                value = float(value)
            else:
                value = int(value)
        item(value, caller='admin')

        return
예제 #20
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)
예제 #21
0
    def __init__(self,
                 smarthome,
                 update='False',
                 ip='127.0.0.1',
                 port=2323,
                 hashed_password=''):
        """
        Constructor
        :param smarthome: smarthomeNG instance
        :param update: Flag: Updates allowed
        :param ip: IP to bind on
        :param port: Port to bind on
        :param hashed_password: Hashed password that is required to logon
        """
        self.logger = logging.getLogger(__name__)

        self.items = Items.get_instance()

        if hashed_password is None or hashed_password == '':
            self.logger.warning(
                "CLI: You should set a password for this plugin.")
            hashed_password = None
        elif hashed_password.lower() == 'none':
            hashed_password = None
        elif not Utils.is_hash(hashed_password):
            self.logger.error(
                "CLI: Value given for 'hashed_password' is not a valid hash value. Login will not be possible"
            )

        self.server = Tcp_server(interface=ip,
                                 port=port,
                                 name='CLI',
                                 mode=Tcp_server.MODE_TEXT_LINE)
        self.server.set_callbacks(incoming_connection=self.handle_connection)
        self.sh = smarthome
        self.updates_allowed = Utils.to_bool(update)
        self.hashed_password = hashed_password
        self.commands = CLICommands(self.sh, self.updates_allowed, self)
        self.alive = False
예제 #22
0
    def __init__(self, sh):
        """
        Initalizes the plugin.

        If you need the sh object at all, use the method self.get_sh() to get it. There should be almost no need for
        a reference to the sh object any more.

        Plugins have to use the new way of getting parameter values:
        use the SmartPlugin method get_parameter_value(parameter_name). 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.
        """

        # Call init code of parent class (SmartPlugin)
        super().__init__()

        self._model = TimmyModel()
        self._shng_items = Items.get_instance()
        self.__delay_scheduler_names = []
        self.__blink_scheduler_names = []

        return
예제 #23
0
파일: scene.py 프로젝트: stoepf/smarthome
    def _eval(self, value):
        """
        Evaluate a scene value

        :param value: value expression to evaluate
        :type value: str

        :return: evaluated value or None
        :rtype: type of evaluated expression or None
        """
        sh = self._sh
        shtime = Shtime.get_instance()
        items = Items.get_instance()
        import math
        import lib.userfunctions as uf

        try:
            rvalue = eval(value)
        except Exception as e:
            logger.warning(" - " + translate("Problem evaluating: {value} - {exception}", {'value': value, 'exception': e}))
            return value
        return rvalue
예제 #24
0
파일: __init__.py 프로젝트: wvhn/plugins
    def write_masteritem_file(self):
        """
        create_master_item.py in smartVISU
        """
        import json
        from lib.item import Items

        # get a list with only the pathes of the items
        items = Items.get_instance()
        items_sorted = sorted(items.return_items(),
                              key=lambda k: str.lower(k['_path']),
                              reverse=False)
        item_list = []
        for item in items_sorted:
            item_list.append(item.property.path + '|' + item.property.type)
        # read config.ini to get the name of the pages directory
        dirname = self.read_from_sv_configini('pages')

        if dirname != '':
            # write json file with list of item pathes
            pagedir_name = os.path.join(self.smartvisu_dir, 'pages', dirname)
            filename = os.path.join(pagedir_name, 'masteritem.json')
            self.logger.debug(f"write_masteritem_file: filename='{filename}'")
            try:
                with open(filename, 'w', encoding='utf-8') as f:
                    json.dump(item_list, f, ensure_ascii=False, indent=4)
                self.logger.info(
                    f"master-itemfile written to smartVISU (to directory {pagedir_name})"
                )
            except:
                self.logger.warning(
                    f"Could not write master-itemfile to smartVISU (to directory {pagedir_name})"
                )
        else:
            self.logger.warning(
                "Master-itemfile not written, because the name of the pages directory could not be read from smartVISU"
            )
        return
예제 #25
0
    def __init__(self,
                 smarthome,
                 driver,
                 connect,
                 prefix="",
                 cycle=60,
                 precision=2):
        self._sh = smarthome
        self.shtime = Shtime.get_instance()
        self.items = Items.get_instance()

        self._dump_cycle = int(cycle)
        self._precision = int(precision)
        self._name = self.get_instance_name()
        self._replace = {
            table: table if prefix == "" else prefix + "_" + table
            for table in ["log", "item"]
        }
        self._replace['item_columns'] = ", ".join(COL_ITEM)
        self._replace['log_columns'] = ", ".join(COL_LOG)
        self._buffer = {}
        self._buffer_lock = threading.Lock()
        self._dump_lock = threading.Lock()

        self._db = lib.db.Database(
            ("" if prefix == "" else prefix.capitalize() + "_") + "Database",
            driver, Utils.string_to_list(connect))
        self._initialized = False
        self._initialize()

        smarthome.scheduler.add('Database dump ' + self._name +
                                ("" if prefix == "" else " [" + prefix + "]"),
                                self._dump,
                                cycle=self._dump_cycle,
                                prio=5)

        self.init_webinterface()
        return
예제 #26
0
    def __init__(self, webif_dir, plugin):
        """
        Initialization of instance of class WebInterface
        
        :param webif_dir: directory where the webinterface of the plugin resides
        :param plugin: instance of the plugin
        :type webif_dir: str
        :type plugin: object
        """
        self.logger = logging.getLogger(__name__)
        self.webif_dir = webif_dir
        self.plugin = plugin
        self.tplenv = self.init_template_environment()

        self.items = Items.get_instance()

        self.knxdeamon = ''
        if self.get_process_info("ps cax|grep eibd") != '':
            self.knxdeamon = 'eibd'
        if self.get_process_info("ps cax|grep knxd") != '':
            if self.knxdeamon != '':
                self.knxdeamon += ' and '
            self.knxdeamon += 'knxd'
예제 #27
0
파일: logic.py 프로젝트: ThomasCr/smarthome
    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)
예제 #28
0
    def __init__(self,
                 smarthome,
                 smartvisu_dir='',
                 overwrite_templates='Yes',
                 visu_style='std',
                 smartvisu_version=''):
        self.logger = logging.getLogger(__name__)
        self._sh = smarthome
        self.items = Items.get_instance()

        self.smartvisu_dir = smartvisu_dir
        self.smartvisu_version = smartvisu_version
        self.overwrite_templates = overwrite_templates
        self.visu_style = visu_style.lower()
        if not self.visu_style in ['std', 'blk']:
            self.visu_style = 'std'
            self.logger.warning(
                "SmartVisuGenerator: visu_style '{}' unknown, using visu_style '{1}'"
                .format(visu_style, self.visu_style))

        self.logger.info("Generating pages for smartVISU v{}".format(
            self.smartvisu_version))

        self.outdir = os.path.join(self.smartvisu_dir, 'pages', 'smarthome')
        self.tpldir = os.path.join(self.smartvisu_dir, 'pages', 'base',
                                   'tplNG')
        self.tmpdir = os.path.join(self.smartvisu_dir, 'temp')
        if self.smartvisu_version == '2.9':
            self.tpldir = os.path.join(self.smartvisu_dir, 'dropins')

        self.thisplgdir = os.path.dirname(os.path.abspath(__file__))
        self.copy_templates()

        self.pages()
        self.logger.info("Generating pages for smartVISU v{} End".format(
            self.smartvisu_version))
예제 #29
0
 def __init__(self, smarthome, cycle=300, path=None, dumpfile=''):
     self.logger = logging.getLogger(__name__)
     #       sqlite3.register_adapter(datetime.datetime, self._timestamp)
     self._sh = smarthome
     self.items = Items.get_instance()
     self.shtime = Shtime.get_instance()
     self.connected = False
     self._buffer = {}
     self._buffer_lock = threading.Lock()
     self.logger.debug("SQLite {0}".format(sqlite3.sqlite_version))
     self._fdb_lock = threading.Lock()
     self._fdb_lock.acquire()
     self._dumpfile = dumpfile
     if path is None:
         self.path = smarthome.base_dir + '/var/db/smarthome.db'
     else:
         self.path = path + '/smarthome.db'
     try:
         self._fdb = sqlite3.connect(self.path, check_same_thread=False)
     except Exception as e:
         self.logger.error(
             "SQLite: Could not connect to the database {}: {}".format(
                 self.path, e))
         self._fdb_lock.release()
         return
     self.connected = True
     integrity = self._fdb.execute(
         "PRAGMA integrity_check(10);").fetchone()[0]
     if integrity == 'ok':
         self.logger.debug("SQLite: database integrity ok")
     else:
         self.logger.error("SQLite: database corrupt. Seek help.")
         self._fdb_lock.release()
         return
     self._fdb.execute(
         "CREATE TABLE IF NOT EXISTS num (_start INTEGER, _item TEXT, _dur INTEGER, _avg REAL, _min REAL, _max REAL, _on REAL);"
     )
     self._fdb.execute(
         "CREATE TABLE IF NOT EXISTS cache (_item TEXT PRIMARY KEY, _start INTEGER, _value REAL);"
     )
     self._fdb.execute("CREATE INDEX IF NOT EXISTS idx ON num (_item);")
     common = self._fdb.execute(
         "SELECT * FROM sqlite_master WHERE name='common' and type='table';"
     ).fetchone()
     if common is None:
         self._fdb.execute("CREATE TABLE common (version INTEGER);")
         self._fdb.execute("INSERT INTO common VALUES (:version);",
                           {'version': self._version})
     else:
         version = int(
             self._fdb.execute("SELECT version FROM common;").fetchone()[0])
         if version < self._version:
             import plugins.sqlite_visu2_8.upgrade
             self.logger.info("SQLite: upgrading database. Please wait!")
             plugins.sqlite_visu2_8.upgrade.Upgrade(self._fdb, version)
             self._fdb.execute("UPDATE common SET version=:version;",
                               {'version': self._version})
     self._fdb.commit()
     self._fdb_lock.release()
     minute = 60 * 1000
     hour = 60 * minute
     day = 24 * hour
     week = 7 * day
     month = 30 * day
     year = 365 * day
     self._frames = {
         'i': minute,
         'h': hour,
         'd': day,
         'w': week,
         'm': month,
         'y': year
     }
     self._times = {
         'i': minute,
         'h': hour,
         'd': day,
         'w': week,
         'm': month,
         'y': year
     }
     #        smarthome.scheduler.add('SQLite Maintain', self._maintain, cron='2 3 * *', prio=5)
     self.scheduler_add('SQLite Maintain',
                        self._maintain,
                        cron='2 3 * *',
                        prio=5)
예제 #30
0
    def add(self,
            name,
            obj,
            prio=3,
            cron=None,
            cycle=None,
            value=None,
            offset=None,
            next=None,
            from_smartplugin=False):
        """
        Adds an entry to the scheduler.

        :param name: Name of the scheduler
        :param obj: Method to call by the scheduler
        :param prio: a priority with default of 3 having 1 as most important and higher numbers less important
        :param cron: a crontab entry of type string or a list of entries
        :param cycle: a time given as integer in seconds or a string with a time given in seconds and a value after an equal sign
        :param value:
        :param offset: an optional offset for cycle. If not given, cycle start point will be varied between 10..15 seconds to prevent too many scheduler entries with the same starting times
        :param next:
        :param from_smartplugin: Only to set to True, if called from the internal method in SmartPlugin class
        """
        # set shtime and items if they were initialized to None in __init__  (potenital timing problem in init of shng)
        if self.shtime == None:
            self.shtime = Shtime.get_instance()
        if self.items == None:
            self.items = Items.get_instance()
        self._lock.acquire()
        if isinstance(cron, str):
            cron = [
                cron,
            ]
        if isinstance(cron, list):
            _cron = {}
            for entry in cron:
                desc, __, _value = entry.partition('=')
                desc = desc.strip()
                if _value == '':
                    _value = None
                else:
                    _value = _value.strip()
                if desc.startswith('init'):
                    offset = 5  # default init offset
                    desc, op, seconds = desc.partition('+')
                    if op:
                        offset += int(seconds)
                    else:
                        desc, op, seconds = desc.partition('-')
                        if op:
                            offset -= int(seconds)
                    value = _value
                    next = self.shtime.now() + datetime.timedelta(
                        seconds=offset)
                else:
                    _cron[desc] = _value
            if _cron == {}:
                cron = None
            else:
                cron = _cron
        if isinstance(cycle, int):
            cycle = {cycle: None}
        elif isinstance(cycle, str):
            cycle, __, _value = cycle.partition('=')
            try:
                cycle = int(cycle.strip())
            except Exception:
                logger.warning(
                    "Scheduler: invalid cycle entry for {0} {1}".format(
                        name, cycle))
                return
            if _value != '':
                _value = _value.strip()
            else:
                _value = None
            cycle = {cycle: _value}
        if cycle is not None and offset is None:  # spread cycle jobs
            offset = random.randint(10, 15)
        # change name for multi instance plugins
        if obj.__class__.__name__ == 'method':
            if isinstance(obj.__self__, SmartPlugin):
                if obj.__self__.get_instance_name() != '':
                    #if not (name).startswith(self._pluginname_prefix):
                    if not from_smartplugin:
                        name = name + '_' + obj.__self__.get_instance_name()
                    logger.debug(
                        "Scheduler: Name changed by adding plugin instance name to: "
                        + name)
        self._scheduler[name] = {
            'prio': prio,
            'obj': obj,
            'cron': cron,
            'cycle': cycle,
            'value': value,
            'next': next,
            'active': True
        }
        if next is None:
            self._next_time(name, offset)
        self._lock.release()
예제 #31
0
    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.etc_dir = sh._etc_dir
        self.shtime = Shtime.get_instance()

        self.logger.debug("Module '{}': Initializing".format(self._shortname))

        # get the parameters for the module (as defined in metadata module.yaml):
        self.logger.debug("Module '{}': Parameters = '{}'".format(self._shortname, dict(self._parameters)))
        self.ip = self.get_parameter_value('ip')
        #if self.ip == '0.0.0.0':
        #    self.ip = Utils.get_local_ipv4_address()
        self.port = self.get_parameter_value('port')
        self.tls_port = self.get_parameter_value('tls_port')
        self.use_tls = self.get_parameter_value('use_tls')
        self.tls_cert = self.get_parameter_value('tls_cert')
        self.tls_key = self.get_parameter_value('tls_key')

        # parameters for smartVISU handling are initialized by the smartvisu plugin
        #self.sv_enabled = self.get_parameter_value('sv_enabled')
        #self.sv_acl = self.get_parameter_value('default_acl')
        #self.sv_querydef = self.get_parameter_value('sv_querydef')
        #self.sv_ser_upd_cycle = self.get_parameter_value('sv_ser_upd_cycle')
        self.sv_enabled = False
        self.sv_acl = 'deny'
        self.sv_querydef = False
        self.sv_ser_upd_cycle = 0

        self.ssl_context = None
        if self.use_tls:
            self.ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
            pem_file = os.path.join(self.etc_dir, self.tls_cert)
            key_file = os.path.join(self.etc_dir, self.tls_key)
            try:
                self.ssl_context.load_cert_chain(pem_file, key_file)
            except Exception as e:
                self.logger.error("Secure websocket port not opened because the following error ocured while initilizing tls: {}".format(e))
                self.ssl_context = None
                self.use_tls = False

        if self.use_tls and self.port == self.tls_port:
            self.logger.error("Secure websocket port not opened because it cannnot be the same port as the ws:// port:")
            self.ssl_context = None
            self.use_tls = False

        self.logger.info("ip         : {}".format(self.ip))
        self.logger.info("port       : {}".format(self.port))
        self.logger.info("tls_port   : {}".format(self.tls_port))
        self.logger.info("use_tls    : {}".format(self.use_tls))
        self.logger.info("tls_cert   : {}".format(self.tls_cert))
        self.logger.info("tls_key    : {}".format(self.tls_key))

        # try to get API handles
        self.items = Items.get_instance()
        self.logics = Logics.get_instance()

        self.loop = None    # Var to hold the event loop for asyncio

        # For Release 1.8 only: Enable smartVISU protocol support even if smartvisu plugin is not loaded
        self.set_smartvisu_support(protocol_enabled=True)
    def __init__(self, smarthome, item):
        self.items = Items.get_instance()
        self.shtime = Shtime.get_instance()
        self.__sh = smarthome
        self.__item = item
        self.__id = self.__item.id()
        self.__name = str(self.__item)
        # initialize logging
        self.__logger = SeLogger.create(self.__item)
        self.__logger.header("Initialize Item {0}".format(self.id))

        # get startup delay
        self.__startup_delay = StateEngineValue.SeValue(
            self, "Startup Delay", False, "num")
        self.__startup_delay.set_from_attr(self.__item, "se_startup_delay",
                                           StateEngineDefaults.startup_delay)
        self.__startup_delay_over = False

        # Init suspend settings
        self.__suspend_time = StateEngineValue.SeValue(
            self, "Suspension time on manual changes", False, "num")
        self.__suspend_time.set_from_attr(self.__item, "se_suspend_time",
                                          StateEngineDefaults.suspend_time)

        # Init laststate items/values
        self.__laststate_item_id = self.return_item_by_attribute(
            "se_laststate_item_id")
        self.__laststate_internal_id = "" if self.__laststate_item_id is None else self.__laststate_item_id(
        )
        self.__laststate_item_name = self.return_item_by_attribute(
            "se_laststate_item_name")
        self.__laststate_internal_name = "" if self.__laststate_item_name is None else self.__laststate_item_name(
        )

        self.__states = []
        self.__repeat_actions = StateEngineValue.SeValue(
            self, "Repeat actions if state is not changed", False, "bool")
        self.__repeat_actions.set_from_attr(self.__item, "se_repeat_actions",
                                            True)

        self.__update_trigger_item = None
        self.__update_trigger_caller = None
        self.__update_trigger_source = None
        self.__update_trigger_dest = None
        self.__update_in_progress = False
        self.__update_original_item = None
        self.__update_original_caller = None
        self.__update_original_source = None

        # Check item configuration
        self.__check_item_config()

        # Init variables
        self.__variables = {
            "item.suspend_time": self.__suspend_time.get(),
            "item.suspend_remaining": 0,
            "current.state_id": "",
            "current.state_name": ""
        }

        # initialize states
        for item_state in self.__item.return_children():
            try:
                self.__states.append(StateEngineState.SeState(
                    self, item_state))
            except ValueError as ex:
                self.__logger.error("Ignoring state {0} because:  {1}".format(
                    item_state.id(), str(ex)))

        if len(self.__states) == 0:
            raise ValueError("{0}: No states defined!".format(self.id))

        # Write settings to log
        self.__write_to_log()

        # start timer with startup-delay
        startup_delay = 0 if self.__startup_delay.is_empty(
        ) else self.__startup_delay.get()
        if startup_delay > 0:
            first_run = self.shtime.now() + datetime.timedelta(
                seconds=startup_delay)
            scheduler_name = self.__id + "-Startup Delay"
            value = {"item": self.__item, "caller": "Init"}
            self.__sh.scheduler.add(scheduler_name,
                                    self.__startup_delay_callback,
                                    value=value,
                                    next=first_run)
        elif startup_delay == -1:
            self.__startup_delay_over = True
            self.__add_triggers()
        else:
            self.__startup_delay_callback(self.__item, "Init", None, None)
예제 #33
0
    return False


def get_item_type(sh, path):
    expr = f'type(sh.{path})'
    return str(eval(expr))


def check_item(sh, path):
    global get_item_type

    return get_item_type(sh, path) == "<class 'lib.item.item.Item'>"


# to get access to the object instance:
items = Items.get_instance()

# to access a method (eg. to get the list of Items):
# allitems = items.return_items()
problems_found = 0
problems_fixed = 0

for one in items.return_items(sorted=True):
    # get the items full path
    path = one.id()
    try:
        if not check_item(sh, path):
            logger.error(f"Error: item {path} has type {get_item_type(sh, path)} but should be an Item Object")
            problems_found += 1
            if repair_item(sh, one):
                if check_item(sh, path):
예제 #34
0
    def add(self, name, obj, prio=3, cron=None, cycle=None, value=None, offset=None, next=None, from_smartplugin=False):
        """
        Adds an entry to the scheduler.
        
        :param name:
        :param obj:
        :param prio: a priority with default of 3 having 1 as most important and higher numbes less important
        :param cron: a crontab entry of type string or a list of entries
        :param cycle: a time given as integer in seconds or a string with a time given in seconds and a value after an equal sign
        :param value:
        :param offset: an optional offset for cycle. If not given, cycle start point will be varied between 10..15 seconds to prevent too many scheduler entries with the same starting times
        :param next:
        :param from_smartplugin:
        """
        if self.shtime == None:
            self.shtime = Shtime.get_instance()
        if self.shtime == None:
            self.items = Items.get_instance()
        self._lock.acquire()
        if isinstance(cron, str):
            cron = [cron, ]
        if isinstance(cron, list):
            _cron = {}
            for entry in cron:
                desc, __, _value = entry.partition('=')
                desc = desc.strip()
                if _value == '':
                    _value = None
                else:
                    _value = _value.strip()
                if desc.startswith('init'):
                    offset = 5  # default init offset
                    desc, op, seconds = desc.partition('+')
                    if op:
                        offset += int(seconds)
                    else:
                        desc, op, seconds = desc.partition('-')
                        if op:
                            offset -= int(seconds)
                    value = _value
#                    next = self._sh.now() + datetime.timedelta(seconds=offset)
                    next = self.shtime.now() + datetime.timedelta(seconds=offset)
                else:
                    _cron[desc] = _value
            if _cron == {}:
                cron = None
            else:
                cron = _cron
        if isinstance(cycle, int):
            cycle = {cycle: None}
        elif isinstance(cycle, str):
            cycle, __, _value = cycle.partition('=')
            try:
                cycle = int(cycle.strip())
            except Exception:
                logger.warning("Scheduler: invalid cycle entry for {0} {1}".format(name, cycle))
                return
            if _value != '':
                _value = _value.strip()
            else:
                _value = None
            cycle = {cycle: _value}
        if cycle is not None and offset is None:  # spread cycle jobs
                offset = random.randint(10, 15)
        # change name for multi instance plugins
        if obj.__class__.__name__ == 'method':
            if isinstance(obj.__self__, SmartPlugin):
                if obj.__self__.get_instance_name() != '':
                    #if not (name).startswith(self._pluginname_prefix):
                    if not from_smartplugin:
                        name = name +'_'+ obj.__self__.get_instance_name()
                    logger.debug("Scheduler: Name changed by adding plugin instance name to: " + name)
        self._scheduler[name] = {'prio': prio, 'obj': obj, 'cron': cron, 'cycle': cycle, 'value': value, 'next': next, 'active': True}
        if next is None:
            self._next_time(name, offset)
        self._lock.release()