Repository navigation
feat: accept QR landing URL as encryption key, native scan in companion app - #133
Open
g4bri3lDev wants to merge 2 commits into
Open
g4bri3lDev wants to merge 2 commits into
g4bri3lDev wants to merge 2 commits into
Conversation
g4bri3lDev
force-pushed
the
feat/qr-code-key-scan
branch
from
September 25, 2026 19:39
48405e9 to
c6f8bf3
Compare
…on app - Encryption-key and reauth fields now accept either the 32-hex key or the opendisplay.org/l/?... link from the device's on-screen QR code, decoded with py-opendisplay's parse_landing_url and checked against the OD###### name. A QR code for another device gives qr_wrong_device; an all-zero key slot, which here means the device hides its key, gives qr_key_hidden. - Ship a small frontend module (registered via add_extra_js_url) that, inside a companion app reporting hasBarCodeScanner, adds a scan button to that field and opens the native scanner over the external bus (bar_code/scan). A scanned OpenDisplay link is put into the field and the step is submitted right away; any other QR code keeps the scanner open with a message. Elsewhere the field stays plain text.
Adds parse_landing_url(), which the encryption-key and reauth fields use to read the link from the device's on-screen QR code.
g4bri3lDev
force-pushed
the
feat/qr-code-key-scan
branch
from
September 25, 2026 20:14
8dc2ebb to
a83d251
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
opendisplay.org/l/?...link from the device's on-screen QR code. The link is decoded with py-opendisplay'sparse_landing_urland checked against theOD######device name.qr_wrong_device: the QR code belongs to another device.qr_key_hidden: the QR code's key slot is all zeros. The firmware zero-fills it when theshow_key_on_screensecurity flag is off, and the flow only asks for a key once the device required one, so the key is hidden rather than unset.frontend/qr-scan.js, registered viaadd_extra_js_url) adds a scan button to that field inside a companion app that reportshasBarCodeScanner. It opens the app's native scanner over the external bus (bar_code/scan). A scanned OpenDisplay link is put into the field and the step is submitted right away (viastep-flow-form'ssubmit()); the Python side decodes and validates it, so a wrong device or hidden key shows up as a form error. Any other QR code keeps the scanner open with "That's not an OpenDisplay QR code" (bar_code/notify). Everywhere else the field stays plain text, and a pasted link works too.manifest.json:after_dependencies: ["frontend"].Why the JS is needed
The app opens its scanner only when the frontend sends
bar_code/scan, and the HA frontend only does that from the Z-Wave add-device dialog. There's no scan option for config-flow fields, and the frontend's barcode listeners are private, so the module wraps the external bus'sreceiveMessageand passes every message through so the frontend still acknowledges it. It depends on frontend internals (ha-selector-text,step-flow-formand itssubmit()) and falls back to the plain field if those change.add_extra_js_urlmodules are injected intoindex.html, so an app webview that was already open only shows the button after a reload.Depends on
py-opendisplay 7.17.0 (OpenDisplay/py-opendisplay#165,
parse_landing_url), pinned inmanifest.jsonandpyproject.tomlby the second commit.Tests
tests/test_qr.py: hex keys, landing URLs, wrong device, hidden key, malformed input.tests/test_frontend.py: static path + extra JS URL are registered once, and not at all on headless instances.tests/test_config_flow.py: QR URL during setup, wrong-device/hidden-key/malformed errors, and reauth.Manual testing