Secrets.py Setup

Open the secrets.py file on your CircuitPython device using Mu or your favorite text editor. You're going to edit this file to enter the Twitter Bearer Token you saved earlier.

  • Change twitter_bearer_token to your app's Twitter bearer token

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 ssid',
    'password' : 'my password',
    'timezone' : "America/New_York", # http://worldtimeapi.org/timezones
    'github_token' : 'fawfj23rakjnfawiefa',
    'hackaday_token' : 'h4xx0rs3kret',
    'twitter_bearer_token' : 'YOUR_SECRET_TWITTER_BEARER_TOKEN'
    }

Code 

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 the contents of the zip file and place them on the CIRCUITPY drive.

# SPDX-FileCopyrightText: 2019 Dave Astels for Adafruit Industries.
# SPDX-FileCopyrightText: 2020 Brent Rubell for Adafruit Industries.
#
# SPDX-License-Identifier: Unlicense
import time
from adafruit_magtag.magtag import MagTag

try:
    from secrets import secrets
except ImportError:
    print(
        """WiFi settings are kept in secrets.py, please add them there!
the secrets dictionary must contain 'ssid' and 'password' at a minimum"""
    )
    raise

# Set to the twitter username you'd like to fetch tweets from
TWITTER_USERNAME = "adafruit"

# Set to the amount of time to deep sleep for, in minutes
SLEEP_TIME = 15

# Set up where we'll be fetching data from
DATA_SOURCE = (
    "https://api.twitter.com/1.1/statuses/user_timeline.json?"
    "screen_name=%s&count=1&tweet_mode=extended" % TWITTER_USERNAME
)
TWEET_TEXT = [0, "full_text"]
TWEET_FULL_NAME = [0, "user", "name"]
TWEET_HANDLE = [0, "user", "screen_name"]

magtag = MagTag(url=DATA_SOURCE, json_path=(TWEET_FULL_NAME, TWEET_HANDLE, TWEET_TEXT))
# Set Twitter OAuth2.0 Bearer Token
bearer_token = secrets["twitter_bearer_token"]
magtag.set_headers({"Authorization": "Bearer " + bearer_token})

# Display setup
magtag.set_background("/images/background.bmp")

# Twitter name
magtag.add_text(
    text_position=(70, 10),
    text_font="/fonts/Arial-Bold-12.pcf",
)

# Twitter handle (@username)
magtag.add_text(
    text_position=(70, 30),
    text_font="/fonts/Arial-12.bdf",
    text_transform=lambda x: "@%s" % x,
)

# Tweet text
magtag.add_text(
    text_font="/fonts/Arial-Bold-12.pcf",
    text_wrap=30,
    text_maxlen=160,
    text_position=(
        5,
        (magtag.graphics.display.height // 2) + 20,
    ),
    line_spacing=0.75,
)

# preload characters
magtag.preload_font()

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

time.sleep(2)
print("Sleeping!")
magtag.exit_and_deep_sleep(SLEEP_TIME * 60)

Once all the files are copied from your computer to the PyPortal, you should have the following files on your CIRCUITPY drive.

Code Usage

Every 15 minutes, the MagTag will attempt to fetch and display a new tweet from the Twitter handler specified in the code.

Then it goes into a deep sleep mode for 15 minutes to save energy.

 

Change the Twitter Handle

To display tweets from a specific Twitter account, change the following line in the code to the account you'd like to show tweets from:

TWITTER_USERNAME = 'adafruit'

Change the Sleep Time

After fetching and displaying a tweet, the MagTag goes into a deep-sleep mode for 15 minutes. Modify the following line in the code to reflect how long the MagTag will enter the deep sleep mode for, in minutes.

SLEEP_TIME = 15

Code Walkthrough

Data Sources

This project fetches data directly from Twitter's timeline API. A request is made to api.twitter.com to fetch the most recent status from a Twitter account, their full name, and their Twitter handle/username (such as @adafruit).

# Set up where we'll be fetching data from
DATA_SOURCE = "https://api.twitter.com/1.1/statuses/user_timeline.json?count=1&screen_name=%s"%TWITTER_USERNAME
TWEET_TEXT = [0, 'text']
TWEET_FULL_NAME = [0, 'user', 'name']
TWEET_HANDLE = [0, 'user', 'screen_name']

MagTag Library

The MagTag library makes it simple to create projects for the MagTag ePaper display. The code passes it the URL to fetch data from along with the JSON paths to retrieve the data.

magtag = MagTag(
    url=DATA_SOURCE,
    json_path=(TWEET_FULL_NAME, TWEET_HANDLE, TWEET_TEXT)
)
# Set Twitter OAuth2.0 Bearer Token
bearer_token = secrets['twitter_bearer_token']
magtag.set_headers({'Authorization': 'Bearer ' + bearer_token})

Display Objects

The code sets up a bitmap image background (a white background with a black Twitter logo) and text fields to hold the contents of the API response.

# Display setup
magtag.set_background("/images/background.bmp")

# Twitter username
magtag.add_text(
    text_position=(70, 10),
    text_font="/fonts/Arial-Bold-12.pcf",
)

# Twitter handle (@username)
magtag.add_text(
    text_position=(70, 30),
    text_font="/fonts/Arial-12.bdf",
    text_transform=lambda x: "@%s"%x,
)

# Tweet text
magtag.add_text(
    text_font="/fonts/Arial-Bold-12.pcf",
    text_wrap=40,
    text_maxlen=140,
    text_position=(
        10,
        (magtag.graphics.display.height // 2)+20,
    ),
    line_spacing=0.75,
)

# preload characters
magtag.preload_font()

Text Transform

Unfortunately, Twitter's API returns a twitter username without the "@" prefix. To add the @ prefix before a twitter username, the code uses an anonymous function (a "lambda") which is passed to the text_transform parameter in the magtag.add_text() function.

So, by calling text_transform=lambda x: "@%s"%x, we're creating a new anonymous function which looks like:

def x_function(x):

  return "@%s"%x

Update the Display

The main chunk of code attempts to fetch the URL from Twitter's API using magtag.fetch(). Then it parses out the data sources and displays the values on text labels.

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

time.sleep(2)
print("Sleeping!")
magtag.exit_and_deep_sleep(SLEEP_TIME * 60)

The code exits and goes into deep sleep until the next SLEEP_TIME minutes. 

magtag.exit_and_deep_sleep(SLEEP_TIME * 60)

This guide was first published on Dec 29, 2020. It was last updated on Dec 29, 2020.

This page (Code Usage) was last updated on Oct 08, 2021.

Text editor powered by tinymce.