diff --git a/README.md b/README.md index 093fe69..41585c8 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,7 @@ Defining the system requirements with exact versions typically is difficult. But * pip 20.2.4 * httpx 0.21.0 * protobuf 3.17.3 +* segno 1.5.2 * zeroconf 0.36.8 Other versions and even other operating systems might work. Feel free to tell us about your experience. If you want to run our unit tests, you also need: diff --git a/devolo_plc_api/__init__.py b/devolo_plc_api/__init__.py index df3b4f7..a672f60 100644 --- a/devolo_plc_api/__init__.py +++ b/devolo_plc_api/__init__.py @@ -2,6 +2,7 @@ from importlib.metadata import PackageNotFoundError, version from .device import Device +from .helpers import wifi_qr_code try: __version__ = version("devolo_plc_api") @@ -9,4 +10,4 @@ # package is not installed - e.g. pulled and run locally __version__ = "0.0.0" -__all__ = ["Device", "__version__"] +__all__ = ["Device", "wifi_qr_code", "__version__"] diff --git a/devolo_plc_api/helpers/__init__.py b/devolo_plc_api/helpers/__init__.py new file mode 100644 index 0000000..0a2c282 --- /dev/null +++ b/devolo_plc_api/helpers/__init__.py @@ -0,0 +1,15 @@ +"""Helper methods to allow advanced usage of information provided by the device.""" +from io import BytesIO + +from segno.helpers import make_wifi + +from devolo_plc_api.device_api import WifiGuestAccessGet +from devolo_plc_api.device_api.wifinetwork_pb2 import WPA_NONE + + +def wifi_qr_code(guest_wifi: WifiGuestAccessGet) -> bytes: + """Generate a wifi QR code.""" + buffer = BytesIO() + qr_code = make_wifi(ssid=guest_wifi.ssid, password=guest_wifi.key, security=None if guest_wifi.wpa == WPA_NONE else "WPA") + qr_code.save(out=buffer, kind="svg") + return buffer.getvalue() diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 12f76f5..0175784 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [Unreleased] + +### Added + +- Generate QR codes from wifi guest settings + ## [v1.3.1] - 2023/05/12 ### Fixed diff --git a/example_async.py b/example_async.py index fa24083..121ddb4 100644 --- a/example_async.py +++ b/example_async.py @@ -1,6 +1,6 @@ import asyncio -from devolo_plc_api import Device +from devolo_plc_api import Device, wifi_qr_code # IP of the device to query IP = "192.168.0.10" @@ -66,6 +66,11 @@ async def run(): print(guest_wifi.enabled) # False print(guest_wifi.remaining_duration) # 0 + # Get a QR code of the guest Wifi settings as byte stream in SVG format + qr = wifi_qr_code(guest_wifi) + with open("qr.svg", "wb") as binary_file: + binary_file.write(qr) + # Enable or disable the wifi guest access. Set enable to True to it turn on, to False to turn it off. Optionally # specify a duration in minutes. Changing SSID or the wifi key is currently not supported. If the state was changed # successfully, True is returned, otherwise False. diff --git a/example_sync.py b/example_sync.py index 8f5f9bb..8604d38 100644 --- a/example_sync.py +++ b/example_sync.py @@ -1,4 +1,4 @@ -from devolo_plc_api import Device +from devolo_plc_api import Device, wifi_qr_code # IP of the device to query IP = "192.168.0.10" @@ -64,6 +64,11 @@ def run(): print(guest_wifi.enabled) # False print(guest_wifi.remaining_duration) # 0 + # Get a QR code of the guest Wifi settings as byte stream in SVG format + qr = wifi_qr_code(guest_wifi) + with open("qr.svg", "wb") as binary_file: + binary_file.write(qr) + # Enable or disable the wifi guest access. Set enable to True to it turn on, to False to turn it off. Optionally # specify a duration in minutes. Changing SSID or the wifi key is currently not supported. If the state was changed # successfully, True is returned, otherwise False. diff --git a/pyproject.toml b/pyproject.toml index 55a4f86..582ebd9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -17,6 +17,7 @@ dependencies = [ "ifaddr>=0.1.7", "httpx>=0.21.0", "protobuf>=4.22.0", + "segno>=1.5.2", "zeroconf>=0.32.0", ] dynamic = [ diff --git a/tests/test_helpers.py b/tests/test_helpers.py new file mode 100644 index 0000000..8ce1b80 --- /dev/null +++ b/tests/test_helpers.py @@ -0,0 +1,29 @@ +"""Test helper methods.""" +from devolo_plc_api import wifi_qr_code +from devolo_plc_api.device_api.wifinetwork_pb2 import WPA_2, WifiGuestAccessGet + + +class TestHelpers: + """Test devolo_plc_api.helpers.""" + + def test_wifi_qr_code(self): + """Test getting wifi guest access status asynchronously.""" + wifi_guest_access = WifiGuestAccessGet(enabled=True, ssid='"Test"', key='"Test"', wpa=WPA_2) + assert ( + wifi_qr_code(wifi_guest_access) + == b'\n\n' + )