home automation with asterisk - astricon 2015 - alberto sagredo castro

39
Home Automation with Asterisk Alberto Sagredo Castro www.voipnovatos.es 10/14/2015

Upload: alberto-sagredo-castro

Post on 22-Jan-2017

18.468 views

Category:

Technology


2 download

TRANSCRIPT

Home Automation with Asterisk

Alberto Sagredo Castro

www.voipnovatos.es

10/14/2015

Who i am• Alberto Sagredo Castro

• a.k.a @albersag on twitter

• Working in VoIP since ten years ago

• Working with Asterisk for about 10 years

• Several large projects with Asterisk and many Asterisk compiled thru Spain and Europe

• Working for Avanzada 7 and USA VOIP

• Other Stuff : Mikrotik, Ubiquiti, Ham Radio and all that contains bits on it

2

Why home automation

• It makes life easier

• Its not expensive

• It helps disabled people

• Internet of Things (IOT) is here

• Its not complex

• Eco friendly and save money

• Just play !3

Home automation vs Asterisk

4

• Asterisk natively does not support home automation protocols

• We need something to interact with ha (home automation)

• What could we use? PHPARI, AGI, .call files, asterisk dialplan, SQL …

• Any programmer here? What about chan_zwave :)

Which protocol to use

5

• home automation is plenty of protocols, open, proprietary, half open half proprietary :) all flavours.

• smarthings

• z-wave

• knx

• insteon

• x10

• zigbee

• opensprinkler

• MQTT

Z-Wave

6

• Its a “propietary” protocol owned by Sigma Designs

• Its widely supported by enterprise and really good compatibility

• Its cheap (50 $/device)

• USA & EU frecuencies

• Feedback from device status

• Low energy

• Zwave alliance (+ 400 manufacturers)

• Mesh network between devices. Good for homes

7

Do not reinvent the wheel

8

• Ok. Asterisk does not support (yet) home automation but i want to use Asterisk in my home automation system…. What could i do?

• I will use Asterisk to generate calls when events happens on my HA system and to interact with them by phone.

• Phone is easier than using apps and works on any platform :)

OpenHab

9

• Its the swedish knife (a.k.a Olle :) for home automation.

• Lots of binding, plenty of protocols supported and many more

• REST API

• Items

• Sitemaps

• Scripts / Rules (Xtend scripting language)

• Transforms

• Interface to admin Habmin and App for design (Openhab Designer)

OpenHab

10

• Its Java .

• Runs on BananaPi or Raspberry Pi without any issues.

• Easy to install.

• Easy as Asterisk to configure.

• Scripting language so you would feel confortable with it

OpenHab

11

How to start

12

• We would need an USB Zwave Dongle (Aeon Labs, Zwave.me,…)

• A Raspberry Pi or Banana Pi

• Zwave devices

• Asterisk of course

• Internet for notifications and persistent data to the cloud

How to start

13

Installing OpenHab

14

• If you use Debian install repos

curl 'https://bintray.com/user/downloadSubjectPublicKey?username=openhab' | sudo apt-key add -

echo "deb http://dl.bintray.com/openhab/apt-repo stable main" | sudo tee /etc/apt/sources.list.d/openhab.list

sudo apt-get update

sudo apt-get install openhab-runtime

update-rc.d openhab defaults

service openhab start

Install Java & esential bindings

15

sudo tar zxvf jdk-8-ea-b36e-linux-arm-hflt-*.tar.gz -C /opt

sudo update-alternatives --install "/usr/bin/java" "java" "/opt/jdk1.8.0/bin/java" 1

sudo update-alternatives for other commands if needed (e.g. javac).

java -version

Install Java & esential bindings

16

sudo apt-get install openhab-addon-binding-samsungtv

sudo apt-get install openhab-addon-binding-zwave

sudo apt-get install openhab-addon-io-myopenhab

sudo apt-get install openhab-addon-persistence-exec openhab-addon-persistence-logging

sudo apt-get install openhab-addon-binding-opensprinkler

sudo apt-get install openhab-addon-binding-http openhab-addon-binding-ntp

sudo apt-get install openhab-addon-action-pushover

sudo apt-get install openhab-addon-binding-asterisk

Asterisk

17

Install Asterisk

Enable manager (AMI) , http and ARI

and Lets see how to integrate!

Integration. Lets fun!

18

• Lets focus in how to integrate this cool “weapons” together.

• We could use:

• ARI

• REST API

• CLI

• .call files

• AstDB

• MySQL

• etc…..

Dangerous Demo 1

19

• IVR to interact with Lights and if everything goes fine, open my garden sprinklers in spain remotely (dont be nasty)

• WIFI SSID -> “VOIPNOVATOS”

• Asterisk -> “10.0.2.x”

• User Extension “20x”

• Password : “astricon” of course

• Call 666 and don't be evil!

Dangerous Demo 1

20

• Asterisk Dialplan [astricon-ivr]

exten => s,1,Noop exten => s,n,Background(welcomeivr) exten => s,n,WaitExten(10) exten => s,n,Hangup

exten => 1,1,Noop(Turn on light) exten => 1,n,GotoIf($[${DB(light/astricon)} = "ON"]?lighton:lightoff) exten => 1,n(lighton),Set(${DB(light/astricon)="OFF"}) exten => 1,n,System(curl --header "Content-Type: text/plain" --request POST --data "OFF" http://10.0.2.2:8080/rest/items/Z_Socket1/) exten => 1,n,Playback(lightoff) exten => 1,n,Hangup exten => 1,n(lightoff),Set(${DB(light/astricon)="ON"}) exten => 1,n,System(curl --header "Content-Type: text/plain" --request POST --data "ON" http://10.0.2.2:8080/rest/items/Z_Socket1/) exten => 1,n,Playback(lighton) exten => 1,n,Hangup

exten => 2,1,Noop(Fire Alarm) exten => 2,n,GotoIf($[${DB(alarm/astricon)} = "ON"]?fired:notfired) exten => 2,n(fired),Set(${DB(alarm/astricon)="OFF"}) exten => 2,n,System(curl --header "Content-Type: text/plain" --request POST --data "OFF" http://10.0.2.2:8080/rest/items/FortrezZ_Siren) exten => 2,n,Playback(thieves) exten => 2,n,Hangup exten => 2,n(notfired),Set(${DB(alarm/astricon)="ON"}) exten => 2,n,System(curl --header "Content-Type: text/plain" --request POST --data "ON" http://10.0.2.2:8080/rest/items/FortrezZ_Siren) exten => 2,n,Playback(nothieves) exten => 2,n,Hangup

exten => 3,1,Noop(Sprinkler) exten => 3,n,GotoIf($[${DB(sprinkler/astricon)} = "ON"]?on:off) exten => 3,n(on),Set(${DB(sprinkler/astricon)="OFF"}) exten => 3,n,System(curl --header "Content-Type: text/plain" --request POST --data "OFF" http://10.0.2.2:8080/rest/items/Sprinklers_Zone4) exten => 3,n,Playback(closedsprinklers) exten => 3,n,Hangup exten => 3,n(off),Set(${DB(sprinkler/astricon)="ON"}) exten => 3,n,System(curl --header "Content-Type: text/plain" --request POST --data "ON" http://10.0.2.2:8080/rest/items/Sprinklers_Zone4) exten => 3,n,Playback(opensprinklers) exten => 3,n,Hangup

Dangerous Demo 2

21

• For some people it could be great to interact using voice while in its home. Being at home or not, Asterisk could turn on lights, turn off alarm and make emergency calls

• Use Google ASR, Its free and it works well! (Use latest agi version as oldest has issues)

• You need internet connection! Hope astricon one would work well!

Dangerous Demo 2

22

• Google ASR

• Asterisk Speech Recognition http://zaf.github.io/asterisk-speech-recog/

Dangerous Demo 2

23

• Asterisk Dialplan [astricon-asr]

exten => s,1,Noop exten => s,n,Background(welcomeivr) exten => s,n,agi(speech-recog-tiny.agi,en-US) exten => s,n,Verbose(1,The text you just said is: ${utterance}) exten => s,n,Verbose(1,The probability to be right is: ${confidence}) exten => s,n,GotoIf($["${uterance}" = "fire alarm"]?firealarm) exten => s,n,GotoIf($["${uterance}" = "turn on"]?turnonlight:out) exten => s,n(firealarm),Goto(firealarm,1) exten => s,n,Hangup exten => s,n(turnonlight),Goto(turnonlight,1) exten => s,n(out),Hangup

exten => turnonlight,1,Noop(Turn on light) exten => turnonlight,n,GotoIf($[${DB(light/astricon)} = "ON"]?lighton:lightoff) exten => turnonlight,n(lighton),Set(DB(light/astricon)="OFF") exten => turnonlight,n,System(curl --header "Content-Type: text/plain" --request POST --data "OFF" http://10.0.2.19:8080/rest/items/Z_Socket1/) exten => turnonlight,n,Playback(lightoff) exten => turnonlight,n,Hangup exten => turnonlight,n(lightoff),Set(DB(light/astricon)="ON") exten => turnonlight,n,System(curl --header "Content-Type: text/plain" --request POST --data "ON" http://10.0.2.19:8080/rest/items/Z_Socket1/) exten => turnonlight,n,Playback(lighton) exten => turnonlight,n,Hangup

exten => firealarm,1,Noop(Fire Alarm) exten => firealarm,n,GotoIf($[${DB(alarm/astricon)} = "ON"]?fired:notfired) exten => firealarm,n(fired),Set(DB(alarm/astricon)="OFF") exten => firealarm,n,System(curl --header "Content-Type: text/plain" --request POST --data "OFF" http://10.0.2.19:8080/rest/items/FortrezZ_Siren) exten => firealarm,n,Playback(nothieves) exten => firealarm,n,Hangup exten => firealarm,n(notfired),Set(DB(alarm/astricon)="ON") exten => firealarm,n,System(curl --header "Content-Type: text/plain" --request POST --data "ON" http://10.0.2.19:8080/rest/items/FortrezZ_Siren) exten => firealarm,n,Playback(thieves) exten => firealarm,n,Hangup

Dangerous Demo 3

24

• Smart followme

• You can use Wifi to detect you are at home or presence detectors.

• If you are outside home, divert your calls to cell phone. Just ring on Kitchens phone if you are cooking (Advise: this will not work if you have kids moving around)

• Here we could use AGI to get motion status from Openhab.

Dangerous Demo 3

25

• Asterisk Dialplan

[astricon-presence]

exten => s,1,Answer() exten => s,n,AGI(openhab.agi, "asterisk", "password", "Fibaro_Motion_1_Motion", "atHomeMotion") exten => s,n,AGI(openhab.agi, "asterisk", "password", "Home_Presence", "atHomeWifi") exten => s,n,GotoIf($["${atHomeMotion}" == "ON"]?athome) exten => s,n,GotoIf($["${atHomeWifi}" == "ON"]?athome:away) exten => s,n,Goto(bye) exten => s,n(athome),Playback(movementdetected) exten => s,n,Hangup() exten => s,n(away),Playback(movementnotdetected) exten => s,n(bye),Hangup()

[astricon-presence2]

exten => s,1,Answer() exten => s,n,GotoIf($["${PRESENCE}" == "ON"]?athome:away) exten => s,n(athome),Playback(movementdetected) exten => s,n,Hangup() exten => s,n(away),Playback(movementnotdetected) exten => s,n,Hangup()

Dangerous Demo 3

26

• Openhab.agi

#!/usr/bin/python

import sys,os,datetime import httplib import base64

def send(data): sys.stdout.write("%s \n"%data) sys.stdout.flush()

AGIENV={} env = "" while(env != "\n"): env = sys.stdin.readline() envdata = env.split(":") if len(envdata)==2: AGIENV[envdata[0].strip()]=envdata[1].strip()

username = AGIENV['agi_arg_1'] password = AGIENV['agi_arg_2'] item = AGIENV['agi_arg_3'] varname = AGIENV['agi_arg_4']

auth = base64.encodestring('%s:%s' % (username, password)).replace('\n', '') headers = {"Authorization" : "Basic %s" % auth} conn = httplib.HTTPConnection("localhost", 8080) conn.request('GET', "/rest/items/%s/state"%item, "", headers) response = conn.getresponse() item_state = response.read()

send("SET VARIABLE %s %s"%(varname, item_state)) sys.stdin.readline()

Dangerous Demo 3

27

• Openhab rules

rule "MotionOn" when Item Fibaro_Motion_1_Motion changed from OFF to ON then counter = counter + 1 logInfo("Rules", "Motion Rule ON") executeCommandLine("/usr/src/openhab/configurations/rules/curlon.sh") pushover("Motion Detected on Astricon")

end

rule "MotionOff" when Time cron "0 */2 * * * ?" then

if(lastCheck == counter) { counter = 0 lastCheck = -1;

logInfo("Rules", "Motion Rule OFF") executeCommandLine("/usr/src/openhab/configurations/rules/curloff.sh") } else { lastCheck = counter } end

Dangerous Demo 3

28

• Openhab rules var Timer timer = null

rule "MotionOn2" when Item Fibaro_Door changed then

if(Fibaro_Door.state==ON) { executeCommandLine("/etc/openhab/configurations/rules/curlondoor.sh") if(timer==null) { timer = createTimer(now.plusSeconds(10)) [| executeCommandLine("/etc/openhab/configurations/rules/curloffdoor.sh") ] } else { timer.reschedule(now.plusSeconds(10)) } } else if(Fibaro_Door.state==OFF) { if(timer!=null) { timer.cancel timer = null } }

end

Dangerous Demo 3

29

• Wifi Detector #!/bin/sh

macalberto="f0:27:2d:00:44:12" athome=0

macs=$(iw dev wlan0 station dump | grep Station | cut -f 2 -s -d" ")

for mac in $macs; do case $mac in "$macalberto") athome=1;; esac done

if [ $athome -eq 1 ]; then

curl --header "Content-Type: text/plain" --request POST --data "ON" http://10.0.2.19:8080/rest/items/Home_Presence/

else

curl --header "Content-Type: text/plain" --request POST --data "OFF" http://10.0.2.19:8080/rest/items/Home_Presence/

fi

• curlon.sh #!/bin/bash curl -v -u asterisk:asterisk -X POST "http://10.0.2.19:8088/ari/asterisk/variable?variable=PRESENCEvalue=ON&api_key=asterisk:asterisk"

Dangerous Demo 4

30

• Create your own Alarm System controlled by phone

• We could arm alarm system by phone

• No monthly fees

• If armed and motion is detected call police or call you before police that would be better :)

• If fired, open sprinklers at garden..

• Used ARI to gen calls on Asterisk

Dangerous Demo 4

31

• ari.conf [general] enabled = yes

allowed_origins=http://ari.asterisk.org

[asterisk] type = user read_only = no password = asterisk

• http.conf [general] enabled = yes bindaddr=0.0.0.0

• manager.conf [general] enabled = yes ;webenabled = yes

port = 5038 bindaddr = 127.0.0.1

[asterisk] secret = asterisk read = system,call,log,verbose,agent,user,config,dtmf,reporting,cdr,dialplan write = system,call,agent,user,config,command,reporting,originate,message

Dangerous Demo 4

32

• extensions.conf [extensiones]

exten => _2XX,1,Dial(SIP/${EXTEN},20,TtrR) exten => _2XX,n,hangup

exten => 900,1,Answer exten => 900,n,Playback(policecall) exten => 900,n,Ringing() exten => 900,n,Wait(10) exten => 900,n,Hangup

• alarmon.sh #!/bin/bash curl -v -u asterisk:asterisk -X POST "http://10.0.2.19:8088/ari/asterisk/variable?variable=ALARM&value=ON&api_key=asterisk:asterisk" curl -v -u asterisk:asterisk -X POST "http://10.0.2.19:8088/ari/channels?endpoint=SIP%2F201&extension=900&context=extensiones&priority=1&callerId=ALARM%20DETECTED%20ASTRICON&timeout=30&api_key=asterisk:asterisk"

Dangerous Demo 4

33

• Openhab rules rule "Alarm" when Item Fibaro_Door changed from OFF to ON

then

if(Fibaro_Door.state == ON && Alarm_Switch.state == ON ) { logInfo("Rules", "Alarm Alarm Alarm") executeCommandLine("/etc/openhab/configurations/rules/alarmon.sh") pushover("Alarm on Astricon") }

end

rule "Water" when Item Fibaro_Flood changed

then

if(Fibaro_Flood.state == 255 && Alarm_Switch.state == ON ) { logInfo("Rules", "Alarm Alarm Alarm") executeCommandLine("/etc/openhab/configurations/rules/alarmon.sh") pushover("Alarm on Astricon") }

end

Bonus Demo

34

• Asterisk Ringing Status and Called/Calling Number

• We have an openhab binding but it does not work with new AMI

• Using JSON answer from Asterisk ARI and jq , json parser will try to get this working.

Bonus Demo

35

• extensions.conf [extensiones]

exten => 999,1,Set(${CALLERID(num)}=778811) exten => 999,n,System(curl --header "Content-Type: text/plain" --request POST --data "ON" http://10.0.2.19:8080/rest/items/Asterisk_Ring) exten => 999,n,Ringing() exten => 999,n,Wait(10) exten => 999,n,Answer() exten => 999,n,Echo() exten => 999,n,Hangup

exten => h,1,System(curl --header "Content-Type: text/plain" --request POST --data "OFF" http://10.0.2.19:8080/rest/items/Asterisk_Ring)

• call.sh #!/bin/bash

json_clause=$(curl http://10.0.2.19:8088/ari/channels?api_key=asterisk:asterisk)

state=$(echo $json_clause | jq '.[0].state') name=$(echo $json_clause | jq '.[0].name') numbercalling=$(echo $json_clause | jq '.[0].caller.number') numbercalled=$(echo $json_clause | jq '.[0].dialplan.exten') numbercalled2=$(echo $json_clause | jq '.[0].connected.number')

curl --header 'Content-Type: text/plain' --request PUT --data "$numbercalling" http://localhost:8080/rest/items/Active_Calling/state/ curl --header 'Content-Type: text/plain' --request PUT --data "$numbercalled" http://localhost:8080/rest/items/Active_Called/state/

Bonus Demo

36

• Openhab rules rule "Call" when Item Asterisk_Ring changed then

if(Asterisk_Ring.state == ON) {

executeCommandLine("bash /etc/openhab/configurations/rules/call.sh") }

if(Asterisk_Ring.state == OFF) { executeCommandLine(" bash /etc/openhab/configurations/rules/calloff.sh") }

end

Questions?

37

Resources

38

• www.openhab.org

• https://github.com/openhab/openhab/wiki/Samples-Rules

• https://github.com/openhab/openhab/wiki/Explanation-of-items

• https://github.com/openhab/openhab/wiki/Linux---OS-X

• http://raspberrypi.stackexchange.com/questions/4683/how-to-install-the-java-jdk-on-raspberry-pi

• http://zaf.github.io/asterisk-speech-recog/

• http://tinsley.io/2015/03/openhab-presence-detection-with-dd-wrt/

Thanks

39

• To my wife and kids they are always with me and also here (Disney off course :)

• All friends wishing luck these days

• To Fibaro

• To Digium for inviting me. It has been a pleasure and an amazing christmas gift!

• To all of you for attending!