def __init__(self, smarthome): super().__init__() if '.'.join(VERSION.split('.', 2)[:2]) <= '1.5': self.logger = logging.getLogger(__name__) try: self.shtime = Shtime.get_instance() self.handle_login = self.get_parameter_value('handle_login') try: self.dl = Http(timeout=self.get_parameter_value('timeout'), hide_login=self.handle_login) except: self.dl = Http(hide_login=self.handle_login) self._items = [] self._icals = {} self._ical_aliases = {} self._cycle = self.get_parameter_value('cycle') calendars = self.get_parameter_value('calendars') config_dir = self.get_parameter_value('directory') except Exception as err: self.logger.error('Problems initializing: {}'.format(err)) self._init_complete = False return try: self._directory = '{}/{}'.format(self.get_vardir(), config_dir) except Exception: self._directory = '{}/var/{}'.format(smarthome.get_basedir(), config_dir) self._directory = os.path.normpath(self._directory) try: os.makedirs(self._directory) self.logger.debug('Created {} subfolder in var'.format(config_dir)) except OSError as e: if e.errno != errno.EEXIST: self.logger.error( 'Problem creating {} folder in {}/var'.format( config_dir, smarthome.get_basedir())) self._init_complete = False return for calendar in calendars: if isinstance(calendar, dict): calendar = list("{!s}:{!s}".format(k, v) for (k, v) in calendar.items())[0] if ':' in calendar and 'http' != calendar[:4]: name, _, cal = calendar.partition(':') calendar = cal.strip() self.logger.info( 'Registering calendar {} with alias {}.'.format( Network.clean_uri(calendar, self.handle_login), name)) self._ical_aliases[name.strip()] = calendar else: self.logger.info( 'Registering calendar {} without alias.'.format( Network.clean_uri(calendar, self.handle_login))) calendar = calendar.strip() self._icals[calendar] = self._read_events(calendar) self.shtime = Shtime.get_instance()
def __init__(self): VERSION = '1.4c.' VERSION += '0.man' self.version = VERSION self.__logs = {} # self.__item_dict = {} # self.__items = [] self.children = [] self._use_modules = 'True' self._moduledict = {} if self.shtime is None: self.shtime = Shtime.get_instance() self.scheduler = MockScheduler() self.connections = lib.connection.Connections() if self.shtime is None: lib.shtime._shtime_instance = self.shtime = Shtime(self) # Start() # self.scheduler = lib.scheduler.Scheduler(self) if self.modules is None: self.with_modules_from(self._module_conf_basename) if self.items is None: lib.item._items_instance = None self.items = lib.item.Items(self) if self.plugins is None: self.with_plugins_from(self._plugin_conf_basename)
def __init__(self, smarthome, name, cache=True, logtofile=True, filepattern="{year:04}-{month:02}-{day:02}-{name}.log", mapping=['time', 'thread', 'level', 'message'], items=[], maxlen=50): log_directory = "var/log/operationlog/" self._sh = smarthome self.shtime = Shtime.get_instance() self.name = name self.logger = logging.getLogger(__name__) if log_directory[0] != "/": base = self._sh.base_dir if base[-1] != "/": base += "/" self.log_directory = base + log_directory else: self.log_directory = log_directory if not os.path.exists(self.log_directory): os.makedirs(log_directory) AbLogger.set_logdirectory(self.log_directory) AbLogger.set_loglevel(2) AbLogger.set_logmaxage(0) AbLogger.__init__(self, name) self._filepattern = filepattern self._log = lib.log.Log(smarthome, name, mapping, int(maxlen)) self._path = name self._cachefile = None self._cache = True self.__myLogger = None self._logcache = None self._maxlen = int(maxlen) self._items = items self._item_conf = {} self._logic_conf = {} self.__date = None self.__fname = None info_txt_cache = ", caching active" if isinstance(cache, str) and cache in ['False', 'false', 'No', 'no']: self._cache = False info_txt_cache = "" self._logtofile = True info_txt_log = "OperationLog {}: logging to file {}{}, keeping {} entries in memory".format(self.name, self.log_directory, self._filepattern, int(self._maxlen)) if isinstance(logtofile, str) and logtofile in ['False', 'false', 'No', 'no']: self._logtofile = False self.logger.info(info_txt_log + info_txt_cache) ############################################################# # Cache ############################################################# if self._cache is True: self._cachefile = self._sh._cache_dir + self._path try: self.__last_change, self._logcache = _cache_read(self._cachefile, self.shtime.tzinfo()) self.load(self._logcache) self.logger.debug("OperationLog {}: read cache: {}".format(self.name, self._logcache)) except Exception: try: _cache_write(self.logger, self._cachefile, self._log.export(int(self._maxlen))) _cache_read(self._cachefile, self.shtime.tzinfo()) self.logger.info("OperationLog {}: generated cache file".format(self.name)) except Exception as e: self.logger.warning("OperationLog {}: problem reading cache: {}".format(self._path, e))
def __init__(self): #VERSION = '1.8.' #VERSION += '2c.man' #self.version = VERSION self.version = bin.shngversion.shNG_version self.python_bin = os.environ.get('_', '') self.__logs = {} # self.__item_dict = {} # self.__items = [] self.children = [] self._use_modules = 'True' self._moduledict = {} if self.shtime is None: self.shtime = Shtime.get_instance() self.scheduler = MockScheduler() if self.shtime is None: lib.shtime._shtime_instance = self.shtime = Shtime(self) # Start() # self.scheduler = lib.scheduler.Scheduler(self) if self.modules is None: self.with_modules_from(self._module_conf_basename) if self.items is None: try: lib.item.items._items_instance = None except: lib.item._items_instance = None self.items = lib.item.Items(self) if self.plugins is None: self.with_plugins_from(self._plugin_conf_basename)
def run(self): """ Run method for the plugin """ self.logger.debug("Run method called") if self._logtofile is True: self.__myLogger = self.create(self.name) sh = self.get_sh() shtime = Shtime.get_instance() for item_id in self._item_conf: if 'olog_eval' in self._item_conf[item_id]: for (ind, eval_str) in enumerate( self._item_conf[item_id]['olog_eval']): try: eval(eval_str) except Exception as e: self.logger.warning( 'olog: could not evaluate {} for item: {}, {}'. format(eval_str, item_id, e)) self._item_conf[item_id]['olog_eval'][ind] = "'--'" for logic_name in self._logic_conf: if 'olog_eval' in self._logic_conf[logic_name]: for (ind, eval_str) in enumerate( self._logic_conf[logic_name]['olog_eval']): try: eval(eval_str) except Exception as e: self.logger.warning( 'olog: could not evaluate {} for logic: {}, {}'. format(eval_str, logic_name, e)) self._logic_conf[logic_name]['olog_eval'][ind] = "'--'" self.alive = True
def __init__(self, sh): super().__init__() self.shtime = Shtime.get_instance() self._client_id = self.get_parameter_value('client_id') self._client_secret = self.get_parameter_value('client_secret') self._cycle = self.get_parameter_value('cycle') self._simulate = self.get_parameter_value('simulate') self._token = None self._items = {} if not self.init_webinterface(WebInterface): self._init_complete = False else: self._hc = HomeConnect( self._client_id, self._client_secret, self.get_redirect_uri(), simulate=self._simulate, token_cache=self.get_sh().get_basedir() + "/plugins/homeconnect/homeconnect_oauth_token.json", token_listener=self.set_token) self._token = self.get_hc().token_load() self.logger.debug("Token loaded: %s" % self._token) if self._token: if not self.get_hc().token_expired(self._token): self._init_appliance_listeners()
def boost(self, c, timer=True, edt=None): """ this function changes setpoint of the given controller to defined boost temperature :param c: controller to be used :param timer: if not True, no timer will be created :param edt: end datetime to override the default """ if re.match(r"[0-9]+$", str(c)): c = 'c' + c self.logger.debug("boost(): called for controller: '{}'".format(c)) if c in self._controller: if self._controller[c]['tempBoost'] > 0: self._items.return_item(self._controller[c]['setpointItem'])(self._controller[c]['tempBoost']) self._controller[c]['HVACMode'] = self.HVACMode_Comfort if self._controller[c]['HVACModeItem'] is not None: self._items.return_item(self._controller[c]['HVACModeItem'])(self._controller[c]['HVACMode']) if self._controller[c]['tempBoostTime'] == 0 and edt is None: timer = False if timer == True: if edt is None: shtime = Shtime.get_instance() edt = shtime.now() + datetime.timedelta(minutes=self._controller[c]['tempBoostTime']) self._deleteTimer('drop_' + c) self._createTimer('boost_' + c, c, edt) else: self.logger.error("boost() unknown controller '{}' - we only have '{}'".format(c, self._controller.keys()))
def valve_protect(self, y=100): """ Initalizes valve protecion 1. call = open valve (y=100) -> timer +5min 2. call = close valve (y=0) -> timer +5min 3. call = active = false """ self.logger.info("run valve protecion") shtime = Shtime.get_instance() edt = shtime.now() + datetime.timedelta(minutes=5) if y == 100: self.scheduler_add('protectClose', self.valve_protect, value={'y': 0}, next=edt) elif y == 0: self.scheduler_add('protectOff', self.valve_protect, value={'y': -1}, next=edt) for c in self._controller.keys(): if self._controller[c]['validated'] and self._controller[c]['valveProtect']: if y >= 0: yItem = self._items.return_item(self._controller[c]['actuatorItem']) self.logger.debug("set item '{}' to '{}'".format(yItem.id(), y)) self._controller[c]['valveProtectActive'] = True yItem(y) else: self._controller[c]['valveProtectActive'] = False
def eval_syntax_checker(self, eval_code, relative_to): expanded_code = '' # set up environment for calculating eval-expression sh = self._sh shtime = Shtime.get_instance() items = Items.get_instance() import math import lib.userfunctions as uf eval_code = eval_code.replace('\r', '').replace('\n', ' ').replace(' ', ' ').strip() if relative_to == '': expanded_code = eval_code else: rel_to_item = items.return_item(relative_to) if rel_to_item is not None: expanded_code = rel_to_item.get_stringwithabsolutepathes( eval_code, 'sh.', '(') expanded_code = rel_to_item.get_stringwithabsolutepathes( expanded_code, 'sh.', '.property') else: expanded_code = "Error: Item {} does not exist!".format( relative_to) try: value = eval(expanded_code) except Exception as e: check_result = "Problem evaluating {}: {}".format( expanded_code, e) else: check_result = value return expanded_code, check_result
def __init__(self, smarthome, driver, connect, prefix="", cycle=60): self._sh = smarthome self.shtime = Shtime.get_instance() self.items = Items.get_instance() self.logger = logging.getLogger(__name__) self._dump_cycle = int(cycle) 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) if not self.init_webinterface(): self._init_complete = False
def __init__(self, sh, *args, **kwargs): # Call init code of parent class (SmartPlugin or MqttPlugin) super().__init__() self._cycle = 300 self.shtime = Shtime.get_instance() self._province_codes = self.ALLOWED_PROVINCES self._vacation_list = {} self.init_webinterface()
def __init__(self, abitem, name: str): super().__init__(abitem) self.shtime = Shtime.get_instance() self.items = Items.get_instance() self._name = name self.__delay = StateEngineValue.SeValue(self._abitem, "delay") self.__repeat = None self.__order = StateEngineValue.SeValue(self._abitem, "order", False, "num") self._scheduler_name = None
def __init__(self, smarthome): self.host = self.get_parameter_value('host') self.port = self.get_parameter_value('port') from bin.smarthome import VERSION if '.'.join(VERSION.split('.', 2)[:2]) <= '1.5': self.logger = logging.getLogger(__name__) lib.connection.Client.__init__(self, self.host, self.port, monitor=True) self.logger.debug("init knx") self.shtime = Shtime.get_instance() busmonitor = self.get_parameter_value('busmonitor') self.gal = {} # group addresses to listen to {DPT: dpt, ITEMS: [item 1, item 2, ..., item n], LOGICS: [ logic 1, logic 2, ..., logic n]} self.gar = {} # group addresses to reply if requested from knx, {DPT: dpt, ITEM: item, LOGIC: None} self._init_ga = [] self._cache_ga = [] # group addresses which should be initalized by the knxd cache self._cache_ga_response_pending = [] self.time_ga = self.get_parameter_value('time_ga') self.date_ga = self.get_parameter_value('date_ga') send_time = self.get_parameter_value('send_time') self._bm_separatefile = False self._bm_format= "BM': {1} set {2} to {3}" # following needed for statistics self.enable_stats = self.get_parameter_value('enable_stats') self.stats_ga = {} # statistics for used group addresses on the BUS self.stats_pa = {} # statistics for used group addresses on the BUS self.stats_last_read = None # last read request from KNX self.stats_last_write = None # last write from KNX self.stats_last_response = None # last response from KNX self.stats_last_action = None # the newes if busmonitor.lower() in ['on','true']: self._busmonitor = self.logger.info elif busmonitor.lower() in ['off','false']: self._busmonitor = self.logger.debug elif busmonitor.lower() == 'logger': self._bm_separatefile = True self._bm_format = "{0};{1};{2};{3}" self._busmonitor = logging.getLogger("knx_busmonitor").info self.logger.warning("Using busmonitor (L) = '{}'".format(busmonitor)) else: self.logger.warning("Invalid value '{}' configured for parameter 'busmonitor', using 'false'".format(busmonitor)) self._busmonitor = self.logger.debug if send_time: self._sh.scheduler.add('KNX[{0}] time'.format(self.get_instance_name()), self._send_time, prio=5, cycle=int(send_time)) self.readonly = self.get_parameter_value('readonly') if self.readonly: self.logger.warning("!!! KNX Plugin in READONLY mode !!! ") self.init_webinterface() return
def broker_uptime(self): """ Return formatted uptime of broker """ if self.shtime is None: self.shtime = Shtime.get_instance() try: return self.shtime.seconds_to_displaystring(int(self._broker['uptime'])) except Exception as e: return '-'
def __init__(self, sh, *args, **kwargs): self.shtime = Shtime.get_instance() self._user_id = self.get_parameter_value('user_id') self._client_id = self.get_parameter_value('client_id') self._consumer_secret = self.get_parameter_value('consumer_secret') self._cycle = self.get_parameter_value('cycle') self._creds = None self._client = None self._items = {} if not self.init_webinterface(): self._init_complete = False
def _set_sh(self, smarthome): """ Set the object's local variable `_sh` to the main smarthomeNG object. You can reference the main object of SmartHomeNG by using self._sh. :Note: **Usually you don't need to call this method**, since it is called during loading of the plugin :param smarthome: the main object of smarthomeNG :type smarthome: object """ self._sh = smarthome if self.shtime is None: self.shtime = Shtime.get_instance()
def __init__(self, abitem, name: str): super().__init__(abitem) self._parent = abitem self._caller = StateEngineDefaults.plugin_identification self.shtime = Shtime.get_instance() self.items = Items.get_instance() self._name = name self.__delay = StateEngineValue.SeValue(self._abitem, "delay") self.__repeat = 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
def __init__(self, smarthome, data_file, callers=None): self.logger = logging.getLogger(__name__) self.logger.info('Init Simulation release 1.5.0.6') self._sh = smarthome self.shtime = Shtime.get_instance() self._datafile = data_file self.lastday = '' self.items = Items.get_instance() self.scheduler = Scheduler.get_instance() self._callers = 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, 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): 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 _restoreTimer(self, c): if os.path.exists(self.path + 'boost_' + c): name = 'boost' elif os.path.exists(self.path + 'boost_' + c): name = 'drop' else: name = 'default' if name == "boost" or name == "drop": filename = name + '_' + c self.logger.info("need to restore '{}'".format(filename)) try: f = open(self.path + filename) ts = f.read() f.close() except OSError as e: self.logger.error("cannot read '{}', error: {}".format( self.path + filename, e.args)) try: ts = int(ts) except ValueError: self.logger.error( "file content '{}' is no timestamp".format(ts)) shtime = Shtime.get_instance() dt = datetime.datetime.fromtimestamp(ts) dt = dt.replace(tzinfo=shtime.tzinfo()) if dt < shtime.now() and self._defaultOnExpiredTimer: self.logger.info( "timer from '{}' is already expired - keep default".format( filename)) self.default(c) else: if name == 'drop': self.drop(c, True, dt) elif name == 'boost': self.boost(c, True, dt) else: self.default(c)
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 __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 __init__(self, sh, testparam=''): """ Initialization Routine for the module """ # TO DO: Shortname anders setzen (oder warten bis der Module Loader es beim Laden setzt self._shortname = self.__class__.__name__ self._shortname = self._shortname.lower() self.logger = logging.getLogger(__name__) self._sh = sh self.shtime = Shtime.get_instance() self.logger.debug(f"Module '{self._shortname}': Initializing") # Test if http module is loaded (if the module uses http) # try: # self.mod_http = Modules.get_instance().get_module('http') # try/except to handle running in a core version that does not support modules # except: # self.mod_http = None # if self.mod_http == None: # self.logger.error( # "Module '{}': Not initializing - Module 'http' has to be loaded BEFORE this module".format(self._shortname)) # self._init_complete = False # return # # self._showtraceback = self.mod_http._showtraceback # get the parameters for the module (as defined in metadata module.yaml): self.logger.debug( f"Module '{self._shortname}': Parameters = '{dict(self._parameters)}'" ) try: # self.broker_ip = self._parameters['broker_host'] pass except KeyError as e: self.logger.critical( f"Module '{self._shortname}': Inconsistent module (invalid metadata definition: {e} not defined)" ) self._init_complete = False return ip = Utils.get_local_ipv4_address() # remove line if `ip` unused
def _restoreTimer(self): """ scans folder for saved timer to restore them at startup """ self.logger.info("check if we need to restore timer") if os.path.isdir(self.path): for filename in os.listdir(self.path): self.logger.info("need to restore '{}'".format(filename)) if not re.match(r"boost_c[0-9]+", filename) and not re.match(r"drop_c[0-9]+", filename): self.logger.error("file looks invalid! Skip it..") return try: f = open(self.path + filename, "r") ts = f.read() f.close() except OSError as e: self.logger.error("cannot read '{}', error: {}".format(self.path + filename, e.args)) continue try: ts = int(ts) except ValueError: self.logger.error("file content '{}' is no timestamp".format(ts)) name, c = filename.split('_') shtime = Shtime.get_instance() dt = datetime.datetime.fromtimestamp(ts) dt = dt.replace(tzinfo=shtime.tzinfo()) if dt < shtime.now(): self.logger.info("timer '{}' is already expired - restore default = {}".format(filename, self._defaultOnExpiredTimer)) if self._defaultOnExpiredTimer: self.default(c) else: self._createTimer(filename, c, dt)
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 valve_protection(self): """ Open and close valves of all RTRs periodically to protect them """ self.logger.info(f"Starting valve protection for all RTRs") for r in self._rtr: if self._rtr[r].valve_protect: self.logger.info( f"- rtr {r}: Valve protection is opening valve") self._rtr[r].valve_protect_active = True else: self.logger.info(f"- rtr {r}: Valve protection is disabled") shtime = Shtime.get_instance() close_time = shtime.now() + datetime.timedelta(minutes=5) # add scheduler to turn protection off after 5 minutes self.scheduler_add('valve_protection_close', self.valve_protection_close, next=close_time) self.update_all_rtrs() 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, 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, 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, abitem): super().__init__(abitem) self._eval_lock = threading.Lock() self.shtime = Shtime.get_instance()
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()