-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathrpi-echo.py
More file actions
192 lines (150 loc) · 5.17 KB
/
rpi-echo.py
File metadata and controls
192 lines (150 loc) · 5.17 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
#!/usr/bin/env python
#########################
#
# Python script using Amazon Alexa or Echo to control Raspberry Pi using an older version
# fauxmo. It only supports one device and two commands.
#
# To control a device say:
#
# Alexa, turn <device> <command>
#
# The scripts here are based on this Instructable
# https://www.instructables.com/id/Control-Raspberry-Pi-GPIO-Using-Amazon-Echo-Fauxmo/
#
# The script can be run on the command or as a systemd servioce:
# To run the script from the command line use:
#
# $ python rpi-echo.py
#
# Once the script is running, say to Amazon Alexa: Alexa, discover devices
#
# $ ps aux | grep rpi-echo
#
# should show two entries for rpi-echo, one is the command above and the other is the script
#
# Wait for dsicovery to complete
#
# If a mistake is made, then delete discovered devices from Alexa app on smartphone
#
# MAKE THE CHANGES IS INDICATED IN THE CODE BELOW
#
# Nothing else needs to be added to this script or any of the others
#
# be sure to rm *.pyc if any changes are made
#
#########################
#########################
# the following lines must go here, otherwise fauxmo does not initialize properly
import mylog
global Log
Log = mylog.mylog('/home/pi', 'rpi-echo.log')
mylog.setLogObject(Log)
import fauxmo
import time
import datetime
import subprocess
# set to True when debugging, otherwise set to False
Log.setDebug(False)
# Starting port, which should be greater than 1024. Each command requires a unique port
# The starting port doesn't need to be changed
startingPort = 5070
# THE BELOW ITEMS SHOULD BE THE ONLY CHANGES REQUIRED
# Enter your device name for Alex/Echo
device = ['security']
# These are the actions to be taken when the echo command is received
#
# The number of actions must equal the number of commands
#
# An action is any command that can be executed from the command line
# example actions:
# sudo shutdown -h 0
# sudo reboot
# python script.py
actions = ['python /usr/local/bin/sleep.py', 'python /usr/local/bin/disarm.py']
# THE ABOVE ITEMS SHOULD BE THE ONLY CHANGES REQUIRED
# I modified these lines in fauxmo.py, which hard codes ON and OFF.
# The commented lines are the originals.
# # success = self.action_handler.on(client_address[0], self.name)
# success = self.action_handler.on(client_address[0], 'ON')
#
# # success = self.action_handler.off(client_address[0], self.name)
# success = self.action_handler.off(client_address[0], 'OFF')
#
# If the commands are changed, then you must change fuaxmo.py
commands = ['ON', 'OFF']
#########################
def getLogHandler():
return Log
class debounce_handler(object):
# prevent multiple Echos from responding to one voice command
DEBOUNCE_SECONDS = 0.3
def __init__(self):
self.lastEcho = time.time()
def on(self, client_address, name):
if self.debounce():
return True
return self.act(client_address, True, name)
def off(self, client_address, name):
if self.debounce():
return True
return self.act(client_address, False, name)
def act(self, client_address, state):
pass
def debounce(self):
if (time.time() - self.lastEcho) < self.DEBOUNCE_SECONDS:
return True
self.lastEcho = time.time()
return False
class device_handler(debounce_handler):
def trigger(self, port, state):
Log.printMsg('trigger: port: ' + str(port) )
def act(self, client_address, state, name):
global commands
global actions
notFound = True
try:
i = 0
for cmd in commands:
if name == cmd:
Log.printMsg("action: " + name + " from Echo " + str(client_address))
subprocess.call(actions[i], shell=True)
notFound = False
i = i + 1
except:
Log.printMsg("rpi-echo: device_handler: act: try failed: " + name)
if notFound:
Log.printMsg("unhandled command received: " + name)
return True
if __name__ == "__main__":
Log.printMsg("*** STARTING WEMO SERVER ***")
# setup parameters for fauxmo
# Plug-and-Play Listener
l = fauxmo.upnp_broadcast_responder()
l.init_socket()
# Poller
p = fauxmo.poller()
p.add(l)
# Register the device callback for handler
d = device_handler()
# Name the device
# fauxmo.fauxmo corresponds to fauxmo.py: fauxmo: __init__
port = startingPort
for dev in device:
fauxmo.fauxmo(dev, l, p, None, port, d)
port = port + 1
# Loop forever waiting for incoming Echo requests
Log.printMsg("Entering WeMo polling loop")
try:
while True:
# Allow time for a ctrl-c to stop the process
p.poll(100)
time.sleep(0.1)
except Exception, e:
Log.printMsg("ERROR: critical exception occurred: " + str(e))
except KeyboardInterrupt: # trap a CTRL+C keyboard interrupt
Log.printMsg("keyboard exception occurred")
except Exception as ex:
Log.printMsg("ERROR: an unhandled exception occurred: " + str(ex))
finally:
Log.printMsg("** STOPPING WEMO SERVER ***")
Log.closeLogFile()