If the rainfall has been less than 1 inch in the last three days then water the garden. Wait three more days and repeat the same logic.
As soon as she told me this algorithm lights went off that this would work as great as a simple script that email’s me to water my new garden. I am also a new owner of a raspyberry pi (details later), which will work perfectly to do the monitoring and notifying.
Here is what I am currently thinking for the setup:
Python 2.7 using the following library’s
- urllib2: python’s http lib for downloading wunderground.com station summary page: (sample page for the station closest to my house)
- BeautifulSoup: HTML parser for site scrapping of the precipitation value
- SQLite3: for simple persistence storage of rain fall data
Here is what I have coded so far:
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
''' Created on Sep 12, 2012 @author: csimpson ''' import urllib2 import sqlite3 import datetime from bs4 import BeautifulSoup from bs4 import SoupStrainer MORNINGSIDE_STATION = 'KGAATLAN54' BASE_URL = 'http://www.wunderground.com/weatherstation/WXDailyHistory.asp?ID=' def fetchRainfall(station): print 'Retrieving rainfall from ' + station weatherData = urllib2.urlopen(BASE_URL+station) html = weatherData.read() onlyTables = SoupStrainer(class_="contentData") soup = BeautifulSoup(html.encode("utf8"), "lxml", parse_only=onlyTables) contentTable = soup.find(text='Precipitation:') contentTable = contentTable.find_parent('tr') inchStr = contentTable.find(class_='b') rainfall = float(inchStr.contents.string) recordRainFall(rainfall) def recordRainFall(inches): date = datetime.date.today() iso = date.isoformat() print 'Station reporting ' + str(inches) + ' inches on ' + iso sql = "INSERT INTO Rainfall(Inches, Date) VALUES('"+str(inches)+"','"+str(iso)+"');" db = sqlite3.connect('rainfall.db') db.execute(sql) db.commit() db.close() if __name__ == '__main__': fetchRainfall(MORNINGSIDE_STATION)
fetchRainfall uses the urllib to get the html page from wunderground.com. I limit my soup parsing to one contentData div on the site since it contains the actual data I care about. From there I found the first “Percipitation:” text node (note the second text node is the months total which is not what I wanted.) From there it was pretty simple the get the parent row and then from the parent dig back down to the reported inch level.
recordRainfall puts the inch level and date into a simple sql database for analysis. Note I configured the db and tables outside this script and if you want to run this example so will you.
This is just the start of the script, but I figured I should post this to give people ideas on how to get daily rain fall levels using python.
Future task include:
- Setup a github repo
- Setting up the logic for sending emails
- Making it generic for all weather stations
- Install scripts
The above script is current running as a cron job on my macbook at 11:55pm to collect the most recent rainfall levels for that day. I will eventually make it to were I can run the script on the next day, but get the rainfall levels for the previous day. This would allow me to collect the full 24 hours 0-24 data instead of data from 0 – 11:55. In Georgia 5 minutes can really be a 1/4 inch, so it is important.
Let me know what you find out about this script when you play around with it.