Skip to content

Commit 7ce14e2

Browse files
authored
Release 0.7.0
Release 0.7.0
2 parents 3a48b14 + 77b145d commit 7ce14e2

20 files changed

+1169
-146
lines changed

.github/release-drafter.yml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
name-template: '$NEXT_PATCH_VERSION Release.'
2+
tag-template: '$NEXT_PATCH_VERSION'
3+
categories:
4+
- title: 'Breaking changes'
5+
labels:
6+
- 'breaking'
7+
- title: '🚀 Features'
8+
labels:
9+
- 'feature'
10+
- 'enhancement'
11+
- title: '🐛 Bug Fixes'
12+
labels:
13+
- 'fix'
14+
- 'bugfix'
15+
- 'bug'
16+
- title: '🧰 Maintenance'
17+
label: 'chore'
18+
change-template: '- $TITLE @$AUTHOR (#$NUMBER)'
19+
template: |
20+
## Changes
21+
22+
$CHANGES
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
name: Release Management
2+
3+
on:
4+
push:
5+
# branches to consider in the event; optional, defaults to all
6+
branches:
7+
- master
8+
9+
jobs:
10+
update_draft_release:
11+
runs-on: ubuntu-latest
12+
steps:
13+
# Drafts your next Release notes as Pull Requests are merged into "master"
14+
- uses: release-drafter/release-drafter@v5
15+
env:
16+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

.github/workflows/tests.yml

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
name: Build & Tests
2+
3+
on:
4+
push:
5+
branches: [ master, dev ]
6+
pull_request:
7+
branches: [ master, dev ]
8+
9+
jobs:
10+
build:
11+
12+
runs-on: ubuntu-latest
13+
strategy:
14+
matrix:
15+
python-version: [3.7, 3.8, 3.9]
16+
17+
steps:
18+
- uses: actions/checkout@v2
19+
- name: Set up Python ${{ matrix.python-version }}
20+
uses: actions/setup-python@v2
21+
with:
22+
python-version: ${{ matrix.python-version }}
23+
- name: Install dependencies
24+
run: |
25+
python -m pip install --upgrade pip
26+
pip install flake8 pytest pytest-asyncio mock
27+
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
28+
pip install -e "."
29+
- name: Lint with flake8
30+
run: |
31+
# stop the build if there are Python syntax errors or undefined names
32+
flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
33+
# exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
34+
flake8 . --count --exit-zero --max-complexity=16 --max-line-length=127 --statistics
35+
- name: Test with pytest
36+
run: |
37+
pytest
38+
39+
markdownlint:
40+
41+
runs-on: ubuntu-latest
42+
name: Test Markdown
43+
steps:
44+
- name: Run mdl
45+
uses: actionshub/markdownlint@master

.travis.yml

Lines changed: 0 additions & 13 deletions
This file was deleted.

README.md

Lines changed: 66 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# zigpy-zigate
22

3-
[![Build Status](https://travis-ci.com/zigpy/zigpy-zigate.svg?branch=master)](https://travis-ci.com/zigpy/zigpy-zigate)
3+
![Build & Tests](https://github.com/zigpy/zigpy-zigate/workflows/Build%20&%20Tests/badge.svg?branch=master)
44
[![Coverage](https://coveralls.io/repos/github/zigpy/zigpy-zigate/badge.svg?branch=master)](https://coveralls.io/github/zigpy/zigpy-zigate?branch=master)
55

66
**WARNING: EXPERIMENTAL! This project is under development as WIP (work in progress). Developer’s work provided “AS IS”.**
@@ -14,29 +14,57 @@ ZiGate is a open source ZigBee adapter hardware that was initially launched on K
1414
- https://www.zigate.fr
1515
- https://www.kickstarter.com/projects/1361563794/zigate-universal-zigbee-gateway-for-smarthome
1616

17-
## Compatible hardware
17+
## Hardware and firmware compatibility
1818
The ZiGate USB adapter communicates via a PL-2303HX USB to Serial Bridge Controller module by Prolific.
1919
There's also a Wi-Fi adapter to communicate with ZiGate over network.
2020

21-
Note! ZiGate open source ZigBee adapter hardware requires ZiGate firmware 3.1a or later to work with this zigpy-zigate module.
21+
Note! ZiGate open source ZigBee USB and GPIO adapter hardware requires ZiGate 3.1a firmware or later to work with this zigpy-zigate module, however ZiGate 3.1d firmware or later is recommended as it contains a specific bug-fix related to zigpy.
2222

2323
### Known working Zigbee radio modules
2424
- [ZiGate USB-TTL](https://zigate.fr/produit/zigate-ttl/)
2525
- [ZiGate USB-DIN](https://zigate.fr/produit/zigate-usb-din/)
2626
- [PiZiGate (ZiGate module for Raspberry Pi GPIO)](https://zigate.fr/produit/pizigate-v1-0/)
27+
- [ZiGate Pack WiFi](https://zigate.fr/produit/zigate-pack-wifi-v1-3/)
2728

2829
### Experimental Zigbee radio modules
29-
- [ZiGate Pack WiFi](https://zigate.fr/produit/zigate-pack-wifi-v1-3/) (work in progress)
30+
- [Open Lumi Gateway](https://github.com/openlumi) - [DIY ZiGate WiFi bridge hacked from an Xiaomi Lumi Gateway with modded OpenWRT firmware](https://github.com/zigpy/zigpy-zigate/issues/59)
3031

3132
## Port configuration
3233

33-
- To configure __usb__ ZiGate port, just specify the port, example : `/dev/ttyUSB0`
34-
- Alternatively you could set port to `auto` to enable automatic usb port discovery
35-
- To configure __pizigate__ port, prefix the port with `pizigate:`, example : `pizigate:/dev/serial0`
36-
- To configure __wifi__ ZiGate, specify IP address and port, example : `socket://192.168.1.10:9999`
34+
- To configure __usb__ ZiGate (USB TTL or DIN) port, just specify the port, example : `/dev/ttyUSB0`
35+
- Alternatively you could manually set port to `auto` to enable automatic usb port discovery
36+
- To configure __pizigate__ port, specify the port, example : `/dev/serial0` or `/dev/ttyAMA0`
37+
- To configure __wifi__ ZiGate, manually specify IP address and port, example : `socket://192.168.1.10:9999`
3738

38-
Note! Requires ZiGate firmware 3.1a and later
39-
- https://zigate.fr/tag/firmware/
39+
__pizigate__ does require some additional adjustements on Raspberry Pi 3/Zero, and 4:
40+
- [Raspberry Pi 3 and Raspberry Pi Zero configuration adjustements](https://zigate.fr/documentation/compatibilite-raspberry-pi-3-et-zero-w/)
41+
- [Raspberry Pi 4 configuration adjustements](https://zigate.fr/documentation/compatibilite-raspberry-pi-4-b/)
42+
43+
## Flasher (ZiGate Firmware Tool)
44+
45+
zigpy-zigate has an integrated Python "flasher" tool to flash firmware updates on your ZiGate (NXP Jennic JN5168).
46+
47+
Thanks to Sander Hoentjen (tjikkun) zigpy-zigate now has an integrated firmware flasher tool!
48+
- [tjikkun original zigate-flasher repo](https://github.com/tjikkun/zigate-flasher)
49+
50+
### Flasher Usage
51+
52+
```bash
53+
usage: python3 -m zigpy_zigate.tools.flasher [-h] -p {/dev/ttyUSB0} [-w WRITE] [-s SAVE] [-u] [-d] [--gpio] [--din]
54+
55+
optional arguments:
56+
-h, --help show this help message and exit
57+
-p {/dev/ttyUSB0}, --serialport {/dev/ttyUSB0}
58+
Serial port, e.g. /dev/ttyUSB0
59+
-w WRITE, --write WRITE
60+
Firmware bin to flash onto the chip
61+
-s SAVE, --save SAVE File to save the currently loaded firmware to
62+
-u, --upgrade Download and flash the lastest available firmware
63+
-d, --debug Set log level to DEBUG
64+
--gpio Configure GPIO for PiZiGate flash
65+
--din Configure USB for ZiGate DIN flash
66+
67+
```
4068

4169
## Testing new releases
4270

@@ -71,6 +99,9 @@ Tagged versions are also released via PyPI
7199
Documents that layout the serial protocol used for ZiGate serial interface communication can be found here:
72100
73101
- https://github.com/fairecasoimeme/ZiGate/tree/master/Protocol
102+
- https://github.com/doudz/zigate
103+
- https://github.com/Neonox31/zigate
104+
- https://github.com/nouknouk/node-zigate
74105
75106
## How to contribute
76107
@@ -82,17 +113,32 @@ Some developers might also be interested in receiving donations in the form of h
82113
83114
## Related projects
84115
85-
### Zigpy
86-
[Zigpy](https://github.com/zigpy/zigpy)** is **[Zigbee protocol stack](https://en.wikipedia.org/wiki/Zigbee)** integration project to implement the **[Zigbee Home Automation](https://www.zigbee.org/)** standard as a Python 3 library. Zigbee Home Automation integration with zigpy allows you to connect one of many off-the-shelf Zigbee adapters using one of the available Zigbee radio library modules compatible with zigpy to control Zigbee based devices. There is currently support for controlling Zigbee device types such as binary sensors (e.g., motion and door sensors), sensors (e.g., temperature sensors), lightbulbs, switches, and fans. A working implementation of zigbe exist in **[Home Assistant](https://www.home-assistant.io)** (Python based open source home automation software) as part of its **[ZHA component](https://www.home-assistant.io/components/zha/)**
116+
#### Zigpy
117+
[Zigpy](https://github.com/zigpy/zigpy) is [Zigbee protocol stack](https://en.wikipedia.org/wiki/Zigbee) integration project to implement the [Zigbee Home Automation](https://www.zigbee.org/) standard as a Python 3 library. Zigbee Home Automation integration with zigpy allows you to connect one of many off-the-shelf Zigbee adapters using one of the available Zigbee radio library modules compatible with zigpy to control Zigbee based devices. There is currently support for controlling Zigbee device types such as binary sensors (e.g., motion and door sensors), sensors (e.g., temperature sensors), lightbulbs, switches, and fans. A working implementation of zigbe exist in [Home Assistant](https://www.home-assistant.io) (Python based open source home automation software) as part of its [ZHA component](https://www.home-assistant.io/components/zha/)
118+
119+
#### ZHA Device Handlers
120+
ZHA deviation handling in Home Assistant relies on the third-party [ZHA Device Handlers](https://github.com/zigpy/zha-device-handlers) project. Zigbee devices that deviate from or do not fully conform to the standard specifications set by the [Zigbee Alliance](https://www.zigbee.org) may require the development of custom [ZHA Device Handlers](https://github.com/zigpy/zha-device-handlers) (ZHA custom quirks handler implementation) to for all their functions to work properly with the ZHA component in Home Assistant. These ZHA Device Handlers for Home Assistant can thus be used to parse custom messages to and from non-compliant Zigbee devices. The custom quirks implementations for zigpy implemented as ZHA Device Handlers for Home Assistant are a similar concept to that of [Hub-connected Device Handlers for the SmartThings platform](https://docs.smartthings.com/en/latest/device-type-developers-guide/) as well as that of [zigbee-herdsman converters as used by Zigbee2mqtt](https://www.zigbee2mqtt.io/how_tos/how_to_support_new_devices.html), meaning they are each virtual representations of a physical device that expose additional functionality that is not provided out-of-the-box by the existing integration between these platforms.
121+
122+
#### ZHA integration component for Home Assistant
123+
[ZHA integration component for Home Assistant](https://www.home-assistant.io/integrations/zha/) is a reference implementation of the zigpy library as integrated into the core of [Home Assistant](https://www.home-assistant.io) (a Python based open source home automation software). There are also other GUI and non-GUI projects for Home Assistant's ZHA components which builds on or depends on its features and functions to enhance or improve its user-experience, some of those are listed and linked below.
124+
125+
#### ZHA Custom Radios
126+
[zha-custom-radios](https://github.com/zha-ng/zha-custom-radios) adds support for custom radio modules for zigpy to [[Home Assistant's ZHA (Zigbee Home Automation) integration component]](https://www.home-assistant.io/integrations/zha/). This custom component for Home Assistant allows users to test out new modules for zigpy in Home Assistant's ZHA integration component before they are integrated into zigpy ZHA and also helps developers new zigpy radio modules without having to modify the Home Assistant's source code.
127+
128+
#### ZHA Custom
129+
[zha_custom](https://github.com/Adminiuga/zha_custom) is a custom component package for Home Assistant (with its ZHA component for zigpy integration) that acts as zigpy commands service wrapper, when installed it allows you to enter custom commands via to zigy to example change advanced configuration and settings that are not available in the UI.
130+
131+
#### ZHA Map
132+
[zha-map](https://github.com/zha-ng/zha-map) for Home Assistant's ZHA component can build a Zigbee network topology map.
87133
88-
### ZHA Device Handlers
89-
ZHA deviation handling in Home Assistant relies on on the third-party [ZHA Device Handlers](https://github.com/dmulcahey/zha-device-handlers) project. Zigbee devices that deviate from or do not fully conform to the standard specifications set by the [Zigbee Alliance](https://www.zigbee.org) may require the development of custom [ZHA Device Handlers](https://github.com/dmulcahey/zha-device-handlers) (ZHA custom quirks handler implementation) to for all their functions to work properly with the ZHA component in Home Assistant. These ZHA Device Handlers for Home Assistant can thus be used to parse custom messages to and from non-compliant Zigbee devices. The custom quirks implementations for zigpy implemented as ZHA Device Handlers for Home Assistant are a similar concept to that of [Hub-connected Device Handlers for the SmartThings Classics platform](https://docs.smartthings.com/en/latest/device-type-developers-guide/) as well as that of [Zigbee-Shepherd Converters as used by Zigbee2mqtt](https://www.zigbee2mqtt.io/how_tos/how_to_support_new_devices.html), meaning they are each virtual representations of a physical device that expose additional functionality that is not provided out-of-the-box by the existing integration between these platforms.
134+
#### ZHA Network Visualization Card
135+
[zha-network-visualization-card](https://github.com/dmulcahey/zha-network-visualization-card) is a custom Lovelace element for Home Assistant which visualize the Zigbee network for the ZHA component.
90136
91-
### ZHA Map
92-
Home Assistant can build ZHA network topology map using the [zha-map](https://github.com/zha-ng/zha-map) project.
137+
#### ZHA Network Card
138+
[zha-network-card](https://github.com/dmulcahey/zha-network-card) is a custom Lovelace card for Home Assistant that displays ZHA component Zigbee network and device information in Home Assistant
93139
94-
### zha-network-visualization-card
95-
[zha-network-visualization-card](https://github.com/dmulcahey/zha-network-visualization-card) is a custom Lovelace element for visualizing the ZHA Zigbee network in Home Assistant.
140+
#### Zigzag
141+
[Zigzag](https://github.com/Samantha-uk/zigzag) is an custom card/panel for [Home Assistant](https://www.home-assistant.io/) that displays a graphical layout of Zigbee devices and the connections between them. Zigzag can be installed as a panel or a custom card and relies on the data provided by the [zha-map](https://github.com/zha-ng/zha-map) integration commponent.
96142
97-
### ZHA Network Card
98-
[zha-network-card](https://github.com/dmulcahey/zha-network-card) is a custom Lovelace card that displays ZHA network and device information in Home Assistant
143+
#### ZHA Device Exporter
144+
[zha-device-exporter](https://github.com/dmulcahey/zha-device-exporter) is a custom component for Home Assistant to allow the ZHA component to export lists of Zigbee devices.

setup.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ def is_raspberry_pi(raise_on_errors=False):
5050

5151
requires = [
5252
'pyserial-asyncio',
53+
'pyusb',
5354
'zigpy>=0.22.2',
5455
]
5556

@@ -66,13 +67,15 @@ def is_raspberry_pi(raise_on_errors=False):
6667
description="A library which communicates with ZiGate radios for zigpy",
6768
long_description=long_description,
6869
long_description_content_type="text/markdown",
69-
url="http://github.com/doudz/zigpy-zigate",
70+
url="http://github.com/zigpy/zigpy-zigate",
7071
author="Sébastien RAMAGE",
7172
author_email="[email protected]",
7273
license="GPL-3.0",
7374
packages=find_packages(exclude=['*.tests']),
7475
install_requires=requires,
7576
tests_require=[
7677
'pytest',
78+
'pytest-asyncio',
79+
'mock'
7780
],
7881
)

tests/__init__.py

Whitespace-only changes.

tests/async_mock.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
"""Mock utilities that are async aware."""
2+
import sys
3+
4+
if sys.version_info[:2] < (3, 8):
5+
from mock import * # noqa
6+
else:
7+
from unittest.mock import * # noqa

tests/test_api.py

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import pytest
44
import serial
55
import serial_asyncio
6-
from asynctest import CoroutineMock, mock
6+
from .async_mock import AsyncMock, MagicMock, patch, sentinel
77

88
import zigpy_zigate.config as config
99
import zigpy_zigate.uart
@@ -15,13 +15,13 @@
1515
@pytest.fixture
1616
def api():
1717
api = zigate_api.ZiGate(DEVICE_CONFIG)
18-
api._uart = mock.MagicMock()
18+
api._uart = MagicMock()
1919
return api
2020

2121

2222
def test_set_application(api):
23-
api.set_application(mock.sentinel.app)
24-
assert api._app == mock.sentinel.app
23+
api.set_application(sentinel.app)
24+
assert api._app == sentinel.app
2525

2626

2727
@pytest.mark.asyncio
@@ -39,26 +39,26 @@ async def mock_conn(loop, protocol_factory, **kwargs):
3939

4040

4141
def test_close(api):
42-
api._uart.close = mock.MagicMock()
42+
api._uart.close = MagicMock()
4343
uart = api._uart
4444
api.close()
4545
assert uart.close.call_count == 1
4646
assert api._uart is None
4747

4848

4949
@pytest.mark.asyncio
50-
@mock.patch.object(zigpy_zigate.uart, "connect")
50+
@patch.object(zigpy_zigate.uart, "connect")
5151
async def test_api_new(conn_mck):
5252
"""Test new class method."""
53-
api = await zigate_api.ZiGate.new(DEVICE_CONFIG, mock.sentinel.application)
53+
api = await zigate_api.ZiGate.new(DEVICE_CONFIG, sentinel.application)
5454
assert isinstance(api, zigate_api.ZiGate)
5555
assert conn_mck.call_count == 1
5656
assert conn_mck.await_count == 1
5757

5858

5959
@pytest.mark.asyncio
60-
@mock.patch.object(zigate_api.ZiGate, "set_raw_mode", new_callable=CoroutineMock)
61-
@mock.patch.object(zigpy_zigate.uart, "connect")
60+
@patch.object(zigate_api.ZiGate, "set_raw_mode", new_callable=AsyncMock)
61+
@patch.object(zigpy_zigate.uart, "connect")
6262
async def test_probe_success(mock_connect, mock_raw_mode):
6363
"""Test device probing."""
6464

@@ -72,8 +72,8 @@ async def test_probe_success(mock_connect, mock_raw_mode):
7272

7373

7474
@pytest.mark.asyncio
75-
@mock.patch.object(zigate_api.ZiGate, "set_raw_mode", side_effect=asyncio.TimeoutError)
76-
@mock.patch.object(zigpy_zigate.uart, "connect")
75+
@patch.object(zigate_api.ZiGate, "set_raw_mode", side_effect=asyncio.TimeoutError)
76+
@patch.object(zigpy_zigate.uart, "connect")
7777
@pytest.mark.parametrize(
7878
"exception",
7979
(asyncio.TimeoutError, serial.SerialException, zigate_api.NoResponseError),
@@ -91,3 +91,14 @@ async def test_probe_fail(mock_connect, mock_raw_mode, exception):
9191
assert mock_connect.call_args[0][0] == DEVICE_CONFIG
9292
assert mock_raw_mode.call_count == 1
9393
assert mock_connect.return_value.close.call_count == 1
94+
95+
96+
@pytest.mark.asyncio
97+
@patch.object(zigate_api.ZiGate, "_command", side_effect=asyncio.TimeoutError)
98+
async def test_api_command(mock_command, api):
99+
"""Test command method."""
100+
try:
101+
await api.set_raw_mode()
102+
except zigate_api.NoResponseError:
103+
pass
104+
assert mock_command.call_count == 2

tests/test_application.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,13 @@
1313
config.CONF_DATABASE: None,
1414
}
1515
)
16-
16+
FAKE_FIRMWARE_VERSION = '3.1z'
1717

1818
@pytest.fixture
1919
def app():
20-
return zigpy_zigate.zigbee.application.ControllerApplication(APP_CONFIG)
20+
a = zigpy_zigate.zigbee.application.ControllerApplication(APP_CONFIG)
21+
a.version = FAKE_FIRMWARE_VERSION
22+
return a
2123

2224

2325
def test_zigpy_ieee(app):
@@ -30,3 +32,8 @@ def test_zigpy_ieee(app):
3032

3133
dst_addr = app.get_dst_address(cluster)
3234
assert dst_addr.serialize() == b"\x03" + data[::-1] + b"\x01"
35+
36+
37+
def test_model_detection(app):
38+
device = zigpy_zigate.zigbee.application.ZiGateDevice(app, 0, 0)
39+
assert device.model == 'ZiGate USB-TTL {}'.format(FAKE_FIRMWARE_VERSION)

0 commit comments

Comments
 (0)