From b3aac2e7b0016b4738aeabd5cdfe051ec0c2c26a Mon Sep 17 00:00:00 2001 From: Alexei Chetroi Date: Sat, 27 Nov 2021 20:01:57 -0500 Subject: [PATCH 01/10] 0.15.0.dev0 version bump --- zigpy_deconz/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zigpy_deconz/__init__.py b/zigpy_deconz/__init__.py index f72dbbc..aa3f67a 100644 --- a/zigpy_deconz/__init__.py +++ b/zigpy_deconz/__init__.py @@ -2,7 +2,7 @@ # coding: utf-8 MAJOR_VERSION = 0 -MINOR_VERSION = 14 +MINOR_VERSION = 15 PATCH_VERSION = "0.dev0" __short_version__ = f"{MAJOR_VERSION}.{MINOR_VERSION}" __version__ = f"{__short_version__}.{PATCH_VERSION}" From 22f07a4cce0f256b49b077827c6a9b26bc586250 Mon Sep 17 00:00:00 2001 From: Florian Freund Date: Thu, 9 Dec 2021 17:19:35 +0100 Subject: [PATCH 02/10] Add support for tcp forwarded serial ports (#176) * Add support for tcp forwarded serial ports * Format code --- zigpy_deconz/uart.py | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/zigpy_deconz/uart.py b/zigpy_deconz/uart.py index d26dfdb..f75f9dd 100644 --- a/zigpy_deconz/uart.py +++ b/zigpy_deconz/uart.py @@ -4,6 +4,7 @@ import binascii import logging from typing import Callable, Dict +import urllib.parse import serial import serial_asyncio @@ -139,15 +140,21 @@ async def connect(config: Dict[str, str], api: Callable, loop=None) -> Gateway: connected_future = asyncio.Future() protocol = Gateway(api, connected_future) - _, protocol = await serial_asyncio.create_serial_connection( - loop, - lambda: protocol, - url=config[CONF_DEVICE_PATH], - baudrate=DECONZ_BAUDRATE, - parity=serial.PARITY_NONE, - stopbits=serial.STOPBITS_ONE, - xonxoff=False, - ) + parsed_path = urllib.parse.urlparse(config[CONF_DEVICE_PATH]) + if parsed_path.scheme == "tcp": + _, protocol = await loop.create_connection( + lambda: protocol, parsed_path.hostname, parsed_path.port + ) + else: + _, protocol = await serial_asyncio.create_serial_connection( + loop, + lambda: protocol, + url=config[CONF_DEVICE_PATH], + baudrate=DECONZ_BAUDRATE, + parity=serial.PARITY_NONE, + stopbits=serial.STOPBITS_ONE, + xonxoff=False, + ) await connected_future From 6560731b162b9062b764c11ef9cedc3ab94af163 Mon Sep 17 00:00:00 2001 From: Alexei Chetroi Date: Sun, 9 Jan 2022 21:32:21 -0500 Subject: [PATCH 03/10] Revert "Updated README.md with info on how-to test new releases (#111)" (#178) This reverts commit 282cc0a0cc01d2ecc666c29e9f1de25f0a0b7a7a. --- README.md | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/README.md b/README.md index fba285c..37319e8 100644 --- a/README.md +++ b/README.md @@ -9,28 +9,6 @@ The goal of this project to add native support for the Dresden-Elektronik deCONZ This library uses the deCONZ serial protocol for communicating with [ConBee](https://www.dresden-elektronik.de/conbee/), [ConBee II (ConBee 2)](https://shop.dresden-elektronik.de/conbee-2.html), and [RaspBee](https://www.dresden-elektronik.de/raspbee/) adapters from [Dresden-Elektronik](https://github.com/dresden-elektronik/). -# Testing new releases - -Testing a new release of the zigpy-deconz library before it is released in Home Assistant. - -If you are using Supervised Home Assistant (formerly known as the Hassio/Hass.io distro): -- Add https://github.com/home-assistant/hassio-addons-development as "add-on" repository -- Install "Custom deps deployment" addon -- Update config like: - ``` - pypi: - - zigpy-deconz==0.9.0 - apk: [] - ``` - where 0.5.1 is the new version -- Start the addon - -If you are instead using some custom python installation of Home Assistant then do this: -- Activate your python virtual env -- Update package with ``pip`` - ``` - pip install zigpy-deconz==0.9.0 - # Releases via PyPI Tagged versions are also released via PyPI From a8412d323175b6d3665cff96506e56969513b971 Mon Sep 17 00:00:00 2001 From: puddly <32534428+puddly@users.noreply.github.com> Date: Sun, 6 Mar 2022 13:28:21 -0500 Subject: [PATCH 04/10] Use manual source routes when retrying and enable APS ACKs (#182) * Add support for manual source routes * Untested implementation * Fix existing unit tests * Runtime test the code * Force requests to send when a route is unknown * Add unit tests * Use APS ACKs by default --- tests/test_api.py | 27 ++++++++++++- tests/test_application.py | 58 +++++++++++++++++++++++++--- tests/test_types.py | 16 ++++++++ zigpy_deconz/api.py | 49 +++++++++++++++++++----- zigpy_deconz/types.py | 61 ++++++++++++++++++++++++++++++ zigpy_deconz/zigbee/application.py | 47 ++++++++++++++++------- 6 files changed, 227 insertions(+), 31 deletions(-) diff --git a/tests/test_api.py b/tests/test_api.py index 9fdc94a..91c7d66 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -2,6 +2,7 @@ import asyncio import binascii +import enum import logging import pytest @@ -146,13 +147,15 @@ def mock_api_frame(name, *args): def _fake_args(arg_type): - if isinstance(arg_type(), t.DeconzAddressEndpoint): + if issubclass(arg_type, enum.Enum): + return list(arg_type)[0] # Pick the first enum value + elif issubclass(arg_type, t.DeconzAddressEndpoint): addr = t.DeconzAddressEndpoint() addr.address_mode = t.ADDRESS_MODE.NWK addr.address = t.uint8_t(0) addr.endpoint = t.uint8_t(0) return addr - if isinstance(arg_type(), t.EUI64): + elif issubclass(arg_type, t.EUI64): return t.EUI64([0x01] * 8) return arg_type() @@ -609,3 +612,23 @@ async def test_set_item(api): assert write_mock.await_count == 1 assert write_mock.call_args[0][0] == "test" assert write_mock.call_args[0][1] is sentinel.test_param + + +@pytest.mark.parametrize("relays", (None, [], [0x1234, 0x5678])) +async def test_aps_data_request_relays(relays, api): + mock_cmd = api._command = AsyncMock() + + await api.aps_data_request( + 0x00, # req id + t.DeconzAddressEndpoint.deserialize(b"\x02\xaa\x55\x01")[0], # dst + ep + 0x0104, # profile id + 0x0007, # cluster id + 0x01, # src ep + b"aps payload", + relays=relays, + ) + assert mock_cmd.call_count == 1 + + if relays: + assert isinstance(mock_cmd.mock_calls[0][1][-1], t.NWKList) + assert mock_cmd.mock_calls[0][1][-1] == t.NWKList(relays) diff --git a/tests/test_application.py b/tests/test_application.py index 1b36dd6..84981cd 100644 --- a/tests/test_application.py +++ b/tests/test_application.py @@ -315,10 +315,21 @@ async def test_permit(app, nwk): assert app._api.write_parameter.call_args_list[0][0][1] == time_s -async def _test_request(app, send_success=True, aps_data_error=False, **kwargs): +async def _test_request(app, *, send_success=True, aps_data_error=False, **kwargs): seq = 123 - async def req_mock(req_id, dst_addr_ep, profile, cluster, src_ep, data): + async def req_mock( + req_id, + dst_addr_ep, + profile, + cluster, + src_ep, + data, + *, + relays=None, + tx_options=t.DeconzTransmitOptions.USE_NWK_KEY_SECURITY, + radius=0 + ): if aps_data_error: raise zigpy_deconz.exception.CommandError(1, "Command Error") if send_success: @@ -327,6 +338,7 @@ async def req_mock(req_id, dst_addr_ep, profile, cluster, src_ep, data): app._pending[req_id].result.set_result(1) app._api.aps_data_request = MagicMock(side_effect=req_mock) + app._api.protocol_version = 0 device = zigpy.device.Device(app, sentinel.ieee, 0x1122) app.get_device = MagicMock(return_value=device) @@ -336,27 +348,61 @@ async def req_mock(req_id, dst_addr_ep, profile, cluster, src_ep, data): async def test_request_send_success(app): req_id = sentinel.req_id app.get_sequence = MagicMock(return_value=req_id) - r = await _test_request(app, True) + r = await _test_request(app, send_success=True) assert r[0] == 0 - r = await _test_request(app, True, use_ieee=True) + r = await _test_request(app, send_success=True, use_ieee=True) assert r[0] == 0 async def test_request_send_fail(app): req_id = sentinel.req_id app.get_sequence = MagicMock(return_value=req_id) - r = await _test_request(app, False) + r = await _test_request(app, send_success=False) assert r[0] != 0 async def test_request_send_aps_data_error(app): req_id = sentinel.req_id app.get_sequence = MagicMock(return_value=req_id) - r = await _test_request(app, False, aps_data_error=True) + r = await _test_request(app, send_success=False, aps_data_error=True) assert r[0] != 0 +async def test_request_retry(app): + req_id = sentinel.req_id + app.get_sequence = MagicMock(return_value=req_id) + + device = zigpy.device.Device(app, sentinel.ieee, 0x1122) + device.relays = [0x5678, 0x1234] + app.get_device = MagicMock(return_value=device) + + async def req_mock( + req_id, + dst_addr_ep, + profile, + cluster, + src_ep, + data, + *, + relays=None, + tx_options=t.DeconzTransmitOptions.USE_NWK_KEY_SECURITY, + radius=0 + ): + app._pending[req_id].result.set_result(1) + + app._api.aps_data_request = MagicMock(side_effect=req_mock) + app._api.protocol_version = application.PROTO_VER_MANUAL_SOURCE_ROUTE + + await app.request(device, 0x0260, 1, 2, 3, 123, b"\x01\x02\x03") + + assert len(app._api.aps_data_request.mock_calls) == 2 + without_relays, with_relays = app._api.aps_data_request.mock_calls + + assert without_relays[2]["relays"] is None + assert with_relays[2]["relays"] == [0x0000, 0x1234, 0x5678] + + async def _test_broadcast(app, send_success=True, aps_data_error=False, **kwargs): seq = sentinel.req_id diff --git a/tests/test_types.py b/tests/test_types.py index f02d052..ee6a236 100644 --- a/tests/test_types.py +++ b/tests/test_types.py @@ -277,3 +277,19 @@ def test_deconz_addr_ep(): a.serialize() a.endpoint = 0xCC assert a.serialize() == data + + +def test_nwklist(): + assert t.NWKList([]).serialize() == b"\x00" + assert t.NWKList([0x1234]).serialize() == b"\x01" + t.NWK(0x1234).serialize() + assert ( + t.NWKList([0x1234, 0x5678]).serialize() + == b"\x02" + t.NWK(0x1234).serialize() + t.NWK(0x5678).serialize() + ) + + assert t.NWKList.deserialize(b"\x00abc") == (t.NWKList([]), b"abc") + assert t.NWKList.deserialize(b"\x01\x34\x12abc") == (t.NWKList([0x1234]), b"abc") + assert t.NWKList.deserialize(b"\x02\x34\x12\x78\x56abc") == ( + t.NWKList([0x1234, 0x5678]), + b"abc", + ) diff --git a/zigpy_deconz/api.py b/zigpy_deconz/api.py index 756f4bf..7120ce2 100644 --- a/zigpy_deconz/api.py +++ b/zigpy_deconz/api.py @@ -98,7 +98,7 @@ def _missing_(cls, value): Command.aps_data_request: ( t.uint16_t, t.uint8_t, - t.uint8_t, + t.DeconzSendDataFlags, t.DeconzAddressEndpoint, t.uint16_t, t.uint16_t, @@ -106,6 +106,7 @@ def _missing_(cls, value): t.LVBytes, t.uint8_t, t.uint8_t, + t.NWKList, # optional ), Command.change_network_state: (t.uint8_t,), Command.device_state: (t.uint8_t, t.uint8_t, t.uint8_t), @@ -515,33 +516,61 @@ def _handle_aps_data_indication(self, data): ) # rssi async def aps_data_request( - self, req_id, dst_addr_ep, profile, cluster, src_ep, aps_payload + self, + req_id, + dst_addr_ep, + profile, + cluster, + src_ep, + aps_payload, + *, + relays=None, + tx_options=t.DeconzTransmitOptions.USE_NWK_KEY_SECURITY, + radius=0, ): dst = dst_addr_ep.serialize() length = len(dst) + len(aps_payload) + 11 delays = (0.5, 1.0, 1.5, None) + + flags = t.DeconzSendDataFlags.NONE + extras = [] + + # https://github.com/zigpy/zigpy-deconz/issues/180#issuecomment-1017932865 + if relays: + # There is a max of 9 relays + assert len(relays) <= 9 + + # APS ACKs should be used to mitigate errors. + tx_options |= t.DeconzTransmitOptions.USE_APS_ACKS + + flags |= t.DeconzSendDataFlags.RELAYS + extras.append(t.NWKList(relays)) + + length += sum(len(e.serialize()) for e in extras) + for delay in delays: try: return await self._command( Command.aps_data_request, length, req_id, - 0, + flags, dst_addr_ep, profile, cluster, src_ep, aps_payload, - 2, - 0, + tx_options, + radius, + *extras, ) except CommandError as ex: LOGGER.debug("'aps_data_request' failure: %s", ex) - if delay is not None and ex.status == Status.BUSY: - LOGGER.debug("retrying 'aps_data_request' in %ss", delay) - await asyncio.sleep(delay) - continue - raise + if delay is None or ex.status != Status.BUSY: + raise + + LOGGER.debug("retrying 'aps_data_request' in %ss", delay) + await asyncio.sleep(delay) def _handle_aps_data_request(self, data): LOGGER.debug("APS data request response: %s", data) diff --git a/zigpy_deconz/types.py b/zigpy_deconz/types.py index bb8931a..56feee6 100644 --- a/zigpy_deconz/types.py +++ b/zigpy_deconz/types.py @@ -126,6 +126,43 @@ class ADDRESS_MODE(uint8_t, enum.Enum): NWK_AND_IEEE = 0x04 +def bitmap_factory(int_type: uint_t) -> enum.Flag: + class _NewEnum(int_type, enum.Flag): + # Rebind classmethods to our own class + _missing_ = classmethod(enum.IntFlag._missing_.__func__) + _create_pseudo_member_ = classmethod( + enum.IntFlag._create_pseudo_member_.__func__ + ) + + __or__ = enum.IntFlag.__or__ + __and__ = enum.IntFlag.__and__ + __xor__ = enum.IntFlag.__xor__ + __ror__ = enum.IntFlag.__ror__ + __rand__ = enum.IntFlag.__rand__ + __rxor__ = enum.IntFlag.__rxor__ + __invert__ = enum.IntFlag.__invert__ + + return _NewEnum + + +class bitmap8(bitmap_factory(uint8_t)): + pass + + +class DeconzSendDataFlags(bitmap8): + NONE = 0x00 + NODE_ID = 0x01 + RELAYS = 0x02 + + +class DeconzTransmitOptions(bitmap8): + NONE = 0x00 + SECURITY_ENABLED = 0x01 + USE_NWK_KEY_SECURITY = 0x02 + USE_APS_ACKS = 0x04 + ALLOW_FRAGMENTATION = 0x08 + + class Struct: _fields = [] @@ -182,6 +219,25 @@ def deserialize(cls, data): return r, data +class LVList(list): + _length_type = None + _itemtype = None + + def serialize(self): + return self._length_type(len(self)).serialize() + b"".join( + [self._itemtype(i).serialize() for i in self] + ) + + @classmethod + def deserialize(cls, data): + length, data = cls._length_type.deserialize(data) + r = cls() + for _ in range(length): + item, data = cls._itemtype.deserialize(data) + r.append(item) + return r, data + + class FixedList(List): _length = None _itemtype = None @@ -235,6 +291,11 @@ class ExtendedPanId(EUI64): pass +class NWKList(LVList): + _length_type = uint8_t + _itemtype = NWK + + class DeconzAddress(Struct): _fields = [ # The address format (AddressMode) diff --git a/zigpy_deconz/zigbee/application.py b/zigpy_deconz/zigbee/application.py index 2502f50..5d57358 100644 --- a/zigpy_deconz/zigbee/application.py +++ b/zigpy_deconz/zigbee/application.py @@ -26,6 +26,7 @@ CHANGE_NETWORK_WAIT = 1 DELAY_NEIGHBOUR_SCAN_S = 1500 SEND_CONFIRM_TIMEOUT = 60 +PROTO_VER_MANUAL_SOURCE_ROUTE = 0x010C PROTO_VER_WATCHDOG = 0x0108 PROTO_VER_NEIGBOURS = 0x0107 WATCHDOG_TTL = 600 @@ -208,7 +209,7 @@ async def mrequest( data, *, hops=0, - non_member_radius=3 + non_member_radius=3, ): """Submit and send data out as a multicast transmission. @@ -281,21 +282,41 @@ async def request( dst_addr_ep.address_mode = t.uint8_t(t.ADDRESS_MODE.NWK) dst_addr_ep.address = device.nwk - with self._pending.new(req_id) as req: - try: - await self._api.aps_data_request( - req_id, dst_addr_ep, profile, cluster, min(1, src_ep), data - ) - except zigpy_deconz.exception.CommandError as ex: - return ex.status, "Couldn't enqueue send data request: {}".format(ex) - - r = await asyncio.wait_for(req.result, SEND_CONFIRM_TIMEOUT) + relays = None + tx_options = t.DeconzTransmitOptions.USE_NWK_KEY_SECURITY + + if expect_reply: + tx_options |= t.DeconzTransmitOptions.USE_APS_ACKS + + for attempt in (1, 2): + with self._pending.new(req_id) as req: + try: + await self._api.aps_data_request( + req_id, + dst_addr_ep, + profile, + cluster, + min(1, src_ep), + data, + relays=relays, + tx_options=tx_options, + ) + except zigpy_deconz.exception.CommandError as ex: + return ex.status, f"Couldn't enqueue send data request: {ex}" + + r = await asyncio.wait_for(req.result, SEND_CONFIRM_TIMEOUT) + + if not r: + return r, "message send success" - if r: LOGGER.debug("Error while sending %s req id frame: %s", req_id, r) - return r, "message send failure" - return r, "message send success" + if attempt == 2: + return r, "message send failure" + elif self._api.protocol_version >= PROTO_VER_MANUAL_SOURCE_ROUTE: + # Force the request to send by including the coordinator + relays = [0x0000] + (device.relays or [])[::-1] + LOGGER.debug("Trying manual source route: %s", relays) async def broadcast( self, From eb37a24f89bb0b4e48e7af65ec5236a15f80e791 Mon Sep 17 00:00:00 2001 From: "Zigbee for Domoticz, a plugin to connect your Zigbee devices to Domoticz" <96482536+zigbeefordomoticz@users.noreply.github.com> Date: Fri, 11 Mar 2022 17:56:04 +0100 Subject: [PATCH 05/10] Align config with other Zigpy radio libs --- zigpy_deconz/config.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/zigpy_deconz/config.py b/zigpy_deconz/config.py index b010785..b90dded 100644 --- a/zigpy_deconz/config.py +++ b/zigpy_deconz/config.py @@ -2,10 +2,20 @@ import voluptuous as vol from zigpy.config import ( # noqa: F401 pylint: disable=unused-import + CONF_NWK, CONF_DEVICE, - CONF_DEVICE_PATH, + CONF_NWK_KEY, CONFIG_SCHEMA, SCHEMA_DEVICE, + CONF_NWK_PAN_ID, + CONF_DEVICE_PATH, + CONF_NWK_CHANNEL, + CONF_NWK_CHANNELS, + CONF_NWK_UPDATE_ID, + CONF_NWK_TC_ADDRESS, + CONF_NWK_TC_LINK_KEY, + CONF_NWK_EXTENDED_PAN_ID, + cv_boolean, ) CONF_WATCHDOG_TTL = "watchdog_ttl" From 87154e64a08366524a6ce33bb8db37aeaa588c8b Mon Sep 17 00:00:00 2001 From: puddly <32534428+puddly@users.noreply.github.com> Date: Fri, 11 Mar 2022 13:08:41 -0500 Subject: [PATCH 06/10] Fix isort --- zigpy_deconz/config.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/zigpy_deconz/config.py b/zigpy_deconz/config.py index b90dded..f12a056 100644 --- a/zigpy_deconz/config.py +++ b/zigpy_deconz/config.py @@ -2,19 +2,19 @@ import voluptuous as vol from zigpy.config import ( # noqa: F401 pylint: disable=unused-import - CONF_NWK, CONF_DEVICE, - CONF_NWK_KEY, - CONFIG_SCHEMA, - SCHEMA_DEVICE, - CONF_NWK_PAN_ID, CONF_DEVICE_PATH, + CONF_NWK, CONF_NWK_CHANNEL, CONF_NWK_CHANNELS, - CONF_NWK_UPDATE_ID, + CONF_NWK_EXTENDED_PAN_ID, + CONF_NWK_KEY, + CONF_NWK_PAN_ID, CONF_NWK_TC_ADDRESS, CONF_NWK_TC_LINK_KEY, - CONF_NWK_EXTENDED_PAN_ID, + CONF_NWK_UPDATE_ID, + CONFIG_SCHEMA, + SCHEMA_DEVICE, cv_boolean, ) From 2b78625795128239f06b361167399e3e3a3b77db Mon Sep 17 00:00:00 2001 From: puddly <32534428+puddly@users.noreply.github.com> Date: Fri, 1 Apr 2022 15:02:14 -0400 Subject: [PATCH 07/10] Upgrade Black in pre-commit to fix Click dep issue --- .pre-commit-config.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 6d34ff6..4dd9b1a 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/psf/black - rev: 20.8b1 + rev: 22.3.0 hooks: - id: black args: @@ -16,7 +16,7 @@ repos: - pydocstyle==5.1.1 - repo: https://github.com/PyCQA/isort - rev: 5.5.2 + rev: 5.10.1 hooks: - id: isort From 993387bff0903a7313539ba9d1cf9e6064da3d9f Mon Sep 17 00:00:00 2001 From: puddly <32534428+puddly@users.noreply.github.com> Date: Fri, 1 Apr 2022 15:04:01 -0400 Subject: [PATCH 08/10] Re-run isort --- zigpy_deconz/config.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/zigpy_deconz/config.py b/zigpy_deconz/config.py index b90dded..f12a056 100644 --- a/zigpy_deconz/config.py +++ b/zigpy_deconz/config.py @@ -2,19 +2,19 @@ import voluptuous as vol from zigpy.config import ( # noqa: F401 pylint: disable=unused-import - CONF_NWK, CONF_DEVICE, - CONF_NWK_KEY, - CONFIG_SCHEMA, - SCHEMA_DEVICE, - CONF_NWK_PAN_ID, CONF_DEVICE_PATH, + CONF_NWK, CONF_NWK_CHANNEL, CONF_NWK_CHANNELS, - CONF_NWK_UPDATE_ID, + CONF_NWK_EXTENDED_PAN_ID, + CONF_NWK_KEY, + CONF_NWK_PAN_ID, CONF_NWK_TC_ADDRESS, CONF_NWK_TC_LINK_KEY, - CONF_NWK_EXTENDED_PAN_ID, + CONF_NWK_UPDATE_ID, + CONFIG_SCHEMA, + SCHEMA_DEVICE, cv_boolean, ) From 87d56cd93511e80dbc6d0d0c419ed2f7fc488b0a Mon Sep 17 00:00:00 2001 From: puddly <32534428+puddly@users.noreply.github.com> Date: Fri, 1 Apr 2022 15:07:43 -0400 Subject: [PATCH 09/10] Revert "Add support for tcp forwarded serial ports (#176)" This reverts commit 22f07a4cce0f256b49b077827c6a9b26bc586250. --- zigpy_deconz/uart.py | 25 +++++++++---------------- 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/zigpy_deconz/uart.py b/zigpy_deconz/uart.py index f75f9dd..d26dfdb 100644 --- a/zigpy_deconz/uart.py +++ b/zigpy_deconz/uart.py @@ -4,7 +4,6 @@ import binascii import logging from typing import Callable, Dict -import urllib.parse import serial import serial_asyncio @@ -140,21 +139,15 @@ async def connect(config: Dict[str, str], api: Callable, loop=None) -> Gateway: connected_future = asyncio.Future() protocol = Gateway(api, connected_future) - parsed_path = urllib.parse.urlparse(config[CONF_DEVICE_PATH]) - if parsed_path.scheme == "tcp": - _, protocol = await loop.create_connection( - lambda: protocol, parsed_path.hostname, parsed_path.port - ) - else: - _, protocol = await serial_asyncio.create_serial_connection( - loop, - lambda: protocol, - url=config[CONF_DEVICE_PATH], - baudrate=DECONZ_BAUDRATE, - parity=serial.PARITY_NONE, - stopbits=serial.STOPBITS_ONE, - xonxoff=False, - ) + _, protocol = await serial_asyncio.create_serial_connection( + loop, + lambda: protocol, + url=config[CONF_DEVICE_PATH], + baudrate=DECONZ_BAUDRATE, + parity=serial.PARITY_NONE, + stopbits=serial.STOPBITS_ONE, + xonxoff=False, + ) await connected_future From 39e04c165fb740350c0d993ba38584f2b02a9e68 Mon Sep 17 00:00:00 2001 From: puddly <32534428+puddly@users.noreply.github.com> Date: Fri, 1 Apr 2022 15:17:39 -0400 Subject: [PATCH 10/10] Bump version to 0.15.0 --- zigpy_deconz/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zigpy_deconz/__init__.py b/zigpy_deconz/__init__.py index aa3f67a..a0c1fe1 100644 --- a/zigpy_deconz/__init__.py +++ b/zigpy_deconz/__init__.py @@ -3,6 +3,6 @@ # coding: utf-8 MAJOR_VERSION = 0 MINOR_VERSION = 15 -PATCH_VERSION = "0.dev0" +PATCH_VERSION = "0" __short_version__ = f"{MAJOR_VERSION}.{MINOR_VERSION}" __version__ = f"{__short_version__}.{PATCH_VERSION}"