Asterisk automated phone call with tts and DTMF

So first we need a bash script that is readable by openhab

#!/bin/bash

AMI_HOST="192.168.1.1"
AMI_PORT="5038"
AMI_USERNAME="openhab"
AMI_SECRET="PASSWORD1234"
PHONE_NUMBER="911"
ALARM_TEXT=$1

(
echo "Action: Login"
echo "Username: $AMI_USERNAME"
echo "Secret: $AMI_SECRET"
echo "Events: off"
echo
echo "Action: Originate"
echo "Channel: Local/s@external-notify"
echo "Exten: s"
echo "Priority: 1"
echo "Context: external-notify"
echo "Variable: TO_SAY=$ALARM_TEXT"
echo "Variable: PHONE_NUMBER=$PHONE_NUMBER"
echo "Async: yes"
echo
echo "Action: Logoff"
echo
) | nc $AMI_HOST $AMI_PORT -q 20

then we also need some rule to trigger that

var boolean dtmfDetectionEnabled = false

rule "Call pbx test external"
when
    Item lightitem_test changed to ON
then
    dtmfDetectionEnabled = true // Enable DTMF detection
    executeCommandLine("/etc/openhab/misc/sip_external_nr.sh", "Hello!!!. OpenHAB has detected side lamp to be on. Do you want to turn it off or leave it on??. Press 1 to leave it on or press 0 to turn it off after the tone!!!.")
    logWarn("Script result", "Calling external number first attempt")

    createTimer(now.plusSeconds(30), [ |
        val hangupStatus = status_string_voip.state.toString
        if (hangupStatus == "Hang-up") {
            executeCommandLine("/etc/openhab/misc/sip_external_nr.sh", "Hello!!!. Second call attempt. OpenHAB has detected side lamp to be on. Do you want to turn it off or leave it on??. Press 1 to leave it on or press 0 to turn it off after the tone!!!.")
            logWarn("Second call result", "Calling external number second attempt")
        }
    ])
end

rule "Handle DTMF Input pbx test external"
when
    Item dtmf_string_voip received update
then
    if (dtmfDetectionEnabled == true && dtmf_string_voip.state instanceof StringType) {
        val dtmfInput = dtmf_string_voip.state.toString
        switch (dtmfInput) {
            case "1": {
                // The user chose to leave the light on
                dtmfDetectionEnabled = false
                logInfo("DTMF input", "User chose to leave the light on.")
            }
            case "0": {
                // The user chose to turn the light off
                lightitem_test .sendCommand(OFF)
                dtmfDetectionEnabled = false
                logInfo("DTMF input", "User chose to turn the light off.")
            }
            case "*": {
                // The user hung up
                logInfo("DTMF input", "User hung up.")
                dtmfDetectionEnabled = false // Disable DTMF detection
            }
        }
    }
end

then we also need to string items

String status_string_voip
String dtmf_string_voip

and finally a dial plan

[external-notify] ; this is a test script to prove sip notification for
exten => s,1,Verbose(2,Openhab automated call external)
same => n,Set(status_string=Calling in progress)
same => n,System(curl -X POST --header "Content-Type: text/plain" --header "Accept: application/json" -d "${status_string}" -H "Authorization: Bearer oh.asterisk.blablabla" "http://192.168.1.1:8080/rest/items/status_string_voip")
same => n,Dial(SIP/trunkname/${PHONE_NUMBER},30,tR)
same => n,Set(DIALSTATUS=${DIALSTATUS})
same => n,Set(call_duration=${ANSWEREDTIME})
same => n,GotoIf($["${DIALSTATUS}"="NOANSWER"]?noanswer:amd)

same => n(amd),AMD()
same => n,NoOp(AMD status: ${AMDSTATUS})
same => n,System(curl -X POST --header "Content-Type: text/plain" --header "Accept: application/json" -d "${AMDSTATUS}" -H "Authorization: Bearer oh.asterisk.blablabla" "http://192.168.1.1:8080/rest/items/status_string_voip")
same => n,GotoIf($[${AMDSTATUS}=HUMAN]?humn:vmachn)

same => n(vmachn),Set(status_string=Voicemail detected)
same => n,System(curl -X POST --header "Content-Type: text/plain" --header "Accept: application/json" -d "${status_string}" -H "Authorization: Bearer oh.asterisk.blablabla" "http://192.168.1.1:8080/rest/items/status_string_voip")
same => n,Hangup()

same => n(humn),Set(status_string=Call connected)
same => n,System(curl -X POST --header "Content-Type: text/plain" --header "Accept: application/json" -d "${status_string}" -H "Authorization: Bearer oh.asterisk.blablabla" "http://192.168.1.1:8080/rest/items/status_string_voip")
same => n,Answer()
same => n,Set(TEXT=${TO_SAY})
same => n,System(echo ${TEXT} | text2wave -o /tmp/festival.wav -eval "(voice_cmu_us_slt_arctic_hts)")
same => n,System(sox /tmp/festival.wav -r 8000 /tmp/festival_resampled.wav)
same => n(startLoop),Wait(2)
same => n,Playback(/tmp/festival_resampled)
same => n,Read(DTMF,beep,1)
same => n,GotoIf($["${DTMF}"=""]?startLoop:hang)

same => n(noanswer),Set(status_string=Call not answered)
same => n,System(curl -X POST --header "Content-Type: text/plain" --header "Accept: application/json" -d "${status_string}" -H "Authorization: Bearer oh.asterisk.blablabla" "http://192.168.1.1:8080/rest/items/status_string_voip")
same => n,Hangup()

same => n(hang),NoOp(DTMF String: ${DTMF})
same => n,Set(dtmf_string=${DTMF})
same => n,System(rm -f /tmp/festival.wav /tmp/festival_resampled.wav)
same => n,System(curl -X POST --header "Content-Type: text/plain" --header "Accept: application/json" -d "${dtmf_string}" -H "Authorization: Bearer oh.asterisk.blablabla" "http://192.168.1.1:8080/rest/items/dtmf_string_voip")
same => n,Set(status_string=*)
same => n,System(curl -X POST --header "Content-Type: text/plain" --header "Accept: application/json" -d "${status_string}" -H "Authorization: Bearer oh.asterisk.blablabla" "http://192.168.1.1:8080/rest/items/status_string_voip")
same => n,Hangup()

exten => h,1,Set(status_string=Hang-up)
same => n,System(curl -X POST --header "Content-Type: text/plain" --header "Accept: application/json" -d "${status_string}" -H "Authorization: Bearer oh.asterisk.blablabla" "http://192.168.1.1:8080/rest/items/status_string_voip")
same => n,System(curl -X POST --header "Content-Type: text/plain" --header "Accept: application/json" -d "*" -H "Authorization: Bearer oh.asterisk.blablabla" "http://192.168.1.1:8080/rest/items/dtmf_string_voip")
same => n,Hangup()

Make sure you have festival installed with the specific voice package and also amd() loaded into asterisk with a conf like this

;
; Answering Machine Detection Configuration

[general]
initial_silence = 5000
greeting = 1500
after_greeting_silence = 1000
total_analysis_time = 5000
min_word_length = 120
between_words_silence = 50
maximum_number_of_words = 3
silence_threshold = 384
maximum_word_length = 4000

Also this part of dial plan oh.asterisk.blablabla is you api key that you can generate from openhab help and about section when you log in

This topic was automatically closed 41 days after the last reply. New replies are no longer allowed.