mirror of
https://github.com/Jeuners/Logpy-AgentOne.git
synced 2026-09-18 03:06:11 +02:00
feat(telefon): Notruf-Ton vor der Ansage, Taste 1 verbindet zu Astra
Hauptnummer und DW3 spielen nach dem Annehmen den Notruf-Ton aus dem Profil (8 kHz mono PCM16). Taste 1 geht wie Durchwahl 9 an den Pipecat-Bootstrap, ohne Taste weiter zu Ansage und Aufnahme. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
9c4903043e
commit
83b576f5e4
9 changed files with 101 additions and 0 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -17,3 +17,4 @@ __pycache__/
|
||||||
/telefon/modell.json
|
/telefon/modell.json
|
||||||
# Trainingsdaten-Export (pipe.export) - enthaelt volle Transkripte/Namen
|
# Trainingsdaten-Export (pipe.export) - enthaelt volle Transkripte/Namen
|
||||||
/training/
|
/training/
|
||||||
|
/telefon/notruf_ton.wav
|
||||||
|
|
|
||||||
19
HANDOFF.md
19
HANDOFF.md
|
|
@ -4,6 +4,25 @@
|
||||||
|
|
||||||
Voller Weg funktioniert Ende-zu-Ende: externer Anruf auf Durchwahl 9 (Plusnet → FreeSWITCH → `dialog/pipecat_bootstrap.py` → WebSocket → Astra) erreicht Astra, und Astra liefert jetzt auch eine echte, fertige Antwort statt nur "Einen Moment bitte" (Fix 2026-09-13, siehe unten) - kein offener Blocker mehr bekannt.
|
Voller Weg funktioniert Ende-zu-Ende: externer Anruf auf Durchwahl 9 (Plusnet → FreeSWITCH → `dialog/pipecat_bootstrap.py` → WebSocket → Astra) erreicht Astra, und Astra liefert jetzt auch eine echte, fertige Antwort statt nur "Einen Moment bitte" (Fix 2026-09-13, siehe unten) - kein offener Blocker mehr bekannt.
|
||||||
|
|
||||||
|
## 2026-09-17 — Notruf-Ton mit Taste 1 -> Astra
|
||||||
|
|
||||||
|
Hauptnummer (Catch-all `00_praxis_ab.xml`) und DW3 (nach den 20 s) spielen
|
||||||
|
nach dem Annehmen `telefon/notruf_ton.wav` (54 s Ton, Quelle
|
||||||
|
`profile/aufzug-notdienst/notruf_ton.m4a`, gebaut von
|
||||||
|
`telefon/notruf_ton_bauen.sh`: 8 kHz mono PCM16, -3 dB). Taste 1 während des
|
||||||
|
Tons oder bis 3 s danach -> `execute_extension notruf_taste_1 XML
|
||||||
|
notruf_menue` -> `socket 127.0.0.1:8095` wie DW9. Ohne Taste weiter zu
|
||||||
|
Ansage + Aufnahme wie bisher. DW9 unverändert direkt Astra.
|
||||||
|
|
||||||
|
Eigener Kontext `notruf_menue` (`dialplan/notruf_menue.xml`, Top-Level),
|
||||||
|
weil der Catch-all in `public` die Wahl sonst verschlucken würde.
|
||||||
|
|
||||||
|
Verifiziert: Loopback mit `uuid_recv_dtmf 1` und echter Anruf 17:00 (DTMF
|
||||||
|
per RTP kam an, Astra übernahm). **Nicht getestet:** Pfad ohne Taste
|
||||||
|
(Ton zu Ende -> Ansage -> Aufnahme) und Profil ohne Ton-Datei.
|
||||||
|
Sicherung vorher: Git-Tag `vor-notruf-ton-2026-09-17`, Live-Dialplan +
|
||||||
|
ansage.wav + plist in `ablage/sicherung-vor-notruf-ton-2026-09-17/`.
|
||||||
|
|
||||||
## 2026-09-17 — Leitung stumm nach IP-Wechsel, Watchdog-Kinder sterben
|
## 2026-09-17 — Leitung stumm nach IP-Wechsel, Watchdog-Kinder sterben
|
||||||
|
|
||||||
**Symptom:** Durchwahl 9 (und die ganze Leitung) nahm nicht ab. Letzter
|
**Symptom:** Durchwahl 9 (und die ganze Leitung) nahm nicht ab. Letzter
|
||||||
|
|
|
||||||
BIN
profile/aufzug-notdienst/notruf_ton.m4a
Normal file
BIN
profile/aufzug-notdienst/notruf_ton.m4a
Normal file
Binary file not shown.
|
|
@ -136,3 +136,6 @@ ffmpeg -v error -y -i "$TMP/sprache.wav" -i "$TMP/ton.wav" \
|
||||||
|
|
||||||
DAUER=$(ffprobe -v error -show_entries format=duration -of csv=p=0 telefon/ansage.wav)
|
DAUER=$(ffprobe -v error -show_entries format=duration -of csv=p=0 telefon/ansage.wav)
|
||||||
printf 'telefon/ansage.wav erzeugt (%.1f s, %s)\n' "$DAUER" "$BESCHREIBUNG"
|
printf 'telefon/ansage.wav erzeugt (%.1f s, %s)\n' "$DAUER" "$BESCHREIBUNG"
|
||||||
|
|
||||||
|
# Notruf-Ton gehoert zum Profil wie die Ansage - bei Profilwechsel mitziehen.
|
||||||
|
PROFIL="$PROFIL" telefon/notruf_ton_bauen.sh
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,14 @@
|
||||||
<action application="set" data="RECORD_ANSWER_REQ=true"/>
|
<action application="set" data="RECORD_ANSWER_REQ=true"/>
|
||||||
<action application="answer"/>
|
<action application="answer"/>
|
||||||
<action application="sleep" data="700"/>
|
<action application="sleep" data="700"/>
|
||||||
|
<!-- Notruf-Ton (telefon/notruf_ton.wav, nur wenn das Profil einen hat,
|
||||||
|
siehe telefon/notruf_ton_bauen.sh). Taste 1 waehrend des Tons oder
|
||||||
|
bis 3 s danach -> Astra, siehe notruf_menue.xml.tpl. Sonst weiter
|
||||||
|
zur Ansage. Argumente: min max versuche timeout_ms terminator
|
||||||
|
datei datei_bei_fehleingabe variable regex ziffern_timeout_ms -->
|
||||||
|
<action application="play_and_get_digits"
|
||||||
|
data="1 1 1 3000 # @@PROJEKT@@/telefon/notruf_ton.wav silence_stream://250 notruf_taste ^1$ 3000"/>
|
||||||
|
<action application="execute_extension" data="notruf_taste_${notruf_taste} XML notruf_menue"/>
|
||||||
<action application="playback" data="@@PROJEKT@@/telefon/ansage.wav"/>
|
<action application="playback" data="@@PROJEKT@@/telefon/ansage.wav"/>
|
||||||
<action application="record"
|
<action application="record"
|
||||||
data="@@PROJEKT@@/telefon/eingang/${strftime(%Y%m%d-%H%M%S)}_${caller_id_number}.wav 120 200 4"/>
|
data="@@PROJEKT@@/telefon/eingang/${strftime(%Y%m%d-%H%M%S)}_${caller_id_number}.wav 120 200 4"/>
|
||||||
|
|
|
||||||
|
|
@ -52,10 +52,14 @@ fuelle() { # <vorlage> <ziel>
|
||||||
fuelle "$PROJEKT/telefon/freeswitch/plusnet.xml.tpl" "$FS_ETC/sip_profiles/external/plusnet.xml"
|
fuelle "$PROJEKT/telefon/freeswitch/plusnet.xml.tpl" "$FS_ETC/sip_profiles/external/plusnet.xml"
|
||||||
chmod 600 "$FS_ETC/sip_profiles/external/plusnet.xml" # enthaelt das SIP-Passwort
|
chmod 600 "$FS_ETC/sip_profiles/external/plusnet.xml" # enthaelt das SIP-Passwort
|
||||||
fuelle "$PROJEKT/telefon/freeswitch/praxis_ab.xml.tpl" "$FS_ETC/dialplan/public/00_praxis_ab.xml"
|
fuelle "$PROJEKT/telefon/freeswitch/praxis_ab.xml.tpl" "$FS_ETC/dialplan/public/00_praxis_ab.xml"
|
||||||
|
# Kontext fuer Taste 1 waehrend des Notruf-Tons - Top-Level unter dialplan/,
|
||||||
|
# nicht in public/ (siehe notruf_menue.xml.tpl).
|
||||||
|
fuelle "$PROJEKT/telefon/freeswitch/notruf_menue.xml.tpl" "$FS_ETC/dialplan/notruf_menue.xml"
|
||||||
|
|
||||||
echo "Trunk -> $FS_ETC/sip_profiles/external/plusnet.xml (Rechte 600)"
|
echo "Trunk -> $FS_ETC/sip_profiles/external/plusnet.xml (Rechte 600)"
|
||||||
echo "Dialplan -> $FS_ETC/dialplan/public/00_praxis_ab.xml"
|
echo "Dialplan -> $FS_ETC/dialplan/public/00_praxis_ab.xml"
|
||||||
echo "Ansage -> $PROJEKT/telefon/ansage.wav"
|
echo "Ansage -> $PROJEKT/telefon/ansage.wav"
|
||||||
|
echo "Notruf -> $FS_ETC/dialplan/notruf_menue.xml (Ton: telefon/notruf_ton.wav, Taste 1 -> Astra)"
|
||||||
echo "Eingang -> $PROJEKT/telefon/eingang"
|
echo "Eingang -> $PROJEKT/telefon/eingang"
|
||||||
|
|
||||||
if [ -n "${DW3_DDI:-}" ]; then
|
if [ -n "${DW3_DDI:-}" ]; then
|
||||||
|
|
|
||||||
25
telefon/freeswitch/notruf_menue.xml.tpl
Normal file
25
telefon/freeswitch/notruf_menue.xml.tpl
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
<include>
|
||||||
|
<!-- Eigener Kontext fuer die Tastenwahl waehrend des Notruf-Tons.
|
||||||
|
00_praxis_ab.xml / 00_dw3_warten.xml spielen telefon/notruf_ton.wav per
|
||||||
|
play_and_get_digits und rufen danach
|
||||||
|
execute_extension notruf_taste_${notruf_taste} XML notruf_menue
|
||||||
|
auf. Nur "notruf_taste_1" hat hier eine Regel; ohne Taste (oder bei
|
||||||
|
fehlender Ton-Datei) findet execute_extension nichts, kehrt zurueck und
|
||||||
|
der Anruf laeuft weiter zu Ansage + Aufnahme.
|
||||||
|
|
||||||
|
Bewusst nicht im Kontext "public": dort matcht der Catch-all in
|
||||||
|
00_praxis_ab.xml jede Nummer und wuerde die Wahl verschlucken.
|
||||||
|
Liegt als Top-Level-Datei unter dialplan/ (wie agentzwei.xml), sonst
|
||||||
|
kennt FreeSWITCH den Kontextnamen nicht.
|
||||||
|
|
||||||
|
Taste 1 -> Astra, genau wie Durchwahl 9 (00_dw9_rufagent.xml). Kein
|
||||||
|
hangup danach: laeuft der Pipecat-Bootstrap nicht, kehrt socket sofort
|
||||||
|
zurueck und der Anrufer bekommt wenigstens den Anrufbeantworter. -->
|
||||||
|
<context name="notruf_menue">
|
||||||
|
<extension name="notruf_taste_1">
|
||||||
|
<condition field="destination_number" expression="^notruf_taste_1$">
|
||||||
|
<action application="socket" data="127.0.0.1:8095 async full"/>
|
||||||
|
</condition>
|
||||||
|
</extension>
|
||||||
|
</context>
|
||||||
|
</include>
|
||||||
|
|
@ -9,6 +9,14 @@
|
||||||
<action application="answer"/>
|
<action application="answer"/>
|
||||||
<!-- kurze Pause, sonst schneidet die Gegenstelle den Anfang der Ansage ab -->
|
<!-- kurze Pause, sonst schneidet die Gegenstelle den Anfang der Ansage ab -->
|
||||||
<action application="sleep" data="700"/>
|
<action application="sleep" data="700"/>
|
||||||
|
<!-- Notruf-Ton (telefon/notruf_ton.wav, nur wenn das Profil einen hat,
|
||||||
|
siehe telefon/notruf_ton_bauen.sh). Taste 1 waehrend des Tons oder
|
||||||
|
bis 3 s danach -> Astra, siehe notruf_menue.xml.tpl. Sonst weiter
|
||||||
|
zur Ansage. Argumente: min max versuche timeout_ms terminator
|
||||||
|
datei datei_bei_fehleingabe variable regex ziffern_timeout_ms -->
|
||||||
|
<action application="play_and_get_digits"
|
||||||
|
data="1 1 1 3000 # @@PROJEKT@@/telefon/notruf_ton.wav silence_stream://250 notruf_taste ^1$ 3000"/>
|
||||||
|
<action application="execute_extension" data="notruf_taste_${notruf_taste} XML notruf_menue"/>
|
||||||
<action application="playback" data="@@PROJEKT@@/telefon/ansage.wav"/>
|
<action application="playback" data="@@PROJEKT@@/telefon/ansage.wav"/>
|
||||||
<!-- record: <datei> <max_sekunden> <stille_schwelle> <stille_sekunden> -->
|
<!-- record: <datei> <max_sekunden> <stille_schwelle> <stille_sekunden> -->
|
||||||
<action application="record"
|
<action application="record"
|
||||||
|
|
|
||||||
33
telefon/notruf_ton_bauen.sh
Executable file
33
telefon/notruf_ton_bauen.sh
Executable file
|
|
@ -0,0 +1,33 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# Erzeugt telefon/notruf_ton.wav aus profile/$PROFIL/notruf_ton.<ext>.
|
||||||
|
# Der Ton laeuft im Dialplan vor der Ansage; Taste 1 verbindet waehrenddessen
|
||||||
|
# zu Astra (siehe telefon/freeswitch/notruf_menue.xml.tpl).
|
||||||
|
# Format wie telefon/ansage.wav: 8 kHz mono PCM16, -3 dB Kopfraum.
|
||||||
|
#
|
||||||
|
# Hat das Profil keinen Ton, wird eine alte notruf_ton.wav entfernt. Der
|
||||||
|
# Dialplan findet dann keine Datei, play_and_get_digits kehrt sofort zurueck
|
||||||
|
# und der Anruf laeuft direkt zur Ansage - kein Ton, kein Menue.
|
||||||
|
set -euo pipefail
|
||||||
|
cd "$(dirname "$0")/.."
|
||||||
|
if [ -z "${PROFIL:-}" ] && [ -f .env ]; then
|
||||||
|
PROFIL=$(awk -F= '$1=="PROFIL"{gsub(/"/,"",$2); print $2}' .env)
|
||||||
|
fi
|
||||||
|
PROFIL="${PROFIL:-praxis}"
|
||||||
|
|
||||||
|
QUELLE=""
|
||||||
|
for ext in m4a ogg mp3 wav aiff; do
|
||||||
|
if [ -f "profile/$PROFIL/notruf_ton.$ext" ]; then
|
||||||
|
QUELLE="profile/$PROFIL/notruf_ton.$ext"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ -z "$QUELLE" ]; then
|
||||||
|
rm -f telefon/notruf_ton.wav
|
||||||
|
echo "Kein Notruf-Ton im Profil $PROFIL - telefon/notruf_ton.wav entfernt (kein Menue)."
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
ffmpeg -v error -y -i "$QUELLE" -af volume=-3dB -ar 8000 -ac 1 -c:a pcm_s16le telefon/notruf_ton.wav
|
||||||
|
DAUER=$(ffprobe -v error -show_entries format=duration -of csv=p=0 telefon/notruf_ton.wav)
|
||||||
|
printf 'telefon/notruf_ton.wav erzeugt (%.1f s, %s)\n' "$DAUER" "$QUELLE"
|
||||||
Loading…
Add table
Add a link
Reference in a new issue