之前的教程都有讲过如何控制Intel Galileo上的GPIO,以及如何通过Intel Galileo发送微博,至此,算是实现了物联网的一半,将本地的信息实时发布到网络,当然最为关键的是,如何实现通过网络控制Intel Galileo呢?
如图所示,Intel Galileo不断向服务器轮询查看是否有来自用户的指令,若有则检查是否为预定指令,然后开始执行,否则继续轮询,如此往返。这里对服务的唯一要求是必须有公网IP,无论是用户还是Intel Galileo均能够访问其数据。
好了,下面就开始写代码吧,需要说明的是,这里的代码在Linux系统下均能运行,只是在操作GPIO有些区别而已。虽然微博现在有些过时,但是其提供了丰富的API,可以省去自己搭建服务的麻烦,对于物联网应用的简单演示是再合适不过了,当然,有一定基础的用户可以选择微信公共号或者其他平台。
#!/usr/bin/env python
# coding=utf-8
import autohome,time,mraa,sys
from time import localtime,strftime
reload(sys)
sys.setdefaultencoding('utf-8')
x = mraa.Gpio(5)
x.dir(mraa.DIR_OUT)
如上所示,先导入若干autohome,weibo,mraa等若干相关库文件,然后设置5号引脚的模式为输出。
因为这里用到的是获取@ 当前用户的微博,并检查是否有“#Intel Galileo#”标记符,然后再检查是否有“开灯”、“关灯”、“闪灯”等命令。所以,先写一个检查包含“#Intel Galileo#”的函数,并根据其返回的True 或 False进行下一步判断:
def check(text):
if (text[0:len(info.screen_name)+1] == '@'+'%s'%info.screen_name) and (text.find('#Intel Galileo#') > 0):
return True
else:
return False
其次是检查符合上面条件的微博中是否有“开灯”、“关灯”、“闪灯”等命令的函数“check_cmd”
def check_cmd(text):
if text.find('开灯') > 0:
return '开灯'
elif text.find('关灯') > 0:
return '关灯'
elif text.find('闪灯') > 0:
return '闪灯'
elif (text.find('开灯')==-1 and text.find('关灯')== -1) and text.find('闪灯')==-1:
return False
下面开始进入主循环了,这里需要注意的是,获取含有相关命令的微博后,指令执行后,Intel Galileo在其微博下方回复相应的评论。
比如:用户发出一条微博,@plantpark #Intel Galileo#开灯;Intel Galileo接收到后,先将灯打开,然后在这条微博下评论“灯已开”+当前时间,这里为了避免在一条微博下重复评论,特对每条新的微博做对比,分别是“pre_time”和“this_time”通过获取每条微博特有的ID进行比对。为何如此写“autohome.get_mention().split(',')”,具体请参照微博API和weibo.py这里不做赘述。
while True:
this_time = autohome.get_mention().split(',')
text=this_time[4]
weibo_id= this_time[1]
if this_time[1] != pre_time[1]:
print 'you have sent a new weibo'
if check(text) == True:
if check_cmd(text) == '关灯':
x.write(0)
autohome.send_comments(weibo_id,'#Intel Galileo#灯已关 %s'%strftime("%m-%d %H:%M:%S",localtime()))
print "灯已关"
elif check_cmd(text) == '开灯':
x.write(1)
autohome.send_comments(weibo_id,'#Intel Galileo#灯已开 %s'%strftime("%m-%d %H:%M:%S",localtime()))
print "灯已开"
elif check_cmd(text) == '闪灯':
blink()
autohome.send_comments(weibo_id,'#Intel Galileo#灯在闪 %s'%strftime("%m-%d %H:%M:%S",localtime()))
print "灯在闪"
else:
autohome.send_comments(weibo_id,'#Intel Galileo#命令错误或当前命令不支持 %s'%strftime("%m-%d %H:%M:%S",localtime()))
else:
print "you haven't sent any new weibos"
time.sleep(20)
pre_time = autohome.get_mention().split(',')
不够,这里仅仅是demo,控制逻辑并不完整,大家可以根据自己的兴趣和时间进行修改和完善,比如“else if”进行多层嵌套,以适应更多条件,或者限定只接收特定用户的指令,增加一定的安全性,诸如此类,可玩性还是非常高的。
好了,把下面的代码复制到你的Intel Galileo中,直接运行看看效果吧(效果如上图所示)。对于这一系列的文章,有问题欢迎邮箱交流hi@oszine.com.
#!/usr/bin/env python
# coding=utf-8
import autohome,time,mraa,sys
from time import localtime,strftime
reload(sys)
sys.setdefaultencoding('utf-8')
x = mraa.Gpio(5)
x.dir(mraa.DIR_OUT)
info=autohome.get_user_info()
def check(text):
if (text[0:len(info.screen_name)+1] == '@'+'%s'%info.screen_name) and (text.find('#Intel Galileo#') > 0):
return True
else:
return False
def blink():
x.write(1)
time.sleep(0.2)
x.write(0)
time.sleep(0.2)
def check_cmd(text):
if text.find('开灯') > 0:
return '开灯'
elif text.find('关灯') > 0:
return '关灯'
elif text.find('闪灯') > 0:
return '闪灯'
elif (text.find('开灯')==-1 and text.find('关灯')== -1) and text.find('闪灯')==-1:
return False
timenow = strftime("%H:%M:%S",localtime())
pre_time = autohome.get_mention().split(',')
while True:
this_time = autohome.get_mention().split(',')
text=this_time[4]
weibo_id= this_time[1]
if this_time[1] != pre_time[1]:
print 'you have sent a new weibo'
if check(text) == True:
if check_cmd(text) == '关灯':
x.write(0)
autohome.send_comments(weibo_id,'#Intel Galileo#灯已关 %s'%strftime("%m-%d %H:%M:%S",localtime()))
print "灯已关"
elif check_cmd(text) == '开灯':
x.write(1)
autohome.send_comments(weibo_id,'#Intel Galileo#灯已开 %s'%strftime("%m-%d %H:%M:%S",localtime()))
print "灯已开"
elif check_cmd(text) == '闪灯':
blink()
autohome.send_comments(weibo_id,'#Intel Galileo#灯在闪 %s'%strftime("%m-%d %H:%M:%S",localtime()))
print "灯在闪"
else:
autohome.send_comments(weibo_id,'#Intel Galileo#命令错误或当前命令不支持 %s'%strftime("%m-%d %H:%M:%S",localtime()))
else:
print "you haven't sent any new weibos"
time.sleep(20)
pre_time = autohome.get_mention().split(',')