diff --git a/db_addon/__init__.py b/db_addon/__init__.py
index ebdb2d76e..c77335857 100644
--- a/db_addon/__init__.py
+++ b/db_addon/__init__.py
@@ -34,7 +34,7 @@
import pickle
import operator
from dateutil.relativedelta import relativedelta
-from typing import Union
+from typing import Union, List, Dict
from dataclasses import dataclass, InitVar
from collections import deque
@@ -44,7 +44,6 @@
from lib.shtime import Shtime
from lib.plugin import Plugins
from .webif import WebInterface
-from .item_attributes import *
from .item_attributes_master import ITEM_ATTRIBUTES
import lib.db
@@ -60,7 +59,7 @@ class DatabaseAddOn(SmartPlugin):
Main class of the Plugin. Does all plugin specific stuff and provides the update functions for the items
"""
- PLUGIN_VERSION = '1.2.9'
+ PLUGIN_VERSION = '1.2.10'
def __init__(self, sh):
"""
@@ -70,7 +69,7 @@ def __init__(self, sh):
# Call init code of parent class (SmartPlugin)
super().__init__()
- self.logger.debug(f'Start of {self.get_shortname()} Plugin.')
+ self.logger.debug(f'Start of {self.get_fullname()} Plugin.')
# get item and shtime instance
self.shtime = Shtime.get_instance()
@@ -82,7 +81,7 @@ def __init__(self, sh):
self.current_values = {} # Dict to hold min and max value of current day / week / month / year for items
self.previous_values = {} # Dict to hold value of end of last day / week / month / year for items
self.item_cache = {} # Dict to hold item_id, oldest_log_ts and oldest_entry for items
- self.value_list_raw_data = {} # List to hold raw data
+ self.value_list_raw_data = {} # Dict to hold value list raw data
# define variables for database, database connection, working queue and status
self.item_queue = queue.Queue() # Queue containing all to be executed items
@@ -104,6 +103,7 @@ def __init__(self, sh):
self.default_net_read_timeout = 60
# define variables from plugin parameters
+ self._pause_item_path = self.get_parameter_value('pause_item')
self.db_configname = self.get_parameter_value('database_plugin_config')
self.startup_run_delay = self.get_parameter_value('startup_run_delay')
self.ignore_0 = self.get_parameter_value('ignore_0')
@@ -114,7 +114,7 @@ def __init__(self, sh):
# path and filename for data storage
data_storage_file = 'db_addon_data'
- self.data_storage_path = f"{os.getcwd()}/var/plugin_data/{self.get_shortname()}/{data_storage_file}.pkl"
+ self.data_storage_path = f"{os.getcwd()}/var/plugin_data/{self.get_fullname()}/{data_storage_file}.pkl"
# get debug log options
self.debug_log = DebugLogOptions(self.log_level)
@@ -130,24 +130,24 @@ def run(self):
Run method for the plugin
"""
- self.logger.debug("Run method called")
+ self.logger.dbghigh(self.translate("Methode '{method}' aufgerufen", {'method': 'run()'}))
# check existence of db-plugin, get parameters, and init connection to db
if not self._check_db_existence():
self.logger.error(f"Check of existence of database plugin incl connection check failed. Plugin not loaded")
- return
+ return self.deinit()
# create db object
self._db = lib.db.Database("DatabaseAddOn", self.db_driver, self.connection_data)
if not self._db.api_initialized:
self.logger.error("Initialization of database API failed")
- return
+ return self.deinit()
self.logger.debug("Initialization of database API successful")
# check initialization of db
if not self._initialize_db():
self.logger.error("Connection to database failed")
- return
+ return self.deinit()
self._db.close()
# check db connection settings
@@ -168,6 +168,10 @@ def run(self):
# create list if all relevant database items
self._create_list_of_relevant_database_items()
+ # let the plugin change the state of pause_item
+ if self._pause_item:
+ self._pause_item(False, self.get_fullname())
+
# set plugin to alive
self.alive = True
@@ -179,12 +183,25 @@ def stop(self):
Stop method for the plugin
"""
- self.logger.debug("Stop method called")
+ self.logger.dbghigh(self.translate("Methode '{method}' aufgerufen", {'method': 'stop()'}))
+
+ # set plugin to alive
self.alive = False
- self.scheduler_remove('cyclic')
- self.scheduler_remove('onchange_delay')
+
+ # let the plugin change the state of pause_item
+ if self._pause_item:
+ self._pause_item(True, self.get_fullname())
+
+ # this stops all schedulers the plugin has started.
+ # self.scheduler_remove('cyclic')
+ # self.scheduler_remove('onchange_delay')
+ self.scheduler_remove_all()
+
+ # close db object
if self._db:
self._db.close()
+
+ # save cache data
self.save_cache_data()
def parse_item(self, item: Item):
@@ -206,269 +223,252 @@ def get_query_parameters_from_db_addon_fct() -> Union[dict, None]:
# get parameter
db_addon_fct_vars = db_addon_fct.split('_')
- func = timeframe = timedelta = start = end = group = group2 = data_con_func = log_text = None
- required_params = None
-
- if db_addon_fct in HISTORIE_ATTRIBUTES_ONCHANGE:
- # handle functions 'minmax onchange' in format 'minmax_timeframe_func' items like 'minmax_heute_max', 'minmax_heute_min', 'minmax_woche_max', 'minmax_woche_min'
- timeframe = translate_timeframe(db_addon_fct_vars[1])
- func = db_addon_fct_vars[2] if db_addon_fct_vars[2] in ALLOWED_MINMAX_FUNCS else None
- start = end = 0
- log_text = 'minmax_timeframe_func'
- required_params = [func, timeframe, start, end]
-
- elif db_addon_fct in HISTORIE_ATTRIBUTES_LAST:
- # handle functions 'minmax_last' in format 'minmax_last_timedelta|timeframe_function' like 'minmax_last_24h_max'
- func = db_addon_fct_vars[3]
- start, timeframe = split_sting_letters_numbers(db_addon_fct_vars[2])
- start = to_int(start)
- timeframe = translate_timeframe(timeframe)
- end = 0
- log_text = 'minmax_last_timedelta|timeframe_function'
- required_params = [func, timeframe, start, end]
-
- elif db_addon_fct in HISTORIE_ATTRIBUTES_TIMEFRAME:
- # handle functions 'min/max/avg' in format 'minmax_timeframe_timedelta_func' like 'minmax_heute_minus2_max'
- func = db_addon_fct_vars[3] # min, max, avg
- timeframe = translate_timeframe(db_addon_fct_vars[1]) # day, week, month, year
- start = end = to_int(split_sting_letters_numbers(db_addon_fct_vars[2])[1])
- log_text = 'minmax_timeframe_timedelta_func'
- required_params = [func, timeframe, start, end]
-
- elif db_addon_fct in ZAEHLERSTAND_ATTRIBUTES_TIMEFRAME:
- # handle functions 'zaehlerstand' in format 'zaehlerstand_timeframe_timedelta' like 'zaehlerstand_heute_minus1'
- func = 'last'
- timeframe = translate_timeframe(db_addon_fct_vars[1])
- start = end = to_int(split_sting_letters_numbers(db_addon_fct_vars[2])[1])
- log_text = 'zaehlerstand_timeframe_timedelta'
- required_params = [timeframe, start, end]
-
- elif db_addon_fct in VERBRAUCH_ATTRIBUTES_ONCHANGE:
- # handle functions 'verbrauch onchange' items in format 'verbrauch_timeframe' like 'verbrauch_heute', 'verbrauch_woche', 'verbrauch_monat', 'verbrauch_jahr'
- timeframe = translate_timeframe(db_addon_fct_vars[1])
- start = end = 0
- log_text = 'verbrauch_timeframe'
- required_params = [timeframe, start, end]
-
- elif db_addon_fct in VERBRAUCH_ATTRIBUTES_TIMEFRAME:
- # handle functions 'verbrauch on-demand' in format 'verbrauch_timeframe_timedelta' like 'verbrauch_heute_minus2'
- timeframe = translate_timeframe(db_addon_fct_vars[1])
- start = end = to_int(split_sting_letters_numbers(db_addon_fct_vars[2])[1])
- log_text = 'verbrauch_timeframe_timedelta'
- required_params = [timeframe, start, end]
-
- elif db_addon_fct in VERBRAUCH_ATTRIBUTES_LAST:
- # handle functions 'verbrauch_last' in format 'verbrauch_last_timedelta|timeframe' like 'verbrauch_last_24h'
- start, timeframe = split_sting_letters_numbers(db_addon_fct_vars[2])
- start = to_int(start)
- timeframe = translate_timeframe(timeframe)
- end = 0
- log_text = 'verbrauch_last_timedelta|timeframe'
- required_params = [timeframe, start, end]
-
- elif db_addon_fct in VERBRAUCH_ATTRIBUTES_ROLLING:
- # handle functions 'verbrauch_on-demand' in format 'verbrauch_rolling_window_timeframe_timedelta' like 'verbrauch_rolling_12m_woche_minus1'
- func = db_addon_fct_vars[1]
- window_inc, window_dur = split_sting_letters_numbers(db_addon_fct_vars[2])
- window_inc = to_int(window_inc) # 12
- window_dur = translate_timeframe(window_dur) # day, week, month, year
- timeframe = translate_timeframe(db_addon_fct_vars[3]) # day, week, month, year
- end = to_int(split_sting_letters_numbers(db_addon_fct_vars[4])[1])
- if window_dur in ALLOWED_QUERY_TIMEFRAMES and window_inc and timeframe and end:
- start = to_int(timeframe_to_timeframe(timeframe, window_dur) * window_inc) + end
- log_text = 'verbrauch_rolling_window_timeframe_timedelta'
- required_params = [func, timeframe, start, end]
-
- elif db_addon_fct in VERBRAUCH_ATTRIBUTES_JAHRESZEITRAUM:
- # handle functions of format 'verbrauch_jahreszeitraum_timedelta' like 'verbrauch_jahreszeitraum_minus1'
- timeframe = translate_timeframe(db_addon_fct_vars[1]) # day, week, month, year
- timedelta = to_int(split_sting_letters_numbers(db_addon_fct_vars[2])[1])
- log_text = 'verbrauch_jahreszeitraum_timedelta'
- required_params = [timeframe, timedelta]
-
- elif db_addon_fct in TAGESMITTEL_ATTRIBUTES_ONCHANGE:
- # handle functions 'tagesmitteltemperatur onchange' items in format 'tagesmitteltemperatur_timeframe' like 'tagesmitteltemperatur_heute', 'tagesmitteltemperatur_woche', 'tagesmitteltemperatur_monat', 'tagesmitteltemperatur_jahr'
- timeframe = translate_timeframe(db_addon_fct_vars[1])
- func = 'max'
- start = end = 0
- log_text = 'tagesmitteltemperatur_timeframe'
- required_params = [timeframe, start, end]
-
- elif db_addon_fct in TAGESMITTEL_ATTRIBUTES_TIMEFRAME:
- # handle 'tagesmitteltemperatur_timeframe_timedelta' like 'tagesmitteltemperatur_heute_minus1'
- func = 'max'
- timeframe = translate_timeframe(db_addon_fct_vars[1])
- start = end = to_int(split_sting_letters_numbers(db_addon_fct_vars[2])[1])
- data_con_func = 'first_hour_avg_day'
- log_text = 'tagesmitteltemperatur_timeframe_timedelta'
- required_params = [func, timeframe, start, end, data_con_func]
-
- elif db_addon_fct in SERIE_ATTRIBUTES_MINMAX:
- # handle functions 'serie_minmax' in format 'serie_minmax_timeframe_func_start|group' like 'serie_minmax_monat_min_15m'
- func = db_addon_fct_vars[3]
- timeframe = translate_timeframe(db_addon_fct_vars[2])
- start, group = split_sting_letters_numbers(db_addon_fct_vars[4])
- start = to_int(start)
- group = translate_timeframe(group)
- end = 0
- log_text = 'serie_minmax_timeframe_func_start|group'
- required_params = [func, timeframe, start, end, group]
-
- elif db_addon_fct in SERIE_ATTRIBUTES_ZAEHLERSTAND:
- # handle functions 'serie_zaehlerstand' in format 'serie_zaehlerstand_timeframe_start|group' like 'serie_zaehlerstand_tag_30d'
- timeframe = translate_timeframe(db_addon_fct_vars[2])
- start, group = split_sting_letters_numbers(db_addon_fct_vars[3])
- start = to_int(start)
- group = translate_timeframe(group)
- log_text = 'serie_zaehlerstand_timeframe_start|group'
- required_params = [timeframe, start, group]
-
- elif db_addon_fct in SERIE_ATTRIBUTES_VERBRAUCH:
- # handle all functions of format 'serie_verbrauch_timeframe_start|group' like 'serie_verbrauch_tag_30d'
- timeframe = translate_timeframe(db_addon_fct_vars[2])
- start, group = split_sting_letters_numbers(db_addon_fct_vars[3])
- start = to_int(start)
- group = translate_timeframe(group)
- log_text = 'serie_verbrauch_timeframe_start|group'
- required_params = [timeframe, start, group]
-
- elif db_addon_fct in SERIE_ATTRIBUTES_SUMME:
- # handle all summe in format 'serie_xxsumme_timeframe_count|group' like serie_waermesumme_monat_24m
- func = 'sum_max'
- start, timeframe = split_sting_letters_numbers(db_addon_fct_vars[3])
- start = to_int(start)
- timeframe = translate_timeframe(timeframe)
- end = 0
- group = 'day',
- group2 = 'month'
- log_text = 'serie_xxsumme_timeframe_count|group'
- required_params = [func, timeframe, start, end, group, group2]
-
- elif db_addon_fct in SERIE_ATTRIBUTES_MITTEL_D:
- # handle 'serie_tagesmittelwert_count|group' like 'serie_tagesmittelwert_0d' => Tagesmittelwert der letzten 0 Tage (also heute)
- func = 'max'
- timeframe = 'year'
- start, group = split_sting_letters_numbers(db_addon_fct_vars[2])
- start = to_int(start)
- group = translate_timeframe(group)
- end = 0
- log_text = 'serie_tagesmittelwert_count|group'
- required_params = [func, timeframe, start, end, group]
-
- elif db_addon_fct in SERIE_ATTRIBUTES_MITTEL_H:
- # handle 'serie_tagesmittelwert_group2_count|group' like 'serie_tagesmittelwert_stunde_0d' => Stundenmittelwerte der letzten 0 Tage (also heute)
- func = 'avg1'
- timeframe = 'day'
- end = 0
- group = 'hour'
- start, group2 = split_sting_letters_numbers(db_addon_fct_vars[3])
- start = to_int(start)
- group2 = translate_timeframe(group2)
- log_text = 'serie_tagesmittelwert_group2_count|group'
- required_params = [func, timeframe, start, end, group, group2]
-
- elif db_addon_fct in SERIE_ATTRIBUTES_MITTEL_H1:
- # handle 'serie_tagesmittelwert_stunde_start_end|group' like 'serie_tagesmittelwert_stunde_30_0d' => Stundenmittelwerte von vor 30 Tagen bis vor 0 Tagen (also heute)
- data_con_func = 'avg_hour'
- start = to_int(db_addon_fct_vars[3])
- end, timeframe = split_sting_letters_numbers(db_addon_fct_vars[4])
- end = to_int(end)
- timeframe = translate_timeframe(timeframe)
- log_text = 'serie_tagesmittelwert_stunde_start_end|group'
- required_params = [timeframe, data_con_func, start, end]
-
- elif db_addon_fct in SERIE_ATTRIBUTES_MITTEL_D_H:
- # handle 'serie_tagesmittelwert_tag_stunde_end|group' like 'serie_tagesmittelwert_tag_stunde_30d' => Tagesmittelwert auf Basis des Mittelwerts pro Stunden für die letzten 30 Tage
- data_con_func = 'first_hour_avg_day'
- end = 0
- start, timeframe = split_sting_letters_numbers(db_addon_fct_vars[4])
- start = to_int(start)
- timeframe = translate_timeframe(timeframe)
- log_text = 'serie_tagesmittelwert_tag_stunde_end|group'
- required_params = [timeframe, data_con_func, start, end]
-
- elif db_addon_fct in ALL_GEN_ATTRIBUTES:
- log_text = 'all_gen_attributes'
- required_params = []
-
- if required_params is None:
+ func = timeframe = timedelta = start = end = group = group2 = data_con_func = None
+ mandatory_params = None
+
+ # handle all functions of cat 'wertehistorie'
+ if db_addon_fct_cat == 'wertehistorie':
+
+ # handle functions of sub_cat 'onchange' like 'minmax_heute_max', 'minmax_heute_min', 'minmax_woche_max', 'minmax_woche_min'
+ if db_addon_fct_sub_cat == 'onchange':
+ timeframe = translate_timeframe(db_addon_fct_vars[1])
+ func = db_addon_fct_vars[2] if db_addon_fct_vars[2] in ALLOWED_MINMAX_FUNCS else None
+ start = end = 0
+ mandatory_params = [func, timeframe, start, end]
+
+ # handle functions of sub_cat 'last' like 'minmax_last' in format 'minmax_last_timedelta|timeframe_function' like 'minmax_last_24h_max'
+ elif db_addon_fct_sub_cat == 'last':
+ func = db_addon_fct_vars[3]
+ start, timeframe = split_sting_letters_numbers(db_addon_fct_vars[2])
+ start = to_int(start)
+ timeframe = translate_timeframe(timeframe)
+ end = 0
+ mandatory_params = [func, timeframe, start, end]
+
+ # handle functions of sub_cat 'timeframe' like 'min/max/avg' in format 'minmax_timeframe_timedelta_func' like 'minmax_heute_minus2_max'
+ elif db_addon_fct_sub_cat == 'timeframe':
+ func = db_addon_fct_vars[3] # min, max, avg
+ timeframe = translate_timeframe(db_addon_fct_vars[1]) # day, week, month, year
+ start = end = to_int(split_sting_letters_numbers(db_addon_fct_vars[2])[1])
+ mandatory_params = [func, timeframe, start, end]
+
+ # handle all functions of cat 'zaehlerstand'
+ elif db_addon_fct_cat == 'zaehler':
+
+ # handle functions of sub_cat 'timeframe' like 'zaehlerstand_timeframe_timedelta' like 'zaehlerstand_heute_minus1'
+ if db_addon_fct_sub_cat == 'timeframe':
+ func = 'last'
+ timeframe = translate_timeframe(db_addon_fct_vars[1])
+ start = end = to_int(split_sting_letters_numbers(db_addon_fct_vars[2])[1])
+ mandatory_params = [func, timeframe, start, end]
+
+ # handle all functions of cat 'verbrauch'
+ elif db_addon_fct_cat == 'verbrauch':
+ # 'start' ist das Zeitinkrement von jetzt (0) für den Zählerstand zu Beginn der Betrachtung; 'end' ist das Zeitinkrement von jetzt (0) für den Zählerstand zum Ende der Betrachtung
+
+ # handle functions of sub_cat 'onchange' in format 'verbrauch_timeframe' like 'verbrauch_heute', 'verbrauch_woche', 'verbrauch_monat', 'verbrauch_jahr'
+ if db_addon_fct_sub_cat == 'onchange':
+ timeframe = translate_timeframe(db_addon_fct_vars[1])
+ end = 0
+ start = end + 1
+ mandatory_params = [timeframe, start, end]
+
+ # handle functions of sub_cat 'last' in format 'verbrauch_last_timedelta|timeframe' like 'verbrauch_last_24h'
+ elif db_addon_fct_sub_cat == 'last':
+ start, timeframe = split_sting_letters_numbers(db_addon_fct_vars[2])
+ start = to_int(start)
+ timeframe = translate_timeframe(timeframe)
+ end = 0
+ mandatory_params = [timeframe, start, end]
+
+ # handle functions of sub_cat 'timeframe' in format 'verbrauch_timeframe_timedelta' like 'verbrauch_heute_minus2'
+ elif db_addon_fct_sub_cat == 'timeframe':
+ timeframe = translate_timeframe(db_addon_fct_vars[1])
+ end = to_int(split_sting_letters_numbers(db_addon_fct_vars[2])[1])
+ start = end + 1
+ mandatory_params = [timeframe, start, end]
+
+ # handle functions of sub_cat 'rolling' in format 'verbrauch_rolling_window_timeframe_timedelta' like 'verbrauch_rolling_12m_woche_minus1'
+ elif db_addon_fct_sub_cat == 'rolling':
+ func = db_addon_fct_vars[1]
+ window_inc, window_dur = split_sting_letters_numbers(db_addon_fct_vars[2])
+ window_inc = to_int(window_inc) # 12
+ window_dur = translate_timeframe(window_dur) # day, week, month, year
+ timeframe = translate_timeframe(db_addon_fct_vars[3]) # day, week, month, year
+ end = to_int(split_sting_letters_numbers(db_addon_fct_vars[4])[1])
+ if window_dur in ALLOWED_QUERY_TIMEFRAMES and window_inc and timeframe and end:
+ start = to_int(timeframe_to_timeframe(timeframe, window_dur) * window_inc) + end
+ mandatory_params = [func, timeframe, start, end]
+
+ # handle functions of sub_cat 'jahrzeit' in format 'verbrauch_jahreszeitraum_timedelta' like 'verbrauch_jahreszeitraum_minus1'
+ elif db_addon_fct_sub_cat == 'jahrzeit':
+ timeframe = translate_timeframe(db_addon_fct_vars[1]) # day, week, month, year
+ timedelta = to_int(split_sting_letters_numbers(db_addon_fct_vars[2])[1])
+ mandatory_params = [timeframe, timedelta]
+
+ # handle all functions of cat 'tagesmittel'
+ elif db_addon_fct_cat == 'tagesmittel':
+
+ # handle functions of sub_cat 'onchange' like 'tagesmitteltemperatur_timeframe' like 'tagesmitteltemperatur_heute', 'tagesmitteltemperatur_woche', 'tagesmitteltemperatur_monat', 'tagesmitteltemperatur_jahr'
+ if db_addon_fct_sub_cat == 'onchange':
+ timeframe = translate_timeframe(db_addon_fct_vars[1])
+ start = end = 0
+ mandatory_params = [timeframe, start, end]
+
+ # handle functions of sub_cat 'timeframe' like 'tagesmitteltemperatur_timeframe_timedelta' like 'tagesmitteltemperatur_heute_minus1'
+ elif db_addon_fct_sub_cat == 'timeframe':
+ timeframe = translate_timeframe(db_addon_fct_vars[1])
+ start = end = to_int(split_sting_letters_numbers(db_addon_fct_vars[2])[1])
+ data_con_func = 'first_hour_avg_day'
+ mandatory_params = [timeframe, start, end, data_con_func]
+
+ # handle all functions of cat 'serie'
+ elif db_addon_fct_cat == 'serie':
+
+ # handle functions of sub_cat 'wertehistorie' in format 'serie_minmax_timeframe_func_start|group' like 'serie_minmax_monat_min_15m'
+ if db_addon_fct_sub_cat == 'wertehistorie':
+ func = db_addon_fct_vars[3]
+ timeframe = translate_timeframe(db_addon_fct_vars[2])
+ start, group = split_sting_letters_numbers(db_addon_fct_vars[4])
+ start = to_int(start)
+ group = translate_timeframe(group)
+ end = 0
+ mandatory_params = [func, timeframe, start, end, group]
+
+ # handle functions of sub_cat 'zaehler' in format 'serie_zaehlerstand_timeframe_start|group' like 'serie_zaehlerstand_tag_30d'
+ elif db_addon_fct_sub_cat == 'zaehler':
+ timeframe = translate_timeframe(db_addon_fct_vars[2])
+ start, group = split_sting_letters_numbers(db_addon_fct_vars[3])
+ start = to_int(start)
+ group = translate_timeframe(group)
+ mandatory_params = [timeframe, start, group]
+
+ # handle functions of sub_cat 'verbrauch' in format 'serie_verbrauch_timeframe_start|group' like 'serie_verbrauch_tag_30d'
+ elif db_addon_fct_sub_cat == 'verbrauch':
+ timeframe = translate_timeframe(db_addon_fct_vars[2])
+ start, group = split_sting_letters_numbers(db_addon_fct_vars[3])
+ start = to_int(start)
+ group = translate_timeframe(group)
+ mandatory_params = [timeframe, start, group]
+
+ # handle functions of sub_cat 'summe' in format 'serie_xxsumme_timeframe_count|group' like serie_waermesumme_monat_24m
+ elif db_addon_fct_sub_cat == 'summe':
+ func = 'sum_max'
+ start, timeframe = split_sting_letters_numbers(db_addon_fct_vars[3])
+ start = to_int(start)
+ timeframe = translate_timeframe(timeframe)
+ end = 0
+ group = 'day',
+ group2 = 'month'
+ mandatory_params = [func, timeframe, start, end, group, group2]
+
+ # handle functions of sub_cat 'mittel_d' in format 'serie_tagesmittelwert_count|group' like 'serie_tagesmittelwert_0d' => Tagesmittelwert der letzten 0 Tage (also heute)
+ elif db_addon_fct_sub_cat == 'mittel_d':
+ func = 'max'
+ timeframe = 'year'
+ start, group = split_sting_letters_numbers(db_addon_fct_vars[2])
+ start = to_int(start)
+ group = translate_timeframe(group)
+ end = 0
+ mandatory_params = [func, timeframe, start, end, group]
+
+ # handle functions of sub_cat 'mittel_h' in format 'serie_tagesmittelwert_group2_count|group' like 'serie_tagesmittelwert_stunde_0d' => Stundenmittelwerte der letzten 0 Tage (also heute)
+ elif db_addon_fct_sub_cat == 'mittel_h':
+ func = 'avg1'
+ timeframe = 'day'
+ end = 0
+ group = 'hour'
+ start, group2 = split_sting_letters_numbers(db_addon_fct_vars[3])
+ start = to_int(start)
+ group2 = translate_timeframe(group2)
+ mandatory_params = [func, timeframe, start, end, group, group2]
+
+ # handle functions of sub_cat 'mittel_h1' in format 'serie_tagesmittelwert_stunde_start_end|group' like 'serie_tagesmittelwert_stunde_30_0d' => Stundenmittelwerte von vor 30 Tagen bis vor 0 Tagen (also heute)
+ elif db_addon_fct_sub_cat == 'mittel_h1':
+ data_con_func = 'avg_hour'
+ start = to_int(db_addon_fct_vars[3])
+ end, timeframe = split_sting_letters_numbers(db_addon_fct_vars[4])
+ end = to_int(end)
+ timeframe = translate_timeframe(timeframe)
+ mandatory_params = [timeframe, data_con_func, start, end]
+
+ # handle functions of sub_cat 'mittel_d_h' in format 'serie_tagesmittelwert_tag_stunde_end|group' like 'serie_tagesmittelwert_tag_stunde_30d' => Tagesmittelwert auf Basis des Mittelwerts pro Stunden für die letzten 30 Tage
+ elif db_addon_fct_sub_cat == 'mittel_d_h':
+ data_con_func = 'first_hour_avg_day'
+ end = 0
+ start, timeframe = split_sting_letters_numbers(db_addon_fct_vars[4])
+ start = to_int(start)
+ timeframe = translate_timeframe(timeframe)
+ mandatory_params = [timeframe, data_con_func, start, end]
+
+ # handle functions of cat 'generic'
+ elif db_addon_fct_cat == 'gen':
+ mandatory_params = []
+
+ if mandatory_params is None:
self.logger.warning(f"For calculating '{db_addon_fct}' at Item '{item.property.path}' no mandatory parameters given.")
- return
-
- if required_params and None in required_params:
- self.logger.warning(f"For calculating '{db_addon_fct}' at Item '{item.property.path}' not all mandatory parameters given. Definitions are: {func=}, {timeframe=}, {timedelta=}, {start=}, {end=}, {group=}, {group2=}, {data_con_func=}")
- return
+ return None
- # create dict and reduce dict to keys with value != None
- param_dict = {'func': func, 'timeframe': timeframe, 'timedelta': timedelta, 'start': start, 'end': end, 'group': group, 'group2': group2, 'data_con_func': data_con_func}
+ if None in mandatory_params:
+ missing_params = [attr for attr, val in zip(['func', 'timeframe', 'timedelta', 'start', 'end', 'group', 'group2', 'data_con_func'], mandatory_params) if val is None]
+ self.logger.warning(f"Missing mandatory parameters for {db_addon_fct} at Item '{item.property.path}'. mandatory parameters={', '.join(missing_params)}")
+ return None
- # return reduced dict w keys with value != None
- return {k: v for k, v in param_dict.items() if v is not None}
+ return {k: v for k, v in locals().items() if k in ['func', 'timeframe', 'timedelta', 'start', 'end', 'group', 'group2', 'data_con_func'] and v is not None}
def get_query_parameters_from_db_addon_params() -> Union[dict, None]:
- """derives parameters from item attribute db_addon_params, if parameter for db_addon_fct are not sufficient
-
- possible_params may be given, if not, default value is used
- required_params must be given
+ """Derives parameters from item attribute db_addon_params, if parameter for db_addon_fct are not sufficient.
+ Possible_params may be given if not, the default value is used. mandatory_params must be given.
"""
- db_addon_params = params_to_dict(self.get_iattr_value(item.conf, 'db_addon_params'))
-
- if not db_addon_params:
- db_addon_params = self.get_iattr_value(item.conf, 'db_addon_params_dict')
+ # get required, optional and additional params for db_addon_func
+ mandatory_params, optional_params, additional_params = item_attribute_dict['params']
- if not db_addon_params:
- db_addon_params = {}
+ # get db_addon_params from item
+ db_addon_params = params_to_dict(self.get_iattr_value(item.conf, 'db_addon_params')) or self.get_iattr_value(item.conf, 'db_addon_params_dict') or {}
- new_db_addon_params = {}
- possible_params = required_params = []
-
- # create item config for all functions with 'summe' like waermesumme, kaeltesumme, gruenlandtemperatursumme
- if db_addon_fct in ('kaeltesumme', 'waermesumme', 'gruenlandtempsumme'):
- possible_params = ['year', 'month']
-
- # create item config for wachstumsgradtage attributes
- elif db_addon_fct == 'wachstumsgradtage':
- possible_params = ['year', 'variant', 'threshold', 'result']
-
- # create item config for kenntage attributes
- elif db_addon_fct in ('wuestentage', 'heisse_tage', 'tropennaechte', 'sommertage', 'heiztage', 'vegetationstage', 'frosttage', 'eistage'):
- possible_params = ['year', 'month']
-
- # create item config for tagesmitteltemperatur
- elif db_addon_fct == 'tagesmitteltemperatur':
- possible_params = ['timeframe', 'count']
+ # check if all required params are given
+ if not all(param in db_addon_params for param in mandatory_params):
+ self.logger.warning(f"Item '{item.property.path}' with {db_addon_fct=} ignored, since not all mandatory parameters {mandatory_params=} in {db_addon_params=} are given.")
+ return None
- # create item config for minmax
- elif db_addon_fct == 'minmax':
- required_params = ['func', 'timeframe', 'start']
+ # reduce db_addon_params from item to (optional_params + mandatory_params)
+ new_db_addon_params = {k: v for k, v in db_addon_params.items() if k in (optional_params + mandatory_params)} if db_addon_params else {}
- # create item config for minmax_last
- elif db_addon_fct == 'minmax_last':
- required_params = ['func', 'timeframe', 'start', 'end']
+ # check if parameter values are valid
+ if 'func' in new_db_addon_params:
+ if (db_addon_fct_cat == 'wertehistorie' and new_db_addon_params['func'] not in ALLOWED_MINMAX_FUNCS) or (db_addon_fct_cat == 'complex' and new_db_addon_params['func'] not in ALLOWED_QUERY_FUNCS):
+ self.logger.warning(f"Parameter 'func'={new_db_addon_params['timeframe']} of item '{item.property.path}' not valid. Item will be ignored.")
+ return None
- # create item config for verbrauch
- elif db_addon_fct == 'verbrauch':
- required_params = ['timeframe', 'start', 'end']
+ if 'timeframe' in new_db_addon_params and new_db_addon_params['timeframe'] not in ALLOWED_QUERY_TIMEFRAMES:
+ self.logger.warning(f"Parameter 'timeframe'={new_db_addon_params['timeframe']} of item '{item.property.path}' not valid. Valid parameter values: {ALLOWED_QUERY_TIMEFRAMES}. Item will be ignored.")
+ return None
- # create item config for zaehlerstand
- elif db_addon_fct == 'zaehlerstand':
- required_params = ['timeframe', 'start']
+ for param in ['start', 'end', 'threshold']:
+ if param in new_db_addon_params:
+ new_value = to_int(new_db_addon_params[param])
+ if new_value is None:
+ self.logger.warning(f"Parameter '{param}'={new_db_addon_params[param]} of item '{item.property.path}' not valid. Parameter value need to be integer. Item will be ignored.")
+ return None
+ else:
+ new_db_addon_params[param] = new_value
+
+ if 'year' in new_db_addon_params and not self._valid_year(new_db_addon_params['year']):
+ self.logger.warning(f"Parameter 'year'={new_db_addon_params['year']} of item '{item.property.path}' not valid. Item will be ignored.")
+ return None
- # create item config for db_request and everything else (get_query_parameters_from_db_addon_fct)
- else:
- required_params = ['func', 'timeframe']
- possible_params = ['start', 'end', 'group', 'group2', 'ignore_value_list', 'use_oldest_entry']
+ if 'month' in new_db_addon_params and not self._valid_month(new_db_addon_params['month']):
+ self.logger.warning(f"Parameter 'month'={new_db_addon_params['month']} of item '{item.property.path}' not valid. Item will be ignored.")
+ return None
- if required_params and not any(param in db_addon_params for param in required_params):
- self.logger.warning(f"Item '{item.property.path}' with {db_addon_fct=} ignored, since not all mandatory parameters in {db_addon_params=} are given. Item will be ignored.")
- return
+ if 'result' in new_db_addon_params and new_db_addon_params['result'] not in ALLOWED_RESULT_TYPES:
+ self.logger.warning(f"Parameter 'result'={new_db_addon_params['result']} of item '{item.property.path}' not valid. Valid parameter values: {ALLOWED_RESULT_TYPES}. Item will be ignored.")
+ return None
- # reduce dict to possible keys + required_params
- for key in possible_params + required_params:
- value = db_addon_params.get(key)
- if value:
- new_db_addon_params[key] = value
+ # add additional params
+ if additional_params:
+ new_db_addon_params.update(additional_params)
return new_db_addon_params
@@ -509,15 +509,6 @@ def get_database_item() -> Item:
return None, None
- def check_db_addon_fct(check_item) -> bool:
- """
- Check if item has db_addon_fct and is onchange
- """
- if self.has_iattr(check_item.conf, 'db_addon_fct'):
- if self.get_iattr_value(check_item.conf, 'db_addon_fct').lower() in ONCHANGE_ATTRIBUTES:
- return True
- return False
-
def format_db_addon_ignore_value_list(optimize: bool = self.optimize_value_filter):
""" Check of list of comparison operators is formally valid """
@@ -581,6 +572,51 @@ def format_db_addon_ignore_value_list(optimize: bool = self.optimize_value_filte
return db_addon_ignore_value_list_optimized
+ # ToDo: check new coding
+ def format_db_addon_ignore_value_list_new(_db_addon_ignore_value_list: List[str], debug_log=False) -> Union[List[str], None]:
+
+ max_values = {'!=': [], '>=': [], '<=': [], '>': [], '<': []}
+ db_addon_ignore_value_list_formatted = []
+
+ for _entry in _db_addon_ignore_value_list:
+ _entry = entry.strip()
+ for _op in max_values.keys():
+ if _op in _entry:
+ _, _value = _entry.split(_op, 1)
+ _value = to_int_float(_value.strip())
+ if _value is not None:
+ db_addon_ignore_value_list_formatted.append(f"{_op} {_value}")
+ max_values[_op].append(_value)
+
+ if debug_log:
+ self.logger.debug(f"Summarized 'ignore_value_list': {db_addon_ignore_value_list_formatted}")
+
+ if not db_addon_ignore_value_list_formatted:
+ return None
+
+ # Optimizing the list
+ lower_values = max(max_values['<'] + max_values['<='], default=None)
+ upper_values = min(max_values['>'] + max_values['>='], default=None)
+
+ db_addon_ignore_value_list_optimized = [
+ f"< {lower_values}" if lower_values is not None else None,
+ f"> {upper_values}" if upper_values is not None else None
+ ] + [f"!= {v}" for v in max_values['!='] if (not lower_values or v >= lower_values) and (not upper_values or v <= upper_values)]
+
+ db_addon_ignore_value_list_optimized = list(filter(None, db_addon_ignore_value_list_optimized))
+
+ if debug_log:
+ self.logger.debug(f"Optimized 'ignore_value_list': {db_addon_ignore_value_list_optimized}")
+
+ return db_addon_ignore_value_list_optimized
+
+ # check for pause item
+ if item.property.path == self._pause_item_path:
+ self.logger.debug(f'pause item {item.property.path} registered')
+ self._pause_item = item
+ self.add_item(item, updating=True)
+ return self.update_item
+
# handle all items with db_addon_fct
if self.has_iattr(item.conf, 'db_addon_fct'):
@@ -591,7 +627,9 @@ def format_db_addon_ignore_value_list(optimize: bool = self.optimize_value_filte
db_addon_fct = self.get_iattr_value(item.conf, 'db_addon_fct').lower()
# read item_attribute_dict aus item_attributes_master
- item_attribute_dict = ITEM_ATTRIBUTES['db_addon_fct'].get(db_addon_fct)
+ item_attribute_dict = ITEM_ATTRIBUTES['db_addon_fct'].get(db_addon_fct, {})
+ db_addon_fct_cat = item_attribute_dict['cat']
+ db_addon_fct_sub_cat = item_attribute_dict['sub_cat']
# get query parameters from db_addon_fct or db_addon_params
if item_attribute_dict['params']:
@@ -638,7 +676,7 @@ def format_db_addon_ignore_value_list(optimize: bool = self.optimize_value_filte
query_params.update({'ignore_value_list': db_addon_ignore_value_list_final})
# create standard items config
- item_config_data_dict = {'db_addon': 'function', 'db_addon_fct': db_addon_fct, 'database_item': database_item, 'query_params': query_params, 'suspended': False}
+ item_config_data_dict = {'db_addon': 'function', 'db_addon_fct': db_addon_fct, 'database_item': database_item, 'query_params': query_params, 'suspended': False, 'cat': db_addon_fct_cat, 'sub_cat': db_addon_fct_sub_cat}
if isinstance(database_item, str):
item_config_data_dict.update({'database_item_path': True})
else:
@@ -688,13 +726,13 @@ def format_db_addon_ignore_value_list(optimize: bool = self.optimize_value_filte
elif self.has_iattr(item.conf, 'db_addon_info'):
if self.debug_log.parse:
self.logger.debug(f"parse item={item.property.path} due to used item attribute 'db_addon_info'")
- self.add_item(item, config_data_dict={'db_addon': 'info', 'db_addon_fct': f"info_{self.get_iattr_value(item.conf, 'db_addon_info').lower()}", 'database_item': None, 'startup': True})
+ self.add_item(item, config_data_dict={'db_addon': 'info', 'db_addon_fct': f"info_{self.get_iattr_value(item.conf, 'db_addon_info').lower()}", 'database_item': None, 'startup': True, 'cat': 'info', 'sub_cat': None})
# handle all items with db_addon_admin
elif self.has_iattr(item.conf, 'db_addon_admin'):
if self.debug_log.parse:
self.logger.debug(f"parse item={item.property.path} due to used item attribute 'db_addon_admin'")
- self.add_item(item, config_data_dict={'db_addon': 'admin', 'db_addon_fct': f"admin_{self.get_iattr_value(item.conf, 'db_addon_admin').lower()}", 'database_item': None})
+ self.add_item(item, config_data_dict={'db_addon': 'admin', 'db_addon_fct': f"admin_{self.get_iattr_value(item.conf, 'db_addon_admin').lower()}", 'database_item': None, 'cat': 'admin', 'sub_cat': None})
return self.update_item
# Reference to 'update_item' for all database items to trigger calculation of on-change items
@@ -713,7 +751,17 @@ def update_item(self, item, caller=None, source=None, dest=None):
:param dest: if given it represents the dest
"""
- if self.alive and caller != self.get_shortname():
+ # check for pause item
+ if item is self._pause_item:
+ if caller != self.get_fullname():
+ self.logger.debug(f'pause item changed to {item()}')
+ if item() and self.alive:
+ self.stop()
+ elif not item() and not self.alive:
+ self.run()
+ return
+
+ if self.alive and caller != self.get_fullname():
# handle database items
if item in self._database_items():
self.logger.debug(f" Updated Item {item.property.path} with value {item()} will be put to queue in approx. {self.onchange_delay_time}s resp. after startup.")
@@ -722,14 +770,12 @@ def update_item(self, item, caller=None, source=None, dest=None):
# handle admin items
elif self.has_iattr(item.conf, 'db_addon_admin'):
self.logger.debug(f"update_item was called with item {item.property.path} from caller {caller}, source {source} and dest {dest}")
- if self.get_iattr_value(item.conf, 'db_addon_admin') == 'suspend':
- self.suspend(item())
- elif self.get_iattr_value(item.conf, 'db_addon_admin') == 'recalc_all':
+ if self.get_iattr_value(item.conf, 'db_addon_admin') == 'recalc_all':
self.execute_all_items()
- item(False, self.get_shortname())
+ item(False, self.get_fullname())
elif self.get_iattr_value(item.conf, 'db_addon_admin') == 'clean_cache_values':
self._init_cache_dicts()
- item(False, self.get_shortname())
+ item(False, self.get_fullname())
def _save_pickle(self, data) -> None:
"""Saves received data as pickle to given file"""
@@ -912,7 +958,7 @@ def _create_due_items() -> list:
_reset_items.update(set(self._onchange_yearly_items()))
# reset der onchange items
- [_item(0, self.get_shortname()) for _item in _reset_items]
+ [_item(0, self.get_fullname()) for _item in _reset_items]
return list(_todo_items)
@@ -998,9 +1044,13 @@ def handle_ondemand(self, item: Item) -> None:
# get parameters
item_config = self.get_item_config(item)
+
if self.debug_log.ondemand:
self.logger.debug(f"Item={item.property.path} with {item_config=}")
+
db_addon_fct = item_config['db_addon_fct']
+ db_addon_fct_cat = item_config['cat']
+ db_addon_fct_sub_cat = item_config['sub_cat']
database_item = item_config['database_item']
query_params = item_config.get('query_params')
if query_params:
@@ -1009,45 +1059,53 @@ def handle_ondemand(self, item: Item) -> None:
else:
params = {}
+ # set default result
+ result = None
+
if self.debug_log.ondemand:
self.logger.debug(f"{db_addon_fct=} will _query_item with {params=}.")
- # handle item starting with 'verbrauch_'
- if db_addon_fct in ALL_VERBRAUCH_ATTRIBUTES:
+ # handle all items of category 'verbrauch'
+ if db_addon_fct_cat == 'verbrauch':
result = self._handle_verbrauch(params)
if result and result < 0:
self.logger.info(f"Result of item {item.property.path} with {db_addon_fct=} was negative. Something seems to be wrong.")
- # handle 'serie_verbrauch'
- elif db_addon_fct in SERIE_ATTRIBUTES_VERBRAUCH:
- result = self._handle_verbrauch_serie(params)
-
- # handle item starting with 'zaehlerstand_'
- elif db_addon_fct in ALL_ZAEHLERSTAND_ATTRIBUTES:
+ # handle all items of category 'zaehler'
+ elif db_addon_fct_cat == 'zaehler':
result = self._handle_zaehlerstand(params)
- # handle 'serie_zaehlerstand'
- elif db_addon_fct in SERIE_ATTRIBUTES_ZAEHLERSTAND:
- result = self._handle_zaehlerstand_serie(params)
+ # handle all items of category 'serie'
+ elif db_addon_fct_cat == 'serie':
- # handle 'serie_tagesmittelwert_stunde_30_0d' and 'serie_tagesmittelwert_tag_stunde_30d'
- elif db_addon_fct in SERIE_ATTRIBUTES_MITTEL_H1 + SERIE_ATTRIBUTES_MITTEL_D_H:
- result = self._prepare_value_list(**params)
+ # handle all items of sub_category 'verbrauch'
+ if db_addon_fct_sub_cat == 'verbrauch':
+ result = self._handle_verbrauch_serie(params)
- # handle TAGESMITTEL_ATTRIBUTES_TIMEFRAME like tagesmitteltemperatur_heute_minus1
- elif db_addon_fct in TAGESMITTEL_ATTRIBUTES_TIMEFRAME:
+ # handle all items of sub_category 'zaehler'
+ elif db_addon_fct_sub_cat == 'zaehler':
+ result = self._handle_zaehlerstand_serie(params)
- params.update({'data_con_func': 'first_hour_avg_day'})
- _result = self._prepare_value_list(**params)
+ # handle items of sub_category 'mittel_h1' and 'mittel_h_d' like 'serie_tagesmittelwert_stunde_30_0d' and 'serie_tagesmittelwert_tag_stunde_30d'
+ elif db_addon_fct_sub_cat in ['mittel_h1', 'mittel_h_d']:
+ result = self._prepare_value_list(**params)
- if isinstance(_result, list):
- result = _result[0][1]
- else:
- result = None
+ # handle all items of category 'tagesmittel'
+ elif db_addon_fct_cat == 'tagesmittel':
+
+ # handle all items of sub_category 'timeframe' like tagesmitteltemperatur_heute_minus1
+ if db_addon_fct_sub_cat == 'timeframe':
+ _result = self._prepare_value_list(**params)
- # handle all functions using temperature sums
- elif db_addon_fct in ALL_SUMME_ATTRIBUTES:
+ if isinstance(_result, list):
+ result = _result[0][1]
+
+ elif db_addon_fct_sub_cat == 'complex':
+ result = self._prepare_value_list(**params)
+
+ # handle all items of category 'summe'
+ elif db_addon_fct_cat == 'summe':
new_params = {}
for entry in ('threshold', 'variant', 'result', 'data_con_func'):
if entry in params:
@@ -1066,7 +1124,7 @@ def handle_ondemand(self, item: Item) -> None:
elif db_addon_fct == 'general_oldest_log':
result = self._get_oldest_log(database_item)
- # handle everything else
+ # handle everything else link db_request, minmax
else:
result = self._query_item(**params)[0][1]
@@ -1082,7 +1140,7 @@ def handle_ondemand(self, item: Item) -> None:
self.logger.info(f" Item value for '{item.property.path}' will be set to {result}")
item_config = self.get_item_config(item)
item_config.update({'value': result})
- item(result, self.get_shortname())
+ item(result, self.get_fullname())
def handle_onchange(self, updated_item: Item, value: float) -> None:
"""
@@ -1191,38 +1249,36 @@ def handle_tagesmittel():
item_config = self.get_item_config(item)
if self.debug_log.onchange:
self.logger.debug(f"Item={item.property.path} with {item_config=}")
- db_addon_fct = item_config['db_addon_fct']
+ db_addon_fct_cat = item_config['cat']
+ db_addon_fct_sub_cat = item_config['sub_cat']
database_item = item_config['database_item']
timeframe = item_config['query_params']['timeframe']
func = item_config['query_params'].get('func')
ignore_value_list = item_config['query_params'].get('ignore_value_list')
new_value = None
- # handle all non on_change functions
- if db_addon_fct not in ONCHANGE_ATTRIBUTES:
+ # handle all on_demand functions
+ if db_addon_fct_sub_cat != 'onchange':
if self.debug_log.onchange:
- self.logger.debug(f"non onchange function detected. Skip update.")
+ self.logger.debug(f"on demand function detected. Skip update.")
continue
- # handle minmax onchange items tagesmitteltemperatur_heute, minmax_heute_avg
- if db_addon_fct in TAGESMITTEL_ATTRIBUTES_ONCHANGE:
+ # handle onchange tagesmittel items like tagesmitteltemperatur_heute
+ if db_addon_fct_cat == 'tagesmittel':
new_value = handle_tagesmittel()
- # handle minmax onchange items like minmax_heute_max, minmax_heute_min, minmax_woche_max, minmax_woche_min.....
- elif db_addon_fct.startswith('minmax'):
+ # handle all onchange wertehistorie items like minmax_heute_max, minmax_heute_min, minmax_woche_max, minmax_woche_min.....
+ elif db_addon_fct_cat == 'wertehistorie':
new_value = handle_minmax()
- # handle verbrauch onchange items ending with heute, woche, monat, jahr
- elif db_addon_fct.startswith('verbrauch'):
+ # handle onchange verbrauch items like verbrauch_heute
+ elif db_addon_fct_cat == 'verbrauch':
new_value = handle_verbrauch()
- if new_value is None:
- continue
-
self.logger.info(f" Item value for '{item.property.path}' with func={func} will be set to {new_value}")
item_config = self.get_item_config(item)
item_config.update({'value': new_value})
- item(new_value, self.get_shortname())
+ item(new_value, self.get_fullname())
def _update_database_items(self) -> None:
"""Turns given as database_item path into database_items"""
@@ -1237,11 +1293,12 @@ def _update_database_items(self) -> None:
else:
item_config.update({'database_item': database_item})
db_addon_startup = bool(self.get_iattr_value(database_item.conf, 'db_addon_startup'))
+ del item_config['database_item_path']
if db_addon_startup:
item_config.update({'startup': True})
def _suspend_item_calculation(self, item: Union[str, Item], suspended: bool = False) -> Union[bool, None]:
- """suspend calculation od dedicated item"""
+ """suspend calculation of dedicated item"""
if isinstance(item, str):
item = self.items.return_item(item)
@@ -1352,7 +1409,7 @@ def _all_items(self) -> list:
# Public functions / Using item_path
#########################################
- def gruenlandtemperatursumme(self, item_path: str, year: Union[int, str] = None, ignore_value_list: list = None) -> Union[int, None]:
+ def gruenlandtemperatursumme(self, item_path: str, year: Union[int, str] = None, ignore_value_list: list = None, result: str = 'total') -> Union[int, None]:
"""
Query database for gruenlandtemperatursumme for given year or year
https://de.wikipedia.org/wiki/Gr%C3%BCnlandtemperatursumme
@@ -1364,14 +1421,15 @@ def gruenlandtemperatursumme(self, item_path: str, year: Union[int, str] = None,
:param item_path: item object or item_id for which the query should be done
:param year: year the gruenlandtemperatursumme should be calculated for
:param ignore_value_list: list of comparison operators for val_num, which will be applied during query
+ :param result: total-Gesamtwert, month-Serie mit Monatswerten, day-Serie mit Tageswerten (default: total)
:return: gruenlandtemperatursumme
"""
item = self.items.return_item(item_path)
if item:
- return self._handle_temp_sums(func='gruendlandtempsumme', database_item=item, year=year, ignore_value_list=ignore_value_list)
+ return self._handle_temp_sums(func='gruendlandtempsumme', database_item=item, year=year, ignore_value_list=ignore_value_list, params={'result': result})
- def waermesumme(self, item_path: str, year: Union[int, str] = None, month: Union[int, str] = None, ignore_value_list: list = None, threshold: int = 0) -> Union[int, None]:
+ def waermesumme(self, item_path: str, year: Union[int, str] = None, month: Union[int, str] = None, ignore_value_list: list = None, threshold: int = 0, result: str = 'total') -> Union[int, None]:
"""
Query database for waermesumme for given year or year/month
https://de.wikipedia.org/wiki/W%C3%A4rmesumme
@@ -1381,14 +1439,15 @@ def waermesumme(self, item_path: str, year: Union[int, str] = None, month: Union
:param month: month the waermesumme should be calculated for
:param ignore_value_list: list of comparison operators for val_num, which will be applied during query
:param threshold: threshold for temperature
+ :param result: total-Gesamtwert, month-Serie mit Monatswerten, day-Serie mit Tageswerten (default: total)
:return: waermesumme
"""
item = self.items.return_item(item_path)
if item:
- return self._handle_temp_sums(func='waermesumme', database_item=item, year=year, month=month, ignore_value_list=ignore_value_list, params={'threshold': threshold})
+ return self._handle_temp_sums(func='waermesumme', database_item=item, year=year, month=month, ignore_value_list=ignore_value_list, params={'threshold': threshold, 'result': result})
- def kaeltesumme(self, item_path: str, year: Union[int, str] = None, month: Union[int, str] = None, ignore_value_list: list = None) -> Union[int, None]:
+ def kaeltesumme(self, item_path: str, year: Union[int, str] = None, month: Union[int, str] = None, ignore_value_list: list = None, result: str = 'total') -> Union[int, None]:
"""
Query database for kaeltesumme for given year or year/month
https://de.wikipedia.org/wiki/K%C3%A4ltesumme
@@ -1397,14 +1456,15 @@ def kaeltesumme(self, item_path: str, year: Union[int, str] = None, month: Union
:param year: year the kaeltesumme should be calculated for
:param month: month the kaeltesumme should be calculated for
:param ignore_value_list: list of comparison operators for val_num, which will be applied during query
+ :param result: total-Gesamtwert, month-Serie mit Monatswerten, day-Serie mit Tageswerten (default: total)
:return: kaeltesumme
"""
item = self.items.return_item(item_path)
if item:
- return self._handle_temp_sums(func='kaeltesumme', database_item=item, year=year, month=month, ignore_value_list=ignore_value_list)
+ return self._handle_temp_sums(func='kaeltesumme', database_item=item, year=year, month=month, ignore_value_list=ignore_value_list, params={'result': result})
- def wachstumsgradtage(self, item_path: str, year: Union[int, str] = None, ignore_value_list: list = None, variant: int = 0, threshold: int = 10) -> Union[int, None]:
+ def wachstumsgradtage(self, item_path: str, year: Union[int, str] = None, ignore_value_list: list = None, variant: int = 0, threshold: int = 10, result: str = 'total') -> Union[int, None]:
"""
Query database for wachstumsgradtage
https://de.wikipedia.org/wiki/Wachstumsgradtag
@@ -1414,12 +1474,13 @@ def wachstumsgradtage(self, item_path: str, year: Union[int, str] = None, ignore
:param ignore_value_list: list of comparison operators for val_num, which will be applied during query
:param variant: variant to be used
:param threshold: Temperature in °C as threshold: Ein Tage mit einer Tagesdurchschnittstemperatur oberhalb des Schwellenwertes gilt als Wachstumsgradtag
+ :param result: total-Gesamtwert, month-Serie mit Monatswerten, day-Serie mit Tageswerten (default: total)
:return: wachstumsgradtage
"""
item = self.items.return_item(item_path)
if item:
- return self._handle_temp_sums(func='wachstumsgradtage', database_item=item, year=year, ignore_value_list=ignore_value_list, params={'threshold': threshold, 'variant': variant})
+ return self._handle_temp_sums(func='wachstumsgradtage', database_item=item, year=year, ignore_value_list=ignore_value_list, params={'threshold': threshold, 'variant': variant, 'result': result})
def temperaturserie(self, item_path: str, year: Union[int, str] = None, ignore_value_list: list = None, data_con_func: str = 'first_hour_avg_day') -> Union[list, None]:
"""
@@ -1522,7 +1583,7 @@ def _handle_verbrauch(self, query_params: dict) -> Union[None, float]:
- Ergibt diese Abfrage keinen Wert, Anfangszählerstand = 0
"""
- # define start, end for verbrauch_jahreszeitraum_timedelta
+ # define start, end for verbrauch_jahreszeitraum_timedelta like 'verbrauch_jahreszeitraum_minus1'
if 'timedelta' in query_params:
timedelta = query_params.pop('timedelta')
today = self.shtime.today(offset=0)
@@ -1530,16 +1591,18 @@ def _handle_verbrauch(self, query_params: dict) -> Union[None, float]:
end_date = today - relativedelta(years=timedelta)
start = (today - start_date).days
end = (today - end_date).days
- else:
- start = query_params['start']
- end = query_params['end']
+ query_params.update({'start': start, 'end': end})
# calculate consumption
if self.debug_log.prepare:
self.logger.debug(f"called with {query_params=}")
- # get value for end and check it;
- query_params.update({'func': 'last', 'start': start, 'end': end})
+ # extract start and end out of query_params
+ _start = query_params.pop('start')
+ _end = query_params.pop('end')
+
+ # get value for end and check it
+ query_params.update({'func': 'last', 'start': _end, 'end': _end})
value_end = self._query_item(**query_params)[0][1]
if self.debug_log.prepare:
@@ -1548,8 +1611,9 @@ def _handle_verbrauch(self, query_params: dict) -> Union[None, float]:
if value_end is None or value_end == 0:
return value_end
- # get value for start and check it;
- query_params.update({'func': 'next', 'start': start, 'end': start})
+ # get value for start and check it
+ # ToDo: Check if right start and end is used
+ query_params.update({'func': 'next', 'start': _start, 'end': _start})
value_start = self._query_item(**query_params)[0][1]
if self.debug_log.prepare:
self.logger.debug(f"{value_start=}")
@@ -1583,16 +1647,18 @@ def _handle_verbrauch_serie(self, query_params: dict) -> list:
for i in range(start, 1, -1):
value = self._handle_verbrauch({'database_item': database_item, 'timeframe': timeframe, 'start': i + 1, 'end': i})
- ts_start, ts_end = self._get_start_end_as_timestamp(timeframe, i, i + 1)
+ # ToDo: check ts_start, ts_end
+ ts_start, ts_end = self._get_start_end_as_timestamp(timeframe=timeframe, start=(i + 1), end=i)
+ if self.debug_log.prepare:
+ self.logger.debug(f"{ts_start=}, {ts_end=}")
series.append([ts_end, value])
return series
+ # ToDo: Test method
def _handle_verbrauch_serie_new(self, query_params: dict) -> list:
"""Ermittlung einer Serie von Verbräuchen in einem Zeitraum für x Zeiträume"""
- # ToDo: Test method
-
query_params.update({'data_con_func': 'max_day', 'cache': True})
raw_data = self._prepare_value_list(**query_params)
@@ -1626,6 +1692,7 @@ def _handle_zaehlerstand(self, query_params: dict) -> Union[float, int, None]:
# get last value of timeframe
query_params.update({'func': 'next'})
last_value = self._query_item(**query_params)[0][1]
+
if self.debug_log.prepare:
self.logger.debug(f"{last_value=}")
@@ -1656,11 +1723,10 @@ def _handle_zaehlerstand_serie(self, query_params: dict) -> list:
return series
+ # ToDo: Test method
def _handle_zaehlerstand_serie_new(self, query_params: dict) -> list:
"""Ermittlung einer Serie von Zählerständen zum Ende eines Zeitraumes für x Zeiträume"""
- # ToDo: Test method
-
query_params.update({'data_con_func': 'max_day', 'cache': True})
raw_data = self._prepare_value_list(**query_params)
@@ -1692,11 +1758,13 @@ def _handle_temp_sums(self, func: str, database_item: Item, year: Union[int, str
:return: temperature sum or day count
- kaeltesumme: Kältesumme nach https://de.wikipedia.org/wiki/K%C3%A4ltesumme
+ params: result
- waermesumme: Wärmesumme https://de.wikipedia.org/wiki/W%C3%A4rmesumme
- params: threshold
+ params: threshold, result
- gruenlandtempsumme: Grünlandtemperatursumme: https://de.wikipedia.org/wiki/Gr%C3%BCnlandtemperatursumme
+ params: result
- wachstumsgradtage: Wachstumsgradtage https://de.wikipedia.org/wiki/Wachstumsgradtag
- params: threshold, variant, result
+ params: year, threshold, variant, result
- temperaturserie: Temperaturserie provide list of lists having timestamp and temperature(s) per day
params: data_con_func
- wuestentage: Wüstentage, Anzahl der Tage mit Tmax ≥ 35 °C
@@ -1731,103 +1799,208 @@ def _handle_temp_sums(self, func: str, database_item: Item, year: Union[int, str
if not params:
params = dict()
- def kaeltesumme() -> float:
+ def kaeltesumme() -> Union[list, float, None]:
"""Berechnung der Kältesumme durch Akkumulieren aller negativen Tagesdurchschnittstemperaturen im Abfragezeitraum
- :return: value of kaeltesumme
+ result 'total': Rückgabe als Gesamtwert
+ result 'month': Rückgabe als Liste mit kumulierten Werten pro Monat [['timestamp1', 'kumulierter Wert am Ende von Monat1'], ['timestamp2', ''kumulierter Wert am Ende von Monat2', [...], ...]
+ result 'day': Rückgabe als Liste mit kumulierten Werten pro Tag [['timestamp1', 'kumulierter Wert am Ende von Tag1'], ['timestamp2', ''kumulierter Wert am Ende von Tag2', [...], ...]
"""
+ # define defaults
+ ks_total = 0
+ ks_serie_day = []
+ ks_serie_month = {}
+
+ # get result type
+ result = params.get('result', 'total')
+
# akkumulieren alle Werte, kleiner 0
- ks = 0
for entry in raw_data:
- if entry[1] < 0:
- ks -= entry[1]
- return int(round(ks, 0))
+ timestamp, value = entry
+
+ # limit values to negtive values
+ ks_day = min(0, value)
- def waermesumme() -> float:
+ # create total value of kaeltesumme
+ ks_total -= ks_day
+
+ # create series kaeltesumme per day
+ ks_serie_day.append([timestamp, round(ks_day, 1)])
+
+ # create series kaeltesumme per month
+ _dt = datetime.datetime.fromtimestamp(timestamp)
+ _dt = _dt.replace(day=1, minute=0, hour=0)
+ _timestamp = self._datetime_to_timestamp(_dt)
+ ks_serie_month[_timestamp] = ks_serie_month.get(_timestamp, 0) + ks_day
+
+ # return result
+ if result == 'day':
+ return ks_serie_day
+ elif result == 'month':
+ return [[k, round(v, 1)] for k, v in ks_serie_month.items()]
+ return int(round(ks_total, 0))
+
+ def waermesumme() -> Union[list, float, None]:
"""Berechnung der Wärmesumme durch Akkumulieren aller Tagesdurchschnittstemperaturen im Abfragezeitraum, die größer/gleich dem Schwellenwert sind
- :return: value of waermesumme
+ threshold: Schwellwert
+ result 'total': Rückgabe als Gesamtwert
+ result 'month': Rückgabe als Liste mit kumulierten Werten pro Monat [['timestamp1', 'kumulierter Wert am Ende von Monat1'], ['timestamp2', ''kumulierter Wert am Ende von Monat2', [...], ...]
+ result 'day': Rückgabe als Liste mit kumulierten Werten pro Tag [['timestamp1', 'kumulierter Wert am Ende von Tag1'], ['timestamp2', ''kumulierter Wert am Ende von Tag2', [...], ...]
"""
# get threshold and set to min 0
- threshold = params.get('threshold', 10)
- threshold = max(0, threshold)
+ threshold = max(params.get('threshold', 10), 0)
+
+ # get result type
+ result = params.get('result', 'total')
+
+ # define defaults
+ ws_total = 0
+ ws_serie_day = []
+ ws_serie_month = {}
# akkumulieren alle Werte, größer/gleich Schwellenwert
- ws = 0
for entry in raw_data:
- if entry[1] >= threshold:
- ws += entry[1]
- return int(round(ws, 0))
+ timestamp, value = entry
+
+ # limit values per threshold
+ ws_day = value if value >= threshold else 0
+
+ # create total value of waermesumme
+ ws_total += ws_day
+
+ # create series kaeltesumme per day
+ ws_serie_day.append([timestamp, round(ws_day, 1)])
+
+ # create series kaeltesumme per month
+ _dt = datetime.datetime.fromtimestamp(timestamp)
+ _dt = _dt.replace(day=1, minute=0, hour=0)
+ _timestamp = self._datetime_to_timestamp(_dt)
+ ws_serie_month[_timestamp] = ws_serie_month.get(_timestamp, 0) + ws_day
+
+ # return result
+ if result == 'day':
+ return ws_serie_day
+ elif result == 'month':
+ return [[k, round(v, 1)] for k, v in ws_serie_month.items()]
+ return int(round(ws_total, 0))
- def gruenlandtempsumme() -> float:
+ def gruenlandtempsumme() -> Union[list, float, None]:
"""Berechnung der Grünlandtemperatursumme durch Akkumulieren alle positiven Tagesmitteltemperaturen, im Januar gewichtet mit 50%, im Februar mit 75%
- :return: value of gruenlandtempsumme
+ result 'total': Rückgabe als Gesamtwert
+ result 'month': Rückgabe als Liste mit kumulierten Werten pro Monat [['timestamp1', 'kumulierter Wert am Ende von Monat1'], ['timestamp2', ''kumulierter Wert am Ende von Monat2', [...], ...]
+ result 'day': Rückgabe als Liste mit kumulierten Werten pro Tag [['timestamp1', 'kumulierter Wert am Ende von Tag1'], ['timestamp2', ''kumulierter Wert am Ende von Tag2', [...], ...]
"""
-
- gts = 0
+ # define defaults
+ gts_total = 0
+ gts_serie_day = []
+ gts_serie_month = {}
+
+ # get result type
+ result = params.get('result', 'total')
+
+ # accumulate value
for entry in raw_data:
timestamp, value = entry
- if value > 0:
- dt = self._timestamp_to_datetime(timestamp / 1000)
- if dt.month == 1:
- value = value * 0.5
- elif dt.month == 2:
- value = value * 0.75
- gts += value
- return int(round(gts, 0))
+
+ # limit values to positive values
+ gts_day = max(0, value)
+
+ # degrade values for january and february
+ dt = self._timestamp_to_datetime(timestamp / 1000)
+ if dt.month == 1:
+ gts_day = gts_day * 0.5
+ elif dt.month == 2:
+ gts_day = gts_day * 0.75
+
+ # create total value of gruenlandtempsumme
+ gts_total += gts_day
+
+ # create series gruenlandtempsumme per day
+ gts_serie_day.append([timestamp, round(gts_day, 1)])
+
+ # create series gruenlandtempsumme per month
+ _dt = datetime.datetime.fromtimestamp(timestamp)
+ _dt = _dt.replace(day=1, minute=0, hour=0)
+ _timestamp = self._datetime_to_timestamp(_dt)
+ gts_serie_month[_timestamp] = gts_serie_month.get(_timestamp, 0) + gts_day
+
+ # return result
+ if result == 'day':
+ return gts_serie_day
+ elif result == 'month':
+ return [[k, round(v, 1)] for k, v in gts_serie_month.items()]
+ return int(round(gts_total, 0))
def wachstumsgradtage() -> Union[list, float, None]:
"""Berechnet die Wachstumsgradtage noch 2 möglichen Varianten und gibt entweder den Gesamtwert oder eine Liste mit kumulierten Werten pro Tag zurück
+ threshold: Schwellwert
variant 0: Berechnungsmethode "Berechnung des einfachen Durchschnitts" mit Vergleich des Durchschnitts der täglichen Minimal- und Maximaltemperatur mit Schwellenwert.
Maximaltemperaturen werden bei 30 °C gekappt.
variant 1: Berechnungsmethode "modifizierte Berechnung des einfachen Durchschnitts" mit Vergleich des Durchschnitts der täglichen Minimal- und Maximaltemperatur mit Schwellenwert.
Vor der Berechnung des Durchschnittes wird jede Temperatur, die den Schwellenwert unterschreitet, auf den Schwellenwert geändert.
Maximaltemperaturen werden bei 30 °C gekappt.
-
- result 'value': Rückgabe als Gesamtwert
- result 'series: Rückgabe als Liste mit kumulierten Werten pro Tag zurück [['timestamp1', 'kumulierter Wert am Ende von Tag1'], ['timestamp2', ''kumulierter Wert am Ende von Tag2', [...], ...]
+ result 'total': Rückgabe als Gesamtwert
+ result 'month': Rückgabe als Liste mit kumulierten Werten pro Monat [['timestamp1', 'kumulierter Wert am Ende von Monat1'], ['timestamp2', ''kumulierter Wert am Ende von Monat2', [...], ...]
+ result 'day': Rückgabe als Liste mit kumulierten Werten pro Tag [['timestamp1', 'kumulierter Wert am Ende von Tag1'], ['timestamp2', ''kumulierter Wert am Ende von Tag2', [...], ...]
"""
# define defaults
- wgte = 0
- wgte_list = []
+ wgt_total = 0
+ wgt_serie_day = []
+ wgt_serie_month = {}
upper_limit = 30
-
+
# get threshold and set to min 0
- threshold = params.get('threshold', 10)
- threshold = max(0, threshold)
+ threshold = max(params.get('threshold', 10), 0)
# get variant
variant = params.get('variant', 0)
# get result type
- result = params.get('result', 'value')
+ result = params.get('result', 'total')
# variant handling
if variant == 0:
- self.logger.info(f"Calculate 'Wachstumsgradtage' according to 'Berechnung des einfachen Durchschnitts'.")
+ self.logger.info(f"Calculate 'Wachstumsgradtage' according to 'Berechnung des einfachen Durchschnitts' to {result=}.")
min_val_c = 'min_val'
elif variant == 1:
- self.logger.info(f"Calculate 'Wachstumsgradtage' according to 'Modifizierte Berechnung des einfachen Durchschnitts'.")
+ self.logger.info(f"Calculate 'Wachstumsgradtage' according to 'Modifizierte Berechnung des einfachen Durchschnitts' to {result=}.")
min_val_c = 'max(threshold, min_val)'
else:
self.logger.warning(f"Requested variant of 'Wachstumsgradtage' not defined. Aborting...")
return
- # accumulate values
+ # accumulate value
for entry in raw_data:
timestamp, min_val, max_val = entry
- wgt = ((eval(min_val_c) + min(upper_limit, max_val)) / 2 ) - threshold
- if wgt > 0:
- wgte += wgt
- wgte_list.append([timestamp, int(round(wgte, 0))])
+
+ # calc wachstumsgradtage per day
+ wgt_day = ((eval(min_val_c) + min(upper_limit, max_val)) / 2) - threshold
+ wgt_day = max(0, wgt_day)
+
+ # create total value of wachstumsgradtage
+ wgt_total += wgt_day
+
+ # create series wachstumsgradtage per day
+ wgt_serie_day.append([timestamp, round(wgt_day, 1)])
+
+ # create series wachstumsgradtage per month
+ _dt = datetime.datetime.fromtimestamp(timestamp)
+ _dt = _dt.replace(day=1, minute=0, hour=0)
+ _timestamp = self._datetime_to_timestamp(_dt)
+ wgt_serie_month[_timestamp] = wgt_serie_month.get(_timestamp, 0) + wgt_day
# return result
- return wgte_list if result == 'series' else int(round(wgte, 0))
+ if result == 'day':
+ return wgt_serie_day
+ elif result == 'month':
+ return [[k, round(v, 1)] for k, v in wgt_serie_month.items()]
+ return int(round(wgt_total, 0))
def temperaturserie() -> list:
"""provide list of lists having timestamp and temperature(s) per day"""
@@ -1867,12 +2040,8 @@ def vegetationstage() -> int:
return _count(operator.ge, 'avg', 5)
def _count(op, minmax: str, limit: int) -> int:
- count = 0
- for entry in raw_data:
- value = entry[2] if minmax == 'max' else entry[1]
- if op(value, limit):
- count += 1
- return count
+ minmax_index = 2 if minmax == 'max' else 1
+ return sum(1 for entry in raw_data if op(entry[minmax_index], limit))
self.logger.debug(f"{func=}, {database_item=}, {year=}, {month=}, {params=}")
@@ -1895,9 +2064,9 @@ def _count(op, minmax: str, limit: int) -> int:
# define start_date, end_date
if month is None:
- ((s_y, s_m, s_d), (e_y, e_m, e_d)) = defaults.get(func, {}).get('start_end', timeframe[3])
- start_date = datetime.date(int(year) + s_y, s_m, s_d)
- end_date = datetime.date(int(year) + e_y, e_m, e_d)
+ ((start_year, start_month, start_day), (end_year, end_month, end_day)) = defaults.get(func, {}).get('start_end', timeframe[3])
+ start_date = datetime.date(int(year) + start_year, start_month, start_day)
+ end_date = datetime.date(int(year) + end_year, end_month, end_day)
elif self._valid_month(month):
start_date = datetime.date(int(year), int(month), 1)
end_date = start_date + relativedelta(months=+1) - datetime.timedelta(days=1)
@@ -1960,24 +2129,25 @@ def _prepare_value_list(self, database_item: Item, timeframe: str, start: int, e
def _group_value_by_datetime_block(block: str) -> dict:
"""
- create dict of datetimes (per day or hour) and values based on database query result in format {'datetime1': [values]}, 'datetime1': [values], ..., 'datetimex': [values]}
+ create dict of datetimes (per day or hour) and values based on database query result in format {{'datetime1': [values]}, 'datetime1': [values], ..., 'datetimex': [values]}
:param block: defined the increment of datetime, default is min, further possible is 'day' and 'hour'
"""
_value_dict = {}
- for _entry in raw_data:
- ts = _entry[0]
+
+ for ts, value in raw_data:
+ # format timestamp
if len(str(ts)) > 10:
ts = ts / 1000
- dt = self._timestamp_to_datetime(ts)
- dt = dt.replace(second=0, microsecond=0, tzinfo=None)
+ # format datetime object
+ dt = self._timestamp_to_datetime(ts).replace(second=0, microsecond=0, tzinfo=None)
if block == 'hour':
dt = dt.replace(minute=0)
if block == 'day':
dt = dt.replace(minute=0, hour=0)
- if dt not in _value_dict:
- _value_dict[dt] = []
- _value_dict[dt].append(_entry[1])
+ # fill dict
+ _value_dict.setdefault(dt, []).append(value)
+
return dict(sorted(_value_dict.items()))
def _concentrate_values(option: str) -> list:
@@ -2091,10 +2261,10 @@ def _check_db_existence(self) -> bool:
if not _db_plugin:
self.logger.error(f"Database plugin not loaded or given ConfigName {self.db_configname} not correct. No need for DatabaseAddOn Plugin.")
return False
- else:
- self.logger.debug(f"Corresponding plugin 'database' with given config name '{self.db_configname}' found.")
- self._db_plugin = _db_plugin
- return self._get_db_parameter()
+
+ self.logger.debug(f"Corresponding plugin 'database' with given config name '{self.db_configname}' found.")
+ self._db_plugin = _db_plugin
+ return self._get_db_parameter()
def _get_db_parameter(self) -> bool:
"""
@@ -2122,11 +2292,10 @@ def _get_db_parameter(self) -> bool:
self.item_attribute_search_str = f"{self.item_attribute_search_str}@{self.db_instance}"
self.connection_data = self._db_plugin.get_parameter_value('connect') # pymsql ['host:localhost', 'user:smarthome', 'passwd:smarthome', 'db:smarthome', 'port:3306']
self.logger.debug(f"Database Plugin available with instance={self.db_instance} and connection={self.connection_data}")
+ return True
except Exception as e:
self.logger.error(f"Error {e} occurred during getting database plugin parameters. DatabaseAddOn Plugin not loaded.")
return False
- else:
- return True
def _check_db_connection_setting(self) -> None:
"""
@@ -2175,7 +2344,7 @@ def _get_oldest_value(self, item: Item) -> Union[int, float, bool]:
Get value of the oldest log of item from cache dict or get value from db and put it to cache dict
:param item: Item, for which query should be done
- :return: oldest value
+ :return: the oldest value
"""
_oldest_entry = self.item_cache.get(item, {}).get('oldest_entry', None)
@@ -2471,8 +2640,7 @@ def _valid_year(self, year: Union[int, str]) -> bool:
if ((isinstance(year, int) or (isinstance(year, str) and year.isdigit())) and (
1980 <= int(year) <= self.shtime.today(offset=0).year)) or (isinstance(year, str) and year == 'current'):
return True
- else:
- return False
+ return False
@staticmethod
def _valid_month(month: Union[int, str]) -> bool:
@@ -2480,8 +2648,7 @@ def _valid_month(month: Union[int, str]) -> bool:
if (isinstance(month, int) or (isinstance(month, str) and month.isdigit())) and (1 <= int(month) <= 12):
return True
- else:
- return False
+ return False
#################################
# Database Query Preparation
@@ -2555,7 +2722,7 @@ def _query_log_timestamp(self, func: str, item_id: int, ts_start: int, ts_end: i
'last': 'LIMIT 1 ',
}
- _where = "item_id = :item_id AND time <= :ts_start " if func == "next" else "item_id = :item_id AND time BETWEEN :ts_start AND :ts_end "
+ _where = "item_id = :item_id AND time <= :ts_end " if func == "next" else "item_id = :item_id AND time BETWEEN :ts_start AND :ts_end "
_db_table = 'log '
@@ -2607,7 +2774,7 @@ def _query_log_timestamp(self, func: str, item_id: int, ts_start: int, ts_end: i
# set params
params = {'item_id': item_id, 'ts_start': ts_start, 'ts_end': ts_end}
if func == "next":
- params.pop('ts_end', None)
+ params.pop('ts_start', None)
# assemble query
query = f"SELECT {_select[func]}FROM {_db_table}WHERE {_where}{_group_by.get(group, '')}{_order.get(func, '')}{_limit.get(func, '')}{_table_alias.get(func, '')}{_group_by.get(group2, '')}".strip()
@@ -2872,30 +3039,28 @@ def __post_init__(self, log_level):
# Helper functions
#######################
-
-def params_to_dict(string: str) -> Union[dict, None]:
+def params_to_dict(string: str) -> Union[Dict[str, Union[str, int]], None]:
"""Parse a string with named arguments and comma separation to dict; (e.g. string = 'year=2022, month=12')"""
+ res_dict = {}
try:
- res_dict = dict((a.strip(), b.strip()) for a, b in (element.split('=') for element in string.split(', ')))
- except Exception:
+ for element in string.split(','):
+ key, value = element.split('=')
+ key, value = key.strip(), value.strip().strip('\'"')
+ if value.isdigit():
+ value = int(value)
+ res_dict[key] = value
+ except AttributeError:
+ return None
+ except ValueError:
return None
- else:
- # convert to int and remove possible double quotes
- for key in res_dict:
- if isinstance(res_dict[key], str):
- res_dict[key] = res_dict[key].replace('"', '')
- res_dict[key] = res_dict[key].replace("'", "")
- if res_dict[key].isdigit():
- res_dict[key] = int(float(res_dict[key]))
-
- # check correctness if known key values (func=str, item, timeframe=str, start=int, end=int, count=int, group=str, group2=str, year=int, month=int):
- for key in res_dict:
- if key in ('func', 'timeframe', 'group', 'group2') and not isinstance(res_dict[key], str):
- return None
- elif key in ('start', 'end', 'count') and not isinstance(res_dict[key], int):
- return None
- return res_dict
+
+ known_keys = {'func': str, 'item': str, 'timeframe': str, 'start': int, 'end': int, 'count': int, 'group': str, 'group2': str, 'year': int, 'month': int}
+ for key, value in res_dict.items():
+ if key in known_keys and not isinstance(value, known_keys[key]):
+ return None
+
+ return res_dict
def translate_timeframe(timeframe: str) -> str:
@@ -2930,7 +3095,7 @@ def timeframe_to_timeframe(timeframe_in: str, timeframe_out: str) -> int:
_w_in_m = _w_in_y / _m_in_y
_d_in_m = _d_in_y / _m_in_y
- lookup = {
+ conversion_factors = {
'hour': {'hour': 1,
'day': _h_in_d,
'week': _h_in_d * _d_in_w,
@@ -2963,7 +3128,7 @@ def timeframe_to_timeframe(timeframe_in: str, timeframe_out: str) -> int:
}
}
- return lookup[timeframe_in][timeframe_out]
+ return conversion_factors[timeframe_in][timeframe_out]
def to_int(arg) -> Union[int, None]:
@@ -3003,3 +3168,5 @@ def split_sting_letters_numbers(string) -> list:
ALLOWED_QUERY_TIMEFRAMES = ['year', 'month', 'week', 'day', 'hour']
ALLOWED_MINMAX_FUNCS = ['min', 'max', 'avg']
+ALLOWED_QUERY_FUNCS = ['avg', 'avg1', 'min', 'max', 'max1', 'sum', 'on', 'integrate', 'sum_max', 'sum_avg', 'sum_min_neg', 'diff_max', 'next', 'raw', 'first', 'last']
+ALLOWED_RESULT_TYPES = ['total', 'month', 'day']
diff --git a/db_addon/item_attributes.py b/db_addon/item_attributes.py
deleted file mode 100644
index 696ffda30..000000000
--- a/db_addon/item_attributes.py
+++ /dev/null
@@ -1,75 +0,0 @@
-# !/usr/bin/env python
-# vim: set encoding=utf-8 tabstop=4 softtabstop=4 shiftwidth=4 expandtab
-# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
-# Copyright 2023 Michael Wenzel
-# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
-# DatabaseAddOn for SmartHomeNG. https://github.com/smarthomeNG//
-#
-# This plugin is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# This plugin is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this plugin. If not, see .
-# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
-
-
-# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
-#
-#
-# THIS FILE IS AUTOMATICALLY CREATED BY USING item_attributes_master.py
-#
-#
-# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
-
-ONCHANGE_ATTRIBUTES = ['verbrauch_heute', 'verbrauch_tag', 'verbrauch_woche', 'verbrauch_monat', 'verbrauch_jahr', 'minmax_heute_min', 'minmax_heute_max', 'minmax_heute_avg', 'minmax_tag_min', 'minmax_tag_max', 'minmax_tag_avg', 'minmax_woche_min', 'minmax_woche_max', 'minmax_monat_min', 'minmax_monat_max', 'minmax_jahr_min', 'minmax_jahr_max', 'tagesmitteltemperatur_heute', 'tagesmitteltemperatur_tag']
-ONCHANGE_HOURLY_ATTRIBUTES = []
-ONCHANGE_DAILY_ATTRIBUTES = ['verbrauch_heute', 'verbrauch_tag', 'minmax_heute_min', 'minmax_heute_max', 'minmax_heute_avg', 'minmax_tag_min', 'minmax_tag_max', 'minmax_tag_avg', 'tagesmitteltemperatur_heute', 'tagesmitteltemperatur_tag']
-ONCHANGE_WEEKLY_ATTRIBUTES = ['verbrauch_woche', 'minmax_woche_min', 'minmax_woche_max']
-ONCHANGE_MONTHLY_ATTRIBUTES = ['verbrauch_monat', 'minmax_monat_min', 'minmax_monat_max']
-ONCHANGE_YEARLY_ATTRIBUTES = ['verbrauch_jahr', 'minmax_jahr_min', 'minmax_jahr_max']
-ONDEMAND_ATTRIBUTES = ['verbrauch_last_24h', 'verbrauch_last_7d', 'verbrauch_heute_minus1', 'verbrauch_heute_minus2', 'verbrauch_heute_minus3', 'verbrauch_heute_minus4', 'verbrauch_heute_minus5', 'verbrauch_heute_minus6', 'verbrauch_heute_minus7', 'verbrauch_heute_minus8', 'verbrauch_tag_minus1', 'verbrauch_tag_minus2', 'verbrauch_tag_minus3', 'verbrauch_tag_minus4', 'verbrauch_tag_minus5', 'verbrauch_tag_minus6', 'verbrauch_tag_minus7', 'verbrauch_tag_minus8', 'verbrauch_woche_minus1', 'verbrauch_woche_minus2', 'verbrauch_woche_minus3', 'verbrauch_woche_minus4', 'verbrauch_monat_minus1', 'verbrauch_monat_minus2', 'verbrauch_monat_minus3', 'verbrauch_monat_minus4', 'verbrauch_monat_minus12', 'verbrauch_jahr_minus1', 'verbrauch_jahr_minus2', 'verbrauch_jahr_minus3', 'verbrauch_rolling_12m_heute_minus1', 'verbrauch_rolling_12m_tag_minus1', 'verbrauch_rolling_12m_woche_minus1', 'verbrauch_rolling_12m_monat_minus1', 'verbrauch_rolling_12m_jahr_minus1', 'verbrauch_jahreszeitraum_minus1', 'verbrauch_jahreszeitraum_minus2', 'verbrauch_jahreszeitraum_minus3', 'zaehlerstand_heute_minus1', 'zaehlerstand_heute_minus2', 'zaehlerstand_heute_minus3', 'zaehlerstand_tag_minus1', 'zaehlerstand_tag_minus2', 'zaehlerstand_tag_minus3', 'zaehlerstand_woche_minus1', 'zaehlerstand_woche_minus2', 'zaehlerstand_woche_minus3', 'zaehlerstand_monat_minus1', 'zaehlerstand_monat_minus2', 'zaehlerstand_monat_minus3', 'zaehlerstand_jahr_minus1', 'zaehlerstand_jahr_minus2', 'zaehlerstand_jahr_minus3', 'minmax_last_24h_min', 'minmax_last_24h_max', 'minmax_last_24h_avg', 'minmax_last_7d_min', 'minmax_last_7d_max', 'minmax_last_7d_avg', 'minmax_heute_minus1_min', 'minmax_heute_minus1_max', 'minmax_heute_minus1_avg', 'minmax_heute_minus2_min', 'minmax_heute_minus2_max', 'minmax_heute_minus2_avg', 'minmax_heute_minus3_min', 'minmax_heute_minus3_max', 'minmax_heute_minus3_avg', 'minmax_tag_minus1_min', 'minmax_tag_minus1_max', 'minmax_tag_minus1_avg', 'minmax_tag_minus2_min', 'minmax_tag_minus2_max', 'minmax_tag_minus2_avg', 'minmax_tag_minus3_min', 'minmax_tag_minus3_max', 'minmax_tag_minus3_avg', 'minmax_woche_minus1_min', 'minmax_woche_minus1_max', 'minmax_woche_minus1_avg', 'minmax_woche_minus2_min', 'minmax_woche_minus2_max', 'minmax_woche_minus2_avg', 'minmax_monat_minus1_min', 'minmax_monat_minus1_max', 'minmax_monat_minus1_avg', 'minmax_monat_minus2_min', 'minmax_monat_minus2_max', 'minmax_monat_minus2_avg', 'minmax_jahr_minus1_min', 'minmax_jahr_minus1_max', 'minmax_jahr_minus1_avg', 'tagesmitteltemperatur_heute_minus1', 'tagesmitteltemperatur_heute_minus2', 'tagesmitteltemperatur_heute_minus3', 'tagesmitteltemperatur_tag_minus1', 'tagesmitteltemperatur_tag_minus2', 'tagesmitteltemperatur_tag_minus3', 'serie_minmax_monat_min_15m', 'serie_minmax_monat_max_15m', 'serie_minmax_monat_avg_15m', 'serie_minmax_woche_min_30w', 'serie_minmax_woche_max_30w', 'serie_minmax_woche_avg_30w', 'serie_minmax_tag_min_30d', 'serie_minmax_tag_max_30d', 'serie_minmax_tag_avg_30d', 'serie_verbrauch_tag_30d', 'serie_verbrauch_woche_30w', 'serie_verbrauch_monat_18m', 'serie_zaehlerstand_tag_30d', 'serie_zaehlerstand_woche_30w', 'serie_zaehlerstand_monat_18m', 'serie_waermesumme_monat_24m', 'serie_kaeltesumme_monat_24m', 'serie_tagesmittelwert_0d', 'serie_tagesmittelwert_stunde_0d', 'serie_tagesmittelwert_stunde_30_0d', 'serie_tagesmittelwert_tag_stunde_30d', 'general_oldest_value', 'general_oldest_log', 'kaeltesumme', 'waermesumme', 'gruenlandtempsumme', 'wachstumsgradtage', 'wuestentage', 'heisse_tage', 'tropennaechte', 'sommertage', 'heiztage', 'vegetationstage', 'frosttage', 'eistage', 'tagesmitteltemperatur', 'db_request', 'minmax', 'minmax_last', 'verbrauch', 'zaehlerstand']
-ONDEMAND_HOURLY_ATTRIBUTES = ['verbrauch_last_24h', 'verbrauch_last_7d']
-ONDEMAND_DAILY_ATTRIBUTES = ['verbrauch_heute_minus1', 'verbrauch_heute_minus2', 'verbrauch_heute_minus3', 'verbrauch_heute_minus4', 'verbrauch_heute_minus5', 'verbrauch_heute_minus6', 'verbrauch_heute_minus7', 'verbrauch_heute_minus8', 'verbrauch_tag_minus1', 'verbrauch_tag_minus2', 'verbrauch_tag_minus3', 'verbrauch_tag_minus4', 'verbrauch_tag_minus5', 'verbrauch_tag_minus6', 'verbrauch_tag_minus7', 'verbrauch_tag_minus8', 'verbrauch_rolling_12m_heute_minus1', 'verbrauch_rolling_12m_tag_minus1', 'verbrauch_jahreszeitraum_minus1', 'verbrauch_jahreszeitraum_minus2', 'verbrauch_jahreszeitraum_minus3', 'zaehlerstand_heute_minus1', 'zaehlerstand_heute_minus2', 'zaehlerstand_heute_minus3', 'zaehlerstand_tag_minus1', 'zaehlerstand_tag_minus2', 'zaehlerstand_tag_minus3', 'minmax_last_24h_min', 'minmax_last_24h_max', 'minmax_last_24h_avg', 'minmax_last_7d_min', 'minmax_last_7d_max', 'minmax_last_7d_avg', 'minmax_heute_minus1_min', 'minmax_heute_minus1_max', 'minmax_heute_minus1_avg', 'minmax_heute_minus2_min', 'minmax_heute_minus2_max', 'minmax_heute_minus2_avg', 'minmax_heute_minus3_min', 'minmax_heute_minus3_max', 'minmax_heute_minus3_avg', 'minmax_tag_minus1_min', 'minmax_tag_minus1_max', 'minmax_tag_minus1_avg', 'minmax_tag_minus2_min', 'minmax_tag_minus2_max', 'minmax_tag_minus2_avg', 'minmax_tag_minus3_min', 'minmax_tag_minus3_max', 'minmax_tag_minus3_avg', 'tagesmitteltemperatur_heute_minus1', 'tagesmitteltemperatur_heute_minus2', 'tagesmitteltemperatur_heute_minus3', 'tagesmitteltemperatur_tag_minus1', 'tagesmitteltemperatur_tag_minus2', 'tagesmitteltemperatur_tag_minus3', 'serie_minmax_tag_min_30d', 'serie_minmax_tag_max_30d', 'serie_minmax_tag_avg_30d', 'serie_verbrauch_tag_30d', 'serie_zaehlerstand_tag_30d', 'serie_tagesmittelwert_0d', 'serie_tagesmittelwert_stunde_0d', 'serie_tagesmittelwert_stunde_30_0d', 'serie_tagesmittelwert_tag_stunde_30d', 'kaeltesumme', 'waermesumme', 'gruenlandtempsumme', 'wachstumsgradtage', 'wuestentage', 'heisse_tage', 'tropennaechte', 'sommertage', 'heiztage', 'vegetationstage', 'frosttage', 'eistage', 'tagesmitteltemperatur']
-ONDEMAND_WEEKLY_ATTRIBUTES = ['verbrauch_woche_minus1', 'verbrauch_woche_minus2', 'verbrauch_woche_minus3', 'verbrauch_woche_minus4', 'verbrauch_rolling_12m_woche_minus1', 'zaehlerstand_woche_minus1', 'zaehlerstand_woche_minus2', 'zaehlerstand_woche_minus3', 'minmax_woche_minus1_min', 'minmax_woche_minus1_max', 'minmax_woche_minus1_avg', 'minmax_woche_minus2_min', 'minmax_woche_minus2_max', 'minmax_woche_minus2_avg', 'serie_minmax_woche_min_30w', 'serie_minmax_woche_max_30w', 'serie_minmax_woche_avg_30w', 'serie_verbrauch_woche_30w', 'serie_zaehlerstand_woche_30w']
-ONDEMAND_MONTHLY_ATTRIBUTES = ['verbrauch_monat_minus1', 'verbrauch_monat_minus2', 'verbrauch_monat_minus3', 'verbrauch_monat_minus4', 'verbrauch_monat_minus12', 'verbrauch_rolling_12m_monat_minus1', 'zaehlerstand_monat_minus1', 'zaehlerstand_monat_minus2', 'zaehlerstand_monat_minus3', 'minmax_monat_minus1_min', 'minmax_monat_minus1_max', 'minmax_monat_minus1_avg', 'minmax_monat_minus2_min', 'minmax_monat_minus2_max', 'minmax_monat_minus2_avg', 'serie_minmax_monat_min_15m', 'serie_minmax_monat_max_15m', 'serie_minmax_monat_avg_15m', 'serie_verbrauch_monat_18m', 'serie_zaehlerstand_monat_18m', 'serie_waermesumme_monat_24m', 'serie_kaeltesumme_monat_24m']
-ONDEMAND_YEARLY_ATTRIBUTES = ['verbrauch_jahr_minus1', 'verbrauch_jahr_minus2', 'verbrauch_jahr_minus3', 'verbrauch_rolling_12m_jahr_minus1', 'zaehlerstand_jahr_minus1', 'zaehlerstand_jahr_minus2', 'zaehlerstand_jahr_minus3', 'minmax_jahr_minus1_min', 'minmax_jahr_minus1_max', 'minmax_jahr_minus1_avg']
-ALL_HOURLY_ATTRIBUTES = ['verbrauch_last_24h', 'verbrauch_last_7d']
-ALL_DAILY_ATTRIBUTES = ['verbrauch_heute', 'verbrauch_tag', 'verbrauch_heute_minus1', 'verbrauch_heute_minus2', 'verbrauch_heute_minus3', 'verbrauch_heute_minus4', 'verbrauch_heute_minus5', 'verbrauch_heute_minus6', 'verbrauch_heute_minus7', 'verbrauch_heute_minus8', 'verbrauch_tag_minus1', 'verbrauch_tag_minus2', 'verbrauch_tag_minus3', 'verbrauch_tag_minus4', 'verbrauch_tag_minus5', 'verbrauch_tag_minus6', 'verbrauch_tag_minus7', 'verbrauch_tag_minus8', 'verbrauch_rolling_12m_heute_minus1', 'verbrauch_rolling_12m_tag_minus1', 'verbrauch_jahreszeitraum_minus1', 'verbrauch_jahreszeitraum_minus2', 'verbrauch_jahreszeitraum_minus3', 'zaehlerstand_heute_minus1', 'zaehlerstand_heute_minus2', 'zaehlerstand_heute_minus3', 'zaehlerstand_tag_minus1', 'zaehlerstand_tag_minus2', 'zaehlerstand_tag_minus3', 'minmax_last_24h_min', 'minmax_last_24h_max', 'minmax_last_24h_avg', 'minmax_last_7d_min', 'minmax_last_7d_max', 'minmax_last_7d_avg', 'minmax_heute_min', 'minmax_heute_max', 'minmax_heute_avg', 'minmax_heute_minus1_min', 'minmax_heute_minus1_max', 'minmax_heute_minus1_avg', 'minmax_heute_minus2_min', 'minmax_heute_minus2_max', 'minmax_heute_minus2_avg', 'minmax_heute_minus3_min', 'minmax_heute_minus3_max', 'minmax_heute_minus3_avg', 'minmax_tag_min', 'minmax_tag_max', 'minmax_tag_avg', 'minmax_tag_minus1_min', 'minmax_tag_minus1_max', 'minmax_tag_minus1_avg', 'minmax_tag_minus2_min', 'minmax_tag_minus2_max', 'minmax_tag_minus2_avg', 'minmax_tag_minus3_min', 'minmax_tag_minus3_max', 'minmax_tag_minus3_avg', 'tagesmitteltemperatur_heute', 'tagesmitteltemperatur_heute_minus1', 'tagesmitteltemperatur_heute_minus2', 'tagesmitteltemperatur_heute_minus3', 'tagesmitteltemperatur_tag', 'tagesmitteltemperatur_tag_minus1', 'tagesmitteltemperatur_tag_minus2', 'tagesmitteltemperatur_tag_minus3', 'serie_minmax_tag_min_30d', 'serie_minmax_tag_max_30d', 'serie_minmax_tag_avg_30d', 'serie_verbrauch_tag_30d', 'serie_zaehlerstand_tag_30d', 'serie_tagesmittelwert_0d', 'serie_tagesmittelwert_stunde_0d', 'serie_tagesmittelwert_stunde_30_0d', 'serie_tagesmittelwert_tag_stunde_30d', 'kaeltesumme', 'waermesumme', 'gruenlandtempsumme', 'wachstumsgradtage', 'wuestentage', 'heisse_tage', 'tropennaechte', 'sommertage', 'heiztage', 'vegetationstage', 'frosttage', 'eistage', 'tagesmitteltemperatur']
-ALL_WEEKLY_ATTRIBUTES = ['verbrauch_woche', 'verbrauch_woche_minus1', 'verbrauch_woche_minus2', 'verbrauch_woche_minus3', 'verbrauch_woche_minus4', 'verbrauch_rolling_12m_woche_minus1', 'zaehlerstand_woche_minus1', 'zaehlerstand_woche_minus2', 'zaehlerstand_woche_minus3', 'minmax_woche_min', 'minmax_woche_max', 'minmax_woche_minus1_min', 'minmax_woche_minus1_max', 'minmax_woche_minus1_avg', 'minmax_woche_minus2_min', 'minmax_woche_minus2_max', 'minmax_woche_minus2_avg', 'serie_minmax_woche_min_30w', 'serie_minmax_woche_max_30w', 'serie_minmax_woche_avg_30w', 'serie_verbrauch_woche_30w', 'serie_zaehlerstand_woche_30w']
-ALL_MONTHLY_ATTRIBUTES = ['verbrauch_monat', 'verbrauch_monat_minus1', 'verbrauch_monat_minus2', 'verbrauch_monat_minus3', 'verbrauch_monat_minus4', 'verbrauch_monat_minus12', 'verbrauch_rolling_12m_monat_minus1', 'zaehlerstand_monat_minus1', 'zaehlerstand_monat_minus2', 'zaehlerstand_monat_minus3', 'minmax_monat_min', 'minmax_monat_max', 'minmax_monat_minus1_min', 'minmax_monat_minus1_max', 'minmax_monat_minus1_avg', 'minmax_monat_minus2_min', 'minmax_monat_minus2_max', 'minmax_monat_minus2_avg', 'serie_minmax_monat_min_15m', 'serie_minmax_monat_max_15m', 'serie_minmax_monat_avg_15m', 'serie_verbrauch_monat_18m', 'serie_zaehlerstand_monat_18m', 'serie_waermesumme_monat_24m', 'serie_kaeltesumme_monat_24m']
-ALL_YEARLY_ATTRIBUTES = ['verbrauch_jahr', 'verbrauch_jahr_minus1', 'verbrauch_jahr_minus2', 'verbrauch_jahr_minus3', 'verbrauch_rolling_12m_jahr_minus1', 'zaehlerstand_jahr_minus1', 'zaehlerstand_jahr_minus2', 'zaehlerstand_jahr_minus3', 'minmax_jahr_min', 'minmax_jahr_max', 'minmax_jahr_minus1_min', 'minmax_jahr_minus1_max', 'minmax_jahr_minus1_avg']
-ALL_PARAMS_ATTRIBUTES = ['kaeltesumme', 'waermesumme', 'gruenlandtempsumme', 'wachstumsgradtage', 'wuestentage', 'heisse_tage', 'tropennaechte', 'sommertage', 'heiztage', 'vegetationstage', 'frosttage', 'eistage', 'tagesmitteltemperatur', 'db_request', 'minmax', 'minmax_last', 'verbrauch', 'zaehlerstand']
-ALL_VERBRAUCH_ATTRIBUTES = ['verbrauch_heute', 'verbrauch_tag', 'verbrauch_woche', 'verbrauch_monat', 'verbrauch_jahr', 'verbrauch_last_24h', 'verbrauch_last_7d', 'verbrauch_heute_minus1', 'verbrauch_heute_minus2', 'verbrauch_heute_minus3', 'verbrauch_heute_minus4', 'verbrauch_heute_minus5', 'verbrauch_heute_minus6', 'verbrauch_heute_minus7', 'verbrauch_heute_minus8', 'verbrauch_tag_minus1', 'verbrauch_tag_minus2', 'verbrauch_tag_minus3', 'verbrauch_tag_minus4', 'verbrauch_tag_minus5', 'verbrauch_tag_minus6', 'verbrauch_tag_minus7', 'verbrauch_tag_minus8', 'verbrauch_woche_minus1', 'verbrauch_woche_minus2', 'verbrauch_woche_minus3', 'verbrauch_woche_minus4', 'verbrauch_monat_minus1', 'verbrauch_monat_minus2', 'verbrauch_monat_minus3', 'verbrauch_monat_minus4', 'verbrauch_monat_minus12', 'verbrauch_jahr_minus1', 'verbrauch_jahr_minus2', 'verbrauch_jahr_minus3', 'verbrauch_rolling_12m_heute_minus1', 'verbrauch_rolling_12m_tag_minus1', 'verbrauch_rolling_12m_woche_minus1', 'verbrauch_rolling_12m_monat_minus1', 'verbrauch_rolling_12m_jahr_minus1', 'verbrauch_jahreszeitraum_minus1', 'verbrauch_jahreszeitraum_minus2', 'verbrauch_jahreszeitraum_minus3']
-VERBRAUCH_ATTRIBUTES_ONCHANGE = ['verbrauch_heute', 'verbrauch_tag', 'verbrauch_woche', 'verbrauch_monat', 'verbrauch_jahr']
-VERBRAUCH_ATTRIBUTES_TIMEFRAME = ['verbrauch_heute_minus1', 'verbrauch_heute_minus2', 'verbrauch_heute_minus3', 'verbrauch_heute_minus4', 'verbrauch_heute_minus5', 'verbrauch_heute_minus6', 'verbrauch_heute_minus7', 'verbrauch_heute_minus8', 'verbrauch_tag_minus1', 'verbrauch_tag_minus2', 'verbrauch_tag_minus3', 'verbrauch_tag_minus4', 'verbrauch_tag_minus5', 'verbrauch_tag_minus6', 'verbrauch_tag_minus7', 'verbrauch_tag_minus8', 'verbrauch_woche_minus1', 'verbrauch_woche_minus2', 'verbrauch_woche_minus3', 'verbrauch_woche_minus4', 'verbrauch_monat_minus1', 'verbrauch_monat_minus2', 'verbrauch_monat_minus3', 'verbrauch_monat_minus4', 'verbrauch_monat_minus12', 'verbrauch_jahr_minus1', 'verbrauch_jahr_minus2', 'verbrauch_jahr_minus3']
-VERBRAUCH_ATTRIBUTES_LAST = ['verbrauch_last_24h', 'verbrauch_last_7d']
-VERBRAUCH_ATTRIBUTES_ROLLING = ['verbrauch_rolling_12m_heute_minus1', 'verbrauch_rolling_12m_tag_minus1', 'verbrauch_rolling_12m_woche_minus1', 'verbrauch_rolling_12m_monat_minus1', 'verbrauch_rolling_12m_jahr_minus1']
-VERBRAUCH_ATTRIBUTES_JAHRESZEITRAUM = ['verbrauch_jahreszeitraum_minus1', 'verbrauch_jahreszeitraum_minus2', 'verbrauch_jahreszeitraum_minus3']
-ALL_ZAEHLERSTAND_ATTRIBUTES = ['zaehlerstand_heute_minus1', 'zaehlerstand_heute_minus2', 'zaehlerstand_heute_minus3', 'zaehlerstand_tag_minus1', 'zaehlerstand_tag_minus2', 'zaehlerstand_tag_minus3', 'zaehlerstand_woche_minus1', 'zaehlerstand_woche_minus2', 'zaehlerstand_woche_minus3', 'zaehlerstand_monat_minus1', 'zaehlerstand_monat_minus2', 'zaehlerstand_monat_minus3', 'zaehlerstand_jahr_minus1', 'zaehlerstand_jahr_minus2', 'zaehlerstand_jahr_minus3']
-ZAEHLERSTAND_ATTRIBUTES_TIMEFRAME = ['zaehlerstand_heute_minus1', 'zaehlerstand_heute_minus2', 'zaehlerstand_heute_minus3', 'zaehlerstand_tag_minus1', 'zaehlerstand_tag_minus2', 'zaehlerstand_tag_minus3', 'zaehlerstand_woche_minus1', 'zaehlerstand_woche_minus2', 'zaehlerstand_woche_minus3', 'zaehlerstand_monat_minus1', 'zaehlerstand_monat_minus2', 'zaehlerstand_monat_minus3', 'zaehlerstand_jahr_minus1', 'zaehlerstand_jahr_minus2', 'zaehlerstand_jahr_minus3']
-ALL_HISTORIE_ATTRIBUTES = ['minmax_last_24h_min', 'minmax_last_24h_max', 'minmax_last_24h_avg', 'minmax_last_7d_min', 'minmax_last_7d_max', 'minmax_last_7d_avg', 'minmax_heute_min', 'minmax_heute_max', 'minmax_heute_avg', 'minmax_heute_minus1_min', 'minmax_heute_minus1_max', 'minmax_heute_minus1_avg', 'minmax_heute_minus2_min', 'minmax_heute_minus2_max', 'minmax_heute_minus2_avg', 'minmax_heute_minus3_min', 'minmax_heute_minus3_max', 'minmax_heute_minus3_avg', 'minmax_tag_min', 'minmax_tag_max', 'minmax_tag_avg', 'minmax_tag_minus1_min', 'minmax_tag_minus1_max', 'minmax_tag_minus1_avg', 'minmax_tag_minus2_min', 'minmax_tag_minus2_max', 'minmax_tag_minus2_avg', 'minmax_tag_minus3_min', 'minmax_tag_minus3_max', 'minmax_tag_minus3_avg', 'minmax_woche_min', 'minmax_woche_max', 'minmax_woche_minus1_min', 'minmax_woche_minus1_max', 'minmax_woche_minus1_avg', 'minmax_woche_minus2_min', 'minmax_woche_minus2_max', 'minmax_woche_minus2_avg', 'minmax_monat_min', 'minmax_monat_max', 'minmax_monat_minus1_min', 'minmax_monat_minus1_max', 'minmax_monat_minus1_avg', 'minmax_monat_minus2_min', 'minmax_monat_minus2_max', 'minmax_monat_minus2_avg', 'minmax_jahr_min', 'minmax_jahr_max', 'minmax_jahr_minus1_min', 'minmax_jahr_minus1_max', 'minmax_jahr_minus1_avg']
-HISTORIE_ATTRIBUTES_ONCHANGE = ['minmax_heute_min', 'minmax_heute_max', 'minmax_heute_avg', 'minmax_tag_min', 'minmax_tag_max', 'minmax_tag_avg', 'minmax_woche_min', 'minmax_woche_max', 'minmax_monat_min', 'minmax_monat_max', 'minmax_jahr_min', 'minmax_jahr_max']
-HISTORIE_ATTRIBUTES_LAST = ['minmax_last_24h_min', 'minmax_last_24h_max', 'minmax_last_24h_avg', 'minmax_last_7d_min', 'minmax_last_7d_max', 'minmax_last_7d_avg']
-HISTORIE_ATTRIBUTES_TIMEFRAME = ['minmax_heute_minus1_min', 'minmax_heute_minus1_max', 'minmax_heute_minus1_avg', 'minmax_heute_minus2_min', 'minmax_heute_minus2_max', 'minmax_heute_minus2_avg', 'minmax_heute_minus3_min', 'minmax_heute_minus3_max', 'minmax_heute_minus3_avg', 'minmax_tag_minus1_min', 'minmax_tag_minus1_max', 'minmax_tag_minus1_avg', 'minmax_tag_minus2_min', 'minmax_tag_minus2_max', 'minmax_tag_minus2_avg', 'minmax_tag_minus3_min', 'minmax_tag_minus3_max', 'minmax_tag_minus3_avg', 'minmax_woche_minus1_min', 'minmax_woche_minus1_max', 'minmax_woche_minus1_avg', 'minmax_woche_minus2_min', 'minmax_woche_minus2_max', 'minmax_woche_minus2_avg', 'minmax_monat_minus1_min', 'minmax_monat_minus1_max', 'minmax_monat_minus1_avg', 'minmax_monat_minus2_min', 'minmax_monat_minus2_max', 'minmax_monat_minus2_avg', 'minmax_jahr_minus1_min', 'minmax_jahr_minus1_max', 'minmax_jahr_minus1_avg']
-ALL_TAGESMITTEL_ATTRIBUTES = ['tagesmitteltemperatur_heute', 'tagesmitteltemperatur_heute_minus1', 'tagesmitteltemperatur_heute_minus2', 'tagesmitteltemperatur_heute_minus3', 'tagesmitteltemperatur_tag', 'tagesmitteltemperatur_tag_minus1', 'tagesmitteltemperatur_tag_minus2', 'tagesmitteltemperatur_tag_minus3']
-TAGESMITTEL_ATTRIBUTES_ONCHANGE = ['tagesmitteltemperatur_heute', 'tagesmitteltemperatur_tag', 'minmax_heute_avg', 'minmax_tag_avg']
-TAGESMITTEL_ATTRIBUTES_TIMEFRAME = ['tagesmitteltemperatur_heute_minus1', 'tagesmitteltemperatur_heute_minus2', 'tagesmitteltemperatur_heute_minus3', 'tagesmitteltemperatur_tag_minus1', 'tagesmitteltemperatur_tag_minus2', 'tagesmitteltemperatur_tag_minus3']
-ALL_SERIE_ATTRIBUTES = ['serie_minmax_monat_min_15m', 'serie_minmax_monat_max_15m', 'serie_minmax_monat_avg_15m', 'serie_minmax_woche_min_30w', 'serie_minmax_woche_max_30w', 'serie_minmax_woche_avg_30w', 'serie_minmax_tag_min_30d', 'serie_minmax_tag_max_30d', 'serie_minmax_tag_avg_30d', 'serie_verbrauch_tag_30d', 'serie_verbrauch_woche_30w', 'serie_verbrauch_monat_18m', 'serie_zaehlerstand_tag_30d', 'serie_zaehlerstand_woche_30w', 'serie_zaehlerstand_monat_18m', 'serie_waermesumme_monat_24m', 'serie_kaeltesumme_monat_24m', 'serie_tagesmittelwert_0d', 'serie_tagesmittelwert_stunde_0d', 'serie_tagesmittelwert_stunde_30_0d', 'serie_tagesmittelwert_tag_stunde_30d']
-SERIE_ATTRIBUTES_MINMAX = ['serie_minmax_monat_min_15m', 'serie_minmax_monat_max_15m', 'serie_minmax_monat_avg_15m', 'serie_minmax_woche_min_30w', 'serie_minmax_woche_max_30w', 'serie_minmax_woche_avg_30w', 'serie_minmax_tag_min_30d', 'serie_minmax_tag_max_30d', 'serie_minmax_tag_avg_30d']
-SERIE_ATTRIBUTES_ZAEHLERSTAND = ['serie_zaehlerstand_tag_30d', 'serie_zaehlerstand_woche_30w', 'serie_zaehlerstand_monat_18m']
-SERIE_ATTRIBUTES_VERBRAUCH = ['serie_verbrauch_tag_30d', 'serie_verbrauch_woche_30w', 'serie_verbrauch_monat_18m']
-SERIE_ATTRIBUTES_SUMME = ['serie_waermesumme_monat_24m', 'serie_kaeltesumme_monat_24m']
-SERIE_ATTRIBUTES_MITTEL_D = ['serie_tagesmittelwert_0d']
-SERIE_ATTRIBUTES_MITTEL_H = ['serie_tagesmittelwert_stunde_0d']
-SERIE_ATTRIBUTES_MITTEL_H1 = ['serie_tagesmittelwert_stunde_30_0d']
-SERIE_ATTRIBUTES_MITTEL_D_H = ['serie_tagesmittelwert_tag_stunde_30d']
-ALL_GEN_ATTRIBUTES = ['general_oldest_value', 'general_oldest_log']
-ALL_SUMME_ATTRIBUTES = ['kaeltesumme', 'waermesumme', 'gruenlandtempsumme', 'wachstumsgradtage', 'wuestentage', 'heisse_tage', 'tropennaechte', 'sommertage', 'heiztage', 'vegetationstage', 'frosttage', 'eistage']
-ALL_COMPLEX_ATTRIBUTES = ['tagesmitteltemperatur', 'db_request', 'minmax', 'minmax_last', 'verbrauch', 'zaehlerstand']
diff --git a/db_addon/item_attributes_master.py b/db_addon/item_attributes_master.py
index 2351f2812..142e21bf3 100644
--- a/db_addon/item_attributes_master.py
+++ b/db_addon/item_attributes_master.py
@@ -27,176 +27,178 @@
DOC_FILE_NAME = 'user_doc.rst'
-PLUGIN_VERSION = '1.2.6'
+PLUGIN_VERSION = '1.2.10'
ITEM_ATTRIBUTES = {
'db_addon_fct': {
- 'verbrauch_heute': {'cat': 'verbrauch', 'sub_cat': 'onchange', 'item_type': 'num', 'cycle': None, 'params': False, 'description': 'Verbrauch am heutigen Tag (Differenz zwischen aktuellem Wert und den Wert am Ende des vorherigen Tages)'},
- 'verbrauch_tag': {'cat': 'verbrauch', 'sub_cat': 'onchange', 'item_type': 'num', 'cycle': None, 'params': False, 'description': 'Verbrauch am heutigen Tag (Differenz zwischen aktuellem Wert und den Wert am Ende des vorherigen Tages)'},
- 'verbrauch_woche': {'cat': 'verbrauch', 'sub_cat': 'onchange', 'item_type': 'num', 'cycle': None, 'params': False, 'description': 'Verbrauch in der aktuellen Woche'},
- 'verbrauch_monat': {'cat': 'verbrauch', 'sub_cat': 'onchange', 'item_type': 'num', 'cycle': None, 'params': False, 'description': 'Verbrauch im aktuellen Monat'},
- 'verbrauch_jahr': {'cat': 'verbrauch', 'sub_cat': 'onchange', 'item_type': 'num', 'cycle': None, 'params': False, 'description': 'Verbrauch im aktuellen Jahr'},
- 'verbrauch_last_24h': {'cat': 'verbrauch', 'sub_cat': 'last', 'item_type': 'num', 'cycle': 'hourly', 'params': False, 'description': 'Verbrauch innerhalb letzten 24h'},
- 'verbrauch_last_7d': {'cat': 'verbrauch', 'sub_cat': 'last', 'item_type': 'num', 'cycle': 'hourly', 'params': False, 'description': 'Verbrauch innerhalb letzten 7 Tage'},
- 'verbrauch_heute_minus1': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'daily', 'params': False, 'description': 'Verbrauch gestern (heute -1 Tag) (Differenz zwischen Wert am Ende des gestrigen Tages und dem Wert am Ende des Tages davor)'},
- 'verbrauch_heute_minus2': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'daily', 'params': False, 'description': 'Verbrauch vorgestern (heute -2 Tage)'},
- 'verbrauch_heute_minus3': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'daily', 'params': False, 'description': 'Verbrauch heute -3 Tage'},
- 'verbrauch_heute_minus4': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'daily', 'params': False, 'description': 'Verbrauch heute -4 Tage'},
- 'verbrauch_heute_minus5': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'daily', 'params': False, 'description': 'Verbrauch heute -5 Tage'},
- 'verbrauch_heute_minus6': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'daily', 'params': False, 'description': 'Verbrauch heute -6 Tage'},
- 'verbrauch_heute_minus7': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'daily', 'params': False, 'description': 'Verbrauch heute -7 Tage'},
- 'verbrauch_heute_minus8': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'daily', 'params': False, 'description': 'Verbrauch heute -8 Tage'},
- 'verbrauch_tag_minus1': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'daily', 'params': False, 'description': 'Verbrauch gestern (heute -1 Tag) (Differenz zwischen Wert am Ende des gestrigen Tages und dem Wert am Ende des Tages davor)'},
- 'verbrauch_tag_minus2': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'daily', 'params': False, 'description': 'Verbrauch vorgestern (heute -2 Tage)'},
- 'verbrauch_tag_minus3': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'daily', 'params': False, 'description': 'Verbrauch heute -3 Tage'},
- 'verbrauch_tag_minus4': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'daily', 'params': False, 'description': 'Verbrauch heute -4 Tage'},
- 'verbrauch_tag_minus5': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'daily', 'params': False, 'description': 'Verbrauch heute -5 Tage'},
- 'verbrauch_tag_minus6': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'daily', 'params': False, 'description': 'Verbrauch heute -6 Tage'},
- 'verbrauch_tag_minus7': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'daily', 'params': False, 'description': 'Verbrauch heute -7 Tage'},
- 'verbrauch_tag_minus8': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'daily', 'params': False, 'description': 'Verbrauch heute -8 Tage'},
- 'verbrauch_woche_minus1': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'weekly', 'params': False, 'description': 'Verbrauch Vorwoche (aktuelle Woche -1)'},
- 'verbrauch_woche_minus2': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'weekly', 'params': False, 'description': 'Verbrauch aktuelle Woche -2 Wochen'},
- 'verbrauch_woche_minus3': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'weekly', 'params': False, 'description': 'Verbrauch aktuelle Woche -3 Wochen'},
- 'verbrauch_woche_minus4': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'weekly', 'params': False, 'description': 'Verbrauch aktuelle Woche -4 Wochen'},
- 'verbrauch_monat_minus1': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'monthly', 'params': False, 'description': 'Verbrauch Vormonat (aktueller Monat -1)'},
- 'verbrauch_monat_minus2': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'monthly', 'params': False, 'description': 'Verbrauch aktueller Monat -2 Monate'},
- 'verbrauch_monat_minus3': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'monthly', 'params': False, 'description': 'Verbrauch aktueller Monat -3 Monate'},
- 'verbrauch_monat_minus4': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'monthly', 'params': False, 'description': 'Verbrauch aktueller Monat -4 Monate'},
- 'verbrauch_monat_minus12': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'monthly', 'params': False, 'description': 'Verbrauch aktueller Monat -12 Monate'},
- 'verbrauch_jahr_minus1': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'yearly', 'params': False, 'description': 'Verbrauch Vorjahr (aktuelles Jahr -1 Jahr)'},
- 'verbrauch_jahr_minus2': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'yearly', 'params': False, 'description': 'Verbrauch aktuelles Jahr -2 Jahre'},
- 'verbrauch_jahr_minus3': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'yearly', 'params': False, 'description': 'Verbrauch aktuelles Jahr -3 Jahre'},
- 'verbrauch_rolling_12m_heute_minus1': {'cat': 'verbrauch', 'sub_cat': 'rolling', 'item_type': 'num', 'cycle': 'daily', 'params': False, 'description': 'Verbrauch der letzten 12 Monate ausgehend im Ende des letzten Tages'},
- 'verbrauch_rolling_12m_tag_minus1': {'cat': 'verbrauch', 'sub_cat': 'rolling', 'item_type': 'num', 'cycle': 'daily', 'params': False, 'description': 'Verbrauch der letzten 12 Monate ausgehend im Ende des letzten Tages'},
- 'verbrauch_rolling_12m_woche_minus1': {'cat': 'verbrauch', 'sub_cat': 'rolling', 'item_type': 'num', 'cycle': 'weekly', 'params': False, 'description': 'Verbrauch der letzten 12 Monate ausgehend im Ende der letzten Woche'},
- 'verbrauch_rolling_12m_monat_minus1': {'cat': 'verbrauch', 'sub_cat': 'rolling', 'item_type': 'num', 'cycle': 'monthly', 'params': False, 'description': 'Verbrauch der letzten 12 Monate ausgehend im Ende des letzten Monats'},
- 'verbrauch_rolling_12m_jahr_minus1': {'cat': 'verbrauch', 'sub_cat': 'rolling', 'item_type': 'num', 'cycle': 'yearly', 'params': False, 'description': 'Verbrauch der letzten 12 Monate ausgehend im Ende des letzten Jahres'},
- 'verbrauch_jahreszeitraum_minus1': {'cat': 'verbrauch', 'sub_cat': 'jahrzeit', 'item_type': 'num', 'cycle': 'daily', 'params': False, 'description': 'Verbrauch seit dem 1.1. bis zum heutigen Tag des Vorjahres'},
- 'verbrauch_jahreszeitraum_minus2': {'cat': 'verbrauch', 'sub_cat': 'jahrzeit', 'item_type': 'num', 'cycle': 'daily', 'params': False, 'description': 'Verbrauch seit dem 1.1. bis zum heutigen Tag vor 2 Jahren'},
- 'verbrauch_jahreszeitraum_minus3': {'cat': 'verbrauch', 'sub_cat': 'jahrzeit', 'item_type': 'num', 'cycle': 'daily', 'params': False, 'description': 'Verbrauch seit dem 1.1. bis zum heutigen Tag vor 3 Jahren'},
- 'zaehlerstand_heute_minus1': {'cat': 'zaehler', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'daily', 'params': False, 'description': 'Zählerstand / Wert am Ende des letzten Tages (heute -1 Tag)'},
- 'zaehlerstand_heute_minus2': {'cat': 'zaehler', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'daily', 'params': False, 'description': 'Zählerstand / Wert am Ende des vorletzten Tages (heute -2 Tag)'},
- 'zaehlerstand_heute_minus3': {'cat': 'zaehler', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'daily', 'params': False, 'description': 'Zählerstand / Wert am Ende des vorvorletzten Tages (heute -3 Tag)'},
- 'zaehlerstand_tag_minus1': {'cat': 'zaehler', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'daily', 'params': False, 'description': 'Zählerstand / Wert am Ende des letzten Tages (heute -1 Tag)'},
- 'zaehlerstand_tag_minus2': {'cat': 'zaehler', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'daily', 'params': False, 'description': 'Zählerstand / Wert am Ende des vorletzten Tages (heute -2 Tag)'},
- 'zaehlerstand_tag_minus3': {'cat': 'zaehler', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'daily', 'params': False, 'description': 'Zählerstand / Wert am Ende des vorvorletzten Tages (heute -3 Tag)'},
- 'zaehlerstand_woche_minus1': {'cat': 'zaehler', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'weekly', 'params': False, 'description': 'Zählerstand / Wert am Ende der vorvorletzten Woche (aktuelle Woche -1 Woche)'},
- 'zaehlerstand_woche_minus2': {'cat': 'zaehler', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'weekly', 'params': False, 'description': 'Zählerstand / Wert am Ende der vorletzten Woche (aktuelle Woche -2 Wochen)'},
- 'zaehlerstand_woche_minus3': {'cat': 'zaehler', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'weekly', 'params': False, 'description': 'Zählerstand / Wert am Ende der aktuellen Woche -3 Wochen'},
- 'zaehlerstand_monat_minus1': {'cat': 'zaehler', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'monthly', 'params': False, 'description': 'Zählerstand / Wert am Ende des letzten Monates (aktueller Monat -1 Monat)'},
- 'zaehlerstand_monat_minus2': {'cat': 'zaehler', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'monthly', 'params': False, 'description': 'Zählerstand / Wert am Ende des vorletzten Monates (aktueller Monat -2 Monate)'},
- 'zaehlerstand_monat_minus3': {'cat': 'zaehler', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'monthly', 'params': False, 'description': 'Zählerstand / Wert am Ende des aktuellen Monats -3 Monate'},
- 'zaehlerstand_jahr_minus1': {'cat': 'zaehler', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'yearly', 'params': False, 'description': 'Zählerstand / Wert am Ende des letzten Jahres (aktuelles Jahr -1 Jahr)'},
- 'zaehlerstand_jahr_minus2': {'cat': 'zaehler', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'yearly', 'params': False, 'description': 'Zählerstand / Wert am Ende des vorletzten Jahres (aktuelles Jahr -2 Jahre)'},
- 'zaehlerstand_jahr_minus3': {'cat': 'zaehler', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'yearly', 'params': False, 'description': 'Zählerstand / Wert am Ende des aktuellen Jahres -3 Jahre'},
- 'minmax_last_24h_min': {'cat': 'wertehistorie', 'sub_cat': 'last', 'item_type': 'num', 'cycle': 'daily', 'params': False, 'description': 'minimaler Wert der letzten 24h'},
- 'minmax_last_24h_max': {'cat': 'wertehistorie', 'sub_cat': 'last', 'item_type': 'num', 'cycle': 'daily', 'params': False, 'description': 'maximaler Wert der letzten 24h'},
- 'minmax_last_24h_avg': {'cat': 'wertehistorie', 'sub_cat': 'last', 'item_type': 'num', 'cycle': 'daily', 'params': False, 'description': 'durchschnittlicher Wert der letzten 24h'},
- 'minmax_last_7d_min': {'cat': 'wertehistorie', 'sub_cat': 'last', 'item_type': 'num', 'cycle': 'daily', 'params': False, 'description': 'minimaler Wert der letzten 7 Tage'},
- 'minmax_last_7d_max': {'cat': 'wertehistorie', 'sub_cat': 'last', 'item_type': 'num', 'cycle': 'daily', 'params': False, 'description': 'maximaler Wert der letzten 7 Tage'},
- 'minmax_last_7d_avg': {'cat': 'wertehistorie', 'sub_cat': 'last', 'item_type': 'num', 'cycle': 'daily', 'params': False, 'description': 'durchschnittlicher Wert der letzten 7 Tage'},
- 'minmax_heute_min': {'cat': 'wertehistorie', 'sub_cat': 'onchange', 'item_type': 'num', 'cycle': None, 'params': False, 'description': 'Minimalwert seit Tagesbeginn'},
- 'minmax_heute_max': {'cat': 'wertehistorie', 'sub_cat': 'onchange', 'item_type': 'num', 'cycle': None, 'params': False, 'description': 'Maximalwert seit Tagesbeginn'},
- 'minmax_heute_avg': {'cat': 'wertehistorie', 'sub_cat': 'onchange', 'item_type': 'num', 'cycle': None, 'params': False, 'description': 'Durchschnittswert seit Tagesbeginn'},
- 'minmax_heute_minus1_min': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'daily', 'params': False, 'description': 'Minimalwert gestern (heute -1 Tag)'},
- 'minmax_heute_minus1_max': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'daily', 'params': False, 'description': 'Maximalwert gestern (heute -1 Tag)'},
- 'minmax_heute_minus1_avg': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'daily', 'params': False, 'description': 'Durchschnittswert gestern (heute -1 Tag)'},
- 'minmax_heute_minus2_min': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'daily', 'params': False, 'description': 'Minimalwert vorgestern (heute -2 Tage)'},
- 'minmax_heute_minus2_max': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'daily', 'params': False, 'description': 'Maximalwert vorgestern (heute -2 Tage)'},
- 'minmax_heute_minus2_avg': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'daily', 'params': False, 'description': 'Durchschnittswert vorgestern (heute -2 Tage)'},
- 'minmax_heute_minus3_min': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'daily', 'params': False, 'description': 'Minimalwert heute vor 3 Tagen'},
- 'minmax_heute_minus3_max': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'daily', 'params': False, 'description': 'Maximalwert heute vor 3 Tagen'},
- 'minmax_heute_minus3_avg': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'daily', 'params': False, 'description': 'Durchschnittswert heute vor 3 Tagen'},
- 'minmax_tag_min': {'cat': 'wertehistorie', 'sub_cat': 'onchange', 'item_type': 'num', 'cycle': None, 'params': False, 'description': 'Minimalwert seit Tagesbeginn'},
- 'minmax_tag_max': {'cat': 'wertehistorie', 'sub_cat': 'onchange', 'item_type': 'num', 'cycle': None, 'params': False, 'description': 'Maximalwert seit Tagesbeginn'},
- 'minmax_tag_avg': {'cat': 'wertehistorie', 'sub_cat': 'onchange', 'item_type': 'num', 'cycle': None, 'params': False, 'description': 'Durchschnittswert seit Tagesbeginn'},
- 'minmax_tag_minus1_min': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'daily', 'params': False, 'description': 'Minimalwert gestern (heute -1 Tag)'},
- 'minmax_tag_minus1_max': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'daily', 'params': False, 'description': 'Maximalwert gestern (heute -1 Tag)'},
- 'minmax_tag_minus1_avg': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'daily', 'params': False, 'description': 'Durchschnittswert gestern (heute -1 Tag)'},
- 'minmax_tag_minus2_min': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'daily', 'params': False, 'description': 'Minimalwert vorgestern (heute -2 Tage)'},
- 'minmax_tag_minus2_max': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'daily', 'params': False, 'description': 'Maximalwert vorgestern (heute -2 Tage)'},
- 'minmax_tag_minus2_avg': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'daily', 'params': False, 'description': 'Durchschnittswert vorgestern (heute -2 Tage)'},
- 'minmax_tag_minus3_min': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'daily', 'params': False, 'description': 'Minimalwert heute vor 3 Tagen'},
- 'minmax_tag_minus3_max': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'daily', 'params': False, 'description': 'Maximalwert heute vor 3 Tagen'},
- 'minmax_tag_minus3_avg': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'daily', 'params': False, 'description': 'Durchschnittswert heute vor 3 Tagen'},
- 'minmax_woche_min': {'cat': 'wertehistorie', 'sub_cat': 'onchange', 'item_type': 'num', 'cycle': None, 'params': False, 'description': 'Minimalwert seit Wochenbeginn'},
- 'minmax_woche_max': {'cat': 'wertehistorie', 'sub_cat': 'onchange', 'item_type': 'num', 'cycle': None, 'params': False, 'description': 'Maximalwert seit Wochenbeginn'},
- 'minmax_woche_minus1_min': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'weekly', 'params': False, 'description': 'Minimalwert Vorwoche (aktuelle Woche -1)'},
- 'minmax_woche_minus1_max': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'weekly', 'params': False, 'description': 'Maximalwert Vorwoche (aktuelle Woche -1)'},
- 'minmax_woche_minus1_avg': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'weekly', 'params': False, 'description': 'Durchschnittswert Vorwoche (aktuelle Woche -1)'},
- 'minmax_woche_minus2_min': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'weekly', 'params': False, 'description': 'Minimalwert aktuelle Woche -2 Wochen'},
- 'minmax_woche_minus2_max': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'weekly', 'params': False, 'description': 'Maximalwert aktuelle Woche -2 Wochen'},
- 'minmax_woche_minus2_avg': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'weekly', 'params': False, 'description': 'Durchschnittswert aktuelle Woche -2 Wochen'},
- 'minmax_monat_min': {'cat': 'wertehistorie', 'sub_cat': 'onchange', 'item_type': 'num', 'cycle': None, 'params': False, 'description': 'Minimalwert seit Monatsbeginn'},
- 'minmax_monat_max': {'cat': 'wertehistorie', 'sub_cat': 'onchange', 'item_type': 'num', 'cycle': None, 'params': False, 'description': 'Maximalwert seit Monatsbeginn'},
- 'minmax_monat_minus1_min': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'monthly', 'params': False, 'description': 'Minimalwert Vormonat (aktueller Monat -1)'},
- 'minmax_monat_minus1_max': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'monthly', 'params': False, 'description': 'Maximalwert Vormonat (aktueller Monat -1)'},
- 'minmax_monat_minus1_avg': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'monthly', 'params': False, 'description': 'Durchschnittswert Vormonat (aktueller Monat -1)'},
- 'minmax_monat_minus2_min': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'monthly', 'params': False, 'description': 'Minimalwert aktueller Monat -2 Monate'},
- 'minmax_monat_minus2_max': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'monthly', 'params': False, 'description': 'Maximalwert aktueller Monat -2 Monate'},
- 'minmax_monat_minus2_avg': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'monthly', 'params': False, 'description': 'Durchschnittswert aktueller Monat -2 Monate'},
- 'minmax_jahr_min': {'cat': 'wertehistorie', 'sub_cat': 'onchange', 'item_type': 'num', 'cycle': None, 'params': False, 'description': 'Minimalwert seit Jahresbeginn'},
- 'minmax_jahr_max': {'cat': 'wertehistorie', 'sub_cat': 'onchange', 'item_type': 'num', 'cycle': None, 'params': False, 'description': 'Maximalwert seit Jahresbeginn'},
- 'minmax_jahr_minus1_min': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'yearly', 'params': False, 'description': 'Minimalwert Vorjahr (aktuelles Jahr -1 Jahr)'},
- 'minmax_jahr_minus1_max': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'yearly', 'params': False, 'description': 'Maximalwert Vorjahr (aktuelles Jahr -1 Jahr)'},
- 'minmax_jahr_minus1_avg': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'yearly', 'params': False, 'description': 'Durchschnittswert Vorjahr (aktuelles Jahr -1 Jahr)'},
- 'tagesmitteltemperatur_heute': {'cat': 'tagesmittel', 'sub_cat': 'onchange', 'item_type': 'num', 'cycle': None, 'params': False, 'description': 'Tagesmitteltemperatur heute'},
- 'tagesmitteltemperatur_heute_minus1': {'cat': 'tagesmittel', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'daily', 'params': False, 'description': 'Tagesmitteltemperatur des letzten Tages (heute -1 Tag)'},
- 'tagesmitteltemperatur_heute_minus2': {'cat': 'tagesmittel', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'daily', 'params': False, 'description': 'Tagesmitteltemperatur des vorletzten Tages (heute -2 Tag)'},
- 'tagesmitteltemperatur_heute_minus3': {'cat': 'tagesmittel', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'daily', 'params': False, 'description': 'Tagesmitteltemperatur des vorvorletzten Tages (heute -3 Tag)'},
- 'tagesmitteltemperatur_tag': {'cat': 'tagesmittel', 'sub_cat': 'onchange', 'item_type': 'num', 'cycle': None, 'params': False, 'description': 'Tagesmitteltemperatur heute'},
- 'tagesmitteltemperatur_tag_minus1': {'cat': 'tagesmittel', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'daily', 'params': False, 'description': 'Tagesmitteltemperatur des letzten Tages (heute -1 Tag)'},
- 'tagesmitteltemperatur_tag_minus2': {'cat': 'tagesmittel', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'daily', 'params': False, 'description': 'Tagesmitteltemperatur des vorletzten Tages (heute -2 Tag)'},
- 'tagesmitteltemperatur_tag_minus3': {'cat': 'tagesmittel', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'daily', 'params': False, 'description': 'Tagesmitteltemperatur des vorvorletzten Tages (heute -3 Tag)'},
- 'serie_minmax_monat_min_15m': {'cat': 'serie', 'sub_cat': 'minmax', 'item_type': 'list', 'cycle': 'monthly', 'params': False, 'description': 'monatlicher Minimalwert der letzten 15 Monate (gleitend)'},
- 'serie_minmax_monat_max_15m': {'cat': 'serie', 'sub_cat': 'minmax', 'item_type': 'list', 'cycle': 'monthly', 'params': False, 'description': 'monatlicher Maximalwert der letzten 15 Monate (gleitend)'},
- 'serie_minmax_monat_avg_15m': {'cat': 'serie', 'sub_cat': 'minmax', 'item_type': 'list', 'cycle': 'monthly', 'params': False, 'description': 'monatlicher Mittelwert der letzten 15 Monate (gleitend)'},
- 'serie_minmax_woche_min_30w': {'cat': 'serie', 'sub_cat': 'minmax', 'item_type': 'list', 'cycle': 'weekly', 'params': False, 'description': 'wöchentlicher Minimalwert der letzten 30 Wochen (gleitend)'},
- 'serie_minmax_woche_max_30w': {'cat': 'serie', 'sub_cat': 'minmax', 'item_type': 'list', 'cycle': 'weekly', 'params': False, 'description': 'wöchentlicher Maximalwert der letzten 30 Wochen (gleitend)'},
- 'serie_minmax_woche_avg_30w': {'cat': 'serie', 'sub_cat': 'minmax', 'item_type': 'list', 'cycle': 'weekly', 'params': False, 'description': 'wöchentlicher Mittelwert der letzten 30 Wochen (gleitend)'},
- 'serie_minmax_tag_min_30d': {'cat': 'serie', 'sub_cat': 'minmax', 'item_type': 'list', 'cycle': 'daily', 'params': False, 'description': 'täglicher Minimalwert der letzten 30 Tage (gleitend)'},
- 'serie_minmax_tag_max_30d': {'cat': 'serie', 'sub_cat': 'minmax', 'item_type': 'list', 'cycle': 'daily', 'params': False, 'description': 'täglicher Maximalwert der letzten 30 Tage (gleitend)'},
- 'serie_minmax_tag_avg_30d': {'cat': 'serie', 'sub_cat': 'minmax', 'item_type': 'list', 'cycle': 'daily', 'params': False, 'description': 'täglicher Mittelwert der letzten 30 Tage (gleitend)'},
- 'serie_verbrauch_tag_30d': {'cat': 'serie', 'sub_cat': 'verbrauch', 'item_type': 'list', 'cycle': 'daily', 'params': False, 'description': 'Verbrauch pro Tag der letzten 30 Tage'},
- 'serie_verbrauch_woche_30w': {'cat': 'serie', 'sub_cat': 'verbrauch', 'item_type': 'list', 'cycle': 'weekly', 'params': False, 'description': 'Verbrauch pro Woche der letzten 30 Wochen'},
- 'serie_verbrauch_monat_18m': {'cat': 'serie', 'sub_cat': 'verbrauch', 'item_type': 'list', 'cycle': 'monthly', 'params': False, 'description': 'Verbrauch pro Monat der letzten 18 Monate'},
- 'serie_zaehlerstand_tag_30d': {'cat': 'serie', 'sub_cat': 'zaehler', 'item_type': 'list', 'cycle': 'daily', 'params': False, 'description': 'Zählerstand am Tagesende der letzten 30 Tage'},
- 'serie_zaehlerstand_woche_30w': {'cat': 'serie', 'sub_cat': 'zaehler', 'item_type': 'list', 'cycle': 'weekly', 'params': False, 'description': 'Zählerstand am Wochenende der letzten 30 Wochen'},
- 'serie_zaehlerstand_monat_18m': {'cat': 'serie', 'sub_cat': 'zaehler', 'item_type': 'list', 'cycle': 'monthly', 'params': False, 'description': 'Zählerstand am Monatsende der letzten 18 Monate'},
- 'serie_waermesumme_monat_24m': {'cat': 'serie', 'sub_cat': 'summe', 'item_type': 'list', 'cycle': 'monthly', 'params': False, 'description': 'monatliche Wärmesumme der letzten 24 Monate'},
- 'serie_kaeltesumme_monat_24m': {'cat': 'serie', 'sub_cat': 'summe', 'item_type': 'list', 'cycle': 'monthly', 'params': False, 'description': 'monatliche Kältesumme der letzten 24 Monate'},
- 'serie_tagesmittelwert_0d': {'cat': 'serie', 'sub_cat': 'mittel_d', 'item_type': 'list', 'cycle': 'daily', 'params': False, 'description': 'Tagesmittelwert für den aktuellen Tag'},
- 'serie_tagesmittelwert_stunde_0d': {'cat': 'serie', 'sub_cat': 'mittel_h', 'item_type': 'list', 'cycle': 'daily', 'params': False, 'description': 'Stundenmittelwert für den aktuellen Tag'},
- 'serie_tagesmittelwert_stunde_30_0d': {'cat': 'serie', 'sub_cat': 'mittel_h1', 'item_type': 'list', 'cycle': 'daily', 'params': False, 'description': 'Stundenmittelwert für den aktuellen Tag'},
- 'serie_tagesmittelwert_tag_stunde_30d': {'cat': 'serie', 'sub_cat': 'mittel_d_h', 'item_type': 'list', 'cycle': 'daily', 'params': False, 'description': 'Stundenmittelwert pro Tag der letzten 30 Tage (bspw. zur Berechnung der Tagesmitteltemperatur basierend auf den Mittelwert der Temperatur pro Stunde'},
- 'general_oldest_value': {'cat': 'gen', 'sub_cat': None, 'item_type': 'num', 'cycle': None, 'params': False, 'description': 'Ausgabe des ältesten Wertes des entsprechenden "Parent-Items" mit database Attribut'},
- 'general_oldest_log': {'cat': 'gen', 'sub_cat': None, 'item_type': 'list', 'cycle': None, 'params': False, 'description': 'Ausgabe des Timestamp des ältesten Eintrages des entsprechenden "Parent-Items" mit database Attribut'},
- 'kaeltesumme': {'cat': 'summe', 'sub_cat': None, 'item_type': 'num', 'cycle': 'daily', 'params': True, 'description': 'Berechnet die Kältesumme für einen Zeitraum, db_addon_params: (year=optional, month=optional)'},
- 'waermesumme': {'cat': 'summe', 'sub_cat': None, 'item_type': 'num', 'cycle': 'daily', 'params': True, 'description': 'Berechnet die Wärmesumme für einen Zeitraum, db_addon_params: (year=optional, month=optional)'},
- 'gruenlandtempsumme': {'cat': 'summe', 'sub_cat': None, 'item_type': 'num', 'cycle': 'daily', 'params': True, 'description': 'Berechnet die Grünlandtemperatursumme für einen Zeitraum, db_addon_params: (year=optional)'},
- 'wachstumsgradtage': {'cat': 'summe', 'sub_cat': None, 'item_type': 'num', 'cycle': 'daily', 'params': True, 'description': 'Berechnet die Wachstumsgradtage auf Basis der stündlichen Durchschnittswerte eines Tages für das laufende Jahr mit an Angabe des Temperaturschwellenwertes (threshold=Schwellentemperatur)'},
- 'wuestentage': {'cat': 'summe', 'sub_cat': 'kenntage', 'item_type': 'num', 'cycle': 'daily', 'params': True, 'description': 'Berechnet die Anzahl der Wüstentage des Jahres, db_addon_params: (year=optional)'},
- 'heisse_tage': {'cat': 'summe', 'sub_cat': 'kenntage', 'item_type': 'num', 'cycle': 'daily', 'params': True, 'description': 'Berechnet die Anzahl der heissen Tage des Jahres, db_addon_params: (year=optional)'},
- 'tropennaechte': {'cat': 'summe', 'sub_cat': 'kenntage', 'item_type': 'num', 'cycle': 'daily', 'params': True, 'description': 'Berechnet die Anzahl der Tropennächte des Jahres, db_addon_params: (year=optional)'},
- 'sommertage': {'cat': 'summe', 'sub_cat': 'kenntage', 'item_type': 'num', 'cycle': 'daily', 'params': True, 'description': 'Berechnet die Anzahl der Sommertage des Jahres, db_addon_params: (year=optional)'},
- 'heiztage': {'cat': 'summe', 'sub_cat': 'kenntage', 'item_type': 'num', 'cycle': 'daily', 'params': True, 'description': 'Berechnet die Anzahl der Heiztage des Jahres, db_addon_params: (year=optional)'},
- 'vegetationstage': {'cat': 'summe', 'sub_cat': 'kenntage', 'item_type': 'num', 'cycle': 'daily', 'params': True, 'description': 'Berechnet die Anzahl der Vegatationstage des Jahres, db_addon_params: (year=optional)'},
- 'frosttage': {'cat': 'summe', 'sub_cat': 'kenntage', 'item_type': 'num', 'cycle': 'daily', 'params': True, 'description': 'Berechnet die Anzahl der Frosttage des Jahres, db_addon_params: (year=optional)'},
- 'eistage': {'cat': 'summe', 'sub_cat': 'kenntage', 'item_type': 'num', 'cycle': 'daily', 'params': True, 'description': 'Berechnet die Anzahl der Eistage des Jahres, db_addon_params: (year=optional)'},
- 'tagesmitteltemperatur': {'cat': 'complex', 'sub_cat': None, 'item_type': 'list', 'cycle': 'daily', 'params': True, 'description': 'Berechnet die Tagesmitteltemperatur auf Basis der stündlichen Durchschnittswerte eines Tages für die angegebene Anzahl von Tagen (timeframe=day, count=integer)'},
- 'db_request': {'cat': 'complex', 'sub_cat': None, 'item_type': 'list', 'cycle': 'group', 'params': True, 'description': 'Abfrage der DB: db_addon_params: (func=mandatory, item=mandatory, timespan=mandatory, start=optional, end=optional, count=optional, group=optional, group2=optional)'},
- 'minmax': {'cat': 'complex', 'sub_cat': None, 'item_type': 'num', 'cycle': 'timeframe', 'params': True, 'description': 'Berechnet einen min/max/avg Wert für einen bestimmen Zeitraum: db_addon_params: (func=mandatory, timeframe=mandatory, start=mandatory)'},
- 'minmax_last': {'cat': 'complex', 'sub_cat': None, 'item_type': 'num', 'cycle': 'timeframe', 'params': True, 'description': 'Berechnet einen min/max/avg Wert für ein bestimmtes Zeitfenster von jetzt zurück: db_addon_params: (func=mandatory, timeframe=mandatory, start=mandatory, end=mandatory)'},
- 'verbrauch': {'cat': 'complex', 'sub_cat': None, 'item_type': 'num', 'cycle': 'timeframe', 'params': True, 'description': 'Berechnet einen Verbrauchswert für einen bestimmen Zeitraum: db_addon_params: (timeframe=mandatory, start=mandatory end=mandatory)'},
- 'zaehlerstand': {'cat': 'complex', 'sub_cat': None, 'item_type': 'num', 'cycle': 'timeframe', 'params': True, 'description': 'Berechnet einen Zählerstand für einen bestimmen Zeitpunkt: db_addon_params: (timeframe=mandatory, start=mandatory)'},
+ 'verbrauch_heute': {'cat': 'verbrauch', 'sub_cat': 'onchange', 'item_type': 'num', 'cycle': None, 'params': None, 'description': 'Verbrauch am heutigen Tag (Differenz zwischen aktuellem Wert und den Wert am Ende des vorherigen Tages)'},
+ 'verbrauch_tag': {'cat': 'verbrauch', 'sub_cat': 'onchange', 'item_type': 'num', 'cycle': None, 'params': None, 'description': 'Verbrauch am heutigen Tag (Differenz zwischen aktuellem Wert und den Wert am Ende des vorherigen Tages)'},
+ 'verbrauch_woche': {'cat': 'verbrauch', 'sub_cat': 'onchange', 'item_type': 'num', 'cycle': None, 'params': None, 'description': 'Verbrauch in der aktuellen Woche'},
+ 'verbrauch_monat': {'cat': 'verbrauch', 'sub_cat': 'onchange', 'item_type': 'num', 'cycle': None, 'params': None, 'description': 'Verbrauch im aktuellen Monat'},
+ 'verbrauch_jahr': {'cat': 'verbrauch', 'sub_cat': 'onchange', 'item_type': 'num', 'cycle': None, 'params': None, 'description': 'Verbrauch im aktuellen Jahr'},
+ 'verbrauch_last_24h': {'cat': 'verbrauch', 'sub_cat': 'last', 'item_type': 'num', 'cycle': 'hourly', 'params': None, 'description': 'Verbrauch innerhalb letzten 24h'},
+ 'verbrauch_last_7d': {'cat': 'verbrauch', 'sub_cat': 'last', 'item_type': 'num', 'cycle': 'hourly', 'params': None, 'description': 'Verbrauch innerhalb letzten 7 Tage'},
+ 'verbrauch_heute_minus1': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'daily', 'params': None, 'description': 'Verbrauch gestern (heute -1 Tag) (Differenz zwischen Wert am Ende des gestrigen Tages und dem Wert am Ende des Tages davor)'},
+ 'verbrauch_heute_minus2': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'daily', 'params': None, 'description': 'Verbrauch vorgestern (heute -2 Tage)'},
+ 'verbrauch_heute_minus3': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'daily', 'params': None, 'description': 'Verbrauch heute -3 Tage'},
+ 'verbrauch_heute_minus4': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'daily', 'params': None, 'description': 'Verbrauch heute -4 Tage'},
+ 'verbrauch_heute_minus5': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'daily', 'params': None, 'description': 'Verbrauch heute -5 Tage'},
+ 'verbrauch_heute_minus6': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'daily', 'params': None, 'description': 'Verbrauch heute -6 Tage'},
+ 'verbrauch_heute_minus7': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'daily', 'params': None, 'description': 'Verbrauch heute -7 Tage'},
+ 'verbrauch_heute_minus8': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'daily', 'params': None, 'description': 'Verbrauch heute -8 Tage'},
+ 'verbrauch_tag_minus1': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'daily', 'params': None, 'description': 'Verbrauch gestern (heute -1 Tag) (Differenz zwischen Wert am Ende des gestrigen Tages und dem Wert am Ende des Tages davor)'},
+ 'verbrauch_tag_minus2': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'daily', 'params': None, 'description': 'Verbrauch vorgestern (heute -2 Tage)'},
+ 'verbrauch_tag_minus3': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'daily', 'params': None, 'description': 'Verbrauch heute -3 Tage'},
+ 'verbrauch_tag_minus4': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'daily', 'params': None, 'description': 'Verbrauch heute -4 Tage'},
+ 'verbrauch_tag_minus5': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'daily', 'params': None, 'description': 'Verbrauch heute -5 Tage'},
+ 'verbrauch_tag_minus6': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'daily', 'params': None, 'description': 'Verbrauch heute -6 Tage'},
+ 'verbrauch_tag_minus7': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'daily', 'params': None, 'description': 'Verbrauch heute -7 Tage'},
+ 'verbrauch_tag_minus8': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'daily', 'params': None, 'description': 'Verbrauch heute -8 Tage'},
+ 'verbrauch_woche_minus1': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'weekly', 'params': None, 'description': 'Verbrauch Vorwoche (aktuelle Woche -1)'},
+ 'verbrauch_woche_minus2': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'weekly', 'params': None, 'description': 'Verbrauch aktuelle Woche -2 Wochen'},
+ 'verbrauch_woche_minus3': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'weekly', 'params': None, 'description': 'Verbrauch aktuelle Woche -3 Wochen'},
+ 'verbrauch_woche_minus4': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'weekly', 'params': None, 'description': 'Verbrauch aktuelle Woche -4 Wochen'},
+ 'verbrauch_monat_minus1': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'monthly', 'params': None, 'description': 'Verbrauch Vormonat (aktueller Monat -1)'},
+ 'verbrauch_monat_minus2': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'monthly', 'params': None, 'description': 'Verbrauch aktueller Monat -2 Monate'},
+ 'verbrauch_monat_minus3': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'monthly', 'params': None, 'description': 'Verbrauch aktueller Monat -3 Monate'},
+ 'verbrauch_monat_minus4': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'monthly', 'params': None, 'description': 'Verbrauch aktueller Monat -4 Monate'},
+ 'verbrauch_monat_minus12': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'monthly', 'params': None, 'description': 'Verbrauch aktueller Monat -12 Monate'},
+ 'verbrauch_jahr_minus1': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'yearly', 'params': None, 'description': 'Verbrauch Vorjahr (aktuelles Jahr -1 Jahr)'},
+ 'verbrauch_jahr_minus2': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'yearly', 'params': None, 'description': 'Verbrauch aktuelles Jahr -2 Jahre'},
+ 'verbrauch_jahr_minus3': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'yearly', 'params': None, 'description': 'Verbrauch aktuelles Jahr -3 Jahre'},
+ 'verbrauch_rolling_12m_heute_minus1': {'cat': 'verbrauch', 'sub_cat': 'rolling', 'item_type': 'num', 'cycle': 'daily', 'params': None, 'description': 'Verbrauch der letzten 12 Monate ausgehend im Ende des letzten Tages'},
+ 'verbrauch_rolling_12m_tag_minus1': {'cat': 'verbrauch', 'sub_cat': 'rolling', 'item_type': 'num', 'cycle': 'daily', 'params': None, 'description': 'Verbrauch der letzten 12 Monate ausgehend im Ende des letzten Tages'},
+ 'verbrauch_rolling_12m_woche_minus1': {'cat': 'verbrauch', 'sub_cat': 'rolling', 'item_type': 'num', 'cycle': 'weekly', 'params': None, 'description': 'Verbrauch der letzten 12 Monate ausgehend im Ende der letzten Woche'},
+ 'verbrauch_rolling_12m_monat_minus1': {'cat': 'verbrauch', 'sub_cat': 'rolling', 'item_type': 'num', 'cycle': 'monthly', 'params': None, 'description': 'Verbrauch der letzten 12 Monate ausgehend im Ende des letzten Monats'},
+ 'verbrauch_rolling_12m_jahr_minus1': {'cat': 'verbrauch', 'sub_cat': 'rolling', 'item_type': 'num', 'cycle': 'yearly', 'params': None, 'description': 'Verbrauch der letzten 12 Monate ausgehend im Ende des letzten Jahres'},
+ 'verbrauch_jahreszeitraum_minus1': {'cat': 'verbrauch', 'sub_cat': 'jahrzeit', 'item_type': 'num', 'cycle': 'daily', 'params': None, 'description': 'Verbrauch seit dem 1.1. bis zum heutigen Tag des Vorjahres'},
+ 'verbrauch_jahreszeitraum_minus2': {'cat': 'verbrauch', 'sub_cat': 'jahrzeit', 'item_type': 'num', 'cycle': 'daily', 'params': None, 'description': 'Verbrauch seit dem 1.1. bis zum heutigen Tag vor 2 Jahren'},
+ 'verbrauch_jahreszeitraum_minus3': {'cat': 'verbrauch', 'sub_cat': 'jahrzeit', 'item_type': 'num', 'cycle': 'daily', 'params': None, 'description': 'Verbrauch seit dem 1.1. bis zum heutigen Tag vor 3 Jahren'},
+ 'zaehlerstand_heute_minus1': {'cat': 'zaehler', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'daily', 'params': None, 'description': 'Zählerstand / Wert am Ende des letzten Tages (heute -1 Tag)'},
+ 'zaehlerstand_heute_minus2': {'cat': 'zaehler', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'daily', 'params': None, 'description': 'Zählerstand / Wert am Ende des vorletzten Tages (heute -2 Tag)'},
+ 'zaehlerstand_heute_minus3': {'cat': 'zaehler', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'daily', 'params': None, 'description': 'Zählerstand / Wert am Ende des vorvorletzten Tages (heute -3 Tag)'},
+ 'zaehlerstand_tag_minus1': {'cat': 'zaehler', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'daily', 'params': None, 'description': 'Zählerstand / Wert am Ende des letzten Tages (heute -1 Tag)'},
+ 'zaehlerstand_tag_minus2': {'cat': 'zaehler', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'daily', 'params': None, 'description': 'Zählerstand / Wert am Ende des vorletzten Tages (heute -2 Tag)'},
+ 'zaehlerstand_tag_minus3': {'cat': 'zaehler', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'daily', 'params': None, 'description': 'Zählerstand / Wert am Ende des vorvorletzten Tages (heute -3 Tag)'},
+ 'zaehlerstand_woche_minus1': {'cat': 'zaehler', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'weekly', 'params': None, 'description': 'Zählerstand / Wert am Ende der vorvorletzten Woche (aktuelle Woche -1 Woche)'},
+ 'zaehlerstand_woche_minus2': {'cat': 'zaehler', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'weekly', 'params': None, 'description': 'Zählerstand / Wert am Ende der vorletzten Woche (aktuelle Woche -2 Wochen)'},
+ 'zaehlerstand_woche_minus3': {'cat': 'zaehler', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'weekly', 'params': None, 'description': 'Zählerstand / Wert am Ende der aktuellen Woche -3 Wochen'},
+ 'zaehlerstand_monat_minus1': {'cat': 'zaehler', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'monthly', 'params': None, 'description': 'Zählerstand / Wert am Ende des letzten Monates (aktueller Monat -1 Monat)'},
+ 'zaehlerstand_monat_minus2': {'cat': 'zaehler', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'monthly', 'params': None, 'description': 'Zählerstand / Wert am Ende des vorletzten Monates (aktueller Monat -2 Monate)'},
+ 'zaehlerstand_monat_minus3': {'cat': 'zaehler', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'monthly', 'params': None, 'description': 'Zählerstand / Wert am Ende des aktuellen Monats -3 Monate'},
+ 'zaehlerstand_jahr_minus1': {'cat': 'zaehler', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'yearly', 'params': None, 'description': 'Zählerstand / Wert am Ende des letzten Jahres (aktuelles Jahr -1 Jahr)'},
+ 'zaehlerstand_jahr_minus2': {'cat': 'zaehler', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'yearly', 'params': None, 'description': 'Zählerstand / Wert am Ende des vorletzten Jahres (aktuelles Jahr -2 Jahre)'},
+ 'zaehlerstand_jahr_minus3': {'cat': 'zaehler', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'yearly', 'params': None, 'description': 'Zählerstand / Wert am Ende des aktuellen Jahres -3 Jahre'},
+ 'minmax_last_24h_min': {'cat': 'wertehistorie', 'sub_cat': 'last', 'item_type': 'num', 'cycle': 'daily', 'params': None, 'description': 'minimaler Wert der letzten 24h'},
+ 'minmax_last_24h_max': {'cat': 'wertehistorie', 'sub_cat': 'last', 'item_type': 'num', 'cycle': 'daily', 'params': None, 'description': 'maximaler Wert der letzten 24h'},
+ 'minmax_last_24h_avg': {'cat': 'wertehistorie', 'sub_cat': 'last', 'item_type': 'num', 'cycle': 'daily', 'params': None, 'description': 'durchschnittlicher Wert der letzten 24h'},
+ 'minmax_last_7d_min': {'cat': 'wertehistorie', 'sub_cat': 'last', 'item_type': 'num', 'cycle': 'daily', 'params': None, 'description': 'minimaler Wert der letzten 7 Tage'},
+ 'minmax_last_7d_max': {'cat': 'wertehistorie', 'sub_cat': 'last', 'item_type': 'num', 'cycle': 'daily', 'params': None, 'description': 'maximaler Wert der letzten 7 Tage'},
+ 'minmax_last_7d_avg': {'cat': 'wertehistorie', 'sub_cat': 'last', 'item_type': 'num', 'cycle': 'daily', 'params': None, 'description': 'durchschnittlicher Wert der letzten 7 Tage'},
+ 'minmax_heute_min': {'cat': 'wertehistorie', 'sub_cat': 'onchange', 'item_type': 'num', 'cycle': None, 'params': None, 'description': 'Minimalwert seit Tagesbeginn'},
+ 'minmax_heute_max': {'cat': 'wertehistorie', 'sub_cat': 'onchange', 'item_type': 'num', 'cycle': None, 'params': None, 'description': 'Maximalwert seit Tagesbeginn'},
+ 'minmax_heute_avg': {'cat': 'wertehistorie', 'sub_cat': 'onchange', 'item_type': 'num', 'cycle': None, 'params': None, 'description': 'Durchschnittswert seit Tagesbeginn'},
+ 'minmax_heute_minus1_min': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'daily', 'params': None, 'description': 'Minimalwert gestern (heute -1 Tag)'},
+ 'minmax_heute_minus1_max': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'daily', 'params': None, 'description': 'Maximalwert gestern (heute -1 Tag)'},
+ 'minmax_heute_minus1_avg': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'daily', 'params': None, 'description': 'Durchschnittswert gestern (heute -1 Tag)'},
+ 'minmax_heute_minus2_min': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'daily', 'params': None, 'description': 'Minimalwert vorgestern (heute -2 Tage)'},
+ 'minmax_heute_minus2_max': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'daily', 'params': None, 'description': 'Maximalwert vorgestern (heute -2 Tage)'},
+ 'minmax_heute_minus2_avg': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'daily', 'params': None, 'description': 'Durchschnittswert vorgestern (heute -2 Tage)'},
+ 'minmax_heute_minus3_min': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'daily', 'params': None, 'description': 'Minimalwert heute vor 3 Tagen'},
+ 'minmax_heute_minus3_max': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'daily', 'params': None, 'description': 'Maximalwert heute vor 3 Tagen'},
+ 'minmax_heute_minus3_avg': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'daily', 'params': None, 'description': 'Durchschnittswert heute vor 3 Tagen'},
+ 'minmax_tag_min': {'cat': 'wertehistorie', 'sub_cat': 'onchange', 'item_type': 'num', 'cycle': None, 'params': None, 'description': 'Minimalwert seit Tagesbeginn'},
+ 'minmax_tag_max': {'cat': 'wertehistorie', 'sub_cat': 'onchange', 'item_type': 'num', 'cycle': None, 'params': None, 'description': 'Maximalwert seit Tagesbeginn'},
+ 'minmax_tag_avg': {'cat': 'wertehistorie', 'sub_cat': 'onchange', 'item_type': 'num', 'cycle': None, 'params': None, 'description': 'Durchschnittswert seit Tagesbeginn'},
+ 'minmax_tag_minus1_min': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'daily', 'params': None, 'description': 'Minimalwert gestern (heute -1 Tag)'},
+ 'minmax_tag_minus1_max': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'daily', 'params': None, 'description': 'Maximalwert gestern (heute -1 Tag)'},
+ 'minmax_tag_minus1_avg': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'daily', 'params': None, 'description': 'Durchschnittswert gestern (heute -1 Tag)'},
+ 'minmax_tag_minus2_min': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'daily', 'params': None, 'description': 'Minimalwert vorgestern (heute -2 Tage)'},
+ 'minmax_tag_minus2_max': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'daily', 'params': None, 'description': 'Maximalwert vorgestern (heute -2 Tage)'},
+ 'minmax_tag_minus2_avg': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'daily', 'params': None, 'description': 'Durchschnittswert vorgestern (heute -2 Tage)'},
+ 'minmax_tag_minus3_min': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'daily', 'params': None, 'description': 'Minimalwert heute vor 3 Tagen'},
+ 'minmax_tag_minus3_max': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'daily', 'params': None, 'description': 'Maximalwert heute vor 3 Tagen'},
+ 'minmax_tag_minus3_avg': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'daily', 'params': None, 'description': 'Durchschnittswert heute vor 3 Tagen'},
+ 'minmax_woche_min': {'cat': 'wertehistorie', 'sub_cat': 'onchange', 'item_type': 'num', 'cycle': None, 'params': None, 'description': 'Minimalwert seit Wochenbeginn'},
+ 'minmax_woche_max': {'cat': 'wertehistorie', 'sub_cat': 'onchange', 'item_type': 'num', 'cycle': None, 'params': None, 'description': 'Maximalwert seit Wochenbeginn'},
+ 'minmax_woche_minus1_min': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'weekly', 'params': None, 'description': 'Minimalwert Vorwoche (aktuelle Woche -1)'},
+ 'minmax_woche_minus1_max': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'weekly', 'params': None, 'description': 'Maximalwert Vorwoche (aktuelle Woche -1)'},
+ 'minmax_woche_minus1_avg': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'weekly', 'params': None, 'description': 'Durchschnittswert Vorwoche (aktuelle Woche -1)'},
+ 'minmax_woche_minus2_min': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'weekly', 'params': None, 'description': 'Minimalwert aktuelle Woche -2 Wochen'},
+ 'minmax_woche_minus2_max': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'weekly', 'params': None, 'description': 'Maximalwert aktuelle Woche -2 Wochen'},
+ 'minmax_woche_minus2_avg': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'weekly', 'params': None, 'description': 'Durchschnittswert aktuelle Woche -2 Wochen'},
+ 'minmax_monat_min': {'cat': 'wertehistorie', 'sub_cat': 'onchange', 'item_type': 'num', 'cycle': None, 'params': None, 'description': 'Minimalwert seit Monatsbeginn'},
+ 'minmax_monat_max': {'cat': 'wertehistorie', 'sub_cat': 'onchange', 'item_type': 'num', 'cycle': None, 'params': None, 'description': 'Maximalwert seit Monatsbeginn'},
+ 'minmax_monat_minus1_min': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'monthly', 'params': None, 'description': 'Minimalwert Vormonat (aktueller Monat -1)'},
+ 'minmax_monat_minus1_max': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'monthly', 'params': None, 'description': 'Maximalwert Vormonat (aktueller Monat -1)'},
+ 'minmax_monat_minus1_avg': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'monthly', 'params': None, 'description': 'Durchschnittswert Vormonat (aktueller Monat -1)'},
+ 'minmax_monat_minus2_min': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'monthly', 'params': None, 'description': 'Minimalwert aktueller Monat -2 Monate'},
+ 'minmax_monat_minus2_max': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'monthly', 'params': None, 'description': 'Maximalwert aktueller Monat -2 Monate'},
+ 'minmax_monat_minus2_avg': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'monthly', 'params': None, 'description': 'Durchschnittswert aktueller Monat -2 Monate'},
+ 'minmax_jahr_min': {'cat': 'wertehistorie', 'sub_cat': 'onchange', 'item_type': 'num', 'cycle': None, 'params': None, 'description': 'Minimalwert seit Jahresbeginn'},
+ 'minmax_jahr_max': {'cat': 'wertehistorie', 'sub_cat': 'onchange', 'item_type': 'num', 'cycle': None, 'params': None, 'description': 'Maximalwert seit Jahresbeginn'},
+ 'minmax_jahr_minus1_min': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'yearly', 'params': None, 'description': 'Minimalwert Vorjahr (aktuelles Jahr -1 Jahr)'},
+ 'minmax_jahr_minus1_max': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'yearly', 'params': None, 'description': 'Maximalwert Vorjahr (aktuelles Jahr -1 Jahr)'},
+ 'minmax_jahr_minus1_avg': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'yearly', 'params': None, 'description': 'Durchschnittswert Vorjahr (aktuelles Jahr -1 Jahr)'},
+ 'tagesmitteltemperatur_heute': {'cat': 'tagesmittel', 'sub_cat': 'onchange', 'item_type': 'num', 'cycle': None, 'params': None, 'description': 'Tagesmitteltemperatur heute'},
+ 'tagesmitteltemperatur_heute_minus1': {'cat': 'tagesmittel', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'daily', 'params': None, 'description': 'Tagesmitteltemperatur des letzten Tages (heute -1 Tag)'},
+ 'tagesmitteltemperatur_heute_minus2': {'cat': 'tagesmittel', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'daily', 'params': None, 'description': 'Tagesmitteltemperatur des vorletzten Tages (heute -2 Tag)'},
+ 'tagesmitteltemperatur_heute_minus3': {'cat': 'tagesmittel', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'daily', 'params': None, 'description': 'Tagesmitteltemperatur des vorvorletzten Tages (heute -3 Tag)'},
+ 'tagesmitteltemperatur_tag': {'cat': 'tagesmittel', 'sub_cat': 'onchange', 'item_type': 'num', 'cycle': None, 'params': None, 'description': 'Tagesmitteltemperatur heute'},
+ 'tagesmitteltemperatur_tag_minus1': {'cat': 'tagesmittel', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'daily', 'params': None, 'description': 'Tagesmitteltemperatur des letzten Tages (heute -1 Tag)'},
+ 'tagesmitteltemperatur_tag_minus2': {'cat': 'tagesmittel', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'daily', 'params': None, 'description': 'Tagesmitteltemperatur des vorletzten Tages (heute -2 Tag)'},
+ 'tagesmitteltemperatur_tag_minus3': {'cat': 'tagesmittel', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'daily', 'params': None, 'description': 'Tagesmitteltemperatur des vorvorletzten Tages (heute -3 Tag)'},
+ 'tagesmittelwert_tag': {'cat': 'tagesmittel', 'sub_cat': 'onchange', 'item_type': 'num', 'cycle': None, 'params': None, 'description': 'Tagesmittelwert heute'},
+ 'tagesmittelwert_tag_minus1': {'cat': 'tagesmittel', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'daily', 'params': None, 'description': 'Tagesmittelwert des letzten Tages (heute -1 Tag)'},
+ 'tagesmittelwert_tag_minus2': {'cat': 'tagesmittel', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'daily', 'params': None, 'description': 'Tagesmittelwert des vorletzten Tages (heute -2 Tag)'},
+ 'tagesmittelwert_tag_minus3': {'cat': 'tagesmittel', 'sub_cat': 'timeframe', 'item_type': 'num', 'cycle': 'daily', 'params': None, 'description': 'Tagesmittelwert des vorvorletzten Tages (heute -3 Tag)'},
+ 'serie_minmax_monat_min_15m': {'cat': 'serie', 'sub_cat': 'minmax', 'item_type': 'list', 'cycle': 'monthly', 'params': None, 'description': 'monatlicher Minimalwert der letzten 15 Monate (gleitend)'},
+ 'serie_minmax_monat_max_15m': {'cat': 'serie', 'sub_cat': 'minmax', 'item_type': 'list', 'cycle': 'monthly', 'params': None, 'description': 'monatlicher Maximalwert der letzten 15 Monate (gleitend)'},
+ 'serie_minmax_monat_avg_15m': {'cat': 'serie', 'sub_cat': 'minmax', 'item_type': 'list', 'cycle': 'monthly', 'params': None, 'description': 'monatlicher Mittelwert der letzten 15 Monate (gleitend)'},
+ 'serie_minmax_woche_min_30w': {'cat': 'serie', 'sub_cat': 'minmax', 'item_type': 'list', 'cycle': 'weekly', 'params': None, 'description': 'wöchentlicher Minimalwert der letzten 30 Wochen (gleitend)'},
+ 'serie_minmax_woche_max_30w': {'cat': 'serie', 'sub_cat': 'minmax', 'item_type': 'list', 'cycle': 'weekly', 'params': None, 'description': 'wöchentlicher Maximalwert der letzten 30 Wochen (gleitend)'},
+ 'serie_minmax_woche_avg_30w': {'cat': 'serie', 'sub_cat': 'minmax', 'item_type': 'list', 'cycle': 'weekly', 'params': None, 'description': 'wöchentlicher Mittelwert der letzten 30 Wochen (gleitend)'},
+ 'serie_minmax_tag_min_30d': {'cat': 'serie', 'sub_cat': 'minmax', 'item_type': 'list', 'cycle': 'daily', 'params': None, 'description': 'täglicher Minimalwert der letzten 30 Tage (gleitend)'},
+ 'serie_minmax_tag_max_30d': {'cat': 'serie', 'sub_cat': 'minmax', 'item_type': 'list', 'cycle': 'daily', 'params': None, 'description': 'täglicher Maximalwert der letzten 30 Tage (gleitend)'},
+ 'serie_minmax_tag_avg_30d': {'cat': 'serie', 'sub_cat': 'minmax', 'item_type': 'list', 'cycle': 'daily', 'params': None, 'description': 'täglicher Mittelwert der letzten 30 Tage (gleitend)'},
+ 'serie_verbrauch_tag_30d': {'cat': 'serie', 'sub_cat': 'verbrauch', 'item_type': 'list', 'cycle': 'daily', 'params': None, 'description': 'Verbrauch pro Tag der letzten 30 Tage'},
+ 'serie_verbrauch_woche_30w': {'cat': 'serie', 'sub_cat': 'verbrauch', 'item_type': 'list', 'cycle': 'weekly', 'params': None, 'description': 'Verbrauch pro Woche der letzten 30 Wochen'},
+ 'serie_verbrauch_monat_18m': {'cat': 'serie', 'sub_cat': 'verbrauch', 'item_type': 'list', 'cycle': 'monthly', 'params': None, 'description': 'Verbrauch pro Monat der letzten 18 Monate'},
+ 'serie_zaehlerstand_tag_30d': {'cat': 'serie', 'sub_cat': 'zaehler', 'item_type': 'list', 'cycle': 'daily', 'params': None, 'description': 'Zählerstand am Tagesende der letzten 30 Tage'},
+ 'serie_zaehlerstand_woche_30w': {'cat': 'serie', 'sub_cat': 'zaehler', 'item_type': 'list', 'cycle': 'weekly', 'params': None, 'description': 'Zählerstand am Wochenende der letzten 30 Wochen'},
+ 'serie_zaehlerstand_monat_18m': {'cat': 'serie', 'sub_cat': 'zaehler', 'item_type': 'list', 'cycle': 'monthly', 'params': None, 'description': 'Zählerstand am Monatsende der letzten 18 Monate'},
+ 'serie_waermesumme_monat_24m': {'cat': 'serie', 'sub_cat': 'summe', 'item_type': 'list', 'cycle': 'monthly', 'params': None, 'description': 'monatliche Wärmesumme der letzten 24 Monate'},
+ 'serie_kaeltesumme_monat_24m': {'cat': 'serie', 'sub_cat': 'summe', 'item_type': 'list', 'cycle': 'monthly', 'params': None, 'description': 'monatliche Kältesumme der letzten 24 Monate'},
+ 'serie_tagesmittelwert_0d': {'cat': 'serie', 'sub_cat': 'mittel_d', 'item_type': 'list', 'cycle': 'daily', 'params': None, 'description': 'Tagesmittelwert für den aktuellen Tag'},
+ 'serie_tagesmittelwert_stunde_0d': {'cat': 'serie', 'sub_cat': 'mittel_h', 'item_type': 'list', 'cycle': 'daily', 'params': None, 'description': 'Stundenmittelwert für den aktuellen Tag'},
+ 'serie_tagesmittelwert_stunde_30_0d': {'cat': 'serie', 'sub_cat': 'mittel_h1', 'item_type': 'list', 'cycle': 'daily', 'params': None, 'description': 'Stundenmittelwert für den aktuellen Tag'},
+ 'serie_tagesmittelwert_tag_stunde_30d': {'cat': 'serie', 'sub_cat': 'mittel_d_h', 'item_type': 'list', 'cycle': 'daily', 'params': None, 'description': 'Stundenmittelwert pro Tag der letzten 30 Tage (bspw. zur Berechnung der Tagesmitteltemperatur basierend auf den Mittelwert der Temperatur pro Stunde'},
+ 'general_oldest_value': {'cat': 'gen', 'sub_cat': None, 'item_type': 'num', 'cycle': None, 'params': None, 'description': 'Ausgabe des ältesten Wertes des entsprechenden "Parent-Items" mit database Attribut'},
+ 'general_oldest_log': {'cat': 'gen', 'sub_cat': None, 'item_type': 'list', 'cycle': None, 'params': None, 'description': 'Ausgabe des Timestamp des ältesten Eintrages des entsprechenden "Parent-Items" mit database Attribut'},
+ 'kaeltesumme': {'cat': 'summe', 'sub_cat': None, 'item_type': 'num', 'cycle': 'daily', 'params': ([], ['year', 'month', 'result'], {}), 'description': 'Berechnet die Kältesumme für einen Zeitraum, db_addon_params: (year=optional, month=optional, ignore_value_list=optional, result=optional)'},
+ 'waermesumme': {'cat': 'summe', 'sub_cat': None, 'item_type': 'num', 'cycle': 'daily', 'params': ([], ['year', 'month', 'threshold', 'result'], {}), 'description': 'Berechnet die Wärmesumme für einen Zeitraum, db_addon_params: (year=optional, month=optional, ignore_value_list=optional, threshold=optional, result=optional)'},
+ 'gruenlandtempsumme': {'cat': 'summe', 'sub_cat': None, 'item_type': 'num', 'cycle': 'daily', 'params': ([], ['year', 'month', 'result'], {}), 'description': 'Berechnet die Grünlandtemperatursumme für einen Zeitraum, db_addon_params: (year=optional, ignore_value_list=optional, result=optional)'},
+ 'wachstumsgradtage': {'cat': 'summe', 'sub_cat': None, 'item_type': 'num', 'cycle': 'daily', 'params': ([], ['year', 'month', 'threshold', 'result'], {}), 'description': 'Berechnet die Wachstumsgradtage auf Basis der stündlichen Durchschnittswerte eines Tages für das laufende Jahr mit an Angabe des Temperaturschwellenwertes, db_addon_params: (year=optional, ignore_value_list=optional, variant=optional, threshold=optional, result=optional)'},
+ 'wuestentage': {'cat': 'summe', 'sub_cat': 'kenntage', 'item_type': 'num', 'cycle': 'daily', 'params': ([], ['year', 'month'], {}), 'description': 'Berechnet die Anzahl der Wüstentage des Jahres, db_addon_params: (year=optional)'},
+ 'heisse_tage': {'cat': 'summe', 'sub_cat': 'kenntage', 'item_type': 'num', 'cycle': 'daily', 'params': ([], ['year', 'month'], {}), 'description': 'Berechnet die Anzahl der heissen Tage des Jahres, db_addon_params: (year=optional)'},
+ 'tropennaechte': {'cat': 'summe', 'sub_cat': 'kenntage', 'item_type': 'num', 'cycle': 'daily', 'params': ([], ['year', 'month'], {}), 'description': 'Berechnet die Anzahl der Tropennächte des Jahres, db_addon_params: (year=optional)'},
+ 'sommertage': {'cat': 'summe', 'sub_cat': 'kenntage', 'item_type': 'num', 'cycle': 'daily', 'params': ([], ['year', 'month'], {}), 'description': 'Berechnet die Anzahl der Sommertage des Jahres, db_addon_params: (year=optional)'},
+ 'heiztage': {'cat': 'summe', 'sub_cat': 'kenntage', 'item_type': 'num', 'cycle': 'daily', 'params': ([], ['year', 'month'], {}), 'description': 'Berechnet die Anzahl der Heiztage des Jahres, db_addon_params: (year=optional)'},
+ 'vegetationstage': {'cat': 'summe', 'sub_cat': 'kenntage', 'item_type': 'num', 'cycle': 'daily', 'params': ([], ['year', 'month'], {}), 'description': 'Berechnet die Anzahl der Vegatationstage des Jahres, db_addon_params: (year=optional)'},
+ 'frosttage': {'cat': 'summe', 'sub_cat': 'kenntage', 'item_type': 'num', 'cycle': 'daily', 'params': ([], ['year', 'month'], {}), 'description': 'Berechnet die Anzahl der Frosttage des Jahres, db_addon_params: (year=optional)'},
+ 'eistage': {'cat': 'summe', 'sub_cat': 'kenntage', 'item_type': 'num', 'cycle': 'daily', 'params': ([], ['year', 'month'], {}), 'description': 'Berechnet die Anzahl der Eistage des Jahres, db_addon_params: (year=optional)'},
+ 'tagesmittelwert': {'cat': 'tagesmittel', 'sub_cat': 'complex', 'item_type': 'list', 'cycle': 'daily', 'params': (['timeframe', 'start', 'end'], [], {'data_con_func': 'avg_hour'}), 'description': 'Berechnet die Tagesmittelwert auf Basis der stündlichen Durchschnittswerte eines Tages für die angegebene Anzahl von Tagen (timeframe=day, count=integer)'},
+ 'db_request': {'cat': 'complex', 'sub_cat': None, 'item_type': 'list', 'cycle': 'group', 'params': (['func', 'timeframe'], ['start', 'end', 'group', 'group2', 'ignore_value_list', 'use_oldest_entry'], {}), 'description': 'Abfrage der DB: db_addon_params: (func=mandatory, item=mandatory, timespan=mandatory, start=optional, end=optional, count=optional, group=optional, group2=optional)'},
+ 'minmax': {'cat': 'wertehistorie', 'sub_cat': 'complex', 'item_type': 'num', 'cycle': 'timeframe', 'params': (['func', 'timeframe', 'start'], ['end'], {}), 'description': 'Ermittelt einen min/max/avg Wert für einen bestimmen Zeitraum: db_addon_params: (func=mandatory, timeframe=mandatory, start=mandatory, end=optional)'},
+ 'verbrauch': {'cat': 'verbrauch', 'sub_cat': 'complex', 'item_type': 'num', 'cycle': 'timeframe', 'params': (['timeframe', 'start', 'end'], [], {}), 'description': 'Berechnet einen Verbrauchswert für einen bestimmen Zeitraum: db_addon_params: (timeframe=mandatory, start=mandatory end=mandatory)'},
+ 'zaehlerstand': {'cat': 'zaehler', 'sub_cat': 'complex', 'item_type': 'num', 'cycle': 'timeframe', 'params': (['timeframe', 'start'], [], {}), 'description': 'Ermittelt einen Zählerstand für einen bestimmen Zeitpunkt: db_addon_params: (timeframe=mandatory, start=mandatory)'},
},
'db_addon_info': {
- 'db_version': {'cat': 'info', 'item_type': 'str', 'cycle': None, 'params': False, 'description': 'Version der verbundenen Datenbank'},
+ 'db_version': {'cat': 'info', 'sub_cat': None, 'item_type': 'str', 'cycle': None, 'params': None, 'description': 'Version der verbundenen Datenbank'},
},
'db_addon_admin': {
- 'suspend': {'cat': 'admin', 'item_type': 'bool', 'cycle': None, 'params': False, 'description': 'Unterbricht die Aktivitäten des Plugin'},
- 'recalc_all': {'cat': 'admin', 'item_type': 'bool', 'cycle': None, 'params': False, 'description': 'Startet einen Neuberechnungslauf aller on-demand Items'},
- 'clean_cache_values': {'cat': 'admin', 'item_type': 'bool', 'cycle': None, 'params': False, 'description': 'Löscht Plugin-Cache und damit alle im Plugin zwischengespeicherten Werte'},
+ 'recalc_all': {'cat': 'admin', 'sub_cat': None, 'item_type': 'bool', 'cycle': None, 'params': None, 'description': 'Startet einen Neuberechnungslauf aller on-demand Items'},
+ 'clean_cache_values': {'cat': 'admin', 'sub_cat': None, 'item_type': 'bool', 'cycle': None, 'params': None, 'description': 'Löscht Plugin-Cache und damit alle im Plugin zwischengespeicherten Werte'},
},
}
@@ -246,26 +248,16 @@ def get_attrs(sub_dict: dict = {}) -> list:
def export_item_attributes_py():
print()
- print(f"A) Start generation of {FILENAME_ATTRIBUTES}")
+ print(f"## Start generation of {FILENAME_ATTRIBUTES}")
ATTRS = dict()
- ATTRS['ONCHANGE_ATTRIBUTES'] = get_attrs(sub_dict={'on': 'change'})
- ATTRS['ONCHANGE_HOURLY_ATTRIBUTES'] = get_attrs(sub_dict={'on': 'change', 'calc': 'hourly'})
- ATTRS['ONCHANGE_DAILY_ATTRIBUTES'] = get_attrs(sub_dict={'on': 'change', 'calc': 'daily'})
- ATTRS['ONCHANGE_WEEKLY_ATTRIBUTES'] = get_attrs(sub_dict={'on': 'change', 'calc': 'weekly'})
- ATTRS['ONCHANGE_MONTHLY_ATTRIBUTES'] = get_attrs(sub_dict={'on': 'change', 'calc': 'monthly'})
- ATTRS['ONCHANGE_YEARLY_ATTRIBUTES'] = get_attrs(sub_dict={'on': 'change', 'calc': 'yearly'})
- ATTRS['ONDEMAND_ATTRIBUTES'] = get_attrs(sub_dict={'on': 'demand'})
- ATTRS['ONDEMAND_HOURLY_ATTRIBUTES'] = get_attrs(sub_dict={'on': 'demand', 'calc': 'hourly'})
- ATTRS['ONDEMAND_DAILY_ATTRIBUTES'] = get_attrs(sub_dict={'on': 'demand', 'calc': 'daily'})
- ATTRS['ONDEMAND_WEEKLY_ATTRIBUTES'] = get_attrs(sub_dict={'on': 'demand', 'calc': 'weekly'})
- ATTRS['ONDEMAND_MONTHLY_ATTRIBUTES'] = get_attrs(sub_dict={'on': 'demand', 'calc': 'monthly'})
- ATTRS['ONDEMAND_YEARLY_ATTRIBUTES'] = get_attrs(sub_dict={'on': 'demand', 'calc': 'yearly'})
- ATTRS['ALL_HOURLY_ATTRIBUTES'] = get_attrs(sub_dict={'calc': 'hourly'})
- ATTRS['ALL_DAILY_ATTRIBUTES'] = get_attrs(sub_dict={'calc': 'daily'})
- ATTRS['ALL_WEEKLY_ATTRIBUTES'] = get_attrs(sub_dict={'calc': 'weekly'})
- ATTRS['ALL_MONTHLY_ATTRIBUTES'] = get_attrs(sub_dict={'calc': 'monthly'})
- ATTRS['ALL_YEARLY_ATTRIBUTES'] = get_attrs(sub_dict={'calc': 'yearly'})
+ ATTRS['ONCHANGE_ATTRIBUTES'] = get_attrs(sub_dict={'cycle': None})
+ ATTRS['ONDEMAND_HOURLY_ATTRIBUTES'] = get_attrs(sub_dict={'cycle': 'hourly'})
+ ATTRS['ONDEMAND_DAILY_ATTRIBUTES'] = get_attrs(sub_dict={'cycle': 'daily'})
+ ATTRS['ONDEMAND_WEEKLY_ATTRIBUTES'] = get_attrs(sub_dict={'cycle': 'weekly'})
+ ATTRS['ONDEMAND_MONTHLY_ATTRIBUTES'] = get_attrs(sub_dict={'cycle': 'monthly'})
+ ATTRS['ONDEMAND_YEARLY_ATTRIBUTES'] = get_attrs(sub_dict={'cycle': 'yearly'})
+ ATTRS['ONDEMAND_ATTRIBUTES'] = ATTRS['ONDEMAND_HOURLY_ATTRIBUTES'] + ATTRS['ONDEMAND_DAILY_ATTRIBUTES'] + ATTRS['ONDEMAND_WEEKLY_ATTRIBUTES'] + ATTRS['ONDEMAND_MONTHLY_ATTRIBUTES'] + ATTRS['ONDEMAND_YEARLY_ATTRIBUTES']
ATTRS['ALL_PARAMS_ATTRIBUTES'] = get_attrs(sub_dict={'params': True})
ATTRS['ALL_VERBRAUCH_ATTRIBUTES'] = get_attrs(sub_dict={'cat': 'verbrauch'})
ATTRS['VERBRAUCH_ATTRIBUTES_ONCHANGE'] = get_attrs(sub_dict={'cat': 'verbrauch', 'sub_cat': 'onchange'})
@@ -331,8 +323,11 @@ def create_plugin_yaml_item_attribute_valids(attribute):
valid_list_item_type = f"""{valid_list_item_type}\n\
- '{ITEM_ATTRIBUTES[attribute][db_addon_fct]['item_type']:<}'"""
+ cycle = ITEM_ATTRIBUTES[attribute][db_addon_fct]['cycle']
+ if not cycle:
+ cycle = ""
valid_list_calculation = f"""{valid_list_calculation}\n\
- - '{ITEM_ATTRIBUTES[attribute][db_addon_fct]['calc']:<}'"""
+ - '{cycle:<}'"""
valid_list_calculation = f"""{valid_list_calculation}\n\r"""
@@ -343,7 +338,7 @@ def update_plugin_yaml_item_attributes():
"""Update 'valid_list', 'valid_list_description', 'valid_list_item_type' and 'valid_list_calculation' of item attributes in plugin.yaml"""
print()
- print(f"B) Start updating valid for attributes in {FILENAME_PLUGIN}")
+ print(f"## Start updating valid for attributes in {FILENAME_PLUGIN}")
for attribute in ITEM_ATTRIBUTES:
@@ -376,7 +371,7 @@ def update_plugin_yaml_item_attributes():
def check_plugin_yaml_structs():
# check structs for wrong attributes
print()
- print(f'C) Checking used attributes in structs defined in {FILENAME_PLUGIN} ')
+ print(f'## Checking used attributes in structs defined in {FILENAME_PLUGIN} ')
# open plugin.yaml and update
yaml = ruamel.yaml.YAML()
@@ -413,7 +408,7 @@ def get_all_keys(d):
def update_user_doc():
# Update user_doc.rst
print()
- print(f'D) Start updating DB-Addon-Attributes and descriptions in {DOC_FILE_NAME}!"')
+ print(f'## Start updating DB-Addon-Attributes and descriptions in {DOC_FILE_NAME}!"')
attribute_list = [
"Dieses Kapitel wurde automatisch durch Ausführen des Skripts in der Datei 'item_attributes_master.py' erstellt.\n", "\n",
"Nachfolgend eine Auflistung der möglichen Attribute für das Plugin im Format: Attribute: Beschreibung | Berechnungszyklus | Item-Type\n",
@@ -428,7 +423,7 @@ def update_user_doc():
for db_addon_fct in ITEM_ATTRIBUTES[attribute]:
attribute_list.append(f"- {db_addon_fct}: {ITEM_ATTRIBUTES[attribute][db_addon_fct]['description']} "
- f"| Berechnung: {ITEM_ATTRIBUTES[attribute][db_addon_fct]['calc']} "
+ f"| Berechnung: {ITEM_ATTRIBUTES[attribute][db_addon_fct]['cycle']} "
f"| Item-Type: {ITEM_ATTRIBUTES[attribute][db_addon_fct]['item_type']}\n")
attribute_list.append("\n")
@@ -437,9 +432,9 @@ def update_user_doc():
start = end = None
for i, line in enumerate(lines):
- if 'db_addon Item-Attribute' in line:
+ if 'Verfügbare Item-Attribute' in line:
start = i + 3
- if 'Hinweise' in line:
+ if 'Beispiele für vordefinierte Auswertungen' in line:
end = i - 1
part1 = lines[0:start]
@@ -450,7 +445,7 @@ def update_user_doc():
for line in new_lines:
file.write(line)
- print(f" Successfully updated Foshk-Attributes in {DOC_FILE_NAME}!")
+ print(f" Successfully updated DB-Addon-Attributes in {DOC_FILE_NAME}!")
if __name__ == '__main__':
@@ -458,7 +453,7 @@ def update_user_doc():
print(f'Start automated update and check of {FILENAME_PLUGIN} with generation of {FILENAME_ATTRIBUTES} and update of {DOC_FILE_NAME}.')
print('-------------------------------------------------------------')
- export_item_attributes_py()
+ # export_item_attributes_py()
update_plugin_yaml_item_attributes()
diff --git a/db_addon/plugin.yaml b/db_addon/plugin.yaml
index 53a0f836a..be58ae85c 100644
--- a/db_addon/plugin.yaml
+++ b/db_addon/plugin.yaml
@@ -11,10 +11,10 @@ plugin:
# keywords: iot xyz
# documentation: https://github.com/smarthomeNG/smarthome/wiki/CLI-Plugin # url of documentation (wiki) page
support: https://knx-user-forum.de/forum/supportforen/smarthome-py/1848494-support-thread-databaseaddon-plugin
- version: 1.2.9 # Plugin version (must match the version specified in __init__.py)
+ version: 1.2.10 # Plugin version (must match the version specified in __init__.py)
sh_minversion: 1.9.3.5 # minimum shNG version to use this plugin
# sh_maxversion: # maximum shNG version to use this plugin (leave empty if latest)
- py_minversion: '3.8' # minimum Python version to use for this plugin
+ py_minversion: '3.9' # minimum Python version to use for this plugin
# py_maxversion: # maximum Python version to use for this plugin (leave empty if latest)
multi_instance: false # plugin supports multi instance
restartable: unknown
@@ -69,6 +69,13 @@ parameters:
de: Sperren der Datenbank während der Abfrage
en: Lock the database during queries
+ pause_item:
+ type: str
+ default: ''
+ description:
+ de: 'Item, um die Ausführung des Plugins zu steuern'
+ en: 'item for controlling plugin execution'
+
item_attributes:
db_addon_fct:
type: str
diff --git a/db_addon/webif/__init__.py b/db_addon/webif/__init__.py
index 79c76ca57..bff423039 100644
--- a/db_addon/webif/__init__.py
+++ b/db_addon/webif/__init__.py
@@ -86,13 +86,13 @@ def index(self, reload=None, action=None, item_path=None, active=None, option=No
return tmpl.render(p=self.plugin,
webif_pagelength=pagelength,
- suspended='true' if self.plugin.suspended else 'false',
items=self.plugin.get_item_list('db_addon', 'function'),
item_count=len(self.plugin.get_item_list('db_addon', 'function')),
plugin_shortname=self.plugin.get_shortname(),
plugin_version=self.plugin.get_version(),
plugin_info=self.plugin.get_info(),
maintenance=True if self.plugin.log_level < 20 else False,
+ paused=not(self.plugin.alive)
)
@cherrypy.expose
@@ -116,7 +116,6 @@ def get_data_html(self, dataSet=None):
data['items'][item.property.path]['last_update'] = item.property.last_update.strftime('%d.%m.%Y %H:%M:%S')
data['items'][item.property.path]['last_change'] = item.property.last_change.strftime('%d.%m.%Y %H:%M:%S')
- data['plugin_suspended'] = self.plugin.suspended
data['maintenance'] = True if self.plugin.log_level == 10 else False
data['queue_length'] = self.plugin.queue_backlog()
data['active_queue_item'] = self.plugin.active_queue_item
@@ -149,12 +148,15 @@ def submit(self, item=None):
self.logger.debug(f"Result for web interface: {result}")
return json.dumps(result).encode('utf-8')
- elif cmd.startswith("suspend_plugin_calculation"):
- self.logger.debug(f"set_plugin_calculation {cmd=}")
+ elif cmd.startswith("pause_plugin"):
+ self.logger.debug(f"pause_plugin {cmd=}")
cmd, value = cmd.split(',')
- value = True if value == "True" else False
- self.logger.info(f"Plugin will be set to suspended: {value} via WebIF.")
- result = self.plugin.suspend(value)
+ if value == "True":
+ self.plugin.stop()
+ else:
+ self.plugin.run()
+ self.logger.warning(f"Plugin will be set to paused: {value} via WebIF.")
+ result = not(self.plugin.alive)
self.logger.debug(f"Result for web interface: {result}")
return json.dumps(result).encode('utf-8')
@@ -187,16 +189,6 @@ def clear_queue(self):
self.logger.debug(f"_clear_queue called")
self.plugin._clear_queue()
- @cherrypy.expose
- def activate(self):
- self.logger.debug(f"active called")
- self.plugin.suspend(False)
-
- @cherrypy.expose
- def suspend(self):
- self.logger.debug(f"suspend called")
- self.plugin.suspend(True)
-
@cherrypy.expose
def debug_log_option(self, log: str = None, state: bool = None):
self.logger.warning(f"debug_log_option called with {log=}, {state=}")
diff --git a/db_addon/webif/templates/index.html b/db_addon/webif/templates/index.html
index 270751ff7..c7da035df 100644
--- a/db_addon/webif/templates/index.html
+++ b/db_addon/webif/templates/index.html
@@ -68,17 +68,17 @@
{% block pluginscripts %}