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 /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 " 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