From 16cb35545499c95ce70ca6dc5eb3ca70090f9948 Mon Sep 17 00:00:00 2001 From: matosys Date: Mon, 23 Feb 2026 07:33:55 +0100 Subject: [PATCH] feat(contrib/battery): add new ble implementation for balderhub.battery.lib.scenario_features.BatteryLevelReader --- docs/source/contrib.rst | 11 ++++++ docs/source/index.rst | 1 + requirements.txt | 1 + setup.cfg | 4 +++ src/balderhub/ble/contrib/__init__.py | 0 src/balderhub/ble/contrib/battery/__init__.py | 0 .../battery/setup_features/__init__.py | 5 +++ .../setup_features/battery_level_reader.py | 34 +++++++++++++++++++ 8 files changed, 56 insertions(+) create mode 100644 docs/source/contrib.rst create mode 100644 src/balderhub/ble/contrib/__init__.py create mode 100644 src/balderhub/ble/contrib/battery/__init__.py create mode 100644 src/balderhub/ble/contrib/battery/setup_features/__init__.py create mode 100644 src/balderhub/ble/contrib/battery/setup_features/battery_level_reader.py diff --git a/docs/source/contrib.rst b/docs/source/contrib.rst new file mode 100644 index 0000000..7cf428e --- /dev/null +++ b/docs/source/contrib.rst @@ -0,0 +1,11 @@ +Contrib-Packages +**************** + + +This section describes all contrib packages. + +For ``balderhub-battery`` +========================= + +.. autoclass:: balderhub.ble.contrib.battery.setup_features.BatteryLevelReader + :members: diff --git a/docs/source/index.rst b/docs/source/index.rst index 99803c1..c56c4d8 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -20,3 +20,4 @@ out the `official documentation `_ first. features.rst examples.rst utilities.rst + contrib.rst diff --git a/requirements.txt b/requirements.txt index 08acab9..7a0ad46 100644 --- a/requirements.txt +++ b/requirements.txt @@ -7,4 +7,5 @@ pycryptodome>=3.17 pylint==2.17.7 balderhub-unit balderhub-heart +balderhub-battery bleak \ No newline at end of file diff --git a/setup.cfg b/setup.cfg index 254517c..5015296 100644 --- a/setup.cfg +++ b/setup.cfg @@ -29,6 +29,9 @@ project_urls = [options] packages = balderhub.ble + balderhub.ble.contrib + balderhub.ble.contrib.battery + balderhub.ble.contrib.battery.setup_features balderhub.ble.lib balderhub.ble.lib.scenario_features balderhub.ble.lib.scenario_features.gatt @@ -39,6 +42,7 @@ packages = install_requires = baldertest balderhub-heart + balderhub-battery bleak python_requires = >=3.9 package_dir = diff --git a/src/balderhub/ble/contrib/__init__.py b/src/balderhub/ble/contrib/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/balderhub/ble/contrib/battery/__init__.py b/src/balderhub/ble/contrib/battery/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/balderhub/ble/contrib/battery/setup_features/__init__.py b/src/balderhub/ble/contrib/battery/setup_features/__init__.py new file mode 100644 index 0000000..17dc539 --- /dev/null +++ b/src/balderhub/ble/contrib/battery/setup_features/__init__.py @@ -0,0 +1,5 @@ +from .battery_level_reader import BatteryLevelReader + +__all__ = [ + 'BatteryLevelReader' +] diff --git a/src/balderhub/ble/contrib/battery/setup_features/battery_level_reader.py b/src/balderhub/ble/contrib/battery/setup_features/battery_level_reader.py new file mode 100644 index 0000000..4c75571 --- /dev/null +++ b/src/balderhub/ble/contrib/battery/setup_features/battery_level_reader.py @@ -0,0 +1,34 @@ +from typing import Union +import time + +import balder + +import balderhub.ble.lib.scenario_features +import balderhub.ble.lib.scenario_features.gatt +import balderhub.ble.lib.setup_features +import balderhub.battery.lib.scenario_features + + +class BatteryLevelReader(balderhub.battery.lib.scenario_features.BatteryLevelReader): + """Setup Level implementation over BLE for reading the battery level""" + controller = balderhub.ble.lib.setup_features.BleakGattControllerFeature() + + class DUT(balder.VDevice): + """vdevice representing the device under test that implements the ``GattBatteryServiceFeature``""" + config = balderhub.ble.lib.scenario_features.BleDeviceConfig() + gatt = balderhub.ble.lib.scenario_features.gatt.GattBatteryServiceFeature() + + def read_current_battery_level(self) -> Union[float, None]: + + try: + self.controller.connect(self.DUT.config.mac_address) + time.sleep(10) # TODO + return self.controller.read(self.DUT.gatt.BatteryLevel).level_percent / 100 + except ValueError as exc: + # TODO improve + if "unable to connect with device at address" in str(exc): + return None + raise exc + finally: + self.controller.unpair() + #self.controller.disconnect()