slackr31337 / PorcupinePipeline

Use Porcupine wake word to trigger a voice assistant pipeline in Home-Assistant
MIT License
30 stars 3 forks source link

add HAConnection class for properly dispatching messages #34

Closed chatziko closed 1 year ago

chatziko commented 1 year ago

I tried this project in my HA setup, it generally works well, thanks a lot for creating it!

One issue I noticed is that PorcupinePipeline often worked for some time and then suddenly crashed and had to be restarted. After some digging I figured out the reason: PorcupinePipeline assumes that after sending a message the response will arrive in the very next received message, which however is not guaranteed.

A common crash scenario: if a pipeline fails for some reason with an error event, stt_task will terminate, going back to wakeword detection. In such case, however, the run-end event will not be processed. Then the next ping will receive back the unconsumed run-end, instead of the pong, causing a disconnect which breaks the program.

The solution is to properly dispatch websocket messages based on their message ids.

To make the logic cleaner, this PR adds a class HAConnection which handles all low-level websocket communication and only provides 3 high-level public functions to communicate with HA.

The functions have clear semantics and proprely dispatch messages based on their ids. So stt_task reads only pipeline events, ping/pong are correctly matched, etc.

Outside the HAConnection class the PR is almost trivial, the core functionality remains identical, just replacing the low-level websocket functions with the ones above. There are also some small changes to fix all typing errors (with both pyright and mypy).

With this PR the the crashes stopped in my setup (at least in my limited testing).