You are on page 1of 28

The Scratch Weather Dashboard

In this resource, you will be creating a basic weather dashboard to monitor


Weather Stations all over the world.

Fetching the interface.py file

For Scratch to be able to talk to Weather Stations, it needs a little help.


There's a complicated Python script you can run that will help Scratch
communicate with them.

1. Open a terminal by pressing the Ctrl , Alt and T keys at the same
time, or by clicking on the icon in the left-hand corner of the screen.

2. Type the following command into the terminal to get the Python file:

wgetOinterface.pyrpf.io/wsd

3. That's it: you've downloaded the file. Keep the terminal open though, as
you'll need it in a minute.

Setting up Scratch

Now we need to help Scratch talk to the file you've downloaded.

1. Open Scratch by clicking on Menu > Programming > Scratch .

2. Once Scratch opens, you need to enable remotesensors . Click on


the sensing button to reveal the sensingblocks :

3. Now find the block called slidersensorvalue and right-click on it. Click
on enableremotesensorconnections :
1 Page
Starting your Python script

1. Now that Scratch can talk to Python, you need to start the Python script
so that it can fetch lots of Weather Station data and send it to Scratch.

2. Go back to the terminal, and type the following:

python3interface.py

Getting data from a Weather Station

1. If you have your own Weather Station at your school, ask your teacher
for the Weather Station's ID. If you don't have one, then you can use the ID in
the code below.

2. The first step is simple. You can make the Scratch cat tell you the
weather for any particular Weather Station you like. First, grab a whengreen
flagclicked block:

3. Then click on Variables and then Make


avariable . Call it id :

4. Once you've created the


variable, you can set it to your
Weather Station's ID. You can find
a list of Weather Station IDs here.

5. Now if you go back to


the Sensing menu in Scratch
and find the slidersensor
value block, you should see
there's a little black arrow that
points downwards, next to the word slider . Click this menu and you can
change the sensor value to lots of different things:
2 Page
6. To start off with, you can choose air_pressure , and
then use a sayfor2secs block (selected
from Looks ) so that the cat will tell you the air
pressure at the Weather Station:

7. If nothing happens, go back to the terminal and


check the output of the interfaces.py script. It
might be displaying the message Stationdatanot
found.PleasechooseanotherID . If this is the case,
then choose another ID from the list of stations.

Playing around with the sensors

Have a play around with different sensor values to see what they do, and what
readings they produce. If you like, you could use join blocks to also get the
cat to tell you more than one sensor value:

What next?

1. In the next worksheet you will learn how to produce a graphical


dashboard, to show you the weather at your station using images and
animations.
3Page
The Scratch Weather Dashboard
In this next worksheet you will learn how to display some weather data
visually, producing a Weather Dashboard. You'll want to start a new Scratch
file and enable the remote sensors, just like you did in the first worksheet.

Choosing a forecaster

The first thing you'll want to do is to choose a weather forecaster, who will be
telling the viewers what the weather is like. Weather forecasters are often
called meteorologists.

1. Choose a new sprite by clicking on the middle button as shown below:

2. Choose any sprite you like. Here we've gone for the squaregirl image:

Your forecaster script

1. You can start off by making your weather forecaster set the ID of the
Weather Station you'll be using, by creating a new variable.

2. She'll then need to say a little bit about the


4

location of the weather forecast. Use


Page
a join block (from Operators ) within a say block to begin with, just like you
did in the first worksheet:

3. Now grab two


more join blocks. In
the right-hand side of
one, you can place the town the weather forecast is coming from. In the left-
hand side of the other, you can place the country of the weather forecast:

4. Now the two join blocks


can be placed together.
It may not be obvious in
the image, but you
should add a single
space character
between the two sensor
values :

5. With that done, you can


place all
three join blocks
together into
the say block:

6. Your forecaster is now finished. Next, you can add some graphical
elements to help users visualise the weather.

A weathervane

Next, you can make a weathervane. Weathervanes show the direction of the
wind, but yours is also going to visualise the speed of the wind.
5 Page

1. Click on the NewSprite button to choose another sprite:


2. In things you should see a Clockhand which is basically just an arrow.
Import this sprite and delete any scripts that come with it:

1. When your weather forecast begins, you'll need to set the size and
direction that the arrow points:

2. In Motionyou should see a turnclockwise__


degrees block. Add this to the bottom of the
script. Then choose
the wind_direction sensor value, and add this
block in:

3. To visualise the wind speed,


you can change the size of
the arrow. Find the change
sizeby__ block (in Looks )
and add this to your script:
6 Page
4. To finish off, find the __*__ block in Operators and use it to multiply
the wind_speed by 10 . You can choose a different number if you like, though:

5. This can then be added into the changesizeby__ block:

Adding a thermometer

1. Next, you're going to produce a working thermometer. You'll need a


graphic to represent it, and the one below should be good enough. You can
get a large version of it here.
7Page
2. Import this sprite into your Scratch program. You'll need to place
this sprite in a very particular place, so it's best to add this into
the script. You're also going to use the pen tool to draw the
mercury inside the thermometer, but because you can't draw
over the top of sprites, you need to stamp the sprite's image to
the canvas first, and then hide it. This is the only script you'll
need on the thermometer:

You'll notice the broadcast at the end. This is going to be used to


tell the pen to start filling in the mercury inside the thermometer.

Drawing the mercury

1. Now you're going to need a new and very tiny sprite. Click on
the leftmost button in the NewSprite menu:

2. All you need is a single white dot in the middle of the screen.
Draw a white dot and then click OK.

3. Now you're going to get this tiny pixel to draw a red line of
mercury inside the thermometer. When the pixel receives a
message to draw, it needs to set up its pen:

4. How the mercury is drawn will depend


on whether the temperature is higher or
lower than 0 . You write the code for
temperatures above 0 first:
8Page
5. The first thing to do is to
make the pen go all the
way to the bottom of the
thermometer, and for the
pen to be
placed down on the
canvas:

6.

Next, the pen


can move up to
the 0 degrees
mark on the
thermometer:

7. Then, depending on the temperature, the pen can move upwards on


the y axis. You might want to tweak the values a little, but 1.7 pixels per
degree seems to work fairly well:
9Page
8.
If

the
temperature is
below zero,
the pen needs
to move to the
30 degree mark:

9. Then the pen needs to again move in the y direction. This can be
achieved using a little bit of maths:

10. The pen can then be placed into the finished script:
10Page
What next?

In worksheet three you'll learn how to fetch the weather from more than one
Weather Station, giving you a global weather dashboard.
11Page
The Scratch Weather Dashboard
In this relatively short worksheet, you'll learn how to access random Weather Stations from all
around the world.

The Python script

Make sure your Python script is still running in the background. The script is constantly listening
out for a broadcast with the name newstation . Each time the script hears the new
stationbroadcast , it chooses a new and random station to collect the data from.

Getting a new station

You can start on the last sprite you created, the one that was just a single dot in the middle of the
page. All you need to do in this script is create a loop that broadcasts newstation every 10
seconds or so. (You can choose your own timing):

Removing the flags

For all your other sprites, you just need to change the greenflagclicked blocks for whenI
receivenewstation blocks:
12Page
Running your script

When you click on the green flag, your script should start working straight away. It will tell you
the area where the station is located, and then the latest temperature and wind readings.

What next?

There are lots of other sensors that you could have a go at visualising in the dashboard. Why not
have a look at humidity, or try to make a visualisation of a barometer to tell you the air pressure?
Perhaps you could show a little column of water to visualise how much rain has fallen?
13

If you'd like to have a go at some other Weather Station resources, then you can have a look
Page

at Fetching the Weather, to have a go at accessing weather data in Python.


Fetching the weather

What you will do

This resource teaches you how to access the Raspberry Pi Weather Station database using a
RESTful API, how to use the haversine formula to calculate which weather station is closest to
you, and how to fetch the latest weather data from that station.

What you will learn

By creating a script to fetch data from a weather database, you will learn:

How to access a RESTful API in Python

How to convert JSON data into dictionaries

How to pretty-print data

How to calculate distances between two points on the Earth's surface

This resource covers elements from the following strands of the Raspberry Pi Digital Making
Curriculum:

Apply abstraction and decomposition to solve more complex problems


14Page
What you will need

Hardware

There are no additional hardware requirements for this resource beyond the
Raspberry Pi and usual peripherals.
Software
To prepare for this resource, you'll need an up-to-date SD card image. See
the updating Raspbian guide.
You'll also need the following additional software installed:
Python 3 requests
For information on installing these libraries, see the software installation page.

Fetching the Weather


One thousand Weather Stations were sent out to schools all over the world at the beginning of
2016, ready to be assembled and begin collecting global weather data.
15Page
Each Weather Station comes equipped with the sensors shown in the table below:

Sensor Name Purpose


Rain gauge Measures the volume of rain falling in millimetres
Anemometer Measures the wind speed in kilometres per hour
Weathervane Measures the wind direction in degrees
Soil temperature probe Measures the soil temperature in degrees Celsius
Temperature sensor Measures the air temperature in degrees Celsius
Humidity sensor Measures the relative humidity of the air as a percentage
Pressure sensor Measures the atmospheric pressure in Pascals
Air quality sensor Measures the air quality as a relative percentage

The Weather Stations continually monitor the weather and then send their data to an Oracle
database, where it is stored and can be accessed.

In this resource you're going to learn how to find a Weather Station you're interested in, and then
get the latest weather updates from that station.

Finding a Weather Station

You can get a list of all the Weather Stations that are currently online, using a simple URL. This
is because the database that all the Weather Stations upload data to has a RESTful API. This is a
method by which you can write code that uses simple HTTP requests (just like a browser) to
fetch the data.

Copy and paste the following URL into a web browser:

https://apex.oracle.com/pls/apex/raspberrypi/weatherstation/getallstations

You should see a web page filled with data. This is a little difficult to read, though. Luckily, we
can grab this data with a little Python code and then present it in a format that's easier to read.

1. Click on Menu > Programming > Python3(IDLE) to open a new Python shell, then
click on File > NewFile .

2. The first thing you'll need is a few Python modules. One of them is not in the standard
library, but you can install it from the Requirements page.

3. fromrequestsimportget
16

4. importjson
Page
frompprintimportpprint

5. The requests module allows you to fetch web pages from the World Wide Web.
The json module allows you to easily read JSON data (which is a way of organising data into
dictionaries). The pprint module is short for pretty-print, and just makes presenting text a little
clearer.

6. The next thing to do is to save that URL you used earlier as a variable:

url=
'https://apex.oracle.com/pls/apex/raspberrypi/weatherstation/getallstation
s'

7. Using get from the requests module you can now fetch the data, and translate it into
Python dictionaries using the json module:

stations=get(url).json()['items']

8. Save and run your code. You can type stations into the Python shell to have a look at
the data.

9. It still looks pretty ugly. Try typing pprint(stations) and see what happens. You
should see a huge list of Weather Stations dictionaries. Each dictionary should look something
like this:

10. {'weather_stn_id':1648902,

11. 'weather_stn_lat':52.197834,

12. 'weather_stn_long':0.125366,

'weather_stn_name':'ACRG_ROOF'}]

13. What you're seeing is the unique ID of the station, its location in the world
using longitude and latitude (You can learn about this in worksheet2), and the name of the
Weather Station.

14. For the next part, you're going to need to pick a Weather Station to fetch the weather
from. Scroll up and down the list and pick a weather_stn_id that you'd like to have a look at.
17

Fetching the latest weather


Page
Now that you have a Weather Station to look at, you can learn how to fetch the last weather
recording from that station. This is again handled using the RESTful API of the Weather Station
database. This time, the URL you need is made up of two parts. The first tells the database that
you're requesting the latest measurements:

'https://apex.oracle.com/pls/apex/raspberrypi/weatherstation/getlatestmeas
urements/'

You need to add the ID of the Weather Station you wish to access to the end of this. For example:

'https://apex.oracle.com/pls/apex/raspberrypi/weatherstation/getlatestmeas
urements/1648902'

1. Create a new Python file again, by clicking on File > NewFile .

2. Once again, you'll need the requests and json modules, as well as pprint :

3. fromrequestsimportget

4. importjson

frompprintimportpprint

5. Now you can define a new url variable, but using the Weather Station ID you've
chosen:

url=
'https://apex.oracle.com/pls/apex/raspberrypi/weatherstation/getlatestmeas
urements/weather_stn_id_goes_here'

6. To get the latest measurements you need one line of code, but we'll add a second line to
pretty-print it straight away:

7. weather=get(url).json()['items']

pprint(weather)

8. You should see something like the following appearing in the shell:

9. >>>[{'air_pressure':1008.81,
18

10. 'air_quality':74.9,
Page
11. 'ambient_temp':23.58,

12. 'created_by':'ACRG_ROOF',

13. 'created_on':'20161116T12:00:01Z',

14. 'ground_temp':18.69,

15. 'humidity':33.41,

16. 'id':1669238,

17. 'rainfall':0,

18. 'reading_timestamp':'20161116T12:00:01Z',

19. 'updated_by':'ACRG_ROOF',

20. 'updated_on':'20161116T12:05:02.437Z',

21. 'weather_stn_id':1648902,

22. 'wind_direction':315,

23. 'wind_gust_speed':0,

'wind_speed':0}]

24. If you don't see any data, it might be because the Weather Station is offline. Just try
another Weather Station Id.

What next?

In worksheet two you'll learn all about longitude and latitude, and how to get the weather
data for the closest Weather Station to your current location.
19Page
Finding a Station near you

Longitude and latitude

It would be nice if you could pick a Weather Station that's close to you to fetch
the data from. You can do this, because the database stores the longitude and
latitude of all the Weather Stations around the world. Let's have a look at what
we mean by longitude and latitude.

1. If you wanted to pinpoint a place on a 2D object like a piece of paper,


you could use x and y coordinates. The x coordinate would place the point's
horizontal position, and the y coordinate would place the vertical position. You
can see an example of this below.

2. Things aren't so simple when you're trying to pinpoint a location on a


sphere, like the Earth. The vertical and horizontal positions wrap around the
sphere, for a start. Also, travelling 5 units of distance along the equator would
be a completely different distance to walking 5 units of distance near one of
the poles. For this reason we use longitude and latitude when locating items
on the Earth's surface.

3. You can draw two imaginary circles around the Earth. The first is called
the equator, which you're probably familiar with. The second is called the
prime meridian, which passes through both the North and South Poles and
also through Greenwich in London.
20Page
4. The centre of these two circles is at the centre of the Earth. Imagine you
were standing in the centre of the Earth; you would be able to pinpoint any
location on the surface by talking about how many degrees you needed to
turn within each of these circles. Longitude tells you how many degrees you
need to turn east or west from the prime meridian. Latitude tells you how
many degrees you need to turn north or south from the equator.

5. The easiest way to find your longitude and latitude is to use Google
Maps. You can click on any spot on the map, and your longitude and latitude
will be revealed at the bottom of the screen.
21
Page
6. The first number is your latitude and the second is your longitude. Make
a note of the values you get, as you'll need them later.

Finding the distance between two points on the Earth

The next part is a little technical. You need to be able to find the distance
between two points on the Earth, given their longitudes and latitudes. This will
allow you to find the closest Weather Station to you.

If you're not particularly interested in how this works, then rather than write the
code, you can download the file you need from here. Just make sure it's
saved as haversine.py and stored in the same directory as the rest of your
code.

As discussed earlier, we use longitude and latitude to work out the exact
position of places on the Earth. Finding distances between these points is
quite tricky, as the distance is over the surface of a sphere, and therefore not
in a straight line. To do this calculation, you need a clever bit of maths called
the haversine formula.

Without getting too technical, the haversine formula can provide the distance
between two points on a sphere using longitudes and latitudes.

1. Open up a Python shell by clicking


on Menu > Programming > Python3(IDLE) .
22

2. Now click on File > NewFile to create a new Python script. Click
Page

on File > SaveAs and call your file haversine.py .


3. To begin with, you're going to need a few functions from
the maths library. Start off your file by importing the following:

frommathimportradians,cos,sin,asin,sqrt

4. Now you can define a new function, which we'll call haversine . It's
going to take 4 arguments, which will be the longitude and latitude of the two
points whose distance we need to find.

defhaversine(lon1,lat1,lon2,lat2):

5. Most mathematical formulae require us to work in radians rather than


degrees when dealing with angles, so the first thing to do is to convert each of
the latitudes and longitudes passed into the function as arguments into
radians.

6. defhaversine(lon1,lat1,lon2,lat2):

7. #convertdegreestoradians

8. lon1=radians(lon1)

9. lat1=radians(lat1)

10. lon2=radians(lon2)

lat2=radians(lat2)

11. Now we want to find the difference between the two longitudes and
latitudes, so add this into your function:

12. dlon=lon2lon1

dlat=lat2lat1

13. Now comes the tricky bit. If you want to know more about the haversine
formula then you can have a read of the Wikipedia article linked above.
Otherwise, you can just take it at face value that the following lines of code will
calculate the distance between the two points:
23

14. a=sin(dlat/2)**2+cos(lat1)*cos(lat2)*sin(dlon/2)**2
Page
15. distance=2*asin(sqrt(a))*6371#6371istheradiusofthe
Earth

returndistance

16. Save your file once again, and then you can test it. Run your file, and
then in the shell you can type the following:

haversine(74.0059,40.7128,0.1278,51.5074)

17. You should get an answer of 5570. This is the distance from London to
New York. You can check the answer online if you like, although the values
will be slightly different as the Earth is not an exact sphere. It's good enough
for our purposes, though.

Try a few more longitudes and latitudes from Google Maps.

Getting ready

In the first worksheet, you fetched all the Weather Stations that are currently
registered. The data came in as a huge list of dictionaries. By iterating through
this list, you can pick out the longitude and latitude of the Weather Stations,
and then run it through your haversine function to find the closest one.

1. Create a new Python file ( File > NewFile ) and make sure you save
it in the same directory as your haversine.py file.

2. Start by importing the requests , json , and pprint modules that you
used in Worksheet One, but you can now also import your haversine function:

3. fromrequestsimportget

4. importjson

5. frompprintimportpprint

fromhaversineimporthaversine
24

6. In Worksheet One, you used two URLs to get the Weather Stations and
the latest weather. You can declare these variables straight away:
Page
7. stations=
'https://apex.oracle.com/pls/apex/raspberrypi/weatherstation/getallstation
s'

weather=
'https://apex.oracle.com/pls/apex/raspberrypi/weatherstation/getlatestmeas
urements/'

8. The second URL isn't complete, as you need to add the weather station
ID to the end. You're going to do that in code.

9. Now add in variables for your current longitude and latitude, that you
found using Google Maps:

10. my_lat=52.194504

my_lon=0.134708

11. To finish off this section, you can fetch the list of all stations, just like you
did in Worksheet One:

all_stations=get(stations).json()['items']

Finding the closest station

For this to work, you're going to need to run the longitude and latitude of all
the stations through the haversine function. The trick will be finding the
smallest distance to your current longitude and latitude, and saving this as a
variable.

1. Start by defining a new function, and setting a variable within it for the
smallest distance. The longest possible distance between two points on the
Earth's surface is 20036km, so this would be a good place to start the
variable:

2. deffind_closest():
25

smallest=20036
Page
3. Now you can use a for loop to iterate through all the stations. Let's
start by printing the data for each:

4. forstationinall_stations:

print(station)

5. To get the list of stations you need to run your function, so type the
following into the shell:

find_closest()

You should see a large list of dictionaries, with each dictionary looking
something like this:

{'weather_stn_name':'ACRG_ROOF','weather_stn_lat':52.197834,
'weather_stn_id':1648902,'weather_stn_long':0.125366}

The data we're interested in is


the 'weather_stn_lat' and 'weather_stn_long' . These are the values
we want to use in the haversine function.

1. Go back to your script; you can now get those values in your function.
Remove the print(station) line and then add the following:

2. station_lon=station['weather_stn_long']

station_lat=station['weather_stn_lat']

3. Now that you have all the data, it can be run through the haversine
function to find the station's distance to you:

4. distance=haversine(my_lon,my_lat,station_lon,
station_lat)

print(distance)

5. Run the code again and type find_closest() in the shell again.
26

6. That's a long list of distances. Next, you need to find the smallest one
Page

and then save that station's ID. If the distance is smaller than
the smallest variable it can be saved, and then next time around the loop it
can be checked again.

7. ifdistance<smallest:

8. smallest=distance

9. closest_station=station['weather_stn_id']

returnclosest_station

10. Your find_closest function should now look like this:

11. deffind_closest():

12. smallest=20036

13. forstationinall_stations:

14. station_lon=station['weather_stn_long']

15. station_lat=station['weather_stn_lat']

16. distance=haversine(my_lon,my_lat,station_lon,
station_lat)

17. ifdistance<smallest:

18. smallest=distance

19. closest_station=station['weather_stn_id']

returnclosest_station

Getting the weather data

Now that you can get the closest Weather Station to you, getting the data is
just as easy as it was in Worksheet One.

1. Start by calling your newly created function and saving the weather
27

station ID:
Page
closest_stn=find_closest()

2. Now this can be added to the end of the weather variable that stores
the URL. It's an integer at the moment though, so it needs to be changed to a
string:

weather=weather+str(closest_stn)

3. Finally, you can use requests to get the data and then pretty-print it:

4. my_weather=get(weather).json()['items']

pprint(my_weather)

5. Run your code and you should see the weather data for the station
nearest you, printed out in the shell.

What next?

You could have a look at some weather data from other locations in the
world. Use the web to find some longitudes and latitudes of other places, and
then fetch weather from their nearest stations.

How about importing the data from several Weather Stations into some
spreadsheet software and drawing some graphs? Or maybe you'd like to try
and use Python to draw some graphs for you?
28Page

You might also like