Last active
October 9, 2023 05:19
-
-
Save mdkendall/a43b203ff42a429706e819179b4aa80c to your computer and use it in GitHub Desktop.
Python script to display Raspberry Pi status on SSD1306-based 128x64px OLED connected via I2C
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
#!/bin/bash | |
# Prerequisite: | |
# Enable I2C using raspi-config if necessary | |
# Install I2C support, Python image library, and other support libraries. | |
sudo apt install -y python3-smbus i2c-tools | |
sudo apt install -y python3-pil | |
sudo apt install -y python3-pip | |
sudo apt install -y python3-setuptools | |
sudo apt install -y python3-rpi.gpio | |
# Install Adafruit SSD1306 driver. This is the older version that | |
# does not depend on the CircuitPython abstraction layer. | |
git clone https://github.com/adafruit/Adafruit_Python_SSD1306.git | |
cd Adafruit_Python_SSD1306 | |
sudo python setup.py install | |
cd .. | |
# Install the process utilities library that is used by the script. | |
sudo apt install python3-psutil | |
# Install the font used by the script | |
wget https://github.com/google/fonts/raw/376ff5c1ab3952ec7d324a2222f1018a09b2a437/apache/roboto/static/Roboto-Regular.ttf -P Roboto | |
sudo cp -r Roboto /usr/share/fonts/truetype | |
# Install the script | |
sudo cp oled_status.py /usr/local/bin/oled_status | |
sudo chmod +x /usr/local/bin/oled_status | |
# Create a user to run the script | |
sudo useradd -r oled | |
sudo usermod -a -G i2c oled | |
# Install the service | |
sudo cp oled.service /lib/systemd/system | |
sudo systemctl start oled | |
sudo systemctl enable oled |
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
[Unit] | |
Description=OLED Status Display | |
[Service] | |
User=oled | |
ExecStart=/usr/local/bin/oled_status | |
SyslogIdentifier=oled | |
Type=simple | |
Restart=on-failure | |
RestartSec=30 | |
Nice=10 | |
[Install] | |
WantedBy=default.target |
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
#! /usr/bin/python3 | |
# Loosely based on Adafruit_Python_SSD1306/examples/stats.py | |
# | |
# Modified to use psutil instead of spawning shells to run commands to get stats. | |
# This, plus sleeping to yield after getting stats and updating image, plus | |
# reducing the update rate to only every 3s, dramatically lowers the CPU usage. | |
# To further reduce impact on other real-time programs, run with 'nice'. | |
import time | |
import psutil | |
import Adafruit_SSD1306 | |
from PIL import Image, ImageDraw, ImageFont | |
# 128x64 display with hardware I2C: | |
disp = Adafruit_SSD1306.SSD1306_128_64(rst=None) | |
# Initialize and clear the display. | |
disp.begin() | |
disp.clear() | |
disp.display() | |
# Create a blank 1-bit image and get an associated drawing object. | |
image = Image.new('1', (disp.width, disp.height)) | |
draw = ImageDraw.Draw(image) | |
# Load a TTF font from a .ttf file and set the height in pixels. | |
font = ImageFont.truetype('/usr/share/fonts/truetype/Roboto/Roboto-Regular.ttf', 12) | |
while True: | |
# Draw a black filled box to clear the image. | |
draw.rectangle((0, 0, disp.width, disp.height), outline=0, fill=0) | |
# Get stats to display. | |
ip_addr = psutil.net_if_addrs()['wlan0'][0].address | |
cpu_percent = psutil.cpu_percent() | |
cpu_load = psutil.getloadavg() | |
mem_usage = psutil.virtual_memory() | |
disk_usage = psutil.disk_usage('/') | |
temperature = psutil.sensors_temperatures()['cpu_thermal'][0].current | |
time.sleep(0.1) | |
# Write text to the image. | |
draw.text((0, 0), "IP %s" % (ip_addr), font=font, fill=255) | |
draw.text((0, 12), "CPU %d%% Load %.2f" % (cpu_percent, cpu_load[0]), font=font, fill=255) | |
draw.text((0, 24), "Mem %d/%dM %d%%" % (mem_usage.used/(1<<20), mem_usage.total/(1<<20), mem_usage.percent), font=font, fill=255) | |
draw.text((0, 36), "Disk %d/%dG %d%%" % (disk_usage.used/(1<<30), disk_usage.total/(1<<30), disk_usage.percent), font=font, fill=255) | |
draw.text((0, 48), "Temp %dC" % (temperature), font=font, fill=255) | |
time.sleep(0.1) | |
# Display image. | |
disp.image(image) | |
disp.display() | |
time.sleep(3) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment