python-ember-mug 1.1.1__tar.gz → 1.2.0b1__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.
- {python_ember_mug-1.1.1 → python_ember_mug-1.2.0b1}/PKG-INFO +3 -1
- {python_ember_mug-1.1.1 → python_ember_mug-1.2.0b1}/ember_mug/__init__.py +1 -1
- {python_ember_mug-1.1.1 → python_ember_mug-1.2.0b1}/ember_mug/consts.py +2 -2
- {python_ember_mug-1.1.1 → python_ember_mug-1.2.0b1}/ember_mug/scanner.py +13 -5
- {python_ember_mug-1.1.1 → python_ember_mug-1.2.0b1}/ember_mug/utils.py +1 -1
- {python_ember_mug-1.1.1 → python_ember_mug-1.2.0b1}/pyproject.toml +3 -2
- {python_ember_mug-1.1.1 → python_ember_mug-1.2.0b1}/tests/cli/test_commands.py +2 -2
- {python_ember_mug-1.1.1 → python_ember_mug-1.2.0b1}/tests/test_consts.py +8 -0
- {python_ember_mug-1.1.1 → python_ember_mug-1.2.0b1}/tests/test_scanner.py +11 -3
- {python_ember_mug-1.1.1 → python_ember_mug-1.2.0b1}/.gitignore +0 -0
- {python_ember_mug-1.1.1 → python_ember_mug-1.2.0b1}/LICENSE +0 -0
- {python_ember_mug-1.1.1 → python_ember_mug-1.2.0b1}/README.md +0 -0
- {python_ember_mug-1.1.1 → python_ember_mug-1.2.0b1}/ember_mug/__main__.py +0 -0
- {python_ember_mug-1.1.1 → python_ember_mug-1.2.0b1}/ember_mug/cli/__init__.py +0 -0
- {python_ember_mug-1.1.1 → python_ember_mug-1.2.0b1}/ember_mug/cli/commands.py +0 -0
- {python_ember_mug-1.1.1 → python_ember_mug-1.2.0b1}/ember_mug/cli/helpers.py +0 -0
- {python_ember_mug-1.1.1 → python_ember_mug-1.2.0b1}/ember_mug/data.py +0 -0
- {python_ember_mug-1.1.1 → python_ember_mug-1.2.0b1}/ember_mug/formatting.py +0 -0
- {python_ember_mug-1.1.1 → python_ember_mug-1.2.0b1}/ember_mug/mug.py +0 -0
- {python_ember_mug-1.1.1 → python_ember_mug-1.2.0b1}/tests/__init__.py +0 -0
- {python_ember_mug-1.1.1 → python_ember_mug-1.2.0b1}/tests/cli/__init__.py +0 -0
- {python_ember_mug-1.1.1 → python_ember_mug-1.2.0b1}/tests/cli/test_helpers.py +0 -0
- {python_ember_mug-1.1.1 → python_ember_mug-1.2.0b1}/tests/conftest.py +0 -0
- {python_ember_mug-1.1.1 → python_ember_mug-1.2.0b1}/tests/test_connection.py +0 -0
- {python_ember_mug-1.1.1 → python_ember_mug-1.2.0b1}/tests/test_data.py +0 -0
- {python_ember_mug-1.1.1 → python_ember_mug-1.2.0b1}/tests/test_formatting.py +0 -0
- {python_ember_mug-1.1.1 → python_ember_mug-1.2.0b1}/tests/test_mug_data.py +0 -0
- {python_ember_mug-1.1.1 → python_ember_mug-1.2.0b1}/tests/test_utils.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: python-ember-mug
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.2.0b1
|
|
4
4
|
Summary: Python Library for Ember Mugs.
|
|
5
5
|
Project-URL: Changelog, https://sopelj.github.io/python-ember-mug/changelog/
|
|
6
6
|
Project-URL: Documentation, https://sopelj.github.io/python-ember-mug/
|
|
@@ -20,6 +20,8 @@ Requires-Python: >=3.11
|
|
|
20
20
|
Requires-Dist: bleak-retry-connector>=3.5.0
|
|
21
21
|
Requires-Dist: bleak>=0.22.2; python_version < '3.13'
|
|
22
22
|
Requires-Dist: bleak>=0.22.3; python_version <= '3.13'
|
|
23
|
+
Provides-Extra: dev
|
|
24
|
+
Requires-Dist: ipython; extra == 'dev'
|
|
23
25
|
Provides-Extra: docs
|
|
24
26
|
Requires-Dist: black; extra == 'docs'
|
|
25
27
|
Requires-Dist: mkdocs-autorefs; extra == 'docs'
|
|
@@ -149,10 +149,10 @@ TRAVEL_MUG_SERVICE_UUIDS = (
|
|
|
149
149
|
str(MugCharacteristic.TRAVEL_MUG_SERVICE_OTHER),
|
|
150
150
|
)
|
|
151
151
|
|
|
152
|
-
DEVICE_SERVICE_UUIDS =
|
|
152
|
+
DEVICE_SERVICE_UUIDS = [
|
|
153
153
|
str(MugCharacteristic.STANDARD_SERVICE),
|
|
154
154
|
*TRAVEL_MUG_SERVICE_UUIDS,
|
|
155
|
-
|
|
155
|
+
]
|
|
156
156
|
|
|
157
157
|
|
|
158
158
|
class LiquidState(IntEnum):
|
|
@@ -5,29 +5,37 @@ from __future__ import annotations
|
|
|
5
5
|
import asyncio
|
|
6
6
|
import contextlib
|
|
7
7
|
import logging
|
|
8
|
-
from typing import TYPE_CHECKING,
|
|
8
|
+
from typing import TYPE_CHECKING, cast
|
|
9
9
|
|
|
10
10
|
from bleak import BleakScanner
|
|
11
11
|
|
|
12
12
|
from .consts import DEVICE_SERVICE_UUIDS, IS_LINUX
|
|
13
13
|
|
|
14
14
|
if TYPE_CHECKING:
|
|
15
|
+
from typing import NotRequired, TypedDict
|
|
16
|
+
|
|
15
17
|
from bleak.backends.device import BLEDevice
|
|
16
18
|
from bleak.backends.scanner import AdvertisementData
|
|
17
19
|
|
|
20
|
+
class ScannerKwargs(TypedDict):
|
|
21
|
+
"""Optional kwargs for scanner."""
|
|
22
|
+
|
|
23
|
+
adapter: NotRequired[str]
|
|
24
|
+
service_uuids: NotRequired[list[str]]
|
|
25
|
+
|
|
18
26
|
|
|
19
27
|
DEFAULT_TIMEOUT = 30
|
|
20
28
|
|
|
21
29
|
logger = logging.getLogger(__name__)
|
|
22
30
|
|
|
23
31
|
|
|
24
|
-
def build_scanner_kwargs(adapter: str | None = None
|
|
32
|
+
def build_scanner_kwargs(adapter: str | None = None, *, service_uuids: list[str] | None = None) -> ScannerKwargs:
|
|
25
33
|
"""Add Adapter to kwargs for scanner if specified and using BlueZ."""
|
|
26
34
|
if adapter and IS_LINUX is not True:
|
|
27
35
|
msg = "The adapter option is only valid for the Linux BlueZ Backend."
|
|
28
36
|
raise ValueError(msg)
|
|
29
|
-
kwargs = {"service_uuids":
|
|
30
|
-
return kwargs | {"adapter": adapter} if adapter else kwargs
|
|
37
|
+
kwargs = {"service_uuids": service_uuids} if service_uuids else {}
|
|
38
|
+
return cast("ScannerKwargs", kwargs | {"adapter": adapter} if adapter else kwargs)
|
|
31
39
|
|
|
32
40
|
|
|
33
41
|
async def discover_devices(
|
|
@@ -47,7 +55,7 @@ async def discover_devices(
|
|
|
47
55
|
```
|
|
48
56
|
|
|
49
57
|
"""
|
|
50
|
-
async with BleakScanner(**build_scanner_kwargs(adapter)) as scanner:
|
|
58
|
+
async with BleakScanner(**build_scanner_kwargs(adapter, service_uuids=DEVICE_SERVICE_UUIDS)) as scanner:
|
|
51
59
|
await asyncio.sleep(wait)
|
|
52
60
|
return [
|
|
53
61
|
(d, a)
|
|
@@ -134,7 +134,7 @@ def guess_model_from_name(name: str | None) -> DeviceModel | None:
|
|
|
134
134
|
|
|
135
135
|
def get_model_info_from_advertiser_data(advertisement: AdvertisementData) -> ModelInfo:
|
|
136
136
|
"""Extract model info from manufacturer data in advertiser data."""
|
|
137
|
-
from ember_mug.data import ModelInfo
|
|
137
|
+
from ember_mug.data import ModelInfo # noqa: PLC0415
|
|
138
138
|
|
|
139
139
|
model_data = advertisement.manufacturer_data.get(EMBER_BLE_SIG, None)
|
|
140
140
|
if model_data is not None:
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
[tool]
|
|
2
|
-
|
|
3
1
|
[project]
|
|
4
2
|
name = "python-ember-mug"
|
|
5
3
|
readme = "README.md"
|
|
@@ -43,6 +41,9 @@ docs = [
|
|
|
43
41
|
"black",
|
|
44
42
|
"termynal",
|
|
45
43
|
]
|
|
44
|
+
dev = [
|
|
45
|
+
"ipython",
|
|
46
|
+
]
|
|
46
47
|
|
|
47
48
|
[project.urls]
|
|
48
49
|
"Changelog" = "https://sopelj.github.io/python-ember-mug/changelog/"
|
|
@@ -316,7 +316,7 @@ def test_ember_cli():
|
|
|
316
316
|
@patch("ember_mug.consts.IS_LINUX", False)
|
|
317
317
|
def test_ember_cli_windows():
|
|
318
318
|
del sys.modules["ember_mug.cli.commands"] # force re-import
|
|
319
|
-
from ember_mug.cli.commands import EmberMugCli
|
|
319
|
+
from ember_mug.cli.commands import EmberMugCli # noqa: PLC0415
|
|
320
320
|
|
|
321
321
|
cli = EmberMugCli()
|
|
322
322
|
|
|
@@ -364,7 +364,7 @@ async def test_cli_run_discover_debug(mock_logging_config: Mock):
|
|
|
364
364
|
@patch("sys.argv", ["file.py", "find", "-m", TEST_MAC, "--raw"])
|
|
365
365
|
async def test_cli_run_non_linux():
|
|
366
366
|
del sys.modules["ember_mug.cli.commands"] # force re-import
|
|
367
|
-
from ember_mug.cli.commands import EmberMugCli
|
|
367
|
+
from ember_mug.cli.commands import EmberMugCli # noqa: PLC0415
|
|
368
368
|
|
|
369
369
|
cli = EmberMugCli()
|
|
370
370
|
mock_find = AsyncMock()
|
|
@@ -4,9 +4,17 @@ from __future__ import annotations
|
|
|
4
4
|
|
|
5
5
|
from uuid import UUID
|
|
6
6
|
|
|
7
|
+
import pytest
|
|
8
|
+
|
|
7
9
|
from ember_mug.consts import LiquidState, MugCharacteristic, VolumeLevel
|
|
8
10
|
|
|
9
11
|
|
|
12
|
+
@pytest.mark.parametrize("characteristic", MugCharacteristic)
|
|
13
|
+
def test_characteristic_uuids(characteristic: MugCharacteristic) -> None:
|
|
14
|
+
assert characteristic.uuid == UUID(f"fc54{characteristic.value:04x}-236c-4c94-8fa9-944a3e5353fa")
|
|
15
|
+
assert str(characteristic) == f"fc54{characteristic.value:04x}-236c-4c94-8fa9-944a3e5353fa"
|
|
16
|
+
|
|
17
|
+
|
|
10
18
|
def test_mug_uuids() -> None:
|
|
11
19
|
assert MugCharacteristic.MUG_NAME.uuid == UUID("fc540001-236c-4c94-8fa9-944a3e5353fa")
|
|
12
20
|
assert str(MugCharacteristic.MUG_NAME) == "fc540001-236c-4c94-8fa9-944a3e5353fa"
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
"""Tests for scanner."""
|
|
2
2
|
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import TYPE_CHECKING
|
|
3
6
|
from unittest.mock import AsyncMock, MagicMock, patch
|
|
4
7
|
|
|
5
8
|
import pytest
|
|
@@ -10,15 +13,20 @@ from ember_mug.scanner import build_scanner_kwargs, discover_devices, find_devic
|
|
|
10
13
|
|
|
11
14
|
from .conftest import TEST_MUG_ADVERTISEMENT
|
|
12
15
|
|
|
16
|
+
if TYPE_CHECKING:
|
|
17
|
+
from ember_mug.scanner import ScannerKwargs
|
|
18
|
+
|
|
13
19
|
MUG_1 = BLEDevice(address="32:36:a5:be:88:cb", name="Ember Ceramic Mug", details={}, rssi=1)
|
|
14
20
|
MUG_2 = BLEDevice(address="9c:da:8c:19:27:da", name="Ember Ceramic Mug", details={}, rssi=1)
|
|
15
21
|
EXAMPLE_MUGS = [MUG_1, MUG_2]
|
|
22
|
+
SERVICE_UUID_KWARG = {"service_uuids": DEVICE_SERVICE_UUIDS}
|
|
23
|
+
ADAPTER_KWARG = {"adapter": "hci0"}
|
|
16
24
|
|
|
17
25
|
|
|
18
26
|
@patch("ember_mug.scanner.IS_LINUX", True)
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
assert build_scanner_kwargs(
|
|
27
|
+
@pytest.mark.parametrize("kwargs", [{}, ADAPTER_KWARG, SERVICE_UUID_KWARG, ADAPTER_KWARG | SERVICE_UUID_KWARG])
|
|
28
|
+
def test_build_scanner_kwargs_linux(kwargs: ScannerKwargs) -> None:
|
|
29
|
+
assert build_scanner_kwargs(**kwargs) == kwargs
|
|
22
30
|
|
|
23
31
|
|
|
24
32
|
@patch("ember_mug.scanner.IS_LINUX", False)
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|