aiobmsble 0.2.1__tar.gz → 0.2.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {aiobmsble-0.2.1/aiobmsble.egg-info → aiobmsble-0.2.2}/PKG-INFO +1 -1
- {aiobmsble-0.2.1 → aiobmsble-0.2.2}/aiobmsble/__init__.py +5 -1
- {aiobmsble-0.2.1 → aiobmsble-0.2.2}/aiobmsble/__main__.py +5 -1
- {aiobmsble-0.2.1 → aiobmsble-0.2.2}/aiobmsble/basebms.py +10 -1
- aiobmsble-0.2.2/aiobmsble/bms/__init__.py +5 -0
- {aiobmsble-0.2.1 → aiobmsble-0.2.2}/aiobmsble/bms/abc_bms.py +5 -1
- {aiobmsble-0.2.1 → aiobmsble-0.2.2}/aiobmsble/bms/ant_bms.py +5 -1
- {aiobmsble-0.2.1 → aiobmsble-0.2.2}/aiobmsble/bms/braunpwr_bms.py +5 -1
- {aiobmsble-0.2.1 → aiobmsble-0.2.2}/aiobmsble/bms/cbtpwr_bms.py +5 -1
- {aiobmsble-0.2.1 → aiobmsble-0.2.2}/aiobmsble/bms/cbtpwr_vb_bms.py +5 -1
- {aiobmsble-0.2.1 → aiobmsble-0.2.2}/aiobmsble/bms/daly_bms.py +5 -1
- {aiobmsble-0.2.1 → aiobmsble-0.2.2}/aiobmsble/bms/dpwrcore_bms.py +5 -1
- {aiobmsble-0.2.1 → aiobmsble-0.2.2}/aiobmsble/bms/dummy_bms.py +5 -1
- {aiobmsble-0.2.1 → aiobmsble-0.2.2}/aiobmsble/bms/ecoworthy_bms.py +5 -1
- {aiobmsble-0.2.1 → aiobmsble-0.2.2}/aiobmsble/bms/ective_bms.py +5 -1
- {aiobmsble-0.2.1 → aiobmsble-0.2.2}/aiobmsble/bms/ej_bms.py +5 -1
- {aiobmsble-0.2.1 → aiobmsble-0.2.2}/aiobmsble/bms/felicity_bms.py +5 -1
- {aiobmsble-0.2.1 → aiobmsble-0.2.2}/aiobmsble/bms/jbd_bms.py +5 -1
- {aiobmsble-0.2.1 → aiobmsble-0.2.2}/aiobmsble/bms/jikong_bms.py +5 -1
- {aiobmsble-0.2.1 → aiobmsble-0.2.2}/aiobmsble/bms/neey_bms.py +5 -1
- {aiobmsble-0.2.1 → aiobmsble-0.2.2}/aiobmsble/bms/ogt_bms.py +5 -1
- {aiobmsble-0.2.1 → aiobmsble-0.2.2}/aiobmsble/bms/pro_bms.py +5 -1
- {aiobmsble-0.2.1 → aiobmsble-0.2.2}/aiobmsble/bms/redodo_bms.py +5 -1
- {aiobmsble-0.2.1 → aiobmsble-0.2.2}/aiobmsble/bms/renogy_bms.py +4 -1
- {aiobmsble-0.2.1 → aiobmsble-0.2.2}/aiobmsble/bms/renogy_pro_bms.py +5 -1
- {aiobmsble-0.2.1 → aiobmsble-0.2.2}/aiobmsble/bms/roypow_bms.py +5 -1
- {aiobmsble-0.2.1 → aiobmsble-0.2.2}/aiobmsble/bms/seplos_bms.py +5 -1
- {aiobmsble-0.2.1 → aiobmsble-0.2.2}/aiobmsble/bms/seplos_v2_bms.py +5 -1
- {aiobmsble-0.2.1 → aiobmsble-0.2.2}/aiobmsble/bms/tdt_bms.py +5 -1
- {aiobmsble-0.2.1 → aiobmsble-0.2.2}/aiobmsble/bms/tianpwr_bms.py +5 -1
- {aiobmsble-0.2.1 → aiobmsble-0.2.2}/aiobmsble/utils.py +15 -5
- {aiobmsble-0.2.1 → aiobmsble-0.2.2/aiobmsble.egg-info}/PKG-INFO +1 -1
- {aiobmsble-0.2.1 → aiobmsble-0.2.2}/pyproject.toml +1 -1
- {aiobmsble-0.2.1 → aiobmsble-0.2.2}/tests/test_basebms.py +7 -0
- {aiobmsble-0.2.1 → aiobmsble-0.2.2}/tests/test_utils.py +4 -5
- aiobmsble-0.2.1/aiobmsble/bms/__init__.py +0 -1
- {aiobmsble-0.2.1 → aiobmsble-0.2.2}/LICENSE +0 -0
- {aiobmsble-0.2.1 → aiobmsble-0.2.2}/MANIFEST.in +0 -0
- {aiobmsble-0.2.1 → aiobmsble-0.2.2}/README.md +0 -0
- {aiobmsble-0.2.1 → aiobmsble-0.2.2}/aiobmsble.egg-info/SOURCES.txt +0 -0
- {aiobmsble-0.2.1 → aiobmsble-0.2.2}/aiobmsble.egg-info/dependency_links.txt +0 -0
- {aiobmsble-0.2.1 → aiobmsble-0.2.2}/aiobmsble.egg-info/entry_points.txt +0 -0
- {aiobmsble-0.2.1 → aiobmsble-0.2.2}/aiobmsble.egg-info/requires.txt +0 -0
- {aiobmsble-0.2.1 → aiobmsble-0.2.2}/aiobmsble.egg-info/top_level.txt +0 -0
- {aiobmsble-0.2.1 → aiobmsble-0.2.2}/setup.cfg +0 -0
- {aiobmsble-0.2.1 → aiobmsble-0.2.2}/tests/test_examples.py +0 -0
- {aiobmsble-0.2.1 → aiobmsble-0.2.2}/tests/test_fuzzing.py +0 -0
- {aiobmsble-0.2.1 → aiobmsble-0.2.2}/tests/test_main.py +0 -0
- {aiobmsble-0.2.1 → aiobmsble-0.2.2}/tests/test_plugins.py +0 -0
@@ -1,4 +1,8 @@
|
|
1
|
-
"""Package for battery management systems (BMS) via Bluetooth LE.
|
1
|
+
"""Package for battery management systems (BMS) via Bluetooth LE (aiobmsble).
|
2
|
+
|
3
|
+
Project: aiobmsble, https://pypi.org/p/aiobmsble/
|
4
|
+
License: Apache-2.0, http://www.apache.org/licenses/
|
5
|
+
"""
|
2
6
|
|
3
7
|
from collections.abc import Callable
|
4
8
|
from enum import IntEnum
|
@@ -1,4 +1,8 @@
|
|
1
|
-
"""Base class defintion for battery management systems (BMS).
|
1
|
+
"""Base class defintion for battery management systems (BMS).
|
2
|
+
|
3
|
+
Project: aiobmsble, https://pypi.org/p/aiobmsble/
|
4
|
+
License: Apache-2.0, http://www.apache.org/licenses/
|
5
|
+
"""
|
2
6
|
|
3
7
|
from abc import ABC, abstractmethod
|
4
8
|
import asyncio
|
@@ -79,6 +83,11 @@ class BaseBMS(ABC):
|
|
79
83
|
self._data: bytearray = bytearray()
|
80
84
|
self._data_event: Final[asyncio.Event] = asyncio.Event()
|
81
85
|
|
86
|
+
@classmethod
|
87
|
+
def get_bms_module(cls) -> str:
|
88
|
+
"""Return BMS module name, e.g. aiobmsble.bms.dummy_bms."""
|
89
|
+
return cls.__module__
|
90
|
+
|
82
91
|
@staticmethod
|
83
92
|
@abstractmethod
|
84
93
|
def matcher_dict_list() -> list[MatcherPattern]:
|
@@ -1,4 +1,8 @@
|
|
1
|
-
"""Module to support CBT Power VB series BMS.
|
1
|
+
"""Module to support CBT Power VB series BMS.
|
2
|
+
|
3
|
+
Project: aiobmsble, https://pypi.org/p/aiobmsble/
|
4
|
+
License: Apache-2.0, http://www.apache.org/licenses/
|
5
|
+
"""
|
2
6
|
|
3
7
|
from string import hexdigits
|
4
8
|
from typing import Final
|
@@ -1,4 +1,8 @@
|
|
1
|
-
"""Module to support D-powercore Smart BMS.
|
1
|
+
"""Module to support D-powercore Smart BMS.
|
2
|
+
|
3
|
+
Project: aiobmsble, https://pypi.org/p/aiobmsble/
|
4
|
+
License: Apache-2.0, http://www.apache.org/licenses/
|
5
|
+
"""
|
2
6
|
|
3
7
|
from enum import IntEnum
|
4
8
|
from string import hexdigits
|
@@ -1,4 +1,8 @@
|
|
1
|
-
"""Module to support Dummy BMS.
|
1
|
+
"""Module to support Dummy BMS.
|
2
|
+
|
3
|
+
Project: aiobmsble, https://pypi.org/p/aiobmsble/
|
4
|
+
License: Apache-2.0, http://www.apache.org/licenses/
|
5
|
+
"""
|
2
6
|
|
3
7
|
from bleak.backends.characteristic import BleakGATTCharacteristic
|
4
8
|
from bleak.backends.device import BLEDevice
|
@@ -1,4 +1,8 @@
|
|
1
|
-
"""Module to support Felicity BMS.
|
1
|
+
"""Module to support Felicity BMS.
|
2
|
+
|
3
|
+
Project: aiobmsble, https://pypi.org/p/aiobmsble/
|
4
|
+
License: Apache-2.0, http://www.apache.org/licenses/
|
5
|
+
"""
|
2
6
|
|
3
7
|
from collections.abc import Callable
|
4
8
|
from json import JSONDecodeError, loads
|
@@ -1,4 +1,8 @@
|
|
1
|
-
"""Module to support Neey Smart BMS.
|
1
|
+
"""Module to support Neey Smart BMS.
|
2
|
+
|
3
|
+
Project: aiobmsble, https://pypi.org/p/aiobmsble/
|
4
|
+
License: Apache-2.0, http://www.apache.org/licenses/
|
5
|
+
"""
|
2
6
|
|
3
7
|
from collections.abc import Callable
|
4
8
|
from struct import unpack_from
|
@@ -1,4 +1,8 @@
|
|
1
|
-
"""Module to support Offgridtec Smart Pro BMS.
|
1
|
+
"""Module to support Offgridtec Smart Pro BMS.
|
2
|
+
|
3
|
+
Project: aiobmsble, https://pypi.org/p/aiobmsble/
|
4
|
+
License: Apache-2.0, http://www.apache.org/licenses/
|
5
|
+
"""
|
2
6
|
|
3
7
|
from collections.abc import Callable
|
4
8
|
from string import digits, hexdigits
|
@@ -1,4 +1,8 @@
|
|
1
|
-
"""Module to support Renogy Pro BMS.
|
1
|
+
"""Module to support Renogy Pro BMS.
|
2
|
+
|
3
|
+
Project: aiobmsble, https://pypi.org/p/aiobmsble/
|
4
|
+
License: Apache-2.0, http://www.apache.org/licenses/
|
5
|
+
"""
|
2
6
|
|
3
7
|
from bleak.backends.characteristic import BleakGATTCharacteristic
|
4
8
|
from bleak.backends.device import BLEDevice
|
@@ -1,4 +1,8 @@
|
|
1
|
-
"""Module to support Seplos V3 Smart BMS.
|
1
|
+
"""Module to support Seplos V3 Smart BMS.
|
2
|
+
|
3
|
+
Project: aiobmsble, https://pypi.org/p/aiobmsble/
|
4
|
+
License: Apache-2.0, http://www.apache.org/licenses/
|
5
|
+
"""
|
2
6
|
|
3
7
|
from collections.abc import Callable
|
4
8
|
from typing import Any, Final
|
@@ -1,4 +1,8 @@
|
|
1
|
-
"""Utilitiy/Support functions for aiobmsble.
|
1
|
+
"""Utilitiy/Support functions for aiobmsble.
|
2
|
+
|
3
|
+
Project: aiobmsble, https://pypi.org/p/aiobmsble/
|
4
|
+
License: Apache-2.0, http://www.apache.org/licenses/
|
5
|
+
"""
|
2
6
|
|
3
7
|
from fnmatch import translate
|
4
8
|
from functools import lru_cache
|
@@ -6,11 +10,15 @@ import importlib
|
|
6
10
|
import pkgutil
|
7
11
|
import re
|
8
12
|
from types import ModuleType
|
13
|
+
from typing import Final
|
9
14
|
|
10
15
|
from bleak.backends.scanner import AdvertisementData
|
11
16
|
|
12
17
|
from aiobmsble import MatcherPattern
|
13
18
|
from aiobmsble.basebms import BaseBMS
|
19
|
+
import aiobmsble.bms
|
20
|
+
|
21
|
+
_MODULE_POSTFIX: Final[str] = "_bms"
|
14
22
|
|
15
23
|
|
16
24
|
def _advertisement_matches(
|
@@ -78,8 +86,8 @@ def load_bms_plugins() -> set[ModuleType]:
|
|
78
86
|
"""
|
79
87
|
return {
|
80
88
|
importlib.import_module(f"aiobmsble.bms.{module_name}")
|
81
|
-
for _, module_name, _ in pkgutil.iter_modules(
|
82
|
-
if module_name.endswith(
|
89
|
+
for _, module_name, _ in pkgutil.iter_modules(aiobmsble.bms.__path__)
|
90
|
+
if module_name.endswith(_MODULE_POSTFIX)
|
83
91
|
}
|
84
92
|
|
85
93
|
|
@@ -87,14 +95,16 @@ def bms_cls(name: str) -> type[BaseBMS] | None:
|
|
87
95
|
"""Return the BMS class that is defined by the name argument.
|
88
96
|
|
89
97
|
Args:
|
90
|
-
name (str): The name of the BMS type
|
98
|
+
name (str): The name of the BMS type (filename of the module)
|
91
99
|
|
92
100
|
Returns:
|
93
101
|
type[BaseBMS] | None: If the BMS class defined by name is found, None otherwise.
|
94
102
|
|
95
103
|
"""
|
104
|
+
if not name.endswith(_MODULE_POSTFIX):
|
105
|
+
return None
|
96
106
|
try:
|
97
|
-
bms_module: ModuleType = importlib.import_module(f"aiobmsble.bms.{name}
|
107
|
+
bms_module: ModuleType = importlib.import_module(f"aiobmsble.bms.{name}")
|
98
108
|
except ModuleNotFoundError:
|
99
109
|
return None
|
100
110
|
return bms_module.BMS
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
4
4
|
|
5
5
|
[project]
|
6
6
|
name = "aiobmsble"
|
7
|
-
version = "0.2.
|
7
|
+
version = "0.2.2"
|
8
8
|
requires-python = ">=3.12"
|
9
9
|
description = "Asynchronous Python library to query battery management systems via Bluetooth Low Energy."
|
10
10
|
readme = "README.md"
|
@@ -14,6 +14,7 @@ import pytest
|
|
14
14
|
|
15
15
|
from aiobmsble import BMSdp, BMSsample, MatcherPattern
|
16
16
|
from aiobmsble.basebms import BaseBMS, crc8, crc_modbus, crc_sum, crc_xmodem, lrc_modbus
|
17
|
+
from aiobmsble.bms.dummy_bms import BMS as DummyBMS
|
17
18
|
|
18
19
|
from .bluetooth import generate_ble_device
|
19
20
|
from .conftest import MockBleakClient
|
@@ -315,6 +316,12 @@ async def test_wr_mode_reset(
|
|
315
316
|
assert bms._inv_wr_mode is None
|
316
317
|
|
317
318
|
|
319
|
+
def test_get_bms_module() -> None:
|
320
|
+
"""Check that basebms and dummy_bms return correct module name."""
|
321
|
+
assert BaseBMS.get_bms_module() == "aiobmsble.basebms"
|
322
|
+
assert DummyBMS.get_bms_module() == "aiobmsble.bms.dummy_bms"
|
323
|
+
|
324
|
+
|
318
325
|
async def test_no_notify(
|
319
326
|
patch_bleak_client: Callable[..., None], caplog: pytest.LogCaptureFixture
|
320
327
|
) -> None:
|
@@ -55,15 +55,14 @@ def test_bms_identify(plugin: ModuleType) -> None:
|
|
55
55
|
def test_bms_cls(plugin: ModuleType) -> None:
|
56
56
|
"""Test that a BMS class is correctly returned from its name."""
|
57
57
|
# strip _bms to get only type
|
58
|
-
bms_type: str = getattr(plugin, "__name__", "").rsplit(".", 1)[-1]
|
58
|
+
bms_type: str = getattr(plugin, "__name__", "").rsplit(".", 1)[-1]
|
59
59
|
bms_class: type[BaseBMS] | None = bms_cls(bms_type)
|
60
60
|
assert bms_class == plugin.BMS
|
61
61
|
|
62
62
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
bms_type: str = "unvailable_bms"
|
63
|
+
@pytest.mark.parametrize("bms_type", ["unavailable_bms", "ignore_me"])
|
64
|
+
def test_bms_cls_none(bms_type: str) -> None:
|
65
|
+
"""Test that a BMS class is None when name is not correct."""
|
67
66
|
bms_class: type[BaseBMS] | None = bms_cls(bms_type)
|
68
67
|
assert bms_class is None
|
69
68
|
|
@@ -1 +0,0 @@
|
|
1
|
-
"""Package for battery management systems (BMS) plugins."""
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|