Update 2 11/15/2015
I recently bought a wifi-controlled plug, however, it only can be controlled in LAN. The possibilities with Raspberry Pi are unlimited, I found a API written in Python which allows me to control this smart plug through Pi. I am now able to let the Pi take over the smart plug by analyzing the data from the light sensor, which, I guess, is a good news for my cat Tina. Generally we cannot reach home before 6 pm, when it is already dark. Although Feline can see in the dark, the yellow light makes her feel warm, at least this is what I think.
Update 1 11/13/2015:
A triple GPIO extension was installed on the Raspberry Pi, I can use one GPIO for the LCD display and one for the sensors. Here is a quick look of the whole system.
The joy stick on the LCD display hat is programmed in such a way that
‘left’ –> Display home condition
‘right’ –> outside weather
‘up’ –> Turn on the backlight
‘down’ –> Turn off the backlight
‘press’ –> Turn off the displayNow the weather station is also able to send updates through twitter (by Twython), please take a look at it here.
我在Raspberry Pi完成的最新项目是一个天气监测站,可以同时监测室内和室外天气状况,并且还可以记录室内光亮程度。室外天气的数据是调用Wunderground的API,天气站可以显示当前天气情况和未来一小时的天气情况,并且如果预报出将会下雨或者下雪,天气站会自动发送电子邮件告知。室内情况有两块传感器实现,天气状态和光亮分别由BME280和TSL2561传感器提供。两块传感器通过I2C接口与Raspberry Pi连接,事实证明I2C设备可以通过并联得到两个不同的地址,具体的布线不在此赘述,可以分别参考Adafruit的连接说明,然后将其并联即可。
程序基于Python 2.0,在Linux环境下使用需要super user权限。
主程序
from cls_readXML import * from cls_sendEmail import * from Adafruit_BME280 import * from fn_lumen import * from tsl2561 import TSL2561 as lightSensor import os import time #====================================================================================== myWeather = readXML() myEmail = email() zipCode = '60616' sensor = BME280(mode=BME280_OSAMPLE_8) email_receiver = ['receiver@gmail.com'] email_alertReceiver = ['receiver01@gmail.com','receiver02@gmail.com'] email_subject = 'Current Weather' email_message = '' #====================================================================================== #Variable initilization myGeo = [] myForecast = [] myTemperature = '' myHumidity = '' myWeatherCondition = '' myFeelslikeT = '' myTime = '' #====================================================================================== while(True): os.system('clear') myGeo = myWeather.getInfo(zipCode, 'display_location') myTemperature = myWeather.getInfo(zipCode, 'temp_f')[0] myHumidity = myWeather.getInfo(zipCode, 'relative_humidity')[0] myWeatherCondition = myWeather.getInfo(zipCode, 'weather')[0] myFeelslikeT = myWeather.getInfo(zipCode,'feelslike_f')[0] myTime = myWeather.getInfo(zipCode,'observation_time')[0] myForecast = myWeather.checkForecast(zipCode) degrees = sensor.read_temperature() pascals = sensor.read_pressure() hectopascals = pascals / 100 humidity = sensor.read_humidity() degrees = degrees * 1.8 + 32.0 tsl = lightSensor(debug=1) lumen = tsl.lux() lumen_reco = checkLum(lumen) forecast = 'Expect {} in the next hour.\nChance of Rain: {}%.\n'.format(myForecast[1],myForecast[3]) msg_outside = ('Current Weather in {}'.format(myGeo[0]) + '\n\n' + myTime + '\n\n' + 'Weather: {}'.format(myWeatherCondition) + '\n' + 'Temperature: {} F \t Feels like: {} F'.format(myTemperature, myFeelslikeT) + '\n' + 'Humidity: {}'.format(myHumidity) ) msg_home = 'Temperature = {0:0.3f} deg F'.format(degrees) + '\n' + 'Pressure = {0:0.2f} hPa'.format(hectopascals) + '\n' + 'Humidity = {0:0.2f} %'.format(humidity) + '\n' + 'Light: {}'.format(lumen_reco) msg = msg_outside + '\n\n' + 'Current Condition at Home\n\n' + msg_home + '\n\n' + forecast badWeather = ['snow','rain','rain showers','snow showers','thunderstorm'] for bad in badWeather: if myForecast[1].lower() == bad: myEmail.sendEmail(email_alertReceiver,'Weather Alert',forecast) print(msg) email_message = msg myEmail.sendEmail(email_receiver, email_subject, email_message) time.sleep(1200)
类库 01
#from urllib.request import urlopen import urllib2 from bs4 import BeautifulSoup key = 'Enter Your Own Key Here' class readXML(): #=================================================================== def getInfo(self, arg_zip, arg_type): zipcode = arg_zip type = arg_type info = [] url='http://api.wunderground.com/api/' + key + '/conditions/q/' + zipcode + '.xml' try: #weather_html = urlopen(url) weather_html = urllib2.urlopen(url) except HTTPError as e: return ['Error', e] else: weather_obj = BeautifulSoup(weather_html.read(), 'html.parser') for child in weather_obj.find(type).children: if child.string == '\n': pass else: info.append(child.string) return info #=================================================================== def _init_(self): pass #=================================================================== def checkUV(self, arg_uv): info = '' suggestion = '' try: uv = int(arg_uv) except: return 'UV Index is not a number!' else: if uv <= 2: info = 'low' suggestion = 'Cover up and Apply SPF 30+ sunscreen' elif uv > 2 and uv <=5: info = 'moderate' suggestion = 'Apply SPF 30+ sunscreen every 2 hours' elif uv > 5 and uv <= 7: info = 'high' suggestion = 'Reduce time in the sun between 10 a.m. and 4 p.m. \n Apply SPF 30+ sunscreen every 2 hours' elif uv > 7 and uv <= 10: info = 'very high' suggestion = 'Reduce time in the sun between 10 a.m. and 4 p.m. \n Apply SPF 30+ sunscreen every 2 hours' elif uv > 10: info = 'extreme' suggestion = 'Reduce time in the sun between 10 a.m. and 4 p.m. \n Apply SPF 30+ sunscreen every 2 hours' else: info = 'UV index out of range' suggestion = 'No suggestions' #=================================================================== def checkForecast(self, arg_zip): zipcode = arg_zip url = 'http://api.wunderground.com/api/' + key + '/hourly/q/' + zipcode +'.xml' myForecast = [] tempStorage = [] try: forecast_html = urllib2.urlopen(url) except: return 'Something is wrong.' else: forecast_obj = BeautifulSoup(forecast_html, 'html.parser') keyWord = ['hour','condition','humidity','pop'] for entry in keyWord: myForecast.append(forecast_obj.find(entry).string) for child in forecast_obj.find('temp').children: if child != '\n': tempStorage.append(child.string) myForecast.append(tempStorage[0]) tempStorage = [] return myForecast
类库 02
import smtplib class email(): #=================================================================== def _init_(self): pass #=================================================================== def sendEmail(self, arg_to, arg_sub, arg_txt): TO = arg_to Subject = arg_sub Text = arg_txt gmail_sender = 'sender@gmail.com' gmail_pswd = 'enter password here' server = smtplib.SMTP('smtp.gmail.com', 587) server.ehlo() server.starttls() server.login(gmail_sender,gmail_pswd) BODY = '\r\n'.join(['To: %s' % TO, 'From: %s' % gmail_sender, 'Subject: %s' % Subject, '', Text]) try: server.sendmail(gmail_sender, TO, BODY) return 'Sent successfully' except: return 'error sending email' server.quit()
from twython import Twython def send_tweet(arg_msg): consumer_key='YOUR_OWN_KEY' consumer_secret = 'YOUR_OWN_KEY' access_key = 'YOUR_OWN_KEY' access_secret = 'YOUR_OWN_KEY' verdict = 0 api = Twython(consumer_key, consumer_secret, access_key, access_secret) if len(arg_msg) <= 140: try: api.update_status(status=arg_msg) except: verdict = 2 else: verdict = 1 else: verdict = 0 return verdict
Smart Plug
import spx def SmartPlug(arg_lumen, arg_currentHour): Night = range(16,23) dark = 100 try: plug = spx.Smartplug('SMART_PLUG_IP') if arg_lumen < dark and arg_currentHour in Night: p.on() else: p.off() return 'Protocal has been successfully applied to the Smart plug' except: return 'Protocal failed to be in effect!'
同时,为了使两块传感器工作,还需要添加Adafruit I2C 的驱动器,BME280驱动和TSL2561驱动。