Note that the data source for the original guide code open-notify.org is no longer up to date. And there are some other minor issues like the number of astronaut names that can fit on the display. This code is left here for study as it goes into more detail. But be advised it'll not pull accurate information due to open-notify.org not being updated.
Astronaut Count and Names
Using CircuitPython code on the PyPortal, we'll have the display show the current number of astronauts in space according to the open-notify.org API.
The PyPortal will do the following:
- Display a custom background .bmp image
- Check for the current number, and names of people in space
- Display the current number of astronauts
- Wait for you to touch the screen and then display the names of he astronauts for 30 seconds
Install CircuitPython Code and Assets
In the embedded code element below, click on the Download: Project Zip link, and save the .zip archive file to your computer.
Then, uncompress the .zip file, it will unpack to a folder named PyPortal_Astronauts.
Copy the contents of the PyPortal_Astronauts directory to your PyPortal's CIRCUITPY drive.
This is what the final contents of the CIRCUITPY drive will look like:
# SPDX-FileCopyrightText: 2019 Limor Fried for Adafruit Industries
#
# SPDX-License-Identifier: MIT
"""
This example will access the open-notify people in space API, the number of
astronauts and their names... and display it on a screen!
if you can find something that spits out JSON data, we can display it
"""
import time
import board
from adafruit_pyportal import PyPortal
from adafruit_bitmap_font import bitmap_font
from adafruit_display_text.label import Label
# Set up where we'll be fetching data from
DATA_SOURCE = "http://api.open-notify.org/astros.json"
DATA_LOCATION = [["number"], ["people"]]
# determine the current working directory
# needed so we know where to find files
cwd = ("/"+__file__).rsplit('/', 1)[0]
# Initialize the pyportal object and let us know what data to fetch and where
# to display it
pyportal = PyPortal(url=DATA_SOURCE,
json_path=DATA_LOCATION,
status_neopixel=board.NEOPIXEL,
default_bg=cwd+"/astronauts_background.bmp",
text_font=cwd+"/fonts/Helvetica-Bold-100.bdf",
text_position=((225, 50), None),
text_color=(0xFFFFFF, None))
names_font = bitmap_font.load_font(cwd+"/fonts/Helvetica-Bold-16.bdf")
# pre-load glyphs for fast printing
names_font.load_glyphs(b'abcdefghjiklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ- ()')
names_position = (10, 135)
names_color = 0xFF00FF
while True:
try:
value = pyportal.fetch()
print("Response is", value)
except RuntimeError as e:
print("Some error occured, retrying! -", e)
stamp = time.monotonic()
while (time.monotonic() - stamp) < 5 *60: # wait 5 minutes before getting again
if pyportal.touchscreen.touch_point:
names = ""
for astro in value[1]:
names += "%s (%s)\n" % (astro['name'], astro['craft'])
names = names[:-1] # remove final '\n'
names_textarea = Label(names_font, text=names)
names_textarea.x = names_position[0]
names_textarea.y = names_position[1]
names_textarea.color = names_color
pyportal.root_group.append(names_textarea)
time.sleep(30) # wait 30 seconds to read it
pyportal.root_group.pop()
How it Works
The PyPortal Astronauts Display does the following things to keep you in the know about non-Earthbound humans:
Background
First, it displays a bitmap graphic named astronauts_background.bmp as the screen's background. This is a 320 x 240 pixel RGB 16-bit raster graphic in .bmp format.
Font
To display information on the screen, the PyPortal code will use a bitmapped font overlayed on top of the background. The font used here is are bitmap fonts made from the Helvetica typeface. You can learn more about converting type in this guide.
In order to speed up the display of text, the pyportal.preload_font() command is used to place the needed glyphs into memory.
JSON
How does the PyPortal know how many people are in space, as well as their names and locations? Is it talking to them when we're not looking?
That would be awesome, but actually it's not the case. Instead, the PyPortal is fetching a JSON file from the open-notify.org API. The address here has what we need: http://api.open-notify.org/astros.json
This file contains all sorts of information, delivered in an easy-to-parse format. If you visit that URL by copying the address and pasting it into the Load Url button of the online code "beautifier" https://codebeautify.org/jsonviewer you'll see the raw JSON file next to a nicely formatted version of it (choose "View" from the dropdown menu in the right hand box to change the display format).
Here it is in a raw-er form, but still using indentation and carriage returns to make it readable:
{
"message": "success",
"number": 6,
"people": [
{
"craft": "ISS",
"name": "Oleg Kononenko"
},
{
"craft": "ISS",
"name": "David Saint-Jacques"
},
{
"craft": "ISS",
"name": "Anne McClain"
},
{
"craft": "ISS",
"name": "Alexey Ovchinin"
},
{
"craft": "ISS",
"name": "Nick Hague"
},
{
"craft": "ISS",
"name": "Christina Koch"
}
]
}
Keys
Look at the code and you'll see two keys that we'll query, number and people. The number key has a value of 6 in this case, so we'll call that a key:value pair written this way "number" : 6
The people key doesn't have a single value, but is instead has a sub-tree with multiple other sets of key:value pairs such as:
"craft" : "ISS" and "name" : "Christina Koch"
Our CircuitPython code is able to grab and parse this data using the following variables:
DATA_SOURCE = "http://api.open-notify.org/astros.json" DATA_LOCATION = [["number"], ["people"]]
Traversing JSON
The DATA_LOCATION contains two variables that we use to traverse the JSON file. In the image here, note how there is a tree hierarchy indicated by the indentation level. The number key is at the top level of the file's hierarchy, so we can call its name directly.
The people key is also at the top level of the hierarchy, but contains a sub-tree of multiple craft and name key:value pairs.
You can see this more clearly by switching to the "Form" view of the code beautifier.
PyPortal Constructor
When we set up the pyportal constructor, we are providing it with these things:
-
urlto query -
json_pathto traverse and find the key:value pair we need -
default_bgpath and name to display the background bitmap -
text_fontpath and name to the font used for displaying the follower count value -
text_positionon the screen's x/y coordinate system text_color
Fetch
With the PyPortal set up, we can then use pyportal.fetch() to do the query and parsing of the data and then display it on screen on top of the background image.
This repeats every five minutes to stay current!
Touchscreen
You'll also notice in the code that there's a section at the bottom inside the main while True: loop that tests for the touchscreen to see if it's been pressed or not by using pyportal.touchscreen.touch_point
When the value is true, due to being pressed, it will then display the names of the astronauts using the pyportal.root_group.append() function. After thirty seconds the names are cleared using the pyportal.root_group.pop() function.
Customization
You can customize this project to make it your own and point to different website API's as the source of your JSON data, as well as adjust the graphics and text.
Text Position
Depending on the design of your background bitmap and the length of the text you're displaying, you may want to reposition the text and caption. You can do this with the text_position and caption_position options.
The PyPortal's display is 320 pixels wide and 240 pixels high. In order to refer to those positions on the screen, we use an x/y coordinate system, where x is horizontal and y is vertical.
The origin of this coordinate system is the upper left corner. This means that a pixel placed at the upper left corner would be (0,0) and the lower right corner would be (320, 240).
Text Color
Another way to customize your display is to adjust the color of the text. The line text_color=0xFFFFFF in the constructor shows how. You will need to use the hexadecimal value for any color you want to display.
You can use something like https://htmlcolorcodes.com/ to pick your color and then copy the hex value, in this example it would be 0x0ED9EE
Background Image
If you would like to create your own background, awesome! You'll want to save the file with these specifications:
- 320 x 240 pixels
- 16-bit RGB color (8-bits per channel)
- Save file as .bmp format
You can then copy the .bmp file to the root level of the CIRCUITPY drive. Make sure you refer to this new filename in the pyportal constructor line:
default_bg=cwd+"/astronaut_background.bmp"
Change that line to use the new filename name, such as:
default_bg=cwd+"/my_new_background.bmp"
Page last edited April 01, 2026
Text editor powered by tinymce.