Skip to content

Commit d619b22

Browse files
authored
WIP Use NWK and IEEE addressing mode for ConBee I (#74)
* Support nwk and ieee addressing mode. For protocol versions 0x010B and newer use NWK and IEEE addressing mode when retrieving APS data from Conbee I controller. * Update tests.
1 parent f75bb43 commit d619b22

File tree

4 files changed

+67
-7
lines changed

4 files changed

+67
-7
lines changed

tests/test_api.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -350,3 +350,29 @@ async def test_write_parameter(api):
350350
assert unk_param not in list(deconz_api.NetworkParameter)
351351
with pytest.raises(KeyError):
352352
await api.write_parameter(unk_param, 0x55aa)
353+
354+
355+
@pytest.mark.parametrize(
356+
"protocol_ver, firmware_version, flags",
357+
[
358+
(0x010A, 0x123405dd, 0x01),
359+
(0x010B, 0x123405dd, 0x04),
360+
(0x010A, 0x123407dd, 0x01),
361+
(0x010B, 0x123407dd, 0x01),
362+
],
363+
)
364+
@pytest.mark.asyncio
365+
async def test_version(protocol_ver, firmware_version, flags, api):
366+
api.read_parameter = mock.MagicMock()
367+
api.read_parameter.side_effect = asyncio.coroutine(
368+
mock.MagicMock(return_value=protocol_ver))
369+
api._command = mock.MagicMock()
370+
api._command.side_effect = asyncio.coroutine(
371+
mock.MagicMock(return_value=[firmware_version]))
372+
r = await api.version()
373+
assert r == firmware_version
374+
assert api._aps_data_ind_flags == flags
375+
376+
377+
def test_handle_version(api):
378+
api._handle_version([mock.sentinel.version])

tests/test_application.py

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,15 @@ def addr_nwk(nwk):
4646
return addr
4747

4848

49+
@pytest.fixture
50+
def addr_nwk_and_ieee(nwk, ieee):
51+
addr = t.DeconzAddress()
52+
addr.address_mode = t.ADDRESS_MODE.NWK_AND_IEEE
53+
addr.address = nwk
54+
addr.ieee = ieee
55+
return addr
56+
57+
4958
def _test_rx(app, addr_ieee, addr_nwk, device, data):
5059
app.get_device = mock.MagicMock(return_value=device)
5160
app.devices = (EUI64(addr_ieee.address), )
@@ -96,6 +105,23 @@ def test_rx_ieee(app, addr_ieee, addr_nwk):
96105
)
97106

98107

108+
def test_rx_nwk_ieee(app, addr_ieee, addr_nwk_and_ieee):
109+
device = mock.MagicMock()
110+
app.handle_message = mock.MagicMock()
111+
_test_rx(app, addr_ieee, addr_nwk_and_ieee, device, mock.sentinel.args)
112+
assert app.handle_message.call_count == 1
113+
assert app.handle_message.call_args == (
114+
(
115+
device,
116+
mock.sentinel.profile_id,
117+
mock.sentinel.cluster_id,
118+
mock.sentinel.src_ep,
119+
mock.sentinel.dst_ep,
120+
mock.sentinel.args,
121+
),
122+
)
123+
124+
99125
def test_rx_wrong_addr_mode(app, addr_ieee, addr_nwk, caplog):
100126
device = mock.MagicMock()
101127
app.handle_message = mock.MagicMock()
@@ -160,7 +186,7 @@ async def test_form_network(app):
160186
async def test_startup(app, monkeypatch, version=0):
161187

162188
async def _version():
163-
return [version]
189+
return version
164190

165191
app.form_network = mock.MagicMock(
166192
side_effect=asyncio.coroutine(mock.MagicMock()))

zigpy_deconz/api.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
COMMAND_TIMEOUT = 2
1313
DECONZ_BAUDRATE = 38400
14+
MIN_PROTO_VERSION = 0x010B
1415

1516

1617
class Command(t.uint8_t, enum.Enum):
@@ -145,6 +146,8 @@ def __init__(self):
145146
self.network_state = NetworkState.OFFLINE
146147
self._data_indication = False
147148
self._data_confirm = False
149+
self._proto_ver = None
150+
self._aps_data_ind_flags = 0x01
148151

149152
def set_application(self, app):
150153
self._app = app
@@ -262,8 +265,12 @@ def _handle_write_parameter(self, data):
262265
return
263266
LOGGER.debug("Write parameter %s: SUCCESS", param.name)
264267

265-
def version(self):
266-
return self._command(Command.version)
268+
async def version(self):
269+
self._proto_ver = await self[NetworkParameter.protocol_version]
270+
version = await self._command(Command.version)
271+
if self._proto_ver >= MIN_PROTO_VERSION and (version[0] & 0x0000FF00) == 0x00000500:
272+
self._aps_data_ind_flags = 0x04
273+
return version[0]
267274

268275
def _handle_version(self, data):
269276
LOGGER.debug("Version response: %x", data[0])
@@ -274,7 +281,7 @@ def _handle_device_state_changed(self, data):
274281

275282
async def _aps_data_indication(self):
276283
try:
277-
r = await self._command(Command.aps_data_indication, 1, 1)
284+
r = await self._command(Command.aps_data_indication, 1, self._aps_data_ind_flags)
278285
LOGGER.debug(("'aps_data_indication' response from %s, ep: %s, "
279286
"profile: 0x%04x, cluster_id: 0x%04x, data: %s"),
280287
r[4], r[5], r[6], r[7], binascii.hexlify(r[8]))

zigpy_deconz/zigbee/application.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,7 @@ async def shutdown(self):
4141

4242
async def startup(self, auto_form=False):
4343
"""Perform a complete application startup"""
44-
r = await self._api.version()
45-
self.version = r[0]
44+
self.version = await self._api.version()
4645
await self._api.device_state()
4746
ieee = await self._api[NetworkParameter.mac_address]
4847
self._ieee = zigpy.types.EUI64(ieee)
@@ -163,7 +162,9 @@ def handle_rx(self, src_addr, src_ep, dst_ep, profile_id, cluster_id, data, lqi,
163162
self.handle_join(nwk, ieee, 0)
164163

165164
try:
166-
if src_addr.address_mode == t.ADDRESS_MODE.NWK.value:
165+
if src_addr.address_mode == t.ADDRESS_MODE.NWK_AND_IEEE:
166+
device = self.get_device(ieee=src_addr.ieee)
167+
elif src_addr.address_mode == t.ADDRESS_MODE.NWK.value:
167168
device = self.get_device(nwk=src_addr.address)
168169
elif src_addr.address_mode == t.ADDRESS_MODE.IEEE.value:
169170
device = self.get_device(ieee=src_addr.address)

0 commit comments

Comments
 (0)