Threat Level Monitor using InkyPhat Red

Good morning fellow pirates. Considering the fact that a certain Russian despot has just been given another 6 years in power after a ̶̶t̶o̶t̶a̶l̶l̶y̶ ̶f̶a̶i̶r̶ ̶a̶n̶d̶ ̶d̶e̶m̶o̶c̶r̶a̶t̶i̶c̶ election, and his penchant for threatening the world with nuclear war, I thought it prudent to create a little project to let me know if shit is about to hit the fan. Mostly so I can sit down and cry as I live within vaporising distance of one of his reported missile targets.

Here it is in action:

This project uses a:
Pi Zero W with pre soldered headers - Raspberry Pi Zero W - Zero W
InkyPhat Red - Inky pHAT (ePaper/eInk/EPD) - Red/Black/White

This project assumes you have already installed the Raspberry Pi OS onto the SD card, and have attached the Inky to the headers. Once booted into RPi OS, configure your wireless settings according to your particular setup, as we need the internet for this project to work.

Next, open terminal and type:

sudo apt update && sudo apt upgrade -y

Now we need to install various dependencies in order for the script we’ll create later to run properly.

Still in terminal, type the following:

sudo apt install python3-requests -y

We use the requests library to fetch data from an external website.

sudo apt install python3-bs4 -y

The BeautifulSoup library is used for parsing HTML content.

Now for the all-important InkyPhat library:

git clone https://github.com/pimoroni/inky.git
cd inky
sudo python3 setup.py install

With that taken care of, we can create our script. Here in the UK, MI5 publishes and updates our current threat level, which we amusingly call the Bikini State. It’s our version of the US DEFCON. There are five levels - Low, Medium, Substantial, Severe and Critical. While working out my code, I connected to the MI5 threat level RSS feed so much, they blocked my IP address, so I have to get the level by parsing text on the main .gov.uk website instead. It’s exactly the same information, just from a different website.

Anyway, here is the code:

import requests
from bs4 import BeautifulSoup
import inkyphat
import time
# No need for schedule module in this version

def update_image():
    url = "https://www.gov.uk/terrorism-national-emergency"
    response = requests.get(url)
    soup = BeautifulSoup(response.text, "html.parser")

    sentence = soup.find(text="The threat to the UK (England, Wales, Scotland and Northern Ireland) from terrorism is ")
    
    if sentence:
        next_word = sentence.find_next("strong")
        if next_word:
            next_word = next_word.text.strip().lower()
            print(f"Retrieved sentence: {sentence}")  # Debugging print
            print(f"Next word (image indicator): {next_word}")  # Debugging print
            if next_word in image_paths:
                inkyphat.clear()  # Clear the display
                inkyphat.set_image(image_paths[next_word])
                inkyphat.show()

inkyphat.set_colour("red")  # Specify the color of your Inky pHAT
inkyphat.set_image("/home/pi/inky/images/connecting.png")
inkyphat.show()
time.sleep(15)  # Wait 5 seconds on boot

image_paths = {
    "low": "/home/pi/inky/images/1.png",
    "medium": "/home/pi/inky/images/2.png",
    "substantial": "/home/pi/inky/images/3.png",
    "severe": "/home/pi/inky/images/4.png",
    "critical": "/home/pi/inky/images/5.png"
}



# Continuous loop to check for updates (alternative to schedule)
while True:
  update_image()
  time.sleep(43200)  # Update every 12 hours (43200 seconds)

Save this as inky_display.py.

This code loads the initial image (connecting.png), waits a few seconds, then checks the website for the text

"The threat to the UK (England, Wales, Scotland and Northern Ireland) from terrorism is ".

The very next word after this text defines which image to update the display with. It will either say low, medium, substantial, severe or critical, with each word having a defined image attached to it.

Low = 1.png
Medium = 2.png
Substantial = 3.png
Severe = 4.png
Critical = 5.png

The code then goes into a continuous loop, checking the website every 12 hours, and updating the image accordingly.

To help you make sure it is displaying the correct image, you can run the code directly from terminal.

python3 inky_display.py

The code outputs the sentence and threat level word to the terminal every time it runs in this way. At the time of creating this tutorial, the threat level is Substantial, so you should see this in terminal:

Retrieved sentence: The threat to the UK (England, Wales, Scotland and Northern Ireland) from terrorism is 
Next word (image indicator): substantial

To get the script to run at boot without any user interaction you’ll need to edit your rc.local file:

sudo nano /etc/rc.local 

Add this to the end of the text in the file, changing the script name if you need to:

python3 /home/pi/inky_display.py &

My images are stored in the /home/pi/inky/images/ folder. If you store yours anywhere else, you’ll need to update the code as appropriate.

I have created a github repo here:

This contains a downloadable inky_display.py file, and all 6 images.

Finally, I don’t own a 3d printer, but here is a decent case I’ve found for this project on Thingiverse: Pi Zero E-Paper Pwnagotchi case by Ray1235225 - Thingiverse

This was a fun, and sometimes frustrating, little project for me. I hope someone else finds it useful!

3 Likes