This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
# wertehistoriel.py | |
''' | |
Die Logik berechnet die Wertehistorie anhand der Items, die im struct "wertehistorie_total" und "wertehistorie_minmax" definiert sind. | |
"Statische" Items: | |
Alle Item werden durchsucht und für die, in derem letzten Pfadabschnitt "gestern", "vorwoche", "vormonat" oder "vorjahr" enthalten ist, wird der entsprechende Wert berechnet. | |
DIe Logik wird hierfür über crontab um 00:00 Uhr getriggert | |
"Dynamische" Items: | |
Das Item '*.logic_wertehistorie_trigger' im jeweiligen struct wird immer bei einer Aktualisierung des Zähleritem getriggert und triggert selbst wiederum diese Logik. | |
Wird die Logik von diesem Item getriggert, werden, von diesem Item ausgehend, für die entsprechenden Items die Werte berechnet. | |
"Tageszählerstand": | |
Um einen Tagesendzählerstand zu erfassen und in ein eigenes Item zu schreiben, wird die Logik via crontab um 23.59 getriggert und dern Zählerstand zwanggsweise in die Items geschrieben. | |
Wird die Logik händisch ausgelöst (Admin), werden alle Berechnungen der statischen Items durchgeführt. | |
Über die Logik-Variable "target_level" kann eingestellt werden, wie viele Ebenen zwischen dem Zähleritem (aktueller Zählerstand / Wert) und den Item für die Historie/Statistik liegen. | |
logic.yaml: | |
wertehistorie: | |
filename: wertehistorie.py | |
watch_item: | |
- '*.logic_wertehistorie_trigger' | |
crontab: | |
- init+60 | |
- 0 0 * * | |
- 59 23 * * | |
''' | |
# Definiere den Unterschied der Itemebene zwischen dem Zähleritem und den Items des structs | |
logic.target_level = 1 # Unterstützt wird 1 bis 3, wobei 1 = Zähleritem ist das Parent-Item der struct-Items, 2 = Zähleritem ist das Grandparent-Item der struct-Items, ... | |
# | |
from lib.item import Items | |
items = Items.get_instance() | |
logic.plugin = sh.plugins.return_plugin('database') | |
if not hasattr(logic, 'oldest_log_dict'): | |
logic.oldest_log_dict = {} | |
''' | |
Definition der "time strings" für die DB abfrage zum jeweiligen Tagesende | |
''' | |
logic.time_str_heute = str(shtime.time_since(shtime.today(), 'im')) + 'i' | |
logic.time_str_heute_minus365 = str(shtime.time_since(shtime.today(-365), 'im')) + 'i' | |
logic.time_str_heute_minus730 = str(shtime.time_since(shtime.today(-730), 'im')) + 'i' | |
logic.time_str_gestern_minus0 = str(shtime.time_since(shtime.today(-1), 'im')) + 'i' | |
logic.time_str_gestern_minus1 = str(shtime.time_since(shtime.today(-2), 'im')) + 'i' | |
logic.time_str_gestern_minus2 = str(shtime.time_since(shtime.today(-3), 'im')) + 'i' | |
logic.time_str_gestern_minus3 = str(shtime.time_since(shtime.today(-4), 'im')) + 'i' | |
logic.time_str_gestern_minus4 = str(shtime.time_since(shtime.today(-5), 'im')) + 'i' | |
logic.time_str_gestern_minus5 = str(shtime.time_since(shtime.today(-6), 'im')) + 'i' | |
logic.time_str_gestern_minus6 = str(shtime.time_since(shtime.today(-7), 'im')) + 'i' | |
logic.time_str_vorwoche_minus0 = str(shtime.time_since(shtime.beginning_of_week(), 'im')) + 'i' | |
logic.time_str_vorwoche_minus1 = str(shtime.time_since(shtime.beginning_of_week(shtime.calendar_week(), None, -1), 'im')) + 'i' | |
logic.time_str_vorwoche_minus2 = str(shtime.time_since(shtime.beginning_of_week(shtime.calendar_week(), None, -2), 'im')) + 'i' | |
logic.time_str_vorwoche_minus3 = str(shtime.time_since(shtime.beginning_of_week(shtime.calendar_week(), None, -3), 'im')) + 'i' | |
logic.time_str_vorwoche_minus4 = str(shtime.time_since(shtime.beginning_of_week(shtime.calendar_week(), None, -4), 'im')) + 'i' | |
logic.time_str_vormonat_minus0 = str(shtime.time_since(shtime.beginning_of_month(), 'im')) + 'i' | |
logic.time_str_vormonat_minus1 = str(shtime.time_since(shtime.beginning_of_month(None, None, -1), 'im')) + 'i' | |
logic.time_str_vormonat_minus2 = str(shtime.time_since(shtime.beginning_of_month(None, None, -2), 'im')) + 'i' | |
logic.time_str_vormonat_minus3 = str(shtime.time_since(shtime.beginning_of_month(None, None, -3), 'im')) + 'i' | |
logic.time_str_vormonat_minus4 = str(shtime.time_since(shtime.beginning_of_month(None, None, -4), 'im')) + 'i' | |
logic.time_str_vormonat_minus12 = str(shtime.time_since(shtime.beginning_of_month(None, None, -12), 'im')) + 'i' | |
logic.time_str_vormonat_minus13 = str(shtime.time_since(shtime.beginning_of_month(None, None, -13), 'im')) + 'i' | |
logic.time_str_vorjahr_minus0 = str(shtime.time_since(shtime.beginning_of_year(), 'im')) + 'i' | |
logic.time_str_vorjahr_minus1 = str(shtime.time_since(shtime.beginning_of_year(None, -1), 'im')) + 'i' | |
logic.time_str_vorjahr_minus2 = str(shtime.time_since(shtime.beginning_of_year(None, -2), 'im')) + 'i' | |
logic.time_str_vorjahr_minus3 = str(shtime.time_since(shtime.beginning_of_year(None, -3), 'im')) + 'i' | |
logic.time_str_vorjahr_minus4 = str(shtime.time_since(shtime.beginning_of_year(None, -4), 'im')) + 'i' | |
def _oldest_log(logger, item, item_id=None, logic=logic): | |
""" | |
Ermittlung des Zeitpunktes des ältesten Eintrags eines Items in der DB | |
:param item: Item, für das der älteste Eintrag ermittelt werden soll | |
:return: timestamp des ältesten Eintrags für das Item aus der DB | |
""" | |
if item_id is None: | |
item_id = logic.plugin.id(item) | |
oldest_log = logic.plugin.readOldestLog(item_id) | |
return oldest_log | |
logic._oldest_log = _oldest_log | |
def _oldest_value(logger, item, logic=logic): | |
""" | |
Ermittlung des ältesten Wertes eines Items in der DB | |
:param item: Item, für das der älteste Wert ermittelt werden soll | |
:return: ältester Wert für das Item aus der SDB | |
""" | |
item_id = logic.plugin.id(item) | |
oldest_entry = logic.plugin.readLog(item_id, logic._oldest_log(logger, item, item_id)) | |
return oldest_entry[0][4] | |
logic._oldest_value = _oldest_value | |
def _time_since_oldest_log(logger, timestamp, logic=logic): | |
""" | |
Ermittlung der Zeit in ganzen Minuten zwischen "now" und dem ältesten Eintrag eines Items in der DB | |
:param item: Item, für das die Zeit seit dem ältesten Eintrag ermittelt werden soll | |
:return: Zeit seit dem ältesten Eintrag in der DB in ganzen Minuten | |
""" | |
oldest_log_dt = datetime.datetime.fromtimestamp(int(timestamp)/1000, datetime.timezone.utc).astimezone().strftime('%Y-%m-%d %H:%M:%S %Z%z') | |
time_since_oldest_log = logic.shtime.time_since(oldest_log_dt, resulttype='im') | |
return time_since_oldest_log | |
logic._time_since_oldest_log = _time_since_oldest_log | |
def delta_value(logger, item, time_str_1, time_str_2, logic=logic): | |
""" | |
Berechnung einer Zählerdifferenz eines Items zwischen 2 Zeitpunkten auf Basis der DB Einträge | |
:param item: Item, für das die Zählerdifferenz ermittelt werden soll | |
:param time_str_1: Zeitstring gemäß database-Plugin für den jüngeren Eintrag (bspw: 200i) | |
:param time_str_2: Zeitstring gemäß database-Plugin für den älteren Eintrag (bspw: 400i) | |
""" | |
value_1 = value_2 = value = None | |
if item not in logic.oldest_log_dict: | |
logic.oldest_log_dict[item.id()] = logic._oldest_log(logger, item) | |
logger.info(logic.oldest_log_dict) | |
time_since_oldest_log = logic._time_since_oldest_log(logger, logic.oldest_log_dict[item.id()]) | |
end = int(time_str_1[0:len(time_str_1)-1]) | |
if time_since_oldest_log > end: | |
value_1 = item.db('max', time_str_1, time_str_1) | |
value_2 = item.db('max', time_str_2, time_str_2) | |
if value_1 is not None: | |
if value_2 is None: | |
logger.info(f'No entries for Item {item.id()} in DB found for requested enddate {time_str_1}; try to use oldest entry instead') | |
value_2 = int(logic._oldest_value(logger, item)) | |
value = round(value_1 - value_2, 2) | |
logger.debug(f'delta_value for item={item.id()} with time_str_1={time_str_1} and time_str_2={time_str_2} is {value}') | |
else: | |
logger.debug(f'delta_value for item={item.id()} using time_str_1={time_str_1} is older as oldest_entry. Therefore no DB request initiated.') | |
return value | |
logic.delta_value = delta_value | |
def single_value(logger, item, time_str_1, logic=logic): | |
""" | |
Abfrage der DB nach dem Wert eines Items zum entsprechenden Zeitpunkt | |
:param item: Item, für das der DB-Wert ermittelt werden soll | |
:param time_str_1: Zeitstring gemäß database-Plugin für den Abfragezeitpunkt (bspw: 200i) | |
""" | |
if item not in logic.oldest_log_dict: | |
logic.oldest_log_dict[item.id()] = logic._oldest_log(logger, item) | |
value = None | |
value = item.db('max', time_str_1, time_str_1) | |
if value is None: | |
logger.info(f'No entries for Item {item.id()} in DB found for requested end {time_str_1}; try to use oldest entry instead') | |
value = int(logic._oldest_value(logger, item)) | |
logger.debug(f'single_value for item={item.id()} with time_str_1={time_str_1} is {value}') | |
return value | |
logic.single_value = single_value | |
def value_of_db_function(logger, item, time_str_1, time_str_2, logic=logic): | |
""" | |
Abfrage der DB mit einer DB-Funktion und Start und Ende des Betrachtungszeitraumes | |
:param item: Item, für das die Zählerdifferenz ermittelt werden soll | |
:param time_str_1: Zeitstring gemäß database-Plugin für den Start es Betrachtungszeitraumes (bspw: 400i) | |
:param time_str_2: Zeitstring gemäß database-Plugin für das Ende des Betrachtungszeitraumes (bspw: 200i) | |
""" | |
value = None | |
a, b, func = (str(item.id())).rpartition('_') | |
if func in ('min', 'max', 'avg'): | |
if item is not None: | |
value = item.db(func, time_str_1, time_str_2) | |
if value is None: | |
logger.info(f'No entries for Item {item} in DB found for requested startdate {time_str_1}; try to use oldest entry instead') | |
time_since_oldest_log = logic._time_since_oldest_log(logger, logic._oldest_log(logger, item)) | |
end = int(time_str_2[0:len(time_str_2)-1]) | |
if time_since_oldest_log > end: | |
time_str_1 = str(logic._time_since_oldest_log(logger, logic._oldest_log(logger, item))) + + 'i' | |
value = item.db(func, time_str_1, time_str_2) | |
logger.debug(f'value_of_db_function for item={item.id()} with function={func}, time_str_1={time_str_1}, time_str_2={time_str_2} is {value}') | |
return value | |
logic.value_of_db_function = value_of_db_function | |
def get_counter_item(logger, item, target_level, logic=logic): | |
""" | |
Ermittlung des Zähleritems (Item, in das immer die aktuellen Werte geschrieben werden) auf Basis der Variable zur Definition des LevelUnterschiedes und des Logic-Trigger-Items | |
:param item: Item, für das das Zähleritem ermittelt werden soll | |
:param target_level: EbenenUnterschiede zwischen Zähleritem und Items aus den stucts | |
""" | |
if target_level == 1: | |
counter_item = item.return_parent() | |
elif target_level == 2: | |
counter_item = item.return_parent().return_parent() | |
elif target_level == 3: | |
counter_item = item.return_parent().return_parent().return_parent() | |
if 'database' in counter_item.property.attributes: | |
return counter_item | |
else: | |
logger.error(f'get_counter_item: No database active for counter item {counter_item}') | |
return None | |
logic.get_counter_item = get_counter_item | |
def calc_gestern(logger, logic=logic): | |
""" | |
Berechnung der Werte für alle Items, die "gestern" im Pfad haben. | |
""" | |
for item in logic.items.match_items('*gestern*'): | |
logger.debug(f'Function <calc_gestern> called with item {item.id()}') | |
counter_item = logic.get_counter_item(logger, item, logic.target_level) | |
if counter_item is not None: | |
time_str_1 = time_str_2 = value = None | |
a, b, func = (str(item.id())).rpartition('_') | |
if func in ('min', 'max', 'avg'): | |
if a.endswith('gestern'): | |
time_str_1 = logic.time_str_gestern_minus0 | |
time_str_2 = logic.time_str_heute | |
elif a.endswith('gestern_minus1'): | |
time_str_1 = logic.time_str_gestern_minus1 | |
time_str_2 = logic.time_str_gestern_minus0 | |
elif a.endswith('gestern_minus2'): | |
time_str_1 = logic.time_str_gestern_minus2 | |
time_str_2 = logic.time_str_gestern_minus1 | |
elif a.endswith('gestern_minus3'): | |
time_str_1 = logic.time_str_gestern_minus3 | |
time_str_2 = logic.time_str_gestern_minus2 | |
if time_str_1 is not None and time_str_2 is not None: | |
value = logic.value_of_db_function(logger, counter_item, time_str_1, time_str_2) | |
else: | |
if not str(item.id()).endswith('min_gestern') and not str(item.id()).endswith('max_gestern') and not str(item.id()).endswith('avg_gestern'): | |
if str(item.id()).endswith('gestern'): | |
time_str_1 = logic.time_str_heute | |
time_str_2 = logic.time_str_gestern_minus0 | |
elif str(item.id()).endswith('gestern_minus1'): | |
time_str_1 = logic.time_str_gestern_minus0 | |
time_str_2 = logic.time_str_gestern_minus1 | |
elif str(item.id()).endswith('gestern_minus2'): | |
time_str_1 = logic.time_str_gestern_minus1 | |
time_str_2 = logic.time_str_gestern_minus2 | |
elif str(item.id()).endswith('gestern_minus3'): | |
time_str_1 = logic.time_str_gestern_minus2 | |
time_str_2 = logic.time_str_gestern_minus3 | |
elif str(item.id()).endswith('gestern_minus4'): | |
time_str_1 = logic.time_str_gestern_minus3 | |
time_str_2 = logic.time_str_gestern_minus4 | |
elif str(item.id()).endswith('gestern_minus5'): | |
time_str_1 = logic.time_str_gestern_minus4 | |
time_str_2 = logic.time_str_gestern_minus5 | |
elif str(item.id()).endswith('gestern_minus6'): | |
time_str_1 = logic.time_str_gestern_minus5 | |
time_str_2 = logic.time_str_gestern_minus6 | |
if time_str_1 is not None and time_str_2 is not None: | |
value = logic.delta_value(logger, counter_item, time_str_1, time_str_2) | |
if value is not None: | |
item(value, logic.logic_name) | |
else: | |
logger.info(f'No entries for Item {counter_item.id()} in DB found for requested timeframe with time_str_1={time_str_1} and time_str_2={time_str_2}.') | |
logic.calc_gestern = calc_gestern | |
def calc_vorwoche(logger, logic=logic): | |
""" | |
Berechnung der Werte für alle Items, die "vorwoche" im Pfad haben. | |
""" | |
for item in logic.items.match_items('*vorwoche*'): | |
logger.debug(f'Function <calc_vorwoche> called with item {item.id()}') | |
counter_item = logic.get_counter_item(logger, item, logic.target_level) | |
if counter_item is not None: | |
time_str_1 = time_str_2 = value = None | |
a, b, func = (str(item.id())).rpartition('_') | |
if func in ('min', 'max', 'avg'): | |
if a.endswith('vorwoche'): | |
time_str_1 = logic.time_str_vorwoche_minus1 | |
time_str_2 = logic.time_str_vorwoche_minus0 | |
elif a.endswith('vorwoche_minus1'): | |
time_str_1 = logic.time_str_vorwoche_minus2 | |
time_str_2 = logic.time_str_vorwoche_minus1 | |
elif a.endswith('vorwoche_minus2'): | |
time_str_1 = logic.time_str_vorwoche_minus3 | |
time_str_2 = logic.time_str_vorwoche_minus2 | |
if time_str_1 is not None and time_str_2 is not None: | |
value = logic.value_of_db_function(logger, counter_item, time_str_1, time_str_2) | |
else: | |
if str(item.id()).endswith('vorwoche'): | |
time_str_1 = logic.time_str_vorwoche_minus0 | |
time_str_2 = logic.time_str_vorwoche_minus1 | |
elif str(item.id()).endswith('vorwoche_minus1'): | |
time_str_1 = logic.time_str_vorwoche_minus1 | |
time_str_2 = logic.time_str_vorwoche_minus2 | |
elif str(item.id()).endswith('vorwoche_minus2'): | |
time_str_1 = logic.time_str_vorwoche_minus2 | |
time_str_2 = logic.time_str_vorwoche_minus3 | |
elif str(item.id()).endswith('vorwoche_minus3'): | |
time_str_1 = logic.time_str_vorwoche_minus3 | |
time_str_2 = logic.time_str_vorwoche_minus4 | |
if time_str_1 is not None and time_str_2 is not None: | |
value = logic.delta_value(logger, counter_item, time_str_1, time_str_2) | |
if value is not None: | |
item(value, logic.logic_name) | |
else: | |
logger.info(f'No entries for Item {counter_item.id()} in DB found for requested timeframe with time_str_1={time_str_1} and time_str_2={time_str_2}.') | |
logic.calc_vorwoche = calc_vorwoche | |
def calc_vormonat(logger, logic=logic): | |
""" | |
Berechnung der Werte für alle Items, die "vormonat" im Pfad haben. | |
""" | |
for item in logic.items.match_items('*vormonat*'): | |
logger.debug(f'Function <calc_vormonat> called with item {item.id()}') | |
counter_item = logic.get_counter_item(logger, item, logic.target_level) | |
if counter_item is not None: | |
time_str_1 = time_str_2 = value = None | |
a, b, func = (str(item.id())).rpartition('_') | |
if func in ('min', 'max', 'avg'): | |
if a.endswith('vormonat'): | |
time_str_1 = logic.time_str_vormonat_minus1 | |
time_str_2 = logic.time_str_vormonat_minus0 | |
elif a.endswith('vormonat_minus1'): | |
time_str_1 = logic.time_str_vormonat_minus2 | |
time_str_2 = logic.time_str_vormonat_minus1 | |
elif a.endswith('vormonat_minus2'): | |
time_str_1 = logic.time_str_vormonat_minus3 | |
time_str_2 = logic.time_str_vormonat_minus2 | |
if time_str_1 is not None and time_str_2 is not None: | |
value = logic.value_of_db_function(logger, counter_item, time_str_1, time_str_2) | |
else: | |
if str(item.id()).endswith('vormonat'): | |
time_str_1 = logic.time_str_vormonat_minus0 | |
time_str_2 = logic.time_str_vormonat_minus1 | |
elif str(item.id()).endswith('vormonat_minus1'): | |
time_str_1 = logic.time_str_vormonat_minus1 | |
time_str_2 = logic.time_str_vormonat_minus2 | |
elif str(item.id()).endswith('vormonat_minus2'): | |
time_str_1 = logic.time_str_vormonat_minus2 | |
time_str_2 = logic.time_str_vormonat_minus3 | |
elif str(item.id()).endswith('vormonat_minus3'): | |
time_str_1 = logic.time_str_vormonat_minus3 | |
time_str_2 = logic.time_str_vormonat_minus4 | |
elif str(item.id()).endswith('vormonat_minus12'): | |
time_str_1 = logic.time_str_vormonat_minus12 | |
time_str_2 = logic.time_str_vormonat_minus13 | |
elif str(item.id()).endswith('vormonat_zaehlerstand'): | |
time_str_1 = logic.time_str_vormonat_minus0 | |
elif str(item.id()).endswith('vormonat_minus1_zaehlerstand'): | |
time_str_1 = logic.time_str_vormonat_minus1 | |
elif str(item.id()).endswith('vormonat_minus2_zaehlerstand'): | |
time_str_1 = logic.time_str_vormonat_minus2 | |
if time_str_1 is not None and time_str_2 is not None: | |
logic.delta_value(logger, item, time_str_1, time_str_2) | |
elif time_str_1 is not None and time_str_2 is None: | |
value = logic.single_value(logger, counter_item, time_str_1) | |
if value is not None: | |
item(value, logic.logic_name) | |
else: | |
logger.info(f'No entries for Item {counter_item.id()} in DB found for requested timeframe with time_str_1={time_str_1} and time_str_2={time_str_2}.') | |
logic.calc_vormonat = calc_vormonat | |
def calc_vorjahr(logger, logic=logic): | |
""" | |
Berechnung der Werte für alle Items, die "vorjahr" im Pfad haben. | |
""" | |
for item in logic.items.match_items('*vorjahr*'): | |
logger.debug(f'Function <calc_vorjahr> called with item {item.id()}') | |
counter_item = logic.get_counter_item(logger, item, logic.target_level) | |
if counter_item is not None: | |
time_str_1 = time_str_2 = value = None | |
a, b, func = (str(item.id())).rpartition('_') | |
if func in ('min', 'max', 'avg'): | |
if a.endswith('vorjahr'): | |
time_str_1 = logic.time_str_vorjahr_minus1 | |
time_str_2 = logic.time_str_vorjahr_minus0 | |
elif a.endswith('vorjahr_minus1'): | |
time_str_1 = logic.time_str_vorjahr_minus2 | |
time_str_2 = logic.time_str_vorjahr_minus1 | |
if time_str_1 is not None and time_str_2 is not None: | |
value = logic.value_of_db_function(logger, counter_item, time_str_1, time_str_2) | |
else: | |
if str(item.id()).endswith('vorjahr'): | |
time_str_1 = logic.time_str_vorjahr_minus0 | |
time_str_2 = logic.time_str_vorjahr_minus1 | |
elif str(item.id()).endswith('vorjahr_minus1'): | |
time_str_1 = logic.time_str_vorjahr_minus1 | |
time_str_2 = logic.time_str_vorjahr_minus2 | |
elif str(item.id()).endswith('vorjahr_minus2'): | |
time_str_1 = logic.time_str_vorjahr_minus2 | |
time_str_2 = logic.time_str_vorjahr_minus3 | |
elif str(item.id()).endswith('vorjahr_minus3'): | |
time_str_1 = logic.time_str_vorjahr_minus3 | |
time_str_2 = logic.time_str_vorjahr_minus4 | |
elif str(item.id()).endswith('vorjahr_zaehlerstand'): | |
time_str_1 = logic.time_str_vorjahr_minus0 | |
elif str(item.id()).endswith('vorjahr_minus1_zaehlerstand'): | |
time_str_1 = logic.time_str_vorjahr_minus1 | |
elif str(item.id()).endswith('vorjahr_minus2_zaehlerstand'): | |
time_str_1 = logic.time_str_vorjahr_minus2 | |
if time_str_1 is not None and time_str_2 is not None: | |
diff_value = logic.delta_value(logger, counter_item, time_str_1, time_str_2) | |
elif time_str_1 is not None and time_str_2 is None: | |
value = diff_value = logic.single_value(logger, counter_item, time_str_1) | |
if value is not None: | |
item(value, logic.logic_name) | |
else: | |
logger.info(f'No entries for Item {counter_item.id()} in DB found for requested timeframe with time_str_1={time_str_1} and time_str_2={time_str_2}.') | |
logic.calc_vorjahr = calc_vorjahr | |
def calc_tagesende(logger, logic=logic): | |
""" | |
Berechnung der der Zählerstände am Tagesende | |
""" | |
for item in logic.items.match_items('*zaehlerstand_tagesende*'): | |
logger.debug(f'Function <calc_tagesende> called with item {item.id()}') | |
counter_item = logic.get_counter_item(logger, item, logic.target_level) | |
if counter_item is not None: | |
value = counter_item.property.value | |
logger.debug(f'Value for item={item.id()} is {value}') | |
item(value, logic.logic_name) | |
logic.calc_tagesende = calc_tagesende | |
def calc_rolling(logger, logic=logic): | |
""" | |
Berechnung der Werte für alle Items, die "rolling" im Pfad haben. Dies wind Werte innerhalb eines "rolling window". | |
""" | |
for item in logic.items.match_items('*rolling*'): | |
logger.debug(f'Function <calc_rolling> called with item {item.id()}') | |
counter_item = logic.get_counter_item(logger, item, logic.target_level) | |
if counter_item is not None: | |
time_str_1 = time_str_2 = value = None | |
if str(item.id()).endswith('rolling_12m'): | |
time_str_1 = logic.time_str_heute | |
time_str_2 = logic.time_str_heute_minus365 | |
elif str(item.id()).endswith('rolling_12m_minus1year'): | |
time_str_1 = logic.time_str_heute_minus365 | |
time_str_2 = logic.time_str_heute_minus730 | |
if time_str_1 is not None and time_str_2 is not None: | |
value = logic.delta_value(logger, counter_item, time_str_1, time_str_2) | |
if value is not None: | |
item(value, logic.logic_name) | |
else: | |
logger.info(f'No entries for Item {counter_item.id()} in DB found for requested timeframe with time_str_1={time_str_1} and time_str_2={time_str_2}.') | |
logic.calc_rolling = calc_rolling | |
def calc_today(logger, item, logic=logic): | |
""" | |
Berechnung der Werte für die dynamsichen Items der Wertehistorie | |
""" | |
logger.debug(f'Function <calc_today> called with item {item.id()}') | |
counter_item = logic.get_counter_item(logger, item, logic.target_level) | |
if counter_item is not None: | |
logger.debug(f'calc_today: counter_item={counter_item.id()} and parent of struct items={item.return_parent().id()}') | |
for child in item.return_parent().return_children(): | |
if str(child.id()).endswith('heute'): | |
item.return_parent().heute(round(counter_item.property.value - logic.single_value(logger, counter_item, logic.time_str_heute), 2), logic.logic_name) | |
elif str(child.id()).endswith('woche'): | |
item.return_parent().woche(round(counter_item.property.value - logic.single_value(logger, counter_item, logic.time_str_vorwoche_minus0), 2), logic.logic_name) | |
elif str(child.id()).endswith('monat'): | |
item.return_parent().monat(round(counter_item.property.value - logic.single_value(logger, counter_item, logic.time_str_vormonat_minus0), 2), logic.logic_name) | |
elif str(child.id()).endswith('jahr'): | |
item.return_parent().jahr(round(counter_item.property.value - logic.single_value(logger, counter_item, logic.time_str_vorjahr_minus0), 2), logic.logic_name) | |
elif str(child.id()).endswith('vorjahreszeitraum'): | |
logic.delta_value(logger, counter_item, '24m', '12m') | |
elif str(child.id()).endswith('last24h_min'): | |
item.return_parent().last24h_min(counter_item.db('min', '24h'), logic.logic_name) | |
elif str(child.id()).endswith('last24h_max'): | |
item.return_parent().last24h_max(counter_item.db('max', '24h'), logic.logic_name) | |
elif str(child.id()).endswith('last24h_avg'): | |
item.return_parent().last24h_avg(counter_item.db('avg', '24h'), logic.logic_name) | |
elif str(child.id()).endswith('last7d_min'): | |
item.return_parent().last7d_min(counter_item.db('min', '7d'), logic.logic_name) | |
elif str(child.id()).endswith('last7d_max'): | |
item.return_parent().last7d_max(counter_item.db('max', '7d'), logic.logic_name) | |
elif str(child.id()).endswith('last7d_avg'): | |
item.return_parent().last7d_avg(counter_item.db('avg', '7d'), logic.logic_name) | |
elif str(child.id()).endswith('heute_min'): | |
item.return_parent().heute_min(counter_item.db('min', logic.time_str_heute), logic.logic_name) | |
elif str(child.id()).endswith('heute_max'): | |
item.return_parent().heute_max(counter_item.db('max', logic.time_str_heute), logic.logic_name) | |
elif str(child.id()).endswith('heute_avg'): | |
item.return_parent().heute_avg(counter_item.db('avg', logic.time_str_heute), logic.logic_name) | |
elif str(child.id()).endswith('woche_min'): | |
item.return_parent().woche_min(counter_item.db('min', logic.time_str_vorwoche_minus0), logic.logic_name) | |
elif str(child.id()).endswith('woche_max'): | |
item.return_parent().woche_max(counter_item.db('max', logic.time_str_vorwoche_minus0), logic.logic_name) | |
elif str(child.id()).endswith('woche_avg'): | |
item.return_parent().woche_avg(counter_item.db('avg', logic.time_str_vorwoche_minus0), logic.logic_name) | |
elif str(child.id()).endswith('monat_min'): | |
item.return_parent().monat_min(counter_item.db('min', logic.time_str_vormonat_minus0), logic.logic_name) | |
elif str(child.id()).endswith('monat_max'): | |
item.return_parent().monat_max(counter_item.db('max', logic.time_str_vormonat_minus0), logic.logic_name) | |
elif str(child.id()).endswith('monat_avg'): | |
item.return_parent().monat_avg(counter_item.db('avg', logic.time_str_vormonat_minus0), logic.logic_name) | |
elif str(child.id()).endswith('jahr_min'): | |
item.return_parent().jahr_min(counter_item.db('min', logic.time_str_vorjahr_minus0), logic.logic_name) | |
elif str(child.id()).endswith('jahr_max'): | |
item.return_parent().jahr_max(counter_item.db('max', logic.time_str_vorjahr_minus0), logic.logic_name) | |
elif str(child.id()).endswith('jahr_max'): | |
item.return_parent().jahr_avg(counter_item.db('avg', logic.time_str_vorjahr_minus0), logic.logic_name) | |
logic.calc_today = calc_today | |
""" | |
MAIN | |
""" | |
logger.info(f"Logik '{logic.id()}' ausgelöst durch: {trigger['by']} und {trigger['source']} mit Wert {trigger['value']}") | |
logic.logic_name = 'Logic' + ':' + str(logic.id()) | |
if bool(logic.plugin) is True: | |
if trigger['by'] == 'Scheduler': | |
if shtime.now().hour == 0 and shtime.now().minute == 0: | |
logger.info(f"Logik '{logic.id()}' hat Aktualisierung der Item GESTERN angefordert.") | |
logic.calc_gestern(logger) | |
logic.calc_rolling(logger) | |
if shtime.now().hour == 0 and shtime.now().minute == 0 and shtime.weekday(shtime.today()) == 1: | |
logger.info(f"Logik '{logic.id()}' hat Aktualisierung der Item VORWOCHE angefordert.") | |
logic.calc_vorwoche(logger) | |
if shtime.now().hour == 0 and shtime.now().minute == 0 and shtime.now().day == 1: | |
logger.info(f"Logik '{logic.id()}' hat Aktualisierung der Item VORMONAT angefordert.") | |
logic.calc_vormonat(logger) | |
if shtime.now().hour == 0 and shtime.now().minute == 0 and shtime.now().day == 1 and shtime.now().month == 1 : | |
logger.info(f"Logik '{logic.id()}' hat Aktualisierung der Item VORJAHR angefordert.") | |
logic.calc_vorjahr(logger) | |
if shtime.now().hour == 23 and shtime.now().minute == 59: | |
logger.info(f"Logik '{logic.id()}' hat Aktualisierung der Item ZAEHLERSTAND_TAGESENDE angefordert.") | |
logic.calc_tagesende(logger) | |
elif trigger['by'] == 'Item': | |
item = items.return_item(trigger['source']) | |
counter_item = logic.get_counter_item(logger, item, logic.target_level) | |
if counter_item is not None: | |
logger.info(f"Item {counter_item.id()} hat über Logik '{logic.id()}' die Aktualisierung der Item HEUTE, WOCHE, MONAT, JAHR angefordert.") | |
logic.calc_today(logger, item) | |
elif trigger['by'] == 'Admin': | |
logger.info(f"Logik '{logic.id()}' manuell ausgelöst und Aktualisierung aller Items GESTERN, VORWOCHE, VORMONAT, VORJAHR und ROLLING angefordert.") | |
logic.calc_gestern(logger) | |
logic.calc_rolling(logger) | |
logic.calc_vorwoche(logger) | |
logic.calc_vormonat(logger) | |
logic.calc_vorjahr(logger) | |
logger.info(logic.oldest_log_dict) | |
else: | |
logger.error(f'Database Plugin not active, Logic will be disabled') | |
logic.disable() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment