Blinkt! Watch CPU & Temperature Visually with a Raspberry Pi

Raspberry Pi Docker Swarm

Blinkt!

While I was using pimoroni example scripts to show CPU usage on my Docker Swarm nodes running on my Raspberry Pi 4b I wanted more. I found the is Docker image cisecke/blinkt-cpu-info however I felt no need to run this Python script as a container. The advantage of this is the script will startup immediately on bootup and not rely on Docker.

First you should have Blinkt! installed. You can go to the official GitHub repository here for their installation instructions or run these commands.

curl https://get.pimoroni.com/blinkt | bash

Or on Raspbian

sudo apt-get install pimoroni

Now since I wasn’t a fan purple I had to edit cisecke’s script to run without Docker and recognize I’m using a Blinkt!. His script also supports LED Shim. Here’s my edited script.

led.py

#!/usr/bin/env python

import signal
import os
import time
import psutil
from subprocess import PIPE, Popen
import sys
import math


#device = os.environ['Device'].lower()
device = "blinkt".entry-title {
display: none;
}
if device not in ['blinkt', 'shim']:
    raise ValueError('Device not recognized.')
if device == "shim":
    import ledshim as output_device
else:
    import blinkt as output_device

#mode = os.environ['Mode'].lower()
mode = "mixed"
if mode not in ['mixed', 'temp', 'load']:
    raise ValueError('Mode not recognized.')
#brightness_parameter = os.environ['Brightness'].strip()
brightness_parameter = .5
if brightness_parameter and not brightness_parameter == "":
    brightness = min(float(brightness_parameter), 1)
else:
    if device == 'shim':
        brightness = 1
    else:
        brightness = 1
#interval = max(float(os.environ['Interval']), 0)
interval = 0.05
#smooth = os.environ['Smooth'].lower() == "true"
smooth = "false"
#marker_parameter = os.environ['Marker'].lower().strip()
marker_parameter = "false"
if marker_parameter in ['true', 'false']:
    marker = marker_parameter == "true"
else:
    marker = device == "shim"
#segmented_parameter = os.environ['Segmented'].lower().strip()
segmented_parameter = 'false'
if segmented_parameter in ['true', 'false']:
    segmented = segmented_parameter == "true"
else:
    segmented = device == "shim"
#direction = os.environ['Direction']
direction = "RTL"

output_device.set_brightness(brightness)
running = True


def sigterm(x, y):
    global running
    running = False


# Register the signal to the handler
signal.signal(signal.SIGTERM, sigterm)


def get_cpu_temperature():
    process = Popen(['vcgencmd', 'measure_temp'], stdout=PIPE)
    output, _error = process.communicate()
    output = output.decode()

    pos_start = output.index('=') + 1
    pos_end = output.index("'")

    temp = float(output[pos_start:pos_end])

    return temp


def show_graph(temp, load):
    segment_pixels_count = output_device.NUM_PIXELS / 4
    temp = temp / 80 * output_device.NUM_PIXELS
    if isinstance(load, list):
        load = [x / 100 * segment_pixels_count for x in load]
    else:
        load = load / 100 * output_device.NUM_PIXELS
    pixels = range(output_device.NUM_PIXELS)
    current = 0
    if direction.lower() == "rtl":
        pixels = reversed(pixels)
    for x in pixels:
        r, g, b = 0, 0, 0
        if temp > 0:
            r = get_value(temp)
            temp -= 1
        if isinstance(load, list):
            segment_index = math.trunc(x / segment_pixels_count)
            if load[segment_index] > 0:
                b = get_value(load[segment_index])
                load[segment_index] -= 1
        else:
            if load > 0:
                g = get_value(load)
                load -= 1

        # show the marker, if it's not the last pixel and if it's the last pixel of the segment.
        if marker and current + 1 != output_device.NUM_PIXELS and (current +1) % segment_pixels_count == 0:
            g = 255
        output_device.set_pixel(x, r, g, b)
        current += 1

    output_device.show()


def get_value(value):
    max_value = 255
    if smooth and value <= 1:
        return max_value * value
    else:
        return max_value


def show_info():
    temp = 0
    load = 0
    if mode in ['mixed', 'temp']:
        temp = get_cpu_temperature()
    if mode in ['mixed', 'load']:
#        if segmented:.entry-title {
display: none;
}
#            load = psutil.cpu_percent(percpu=segmented)
#        else:
            load = psutil.cpu_percent()
    show_graph(temp, load)


if __name__ == '__main__':
    while True:
        if running:
            show_info()
            time.sleep(interval)
        else:
            break
    # shut off pixels and exit
    output_device.clear()
    output_device.show()


Then we need to start the script on boot so we will edit crontab

crontab -e

An add this line

@reboot python3 path_to_your_script/led.py &

Now either reboot or run the script manually and you should get this

Posted in DockerHardwareRaspberry PiSoftware

Tags - BlinktRaspberry Pi