Hi all,
This is not for the faint hearted and requires some reasonable level of Asterisk knowledge, with that said.
This is my version of how I get the Amazon Echo (Alexa) to announce my incoming calls.
There are loads of ways this can be done and I am merely providing one way.
It has a dependency that you have
- AmazonEchoControl binding setup and able to make announcements using TTS command.
- Also I recommend that you have the OH2 REST UI enabled it makes testing easier.
On Openhab I created the following:
items
Switch asteriskCall "Ring Group Call [%s]" { expire="3s,command=OFF" }
String asteriskCallerID "Caller ID [%s]"
String asteriskCallerIDCNAM "Caller ID Name [%s]"
Sitemap
Text label="Asterisk" icon=phone {
Default item=asteriskCallerID
Default item=asteriskCallerIDCNAM
Default item=asteriskCall
}
Rules
var String caller
val String precallerid = "Incoming call, "
rule "incoming call"
when
// asteriskCallerID is a string item which contains callerID populated in the asterisk dialplan
Item asteriskCallerID received command
then
logInfo("Asterisk-Caller-ID","Caller ID " + asteriskCallerID.state.toString )
logInfo("Asterisk-Caller-ID"," Incoming Call " + asteriskCall.state )
// home contacts, add a case statement for each number to announce.
if (asteriskCall.state==ON) {
// map known names to CID
var t = transform("MAP", "Home_Contacts.map", asteriskCallerID.state.toString)
caller = precallerid + " " + if(t == "") asteriskCallerID.state else t
**_LR_Echo_TTS_**.sendCommand(caller)
val CNAM = caller.toString.split(',').get(1)
logInfo("Asterisk-Caller-ID"," Caller CNAM: " + CNAM.toString )
postUpdate(asteriskCallerIDCNAM,CNAM)
}
end
Contacts are added in a map file after a great suggestion from @rikoshak, an example is shown below.
transform/Home_Contact.map
021XXXXXXX=Sue Mobile
027XXXXXXX=Paul Mobile
Make sure to add the contacts you want as mappings.
Make sure to change the Echo binding TTS command item to suit your environment.
Next, do some testing. ?Using the REST UI populate the asteriskCallerID parameter with a phone number.
Then using your Basic UI enable the switch ‘asteriskCall’ You should hear your echo device announce the incoming call.
Once the above is working its time to make asterisk populate the caller ID for incoming calls and also switch on the flag to say its an incoming call.
In my rather old v13 FreePBX asterisk install I went to the following conf files and added the following entries.
/etc/asterisk/extensions_override_freepbx.conf
[from-trunk]
exten => 0123456789,n,Set(IncCall=${SHELL(curl -X POST --header "Content-Type: text/plain" --header "Accept: application/json" -d "ON" "http://<OPENHAB>:8080/rest/items/asteriskCall" && echo -n 1 || echo -n 0)});
exten => 0123456789,n,NoOp(IncCall is ${IncCall});
Replace 0123456789 with the number people dial to reach you.
And replace < OPENHAB > with your OH2 IP address. also change the port if you need to
The first rule in the conf file does all the heavy lifting the second is just a result confirmation that will be visible in the asterisk console if you need it to test. a result of 1 is successful and a 0 is a failure.
Now you can do some more testing when you call your home number, asterisk should populate the Asterisk Caller ID information in your sitemap with the correct caller identity of the phone ringing you.
When that works fine we are on to the last step we want asterisk to switch on the incoming call switch so that the OH rule condition will match and the announcement will be spoken.
To do this, on your asterisk server you edit the same file and copy your ‘’ context from the extensions_additional.conf file. we then need to choose carefully where to add the following two lines,
exten => s,n,Set(InCallNUMResp=${SHELL(curl -X POST --header "Content-Type: text/plain" --header "Accept: application/json" --data-urlencode ${CALLERID(num)} "http://<OPENHAB>:8080/rest/items/asteriskCallerID" && echo -n 1 || echo -n 0)});
exten => s,n,NoOp(InCallNUMResp is ${InCallNUMResp});
In my version i decided to insert it in the macro-user-callerid context, I did this by copying the macro in its entirity into the override file and inserting the lines I wanted.
beelow is my example, yours may vary.
[macro-user-callerid]
exten => lang-playback,1,GosubIf($[${DIALPLAN_EXISTS(macro-user-callerid,${CHANNEL(language)})}]?macro-user-callerid,${CHANNEL(language)},${ARG1}():macro-user-callerid,en,${ARG1}())
exten => lang-playback,n,Return()
exten => s,1,Noop(override - Running through macro-user-callerid)
exten => s,n,Set(TOUCH_MONITOR=${UNIQUEID})
exten => s,n,Set(AMPUSER=${IF($["${AMPUSER}" = ""]?${CALLERID(number)}:${AMPUSER})})
exten => s,n,Noop(BEGIN - trigger openhab integration)
exten => s,n,Set(InCallNUMResp=${SH
ELL(curl -X POST --header "Content-Type: text/plain" --header "Accept: application/json" --data-urlencode ${CALLERID(num)} "http://<OPENHAB>:8080/rest/items/asteriskCallerID" && echo -n 1 || echo -n 0)});
exten => s,n,NoOp(InCallNUMResp is ${InCallNUMResp});
exten => s,n,Noop(END - Openhab integration)
exten => s,n,GotoIf($["${CUT(CHANNEL,@,2):5:5}"="queue" | ${LEN(${AMPUSERCIDNAME})}]?report)
exten => s,n,ExecIf($["${REALCALLERIDNUM:1:2}" = ""]?Set(REALCALLERIDNUM=${CALLERID(number)}))
exten => s,n,Set(AMPUSER=${DB(DEVICE/${REALCALLERIDNUM}/user)})
exten => s,n,GotoIf($["${AMPUSER}" = "none"]?limit)
exten => s,n,Set(AMPUSERCIDNAME=${DB(AMPUSER/${AMPUSER}/cidname)})
exten => s,n,ExecIf($["${ARG2}" != "EXTERNAL" & ${DB_EXISTS(AMPUSER/${AMPUSER}/cidnum)} & "${AMPUSER}" != "${DB(AMPUSER/${AMPUSER}/cidnum)}"]?Set(__CIDMASQUERADING=TRUE))
exten => s,n,GotoIf($["${AMPUSERCIDNAME:1:2}" = ""]?report)
exten => s,n,Set(AMPUSERCID=${IF($["${ARG2}" != "EXTERNAL" & "${DB_EXISTS(AMPUSER/${AMPUSER}/cidnum)}" = "1"]?${DB_RESULT}:${AMPUSER})})
exten => s,n,Set(__DIAL_OPTIONS=${IF($["${DB_EXISTS(AMPUSER/${AMPUSER}/dialopts)}" = "1"]?${DB_RESULT}:${DIAL_OPTIONS})})
exten => s,n,Set(CALLERID(all)="${AMPUSERCIDNAME}" <${AMPUSERCID}>)
exten => s,n,GotoIf($["${ARG1}"="LIMIT" & ${LEN(${AMPUSER})} & ${DB_EXISTS(AMPUSER/${AMPUSER}/concurrency_limit)} & ${DB(AMPUSER/${AMPUSER}/concurrency_limit)}>0 & ${GROUP_COUNT(${AMPUSER}@concurrency_limit)}>=${DB(AMPUSER/${AMPUSER}/concurrency_limit)}]?limit)
exten => s,n,ExecIf($["${ARG1}"="LIMIT" & ${LEN(${AMPUSER})}]?Set(GROUP(concurrency_limit)=${AMPUSER}))
exten => s,n,ExecIf($["${DB(AMPUSER/${AMPUSER}/language)}" != ""]?Set(CHANNEL(language)=${DB(AMPUSER/${AMPUSER}/language)}))
exten => s,n(report),Noop(Macro Depth is ${MACRO_DEPTH})
exten => s,n,GotoIf($["${MACRO_DEPTH}" = "" | ${MACRO_DEPTH} < 6 ]?report2:macroerror)
exten => s,n(report2),GotoIf($[ "${ARG1}" = "SKIPTTL" | "${ARG1}" = "LIMIT" ]?continue)
exten => s,n,ExecIf($["${CALLEE_ACCOUNCODE}" = ""]?Set(__CALLEE_ACCOUNCODE=${DB(AMPUSER/${IF($["${MACRO_CONTEXT}"="macro-exten-vm"]?${ARG2}:${MACRO_EXTEN})}/accountcode)}))
exten => s,n(report3),Set(__TTL=${IF($["foo${TTL}" = "foo"]?64:$[ ${TTL} - 1 ])})
exten => s,n,GotoIf($[ ${TTL} > 0 ]?continue)
exten => s,n,Wait(${RINGTIMER})
exten => s,n,Answer
exten => s,n,Wait(1)
exten => s,n,Gosub(macro-user-callerid,lang-playback,1(hook_0))
exten => s,n,Macro(hangupcall,)
exten => s,n(macroerror),Noop(Macro Limit Reached. Aborting Call)
exten => s,n,Answer
exten => s,n,Wait(1)
exten => s,n,Gosub(macro-user-callerid,lang-playback,1(hook_2))
exten => s,n,Macro(hangupcall,)
exten => s,n(limit),Answer
exten => s,n,Wait(1)
exten => s,n,Gosub(macro-user-callerid,lang-playback,1(hook_1))
exten => s,n,Macro(hangupcall,)
exten => s,n,Congestion(20)
exten => s,n(continue),Set(CALLERID(number)=${CALLERID(number):0:40})
exten => s,n,Set(CALLERID(name)=${CALLERID(name):0:40})
exten => s,n,GotoIf($["${CALLERID(name)}" = ""]?cnum)
exten => s,n,Set(CDR(cnam)=${CALLERID(name)})
exten => s,n(cnum),Set(CDR(cnum)=${CALLERID(num)})
exten => s,n,Set(CHANNEL(language)=${MASTER_CHANNEL(CHANNEL(language))})
exten => h,1,Macro(hangupcall,)
exten => en,1(hook_0),Playback(im-sorry&an-error-has-occurred&with&call-forwarding)
exten => en,n,Return()
exten => en,n(hook_1),Playback(beep&im-sorry&your&simul-call-limit-reached&goodbye)
exten => en,n,Return()
exten => en,n(hook_2),Playback(im-sorry&an-error-has-occurred)
exten => en,n,Return()
exten => ja,1(hook_0),Playback(im-sorry&call-forwarding&jp-no&an-error-has-occured)
exten => ja,n,Return()
exten => ja,n(hook_1),Playback(beep&im-sorry&simul-call-limit-reached)
exten => ja,n,Return()
exten => ja,n(hook_2),Playback(im-sorry&an-error-has-occured)
exten => ja,n,Return()
;End of macro-user-callerid-custom
you will see the two Openhab integration lines in the second block of code.
Anytime you edit the asterisk conf files make sure you run ‘dialplan reload’ at the console CLI so that the changes take effect.
if you have any issues simply delete the stuff out of the override file that you put in and reload the dialplan and it all should return to the point prior to you modifying it.
[EDIT] I have now updated to include the mapping suggestion from Rich.
Good luck
Paul