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)
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()
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)
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)
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)
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()
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)
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))
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
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
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
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
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()
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
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
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
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
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
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
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)
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
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
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
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
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
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'
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)
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))
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)
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()
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)
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):
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()