MagTag CovidActNow
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Adapted from SpaceX Launch Display example | |
# SPDX-FileCopyrightText: Anne Barela November 2020, for Adafruit Industries LLC | |
# SPDX-FileCopyrightText: 2020-2021, Ryan Pavlik | |
# SPDX-License-Identifier: MIT | |
import time | |
import terminalio | |
from adafruit_magtag.magtag import MagTag | |
from secrets import secrets | |
# in seconds, we can refresh about 100 times on a battery | |
TIME_BETWEEN_REFRESHES = 24 * 60 * 60 # once a day delay | |
# For QR code, optional | |
# For some reason, pulling it from the API's json | |
# isn't working. | |
URL = secrets.get("url") | |
# Set up data location and fields | |
# See https://apidocs.covidactnow.org/api#tag/State-Data | |
fips = secrets.get("county_fips_code") | |
state_code = secrets.get("state_code") | |
cbsa = secrets.get("cbsa") | |
if fips: | |
DATA_SOURCE = ( | |
"https://api.covidactnow.org/v2/county/{fips}.json?apiKey={apiKey}".format( | |
fips=fips, apiKey=secrets["covid_act_now_key"] | |
) | |
) | |
TITLE_LOCATION = ("county",) | |
elif state_code: | |
DATA_SOURCE = ( | |
"https://api.covidactnow.org/v2/state/{state}.json?apiKey={apiKey}".format( | |
state=state_code, apiKey=secrets["covid_act_now_key"] | |
) | |
) | |
TITLE_LOCATION = ("state",) | |
elif cbsa: | |
DATA_SOURCE = ( | |
"https://api.covidactnow.org/v2/cbsa/{cbsa}.json?apiKey={apiKey}".format( | |
cbsa=cbsa, apiKey=secrets["covid_act_now_key"] | |
) | |
) | |
# TODO no human-readable description of a CBSA? | |
TITLE_LOCATION = ("locationId",) | |
else: | |
raise RuntimeError("Must specify county_fips_code, state_code, or cbsa in secrets.") | |
OVERALL_LOCATION = ( | |
"riskLevels", | |
"overall", | |
) | |
CDC_LEVEL_LOCATION = ("cdcTransmissionLevel",) | |
POSITIVITY_LOCATION = ( | |
"metrics", | |
"testPositivityRatio", | |
) | |
CASE_DENSITY_LOCATION = ( | |
"metrics", | |
"caseDensity", | |
) | |
R_T_LOCATION = ( | |
"metrics", | |
"infectionRate", | |
) | |
VAX_STARTED_LOCATION = ( | |
"metrics", | |
"vaccinationsInitiatedRatio", | |
) | |
LAST_UPDATED_LOCATION = ("lastUpdatedDate",) | |
ANNOTATIONS_LOCATION = ("annotations",) | |
URL_LOCATION = ("url",) | |
# These functions take the JSON data keys and does checks to determine | |
# how to display the data. They're used in the add_text blocks below | |
RISK_LEVELS_CONCISE = [ | |
"Low", | |
"Medium", | |
"High", | |
"Very High", | |
"Unknown", | |
"Severe", | |
] | |
RISK_LEVELS = [ | |
"Low - On track to contain COVID", | |
"Medium - Slow disease growth", | |
"High - At risk of outbreak", | |
"Very High - Active or imminent outbreak", | |
"Unknown - Risk unknown", | |
"Severe - Severe outbreak", | |
] | |
CDC_LEVELS = [ | |
"Low", | |
"Moderate", | |
"Substantial", | |
"High", | |
"Unknown", | |
] | |
def title_transform(val): | |
return "CovidActNow: " + val | |
def overall_transform(val): | |
# return RISK_LEVELS[val] | |
return RISK_LEVELS_CONCISE[val] | |
def case_density_transform(val): | |
return "Case density per 100k: {}".format(val) | |
def positivity_transform(val): | |
if val is None: | |
val = "Unknown" | |
else: | |
val = "{}%".format(val * 100) | |
return "Test Positivity: " + val | |
def r_t_transform(val): | |
if val is None: | |
val = "Unknown" | |
return "Estimated R_T: {}".format(val) | |
def r_t_ci90_transform(val): | |
if val is None: | |
val = "Unknown" | |
return "90th %ile: {}".format(val) | |
def cdc_level_transform(val): | |
if val is None: | |
val = "Unknown" | |
else: | |
val = CDC_LEVELS[val] | |
return "CDC risk level: {}".format(val) | |
def generic_risk_level_transform(name, val): | |
return name + ": " + RISK_LEVELS_CONCISE[val] | |
def updated_transform(val): | |
return "Data from CovidActNow, updated: " + val | |
def generic_transform(val): | |
return str(val) | |
# Set up the MagTag with the JSON data parameters | |
magtag = MagTag( | |
url=DATA_SOURCE, | |
json_path=( | |
TITLE_LOCATION, | |
OVERALL_LOCATION, | |
CDC_LEVEL_LOCATION, | |
POSITIVITY_LOCATION, | |
CASE_DENSITY_LOCATION, | |
R_T_LOCATION, | |
VAX_STARTED_LOCATION, | |
LAST_UPDATED_LOCATION, | |
ANNOTATIONS_LOCATION, | |
URL_LOCATION, | |
), | |
) | |
FIRST_LINE_POS = 40 | |
LINE_HEIGHT = 15 | |
magtag.add_text( | |
text_font="/fonts/SourceSerifPro-Bold-25.bdf", | |
text_position=(10, 15), | |
) | |
# Formatting for the overall risk | |
magtag.add_text( | |
text_font="/fonts/SourceSerifPro-Bold-25.bdf", | |
text_position=(175, 15), | |
text_transform=overall_transform, | |
) | |
# Formatting for the CDC risk | |
magtag.add_text( | |
text_font="/fonts/Montserrat-Regular-12.bdf", | |
text_position=(10, FIRST_LINE_POS), | |
text_transform=cdc_level_transform, | |
) | |
# Formatting for the positivity risk | |
magtag.add_text( | |
text_font="/fonts/Montserrat-Regular-12.bdf", | |
text_position=(10, FIRST_LINE_POS + LINE_HEIGHT * 1), | |
text_transform=positivity_transform, | |
) | |
magtag.add_text( | |
text_font="/fonts/Montserrat-Regular-12.bdf", | |
text_position=(10, FIRST_LINE_POS + LINE_HEIGHT * 2), | |
text_transform=case_density_transform, | |
) | |
magtag.add_text( | |
text_font="/fonts/Montserrat-Regular-12.bdf", | |
text_position=(10, FIRST_LINE_POS + LINE_HEIGHT * 3), | |
text_transform=r_t_transform, | |
) | |
magtag.add_text( | |
text_font="/fonts/Montserrat-Regular-12.bdf", | |
text_position=(10, FIRST_LINE_POS + LINE_HEIGHT * 4), | |
text_transform=lambda val: "First vaccine dose coverage: {:.1f}%".format(val * 100), | |
) | |
magtag.add_text( | |
text_font=terminalio.FONT, text_position=(10, 120), text_transform=updated_transform | |
) | |
if URL: | |
magtag.graphics.qrcode(URL, qr_size=2, x=220, y=45) | |
try: | |
# Have the MagTag connect to the internet | |
magtag.network.connect() | |
# This statement gets the JSON data and displays it automagically | |
value = magtag.fetch() | |
print("Response is", str(value).replace("'", '"').replace('None', 'null')) | |
# The last json value returned is the URL | |
# print(value[-1]) | |
# but this doesn't work. | |
# url = value[-1].encode('utf-8') | |
# magtag.graphics.qrcode(url, qr_size=2, x=220, y=45) | |
except (ValueError, RuntimeError) as e: | |
print("Some error occured, retrying! -", e) | |
# wait 2 seconds for display to complete | |
time.sleep(2) | |
magtag.exit_and_deep_sleep(TIME_BETWEEN_REFRESHES) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment