Skip to content

Add native Amazon Pryon Alexa wake-word support - #13

Draft
baileyboy0304 wants to merge 8 commits into
ygelfand:mainfrom
baileyboy0304:agent/pryon-alexa-wakeword
Draft

Add native Amazon Pryon Alexa wake-word support#13
baileyboy0304 wants to merge 8 commits into
ygelfand:mainfrom
baileyboy0304:agent/pryon-alexa-wakeword

Conversation

@baileyboy0304

@baileyboy0304 baileyboy0304 commented Aug 15, 2026

Copy link
Copy Markdown

Summary

  • add a privileged, wake-only Android companion that uses the Amazon Pryon detector already present on compatible Echo Dot 2 firmware;
  • expose Alexa as an EchoLocal wake-word choice while leaving Home Assistant Assist, LEDs, capture, TTS, media, ducking and Sendspin under EchoLocal control;
  • use Pryon's firmware-owned Amazon AudioStream as the single microphone owner and give EchoLocal a second authenticated reader, avoiding Fire OS's one-active-input race;
  • require both Pryon's native input-frame counter and EchoLocal's first shared PCM frame before installation can report success;
  • extend echoctl install and echoctl status to discover, install, reboot and verify the Pryon components; and
  • add a complete Windows source-tree provisioner that builds the payload, safeguards the target device, creates a rollback snapshot, saves the ESPHome credentials and verifies the completed installation.

Why

EchoLocal previously treated every selectable wake word as a local TFLite model. The original Echo firmware already includes an efficient native Pryon detector, but it lives behind privileged Android services and owns the firmware hotword recorder. The first integration let Pryon and EchoLocal open separate AudioRecord inputs. Fire OS only permits one active input on this hardware, so whichever process won startup worked while the other failed with startInput failed: other input ... already started and status -38.

That made an earlier live success timing-dependent. It also exposed a verifier gap: PRYON_READY proved native initialization, but did not prove that microphone frames were advancing or reaching EchoLocal.

This revision makes Pryon the sole recorder, shares its Amazon AudioStream with EchoLocal, and verifies the complete live-audio path before declaring the device ready.

Architecture and security boundary

The com.echolocal.pryon APK initializes firmware-owned NativeWakeWordServiceCore classes and locale model manifests. Amazon's native service owns the privileged 16 kHz recorder and writes to its AudioStream. A root-authenticated local socket exposes a second reader to EchoLocal's Android media helper for conversation audio. A separate UID-authenticated socket carries bounded, versioned JSON wake events only.

Pryon performs wake detection only. EchoLocal still owns the Home Assistant pipeline, LEDs, conversation capture, TTS, media and ducking. No audio is sent to Amazon or another remote service by this integration.

No Amazon APK, native library or model is included in this repository or copied off the device. The installer discovers and validates the required files in place on the user's attached Dot.

User impact

After pairing the ESPHome device, Alexa appears in the assistant Wake word select. Bundled microWakeWord models and downloaded openWakeWord/microWakeWord models remain available, including in other assistant slots.

Only Alexa is exposed in this PR. Some firmware/locale combinations also contain Amazon, Computer or Echo, but changing Pryon models requires an Android process restart and deserves separate hardware coverage.

For an unlocked Echo Dot 2 with TWRP recovery on Windows:

.\provision-echo-dot.ps1 -Name "Kitchen Echo"

The provisioner refuses non-biscuit hardware, supports -Serial when multiple devices are attached, and can safely be rerun. It prints the 32-byte ESPHome encryption key and also saves a private home-assistant-credentials.txt receipt inside its gitignored rollback snapshot. The cyan startup walk now fades after 60 seconds if Home Assistant has not subscribed, rather than looking like a recovery or boot loop.

Amazon account registration is not required after unlock; local Wi-Fi is required for ESPHome/Home Assistant.

Fresh-device hardening

The full installer was exercised on a freshly unlocked Dot. Its TWRP build automatically mounted the same userdata filesystem at both /data and /sdcard; rebooting directly after the boot-image write could leave the ext4 journal inconsistent and make Android remount /data read-only. The flash stage now resolves the actual userdata block device, syncs, unmounts those targets in reverse order, verifies no userdata mount remains, and refuses to reboot on an unexpected mount.

On the first Android boot, dex2oat also took about 36 seconds to compile the newly installed Amazon speech package. Pryon did initialize successfully, but the old 30-second verifier reported failure first. Pryon readiness remains bounded but now allows 90 seconds for that one-time compilation.

Updating an installed companion could also leave its old APK/native libraries mapped and make the final /system read-only remount fail. The installer now force-stops the old package before replacement.

Validation

  • powershell.exe -NoProfile -ExecutionPolicy Bypass -File .\provision-echo-dot.ps1 -BuildOnly passed, including the signed API-22 Pryon APK, Android helper JAR, Linux/ARM64 daemon and embedded Windows installer.
  • Targeted Go tests passed for the installer, Amazon protocol and LED startup behavior, including negative cases for every missing live-audio readiness marker.
  • GOOS=linux GOARCH=arm64 CGO_ENABLED=0 go build ./... and go vet ./... passed.
  • git diff --check passed.
  • The exact single-script provisioner completed successfully on a rooted biscuit running Fire OS 272.6.8.0, rebooted normally, rediscovered ESPHome/mDNS and saved the credential receipt.
  • Live speech produced PRYON_WAKEWORD_DETECTED word=alexa, an authenticated helper forward, an EchoLocal turn started, and 1.92 seconds of conversation PCM sent to Home Assistant.
  • dumpsys media.audio_flinger showed one active 16 kHz mono input owned by Pryon. No startInput failed, Error starting AudioRecord, filesystem or I/O errors were present.
  • After installation /system was read-only, /data was read-write, Android reported boot complete, EchoLocal was resident, and the ring frame was fully off after the 60-second unsubscribed timeout.

Review notes

The commits keep the Android transport, Pryon wake routing, installer/provisioning, documentation, fresh-device filesystem hardening, microphone correctness fix and installer UX changes reviewable. The branch is based on current main (0.0.5) and preserves the newer BLE/iBeacon changes that landed after the initial hardware work began.

@electroflame

Copy link
Copy Markdown

I don't mean to overstep here since this isn't my project, just a user and believer in what it's trying to do, but I fail to see why this would be a net-benefit for firmware that's trying to de-Amazon these devices. This is a pretty huge PR, with a lot of added/changed files to keep track of/sift through, and the overall technical debt is pretty immense for the (in my opinion, minor) feature it adds.

Is there a demonstrable improvement and/or difference over just using a trained OpenWakeWord or MicroWakeWord of "Alexa", like this, or this, for example?

Trying to loop a bunch of the Amazon firmware stuff back in here just for one (or maybe three) wake word(s) seems wrong, in my opinion. The open models do a pretty good job (and aren't proprietary), and a trained one does even better, so I'm not seeing why this would be worth the amount of future maintenance added by these pretty massive changes.

@ygelfand

Copy link
Copy Markdown
Owner

thx @electroflame and @baileyboy0304 yeah I'm not to keen on implementing/including something like this, at least not in its current state. It steps quiet a bit away from the single non-cgo binary daemon. Maybe a generic "external" wake word capability would be something that I could add, and this would be part of a separate project, if there's enough interest in such a use case. But also curious what real world experience has been for others w/ mww/oww, if the current implementation is falling short, that's a different story.

@T-vK

T-vK commented Sep 1, 2026

Copy link
Copy Markdown

I agree that the impact on architecture of this PR to this project is quite substantial.

It would be really interesting to see some benchmarks comparing the wake-word performance, though.
My personal experience with OpenWakeWord (no matter which model) is that it performs significantly worse than a regular Alexa device. Without actually having measured anything I would say it compares somewhat like this, given you have ideal/reasonable OpenWakeWord settings:

Condition Stock Alexa OpenWakeWord
Whispering ~2 m Doesn't work at all
Quiet voice ~3-4 m ~1 m
Conversational volume 4-6 m 2-3 m
Loud music in the background ~3 m Doesn't work at all

Not to mention the false-positives / false-negatives...
(My experience is mostly using the "ok nabu" model (other models I tested performed significantly worse) on a 2nd Gen RS03QR.)

If my numbers are even remotely close to reality, it would have a significant impact.

I feel like if someone could come up with a less hacky, more modular way that doesn't require Pryon to own the microphone, but instead allows piping the audio either to OpenWakeWord/microWakeWord or Pryon, that would be a great addition to this project.

@ygelfand

ygelfand commented Sep 1, 2026

Copy link
Copy Markdown
Owner

@T-vK are those results regardless of settings (gain, cancellation, noise reduction, etc?). also I would suggest trying the newer v3 oww wakewords, which seem to do quiet a bit better (at least for me).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants