Magtag Covid Tracking Project Iot Display: Created by Lady Ada

Download as pdf or txt
Download as pdf or txt
You are on page 1of 30

MagTag Covid Tracking Project IoT Display

Created by lady ada

Last updated on 2021-05-19 05:20:39 PM EDT


Guide Contents

Guide Contents 2
Overview 3
Parts Required 3
Also needed: 4
Install CircuitPython 5
Set Up CircuitPython 5
Option 1 - Load with UF2 Bootloader 6
Try Launching UF2 Bootloader 6
Option 2 - Use esptool to load BIN file 7
Option 3 - Use Chrome Browser To Upload BIN file 8
CircuitPython Internet Libraries 9
Adafruit CircuitPython Library Bundle 9
CircuitPython Internet Test 10
Secrets File 10
Connect to WiFi 11
Getting The Date & Time 16
Step 1) Make an Adafruit account 16
Step 2) Sign into Adafruit IO 16
Step 3) Get your Adafruit IO Key 16
Step 4) Upload Test Python Code 17
MagTag-Specific CircuitPython Libraries 20
Get Latest Adafruit CircuitPython Bundle 20
Secrets 20
Project Code 22
Download and Install Code + Font 22
Code Walkthrough 24
Daily Update Time 25
Text Transforms with lambdas 25
Adding a QR Code 26
Connect and Update 26
Custom Plastic Cutout 29

© Adafruit Industries https://learn.adafruit.com/magtag-covid-tracking-project-iot-display Page 2 of 30


Overview

The Covid Tracking Project (https://covidtracking.com (https://adafru.it/Pdd)) tracks all US state data and
collates it into one report. This project for MagTag wakes up once a day at 8pm, about a half hour after the
data is posted daily, and displays the latest data report.

In between check-ins the MagTag goes into a deep sleep mode so it will run for many weeks on a charge

Parts Required
You'll want a MagTag + battery, and magnetic feet to attach it to your fridge or other metallic surface

Adafruit MagTag Starter Kit - 2.9" Grayscale E-Ink WiFi Display


The Adafruit MagTag combines the new ESP32-S2 wireless module and a 2.9" grayscale E-Ink display to make a low-power IoT display
that can show data on its screen...
Out of Stock
Out of
Stock

You can also get the parts separately

Adafruit MagTag - 2.9" Grayscale E-Ink WiFi Display


The Adafruit MagTag combines the new ESP32-S2 wireless module and a 2.9" grayscale E-Ink display to make a low-power IoT display
that can show data on its screen even when power...
Out of Stock

© Adafruit Industries https://learn.adafruit.com/magtag-covid-tracking-project-iot-display Page 3 of 30


Out of
Stock

Lithium Ion Polymer Battery with Short Cable - 3.7V 420mAh


Lithium ion polymer (also known as 'lipo' or 'lipoly') batteries are thin, light and powerful. The output ranges from 4.2V when completely
charged to 3.7V. This battery...
$6.95
In Stock
Add to Cart

Mini Magnet Feet for RGB LED Matrices (Pack of 4)


Got a glorious RGB Matrix project you want to mount and display in your workspace or home? If you have one of the matrix panels listed
below, you'll need a pack of these...
Out of Stock
Out of
Stock

Also needed:

WiFi network (802.11 b/g/n)


A desktop or laptop computer is required for initial setup: any text editor will suffice
An Adafruit IO (https://adafru.it/BRB) account. If you’ve previously purchased from Adafruit and
created an account, this is automagic (and free)!

© Adafruit Industries https://learn.adafruit.com/magtag-covid-tracking-project-iot-display Page 4 of 30


Install CircuitPython
CircuitPython (https://adafru.it/tB7) is a derivative of MicroPython (https://adafru.it/BeZ) designed to simplify
experimentation and education on low-cost microcontrollers. It makes it easier than ever to get
prototyping by requiring no upfront desktop software downloads. Simply copy and edit files on the
CIRCUITPY drive to iterate.

Set Up CircuitPython
Follow the steps to get CircuitPython installed on your MagTag.

https://adafru.it/OBd
https://adafru.it/OBd

Click the link above and download the latest .BIN and
.UF2 file

(depending on how you program the ESP32S2 board you


may need one or the other, might as well get both)

Download and save it to your desktop (or wherever is


handy).

© Adafruit Industries https://learn.adafruit.com/magtag-covid-tracking-project-iot-display Page 5 of 30


Plug your MagTag into your computer using a known-
good USB cable.

A lot of people end up using charge-only USB cables and


it is very frustrating! So make sure you have a USB cable
you know is good for data sync.

Option 1 - Load with UF2 Bootloader


This is by far the easiest way to load CircuitPython. However it requires your board has the UF2
bootloader installed. Some early boards do not (we hadn't written UF2 yet!) - in which case you can load
using the built in ROM bootloader.

Still, try this first!

Try Launching UF2 Bootloader


Loading CircuitPython by drag-n-drop UF2 bootloader is
the easier way and we recommend it. If you have a
MagTag where the front of the board is black, your
MagTag came with UF2 already on it.

Launch UF2 by double-clicking the Reset button (the one


next to the USB C port). You may have to try a few times
to get the timing right.

© Adafruit Industries https://learn.adafruit.com/magtag-covid-tracking-project-iot-display Page 6 of 30


If the UF2 bootloader is installed, you will see a new disk
drive appear called MAGTAGBOOT

Copy the UF2 file you downloaded at the first step of this
tutorial onto the MAGTAGBOOT drive

If you're using Windows and you get an error at the end of the file copy that says Error from the file copy,
Error 0x800701B1: A device which does not exist was specified. You can ignore this error, the bootloader
sometimes disconnects without telling Windows, the install completed just fine and you can continue. If its
really annoying, you can also upgrade the bootloader (the latest version of the UF2 bootloader fixes this
warning) (https://adafru.it/Pfk)

Your board should auto-reset into CircuitPython, or you


may need to press reset. A CIRCUITPY drive will appear.
You're done! Go to the next pages.

Option 2 - Use esptool to load BIN file

© Adafruit Industries https://learn.adafruit.com/magtag-covid-tracking-project-iot-display Page 7 of 30


If you have an original MagTag with while soldermask on the front, we didn't have UF2 written for the
ESP32S2 yet so it will not come with the UF2 bootloader.

You can upload with esptool to the ROM (hardware) bootloader instead!

Follow the initial steps found in the Run esptool and check
connection section of the ROM Bootloader
page (https://adafru.it/OBc) to verify your environment is
set up, your board is successfully connected, and which
port it's using.

In the final command to write a binary file to the board,


replace the port with your port, and replace
"firmware.bin" with the the file you downloaded above.

The output should look something like the output in the


image.

Press reset to exit the bootloader.

Your CIRCUITPY drive should appear!

You're all set! Go to the next pages.

Option 3 - Use Chrome Browser To Upload BIN file


If for some reason you cannot get esptool to run, you can always try using the Chrome-browser version of
esptool we have written. This is handy if you don't have Python on your computer, or something is really
weird with your setup that makes esptool not run (which happens sometimes and isn't worth debugging!)
You can follow along on the Web Serial ESPTool (https://adafru.it/Pdq) page and either load the UF2
bootloader and then come back to Option 1 on this page, or you can download the CircuitPython BIN file
directly using the tool in the same manner as the bootloader.

© Adafruit Industries https://learn.adafruit.com/magtag-covid-tracking-project-iot-display Page 8 of 30


CircuitPython Internet Libraries
To use the internet-connectivity built into your ESP32-S2 with CircuitPython, you must first install a number
of libraries. This page covers that process.

Adafruit CircuitPython Library Bundle


Download the Adafruit CircuitPython Bundle. You can find the latest release here:

https://adafru.it/ENC

https://adafru.it/ENC

Download the adafruit-circuitpython-bundle-version-mpy-*.zip bundle zip file, and unzip a folder of the
same name. Inside you'll find a lib folder. The entire collection of libraries is too large to fit on
the CIRCUITPY drive. Instead, add each library as you need it, this will reduce the space usage but you'll
need to put in a little more effort.

At a minimum we recommend the following libraries, in fact we more than recommend. They're basically
required. So grab them and install them into CIRCUITPY/lib now!

adafruit_requests.mpy - A requests-like library for HTTP commands.


neopixel.mpy - Helper library to use NeoPixel LEDs, often built into the boards so they're great for
quick feedback

Once you have added those files, please continue to the next page to set up and test Internet connectivity

© Adafruit Industries https://learn.adafruit.com/magtag-covid-tracking-project-iot-display Page 9 of 30


CircuitPython Internet Test
Once you have CircuitPython installed and the minimum libraries installed we can get your board
connected to the Internet.

To get connected, you will need to start by creating a secrets.py file.

Secrets File
We expect people to share tons of projects as they build CircuitPython WiFi widgets. What we want to
avoid is people accidentally sharing their passwords or secret tokens and API keys. So, we designed all
our examples to use a secrets.py file, that is in your CIRCUITPY drive, to hold secret/private/custom data.
That way you can share your main project without worrying about accidentally sharing private stuff.

Your secrets.py file should look like this:

# This file is where you keep secret settings, passwords, and tokens!
# If you put them in the code you risk committing that info or sharing it

secrets = {
'ssid' : 'home_wifi_network',
'password' : 'wifi_password',
'aio_username' : 'my_adafruit_io_username',
'aio_key' : 'my_adafruit_io_key',
'timezone' : "America/New_York", # http://worldtimeapi.org/timezones
}

Copy and paste that text/code into a file called secrets.py and save it to your CIRCUITPY folder like so:

Inside is a python dictionary named secrets with a line for each entry. Each entry has an entry name

© Adafruit Industries https://learn.adafruit.com/magtag-covid-tracking-project-iot-display Page 10 of 30


(say 'ssid' ) and then a colon to separate it from the entry key 'home ssid' and finally a comma ,

At a minimum you'll need to adjust the ssid and password for your local WiFi setup so do that now!

As you make projects you may need more tokens and keys, just add them one line at a time. See for
example other tokens such as one for accessing github or the hackaday API. Other non-secret data like
your timezone can also go here, just cause its called secrets doesn't mean you can't have general
customization data in there!

For the correct time zone string, look at http://worldtimeapi.org/timezones (https://adafru.it/EcP) and
remember that if your city is not listed, look for a city in the same time zone, for example Boston, New
York, Philadelphia, Washington DC, and Miami are all on the same time as New York.

Of course, don't share your secrets.py - keep that out of GitHub, Discord or other project-sharing sites.

Don't share your secrets.py file, it has your passwords and API keys in it!

Connect to WiFi
OK now you have your secrets setup - you can connect to the Internet using the Requests module.

First make sure you are running the latest version of Adafruit CircuitPython (https://adafru.it/Amd) for your
board.

Next you'll need to install the necessary libraries to use the hardware--carefully follow the steps to find and
install these libraries from Adafruit's CircuitPython library bundle (https://adafru.it/zdx). Our introduction
guide has a great page on how to install the library bundle (https://adafru.it/ABU).

adafruit_requests
neopixel

Before continuing make sure your board's CIRCUITPY/lib folder or root filesystem has the above files
copied over.

Once that's done, load up the following example using Mu or your favorite editor:

© Adafruit Industries https://learn.adafruit.com/magtag-covid-tracking-project-iot-display Page 11 of 30


import ipaddress
import ssl
import wifi
import socketpool
import adafruit_requests

# URLs to fetch from


TEXT_URL = "http://wifitest.adafruit.com/testwifi/index.html"
JSON_QUOTES_URL = "https://www.adafruit.com/api/quotes.php"
JSON_STARS_URL = "https://api.github.com/repos/adafruit/circuitpython"

# Get wifi details and more from a secrets.py file


try:
from secrets import secrets
except ImportError:
print("WiFi secrets are kept in secrets.py, please add them there!")
raise

print("ESP32-S2 WebClient Test")

print("My MAC addr:", [hex(i) for i in wifi.radio.mac_address])

print("Available WiFi networks:")


for network in wifi.radio.start_scanning_networks():
print("\t%s\t\tRSSI: %d\tChannel: %d" % (str(network.ssid, "utf-8"),
network.rssi, network.channel))
wifi.radio.stop_scanning_networks()

print("Connecting to %s"%secrets["ssid"])
wifi.radio.connect(secrets["ssid"], secrets["password"])
print("Connected to %s!"%secrets["ssid"])
print("My IP address is", wifi.radio.ipv4_address)

ipv4 = ipaddress.ip_address("8.8.4.4")
print("Ping google.com: %f ms" % (wifi.radio.ping(ipv4)*1000))

pool = socketpool.SocketPool(wifi.radio)
requests = adafruit_requests.Session(pool, ssl.create_default_context())

print("Fetching text from", TEXT_URL)


response = requests.get(TEXT_URL)
print("-" * 40)
print(response.text)
print("-" * 40)

print("Fetching json from", JSON_QUOTES_URL)


response = requests.get(JSON_QUOTES_URL)
print("-" * 40)
print(response.json())
print("-" * 40)

print()

print("Fetching and parsing json from", JSON_STARS_URL)


response = requests.get(JSON_STARS_URL)
print("-" * 40)
print("CircuitPython GitHub Stars", response.json()["stargazers_count"])

© Adafruit Industries https://learn.adafruit.com/magtag-covid-tracking-project-iot-display Page 12 of 30


print("CircuitPython GitHub Stars", response.json()["stargazers_count"])
print("-" * 40)

print("done")

And save it to your board. Make sure the file is named code.py.

Open up your REPL, you should see something like the following:

In order, the example code...

Checks the ESP32-S2's MAC address.

print("My MAC addr:", [hex(i) for i in wifi.radio.mac_address])

Performs a scan of all access points and prints out the access point's name (SSID), signal strength (RSSI),
and channel.

© Adafruit Industries https://learn.adafruit.com/magtag-covid-tracking-project-iot-display Page 13 of 30


print("Avaliable WiFi networks:")
for network in wifi.radio.start_scanning_networks():
print("\t%s\t\tRSSI: %d\tChannel: %d" % (str(network.ssid, "utf-8"),
network.rssi, network.channel))
wifi.radio.stop_scanning_networks()

Connects to the access point you defined in the secrets.py file, prints out its local IP address, and attempts
to ping google.com to check its network connectivity.

print("Connecting to %s"%secrets["ssid"])
wifi.radio.connect(secrets["ssid"], secrets["password"])
print(print("Connected to %s!"%secrets["ssid"]))
print("My IP address is", wifi.radio.ipv4_address)

ipv4 = ipaddress.ip_address("8.8.4.4")
print("Ping google.com: %f ms" % wifi.radio.ping(ipv4))

The code creates a socketpool using the wifi radio's available sockets. This is performed so we don't need
to re-use sockets. Then, it initializes a a new instance of the requests (https://adafru.it/E9o) interface -
which makes getting data from the internet really really easy.

pool = socketpool.SocketPool(wifi.radio)
requests = adafruit_requests.Session(pool, ssl.create_default_context())

To read in plain-text from a web URL, call requests.get - you may pass in either a http, or a http s url for SSL
connectivity.

print("Fetching text from", TEXT_URL)


response = requests.get(TEXT_URL)
print("-" * 40)
print(response.text)
print("-" * 40)

Requests can also display a JSON-formatted response from a web URL using a call to requests.get .

print("Fetching json from", JSON_QUOTES_URL)


response = requests.get(JSON_QUOTES_URL)
print("-" * 40)
print(response.json())
print("-" * 40)

Finally, you can fetch and parse a JSON URL using requests.get . This code snippet obtains the
stargazers_count field from a call to the GitHub API.

© Adafruit Industries https://learn.adafruit.com/magtag-covid-tracking-project-iot-display Page 14 of 30


print("Fetching and parsing json from", JSON_STARS_URL)
response = requests.get(JSON_STARS_URL)
print("-" * 40)
print("CircuitPython GitHub Stars", response.json()["stargazers_count"])
print("-" * 40)

OK you now have your ESP32-S2 board set up with a proper secrets.py file and can connect over the
Internet. If not, check that your secrets.py file has the right ssid and password and retrace your steps until
you get the Internet connectivity working!

© Adafruit Industries https://learn.adafruit.com/magtag-covid-tracking-project-iot-display Page 15 of 30


Getting The Date & Time
A very common need for projects is to know the current date and time. Especially when you want to deep
sleep until an event, or you want to change your display based on what day, time, date, etc. it is

Determining the correct local time is really really hard. There are various time zones, Daylight Savings
dates, leap seconds, etc. Trying to get NTP time and then back-calculating what the local time is, is
extraordinarily hard on a microcontroller just isn't worth the effort and it will get out of sync as laws change
anyways.

For that reason, we have the free adafruit.io time service. Free for anyone, with a free adafruit.io account.
You do need an account because we have to keep accidentally mis-programmed-board from
overwhelming adafruit.io and lock them out temporarily. Again, it's free!

There are other services like WorldTimeAPI, but we don't use those for our guides because they
are nice people and we don't want to accidentally overload their site. Also, there's a chance it
may eventually go down or also require an account.

Step 1) Make an Adafruit account


It's free! Visit https://accounts.adafruit.com/ (https://adafru.it/dyy) to register and make an account if you do
not already have one

Step 2) Sign into Adafruit IO


Head over to io.adafruit.com (https://adafru.it/fsU) and click Sign In to log into IO using your Adafruit
account. It's free and fast to join.

Step 3) Get your Adafruit IO Key


Click on My Key in the top bar

You will get a popup with your Username and Key (In this screenshot, we've covered it with red blocks)

© Adafruit Industries https://learn.adafruit.com/magtag-covid-tracking-project-iot-display Page 16 of 30


Go to your secrets.py file on your CIRCUITPY drive and add three lines for aio_username , aio_key and
timezone so you get something like the following:

# This file is where you keep secret settings, passwords, and tokens!
# If you put them in the code you risk committing that info or sharing it

secrets = {
'ssid' : 'home_wifi_network',
'password' : 'wifi_password',
'aio_username' : 'my_adafruit_io_username',
'aio_key' : 'my_adafruit_io_key',
'timezone' : "America/New_York", # http://worldtimeapi.org/timezones
}

The timezone is optional, if you don't have that entry, adafruit.io will guess your timezone based on
geographic IP address lookup. You can visit http://worldtimeapi.org/timezones (https://adafru.it/EcP) to see
all the time zones available (even though we do not use worldtimeapi for time-keeping we do use the
same time zone table)

Step 4) Upload Test Python Code


This code is like the Internet Test code from before, but this time it will connect to adafruit.io and get the
local time

© Adafruit Industries https://learn.adafruit.com/magtag-covid-tracking-project-iot-display Page 17 of 30


import ipaddress
import ssl
import wifi
import socketpool
import adafruit_requests
import secrets

TEXT_URL = "http://wifitest.adafruit.com/testwifi/index.html"
JSON_QUOTES_URL = "https://www.adafruit.com/api/quotes.php"
JSON_STARS_URL = "https://api.github.com/repos/adafruit/circuitpython"

# Get wifi details and more from a secrets.py file


try:
from secrets import secrets
except ImportError:
print("WiFi secrets are kept in secrets.py, please add them there!")
raise

# Get our username, key and desired timezone


aio_username = secrets["aio_username"]
aio_key = secrets["aio_key"]
location = secrets.get("timezone", None)
TIME_URL = "https://io.adafruit.com/api/v2/%s/integrations/time/strftime?x-aio-key=%s" %
(aio_username, aio_key)
TIME_URL += "&fmt=%25Y-%25m-%25d+%25H%3A%25M%3A%25S.%25L+%25j+%25u+%25z+%25Z"

print("ESP32-S2 Adafruit IO Time test")

print("My MAC addr:", [hex(i) for i in wifi.radio.mac_address])

print("Available WiFi networks:")


for network in wifi.radio.start_scanning_networks():
print("\t%s\t\tRSSI: %d\tChannel: %d" % (str(network.ssid, "utf-8"),
network.rssi, network.channel))
wifi.radio.stop_scanning_networks()

print("Connecting to %s"%secrets["ssid"])
wifi.radio.connect(secrets["ssid"], secrets["password"])
print("Connected to %s!"%secrets["ssid"])
print("My IP address is", wifi.radio.ipv4_address)

ipv4 = ipaddress.ip_address("8.8.4.4")
print("Ping google.com: %f ms" % wifi.radio.ping(ipv4))

pool = socketpool.SocketPool(wifi.radio)
requests = adafruit_requests.Session(pool, ssl.create_default_context())

print("Fetching text from", TIME_URL)


response = requests.get(TIME_URL)
print("-" * 40)
print(response.text)
print("-" * 40)

After running this, you will see something like the below text. We have blocked out the part with the secret

© Adafruit Industries https://learn.adafruit.com/magtag-covid-tracking-project-iot-display Page 18 of 30


username and key data!

Note at the end you will get the date, time, and your timezone! If so, you have correctly configured your
secrets.py and can continue to the next steps!

© Adafruit Industries https://learn.adafruit.com/magtag-covid-tracking-project-iot-display Page 19 of 30


MagTag-Specific CircuitPython Libraries
To use all the amazing features of your MagTag with CircuitPython, you must first install a number of
libraries. This page covers that process.

Get Latest Adafruit CircuitPython Bundle


Download the Adafruit CircuitPython Library Bundle. You can find the latest release here:

https://adafru.it/ENC
https://adafru.it/ENC

Download the adafruit-circuitpython-bundle-version-mpy-*.zip bundle zip file, and unzip a folder of the
same name. Inside you'll find a lib folder. The entire collection of libraries is too large to fit on the
CIRCUITPY drive. Therefore, you'll need to copy the necessary libraries to your board individually.

At a minimum, the following libraries are required. Copy the following folders or .mpy files to the lib folder
on your CIRCUITPY drive. If the library is a folder, copy the entire folder to the lib folder on your board.

Library folders (copy the whole folder over to lib):

adafruit_magtag - This is a helper library designed for using all of the features of the MagTag,
including networking, buttons, NeoPixels, etc.
adafruit_portalbase - This library is the base library that adafruit_magtag is built on top of.
adafruit_bitmap_font - There is fancy font support, and it's easy to make new fonts. This library reads
and parses font files.
adafruit_display_text - This library displays text on the screen.
adafruit_io - This library helps connect the MagTag to our free data logging and viewing service

Library files:

adafruit_requests.mpy - This library allows us to perform HTTP requests and get responses back
from servers. GET/POST/PUT/PATCH - they're all in here!
adafruit_fakerequests.mpy - This library allows you to create fake HTTP requests by using local files.
adafruit_miniqr.mpy - QR creation library lets us add easy-to-scan 2D barcodes to the E-Ink display
neopixel.mpy - This library is used to control the onboard NeoPixels.
simpleio.mpy - This library is used for tone generation.

Secrets
Even if you aren't planning to go online with your MagTag, you'll need to have a secrets.py file in the root

© Adafruit Industries https://learn.adafruit.com/magtag-covid-tracking-project-iot-display Page 20 of 30


directory (top level) of your CIRCUITPY drive. If you do not intend to connect to wireless, it does not need
to have valid data in it. Here's more info on the secrets.py file (https://adafru.it/P3b).

© Adafruit Industries https://learn.adafruit.com/magtag-covid-tracking-project-iot-display Page 21 of 30


Project Code
Download and Install Code + Font
Make sure you've installed CircuitPython and all the required libraries, as well as set up adafruit.io API
access to be able to get the local time on the previous pages.

Once ready, click the Download: Project Zip File link below in the code window to get a zip file with all the
files needed for the project. Copy code.py from the zip file and place on the CIRCUITPY drive along with
the fonts/ directory that contains the arial-bold-12.pcf font

# SPDX-FileCopyrightText: 2020 ladyada, written for Adafruit Industries


#
# SPDX-License-Identifier: Unlicense
import time
import alarm
import supervisor
import alarm
from adafruit_magtag.magtag import MagTag

# Change this to the hour you want to check the data at, for us its 8pm
# local time (eastern), which is 20:00 hrs
DAILY_UPDATE_HOUR = 20

# Set up where we'll be fetching data from


DATA_SOURCE = "https://api.covidtracking.com/v1/us/current.json"
DATE_LOCATION = [0, 'dateChecked']
NEWPOS_LOCATION = [0, 'positiveIncrease']
CURRHOSP_LOCATION = [0, 'hospitalizedCurrently']
NEWHOSP_LOCATION = [0, 'hospitalizedIncrease']
ALLDEATH_LOCATION = [0, 'death']
NEWDEATH_LOCATION = [0, 'deathIncrease']

magtag = MagTag(
url=DATA_SOURCE,
json_path=(DATE_LOCATION, NEWPOS_LOCATION,
CURRHOSP_LOCATION, NEWHOSP_LOCATION,
ALLDEATH_LOCATION, NEWDEATH_LOCATION),
)

# Date stamp of info


magtag.add_text(
text_font="/fonts/Arial-Bold-12.pcf",
text_position=(10, 15),
text_transform=lambda x: "Date: {}".format(x[0:10]),
)
# Positive increase
magtag.add_text(
text_font="/fonts/Arial-Bold-12.pcf",
text_position=(10, 35),
text_transform=lambda x: "New positive: {:,}".format(x),

© Adafruit Industries https://learn.adafruit.com/magtag-covid-tracking-project-iot-display Page 22 of 30


text_transform=lambda x: "New positive: {:,}".format(x),
)
# Curr hospitalized
magtag.add_text(
text_font="/fonts/Arial-Bold-12.pcf",
text_position=(10, 55),
text_transform=lambda x: "Current Hospital: {:,}".format(x),
)
# Change in hospitalized
magtag.add_text(
text_font="/fonts/Arial-Bold-12.pcf",
text_position=(10, 75),
text_transform=lambda x: "Change in Hospital: {:,}".format(x),
)
# All deaths
magtag.add_text(
text_font="/fonts/Arial-Bold-12.pcf",
text_position=(10, 95),
text_transform=lambda x: "Total deaths: {:,}".format(x),
)
# new deaths
magtag.add_text(
text_font="/fonts/Arial-Bold-12.pcf",
text_position=(10, 115),
text_transform=lambda x: "New deaths: {:,}".format(x),
)

# updated time
magtag.add_text(
text_font="/fonts/Arial-Bold-12.pcf",
text_position=(245, 30),
line_spacing=0.75,
is_data=False
)

magtag.graphics.qrcode(b"https://covidtracking.com/data",
qr_size=2, x=240, y=70)

magtag.peripherals.neopixels.brightness = 0.1
magtag.peripherals.neopixel_disable = False # turn on lights
magtag.peripherals.neopixels.fill(0x0F0000) # red!

magtag.get_local_time()
try:
now = time.localtime()
print("Now: ", now)

# display the current time since its the last-update


updated_at = "%d/%d\n%d:%02d" % now[1:5]
magtag.set_text(updated_at, 6, False)

# get data from the Covid Tracking Project


value = magtag.fetch()
print("Response is", value)

# OK we're done!
magtag.peripherals.neopixels.fill(0x000F00) # greten
except (ValueError, RuntimeError) as e:

© Adafruit Industries https://learn.adafruit.com/magtag-covid-tracking-project-iot-display Page 23 of 30


except (ValueError, RuntimeError) as e:
print("Some error occured, trying again later -", e)

time.sleep(2) # let screen finish updating

# we only wanna wake up once a day, around the event update time:
event_time = time.struct_time((now[0], now[1], now[2],
DAILY_UPDATE_HOUR, 0, 0,
-1, -1, now[8]))
# how long is that from now?
remaining = time.mktime(event_time) - time.mktime(now)
if remaining < 0: # ah its aready happened today...
remaining += 24 * 60 * 60 # wrap around to the next day
remaining_hrs = remaining // 3660
remaining_min = (remaining % 3600) // 60
print("Gonna zzz for %d hours, %d minutes" % (remaining_hrs, remaining_min))

# Turn it all off and go to bed till the next update time
magtag.exit_and_deep_sleep(remaining)

Code Walkthrough
Thankfully, the Covid Tracking Project folks made a free, easy-to-use JSON API endpoint that you can
easily query with the MagTag to get the current stats at https://api.covidtracking.com/v1/us/current.json
You can click on it right from your browser to see the current data and you'll get something like this

© Adafruit Industries https://learn.adafruit.com/magtag-covid-tracking-project-iot-display Page 24 of 30


[
{
"date": 20201210,
"states": 56,
"positive": 15360841,
"negative": 167187901,
"pending": 12409,
"hospitalizedCurrently": 107258,
"hospitalizedCumulative": 603554,
"inIcuCurrently": 21023,
"inIcuCumulative": 32919,
"onVentilatorCurrently": 7442,
"onVentilatorCumulative": 3394,
"recovered": 5985047,
"dateChecked": "2020-12-10T24:00:00Z",
"death": 283555,
"hospitalized": 603554,
"totalTestResults": 213015816,
"lastModified": "2020-12-10T24:00:00Z",
"total": 0,
"posNeg": 0,
"deathIncrease": 3067,
"hospitalizedIncrease": 4335,
"negativeIncrease": 1339749,
"positiveIncrease": 215669,
"totalTestResultsIncrease": 1954686,
"hash": "27226d54c5463327b7303d241b4085e06d976068"
}
]

These are pretty self-explanatory, note that date is not the current date, but the date at which the data
was collected. We'll be displaying positiveIncrease , hospitalizedCurrently, hospitalizedIncrease, death and
deathIncrease but of course the display can be customized.

Daily Update Time


The report from CTP only gets updated once a day, so its a good project for MagTag to deep-sleep
between reads. That way it can last many weeks on a charge. Data is updated at around 7:30pm eastern,
which is our local time. To account for any delay in reporting, we will check every night at 8pm eastern.
8pm eastern in 24-hour-time numbers is 20:00, so we put in 20 as the daily-check-hour. If you're in
another timezone, figure out what local time that translates to if you'd like to catch the report right after its
posted.

# Change this to the hour you want to check the data at, for us its 8pm
# local time (eastern), which is 20:00 hrs
DAILY_UPDATE_HOUR = 20

Text Transforms with lambdas

© Adafruit Industries https://learn.adafruit.com/magtag-covid-tracking-project-iot-display Page 25 of 30


The numbers we get from CTP need to have some text before them to explain what they are, for example
"New Positive" before the number we extract from the json API as "negativeIncrease": 1339749

To do that we use an 'anonymous function' (a.k.a. a lambda) which we can code in-line that will take the
string extracted " 1339749 " and preface it with the text " New positive: " as well as putting commas in
between the digit groupings.

Thats what this line does:

text_transform=lambda x: "New positive: {:,}".format(x)

lambda x: is basically the same as making a new function with:

def anonymous_function(x):
return "New positive: {:,}".format(x)

except it doesn't even have a name!

Adding a QR Code
For more info, you can visit the CTP website, we insert a QR code which will show on the E-Ink display
very nicely and can be scanned to get the full report

magtag.graphics.qrcode(b"https://covidtracking.com/data", qr_size=2, x=240, y=70)

The ' qr_size ' indicates the scaling, e.g. how big the pixel squares are. X and Y coordinates puts it over
on the bottom right

Connect and Update


The main chunk of code turns on the NeoPixels red for an indicator that we're connecting to the Internet,
gets the local time (we need this later), updates a text box in the top-right with the timestamp of the
current date/time so you know when it was last running, then calls magtag.fetch() to update all the text
boxes.

© Adafruit Industries https://learn.adafruit.com/magtag-covid-tracking-project-iot-display Page 26 of 30


magtag.peripherals.neopixels.brightness = 0.1
magtag.peripherals.neopixel_disable = False # turn on lights
magtag.peripherals.neopixels.fill(0x0F0000) # red!

magtag.get_local_time()
try:
now = time.localtime()
print("Now: ", now)

# display the current time since its the last-update


updated_at = "%d/%d\n%d:%02d" % now[1:5]
magtag.set_text(updated_at, 6, False)

# get data from the Covid Tracking Project


value = magtag.fetch()
print("Response is", value)

# OK we're done!
magtag.peripherals.neopixels.fill(0x000F00) # greten
except (ValueError, RuntimeError) as e:
print("Some error occured, trying again later -", e)

time.sleep(2) # let screen finish updating

After the display has updated, its time to go to sleep. For this project we want to wake up at exactly 8pm,
which might be later today or it might be tomorrow. Since we don't know what day it will be, we first
assume that we will be waking up later today by creating a new time structure with the same year, month,
day as today but the hour, min, sec is DAILY_UPDATE_HOUR, 0, 0:

event_time = time.struct_time((now[0], now[1], now[2], DAILY_UPDATE_HOUR, 0, 0, -1, -1, now[8]))

Then we convert the current time, and the next-wakeup time to seconds using time.mktime() and subtract
the difference. That is, what is the number of seconds between these two time points

remaining = time.mktime(event_time) - time.mktime(now)

If the amount of time is negative, that mean's that the "wake up today" time already happened, so we add
24-hours-worth of seconds to the time difference, to get to the event time one day later (tomorrow!)

if remaining < 0: # ah its aready happened today...


remaining += 24 * 60 * 60 # wrap around to the next day

We then display that time in hours and minutes, just for us to debug as humans

remaining_hrs = remaining // 3660


remaining_min = (remaining % 3600) // 60
print("Gonna zzz for %d hours, %d minutes" % (remaining_hrs, remaining_min))

And finally, we go into deep sleep mode until that time comes up

© Adafruit Industries https://learn.adafruit.com/magtag-covid-tracking-project-iot-display Page 27 of 30


# Turn it all off and go to bed till the next update time
magtag.exit_and_deep_sleep(remaining)

© Adafruit Industries https://learn.adafruit.com/magtag-covid-tracking-project-iot-display Page 28 of 30


Custom Plastic Cutout

If you'd like to give your MagTag a custom plastic cutout, you can cut out this AI file on a laser cutter or
CNC cutter out of 1.5mm thick material

https://adafru.it/Pde
https://adafru.it/Pde

© Adafruit Industries https://learn.adafruit.com/magtag-covid-tracking-project-iot-display Page 29 of 30


© Adafruit Industries Last Updated: 2021-05-19 05:20:39 PM EDT Page 30 of 30

You might also like