Files
ESP32_ZACUS/plip_voice/main/Kconfig.projbuild
T
clement b203f0e4de
CI / platformio (pull_request) Failing after 3m46s
CI / platformio (push) Failing after 4m1s
plip: optional auto story-ring (off by default)
Escape-room mechanic: the retro phone can call the players on its own
and tell them a story when they pick up.

Approach: a story_ring_task rings at a random 15-30 min interval (only
when the line is idle and a story pack is on the SD). Picking up routes
through enter_story_from_ring(), which silences the bell and launches a
random story via plip_gamebook_begin_random() straight into the gamebook
state — no menu. If nobody answers within 1 min the bell stops and the
next ring is rescheduled; hanging up mid-ring also silences it.

The whole feature is gated behind CONFIG_PLIP_AUTO_RING (default n), so
the phone stays silent unless explicitly enabled in menuconfig. The hook
pickup paths (raw SLIC poll + debounced edge) mirror the existing NPC
incoming-call handling, which is unreliable while the bell rings.
2026-06-20 21:08:56 +02:00

132 lines
5.5 KiB
Plaintext

menu "PLIP Voice Configuration"
config PLIP_WIFI_SSID
string "WiFi SSID"
default "zacus-net"
help
WiFi network SSID. Credentials can also be stored in NVS
(namespace "wifi", keys "ssid"/"pwd") — NVS takes precedence.
config PLIP_WIFI_PASSWORD
string "WiFi Password"
default ""
help
WiFi password. Leave empty for open networks.
config PLIP_WIFI_CHANNEL
int "WiFi channel hint (0 = auto)"
default 11
range 0 13
help
Bias the STA scan to start on this channel. Must match the
master ESP32's connected channel for ESP-NOW co-channel
operation. Lab network uses channel 11.
config PLIP_MASTER_URL
string "Zacus Master Base URL"
default "http://192.168.0.188"
help
Base URL of the Zacus master ESP32 (Freenove board). The PLIP
reports hook transitions to <url>/voice/hook.
config PLIP_SPEAKER_VOLUME
int "Default Speaker Volume (0-100)"
default 98
range 0 100
help
Default speaker output volume at boot.
config PLIP_HOOK_GPIO
int "Off-hook GPIO number"
default 23
help
GPIO that signals handset off-hook.
SLIC SHK line is GPIO23 (A1S board KEY4, re-assigned to SLIC).
Legacy dev kit stub used GPIO4 (BOOT button, active-LOW).
config PLIP_HOOK_ACTIVE_HIGH
bool "Hook GPIO active-HIGH means off-hook"
default y
help
When enabled, a HIGH level on PLIP_HOOK_GPIO means the handset is
off-hook (SLIC SHK polarity). When disabled, LOW means off-hook
(original dev-kit pull-up + BOOT button polarity).
config PLIP_DIAL_PULSE
bool "Enable rotary dial pulse decoding on SHK GPIO"
default y
help
When enabled, brief open/close pulses on the hook GPIO (from a
rotary dial) are decoded into digits and pushed to the dialer.
Each pulse train: ~60-100 ms open + ~40 ms closed; 10 pulses = digit 0.
A gap > PLIP_DIAL_PULSE_MAX_GAP_MS terminates the digit.
config PLIP_DIAL_PULSE_MAX_GAP_MS
int "Rotary pulse inter-digit gap (ms)"
default 200
depends on PLIP_DIAL_PULSE
range 100 500
help
If the hook GPIO stays closed for more than this duration after
a pulse train, the train is considered complete and the digit is
emitted. 200 ms is standard for French rotary dials.
config PLIP_DIAL_DTMF
bool "Enable DTMF (touch-tone) dialing via Goertzel"
default n
help
When enabled, a background task reads 20 ms microphone frames and
runs a Goertzel-based DTMF detector (8 frequencies: 697-1633 Hz).
Confirmed digits (≥ 40 ms tone, with twist and dominance guards)
are pushed to the dialer just like rotary pulses.
The detector is active only between off-hook and the start of the
NPC greeting; it is disarmed during voice capture (CONNECTED state).
Can be combined with PLIP_DIAL_PULSE: whichever source detects a
digit first wins. Default off — enable for touch-tone handsets.
config PLIP_AUTO_RING
bool "Auto story-ring (rings by itself every 15-30 min)"
default n
help
When enabled, the phone rings on its own at a random 15-30 minute
interval; picking up launches a random audio story straight away
(no menu). If nobody answers within 1 minute the bell stops and the
next ring is rescheduled. Default off — enable for the escape-room
ambience where the phone calls the players.
config PLIP_GATEWAY_URL
string "NPC Gateway Base URL"
default "http://192.168.0.50:8401"
help
Base URL of the PLIP voice gateway (zacus-gateway FastAPI), as seen
from the PLIP on the local LAN. Override at build time or via
sdkconfig.defaults. The turn_client appends /v1/voice/turn.
Example: http://192.168.0.10:8401 (IP of the Mac running the gateway).
config PLIP_GATEWAY_TOKEN
string "NPC Gateway Bearer Token"
default ""
help
Bearer token sent as "Authorization: Bearer <token>" on every
/v1/voice/turn request. Leave empty to skip the header.
config PLIP_VOICE_REPLY
bool "Enable Stage-3 conversational LISTEN loop (capture -> /v1/voice/reply -> play)"
default n
help
When enabled, after the NPC greeting is played (STATE_CONNECTED),
the firmware enters a continuous listen loop:
1. Capture mic audio (up to 8 s, VAD-gated) via audio_capture_wav().
2. POST the captured WAV as multipart/form-data to
CONFIG_PLIP_GATEWAY_URL/v1/voice/reply (STT + NPC reply via Kyutai).
3. Play the NPC response WAV from /spiffs/reply.wav.
4. Repeat until the handset is hung up.
Requires the gateway (zacus-gateway FastAPI) to be reachable and
the /v1/voice/reply endpoint to be operational.
Capture buffer (~256 KB for 8 s) is allocated from PSRAM when
available; falls back to internal heap with reduced duration (4 s).
Leave OFF (default) to keep STATE_CONNECTED as a terminal state
(Stage 2 behaviour — greeting only, no further interaction).
endmenu