diff --git a/README.md b/README.md index da24f00cc0181abde19a6a3ea96eb6520936bba8..c4ca544eb96ffc569ef41e36a3d9a5b3659f5c08 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -[PACKAGE]: ../../raw/master/mkp/fritzbox_smarthome-0.8.7-20240108.mkp "fritzbox_smarthome-0.8.7-20240108.mkp" +[PACKAGE]: ../../raw/master/mkp/fritzbox_smarthome-0.8.8-20240109.mkp "fritzbox_smarthome-0.8.8-20240109.mkp" # AVM Fritz!Box Smarthome This repository contains a additional check_MK Fritz!Box Agent which can gather informations over the AVM AHA HTTP Interface about SmartHome Devices connected to an Fritz!Box. diff --git a/mkp/fritzbox_smarthome-0.8.8-20240109.mkp b/mkp/fritzbox_smarthome-0.8.8-20240109.mkp new file mode 100644 index 0000000000000000000000000000000000000000..55f50e4a6086bd6befc34d4543250fdd1f40da67 Binary files /dev/null and b/mkp/fritzbox_smarthome-0.8.8-20240109.mkp differ diff --git a/source/agent_based/fritzbox_smarthome_power_meter.py b/source/agent_based/fritzbox_smarthome_power_meter.py index a337af5f6325e628e439f6aaa774d3b808f35668..b7107eaf6e1352d2b999d5ceb8c768ecc6206943 100644 --- a/source/agent_based/fritzbox_smarthome_power_meter.py +++ b/source/agent_based/fritzbox_smarthome_power_meter.py @@ -12,20 +12,74 @@ # import time from time import localtime, time as time_now from typing import Dict +from os import environ +from pathlib import Path +from json import loads, dumps +from cmk.checkers import plugin_contexts from cmk.base.plugins.agent_based.agent_based_api.v1 import ( Metric, Result, Service, State, check_levels, - get_value_store, register, ) from cmk.base.plugins.agent_based.agent_based_api.v1.type_defs import CheckResult, DiscoveryResult from cmk.utils.render import physical_precision from cmk.base.plugins.agent_based.utils.fritzbox_smarthome import AvmSmartHomeDevice +OMD_ROOT = environ["OMD_ROOT"] + + +class FritzBoxValueStore: + """ + Persistent kind of value_store. Located under ~/var/fritzbox_smarthome/{hostname}_{service_description} + """ + def __init__(self): + self._host_name = plugin_contexts.host_name() + self._service_description = plugin_contexts.service_description().replace(' ', '_') + self._file = Path(f'{OMD_ROOT}/var/firtzbox_smarthome/{self._host_name}_{self._service_description}') + self._counters = {} + if self._file.exists(): + self._counters = loads(self._file.read_text()) + else: + self._counters = {} + + def get(self, key: str, default_value: int | str | float | bool | None = None): + """ + Get a value from the value store + Args: + key: the key in the value store + default_value: the default value to return if key not found + + Returns: + The value for key from the value store. If key not exists the default_value or None + """ + return self._counters.get(key, default_value) + + def set(self, key: str, value: str | int | float | None) -> None: + """ + Set a value in the value stare. Use "None" as value to remove a key. + Args: + key: the key in the value store + value: the value to set + """ + if value is None: + try: + self._counters.pop(key) + except KeyError: + pass + else: + self._counters[key] = value + + def save(self) -> None: + """ + Save the value_store as json to file + """ + self._file.parent.mkdir(exist_ok=True, parents=True) + self._file.write_text(dumps(self._counters)) + def discovery_fritzbox_smarthome_voltage_single( section: AvmSmartHomeDevice | Dict[str, AvmSmartHomeDevice] @@ -174,7 +228,7 @@ def discovery_fritzbox_smarthome_energy_multiple( def _cost_period_x( - value_store: get_value_store, + value_store: FritzBoxValueStore, period_name: str, current_period: int, rate_name: str, @@ -187,17 +241,17 @@ def _cost_period_x( # reset all # value_store[rate_name] = 0 - if stored_period := value_store.get(period_name): - value_store[period_name] = current_period + if stored_period := value_store.get(key=period_name): + value_store.set(key=period_name, value=current_period) cost = last_reading / 1000 * cost_kwh if current_period != stored_period: - value_store[period_name] = current_period - value_store[rate_name] = cost + value_store.set(key=period_name, value=current_period) + value_store.set(key=rate_name, value=cost) else: - cost = value_store.get(rate_name, 0) + cost - value_store[rate_name] = cost + cost = value_store.get(key=rate_name, default_value=0) + cost + value_store.set(key=rate_name, value=cost) cost = round(cost, precision) @@ -216,14 +270,14 @@ def check_fritzbox_smarthome_energy_single( energy = None time_span = None - value_store = get_value_store() + value_store = FritzBoxValueStore() if section.power_meter and section.power_meter.power is not None: if not (last_timestamp := value_store.get('last_timestamp')): - value_store['last_timestamp'] = time_now() + value_store.set(key='last_timestamp', value=time_now()) else: time_span = time_now() - last_timestamp - value_store['last_timestamp'] = time_now() + value_store.set(key='last_timestamp', value=time_now()) energy = section.power_meter.power / 3600 * time_span @@ -316,6 +370,8 @@ def check_fritzbox_smarthome_energy_single( ) yield Result(state=State.OK, notice=' ') + value_store.save() + if energy: yield Result( state=State.OK, diff --git a/source/packages/fritzbox_smarthome b/source/packages/fritzbox_smarthome index e5b06686c4dc2a3474f913e93d38ea7bf06f4cc9..bd5b1eb53f5e16b95ca07d28d4a3108d1dce4f48 100644 --- a/source/packages/fritzbox_smarthome +++ b/source/packages/fritzbox_smarthome @@ -50,7 +50,7 @@ 'plugins/views/fritzbox_smarthome.py']}, 'name': 'fritzbox_smarthome', 'title': 'Fritz!Box SmartHome', - 'version': '0.8.7-20240108', + 'version': '0.8.8-20240109', 'version.min_required': '2.2.0b1', 'version.packaged': '2.2.0p17', 'version.usable_until': None}