python-ember-mug 1.0.1__tar.gz → 1.1.0__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.
Files changed (28) hide show
  1. {python_ember_mug-1.0.1 → python_ember_mug-1.1.0}/PKG-INFO +8 -10
  2. {python_ember_mug-1.0.1 → python_ember_mug-1.1.0}/README.md +3 -3
  3. {python_ember_mug-1.0.1 → python_ember_mug-1.1.0}/ember_mug/__init__.py +2 -1
  4. {python_ember_mug-1.0.1 → python_ember_mug-1.1.0}/ember_mug/cli/commands.py +23 -23
  5. {python_ember_mug-1.0.1 → python_ember_mug-1.1.0}/ember_mug/mug.py +2 -2
  6. {python_ember_mug-1.0.1 → python_ember_mug-1.1.0}/ember_mug/scanner.py +23 -12
  7. {python_ember_mug-1.0.1 → python_ember_mug-1.1.0}/pyproject.toml +7 -9
  8. {python_ember_mug-1.0.1 → python_ember_mug-1.1.0}/tests/cli/test_commands.py +43 -43
  9. {python_ember_mug-1.0.1 → python_ember_mug-1.1.0}/tests/test_scanner.py +16 -16
  10. {python_ember_mug-1.0.1 → python_ember_mug-1.1.0}/.gitignore +0 -0
  11. {python_ember_mug-1.0.1 → python_ember_mug-1.1.0}/LICENSE +0 -0
  12. {python_ember_mug-1.0.1 → python_ember_mug-1.1.0}/ember_mug/__main__.py +0 -0
  13. {python_ember_mug-1.0.1 → python_ember_mug-1.1.0}/ember_mug/cli/__init__.py +0 -0
  14. {python_ember_mug-1.0.1 → python_ember_mug-1.1.0}/ember_mug/cli/helpers.py +0 -0
  15. {python_ember_mug-1.0.1 → python_ember_mug-1.1.0}/ember_mug/consts.py +0 -0
  16. {python_ember_mug-1.0.1 → python_ember_mug-1.1.0}/ember_mug/data.py +0 -0
  17. {python_ember_mug-1.0.1 → python_ember_mug-1.1.0}/ember_mug/formatting.py +0 -0
  18. {python_ember_mug-1.0.1 → python_ember_mug-1.1.0}/ember_mug/utils.py +0 -0
  19. {python_ember_mug-1.0.1 → python_ember_mug-1.1.0}/tests/__init__.py +0 -0
  20. {python_ember_mug-1.0.1 → python_ember_mug-1.1.0}/tests/cli/__init__.py +0 -0
  21. {python_ember_mug-1.0.1 → python_ember_mug-1.1.0}/tests/cli/test_helpers.py +0 -0
  22. {python_ember_mug-1.0.1 → python_ember_mug-1.1.0}/tests/conftest.py +0 -0
  23. {python_ember_mug-1.0.1 → python_ember_mug-1.1.0}/tests/test_connection.py +0 -0
  24. {python_ember_mug-1.0.1 → python_ember_mug-1.1.0}/tests/test_consts.py +0 -0
  25. {python_ember_mug-1.0.1 → python_ember_mug-1.1.0}/tests/test_data.py +0 -0
  26. {python_ember_mug-1.0.1 → python_ember_mug-1.1.0}/tests/test_formatting.py +0 -0
  27. {python_ember_mug-1.0.1 → python_ember_mug-1.1.0}/tests/test_mug_data.py +0 -0
  28. {python_ember_mug-1.0.1 → python_ember_mug-1.1.0}/tests/test_utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: python-ember-mug
3
- Version: 1.0.1
3
+ Version: 1.1.0
4
4
  Summary: Python Library for Ember Mugs.
5
5
  Project-URL: Documentation, https://sopelj.github.io/python-ember-mug/
6
6
  Project-URL: Source code, https://github.com/sopelj/python-ember-mug/
@@ -13,18 +13,16 @@ Classifier: Intended Audience :: Developers
13
13
  Classifier: License :: OSI Approved :: MIT License
14
14
  Classifier: Natural Language :: English
15
15
  Classifier: Programming Language :: Python :: 3
16
- Classifier: Programming Language :: Python :: 3.10
17
16
  Classifier: Programming Language :: Python :: 3.11
18
17
  Classifier: Programming Language :: Python :: 3.12
19
- Requires-Python: >=3.10
20
- Requires-Dist: async-timeout; python_version < '3.11'
21
- Requires-Dist: bleak-retry-connector>=3.1.2
22
- Requires-Dist: bleak>=0.21.0
18
+ Requires-Python: >=3.11
19
+ Requires-Dist: bleak-retry-connector>=3.5.0
20
+ Requires-Dist: bleak>=0.22.2
23
21
  Provides-Extra: docs
24
22
  Requires-Dist: black; extra == 'docs'
25
23
  Requires-Dist: mkdocs-autorefs; extra == 'docs'
26
24
  Requires-Dist: mkdocs-gen-files; extra == 'docs'
27
- Requires-Dist: mkdocs-include-markdown-plugin<7.0.0,>=3.6.1; extra == 'docs'
25
+ Requires-Dist: mkdocs-include-markdown-plugin<8.0.0,>=3.6.1; extra == 'docs'
28
26
  Requires-Dist: mkdocs-literate-nav; extra == 'docs'
29
27
  Requires-Dist: mkdocs-material-extensions; extra == 'docs'
30
28
  Requires-Dist: mkdocs-material<10.0.0,>=8.4.1; extra == 'docs'
@@ -102,15 +100,15 @@ Attributes by device:
102
100
  ### Python
103
101
 
104
102
  ```python
105
- from ember_mug.scanner import find_mug, discover_mugs
103
+ from ember_mug.scanner import find_device, discover_devices
106
104
  from ember_mug.utils import get_model_info_from_advertiser_data
107
105
  from ember_mug.mug import EmberMug
108
106
 
109
107
  # if first time with mug in pairing
110
- mugs = await discover_mugs()
108
+ devices = await discover_devices()
111
109
 
112
110
  # after paired you can simply use
113
- device, advertisement = await find_mug()
111
+ device, advertisement = await find_device()
114
112
  model_info = get_model_info_from_advertiser_data(advertisement)
115
113
  mug = EmberMug(device, model_info)
116
114
  await mug.update_all()
@@ -62,15 +62,15 @@ Attributes by device:
62
62
  ### Python
63
63
 
64
64
  ```python
65
- from ember_mug.scanner import find_mug, discover_mugs
65
+ from ember_mug.scanner import find_device, discover_devices
66
66
  from ember_mug.utils import get_model_info_from_advertiser_data
67
67
  from ember_mug.mug import EmberMug
68
68
 
69
69
  # if first time with mug in pairing
70
- mugs = await discover_mugs()
70
+ devices = await discover_devices()
71
71
 
72
72
  # after paired you can simply use
73
- device, advertisement = await find_mug()
73
+ device, advertisement = await find_device()
74
74
  model_info = get_model_info_from_advertiser_data(advertisement)
75
75
  mug = EmberMug(device, model_info)
76
76
  await mug.update_all()
@@ -1,8 +1,9 @@
1
1
  """Top-level package for Python Ember Mug."""
2
+
2
3
  from .mug import EmberMug
3
4
 
4
5
  __all__ = ("EmberMug",)
5
6
 
6
7
  __author__ = """Jesse Sopel"""
7
8
  __email__ = "jesse.sopel@gmail.com"
8
- __version__ = "1.0.1"
9
+ __version__ = "1.1.0"
@@ -14,7 +14,7 @@ from bleak import AdvertisementData, BleakError
14
14
  from ember_mug.consts import ATTR_LABELS, EXTRA_ATTRS, IS_LINUX, VolumeLevel
15
15
  from ember_mug.data import Colour
16
16
  from ember_mug.mug import EmberMug
17
- from ember_mug.scanner import discover_mugs, find_mug
17
+ from ember_mug.scanner import discover_devices, find_device
18
18
 
19
19
  from ..formatting import format_capacity
20
20
  from ..utils import get_model_info_from_advertiser_data
@@ -29,9 +29,9 @@ all_attrs = list(ATTR_LABELS) + list(EXTRA_ATTRS)
29
29
  get_attribute_names = [n.replace("_", "-") for n in all_attrs]
30
30
 
31
31
 
32
- async def get_mug(args: Namespace) -> EmberMug:
33
- """Help to get the mug based on args."""
34
- device, advertisement = await find_device(args)
32
+ async def get_device(args: Namespace) -> EmberMug:
33
+ """Help to get the devices based on command args."""
34
+ device, advertisement = await find_device_cmd(args)
35
35
  mug = EmberMug(
36
36
  device,
37
37
  get_model_info_from_advertiser_data(advertisement),
@@ -43,10 +43,10 @@ async def get_mug(args: Namespace) -> EmberMug:
43
43
  return mug
44
44
 
45
45
 
46
- async def find_device(args: Namespace) -> tuple[BLEDevice, AdvertisementData]:
46
+ async def find_device_cmd(args: Namespace) -> tuple[BLEDevice, AdvertisementData]:
47
47
  """Find a single device that has already been paired."""
48
48
  try:
49
- device, advertisement = await find_mug(mac=args.mac, adapter=args.adapter)
49
+ device, advertisement = await find_device(mac=args.mac, adapter=args.adapter)
50
50
  except BleakError as e:
51
51
  print(f"An error occurred trying to find a device: {e}")
52
52
  sys.exit(1)
@@ -58,10 +58,10 @@ async def find_device(args: Namespace) -> tuple[BLEDevice, AdvertisementData]:
58
58
  return device, advertisement
59
59
 
60
60
 
61
- async def discover(args: Namespace) -> list[tuple[BLEDevice, AdvertisementData]]:
61
+ async def discover_cmd(args: Namespace) -> list[tuple[BLEDevice, AdvertisementData]]:
62
62
  """Discover new devices in pairing mode."""
63
63
  try:
64
- mugs = await discover_mugs(mac=args.mac)
64
+ mugs = await discover_devices(mac=args.mac)
65
65
  except BleakError as e:
66
66
  print(f"An error occurred trying to discover devices: {e}")
67
67
  sys.exit(1)
@@ -83,9 +83,9 @@ async def discover(args: Namespace) -> list[tuple[BLEDevice, AdvertisementData]]
83
83
  return mugs
84
84
 
85
85
 
86
- async def fetch_info(args: Namespace) -> None:
86
+ async def fetch_info_cmd(args: Namespace) -> None:
87
87
  """Fetch all information from a mug and end."""
88
- mug = await get_mug(args)
88
+ mug = await get_device(args)
89
89
  async with mug.connection(adapter=args.adapter):
90
90
  if not args.raw:
91
91
  print("Connected.\nFetching Info")
@@ -93,9 +93,9 @@ async def fetch_info(args: Namespace) -> None:
93
93
  print_info(mug)
94
94
 
95
95
 
96
- async def poll_mug(args: Namespace) -> None:
96
+ async def poll_device_cmd(args: Namespace) -> None:
97
97
  """Fetch all information and keep polling for changes."""
98
- mug = await get_mug(args)
98
+ mug = await get_device(args)
99
99
  async with mug.connection(adapter=args.adapter):
100
100
  if not args.raw:
101
101
  print("Connected.\nFetching Info")
@@ -111,9 +111,9 @@ async def poll_mug(args: Namespace) -> None:
111
111
  print_changes(await mug.update_all(), mug.data.use_metric)
112
112
 
113
113
 
114
- async def get_mug_value(args: Namespace) -> None:
114
+ async def get_device_value_cmd(args: Namespace) -> None:
115
115
  """Get values from the mug and print them."""
116
- mug = await get_mug(args)
116
+ mug = await get_device(args)
117
117
  data = {}
118
118
  attributes = [a.replace("-", "_") for a in args.attributes]
119
119
  async with mug.connection(adapter=args.adapter):
@@ -131,8 +131,8 @@ async def get_mug_value(args: Namespace) -> None:
131
131
  print_table([(ATTR_LABELS.get(attr, attr), str(mug.data.get_formatted_attr(attr))) for attr in data])
132
132
 
133
133
 
134
- async def set_mug_value(args: Namespace) -> None:
135
- """Set one or more values on the mug."""
134
+ async def set_device_value_cmd(args: Namespace) -> None:
135
+ """Set one or more values on the device."""
136
136
  attrs = ("name", "target_temp", "temperature_unit", "led_colour", "volume_level")
137
137
  values = [(attr, value) for attr in attrs if (value := getattr(args, attr, None))]
138
138
  if not values:
@@ -141,7 +141,7 @@ async def set_mug_value(args: Namespace) -> None:
141
141
  print(f'Options: {", ".join(options)}')
142
142
  sys.exit(1)
143
143
 
144
- mug = await get_mug(args)
144
+ mug = await get_device(args)
145
145
  async with mug.connection(adapter=args.adapter):
146
146
  for attr, value in values:
147
147
  method = getattr(mug, f'set_{attr.replace("-", "_")}')
@@ -180,12 +180,12 @@ class EmberMugCli:
180
180
  """Very simple CLI Interface to interact with a mug."""
181
181
 
182
182
  _commands: ClassVar[dict[str, Callable[[Namespace], Awaitable]]] = {
183
- "find": find_device,
184
- "discover": discover,
185
- "info": fetch_info,
186
- "poll": poll_mug,
187
- "get": get_mug_value,
188
- "set": set_mug_value,
183
+ "find": find_device_cmd,
184
+ "discover": discover_cmd,
185
+ "info": fetch_info_cmd,
186
+ "poll": poll_device_cmd,
187
+ "get": get_device_value_cmd,
188
+ "set": set_device_value_cmd,
189
189
  }
190
190
 
191
191
  def __init__(self) -> None:
@@ -4,7 +4,7 @@ from __future__ import annotations
4
4
  import asyncio
5
5
  import contextlib
6
6
  import logging
7
- from datetime import datetime, timezone
7
+ from datetime import UTC, datetime
8
8
  from enum import Enum
9
9
  from functools import cached_property
10
10
  from time import time
@@ -389,7 +389,7 @@ class EmberMug:
389
389
  """Get date and time zone."""
390
390
  date_time_zone_bytes = await self._read(MugCharacteristic.DATE_TIME_AND_ZONE)
391
391
  time_value = bytes_to_big_int(date_time_zone_bytes[:4])
392
- return datetime.fromtimestamp(time_value, timezone.utc) if time_value > 0 else None
392
+ return datetime.fromtimestamp(time_value, UTC) if time_value > 0 else None
393
393
 
394
394
  async def get_firmware(self) -> MugFirmwareInfo:
395
395
  """Get firmware info."""
@@ -4,19 +4,12 @@ from __future__ import annotations
4
4
  import asyncio
5
5
  import contextlib
6
6
  import logging
7
- import sys
8
7
  from typing import TYPE_CHECKING, Any
9
8
 
10
9
  from bleak import BleakScanner
11
10
 
12
11
  from .consts import DEVICE_SERVICE_UUIDS, IS_LINUX
13
12
 
14
- if sys.version_info < (3, 11):
15
- # library required before Python 3.11
16
- import async_timeout
17
- else:
18
- async_timeout = asyncio
19
-
20
13
  if TYPE_CHECKING:
21
14
  from bleak.backends.device import BLEDevice
22
15
  from bleak.backends.scanner import AdvertisementData
@@ -36,12 +29,22 @@ def build_scanner_kwargs(adapter: str | None = None) -> dict[str, Any]:
36
29
  return kwargs | {"adapter": adapter} if adapter else kwargs
37
30
 
38
31
 
39
- async def discover_mugs(
32
+ async def discover_devices(
40
33
  mac: str | None = None,
41
34
  adapter: str | None = None,
42
35
  wait: int = 5,
43
36
  ) -> list[tuple[BLEDevice, AdvertisementData]]:
44
- """Discover new mugs in pairing mode."""
37
+ """
38
+ Discover new devices in pairing mode.
39
+
40
+ Example:
41
+ -------
42
+ ```python
43
+ devices = await discover_devices()
44
+ for device, advertisement in devices:
45
+ print(device.address, advertisement)
46
+ ```
47
+ """
45
48
  async with BleakScanner(**build_scanner_kwargs(adapter)) as scanner:
46
49
  await asyncio.sleep(wait)
47
50
  return [
@@ -51,17 +54,25 @@ async def discover_mugs(
51
54
  ]
52
55
 
53
56
 
54
- async def find_mug(
57
+ async def find_device(
55
58
  mac: str | None = None,
56
59
  adapter: str | None = None,
57
60
  timeout: int = DEFAULT_TIMEOUT,
58
61
  ) -> tuple[BLEDevice, AdvertisementData] | tuple[None, None]:
59
- """Find a mug."""
62
+ """
63
+ Find a device that has previously been discovered.
64
+
65
+ Example:
66
+ -------
67
+ ```python
68
+ device = await find_device("my:mac:addr")
69
+ ```
70
+ """
60
71
  if mac is not None:
61
72
  mac = mac.lower()
62
73
  async with BleakScanner(**build_scanner_kwargs(adapter)) as scanner:
63
74
  with contextlib.suppress(asyncio.TimeoutError):
64
- async with async_timeout.timeout(timeout):
75
+ async with asyncio.timeout(timeout):
65
76
  async for device, advertisement in scanner.advertisement_data():
66
77
  if (not mac and device.name and device.name.startswith("Ember")) or (
67
78
  mac and device.address.lower() == mac
@@ -8,21 +8,19 @@ authors = [
8
8
  { name = "Jesse Sopel", email = "jesse.sopel@gmail.com" },
9
9
  ]
10
10
  license = "MIT"
11
- requires-python = ">=3.10"
11
+ requires-python = ">=3.11"
12
12
  dynamic = ["version"]
13
13
  classifiers=[
14
14
  'Intended Audience :: Developers',
15
15
  'License :: OSI Approved :: MIT License',
16
16
  'Natural Language :: English',
17
17
  'Programming Language :: Python :: 3',
18
- 'Programming Language :: Python :: 3.10',
19
18
  'Programming Language :: Python :: 3.11',
20
19
  'Programming Language :: Python :: 3.12',
21
20
  ]
22
21
  dependencies = [
23
- "bleak-retry-connector>=3.1.2",
24
- "bleak>=0.21.0",
25
- "async-timeout; python_version < '3.11'",
22
+ "bleak-retry-connector>=3.5.0",
23
+ "bleak>=0.22.2",
26
24
  ]
27
25
 
28
26
  [project.optional-dependencies]
@@ -33,7 +31,7 @@ test = [
33
31
  ]
34
32
  docs = [
35
33
  "mkdocs>=1.1.21",
36
- "mkdocs-include-markdown-plugin>=3.6.1,<7.0.0",
34
+ "mkdocs-include-markdown-plugin>=3.6.1,<8.0.0",
37
35
  "mkdocs-material>=8.4.1,<10.0.0",
38
36
  "mkdocstrings[python]",
39
37
  "mkdocs-material-extensions",
@@ -78,7 +76,7 @@ python = "3.12"
78
76
  features = ["test"]
79
77
 
80
78
  [[tool.hatch.envs.test.matrix]]
81
- python = ["3.10", "3.11", "3.12"]
79
+ python = ["3.11", "3.12"]
82
80
 
83
81
  [tool.hatch.envs.test.scripts]
84
82
  cov = "pytest -vvv --asyncio-mode=auto --cov=ember_mug --cov-branch --cov-report=xml --cov-report=term-missing tests"
@@ -95,7 +93,7 @@ serve = "mkdocs serve --dev-addr localhost:8000"
95
93
  [tool.black]
96
94
  line-length = 120
97
95
  skip-string-normalization = true
98
- target-version = ['py310', 'py311', 'py312']
96
+ target-version = ["py311", "py312"]
99
97
  include = '\.pyi?$'
100
98
  exclude = '''
101
99
  /(
@@ -126,7 +124,7 @@ exclude_lines = [
126
124
  [tool.ruff]
127
125
  fix = true
128
126
  line-length = 120
129
- target-version = "py310"
127
+ target-version = "py311"
130
128
  select = [
131
129
  "A",
132
130
  "ASYNC",
@@ -13,13 +13,13 @@ from ember_mug import EmberMug
13
13
  from ember_mug.cli.commands import (
14
14
  EmberMugCli,
15
15
  colour_type,
16
- discover,
17
- fetch_info,
18
- find_device,
19
- get_mug,
20
- get_mug_value,
21
- poll_mug,
22
- set_mug_value,
16
+ discover_cmd,
17
+ fetch_info_cmd,
18
+ find_device_cmd,
19
+ get_device,
20
+ get_device_value_cmd,
21
+ poll_device_cmd,
22
+ set_device_value_cmd,
23
23
  )
24
24
  from ember_mug.consts import DeviceColour, DeviceModel
25
25
  from ember_mug.data import Colour, ModelInfo, MugData
@@ -34,7 +34,7 @@ if TYPE_CHECKING:
34
34
 
35
35
  @pytest.fixture()
36
36
  def mock_mug_with_connection() -> Generator[AsyncMock, None, None]:
37
- with patch("ember_mug.cli.commands.get_mug") as mock:
37
+ with patch("ember_mug.cli.commands.get_device") as mock:
38
38
  mock_mug = AsyncMock()
39
39
  mock_mug.connection = Mock(return_value=mock_connection)
40
40
  mock.return_value = mock_mug
@@ -54,18 +54,18 @@ def mock_namespace(**kwargs: Any) -> Namespace:
54
54
 
55
55
 
56
56
  @patch("ember_mug.cli.commands.EmberMug", spec=EmberMug)
57
- @patch("ember_mug.cli.commands.find_device")
58
- async def test_get_mug(
59
- mock_find_device: AsyncMock,
57
+ @patch("ember_mug.cli.commands.find_device_cmd")
58
+ async def test_get_device(
59
+ mock_find_device_cmd: AsyncMock,
60
60
  mock_ember_mug: AsyncMock,
61
61
  capsys: CaptureFixture,
62
62
  ble_device: BLEDevice,
63
63
  ) -> None:
64
- mock_find_device.return_value = ble_device, TEST_MUG_ADVERTISEMENT
64
+ mock_find_device_cmd.return_value = ble_device, TEST_MUG_ADVERTISEMENT
65
65
  args = mock_namespace(extra=True)
66
- mug = await get_mug(args)
66
+ mug = await get_device(args)
67
67
  assert mug is not None
68
- mock_find_device.assert_called_once_with(args)
68
+ mock_find_device_cmd.assert_called_once_with(args)
69
69
  mock_ember_mug.assert_called_once_with(
70
70
  ble_device,
71
71
  ModelInfo(DeviceModel.MUG_2_10_OZ, DeviceColour.BLACK),
@@ -77,17 +77,17 @@ async def test_get_mug(
77
77
 
78
78
  # Raw prints nothing
79
79
  args = mock_namespace(extra=True, raw=True)
80
- mug = await get_mug(args)
80
+ mug = await get_device(args)
81
81
  assert mug is not None
82
82
  captured = capsys.readouterr()
83
83
  assert captured.out == ""
84
84
 
85
85
 
86
- @patch("ember_mug.cli.commands.find_mug")
86
+ @patch("ember_mug.cli.commands.find_device")
87
87
  async def test_find_device(mock_find_mug: AsyncMock, capsys: CaptureFixture, ble_device: BLEDevice) -> None:
88
88
  mock_find_mug.return_value = (ble_device, TEST_MUG_ADVERTISEMENT)
89
89
  args = mock_namespace(mac=ble_device.address)
90
- device, advertisement = await find_device(args)
90
+ device, advertisement = await find_device_cmd(args)
91
91
  assert device == ble_device
92
92
  assert advertisement == TEST_MUG_ADVERTISEMENT
93
93
  mock_find_mug.assert_called_once_with(mac=ble_device.address, adapter=None)
@@ -96,38 +96,38 @@ async def test_find_device(mock_find_mug: AsyncMock, capsys: CaptureFixture, ble
96
96
 
97
97
  # Raw prints nothing
98
98
  args = Namespace(mac=ble_device.address, adapter=None, raw=True)
99
- await find_device(args)
99
+ await find_device_cmd(args)
100
100
  captured = capsys.readouterr()
101
101
  assert captured.out == ""
102
102
 
103
103
 
104
- @patch("ember_mug.cli.commands.find_mug")
104
+ @patch("ember_mug.cli.commands.find_device")
105
105
  async def test_find_device_no_device(mock_find_mug: AsyncMock, capsys: CaptureFixture) -> None:
106
106
  mock_find_mug.return_value = (None, None)
107
107
  args = mock_namespace(mac=TEST_MAC)
108
108
  with pytest.raises(SystemExit, match="1"):
109
- await find_device(args)
109
+ await find_device_cmd(args)
110
110
  mock_find_mug.assert_called_once_with(mac=TEST_MAC, adapter=None)
111
111
  captured = capsys.readouterr()
112
112
  assert captured.out == "No device was found.\n"
113
113
 
114
114
 
115
- @patch("ember_mug.cli.commands.find_mug")
115
+ @patch("ember_mug.cli.commands.find_device")
116
116
  async def test_find_device_bleak_error(mock_find_mug: AsyncMock, capsys: CaptureFixture) -> None:
117
117
  mock_find_mug.side_effect = BleakError("Test Error")
118
118
  args = mock_namespace(mac=TEST_MAC)
119
119
  with pytest.raises(SystemExit, match="1"):
120
- await find_device(args)
120
+ await find_device_cmd(args)
121
121
  mock_find_mug.assert_called_once_with(mac=TEST_MAC, adapter=None)
122
122
  captured = capsys.readouterr()
123
123
  assert captured.out == "An error occurred trying to find a device: Test Error\n"
124
124
 
125
125
 
126
- @patch("ember_mug.cli.commands.discover_mugs")
126
+ @patch("ember_mug.cli.commands.discover_devices")
127
127
  async def test_discover(mock_discover_mugs: AsyncMock, capsys: CaptureFixture, ble_device: BLEDevice) -> None:
128
128
  mock_discover_mugs.return_value = [(ble_device, TEST_MUG_ADVERTISEMENT)]
129
129
  args = mock_namespace(mac=TEST_MAC)
130
- mugs = await discover(args)
130
+ mugs = await discover_cmd(args)
131
131
  assert mugs == [(ble_device, TEST_MUG_ADVERTISEMENT)]
132
132
  mock_discover_mugs.assert_called_once_with(mac=TEST_MAC)
133
133
  captured = capsys.readouterr()
@@ -141,30 +141,30 @@ async def test_discover(mock_discover_mugs: AsyncMock, capsys: CaptureFixture, b
141
141
 
142
142
  mock_discover_mugs.reset_mock()
143
143
  args = mock_namespace(mac=TEST_MAC, raw=True)
144
- mugs = await discover(args)
144
+ mugs = await discover_cmd(args)
145
145
  assert mugs == [(ble_device, TEST_MUG_ADVERTISEMENT)]
146
146
  mock_discover_mugs.assert_called_once_with(mac=TEST_MAC)
147
147
  captured = capsys.readouterr()
148
148
  assert captured.out == f"{TEST_MAC}\n"
149
149
 
150
150
 
151
- @patch("ember_mug.cli.commands.discover_mugs")
151
+ @patch("ember_mug.cli.commands.discover_devices")
152
152
  async def test_discover_no_device(mock_discover_mugs: AsyncMock, capsys: CaptureFixture) -> None:
153
153
  mock_discover_mugs.return_value = []
154
154
  args = mock_namespace(mac=TEST_MAC)
155
155
  with pytest.raises(SystemExit, match="1"):
156
- await discover(args)
156
+ await discover_cmd(args)
157
157
  mock_discover_mugs.assert_called_once_with(mac=TEST_MAC)
158
158
  captured = capsys.readouterr()
159
159
  assert captured.out == 'No devices were found. Be sure it is in pairing mode. Or use "find" if already paired.\n'
160
160
 
161
161
 
162
- @patch("ember_mug.cli.commands.discover_mugs")
162
+ @patch("ember_mug.cli.commands.discover_devices")
163
163
  async def test_discover_bleak_error(mock_discover_mugs: AsyncMock, capsys: CaptureFixture) -> None:
164
164
  mock_discover_mugs.side_effect = BleakError("Test Error")
165
165
  args = mock_namespace(mac=TEST_MAC)
166
166
  with pytest.raises(SystemExit, match="1"):
167
- await discover(args)
167
+ await discover_cmd(args)
168
168
  mock_discover_mugs.assert_called_once_with(mac=TEST_MAC)
169
169
  captured = capsys.readouterr()
170
170
  assert captured.out == "An error occurred trying to discover devices: Test Error\n"
@@ -178,14 +178,14 @@ async def test_fetch_info(
178
178
  ) -> None:
179
179
  # Test normal
180
180
  args = mock_namespace(mac=TEST_MAC)
181
- await fetch_info(args)
181
+ await fetch_info_cmd(args)
182
182
  captured = capsys.readouterr()
183
183
  assert captured.out == "Connected.\nFetching Info\n"
184
184
  mock_print_info.assert_called_once_with(mock_mug_with_connection)
185
185
 
186
186
  # Test with Raw
187
187
  args = mock_namespace(mac=TEST_MAC, raw=True)
188
- await fetch_info(args)
188
+ await fetch_info_cmd(args)
189
189
  captured = capsys.readouterr()
190
190
  assert captured.out == ""
191
191
 
@@ -194,7 +194,7 @@ async def test_fetch_info(
194
194
  @patch("ember_mug.cli.commands.print_info")
195
195
  @patch("ember_mug.cli.commands.print_changes")
196
196
  @patch("ember_mug.cli.commands.CommandLoop", lambda: [1])
197
- async def test_poll_mug(
197
+ async def test_poll_device_cmd(
198
198
  mock_print_changes: AsyncMock,
199
199
  mock_print_info: AsyncMock,
200
200
  mock_sleep: AsyncMock,
@@ -203,7 +203,7 @@ async def test_poll_mug(
203
203
  ) -> None:
204
204
  # Test normal
205
205
  args = mock_namespace(mac=TEST_MAC)
206
- await poll_mug(args)
206
+ await poll_device_cmd(args)
207
207
  captured = capsys.readouterr()
208
208
  assert captured.out == "Connected.\nFetching Info\n\nWatching for changes\n"
209
209
  mock_sleep.assert_has_calls([call(1)] * 60)
@@ -211,14 +211,14 @@ async def test_poll_mug(
211
211
  # Test with Raw
212
212
  mock_sleep.reset_mock()
213
213
  args = mock_namespace(mac=TEST_MAC, raw=True)
214
- await poll_mug(args)
214
+ await poll_device_cmd(args)
215
215
  mock_sleep.assert_has_calls([call(1)] * 60)
216
216
  captured = capsys.readouterr()
217
217
  assert captured.out == ""
218
218
 
219
219
 
220
220
  @patch("ember_mug.cli.commands.print_table")
221
- async def test_get_mug_value(
221
+ async def test_get_device_value_cmd(
222
222
  mocked_print_table: Mock,
223
223
  mock_mug_with_connection: AsyncMock,
224
224
  capsys: CaptureFixture,
@@ -228,25 +228,25 @@ async def test_get_mug_value(
228
228
  mock_mug_with_connection.get_target_temp.return_value = 55.5
229
229
  mock_mug_with_connection.get_name.return_value = "test"
230
230
  args = mock_namespace(attributes=["target_temp", "name"])
231
- await get_mug_value(args)
231
+ await get_device_value_cmd(args)
232
232
  mock_mug_with_connection.get_target_temp.assert_called_once()
233
233
  mocked_print_table.assert_called_once_with([("Target Temp", "test"), ("Device Name", "test")])
234
234
 
235
235
  mock_mug_with_connection.get_led_colour.return_value = 55.5
236
236
  args = mock_namespace(attributes=["led_colour", "name"], raw=True)
237
- await get_mug_value(args)
237
+ await get_device_value_cmd(args)
238
238
  captured = capsys.readouterr()
239
239
  assert captured.out == "55.5\ntest\n"
240
240
 
241
241
  mock_mug_with_connection.get_name.side_effect = NotImplementedError
242
242
  args = mock_namespace(attributes=["name"], raw=True)
243
243
  with pytest.raises(SystemExit, match="1"):
244
- await get_mug_value(args)
244
+ await get_device_value_cmd(args)
245
245
 
246
246
 
247
- async def test_set_mug_value_no_value(capsys: CaptureFixture) -> None:
247
+ async def test_set_device_value_cmd_no_value(capsys: CaptureFixture) -> None:
248
248
  with pytest.raises(SystemExit, match="1"):
249
- await set_mug_value(Namespace())
249
+ await set_device_value_cmd(Namespace())
250
250
  captured = capsys.readouterr()
251
251
  assert captured.out == (
252
252
  "Please specify at least one attribute and value to set.\n"
@@ -254,16 +254,16 @@ async def test_set_mug_value_no_value(capsys: CaptureFixture) -> None:
254
254
  )
255
255
 
256
256
 
257
- async def test_set_mug_value(mock_mug_with_connection: AsyncMock) -> None:
257
+ async def test_set_device_value_cmd(mock_mug_with_connection: AsyncMock) -> None:
258
258
  mock_mug_with_connection.data = MugData(ModelInfo())
259
259
  args = mock_namespace(name="test")
260
- await set_mug_value(args)
260
+ await set_device_value_cmd(args)
261
261
  mock_mug_with_connection.set_name.assert_called_once_with("test")
262
262
 
263
263
  mock_mug_with_connection.reset_mock()
264
264
  mock_mug_with_connection.set_name.side_effect = NotImplementedError("Unable to set name on Cup")
265
265
  with pytest.raises(SystemExit, match="1"):
266
- await set_mug_value(args)
266
+ await set_device_value_cmd(args)
267
267
 
268
268
 
269
269
  @pytest.mark.parametrize(
@@ -5,7 +5,7 @@ import pytest
5
5
  from bleak.backends.device import BLEDevice
6
6
 
7
7
  from ember_mug.consts import DEVICE_SERVICE_UUIDS
8
- from ember_mug.scanner import build_scanner_kwargs, discover_mugs, find_mug
8
+ from ember_mug.scanner import build_scanner_kwargs, discover_devices, find_device
9
9
 
10
10
  from .conftest import TEST_MUG_ADVERTISEMENT
11
11
 
@@ -29,34 +29,34 @@ def test_build_scanner_kwargs_other() -> None:
29
29
 
30
30
  @patch("asyncio.sleep")
31
31
  @patch("ember_mug.scanner.BleakScanner")
32
- async def test_discover_mugs(mock_scanner: AsyncMock, mock_sleep: AsyncMock) -> None:
32
+ async def test_discover_devices(mock_scanner: AsyncMock, mock_sleep: AsyncMock) -> None:
33
33
  mock_scanner.return_value.__aenter__.return_value.discovered_devices_and_advertisement_data = {
34
34
  m.address: (m, TEST_MUG_ADVERTISEMENT) for m in EXAMPLE_MUGS
35
35
  }
36
- mugs = await discover_mugs()
37
- assert len(mugs) == 2
38
- mugs = await discover_mugs(mac="32:36:a5:be:88:cb")
39
- assert len(mugs) == 1
40
- device_1, advertisement_1 = mugs[0]
36
+ devices = await discover_devices()
37
+ assert len(devices) == 2
38
+ devices = await discover_devices(mac="32:36:a5:be:88:cb")
39
+ assert len(devices) == 1
40
+ device_1, advertisement_1 = devices[0]
41
41
  assert device_1.address == "32:36:a5:be:88:cb"
42
42
  mock_sleep.assert_called_with(5)
43
43
 
44
44
 
45
45
  @patch("asyncio.sleep")
46
46
  @patch("ember_mug.scanner.BleakScanner")
47
- async def test_find_mug(mock_scanner: AsyncMock, mock_sleep: AsyncMock) -> None:
47
+ async def test_find_device(mock_scanner: AsyncMock, mock_sleep: AsyncMock) -> None:
48
48
  mock_data_iterator = MagicMock()
49
49
  mock_data_iterator().__aiter__.return_value = [(m, TEST_MUG_ADVERTISEMENT) for m in EXAMPLE_MUGS]
50
50
  mock_scanner.return_value.__aenter__.return_value.advertisement_data = mock_data_iterator
51
51
 
52
52
  # Without filter
53
- mug, advertisement = await find_mug()
54
- assert mug is not None
55
- assert mug.name == "Ember Ceramic Mug"
56
- assert mug.address == MUG_1.address
53
+ device, advertisement = await find_device()
54
+ assert device is not None
55
+ assert device.name == "Ember Ceramic Mug"
56
+ assert device.address == MUG_1.address
57
57
 
58
58
  # With Filter
59
- mug, advertisement = await find_mug(mac=MUG_2.address)
60
- assert mug is not None
61
- assert mug.name == "Ember Ceramic Mug"
62
- assert mug.address == MUG_2.address
59
+ device, advertisement = await find_device(mac=MUG_2.address)
60
+ assert device is not None
61
+ assert device.name == "Ember Ceramic Mug"
62
+ assert device.address == MUG_2.address