3.4 KiB
3.4 KiB
WebSocket Audio Streaming Implementation Plan
Implement a WebSocket-based real-time voice integration between the ESP32 board and the Hermes Voice Gateway (Phase 1: WebSocket streaming with server-side batch fallback) to solve the RAM/Flash storage constraints and lower latency.
User Review Required
Important
- This plan adds a new route
/api/esp32/voice/wsto the Hermes Gateway. The old POST route/api/esp32/voicewill remain completely intact to act as a stable fallback.- A lightweight WebSocket client
websocket_client.pywill be added to the MicroPythonlib/directory since standard MicroPython doesn't bundle a WebSocket client by default.
Open Questions
Note
None at the moment. The proposed wire protocol and incremental phased approach minimize risk.
Proposed Changes
1. Hermes Voice Gateway
[MODIFY] api_server_endpoint.py
- Add a
_handle_esp32_voice_websockethandler method. - Listen for a JSON
startframe to read parameters likedevice_id,reply_mode, andscreen_url. - Accept incoming binary frames (raw PCM s16le mono 16 kHz chunks) and write them directly to a temporary WAV file on the host's disk.
- Upon receiving the JSON
endframe (or a disconnection/timeout):- Close the WAV file writer.
- Invoke
transcribe_audio(wav_path)using the localfaster-whisperengine. - Run the agent turn via
_run_esp32_voice_turn. - Synthesize TTS audio and send the resulting WAV file back as a binary frame to the client.
- Update
register_esp32_voice_routeto bind the new WebSocket endpoint:app.router.add_get("/api/esp32/voice/ws", api_server._handle_esp32_voice_websocket)
[MODIFY] README.md
- Update documentation to cover the new
/api/esp32/voice/wsWebSocket client contract and protocol.
2. ESP32 MicroPython Firmware
[NEW] websocket_client.py
- Implement a minimal, robust, memory-efficient WebSocket client helper class (
WebSocketClient) in MicroPython. - Support HTTP handshake, sending/receiving text frames (opcode 1), and binary frames (opcode 2) with proper masking (client-to-server requirement).
[NEW] demo_websocket_voice.py
- Create a dedicated firmware script demonstrating how the board communicates with the new gateway:
- Connect to
ws://<ip>:8642/api/esp32/voice/ws. - Send the JSON start frame.
- Record continuously from I2S and stream 100ms chunks (3200 bytes mono) over the socket.
- Send the JSON end frame on screen release.
- Listen for the server's response WAV frame and play it using the ES8311 speaker codec.
- Connect to
Verification Plan
Automated Tests
- Run
python3 hermes_voice_gateway/smoke_test.pyto ensure local helper methods (normalization, MIME mapping) remain fully functional.
Manual Verification
- Run the updated Hermes server with the new WebSocket route registered.
- Run
demo_websocket_voice.pyon the ESP32 board. - Verify that the ESP32 connects, streams audio chunks on-the-fly without running out of RAM (SRAM memory checks via
gc.mem_free()), transcribes the speech, and plays back the agent's voice response.