From 66ffb00f757c0c790bdd3d9ce378db39bd536ebc Mon Sep 17 00:00:00 2001
From: "th.l" <thl-cmk@outlook.com>
Date: Mon, 8 Jan 2024 09:27:50 +0100
Subject: [PATCH] update project

---
 README.md                                     |   2 +-
 mkp/fritzbox_smarthome-0.8.6-20240106.mkp     | Bin 0 -> 16122 bytes
 .../fritzbox_smarthome_app_lock.py            |  17 +--
 .../fritzbox_smarthome_device_lock.py         |  17 +--
 .../fritzbox_smarthome_power_meter.py         | 131 ++++++++++++++++--
 source/gui/metrics/fritzbox_smarthome.py      |  84 +++++++++--
 .../check_parameters/electrical_energy.py     |  59 +++++---
 source/gui/wato/check_parameters/epower.py    |  36 +++--
 .../fritzbox_smarthome_lock.py                | 111 +++++++++++++++
 .../agent_fritzbox_smarthome.py               |   8 +-
 source/packages/fritzbox_smarthome            |   5 +-
 11 files changed, 381 insertions(+), 89 deletions(-)
 create mode 100644 mkp/fritzbox_smarthome-0.8.6-20240106.mkp
 create mode 100644 source/gui/wato/check_parameters/fritzbox_smarthome_lock.py

diff --git a/README.md b/README.md
index 0b5890b..7da7190 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-[PACKAGE]: ../../raw/master/mkp/fritzbox_smarthome-0.8.5-20240105.mkp "fritzbox_smarthome-0.8.5-20240105.mkp"
+[PACKAGE]: ../../raw/master/mkp/fritzbox_smarthome-0.8.6-20240106.mkp "fritzbox_smarthome-0.8.6-20240106.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.6-20240106.mkp b/mkp/fritzbox_smarthome-0.8.6-20240106.mkp
new file mode 100644
index 0000000000000000000000000000000000000000..4900cea5f4a3f4c7d9afa1c5dd725dd1eab2ca42
GIT binary patch
literal 16122
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

literal 0
HcmV?d00001

diff --git a/source/agent_based/fritzbox_smarthome_app_lock.py b/source/agent_based/fritzbox_smarthome_app_lock.py
index 8582225..401eb56 100644
--- a/source/agent_based/fritzbox_smarthome_app_lock.py
+++ b/source/agent_based/fritzbox_smarthome_app_lock.py
@@ -10,7 +10,7 @@
 #
 #
 
-from typing import Dict
+from typing import Dict, Tuple
 
 from cmk.base.plugins.agent_based.agent_based_api.v1 import (
     Service,
@@ -45,14 +45,15 @@ def check_fritzbox_smarthome_app_lock_single(
     if not isinstance(section, AvmSmartHomeDevice) or section.lock is None:
         return
 
-    def _get_status(status: int):
+    def _get_status(status: int) -> Tuple[str, int]:
         _lock = {
-            0: 'is not deactivated',
-            1: 'is deactivated',
+            0: ('activated',  params.get('lock', {}).get('activated', 0)),
+            1: ('deactivated', params.get('lock', {}).get('deactivated', 0)),
         }
-        return _lock.get(status, f'unknown ({status})')
+        return _lock.get(status, (f'unknown ({status})', 3))
 
-    yield Result(state=State.OK, summary=f'Manual access for phone, app or user interface {_get_status(section.lock)}')
+    state_readable, state = _get_status(section.lock)
+    yield Result(state=State(state), summary=f'Manual access for phone, app or user interface is {state_readable}')
 
 
 def check_fritzbox_smarthome_app_lock_multiple(
@@ -71,7 +72,7 @@ register.check_plugin(
     sections=['fritzbox_smarthome'],
     discovery_function=discovery_fritzbox_smarthome_app_lock_single,
     check_function=check_fritzbox_smarthome_app_lock_single,
-    # check_ruleset_name='fritzbox_smarthome_app_lock',
+    check_ruleset_name='fritzbox_smarthome_app_lock_single',
     check_default_parameters={}
 )
 
@@ -82,6 +83,6 @@ register.check_plugin(
     sections=['fritzbox_smarthome'],
     discovery_function=discovery_fritzbox_smarthome_app_lock_multiple,
     check_function=check_fritzbox_smarthome_app_lock_multiple,
-    # check_ruleset_name='fritzbox_smarthome_app_lock',
+    check_ruleset_name='fritzbox_smarthome_app_lock_multiple',
     check_default_parameters={}
 )
diff --git a/source/agent_based/fritzbox_smarthome_device_lock.py b/source/agent_based/fritzbox_smarthome_device_lock.py
index a6e1bc2..bf0008a 100644
--- a/source/agent_based/fritzbox_smarthome_device_lock.py
+++ b/source/agent_based/fritzbox_smarthome_device_lock.py
@@ -10,7 +10,7 @@
 #
 #
 
-from typing import Dict
+from typing import Dict, Tuple
 
 from cmk.base.plugins.agent_based.agent_based_api.v1 import (
     Service,
@@ -45,14 +45,15 @@ def check_fritzbox_smarthome_device_lock_single(
     if not isinstance(section, AvmSmartHomeDevice) or section.device_lock is None:
         return
 
-    def _get_status(status: int):
+    def _get_status(status: int) -> Tuple[str, int]:
         _dev_lock = {
-            0: 'is not active',
-            1: 'is active',
+            0: ('deactivated', params.get('lock', {}).get('deactivated', 0)),
+            1: ('activated', params.get('lock', {}).get('activated', 0)),
         }
-        return _dev_lock.get(status, f'unknown ({status})')
+        return _dev_lock.get(status, (f'unknown ({status})', 3))
 
-    yield Result(state=State.OK, summary=f'Button lock on the device {_get_status(section.device_lock)}')
+    state_readable, state = _get_status(section.device_lock)
+    yield Result(state=State(state), summary=f'Button lock on the device is {state_readable}')
 
 
 def check_fritzbox_smarthome_device_lock_multiple(
@@ -71,7 +72,7 @@ register.check_plugin(
     sections=['fritzbox_smarthome'],
     discovery_function=discovery_fritzbox_smarthome_device_lock_single,
     check_function=check_fritzbox_smarthome_device_lock_single,
-    # check_ruleset_name='fritzbox_smarthome_device_lock_single',
+    check_ruleset_name='fritzbox_smarthome_device_lock_single',
     check_default_parameters={}
 )
 
@@ -81,6 +82,6 @@ register.check_plugin(
     sections=['fritzbox_smarthome'],
     discovery_function=discovery_fritzbox_smarthome_device_lock_multiple,
     check_function=check_fritzbox_smarthome_device_lock_multiple,
-    # check_ruleset_name='fritzbox_smarthome_device_lock_multiple',
+    check_ruleset_name='fritzbox_smarthome_device_lock_multiple',
     check_default_parameters={}
 )
diff --git a/source/agent_based/fritzbox_smarthome_power_meter.py b/source/agent_based/fritzbox_smarthome_power_meter.py
index 9b0f610..89ee6be 100644
--- a/source/agent_based/fritzbox_smarthome_power_meter.py
+++ b/source/agent_based/fritzbox_smarthome_power_meter.py
@@ -9,18 +9,16 @@
 # File  : fritzbox_smarthome_power_meter.py (check plugin)
 #
 #
-
-from time import time as time_now
+# import time
+from time import localtime, time as time_now
 from typing import Dict
 
 from cmk.base.plugins.agent_based.agent_based_api.v1 import (
-    GetRateError,
     Metric,
     Result,
     Service,
     State,
     check_levels,
-    get_rate,
     get_value_store,
     register,
 )
@@ -175,35 +173,67 @@ def discovery_fritzbox_smarthome_energy_multiple(
                 yield Service(item=str(device_id))
 
 
+def _cost_period_x(
+        value_store: get_value_store,
+        period_name: str,
+        current_period: int,
+        rate_name: str,
+        last_reading: float,
+        precision: int,
+        message: str,
+        cost_kwh: float,
+) -> CheckResult:
+    # reset all
+    # value_store[rate_name] = 0
+
+    if stored_period := value_store.get(period_name):
+        value_store[period_name] = current_period
+
+    if current_period != stored_period:
+        value_store[period_name] = current_period
+        value_store[rate_name] = 0
+        value = last_reading
+    else:
+        value = value_store.get(rate_name, 0) + last_reading
+        value_store[rate_name] = value
+
+    value = round((value / 1000 * cost_kwh), precision)
+
+    yield Result(
+        state=State.OK,
+        notice=message.replace('__value__', f'{value:.4f}')
+    )
+    yield Metric(name=rate_name, value=value)
+
+
 def check_fritzbox_smarthome_energy_single(
         params, section: AvmSmartHomeDevice | Dict[str, AvmSmartHomeDevice]
 ) -> CheckResult:
     if not isinstance(section, AvmSmartHomeDevice):
         return
 
+    energy = None
+    time_span = None
+    value_store = get_value_store()
+
     if section.power_meter and section.power_meter.power is not None:
-        value_store = get_value_store()
         if not (last_timestamp := value_store.get('last_timestamp')):
             value_store['last_timestamp'] = time_now()
         else:
             time_span = time_now() - last_timestamp
             value_store['last_timestamp'] = time_now()
+
             energy = section.power_meter.power / 3600 * time_span
 
             yield from check_levels(
                 value=energy,
                 metric_name='energy_current',
-                label='Consumption current',
-                render_func=lambda x: physical_precision(v=x, precision=3, unit_symbol="Wh"),
+                label='Consumption since last reading',
+                render_func=lambda x: f'{physical_precision(v=x, precision=3, unit_symbol="Wh")} (estimated)',
                 levels_lower=params.get('levels_lower'),
                 levels_upper=params.get('levels_upper'),
             )
-            yield Result(
-                state=State.OK,
-                notice=f'Consumption current is an estimation, '
-                       f'assuming constant power usage of {section.power_meter.power}W '
-                       f'for the last {time_span:.2f} seconds'
-            )
+            yield Metric(name='energy_timespan', value=time_span)
 
     if section.power_meter and section.power_meter.energy is not None:
         yield Result(
@@ -213,6 +243,81 @@ def check_fritzbox_smarthome_energy_single(
         )
         yield Metric(name='energy_total', value=section.power_meter.energy)
 
+        if (cost_kwh := params.get('cost_kwh', None)) is not None:
+            _currency = {
+                'CHF': 'fr',  # swiss franc
+                'CZK': 'Kč',  # Czech koruna
+                'DKK': 'kr.',  # Danish krone
+                'EUR': '€',
+                'GBP': '£',
+                'JPY': 'Â¥',
+                'PLN': 'zł',  # Polish złoty
+                'USD': '$',
+            }
+            cost_kwh, unit_sign = cost_kwh
+            unit_sign = _currency.get(unit_sign, "€")
+
+            cost = section.power_meter.energy / 1000 * cost_kwh
+
+            yield Result(
+                state=State.OK,
+                summary=f'Cost total: {cost:.2f}{unit_sign} ({cost_kwh:.2f}{unit_sign}/kWh)',
+            )
+
+            if energy is not None and time_span is not None:
+                yield Result(state=State.OK, notice=' ')
+                yield Result(state=State.OK, notice='Cost for this:')
+                loca_time = localtime()
+                yield from _cost_period_x(
+                    value_store=value_store,
+                    period_name='current_hour',
+                    current_period=loca_time.tm_hour,
+                    rate_name='cost_per_hour',
+                    last_reading=energy,
+                    precision=6,
+                    message=f'Hour_: __value__{unit_sign}',
+                    cost_kwh=cost_kwh,
+                )
+                yield from _cost_period_x(
+                    value_store=value_store,
+                    period_name='current_day',
+                    current_period=loca_time.tm_mday,
+                    rate_name='cost_per_day',
+                    last_reading=energy,
+                    precision=4,
+                    message=f'Day__: __value__{unit_sign}',
+                    cost_kwh=cost_kwh,
+                )
+                yield from _cost_period_x(
+                    value_store=value_store,
+                    period_name='current_month',
+                    current_period=loca_time.tm_mon,
+                    rate_name='cost_per_month',
+                    last_reading=energy,
+                    precision=4,
+                    message=f'Month: __value__{unit_sign}',
+                    cost_kwh=cost_kwh,
+                )
+                yield from _cost_period_x(
+                    value_store=value_store,
+                    period_name='current_year',
+                    current_period=loca_time.tm_year,
+                    rate_name='cost_per_year',
+                    last_reading=energy,
+                    precision=4,
+                    message=f'Year_: __value__{unit_sign}',
+                    cost_kwh=cost_kwh,
+                )
+                yield Result(state=State.OK, notice=' ')
+
+    if energy:
+        yield Result(
+            state=State.OK,
+            notice=f'All estimates based on the assumption, of a constant '
+                   f'power usage of {section.power_meter.power}W '
+                   f'for the last {time_span:.2f} seconds'
+        )
+
 
 def check_fritzbox_smarthome_energy_multiple(
         item, params, section: AvmSmartHomeDevice | Dict[str, AvmSmartHomeDevice]
diff --git a/source/gui/metrics/fritzbox_smarthome.py b/source/gui/metrics/fritzbox_smarthome.py
index f7cdc27..c3bb610 100644
--- a/source/gui/metrics/fritzbox_smarthome.py
+++ b/source/gui/metrics/fritzbox_smarthome.py
@@ -14,15 +14,25 @@ from cmk.gui.plugins.metrics.utils import (
     graph_info,
     check_metrics,
     perfometer_info,
+    unit_info,
 )
+from cmk.utils.render import fmt_number_with_precision
 
+unit_info["CURRENCY"] = {
+    "title": _("Currency"),
+    "symbol": "¤",  # https://en.wikipedia.org/wiki/Currency_sign_(typography)
+    # "render": lambda v: "%s ¤" % v,
+    # "render": lambda v: f"{v:.4f} ¤",
+    # "js_render": "v => v.toFixed(2) + ' ¤'",
+    "render": lambda v: fmt_number_with_precision(v, precision=4, drop_zeroes=True, unit='¤'),
+    "js_render": "v => cmk.number_format.fmt_number_with_precision(v, cmk.number_format.SIUnitPrefixes, 4, true, '¤')",
+}
 check_metrics["check_mk-fritzbox_smarthome_thermostat_single"] = {
     "temp_current": {"auto_graph": False},
     "temp_target": {"auto_graph": False},
     "temp_economic": {"auto_graph": False},
     "temp_comfort": {"auto_graph": False},
 }
-
 check_metrics["check_mk-fritzbox_smarthome_thermostat_multiple"] = {
     "temp_current": {"auto_graph": False},
     "temp_target": {"auto_graph": False},
@@ -30,17 +40,46 @@ check_metrics["check_mk-fritzbox_smarthome_thermostat_multiple"] = {
     "temp_comfort": {"auto_graph": False},
 }
 
+metric_info["cost_last_reading"] = {
+    "title": _("Cost last"),
+    "color": "11/b",
+    "unit": "CURRENCY",
+}
+metric_info["cost_per_hour"] = {
+    "title": _("Cost this hour"),
+    "color": "13/a",
+    "unit": "CURRENCY",
+}
+metric_info["cost_per_day"] = {
+    "title": _("Cost this day"),
+    "color": "23/a",
+    "unit": "CURRENCY",
+}
+metric_info["cost_per_month"] = {
+    "title": _("Cost this month"),
+    "color": "33/a",
+    "unit": "CURRENCY",
+}
+metric_info["cost_per_year"] = {
+    "title": _("Cost this year"),
+    "color": "43/a",
+    "unit": "CURRENCY",
+}
 metric_info["energy_total"] = {
     "title": _("Energy total"),
     "color": "31/b",
     "unit": "wh",
 }
-
 metric_info["energy_current"] = {
-    "title": _("Energy current"),
+    "title": _("Energy since last"),
     "color": "16/b",
     "unit": "wh",
 }
+metric_info["energy_timespan"] = {
+    "title": _("Time between readings"),
+    "color": "36/b",
+    "unit": "s",
+}
 
 metric_info["temp_current"] = {
     "title": _("Temperature current"),
@@ -64,12 +103,35 @@ metric_info["temp_comfort"] = {
 }
 
 graph_info["fritzbox_smart_home_energy_surrent"] = {
-    "title": "Electrical energy consumption current",
+    "title": "Electrical energy consumption since last reading",
     "metrics": [
         ("energy_current", "area")
     ]
 }
 
+graph_info["fritzbox_smart_home_energy_time_span"] = {
+    "title": "Electrical energy time between readings",
+    "metrics": [
+        ("energy_timespan", "area")
+    ]
+}
+
+graph_info["fritzbox_smart_home_energy_cost"] = {
+    "title": "Electrical energy cost",
+    "metrics": [
+        ("cost_per_year", "area"),
+        ("cost_per_month", "area"),
+        ("cost_per_day", "area"),
+        ("cost_per_hour", "area"),
+    ],
+    "optional_metrics": [
+        "cost_per_hour",
+        "cost_per_day",
+        "cost_per_month",
+        "cost_per_year",
+    ],
+}
+
 graph_info["fritzbox_smart_home_energy_total"] = {
     "title": "Electrical energy consumption total",
     "metrics": [
@@ -105,11 +167,9 @@ perfometer_info.append(('stacked', [
     }
 ]))
 
-perfometer_info.append(
-    {
-        "type": "logarithmic",
-        "metric": "energy_current",
-        "half_value": 100,
-        "exponent": 3,
-    }
-)
\ No newline at end of file
+perfometer_info.append({
+    "type": "logarithmic",
+    "metric": "energy_current",
+    "half_value": 100,
+    "exponent": 3,
+})
diff --git a/source/gui/wato/check_parameters/electrical_energy.py b/source/gui/wato/check_parameters/electrical_energy.py
index 2574985..a0296ab 100644
--- a/source/gui/wato/check_parameters/electrical_energy.py
+++ b/source/gui/wato/check_parameters/electrical_energy.py
@@ -15,7 +15,7 @@ from cmk.gui.plugins.wato.utils import (
     rulespec_registry,
     RulespecGroupCheckParametersEnvironment,
 )
-from cmk.gui.valuespec import Dictionary, Integer, TextInput, Tuple
+from cmk.gui.valuespec import Dictionary, DropdownChoice, Float,  Integer, TextInput, Tuple
 
 
 def _item_spec_energy():
@@ -28,26 +28,43 @@ def _parameter_valuespec_energy():
     return Dictionary(
         title=_('Parameters'),
         elements=[
-            (
-                "levels_upper",
-                Tuple(
-                    title=_("Upper levels for electrical energy"),
-                    elements=[
-                        Integer(title=_("warning at"), unit="Wh"),
-                        Integer(title=_("critical at"), unit="Wh"),
-                    ],
-                ),
-            ),
-            (
-                "levels_lower",
-                Tuple(
-                    title=_("Lower levels for electrical energy"),
-                    elements=[
-                        Integer(title=_("warning if below"), unit="Wh"),
-                        Integer(title=_("critical if below"), unit="Wh"),
-                    ],
-                ),
-            ),
+            ("levels_upper",
+             Tuple(
+                 title=_("Upper levels for electrical energy"),
+                 elements=[
+                     Integer(title=_("warning at"), unit="Wh"),
+                     Integer(title=_("critical at"), unit="Wh"),
+                 ],
+             )),
+            ("levels_lower",
+             Tuple(
+                 title=_("Lower levels for electrical energy"),
+                 elements=[
+                     Integer(title=_("warning if below"), unit="Wh"),
+                     Integer(title=_("critical if below"), unit="Wh"),
+                 ],
+             )),
+            ("cost_kwh",
+             Tuple(
+                 title=_("Cost per kWh"),
+                 orientation='horizontal',
+                 elements=[
+                     Float(title=_("Cost"), default_value=0.3),
+                     DropdownChoice(
+                         title=_("Currency"),
+                         default_value='EUR',
+                         choices=[
+                             ('CHF', 'fr (franc suisse)'),
+                             ('CZK', 'Kč (koruna česká)'),
+                             ('DKK', 'kr. (dansk krone)'),
+                             ('EUR', '€ (Euro)'),
+                             ('GBP', '£ (Pound)'),
+                             ('JPY', 'Â¥ (Yen)'),
+                             ('PLN', 'zł (Polski złoty)'),
+                             ('USD', '$ (Dollar)'),
+                         ]),
+                 ],
+             )),
         ],
         help=_(
             "Levels for the electrical energy consumption of a device "
diff --git a/source/gui/wato/check_parameters/epower.py b/source/gui/wato/check_parameters/epower.py
index 74696b9..a039b09 100644
--- a/source/gui/wato/check_parameters/epower.py
+++ b/source/gui/wato/check_parameters/epower.py
@@ -30,26 +30,22 @@ def _parameter_valuespec_epower():
         Dictionary(
             title=_("Parameters"),
             elements=[
-                (
-                    "levels_lower",
-                    Tuple(
-                        title=_("Lower levels for electrical power"),
-                        elements=[
-                            Integer(title=_("warning if below"), unit="Watt"),
-                            Integer(title=_("critical if below"), unit="Watt"),
-                        ],
-                    ),
-                ),
-                (
-                    "levels_upper",
-                    Tuple(
-                        title=_("Upper levels for electrical power"),
-                        elements=[
-                            Integer(title=_("warning at"), unit="Watt"),
-                            Integer(title=_("critical at"), unit="Watt"),
-                        ],
-                    ),
-                ),
+                ("levels_lower",
+                 Tuple(
+                     title=_("Lower levels for electrical power"),
+                     elements=[
+                         Integer(title=_("warning if below"), unit="Watt"),
+                         Integer(title=_("critical if below"), unit="Watt"),
+                     ],
+                 )),
+                ("levels_upper",
+                 Tuple(
+                     title=_("Upper levels for electrical power"),
+                     elements=[
+                         Integer(title=_("warning at"), unit="Watt"),
+                         Integer(title=_("critical at"), unit="Watt"),
+                     ],
+                 )),
             ],
             help=_(
                 "Levels for the electrical power consumption of a device "
diff --git a/source/gui/wato/check_parameters/fritzbox_smarthome_lock.py b/source/gui/wato/check_parameters/fritzbox_smarthome_lock.py
new file mode 100644
index 0000000..e1cc10f
--- /dev/null
+++ b/source/gui/wato/check_parameters/fritzbox_smarthome_lock.py
@@ -0,0 +1,111 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+#
+# License: GNU General Public License v2
+#
+# Author: thl-cmk[at]outlook[dot]com
+# URL   : https://thl-cmk.hopto.org
+# Date  : 2023-12-28
+# File  : fritzbox_smarthome_lock.py (WATO check plugin)
+#
+
+
+from cmk.gui.i18n import _
+from cmk.gui.valuespec import (
+    Dictionary,
+    MonitoringState,
+    TextInput,
+    Alternative,
+)
+from cmk.gui.plugins.wato.utils import (
+    CheckParameterRulespecWithItem,
+    CheckParameterRulespecWithoutItem,
+    RulespecGroupCheckParametersApplications,
+    rulespec_registry,
+)
+
+
+def _parameter_valuespec_fritzbox_smarthome_lock(message: str):
+    return Dictionary(
+        title=_('Parameter'),
+        elements=[
+            ('lock',
+             Alternative(
+                 title=_(message),
+                 elements=[
+                     Dictionary(
+                         title=_('Activated'),
+                         optional_keys=False,
+                         elements=[
+                             ('activated',
+                              MonitoringState(
+                                  title=_('Monitoring state'),
+                                  default_value=0,
+                              )),
+                         ]),
+                     Dictionary(
+                         title=_('Deactivated'),
+                         optional_keys=False,
+                         elements=[
+                             ('deactivated',
+                              MonitoringState(
+                                  title=_('Monitoring state'),
+                                  default_value=0,
+                              ))
+                         ]),
+                 ]
+             )),
+        ],
+    )
+
+
+def _parameter_valuespec_fritzbox_smarthome_app_lock():
+    return _parameter_valuespec_fritzbox_smarthome_lock(message='Manual access for phone, app or user interface')
+
+
+rulespec_registry.register(
+    CheckParameterRulespecWithoutItem(
+        check_group_name="fritzbox_smarthome_app_lock_single",
+        group=RulespecGroupCheckParametersApplications,
+        match_type="dict",
+        parameter_valuespec=_parameter_valuespec_fritzbox_smarthome_app_lock,
+        title=lambda: _('Fritz!Box Smarthome App Lock')
+    )
+)
+
+rulespec_registry.register(
+    CheckParameterRulespecWithItem(
+        check_group_name="fritzbox_smarthome_app_lock_multiple",
+        group=RulespecGroupCheckParametersApplications,
+        match_type="dict",
+        parameter_valuespec=_parameter_valuespec_fritzbox_smarthome_app_lock,
+        title=lambda: _('Fritz!Box Smarthome App Look (with Device-ID)'),
+        item_spec=lambda: TextInput(title=_('Device-ID')),
+    )
+)
+
+
+def _parameter_valuespec_fritzbox_smarthome_device_lock():
+    return _parameter_valuespec_fritzbox_smarthome_lock(message='Button lock on the device')
+
+
+rulespec_registry.register(
+    CheckParameterRulespecWithoutItem(
+        check_group_name="fritzbox_smarthome_device_lock_single",
+        group=RulespecGroupCheckParametersApplications,
+        match_type="dict",
+        parameter_valuespec=_parameter_valuespec_fritzbox_smarthome_device_lock,
+        title=lambda: _('Fritz!Box Smarthome Device Lock')
+    )
+)
+
+rulespec_registry.register(
+    CheckParameterRulespecWithItem(
+        check_group_name="fritzbox_smarthome_device_lock_multiple",
+        group=RulespecGroupCheckParametersApplications,
+        match_type="dict",
+        parameter_valuespec=_parameter_valuespec_fritzbox_smarthome_device_lock,
+        title=lambda: _('Fritz!Box Smarthome Device Lock (with Device-ID)'),
+        item_spec=lambda: TextInput(title=_('Device-ID')),
+    )
+)
diff --git a/source/lib/python3/cmk/special_agents/agent_fritzbox_smarthome.py b/source/lib/python3/cmk/special_agents/agent_fritzbox_smarthome.py
index b669650..4608565 100644
--- a/source/lib/python3/cmk/special_agents/agent_fritzbox_smarthome.py
+++ b/source/lib/python3/cmk/special_agents/agent_fritzbox_smarthome.py
@@ -245,10 +245,10 @@ def check_fritzbox_smarthome(args):
         energy_up = int(time.time() - start_time) / 3600 * (int(power) / 1000)
         __switch_01["powermeter"]["energy"] = str(int(energy + energy_up))
 
-        devices.append(__switch_01)
-        devices.append(__repeater_01)
-        devices.append(__repeater_02)
-        devices.append(__thermostat_01)
+        # devices.append(__switch_01)
+        # devices.append(__repeater_01)
+        # devices.append(__repeater_02)
+        # devices.append(__thermostat_01)
 
     for xml_device in xml_devicelist.findall('device'):
         devices.append(parse_xml_to_json(xml_device))
diff --git a/source/packages/fritzbox_smarthome b/source/packages/fritzbox_smarthome
index 4d2081e..45968ae 100644
--- a/source/packages/fritzbox_smarthome
+++ b/source/packages/fritzbox_smarthome
@@ -43,13 +43,14 @@
                    'wato/check_parameters/fritzbox_smarthome.py',
                    'metrics/fritzbox_smarthome.py',
                    'wato/check_parameters/temperature_single.py',
-                   'wato/check_parameters/voltage_single.py'],
+                   'wato/check_parameters/voltage_single.py',
+                   'wato/check_parameters/fritzbox_smarthome_lock.py'],
            'lib': ['python3/cmk/special_agents/agent_fritzbox_smarthome.py'],
            'web': ['plugins/wato/agent_fritzbox_smarthome.py',
                    'plugins/views/fritzbox_smarthome.py']},
  'name': 'fritzbox_smarthome',
  'title': 'Fritz!Box SmartHome',
- 'version': '0.8.5-20240105',
+ 'version': '0.8.6-20240106',
  'version.min_required': '2.2.0b1',
  'version.packaged': '2.2.0p17',
  'version.usable_until': None}
-- 
GitLab