How It Works

The CircuitPython code is doing a few neat tricks to display the guide count data.

Background

First, it displays a bitmap graphic as the screen's background. This is a 320 x 240 pixel RGB 16-bit raster graphic in .bmp format.

Font

Then, it displays the words "total tutorials:" as a caption, created with bitmapped fonts to overlay on top of the background. The fonts used here is are bitmap fonts made from the Collegiate typeface. You can learn more about converting type in this guide.

Next, the PyPortal will display the current number of guides on learn.adafruit.com

JSON

If you visit the URL we extracted from Dashblock earlier (looks like https://api.dashblock.io/model/v1?api_key=yourLongKeyHere) and copy the address and paste 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:

{
  "entities": [
    {
      "guide count": "1972 tutorials total and counting"
    }
  ]
}

Keys

If we look through the JSON page, we'll see a key called guide count that has a value of 1972 tutorials and counting. The raw JSON for this key : value pair looks like this: "guide count": 1972 tutorials and counting

Our CircuitPython code is able to grab and parse this data using the variable:

GUIDE_COUNT = ['entities', 0, 'guide count']

Traversing JSON

GUIDE_COUNT contains a value that we use to traverse the JSON file. In the image above, note how there is a tree hierarchy indicated by the indentation level. The guide count key is one set of brackets indented from the 2nd level of the file's hierarchy, so we can call it the child of the 2nd index of the array, which is 0. The top level of the file's hierarchy is called "entities", which is the first level we reference. You can see this more clearly by switching to the "Form" view of the code beautifier as seen below:

Our GUIDE_COUNT is therefore ['entities', 0, 'guide count']

PyPortal Constructor

When we set up the pyportal constructor, we are providing it with these things:

  • url to query
  • json_path to traverse and find the key:value pair we need
  • default_bg path and name to display the background bitmap
  • text_font path and name to the font used for displaying the follower count value
  • text_position on the screen's x/y coordinate system
  • text_color
  • text_maxlen max text length, only want first 4 chars for number of guides
  • caption_text to display statically
  • caption_font
  • caption_position
  • caption_color

Text Max Length

You may notice the data we get from guide count is 1972 tutorials and counting however we only want the 1972 part. How do we choose only this part? Using the text_maxlen parameter in the pyportal constructor we can choose to select and display only the first 4 characters of that text by setting text_maxlen = 4.

Fetch

With the pyportal set up, we can then use pyportal.fetch() to do the query and parsing of the learn data and then display it on screen along with the caption text on top of the background image.

Ba-Ding!

Additionally, we use the last_value variable's state to compare against the latest value. If they differ, we play the coin.wav file for a satisfying ding over the PyPortal's built in speaker!

To make your own .wav files, check out this guide.

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).

So, if you wanted to move the subscriber count text to the right and up closer to the top, your code may look like this for that part of the pyportal constructor: text_position=(250, 10)

Text Color

Another way to customize your stats trophy is to adjust the color of the text. The line text_color=0xFFFFFF in the constructor shows how. You will need to use the hexidecimal 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
  • 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+"/twitter_background.bmp"

Change that line to use the new filename name, such as:

default_bg=cwd+"/my_new_background.bmp"

Going further

You can use the following code example as a template for future API projects.

The data from most websites is now at your fingertips! This could include:

  • Weather
  • News
  • Social media followers
  • so much more!
import time
import board
from adafruit_pyportal import PyPortal

# Get wifi details and more from a secrets.py file
try:
    from secrets import secrets
except ImportError:
    print("WiFi settings are kept in settings.py, please add them there!")
    raise

# Set up where we'll be fetching data from
DATA_SOURCE = "URL.OF.JSON.DATA"
JSON_DATA = ['Outside first element', 0, 'inside first element']
CAPTION = 'caption'

# 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 = (JSON_DATA),
                    status_neopixel=board.NEOPIXEL,
                    default_bg=cwd+"/<pathToBackgroundImage>",
                    text_font=cwd+"/<pathToFont>",
                    text_position=((40, 100)), # definition location
                    text_color=(0x8080FF),
                    text_wrap=(20), #how many chars you want until it wraps
                    text_maxlen=(4), # max text size for word, part of speech and def
                    caption_text=CAPTION,
                    caption_font=cwd+"/fonts/<pathToFont>",
                    caption_position=(40, 60),
                    caption_color=0xFFFFFF)

while True:
    try:
        value = pyportal.fetch()
        print("Response is", value)
    except RuntimeError as e:
        print("Some error occured, retrying! -", e)

    time.sleep(600) #update every 10 mins

This guide was first published on Sep 09, 2019. It was last updated on Sep 09, 2019.

This page (What's Going On?) was last updated on Aug 29, 2019.

Text editor powered by tinymce.