用raspberry pi 实现微博开关灯

hack总喜欢在虚拟的网络世界控制现实世界,比如《生活大爆炸》里的远程开灯,英国IT宅男用twitter喂狗。利用待业在家的闲暇时间,在raspberry pi 上实现了用微博开关灯。实现过程比代码更有趣。

发条微博开灯可以分为三步:1, 用户发微博,比如: raspberry pi 开灯,我5分钟后到家。2,raspberry pi 获取用户发的微博,并分析是否有包含开灯指令的微博 3,如果包含指令,执行开灯动作。

在PC、手机上发微博都非常方便,黑白屏手机还可以通过短信发微博,第一步完全不需要编写任何代码。外国的牛人贡献了python版本的raspberry pi GPIO库函数,只需三五行python就能实现开关灯。如果,我们获得了用户的最新的微博,只需用个简单的正则表达式搜索微博内容,就可以知道微博是否包含开灯指令。

整个项目最难的是如何获取用户的微博。不想去啃微博的API文档,用Google找了几份代码,用自己申请的 APP KEY测试,所有的代码都不可用。在CSND上发现一份wx编写的发送微博测试代码,这个代码是能用的,把源码里面的APP KEY和APP SECRET换成自己申请的,就不能发送微博了。看来是,我建立的微博应用“树莓派robot”没有通过审核,APP KEY和APP SECRET不可用。

将网上的几段代码拼凑在一起,稍加修饰就完成了获取指定账户最近20条微博的python程序,在这个程序上加上正则、GPIO操作等辅助代码就实现了发微博控制台灯的功能。我只花了三个小时写这个程序。下面是完整的源码

jk.py (控制台灯代码)

    
    
    
    
import time import RPi.GPIO as GPIO class jk: pin = 0 def __init__ (self,jk): self.pin = jk GPIO.setmode(GPIO.BCM) GPIO.setup(self.pin,GPIO.OUT) GPIO.output(self.pin,GPIO.LOW) def turn_on(self): GPIO.output(self.pin,GPIO.HIGH) def turn_off(self): GPIO.output(self.pin,GPIO.LOW) if __name__ == " __main__ " : lamp = jk( 17 ) while 1 : lamp.turn_on() time.sleep( 10 ) lamp.turn_off() time.sleep( 10 )

http_time.py (校时代码)

    
    
    
    
# -*-coding:utf8 -*- import httplib as client import time import os def get_webservertime(host): conn = client.HTTPConnection(host) conn.request( " GET " , " / " ) r = conn.getresponse() ts = r.getheader( ' date ' ) # 获取http头date部分 # 将GMT时间转换成北京时间 local_time = time.mktime(time.strptime(ts[ 5 :], " %d %b %Y %H:%M:%S GMT " )) + ( 8 * 60 * 60 ) ltime = time.gmtime(local_time) # 使用date设置时间 dat = ' date -u -s "%d-%d-%d %d:%d:%d" ' % (ltime.tm_year,ltime.tm_mon,ltime.tm_mday,ltime.tm_hour,ltime.tm_min,ltime.tm_sec) os.system(dat) if __name__ == " __main__ " get_webservertime( ' www.baidu.com ' )

demo.py (主程序)

    
    
    
    
# !/usr/bin/env python # -*- coding: utf8 -*- # generated by wxGlade 0.6.5 on Thu Jul 05 00:17:55 2012 import urllib, urllib2, re from weibo1 import APIClient, OAuthToken # 通过提供的账号和密码,返回APIClient对象实例 def GetBlogClient(uname, passw): APP_KEY = u ' 783190658 ' # app key APP_SECRET = u ' 7f63ae9eb3c1438e9f8932748ca8a341 ' # app secret # 实例化APIClient client = APIClient(app_key = APP_KEY, app_secret = APP_SECRET) # 获取OAuth request token reqToken = client.get_request_token() # 用户授权url auth_url = client.get_authorize_url(reqToken) post_data = urllib.urlencode({ " action " : " submit " , " forcelogin " : "" , " from " : "" , " oauth_callback " : " http://api.weibo.com/oauth2/default.html " , " oauth_token " : reqToken.oauth_token, " passwd " : passw, " regCallback " : "" , " ssoDoor " : "" , " userId " : uname, " vdCheckflag " : 1 , " vsnval " : "" }) mat = re.search( r ' &oauth_verifier=(.+) ' , urllib2.urlopen(urllib2.Request( " http://api.t.sina.com.cn/oauth/authorize " , post_data, headers = { ' User-Agent ' : ' Mozilla/5.0 (Windows NT 6.1) ' , ' Referer ' : auth_url } )).url ) if mat: client = APIClient( APP_KEY, APP_SECRET, OAuthToken( reqToken.oauth_token, reqToken.oauth_token_secret, mat.group( 1 ) )) # 返回APIClient return APIClient(APP_KEY, APP_SECRET, client.get_access_token()) else : raise Exception() import time from jk import jk import http_time if __name__ == " __main__ " : api = GetBlogClient( ' 你的weibo帐号 ' , ' 你的密码 ' ) # 例如,api = GetBlogClient('[email protected]','123456') # 获取uid account = api.account__verify_credentials() uid = account.id open_pattern = re.compile(u ' @树莓派 开灯 ' .encode( ' UTF-8 ' )) close_pattern = re.compile(u ' @树莓派 关灯 ' .encode( ' UTF-8 ' )) # 只相应10分钟以内的最新weibo指令,指令只被执行一次 # 校准系统时间 http_time.get_webservertime( ' www.baidu.com ' ) created_time = time.time() order_time = time.time() - 60000 # 初始化硬件 lamp = jk( 17 ) while 1 : weibos = api.statuses__user_timeline(status = uid) for weibo in weibos: # 计算weibo建立时间 created_time = time.mktime(time.strptime(weibo.created_at, " %a %b %d %H:%M:%S +0800 %Y " )) if created_time > order_time: content = weibo.text # weibo.text.encode('UTF-8')报错 match = open_pattern.search(content.encode( ' UTF-8 ' )) if match is not None: print ' 收到开灯指令weibo ' lamp.turn_on() order_time = created_time break match = close_pattern.search(content.encode( ' UTF-8 ' )) if match is not None: print ' 收到关灯指令weibo ' lamp.turn_off() order_time = created_time break else : break time.sleep( 10 )

源码在这里,需要修改 demo.py 中的api = GetBlogClient('你的weibo帐号','你的密码')

如果你的微博帐号登入时需要输入验证码,这个程序不能正常的获得授权,不能自动读取你的微博。

 

ps.附上自制的raspberry pi 继电器扩展版靓照一张,需要完整资料的朋友请留言。

image

你可能感兴趣的:(用raspberry pi 实现微博开关灯)