-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathShac4Pi_HOWTO
More file actions
343 lines (276 loc) · 14.7 KB
/
Copy pathShac4Pi_HOWTO
File metadata and controls
343 lines (276 loc) · 14.7 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
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
Shac4Pi setup and HOWTO
=======================
Written by Philip Booysen <philipbooysen@gmail.com>
Fri Apr 24 13:46:24 SAST 2015
Objective : Fire up a XMPP based python client on a Raspberry Pi Model B (version 1)
such that it is able to persistently be logged into Gtalk, such that when
commands or GPIO pin high/low commands are sent via XMPP buddies to this
account,
1) Download Raspian image
Reference : https://www.raspberrypi.org/downloads/
Linked : http://downloads.raspberrypi.org/raspbian_latest
At time of writing the above linked to :
$ wget http://director.downloads.raspberrypi.org/raspbian/images/raspbian-2015-02-17/2015-02-16-raspbian-wheezy.zip
2) Put the image on SDcard
$ sudo dd bs=4M if=2015-02-16-raspbian-wheezy.img of=/dev/mmcblk0
3) Boot Raspbian using a Raspberry Pi
4) Log in (if raspi-config is not presented by default)
User : pi
Password : raspberry
5) sudo raspi-config (if required)
6) If you want to have a completely up to date Rsapbian
To note: This can take a while, depends on Raspi1 vs Raspi2 and your bandwidth, could take up 20 minutes or more
$ sudo apt-get update
$ sudo apt-get upgrade
7) Now we prepare the correct packages and dependancies to be installed:
$ sudo apt-get install python-pip git-core python2.7-dev
$ sudo easy_install -U distribute
$ sudo pip install RPi.GPIO xmpppy pydns
$ git clone https://github.com/mitchtech/raspi_gtalk_robot.git
$ cd raspi_gtalk_robot
Finally, you will need to configure the Raspi Bot’s Gtalk username and password. This is done by editing the fields BOT_GTALK_USER, BOT_GTALK_PASS, and BOT_ADMIN, on lines 31-33 in the raspiBot.py file. It is recommended, though not required, to give the Raspi Bot its own Gmail account.
BOT_ADMIN works such that if you set the BOT_ADMIN to your own XMPP Jabber ID, you will receive feedback on every command or instruction sent to the bot. Theoretically no one else will receive any messages back from shac4pi@gmail.com .
Philip initially also got errors after running ./raspiBot.py , when working with certain GPIO pin numbers, error : "The channel sent is invalid on a Raspberry Pi"
Reference : http://stackoverflow.com/questions/24226310/valueerror-the-channel-sent-is-invalid-on-a-raspberry-pi-controlling-gpio-pin
so eventually had to change line 37 which stated:
-GPIO.setmode(GPIO.BOARD) # or GPIO.setmode(GPIO.BCM)
and change it the otherway around such that BCM mode get's used for Raspi1 like in our case:
+GPIO.setmode(GPIO.BCM) # or GPIO.setmode(GPIO.BOARD)
Since access to the Raspberry Pi GPIO pins is restricted, the script needs to be run with sudo:
$ sudo python ./raspiBot.py
Example output :
====
$ sudo python ./raspiBot.py
Warning: unable to estabilish secure connection - TLS failed!
Bot started.
----------------------------------------------------------------------------------------------------
shac4pi@gmail.com/messaging-lcsw_hangoutsF15011CE , messaging-lcsw_hangoutsF15011CE , None , None , None
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
----------------------------------------------------------------------------------------------------
32sjo75o1fcf23gd1cg2orxm1d@public.talk.google.com/PsiAA09C71E , PsiAA09C71E , None , None , None
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
----------------------------------------------------------------------------------------------------
32sjo75o1fcf23gd1cg2orxm1d@public.talk.google.com/messaging-lcsw_hangoutsDF82C3B7 , messaging-lcsw_hangoutsDF82C3B7 , None , None , away
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
----------------------------------------------------------------------------------------------------
32sjo75o1fcf23gd1cg2orxm1d@public.talk.google.com/MessagingA6df2ab75 , MessagingA6df2ab75 , None , None , away
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.
.
.
====
8) Then make sure you jabber/xmpp message shac4pi@gmail.com from your jabber client. I actually first logged into shac4pi@gmail.com and opened the Gtalk chat client in the browser, search for myself "Philip Booysen" and messages myself, then auth shac4pi on my xmpp client, and started testing messaging forward and backwards. Then I ran the raspiBot.py
9) As of Fri Apr 24 15:44:41 SAST 2015 the raspiBot.py looked like this:
#====
$ cat raspiBot.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# PyGtalkRobot: A simple jabber/xmpp bot framework using Regular Expression Pattern as command controller
# Copyright (c) 2008 Demiao Lin <ldmiao@gmail.com>
#
# RaspiBot: A simple software robot for Raspberry Pi based on PyGtalkRobot
# Copyright (c) 2013 Michael Mitchell <michael@mitchtech.net>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# PyGtalkRobot Homepage: http://code.google.com/p/pygtalkrobot/
# RaspiBot Homepage: http://code.google.com/p/pygtalkrobot/
#
import time
import subprocess
import RPi.GPIO as GPIO
from PyGtalkRobot import GtalkRobot
BOT_GTALK_USER = 'our_shac4pi_user@gmail.com'
BOT_GTALK_PASS = 'ourpassword'
BOT_ADMIN = 'the_bot_admin@gmail.com'
debug=open('/tmp/shac4py.log', 'w+')
#GPIO.setmode(GPIO.BOARD) # or
GPIO.setmode(GPIO.BCM)
############################################################################################################################
class RaspiBot(GtalkRobot):
#Regular Expression Pattern Tips:
# I or IGNORECASE <=> (?i) case insensitive matching
# L or LOCALE <=> (?L) make \w, \W, \b, \B dependent on the current locale
# M or MULTILINE <=> (?m) matches every new line and not only start/end of the whole string
# S or DOTALL <=> (?s) '.' matches ALL chars, including newline
# U or UNICODE <=> (?u) Make \w, \W, \b, and \B dependent on the Unicode character properties database.
# X or VERBOSE <=> (?x) Ignores whitespace outside character sets
#"command_" is the command prefix, "001" is the priviledge num, "setState" is the method name.
#This method is used to change the state and status text of the bot.
def command_001_setState(self, user, message, args):
#the __doc__ of the function is the Regular Expression of this command, if matched, this command method will be called.
#The parameter "args" is a list, which will hold the matched string in parenthesis of Regular Expression.
'''(available|online|busy|dnd|away|idle|out|xa)( +(.*))?$(?i)'''
show = args[0]
status = args[1]
jid = user.getStripped()
# Verify if the user is the Administrator of this bot
if jid == BOT_ADMIN:
print jid, " ---> ",bot.getResources(jid), bot.getShow(jid), bot.getStatus(jid)
self.setState(show, status)
self.replyMessage(user, "State settings changed!")
#This method turns on the specified GPIO pin
def command_003_pinOn(self, user, message, args):
'''(pinon|pon|on|high)( +(.*))?$(?i)'''
print "GPIO pin on\n"
debug.write("GPIO pin on\n")
pin_num = args[1]
GPIO.setup(int(pin_num), GPIO.OUT)
GPIO.output(int(pin_num), True)
self.replyMessage(user, "\nPin on: "+ pin_num +" at: "+time.strftime("%Y-%m-%d %a %H:%M:%S", time.localtime()))
#This method turns off the specified GPIO pin
def command_003_pinOff(self, user, message, args):
'''(pinoff|poff|off|low)( +(.*))?$(?i)'''
print "GPIO pin off\n"
debug.write("GPIO pin off\n")
pin_num = args[1]
GPIO.setup(int(pin_num), GPIO.OUT)
GPIO.output(int(pin_num), False)
self.replyMessage(user, "\nPin off: "+ pin_num +" at: "+time.strftime("%Y-%m-%d %a %H:%M:%S", time.localtime()))
#This method writes to the specified GPIO pin
def command_003_write(self, user, message, args):
'''(write|w)( +(.*))?$(?i)'''
print "GPIO pin write\n"
debug.write("GPIO pin write\n")
arg_str = args[1]
aargs = arg_str.split()
pin_num = aargs[0]
state = aargs[1]
if int(state) == 1:
GPIO.output(int(pin_num), True)
self.replyMessage(user, "Pin on: "+ pin_num +" at: "+time.strftime("%Y-%m-%d %a %H:%M:%S", time.localtime()))
elif int(state) == 0:
GPIO.output(int(pin_num), False)
self.replyMessage(user, "Pin off: "+ pin_num +" at: "+time.strftime("%Y-%m-%d %a %H:%M:%S", time.localtime()))
#This method reads the value of the specified GPIO pin
def command_003_read(self, user, message, args):
'''(read|r)( +(.*))?$(?i)'''
print "GPIO pin read\n"
debug.write("GPIO pin read\n")
pin_num = args[1]
GPIO.setup(int(pin_num), GPIO.IN)
pin_value = GPIO.input(int(pin_num))
self.replyMessage(user, "\nPin read: "+ pin_num + " value: " + str(pin_value) + " at: "+time.strftime("%Y-%m-%d %a %H:%M:%S", time.localtime()))
#This executes the shell command argument after 'shell' or 'bash'
def command_003_shell(self, user, message, args):
'''(shell|bash)( +(.*))?$(?i)'''
cmd = args[1]
p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
output = ""
for line in p.stdout.readlines():
output += line
print line,
debug.write(line)
retval = p.wait()
self.replyMessage(user, output +" at: "+time.strftime("%Y-%m-%d %a %H:%M:%S", time.localtime()))
#This method is the default response
def command_100_default(self, user, message, args):
'''.*?(?s)(?m)'''
self.replyMessage(user, time.strftime("%Y-%m-%d %a %H:%M:%S", time.localtime()))
############################################################################################################################
if __name__ == "__main__":
bot = RaspiBot()
bot.setState('available', "Raspi Gtalk Robot")
bot.start(BOT_GTALK_USER, BOT_GTALK_PASS)
#====
9) As of Fri Apr 24 16:47:39 SAST 2015 the raspiBot.py looked like this:
#====
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# PyGtalkRobot: A simple jabber/xmpp bot framework using Regular Expression Pattern as command controller
# Copyright (c) 2008 Demiao Lin <ldmiao@gmail.com>
#
# RaspiBot: A simple software robot for Raspberry Pi based on PyGtalkRobot
# Copyright (c) 2013 Michael Mitchell <michael@mitchtech.net>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# PyGtalkRobot Homepage: http://code.google.com/p/pygtalkrobot/
# RaspiBot Homepage: http://code.google.com/p/pygtalkrobot/
#
import time
import subprocess
import RPi.GPIO as GPIO
from PyGtalkRobot import GtalkRobot
BOT_GTALK_USER = 'our_shac4pi_user@gmail.com'
BOT_GTALK_PASS = 'ourpassword'
BOT_ADMIN = 'the_bot_admin@gmail.com'
debug=open('/tmp/shac4py.log', 'w+')
#GPIO.setmode(GPIO.BOARD) # or
GPIO.setmode(GPIO.BCM)
############################################################################################################################
class RaspiBot(GtalkRobot):
#Regular Expression Pattern Tips:
# I or IGNORECASE <=> (?i) case insensitive matching
# L or LOCALE <=> (?L) make \w, \W, \b, \B dependent on the current locale
# M or MULTILINE <=> (?m) matches every new line and not only start/end of the whole string
# S or DOTALL <=> (?s) '.' matches ALL chars, including newline
# U or UNICODE <=> (?u) Make \w, \W, \b, and \B dependent on the Unicode character properties database.
# X or VERBOSE <=> (?x) Ignores whitespace outside character sets
#"command_" is the command prefix, "001" is the priviledge num, "setState" is the method name.
#This method is used to change the state and status text of the bot.
def command_001_setState(self, user, message, args):
#the __doc__ of the function is the Regular Expression of this command, if matched, this command method will be called.
#The parameter "args" is a list, which will hold the matched string in parenthesis of Regular Expression.
'''(available|online|busy|dnd|away|idle|out|xa)( +(.*))?$(?i)'''
show = args[0]
status = args[1]
jid = user.getStripped()
# Verify if the user is the Administrator of this bot
if jid == BOT_ADMIN:
print jid, " ---> ",bot.getResources(jid), bot.getShow(jid), bot.getStatus(jid)
self.setState(show, status)
self.replyMessage(user, "State settings changed!")
#This method opens a specified door
def command_003_pinOn(self, user, message, args):
'''(door_open)( +(.*))?$(?i)'''
door_num = args[1]
print "About to open a door : "+ door_num +"\n"
if int(door_num) == 1:
pin_num=23
if int(door_num) == 2:
pin_num=24
GPIO.setup(int(pin_num), GPIO.OUT)
GPIO.output(int(pin_num), True)
self.replyMessage(user, "\nOpening door: "+ door_num +" at: "+time.strftime("%Y-%m-%d %a %H:%M:%S", time.localtime()))
# sleep for 10 seconds here
time.sleep(10)
GPIO.setup(int(pin_num), GPIO.OUT)
GPIO.output(int(pin_num), False)
#This method is the default response
def command_100_default(self, user, message, args):
'''.*?(?s)(?m)'''
self.replyMessage(user, time.strftime("%Y-%m-%d %a %H:%M:%S", time.localtime()))
############################################################################################################################
if __name__ == "__main__":
bot = RaspiBot()
bot.setState('available', "Raspi Gtalk Robot")
bot.start(BOT_GTALK_USER, BOT_GTALK_PASS)
#====
Viola!
Have phun
Philip