Skip to content

Instantly share code, notes, and snippets.

@douxxtech
Created October 12, 2025 14:10
Show Gist options
  • Select an option

  • Save douxxtech/4adda818b33b0ec02d3084a43b0dde5f to your computer and use it in GitHub Desktop.

Select an option

Save douxxtech/4adda818b33b0ec02d3084a43b0dde5f to your computer and use it in GitHub Desktop.
A simple python script to broadcast SSTV stats via radio.

SSTV Stats

A simple python script to broadcast SSTV stats via radio.

This script uses piwave (2.0.7, not latest!), make sure to install it properly on a Raspberry Pi before using.
Other required modules can be installed via PIP

import time
import psutil
from PIL import Image, ImageDraw, ImageFont
from pysstv.grayscale import Robot8BW
from piwave import PiWave
from datetime import datetime
import subprocess

IMAGE_PATH = "pi_stats.png"
SSTV_WAV = "pi_stats.wav"

FREQUENCY = 96.9  # MHz
piwave = PiWave(
    frequency=FREQUENCY,
    ps="PiStats",
    rt="Raspberry Pi System Stats SSTV",
    pi="ABCD",
    loop=False,
    debug=True
)

def get_system_info():
    info = {}
    info['CPU Temp'] = f"{get_cpu_temp()}°C"
    info['CPU Load'] = psutil.cpu_percent(interval=0.5)
    info['RAM Usage'] = f"{psutil.virtual_memory().percent}%"
    info['Disk Usage'] = f"{psutil.disk_usage('/').percent}%"
    uptime_seconds = round(time.time() - psutil.boot_time())
    hours, remainder = divmod(uptime_seconds, 3600)
    minutes, seconds = divmod(remainder, 60)
    info['Uptime'] = f"{hours}h {minutes}m {seconds}s"
    info['Time'] = datetime.now().strftime("%H:%M:%S")
    return info

def get_cpu_temp():
    try:
        res = subprocess.check_output("vcgencmd measure_temp", shell=True).decode()
        # stout-> "temp=49.8'C"
        return float(res.split('=')[1].split("'")[0])
    except:
        return 0

def get_wifi_signal():
    try:
        import subprocess
        res = subprocess.check_output("iwconfig wlan0", shell=True, stderr=subprocess.DEVNULL).decode()
        for line in res.split('\n'):
            if 'Signal level' in line:
                level = line.split('Signal level=')[1].split(' ')[0]
                return int(level)
    except:
        return 0

def create_image(info):
    width, height = 320, 256
    image = Image.new('1', (width, height), color=0)  # fond noir
    draw = ImageDraw.Draw(image)
    font = ImageFont.load_default()

    title = "[ PiStats ]"
    draw.text((10, 0), title, font=font, fill=1)

    y = 20
    line_height = 15 # yet another random value so it fits
    keys = ['CPU Temp', 'CPU Load', 'RAM Usage', 'Disk Usage', 'Uptime', 'Time']

    for key in keys:
        val = info.get(key, 'N/A')
        draw.text((10, y), f"{key}: {val}", font=font, fill=1)
        y += line_height

    image.save(IMAGE_PATH)

def convert_to_sstv():
    img = Image.open(IMAGE_PATH)
    sstv = Robot8BW(img, samples_per_sec=44100, bits=16)
    sstv.write_wav(SSTV_WAV)

def transmit():
    piwave.stop()
    piwave.add_files([SSTV_WAV])
    piwave.play()

while True:
    info = get_system_info()
    create_image(info)
    convert_to_sstv()
    transmit()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment