Local Web Bluetooth page that provisions the Pine64 PineVoice speaker over the Improv BLE protocol. Waits for the AUTHORIZED state before sending credentials (per the Improv spec), uses write-with-response since the firmware declares the RPC characteristic write-only, and logs the device state/error sequence for diagnostics. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2.2 KiB
PineVoice WiFi Setup Tool
Local Improv-BLE provisioning page for the Pine64 PineVoice smart speaker. Serves from localhost so Web Bluetooth works and no VPN/proxy can interfere.
Run
python3 -m http.server 8377 --bind 127.0.0.1 -d ~/Projects/pine
Then open http://localhost:8377 in Chrome (needs Web Bluetooth — Chrome/Edge, not Safari/Firefox).
Use
- Put the speaker in provisioning mode: ring LED blinking yellow (hold the • dot button 15 s to reset if needed).
- Enter SSID + password, click Connect PineVoice, pick PineVoice in the Bluetooth chooser.
- If the log says authorization required, press the centre button on the
speaker. The page waits for this and only sends credentials once the device
reports
authorized. Authorization lapses after ~1 min, so don't linger. - Success: log shows
✓ PROVISIONED, speaker plays a chime, LED breathes dim magenta. Failure: speaker plays a failure sound within ~20 s and the log shows the reason.
After WiFi: add to Home Assistant
Settings → Devices & services → discovered Wyoming Protocol device →
Configure. If not auto-discovered: Add integration → Wyoming Protocol →
host = speaker IP, port 10700. Requires an Assist pipeline with
Whisper (STT) and Piper (TTS). Wake word: "Hey Jarvis", or press the center button.
The gotchas this tool fixes
Authorization ordering. Per the Improv BLE spec,
a device in AUTHORIZATION_REQUIRED (0x01) rejects a WIFI_SETTINGS RPC with
error 0x04. The client must wait for the state to become AUTHORIZED (0x02)
— i.e. for the physical button press — before writing. Sending immediately looks
like a successful write (the device ACKs the GATT write) but provisioning never
starts.
Write-with-response. The PineVoice firmware declares its Improv RPC characteristic as
write-WITH-response only (GATT_CHRC_PROP_WRITE in
pinevoice_fw_e907/app/src/improv/improv.c). Anything that sends credentials
as an unacknowledged BLE Write Command is silently ignored — no error, no
state change. This page uses writeValueWithResponse explicitly.
Firmware source: https://codeberg.org/pine64/pinevoice_smartspeaker_sdk