b203f0e4de
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.
132 lines
5.5 KiB
Plaintext
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
|