Getting Storm Information

Having a JSON source makes things really easy. And the PyPortal library makes getting that data easy as well. The location is provided when we created the PyPortal object:

Download: file
# setup pyportal
pyportal = PyPortal(
    url="https://www.nhc.noaa.gov/CurrentStorms.json",
    json_path=["activeStorms"],
    status_neopixel=board.NEOPIXEL,
    default_bg="/map.bmp",
)

We give it the URL as well as the path location to where we'll find the data. Note that the background map BMP is also specified.

Then, to actually go fetch the data, we just call fetch():

Download: file
storm_data = pyportal.fetch()

And if everything works (network connection, etc.), then we should get back a Python list. The list will have a dictionary for each storm. Each dictionary has all the info we want, and we simply access the data via its associated key. For example, the name:

Download: file
storm["name"]

Computing Screen Coordinates

The storm location in the JSON file is provided in terms of latitude and longitude. So some work must be done to convert that into screen (x, y) coordinates. See this other guide for a more in depth discussion of what is involved:

The same general approach is used for the hurricane tracker.

Storm Icons

The storm icons are contained in a single BMP. This uses the concept of a sprite sheet, which can break down the single BMP into tiles, with each tile containing a single icon. For more information about sprite sheets, see here:

In this case, each icon is 16x16 pixels. There are 3 of them, so the total bitmap size is 16x48 pixels. A background color of yellow is used so that it can easily be found and set as the transparency color. That's what these lines of code do:

Download: file
for i, c in enumerate(icons_pal):
    if c == 0xFFFF00:
        icons_pal.make_transparent(i)

Here's a summary of what the icons mean:

Storm Graphics Group

For each storm found, the tracker will display 3 things at the storm location:

  1. An icon based on storm classification
  2. The storm name
  3. An arrow indicating storm movement direction

To make it easy to place all of these items, a new displayio.Group is created for each storm. That's what this line does:

Download: file
storm_gfx = displayio.Group(max_size=3)  # icon + label + arrow

Then each of the items are added via the append() function. And then the group itself is added to the main display ground via this line:

Download: file
storm_icons.append(storm_gfx)

This is a good example of how nesting groups within groups can be useful.

Putting It All Together

How all this comes together is pretty simple. The initial setup of the PyPortal specifies the JSON data source and background map. That, along with your secrets.py file for connecting to your network, sets up most of the hardware.

Then, the current JSON data is fetched. For each storm found within the map region, it's (x, y) location on the screen is computed and the proper icon and other graphics are shown.

And that's it. With a simple time check, this same process is then repeated at regular intervals.

This guide was first published on Aug 14, 2020. It was last updated on Aug 14, 2020.
This page (How It Works) was last updated on Oct 15, 2020.