Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add helper to generate QR codes from wifi credentials #137

Merged
merged 4 commits into from
Jul 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
3 changes: 2 additions & 1 deletion devolo_plc_api/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@
from importlib.metadata import PackageNotFoundError, version

from .device import Device
from .helpers import wifi_qr_code

try:
__version__ = version("devolo_plc_api")
except PackageNotFoundError:
# package is not installed - e.g. pulled and run locally
__version__ = "0.0.0"

__all__ = ["Device", "__version__"]
__all__ = ["Device", "wifi_qr_code", "__version__"]
22 changes: 22 additions & 0 deletions devolo_plc_api/helpers/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
"""Helper methods to allow advanced usage of information provided by the device."""
from io import BytesIO
from typing import Any

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, kind: str = "svg", **kwargs: Any) -> bytes:
"""
Generate a wifi QR code.

:param guest_wifi: Wifi credentials to represent in the QR code
:param kind: Output format of the image
:return: Bytes of image
"""
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=kind, **kwargs)
return buffer.getvalue()
6 changes: 6 additions & 0 deletions docs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.2] - 2023/07/13

### Fixed
Expand Down
7 changes: 6 additions & 1 deletion example_async.py
Original file line number Diff line number Diff line change
@@ -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"
Expand Down Expand Up @@ -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.
Expand Down
7 changes: 6 additions & 1 deletion example_sync.py
Original file line number Diff line number Diff line change
@@ -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"
Expand Down Expand Up @@ -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.
Expand Down
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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 = [
Expand Down
4 changes: 4 additions & 0 deletions tests/snapshots/test_helpers.ambr
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# serializer version: 1
# name: TestHelpers.test_wifi_qr_code
b'<?xml version="1.0" encoding="utf-8"?>\n<svg xmlns="http://www.w3.org/2000/svg" width="37" height="37" class="segno"><path class="qrline" stroke="#000" d="M4 4.5h7m2 0h1m1 0h1m2 0h1m7 0h7m-29 1h1m5 0h1m2 0h1m6 0h2m2 0h1m1 0h1m5 0h1m-29 1h1m1 0h3m1 0h1m2 0h1m1 0h1m2 0h2m1 0h3m2 0h1m1 0h3m1 0h1m-29 1h1m1 0h3m1 0h1m3 0h2m1 0h1m6 0h1m1 0h1m1 0h3m1 0h1m-29 1h1m1 0h3m1 0h1m3 0h1m1 0h1m4 0h1m2 0h1m1 0h1m1 0h3m1 0h1m-29 1h1m5 0h1m1 0h2m5 0h1m1 0h1m1 0h2m1 0h1m5 0h1m-29 1h7m1 0h1m1 0h1m1 0h1m1 0h1m1 0h1m1 0h1m1 0h1m1 0h7m-17 1h2m1 0h3m1 0h1m-20 1h1m2 0h1m1 0h2m1 0h2m4 0h1m1 0h2m3 0h1m1 0h1m-24 1h5m4 0h3m1 0h1m1 0h1m2 0h1m3 0h2m1 0h3m-28 1h1m1 0h1m2 0h2m1 0h1m2 0h4m1 0h1m2 0h2m1 0h2m2 0h2m-28 1h1m1 0h3m3 0h2m1 0h3m5 0h1m1 0h2m2 0h4m-29 1h1m5 0h1m1 0h1m1 0h1m3 0h2m1 0h3m1 0h5m1 0h2m-29 1h5m2 0h1m4 0h3m1 0h2m2 0h1m1 0h1m3 0h3m-29 1h2m4 0h2m1 0h1m2 0h3m3 0h1m2 0h1m4 0h3m-26 1h1m1 0h1m2 0h5m4 0h1m1 0h3m1 0h2m-25 1h2m1 0h1m2 0h3m1 0h1m1 0h2m1 0h2m2 0h1m3 0h1m2 0h1m1 0h1m-28 1h3m1 0h1m1 0h1m1 0h6m3 0h1m2 0h2m3 0h2m-28 1h1m1 0h5m1 0h1m5 0h1m1 0h1m5 0h3m1 0h3m-27 1h1m1 0h1m2 0h3m1 0h2m1 0h1m1 0h2m1 0h1m1 0h1m1 0h1m-24 1h1m1 0h1m3 0h1m1 0h1m1 0h1m1 0h1m3 0h1m3 0h9m-21 1h5m1 0h1m2 0h1m2 0h1m3 0h3m-27 1h7m2 0h2m1 0h1m7 0h1m1 0h1m1 0h2m1 0h1m-28 1h1m5 0h1m1 0h1m5 0h3m1 0h1m1 0h1m3 0h1m1 0h3m-29 1h1m1 0h3m1 0h1m2 0h4m2 0h1m1 0h1m2 0h7m1 0h1m-29 1h1m1 0h3m1 0h1m1 0h1m1 0h1m2 0h1m1 0h1m1 0h3m2 0h2m1 0h1m1 0h1m-28 1h1m1 0h3m1 0h1m2 0h2m3 0h1m1 0h1m1 0h2m1 0h2m1 0h3m1 0h1m-29 1h1m5 0h1m2 0h2m1 0h1m2 0h6m2 0h1m3 0h1m-28 1h7m1 0h1m2 0h1m1 0h1m2 0h2m2 0h1m3 0h1m1 0h2"/></svg>\n'
# ---
14 changes: 14 additions & 0 deletions tests/test_helpers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
"""Test helper methods."""
from syrupy.assertion import SnapshotAssertion

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, snapshot: SnapshotAssertion):
"""Test creating a QR code."""
wifi_guest_access = WifiGuestAccessGet(enabled=True, ssid='"Test"', key='"Test"', wpa=WPA_2)
assert wifi_qr_code(wifi_guest_access) == snapshot