From 2bfaf5b1594b4cfff742e7814f5853b867291836 Mon Sep 17 00:00:00 2001 From: sisamiwe Date: Thu, 27 Jul 2023 12:46:35 +0200 Subject: [PATCH 01/18] DB_ADDON: - Introduce plugin parameter to lock database before reading - allow excluding items from calculation via WebIF - allow to re-calculate items per WebIF - allow plugin item cache to be cleared for certain item per WebIF - just use shtime for time and date calculation - make sure, that db query always fetches latest entries - internal improvements --- db_addon/__init__.py | 953 ++++++++++++---------- db_addon/item_attributes_master.py | 299 ------- db_addon/locale.yaml | 0 db_addon/plugin.yaml | 17 +- db_addon/requirements.txt | 0 db_addon/user_doc.rst | 0 db_addon/webif/__init__.py | 102 ++- db_addon/webif/static/img/plugin_logo.png | Bin db_addon/webif/templates/index.html | 111 ++- 9 files changed, 733 insertions(+), 749 deletions(-) mode change 100755 => 100644 db_addon/__init__.py delete mode 100755 db_addon/item_attributes_master.py mode change 100755 => 100644 db_addon/locale.yaml mode change 100755 => 100644 db_addon/plugin.yaml mode change 100755 => 100644 db_addon/requirements.txt mode change 100755 => 100644 db_addon/user_doc.rst mode change 100755 => 100644 db_addon/webif/__init__.py mode change 100755 => 100644 db_addon/webif/static/img/plugin_logo.png mode change 100755 => 100644 db_addon/webif/templates/index.html diff --git a/db_addon/__init__.py b/db_addon/__init__.py old mode 100755 new mode 100644 index f20b78023..02c521b7a --- a/db_addon/__init__.py +++ b/db_addon/__init__.py @@ -30,8 +30,11 @@ import time import re import queue +import threading +import logging from dateutil.relativedelta import relativedelta from typing import Union +from dataclasses import dataclass, InitVar from lib.model.smartplugin import SmartPlugin from lib.item import Items @@ -53,7 +56,8 @@ 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.2' + PLUGIN_VERSION = '1.2.3' + REVISION = 'C' def __init__(self, sh): """ @@ -75,6 +79,8 @@ def __init__(self, sh): # define variables for database, database connection, working queue and status self.item_queue = queue.Queue() # Queue containing all to be executed items + # ToDo: Check if still needed + self.queue_consumer_thread = None # Queue consumer thread self._db_plugin = None # object if database plugin self._db = None # object of database self.connection_data = None # connection data list of database @@ -82,19 +88,13 @@ def __init__(self, sh): self.db_instance = None # instance of the used database self.item_attribute_search_str = 'database' # attribute, on which an item configured for database can be identified self.last_connect_time = 0 # mechanism for limiting db connection requests + # ToDo: Check if still needed + self.last_commit_time = 0 self.alive = None # Is plugin alive? self.startup_finished = False # Startup of Plugin finished self.suspended = False # Is plugin activity suspended self.active_queue_item: str = '-' # String holding item path of currently executed item - # define debug logs - self.parse_debug = True # Enable / Disable debug logging for method 'parse item' - self.execute_debug = True # Enable / Disable debug logging for method 'execute items' - self.sql_debug = True # Enable / Disable debug logging for sql stuff - self.ondemand_debug = True # Enable / Disable debug logging for method 'handle_ondemand' - self.onchange_debug = True # Enable / Disable debug logging for method 'handle_onchange' - self.prepare_debug = True # Enable / Disable debug logging for query preparation - # define default mysql settings self.default_connect_timeout = 60 self.default_net_read_timeout = 60 @@ -106,6 +106,12 @@ def __init__(self, sh): self.value_filter = self.get_parameter_value('value_filter') self.optimize_value_filter = self.get_parameter_value('optimize_value_filter') self.use_oldest_entry = self.get_parameter_value('use_oldest_entry') + self.lock_db_for_query = self.get_parameter_value('lock_db_for_query') + # ToDo: Check if still needed + self.refresh_cycle = self.get_parameter_value('refresh_cycle') + + # get debug log options + self.debug_log = DebugLogOptions(self.log_level) # init cache dicts self._init_cache_dicts() @@ -132,20 +138,21 @@ def run(self): return self.deinit() self.logger.debug("Initialization of database API successful") - # init db + # check initialization of db if not self._initialize_db(): self.logger.error("Connection to database failed") return self.deinit() + self._db.close() # check db connection settings - if self.db_driver is not None and self.db_driver.lower() == 'pymysql': + if self.db_driver.lower() == 'pymysql': self._check_db_connection_setting() # add scheduler for cyclic trigger item calculation - self.scheduler_add('cyclic', self.execute_due_items, prio=3, cron='5 0 0 * * *', cycle=None, value=None, offset=None, next=None) + self.scheduler_add('cyclic', self.execute_due_items, prio=3, cron='10 0 * * *', cycle=None, value=None, offset=None, next=None) # add scheduler to trigger items to be calculated at startup with delay - dt = self.shtime.now() + datetime.timedelta(seconds=(self.startup_run_delay + 3)) + dt = self.shtime.now() + relativedelta(seconds=(self.startup_run_delay + 3)) self.logger.info(f"Set scheduler for calculating startup-items with delay of {self.startup_run_delay + 3}s to {dt}.") self.scheduler_add('startup', self.execute_startup_items, next=dt) @@ -156,8 +163,12 @@ def run(self): self.alive = True # work item queue + self.work_item_queue() + + # ToDo: Check if still needed + """ try: - self.work_item_queue() + self._queue_consumer_thread_startup() except Exception as e: self.logger.warning(f"During working item queue Exception '{e}' occurred.") self.logger.debug(e, exc_info=True) @@ -165,6 +176,7 @@ def run(self): # self.deinit() self.logger.error("Suspend Plugin and clear Item-Queue.") self.suspend(True) + """ def stop(self): """ @@ -174,6 +186,9 @@ def stop(self): self.logger.debug("Stop method called") self.alive = False self.scheduler_remove('cyclic') + self._db.close() + # ToDo: Check if still needed + # self._queue_consumer_thread_shutdown() def parse_item(self, item: Item): """ @@ -198,7 +213,7 @@ def get_query_parameters_from_db_addon_fct() -> Union[dict, None]: if db_addon_fct in HISTORIE_ATTRIBUTES_ONCHANGE: # handle functions 'minmax on-change' in format 'minmax_timeframe_func' items like 'minmax_heute_max', 'minmax_heute_min', 'minmax_woche_max', 'minmax_woche_min' - timeframe = harmonize_timeframe_expression(db_addon_fct_vars[1]) + 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' @@ -209,7 +224,7 @@ def get_query_parameters_from_db_addon_fct() -> Union[dict, None]: func = db_addon_fct_vars[3] start, timeframe = split_sting_letters_numbers(db_addon_fct_vars[2]) start = to_int(start) - timeframe = harmonize_timeframe_expression(timeframe) + timeframe = translate_timeframe(timeframe) end = 0 log_text = 'minmax_last_timedelta|timeframe_function' required_params = [func, timeframe, start, end] @@ -217,7 +232,7 @@ def get_query_parameters_from_db_addon_fct() -> Union[dict, None]: 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 = harmonize_timeframe_expression(db_addon_fct_vars[1]) # day, week, month, year + timeframe = translate_timeframe(db_addon_fct_vars[1]) # day, week, month, year end = to_int(split_sting_letters_numbers(db_addon_fct_vars[2])[1]) start = end log_text = 'minmax_timeframe_timedelta_func' @@ -226,7 +241,7 @@ def get_query_parameters_from_db_addon_fct() -> Union[dict, None]: elif db_addon_fct in ZAEHLERSTAND_ATTRIBUTES_TIMEFRAME: # handle functions 'zaehlerstand' in format 'zaehlerstand_timeframe_timedelta' like 'zaehlerstand_heute_minus1' # func = 'max' - timeframe = harmonize_timeframe_expression(db_addon_fct_vars[1]) + timeframe = translate_timeframe(db_addon_fct_vars[1]) end = to_int(split_sting_letters_numbers(db_addon_fct_vars[2])[1]) start = end log_text = 'zaehlerstand_timeframe_timedelta' @@ -234,7 +249,7 @@ def get_query_parameters_from_db_addon_fct() -> Union[dict, None]: elif db_addon_fct in VERBRAUCH_ATTRIBUTES_ONCHANGE: # handle functions 'verbrauch on-change' items in format 'verbrauch_timeframe' like 'verbrauch_heute', 'verbrauch_woche', 'verbrauch_monat', 'verbrauch_jahr' - timeframe = harmonize_timeframe_expression(db_addon_fct_vars[1]) + timeframe = translate_timeframe(db_addon_fct_vars[1]) end = 0 start = 1 log_text = 'verbrauch_timeframe' @@ -242,7 +257,7 @@ def get_query_parameters_from_db_addon_fct() -> Union[dict, None]: elif db_addon_fct in VERBRAUCH_ATTRIBUTES_TIMEFRAME: # handle functions 'verbrauch on-demand' in format 'verbrauch_timeframe_timedelta' like 'verbrauch_heute_minus2' - timeframe = harmonize_timeframe_expression(db_addon_fct_vars[1]) + timeframe = translate_timeframe(db_addon_fct_vars[1]) # end = to_int(db_addon_fct_vars[2][-1]) end = to_int(split_sting_letters_numbers(db_addon_fct_vars[2])[1]) start = end + 1 @@ -250,28 +265,29 @@ def get_query_parameters_from_db_addon_fct() -> Union[dict, None]: required_params = [timeframe, start, end] elif db_addon_fct in VERBRAUCH_ATTRIBUTES_ROLLING: + # ToDo: check if rolling window correct; muss start und ende dynamisch berechnet werden? # 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 = harmonize_timeframe_expression(window_dur) # day, week, month, year - timeframe = harmonize_timeframe_expression(db_addon_fct_vars[3]) # day, week, month, year + 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(convert_timeframe(timeframe, window_dur) * window_inc) + 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 = harmonize_timeframe_expression(db_addon_fct_vars[1]) # day, week, month, year + 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 on-change' items in format 'tagesmitteltemperatur_timeframe' like 'tagesmitteltemperatur_heute', 'tagesmitteltemperatur_woche', 'tagesmitteltemperatur_monat', 'tagesmitteltemperatur_jahr' - timeframe = harmonize_timeframe_expression(db_addon_fct_vars[1]) + timeframe = translate_timeframe(db_addon_fct_vars[1]) func = 'max' start = end = 0 log_text = 'tagesmitteltemperatur_timeframe' @@ -280,7 +296,7 @@ def get_query_parameters_from_db_addon_fct() -> Union[dict, None]: elif db_addon_fct in TAGESMITTEL_ATTRIBUTES_TIMEFRAME: # handle 'tagesmitteltemperatur_timeframe_timedelta' like 'tagesmitteltemperatur_heute_minus1' func = 'max' - timeframe = harmonize_timeframe_expression(db_addon_fct_vars[1]) + timeframe = translate_timeframe(db_addon_fct_vars[1]) end = to_int(split_sting_letters_numbers(db_addon_fct_vars[2])[1]) start = end method = 'avg_hour' @@ -290,10 +306,10 @@ def get_query_parameters_from_db_addon_fct() -> Union[dict, None]: 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 = harmonize_timeframe_expression(db_addon_fct_vars[2]) + timeframe = translate_timeframe(db_addon_fct_vars[2]) start, group = split_sting_letters_numbers(db_addon_fct_vars[4]) start = to_int(start) - group = harmonize_timeframe_expression(group) + group = translate_timeframe(group) end = 0 log_text = 'serie_minmax_timeframe_func_start|group' required_params = [func, timeframe, start, end, group] @@ -301,20 +317,20 @@ def get_query_parameters_from_db_addon_fct() -> Union[dict, None]: elif db_addon_fct in SERIE_ATTRIBUTES_ZAEHLERSTAND: # handle functions 'serie_zaehlerstand' in format 'serie_zaehlerstand_timeframe_start|group' like 'serie_zaehlerstand_tag_30d' func = 'max' - timeframe = harmonize_timeframe_expression(db_addon_fct_vars[2]) + timeframe = translate_timeframe(db_addon_fct_vars[2]) start, group = split_sting_letters_numbers(db_addon_fct_vars[3]) start = to_int(start) - group = harmonize_timeframe_expression(group) + 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' func = 'diff_max' - timeframe = harmonize_timeframe_expression(db_addon_fct_vars[2]) + timeframe = translate_timeframe(db_addon_fct_vars[2]) start, group = split_sting_letters_numbers(db_addon_fct_vars[3]) start = to_int(start) - group = harmonize_timeframe_expression(group) + group = translate_timeframe(group) log_text = 'serie_verbrauch_timeframe_start|group' required_params = [timeframe, start, group] @@ -323,7 +339,7 @@ def get_query_parameters_from_db_addon_fct() -> Union[dict, None]: func = 'sum_max' start, timeframe = split_sting_letters_numbers(db_addon_fct_vars[3]) start = to_int(start) - timeframe = harmonize_timeframe_expression(timeframe) + timeframe = translate_timeframe(timeframe) end = 0 group = 'day', group2 = 'month' @@ -336,7 +352,7 @@ def get_query_parameters_from_db_addon_fct() -> Union[dict, None]: timeframe = 'year' start, group = split_sting_letters_numbers(db_addon_fct_vars[2]) start = to_int(start) - group = harmonize_timeframe_expression(group) + group = translate_timeframe(group) end = 0 log_text = 'serie_tagesmittelwert_count|group' required_params = [func, timeframe, start, end, group] @@ -349,17 +365,17 @@ def get_query_parameters_from_db_addon_fct() -> Union[dict, None]: group = 'hour' start, group2 = split_sting_letters_numbers(db_addon_fct_vars[3]) start = to_int(start) - group2 = harmonize_timeframe_expression(group2) + 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 Tage bis vor 0 Tagen (also heute) + # handle 'serie_tagesmittelwert_stunde_start_end|group' like 'serie_tagesmittelwert_stunde_30_0d' => Stundenmittelwerte von vor 30 Tagen bis vor 0 Tagen (also heute) method = '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 = harmonize_timeframe_expression(timeframe) + timeframe = translate_timeframe(timeframe) log_text = 'serie_tagesmittelwert_stunde_start_end|group' required_params = [timeframe, method, start, end] @@ -369,7 +385,7 @@ def get_query_parameters_from_db_addon_fct() -> Union[dict, None]: end = 0 start, timeframe = split_sting_letters_numbers(db_addon_fct_vars[4]) start = to_int(start) - timeframe = harmonize_timeframe_expression(timeframe) + timeframe = translate_timeframe(timeframe) log_text = 'serie_tagesmittelwert_tag_stunde_end|group' required_params = [timeframe, method, start, end] @@ -461,7 +477,7 @@ def get_database_item_path() -> tuple: for i in range(3): if self.has_iattr(_lookup_item.conf, 'db_addon_database_item'): - if self.parse_debug: + if self.debug_log.parse: self.logger.debug(f"Attribut 'db_addon_database_item' for item='{item.path()}' has been found {i + 1} level above item at '{_lookup_item.path()}'.") _database_item_path = self.get_iattr_value(_lookup_item.conf, 'db_addon_database_item') _startup = bool(self.get_iattr_value(_lookup_item.conf, 'db_addon_startup')) @@ -480,7 +496,7 @@ def get_database_item() -> Item: for i in range(2): if self.has_iattr(_lookup_item.conf, self.item_attribute_search_str): - if self.parse_debug: + if self.debug_log.parse: self.logger.debug(f"Attribut '{self.item_attribute_search_str}' for item='{item.path()}' has been found {i + 1} level above item at '{_lookup_item.path()}'.") return _lookup_item else: @@ -532,7 +548,7 @@ def format_db_addon_ignore_value_list(optimize: bool = self.optimize_value_filte db_addon_ignore_value_list_formatted.append(f"{op} {value}") max_values[op].append(value) - if self.parse_debug: + if self.debug_log.parse: self.logger.debug(f"Summarized 'ignore_value_list' for item {item.path()}: {db_addon_ignore_value_list_formatted}") if not db_addon_ignore_value_list_formatted: @@ -541,7 +557,7 @@ def format_db_addon_ignore_value_list(optimize: bool = self.optimize_value_filte if not optimize: return db_addon_ignore_value_list_formatted - if self.parse_debug: + if self.debug_log.parse: self.logger.debug(f"Optimizing 'ignore_value_list' for item {item.path()} active.") # find low @@ -572,7 +588,7 @@ def format_db_addon_ignore_value_list(optimize: bool = self.optimize_value_filte if (not lower_end[0] or (lower_end[0] and v >= lower_end[1])) or (not upper_end[0] or (upper_end[0] and v <= upper_end[1])): db_addon_ignore_value_list_optimized.append(f'!= {v}') - if self.parse_debug: + if self.debug_log.parse: self.logger.debug(f"Optimized 'ignore_value_list' for item {item.path()}: {db_addon_ignore_value_list_optimized}") return db_addon_ignore_value_list_optimized @@ -580,7 +596,7 @@ def format_db_addon_ignore_value_list(optimize: bool = self.optimize_value_filte # handle all items with db_addon_fct if self.has_iattr(item.conf, 'db_addon_fct'): - if self.parse_debug: + if self.debug_log.parse: self.logger.debug(f"parse item: {item.path()} due to 'db_addon_fct'") # get db_addon_fct attribute value @@ -600,7 +616,7 @@ def format_db_addon_ignore_value_list(optimize: bool = self.optimize_value_filte database_item = get_database_item() db_addon_startup = bool(self.get_iattr_value(item.conf, 'db_addon_startup')) if database_item is None: - self.logger.warning(f"No database item found for {item.path()}: Item ignored. Maybe you should check instance of database plugin.") + self.logger.warning(f"No database item found for item={item.path()}: Item ignored. Maybe you should check instance of database plugin.") return # get/create list of comparison operators and check it @@ -623,20 +639,20 @@ def format_db_addon_ignore_value_list(optimize: bool = self.optimize_value_filte if db_addon_ignore_value_list: db_addon_ignore_value_list_final = format_db_addon_ignore_value_list() - if self.parse_debug: + if self.debug_log.parse: self.logger.debug(f"{db_addon_ignore_value_list_final=}") 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} + item_config_data_dict = {'db_addon': 'function', 'db_addon_fct': db_addon_fct, 'database_item': database_item, 'query_params': query_params, 'active': True} if isinstance(database_item, str): item_config_data_dict.update({'database_item_path': True}) else: database_item = database_item.path() # do logging - if self.parse_debug: - self.logger.debug(f"Item '{item.path()}' added with db_addon_fct={db_addon_fct} and database_item={database_item}") + if self.debug_log.parse: + self.logger.debug(f"Item={item.path()} added with db_addon_fct={db_addon_fct} and database_item={database_item}") # add cycle for item groups if db_addon_fct in ALL_DAILY_ATTRIBUTES: @@ -661,7 +677,7 @@ def format_db_addon_ignore_value_list(optimize: bool = self.optimize_value_filte item_config_data_dict.update({'cycle': f"{timeframe_to_updatecyle(cycle)}"}) # do logging - if self.parse_debug: + if self.debug_log.parse: self.logger.debug(f"Item '{item.path()}' added to be run {item_config_data_dict['cycle']}.") # create item config for item to be run on startup @@ -675,21 +691,21 @@ def format_db_addon_ignore_value_list(optimize: bool = self.optimize_value_filte # handle all items with db_addon_info elif self.has_iattr(item.conf, 'db_addon_info'): - if self.parse_debug: - self.logger.debug(f"parse item: {item.path()} due to used item attribute 'db_addon_info'") + if self.debug_log.parse: + self.logger.debug(f"parse item={item.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}) # handle all items with db_addon_admin elif self.has_iattr(item.conf, 'db_addon_admin'): - if self.parse_debug: - self.logger.debug(f"parse item: {item.path()} due to used item attribute 'db_addon_admin'") + if self.debug_log.parse: + self.logger.debug(f"parse item={item.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}) return self.update_item # Reference to 'update_item' für alle Items mit Attribut 'database', um die on_change Items zu berechnen elif self.has_iattr(item.conf, self.item_attribute_search_str) and has_db_addon_item(): - if self.parse_debug: - self.logger.debug(f"reference to update_item for item '{item.path()}' will be set due to on-change") + if self.debug_log.parse: + self.logger.debug(f"reference to update_item for item={item.path()} will be set due to on-change") self.add_item(item, config_data_dict={'db_addon': 'database'}) return self.update_item @@ -739,7 +755,7 @@ def execute_startup_items(self) -> None: self.execute_items(option='startup') self.startup_finished = True - def execute_items(self, option: str = 'due'): + def execute_items(self, option: str = 'due', item: str = None): """Execute all items per option""" def _create_due_items() -> list: @@ -752,33 +768,36 @@ def _create_due_items() -> list: self.previous_values[DAY] = {} # wenn Wochentag == Montag, werden auch die wöchentlichen Items berechnet - if self.shtime.now().hour == 0 and self.shtime.now().minute == 0 and self.shtime.weekday( - self.shtime.today()) == 1: + if self.shtime.weekday(self.shtime.today()) == 1: _todo_items.update(set(self._weekly_items())) self.current_values[WEEK] = {} self.previous_values[WEEK] = {} # wenn der erste Tage eines Monates ist, werden auch die monatlichen Items berechnet - if self.shtime.now().hour == 0 and self.shtime.now().minute == 0 and self.shtime.now().day == 1: + if self.shtime.now().day == 1: _todo_items.update(set(self._monthly_items())) self.current_values[MONTH] = {} self.previous_values[MONTH] = {} - # wenn der erste Tage des ersten Monates eines Jahres ist, werden auch die jährlichen Items berechnet - if self.shtime.now().hour == 0 and self.shtime.now().minute == 0 and self.shtime.now().day == 1 and self.shtime.now().month == 1: - _todo_items.update(set(self._yearly_items())) - self.current_values[YEAR] = {} - self.previous_values[YEAR] = {} + # wenn der erste Tage des ersten Monates eines Jahres ist, werden auch die jährlichen Items berechnet + if self.shtime.now().month == 1: + _todo_items.update(set(self._yearly_items())) + self.current_values[YEAR] = {} + self.previous_values[YEAR] = {} return list(_todo_items) - if self.execute_debug: + if self.debug_log.execute: self.logger.debug(f"execute_items called with {option=}") if self.suspended: self.logger.info(f"Plugin is suspended. No items will be calculated.") return + deactivated_items = self._deactivated_items() + if len(deactivated_items) > 0: + self.logger.info(f"{len(deactivated_items)} are de-activated and will not be calculated.") + todo_items = [] if option == 'startup': todo_items = self._startup_items() @@ -794,7 +813,17 @@ def _create_due_items() -> list: todo_items = self._all_items() elif option == 'due': todo_items = _create_due_items() + elif option == 'item': + if isinstance(item, str): + item = self.items.return_item(item) + if isinstance(item, Item): + todo_items = [item] + # remove de-activated items + if option != 'item': + todo_items = list(set(todo_items) - set(deactivated_items)) + + # put to queue self.logger.info(f"{len(todo_items)} items will be calculated for {option=}.") [self.item_queue.put(i) for i in todo_items] @@ -804,17 +833,18 @@ def work_item_queue(self) -> None: while self.alive: try: queue_entry = self.item_queue.get(True, 10) + self.logger.debug(f"{queue_entry=}") except queue.Empty: self.active_queue_item = '-' pass else: if isinstance(queue_entry, tuple): item, value = queue_entry - self.logger.info(f"# {self.item_queue.qsize() + 1} item(s) to do. || 'on-change' item '{item.path()}' with {value=} will be processed.") + self.logger.info(f"# {self.item_queue.qsize() + 1} item(s) to do. || 'on-change' item={item.path()} with {value=} will be processed.") self.active_queue_item = str(item.path()) self.handle_onchange(item, value) else: - self.logger.info(f"# {self.item_queue.qsize() + 1} item(s) to do. || 'on-demand' item '{queue_entry.path()}' will be processed.") + self.logger.info(f"# {self.item_queue.qsize() + 1} item(s) to do. || 'on-demand' item={queue_entry.path()} will be processed.") self.active_queue_item = str(queue_entry.path()) self.handle_ondemand(queue_entry) @@ -827,7 +857,7 @@ def handle_ondemand(self, item: Item) -> None: # get parameters item_config = self.get_item_config(item) - if self.ondemand_debug: + if self.debug_log.ondemand: self.logger.debug(f"Item={item.path()} with {item_config=}") db_addon_fct = item_config['db_addon_fct'] database_item = item_config['database_item'] @@ -838,7 +868,7 @@ def handle_ondemand(self, item: Item) -> None: else: params = {} - if self.ondemand_debug: + if self.debug_log.ondemand: self.logger.debug(f"{db_addon_fct=} will _query_item with {params=}.") # handle item starting with 'verbrauch_' @@ -846,7 +876,7 @@ def handle_ondemand(self, item: Item) -> None: result = self._handle_verbrauch(params) if result and result < 0: - self.logger.warning(f"Result of item {item.path()} with {db_addon_fct=} was negative. Something seems to be wrong.") + self.logger.info(f"Result of item {item.path()} with {db_addon_fct=} was negative. Something seems to be wrong.") # handle 'serie_verbrauch' elif db_addon_fct in SERIE_ATTRIBUTES_VERBRAUCH: @@ -907,7 +937,7 @@ def handle_ondemand(self, item: Item) -> None: result = self._query_item(**params)[0][1] # log result - if self.ondemand_debug: + if self.debug_log.ondemand: self.logger.debug(f"result is {result} for item '{item.path()}' with '{db_addon_fct=}'") if result is None: @@ -932,7 +962,7 @@ def handle_minmax(): cache_dict = self.current_values[timeframe] init = False - if self.onchange_debug: + if self.debug_log.onchange: self.logger.debug(f"'minmax' Item={updated_item.path()} with {func=} and {timeframe=} detected. Check for update of cache_dicts {cache_dict=} and item value.") # make sure, that database item is in cache dict @@ -942,55 +972,55 @@ def handle_minmax(): # get _recent_value; if not already cached, create cache cached_value = cache_dict[database_item].get(func) if cached_value is None: - if self.onchange_debug: + if self.debug_log.onchange: self.logger.debug(f"{func} value for {timeframe=} of item={updated_item.path()} not in cache dict. Query database.") query_params = {'func': func, 'database_item': database_item, 'timeframe': timeframe, 'start': 0, 'end': 0, 'ignore_value_list': ignore_value_list, 'use_oldest_entry': True} cached_value = self._query_item(**query_params)[0][1] if cached_value is None: - if self.onchange_debug: - self.logger.debug(f"{func} value for {timeframe=} of item={updated_item.path()} not available in database. Abort calculation.") + if self.debug_log.onchange: + self.logger.debug(f"{func} value for {timeframe=} of item={updated_item.path()} not available in database. Abort calculation.") return init = True - # if value not given -> read + # if value not given if init: - if self.onchange_debug: - self.logger.debug(f"initial {func} value for {timeframe=} of item={item.path()} with will be set to {cached_value}") - cache_dict[database_item][func] = cached_value - return cached_value + if self.debug_log.onchange: + self.logger.debug(f"initial {func} value for {timeframe=} of item={item.path()} with will be set to {value}") + cache_dict[database_item][func] = value + return value # check value for update of cache dict min elif func == 'min' and value < cached_value: - if self.onchange_debug: + if self.debug_log.onchange: self.logger.debug(f"new value={value} lower then current min_value={cached_value} for {timeframe=}. cache_dict will be updated") cache_dict[database_item][func] = value return value # check value for update of cache dict max elif func == 'max' and value > cached_value: - if self.onchange_debug: + if self.debug_log.onchange: self.logger.debug(f"new value={value} higher then current max_value={cached_value} for {timeframe=}. cache_dict will be updated") cache_dict[database_item][func] = value return value # no impact - if self.onchange_debug: + if self.debug_log.onchange: self.logger.debug(f"new value={value} will not change max/min for period={timeframe}.") return None def handle_verbrauch(): cache_dict = self.previous_values[timeframe] - if self.onchange_debug: + if self.debug_log.onchange: self.logger.debug(f"'verbrauch' item {updated_item.path()} with {func=} and {value=} detected. Check for update of cache_dicts {cache_dict=} and item value.") # get _cached_value for value at end of last period; if not already cached, create cache cached_value = cache_dict.get(database_item) if cached_value is None: - if self.onchange_debug: + if self.debug_log.onchange: self.logger.debug(f"Most recent value for last {timeframe=} of item={updated_item.path()} not in cache dict. Query database.") # try to get most recent value of last timeframe, assuming that this is the value at end of last timeframe @@ -1002,12 +1032,12 @@ def handle_verbrauch(): return cache_dict[database_item] = cached_value - if self.onchange_debug: + if self.debug_log.onchange: self.logger.debug(f"Value for Item={updated_item.path()} at end of last {timeframe} not in cache dict. Value={cached_value} has been added.") # calculate value, set item value, put data into plugin_item_dict _new_value = value - cached_value - return _new_value if isinstance(_new_value, int) else round(_new_value, 1) + return _new_value if isinstance(_new_value, int) else round(_new_value, 2) def handle_tagesmittel(): result = self._prepare_value_list(database_item=database_item, timeframe='day', start=0, end=0, ignore_value_list=ignore_value_list, method='first_hour') @@ -1015,17 +1045,18 @@ def handle_tagesmittel(): if isinstance(result, list): return result[0][1] - if self.onchange_debug: + if self.debug_log.onchange: self.logger.debug(f"called with updated_item={updated_item.path()} and value={value}.") relevant_item_list = set(self.get_item_list('database_item', updated_item)) & set(self.get_item_list('cycle', 'on-change')) - if self.onchange_debug: + if self.debug_log.onchange: self.logger.debug(f"Following items where identified for update: {relevant_item_list}.") for item in relevant_item_list: item_config = self.get_item_config(item) - self.logger.debug(f"Item={item.path()} with {item_config=}") + if self.debug_log.onchange: + self.logger.debug(f"Item={item.path()} with {item_config=}") db_addon_fct = item_config['db_addon_fct'] database_item = item_config['database_item'] timeframe = item_config['query_params']['timeframe'] @@ -1035,7 +1066,7 @@ def handle_tagesmittel(): # handle all on_change functions if db_addon_fct not in ALL_ONCHANGE_ATTRIBUTES: - if self.onchange_debug: + if self.debug_log.onchange: self.logger.debug(f"non on-change function detected. Skip update.") continue @@ -1074,8 +1105,19 @@ def _update_database_items(self) -> None: if db_addon_startup: item_config.update({'startup': True}) + def _activate_item_calculation(self, item: Union[str, Item], active: bool = True) -> None: + """active / de-active item calculation""" + if isinstance(item, str): + item = self.items.return_item(item) + + if not isinstance(item, Item): + return + + item_config = self.get_item_config(item) + item_config['active'] = active + @property - def log_level(self): + def log_level(self) -> int: return self.logger.getEffectiveLevel() def queue_backlog(self) -> int: @@ -1120,6 +1162,9 @@ def _database_item_path_items(self) -> list: def _ondemand_items(self) -> list: return self._daily_items() + self._weekly_items() + self._monthly_items() + self._yearly_items() + self._static_items() + def _deactivated_items(self) -> list: + return self.get_item_list('active', False) + def _all_items(self) -> list: # return self._ondemand_items() + self._onchange_items() + self._static_items() + self._admin_items() + self._info_items() return self.get_item_list('db_addon', 'function') @@ -1133,7 +1178,7 @@ def gruenlandtemperatursumme(self, item_path: str, year: Union[int, str] = None) Query database for gruenlandtemperatursumme for given year or year https://de.wikipedia.org/wiki/Gr%C3%BCnlandtemperatursumme - Beim Grünland wird die Wärmesumme nach Ernst und Loeper benutzt, um den Vegetationsbeginn und somit den Termin von Düngungsmaßnahmen zu bestimmen. + Beim Grünland wird die Wärmesumme nach Ernst und Loeper benutzt, um den Vegetationsbeginn und somit den Termin von Duengemaßnahmen zu bestimmen. Dabei erfolgt die Aufsummierung der Tagesmitteltemperaturen über 0 °C, wobei der Januar mit 0.5 und der Februar mit 0.75 gewichtet wird. Bei einer Wärmesumme von 200 Grad ist eine Düngung angesagt. @@ -1199,7 +1244,7 @@ def tagesmitteltemperatur(self, item_path: str, timeframe: str = None, count: in count = to_int(count) end = 0 start = end + count - query_params = {'database_item': item, 'func': 'max', 'timeframe': harmonize_timeframe_expression(timeframe), 'start': start, 'end': end} + query_params = {'database_item': item, 'func': 'max', 'timeframe': translate_timeframe(timeframe), 'start': start, 'end': end} return self._handle_tagesmitteltemperatur(**query_params) def wachstumsgradtage(self, item_path: str, year: Union[int, str] = None, method: int = 0, threshold: int = 10) -> Union[int, None]: @@ -1295,11 +1340,11 @@ def suspend(self, state: bool = False) -> bool: """ if state: - self.logger.warning("Plugin is set to 'suspended'. Queries to database will not be made until suspension is cancelled.") + self.logger.info("Plugin is set to 'suspended'. Queries to database will not be made until suspension is cleared.") self.suspended = True self._clear_queue() else: - self.logger.warning("Plugin suspension cancelled. Queries to database will be resumed.") + self.logger.info("Plugin suspension cleared. Queries to database will be resumed.") self.suspended = False # write back value to item, if one exists @@ -1333,8 +1378,8 @@ def _handle_verbrauch(self, query_params: dict) -> Union[None, float]: # define start, end for verbrauch_jahreszeitraum_timedelta if 'timedelta' in query_params: timedelta = query_params.pop('timedelta') - today = datetime.date.today() - start_date = datetime.date(today.year, 1, 1) - relativedelta(years=timedelta) + today = self.shtime.today(offset=0) + start_date = self.shtime.beginning_of_year(offset=-timedelta) end_date = today - relativedelta(years=timedelta) start = (today - start_date).days end = (today - end_date).days @@ -1343,14 +1388,14 @@ def _handle_verbrauch(self, query_params: dict) -> Union[None, float]: end = query_params['end'] # calculate consumption - if self.prepare_debug: + 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': end, 'end': end}) value_end = self._query_item(**query_params)[0][1] - if self.prepare_debug: + if self.debug_log.prepare: self.logger.debug(f"{value_end=}") if value_end is None or value_end == 0: @@ -1359,36 +1404,37 @@ def _handle_verbrauch(self, query_params: dict) -> Union[None, float]: # get value for start and check it; query_params.update({'func': 'last', 'start': start, 'end': start}) value_start = self._query_item(**query_params)[0][1] - if self.prepare_debug: + if self.debug_log.prepare: self.logger.debug(f"{value_start=}") if value_start is None: - if self.prepare_debug: + if self.debug_log.prepare: self.logger.debug(f"Error occurred during query. Return.") return if not value_start: - self.logger.info(f"No DB Entry found for requested start date. Looking for next recent DB entry.") + self.logger.info(f"No DB Entry of item={query_params['database_item'].path()} found for requested start date. Looking for next recent DB entry.") query_params.update({'func': 'next'}) value_start = self._query_item(**query_params)[0][1] - if self.prepare_debug: + if self.debug_log.prepare: self.logger.debug(f"next recent value is {value_start=}") if not value_start: value_start = 0 - if self.prepare_debug: + if self.debug_log.prepare: self.logger.debug(f"No start value available. Will be set to 0 as default") # calculate consumption consumption = value_end - value_start - if self.prepare_debug: - self.logger.debug(f"{consumption=}") if isinstance(consumption, float): if consumption.is_integer(): consumption = int(consumption) else: - consumption = round(consumption, 1) + consumption = round(consumption, 2) + + if self.debug_log.prepare: + self.logger.debug(f"{consumption=}") return consumption @@ -1402,7 +1448,7 @@ def _handle_verbrauch_serie(self, query_params: dict) -> list: for i in range(1, start): value = self._handle_verbrauch({'database_item': database_item, 'timeframe': timeframe, 'start': i + 1, 'end': i}) - ts_start, ts_end = get_start_end_as_timestamp(timeframe, i, i + 1) + ts_start, ts_end = self._get_start_end_as_timestamp(timeframe, i, i + 1) series.append([ts_end, value]) return series @@ -1420,33 +1466,34 @@ def _handle_zaehlerstand(self, query_params: dict) -> Union[float, int, None]: - Ergibt diese Abfrage keinen Wert, dann Rückgabe von None """ - if self.prepare_debug: + if self.debug_log.prepare: self.logger.debug(f"called with {query_params=}") # get last value of timeframe query_params.update({'func': 'last'}) last_value = self._query_item(**query_params)[0][1] - if self.prepare_debug: + if self.debug_log.prepare: self.logger.debug(f"{last_value=}") if last_value is None: - if self.prepare_debug: + if self.debug_log.prepare: self.logger.debug(f"Error occurred during query. Return.") return if not last_value: # get last value (next) before timeframe - self.logger.info(f"No DB Entry found for requested start date. Looking for next recent DB entry.") + if self.debug_log.prepare: + self.logger.debug(f"No DB entry for item={query_params['database_item'].path()} found for requested start date. Looking for next recent DB entry.") query_params.update({'func': 'next'}) last_value = self._query_item(**query_params)[0][1] - if self.prepare_debug: + if self.debug_log.prepare: self.logger.debug(f"next recent value is {last_value=}") if isinstance(last_value, float): if last_value.is_integer(): last_value = int(last_value) else: - last_value = round(last_value, 1) + last_value = round(last_value, 2) return last_value @@ -1460,7 +1507,7 @@ def _handle_zaehlerstand_serie(self, query_params: dict) -> list: for i in range(1, start): value = self._handle_zaehlerstand({'database_item': database_item, 'timeframe': timeframe, 'start': i, 'end': i}) - ts_start = get_start_end_as_timestamp(timeframe, i, i)[0] + ts_start = self._get_start_end_as_timestamp(timeframe, i, i)[0] series.append([ts_start, value]) return series @@ -1476,30 +1523,29 @@ def _handle_kaeltesumme(self, database_item: Item, year: Union[int, str] = None, :return: kaeltesumme """ - if self.prepare_debug: + if self.debug_log.prepare: self.logger.debug(f"called with {database_item=}, {year=}, {month=}") # check validity of given year - if not valid_year(year): + if not self._valid_year(year): self.logger.error(f"Year for item={database_item.path()} was {year}. This is not a valid year. Query cancelled.") return - # set default year - if not year: - year = 'current' + # get datetime of today + today = self.shtime.today(offset=0) # define year - if year == 'current': - if datetime.date.today() < datetime.date(int(datetime.date.today().year), 9, 21): - year = datetime.date.today().year - 1 + if not year or year == 'current': + if today < datetime.date(int(today.year), 9, 21): + year = today.year - 1 else: - year = datetime.date.today().year + year = today.year # define start_date and end_date if month is None: start_date = datetime.date(int(year), 9, 21) end_date = datetime.date(int(year) + 1, 3, 22) - elif valid_month(month): + 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) else: @@ -1507,7 +1553,6 @@ def _handle_kaeltesumme(self, database_item: Item, year: Union[int, str] = None, return # define start / end - today = datetime.date.today() if start_date > today: self.logger.error(f"Start time for query of item={database_item.path()} is in future. Query cancelled.") return @@ -1519,10 +1564,10 @@ def _handle_kaeltesumme(self, database_item: Item, year: Union[int, str] = None, return # get raw data as list - if self.prepare_debug: + if self.debug_log.prepare: self.logger.debug("try to get raw data") raw_data = self._prepare_value_list(database_item=database_item, timeframe='day', start=start, end=end, method='avg_hour') - if self.execute_debug: + if self.debug_log.prepare: self.logger.debug(f"raw_value_list={raw_data=}") # calculate value @@ -1549,7 +1594,7 @@ def _handle_waermesumme(self, database_item: Item, year: Union[int, str] = None, # get raw data as list raw_data = self._prepare_waermesumme(database_item=database_item, year=year, month=month) - if self.execute_debug: + if self.debug_log.prepare: self.logger.debug(f"raw_value_list={raw_data=}") # set threshold to min 0 @@ -1578,7 +1623,7 @@ def _handle_gruenlandtemperatursumme(self, database_item: Item, year: Union[int, # get raw data as list raw_data = self._prepare_waermesumme(database_item=database_item, year=year) - if self.execute_debug: + if self.debug_log.prepare: self.logger.debug(f"raw_data={raw_data}") # calculate value @@ -1591,7 +1636,7 @@ def _handle_gruenlandtemperatursumme(self, database_item: Item, year: Union[int, for entry in raw_data: timestamp, value = entry if value > 0: - dt = datetime.datetime.fromtimestamp(timestamp / 1000) + dt = self._timestamp_to_datetime(timestamp / 1000) if dt.month == 1: value = value * 0.5 elif dt.month == 2: @@ -1611,24 +1656,22 @@ def _handle_wachstumsgradtage(self, database_item: Item, year: Union[int, str] = :return: wachstumsgradtage """ - # set default year - if not year: - year = 'current' - - if not valid_year(year): + if not self._valid_year(year): self.logger.error(f"Year for item={database_item.path()} was {year}. This is not a valid year. Query cancelled.") return + # get datetime of today + today = self.shtime.today(offset=0) + # define year - if year == 'current': - year = datetime.date.today().year + if not year or year == 'current': + year = today.year # define start_date, end_date start_date = datetime.date(int(year), 1, 1) end_date = datetime.date(int(year), 9, 21) # check start_date - today = datetime.date.today() if start_date > today: self.logger.info(f"Start time for query of item={database_item.path()} is in future. Query cancelled.") return @@ -1643,8 +1686,8 @@ def _handle_wachstumsgradtage(self, database_item: Item, year: Union[int, str] = return # get raw data as list - raw_data = self._prepare_value_list(database_item=database_item, timeframe='day', start=start, end=end, method='minmax_hour') - if self.execute_debug: + raw_data = self._prepare_value_list(database_item=database_item, timeframe='day', start=start, end=end, method='minmax_hour') + if self.debug_log.prepare: self.logger.debug(f"raw_value_list={raw_data}") # calculate value @@ -1709,24 +1752,22 @@ def _handle_temperaturserie(self, database_item: Item, year: Union[int, str] = N :return: list of temperatures """ - # set default year - if not year: - year = 'current' - - if not valid_year(year): + if not self._valid_year(year): self.logger.error(f"Year for item={database_item.path()} was {year}. This is not a valid year. Query cancelled.") return + # get datetime of today + today = self.shtime.today(offset=0) + # define year - if year == 'current': - year = datetime.date.today().year + if not year or year == 'current': + year = today.year # define start_date, end_date start_date = datetime.date(int(year), 1, 1) end_date = datetime.date(int(year), 12, 31) # check start_date - today = datetime.date.today() if start_date > today: self.logger.info(f"Start time for query of item={database_item.path()} is in future. Query cancelled.") return @@ -1742,7 +1783,7 @@ def _handle_temperaturserie(self, database_item: Item, year: Union[int, str] = N # get raw data as list temp_list = self._prepare_value_list(database_item=database_item, timeframe='day', start=start, end=end, method=method) - if self.execute_debug: + if self.debug_log.prepare: self.logger.debug(f"{temp_list=}") return temp_list @@ -1751,23 +1792,22 @@ def _prepare_waermesumme(self, database_item: Item, year: Union[int, str] = None """Prepares raw data for waermesumme""" # check validity of given year - if not valid_year(year): + if not self._valid_year(year): self.logger.error(f"Year for item={database_item.path()} was {year}. This is not a valid year. Query cancelled.") return - # set default year - if not year: - year = 'current' + # get datetime of today + today = self.shtime.today(offset=0) # define year - if year == 'current': - year = datetime.date.today().year + if not year or year == 'current': + year = today.year # define start_date, end_date if month is None: start_date = datetime.date(int(year), 1, 1) end_date = datetime.date(int(year), 9, 21) - elif valid_month(month): + 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) else: @@ -1775,7 +1815,6 @@ def _prepare_waermesumme(self, database_item: Item, year: Union[int, str] = None return # check start_date - today = datetime.date.today() if start_date > today: self.logger.info(f"Start time for query of item={database_item.path()} is in future. Query cancelled.") return @@ -1814,12 +1853,12 @@ def _prepare_value_list(self, database_item: Item, timeframe: str, start: int, e def _create_raw_value_dict(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]} - :param block: defined the increment of datetimes, default is hour, furhter possible is 'day' + :param block: defined the increment of datetimes, default is hour, further possible is 'day' """ _value_dict = {} for _entry in raw_data: - dt = datetime.datetime.utcfromtimestamp(_entry[0] / 1000) + dt = self._timestamp_to_datetime(_entry[0] / 1000) dt = dt.replace(minute=0, second=0, microsecond=0) if block == 'day': dt = dt.replace(hour=0) @@ -1843,15 +1882,18 @@ def _create_value_list_timestamp_value(option: str) -> list: _value_list = [] # create nested list with timestamp, avg_value per hour/day for entry in value_dict: - _timestamp = datetime_to_timestamp(entry) + _timestamp = self._datetime_to_timestamp(entry) if option == 'first': _value_list.append([_timestamp, value_dict[entry][0]]) elif option == 'avg': - _value_list.append([_timestamp, round(sum(value_dict[entry]) / len(value_dict[entry]), 1)]) + _value_list.append([_timestamp, round(sum(value_dict[entry]) / len(value_dict[entry]), 2)]) elif option == 'minmax': _value_list.append([_timestamp, min(value_dict[entry]), max(value_dict[entry])]) return _value_list + if self.debug_log.prepare: + self.logger.debug(f'called with database_item={database_item.path()}, {timeframe=}, {start=}, {end=}, {ignore_value_list=}, {method=}') + # check method if method in ['avg_day', 'avg_hour', 'minmax_day', 'minmax_hour', 'first_day', 'first_hour']: _method, _block = method.split('_') @@ -1864,18 +1906,18 @@ def _create_value_list_timestamp_value(option: str) -> list: # get raw data from database raw_data = self._query_item(func='raw', database_item=database_item, timeframe=timeframe, start=start, end=end, ignore_value_list=ignore_value_list) - if raw_data in [[[None, None]], [[0, 0]]]: - self.logger.warning("no valid data from database query received during _prepare_value_list. Aborting...") + if raw_data == [[None, None]] or raw_data == [[0, 0]]: + self.logger.info(f"no valid data from database query for item={database_item.path()} received during _prepare_value_list. Aborting...") return # create nested dict with values value_dict = _create_raw_value_dict(block=_block) - if self.prepare_debug: + if self.debug_log.prepare: self.logger.debug(f"{value_dict=}") # return value list result = _create_value_list_timestamp_value(option=_method) - if self.prepare_debug: + if self.debug_log.prepare: self.logger.debug(f"{method=}, {result=}") return result @@ -1937,33 +1979,9 @@ def _get_db_parameter(self) -> bool: else: return True - def _initialize_db(self) -> bool: - """ - Initializes database connection - - :return: Status of initialization - """ - - try: - if not self._db.connected(): - # limit connection requests to 20 seconds. - current_time = time.time() - time_delta_last_connect = current_time - self.last_connect_time - if time_delta_last_connect > 20: - self.last_connect_time = time.time() - self._db.connect() - else: - self.logger.error(f"_initialize_db: Database reconnect suppressed: Delta time: {time_delta_last_connect}") - return False - except Exception as e: - self.logger.critical(f"_initialize_db: Database: Initialization failed: {e}") - return False - else: - return True - def _check_db_connection_setting(self) -> None: """ - Check Setting of DB connection for stable use. + Check Setting of mysql connection for stable use. """ try: connect_timeout = int(self._get_db_connect_timeout()[1]) @@ -1998,8 +2016,8 @@ def _get_oldest_log(self, item: Item) -> Union[None, int]: self.item_cache[item] = {} self.item_cache[item]['oldest_log'] = oldest_log - if self.prepare_debug: - self.logger.debug(f"_get_oldest_log for item {item.path()} = {oldest_log}") + if self.debug_log.prepare: + self.logger.debug(f"_get_oldest_log for item={item.path()} = {oldest_log}") return oldest_log @@ -2024,7 +2042,7 @@ def _get_oldest_value(self, item: Item) -> Union[int, float, bool]: oldest_log = self._get_oldest_log(item) if oldest_log is None: validity = True - self.logger.error(f"oldest_log for item {item.path()} could not be read; value is set to -999999999") + self.logger.error(f"oldest_log for item={item.path()} could not be read; value is set to -999999999") oldest_entry = self._read_log_timestamp(item_id, oldest_log) i += 1 if isinstance(oldest_entry, list) and isinstance(oldest_entry[0], tuple) and len(oldest_entry[0]) >= 4: @@ -2035,10 +2053,10 @@ def _get_oldest_value(self, item: Item) -> Union[int, float, bool]: validity = True elif i == 10: validity = True - self.logger.error(f"oldest_value for item {item.path()} could not be read; value is set to -999999999") + self.logger.error(f"oldest_value for item={item.path()} could not be read; value is set to -999999999") - if self.prepare_debug: - self.logger.debug(f"_get_oldest_value for item {item.path()} = {_oldest_value}") + if self.debug_log.prepare: + self.logger.debug(f"_get_oldest_value for item={item.path()} = {_oldest_value}") return _oldest_value @@ -2080,7 +2098,7 @@ def _get_itemid_for_query(self, item: Union[Item, str, int]) -> Union[int, None] item_id = None return item_id - def _query_item(self, func: str, database_item: Item, timeframe: str, start: int = None, end: int = 0, group: str = None, group2: str = None, ignore_value_list=None, use_oldest_entry: bool = False) -> list: + def _query_item(self, func: str, database_item: Item, timeframe: str, start: int = None, end: int = 0, group: str = "", group2: str = "", ignore_value_list=None, use_oldest_entry: bool = False) -> list: """ Do diverse checks of input, and prepare query of log by getting item_id, start / end in timestamp etc. @@ -2097,84 +2115,85 @@ def _query_item(self, func: str, database_item: Item, timeframe: str, start: int :return: query response / list for value pairs [[None, None]] for errors, [[0,0]] for no-data in DB """ - if self.prepare_debug: - self.logger.debug(f"called with {func=}, item={database_item.path()}, {timeframe=}, {start=}, {end=}, {group=}, {group2=}, {ignore_value_list=}") + if self.debug_log.prepare: + self.logger.debug(f" called with {func=}, item={database_item.path()}, {timeframe=}, {start=}, {end=}, {group=}, {group2=}, {ignore_value_list=}, {use_oldest_entry=}") # set default result - default_result = [[None, None]] + error_result = [[None, None]] + nodata_result = [[0, 0]] # check correctness of timeframe if timeframe not in ALLOWED_QUERY_TIMEFRAMES: self.logger.error(f"Requested {timeframe=} for item={database_item.path()} not defined; Need to be 'year' or 'month' or 'week' or 'day' or 'hour''. Query cancelled.") - return default_result + return error_result # define start and end of query as timestamp in microseconds - ts_start, ts_end = get_start_end_as_timestamp(timeframe, start, end) + ts_start, ts_end = self._get_start_end_as_timestamp(timeframe, start, end) oldest_log = self._get_oldest_log(database_item) if oldest_log is None: - return default_result + return error_result # check correctness of ts_start / ts_end if ts_start is None: ts_start = oldest_log if ts_end is None or ts_start > ts_end: - if self.prepare_debug: + if self.debug_log.prepare: self.logger.debug(f"{ts_start=}, {ts_end=}") self.logger.warning(f"Requested {start=} for item={database_item.path()} is not valid since {start=} < {end=} or end not given. Query cancelled.") - return default_result + return error_result # define item_id item_id = self._get_itemid(database_item) if not item_id: - self.logger.error(f"ItemId for item={database_item.path()} not found. Query cancelled.") - return default_result + self.logger.error(f"DB ItemId for item={database_item.path()} not found. Query cancelled.") + return error_result - if self.prepare_debug: - self.logger.debug(f"Requested {timeframe=} with {start=} and {end=} resulted in start being timestamp={ts_start} / {timestamp_to_timestring(ts_start)} and end being timestamp={ts_end} / {timestamp_to_timestring(ts_end)}") + if self.debug_log.prepare: + self.logger.debug(f" Requested {timeframe=} with {start=} and {end=} resulted in start being timestamp={ts_start}/{self._timestamp_to_timestring(ts_start)} and end being timestamp={ts_end}/{self._timestamp_to_timestring(ts_end)}") # check if values for end time and start time are in database if ts_end < oldest_log: # (Abfrage abbrechen, wenn Endzeitpunkt in UNIX-timestamp der Abfrage kleiner (und damit jünger) ist, als der UNIX-timestamp des ältesten Eintrages) - self.logger.info(f"Requested end time timestamp={ts_end} / {timestamp_to_timestring(ts_end)} of query for Item='{database_item.path()}' is prior to oldest entry with timestamp={oldest_log} / {timestamp_to_timestring(oldest_log)}. Query cancelled.") - return default_result + self.logger.info(f" Requested end time timestamp={ts_end}/{self._timestamp_to_timestring(ts_end)} of query for item={database_item.path()} is prior to oldest entry with timestamp={oldest_log}/{self._timestamp_to_timestring(oldest_log)}. Query cancelled.") + return error_result if ts_start < oldest_log: if self.use_oldest_entry or use_oldest_entry: - self.logger.info(f"Requested start time timestamp={ts_start} / {timestamp_to_timestring(ts_start)} of query for Item='{database_item.path()}' is prior to oldest entry with timestamp={oldest_log} / {timestamp_to_timestring(oldest_log)}. Oldest available entry will be used.") + self.logger.info(f" Requested start time timestamp={ts_start}/{self._timestamp_to_timestring(ts_start)} of query for item={database_item.path()} is prior to oldest entry with timestamp={oldest_log}/{self._timestamp_to_timestring(oldest_log)}. Oldest available entry will be used.") ts_start = oldest_log else: - self.logger.info(f"Requested start time timestamp={ts_start} / {timestamp_to_timestring(ts_start)} of query for Item='{database_item.path()}' is prior to oldest entry with timestamp={oldest_log} / {timestamp_to_timestring(oldest_log)}. Query cancelled.") - return default_result + self.logger.info(f" Requested start time timestamp={ts_start}/{self._timestamp_to_timestring(ts_start)} of query for item={database_item.path()} is prior to oldest entry with timestamp={oldest_log}/{self._timestamp_to_timestring(oldest_log)}. Query cancelled.") + return error_result # prepare and do query query_params = {'func': func, 'item_id': item_id, 'ts_start': ts_start, 'ts_end': ts_end, 'group': group, 'group2': group2, 'ignore_value_list': ignore_value_list} query_result = self._query_log_timestamp(**query_params) - if self.prepare_debug: - self.logger.debug(f"result of '_query_log_timestamp' {query_result=}") + if self.debug_log.prepare: + self.logger.debug(f" result of '_query_log_timestamp' {query_result=}") # post process query_result if query_result is None: - self.logger.error(f"Error occurred during _query_item. Aborting...") - return default_result + self.logger.error(f"Error occurred during '_query_log_timestamp' of item={database_item.path()}. Aborting...") + return error_result if len(query_result) == 0: - self.logger.info(f"No values for item in requested timeframe in database found.") - return [[0, 0]] + self.logger.info(f" No values for item={database_item.path()} in requested timeframe between {ts_start}/{self._timestamp_to_timestring(ts_start)} and {ts_end}/{self._timestamp_to_timestring(ts_end)} in database found.") + return nodata_result result = [] for element in query_result: timestamp, value = element if timestamp is not None and value is not None: if isinstance(value, float): - value = round(value, 1) + value = round(value, 2) result.append([timestamp, value]) - if self.prepare_debug: - self.logger.debug(f"value for item={database_item.path()} with {query_params=}: {result}") + if self.debug_log.prepare: + self.logger.debug(f" value for item={database_item.path()} with {query_params=}: {result}") if not result: - self.logger.info(f"No values for item in requested timeframe in database found.") - return default_result + self.logger.info(f" No values for item={database_item.path()} in requested timeframe between {ts_start}/{self._timestamp_to_timestring(ts_start)} and {ts_end}/{self._timestamp_to_timestring(ts_end)} in database found.") + return nodata_result return result @@ -2201,6 +2220,28 @@ def _init_cache_dicts(self) -> None: YEAR: {} } + def _clean_item_cache(self, item: Union[str, Item]) -> None: + """set cached values for item to None""" + + if isinstance(item, str): + item = self.items.return_item(item) + + if not isinstance(item, Item): + return + + database_item = self.get_item_config(item).get('database_item') + + if database_item: + for timeframe in self.previous_values: + for cached_item in self.previous_values[timeframe]: + if cached_item == database_item: + self.previous_values[timeframe][cached_item] = None + + for timeframe in self.current_values: + for cached_item in self.current_values[timeframe]: + if cached_item == database_item: + self.current_values[timeframe][cached_item] = {} + def _clear_queue(self) -> None: """ Clear working queue @@ -2209,11 +2250,108 @@ def _clear_queue(self) -> None: self.logger.info(f"Working queue will be cleared. Calculation run will end.") self.item_queue.queue.clear() + # ToDo: Check if still needed + def _queue_consumer_thread_startup(self): + """Start a thread to work item queue""" + + self.logger = logging.getLogger(__name__) + _name = 'plugins.' + self.get_fullname() + '.work_item_queue' + + try: + self.queue_consumer_thread = threading.Thread(target=self.work_item_queue, name=_name, daemon=False) + self.queue_consumer_thread.start() + self.logger.debug("Thread for 'queue_consumer_thread' has been started") + except threading.ThreadError: + self.logger.error("Unable to launch thread for 'queue_consumer_thread'.") + self.queue_consumer_thread = None + + # ToDo: Check if still needed + def _queue_consumer_thread_shutdown(self): + """Shut down the thread to work item queue""" + + if self.queue_consumer_thread: + self.queue_consumer_thread.join() + if self.queue_consumer_thread.is_alive(): + self.logger.error("Unable to shut down 'queue_consumer_thread' thread") + else: + self.logger.info("Thread 'queue_consumer_thread' has been shut down.") + self.queue_consumer_thread = None + + def _get_start_end_as_timestamp(self, timeframe: str, start: Union[int, str, None], end: Union[int, str, None]) -> tuple: + """ + Provides start and end as timestamp in microseconds from timeframe with start and end + + :param timeframe: timeframe as week, month, year + :param start: beginning timeframe in x timeframes from now + :param end: end of timeframe in x timeframes from now + + :return: start time in timestamp in microseconds, end time in timestamp in microseconds + + """ + + ts_start = ts_end = None + + def get_query_timestamp(_offset) -> int: + if timeframe == 'week': + _date = self.shtime.beginning_of_week(offset=_offset) + elif timeframe == 'month': + _date = self.shtime.beginning_of_month(offset=_offset) + elif timeframe == 'year': + _date = self.shtime.beginning_of_year(offset=_offset) + else: + _date = self.shtime.today(offset=_offset) + + return self._datetime_to_timestamp(datetime.datetime.combine(_date, datetime.datetime.min.time())) * 1000 + + if isinstance(start, str) and start.isdigit(): + start = int(start) + if isinstance(start, int): + ts_start = get_query_timestamp(-start) + + if isinstance(end, str) and end.isdigit(): + end = int(end) + if isinstance(end, int): + ts_end = get_query_timestamp(-end + 1) + + return ts_start, ts_end + + def _datetime_to_timestamp(self, dt: datetime) -> int: + """Provides timestamp from given datetime""" + + return int(dt.replace(tzinfo=self.shtime.tzinfo()).timestamp()) + + def _timestamp_to_datetime(self, timestamp: int) -> datetime: + """Parse timestamp from db query to datetime""" + + return datetime.datetime.fromtimestamp(timestamp / 1000, tz=self.shtime.tzinfo()) + + def _timestamp_to_timestring(self, timestamp: int) -> str: + """Parse timestamp from db query to string representing date and time""" + + return self._timestamp_to_datetime(timestamp).strftime('%Y-%m-%d %H:%M:%S') + + def _valid_year(self, year: Union[int, str]) -> bool: + """Check if given year is digit and within allowed range""" + + 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 + + def _valid_month(self, month: Union[int, str]) -> bool: + """Check if given month is digit and within allowed range""" + + if (isinstance(month, int) or (isinstance(month, str) and month.isdigit())) and (1 <= int(month) <= 12): + return True + else: + return False + ################################# # Database Query Preparation ################################# - def _query_log_timestamp(self, func: str, item_id: int, ts_start: int, ts_end: int, group: str = None, group2: str = None, ignore_value_list=None) -> Union[list, None]: + def _query_log_timestamp(self, func: str, item_id: int, ts_start: int, ts_end: int, group: str = "", group2: str = "", ignore_value_list=None) -> Union[list, None]: """ Assemble a mysql query str and param dict based on given parameters, get query response and return it @@ -2230,7 +2368,7 @@ def _query_log_timestamp(self, func: str, item_id: int, ts_start: int, ts_end: i """ # do debug log - if self.prepare_debug: + if self.debug_log.prepare: self.logger.debug(f"Called with {func=}, {item_id=}, {ts_start=}, {ts_end=}, {group=}, {group2=}, {ignore_value_list=}") # define query parts @@ -2254,41 +2392,31 @@ def _query_log_timestamp(self, func: str, item_id: int, ts_start: int, ts_end: i } _table_alias = { - 'avg': '', 'avg1': ') AS table1 ', - 'min': '', - 'max': '', 'max1': ') AS table1 ', - 'sum': '', - 'on': '', - 'integrate': '', 'sum_max': ') AS table1 ', 'sum_avg': ') AS table1 ', 'sum_min_neg': ') AS table1 ', 'diff_max': ') AS table1 ', - 'next': '', - 'raw': '', - 'first': '', - 'last': '', } _order = { - 'avg': 'time ASC ', - 'avg1': 'time ASC ', - 'min': 'time ASC ', - 'max': 'time ASC ', - 'max1': 'time ASC ', - 'sum': 'time ASC ', - 'on': 'time ASC ', - 'integrate': 'time ASC ', - 'sum_max': 'time ASC ', - 'sum_avg': 'time ASC ', - 'sum_min_neg': 'time ASC ', - 'diff_max': 'time ASC ', - 'next': 'time DESC LIMIT 1 ', - 'raw': 'time ASC ', - 'first': 'time ASC LIMIT 1 ', - 'last': 'time DESC LIMIT 1 ', + 'avg1': 'ORDER BY time ASC ', + 'max1': 'ORDER BY time ASC ', + 'on': 'ORDER BY time ASC ', + 'sum_max': 'ORDER BY time ASC ', + 'sum_min_neg': 'ORDER BY time ASC ', + 'diff_max': 'ORDER BY time ASC ', + 'next': 'ORDER BY time DESC ', + 'raw': 'ORDER BY time ASC ', + 'first': 'ORDER BY time ASC ', + 'last': 'ORDER BY time DESC ', + } + + _limit = { + 'next': 'LIMIT 1 ', + 'first': 'LIMIT 1 ', + '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 " @@ -2301,7 +2429,6 @@ def _query_log_timestamp(self, func: str, item_id: int, ts_start: int, ts_end: i "week": "GROUP BY YEARWEEK(FROM_UNIXTIME(time/1000), 5) ", "day": "GROUP BY DATE(FROM_UNIXTIME(time/1000)) ", "hour": "GROUP BY FROM_UNIXTIME((time/1000),'%Y%m%d%H') ", - None: "", } _group_by_sqlite = { @@ -2310,7 +2437,6 @@ def _query_log_timestamp(self, func: str, item_id: int, ts_start: int, ts_end: i "week": "GROUP BY strftime('%Y%W', date((time/1000),'unixepoch')) ", "day": "GROUP BY date((time/1000),'unixepoch') ", "hour": "GROUP BY strftime('%Y%m%d%H', datetime((time/1000),'unixepoch')) ", - None: "", } # select query parts depending in db driver @@ -2328,10 +2454,10 @@ def _query_log_timestamp(self, func: str, item_id: int, ts_start: int, ts_end: i return # check correctness of group and group2 - if group not in _group_by: + if group and group not in _group_by: self.logger.error(f"Requested {group=} for item={item_id=} not defined. Query cancelled.") return - if group2 not in _group_by: + if group2 and group2 not in _group_by: self.logger.error(f"Requested {group2=} for item={item_id=} not defined. Query cancelled.") return @@ -2348,75 +2474,62 @@ def _query_log_timestamp(self, func: str, item_id: int, ts_start: int, ts_end: i params.update({'ts_end': ts_end}) # assemble query - query = f"SELECT {_select[func]}FROM {_db_table}WHERE {_where}{_group_by[group]}ORDER BY {_order[func]}{_table_alias[func]}{_group_by[group2]}".strip() + 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() if self.db_driver.lower() == 'sqlite3': query = query.replace('IF', 'IIF') # do debug log - if self.prepare_debug: + if self.debug_log.prepare: self.logger.debug(f"{query=}, {params=}") # request database and return result return self._fetchall(query, params) - def _read_log_all(self, item_id: int): + def _read_log_oldest(self, item_id: int) -> int: """ - Read the oldest log record for given item + Read the oldest log record for given database ID - :param item_id: item_id to read the record for - :return: Log record for item_id + :param item_id: Database ID of item to read the record for + :return: timestamp of oldest log entry of given item_id """ - if self.prepare_debug: - self.logger.debug(f"called for {item_id=}") - - query = "SELECT * FROM log WHERE (item_id = :item_id) AND (time = None OR 1 = 1)" params = {'item_id': item_id} - result = self._fetchall(query, params) - return result + query = "SELECT min(time) FROM log WHERE item_id = :item_id;" + return self._fetchall(query, params)[0][0] - def _read_log_oldest(self, item_id: int, cur=None) -> int: + def _read_log_newest(self, item_id: int) -> int: """ Read the oldest log record for given database ID :param item_id: Database ID of item to read the record for - :type item_id: int - :param cur: A database cursor object if available (optional) - - :return: Log record for the database ID + :return: timestamp of newest log entry of given item_id """ params = {'item_id': item_id} - query = "SELECT min(time) FROM log WHERE item_id = :item_id;" - return self._fetchall(query, params, cur=cur)[0][0] + query = "SELECT max(time) FROM log WHERE item_id = :item_id;" + return self._fetchall(query, params)[0][0] - def _read_log_timestamp(self, item_id: int, timestamp: int, cur=None) -> Union[list, None]: + def _read_log_timestamp(self, item_id: int, timestamp: int) -> Union[list, None]: """ Read database log record for given database ID :param item_id: Database ID of item to read the record for - :type item_id: int :param timestamp: timestamp for the given value - :type timestamp: int - :param cur: A database cursor object if available (optional) - :return: Log record for the database ID at given timestamp """ params = {'item_id': item_id, 'timestamp': timestamp} query = "SELECT * FROM log WHERE item_id = :item_id AND time = :timestamp;" - return self._fetchall(query, params, cur=cur) + return self._fetchall(query, params) - def _read_item_table(self, item_id: int = None, item_path: str = None): + def _read_item_table(self, item_id: int = None, item_path: str = None) -> Union[list, None]: """ Read item table :param item_id: unique ID for item within database :param item_path: item_path for Item within the database - :return: Data for the selected item - :rtype: tuple """ columns_entries = ('id', 'name', 'time', 'val_str', 'val_num', 'val_bool', 'changed') @@ -2456,9 +2569,34 @@ def _get_db_net_read_timeout(self) -> list: query = "SHOW GLOBAL VARIABLES LIKE 'net_read_timeout'" return self._fetchone(query) - ####################### - # Database Queries - ####################### + ############################### + # Database specific stuff + ############################### + + def _initialize_db(self) -> bool: + """ + Initializes database connection + + :return: Status of initialization + """ + + try: + if not self._db.connected(): + # limit connection requests to 20 seconds. + time_since_last_connect = time.time() - self.last_connect_time + if time_since_last_connect > 20: + self.last_connect_time = time.time() + self.logger.debug(f"Connect to database.") + self._db.connect() + else: + self.logger.warning(f"Database reconnect suppressed since last connection is less then 20sec ago.") + return False + + except Exception as e: + self.logger.critical(f"Initialization of Database Connection failed: {e}") + return False + + return True def _execute(self, query: str, params: dict = None, cur=None) -> list: if params is None: @@ -2476,13 +2614,15 @@ def _fetchall(self, query: str, params: dict = None, cur=None) -> list: if params is None: params = {} - return self._query(self._db.fetchall, query, params, cur) + tuples = self._query(self._db.fetchall, query, params, cur) + return None if tuples is None else list(tuples) - def _query(self, fetch, query: str, params: dict = None, cur=None) -> Union[None, list]: + # ToDo: Check if still needed. + def _query_geht(self, fetch, query: str, params: dict = None, cur=None) -> Union[None, list]: if params is None: params = {} - if self.sql_debug: + if self.debug_log.sql: self.logger.debug(f"Called with {query=}, {params=}, {cur=}") if not self._initialize_db(): @@ -2492,26 +2632,103 @@ def _query(self, fetch, query: str, params: dict = None, cur=None) -> Union[None if self._db.verify(5) == 0: self.logger.error("Connection to database not recovered.") return None - if not self._db.lock(300): - self.logger.error("Can't query due to fail to acquire lock.") + + if self.lock_db_for_query and not self._db.lock(300): + self.logger.error("Can't query database due to fail to acquire lock.") return None query_readable = re.sub(r':([a-z_]+)', r'{\1}', query).format(**params) + # do periodic commit to get latest data during fetch + time_since_last_commit = time.time() - self.last_commit_time + if time_since_last_commit > self.refresh_cycle: + self.last_commit_time = time.time() + self.logger.debug(f"Commit to database for getting updated data. time_since_last_commit={int(time_since_last_commit)}") + self._db.commit() + + # fetch data try: tuples = fetch(query, params, cur=cur) except Exception as e: - self.logger.error(f"Error for query '{query_readable}': {e}") + self.logger.error(f"Error '{e}' for query={query_readable} occurred.") tuples = None pass finally: - if cur is None: + if cur is None and self.lock_db_for_query: self._db.release() - if self.sql_debug: - self.logger.debug(f"Result of '{query_readable}': {tuples}") + if self.debug_log.sql: + self.logger.debug(f"Result of query={query_readable}: {tuples}") + + return tuples + + def _query(self, fetch, query: str, params: dict = None, cur=None) -> Union[None, list]: + if params is None: + params = {} + + if self.debug_log.sql: + self.logger.debug(f"Called with {query=}, {params=}, {cur=}") + + # recovery connection to database + if cur is None or not self._db.connected: + verify_conn = self._db.verify(retry=5) + if verify_conn == 0: + self.logger.error("Connection to database NOT recovered.") + return None + else: + if self.debug_log.sql: + self.logger.debug("Connection to database recovered.") + + # lock database if required + if cur is None and self.lock_db_for_query: + if not self._db.lock(300): + self.logger.error("Can't query database due to fail to acquire lock.") + return None + + # fetch data + query_readable = re.sub(r':([a-z_]+)', r'{\1}', query).format(**params) + try: + tuples = fetch(query, params, cur=cur) + except Exception as e: + self.logger.error(f"Error '{e}' for query={query_readable} occurred.") + tuples = None + pass + + # release database + if cur is None and self.lock_db_for_query: + self._db.release() + + # close connection + self._db.close() + + if self.debug_log.sql: + self.logger.debug(f"Result of query={query_readable}: {tuples}") + return tuples + +@dataclass +class DebugLogOptions: + """Class to simplify use and handling of debug log options.""" + + log_level: InitVar[int] = 10 + parse: bool = True # Enable / Disable debug logging for method 'parse item' + execute: bool = True # Enable / Disable debug logging for method 'execute items' + ondemand: bool = True # Enable / Disable debug logging for method 'handle_ondemand' + onchange: bool = True # Enable / Disable debug logging for method 'handle_onchange' + prepare: bool = True # Enable / Disable debug logging for query preparation + sql: bool = True # Enable / Disable debug logging for sql stuff + + def __post_init__(self, log_level): + if log_level > 10: + self.parse = False + self.execute = False + self.ondemand = False + self.onchange = False + self.prepare = False + self.prepare = False + + ####################### # Helper functions ####################### @@ -2539,42 +2756,11 @@ def params_to_dict(string: str) -> Union[dict, None]: return None elif key in ('start', 'end', 'count') and not isinstance(res_dict[key], int): return None - elif key in 'year': - if not valid_year(res_dict[key]): - return None - elif key in 'month': - if not valid_month(res_dict[key]): - return None return res_dict -def valid_year(year: Union[int, str]) -> bool: - """Check if given year is digit and within allowed range""" - - if ((isinstance(year, int) or (isinstance(year, str) and year.isdigit())) and ( - 1980 <= int(year) <= datetime.date.today().year)) or (isinstance(year, str) and year == 'current'): - return True - else: - return False - - -def valid_month(month: Union[int, str]) -> bool: - """Check if given month is digit and within allowed range""" - - if (isinstance(month, int) or (isinstance(month, str) and month.isdigit())) and (1 <= int(month) <= 12): - return True - else: - return False - - -def timestamp_to_timestring(timestamp: int) -> str: - """Parse timestamp from db query to string representing date and time""" - - return datetime.datetime.utcfromtimestamp(timestamp / 1000).strftime('%Y-%m-%d %H:%M:%S') - - -def harmonize_timeframe_expression(timeframe: str) -> str: - """harmonizes different expression of timeframe""" +def translate_timeframe(timeframe: str) -> str: + """translates different expression of timeframe""" lookup = { 'tag': 'day', @@ -2594,7 +2780,7 @@ def harmonize_timeframe_expression(timeframe: str) -> str: return lookup.get(timeframe) -def convert_timeframe(timeframe_in: str, timeframe_out: str) -> int: +def timeframe_to_timeframe(timeframe_in: str, timeframe_out: str) -> int: """Convert timeframe to timeframe like month in years or years in days""" _h_in_d = 24 @@ -2641,104 +2827,6 @@ def convert_timeframe(timeframe_in: str, timeframe_out: str) -> int: return lookup[timeframe_in][timeframe_out] -def get_start_end_as_timestamp(timeframe: str, start: Union[int, str, None], end: Union[int, str, None]) -> tuple: - """ - Provides start and end as timestamp in microseconds from timeframe with start and end - - :param timeframe: timeframe as week, month, year - :param start: beginning timeframe in x timeframes from now - :param end: end of timeframe in x timeframes from now - - :return: start time in timestamp in microseconds, end time in timestamp in microseconds - - """ - - def get_start() -> datetime: - if timeframe == 'week': - return _week_beginning() - elif timeframe == 'month': - return _month_beginning() - elif timeframe == 'year': - return _year_beginning() - else: - return _day_beginning() - - def get_end() -> datetime: - if timeframe == 'week': - return _week_end() - elif timeframe == 'month': - return _month_end() - elif timeframe == 'year': - return _year_end() - else: - return _day_end() - - def _year_beginning(delta: int = start) -> datetime: - """provides datetime of beginning of year of today minus x years""" - - _dt = datetime.datetime.combine(datetime.date.today(), datetime.datetime.min.time()) - return _dt.replace(month=1, day=1) - relativedelta(years=delta) - - def _year_end(delta: int = end) -> datetime: - """provides datetime of end of year of today minus x years""" - - return _year_beginning(delta) + relativedelta(years=1) - - def _month_beginning(delta: int = start) -> datetime: - """provides datetime of beginning of month minus x month""" - - _dt = datetime.datetime.combine(datetime.date.today(), datetime.datetime.min.time()) - return _dt.replace(day=1) - relativedelta(months=delta) - - def _month_end(delta: int = end) -> datetime: - """provides datetime of end of month minus x month""" - - return _month_beginning(delta) + relativedelta(months=1) - - def _week_beginning(delta: int = start) -> datetime: - """provides datetime of beginning of week minus x weeks""" - - _dt = datetime.datetime.combine(datetime.date.today(), datetime.datetime.min.time()) - return _dt - relativedelta(days=(datetime.date.today().weekday() + (delta * 7))) - - def _week_end(delta: int = end) -> datetime: - """provides datetime of end of week minus x weeks""" - - return _week_beginning(delta) + relativedelta(days=7) - - def _day_beginning(delta: int = start) -> datetime: - """provides datetime of beginning of today minus x days""" - - return datetime.datetime.combine(datetime.date.today(), datetime.datetime.min.time()) - relativedelta(days=delta) - - def _day_end(delta: int = end) -> datetime: - """provides datetime of end of today minus x days""" - - return _day_beginning(delta) + relativedelta(days=1) - - if isinstance(start, str) and start.isdigit(): - start = int(start) - if isinstance(start, int): - ts_start = datetime_to_timestamp(get_start()) * 1000 - else: - ts_start = None - - if isinstance(end, str) and end.isdigit(): - end = int(end) - if isinstance(end, int): - ts_end = datetime_to_timestamp(get_end()) * 1000 - else: - ts_end = None - - return ts_start, ts_end - - -def datetime_to_timestamp(dt: datetime) -> int: - """Provides timestamp from given datetime""" - - return int(dt.replace(tzinfo=datetime.timezone.utc).timestamp()) - - def to_int(arg) -> Union[int, None]: try: return int(arg) @@ -2776,4 +2864,3 @@ def split_sting_letters_numbers(string) -> list: ALLOWED_QUERY_TIMEFRAMES = ['year', 'month', 'week', 'day', 'hour'] ALLOWED_MINMAX_FUNCS = ['min', 'max', 'avg'] - diff --git a/db_addon/item_attributes_master.py b/db_addon/item_attributes_master.py deleted file mode 100755 index 00b54a8cf..000000000 --- a/db_addon/item_attributes_master.py +++ /dev/null @@ -1,299 +0,0 @@ -# !/usr/bin/env python -# vim: set encoding=utf-8 tabstop=4 softtabstop=4 shiftwidth=4 expandtab -# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # -# Copyright 2023 Michael Wenzel -# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # -# AVM 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 . -# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # - -import ruamel.yaml - -FILENAME_ATTRIBUTES = 'item_attributes.py' - -FILENAME_PLUGIN = 'plugin.yaml' - -ITEM_ATTRIBUTES = { - 'db_addon_fct': { - 'verbrauch_heute': {'cat': 'verbrauch', 'sub_cat': 'onchange', 'item_type': 'num', 'calc': 'onchange', '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', 'calc': 'onchange', 'params': False, 'description': 'Verbrauch in der aktuellen Woche'}, - 'verbrauch_monat': {'cat': 'verbrauch', 'sub_cat': 'onchange', 'item_type': 'num', 'calc': 'onchange', 'params': False, 'description': 'Verbrauch im aktuellen Monat'}, - 'verbrauch_jahr': {'cat': 'verbrauch', 'sub_cat': 'onchange', 'item_type': 'num', 'calc': 'onchange', 'params': False, 'description': 'Verbrauch im aktuellen Jahr'}, - 'verbrauch_heute_minus1': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': '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', 'calc': 'daily', 'params': False, 'description': 'Verbrauch vorgestern (heute -2 Tage)'}, - 'verbrauch_heute_minus3': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Verbrauch heute -3 Tage'}, - 'verbrauch_heute_minus4': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Verbrauch heute -4 Tage'}, - 'verbrauch_heute_minus5': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Verbrauch heute -5 Tage'}, - 'verbrauch_heute_minus6': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Verbrauch heute -6 Tage'}, - 'verbrauch_heute_minus7': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Verbrauch heute -7 Tage'}, - 'verbrauch_woche_minus1': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'weekly', 'params': False, 'description': 'Verbrauch Vorwoche (aktuelle Woche -1)'}, - 'verbrauch_woche_minus2': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'weekly', 'params': False, 'description': 'Verbrauch aktuelle Woche -2 Wochen'}, - 'verbrauch_woche_minus3': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'weekly', 'params': False, 'description': 'Verbrauch aktuelle Woche -3 Wochen'}, - 'verbrauch_woche_minus4': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'weekly', 'params': False, 'description': 'Verbrauch aktuelle Woche -4 Wochen'}, - 'verbrauch_monat_minus1': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'monthly', 'params': False, 'description': 'Verbrauch Vormonat (aktueller Monat -1)'}, - 'verbrauch_monat_minus2': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'monthly', 'params': False, 'description': 'Verbrauch aktueller Monat -2 Monate'}, - 'verbrauch_monat_minus3': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'monthly', 'params': False, 'description': 'Verbrauch aktueller Monat -3 Monate'}, - 'verbrauch_monat_minus4': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'monthly', 'params': False, 'description': 'Verbrauch aktueller Monat -4 Monate'}, - 'verbrauch_monat_minus12': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'monthly', 'params': False, 'description': 'Verbrauch aktueller Monat -12 Monate'}, - 'verbrauch_jahr_minus1': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'yearly', 'params': False, 'description': 'Verbrauch Vorjahr (aktuelles Jahr -1 Jahr)'}, - 'verbrauch_jahr_minus2': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'yearly', 'params': False, 'description': 'Verbrauch aktuelles Jahr -2 Jahre'}, - 'verbrauch_rolling_12m_heute_minus1': {'cat': 'verbrauch', 'sub_cat': 'rolling', 'item_type': 'num', 'calc': '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', 'calc': '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', 'calc': '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', 'calc': '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', 'calc': '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', 'calc': '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', 'calc': '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', 'calc': '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', 'calc': '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', 'calc': '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', 'calc': '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', 'calc': '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', 'calc': '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', 'calc': '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', 'calc': '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', 'calc': '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', 'calc': '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', 'calc': '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', 'calc': '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', 'calc': 'daily', 'params': False, 'description': 'minimaler Wert der letzten 24h'}, - 'minmax_last_24h_max': {'cat': 'wertehistorie', 'sub_cat': 'last', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'maximaler Wert der letzten 24h'}, - 'minmax_last_24h_avg': {'cat': 'wertehistorie', 'sub_cat': 'last', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'durchschnittlicher Wert der letzten 24h'}, - 'minmax_last_7d_min': {'cat': 'wertehistorie', 'sub_cat': 'last', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'minimaler Wert der letzten 7 Tage'}, - 'minmax_last_7d_max': {'cat': 'wertehistorie', 'sub_cat': 'last', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'maximaler Wert der letzten 7 Tage'}, - 'minmax_last_7d_avg': {'cat': 'wertehistorie', 'sub_cat': 'last', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'durchschnittlicher Wert der letzten 7 Tage'}, - 'minmax_heute_min': {'cat': 'wertehistorie', 'sub_cat': 'onchange', 'item_type': 'num', 'calc': 'onchange', 'params': False, 'description': 'Minimalwert seit Tagesbeginn'}, - 'minmax_heute_max': {'cat': 'wertehistorie', 'sub_cat': 'onchange', 'item_type': 'num', 'calc': 'onchange', 'params': False, 'description': 'Maximalwert seit Tagesbeginn'}, - 'minmax_heute_avg': {'cat': 'wertehistorie', 'sub_cat': 'onchange', 'item_type': 'num', 'calc': 'onchange', 'params': False, 'description': 'Durschnittswert seit Tagesbeginn'}, - 'minmax_heute_minus1_min': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Minimalwert gestern (heute -1 Tag)'}, - 'minmax_heute_minus1_max': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Maximalwert gestern (heute -1 Tag)'}, - 'minmax_heute_minus1_avg': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Durchschnittswert gestern (heute -1 Tag)'}, - 'minmax_heute_minus2_min': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Minimalwert vorgestern (heute -2 Tage)'}, - 'minmax_heute_minus2_max': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Maximalwert vorgestern (heute -2 Tage)'}, - 'minmax_heute_minus2_avg': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Durchschnittswert vorgestern (heute -2 Tage)'}, - 'minmax_heute_minus3_min': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Minimalwert heute vor 3 Tagen'}, - 'minmax_heute_minus3_max': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Maximalwert heute vor 3 Tagen'}, - 'minmax_heute_minus3_avg': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Durchschnittswert heute vor 3 Tagen'}, - 'minmax_woche_min': {'cat': 'wertehistorie', 'sub_cat': 'onchange', 'item_type': 'num', 'calc': 'onchange', 'params': False, 'description': 'Minimalwert seit Wochenbeginn'}, - 'minmax_woche_max': {'cat': 'wertehistorie', 'sub_cat': 'onchange', 'item_type': 'num', 'calc': 'onchange', 'params': False, 'description': 'Maximalwert seit Wochenbeginn'}, - 'minmax_woche_minus1_min': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'weekly', 'params': False, 'description': 'Minimalwert Vorwoche (aktuelle Woche -1)'}, - 'minmax_woche_minus1_max': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'weekly', 'params': False, 'description': 'Maximalwert Vorwoche (aktuelle Woche -1)'}, - 'minmax_woche_minus1_avg': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'weekly', 'params': False, 'description': 'Durchschnittswert Vorwoche (aktuelle Woche -1)'}, - 'minmax_woche_minus2_min': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'weekly', 'params': False, 'description': 'Minimalwert aktuelle Woche -2 Wochen'}, - 'minmax_woche_minus2_max': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'weekly', 'params': False, 'description': 'Maximalwert aktuelle Woche -2 Wochen'}, - 'minmax_woche_minus2_avg': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'weekly', 'params': False, 'description': 'Durchschnittswert aktuelle Woche -2 Wochen'}, - 'minmax_monat_min': {'cat': 'wertehistorie', 'sub_cat': 'onchange', 'item_type': 'num', 'calc': 'onchange', 'params': False, 'description': 'Minimalwert seit Monatsbeginn'}, - 'minmax_monat_max': {'cat': 'wertehistorie', 'sub_cat': 'onchange', 'item_type': 'num', 'calc': 'onchange', 'params': False, 'description': 'Maximalwert seit Monatsbeginn'}, - 'minmax_monat_minus1_min': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'monthly', 'params': False, 'description': 'Minimalwert Vormonat (aktueller Monat -1)'}, - 'minmax_monat_minus1_max': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'monthly', 'params': False, 'description': 'Maximalwert Vormonat (aktueller Monat -1)'}, - 'minmax_monat_minus1_avg': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'monthly', 'params': False, 'description': 'Durchschnittswert Vormonat (aktueller Monat -1)'}, - 'minmax_monat_minus2_min': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'monthly', 'params': False, 'description': 'Minimalwert aktueller Monat -2 Monate'}, - 'minmax_monat_minus2_max': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'monthly', 'params': False, 'description': 'Maximalwert aktueller Monat -2 Monate'}, - 'minmax_monat_minus2_avg': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'monthly', 'params': False, 'description': 'Durchschnittswert aktueller Monat -2 Monate'}, - 'minmax_jahr_min': {'cat': 'wertehistorie', 'sub_cat': 'onchange', 'item_type': 'num', 'calc': 'onchange', 'params': False, 'description': 'Minimalwert seit Jahresbeginn'}, - 'minmax_jahr_max': {'cat': 'wertehistorie', 'sub_cat': 'onchange', 'item_type': 'num', 'calc': 'onchange', 'params': False, 'description': 'Maximalwert seit Jahresbeginn'}, - 'minmax_jahr_minus1_min': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'yearly', 'params': False, 'description': 'Minimalwert Vorjahr (aktuelles Jahr -1 Jahr)'}, - 'minmax_jahr_minus1_max': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'yearly', 'params': False, 'description': 'Maximalwert Vorjahr (aktuelles Jahr -1 Jahr)'}, - 'minmax_jahr_minus1_avg': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'yearly', 'params': False, 'description': 'Durchschnittswert Vorjahr (aktuelles Jahr -1 Jahr)'}, - 'tagesmitteltemperatur_heute': {'cat': 'tagesmittel', 'sub_cat': 'onchange', 'item_type': 'num', 'calc': 'onchange', 'params': False, 'description': 'Tagesmitteltemperatur heute'}, - 'tagesmitteltemperatur_heute_minus1': {'cat': 'tagesmittel', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Tagesmitteltemperatur des letzten Tages (heute -1 Tag)'}, - 'tagesmitteltemperatur_heute_minus2': {'cat': 'tagesmittel', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Tagesmitteltemperatur des vorletzten Tages (heute -2 Tag)'}, - 'tagesmitteltemperatur_heute_minus3': {'cat': 'tagesmittel', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Tagesmitteltemperatur des vorvorletzten Tages (heute -3 Tag)'}, - 'serie_minmax_monat_min_15m': {'cat': 'serie', 'sub_cat': 'minmax', 'item_type': 'list', 'calc': 'monthly', 'params': False, 'description': 'monatlicher Minimalwert der letzten 15 Monate (gleitend)'}, - 'serie_minmax_monat_max_15m': {'cat': 'serie', 'sub_cat': 'minmax', 'item_type': 'list', 'calc': 'monthly', 'params': False, 'description': 'monatlicher Maximalwert der letzten 15 Monate (gleitend)'}, - 'serie_minmax_monat_avg_15m': {'cat': 'serie', 'sub_cat': 'minmax', 'item_type': 'list', 'calc': 'monthly', 'params': False, 'description': 'monatlicher Mittelwert der letzten 15 Monate (gleitend)'}, - 'serie_minmax_woche_min_30w': {'cat': 'serie', 'sub_cat': 'minmax', 'item_type': 'list', 'calc': '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', 'calc': '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', 'calc': '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', 'calc': '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', 'calc': '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', 'calc': 'daily', 'params': False, 'description': 'täglicher Mittelwert der letzten 30 Tage (gleitend)'}, - 'serie_verbrauch_tag_30d': {'cat': 'serie', 'sub_cat': 'verbrauch', 'item_type': 'list', 'calc': 'daily', 'params': False, 'description': 'Verbrauch pro Tag der letzten 30 Tage'}, - 'serie_verbrauch_woche_30w': {'cat': 'serie', 'sub_cat': 'verbrauch', 'item_type': 'list', 'calc': 'weekly', 'params': False, 'description': 'Verbrauch pro Woche der letzten 30 Wochen'}, - 'serie_verbrauch_monat_18m': {'cat': 'serie', 'sub_cat': 'verbrauch', 'item_type': 'list', 'calc': 'monthly', 'params': False, 'description': 'Verbrauch pro Monat der letzten 18 Monate'}, - 'serie_zaehlerstand_tag_30d': {'cat': 'serie', 'sub_cat': 'zaehler', 'item_type': 'list', 'calc': 'daily', 'params': False, 'description': 'Zählerstand am Tagesende der letzten 30 Tage'}, - 'serie_zaehlerstand_woche_30w': {'cat': 'serie', 'sub_cat': 'zaehler', 'item_type': 'list', 'calc': 'weekly', 'params': False, 'description': 'Zählerstand am Wochenende der letzten 30 Wochen'}, - 'serie_zaehlerstand_monat_18m': {'cat': 'serie', 'sub_cat': 'zaehler', 'item_type': 'list', 'calc': 'monthly', 'params': False, 'description': 'Zählerstand am Monatsende der letzten 18 Monate'}, - 'serie_waermesumme_monat_24m': {'cat': 'serie', 'sub_cat': 'summe', 'item_type': 'list', 'calc': 'monthly', 'params': False, 'description': 'monatliche Wärmesumme der letzten 24 Monate'}, - 'serie_kaeltesumme_monat_24m': {'cat': 'serie', 'sub_cat': 'summe', 'item_type': 'list', 'calc': 'monthly', 'params': False, 'description': 'monatliche Kältesumme der letzten 24 Monate'}, - 'serie_tagesmittelwert_0d': {'cat': 'serie', 'sub_cat': 'mittel_d', 'item_type': 'list', 'calc': 'daily', 'params': False, 'description': 'Tagesmittelwert für den aktuellen Tag'}, - 'serie_tagesmittelwert_stunde_0d': {'cat': 'serie', 'sub_cat': 'mittel_h', 'item_type': 'list', 'calc': 'daily', 'params': False, 'description': 'Stundenmittelwert für den aktuellen Tag'}, - 'serie_tagesmittelwert_stunde_30_0d': {'cat': 'serie', 'sub_cat': 'mittel_h1', 'item_type': 'list', 'calc': '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', 'calc': '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', 'calc': 'no', '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', 'calc': 'no', 'params': False, 'description': 'Ausgabe des Timestamp des ältesten Eintrages des entsprechenden "Parent-Items" mit database Attribut'}, - 'kaeltesumme': {'cat': 'complex', 'sub_cat': 'summe', 'item_type': 'num', 'calc': 'daily', 'params': True, 'description': 'Berechnet die Kältesumme für einen Zeitraum, db_addon_params: (year=mandatory, month=optional)'}, - 'waermesumme': {'cat': 'complex', 'sub_cat': 'summe', 'item_type': 'num', 'calc': 'daily', 'params': True, 'description': 'Berechnet die Wärmesumme für einen Zeitraum, db_addon_params: (year=mandatory, month=optional)'}, - 'gruenlandtempsumme': {'cat': 'complex', 'sub_cat': None, 'item_type': 'num', 'calc': 'daily', 'params': True, 'description': 'Berechnet die Grünlandtemperatursumme für einen Zeitraum, db_addon_params: (year=mandatory)'}, - 'tagesmitteltemperatur': {'cat': 'complex', 'sub_cat': None, 'item_type': 'list', 'calc': '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)'}, - 'wachstumsgradtage': {'cat': 'complex', 'sub_cat': None, 'item_type': 'num', 'calc': '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)'}, - 'db_request': {'cat': 'complex', 'sub_cat': None, 'item_type': 'list', 'calc': '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', 'calc': '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', 'calc': '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', 'calc': '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', 'calc': 'timeframe', 'params': True, 'description': 'Berechnet 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', 'calc': 'no', 'params': False, 'description': 'Version der verbundenen Datenbank'}, - }, - 'db_addon_admin': { - 'suspend': {'cat': 'admin', 'item_type': 'bool', 'calc': 'no', 'params': False, 'description': 'Unterbricht die Aktivitäten des Plugin'}, - 'recalc_all': {'cat': 'admin', 'item_type': 'bool', 'calc': 'no', 'params': False, 'description': 'Startet einen Neuberechnungslauf aller on-demand Items'}, - 'clean_cache_values': {'cat': 'admin', 'item_type': 'bool', 'calc': 'no', 'params': False, 'description': 'Löscht Plugin-Cache und damit alle im Plugin zwischengespeicherten Werte'}, - }, -} - -FILE_HEADER = """\ -# !/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 -# -# -# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # - -""" - -def get_attrs(sub_dict: dict = {}) -> list: - attributes = [] - for entry in ITEM_ATTRIBUTES: - for db_addon_fct in ITEM_ATTRIBUTES[entry]: - if sub_dict.items() <= ITEM_ATTRIBUTES[entry][db_addon_fct].items(): - attributes.append(db_addon_fct) - return attributes - -def export_item_attributes_py(): - ATTRS = dict() - ATTRS['ALL_ONCHANGE_ATTRIBUTES'] = get_attrs(sub_dict={'calc': 'onchange'}) - 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['ALL_NEED_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'}) - ATTRS['VERBRAUCH_ATTRIBUTES_TIMEFRAME'] = get_attrs(sub_dict={'cat': 'verbrauch', 'sub_cat': 'timeframe'}) - ATTRS['VERBRAUCH_ATTRIBUTES_ROLLING'] = get_attrs(sub_dict={'cat': 'verbrauch', 'sub_cat': 'rolling'}) - ATTRS['VERBRAUCH_ATTRIBUTES_JAHRESZEITRAUM'] = get_attrs(sub_dict={'cat': 'verbrauch', 'sub_cat': 'jahrzeit'}) - ATTRS['ALL_ZAEHLERSTAND_ATTRIBUTES'] = get_attrs(sub_dict={'cat': 'zaehler'}) - ATTRS['ZAEHLERSTAND_ATTRIBUTES_TIMEFRAME'] = get_attrs(sub_dict={'cat': 'zaehler', 'sub_cat': 'timeframe'}) - ATTRS['ALL_HISTORIE_ATTRIBUTES'] = get_attrs(sub_dict={'cat': 'wertehistorie'}) - ATTRS['HISTORIE_ATTRIBUTES_ONCHANGE'] = get_attrs(sub_dict={'cat': 'wertehistorie', 'sub_cat': 'onchange'}) - ATTRS['HISTORIE_ATTRIBUTES_LAST'] = get_attrs(sub_dict={'cat': 'wertehistorie', 'sub_cat': 'last'}) - ATTRS['HISTORIE_ATTRIBUTES_TIMEFRAME'] = get_attrs(sub_dict={'cat': 'wertehistorie', 'sub_cat': 'timeframe'}) - ATTRS['ALL_TAGESMITTEL_ATTRIBUTES'] = get_attrs(sub_dict={'cat': 'tagesmittel'}) - ATTRS['TAGESMITTEL_ATTRIBUTES_ONCHANGE'] = get_attrs(sub_dict={'cat': 'tagesmittel', 'sub_cat': 'onchange'}) - ATTRS['TAGESMITTEL_ATTRIBUTES_TIMEFRAME'] = get_attrs(sub_dict={'cat': 'tagesmittel', 'sub_cat': 'timeframe'}) - ATTRS['ALL_SERIE_ATTRIBUTES'] = get_attrs(sub_dict={'cat': 'serie'}) - ATTRS['SERIE_ATTRIBUTES_MINMAX'] = get_attrs(sub_dict={'cat': 'serie', 'sub_cat': 'minmax'}) - ATTRS['SERIE_ATTRIBUTES_ZAEHLERSTAND'] = get_attrs(sub_dict={'cat': 'serie', 'sub_cat': 'zaehler'}) - ATTRS['SERIE_ATTRIBUTES_VERBRAUCH'] = get_attrs(sub_dict={'cat': 'serie', 'sub_cat': 'verbrauch'}) - ATTRS['SERIE_ATTRIBUTES_SUMME'] = get_attrs(sub_dict={'cat': 'serie', 'sub_cat': 'summe'}) - ATTRS['SERIE_ATTRIBUTES_MITTEL_D'] = get_attrs(sub_dict={'cat': 'serie', 'sub_cat': 'mittel_d'}) - ATTRS['SERIE_ATTRIBUTES_MITTEL_H'] = get_attrs(sub_dict={'cat': 'serie', 'sub_cat': 'mittel_h'}) - ATTRS['SERIE_ATTRIBUTES_MITTEL_H1'] = get_attrs(sub_dict={'cat': 'serie', 'sub_cat': 'mittel_h1'}) - ATTRS['SERIE_ATTRIBUTES_MITTEL_D_H'] = get_attrs(sub_dict={'cat': 'serie', 'sub_cat': 'mittel_d_h'}) - ATTRS['ALL_GEN_ATTRIBUTES'] = get_attrs(sub_dict={'cat': 'gen'}) - ATTRS['ALL_COMPLEX_ATTRIBUTES'] = get_attrs(sub_dict={'cat': 'complex'}) - - # create file and write header - f = open(FILENAME_ATTRIBUTES, "w") - f.write(FILE_HEADER) - f.close() - - # write avm_data_types - for attr, alist in ATTRS.items(): - with open(FILENAME_ATTRIBUTES, "a") as f: - print(f'{attr} = {alist!r}', file=f) - - print('item_attributes.py successfully created!') - -def create_plugin_yaml_item_attribute_valids(): - """Create valid_list of db_addon_fct based on master dict""" - - valid_list_str = """ # NOTE: valid_list is automatically created by using item_attributes_master.py""" - valid_list_desc_str = """ # NOTE: valid_list_description is automatically created by using item_attributes_master.py""" - valid_list_item_type = """ # NOTE: valid_list_item_type is automatically created by using item_attributes_master.py""" - valid_list_calculation = """ # NOTE: valid_list_calculation is automatically created by using item_attributes_master.py""" - - for db_addon_fct in ITEM_ATTRIBUTES[attribute]: - valid_list_str = f"""{valid_list_str}\n\ - - {db_addon_fct!r:<40}""" - - valid_list_desc_str = f"""{valid_list_desc_str}\n\ - - '{ITEM_ATTRIBUTES[attribute][db_addon_fct]['description']:<}'""" - - valid_list_item_type = f"""{valid_list_item_type}\n\ - - '{ITEM_ATTRIBUTES[attribute][db_addon_fct]['item_type']:<}'""" - - valid_list_calculation = f"""{valid_list_calculation}\n\ - - '{ITEM_ATTRIBUTES[attribute][db_addon_fct]['calc']:<}'""" - - valid_list_calculation = f"""{valid_list_calculation}\n\r""" - - return valid_list_str, valid_list_desc_str, valid_list_item_type, valid_list_calculation - -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""" - - yaml = ruamel.yaml.YAML() - yaml.indent(mapping=4, sequence=4, offset=4) - yaml.width = 200 - yaml.allow_unicode = True - yaml.preserve_quotes = False - - valid_list_str, valid_list_desc_str, valid_list_item_type_str, valid_list_calc_str = create_plugin_yaml_item_attribute_valids() - - with open(FILENAME_PLUGIN, 'r', encoding="utf-8") as f: - data = yaml.load(f) - - if data.get('item_attributes', {}).get(attribute): - data['item_attributes'][attribute]['valid_list'] = yaml.load(valid_list_str) - data['item_attributes'][attribute]['valid_list_description'] = yaml.load(valid_list_desc_str) - data['item_attributes'][attribute]['valid_list_item_type'] = yaml.load(valid_list_item_type_str) - data['item_attributes'][attribute]['valid_list_calculation'] = yaml.load(valid_list_calc_str) - - with open(FILENAME_PLUGIN, 'w', encoding="utf-8") as f: - yaml.dump(data, f) - print(f"Successfully updated Attribute '{attribute}' in plugin.yaml!") - else: - print(f"Attribute '{attribute}' not defined in plugin.yaml") - -if __name__ == '__main__': - export_item_attributes_py() - for attribute in ITEM_ATTRIBUTES: - update_plugin_yaml_item_attributes() diff --git a/db_addon/locale.yaml b/db_addon/locale.yaml old mode 100755 new mode 100644 diff --git a/db_addon/plugin.yaml b/db_addon/plugin.yaml old mode 100755 new mode 100644 index 98115af82..c050022f5 --- a/db_addon/plugin.yaml +++ b/db_addon/plugin.yaml @@ -11,7 +11,7 @@ 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.2 # Plugin version (must match the version specified in __init__.py) + version: 1.2.3 # 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 @@ -62,6 +62,21 @@ parameters: de: 'True: Verwendung des ältesten Eintrags des Items in der Datenbank, falls der Start des Abfragezeitraums zeitlich vor diesem Eintrag liegt False: Abbruch der Datenbankabfrage' en: 'True: Use of oldest entry of item in database, if start of query is prior to oldest entry False: Cancel query' + lock_db_for_query: + type: bool + default: false + description: + de: 'Sperren der Datenbank während der Abfrage' + en: 'Lock the database during queries' + + refresh_cycle: + type: int + default: 60 + description: + de: 'Zyklus, in dem die Datenbank neu gelesen wird' + en: 'Cycle to update database' + + item_attributes: db_addon_fct: type: str diff --git a/db_addon/requirements.txt b/db_addon/requirements.txt old mode 100755 new mode 100644 diff --git a/db_addon/user_doc.rst b/db_addon/user_doc.rst old mode 100755 new mode 100644 diff --git a/db_addon/webif/__init__.py b/db_addon/webif/__init__.py old mode 100755 new mode 100644 index 604f6b147..0bc74ca9a --- a/db_addon/webif/__init__.py +++ b/db_addon/webif/__init__.py @@ -59,7 +59,7 @@ def __init__(self, webif_dir, plugin): self.tplenv = self.init_template_environment() @cherrypy.expose - def index(self, reload=None): + def index(self, reload=None, action=None, item_path=None, active=None, option=None): """ Build index.html for cherrypy @@ -70,6 +70,19 @@ def index(self, reload=None): tmpl = self.tplenv.get_template('index.html') + if action is not None: + if action == "recalc_item" and item_path is not None: + self.logger.info(f"Recalc of item={item_path} called via WebIF. Item put to Queue for new calculation.") + self.plugin.execute_items(option='item', item=item_path) + + elif action == "clean_item_cache" and item_path is not None: + self.logger.info(f"Clean item cache of item={item_path} called via WebIF. Plugin item value cache will be cleaned.") + self.plugin._clean_item_cache(item=item_path) + + elif action == "_activate_item_calculation" and item_path is not None and active is not None: + self.logger.info(f"Item calculation of item={item_path} will be set to {bool(int(active))} via WebIF.") + self.plugin._activate_item_calculation(item=item_path, active=bool(int(active))) + return tmpl.render(p=self.plugin, webif_pagelength=self.plugin.get_parameter_value('webif_pagelength'), suspended='true' if self.plugin.suspended else 'false', @@ -78,7 +91,7 @@ def index(self, reload=None): 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 == 10 else False, + maintenance=True if self.plugin.log_level < 20 else False, ) @cherrypy.expose @@ -94,24 +107,33 @@ def get_data_html(self, dataSet=None): if dataSet is None: # get the new data data = dict() - data['items'] = {} + data['items'] = {} for item in self.plugin.get_item_list('db_addon', 'function'): - data['items'][item.id()] = {} - data['items'][item.id()]['value'] = item.property.value - data['items'][item.id()]['last_update'] = item.property.last_update.strftime('%d.%m.%Y %H:%M:%S') - data['items'][item.id()]['last_change'] = item.property.last_change.strftime('%d.%m.%Y %H:%M:%S') + data['items'][item.path()] = {} + data['items'][item.path()]['value'] = item.property.value + data['items'][item.path()]['last_update'] = item.property.last_update.strftime('%d.%m.%Y %H:%M:%S') + data['items'][item.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 + data['debug_log'] = {} + for debug in ['parse', 'execute', 'ondemand', 'onchange', 'prepare', 'sql']: + data['debug_log'][debug] = getattr(self.plugin.debug_log, debug) + try: return json.dumps(data, default=str) except Exception as e: self.logger.error(f"get_data_html exception: {e}") + @cherrypy.expose + def submit(self, cmd=None, param1=None, param2=None): + """Submit handler für Ajax""" + self.logger.warning(f"submit: {cmd=}, {param1=}, {param2=}") + @cherrypy.expose def recalc_all(self): self.logger.debug(f"recalc_all called") @@ -136,3 +158,69 @@ def activate(self): 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=}") + _state = True if state == 'true' else False + setattr(self.plugin.debug_log, log, _state) + + @cherrypy.expose + def debug_log_option_parse_true(self): + self.logger.debug("debug_log_option_parse_true") + setattr(self.plugin.debug_log, 'parse', True) + + @cherrypy.expose + def debug_log_option_parse_false (self): + self.logger.debug("debug_log_option_parse_false") + setattr(self.plugin.debug_log, 'parse', False) + + @cherrypy.expose + def debug_log_option_execute_true(self): + self.logger.debug("debug_log_option_execute_true") + setattr(self.plugin.debug_log, 'execute', True) + + @cherrypy.expose + def debug_log_option_execute_false (self): + self.logger.debug("debug_log_option_execute_false") + setattr(self.plugin.debug_log, 'execute', False) + + @cherrypy.expose + def debug_log_option_ondemand_true(self): + self.logger.debug("debug_log_option_ondemand_true") + setattr(self.plugin.debug_log, 'ondemand', True) + + @cherrypy.expose + def debug_log_option_ondemand_false (self): + self.logger.debug("debug_log_option_ondemand_false") + setattr(self.plugin.debug_log, 'ondemand', False) + + @cherrypy.expose + def debug_log_option_onchange_true(self): + self.logger.debug("debug_log_option_onchange_true") + setattr(self.plugin.debug_log, 'onchange', True) + + @cherrypy.expose + def debug_log_option_onchange_false (self): + self.logger.debug("debug_log_option_onchange_false") + setattr(self.plugin.debug_log, 'onchange', False) + + @cherrypy.expose + def debug_log_option_prepare_true(self): + self.logger.debug("debug_log_option_prepare_true") + setattr(self.plugin.debug_log, 'prepare', True) + + @cherrypy.expose + def debug_log_option_prepare_false (self): + self.logger.debug("debug_log_option_prepare_false") + setattr(self.plugin.debug_log, 'prepare', False) + + @cherrypy.expose + def debug_log_option_sql_true(self): + self.logger.debug("debug_log_option_sql_true") + setattr(self.plugin.debug_log, 'sql', True) + + @cherrypy.expose + def debug_log_option_sql_false (self): + self.logger.debug("debug_log_option_sql_false") + setattr(self.plugin.debug_log, 'sql', False) \ No newline at end of file diff --git a/db_addon/webif/static/img/plugin_logo.png b/db_addon/webif/static/img/plugin_logo.png old mode 100755 new mode 100644 diff --git a/db_addon/webif/templates/index.html b/db_addon/webif/templates/index.html old mode 100755 new mode 100644 index 62f398e70..99aeddaa5 --- a/db_addon/webif/templates/index.html +++ b/db_addon/webif/templates/index.html @@ -35,6 +35,9 @@ } table th.last { width: 150px; + } + table th.aktion { + width: 100px; } table th.dict { width: 150px; @@ -101,6 +104,13 @@ document.getElementById('pause').disabled = true; } } + + { document.getElementById('debug_parse').checked = objResponse['debug_log']['parse']; } + { document.getElementById('debug_execute').checked = objResponse['debug_log']['execute']; } + { document.getElementById('debug_ondemand').checked = objResponse['debug_log']['ondemand']; } + { document.getElementById('debug_onchange').checked = objResponse['debug_log']['onchange']; } + { document.getElementById('debug_prepare').checked = objResponse['debug_log']['prepare']; } + { document.getElementById('debug_sql').checked = objResponse['debug_log']['sql']; } } @@ -156,8 +166,13 @@ { title: '{{ _('Letzter Change') }}', targets: [8], "className": "last" + }, + { + title: '{{ _('Aktionen') }}', + targets: [9], "className": "aktion" }].concat($.fn.dataTable.defaults.columnDefs), pageResize: resize}); + {% if maintenance %} mtable2 = $('#mtable2').DataTable( { columnDefs: [ @@ -180,6 +195,8 @@ catch (e) { console.warn("Datatable JS not loaded, showing standard table without reorder option " + e); } + + // Handler für Suspend (Play/Pause) Button if ({{ suspended }} == false) { document.getElementById('play').classList = 'btn btn-success btn-sm'; document.getElementById('play').disabled = true; @@ -192,6 +209,31 @@ document.getElementById('pause').classList = 'btn btn-danger btn-sm'; document.getElementById('pause').disabled = true; } + + // Handler für Formular - das "submit"-Element (Senden) wird abgefangen + $("#button_pressed").submit(function(e) { + + // keine HTML-Aktion ausführen (z.B. Formular senden) + e.preventDefault(); + + console.log('submit') + + // die Kennung des gedrückten Buttons per AJAX senden + $.post('submit', {button: $("#button").val()}, function(data) { + + console.log(data) + + // Zeile ermitteln + // var row = $("#button").val() + // var id = row + "_value" + + // nur die betroffene Zeile ändern. Der dritte Parameter muss mit der Tabellen-ID identisch sein. + // shngInserText(id, data.wert, 'maintable') + + }); + return false ; + }); + }); @@ -206,6 +248,7 @@ } } + + + {% endblock pluginscripts %} @@ -231,7 +282,7 @@ {{ _('Verbunden') }} - {% if p._db._connected %}{{ _('Ja') }}{% else %}{{ _('Nein') }}{% endif %} + {% if p._db._connected %}{{ _('Ja') }}{% else %}{{ _('Nein') }}{% endif %} {{ _('Treiber') }} {{ p.db_driver }} {{ _('Startup Delay') }} @@ -255,10 +306,35 @@ {% endif %} {% endfor %} - {{ _('Item in Berechnung') }} + {{ _('Item in Berechnung') }} {{ p.active_queue_item }} - {{ _('Arbeitsvorrat') }} - {{ p.queue_backlog }} {{ _('Items') }} + {{ _('Arbeitsvorrat') }} + {{ p.queue_backlog }} {{ _('Items') }} + {{ _('LogLevel') }} + + {{ p.log_level }} + {% if p.log_level == 10 %} + {{ (' || ') }} +
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+ {% endif %} + @@ -282,11 +358,7 @@ {% set tabcount = 3 %} {% set tab1title = "" ~ plugin_shortname ~ " Items (" ~ item_count ~ ")" %} -{% if maintenance %} - {% set tab2title = "" ~ plugin_shortname ~ " Maintenance" %} -{% else %} - {% set tab2title = "hidden" %} -{% endif %} +{% set tab2title = "" ~ plugin_shortname ~ " Maintenance" %} {% set tab3title = "" ~ plugin_shortname ~ " API/Doku" %} @@ -312,10 +384,31 @@ {{ item._value | float | round(2) }} {{ item.property.last_update.strftime('%d.%m.%Y %H:%M:%S') }} {{ item.property.last_change.strftime('%d.%m.%Y %H:%M:%S') }} + + + + {% if p.get_item_config(item._path)['active'] %} + + {% else %} + + {% endif %} + + + {% endfor %} +
+ +
{% endblock bodytab1 %} From 22dc7e8210ac74ec753e53f0ee18c7491c35b3a5 Mon Sep 17 00:00:00 2001 From: sisamiwe Date: Mon, 7 Aug 2023 11:48:39 +0200 Subject: [PATCH 02/18] DB_ADDON: - use commit, to always fetches latest entries - internal improvements --- db_addon/__init__.py | 45 +++++++++++++------------ db_addon/plugin.yaml | 8 ----- db_addon/webif/__init__.py | 20 +++++++++-- db_addon/webif/templates/index.html | 51 +++++++++++++++++++---------- 4 files changed, 73 insertions(+), 51 deletions(-) diff --git a/db_addon/__init__.py b/db_addon/__init__.py index 02c521b7a..d254064f2 100644 --- a/db_addon/__init__.py +++ b/db_addon/__init__.py @@ -57,7 +57,8 @@ class DatabaseAddOn(SmartPlugin): """ PLUGIN_VERSION = '1.2.3' - REVISION = 'C' + # ToDo: remove revision + REVISION = 'D' def __init__(self, sh): """ @@ -88,8 +89,6 @@ def __init__(self, sh): self.db_instance = None # instance of the used database self.item_attribute_search_str = 'database' # attribute, on which an item configured for database can be identified self.last_connect_time = 0 # mechanism for limiting db connection requests - # ToDo: Check if still needed - self.last_commit_time = 0 self.alive = None # Is plugin alive? self.startup_finished = False # Startup of Plugin finished self.suspended = False # Is plugin activity suspended @@ -107,8 +106,6 @@ def __init__(self, sh): self.optimize_value_filter = self.get_parameter_value('optimize_value_filter') self.use_oldest_entry = self.get_parameter_value('use_oldest_entry') self.lock_db_for_query = self.get_parameter_value('lock_db_for_query') - # ToDo: Check if still needed - self.refresh_cycle = self.get_parameter_value('refresh_cycle') # get debug log options self.debug_log = DebugLogOptions(self.log_level) @@ -265,7 +262,6 @@ def get_query_parameters_from_db_addon_fct() -> Union[dict, None]: required_params = [timeframe, start, end] elif db_addon_fct in VERBRAUCH_ATTRIBUTES_ROLLING: - # ToDo: check if rolling window correct; muss start und ende dynamisch berechnet werden? # 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]) @@ -2339,7 +2335,8 @@ def _valid_year(self, year: Union[int, str]) -> bool: else: return False - def _valid_month(self, month: Union[int, str]) -> bool: + @staticmethod + def _valid_month(month: Union[int, str]) -> bool: """Check if given month is digit and within allowed range""" if (isinstance(month, int) or (isinstance(month, str) and month.isdigit())) and (1 <= int(month) <= 12): @@ -2618,7 +2615,9 @@ def _fetchall(self, query: str, params: dict = None, cur=None) -> list: return None if tuples is None else list(tuples) # ToDo: Check if still needed. - def _query_geht(self, fetch, query: str, params: dict = None, cur=None) -> Union[None, list]: + def _query(self, fetch, query: str, params: dict = None, cur=None) -> Union[None, list]: + """query using commit to get latest data from db""" + if params is None: params = {} @@ -2629,22 +2628,19 @@ def _query_geht(self, fetch, query: str, params: dict = None, cur=None) -> Union return None if cur is None: - if self._db.verify(5) == 0: - self.logger.error("Connection to database not recovered.") + verify_conn = self._db.verify(retry=5) + if verify_conn == 0: + self.logger.error("Connection to database NOT recovered.") return None - if self.lock_db_for_query and not self._db.lock(300): - self.logger.error("Can't query database due to fail to acquire lock.") - return None + if self.lock_db_for_query and not self._db.lock(300): + self.logger.error("Can't query database due to fail to acquire lock.") + return None query_readable = re.sub(r':([a-z_]+)', r'{\1}', query).format(**params) - # do periodic commit to get latest data during fetch - time_since_last_commit = time.time() - self.last_commit_time - if time_since_last_commit > self.refresh_cycle: - self.last_commit_time = time.time() - self.logger.debug(f"Commit to database for getting updated data. time_since_last_commit={int(time_since_last_commit)}") - self._db.commit() + # do commit to get latest data during fetch + self._db.commit() # fetch data try: @@ -2653,16 +2649,19 @@ def _query_geht(self, fetch, query: str, params: dict = None, cur=None) -> Union self.logger.error(f"Error '{e}' for query={query_readable} occurred.") tuples = None pass - finally: - if cur is None and self.lock_db_for_query: - self._db.release() + + if cur is None and self.lock_db_for_query: + self._db.release() if self.debug_log.sql: self.logger.debug(f"Result of query={query_readable}: {tuples}") return tuples - def _query(self, fetch, query: str, params: dict = None, cur=None) -> Union[None, list]: + # ToDo: Check if still needed. + def _query_geht_gut(self, fetch, query: str, params: dict = None, cur=None) -> Union[None, list]: + """query open and close connection for each query to get latest data from db""" + if params is None: params = {} diff --git a/db_addon/plugin.yaml b/db_addon/plugin.yaml index c050022f5..84e5ad089 100644 --- a/db_addon/plugin.yaml +++ b/db_addon/plugin.yaml @@ -69,14 +69,6 @@ parameters: de: 'Sperren der Datenbank während der Abfrage' en: 'Lock the database during queries' - refresh_cycle: - type: int - default: 60 - description: - de: 'Zyklus, in dem die Datenbank neu gelesen wird' - en: 'Cycle to update database' - - item_attributes: db_addon_fct: type: str diff --git a/db_addon/webif/__init__.py b/db_addon/webif/__init__.py index 0bc74ca9a..d1fca7eba 100644 --- a/db_addon/webif/__init__.py +++ b/db_addon/webif/__init__.py @@ -130,9 +130,23 @@ def get_data_html(self, dataSet=None): self.logger.error(f"get_data_html exception: {e}") @cherrypy.expose - def submit(self, cmd=None, param1=None, param2=None): - """Submit handler für Ajax""" - self.logger.warning(f"submit: {cmd=}, {param1=}, {param2=}") + def submit(self, param1=None): + ''' + Submit handler für Ajax + ''' + result = None + + self.logger.warning(f'{param1}') + + if param1 is not None: + + # verarbeite die Daten + self.logger.warning(f'{param1}') + + if result_dict is not None: + # JSON zurücksenden + cherrypy.response.headers['Content-Type'] = 'application/json' + return json.dumps(result_dict).encode('utf-8') @cherrypy.expose def recalc_all(self): diff --git a/db_addon/webif/templates/index.html b/db_addon/webif/templates/index.html index 99aeddaa5..1b0af72cc 100644 --- a/db_addon/webif/templates/index.html +++ b/db_addon/webif/templates/index.html @@ -210,29 +210,47 @@ document.getElementById('pause').disabled = true; } - // Handler für Formular - das "submit"-Element (Senden) wird abgefangen - $("#button_pressed").submit(function(e) { + // Handler für einfachen Button - das "click"-Element wird abgefangen + $("#clear").click(function(e) { - // keine HTML-Aktion ausführen (z.B. Formular senden) - e.preventDefault(); + // keine HTML-Aktion ausführen (z.B. Formular senden) + e.preventDefault(); - console.log('submit') + // festen Wert per AJAX senden + $.post('submit', {clear: "true"}, function(data) { - // die Kennung des gedrückten Buttons per AJAX senden - $.post('submit', {button: $("#button").val()}, function(data) { + // Ergebnis in Feld #fromip schreiben. Der dritte Parameter muss mit der Tabellen-ID identisch sein. + shngInsertText('fromip', data.ip, 'maintable') + }); + return false ; + }); + + // Handler für Formular - das "submit"-Element (Senden) wird abgefangen + $("#button_pressed").submit(function(e) { + + // keine HTML-Aktion ausführen (z.B. Formular senden) + e.preventDefault(); - console.log(data) + // die Kennung des gedrückten Buttons per AJAX senden + $.post('submit', {button: $("#button").val()}, function(data) { - // Zeile ermitteln - // var row = $("#button").val() - // var id = row + "_value" + // Zeile ermitteln + var row = $("#button").val() + var id = row + "_value" + + console.log(row) - // nur die betroffene Zeile ändern. Der dritte Parameter muss mit der Tabellen-ID identisch sein. - // shngInserText(id, data.wert, 'maintable') + // nur die betroffene Zeile ändern. Der dritte Parameter muss mit der Tabellen-ID identisch sein. + shngInserText(id, data.wert, 'maintable') + // alternativ kann auch ein ganzes Feld übertragen werden... + for (var row in data) { + shngInsertText(row + "_value", data.row.wert, 'maintable') + } + }); + return false ; }); - return false ; - }); + }); @@ -277,7 +295,6 @@ {% block headtable %} - @@ -397,7 +414,7 @@ class="btn-sm btn-secondary" type="button" title="{{ 'TestButton' }}" - onclick="$('#button').val('{{ item.property.path }}');$('#button_pressed').submit();" + onclick="$('#button').val('{{ item }}');$('#button_pressed').submit();" > T From 94d592735ec4d7decc2eac1e44c85c2ceef5eaf8 Mon Sep 17 00:00:00 2001 From: sisamiwe Date: Mon, 7 Aug 2023 11:52:11 +0200 Subject: [PATCH 03/18] DB_ADDON: - add item_attributes_master.py --- db_addon/item_attributes_master.py | 299 +++++++++++++++++++++++++++++ 1 file changed, 299 insertions(+) create mode 100644 db_addon/item_attributes_master.py diff --git a/db_addon/item_attributes_master.py b/db_addon/item_attributes_master.py new file mode 100644 index 000000000..00b54a8cf --- /dev/null +++ b/db_addon/item_attributes_master.py @@ -0,0 +1,299 @@ +# !/usr/bin/env python +# vim: set encoding=utf-8 tabstop=4 softtabstop=4 shiftwidth=4 expandtab +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +# Copyright 2023 Michael Wenzel +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +# AVM 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 . +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + +import ruamel.yaml + +FILENAME_ATTRIBUTES = 'item_attributes.py' + +FILENAME_PLUGIN = 'plugin.yaml' + +ITEM_ATTRIBUTES = { + 'db_addon_fct': { + 'verbrauch_heute': {'cat': 'verbrauch', 'sub_cat': 'onchange', 'item_type': 'num', 'calc': 'onchange', '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', 'calc': 'onchange', 'params': False, 'description': 'Verbrauch in der aktuellen Woche'}, + 'verbrauch_monat': {'cat': 'verbrauch', 'sub_cat': 'onchange', 'item_type': 'num', 'calc': 'onchange', 'params': False, 'description': 'Verbrauch im aktuellen Monat'}, + 'verbrauch_jahr': {'cat': 'verbrauch', 'sub_cat': 'onchange', 'item_type': 'num', 'calc': 'onchange', 'params': False, 'description': 'Verbrauch im aktuellen Jahr'}, + 'verbrauch_heute_minus1': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': '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', 'calc': 'daily', 'params': False, 'description': 'Verbrauch vorgestern (heute -2 Tage)'}, + 'verbrauch_heute_minus3': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Verbrauch heute -3 Tage'}, + 'verbrauch_heute_minus4': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Verbrauch heute -4 Tage'}, + 'verbrauch_heute_minus5': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Verbrauch heute -5 Tage'}, + 'verbrauch_heute_minus6': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Verbrauch heute -6 Tage'}, + 'verbrauch_heute_minus7': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Verbrauch heute -7 Tage'}, + 'verbrauch_woche_minus1': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'weekly', 'params': False, 'description': 'Verbrauch Vorwoche (aktuelle Woche -1)'}, + 'verbrauch_woche_minus2': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'weekly', 'params': False, 'description': 'Verbrauch aktuelle Woche -2 Wochen'}, + 'verbrauch_woche_minus3': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'weekly', 'params': False, 'description': 'Verbrauch aktuelle Woche -3 Wochen'}, + 'verbrauch_woche_minus4': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'weekly', 'params': False, 'description': 'Verbrauch aktuelle Woche -4 Wochen'}, + 'verbrauch_monat_minus1': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'monthly', 'params': False, 'description': 'Verbrauch Vormonat (aktueller Monat -1)'}, + 'verbrauch_monat_minus2': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'monthly', 'params': False, 'description': 'Verbrauch aktueller Monat -2 Monate'}, + 'verbrauch_monat_minus3': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'monthly', 'params': False, 'description': 'Verbrauch aktueller Monat -3 Monate'}, + 'verbrauch_monat_minus4': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'monthly', 'params': False, 'description': 'Verbrauch aktueller Monat -4 Monate'}, + 'verbrauch_monat_minus12': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'monthly', 'params': False, 'description': 'Verbrauch aktueller Monat -12 Monate'}, + 'verbrauch_jahr_minus1': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'yearly', 'params': False, 'description': 'Verbrauch Vorjahr (aktuelles Jahr -1 Jahr)'}, + 'verbrauch_jahr_minus2': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'yearly', 'params': False, 'description': 'Verbrauch aktuelles Jahr -2 Jahre'}, + 'verbrauch_rolling_12m_heute_minus1': {'cat': 'verbrauch', 'sub_cat': 'rolling', 'item_type': 'num', 'calc': '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', 'calc': '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', 'calc': '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', 'calc': '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', 'calc': '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', 'calc': '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', 'calc': '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', 'calc': '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', 'calc': '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', 'calc': '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', 'calc': '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', 'calc': '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', 'calc': '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', 'calc': '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', 'calc': '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', 'calc': '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', 'calc': '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', 'calc': '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', 'calc': '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', 'calc': 'daily', 'params': False, 'description': 'minimaler Wert der letzten 24h'}, + 'minmax_last_24h_max': {'cat': 'wertehistorie', 'sub_cat': 'last', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'maximaler Wert der letzten 24h'}, + 'minmax_last_24h_avg': {'cat': 'wertehistorie', 'sub_cat': 'last', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'durchschnittlicher Wert der letzten 24h'}, + 'minmax_last_7d_min': {'cat': 'wertehistorie', 'sub_cat': 'last', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'minimaler Wert der letzten 7 Tage'}, + 'minmax_last_7d_max': {'cat': 'wertehistorie', 'sub_cat': 'last', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'maximaler Wert der letzten 7 Tage'}, + 'minmax_last_7d_avg': {'cat': 'wertehistorie', 'sub_cat': 'last', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'durchschnittlicher Wert der letzten 7 Tage'}, + 'minmax_heute_min': {'cat': 'wertehistorie', 'sub_cat': 'onchange', 'item_type': 'num', 'calc': 'onchange', 'params': False, 'description': 'Minimalwert seit Tagesbeginn'}, + 'minmax_heute_max': {'cat': 'wertehistorie', 'sub_cat': 'onchange', 'item_type': 'num', 'calc': 'onchange', 'params': False, 'description': 'Maximalwert seit Tagesbeginn'}, + 'minmax_heute_avg': {'cat': 'wertehistorie', 'sub_cat': 'onchange', 'item_type': 'num', 'calc': 'onchange', 'params': False, 'description': 'Durschnittswert seit Tagesbeginn'}, + 'minmax_heute_minus1_min': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Minimalwert gestern (heute -1 Tag)'}, + 'minmax_heute_minus1_max': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Maximalwert gestern (heute -1 Tag)'}, + 'minmax_heute_minus1_avg': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Durchschnittswert gestern (heute -1 Tag)'}, + 'minmax_heute_minus2_min': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Minimalwert vorgestern (heute -2 Tage)'}, + 'minmax_heute_minus2_max': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Maximalwert vorgestern (heute -2 Tage)'}, + 'minmax_heute_minus2_avg': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Durchschnittswert vorgestern (heute -2 Tage)'}, + 'minmax_heute_minus3_min': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Minimalwert heute vor 3 Tagen'}, + 'minmax_heute_minus3_max': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Maximalwert heute vor 3 Tagen'}, + 'minmax_heute_minus3_avg': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Durchschnittswert heute vor 3 Tagen'}, + 'minmax_woche_min': {'cat': 'wertehistorie', 'sub_cat': 'onchange', 'item_type': 'num', 'calc': 'onchange', 'params': False, 'description': 'Minimalwert seit Wochenbeginn'}, + 'minmax_woche_max': {'cat': 'wertehistorie', 'sub_cat': 'onchange', 'item_type': 'num', 'calc': 'onchange', 'params': False, 'description': 'Maximalwert seit Wochenbeginn'}, + 'minmax_woche_minus1_min': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'weekly', 'params': False, 'description': 'Minimalwert Vorwoche (aktuelle Woche -1)'}, + 'minmax_woche_minus1_max': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'weekly', 'params': False, 'description': 'Maximalwert Vorwoche (aktuelle Woche -1)'}, + 'minmax_woche_minus1_avg': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'weekly', 'params': False, 'description': 'Durchschnittswert Vorwoche (aktuelle Woche -1)'}, + 'minmax_woche_minus2_min': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'weekly', 'params': False, 'description': 'Minimalwert aktuelle Woche -2 Wochen'}, + 'minmax_woche_minus2_max': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'weekly', 'params': False, 'description': 'Maximalwert aktuelle Woche -2 Wochen'}, + 'minmax_woche_minus2_avg': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'weekly', 'params': False, 'description': 'Durchschnittswert aktuelle Woche -2 Wochen'}, + 'minmax_monat_min': {'cat': 'wertehistorie', 'sub_cat': 'onchange', 'item_type': 'num', 'calc': 'onchange', 'params': False, 'description': 'Minimalwert seit Monatsbeginn'}, + 'minmax_monat_max': {'cat': 'wertehistorie', 'sub_cat': 'onchange', 'item_type': 'num', 'calc': 'onchange', 'params': False, 'description': 'Maximalwert seit Monatsbeginn'}, + 'minmax_monat_minus1_min': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'monthly', 'params': False, 'description': 'Minimalwert Vormonat (aktueller Monat -1)'}, + 'minmax_monat_minus1_max': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'monthly', 'params': False, 'description': 'Maximalwert Vormonat (aktueller Monat -1)'}, + 'minmax_monat_minus1_avg': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'monthly', 'params': False, 'description': 'Durchschnittswert Vormonat (aktueller Monat -1)'}, + 'minmax_monat_minus2_min': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'monthly', 'params': False, 'description': 'Minimalwert aktueller Monat -2 Monate'}, + 'minmax_monat_minus2_max': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'monthly', 'params': False, 'description': 'Maximalwert aktueller Monat -2 Monate'}, + 'minmax_monat_minus2_avg': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'monthly', 'params': False, 'description': 'Durchschnittswert aktueller Monat -2 Monate'}, + 'minmax_jahr_min': {'cat': 'wertehistorie', 'sub_cat': 'onchange', 'item_type': 'num', 'calc': 'onchange', 'params': False, 'description': 'Minimalwert seit Jahresbeginn'}, + 'minmax_jahr_max': {'cat': 'wertehistorie', 'sub_cat': 'onchange', 'item_type': 'num', 'calc': 'onchange', 'params': False, 'description': 'Maximalwert seit Jahresbeginn'}, + 'minmax_jahr_minus1_min': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'yearly', 'params': False, 'description': 'Minimalwert Vorjahr (aktuelles Jahr -1 Jahr)'}, + 'minmax_jahr_minus1_max': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'yearly', 'params': False, 'description': 'Maximalwert Vorjahr (aktuelles Jahr -1 Jahr)'}, + 'minmax_jahr_minus1_avg': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'yearly', 'params': False, 'description': 'Durchschnittswert Vorjahr (aktuelles Jahr -1 Jahr)'}, + 'tagesmitteltemperatur_heute': {'cat': 'tagesmittel', 'sub_cat': 'onchange', 'item_type': 'num', 'calc': 'onchange', 'params': False, 'description': 'Tagesmitteltemperatur heute'}, + 'tagesmitteltemperatur_heute_minus1': {'cat': 'tagesmittel', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Tagesmitteltemperatur des letzten Tages (heute -1 Tag)'}, + 'tagesmitteltemperatur_heute_minus2': {'cat': 'tagesmittel', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Tagesmitteltemperatur des vorletzten Tages (heute -2 Tag)'}, + 'tagesmitteltemperatur_heute_minus3': {'cat': 'tagesmittel', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Tagesmitteltemperatur des vorvorletzten Tages (heute -3 Tag)'}, + 'serie_minmax_monat_min_15m': {'cat': 'serie', 'sub_cat': 'minmax', 'item_type': 'list', 'calc': 'monthly', 'params': False, 'description': 'monatlicher Minimalwert der letzten 15 Monate (gleitend)'}, + 'serie_minmax_monat_max_15m': {'cat': 'serie', 'sub_cat': 'minmax', 'item_type': 'list', 'calc': 'monthly', 'params': False, 'description': 'monatlicher Maximalwert der letzten 15 Monate (gleitend)'}, + 'serie_minmax_monat_avg_15m': {'cat': 'serie', 'sub_cat': 'minmax', 'item_type': 'list', 'calc': 'monthly', 'params': False, 'description': 'monatlicher Mittelwert der letzten 15 Monate (gleitend)'}, + 'serie_minmax_woche_min_30w': {'cat': 'serie', 'sub_cat': 'minmax', 'item_type': 'list', 'calc': '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', 'calc': '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', 'calc': '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', 'calc': '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', 'calc': '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', 'calc': 'daily', 'params': False, 'description': 'täglicher Mittelwert der letzten 30 Tage (gleitend)'}, + 'serie_verbrauch_tag_30d': {'cat': 'serie', 'sub_cat': 'verbrauch', 'item_type': 'list', 'calc': 'daily', 'params': False, 'description': 'Verbrauch pro Tag der letzten 30 Tage'}, + 'serie_verbrauch_woche_30w': {'cat': 'serie', 'sub_cat': 'verbrauch', 'item_type': 'list', 'calc': 'weekly', 'params': False, 'description': 'Verbrauch pro Woche der letzten 30 Wochen'}, + 'serie_verbrauch_monat_18m': {'cat': 'serie', 'sub_cat': 'verbrauch', 'item_type': 'list', 'calc': 'monthly', 'params': False, 'description': 'Verbrauch pro Monat der letzten 18 Monate'}, + 'serie_zaehlerstand_tag_30d': {'cat': 'serie', 'sub_cat': 'zaehler', 'item_type': 'list', 'calc': 'daily', 'params': False, 'description': 'Zählerstand am Tagesende der letzten 30 Tage'}, + 'serie_zaehlerstand_woche_30w': {'cat': 'serie', 'sub_cat': 'zaehler', 'item_type': 'list', 'calc': 'weekly', 'params': False, 'description': 'Zählerstand am Wochenende der letzten 30 Wochen'}, + 'serie_zaehlerstand_monat_18m': {'cat': 'serie', 'sub_cat': 'zaehler', 'item_type': 'list', 'calc': 'monthly', 'params': False, 'description': 'Zählerstand am Monatsende der letzten 18 Monate'}, + 'serie_waermesumme_monat_24m': {'cat': 'serie', 'sub_cat': 'summe', 'item_type': 'list', 'calc': 'monthly', 'params': False, 'description': 'monatliche Wärmesumme der letzten 24 Monate'}, + 'serie_kaeltesumme_monat_24m': {'cat': 'serie', 'sub_cat': 'summe', 'item_type': 'list', 'calc': 'monthly', 'params': False, 'description': 'monatliche Kältesumme der letzten 24 Monate'}, + 'serie_tagesmittelwert_0d': {'cat': 'serie', 'sub_cat': 'mittel_d', 'item_type': 'list', 'calc': 'daily', 'params': False, 'description': 'Tagesmittelwert für den aktuellen Tag'}, + 'serie_tagesmittelwert_stunde_0d': {'cat': 'serie', 'sub_cat': 'mittel_h', 'item_type': 'list', 'calc': 'daily', 'params': False, 'description': 'Stundenmittelwert für den aktuellen Tag'}, + 'serie_tagesmittelwert_stunde_30_0d': {'cat': 'serie', 'sub_cat': 'mittel_h1', 'item_type': 'list', 'calc': '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', 'calc': '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', 'calc': 'no', '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', 'calc': 'no', 'params': False, 'description': 'Ausgabe des Timestamp des ältesten Eintrages des entsprechenden "Parent-Items" mit database Attribut'}, + 'kaeltesumme': {'cat': 'complex', 'sub_cat': 'summe', 'item_type': 'num', 'calc': 'daily', 'params': True, 'description': 'Berechnet die Kältesumme für einen Zeitraum, db_addon_params: (year=mandatory, month=optional)'}, + 'waermesumme': {'cat': 'complex', 'sub_cat': 'summe', 'item_type': 'num', 'calc': 'daily', 'params': True, 'description': 'Berechnet die Wärmesumme für einen Zeitraum, db_addon_params: (year=mandatory, month=optional)'}, + 'gruenlandtempsumme': {'cat': 'complex', 'sub_cat': None, 'item_type': 'num', 'calc': 'daily', 'params': True, 'description': 'Berechnet die Grünlandtemperatursumme für einen Zeitraum, db_addon_params: (year=mandatory)'}, + 'tagesmitteltemperatur': {'cat': 'complex', 'sub_cat': None, 'item_type': 'list', 'calc': '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)'}, + 'wachstumsgradtage': {'cat': 'complex', 'sub_cat': None, 'item_type': 'num', 'calc': '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)'}, + 'db_request': {'cat': 'complex', 'sub_cat': None, 'item_type': 'list', 'calc': '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', 'calc': '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', 'calc': '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', 'calc': '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', 'calc': 'timeframe', 'params': True, 'description': 'Berechnet 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', 'calc': 'no', 'params': False, 'description': 'Version der verbundenen Datenbank'}, + }, + 'db_addon_admin': { + 'suspend': {'cat': 'admin', 'item_type': 'bool', 'calc': 'no', 'params': False, 'description': 'Unterbricht die Aktivitäten des Plugin'}, + 'recalc_all': {'cat': 'admin', 'item_type': 'bool', 'calc': 'no', 'params': False, 'description': 'Startet einen Neuberechnungslauf aller on-demand Items'}, + 'clean_cache_values': {'cat': 'admin', 'item_type': 'bool', 'calc': 'no', 'params': False, 'description': 'Löscht Plugin-Cache und damit alle im Plugin zwischengespeicherten Werte'}, + }, +} + +FILE_HEADER = """\ +# !/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 +# +# +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + +""" + +def get_attrs(sub_dict: dict = {}) -> list: + attributes = [] + for entry in ITEM_ATTRIBUTES: + for db_addon_fct in ITEM_ATTRIBUTES[entry]: + if sub_dict.items() <= ITEM_ATTRIBUTES[entry][db_addon_fct].items(): + attributes.append(db_addon_fct) + return attributes + +def export_item_attributes_py(): + ATTRS = dict() + ATTRS['ALL_ONCHANGE_ATTRIBUTES'] = get_attrs(sub_dict={'calc': 'onchange'}) + 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['ALL_NEED_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'}) + ATTRS['VERBRAUCH_ATTRIBUTES_TIMEFRAME'] = get_attrs(sub_dict={'cat': 'verbrauch', 'sub_cat': 'timeframe'}) + ATTRS['VERBRAUCH_ATTRIBUTES_ROLLING'] = get_attrs(sub_dict={'cat': 'verbrauch', 'sub_cat': 'rolling'}) + ATTRS['VERBRAUCH_ATTRIBUTES_JAHRESZEITRAUM'] = get_attrs(sub_dict={'cat': 'verbrauch', 'sub_cat': 'jahrzeit'}) + ATTRS['ALL_ZAEHLERSTAND_ATTRIBUTES'] = get_attrs(sub_dict={'cat': 'zaehler'}) + ATTRS['ZAEHLERSTAND_ATTRIBUTES_TIMEFRAME'] = get_attrs(sub_dict={'cat': 'zaehler', 'sub_cat': 'timeframe'}) + ATTRS['ALL_HISTORIE_ATTRIBUTES'] = get_attrs(sub_dict={'cat': 'wertehistorie'}) + ATTRS['HISTORIE_ATTRIBUTES_ONCHANGE'] = get_attrs(sub_dict={'cat': 'wertehistorie', 'sub_cat': 'onchange'}) + ATTRS['HISTORIE_ATTRIBUTES_LAST'] = get_attrs(sub_dict={'cat': 'wertehistorie', 'sub_cat': 'last'}) + ATTRS['HISTORIE_ATTRIBUTES_TIMEFRAME'] = get_attrs(sub_dict={'cat': 'wertehistorie', 'sub_cat': 'timeframe'}) + ATTRS['ALL_TAGESMITTEL_ATTRIBUTES'] = get_attrs(sub_dict={'cat': 'tagesmittel'}) + ATTRS['TAGESMITTEL_ATTRIBUTES_ONCHANGE'] = get_attrs(sub_dict={'cat': 'tagesmittel', 'sub_cat': 'onchange'}) + ATTRS['TAGESMITTEL_ATTRIBUTES_TIMEFRAME'] = get_attrs(sub_dict={'cat': 'tagesmittel', 'sub_cat': 'timeframe'}) + ATTRS['ALL_SERIE_ATTRIBUTES'] = get_attrs(sub_dict={'cat': 'serie'}) + ATTRS['SERIE_ATTRIBUTES_MINMAX'] = get_attrs(sub_dict={'cat': 'serie', 'sub_cat': 'minmax'}) + ATTRS['SERIE_ATTRIBUTES_ZAEHLERSTAND'] = get_attrs(sub_dict={'cat': 'serie', 'sub_cat': 'zaehler'}) + ATTRS['SERIE_ATTRIBUTES_VERBRAUCH'] = get_attrs(sub_dict={'cat': 'serie', 'sub_cat': 'verbrauch'}) + ATTRS['SERIE_ATTRIBUTES_SUMME'] = get_attrs(sub_dict={'cat': 'serie', 'sub_cat': 'summe'}) + ATTRS['SERIE_ATTRIBUTES_MITTEL_D'] = get_attrs(sub_dict={'cat': 'serie', 'sub_cat': 'mittel_d'}) + ATTRS['SERIE_ATTRIBUTES_MITTEL_H'] = get_attrs(sub_dict={'cat': 'serie', 'sub_cat': 'mittel_h'}) + ATTRS['SERIE_ATTRIBUTES_MITTEL_H1'] = get_attrs(sub_dict={'cat': 'serie', 'sub_cat': 'mittel_h1'}) + ATTRS['SERIE_ATTRIBUTES_MITTEL_D_H'] = get_attrs(sub_dict={'cat': 'serie', 'sub_cat': 'mittel_d_h'}) + ATTRS['ALL_GEN_ATTRIBUTES'] = get_attrs(sub_dict={'cat': 'gen'}) + ATTRS['ALL_COMPLEX_ATTRIBUTES'] = get_attrs(sub_dict={'cat': 'complex'}) + + # create file and write header + f = open(FILENAME_ATTRIBUTES, "w") + f.write(FILE_HEADER) + f.close() + + # write avm_data_types + for attr, alist in ATTRS.items(): + with open(FILENAME_ATTRIBUTES, "a") as f: + print(f'{attr} = {alist!r}', file=f) + + print('item_attributes.py successfully created!') + +def create_plugin_yaml_item_attribute_valids(): + """Create valid_list of db_addon_fct based on master dict""" + + valid_list_str = """ # NOTE: valid_list is automatically created by using item_attributes_master.py""" + valid_list_desc_str = """ # NOTE: valid_list_description is automatically created by using item_attributes_master.py""" + valid_list_item_type = """ # NOTE: valid_list_item_type is automatically created by using item_attributes_master.py""" + valid_list_calculation = """ # NOTE: valid_list_calculation is automatically created by using item_attributes_master.py""" + + for db_addon_fct in ITEM_ATTRIBUTES[attribute]: + valid_list_str = f"""{valid_list_str}\n\ + - {db_addon_fct!r:<40}""" + + valid_list_desc_str = f"""{valid_list_desc_str}\n\ + - '{ITEM_ATTRIBUTES[attribute][db_addon_fct]['description']:<}'""" + + valid_list_item_type = f"""{valid_list_item_type}\n\ + - '{ITEM_ATTRIBUTES[attribute][db_addon_fct]['item_type']:<}'""" + + valid_list_calculation = f"""{valid_list_calculation}\n\ + - '{ITEM_ATTRIBUTES[attribute][db_addon_fct]['calc']:<}'""" + + valid_list_calculation = f"""{valid_list_calculation}\n\r""" + + return valid_list_str, valid_list_desc_str, valid_list_item_type, valid_list_calculation + +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""" + + yaml = ruamel.yaml.YAML() + yaml.indent(mapping=4, sequence=4, offset=4) + yaml.width = 200 + yaml.allow_unicode = True + yaml.preserve_quotes = False + + valid_list_str, valid_list_desc_str, valid_list_item_type_str, valid_list_calc_str = create_plugin_yaml_item_attribute_valids() + + with open(FILENAME_PLUGIN, 'r', encoding="utf-8") as f: + data = yaml.load(f) + + if data.get('item_attributes', {}).get(attribute): + data['item_attributes'][attribute]['valid_list'] = yaml.load(valid_list_str) + data['item_attributes'][attribute]['valid_list_description'] = yaml.load(valid_list_desc_str) + data['item_attributes'][attribute]['valid_list_item_type'] = yaml.load(valid_list_item_type_str) + data['item_attributes'][attribute]['valid_list_calculation'] = yaml.load(valid_list_calc_str) + + with open(FILENAME_PLUGIN, 'w', encoding="utf-8") as f: + yaml.dump(data, f) + print(f"Successfully updated Attribute '{attribute}' in plugin.yaml!") + else: + print(f"Attribute '{attribute}' not defined in plugin.yaml") + +if __name__ == '__main__': + export_item_attributes_py() + for attribute in ITEM_ATTRIBUTES: + update_plugin_yaml_item_attributes() From 5bb511afd52656c498f3f7187d45c879e3e76f50 Mon Sep 17 00:00:00 2001 From: sisamiwe Date: Fri, 11 Aug 2023 16:01:22 +0200 Subject: [PATCH 04/18] db_addon: - execution of onchange to make sure changed values are already in db - store/load cached data as pickle to survive restart - enhance automated update scripts --- db_addon/__init__.py | 153 +++++++++++++++++++++++++++-- db_addon/item_attributes_master.py | 97 ++++++++++++++---- db_addon/plugin.yaml | 4 +- 3 files changed, 228 insertions(+), 26 deletions(-) diff --git a/db_addon/__init__.py b/db_addon/__init__.py index d254064f2..cc7646ce6 100644 --- a/db_addon/__init__.py +++ b/db_addon/__init__.py @@ -25,6 +25,7 @@ # ######################################################################### +import os import sqlvalidator import datetime import time @@ -32,9 +33,11 @@ import queue import threading import logging +import pickle from dateutil.relativedelta import relativedelta from typing import Union from dataclasses import dataclass, InitVar +from collections import deque from lib.model.smartplugin import SmartPlugin from lib.item import Items @@ -58,7 +61,7 @@ class DatabaseAddOn(SmartPlugin): PLUGIN_VERSION = '1.2.3' # ToDo: remove revision - REVISION = 'D' + REVISION = 'E' def __init__(self, sh): """ @@ -68,18 +71,22 @@ def __init__(self, sh): # Call init code of parent class (SmartPlugin) super().__init__() + self.logger.debug(f'Start of {self.get_shortname()} Plugin.') + # get item and shtime instance self.shtime = Shtime.get_instance() self.items = Items.get_instance() self.plugins = Plugins.get_instance() # define cache dicts - 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.pickle_data_validity_time = 600 # seconds after which the data saved in pickle are not valid anymore + 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 # define variables for database, database connection, working queue and status self.item_queue = queue.Queue() # Queue containing all to be executed items + self.update_item_delay_deque = deque() # Deque for delay working of updated item values # ToDo: Check if still needed self.queue_consumer_thread = None # Queue consumer thread self._db_plugin = None # object if database plugin @@ -93,6 +100,7 @@ def __init__(self, sh): self.startup_finished = False # Startup of Plugin finished self.suspended = False # Is plugin activity suspended self.active_queue_item: str = '-' # String holding item path of currently executed item + self.onchange_delay_time = 30 # define default mysql settings self.default_connect_timeout = 60 @@ -107,11 +115,15 @@ def __init__(self, sh): self.use_oldest_entry = self.get_parameter_value('use_oldest_entry') self.lock_db_for_query = self.get_parameter_value('lock_db_for_query') + # 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" + # get debug log options self.debug_log = DebugLogOptions(self.log_level) - # init cache dicts - self._init_cache_dicts() + # init cache data + self.init_cache_data() # init webinterface self.init_webinterface(WebInterface) @@ -153,6 +165,9 @@ def run(self): self.logger.info(f"Set scheduler for calculating startup-items with delay of {self.startup_run_delay + 3}s to {dt}.") self.scheduler_add('startup', self.execute_startup_items, next=dt) + # add scheduler for delayed working if onchange items + self.scheduler_add('onchange_delay', self.work_update_item_delay_deque, prio=3, cron=None, cycle=30, value=None, offset=None, next=None) + # update database_items in item config, where path was given self._update_database_items() @@ -183,7 +198,10 @@ def stop(self): self.logger.debug("Stop method called") self.alive = False self.scheduler_remove('cyclic') + self.scheduler_remove('onchange_delay') self._db.close() + self.save_cache_data() + # ToDo: Check if still needed # self._queue_consumer_thread_shutdown() @@ -740,6 +758,115 @@ def update_item(self, item, caller=None, source=None, dest=None): self._init_cache_dicts() item(False, self.get_shortname()) + def _save_pickle(self, data) -> None: + """Saves received data as pickle to given file""" + + if data and len(data) > 0: + self.logger.debug(f"Start writing data {data=} to '{self.data_storage_path}'") + os.makedirs(os.path.dirname(self.data_storage_path), exist_ok=True) + try: + with open(self.data_storage_path, "wb") as output: + try: + pickle.dump(data, output, pickle.HIGHEST_PROTOCOL) + self.logger.debug(f"Successfully wrote data to '{self.data_storage_path}'") + except Exception as e: + self.logger.debug(f"Unable to write data to '{self.data_storage_path}': {e}") + pass + except OSError as e: + self.logger.debug(f"Unable to write data to '{self.data_storage_path}': {e}") + pass + + def _read_pickle(self): + """read a pickle file to gather data""" + + self.logger.debug(f"Start reading data from '{self.data_storage_path}'") + + if os.path.exists(self.data_storage_path): + with open(self.data_storage_path, 'rb') as data: + try: + data = pickle.load(data) + self.logger.debug(f"Successfully read data from {self.data_storage_path}") + return data + except Exception as e: + self.logger.debug(f"Unable to read data from {self.data_storage_path}: {e}") + return None + + self.logger.debug(f"Unable to read data from {self.data_storage_path}: 'File/Path not existing'") + return None + + def init_cache_data(self): + """init cache dicts by reading pickle""" + + def create_items_1(d): + n_d = {} + for item_str in d: + item = self.items.return_item(item_str) + if item: + n_d[item] = d[item_str] + return n_d + + def create_items_2(d): + n_d = {} + for timeframe in d: + n_d[timeframe] = {} + for item_str in d[timeframe]: + item = self.items.return_item(item_str) + if item: + n_d[timeframe][item] = d[timeframe][item_str] + return n_d + + # init cache dicts + self._init_cache_dicts() + + # read pickle and set data + raw_data = self._read_pickle() + + if not isinstance(raw_data, dict): + self.logger.info("Unable to extract db_addon data from pickle file. Start with empty cache.") + return + + current_values = raw_data.get('current_values') + previous_values = raw_data.get('previous_values') + item_cache = raw_data.get('item_cache') + stop_time = raw_data.get('stop_time') + + if not stop_time or (int(time.time()) - stop_time) > self.pickle_data_validity_time: + self.logger.info("Data for db_addon read from pickle are expired. Start with empty cache.") + return + + if isinstance(current_values, dict): + self.current_values = create_items_2(current_values) + if isinstance(previous_values, dict): + self.previous_values = create_items_2(previous_values) + if isinstance(item_cache, dict): + self.item_cache = create_items_1(item_cache) + + def save_cache_data(self): + """save all relevant data to survive restart, transform items in item_str""" + + def clean_items_1(d): + n_d = {} + for item in d: + n_d[item.path()] = d[item] + return n_d + + def clean_items_2(d): + n_d = {} + for timeframe in d: + n_d[timeframe] = {} + for item in d[timeframe]: + n_d[timeframe][item.path()] = d[timeframe][item] + return n_d + + self._save_pickle({'current_values': clean_items_2(self.current_values), + 'previous_values': clean_items_2(self.previous_values), + 'item_cache': clean_items_1(self.item_cache), + 'stop_time': int(time.time())}) + + ######################################### + # Item Handling + ######################################### + def execute_due_items(self) -> None: """Execute all items, which are due""" @@ -838,12 +965,24 @@ def work_item_queue(self) -> None: item, value = queue_entry self.logger.info(f"# {self.item_queue.qsize() + 1} item(s) to do. || 'on-change' item={item.path()} with {value=} will be processed.") self.active_queue_item = str(item.path()) - self.handle_onchange(item, value) + # self.handle_onchange(item, value) + self.update_item_delay_deque.append([int(time.time()) + self.onchange_delay_time, item, value]) else: self.logger.info(f"# {self.item_queue.qsize() + 1} item(s) to do. || 'on-demand' item={queue_entry.path()} will be processed.") self.active_queue_item = str(queue_entry.path()) self.handle_ondemand(queue_entry) + def work_update_item_delay_deque(self): + """check update_item_delay_deque is due and process it""" + + for i in range(len(self.update_item_delay_deque)): + [update_time, item, value] = self.update_item_delay_deque.popleft() + if update_time < int(time.time()): + self.logger.debug(f"Item {item.path()} with {value=} is now due for being processed.") + self.handle_onchange(item, value) + else: + self.update_item_delay_deque.append([update_time, item, value]) + def handle_ondemand(self, item: Item) -> None: """ Calculate value for requested item, fill cache dicts and set item value. diff --git a/db_addon/item_attributes_master.py b/db_addon/item_attributes_master.py index 00b54a8cf..6fa54edf5 100644 --- a/db_addon/item_attributes_master.py +++ b/db_addon/item_attributes_master.py @@ -188,6 +188,7 @@ """ + def get_attrs(sub_dict: dict = {}) -> list: attributes = [] for entry in ITEM_ATTRIBUTES: @@ -196,7 +197,12 @@ def get_attrs(sub_dict: dict = {}) -> list: attributes.append(db_addon_fct) return attributes + def export_item_attributes_py(): + + print() + print(f"A) Start generation of {FILENAME_ATTRIBUTES}") + ATTRS = dict() ATTRS['ALL_ONCHANGE_ATTRIBUTES'] = get_attrs(sub_dict={'calc': 'onchange'}) ATTRS['ALL_DAILY_ATTRIBUTES'] = get_attrs(sub_dict={'calc': 'daily'}) @@ -240,9 +246,10 @@ def export_item_attributes_py(): with open(FILENAME_ATTRIBUTES, "a") as f: print(f'{attr} = {alist!r}', file=f) - print('item_attributes.py successfully created!') + print(f" {FILENAME_ATTRIBUTES} successfully generated.") -def create_plugin_yaml_item_attribute_valids(): + +def create_plugin_yaml_item_attribute_valids(attribute): """Create valid_list of db_addon_fct based on master dict""" valid_list_str = """ # NOTE: valid_list is automatically created by using item_attributes_master.py""" @@ -267,33 +274,89 @@ def create_plugin_yaml_item_attribute_valids(): return valid_list_str, valid_list_desc_str, valid_list_item_type, valid_list_calculation + 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}") + + for attribute in ITEM_ATTRIBUTES: + + print(f" Attribute {attribute} in progress") + + yaml = ruamel.yaml.YAML() + yaml.indent(mapping=4, sequence=4, offset=4) + yaml.width = 200 + yaml.allow_unicode = True + yaml.preserve_quotes = False + + valid_list_str, valid_list_desc_str, valid_list_item_type_str, valid_list_calc_str = create_plugin_yaml_item_attribute_valids(attribute) + + with open(FILENAME_PLUGIN, 'r', encoding="utf-8") as f: + data = yaml.load(f) + + if data.get('item_attributes', {}).get(attribute): + data['item_attributes'][attribute]['valid_list'] = yaml.load(valid_list_str) + data['item_attributes'][attribute]['valid_list_description'] = yaml.load(valid_list_desc_str) + data['item_attributes'][attribute]['valid_list_item_type'] = yaml.load(valid_list_item_type_str) + data['item_attributes'][attribute]['valid_list_calculation'] = yaml.load(valid_list_calc_str) + + with open(FILENAME_PLUGIN, 'w', encoding="utf-8") as f: + yaml.dump(data, f) + print(f" Successfully updated Attribute '{attribute}' in plugin.yaml!") + else: + print(f" Attribute '{attribute}' not defined in plugin.yaml") + + +def check_plugin_yaml_structs(): + # check structs for wrong attributes + print() + print(f'C) Checking used attributes in structs defined in {FILENAME_PLUGIN} ') + + # open plugin.yaml and update yaml = ruamel.yaml.YAML() yaml.indent(mapping=4, sequence=4, offset=4) yaml.width = 200 yaml.allow_unicode = True yaml.preserve_quotes = False - - valid_list_str, valid_list_desc_str, valid_list_item_type_str, valid_list_calc_str = create_plugin_yaml_item_attribute_valids() - with open(FILENAME_PLUGIN, 'r', encoding="utf-8") as f: data = yaml.load(f) - if data.get('item_attributes', {}).get(attribute): - data['item_attributes'][attribute]['valid_list'] = yaml.load(valid_list_str) - data['item_attributes'][attribute]['valid_list_description'] = yaml.load(valid_list_desc_str) - data['item_attributes'][attribute]['valid_list_item_type'] = yaml.load(valid_list_item_type_str) - data['item_attributes'][attribute]['valid_list_calculation'] = yaml.load(valid_list_calc_str) + structs = data.get('item_structs') + + def get_all_keys(d): + for key, value in d.items(): + yield key, value + if isinstance(value, dict): + yield from get_all_keys(value) + + attr_valid = True + + if structs: + for attr, attr_val in get_all_keys(structs): + if attr in ITEM_ATTRIBUTES: + if attr_val not in ITEM_ATTRIBUTES[attr].keys(): + print(f" - {attr_val} not a valid value for {ITEM_ATTRIBUTES[attr]}") + attr_valid = False + + if attr_valid: + print(f" All used attributes are valid.") + + print(f' Check complete.') + - with open(FILENAME_PLUGIN, 'w', encoding="utf-8") as f: - yaml.dump(data, f) - print(f"Successfully updated Attribute '{attribute}' in plugin.yaml!") - else: - print(f"Attribute '{attribute}' not defined in plugin.yaml") if __name__ == '__main__': + + print(f'Start automated update and check of {FILENAME_PLUGIN} and generation of {FILENAME_ATTRIBUTES}.') + print('-------------------------------------------------------------') + export_item_attributes_py() - for attribute in ITEM_ATTRIBUTES: - update_plugin_yaml_item_attributes() + + update_plugin_yaml_item_attributes() + + check_plugin_yaml_structs() + + print() + print(f'Automated update and check of {FILENAME_PLUGIN} and generation of {FILENAME_ATTRIBUTES} complete.') diff --git a/db_addon/plugin.yaml b/db_addon/plugin.yaml index 84e5ad089..c966df1bd 100644 --- a/db_addon/plugin.yaml +++ b/db_addon/plugin.yaml @@ -66,8 +66,8 @@ parameters: type: bool default: false description: - de: 'Sperren der Datenbank während der Abfrage' - en: 'Lock the database during queries' + de: Sperren der Datenbank während der Abfrage + en: Lock the database during queries item_attributes: db_addon_fct: From ba85b626fd5000e6bccaff7a3cea9b680a01ca68 Mon Sep 17 00:00:00 2001 From: sisamiwe Date: Sat, 12 Aug 2023 20:06:05 +0200 Subject: [PATCH 05/18] db_addon: - bugfix in work_update_item_delay_deque - update user-doc.rst --- db_addon/__init__.py | 16 +- db_addon/item_attributes_master.py | 50 +++++- db_addon/user_doc.rst | 262 ++++++++++++++++++++++++++++- 3 files changed, 318 insertions(+), 10 deletions(-) diff --git a/db_addon/__init__.py b/db_addon/__init__.py index cc7646ce6..7a87fa828 100644 --- a/db_addon/__init__.py +++ b/db_addon/__init__.py @@ -975,13 +975,15 @@ def work_item_queue(self) -> None: def work_update_item_delay_deque(self): """check update_item_delay_deque is due and process it""" - for i in range(len(self.update_item_delay_deque)): - [update_time, item, value] = self.update_item_delay_deque.popleft() - if update_time < int(time.time()): - self.logger.debug(f"Item {item.path()} with {value=} is now due for being processed.") - self.handle_onchange(item, value) - else: - self.update_item_delay_deque.append([update_time, item, value]) + deque_len = len(self.update_item_delay_deque) + if deque_len > 0: + for i in range(deque_len): + [update_time, item, value] = self.update_item_delay_deque.popleft() + if update_time < int(time.time()): + self.logger.debug(f"Item {item.path()} with {value=} is now due for being processed.") + self.handle_onchange(item, value) + else: + self.update_item_delay_deque.append([update_time, item, value]) def handle_ondemand(self, item: Item) -> None: """ diff --git a/db_addon/item_attributes_master.py b/db_addon/item_attributes_master.py index 6fa54edf5..d0bd1436f 100644 --- a/db_addon/item_attributes_master.py +++ b/db_addon/item_attributes_master.py @@ -25,6 +25,8 @@ FILENAME_PLUGIN = 'plugin.yaml' +DOC_FILE_NAME = 'user_doc.rst' + ITEM_ATTRIBUTES = { 'db_addon_fct': { 'verbrauch_heute': {'cat': 'verbrauch', 'sub_cat': 'onchange', 'item_type': 'num', 'calc': 'onchange', 'params': False, 'description': 'Verbrauch am heutigen Tag (Differenz zwischen aktuellem Wert und den Wert am Ende des vorherigen Tages)'}, @@ -312,7 +314,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'D) Checking used attributes in structs defined in {FILENAME_PLUGIN} ') # open plugin.yaml and update yaml = ruamel.yaml.YAML() @@ -346,10 +348,52 @@ def get_all_keys(d): print(f' Check complete.') +def update_user_doc(): + # Update user_doc.rst + print() + print(f'C) 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", + "\n"] + + for attribute in ITEM_ATTRIBUTES: + attribute_list.append("\n") + attribute_list.append(f"{attribute}\n") + attribute_list.append('-' * len(attribute)) + attribute_list.append("\n") + attribute_list.append("\n") + + 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"| Item-Type: {ITEM_ATTRIBUTES[attribute][db_addon_fct]['item_type']}\n") + attribute_list.append("\n") + + with open(DOC_FILE_NAME, 'r', encoding='utf-8') as file: + lines = file.readlines() + + start = end = None + for i, line in enumerate(lines): + if 'db_addon Item-Attribute' in line: + start = i + 3 + if 'Hinweise' in line: + end = i - 1 + + part1 = lines[0:start] + part3 = lines[end:len(lines)] + new_lines = part1 + attribute_list + part3 + + with open(DOC_FILE_NAME, 'w', encoding='utf-8') as file: + for line in new_lines: + file.write(line) + + print(f" Successfully updated Foshk-Attributes in {DOC_FILE_NAME}!") + if __name__ == '__main__': - print(f'Start automated update and check of {FILENAME_PLUGIN} and generation of {FILENAME_ATTRIBUTES}.') + 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() @@ -358,5 +402,7 @@ def get_all_keys(d): check_plugin_yaml_structs() + update_user_doc() + print() print(f'Automated update and check of {FILENAME_PLUGIN} and generation of {FILENAME_ATTRIBUTES} complete.') diff --git a/db_addon/user_doc.rst b/db_addon/user_doc.rst index 6f7978e1d..442888df7 100644 --- a/db_addon/user_doc.rst +++ b/db_addon/user_doc.rst @@ -68,7 +68,6 @@ Hinweis: Das Plugin selbst ist aktuell nicht multi-instance fähig. Das bedeutet des Database-Plugin abgebunden werden kann. - Konfiguration ============= @@ -93,6 +92,267 @@ Dazu folgenden Block am Ende der Datei */etc/mysql/my.cnf* einfügen bzw den exi interactive_timeout = 28800 +db_addon Item-Attribute +======================= + +Dieses Kapitel wurde automatisch durch Ausführen des Skripts in der Datei 'item_attributes_master.py' erstellt. + +Nachfolgend eine Auflistung der möglichen Attribute für das Plugin im Format: Attribute: Beschreibung | Berechnungszyklus | Item-Type + + +db_addon_fct +------------ + +- verbrauch_heute: Verbrauch am heutigen Tag (Differenz zwischen aktuellem Wert und den Wert am Ende des vorherigen Tages) | Berechnung: onchange | Item-Type: num + +- verbrauch_woche: Verbrauch in der aktuellen Woche | Berechnung: onchange | Item-Type: num + +- verbrauch_monat: Verbrauch im aktuellen Monat | Berechnung: onchange | Item-Type: num + +- verbrauch_jahr: Verbrauch im aktuellen Jahr | Berechnung: onchange | Item-Type: num + +- verbrauch_heute_minus1: Verbrauch gestern (heute -1 Tag) (Differenz zwischen Wert am Ende des gestrigen Tages und dem Wert am Ende des Tages davor) | Berechnung: daily | Item-Type: num + +- verbrauch_heute_minus2: Verbrauch vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num + +- verbrauch_heute_minus3: Verbrauch heute -3 Tage | Berechnung: daily | Item-Type: num + +- verbrauch_heute_minus4: Verbrauch heute -4 Tage | Berechnung: daily | Item-Type: num + +- verbrauch_heute_minus5: Verbrauch heute -5 Tage | Berechnung: daily | Item-Type: num + +- verbrauch_heute_minus6: Verbrauch heute -6 Tage | Berechnung: daily | Item-Type: num + +- verbrauch_heute_minus7: Verbrauch heute -7 Tage | Berechnung: daily | Item-Type: num + +- verbrauch_woche_minus1: Verbrauch Vorwoche (aktuelle Woche -1) | Berechnung: weekly | Item-Type: num + +- verbrauch_woche_minus2: Verbrauch aktuelle Woche -2 Wochen | Berechnung: weekly | Item-Type: num + +- verbrauch_woche_minus3: Verbrauch aktuelle Woche -3 Wochen | Berechnung: weekly | Item-Type: num + +- verbrauch_woche_minus4: Verbrauch aktuelle Woche -4 Wochen | Berechnung: weekly | Item-Type: num + +- verbrauch_monat_minus1: Verbrauch Vormonat (aktueller Monat -1) | Berechnung: monthly | Item-Type: num + +- verbrauch_monat_minus2: Verbrauch aktueller Monat -2 Monate | Berechnung: monthly | Item-Type: num + +- verbrauch_monat_minus3: Verbrauch aktueller Monat -3 Monate | Berechnung: monthly | Item-Type: num + +- verbrauch_monat_minus4: Verbrauch aktueller Monat -4 Monate | Berechnung: monthly | Item-Type: num + +- verbrauch_monat_minus12: Verbrauch aktueller Monat -12 Monate | Berechnung: monthly | Item-Type: num + +- verbrauch_jahr_minus1: Verbrauch Vorjahr (aktuelles Jahr -1 Jahr) | Berechnung: yearly | Item-Type: num + +- verbrauch_jahr_minus2: Verbrauch aktuelles Jahr -2 Jahre | Berechnung: yearly | Item-Type: num + +- verbrauch_rolling_12m_heute_minus1: Verbrauch der letzten 12 Monate ausgehend im Ende des letzten Tages | Berechnung: daily | Item-Type: num + +- verbrauch_rolling_12m_woche_minus1: Verbrauch der letzten 12 Monate ausgehend im Ende der letzten Woche | Berechnung: weekly | Item-Type: num + +- verbrauch_rolling_12m_monat_minus1: Verbrauch der letzten 12 Monate ausgehend im Ende des letzten Monats | Berechnung: monthly | Item-Type: num + +- verbrauch_rolling_12m_jahr_minus1: Verbrauch der letzten 12 Monate ausgehend im Ende des letzten Jahres | Berechnung: yearly | Item-Type: num + +- verbrauch_jahreszeitraum_minus1: Verbrauch seit dem 1.1. bis zum heutigen Tag des Vorjahres | Berechnung: daily | Item-Type: num + +- verbrauch_jahreszeitraum_minus2: Verbrauch seit dem 1.1. bis zum heutigen Tag vor 2 Jahren | Berechnung: daily | Item-Type: num + +- verbrauch_jahreszeitraum_minus3: Verbrauch seit dem 1.1. bis zum heutigen Tag vor 3 Jahren | Berechnung: daily | Item-Type: num + +- zaehlerstand_heute_minus1: Zählerstand / Wert am Ende des letzten Tages (heute -1 Tag) | Berechnung: daily | Item-Type: num + +- zaehlerstand_heute_minus2: Zählerstand / Wert am Ende des vorletzten Tages (heute -2 Tag) | Berechnung: daily | Item-Type: num + +- zaehlerstand_heute_minus3: Zählerstand / Wert am Ende des vorvorletzten Tages (heute -3 Tag) | Berechnung: daily | Item-Type: num + +- zaehlerstand_woche_minus1: Zählerstand / Wert am Ende der vorvorletzten Woche (aktuelle Woche -1 Woche) | Berechnung: weekly | Item-Type: num + +- zaehlerstand_woche_minus2: Zählerstand / Wert am Ende der vorletzten Woche (aktuelle Woche -2 Wochen) | Berechnung: weekly | Item-Type: num + +- zaehlerstand_woche_minus3: Zählerstand / Wert am Ende der aktuellen Woche -3 Wochen | Berechnung: weekly | Item-Type: num + +- zaehlerstand_monat_minus1: Zählerstand / Wert am Ende des letzten Monates (aktueller Monat -1 Monat) | Berechnung: monthly | Item-Type: num + +- zaehlerstand_monat_minus2: Zählerstand / Wert am Ende des vorletzten Monates (aktueller Monat -2 Monate) | Berechnung: monthly | Item-Type: num + +- zaehlerstand_monat_minus3: Zählerstand / Wert am Ende des aktuellen Monats -3 Monate | Berechnung: monthly | Item-Type: num + +- zaehlerstand_jahr_minus1: Zählerstand / Wert am Ende des letzten Jahres (aktuelles Jahr -1 Jahr) | Berechnung: yearly | Item-Type: num + +- zaehlerstand_jahr_minus2: Zählerstand / Wert am Ende des vorletzten Jahres (aktuelles Jahr -2 Jahre) | Berechnung: yearly | Item-Type: num + +- zaehlerstand_jahr_minus3: Zählerstand / Wert am Ende des aktuellen Jahres -3 Jahre | Berechnung: yearly | Item-Type: num + +- minmax_last_24h_min: minimaler Wert der letzten 24h | Berechnung: daily | Item-Type: num + +- minmax_last_24h_max: maximaler Wert der letzten 24h | Berechnung: daily | Item-Type: num + +- minmax_last_24h_avg: durchschnittlicher Wert der letzten 24h | Berechnung: daily | Item-Type: num + +- minmax_last_7d_min: minimaler Wert der letzten 7 Tage | Berechnung: daily | Item-Type: num + +- minmax_last_7d_max: maximaler Wert der letzten 7 Tage | Berechnung: daily | Item-Type: num + +- minmax_last_7d_avg: durchschnittlicher Wert der letzten 7 Tage | Berechnung: daily | Item-Type: num + +- minmax_heute_min: Minimalwert seit Tagesbeginn | Berechnung: onchange | Item-Type: num + +- minmax_heute_max: Maximalwert seit Tagesbeginn | Berechnung: onchange | Item-Type: num + +- minmax_heute_avg: Durschnittswert seit Tagesbeginn | Berechnung: onchange | Item-Type: num + +- minmax_heute_minus1_min: Minimalwert gestern (heute -1 Tag) | Berechnung: daily | Item-Type: num + +- minmax_heute_minus1_max: Maximalwert gestern (heute -1 Tag) | Berechnung: daily | Item-Type: num + +- minmax_heute_minus1_avg: Durchschnittswert gestern (heute -1 Tag) | Berechnung: daily | Item-Type: num + +- minmax_heute_minus2_min: Minimalwert vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num + +- minmax_heute_minus2_max: Maximalwert vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num + +- minmax_heute_minus2_avg: Durchschnittswert vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num + +- minmax_heute_minus3_min: Minimalwert heute vor 3 Tagen | Berechnung: daily | Item-Type: num + +- minmax_heute_minus3_max: Maximalwert heute vor 3 Tagen | Berechnung: daily | Item-Type: num + +- minmax_heute_minus3_avg: Durchschnittswert heute vor 3 Tagen | Berechnung: daily | Item-Type: num + +- minmax_woche_min: Minimalwert seit Wochenbeginn | Berechnung: onchange | Item-Type: num + +- minmax_woche_max: Maximalwert seit Wochenbeginn | Berechnung: onchange | Item-Type: num + +- minmax_woche_minus1_min: Minimalwert Vorwoche (aktuelle Woche -1) | Berechnung: weekly | Item-Type: num + +- minmax_woche_minus1_max: Maximalwert Vorwoche (aktuelle Woche -1) | Berechnung: weekly | Item-Type: num + +- minmax_woche_minus1_avg: Durchschnittswert Vorwoche (aktuelle Woche -1) | Berechnung: weekly | Item-Type: num + +- minmax_woche_minus2_min: Minimalwert aktuelle Woche -2 Wochen | Berechnung: weekly | Item-Type: num + +- minmax_woche_minus2_max: Maximalwert aktuelle Woche -2 Wochen | Berechnung: weekly | Item-Type: num + +- minmax_woche_minus2_avg: Durchschnittswert aktuelle Woche -2 Wochen | Berechnung: weekly | Item-Type: num + +- minmax_monat_min: Minimalwert seit Monatsbeginn | Berechnung: onchange | Item-Type: num + +- minmax_monat_max: Maximalwert seit Monatsbeginn | Berechnung: onchange | Item-Type: num + +- minmax_monat_minus1_min: Minimalwert Vormonat (aktueller Monat -1) | Berechnung: monthly | Item-Type: num + +- minmax_monat_minus1_max: Maximalwert Vormonat (aktueller Monat -1) | Berechnung: monthly | Item-Type: num + +- minmax_monat_minus1_avg: Durchschnittswert Vormonat (aktueller Monat -1) | Berechnung: monthly | Item-Type: num + +- minmax_monat_minus2_min: Minimalwert aktueller Monat -2 Monate | Berechnung: monthly | Item-Type: num + +- minmax_monat_minus2_max: Maximalwert aktueller Monat -2 Monate | Berechnung: monthly | Item-Type: num + +- minmax_monat_minus2_avg: Durchschnittswert aktueller Monat -2 Monate | Berechnung: monthly | Item-Type: num + +- minmax_jahr_min: Minimalwert seit Jahresbeginn | Berechnung: onchange | Item-Type: num + +- minmax_jahr_max: Maximalwert seit Jahresbeginn | Berechnung: onchange | Item-Type: num + +- minmax_jahr_minus1_min: Minimalwert Vorjahr (aktuelles Jahr -1 Jahr) | Berechnung: yearly | Item-Type: num + +- minmax_jahr_minus1_max: Maximalwert Vorjahr (aktuelles Jahr -1 Jahr) | Berechnung: yearly | Item-Type: num + +- minmax_jahr_minus1_avg: Durchschnittswert Vorjahr (aktuelles Jahr -1 Jahr) | Berechnung: yearly | Item-Type: num + +- tagesmitteltemperatur_heute: Tagesmitteltemperatur heute | Berechnung: onchange | Item-Type: num + +- tagesmitteltemperatur_heute_minus1: Tagesmitteltemperatur des letzten Tages (heute -1 Tag) | Berechnung: daily | Item-Type: num + +- tagesmitteltemperatur_heute_minus2: Tagesmitteltemperatur des vorletzten Tages (heute -2 Tag) | Berechnung: daily | Item-Type: num + +- tagesmitteltemperatur_heute_minus3: Tagesmitteltemperatur des vorvorletzten Tages (heute -3 Tag) | Berechnung: daily | Item-Type: num + +- serie_minmax_monat_min_15m: monatlicher Minimalwert der letzten 15 Monate (gleitend) | Berechnung: monthly | Item-Type: list + +- serie_minmax_monat_max_15m: monatlicher Maximalwert der letzten 15 Monate (gleitend) | Berechnung: monthly | Item-Type: list + +- serie_minmax_monat_avg_15m: monatlicher Mittelwert der letzten 15 Monate (gleitend) | Berechnung: monthly | Item-Type: list + +- serie_minmax_woche_min_30w: wöchentlicher Minimalwert der letzten 30 Wochen (gleitend) | Berechnung: weekly | Item-Type: list + +- serie_minmax_woche_max_30w: wöchentlicher Maximalwert der letzten 30 Wochen (gleitend) | Berechnung: weekly | Item-Type: list + +- serie_minmax_woche_avg_30w: wöchentlicher Mittelwert der letzten 30 Wochen (gleitend) | Berechnung: weekly | Item-Type: list + +- serie_minmax_tag_min_30d: täglicher Minimalwert der letzten 30 Tage (gleitend) | Berechnung: daily | Item-Type: list + +- serie_minmax_tag_max_30d: täglicher Maximalwert der letzten 30 Tage (gleitend) | Berechnung: daily | Item-Type: list + +- serie_minmax_tag_avg_30d: täglicher Mittelwert der letzten 30 Tage (gleitend) | Berechnung: daily | Item-Type: list + +- serie_verbrauch_tag_30d: Verbrauch pro Tag der letzten 30 Tage | Berechnung: daily | Item-Type: list + +- serie_verbrauch_woche_30w: Verbrauch pro Woche der letzten 30 Wochen | Berechnung: weekly | Item-Type: list + +- serie_verbrauch_monat_18m: Verbrauch pro Monat der letzten 18 Monate | Berechnung: monthly | Item-Type: list + +- serie_zaehlerstand_tag_30d: Zählerstand am Tagesende der letzten 30 Tage | Berechnung: daily | Item-Type: list + +- serie_zaehlerstand_woche_30w: Zählerstand am Wochenende der letzten 30 Wochen | Berechnung: weekly | Item-Type: list + +- serie_zaehlerstand_monat_18m: Zählerstand am Monatsende der letzten 18 Monate | Berechnung: monthly | Item-Type: list + +- serie_waermesumme_monat_24m: monatliche Wärmesumme der letzten 24 Monate | Berechnung: monthly | Item-Type: list + +- serie_kaeltesumme_monat_24m: monatliche Kältesumme der letzten 24 Monate | Berechnung: monthly | Item-Type: list + +- serie_tagesmittelwert_0d: Tagesmittelwert für den aktuellen Tag | Berechnung: daily | Item-Type: list + +- serie_tagesmittelwert_stunde_0d: Stundenmittelwert für den aktuellen Tag | Berechnung: daily | Item-Type: list + +- serie_tagesmittelwert_stunde_30_0d: Stundenmittelwert für den aktuellen Tag | Berechnung: daily | Item-Type: list + +- serie_tagesmittelwert_tag_stunde_30d: Stundenmittelwert pro Tag der letzten 30 Tage (bspw. zur Berechnung der Tagesmitteltemperatur basierend auf den Mittelwert der Temperatur pro Stunde | Berechnung: daily | Item-Type: list + +- general_oldest_value: Ausgabe des ältesten Wertes des entsprechenden "Parent-Items" mit database Attribut | Berechnung: no | Item-Type: num + +- general_oldest_log: Ausgabe des Timestamp des ältesten Eintrages des entsprechenden "Parent-Items" mit database Attribut | Berechnung: no | Item-Type: list + +- kaeltesumme: Berechnet die Kältesumme für einen Zeitraum, db_addon_params: (year=mandatory, month=optional) | Berechnung: daily | Item-Type: num + +- waermesumme: Berechnet die Wärmesumme für einen Zeitraum, db_addon_params: (year=mandatory, month=optional) | Berechnung: daily | Item-Type: num + +- gruenlandtempsumme: Berechnet die Grünlandtemperatursumme für einen Zeitraum, db_addon_params: (year=mandatory) | Berechnung: daily | Item-Type: num + +- tagesmitteltemperatur: Berechnet die Tagesmitteltemperatur auf Basis der stündlichen Durchschnittswerte eines Tages für die angegebene Anzahl von Tagen (timeframe=day, count=integer) | Berechnung: daily | Item-Type: list + +- wachstumsgradtage: Berechnet die Wachstumsgradtage auf Basis der stündlichen Durchschnittswerte eines Tages für das laufende Jahr mit an Angabe des Temperaturschwellenwertes (threshold=Schwellentemperatur) | Berechnung: daily | Item-Type: num + +- db_request: Abfrage der DB: db_addon_params: (func=mandatory, item=mandatory, timespan=mandatory, start=optional, end=optional, count=optional, group=optional, group2=optional) | Berechnung: group | Item-Type: list + +- minmax: Berechnet einen min/max/avg Wert für einen bestimmen Zeitraum: db_addon_params: (func=mandatory, timeframe=mandatory, start=mandatory) | Berechnung: timeframe | Item-Type: num + +- minmax_last: 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) | Berechnung: timeframe | Item-Type: num + +- verbrauch: Berechnet einen Verbrauchswert für einen bestimmen Zeitraum: db_addon_params: (timeframe=mandatory, start=mandatory end=mandatory) | Berechnung: timeframe | Item-Type: num + +- zaehlerstand: Berechnet einen Zählerstand für einen bestimmen Zeitpunkt: db_addon_params: (timeframe=mandatory, start=mandatory) | Berechnung: timeframe | Item-Type: num + + +db_addon_info +------------- + +- db_version: Version der verbundenen Datenbank | Berechnung: no | Item-Type: str + + +db_addon_admin +-------------- + +- suspend: Unterbricht die Aktivitäten des Plugin | Berechnung: no | Item-Type: bool + +- recalc_all: Startet einen Neuberechnungslauf aller on-demand Items | Berechnung: no | Item-Type: bool + +- clean_cache_values: Löscht Plugin-Cache und damit alle im Plugin zwischengespeicherten Werte | Berechnung: no | Item-Type: bool + Hinweise ======== From 7111c73d8aeeab4664f4f3b81c4af8c190e9690f Mon Sep 17 00:00:00 2001 From: sisamiwe Date: Mon, 14 Aug 2023 11:53:54 +0200 Subject: [PATCH 06/18] db_addon: - bugfix webif - update plugin.yaml --- db_addon/plugin.yaml | 2 +- db_addon/webif/templates/index.html | 34 +++++++++++++++-------------- 2 files changed, 19 insertions(+), 17 deletions(-) diff --git a/db_addon/plugin.yaml b/db_addon/plugin.yaml index c966df1bd..5f719b5b9 100644 --- a/db_addon/plugin.yaml +++ b/db_addon/plugin.yaml @@ -36,7 +36,7 @@ parameters: en: Delay in seconds, after which the startup calculations will be run ignore_0: - type: list + type: list(str) default: [] description: de: 'Bei Items, bei denen ein String aus der Liste im Pfadnamen vorkommt, werden 0-Werte (val_num = 0) bei Datenbankauswertungen ignoriert. Beispieleintrag: temp | hum' diff --git a/db_addon/webif/templates/index.html b/db_addon/webif/templates/index.html index 1b0af72cc..cf6eb4964 100644 --- a/db_addon/webif/templates/index.html +++ b/db_addon/webif/templates/index.html @@ -306,22 +306,24 @@ {% set first = True %} - {% for key, value in p._db._params.items() %} - {% if loop.index % 4 == 0 %} - - {% endif %} - {% if key != "passwd" %} - - {% else %} - - {% endif %} - {% if loop.index % 3 > 0 and loop.last %} - - {% endif %} - {% if loop.index % 4 == 0 and not first %} - - {% endif %} - {% endfor %} + {% if p._db %} + {% for key, value in p._db._params.items() %} + {% if loop.index % 4 == 0 %} + + {% endif %} + {% if key != "passwd" %} + + {% else %} + + {% endif %} + {% if loop.index % 3 > 0 and loop.last %} + + {% endif %} + {% if loop.index % 4 == 0 and not first %} + + {% endif %} + {% endfor %} + {% endif %} From c1e0ed95554050aa62f738e75ec80bb21fabf810 Mon Sep 17 00:00:00 2001 From: sisamiwe Date: Wed, 16 Aug 2023 08:06:38 +0200 Subject: [PATCH 07/18] - change way of delaying on-change items for being processed --- db_addon/__init__.py | 50 +++++++++++++++++++++----------------------- 1 file changed, 24 insertions(+), 26 deletions(-) diff --git a/db_addon/__init__.py b/db_addon/__init__.py index 7a87fa828..2175c53de 100644 --- a/db_addon/__init__.py +++ b/db_addon/__init__.py @@ -61,7 +61,7 @@ class DatabaseAddOn(SmartPlugin): PLUGIN_VERSION = '1.2.3' # ToDo: remove revision - REVISION = 'E' + REVISION = 'G' def __init__(self, sh): """ @@ -97,7 +97,6 @@ def __init__(self, sh): self.item_attribute_search_str = 'database' # attribute, on which an item configured for database can be identified self.last_connect_time = 0 # mechanism for limiting db connection requests self.alive = None # Is plugin alive? - self.startup_finished = False # Startup of Plugin finished self.suspended = False # Is plugin activity suspended self.active_queue_item: str = '-' # String holding item path of currently executed item self.onchange_delay_time = 30 @@ -165,9 +164,6 @@ def run(self): self.logger.info(f"Set scheduler for calculating startup-items with delay of {self.startup_run_delay + 3}s to {dt}.") self.scheduler_add('startup', self.execute_startup_items, next=dt) - # add scheduler for delayed working if onchange items - self.scheduler_add('onchange_delay', self.work_update_item_delay_deque, prio=3, cron=None, cycle=30, value=None, offset=None, next=None) - # update database_items in item config, where path was given self._update_database_items() @@ -738,13 +734,13 @@ def update_item(self, item, caller=None, source=None, dest=None): if self.alive and caller != self.get_shortname(): # handle database items if item in self._database_items(): - if not self.startup_finished: - self.logger.info(f"Handling of 'on-change' is paused for startup. No updated will be processed.") - elif self.suspended: + # if not self.startup_finished: + # self.logger.info(f"Handling of 'on-change' is paused for startup. No updated will be processed.") + if self.suspended: self.logger.info(f"Plugin is suspended. No updated will be processed.") else: - self.logger.info(f"+ Updated item '{item.path()}' with value {item()} will be put to queue for processing. {self.item_queue.qsize() + 1} items to do.") - self.item_queue.put((item, item())) + self.logger.debug(f" Updated Item {item.path()} with value {item()} will be put to queue in approx. {self.onchange_delay_time}s resp. after startup.") + self.update_item_delay_deque.append([item, item(), int(time.time() + self.onchange_delay_time)]) # handle admin items elif self.has_iattr(item.conf, 'db_addon_admin'): @@ -762,7 +758,7 @@ def _save_pickle(self, data) -> None: """Saves received data as pickle to given file""" if data and len(data) > 0: - self.logger.debug(f"Start writing data {data=} to '{self.data_storage_path}'") + self.logger.debug(f"Start writing {data=} to '{self.data_storage_path}'") os.makedirs(os.path.dirname(self.data_storage_path), exist_ok=True) try: with open(self.data_storage_path, "wb") as output: @@ -873,10 +869,13 @@ def execute_due_items(self) -> None: self.execute_items() def execute_startup_items(self) -> None: - """Execute all startup_items""" + """Execute all startup_items and set scheduler for delaying on-change items""" + # execute item calculation self.execute_items(option='startup') - self.startup_finished = True + + # add scheduler for delayed working if onchange items + self.scheduler_add('onchange_delay', self.work_update_item_delay_deque, prio=3, cron=None, cycle=30, value=None, offset=None, next=None) def execute_items(self, option: str = 'due', item: str = None): """Execute all items per option""" @@ -965,25 +964,24 @@ def work_item_queue(self) -> None: item, value = queue_entry self.logger.info(f"# {self.item_queue.qsize() + 1} item(s) to do. || 'on-change' item={item.path()} with {value=} will be processed.") self.active_queue_item = str(item.path()) - # self.handle_onchange(item, value) - self.update_item_delay_deque.append([int(time.time()) + self.onchange_delay_time, item, value]) + self.handle_onchange(item, value) else: self.logger.info(f"# {self.item_queue.qsize() + 1} item(s) to do. || 'on-demand' item={queue_entry.path()} will be processed.") self.active_queue_item = str(queue_entry.path()) self.handle_ondemand(queue_entry) def work_update_item_delay_deque(self): - """check update_item_delay_deque is due and process it""" - - deque_len = len(self.update_item_delay_deque) - if deque_len > 0: - for i in range(deque_len): - [update_time, item, value] = self.update_item_delay_deque.popleft() - if update_time < int(time.time()): - self.logger.debug(f"Item {item.path()} with {value=} is now due for being processed.") - self.handle_onchange(item, value) - else: - self.update_item_delay_deque.append([update_time, item, value]) + """check if entries in update_item_delay_deque are due, if so put it to working queue""" + + while self.update_item_delay_deque: + update_time = self.update_item_delay_deque[0][2] + if update_time <= int(time.time()): + [item, value, *_] = self.update_item_delay_deque.popleft() + self.logger.info(f"+ Updated item '{item.path()}' with value {item()} is now due to be put to queue for processing. {self.item_queue.qsize() + 1} items to do.") + self.item_queue.put((item, value)) + else: + self.logger.debug(f"Remaining items in deque are not due, yet.") + break def handle_ondemand(self, item: Item) -> None: """ From 7a2e993d1773afd2d2d4c1c9051852e2575cd5a6 Mon Sep 17 00:00:00 2001 From: sisamiwe Date: Wed, 16 Aug 2023 08:11:38 +0200 Subject: [PATCH 08/18] - change way of delaying on-change items for being processed --- db_addon/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/db_addon/__init__.py b/db_addon/__init__.py index 2175c53de..446d44d81 100644 --- a/db_addon/__init__.py +++ b/db_addon/__init__.py @@ -980,7 +980,7 @@ def work_update_item_delay_deque(self): self.logger.info(f"+ Updated item '{item.path()}' with value {item()} is now due to be put to queue for processing. {self.item_queue.qsize() + 1} items to do.") self.item_queue.put((item, value)) else: - self.logger.debug(f"Remaining items in deque are not due, yet.") + self.logger.debug(f"Remaining {len(self.update_item_delay_deque)} items in deque are not due, yet.") break def handle_ondemand(self, item: Item) -> None: From 4010d0ff5c61a5c91ffaaaceb798dd3b0b45d946 Mon Sep 17 00:00:00 2001 From: sisamiwe Date: Sun, 20 Aug 2023 17:10:31 +0200 Subject: [PATCH 09/18] =?UTF-8?q?DB=5FADDON:=20-=20rewrite=20of=20diverse?= =?UTF-8?q?=20methods=20for=20better=20maintainablility=20-=20introduce=20?= =?UTF-8?q?'Kenntage'=20like=20W=C3=BCstentag,=20Hei=C3=9Fer=20Tag,=20...?= =?UTF-8?q?=20-=20Bugfixing=20-=20update=20user=5Fdoc.rst=20-=20update=20i?= =?UTF-8?q?tem=5Fattributes=5Fmaster.py=20-=20update=20item=5Fattributes.p?= =?UTF-8?q?y?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- db_addon/__init__.py | 687 ++++++++++++++--------------- db_addon/item_attributes.py | 7 +- db_addon/item_attributes_master.py | 25 +- db_addon/plugin.yaml | 44 +- db_addon/user_doc.rst | 89 +++- 5 files changed, 466 insertions(+), 386 deletions(-) diff --git a/db_addon/__init__.py b/db_addon/__init__.py index 446d44d81..2cfb1369f 100644 --- a/db_addon/__init__.py +++ b/db_addon/__init__.py @@ -34,6 +34,7 @@ import threading import logging import pickle +import operator from dateutil.relativedelta import relativedelta from typing import Union from dataclasses import dataclass, InitVar @@ -61,7 +62,7 @@ class DatabaseAddOn(SmartPlugin): PLUGIN_VERSION = '1.2.3' # ToDo: remove revision - REVISION = 'G' + REVISION = 'H' def __init__(self, sh): """ @@ -83,6 +84,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 = {} # define variables for database, database connection, working queue and status self.item_queue = queue.Queue() # Queue containing all to be executed items @@ -216,10 +218,11 @@ def parse_item(self, item: Item): """ def get_query_parameters_from_db_addon_fct() -> Union[dict, None]: + """ derived parameters from given db_addon_fct""" # get parameter db_addon_fct_vars = db_addon_fct.split('_') - func = timeframe = timedelta = start = end = group = group2 = method = log_text = None + func = timeframe = timedelta = start = end = group = group2 = data_con_func = log_text = None required_params = None if db_addon_fct in HISTORIE_ATTRIBUTES_ONCHANGE: @@ -309,9 +312,9 @@ def get_query_parameters_from_db_addon_fct() -> Union[dict, None]: timeframe = translate_timeframe(db_addon_fct_vars[1]) end = to_int(split_sting_letters_numbers(db_addon_fct_vars[2])[1]) start = end - method = 'avg_hour' + data_con_func = 'first_hour_avg_day' log_text = 'tagesmitteltemperatur_timeframe_timedelta' - required_params = [func, timeframe, start, end, method] + 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' @@ -381,23 +384,23 @@ def get_query_parameters_from_db_addon_fct() -> Union[dict, None]: 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) - method = 'avg_hour' + 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, method, start, end] + 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 - method = 'avg_hour' + 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, method, start, end] + required_params = [timeframe, data_con_func, start, end] elif db_addon_fct in ALL_GEN_ATTRIBUTES: log_text = 'all_gen_attributes' @@ -408,37 +411,44 @@ def get_query_parameters_from_db_addon_fct() -> Union[dict, None]: return if required_params and None in required_params: - self.logger.warning(f"For calculating '{db_addon_fct}' at Item '{item.path()}' not all mandatory parameters given. Definitions are: {func=}, {timeframe=}, {timedelta=}, {start=}, {end=}, {group=}, {group2=}, {method=}") + self.logger.warning(f"For calculating '{db_addon_fct}' at Item '{item.path()}' not all mandatory parameters given. Definitions are: {func=}, {timeframe=}, {timedelta=}, {start=}, {end=}, {group=}, {group2=}, {data_con_func=}") return # 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, 'method': method} + param_dict = {'func': func, 'timeframe': timeframe, 'timedelta': timedelta, 'start': start, 'end': end, 'group': group, 'group2': group2, 'data_con_func': data_con_func} # return reduced dict w keys with value != None return {k: v for k, v in param_dict.items() if v is not None} def get_query_parameters_from_db_addon_params() -> Union[dict, None]: - """get query parameters from item attribute db_addon_params""" + """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 + """ 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') + if not db_addon_params: + db_addon_params = {} + new_db_addon_params = {} possible_params = required_params = [] - if db_addon_params is None: - self.logger.warning(f"Definition for Item '{item.path()}' with db_addon_fct={db_addon_fct} incomplete, since parameters via 'db_addon_params' not given. Item will be ignored.") - return - # create item config for all functions with 'summe' like waermesumme, kaeltesumme, gruenlandtemperatursumme - if 'summe' in db_addon_fct: + if db_addon_fct in ('kaeltesumme', 'waermesumme', 'gruenlandtempsumme'): possible_params = ['year', 'month'] - # create item config for wachstumsgradtage function + # create item config for wachstumsgradtage attributes elif db_addon_fct == 'wachstumsgradtage': - possible_params = ['year', 'method', 'threshold'] + 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': @@ -475,8 +485,7 @@ def get_query_parameters_from_db_addon_params() -> Union[dict, None]: if value: new_db_addon_params[key] = value - if new_db_addon_params: - return new_db_addon_params + return new_db_addon_params def get_database_item_path() -> tuple: """ @@ -488,10 +497,11 @@ def get_database_item_path() -> tuple: for i in range(3): if self.has_iattr(_lookup_item.conf, 'db_addon_database_item'): if self.debug_log.parse: - self.logger.debug(f"Attribut 'db_addon_database_item' for item='{item.path()}' has been found {i + 1} level above item at '{_lookup_item.path()}'.") + self.logger.debug(f"Attribut 'db_addon_database_item' for item='{item.path()}' has been found {i} level above item at '{_lookup_item.path()}'.") _database_item_path = self.get_iattr_value(_lookup_item.conf, 'db_addon_database_item') - _startup = bool(self.get_iattr_value(_lookup_item.conf, 'db_addon_startup')) - return _database_item_path, _startup + if self.debug_log.parse: + self.logger.debug(f"{_database_item_path=}, {_lookup_item.path()}") + return _database_item_path, _lookup_item else: _lookup_item = _lookup_item.return_parent() @@ -613,26 +623,29 @@ 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() # get query parameters from db_addon_fct or db_addon_params - if db_addon_fct in ALL_NEED_PARAMS_ATTRIBUTES: + if db_addon_fct in ALL_PARAMS_ATTRIBUTES: query_params = get_query_parameters_from_db_addon_params() else: query_params = get_query_parameters_from_db_addon_fct() - if not query_params: + if query_params is None: return # get database item (and attribute value if item should be calculated at plugin startup) and return if not available - database_item, db_addon_startup = get_database_item_path() + database_item, database_item_definition_item = get_database_item_path() if database_item is None: database_item = get_database_item() - db_addon_startup = bool(self.get_iattr_value(item.conf, 'db_addon_startup')) + database_item_definition_item = item + db_addon_startup = self.get_iattr_value(database_item_definition_item.conf, 'db_addon_startup') + db_addon_ignore_value_list = self.get_iattr_value(database_item_definition_item.conf, 'db_addon_ignore_value_list') # ['> 0', '< 35'] + db_addon_ignore_value = self.get_iattr_value(database_item_definition_item.conf, 'db_addon_ignore_value') # num if database_item is None: self.logger.warning(f"No database item found for item={item.path()}: Item ignored. Maybe you should check instance of database plugin.") return + else: + if self.debug_log.parse: + self.logger.debug(f"{database_item=}, {db_addon_startup=}, {db_addon_ignore_value_list=}, {db_addon_ignore_value=}") - # get/create list of comparison operators and check it - db_addon_ignore_value_list = self.get_iattr_value(item.conf, 'db_addon_ignore_value_list') # ['> 0', '< 35'] - db_addon_ignore_value = self.get_iattr_value(item.conf, 'db_addon_ignore_value') # num - + # create list of comparison operators and check it if not db_addon_ignore_value_list: db_addon_ignore_value_list = [] @@ -888,6 +901,7 @@ def _create_due_items() -> list: _todo_items.update(set(self._daily_items())) self.current_values[DAY] = {} self.previous_values[DAY] = {} + self.value_list_raw_data = {} # wenn Wochentag == Montag, werden auch die wöchentlichen Items berechnet if self.shtime.weekday(self.shtime.today()) == 1: @@ -1032,7 +1046,7 @@ def handle_ondemand(self, item: Item) -> None: # handle TAGESMITTEL_ATTRIBUTES_TIMEFRAME like tagesmitteltemperatur_heute_minus1 elif db_addon_fct in TAGESMITTEL_ATTRIBUTES_TIMEFRAME: - params.update({'method': 'avg_hour'}) + params.update({'data_con_func': 'first_hour_avg_day'}) _result = self._prepare_value_list(**params) if isinstance(_result, list): @@ -1052,22 +1066,15 @@ def handle_ondemand(self, item: Item) -> None: elif db_addon_fct == 'general_oldest_log': result = self._get_oldest_log(database_item) - # handle kaeltesumme - elif db_addon_fct == 'kaeltesumme': - result = self._handle_kaeltesumme(database_item=database_item, year=params.get('year'), month=params.get('month')) - - # handle waermesumme - elif db_addon_fct == 'waermesumme': - result = self._handle_waermesumme(database_item=database_item, year=params.get('year'), month=params.get('month')) - - # handle gruenlandtempsumme - elif db_addon_fct == 'gruenlandtempsumme': - result = self._handle_gruenlandtemperatursumme(database_item=database_item, year=params.get('year')) - - # handle wachstumsgradtage - elif db_addon_fct == 'wachstumsgradtage': - result = self._handle_wachstumsgradtage(database_item=database_item, year=params.get('year')) + # handle all functions using temperature sums + elif db_addon_fct in ALL_SUMME_ATTRIBUTES: + new_params = {} + for entry in ('threshold', 'variant', 'result', 'data_con_func'): + if entry in params: + new_params.update({entry: params[entry]}) + result = self._handle_temp_sums(func=db_addon_fct, database_item=database_item, year=params.get('year'), month=params.get('month'), ignore_value_list=params.get('ignore_value_list'), params=new_params) + # handle everything else else: result = self._query_item(**params)[0][1] @@ -1123,9 +1130,9 @@ def handle_minmax(): # if value not given if init: if self.debug_log.onchange: - self.logger.debug(f"initial {func} value for {timeframe=} of item={item.path()} with will be set to {value}") - cache_dict[database_item][func] = value - return value + self.logger.debug(f"initial {func} value for {timeframe=} of item={item.path()} with will be set to {cached_value}") + cache_dict[database_item][func] = cached_value + return cached_value # check value for update of cache dict min elif func == 'min' and value < cached_value: @@ -1175,7 +1182,7 @@ def handle_verbrauch(): return _new_value if isinstance(_new_value, int) else round(_new_value, 2) def handle_tagesmittel(): - result = self._prepare_value_list(database_item=database_item, timeframe='day', start=0, end=0, ignore_value_list=ignore_value_list, method='first_hour') + result = self._prepare_value_list(database_item=database_item, timeframe='day', start=0, end=0, ignore_value_list=ignore_value_list, data_con_func='first_hour') if isinstance(result, list): return result[0][1] @@ -1199,7 +1206,7 @@ def handle_tagesmittel(): ignore_value_list = item_config['query_params'].get('ignore_value_list') new_value = None - # handle all on_change functions + # handle all non on_change functions if db_addon_fct not in ALL_ONCHANGE_ATTRIBUTES: if self.debug_log.onchange: self.logger.debug(f"non on-change function detected. Skip update.") @@ -1308,7 +1315,7 @@ def _all_items(self) -> list: # Public functions / Using item_path ######################################### - def gruenlandtemperatursumme(self, item_path: str, year: Union[int, str] = None) -> Union[int, None]: + def gruenlandtemperatursumme(self, item_path: str, year: Union[int, str] = None, ignore_value_list: list = None) -> Union[int, None]: """ Query database for gruenlandtemperatursumme for given year or year https://de.wikipedia.org/wiki/Gr%C3%BCnlandtemperatursumme @@ -1324,9 +1331,9 @@ def gruenlandtemperatursumme(self, item_path: str, year: Union[int, str] = None) item = self.items.return_item(item_path) if item: - return self._handle_gruenlandtemperatursumme(item, year) + return self._handle_temp_sums(func='gruendlandtempsumme', database_item=item, year=year, ignore_value_list=ignore_value_list) - def waermesumme(self, item_path: str, year: Union[int, str] = None, month: Union[int, str] = 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) -> Union[int, None]: """ Query database for waermesumme for given year or year/month https://de.wikipedia.org/wiki/W%C3%A4rmesumme @@ -1340,9 +1347,9 @@ def waermesumme(self, item_path: str, year: Union[int, str] = None, month: Union item = self.items.return_item(item_path) if item: - return self._handle_waermesumme(item, year, month, threshold) + return self._handle_temp_sums(func='waermesumme', database_item=item, year=year, month=month, ignore_value_list=ignore_value_list, params={'threshold': threshold}) - def kaeltesumme(self, item_path: str, year: Union[int, str] = None, month: Union[int, str] = 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) -> Union[int, None]: """ Query database for kaeltesumme for given year or year/month https://de.wikipedia.org/wiki/K%C3%A4ltesumme @@ -1355,63 +1362,37 @@ def kaeltesumme(self, item_path: str, year: Union[int, str] = None, month: Union item = self.items.return_item(item_path) if item: - return self._handle_kaeltesumme(item, year, month) - - def tagesmitteltemperatur(self, item_path: str, timeframe: str = None, count: int = None) -> list: - """ - Query database for tagesmitteltemperatur - https://www.dwd.de/DE/leistungen/klimadatendeutschland/beschreibung_tagesmonatswerte.html - - :param item_path: item object or item_id for which the query should be done - :param timeframe: time increment for determination - :param count: number of time increments starting from now to the left (into the past) - :return: tagesmitteltemperatur - """ - - if not timeframe: - timeframe = 'day' - - if not count: - count = 0 - - item = self.items.return_item(item_path) - if item: - count = to_int(count) - end = 0 - start = end + count - query_params = {'database_item': item, 'func': 'max', 'timeframe': translate_timeframe(timeframe), 'start': start, 'end': end} - return self._handle_tagesmitteltemperatur(**query_params) + return self._handle_temp_sums(func='kaeltesumme', database_item=item, year=year, month=month, ignore_value_list=ignore_value_list) - def wachstumsgradtage(self, item_path: str, year: Union[int, str] = None, method: 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) -> Union[int, None]: """ Query database for wachstumsgradtage https://de.wikipedia.org/wiki/Wachstumsgradtag :param item_path: item object or item_id for which the query should be done :param year: year the wachstumsgradtage should be calculated for - :param method: method to be used + :param variant: variant to be used :param threshold: Temperature in °C as threshold: Ein Tage mit einer Tagesdurchschnittstemperatur oberhalb des Schwellenwertes gilt als Wachstumsgradtag :return: wachstumsgradtage """ item = self.items.return_item(item_path) if item: - return self._handle_wachstumsgradtage(database_item=item, year=year, method=method, threshold=threshold) + return self._handle_temp_sums(func='wachstumsgradtage', database_item=item, year=year, ignore_value_list=ignore_value_list, params={'threshold': threshold, 'variant': variant}) - def temperaturserie(self, item_path: str, year: Union[int, str] = None, method: str = 'avg_hour') -> Union[list, None]: + 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]: """ - Query database for wachstumsgradtage - https://de.wikipedia.org/wiki/Wachstumsgradtag + Query database for temperaturserie :param item_path: item object or item_id for which the query should be done :param year: year the wachstumsgradtage should be calculated for - :param method: Calculation method - :return: wachstumsgradtage + :param data_con_func: data concentration function + :return: temperature series """ item = self.items.return_item(item_path) if item: - return self._handle_temperaturserie(item, year, method) + return self._handle_temp_sums(func='temperaturserie', database_item=item, year=year, ignore_value_list=ignore_value_list, params={'data_con_func': data_con_func}) def query_item(self, func: str, item_path: str, timeframe: str, start: int = None, end: int = 0, group: str = None, group2: str = None, ignore_value_list=None) -> list: item = self.items.return_item(item_path) @@ -1647,98 +1628,76 @@ def _handle_zaehlerstand_serie(self, query_params: dict) -> list: return series - def _handle_kaeltesumme(self, database_item: Item, year: Union[int, str] = None, month: Union[int, str] = None) -> Union[int, None]: + def _handle_temp_sums(self, func: str, database_item: Item, year: Union[int, str] = None, month: Union[int, str] = None, ignore_value_list: list = None, params: dict = {}) -> Union[list, None]: """ - Query database for kaeltesumme for given year or year/month - https://de.wikipedia.org/wiki/K%C3%A4ltesumme - + Calculates diverse temperature sums and day counts + + :param func: defines which temperature sum or count should be calculated :param database_item: item object or item_id for which the query should be done :param year: year the kaeltesumme should be calculated for :param month: month the kaeltesumme should be calculated for - :return: kaeltesumme - """ - - if self.debug_log.prepare: - self.logger.debug(f"called with {database_item=}, {year=}, {month=}") - - # check validity of given year - if not self._valid_year(year): - self.logger.error(f"Year for item={database_item.path()} was {year}. This is not a valid year. Query cancelled.") - return - - # get datetime of today - today = self.shtime.today(offset=0) - - # define year - if not year or year == 'current': - if today < datetime.date(int(today.year), 9, 21): - year = today.year - 1 - else: - year = today.year - - # define start_date and end_date - if month is None: - start_date = datetime.date(int(year), 9, 21) - end_date = datetime.date(int(year) + 1, 3, 22) - 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) - else: - self.logger.error(f"Month for item={database_item.path()} was {month}. This is not a valid month. Query cancelled.") - return - - # define start / end - if start_date > today: - self.logger.error(f"Start time for query of item={database_item.path()} is in future. Query cancelled.") - return - - start = (today - start_date).days - end = (today - end_date).days if end_date < today else 0 - if start < end: - self.logger.error(f"End time for query of item={database_item.path()} is before start time. Query cancelled.") - return - - # get raw data as list - if self.debug_log.prepare: - self.logger.debug("try to get raw data") - raw_data = self._prepare_value_list(database_item=database_item, timeframe='day', start=start, end=end, method='avg_hour') - if self.debug_log.prepare: - self.logger.debug(f"raw_value_list={raw_data=}") - - # calculate value - if raw_data is None: - return - elif isinstance(raw_data, list): - # akkumulieren alle negativen Werte + :param params: params to be used for executing function (see below) + :return: temperature sum or day count + + - kaeltesumme: Kältesumme nach https://de.wikipedia.org/wiki/K%C3%A4ltesumme + - waermesumme: Wärmesumme https://de.wikipedia.org/wiki/W%C3%A4rmesumme + params: threshold + - gruenlandtempsumme: Grünlandtemperatursumme: https://de.wikipedia.org/wiki/Gr%C3%BCnlandtemperatursumme + - wachstumsgradtage: Wachstumsgradtage https://de.wikipedia.org/wiki/Wachstumsgradtag + params: 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 + - heisse_tage: Heiße Tage, Anzahl der Tage mit Tmax ≥ 30 °C + - tropennaechte: Tropennächte, Anzahl der Tage mit Tmin ≥ 20 °C + - sommertage: Sommertage, Anzahl der Tage mit Tmax ≥ 25 °C + - heiztage: Heiztage, Anzahl der Tage mit Tmed < 15 °C / 12 °C + - vegetationstage: Vegetationstage, Anzahl der Tage mit Tmed ≥ 5 °C + - frosttage: Frosttage, Anzahl der Tage mit Tmin < 0 °C + - eistage: Eistage, Anzahl der Tage mit Tmax < 0 °C + """ + + timeframe = {1: ((0, 9, 21), (1, 3, 22)), + 2: ((0, 1, 1), (0, 9, 21)), + 3: ((0, 1, 1), (0, 12, 31))} + + defaults = {'kaeltesumme': {'start_end': timeframe[1], 'data_con_func': 'first_hour_avg_day'}, + 'waermesumme': {'start_end': timeframe[2], 'data_con_func': 'first_hour_avg_day'}, + 'gruenlandtempsumme': {'start_end': timeframe[2], 'data_con_func': 'first_hour_avg_day'}, + 'wachstumsgradtage': {'start_end': timeframe[2], 'data_con_func': 'minmax_day'}, + 'temperaturserie': {'start_end': timeframe[2], 'data_con_func': params.get('data_con_func', 'avg_hour')}, + 'wuestentage': {'start_end': timeframe[3], 'data_con_func': 'minmax_day'}, + 'heisse_tage': {'start_end': timeframe[3], 'data_con_func': 'minmax_day'}, + 'tropennaechte': {'start_end': timeframe[3], 'data_con_func': 'minmax_day'}, + 'sommertage': {'start_end': timeframe[3], 'data_con_func': 'minmax_day'}, + 'heiztage': {'start_end': timeframe[3], 'data_con_func': 'first_hour_avg_day'}, + 'vegetationstage': {'start_end': timeframe[3], 'data_con_func': 'first_hour_avg_day'}, + 'frosttage': {'start_end': timeframe[3], 'data_con_func': 'minmax_day'}, + 'eistage': {'start_end': timeframe[3], 'data_con_func': 'minmax_day'}, + } + + def kaeltesumme() -> float: + """Berechnung der Kältesumme durch Akkumulieren aller negativen Tagesdurchschnittstemperaturen im Abfragezeitraum + + :return: value of waermesumme + """ + ks = 0 for entry in raw_data: if entry[1] < 0: ks -= entry[1] return int(round(ks, 0)) - def _handle_waermesumme(self, database_item: Item, year: Union[int, str] = None, month: Union[int, str] = None, threshold: int = 0) -> Union[int, None]: - """ - Query database for waermesumme for given year or year/month - https://de.wikipedia.org/wiki/W%C3%A4rmesumme - - :param database_item: item object or item_id for which the query should be done - :param year: year the waermesumme should be calculated for; "current" for current year - :param month: month the waermesumme should be calculated for - :return: waermesumme - """ + def waermesumme() -> float: + """Berechnung der Wärmesumme durch Akkumulieren aller Tagesdurchschnittstemperaturen im Abfragezeitraum, die größer/gleich dem Schwellenwert sind - # get raw data as list - raw_data = self._prepare_waermesumme(database_item=database_item, year=year, month=month) - if self.debug_log.prepare: - self.logger.debug(f"raw_value_list={raw_data=}") - - # set threshold to min 0 - threshold = max(0, threshold) + :return: value of waermesumme + """ + + # get threshold and set to min 0 + threshold = params.get('threshold', 10) + threshold = max(0, threshold) - # calculate value - if raw_data is None: - return - elif isinstance(raw_data, list): # akkumulieren alle Werte, größer/gleich Schwellenwert ws = 0 for entry in raw_data: @@ -1746,27 +1705,12 @@ def _handle_waermesumme(self, database_item: Item, year: Union[int, str] = None, ws += entry[1] return int(round(ws, 0)) - def _handle_gruenlandtemperatursumme(self, database_item: Item, year: Union[int, str] = None) -> Union[int, None]: - """ - Query database for gruenlandtemperatursumme for given year or year/month - https://de.wikipedia.org/wiki/Gr%C3%BCnlandtemperatursumme - - :param database_item: item object for which the query should be done - :param year: year the gruenlandtemperatursumme should be calculated for - :return: gruenlandtemperatursumme - """ - - # get raw data as list - raw_data = self._prepare_waermesumme(database_item=database_item, year=year) - if self.debug_log.prepare: - self.logger.debug(f"raw_data={raw_data}") - - # calculate value - if raw_data is None: - return + def gruenlandtempsumme() -> float: + """Berechnung der Grünlandtemperatursumme durch Akkumulieren alle positiven Tagesmitteltemperaturen, im Januar gewichtet mit 50%, im Februar mit 75% - elif isinstance(raw_data, list): - # akkumulieren alle positiven Tagesmitteltemperaturen, im Januar gewichtet mit 50%, im Februar mit 75% + :return: value of gruenlandtempsumme + """ + gts = 0 for entry in raw_data: timestamp, value = entry @@ -1779,179 +1723,142 @@ def _handle_gruenlandtemperatursumme(self, database_item: Item, year: Union[int, gts += value return int(round(gts, 0)) - def _handle_wachstumsgradtage(self, database_item: Item, year: Union[int, str] = None, method: int = 0, threshold: int = 10) -> Union[list, float, None]: - """ - Calculate "wachstumsgradtage" for given year with temperature threshold - https://de.wikipedia.org/wiki/Wachstumsgradtag - - :param database_item: item object or item_id for which the query should be done - :param year: year the wachstumsgradtage should be calculated for - :param method: calculation method to be used - :param threshold: temperature in °C as threshold for evaluation - :return: wachstumsgradtage - """ - - if not self._valid_year(year): - self.logger.error(f"Year for item={database_item.path()} was {year}. This is not a valid year. Query cancelled.") - return - - # get datetime of today - today = self.shtime.today(offset=0) - - # define year - if not year or year == 'current': - year = today.year - - # define start_date, end_date - start_date = datetime.date(int(year), 1, 1) - end_date = datetime.date(int(year), 9, 21) - - # check start_date - if start_date > today: - self.logger.info(f"Start time for query of item={database_item.path()} is in future. Query cancelled.") - return - - # define start / end - start = (today - start_date).days - end = (today - end_date).days if end_date < today else 0 - - # check end - if start < end: - self.logger.error(f"End time for query of item={database_item.path()} is before start time. Query cancelled.") - return - - # get raw data as list - raw_data = self._prepare_value_list(database_item=database_item, timeframe='day', start=start, end=end, method='minmax_hour') - if self.debug_log.prepare: - self.logger.debug(f"raw_value_list={raw_data}") - - # calculate value - if raw_data is None: - return - - if isinstance(raw_data, list): - # Die Berechnung des einfachen Durchschnitts // akkumuliere positive Differenz aus Mittelwert aus Tagesminimaltemperatur und Tagesmaximaltemperatur limitiert auf 30°C und Schwellenwert + def wachstumsgradtage() -> Union[list, float, None]: + """Berechnet die Wachstumsgradtage noch 3 möglichen Methoden und gibt entweder den Gesamtwert oder eine Liste mit kumulierten Werten pro Tag zurück + + variant 1: Berechnung des einfachen Durchschnitts + variant 2: modifizierte Berechnung des einfachen Durchschnitts. + variant 3: Zähle Tage, bei denen die Tagesmitteltemperatur oberhalb des Schwellenwertes lag + + 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', [...], ...] + """ + + # define defaults wgte = 0 wgte_list = [] - if method == 0 or method == 10: + + # get threshold and set to min 0 + threshold = params.get('threshold', 10) + threshold = max(0, threshold) + + # get variant + variant = params.get('variant', 0) + + # get result type + result = params.get('result', 'value') + + # Berechnung des einfachen Durchschnitts + if variant == 0: self.logger.info(f"Calculate 'Wachstumsgradtag' according to 'Berechnung des einfachen Durchschnitts'.") - for entry in raw_data: - timestamp, min_val, max_val = entry - wgt = (((min_val + min(30, max_val)) / 2) - threshold) - if wgt > 0: - wgte += wgt - wgte_list.append([timestamp, int(round(wgte, 0))]) - if method == 0: - return int(round(wgte, 0)) - else: - return wgte_list - # Die modifizierte Berechnung des einfachen Durchschnitts. // akkumuliere positive Differenz aus Mittelwert aus Tagesminimaltemperatur mit mind Schwellentemperatur und Tagesmaximaltemperatur limitiert auf 30°C und Schwellenwert - elif method == 1 or method == 11: + elif variant == 1: self.logger.info(f"Calculate 'Wachstumsgradtag' according to 'Modifizierte Berechnung des einfachen Durchschnitts'.") - for entry in raw_data: - timestamp, min_val, max_val = entry - wgt = (((max(threshold, min_val) + min(30.0, max_val)) / 2) - threshold) - if wgt > 0: - wgte += wgt - wgte_list.append([timestamp, int(round(wgte, 0))]) - if method == 1: - return int(round(wgte, 0)) - else: - return wgte_list - # Zähle Tage, bei denen die Tagesmitteltemperatur oberhalb des Schwellenwertes lag - elif method == 2 or method == 12: + elif variant == 2: self.logger.info(f"Calculate 'Wachstumsgradtag' according to 'Anzahl der Tage, bei denen die Tagesmitteltemperatur oberhalb des Schwellenwertes lag'.") - for entry in raw_data: - timestamp, min_val, max_val = entry + else: + self.logger.warning(f"Requested variant of 'Wachstumsgradtag' not defined. Aborting...") + return + + for entry in raw_data: + timestamp, min_val, max_val = entry + + if variant == 0: + wgt = (((min_val + min(30, max_val)) / 2) - threshold) + elif variant == 1: + wgt = (((max(threshold, min_val) + min(30.0, max_val)) / 2) - threshold) + elif variant == 2: wgt = (((min_val + min(30, max_val)) / 2) - threshold) - if wgt > 0: - wgte += 1 - wgte_list.append([timestamp, wgte]) - if method == 0: - return wgte else: - return wgte_list + wgt = None - else: - self.logger.info(f"Method for 'Wachstumsgradtag' calculation not defined.'") + if wgt and wgt > 0: + wgte += wgt + wgte_list.append([timestamp, int(round(wgte, 0))]) - def _handle_temperaturserie(self, database_item: Item, year: Union[int, str] = None, method: str = 'avg_hour') -> Union[list, None]: - """ - provide list of lists having timestamp and temperature(s) per day + if result == 'series': + return wgte_list + else: + return int(round(wgte, 0)) - :param database_item: item object or item_id for which the query should be done - :param year: year the wachstumsgradtage should be calculated for - :param method: calculation method to be used - :return: list of temperatures - """ + def temperaturserie() -> list: + """provide list of lists having timestamp and temperature(s) per day""" - if not self._valid_year(year): - self.logger.error(f"Year for item={database_item.path()} was {year}. This is not a valid year. Query cancelled.") - return + return raw_data - # get datetime of today - today = self.shtime.today(offset=0) + def wuestentage() -> int: + """provide number day counted as Wüstentag with Tmax ≥ 35°C""" + return _count(operator.ge, 'max', 35) - # define year - if not year or year == 'current': - year = today.year + def heisse_tage() -> int: + """provide number day counted as heißer Tag with Tmax ≥ 30°C""" + return _count(operator.ge, 'max', 30) - # define start_date, end_date - start_date = datetime.date(int(year), 1, 1) - end_date = datetime.date(int(year), 12, 31) + def tropennaechte() -> int: + """provide number day counted as Tropnenacht with Tmin ≥ 20 °C""" + return _count(operator.ge, 'min', 20) - # check start_date - if start_date > today: - self.logger.info(f"Start time for query of item={database_item.path()} is in future. Query cancelled.") - return + def sommertage() -> int: + """provide number day counted as Sommertag with Tmax ≥ 25°C""" + return _count(operator.ge, 'max', 25) - # define start / end - start = (today - start_date).days - end = (today - end_date).days if end_date < today else 0 + def frosttage() -> int: + """provide number day counted as Frosttag with Tmin < 0°C""" + return _count(operator.lt, 'min', 0) - # check end - if start < end: - self.logger.error(f"End time for query of item={database_item.path()} is before start time. Query cancelled.") - return + def eistage() -> int: + """provide number day counted as Frosttag with Tmax < 0°C""" + return _count(operator.lt, 'max', 0) - # get raw data as list - temp_list = self._prepare_value_list(database_item=database_item, timeframe='day', start=start, end=end, method=method) - if self.debug_log.prepare: - self.logger.debug(f"{temp_list=}") + def heiztage() -> int: + """provide number day counted as Frosttag with Tavg < 15°C""" + return _count(operator.lt, 'avg', 15) - return temp_list + def vegetationstage() -> int: + """provide number day counted as Frosttag with Tavg > 5°C""" + return _count(operator.ge, 'avg', 5) - def _prepare_waermesumme(self, database_item: Item, year: Union[int, str] = None, month: Union[int, str] = None) -> Union[list, None]: - """Prepares raw data for waermesumme""" + 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 - # check validity of given year - if not self._valid_year(year): - self.logger.error(f"Year for item={database_item.path()} was {year}. This is not a valid year. Query cancelled.") + self.logger.debug(f"{func=}, {database_item=}, {year=}, {month=}, {params=}") + + # check if func is defined + if func not in defaults: + self.logger.warning(f"_handle_temp_sums called with {func=}, which is not defined. Aborting...") return # get datetime of today today = self.shtime.today(offset=0) - # define year + # define year or check validity of given year if not year or year == 'current': year = today.year + elif not self._valid_year(year): + self.logger.error(f"Year for item={database_item.path()} was {year}. This is not a valid year. Aborting...") + return # define start_date, end_date if month is None: - start_date = datetime.date(int(year), 1, 1) - end_date = datetime.date(int(year), 9, 21) + ((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) 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) else: - self.logger.error(f"Month for item={database_item.path()} was {month}. This is not a valid month. Query cancelled.") + self.logger.error(f"Month for item={database_item.path()} was {month}. This is not a valid month. Aborting...") return # check start_date if start_date > today: - self.logger.info(f"Start time for query of item={database_item.path()} is in future. Query cancelled.") + self.logger.info(f"Start time for query of item={database_item.path()} is in future. Aborting...") return # define start / end @@ -1960,13 +1867,25 @@ def _prepare_waermesumme(self, database_item: Item, year: Union[int, str] = None # check end if start < end: - self.logger.error(f"End time for query of item={database_item.path()} is before start time. Query cancelled.") + self.logger.error(f"End time for query of item={database_item.path()} is before start time. Aborting...") + return + + # get raw data as list + if self.debug_log.prepare: + self.logger.debug("try to get raw data") + data_con_func = defaults.get(func, {}).get('data_con_func') + raw_data = self._prepare_value_list(database_item=database_item, timeframe='day', start=start, end=end, ignore_value_list=ignore_value_list, data_con_func=data_con_func, cache=True) + if self.debug_log.prepare: + self.logger.debug(f"raw_value_list={raw_data}") + + # return None, if now raw data + if raw_data is None or not isinstance(raw_data, list): return - # return raw data as list - return self._prepare_value_list(database_item=database_item, timeframe='day', start=start, end=end, method='avg_hour') + # calculate value and return it + return locals()[func]() - def _prepare_value_list(self, database_item: Item, timeframe: str, start: int, end: int = 0, ignore_value_list=None, method: str = 'avg_hour') -> Union[list, None]: + def _prepare_value_list(self, database_item: Item, timeframe: str, start: int, end: int = 0, ignore_value_list=None, data_con_func: str = 'avg_day', cache: bool = False) -> Union[list, None]: """ returns list of lists having timestamp and values(s) per day / hour in format of regular database query @@ -1975,35 +1894,40 @@ def _prepare_value_list(self, database_item: Item, timeframe: str, start: int, e :param start: increments for timeframe from now to start :param end: increments for timeframe from now to end :param ignore_value_list: list of comparison operators for val_num, which will be applied during query - :param method: calculation method + :param data_con_func: data concentration function - avg_day: determines average value per day of values within plugin - avg_hour: determines average value per hour of values within plugin - first_day: determines first value per day of values within plugin - first_hour: determines first value per hour of values within plugin - minmax_day: determines min and max value per day of values within plugin - minmax_hour: determines min and max value per hour of values within plugin + - first_hour_avg_day: 2-step concentration: 1) concentrate values within an hour by using first value 2) concentrate values by average for first value of each hour :return: list of list with [timestamp, value] """ - def _create_raw_value_dict(block: str) -> dict: + 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]} - :param block: defined the increment of datetimes, default is hour, further possible is 'day' + :param block: defined the increment of datetime, default is min, further possible is 'day' and 'hour' """ _value_dict = {} for _entry in raw_data: - dt = self._timestamp_to_datetime(_entry[0] / 1000) - dt = dt.replace(minute=0, second=0, microsecond=0) + ts = _entry[0] + if len(str(ts)) > 10: + ts = ts / 1000 + dt = self._timestamp_to_datetime(ts) + dt = dt.replace(second=0, microsecond=0, tzinfo=None) + if block == 'hour': + dt = dt.replace(minute=0) if block == 'day': - dt = dt.replace(hour=0) + dt = dt.replace(minute=0, hour=0) if dt not in _value_dict: _value_dict[dt] = [] _value_dict[dt].append(_entry[1]) - return dict(sorted(_value_dict.items())) - def _create_value_list_timestamp_value(option: str) -> list: + def _concentrate_values(option: str) -> list: """ Create list of list with [[timestamp1, value1], [timestamp2, value2], ...] based on value_dict in format of database query result values given in the list will be concentrated as per given option @@ -2015,7 +1939,7 @@ def _create_value_list_timestamp_value(option: str) -> list: """ _value_list = [] - # create nested list with timestamp, avg_value per hour/day + # create nested list with timestamp, avg_value or minmax per hour/day for entry in value_dict: _timestamp = self._datetime_to_timestamp(entry) if option == 'first': @@ -2027,33 +1951,64 @@ def _create_value_list_timestamp_value(option: str) -> list: return _value_list if self.debug_log.prepare: - self.logger.debug(f'called with database_item={database_item.path()}, {timeframe=}, {start=}, {end=}, {ignore_value_list=}, {method=}') + self.logger.debug(f'called with database_item={database_item.path()}, {timeframe=}, {start=}, {end=}, {ignore_value_list=}, {data_con_func=}') - # check method - if method in ['avg_day', 'avg_hour', 'minmax_day', 'minmax_hour', 'first_day', 'first_hour']: - _method, _block = method.split('_') - elif method in ['avg', 'minmax', 'first']: - _method = method - _block = 'hour' - else: - self.logger.warning(f"defined {method=} for _prepare_value_list unknown. Need to be 'avg_day', 'avg_hour', 'minmax_day', 'minmax_hour', 'first_day' or 'first_hour'. Aborting...") + if data_con_func not in ('avg', 'minmax', 'first', 'avg_day', 'avg_hour', 'minmax_day', 'minmax_hour', 'first_day','first_hour', 'first_hour_avg_day', 'avg_hour_avg_day'): + self.logger.warning(f"defined {data_con_func=} for _prepare_value_list unknown. Need to be 'avg', 'minmax', 'first', 'avg_day', 'avg_hour', 'minmax_day', 'minmax_hour', 'first_day','first_hour', 'first_hour_avg_day' or 'avg_hour_avg_day'. Aborting...") return + # define defaults + _data_con1 = _block1 = _data_con2 = _block2 = result = None + + # check data_con_func + data_con_func_list = data_con_func.split('_') + if len(data_con_func_list) == 1: + _data_con1 = data_con_func_list + _block = 'hour' + elif len(data_con_func_list) == 2: + _data_con1, _block1 = data_con_func_list + elif len(data_con_func_list) == 4: + _data_con1, _block1, _data_con2, _block2 = data_con_func_list + + # define quere params + _query_params = {'func': 'raw', 'database_item': database_item, 'timeframe': timeframe, 'start': start, 'end': end, 'ignore_value_list': ignore_value_list} + # get raw data from database - raw_data = self._query_item(func='raw', database_item=database_item, timeframe=timeframe, start=start, end=end, ignore_value_list=ignore_value_list) - if raw_data == [[None, None]] or raw_data == [[0, 0]]: - self.logger.info(f"no valid data from database query for item={database_item.path()} received during _prepare_value_list. Aborting...") - return + if not cache or str(_query_params) not in self.value_list_raw_data: + raw_data = self._query_item(**_query_params) - # create nested dict with values - value_dict = _create_raw_value_dict(block=_block) - if self.debug_log.prepare: - self.logger.debug(f"{value_dict=}") + if raw_data == [[None, None]] or raw_data == [[0, 0]]: + self.logger.info(f"no valid data from database query for item={database_item.path()} received during _prepare_value_list. Aborting...") + return - # return value list - result = _create_value_list_timestamp_value(option=_method) - if self.debug_log.prepare: - self.logger.debug(f"{method=}, {result=}") + if cache: + self.logger.debug(f"raw_data for {_query_params=} put to cache.") + self.value_list_raw_data[str(_query_params)] = raw_data + else: + self.logger.debug(f"raw_data for {_query_params=} read from cache.") + raw_data = self.value_list_raw_data[str(_query_params)] + + if _data_con1 and _block1: + # create nested dict with values + value_dict = _group_value_by_datetime_block(block=_block1) + if self.debug_log.prepare: + self.logger.debug(f"{_block1=}, {value_dict=}") + + # return value list + result = _concentrate_values(option=_data_con1) + if self.debug_log.prepare: + self.logger.debug(f"{_data_con1=}, {result=}") + + if _data_con2 and _block2: + # create nested dict with values + value_dict = _group_value_by_datetime_block(block=_block2) + if self.debug_log.prepare: + self.logger.debug(f"{_block2=}, {value_dict=}") + + # return value list + result = _concentrate_values(option=_data_con2) + if self.debug_log.prepare: + self.logger.debug(f"{_data_con2=}, {result=}") return result @@ -2355,6 +2310,8 @@ def _init_cache_dicts(self) -> None: YEAR: {} } + self.value_list_raw_data = {} + def _clean_item_cache(self, item: Union[str, Item]) -> None: """set cached values for item to None""" @@ -2455,15 +2412,15 @@ def _datetime_to_timestamp(self, dt: datetime) -> int: return int(dt.replace(tzinfo=self.shtime.tzinfo()).timestamp()) - def _timestamp_to_datetime(self, timestamp: int) -> datetime: + def _timestamp_to_datetime(self, timestamp: float) -> datetime: """Parse timestamp from db query to datetime""" - return datetime.datetime.fromtimestamp(timestamp / 1000, tz=self.shtime.tzinfo()) + return datetime.datetime.fromtimestamp(timestamp, tz=self.shtime.tzinfo()) def _timestamp_to_timestring(self, timestamp: int) -> str: """Parse timestamp from db query to string representing date and time""" - return self._timestamp_to_datetime(timestamp).strftime('%Y-%m-%d %H:%M:%S') + return self._timestamp_to_datetime(timestamp / 1000).strftime('%Y-%m-%d %H:%M:%S') def _valid_year(self, year: Union[int, str]) -> bool: """Check if given year is digit and within allowed range""" @@ -2548,7 +2505,7 @@ def _query_log_timestamp(self, func: str, item_id: int, ts_start: int, ts_end: i 'first': 'ORDER BY time ASC ', 'last': 'ORDER BY time DESC ', } - + _limit = { 'next': 'LIMIT 1 ', 'first': 'LIMIT 1 ', @@ -2632,7 +2589,8 @@ def _read_log_oldest(self, item_id: int) -> int: params = {'item_id': item_id} query = "SELECT min(time) FROM log WHERE item_id = :item_id;" - return self._fetchall(query, params)[0][0] + result = self._fetchall(query, params) + return None if result is None else result[0][0] def _read_log_newest(self, item_id: int) -> int: """ @@ -2644,7 +2602,8 @@ def _read_log_newest(self, item_id: int) -> int: params = {'item_id': item_id} query = "SELECT max(time) FROM log WHERE item_id = :item_id;" - return self._fetchall(query, params)[0][0] + result = self._fetchall(query, params) + return None if result is None else result[0][0] def _read_log_timestamp(self, item_id: int, timestamp: int) -> Union[list, None]: """ diff --git a/db_addon/item_attributes.py b/db_addon/item_attributes.py index 7c04066fc..e1d94b417 100644 --- a/db_addon/item_attributes.py +++ b/db_addon/item_attributes.py @@ -29,11 +29,11 @@ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # ALL_ONCHANGE_ATTRIBUTES = ['verbrauch_heute', 'verbrauch_woche', 'verbrauch_monat', 'verbrauch_jahr', 'minmax_heute_min', 'minmax_heute_max', 'minmax_heute_avg', 'minmax_woche_min', 'minmax_woche_max', 'minmax_monat_min', 'minmax_monat_max', 'minmax_jahr_min', 'minmax_jahr_max', 'tagesmitteltemperatur_heute'] -ALL_DAILY_ATTRIBUTES = ['verbrauch_heute_minus1', 'verbrauch_heute_minus2', 'verbrauch_heute_minus3', 'verbrauch_heute_minus4', 'verbrauch_heute_minus5', 'verbrauch_heute_minus6', 'verbrauch_heute_minus7', 'verbrauch_rolling_12m_heute_minus1', 'verbrauch_jahreszeitraum_minus1', 'verbrauch_jahreszeitraum_minus2', 'verbrauch_jahreszeitraum_minus3', 'zaehlerstand_heute_minus1', 'zaehlerstand_heute_minus2', 'zaehlerstand_heute_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', 'tagesmitteltemperatur_heute_minus1', 'tagesmitteltemperatur_heute_minus2', 'tagesmitteltemperatur_heute_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', 'tagesmitteltemperatur', 'wachstumsgradtage'] +ALL_DAILY_ATTRIBUTES = ['verbrauch_heute_minus1', 'verbrauch_heute_minus2', 'verbrauch_heute_minus3', 'verbrauch_heute_minus4', 'verbrauch_heute_minus5', 'verbrauch_heute_minus6', 'verbrauch_heute_minus7', 'verbrauch_rolling_12m_heute_minus1', 'verbrauch_jahreszeitraum_minus1', 'verbrauch_jahreszeitraum_minus2', 'verbrauch_jahreszeitraum_minus3', 'zaehlerstand_heute_minus1', 'zaehlerstand_heute_minus2', 'zaehlerstand_heute_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', 'tagesmitteltemperatur_heute_minus1', 'tagesmitteltemperatur_heute_minus2', 'tagesmitteltemperatur_heute_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_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'] ALL_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'] ALL_YEARLY_ATTRIBUTES = ['verbrauch_jahr_minus1', 'verbrauch_jahr_minus2', '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_NEED_PARAMS_ATTRIBUTES = ['kaeltesumme', 'waermesumme', 'gruenlandtempsumme', 'tagesmitteltemperatur', 'wachstumsgradtage', 'db_request', 'minmax', 'minmax_last', 'verbrauch', 'zaehlerstand'] +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_woche', 'verbrauch_monat', 'verbrauch_jahr', 'verbrauch_heute_minus1', 'verbrauch_heute_minus2', 'verbrauch_heute_minus3', 'verbrauch_heute_minus4', 'verbrauch_heute_minus5', 'verbrauch_heute_minus6', 'verbrauch_heute_minus7', '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_rolling_12m_heute_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_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_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'] @@ -58,4 +58,5 @@ 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_COMPLEX_ATTRIBUTES = ['kaeltesumme', 'waermesumme', 'gruenlandtempsumme', 'tagesmitteltemperatur', 'wachstumsgradtage', 'db_request', 'minmax', 'minmax_last', 'verbrauch', 'zaehlerstand'] +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 d0bd1436f..cdf36d71c 100644 --- a/db_addon/item_attributes_master.py +++ b/db_addon/item_attributes_master.py @@ -27,6 +27,8 @@ DOC_FILE_NAME = 'user_doc.rst' +PLUGIN_VERSION = '1.2.3' + ITEM_ATTRIBUTES = { 'db_addon_fct': { 'verbrauch_heute': {'cat': 'verbrauch', 'sub_cat': 'onchange', 'item_type': 'num', 'calc': 'onchange', 'params': False, 'description': 'Verbrauch am heutigen Tag (Differenz zwischen aktuellem Wert und den Wert am Ende des vorherigen Tages)'}, @@ -136,11 +138,19 @@ 'serie_tagesmittelwert_tag_stunde_30d': {'cat': 'serie', 'sub_cat': 'mittel_d_h', 'item_type': 'list', 'calc': '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', 'calc': 'no', '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', 'calc': 'no', 'params': False, 'description': 'Ausgabe des Timestamp des ältesten Eintrages des entsprechenden "Parent-Items" mit database Attribut'}, - 'kaeltesumme': {'cat': 'complex', 'sub_cat': 'summe', 'item_type': 'num', 'calc': 'daily', 'params': True, 'description': 'Berechnet die Kältesumme für einen Zeitraum, db_addon_params: (year=mandatory, month=optional)'}, - 'waermesumme': {'cat': 'complex', 'sub_cat': 'summe', 'item_type': 'num', 'calc': 'daily', 'params': True, 'description': 'Berechnet die Wärmesumme für einen Zeitraum, db_addon_params: (year=mandatory, month=optional)'}, - 'gruenlandtempsumme': {'cat': 'complex', 'sub_cat': None, 'item_type': 'num', 'calc': 'daily', 'params': True, 'description': 'Berechnet die Grünlandtemperatursumme für einen Zeitraum, db_addon_params: (year=mandatory)'}, + 'kaeltesumme': {'cat': 'summe', 'sub_cat': None, 'item_type': 'num', 'calc': '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', 'calc': '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', 'calc': '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', 'calc': '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', 'calc': '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', 'calc': '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', 'calc': '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', 'calc': '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', 'calc': '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', 'calc': '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', 'calc': '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', 'calc': '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', 'calc': '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)'}, - 'wachstumsgradtage': {'cat': 'complex', 'sub_cat': None, 'item_type': 'num', 'calc': '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)'}, 'db_request': {'cat': 'complex', 'sub_cat': None, 'item_type': 'list', 'calc': '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', 'calc': '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', 'calc': '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)'}, @@ -211,7 +221,7 @@ def export_item_attributes_py(): 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['ALL_NEED_PARAMS_ATTRIBUTES'] = get_attrs(sub_dict={'params': True}) + 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'}) ATTRS['VERBRAUCH_ATTRIBUTES_TIMEFRAME'] = get_attrs(sub_dict={'cat': 'verbrauch', 'sub_cat': 'timeframe'}) @@ -236,6 +246,7 @@ def export_item_attributes_py(): ATTRS['SERIE_ATTRIBUTES_MITTEL_H1'] = get_attrs(sub_dict={'cat': 'serie', 'sub_cat': 'mittel_h1'}) ATTRS['SERIE_ATTRIBUTES_MITTEL_D_H'] = get_attrs(sub_dict={'cat': 'serie', 'sub_cat': 'mittel_d_h'}) ATTRS['ALL_GEN_ATTRIBUTES'] = get_attrs(sub_dict={'cat': 'gen'}) + ATTRS['ALL_SUMME_ATTRIBUTES'] = get_attrs(sub_dict={'cat': 'summe'}) ATTRS['ALL_COMPLEX_ATTRIBUTES'] = get_attrs(sub_dict={'cat': 'complex'}) # create file and write header @@ -314,7 +325,7 @@ def update_plugin_yaml_item_attributes(): def check_plugin_yaml_structs(): # check structs for wrong attributes print() - print(f'D) Checking used attributes in structs defined in {FILENAME_PLUGIN} ') + print(f'C) Checking used attributes in structs defined in {FILENAME_PLUGIN} ') # open plugin.yaml and update yaml = ruamel.yaml.YAML() @@ -351,7 +362,7 @@ def get_all_keys(d): def update_user_doc(): # Update user_doc.rst print() - print(f'C) Start updating DB-Addon-Attributes and descriptions in {DOC_FILE_NAME}!"') + print(f'D) 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", diff --git a/db_addon/plugin.yaml b/db_addon/plugin.yaml index 5f719b5b9..7de29be1f 100644 --- a/db_addon/plugin.yaml +++ b/db_addon/plugin.yaml @@ -187,8 +187,16 @@ item_attributes: - kaeltesumme - waermesumme - gruenlandtempsumme - - tagesmitteltemperatur - wachstumsgradtage + - wuestentage + - heisse_tage + - tropennaechte + - sommertage + - heiztage + - vegetationstage + - frosttage + - eistage + - tagesmitteltemperatur - db_request - minmax - minmax_last @@ -303,11 +311,19 @@ item_attributes: - Stundenmittelwert pro Tag der letzten 30 Tage (bspw. zur Berechnung der Tagesmitteltemperatur basierend auf den Mittelwert der Temperatur pro Stunde - Ausgabe des ältesten Wertes des entsprechenden "Parent-Items" mit database Attribut - Ausgabe des Timestamp des ältesten Eintrages des entsprechenden "Parent-Items" mit database Attribut - - 'Berechnet die Kältesumme für einen Zeitraum, db_addon_params: (year=mandatory, month=optional)' - - 'Berechnet die Wärmesumme für einen Zeitraum, db_addon_params: (year=mandatory, month=optional)' - - 'Berechnet die Grünlandtemperatursumme für einen Zeitraum, db_addon_params: (year=mandatory)' - - Berechnet die Tagesmitteltemperatur auf Basis der stündlichen Durchschnittswerte eines Tages für die angegebene Anzahl von Tagen (timeframe=day, count=integer) + - 'Berechnet die Kältesumme für einen Zeitraum, db_addon_params: (year=optional, month=optional)' + - 'Berechnet die Wärmesumme für einen Zeitraum, db_addon_params: (year=optional, month=optional)' + - 'Berechnet die Grünlandtemperatursumme für einen Zeitraum, db_addon_params: (year=optional)' - Berechnet die Wachstumsgradtage auf Basis der stündlichen Durchschnittswerte eines Tages für das laufende Jahr mit an Angabe des Temperaturschwellenwertes (threshold=Schwellentemperatur) + - 'Berechnet die Anzahl der Wüstentage des Jahres, db_addon_params: (year=optional)' + - 'Berechnet die Anzahl der heissen Tage des Jahres, db_addon_params: (year=optional)' + - 'Berechnet die Anzahl der Tropennächte des Jahres, db_addon_params: (year=optional)' + - 'Berechnet die Anzahl der Sommertage des Jahres, db_addon_params: (year=optional)' + - 'Berechnet die Anzahl der Heiztage des Jahres, db_addon_params: (year=optional)' + - 'Berechnet die Anzahl der Vegatationstage des Jahres, db_addon_params: (year=optional)' + - 'Berechnet die Anzahl der Frosttage des Jahres, db_addon_params: (year=optional)' + - 'Berechnet die Anzahl der Eistage des Jahres, db_addon_params: (year=optional)' + - Berechnet die Tagesmitteltemperatur auf Basis der stündlichen Durchschnittswerte eines Tages für die angegebene Anzahl von Tagen (timeframe=day, count=integer) - 'Abfrage der DB: db_addon_params: (func=mandatory, item=mandatory, timespan=mandatory, start=optional, end=optional, count=optional, group=optional, group2=optional)' - 'Berechnet einen min/max/avg Wert für einen bestimmen Zeitraum: db_addon_params: (func=mandatory, timeframe=mandatory, start=mandatory)' - '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)' @@ -425,8 +441,16 @@ item_attributes: - num - num - num - - list - num + - num + - num + - num + - num + - num + - num + - num + - num + - list - list - num - num @@ -546,6 +570,14 @@ item_attributes: - daily - daily - daily + - daily + - daily + - daily + - daily + - daily + - daily + - daily + - daily - group - timeframe - timeframe diff --git a/db_addon/user_doc.rst b/db_addon/user_doc.rst index 442888df7..d95d4658d 100644 --- a/db_addon/user_doc.rst +++ b/db_addon/user_doc.rst @@ -317,16 +317,32 @@ db_addon_fct - general_oldest_log: Ausgabe des Timestamp des ältesten Eintrages des entsprechenden "Parent-Items" mit database Attribut | Berechnung: no | Item-Type: list -- kaeltesumme: Berechnet die Kältesumme für einen Zeitraum, db_addon_params: (year=mandatory, month=optional) | Berechnung: daily | Item-Type: num +- kaeltesumme: Berechnet die Kältesumme für einen Zeitraum, db_addon_params: (year=optional, month=optional) | Berechnung: daily | Item-Type: num -- waermesumme: Berechnet die Wärmesumme für einen Zeitraum, db_addon_params: (year=mandatory, month=optional) | Berechnung: daily | Item-Type: num +- waermesumme: Berechnet die Wärmesumme für einen Zeitraum, db_addon_params: (year=optional, month=optional) | Berechnung: daily | Item-Type: num -- gruenlandtempsumme: Berechnet die Grünlandtemperatursumme für einen Zeitraum, db_addon_params: (year=mandatory) | Berechnung: daily | Item-Type: num - -- tagesmitteltemperatur: Berechnet die Tagesmitteltemperatur auf Basis der stündlichen Durchschnittswerte eines Tages für die angegebene Anzahl von Tagen (timeframe=day, count=integer) | Berechnung: daily | Item-Type: list +- gruenlandtempsumme: Berechnet die Grünlandtemperatursumme für einen Zeitraum, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num - wachstumsgradtage: Berechnet die Wachstumsgradtage auf Basis der stündlichen Durchschnittswerte eines Tages für das laufende Jahr mit an Angabe des Temperaturschwellenwertes (threshold=Schwellentemperatur) | Berechnung: daily | Item-Type: num +- wuestentage: Berechnet die Anzahl der Wüstentage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num + +- heisse_tage: Berechnet die Anzahl der heissen Tage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num + +- tropennaechte: Berechnet die Anzahl der Tropennächte des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num + +- sommertage: Berechnet die Anzahl der Sommertage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num + +- heiztage: Berechnet die Anzahl der Heiztage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num + +- vegetationstage: Berechnet die Anzahl der Vegatationstage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num + +- frosttage: Berechnet die Anzahl der Frosttage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num + +- eistage: Berechnet die Anzahl der Eistage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num + +- tagesmitteltemperatur: Berechnet die Tagesmitteltemperatur auf Basis der stündlichen Durchschnittswerte eines Tages für die angegebene Anzahl von Tagen (timeframe=day, count=integer) | Berechnung: daily | Item-Type: list + - db_request: Abfrage der DB: db_addon_params: (func=mandatory, item=mandatory, timespan=mandatory, start=optional, end=optional, count=optional, group=optional, group2=optional) | Berechnung: group | Item-Type: list - minmax: Berechnet einen min/max/avg Wert für einen bestimmen Zeitraum: db_addon_params: (func=mandatory, timeframe=mandatory, start=mandatory) | Berechnung: timeframe | Item-Type: num @@ -390,6 +406,67 @@ Hinweise starker Systembelastung nützlich sein. +Konfiguration im Item +===================== + +direkt +------ +Bei der direkten Konfiguration wird das auszuwertende Database-Item durch das Plugin selbst bestimmt. Dazu muss die Konfiguration des +Attributes `db_addon_fct` oder eines entsprechenden `struct` direkt im Database-Item oder in der Itemstruktur bis zu 3 Ebenen darunter erfolgen. + +.. code-block:: yaml + wasserzaehler: + zaehlerstand: + type: num + knx_dpt: 12 + knx_cache: 5/3/4 + database: init + struct: + - db_addon.verbrauch_1 + +oder + +.. code-block:: yaml + wasserzaehler: + zaehlerstand: + type: num + knx_dpt: 12 + knx_cache: 5/3/4 + database: init + + auswertung: + type: foo + struct: + - db_addon.verbrauch_1 + + +indirekt +-------- +Bei der indirekten Konfiguration muss das auszuwertende Database-Item zusätzlich über das Attribut `db_addon_database_item` konfiguriert/angegeben werden. +Die Konfiguration kann somit frei im Itembaum erfolgen. Es wird hier der gleiche Syntax wie bei `eval_trigger` verwendet (Itempfad als String) + +.. code-block:: yaml + wasserzaehler: + zaehlerstand: + type: num + knx_dpt: 12 + knx_cache: 5/3/4 + database: init + + auswertungen: + wasser: + typ: foo + db_addon_database_item: wasserzaehler.zaehlerstand + db_addon_startup: yes + db_addon_ignore_value_list: ['!=0'] + struct: + - db_addon.verbrauch_1 + +Hinweis: +Da ein Zähler nicht 0 werden kann/sollte, aber beim Starten/Beenden von shNG auch 0 in die Datenbank geschrieben wird, kann man mit Hilfe des Attributs `db_addon_ignore_value_list` +diese Werte bei Abfragen der Datenbank maskieren. + + Beispiele ========= @@ -437,7 +514,7 @@ Soll bspw. die minimalen und maximalen Temperaturen ausgewertet werden, kann die Die Temperaturwerte werden in die Datenbank geschrieben und darauf basierend ausgewertet. Die structs 'db_addon.minmax_1' und 'db_addon.minmax_2' stellen entsprechende Items für die min/max Auswertung zur Verfügung. -| + Web Interface ============= From b1c44e2a7c0e8139d1ed1431c9184e24a137115d Mon Sep 17 00:00:00 2001 From: sisamiwe Date: Wed, 23 Aug 2023 16:16:04 +0200 Subject: [PATCH 10/18] DB_ADDON: - bugfixing methods - add all attributs containing 'heute' also with 'tag' - bugfix structs --- db_addon/__init__.py | 73 +++++--- db_addon/item_attributes.py | 28 +-- db_addon/item_attributes_master.py | 37 +++- db_addon/plugin.yaml | 278 +++++++++++++++++++++-------- db_addon/user_doc.rst | 60 +++++++ db_addon/webif/__init__.py | 3 +- 6 files changed, 361 insertions(+), 118 deletions(-) diff --git a/db_addon/__init__.py b/db_addon/__init__.py index 2cfb1369f..c0a809c29 100644 --- a/db_addon/__init__.py +++ b/db_addon/__init__.py @@ -60,9 +60,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.3' - # ToDo: remove revision - REVISION = 'H' + PLUGIN_VERSION = '1.2.4' def __init__(self, sh): """ @@ -254,7 +252,7 @@ def get_query_parameters_from_db_addon_fct() -> Union[dict, None]: elif db_addon_fct in ZAEHLERSTAND_ATTRIBUTES_TIMEFRAME: # handle functions 'zaehlerstand' in format 'zaehlerstand_timeframe_timedelta' like 'zaehlerstand_heute_minus1' - # func = 'max' + func = 'last' timeframe = translate_timeframe(db_addon_fct_vars[1]) end = to_int(split_sting_letters_numbers(db_addon_fct_vars[2])[1]) start = end @@ -272,7 +270,6 @@ def get_query_parameters_from_db_addon_fct() -> Union[dict, None]: 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]) - # end = to_int(db_addon_fct_vars[2][-1]) end = to_int(split_sting_letters_numbers(db_addon_fct_vars[2])[1]) start = end + 1 log_text = 'verbrauch_timeframe_timedelta' @@ -329,7 +326,6 @@ def get_query_parameters_from_db_addon_fct() -> Union[dict, None]: elif db_addon_fct in SERIE_ATTRIBUTES_ZAEHLERSTAND: # handle functions 'serie_zaehlerstand' in format 'serie_zaehlerstand_timeframe_start|group' like 'serie_zaehlerstand_tag_30d' - func = 'max' timeframe = translate_timeframe(db_addon_fct_vars[2]) start, group = split_sting_letters_numbers(db_addon_fct_vars[3]) start = to_int(start) @@ -339,7 +335,6 @@ def get_query_parameters_from_db_addon_fct() -> Union[dict, None]: elif db_addon_fct in SERIE_ATTRIBUTES_VERBRAUCH: # handle all functions of format 'serie_verbrauch_timeframe_start|group' like 'serie_verbrauch_tag_30d' - func = 'diff_max' timeframe = translate_timeframe(db_addon_fct_vars[2]) start, group = split_sting_letters_numbers(db_addon_fct_vars[3]) start = to_int(start) @@ -1054,6 +1049,14 @@ def handle_ondemand(self, item: Item) -> None: else: result = None + # handle all functions using temperature sums + elif db_addon_fct in ALL_SUMME_ATTRIBUTES: + new_params = {} + for entry in ('threshold', 'variant', 'result', 'data_con_func'): + if entry in params: + new_params.update({entry: params[entry]}) + result = self._handle_temp_sums(func=db_addon_fct, database_item=database_item, year=params.get('year'), month=params.get('month'), ignore_value_list=params.get('ignore_value_list'), params=new_params) + # handle info functions elif db_addon_fct == 'info_db_version': result = self._get_db_version() @@ -1066,14 +1069,6 @@ def handle_ondemand(self, item: Item) -> None: elif db_addon_fct == 'general_oldest_log': result = self._get_oldest_log(database_item) - # handle all functions using temperature sums - elif db_addon_fct in ALL_SUMME_ATTRIBUTES: - new_params = {} - for entry in ('threshold', 'variant', 'result', 'data_con_func'): - if entry in params: - new_params.update({entry: params[entry]}) - result = self._handle_temp_sums(func=db_addon_fct, database_item=database_item, year=params.get('year'), month=params.get('month'), ignore_value_list=params.get('ignore_value_list'), params=new_params) - # handle everything else else: result = self._query_item(**params)[0][1] @@ -1213,7 +1208,7 @@ def handle_tagesmittel(): continue # handle minmax on-change items tagesmitteltemperatur_heute, minmax_heute_avg - if db_addon_fct in ['tagesmitteltemperatur_heute', 'minmax_heute_avg']: + if db_addon_fct in TAGESMITTEL_ATTRIBUTES_ONCHANGE: new_value = handle_tagesmittel() # handle minmax on-change items like minmax_heute_max, minmax_heute_min, minmax_woche_max, minmax_woche_min..... @@ -1326,6 +1321,7 @@ 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 :return: gruenlandtemperatursumme """ @@ -1341,6 +1337,7 @@ def waermesumme(self, item_path: str, year: Union[int, str] = None, month: Union :param item_path: item object or item_id for which the query should be done :param year: year the waermesumme should be calculated for :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 :return: waermesumme """ @@ -1357,6 +1354,7 @@ def kaeltesumme(self, item_path: str, year: Union[int, str] = None, month: Union :param item_path: item object or item_id for which the query should be done :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 :return: kaeltesumme """ @@ -1371,6 +1369,7 @@ def wachstumsgradtage(self, item_path: str, year: Union[int, str] = None, ignore :param item_path: item object or item_id for which the query should be done :param year: year the wachstumsgradtage should be calculated for + :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 :return: wachstumsgradtage @@ -1386,6 +1385,7 @@ def temperaturserie(self, item_path: str, year: Union[int, str] = None, ignore_v :param item_path: item object or item_id for which the query should be done :param year: year the wachstumsgradtage should be calculated for + :param ignore_value_list: list of comparison operators for val_num, which will be applied during query :param data_con_func: data concentration function :return: temperature series """ @@ -1395,6 +1395,21 @@ def temperaturserie(self, item_path: str, year: Union[int, str] = None, ignore_v return self._handle_temp_sums(func='temperaturserie', database_item=item, year=year, ignore_value_list=ignore_value_list, params={'data_con_func': data_con_func}) def query_item(self, func: str, item_path: str, timeframe: str, start: int = None, end: int = 0, group: str = None, group2: str = None, ignore_value_list=None) -> list: + """ + Query database, format response and return it + + :param func: function, defined in query_item method to be used at query + :param item_path: item str or item_id for which the query should be done + :param timeframe: time increment für definition of start, end, count (day, week, month, year) + :param start: start of timeframe (oldest) for query given in x time increments (default = None, meaning complete database) + :param end: end of timeframe (newest) for query given in x time increments (default = 0, meaning today, end of last week, end of last month, end of last year) + :param group: first grouping parameter (default = None, possible values: day, week, month, year) + :param group2: second grouping parameter (default = None, possible values: day, week, month, year) + :param ignore_value_list: list of comparison operators for val_num, which will be applied during query + + :return: formatted query response + """ + item = self.items.return_item(item_path) if item is None: return [] @@ -1405,7 +1420,7 @@ def fetch_log(self, func: str, item_path: str, timeframe: str, start: int = None """ Query database, format response and return it - :param func: function to be used at query + :param func: sql function to be used at query :param item_path: item str or item_id for which the query should be done :param timeframe: time increment für definition of start, end, count (day, week, month, year) :param start: start of timeframe (oldest) for query given in x time increments (default = None, meaning complete database) @@ -1562,7 +1577,7 @@ def _handle_verbrauch_serie(self, query_params: dict) -> list: timeframe = query_params['timeframe'] start = query_params['start'] - for i in range(1, start): + 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) series.append([ts_end, value]) @@ -1621,14 +1636,14 @@ def _handle_zaehlerstand_serie(self, query_params: dict) -> list: timeframe = query_params['timeframe'] start = query_params['start'] - for i in range(1, start): + for i in range(start, 1, -1): value = self._handle_zaehlerstand({'database_item': database_item, 'timeframe': timeframe, 'start': i, 'end': i}) ts_start = self._get_start_end_as_timestamp(timeframe, i, i)[0] series.append([ts_start, value]) return series - def _handle_temp_sums(self, func: str, database_item: Item, year: Union[int, str] = None, month: Union[int, str] = None, ignore_value_list: list = None, params: dict = {}) -> Union[list, None]: + def _handle_temp_sums(self, func: str, database_item: Item, year: Union[int, str] = None, month: Union[int, str] = None, ignore_value_list: list = None, params: dict = None) -> Union[list, None]: """ Calculates diverse temperature sums and day counts @@ -1676,6 +1691,9 @@ def _handle_temp_sums(self, func: str, database_item: Item, year: Union[int, str 'eistage': {'start_end': timeframe[3], 'data_con_func': 'minmax_day'}, } + if not params: + params = dict() + def kaeltesumme() -> float: """Berechnung der Kältesumme durch Akkumulieren aller negativen Tagesdurchschnittstemperaturen im Abfragezeitraum @@ -1901,6 +1919,10 @@ def _prepare_value_list(self, database_item: Item, timeframe: str, start: int, e - first_hour: determines first value per hour of values within plugin - minmax_day: determines min and max value per day of values within plugin - minmax_hour: determines min and max value per hour of values within plugin + - min_day: determines min value per day of values within plugin + - max_hour: determines max value per hour of values within plugin + - min_day: determines min value per day of values within plugin + - max_hour: determines max value per hour of values within plugin - first_hour_avg_day: 2-step concentration: 1) concentrate values within an hour by using first value 2) concentrate values by average for first value of each hour :return: list of list with [timestamp, value] """ @@ -1936,6 +1958,8 @@ def _concentrate_values(option: str) -> list: 'first' will take first entry of list per datetime to get as close to value at full hour as possible 'avg' will use the calculated average of values in list per datetime 'minmax' will get min and max value of list per datetime + 'min' will get the min value of list per datetime + 'max' will get the min value of list per datetime """ _value_list = [] @@ -1948,12 +1972,16 @@ def _concentrate_values(option: str) -> list: _value_list.append([_timestamp, round(sum(value_dict[entry]) / len(value_dict[entry]), 2)]) elif option == 'minmax': _value_list.append([_timestamp, min(value_dict[entry]), max(value_dict[entry])]) + elif option == 'max': + _value_list.append([_timestamp, max(value_dict[entry])]) + elif option == 'min': + _value_list.append([_timestamp, min(value_dict[entry])]) return _value_list if self.debug_log.prepare: self.logger.debug(f'called with database_item={database_item.path()}, {timeframe=}, {start=}, {end=}, {ignore_value_list=}, {data_con_func=}') - if data_con_func not in ('avg', 'minmax', 'first', 'avg_day', 'avg_hour', 'minmax_day', 'minmax_hour', 'first_day','first_hour', 'first_hour_avg_day', 'avg_hour_avg_day'): + if data_con_func not in ('min', 'max', 'avg', 'minmax', 'first', 'avg_day', 'avg_hour', 'minmax_day', 'minmax_hour', 'first_day', 'first_hour', 'first_hour_avg_day', 'avg_hour_avg_day', 'min_hour', 'min_day', 'max_hour', 'max_day'): self.logger.warning(f"defined {data_con_func=} for _prepare_value_list unknown. Need to be 'avg', 'minmax', 'first', 'avg_day', 'avg_hour', 'minmax_day', 'minmax_hour', 'first_day','first_hour', 'first_hour_avg_day' or 'avg_hour_avg_day'. Aborting...") return @@ -2712,7 +2740,6 @@ def _fetchall(self, query: str, params: dict = None, cur=None) -> list: tuples = self._query(self._db.fetchall, query, params, cur) return None if tuples is None else list(tuples) - # ToDo: Check if still needed. def _query(self, fetch, query: str, params: dict = None, cur=None) -> Union[None, list]: """query using commit to get latest data from db""" @@ -2757,7 +2784,7 @@ def _query(self, fetch, query: str, params: dict = None, cur=None) -> Union[None return tuples # ToDo: Check if still needed. - def _query_geht_gut(self, fetch, query: str, params: dict = None, cur=None) -> Union[None, list]: + def _query_with_close(self, fetch, query: str, params: dict = None, cur=None) -> Union[None, list]: """query open and close connection for each query to get latest data from db""" if params is None: diff --git a/db_addon/item_attributes.py b/db_addon/item_attributes.py index e1d94b417..e28c243c2 100644 --- a/db_addon/item_attributes.py +++ b/db_addon/item_attributes.py @@ -28,26 +28,26 @@ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # -ALL_ONCHANGE_ATTRIBUTES = ['verbrauch_heute', 'verbrauch_woche', 'verbrauch_monat', 'verbrauch_jahr', 'minmax_heute_min', 'minmax_heute_max', 'minmax_heute_avg', 'minmax_woche_min', 'minmax_woche_max', 'minmax_monat_min', 'minmax_monat_max', 'minmax_jahr_min', 'minmax_jahr_max', 'tagesmitteltemperatur_heute'] -ALL_DAILY_ATTRIBUTES = ['verbrauch_heute_minus1', 'verbrauch_heute_minus2', 'verbrauch_heute_minus3', 'verbrauch_heute_minus4', 'verbrauch_heute_minus5', 'verbrauch_heute_minus6', 'verbrauch_heute_minus7', 'verbrauch_rolling_12m_heute_minus1', 'verbrauch_jahreszeitraum_minus1', 'verbrauch_jahreszeitraum_minus2', 'verbrauch_jahreszeitraum_minus3', 'zaehlerstand_heute_minus1', 'zaehlerstand_heute_minus2', 'zaehlerstand_heute_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', 'tagesmitteltemperatur_heute_minus1', 'tagesmitteltemperatur_heute_minus2', 'tagesmitteltemperatur_heute_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_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'] +ALL_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'] ALL_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'] ALL_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'] ALL_YEARLY_ATTRIBUTES = ['verbrauch_jahr_minus1', 'verbrauch_jahr_minus2', '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_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_woche', 'verbrauch_monat', 'verbrauch_jahr', 'verbrauch_heute_minus1', 'verbrauch_heute_minus2', 'verbrauch_heute_minus3', 'verbrauch_heute_minus4', 'verbrauch_heute_minus5', 'verbrauch_heute_minus6', 'verbrauch_heute_minus7', '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_rolling_12m_heute_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_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_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_ATTRIBUTES_ROLLING = ['verbrauch_rolling_12m_heute_minus1', 'verbrauch_rolling_12m_woche_minus1', 'verbrauch_rolling_12m_monat_minus1', 'verbrauch_rolling_12m_jahr_minus1'] +ALL_VERBRAUCH_ATTRIBUTES = ['verbrauch_heute', 'verbrauch_tag', 'verbrauch_woche', 'verbrauch_monat', 'verbrauch_jahr', '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_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_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_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_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_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_woche_min', 'minmax_woche_max', 'minmax_monat_min', 'minmax_monat_max', 'minmax_jahr_min', 'minmax_jahr_max'] +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_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'] -TAGESMITTEL_ATTRIBUTES_ONCHANGE = ['tagesmitteltemperatur_heute'] -TAGESMITTEL_ATTRIBUTES_TIMEFRAME = ['tagesmitteltemperatur_heute_minus1', 'tagesmitteltemperatur_heute_minus2', 'tagesmitteltemperatur_heute_minus3'] +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'] diff --git a/db_addon/item_attributes_master.py b/db_addon/item_attributes_master.py index cdf36d71c..ae6855bca 100644 --- a/db_addon/item_attributes_master.py +++ b/db_addon/item_attributes_master.py @@ -27,11 +27,12 @@ DOC_FILE_NAME = 'user_doc.rst' -PLUGIN_VERSION = '1.2.3' +PLUGIN_VERSION = '1.2.4' ITEM_ATTRIBUTES = { 'db_addon_fct': { 'verbrauch_heute': {'cat': 'verbrauch', 'sub_cat': 'onchange', 'item_type': 'num', 'calc': 'onchange', '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', 'calc': 'onchange', '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', 'calc': 'onchange', 'params': False, 'description': 'Verbrauch in der aktuellen Woche'}, 'verbrauch_monat': {'cat': 'verbrauch', 'sub_cat': 'onchange', 'item_type': 'num', 'calc': 'onchange', 'params': False, 'description': 'Verbrauch im aktuellen Monat'}, 'verbrauch_jahr': {'cat': 'verbrauch', 'sub_cat': 'onchange', 'item_type': 'num', 'calc': 'onchange', 'params': False, 'description': 'Verbrauch im aktuellen Jahr'}, @@ -42,6 +43,15 @@ 'verbrauch_heute_minus5': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Verbrauch heute -5 Tage'}, 'verbrauch_heute_minus6': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Verbrauch heute -6 Tage'}, 'verbrauch_heute_minus7': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Verbrauch heute -7 Tage'}, + 'verbrauch_heute_minus8': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Verbrauch heute -8 Tage'}, + 'verbrauch_tag_minus1': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': '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', 'calc': 'daily', 'params': False, 'description': 'Verbrauch vorgestern (heute -2 Tage)'}, + 'verbrauch_tag_minus3': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Verbrauch heute -3 Tage'}, + 'verbrauch_tag_minus4': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Verbrauch heute -4 Tage'}, + 'verbrauch_tag_minus5': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Verbrauch heute -5 Tage'}, + 'verbrauch_tag_minus6': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Verbrauch heute -6 Tage'}, + 'verbrauch_tag_minus7': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Verbrauch heute -7 Tage'}, + 'verbrauch_tag_minus8': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Verbrauch heute -8 Tage'}, 'verbrauch_woche_minus1': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'weekly', 'params': False, 'description': 'Verbrauch Vorwoche (aktuelle Woche -1)'}, 'verbrauch_woche_minus2': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'weekly', 'params': False, 'description': 'Verbrauch aktuelle Woche -2 Wochen'}, 'verbrauch_woche_minus3': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'weekly', 'params': False, 'description': 'Verbrauch aktuelle Woche -3 Wochen'}, @@ -54,6 +64,7 @@ 'verbrauch_jahr_minus1': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'yearly', 'params': False, 'description': 'Verbrauch Vorjahr (aktuelles Jahr -1 Jahr)'}, 'verbrauch_jahr_minus2': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'yearly', 'params': False, 'description': 'Verbrauch aktuelles Jahr -2 Jahre'}, 'verbrauch_rolling_12m_heute_minus1': {'cat': 'verbrauch', 'sub_cat': 'rolling', 'item_type': 'num', 'calc': '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', 'calc': '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', 'calc': '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', 'calc': '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', 'calc': 'yearly', 'params': False, 'description': 'Verbrauch der letzten 12 Monate ausgehend im Ende des letzten Jahres'}, @@ -63,6 +74,9 @@ 'zaehlerstand_heute_minus1': {'cat': 'zaehler', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': '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', 'calc': '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', 'calc': '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', 'calc': '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', 'calc': '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', 'calc': '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', 'calc': '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', 'calc': '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', 'calc': 'weekly', 'params': False, 'description': 'Zählerstand / Wert am Ende der aktuellen Woche -3 Wochen'}, @@ -90,6 +104,18 @@ 'minmax_heute_minus3_min': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Minimalwert heute vor 3 Tagen'}, 'minmax_heute_minus3_max': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Maximalwert heute vor 3 Tagen'}, 'minmax_heute_minus3_avg': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Durchschnittswert heute vor 3 Tagen'}, + 'minmax_tag_min': {'cat': 'wertehistorie', 'sub_cat': 'onchange', 'item_type': 'num', 'calc': 'onchange', 'params': False, 'description': 'Minimalwert seit Tagesbeginn'}, + 'minmax_tag_max': {'cat': 'wertehistorie', 'sub_cat': 'onchange', 'item_type': 'num', 'calc': 'onchange', 'params': False, 'description': 'Maximalwert seit Tagesbeginn'}, + 'minmax_tag_avg': {'cat': 'wertehistorie', 'sub_cat': 'onchange', 'item_type': 'num', 'calc': 'onchange', 'params': False, 'description': 'Durschnittswert seit Tagesbeginn'}, + 'minmax_tag_minus1_min': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Minimalwert gestern (heute -1 Tag)'}, + 'minmax_tag_minus1_max': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Maximalwert gestern (heute -1 Tag)'}, + 'minmax_tag_minus1_avg': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Durchschnittswert gestern (heute -1 Tag)'}, + 'minmax_tag_minus2_min': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Minimalwert vorgestern (heute -2 Tage)'}, + 'minmax_tag_minus2_max': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Maximalwert vorgestern (heute -2 Tage)'}, + 'minmax_tag_minus2_avg': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Durchschnittswert vorgestern (heute -2 Tage)'}, + 'minmax_tag_minus3_min': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Minimalwert heute vor 3 Tagen'}, + 'minmax_tag_minus3_max': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Maximalwert heute vor 3 Tagen'}, + 'minmax_tag_minus3_avg': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Durchschnittswert heute vor 3 Tagen'}, 'minmax_woche_min': {'cat': 'wertehistorie', 'sub_cat': 'onchange', 'item_type': 'num', 'calc': 'onchange', 'params': False, 'description': 'Minimalwert seit Wochenbeginn'}, 'minmax_woche_max': {'cat': 'wertehistorie', 'sub_cat': 'onchange', 'item_type': 'num', 'calc': 'onchange', 'params': False, 'description': 'Maximalwert seit Wochenbeginn'}, 'minmax_woche_minus1_min': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'weekly', 'params': False, 'description': 'Minimalwert Vorwoche (aktuelle Woche -1)'}, @@ -115,6 +141,10 @@ 'tagesmitteltemperatur_heute_minus1': {'cat': 'tagesmittel', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Tagesmitteltemperatur des letzten Tages (heute -1 Tag)'}, 'tagesmitteltemperatur_heute_minus2': {'cat': 'tagesmittel', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Tagesmitteltemperatur des vorletzten Tages (heute -2 Tag)'}, 'tagesmitteltemperatur_heute_minus3': {'cat': 'tagesmittel', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Tagesmitteltemperatur des vorvorletzten Tages (heute -3 Tag)'}, + 'tagesmitteltemperatur_tag': {'cat': 'tagesmittel', 'sub_cat': 'onchange', 'item_type': 'num', 'calc': 'onchange', 'params': False, 'description': 'Tagesmitteltemperatur heute'}, + 'tagesmitteltemperatur_tag_minus1': {'cat': 'tagesmittel', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Tagesmitteltemperatur des letzten Tages (heute -1 Tag)'}, + 'tagesmitteltemperatur_tag_minus2': {'cat': 'tagesmittel', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Tagesmitteltemperatur des vorletzten Tages (heute -2 Tag)'}, + 'tagesmitteltemperatur_tag_minus3': {'cat': 'tagesmittel', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Tagesmitteltemperatur des vorvorletzten Tages (heute -3 Tag)'}, 'serie_minmax_monat_min_15m': {'cat': 'serie', 'sub_cat': 'minmax', 'item_type': 'list', 'calc': 'monthly', 'params': False, 'description': 'monatlicher Minimalwert der letzten 15 Monate (gleitend)'}, 'serie_minmax_monat_max_15m': {'cat': 'serie', 'sub_cat': 'minmax', 'item_type': 'list', 'calc': 'monthly', 'params': False, 'description': 'monatlicher Maximalwert der letzten 15 Monate (gleitend)'}, 'serie_minmax_monat_avg_15m': {'cat': 'serie', 'sub_cat': 'minmax', 'item_type': 'list', 'calc': 'monthly', 'params': False, 'description': 'monatlicher Mittelwert der letzten 15 Monate (gleitend)'}, @@ -248,6 +278,11 @@ def export_item_attributes_py(): ATTRS['ALL_GEN_ATTRIBUTES'] = get_attrs(sub_dict={'cat': 'gen'}) ATTRS['ALL_SUMME_ATTRIBUTES'] = get_attrs(sub_dict={'cat': 'summe'}) ATTRS['ALL_COMPLEX_ATTRIBUTES'] = get_attrs(sub_dict={'cat': 'complex'}) + ATTRS['TAGESMITTEL_ATTRIBUTES_ONCHANGE'] = get_attrs(sub_dict={'cat': 'tagesmittel', 'sub_cat': 'onchange'}) + + for entry in ATTRS['HISTORIE_ATTRIBUTES_ONCHANGE']: + if entry.endswith('avg'): + ATTRS['TAGESMITTEL_ATTRIBUTES_ONCHANGE'].append(entry) # create file and write header f = open(FILENAME_ATTRIBUTES, "w") diff --git a/db_addon/plugin.yaml b/db_addon/plugin.yaml index 7de29be1f..44aebd666 100644 --- a/db_addon/plugin.yaml +++ b/db_addon/plugin.yaml @@ -11,7 +11,7 @@ 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.3 # Plugin version (must match the version specified in __init__.py) + version: 1.2.4 # 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 @@ -78,6 +78,7 @@ item_attributes: valid_list: # NOTE: valid_list is automatically created by using item_attributes_master.py - verbrauch_heute + - verbrauch_tag - verbrauch_woche - verbrauch_monat - verbrauch_jahr @@ -88,6 +89,15 @@ item_attributes: - 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 @@ -100,6 +110,7 @@ item_attributes: - verbrauch_jahr_minus1 - verbrauch_jahr_minus2 - 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 @@ -109,6 +120,9 @@ item_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 @@ -136,6 +150,18 @@ item_attributes: - 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 @@ -161,6 +187,10 @@ item_attributes: - tagesmitteltemperatur_heute_minus1 - tagesmitteltemperatur_heute_minus2 - tagesmitteltemperatur_heute_minus3 + - tagesmitteltemperatur_tag + - tagesmitteltemperatur_tag_minus1 + - tagesmitteltemperatur_tag_minus2 + - tagesmitteltemperatur_tag_minus3 - serie_minmax_monat_min_15m - serie_minmax_monat_max_15m - serie_minmax_monat_avg_15m @@ -204,6 +234,7 @@ item_attributes: - zaehlerstand valid_list_description: # NOTE: valid_list_description is automatically created by using item_attributes_master.py + - Verbrauch am heutigen Tag (Differenz zwischen aktuellem Wert und den Wert am Ende des vorherigen Tages) - Verbrauch am heutigen Tag (Differenz zwischen aktuellem Wert und den Wert am Ende des vorherigen Tages) - Verbrauch in der aktuellen Woche - Verbrauch im aktuellen Monat @@ -215,6 +246,15 @@ item_attributes: - Verbrauch heute -5 Tage - Verbrauch heute -6 Tage - Verbrauch heute -7 Tage + - Verbrauch heute -8 Tage + - Verbrauch gestern (heute -1 Tag) (Differenz zwischen Wert am Ende des gestrigen Tages und dem Wert am Ende des Tages davor) + - Verbrauch vorgestern (heute -2 Tage) + - Verbrauch heute -3 Tage + - Verbrauch heute -4 Tage + - Verbrauch heute -5 Tage + - Verbrauch heute -6 Tage + - Verbrauch heute -7 Tage + - Verbrauch heute -8 Tage - Verbrauch Vorwoche (aktuelle Woche -1) - Verbrauch aktuelle Woche -2 Wochen - Verbrauch aktuelle Woche -3 Wochen @@ -227,6 +267,7 @@ item_attributes: - Verbrauch Vorjahr (aktuelles Jahr -1 Jahr) - Verbrauch aktuelles Jahr -2 Jahre - Verbrauch der letzten 12 Monate ausgehend im Ende des letzten Tages + - Verbrauch der letzten 12 Monate ausgehend im Ende des letzten Tages - Verbrauch der letzten 12 Monate ausgehend im Ende der letzten Woche - Verbrauch der letzten 12 Monate ausgehend im Ende des letzten Monats - Verbrauch der letzten 12 Monate ausgehend im Ende des letzten Jahres @@ -236,6 +277,9 @@ item_attributes: - Zählerstand / Wert am Ende des letzten Tages (heute -1 Tag) - Zählerstand / Wert am Ende des vorletzten Tages (heute -2 Tag) - Zählerstand / Wert am Ende des vorvorletzten Tages (heute -3 Tag) + - Zählerstand / Wert am Ende des letzten Tages (heute -1 Tag) + - Zählerstand / Wert am Ende des vorletzten Tages (heute -2 Tag) + - Zählerstand / Wert am Ende des vorvorletzten Tages (heute -3 Tag) - Zählerstand / Wert am Ende der vorvorletzten Woche (aktuelle Woche -1 Woche) - Zählerstand / Wert am Ende der vorletzten Woche (aktuelle Woche -2 Wochen) - Zählerstand / Wert am Ende der aktuellen Woche -3 Wochen @@ -263,6 +307,18 @@ item_attributes: - Minimalwert heute vor 3 Tagen - Maximalwert heute vor 3 Tagen - Durchschnittswert heute vor 3 Tagen + - Minimalwert seit Tagesbeginn + - Maximalwert seit Tagesbeginn + - Durschnittswert seit Tagesbeginn + - Minimalwert gestern (heute -1 Tag) + - Maximalwert gestern (heute -1 Tag) + - Durchschnittswert gestern (heute -1 Tag) + - Minimalwert vorgestern (heute -2 Tage) + - Maximalwert vorgestern (heute -2 Tage) + - Durchschnittswert vorgestern (heute -2 Tage) + - Minimalwert heute vor 3 Tagen + - Maximalwert heute vor 3 Tagen + - Durchschnittswert heute vor 3 Tagen - Minimalwert seit Wochenbeginn - Maximalwert seit Wochenbeginn - Minimalwert Vorwoche (aktuelle Woche -1) @@ -288,6 +344,10 @@ item_attributes: - Tagesmitteltemperatur des letzten Tages (heute -1 Tag) - Tagesmitteltemperatur des vorletzten Tages (heute -2 Tag) - Tagesmitteltemperatur des vorvorletzten Tages (heute -3 Tag) + - Tagesmitteltemperatur heute + - Tagesmitteltemperatur des letzten Tages (heute -1 Tag) + - Tagesmitteltemperatur des vorletzten Tages (heute -2 Tag) + - Tagesmitteltemperatur des vorvorletzten Tages (heute -3 Tag) - monatlicher Minimalwert der letzten 15 Monate (gleitend) - monatlicher Maximalwert der letzten 15 Monate (gleitend) - monatlicher Mittelwert der letzten 15 Monate (gleitend) @@ -415,6 +475,36 @@ item_attributes: - num - num - num + - num + - num + - num + - num + - num + - num + - num + - num + - num + - num + - num + - num + - num + - num + - num + - num + - num + - num + - num + - num + - num + - num + - num + - num + - num + - num + - num + - num + - num + - num - list - list - list @@ -462,6 +552,16 @@ item_attributes: - onchange - onchange - onchange + - onchange + - daily + - daily + - daily + - daily + - daily + - daily + - daily + - daily + - daily - daily - daily - daily @@ -481,6 +581,7 @@ item_attributes: - yearly - yearly - daily + - daily - weekly - monthly - yearly @@ -490,6 +591,9 @@ item_attributes: - daily - daily - daily + - daily + - daily + - daily - weekly - weekly - weekly @@ -519,6 +623,18 @@ item_attributes: - daily - onchange - onchange + - onchange + - daily + - daily + - daily + - daily + - daily + - daily + - daily + - daily + - daily + - onchange + - onchange - weekly - weekly - weekly @@ -542,6 +658,10 @@ item_attributes: - daily - daily - daily + - onchange + - daily + - daily + - daily - monthly - monthly - monthly @@ -664,9 +784,9 @@ item_attributes: item_structs: verbrauch_1: name: Struct für Verbrauchsauswertung bei Zählern mit stetig ansteigendem Zählerstand (Teil 1) - verbrauch_heute: - name: Verbrauch heute - db_addon_fct: verbrauch_heute + verbrauch_tag: + name: Verbrauch am heutigen Tag + db_addon_fct: verbrauch_tag db_addon_startup: yes type: num visu_acl: ro @@ -698,37 +818,37 @@ item_structs: verbrauch_rolling_12m: name: Verbrauch innerhalb der letzten 12 Monate ausgehend von gestern - db_addon_fct: verbrauch_rolling_12m_heute_minus1 + db_addon_fct: verbrauch_rolling_12m_tag_minus1 db_addon_startup: yes type: num visu_acl: ro # cache: yes - verbrauch_gestern: + verbrauch_tag_minus1: name: Verbrauch gestern - db_addon_fct: verbrauch_heute_minus1 + db_addon_fct: verbrauch_tag_minus1 db_addon_startup: yes type: num visu_acl: ro # cache: yes - verbrauch_gestern_minus1: + verbrauch_tag_minus2: name: Verbrauch vorgestern - db_addon_fct: verbrauch_heute_minus2 + db_addon_fct: verbrauch_tag_minus2 db_addon_startup: yes type: num visu_acl: ro # cache: yes - verbrauch_gestern_minus2: + verbrauch_tag_minus3: name: Verbrauch vor 3 Tagen - db_addon_fct: verbrauch_heute_minus3 + db_addon_fct: verbrauch_tag_minus3 db_addon_startup: yes type: num visu_acl: ro # cache: yes - verbrauch_vorwoche: + verbrauch_woche_minus1: name: Verbrauch in der Vorwoche db_addon_fct: verbrauch_woche_minus1 db_addon_startup: yes @@ -736,7 +856,7 @@ item_structs: visu_acl: ro # cache: yes - verbrauch_vorwoche_minus1: + verbrauch_woche_minus2: name: Verbrauch vor 2 Wochen db_addon_fct: verbrauch_woche_minus2 db_addon_startup: yes @@ -744,7 +864,7 @@ item_structs: visu_acl: ro # cache: yes - verbrauch_vormonat: + verbrauch_monat_minus1: name: Verbrauch im Vormonat db_addon_fct: verbrauch_monat_minus1 db_addon_startup: yes @@ -752,7 +872,7 @@ item_structs: visu_acl: ro # cache: yes - verbrauch_vormonat_minus12: + verbrauch_monat_minus12: name: Verbrauch vor 12 Monaten db_addon_fct: verbrauch_monat_minus12 db_addon_startup: yes @@ -778,70 +898,70 @@ item_structs: verbrauch_2: name: Struct für Verbrauchsauswertung bei Zählern mit stetig ansteigendem Zählerstand (Teil 2) - verbrauch_gestern_minus3: - name: Verbrauch vor 3 Tagen - db_addon_fct: verbrauch_heute_minus3 - type: num - visu_acl: ro - cache: yes - - verbrauch_gestern_minus4: + verbrauch_tag_minus4: name: Verbrauch vor 4 Tagen - db_addon_fct: verbrauch_heute_minus4 + db_addon_fct: verbrauch_tag_minus4 type: num visu_acl: ro cache: yes - verbrauch_gestern_minus5: + verbrauch_tag_minus5: name: Verbrauch vor 5 Tagen - db_addon_fct: verbrauch_heute_minus5 + db_addon_fct: verbrauch_tag_minus5 type: num visu_acl: ro cache: yes - verbrauch_gestern_minus6: + verbrauch_tag_minus6: name: Verbrauch vor 6 Tagen - db_addon_fct: verbrauch_heute_minus6 + db_addon_fct: verbrauch_tag_minus6 type: num visu_acl: ro cache: yes - verbrauch_gestern_minus7: + verbrauch_tag_minus7: name: Verbrauch vor 7 Tagen - db_addon_fct: verbrauch_heute_minus7 + db_addon_fct: verbrauch_tag_minus7 + type: num + visu_acl: ro + cache: yes + + verbrauch_tag_minus8: + name: Verbrauch vor 8 Tagen + db_addon_fct: verbrauch_tag_minus8 type: num visu_acl: ro cache: yes - verbrauch_vorwoche_minus2: + verbrauch_woche_minus3: name: Verbrauch vor 3 Wochen db_addon_fct: verbrauch_woche_minus3 type: num visu_acl: ro cache: yes - verbrauch_vorwoche_minus3: + verbrauch_woche_minus4: name: Verbrauch vor 4 Wochen db_addon_fct: verbrauch_woche_minus4 type: num visu_acl: ro cache: yes - verbrauch_vormonat_minus1: + verbrauch_monat_minus2: name: Verbrauch vor 2 Monaten db_addon_fct: verbrauch_monat_minus2 type: num visu_acl: ro cache: yes - verbrauch_vormonat_minus2: + verbrauch_monat_minus3: name: Verbrauch vor 3 Monaten db_addon_fct: verbrauch_monat_minus3 type: num visu_acl: ro cache: yes - verbrauch_vormonat_minus3: + verbrauch_monat_minus4: name: Verbrauch vor 4 Monaten db_addon_fct: verbrauch_monat_minus4 type: num @@ -852,13 +972,13 @@ item_structs: name: Struct für die Erfassung von Zählerständen zu bestimmten Zeitpunkten bei Zählern mit stetig ansteigendem Zählerstand zaehlerstand_gestern: name: Zählerstand zum Ende des gestrigen Tages - db_addon_fct: zaehlerstand_heute_minus1 + db_addon_fct: zaehlerstand_tag_minus1 db_addon_startup: yes type: num visu_acl: ro # cache: yes - zaehlerstand_vorwoche: + zaehlerstand_woche_minus1: name: Zählerstand zum Ende der vorigen Woche db_addon_fct: zaehlerstand_woche_minus1 db_addon_startup: yes @@ -866,7 +986,7 @@ item_structs: visu_acl: ro # cache: yes - zaehlerstand_vormonat: + zaehlerstand_monat_minus1: name: Zählerstand zum Ende des Vormonates db_addon_fct: zaehlerstand_monat_minus1 db_addon_startup: yes @@ -874,7 +994,7 @@ item_structs: visu_acl: ro # cache: yes - zaehlerstand_vormonat_minus1: + zaehlerstand_monat_minus2: name: Zählerstand zum Monatsende vor 2 Monaten db_addon_fct: zaehlerstand_monat_minus2 db_addon_startup: yes @@ -882,7 +1002,7 @@ item_structs: visu_acl: ro # cache: yes - zaehlerstand_vormonat_minus2: + zaehlerstand_monat_minus3: name: Zählerstand zum Monatsende vor 3 Monaten db_addon_fct: zaehlerstand_monat_minus3 db_addon_startup: yes @@ -890,7 +1010,7 @@ item_structs: visu_acl: ro # cache: yes - zaehlerstand_vorjahr: + zaehlerstand_jahr_minus1: name: Zählerstand am Ende des vorigen Jahres db_addon_fct: zaehlerstand_jahr_minus1 db_addon_startup: yes @@ -901,24 +1021,24 @@ item_structs: minmax_1: name: Struct für Auswertung der Wertehistorie bei schwankenden Werten wie bspw. Temperatur oder Leistung (Teil 1) - heute_min: + tag_min: name: Minimaler Wert seit Tagesbeginn - db_addon_fct: minmax_heute_min + db_addon_fct: minmax_tag_min db_addon_ignore_value: 0 db_addon_startup: yes type: num # cache: yes - heute_max: + tag_max: name: Maximaler Wert seit Tagesbeginn - db_addon_fct: minmax_heute_max + db_addon_fct: minmax_tag_max db_addon_startup: yes type: num # cache: yes - heute_avg: + tag_avg: name: Maximaler Wert seit Tagesbeginn - db_addon_fct: minmax_heute_avg + db_addon_fct: minmax_tag_avg db_addon_startup: yes type: num @@ -978,77 +1098,77 @@ item_structs: type: num # cache: yes - gestern_min: + tag_minus1_min: name: Minimaler Wert gestern - db_addon_fct: minmax_heute_minus1_min + db_addon_fct: minmax_tag_minus1_min db_addon_startup: yes type: num # cache: yes - gestern_max: + tag_minus1_max: name: Maximaler Wert gestern - db_addon_fct: minmax_heute_minus1_max + db_addon_fct: minmax_tag_minus1_max db_addon_startup: yes type: num # cache: yes - gestern_avg: + tag_minus1_avg: name: Durchschnittlicher Wert gestern - db_addon_fct: minmax_heute_minus1_avg + db_addon_fct: minmax_tag_minus1_avg db_addon_startup: yes type: num # cache: yes - vorwoche_min: + woche_minus1_min: name: Minimaler Wert in der Vorwoche db_addon_fct: minmax_woche_minus1_min db_addon_startup: yes type: num # cache: yes - vorwoche_max: + woche_minus1_max: name: Maximaler Wert in der Vorwoche db_addon_fct: minmax_woche_minus1_max db_addon_startup: yes type: num # cache: yes - vorwoche_avg: + woche_minus1_avg: name: Durchschnittlicher Wert in der Vorwoche db_addon_fct: minmax_woche_minus1_avg db_addon_startup: yes type: num # cache: yes - vormonat_min: + monat_minus1_min: name: Minimaler Wert im Vormonat db_addon_fct: minmax_monat_minus1_min db_addon_startup: yes type: num # cache: yes - vormonat_max: + monat_minus1_max: name: Maximaler Wert im Vormonat db_addon_fct: minmax_monat_minus1_max db_addon_startup: yes type: num # cache: yes - vormonat_avg: + monat_minus1_avg: name: Durchschnittlicher Wert im Vormonat db_addon_fct: minmax_monat_minus1_avg db_addon_startup: yes type: num # cache: yes - vorjahr_min: + jahr_minus1_min: name: Minimaler Wert im Vorjahr db_addon_fct: minmax_jahr_minus1_min db_addon_startup: yes type: num # cache: yes - vorjahr_max: + jahr_minus1_max: name: Maximaler Wert im Vorjahr db_addon_fct: minmax_jahr_minus1_max db_addon_startup: yes @@ -1058,73 +1178,73 @@ item_structs: minmax_2: name: Struct für Auswertung der Wertehistorie bei schwankenden Werten wie bspw. Temperatur oder Leistung (Teil 2) - gestern_minus1_min: + tag_minus2_min: name: Minimaler Wert vorgestern - db_addon_fct: minmax_heute_minus2_min + db_addon_fct: minmax_tag_minus2_min type: num cache: yes - gestern_minus1_max: + tag_minus2_max: name: Maximaler Wert vorgestern - db_addon_fct: minmax_heute_minus2_max + db_addon_fct: minmax_tag_minus2_max type: num cache: yes - gestern_minus1_avg: + tag_minus2_avg: name: Durchschnittlicher Wert vorgestern - db_addon_fct: minmax_heute_minus2_avg + db_addon_fct: minmax_tag_minus2_avg type: num cache: yes - gestern_minus2_min: + tag_minus3_min: name: Minimaler Wert vor 3 Tagen - db_addon_fct: minmax_heute_minus3_min + db_addon_fct: minmax_tag_minus3_min type: num cache: yes - gestern_minus2_max: + tag_minus3_max: name: Maximaler Wert vor 3 Tagen - db_addon_fct: minmax_heute_minus3_max + db_addon_fct: minmax_tag_minus3_max type: num cache: yes - gestern_minus2_avg: + tag_minus3_avg: name: Durchschnittlicher Wert vor 3 Tagen - db_addon_fct: minmax_heute_minus3_avg + db_addon_fct: minmax_tag_minus3_avg type: num cache: yes - vorwoche_minus1_min: + woche_minus2_min: name: Minimaler Wert in der Woche vor 2 Wochen db_addon_fct: minmax_woche_minus2_min type: num cache: yes - vorwoche_minus1_max: + woche_minus2_max: name: Maximaler Wert in der Woche vor 2 Wochen db_addon_fct: minmax_woche_minus2_max type: num cache: yes - vorwoche_minus1_avg: + woche_minus2_avg: name: Durchschnittlicher Wert in der Woche vor 2 Wochen db_addon_fct: minmax_woche_minus2_avg type: num cache: yes - vormonat_minus1_min: + monat_minus2_min: name: Minimaler Wert im Monat vor 2 Monaten db_addon_fct: minmax_monat_minus2_min type: num cache: yes - vormonat_minus1_max: + monat_minus2_max: name: Maximaler Wert im Monat vor 2 Monaten db_addon_fct: minmax_monat_minus2_max type: num cache: yes - vormonat_minus1_avg: + monat_minus2_avg: name: Durchschnittlicher Wert im Monat vor 2 Monaten db_addon_fct: minmax_monat_minus2_avg type: num diff --git a/db_addon/user_doc.rst b/db_addon/user_doc.rst index d95d4658d..bb3457f48 100644 --- a/db_addon/user_doc.rst +++ b/db_addon/user_doc.rst @@ -105,6 +105,8 @@ db_addon_fct - verbrauch_heute: Verbrauch am heutigen Tag (Differenz zwischen aktuellem Wert und den Wert am Ende des vorherigen Tages) | Berechnung: onchange | Item-Type: num +- verbrauch_tag: Verbrauch am heutigen Tag (Differenz zwischen aktuellem Wert und den Wert am Ende des vorherigen Tages) | Berechnung: onchange | Item-Type: num + - verbrauch_woche: Verbrauch in der aktuellen Woche | Berechnung: onchange | Item-Type: num - verbrauch_monat: Verbrauch im aktuellen Monat | Berechnung: onchange | Item-Type: num @@ -125,6 +127,24 @@ db_addon_fct - verbrauch_heute_minus7: Verbrauch heute -7 Tage | Berechnung: daily | Item-Type: num +- verbrauch_heute_minus8: Verbrauch heute -8 Tage | Berechnung: daily | Item-Type: num + +- verbrauch_tag_minus1: Verbrauch gestern (heute -1 Tag) (Differenz zwischen Wert am Ende des gestrigen Tages und dem Wert am Ende des Tages davor) | Berechnung: daily | Item-Type: num + +- verbrauch_tag_minus2: Verbrauch vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num + +- verbrauch_tag_minus3: Verbrauch heute -3 Tage | Berechnung: daily | Item-Type: num + +- verbrauch_tag_minus4: Verbrauch heute -4 Tage | Berechnung: daily | Item-Type: num + +- verbrauch_tag_minus5: Verbrauch heute -5 Tage | Berechnung: daily | Item-Type: num + +- verbrauch_tag_minus6: Verbrauch heute -6 Tage | Berechnung: daily | Item-Type: num + +- verbrauch_tag_minus7: Verbrauch heute -7 Tage | Berechnung: daily | Item-Type: num + +- verbrauch_tag_minus8: Verbrauch heute -8 Tage | Berechnung: daily | Item-Type: num + - verbrauch_woche_minus1: Verbrauch Vorwoche (aktuelle Woche -1) | Berechnung: weekly | Item-Type: num - verbrauch_woche_minus2: Verbrauch aktuelle Woche -2 Wochen | Berechnung: weekly | Item-Type: num @@ -149,6 +169,8 @@ db_addon_fct - verbrauch_rolling_12m_heute_minus1: Verbrauch der letzten 12 Monate ausgehend im Ende des letzten Tages | Berechnung: daily | Item-Type: num +- verbrauch_rolling_12m_tag_minus1: Verbrauch der letzten 12 Monate ausgehend im Ende des letzten Tages | Berechnung: daily | Item-Type: num + - verbrauch_rolling_12m_woche_minus1: Verbrauch der letzten 12 Monate ausgehend im Ende der letzten Woche | Berechnung: weekly | Item-Type: num - verbrauch_rolling_12m_monat_minus1: Verbrauch der letzten 12 Monate ausgehend im Ende des letzten Monats | Berechnung: monthly | Item-Type: num @@ -167,6 +189,12 @@ db_addon_fct - zaehlerstand_heute_minus3: Zählerstand / Wert am Ende des vorvorletzten Tages (heute -3 Tag) | Berechnung: daily | Item-Type: num +- zaehlerstand_tag_minus1: Zählerstand / Wert am Ende des letzten Tages (heute -1 Tag) | Berechnung: daily | Item-Type: num + +- zaehlerstand_tag_minus2: Zählerstand / Wert am Ende des vorletzten Tages (heute -2 Tag) | Berechnung: daily | Item-Type: num + +- zaehlerstand_tag_minus3: Zählerstand / Wert am Ende des vorvorletzten Tages (heute -3 Tag) | Berechnung: daily | Item-Type: num + - zaehlerstand_woche_minus1: Zählerstand / Wert am Ende der vorvorletzten Woche (aktuelle Woche -1 Woche) | Berechnung: weekly | Item-Type: num - zaehlerstand_woche_minus2: Zählerstand / Wert am Ende der vorletzten Woche (aktuelle Woche -2 Wochen) | Berechnung: weekly | Item-Type: num @@ -221,6 +249,30 @@ db_addon_fct - minmax_heute_minus3_avg: Durchschnittswert heute vor 3 Tagen | Berechnung: daily | Item-Type: num +- minmax_tag_min: Minimalwert seit Tagesbeginn | Berechnung: onchange | Item-Type: num + +- minmax_tag_max: Maximalwert seit Tagesbeginn | Berechnung: onchange | Item-Type: num + +- minmax_tag_avg: Durschnittswert seit Tagesbeginn | Berechnung: onchange | Item-Type: num + +- minmax_tag_minus1_min: Minimalwert gestern (heute -1 Tag) | Berechnung: daily | Item-Type: num + +- minmax_tag_minus1_max: Maximalwert gestern (heute -1 Tag) | Berechnung: daily | Item-Type: num + +- minmax_tag_minus1_avg: Durchschnittswert gestern (heute -1 Tag) | Berechnung: daily | Item-Type: num + +- minmax_tag_minus2_min: Minimalwert vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num + +- minmax_tag_minus2_max: Maximalwert vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num + +- minmax_tag_minus2_avg: Durchschnittswert vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num + +- minmax_tag_minus3_min: Minimalwert heute vor 3 Tagen | Berechnung: daily | Item-Type: num + +- minmax_tag_minus3_max: Maximalwert heute vor 3 Tagen | Berechnung: daily | Item-Type: num + +- minmax_tag_minus3_avg: Durchschnittswert heute vor 3 Tagen | Berechnung: daily | Item-Type: num + - minmax_woche_min: Minimalwert seit Wochenbeginn | Berechnung: onchange | Item-Type: num - minmax_woche_max: Maximalwert seit Wochenbeginn | Berechnung: onchange | Item-Type: num @@ -271,6 +323,14 @@ db_addon_fct - tagesmitteltemperatur_heute_minus3: Tagesmitteltemperatur des vorvorletzten Tages (heute -3 Tag) | Berechnung: daily | Item-Type: num +- tagesmitteltemperatur_tag: Tagesmitteltemperatur heute | Berechnung: onchange | Item-Type: num + +- tagesmitteltemperatur_tag_minus1: Tagesmitteltemperatur des letzten Tages (heute -1 Tag) | Berechnung: daily | Item-Type: num + +- tagesmitteltemperatur_tag_minus2: Tagesmitteltemperatur des vorletzten Tages (heute -2 Tag) | Berechnung: daily | Item-Type: num + +- tagesmitteltemperatur_tag_minus3: Tagesmitteltemperatur des vorvorletzten Tages (heute -3 Tag) | Berechnung: daily | Item-Type: num + - serie_minmax_monat_min_15m: monatlicher Minimalwert der letzten 15 Monate (gleitend) | Berechnung: monthly | Item-Type: list - serie_minmax_monat_max_15m: monatlicher Maximalwert der letzten 15 Monate (gleitend) | Berechnung: monthly | Item-Type: list diff --git a/db_addon/webif/__init__.py b/db_addon/webif/__init__.py index d1fca7eba..05dbb8d7a 100644 --- a/db_addon/webif/__init__.py +++ b/db_addon/webif/__init__.py @@ -68,6 +68,7 @@ def index(self, reload=None, action=None, item_path=None, active=None, option=No :return: contents of the template after being rendered """ + pagelength = self.plugin.get_parameter_value('webif_pagelength') tmpl = self.tplenv.get_template('index.html') if action is not None: @@ -84,7 +85,7 @@ def index(self, reload=None, action=None, item_path=None, active=None, option=No self.plugin._activate_item_calculation(item=item_path, active=bool(int(active))) return tmpl.render(p=self.plugin, - webif_pagelength=self.plugin.get_parameter_value('webif_pagelength'), + 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')), From 92c3abe26cc52c03cbc964432e32ba9a03da8cd8 Mon Sep 17 00:00:00 2001 From: sisamiwe Date: Sun, 17 Sep 2023 20:14:30 +0200 Subject: [PATCH 11/18] DB_ADDON: - update WebIF for button - add attribute "verbauch_last_24h" - update methods to handle hourly calculation - bump to 1.2.5 --- db_addon/__init__.py | 200 +++++++++++------ db_addon/item_attributes.py | 4 +- db_addon/item_attributes_master.py | 6 +- db_addon/locale.yaml | 1 + db_addon/plugin.yaml | 18 +- db_addon/user_doc.rst | 321 +++++++++++++++++++++------- db_addon/webif/__init__.py | 43 ++-- db_addon/webif/templates/index.html | 217 ++++++++++--------- 8 files changed, 558 insertions(+), 252 deletions(-) diff --git a/db_addon/__init__.py b/db_addon/__init__.py index c0a809c29..b728211e8 100644 --- a/db_addon/__init__.py +++ b/db_addon/__init__.py @@ -49,6 +49,7 @@ from .item_attributes import * import lib.db +HOUR = 'hour' DAY = 'day' WEEK = 'week' MONTH = 'month' @@ -60,7 +61,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.4' + PLUGIN_VERSION = '1.2.5' def __init__(self, sh): """ @@ -157,7 +158,7 @@ def run(self): self._check_db_connection_setting() # add scheduler for cyclic trigger item calculation - self.scheduler_add('cyclic', self.execute_due_items, prio=3, cron='10 0 * * *', cycle=None, value=None, offset=None, next=None) + self.scheduler_add('cyclic', self.execute_due_items, prio=3, cron='10 * * * *', cycle=None, value=None, offset=None, next=None) # add scheduler to trigger items to be calculated at startup with delay dt = self.shtime.now() + relativedelta(seconds=(self.startup_run_delay + 3)) @@ -195,7 +196,8 @@ def stop(self): self.alive = False self.scheduler_remove('cyclic') self.scheduler_remove('onchange_delay') - self._db.close() + if self._db: + self._db.close() self.save_cache_data() # ToDo: Check if still needed @@ -275,6 +277,15 @@ def get_query_parameters_from_db_addon_fct() -> Union[dict, None]: 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] @@ -673,7 +684,9 @@ def format_db_addon_ignore_value_list(optimize: bool = self.optimize_value_filte self.logger.debug(f"Item={item.path()} added with db_addon_fct={db_addon_fct} and database_item={database_item}") # add cycle for item groups - if db_addon_fct in ALL_DAILY_ATTRIBUTES: + if db_addon_fct in ALL_HOURLY_ATTRIBUTES: + item_config_data_dict.update({'cycle': 'hourly'}) + elif db_addon_fct in ALL_DAILY_ATTRIBUTES: item_config_data_dict.update({'cycle': 'daily'}) elif db_addon_fct in ALL_WEEKLY_ATTRIBUTES: item_config_data_dict.update({'cycle': 'weekly'}) @@ -693,6 +706,9 @@ def format_db_addon_ignore_value_list(optimize: bool = self.optimize_value_filte elif db_addon_fct == 'minmax': cycle = item_config_data_dict['query_params']['timeframe'] item_config_data_dict.update({'cycle': f"{timeframe_to_updatecyle(cycle)}"}) + else: + self.logger.warning(f"Cycle for {item.path()} undefined") + item_config_data_dict.update({'cycle': None}) # do logging if self.debug_log.parse: @@ -891,30 +907,38 @@ def execute_items(self, option: str = 'due', item: str = None): def _create_due_items() -> list: """Create list of items which are due and reset cache dicts""" - # täglich zu berechnende Items zur Action Liste hinzufügen + # set für zu berechnende Items erstellen _todo_items = set() - _todo_items.update(set(self._daily_items())) - self.current_values[DAY] = {} - self.previous_values[DAY] = {} - self.value_list_raw_data = {} - - # wenn Wochentag == Montag, werden auch die wöchentlichen Items berechnet - if self.shtime.weekday(self.shtime.today()) == 1: - _todo_items.update(set(self._weekly_items())) - self.current_values[WEEK] = {} - self.previous_values[WEEK] = {} - - # wenn der erste Tage eines Monates ist, werden auch die monatlichen Items berechnet - if self.shtime.now().day == 1: - _todo_items.update(set(self._monthly_items())) - self.current_values[MONTH] = {} - self.previous_values[MONTH] = {} - - # wenn der erste Tage des ersten Monates eines Jahres ist, werden auch die jährlichen Items berechnet - if self.shtime.now().month == 1: - _todo_items.update(set(self._yearly_items())) - self.current_values[YEAR] = {} - self.previous_values[YEAR] = {} + + # stündlich zu berechnende Items hinzufügen + _todo_items.update(set(self._hourly_items())) + self.current_values[HOUR] = {} + self.previous_values[HOUR] = {} + + # wenn aktuelle Stunde == 0, werden auch die täglichen Items berechnet + if self.shtime.now().hour == 0: + _todo_items.update(set(self._daily_items())) + self.current_values[DAY] = {} + self.previous_values[DAY] = {} + self.value_list_raw_data = {} + + # wenn zusätzlich der Wochentag == Montag, werden auch die wöchentlichen Items berechnet + if self.shtime.weekday(self.shtime.today()) == 1: + _todo_items.update(set(self._weekly_items())) + self.current_values[WEEK] = {} + self.previous_values[WEEK] = {} + + # wenn zusätzlich der erste Tage eines Monates ist, werden auch die monatlichen Items berechnet + if self.shtime.now().day == 1: + _todo_items.update(set(self._monthly_items())) + self.current_values[MONTH] = {} + self.previous_values[MONTH] = {} + + # wenn zusätzlich der erste Monat ist, werden auch die jährlichen Items berechnet + if self.shtime.now().month == 1: + _todo_items.update(set(self._yearly_items())) + self.current_values[YEAR] = {} + self.previous_values[YEAR] = {} return list(_todo_items) @@ -956,7 +980,10 @@ def _create_due_items() -> list: # put to queue self.logger.info(f"{len(todo_items)} items will be calculated for {option=}.") + if self.debug_log.execute: + self.logger.debug(f"Items to be calculated: {todo_items=}") [self.item_queue.put(i) for i in todo_items] + return True def work_item_queue(self) -> None: """Handles item queue were all to be executed items were be placed in.""" @@ -1228,6 +1255,7 @@ def handle_tagesmittel(): item(new_value, self.get_shortname()) def _update_database_items(self) -> None: + """Turns given as database_item path into database_items""" for item in self._database_item_path_items(): item_config = self.get_item_config(item) database_item_path = item_config.get('database_item') @@ -1242,7 +1270,7 @@ def _update_database_items(self) -> None: if db_addon_startup: item_config.update({'startup': True}) - def _activate_item_calculation(self, item: Union[str, Item], active: bool = True) -> None: + def _activate_item_calculation(self, item: Union[str, Item], active: bool = True) -> Union[bool, None]: """active / de-active item calculation""" if isinstance(item, str): item = self.items.return_item(item) @@ -1252,6 +1280,7 @@ def _activate_item_calculation(self, item: Union[str, Item], active: bool = True item_config = self.get_item_config(item) item_config['active'] = active + return active @property def log_level(self) -> int: @@ -1269,6 +1298,9 @@ def _startup_items(self) -> list: def _onchange_items(self) -> list: return self.get_item_list('cycle', 'on-change') + def _hourly_items(self) -> list: + return self.get_item_list('cycle', 'hourly') + def _daily_items(self) -> list: return self.get_item_list('cycle', 'daily') @@ -1495,15 +1527,11 @@ def _handle_verbrauch(self, query_params: dict) -> Union[None, float]: Ermittlung des Verbrauches innerhalb eines Zeitraumes Die Vorgehensweise ist: - - Endwert: Abfrage des letzten Eintrages im Zeitraum - - Ergibt diese Abfrage einen Wert, gab eines einen Eintrag im Zeitraum in der DB, es wurde also etwas verbraucht, dann entspricht dieser dem Endzählerstand + - Endwert / Endzählerstand: Abfrage des letzten Eintrages (Zählerstandes) im Zeitraum - Ergibt diese Abfrage keinen Wert, gab eines keinen Eintrag im Zeitraum in der DB, es wurde also nichts verbraucht -> Rückgabe von 0 - - Startwert: Abfrage des letzten Eintrages im Zeitraum vor dem Abfragezeitraum - - Ergibt diese Abfrage einen Wert, entspricht dieser dem Zählerstand am Ende des Zeitraumes vor dem Abfragezeitraum - - Ergibt diese Abfrage keinen Wert, wurde in Zeitraum, vor dem Abfragezeitraum nichts verbraucht, der Anfangszählerstand kann so nicht ermittelt werden. - - Abfrage des nächsten Wertes vor dem Zeitraum - - Ergibt diese Abfrage einen Wert, entspricht dieser dem Anfangszählerstand - - Ergibt diese Abfrage keinen Wert, Anfangszählerstand = 0 + - Startwert / Anfangszählerstand: Abfrage des letzten Eintrages (Zählerstandes) vor dem Abfragezeitraum + - Ergibt diese Abfrage einen Wert, entspricht dieser dem Anfangszählerstand + - Ergibt diese Abfrage keinen Wert, Anfangszählerstand = 0 """ # define start, end for verbrauch_jahreszeitraum_timedelta @@ -1523,7 +1551,7 @@ def _handle_verbrauch(self, query_params: dict) -> Union[None, float]: self.logger.debug(f"called with {query_params=}") # get value for end and check it; - query_params.update({'func': 'last', 'start': end, 'end': end}) + query_params.update({'func': 'last', 'start': start, 'end': end}) value_end = self._query_item(**query_params)[0][1] if self.debug_log.prepare: @@ -1533,28 +1561,19 @@ def _handle_verbrauch(self, query_params: dict) -> Union[None, float]: return value_end # get value for start and check it; - query_params.update({'func': 'last', 'start': start, 'end': start}) + 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=}") - - if value_start is None: - if self.debug_log.prepare: - self.logger.debug(f"Error occurred during query. Return.") - return - - if not value_start: - self.logger.info(f"No DB Entry of item={query_params['database_item'].path()} found for requested start date. Looking for next recent DB entry.") - query_params.update({'func': 'next'}) - value_start = self._query_item(**query_params)[0][1] - if self.debug_log.prepare: - self.logger.debug(f"next recent value is {value_start=}") + self.logger.debug(f"next recent value is {value_start=}") if not value_start: value_start = 0 if self.debug_log.prepare: self.logger.debug(f"No start value available. Will be set to 0 as default") + if self.debug_log.prepare: + self.logger.debug(f"{value_start=}") + # calculate consumption consumption = value_end - value_start @@ -1584,6 +1603,30 @@ def _handle_verbrauch_serie(self, query_params: dict) -> list: return series + 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) + + new_dict = {k[0]: k[1:][0] for k in raw_data} + consumption_list = [] + start_ts = min(new_dict) + start_val = new_dict[start_ts] + + for i in range(query_params['start']): + end_ts = int(start_ts + 24 * 60 * 60) + end_val = new_dict.get(end_ts, None) + if not end_val: + end_val = start_val + consumption_list.append([end_ts, round((end_val - start_val), 2)]) + start_ts = end_ts + start_val = end_val + + return consumption_list + def _handle_zaehlerstand(self, query_params: dict) -> Union[float, int, None]: """ Ermittlung des Zählerstandes zum Ende eines Zeitraumes @@ -1643,6 +1686,30 @@ def _handle_zaehlerstand_serie(self, query_params: dict) -> list: return series + 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) + + new_dict = {k[0]: k[1:][0] for k in raw_data} + zaehler_list = [] + start_ts = min(new_dict) + start_val = new_dict[start_ts] + + for i in range(query_params['start']): + end_ts = int(start_ts + 24 * 60 * 60) + end_val = new_dict.get(end_ts, None) + if not end_val: + end_val = start_val + zaehler_list.append([end_ts, round(end_val, 2)]) + start_ts = end_ts + start_val = end_val + + return zaehler_list + def _handle_temp_sums(self, func: str, database_item: Item, year: Union[int, str] = None, month: Union[int, str] = None, ignore_value_list: list = None, params: dict = None) -> Union[list, None]: """ Calculates diverse temperature sums and day counts @@ -2257,7 +2324,7 @@ def _query_item(self, func: str, database_item: Item, timeframe: str, start: int if ts_end is None or ts_start > ts_end: if self.debug_log.prepare: self.logger.debug(f"{ts_start=}, {ts_end=}") - self.logger.warning(f"Requested {start=} for item={database_item.path()} is not valid since {start=} < {end=} or end not given. Query cancelled.") + self.logger.warning(f"Requested {start=} for item={database_item.path()} is not valid since {start=} > {end=} or end not given. Query cancelled.") return error_result # define item_id @@ -2325,6 +2392,7 @@ def _init_cache_dicts(self) -> None: self.item_cache = {} self.current_values = { + HOUR: {}, DAY: {}, WEEK: {}, MONTH: {}, @@ -2332,6 +2400,7 @@ def _init_cache_dicts(self) -> None: } self.previous_values = { + HOUR: {}, DAY: {}, WEEK: {}, MONTH: {}, @@ -2340,14 +2409,14 @@ def _init_cache_dicts(self) -> None: self.value_list_raw_data = {} - def _clean_item_cache(self, item: Union[str, Item]) -> None: + def _clean_item_cache(self, item: Union[str, Item]) -> bool: """set cached values for item to None""" if isinstance(item, str): item = self.items.return_item(item) if not isinstance(item, Item): - return + return False database_item = self.get_item_config(item).get('database_item') @@ -2362,6 +2431,9 @@ def _clean_item_cache(self, item: Union[str, Item]) -> None: if cached_item == database_item: self.current_values[timeframe][cached_item] = {} + return True + return False + def _clear_queue(self) -> None: """ Clear working queue @@ -2412,26 +2484,32 @@ def _get_start_end_as_timestamp(self, timeframe: str, start: Union[int, str, Non ts_start = ts_end = None def get_query_timestamp(_offset) -> int: - if timeframe == 'week': - _date = self.shtime.beginning_of_week(offset=_offset) + if timeframe == 'hour': + dt = self.shtime.now().replace(microsecond=0, second=0, minute=0) - datetime.timedelta(hours=_offset) + return self._datetime_to_timestamp(dt) * 1000 + elif timeframe == 'week': + _date = self.shtime.beginning_of_week(offset=-_offset) elif timeframe == 'month': - _date = self.shtime.beginning_of_month(offset=_offset) + _date = self.shtime.beginning_of_month(offset=-_offset) elif timeframe == 'year': - _date = self.shtime.beginning_of_year(offset=_offset) + _date = self.shtime.beginning_of_year(offset=-_offset) else: - _date = self.shtime.today(offset=_offset) + _date = self.shtime.today(offset=-_offset) return self._datetime_to_timestamp(datetime.datetime.combine(_date, datetime.datetime.min.time())) * 1000 if isinstance(start, str) and start.isdigit(): start = int(start) if isinstance(start, int): - ts_start = get_query_timestamp(-start) + ts_start = get_query_timestamp(start) if isinstance(end, str) and end.isdigit(): end = int(end) if isinstance(end, int): - ts_end = get_query_timestamp(-end + 1) + if timeframe == 'hour': + ts_end = get_query_timestamp(end) + else: + ts_end = get_query_timestamp(end - 1) return ts_start, ts_end diff --git a/db_addon/item_attributes.py b/db_addon/item_attributes.py index e28c243c2..23ee09161 100644 --- a/db_addon/item_attributes.py +++ b/db_addon/item_attributes.py @@ -29,14 +29,16 @@ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # ALL_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'] +ALL_HOURLY_ATTRIBUTES = ['verbrauch_last_24h', 'verbrauch_last_7d'] ALL_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'] ALL_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'] ALL_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'] ALL_YEARLY_ATTRIBUTES = ['verbrauch_jahr_minus1', 'verbrauch_jahr_minus2', '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_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_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_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'] +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_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_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'] diff --git a/db_addon/item_attributes_master.py b/db_addon/item_attributes_master.py index ae6855bca..b6ddb65a0 100644 --- a/db_addon/item_attributes_master.py +++ b/db_addon/item_attributes_master.py @@ -27,7 +27,7 @@ DOC_FILE_NAME = 'user_doc.rst' -PLUGIN_VERSION = '1.2.4' +PLUGIN_VERSION = '1.2.5' ITEM_ATTRIBUTES = { 'db_addon_fct': { @@ -36,6 +36,8 @@ 'verbrauch_woche': {'cat': 'verbrauch', 'sub_cat': 'onchange', 'item_type': 'num', 'calc': 'onchange', 'params': False, 'description': 'Verbrauch in der aktuellen Woche'}, 'verbrauch_monat': {'cat': 'verbrauch', 'sub_cat': 'onchange', 'item_type': 'num', 'calc': 'onchange', 'params': False, 'description': 'Verbrauch im aktuellen Monat'}, 'verbrauch_jahr': {'cat': 'verbrauch', 'sub_cat': 'onchange', 'item_type': 'num', 'calc': 'onchange', 'params': False, 'description': 'Verbrauch im aktuellen Jahr'}, + 'verbrauch_last_24h': {'cat': 'verbrauch', 'sub_cat': 'last', 'item_type': 'num', 'calc': 'hourly', 'params': False, 'description': 'Verbrauch innerhalb letzten 24h'}, + 'verbrauch_last_7d': {'cat': 'verbrauch', 'sub_cat': 'last', 'item_type': 'num', 'calc': 'hourly', 'params': False, 'description': 'Verbrauch innerhalb letzten 7 Tage'}, 'verbrauch_heute_minus1': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': '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', 'calc': 'daily', 'params': False, 'description': 'Verbrauch vorgestern (heute -2 Tage)'}, 'verbrauch_heute_minus3': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Verbrauch heute -3 Tage'}, @@ -247,6 +249,7 @@ def export_item_attributes_py(): ATTRS = dict() ATTRS['ALL_ONCHANGE_ATTRIBUTES'] = get_attrs(sub_dict={'calc': 'onchange'}) + 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'}) @@ -255,6 +258,7 @@ def export_item_attributes_py(): ATTRS['ALL_VERBRAUCH_ATTRIBUTES'] = get_attrs(sub_dict={'cat': 'verbrauch'}) ATTRS['VERBRAUCH_ATTRIBUTES_ONCHANGE'] = get_attrs(sub_dict={'cat': 'verbrauch', 'sub_cat': 'onchange'}) ATTRS['VERBRAUCH_ATTRIBUTES_TIMEFRAME'] = get_attrs(sub_dict={'cat': 'verbrauch', 'sub_cat': 'timeframe'}) + ATTRS['VERBRAUCH_ATTRIBUTES_LAST'] = get_attrs(sub_dict={'cat': 'verbrauch', 'sub_cat': 'last'}) ATTRS['VERBRAUCH_ATTRIBUTES_ROLLING'] = get_attrs(sub_dict={'cat': 'verbrauch', 'sub_cat': 'rolling'}) ATTRS['VERBRAUCH_ATTRIBUTES_JAHRESZEITRAUM'] = get_attrs(sub_dict={'cat': 'verbrauch', 'sub_cat': 'jahrzeit'}) ATTRS['ALL_ZAEHLERSTAND_ATTRIBUTES'] = get_attrs(sub_dict={'cat': 'zaehler'}) diff --git a/db_addon/locale.yaml b/db_addon/locale.yaml index 2c14a15da..b465b6014 100644 --- a/db_addon/locale.yaml +++ b/db_addon/locale.yaml @@ -1,6 +1,7 @@ # translations for the web interface plugin_translations: # Translations for the plugin specially for the web interface + 'hourly': {'de': 'stündlich', 'en': 'hourly'} 'daily': {'de': 'täglich', 'en': 'daily'} 'weekly': {'de': 'wöchentlich', 'en': '='} 'monthly': {'de': 'monatlich', 'en': '='} diff --git a/db_addon/plugin.yaml b/db_addon/plugin.yaml index 44aebd666..dfb51fbb7 100644 --- a/db_addon/plugin.yaml +++ b/db_addon/plugin.yaml @@ -11,7 +11,7 @@ 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.4 # Plugin version (must match the version specified in __init__.py) + version: 1.2.5 # 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 @@ -82,6 +82,8 @@ item_attributes: - verbrauch_woche - verbrauch_monat - verbrauch_jahr + - verbrauch_last_24h + - verbrauch_last_7d - verbrauch_heute_minus1 - verbrauch_heute_minus2 - verbrauch_heute_minus3 @@ -239,6 +241,8 @@ item_attributes: - Verbrauch in der aktuellen Woche - Verbrauch im aktuellen Monat - Verbrauch im aktuellen Jahr + - Verbrauch innerhalb letzten 24h + - Verbrauch innerhalb letzten 7 Tage - Verbrauch gestern (heute -1 Tag) (Differenz zwischen Wert am Ende des gestrigen Tages und dem Wert am Ende des Tages davor) - Verbrauch vorgestern (heute -2 Tage) - Verbrauch heute -3 Tage @@ -505,6 +509,8 @@ item_attributes: - num - num - num + - num + - num - list - list - list @@ -553,6 +559,8 @@ item_attributes: - onchange - onchange - onchange + - hourly + - hourly - daily - daily - daily @@ -792,6 +800,14 @@ item_structs: visu_acl: ro # cache: yes + verbrauch_last_24h: + name: Verbrauch innerhalb der letzten 24h + db_addon_fct: verbrauch_last_24h + db_addon_startup: yes + type: num + visu_acl: ro + # cache: yes + verbrauch_woche: name: Verbrauch seit Wochenbeginn db_addon_fct: verbrauch_woche diff --git a/db_addon/user_doc.rst b/db_addon/user_doc.rst index bb3457f48..a83616b44 100644 --- a/db_addon/user_doc.rst +++ b/db_addon/user_doc.rst @@ -68,6 +68,7 @@ Hinweis: Das Plugin selbst ist aktuell nicht multi-instance fähig. Das bedeutet des Database-Plugin abgebunden werden kann. + Konfiguration ============= @@ -92,9 +93,230 @@ Dazu folgenden Block am Ende der Datei */etc/mysql/my.cnf* einfügen bzw den exi interactive_timeout = 28800 -db_addon Item-Attribute -======================= +Hinweise +======== + + - Das Plugin startet die Berechnungen der Werte nach einer gewissen (konfigurierbaren) Zeit (Attribut `startup_run_delay`) + nach dem Start von shNG, um den Startvorgang nicht zu beeinflussen. + + - Bei Start werden automatisch nur die Items berechnet, für das das Attribute `db_addon_startup` gesetzt wurde. Alle anderen + Items werden erst zur konfigurierten Zeit berechnet. Das Attribute `db_addon_startup` kann auch direkt am `Database-Item` + gesetzt werden. Dabei wird das Attribut auf alle darunter liegenden `db_addon-Items` (bspw. bei Verwendung von structs) vererbt. + Über das WebIF kann die Berechnung aller definierten Items ausgelöst werden. + + - Für sogenannte `on_change` Items, also Items, deren Berechnung bis zum Jetzt (bspw. verbrauch-heute) gehen, wird die Berechnung + immer bei eintreffen eines neuen Wertes gestartet. Zu Reduktion der Belastung auf die Datenbank werden die Werte für das Ende der + letzten Periode gecached. + + - Berechnungen werden nur ausgeführt, wenn für den kompletten abgefragten Zeitraum Werte in der Datenbank vorliegen. Wird bspw. + der Verbrauch des letzten Monats abgefragt wobei erst Werte ab dem 3. des Monats in der Datenbank sind, wird die Berechnung abgebrochen. + + - Mit dem Attribut `use_oldest_entry` kann dieses Verhalten verändert werden. Ist das Attribut gesetzt, wird, wenn für den + Beginn der Abfragezeitraums keinen Werte vorliegen, der älteste Eintrag der Datenbank genutzt. + + - Für die Auswertung kann es nützlich sein, bestimmte Werte aus der Datenbank bei der Berechnung auszublenden. Hierfür stehen + 2 Möglichkeiten zur Verfügung: + - Plugin-Attribut `ignore_0`: (list of strings) Bei Items, bei denen ein String aus der Liste im Pfadnamen vorkommt, + werden 0-Werte (val_num = 0) bei Datenbankauswertungen ignoriert. Hat also das Attribut den Wert ['temp'] werden bei allen Items mit + 'temp' im Pfadnamen die 0-Werte bei der Auswertung ignoriert. + - Item-Attribut `db_addon_ignore_value`: (num) Dieser Wert wird bei der Abfrage bzw. Auswertung der Datenbank für diese + Item ignoriert. + + - Das Plugin enthält sehr ausführliche Logginginformation. Bei unerwartetem Verhalten, den LogLevel entsprechend anpassen, + um mehr information zu erhalten. + + - Berechnungen des Plugins können im WebIF unterbrochen werden. Auch das gesamte Plugin kann pausiert werden. Dies kann bei + starker Systembelastung nützlich sein. + + +Beispiele +========= + +Verbrauch +--------- + +Soll bspw. der Verbrauch von Wasser ausgewertet werden, so ist dies wie folgt möglich: + + +.. code-block:: yaml + + wasserzaehler: + zaehlerstand: + type: num + knx_dpt: 12 + knx_cache: 5/3/4 + eval: round(value/1000, 1) + database: init + struct: + - db_addon.verbrauch_1 + - db_addon.verbrauch_2 + - db_addon.zaehlerstand_1 + +Die Werte des Wasserzählerstandes werden in die Datenbank geschrieben und darauf basierend ausgewertet. Die structs +'db_addon.verbrauch_1' und 'db_addon.verbrauch_2' stellen entsprechende Items für die Verbrauchsauswerten zur Verfügung. + +minmax +------ + +Soll bspw. die minimalen und maximalen Temperaturen ausgewertet werden, kann dies so umgesetzt werden: + +.. code-block:: yaml + + temperature: + aussen: + nord: + name: Außentemp Nordseite + type: num + visu_acl: ro + knx_dpt: 9 + knx_cache: 6/5/1 + database: init + struct: + - db_addon.minmax_1 + - db_addon.minmax_2 + +Die Temperaturwerte werden in die Datenbank geschrieben und darauf basierend ausgewertet. Die structs +'db_addon.minmax_1' und 'db_addon.minmax_2' stellen entsprechende Items für die min/max Auswertung zur Verfügung. + +| + +Web Interface +============= + +Das WebIF stellt neben der Ansicht verbundener Items und deren Parameter und Werte auch Funktionen für die +Administration des Plugins bereit. + +Es stehen Button für: + +- Neuberechnung aller Items +- Abbruch eines aktiven Berechnungslaufes +- Pausieren des Plugins +- Wiederaufnahme des Plugins + +bereit. + +Achtung: Das Auslösen einer kompletten Neuberechnung aller Items kann zu einer starken Belastung der Datenbank +aufgrund vieler Leseanfragen führen. + + +db_addon Items +-------------- + +Dieser Reiter des Webinterface zeigt die Items an, für die ein DatabaseAddon Attribut konfiguriert ist. + + +db_addon Maintenance +-------------------- + +Das Webinterface zeigt detaillierte Informationen über die im Plugin verfügbaren Daten an. +Dies dient der Maintenance bzw. Fehlersuche. Dieser Tab ist nur bei Log-Level "Debug" verfügbar. + + +Erläuterungen zu Temperatursummen +================================= + + +Grünlandtemperatursumme +----------------------- + +Beim Grünland wird die Wärmesumme nach Ernst und Loeper benutzt, um den Vegetationsbeginn und somit den Termin von Düngungsmaßnahmen zu bestimmen. +Dabei erfolgt die Aufsummierung der Tagesmitteltemperaturen über 0 °C, wobei der Januar mit 0.5 und der Februar mit 0.75 gewichtet wird. +Bei einer Wärmesumme von 200 Grad ist eine Düngung angesagt. + +siehe: https://de.wikipedia.org/wiki/Gr%C3%BCnlandtemperatursumme + +Folgende Parameter sind möglich / notwendig: + + +.. code-block:: yaml + + db_addon_params: "year=current" + +- year: Jahreszahl (str oder int), für das die Berechnung ausgeführt werden soll oder "current" für aktuelles Jahr (default: 'current') + + +Wachstumsgradtag +---------------- +Der Begriff Wachstumsgradtage (WGT) ist ein Überbegriff für verschiedene Größen. +Gemeinsam ist ihnen, daß zur Berechnung eine Lufttemperatur von einem Schwellenwert subtrahiert wird. +Je nach Fragestellung und Pflanzenart werden der Schwellenwert unterschiedlich gewählt und die Temperatur unterschiedlich bestimmt. +Verfügbar sind die Berechnung über 0) "einfachen Durchschnitt der Tagestemperaturen", 1) "modifizierten Durchschnitt der Tagestemperaturen" +und 2) Anzahl der Tage, deren Mitteltempertatur oberhalb der Schwellentemperatur lag. + +siehe https://de.wikipedia.org/wiki/Wachstumsgradtag + +Folgende Parameter sind möglich / notwendig: + +.. code-block:: yaml + + db_addon_params: "year=current, method=1, threshold=10" + +- year: Jahreszahl (str oder int), für das die Berechnung ausgeführt werden soll oder "current" für aktuelles Jahr (default: 'current') +- method: 0-Berechnung über "einfachen Durchschnitt der Tagestemperaturen", 1-Berechnung über "modifizierten Durchschnitt (default: 0) +der Tagestemperaturen" 2-Anzahl der Tage, mit Mitteltempertatur oberhalb Schwellentemperatur// 10, 11 Ausgabe aus Zeitserie +- threshold: Schwellentemperatur in °C (int) (default: 10) + + +Wärmesumme +---------- + +Die Wärmesumme soll eine Aussage über den Sommer und die Pflanzenreife liefern. Es gibt keine eindeutige Definition der Größe "Wärmesumme". +Berechnet wird die Wärmesumme als Summe aller Tagesmitteltemperaturen über einem Schwellenwert ab dem 1.1. des Jahres. + +siehe https://de.wikipedia.org/wiki/W%C3%A4rmesumme + +Folgende Parameter sind möglich / notwendig: + +.. code-block:: yaml + + db_addon_params: "year=current, month=1, threshold=10" + +- year: Jahreszahl (str oder int), für das die Berechnung ausgeführt werden soll oder "current" für aktuelles Jahr (default: 'current') +- month: Monat (int) des Jahres, für das die Berechnung ausgeführt werden soll (optional) (default: None) +- threshold: Schwellentemperatur in °C (int) (default: 10) + + +Kältesumme +---------- + +Die Kältesumme soll eine Aussage über die Härte des Winters liefern. +Berechnet wird die Kältesumme als Summe aller negativen Tagesmitteltemperaturen ab dem 21.9. des Jahres bis 31.3. des Folgejahres. + +siehe https://de.wikipedia.org/wiki/K%C3%A4ltesumme + +Folgende Parameter sind möglich / notwendig: + +.. code-block:: yaml + + db_addon_params: "year=current, month=1" + +- year: Jahreszahl (str oder int), für das die Berechnung ausgeführt werden soll oder "current" für aktuelles Jahr (default: 'current') +- month: Monat (int) des Jahres, für das die Berechnung ausgeführt werden soll (optional) (default: None) + + +Tagesmitteltemperatur +--------------------- + +Die Tagesmitteltemperatur wird auf Basis der stündlichen Durchschnittswerte eines Tages (aller in der DB enthaltenen Datensätze) +für die angegebene Anzahl von Tagen (days=optional) berechnet. + + + +Vorgehen bei Funktionserweiterung des Plugins bzw. Ergänzung weiterer Werte für Item-Attribute +---------------------------------------------------------------------------------------------- + +Aufgrund der Vielzahl der möglichen Werte der Itemattribute, insbesondere des Itemattributes `db_addon_fct`, wurde die Erstellung/Update +der entsprechenden Teile der `plugin.yam` sowie die Erstellung der Datei `item_attributes.py`, die vom Plugin verwendet wird, automatisiert. + +Die Masterinformationen für alle Itemattribute sowie die Skripte zum Erstellen/Update der beiden Dateien sind in der +Datei `item_attributes_master.py` enthalten. + +.. important:: + + Korrekturen, Erweiterungen etc. der Itemattribute sollten nur in der Datei `item_attributes_master.py` + im Dict der Variable `ITEM_ATTRIBUTS` vorgenommen werden. Das Ausführen der Datei `item_attributes_master.py` (main) + erstellt die `item_attributes.py` und aktualisiert die `plugin.yaml` entsprechend. Dieses Kapitel wurde automatisch durch Ausführen des Skripts in der Datei 'item_attributes_master.py' erstellt. Nachfolgend eine Auflistung der möglichen Attribute für das Plugin im Format: Attribute: Beschreibung | Berechnungszyklus | Item-Type @@ -113,6 +335,10 @@ db_addon_fct - verbrauch_jahr: Verbrauch im aktuellen Jahr | Berechnung: onchange | Item-Type: num +- verbrauch_last_24h: Verbrauch innerhalb letzten 24h | Berechnung: hourly | Item-Type: num + +- verbrauch_last_7d: Verbrauch innerhalb letzten 7 Tage | Berechnung: hourly | Item-Type: num + - verbrauch_heute_minus1: Verbrauch gestern (heute -1 Tag) (Differenz zwischen Wert am Ende des gestrigen Tages und dem Wert am Ende des Tages davor) | Berechnung: daily | Item-Type: num - verbrauch_heute_minus2: Verbrauch vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num @@ -466,67 +692,6 @@ Hinweise starker Systembelastung nützlich sein. -Konfiguration im Item -===================== - -direkt ------- -Bei der direkten Konfiguration wird das auszuwertende Database-Item durch das Plugin selbst bestimmt. Dazu muss die Konfiguration des -Attributes `db_addon_fct` oder eines entsprechenden `struct` direkt im Database-Item oder in der Itemstruktur bis zu 3 Ebenen darunter erfolgen. - -.. code-block:: yaml - wasserzaehler: - zaehlerstand: - type: num - knx_dpt: 12 - knx_cache: 5/3/4 - database: init - struct: - - db_addon.verbrauch_1 - -oder - -.. code-block:: yaml - wasserzaehler: - zaehlerstand: - type: num - knx_dpt: 12 - knx_cache: 5/3/4 - database: init - - auswertung: - type: foo - struct: - - db_addon.verbrauch_1 - - -indirekt --------- -Bei der indirekten Konfiguration muss das auszuwertende Database-Item zusätzlich über das Attribut `db_addon_database_item` konfiguriert/angegeben werden. -Die Konfiguration kann somit frei im Itembaum erfolgen. Es wird hier der gleiche Syntax wie bei `eval_trigger` verwendet (Itempfad als String) - -.. code-block:: yaml - wasserzaehler: - zaehlerstand: - type: num - knx_dpt: 12 - knx_cache: 5/3/4 - database: init - - auswertungen: - wasser: - typ: foo - db_addon_database_item: wasserzaehler.zaehlerstand - db_addon_startup: yes - db_addon_ignore_value_list: ['!=0'] - struct: - - db_addon.verbrauch_1 - -Hinweis: -Da ein Zähler nicht 0 werden kann/sollte, aber beim Starten/Beenden von shNG auch 0 in die Datenbank geschrieben wird, kann man mit Hilfe des Attributs `db_addon_ignore_value_list` -diese Werte bei Abfragen der Datenbank maskieren. - - Beispiele ========= @@ -537,6 +702,7 @@ Soll bspw. der Verbrauch von Wasser ausgewertet werden, so ist dies wie folgt m .. code-block:: yaml + wasserzaehler: zaehlerstand: type: num @@ -558,6 +724,7 @@ minmax Soll bspw. die minimalen und maximalen Temperaturen ausgewertet werden, kann dies so umgesetzt werden: .. code-block:: yaml + temperature: aussen: nord: @@ -574,7 +741,7 @@ Soll bspw. die minimalen und maximalen Temperaturen ausgewertet werden, kann die Die Temperaturwerte werden in die Datenbank geschrieben und darauf basierend ausgewertet. Die structs 'db_addon.minmax_1' und 'db_addon.minmax_2' stellen entsprechende Items für die min/max Auswertung zur Verfügung. - +| Web Interface ============= @@ -615,8 +782,8 @@ Erläuterungen zu Temperatursummen Grünlandtemperatursumme ----------------------- -Beim Grünland wird die Wärmesumme nach Ernst und Loeper benutzt, um den Vegetationsbeginn und somit den Termin von Düngungsmaßnahmen zu bestimmen. -Dabei erfolgt die Aufsummierung der Tagesmitteltemperaturen über 0 °C, wobei der Januar mit 0.5 und der Februar mit 0.75 gewichtet wird. +Beim Grünland wird die Wärmesumme nach Ernst und Loeper benutzt, um den Vegetationsbeginn und somit den Termin von Düngungsmaßnahmen zu bestimmen. +Dabei erfolgt die Aufsummierung der Tagesmitteltemperaturen über 0 °C, wobei der Januar mit 0.5 und der Februar mit 0.75 gewichtet wird. Bei einer Wärmesumme von 200 Grad ist eine Düngung angesagt. siehe: https://de.wikipedia.org/wiki/Gr%C3%BCnlandtemperatursumme @@ -625,6 +792,7 @@ Folgende Parameter sind möglich / notwendig: .. code-block:: yaml + db_addon_params: "year=current" - year: Jahreszahl (str oder int), für das die Berechnung ausgeführt werden soll oder "current" für aktuelles Jahr (default: 'current') @@ -632,10 +800,10 @@ Folgende Parameter sind möglich / notwendig: Wachstumsgradtag ---------------- -Der Begriff Wachstumsgradtage (WGT) ist ein Überbegriff für verschiedene Größen. -Gemeinsam ist ihnen, daß zur Berechnung eine Lufttemperatur von einem Schwellenwert subtrahiert wird. -Je nach Fragestellung und Pflanzenart werden der Schwellenwert unterschiedlich gewählt und die Temperatur unterschiedlich bestimmt. -Verfügbar sind die Berechnung über 0) "einfachen Durchschnitt der Tagestemperaturen", 1) "modifizierten Durchschnitt der Tagestemperaturen" +Der Begriff Wachstumsgradtage (WGT) ist ein Überbegriff für verschiedene Größen. +Gemeinsam ist ihnen, daß zur Berechnung eine Lufttemperatur von einem Schwellenwert subtrahiert wird. +Je nach Fragestellung und Pflanzenart werden der Schwellenwert unterschiedlich gewählt und die Temperatur unterschiedlich bestimmt. +Verfügbar sind die Berechnung über 0) "einfachen Durchschnitt der Tagestemperaturen", 1) "modifizierten Durchschnitt der Tagestemperaturen" und 2) Anzahl der Tage, deren Mitteltempertatur oberhalb der Schwellentemperatur lag. siehe https://de.wikipedia.org/wiki/Wachstumsgradtag @@ -643,6 +811,7 @@ siehe https://de.wikipedia.org/wiki/Wachstumsgradtag Folgende Parameter sind möglich / notwendig: .. code-block:: yaml + db_addon_params: "year=current, method=1, threshold=10" - year: Jahreszahl (str oder int), für das die Berechnung ausgeführt werden soll oder "current" für aktuelles Jahr (default: 'current') @@ -655,13 +824,14 @@ Wärmesumme ---------- Die Wärmesumme soll eine Aussage über den Sommer und die Pflanzenreife liefern. Es gibt keine eindeutige Definition der Größe "Wärmesumme". -Berechnet wird die Wärmesumme als Summe aller Tagesmitteltemperaturen über einem Schwellenwert ab dem 1.1. des Jahres. +Berechnet wird die Wärmesumme als Summe aller Tagesmitteltemperaturen über einem Schwellenwert ab dem 1.1. des Jahres. siehe https://de.wikipedia.org/wiki/W%C3%A4rmesumme Folgende Parameter sind möglich / notwendig: .. code-block:: yaml + db_addon_params: "year=current, month=1, threshold=10" - year: Jahreszahl (str oder int), für das die Berechnung ausgeführt werden soll oder "current" für aktuelles Jahr (default: 'current') @@ -672,7 +842,7 @@ Folgende Parameter sind möglich / notwendig: Kältesumme ---------- -Die Kältesumme soll eine Aussage über die Härte des Winters liefern. +Die Kältesumme soll eine Aussage über die Härte des Winters liefern. Berechnet wird die Kältesumme als Summe aller negativen Tagesmitteltemperaturen ab dem 21.9. des Jahres bis 31.3. des Folgejahres. siehe https://de.wikipedia.org/wiki/K%C3%A4ltesumme @@ -680,6 +850,7 @@ siehe https://de.wikipedia.org/wiki/K%C3%A4ltesumme Folgende Parameter sind möglich / notwendig: .. code-block:: yaml + db_addon_params: "year=current, month=1" - year: Jahreszahl (str oder int), für das die Berechnung ausgeführt werden soll oder "current" für aktuelles Jahr (default: 'current') @@ -697,14 +868,14 @@ für die angegebene Anzahl von Tagen (days=optional) berechnet. Vorgehen bei Funktionserweiterung des Plugins bzw. Ergänzung weiterer Werte für Item-Attribute ---------------------------------------------------------------------------------------------- -Augrund der Vielzahl der möglichen Werte der Itemattribute, insbesondere des Itemattributes`db_addon_fct`, wurde die Erstellung/Update +Aufgrund der Vielzahl der möglichen Werte der Itemattribute, insbesondere des Itemattributes `db_addon_fct`, wurde die Erstellung/Update der entsprechenden Teile der `plugin.yam` sowie die Erstellung der Datei `item_attributes.py`, die vom Plugin verwendet wird, automatisiert. -Die Masterinformationen für alle Itemattributs sowie die Skripte zum Erstellen/Update der beiden Dateien sind in der +Die Masterinformationen für alle Itemattribute sowie die Skripte zum Erstellen/Update der beiden Dateien sind in der Datei `item_attributes_master.py` enthalten. .. important:: Korrekturen, Erweiterungen etc. der Itemattribute sollten nur in der Datei `item_attributes_master.py` im Dict der Variable `ITEM_ATTRIBUTS` vorgenommen werden. Das Ausführen der Datei `item_attributes_master.py` (main) - erstellt die `item_attributes.py` und aktualisiert die `plugin.yaml` entsprechend. \ No newline at end of file + erstellt die `item_attributes.py` und aktualisiert die `plugin.yaml` entsprechend. diff --git a/db_addon/webif/__init__.py b/db_addon/webif/__init__.py index 05dbb8d7a..e4ee8dcee 100644 --- a/db_addon/webif/__init__.py +++ b/db_addon/webif/__init__.py @@ -131,23 +131,40 @@ def get_data_html(self, dataSet=None): self.logger.error(f"get_data_html exception: {e}") @cherrypy.expose - def submit(self, param1=None): - ''' - Submit handler für Ajax - ''' + def submit(self, item=None): result = None + item_path, cmd = item.split(':') + if item_path is not None and cmd is not None: + self.logger.debug(f"Sending db_addon {cmd=} for {item_path=} via web interface") - self.logger.warning(f'{param1}') - - if param1 is not None: - - # verarbeite die Daten - self.logger.warning(f'{param1}') + if cmd == "recalc_item": + self.logger.info(f"Recalc of item={item_path} called via WebIF. Item put to Queue for new calculation.") + result = self.plugin.execute_items(option='item', item=item_path) + self.logger.debug(f"Result for web interface: {result}") + return json.dumps(result).encode('utf-8') - if result_dict is not None: + elif cmd == "clean_item_cache": + self.logger.info(f"Clean item cache of item={item_path} called via WebIF. Plugin item value cache will be cleaned.") + result = self.plugin._clean_item_cache(item=item_path) + self.logger.debug(f"Result for web interface: {result}") + return json.dumps(result).encode('utf-8') + + elif cmd.startswith("set_item_calculation"): + cmd, value = cmd.split(',') + self.logger.info(f"Item calculation of item={item_path} will be set to '{value}' via WebIF.") + if value == "True": + value = True + else: + value = False + result = self.plugin._activate_item_calculation(item=item_path, active=value) + self.logger.debug(f"Result for web interface: {result}") + return json.dumps(result).encode('utf-8') + + if result is not None: # JSON zurücksenden cherrypy.response.headers['Content-Type'] = 'application/json' - return json.dumps(result_dict).encode('utf-8') + self.logger.debug(f"Result for web interface: {result}") + return json.dumps(result).encode('utf-8') @cherrypy.expose def recalc_all(self): @@ -238,4 +255,4 @@ def debug_log_option_sql_true(self): @cherrypy.expose def debug_log_option_sql_false (self): self.logger.debug("debug_log_option_sql_false") - setattr(self.plugin.debug_log, 'sql', False) \ No newline at end of file + setattr(self.plugin.debug_log, 'sql', False) diff --git a/db_addon/webif/templates/index.html b/db_addon/webif/templates/index.html index cf6eb4964..5bcd657ce 100644 --- a/db_addon/webif/templates/index.html +++ b/db_addon/webif/templates/index.html @@ -64,6 +64,49 @@ {% block pluginscripts %} + + @@ -287,10 +307,15 @@ + {% endblock pluginscripts %} @@ -333,24 +358,26 @@ @@ -404,22 +431,11 @@ {% endfor %} @@ -427,6 +443,7 @@
{{ (p.startup_run_delay) }}s
{{ key }}{{ value }}{{ key }}{% for letter in value %}*{% endfor %}
{{ key }}{{ value }}{{ key }}{% for letter in value %}*{% endfor %}
{{ _('Item in Berechnung') }} {{ p.active_queue_item }} {{ p.log_level }} {% if p.log_level == 10 %} - {{ (' || ') }} -
- -
-
- -
-
- -
-
- -
-
- -
-
- +
+ {{ (' || ') }} +
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
{% endif %}
{{ item.property.last_update.strftime('%d.%m.%Y %H:%M:%S') }} {{ item.property.last_change.strftime('%d.%m.%Y %H:%M:%S') }} - - - {% if p.get_item_config(item._path)['active'] %} - - {% else %} - - {% endif %} + + - + +
+
{% endblock bodytab1 %} From 571b923f46a7cbffa1c26f480bbc663e95c3214b Mon Sep 17 00:00:00 2001 From: sisamiwe Date: Thu, 21 Sep 2023 14:06:21 +0200 Subject: [PATCH 12/18] DB_ADDON: - update WebIF for button - debug _handle_verbrauch - update docu - bump to 1.2.6 --- db_addon/__init__.py | 28 +- db_addon/item_attributes_master.py | 2 +- db_addon/plugin.yaml | 2 +- db_addon/user_doc.rst | 562 ++++++++++++++++++++++++++++ db_addon/webif/__init__.py | 22 +- db_addon/webif/templates/index.html | 187 ++++----- 6 files changed, 673 insertions(+), 130 deletions(-) diff --git a/db_addon/__init__.py b/db_addon/__init__.py index b728211e8..737c4fb26 100644 --- a/db_addon/__init__.py +++ b/db_addon/__init__.py @@ -61,7 +61,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.5' + PLUGIN_VERSION = '1.2.6' def __init__(self, sh): """ @@ -273,7 +273,7 @@ def get_query_parameters_from_db_addon_fct() -> Union[dict, None]: # handle functions 'verbrauch on-demand' in format 'verbrauch_timeframe_timedelta' like 'verbrauch_heute_minus2' timeframe = translate_timeframe(db_addon_fct_vars[1]) end = to_int(split_sting_letters_numbers(db_addon_fct_vars[2])[1]) - start = end + 1 + start = end log_text = 'verbrauch_timeframe_timedelta' required_params = [timeframe, start, end] @@ -673,7 +673,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, 'active': True} + item_config_data_dict = {'db_addon': 'function', 'db_addon_fct': db_addon_fct, 'database_item': database_item, 'query_params': query_params, 'suspended': False} if isinstance(database_item, str): item_config_data_dict.update({'database_item_path': True}) else: @@ -949,9 +949,9 @@ def _create_due_items() -> list: self.logger.info(f"Plugin is suspended. No items will be calculated.") return - deactivated_items = self._deactivated_items() - if len(deactivated_items) > 0: - self.logger.info(f"{len(deactivated_items)} are de-activated and will not be calculated.") + suspended_items = self._suspended_items() + if len(suspended_items) > 0: + self.logger.info(f"{len(suspended_items)} are suspended and will not be calculated.") todo_items = [] if option == 'startup': @@ -974,9 +974,9 @@ def _create_due_items() -> list: if isinstance(item, Item): todo_items = [item] - # remove de-activated items + # remove suspended items if option != 'item': - todo_items = list(set(todo_items) - set(deactivated_items)) + todo_items = list(set(todo_items) - set(suspended_items)) # put to queue self.logger.info(f"{len(todo_items)} items will be calculated for {option=}.") @@ -1270,8 +1270,8 @@ def _update_database_items(self) -> None: if db_addon_startup: item_config.update({'startup': True}) - def _activate_item_calculation(self, item: Union[str, Item], active: bool = True) -> Union[bool, None]: - """active / de-active item calculation""" + def _suspend_item_calculation(self, item: Union[str, Item], suspended: bool = False) -> Union[bool, None]: + """suspend calculation od decicated item""" if isinstance(item, str): item = self.items.return_item(item) @@ -1279,8 +1279,8 @@ def _activate_item_calculation(self, item: Union[str, Item], active: bool = True return item_config = self.get_item_config(item) - item_config['active'] = active - return active + item_config['suspended'] = suspended + return suspended @property def log_level(self) -> int: @@ -1331,8 +1331,8 @@ def _database_item_path_items(self) -> list: def _ondemand_items(self) -> list: return self._daily_items() + self._weekly_items() + self._monthly_items() + self._yearly_items() + self._static_items() - def _deactivated_items(self) -> list: - return self.get_item_list('active', False) + def _suspended_items(self) -> list: + return self.get_item_list('suspended', True) def _all_items(self) -> list: # return self._ondemand_items() + self._onchange_items() + self._static_items() + self._admin_items() + self._info_items() diff --git a/db_addon/item_attributes_master.py b/db_addon/item_attributes_master.py index b6ddb65a0..2244f4ce6 100644 --- a/db_addon/item_attributes_master.py +++ b/db_addon/item_attributes_master.py @@ -27,7 +27,7 @@ DOC_FILE_NAME = 'user_doc.rst' -PLUGIN_VERSION = '1.2.5' +PLUGIN_VERSION = '1.2.6' ITEM_ATTRIBUTES = { 'db_addon_fct': { diff --git a/db_addon/plugin.yaml b/db_addon/plugin.yaml index dfb51fbb7..776c7d7d7 100644 --- a/db_addon/plugin.yaml +++ b/db_addon/plugin.yaml @@ -11,7 +11,7 @@ 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.5 # Plugin version (must match the version specified in __init__.py) + version: 1.2.6 # 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 diff --git a/db_addon/user_doc.rst b/db_addon/user_doc.rst index a83616b44..fb274f839 100644 --- a/db_addon/user_doc.rst +++ b/db_addon/user_doc.rst @@ -865,6 +865,568 @@ für die angegebene Anzahl von Tagen (days=optional) berechnet. +Vorgehen bei Funktionserweiterung des Plugins bzw. Ergänzung weiterer Werte für Item-Attribute +---------------------------------------------------------------------------------------------- + +Aufgrund der Vielzahl der möglichen Werte der Itemattribute, insbesondere des Itemattributes `db_addon_fct`, wurde die Erstellung/Update +der entsprechenden Teile der `plugin.yam` sowie die Erstellung der Datei `item_attributes.py`, die vom Plugin verwendet wird, automatisiert. + +Die Masterinformationen für alle Itemattribute sowie die Skripte zum Erstellen/Update der beiden Dateien sind in der +Datei `item_attributes_master.py` enthalten. + +.. important:: + + Korrekturen, Erweiterungen etc. der Itemattribute sollten nur in der Datei `item_attributes_master.py` + im Dict der Variable `ITEM_ATTRIBUTS` vorgenommen werden. Das Ausführen der Datei `item_attributes_master.py` (main) + erstellt die `item_attributes.py` und aktualisiert die `plugin.yaml` entsprechend. +Dieses Kapitel wurde automatisch durch Ausführen des Skripts in der Datei 'item_attributes_master.py' erstellt. + +Nachfolgend eine Auflistung der möglichen Attribute für das Plugin im Format: Attribute: Beschreibung | Berechnungszyklus | Item-Type + + +db_addon_fct +------------ + +- verbrauch_heute: Verbrauch am heutigen Tag (Differenz zwischen aktuellem Wert und den Wert am Ende des vorherigen Tages) | Berechnung: onchange | Item-Type: num + +- verbrauch_tag: Verbrauch am heutigen Tag (Differenz zwischen aktuellem Wert und den Wert am Ende des vorherigen Tages) | Berechnung: onchange | Item-Type: num + +- verbrauch_woche: Verbrauch in der aktuellen Woche | Berechnung: onchange | Item-Type: num + +- verbrauch_monat: Verbrauch im aktuellen Monat | Berechnung: onchange | Item-Type: num + +- verbrauch_jahr: Verbrauch im aktuellen Jahr | Berechnung: onchange | Item-Type: num + +- verbrauch_last_24h: Verbrauch innerhalb letzten 24h | Berechnung: hourly | Item-Type: num + +- verbrauch_last_7d: Verbrauch innerhalb letzten 7 Tage | Berechnung: hourly | Item-Type: num + +- verbrauch_heute_minus1: Verbrauch gestern (heute -1 Tag) (Differenz zwischen Wert am Ende des gestrigen Tages und dem Wert am Ende des Tages davor) | Berechnung: daily | Item-Type: num + +- verbrauch_heute_minus2: Verbrauch vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num + +- verbrauch_heute_minus3: Verbrauch heute -3 Tage | Berechnung: daily | Item-Type: num + +- verbrauch_heute_minus4: Verbrauch heute -4 Tage | Berechnung: daily | Item-Type: num + +- verbrauch_heute_minus5: Verbrauch heute -5 Tage | Berechnung: daily | Item-Type: num + +- verbrauch_heute_minus6: Verbrauch heute -6 Tage | Berechnung: daily | Item-Type: num + +- verbrauch_heute_minus7: Verbrauch heute -7 Tage | Berechnung: daily | Item-Type: num + +- verbrauch_heute_minus8: Verbrauch heute -8 Tage | Berechnung: daily | Item-Type: num + +- verbrauch_tag_minus1: Verbrauch gestern (heute -1 Tag) (Differenz zwischen Wert am Ende des gestrigen Tages und dem Wert am Ende des Tages davor) | Berechnung: daily | Item-Type: num + +- verbrauch_tag_minus2: Verbrauch vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num + +- verbrauch_tag_minus3: Verbrauch heute -3 Tage | Berechnung: daily | Item-Type: num + +- verbrauch_tag_minus4: Verbrauch heute -4 Tage | Berechnung: daily | Item-Type: num + +- verbrauch_tag_minus5: Verbrauch heute -5 Tage | Berechnung: daily | Item-Type: num + +- verbrauch_tag_minus6: Verbrauch heute -6 Tage | Berechnung: daily | Item-Type: num + +- verbrauch_tag_minus7: Verbrauch heute -7 Tage | Berechnung: daily | Item-Type: num + +- verbrauch_tag_minus8: Verbrauch heute -8 Tage | Berechnung: daily | Item-Type: num + +- verbrauch_woche_minus1: Verbrauch Vorwoche (aktuelle Woche -1) | Berechnung: weekly | Item-Type: num + +- verbrauch_woche_minus2: Verbrauch aktuelle Woche -2 Wochen | Berechnung: weekly | Item-Type: num + +- verbrauch_woche_minus3: Verbrauch aktuelle Woche -3 Wochen | Berechnung: weekly | Item-Type: num + +- verbrauch_woche_minus4: Verbrauch aktuelle Woche -4 Wochen | Berechnung: weekly | Item-Type: num + +- verbrauch_monat_minus1: Verbrauch Vormonat (aktueller Monat -1) | Berechnung: monthly | Item-Type: num + +- verbrauch_monat_minus2: Verbrauch aktueller Monat -2 Monate | Berechnung: monthly | Item-Type: num + +- verbrauch_monat_minus3: Verbrauch aktueller Monat -3 Monate | Berechnung: monthly | Item-Type: num + +- verbrauch_monat_minus4: Verbrauch aktueller Monat -4 Monate | Berechnung: monthly | Item-Type: num + +- verbrauch_monat_minus12: Verbrauch aktueller Monat -12 Monate | Berechnung: monthly | Item-Type: num + +- verbrauch_jahr_minus1: Verbrauch Vorjahr (aktuelles Jahr -1 Jahr) | Berechnung: yearly | Item-Type: num + +- verbrauch_jahr_minus2: Verbrauch aktuelles Jahr -2 Jahre | Berechnung: yearly | Item-Type: num + +- verbrauch_rolling_12m_heute_minus1: Verbrauch der letzten 12 Monate ausgehend im Ende des letzten Tages | Berechnung: daily | Item-Type: num + +- verbrauch_rolling_12m_tag_minus1: Verbrauch der letzten 12 Monate ausgehend im Ende des letzten Tages | Berechnung: daily | Item-Type: num + +- verbrauch_rolling_12m_woche_minus1: Verbrauch der letzten 12 Monate ausgehend im Ende der letzten Woche | Berechnung: weekly | Item-Type: num + +- verbrauch_rolling_12m_monat_minus1: Verbrauch der letzten 12 Monate ausgehend im Ende des letzten Monats | Berechnung: monthly | Item-Type: num + +- verbrauch_rolling_12m_jahr_minus1: Verbrauch der letzten 12 Monate ausgehend im Ende des letzten Jahres | Berechnung: yearly | Item-Type: num + +- verbrauch_jahreszeitraum_minus1: Verbrauch seit dem 1.1. bis zum heutigen Tag des Vorjahres | Berechnung: daily | Item-Type: num + +- verbrauch_jahreszeitraum_minus2: Verbrauch seit dem 1.1. bis zum heutigen Tag vor 2 Jahren | Berechnung: daily | Item-Type: num + +- verbrauch_jahreszeitraum_minus3: Verbrauch seit dem 1.1. bis zum heutigen Tag vor 3 Jahren | Berechnung: daily | Item-Type: num + +- zaehlerstand_heute_minus1: Zählerstand / Wert am Ende des letzten Tages (heute -1 Tag) | Berechnung: daily | Item-Type: num + +- zaehlerstand_heute_minus2: Zählerstand / Wert am Ende des vorletzten Tages (heute -2 Tag) | Berechnung: daily | Item-Type: num + +- zaehlerstand_heute_minus3: Zählerstand / Wert am Ende des vorvorletzten Tages (heute -3 Tag) | Berechnung: daily | Item-Type: num + +- zaehlerstand_tag_minus1: Zählerstand / Wert am Ende des letzten Tages (heute -1 Tag) | Berechnung: daily | Item-Type: num + +- zaehlerstand_tag_minus2: Zählerstand / Wert am Ende des vorletzten Tages (heute -2 Tag) | Berechnung: daily | Item-Type: num + +- zaehlerstand_tag_minus3: Zählerstand / Wert am Ende des vorvorletzten Tages (heute -3 Tag) | Berechnung: daily | Item-Type: num + +- zaehlerstand_woche_minus1: Zählerstand / Wert am Ende der vorvorletzten Woche (aktuelle Woche -1 Woche) | Berechnung: weekly | Item-Type: num + +- zaehlerstand_woche_minus2: Zählerstand / Wert am Ende der vorletzten Woche (aktuelle Woche -2 Wochen) | Berechnung: weekly | Item-Type: num + +- zaehlerstand_woche_minus3: Zählerstand / Wert am Ende der aktuellen Woche -3 Wochen | Berechnung: weekly | Item-Type: num + +- zaehlerstand_monat_minus1: Zählerstand / Wert am Ende des letzten Monates (aktueller Monat -1 Monat) | Berechnung: monthly | Item-Type: num + +- zaehlerstand_monat_minus2: Zählerstand / Wert am Ende des vorletzten Monates (aktueller Monat -2 Monate) | Berechnung: monthly | Item-Type: num + +- zaehlerstand_monat_minus3: Zählerstand / Wert am Ende des aktuellen Monats -3 Monate | Berechnung: monthly | Item-Type: num + +- zaehlerstand_jahr_minus1: Zählerstand / Wert am Ende des letzten Jahres (aktuelles Jahr -1 Jahr) | Berechnung: yearly | Item-Type: num + +- zaehlerstand_jahr_minus2: Zählerstand / Wert am Ende des vorletzten Jahres (aktuelles Jahr -2 Jahre) | Berechnung: yearly | Item-Type: num + +- zaehlerstand_jahr_minus3: Zählerstand / Wert am Ende des aktuellen Jahres -3 Jahre | Berechnung: yearly | Item-Type: num + +- minmax_last_24h_min: minimaler Wert der letzten 24h | Berechnung: daily | Item-Type: num + +- minmax_last_24h_max: maximaler Wert der letzten 24h | Berechnung: daily | Item-Type: num + +- minmax_last_24h_avg: durchschnittlicher Wert der letzten 24h | Berechnung: daily | Item-Type: num + +- minmax_last_7d_min: minimaler Wert der letzten 7 Tage | Berechnung: daily | Item-Type: num + +- minmax_last_7d_max: maximaler Wert der letzten 7 Tage | Berechnung: daily | Item-Type: num + +- minmax_last_7d_avg: durchschnittlicher Wert der letzten 7 Tage | Berechnung: daily | Item-Type: num + +- minmax_heute_min: Minimalwert seit Tagesbeginn | Berechnung: onchange | Item-Type: num + +- minmax_heute_max: Maximalwert seit Tagesbeginn | Berechnung: onchange | Item-Type: num + +- minmax_heute_avg: Durschnittswert seit Tagesbeginn | Berechnung: onchange | Item-Type: num + +- minmax_heute_minus1_min: Minimalwert gestern (heute -1 Tag) | Berechnung: daily | Item-Type: num + +- minmax_heute_minus1_max: Maximalwert gestern (heute -1 Tag) | Berechnung: daily | Item-Type: num + +- minmax_heute_minus1_avg: Durchschnittswert gestern (heute -1 Tag) | Berechnung: daily | Item-Type: num + +- minmax_heute_minus2_min: Minimalwert vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num + +- minmax_heute_minus2_max: Maximalwert vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num + +- minmax_heute_minus2_avg: Durchschnittswert vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num + +- minmax_heute_minus3_min: Minimalwert heute vor 3 Tagen | Berechnung: daily | Item-Type: num + +- minmax_heute_minus3_max: Maximalwert heute vor 3 Tagen | Berechnung: daily | Item-Type: num + +- minmax_heute_minus3_avg: Durchschnittswert heute vor 3 Tagen | Berechnung: daily | Item-Type: num + +- minmax_tag_min: Minimalwert seit Tagesbeginn | Berechnung: onchange | Item-Type: num + +- minmax_tag_max: Maximalwert seit Tagesbeginn | Berechnung: onchange | Item-Type: num + +- minmax_tag_avg: Durschnittswert seit Tagesbeginn | Berechnung: onchange | Item-Type: num + +- minmax_tag_minus1_min: Minimalwert gestern (heute -1 Tag) | Berechnung: daily | Item-Type: num + +- minmax_tag_minus1_max: Maximalwert gestern (heute -1 Tag) | Berechnung: daily | Item-Type: num + +- minmax_tag_minus1_avg: Durchschnittswert gestern (heute -1 Tag) | Berechnung: daily | Item-Type: num + +- minmax_tag_minus2_min: Minimalwert vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num + +- minmax_tag_minus2_max: Maximalwert vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num + +- minmax_tag_minus2_avg: Durchschnittswert vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num + +- minmax_tag_minus3_min: Minimalwert heute vor 3 Tagen | Berechnung: daily | Item-Type: num + +- minmax_tag_minus3_max: Maximalwert heute vor 3 Tagen | Berechnung: daily | Item-Type: num + +- minmax_tag_minus3_avg: Durchschnittswert heute vor 3 Tagen | Berechnung: daily | Item-Type: num + +- minmax_woche_min: Minimalwert seit Wochenbeginn | Berechnung: onchange | Item-Type: num + +- minmax_woche_max: Maximalwert seit Wochenbeginn | Berechnung: onchange | Item-Type: num + +- minmax_woche_minus1_min: Minimalwert Vorwoche (aktuelle Woche -1) | Berechnung: weekly | Item-Type: num + +- minmax_woche_minus1_max: Maximalwert Vorwoche (aktuelle Woche -1) | Berechnung: weekly | Item-Type: num + +- minmax_woche_minus1_avg: Durchschnittswert Vorwoche (aktuelle Woche -1) | Berechnung: weekly | Item-Type: num + +- minmax_woche_minus2_min: Minimalwert aktuelle Woche -2 Wochen | Berechnung: weekly | Item-Type: num + +- minmax_woche_minus2_max: Maximalwert aktuelle Woche -2 Wochen | Berechnung: weekly | Item-Type: num + +- minmax_woche_minus2_avg: Durchschnittswert aktuelle Woche -2 Wochen | Berechnung: weekly | Item-Type: num + +- minmax_monat_min: Minimalwert seit Monatsbeginn | Berechnung: onchange | Item-Type: num + +- minmax_monat_max: Maximalwert seit Monatsbeginn | Berechnung: onchange | Item-Type: num + +- minmax_monat_minus1_min: Minimalwert Vormonat (aktueller Monat -1) | Berechnung: monthly | Item-Type: num + +- minmax_monat_minus1_max: Maximalwert Vormonat (aktueller Monat -1) | Berechnung: monthly | Item-Type: num + +- minmax_monat_minus1_avg: Durchschnittswert Vormonat (aktueller Monat -1) | Berechnung: monthly | Item-Type: num + +- minmax_monat_minus2_min: Minimalwert aktueller Monat -2 Monate | Berechnung: monthly | Item-Type: num + +- minmax_monat_minus2_max: Maximalwert aktueller Monat -2 Monate | Berechnung: monthly | Item-Type: num + +- minmax_monat_minus2_avg: Durchschnittswert aktueller Monat -2 Monate | Berechnung: monthly | Item-Type: num + +- minmax_jahr_min: Minimalwert seit Jahresbeginn | Berechnung: onchange | Item-Type: num + +- minmax_jahr_max: Maximalwert seit Jahresbeginn | Berechnung: onchange | Item-Type: num + +- minmax_jahr_minus1_min: Minimalwert Vorjahr (aktuelles Jahr -1 Jahr) | Berechnung: yearly | Item-Type: num + +- minmax_jahr_minus1_max: Maximalwert Vorjahr (aktuelles Jahr -1 Jahr) | Berechnung: yearly | Item-Type: num + +- minmax_jahr_minus1_avg: Durchschnittswert Vorjahr (aktuelles Jahr -1 Jahr) | Berechnung: yearly | Item-Type: num + +- tagesmitteltemperatur_heute: Tagesmitteltemperatur heute | Berechnung: onchange | Item-Type: num + +- tagesmitteltemperatur_heute_minus1: Tagesmitteltemperatur des letzten Tages (heute -1 Tag) | Berechnung: daily | Item-Type: num + +- tagesmitteltemperatur_heute_minus2: Tagesmitteltemperatur des vorletzten Tages (heute -2 Tag) | Berechnung: daily | Item-Type: num + +- tagesmitteltemperatur_heute_minus3: Tagesmitteltemperatur des vorvorletzten Tages (heute -3 Tag) | Berechnung: daily | Item-Type: num + +- tagesmitteltemperatur_tag: Tagesmitteltemperatur heute | Berechnung: onchange | Item-Type: num + +- tagesmitteltemperatur_tag_minus1: Tagesmitteltemperatur des letzten Tages (heute -1 Tag) | Berechnung: daily | Item-Type: num + +- tagesmitteltemperatur_tag_minus2: Tagesmitteltemperatur des vorletzten Tages (heute -2 Tag) | Berechnung: daily | Item-Type: num + +- tagesmitteltemperatur_tag_minus3: Tagesmitteltemperatur des vorvorletzten Tages (heute -3 Tag) | Berechnung: daily | Item-Type: num + +- serie_minmax_monat_min_15m: monatlicher Minimalwert der letzten 15 Monate (gleitend) | Berechnung: monthly | Item-Type: list + +- serie_minmax_monat_max_15m: monatlicher Maximalwert der letzten 15 Monate (gleitend) | Berechnung: monthly | Item-Type: list + +- serie_minmax_monat_avg_15m: monatlicher Mittelwert der letzten 15 Monate (gleitend) | Berechnung: monthly | Item-Type: list + +- serie_minmax_woche_min_30w: wöchentlicher Minimalwert der letzten 30 Wochen (gleitend) | Berechnung: weekly | Item-Type: list + +- serie_minmax_woche_max_30w: wöchentlicher Maximalwert der letzten 30 Wochen (gleitend) | Berechnung: weekly | Item-Type: list + +- serie_minmax_woche_avg_30w: wöchentlicher Mittelwert der letzten 30 Wochen (gleitend) | Berechnung: weekly | Item-Type: list + +- serie_minmax_tag_min_30d: täglicher Minimalwert der letzten 30 Tage (gleitend) | Berechnung: daily | Item-Type: list + +- serie_minmax_tag_max_30d: täglicher Maximalwert der letzten 30 Tage (gleitend) | Berechnung: daily | Item-Type: list + +- serie_minmax_tag_avg_30d: täglicher Mittelwert der letzten 30 Tage (gleitend) | Berechnung: daily | Item-Type: list + +- serie_verbrauch_tag_30d: Verbrauch pro Tag der letzten 30 Tage | Berechnung: daily | Item-Type: list + +- serie_verbrauch_woche_30w: Verbrauch pro Woche der letzten 30 Wochen | Berechnung: weekly | Item-Type: list + +- serie_verbrauch_monat_18m: Verbrauch pro Monat der letzten 18 Monate | Berechnung: monthly | Item-Type: list + +- serie_zaehlerstand_tag_30d: Zählerstand am Tagesende der letzten 30 Tage | Berechnung: daily | Item-Type: list + +- serie_zaehlerstand_woche_30w: Zählerstand am Wochenende der letzten 30 Wochen | Berechnung: weekly | Item-Type: list + +- serie_zaehlerstand_monat_18m: Zählerstand am Monatsende der letzten 18 Monate | Berechnung: monthly | Item-Type: list + +- serie_waermesumme_monat_24m: monatliche Wärmesumme der letzten 24 Monate | Berechnung: monthly | Item-Type: list + +- serie_kaeltesumme_monat_24m: monatliche Kältesumme der letzten 24 Monate | Berechnung: monthly | Item-Type: list + +- serie_tagesmittelwert_0d: Tagesmittelwert für den aktuellen Tag | Berechnung: daily | Item-Type: list + +- serie_tagesmittelwert_stunde_0d: Stundenmittelwert für den aktuellen Tag | Berechnung: daily | Item-Type: list + +- serie_tagesmittelwert_stunde_30_0d: Stundenmittelwert für den aktuellen Tag | Berechnung: daily | Item-Type: list + +- serie_tagesmittelwert_tag_stunde_30d: Stundenmittelwert pro Tag der letzten 30 Tage (bspw. zur Berechnung der Tagesmitteltemperatur basierend auf den Mittelwert der Temperatur pro Stunde | Berechnung: daily | Item-Type: list + +- general_oldest_value: Ausgabe des ältesten Wertes des entsprechenden "Parent-Items" mit database Attribut | Berechnung: no | Item-Type: num + +- general_oldest_log: Ausgabe des Timestamp des ältesten Eintrages des entsprechenden "Parent-Items" mit database Attribut | Berechnung: no | Item-Type: list + +- kaeltesumme: Berechnet die Kältesumme für einen Zeitraum, db_addon_params: (year=optional, month=optional) | Berechnung: daily | Item-Type: num + +- waermesumme: Berechnet die Wärmesumme für einen Zeitraum, db_addon_params: (year=optional, month=optional) | Berechnung: daily | Item-Type: num + +- gruenlandtempsumme: Berechnet die Grünlandtemperatursumme für einen Zeitraum, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num + +- wachstumsgradtage: Berechnet die Wachstumsgradtage auf Basis der stündlichen Durchschnittswerte eines Tages für das laufende Jahr mit an Angabe des Temperaturschwellenwertes (threshold=Schwellentemperatur) | Berechnung: daily | Item-Type: num + +- wuestentage: Berechnet die Anzahl der Wüstentage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num + +- heisse_tage: Berechnet die Anzahl der heissen Tage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num + +- tropennaechte: Berechnet die Anzahl der Tropennächte des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num + +- sommertage: Berechnet die Anzahl der Sommertage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num + +- heiztage: Berechnet die Anzahl der Heiztage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num + +- vegetationstage: Berechnet die Anzahl der Vegatationstage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num + +- frosttage: Berechnet die Anzahl der Frosttage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num + +- eistage: Berechnet die Anzahl der Eistage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num + +- tagesmitteltemperatur: Berechnet die Tagesmitteltemperatur auf Basis der stündlichen Durchschnittswerte eines Tages für die angegebene Anzahl von Tagen (timeframe=day, count=integer) | Berechnung: daily | Item-Type: list + +- db_request: Abfrage der DB: db_addon_params: (func=mandatory, item=mandatory, timespan=mandatory, start=optional, end=optional, count=optional, group=optional, group2=optional) | Berechnung: group | Item-Type: list + +- minmax: Berechnet einen min/max/avg Wert für einen bestimmen Zeitraum: db_addon_params: (func=mandatory, timeframe=mandatory, start=mandatory) | Berechnung: timeframe | Item-Type: num + +- minmax_last: 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) | Berechnung: timeframe | Item-Type: num + +- verbrauch: Berechnet einen Verbrauchswert für einen bestimmen Zeitraum: db_addon_params: (timeframe=mandatory, start=mandatory end=mandatory) | Berechnung: timeframe | Item-Type: num + +- zaehlerstand: Berechnet einen Zählerstand für einen bestimmen Zeitpunkt: db_addon_params: (timeframe=mandatory, start=mandatory) | Berechnung: timeframe | Item-Type: num + + +db_addon_info +------------- + +- db_version: Version der verbundenen Datenbank | Berechnung: no | Item-Type: str + + +db_addon_admin +-------------- + +- suspend: Unterbricht die Aktivitäten des Plugin | Berechnung: no | Item-Type: bool + +- recalc_all: Startet einen Neuberechnungslauf aller on-demand Items | Berechnung: no | Item-Type: bool + +- clean_cache_values: Löscht Plugin-Cache und damit alle im Plugin zwischengespeicherten Werte | Berechnung: no | Item-Type: bool + + +Hinweise +======== + + - Das Plugin startet die Berechnungen der Werte nach einer gewissen (konfigurierbaren) Zeit (Attribut `startup_run_delay`) + nach dem Start von shNG, um den Startvorgang nicht zu beeinflussen. + + - Bei Start werden automatisch nur die Items berechnet, für das das Attribute `db_addon_startup` gesetzt wurde. Alle anderen + Items werden erst zur konfigurierten Zeit berechnet. Das Attribute `db_addon_startup` kann auch direkt am `Database-Item` + gesetzt werden. Dabei wird das Attribut auf alle darunter liegenden `db_addon-Items` (bspw. bei Verwendung von structs) vererbt. + Über das WebIF kann die Berechnung aller definierten Items ausgelöst werden. + + - Für sogenannte `on_change` Items, also Items, deren Berechnung bis zum Jetzt (bspw. verbrauch-heute) gehen, wird die Berechnung + immer bei eintreffen eines neuen Wertes gestartet. Zu Reduktion der Belastung auf die Datenbank werden die Werte für das Ende der + letzten Periode gecached. + + - Berechnungen werden nur ausgeführt, wenn für den kompletten abgefragten Zeitraum Werte in der Datenbank vorliegen. Wird bspw. + der Verbrauch des letzten Monats abgefragt wobei erst Werte ab dem 3. des Monats in der Datenbank sind, wird die Berechnung abgebrochen. + + - Mit dem Attribut `use_oldest_entry` kann dieses Verhalten verändert werden. Ist das Attribut gesetzt, wird, wenn für den + Beginn der Abfragezeitraums keinen Werte vorliegen, der älteste Eintrag der Datenbank genutzt. + + - Für die Auswertung kann es nützlich sein, bestimmte Werte aus der Datenbank bei der Berechnung auszublenden. Hierfür stehen + 2 Möglichkeiten zur Verfügung: + - Plugin-Attribut `ignore_0`: (list of strings) Bei Items, bei denen ein String aus der Liste im Pfadnamen vorkommt, + werden 0-Werte (val_num = 0) bei Datenbankauswertungen ignoriert. Hat also das Attribut den Wert ['temp'] werden bei allen Items mit + 'temp' im Pfadnamen die 0-Werte bei der Auswertung ignoriert. + - Item-Attribut `db_addon_ignore_value`: (num) Dieser Wert wird bei der Abfrage bzw. Auswertung der Datenbank für diese + Item ignoriert. + + - Das Plugin enthält sehr ausführliche Logginginformation. Bei unerwartetem Verhalten, den LogLevel entsprechend anpassen, + um mehr information zu erhalten. + + - Berechnungen des Plugins können im WebIF unterbrochen werden. Auch das gesamte Plugin kann pausiert werden. Dies kann bei + starker Systembelastung nützlich sein. + + +Beispiele +========= + +Verbrauch +--------- + +Soll bspw. der Verbrauch von Wasser ausgewertet werden, so ist dies wie folgt möglich: + + +.. code-block:: yaml + + wasserzaehler: + zaehlerstand: + type: num + knx_dpt: 12 + knx_cache: 5/3/4 + eval: round(value/1000, 1) + database: init + struct: + - db_addon.verbrauch_1 + - db_addon.verbrauch_2 + - db_addon.zaehlerstand_1 + +Die Werte des Wasserzählerstandes werden in die Datenbank geschrieben und darauf basierend ausgewertet. Die structs +'db_addon.verbrauch_1' und 'db_addon.verbrauch_2' stellen entsprechende Items für die Verbrauchsauswerten zur Verfügung. + +minmax +------ + +Soll bspw. die minimalen und maximalen Temperaturen ausgewertet werden, kann dies so umgesetzt werden: + +.. code-block:: yaml + + temperature: + aussen: + nord: + name: Außentemp Nordseite + type: num + visu_acl: ro + knx_dpt: 9 + knx_cache: 6/5/1 + database: init + struct: + - db_addon.minmax_1 + - db_addon.minmax_2 + +Die Temperaturwerte werden in die Datenbank geschrieben und darauf basierend ausgewertet. Die structs +'db_addon.minmax_1' und 'db_addon.minmax_2' stellen entsprechende Items für die min/max Auswertung zur Verfügung. + +| + +Web Interface +============= + +Das WebIF stellt neben der Ansicht verbundener Items und deren Parameter und Werte auch Funktionen für die +Administration des Plugins bereit. + +Es stehen Button für: + +- Neuberechnung aller Items +- Abbruch eines aktiven Berechnungslaufes +- Pausieren des Plugins +- Wiederaufnahme des Plugins + +bereit. + +Achtung: Das Auslösen einer kompletten Neuberechnung aller Items kann zu einer starken Belastung der Datenbank +aufgrund vieler Leseanfragen führen. + + +db_addon Items +-------------- + +Dieser Reiter des Webinterface zeigt die Items an, für die ein DatabaseAddon Attribut konfiguriert ist. + + +db_addon Maintenance +-------------------- + +Das Webinterface zeigt detaillierte Informationen über die im Plugin verfügbaren Daten an. +Dies dient der Maintenance bzw. Fehlersuche. Dieser Tab ist nur bei Log-Level "Debug" verfügbar. + + +Erläuterungen zu Temperatursummen +================================= + + +Grünlandtemperatursumme +----------------------- + +Beim Grünland wird die Wärmesumme nach Ernst und Loeper benutzt, um den Vegetationsbeginn und somit den Termin von Düngungsmaßnahmen zu bestimmen. +Dabei erfolgt die Aufsummierung der Tagesmitteltemperaturen über 0 °C, wobei der Januar mit 0.5 und der Februar mit 0.75 gewichtet wird. +Bei einer Wärmesumme von 200 Grad ist eine Düngung angesagt. + +siehe: https://de.wikipedia.org/wiki/Gr%C3%BCnlandtemperatursumme + +Folgende Parameter sind möglich / notwendig: + + +.. code-block:: yaml + + db_addon_params: "year=current" + +- year: Jahreszahl (str oder int), für das die Berechnung ausgeführt werden soll oder "current" für aktuelles Jahr (default: 'current') + + +Wachstumsgradtag +---------------- +Der Begriff Wachstumsgradtage (WGT) ist ein Überbegriff für verschiedene Größen. +Gemeinsam ist ihnen, daß zur Berechnung eine Lufttemperatur von einem Schwellenwert subtrahiert wird. +Je nach Fragestellung und Pflanzenart werden der Schwellenwert unterschiedlich gewählt und die Temperatur unterschiedlich bestimmt. +Verfügbar sind die Berechnung über 0) "einfachen Durchschnitt der Tagestemperaturen", 1) "modifizierten Durchschnitt der Tagestemperaturen" +und 2) Anzahl der Tage, deren Mitteltempertatur oberhalb der Schwellentemperatur lag. + +siehe https://de.wikipedia.org/wiki/Wachstumsgradtag + +Folgende Parameter sind möglich / notwendig: + +.. code-block:: yaml + + db_addon_params: "year=current, method=1, threshold=10" + +- year: Jahreszahl (str oder int), für das die Berechnung ausgeführt werden soll oder "current" für aktuelles Jahr (default: 'current') +- method: 0-Berechnung über "einfachen Durchschnitt der Tagestemperaturen", 1-Berechnung über "modifizierten Durchschnitt (default: 0) +der Tagestemperaturen" 2-Anzahl der Tage, mit Mitteltempertatur oberhalb Schwellentemperatur// 10, 11 Ausgabe aus Zeitserie +- threshold: Schwellentemperatur in °C (int) (default: 10) + + +Wärmesumme +---------- + +Die Wärmesumme soll eine Aussage über den Sommer und die Pflanzenreife liefern. Es gibt keine eindeutige Definition der Größe "Wärmesumme". +Berechnet wird die Wärmesumme als Summe aller Tagesmitteltemperaturen über einem Schwellenwert ab dem 1.1. des Jahres. + +siehe https://de.wikipedia.org/wiki/W%C3%A4rmesumme + +Folgende Parameter sind möglich / notwendig: + +.. code-block:: yaml + + db_addon_params: "year=current, month=1, threshold=10" + +- year: Jahreszahl (str oder int), für das die Berechnung ausgeführt werden soll oder "current" für aktuelles Jahr (default: 'current') +- month: Monat (int) des Jahres, für das die Berechnung ausgeführt werden soll (optional) (default: None) +- threshold: Schwellentemperatur in °C (int) (default: 10) + + +Kältesumme +---------- + +Die Kältesumme soll eine Aussage über die Härte des Winters liefern. +Berechnet wird die Kältesumme als Summe aller negativen Tagesmitteltemperaturen ab dem 21.9. des Jahres bis 31.3. des Folgejahres. + +siehe https://de.wikipedia.org/wiki/K%C3%A4ltesumme + +Folgende Parameter sind möglich / notwendig: + +.. code-block:: yaml + + db_addon_params: "year=current, month=1" + +- year: Jahreszahl (str oder int), für das die Berechnung ausgeführt werden soll oder "current" für aktuelles Jahr (default: 'current') +- month: Monat (int) des Jahres, für das die Berechnung ausgeführt werden soll (optional) (default: None) + + +Tagesmitteltemperatur +--------------------- + +Die Tagesmitteltemperatur wird auf Basis der stündlichen Durchschnittswerte eines Tages (aller in der DB enthaltenen Datensätze) +für die angegebene Anzahl von Tagen (days=optional) berechnet. + + + Vorgehen bei Funktionserweiterung des Plugins bzw. Ergänzung weiterer Werte für Item-Attribute ---------------------------------------------------------------------------------------------- diff --git a/db_addon/webif/__init__.py b/db_addon/webif/__init__.py index e4ee8dcee..c7f7c6a71 100644 --- a/db_addon/webif/__init__.py +++ b/db_addon/webif/__init__.py @@ -135,7 +135,7 @@ def submit(self, item=None): result = None item_path, cmd = item.split(':') if item_path is not None and cmd is not None: - self.logger.debug(f"Sending db_addon {cmd=} for {item_path=} via web interface") + self.logger.debug(f"Received db_addon {cmd=} for {item_path=} via web interface") if cmd == "recalc_item": self.logger.info(f"Recalc of item={item_path} called via WebIF. Item put to Queue for new calculation.") @@ -149,14 +149,20 @@ def submit(self, item=None): self.logger.debug(f"Result for web interface: {result}") return json.dumps(result).encode('utf-8') - elif cmd.startswith("set_item_calculation"): + elif cmd.startswith("suspend_plugin_calculation"): + self.logger.debug(f"set_plugin_calculation {cmd=}") cmd, value = cmd.split(',') - self.logger.info(f"Item calculation of item={item_path} will be set to '{value}' via WebIF.") - if value == "True": - value = True - else: - value = False - result = self.plugin._activate_item_calculation(item=item_path, active=value) + 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) + self.logger.debug(f"Result for web interface: {result}") + return json.dumps(result).encode('utf-8') + + elif cmd.startswith("suspend_item_calculation"): + cmd, value = cmd.split(',') + self.logger.info(f"Item calculation of item={item_path} will be set to suspended: {value} via WebIF.") + value = True if value == "True" else False + result = self.plugin._suspend_item_calculation(item=item_path, suspended=value) self.logger.debug(f"Result for web interface: {result}") return json.dumps(result).encode('utf-8') diff --git a/db_addon/webif/templates/index.html b/db_addon/webif/templates/index.html index 5bcd657ce..270751ff7 100644 --- a/db_addon/webif/templates/index.html +++ b/db_addon/webif/templates/index.html @@ -59,33 +59,49 @@ .shng_effect_standard { background-color: none; } + button.actionbutton { + width: 32px; + } {% endblock pluginstyles %} {% block pluginscripts %} @@ -134,26 +149,17 @@ shngInsertText('queue_length', item_count); shngInsertText('active_queue_item', objResponse['active_queue_item']); - if (objResponse['plugin_suspended'] === false) { - document.getElementById('play').classList = 'btn btn-success btn-sm'; - document.getElementById('play').disabled = true; - document.getElementById('pause').classList = 'btn btn-outline-danger btn-sm'; - document.getElementById('pause').disabled = false; - } - else { - document.getElementById('play').classList = 'btn btn-outline-success btn-sm'; - document.getElementById('play').disabled = false; - document.getElementById('pause').classList = 'btn btn-danger btn-sm'; - document.getElementById('pause').disabled = true; - } + togglePlayPause("plugin_button_playpause", objResponse['plugin_suspended'].toString()); } - document.getElementById('debug_parse').checked = objResponse['debug_log']['parse']; - document.getElementById('debug_execute').checked = objResponse['debug_log']['execute']; - document.getElementById('debug_ondemand').checked = objResponse['debug_log']['ondemand']; - document.getElementById('debug_onchange').checked = objResponse['debug_log']['onchange']; - document.getElementById('debug_prepare').checked = objResponse['debug_log']['prepare']; - document.getElementById('debug_sql').checked = objResponse['debug_log']['sql']; + if ($("#logging").length > 0){ + document.getElementById('debug_parse').checked = objResponse['debug_log']['parse']; + document.getElementById('debug_execute').checked = objResponse['debug_log']['execute']; + document.getElementById('debug_ondemand').checked = objResponse['debug_log']['ondemand']; + document.getElementById('debug_onchange').checked = objResponse['debug_log']['onchange']; + document.getElementById('debug_prepare').checked = objResponse['debug_log']['prepare']; + document.getElementById('debug_sql').checked = objResponse['debug_log']['sql']; + } } @@ -166,27 +172,26 @@ // keine HTML-Aktion ausführen (z.B. Formular senden) e.preventDefault(); let value = $("#button").val(); + const id = $("#button_id").val(); + const escapedId = $.escapeSelector(id); + const buttonElement = $("#" + escapedId); console.log('Sending db_addon command for ' + value); // die Kennung des gedrückten Buttons per AJAX senden $.post('submit', {item: value}, function(data) { - let id = $("#button_id").val(); - console.log("Return value from plugin: " + data + " id " + id); - - toggleButton(id, data) - - const escapedVal = $.escapeSelector(value); - const buttonElement = $("#" + escapedVal + "_button"); - if (data) - updateButton(buttonElement, "checkmark"); - else - updateButton(buttonElement, "issue"); + console.log("Return value from plugin: id=" + id + ", data=" + data); + if (id.endsWith("_playpause")) + togglePlayPause(id, data.toString()); + else { + if (data === "true") + updateButton(buttonElement, "btn-success"); + else + updateButton(buttonElement, "btn-danger"); + } }).fail(function(jqXHR, textStatus, errorThrown) { // Error callback console.error("AJAX request failed:", textStatus, errorThrown); - const escapedVal = $.escapeSelector($("#button").val()); - const buttonElement = $("#" + escapedVal + "_button"); - updateButton(buttonElement, "issue"); + updateButton(buttonElement, "btn-danger"); }); return false ; }); @@ -259,34 +264,9 @@ console.warn("Datatable JS not loaded, showing standard table without reorder option " + e); } - // Handler für Suspend (Play/Pause) Button - if ({{ suspended }} == false) { - document.getElementById('play').classList = 'btn btn-success btn-sm'; - document.getElementById('play').disabled = true; - document.getElementById('pause').classList = 'btn btn-outline-danger btn-sm'; - document.getElementById('pause').disabled = false; - } - else { - document.getElementById('play').classList = 'btn btn-outline-success btn-sm'; - document.getElementById('play').disabled = false; - document.getElementById('pause').classList = 'btn btn-danger btn-sm'; - document.getElementById('pause').disabled = true; - } }); - - @@ -358,26 +334,24 @@ {{ p.log_level }} {% if p.log_level == 10 %} -
- {{ (' || ') }} -
- -
-
- -
-
- -
-
- -
-
- -
-
- -
+ {{' || ' }} +
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+
{% endif %} @@ -393,11 +367,13 @@ -
- - -
+ +
+
+ + +
{% endblock %} @@ -427,15 +403,14 @@ {{ p.get_item_config(item._path)['db_addon_fct'] }} {{ _(p.get_item_config(item)['cycle']|string) }} {% if p.get_item_config(item)['startup'] %}{{ _('Ja') }}{% else %}{{ _('Nein') }}{% endif %} - {{ item._value | float | round(2) }} - {{ item.property.last_update.strftime('%d.%m.%Y %H:%M:%S') }} - {{ item.property.last_change.strftime('%d.%m.%Y %H:%M:%S') }} +   +   +   - - - - - + + + + {% endfor %} From 0bf6ceae648d52f1437d54c336f194a5ca456c0b Mon Sep 17 00:00:00 2001 From: sisamiwe Date: Sat, 23 Sep 2023 14:40:11 +0200 Subject: [PATCH 13/18] =?UTF-8?q?DB=5FADDON:=20-=20bugfix=20bei=20Verbrauc?= =?UTF-8?q?hsberechnung=20der=20on-change=20Items=20-=20Bugfix=20bis=20Z?= =?UTF-8?q?=C3=A4hlerstand?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- db_addon/__init__.py | 45 +++++++++++--------------------------------- 1 file changed, 11 insertions(+), 34 deletions(-) diff --git a/db_addon/__init__.py b/db_addon/__init__.py index 737c4fb26..f32549361 100644 --- a/db_addon/__init__.py +++ b/db_addon/__init__.py @@ -247,8 +247,7 @@ def get_query_parameters_from_db_addon_fct() -> Union[dict, None]: # 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 - end = to_int(split_sting_letters_numbers(db_addon_fct_vars[2])[1]) - start = end + 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] @@ -256,24 +255,21 @@ def get_query_parameters_from_db_addon_fct() -> Union[dict, None]: # handle functions 'zaehlerstand' in format 'zaehlerstand_timeframe_timedelta' like 'zaehlerstand_heute_minus1' func = 'last' timeframe = translate_timeframe(db_addon_fct_vars[1]) - end = to_int(split_sting_letters_numbers(db_addon_fct_vars[2])[1]) - start = end + 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 on-change' items in format 'verbrauch_timeframe' like 'verbrauch_heute', 'verbrauch_woche', 'verbrauch_monat', 'verbrauch_jahr' timeframe = translate_timeframe(db_addon_fct_vars[1]) - end = 0 - start = 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]) - end = to_int(split_sting_letters_numbers(db_addon_fct_vars[2])[1]) - start = end + start = end = to_int(split_sting_letters_numbers(db_addon_fct_vars[2])[1]) log_text = 'verbrauch_timeframe_timedelta' required_params = [timeframe, start, end] @@ -318,8 +314,7 @@ def get_query_parameters_from_db_addon_fct() -> Union[dict, None]: # handle 'tagesmitteltemperatur_timeframe_timedelta' like 'tagesmitteltemperatur_heute_minus1' func = 'max' timeframe = translate_timeframe(db_addon_fct_vars[1]) - end = to_int(split_sting_letters_numbers(db_addon_fct_vars[2])[1]) - start = end + 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] @@ -1564,16 +1559,13 @@ def _handle_verbrauch(self, query_params: dict) -> Union[None, float]: 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"next recent value is {value_start=}") + self.logger.debug(f"{value_start=}") if not value_start: value_start = 0 if self.debug_log.prepare: self.logger.debug(f"No start value available. Will be set to 0 as default") - if self.debug_log.prepare: - self.logger.debug(f"{value_start=}") - # calculate consumption consumption = value_end - value_start @@ -1629,39 +1621,24 @@ def _handle_verbrauch_serie_new(self, query_params: dict) -> list: def _handle_zaehlerstand(self, query_params: dict) -> Union[float, int, None]: """ - Ermittlung des Zählerstandes zum Ende eines Zeitraumes + Ermittlung des Zählerstandes zu Beginn des Zeitraumes Die Vorgehensweise ist: - - Abfrage des letzten Eintrages im Zeitraum - - Ergibt diese Abfrage einen Wert, entspricht dieser dem Zählerstand - - Ergibt diese Abfrage keinen Wert, dann - - Abfrage des nächsten Wertes vor dem Zeitraum - - Ergibt diese Abfrage einen Wert, entspricht dieser dem Zählerstand - - Ergibt diese Abfrage keinen Wert, dann Rückgabe von None + - Abfrage des letzten Eintrages vor dem Beginn des Zeitraums """ if self.debug_log.prepare: self.logger.debug(f"called with {query_params=}") # get last value of timeframe - query_params.update({'func': 'last'}) + 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=}") if last_value is None: - if self.debug_log.prepare: - self.logger.debug(f"Error occurred during query. Return.") - return - - if not last_value: - # get last value (next) before timeframe - if self.debug_log.prepare: - self.logger.debug(f"No DB entry for item={query_params['database_item'].path()} found for requested start date. Looking for next recent DB entry.") - query_params.update({'func': 'next'}) - last_value = self._query_item(**query_params)[0][1] - if self.debug_log.prepare: - self.logger.debug(f"next recent value is {last_value=}") + self.logger.info('No entry in database found. Maybe item was just created. Setting last_value to 0.') + last_value = 0 if isinstance(last_value, float): if last_value.is_integer(): From 9d550da7c80f4d03966744db5a66dfd4d989f2ff Mon Sep 17 00:00:00 2001 From: sisamiwe Date: Sat, 28 Oct 2023 20:30:25 +0200 Subject: [PATCH 14/18] DB_ADDON: - bump to 1.2.7 - add attribute 'verbrauch_jahr_minus3' - reset on_change items if new timeframe starts (e.g. reset all on_change items for day at midnight) - use item_attributes_master.py during parse_item --- db_addon/__init__.py | 172 +- db_addon/item_attributes.py | 25 +- db_addon/item_attributes_master.py | 340 +-- db_addon/plugin.yaml | 137 +- db_addon/user_doc.rst | 3384 ++++++++++++++++++++++++++++ 5 files changed, 3770 insertions(+), 288 deletions(-) diff --git a/db_addon/__init__.py b/db_addon/__init__.py index f32549361..fe7b389d7 100644 --- a/db_addon/__init__.py +++ b/db_addon/__init__.py @@ -47,6 +47,7 @@ from lib.plugin import Plugins from .webif import WebInterface from .item_attributes import * +from .item_attributes_master import ITEM_ATTRIBUTES import lib.db HOUR = 'hour' @@ -61,7 +62,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.6' + PLUGIN_VERSION = '1.2.7' def __init__(self, sh): """ @@ -226,7 +227,7 @@ def get_query_parameters_from_db_addon_fct() -> Union[dict, None]: required_params = None if db_addon_fct in HISTORIE_ATTRIBUTES_ONCHANGE: - # handle functions 'minmax on-change' in format 'minmax_timeframe_func' items like 'minmax_heute_max', 'minmax_heute_min', 'minmax_woche_max', 'minmax_woche_min' + # 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 @@ -260,7 +261,7 @@ def get_query_parameters_from_db_addon_fct() -> Union[dict, None]: required_params = [timeframe, start, end] elif db_addon_fct in VERBRAUCH_ATTRIBUTES_ONCHANGE: - # handle functions 'verbrauch on-change' items in format 'verbrauch_timeframe' like 'verbrauch_heute', 'verbrauch_woche', 'verbrauch_monat', 'verbrauch_jahr' + # 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' @@ -303,7 +304,7 @@ def get_query_parameters_from_db_addon_fct() -> Union[dict, None]: required_params = [timeframe, timedelta] elif db_addon_fct in TAGESMITTEL_ATTRIBUTES_ONCHANGE: - # handle functions 'tagesmitteltemperatur on-change' items in format 'tagesmitteltemperatur_timeframe' like 'tagesmitteltemperatur_heute', 'tagesmitteltemperatur_woche', 'tagesmitteltemperatur_monat', 'tagesmitteltemperatur_jahr' + # 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 @@ -547,7 +548,7 @@ 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 ALL_ONCHANGE_ATTRIBUTES: + if self.get_iattr_value(check_item.conf, 'db_addon_fct').lower() in ONCHANGE_ATTRIBUTES: return True return False @@ -623,8 +624,12 @@ def format_db_addon_ignore_value_list(optimize: bool = self.optimize_value_filte # get db_addon_fct attribute value 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) + self.logger.debug(f"{db_addon_fct}: {item_attribute_dict=}") + # get query parameters from db_addon_fct or db_addon_params - if db_addon_fct in ALL_PARAMS_ATTRIBUTES: + if item_attribute_dict['params']: query_params = get_query_parameters_from_db_addon_params() else: query_params = get_query_parameters_from_db_addon_fct() @@ -678,39 +683,59 @@ def format_db_addon_ignore_value_list(optimize: bool = self.optimize_value_filte if self.debug_log.parse: self.logger.debug(f"Item={item.path()} added with db_addon_fct={db_addon_fct} and database_item={database_item}") + # add type (onchange or ondemand) to item dict + item_config_data_dict.update({'on': item_attribute_dict['on']}) + # ToDo: Remove + # if db_addon_fct in ONCHANGE_ATTRIBUTES: + # item_config_data_dict.update({'on': 'change'}) + # elif db_addon_fct in ONDEMAND_ATTRIBUTES: + # item_config_data_dict.update({'on': 'demand'}) + # add cycle for item groups - if db_addon_fct in ALL_HOURLY_ATTRIBUTES: - item_config_data_dict.update({'cycle': 'hourly'}) - elif db_addon_fct in ALL_DAILY_ATTRIBUTES: - item_config_data_dict.update({'cycle': 'daily'}) - elif db_addon_fct in ALL_WEEKLY_ATTRIBUTES: - item_config_data_dict.update({'cycle': 'weekly'}) - elif db_addon_fct in ALL_MONTHLY_ATTRIBUTES: - item_config_data_dict.update({'cycle': 'monthly'}) - elif db_addon_fct in ALL_YEARLY_ATTRIBUTES: - item_config_data_dict.update({'cycle': 'yearly'}) - elif db_addon_fct in ALL_GEN_ATTRIBUTES: - item_config_data_dict.update({'cycle': 'static'}) - elif db_addon_fct in ALL_ONCHANGE_ATTRIBUTES: - item_config_data_dict.update({'cycle': 'on-change'}) - elif db_addon_fct == 'db_request': + cycle = item_attribute_dict['calc'] + if cycle == 'group': cycle = item_config_data_dict['query_params'].get('group') if not cycle: cycle = item_config_data_dict['query_params'].get('timeframe') - item_config_data_dict.update({'cycle': f"{timeframe_to_updatecyle(cycle)}"}) - elif db_addon_fct == 'minmax': - cycle = item_config_data_dict['query_params']['timeframe'] - item_config_data_dict.update({'cycle': f"{timeframe_to_updatecyle(cycle)}"}) - else: - self.logger.warning(f"Cycle for {item.path()} undefined") - item_config_data_dict.update({'cycle': None}) + cycle = f"{timeframe_to_updatecyle(cycle)}" + elif cycle == 'timeframe': + cycle = item_config_data_dict['query_params'].get('timeframe') + cycle = f"{timeframe_to_updatecyle(cycle)}" + elif cycle == 'None': + cycle = None + item_config_data_dict.update({'cycle': cycle}) + + # ToDo: Remove + # if db_addon_fct in ALL_HOURLY_ATTRIBUTES: + # item_config_data_dict.update({'cycle': 'hourly'}) + # elif db_addon_fct in ALL_DAILY_ATTRIBUTES: + # item_config_data_dict.update({'cycle': 'daily'}) + # elif db_addon_fct in ALL_WEEKLY_ATTRIBUTES: + # item_config_data_dict.update({'cycle': 'weekly'}) + # elif db_addon_fct in ALL_MONTHLY_ATTRIBUTES: + # item_config_data_dict.update({'cycle': 'monthly'}) + # elif db_addon_fct in ALL_YEARLY_ATTRIBUTES: + # item_config_data_dict.update({'cycle': 'yearly'}) + # elif db_addon_fct in ALL_GEN_ATTRIBUTES: + # item_config_data_dict.update({'cycle': 'static'}) + # elif db_addon_fct == 'db_request': + # cycle = item_config_data_dict['query_params'].get('group') + # if not cycle: + # cycle = item_config_data_dict['query_params'].get('timeframe') + # item_config_data_dict.update({'cycle': f"{timeframe_to_updatecyle(cycle)}"}) + # elif db_addon_fct == 'minmax': + # cycle = item_config_data_dict['query_params']['timeframe'] + # item_config_data_dict.update({'cycle': f"{timeframe_to_updatecyle(cycle)}"}) + # else: + # self.logger.warning(f"Cycle for {item.path()} undefined") + # item_config_data_dict.update({'cycle': None}) # do logging if self.debug_log.parse: self.logger.debug(f"Item '{item.path()}' added to be run {item_config_data_dict['cycle']}.") # create item config for item to be run on startup - if db_addon_startup or db_addon_fct in ALL_GEN_ATTRIBUTES: + if db_addon_startup or item_attribute_dict['cat'] == 'gen': item_config_data_dict.update({'startup': True}) else: item_config_data_dict.update({'startup': False}) @@ -734,7 +759,7 @@ def format_db_addon_ignore_value_list(optimize: bool = self.optimize_value_filte # Reference to 'update_item' für alle Items mit Attribut 'database', um die on_change Items zu berechnen elif self.has_iattr(item.conf, self.item_attribute_search_str) and has_db_addon_item(): if self.debug_log.parse: - self.logger.debug(f"reference to update_item for item={item.path()} will be set due to on-change") + self.logger.debug(f"reference to update_item for item={item.path()} will be set due to onchange") self.add_item(item, config_data_dict={'db_addon': 'database'}) return self.update_item @@ -754,7 +779,7 @@ def update_item(self, item, caller=None, source=None, dest=None): # handle database items if item in self._database_items(): # if not self.startup_finished: - # self.logger.info(f"Handling of 'on-change' is paused for startup. No updated will be processed.") + # self.logger.info(f"Handling of 'onchange' is paused for startup. No updated will be processed.") if self.suspended: self.logger.info(f"Plugin is suspended. No updated will be processed.") else: @@ -888,7 +913,7 @@ def execute_due_items(self) -> None: self.execute_items() def execute_startup_items(self) -> None: - """Execute all startup_items and set scheduler for delaying on-change items""" + """Execute all startup_items and set scheduler for delaying onchange items""" # execute item calculation self.execute_items(option='startup') @@ -904,36 +929,57 @@ def _create_due_items() -> list: # set für zu berechnende Items erstellen _todo_items = set() + _reset_items = set() # stündlich zu berechnende Items hinzufügen - _todo_items.update(set(self._hourly_items())) + _todo_items.update(set(self._ondemand_hourly_items())) + # cache dict leeren self.current_values[HOUR] = {} self.previous_values[HOUR] = {} # wenn aktuelle Stunde == 0, werden auch die täglichen Items berechnet if self.shtime.now().hour == 0: - _todo_items.update(set(self._daily_items())) + # item zur Aufgabeliste hinzufügen + _todo_items.update(set(self._ondemand_daily_items())) + # cache dict leeren self.current_values[DAY] = {} self.previous_values[DAY] = {} self.value_list_raw_data = {} + # reset Item-Wert alle onchange + _reset_items.update(set(self._onchange_daily_items())) # wenn zusätzlich der Wochentag == Montag, werden auch die wöchentlichen Items berechnet if self.shtime.weekday(self.shtime.today()) == 1: - _todo_items.update(set(self._weekly_items())) + # item zur Aufgabeliste hinzufügen + _todo_items.update(set(self._ondemand_weekly_items())) + # cache dict leeren self.current_values[WEEK] = {} self.previous_values[WEEK] = {} + # reset Item-Wert alle onchange + _reset_items.update(set(self._onchange_weekly_items())) # wenn zusätzlich der erste Tage eines Monates ist, werden auch die monatlichen Items berechnet if self.shtime.now().day == 1: - _todo_items.update(set(self._monthly_items())) + # item zur Aufgabeliste hinzufügen + _todo_items.update(set(self._ondemand_monthly_items())) + # cache dict leeren self.current_values[MONTH] = {} self.previous_values[MONTH] = {} + # reset Item-Wert alle onchange + _reset_items.update(set(self._onchange_monthly_items())) # wenn zusätzlich der erste Monat ist, werden auch die jährlichen Items berechnet if self.shtime.now().month == 1: - _todo_items.update(set(self._yearly_items())) + # item zur Aufgabeliste hinzufügen + _todo_items.update(set(self._ondemand_yearly_items())) + # cache dict leeren self.current_values[YEAR] = {} self.previous_values[YEAR] = {} + # reset Item-Wert alle onchange + _reset_items.update(set(self._onchange_yearly_items())) + + # reset der onchange items + [_item(0, self.get_shortname()) for _item in _reset_items] return list(_todo_items) @@ -993,7 +1039,7 @@ def work_item_queue(self) -> None: else: if isinstance(queue_entry, tuple): item, value = queue_entry - self.logger.info(f"# {self.item_queue.qsize() + 1} item(s) to do. || 'on-change' item={item.path()} with {value=} will be processed.") + self.logger.info(f"# {self.item_queue.qsize() + 1} item(s) to do. || 'onchange' item={item.path()} with {value=} will be processed.") self.active_queue_item = str(item.path()) self.handle_onchange(item, value) else: @@ -1207,7 +1253,7 @@ def handle_tagesmittel(): if self.debug_log.onchange: self.logger.debug(f"called with updated_item={updated_item.path()} and value={value}.") - relevant_item_list = set(self.get_item_list('database_item', updated_item)) & set(self.get_item_list('cycle', 'on-change')) + relevant_item_list = set(self.get_item_list('database_item', updated_item)) & set(self.get_item_list('cycle', 'onchange')) if self.debug_log.onchange: self.logger.debug(f"Following items where identified for update: {relevant_item_list}.") @@ -1224,20 +1270,20 @@ def handle_tagesmittel(): new_value = None # handle all non on_change functions - if db_addon_fct not in ALL_ONCHANGE_ATTRIBUTES: + if db_addon_fct not in ONCHANGE_ATTRIBUTES: if self.debug_log.onchange: - self.logger.debug(f"non on-change function detected. Skip update.") + self.logger.debug(f"non onchange function detected. Skip update.") continue - # handle minmax on-change items tagesmitteltemperatur_heute, minmax_heute_avg + # handle minmax onchange items tagesmitteltemperatur_heute, minmax_heute_avg if db_addon_fct in TAGESMITTEL_ATTRIBUTES_ONCHANGE: new_value = handle_tagesmittel() - # handle minmax on-change items like minmax_heute_max, minmax_heute_min, minmax_woche_max, minmax_woche_min..... + # handle minmax onchange items like minmax_heute_max, minmax_heute_min, minmax_woche_max, minmax_woche_min..... elif db_addon_fct.startswith('minmax'): new_value = handle_minmax() - # handle verbrauch on-change items ending with heute, woche, monat, jahr + # handle verbrauch onchange items ending with heute, woche, monat, jahr elif db_addon_fct.startswith('verbrauch'): new_value = handle_verbrauch() @@ -1291,7 +1337,40 @@ def _startup_items(self) -> list: return self.get_item_list('startup', True) def _onchange_items(self) -> list: - return self.get_item_list('cycle', 'on-change') + return self.get_item_list('on', 'change') + + def _onchange_hourly_items(self) -> list: + return list(set(self._onchange_items()) & set(self._hourly_items())) + + def _onchange_daily_items(self) -> list: + return list(set(self._onchange_items()) & set(self._daily_items())) + + def _onchange_weekly_items(self) -> list: + return list(set(self._onchange_items()) & set(self._weekly_items())) + + def _onchange_monthly_items(self) -> list: + return list(set(self._onchange_items()) & set(self._monthly_items())) + + def _onchange_yearly_items(self) -> list: + return list(set(self._onchange_items()) & set(self._yearly_items())) + + def _ondemand_items(self) -> list: + return self.get_item_list('on', 'demand') + + def _ondemand_hourly_items(self) -> list: + return list(set(self._ondemand_items()) & set(self._hourly_items())) + + def _ondemand_daily_items(self) -> list: + return list(set(self._ondemand_items()) & set(self._daily_items())) + + def _ondemand_weekly_items(self) -> list: + return list(set(self._ondemand_items()) & set(self._weekly_items())) + + def _ondemand_monthly_items(self) -> list: + return list(set(self._ondemand_items()) & set(self._monthly_items())) + + def _ondemand_yearly_items(self) -> list: + return list(set(self._ondemand_items()) & set(self._yearly_items())) def _hourly_items(self) -> list: return self.get_item_list('cycle', 'hourly') @@ -1323,9 +1402,6 @@ def _database_items(self) -> list: def _database_item_path_items(self) -> list: return self.get_item_list('database_item_path', True) - def _ondemand_items(self) -> list: - return self._daily_items() + self._weekly_items() + self._monthly_items() + self._yearly_items() + self._static_items() - def _suspended_items(self) -> list: return self.get_item_list('suspended', True) diff --git a/db_addon/item_attributes.py b/db_addon/item_attributes.py index 23ee09161..696ffda30 100644 --- a/db_addon/item_attributes.py +++ b/db_addon/item_attributes.py @@ -28,16 +28,27 @@ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # -ALL_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_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_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'] -ALL_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'] -ALL_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'] -ALL_YEARLY_ATTRIBUTES = ['verbrauch_jahr_minus1', 'verbrauch_jahr_minus2', '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_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_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'] +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_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'] diff --git a/db_addon/item_attributes_master.py b/db_addon/item_attributes_master.py index 2244f4ce6..012e0ca2f 100644 --- a/db_addon/item_attributes_master.py +++ b/db_addon/item_attributes_master.py @@ -31,171 +31,172 @@ ITEM_ATTRIBUTES = { 'db_addon_fct': { - 'verbrauch_heute': {'cat': 'verbrauch', 'sub_cat': 'onchange', 'item_type': 'num', 'calc': 'onchange', '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', 'calc': 'onchange', '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', 'calc': 'onchange', 'params': False, 'description': 'Verbrauch in der aktuellen Woche'}, - 'verbrauch_monat': {'cat': 'verbrauch', 'sub_cat': 'onchange', 'item_type': 'num', 'calc': 'onchange', 'params': False, 'description': 'Verbrauch im aktuellen Monat'}, - 'verbrauch_jahr': {'cat': 'verbrauch', 'sub_cat': 'onchange', 'item_type': 'num', 'calc': 'onchange', 'params': False, 'description': 'Verbrauch im aktuellen Jahr'}, - 'verbrauch_last_24h': {'cat': 'verbrauch', 'sub_cat': 'last', 'item_type': 'num', 'calc': 'hourly', 'params': False, 'description': 'Verbrauch innerhalb letzten 24h'}, - 'verbrauch_last_7d': {'cat': 'verbrauch', 'sub_cat': 'last', 'item_type': 'num', 'calc': 'hourly', 'params': False, 'description': 'Verbrauch innerhalb letzten 7 Tage'}, - 'verbrauch_heute_minus1': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': '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', 'calc': 'daily', 'params': False, 'description': 'Verbrauch vorgestern (heute -2 Tage)'}, - 'verbrauch_heute_minus3': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Verbrauch heute -3 Tage'}, - 'verbrauch_heute_minus4': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Verbrauch heute -4 Tage'}, - 'verbrauch_heute_minus5': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Verbrauch heute -5 Tage'}, - 'verbrauch_heute_minus6': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Verbrauch heute -6 Tage'}, - 'verbrauch_heute_minus7': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Verbrauch heute -7 Tage'}, - 'verbrauch_heute_minus8': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Verbrauch heute -8 Tage'}, - 'verbrauch_tag_minus1': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': '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', 'calc': 'daily', 'params': False, 'description': 'Verbrauch vorgestern (heute -2 Tage)'}, - 'verbrauch_tag_minus3': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Verbrauch heute -3 Tage'}, - 'verbrauch_tag_minus4': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Verbrauch heute -4 Tage'}, - 'verbrauch_tag_minus5': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Verbrauch heute -5 Tage'}, - 'verbrauch_tag_minus6': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Verbrauch heute -6 Tage'}, - 'verbrauch_tag_minus7': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Verbrauch heute -7 Tage'}, - 'verbrauch_tag_minus8': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Verbrauch heute -8 Tage'}, - 'verbrauch_woche_minus1': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'weekly', 'params': False, 'description': 'Verbrauch Vorwoche (aktuelle Woche -1)'}, - 'verbrauch_woche_minus2': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'weekly', 'params': False, 'description': 'Verbrauch aktuelle Woche -2 Wochen'}, - 'verbrauch_woche_minus3': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'weekly', 'params': False, 'description': 'Verbrauch aktuelle Woche -3 Wochen'}, - 'verbrauch_woche_minus4': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'weekly', 'params': False, 'description': 'Verbrauch aktuelle Woche -4 Wochen'}, - 'verbrauch_monat_minus1': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'monthly', 'params': False, 'description': 'Verbrauch Vormonat (aktueller Monat -1)'}, - 'verbrauch_monat_minus2': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'monthly', 'params': False, 'description': 'Verbrauch aktueller Monat -2 Monate'}, - 'verbrauch_monat_minus3': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'monthly', 'params': False, 'description': 'Verbrauch aktueller Monat -3 Monate'}, - 'verbrauch_monat_minus4': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'monthly', 'params': False, 'description': 'Verbrauch aktueller Monat -4 Monate'}, - 'verbrauch_monat_minus12': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'monthly', 'params': False, 'description': 'Verbrauch aktueller Monat -12 Monate'}, - 'verbrauch_jahr_minus1': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'yearly', 'params': False, 'description': 'Verbrauch Vorjahr (aktuelles Jahr -1 Jahr)'}, - 'verbrauch_jahr_minus2': {'cat': 'verbrauch', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'yearly', 'params': False, 'description': 'Verbrauch aktuelles Jahr -2 Jahre'}, - 'verbrauch_rolling_12m_heute_minus1': {'cat': 'verbrauch', 'sub_cat': 'rolling', 'item_type': 'num', 'calc': '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', 'calc': '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', 'calc': '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', 'calc': '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', 'calc': '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', 'calc': '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', 'calc': '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', 'calc': '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', 'calc': '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', 'calc': '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', 'calc': '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', 'calc': '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', 'calc': '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', 'calc': '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', 'calc': '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', 'calc': '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', 'calc': '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', 'calc': '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', 'calc': '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', 'calc': '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', 'calc': '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', 'calc': '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', 'calc': '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', 'calc': 'daily', 'params': False, 'description': 'minimaler Wert der letzten 24h'}, - 'minmax_last_24h_max': {'cat': 'wertehistorie', 'sub_cat': 'last', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'maximaler Wert der letzten 24h'}, - 'minmax_last_24h_avg': {'cat': 'wertehistorie', 'sub_cat': 'last', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'durchschnittlicher Wert der letzten 24h'}, - 'minmax_last_7d_min': {'cat': 'wertehistorie', 'sub_cat': 'last', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'minimaler Wert der letzten 7 Tage'}, - 'minmax_last_7d_max': {'cat': 'wertehistorie', 'sub_cat': 'last', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'maximaler Wert der letzten 7 Tage'}, - 'minmax_last_7d_avg': {'cat': 'wertehistorie', 'sub_cat': 'last', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'durchschnittlicher Wert der letzten 7 Tage'}, - 'minmax_heute_min': {'cat': 'wertehistorie', 'sub_cat': 'onchange', 'item_type': 'num', 'calc': 'onchange', 'params': False, 'description': 'Minimalwert seit Tagesbeginn'}, - 'minmax_heute_max': {'cat': 'wertehistorie', 'sub_cat': 'onchange', 'item_type': 'num', 'calc': 'onchange', 'params': False, 'description': 'Maximalwert seit Tagesbeginn'}, - 'minmax_heute_avg': {'cat': 'wertehistorie', 'sub_cat': 'onchange', 'item_type': 'num', 'calc': 'onchange', 'params': False, 'description': 'Durschnittswert seit Tagesbeginn'}, - 'minmax_heute_minus1_min': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Minimalwert gestern (heute -1 Tag)'}, - 'minmax_heute_minus1_max': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Maximalwert gestern (heute -1 Tag)'}, - 'minmax_heute_minus1_avg': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Durchschnittswert gestern (heute -1 Tag)'}, - 'minmax_heute_minus2_min': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Minimalwert vorgestern (heute -2 Tage)'}, - 'minmax_heute_minus2_max': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Maximalwert vorgestern (heute -2 Tage)'}, - 'minmax_heute_minus2_avg': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Durchschnittswert vorgestern (heute -2 Tage)'}, - 'minmax_heute_minus3_min': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Minimalwert heute vor 3 Tagen'}, - 'minmax_heute_minus3_max': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Maximalwert heute vor 3 Tagen'}, - 'minmax_heute_minus3_avg': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Durchschnittswert heute vor 3 Tagen'}, - 'minmax_tag_min': {'cat': 'wertehistorie', 'sub_cat': 'onchange', 'item_type': 'num', 'calc': 'onchange', 'params': False, 'description': 'Minimalwert seit Tagesbeginn'}, - 'minmax_tag_max': {'cat': 'wertehistorie', 'sub_cat': 'onchange', 'item_type': 'num', 'calc': 'onchange', 'params': False, 'description': 'Maximalwert seit Tagesbeginn'}, - 'minmax_tag_avg': {'cat': 'wertehistorie', 'sub_cat': 'onchange', 'item_type': 'num', 'calc': 'onchange', 'params': False, 'description': 'Durschnittswert seit Tagesbeginn'}, - 'minmax_tag_minus1_min': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Minimalwert gestern (heute -1 Tag)'}, - 'minmax_tag_minus1_max': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Maximalwert gestern (heute -1 Tag)'}, - 'minmax_tag_minus1_avg': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Durchschnittswert gestern (heute -1 Tag)'}, - 'minmax_tag_minus2_min': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Minimalwert vorgestern (heute -2 Tage)'}, - 'minmax_tag_minus2_max': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Maximalwert vorgestern (heute -2 Tage)'}, - 'minmax_tag_minus2_avg': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Durchschnittswert vorgestern (heute -2 Tage)'}, - 'minmax_tag_minus3_min': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Minimalwert heute vor 3 Tagen'}, - 'minmax_tag_minus3_max': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Maximalwert heute vor 3 Tagen'}, - 'minmax_tag_minus3_avg': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Durchschnittswert heute vor 3 Tagen'}, - 'minmax_woche_min': {'cat': 'wertehistorie', 'sub_cat': 'onchange', 'item_type': 'num', 'calc': 'onchange', 'params': False, 'description': 'Minimalwert seit Wochenbeginn'}, - 'minmax_woche_max': {'cat': 'wertehistorie', 'sub_cat': 'onchange', 'item_type': 'num', 'calc': 'onchange', 'params': False, 'description': 'Maximalwert seit Wochenbeginn'}, - 'minmax_woche_minus1_min': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'weekly', 'params': False, 'description': 'Minimalwert Vorwoche (aktuelle Woche -1)'}, - 'minmax_woche_minus1_max': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'weekly', 'params': False, 'description': 'Maximalwert Vorwoche (aktuelle Woche -1)'}, - 'minmax_woche_minus1_avg': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'weekly', 'params': False, 'description': 'Durchschnittswert Vorwoche (aktuelle Woche -1)'}, - 'minmax_woche_minus2_min': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'weekly', 'params': False, 'description': 'Minimalwert aktuelle Woche -2 Wochen'}, - 'minmax_woche_minus2_max': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'weekly', 'params': False, 'description': 'Maximalwert aktuelle Woche -2 Wochen'}, - 'minmax_woche_minus2_avg': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'weekly', 'params': False, 'description': 'Durchschnittswert aktuelle Woche -2 Wochen'}, - 'minmax_monat_min': {'cat': 'wertehistorie', 'sub_cat': 'onchange', 'item_type': 'num', 'calc': 'onchange', 'params': False, 'description': 'Minimalwert seit Monatsbeginn'}, - 'minmax_monat_max': {'cat': 'wertehistorie', 'sub_cat': 'onchange', 'item_type': 'num', 'calc': 'onchange', 'params': False, 'description': 'Maximalwert seit Monatsbeginn'}, - 'minmax_monat_minus1_min': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'monthly', 'params': False, 'description': 'Minimalwert Vormonat (aktueller Monat -1)'}, - 'minmax_monat_minus1_max': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'monthly', 'params': False, 'description': 'Maximalwert Vormonat (aktueller Monat -1)'}, - 'minmax_monat_minus1_avg': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'monthly', 'params': False, 'description': 'Durchschnittswert Vormonat (aktueller Monat -1)'}, - 'minmax_monat_minus2_min': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'monthly', 'params': False, 'description': 'Minimalwert aktueller Monat -2 Monate'}, - 'minmax_monat_minus2_max': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'monthly', 'params': False, 'description': 'Maximalwert aktueller Monat -2 Monate'}, - 'minmax_monat_minus2_avg': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'monthly', 'params': False, 'description': 'Durchschnittswert aktueller Monat -2 Monate'}, - 'minmax_jahr_min': {'cat': 'wertehistorie', 'sub_cat': 'onchange', 'item_type': 'num', 'calc': 'onchange', 'params': False, 'description': 'Minimalwert seit Jahresbeginn'}, - 'minmax_jahr_max': {'cat': 'wertehistorie', 'sub_cat': 'onchange', 'item_type': 'num', 'calc': 'onchange', 'params': False, 'description': 'Maximalwert seit Jahresbeginn'}, - 'minmax_jahr_minus1_min': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'yearly', 'params': False, 'description': 'Minimalwert Vorjahr (aktuelles Jahr -1 Jahr)'}, - 'minmax_jahr_minus1_max': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'yearly', 'params': False, 'description': 'Maximalwert Vorjahr (aktuelles Jahr -1 Jahr)'}, - 'minmax_jahr_minus1_avg': {'cat': 'wertehistorie', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'yearly', 'params': False, 'description': 'Durchschnittswert Vorjahr (aktuelles Jahr -1 Jahr)'}, - 'tagesmitteltemperatur_heute': {'cat': 'tagesmittel', 'sub_cat': 'onchange', 'item_type': 'num', 'calc': 'onchange', 'params': False, 'description': 'Tagesmitteltemperatur heute'}, - 'tagesmitteltemperatur_heute_minus1': {'cat': 'tagesmittel', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Tagesmitteltemperatur des letzten Tages (heute -1 Tag)'}, - 'tagesmitteltemperatur_heute_minus2': {'cat': 'tagesmittel', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Tagesmitteltemperatur des vorletzten Tages (heute -2 Tag)'}, - 'tagesmitteltemperatur_heute_minus3': {'cat': 'tagesmittel', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Tagesmitteltemperatur des vorvorletzten Tages (heute -3 Tag)'}, - 'tagesmitteltemperatur_tag': {'cat': 'tagesmittel', 'sub_cat': 'onchange', 'item_type': 'num', 'calc': 'onchange', 'params': False, 'description': 'Tagesmitteltemperatur heute'}, - 'tagesmitteltemperatur_tag_minus1': {'cat': 'tagesmittel', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Tagesmitteltemperatur des letzten Tages (heute -1 Tag)'}, - 'tagesmitteltemperatur_tag_minus2': {'cat': 'tagesmittel', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Tagesmitteltemperatur des vorletzten Tages (heute -2 Tag)'}, - 'tagesmitteltemperatur_tag_minus3': {'cat': 'tagesmittel', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Tagesmitteltemperatur des vorvorletzten Tages (heute -3 Tag)'}, - 'serie_minmax_monat_min_15m': {'cat': 'serie', 'sub_cat': 'minmax', 'item_type': 'list', 'calc': 'monthly', 'params': False, 'description': 'monatlicher Minimalwert der letzten 15 Monate (gleitend)'}, - 'serie_minmax_monat_max_15m': {'cat': 'serie', 'sub_cat': 'minmax', 'item_type': 'list', 'calc': 'monthly', 'params': False, 'description': 'monatlicher Maximalwert der letzten 15 Monate (gleitend)'}, - 'serie_minmax_monat_avg_15m': {'cat': 'serie', 'sub_cat': 'minmax', 'item_type': 'list', 'calc': 'monthly', 'params': False, 'description': 'monatlicher Mittelwert der letzten 15 Monate (gleitend)'}, - 'serie_minmax_woche_min_30w': {'cat': 'serie', 'sub_cat': 'minmax', 'item_type': 'list', 'calc': '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', 'calc': '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', 'calc': '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', 'calc': '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', 'calc': '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', 'calc': 'daily', 'params': False, 'description': 'täglicher Mittelwert der letzten 30 Tage (gleitend)'}, - 'serie_verbrauch_tag_30d': {'cat': 'serie', 'sub_cat': 'verbrauch', 'item_type': 'list', 'calc': 'daily', 'params': False, 'description': 'Verbrauch pro Tag der letzten 30 Tage'}, - 'serie_verbrauch_woche_30w': {'cat': 'serie', 'sub_cat': 'verbrauch', 'item_type': 'list', 'calc': 'weekly', 'params': False, 'description': 'Verbrauch pro Woche der letzten 30 Wochen'}, - 'serie_verbrauch_monat_18m': {'cat': 'serie', 'sub_cat': 'verbrauch', 'item_type': 'list', 'calc': 'monthly', 'params': False, 'description': 'Verbrauch pro Monat der letzten 18 Monate'}, - 'serie_zaehlerstand_tag_30d': {'cat': 'serie', 'sub_cat': 'zaehler', 'item_type': 'list', 'calc': 'daily', 'params': False, 'description': 'Zählerstand am Tagesende der letzten 30 Tage'}, - 'serie_zaehlerstand_woche_30w': {'cat': 'serie', 'sub_cat': 'zaehler', 'item_type': 'list', 'calc': 'weekly', 'params': False, 'description': 'Zählerstand am Wochenende der letzten 30 Wochen'}, - 'serie_zaehlerstand_monat_18m': {'cat': 'serie', 'sub_cat': 'zaehler', 'item_type': 'list', 'calc': 'monthly', 'params': False, 'description': 'Zählerstand am Monatsende der letzten 18 Monate'}, - 'serie_waermesumme_monat_24m': {'cat': 'serie', 'sub_cat': 'summe', 'item_type': 'list', 'calc': 'monthly', 'params': False, 'description': 'monatliche Wärmesumme der letzten 24 Monate'}, - 'serie_kaeltesumme_monat_24m': {'cat': 'serie', 'sub_cat': 'summe', 'item_type': 'list', 'calc': 'monthly', 'params': False, 'description': 'monatliche Kältesumme der letzten 24 Monate'}, - 'serie_tagesmittelwert_0d': {'cat': 'serie', 'sub_cat': 'mittel_d', 'item_type': 'list', 'calc': 'daily', 'params': False, 'description': 'Tagesmittelwert für den aktuellen Tag'}, - 'serie_tagesmittelwert_stunde_0d': {'cat': 'serie', 'sub_cat': 'mittel_h', 'item_type': 'list', 'calc': 'daily', 'params': False, 'description': 'Stundenmittelwert für den aktuellen Tag'}, - 'serie_tagesmittelwert_stunde_30_0d': {'cat': 'serie', 'sub_cat': 'mittel_h1', 'item_type': 'list', 'calc': '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', 'calc': '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', 'calc': 'no', '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', 'calc': 'no', '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', 'calc': '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', 'calc': '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', 'calc': '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', 'calc': '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', 'calc': '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', 'calc': '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', 'calc': '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', 'calc': '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', 'calc': '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', 'calc': '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', 'calc': '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', 'calc': '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', 'calc': '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', 'calc': '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', 'calc': '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', 'calc': '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', 'calc': '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', 'calc': 'timeframe', 'params': True, 'description': 'Berechnet einen Zählerstand für einen bestimmen Zeitpunkt: db_addon_params: (timeframe=mandatory, start=mandatory)'}, + 'verbrauch_heute': {'cat': 'verbrauch', 'on': 'change', 'sub_cat': 'onchange', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Verbrauch am heutigen Tag (Differenz zwischen aktuellem Wert und den Wert am Ende des vorherigen Tages)'}, + 'verbrauch_tag': {'cat': 'verbrauch', 'on': 'change', 'sub_cat': 'onchange', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Verbrauch am heutigen Tag (Differenz zwischen aktuellem Wert und den Wert am Ende des vorherigen Tages)'}, + 'verbrauch_woche': {'cat': 'verbrauch', 'on': 'change', 'sub_cat': 'onchange', 'item_type': 'num', 'calc': 'weekly', 'params': False, 'description': 'Verbrauch in der aktuellen Woche'}, + 'verbrauch_monat': {'cat': 'verbrauch', 'on': 'change', 'sub_cat': 'onchange', 'item_type': 'num', 'calc': 'monthly', 'params': False, 'description': 'Verbrauch im aktuellen Monat'}, + 'verbrauch_jahr': {'cat': 'verbrauch', 'on': 'change', 'sub_cat': 'onchange', 'item_type': 'num', 'calc': 'yearly', 'params': False, 'description': 'Verbrauch im aktuellen Jahr'}, + 'verbrauch_last_24h': {'cat': 'verbrauch', 'on': 'demand', 'sub_cat': 'last', 'item_type': 'num', 'calc': 'hourly', 'params': False, 'description': 'Verbrauch innerhalb letzten 24h'}, + 'verbrauch_last_7d': {'cat': 'verbrauch', 'on': 'demand', 'sub_cat': 'last', 'item_type': 'num', 'calc': 'hourly', 'params': False, 'description': 'Verbrauch innerhalb letzten 7 Tage'}, + 'verbrauch_heute_minus1': {'cat': 'verbrauch', 'on': 'demand', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': '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', 'on': 'demand', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Verbrauch vorgestern (heute -2 Tage)'}, + 'verbrauch_heute_minus3': {'cat': 'verbrauch', 'on': 'demand', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Verbrauch heute -3 Tage'}, + 'verbrauch_heute_minus4': {'cat': 'verbrauch', 'on': 'demand', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Verbrauch heute -4 Tage'}, + 'verbrauch_heute_minus5': {'cat': 'verbrauch', 'on': 'demand', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Verbrauch heute -5 Tage'}, + 'verbrauch_heute_minus6': {'cat': 'verbrauch', 'on': 'demand', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Verbrauch heute -6 Tage'}, + 'verbrauch_heute_minus7': {'cat': 'verbrauch', 'on': 'demand', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Verbrauch heute -7 Tage'}, + 'verbrauch_heute_minus8': {'cat': 'verbrauch', 'on': 'demand', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Verbrauch heute -8 Tage'}, + 'verbrauch_tag_minus1': {'cat': 'verbrauch', 'on': 'demand', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': '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', 'on': 'demand', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Verbrauch vorgestern (heute -2 Tage)'}, + 'verbrauch_tag_minus3': {'cat': 'verbrauch', 'on': 'demand', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Verbrauch heute -3 Tage'}, + 'verbrauch_tag_minus4': {'cat': 'verbrauch', 'on': 'demand', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Verbrauch heute -4 Tage'}, + 'verbrauch_tag_minus5': {'cat': 'verbrauch', 'on': 'demand', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Verbrauch heute -5 Tage'}, + 'verbrauch_tag_minus6': {'cat': 'verbrauch', 'on': 'demand', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Verbrauch heute -6 Tage'}, + 'verbrauch_tag_minus7': {'cat': 'verbrauch', 'on': 'demand', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Verbrauch heute -7 Tage'}, + 'verbrauch_tag_minus8': {'cat': 'verbrauch', 'on': 'demand', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Verbrauch heute -8 Tage'}, + 'verbrauch_woche_minus1': {'cat': 'verbrauch', 'on': 'demand', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'weekly', 'params': False, 'description': 'Verbrauch Vorwoche (aktuelle Woche -1)'}, + 'verbrauch_woche_minus2': {'cat': 'verbrauch', 'on': 'demand', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'weekly', 'params': False, 'description': 'Verbrauch aktuelle Woche -2 Wochen'}, + 'verbrauch_woche_minus3': {'cat': 'verbrauch', 'on': 'demand', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'weekly', 'params': False, 'description': 'Verbrauch aktuelle Woche -3 Wochen'}, + 'verbrauch_woche_minus4': {'cat': 'verbrauch', 'on': 'demand', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'weekly', 'params': False, 'description': 'Verbrauch aktuelle Woche -4 Wochen'}, + 'verbrauch_monat_minus1': {'cat': 'verbrauch', 'on': 'demand', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'monthly', 'params': False, 'description': 'Verbrauch Vormonat (aktueller Monat -1)'}, + 'verbrauch_monat_minus2': {'cat': 'verbrauch', 'on': 'demand', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'monthly', 'params': False, 'description': 'Verbrauch aktueller Monat -2 Monate'}, + 'verbrauch_monat_minus3': {'cat': 'verbrauch', 'on': 'demand', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'monthly', 'params': False, 'description': 'Verbrauch aktueller Monat -3 Monate'}, + 'verbrauch_monat_minus4': {'cat': 'verbrauch', 'on': 'demand', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'monthly', 'params': False, 'description': 'Verbrauch aktueller Monat -4 Monate'}, + 'verbrauch_monat_minus12': {'cat': 'verbrauch', 'on': 'demand', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'monthly', 'params': False, 'description': 'Verbrauch aktueller Monat -12 Monate'}, + 'verbrauch_jahr_minus1': {'cat': 'verbrauch', 'on': 'demand', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'yearly', 'params': False, 'description': 'Verbrauch Vorjahr (aktuelles Jahr -1 Jahr)'}, + 'verbrauch_jahr_minus2': {'cat': 'verbrauch', 'on': 'demand', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'yearly', 'params': False, 'description': 'Verbrauch aktuelles Jahr -2 Jahre'}, + 'verbrauch_jahr_minus3': {'cat': 'verbrauch', 'on': 'demand', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'yearly', 'params': False, 'description': 'Verbrauch aktuelles Jahr -3 Jahre'}, + 'verbrauch_rolling_12m_heute_minus1': {'cat': 'verbrauch', 'on': 'demand', 'sub_cat': 'rolling', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Verbrauch der letzten 12 Monate ausgehend im Ende des letzten Tages'}, + 'verbrauch_rolling_12m_tag_minus1': {'cat': 'verbrauch', 'on': 'demand', 'sub_cat': 'rolling', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Verbrauch der letzten 12 Monate ausgehend im Ende des letzten Tages'}, + 'verbrauch_rolling_12m_woche_minus1': {'cat': 'verbrauch', 'on': 'demand', 'sub_cat': 'rolling', 'item_type': 'num', 'calc': 'weekly', 'params': False, 'description': 'Verbrauch der letzten 12 Monate ausgehend im Ende der letzten Woche'}, + 'verbrauch_rolling_12m_monat_minus1': {'cat': 'verbrauch', 'on': 'demand', 'sub_cat': 'rolling', 'item_type': 'num', 'calc': 'monthly', 'params': False, 'description': 'Verbrauch der letzten 12 Monate ausgehend im Ende des letzten Monats'}, + 'verbrauch_rolling_12m_jahr_minus1': {'cat': 'verbrauch', 'on': 'demand', 'sub_cat': 'rolling', 'item_type': 'num', 'calc': 'yearly', 'params': False, 'description': 'Verbrauch der letzten 12 Monate ausgehend im Ende des letzten Jahres'}, + 'verbrauch_jahreszeitraum_minus1': {'cat': 'verbrauch', 'on': 'demand', 'sub_cat': 'jahrzeit', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Verbrauch seit dem 1.1. bis zum heutigen Tag des Vorjahres'}, + 'verbrauch_jahreszeitraum_minus2': {'cat': 'verbrauch', 'on': 'demand', 'sub_cat': 'jahrzeit', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Verbrauch seit dem 1.1. bis zum heutigen Tag vor 2 Jahren'}, + 'verbrauch_jahreszeitraum_minus3': {'cat': 'verbrauch', 'on': 'demand', 'sub_cat': 'jahrzeit', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Verbrauch seit dem 1.1. bis zum heutigen Tag vor 3 Jahren'}, + 'zaehlerstand_heute_minus1': {'cat': 'zaehler', 'on': 'demand', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Zählerstand / Wert am Ende des letzten Tages (heute -1 Tag)'}, + 'zaehlerstand_heute_minus2': {'cat': 'zaehler', 'on': 'demand', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Zählerstand / Wert am Ende des vorletzten Tages (heute -2 Tag)'}, + 'zaehlerstand_heute_minus3': {'cat': 'zaehler', 'on': 'demand', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Zählerstand / Wert am Ende des vorvorletzten Tages (heute -3 Tag)'}, + 'zaehlerstand_tag_minus1': {'cat': 'zaehler', 'on': 'demand', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Zählerstand / Wert am Ende des letzten Tages (heute -1 Tag)'}, + 'zaehlerstand_tag_minus2': {'cat': 'zaehler', 'on': 'demand', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Zählerstand / Wert am Ende des vorletzten Tages (heute -2 Tag)'}, + 'zaehlerstand_tag_minus3': {'cat': 'zaehler', 'on': 'demand', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Zählerstand / Wert am Ende des vorvorletzten Tages (heute -3 Tag)'}, + 'zaehlerstand_woche_minus1': {'cat': 'zaehler', 'on': 'demand', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'weekly', 'params': False, 'description': 'Zählerstand / Wert am Ende der vorvorletzten Woche (aktuelle Woche -1 Woche)'}, + 'zaehlerstand_woche_minus2': {'cat': 'zaehler', 'on': 'demand', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'weekly', 'params': False, 'description': 'Zählerstand / Wert am Ende der vorletzten Woche (aktuelle Woche -2 Wochen)'}, + 'zaehlerstand_woche_minus3': {'cat': 'zaehler', 'on': 'demand', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'weekly', 'params': False, 'description': 'Zählerstand / Wert am Ende der aktuellen Woche -3 Wochen'}, + 'zaehlerstand_monat_minus1': {'cat': 'zaehler', 'on': 'demand', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'monthly', 'params': False, 'description': 'Zählerstand / Wert am Ende des letzten Monates (aktueller Monat -1 Monat)'}, + 'zaehlerstand_monat_minus2': {'cat': 'zaehler', 'on': 'demand', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'monthly', 'params': False, 'description': 'Zählerstand / Wert am Ende des vorletzten Monates (aktueller Monat -2 Monate)'}, + 'zaehlerstand_monat_minus3': {'cat': 'zaehler', 'on': 'demand', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'monthly', 'params': False, 'description': 'Zählerstand / Wert am Ende des aktuellen Monats -3 Monate'}, + 'zaehlerstand_jahr_minus1': {'cat': 'zaehler', 'on': 'demand', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'yearly', 'params': False, 'description': 'Zählerstand / Wert am Ende des letzten Jahres (aktuelles Jahr -1 Jahr)'}, + 'zaehlerstand_jahr_minus2': {'cat': 'zaehler', 'on': 'demand', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'yearly', 'params': False, 'description': 'Zählerstand / Wert am Ende des vorletzten Jahres (aktuelles Jahr -2 Jahre)'}, + 'zaehlerstand_jahr_minus3': {'cat': 'zaehler', 'on': 'demand', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'yearly', 'params': False, 'description': 'Zählerstand / Wert am Ende des aktuellen Jahres -3 Jahre'}, + 'minmax_last_24h_min': {'cat': 'wertehistorie', 'on': 'demand', 'sub_cat': 'last', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'minimaler Wert der letzten 24h'}, + 'minmax_last_24h_max': {'cat': 'wertehistorie', 'on': 'demand', 'sub_cat': 'last', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'maximaler Wert der letzten 24h'}, + 'minmax_last_24h_avg': {'cat': 'wertehistorie', 'on': 'demand', 'sub_cat': 'last', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'durchschnittlicher Wert der letzten 24h'}, + 'minmax_last_7d_min': {'cat': 'wertehistorie', 'on': 'demand', 'sub_cat': 'last', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'minimaler Wert der letzten 7 Tage'}, + 'minmax_last_7d_max': {'cat': 'wertehistorie', 'on': 'demand', 'sub_cat': 'last', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'maximaler Wert der letzten 7 Tage'}, + 'minmax_last_7d_avg': {'cat': 'wertehistorie', 'on': 'demand', 'sub_cat': 'last', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'durchschnittlicher Wert der letzten 7 Tage'}, + 'minmax_heute_min': {'cat': 'wertehistorie', 'on': 'change', 'sub_cat': 'onchange', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Minimalwert seit Tagesbeginn'}, + 'minmax_heute_max': {'cat': 'wertehistorie', 'on': 'change', 'sub_cat': 'onchange', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Maximalwert seit Tagesbeginn'}, + 'minmax_heute_avg': {'cat': 'wertehistorie', 'on': 'change', 'sub_cat': 'onchange', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Durschnittswert seit Tagesbeginn'}, + 'minmax_heute_minus1_min': {'cat': 'wertehistorie', 'on': 'demand', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Minimalwert gestern (heute -1 Tag)'}, + 'minmax_heute_minus1_max': {'cat': 'wertehistorie', 'on': 'demand', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Maximalwert gestern (heute -1 Tag)'}, + 'minmax_heute_minus1_avg': {'cat': 'wertehistorie', 'on': 'demand', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Durchschnittswert gestern (heute -1 Tag)'}, + 'minmax_heute_minus2_min': {'cat': 'wertehistorie', 'on': 'demand', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Minimalwert vorgestern (heute -2 Tage)'}, + 'minmax_heute_minus2_max': {'cat': 'wertehistorie', 'on': 'demand', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Maximalwert vorgestern (heute -2 Tage)'}, + 'minmax_heute_minus2_avg': {'cat': 'wertehistorie', 'on': 'demand', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Durchschnittswert vorgestern (heute -2 Tage)'}, + 'minmax_heute_minus3_min': {'cat': 'wertehistorie', 'on': 'demand', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Minimalwert heute vor 3 Tagen'}, + 'minmax_heute_minus3_max': {'cat': 'wertehistorie', 'on': 'demand', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Maximalwert heute vor 3 Tagen'}, + 'minmax_heute_minus3_avg': {'cat': 'wertehistorie', 'on': 'demand', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Durchschnittswert heute vor 3 Tagen'}, + 'minmax_tag_min': {'cat': 'wertehistorie', 'on': 'change', 'sub_cat': 'onchange', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Minimalwert seit Tagesbeginn'}, + 'minmax_tag_max': {'cat': 'wertehistorie', 'on': 'change', 'sub_cat': 'onchange', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Maximalwert seit Tagesbeginn'}, + 'minmax_tag_avg': {'cat': 'wertehistorie', 'on': 'change', 'sub_cat': 'onchange', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Durschnittswert seit Tagesbeginn'}, + 'minmax_tag_minus1_min': {'cat': 'wertehistorie', 'on': 'demand', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Minimalwert gestern (heute -1 Tag)'}, + 'minmax_tag_minus1_max': {'cat': 'wertehistorie', 'on': 'demand', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Maximalwert gestern (heute -1 Tag)'}, + 'minmax_tag_minus1_avg': {'cat': 'wertehistorie', 'on': 'demand', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Durchschnittswert gestern (heute -1 Tag)'}, + 'minmax_tag_minus2_min': {'cat': 'wertehistorie', 'on': 'demand', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Minimalwert vorgestern (heute -2 Tage)'}, + 'minmax_tag_minus2_max': {'cat': 'wertehistorie', 'on': 'demand', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Maximalwert vorgestern (heute -2 Tage)'}, + 'minmax_tag_minus2_avg': {'cat': 'wertehistorie', 'on': 'demand', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Durchschnittswert vorgestern (heute -2 Tage)'}, + 'minmax_tag_minus3_min': {'cat': 'wertehistorie', 'on': 'demand', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Minimalwert heute vor 3 Tagen'}, + 'minmax_tag_minus3_max': {'cat': 'wertehistorie', 'on': 'demand', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Maximalwert heute vor 3 Tagen'}, + 'minmax_tag_minus3_avg': {'cat': 'wertehistorie', 'on': 'demand', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Durchschnittswert heute vor 3 Tagen'}, + 'minmax_woche_min': {'cat': 'wertehistorie', 'on': 'change', 'sub_cat': 'onchange', 'item_type': 'num', 'calc': 'weekly', 'params': False, 'description': 'Minimalwert seit Wochenbeginn'}, + 'minmax_woche_max': {'cat': 'wertehistorie', 'on': 'change', 'sub_cat': 'onchange', 'item_type': 'num', 'calc': 'weekly', 'params': False, 'description': 'Maximalwert seit Wochenbeginn'}, + 'minmax_woche_minus1_min': {'cat': 'wertehistorie', 'on': 'demand', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'weekly', 'params': False, 'description': 'Minimalwert Vorwoche (aktuelle Woche -1)'}, + 'minmax_woche_minus1_max': {'cat': 'wertehistorie', 'on': 'demand', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'weekly', 'params': False, 'description': 'Maximalwert Vorwoche (aktuelle Woche -1)'}, + 'minmax_woche_minus1_avg': {'cat': 'wertehistorie', 'on': 'demand', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'weekly', 'params': False, 'description': 'Durchschnittswert Vorwoche (aktuelle Woche -1)'}, + 'minmax_woche_minus2_min': {'cat': 'wertehistorie', 'on': 'demand', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'weekly', 'params': False, 'description': 'Minimalwert aktuelle Woche -2 Wochen'}, + 'minmax_woche_minus2_max': {'cat': 'wertehistorie', 'on': 'demand', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'weekly', 'params': False, 'description': 'Maximalwert aktuelle Woche -2 Wochen'}, + 'minmax_woche_minus2_avg': {'cat': 'wertehistorie', 'on': 'demand', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'weekly', 'params': False, 'description': 'Durchschnittswert aktuelle Woche -2 Wochen'}, + 'minmax_monat_min': {'cat': 'wertehistorie', 'on': 'change', 'sub_cat': 'onchange', 'item_type': 'num', 'calc': 'monthly', 'params': False, 'description': 'Minimalwert seit Monatsbeginn'}, + 'minmax_monat_max': {'cat': 'wertehistorie', 'on': 'change', 'sub_cat': 'onchange', 'item_type': 'num', 'calc': 'monthly', 'params': False, 'description': 'Maximalwert seit Monatsbeginn'}, + 'minmax_monat_minus1_min': {'cat': 'wertehistorie', 'on': 'demand', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'monthly', 'params': False, 'description': 'Minimalwert Vormonat (aktueller Monat -1)'}, + 'minmax_monat_minus1_max': {'cat': 'wertehistorie', 'on': 'demand', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'monthly', 'params': False, 'description': 'Maximalwert Vormonat (aktueller Monat -1)'}, + 'minmax_monat_minus1_avg': {'cat': 'wertehistorie', 'on': 'demand', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'monthly', 'params': False, 'description': 'Durchschnittswert Vormonat (aktueller Monat -1)'}, + 'minmax_monat_minus2_min': {'cat': 'wertehistorie', 'on': 'demand', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'monthly', 'params': False, 'description': 'Minimalwert aktueller Monat -2 Monate'}, + 'minmax_monat_minus2_max': {'cat': 'wertehistorie', 'on': 'demand', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'monthly', 'params': False, 'description': 'Maximalwert aktueller Monat -2 Monate'}, + 'minmax_monat_minus2_avg': {'cat': 'wertehistorie', 'on': 'demand', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'monthly', 'params': False, 'description': 'Durchschnittswert aktueller Monat -2 Monate'}, + 'minmax_jahr_min': {'cat': 'wertehistorie', 'on': 'change', 'sub_cat': 'onchange', 'item_type': 'num', 'calc': 'yearly', 'params': False, 'description': 'Minimalwert seit Jahresbeginn'}, + 'minmax_jahr_max': {'cat': 'wertehistorie', 'on': 'change', 'sub_cat': 'onchange', 'item_type': 'num', 'calc': 'yearly', 'params': False, 'description': 'Maximalwert seit Jahresbeginn'}, + 'minmax_jahr_minus1_min': {'cat': 'wertehistorie', 'on': 'demand', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'yearly', 'params': False, 'description': 'Minimalwert Vorjahr (aktuelles Jahr -1 Jahr)'}, + 'minmax_jahr_minus1_max': {'cat': 'wertehistorie', 'on': 'demand', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'yearly', 'params': False, 'description': 'Maximalwert Vorjahr (aktuelles Jahr -1 Jahr)'}, + 'minmax_jahr_minus1_avg': {'cat': 'wertehistorie', 'on': 'demand', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'yearly', 'params': False, 'description': 'Durchschnittswert Vorjahr (aktuelles Jahr -1 Jahr)'}, + 'tagesmitteltemperatur_heute': {'cat': 'tagesmittel', 'on': 'change', 'sub_cat': 'onchange', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Tagesmitteltemperatur heute'}, + 'tagesmitteltemperatur_heute_minus1': {'cat': 'tagesmittel', 'on': 'demand', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Tagesmitteltemperatur des letzten Tages (heute -1 Tag)'}, + 'tagesmitteltemperatur_heute_minus2': {'cat': 'tagesmittel', 'on': 'demand', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Tagesmitteltemperatur des vorletzten Tages (heute -2 Tag)'}, + 'tagesmitteltemperatur_heute_minus3': {'cat': 'tagesmittel', 'on': 'demand', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Tagesmitteltemperatur des vorvorletzten Tages (heute -3 Tag)'}, + 'tagesmitteltemperatur_tag': {'cat': 'tagesmittel', 'on': 'change', 'sub_cat': 'onchange', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Tagesmitteltemperatur heute'}, + 'tagesmitteltemperatur_tag_minus1': {'cat': 'tagesmittel', 'on': 'demand', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Tagesmitteltemperatur des letzten Tages (heute -1 Tag)'}, + 'tagesmitteltemperatur_tag_minus2': {'cat': 'tagesmittel', 'on': 'demand', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Tagesmitteltemperatur des vorletzten Tages (heute -2 Tag)'}, + 'tagesmitteltemperatur_tag_minus3': {'cat': 'tagesmittel', 'on': 'demand', 'sub_cat': 'timeframe', 'item_type': 'num', 'calc': 'daily', 'params': False, 'description': 'Tagesmitteltemperatur des vorvorletzten Tages (heute -3 Tag)'}, + 'serie_minmax_monat_min_15m': {'cat': 'serie', 'on': 'demand', 'sub_cat': 'minmax', 'item_type': 'list', 'calc': 'monthly', 'params': False, 'description': 'monatlicher Minimalwert der letzten 15 Monate (gleitend)'}, + 'serie_minmax_monat_max_15m': {'cat': 'serie', 'on': 'demand', 'sub_cat': 'minmax', 'item_type': 'list', 'calc': 'monthly', 'params': False, 'description': 'monatlicher Maximalwert der letzten 15 Monate (gleitend)'}, + 'serie_minmax_monat_avg_15m': {'cat': 'serie', 'on': 'demand', 'sub_cat': 'minmax', 'item_type': 'list', 'calc': 'monthly', 'params': False, 'description': 'monatlicher Mittelwert der letzten 15 Monate (gleitend)'}, + 'serie_minmax_woche_min_30w': {'cat': 'serie', 'on': 'demand', 'sub_cat': 'minmax', 'item_type': 'list', 'calc': 'weekly', 'params': False, 'description': 'wöchentlicher Minimalwert der letzten 30 Wochen (gleitend)'}, + 'serie_minmax_woche_max_30w': {'cat': 'serie', 'on': 'demand', 'sub_cat': 'minmax', 'item_type': 'list', 'calc': 'weekly', 'params': False, 'description': 'wöchentlicher Maximalwert der letzten 30 Wochen (gleitend)'}, + 'serie_minmax_woche_avg_30w': {'cat': 'serie', 'on': 'demand', 'sub_cat': 'minmax', 'item_type': 'list', 'calc': 'weekly', 'params': False, 'description': 'wöchentlicher Mittelwert der letzten 30 Wochen (gleitend)'}, + 'serie_minmax_tag_min_30d': {'cat': 'serie', 'on': 'demand', 'sub_cat': 'minmax', 'item_type': 'list', 'calc': 'daily', 'params': False, 'description': 'täglicher Minimalwert der letzten 30 Tage (gleitend)'}, + 'serie_minmax_tag_max_30d': {'cat': 'serie', 'on': 'demand', 'sub_cat': 'minmax', 'item_type': 'list', 'calc': 'daily', 'params': False, 'description': 'täglicher Maximalwert der letzten 30 Tage (gleitend)'}, + 'serie_minmax_tag_avg_30d': {'cat': 'serie', 'on': 'demand', 'sub_cat': 'minmax', 'item_type': 'list', 'calc': 'daily', 'params': False, 'description': 'täglicher Mittelwert der letzten 30 Tage (gleitend)'}, + 'serie_verbrauch_tag_30d': {'cat': 'serie', 'on': 'demand', 'sub_cat': 'verbrauch', 'item_type': 'list', 'calc': 'daily', 'params': False, 'description': 'Verbrauch pro Tag der letzten 30 Tage'}, + 'serie_verbrauch_woche_30w': {'cat': 'serie', 'on': 'demand', 'sub_cat': 'verbrauch', 'item_type': 'list', 'calc': 'weekly', 'params': False, 'description': 'Verbrauch pro Woche der letzten 30 Wochen'}, + 'serie_verbrauch_monat_18m': {'cat': 'serie', 'on': 'demand', 'sub_cat': 'verbrauch', 'item_type': 'list', 'calc': 'monthly', 'params': False, 'description': 'Verbrauch pro Monat der letzten 18 Monate'}, + 'serie_zaehlerstand_tag_30d': {'cat': 'serie', 'on': 'demand', 'sub_cat': 'zaehler', 'item_type': 'list', 'calc': 'daily', 'params': False, 'description': 'Zählerstand am Tagesende der letzten 30 Tage'}, + 'serie_zaehlerstand_woche_30w': {'cat': 'serie', 'on': 'demand', 'sub_cat': 'zaehler', 'item_type': 'list', 'calc': 'weekly', 'params': False, 'description': 'Zählerstand am Wochenende der letzten 30 Wochen'}, + 'serie_zaehlerstand_monat_18m': {'cat': 'serie', 'on': 'demand', 'sub_cat': 'zaehler', 'item_type': 'list', 'calc': 'monthly', 'params': False, 'description': 'Zählerstand am Monatsende der letzten 18 Monate'}, + 'serie_waermesumme_monat_24m': {'cat': 'serie', 'on': 'demand', 'sub_cat': 'summe', 'item_type': 'list', 'calc': 'monthly', 'params': False, 'description': 'monatliche Wärmesumme der letzten 24 Monate'}, + 'serie_kaeltesumme_monat_24m': {'cat': 'serie', 'on': 'demand', 'sub_cat': 'summe', 'item_type': 'list', 'calc': 'monthly', 'params': False, 'description': 'monatliche Kältesumme der letzten 24 Monate'}, + 'serie_tagesmittelwert_0d': {'cat': 'serie', 'on': 'demand', 'sub_cat': 'mittel_d', 'item_type': 'list', 'calc': 'daily', 'params': False, 'description': 'Tagesmittelwert für den aktuellen Tag'}, + 'serie_tagesmittelwert_stunde_0d': {'cat': 'serie', 'on': 'demand', 'sub_cat': 'mittel_h', 'item_type': 'list', 'calc': 'daily', 'params': False, 'description': 'Stundenmittelwert für den aktuellen Tag'}, + 'serie_tagesmittelwert_stunde_30_0d': {'cat': 'serie', 'on': 'demand', 'sub_cat': 'mittel_h1', 'item_type': 'list', 'calc': 'daily', 'params': False, 'description': 'Stundenmittelwert für den aktuellen Tag'}, + 'serie_tagesmittelwert_tag_stunde_30d': {'cat': 'serie', 'on': 'demand', 'sub_cat': 'mittel_d_h', 'item_type': 'list', 'calc': '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', 'on': 'demand', 'sub_cat': None, 'item_type': 'num', 'calc': 'None', 'params': False, 'description': 'Ausgabe des ältesten Wertes des entsprechenden "Parent-Items" mit database Attribut'}, + 'general_oldest_log': {'cat': 'gen', 'on': 'demand', 'sub_cat': None, 'item_type': 'list', 'calc': 'None', 'params': False, 'description': 'Ausgabe des Timestamp des ältesten Eintrages des entsprechenden "Parent-Items" mit database Attribut'}, + 'kaeltesumme': {'cat': 'summe', 'on': 'demand', 'sub_cat': None, 'item_type': 'num', 'calc': 'daily', 'params': True, 'description': 'Berechnet die Kältesumme für einen Zeitraum, db_addon_params: (year=optional, month=optional)'}, + 'waermesumme': {'cat': 'summe', 'on': 'demand', 'sub_cat': None, 'item_type': 'num', 'calc': 'daily', 'params': True, 'description': 'Berechnet die Wärmesumme für einen Zeitraum, db_addon_params: (year=optional, month=optional)'}, + 'gruenlandtempsumme': {'cat': 'summe', 'on': 'demand', 'sub_cat': None, 'item_type': 'num', 'calc': 'daily', 'params': True, 'description': 'Berechnet die Grünlandtemperatursumme für einen Zeitraum, db_addon_params: (year=optional)'}, + 'wachstumsgradtage': {'cat': 'summe', 'on': 'demand', 'sub_cat': None, 'item_type': 'num', 'calc': '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', 'on': 'demand', 'sub_cat': 'kenntage', 'item_type': 'num', 'calc': 'daily', 'params': True, 'description': 'Berechnet die Anzahl der Wüstentage des Jahres, db_addon_params: (year=optional)'}, + 'heisse_tage': {'cat': 'summe', 'on': 'demand', 'sub_cat': 'kenntage', 'item_type': 'num', 'calc': 'daily', 'params': True, 'description': 'Berechnet die Anzahl der heissen Tage des Jahres, db_addon_params: (year=optional)'}, + 'tropennaechte': {'cat': 'summe', 'on': 'demand', 'sub_cat': 'kenntage', 'item_type': 'num', 'calc': 'daily', 'params': True, 'description': 'Berechnet die Anzahl der Tropennächte des Jahres, db_addon_params: (year=optional)'}, + 'sommertage': {'cat': 'summe', 'on': 'demand', 'sub_cat': 'kenntage', 'item_type': 'num', 'calc': 'daily', 'params': True, 'description': 'Berechnet die Anzahl der Sommertage des Jahres, db_addon_params: (year=optional)'}, + 'heiztage': {'cat': 'summe', 'on': 'demand', 'sub_cat': 'kenntage', 'item_type': 'num', 'calc': 'daily', 'params': True, 'description': 'Berechnet die Anzahl der Heiztage des Jahres, db_addon_params: (year=optional)'}, + 'vegetationstage': {'cat': 'summe', 'on': 'demand', 'sub_cat': 'kenntage', 'item_type': 'num', 'calc': 'daily', 'params': True, 'description': 'Berechnet die Anzahl der Vegatationstage des Jahres, db_addon_params: (year=optional)'}, + 'frosttage': {'cat': 'summe', 'on': 'demand', 'sub_cat': 'kenntage', 'item_type': 'num', 'calc': 'daily', 'params': True, 'description': 'Berechnet die Anzahl der Frosttage des Jahres, db_addon_params: (year=optional)'}, + 'eistage': {'cat': 'summe', 'on': 'demand', 'sub_cat': 'kenntage', 'item_type': 'num', 'calc': 'daily', 'params': True, 'description': 'Berechnet die Anzahl der Eistage des Jahres, db_addon_params: (year=optional)'}, + 'tagesmitteltemperatur': {'cat': 'complex', 'on': 'demand', 'sub_cat': None, 'item_type': 'list', 'calc': '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', 'on': 'demand', 'sub_cat': None, 'item_type': 'list', 'calc': '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', 'on': 'demand', 'sub_cat': None, 'item_type': 'num', 'calc': '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', 'on': 'demand', 'sub_cat': None, 'item_type': 'num', 'calc': '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', 'on': 'demand', 'sub_cat': None, 'item_type': 'num', 'calc': 'timeframe', 'params': True, 'description': 'Berechnet einen Verbrauchswert für einen bestimmen Zeitraum: db_addon_params: (timeframe=mandatory, start=mandatory end=mandatory)'}, + 'zaehlerstand': {'cat': 'complex', 'on': 'demand', 'sub_cat': None, 'item_type': 'num', 'calc': 'timeframe', 'params': True, 'description': 'Berechnet 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', 'calc': 'no', 'params': False, 'description': 'Version der verbundenen Datenbank'}, - }, - 'db_addon_admin': { - 'suspend': {'cat': 'admin', 'item_type': 'bool', 'calc': 'no', 'params': False, 'description': 'Unterbricht die Aktivitäten des Plugin'}, - 'recalc_all': {'cat': 'admin', 'item_type': 'bool', 'calc': 'no', 'params': False, 'description': 'Startet einen Neuberechnungslauf aller on-demand Items'}, - 'clean_cache_values': {'cat': 'admin', 'item_type': 'bool', 'calc': 'no', 'params': False, 'description': 'Löscht Plugin-Cache und damit alle im Plugin zwischengespeicherten Werte'}, + 'db_version': {'cat': 'info', 'item_type': 'str', 'calc': 'no', 'params': False, 'description': 'Version der verbundenen Datenbank'}, + }, + 'db_addon_admin': { + 'suspend': {'cat': 'admin', 'item_type': 'bool', 'calc': 'no', 'params': False, 'description': 'Unterbricht die Aktivitäten des Plugin'}, + 'recalc_all': {'cat': 'admin', 'item_type': 'bool', 'calc': 'no', 'params': False, 'description': 'Startet einen Neuberechnungslauf aller on-demand Items'}, + 'clean_cache_values': {'cat': 'admin', 'item_type': 'bool', 'calc': 'no', 'params': False, 'description': 'Löscht Plugin-Cache und damit alle im Plugin zwischengespeicherten Werte'}, }, } @@ -248,7 +249,18 @@ def export_item_attributes_py(): print(f"A) Start generation of {FILENAME_ATTRIBUTES}") ATTRS = dict() - ATTRS['ALL_ONCHANGE_ATTRIBUTES'] = get_attrs(sub_dict={'calc': 'onchange'}) + 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'}) diff --git a/db_addon/plugin.yaml b/db_addon/plugin.yaml index 776c7d7d7..37ac45de6 100644 --- a/db_addon/plugin.yaml +++ b/db_addon/plugin.yaml @@ -11,7 +11,7 @@ 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.6 # Plugin version (must match the version specified in __init__.py) + version: 1.2.7 # 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 @@ -111,6 +111,7 @@ item_attributes: - 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 @@ -270,6 +271,7 @@ item_attributes: - Verbrauch aktueller Monat -12 Monate - Verbrauch Vorjahr (aktuelles Jahr -1 Jahr) - Verbrauch aktuelles Jahr -2 Jahre + - Verbrauch aktuelles Jahr -3 Jahre - Verbrauch der letzten 12 Monate ausgehend im Ende des letzten Tages - Verbrauch der letzten 12 Monate ausgehend im Ende des letzten Tages - Verbrauch der letzten 12 Monate ausgehend im Ende der letzten Woche @@ -511,6 +513,7 @@ item_attributes: - num - num - num + - num - list - list - list @@ -554,11 +557,11 @@ item_attributes: - num valid_list_calculation: # NOTE: valid_list_calculation is automatically created by using item_attributes_master.py - - onchange - - onchange - - onchange - - onchange - - onchange + - daily + - daily + - weekly + - monthly + - yearly - hourly - hourly - daily @@ -588,6 +591,7 @@ item_attributes: - monthly - yearly - yearly + - yearly - daily - daily - weekly @@ -617,9 +621,6 @@ item_attributes: - daily - daily - daily - - onchange - - onchange - - onchange - daily - daily - daily @@ -629,9 +630,6 @@ item_attributes: - daily - daily - daily - - onchange - - onchange - - onchange - daily - daily - daily @@ -641,32 +639,38 @@ item_attributes: - daily - daily - daily - - onchange - - onchange + - daily + - daily + - daily + - daily + - daily + - daily + - weekly - weekly - weekly - weekly - weekly - weekly - weekly - - onchange - - onchange + - weekly + - monthly - monthly - monthly - monthly - monthly - monthly - monthly - - onchange - - onchange + - monthly + - yearly - yearly - yearly - yearly - - onchange + - yearly + - daily + - daily - daily - daily - daily - - onchange - daily - daily - daily @@ -691,8 +695,8 @@ item_attributes: - daily - daily - daily - - no - - no + - None + - None - daily - daily - daily @@ -758,31 +762,26 @@ item_attributes: description: de: Parameter für eine Auswertefunktion des DB-Addon Plugins im Format 'kwargs' enclosed in quotes like 'keyword=argument, keyword=argument' en: Parameters of a DB-Addon Plugin evaluation function. Need to have format of 'kwargs' enclosed in quotes like 'keyword=argument, keyword=argument' - db_addon_params_dict: type: dict description: de: Parameter für eine Auswertefunktion des DB-Addon Plugins im Format eines Dictionary en: Parameters of a DB-Addon Plugin evaluation function. Need to have format of a dictionary - db_addon_startup: type: bool description: de: Ausführen der Berechnung bei Plugin Start (mit zeitlichem Abstand, wie in den Plugin Parametern definiert) en: Run function in startup of plugin (with delay, set in plugin parameters) - db_addon_ignore_value: type: num description: de: Wert der bei Abfrage bzw. Auswertung der Datenbank für diese Item ignoriert werden soll en: Value which will be ignored at database query - db_addon_ignore_value_list: type: list(str) description: de: "Liste von Vergleichsoperatoren, die bei Abfrage bzw. Auswertung der Datenbank für dieses Item berücksichtigt werden sollen. Bsp: ['> 0', '< 35']" en: List of comparison operators which will be used at database query - db_addon_database_item: type: str description: @@ -798,7 +797,7 @@ item_structs: db_addon_startup: yes type: num visu_acl: ro - # cache: yes + cache: yes verbrauch_last_24h: name: Verbrauch innerhalb der letzten 24h @@ -806,7 +805,7 @@ item_structs: db_addon_startup: yes type: num visu_acl: ro - # cache: yes + cache: yes verbrauch_woche: name: Verbrauch seit Wochenbeginn @@ -814,7 +813,7 @@ item_structs: db_addon_startup: yes type: num visu_acl: ro - # cache: yes + cache: yes verbrauch_monat: name: Verbrauch seit Monatsbeginn @@ -822,7 +821,7 @@ item_structs: db_addon_startup: yes type: num visu_acl: ro - # cache: yes + cache: yes verbrauch_jahr: name: Verbrauch seit Jahresbeginn @@ -830,7 +829,7 @@ item_structs: db_addon_startup: yes type: num visu_acl: ro - # cache: yes + cache: yes verbrauch_rolling_12m: name: Verbrauch innerhalb der letzten 12 Monate ausgehend von gestern @@ -838,7 +837,7 @@ item_structs: db_addon_startup: yes type: num visu_acl: ro - # cache: yes + cache: yes verbrauch_tag_minus1: name: Verbrauch gestern @@ -846,7 +845,7 @@ item_structs: db_addon_startup: yes type: num visu_acl: ro - # cache: yes + cache: yes verbrauch_tag_minus2: name: Verbrauch vorgestern @@ -854,7 +853,7 @@ item_structs: db_addon_startup: yes type: num visu_acl: ro - # cache: yes + cache: yes verbrauch_tag_minus3: name: Verbrauch vor 3 Tagen @@ -862,7 +861,7 @@ item_structs: db_addon_startup: yes type: num visu_acl: ro - # cache: yes + cache: yes verbrauch_woche_minus1: name: Verbrauch in der Vorwoche @@ -870,7 +869,7 @@ item_structs: db_addon_startup: yes type: num visu_acl: ro - # cache: yes + cache: yes verbrauch_woche_minus2: name: Verbrauch vor 2 Wochen @@ -878,7 +877,7 @@ item_structs: db_addon_startup: yes type: num visu_acl: ro - # cache: yes + cache: yes verbrauch_monat_minus1: name: Verbrauch im Vormonat @@ -886,7 +885,7 @@ item_structs: db_addon_startup: yes type: num visu_acl: ro - # cache: yes + cache: yes verbrauch_monat_minus12: name: Verbrauch vor 12 Monaten @@ -894,7 +893,7 @@ item_structs: db_addon_startup: yes type: num visu_acl: ro - # cache: yes + cache: yes verbrauch_vorjahreszeitraum: name: Verbrauch im Jahreszeitraum 1.1. bis jetzt vor einem Jahr @@ -902,7 +901,7 @@ item_structs: db_addon_startup: yes type: num visu_acl: ro - # cache: yes + cache: yes verbrauch_verbrauch_rolling_12m_woche_minus1: name: Verbrauch innerhalb der letzten 12 Monate ausgehend vom Ende letzter Woche @@ -910,7 +909,7 @@ item_structs: db_addon_startup: yes type: num visu_acl: ro - # cache: yes + cache: yes verbrauch_2: name: Struct für Verbrauchsauswertung bei Zählern mit stetig ansteigendem Zählerstand (Teil 2) @@ -992,7 +991,7 @@ item_structs: db_addon_startup: yes type: num visu_acl: ro - # cache: yes + cache: yes zaehlerstand_woche_minus1: name: Zählerstand zum Ende der vorigen Woche @@ -1000,7 +999,7 @@ item_structs: db_addon_startup: yes type: num visu_acl: ro - # cache: yes + cache: yes zaehlerstand_monat_minus1: name: Zählerstand zum Ende des Vormonates @@ -1008,7 +1007,7 @@ item_structs: db_addon_startup: yes type: num visu_acl: ro - # cache: yes + cache: yes zaehlerstand_monat_minus2: name: Zählerstand zum Monatsende vor 2 Monaten @@ -1016,7 +1015,7 @@ item_structs: db_addon_startup: yes type: num visu_acl: ro - # cache: yes + cache: yes zaehlerstand_monat_minus3: name: Zählerstand zum Monatsende vor 3 Monaten @@ -1024,7 +1023,7 @@ item_structs: db_addon_startup: yes type: num visu_acl: ro - # cache: yes + cache: yes zaehlerstand_jahr_minus1: name: Zählerstand am Ende des vorigen Jahres @@ -1032,7 +1031,7 @@ item_structs: db_addon_startup: yes type: num visu_acl: ro - # cache: yes + cache: yes minmax_1: name: Struct für Auswertung der Wertehistorie bei schwankenden Werten wie bspw. Temperatur oder Leistung (Teil 1) @@ -1043,14 +1042,14 @@ item_structs: db_addon_ignore_value: 0 db_addon_startup: yes type: num - # cache: yes + cache: yes tag_max: name: Maximaler Wert seit Tagesbeginn db_addon_fct: minmax_tag_max db_addon_startup: yes type: num - # cache: yes + cache: yes tag_avg: name: Maximaler Wert seit Tagesbeginn @@ -1063,133 +1062,133 @@ item_structs: db_addon_fct: minmax_last_24h_min db_addon_startup: yes type: num - # cache: yes + cache: yes last24h_max: name: Maximaler Wert in den letzten 24h (gleitend) db_addon_fct: minmax_last_24h_max db_addon_startup: yes type: num - # cache: yes + cache: yes woche_min: name: Minimaler Wert seit Wochenbeginn db_addon_fct: minmax_woche_min db_addon_startup: yes type: num - # cache: yes + cache: yes woche_max: name: Maximaler Wert seit Wochenbeginn db_addon_fct: minmax_woche_max db_addon_startup: yes type: num - # cache: yes + cache: yes monat_min: name: Minimaler Wert seit Monatsbeginn db_addon_fct: minmax_monat_min db_addon_startup: yes type: num - # cache: yes + cache: yes monat_max: name: Maximaler Wert seit Monatsbeginn db_addon_fct: minmax_monat_max db_addon_startup: yes type: num - # cache: yes + cache: yes jahr_min: name: Minimaler Wert seit Jahresbeginn db_addon_fct: minmax_jahr_min db_addon_startup: yes type: num - # cache: yes + cache: yes jahr_max: name: Maximaler Wert seit Jahresbeginn db_addon_fct: minmax_jahr_max db_addon_startup: yes type: num - # cache: yes + cache: yes tag_minus1_min: name: Minimaler Wert gestern db_addon_fct: minmax_tag_minus1_min db_addon_startup: yes type: num - # cache: yes + cache: yes tag_minus1_max: name: Maximaler Wert gestern db_addon_fct: minmax_tag_minus1_max db_addon_startup: yes type: num - # cache: yes + cache: yes tag_minus1_avg: name: Durchschnittlicher Wert gestern db_addon_fct: minmax_tag_minus1_avg db_addon_startup: yes type: num - # cache: yes + cache: yes woche_minus1_min: name: Minimaler Wert in der Vorwoche db_addon_fct: minmax_woche_minus1_min db_addon_startup: yes type: num - # cache: yes + cache: yes woche_minus1_max: name: Maximaler Wert in der Vorwoche db_addon_fct: minmax_woche_minus1_max db_addon_startup: yes type: num - # cache: yes + cache: yes woche_minus1_avg: name: Durchschnittlicher Wert in der Vorwoche db_addon_fct: minmax_woche_minus1_avg db_addon_startup: yes type: num - # cache: yes + cache: yes monat_minus1_min: name: Minimaler Wert im Vormonat db_addon_fct: minmax_monat_minus1_min db_addon_startup: yes type: num - # cache: yes + cache: yes monat_minus1_max: name: Maximaler Wert im Vormonat db_addon_fct: minmax_monat_minus1_max db_addon_startup: yes type: num - # cache: yes + cache: yes monat_minus1_avg: name: Durchschnittlicher Wert im Vormonat db_addon_fct: minmax_monat_minus1_avg db_addon_startup: yes type: num - # cache: yes + cache: yes jahr_minus1_min: name: Minimaler Wert im Vorjahr db_addon_fct: minmax_jahr_minus1_min db_addon_startup: yes type: num - # cache: yes + cache: yes jahr_minus1_max: name: Maximaler Wert im Vorjahr db_addon_fct: minmax_jahr_minus1_max db_addon_startup: yes type: num - # cache: yes + cache: yes minmax_2: name: Struct für Auswertung der Wertehistorie bei schwankenden Werten wie bspw. Temperatur oder Leistung (Teil 2) diff --git a/db_addon/user_doc.rst b/db_addon/user_doc.rst index fb274f839..c260a7336 100644 --- a/db_addon/user_doc.rst +++ b/db_addon/user_doc.rst @@ -1427,6 +1427,3390 @@ für die angegebene Anzahl von Tagen (days=optional) berechnet. +Vorgehen bei Funktionserweiterung des Plugins bzw. Ergänzung weiterer Werte für Item-Attribute +---------------------------------------------------------------------------------------------- + +Aufgrund der Vielzahl der möglichen Werte der Itemattribute, insbesondere des Itemattributes `db_addon_fct`, wurde die Erstellung/Update +der entsprechenden Teile der `plugin.yam` sowie die Erstellung der Datei `item_attributes.py`, die vom Plugin verwendet wird, automatisiert. + +Die Masterinformationen für alle Itemattribute sowie die Skripte zum Erstellen/Update der beiden Dateien sind in der +Datei `item_attributes_master.py` enthalten. + +.. important:: + + Korrekturen, Erweiterungen etc. der Itemattribute sollten nur in der Datei `item_attributes_master.py` + im Dict der Variable `ITEM_ATTRIBUTS` vorgenommen werden. Das Ausführen der Datei `item_attributes_master.py` (main) + erstellt die `item_attributes.py` und aktualisiert die `plugin.yaml` entsprechend. +Dieses Kapitel wurde automatisch durch Ausführen des Skripts in der Datei 'item_attributes_master.py' erstellt. + +Nachfolgend eine Auflistung der möglichen Attribute für das Plugin im Format: Attribute: Beschreibung | Berechnungszyklus | Item-Type + + +db_addon_fct +------------ + +- verbrauch_heute: Verbrauch am heutigen Tag (Differenz zwischen aktuellem Wert und den Wert am Ende des vorherigen Tages) | Berechnung: onchange | Item-Type: num + +- verbrauch_tag: Verbrauch am heutigen Tag (Differenz zwischen aktuellem Wert und den Wert am Ende des vorherigen Tages) | Berechnung: onchange | Item-Type: num + +- verbrauch_woche: Verbrauch in der aktuellen Woche | Berechnung: onchange | Item-Type: num + +- verbrauch_monat: Verbrauch im aktuellen Monat | Berechnung: onchange | Item-Type: num + +- verbrauch_jahr: Verbrauch im aktuellen Jahr | Berechnung: onchange | Item-Type: num + +- verbrauch_last_24h: Verbrauch innerhalb letzten 24h | Berechnung: hourly | Item-Type: num + +- verbrauch_last_7d: Verbrauch innerhalb letzten 7 Tage | Berechnung: hourly | Item-Type: num + +- verbrauch_heute_minus1: Verbrauch gestern (heute -1 Tag) (Differenz zwischen Wert am Ende des gestrigen Tages und dem Wert am Ende des Tages davor) | Berechnung: daily | Item-Type: num + +- verbrauch_heute_minus2: Verbrauch vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num + +- verbrauch_heute_minus3: Verbrauch heute -3 Tage | Berechnung: daily | Item-Type: num + +- verbrauch_heute_minus4: Verbrauch heute -4 Tage | Berechnung: daily | Item-Type: num + +- verbrauch_heute_minus5: Verbrauch heute -5 Tage | Berechnung: daily | Item-Type: num + +- verbrauch_heute_minus6: Verbrauch heute -6 Tage | Berechnung: daily | Item-Type: num + +- verbrauch_heute_minus7: Verbrauch heute -7 Tage | Berechnung: daily | Item-Type: num + +- verbrauch_heute_minus8: Verbrauch heute -8 Tage | Berechnung: daily | Item-Type: num + +- verbrauch_tag_minus1: Verbrauch gestern (heute -1 Tag) (Differenz zwischen Wert am Ende des gestrigen Tages und dem Wert am Ende des Tages davor) | Berechnung: daily | Item-Type: num + +- verbrauch_tag_minus2: Verbrauch vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num + +- verbrauch_tag_minus3: Verbrauch heute -3 Tage | Berechnung: daily | Item-Type: num + +- verbrauch_tag_minus4: Verbrauch heute -4 Tage | Berechnung: daily | Item-Type: num + +- verbrauch_tag_minus5: Verbrauch heute -5 Tage | Berechnung: daily | Item-Type: num + +- verbrauch_tag_minus6: Verbrauch heute -6 Tage | Berechnung: daily | Item-Type: num + +- verbrauch_tag_minus7: Verbrauch heute -7 Tage | Berechnung: daily | Item-Type: num + +- verbrauch_tag_minus8: Verbrauch heute -8 Tage | Berechnung: daily | Item-Type: num + +- verbrauch_woche_minus1: Verbrauch Vorwoche (aktuelle Woche -1) | Berechnung: weekly | Item-Type: num + +- verbrauch_woche_minus2: Verbrauch aktuelle Woche -2 Wochen | Berechnung: weekly | Item-Type: num + +- verbrauch_woche_minus3: Verbrauch aktuelle Woche -3 Wochen | Berechnung: weekly | Item-Type: num + +- verbrauch_woche_minus4: Verbrauch aktuelle Woche -4 Wochen | Berechnung: weekly | Item-Type: num + +- verbrauch_monat_minus1: Verbrauch Vormonat (aktueller Monat -1) | Berechnung: monthly | Item-Type: num + +- verbrauch_monat_minus2: Verbrauch aktueller Monat -2 Monate | Berechnung: monthly | Item-Type: num + +- verbrauch_monat_minus3: Verbrauch aktueller Monat -3 Monate | Berechnung: monthly | Item-Type: num + +- verbrauch_monat_minus4: Verbrauch aktueller Monat -4 Monate | Berechnung: monthly | Item-Type: num + +- verbrauch_monat_minus12: Verbrauch aktueller Monat -12 Monate | Berechnung: monthly | Item-Type: num + +- verbrauch_jahr_minus1: Verbrauch Vorjahr (aktuelles Jahr -1 Jahr) | Berechnung: yearly | Item-Type: num + +- verbrauch_jahr_minus2: Verbrauch aktuelles Jahr -2 Jahre | Berechnung: yearly | Item-Type: num + +- verbrauch_jahr_minus3: Verbrauch aktuelles Jahr -3 Jahre | Berechnung: yearly | Item-Type: num + +- verbrauch_rolling_12m_heute_minus1: Verbrauch der letzten 12 Monate ausgehend im Ende des letzten Tages | Berechnung: daily | Item-Type: num + +- verbrauch_rolling_12m_tag_minus1: Verbrauch der letzten 12 Monate ausgehend im Ende des letzten Tages | Berechnung: daily | Item-Type: num + +- verbrauch_rolling_12m_woche_minus1: Verbrauch der letzten 12 Monate ausgehend im Ende der letzten Woche | Berechnung: weekly | Item-Type: num + +- verbrauch_rolling_12m_monat_minus1: Verbrauch der letzten 12 Monate ausgehend im Ende des letzten Monats | Berechnung: monthly | Item-Type: num + +- verbrauch_rolling_12m_jahr_minus1: Verbrauch der letzten 12 Monate ausgehend im Ende des letzten Jahres | Berechnung: yearly | Item-Type: num + +- verbrauch_jahreszeitraum_minus1: Verbrauch seit dem 1.1. bis zum heutigen Tag des Vorjahres | Berechnung: daily | Item-Type: num + +- verbrauch_jahreszeitraum_minus2: Verbrauch seit dem 1.1. bis zum heutigen Tag vor 2 Jahren | Berechnung: daily | Item-Type: num + +- verbrauch_jahreszeitraum_minus3: Verbrauch seit dem 1.1. bis zum heutigen Tag vor 3 Jahren | Berechnung: daily | Item-Type: num + +- zaehlerstand_heute_minus1: Zählerstand / Wert am Ende des letzten Tages (heute -1 Tag) | Berechnung: daily | Item-Type: num + +- zaehlerstand_heute_minus2: Zählerstand / Wert am Ende des vorletzten Tages (heute -2 Tag) | Berechnung: daily | Item-Type: num + +- zaehlerstand_heute_minus3: Zählerstand / Wert am Ende des vorvorletzten Tages (heute -3 Tag) | Berechnung: daily | Item-Type: num + +- zaehlerstand_tag_minus1: Zählerstand / Wert am Ende des letzten Tages (heute -1 Tag) | Berechnung: daily | Item-Type: num + +- zaehlerstand_tag_minus2: Zählerstand / Wert am Ende des vorletzten Tages (heute -2 Tag) | Berechnung: daily | Item-Type: num + +- zaehlerstand_tag_minus3: Zählerstand / Wert am Ende des vorvorletzten Tages (heute -3 Tag) | Berechnung: daily | Item-Type: num + +- zaehlerstand_woche_minus1: Zählerstand / Wert am Ende der vorvorletzten Woche (aktuelle Woche -1 Woche) | Berechnung: weekly | Item-Type: num + +- zaehlerstand_woche_minus2: Zählerstand / Wert am Ende der vorletzten Woche (aktuelle Woche -2 Wochen) | Berechnung: weekly | Item-Type: num + +- zaehlerstand_woche_minus3: Zählerstand / Wert am Ende der aktuellen Woche -3 Wochen | Berechnung: weekly | Item-Type: num + +- zaehlerstand_monat_minus1: Zählerstand / Wert am Ende des letzten Monates (aktueller Monat -1 Monat) | Berechnung: monthly | Item-Type: num + +- zaehlerstand_monat_minus2: Zählerstand / Wert am Ende des vorletzten Monates (aktueller Monat -2 Monate) | Berechnung: monthly | Item-Type: num + +- zaehlerstand_monat_minus3: Zählerstand / Wert am Ende des aktuellen Monats -3 Monate | Berechnung: monthly | Item-Type: num + +- zaehlerstand_jahr_minus1: Zählerstand / Wert am Ende des letzten Jahres (aktuelles Jahr -1 Jahr) | Berechnung: yearly | Item-Type: num + +- zaehlerstand_jahr_minus2: Zählerstand / Wert am Ende des vorletzten Jahres (aktuelles Jahr -2 Jahre) | Berechnung: yearly | Item-Type: num + +- zaehlerstand_jahr_minus3: Zählerstand / Wert am Ende des aktuellen Jahres -3 Jahre | Berechnung: yearly | Item-Type: num + +- minmax_last_24h_min: minimaler Wert der letzten 24h | Berechnung: daily | Item-Type: num + +- minmax_last_24h_max: maximaler Wert der letzten 24h | Berechnung: daily | Item-Type: num + +- minmax_last_24h_avg: durchschnittlicher Wert der letzten 24h | Berechnung: daily | Item-Type: num + +- minmax_last_7d_min: minimaler Wert der letzten 7 Tage | Berechnung: daily | Item-Type: num + +- minmax_last_7d_max: maximaler Wert der letzten 7 Tage | Berechnung: daily | Item-Type: num + +- minmax_last_7d_avg: durchschnittlicher Wert der letzten 7 Tage | Berechnung: daily | Item-Type: num + +- minmax_heute_min: Minimalwert seit Tagesbeginn | Berechnung: onchange | Item-Type: num + +- minmax_heute_max: Maximalwert seit Tagesbeginn | Berechnung: onchange | Item-Type: num + +- minmax_heute_avg: Durschnittswert seit Tagesbeginn | Berechnung: onchange | Item-Type: num + +- minmax_heute_minus1_min: Minimalwert gestern (heute -1 Tag) | Berechnung: daily | Item-Type: num + +- minmax_heute_minus1_max: Maximalwert gestern (heute -1 Tag) | Berechnung: daily | Item-Type: num + +- minmax_heute_minus1_avg: Durchschnittswert gestern (heute -1 Tag) | Berechnung: daily | Item-Type: num + +- minmax_heute_minus2_min: Minimalwert vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num + +- minmax_heute_minus2_max: Maximalwert vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num + +- minmax_heute_minus2_avg: Durchschnittswert vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num + +- minmax_heute_minus3_min: Minimalwert heute vor 3 Tagen | Berechnung: daily | Item-Type: num + +- minmax_heute_minus3_max: Maximalwert heute vor 3 Tagen | Berechnung: daily | Item-Type: num + +- minmax_heute_minus3_avg: Durchschnittswert heute vor 3 Tagen | Berechnung: daily | Item-Type: num + +- minmax_tag_min: Minimalwert seit Tagesbeginn | Berechnung: onchange | Item-Type: num + +- minmax_tag_max: Maximalwert seit Tagesbeginn | Berechnung: onchange | Item-Type: num + +- minmax_tag_avg: Durschnittswert seit Tagesbeginn | Berechnung: onchange | Item-Type: num + +- minmax_tag_minus1_min: Minimalwert gestern (heute -1 Tag) | Berechnung: daily | Item-Type: num + +- minmax_tag_minus1_max: Maximalwert gestern (heute -1 Tag) | Berechnung: daily | Item-Type: num + +- minmax_tag_minus1_avg: Durchschnittswert gestern (heute -1 Tag) | Berechnung: daily | Item-Type: num + +- minmax_tag_minus2_min: Minimalwert vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num + +- minmax_tag_minus2_max: Maximalwert vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num + +- minmax_tag_minus2_avg: Durchschnittswert vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num + +- minmax_tag_minus3_min: Minimalwert heute vor 3 Tagen | Berechnung: daily | Item-Type: num + +- minmax_tag_minus3_max: Maximalwert heute vor 3 Tagen | Berechnung: daily | Item-Type: num + +- minmax_tag_minus3_avg: Durchschnittswert heute vor 3 Tagen | Berechnung: daily | Item-Type: num + +- minmax_woche_min: Minimalwert seit Wochenbeginn | Berechnung: onchange | Item-Type: num + +- minmax_woche_max: Maximalwert seit Wochenbeginn | Berechnung: onchange | Item-Type: num + +- minmax_woche_minus1_min: Minimalwert Vorwoche (aktuelle Woche -1) | Berechnung: weekly | Item-Type: num + +- minmax_woche_minus1_max: Maximalwert Vorwoche (aktuelle Woche -1) | Berechnung: weekly | Item-Type: num + +- minmax_woche_minus1_avg: Durchschnittswert Vorwoche (aktuelle Woche -1) | Berechnung: weekly | Item-Type: num + +- minmax_woche_minus2_min: Minimalwert aktuelle Woche -2 Wochen | Berechnung: weekly | Item-Type: num + +- minmax_woche_minus2_max: Maximalwert aktuelle Woche -2 Wochen | Berechnung: weekly | Item-Type: num + +- minmax_woche_minus2_avg: Durchschnittswert aktuelle Woche -2 Wochen | Berechnung: weekly | Item-Type: num + +- minmax_monat_min: Minimalwert seit Monatsbeginn | Berechnung: onchange | Item-Type: num + +- minmax_monat_max: Maximalwert seit Monatsbeginn | Berechnung: onchange | Item-Type: num + +- minmax_monat_minus1_min: Minimalwert Vormonat (aktueller Monat -1) | Berechnung: monthly | Item-Type: num + +- minmax_monat_minus1_max: Maximalwert Vormonat (aktueller Monat -1) | Berechnung: monthly | Item-Type: num + +- minmax_monat_minus1_avg: Durchschnittswert Vormonat (aktueller Monat -1) | Berechnung: monthly | Item-Type: num + +- minmax_monat_minus2_min: Minimalwert aktueller Monat -2 Monate | Berechnung: monthly | Item-Type: num + +- minmax_monat_minus2_max: Maximalwert aktueller Monat -2 Monate | Berechnung: monthly | Item-Type: num + +- minmax_monat_minus2_avg: Durchschnittswert aktueller Monat -2 Monate | Berechnung: monthly | Item-Type: num + +- minmax_jahr_min: Minimalwert seit Jahresbeginn | Berechnung: onchange | Item-Type: num + +- minmax_jahr_max: Maximalwert seit Jahresbeginn | Berechnung: onchange | Item-Type: num + +- minmax_jahr_minus1_min: Minimalwert Vorjahr (aktuelles Jahr -1 Jahr) | Berechnung: yearly | Item-Type: num + +- minmax_jahr_minus1_max: Maximalwert Vorjahr (aktuelles Jahr -1 Jahr) | Berechnung: yearly | Item-Type: num + +- minmax_jahr_minus1_avg: Durchschnittswert Vorjahr (aktuelles Jahr -1 Jahr) | Berechnung: yearly | Item-Type: num + +- tagesmitteltemperatur_heute: Tagesmitteltemperatur heute | Berechnung: onchange | Item-Type: num + +- tagesmitteltemperatur_heute_minus1: Tagesmitteltemperatur des letzten Tages (heute -1 Tag) | Berechnung: daily | Item-Type: num + +- tagesmitteltemperatur_heute_minus2: Tagesmitteltemperatur des vorletzten Tages (heute -2 Tag) | Berechnung: daily | Item-Type: num + +- tagesmitteltemperatur_heute_minus3: Tagesmitteltemperatur des vorvorletzten Tages (heute -3 Tag) | Berechnung: daily | Item-Type: num + +- tagesmitteltemperatur_tag: Tagesmitteltemperatur heute | Berechnung: onchange | Item-Type: num + +- tagesmitteltemperatur_tag_minus1: Tagesmitteltemperatur des letzten Tages (heute -1 Tag) | Berechnung: daily | Item-Type: num + +- tagesmitteltemperatur_tag_minus2: Tagesmitteltemperatur des vorletzten Tages (heute -2 Tag) | Berechnung: daily | Item-Type: num + +- tagesmitteltemperatur_tag_minus3: Tagesmitteltemperatur des vorvorletzten Tages (heute -3 Tag) | Berechnung: daily | Item-Type: num + +- serie_minmax_monat_min_15m: monatlicher Minimalwert der letzten 15 Monate (gleitend) | Berechnung: monthly | Item-Type: list + +- serie_minmax_monat_max_15m: monatlicher Maximalwert der letzten 15 Monate (gleitend) | Berechnung: monthly | Item-Type: list + +- serie_minmax_monat_avg_15m: monatlicher Mittelwert der letzten 15 Monate (gleitend) | Berechnung: monthly | Item-Type: list + +- serie_minmax_woche_min_30w: wöchentlicher Minimalwert der letzten 30 Wochen (gleitend) | Berechnung: weekly | Item-Type: list + +- serie_minmax_woche_max_30w: wöchentlicher Maximalwert der letzten 30 Wochen (gleitend) | Berechnung: weekly | Item-Type: list + +- serie_minmax_woche_avg_30w: wöchentlicher Mittelwert der letzten 30 Wochen (gleitend) | Berechnung: weekly | Item-Type: list + +- serie_minmax_tag_min_30d: täglicher Minimalwert der letzten 30 Tage (gleitend) | Berechnung: daily | Item-Type: list + +- serie_minmax_tag_max_30d: täglicher Maximalwert der letzten 30 Tage (gleitend) | Berechnung: daily | Item-Type: list + +- serie_minmax_tag_avg_30d: täglicher Mittelwert der letzten 30 Tage (gleitend) | Berechnung: daily | Item-Type: list + +- serie_verbrauch_tag_30d: Verbrauch pro Tag der letzten 30 Tage | Berechnung: daily | Item-Type: list + +- serie_verbrauch_woche_30w: Verbrauch pro Woche der letzten 30 Wochen | Berechnung: weekly | Item-Type: list + +- serie_verbrauch_monat_18m: Verbrauch pro Monat der letzten 18 Monate | Berechnung: monthly | Item-Type: list + +- serie_zaehlerstand_tag_30d: Zählerstand am Tagesende der letzten 30 Tage | Berechnung: daily | Item-Type: list + +- serie_zaehlerstand_woche_30w: Zählerstand am Wochenende der letzten 30 Wochen | Berechnung: weekly | Item-Type: list + +- serie_zaehlerstand_monat_18m: Zählerstand am Monatsende der letzten 18 Monate | Berechnung: monthly | Item-Type: list + +- serie_waermesumme_monat_24m: monatliche Wärmesumme der letzten 24 Monate | Berechnung: monthly | Item-Type: list + +- serie_kaeltesumme_monat_24m: monatliche Kältesumme der letzten 24 Monate | Berechnung: monthly | Item-Type: list + +- serie_tagesmittelwert_0d: Tagesmittelwert für den aktuellen Tag | Berechnung: daily | Item-Type: list + +- serie_tagesmittelwert_stunde_0d: Stundenmittelwert für den aktuellen Tag | Berechnung: daily | Item-Type: list + +- serie_tagesmittelwert_stunde_30_0d: Stundenmittelwert für den aktuellen Tag | Berechnung: daily | Item-Type: list + +- serie_tagesmittelwert_tag_stunde_30d: Stundenmittelwert pro Tag der letzten 30 Tage (bspw. zur Berechnung der Tagesmitteltemperatur basierend auf den Mittelwert der Temperatur pro Stunde | Berechnung: daily | Item-Type: list + +- general_oldest_value: Ausgabe des ältesten Wertes des entsprechenden "Parent-Items" mit database Attribut | Berechnung: no | Item-Type: num + +- general_oldest_log: Ausgabe des Timestamp des ältesten Eintrages des entsprechenden "Parent-Items" mit database Attribut | Berechnung: no | Item-Type: list + +- kaeltesumme: Berechnet die Kältesumme für einen Zeitraum, db_addon_params: (year=optional, month=optional) | Berechnung: daily | Item-Type: num + +- waermesumme: Berechnet die Wärmesumme für einen Zeitraum, db_addon_params: (year=optional, month=optional) | Berechnung: daily | Item-Type: num + +- gruenlandtempsumme: Berechnet die Grünlandtemperatursumme für einen Zeitraum, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num + +- wachstumsgradtage: Berechnet die Wachstumsgradtage auf Basis der stündlichen Durchschnittswerte eines Tages für das laufende Jahr mit an Angabe des Temperaturschwellenwertes (threshold=Schwellentemperatur) | Berechnung: daily | Item-Type: num + +- wuestentage: Berechnet die Anzahl der Wüstentage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num + +- heisse_tage: Berechnet die Anzahl der heissen Tage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num + +- tropennaechte: Berechnet die Anzahl der Tropennächte des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num + +- sommertage: Berechnet die Anzahl der Sommertage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num + +- heiztage: Berechnet die Anzahl der Heiztage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num + +- vegetationstage: Berechnet die Anzahl der Vegatationstage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num + +- frosttage: Berechnet die Anzahl der Frosttage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num + +- eistage: Berechnet die Anzahl der Eistage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num + +- tagesmitteltemperatur: Berechnet die Tagesmitteltemperatur auf Basis der stündlichen Durchschnittswerte eines Tages für die angegebene Anzahl von Tagen (timeframe=day, count=integer) | Berechnung: daily | Item-Type: list + +- db_request: Abfrage der DB: db_addon_params: (func=mandatory, item=mandatory, timespan=mandatory, start=optional, end=optional, count=optional, group=optional, group2=optional) | Berechnung: group | Item-Type: list + +- minmax: Berechnet einen min/max/avg Wert für einen bestimmen Zeitraum: db_addon_params: (func=mandatory, timeframe=mandatory, start=mandatory) | Berechnung: timeframe | Item-Type: num + +- minmax_last: 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) | Berechnung: timeframe | Item-Type: num + +- verbrauch: Berechnet einen Verbrauchswert für einen bestimmen Zeitraum: db_addon_params: (timeframe=mandatory, start=mandatory end=mandatory) | Berechnung: timeframe | Item-Type: num + +- zaehlerstand: Berechnet einen Zählerstand für einen bestimmen Zeitpunkt: db_addon_params: (timeframe=mandatory, start=mandatory) | Berechnung: timeframe | Item-Type: num + + +db_addon_info +------------- + +- db_version: Version der verbundenen Datenbank | Berechnung: no | Item-Type: str + + +db_addon_admin +-------------- + +- suspend: Unterbricht die Aktivitäten des Plugin | Berechnung: no | Item-Type: bool + +- recalc_all: Startet einen Neuberechnungslauf aller on-demand Items | Berechnung: no | Item-Type: bool + +- clean_cache_values: Löscht Plugin-Cache und damit alle im Plugin zwischengespeicherten Werte | Berechnung: no | Item-Type: bool + + +Hinweise +======== + + - Das Plugin startet die Berechnungen der Werte nach einer gewissen (konfigurierbaren) Zeit (Attribut `startup_run_delay`) + nach dem Start von shNG, um den Startvorgang nicht zu beeinflussen. + + - Bei Start werden automatisch nur die Items berechnet, für das das Attribute `db_addon_startup` gesetzt wurde. Alle anderen + Items werden erst zur konfigurierten Zeit berechnet. Das Attribute `db_addon_startup` kann auch direkt am `Database-Item` + gesetzt werden. Dabei wird das Attribut auf alle darunter liegenden `db_addon-Items` (bspw. bei Verwendung von structs) vererbt. + Über das WebIF kann die Berechnung aller definierten Items ausgelöst werden. + + - Für sogenannte `on_change` Items, also Items, deren Berechnung bis zum Jetzt (bspw. verbrauch-heute) gehen, wird die Berechnung + immer bei eintreffen eines neuen Wertes gestartet. Zu Reduktion der Belastung auf die Datenbank werden die Werte für das Ende der + letzten Periode gecached. + + - Berechnungen werden nur ausgeführt, wenn für den kompletten abgefragten Zeitraum Werte in der Datenbank vorliegen. Wird bspw. + der Verbrauch des letzten Monats abgefragt wobei erst Werte ab dem 3. des Monats in der Datenbank sind, wird die Berechnung abgebrochen. + + - Mit dem Attribut `use_oldest_entry` kann dieses Verhalten verändert werden. Ist das Attribut gesetzt, wird, wenn für den + Beginn der Abfragezeitraums keinen Werte vorliegen, der älteste Eintrag der Datenbank genutzt. + + - Für die Auswertung kann es nützlich sein, bestimmte Werte aus der Datenbank bei der Berechnung auszublenden. Hierfür stehen + 2 Möglichkeiten zur Verfügung: + - Plugin-Attribut `ignore_0`: (list of strings) Bei Items, bei denen ein String aus der Liste im Pfadnamen vorkommt, + werden 0-Werte (val_num = 0) bei Datenbankauswertungen ignoriert. Hat also das Attribut den Wert ['temp'] werden bei allen Items mit + 'temp' im Pfadnamen die 0-Werte bei der Auswertung ignoriert. + - Item-Attribut `db_addon_ignore_value`: (num) Dieser Wert wird bei der Abfrage bzw. Auswertung der Datenbank für diese + Item ignoriert. + + - Das Plugin enthält sehr ausführliche Logginginformation. Bei unerwartetem Verhalten, den LogLevel entsprechend anpassen, + um mehr information zu erhalten. + + - Berechnungen des Plugins können im WebIF unterbrochen werden. Auch das gesamte Plugin kann pausiert werden. Dies kann bei + starker Systembelastung nützlich sein. + + +Beispiele +========= + +Verbrauch +--------- + +Soll bspw. der Verbrauch von Wasser ausgewertet werden, so ist dies wie folgt möglich: + + +.. code-block:: yaml + + wasserzaehler: + zaehlerstand: + type: num + knx_dpt: 12 + knx_cache: 5/3/4 + eval: round(value/1000, 1) + database: init + struct: + - db_addon.verbrauch_1 + - db_addon.verbrauch_2 + - db_addon.zaehlerstand_1 + +Die Werte des Wasserzählerstandes werden in die Datenbank geschrieben und darauf basierend ausgewertet. Die structs +'db_addon.verbrauch_1' und 'db_addon.verbrauch_2' stellen entsprechende Items für die Verbrauchsauswerten zur Verfügung. + +minmax +------ + +Soll bspw. die minimalen und maximalen Temperaturen ausgewertet werden, kann dies so umgesetzt werden: + +.. code-block:: yaml + + temperature: + aussen: + nord: + name: Außentemp Nordseite + type: num + visu_acl: ro + knx_dpt: 9 + knx_cache: 6/5/1 + database: init + struct: + - db_addon.minmax_1 + - db_addon.minmax_2 + +Die Temperaturwerte werden in die Datenbank geschrieben und darauf basierend ausgewertet. Die structs +'db_addon.minmax_1' und 'db_addon.minmax_2' stellen entsprechende Items für die min/max Auswertung zur Verfügung. + +| + +Web Interface +============= + +Das WebIF stellt neben der Ansicht verbundener Items und deren Parameter und Werte auch Funktionen für die +Administration des Plugins bereit. + +Es stehen Button für: + +- Neuberechnung aller Items +- Abbruch eines aktiven Berechnungslaufes +- Pausieren des Plugins +- Wiederaufnahme des Plugins + +bereit. + +Achtung: Das Auslösen einer kompletten Neuberechnung aller Items kann zu einer starken Belastung der Datenbank +aufgrund vieler Leseanfragen führen. + + +db_addon Items +-------------- + +Dieser Reiter des Webinterface zeigt die Items an, für die ein DatabaseAddon Attribut konfiguriert ist. + + +db_addon Maintenance +-------------------- + +Das Webinterface zeigt detaillierte Informationen über die im Plugin verfügbaren Daten an. +Dies dient der Maintenance bzw. Fehlersuche. Dieser Tab ist nur bei Log-Level "Debug" verfügbar. + + +Erläuterungen zu Temperatursummen +================================= + + +Grünlandtemperatursumme +----------------------- + +Beim Grünland wird die Wärmesumme nach Ernst und Loeper benutzt, um den Vegetationsbeginn und somit den Termin von Düngungsmaßnahmen zu bestimmen. +Dabei erfolgt die Aufsummierung der Tagesmitteltemperaturen über 0 °C, wobei der Januar mit 0.5 und der Februar mit 0.75 gewichtet wird. +Bei einer Wärmesumme von 200 Grad ist eine Düngung angesagt. + +siehe: https://de.wikipedia.org/wiki/Gr%C3%BCnlandtemperatursumme + +Folgende Parameter sind möglich / notwendig: + + +.. code-block:: yaml + + db_addon_params: "year=current" + +- year: Jahreszahl (str oder int), für das die Berechnung ausgeführt werden soll oder "current" für aktuelles Jahr (default: 'current') + + +Wachstumsgradtag +---------------- +Der Begriff Wachstumsgradtage (WGT) ist ein Überbegriff für verschiedene Größen. +Gemeinsam ist ihnen, daß zur Berechnung eine Lufttemperatur von einem Schwellenwert subtrahiert wird. +Je nach Fragestellung und Pflanzenart werden der Schwellenwert unterschiedlich gewählt und die Temperatur unterschiedlich bestimmt. +Verfügbar sind die Berechnung über 0) "einfachen Durchschnitt der Tagestemperaturen", 1) "modifizierten Durchschnitt der Tagestemperaturen" +und 2) Anzahl der Tage, deren Mitteltempertatur oberhalb der Schwellentemperatur lag. + +siehe https://de.wikipedia.org/wiki/Wachstumsgradtag + +Folgende Parameter sind möglich / notwendig: + +.. code-block:: yaml + + db_addon_params: "year=current, method=1, threshold=10" + +- year: Jahreszahl (str oder int), für das die Berechnung ausgeführt werden soll oder "current" für aktuelles Jahr (default: 'current') +- method: 0-Berechnung über "einfachen Durchschnitt der Tagestemperaturen", 1-Berechnung über "modifizierten Durchschnitt (default: 0) +der Tagestemperaturen" 2-Anzahl der Tage, mit Mitteltempertatur oberhalb Schwellentemperatur// 10, 11 Ausgabe aus Zeitserie +- threshold: Schwellentemperatur in °C (int) (default: 10) + + +Wärmesumme +---------- + +Die Wärmesumme soll eine Aussage über den Sommer und die Pflanzenreife liefern. Es gibt keine eindeutige Definition der Größe "Wärmesumme". +Berechnet wird die Wärmesumme als Summe aller Tagesmitteltemperaturen über einem Schwellenwert ab dem 1.1. des Jahres. + +siehe https://de.wikipedia.org/wiki/W%C3%A4rmesumme + +Folgende Parameter sind möglich / notwendig: + +.. code-block:: yaml + + db_addon_params: "year=current, month=1, threshold=10" + +- year: Jahreszahl (str oder int), für das die Berechnung ausgeführt werden soll oder "current" für aktuelles Jahr (default: 'current') +- month: Monat (int) des Jahres, für das die Berechnung ausgeführt werden soll (optional) (default: None) +- threshold: Schwellentemperatur in °C (int) (default: 10) + + +Kältesumme +---------- + +Die Kältesumme soll eine Aussage über die Härte des Winters liefern. +Berechnet wird die Kältesumme als Summe aller negativen Tagesmitteltemperaturen ab dem 21.9. des Jahres bis 31.3. des Folgejahres. + +siehe https://de.wikipedia.org/wiki/K%C3%A4ltesumme + +Folgende Parameter sind möglich / notwendig: + +.. code-block:: yaml + + db_addon_params: "year=current, month=1" + +- year: Jahreszahl (str oder int), für das die Berechnung ausgeführt werden soll oder "current" für aktuelles Jahr (default: 'current') +- month: Monat (int) des Jahres, für das die Berechnung ausgeführt werden soll (optional) (default: None) + + +Tagesmitteltemperatur +--------------------- + +Die Tagesmitteltemperatur wird auf Basis der stündlichen Durchschnittswerte eines Tages (aller in der DB enthaltenen Datensätze) +für die angegebene Anzahl von Tagen (days=optional) berechnet. + + + +Vorgehen bei Funktionserweiterung des Plugins bzw. Ergänzung weiterer Werte für Item-Attribute +---------------------------------------------------------------------------------------------- + +Aufgrund der Vielzahl der möglichen Werte der Itemattribute, insbesondere des Itemattributes `db_addon_fct`, wurde die Erstellung/Update +der entsprechenden Teile der `plugin.yam` sowie die Erstellung der Datei `item_attributes.py`, die vom Plugin verwendet wird, automatisiert. + +Die Masterinformationen für alle Itemattribute sowie die Skripte zum Erstellen/Update der beiden Dateien sind in der +Datei `item_attributes_master.py` enthalten. + +.. important:: + + Korrekturen, Erweiterungen etc. der Itemattribute sollten nur in der Datei `item_attributes_master.py` + im Dict der Variable `ITEM_ATTRIBUTS` vorgenommen werden. Das Ausführen der Datei `item_attributes_master.py` (main) + erstellt die `item_attributes.py` und aktualisiert die `plugin.yaml` entsprechend. +Dieses Kapitel wurde automatisch durch Ausführen des Skripts in der Datei 'item_attributes_master.py' erstellt. + +Nachfolgend eine Auflistung der möglichen Attribute für das Plugin im Format: Attribute: Beschreibung | Berechnungszyklus | Item-Type + + +db_addon_fct +------------ + +- verbrauch_heute: Verbrauch am heutigen Tag (Differenz zwischen aktuellem Wert und den Wert am Ende des vorherigen Tages) | Berechnung: onchange | Item-Type: num + +- verbrauch_tag: Verbrauch am heutigen Tag (Differenz zwischen aktuellem Wert und den Wert am Ende des vorherigen Tages) | Berechnung: onchange | Item-Type: num + +- verbrauch_woche: Verbrauch in der aktuellen Woche | Berechnung: onchange | Item-Type: num + +- verbrauch_monat: Verbrauch im aktuellen Monat | Berechnung: onchange | Item-Type: num + +- verbrauch_jahr: Verbrauch im aktuellen Jahr | Berechnung: onchange | Item-Type: num + +- verbrauch_last_24h: Verbrauch innerhalb letzten 24h | Berechnung: hourly | Item-Type: num + +- verbrauch_last_7d: Verbrauch innerhalb letzten 7 Tage | Berechnung: hourly | Item-Type: num + +- verbrauch_heute_minus1: Verbrauch gestern (heute -1 Tag) (Differenz zwischen Wert am Ende des gestrigen Tages und dem Wert am Ende des Tages davor) | Berechnung: daily | Item-Type: num + +- verbrauch_heute_minus2: Verbrauch vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num + +- verbrauch_heute_minus3: Verbrauch heute -3 Tage | Berechnung: daily | Item-Type: num + +- verbrauch_heute_minus4: Verbrauch heute -4 Tage | Berechnung: daily | Item-Type: num + +- verbrauch_heute_minus5: Verbrauch heute -5 Tage | Berechnung: daily | Item-Type: num + +- verbrauch_heute_minus6: Verbrauch heute -6 Tage | Berechnung: daily | Item-Type: num + +- verbrauch_heute_minus7: Verbrauch heute -7 Tage | Berechnung: daily | Item-Type: num + +- verbrauch_heute_minus8: Verbrauch heute -8 Tage | Berechnung: daily | Item-Type: num + +- verbrauch_tag_minus1: Verbrauch gestern (heute -1 Tag) (Differenz zwischen Wert am Ende des gestrigen Tages und dem Wert am Ende des Tages davor) | Berechnung: daily | Item-Type: num + +- verbrauch_tag_minus2: Verbrauch vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num + +- verbrauch_tag_minus3: Verbrauch heute -3 Tage | Berechnung: daily | Item-Type: num + +- verbrauch_tag_minus4: Verbrauch heute -4 Tage | Berechnung: daily | Item-Type: num + +- verbrauch_tag_minus5: Verbrauch heute -5 Tage | Berechnung: daily | Item-Type: num + +- verbrauch_tag_minus6: Verbrauch heute -6 Tage | Berechnung: daily | Item-Type: num + +- verbrauch_tag_minus7: Verbrauch heute -7 Tage | Berechnung: daily | Item-Type: num + +- verbrauch_tag_minus8: Verbrauch heute -8 Tage | Berechnung: daily | Item-Type: num + +- verbrauch_woche_minus1: Verbrauch Vorwoche (aktuelle Woche -1) | Berechnung: weekly | Item-Type: num + +- verbrauch_woche_minus2: Verbrauch aktuelle Woche -2 Wochen | Berechnung: weekly | Item-Type: num + +- verbrauch_woche_minus3: Verbrauch aktuelle Woche -3 Wochen | Berechnung: weekly | Item-Type: num + +- verbrauch_woche_minus4: Verbrauch aktuelle Woche -4 Wochen | Berechnung: weekly | Item-Type: num + +- verbrauch_monat_minus1: Verbrauch Vormonat (aktueller Monat -1) | Berechnung: monthly | Item-Type: num + +- verbrauch_monat_minus2: Verbrauch aktueller Monat -2 Monate | Berechnung: monthly | Item-Type: num + +- verbrauch_monat_minus3: Verbrauch aktueller Monat -3 Monate | Berechnung: monthly | Item-Type: num + +- verbrauch_monat_minus4: Verbrauch aktueller Monat -4 Monate | Berechnung: monthly | Item-Type: num + +- verbrauch_monat_minus12: Verbrauch aktueller Monat -12 Monate | Berechnung: monthly | Item-Type: num + +- verbrauch_jahr_minus1: Verbrauch Vorjahr (aktuelles Jahr -1 Jahr) | Berechnung: yearly | Item-Type: num + +- verbrauch_jahr_minus2: Verbrauch aktuelles Jahr -2 Jahre | Berechnung: yearly | Item-Type: num + +- verbrauch_jahr_minus3: Verbrauch aktuelles Jahr -3 Jahre | Berechnung: yearly | Item-Type: num + +- verbrauch_rolling_12m_heute_minus1: Verbrauch der letzten 12 Monate ausgehend im Ende des letzten Tages | Berechnung: daily | Item-Type: num + +- verbrauch_rolling_12m_tag_minus1: Verbrauch der letzten 12 Monate ausgehend im Ende des letzten Tages | Berechnung: daily | Item-Type: num + +- verbrauch_rolling_12m_woche_minus1: Verbrauch der letzten 12 Monate ausgehend im Ende der letzten Woche | Berechnung: weekly | Item-Type: num + +- verbrauch_rolling_12m_monat_minus1: Verbrauch der letzten 12 Monate ausgehend im Ende des letzten Monats | Berechnung: monthly | Item-Type: num + +- verbrauch_rolling_12m_jahr_minus1: Verbrauch der letzten 12 Monate ausgehend im Ende des letzten Jahres | Berechnung: yearly | Item-Type: num + +- verbrauch_jahreszeitraum_minus1: Verbrauch seit dem 1.1. bis zum heutigen Tag des Vorjahres | Berechnung: daily | Item-Type: num + +- verbrauch_jahreszeitraum_minus2: Verbrauch seit dem 1.1. bis zum heutigen Tag vor 2 Jahren | Berechnung: daily | Item-Type: num + +- verbrauch_jahreszeitraum_minus3: Verbrauch seit dem 1.1. bis zum heutigen Tag vor 3 Jahren | Berechnung: daily | Item-Type: num + +- zaehlerstand_heute_minus1: Zählerstand / Wert am Ende des letzten Tages (heute -1 Tag) | Berechnung: daily | Item-Type: num + +- zaehlerstand_heute_minus2: Zählerstand / Wert am Ende des vorletzten Tages (heute -2 Tag) | Berechnung: daily | Item-Type: num + +- zaehlerstand_heute_minus3: Zählerstand / Wert am Ende des vorvorletzten Tages (heute -3 Tag) | Berechnung: daily | Item-Type: num + +- zaehlerstand_tag_minus1: Zählerstand / Wert am Ende des letzten Tages (heute -1 Tag) | Berechnung: daily | Item-Type: num + +- zaehlerstand_tag_minus2: Zählerstand / Wert am Ende des vorletzten Tages (heute -2 Tag) | Berechnung: daily | Item-Type: num + +- zaehlerstand_tag_minus3: Zählerstand / Wert am Ende des vorvorletzten Tages (heute -3 Tag) | Berechnung: daily | Item-Type: num + +- zaehlerstand_woche_minus1: Zählerstand / Wert am Ende der vorvorletzten Woche (aktuelle Woche -1 Woche) | Berechnung: weekly | Item-Type: num + +- zaehlerstand_woche_minus2: Zählerstand / Wert am Ende der vorletzten Woche (aktuelle Woche -2 Wochen) | Berechnung: weekly | Item-Type: num + +- zaehlerstand_woche_minus3: Zählerstand / Wert am Ende der aktuellen Woche -3 Wochen | Berechnung: weekly | Item-Type: num + +- zaehlerstand_monat_minus1: Zählerstand / Wert am Ende des letzten Monates (aktueller Monat -1 Monat) | Berechnung: monthly | Item-Type: num + +- zaehlerstand_monat_minus2: Zählerstand / Wert am Ende des vorletzten Monates (aktueller Monat -2 Monate) | Berechnung: monthly | Item-Type: num + +- zaehlerstand_monat_minus3: Zählerstand / Wert am Ende des aktuellen Monats -3 Monate | Berechnung: monthly | Item-Type: num + +- zaehlerstand_jahr_minus1: Zählerstand / Wert am Ende des letzten Jahres (aktuelles Jahr -1 Jahr) | Berechnung: yearly | Item-Type: num + +- zaehlerstand_jahr_minus2: Zählerstand / Wert am Ende des vorletzten Jahres (aktuelles Jahr -2 Jahre) | Berechnung: yearly | Item-Type: num + +- zaehlerstand_jahr_minus3: Zählerstand / Wert am Ende des aktuellen Jahres -3 Jahre | Berechnung: yearly | Item-Type: num + +- minmax_last_24h_min: minimaler Wert der letzten 24h | Berechnung: daily | Item-Type: num + +- minmax_last_24h_max: maximaler Wert der letzten 24h | Berechnung: daily | Item-Type: num + +- minmax_last_24h_avg: durchschnittlicher Wert der letzten 24h | Berechnung: daily | Item-Type: num + +- minmax_last_7d_min: minimaler Wert der letzten 7 Tage | Berechnung: daily | Item-Type: num + +- minmax_last_7d_max: maximaler Wert der letzten 7 Tage | Berechnung: daily | Item-Type: num + +- minmax_last_7d_avg: durchschnittlicher Wert der letzten 7 Tage | Berechnung: daily | Item-Type: num + +- minmax_heute_min: Minimalwert seit Tagesbeginn | Berechnung: onchange | Item-Type: num + +- minmax_heute_max: Maximalwert seit Tagesbeginn | Berechnung: onchange | Item-Type: num + +- minmax_heute_avg: Durschnittswert seit Tagesbeginn | Berechnung: onchange | Item-Type: num + +- minmax_heute_minus1_min: Minimalwert gestern (heute -1 Tag) | Berechnung: daily | Item-Type: num + +- minmax_heute_minus1_max: Maximalwert gestern (heute -1 Tag) | Berechnung: daily | Item-Type: num + +- minmax_heute_minus1_avg: Durchschnittswert gestern (heute -1 Tag) | Berechnung: daily | Item-Type: num + +- minmax_heute_minus2_min: Minimalwert vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num + +- minmax_heute_minus2_max: Maximalwert vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num + +- minmax_heute_minus2_avg: Durchschnittswert vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num + +- minmax_heute_minus3_min: Minimalwert heute vor 3 Tagen | Berechnung: daily | Item-Type: num + +- minmax_heute_minus3_max: Maximalwert heute vor 3 Tagen | Berechnung: daily | Item-Type: num + +- minmax_heute_minus3_avg: Durchschnittswert heute vor 3 Tagen | Berechnung: daily | Item-Type: num + +- minmax_tag_min: Minimalwert seit Tagesbeginn | Berechnung: onchange | Item-Type: num + +- minmax_tag_max: Maximalwert seit Tagesbeginn | Berechnung: onchange | Item-Type: num + +- minmax_tag_avg: Durschnittswert seit Tagesbeginn | Berechnung: onchange | Item-Type: num + +- minmax_tag_minus1_min: Minimalwert gestern (heute -1 Tag) | Berechnung: daily | Item-Type: num + +- minmax_tag_minus1_max: Maximalwert gestern (heute -1 Tag) | Berechnung: daily | Item-Type: num + +- minmax_tag_minus1_avg: Durchschnittswert gestern (heute -1 Tag) | Berechnung: daily | Item-Type: num + +- minmax_tag_minus2_min: Minimalwert vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num + +- minmax_tag_minus2_max: Maximalwert vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num + +- minmax_tag_minus2_avg: Durchschnittswert vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num + +- minmax_tag_minus3_min: Minimalwert heute vor 3 Tagen | Berechnung: daily | Item-Type: num + +- minmax_tag_minus3_max: Maximalwert heute vor 3 Tagen | Berechnung: daily | Item-Type: num + +- minmax_tag_minus3_avg: Durchschnittswert heute vor 3 Tagen | Berechnung: daily | Item-Type: num + +- minmax_woche_min: Minimalwert seit Wochenbeginn | Berechnung: onchange | Item-Type: num + +- minmax_woche_max: Maximalwert seit Wochenbeginn | Berechnung: onchange | Item-Type: num + +- minmax_woche_minus1_min: Minimalwert Vorwoche (aktuelle Woche -1) | Berechnung: weekly | Item-Type: num + +- minmax_woche_minus1_max: Maximalwert Vorwoche (aktuelle Woche -1) | Berechnung: weekly | Item-Type: num + +- minmax_woche_minus1_avg: Durchschnittswert Vorwoche (aktuelle Woche -1) | Berechnung: weekly | Item-Type: num + +- minmax_woche_minus2_min: Minimalwert aktuelle Woche -2 Wochen | Berechnung: weekly | Item-Type: num + +- minmax_woche_minus2_max: Maximalwert aktuelle Woche -2 Wochen | Berechnung: weekly | Item-Type: num + +- minmax_woche_minus2_avg: Durchschnittswert aktuelle Woche -2 Wochen | Berechnung: weekly | Item-Type: num + +- minmax_monat_min: Minimalwert seit Monatsbeginn | Berechnung: onchange | Item-Type: num + +- minmax_monat_max: Maximalwert seit Monatsbeginn | Berechnung: onchange | Item-Type: num + +- minmax_monat_minus1_min: Minimalwert Vormonat (aktueller Monat -1) | Berechnung: monthly | Item-Type: num + +- minmax_monat_minus1_max: Maximalwert Vormonat (aktueller Monat -1) | Berechnung: monthly | Item-Type: num + +- minmax_monat_minus1_avg: Durchschnittswert Vormonat (aktueller Monat -1) | Berechnung: monthly | Item-Type: num + +- minmax_monat_minus2_min: Minimalwert aktueller Monat -2 Monate | Berechnung: monthly | Item-Type: num + +- minmax_monat_minus2_max: Maximalwert aktueller Monat -2 Monate | Berechnung: monthly | Item-Type: num + +- minmax_monat_minus2_avg: Durchschnittswert aktueller Monat -2 Monate | Berechnung: monthly | Item-Type: num + +- minmax_jahr_min: Minimalwert seit Jahresbeginn | Berechnung: onchange | Item-Type: num + +- minmax_jahr_max: Maximalwert seit Jahresbeginn | Berechnung: onchange | Item-Type: num + +- minmax_jahr_minus1_min: Minimalwert Vorjahr (aktuelles Jahr -1 Jahr) | Berechnung: yearly | Item-Type: num + +- minmax_jahr_minus1_max: Maximalwert Vorjahr (aktuelles Jahr -1 Jahr) | Berechnung: yearly | Item-Type: num + +- minmax_jahr_minus1_avg: Durchschnittswert Vorjahr (aktuelles Jahr -1 Jahr) | Berechnung: yearly | Item-Type: num + +- tagesmitteltemperatur_heute: Tagesmitteltemperatur heute | Berechnung: onchange | Item-Type: num + +- tagesmitteltemperatur_heute_minus1: Tagesmitteltemperatur des letzten Tages (heute -1 Tag) | Berechnung: daily | Item-Type: num + +- tagesmitteltemperatur_heute_minus2: Tagesmitteltemperatur des vorletzten Tages (heute -2 Tag) | Berechnung: daily | Item-Type: num + +- tagesmitteltemperatur_heute_minus3: Tagesmitteltemperatur des vorvorletzten Tages (heute -3 Tag) | Berechnung: daily | Item-Type: num + +- tagesmitteltemperatur_tag: Tagesmitteltemperatur heute | Berechnung: onchange | Item-Type: num + +- tagesmitteltemperatur_tag_minus1: Tagesmitteltemperatur des letzten Tages (heute -1 Tag) | Berechnung: daily | Item-Type: num + +- tagesmitteltemperatur_tag_minus2: Tagesmitteltemperatur des vorletzten Tages (heute -2 Tag) | Berechnung: daily | Item-Type: num + +- tagesmitteltemperatur_tag_minus3: Tagesmitteltemperatur des vorvorletzten Tages (heute -3 Tag) | Berechnung: daily | Item-Type: num + +- serie_minmax_monat_min_15m: monatlicher Minimalwert der letzten 15 Monate (gleitend) | Berechnung: monthly | Item-Type: list + +- serie_minmax_monat_max_15m: monatlicher Maximalwert der letzten 15 Monate (gleitend) | Berechnung: monthly | Item-Type: list + +- serie_minmax_monat_avg_15m: monatlicher Mittelwert der letzten 15 Monate (gleitend) | Berechnung: monthly | Item-Type: list + +- serie_minmax_woche_min_30w: wöchentlicher Minimalwert der letzten 30 Wochen (gleitend) | Berechnung: weekly | Item-Type: list + +- serie_minmax_woche_max_30w: wöchentlicher Maximalwert der letzten 30 Wochen (gleitend) | Berechnung: weekly | Item-Type: list + +- serie_minmax_woche_avg_30w: wöchentlicher Mittelwert der letzten 30 Wochen (gleitend) | Berechnung: weekly | Item-Type: list + +- serie_minmax_tag_min_30d: täglicher Minimalwert der letzten 30 Tage (gleitend) | Berechnung: daily | Item-Type: list + +- serie_minmax_tag_max_30d: täglicher Maximalwert der letzten 30 Tage (gleitend) | Berechnung: daily | Item-Type: list + +- serie_minmax_tag_avg_30d: täglicher Mittelwert der letzten 30 Tage (gleitend) | Berechnung: daily | Item-Type: list + +- serie_verbrauch_tag_30d: Verbrauch pro Tag der letzten 30 Tage | Berechnung: daily | Item-Type: list + +- serie_verbrauch_woche_30w: Verbrauch pro Woche der letzten 30 Wochen | Berechnung: weekly | Item-Type: list + +- serie_verbrauch_monat_18m: Verbrauch pro Monat der letzten 18 Monate | Berechnung: monthly | Item-Type: list + +- serie_zaehlerstand_tag_30d: Zählerstand am Tagesende der letzten 30 Tage | Berechnung: daily | Item-Type: list + +- serie_zaehlerstand_woche_30w: Zählerstand am Wochenende der letzten 30 Wochen | Berechnung: weekly | Item-Type: list + +- serie_zaehlerstand_monat_18m: Zählerstand am Monatsende der letzten 18 Monate | Berechnung: monthly | Item-Type: list + +- serie_waermesumme_monat_24m: monatliche Wärmesumme der letzten 24 Monate | Berechnung: monthly | Item-Type: list + +- serie_kaeltesumme_monat_24m: monatliche Kältesumme der letzten 24 Monate | Berechnung: monthly | Item-Type: list + +- serie_tagesmittelwert_0d: Tagesmittelwert für den aktuellen Tag | Berechnung: daily | Item-Type: list + +- serie_tagesmittelwert_stunde_0d: Stundenmittelwert für den aktuellen Tag | Berechnung: daily | Item-Type: list + +- serie_tagesmittelwert_stunde_30_0d: Stundenmittelwert für den aktuellen Tag | Berechnung: daily | Item-Type: list + +- serie_tagesmittelwert_tag_stunde_30d: Stundenmittelwert pro Tag der letzten 30 Tage (bspw. zur Berechnung der Tagesmitteltemperatur basierend auf den Mittelwert der Temperatur pro Stunde | Berechnung: daily | Item-Type: list + +- general_oldest_value: Ausgabe des ältesten Wertes des entsprechenden "Parent-Items" mit database Attribut | Berechnung: no | Item-Type: num + +- general_oldest_log: Ausgabe des Timestamp des ältesten Eintrages des entsprechenden "Parent-Items" mit database Attribut | Berechnung: no | Item-Type: list + +- kaeltesumme: Berechnet die Kältesumme für einen Zeitraum, db_addon_params: (year=optional, month=optional) | Berechnung: daily | Item-Type: num + +- waermesumme: Berechnet die Wärmesumme für einen Zeitraum, db_addon_params: (year=optional, month=optional) | Berechnung: daily | Item-Type: num + +- gruenlandtempsumme: Berechnet die Grünlandtemperatursumme für einen Zeitraum, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num + +- wachstumsgradtage: Berechnet die Wachstumsgradtage auf Basis der stündlichen Durchschnittswerte eines Tages für das laufende Jahr mit an Angabe des Temperaturschwellenwertes (threshold=Schwellentemperatur) | Berechnung: daily | Item-Type: num + +- wuestentage: Berechnet die Anzahl der Wüstentage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num + +- heisse_tage: Berechnet die Anzahl der heissen Tage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num + +- tropennaechte: Berechnet die Anzahl der Tropennächte des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num + +- sommertage: Berechnet die Anzahl der Sommertage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num + +- heiztage: Berechnet die Anzahl der Heiztage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num + +- vegetationstage: Berechnet die Anzahl der Vegatationstage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num + +- frosttage: Berechnet die Anzahl der Frosttage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num + +- eistage: Berechnet die Anzahl der Eistage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num + +- tagesmitteltemperatur: Berechnet die Tagesmitteltemperatur auf Basis der stündlichen Durchschnittswerte eines Tages für die angegebene Anzahl von Tagen (timeframe=day, count=integer) | Berechnung: daily | Item-Type: list + +- db_request: Abfrage der DB: db_addon_params: (func=mandatory, item=mandatory, timespan=mandatory, start=optional, end=optional, count=optional, group=optional, group2=optional) | Berechnung: group | Item-Type: list + +- minmax: Berechnet einen min/max/avg Wert für einen bestimmen Zeitraum: db_addon_params: (func=mandatory, timeframe=mandatory, start=mandatory) | Berechnung: timeframe | Item-Type: num + +- minmax_last: 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) | Berechnung: timeframe | Item-Type: num + +- verbrauch: Berechnet einen Verbrauchswert für einen bestimmen Zeitraum: db_addon_params: (timeframe=mandatory, start=mandatory end=mandatory) | Berechnung: timeframe | Item-Type: num + +- zaehlerstand: Berechnet einen Zählerstand für einen bestimmen Zeitpunkt: db_addon_params: (timeframe=mandatory, start=mandatory) | Berechnung: timeframe | Item-Type: num + + +db_addon_info +------------- + +- db_version: Version der verbundenen Datenbank | Berechnung: no | Item-Type: str + + +db_addon_admin +-------------- + +- suspend: Unterbricht die Aktivitäten des Plugin | Berechnung: no | Item-Type: bool + +- recalc_all: Startet einen Neuberechnungslauf aller on-demand Items | Berechnung: no | Item-Type: bool + +- clean_cache_values: Löscht Plugin-Cache und damit alle im Plugin zwischengespeicherten Werte | Berechnung: no | Item-Type: bool + + +Hinweise +======== + + - Das Plugin startet die Berechnungen der Werte nach einer gewissen (konfigurierbaren) Zeit (Attribut `startup_run_delay`) + nach dem Start von shNG, um den Startvorgang nicht zu beeinflussen. + + - Bei Start werden automatisch nur die Items berechnet, für das das Attribute `db_addon_startup` gesetzt wurde. Alle anderen + Items werden erst zur konfigurierten Zeit berechnet. Das Attribute `db_addon_startup` kann auch direkt am `Database-Item` + gesetzt werden. Dabei wird das Attribut auf alle darunter liegenden `db_addon-Items` (bspw. bei Verwendung von structs) vererbt. + Über das WebIF kann die Berechnung aller definierten Items ausgelöst werden. + + - Für sogenannte `on_change` Items, also Items, deren Berechnung bis zum Jetzt (bspw. verbrauch-heute) gehen, wird die Berechnung + immer bei eintreffen eines neuen Wertes gestartet. Zu Reduktion der Belastung auf die Datenbank werden die Werte für das Ende der + letzten Periode gecached. + + - Berechnungen werden nur ausgeführt, wenn für den kompletten abgefragten Zeitraum Werte in der Datenbank vorliegen. Wird bspw. + der Verbrauch des letzten Monats abgefragt wobei erst Werte ab dem 3. des Monats in der Datenbank sind, wird die Berechnung abgebrochen. + + - Mit dem Attribut `use_oldest_entry` kann dieses Verhalten verändert werden. Ist das Attribut gesetzt, wird, wenn für den + Beginn der Abfragezeitraums keinen Werte vorliegen, der älteste Eintrag der Datenbank genutzt. + + - Für die Auswertung kann es nützlich sein, bestimmte Werte aus der Datenbank bei der Berechnung auszublenden. Hierfür stehen + 2 Möglichkeiten zur Verfügung: + - Plugin-Attribut `ignore_0`: (list of strings) Bei Items, bei denen ein String aus der Liste im Pfadnamen vorkommt, + werden 0-Werte (val_num = 0) bei Datenbankauswertungen ignoriert. Hat also das Attribut den Wert ['temp'] werden bei allen Items mit + 'temp' im Pfadnamen die 0-Werte bei der Auswertung ignoriert. + - Item-Attribut `db_addon_ignore_value`: (num) Dieser Wert wird bei der Abfrage bzw. Auswertung der Datenbank für diese + Item ignoriert. + + - Das Plugin enthält sehr ausführliche Logginginformation. Bei unerwartetem Verhalten, den LogLevel entsprechend anpassen, + um mehr information zu erhalten. + + - Berechnungen des Plugins können im WebIF unterbrochen werden. Auch das gesamte Plugin kann pausiert werden. Dies kann bei + starker Systembelastung nützlich sein. + + +Beispiele +========= + +Verbrauch +--------- + +Soll bspw. der Verbrauch von Wasser ausgewertet werden, so ist dies wie folgt möglich: + + +.. code-block:: yaml + + wasserzaehler: + zaehlerstand: + type: num + knx_dpt: 12 + knx_cache: 5/3/4 + eval: round(value/1000, 1) + database: init + struct: + - db_addon.verbrauch_1 + - db_addon.verbrauch_2 + - db_addon.zaehlerstand_1 + +Die Werte des Wasserzählerstandes werden in die Datenbank geschrieben und darauf basierend ausgewertet. Die structs +'db_addon.verbrauch_1' und 'db_addon.verbrauch_2' stellen entsprechende Items für die Verbrauchsauswerten zur Verfügung. + +minmax +------ + +Soll bspw. die minimalen und maximalen Temperaturen ausgewertet werden, kann dies so umgesetzt werden: + +.. code-block:: yaml + + temperature: + aussen: + nord: + name: Außentemp Nordseite + type: num + visu_acl: ro + knx_dpt: 9 + knx_cache: 6/5/1 + database: init + struct: + - db_addon.minmax_1 + - db_addon.minmax_2 + +Die Temperaturwerte werden in die Datenbank geschrieben und darauf basierend ausgewertet. Die structs +'db_addon.minmax_1' und 'db_addon.minmax_2' stellen entsprechende Items für die min/max Auswertung zur Verfügung. + +| + +Web Interface +============= + +Das WebIF stellt neben der Ansicht verbundener Items und deren Parameter und Werte auch Funktionen für die +Administration des Plugins bereit. + +Es stehen Button für: + +- Neuberechnung aller Items +- Abbruch eines aktiven Berechnungslaufes +- Pausieren des Plugins +- Wiederaufnahme des Plugins + +bereit. + +Achtung: Das Auslösen einer kompletten Neuberechnung aller Items kann zu einer starken Belastung der Datenbank +aufgrund vieler Leseanfragen führen. + + +db_addon Items +-------------- + +Dieser Reiter des Webinterface zeigt die Items an, für die ein DatabaseAddon Attribut konfiguriert ist. + + +db_addon Maintenance +-------------------- + +Das Webinterface zeigt detaillierte Informationen über die im Plugin verfügbaren Daten an. +Dies dient der Maintenance bzw. Fehlersuche. Dieser Tab ist nur bei Log-Level "Debug" verfügbar. + + +Erläuterungen zu Temperatursummen +================================= + + +Grünlandtemperatursumme +----------------------- + +Beim Grünland wird die Wärmesumme nach Ernst und Loeper benutzt, um den Vegetationsbeginn und somit den Termin von Düngungsmaßnahmen zu bestimmen. +Dabei erfolgt die Aufsummierung der Tagesmitteltemperaturen über 0 °C, wobei der Januar mit 0.5 und der Februar mit 0.75 gewichtet wird. +Bei einer Wärmesumme von 200 Grad ist eine Düngung angesagt. + +siehe: https://de.wikipedia.org/wiki/Gr%C3%BCnlandtemperatursumme + +Folgende Parameter sind möglich / notwendig: + + +.. code-block:: yaml + + db_addon_params: "year=current" + +- year: Jahreszahl (str oder int), für das die Berechnung ausgeführt werden soll oder "current" für aktuelles Jahr (default: 'current') + + +Wachstumsgradtag +---------------- +Der Begriff Wachstumsgradtage (WGT) ist ein Überbegriff für verschiedene Größen. +Gemeinsam ist ihnen, daß zur Berechnung eine Lufttemperatur von einem Schwellenwert subtrahiert wird. +Je nach Fragestellung und Pflanzenart werden der Schwellenwert unterschiedlich gewählt und die Temperatur unterschiedlich bestimmt. +Verfügbar sind die Berechnung über 0) "einfachen Durchschnitt der Tagestemperaturen", 1) "modifizierten Durchschnitt der Tagestemperaturen" +und 2) Anzahl der Tage, deren Mitteltempertatur oberhalb der Schwellentemperatur lag. + +siehe https://de.wikipedia.org/wiki/Wachstumsgradtag + +Folgende Parameter sind möglich / notwendig: + +.. code-block:: yaml + + db_addon_params: "year=current, method=1, threshold=10" + +- year: Jahreszahl (str oder int), für das die Berechnung ausgeführt werden soll oder "current" für aktuelles Jahr (default: 'current') +- method: 0-Berechnung über "einfachen Durchschnitt der Tagestemperaturen", 1-Berechnung über "modifizierten Durchschnitt (default: 0) +der Tagestemperaturen" 2-Anzahl der Tage, mit Mitteltempertatur oberhalb Schwellentemperatur// 10, 11 Ausgabe aus Zeitserie +- threshold: Schwellentemperatur in °C (int) (default: 10) + + +Wärmesumme +---------- + +Die Wärmesumme soll eine Aussage über den Sommer und die Pflanzenreife liefern. Es gibt keine eindeutige Definition der Größe "Wärmesumme". +Berechnet wird die Wärmesumme als Summe aller Tagesmitteltemperaturen über einem Schwellenwert ab dem 1.1. des Jahres. + +siehe https://de.wikipedia.org/wiki/W%C3%A4rmesumme + +Folgende Parameter sind möglich / notwendig: + +.. code-block:: yaml + + db_addon_params: "year=current, month=1, threshold=10" + +- year: Jahreszahl (str oder int), für das die Berechnung ausgeführt werden soll oder "current" für aktuelles Jahr (default: 'current') +- month: Monat (int) des Jahres, für das die Berechnung ausgeführt werden soll (optional) (default: None) +- threshold: Schwellentemperatur in °C (int) (default: 10) + + +Kältesumme +---------- + +Die Kältesumme soll eine Aussage über die Härte des Winters liefern. +Berechnet wird die Kältesumme als Summe aller negativen Tagesmitteltemperaturen ab dem 21.9. des Jahres bis 31.3. des Folgejahres. + +siehe https://de.wikipedia.org/wiki/K%C3%A4ltesumme + +Folgende Parameter sind möglich / notwendig: + +.. code-block:: yaml + + db_addon_params: "year=current, month=1" + +- year: Jahreszahl (str oder int), für das die Berechnung ausgeführt werden soll oder "current" für aktuelles Jahr (default: 'current') +- month: Monat (int) des Jahres, für das die Berechnung ausgeführt werden soll (optional) (default: None) + + +Tagesmitteltemperatur +--------------------- + +Die Tagesmitteltemperatur wird auf Basis der stündlichen Durchschnittswerte eines Tages (aller in der DB enthaltenen Datensätze) +für die angegebene Anzahl von Tagen (days=optional) berechnet. + + + +Vorgehen bei Funktionserweiterung des Plugins bzw. Ergänzung weiterer Werte für Item-Attribute +---------------------------------------------------------------------------------------------- + +Aufgrund der Vielzahl der möglichen Werte der Itemattribute, insbesondere des Itemattributes `db_addon_fct`, wurde die Erstellung/Update +der entsprechenden Teile der `plugin.yam` sowie die Erstellung der Datei `item_attributes.py`, die vom Plugin verwendet wird, automatisiert. + +Die Masterinformationen für alle Itemattribute sowie die Skripte zum Erstellen/Update der beiden Dateien sind in der +Datei `item_attributes_master.py` enthalten. + +.. important:: + + Korrekturen, Erweiterungen etc. der Itemattribute sollten nur in der Datei `item_attributes_master.py` + im Dict der Variable `ITEM_ATTRIBUTS` vorgenommen werden. Das Ausführen der Datei `item_attributes_master.py` (main) + erstellt die `item_attributes.py` und aktualisiert die `plugin.yaml` entsprechend. +Dieses Kapitel wurde automatisch durch Ausführen des Skripts in der Datei 'item_attributes_master.py' erstellt. + +Nachfolgend eine Auflistung der möglichen Attribute für das Plugin im Format: Attribute: Beschreibung | Berechnungszyklus | Item-Type + + +db_addon_fct +------------ + +- verbrauch_heute: Verbrauch am heutigen Tag (Differenz zwischen aktuellem Wert und den Wert am Ende des vorherigen Tages) | Berechnung: daily | Item-Type: num + +- verbrauch_tag: Verbrauch am heutigen Tag (Differenz zwischen aktuellem Wert und den Wert am Ende des vorherigen Tages) | Berechnung: daily | Item-Type: num + +- verbrauch_woche: Verbrauch in der aktuellen Woche | Berechnung: weekly | Item-Type: num + +- verbrauch_monat: Verbrauch im aktuellen Monat | Berechnung: monthly | Item-Type: num + +- verbrauch_jahr: Verbrauch im aktuellen Jahr | Berechnung: yearly | Item-Type: num + +- verbrauch_last_24h: Verbrauch innerhalb letzten 24h | Berechnung: hourly | Item-Type: num + +- verbrauch_last_7d: Verbrauch innerhalb letzten 7 Tage | Berechnung: hourly | Item-Type: num + +- verbrauch_heute_minus1: Verbrauch gestern (heute -1 Tag) (Differenz zwischen Wert am Ende des gestrigen Tages und dem Wert am Ende des Tages davor) | Berechnung: daily | Item-Type: num + +- verbrauch_heute_minus2: Verbrauch vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num + +- verbrauch_heute_minus3: Verbrauch heute -3 Tage | Berechnung: daily | Item-Type: num + +- verbrauch_heute_minus4: Verbrauch heute -4 Tage | Berechnung: daily | Item-Type: num + +- verbrauch_heute_minus5: Verbrauch heute -5 Tage | Berechnung: daily | Item-Type: num + +- verbrauch_heute_minus6: Verbrauch heute -6 Tage | Berechnung: daily | Item-Type: num + +- verbrauch_heute_minus7: Verbrauch heute -7 Tage | Berechnung: daily | Item-Type: num + +- verbrauch_heute_minus8: Verbrauch heute -8 Tage | Berechnung: daily | Item-Type: num + +- verbrauch_tag_minus1: Verbrauch gestern (heute -1 Tag) (Differenz zwischen Wert am Ende des gestrigen Tages und dem Wert am Ende des Tages davor) | Berechnung: daily | Item-Type: num + +- verbrauch_tag_minus2: Verbrauch vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num + +- verbrauch_tag_minus3: Verbrauch heute -3 Tage | Berechnung: daily | Item-Type: num + +- verbrauch_tag_minus4: Verbrauch heute -4 Tage | Berechnung: daily | Item-Type: num + +- verbrauch_tag_minus5: Verbrauch heute -5 Tage | Berechnung: daily | Item-Type: num + +- verbrauch_tag_minus6: Verbrauch heute -6 Tage | Berechnung: daily | Item-Type: num + +- verbrauch_tag_minus7: Verbrauch heute -7 Tage | Berechnung: daily | Item-Type: num + +- verbrauch_tag_minus8: Verbrauch heute -8 Tage | Berechnung: daily | Item-Type: num + +- verbrauch_woche_minus1: Verbrauch Vorwoche (aktuelle Woche -1) | Berechnung: weekly | Item-Type: num + +- verbrauch_woche_minus2: Verbrauch aktuelle Woche -2 Wochen | Berechnung: weekly | Item-Type: num + +- verbrauch_woche_minus3: Verbrauch aktuelle Woche -3 Wochen | Berechnung: weekly | Item-Type: num + +- verbrauch_woche_minus4: Verbrauch aktuelle Woche -4 Wochen | Berechnung: weekly | Item-Type: num + +- verbrauch_monat_minus1: Verbrauch Vormonat (aktueller Monat -1) | Berechnung: monthly | Item-Type: num + +- verbrauch_monat_minus2: Verbrauch aktueller Monat -2 Monate | Berechnung: monthly | Item-Type: num + +- verbrauch_monat_minus3: Verbrauch aktueller Monat -3 Monate | Berechnung: monthly | Item-Type: num + +- verbrauch_monat_minus4: Verbrauch aktueller Monat -4 Monate | Berechnung: monthly | Item-Type: num + +- verbrauch_monat_minus12: Verbrauch aktueller Monat -12 Monate | Berechnung: monthly | Item-Type: num + +- verbrauch_jahr_minus1: Verbrauch Vorjahr (aktuelles Jahr -1 Jahr) | Berechnung: yearly | Item-Type: num + +- verbrauch_jahr_minus2: Verbrauch aktuelles Jahr -2 Jahre | Berechnung: yearly | Item-Type: num + +- verbrauch_jahr_minus3: Verbrauch aktuelles Jahr -3 Jahre | Berechnung: yearly | Item-Type: num + +- verbrauch_rolling_12m_heute_minus1: Verbrauch der letzten 12 Monate ausgehend im Ende des letzten Tages | Berechnung: daily | Item-Type: num + +- verbrauch_rolling_12m_tag_minus1: Verbrauch der letzten 12 Monate ausgehend im Ende des letzten Tages | Berechnung: daily | Item-Type: num + +- verbrauch_rolling_12m_woche_minus1: Verbrauch der letzten 12 Monate ausgehend im Ende der letzten Woche | Berechnung: weekly | Item-Type: num + +- verbrauch_rolling_12m_monat_minus1: Verbrauch der letzten 12 Monate ausgehend im Ende des letzten Monats | Berechnung: monthly | Item-Type: num + +- verbrauch_rolling_12m_jahr_minus1: Verbrauch der letzten 12 Monate ausgehend im Ende des letzten Jahres | Berechnung: yearly | Item-Type: num + +- verbrauch_jahreszeitraum_minus1: Verbrauch seit dem 1.1. bis zum heutigen Tag des Vorjahres | Berechnung: daily | Item-Type: num + +- verbrauch_jahreszeitraum_minus2: Verbrauch seit dem 1.1. bis zum heutigen Tag vor 2 Jahren | Berechnung: daily | Item-Type: num + +- verbrauch_jahreszeitraum_minus3: Verbrauch seit dem 1.1. bis zum heutigen Tag vor 3 Jahren | Berechnung: daily | Item-Type: num + +- zaehlerstand_heute_minus1: Zählerstand / Wert am Ende des letzten Tages (heute -1 Tag) | Berechnung: daily | Item-Type: num + +- zaehlerstand_heute_minus2: Zählerstand / Wert am Ende des vorletzten Tages (heute -2 Tag) | Berechnung: daily | Item-Type: num + +- zaehlerstand_heute_minus3: Zählerstand / Wert am Ende des vorvorletzten Tages (heute -3 Tag) | Berechnung: daily | Item-Type: num + +- zaehlerstand_tag_minus1: Zählerstand / Wert am Ende des letzten Tages (heute -1 Tag) | Berechnung: daily | Item-Type: num + +- zaehlerstand_tag_minus2: Zählerstand / Wert am Ende des vorletzten Tages (heute -2 Tag) | Berechnung: daily | Item-Type: num + +- zaehlerstand_tag_minus3: Zählerstand / Wert am Ende des vorvorletzten Tages (heute -3 Tag) | Berechnung: daily | Item-Type: num + +- zaehlerstand_woche_minus1: Zählerstand / Wert am Ende der vorvorletzten Woche (aktuelle Woche -1 Woche) | Berechnung: weekly | Item-Type: num + +- zaehlerstand_woche_minus2: Zählerstand / Wert am Ende der vorletzten Woche (aktuelle Woche -2 Wochen) | Berechnung: weekly | Item-Type: num + +- zaehlerstand_woche_minus3: Zählerstand / Wert am Ende der aktuellen Woche -3 Wochen | Berechnung: weekly | Item-Type: num + +- zaehlerstand_monat_minus1: Zählerstand / Wert am Ende des letzten Monates (aktueller Monat -1 Monat) | Berechnung: monthly | Item-Type: num + +- zaehlerstand_monat_minus2: Zählerstand / Wert am Ende des vorletzten Monates (aktueller Monat -2 Monate) | Berechnung: monthly | Item-Type: num + +- zaehlerstand_monat_minus3: Zählerstand / Wert am Ende des aktuellen Monats -3 Monate | Berechnung: monthly | Item-Type: num + +- zaehlerstand_jahr_minus1: Zählerstand / Wert am Ende des letzten Jahres (aktuelles Jahr -1 Jahr) | Berechnung: yearly | Item-Type: num + +- zaehlerstand_jahr_minus2: Zählerstand / Wert am Ende des vorletzten Jahres (aktuelles Jahr -2 Jahre) | Berechnung: yearly | Item-Type: num + +- zaehlerstand_jahr_minus3: Zählerstand / Wert am Ende des aktuellen Jahres -3 Jahre | Berechnung: yearly | Item-Type: num + +- minmax_last_24h_min: minimaler Wert der letzten 24h | Berechnung: daily | Item-Type: num + +- minmax_last_24h_max: maximaler Wert der letzten 24h | Berechnung: daily | Item-Type: num + +- minmax_last_24h_avg: durchschnittlicher Wert der letzten 24h | Berechnung: daily | Item-Type: num + +- minmax_last_7d_min: minimaler Wert der letzten 7 Tage | Berechnung: daily | Item-Type: num + +- minmax_last_7d_max: maximaler Wert der letzten 7 Tage | Berechnung: daily | Item-Type: num + +- minmax_last_7d_avg: durchschnittlicher Wert der letzten 7 Tage | Berechnung: daily | Item-Type: num + +- minmax_heute_min: Minimalwert seit Tagesbeginn | Berechnung: onchange | Item-Type: num + +- minmax_heute_max: Maximalwert seit Tagesbeginn | Berechnung: onchange | Item-Type: num + +- minmax_heute_avg: Durschnittswert seit Tagesbeginn | Berechnung: onchange | Item-Type: num + +- minmax_heute_minus1_min: Minimalwert gestern (heute -1 Tag) | Berechnung: daily | Item-Type: num + +- minmax_heute_minus1_max: Maximalwert gestern (heute -1 Tag) | Berechnung: daily | Item-Type: num + +- minmax_heute_minus1_avg: Durchschnittswert gestern (heute -1 Tag) | Berechnung: daily | Item-Type: num + +- minmax_heute_minus2_min: Minimalwert vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num + +- minmax_heute_minus2_max: Maximalwert vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num + +- minmax_heute_minus2_avg: Durchschnittswert vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num + +- minmax_heute_minus3_min: Minimalwert heute vor 3 Tagen | Berechnung: daily | Item-Type: num + +- minmax_heute_minus3_max: Maximalwert heute vor 3 Tagen | Berechnung: daily | Item-Type: num + +- minmax_heute_minus3_avg: Durchschnittswert heute vor 3 Tagen | Berechnung: daily | Item-Type: num + +- minmax_tag_min: Minimalwert seit Tagesbeginn | Berechnung: onchange | Item-Type: num + +- minmax_tag_max: Maximalwert seit Tagesbeginn | Berechnung: onchange | Item-Type: num + +- minmax_tag_avg: Durschnittswert seit Tagesbeginn | Berechnung: onchange | Item-Type: num + +- minmax_tag_minus1_min: Minimalwert gestern (heute -1 Tag) | Berechnung: daily | Item-Type: num + +- minmax_tag_minus1_max: Maximalwert gestern (heute -1 Tag) | Berechnung: daily | Item-Type: num + +- minmax_tag_minus1_avg: Durchschnittswert gestern (heute -1 Tag) | Berechnung: daily | Item-Type: num + +- minmax_tag_minus2_min: Minimalwert vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num + +- minmax_tag_minus2_max: Maximalwert vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num + +- minmax_tag_minus2_avg: Durchschnittswert vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num + +- minmax_tag_minus3_min: Minimalwert heute vor 3 Tagen | Berechnung: daily | Item-Type: num + +- minmax_tag_minus3_max: Maximalwert heute vor 3 Tagen | Berechnung: daily | Item-Type: num + +- minmax_tag_minus3_avg: Durchschnittswert heute vor 3 Tagen | Berechnung: daily | Item-Type: num + +- minmax_woche_min: Minimalwert seit Wochenbeginn | Berechnung: onchange | Item-Type: num + +- minmax_woche_max: Maximalwert seit Wochenbeginn | Berechnung: onchange | Item-Type: num + +- minmax_woche_minus1_min: Minimalwert Vorwoche (aktuelle Woche -1) | Berechnung: weekly | Item-Type: num + +- minmax_woche_minus1_max: Maximalwert Vorwoche (aktuelle Woche -1) | Berechnung: weekly | Item-Type: num + +- minmax_woche_minus1_avg: Durchschnittswert Vorwoche (aktuelle Woche -1) | Berechnung: weekly | Item-Type: num + +- minmax_woche_minus2_min: Minimalwert aktuelle Woche -2 Wochen | Berechnung: weekly | Item-Type: num + +- minmax_woche_minus2_max: Maximalwert aktuelle Woche -2 Wochen | Berechnung: weekly | Item-Type: num + +- minmax_woche_minus2_avg: Durchschnittswert aktuelle Woche -2 Wochen | Berechnung: weekly | Item-Type: num + +- minmax_monat_min: Minimalwert seit Monatsbeginn | Berechnung: onchange | Item-Type: num + +- minmax_monat_max: Maximalwert seit Monatsbeginn | Berechnung: onchange | Item-Type: num + +- minmax_monat_minus1_min: Minimalwert Vormonat (aktueller Monat -1) | Berechnung: monthly | Item-Type: num + +- minmax_monat_minus1_max: Maximalwert Vormonat (aktueller Monat -1) | Berechnung: monthly | Item-Type: num + +- minmax_monat_minus1_avg: Durchschnittswert Vormonat (aktueller Monat -1) | Berechnung: monthly | Item-Type: num + +- minmax_monat_minus2_min: Minimalwert aktueller Monat -2 Monate | Berechnung: monthly | Item-Type: num + +- minmax_monat_minus2_max: Maximalwert aktueller Monat -2 Monate | Berechnung: monthly | Item-Type: num + +- minmax_monat_minus2_avg: Durchschnittswert aktueller Monat -2 Monate | Berechnung: monthly | Item-Type: num + +- minmax_jahr_min: Minimalwert seit Jahresbeginn | Berechnung: onchange | Item-Type: num + +- minmax_jahr_max: Maximalwert seit Jahresbeginn | Berechnung: onchange | Item-Type: num + +- minmax_jahr_minus1_min: Minimalwert Vorjahr (aktuelles Jahr -1 Jahr) | Berechnung: yearly | Item-Type: num + +- minmax_jahr_minus1_max: Maximalwert Vorjahr (aktuelles Jahr -1 Jahr) | Berechnung: yearly | Item-Type: num + +- minmax_jahr_minus1_avg: Durchschnittswert Vorjahr (aktuelles Jahr -1 Jahr) | Berechnung: yearly | Item-Type: num + +- tagesmitteltemperatur_heute: Tagesmitteltemperatur heute | Berechnung: onchange | Item-Type: num + +- tagesmitteltemperatur_heute_minus1: Tagesmitteltemperatur des letzten Tages (heute -1 Tag) | Berechnung: daily | Item-Type: num + +- tagesmitteltemperatur_heute_minus2: Tagesmitteltemperatur des vorletzten Tages (heute -2 Tag) | Berechnung: daily | Item-Type: num + +- tagesmitteltemperatur_heute_minus3: Tagesmitteltemperatur des vorvorletzten Tages (heute -3 Tag) | Berechnung: daily | Item-Type: num + +- tagesmitteltemperatur_tag: Tagesmitteltemperatur heute | Berechnung: onchange | Item-Type: num + +- tagesmitteltemperatur_tag_minus1: Tagesmitteltemperatur des letzten Tages (heute -1 Tag) | Berechnung: daily | Item-Type: num + +- tagesmitteltemperatur_tag_minus2: Tagesmitteltemperatur des vorletzten Tages (heute -2 Tag) | Berechnung: daily | Item-Type: num + +- tagesmitteltemperatur_tag_minus3: Tagesmitteltemperatur des vorvorletzten Tages (heute -3 Tag) | Berechnung: daily | Item-Type: num + +- serie_minmax_monat_min_15m: monatlicher Minimalwert der letzten 15 Monate (gleitend) | Berechnung: monthly | Item-Type: list + +- serie_minmax_monat_max_15m: monatlicher Maximalwert der letzten 15 Monate (gleitend) | Berechnung: monthly | Item-Type: list + +- serie_minmax_monat_avg_15m: monatlicher Mittelwert der letzten 15 Monate (gleitend) | Berechnung: monthly | Item-Type: list + +- serie_minmax_woche_min_30w: wöchentlicher Minimalwert der letzten 30 Wochen (gleitend) | Berechnung: weekly | Item-Type: list + +- serie_minmax_woche_max_30w: wöchentlicher Maximalwert der letzten 30 Wochen (gleitend) | Berechnung: weekly | Item-Type: list + +- serie_minmax_woche_avg_30w: wöchentlicher Mittelwert der letzten 30 Wochen (gleitend) | Berechnung: weekly | Item-Type: list + +- serie_minmax_tag_min_30d: täglicher Minimalwert der letzten 30 Tage (gleitend) | Berechnung: daily | Item-Type: list + +- serie_minmax_tag_max_30d: täglicher Maximalwert der letzten 30 Tage (gleitend) | Berechnung: daily | Item-Type: list + +- serie_minmax_tag_avg_30d: täglicher Mittelwert der letzten 30 Tage (gleitend) | Berechnung: daily | Item-Type: list + +- serie_verbrauch_tag_30d: Verbrauch pro Tag der letzten 30 Tage | Berechnung: daily | Item-Type: list + +- serie_verbrauch_woche_30w: Verbrauch pro Woche der letzten 30 Wochen | Berechnung: weekly | Item-Type: list + +- serie_verbrauch_monat_18m: Verbrauch pro Monat der letzten 18 Monate | Berechnung: monthly | Item-Type: list + +- serie_zaehlerstand_tag_30d: Zählerstand am Tagesende der letzten 30 Tage | Berechnung: daily | Item-Type: list + +- serie_zaehlerstand_woche_30w: Zählerstand am Wochenende der letzten 30 Wochen | Berechnung: weekly | Item-Type: list + +- serie_zaehlerstand_monat_18m: Zählerstand am Monatsende der letzten 18 Monate | Berechnung: monthly | Item-Type: list + +- serie_waermesumme_monat_24m: monatliche Wärmesumme der letzten 24 Monate | Berechnung: monthly | Item-Type: list + +- serie_kaeltesumme_monat_24m: monatliche Kältesumme der letzten 24 Monate | Berechnung: monthly | Item-Type: list + +- serie_tagesmittelwert_0d: Tagesmittelwert für den aktuellen Tag | Berechnung: daily | Item-Type: list + +- serie_tagesmittelwert_stunde_0d: Stundenmittelwert für den aktuellen Tag | Berechnung: daily | Item-Type: list + +- serie_tagesmittelwert_stunde_30_0d: Stundenmittelwert für den aktuellen Tag | Berechnung: daily | Item-Type: list + +- serie_tagesmittelwert_tag_stunde_30d: Stundenmittelwert pro Tag der letzten 30 Tage (bspw. zur Berechnung der Tagesmitteltemperatur basierend auf den Mittelwert der Temperatur pro Stunde | Berechnung: daily | Item-Type: list + +- general_oldest_value: Ausgabe des ältesten Wertes des entsprechenden "Parent-Items" mit database Attribut | Berechnung: no | Item-Type: num + +- general_oldest_log: Ausgabe des Timestamp des ältesten Eintrages des entsprechenden "Parent-Items" mit database Attribut | Berechnung: no | Item-Type: list + +- kaeltesumme: Berechnet die Kältesumme für einen Zeitraum, db_addon_params: (year=optional, month=optional) | Berechnung: daily | Item-Type: num + +- waermesumme: Berechnet die Wärmesumme für einen Zeitraum, db_addon_params: (year=optional, month=optional) | Berechnung: daily | Item-Type: num + +- gruenlandtempsumme: Berechnet die Grünlandtemperatursumme für einen Zeitraum, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num + +- wachstumsgradtage: Berechnet die Wachstumsgradtage auf Basis der stündlichen Durchschnittswerte eines Tages für das laufende Jahr mit an Angabe des Temperaturschwellenwertes (threshold=Schwellentemperatur) | Berechnung: daily | Item-Type: num + +- wuestentage: Berechnet die Anzahl der Wüstentage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num + +- heisse_tage: Berechnet die Anzahl der heissen Tage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num + +- tropennaechte: Berechnet die Anzahl der Tropennächte des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num + +- sommertage: Berechnet die Anzahl der Sommertage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num + +- heiztage: Berechnet die Anzahl der Heiztage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num + +- vegetationstage: Berechnet die Anzahl der Vegatationstage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num + +- frosttage: Berechnet die Anzahl der Frosttage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num + +- eistage: Berechnet die Anzahl der Eistage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num + +- tagesmitteltemperatur: Berechnet die Tagesmitteltemperatur auf Basis der stündlichen Durchschnittswerte eines Tages für die angegebene Anzahl von Tagen (timeframe=day, count=integer) | Berechnung: daily | Item-Type: list + +- db_request: Abfrage der DB: db_addon_params: (func=mandatory, item=mandatory, timespan=mandatory, start=optional, end=optional, count=optional, group=optional, group2=optional) | Berechnung: group | Item-Type: list + +- minmax: Berechnet einen min/max/avg Wert für einen bestimmen Zeitraum: db_addon_params: (func=mandatory, timeframe=mandatory, start=mandatory) | Berechnung: timeframe | Item-Type: num + +- minmax_last: 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) | Berechnung: timeframe | Item-Type: num + +- verbrauch: Berechnet einen Verbrauchswert für einen bestimmen Zeitraum: db_addon_params: (timeframe=mandatory, start=mandatory end=mandatory) | Berechnung: timeframe | Item-Type: num + +- zaehlerstand: Berechnet einen Zählerstand für einen bestimmen Zeitpunkt: db_addon_params: (timeframe=mandatory, start=mandatory) | Berechnung: timeframe | Item-Type: num + + +db_addon_info +------------- + +- db_version: Version der verbundenen Datenbank | Berechnung: no | Item-Type: str + + +db_addon_admin +-------------- + +- suspend: Unterbricht die Aktivitäten des Plugin | Berechnung: no | Item-Type: bool + +- recalc_all: Startet einen Neuberechnungslauf aller on-demand Items | Berechnung: no | Item-Type: bool + +- clean_cache_values: Löscht Plugin-Cache und damit alle im Plugin zwischengespeicherten Werte | Berechnung: no | Item-Type: bool + + +Hinweise +======== + + - Das Plugin startet die Berechnungen der Werte nach einer gewissen (konfigurierbaren) Zeit (Attribut `startup_run_delay`) + nach dem Start von shNG, um den Startvorgang nicht zu beeinflussen. + + - Bei Start werden automatisch nur die Items berechnet, für das das Attribute `db_addon_startup` gesetzt wurde. Alle anderen + Items werden erst zur konfigurierten Zeit berechnet. Das Attribute `db_addon_startup` kann auch direkt am `Database-Item` + gesetzt werden. Dabei wird das Attribut auf alle darunter liegenden `db_addon-Items` (bspw. bei Verwendung von structs) vererbt. + Über das WebIF kann die Berechnung aller definierten Items ausgelöst werden. + + - Für sogenannte `on_change` Items, also Items, deren Berechnung bis zum Jetzt (bspw. verbrauch-heute) gehen, wird die Berechnung + immer bei eintreffen eines neuen Wertes gestartet. Zu Reduktion der Belastung auf die Datenbank werden die Werte für das Ende der + letzten Periode gecached. + + - Berechnungen werden nur ausgeführt, wenn für den kompletten abgefragten Zeitraum Werte in der Datenbank vorliegen. Wird bspw. + der Verbrauch des letzten Monats abgefragt wobei erst Werte ab dem 3. des Monats in der Datenbank sind, wird die Berechnung abgebrochen. + + - Mit dem Attribut `use_oldest_entry` kann dieses Verhalten verändert werden. Ist das Attribut gesetzt, wird, wenn für den + Beginn der Abfragezeitraums keinen Werte vorliegen, der älteste Eintrag der Datenbank genutzt. + + - Für die Auswertung kann es nützlich sein, bestimmte Werte aus der Datenbank bei der Berechnung auszublenden. Hierfür stehen + 2 Möglichkeiten zur Verfügung: + - Plugin-Attribut `ignore_0`: (list of strings) Bei Items, bei denen ein String aus der Liste im Pfadnamen vorkommt, + werden 0-Werte (val_num = 0) bei Datenbankauswertungen ignoriert. Hat also das Attribut den Wert ['temp'] werden bei allen Items mit + 'temp' im Pfadnamen die 0-Werte bei der Auswertung ignoriert. + - Item-Attribut `db_addon_ignore_value`: (num) Dieser Wert wird bei der Abfrage bzw. Auswertung der Datenbank für diese + Item ignoriert. + + - Das Plugin enthält sehr ausführliche Logginginformation. Bei unerwartetem Verhalten, den LogLevel entsprechend anpassen, + um mehr information zu erhalten. + + - Berechnungen des Plugins können im WebIF unterbrochen werden. Auch das gesamte Plugin kann pausiert werden. Dies kann bei + starker Systembelastung nützlich sein. + + +Beispiele +========= + +Verbrauch +--------- + +Soll bspw. der Verbrauch von Wasser ausgewertet werden, so ist dies wie folgt möglich: + + +.. code-block:: yaml + + wasserzaehler: + zaehlerstand: + type: num + knx_dpt: 12 + knx_cache: 5/3/4 + eval: round(value/1000, 1) + database: init + struct: + - db_addon.verbrauch_1 + - db_addon.verbrauch_2 + - db_addon.zaehlerstand_1 + +Die Werte des Wasserzählerstandes werden in die Datenbank geschrieben und darauf basierend ausgewertet. Die structs +'db_addon.verbrauch_1' und 'db_addon.verbrauch_2' stellen entsprechende Items für die Verbrauchsauswerten zur Verfügung. + +minmax +------ + +Soll bspw. die minimalen und maximalen Temperaturen ausgewertet werden, kann dies so umgesetzt werden: + +.. code-block:: yaml + + temperature: + aussen: + nord: + name: Außentemp Nordseite + type: num + visu_acl: ro + knx_dpt: 9 + knx_cache: 6/5/1 + database: init + struct: + - db_addon.minmax_1 + - db_addon.minmax_2 + +Die Temperaturwerte werden in die Datenbank geschrieben und darauf basierend ausgewertet. Die structs +'db_addon.minmax_1' und 'db_addon.minmax_2' stellen entsprechende Items für die min/max Auswertung zur Verfügung. + +| + +Web Interface +============= + +Das WebIF stellt neben der Ansicht verbundener Items und deren Parameter und Werte auch Funktionen für die +Administration des Plugins bereit. + +Es stehen Button für: + +- Neuberechnung aller Items +- Abbruch eines aktiven Berechnungslaufes +- Pausieren des Plugins +- Wiederaufnahme des Plugins + +bereit. + +Achtung: Das Auslösen einer kompletten Neuberechnung aller Items kann zu einer starken Belastung der Datenbank +aufgrund vieler Leseanfragen führen. + + +db_addon Items +-------------- + +Dieser Reiter des Webinterface zeigt die Items an, für die ein DatabaseAddon Attribut konfiguriert ist. + + +db_addon Maintenance +-------------------- + +Das Webinterface zeigt detaillierte Informationen über die im Plugin verfügbaren Daten an. +Dies dient der Maintenance bzw. Fehlersuche. Dieser Tab ist nur bei Log-Level "Debug" verfügbar. + + +Erläuterungen zu Temperatursummen +================================= + + +Grünlandtemperatursumme +----------------------- + +Beim Grünland wird die Wärmesumme nach Ernst und Loeper benutzt, um den Vegetationsbeginn und somit den Termin von Düngungsmaßnahmen zu bestimmen. +Dabei erfolgt die Aufsummierung der Tagesmitteltemperaturen über 0 °C, wobei der Januar mit 0.5 und der Februar mit 0.75 gewichtet wird. +Bei einer Wärmesumme von 200 Grad ist eine Düngung angesagt. + +siehe: https://de.wikipedia.org/wiki/Gr%C3%BCnlandtemperatursumme + +Folgende Parameter sind möglich / notwendig: + + +.. code-block:: yaml + + db_addon_params: "year=current" + +- year: Jahreszahl (str oder int), für das die Berechnung ausgeführt werden soll oder "current" für aktuelles Jahr (default: 'current') + + +Wachstumsgradtag +---------------- +Der Begriff Wachstumsgradtage (WGT) ist ein Überbegriff für verschiedene Größen. +Gemeinsam ist ihnen, daß zur Berechnung eine Lufttemperatur von einem Schwellenwert subtrahiert wird. +Je nach Fragestellung und Pflanzenart werden der Schwellenwert unterschiedlich gewählt und die Temperatur unterschiedlich bestimmt. +Verfügbar sind die Berechnung über 0) "einfachen Durchschnitt der Tagestemperaturen", 1) "modifizierten Durchschnitt der Tagestemperaturen" +und 2) Anzahl der Tage, deren Mitteltempertatur oberhalb der Schwellentemperatur lag. + +siehe https://de.wikipedia.org/wiki/Wachstumsgradtag + +Folgende Parameter sind möglich / notwendig: + +.. code-block:: yaml + + db_addon_params: "year=current, method=1, threshold=10" + +- year: Jahreszahl (str oder int), für das die Berechnung ausgeführt werden soll oder "current" für aktuelles Jahr (default: 'current') +- method: 0-Berechnung über "einfachen Durchschnitt der Tagestemperaturen", 1-Berechnung über "modifizierten Durchschnitt (default: 0) +der Tagestemperaturen" 2-Anzahl der Tage, mit Mitteltempertatur oberhalb Schwellentemperatur// 10, 11 Ausgabe aus Zeitserie +- threshold: Schwellentemperatur in °C (int) (default: 10) + + +Wärmesumme +---------- + +Die Wärmesumme soll eine Aussage über den Sommer und die Pflanzenreife liefern. Es gibt keine eindeutige Definition der Größe "Wärmesumme". +Berechnet wird die Wärmesumme als Summe aller Tagesmitteltemperaturen über einem Schwellenwert ab dem 1.1. des Jahres. + +siehe https://de.wikipedia.org/wiki/W%C3%A4rmesumme + +Folgende Parameter sind möglich / notwendig: + +.. code-block:: yaml + + db_addon_params: "year=current, month=1, threshold=10" + +- year: Jahreszahl (str oder int), für das die Berechnung ausgeführt werden soll oder "current" für aktuelles Jahr (default: 'current') +- month: Monat (int) des Jahres, für das die Berechnung ausgeführt werden soll (optional) (default: None) +- threshold: Schwellentemperatur in °C (int) (default: 10) + + +Kältesumme +---------- + +Die Kältesumme soll eine Aussage über die Härte des Winters liefern. +Berechnet wird die Kältesumme als Summe aller negativen Tagesmitteltemperaturen ab dem 21.9. des Jahres bis 31.3. des Folgejahres. + +siehe https://de.wikipedia.org/wiki/K%C3%A4ltesumme + +Folgende Parameter sind möglich / notwendig: + +.. code-block:: yaml + + db_addon_params: "year=current, month=1" + +- year: Jahreszahl (str oder int), für das die Berechnung ausgeführt werden soll oder "current" für aktuelles Jahr (default: 'current') +- month: Monat (int) des Jahres, für das die Berechnung ausgeführt werden soll (optional) (default: None) + + +Tagesmitteltemperatur +--------------------- + +Die Tagesmitteltemperatur wird auf Basis der stündlichen Durchschnittswerte eines Tages (aller in der DB enthaltenen Datensätze) +für die angegebene Anzahl von Tagen (days=optional) berechnet. + + + +Vorgehen bei Funktionserweiterung des Plugins bzw. Ergänzung weiterer Werte für Item-Attribute +---------------------------------------------------------------------------------------------- + +Aufgrund der Vielzahl der möglichen Werte der Itemattribute, insbesondere des Itemattributes `db_addon_fct`, wurde die Erstellung/Update +der entsprechenden Teile der `plugin.yam` sowie die Erstellung der Datei `item_attributes.py`, die vom Plugin verwendet wird, automatisiert. + +Die Masterinformationen für alle Itemattribute sowie die Skripte zum Erstellen/Update der beiden Dateien sind in der +Datei `item_attributes_master.py` enthalten. + +.. important:: + + Korrekturen, Erweiterungen etc. der Itemattribute sollten nur in der Datei `item_attributes_master.py` + im Dict der Variable `ITEM_ATTRIBUTS` vorgenommen werden. Das Ausführen der Datei `item_attributes_master.py` (main) + erstellt die `item_attributes.py` und aktualisiert die `plugin.yaml` entsprechend. +Dieses Kapitel wurde automatisch durch Ausführen des Skripts in der Datei 'item_attributes_master.py' erstellt. + +Nachfolgend eine Auflistung der möglichen Attribute für das Plugin im Format: Attribute: Beschreibung | Berechnungszyklus | Item-Type + + +db_addon_fct +------------ + +- verbrauch_heute: Verbrauch am heutigen Tag (Differenz zwischen aktuellem Wert und den Wert am Ende des vorherigen Tages) | Berechnung: daily | Item-Type: num + +- verbrauch_tag: Verbrauch am heutigen Tag (Differenz zwischen aktuellem Wert und den Wert am Ende des vorherigen Tages) | Berechnung: daily | Item-Type: num + +- verbrauch_woche: Verbrauch in der aktuellen Woche | Berechnung: weekly | Item-Type: num + +- verbrauch_monat: Verbrauch im aktuellen Monat | Berechnung: monthly | Item-Type: num + +- verbrauch_jahr: Verbrauch im aktuellen Jahr | Berechnung: yearly | Item-Type: num + +- verbrauch_last_24h: Verbrauch innerhalb letzten 24h | Berechnung: hourly | Item-Type: num + +- verbrauch_last_7d: Verbrauch innerhalb letzten 7 Tage | Berechnung: hourly | Item-Type: num + +- verbrauch_heute_minus1: Verbrauch gestern (heute -1 Tag) (Differenz zwischen Wert am Ende des gestrigen Tages und dem Wert am Ende des Tages davor) | Berechnung: daily | Item-Type: num + +- verbrauch_heute_minus2: Verbrauch vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num + +- verbrauch_heute_minus3: Verbrauch heute -3 Tage | Berechnung: daily | Item-Type: num + +- verbrauch_heute_minus4: Verbrauch heute -4 Tage | Berechnung: daily | Item-Type: num + +- verbrauch_heute_minus5: Verbrauch heute -5 Tage | Berechnung: daily | Item-Type: num + +- verbrauch_heute_minus6: Verbrauch heute -6 Tage | Berechnung: daily | Item-Type: num + +- verbrauch_heute_minus7: Verbrauch heute -7 Tage | Berechnung: daily | Item-Type: num + +- verbrauch_heute_minus8: Verbrauch heute -8 Tage | Berechnung: daily | Item-Type: num + +- verbrauch_tag_minus1: Verbrauch gestern (heute -1 Tag) (Differenz zwischen Wert am Ende des gestrigen Tages und dem Wert am Ende des Tages davor) | Berechnung: daily | Item-Type: num + +- verbrauch_tag_minus2: Verbrauch vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num + +- verbrauch_tag_minus3: Verbrauch heute -3 Tage | Berechnung: daily | Item-Type: num + +- verbrauch_tag_minus4: Verbrauch heute -4 Tage | Berechnung: daily | Item-Type: num + +- verbrauch_tag_minus5: Verbrauch heute -5 Tage | Berechnung: daily | Item-Type: num + +- verbrauch_tag_minus6: Verbrauch heute -6 Tage | Berechnung: daily | Item-Type: num + +- verbrauch_tag_minus7: Verbrauch heute -7 Tage | Berechnung: daily | Item-Type: num + +- verbrauch_tag_minus8: Verbrauch heute -8 Tage | Berechnung: daily | Item-Type: num + +- verbrauch_woche_minus1: Verbrauch Vorwoche (aktuelle Woche -1) | Berechnung: weekly | Item-Type: num + +- verbrauch_woche_minus2: Verbrauch aktuelle Woche -2 Wochen | Berechnung: weekly | Item-Type: num + +- verbrauch_woche_minus3: Verbrauch aktuelle Woche -3 Wochen | Berechnung: weekly | Item-Type: num + +- verbrauch_woche_minus4: Verbrauch aktuelle Woche -4 Wochen | Berechnung: weekly | Item-Type: num + +- verbrauch_monat_minus1: Verbrauch Vormonat (aktueller Monat -1) | Berechnung: monthly | Item-Type: num + +- verbrauch_monat_minus2: Verbrauch aktueller Monat -2 Monate | Berechnung: monthly | Item-Type: num + +- verbrauch_monat_minus3: Verbrauch aktueller Monat -3 Monate | Berechnung: monthly | Item-Type: num + +- verbrauch_monat_minus4: Verbrauch aktueller Monat -4 Monate | Berechnung: monthly | Item-Type: num + +- verbrauch_monat_minus12: Verbrauch aktueller Monat -12 Monate | Berechnung: monthly | Item-Type: num + +- verbrauch_jahr_minus1: Verbrauch Vorjahr (aktuelles Jahr -1 Jahr) | Berechnung: yearly | Item-Type: num + +- verbrauch_jahr_minus2: Verbrauch aktuelles Jahr -2 Jahre | Berechnung: yearly | Item-Type: num + +- verbrauch_jahr_minus3: Verbrauch aktuelles Jahr -3 Jahre | Berechnung: yearly | Item-Type: num + +- verbrauch_rolling_12m_heute_minus1: Verbrauch der letzten 12 Monate ausgehend im Ende des letzten Tages | Berechnung: daily | Item-Type: num + +- verbrauch_rolling_12m_tag_minus1: Verbrauch der letzten 12 Monate ausgehend im Ende des letzten Tages | Berechnung: daily | Item-Type: num + +- verbrauch_rolling_12m_woche_minus1: Verbrauch der letzten 12 Monate ausgehend im Ende der letzten Woche | Berechnung: weekly | Item-Type: num + +- verbrauch_rolling_12m_monat_minus1: Verbrauch der letzten 12 Monate ausgehend im Ende des letzten Monats | Berechnung: monthly | Item-Type: num + +- verbrauch_rolling_12m_jahr_minus1: Verbrauch der letzten 12 Monate ausgehend im Ende des letzten Jahres | Berechnung: yearly | Item-Type: num + +- verbrauch_jahreszeitraum_minus1: Verbrauch seit dem 1.1. bis zum heutigen Tag des Vorjahres | Berechnung: daily | Item-Type: num + +- verbrauch_jahreszeitraum_minus2: Verbrauch seit dem 1.1. bis zum heutigen Tag vor 2 Jahren | Berechnung: daily | Item-Type: num + +- verbrauch_jahreszeitraum_minus3: Verbrauch seit dem 1.1. bis zum heutigen Tag vor 3 Jahren | Berechnung: daily | Item-Type: num + +- zaehlerstand_heute_minus1: Zählerstand / Wert am Ende des letzten Tages (heute -1 Tag) | Berechnung: daily | Item-Type: num + +- zaehlerstand_heute_minus2: Zählerstand / Wert am Ende des vorletzten Tages (heute -2 Tag) | Berechnung: daily | Item-Type: num + +- zaehlerstand_heute_minus3: Zählerstand / Wert am Ende des vorvorletzten Tages (heute -3 Tag) | Berechnung: daily | Item-Type: num + +- zaehlerstand_tag_minus1: Zählerstand / Wert am Ende des letzten Tages (heute -1 Tag) | Berechnung: daily | Item-Type: num + +- zaehlerstand_tag_minus2: Zählerstand / Wert am Ende des vorletzten Tages (heute -2 Tag) | Berechnung: daily | Item-Type: num + +- zaehlerstand_tag_minus3: Zählerstand / Wert am Ende des vorvorletzten Tages (heute -3 Tag) | Berechnung: daily | Item-Type: num + +- zaehlerstand_woche_minus1: Zählerstand / Wert am Ende der vorvorletzten Woche (aktuelle Woche -1 Woche) | Berechnung: weekly | Item-Type: num + +- zaehlerstand_woche_minus2: Zählerstand / Wert am Ende der vorletzten Woche (aktuelle Woche -2 Wochen) | Berechnung: weekly | Item-Type: num + +- zaehlerstand_woche_minus3: Zählerstand / Wert am Ende der aktuellen Woche -3 Wochen | Berechnung: weekly | Item-Type: num + +- zaehlerstand_monat_minus1: Zählerstand / Wert am Ende des letzten Monates (aktueller Monat -1 Monat) | Berechnung: monthly | Item-Type: num + +- zaehlerstand_monat_minus2: Zählerstand / Wert am Ende des vorletzten Monates (aktueller Monat -2 Monate) | Berechnung: monthly | Item-Type: num + +- zaehlerstand_monat_minus3: Zählerstand / Wert am Ende des aktuellen Monats -3 Monate | Berechnung: monthly | Item-Type: num + +- zaehlerstand_jahr_minus1: Zählerstand / Wert am Ende des letzten Jahres (aktuelles Jahr -1 Jahr) | Berechnung: yearly | Item-Type: num + +- zaehlerstand_jahr_minus2: Zählerstand / Wert am Ende des vorletzten Jahres (aktuelles Jahr -2 Jahre) | Berechnung: yearly | Item-Type: num + +- zaehlerstand_jahr_minus3: Zählerstand / Wert am Ende des aktuellen Jahres -3 Jahre | Berechnung: yearly | Item-Type: num + +- minmax_last_24h_min: minimaler Wert der letzten 24h | Berechnung: daily | Item-Type: num + +- minmax_last_24h_max: maximaler Wert der letzten 24h | Berechnung: daily | Item-Type: num + +- minmax_last_24h_avg: durchschnittlicher Wert der letzten 24h | Berechnung: daily | Item-Type: num + +- minmax_last_7d_min: minimaler Wert der letzten 7 Tage | Berechnung: daily | Item-Type: num + +- minmax_last_7d_max: maximaler Wert der letzten 7 Tage | Berechnung: daily | Item-Type: num + +- minmax_last_7d_avg: durchschnittlicher Wert der letzten 7 Tage | Berechnung: daily | Item-Type: num + +- minmax_heute_min: Minimalwert seit Tagesbeginn | Berechnung: daily | Item-Type: num + +- minmax_heute_max: Maximalwert seit Tagesbeginn | Berechnung: daily | Item-Type: num + +- minmax_heute_avg: Durschnittswert seit Tagesbeginn | Berechnung: daily | Item-Type: num + +- minmax_heute_minus1_min: Minimalwert gestern (heute -1 Tag) | Berechnung: daily | Item-Type: num + +- minmax_heute_minus1_max: Maximalwert gestern (heute -1 Tag) | Berechnung: daily | Item-Type: num + +- minmax_heute_minus1_avg: Durchschnittswert gestern (heute -1 Tag) | Berechnung: daily | Item-Type: num + +- minmax_heute_minus2_min: Minimalwert vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num + +- minmax_heute_minus2_max: Maximalwert vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num + +- minmax_heute_minus2_avg: Durchschnittswert vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num + +- minmax_heute_minus3_min: Minimalwert heute vor 3 Tagen | Berechnung: daily | Item-Type: num + +- minmax_heute_minus3_max: Maximalwert heute vor 3 Tagen | Berechnung: daily | Item-Type: num + +- minmax_heute_minus3_avg: Durchschnittswert heute vor 3 Tagen | Berechnung: daily | Item-Type: num + +- minmax_tag_min: Minimalwert seit Tagesbeginn | Berechnung: daily | Item-Type: num + +- minmax_tag_max: Maximalwert seit Tagesbeginn | Berechnung: daily | Item-Type: num + +- minmax_tag_avg: Durschnittswert seit Tagesbeginn | Berechnung: daily | Item-Type: num + +- minmax_tag_minus1_min: Minimalwert gestern (heute -1 Tag) | Berechnung: daily | Item-Type: num + +- minmax_tag_minus1_max: Maximalwert gestern (heute -1 Tag) | Berechnung: daily | Item-Type: num + +- minmax_tag_minus1_avg: Durchschnittswert gestern (heute -1 Tag) | Berechnung: daily | Item-Type: num + +- minmax_tag_minus2_min: Minimalwert vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num + +- minmax_tag_minus2_max: Maximalwert vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num + +- minmax_tag_minus2_avg: Durchschnittswert vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num + +- minmax_tag_minus3_min: Minimalwert heute vor 3 Tagen | Berechnung: daily | Item-Type: num + +- minmax_tag_minus3_max: Maximalwert heute vor 3 Tagen | Berechnung: daily | Item-Type: num + +- minmax_tag_minus3_avg: Durchschnittswert heute vor 3 Tagen | Berechnung: daily | Item-Type: num + +- minmax_woche_min: Minimalwert seit Wochenbeginn | Berechnung: weekly | Item-Type: num + +- minmax_woche_max: Maximalwert seit Wochenbeginn | Berechnung: weekly | Item-Type: num + +- minmax_woche_minus1_min: Minimalwert Vorwoche (aktuelle Woche -1) | Berechnung: weekly | Item-Type: num + +- minmax_woche_minus1_max: Maximalwert Vorwoche (aktuelle Woche -1) | Berechnung: weekly | Item-Type: num + +- minmax_woche_minus1_avg: Durchschnittswert Vorwoche (aktuelle Woche -1) | Berechnung: weekly | Item-Type: num + +- minmax_woche_minus2_min: Minimalwert aktuelle Woche -2 Wochen | Berechnung: weekly | Item-Type: num + +- minmax_woche_minus2_max: Maximalwert aktuelle Woche -2 Wochen | Berechnung: weekly | Item-Type: num + +- minmax_woche_minus2_avg: Durchschnittswert aktuelle Woche -2 Wochen | Berechnung: weekly | Item-Type: num + +- minmax_monat_min: Minimalwert seit Monatsbeginn | Berechnung: monthly | Item-Type: num + +- minmax_monat_max: Maximalwert seit Monatsbeginn | Berechnung: monthly | Item-Type: num + +- minmax_monat_minus1_min: Minimalwert Vormonat (aktueller Monat -1) | Berechnung: monthly | Item-Type: num + +- minmax_monat_minus1_max: Maximalwert Vormonat (aktueller Monat -1) | Berechnung: monthly | Item-Type: num + +- minmax_monat_minus1_avg: Durchschnittswert Vormonat (aktueller Monat -1) | Berechnung: monthly | Item-Type: num + +- minmax_monat_minus2_min: Minimalwert aktueller Monat -2 Monate | Berechnung: monthly | Item-Type: num + +- minmax_monat_minus2_max: Maximalwert aktueller Monat -2 Monate | Berechnung: monthly | Item-Type: num + +- minmax_monat_minus2_avg: Durchschnittswert aktueller Monat -2 Monate | Berechnung: monthly | Item-Type: num + +- minmax_jahr_min: Minimalwert seit Jahresbeginn | Berechnung: yearly | Item-Type: num + +- minmax_jahr_max: Maximalwert seit Jahresbeginn | Berechnung: yearly | Item-Type: num + +- minmax_jahr_minus1_min: Minimalwert Vorjahr (aktuelles Jahr -1 Jahr) | Berechnung: yearly | Item-Type: num + +- minmax_jahr_minus1_max: Maximalwert Vorjahr (aktuelles Jahr -1 Jahr) | Berechnung: yearly | Item-Type: num + +- minmax_jahr_minus1_avg: Durchschnittswert Vorjahr (aktuelles Jahr -1 Jahr) | Berechnung: yearly | Item-Type: num + +- tagesmitteltemperatur_heute: Tagesmitteltemperatur heute | Berechnung: daily | Item-Type: num + +- tagesmitteltemperatur_heute_minus1: Tagesmitteltemperatur des letzten Tages (heute -1 Tag) | Berechnung: daily | Item-Type: num + +- tagesmitteltemperatur_heute_minus2: Tagesmitteltemperatur des vorletzten Tages (heute -2 Tag) | Berechnung: daily | Item-Type: num + +- tagesmitteltemperatur_heute_minus3: Tagesmitteltemperatur des vorvorletzten Tages (heute -3 Tag) | Berechnung: daily | Item-Type: num + +- tagesmitteltemperatur_tag: Tagesmitteltemperatur heute | Berechnung: daily | Item-Type: num + +- tagesmitteltemperatur_tag_minus1: Tagesmitteltemperatur des letzten Tages (heute -1 Tag) | Berechnung: daily | Item-Type: num + +- tagesmitteltemperatur_tag_minus2: Tagesmitteltemperatur des vorletzten Tages (heute -2 Tag) | Berechnung: daily | Item-Type: num + +- tagesmitteltemperatur_tag_minus3: Tagesmitteltemperatur des vorvorletzten Tages (heute -3 Tag) | Berechnung: daily | Item-Type: num + +- serie_minmax_monat_min_15m: monatlicher Minimalwert der letzten 15 Monate (gleitend) | Berechnung: monthly | Item-Type: list + +- serie_minmax_monat_max_15m: monatlicher Maximalwert der letzten 15 Monate (gleitend) | Berechnung: monthly | Item-Type: list + +- serie_minmax_monat_avg_15m: monatlicher Mittelwert der letzten 15 Monate (gleitend) | Berechnung: monthly | Item-Type: list + +- serie_minmax_woche_min_30w: wöchentlicher Minimalwert der letzten 30 Wochen (gleitend) | Berechnung: weekly | Item-Type: list + +- serie_minmax_woche_max_30w: wöchentlicher Maximalwert der letzten 30 Wochen (gleitend) | Berechnung: weekly | Item-Type: list + +- serie_minmax_woche_avg_30w: wöchentlicher Mittelwert der letzten 30 Wochen (gleitend) | Berechnung: weekly | Item-Type: list + +- serie_minmax_tag_min_30d: täglicher Minimalwert der letzten 30 Tage (gleitend) | Berechnung: daily | Item-Type: list + +- serie_minmax_tag_max_30d: täglicher Maximalwert der letzten 30 Tage (gleitend) | Berechnung: daily | Item-Type: list + +- serie_minmax_tag_avg_30d: täglicher Mittelwert der letzten 30 Tage (gleitend) | Berechnung: daily | Item-Type: list + +- serie_verbrauch_tag_30d: Verbrauch pro Tag der letzten 30 Tage | Berechnung: daily | Item-Type: list + +- serie_verbrauch_woche_30w: Verbrauch pro Woche der letzten 30 Wochen | Berechnung: weekly | Item-Type: list + +- serie_verbrauch_monat_18m: Verbrauch pro Monat der letzten 18 Monate | Berechnung: monthly | Item-Type: list + +- serie_zaehlerstand_tag_30d: Zählerstand am Tagesende der letzten 30 Tage | Berechnung: daily | Item-Type: list + +- serie_zaehlerstand_woche_30w: Zählerstand am Wochenende der letzten 30 Wochen | Berechnung: weekly | Item-Type: list + +- serie_zaehlerstand_monat_18m: Zählerstand am Monatsende der letzten 18 Monate | Berechnung: monthly | Item-Type: list + +- serie_waermesumme_monat_24m: monatliche Wärmesumme der letzten 24 Monate | Berechnung: monthly | Item-Type: list + +- serie_kaeltesumme_monat_24m: monatliche Kältesumme der letzten 24 Monate | Berechnung: monthly | Item-Type: list + +- serie_tagesmittelwert_0d: Tagesmittelwert für den aktuellen Tag | Berechnung: daily | Item-Type: list + +- serie_tagesmittelwert_stunde_0d: Stundenmittelwert für den aktuellen Tag | Berechnung: daily | Item-Type: list + +- serie_tagesmittelwert_stunde_30_0d: Stundenmittelwert für den aktuellen Tag | Berechnung: daily | Item-Type: list + +- serie_tagesmittelwert_tag_stunde_30d: Stundenmittelwert pro Tag der letzten 30 Tage (bspw. zur Berechnung der Tagesmitteltemperatur basierend auf den Mittelwert der Temperatur pro Stunde | Berechnung: daily | Item-Type: list + +- general_oldest_value: Ausgabe des ältesten Wertes des entsprechenden "Parent-Items" mit database Attribut | Berechnung: no | Item-Type: num + +- general_oldest_log: Ausgabe des Timestamp des ältesten Eintrages des entsprechenden "Parent-Items" mit database Attribut | Berechnung: no | Item-Type: list + +- kaeltesumme: Berechnet die Kältesumme für einen Zeitraum, db_addon_params: (year=optional, month=optional) | Berechnung: daily | Item-Type: num + +- waermesumme: Berechnet die Wärmesumme für einen Zeitraum, db_addon_params: (year=optional, month=optional) | Berechnung: daily | Item-Type: num + +- gruenlandtempsumme: Berechnet die Grünlandtemperatursumme für einen Zeitraum, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num + +- wachstumsgradtage: Berechnet die Wachstumsgradtage auf Basis der stündlichen Durchschnittswerte eines Tages für das laufende Jahr mit an Angabe des Temperaturschwellenwertes (threshold=Schwellentemperatur) | Berechnung: daily | Item-Type: num + +- wuestentage: Berechnet die Anzahl der Wüstentage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num + +- heisse_tage: Berechnet die Anzahl der heissen Tage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num + +- tropennaechte: Berechnet die Anzahl der Tropennächte des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num + +- sommertage: Berechnet die Anzahl der Sommertage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num + +- heiztage: Berechnet die Anzahl der Heiztage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num + +- vegetationstage: Berechnet die Anzahl der Vegatationstage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num + +- frosttage: Berechnet die Anzahl der Frosttage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num + +- eistage: Berechnet die Anzahl der Eistage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num + +- tagesmitteltemperatur: Berechnet die Tagesmitteltemperatur auf Basis der stündlichen Durchschnittswerte eines Tages für die angegebene Anzahl von Tagen (timeframe=day, count=integer) | Berechnung: daily | Item-Type: list + +- db_request: Abfrage der DB: db_addon_params: (func=mandatory, item=mandatory, timespan=mandatory, start=optional, end=optional, count=optional, group=optional, group2=optional) | Berechnung: group | Item-Type: list + +- minmax: Berechnet einen min/max/avg Wert für einen bestimmen Zeitraum: db_addon_params: (func=mandatory, timeframe=mandatory, start=mandatory) | Berechnung: timeframe | Item-Type: num + +- minmax_last: 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) | Berechnung: timeframe | Item-Type: num + +- verbrauch: Berechnet einen Verbrauchswert für einen bestimmen Zeitraum: db_addon_params: (timeframe=mandatory, start=mandatory end=mandatory) | Berechnung: timeframe | Item-Type: num + +- zaehlerstand: Berechnet einen Zählerstand für einen bestimmen Zeitpunkt: db_addon_params: (timeframe=mandatory, start=mandatory) | Berechnung: timeframe | Item-Type: num + + +db_addon_info +------------- + +- db_version: Version der verbundenen Datenbank | Berechnung: no | Item-Type: str + + +db_addon_admin +-------------- + +- suspend: Unterbricht die Aktivitäten des Plugin | Berechnung: no | Item-Type: bool + +- recalc_all: Startet einen Neuberechnungslauf aller on-demand Items | Berechnung: no | Item-Type: bool + +- clean_cache_values: Löscht Plugin-Cache und damit alle im Plugin zwischengespeicherten Werte | Berechnung: no | Item-Type: bool + + +Hinweise +======== + + - Das Plugin startet die Berechnungen der Werte nach einer gewissen (konfigurierbaren) Zeit (Attribut `startup_run_delay`) + nach dem Start von shNG, um den Startvorgang nicht zu beeinflussen. + + - Bei Start werden automatisch nur die Items berechnet, für das das Attribute `db_addon_startup` gesetzt wurde. Alle anderen + Items werden erst zur konfigurierten Zeit berechnet. Das Attribute `db_addon_startup` kann auch direkt am `Database-Item` + gesetzt werden. Dabei wird das Attribut auf alle darunter liegenden `db_addon-Items` (bspw. bei Verwendung von structs) vererbt. + Über das WebIF kann die Berechnung aller definierten Items ausgelöst werden. + + - Für sogenannte `on_change` Items, also Items, deren Berechnung bis zum Jetzt (bspw. verbrauch-heute) gehen, wird die Berechnung + immer bei eintreffen eines neuen Wertes gestartet. Zu Reduktion der Belastung auf die Datenbank werden die Werte für das Ende der + letzten Periode gecached. + + - Berechnungen werden nur ausgeführt, wenn für den kompletten abgefragten Zeitraum Werte in der Datenbank vorliegen. Wird bspw. + der Verbrauch des letzten Monats abgefragt wobei erst Werte ab dem 3. des Monats in der Datenbank sind, wird die Berechnung abgebrochen. + + - Mit dem Attribut `use_oldest_entry` kann dieses Verhalten verändert werden. Ist das Attribut gesetzt, wird, wenn für den + Beginn der Abfragezeitraums keinen Werte vorliegen, der älteste Eintrag der Datenbank genutzt. + + - Für die Auswertung kann es nützlich sein, bestimmte Werte aus der Datenbank bei der Berechnung auszublenden. Hierfür stehen + 2 Möglichkeiten zur Verfügung: + - Plugin-Attribut `ignore_0`: (list of strings) Bei Items, bei denen ein String aus der Liste im Pfadnamen vorkommt, + werden 0-Werte (val_num = 0) bei Datenbankauswertungen ignoriert. Hat also das Attribut den Wert ['temp'] werden bei allen Items mit + 'temp' im Pfadnamen die 0-Werte bei der Auswertung ignoriert. + - Item-Attribut `db_addon_ignore_value`: (num) Dieser Wert wird bei der Abfrage bzw. Auswertung der Datenbank für diese + Item ignoriert. + + - Das Plugin enthält sehr ausführliche Logginginformation. Bei unerwartetem Verhalten, den LogLevel entsprechend anpassen, + um mehr information zu erhalten. + + - Berechnungen des Plugins können im WebIF unterbrochen werden. Auch das gesamte Plugin kann pausiert werden. Dies kann bei + starker Systembelastung nützlich sein. + + +Beispiele +========= + +Verbrauch +--------- + +Soll bspw. der Verbrauch von Wasser ausgewertet werden, so ist dies wie folgt möglich: + + +.. code-block:: yaml + + wasserzaehler: + zaehlerstand: + type: num + knx_dpt: 12 + knx_cache: 5/3/4 + eval: round(value/1000, 1) + database: init + struct: + - db_addon.verbrauch_1 + - db_addon.verbrauch_2 + - db_addon.zaehlerstand_1 + +Die Werte des Wasserzählerstandes werden in die Datenbank geschrieben und darauf basierend ausgewertet. Die structs +'db_addon.verbrauch_1' und 'db_addon.verbrauch_2' stellen entsprechende Items für die Verbrauchsauswerten zur Verfügung. + +minmax +------ + +Soll bspw. die minimalen und maximalen Temperaturen ausgewertet werden, kann dies so umgesetzt werden: + +.. code-block:: yaml + + temperature: + aussen: + nord: + name: Außentemp Nordseite + type: num + visu_acl: ro + knx_dpt: 9 + knx_cache: 6/5/1 + database: init + struct: + - db_addon.minmax_1 + - db_addon.minmax_2 + +Die Temperaturwerte werden in die Datenbank geschrieben und darauf basierend ausgewertet. Die structs +'db_addon.minmax_1' und 'db_addon.minmax_2' stellen entsprechende Items für die min/max Auswertung zur Verfügung. + +| + +Web Interface +============= + +Das WebIF stellt neben der Ansicht verbundener Items und deren Parameter und Werte auch Funktionen für die +Administration des Plugins bereit. + +Es stehen Button für: + +- Neuberechnung aller Items +- Abbruch eines aktiven Berechnungslaufes +- Pausieren des Plugins +- Wiederaufnahme des Plugins + +bereit. + +Achtung: Das Auslösen einer kompletten Neuberechnung aller Items kann zu einer starken Belastung der Datenbank +aufgrund vieler Leseanfragen führen. + + +db_addon Items +-------------- + +Dieser Reiter des Webinterface zeigt die Items an, für die ein DatabaseAddon Attribut konfiguriert ist. + + +db_addon Maintenance +-------------------- + +Das Webinterface zeigt detaillierte Informationen über die im Plugin verfügbaren Daten an. +Dies dient der Maintenance bzw. Fehlersuche. Dieser Tab ist nur bei Log-Level "Debug" verfügbar. + + +Erläuterungen zu Temperatursummen +================================= + + +Grünlandtemperatursumme +----------------------- + +Beim Grünland wird die Wärmesumme nach Ernst und Loeper benutzt, um den Vegetationsbeginn und somit den Termin von Düngungsmaßnahmen zu bestimmen. +Dabei erfolgt die Aufsummierung der Tagesmitteltemperaturen über 0 °C, wobei der Januar mit 0.5 und der Februar mit 0.75 gewichtet wird. +Bei einer Wärmesumme von 200 Grad ist eine Düngung angesagt. + +siehe: https://de.wikipedia.org/wiki/Gr%C3%BCnlandtemperatursumme + +Folgende Parameter sind möglich / notwendig: + + +.. code-block:: yaml + + db_addon_params: "year=current" + +- year: Jahreszahl (str oder int), für das die Berechnung ausgeführt werden soll oder "current" für aktuelles Jahr (default: 'current') + + +Wachstumsgradtag +---------------- +Der Begriff Wachstumsgradtage (WGT) ist ein Überbegriff für verschiedene Größen. +Gemeinsam ist ihnen, daß zur Berechnung eine Lufttemperatur von einem Schwellenwert subtrahiert wird. +Je nach Fragestellung und Pflanzenart werden der Schwellenwert unterschiedlich gewählt und die Temperatur unterschiedlich bestimmt. +Verfügbar sind die Berechnung über 0) "einfachen Durchschnitt der Tagestemperaturen", 1) "modifizierten Durchschnitt der Tagestemperaturen" +und 2) Anzahl der Tage, deren Mitteltempertatur oberhalb der Schwellentemperatur lag. + +siehe https://de.wikipedia.org/wiki/Wachstumsgradtag + +Folgende Parameter sind möglich / notwendig: + +.. code-block:: yaml + + db_addon_params: "year=current, method=1, threshold=10" + +- year: Jahreszahl (str oder int), für das die Berechnung ausgeführt werden soll oder "current" für aktuelles Jahr (default: 'current') +- method: 0-Berechnung über "einfachen Durchschnitt der Tagestemperaturen", 1-Berechnung über "modifizierten Durchschnitt (default: 0) +der Tagestemperaturen" 2-Anzahl der Tage, mit Mitteltempertatur oberhalb Schwellentemperatur// 10, 11 Ausgabe aus Zeitserie +- threshold: Schwellentemperatur in °C (int) (default: 10) + + +Wärmesumme +---------- + +Die Wärmesumme soll eine Aussage über den Sommer und die Pflanzenreife liefern. Es gibt keine eindeutige Definition der Größe "Wärmesumme". +Berechnet wird die Wärmesumme als Summe aller Tagesmitteltemperaturen über einem Schwellenwert ab dem 1.1. des Jahres. + +siehe https://de.wikipedia.org/wiki/W%C3%A4rmesumme + +Folgende Parameter sind möglich / notwendig: + +.. code-block:: yaml + + db_addon_params: "year=current, month=1, threshold=10" + +- year: Jahreszahl (str oder int), für das die Berechnung ausgeführt werden soll oder "current" für aktuelles Jahr (default: 'current') +- month: Monat (int) des Jahres, für das die Berechnung ausgeführt werden soll (optional) (default: None) +- threshold: Schwellentemperatur in °C (int) (default: 10) + + +Kältesumme +---------- + +Die Kältesumme soll eine Aussage über die Härte des Winters liefern. +Berechnet wird die Kältesumme als Summe aller negativen Tagesmitteltemperaturen ab dem 21.9. des Jahres bis 31.3. des Folgejahres. + +siehe https://de.wikipedia.org/wiki/K%C3%A4ltesumme + +Folgende Parameter sind möglich / notwendig: + +.. code-block:: yaml + + db_addon_params: "year=current, month=1" + +- year: Jahreszahl (str oder int), für das die Berechnung ausgeführt werden soll oder "current" für aktuelles Jahr (default: 'current') +- month: Monat (int) des Jahres, für das die Berechnung ausgeführt werden soll (optional) (default: None) + + +Tagesmitteltemperatur +--------------------- + +Die Tagesmitteltemperatur wird auf Basis der stündlichen Durchschnittswerte eines Tages (aller in der DB enthaltenen Datensätze) +für die angegebene Anzahl von Tagen (days=optional) berechnet. + + + +Vorgehen bei Funktionserweiterung des Plugins bzw. Ergänzung weiterer Werte für Item-Attribute +---------------------------------------------------------------------------------------------- + +Aufgrund der Vielzahl der möglichen Werte der Itemattribute, insbesondere des Itemattributes `db_addon_fct`, wurde die Erstellung/Update +der entsprechenden Teile der `plugin.yam` sowie die Erstellung der Datei `item_attributes.py`, die vom Plugin verwendet wird, automatisiert. + +Die Masterinformationen für alle Itemattribute sowie die Skripte zum Erstellen/Update der beiden Dateien sind in der +Datei `item_attributes_master.py` enthalten. + +.. important:: + + Korrekturen, Erweiterungen etc. der Itemattribute sollten nur in der Datei `item_attributes_master.py` + im Dict der Variable `ITEM_ATTRIBUTS` vorgenommen werden. Das Ausführen der Datei `item_attributes_master.py` (main) + erstellt die `item_attributes.py` und aktualisiert die `plugin.yaml` entsprechend. +Dieses Kapitel wurde automatisch durch Ausführen des Skripts in der Datei 'item_attributes_master.py' erstellt. + +Nachfolgend eine Auflistung der möglichen Attribute für das Plugin im Format: Attribute: Beschreibung | Berechnungszyklus | Item-Type + + +db_addon_fct +------------ + +- verbrauch_heute: Verbrauch am heutigen Tag (Differenz zwischen aktuellem Wert und den Wert am Ende des vorherigen Tages) | Berechnung: daily | Item-Type: num + +- verbrauch_tag: Verbrauch am heutigen Tag (Differenz zwischen aktuellem Wert und den Wert am Ende des vorherigen Tages) | Berechnung: daily | Item-Type: num + +- verbrauch_woche: Verbrauch in der aktuellen Woche | Berechnung: weekly | Item-Type: num + +- verbrauch_monat: Verbrauch im aktuellen Monat | Berechnung: monthly | Item-Type: num + +- verbrauch_jahr: Verbrauch im aktuellen Jahr | Berechnung: yearly | Item-Type: num + +- verbrauch_last_24h: Verbrauch innerhalb letzten 24h | Berechnung: hourly | Item-Type: num + +- verbrauch_last_7d: Verbrauch innerhalb letzten 7 Tage | Berechnung: hourly | Item-Type: num + +- verbrauch_heute_minus1: Verbrauch gestern (heute -1 Tag) (Differenz zwischen Wert am Ende des gestrigen Tages und dem Wert am Ende des Tages davor) | Berechnung: daily | Item-Type: num + +- verbrauch_heute_minus2: Verbrauch vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num + +- verbrauch_heute_minus3: Verbrauch heute -3 Tage | Berechnung: daily | Item-Type: num + +- verbrauch_heute_minus4: Verbrauch heute -4 Tage | Berechnung: daily | Item-Type: num + +- verbrauch_heute_minus5: Verbrauch heute -5 Tage | Berechnung: daily | Item-Type: num + +- verbrauch_heute_minus6: Verbrauch heute -6 Tage | Berechnung: daily | Item-Type: num + +- verbrauch_heute_minus7: Verbrauch heute -7 Tage | Berechnung: daily | Item-Type: num + +- verbrauch_heute_minus8: Verbrauch heute -8 Tage | Berechnung: daily | Item-Type: num + +- verbrauch_tag_minus1: Verbrauch gestern (heute -1 Tag) (Differenz zwischen Wert am Ende des gestrigen Tages und dem Wert am Ende des Tages davor) | Berechnung: daily | Item-Type: num + +- verbrauch_tag_minus2: Verbrauch vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num + +- verbrauch_tag_minus3: Verbrauch heute -3 Tage | Berechnung: daily | Item-Type: num + +- verbrauch_tag_minus4: Verbrauch heute -4 Tage | Berechnung: daily | Item-Type: num + +- verbrauch_tag_minus5: Verbrauch heute -5 Tage | Berechnung: daily | Item-Type: num + +- verbrauch_tag_minus6: Verbrauch heute -6 Tage | Berechnung: daily | Item-Type: num + +- verbrauch_tag_minus7: Verbrauch heute -7 Tage | Berechnung: daily | Item-Type: num + +- verbrauch_tag_minus8: Verbrauch heute -8 Tage | Berechnung: daily | Item-Type: num + +- verbrauch_woche_minus1: Verbrauch Vorwoche (aktuelle Woche -1) | Berechnung: weekly | Item-Type: num + +- verbrauch_woche_minus2: Verbrauch aktuelle Woche -2 Wochen | Berechnung: weekly | Item-Type: num + +- verbrauch_woche_minus3: Verbrauch aktuelle Woche -3 Wochen | Berechnung: weekly | Item-Type: num + +- verbrauch_woche_minus4: Verbrauch aktuelle Woche -4 Wochen | Berechnung: weekly | Item-Type: num + +- verbrauch_monat_minus1: Verbrauch Vormonat (aktueller Monat -1) | Berechnung: monthly | Item-Type: num + +- verbrauch_monat_minus2: Verbrauch aktueller Monat -2 Monate | Berechnung: monthly | Item-Type: num + +- verbrauch_monat_minus3: Verbrauch aktueller Monat -3 Monate | Berechnung: monthly | Item-Type: num + +- verbrauch_monat_minus4: Verbrauch aktueller Monat -4 Monate | Berechnung: monthly | Item-Type: num + +- verbrauch_monat_minus12: Verbrauch aktueller Monat -12 Monate | Berechnung: monthly | Item-Type: num + +- verbrauch_jahr_minus1: Verbrauch Vorjahr (aktuelles Jahr -1 Jahr) | Berechnung: yearly | Item-Type: num + +- verbrauch_jahr_minus2: Verbrauch aktuelles Jahr -2 Jahre | Berechnung: yearly | Item-Type: num + +- verbrauch_jahr_minus3: Verbrauch aktuelles Jahr -3 Jahre | Berechnung: yearly | Item-Type: num + +- verbrauch_rolling_12m_heute_minus1: Verbrauch der letzten 12 Monate ausgehend im Ende des letzten Tages | Berechnung: daily | Item-Type: num + +- verbrauch_rolling_12m_tag_minus1: Verbrauch der letzten 12 Monate ausgehend im Ende des letzten Tages | Berechnung: daily | Item-Type: num + +- verbrauch_rolling_12m_woche_minus1: Verbrauch der letzten 12 Monate ausgehend im Ende der letzten Woche | Berechnung: weekly | Item-Type: num + +- verbrauch_rolling_12m_monat_minus1: Verbrauch der letzten 12 Monate ausgehend im Ende des letzten Monats | Berechnung: monthly | Item-Type: num + +- verbrauch_rolling_12m_jahr_minus1: Verbrauch der letzten 12 Monate ausgehend im Ende des letzten Jahres | Berechnung: yearly | Item-Type: num + +- verbrauch_jahreszeitraum_minus1: Verbrauch seit dem 1.1. bis zum heutigen Tag des Vorjahres | Berechnung: daily | Item-Type: num + +- verbrauch_jahreszeitraum_minus2: Verbrauch seit dem 1.1. bis zum heutigen Tag vor 2 Jahren | Berechnung: daily | Item-Type: num + +- verbrauch_jahreszeitraum_minus3: Verbrauch seit dem 1.1. bis zum heutigen Tag vor 3 Jahren | Berechnung: daily | Item-Type: num + +- zaehlerstand_heute_minus1: Zählerstand / Wert am Ende des letzten Tages (heute -1 Tag) | Berechnung: daily | Item-Type: num + +- zaehlerstand_heute_minus2: Zählerstand / Wert am Ende des vorletzten Tages (heute -2 Tag) | Berechnung: daily | Item-Type: num + +- zaehlerstand_heute_minus3: Zählerstand / Wert am Ende des vorvorletzten Tages (heute -3 Tag) | Berechnung: daily | Item-Type: num + +- zaehlerstand_tag_minus1: Zählerstand / Wert am Ende des letzten Tages (heute -1 Tag) | Berechnung: daily | Item-Type: num + +- zaehlerstand_tag_minus2: Zählerstand / Wert am Ende des vorletzten Tages (heute -2 Tag) | Berechnung: daily | Item-Type: num + +- zaehlerstand_tag_minus3: Zählerstand / Wert am Ende des vorvorletzten Tages (heute -3 Tag) | Berechnung: daily | Item-Type: num + +- zaehlerstand_woche_minus1: Zählerstand / Wert am Ende der vorvorletzten Woche (aktuelle Woche -1 Woche) | Berechnung: weekly | Item-Type: num + +- zaehlerstand_woche_minus2: Zählerstand / Wert am Ende der vorletzten Woche (aktuelle Woche -2 Wochen) | Berechnung: weekly | Item-Type: num + +- zaehlerstand_woche_minus3: Zählerstand / Wert am Ende der aktuellen Woche -3 Wochen | Berechnung: weekly | Item-Type: num + +- zaehlerstand_monat_minus1: Zählerstand / Wert am Ende des letzten Monates (aktueller Monat -1 Monat) | Berechnung: monthly | Item-Type: num + +- zaehlerstand_monat_minus2: Zählerstand / Wert am Ende des vorletzten Monates (aktueller Monat -2 Monate) | Berechnung: monthly | Item-Type: num + +- zaehlerstand_monat_minus3: Zählerstand / Wert am Ende des aktuellen Monats -3 Monate | Berechnung: monthly | Item-Type: num + +- zaehlerstand_jahr_minus1: Zählerstand / Wert am Ende des letzten Jahres (aktuelles Jahr -1 Jahr) | Berechnung: yearly | Item-Type: num + +- zaehlerstand_jahr_minus2: Zählerstand / Wert am Ende des vorletzten Jahres (aktuelles Jahr -2 Jahre) | Berechnung: yearly | Item-Type: num + +- zaehlerstand_jahr_minus3: Zählerstand / Wert am Ende des aktuellen Jahres -3 Jahre | Berechnung: yearly | Item-Type: num + +- minmax_last_24h_min: minimaler Wert der letzten 24h | Berechnung: daily | Item-Type: num + +- minmax_last_24h_max: maximaler Wert der letzten 24h | Berechnung: daily | Item-Type: num + +- minmax_last_24h_avg: durchschnittlicher Wert der letzten 24h | Berechnung: daily | Item-Type: num + +- minmax_last_7d_min: minimaler Wert der letzten 7 Tage | Berechnung: daily | Item-Type: num + +- minmax_last_7d_max: maximaler Wert der letzten 7 Tage | Berechnung: daily | Item-Type: num + +- minmax_last_7d_avg: durchschnittlicher Wert der letzten 7 Tage | Berechnung: daily | Item-Type: num + +- minmax_heute_min: Minimalwert seit Tagesbeginn | Berechnung: daily | Item-Type: num + +- minmax_heute_max: Maximalwert seit Tagesbeginn | Berechnung: daily | Item-Type: num + +- minmax_heute_avg: Durschnittswert seit Tagesbeginn | Berechnung: daily | Item-Type: num + +- minmax_heute_minus1_min: Minimalwert gestern (heute -1 Tag) | Berechnung: daily | Item-Type: num + +- minmax_heute_minus1_max: Maximalwert gestern (heute -1 Tag) | Berechnung: daily | Item-Type: num + +- minmax_heute_minus1_avg: Durchschnittswert gestern (heute -1 Tag) | Berechnung: daily | Item-Type: num + +- minmax_heute_minus2_min: Minimalwert vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num + +- minmax_heute_minus2_max: Maximalwert vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num + +- minmax_heute_minus2_avg: Durchschnittswert vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num + +- minmax_heute_minus3_min: Minimalwert heute vor 3 Tagen | Berechnung: daily | Item-Type: num + +- minmax_heute_minus3_max: Maximalwert heute vor 3 Tagen | Berechnung: daily | Item-Type: num + +- minmax_heute_minus3_avg: Durchschnittswert heute vor 3 Tagen | Berechnung: daily | Item-Type: num + +- minmax_tag_min: Minimalwert seit Tagesbeginn | Berechnung: daily | Item-Type: num + +- minmax_tag_max: Maximalwert seit Tagesbeginn | Berechnung: daily | Item-Type: num + +- minmax_tag_avg: Durschnittswert seit Tagesbeginn | Berechnung: daily | Item-Type: num + +- minmax_tag_minus1_min: Minimalwert gestern (heute -1 Tag) | Berechnung: daily | Item-Type: num + +- minmax_tag_minus1_max: Maximalwert gestern (heute -1 Tag) | Berechnung: daily | Item-Type: num + +- minmax_tag_minus1_avg: Durchschnittswert gestern (heute -1 Tag) | Berechnung: daily | Item-Type: num + +- minmax_tag_minus2_min: Minimalwert vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num + +- minmax_tag_minus2_max: Maximalwert vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num + +- minmax_tag_minus2_avg: Durchschnittswert vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num + +- minmax_tag_minus3_min: Minimalwert heute vor 3 Tagen | Berechnung: daily | Item-Type: num + +- minmax_tag_minus3_max: Maximalwert heute vor 3 Tagen | Berechnung: daily | Item-Type: num + +- minmax_tag_minus3_avg: Durchschnittswert heute vor 3 Tagen | Berechnung: daily | Item-Type: num + +- minmax_woche_min: Minimalwert seit Wochenbeginn | Berechnung: weekly | Item-Type: num + +- minmax_woche_max: Maximalwert seit Wochenbeginn | Berechnung: weekly | Item-Type: num + +- minmax_woche_minus1_min: Minimalwert Vorwoche (aktuelle Woche -1) | Berechnung: weekly | Item-Type: num + +- minmax_woche_minus1_max: Maximalwert Vorwoche (aktuelle Woche -1) | Berechnung: weekly | Item-Type: num + +- minmax_woche_minus1_avg: Durchschnittswert Vorwoche (aktuelle Woche -1) | Berechnung: weekly | Item-Type: num + +- minmax_woche_minus2_min: Minimalwert aktuelle Woche -2 Wochen | Berechnung: weekly | Item-Type: num + +- minmax_woche_minus2_max: Maximalwert aktuelle Woche -2 Wochen | Berechnung: weekly | Item-Type: num + +- minmax_woche_minus2_avg: Durchschnittswert aktuelle Woche -2 Wochen | Berechnung: weekly | Item-Type: num + +- minmax_monat_min: Minimalwert seit Monatsbeginn | Berechnung: monthly | Item-Type: num + +- minmax_monat_max: Maximalwert seit Monatsbeginn | Berechnung: monthly | Item-Type: num + +- minmax_monat_minus1_min: Minimalwert Vormonat (aktueller Monat -1) | Berechnung: monthly | Item-Type: num + +- minmax_monat_minus1_max: Maximalwert Vormonat (aktueller Monat -1) | Berechnung: monthly | Item-Type: num + +- minmax_monat_minus1_avg: Durchschnittswert Vormonat (aktueller Monat -1) | Berechnung: monthly | Item-Type: num + +- minmax_monat_minus2_min: Minimalwert aktueller Monat -2 Monate | Berechnung: monthly | Item-Type: num + +- minmax_monat_minus2_max: Maximalwert aktueller Monat -2 Monate | Berechnung: monthly | Item-Type: num + +- minmax_monat_minus2_avg: Durchschnittswert aktueller Monat -2 Monate | Berechnung: monthly | Item-Type: num + +- minmax_jahr_min: Minimalwert seit Jahresbeginn | Berechnung: yearly | Item-Type: num + +- minmax_jahr_max: Maximalwert seit Jahresbeginn | Berechnung: yearly | Item-Type: num + +- minmax_jahr_minus1_min: Minimalwert Vorjahr (aktuelles Jahr -1 Jahr) | Berechnung: yearly | Item-Type: num + +- minmax_jahr_minus1_max: Maximalwert Vorjahr (aktuelles Jahr -1 Jahr) | Berechnung: yearly | Item-Type: num + +- minmax_jahr_minus1_avg: Durchschnittswert Vorjahr (aktuelles Jahr -1 Jahr) | Berechnung: yearly | Item-Type: num + +- tagesmitteltemperatur_heute: Tagesmitteltemperatur heute | Berechnung: daily | Item-Type: num + +- tagesmitteltemperatur_heute_minus1: Tagesmitteltemperatur des letzten Tages (heute -1 Tag) | Berechnung: daily | Item-Type: num + +- tagesmitteltemperatur_heute_minus2: Tagesmitteltemperatur des vorletzten Tages (heute -2 Tag) | Berechnung: daily | Item-Type: num + +- tagesmitteltemperatur_heute_minus3: Tagesmitteltemperatur des vorvorletzten Tages (heute -3 Tag) | Berechnung: daily | Item-Type: num + +- tagesmitteltemperatur_tag: Tagesmitteltemperatur heute | Berechnung: daily | Item-Type: num + +- tagesmitteltemperatur_tag_minus1: Tagesmitteltemperatur des letzten Tages (heute -1 Tag) | Berechnung: daily | Item-Type: num + +- tagesmitteltemperatur_tag_minus2: Tagesmitteltemperatur des vorletzten Tages (heute -2 Tag) | Berechnung: daily | Item-Type: num + +- tagesmitteltemperatur_tag_minus3: Tagesmitteltemperatur des vorvorletzten Tages (heute -3 Tag) | Berechnung: daily | Item-Type: num + +- serie_minmax_monat_min_15m: monatlicher Minimalwert der letzten 15 Monate (gleitend) | Berechnung: monthly | Item-Type: list + +- serie_minmax_monat_max_15m: monatlicher Maximalwert der letzten 15 Monate (gleitend) | Berechnung: monthly | Item-Type: list + +- serie_minmax_monat_avg_15m: monatlicher Mittelwert der letzten 15 Monate (gleitend) | Berechnung: monthly | Item-Type: list + +- serie_minmax_woche_min_30w: wöchentlicher Minimalwert der letzten 30 Wochen (gleitend) | Berechnung: weekly | Item-Type: list + +- serie_minmax_woche_max_30w: wöchentlicher Maximalwert der letzten 30 Wochen (gleitend) | Berechnung: weekly | Item-Type: list + +- serie_minmax_woche_avg_30w: wöchentlicher Mittelwert der letzten 30 Wochen (gleitend) | Berechnung: weekly | Item-Type: list + +- serie_minmax_tag_min_30d: täglicher Minimalwert der letzten 30 Tage (gleitend) | Berechnung: daily | Item-Type: list + +- serie_minmax_tag_max_30d: täglicher Maximalwert der letzten 30 Tage (gleitend) | Berechnung: daily | Item-Type: list + +- serie_minmax_tag_avg_30d: täglicher Mittelwert der letzten 30 Tage (gleitend) | Berechnung: daily | Item-Type: list + +- serie_verbrauch_tag_30d: Verbrauch pro Tag der letzten 30 Tage | Berechnung: daily | Item-Type: list + +- serie_verbrauch_woche_30w: Verbrauch pro Woche der letzten 30 Wochen | Berechnung: weekly | Item-Type: list + +- serie_verbrauch_monat_18m: Verbrauch pro Monat der letzten 18 Monate | Berechnung: monthly | Item-Type: list + +- serie_zaehlerstand_tag_30d: Zählerstand am Tagesende der letzten 30 Tage | Berechnung: daily | Item-Type: list + +- serie_zaehlerstand_woche_30w: Zählerstand am Wochenende der letzten 30 Wochen | Berechnung: weekly | Item-Type: list + +- serie_zaehlerstand_monat_18m: Zählerstand am Monatsende der letzten 18 Monate | Berechnung: monthly | Item-Type: list + +- serie_waermesumme_monat_24m: monatliche Wärmesumme der letzten 24 Monate | Berechnung: monthly | Item-Type: list + +- serie_kaeltesumme_monat_24m: monatliche Kältesumme der letzten 24 Monate | Berechnung: monthly | Item-Type: list + +- serie_tagesmittelwert_0d: Tagesmittelwert für den aktuellen Tag | Berechnung: daily | Item-Type: list + +- serie_tagesmittelwert_stunde_0d: Stundenmittelwert für den aktuellen Tag | Berechnung: daily | Item-Type: list + +- serie_tagesmittelwert_stunde_30_0d: Stundenmittelwert für den aktuellen Tag | Berechnung: daily | Item-Type: list + +- serie_tagesmittelwert_tag_stunde_30d: Stundenmittelwert pro Tag der letzten 30 Tage (bspw. zur Berechnung der Tagesmitteltemperatur basierend auf den Mittelwert der Temperatur pro Stunde | Berechnung: daily | Item-Type: list + +- general_oldest_value: Ausgabe des ältesten Wertes des entsprechenden "Parent-Items" mit database Attribut | Berechnung: no | Item-Type: num + +- general_oldest_log: Ausgabe des Timestamp des ältesten Eintrages des entsprechenden "Parent-Items" mit database Attribut | Berechnung: no | Item-Type: list + +- kaeltesumme: Berechnet die Kältesumme für einen Zeitraum, db_addon_params: (year=optional, month=optional) | Berechnung: daily | Item-Type: num + +- waermesumme: Berechnet die Wärmesumme für einen Zeitraum, db_addon_params: (year=optional, month=optional) | Berechnung: daily | Item-Type: num + +- gruenlandtempsumme: Berechnet die Grünlandtemperatursumme für einen Zeitraum, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num + +- wachstumsgradtage: Berechnet die Wachstumsgradtage auf Basis der stündlichen Durchschnittswerte eines Tages für das laufende Jahr mit an Angabe des Temperaturschwellenwertes (threshold=Schwellentemperatur) | Berechnung: daily | Item-Type: num + +- wuestentage: Berechnet die Anzahl der Wüstentage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num + +- heisse_tage: Berechnet die Anzahl der heissen Tage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num + +- tropennaechte: Berechnet die Anzahl der Tropennächte des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num + +- sommertage: Berechnet die Anzahl der Sommertage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num + +- heiztage: Berechnet die Anzahl der Heiztage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num + +- vegetationstage: Berechnet die Anzahl der Vegatationstage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num + +- frosttage: Berechnet die Anzahl der Frosttage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num + +- eistage: Berechnet die Anzahl der Eistage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num + +- tagesmitteltemperatur: Berechnet die Tagesmitteltemperatur auf Basis der stündlichen Durchschnittswerte eines Tages für die angegebene Anzahl von Tagen (timeframe=day, count=integer) | Berechnung: daily | Item-Type: list + +- db_request: Abfrage der DB: db_addon_params: (func=mandatory, item=mandatory, timespan=mandatory, start=optional, end=optional, count=optional, group=optional, group2=optional) | Berechnung: group | Item-Type: list + +- minmax: Berechnet einen min/max/avg Wert für einen bestimmen Zeitraum: db_addon_params: (func=mandatory, timeframe=mandatory, start=mandatory) | Berechnung: timeframe | Item-Type: num + +- minmax_last: 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) | Berechnung: timeframe | Item-Type: num + +- verbrauch: Berechnet einen Verbrauchswert für einen bestimmen Zeitraum: db_addon_params: (timeframe=mandatory, start=mandatory end=mandatory) | Berechnung: timeframe | Item-Type: num + +- zaehlerstand: Berechnet einen Zählerstand für einen bestimmen Zeitpunkt: db_addon_params: (timeframe=mandatory, start=mandatory) | Berechnung: timeframe | Item-Type: num + + +db_addon_info +------------- + +- db_version: Version der verbundenen Datenbank | Berechnung: no | Item-Type: str + + +db_addon_admin +-------------- + +- suspend: Unterbricht die Aktivitäten des Plugin | Berechnung: no | Item-Type: bool + +- recalc_all: Startet einen Neuberechnungslauf aller on-demand Items | Berechnung: no | Item-Type: bool + +- clean_cache_values: Löscht Plugin-Cache und damit alle im Plugin zwischengespeicherten Werte | Berechnung: no | Item-Type: bool + + +Hinweise +======== + + - Das Plugin startet die Berechnungen der Werte nach einer gewissen (konfigurierbaren) Zeit (Attribut `startup_run_delay`) + nach dem Start von shNG, um den Startvorgang nicht zu beeinflussen. + + - Bei Start werden automatisch nur die Items berechnet, für das das Attribute `db_addon_startup` gesetzt wurde. Alle anderen + Items werden erst zur konfigurierten Zeit berechnet. Das Attribute `db_addon_startup` kann auch direkt am `Database-Item` + gesetzt werden. Dabei wird das Attribut auf alle darunter liegenden `db_addon-Items` (bspw. bei Verwendung von structs) vererbt. + Über das WebIF kann die Berechnung aller definierten Items ausgelöst werden. + + - Für sogenannte `on_change` Items, also Items, deren Berechnung bis zum Jetzt (bspw. verbrauch-heute) gehen, wird die Berechnung + immer bei eintreffen eines neuen Wertes gestartet. Zu Reduktion der Belastung auf die Datenbank werden die Werte für das Ende der + letzten Periode gecached. + + - Berechnungen werden nur ausgeführt, wenn für den kompletten abgefragten Zeitraum Werte in der Datenbank vorliegen. Wird bspw. + der Verbrauch des letzten Monats abgefragt wobei erst Werte ab dem 3. des Monats in der Datenbank sind, wird die Berechnung abgebrochen. + + - Mit dem Attribut `use_oldest_entry` kann dieses Verhalten verändert werden. Ist das Attribut gesetzt, wird, wenn für den + Beginn der Abfragezeitraums keinen Werte vorliegen, der älteste Eintrag der Datenbank genutzt. + + - Für die Auswertung kann es nützlich sein, bestimmte Werte aus der Datenbank bei der Berechnung auszublenden. Hierfür stehen + 2 Möglichkeiten zur Verfügung: + - Plugin-Attribut `ignore_0`: (list of strings) Bei Items, bei denen ein String aus der Liste im Pfadnamen vorkommt, + werden 0-Werte (val_num = 0) bei Datenbankauswertungen ignoriert. Hat also das Attribut den Wert ['temp'] werden bei allen Items mit + 'temp' im Pfadnamen die 0-Werte bei der Auswertung ignoriert. + - Item-Attribut `db_addon_ignore_value`: (num) Dieser Wert wird bei der Abfrage bzw. Auswertung der Datenbank für diese + Item ignoriert. + + - Das Plugin enthält sehr ausführliche Logginginformation. Bei unerwartetem Verhalten, den LogLevel entsprechend anpassen, + um mehr information zu erhalten. + + - Berechnungen des Plugins können im WebIF unterbrochen werden. Auch das gesamte Plugin kann pausiert werden. Dies kann bei + starker Systembelastung nützlich sein. + + +Beispiele +========= + +Verbrauch +--------- + +Soll bspw. der Verbrauch von Wasser ausgewertet werden, so ist dies wie folgt möglich: + + +.. code-block:: yaml + + wasserzaehler: + zaehlerstand: + type: num + knx_dpt: 12 + knx_cache: 5/3/4 + eval: round(value/1000, 1) + database: init + struct: + - db_addon.verbrauch_1 + - db_addon.verbrauch_2 + - db_addon.zaehlerstand_1 + +Die Werte des Wasserzählerstandes werden in die Datenbank geschrieben und darauf basierend ausgewertet. Die structs +'db_addon.verbrauch_1' und 'db_addon.verbrauch_2' stellen entsprechende Items für die Verbrauchsauswerten zur Verfügung. + +minmax +------ + +Soll bspw. die minimalen und maximalen Temperaturen ausgewertet werden, kann dies so umgesetzt werden: + +.. code-block:: yaml + + temperature: + aussen: + nord: + name: Außentemp Nordseite + type: num + visu_acl: ro + knx_dpt: 9 + knx_cache: 6/5/1 + database: init + struct: + - db_addon.minmax_1 + - db_addon.minmax_2 + +Die Temperaturwerte werden in die Datenbank geschrieben und darauf basierend ausgewertet. Die structs +'db_addon.minmax_1' und 'db_addon.minmax_2' stellen entsprechende Items für die min/max Auswertung zur Verfügung. + +| + +Web Interface +============= + +Das WebIF stellt neben der Ansicht verbundener Items und deren Parameter und Werte auch Funktionen für die +Administration des Plugins bereit. + +Es stehen Button für: + +- Neuberechnung aller Items +- Abbruch eines aktiven Berechnungslaufes +- Pausieren des Plugins +- Wiederaufnahme des Plugins + +bereit. + +Achtung: Das Auslösen einer kompletten Neuberechnung aller Items kann zu einer starken Belastung der Datenbank +aufgrund vieler Leseanfragen führen. + + +db_addon Items +-------------- + +Dieser Reiter des Webinterface zeigt die Items an, für die ein DatabaseAddon Attribut konfiguriert ist. + + +db_addon Maintenance +-------------------- + +Das Webinterface zeigt detaillierte Informationen über die im Plugin verfügbaren Daten an. +Dies dient der Maintenance bzw. Fehlersuche. Dieser Tab ist nur bei Log-Level "Debug" verfügbar. + + +Erläuterungen zu Temperatursummen +================================= + + +Grünlandtemperatursumme +----------------------- + +Beim Grünland wird die Wärmesumme nach Ernst und Loeper benutzt, um den Vegetationsbeginn und somit den Termin von Düngungsmaßnahmen zu bestimmen. +Dabei erfolgt die Aufsummierung der Tagesmitteltemperaturen über 0 °C, wobei der Januar mit 0.5 und der Februar mit 0.75 gewichtet wird. +Bei einer Wärmesumme von 200 Grad ist eine Düngung angesagt. + +siehe: https://de.wikipedia.org/wiki/Gr%C3%BCnlandtemperatursumme + +Folgende Parameter sind möglich / notwendig: + + +.. code-block:: yaml + + db_addon_params: "year=current" + +- year: Jahreszahl (str oder int), für das die Berechnung ausgeführt werden soll oder "current" für aktuelles Jahr (default: 'current') + + +Wachstumsgradtag +---------------- +Der Begriff Wachstumsgradtage (WGT) ist ein Überbegriff für verschiedene Größen. +Gemeinsam ist ihnen, daß zur Berechnung eine Lufttemperatur von einem Schwellenwert subtrahiert wird. +Je nach Fragestellung und Pflanzenart werden der Schwellenwert unterschiedlich gewählt und die Temperatur unterschiedlich bestimmt. +Verfügbar sind die Berechnung über 0) "einfachen Durchschnitt der Tagestemperaturen", 1) "modifizierten Durchschnitt der Tagestemperaturen" +und 2) Anzahl der Tage, deren Mitteltempertatur oberhalb der Schwellentemperatur lag. + +siehe https://de.wikipedia.org/wiki/Wachstumsgradtag + +Folgende Parameter sind möglich / notwendig: + +.. code-block:: yaml + + db_addon_params: "year=current, method=1, threshold=10" + +- year: Jahreszahl (str oder int), für das die Berechnung ausgeführt werden soll oder "current" für aktuelles Jahr (default: 'current') +- method: 0-Berechnung über "einfachen Durchschnitt der Tagestemperaturen", 1-Berechnung über "modifizierten Durchschnitt (default: 0) +der Tagestemperaturen" 2-Anzahl der Tage, mit Mitteltempertatur oberhalb Schwellentemperatur// 10, 11 Ausgabe aus Zeitserie +- threshold: Schwellentemperatur in °C (int) (default: 10) + + +Wärmesumme +---------- + +Die Wärmesumme soll eine Aussage über den Sommer und die Pflanzenreife liefern. Es gibt keine eindeutige Definition der Größe "Wärmesumme". +Berechnet wird die Wärmesumme als Summe aller Tagesmitteltemperaturen über einem Schwellenwert ab dem 1.1. des Jahres. + +siehe https://de.wikipedia.org/wiki/W%C3%A4rmesumme + +Folgende Parameter sind möglich / notwendig: + +.. code-block:: yaml + + db_addon_params: "year=current, month=1, threshold=10" + +- year: Jahreszahl (str oder int), für das die Berechnung ausgeführt werden soll oder "current" für aktuelles Jahr (default: 'current') +- month: Monat (int) des Jahres, für das die Berechnung ausgeführt werden soll (optional) (default: None) +- threshold: Schwellentemperatur in °C (int) (default: 10) + + +Kältesumme +---------- + +Die Kältesumme soll eine Aussage über die Härte des Winters liefern. +Berechnet wird die Kältesumme als Summe aller negativen Tagesmitteltemperaturen ab dem 21.9. des Jahres bis 31.3. des Folgejahres. + +siehe https://de.wikipedia.org/wiki/K%C3%A4ltesumme + +Folgende Parameter sind möglich / notwendig: + +.. code-block:: yaml + + db_addon_params: "year=current, month=1" + +- year: Jahreszahl (str oder int), für das die Berechnung ausgeführt werden soll oder "current" für aktuelles Jahr (default: 'current') +- month: Monat (int) des Jahres, für das die Berechnung ausgeführt werden soll (optional) (default: None) + + +Tagesmitteltemperatur +--------------------- + +Die Tagesmitteltemperatur wird auf Basis der stündlichen Durchschnittswerte eines Tages (aller in der DB enthaltenen Datensätze) +für die angegebene Anzahl von Tagen (days=optional) berechnet. + + + +Vorgehen bei Funktionserweiterung des Plugins bzw. Ergänzung weiterer Werte für Item-Attribute +---------------------------------------------------------------------------------------------- + +Aufgrund der Vielzahl der möglichen Werte der Itemattribute, insbesondere des Itemattributes `db_addon_fct`, wurde die Erstellung/Update +der entsprechenden Teile der `plugin.yam` sowie die Erstellung der Datei `item_attributes.py`, die vom Plugin verwendet wird, automatisiert. + +Die Masterinformationen für alle Itemattribute sowie die Skripte zum Erstellen/Update der beiden Dateien sind in der +Datei `item_attributes_master.py` enthalten. + +.. important:: + + Korrekturen, Erweiterungen etc. der Itemattribute sollten nur in der Datei `item_attributes_master.py` + im Dict der Variable `ITEM_ATTRIBUTS` vorgenommen werden. Das Ausführen der Datei `item_attributes_master.py` (main) + erstellt die `item_attributes.py` und aktualisiert die `plugin.yaml` entsprechend. +Dieses Kapitel wurde automatisch durch Ausführen des Skripts in der Datei 'item_attributes_master.py' erstellt. + +Nachfolgend eine Auflistung der möglichen Attribute für das Plugin im Format: Attribute: Beschreibung | Berechnungszyklus | Item-Type + + +db_addon_fct +------------ + +- verbrauch_heute: Verbrauch am heutigen Tag (Differenz zwischen aktuellem Wert und den Wert am Ende des vorherigen Tages) | Berechnung: daily | Item-Type: num + +- verbrauch_tag: Verbrauch am heutigen Tag (Differenz zwischen aktuellem Wert und den Wert am Ende des vorherigen Tages) | Berechnung: daily | Item-Type: num + +- verbrauch_woche: Verbrauch in der aktuellen Woche | Berechnung: weekly | Item-Type: num + +- verbrauch_monat: Verbrauch im aktuellen Monat | Berechnung: monthly | Item-Type: num + +- verbrauch_jahr: Verbrauch im aktuellen Jahr | Berechnung: yearly | Item-Type: num + +- verbrauch_last_24h: Verbrauch innerhalb letzten 24h | Berechnung: hourly | Item-Type: num + +- verbrauch_last_7d: Verbrauch innerhalb letzten 7 Tage | Berechnung: hourly | Item-Type: num + +- verbrauch_heute_minus1: Verbrauch gestern (heute -1 Tag) (Differenz zwischen Wert am Ende des gestrigen Tages und dem Wert am Ende des Tages davor) | Berechnung: daily | Item-Type: num + +- verbrauch_heute_minus2: Verbrauch vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num + +- verbrauch_heute_minus3: Verbrauch heute -3 Tage | Berechnung: daily | Item-Type: num + +- verbrauch_heute_minus4: Verbrauch heute -4 Tage | Berechnung: daily | Item-Type: num + +- verbrauch_heute_minus5: Verbrauch heute -5 Tage | Berechnung: daily | Item-Type: num + +- verbrauch_heute_minus6: Verbrauch heute -6 Tage | Berechnung: daily | Item-Type: num + +- verbrauch_heute_minus7: Verbrauch heute -7 Tage | Berechnung: daily | Item-Type: num + +- verbrauch_heute_minus8: Verbrauch heute -8 Tage | Berechnung: daily | Item-Type: num + +- verbrauch_tag_minus1: Verbrauch gestern (heute -1 Tag) (Differenz zwischen Wert am Ende des gestrigen Tages und dem Wert am Ende des Tages davor) | Berechnung: daily | Item-Type: num + +- verbrauch_tag_minus2: Verbrauch vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num + +- verbrauch_tag_minus3: Verbrauch heute -3 Tage | Berechnung: daily | Item-Type: num + +- verbrauch_tag_minus4: Verbrauch heute -4 Tage | Berechnung: daily | Item-Type: num + +- verbrauch_tag_minus5: Verbrauch heute -5 Tage | Berechnung: daily | Item-Type: num + +- verbrauch_tag_minus6: Verbrauch heute -6 Tage | Berechnung: daily | Item-Type: num + +- verbrauch_tag_minus7: Verbrauch heute -7 Tage | Berechnung: daily | Item-Type: num + +- verbrauch_tag_minus8: Verbrauch heute -8 Tage | Berechnung: daily | Item-Type: num + +- verbrauch_woche_minus1: Verbrauch Vorwoche (aktuelle Woche -1) | Berechnung: weekly | Item-Type: num + +- verbrauch_woche_minus2: Verbrauch aktuelle Woche -2 Wochen | Berechnung: weekly | Item-Type: num + +- verbrauch_woche_minus3: Verbrauch aktuelle Woche -3 Wochen | Berechnung: weekly | Item-Type: num + +- verbrauch_woche_minus4: Verbrauch aktuelle Woche -4 Wochen | Berechnung: weekly | Item-Type: num + +- verbrauch_monat_minus1: Verbrauch Vormonat (aktueller Monat -1) | Berechnung: monthly | Item-Type: num + +- verbrauch_monat_minus2: Verbrauch aktueller Monat -2 Monate | Berechnung: monthly | Item-Type: num + +- verbrauch_monat_minus3: Verbrauch aktueller Monat -3 Monate | Berechnung: monthly | Item-Type: num + +- verbrauch_monat_minus4: Verbrauch aktueller Monat -4 Monate | Berechnung: monthly | Item-Type: num + +- verbrauch_monat_minus12: Verbrauch aktueller Monat -12 Monate | Berechnung: monthly | Item-Type: num + +- verbrauch_jahr_minus1: Verbrauch Vorjahr (aktuelles Jahr -1 Jahr) | Berechnung: yearly | Item-Type: num + +- verbrauch_jahr_minus2: Verbrauch aktuelles Jahr -2 Jahre | Berechnung: yearly | Item-Type: num + +- verbrauch_jahr_minus3: Verbrauch aktuelles Jahr -3 Jahre | Berechnung: yearly | Item-Type: num + +- verbrauch_rolling_12m_heute_minus1: Verbrauch der letzten 12 Monate ausgehend im Ende des letzten Tages | Berechnung: daily | Item-Type: num + +- verbrauch_rolling_12m_tag_minus1: Verbrauch der letzten 12 Monate ausgehend im Ende des letzten Tages | Berechnung: daily | Item-Type: num + +- verbrauch_rolling_12m_woche_minus1: Verbrauch der letzten 12 Monate ausgehend im Ende der letzten Woche | Berechnung: weekly | Item-Type: num + +- verbrauch_rolling_12m_monat_minus1: Verbrauch der letzten 12 Monate ausgehend im Ende des letzten Monats | Berechnung: monthly | Item-Type: num + +- verbrauch_rolling_12m_jahr_minus1: Verbrauch der letzten 12 Monate ausgehend im Ende des letzten Jahres | Berechnung: yearly | Item-Type: num + +- verbrauch_jahreszeitraum_minus1: Verbrauch seit dem 1.1. bis zum heutigen Tag des Vorjahres | Berechnung: daily | Item-Type: num + +- verbrauch_jahreszeitraum_minus2: Verbrauch seit dem 1.1. bis zum heutigen Tag vor 2 Jahren | Berechnung: daily | Item-Type: num + +- verbrauch_jahreszeitraum_minus3: Verbrauch seit dem 1.1. bis zum heutigen Tag vor 3 Jahren | Berechnung: daily | Item-Type: num + +- zaehlerstand_heute_minus1: Zählerstand / Wert am Ende des letzten Tages (heute -1 Tag) | Berechnung: daily | Item-Type: num + +- zaehlerstand_heute_minus2: Zählerstand / Wert am Ende des vorletzten Tages (heute -2 Tag) | Berechnung: daily | Item-Type: num + +- zaehlerstand_heute_minus3: Zählerstand / Wert am Ende des vorvorletzten Tages (heute -3 Tag) | Berechnung: daily | Item-Type: num + +- zaehlerstand_tag_minus1: Zählerstand / Wert am Ende des letzten Tages (heute -1 Tag) | Berechnung: daily | Item-Type: num + +- zaehlerstand_tag_minus2: Zählerstand / Wert am Ende des vorletzten Tages (heute -2 Tag) | Berechnung: daily | Item-Type: num + +- zaehlerstand_tag_minus3: Zählerstand / Wert am Ende des vorvorletzten Tages (heute -3 Tag) | Berechnung: daily | Item-Type: num + +- zaehlerstand_woche_minus1: Zählerstand / Wert am Ende der vorvorletzten Woche (aktuelle Woche -1 Woche) | Berechnung: weekly | Item-Type: num + +- zaehlerstand_woche_minus2: Zählerstand / Wert am Ende der vorletzten Woche (aktuelle Woche -2 Wochen) | Berechnung: weekly | Item-Type: num + +- zaehlerstand_woche_minus3: Zählerstand / Wert am Ende der aktuellen Woche -3 Wochen | Berechnung: weekly | Item-Type: num + +- zaehlerstand_monat_minus1: Zählerstand / Wert am Ende des letzten Monates (aktueller Monat -1 Monat) | Berechnung: monthly | Item-Type: num + +- zaehlerstand_monat_minus2: Zählerstand / Wert am Ende des vorletzten Monates (aktueller Monat -2 Monate) | Berechnung: monthly | Item-Type: num + +- zaehlerstand_monat_minus3: Zählerstand / Wert am Ende des aktuellen Monats -3 Monate | Berechnung: monthly | Item-Type: num + +- zaehlerstand_jahr_minus1: Zählerstand / Wert am Ende des letzten Jahres (aktuelles Jahr -1 Jahr) | Berechnung: yearly | Item-Type: num + +- zaehlerstand_jahr_minus2: Zählerstand / Wert am Ende des vorletzten Jahres (aktuelles Jahr -2 Jahre) | Berechnung: yearly | Item-Type: num + +- zaehlerstand_jahr_minus3: Zählerstand / Wert am Ende des aktuellen Jahres -3 Jahre | Berechnung: yearly | Item-Type: num + +- minmax_last_24h_min: minimaler Wert der letzten 24h | Berechnung: daily | Item-Type: num + +- minmax_last_24h_max: maximaler Wert der letzten 24h | Berechnung: daily | Item-Type: num + +- minmax_last_24h_avg: durchschnittlicher Wert der letzten 24h | Berechnung: daily | Item-Type: num + +- minmax_last_7d_min: minimaler Wert der letzten 7 Tage | Berechnung: daily | Item-Type: num + +- minmax_last_7d_max: maximaler Wert der letzten 7 Tage | Berechnung: daily | Item-Type: num + +- minmax_last_7d_avg: durchschnittlicher Wert der letzten 7 Tage | Berechnung: daily | Item-Type: num + +- minmax_heute_min: Minimalwert seit Tagesbeginn | Berechnung: daily | Item-Type: num + +- minmax_heute_max: Maximalwert seit Tagesbeginn | Berechnung: daily | Item-Type: num + +- minmax_heute_avg: Durschnittswert seit Tagesbeginn | Berechnung: daily | Item-Type: num + +- minmax_heute_minus1_min: Minimalwert gestern (heute -1 Tag) | Berechnung: daily | Item-Type: num + +- minmax_heute_minus1_max: Maximalwert gestern (heute -1 Tag) | Berechnung: daily | Item-Type: num + +- minmax_heute_minus1_avg: Durchschnittswert gestern (heute -1 Tag) | Berechnung: daily | Item-Type: num + +- minmax_heute_minus2_min: Minimalwert vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num + +- minmax_heute_minus2_max: Maximalwert vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num + +- minmax_heute_minus2_avg: Durchschnittswert vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num + +- minmax_heute_minus3_min: Minimalwert heute vor 3 Tagen | Berechnung: daily | Item-Type: num + +- minmax_heute_minus3_max: Maximalwert heute vor 3 Tagen | Berechnung: daily | Item-Type: num + +- minmax_heute_minus3_avg: Durchschnittswert heute vor 3 Tagen | Berechnung: daily | Item-Type: num + +- minmax_tag_min: Minimalwert seit Tagesbeginn | Berechnung: daily | Item-Type: num + +- minmax_tag_max: Maximalwert seit Tagesbeginn | Berechnung: daily | Item-Type: num + +- minmax_tag_avg: Durschnittswert seit Tagesbeginn | Berechnung: daily | Item-Type: num + +- minmax_tag_minus1_min: Minimalwert gestern (heute -1 Tag) | Berechnung: daily | Item-Type: num + +- minmax_tag_minus1_max: Maximalwert gestern (heute -1 Tag) | Berechnung: daily | Item-Type: num + +- minmax_tag_minus1_avg: Durchschnittswert gestern (heute -1 Tag) | Berechnung: daily | Item-Type: num + +- minmax_tag_minus2_min: Minimalwert vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num + +- minmax_tag_minus2_max: Maximalwert vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num + +- minmax_tag_minus2_avg: Durchschnittswert vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num + +- minmax_tag_minus3_min: Minimalwert heute vor 3 Tagen | Berechnung: daily | Item-Type: num + +- minmax_tag_minus3_max: Maximalwert heute vor 3 Tagen | Berechnung: daily | Item-Type: num + +- minmax_tag_minus3_avg: Durchschnittswert heute vor 3 Tagen | Berechnung: daily | Item-Type: num + +- minmax_woche_min: Minimalwert seit Wochenbeginn | Berechnung: weekly | Item-Type: num + +- minmax_woche_max: Maximalwert seit Wochenbeginn | Berechnung: weekly | Item-Type: num + +- minmax_woche_minus1_min: Minimalwert Vorwoche (aktuelle Woche -1) | Berechnung: weekly | Item-Type: num + +- minmax_woche_minus1_max: Maximalwert Vorwoche (aktuelle Woche -1) | Berechnung: weekly | Item-Type: num + +- minmax_woche_minus1_avg: Durchschnittswert Vorwoche (aktuelle Woche -1) | Berechnung: weekly | Item-Type: num + +- minmax_woche_minus2_min: Minimalwert aktuelle Woche -2 Wochen | Berechnung: weekly | Item-Type: num + +- minmax_woche_minus2_max: Maximalwert aktuelle Woche -2 Wochen | Berechnung: weekly | Item-Type: num + +- minmax_woche_minus2_avg: Durchschnittswert aktuelle Woche -2 Wochen | Berechnung: weekly | Item-Type: num + +- minmax_monat_min: Minimalwert seit Monatsbeginn | Berechnung: monthly | Item-Type: num + +- minmax_monat_max: Maximalwert seit Monatsbeginn | Berechnung: monthly | Item-Type: num + +- minmax_monat_minus1_min: Minimalwert Vormonat (aktueller Monat -1) | Berechnung: monthly | Item-Type: num + +- minmax_monat_minus1_max: Maximalwert Vormonat (aktueller Monat -1) | Berechnung: monthly | Item-Type: num + +- minmax_monat_minus1_avg: Durchschnittswert Vormonat (aktueller Monat -1) | Berechnung: monthly | Item-Type: num + +- minmax_monat_minus2_min: Minimalwert aktueller Monat -2 Monate | Berechnung: monthly | Item-Type: num + +- minmax_monat_minus2_max: Maximalwert aktueller Monat -2 Monate | Berechnung: monthly | Item-Type: num + +- minmax_monat_minus2_avg: Durchschnittswert aktueller Monat -2 Monate | Berechnung: monthly | Item-Type: num + +- minmax_jahr_min: Minimalwert seit Jahresbeginn | Berechnung: yearly | Item-Type: num + +- minmax_jahr_max: Maximalwert seit Jahresbeginn | Berechnung: yearly | Item-Type: num + +- minmax_jahr_minus1_min: Minimalwert Vorjahr (aktuelles Jahr -1 Jahr) | Berechnung: yearly | Item-Type: num + +- minmax_jahr_minus1_max: Maximalwert Vorjahr (aktuelles Jahr -1 Jahr) | Berechnung: yearly | Item-Type: num + +- minmax_jahr_minus1_avg: Durchschnittswert Vorjahr (aktuelles Jahr -1 Jahr) | Berechnung: yearly | Item-Type: num + +- tagesmitteltemperatur_heute: Tagesmitteltemperatur heute | Berechnung: daily | Item-Type: num + +- tagesmitteltemperatur_heute_minus1: Tagesmitteltemperatur des letzten Tages (heute -1 Tag) | Berechnung: daily | Item-Type: num + +- tagesmitteltemperatur_heute_minus2: Tagesmitteltemperatur des vorletzten Tages (heute -2 Tag) | Berechnung: daily | Item-Type: num + +- tagesmitteltemperatur_heute_minus3: Tagesmitteltemperatur des vorvorletzten Tages (heute -3 Tag) | Berechnung: daily | Item-Type: num + +- tagesmitteltemperatur_tag: Tagesmitteltemperatur heute | Berechnung: daily | Item-Type: num + +- tagesmitteltemperatur_tag_minus1: Tagesmitteltemperatur des letzten Tages (heute -1 Tag) | Berechnung: daily | Item-Type: num + +- tagesmitteltemperatur_tag_minus2: Tagesmitteltemperatur des vorletzten Tages (heute -2 Tag) | Berechnung: daily | Item-Type: num + +- tagesmitteltemperatur_tag_minus3: Tagesmitteltemperatur des vorvorletzten Tages (heute -3 Tag) | Berechnung: daily | Item-Type: num + +- serie_minmax_monat_min_15m: monatlicher Minimalwert der letzten 15 Monate (gleitend) | Berechnung: monthly | Item-Type: list + +- serie_minmax_monat_max_15m: monatlicher Maximalwert der letzten 15 Monate (gleitend) | Berechnung: monthly | Item-Type: list + +- serie_minmax_monat_avg_15m: monatlicher Mittelwert der letzten 15 Monate (gleitend) | Berechnung: monthly | Item-Type: list + +- serie_minmax_woche_min_30w: wöchentlicher Minimalwert der letzten 30 Wochen (gleitend) | Berechnung: weekly | Item-Type: list + +- serie_minmax_woche_max_30w: wöchentlicher Maximalwert der letzten 30 Wochen (gleitend) | Berechnung: weekly | Item-Type: list + +- serie_minmax_woche_avg_30w: wöchentlicher Mittelwert der letzten 30 Wochen (gleitend) | Berechnung: weekly | Item-Type: list + +- serie_minmax_tag_min_30d: täglicher Minimalwert der letzten 30 Tage (gleitend) | Berechnung: daily | Item-Type: list + +- serie_minmax_tag_max_30d: täglicher Maximalwert der letzten 30 Tage (gleitend) | Berechnung: daily | Item-Type: list + +- serie_minmax_tag_avg_30d: täglicher Mittelwert der letzten 30 Tage (gleitend) | Berechnung: daily | Item-Type: list + +- serie_verbrauch_tag_30d: Verbrauch pro Tag der letzten 30 Tage | Berechnung: daily | Item-Type: list + +- serie_verbrauch_woche_30w: Verbrauch pro Woche der letzten 30 Wochen | Berechnung: weekly | Item-Type: list + +- serie_verbrauch_monat_18m: Verbrauch pro Monat der letzten 18 Monate | Berechnung: monthly | Item-Type: list + +- serie_zaehlerstand_tag_30d: Zählerstand am Tagesende der letzten 30 Tage | Berechnung: daily | Item-Type: list + +- serie_zaehlerstand_woche_30w: Zählerstand am Wochenende der letzten 30 Wochen | Berechnung: weekly | Item-Type: list + +- serie_zaehlerstand_monat_18m: Zählerstand am Monatsende der letzten 18 Monate | Berechnung: monthly | Item-Type: list + +- serie_waermesumme_monat_24m: monatliche Wärmesumme der letzten 24 Monate | Berechnung: monthly | Item-Type: list + +- serie_kaeltesumme_monat_24m: monatliche Kältesumme der letzten 24 Monate | Berechnung: monthly | Item-Type: list + +- serie_tagesmittelwert_0d: Tagesmittelwert für den aktuellen Tag | Berechnung: daily | Item-Type: list + +- serie_tagesmittelwert_stunde_0d: Stundenmittelwert für den aktuellen Tag | Berechnung: daily | Item-Type: list + +- serie_tagesmittelwert_stunde_30_0d: Stundenmittelwert für den aktuellen Tag | Berechnung: daily | Item-Type: list + +- serie_tagesmittelwert_tag_stunde_30d: Stundenmittelwert pro Tag der letzten 30 Tage (bspw. zur Berechnung der Tagesmitteltemperatur basierend auf den Mittelwert der Temperatur pro Stunde | Berechnung: daily | Item-Type: list + +- general_oldest_value: Ausgabe des ältesten Wertes des entsprechenden "Parent-Items" mit database Attribut | Berechnung: None | Item-Type: num + +- general_oldest_log: Ausgabe des Timestamp des ältesten Eintrages des entsprechenden "Parent-Items" mit database Attribut | Berechnung: None | Item-Type: list + +- kaeltesumme: Berechnet die Kältesumme für einen Zeitraum, db_addon_params: (year=optional, month=optional) | Berechnung: daily | Item-Type: num + +- waermesumme: Berechnet die Wärmesumme für einen Zeitraum, db_addon_params: (year=optional, month=optional) | Berechnung: daily | Item-Type: num + +- gruenlandtempsumme: Berechnet die Grünlandtemperatursumme für einen Zeitraum, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num + +- wachstumsgradtage: Berechnet die Wachstumsgradtage auf Basis der stündlichen Durchschnittswerte eines Tages für das laufende Jahr mit an Angabe des Temperaturschwellenwertes (threshold=Schwellentemperatur) | Berechnung: daily | Item-Type: num + +- wuestentage: Berechnet die Anzahl der Wüstentage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num + +- heisse_tage: Berechnet die Anzahl der heissen Tage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num + +- tropennaechte: Berechnet die Anzahl der Tropennächte des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num + +- sommertage: Berechnet die Anzahl der Sommertage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num + +- heiztage: Berechnet die Anzahl der Heiztage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num + +- vegetationstage: Berechnet die Anzahl der Vegatationstage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num + +- frosttage: Berechnet die Anzahl der Frosttage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num + +- eistage: Berechnet die Anzahl der Eistage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num + +- tagesmitteltemperatur: Berechnet die Tagesmitteltemperatur auf Basis der stündlichen Durchschnittswerte eines Tages für die angegebene Anzahl von Tagen (timeframe=day, count=integer) | Berechnung: daily | Item-Type: list + +- db_request: Abfrage der DB: db_addon_params: (func=mandatory, item=mandatory, timespan=mandatory, start=optional, end=optional, count=optional, group=optional, group2=optional) | Berechnung: group | Item-Type: list + +- minmax: Berechnet einen min/max/avg Wert für einen bestimmen Zeitraum: db_addon_params: (func=mandatory, timeframe=mandatory, start=mandatory) | Berechnung: timeframe | Item-Type: num + +- minmax_last: 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) | Berechnung: timeframe | Item-Type: num + +- verbrauch: Berechnet einen Verbrauchswert für einen bestimmen Zeitraum: db_addon_params: (timeframe=mandatory, start=mandatory end=mandatory) | Berechnung: timeframe | Item-Type: num + +- zaehlerstand: Berechnet einen Zählerstand für einen bestimmen Zeitpunkt: db_addon_params: (timeframe=mandatory, start=mandatory) | Berechnung: timeframe | Item-Type: num + + +db_addon_info +------------- + +- db_version: Version der verbundenen Datenbank | Berechnung: no | Item-Type: str + + +db_addon_admin +-------------- + +- suspend: Unterbricht die Aktivitäten des Plugin | Berechnung: no | Item-Type: bool + +- recalc_all: Startet einen Neuberechnungslauf aller on-demand Items | Berechnung: no | Item-Type: bool + +- clean_cache_values: Löscht Plugin-Cache und damit alle im Plugin zwischengespeicherten Werte | Berechnung: no | Item-Type: bool + + +Hinweise +======== + + - Das Plugin startet die Berechnungen der Werte nach einer gewissen (konfigurierbaren) Zeit (Attribut `startup_run_delay`) + nach dem Start von shNG, um den Startvorgang nicht zu beeinflussen. + + - Bei Start werden automatisch nur die Items berechnet, für das das Attribute `db_addon_startup` gesetzt wurde. Alle anderen + Items werden erst zur konfigurierten Zeit berechnet. Das Attribute `db_addon_startup` kann auch direkt am `Database-Item` + gesetzt werden. Dabei wird das Attribut auf alle darunter liegenden `db_addon-Items` (bspw. bei Verwendung von structs) vererbt. + Über das WebIF kann die Berechnung aller definierten Items ausgelöst werden. + + - Für sogenannte `on_change` Items, also Items, deren Berechnung bis zum Jetzt (bspw. verbrauch-heute) gehen, wird die Berechnung + immer bei eintreffen eines neuen Wertes gestartet. Zu Reduktion der Belastung auf die Datenbank werden die Werte für das Ende der + letzten Periode gecached. + + - Berechnungen werden nur ausgeführt, wenn für den kompletten abgefragten Zeitraum Werte in der Datenbank vorliegen. Wird bspw. + der Verbrauch des letzten Monats abgefragt wobei erst Werte ab dem 3. des Monats in der Datenbank sind, wird die Berechnung abgebrochen. + + - Mit dem Attribut `use_oldest_entry` kann dieses Verhalten verändert werden. Ist das Attribut gesetzt, wird, wenn für den + Beginn der Abfragezeitraums keinen Werte vorliegen, der älteste Eintrag der Datenbank genutzt. + + - Für die Auswertung kann es nützlich sein, bestimmte Werte aus der Datenbank bei der Berechnung auszublenden. Hierfür stehen + 2 Möglichkeiten zur Verfügung: + - Plugin-Attribut `ignore_0`: (list of strings) Bei Items, bei denen ein String aus der Liste im Pfadnamen vorkommt, + werden 0-Werte (val_num = 0) bei Datenbankauswertungen ignoriert. Hat also das Attribut den Wert ['temp'] werden bei allen Items mit + 'temp' im Pfadnamen die 0-Werte bei der Auswertung ignoriert. + - Item-Attribut `db_addon_ignore_value`: (num) Dieser Wert wird bei der Abfrage bzw. Auswertung der Datenbank für diese + Item ignoriert. + + - Das Plugin enthält sehr ausführliche Logginginformation. Bei unerwartetem Verhalten, den LogLevel entsprechend anpassen, + um mehr information zu erhalten. + + - Berechnungen des Plugins können im WebIF unterbrochen werden. Auch das gesamte Plugin kann pausiert werden. Dies kann bei + starker Systembelastung nützlich sein. + + +Beispiele +========= + +Verbrauch +--------- + +Soll bspw. der Verbrauch von Wasser ausgewertet werden, so ist dies wie folgt möglich: + + +.. code-block:: yaml + + wasserzaehler: + zaehlerstand: + type: num + knx_dpt: 12 + knx_cache: 5/3/4 + eval: round(value/1000, 1) + database: init + struct: + - db_addon.verbrauch_1 + - db_addon.verbrauch_2 + - db_addon.zaehlerstand_1 + +Die Werte des Wasserzählerstandes werden in die Datenbank geschrieben und darauf basierend ausgewertet. Die structs +'db_addon.verbrauch_1' und 'db_addon.verbrauch_2' stellen entsprechende Items für die Verbrauchsauswerten zur Verfügung. + +minmax +------ + +Soll bspw. die minimalen und maximalen Temperaturen ausgewertet werden, kann dies so umgesetzt werden: + +.. code-block:: yaml + + temperature: + aussen: + nord: + name: Außentemp Nordseite + type: num + visu_acl: ro + knx_dpt: 9 + knx_cache: 6/5/1 + database: init + struct: + - db_addon.minmax_1 + - db_addon.minmax_2 + +Die Temperaturwerte werden in die Datenbank geschrieben und darauf basierend ausgewertet. Die structs +'db_addon.minmax_1' und 'db_addon.minmax_2' stellen entsprechende Items für die min/max Auswertung zur Verfügung. + +| + +Web Interface +============= + +Das WebIF stellt neben der Ansicht verbundener Items und deren Parameter und Werte auch Funktionen für die +Administration des Plugins bereit. + +Es stehen Button für: + +- Neuberechnung aller Items +- Abbruch eines aktiven Berechnungslaufes +- Pausieren des Plugins +- Wiederaufnahme des Plugins + +bereit. + +Achtung: Das Auslösen einer kompletten Neuberechnung aller Items kann zu einer starken Belastung der Datenbank +aufgrund vieler Leseanfragen führen. + + +db_addon Items +-------------- + +Dieser Reiter des Webinterface zeigt die Items an, für die ein DatabaseAddon Attribut konfiguriert ist. + + +db_addon Maintenance +-------------------- + +Das Webinterface zeigt detaillierte Informationen über die im Plugin verfügbaren Daten an. +Dies dient der Maintenance bzw. Fehlersuche. Dieser Tab ist nur bei Log-Level "Debug" verfügbar. + + +Erläuterungen zu Temperatursummen +================================= + + +Grünlandtemperatursumme +----------------------- + +Beim Grünland wird die Wärmesumme nach Ernst und Loeper benutzt, um den Vegetationsbeginn und somit den Termin von Düngungsmaßnahmen zu bestimmen. +Dabei erfolgt die Aufsummierung der Tagesmitteltemperaturen über 0 °C, wobei der Januar mit 0.5 und der Februar mit 0.75 gewichtet wird. +Bei einer Wärmesumme von 200 Grad ist eine Düngung angesagt. + +siehe: https://de.wikipedia.org/wiki/Gr%C3%BCnlandtemperatursumme + +Folgende Parameter sind möglich / notwendig: + + +.. code-block:: yaml + + db_addon_params: "year=current" + +- year: Jahreszahl (str oder int), für das die Berechnung ausgeführt werden soll oder "current" für aktuelles Jahr (default: 'current') + + +Wachstumsgradtag +---------------- +Der Begriff Wachstumsgradtage (WGT) ist ein Überbegriff für verschiedene Größen. +Gemeinsam ist ihnen, daß zur Berechnung eine Lufttemperatur von einem Schwellenwert subtrahiert wird. +Je nach Fragestellung und Pflanzenart werden der Schwellenwert unterschiedlich gewählt und die Temperatur unterschiedlich bestimmt. +Verfügbar sind die Berechnung über 0) "einfachen Durchschnitt der Tagestemperaturen", 1) "modifizierten Durchschnitt der Tagestemperaturen" +und 2) Anzahl der Tage, deren Mitteltempertatur oberhalb der Schwellentemperatur lag. + +siehe https://de.wikipedia.org/wiki/Wachstumsgradtag + +Folgende Parameter sind möglich / notwendig: + +.. code-block:: yaml + + db_addon_params: "year=current, method=1, threshold=10" + +- year: Jahreszahl (str oder int), für das die Berechnung ausgeführt werden soll oder "current" für aktuelles Jahr (default: 'current') +- method: 0-Berechnung über "einfachen Durchschnitt der Tagestemperaturen", 1-Berechnung über "modifizierten Durchschnitt (default: 0) +der Tagestemperaturen" 2-Anzahl der Tage, mit Mitteltempertatur oberhalb Schwellentemperatur// 10, 11 Ausgabe aus Zeitserie +- threshold: Schwellentemperatur in °C (int) (default: 10) + + +Wärmesumme +---------- + +Die Wärmesumme soll eine Aussage über den Sommer und die Pflanzenreife liefern. Es gibt keine eindeutige Definition der Größe "Wärmesumme". +Berechnet wird die Wärmesumme als Summe aller Tagesmitteltemperaturen über einem Schwellenwert ab dem 1.1. des Jahres. + +siehe https://de.wikipedia.org/wiki/W%C3%A4rmesumme + +Folgende Parameter sind möglich / notwendig: + +.. code-block:: yaml + + db_addon_params: "year=current, month=1, threshold=10" + +- year: Jahreszahl (str oder int), für das die Berechnung ausgeführt werden soll oder "current" für aktuelles Jahr (default: 'current') +- month: Monat (int) des Jahres, für das die Berechnung ausgeführt werden soll (optional) (default: None) +- threshold: Schwellentemperatur in °C (int) (default: 10) + + +Kältesumme +---------- + +Die Kältesumme soll eine Aussage über die Härte des Winters liefern. +Berechnet wird die Kältesumme als Summe aller negativen Tagesmitteltemperaturen ab dem 21.9. des Jahres bis 31.3. des Folgejahres. + +siehe https://de.wikipedia.org/wiki/K%C3%A4ltesumme + +Folgende Parameter sind möglich / notwendig: + +.. code-block:: yaml + + db_addon_params: "year=current, month=1" + +- year: Jahreszahl (str oder int), für das die Berechnung ausgeführt werden soll oder "current" für aktuelles Jahr (default: 'current') +- month: Monat (int) des Jahres, für das die Berechnung ausgeführt werden soll (optional) (default: None) + + +Tagesmitteltemperatur +--------------------- + +Die Tagesmitteltemperatur wird auf Basis der stündlichen Durchschnittswerte eines Tages (aller in der DB enthaltenen Datensätze) +für die angegebene Anzahl von Tagen (days=optional) berechnet. + + + Vorgehen bei Funktionserweiterung des Plugins bzw. Ergänzung weiterer Werte für Item-Attribute ---------------------------------------------------------------------------------------------- From d38f3ce49848d1113edaa311d12b2c26249f273e Mon Sep 17 00:00:00 2001 From: sisamiwe Date: Sun, 29 Oct 2023 18:06:57 +0100 Subject: [PATCH 15/18] DB_ADDON: - update user_doc.rst --- db_addon/user_doc.rst | 4238 +---------------------------------------- 1 file changed, 80 insertions(+), 4158 deletions(-) diff --git a/db_addon/user_doc.rst b/db_addon/user_doc.rst index c260a7336..9b501e02e 100644 --- a/db_addon/user_doc.rst +++ b/db_addon/user_doc.rst @@ -26,7 +26,7 @@ konfiguriert ist, wird dieses Item automatisch ermittelt. Bedeutet: Sind die Ite oder Kindeskinder oder Kindeskinderkinder des Items, für das das Database Attribut konfiguriert ist, wird dieses automatisch ermittelt. -Alternativ kann mit dem Attribute "db_addon_database_item" auch der absolute Pfad des Items angegeben werden, für das +Alternativ kann mit dem Attribute "db_addon_database_item" auch der absolute Pfad des Items angegeben werden, für das das Database Attribut konfiguriert ist. Bsp: @@ -68,32 +68,6 @@ Hinweis: Das Plugin selbst ist aktuell nicht multi-instance fähig. Das bedeutet des Database-Plugin abgebunden werden kann. - -Konfiguration -============= - -Diese Plugin Parameter und die Informationen zur Item-spezifischen Konfiguration des Plugins sind -unter :doc:`/plugins_doc/config/db_addon` beschrieben. - -mysql Datenbank ---------------- - -Bei Verwendung von mysql sollten einige Variablen der Datenbank angepasst werden, so dass die komplexeren Anfragen -ohne Fehler bearbeitet werden. - -Dazu folgenden Block am Ende der Datei */etc/mysql/my.cnf* einfügen bzw den existierenden ergänzen. - - -.. code-block:: bash - - [mysqld] - connect_timeout = 60 - net_read_timeout = 60 - wait_timeout = 28800 - interactive_timeout = 28800 - - - Hinweise ======== @@ -130,198 +104,35 @@ Hinweise starker Systembelastung nützlich sein. -Beispiele -========= - -Verbrauch ---------- - -Soll bspw. der Verbrauch von Wasser ausgewertet werden, so ist dies wie folgt möglich: - - -.. code-block:: yaml - - wasserzaehler: - zaehlerstand: - type: num - knx_dpt: 12 - knx_cache: 5/3/4 - eval: round(value/1000, 1) - database: init - struct: - - db_addon.verbrauch_1 - - db_addon.verbrauch_2 - - db_addon.zaehlerstand_1 +mysql Datenbank +--------------- -Die Werte des Wasserzählerstandes werden in die Datenbank geschrieben und darauf basierend ausgewertet. Die structs -'db_addon.verbrauch_1' und 'db_addon.verbrauch_2' stellen entsprechende Items für die Verbrauchsauswerten zur Verfügung. +Bei Verwendung von mysql sollten einige Variablen der Datenbank angepasst werden, so dass die komplexeren Anfragen +ohne Fehler bearbeitet werden. -minmax ------- +Dazu folgenden Block am Ende der Datei */etc/mysql/my.cnf* einfügen bzw den existierenden ergänzen. -Soll bspw. die minimalen und maximalen Temperaturen ausgewertet werden, kann dies so umgesetzt werden: -.. code-block:: yaml +.. code-block:: bash - temperature: - aussen: - nord: - name: Außentemp Nordseite - type: num - visu_acl: ro - knx_dpt: 9 - knx_cache: 6/5/1 - database: init - struct: - - db_addon.minmax_1 - - db_addon.minmax_2 + [mysqld] + connect_timeout = 60 + net_read_timeout = 60 + wait_timeout = 28800 + interactive_timeout = 28800 -Die Temperaturwerte werden in die Datenbank geschrieben und darauf basierend ausgewertet. Die structs -'db_addon.minmax_1' und 'db_addon.minmax_2' stellen entsprechende Items für die min/max Auswertung zur Verfügung. -| -Web Interface +Konfiguration ============= -Das WebIF stellt neben der Ansicht verbundener Items und deren Parameter und Werte auch Funktionen für die -Administration des Plugins bereit. - -Es stehen Button für: - -- Neuberechnung aller Items -- Abbruch eines aktiven Berechnungslaufes -- Pausieren des Plugins -- Wiederaufnahme des Plugins - -bereit. - -Achtung: Das Auslösen einer kompletten Neuberechnung aller Items kann zu einer starken Belastung der Datenbank -aufgrund vieler Leseanfragen führen. - - -db_addon Items --------------- - -Dieser Reiter des Webinterface zeigt die Items an, für die ein DatabaseAddon Attribut konfiguriert ist. - - -db_addon Maintenance --------------------- - -Das Webinterface zeigt detaillierte Informationen über die im Plugin verfügbaren Daten an. -Dies dient der Maintenance bzw. Fehlersuche. Dieser Tab ist nur bei Log-Level "Debug" verfügbar. - - -Erläuterungen zu Temperatursummen -================================= - - -Grünlandtemperatursumme ------------------------ - -Beim Grünland wird die Wärmesumme nach Ernst und Loeper benutzt, um den Vegetationsbeginn und somit den Termin von Düngungsmaßnahmen zu bestimmen. -Dabei erfolgt die Aufsummierung der Tagesmitteltemperaturen über 0 °C, wobei der Januar mit 0.5 und der Februar mit 0.75 gewichtet wird. -Bei einer Wärmesumme von 200 Grad ist eine Düngung angesagt. - -siehe: https://de.wikipedia.org/wiki/Gr%C3%BCnlandtemperatursumme - -Folgende Parameter sind möglich / notwendig: - - -.. code-block:: yaml - - db_addon_params: "year=current" - -- year: Jahreszahl (str oder int), für das die Berechnung ausgeführt werden soll oder "current" für aktuelles Jahr (default: 'current') - - -Wachstumsgradtag ----------------- -Der Begriff Wachstumsgradtage (WGT) ist ein Überbegriff für verschiedene Größen. -Gemeinsam ist ihnen, daß zur Berechnung eine Lufttemperatur von einem Schwellenwert subtrahiert wird. -Je nach Fragestellung und Pflanzenart werden der Schwellenwert unterschiedlich gewählt und die Temperatur unterschiedlich bestimmt. -Verfügbar sind die Berechnung über 0) "einfachen Durchschnitt der Tagestemperaturen", 1) "modifizierten Durchschnitt der Tagestemperaturen" -und 2) Anzahl der Tage, deren Mitteltempertatur oberhalb der Schwellentemperatur lag. - -siehe https://de.wikipedia.org/wiki/Wachstumsgradtag - -Folgende Parameter sind möglich / notwendig: - -.. code-block:: yaml - - db_addon_params: "year=current, method=1, threshold=10" - -- year: Jahreszahl (str oder int), für das die Berechnung ausgeführt werden soll oder "current" für aktuelles Jahr (default: 'current') -- method: 0-Berechnung über "einfachen Durchschnitt der Tagestemperaturen", 1-Berechnung über "modifizierten Durchschnitt (default: 0) -der Tagestemperaturen" 2-Anzahl der Tage, mit Mitteltempertatur oberhalb Schwellentemperatur// 10, 11 Ausgabe aus Zeitserie -- threshold: Schwellentemperatur in °C (int) (default: 10) - - -Wärmesumme ----------- - -Die Wärmesumme soll eine Aussage über den Sommer und die Pflanzenreife liefern. Es gibt keine eindeutige Definition der Größe "Wärmesumme". -Berechnet wird die Wärmesumme als Summe aller Tagesmitteltemperaturen über einem Schwellenwert ab dem 1.1. des Jahres. - -siehe https://de.wikipedia.org/wiki/W%C3%A4rmesumme - -Folgende Parameter sind möglich / notwendig: - -.. code-block:: yaml - - db_addon_params: "year=current, month=1, threshold=10" - -- year: Jahreszahl (str oder int), für das die Berechnung ausgeführt werden soll oder "current" für aktuelles Jahr (default: 'current') -- month: Monat (int) des Jahres, für das die Berechnung ausgeführt werden soll (optional) (default: None) -- threshold: Schwellentemperatur in °C (int) (default: 10) - - -Kältesumme ----------- - -Die Kältesumme soll eine Aussage über die Härte des Winters liefern. -Berechnet wird die Kältesumme als Summe aller negativen Tagesmitteltemperaturen ab dem 21.9. des Jahres bis 31.3. des Folgejahres. - -siehe https://de.wikipedia.org/wiki/K%C3%A4ltesumme - -Folgende Parameter sind möglich / notwendig: - -.. code-block:: yaml - - db_addon_params: "year=current, month=1" - -- year: Jahreszahl (str oder int), für das die Berechnung ausgeführt werden soll oder "current" für aktuelles Jahr (default: 'current') -- month: Monat (int) des Jahres, für das die Berechnung ausgeführt werden soll (optional) (default: None) - - -Tagesmitteltemperatur ---------------------- - -Die Tagesmitteltemperatur wird auf Basis der stündlichen Durchschnittswerte eines Tages (aller in der DB enthaltenen Datensätze) -für die angegebene Anzahl von Tagen (days=optional) berechnet. - - - -Vorgehen bei Funktionserweiterung des Plugins bzw. Ergänzung weiterer Werte für Item-Attribute ----------------------------------------------------------------------------------------------- - -Aufgrund der Vielzahl der möglichen Werte der Itemattribute, insbesondere des Itemattributes `db_addon_fct`, wurde die Erstellung/Update -der entsprechenden Teile der `plugin.yam` sowie die Erstellung der Datei `item_attributes.py`, die vom Plugin verwendet wird, automatisiert. - -Die Masterinformationen für alle Itemattribute sowie die Skripte zum Erstellen/Update der beiden Dateien sind in der -Datei `item_attributes_master.py` enthalten. - -.. important:: +Diese Plugin Parameter und die Informationen zur Item-spezifischen Konfiguration des Plugins sind +unter :doc:`/plugins_doc/config/db_addon` beschrieben. - Korrekturen, Erweiterungen etc. der Itemattribute sollten nur in der Datei `item_attributes_master.py` - im Dict der Variable `ITEM_ATTRIBUTS` vorgenommen werden. Das Ausführen der Datei `item_attributes_master.py` (main) - erstellt die `item_attributes.py` und aktualisiert die `plugin.yaml` entsprechend. -Dieses Kapitel wurde automatisch durch Ausführen des Skripts in der Datei 'item_attributes_master.py' erstellt. +Die folgenden Kapitel wurde automatisch durch Ausführen des Skripts in der Datei 'item_attributes_master.py' erstellt. Nachfolgend eine Auflistung der möglichen Attribute für das Plugin im Format: Attribute: Beschreibung | Berechnungszyklus | Item-Type - db_addon_fct ------------ @@ -656,41 +467,6 @@ db_addon_admin - clean_cache_values: Löscht Plugin-Cache und damit alle im Plugin zwischengespeicherten Werte | Berechnung: no | Item-Type: bool -Hinweise -======== - - - Das Plugin startet die Berechnungen der Werte nach einer gewissen (konfigurierbaren) Zeit (Attribut `startup_run_delay`) - nach dem Start von shNG, um den Startvorgang nicht zu beeinflussen. - - - Bei Start werden automatisch nur die Items berechnet, für das das Attribute `db_addon_startup` gesetzt wurde. Alle anderen - Items werden erst zur konfigurierten Zeit berechnet. Das Attribute `db_addon_startup` kann auch direkt am `Database-Item` - gesetzt werden. Dabei wird das Attribut auf alle darunter liegenden `db_addon-Items` (bspw. bei Verwendung von structs) vererbt. - Über das WebIF kann die Berechnung aller definierten Items ausgelöst werden. - - - Für sogenannte `on_change` Items, also Items, deren Berechnung bis zum Jetzt (bspw. verbrauch-heute) gehen, wird die Berechnung - immer bei eintreffen eines neuen Wertes gestartet. Zu Reduktion der Belastung auf die Datenbank werden die Werte für das Ende der - letzten Periode gecached. - - - Berechnungen werden nur ausgeführt, wenn für den kompletten abgefragten Zeitraum Werte in der Datenbank vorliegen. Wird bspw. - der Verbrauch des letzten Monats abgefragt wobei erst Werte ab dem 3. des Monats in der Datenbank sind, wird die Berechnung abgebrochen. - - - Mit dem Attribut `use_oldest_entry` kann dieses Verhalten verändert werden. Ist das Attribut gesetzt, wird, wenn für den - Beginn der Abfragezeitraums keinen Werte vorliegen, der älteste Eintrag der Datenbank genutzt. - - - Für die Auswertung kann es nützlich sein, bestimmte Werte aus der Datenbank bei der Berechnung auszublenden. Hierfür stehen - 2 Möglichkeiten zur Verfügung: - - Plugin-Attribut `ignore_0`: (list of strings) Bei Items, bei denen ein String aus der Liste im Pfadnamen vorkommt, - werden 0-Werte (val_num = 0) bei Datenbankauswertungen ignoriert. Hat also das Attribut den Wert ['temp'] werden bei allen Items mit - 'temp' im Pfadnamen die 0-Werte bei der Auswertung ignoriert. - - Item-Attribut `db_addon_ignore_value`: (num) Dieser Wert wird bei der Abfrage bzw. Auswertung der Datenbank für diese - Item ignoriert. - - - Das Plugin enthält sehr ausführliche Logginginformation. Bei unerwartetem Verhalten, den LogLevel entsprechend anpassen, - um mehr information zu erhalten. - - - Berechnungen des Plugins können im WebIF unterbrochen werden. Auch das gesamte Plugin kann pausiert werden. Dies kann bei - starker Systembelastung nützlich sein. - Beispiele ========= @@ -718,6 +494,7 @@ Soll bspw. der Verbrauch von Wasser ausgewertet werden, so ist dies wie folgt m Die Werte des Wasserzählerstandes werden in die Datenbank geschrieben und darauf basierend ausgewertet. Die structs 'db_addon.verbrauch_1' und 'db_addon.verbrauch_2' stellen entsprechende Items für die Verbrauchsauswerten zur Verfügung. + minmax ------ @@ -741,3953 +518,97 @@ Soll bspw. die minimalen und maximalen Temperaturen ausgewertet werden, kann die Die Temperaturwerte werden in die Datenbank geschrieben und darauf basierend ausgewertet. Die structs 'db_addon.minmax_1' und 'db_addon.minmax_2' stellen entsprechende Items für die min/max Auswertung zur Verfügung. -| -Web Interface -============= +Verwendung von eigenen Zeiträumen +--------------------------------- -Das WebIF stellt neben der Ansicht verbundener Items und deren Parameter und Werte auch Funktionen für die -Administration des Plugins bereit. +Die Verwendung vorgefertigter Attribute wie bspw "minmax_tag_minus1" bieten eine gute und einfache Möglichkeit, entsprechende Werte ermitteln zu lassen. +Mehr Möglichkeiten bieten die Attribute "minmax", "minmax_last", "zaehlerstand" und "verbrauch". Hier müssen die weiteren Parameterwerte über das Attribut +"db_addon_params_dict" oder "db_addon_params" definiert werden. -Es stehen Button für: - -- Neuberechnung aller Items -- Abbruch eines aktiven Berechnungslaufes -- Pausieren des Plugins -- Wiederaufnahme des Plugins - -bereit. - -Achtung: Das Auslösen einer kompletten Neuberechnung aller Items kann zu einer starken Belastung der Datenbank -aufgrund vieler Leseanfragen führen. - - -db_addon Items --------------- - -Dieser Reiter des Webinterface zeigt die Items an, für die ein DatabaseAddon Attribut konfiguriert ist. - - -db_addon Maintenance --------------------- - -Das Webinterface zeigt detaillierte Informationen über die im Plugin verfügbaren Daten an. -Dies dient der Maintenance bzw. Fehlersuche. Dieser Tab ist nur bei Log-Level "Debug" verfügbar. - - -Erläuterungen zu Temperatursummen -================================= - - -Grünlandtemperatursumme ------------------------ - -Beim Grünland wird die Wärmesumme nach Ernst und Loeper benutzt, um den Vegetationsbeginn und somit den Termin von Düngungsmaßnahmen zu bestimmen. -Dabei erfolgt die Aufsummierung der Tagesmitteltemperaturen über 0 °C, wobei der Januar mit 0.5 und der Februar mit 0.75 gewichtet wird. -Bei einer Wärmesumme von 200 Grad ist eine Düngung angesagt. - -siehe: https://de.wikipedia.org/wiki/Gr%C3%BCnlandtemperatursumme - -Folgende Parameter sind möglich / notwendig: - - -.. code-block:: yaml - - db_addon_params: "year=current" - -- year: Jahreszahl (str oder int), für das die Berechnung ausgeführt werden soll oder "current" für aktuelles Jahr (default: 'current') - - -Wachstumsgradtag ----------------- -Der Begriff Wachstumsgradtage (WGT) ist ein Überbegriff für verschiedene Größen. -Gemeinsam ist ihnen, daß zur Berechnung eine Lufttemperatur von einem Schwellenwert subtrahiert wird. -Je nach Fragestellung und Pflanzenart werden der Schwellenwert unterschiedlich gewählt und die Temperatur unterschiedlich bestimmt. -Verfügbar sind die Berechnung über 0) "einfachen Durchschnitt der Tagestemperaturen", 1) "modifizierten Durchschnitt der Tagestemperaturen" -und 2) Anzahl der Tage, deren Mitteltempertatur oberhalb der Schwellentemperatur lag. - -siehe https://de.wikipedia.org/wiki/Wachstumsgradtag - -Folgende Parameter sind möglich / notwendig: - -.. code-block:: yaml - - db_addon_params: "year=current, method=1, threshold=10" - -- year: Jahreszahl (str oder int), für das die Berechnung ausgeführt werden soll oder "current" für aktuelles Jahr (default: 'current') -- method: 0-Berechnung über "einfachen Durchschnitt der Tagestemperaturen", 1-Berechnung über "modifizierten Durchschnitt (default: 0) -der Tagestemperaturen" 2-Anzahl der Tage, mit Mitteltempertatur oberhalb Schwellentemperatur// 10, 11 Ausgabe aus Zeitserie -- threshold: Schwellentemperatur in °C (int) (default: 10) - - -Wärmesumme ----------- - -Die Wärmesumme soll eine Aussage über den Sommer und die Pflanzenreife liefern. Es gibt keine eindeutige Definition der Größe "Wärmesumme". -Berechnet wird die Wärmesumme als Summe aller Tagesmitteltemperaturen über einem Schwellenwert ab dem 1.1. des Jahres. - -siehe https://de.wikipedia.org/wiki/W%C3%A4rmesumme - -Folgende Parameter sind möglich / notwendig: - -.. code-block:: yaml - - db_addon_params: "year=current, month=1, threshold=10" - -- year: Jahreszahl (str oder int), für das die Berechnung ausgeführt werden soll oder "current" für aktuelles Jahr (default: 'current') -- month: Monat (int) des Jahres, für das die Berechnung ausgeführt werden soll (optional) (default: None) -- threshold: Schwellentemperatur in °C (int) (default: 10) - - -Kältesumme ----------- - -Die Kältesumme soll eine Aussage über die Härte des Winters liefern. -Berechnet wird die Kältesumme als Summe aller negativen Tagesmitteltemperaturen ab dem 21.9. des Jahres bis 31.3. des Folgejahres. - -siehe https://de.wikipedia.org/wiki/K%C3%A4ltesumme - -Folgende Parameter sind möglich / notwendig: - -.. code-block:: yaml - - db_addon_params: "year=current, month=1" - -- year: Jahreszahl (str oder int), für das die Berechnung ausgeführt werden soll oder "current" für aktuelles Jahr (default: 'current') -- month: Monat (int) des Jahres, für das die Berechnung ausgeführt werden soll (optional) (default: None) - - -Tagesmitteltemperatur ---------------------- - -Die Tagesmitteltemperatur wird auf Basis der stündlichen Durchschnittswerte eines Tages (aller in der DB enthaltenen Datensätze) -für die angegebene Anzahl von Tagen (days=optional) berechnet. - - - -Vorgehen bei Funktionserweiterung des Plugins bzw. Ergänzung weiterer Werte für Item-Attribute ----------------------------------------------------------------------------------------------- - -Aufgrund der Vielzahl der möglichen Werte der Itemattribute, insbesondere des Itemattributes `db_addon_fct`, wurde die Erstellung/Update -der entsprechenden Teile der `plugin.yam` sowie die Erstellung der Datei `item_attributes.py`, die vom Plugin verwendet wird, automatisiert. - -Die Masterinformationen für alle Itemattribute sowie die Skripte zum Erstellen/Update der beiden Dateien sind in der -Datei `item_attributes_master.py` enthalten. - -.. important:: - - Korrekturen, Erweiterungen etc. der Itemattribute sollten nur in der Datei `item_attributes_master.py` - im Dict der Variable `ITEM_ATTRIBUTS` vorgenommen werden. Das Ausführen der Datei `item_attributes_master.py` (main) - erstellt die `item_attributes.py` und aktualisiert die `plugin.yaml` entsprechend. -Dieses Kapitel wurde automatisch durch Ausführen des Skripts in der Datei 'item_attributes_master.py' erstellt. - -Nachfolgend eine Auflistung der möglichen Attribute für das Plugin im Format: Attribute: Beschreibung | Berechnungszyklus | Item-Type - - -db_addon_fct ------------- - -- verbrauch_heute: Verbrauch am heutigen Tag (Differenz zwischen aktuellem Wert und den Wert am Ende des vorherigen Tages) | Berechnung: onchange | Item-Type: num - -- verbrauch_tag: Verbrauch am heutigen Tag (Differenz zwischen aktuellem Wert und den Wert am Ende des vorherigen Tages) | Berechnung: onchange | Item-Type: num - -- verbrauch_woche: Verbrauch in der aktuellen Woche | Berechnung: onchange | Item-Type: num - -- verbrauch_monat: Verbrauch im aktuellen Monat | Berechnung: onchange | Item-Type: num - -- verbrauch_jahr: Verbrauch im aktuellen Jahr | Berechnung: onchange | Item-Type: num - -- verbrauch_last_24h: Verbrauch innerhalb letzten 24h | Berechnung: hourly | Item-Type: num - -- verbrauch_last_7d: Verbrauch innerhalb letzten 7 Tage | Berechnung: hourly | Item-Type: num - -- verbrauch_heute_minus1: Verbrauch gestern (heute -1 Tag) (Differenz zwischen Wert am Ende des gestrigen Tages und dem Wert am Ende des Tages davor) | Berechnung: daily | Item-Type: num - -- verbrauch_heute_minus2: Verbrauch vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num - -- verbrauch_heute_minus3: Verbrauch heute -3 Tage | Berechnung: daily | Item-Type: num - -- verbrauch_heute_minus4: Verbrauch heute -4 Tage | Berechnung: daily | Item-Type: num - -- verbrauch_heute_minus5: Verbrauch heute -5 Tage | Berechnung: daily | Item-Type: num - -- verbrauch_heute_minus6: Verbrauch heute -6 Tage | Berechnung: daily | Item-Type: num - -- verbrauch_heute_minus7: Verbrauch heute -7 Tage | Berechnung: daily | Item-Type: num - -- verbrauch_heute_minus8: Verbrauch heute -8 Tage | Berechnung: daily | Item-Type: num - -- verbrauch_tag_minus1: Verbrauch gestern (heute -1 Tag) (Differenz zwischen Wert am Ende des gestrigen Tages und dem Wert am Ende des Tages davor) | Berechnung: daily | Item-Type: num - -- verbrauch_tag_minus2: Verbrauch vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num - -- verbrauch_tag_minus3: Verbrauch heute -3 Tage | Berechnung: daily | Item-Type: num - -- verbrauch_tag_minus4: Verbrauch heute -4 Tage | Berechnung: daily | Item-Type: num - -- verbrauch_tag_minus5: Verbrauch heute -5 Tage | Berechnung: daily | Item-Type: num - -- verbrauch_tag_minus6: Verbrauch heute -6 Tage | Berechnung: daily | Item-Type: num - -- verbrauch_tag_minus7: Verbrauch heute -7 Tage | Berechnung: daily | Item-Type: num - -- verbrauch_tag_minus8: Verbrauch heute -8 Tage | Berechnung: daily | Item-Type: num - -- verbrauch_woche_minus1: Verbrauch Vorwoche (aktuelle Woche -1) | Berechnung: weekly | Item-Type: num - -- verbrauch_woche_minus2: Verbrauch aktuelle Woche -2 Wochen | Berechnung: weekly | Item-Type: num - -- verbrauch_woche_minus3: Verbrauch aktuelle Woche -3 Wochen | Berechnung: weekly | Item-Type: num - -- verbrauch_woche_minus4: Verbrauch aktuelle Woche -4 Wochen | Berechnung: weekly | Item-Type: num - -- verbrauch_monat_minus1: Verbrauch Vormonat (aktueller Monat -1) | Berechnung: monthly | Item-Type: num - -- verbrauch_monat_minus2: Verbrauch aktueller Monat -2 Monate | Berechnung: monthly | Item-Type: num - -- verbrauch_monat_minus3: Verbrauch aktueller Monat -3 Monate | Berechnung: monthly | Item-Type: num - -- verbrauch_monat_minus4: Verbrauch aktueller Monat -4 Monate | Berechnung: monthly | Item-Type: num - -- verbrauch_monat_minus12: Verbrauch aktueller Monat -12 Monate | Berechnung: monthly | Item-Type: num - -- verbrauch_jahr_minus1: Verbrauch Vorjahr (aktuelles Jahr -1 Jahr) | Berechnung: yearly | Item-Type: num - -- verbrauch_jahr_minus2: Verbrauch aktuelles Jahr -2 Jahre | Berechnung: yearly | Item-Type: num - -- verbrauch_rolling_12m_heute_minus1: Verbrauch der letzten 12 Monate ausgehend im Ende des letzten Tages | Berechnung: daily | Item-Type: num - -- verbrauch_rolling_12m_tag_minus1: Verbrauch der letzten 12 Monate ausgehend im Ende des letzten Tages | Berechnung: daily | Item-Type: num - -- verbrauch_rolling_12m_woche_minus1: Verbrauch der letzten 12 Monate ausgehend im Ende der letzten Woche | Berechnung: weekly | Item-Type: num - -- verbrauch_rolling_12m_monat_minus1: Verbrauch der letzten 12 Monate ausgehend im Ende des letzten Monats | Berechnung: monthly | Item-Type: num - -- verbrauch_rolling_12m_jahr_minus1: Verbrauch der letzten 12 Monate ausgehend im Ende des letzten Jahres | Berechnung: yearly | Item-Type: num - -- verbrauch_jahreszeitraum_minus1: Verbrauch seit dem 1.1. bis zum heutigen Tag des Vorjahres | Berechnung: daily | Item-Type: num - -- verbrauch_jahreszeitraum_minus2: Verbrauch seit dem 1.1. bis zum heutigen Tag vor 2 Jahren | Berechnung: daily | Item-Type: num - -- verbrauch_jahreszeitraum_minus3: Verbrauch seit dem 1.1. bis zum heutigen Tag vor 3 Jahren | Berechnung: daily | Item-Type: num - -- zaehlerstand_heute_minus1: Zählerstand / Wert am Ende des letzten Tages (heute -1 Tag) | Berechnung: daily | Item-Type: num - -- zaehlerstand_heute_minus2: Zählerstand / Wert am Ende des vorletzten Tages (heute -2 Tag) | Berechnung: daily | Item-Type: num - -- zaehlerstand_heute_minus3: Zählerstand / Wert am Ende des vorvorletzten Tages (heute -3 Tag) | Berechnung: daily | Item-Type: num - -- zaehlerstand_tag_minus1: Zählerstand / Wert am Ende des letzten Tages (heute -1 Tag) | Berechnung: daily | Item-Type: num - -- zaehlerstand_tag_minus2: Zählerstand / Wert am Ende des vorletzten Tages (heute -2 Tag) | Berechnung: daily | Item-Type: num - -- zaehlerstand_tag_minus3: Zählerstand / Wert am Ende des vorvorletzten Tages (heute -3 Tag) | Berechnung: daily | Item-Type: num - -- zaehlerstand_woche_minus1: Zählerstand / Wert am Ende der vorvorletzten Woche (aktuelle Woche -1 Woche) | Berechnung: weekly | Item-Type: num - -- zaehlerstand_woche_minus2: Zählerstand / Wert am Ende der vorletzten Woche (aktuelle Woche -2 Wochen) | Berechnung: weekly | Item-Type: num - -- zaehlerstand_woche_minus3: Zählerstand / Wert am Ende der aktuellen Woche -3 Wochen | Berechnung: weekly | Item-Type: num - -- zaehlerstand_monat_minus1: Zählerstand / Wert am Ende des letzten Monates (aktueller Monat -1 Monat) | Berechnung: monthly | Item-Type: num - -- zaehlerstand_monat_minus2: Zählerstand / Wert am Ende des vorletzten Monates (aktueller Monat -2 Monate) | Berechnung: monthly | Item-Type: num - -- zaehlerstand_monat_minus3: Zählerstand / Wert am Ende des aktuellen Monats -3 Monate | Berechnung: monthly | Item-Type: num - -- zaehlerstand_jahr_minus1: Zählerstand / Wert am Ende des letzten Jahres (aktuelles Jahr -1 Jahr) | Berechnung: yearly | Item-Type: num - -- zaehlerstand_jahr_minus2: Zählerstand / Wert am Ende des vorletzten Jahres (aktuelles Jahr -2 Jahre) | Berechnung: yearly | Item-Type: num - -- zaehlerstand_jahr_minus3: Zählerstand / Wert am Ende des aktuellen Jahres -3 Jahre | Berechnung: yearly | Item-Type: num - -- minmax_last_24h_min: minimaler Wert der letzten 24h | Berechnung: daily | Item-Type: num - -- minmax_last_24h_max: maximaler Wert der letzten 24h | Berechnung: daily | Item-Type: num - -- minmax_last_24h_avg: durchschnittlicher Wert der letzten 24h | Berechnung: daily | Item-Type: num - -- minmax_last_7d_min: minimaler Wert der letzten 7 Tage | Berechnung: daily | Item-Type: num - -- minmax_last_7d_max: maximaler Wert der letzten 7 Tage | Berechnung: daily | Item-Type: num - -- minmax_last_7d_avg: durchschnittlicher Wert der letzten 7 Tage | Berechnung: daily | Item-Type: num - -- minmax_heute_min: Minimalwert seit Tagesbeginn | Berechnung: onchange | Item-Type: num - -- minmax_heute_max: Maximalwert seit Tagesbeginn | Berechnung: onchange | Item-Type: num - -- minmax_heute_avg: Durschnittswert seit Tagesbeginn | Berechnung: onchange | Item-Type: num - -- minmax_heute_minus1_min: Minimalwert gestern (heute -1 Tag) | Berechnung: daily | Item-Type: num - -- minmax_heute_minus1_max: Maximalwert gestern (heute -1 Tag) | Berechnung: daily | Item-Type: num - -- minmax_heute_minus1_avg: Durchschnittswert gestern (heute -1 Tag) | Berechnung: daily | Item-Type: num - -- minmax_heute_minus2_min: Minimalwert vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num - -- minmax_heute_minus2_max: Maximalwert vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num - -- minmax_heute_minus2_avg: Durchschnittswert vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num - -- minmax_heute_minus3_min: Minimalwert heute vor 3 Tagen | Berechnung: daily | Item-Type: num - -- minmax_heute_minus3_max: Maximalwert heute vor 3 Tagen | Berechnung: daily | Item-Type: num - -- minmax_heute_minus3_avg: Durchschnittswert heute vor 3 Tagen | Berechnung: daily | Item-Type: num - -- minmax_tag_min: Minimalwert seit Tagesbeginn | Berechnung: onchange | Item-Type: num - -- minmax_tag_max: Maximalwert seit Tagesbeginn | Berechnung: onchange | Item-Type: num - -- minmax_tag_avg: Durschnittswert seit Tagesbeginn | Berechnung: onchange | Item-Type: num - -- minmax_tag_minus1_min: Minimalwert gestern (heute -1 Tag) | Berechnung: daily | Item-Type: num - -- minmax_tag_minus1_max: Maximalwert gestern (heute -1 Tag) | Berechnung: daily | Item-Type: num - -- minmax_tag_minus1_avg: Durchschnittswert gestern (heute -1 Tag) | Berechnung: daily | Item-Type: num - -- minmax_tag_minus2_min: Minimalwert vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num - -- minmax_tag_minus2_max: Maximalwert vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num - -- minmax_tag_minus2_avg: Durchschnittswert vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num - -- minmax_tag_minus3_min: Minimalwert heute vor 3 Tagen | Berechnung: daily | Item-Type: num - -- minmax_tag_minus3_max: Maximalwert heute vor 3 Tagen | Berechnung: daily | Item-Type: num - -- minmax_tag_minus3_avg: Durchschnittswert heute vor 3 Tagen | Berechnung: daily | Item-Type: num - -- minmax_woche_min: Minimalwert seit Wochenbeginn | Berechnung: onchange | Item-Type: num - -- minmax_woche_max: Maximalwert seit Wochenbeginn | Berechnung: onchange | Item-Type: num - -- minmax_woche_minus1_min: Minimalwert Vorwoche (aktuelle Woche -1) | Berechnung: weekly | Item-Type: num - -- minmax_woche_minus1_max: Maximalwert Vorwoche (aktuelle Woche -1) | Berechnung: weekly | Item-Type: num - -- minmax_woche_minus1_avg: Durchschnittswert Vorwoche (aktuelle Woche -1) | Berechnung: weekly | Item-Type: num - -- minmax_woche_minus2_min: Minimalwert aktuelle Woche -2 Wochen | Berechnung: weekly | Item-Type: num - -- minmax_woche_minus2_max: Maximalwert aktuelle Woche -2 Wochen | Berechnung: weekly | Item-Type: num - -- minmax_woche_minus2_avg: Durchschnittswert aktuelle Woche -2 Wochen | Berechnung: weekly | Item-Type: num - -- minmax_monat_min: Minimalwert seit Monatsbeginn | Berechnung: onchange | Item-Type: num - -- minmax_monat_max: Maximalwert seit Monatsbeginn | Berechnung: onchange | Item-Type: num - -- minmax_monat_minus1_min: Minimalwert Vormonat (aktueller Monat -1) | Berechnung: monthly | Item-Type: num - -- minmax_monat_minus1_max: Maximalwert Vormonat (aktueller Monat -1) | Berechnung: monthly | Item-Type: num - -- minmax_monat_minus1_avg: Durchschnittswert Vormonat (aktueller Monat -1) | Berechnung: monthly | Item-Type: num - -- minmax_monat_minus2_min: Minimalwert aktueller Monat -2 Monate | Berechnung: monthly | Item-Type: num - -- minmax_monat_minus2_max: Maximalwert aktueller Monat -2 Monate | Berechnung: monthly | Item-Type: num - -- minmax_monat_minus2_avg: Durchschnittswert aktueller Monat -2 Monate | Berechnung: monthly | Item-Type: num - -- minmax_jahr_min: Minimalwert seit Jahresbeginn | Berechnung: onchange | Item-Type: num - -- minmax_jahr_max: Maximalwert seit Jahresbeginn | Berechnung: onchange | Item-Type: num - -- minmax_jahr_minus1_min: Minimalwert Vorjahr (aktuelles Jahr -1 Jahr) | Berechnung: yearly | Item-Type: num - -- minmax_jahr_minus1_max: Maximalwert Vorjahr (aktuelles Jahr -1 Jahr) | Berechnung: yearly | Item-Type: num - -- minmax_jahr_minus1_avg: Durchschnittswert Vorjahr (aktuelles Jahr -1 Jahr) | Berechnung: yearly | Item-Type: num - -- tagesmitteltemperatur_heute: Tagesmitteltemperatur heute | Berechnung: onchange | Item-Type: num - -- tagesmitteltemperatur_heute_minus1: Tagesmitteltemperatur des letzten Tages (heute -1 Tag) | Berechnung: daily | Item-Type: num - -- tagesmitteltemperatur_heute_minus2: Tagesmitteltemperatur des vorletzten Tages (heute -2 Tag) | Berechnung: daily | Item-Type: num - -- tagesmitteltemperatur_heute_minus3: Tagesmitteltemperatur des vorvorletzten Tages (heute -3 Tag) | Berechnung: daily | Item-Type: num - -- tagesmitteltemperatur_tag: Tagesmitteltemperatur heute | Berechnung: onchange | Item-Type: num - -- tagesmitteltemperatur_tag_minus1: Tagesmitteltemperatur des letzten Tages (heute -1 Tag) | Berechnung: daily | Item-Type: num - -- tagesmitteltemperatur_tag_minus2: Tagesmitteltemperatur des vorletzten Tages (heute -2 Tag) | Berechnung: daily | Item-Type: num - -- tagesmitteltemperatur_tag_minus3: Tagesmitteltemperatur des vorvorletzten Tages (heute -3 Tag) | Berechnung: daily | Item-Type: num - -- serie_minmax_monat_min_15m: monatlicher Minimalwert der letzten 15 Monate (gleitend) | Berechnung: monthly | Item-Type: list - -- serie_minmax_monat_max_15m: monatlicher Maximalwert der letzten 15 Monate (gleitend) | Berechnung: monthly | Item-Type: list - -- serie_minmax_monat_avg_15m: monatlicher Mittelwert der letzten 15 Monate (gleitend) | Berechnung: monthly | Item-Type: list - -- serie_minmax_woche_min_30w: wöchentlicher Minimalwert der letzten 30 Wochen (gleitend) | Berechnung: weekly | Item-Type: list - -- serie_minmax_woche_max_30w: wöchentlicher Maximalwert der letzten 30 Wochen (gleitend) | Berechnung: weekly | Item-Type: list - -- serie_minmax_woche_avg_30w: wöchentlicher Mittelwert der letzten 30 Wochen (gleitend) | Berechnung: weekly | Item-Type: list - -- serie_minmax_tag_min_30d: täglicher Minimalwert der letzten 30 Tage (gleitend) | Berechnung: daily | Item-Type: list - -- serie_minmax_tag_max_30d: täglicher Maximalwert der letzten 30 Tage (gleitend) | Berechnung: daily | Item-Type: list - -- serie_minmax_tag_avg_30d: täglicher Mittelwert der letzten 30 Tage (gleitend) | Berechnung: daily | Item-Type: list - -- serie_verbrauch_tag_30d: Verbrauch pro Tag der letzten 30 Tage | Berechnung: daily | Item-Type: list - -- serie_verbrauch_woche_30w: Verbrauch pro Woche der letzten 30 Wochen | Berechnung: weekly | Item-Type: list - -- serie_verbrauch_monat_18m: Verbrauch pro Monat der letzten 18 Monate | Berechnung: monthly | Item-Type: list - -- serie_zaehlerstand_tag_30d: Zählerstand am Tagesende der letzten 30 Tage | Berechnung: daily | Item-Type: list - -- serie_zaehlerstand_woche_30w: Zählerstand am Wochenende der letzten 30 Wochen | Berechnung: weekly | Item-Type: list - -- serie_zaehlerstand_monat_18m: Zählerstand am Monatsende der letzten 18 Monate | Berechnung: monthly | Item-Type: list - -- serie_waermesumme_monat_24m: monatliche Wärmesumme der letzten 24 Monate | Berechnung: monthly | Item-Type: list - -- serie_kaeltesumme_monat_24m: monatliche Kältesumme der letzten 24 Monate | Berechnung: monthly | Item-Type: list - -- serie_tagesmittelwert_0d: Tagesmittelwert für den aktuellen Tag | Berechnung: daily | Item-Type: list - -- serie_tagesmittelwert_stunde_0d: Stundenmittelwert für den aktuellen Tag | Berechnung: daily | Item-Type: list - -- serie_tagesmittelwert_stunde_30_0d: Stundenmittelwert für den aktuellen Tag | Berechnung: daily | Item-Type: list - -- serie_tagesmittelwert_tag_stunde_30d: Stundenmittelwert pro Tag der letzten 30 Tage (bspw. zur Berechnung der Tagesmitteltemperatur basierend auf den Mittelwert der Temperatur pro Stunde | Berechnung: daily | Item-Type: list - -- general_oldest_value: Ausgabe des ältesten Wertes des entsprechenden "Parent-Items" mit database Attribut | Berechnung: no | Item-Type: num - -- general_oldest_log: Ausgabe des Timestamp des ältesten Eintrages des entsprechenden "Parent-Items" mit database Attribut | Berechnung: no | Item-Type: list - -- kaeltesumme: Berechnet die Kältesumme für einen Zeitraum, db_addon_params: (year=optional, month=optional) | Berechnung: daily | Item-Type: num - -- waermesumme: Berechnet die Wärmesumme für einen Zeitraum, db_addon_params: (year=optional, month=optional) | Berechnung: daily | Item-Type: num - -- gruenlandtempsumme: Berechnet die Grünlandtemperatursumme für einen Zeitraum, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num - -- wachstumsgradtage: Berechnet die Wachstumsgradtage auf Basis der stündlichen Durchschnittswerte eines Tages für das laufende Jahr mit an Angabe des Temperaturschwellenwertes (threshold=Schwellentemperatur) | Berechnung: daily | Item-Type: num - -- wuestentage: Berechnet die Anzahl der Wüstentage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num - -- heisse_tage: Berechnet die Anzahl der heissen Tage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num - -- tropennaechte: Berechnet die Anzahl der Tropennächte des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num - -- sommertage: Berechnet die Anzahl der Sommertage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num - -- heiztage: Berechnet die Anzahl der Heiztage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num - -- vegetationstage: Berechnet die Anzahl der Vegatationstage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num - -- frosttage: Berechnet die Anzahl der Frosttage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num - -- eistage: Berechnet die Anzahl der Eistage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num - -- tagesmitteltemperatur: Berechnet die Tagesmitteltemperatur auf Basis der stündlichen Durchschnittswerte eines Tages für die angegebene Anzahl von Tagen (timeframe=day, count=integer) | Berechnung: daily | Item-Type: list - -- db_request: Abfrage der DB: db_addon_params: (func=mandatory, item=mandatory, timespan=mandatory, start=optional, end=optional, count=optional, group=optional, group2=optional) | Berechnung: group | Item-Type: list - -- minmax: Berechnet einen min/max/avg Wert für einen bestimmen Zeitraum: db_addon_params: (func=mandatory, timeframe=mandatory, start=mandatory) | Berechnung: timeframe | Item-Type: num - -- minmax_last: 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) | Berechnung: timeframe | Item-Type: num - -- verbrauch: Berechnet einen Verbrauchswert für einen bestimmen Zeitraum: db_addon_params: (timeframe=mandatory, start=mandatory end=mandatory) | Berechnung: timeframe | Item-Type: num - -- zaehlerstand: Berechnet einen Zählerstand für einen bestimmen Zeitpunkt: db_addon_params: (timeframe=mandatory, start=mandatory) | Berechnung: timeframe | Item-Type: num - - -db_addon_info -------------- - -- db_version: Version der verbundenen Datenbank | Berechnung: no | Item-Type: str - - -db_addon_admin --------------- - -- suspend: Unterbricht die Aktivitäten des Plugin | Berechnung: no | Item-Type: bool - -- recalc_all: Startet einen Neuberechnungslauf aller on-demand Items | Berechnung: no | Item-Type: bool - -- clean_cache_values: Löscht Plugin-Cache und damit alle im Plugin zwischengespeicherten Werte | Berechnung: no | Item-Type: bool - - -Hinweise -======== - - - Das Plugin startet die Berechnungen der Werte nach einer gewissen (konfigurierbaren) Zeit (Attribut `startup_run_delay`) - nach dem Start von shNG, um den Startvorgang nicht zu beeinflussen. - - - Bei Start werden automatisch nur die Items berechnet, für das das Attribute `db_addon_startup` gesetzt wurde. Alle anderen - Items werden erst zur konfigurierten Zeit berechnet. Das Attribute `db_addon_startup` kann auch direkt am `Database-Item` - gesetzt werden. Dabei wird das Attribut auf alle darunter liegenden `db_addon-Items` (bspw. bei Verwendung von structs) vererbt. - Über das WebIF kann die Berechnung aller definierten Items ausgelöst werden. - - - Für sogenannte `on_change` Items, also Items, deren Berechnung bis zum Jetzt (bspw. verbrauch-heute) gehen, wird die Berechnung - immer bei eintreffen eines neuen Wertes gestartet. Zu Reduktion der Belastung auf die Datenbank werden die Werte für das Ende der - letzten Periode gecached. - - - Berechnungen werden nur ausgeführt, wenn für den kompletten abgefragten Zeitraum Werte in der Datenbank vorliegen. Wird bspw. - der Verbrauch des letzten Monats abgefragt wobei erst Werte ab dem 3. des Monats in der Datenbank sind, wird die Berechnung abgebrochen. - - - Mit dem Attribut `use_oldest_entry` kann dieses Verhalten verändert werden. Ist das Attribut gesetzt, wird, wenn für den - Beginn der Abfragezeitraums keinen Werte vorliegen, der älteste Eintrag der Datenbank genutzt. - - - Für die Auswertung kann es nützlich sein, bestimmte Werte aus der Datenbank bei der Berechnung auszublenden. Hierfür stehen - 2 Möglichkeiten zur Verfügung: - - Plugin-Attribut `ignore_0`: (list of strings) Bei Items, bei denen ein String aus der Liste im Pfadnamen vorkommt, - werden 0-Werte (val_num = 0) bei Datenbankauswertungen ignoriert. Hat also das Attribut den Wert ['temp'] werden bei allen Items mit - 'temp' im Pfadnamen die 0-Werte bei der Auswertung ignoriert. - - Item-Attribut `db_addon_ignore_value`: (num) Dieser Wert wird bei der Abfrage bzw. Auswertung der Datenbank für diese - Item ignoriert. - - - Das Plugin enthält sehr ausführliche Logginginformation. Bei unerwartetem Verhalten, den LogLevel entsprechend anpassen, - um mehr information zu erhalten. - - - Berechnungen des Plugins können im WebIF unterbrochen werden. Auch das gesamte Plugin kann pausiert werden. Dies kann bei - starker Systembelastung nützlich sein. - - -Beispiele -========= - -Verbrauch ---------- - -Soll bspw. der Verbrauch von Wasser ausgewertet werden, so ist dies wie folgt möglich: - - -.. code-block:: yaml - - wasserzaehler: - zaehlerstand: - type: num - knx_dpt: 12 - knx_cache: 5/3/4 - eval: round(value/1000, 1) - database: init - struct: - - db_addon.verbrauch_1 - - db_addon.verbrauch_2 - - db_addon.zaehlerstand_1 - -Die Werte des Wasserzählerstandes werden in die Datenbank geschrieben und darauf basierend ausgewertet. Die structs -'db_addon.verbrauch_1' und 'db_addon.verbrauch_2' stellen entsprechende Items für die Verbrauchsauswerten zur Verfügung. - -minmax ------- - -Soll bspw. die minimalen und maximalen Temperaturen ausgewertet werden, kann dies so umgesetzt werden: - -.. code-block:: yaml - - temperature: - aussen: - nord: - name: Außentemp Nordseite - type: num - visu_acl: ro - knx_dpt: 9 - knx_cache: 6/5/1 - database: init - struct: - - db_addon.minmax_1 - - db_addon.minmax_2 - -Die Temperaturwerte werden in die Datenbank geschrieben und darauf basierend ausgewertet. Die structs -'db_addon.minmax_1' und 'db_addon.minmax_2' stellen entsprechende Items für die min/max Auswertung zur Verfügung. - -| - -Web Interface -============= - -Das WebIF stellt neben der Ansicht verbundener Items und deren Parameter und Werte auch Funktionen für die -Administration des Plugins bereit. - -Es stehen Button für: - -- Neuberechnung aller Items -- Abbruch eines aktiven Berechnungslaufes -- Pausieren des Plugins -- Wiederaufnahme des Plugins - -bereit. - -Achtung: Das Auslösen einer kompletten Neuberechnung aller Items kann zu einer starken Belastung der Datenbank -aufgrund vieler Leseanfragen führen. - - -db_addon Items --------------- - -Dieser Reiter des Webinterface zeigt die Items an, für die ein DatabaseAddon Attribut konfiguriert ist. - - -db_addon Maintenance --------------------- - -Das Webinterface zeigt detaillierte Informationen über die im Plugin verfügbaren Daten an. -Dies dient der Maintenance bzw. Fehlersuche. Dieser Tab ist nur bei Log-Level "Debug" verfügbar. - - -Erläuterungen zu Temperatursummen -================================= - - -Grünlandtemperatursumme ------------------------ - -Beim Grünland wird die Wärmesumme nach Ernst und Loeper benutzt, um den Vegetationsbeginn und somit den Termin von Düngungsmaßnahmen zu bestimmen. -Dabei erfolgt die Aufsummierung der Tagesmitteltemperaturen über 0 °C, wobei der Januar mit 0.5 und der Februar mit 0.75 gewichtet wird. -Bei einer Wärmesumme von 200 Grad ist eine Düngung angesagt. - -siehe: https://de.wikipedia.org/wiki/Gr%C3%BCnlandtemperatursumme - -Folgende Parameter sind möglich / notwendig: - - -.. code-block:: yaml - - db_addon_params: "year=current" - -- year: Jahreszahl (str oder int), für das die Berechnung ausgeführt werden soll oder "current" für aktuelles Jahr (default: 'current') - - -Wachstumsgradtag ----------------- -Der Begriff Wachstumsgradtage (WGT) ist ein Überbegriff für verschiedene Größen. -Gemeinsam ist ihnen, daß zur Berechnung eine Lufttemperatur von einem Schwellenwert subtrahiert wird. -Je nach Fragestellung und Pflanzenart werden der Schwellenwert unterschiedlich gewählt und die Temperatur unterschiedlich bestimmt. -Verfügbar sind die Berechnung über 0) "einfachen Durchschnitt der Tagestemperaturen", 1) "modifizierten Durchschnitt der Tagestemperaturen" -und 2) Anzahl der Tage, deren Mitteltempertatur oberhalb der Schwellentemperatur lag. - -siehe https://de.wikipedia.org/wiki/Wachstumsgradtag - -Folgende Parameter sind möglich / notwendig: - -.. code-block:: yaml - - db_addon_params: "year=current, method=1, threshold=10" - -- year: Jahreszahl (str oder int), für das die Berechnung ausgeführt werden soll oder "current" für aktuelles Jahr (default: 'current') -- method: 0-Berechnung über "einfachen Durchschnitt der Tagestemperaturen", 1-Berechnung über "modifizierten Durchschnitt (default: 0) -der Tagestemperaturen" 2-Anzahl der Tage, mit Mitteltempertatur oberhalb Schwellentemperatur// 10, 11 Ausgabe aus Zeitserie -- threshold: Schwellentemperatur in °C (int) (default: 10) - - -Wärmesumme ----------- - -Die Wärmesumme soll eine Aussage über den Sommer und die Pflanzenreife liefern. Es gibt keine eindeutige Definition der Größe "Wärmesumme". -Berechnet wird die Wärmesumme als Summe aller Tagesmitteltemperaturen über einem Schwellenwert ab dem 1.1. des Jahres. - -siehe https://de.wikipedia.org/wiki/W%C3%A4rmesumme - -Folgende Parameter sind möglich / notwendig: - -.. code-block:: yaml - - db_addon_params: "year=current, month=1, threshold=10" - -- year: Jahreszahl (str oder int), für das die Berechnung ausgeführt werden soll oder "current" für aktuelles Jahr (default: 'current') -- month: Monat (int) des Jahres, für das die Berechnung ausgeführt werden soll (optional) (default: None) -- threshold: Schwellentemperatur in °C (int) (default: 10) - - -Kältesumme ----------- - -Die Kältesumme soll eine Aussage über die Härte des Winters liefern. -Berechnet wird die Kältesumme als Summe aller negativen Tagesmitteltemperaturen ab dem 21.9. des Jahres bis 31.3. des Folgejahres. - -siehe https://de.wikipedia.org/wiki/K%C3%A4ltesumme - -Folgende Parameter sind möglich / notwendig: - -.. code-block:: yaml - - db_addon_params: "year=current, month=1" - -- year: Jahreszahl (str oder int), für das die Berechnung ausgeführt werden soll oder "current" für aktuelles Jahr (default: 'current') -- month: Monat (int) des Jahres, für das die Berechnung ausgeführt werden soll (optional) (default: None) - - -Tagesmitteltemperatur ---------------------- - -Die Tagesmitteltemperatur wird auf Basis der stündlichen Durchschnittswerte eines Tages (aller in der DB enthaltenen Datensätze) -für die angegebene Anzahl von Tagen (days=optional) berechnet. - - - -Vorgehen bei Funktionserweiterung des Plugins bzw. Ergänzung weiterer Werte für Item-Attribute ----------------------------------------------------------------------------------------------- - -Aufgrund der Vielzahl der möglichen Werte der Itemattribute, insbesondere des Itemattributes `db_addon_fct`, wurde die Erstellung/Update -der entsprechenden Teile der `plugin.yam` sowie die Erstellung der Datei `item_attributes.py`, die vom Plugin verwendet wird, automatisiert. - -Die Masterinformationen für alle Itemattribute sowie die Skripte zum Erstellen/Update der beiden Dateien sind in der -Datei `item_attributes_master.py` enthalten. - -.. important:: - - Korrekturen, Erweiterungen etc. der Itemattribute sollten nur in der Datei `item_attributes_master.py` - im Dict der Variable `ITEM_ATTRIBUTS` vorgenommen werden. Das Ausführen der Datei `item_attributes_master.py` (main) - erstellt die `item_attributes.py` und aktualisiert die `plugin.yaml` entsprechend. -Dieses Kapitel wurde automatisch durch Ausführen des Skripts in der Datei 'item_attributes_master.py' erstellt. - -Nachfolgend eine Auflistung der möglichen Attribute für das Plugin im Format: Attribute: Beschreibung | Berechnungszyklus | Item-Type - - -db_addon_fct ------------- - -- verbrauch_heute: Verbrauch am heutigen Tag (Differenz zwischen aktuellem Wert und den Wert am Ende des vorherigen Tages) | Berechnung: onchange | Item-Type: num - -- verbrauch_tag: Verbrauch am heutigen Tag (Differenz zwischen aktuellem Wert und den Wert am Ende des vorherigen Tages) | Berechnung: onchange | Item-Type: num - -- verbrauch_woche: Verbrauch in der aktuellen Woche | Berechnung: onchange | Item-Type: num - -- verbrauch_monat: Verbrauch im aktuellen Monat | Berechnung: onchange | Item-Type: num - -- verbrauch_jahr: Verbrauch im aktuellen Jahr | Berechnung: onchange | Item-Type: num - -- verbrauch_last_24h: Verbrauch innerhalb letzten 24h | Berechnung: hourly | Item-Type: num - -- verbrauch_last_7d: Verbrauch innerhalb letzten 7 Tage | Berechnung: hourly | Item-Type: num - -- verbrauch_heute_minus1: Verbrauch gestern (heute -1 Tag) (Differenz zwischen Wert am Ende des gestrigen Tages und dem Wert am Ende des Tages davor) | Berechnung: daily | Item-Type: num - -- verbrauch_heute_minus2: Verbrauch vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num - -- verbrauch_heute_minus3: Verbrauch heute -3 Tage | Berechnung: daily | Item-Type: num - -- verbrauch_heute_minus4: Verbrauch heute -4 Tage | Berechnung: daily | Item-Type: num - -- verbrauch_heute_minus5: Verbrauch heute -5 Tage | Berechnung: daily | Item-Type: num - -- verbrauch_heute_minus6: Verbrauch heute -6 Tage | Berechnung: daily | Item-Type: num - -- verbrauch_heute_minus7: Verbrauch heute -7 Tage | Berechnung: daily | Item-Type: num - -- verbrauch_heute_minus8: Verbrauch heute -8 Tage | Berechnung: daily | Item-Type: num - -- verbrauch_tag_minus1: Verbrauch gestern (heute -1 Tag) (Differenz zwischen Wert am Ende des gestrigen Tages und dem Wert am Ende des Tages davor) | Berechnung: daily | Item-Type: num - -- verbrauch_tag_minus2: Verbrauch vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num - -- verbrauch_tag_minus3: Verbrauch heute -3 Tage | Berechnung: daily | Item-Type: num - -- verbrauch_tag_minus4: Verbrauch heute -4 Tage | Berechnung: daily | Item-Type: num - -- verbrauch_tag_minus5: Verbrauch heute -5 Tage | Berechnung: daily | Item-Type: num - -- verbrauch_tag_minus6: Verbrauch heute -6 Tage | Berechnung: daily | Item-Type: num - -- verbrauch_tag_minus7: Verbrauch heute -7 Tage | Berechnung: daily | Item-Type: num - -- verbrauch_tag_minus8: Verbrauch heute -8 Tage | Berechnung: daily | Item-Type: num - -- verbrauch_woche_minus1: Verbrauch Vorwoche (aktuelle Woche -1) | Berechnung: weekly | Item-Type: num - -- verbrauch_woche_minus2: Verbrauch aktuelle Woche -2 Wochen | Berechnung: weekly | Item-Type: num - -- verbrauch_woche_minus3: Verbrauch aktuelle Woche -3 Wochen | Berechnung: weekly | Item-Type: num - -- verbrauch_woche_minus4: Verbrauch aktuelle Woche -4 Wochen | Berechnung: weekly | Item-Type: num - -- verbrauch_monat_minus1: Verbrauch Vormonat (aktueller Monat -1) | Berechnung: monthly | Item-Type: num - -- verbrauch_monat_minus2: Verbrauch aktueller Monat -2 Monate | Berechnung: monthly | Item-Type: num - -- verbrauch_monat_minus3: Verbrauch aktueller Monat -3 Monate | Berechnung: monthly | Item-Type: num - -- verbrauch_monat_minus4: Verbrauch aktueller Monat -4 Monate | Berechnung: monthly | Item-Type: num - -- verbrauch_monat_minus12: Verbrauch aktueller Monat -12 Monate | Berechnung: monthly | Item-Type: num - -- verbrauch_jahr_minus1: Verbrauch Vorjahr (aktuelles Jahr -1 Jahr) | Berechnung: yearly | Item-Type: num - -- verbrauch_jahr_minus2: Verbrauch aktuelles Jahr -2 Jahre | Berechnung: yearly | Item-Type: num - -- verbrauch_jahr_minus3: Verbrauch aktuelles Jahr -3 Jahre | Berechnung: yearly | Item-Type: num - -- verbrauch_rolling_12m_heute_minus1: Verbrauch der letzten 12 Monate ausgehend im Ende des letzten Tages | Berechnung: daily | Item-Type: num - -- verbrauch_rolling_12m_tag_minus1: Verbrauch der letzten 12 Monate ausgehend im Ende des letzten Tages | Berechnung: daily | Item-Type: num - -- verbrauch_rolling_12m_woche_minus1: Verbrauch der letzten 12 Monate ausgehend im Ende der letzten Woche | Berechnung: weekly | Item-Type: num - -- verbrauch_rolling_12m_monat_minus1: Verbrauch der letzten 12 Monate ausgehend im Ende des letzten Monats | Berechnung: monthly | Item-Type: num - -- verbrauch_rolling_12m_jahr_minus1: Verbrauch der letzten 12 Monate ausgehend im Ende des letzten Jahres | Berechnung: yearly | Item-Type: num - -- verbrauch_jahreszeitraum_minus1: Verbrauch seit dem 1.1. bis zum heutigen Tag des Vorjahres | Berechnung: daily | Item-Type: num - -- verbrauch_jahreszeitraum_minus2: Verbrauch seit dem 1.1. bis zum heutigen Tag vor 2 Jahren | Berechnung: daily | Item-Type: num - -- verbrauch_jahreszeitraum_minus3: Verbrauch seit dem 1.1. bis zum heutigen Tag vor 3 Jahren | Berechnung: daily | Item-Type: num - -- zaehlerstand_heute_minus1: Zählerstand / Wert am Ende des letzten Tages (heute -1 Tag) | Berechnung: daily | Item-Type: num - -- zaehlerstand_heute_minus2: Zählerstand / Wert am Ende des vorletzten Tages (heute -2 Tag) | Berechnung: daily | Item-Type: num - -- zaehlerstand_heute_minus3: Zählerstand / Wert am Ende des vorvorletzten Tages (heute -3 Tag) | Berechnung: daily | Item-Type: num - -- zaehlerstand_tag_minus1: Zählerstand / Wert am Ende des letzten Tages (heute -1 Tag) | Berechnung: daily | Item-Type: num - -- zaehlerstand_tag_minus2: Zählerstand / Wert am Ende des vorletzten Tages (heute -2 Tag) | Berechnung: daily | Item-Type: num - -- zaehlerstand_tag_minus3: Zählerstand / Wert am Ende des vorvorletzten Tages (heute -3 Tag) | Berechnung: daily | Item-Type: num - -- zaehlerstand_woche_minus1: Zählerstand / Wert am Ende der vorvorletzten Woche (aktuelle Woche -1 Woche) | Berechnung: weekly | Item-Type: num - -- zaehlerstand_woche_minus2: Zählerstand / Wert am Ende der vorletzten Woche (aktuelle Woche -2 Wochen) | Berechnung: weekly | Item-Type: num - -- zaehlerstand_woche_minus3: Zählerstand / Wert am Ende der aktuellen Woche -3 Wochen | Berechnung: weekly | Item-Type: num - -- zaehlerstand_monat_minus1: Zählerstand / Wert am Ende des letzten Monates (aktueller Monat -1 Monat) | Berechnung: monthly | Item-Type: num - -- zaehlerstand_monat_minus2: Zählerstand / Wert am Ende des vorletzten Monates (aktueller Monat -2 Monate) | Berechnung: monthly | Item-Type: num - -- zaehlerstand_monat_minus3: Zählerstand / Wert am Ende des aktuellen Monats -3 Monate | Berechnung: monthly | Item-Type: num - -- zaehlerstand_jahr_minus1: Zählerstand / Wert am Ende des letzten Jahres (aktuelles Jahr -1 Jahr) | Berechnung: yearly | Item-Type: num - -- zaehlerstand_jahr_minus2: Zählerstand / Wert am Ende des vorletzten Jahres (aktuelles Jahr -2 Jahre) | Berechnung: yearly | Item-Type: num - -- zaehlerstand_jahr_minus3: Zählerstand / Wert am Ende des aktuellen Jahres -3 Jahre | Berechnung: yearly | Item-Type: num - -- minmax_last_24h_min: minimaler Wert der letzten 24h | Berechnung: daily | Item-Type: num - -- minmax_last_24h_max: maximaler Wert der letzten 24h | Berechnung: daily | Item-Type: num - -- minmax_last_24h_avg: durchschnittlicher Wert der letzten 24h | Berechnung: daily | Item-Type: num - -- minmax_last_7d_min: minimaler Wert der letzten 7 Tage | Berechnung: daily | Item-Type: num - -- minmax_last_7d_max: maximaler Wert der letzten 7 Tage | Berechnung: daily | Item-Type: num - -- minmax_last_7d_avg: durchschnittlicher Wert der letzten 7 Tage | Berechnung: daily | Item-Type: num - -- minmax_heute_min: Minimalwert seit Tagesbeginn | Berechnung: onchange | Item-Type: num - -- minmax_heute_max: Maximalwert seit Tagesbeginn | Berechnung: onchange | Item-Type: num - -- minmax_heute_avg: Durschnittswert seit Tagesbeginn | Berechnung: onchange | Item-Type: num - -- minmax_heute_minus1_min: Minimalwert gestern (heute -1 Tag) | Berechnung: daily | Item-Type: num - -- minmax_heute_minus1_max: Maximalwert gestern (heute -1 Tag) | Berechnung: daily | Item-Type: num - -- minmax_heute_minus1_avg: Durchschnittswert gestern (heute -1 Tag) | Berechnung: daily | Item-Type: num - -- minmax_heute_minus2_min: Minimalwert vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num - -- minmax_heute_minus2_max: Maximalwert vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num - -- minmax_heute_minus2_avg: Durchschnittswert vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num - -- minmax_heute_minus3_min: Minimalwert heute vor 3 Tagen | Berechnung: daily | Item-Type: num - -- minmax_heute_minus3_max: Maximalwert heute vor 3 Tagen | Berechnung: daily | Item-Type: num - -- minmax_heute_minus3_avg: Durchschnittswert heute vor 3 Tagen | Berechnung: daily | Item-Type: num - -- minmax_tag_min: Minimalwert seit Tagesbeginn | Berechnung: onchange | Item-Type: num - -- minmax_tag_max: Maximalwert seit Tagesbeginn | Berechnung: onchange | Item-Type: num - -- minmax_tag_avg: Durschnittswert seit Tagesbeginn | Berechnung: onchange | Item-Type: num - -- minmax_tag_minus1_min: Minimalwert gestern (heute -1 Tag) | Berechnung: daily | Item-Type: num - -- minmax_tag_minus1_max: Maximalwert gestern (heute -1 Tag) | Berechnung: daily | Item-Type: num - -- minmax_tag_minus1_avg: Durchschnittswert gestern (heute -1 Tag) | Berechnung: daily | Item-Type: num - -- minmax_tag_minus2_min: Minimalwert vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num - -- minmax_tag_minus2_max: Maximalwert vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num - -- minmax_tag_minus2_avg: Durchschnittswert vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num - -- minmax_tag_minus3_min: Minimalwert heute vor 3 Tagen | Berechnung: daily | Item-Type: num - -- minmax_tag_minus3_max: Maximalwert heute vor 3 Tagen | Berechnung: daily | Item-Type: num - -- minmax_tag_minus3_avg: Durchschnittswert heute vor 3 Tagen | Berechnung: daily | Item-Type: num - -- minmax_woche_min: Minimalwert seit Wochenbeginn | Berechnung: onchange | Item-Type: num - -- minmax_woche_max: Maximalwert seit Wochenbeginn | Berechnung: onchange | Item-Type: num - -- minmax_woche_minus1_min: Minimalwert Vorwoche (aktuelle Woche -1) | Berechnung: weekly | Item-Type: num - -- minmax_woche_minus1_max: Maximalwert Vorwoche (aktuelle Woche -1) | Berechnung: weekly | Item-Type: num - -- minmax_woche_minus1_avg: Durchschnittswert Vorwoche (aktuelle Woche -1) | Berechnung: weekly | Item-Type: num - -- minmax_woche_minus2_min: Minimalwert aktuelle Woche -2 Wochen | Berechnung: weekly | Item-Type: num - -- minmax_woche_minus2_max: Maximalwert aktuelle Woche -2 Wochen | Berechnung: weekly | Item-Type: num - -- minmax_woche_minus2_avg: Durchschnittswert aktuelle Woche -2 Wochen | Berechnung: weekly | Item-Type: num - -- minmax_monat_min: Minimalwert seit Monatsbeginn | Berechnung: onchange | Item-Type: num - -- minmax_monat_max: Maximalwert seit Monatsbeginn | Berechnung: onchange | Item-Type: num - -- minmax_monat_minus1_min: Minimalwert Vormonat (aktueller Monat -1) | Berechnung: monthly | Item-Type: num - -- minmax_monat_minus1_max: Maximalwert Vormonat (aktueller Monat -1) | Berechnung: monthly | Item-Type: num - -- minmax_monat_minus1_avg: Durchschnittswert Vormonat (aktueller Monat -1) | Berechnung: monthly | Item-Type: num - -- minmax_monat_minus2_min: Minimalwert aktueller Monat -2 Monate | Berechnung: monthly | Item-Type: num - -- minmax_monat_minus2_max: Maximalwert aktueller Monat -2 Monate | Berechnung: monthly | Item-Type: num - -- minmax_monat_minus2_avg: Durchschnittswert aktueller Monat -2 Monate | Berechnung: monthly | Item-Type: num - -- minmax_jahr_min: Minimalwert seit Jahresbeginn | Berechnung: onchange | Item-Type: num - -- minmax_jahr_max: Maximalwert seit Jahresbeginn | Berechnung: onchange | Item-Type: num - -- minmax_jahr_minus1_min: Minimalwert Vorjahr (aktuelles Jahr -1 Jahr) | Berechnung: yearly | Item-Type: num - -- minmax_jahr_minus1_max: Maximalwert Vorjahr (aktuelles Jahr -1 Jahr) | Berechnung: yearly | Item-Type: num - -- minmax_jahr_minus1_avg: Durchschnittswert Vorjahr (aktuelles Jahr -1 Jahr) | Berechnung: yearly | Item-Type: num - -- tagesmitteltemperatur_heute: Tagesmitteltemperatur heute | Berechnung: onchange | Item-Type: num - -- tagesmitteltemperatur_heute_minus1: Tagesmitteltemperatur des letzten Tages (heute -1 Tag) | Berechnung: daily | Item-Type: num - -- tagesmitteltemperatur_heute_minus2: Tagesmitteltemperatur des vorletzten Tages (heute -2 Tag) | Berechnung: daily | Item-Type: num - -- tagesmitteltemperatur_heute_minus3: Tagesmitteltemperatur des vorvorletzten Tages (heute -3 Tag) | Berechnung: daily | Item-Type: num - -- tagesmitteltemperatur_tag: Tagesmitteltemperatur heute | Berechnung: onchange | Item-Type: num - -- tagesmitteltemperatur_tag_minus1: Tagesmitteltemperatur des letzten Tages (heute -1 Tag) | Berechnung: daily | Item-Type: num - -- tagesmitteltemperatur_tag_minus2: Tagesmitteltemperatur des vorletzten Tages (heute -2 Tag) | Berechnung: daily | Item-Type: num - -- tagesmitteltemperatur_tag_minus3: Tagesmitteltemperatur des vorvorletzten Tages (heute -3 Tag) | Berechnung: daily | Item-Type: num - -- serie_minmax_monat_min_15m: monatlicher Minimalwert der letzten 15 Monate (gleitend) | Berechnung: monthly | Item-Type: list - -- serie_minmax_monat_max_15m: monatlicher Maximalwert der letzten 15 Monate (gleitend) | Berechnung: monthly | Item-Type: list - -- serie_minmax_monat_avg_15m: monatlicher Mittelwert der letzten 15 Monate (gleitend) | Berechnung: monthly | Item-Type: list - -- serie_minmax_woche_min_30w: wöchentlicher Minimalwert der letzten 30 Wochen (gleitend) | Berechnung: weekly | Item-Type: list - -- serie_minmax_woche_max_30w: wöchentlicher Maximalwert der letzten 30 Wochen (gleitend) | Berechnung: weekly | Item-Type: list - -- serie_minmax_woche_avg_30w: wöchentlicher Mittelwert der letzten 30 Wochen (gleitend) | Berechnung: weekly | Item-Type: list - -- serie_minmax_tag_min_30d: täglicher Minimalwert der letzten 30 Tage (gleitend) | Berechnung: daily | Item-Type: list - -- serie_minmax_tag_max_30d: täglicher Maximalwert der letzten 30 Tage (gleitend) | Berechnung: daily | Item-Type: list - -- serie_minmax_tag_avg_30d: täglicher Mittelwert der letzten 30 Tage (gleitend) | Berechnung: daily | Item-Type: list - -- serie_verbrauch_tag_30d: Verbrauch pro Tag der letzten 30 Tage | Berechnung: daily | Item-Type: list - -- serie_verbrauch_woche_30w: Verbrauch pro Woche der letzten 30 Wochen | Berechnung: weekly | Item-Type: list - -- serie_verbrauch_monat_18m: Verbrauch pro Monat der letzten 18 Monate | Berechnung: monthly | Item-Type: list - -- serie_zaehlerstand_tag_30d: Zählerstand am Tagesende der letzten 30 Tage | Berechnung: daily | Item-Type: list - -- serie_zaehlerstand_woche_30w: Zählerstand am Wochenende der letzten 30 Wochen | Berechnung: weekly | Item-Type: list - -- serie_zaehlerstand_monat_18m: Zählerstand am Monatsende der letzten 18 Monate | Berechnung: monthly | Item-Type: list - -- serie_waermesumme_monat_24m: monatliche Wärmesumme der letzten 24 Monate | Berechnung: monthly | Item-Type: list - -- serie_kaeltesumme_monat_24m: monatliche Kältesumme der letzten 24 Monate | Berechnung: monthly | Item-Type: list - -- serie_tagesmittelwert_0d: Tagesmittelwert für den aktuellen Tag | Berechnung: daily | Item-Type: list - -- serie_tagesmittelwert_stunde_0d: Stundenmittelwert für den aktuellen Tag | Berechnung: daily | Item-Type: list - -- serie_tagesmittelwert_stunde_30_0d: Stundenmittelwert für den aktuellen Tag | Berechnung: daily | Item-Type: list - -- serie_tagesmittelwert_tag_stunde_30d: Stundenmittelwert pro Tag der letzten 30 Tage (bspw. zur Berechnung der Tagesmitteltemperatur basierend auf den Mittelwert der Temperatur pro Stunde | Berechnung: daily | Item-Type: list - -- general_oldest_value: Ausgabe des ältesten Wertes des entsprechenden "Parent-Items" mit database Attribut | Berechnung: no | Item-Type: num - -- general_oldest_log: Ausgabe des Timestamp des ältesten Eintrages des entsprechenden "Parent-Items" mit database Attribut | Berechnung: no | Item-Type: list - -- kaeltesumme: Berechnet die Kältesumme für einen Zeitraum, db_addon_params: (year=optional, month=optional) | Berechnung: daily | Item-Type: num - -- waermesumme: Berechnet die Wärmesumme für einen Zeitraum, db_addon_params: (year=optional, month=optional) | Berechnung: daily | Item-Type: num - -- gruenlandtempsumme: Berechnet die Grünlandtemperatursumme für einen Zeitraum, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num - -- wachstumsgradtage: Berechnet die Wachstumsgradtage auf Basis der stündlichen Durchschnittswerte eines Tages für das laufende Jahr mit an Angabe des Temperaturschwellenwertes (threshold=Schwellentemperatur) | Berechnung: daily | Item-Type: num - -- wuestentage: Berechnet die Anzahl der Wüstentage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num - -- heisse_tage: Berechnet die Anzahl der heissen Tage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num - -- tropennaechte: Berechnet die Anzahl der Tropennächte des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num - -- sommertage: Berechnet die Anzahl der Sommertage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num - -- heiztage: Berechnet die Anzahl der Heiztage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num - -- vegetationstage: Berechnet die Anzahl der Vegatationstage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num - -- frosttage: Berechnet die Anzahl der Frosttage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num - -- eistage: Berechnet die Anzahl der Eistage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num - -- tagesmitteltemperatur: Berechnet die Tagesmitteltemperatur auf Basis der stündlichen Durchschnittswerte eines Tages für die angegebene Anzahl von Tagen (timeframe=day, count=integer) | Berechnung: daily | Item-Type: list - -- db_request: Abfrage der DB: db_addon_params: (func=mandatory, item=mandatory, timespan=mandatory, start=optional, end=optional, count=optional, group=optional, group2=optional) | Berechnung: group | Item-Type: list - -- minmax: Berechnet einen min/max/avg Wert für einen bestimmen Zeitraum: db_addon_params: (func=mandatory, timeframe=mandatory, start=mandatory) | Berechnung: timeframe | Item-Type: num - -- minmax_last: 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) | Berechnung: timeframe | Item-Type: num - -- verbrauch: Berechnet einen Verbrauchswert für einen bestimmen Zeitraum: db_addon_params: (timeframe=mandatory, start=mandatory end=mandatory) | Berechnung: timeframe | Item-Type: num - -- zaehlerstand: Berechnet einen Zählerstand für einen bestimmen Zeitpunkt: db_addon_params: (timeframe=mandatory, start=mandatory) | Berechnung: timeframe | Item-Type: num - - -db_addon_info -------------- - -- db_version: Version der verbundenen Datenbank | Berechnung: no | Item-Type: str - - -db_addon_admin --------------- - -- suspend: Unterbricht die Aktivitäten des Plugin | Berechnung: no | Item-Type: bool - -- recalc_all: Startet einen Neuberechnungslauf aller on-demand Items | Berechnung: no | Item-Type: bool - -- clean_cache_values: Löscht Plugin-Cache und damit alle im Plugin zwischengespeicherten Werte | Berechnung: no | Item-Type: bool - - -Hinweise -======== - - - Das Plugin startet die Berechnungen der Werte nach einer gewissen (konfigurierbaren) Zeit (Attribut `startup_run_delay`) - nach dem Start von shNG, um den Startvorgang nicht zu beeinflussen. - - - Bei Start werden automatisch nur die Items berechnet, für das das Attribute `db_addon_startup` gesetzt wurde. Alle anderen - Items werden erst zur konfigurierten Zeit berechnet. Das Attribute `db_addon_startup` kann auch direkt am `Database-Item` - gesetzt werden. Dabei wird das Attribut auf alle darunter liegenden `db_addon-Items` (bspw. bei Verwendung von structs) vererbt. - Über das WebIF kann die Berechnung aller definierten Items ausgelöst werden. - - - Für sogenannte `on_change` Items, also Items, deren Berechnung bis zum Jetzt (bspw. verbrauch-heute) gehen, wird die Berechnung - immer bei eintreffen eines neuen Wertes gestartet. Zu Reduktion der Belastung auf die Datenbank werden die Werte für das Ende der - letzten Periode gecached. - - - Berechnungen werden nur ausgeführt, wenn für den kompletten abgefragten Zeitraum Werte in der Datenbank vorliegen. Wird bspw. - der Verbrauch des letzten Monats abgefragt wobei erst Werte ab dem 3. des Monats in der Datenbank sind, wird die Berechnung abgebrochen. - - - Mit dem Attribut `use_oldest_entry` kann dieses Verhalten verändert werden. Ist das Attribut gesetzt, wird, wenn für den - Beginn der Abfragezeitraums keinen Werte vorliegen, der älteste Eintrag der Datenbank genutzt. - - - Für die Auswertung kann es nützlich sein, bestimmte Werte aus der Datenbank bei der Berechnung auszublenden. Hierfür stehen - 2 Möglichkeiten zur Verfügung: - - Plugin-Attribut `ignore_0`: (list of strings) Bei Items, bei denen ein String aus der Liste im Pfadnamen vorkommt, - werden 0-Werte (val_num = 0) bei Datenbankauswertungen ignoriert. Hat also das Attribut den Wert ['temp'] werden bei allen Items mit - 'temp' im Pfadnamen die 0-Werte bei der Auswertung ignoriert. - - Item-Attribut `db_addon_ignore_value`: (num) Dieser Wert wird bei der Abfrage bzw. Auswertung der Datenbank für diese - Item ignoriert. - - - Das Plugin enthält sehr ausführliche Logginginformation. Bei unerwartetem Verhalten, den LogLevel entsprechend anpassen, - um mehr information zu erhalten. - - - Berechnungen des Plugins können im WebIF unterbrochen werden. Auch das gesamte Plugin kann pausiert werden. Dies kann bei - starker Systembelastung nützlich sein. - - -Beispiele -========= - -Verbrauch ---------- - -Soll bspw. der Verbrauch von Wasser ausgewertet werden, so ist dies wie folgt möglich: - - -.. code-block:: yaml - - wasserzaehler: - zaehlerstand: - type: num - knx_dpt: 12 - knx_cache: 5/3/4 - eval: round(value/1000, 1) - database: init - struct: - - db_addon.verbrauch_1 - - db_addon.verbrauch_2 - - db_addon.zaehlerstand_1 - -Die Werte des Wasserzählerstandes werden in die Datenbank geschrieben und darauf basierend ausgewertet. Die structs -'db_addon.verbrauch_1' und 'db_addon.verbrauch_2' stellen entsprechende Items für die Verbrauchsauswerten zur Verfügung. - -minmax ------- - -Soll bspw. die minimalen und maximalen Temperaturen ausgewertet werden, kann dies so umgesetzt werden: - -.. code-block:: yaml - - temperature: - aussen: - nord: - name: Außentemp Nordseite - type: num - visu_acl: ro - knx_dpt: 9 - knx_cache: 6/5/1 - database: init - struct: - - db_addon.minmax_1 - - db_addon.minmax_2 - -Die Temperaturwerte werden in die Datenbank geschrieben und darauf basierend ausgewertet. Die structs -'db_addon.minmax_1' und 'db_addon.minmax_2' stellen entsprechende Items für die min/max Auswertung zur Verfügung. - -| - -Web Interface -============= - -Das WebIF stellt neben der Ansicht verbundener Items und deren Parameter und Werte auch Funktionen für die -Administration des Plugins bereit. - -Es stehen Button für: - -- Neuberechnung aller Items -- Abbruch eines aktiven Berechnungslaufes -- Pausieren des Plugins -- Wiederaufnahme des Plugins - -bereit. - -Achtung: Das Auslösen einer kompletten Neuberechnung aller Items kann zu einer starken Belastung der Datenbank -aufgrund vieler Leseanfragen führen. - - -db_addon Items --------------- - -Dieser Reiter des Webinterface zeigt die Items an, für die ein DatabaseAddon Attribut konfiguriert ist. - - -db_addon Maintenance --------------------- - -Das Webinterface zeigt detaillierte Informationen über die im Plugin verfügbaren Daten an. -Dies dient der Maintenance bzw. Fehlersuche. Dieser Tab ist nur bei Log-Level "Debug" verfügbar. - - -Erläuterungen zu Temperatursummen -================================= - - -Grünlandtemperatursumme ------------------------ - -Beim Grünland wird die Wärmesumme nach Ernst und Loeper benutzt, um den Vegetationsbeginn und somit den Termin von Düngungsmaßnahmen zu bestimmen. -Dabei erfolgt die Aufsummierung der Tagesmitteltemperaturen über 0 °C, wobei der Januar mit 0.5 und der Februar mit 0.75 gewichtet wird. -Bei einer Wärmesumme von 200 Grad ist eine Düngung angesagt. - -siehe: https://de.wikipedia.org/wiki/Gr%C3%BCnlandtemperatursumme - -Folgende Parameter sind möglich / notwendig: - - -.. code-block:: yaml - - db_addon_params: "year=current" - -- year: Jahreszahl (str oder int), für das die Berechnung ausgeführt werden soll oder "current" für aktuelles Jahr (default: 'current') - - -Wachstumsgradtag ----------------- -Der Begriff Wachstumsgradtage (WGT) ist ein Überbegriff für verschiedene Größen. -Gemeinsam ist ihnen, daß zur Berechnung eine Lufttemperatur von einem Schwellenwert subtrahiert wird. -Je nach Fragestellung und Pflanzenart werden der Schwellenwert unterschiedlich gewählt und die Temperatur unterschiedlich bestimmt. -Verfügbar sind die Berechnung über 0) "einfachen Durchschnitt der Tagestemperaturen", 1) "modifizierten Durchschnitt der Tagestemperaturen" -und 2) Anzahl der Tage, deren Mitteltempertatur oberhalb der Schwellentemperatur lag. - -siehe https://de.wikipedia.org/wiki/Wachstumsgradtag - -Folgende Parameter sind möglich / notwendig: - -.. code-block:: yaml - - db_addon_params: "year=current, method=1, threshold=10" - -- year: Jahreszahl (str oder int), für das die Berechnung ausgeführt werden soll oder "current" für aktuelles Jahr (default: 'current') -- method: 0-Berechnung über "einfachen Durchschnitt der Tagestemperaturen", 1-Berechnung über "modifizierten Durchschnitt (default: 0) -der Tagestemperaturen" 2-Anzahl der Tage, mit Mitteltempertatur oberhalb Schwellentemperatur// 10, 11 Ausgabe aus Zeitserie -- threshold: Schwellentemperatur in °C (int) (default: 10) - - -Wärmesumme ----------- - -Die Wärmesumme soll eine Aussage über den Sommer und die Pflanzenreife liefern. Es gibt keine eindeutige Definition der Größe "Wärmesumme". -Berechnet wird die Wärmesumme als Summe aller Tagesmitteltemperaturen über einem Schwellenwert ab dem 1.1. des Jahres. - -siehe https://de.wikipedia.org/wiki/W%C3%A4rmesumme - -Folgende Parameter sind möglich / notwendig: - -.. code-block:: yaml - - db_addon_params: "year=current, month=1, threshold=10" - -- year: Jahreszahl (str oder int), für das die Berechnung ausgeführt werden soll oder "current" für aktuelles Jahr (default: 'current') -- month: Monat (int) des Jahres, für das die Berechnung ausgeführt werden soll (optional) (default: None) -- threshold: Schwellentemperatur in °C (int) (default: 10) - - -Kältesumme ----------- - -Die Kältesumme soll eine Aussage über die Härte des Winters liefern. -Berechnet wird die Kältesumme als Summe aller negativen Tagesmitteltemperaturen ab dem 21.9. des Jahres bis 31.3. des Folgejahres. - -siehe https://de.wikipedia.org/wiki/K%C3%A4ltesumme - -Folgende Parameter sind möglich / notwendig: - -.. code-block:: yaml - - db_addon_params: "year=current, month=1" - -- year: Jahreszahl (str oder int), für das die Berechnung ausgeführt werden soll oder "current" für aktuelles Jahr (default: 'current') -- month: Monat (int) des Jahres, für das die Berechnung ausgeführt werden soll (optional) (default: None) - - -Tagesmitteltemperatur ---------------------- - -Die Tagesmitteltemperatur wird auf Basis der stündlichen Durchschnittswerte eines Tages (aller in der DB enthaltenen Datensätze) -für die angegebene Anzahl von Tagen (days=optional) berechnet. - - - -Vorgehen bei Funktionserweiterung des Plugins bzw. Ergänzung weiterer Werte für Item-Attribute ----------------------------------------------------------------------------------------------- - -Aufgrund der Vielzahl der möglichen Werte der Itemattribute, insbesondere des Itemattributes `db_addon_fct`, wurde die Erstellung/Update -der entsprechenden Teile der `plugin.yam` sowie die Erstellung der Datei `item_attributes.py`, die vom Plugin verwendet wird, automatisiert. - -Die Masterinformationen für alle Itemattribute sowie die Skripte zum Erstellen/Update der beiden Dateien sind in der -Datei `item_attributes_master.py` enthalten. - -.. important:: - - Korrekturen, Erweiterungen etc. der Itemattribute sollten nur in der Datei `item_attributes_master.py` - im Dict der Variable `ITEM_ATTRIBUTS` vorgenommen werden. Das Ausführen der Datei `item_attributes_master.py` (main) - erstellt die `item_attributes.py` und aktualisiert die `plugin.yaml` entsprechend. -Dieses Kapitel wurde automatisch durch Ausführen des Skripts in der Datei 'item_attributes_master.py' erstellt. - -Nachfolgend eine Auflistung der möglichen Attribute für das Plugin im Format: Attribute: Beschreibung | Berechnungszyklus | Item-Type - - -db_addon_fct ------------- - -- verbrauch_heute: Verbrauch am heutigen Tag (Differenz zwischen aktuellem Wert und den Wert am Ende des vorherigen Tages) | Berechnung: onchange | Item-Type: num - -- verbrauch_tag: Verbrauch am heutigen Tag (Differenz zwischen aktuellem Wert und den Wert am Ende des vorherigen Tages) | Berechnung: onchange | Item-Type: num - -- verbrauch_woche: Verbrauch in der aktuellen Woche | Berechnung: onchange | Item-Type: num - -- verbrauch_monat: Verbrauch im aktuellen Monat | Berechnung: onchange | Item-Type: num - -- verbrauch_jahr: Verbrauch im aktuellen Jahr | Berechnung: onchange | Item-Type: num - -- verbrauch_last_24h: Verbrauch innerhalb letzten 24h | Berechnung: hourly | Item-Type: num - -- verbrauch_last_7d: Verbrauch innerhalb letzten 7 Tage | Berechnung: hourly | Item-Type: num - -- verbrauch_heute_minus1: Verbrauch gestern (heute -1 Tag) (Differenz zwischen Wert am Ende des gestrigen Tages und dem Wert am Ende des Tages davor) | Berechnung: daily | Item-Type: num - -- verbrauch_heute_minus2: Verbrauch vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num - -- verbrauch_heute_minus3: Verbrauch heute -3 Tage | Berechnung: daily | Item-Type: num - -- verbrauch_heute_minus4: Verbrauch heute -4 Tage | Berechnung: daily | Item-Type: num - -- verbrauch_heute_minus5: Verbrauch heute -5 Tage | Berechnung: daily | Item-Type: num - -- verbrauch_heute_minus6: Verbrauch heute -6 Tage | Berechnung: daily | Item-Type: num - -- verbrauch_heute_minus7: Verbrauch heute -7 Tage | Berechnung: daily | Item-Type: num - -- verbrauch_heute_minus8: Verbrauch heute -8 Tage | Berechnung: daily | Item-Type: num - -- verbrauch_tag_minus1: Verbrauch gestern (heute -1 Tag) (Differenz zwischen Wert am Ende des gestrigen Tages und dem Wert am Ende des Tages davor) | Berechnung: daily | Item-Type: num - -- verbrauch_tag_minus2: Verbrauch vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num - -- verbrauch_tag_minus3: Verbrauch heute -3 Tage | Berechnung: daily | Item-Type: num - -- verbrauch_tag_minus4: Verbrauch heute -4 Tage | Berechnung: daily | Item-Type: num - -- verbrauch_tag_minus5: Verbrauch heute -5 Tage | Berechnung: daily | Item-Type: num - -- verbrauch_tag_minus6: Verbrauch heute -6 Tage | Berechnung: daily | Item-Type: num - -- verbrauch_tag_minus7: Verbrauch heute -7 Tage | Berechnung: daily | Item-Type: num - -- verbrauch_tag_minus8: Verbrauch heute -8 Tage | Berechnung: daily | Item-Type: num - -- verbrauch_woche_minus1: Verbrauch Vorwoche (aktuelle Woche -1) | Berechnung: weekly | Item-Type: num - -- verbrauch_woche_minus2: Verbrauch aktuelle Woche -2 Wochen | Berechnung: weekly | Item-Type: num - -- verbrauch_woche_minus3: Verbrauch aktuelle Woche -3 Wochen | Berechnung: weekly | Item-Type: num - -- verbrauch_woche_minus4: Verbrauch aktuelle Woche -4 Wochen | Berechnung: weekly | Item-Type: num - -- verbrauch_monat_minus1: Verbrauch Vormonat (aktueller Monat -1) | Berechnung: monthly | Item-Type: num - -- verbrauch_monat_minus2: Verbrauch aktueller Monat -2 Monate | Berechnung: monthly | Item-Type: num - -- verbrauch_monat_minus3: Verbrauch aktueller Monat -3 Monate | Berechnung: monthly | Item-Type: num - -- verbrauch_monat_minus4: Verbrauch aktueller Monat -4 Monate | Berechnung: monthly | Item-Type: num - -- verbrauch_monat_minus12: Verbrauch aktueller Monat -12 Monate | Berechnung: monthly | Item-Type: num - -- verbrauch_jahr_minus1: Verbrauch Vorjahr (aktuelles Jahr -1 Jahr) | Berechnung: yearly | Item-Type: num - -- verbrauch_jahr_minus2: Verbrauch aktuelles Jahr -2 Jahre | Berechnung: yearly | Item-Type: num - -- verbrauch_jahr_minus3: Verbrauch aktuelles Jahr -3 Jahre | Berechnung: yearly | Item-Type: num - -- verbrauch_rolling_12m_heute_minus1: Verbrauch der letzten 12 Monate ausgehend im Ende des letzten Tages | Berechnung: daily | Item-Type: num - -- verbrauch_rolling_12m_tag_minus1: Verbrauch der letzten 12 Monate ausgehend im Ende des letzten Tages | Berechnung: daily | Item-Type: num - -- verbrauch_rolling_12m_woche_minus1: Verbrauch der letzten 12 Monate ausgehend im Ende der letzten Woche | Berechnung: weekly | Item-Type: num - -- verbrauch_rolling_12m_monat_minus1: Verbrauch der letzten 12 Monate ausgehend im Ende des letzten Monats | Berechnung: monthly | Item-Type: num - -- verbrauch_rolling_12m_jahr_minus1: Verbrauch der letzten 12 Monate ausgehend im Ende des letzten Jahres | Berechnung: yearly | Item-Type: num - -- verbrauch_jahreszeitraum_minus1: Verbrauch seit dem 1.1. bis zum heutigen Tag des Vorjahres | Berechnung: daily | Item-Type: num - -- verbrauch_jahreszeitraum_minus2: Verbrauch seit dem 1.1. bis zum heutigen Tag vor 2 Jahren | Berechnung: daily | Item-Type: num - -- verbrauch_jahreszeitraum_minus3: Verbrauch seit dem 1.1. bis zum heutigen Tag vor 3 Jahren | Berechnung: daily | Item-Type: num - -- zaehlerstand_heute_minus1: Zählerstand / Wert am Ende des letzten Tages (heute -1 Tag) | Berechnung: daily | Item-Type: num - -- zaehlerstand_heute_minus2: Zählerstand / Wert am Ende des vorletzten Tages (heute -2 Tag) | Berechnung: daily | Item-Type: num - -- zaehlerstand_heute_minus3: Zählerstand / Wert am Ende des vorvorletzten Tages (heute -3 Tag) | Berechnung: daily | Item-Type: num - -- zaehlerstand_tag_minus1: Zählerstand / Wert am Ende des letzten Tages (heute -1 Tag) | Berechnung: daily | Item-Type: num - -- zaehlerstand_tag_minus2: Zählerstand / Wert am Ende des vorletzten Tages (heute -2 Tag) | Berechnung: daily | Item-Type: num - -- zaehlerstand_tag_minus3: Zählerstand / Wert am Ende des vorvorletzten Tages (heute -3 Tag) | Berechnung: daily | Item-Type: num - -- zaehlerstand_woche_minus1: Zählerstand / Wert am Ende der vorvorletzten Woche (aktuelle Woche -1 Woche) | Berechnung: weekly | Item-Type: num - -- zaehlerstand_woche_minus2: Zählerstand / Wert am Ende der vorletzten Woche (aktuelle Woche -2 Wochen) | Berechnung: weekly | Item-Type: num - -- zaehlerstand_woche_minus3: Zählerstand / Wert am Ende der aktuellen Woche -3 Wochen | Berechnung: weekly | Item-Type: num - -- zaehlerstand_monat_minus1: Zählerstand / Wert am Ende des letzten Monates (aktueller Monat -1 Monat) | Berechnung: monthly | Item-Type: num - -- zaehlerstand_monat_minus2: Zählerstand / Wert am Ende des vorletzten Monates (aktueller Monat -2 Monate) | Berechnung: monthly | Item-Type: num - -- zaehlerstand_monat_minus3: Zählerstand / Wert am Ende des aktuellen Monats -3 Monate | Berechnung: monthly | Item-Type: num - -- zaehlerstand_jahr_minus1: Zählerstand / Wert am Ende des letzten Jahres (aktuelles Jahr -1 Jahr) | Berechnung: yearly | Item-Type: num - -- zaehlerstand_jahr_minus2: Zählerstand / Wert am Ende des vorletzten Jahres (aktuelles Jahr -2 Jahre) | Berechnung: yearly | Item-Type: num - -- zaehlerstand_jahr_minus3: Zählerstand / Wert am Ende des aktuellen Jahres -3 Jahre | Berechnung: yearly | Item-Type: num - -- minmax_last_24h_min: minimaler Wert der letzten 24h | Berechnung: daily | Item-Type: num - -- minmax_last_24h_max: maximaler Wert der letzten 24h | Berechnung: daily | Item-Type: num - -- minmax_last_24h_avg: durchschnittlicher Wert der letzten 24h | Berechnung: daily | Item-Type: num - -- minmax_last_7d_min: minimaler Wert der letzten 7 Tage | Berechnung: daily | Item-Type: num - -- minmax_last_7d_max: maximaler Wert der letzten 7 Tage | Berechnung: daily | Item-Type: num - -- minmax_last_7d_avg: durchschnittlicher Wert der letzten 7 Tage | Berechnung: daily | Item-Type: num - -- minmax_heute_min: Minimalwert seit Tagesbeginn | Berechnung: onchange | Item-Type: num - -- minmax_heute_max: Maximalwert seit Tagesbeginn | Berechnung: onchange | Item-Type: num - -- minmax_heute_avg: Durschnittswert seit Tagesbeginn | Berechnung: onchange | Item-Type: num - -- minmax_heute_minus1_min: Minimalwert gestern (heute -1 Tag) | Berechnung: daily | Item-Type: num - -- minmax_heute_minus1_max: Maximalwert gestern (heute -1 Tag) | Berechnung: daily | Item-Type: num - -- minmax_heute_minus1_avg: Durchschnittswert gestern (heute -1 Tag) | Berechnung: daily | Item-Type: num - -- minmax_heute_minus2_min: Minimalwert vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num - -- minmax_heute_minus2_max: Maximalwert vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num - -- minmax_heute_minus2_avg: Durchschnittswert vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num - -- minmax_heute_minus3_min: Minimalwert heute vor 3 Tagen | Berechnung: daily | Item-Type: num - -- minmax_heute_minus3_max: Maximalwert heute vor 3 Tagen | Berechnung: daily | Item-Type: num - -- minmax_heute_minus3_avg: Durchschnittswert heute vor 3 Tagen | Berechnung: daily | Item-Type: num - -- minmax_tag_min: Minimalwert seit Tagesbeginn | Berechnung: onchange | Item-Type: num - -- minmax_tag_max: Maximalwert seit Tagesbeginn | Berechnung: onchange | Item-Type: num - -- minmax_tag_avg: Durschnittswert seit Tagesbeginn | Berechnung: onchange | Item-Type: num - -- minmax_tag_minus1_min: Minimalwert gestern (heute -1 Tag) | Berechnung: daily | Item-Type: num - -- minmax_tag_minus1_max: Maximalwert gestern (heute -1 Tag) | Berechnung: daily | Item-Type: num - -- minmax_tag_minus1_avg: Durchschnittswert gestern (heute -1 Tag) | Berechnung: daily | Item-Type: num - -- minmax_tag_minus2_min: Minimalwert vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num - -- minmax_tag_minus2_max: Maximalwert vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num - -- minmax_tag_minus2_avg: Durchschnittswert vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num - -- minmax_tag_minus3_min: Minimalwert heute vor 3 Tagen | Berechnung: daily | Item-Type: num - -- minmax_tag_minus3_max: Maximalwert heute vor 3 Tagen | Berechnung: daily | Item-Type: num - -- minmax_tag_minus3_avg: Durchschnittswert heute vor 3 Tagen | Berechnung: daily | Item-Type: num - -- minmax_woche_min: Minimalwert seit Wochenbeginn | Berechnung: onchange | Item-Type: num - -- minmax_woche_max: Maximalwert seit Wochenbeginn | Berechnung: onchange | Item-Type: num - -- minmax_woche_minus1_min: Minimalwert Vorwoche (aktuelle Woche -1) | Berechnung: weekly | Item-Type: num - -- minmax_woche_minus1_max: Maximalwert Vorwoche (aktuelle Woche -1) | Berechnung: weekly | Item-Type: num - -- minmax_woche_minus1_avg: Durchschnittswert Vorwoche (aktuelle Woche -1) | Berechnung: weekly | Item-Type: num - -- minmax_woche_minus2_min: Minimalwert aktuelle Woche -2 Wochen | Berechnung: weekly | Item-Type: num - -- minmax_woche_minus2_max: Maximalwert aktuelle Woche -2 Wochen | Berechnung: weekly | Item-Type: num - -- minmax_woche_minus2_avg: Durchschnittswert aktuelle Woche -2 Wochen | Berechnung: weekly | Item-Type: num - -- minmax_monat_min: Minimalwert seit Monatsbeginn | Berechnung: onchange | Item-Type: num - -- minmax_monat_max: Maximalwert seit Monatsbeginn | Berechnung: onchange | Item-Type: num - -- minmax_monat_minus1_min: Minimalwert Vormonat (aktueller Monat -1) | Berechnung: monthly | Item-Type: num - -- minmax_monat_minus1_max: Maximalwert Vormonat (aktueller Monat -1) | Berechnung: monthly | Item-Type: num - -- minmax_monat_minus1_avg: Durchschnittswert Vormonat (aktueller Monat -1) | Berechnung: monthly | Item-Type: num - -- minmax_monat_minus2_min: Minimalwert aktueller Monat -2 Monate | Berechnung: monthly | Item-Type: num - -- minmax_monat_minus2_max: Maximalwert aktueller Monat -2 Monate | Berechnung: monthly | Item-Type: num - -- minmax_monat_minus2_avg: Durchschnittswert aktueller Monat -2 Monate | Berechnung: monthly | Item-Type: num - -- minmax_jahr_min: Minimalwert seit Jahresbeginn | Berechnung: onchange | Item-Type: num - -- minmax_jahr_max: Maximalwert seit Jahresbeginn | Berechnung: onchange | Item-Type: num - -- minmax_jahr_minus1_min: Minimalwert Vorjahr (aktuelles Jahr -1 Jahr) | Berechnung: yearly | Item-Type: num - -- minmax_jahr_minus1_max: Maximalwert Vorjahr (aktuelles Jahr -1 Jahr) | Berechnung: yearly | Item-Type: num - -- minmax_jahr_minus1_avg: Durchschnittswert Vorjahr (aktuelles Jahr -1 Jahr) | Berechnung: yearly | Item-Type: num - -- tagesmitteltemperatur_heute: Tagesmitteltemperatur heute | Berechnung: onchange | Item-Type: num - -- tagesmitteltemperatur_heute_minus1: Tagesmitteltemperatur des letzten Tages (heute -1 Tag) | Berechnung: daily | Item-Type: num - -- tagesmitteltemperatur_heute_minus2: Tagesmitteltemperatur des vorletzten Tages (heute -2 Tag) | Berechnung: daily | Item-Type: num - -- tagesmitteltemperatur_heute_minus3: Tagesmitteltemperatur des vorvorletzten Tages (heute -3 Tag) | Berechnung: daily | Item-Type: num - -- tagesmitteltemperatur_tag: Tagesmitteltemperatur heute | Berechnung: onchange | Item-Type: num - -- tagesmitteltemperatur_tag_minus1: Tagesmitteltemperatur des letzten Tages (heute -1 Tag) | Berechnung: daily | Item-Type: num - -- tagesmitteltemperatur_tag_minus2: Tagesmitteltemperatur des vorletzten Tages (heute -2 Tag) | Berechnung: daily | Item-Type: num - -- tagesmitteltemperatur_tag_minus3: Tagesmitteltemperatur des vorvorletzten Tages (heute -3 Tag) | Berechnung: daily | Item-Type: num - -- serie_minmax_monat_min_15m: monatlicher Minimalwert der letzten 15 Monate (gleitend) | Berechnung: monthly | Item-Type: list - -- serie_minmax_monat_max_15m: monatlicher Maximalwert der letzten 15 Monate (gleitend) | Berechnung: monthly | Item-Type: list - -- serie_minmax_monat_avg_15m: monatlicher Mittelwert der letzten 15 Monate (gleitend) | Berechnung: monthly | Item-Type: list - -- serie_minmax_woche_min_30w: wöchentlicher Minimalwert der letzten 30 Wochen (gleitend) | Berechnung: weekly | Item-Type: list - -- serie_minmax_woche_max_30w: wöchentlicher Maximalwert der letzten 30 Wochen (gleitend) | Berechnung: weekly | Item-Type: list - -- serie_minmax_woche_avg_30w: wöchentlicher Mittelwert der letzten 30 Wochen (gleitend) | Berechnung: weekly | Item-Type: list - -- serie_minmax_tag_min_30d: täglicher Minimalwert der letzten 30 Tage (gleitend) | Berechnung: daily | Item-Type: list - -- serie_minmax_tag_max_30d: täglicher Maximalwert der letzten 30 Tage (gleitend) | Berechnung: daily | Item-Type: list - -- serie_minmax_tag_avg_30d: täglicher Mittelwert der letzten 30 Tage (gleitend) | Berechnung: daily | Item-Type: list - -- serie_verbrauch_tag_30d: Verbrauch pro Tag der letzten 30 Tage | Berechnung: daily | Item-Type: list - -- serie_verbrauch_woche_30w: Verbrauch pro Woche der letzten 30 Wochen | Berechnung: weekly | Item-Type: list - -- serie_verbrauch_monat_18m: Verbrauch pro Monat der letzten 18 Monate | Berechnung: monthly | Item-Type: list - -- serie_zaehlerstand_tag_30d: Zählerstand am Tagesende der letzten 30 Tage | Berechnung: daily | Item-Type: list - -- serie_zaehlerstand_woche_30w: Zählerstand am Wochenende der letzten 30 Wochen | Berechnung: weekly | Item-Type: list - -- serie_zaehlerstand_monat_18m: Zählerstand am Monatsende der letzten 18 Monate | Berechnung: monthly | Item-Type: list - -- serie_waermesumme_monat_24m: monatliche Wärmesumme der letzten 24 Monate | Berechnung: monthly | Item-Type: list - -- serie_kaeltesumme_monat_24m: monatliche Kältesumme der letzten 24 Monate | Berechnung: monthly | Item-Type: list - -- serie_tagesmittelwert_0d: Tagesmittelwert für den aktuellen Tag | Berechnung: daily | Item-Type: list - -- serie_tagesmittelwert_stunde_0d: Stundenmittelwert für den aktuellen Tag | Berechnung: daily | Item-Type: list - -- serie_tagesmittelwert_stunde_30_0d: Stundenmittelwert für den aktuellen Tag | Berechnung: daily | Item-Type: list - -- serie_tagesmittelwert_tag_stunde_30d: Stundenmittelwert pro Tag der letzten 30 Tage (bspw. zur Berechnung der Tagesmitteltemperatur basierend auf den Mittelwert der Temperatur pro Stunde | Berechnung: daily | Item-Type: list - -- general_oldest_value: Ausgabe des ältesten Wertes des entsprechenden "Parent-Items" mit database Attribut | Berechnung: no | Item-Type: num - -- general_oldest_log: Ausgabe des Timestamp des ältesten Eintrages des entsprechenden "Parent-Items" mit database Attribut | Berechnung: no | Item-Type: list - -- kaeltesumme: Berechnet die Kältesumme für einen Zeitraum, db_addon_params: (year=optional, month=optional) | Berechnung: daily | Item-Type: num - -- waermesumme: Berechnet die Wärmesumme für einen Zeitraum, db_addon_params: (year=optional, month=optional) | Berechnung: daily | Item-Type: num - -- gruenlandtempsumme: Berechnet die Grünlandtemperatursumme für einen Zeitraum, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num - -- wachstumsgradtage: Berechnet die Wachstumsgradtage auf Basis der stündlichen Durchschnittswerte eines Tages für das laufende Jahr mit an Angabe des Temperaturschwellenwertes (threshold=Schwellentemperatur) | Berechnung: daily | Item-Type: num - -- wuestentage: Berechnet die Anzahl der Wüstentage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num - -- heisse_tage: Berechnet die Anzahl der heissen Tage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num - -- tropennaechte: Berechnet die Anzahl der Tropennächte des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num - -- sommertage: Berechnet die Anzahl der Sommertage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num - -- heiztage: Berechnet die Anzahl der Heiztage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num - -- vegetationstage: Berechnet die Anzahl der Vegatationstage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num - -- frosttage: Berechnet die Anzahl der Frosttage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num - -- eistage: Berechnet die Anzahl der Eistage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num - -- tagesmitteltemperatur: Berechnet die Tagesmitteltemperatur auf Basis der stündlichen Durchschnittswerte eines Tages für die angegebene Anzahl von Tagen (timeframe=day, count=integer) | Berechnung: daily | Item-Type: list - -- db_request: Abfrage der DB: db_addon_params: (func=mandatory, item=mandatory, timespan=mandatory, start=optional, end=optional, count=optional, group=optional, group2=optional) | Berechnung: group | Item-Type: list - -- minmax: Berechnet einen min/max/avg Wert für einen bestimmen Zeitraum: db_addon_params: (func=mandatory, timeframe=mandatory, start=mandatory) | Berechnung: timeframe | Item-Type: num - -- minmax_last: 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) | Berechnung: timeframe | Item-Type: num - -- verbrauch: Berechnet einen Verbrauchswert für einen bestimmen Zeitraum: db_addon_params: (timeframe=mandatory, start=mandatory end=mandatory) | Berechnung: timeframe | Item-Type: num - -- zaehlerstand: Berechnet einen Zählerstand für einen bestimmen Zeitpunkt: db_addon_params: (timeframe=mandatory, start=mandatory) | Berechnung: timeframe | Item-Type: num - - -db_addon_info -------------- - -- db_version: Version der verbundenen Datenbank | Berechnung: no | Item-Type: str - - -db_addon_admin --------------- - -- suspend: Unterbricht die Aktivitäten des Plugin | Berechnung: no | Item-Type: bool - -- recalc_all: Startet einen Neuberechnungslauf aller on-demand Items | Berechnung: no | Item-Type: bool - -- clean_cache_values: Löscht Plugin-Cache und damit alle im Plugin zwischengespeicherten Werte | Berechnung: no | Item-Type: bool - - -Hinweise -======== - - - Das Plugin startet die Berechnungen der Werte nach einer gewissen (konfigurierbaren) Zeit (Attribut `startup_run_delay`) - nach dem Start von shNG, um den Startvorgang nicht zu beeinflussen. - - - Bei Start werden automatisch nur die Items berechnet, für das das Attribute `db_addon_startup` gesetzt wurde. Alle anderen - Items werden erst zur konfigurierten Zeit berechnet. Das Attribute `db_addon_startup` kann auch direkt am `Database-Item` - gesetzt werden. Dabei wird das Attribut auf alle darunter liegenden `db_addon-Items` (bspw. bei Verwendung von structs) vererbt. - Über das WebIF kann die Berechnung aller definierten Items ausgelöst werden. - - - Für sogenannte `on_change` Items, also Items, deren Berechnung bis zum Jetzt (bspw. verbrauch-heute) gehen, wird die Berechnung - immer bei eintreffen eines neuen Wertes gestartet. Zu Reduktion der Belastung auf die Datenbank werden die Werte für das Ende der - letzten Periode gecached. - - - Berechnungen werden nur ausgeführt, wenn für den kompletten abgefragten Zeitraum Werte in der Datenbank vorliegen. Wird bspw. - der Verbrauch des letzten Monats abgefragt wobei erst Werte ab dem 3. des Monats in der Datenbank sind, wird die Berechnung abgebrochen. - - - Mit dem Attribut `use_oldest_entry` kann dieses Verhalten verändert werden. Ist das Attribut gesetzt, wird, wenn für den - Beginn der Abfragezeitraums keinen Werte vorliegen, der älteste Eintrag der Datenbank genutzt. - - - Für die Auswertung kann es nützlich sein, bestimmte Werte aus der Datenbank bei der Berechnung auszublenden. Hierfür stehen - 2 Möglichkeiten zur Verfügung: - - Plugin-Attribut `ignore_0`: (list of strings) Bei Items, bei denen ein String aus der Liste im Pfadnamen vorkommt, - werden 0-Werte (val_num = 0) bei Datenbankauswertungen ignoriert. Hat also das Attribut den Wert ['temp'] werden bei allen Items mit - 'temp' im Pfadnamen die 0-Werte bei der Auswertung ignoriert. - - Item-Attribut `db_addon_ignore_value`: (num) Dieser Wert wird bei der Abfrage bzw. Auswertung der Datenbank für diese - Item ignoriert. - - - Das Plugin enthält sehr ausführliche Logginginformation. Bei unerwartetem Verhalten, den LogLevel entsprechend anpassen, - um mehr information zu erhalten. - - - Berechnungen des Plugins können im WebIF unterbrochen werden. Auch das gesamte Plugin kann pausiert werden. Dies kann bei - starker Systembelastung nützlich sein. - - -Beispiele -========= - -Verbrauch ---------- - -Soll bspw. der Verbrauch von Wasser ausgewertet werden, so ist dies wie folgt möglich: - - -.. code-block:: yaml - - wasserzaehler: - zaehlerstand: - type: num - knx_dpt: 12 - knx_cache: 5/3/4 - eval: round(value/1000, 1) - database: init - struct: - - db_addon.verbrauch_1 - - db_addon.verbrauch_2 - - db_addon.zaehlerstand_1 - -Die Werte des Wasserzählerstandes werden in die Datenbank geschrieben und darauf basierend ausgewertet. Die structs -'db_addon.verbrauch_1' und 'db_addon.verbrauch_2' stellen entsprechende Items für die Verbrauchsauswerten zur Verfügung. - -minmax ------- - -Soll bspw. die minimalen und maximalen Temperaturen ausgewertet werden, kann dies so umgesetzt werden: - -.. code-block:: yaml - - temperature: - aussen: - nord: - name: Außentemp Nordseite - type: num - visu_acl: ro - knx_dpt: 9 - knx_cache: 6/5/1 - database: init - struct: - - db_addon.minmax_1 - - db_addon.minmax_2 - -Die Temperaturwerte werden in die Datenbank geschrieben und darauf basierend ausgewertet. Die structs -'db_addon.minmax_1' und 'db_addon.minmax_2' stellen entsprechende Items für die min/max Auswertung zur Verfügung. - -| - -Web Interface -============= - -Das WebIF stellt neben der Ansicht verbundener Items und deren Parameter und Werte auch Funktionen für die -Administration des Plugins bereit. - -Es stehen Button für: - -- Neuberechnung aller Items -- Abbruch eines aktiven Berechnungslaufes -- Pausieren des Plugins -- Wiederaufnahme des Plugins - -bereit. - -Achtung: Das Auslösen einer kompletten Neuberechnung aller Items kann zu einer starken Belastung der Datenbank -aufgrund vieler Leseanfragen führen. - - -db_addon Items --------------- - -Dieser Reiter des Webinterface zeigt die Items an, für die ein DatabaseAddon Attribut konfiguriert ist. - - -db_addon Maintenance --------------------- - -Das Webinterface zeigt detaillierte Informationen über die im Plugin verfügbaren Daten an. -Dies dient der Maintenance bzw. Fehlersuche. Dieser Tab ist nur bei Log-Level "Debug" verfügbar. - - -Erläuterungen zu Temperatursummen -================================= - - -Grünlandtemperatursumme ------------------------ - -Beim Grünland wird die Wärmesumme nach Ernst und Loeper benutzt, um den Vegetationsbeginn und somit den Termin von Düngungsmaßnahmen zu bestimmen. -Dabei erfolgt die Aufsummierung der Tagesmitteltemperaturen über 0 °C, wobei der Januar mit 0.5 und der Februar mit 0.75 gewichtet wird. -Bei einer Wärmesumme von 200 Grad ist eine Düngung angesagt. - -siehe: https://de.wikipedia.org/wiki/Gr%C3%BCnlandtemperatursumme - -Folgende Parameter sind möglich / notwendig: - - -.. code-block:: yaml - - db_addon_params: "year=current" - -- year: Jahreszahl (str oder int), für das die Berechnung ausgeführt werden soll oder "current" für aktuelles Jahr (default: 'current') - - -Wachstumsgradtag ----------------- -Der Begriff Wachstumsgradtage (WGT) ist ein Überbegriff für verschiedene Größen. -Gemeinsam ist ihnen, daß zur Berechnung eine Lufttemperatur von einem Schwellenwert subtrahiert wird. -Je nach Fragestellung und Pflanzenart werden der Schwellenwert unterschiedlich gewählt und die Temperatur unterschiedlich bestimmt. -Verfügbar sind die Berechnung über 0) "einfachen Durchschnitt der Tagestemperaturen", 1) "modifizierten Durchschnitt der Tagestemperaturen" -und 2) Anzahl der Tage, deren Mitteltempertatur oberhalb der Schwellentemperatur lag. - -siehe https://de.wikipedia.org/wiki/Wachstumsgradtag - -Folgende Parameter sind möglich / notwendig: - -.. code-block:: yaml - - db_addon_params: "year=current, method=1, threshold=10" - -- year: Jahreszahl (str oder int), für das die Berechnung ausgeführt werden soll oder "current" für aktuelles Jahr (default: 'current') -- method: 0-Berechnung über "einfachen Durchschnitt der Tagestemperaturen", 1-Berechnung über "modifizierten Durchschnitt (default: 0) -der Tagestemperaturen" 2-Anzahl der Tage, mit Mitteltempertatur oberhalb Schwellentemperatur// 10, 11 Ausgabe aus Zeitserie -- threshold: Schwellentemperatur in °C (int) (default: 10) - - -Wärmesumme ----------- - -Die Wärmesumme soll eine Aussage über den Sommer und die Pflanzenreife liefern. Es gibt keine eindeutige Definition der Größe "Wärmesumme". -Berechnet wird die Wärmesumme als Summe aller Tagesmitteltemperaturen über einem Schwellenwert ab dem 1.1. des Jahres. - -siehe https://de.wikipedia.org/wiki/W%C3%A4rmesumme - -Folgende Parameter sind möglich / notwendig: - -.. code-block:: yaml - - db_addon_params: "year=current, month=1, threshold=10" - -- year: Jahreszahl (str oder int), für das die Berechnung ausgeführt werden soll oder "current" für aktuelles Jahr (default: 'current') -- month: Monat (int) des Jahres, für das die Berechnung ausgeführt werden soll (optional) (default: None) -- threshold: Schwellentemperatur in °C (int) (default: 10) - - -Kältesumme ----------- - -Die Kältesumme soll eine Aussage über die Härte des Winters liefern. -Berechnet wird die Kältesumme als Summe aller negativen Tagesmitteltemperaturen ab dem 21.9. des Jahres bis 31.3. des Folgejahres. - -siehe https://de.wikipedia.org/wiki/K%C3%A4ltesumme - -Folgende Parameter sind möglich / notwendig: - -.. code-block:: yaml - - db_addon_params: "year=current, month=1" - -- year: Jahreszahl (str oder int), für das die Berechnung ausgeführt werden soll oder "current" für aktuelles Jahr (default: 'current') -- month: Monat (int) des Jahres, für das die Berechnung ausgeführt werden soll (optional) (default: None) - - -Tagesmitteltemperatur ---------------------- - -Die Tagesmitteltemperatur wird auf Basis der stündlichen Durchschnittswerte eines Tages (aller in der DB enthaltenen Datensätze) -für die angegebene Anzahl von Tagen (days=optional) berechnet. - - - -Vorgehen bei Funktionserweiterung des Plugins bzw. Ergänzung weiterer Werte für Item-Attribute ----------------------------------------------------------------------------------------------- - -Aufgrund der Vielzahl der möglichen Werte der Itemattribute, insbesondere des Itemattributes `db_addon_fct`, wurde die Erstellung/Update -der entsprechenden Teile der `plugin.yam` sowie die Erstellung der Datei `item_attributes.py`, die vom Plugin verwendet wird, automatisiert. - -Die Masterinformationen für alle Itemattribute sowie die Skripte zum Erstellen/Update der beiden Dateien sind in der -Datei `item_attributes_master.py` enthalten. - -.. important:: - - Korrekturen, Erweiterungen etc. der Itemattribute sollten nur in der Datei `item_attributes_master.py` - im Dict der Variable `ITEM_ATTRIBUTS` vorgenommen werden. Das Ausführen der Datei `item_attributes_master.py` (main) - erstellt die `item_attributes.py` und aktualisiert die `plugin.yaml` entsprechend. -Dieses Kapitel wurde automatisch durch Ausführen des Skripts in der Datei 'item_attributes_master.py' erstellt. - -Nachfolgend eine Auflistung der möglichen Attribute für das Plugin im Format: Attribute: Beschreibung | Berechnungszyklus | Item-Type - - -db_addon_fct ------------- - -- verbrauch_heute: Verbrauch am heutigen Tag (Differenz zwischen aktuellem Wert und den Wert am Ende des vorherigen Tages) | Berechnung: daily | Item-Type: num - -- verbrauch_tag: Verbrauch am heutigen Tag (Differenz zwischen aktuellem Wert und den Wert am Ende des vorherigen Tages) | Berechnung: daily | Item-Type: num - -- verbrauch_woche: Verbrauch in der aktuellen Woche | Berechnung: weekly | Item-Type: num - -- verbrauch_monat: Verbrauch im aktuellen Monat | Berechnung: monthly | Item-Type: num - -- verbrauch_jahr: Verbrauch im aktuellen Jahr | Berechnung: yearly | Item-Type: num - -- verbrauch_last_24h: Verbrauch innerhalb letzten 24h | Berechnung: hourly | Item-Type: num - -- verbrauch_last_7d: Verbrauch innerhalb letzten 7 Tage | Berechnung: hourly | Item-Type: num - -- verbrauch_heute_minus1: Verbrauch gestern (heute -1 Tag) (Differenz zwischen Wert am Ende des gestrigen Tages und dem Wert am Ende des Tages davor) | Berechnung: daily | Item-Type: num - -- verbrauch_heute_minus2: Verbrauch vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num - -- verbrauch_heute_minus3: Verbrauch heute -3 Tage | Berechnung: daily | Item-Type: num - -- verbrauch_heute_minus4: Verbrauch heute -4 Tage | Berechnung: daily | Item-Type: num - -- verbrauch_heute_minus5: Verbrauch heute -5 Tage | Berechnung: daily | Item-Type: num - -- verbrauch_heute_minus6: Verbrauch heute -6 Tage | Berechnung: daily | Item-Type: num - -- verbrauch_heute_minus7: Verbrauch heute -7 Tage | Berechnung: daily | Item-Type: num - -- verbrauch_heute_minus8: Verbrauch heute -8 Tage | Berechnung: daily | Item-Type: num - -- verbrauch_tag_minus1: Verbrauch gestern (heute -1 Tag) (Differenz zwischen Wert am Ende des gestrigen Tages und dem Wert am Ende des Tages davor) | Berechnung: daily | Item-Type: num - -- verbrauch_tag_minus2: Verbrauch vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num - -- verbrauch_tag_minus3: Verbrauch heute -3 Tage | Berechnung: daily | Item-Type: num - -- verbrauch_tag_minus4: Verbrauch heute -4 Tage | Berechnung: daily | Item-Type: num - -- verbrauch_tag_minus5: Verbrauch heute -5 Tage | Berechnung: daily | Item-Type: num - -- verbrauch_tag_minus6: Verbrauch heute -6 Tage | Berechnung: daily | Item-Type: num - -- verbrauch_tag_minus7: Verbrauch heute -7 Tage | Berechnung: daily | Item-Type: num - -- verbrauch_tag_minus8: Verbrauch heute -8 Tage | Berechnung: daily | Item-Type: num - -- verbrauch_woche_minus1: Verbrauch Vorwoche (aktuelle Woche -1) | Berechnung: weekly | Item-Type: num - -- verbrauch_woche_minus2: Verbrauch aktuelle Woche -2 Wochen | Berechnung: weekly | Item-Type: num - -- verbrauch_woche_minus3: Verbrauch aktuelle Woche -3 Wochen | Berechnung: weekly | Item-Type: num - -- verbrauch_woche_minus4: Verbrauch aktuelle Woche -4 Wochen | Berechnung: weekly | Item-Type: num - -- verbrauch_monat_minus1: Verbrauch Vormonat (aktueller Monat -1) | Berechnung: monthly | Item-Type: num - -- verbrauch_monat_minus2: Verbrauch aktueller Monat -2 Monate | Berechnung: monthly | Item-Type: num - -- verbrauch_monat_minus3: Verbrauch aktueller Monat -3 Monate | Berechnung: monthly | Item-Type: num - -- verbrauch_monat_minus4: Verbrauch aktueller Monat -4 Monate | Berechnung: monthly | Item-Type: num - -- verbrauch_monat_minus12: Verbrauch aktueller Monat -12 Monate | Berechnung: monthly | Item-Type: num - -- verbrauch_jahr_minus1: Verbrauch Vorjahr (aktuelles Jahr -1 Jahr) | Berechnung: yearly | Item-Type: num - -- verbrauch_jahr_minus2: Verbrauch aktuelles Jahr -2 Jahre | Berechnung: yearly | Item-Type: num - -- verbrauch_jahr_minus3: Verbrauch aktuelles Jahr -3 Jahre | Berechnung: yearly | Item-Type: num - -- verbrauch_rolling_12m_heute_minus1: Verbrauch der letzten 12 Monate ausgehend im Ende des letzten Tages | Berechnung: daily | Item-Type: num - -- verbrauch_rolling_12m_tag_minus1: Verbrauch der letzten 12 Monate ausgehend im Ende des letzten Tages | Berechnung: daily | Item-Type: num - -- verbrauch_rolling_12m_woche_minus1: Verbrauch der letzten 12 Monate ausgehend im Ende der letzten Woche | Berechnung: weekly | Item-Type: num - -- verbrauch_rolling_12m_monat_minus1: Verbrauch der letzten 12 Monate ausgehend im Ende des letzten Monats | Berechnung: monthly | Item-Type: num - -- verbrauch_rolling_12m_jahr_minus1: Verbrauch der letzten 12 Monate ausgehend im Ende des letzten Jahres | Berechnung: yearly | Item-Type: num - -- verbrauch_jahreszeitraum_minus1: Verbrauch seit dem 1.1. bis zum heutigen Tag des Vorjahres | Berechnung: daily | Item-Type: num - -- verbrauch_jahreszeitraum_minus2: Verbrauch seit dem 1.1. bis zum heutigen Tag vor 2 Jahren | Berechnung: daily | Item-Type: num - -- verbrauch_jahreszeitraum_minus3: Verbrauch seit dem 1.1. bis zum heutigen Tag vor 3 Jahren | Berechnung: daily | Item-Type: num - -- zaehlerstand_heute_minus1: Zählerstand / Wert am Ende des letzten Tages (heute -1 Tag) | Berechnung: daily | Item-Type: num - -- zaehlerstand_heute_minus2: Zählerstand / Wert am Ende des vorletzten Tages (heute -2 Tag) | Berechnung: daily | Item-Type: num - -- zaehlerstand_heute_minus3: Zählerstand / Wert am Ende des vorvorletzten Tages (heute -3 Tag) | Berechnung: daily | Item-Type: num - -- zaehlerstand_tag_minus1: Zählerstand / Wert am Ende des letzten Tages (heute -1 Tag) | Berechnung: daily | Item-Type: num - -- zaehlerstand_tag_minus2: Zählerstand / Wert am Ende des vorletzten Tages (heute -2 Tag) | Berechnung: daily | Item-Type: num - -- zaehlerstand_tag_minus3: Zählerstand / Wert am Ende des vorvorletzten Tages (heute -3 Tag) | Berechnung: daily | Item-Type: num - -- zaehlerstand_woche_minus1: Zählerstand / Wert am Ende der vorvorletzten Woche (aktuelle Woche -1 Woche) | Berechnung: weekly | Item-Type: num - -- zaehlerstand_woche_minus2: Zählerstand / Wert am Ende der vorletzten Woche (aktuelle Woche -2 Wochen) | Berechnung: weekly | Item-Type: num - -- zaehlerstand_woche_minus3: Zählerstand / Wert am Ende der aktuellen Woche -3 Wochen | Berechnung: weekly | Item-Type: num - -- zaehlerstand_monat_minus1: Zählerstand / Wert am Ende des letzten Monates (aktueller Monat -1 Monat) | Berechnung: monthly | Item-Type: num - -- zaehlerstand_monat_minus2: Zählerstand / Wert am Ende des vorletzten Monates (aktueller Monat -2 Monate) | Berechnung: monthly | Item-Type: num - -- zaehlerstand_monat_minus3: Zählerstand / Wert am Ende des aktuellen Monats -3 Monate | Berechnung: monthly | Item-Type: num - -- zaehlerstand_jahr_minus1: Zählerstand / Wert am Ende des letzten Jahres (aktuelles Jahr -1 Jahr) | Berechnung: yearly | Item-Type: num - -- zaehlerstand_jahr_minus2: Zählerstand / Wert am Ende des vorletzten Jahres (aktuelles Jahr -2 Jahre) | Berechnung: yearly | Item-Type: num - -- zaehlerstand_jahr_minus3: Zählerstand / Wert am Ende des aktuellen Jahres -3 Jahre | Berechnung: yearly | Item-Type: num - -- minmax_last_24h_min: minimaler Wert der letzten 24h | Berechnung: daily | Item-Type: num - -- minmax_last_24h_max: maximaler Wert der letzten 24h | Berechnung: daily | Item-Type: num - -- minmax_last_24h_avg: durchschnittlicher Wert der letzten 24h | Berechnung: daily | Item-Type: num - -- minmax_last_7d_min: minimaler Wert der letzten 7 Tage | Berechnung: daily | Item-Type: num - -- minmax_last_7d_max: maximaler Wert der letzten 7 Tage | Berechnung: daily | Item-Type: num - -- minmax_last_7d_avg: durchschnittlicher Wert der letzten 7 Tage | Berechnung: daily | Item-Type: num - -- minmax_heute_min: Minimalwert seit Tagesbeginn | Berechnung: onchange | Item-Type: num - -- minmax_heute_max: Maximalwert seit Tagesbeginn | Berechnung: onchange | Item-Type: num - -- minmax_heute_avg: Durschnittswert seit Tagesbeginn | Berechnung: onchange | Item-Type: num - -- minmax_heute_minus1_min: Minimalwert gestern (heute -1 Tag) | Berechnung: daily | Item-Type: num - -- minmax_heute_minus1_max: Maximalwert gestern (heute -1 Tag) | Berechnung: daily | Item-Type: num - -- minmax_heute_minus1_avg: Durchschnittswert gestern (heute -1 Tag) | Berechnung: daily | Item-Type: num - -- minmax_heute_minus2_min: Minimalwert vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num - -- minmax_heute_minus2_max: Maximalwert vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num - -- minmax_heute_minus2_avg: Durchschnittswert vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num - -- minmax_heute_minus3_min: Minimalwert heute vor 3 Tagen | Berechnung: daily | Item-Type: num - -- minmax_heute_minus3_max: Maximalwert heute vor 3 Tagen | Berechnung: daily | Item-Type: num - -- minmax_heute_minus3_avg: Durchschnittswert heute vor 3 Tagen | Berechnung: daily | Item-Type: num - -- minmax_tag_min: Minimalwert seit Tagesbeginn | Berechnung: onchange | Item-Type: num - -- minmax_tag_max: Maximalwert seit Tagesbeginn | Berechnung: onchange | Item-Type: num - -- minmax_tag_avg: Durschnittswert seit Tagesbeginn | Berechnung: onchange | Item-Type: num - -- minmax_tag_minus1_min: Minimalwert gestern (heute -1 Tag) | Berechnung: daily | Item-Type: num - -- minmax_tag_minus1_max: Maximalwert gestern (heute -1 Tag) | Berechnung: daily | Item-Type: num - -- minmax_tag_minus1_avg: Durchschnittswert gestern (heute -1 Tag) | Berechnung: daily | Item-Type: num - -- minmax_tag_minus2_min: Minimalwert vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num - -- minmax_tag_minus2_max: Maximalwert vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num - -- minmax_tag_minus2_avg: Durchschnittswert vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num - -- minmax_tag_minus3_min: Minimalwert heute vor 3 Tagen | Berechnung: daily | Item-Type: num - -- minmax_tag_minus3_max: Maximalwert heute vor 3 Tagen | Berechnung: daily | Item-Type: num - -- minmax_tag_minus3_avg: Durchschnittswert heute vor 3 Tagen | Berechnung: daily | Item-Type: num - -- minmax_woche_min: Minimalwert seit Wochenbeginn | Berechnung: onchange | Item-Type: num - -- minmax_woche_max: Maximalwert seit Wochenbeginn | Berechnung: onchange | Item-Type: num - -- minmax_woche_minus1_min: Minimalwert Vorwoche (aktuelle Woche -1) | Berechnung: weekly | Item-Type: num - -- minmax_woche_minus1_max: Maximalwert Vorwoche (aktuelle Woche -1) | Berechnung: weekly | Item-Type: num - -- minmax_woche_minus1_avg: Durchschnittswert Vorwoche (aktuelle Woche -1) | Berechnung: weekly | Item-Type: num - -- minmax_woche_minus2_min: Minimalwert aktuelle Woche -2 Wochen | Berechnung: weekly | Item-Type: num - -- minmax_woche_minus2_max: Maximalwert aktuelle Woche -2 Wochen | Berechnung: weekly | Item-Type: num - -- minmax_woche_minus2_avg: Durchschnittswert aktuelle Woche -2 Wochen | Berechnung: weekly | Item-Type: num - -- minmax_monat_min: Minimalwert seit Monatsbeginn | Berechnung: onchange | Item-Type: num - -- minmax_monat_max: Maximalwert seit Monatsbeginn | Berechnung: onchange | Item-Type: num - -- minmax_monat_minus1_min: Minimalwert Vormonat (aktueller Monat -1) | Berechnung: monthly | Item-Type: num - -- minmax_monat_minus1_max: Maximalwert Vormonat (aktueller Monat -1) | Berechnung: monthly | Item-Type: num - -- minmax_monat_minus1_avg: Durchschnittswert Vormonat (aktueller Monat -1) | Berechnung: monthly | Item-Type: num - -- minmax_monat_minus2_min: Minimalwert aktueller Monat -2 Monate | Berechnung: monthly | Item-Type: num - -- minmax_monat_minus2_max: Maximalwert aktueller Monat -2 Monate | Berechnung: monthly | Item-Type: num - -- minmax_monat_minus2_avg: Durchschnittswert aktueller Monat -2 Monate | Berechnung: monthly | Item-Type: num - -- minmax_jahr_min: Minimalwert seit Jahresbeginn | Berechnung: onchange | Item-Type: num - -- minmax_jahr_max: Maximalwert seit Jahresbeginn | Berechnung: onchange | Item-Type: num - -- minmax_jahr_minus1_min: Minimalwert Vorjahr (aktuelles Jahr -1 Jahr) | Berechnung: yearly | Item-Type: num - -- minmax_jahr_minus1_max: Maximalwert Vorjahr (aktuelles Jahr -1 Jahr) | Berechnung: yearly | Item-Type: num - -- minmax_jahr_minus1_avg: Durchschnittswert Vorjahr (aktuelles Jahr -1 Jahr) | Berechnung: yearly | Item-Type: num - -- tagesmitteltemperatur_heute: Tagesmitteltemperatur heute | Berechnung: onchange | Item-Type: num - -- tagesmitteltemperatur_heute_minus1: Tagesmitteltemperatur des letzten Tages (heute -1 Tag) | Berechnung: daily | Item-Type: num - -- tagesmitteltemperatur_heute_minus2: Tagesmitteltemperatur des vorletzten Tages (heute -2 Tag) | Berechnung: daily | Item-Type: num - -- tagesmitteltemperatur_heute_minus3: Tagesmitteltemperatur des vorvorletzten Tages (heute -3 Tag) | Berechnung: daily | Item-Type: num - -- tagesmitteltemperatur_tag: Tagesmitteltemperatur heute | Berechnung: onchange | Item-Type: num - -- tagesmitteltemperatur_tag_minus1: Tagesmitteltemperatur des letzten Tages (heute -1 Tag) | Berechnung: daily | Item-Type: num - -- tagesmitteltemperatur_tag_minus2: Tagesmitteltemperatur des vorletzten Tages (heute -2 Tag) | Berechnung: daily | Item-Type: num - -- tagesmitteltemperatur_tag_minus3: Tagesmitteltemperatur des vorvorletzten Tages (heute -3 Tag) | Berechnung: daily | Item-Type: num - -- serie_minmax_monat_min_15m: monatlicher Minimalwert der letzten 15 Monate (gleitend) | Berechnung: monthly | Item-Type: list - -- serie_minmax_monat_max_15m: monatlicher Maximalwert der letzten 15 Monate (gleitend) | Berechnung: monthly | Item-Type: list - -- serie_minmax_monat_avg_15m: monatlicher Mittelwert der letzten 15 Monate (gleitend) | Berechnung: monthly | Item-Type: list - -- serie_minmax_woche_min_30w: wöchentlicher Minimalwert der letzten 30 Wochen (gleitend) | Berechnung: weekly | Item-Type: list - -- serie_minmax_woche_max_30w: wöchentlicher Maximalwert der letzten 30 Wochen (gleitend) | Berechnung: weekly | Item-Type: list - -- serie_minmax_woche_avg_30w: wöchentlicher Mittelwert der letzten 30 Wochen (gleitend) | Berechnung: weekly | Item-Type: list - -- serie_minmax_tag_min_30d: täglicher Minimalwert der letzten 30 Tage (gleitend) | Berechnung: daily | Item-Type: list - -- serie_minmax_tag_max_30d: täglicher Maximalwert der letzten 30 Tage (gleitend) | Berechnung: daily | Item-Type: list - -- serie_minmax_tag_avg_30d: täglicher Mittelwert der letzten 30 Tage (gleitend) | Berechnung: daily | Item-Type: list - -- serie_verbrauch_tag_30d: Verbrauch pro Tag der letzten 30 Tage | Berechnung: daily | Item-Type: list - -- serie_verbrauch_woche_30w: Verbrauch pro Woche der letzten 30 Wochen | Berechnung: weekly | Item-Type: list - -- serie_verbrauch_monat_18m: Verbrauch pro Monat der letzten 18 Monate | Berechnung: monthly | Item-Type: list - -- serie_zaehlerstand_tag_30d: Zählerstand am Tagesende der letzten 30 Tage | Berechnung: daily | Item-Type: list - -- serie_zaehlerstand_woche_30w: Zählerstand am Wochenende der letzten 30 Wochen | Berechnung: weekly | Item-Type: list - -- serie_zaehlerstand_monat_18m: Zählerstand am Monatsende der letzten 18 Monate | Berechnung: monthly | Item-Type: list - -- serie_waermesumme_monat_24m: monatliche Wärmesumme der letzten 24 Monate | Berechnung: monthly | Item-Type: list - -- serie_kaeltesumme_monat_24m: monatliche Kältesumme der letzten 24 Monate | Berechnung: monthly | Item-Type: list - -- serie_tagesmittelwert_0d: Tagesmittelwert für den aktuellen Tag | Berechnung: daily | Item-Type: list - -- serie_tagesmittelwert_stunde_0d: Stundenmittelwert für den aktuellen Tag | Berechnung: daily | Item-Type: list - -- serie_tagesmittelwert_stunde_30_0d: Stundenmittelwert für den aktuellen Tag | Berechnung: daily | Item-Type: list - -- serie_tagesmittelwert_tag_stunde_30d: Stundenmittelwert pro Tag der letzten 30 Tage (bspw. zur Berechnung der Tagesmitteltemperatur basierend auf den Mittelwert der Temperatur pro Stunde | Berechnung: daily | Item-Type: list - -- general_oldest_value: Ausgabe des ältesten Wertes des entsprechenden "Parent-Items" mit database Attribut | Berechnung: no | Item-Type: num - -- general_oldest_log: Ausgabe des Timestamp des ältesten Eintrages des entsprechenden "Parent-Items" mit database Attribut | Berechnung: no | Item-Type: list - -- kaeltesumme: Berechnet die Kältesumme für einen Zeitraum, db_addon_params: (year=optional, month=optional) | Berechnung: daily | Item-Type: num - -- waermesumme: Berechnet die Wärmesumme für einen Zeitraum, db_addon_params: (year=optional, month=optional) | Berechnung: daily | Item-Type: num - -- gruenlandtempsumme: Berechnet die Grünlandtemperatursumme für einen Zeitraum, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num - -- wachstumsgradtage: Berechnet die Wachstumsgradtage auf Basis der stündlichen Durchschnittswerte eines Tages für das laufende Jahr mit an Angabe des Temperaturschwellenwertes (threshold=Schwellentemperatur) | Berechnung: daily | Item-Type: num - -- wuestentage: Berechnet die Anzahl der Wüstentage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num - -- heisse_tage: Berechnet die Anzahl der heissen Tage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num - -- tropennaechte: Berechnet die Anzahl der Tropennächte des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num - -- sommertage: Berechnet die Anzahl der Sommertage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num - -- heiztage: Berechnet die Anzahl der Heiztage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num - -- vegetationstage: Berechnet die Anzahl der Vegatationstage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num - -- frosttage: Berechnet die Anzahl der Frosttage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num - -- eistage: Berechnet die Anzahl der Eistage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num - -- tagesmitteltemperatur: Berechnet die Tagesmitteltemperatur auf Basis der stündlichen Durchschnittswerte eines Tages für die angegebene Anzahl von Tagen (timeframe=day, count=integer) | Berechnung: daily | Item-Type: list - -- db_request: Abfrage der DB: db_addon_params: (func=mandatory, item=mandatory, timespan=mandatory, start=optional, end=optional, count=optional, group=optional, group2=optional) | Berechnung: group | Item-Type: list - -- minmax: Berechnet einen min/max/avg Wert für einen bestimmen Zeitraum: db_addon_params: (func=mandatory, timeframe=mandatory, start=mandatory) | Berechnung: timeframe | Item-Type: num - -- minmax_last: 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) | Berechnung: timeframe | Item-Type: num - -- verbrauch: Berechnet einen Verbrauchswert für einen bestimmen Zeitraum: db_addon_params: (timeframe=mandatory, start=mandatory end=mandatory) | Berechnung: timeframe | Item-Type: num - -- zaehlerstand: Berechnet einen Zählerstand für einen bestimmen Zeitpunkt: db_addon_params: (timeframe=mandatory, start=mandatory) | Berechnung: timeframe | Item-Type: num - - -db_addon_info -------------- - -- db_version: Version der verbundenen Datenbank | Berechnung: no | Item-Type: str - - -db_addon_admin --------------- - -- suspend: Unterbricht die Aktivitäten des Plugin | Berechnung: no | Item-Type: bool - -- recalc_all: Startet einen Neuberechnungslauf aller on-demand Items | Berechnung: no | Item-Type: bool - -- clean_cache_values: Löscht Plugin-Cache und damit alle im Plugin zwischengespeicherten Werte | Berechnung: no | Item-Type: bool - - -Hinweise -======== - - - Das Plugin startet die Berechnungen der Werte nach einer gewissen (konfigurierbaren) Zeit (Attribut `startup_run_delay`) - nach dem Start von shNG, um den Startvorgang nicht zu beeinflussen. - - - Bei Start werden automatisch nur die Items berechnet, für das das Attribute `db_addon_startup` gesetzt wurde. Alle anderen - Items werden erst zur konfigurierten Zeit berechnet. Das Attribute `db_addon_startup` kann auch direkt am `Database-Item` - gesetzt werden. Dabei wird das Attribut auf alle darunter liegenden `db_addon-Items` (bspw. bei Verwendung von structs) vererbt. - Über das WebIF kann die Berechnung aller definierten Items ausgelöst werden. - - - Für sogenannte `on_change` Items, also Items, deren Berechnung bis zum Jetzt (bspw. verbrauch-heute) gehen, wird die Berechnung - immer bei eintreffen eines neuen Wertes gestartet. Zu Reduktion der Belastung auf die Datenbank werden die Werte für das Ende der - letzten Periode gecached. - - - Berechnungen werden nur ausgeführt, wenn für den kompletten abgefragten Zeitraum Werte in der Datenbank vorliegen. Wird bspw. - der Verbrauch des letzten Monats abgefragt wobei erst Werte ab dem 3. des Monats in der Datenbank sind, wird die Berechnung abgebrochen. - - - Mit dem Attribut `use_oldest_entry` kann dieses Verhalten verändert werden. Ist das Attribut gesetzt, wird, wenn für den - Beginn der Abfragezeitraums keinen Werte vorliegen, der älteste Eintrag der Datenbank genutzt. - - - Für die Auswertung kann es nützlich sein, bestimmte Werte aus der Datenbank bei der Berechnung auszublenden. Hierfür stehen - 2 Möglichkeiten zur Verfügung: - - Plugin-Attribut `ignore_0`: (list of strings) Bei Items, bei denen ein String aus der Liste im Pfadnamen vorkommt, - werden 0-Werte (val_num = 0) bei Datenbankauswertungen ignoriert. Hat also das Attribut den Wert ['temp'] werden bei allen Items mit - 'temp' im Pfadnamen die 0-Werte bei der Auswertung ignoriert. - - Item-Attribut `db_addon_ignore_value`: (num) Dieser Wert wird bei der Abfrage bzw. Auswertung der Datenbank für diese - Item ignoriert. - - - Das Plugin enthält sehr ausführliche Logginginformation. Bei unerwartetem Verhalten, den LogLevel entsprechend anpassen, - um mehr information zu erhalten. - - - Berechnungen des Plugins können im WebIF unterbrochen werden. Auch das gesamte Plugin kann pausiert werden. Dies kann bei - starker Systembelastung nützlich sein. - - -Beispiele -========= - -Verbrauch ---------- - -Soll bspw. der Verbrauch von Wasser ausgewertet werden, so ist dies wie folgt möglich: - - -.. code-block:: yaml - - wasserzaehler: - zaehlerstand: - type: num - knx_dpt: 12 - knx_cache: 5/3/4 - eval: round(value/1000, 1) - database: init - struct: - - db_addon.verbrauch_1 - - db_addon.verbrauch_2 - - db_addon.zaehlerstand_1 - -Die Werte des Wasserzählerstandes werden in die Datenbank geschrieben und darauf basierend ausgewertet. Die structs -'db_addon.verbrauch_1' und 'db_addon.verbrauch_2' stellen entsprechende Items für die Verbrauchsauswerten zur Verfügung. - -minmax ------- - -Soll bspw. die minimalen und maximalen Temperaturen ausgewertet werden, kann dies so umgesetzt werden: - -.. code-block:: yaml - - temperature: - aussen: - nord: - name: Außentemp Nordseite - type: num - visu_acl: ro - knx_dpt: 9 - knx_cache: 6/5/1 - database: init - struct: - - db_addon.minmax_1 - - db_addon.minmax_2 - -Die Temperaturwerte werden in die Datenbank geschrieben und darauf basierend ausgewertet. Die structs -'db_addon.minmax_1' und 'db_addon.minmax_2' stellen entsprechende Items für die min/max Auswertung zur Verfügung. - -| - -Web Interface -============= - -Das WebIF stellt neben der Ansicht verbundener Items und deren Parameter und Werte auch Funktionen für die -Administration des Plugins bereit. - -Es stehen Button für: - -- Neuberechnung aller Items -- Abbruch eines aktiven Berechnungslaufes -- Pausieren des Plugins -- Wiederaufnahme des Plugins - -bereit. - -Achtung: Das Auslösen einer kompletten Neuberechnung aller Items kann zu einer starken Belastung der Datenbank -aufgrund vieler Leseanfragen führen. - - -db_addon Items --------------- - -Dieser Reiter des Webinterface zeigt die Items an, für die ein DatabaseAddon Attribut konfiguriert ist. - - -db_addon Maintenance --------------------- - -Das Webinterface zeigt detaillierte Informationen über die im Plugin verfügbaren Daten an. -Dies dient der Maintenance bzw. Fehlersuche. Dieser Tab ist nur bei Log-Level "Debug" verfügbar. - - -Erläuterungen zu Temperatursummen -================================= - - -Grünlandtemperatursumme ------------------------ - -Beim Grünland wird die Wärmesumme nach Ernst und Loeper benutzt, um den Vegetationsbeginn und somit den Termin von Düngungsmaßnahmen zu bestimmen. -Dabei erfolgt die Aufsummierung der Tagesmitteltemperaturen über 0 °C, wobei der Januar mit 0.5 und der Februar mit 0.75 gewichtet wird. -Bei einer Wärmesumme von 200 Grad ist eine Düngung angesagt. - -siehe: https://de.wikipedia.org/wiki/Gr%C3%BCnlandtemperatursumme - -Folgende Parameter sind möglich / notwendig: - - -.. code-block:: yaml - - db_addon_params: "year=current" - -- year: Jahreszahl (str oder int), für das die Berechnung ausgeführt werden soll oder "current" für aktuelles Jahr (default: 'current') - - -Wachstumsgradtag ----------------- -Der Begriff Wachstumsgradtage (WGT) ist ein Überbegriff für verschiedene Größen. -Gemeinsam ist ihnen, daß zur Berechnung eine Lufttemperatur von einem Schwellenwert subtrahiert wird. -Je nach Fragestellung und Pflanzenart werden der Schwellenwert unterschiedlich gewählt und die Temperatur unterschiedlich bestimmt. -Verfügbar sind die Berechnung über 0) "einfachen Durchschnitt der Tagestemperaturen", 1) "modifizierten Durchschnitt der Tagestemperaturen" -und 2) Anzahl der Tage, deren Mitteltempertatur oberhalb der Schwellentemperatur lag. - -siehe https://de.wikipedia.org/wiki/Wachstumsgradtag - -Folgende Parameter sind möglich / notwendig: - -.. code-block:: yaml - - db_addon_params: "year=current, method=1, threshold=10" - -- year: Jahreszahl (str oder int), für das die Berechnung ausgeführt werden soll oder "current" für aktuelles Jahr (default: 'current') -- method: 0-Berechnung über "einfachen Durchschnitt der Tagestemperaturen", 1-Berechnung über "modifizierten Durchschnitt (default: 0) -der Tagestemperaturen" 2-Anzahl der Tage, mit Mitteltempertatur oberhalb Schwellentemperatur// 10, 11 Ausgabe aus Zeitserie -- threshold: Schwellentemperatur in °C (int) (default: 10) - - -Wärmesumme ----------- - -Die Wärmesumme soll eine Aussage über den Sommer und die Pflanzenreife liefern. Es gibt keine eindeutige Definition der Größe "Wärmesumme". -Berechnet wird die Wärmesumme als Summe aller Tagesmitteltemperaturen über einem Schwellenwert ab dem 1.1. des Jahres. - -siehe https://de.wikipedia.org/wiki/W%C3%A4rmesumme - -Folgende Parameter sind möglich / notwendig: - -.. code-block:: yaml - - db_addon_params: "year=current, month=1, threshold=10" - -- year: Jahreszahl (str oder int), für das die Berechnung ausgeführt werden soll oder "current" für aktuelles Jahr (default: 'current') -- month: Monat (int) des Jahres, für das die Berechnung ausgeführt werden soll (optional) (default: None) -- threshold: Schwellentemperatur in °C (int) (default: 10) - - -Kältesumme ----------- - -Die Kältesumme soll eine Aussage über die Härte des Winters liefern. -Berechnet wird die Kältesumme als Summe aller negativen Tagesmitteltemperaturen ab dem 21.9. des Jahres bis 31.3. des Folgejahres. - -siehe https://de.wikipedia.org/wiki/K%C3%A4ltesumme - -Folgende Parameter sind möglich / notwendig: - -.. code-block:: yaml - - db_addon_params: "year=current, month=1" - -- year: Jahreszahl (str oder int), für das die Berechnung ausgeführt werden soll oder "current" für aktuelles Jahr (default: 'current') -- month: Monat (int) des Jahres, für das die Berechnung ausgeführt werden soll (optional) (default: None) - - -Tagesmitteltemperatur ---------------------- - -Die Tagesmitteltemperatur wird auf Basis der stündlichen Durchschnittswerte eines Tages (aller in der DB enthaltenen Datensätze) -für die angegebene Anzahl von Tagen (days=optional) berechnet. - - - -Vorgehen bei Funktionserweiterung des Plugins bzw. Ergänzung weiterer Werte für Item-Attribute ----------------------------------------------------------------------------------------------- - -Aufgrund der Vielzahl der möglichen Werte der Itemattribute, insbesondere des Itemattributes `db_addon_fct`, wurde die Erstellung/Update -der entsprechenden Teile der `plugin.yam` sowie die Erstellung der Datei `item_attributes.py`, die vom Plugin verwendet wird, automatisiert. - -Die Masterinformationen für alle Itemattribute sowie die Skripte zum Erstellen/Update der beiden Dateien sind in der -Datei `item_attributes_master.py` enthalten. - -.. important:: - - Korrekturen, Erweiterungen etc. der Itemattribute sollten nur in der Datei `item_attributes_master.py` - im Dict der Variable `ITEM_ATTRIBUTS` vorgenommen werden. Das Ausführen der Datei `item_attributes_master.py` (main) - erstellt die `item_attributes.py` und aktualisiert die `plugin.yaml` entsprechend. -Dieses Kapitel wurde automatisch durch Ausführen des Skripts in der Datei 'item_attributes_master.py' erstellt. - -Nachfolgend eine Auflistung der möglichen Attribute für das Plugin im Format: Attribute: Beschreibung | Berechnungszyklus | Item-Type - - -db_addon_fct ------------- - -- verbrauch_heute: Verbrauch am heutigen Tag (Differenz zwischen aktuellem Wert und den Wert am Ende des vorherigen Tages) | Berechnung: daily | Item-Type: num - -- verbrauch_tag: Verbrauch am heutigen Tag (Differenz zwischen aktuellem Wert und den Wert am Ende des vorherigen Tages) | Berechnung: daily | Item-Type: num - -- verbrauch_woche: Verbrauch in der aktuellen Woche | Berechnung: weekly | Item-Type: num - -- verbrauch_monat: Verbrauch im aktuellen Monat | Berechnung: monthly | Item-Type: num - -- verbrauch_jahr: Verbrauch im aktuellen Jahr | Berechnung: yearly | Item-Type: num - -- verbrauch_last_24h: Verbrauch innerhalb letzten 24h | Berechnung: hourly | Item-Type: num - -- verbrauch_last_7d: Verbrauch innerhalb letzten 7 Tage | Berechnung: hourly | Item-Type: num - -- verbrauch_heute_minus1: Verbrauch gestern (heute -1 Tag) (Differenz zwischen Wert am Ende des gestrigen Tages und dem Wert am Ende des Tages davor) | Berechnung: daily | Item-Type: num - -- verbrauch_heute_minus2: Verbrauch vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num - -- verbrauch_heute_minus3: Verbrauch heute -3 Tage | Berechnung: daily | Item-Type: num - -- verbrauch_heute_minus4: Verbrauch heute -4 Tage | Berechnung: daily | Item-Type: num - -- verbrauch_heute_minus5: Verbrauch heute -5 Tage | Berechnung: daily | Item-Type: num - -- verbrauch_heute_minus6: Verbrauch heute -6 Tage | Berechnung: daily | Item-Type: num - -- verbrauch_heute_minus7: Verbrauch heute -7 Tage | Berechnung: daily | Item-Type: num - -- verbrauch_heute_minus8: Verbrauch heute -8 Tage | Berechnung: daily | Item-Type: num - -- verbrauch_tag_minus1: Verbrauch gestern (heute -1 Tag) (Differenz zwischen Wert am Ende des gestrigen Tages und dem Wert am Ende des Tages davor) | Berechnung: daily | Item-Type: num - -- verbrauch_tag_minus2: Verbrauch vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num - -- verbrauch_tag_minus3: Verbrauch heute -3 Tage | Berechnung: daily | Item-Type: num - -- verbrauch_tag_minus4: Verbrauch heute -4 Tage | Berechnung: daily | Item-Type: num - -- verbrauch_tag_minus5: Verbrauch heute -5 Tage | Berechnung: daily | Item-Type: num - -- verbrauch_tag_minus6: Verbrauch heute -6 Tage | Berechnung: daily | Item-Type: num - -- verbrauch_tag_minus7: Verbrauch heute -7 Tage | Berechnung: daily | Item-Type: num - -- verbrauch_tag_minus8: Verbrauch heute -8 Tage | Berechnung: daily | Item-Type: num - -- verbrauch_woche_minus1: Verbrauch Vorwoche (aktuelle Woche -1) | Berechnung: weekly | Item-Type: num - -- verbrauch_woche_minus2: Verbrauch aktuelle Woche -2 Wochen | Berechnung: weekly | Item-Type: num - -- verbrauch_woche_minus3: Verbrauch aktuelle Woche -3 Wochen | Berechnung: weekly | Item-Type: num - -- verbrauch_woche_minus4: Verbrauch aktuelle Woche -4 Wochen | Berechnung: weekly | Item-Type: num - -- verbrauch_monat_minus1: Verbrauch Vormonat (aktueller Monat -1) | Berechnung: monthly | Item-Type: num - -- verbrauch_monat_minus2: Verbrauch aktueller Monat -2 Monate | Berechnung: monthly | Item-Type: num - -- verbrauch_monat_minus3: Verbrauch aktueller Monat -3 Monate | Berechnung: monthly | Item-Type: num - -- verbrauch_monat_minus4: Verbrauch aktueller Monat -4 Monate | Berechnung: monthly | Item-Type: num - -- verbrauch_monat_minus12: Verbrauch aktueller Monat -12 Monate | Berechnung: monthly | Item-Type: num - -- verbrauch_jahr_minus1: Verbrauch Vorjahr (aktuelles Jahr -1 Jahr) | Berechnung: yearly | Item-Type: num - -- verbrauch_jahr_minus2: Verbrauch aktuelles Jahr -2 Jahre | Berechnung: yearly | Item-Type: num - -- verbrauch_jahr_minus3: Verbrauch aktuelles Jahr -3 Jahre | Berechnung: yearly | Item-Type: num - -- verbrauch_rolling_12m_heute_minus1: Verbrauch der letzten 12 Monate ausgehend im Ende des letzten Tages | Berechnung: daily | Item-Type: num - -- verbrauch_rolling_12m_tag_minus1: Verbrauch der letzten 12 Monate ausgehend im Ende des letzten Tages | Berechnung: daily | Item-Type: num - -- verbrauch_rolling_12m_woche_minus1: Verbrauch der letzten 12 Monate ausgehend im Ende der letzten Woche | Berechnung: weekly | Item-Type: num - -- verbrauch_rolling_12m_monat_minus1: Verbrauch der letzten 12 Monate ausgehend im Ende des letzten Monats | Berechnung: monthly | Item-Type: num - -- verbrauch_rolling_12m_jahr_minus1: Verbrauch der letzten 12 Monate ausgehend im Ende des letzten Jahres | Berechnung: yearly | Item-Type: num - -- verbrauch_jahreszeitraum_minus1: Verbrauch seit dem 1.1. bis zum heutigen Tag des Vorjahres | Berechnung: daily | Item-Type: num - -- verbrauch_jahreszeitraum_minus2: Verbrauch seit dem 1.1. bis zum heutigen Tag vor 2 Jahren | Berechnung: daily | Item-Type: num - -- verbrauch_jahreszeitraum_minus3: Verbrauch seit dem 1.1. bis zum heutigen Tag vor 3 Jahren | Berechnung: daily | Item-Type: num - -- zaehlerstand_heute_minus1: Zählerstand / Wert am Ende des letzten Tages (heute -1 Tag) | Berechnung: daily | Item-Type: num - -- zaehlerstand_heute_minus2: Zählerstand / Wert am Ende des vorletzten Tages (heute -2 Tag) | Berechnung: daily | Item-Type: num - -- zaehlerstand_heute_minus3: Zählerstand / Wert am Ende des vorvorletzten Tages (heute -3 Tag) | Berechnung: daily | Item-Type: num - -- zaehlerstand_tag_minus1: Zählerstand / Wert am Ende des letzten Tages (heute -1 Tag) | Berechnung: daily | Item-Type: num - -- zaehlerstand_tag_minus2: Zählerstand / Wert am Ende des vorletzten Tages (heute -2 Tag) | Berechnung: daily | Item-Type: num - -- zaehlerstand_tag_minus3: Zählerstand / Wert am Ende des vorvorletzten Tages (heute -3 Tag) | Berechnung: daily | Item-Type: num - -- zaehlerstand_woche_minus1: Zählerstand / Wert am Ende der vorvorletzten Woche (aktuelle Woche -1 Woche) | Berechnung: weekly | Item-Type: num - -- zaehlerstand_woche_minus2: Zählerstand / Wert am Ende der vorletzten Woche (aktuelle Woche -2 Wochen) | Berechnung: weekly | Item-Type: num - -- zaehlerstand_woche_minus3: Zählerstand / Wert am Ende der aktuellen Woche -3 Wochen | Berechnung: weekly | Item-Type: num - -- zaehlerstand_monat_minus1: Zählerstand / Wert am Ende des letzten Monates (aktueller Monat -1 Monat) | Berechnung: monthly | Item-Type: num - -- zaehlerstand_monat_minus2: Zählerstand / Wert am Ende des vorletzten Monates (aktueller Monat -2 Monate) | Berechnung: monthly | Item-Type: num - -- zaehlerstand_monat_minus3: Zählerstand / Wert am Ende des aktuellen Monats -3 Monate | Berechnung: monthly | Item-Type: num - -- zaehlerstand_jahr_minus1: Zählerstand / Wert am Ende des letzten Jahres (aktuelles Jahr -1 Jahr) | Berechnung: yearly | Item-Type: num - -- zaehlerstand_jahr_minus2: Zählerstand / Wert am Ende des vorletzten Jahres (aktuelles Jahr -2 Jahre) | Berechnung: yearly | Item-Type: num - -- zaehlerstand_jahr_minus3: Zählerstand / Wert am Ende des aktuellen Jahres -3 Jahre | Berechnung: yearly | Item-Type: num - -- minmax_last_24h_min: minimaler Wert der letzten 24h | Berechnung: daily | Item-Type: num - -- minmax_last_24h_max: maximaler Wert der letzten 24h | Berechnung: daily | Item-Type: num - -- minmax_last_24h_avg: durchschnittlicher Wert der letzten 24h | Berechnung: daily | Item-Type: num - -- minmax_last_7d_min: minimaler Wert der letzten 7 Tage | Berechnung: daily | Item-Type: num - -- minmax_last_7d_max: maximaler Wert der letzten 7 Tage | Berechnung: daily | Item-Type: num - -- minmax_last_7d_avg: durchschnittlicher Wert der letzten 7 Tage | Berechnung: daily | Item-Type: num - -- minmax_heute_min: Minimalwert seit Tagesbeginn | Berechnung: daily | Item-Type: num - -- minmax_heute_max: Maximalwert seit Tagesbeginn | Berechnung: daily | Item-Type: num - -- minmax_heute_avg: Durschnittswert seit Tagesbeginn | Berechnung: daily | Item-Type: num - -- minmax_heute_minus1_min: Minimalwert gestern (heute -1 Tag) | Berechnung: daily | Item-Type: num - -- minmax_heute_minus1_max: Maximalwert gestern (heute -1 Tag) | Berechnung: daily | Item-Type: num - -- minmax_heute_minus1_avg: Durchschnittswert gestern (heute -1 Tag) | Berechnung: daily | Item-Type: num - -- minmax_heute_minus2_min: Minimalwert vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num - -- minmax_heute_minus2_max: Maximalwert vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num - -- minmax_heute_minus2_avg: Durchschnittswert vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num - -- minmax_heute_minus3_min: Minimalwert heute vor 3 Tagen | Berechnung: daily | Item-Type: num - -- minmax_heute_minus3_max: Maximalwert heute vor 3 Tagen | Berechnung: daily | Item-Type: num - -- minmax_heute_minus3_avg: Durchschnittswert heute vor 3 Tagen | Berechnung: daily | Item-Type: num - -- minmax_tag_min: Minimalwert seit Tagesbeginn | Berechnung: daily | Item-Type: num - -- minmax_tag_max: Maximalwert seit Tagesbeginn | Berechnung: daily | Item-Type: num - -- minmax_tag_avg: Durschnittswert seit Tagesbeginn | Berechnung: daily | Item-Type: num - -- minmax_tag_minus1_min: Minimalwert gestern (heute -1 Tag) | Berechnung: daily | Item-Type: num - -- minmax_tag_minus1_max: Maximalwert gestern (heute -1 Tag) | Berechnung: daily | Item-Type: num - -- minmax_tag_minus1_avg: Durchschnittswert gestern (heute -1 Tag) | Berechnung: daily | Item-Type: num - -- minmax_tag_minus2_min: Minimalwert vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num - -- minmax_tag_minus2_max: Maximalwert vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num - -- minmax_tag_minus2_avg: Durchschnittswert vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num - -- minmax_tag_minus3_min: Minimalwert heute vor 3 Tagen | Berechnung: daily | Item-Type: num - -- minmax_tag_minus3_max: Maximalwert heute vor 3 Tagen | Berechnung: daily | Item-Type: num - -- minmax_tag_minus3_avg: Durchschnittswert heute vor 3 Tagen | Berechnung: daily | Item-Type: num - -- minmax_woche_min: Minimalwert seit Wochenbeginn | Berechnung: weekly | Item-Type: num - -- minmax_woche_max: Maximalwert seit Wochenbeginn | Berechnung: weekly | Item-Type: num - -- minmax_woche_minus1_min: Minimalwert Vorwoche (aktuelle Woche -1) | Berechnung: weekly | Item-Type: num - -- minmax_woche_minus1_max: Maximalwert Vorwoche (aktuelle Woche -1) | Berechnung: weekly | Item-Type: num - -- minmax_woche_minus1_avg: Durchschnittswert Vorwoche (aktuelle Woche -1) | Berechnung: weekly | Item-Type: num - -- minmax_woche_minus2_min: Minimalwert aktuelle Woche -2 Wochen | Berechnung: weekly | Item-Type: num - -- minmax_woche_minus2_max: Maximalwert aktuelle Woche -2 Wochen | Berechnung: weekly | Item-Type: num - -- minmax_woche_minus2_avg: Durchschnittswert aktuelle Woche -2 Wochen | Berechnung: weekly | Item-Type: num - -- minmax_monat_min: Minimalwert seit Monatsbeginn | Berechnung: monthly | Item-Type: num - -- minmax_monat_max: Maximalwert seit Monatsbeginn | Berechnung: monthly | Item-Type: num - -- minmax_monat_minus1_min: Minimalwert Vormonat (aktueller Monat -1) | Berechnung: monthly | Item-Type: num - -- minmax_monat_minus1_max: Maximalwert Vormonat (aktueller Monat -1) | Berechnung: monthly | Item-Type: num - -- minmax_monat_minus1_avg: Durchschnittswert Vormonat (aktueller Monat -1) | Berechnung: monthly | Item-Type: num - -- minmax_monat_minus2_min: Minimalwert aktueller Monat -2 Monate | Berechnung: monthly | Item-Type: num - -- minmax_monat_minus2_max: Maximalwert aktueller Monat -2 Monate | Berechnung: monthly | Item-Type: num - -- minmax_monat_minus2_avg: Durchschnittswert aktueller Monat -2 Monate | Berechnung: monthly | Item-Type: num - -- minmax_jahr_min: Minimalwert seit Jahresbeginn | Berechnung: yearly | Item-Type: num - -- minmax_jahr_max: Maximalwert seit Jahresbeginn | Berechnung: yearly | Item-Type: num - -- minmax_jahr_minus1_min: Minimalwert Vorjahr (aktuelles Jahr -1 Jahr) | Berechnung: yearly | Item-Type: num - -- minmax_jahr_minus1_max: Maximalwert Vorjahr (aktuelles Jahr -1 Jahr) | Berechnung: yearly | Item-Type: num - -- minmax_jahr_minus1_avg: Durchschnittswert Vorjahr (aktuelles Jahr -1 Jahr) | Berechnung: yearly | Item-Type: num - -- tagesmitteltemperatur_heute: Tagesmitteltemperatur heute | Berechnung: daily | Item-Type: num - -- tagesmitteltemperatur_heute_minus1: Tagesmitteltemperatur des letzten Tages (heute -1 Tag) | Berechnung: daily | Item-Type: num - -- tagesmitteltemperatur_heute_minus2: Tagesmitteltemperatur des vorletzten Tages (heute -2 Tag) | Berechnung: daily | Item-Type: num - -- tagesmitteltemperatur_heute_minus3: Tagesmitteltemperatur des vorvorletzten Tages (heute -3 Tag) | Berechnung: daily | Item-Type: num - -- tagesmitteltemperatur_tag: Tagesmitteltemperatur heute | Berechnung: daily | Item-Type: num - -- tagesmitteltemperatur_tag_minus1: Tagesmitteltemperatur des letzten Tages (heute -1 Tag) | Berechnung: daily | Item-Type: num - -- tagesmitteltemperatur_tag_minus2: Tagesmitteltemperatur des vorletzten Tages (heute -2 Tag) | Berechnung: daily | Item-Type: num - -- tagesmitteltemperatur_tag_minus3: Tagesmitteltemperatur des vorvorletzten Tages (heute -3 Tag) | Berechnung: daily | Item-Type: num - -- serie_minmax_monat_min_15m: monatlicher Minimalwert der letzten 15 Monate (gleitend) | Berechnung: monthly | Item-Type: list - -- serie_minmax_monat_max_15m: monatlicher Maximalwert der letzten 15 Monate (gleitend) | Berechnung: monthly | Item-Type: list - -- serie_minmax_monat_avg_15m: monatlicher Mittelwert der letzten 15 Monate (gleitend) | Berechnung: monthly | Item-Type: list - -- serie_minmax_woche_min_30w: wöchentlicher Minimalwert der letzten 30 Wochen (gleitend) | Berechnung: weekly | Item-Type: list - -- serie_minmax_woche_max_30w: wöchentlicher Maximalwert der letzten 30 Wochen (gleitend) | Berechnung: weekly | Item-Type: list - -- serie_minmax_woche_avg_30w: wöchentlicher Mittelwert der letzten 30 Wochen (gleitend) | Berechnung: weekly | Item-Type: list - -- serie_minmax_tag_min_30d: täglicher Minimalwert der letzten 30 Tage (gleitend) | Berechnung: daily | Item-Type: list - -- serie_minmax_tag_max_30d: täglicher Maximalwert der letzten 30 Tage (gleitend) | Berechnung: daily | Item-Type: list - -- serie_minmax_tag_avg_30d: täglicher Mittelwert der letzten 30 Tage (gleitend) | Berechnung: daily | Item-Type: list - -- serie_verbrauch_tag_30d: Verbrauch pro Tag der letzten 30 Tage | Berechnung: daily | Item-Type: list - -- serie_verbrauch_woche_30w: Verbrauch pro Woche der letzten 30 Wochen | Berechnung: weekly | Item-Type: list - -- serie_verbrauch_monat_18m: Verbrauch pro Monat der letzten 18 Monate | Berechnung: monthly | Item-Type: list - -- serie_zaehlerstand_tag_30d: Zählerstand am Tagesende der letzten 30 Tage | Berechnung: daily | Item-Type: list - -- serie_zaehlerstand_woche_30w: Zählerstand am Wochenende der letzten 30 Wochen | Berechnung: weekly | Item-Type: list - -- serie_zaehlerstand_monat_18m: Zählerstand am Monatsende der letzten 18 Monate | Berechnung: monthly | Item-Type: list - -- serie_waermesumme_monat_24m: monatliche Wärmesumme der letzten 24 Monate | Berechnung: monthly | Item-Type: list - -- serie_kaeltesumme_monat_24m: monatliche Kältesumme der letzten 24 Monate | Berechnung: monthly | Item-Type: list - -- serie_tagesmittelwert_0d: Tagesmittelwert für den aktuellen Tag | Berechnung: daily | Item-Type: list - -- serie_tagesmittelwert_stunde_0d: Stundenmittelwert für den aktuellen Tag | Berechnung: daily | Item-Type: list - -- serie_tagesmittelwert_stunde_30_0d: Stundenmittelwert für den aktuellen Tag | Berechnung: daily | Item-Type: list - -- serie_tagesmittelwert_tag_stunde_30d: Stundenmittelwert pro Tag der letzten 30 Tage (bspw. zur Berechnung der Tagesmitteltemperatur basierend auf den Mittelwert der Temperatur pro Stunde | Berechnung: daily | Item-Type: list - -- general_oldest_value: Ausgabe des ältesten Wertes des entsprechenden "Parent-Items" mit database Attribut | Berechnung: no | Item-Type: num - -- general_oldest_log: Ausgabe des Timestamp des ältesten Eintrages des entsprechenden "Parent-Items" mit database Attribut | Berechnung: no | Item-Type: list - -- kaeltesumme: Berechnet die Kältesumme für einen Zeitraum, db_addon_params: (year=optional, month=optional) | Berechnung: daily | Item-Type: num - -- waermesumme: Berechnet die Wärmesumme für einen Zeitraum, db_addon_params: (year=optional, month=optional) | Berechnung: daily | Item-Type: num - -- gruenlandtempsumme: Berechnet die Grünlandtemperatursumme für einen Zeitraum, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num - -- wachstumsgradtage: Berechnet die Wachstumsgradtage auf Basis der stündlichen Durchschnittswerte eines Tages für das laufende Jahr mit an Angabe des Temperaturschwellenwertes (threshold=Schwellentemperatur) | Berechnung: daily | Item-Type: num - -- wuestentage: Berechnet die Anzahl der Wüstentage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num - -- heisse_tage: Berechnet die Anzahl der heissen Tage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num - -- tropennaechte: Berechnet die Anzahl der Tropennächte des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num - -- sommertage: Berechnet die Anzahl der Sommertage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num - -- heiztage: Berechnet die Anzahl der Heiztage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num - -- vegetationstage: Berechnet die Anzahl der Vegatationstage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num - -- frosttage: Berechnet die Anzahl der Frosttage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num - -- eistage: Berechnet die Anzahl der Eistage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num - -- tagesmitteltemperatur: Berechnet die Tagesmitteltemperatur auf Basis der stündlichen Durchschnittswerte eines Tages für die angegebene Anzahl von Tagen (timeframe=day, count=integer) | Berechnung: daily | Item-Type: list - -- db_request: Abfrage der DB: db_addon_params: (func=mandatory, item=mandatory, timespan=mandatory, start=optional, end=optional, count=optional, group=optional, group2=optional) | Berechnung: group | Item-Type: list - -- minmax: Berechnet einen min/max/avg Wert für einen bestimmen Zeitraum: db_addon_params: (func=mandatory, timeframe=mandatory, start=mandatory) | Berechnung: timeframe | Item-Type: num - -- minmax_last: 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) | Berechnung: timeframe | Item-Type: num - -- verbrauch: Berechnet einen Verbrauchswert für einen bestimmen Zeitraum: db_addon_params: (timeframe=mandatory, start=mandatory end=mandatory) | Berechnung: timeframe | Item-Type: num - -- zaehlerstand: Berechnet einen Zählerstand für einen bestimmen Zeitpunkt: db_addon_params: (timeframe=mandatory, start=mandatory) | Berechnung: timeframe | Item-Type: num - - -db_addon_info -------------- - -- db_version: Version der verbundenen Datenbank | Berechnung: no | Item-Type: str - - -db_addon_admin --------------- - -- suspend: Unterbricht die Aktivitäten des Plugin | Berechnung: no | Item-Type: bool - -- recalc_all: Startet einen Neuberechnungslauf aller on-demand Items | Berechnung: no | Item-Type: bool - -- clean_cache_values: Löscht Plugin-Cache und damit alle im Plugin zwischengespeicherten Werte | Berechnung: no | Item-Type: bool - - -Hinweise -======== - - - Das Plugin startet die Berechnungen der Werte nach einer gewissen (konfigurierbaren) Zeit (Attribut `startup_run_delay`) - nach dem Start von shNG, um den Startvorgang nicht zu beeinflussen. - - - Bei Start werden automatisch nur die Items berechnet, für das das Attribute `db_addon_startup` gesetzt wurde. Alle anderen - Items werden erst zur konfigurierten Zeit berechnet. Das Attribute `db_addon_startup` kann auch direkt am `Database-Item` - gesetzt werden. Dabei wird das Attribut auf alle darunter liegenden `db_addon-Items` (bspw. bei Verwendung von structs) vererbt. - Über das WebIF kann die Berechnung aller definierten Items ausgelöst werden. - - - Für sogenannte `on_change` Items, also Items, deren Berechnung bis zum Jetzt (bspw. verbrauch-heute) gehen, wird die Berechnung - immer bei eintreffen eines neuen Wertes gestartet. Zu Reduktion der Belastung auf die Datenbank werden die Werte für das Ende der - letzten Periode gecached. - - - Berechnungen werden nur ausgeführt, wenn für den kompletten abgefragten Zeitraum Werte in der Datenbank vorliegen. Wird bspw. - der Verbrauch des letzten Monats abgefragt wobei erst Werte ab dem 3. des Monats in der Datenbank sind, wird die Berechnung abgebrochen. - - - Mit dem Attribut `use_oldest_entry` kann dieses Verhalten verändert werden. Ist das Attribut gesetzt, wird, wenn für den - Beginn der Abfragezeitraums keinen Werte vorliegen, der älteste Eintrag der Datenbank genutzt. - - - Für die Auswertung kann es nützlich sein, bestimmte Werte aus der Datenbank bei der Berechnung auszublenden. Hierfür stehen - 2 Möglichkeiten zur Verfügung: - - Plugin-Attribut `ignore_0`: (list of strings) Bei Items, bei denen ein String aus der Liste im Pfadnamen vorkommt, - werden 0-Werte (val_num = 0) bei Datenbankauswertungen ignoriert. Hat also das Attribut den Wert ['temp'] werden bei allen Items mit - 'temp' im Pfadnamen die 0-Werte bei der Auswertung ignoriert. - - Item-Attribut `db_addon_ignore_value`: (num) Dieser Wert wird bei der Abfrage bzw. Auswertung der Datenbank für diese - Item ignoriert. - - - Das Plugin enthält sehr ausführliche Logginginformation. Bei unerwartetem Verhalten, den LogLevel entsprechend anpassen, - um mehr information zu erhalten. - - - Berechnungen des Plugins können im WebIF unterbrochen werden. Auch das gesamte Plugin kann pausiert werden. Dies kann bei - starker Systembelastung nützlich sein. - - -Beispiele -========= - -Verbrauch ---------- - -Soll bspw. der Verbrauch von Wasser ausgewertet werden, so ist dies wie folgt möglich: - - -.. code-block:: yaml - - wasserzaehler: - zaehlerstand: - type: num - knx_dpt: 12 - knx_cache: 5/3/4 - eval: round(value/1000, 1) - database: init - struct: - - db_addon.verbrauch_1 - - db_addon.verbrauch_2 - - db_addon.zaehlerstand_1 - -Die Werte des Wasserzählerstandes werden in die Datenbank geschrieben und darauf basierend ausgewertet. Die structs -'db_addon.verbrauch_1' und 'db_addon.verbrauch_2' stellen entsprechende Items für die Verbrauchsauswerten zur Verfügung. - -minmax ------- - -Soll bspw. die minimalen und maximalen Temperaturen ausgewertet werden, kann dies so umgesetzt werden: - -.. code-block:: yaml - - temperature: - aussen: - nord: - name: Außentemp Nordseite - type: num - visu_acl: ro - knx_dpt: 9 - knx_cache: 6/5/1 - database: init - struct: - - db_addon.minmax_1 - - db_addon.minmax_2 - -Die Temperaturwerte werden in die Datenbank geschrieben und darauf basierend ausgewertet. Die structs -'db_addon.minmax_1' und 'db_addon.minmax_2' stellen entsprechende Items für die min/max Auswertung zur Verfügung. - -| - -Web Interface -============= - -Das WebIF stellt neben der Ansicht verbundener Items und deren Parameter und Werte auch Funktionen für die -Administration des Plugins bereit. - -Es stehen Button für: - -- Neuberechnung aller Items -- Abbruch eines aktiven Berechnungslaufes -- Pausieren des Plugins -- Wiederaufnahme des Plugins - -bereit. - -Achtung: Das Auslösen einer kompletten Neuberechnung aller Items kann zu einer starken Belastung der Datenbank -aufgrund vieler Leseanfragen führen. - - -db_addon Items --------------- - -Dieser Reiter des Webinterface zeigt die Items an, für die ein DatabaseAddon Attribut konfiguriert ist. - - -db_addon Maintenance --------------------- - -Das Webinterface zeigt detaillierte Informationen über die im Plugin verfügbaren Daten an. -Dies dient der Maintenance bzw. Fehlersuche. Dieser Tab ist nur bei Log-Level "Debug" verfügbar. - - -Erläuterungen zu Temperatursummen -================================= - - -Grünlandtemperatursumme ------------------------ - -Beim Grünland wird die Wärmesumme nach Ernst und Loeper benutzt, um den Vegetationsbeginn und somit den Termin von Düngungsmaßnahmen zu bestimmen. -Dabei erfolgt die Aufsummierung der Tagesmitteltemperaturen über 0 °C, wobei der Januar mit 0.5 und der Februar mit 0.75 gewichtet wird. -Bei einer Wärmesumme von 200 Grad ist eine Düngung angesagt. - -siehe: https://de.wikipedia.org/wiki/Gr%C3%BCnlandtemperatursumme - -Folgende Parameter sind möglich / notwendig: - - -.. code-block:: yaml - - db_addon_params: "year=current" - -- year: Jahreszahl (str oder int), für das die Berechnung ausgeführt werden soll oder "current" für aktuelles Jahr (default: 'current') - - -Wachstumsgradtag ----------------- -Der Begriff Wachstumsgradtage (WGT) ist ein Überbegriff für verschiedene Größen. -Gemeinsam ist ihnen, daß zur Berechnung eine Lufttemperatur von einem Schwellenwert subtrahiert wird. -Je nach Fragestellung und Pflanzenart werden der Schwellenwert unterschiedlich gewählt und die Temperatur unterschiedlich bestimmt. -Verfügbar sind die Berechnung über 0) "einfachen Durchschnitt der Tagestemperaturen", 1) "modifizierten Durchschnitt der Tagestemperaturen" -und 2) Anzahl der Tage, deren Mitteltempertatur oberhalb der Schwellentemperatur lag. - -siehe https://de.wikipedia.org/wiki/Wachstumsgradtag - -Folgende Parameter sind möglich / notwendig: - -.. code-block:: yaml - - db_addon_params: "year=current, method=1, threshold=10" - -- year: Jahreszahl (str oder int), für das die Berechnung ausgeführt werden soll oder "current" für aktuelles Jahr (default: 'current') -- method: 0-Berechnung über "einfachen Durchschnitt der Tagestemperaturen", 1-Berechnung über "modifizierten Durchschnitt (default: 0) -der Tagestemperaturen" 2-Anzahl der Tage, mit Mitteltempertatur oberhalb Schwellentemperatur// 10, 11 Ausgabe aus Zeitserie -- threshold: Schwellentemperatur in °C (int) (default: 10) - - -Wärmesumme ----------- - -Die Wärmesumme soll eine Aussage über den Sommer und die Pflanzenreife liefern. Es gibt keine eindeutige Definition der Größe "Wärmesumme". -Berechnet wird die Wärmesumme als Summe aller Tagesmitteltemperaturen über einem Schwellenwert ab dem 1.1. des Jahres. - -siehe https://de.wikipedia.org/wiki/W%C3%A4rmesumme - -Folgende Parameter sind möglich / notwendig: - -.. code-block:: yaml - - db_addon_params: "year=current, month=1, threshold=10" - -- year: Jahreszahl (str oder int), für das die Berechnung ausgeführt werden soll oder "current" für aktuelles Jahr (default: 'current') -- month: Monat (int) des Jahres, für das die Berechnung ausgeführt werden soll (optional) (default: None) -- threshold: Schwellentemperatur in °C (int) (default: 10) - - -Kältesumme ----------- - -Die Kältesumme soll eine Aussage über die Härte des Winters liefern. -Berechnet wird die Kältesumme als Summe aller negativen Tagesmitteltemperaturen ab dem 21.9. des Jahres bis 31.3. des Folgejahres. - -siehe https://de.wikipedia.org/wiki/K%C3%A4ltesumme - -Folgende Parameter sind möglich / notwendig: - -.. code-block:: yaml - - db_addon_params: "year=current, month=1" - -- year: Jahreszahl (str oder int), für das die Berechnung ausgeführt werden soll oder "current" für aktuelles Jahr (default: 'current') -- month: Monat (int) des Jahres, für das die Berechnung ausgeführt werden soll (optional) (default: None) - - -Tagesmitteltemperatur ---------------------- - -Die Tagesmitteltemperatur wird auf Basis der stündlichen Durchschnittswerte eines Tages (aller in der DB enthaltenen Datensätze) -für die angegebene Anzahl von Tagen (days=optional) berechnet. - - - -Vorgehen bei Funktionserweiterung des Plugins bzw. Ergänzung weiterer Werte für Item-Attribute ----------------------------------------------------------------------------------------------- - -Aufgrund der Vielzahl der möglichen Werte der Itemattribute, insbesondere des Itemattributes `db_addon_fct`, wurde die Erstellung/Update -der entsprechenden Teile der `plugin.yam` sowie die Erstellung der Datei `item_attributes.py`, die vom Plugin verwendet wird, automatisiert. - -Die Masterinformationen für alle Itemattribute sowie die Skripte zum Erstellen/Update der beiden Dateien sind in der -Datei `item_attributes_master.py` enthalten. - -.. important:: - - Korrekturen, Erweiterungen etc. der Itemattribute sollten nur in der Datei `item_attributes_master.py` - im Dict der Variable `ITEM_ATTRIBUTS` vorgenommen werden. Das Ausführen der Datei `item_attributes_master.py` (main) - erstellt die `item_attributes.py` und aktualisiert die `plugin.yaml` entsprechend. -Dieses Kapitel wurde automatisch durch Ausführen des Skripts in der Datei 'item_attributes_master.py' erstellt. - -Nachfolgend eine Auflistung der möglichen Attribute für das Plugin im Format: Attribute: Beschreibung | Berechnungszyklus | Item-Type - - -db_addon_fct ------------- - -- verbrauch_heute: Verbrauch am heutigen Tag (Differenz zwischen aktuellem Wert und den Wert am Ende des vorherigen Tages) | Berechnung: daily | Item-Type: num - -- verbrauch_tag: Verbrauch am heutigen Tag (Differenz zwischen aktuellem Wert und den Wert am Ende des vorherigen Tages) | Berechnung: daily | Item-Type: num - -- verbrauch_woche: Verbrauch in der aktuellen Woche | Berechnung: weekly | Item-Type: num - -- verbrauch_monat: Verbrauch im aktuellen Monat | Berechnung: monthly | Item-Type: num - -- verbrauch_jahr: Verbrauch im aktuellen Jahr | Berechnung: yearly | Item-Type: num - -- verbrauch_last_24h: Verbrauch innerhalb letzten 24h | Berechnung: hourly | Item-Type: num - -- verbrauch_last_7d: Verbrauch innerhalb letzten 7 Tage | Berechnung: hourly | Item-Type: num - -- verbrauch_heute_minus1: Verbrauch gestern (heute -1 Tag) (Differenz zwischen Wert am Ende des gestrigen Tages und dem Wert am Ende des Tages davor) | Berechnung: daily | Item-Type: num - -- verbrauch_heute_minus2: Verbrauch vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num - -- verbrauch_heute_minus3: Verbrauch heute -3 Tage | Berechnung: daily | Item-Type: num - -- verbrauch_heute_minus4: Verbrauch heute -4 Tage | Berechnung: daily | Item-Type: num - -- verbrauch_heute_minus5: Verbrauch heute -5 Tage | Berechnung: daily | Item-Type: num - -- verbrauch_heute_minus6: Verbrauch heute -6 Tage | Berechnung: daily | Item-Type: num - -- verbrauch_heute_minus7: Verbrauch heute -7 Tage | Berechnung: daily | Item-Type: num - -- verbrauch_heute_minus8: Verbrauch heute -8 Tage | Berechnung: daily | Item-Type: num - -- verbrauch_tag_minus1: Verbrauch gestern (heute -1 Tag) (Differenz zwischen Wert am Ende des gestrigen Tages und dem Wert am Ende des Tages davor) | Berechnung: daily | Item-Type: num - -- verbrauch_tag_minus2: Verbrauch vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num - -- verbrauch_tag_minus3: Verbrauch heute -3 Tage | Berechnung: daily | Item-Type: num - -- verbrauch_tag_minus4: Verbrauch heute -4 Tage | Berechnung: daily | Item-Type: num - -- verbrauch_tag_minus5: Verbrauch heute -5 Tage | Berechnung: daily | Item-Type: num - -- verbrauch_tag_minus6: Verbrauch heute -6 Tage | Berechnung: daily | Item-Type: num - -- verbrauch_tag_minus7: Verbrauch heute -7 Tage | Berechnung: daily | Item-Type: num - -- verbrauch_tag_minus8: Verbrauch heute -8 Tage | Berechnung: daily | Item-Type: num - -- verbrauch_woche_minus1: Verbrauch Vorwoche (aktuelle Woche -1) | Berechnung: weekly | Item-Type: num - -- verbrauch_woche_minus2: Verbrauch aktuelle Woche -2 Wochen | Berechnung: weekly | Item-Type: num - -- verbrauch_woche_minus3: Verbrauch aktuelle Woche -3 Wochen | Berechnung: weekly | Item-Type: num - -- verbrauch_woche_minus4: Verbrauch aktuelle Woche -4 Wochen | Berechnung: weekly | Item-Type: num - -- verbrauch_monat_minus1: Verbrauch Vormonat (aktueller Monat -1) | Berechnung: monthly | Item-Type: num - -- verbrauch_monat_minus2: Verbrauch aktueller Monat -2 Monate | Berechnung: monthly | Item-Type: num - -- verbrauch_monat_minus3: Verbrauch aktueller Monat -3 Monate | Berechnung: monthly | Item-Type: num - -- verbrauch_monat_minus4: Verbrauch aktueller Monat -4 Monate | Berechnung: monthly | Item-Type: num - -- verbrauch_monat_minus12: Verbrauch aktueller Monat -12 Monate | Berechnung: monthly | Item-Type: num - -- verbrauch_jahr_minus1: Verbrauch Vorjahr (aktuelles Jahr -1 Jahr) | Berechnung: yearly | Item-Type: num - -- verbrauch_jahr_minus2: Verbrauch aktuelles Jahr -2 Jahre | Berechnung: yearly | Item-Type: num - -- verbrauch_jahr_minus3: Verbrauch aktuelles Jahr -3 Jahre | Berechnung: yearly | Item-Type: num - -- verbrauch_rolling_12m_heute_minus1: Verbrauch der letzten 12 Monate ausgehend im Ende des letzten Tages | Berechnung: daily | Item-Type: num - -- verbrauch_rolling_12m_tag_minus1: Verbrauch der letzten 12 Monate ausgehend im Ende des letzten Tages | Berechnung: daily | Item-Type: num - -- verbrauch_rolling_12m_woche_minus1: Verbrauch der letzten 12 Monate ausgehend im Ende der letzten Woche | Berechnung: weekly | Item-Type: num - -- verbrauch_rolling_12m_monat_minus1: Verbrauch der letzten 12 Monate ausgehend im Ende des letzten Monats | Berechnung: monthly | Item-Type: num - -- verbrauch_rolling_12m_jahr_minus1: Verbrauch der letzten 12 Monate ausgehend im Ende des letzten Jahres | Berechnung: yearly | Item-Type: num - -- verbrauch_jahreszeitraum_minus1: Verbrauch seit dem 1.1. bis zum heutigen Tag des Vorjahres | Berechnung: daily | Item-Type: num - -- verbrauch_jahreszeitraum_minus2: Verbrauch seit dem 1.1. bis zum heutigen Tag vor 2 Jahren | Berechnung: daily | Item-Type: num - -- verbrauch_jahreszeitraum_minus3: Verbrauch seit dem 1.1. bis zum heutigen Tag vor 3 Jahren | Berechnung: daily | Item-Type: num - -- zaehlerstand_heute_minus1: Zählerstand / Wert am Ende des letzten Tages (heute -1 Tag) | Berechnung: daily | Item-Type: num - -- zaehlerstand_heute_minus2: Zählerstand / Wert am Ende des vorletzten Tages (heute -2 Tag) | Berechnung: daily | Item-Type: num - -- zaehlerstand_heute_minus3: Zählerstand / Wert am Ende des vorvorletzten Tages (heute -3 Tag) | Berechnung: daily | Item-Type: num - -- zaehlerstand_tag_minus1: Zählerstand / Wert am Ende des letzten Tages (heute -1 Tag) | Berechnung: daily | Item-Type: num - -- zaehlerstand_tag_minus2: Zählerstand / Wert am Ende des vorletzten Tages (heute -2 Tag) | Berechnung: daily | Item-Type: num - -- zaehlerstand_tag_minus3: Zählerstand / Wert am Ende des vorvorletzten Tages (heute -3 Tag) | Berechnung: daily | Item-Type: num - -- zaehlerstand_woche_minus1: Zählerstand / Wert am Ende der vorvorletzten Woche (aktuelle Woche -1 Woche) | Berechnung: weekly | Item-Type: num - -- zaehlerstand_woche_minus2: Zählerstand / Wert am Ende der vorletzten Woche (aktuelle Woche -2 Wochen) | Berechnung: weekly | Item-Type: num - -- zaehlerstand_woche_minus3: Zählerstand / Wert am Ende der aktuellen Woche -3 Wochen | Berechnung: weekly | Item-Type: num - -- zaehlerstand_monat_minus1: Zählerstand / Wert am Ende des letzten Monates (aktueller Monat -1 Monat) | Berechnung: monthly | Item-Type: num - -- zaehlerstand_monat_minus2: Zählerstand / Wert am Ende des vorletzten Monates (aktueller Monat -2 Monate) | Berechnung: monthly | Item-Type: num - -- zaehlerstand_monat_minus3: Zählerstand / Wert am Ende des aktuellen Monats -3 Monate | Berechnung: monthly | Item-Type: num - -- zaehlerstand_jahr_minus1: Zählerstand / Wert am Ende des letzten Jahres (aktuelles Jahr -1 Jahr) | Berechnung: yearly | Item-Type: num - -- zaehlerstand_jahr_minus2: Zählerstand / Wert am Ende des vorletzten Jahres (aktuelles Jahr -2 Jahre) | Berechnung: yearly | Item-Type: num - -- zaehlerstand_jahr_minus3: Zählerstand / Wert am Ende des aktuellen Jahres -3 Jahre | Berechnung: yearly | Item-Type: num - -- minmax_last_24h_min: minimaler Wert der letzten 24h | Berechnung: daily | Item-Type: num - -- minmax_last_24h_max: maximaler Wert der letzten 24h | Berechnung: daily | Item-Type: num - -- minmax_last_24h_avg: durchschnittlicher Wert der letzten 24h | Berechnung: daily | Item-Type: num - -- minmax_last_7d_min: minimaler Wert der letzten 7 Tage | Berechnung: daily | Item-Type: num - -- minmax_last_7d_max: maximaler Wert der letzten 7 Tage | Berechnung: daily | Item-Type: num - -- minmax_last_7d_avg: durchschnittlicher Wert der letzten 7 Tage | Berechnung: daily | Item-Type: num - -- minmax_heute_min: Minimalwert seit Tagesbeginn | Berechnung: daily | Item-Type: num - -- minmax_heute_max: Maximalwert seit Tagesbeginn | Berechnung: daily | Item-Type: num - -- minmax_heute_avg: Durschnittswert seit Tagesbeginn | Berechnung: daily | Item-Type: num - -- minmax_heute_minus1_min: Minimalwert gestern (heute -1 Tag) | Berechnung: daily | Item-Type: num - -- minmax_heute_minus1_max: Maximalwert gestern (heute -1 Tag) | Berechnung: daily | Item-Type: num - -- minmax_heute_minus1_avg: Durchschnittswert gestern (heute -1 Tag) | Berechnung: daily | Item-Type: num - -- minmax_heute_minus2_min: Minimalwert vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num - -- minmax_heute_minus2_max: Maximalwert vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num - -- minmax_heute_minus2_avg: Durchschnittswert vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num - -- minmax_heute_minus3_min: Minimalwert heute vor 3 Tagen | Berechnung: daily | Item-Type: num - -- minmax_heute_minus3_max: Maximalwert heute vor 3 Tagen | Berechnung: daily | Item-Type: num - -- minmax_heute_minus3_avg: Durchschnittswert heute vor 3 Tagen | Berechnung: daily | Item-Type: num - -- minmax_tag_min: Minimalwert seit Tagesbeginn | Berechnung: daily | Item-Type: num - -- minmax_tag_max: Maximalwert seit Tagesbeginn | Berechnung: daily | Item-Type: num - -- minmax_tag_avg: Durschnittswert seit Tagesbeginn | Berechnung: daily | Item-Type: num - -- minmax_tag_minus1_min: Minimalwert gestern (heute -1 Tag) | Berechnung: daily | Item-Type: num - -- minmax_tag_minus1_max: Maximalwert gestern (heute -1 Tag) | Berechnung: daily | Item-Type: num - -- minmax_tag_minus1_avg: Durchschnittswert gestern (heute -1 Tag) | Berechnung: daily | Item-Type: num - -- minmax_tag_minus2_min: Minimalwert vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num - -- minmax_tag_minus2_max: Maximalwert vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num - -- minmax_tag_minus2_avg: Durchschnittswert vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num - -- minmax_tag_minus3_min: Minimalwert heute vor 3 Tagen | Berechnung: daily | Item-Type: num - -- minmax_tag_minus3_max: Maximalwert heute vor 3 Tagen | Berechnung: daily | Item-Type: num - -- minmax_tag_minus3_avg: Durchschnittswert heute vor 3 Tagen | Berechnung: daily | Item-Type: num - -- minmax_woche_min: Minimalwert seit Wochenbeginn | Berechnung: weekly | Item-Type: num - -- minmax_woche_max: Maximalwert seit Wochenbeginn | Berechnung: weekly | Item-Type: num - -- minmax_woche_minus1_min: Minimalwert Vorwoche (aktuelle Woche -1) | Berechnung: weekly | Item-Type: num - -- minmax_woche_minus1_max: Maximalwert Vorwoche (aktuelle Woche -1) | Berechnung: weekly | Item-Type: num - -- minmax_woche_minus1_avg: Durchschnittswert Vorwoche (aktuelle Woche -1) | Berechnung: weekly | Item-Type: num - -- minmax_woche_minus2_min: Minimalwert aktuelle Woche -2 Wochen | Berechnung: weekly | Item-Type: num - -- minmax_woche_minus2_max: Maximalwert aktuelle Woche -2 Wochen | Berechnung: weekly | Item-Type: num - -- minmax_woche_minus2_avg: Durchschnittswert aktuelle Woche -2 Wochen | Berechnung: weekly | Item-Type: num - -- minmax_monat_min: Minimalwert seit Monatsbeginn | Berechnung: monthly | Item-Type: num - -- minmax_monat_max: Maximalwert seit Monatsbeginn | Berechnung: monthly | Item-Type: num - -- minmax_monat_minus1_min: Minimalwert Vormonat (aktueller Monat -1) | Berechnung: monthly | Item-Type: num - -- minmax_monat_minus1_max: Maximalwert Vormonat (aktueller Monat -1) | Berechnung: monthly | Item-Type: num - -- minmax_monat_minus1_avg: Durchschnittswert Vormonat (aktueller Monat -1) | Berechnung: monthly | Item-Type: num - -- minmax_monat_minus2_min: Minimalwert aktueller Monat -2 Monate | Berechnung: monthly | Item-Type: num - -- minmax_monat_minus2_max: Maximalwert aktueller Monat -2 Monate | Berechnung: monthly | Item-Type: num - -- minmax_monat_minus2_avg: Durchschnittswert aktueller Monat -2 Monate | Berechnung: monthly | Item-Type: num - -- minmax_jahr_min: Minimalwert seit Jahresbeginn | Berechnung: yearly | Item-Type: num - -- minmax_jahr_max: Maximalwert seit Jahresbeginn | Berechnung: yearly | Item-Type: num - -- minmax_jahr_minus1_min: Minimalwert Vorjahr (aktuelles Jahr -1 Jahr) | Berechnung: yearly | Item-Type: num - -- minmax_jahr_minus1_max: Maximalwert Vorjahr (aktuelles Jahr -1 Jahr) | Berechnung: yearly | Item-Type: num - -- minmax_jahr_minus1_avg: Durchschnittswert Vorjahr (aktuelles Jahr -1 Jahr) | Berechnung: yearly | Item-Type: num - -- tagesmitteltemperatur_heute: Tagesmitteltemperatur heute | Berechnung: daily | Item-Type: num - -- tagesmitteltemperatur_heute_minus1: Tagesmitteltemperatur des letzten Tages (heute -1 Tag) | Berechnung: daily | Item-Type: num - -- tagesmitteltemperatur_heute_minus2: Tagesmitteltemperatur des vorletzten Tages (heute -2 Tag) | Berechnung: daily | Item-Type: num - -- tagesmitteltemperatur_heute_minus3: Tagesmitteltemperatur des vorvorletzten Tages (heute -3 Tag) | Berechnung: daily | Item-Type: num - -- tagesmitteltemperatur_tag: Tagesmitteltemperatur heute | Berechnung: daily | Item-Type: num - -- tagesmitteltemperatur_tag_minus1: Tagesmitteltemperatur des letzten Tages (heute -1 Tag) | Berechnung: daily | Item-Type: num - -- tagesmitteltemperatur_tag_minus2: Tagesmitteltemperatur des vorletzten Tages (heute -2 Tag) | Berechnung: daily | Item-Type: num - -- tagesmitteltemperatur_tag_minus3: Tagesmitteltemperatur des vorvorletzten Tages (heute -3 Tag) | Berechnung: daily | Item-Type: num - -- serie_minmax_monat_min_15m: monatlicher Minimalwert der letzten 15 Monate (gleitend) | Berechnung: monthly | Item-Type: list - -- serie_minmax_monat_max_15m: monatlicher Maximalwert der letzten 15 Monate (gleitend) | Berechnung: monthly | Item-Type: list - -- serie_minmax_monat_avg_15m: monatlicher Mittelwert der letzten 15 Monate (gleitend) | Berechnung: monthly | Item-Type: list - -- serie_minmax_woche_min_30w: wöchentlicher Minimalwert der letzten 30 Wochen (gleitend) | Berechnung: weekly | Item-Type: list - -- serie_minmax_woche_max_30w: wöchentlicher Maximalwert der letzten 30 Wochen (gleitend) | Berechnung: weekly | Item-Type: list - -- serie_minmax_woche_avg_30w: wöchentlicher Mittelwert der letzten 30 Wochen (gleitend) | Berechnung: weekly | Item-Type: list - -- serie_minmax_tag_min_30d: täglicher Minimalwert der letzten 30 Tage (gleitend) | Berechnung: daily | Item-Type: list - -- serie_minmax_tag_max_30d: täglicher Maximalwert der letzten 30 Tage (gleitend) | Berechnung: daily | Item-Type: list - -- serie_minmax_tag_avg_30d: täglicher Mittelwert der letzten 30 Tage (gleitend) | Berechnung: daily | Item-Type: list - -- serie_verbrauch_tag_30d: Verbrauch pro Tag der letzten 30 Tage | Berechnung: daily | Item-Type: list - -- serie_verbrauch_woche_30w: Verbrauch pro Woche der letzten 30 Wochen | Berechnung: weekly | Item-Type: list - -- serie_verbrauch_monat_18m: Verbrauch pro Monat der letzten 18 Monate | Berechnung: monthly | Item-Type: list - -- serie_zaehlerstand_tag_30d: Zählerstand am Tagesende der letzten 30 Tage | Berechnung: daily | Item-Type: list - -- serie_zaehlerstand_woche_30w: Zählerstand am Wochenende der letzten 30 Wochen | Berechnung: weekly | Item-Type: list - -- serie_zaehlerstand_monat_18m: Zählerstand am Monatsende der letzten 18 Monate | Berechnung: monthly | Item-Type: list - -- serie_waermesumme_monat_24m: monatliche Wärmesumme der letzten 24 Monate | Berechnung: monthly | Item-Type: list - -- serie_kaeltesumme_monat_24m: monatliche Kältesumme der letzten 24 Monate | Berechnung: monthly | Item-Type: list - -- serie_tagesmittelwert_0d: Tagesmittelwert für den aktuellen Tag | Berechnung: daily | Item-Type: list - -- serie_tagesmittelwert_stunde_0d: Stundenmittelwert für den aktuellen Tag | Berechnung: daily | Item-Type: list - -- serie_tagesmittelwert_stunde_30_0d: Stundenmittelwert für den aktuellen Tag | Berechnung: daily | Item-Type: list - -- serie_tagesmittelwert_tag_stunde_30d: Stundenmittelwert pro Tag der letzten 30 Tage (bspw. zur Berechnung der Tagesmitteltemperatur basierend auf den Mittelwert der Temperatur pro Stunde | Berechnung: daily | Item-Type: list - -- general_oldest_value: Ausgabe des ältesten Wertes des entsprechenden "Parent-Items" mit database Attribut | Berechnung: no | Item-Type: num - -- general_oldest_log: Ausgabe des Timestamp des ältesten Eintrages des entsprechenden "Parent-Items" mit database Attribut | Berechnung: no | Item-Type: list - -- kaeltesumme: Berechnet die Kältesumme für einen Zeitraum, db_addon_params: (year=optional, month=optional) | Berechnung: daily | Item-Type: num - -- waermesumme: Berechnet die Wärmesumme für einen Zeitraum, db_addon_params: (year=optional, month=optional) | Berechnung: daily | Item-Type: num - -- gruenlandtempsumme: Berechnet die Grünlandtemperatursumme für einen Zeitraum, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num - -- wachstumsgradtage: Berechnet die Wachstumsgradtage auf Basis der stündlichen Durchschnittswerte eines Tages für das laufende Jahr mit an Angabe des Temperaturschwellenwertes (threshold=Schwellentemperatur) | Berechnung: daily | Item-Type: num - -- wuestentage: Berechnet die Anzahl der Wüstentage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num - -- heisse_tage: Berechnet die Anzahl der heissen Tage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num - -- tropennaechte: Berechnet die Anzahl der Tropennächte des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num - -- sommertage: Berechnet die Anzahl der Sommertage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num - -- heiztage: Berechnet die Anzahl der Heiztage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num - -- vegetationstage: Berechnet die Anzahl der Vegatationstage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num - -- frosttage: Berechnet die Anzahl der Frosttage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num - -- eistage: Berechnet die Anzahl der Eistage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num - -- tagesmitteltemperatur: Berechnet die Tagesmitteltemperatur auf Basis der stündlichen Durchschnittswerte eines Tages für die angegebene Anzahl von Tagen (timeframe=day, count=integer) | Berechnung: daily | Item-Type: list - -- db_request: Abfrage der DB: db_addon_params: (func=mandatory, item=mandatory, timespan=mandatory, start=optional, end=optional, count=optional, group=optional, group2=optional) | Berechnung: group | Item-Type: list - -- minmax: Berechnet einen min/max/avg Wert für einen bestimmen Zeitraum: db_addon_params: (func=mandatory, timeframe=mandatory, start=mandatory) | Berechnung: timeframe | Item-Type: num - -- minmax_last: 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) | Berechnung: timeframe | Item-Type: num - -- verbrauch: Berechnet einen Verbrauchswert für einen bestimmen Zeitraum: db_addon_params: (timeframe=mandatory, start=mandatory end=mandatory) | Berechnung: timeframe | Item-Type: num - -- zaehlerstand: Berechnet einen Zählerstand für einen bestimmen Zeitpunkt: db_addon_params: (timeframe=mandatory, start=mandatory) | Berechnung: timeframe | Item-Type: num - - -db_addon_info -------------- - -- db_version: Version der verbundenen Datenbank | Berechnung: no | Item-Type: str - - -db_addon_admin --------------- - -- suspend: Unterbricht die Aktivitäten des Plugin | Berechnung: no | Item-Type: bool - -- recalc_all: Startet einen Neuberechnungslauf aller on-demand Items | Berechnung: no | Item-Type: bool - -- clean_cache_values: Löscht Plugin-Cache und damit alle im Plugin zwischengespeicherten Werte | Berechnung: no | Item-Type: bool - - -Hinweise -======== - - - Das Plugin startet die Berechnungen der Werte nach einer gewissen (konfigurierbaren) Zeit (Attribut `startup_run_delay`) - nach dem Start von shNG, um den Startvorgang nicht zu beeinflussen. - - - Bei Start werden automatisch nur die Items berechnet, für das das Attribute `db_addon_startup` gesetzt wurde. Alle anderen - Items werden erst zur konfigurierten Zeit berechnet. Das Attribute `db_addon_startup` kann auch direkt am `Database-Item` - gesetzt werden. Dabei wird das Attribut auf alle darunter liegenden `db_addon-Items` (bspw. bei Verwendung von structs) vererbt. - Über das WebIF kann die Berechnung aller definierten Items ausgelöst werden. - - - Für sogenannte `on_change` Items, also Items, deren Berechnung bis zum Jetzt (bspw. verbrauch-heute) gehen, wird die Berechnung - immer bei eintreffen eines neuen Wertes gestartet. Zu Reduktion der Belastung auf die Datenbank werden die Werte für das Ende der - letzten Periode gecached. - - - Berechnungen werden nur ausgeführt, wenn für den kompletten abgefragten Zeitraum Werte in der Datenbank vorliegen. Wird bspw. - der Verbrauch des letzten Monats abgefragt wobei erst Werte ab dem 3. des Monats in der Datenbank sind, wird die Berechnung abgebrochen. - - - Mit dem Attribut `use_oldest_entry` kann dieses Verhalten verändert werden. Ist das Attribut gesetzt, wird, wenn für den - Beginn der Abfragezeitraums keinen Werte vorliegen, der älteste Eintrag der Datenbank genutzt. - - - Für die Auswertung kann es nützlich sein, bestimmte Werte aus der Datenbank bei der Berechnung auszublenden. Hierfür stehen - 2 Möglichkeiten zur Verfügung: - - Plugin-Attribut `ignore_0`: (list of strings) Bei Items, bei denen ein String aus der Liste im Pfadnamen vorkommt, - werden 0-Werte (val_num = 0) bei Datenbankauswertungen ignoriert. Hat also das Attribut den Wert ['temp'] werden bei allen Items mit - 'temp' im Pfadnamen die 0-Werte bei der Auswertung ignoriert. - - Item-Attribut `db_addon_ignore_value`: (num) Dieser Wert wird bei der Abfrage bzw. Auswertung der Datenbank für diese - Item ignoriert. - - - Das Plugin enthält sehr ausführliche Logginginformation. Bei unerwartetem Verhalten, den LogLevel entsprechend anpassen, - um mehr information zu erhalten. - - - Berechnungen des Plugins können im WebIF unterbrochen werden. Auch das gesamte Plugin kann pausiert werden. Dies kann bei - starker Systembelastung nützlich sein. - - -Beispiele -========= - -Verbrauch ---------- - -Soll bspw. der Verbrauch von Wasser ausgewertet werden, so ist dies wie folgt möglich: - - -.. code-block:: yaml - - wasserzaehler: - zaehlerstand: - type: num - knx_dpt: 12 - knx_cache: 5/3/4 - eval: round(value/1000, 1) - database: init - struct: - - db_addon.verbrauch_1 - - db_addon.verbrauch_2 - - db_addon.zaehlerstand_1 - -Die Werte des Wasserzählerstandes werden in die Datenbank geschrieben und darauf basierend ausgewertet. Die structs -'db_addon.verbrauch_1' und 'db_addon.verbrauch_2' stellen entsprechende Items für die Verbrauchsauswerten zur Verfügung. - -minmax ------- - -Soll bspw. die minimalen und maximalen Temperaturen ausgewertet werden, kann dies so umgesetzt werden: - -.. code-block:: yaml - - temperature: - aussen: - nord: - name: Außentemp Nordseite - type: num - visu_acl: ro - knx_dpt: 9 - knx_cache: 6/5/1 - database: init - struct: - - db_addon.minmax_1 - - db_addon.minmax_2 - -Die Temperaturwerte werden in die Datenbank geschrieben und darauf basierend ausgewertet. Die structs -'db_addon.minmax_1' und 'db_addon.minmax_2' stellen entsprechende Items für die min/max Auswertung zur Verfügung. - -| - -Web Interface -============= - -Das WebIF stellt neben der Ansicht verbundener Items und deren Parameter und Werte auch Funktionen für die -Administration des Plugins bereit. - -Es stehen Button für: - -- Neuberechnung aller Items -- Abbruch eines aktiven Berechnungslaufes -- Pausieren des Plugins -- Wiederaufnahme des Plugins - -bereit. - -Achtung: Das Auslösen einer kompletten Neuberechnung aller Items kann zu einer starken Belastung der Datenbank -aufgrund vieler Leseanfragen führen. - - -db_addon Items --------------- - -Dieser Reiter des Webinterface zeigt die Items an, für die ein DatabaseAddon Attribut konfiguriert ist. - - -db_addon Maintenance --------------------- - -Das Webinterface zeigt detaillierte Informationen über die im Plugin verfügbaren Daten an. -Dies dient der Maintenance bzw. Fehlersuche. Dieser Tab ist nur bei Log-Level "Debug" verfügbar. - - -Erläuterungen zu Temperatursummen -================================= - - -Grünlandtemperatursumme ------------------------ - -Beim Grünland wird die Wärmesumme nach Ernst und Loeper benutzt, um den Vegetationsbeginn und somit den Termin von Düngungsmaßnahmen zu bestimmen. -Dabei erfolgt die Aufsummierung der Tagesmitteltemperaturen über 0 °C, wobei der Januar mit 0.5 und der Februar mit 0.75 gewichtet wird. -Bei einer Wärmesumme von 200 Grad ist eine Düngung angesagt. - -siehe: https://de.wikipedia.org/wiki/Gr%C3%BCnlandtemperatursumme - -Folgende Parameter sind möglich / notwendig: - - -.. code-block:: yaml - - db_addon_params: "year=current" - -- year: Jahreszahl (str oder int), für das die Berechnung ausgeführt werden soll oder "current" für aktuelles Jahr (default: 'current') - - -Wachstumsgradtag ----------------- -Der Begriff Wachstumsgradtage (WGT) ist ein Überbegriff für verschiedene Größen. -Gemeinsam ist ihnen, daß zur Berechnung eine Lufttemperatur von einem Schwellenwert subtrahiert wird. -Je nach Fragestellung und Pflanzenart werden der Schwellenwert unterschiedlich gewählt und die Temperatur unterschiedlich bestimmt. -Verfügbar sind die Berechnung über 0) "einfachen Durchschnitt der Tagestemperaturen", 1) "modifizierten Durchschnitt der Tagestemperaturen" -und 2) Anzahl der Tage, deren Mitteltempertatur oberhalb der Schwellentemperatur lag. - -siehe https://de.wikipedia.org/wiki/Wachstumsgradtag - -Folgende Parameter sind möglich / notwendig: - -.. code-block:: yaml - - db_addon_params: "year=current, method=1, threshold=10" - -- year: Jahreszahl (str oder int), für das die Berechnung ausgeführt werden soll oder "current" für aktuelles Jahr (default: 'current') -- method: 0-Berechnung über "einfachen Durchschnitt der Tagestemperaturen", 1-Berechnung über "modifizierten Durchschnitt (default: 0) -der Tagestemperaturen" 2-Anzahl der Tage, mit Mitteltempertatur oberhalb Schwellentemperatur// 10, 11 Ausgabe aus Zeitserie -- threshold: Schwellentemperatur in °C (int) (default: 10) - - -Wärmesumme ----------- - -Die Wärmesumme soll eine Aussage über den Sommer und die Pflanzenreife liefern. Es gibt keine eindeutige Definition der Größe "Wärmesumme". -Berechnet wird die Wärmesumme als Summe aller Tagesmitteltemperaturen über einem Schwellenwert ab dem 1.1. des Jahres. - -siehe https://de.wikipedia.org/wiki/W%C3%A4rmesumme - -Folgende Parameter sind möglich / notwendig: - -.. code-block:: yaml - - db_addon_params: "year=current, month=1, threshold=10" - -- year: Jahreszahl (str oder int), für das die Berechnung ausgeführt werden soll oder "current" für aktuelles Jahr (default: 'current') -- month: Monat (int) des Jahres, für das die Berechnung ausgeführt werden soll (optional) (default: None) -- threshold: Schwellentemperatur in °C (int) (default: 10) - - -Kältesumme ----------- - -Die Kältesumme soll eine Aussage über die Härte des Winters liefern. -Berechnet wird die Kältesumme als Summe aller negativen Tagesmitteltemperaturen ab dem 21.9. des Jahres bis 31.3. des Folgejahres. - -siehe https://de.wikipedia.org/wiki/K%C3%A4ltesumme - -Folgende Parameter sind möglich / notwendig: - -.. code-block:: yaml - - db_addon_params: "year=current, month=1" - -- year: Jahreszahl (str oder int), für das die Berechnung ausgeführt werden soll oder "current" für aktuelles Jahr (default: 'current') -- month: Monat (int) des Jahres, für das die Berechnung ausgeführt werden soll (optional) (default: None) - - -Tagesmitteltemperatur ---------------------- - -Die Tagesmitteltemperatur wird auf Basis der stündlichen Durchschnittswerte eines Tages (aller in der DB enthaltenen Datensätze) -für die angegebene Anzahl von Tagen (days=optional) berechnet. - - - -Vorgehen bei Funktionserweiterung des Plugins bzw. Ergänzung weiterer Werte für Item-Attribute ----------------------------------------------------------------------------------------------- - -Aufgrund der Vielzahl der möglichen Werte der Itemattribute, insbesondere des Itemattributes `db_addon_fct`, wurde die Erstellung/Update -der entsprechenden Teile der `plugin.yam` sowie die Erstellung der Datei `item_attributes.py`, die vom Plugin verwendet wird, automatisiert. - -Die Masterinformationen für alle Itemattribute sowie die Skripte zum Erstellen/Update der beiden Dateien sind in der -Datei `item_attributes_master.py` enthalten. - -.. important:: - - Korrekturen, Erweiterungen etc. der Itemattribute sollten nur in der Datei `item_attributes_master.py` - im Dict der Variable `ITEM_ATTRIBUTS` vorgenommen werden. Das Ausführen der Datei `item_attributes_master.py` (main) - erstellt die `item_attributes.py` und aktualisiert die `plugin.yaml` entsprechend. -Dieses Kapitel wurde automatisch durch Ausführen des Skripts in der Datei 'item_attributes_master.py' erstellt. - -Nachfolgend eine Auflistung der möglichen Attribute für das Plugin im Format: Attribute: Beschreibung | Berechnungszyklus | Item-Type - - -db_addon_fct ------------- - -- verbrauch_heute: Verbrauch am heutigen Tag (Differenz zwischen aktuellem Wert und den Wert am Ende des vorherigen Tages) | Berechnung: daily | Item-Type: num - -- verbrauch_tag: Verbrauch am heutigen Tag (Differenz zwischen aktuellem Wert und den Wert am Ende des vorherigen Tages) | Berechnung: daily | Item-Type: num - -- verbrauch_woche: Verbrauch in der aktuellen Woche | Berechnung: weekly | Item-Type: num - -- verbrauch_monat: Verbrauch im aktuellen Monat | Berechnung: monthly | Item-Type: num - -- verbrauch_jahr: Verbrauch im aktuellen Jahr | Berechnung: yearly | Item-Type: num - -- verbrauch_last_24h: Verbrauch innerhalb letzten 24h | Berechnung: hourly | Item-Type: num - -- verbrauch_last_7d: Verbrauch innerhalb letzten 7 Tage | Berechnung: hourly | Item-Type: num - -- verbrauch_heute_minus1: Verbrauch gestern (heute -1 Tag) (Differenz zwischen Wert am Ende des gestrigen Tages und dem Wert am Ende des Tages davor) | Berechnung: daily | Item-Type: num - -- verbrauch_heute_minus2: Verbrauch vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num - -- verbrauch_heute_minus3: Verbrauch heute -3 Tage | Berechnung: daily | Item-Type: num - -- verbrauch_heute_minus4: Verbrauch heute -4 Tage | Berechnung: daily | Item-Type: num - -- verbrauch_heute_minus5: Verbrauch heute -5 Tage | Berechnung: daily | Item-Type: num - -- verbrauch_heute_minus6: Verbrauch heute -6 Tage | Berechnung: daily | Item-Type: num - -- verbrauch_heute_minus7: Verbrauch heute -7 Tage | Berechnung: daily | Item-Type: num - -- verbrauch_heute_minus8: Verbrauch heute -8 Tage | Berechnung: daily | Item-Type: num - -- verbrauch_tag_minus1: Verbrauch gestern (heute -1 Tag) (Differenz zwischen Wert am Ende des gestrigen Tages und dem Wert am Ende des Tages davor) | Berechnung: daily | Item-Type: num - -- verbrauch_tag_minus2: Verbrauch vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num - -- verbrauch_tag_minus3: Verbrauch heute -3 Tage | Berechnung: daily | Item-Type: num - -- verbrauch_tag_minus4: Verbrauch heute -4 Tage | Berechnung: daily | Item-Type: num - -- verbrauch_tag_minus5: Verbrauch heute -5 Tage | Berechnung: daily | Item-Type: num - -- verbrauch_tag_minus6: Verbrauch heute -6 Tage | Berechnung: daily | Item-Type: num - -- verbrauch_tag_minus7: Verbrauch heute -7 Tage | Berechnung: daily | Item-Type: num - -- verbrauch_tag_minus8: Verbrauch heute -8 Tage | Berechnung: daily | Item-Type: num - -- verbrauch_woche_minus1: Verbrauch Vorwoche (aktuelle Woche -1) | Berechnung: weekly | Item-Type: num - -- verbrauch_woche_minus2: Verbrauch aktuelle Woche -2 Wochen | Berechnung: weekly | Item-Type: num - -- verbrauch_woche_minus3: Verbrauch aktuelle Woche -3 Wochen | Berechnung: weekly | Item-Type: num - -- verbrauch_woche_minus4: Verbrauch aktuelle Woche -4 Wochen | Berechnung: weekly | Item-Type: num - -- verbrauch_monat_minus1: Verbrauch Vormonat (aktueller Monat -1) | Berechnung: monthly | Item-Type: num - -- verbrauch_monat_minus2: Verbrauch aktueller Monat -2 Monate | Berechnung: monthly | Item-Type: num - -- verbrauch_monat_minus3: Verbrauch aktueller Monat -3 Monate | Berechnung: monthly | Item-Type: num - -- verbrauch_monat_minus4: Verbrauch aktueller Monat -4 Monate | Berechnung: monthly | Item-Type: num - -- verbrauch_monat_minus12: Verbrauch aktueller Monat -12 Monate | Berechnung: monthly | Item-Type: num - -- verbrauch_jahr_minus1: Verbrauch Vorjahr (aktuelles Jahr -1 Jahr) | Berechnung: yearly | Item-Type: num - -- verbrauch_jahr_minus2: Verbrauch aktuelles Jahr -2 Jahre | Berechnung: yearly | Item-Type: num - -- verbrauch_jahr_minus3: Verbrauch aktuelles Jahr -3 Jahre | Berechnung: yearly | Item-Type: num - -- verbrauch_rolling_12m_heute_minus1: Verbrauch der letzten 12 Monate ausgehend im Ende des letzten Tages | Berechnung: daily | Item-Type: num - -- verbrauch_rolling_12m_tag_minus1: Verbrauch der letzten 12 Monate ausgehend im Ende des letzten Tages | Berechnung: daily | Item-Type: num - -- verbrauch_rolling_12m_woche_minus1: Verbrauch der letzten 12 Monate ausgehend im Ende der letzten Woche | Berechnung: weekly | Item-Type: num - -- verbrauch_rolling_12m_monat_minus1: Verbrauch der letzten 12 Monate ausgehend im Ende des letzten Monats | Berechnung: monthly | Item-Type: num - -- verbrauch_rolling_12m_jahr_minus1: Verbrauch der letzten 12 Monate ausgehend im Ende des letzten Jahres | Berechnung: yearly | Item-Type: num - -- verbrauch_jahreszeitraum_minus1: Verbrauch seit dem 1.1. bis zum heutigen Tag des Vorjahres | Berechnung: daily | Item-Type: num - -- verbrauch_jahreszeitraum_minus2: Verbrauch seit dem 1.1. bis zum heutigen Tag vor 2 Jahren | Berechnung: daily | Item-Type: num - -- verbrauch_jahreszeitraum_minus3: Verbrauch seit dem 1.1. bis zum heutigen Tag vor 3 Jahren | Berechnung: daily | Item-Type: num - -- zaehlerstand_heute_minus1: Zählerstand / Wert am Ende des letzten Tages (heute -1 Tag) | Berechnung: daily | Item-Type: num - -- zaehlerstand_heute_minus2: Zählerstand / Wert am Ende des vorletzten Tages (heute -2 Tag) | Berechnung: daily | Item-Type: num - -- zaehlerstand_heute_minus3: Zählerstand / Wert am Ende des vorvorletzten Tages (heute -3 Tag) | Berechnung: daily | Item-Type: num - -- zaehlerstand_tag_minus1: Zählerstand / Wert am Ende des letzten Tages (heute -1 Tag) | Berechnung: daily | Item-Type: num - -- zaehlerstand_tag_minus2: Zählerstand / Wert am Ende des vorletzten Tages (heute -2 Tag) | Berechnung: daily | Item-Type: num - -- zaehlerstand_tag_minus3: Zählerstand / Wert am Ende des vorvorletzten Tages (heute -3 Tag) | Berechnung: daily | Item-Type: num - -- zaehlerstand_woche_minus1: Zählerstand / Wert am Ende der vorvorletzten Woche (aktuelle Woche -1 Woche) | Berechnung: weekly | Item-Type: num - -- zaehlerstand_woche_minus2: Zählerstand / Wert am Ende der vorletzten Woche (aktuelle Woche -2 Wochen) | Berechnung: weekly | Item-Type: num - -- zaehlerstand_woche_minus3: Zählerstand / Wert am Ende der aktuellen Woche -3 Wochen | Berechnung: weekly | Item-Type: num - -- zaehlerstand_monat_minus1: Zählerstand / Wert am Ende des letzten Monates (aktueller Monat -1 Monat) | Berechnung: monthly | Item-Type: num - -- zaehlerstand_monat_minus2: Zählerstand / Wert am Ende des vorletzten Monates (aktueller Monat -2 Monate) | Berechnung: monthly | Item-Type: num - -- zaehlerstand_monat_minus3: Zählerstand / Wert am Ende des aktuellen Monats -3 Monate | Berechnung: monthly | Item-Type: num - -- zaehlerstand_jahr_minus1: Zählerstand / Wert am Ende des letzten Jahres (aktuelles Jahr -1 Jahr) | Berechnung: yearly | Item-Type: num - -- zaehlerstand_jahr_minus2: Zählerstand / Wert am Ende des vorletzten Jahres (aktuelles Jahr -2 Jahre) | Berechnung: yearly | Item-Type: num - -- zaehlerstand_jahr_minus3: Zählerstand / Wert am Ende des aktuellen Jahres -3 Jahre | Berechnung: yearly | Item-Type: num - -- minmax_last_24h_min: minimaler Wert der letzten 24h | Berechnung: daily | Item-Type: num - -- minmax_last_24h_max: maximaler Wert der letzten 24h | Berechnung: daily | Item-Type: num - -- minmax_last_24h_avg: durchschnittlicher Wert der letzten 24h | Berechnung: daily | Item-Type: num - -- minmax_last_7d_min: minimaler Wert der letzten 7 Tage | Berechnung: daily | Item-Type: num - -- minmax_last_7d_max: maximaler Wert der letzten 7 Tage | Berechnung: daily | Item-Type: num - -- minmax_last_7d_avg: durchschnittlicher Wert der letzten 7 Tage | Berechnung: daily | Item-Type: num - -- minmax_heute_min: Minimalwert seit Tagesbeginn | Berechnung: daily | Item-Type: num - -- minmax_heute_max: Maximalwert seit Tagesbeginn | Berechnung: daily | Item-Type: num - -- minmax_heute_avg: Durschnittswert seit Tagesbeginn | Berechnung: daily | Item-Type: num - -- minmax_heute_minus1_min: Minimalwert gestern (heute -1 Tag) | Berechnung: daily | Item-Type: num - -- minmax_heute_minus1_max: Maximalwert gestern (heute -1 Tag) | Berechnung: daily | Item-Type: num - -- minmax_heute_minus1_avg: Durchschnittswert gestern (heute -1 Tag) | Berechnung: daily | Item-Type: num - -- minmax_heute_minus2_min: Minimalwert vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num - -- minmax_heute_minus2_max: Maximalwert vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num - -- minmax_heute_minus2_avg: Durchschnittswert vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num - -- minmax_heute_minus3_min: Minimalwert heute vor 3 Tagen | Berechnung: daily | Item-Type: num - -- minmax_heute_minus3_max: Maximalwert heute vor 3 Tagen | Berechnung: daily | Item-Type: num - -- minmax_heute_minus3_avg: Durchschnittswert heute vor 3 Tagen | Berechnung: daily | Item-Type: num - -- minmax_tag_min: Minimalwert seit Tagesbeginn | Berechnung: daily | Item-Type: num - -- minmax_tag_max: Maximalwert seit Tagesbeginn | Berechnung: daily | Item-Type: num - -- minmax_tag_avg: Durschnittswert seit Tagesbeginn | Berechnung: daily | Item-Type: num - -- minmax_tag_minus1_min: Minimalwert gestern (heute -1 Tag) | Berechnung: daily | Item-Type: num - -- minmax_tag_minus1_max: Maximalwert gestern (heute -1 Tag) | Berechnung: daily | Item-Type: num - -- minmax_tag_minus1_avg: Durchschnittswert gestern (heute -1 Tag) | Berechnung: daily | Item-Type: num - -- minmax_tag_minus2_min: Minimalwert vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num - -- minmax_tag_minus2_max: Maximalwert vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num - -- minmax_tag_minus2_avg: Durchschnittswert vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num - -- minmax_tag_minus3_min: Minimalwert heute vor 3 Tagen | Berechnung: daily | Item-Type: num - -- minmax_tag_minus3_max: Maximalwert heute vor 3 Tagen | Berechnung: daily | Item-Type: num - -- minmax_tag_minus3_avg: Durchschnittswert heute vor 3 Tagen | Berechnung: daily | Item-Type: num - -- minmax_woche_min: Minimalwert seit Wochenbeginn | Berechnung: weekly | Item-Type: num - -- minmax_woche_max: Maximalwert seit Wochenbeginn | Berechnung: weekly | Item-Type: num - -- minmax_woche_minus1_min: Minimalwert Vorwoche (aktuelle Woche -1) | Berechnung: weekly | Item-Type: num - -- minmax_woche_minus1_max: Maximalwert Vorwoche (aktuelle Woche -1) | Berechnung: weekly | Item-Type: num - -- minmax_woche_minus1_avg: Durchschnittswert Vorwoche (aktuelle Woche -1) | Berechnung: weekly | Item-Type: num - -- minmax_woche_minus2_min: Minimalwert aktuelle Woche -2 Wochen | Berechnung: weekly | Item-Type: num - -- minmax_woche_minus2_max: Maximalwert aktuelle Woche -2 Wochen | Berechnung: weekly | Item-Type: num - -- minmax_woche_minus2_avg: Durchschnittswert aktuelle Woche -2 Wochen | Berechnung: weekly | Item-Type: num - -- minmax_monat_min: Minimalwert seit Monatsbeginn | Berechnung: monthly | Item-Type: num - -- minmax_monat_max: Maximalwert seit Monatsbeginn | Berechnung: monthly | Item-Type: num - -- minmax_monat_minus1_min: Minimalwert Vormonat (aktueller Monat -1) | Berechnung: monthly | Item-Type: num - -- minmax_monat_minus1_max: Maximalwert Vormonat (aktueller Monat -1) | Berechnung: monthly | Item-Type: num - -- minmax_monat_minus1_avg: Durchschnittswert Vormonat (aktueller Monat -1) | Berechnung: monthly | Item-Type: num - -- minmax_monat_minus2_min: Minimalwert aktueller Monat -2 Monate | Berechnung: monthly | Item-Type: num - -- minmax_monat_minus2_max: Maximalwert aktueller Monat -2 Monate | Berechnung: monthly | Item-Type: num - -- minmax_monat_minus2_avg: Durchschnittswert aktueller Monat -2 Monate | Berechnung: monthly | Item-Type: num - -- minmax_jahr_min: Minimalwert seit Jahresbeginn | Berechnung: yearly | Item-Type: num - -- minmax_jahr_max: Maximalwert seit Jahresbeginn | Berechnung: yearly | Item-Type: num - -- minmax_jahr_minus1_min: Minimalwert Vorjahr (aktuelles Jahr -1 Jahr) | Berechnung: yearly | Item-Type: num - -- minmax_jahr_minus1_max: Maximalwert Vorjahr (aktuelles Jahr -1 Jahr) | Berechnung: yearly | Item-Type: num - -- minmax_jahr_minus1_avg: Durchschnittswert Vorjahr (aktuelles Jahr -1 Jahr) | Berechnung: yearly | Item-Type: num - -- tagesmitteltemperatur_heute: Tagesmitteltemperatur heute | Berechnung: daily | Item-Type: num - -- tagesmitteltemperatur_heute_minus1: Tagesmitteltemperatur des letzten Tages (heute -1 Tag) | Berechnung: daily | Item-Type: num - -- tagesmitteltemperatur_heute_minus2: Tagesmitteltemperatur des vorletzten Tages (heute -2 Tag) | Berechnung: daily | Item-Type: num - -- tagesmitteltemperatur_heute_minus3: Tagesmitteltemperatur des vorvorletzten Tages (heute -3 Tag) | Berechnung: daily | Item-Type: num - -- tagesmitteltemperatur_tag: Tagesmitteltemperatur heute | Berechnung: daily | Item-Type: num - -- tagesmitteltemperatur_tag_minus1: Tagesmitteltemperatur des letzten Tages (heute -1 Tag) | Berechnung: daily | Item-Type: num - -- tagesmitteltemperatur_tag_minus2: Tagesmitteltemperatur des vorletzten Tages (heute -2 Tag) | Berechnung: daily | Item-Type: num - -- tagesmitteltemperatur_tag_minus3: Tagesmitteltemperatur des vorvorletzten Tages (heute -3 Tag) | Berechnung: daily | Item-Type: num - -- serie_minmax_monat_min_15m: monatlicher Minimalwert der letzten 15 Monate (gleitend) | Berechnung: monthly | Item-Type: list - -- serie_minmax_monat_max_15m: monatlicher Maximalwert der letzten 15 Monate (gleitend) | Berechnung: monthly | Item-Type: list - -- serie_minmax_monat_avg_15m: monatlicher Mittelwert der letzten 15 Monate (gleitend) | Berechnung: monthly | Item-Type: list - -- serie_minmax_woche_min_30w: wöchentlicher Minimalwert der letzten 30 Wochen (gleitend) | Berechnung: weekly | Item-Type: list - -- serie_minmax_woche_max_30w: wöchentlicher Maximalwert der letzten 30 Wochen (gleitend) | Berechnung: weekly | Item-Type: list - -- serie_minmax_woche_avg_30w: wöchentlicher Mittelwert der letzten 30 Wochen (gleitend) | Berechnung: weekly | Item-Type: list - -- serie_minmax_tag_min_30d: täglicher Minimalwert der letzten 30 Tage (gleitend) | Berechnung: daily | Item-Type: list - -- serie_minmax_tag_max_30d: täglicher Maximalwert der letzten 30 Tage (gleitend) | Berechnung: daily | Item-Type: list - -- serie_minmax_tag_avg_30d: täglicher Mittelwert der letzten 30 Tage (gleitend) | Berechnung: daily | Item-Type: list - -- serie_verbrauch_tag_30d: Verbrauch pro Tag der letzten 30 Tage | Berechnung: daily | Item-Type: list - -- serie_verbrauch_woche_30w: Verbrauch pro Woche der letzten 30 Wochen | Berechnung: weekly | Item-Type: list - -- serie_verbrauch_monat_18m: Verbrauch pro Monat der letzten 18 Monate | Berechnung: monthly | Item-Type: list - -- serie_zaehlerstand_tag_30d: Zählerstand am Tagesende der letzten 30 Tage | Berechnung: daily | Item-Type: list - -- serie_zaehlerstand_woche_30w: Zählerstand am Wochenende der letzten 30 Wochen | Berechnung: weekly | Item-Type: list - -- serie_zaehlerstand_monat_18m: Zählerstand am Monatsende der letzten 18 Monate | Berechnung: monthly | Item-Type: list - -- serie_waermesumme_monat_24m: monatliche Wärmesumme der letzten 24 Monate | Berechnung: monthly | Item-Type: list - -- serie_kaeltesumme_monat_24m: monatliche Kältesumme der letzten 24 Monate | Berechnung: monthly | Item-Type: list - -- serie_tagesmittelwert_0d: Tagesmittelwert für den aktuellen Tag | Berechnung: daily | Item-Type: list - -- serie_tagesmittelwert_stunde_0d: Stundenmittelwert für den aktuellen Tag | Berechnung: daily | Item-Type: list - -- serie_tagesmittelwert_stunde_30_0d: Stundenmittelwert für den aktuellen Tag | Berechnung: daily | Item-Type: list - -- serie_tagesmittelwert_tag_stunde_30d: Stundenmittelwert pro Tag der letzten 30 Tage (bspw. zur Berechnung der Tagesmitteltemperatur basierend auf den Mittelwert der Temperatur pro Stunde | Berechnung: daily | Item-Type: list +Bei Verwendung von "db_addon_params" müssen die Parameter im Format 'kwargs' eingerahmt von Quotes angegeben werden: 'func=min, timeframe=day' +Bei Verwendung von "db_addon_params_dict" müssen die Parameter im Format 'dicht' eingerahmt von Quotes angegeben werden: "{'func': 'min', 'timeframe': 'day', 'start': 1}" -- general_oldest_value: Ausgabe des ältesten Wertes des entsprechenden "Parent-Items" mit database Attribut | Berechnung: None | Item-Type: num +Hier ein Beispiel: -- general_oldest_log: Ausgabe des Timestamp des ältesten Eintrages des entsprechenden "Parent-Items" mit database Attribut | Berechnung: None | Item-Type: list - -- kaeltesumme: Berechnet die Kältesumme für einen Zeitraum, db_addon_params: (year=optional, month=optional) | Berechnung: daily | Item-Type: num - -- waermesumme: Berechnet die Wärmesumme für einen Zeitraum, db_addon_params: (year=optional, month=optional) | Berechnung: daily | Item-Type: num - -- gruenlandtempsumme: Berechnet die Grünlandtemperatursumme für einen Zeitraum, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num - -- wachstumsgradtage: Berechnet die Wachstumsgradtage auf Basis der stündlichen Durchschnittswerte eines Tages für das laufende Jahr mit an Angabe des Temperaturschwellenwertes (threshold=Schwellentemperatur) | Berechnung: daily | Item-Type: num - -- wuestentage: Berechnet die Anzahl der Wüstentage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num - -- heisse_tage: Berechnet die Anzahl der heissen Tage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num - -- tropennaechte: Berechnet die Anzahl der Tropennächte des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num - -- sommertage: Berechnet die Anzahl der Sommertage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num - -- heiztage: Berechnet die Anzahl der Heiztage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num - -- vegetationstage: Berechnet die Anzahl der Vegatationstage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num - -- frosttage: Berechnet die Anzahl der Frosttage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num - -- eistage: Berechnet die Anzahl der Eistage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num - -- tagesmitteltemperatur: Berechnet die Tagesmitteltemperatur auf Basis der stündlichen Durchschnittswerte eines Tages für die angegebene Anzahl von Tagen (timeframe=day, count=integer) | Berechnung: daily | Item-Type: list - -- db_request: Abfrage der DB: db_addon_params: (func=mandatory, item=mandatory, timespan=mandatory, start=optional, end=optional, count=optional, group=optional, group2=optional) | Berechnung: group | Item-Type: list - -- minmax: Berechnet einen min/max/avg Wert für einen bestimmen Zeitraum: db_addon_params: (func=mandatory, timeframe=mandatory, start=mandatory) | Berechnung: timeframe | Item-Type: num - -- minmax_last: 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) | Berechnung: timeframe | Item-Type: num - -- verbrauch: Berechnet einen Verbrauchswert für einen bestimmen Zeitraum: db_addon_params: (timeframe=mandatory, start=mandatory end=mandatory) | Berechnung: timeframe | Item-Type: num - -- zaehlerstand: Berechnet einen Zählerstand für einen bestimmen Zeitpunkt: db_addon_params: (timeframe=mandatory, start=mandatory) | Berechnung: timeframe | Item-Type: num - - -db_addon_info -------------- - -- db_version: Version der verbundenen Datenbank | Berechnung: no | Item-Type: str - - -db_addon_admin --------------- - -- suspend: Unterbricht die Aktivitäten des Plugin | Berechnung: no | Item-Type: bool - -- recalc_all: Startet einen Neuberechnungslauf aller on-demand Items | Berechnung: no | Item-Type: bool - -- clean_cache_values: Löscht Plugin-Cache und damit alle im Plugin zwischengespeicherten Werte | Berechnung: no | Item-Type: bool +.. code-block:: yaml + temperature: + type: num -Hinweise -======== + minmax_test_min_gestern: + name: Minimaler Wert gestern + type: num + db_addon_fct: minmax + db_addon_params_dict: "{'func': 'min', 'timeframe': 'day', 'start': 1}" + db_addon_startup: yes - - Das Plugin startet die Berechnungen der Werte nach einer gewissen (konfigurierbaren) Zeit (Attribut `startup_run_delay`) - nach dem Start von shNG, um den Startvorgang nicht zu beeinflussen. +minmax +------ - - Bei Start werden automatisch nur die Items berechnet, für das das Attribute `db_addon_startup` gesetzt wurde. Alle anderen - Items werden erst zur konfigurierten Zeit berechnet. Das Attribute `db_addon_startup` kann auch direkt am `Database-Item` - gesetzt werden. Dabei wird das Attribut auf alle darunter liegenden `db_addon-Items` (bspw. bei Verwendung von structs) vererbt. - Über das WebIF kann die Berechnung aller definierten Items ausgelöst werden. +Berechnet einen min/max/avg Wert für einen bestimmen Zeitraum. +In den db_addon_params müssen folgenden Parameter definiert sein: - - Für sogenannte `on_change` Items, also Items, deren Berechnung bis zum Jetzt (bspw. verbrauch-heute) gehen, wird die Berechnung - immer bei eintreffen eines neuen Wertes gestartet. Zu Reduktion der Belastung auf die Datenbank werden die Werte für das Ende der - letzten Periode gecached. +- func: min/max/avg +- timeframe: day/week/month/year +- start: integer wert - - Berechnungen werden nur ausgeführt, wenn für den kompletten abgefragten Zeitraum Werte in der Datenbank vorliegen. Wird bspw. - der Verbrauch des letzten Monats abgefragt wobei erst Werte ab dem 3. des Monats in der Datenbank sind, wird die Berechnung abgebrochen. +Hier ein Beispiel: - - Mit dem Attribut `use_oldest_entry` kann dieses Verhalten verändert werden. Ist das Attribut gesetzt, wird, wenn für den - Beginn der Abfragezeitraums keinen Werte vorliegen, der älteste Eintrag der Datenbank genutzt. +.. code-block:: yaml + minmax_min_gestern: + name: Minimaler Wert gestern + type: num + db_addon_fct: minmax + db_addon_params_dict: "{'func': 'min', 'timeframe': 'day', 'start': 1}" - - Für die Auswertung kann es nützlich sein, bestimmte Werte aus der Datenbank bei der Berechnung auszublenden. Hierfür stehen - 2 Möglichkeiten zur Verfügung: - - Plugin-Attribut `ignore_0`: (list of strings) Bei Items, bei denen ein String aus der Liste im Pfadnamen vorkommt, - werden 0-Werte (val_num = 0) bei Datenbankauswertungen ignoriert. Hat also das Attribut den Wert ['temp'] werden bei allen Items mit - 'temp' im Pfadnamen die 0-Werte bei der Auswertung ignoriert. - - Item-Attribut `db_addon_ignore_value`: (num) Dieser Wert wird bei der Abfrage bzw. Auswertung der Datenbank für diese - Item ignoriert. - - Das Plugin enthält sehr ausführliche Logginginformation. Bei unerwartetem Verhalten, den LogLevel entsprechend anpassen, - um mehr information zu erhalten. +minmax_last +----------- +'Berechnet einen min/max/avg Wert für ein bestimmtes Zeitfenster von jetzt zurück. +In den db_addon_params müssen folgenden Parameter definiert sein: - - Berechnungen des Plugins können im WebIF unterbrochen werden. Auch das gesamte Plugin kann pausiert werden. Dies kann bei - starker Systembelastung nützlich sein. +- func: min/max/avg +- timeframe: day/week/month/year +- start: integer wert +- end: integer wert +.. code-block:: yaml + minmax_last_21: + type: num + db_addon_fct: minmax_last + db_addon_params_dict: "{'func': 'min', 'timeframe': 'day', 'start': 2, 'end': 1}" -Beispiele -========= -Verbrauch +verbrauch --------- +Berechnet einen Verbrauchswert für einen bestimmen Zeitraum: -Soll bspw. der Verbrauch von Wasser ausgewertet werden, so ist dies wie folgt möglich: - +- timeframe: day/week/month/year +- start: integer wert +- end: integer wert .. code-block:: yaml - - wasserzaehler: - zaehlerstand: + verbrauch_gestern: type: num - knx_dpt: 12 - knx_cache: 5/3/4 - eval: round(value/1000, 1) - database: init - struct: - - db_addon.verbrauch_1 - - db_addon.verbrauch_2 - - db_addon.zaehlerstand_1 - -Die Werte des Wasserzählerstandes werden in die Datenbank geschrieben und darauf basierend ausgewertet. Die structs -'db_addon.verbrauch_1' und 'db_addon.verbrauch_2' stellen entsprechende Items für die Verbrauchsauswerten zur Verfügung. + db_addon_fct: verbrauch + db_addon_params_dict: "{'timeframe': 'day', 'start': 2, 'end': 1}" -minmax ------- -Soll bspw. die minimalen und maximalen Temperaturen ausgewertet werden, kann dies so umgesetzt werden: +zaehlerstand +------------ -.. code-block:: yaml +Berechnet einen Zählerstand für einen bestimmen Zeitpunkt: - temperature: - aussen: - nord: - name: Außentemp Nordseite - type: num - visu_acl: ro - knx_dpt: 9 - knx_cache: 6/5/1 - database: init - struct: - - db_addon.minmax_1 - - db_addon.minmax_2 +- timeframe: day/week/month/year +- start: integer wert -Die Temperaturwerte werden in die Datenbank geschrieben und darauf basierend ausgewertet. Die structs -'db_addon.minmax_1' und 'db_addon.minmax_2' stellen entsprechende Items für die min/max Auswertung zur Verfügung. +.. code-block:: yaml + zaehlerstand_gestern: + type: num + db_addon_fct: zaehlerstand + db_addon_params_dict: "{'timeframe': 'day', 'start': 1}" -| Web Interface ============= @@ -4721,6 +642,7 @@ Das Webinterface zeigt detaillierte Informationen über die im Plugin verfügbar Dies dient der Maintenance bzw. Fehlersuche. Dieser Tab ist nur bei Log-Level "Debug" verfügbar. + Erläuterungen zu Temperatursummen ================================= From c14e4d74e03b3ff57716766849aa8edcdba4e99b Mon Sep 17 00:00:00 2001 From: sisamiwe Date: Thu, 30 Nov 2023 10:40:57 +0100 Subject: [PATCH 16/18] DB_ADDON: - bugfix on-change item calculation --- db_addon/__init__.py | 32 +------------------------------- 1 file changed, 1 insertion(+), 31 deletions(-) diff --git a/db_addon/__init__.py b/db_addon/__init__.py index fe7b389d7..d0afe70f1 100644 --- a/db_addon/__init__.py +++ b/db_addon/__init__.py @@ -685,11 +685,6 @@ def format_db_addon_ignore_value_list(optimize: bool = self.optimize_value_filte # add type (onchange or ondemand) to item dict item_config_data_dict.update({'on': item_attribute_dict['on']}) - # ToDo: Remove - # if db_addon_fct in ONCHANGE_ATTRIBUTES: - # item_config_data_dict.update({'on': 'change'}) - # elif db_addon_fct in ONDEMAND_ATTRIBUTES: - # item_config_data_dict.update({'on': 'demand'}) # add cycle for item groups cycle = item_attribute_dict['calc'] @@ -705,31 +700,6 @@ def format_db_addon_ignore_value_list(optimize: bool = self.optimize_value_filte cycle = None item_config_data_dict.update({'cycle': cycle}) - # ToDo: Remove - # if db_addon_fct in ALL_HOURLY_ATTRIBUTES: - # item_config_data_dict.update({'cycle': 'hourly'}) - # elif db_addon_fct in ALL_DAILY_ATTRIBUTES: - # item_config_data_dict.update({'cycle': 'daily'}) - # elif db_addon_fct in ALL_WEEKLY_ATTRIBUTES: - # item_config_data_dict.update({'cycle': 'weekly'}) - # elif db_addon_fct in ALL_MONTHLY_ATTRIBUTES: - # item_config_data_dict.update({'cycle': 'monthly'}) - # elif db_addon_fct in ALL_YEARLY_ATTRIBUTES: - # item_config_data_dict.update({'cycle': 'yearly'}) - # elif db_addon_fct in ALL_GEN_ATTRIBUTES: - # item_config_data_dict.update({'cycle': 'static'}) - # elif db_addon_fct == 'db_request': - # cycle = item_config_data_dict['query_params'].get('group') - # if not cycle: - # cycle = item_config_data_dict['query_params'].get('timeframe') - # item_config_data_dict.update({'cycle': f"{timeframe_to_updatecyle(cycle)}"}) - # elif db_addon_fct == 'minmax': - # cycle = item_config_data_dict['query_params']['timeframe'] - # item_config_data_dict.update({'cycle': f"{timeframe_to_updatecyle(cycle)}"}) - # else: - # self.logger.warning(f"Cycle for {item.path()} undefined") - # item_config_data_dict.update({'cycle': None}) - # do logging if self.debug_log.parse: self.logger.debug(f"Item '{item.path()}' added to be run {item_config_data_dict['cycle']}.") @@ -1253,7 +1223,7 @@ def handle_tagesmittel(): if self.debug_log.onchange: self.logger.debug(f"called with updated_item={updated_item.path()} and value={value}.") - relevant_item_list = set(self.get_item_list('database_item', updated_item)) & set(self.get_item_list('cycle', 'onchange')) + relevant_item_list = set(self.get_item_list('database_item', updated_item)) & set(self.get_item_list('on', 'change')) if self.debug_log.onchange: self.logger.debug(f"Following items where identified for update: {relevant_item_list}.") From fa35ed32eb36d42aaebc12c116be2bddb258a9c4 Mon Sep 17 00:00:00 2001 From: sisamiwe Date: Thu, 30 Nov 2023 16:00:20 +0100 Subject: [PATCH 17/18] DB_ADDON: - resolve conflicts to be able to merge --- db_addon/user_doc.rst | 749 ------------------------------------------ 1 file changed, 749 deletions(-) delete mode 100644 db_addon/user_doc.rst diff --git a/db_addon/user_doc.rst b/db_addon/user_doc.rst deleted file mode 100644 index 9b501e02e..000000000 --- a/db_addon/user_doc.rst +++ /dev/null @@ -1,749 +0,0 @@ - -.. index:: Plugins; db_addon (Datenbank Unterstützung) -.. index:: db_addon - -======== -db_addon -======== - -.. image:: webif/static/img/plugin_logo.png - :alt: plugin logo - :width: 300px - :height: 300px - :scale: 50 % - :align: left - - -Das Plugin bietet eine Funktionserweiterung zum Database Plugin und ermöglicht die einfache Auswertung von Messdaten. -Basierend auf den Daten in der Datenbank können bspw. Auswertungen zu Verbrauch (heute, gestern, ...) oder zu Minimal- -und Maximalwerten gefahren werden. -Diese Auswertungen werden zyklisch zum Tageswechsel, Wochenwechsel, Monatswechsel oder Jahreswechsel, in Abhängigkeit -der Funktion erzeugt. -Um die Zugriffe auf die Datenbank zu minimieren, werden diverse Daten zwischengespeichert. - -Sind Items mit einem DatabaseAddon-Attribut im gleichen Pfad, wie das Item, für das das Database Attribut -konfiguriert ist, wird dieses Item automatisch ermittelt. Bedeutet: Sind die Items mit dem DatabaseAddon-Attribute Kinder -oder Kindeskinder oder Kindeskinderkinder des Items, für das das Database Attribut konfiguriert ist, wird dieses automatisch -ermittelt. - -Alternativ kann mit dem Attribute "db_addon_database_item" auch der absolute Pfad des Items angegeben werden, für das -das Database Attribut konfiguriert ist. - -Bsp: - - -.. code-block:: yaml - - temperatur: - type: bool - database: yes - - auswertung: - type: foo - - heute_min: - type: num - db_addon_fct: heute_min - - gestern_max: - type: num - db_addon_fct: heute_minus1_max - - - tagesmitteltemperatur_gestern: - type: num - db_addon_fct: heute_minus1_avg - db_addon_database_item: 'temperatur' - - -Anforderungen -============= - -Es muss das Database Plugin konfiguriert und aktiv sein. In den Plugin Parametern ist der Name der Konfiguration des -Database-Plugins anzugeben. Damit ist auch eine etwaig definierte Instanz des Database-Plugins definiert. -Die Konfiguration des DatabaseAddon-Plugin erfolgt automatisch bei Start. - - -Hinweis: Das Plugin selbst ist aktuell nicht multi-instance fähig. Das bedeutet, dass das Plugin aktuell nur eine Instanz -des Database-Plugin abgebunden werden kann. - - -Hinweise -======== - - - Das Plugin startet die Berechnungen der Werte nach einer gewissen (konfigurierbaren) Zeit (Attribut `startup_run_delay`) - nach dem Start von shNG, um den Startvorgang nicht zu beeinflussen. - - - Bei Start werden automatisch nur die Items berechnet, für das das Attribute `db_addon_startup` gesetzt wurde. Alle anderen - Items werden erst zur konfigurierten Zeit berechnet. Das Attribute `db_addon_startup` kann auch direkt am `Database-Item` - gesetzt werden. Dabei wird das Attribut auf alle darunter liegenden `db_addon-Items` (bspw. bei Verwendung von structs) vererbt. - Über das WebIF kann die Berechnung aller definierten Items ausgelöst werden. - - - Für sogenannte `on_change` Items, also Items, deren Berechnung bis zum Jetzt (bspw. verbrauch-heute) gehen, wird die Berechnung - immer bei eintreffen eines neuen Wertes gestartet. Zu Reduktion der Belastung auf die Datenbank werden die Werte für das Ende der - letzten Periode gecached. - - - Berechnungen werden nur ausgeführt, wenn für den kompletten abgefragten Zeitraum Werte in der Datenbank vorliegen. Wird bspw. - der Verbrauch des letzten Monats abgefragt wobei erst Werte ab dem 3. des Monats in der Datenbank sind, wird die Berechnung abgebrochen. - - - Mit dem Attribut `use_oldest_entry` kann dieses Verhalten verändert werden. Ist das Attribut gesetzt, wird, wenn für den - Beginn der Abfragezeitraums keinen Werte vorliegen, der älteste Eintrag der Datenbank genutzt. - - - Für die Auswertung kann es nützlich sein, bestimmte Werte aus der Datenbank bei der Berechnung auszublenden. Hierfür stehen - 2 Möglichkeiten zur Verfügung: - - Plugin-Attribut `ignore_0`: (list of strings) Bei Items, bei denen ein String aus der Liste im Pfadnamen vorkommt, - werden 0-Werte (val_num = 0) bei Datenbankauswertungen ignoriert. Hat also das Attribut den Wert ['temp'] werden bei allen Items mit - 'temp' im Pfadnamen die 0-Werte bei der Auswertung ignoriert. - - Item-Attribut `db_addon_ignore_value`: (num) Dieser Wert wird bei der Abfrage bzw. Auswertung der Datenbank für diese - Item ignoriert. - - - Das Plugin enthält sehr ausführliche Logginginformation. Bei unerwartetem Verhalten, den LogLevel entsprechend anpassen, - um mehr information zu erhalten. - - - Berechnungen des Plugins können im WebIF unterbrochen werden. Auch das gesamte Plugin kann pausiert werden. Dies kann bei - starker Systembelastung nützlich sein. - - -mysql Datenbank ---------------- - -Bei Verwendung von mysql sollten einige Variablen der Datenbank angepasst werden, so dass die komplexeren Anfragen -ohne Fehler bearbeitet werden. - -Dazu folgenden Block am Ende der Datei */etc/mysql/my.cnf* einfügen bzw den existierenden ergänzen. - - -.. code-block:: bash - - [mysqld] - connect_timeout = 60 - net_read_timeout = 60 - wait_timeout = 28800 - interactive_timeout = 28800 - - - -Konfiguration -============= - -Diese Plugin Parameter und die Informationen zur Item-spezifischen Konfiguration des Plugins sind -unter :doc:`/plugins_doc/config/db_addon` beschrieben. - -Die folgenden Kapitel wurde automatisch durch Ausführen des Skripts in der Datei 'item_attributes_master.py' erstellt. - -Nachfolgend eine Auflistung der möglichen Attribute für das Plugin im Format: Attribute: Beschreibung | Berechnungszyklus | Item-Type - -db_addon_fct ------------- - -- verbrauch_heute: Verbrauch am heutigen Tag (Differenz zwischen aktuellem Wert und den Wert am Ende des vorherigen Tages) | Berechnung: onchange | Item-Type: num - -- verbrauch_tag: Verbrauch am heutigen Tag (Differenz zwischen aktuellem Wert und den Wert am Ende des vorherigen Tages) | Berechnung: onchange | Item-Type: num - -- verbrauch_woche: Verbrauch in der aktuellen Woche | Berechnung: onchange | Item-Type: num - -- verbrauch_monat: Verbrauch im aktuellen Monat | Berechnung: onchange | Item-Type: num - -- verbrauch_jahr: Verbrauch im aktuellen Jahr | Berechnung: onchange | Item-Type: num - -- verbrauch_last_24h: Verbrauch innerhalb letzten 24h | Berechnung: hourly | Item-Type: num - -- verbrauch_last_7d: Verbrauch innerhalb letzten 7 Tage | Berechnung: hourly | Item-Type: num - -- verbrauch_heute_minus1: Verbrauch gestern (heute -1 Tag) (Differenz zwischen Wert am Ende des gestrigen Tages und dem Wert am Ende des Tages davor) | Berechnung: daily | Item-Type: num - -- verbrauch_heute_minus2: Verbrauch vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num - -- verbrauch_heute_minus3: Verbrauch heute -3 Tage | Berechnung: daily | Item-Type: num - -- verbrauch_heute_minus4: Verbrauch heute -4 Tage | Berechnung: daily | Item-Type: num - -- verbrauch_heute_minus5: Verbrauch heute -5 Tage | Berechnung: daily | Item-Type: num - -- verbrauch_heute_minus6: Verbrauch heute -6 Tage | Berechnung: daily | Item-Type: num - -- verbrauch_heute_minus7: Verbrauch heute -7 Tage | Berechnung: daily | Item-Type: num - -- verbrauch_heute_minus8: Verbrauch heute -8 Tage | Berechnung: daily | Item-Type: num - -- verbrauch_tag_minus1: Verbrauch gestern (heute -1 Tag) (Differenz zwischen Wert am Ende des gestrigen Tages und dem Wert am Ende des Tages davor) | Berechnung: daily | Item-Type: num - -- verbrauch_tag_minus2: Verbrauch vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num - -- verbrauch_tag_minus3: Verbrauch heute -3 Tage | Berechnung: daily | Item-Type: num - -- verbrauch_tag_minus4: Verbrauch heute -4 Tage | Berechnung: daily | Item-Type: num - -- verbrauch_tag_minus5: Verbrauch heute -5 Tage | Berechnung: daily | Item-Type: num - -- verbrauch_tag_minus6: Verbrauch heute -6 Tage | Berechnung: daily | Item-Type: num - -- verbrauch_tag_minus7: Verbrauch heute -7 Tage | Berechnung: daily | Item-Type: num - -- verbrauch_tag_minus8: Verbrauch heute -8 Tage | Berechnung: daily | Item-Type: num - -- verbrauch_woche_minus1: Verbrauch Vorwoche (aktuelle Woche -1) | Berechnung: weekly | Item-Type: num - -- verbrauch_woche_minus2: Verbrauch aktuelle Woche -2 Wochen | Berechnung: weekly | Item-Type: num - -- verbrauch_woche_minus3: Verbrauch aktuelle Woche -3 Wochen | Berechnung: weekly | Item-Type: num - -- verbrauch_woche_minus4: Verbrauch aktuelle Woche -4 Wochen | Berechnung: weekly | Item-Type: num - -- verbrauch_monat_minus1: Verbrauch Vormonat (aktueller Monat -1) | Berechnung: monthly | Item-Type: num - -- verbrauch_monat_minus2: Verbrauch aktueller Monat -2 Monate | Berechnung: monthly | Item-Type: num - -- verbrauch_monat_minus3: Verbrauch aktueller Monat -3 Monate | Berechnung: monthly | Item-Type: num - -- verbrauch_monat_minus4: Verbrauch aktueller Monat -4 Monate | Berechnung: monthly | Item-Type: num - -- verbrauch_monat_minus12: Verbrauch aktueller Monat -12 Monate | Berechnung: monthly | Item-Type: num - -- verbrauch_jahr_minus1: Verbrauch Vorjahr (aktuelles Jahr -1 Jahr) | Berechnung: yearly | Item-Type: num - -- verbrauch_jahr_minus2: Verbrauch aktuelles Jahr -2 Jahre | Berechnung: yearly | Item-Type: num - -- verbrauch_rolling_12m_heute_minus1: Verbrauch der letzten 12 Monate ausgehend im Ende des letzten Tages | Berechnung: daily | Item-Type: num - -- verbrauch_rolling_12m_tag_minus1: Verbrauch der letzten 12 Monate ausgehend im Ende des letzten Tages | Berechnung: daily | Item-Type: num - -- verbrauch_rolling_12m_woche_minus1: Verbrauch der letzten 12 Monate ausgehend im Ende der letzten Woche | Berechnung: weekly | Item-Type: num - -- verbrauch_rolling_12m_monat_minus1: Verbrauch der letzten 12 Monate ausgehend im Ende des letzten Monats | Berechnung: monthly | Item-Type: num - -- verbrauch_rolling_12m_jahr_minus1: Verbrauch der letzten 12 Monate ausgehend im Ende des letzten Jahres | Berechnung: yearly | Item-Type: num - -- verbrauch_jahreszeitraum_minus1: Verbrauch seit dem 1.1. bis zum heutigen Tag des Vorjahres | Berechnung: daily | Item-Type: num - -- verbrauch_jahreszeitraum_minus2: Verbrauch seit dem 1.1. bis zum heutigen Tag vor 2 Jahren | Berechnung: daily | Item-Type: num - -- verbrauch_jahreszeitraum_minus3: Verbrauch seit dem 1.1. bis zum heutigen Tag vor 3 Jahren | Berechnung: daily | Item-Type: num - -- zaehlerstand_heute_minus1: Zählerstand / Wert am Ende des letzten Tages (heute -1 Tag) | Berechnung: daily | Item-Type: num - -- zaehlerstand_heute_minus2: Zählerstand / Wert am Ende des vorletzten Tages (heute -2 Tag) | Berechnung: daily | Item-Type: num - -- zaehlerstand_heute_minus3: Zählerstand / Wert am Ende des vorvorletzten Tages (heute -3 Tag) | Berechnung: daily | Item-Type: num - -- zaehlerstand_tag_minus1: Zählerstand / Wert am Ende des letzten Tages (heute -1 Tag) | Berechnung: daily | Item-Type: num - -- zaehlerstand_tag_minus2: Zählerstand / Wert am Ende des vorletzten Tages (heute -2 Tag) | Berechnung: daily | Item-Type: num - -- zaehlerstand_tag_minus3: Zählerstand / Wert am Ende des vorvorletzten Tages (heute -3 Tag) | Berechnung: daily | Item-Type: num - -- zaehlerstand_woche_minus1: Zählerstand / Wert am Ende der vorvorletzten Woche (aktuelle Woche -1 Woche) | Berechnung: weekly | Item-Type: num - -- zaehlerstand_woche_minus2: Zählerstand / Wert am Ende der vorletzten Woche (aktuelle Woche -2 Wochen) | Berechnung: weekly | Item-Type: num - -- zaehlerstand_woche_minus3: Zählerstand / Wert am Ende der aktuellen Woche -3 Wochen | Berechnung: weekly | Item-Type: num - -- zaehlerstand_monat_minus1: Zählerstand / Wert am Ende des letzten Monates (aktueller Monat -1 Monat) | Berechnung: monthly | Item-Type: num - -- zaehlerstand_monat_minus2: Zählerstand / Wert am Ende des vorletzten Monates (aktueller Monat -2 Monate) | Berechnung: monthly | Item-Type: num - -- zaehlerstand_monat_minus3: Zählerstand / Wert am Ende des aktuellen Monats -3 Monate | Berechnung: monthly | Item-Type: num - -- zaehlerstand_jahr_minus1: Zählerstand / Wert am Ende des letzten Jahres (aktuelles Jahr -1 Jahr) | Berechnung: yearly | Item-Type: num - -- zaehlerstand_jahr_minus2: Zählerstand / Wert am Ende des vorletzten Jahres (aktuelles Jahr -2 Jahre) | Berechnung: yearly | Item-Type: num - -- zaehlerstand_jahr_minus3: Zählerstand / Wert am Ende des aktuellen Jahres -3 Jahre | Berechnung: yearly | Item-Type: num - -- minmax_last_24h_min: minimaler Wert der letzten 24h | Berechnung: daily | Item-Type: num - -- minmax_last_24h_max: maximaler Wert der letzten 24h | Berechnung: daily | Item-Type: num - -- minmax_last_24h_avg: durchschnittlicher Wert der letzten 24h | Berechnung: daily | Item-Type: num - -- minmax_last_7d_min: minimaler Wert der letzten 7 Tage | Berechnung: daily | Item-Type: num - -- minmax_last_7d_max: maximaler Wert der letzten 7 Tage | Berechnung: daily | Item-Type: num - -- minmax_last_7d_avg: durchschnittlicher Wert der letzten 7 Tage | Berechnung: daily | Item-Type: num - -- minmax_heute_min: Minimalwert seit Tagesbeginn | Berechnung: onchange | Item-Type: num - -- minmax_heute_max: Maximalwert seit Tagesbeginn | Berechnung: onchange | Item-Type: num - -- minmax_heute_avg: Durschnittswert seit Tagesbeginn | Berechnung: onchange | Item-Type: num - -- minmax_heute_minus1_min: Minimalwert gestern (heute -1 Tag) | Berechnung: daily | Item-Type: num - -- minmax_heute_minus1_max: Maximalwert gestern (heute -1 Tag) | Berechnung: daily | Item-Type: num - -- minmax_heute_minus1_avg: Durchschnittswert gestern (heute -1 Tag) | Berechnung: daily | Item-Type: num - -- minmax_heute_minus2_min: Minimalwert vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num - -- minmax_heute_minus2_max: Maximalwert vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num - -- minmax_heute_minus2_avg: Durchschnittswert vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num - -- minmax_heute_minus3_min: Minimalwert heute vor 3 Tagen | Berechnung: daily | Item-Type: num - -- minmax_heute_minus3_max: Maximalwert heute vor 3 Tagen | Berechnung: daily | Item-Type: num - -- minmax_heute_minus3_avg: Durchschnittswert heute vor 3 Tagen | Berechnung: daily | Item-Type: num - -- minmax_tag_min: Minimalwert seit Tagesbeginn | Berechnung: onchange | Item-Type: num - -- minmax_tag_max: Maximalwert seit Tagesbeginn | Berechnung: onchange | Item-Type: num - -- minmax_tag_avg: Durschnittswert seit Tagesbeginn | Berechnung: onchange | Item-Type: num - -- minmax_tag_minus1_min: Minimalwert gestern (heute -1 Tag) | Berechnung: daily | Item-Type: num - -- minmax_tag_minus1_max: Maximalwert gestern (heute -1 Tag) | Berechnung: daily | Item-Type: num - -- minmax_tag_minus1_avg: Durchschnittswert gestern (heute -1 Tag) | Berechnung: daily | Item-Type: num - -- minmax_tag_minus2_min: Minimalwert vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num - -- minmax_tag_minus2_max: Maximalwert vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num - -- minmax_tag_minus2_avg: Durchschnittswert vorgestern (heute -2 Tage) | Berechnung: daily | Item-Type: num - -- minmax_tag_minus3_min: Minimalwert heute vor 3 Tagen | Berechnung: daily | Item-Type: num - -- minmax_tag_minus3_max: Maximalwert heute vor 3 Tagen | Berechnung: daily | Item-Type: num - -- minmax_tag_minus3_avg: Durchschnittswert heute vor 3 Tagen | Berechnung: daily | Item-Type: num - -- minmax_woche_min: Minimalwert seit Wochenbeginn | Berechnung: onchange | Item-Type: num - -- minmax_woche_max: Maximalwert seit Wochenbeginn | Berechnung: onchange | Item-Type: num - -- minmax_woche_minus1_min: Minimalwert Vorwoche (aktuelle Woche -1) | Berechnung: weekly | Item-Type: num - -- minmax_woche_minus1_max: Maximalwert Vorwoche (aktuelle Woche -1) | Berechnung: weekly | Item-Type: num - -- minmax_woche_minus1_avg: Durchschnittswert Vorwoche (aktuelle Woche -1) | Berechnung: weekly | Item-Type: num - -- minmax_woche_minus2_min: Minimalwert aktuelle Woche -2 Wochen | Berechnung: weekly | Item-Type: num - -- minmax_woche_minus2_max: Maximalwert aktuelle Woche -2 Wochen | Berechnung: weekly | Item-Type: num - -- minmax_woche_minus2_avg: Durchschnittswert aktuelle Woche -2 Wochen | Berechnung: weekly | Item-Type: num - -- minmax_monat_min: Minimalwert seit Monatsbeginn | Berechnung: onchange | Item-Type: num - -- minmax_monat_max: Maximalwert seit Monatsbeginn | Berechnung: onchange | Item-Type: num - -- minmax_monat_minus1_min: Minimalwert Vormonat (aktueller Monat -1) | Berechnung: monthly | Item-Type: num - -- minmax_monat_minus1_max: Maximalwert Vormonat (aktueller Monat -1) | Berechnung: monthly | Item-Type: num - -- minmax_monat_minus1_avg: Durchschnittswert Vormonat (aktueller Monat -1) | Berechnung: monthly | Item-Type: num - -- minmax_monat_minus2_min: Minimalwert aktueller Monat -2 Monate | Berechnung: monthly | Item-Type: num - -- minmax_monat_minus2_max: Maximalwert aktueller Monat -2 Monate | Berechnung: monthly | Item-Type: num - -- minmax_monat_minus2_avg: Durchschnittswert aktueller Monat -2 Monate | Berechnung: monthly | Item-Type: num - -- minmax_jahr_min: Minimalwert seit Jahresbeginn | Berechnung: onchange | Item-Type: num - -- minmax_jahr_max: Maximalwert seit Jahresbeginn | Berechnung: onchange | Item-Type: num - -- minmax_jahr_minus1_min: Minimalwert Vorjahr (aktuelles Jahr -1 Jahr) | Berechnung: yearly | Item-Type: num - -- minmax_jahr_minus1_max: Maximalwert Vorjahr (aktuelles Jahr -1 Jahr) | Berechnung: yearly | Item-Type: num - -- minmax_jahr_minus1_avg: Durchschnittswert Vorjahr (aktuelles Jahr -1 Jahr) | Berechnung: yearly | Item-Type: num - -- tagesmitteltemperatur_heute: Tagesmitteltemperatur heute | Berechnung: onchange | Item-Type: num - -- tagesmitteltemperatur_heute_minus1: Tagesmitteltemperatur des letzten Tages (heute -1 Tag) | Berechnung: daily | Item-Type: num - -- tagesmitteltemperatur_heute_minus2: Tagesmitteltemperatur des vorletzten Tages (heute -2 Tag) | Berechnung: daily | Item-Type: num - -- tagesmitteltemperatur_heute_minus3: Tagesmitteltemperatur des vorvorletzten Tages (heute -3 Tag) | Berechnung: daily | Item-Type: num - -- tagesmitteltemperatur_tag: Tagesmitteltemperatur heute | Berechnung: onchange | Item-Type: num - -- tagesmitteltemperatur_tag_minus1: Tagesmitteltemperatur des letzten Tages (heute -1 Tag) | Berechnung: daily | Item-Type: num - -- tagesmitteltemperatur_tag_minus2: Tagesmitteltemperatur des vorletzten Tages (heute -2 Tag) | Berechnung: daily | Item-Type: num - -- tagesmitteltemperatur_tag_minus3: Tagesmitteltemperatur des vorvorletzten Tages (heute -3 Tag) | Berechnung: daily | Item-Type: num - -- serie_minmax_monat_min_15m: monatlicher Minimalwert der letzten 15 Monate (gleitend) | Berechnung: monthly | Item-Type: list - -- serie_minmax_monat_max_15m: monatlicher Maximalwert der letzten 15 Monate (gleitend) | Berechnung: monthly | Item-Type: list - -- serie_minmax_monat_avg_15m: monatlicher Mittelwert der letzten 15 Monate (gleitend) | Berechnung: monthly | Item-Type: list - -- serie_minmax_woche_min_30w: wöchentlicher Minimalwert der letzten 30 Wochen (gleitend) | Berechnung: weekly | Item-Type: list - -- serie_minmax_woche_max_30w: wöchentlicher Maximalwert der letzten 30 Wochen (gleitend) | Berechnung: weekly | Item-Type: list - -- serie_minmax_woche_avg_30w: wöchentlicher Mittelwert der letzten 30 Wochen (gleitend) | Berechnung: weekly | Item-Type: list - -- serie_minmax_tag_min_30d: täglicher Minimalwert der letzten 30 Tage (gleitend) | Berechnung: daily | Item-Type: list - -- serie_minmax_tag_max_30d: täglicher Maximalwert der letzten 30 Tage (gleitend) | Berechnung: daily | Item-Type: list - -- serie_minmax_tag_avg_30d: täglicher Mittelwert der letzten 30 Tage (gleitend) | Berechnung: daily | Item-Type: list - -- serie_verbrauch_tag_30d: Verbrauch pro Tag der letzten 30 Tage | Berechnung: daily | Item-Type: list - -- serie_verbrauch_woche_30w: Verbrauch pro Woche der letzten 30 Wochen | Berechnung: weekly | Item-Type: list - -- serie_verbrauch_monat_18m: Verbrauch pro Monat der letzten 18 Monate | Berechnung: monthly | Item-Type: list - -- serie_zaehlerstand_tag_30d: Zählerstand am Tagesende der letzten 30 Tage | Berechnung: daily | Item-Type: list - -- serie_zaehlerstand_woche_30w: Zählerstand am Wochenende der letzten 30 Wochen | Berechnung: weekly | Item-Type: list - -- serie_zaehlerstand_monat_18m: Zählerstand am Monatsende der letzten 18 Monate | Berechnung: monthly | Item-Type: list - -- serie_waermesumme_monat_24m: monatliche Wärmesumme der letzten 24 Monate | Berechnung: monthly | Item-Type: list - -- serie_kaeltesumme_monat_24m: monatliche Kältesumme der letzten 24 Monate | Berechnung: monthly | Item-Type: list - -- serie_tagesmittelwert_0d: Tagesmittelwert für den aktuellen Tag | Berechnung: daily | Item-Type: list - -- serie_tagesmittelwert_stunde_0d: Stundenmittelwert für den aktuellen Tag | Berechnung: daily | Item-Type: list - -- serie_tagesmittelwert_stunde_30_0d: Stundenmittelwert für den aktuellen Tag | Berechnung: daily | Item-Type: list - -- serie_tagesmittelwert_tag_stunde_30d: Stundenmittelwert pro Tag der letzten 30 Tage (bspw. zur Berechnung der Tagesmitteltemperatur basierend auf den Mittelwert der Temperatur pro Stunde | Berechnung: daily | Item-Type: list - -- general_oldest_value: Ausgabe des ältesten Wertes des entsprechenden "Parent-Items" mit database Attribut | Berechnung: no | Item-Type: num - -- general_oldest_log: Ausgabe des Timestamp des ältesten Eintrages des entsprechenden "Parent-Items" mit database Attribut | Berechnung: no | Item-Type: list - -- kaeltesumme: Berechnet die Kältesumme für einen Zeitraum, db_addon_params: (year=optional, month=optional) | Berechnung: daily | Item-Type: num - -- waermesumme: Berechnet die Wärmesumme für einen Zeitraum, db_addon_params: (year=optional, month=optional) | Berechnung: daily | Item-Type: num - -- gruenlandtempsumme: Berechnet die Grünlandtemperatursumme für einen Zeitraum, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num - -- wachstumsgradtage: Berechnet die Wachstumsgradtage auf Basis der stündlichen Durchschnittswerte eines Tages für das laufende Jahr mit an Angabe des Temperaturschwellenwertes (threshold=Schwellentemperatur) | Berechnung: daily | Item-Type: num - -- wuestentage: Berechnet die Anzahl der Wüstentage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num - -- heisse_tage: Berechnet die Anzahl der heissen Tage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num - -- tropennaechte: Berechnet die Anzahl der Tropennächte des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num - -- sommertage: Berechnet die Anzahl der Sommertage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num - -- heiztage: Berechnet die Anzahl der Heiztage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num - -- vegetationstage: Berechnet die Anzahl der Vegatationstage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num - -- frosttage: Berechnet die Anzahl der Frosttage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num - -- eistage: Berechnet die Anzahl der Eistage des Jahres, db_addon_params: (year=optional) | Berechnung: daily | Item-Type: num - -- tagesmitteltemperatur: Berechnet die Tagesmitteltemperatur auf Basis der stündlichen Durchschnittswerte eines Tages für die angegebene Anzahl von Tagen (timeframe=day, count=integer) | Berechnung: daily | Item-Type: list - -- db_request: Abfrage der DB: db_addon_params: (func=mandatory, item=mandatory, timespan=mandatory, start=optional, end=optional, count=optional, group=optional, group2=optional) | Berechnung: group | Item-Type: list - -- minmax: Berechnet einen min/max/avg Wert für einen bestimmen Zeitraum: db_addon_params: (func=mandatory, timeframe=mandatory, start=mandatory) | Berechnung: timeframe | Item-Type: num - -- minmax_last: 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) | Berechnung: timeframe | Item-Type: num - -- verbrauch: Berechnet einen Verbrauchswert für einen bestimmen Zeitraum: db_addon_params: (timeframe=mandatory, start=mandatory end=mandatory) | Berechnung: timeframe | Item-Type: num - -- zaehlerstand: Berechnet einen Zählerstand für einen bestimmen Zeitpunkt: db_addon_params: (timeframe=mandatory, start=mandatory) | Berechnung: timeframe | Item-Type: num - - -db_addon_info -------------- - -- db_version: Version der verbundenen Datenbank | Berechnung: no | Item-Type: str - - -db_addon_admin --------------- - -- suspend: Unterbricht die Aktivitäten des Plugin | Berechnung: no | Item-Type: bool - -- recalc_all: Startet einen Neuberechnungslauf aller on-demand Items | Berechnung: no | Item-Type: bool - -- clean_cache_values: Löscht Plugin-Cache und damit alle im Plugin zwischengespeicherten Werte | Berechnung: no | Item-Type: bool - - - -Beispiele -========= - -Verbrauch ---------- - -Soll bspw. der Verbrauch von Wasser ausgewertet werden, so ist dies wie folgt möglich: - - -.. code-block:: yaml - - wasserzaehler: - zaehlerstand: - type: num - knx_dpt: 12 - knx_cache: 5/3/4 - eval: round(value/1000, 1) - database: init - struct: - - db_addon.verbrauch_1 - - db_addon.verbrauch_2 - - db_addon.zaehlerstand_1 - -Die Werte des Wasserzählerstandes werden in die Datenbank geschrieben und darauf basierend ausgewertet. Die structs -'db_addon.verbrauch_1' und 'db_addon.verbrauch_2' stellen entsprechende Items für die Verbrauchsauswerten zur Verfügung. - - -minmax ------- - -Soll bspw. die minimalen und maximalen Temperaturen ausgewertet werden, kann dies so umgesetzt werden: - -.. code-block:: yaml - - temperature: - aussen: - nord: - name: Außentemp Nordseite - type: num - visu_acl: ro - knx_dpt: 9 - knx_cache: 6/5/1 - database: init - struct: - - db_addon.minmax_1 - - db_addon.minmax_2 - -Die Temperaturwerte werden in die Datenbank geschrieben und darauf basierend ausgewertet. Die structs -'db_addon.minmax_1' und 'db_addon.minmax_2' stellen entsprechende Items für die min/max Auswertung zur Verfügung. - - -Verwendung von eigenen Zeiträumen ---------------------------------- - -Die Verwendung vorgefertigter Attribute wie bspw "minmax_tag_minus1" bieten eine gute und einfache Möglichkeit, entsprechende Werte ermitteln zu lassen. -Mehr Möglichkeiten bieten die Attribute "minmax", "minmax_last", "zaehlerstand" und "verbrauch". Hier müssen die weiteren Parameterwerte über das Attribut -"db_addon_params_dict" oder "db_addon_params" definiert werden. - -Bei Verwendung von "db_addon_params" müssen die Parameter im Format 'kwargs' eingerahmt von Quotes angegeben werden: 'func=min, timeframe=day' -Bei Verwendung von "db_addon_params_dict" müssen die Parameter im Format 'dicht' eingerahmt von Quotes angegeben werden: "{'func': 'min', 'timeframe': 'day', 'start': 1}" - -Hier ein Beispiel: - -.. code-block:: yaml - - temperature: - type: num - - minmax_test_min_gestern: - name: Minimaler Wert gestern - type: num - db_addon_fct: minmax - db_addon_params_dict: "{'func': 'min', 'timeframe': 'day', 'start': 1}" - db_addon_startup: yes - -minmax ------- - -Berechnet einen min/max/avg Wert für einen bestimmen Zeitraum. -In den db_addon_params müssen folgenden Parameter definiert sein: - -- func: min/max/avg -- timeframe: day/week/month/year -- start: integer wert - -Hier ein Beispiel: - -.. code-block:: yaml - minmax_min_gestern: - name: Minimaler Wert gestern - type: num - db_addon_fct: minmax - db_addon_params_dict: "{'func': 'min', 'timeframe': 'day', 'start': 1}" - - -minmax_last ------------ -'Berechnet einen min/max/avg Wert für ein bestimmtes Zeitfenster von jetzt zurück. -In den db_addon_params müssen folgenden Parameter definiert sein: - -- func: min/max/avg -- timeframe: day/week/month/year -- start: integer wert -- end: integer wert - -.. code-block:: yaml - minmax_last_21: - type: num - db_addon_fct: minmax_last - db_addon_params_dict: "{'func': 'min', 'timeframe': 'day', 'start': 2, 'end': 1}" - - -verbrauch ---------- -Berechnet einen Verbrauchswert für einen bestimmen Zeitraum: - -- timeframe: day/week/month/year -- start: integer wert -- end: integer wert - -.. code-block:: yaml - verbrauch_gestern: - type: num - db_addon_fct: verbrauch - db_addon_params_dict: "{'timeframe': 'day', 'start': 2, 'end': 1}" - - -zaehlerstand ------------- - -Berechnet einen Zählerstand für einen bestimmen Zeitpunkt: - -- timeframe: day/week/month/year -- start: integer wert - -.. code-block:: yaml - zaehlerstand_gestern: - type: num - db_addon_fct: zaehlerstand - db_addon_params_dict: "{'timeframe': 'day', 'start': 1}" - - -Web Interface -============= - -Das WebIF stellt neben der Ansicht verbundener Items und deren Parameter und Werte auch Funktionen für die -Administration des Plugins bereit. - -Es stehen Button für: - -- Neuberechnung aller Items -- Abbruch eines aktiven Berechnungslaufes -- Pausieren des Plugins -- Wiederaufnahme des Plugins - -bereit. - -Achtung: Das Auslösen einer kompletten Neuberechnung aller Items kann zu einer starken Belastung der Datenbank -aufgrund vieler Leseanfragen führen. - - -db_addon Items --------------- - -Dieser Reiter des Webinterface zeigt die Items an, für die ein DatabaseAddon Attribut konfiguriert ist. - - -db_addon Maintenance --------------------- - -Das Webinterface zeigt detaillierte Informationen über die im Plugin verfügbaren Daten an. -Dies dient der Maintenance bzw. Fehlersuche. Dieser Tab ist nur bei Log-Level "Debug" verfügbar. - - - -Erläuterungen zu Temperatursummen -================================= - - -Grünlandtemperatursumme ------------------------ - -Beim Grünland wird die Wärmesumme nach Ernst und Loeper benutzt, um den Vegetationsbeginn und somit den Termin von Düngungsmaßnahmen zu bestimmen. -Dabei erfolgt die Aufsummierung der Tagesmitteltemperaturen über 0 °C, wobei der Januar mit 0.5 und der Februar mit 0.75 gewichtet wird. -Bei einer Wärmesumme von 200 Grad ist eine Düngung angesagt. - -siehe: https://de.wikipedia.org/wiki/Gr%C3%BCnlandtemperatursumme - -Folgende Parameter sind möglich / notwendig: - - -.. code-block:: yaml - - db_addon_params: "year=current" - -- year: Jahreszahl (str oder int), für das die Berechnung ausgeführt werden soll oder "current" für aktuelles Jahr (default: 'current') - - -Wachstumsgradtag ----------------- -Der Begriff Wachstumsgradtage (WGT) ist ein Überbegriff für verschiedene Größen. -Gemeinsam ist ihnen, daß zur Berechnung eine Lufttemperatur von einem Schwellenwert subtrahiert wird. -Je nach Fragestellung und Pflanzenart werden der Schwellenwert unterschiedlich gewählt und die Temperatur unterschiedlich bestimmt. -Verfügbar sind die Berechnung über 0) "einfachen Durchschnitt der Tagestemperaturen", 1) "modifizierten Durchschnitt der Tagestemperaturen" -und 2) Anzahl der Tage, deren Mitteltempertatur oberhalb der Schwellentemperatur lag. - -siehe https://de.wikipedia.org/wiki/Wachstumsgradtag - -Folgende Parameter sind möglich / notwendig: - -.. code-block:: yaml - - db_addon_params: "year=current, method=1, threshold=10" - -- year: Jahreszahl (str oder int), für das die Berechnung ausgeführt werden soll oder "current" für aktuelles Jahr (default: 'current') -- method: 0-Berechnung über "einfachen Durchschnitt der Tagestemperaturen", 1-Berechnung über "modifizierten Durchschnitt (default: 0) -der Tagestemperaturen" 2-Anzahl der Tage, mit Mitteltempertatur oberhalb Schwellentemperatur// 10, 11 Ausgabe aus Zeitserie -- threshold: Schwellentemperatur in °C (int) (default: 10) - - -Wärmesumme ----------- - -Die Wärmesumme soll eine Aussage über den Sommer und die Pflanzenreife liefern. Es gibt keine eindeutige Definition der Größe "Wärmesumme". -Berechnet wird die Wärmesumme als Summe aller Tagesmitteltemperaturen über einem Schwellenwert ab dem 1.1. des Jahres. - -siehe https://de.wikipedia.org/wiki/W%C3%A4rmesumme - -Folgende Parameter sind möglich / notwendig: - -.. code-block:: yaml - - db_addon_params: "year=current, month=1, threshold=10" - -- year: Jahreszahl (str oder int), für das die Berechnung ausgeführt werden soll oder "current" für aktuelles Jahr (default: 'current') -- month: Monat (int) des Jahres, für das die Berechnung ausgeführt werden soll (optional) (default: None) -- threshold: Schwellentemperatur in °C (int) (default: 10) - - -Kältesumme ----------- - -Die Kältesumme soll eine Aussage über die Härte des Winters liefern. -Berechnet wird die Kältesumme als Summe aller negativen Tagesmitteltemperaturen ab dem 21.9. des Jahres bis 31.3. des Folgejahres. - -siehe https://de.wikipedia.org/wiki/K%C3%A4ltesumme - -Folgende Parameter sind möglich / notwendig: - -.. code-block:: yaml - - db_addon_params: "year=current, month=1" - -- year: Jahreszahl (str oder int), für das die Berechnung ausgeführt werden soll oder "current" für aktuelles Jahr (default: 'current') -- month: Monat (int) des Jahres, für das die Berechnung ausgeführt werden soll (optional) (default: None) - - -Tagesmitteltemperatur ---------------------- - -Die Tagesmitteltemperatur wird auf Basis der stündlichen Durchschnittswerte eines Tages (aller in der DB enthaltenen Datensätze) -für die angegebene Anzahl von Tagen (days=optional) berechnet. - - - -Vorgehen bei Funktionserweiterung des Plugins bzw. Ergänzung weiterer Werte für Item-Attribute ----------------------------------------------------------------------------------------------- - -Aufgrund der Vielzahl der möglichen Werte der Itemattribute, insbesondere des Itemattributes `db_addon_fct`, wurde die Erstellung/Update -der entsprechenden Teile der `plugin.yam` sowie die Erstellung der Datei `item_attributes.py`, die vom Plugin verwendet wird, automatisiert. - -Die Masterinformationen für alle Itemattribute sowie die Skripte zum Erstellen/Update der beiden Dateien sind in der -Datei `item_attributes_master.py` enthalten. - -.. important:: - - Korrekturen, Erweiterungen etc. der Itemattribute sollten nur in der Datei `item_attributes_master.py` - im Dict der Variable `ITEM_ATTRIBUTS` vorgenommen werden. Das Ausführen der Datei `item_attributes_master.py` (main) - erstellt die `item_attributes.py` und aktualisiert die `plugin.yaml` entsprechend. From 3869f4af0062240e0968c303016aaf58c85293ff Mon Sep 17 00:00:00 2001 From: sisamiwe Date: Thu, 30 Nov 2023 16:11:30 +0100 Subject: [PATCH 18/18] DB_ADDON: - resolve conflicts to be able to merge --- db_addon/user_doc.rst | 317 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 317 insertions(+) create mode 100644 db_addon/user_doc.rst diff --git a/db_addon/user_doc.rst b/db_addon/user_doc.rst new file mode 100644 index 000000000..9fb0a207b --- /dev/null +++ b/db_addon/user_doc.rst @@ -0,0 +1,317 @@ + +.. index:: Plugins; db_addon (Datenbank Unterstützung) +.. index:: db_addon + +======== +db_addon +======== + +.. image:: webif/static/img/plugin_logo.png + :alt: plugin logo + :width: 300px + :height: 300px + :scale: 50 % + :align: left + + +Das Plugin bietet eine Funktionserweiterung zum Database Plugin und ermöglicht die einfache Auswertung von Messdaten. +Basierend auf den Daten in der Datenbank können bspw. Auswertungen zu Verbrauch (heute, gestern, ...) oder zu Minimal- +und Maximalwerten gefahren werden. +Diese Auswertungen werden zyklisch zum Tageswechsel, Wochenwechsel, Monatswechsel oder Jahreswechsel, in Abhängigkeit +der Funktion erzeugt. +Um die Zugriffe auf die Datenbank zu minimieren, werden diverse Daten zwischengespeichert. + +Sind Items mit einem DatabaseAddon-Attribut im gleichen Pfad, wie das Item, für das das Database Attribut +konfiguriert ist, wird dieses Item automatisch ermittelt. Bedeutet: Sind die Items mit dem DatabaseAddon-Attribute Kinder +oder Kindeskinder oder Kindeskinderkinder des Items, für das das Database Attribut konfiguriert ist, wird dieses automatisch +ermittelt. + +Alternativ kann mit dem Attribute "db_addon_database_item" auch der absolute Pfad des Items angegeben werden, für das +das Database Attribut konfiguriert ist. + +Beispiel: + + +.. code-block:: yaml + + temperatur: + type: bool + database: yes + + auswertung: + type: foo + + heute_min: + type: num + db_addon_fct: heute_min + + gestern_max: + type: num + db_addon_fct: heute_minus1_max + + + tagesmitteltemperatur_gestern: + type: num + db_addon_fct: heute_minus1_avg + db_addon_database_item: 'temperatur' + + +Anforderungen +============= + +Es muss das Database Plugin konfiguriert und aktiv sein. In den Plugin Parametern ist der Name der Konfiguration des +Database-Plugins anzugeben. Damit ist auch eine etwaig definierte Instanz des Database-Plugins definiert. +Die Konfiguration des DatabaseAddon-Plugin erfolgt automatisch bei Start. + + +Hinweis: Das Plugin selbst ist aktuell nicht multi-instance fähig. Das bedeutet, dass das Plugin aktuell nur eine Instanz +des Database-Plugin abgebunden werden kann. + + + +Konfiguration +============= + +Diese Plugin Parameter und die Informationen zur Item-spezifischen Konfiguration des Plugins sind +unter :doc:`/plugins_doc/config/db_addon` beschrieben. + +mysql Datenbank +--------------- + +Bei Verwendung von mysql sollten einige Variablen der Datenbank angepasst werden, so dass die komplexeren Anfragen +ohne Fehler bearbeitet werden. + +Dazu folgenden Block am Ende der Datei */etc/mysql/my.cnf* einfügen bzw den existierenden ergänzen. + + +.. code-block:: bash + + [mysqld] + connect_timeout = 60 + net_read_timeout = 60 + wait_timeout = 28800 + interactive_timeout = 28800 + + + +Hinweise +======== + +- Das Plugin startet die Berechnungen der Werte nach einer gewissen (konfigurierbaren) Zeit (Attribut `startup_run_delay`) + nach dem Start von shNG, um den Startvorgang nicht zu beeinflussen. + +- Bei Start werden automatisch nur die Items berechnet, für das das Attribute `db_addon_startup` gesetzt wurde. Alle anderen + Items werden erst zur konfigurierten Zeit berechnet. Das Attribute `db_addon_startup` kann auch direkt am `Database-Item` + gesetzt werden. Dabei wird das Attribut auf alle darunter liegenden `db_addon-Items` (bspw. bei Verwendung von structs) vererbt. + Über das WebIF kann die Berechnung aller definierten Items ausgelöst werden. + +- Für sogenannte `on_change` Items, also Items, deren Berechnung bis zum Jetzt (bspw. verbrauch-heute) gehen, wird die Berechnung + immer bei eintreffen eines neuen Wertes gestartet. Zu Reduktion der Belastung auf die Datenbank werden die Werte für das Ende der + letzten Periode gecached. + +- Berechnungen werden nur ausgeführt, wenn für den kompletten abgefragten Zeitraum Werte in der Datenbank vorliegen. Wird bspw. + der Verbrauch des letzten Monats abgefragt wobei erst Werte ab dem 3. des Monats in der Datenbank sind, wird die Berechnung abgebrochen. + +- Mit dem Attribut `use_oldest_entry` kann dieses Verhalten verändert werden. Ist das Attribut gesetzt, wird, wenn für den + Beginn der Abfragezeitraums keinen Werte vorliegen, der älteste Eintrag der Datenbank genutzt. + +- Für die Auswertung kann es nützlich sein, bestimmte Werte aus der Datenbank bei der Berechnung auszublenden. Hierfür stehen 2 Möglichkeiten zur Verfügung: + - Plugin-Attribut `ignore_0`: (list of strings) Bei Items, bei denen ein String aus der Liste im Pfadnamen vorkommt, + werden 0-Werte (val_num = 0) bei Datenbankauswertungen ignoriert. Hat also das Attribut den Wert ['temp'] werden bei allen Items mit + 'temp' im Pfadnamen die 0-Werte bei der Auswertung ignoriert. + + - Item-Attribut `db_addon_ignore_value`: (num) Dieser Wert wird bei der Abfrage bzw. Auswertung der Datenbank für dieses Item ignoriert. + +- Das Plugin enthält sehr ausführliche Logginginformation. Bei unerwartetem Verhalten, den LogLevel entsprechend anpassen, + um mehr information zu erhalten. + +- Berechnungen des Plugins können im WebIF unterbrochen werden. Auch das gesamte Plugin kann pausiert werden. Dies kann bei + starker Systembelastung nützlich sein. + + +Beispiele +========= + +Verbrauch +--------- + +Soll bspw. der Verbrauch von Wasser ausgewertet werden, so ist dies wie folgt möglich: + + +.. code-block:: yaml + + wasserzaehler: + zaehlerstand: + type: num + knx_dpt: 12 + knx_cache: 5/3/4 + eval: round(value/1000, 1) + database: init + struct: + - db_addon.verbrauch_1 + - db_addon.verbrauch_2 + - db_addon.zaehlerstand_1 + +Die Werte des Wasserzählerstandes werden in die Datenbank geschrieben und darauf basierend ausgewertet. Die structs +'db_addon.verbrauch_1' und 'db_addon.verbrauch_2' stellen entsprechende Items für die Verbrauchsauswerten zur Verfügung. + +minmax +------ + +Soll bspw. die minimalen und maximalen Temperaturen ausgewertet werden, kann dies so umgesetzt werden: + +.. code-block:: yaml + + temperature: + aussen: + nord: + name: Außentemp Nordseite + type: num + visu_acl: ro + knx_dpt: 9 + knx_cache: 6/5/1 + database: init + struct: + - db_addon.minmax_1 + - db_addon.minmax_2 + +Die Temperaturwerte werden in die Datenbank geschrieben und darauf basierend ausgewertet. Die structs +'db_addon.minmax_1' und 'db_addon.minmax_2' stellen entsprechende Items für die min/max Auswertung zur Verfügung. + + +Web Interface +============= + +Das WebIF stellt neben der Ansicht verbundener Items und deren Parameter und Werte auch Funktionen für die +Administration des Plugins bereit. + +Es stehen Button für: + +- Neuberechnung aller Items +- Abbruch eines aktiven Berechnungslaufes +- Pausieren des Plugins +- Wiederaufnahme des Plugins + +bereit. + +Achtung: Das Auslösen einer kompletten Neuberechnung aller Items kann zu einer starken Belastung der Datenbank +aufgrund vieler Leseanfragen führen. + + +db_addon Items +-------------- + +Dieser Reiter des Webinterface zeigt die Items an, für die ein DatabaseAddon Attribut konfiguriert ist. + + +db_addon Maintenance +-------------------- + +Das Webinterface zeigt detaillierte Informationen über die im Plugin verfügbaren Daten an. +Dies dient der Maintenance bzw. Fehlersuche. Dieser Tab ist nur bei Log-Level "Debug" verfügbar. + + +Erläuterungen zu Temperatursummen +================================= + + +Grünlandtemperatursumme +----------------------- + +Beim Grünland wird die Wärmesumme nach Ernst und Loeper benutzt, um den Vegetationsbeginn und somit den Termin von Düngungsmaßnahmen zu bestimmen. +Dabei erfolgt die Aufsummierung der Tagesmitteltemperaturen über 0 °C, wobei der Januar mit 0.5 und der Februar mit 0.75 gewichtet wird. +Bei einer Wärmesumme von 200 Grad ist eine Düngung angesagt. + +siehe: https://de.wikipedia.org/wiki/Gr%C3%BCnlandtemperatursumme + +Folgende Parameter sind möglich / notwendig: + + +.. code-block:: yaml + + db_addon_params: "year=current" + +- year: Jahreszahl (str oder int), für das die Berechnung ausgeführt werden soll oder "current" für aktuelles Jahr (default: 'current') + + +Wachstumsgradtag +---------------- +Der Begriff Wachstumsgradtage (WGT) ist ein Überbegriff für verschiedene Größen. +Gemeinsam ist ihnen, daß zur Berechnung eine Lufttemperatur von einem Schwellenwert subtrahiert wird. +Je nach Fragestellung und Pflanzenart werden der Schwellenwert unterschiedlich gewählt und die Temperatur unterschiedlich bestimmt. +Verfügbar sind die Berechnung über 0) "einfachen Durchschnitt der Tagestemperaturen", 1) "modifizierten Durchschnitt der Tagestemperaturen" +und 2) Anzahl der Tage, deren Mitteltempertatur oberhalb der Schwellentemperatur lag. + +siehe https://de.wikipedia.org/wiki/Wachstumsgradtag + +Folgende Parameter sind möglich / notwendig: + +.. code-block:: yaml + + db_addon_params: "year=current, method=1, threshold=10" + +- year: Jahreszahl (str oder int), für das die Berechnung ausgeführt werden soll oder "current" für aktuelles Jahr (default: 'current') +- method: 0-Berechnung über "einfachen Durchschnitt der Tagestemperaturen", 1-Berechnung über "modifizierten Durchschnitt (default: 0) + der Tagestemperaturen" 2-Anzahl der Tage, mit Mitteltempertatur oberhalb Schwellentemperatur// 10, 11 Ausgabe aus Zeitserie +- threshold: Schwellentemperatur in °C (int) (default: 10) + + +Wärmesumme +---------- + +Die Wärmesumme soll eine Aussage über den Sommer und die Pflanzenreife liefern. Es gibt keine eindeutige Definition der Größe "Wärmesumme". +Berechnet wird die Wärmesumme als Summe aller Tagesmitteltemperaturen über einem Schwellenwert ab dem 1.1. des Jahres. + +siehe https://de.wikipedia.org/wiki/W%C3%A4rmesumme + +Folgende Parameter sind möglich / notwendig: + +.. code-block:: yaml + + db_addon_params: "year=current, month=1, threshold=10" + +- year: Jahreszahl (str oder int), für das die Berechnung ausgeführt werden soll oder "current" für aktuelles Jahr (default: 'current') +- month: Monat (int) des Jahres, für das die Berechnung ausgeführt werden soll (optional) (default: None) +- threshold: Schwellentemperatur in °C (int) (default: 10) + + +Kältesumme +---------- + +Die Kältesumme soll eine Aussage über die Härte des Winters liefern. +Berechnet wird die Kältesumme als Summe aller negativen Tagesmitteltemperaturen ab dem 21.9. des Jahres bis 31.3. des Folgejahres. + +siehe https://de.wikipedia.org/wiki/K%C3%A4ltesumme + +Folgende Parameter sind möglich / notwendig: + +.. code-block:: yaml + + db_addon_params: "year=current, month=1" + +- year: Jahreszahl (str oder int), für das die Berechnung ausgeführt werden soll oder "current" für aktuelles Jahr (default: 'current') +- month: Monat (int) des Jahres, für das die Berechnung ausgeführt werden soll (optional) (default: None) + + +Tagesmitteltemperatur +--------------------- + +Die Tagesmitteltemperatur wird auf Basis der stündlichen Durchschnittswerte eines Tages (aller in der DB enthaltenen Datensätze) +für die angegebene Anzahl von Tagen (days=optional) berechnet. + + + +Vorgehen bei Funktionserweiterung des Plugins bzw. Ergänzung weiterer Werte für Item-Attribute +---------------------------------------------------------------------------------------------- + +Augrund der Vielzahl der möglichen Werte der Itemattribute, insbesondere des Itemattributes`db_addon_fct`, wurde die Erstellung/Update +der entsprechenden Teile der `plugin.yam` sowie die Erstellung der Datei `item_attributes.py`, die vom Plugin verwendet wird, automatisiert. + +Die Masterinformationen für alle Itemattributs sowie die Skripte zum Erstellen/Update der beiden Dateien sind in der +Datei `item_attributes_master.py` enthalten. + +.. important:: + + Korrekturen, Erweiterungen etc. der Itemattribute sollten nur in der Datei `item_attributes_master.py` + im Dict der Variable `ITEM_ATTRIBUTS` vorgenommen werden. Das Ausführen der Datei `item_attributes_master.py` (main) + erstellt die `item_attributes.py` und aktualisiert die `plugin.yaml` entsprechend. \ No newline at end of file