Reusable how-to for generating a printable PDF with a Wi-Fi QR code so guests can scan-to-join, produced entirely on the Mac with no extra system tooling. Verified working 2026-07-31.
For Agents
Pipeline: pull
ssid+keyfrom the telep-router viauci show wireless→ build an HTML card with an inline SVG QR (segno) → render to PDF with headless Google Chrome → print. Never write the actual Wi-Fi passwords into this vault. Read them live from the router at print time.
Wi-Fi QR payload format
A Wi-Fi QR code is just a plain-text string in this format:
WIFI:T:<auth>;S:<ssid>;P:<password>;;
T:— auth type. UseWPA. It is the widely-compatible value and modern phones join WPA3/SAE networks from aT:WPApayload fine. (nopassfor open networks;WEPis legacy.)S:— SSID.P:— password.- Note the double semicolon at the end.
- Escape any of
\ ; , : "appearing in the SSID or password with a leading backslash.
You rarely hand-build this string — segno.helpers.make_wifi(...) does it for you (see below).
Where the network details come from
The source of truth is the OpenWrt router, not this note. SSH in and read UCI:
/usr/bin/ssh root@100.69.112.32 # telep-router, over the tailnet (was 100.115.194.51 before the 2026-08-03 reset)
uci show wireless # ssid / key / encryption per radio| Network | SSID | Encryption | Notes |
|---|---|---|---|
| Main | telep1 | sae (WPA3) | Same SSID on both radios (radio0 5 GHz + radio1 2.4 GHz). Use T:WPA in the payload. |
| Cameras | telep-cc | psk2 (WPA2) | Isolated VLAN. PSK is flagged leaked — rotate it before printing a QR for it. |
See WiFi for the radio layout and Camera VLAN (telep-cc) for the camera network.
The pipeline
1. Throwaway venv + segno
There is no qrencode on this Mac. Python is python3.14 and externally-managed (PEP 668), so system-wide pip install is blocked. Use a disposable venv — segno is pure Python (no C deps):
python3 -m venv venv
venv/bin/pip install segno2. Build the HTML card
segno.helpers.make_wifi builds the QR; render it as an inline SVG into an A4 HTML card with the SSID title, a scan to join caption, and the password in monospace so people can also type it.
import io
import segno
from segno import helpers
ssid = "telep1"
password = "<read from: uci show wireless>" # do NOT hardcode / commit
qr = helpers.make_wifi(ssid=ssid, password=password, security="WPA")
buf = io.BytesIO() # segno's SVG writer emits BYTES
qr.save(buf, kind="svg", scale=8, border=2)
svg = buf.getvalue().decode("utf-8")
html = f"""<!doctype html><meta charset="utf-8">
<style>
@page {{ size: A4; margin: 0; }}
body {{ margin: 0; font-family: -apple-system, Helvetica, sans-serif; }}
.card {{ height: 100vh; display: flex; flex-direction: column;
align-items: center; justify-content: center; gap: 1.2rem; }}
h1 {{ font-size: 3rem; margin: 0; }}
.cap {{ font-size: 1.4rem; color: #444; }}
.pw {{ font-family: ui-monospace, Menlo, monospace; font-size: 1.6rem; }}
svg {{ width: 55vw; height: auto; }}
</style>
<div class="card">
<h1>{ssid}</h1>
{svg}
<div class="cap">Scan to join Wi-Fi</div>
<div class="pw">{password}</div>
</div>"""
with open("sheet.html", "w") as f:
f.write(html)3. Render to PDF with headless Chrome
There is no wkhtmltopdf, but Google Chrome is installed and prints HTML to PDF headless:
"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" \
--headless --disable-gpu --no-pdf-header-footer \
--print-to-pdf=out.pdf "file://$(pwd)/sheet.html"4. Verify, then print
Open out.pdf (open -a Preview out.pdf, or the Read tool renders it). Scan it once with a phone before printing a batch — especially for telep1, which is WPA3-only.
Gotchas
PEP 668 — do not
--break-system-packages
python3.14here is externally-managed; systempip installis blocked. Use a throwawayvenv, never--break-system-packages.
segno SVG writer returns bytes
Save SVG into
io.BytesIO()then.getvalue().decode("utf-8"). Usingio.StringIO()raisesTypeError: string argument expected, got 'bytes'.
T:WPAalso covers WPA3A
WIFI:T:WPA;...payload joins WPA3/SAE networks (liketelep1) on modern phones. There is no separateT:WPA3value worth using —WPAis the compatible choice.
Related
- telep-router — source of
ssid/key/encryptionviauci show wireless - homelab
- LOG
- TOPICS