Skip to content

Commit c3cfc2d

Browse files
authored
0.12.0 Release
2 parents a98eaac + 73d786f commit c3cfc2d

File tree

11 files changed

+829
-85
lines changed

11 files changed

+829
-85
lines changed

LICENSE

Lines changed: 674 additions & 0 deletions
Large diffs are not rendered by default.

README.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,12 @@ These are XBee Zigbee based radios that have been tested with the [zigpy-xbee](h
2929
- Digi XBee Series 2 (S2) modules. Note: These will need to be manually flashed with the Zigbee Coordinator API firmware via XCTU.
3030
- Digi XBee Series 3 (xbee3-24) modules
3131

32-
# Releases of zigpy-xbee-homeassistant via PyPI
33-
Tagged versions of zigpy-xbee-homeassistant are also released via PyPI
32+
# Releases of zigpy-xbee via PyPI
33+
Tagged versions of zigpy-xbee are also released via PyPI
3434

35-
- https://pypi.org/project/zigpy-xbee-homeassistant/
36-
- https://pypi.org/project/zigpy-xbee-homeassistant/#history
37-
- https://pypi.org/project/zigpy-xbee-homeassistant/#files
35+
- https://pypi.org/project/zigpy-xbee/
36+
- https://pypi.org/project/zigpy-xbee/#history
37+
- https://pypi.org/project/zigpy-xbee/#files
3838

3939
# How to contribute
4040

setup.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,26 @@
11
"""Setup module for zigpy-xbee"""
22

3+
import os
4+
35
from setuptools import find_packages, setup
46

57
import zigpy_xbee
68

9+
this_directory = os.path.join(os.path.abspath(os.path.dirname(__file__)))
10+
with open(os.path.join(this_directory, "README.md"), encoding="utf-8") as f:
11+
long_description = f.read()
12+
713
setup(
8-
name="zigpy-xbee-homeassistant",
14+
name="zigpy-xbee",
915
version=zigpy_xbee.__version__,
1016
description="A library which communicates with XBee radios for zigpy",
17+
long_description=long_description,
18+
long_description_content_type="text/markdown",
1119
url="http://github.com/zigpy/zigpy-xbee",
1220
author="Russell Cloran",
1321
author_email="[email protected]",
1422
license="GPL-3.0",
1523
packages=find_packages(exclude=["*.tests"]),
16-
install_requires=["pyserial-asyncio", "zigpy-homeassistant >= 0.17.0"],
24+
install_requires=["pyserial-asyncio", "zigpy>= 0.20.a1"],
1725
tests_require=["pytest"],
1826
)

tests/test_api.py

Lines changed: 31 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -7,24 +7,26 @@
77
import zigpy.exceptions
88

99
from zigpy_xbee import api as xbee_api, types as t, uart
10+
import zigpy_xbee.config
1011
from zigpy_xbee.zigbee.application import ControllerApplication
1112

13+
DEVICE_CONFIG = zigpy_xbee.config.SCHEMA_DEVICE(
14+
{zigpy_xbee.config.CONF_DEVICE_PATH: "/dev/null"}
15+
)
16+
1217

1318
@pytest.fixture
1419
def api():
15-
api = xbee_api.XBee()
20+
api = xbee_api.XBee(DEVICE_CONFIG)
1621
api._uart = mock.MagicMock()
1722
return api
1823

1924

2025
@pytest.mark.asyncio
2126
async def test_connect(monkeypatch):
22-
api = xbee_api.XBee()
23-
dev = mock.MagicMock()
24-
monkeypatch.setattr(
25-
uart, "connect", mock.MagicMock(side_effect=asyncio.coroutine(mock.MagicMock()))
26-
)
27-
await api.connect(dev, 115200)
27+
api = xbee_api.XBee(DEVICE_CONFIG)
28+
monkeypatch.setattr(uart, "connect", CoroutineMock())
29+
await api.connect()
2830

2931

3032
def test_close(api):
@@ -542,14 +544,13 @@ def test_handle_many_to_one_rri(api):
542544

543545
@pytest.mark.asyncio
544546
async def test_reconnect_multiple_disconnects(monkeypatch, caplog):
545-
api = xbee_api.XBee()
546-
dev = mock.sentinel.uart
547+
api = xbee_api.XBee(DEVICE_CONFIG)
547548
connect_mock = CoroutineMock()
548549
connect_mock.return_value = asyncio.Future()
549550
connect_mock.return_value.set_result(True)
550551
monkeypatch.setattr(uart, "connect", connect_mock)
551552

552-
await api.connect(dev, 115200)
553+
await api.connect()
553554

554555
caplog.set_level(logging.DEBUG)
555556
connected = asyncio.Future()
@@ -568,14 +569,13 @@ async def test_reconnect_multiple_disconnects(monkeypatch, caplog):
568569

569570
@pytest.mark.asyncio
570571
async def test_reconnect_multiple_attempts(monkeypatch, caplog):
571-
api = xbee_api.XBee()
572-
dev = mock.sentinel.uart
572+
api = xbee_api.XBee(DEVICE_CONFIG)
573573
connect_mock = CoroutineMock()
574574
connect_mock.return_value = asyncio.Future()
575575
connect_mock.return_value.set_result(True)
576576
monkeypatch.setattr(uart, "connect", connect_mock)
577577

578-
await api.connect(dev, 115200)
578+
await api.connect()
579579

580580
caplog.set_level(logging.DEBUG)
581581
connected = asyncio.Future()
@@ -597,11 +597,11 @@ async def test_reconnect_multiple_attempts(monkeypatch, caplog):
597597
async def test_probe_success(mock_connect, mock_at_cmd):
598598
"""Test device probing."""
599599

600-
res = await xbee_api.XBee.probe(mock.sentinel.uart, mock.sentinel.baud)
600+
res = await xbee_api.XBee.probe(DEVICE_CONFIG)
601601
assert res is True
602602
assert mock_connect.call_count == 1
603603
assert mock_connect.await_count == 1
604-
assert mock_connect.call_args[0][0] is mock.sentinel.uart
604+
assert mock_connect.call_args[0][0] == DEVICE_CONFIG
605605
assert mock_at_cmd.call_count == 1
606606
assert mock_connect.return_value.close.call_count == 1
607607

@@ -613,11 +613,11 @@ async def test_probe_success(mock_connect, mock_at_cmd):
613613
async def test_probe_success_api_mode(mock_connect, mock_at_cmd, mock_api_mode):
614614
"""Test device probing."""
615615

616-
res = await xbee_api.XBee.probe(mock.sentinel.uart, mock.sentinel.baud)
616+
res = await xbee_api.XBee.probe(DEVICE_CONFIG)
617617
assert res is True
618618
assert mock_connect.call_count == 1
619619
assert mock_connect.await_count == 1
620-
assert mock_connect.call_args[0][0] is mock.sentinel.uart
620+
assert mock_connect.call_args[0][0] == DEVICE_CONFIG
621621
assert mock_at_cmd.call_count == 1
622622
assert mock_api_mode.call_count == 1
623623
assert mock_connect.return_value.close.call_count == 1
@@ -638,11 +638,11 @@ async def test_probe_fail(mock_connect, mock_at_cmd, mock_api_mode, exception):
638638
mock_api_mode.reset_mock()
639639
mock_at_cmd.reset_mock()
640640
mock_connect.reset_mock()
641-
res = await xbee_api.XBee.probe(mock.sentinel.uart, mock.sentinel.baud)
641+
res = await xbee_api.XBee.probe(DEVICE_CONFIG)
642642
assert res is False
643643
assert mock_connect.call_count == 1
644644
assert mock_connect.await_count == 1
645-
assert mock_connect.call_args[0][0] is mock.sentinel.uart
645+
assert mock_connect.call_args[0][0] == DEVICE_CONFIG
646646
assert mock_at_cmd.call_count == 1
647647
assert mock_api_mode.call_count == 1
648648
assert mock_connect.return_value.close.call_count == 1
@@ -658,11 +658,21 @@ async def test_probe_fail_api_mode(mock_connect, mock_at_cmd, mock_api_mode):
658658
mock_api_mode.reset_mock()
659659
mock_at_cmd.reset_mock()
660660
mock_connect.reset_mock()
661-
res = await xbee_api.XBee.probe(mock.sentinel.uart, mock.sentinel.baud)
661+
res = await xbee_api.XBee.probe(DEVICE_CONFIG)
662662
assert res is False
663663
assert mock_connect.call_count == 1
664664
assert mock_connect.await_count == 1
665-
assert mock_connect.call_args[0][0] is mock.sentinel.uart
665+
assert mock_connect.call_args[0][0] == DEVICE_CONFIG
666666
assert mock_at_cmd.call_count == 1
667667
assert mock_api_mode.call_count == 1
668668
assert mock_connect.return_value.close.call_count == 1
669+
670+
671+
@pytest.mark.asyncio
672+
@mock.patch.object(xbee_api.XBee, "connect")
673+
async def test_xbee_new(conn_mck):
674+
"""Test new class method."""
675+
api = await xbee_api.XBee.new(mock.sentinel.application, DEVICE_CONFIG)
676+
assert isinstance(api, xbee_api.XBee)
677+
assert conn_mck.call_count == 1
678+
assert conn_mck.await_count == 1

tests/test_application.py

Lines changed: 24 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,34 @@
11
import asyncio
2-
from unittest import mock
32

3+
from asynctest import CoroutineMock, mock
44
import pytest
55
from zigpy import types as t
66
from zigpy.zdo.types import ZDOCmd
77

88
from zigpy_xbee.api import ModemStatus, XBee
9+
import zigpy_xbee.config as config
910
import zigpy_xbee.types as xbee_t
1011
from zigpy_xbee.zigbee import application
1112

13+
APP_CONFIG = {
14+
config.CONF_DEVICE: {
15+
config.CONF_DEVICE_PATH: "/dev/null",
16+
config.CONF_DEVICE_BAUDRATE: 115200,
17+
},
18+
config.CONF_DATABASE: None,
19+
}
20+
1221

1322
@pytest.fixture
14-
def app(monkeypatch, database_file=None):
23+
def app(monkeypatch):
1524
monkeypatch.setattr(application, "TIMEOUT_TX_STATUS", 0.1)
1625
monkeypatch.setattr(application, "TIMEOUT_REPLY", 0.1)
1726
monkeypatch.setattr(application, "TIMEOUT_REPLY_EXTENDED", 0.1)
18-
return application.ControllerApplication(XBee(), database_file=database_file)
27+
app = application.ControllerApplication(APP_CONFIG)
28+
api = XBee(APP_CONFIG[config.CONF_DEVICE])
29+
monkeypatch.setattr(api, "_command", CoroutineMock())
30+
app._api = api
31+
return app
1932

2033

2134
def test_modem_status(app):
@@ -188,11 +201,7 @@ async def test_broadcast(app):
188201
b"\x02\x01\x00",
189202
)
190203

191-
app._api._command = mock.MagicMock(
192-
side_effect=asyncio.coroutine(
193-
mock.MagicMock(return_value=xbee_t.TXStatus.SUCCESS)
194-
)
195-
)
204+
app._api._command.return_value = xbee_t.TXStatus.SUCCESS
196205

197206
r = await app.broadcast(profile, cluster, src_ep, dst_ep, grpid, radius, tsn, data)
198207
assert r[0] == xbee_t.TXStatus.SUCCESS
@@ -202,17 +211,11 @@ async def test_broadcast(app):
202211
assert app._api._command.call_args[0][4] == dst_ep
203212
assert app._api._command.call_args[0][9] == data
204213

205-
app._api._command = mock.MagicMock(
206-
side_effect=asyncio.coroutine(
207-
mock.MagicMock(return_value=xbee_t.TXStatus.ADDRESS_NOT_FOUND)
208-
)
209-
)
214+
app._api._command.return_value = xbee_t.TXStatus.ADDRESS_NOT_FOUND
210215
r = await app.broadcast(profile, cluster, src_ep, dst_ep, grpid, radius, tsn, data)
211216
assert r[0] != xbee_t.TXStatus.SUCCESS
212217

213-
app._api._command = mock.MagicMock(
214-
side_effect=asyncio.coroutine(mock.MagicMock(side_effect=asyncio.TimeoutError))
215-
)
218+
app._api._command.side_effect = asyncio.TimeoutError
216219
r = await app.broadcast(profile, cluster, src_ep, dst_ep, grpid, radius, tsn, data)
217220
assert r[0] != xbee_t.TXStatus.SUCCESS
218221

@@ -304,19 +307,17 @@ async def _at_command_mock(cmd, *args):
304307
"ZS": zs,
305308
}.get(cmd, None)
306309

307-
app._api._at_command = mock.MagicMock(
308-
spec=XBee._at_command, side_effect=_at_command_mock
309-
)
310-
311310
async def init_api_mode_mock():
312311
nonlocal api_mode
313312
api_mode = api_config_succeeds
314313
return api_config_succeeds
315314

316-
app._api.init_api_mode = mock.MagicMock(side_effect=init_api_mode_mock)
317-
app.form_network = mock.MagicMock(side_effect=asyncio.coroutine(mock.MagicMock()))
315+
app.form_network = CoroutineMock()
318316

319-
await app.startup(auto_form=auto_form)
317+
with mock.patch.object(XBee, "new") as api:
318+
api.return_value._at_command = CoroutineMock(side_effect=_at_command_mock)
319+
api.return_value.init_api_mode = CoroutineMock(side_effect=init_api_mode_mock)
320+
await app.startup(auto_form=auto_form)
320321
return app
321322

322323

tests/test_uart.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@
55
import serial_asyncio
66

77
from zigpy_xbee import uart
8+
import zigpy_xbee.config
9+
10+
DEVICE_CONFIG = zigpy_xbee.config.SCHEMA_DEVICE(
11+
{zigpy_xbee.config.CONF_DEVICE_PATH: "/dev/null"}
12+
)
813

914

1015
@pytest.fixture
@@ -29,7 +34,6 @@ def test_baudrate_fail(gw):
2934
@pytest.mark.asyncio
3035
async def test_connect(monkeypatch):
3136
api = mock.MagicMock()
32-
portmock = mock.MagicMock()
3337

3438
async def mock_conn(loop, protocol_factory, **kwargs):
3539
protocol = protocol_factory()
@@ -38,7 +42,7 @@ async def mock_conn(loop, protocol_factory, **kwargs):
3842

3943
monkeypatch.setattr(serial_asyncio, "create_serial_connection", mock_conn)
4044

41-
await uart.connect(portmock, 57600, api)
45+
await uart.connect(DEVICE_CONFIG, api)
4246

4347

4448
def test_command_mode_rsp(gw):

zigpy_xbee/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
MAJOR_VERSION = 0
2-
MINOR_VERSION = 11
2+
MINOR_VERSION = 12
33
PATCH_VERSION = "0"
44
__short_version__ = "{}.{}".format(MAJOR_VERSION, MINOR_VERSION)
55
__version__ = "{}.{}".format(__short_version__, PATCH_VERSION)

0 commit comments

Comments
 (0)