Weather monitoring
Alex Cox is sick of craning his neck towards the sky and wondering what to wear outside, so it’s time to make more of his weather sensors.
Alex Cox is sick of craning his neck towards the sky and wondering what to wear outside, so it’s time to make more of his weather sensors.
Weather, eh? Who’d have it? Whether it is the relentless onslaught of that burning gasball in the sky or the incessant gushing of the rain, weather never ends – and not only does that make it the perfect topic of conversation with half-acquaintances ( editors?–Ed) and family members, it makes for a great project: using Linux shenanigans and fancy sensors to feed your obsession with meteorology the right way.
A few issues ago ( LXF238), we looked at the MakerLife Weather Station kit. The fact that we have one hanging around means we’re making it (and its Pi Zero W, and included sensors) at least the initial basis of this tutorial. But you’re not missing out if you don’t have the same kit to work with. This is something you can build off your own back: various Pi-friendly stores sell sensors that hook onto GPIO pins or sit in USB ports. You could also exploit the more commercial end of the market. The Netatmo Smart Home Weather Station (a slightly painful £150 investment) can be tapped into by
weeWX, which you can find out more about in the ‘Your own weather website’ box ( belowright).
So we have sensors, but how these work to generate the data isn’t important – it’s the end result, a stream of data points, which is key. How we interpret that data and what we do with it once we’ve understood it is what turns a simple live-reading weather station into a more capable archival machine. It will then give us the chance to make predictions based not only on what’s happening now, but on what happened in the past.
Pulling Python around
The Makerlife kit (which, it seems, has been discontinued) pulls in its data using a couple of Python libraries. The same is likely true for most Raspberry Pi weather sensors. This is a good thing: Python being the LEGO-esque coding toolkit that it is, it’s likely that any sensor you pick up will integrate with any programs you happen to write, as long as you import the appropriate libraries. And this gives us a number of opportunities.
We could, on the most basic level, pipe this raw output not straight onto the screen, but into a text file, which we can process later to spot trends. This is easy enough: taking the code obtained by our weather station, we first add a line outside the main loop to open a file in append mode – something along the lines of f=
open(“weather.txt”, “a”) and then replace any instances where it would print to screen with code such as
f.write(“<weather data>”) , with the data being whatever our code had originally pulled out. Be sure to use
f.close() to cap off the file when you’re done with it. With more tweaking and a little formatting, and you could turn that output into a comma separated file, suitable for importing directly into a spreadsheet and transforming into graphs. Obviously, you need to be a little careful with your storage here, and consider whether you want to write out with such frequency given that a Raspberry Pi tends to run from a rather fragile SD card.
Using weather lists
You could, instead, append that data to a Python list to reduce the number of writes you need to make. Start by creating an empty list variable with weatherlist = [] . Add a counter variable (you’re going to use i because, well, that’s the done thing) to control both where in that list the data is going to be put, and the frequency that you’ll output that data to a file, add one to the counter each time the loop goes through, and switch out your existing f.write or print statements for weatherlist.
insert(i, <weather data>) statements which will build your list as it goes.
When your counter reaches an appropriate value, you can then use your preferred write method to output the contents of your list to a file. We’d suggest joining the list items together, dropping it as a single chunk (gracefully closing the file by using the with function) then resetting the list and counter once we’re done: w_string = ‘,’.join(weatherlist) weatherlist = [] i=0 with open(‘weather.txt’, ‘a’) as f: f.write(w_string) This is very basic, inelegant code. You can, no doubt, do better – and you should. It’s more a representation
of the possibilities than it is a doctrine in Python weather data management.
Now, we’re not casting any aspersions here, but it’s fair to say that the sensors which your weather station carry are, unless you’ve gone a little crazy with the spending, likely not dragging in every single weather metric that matters. Maybe you don’t even have any weather station gear, you poor thing. Lucky, we can get modular here too – both Yahoo ( https://pypi.org/
project/weather-api) and the excellent DarkSky ( https://github.com/ZeevG/python-forecast.io) offer up live and localised data which you can import and process off your own back.
Dark skies are forecast
Let’s look at the latter. Go to https://darksky.net/dev, hit the button, and get yourself an API key, which is required to tap into the data. It’s free unless you’re a heavy user – you get 1,000 API calls per day, and they’re charged at a nominal rate after that. Next, jump into a terminal and download the relevant wrapper through pip by using install pip install python-forecastio .
Once it’s installed, pulling that data in is relatively straightforward. At the beginning of your chunk of Python code, add in the relevant libraries with import forecastio , then add some variables just below; api_key
= “<your api key>” keeps that key (which you’ll need to pass to the main function) handy, while lat = <latitude> and lon = <longtitude> store your precise location, useful for making the most of DarkSky’s hyper-local forecasting. If you (somehow!) don’t already know your latitude and longtitude, latlong.net will connect you to an OpenStreetMap instance that’ll cough up the goods.
With the prerequisites written in, you can create a forecast object using the following line: forecast = forecastio.load_forecast(api_key, lat, lon)
This puts a whole wedge of data, and the relevant methods to extract it, into the forecast object; pull from it by, for example, adding the following (or a more graceful version of it): weatherHour=forecast.hourly() print weatherHour.summary print weatherHour.icon
There are tons more options to exploit, if you’re after a particular metric, a particular timescale, or anything else. That forecast object also includes daily() ,
minutely() and currently() methods, and you can simply use forecast.update() to refresh the object with the latest info. That raw data is stored in the data portion of the DataBlock – do with that what you will.
If you want to play with DarkSky using a different language, you can: there are wrappers for every language from Python 2 and 3 to Ruby, PHP and more to be found at https://darksky.net/dev/docs/libraries. Have fun watching the skies!