Files
nrfwatch/sim/view.py
T
2026-05-01 11:53:56 +02:00

93 lines
2.1 KiB
Python

#!/usr/bin/env python3
"""Reads hex-framed display data from stdin, writes PBM, auto-launches feh."""
import sys
import os
import signal
import subprocess
import time
WIDTH = 200
HEIGHT = 200
BUFSIZE = (WIDTH * HEIGHT) // 8
OUT = "/tmp/nrfwarch.pbm"
FRAME_START = "!F!"
FRAME_END = "!E!"
feh_proc = None
def write_pbm(data):
header = f"P4\n{WIDTH} {HEIGHT}\n".encode()
inverted = bytes((~b) & 0xFF for b in data)
tmp = OUT + ".tmp"
with open(tmp, "wb") as f:
f.write(header)
f.write(inverted)
os.replace(tmp, OUT)
def launch_feh():
global feh_proc
if feh_proc is not None and feh_proc.poll() is None:
return
try:
feh_proc = subprocess.Popen(
[
"feh",
"--force-aliasing",
"--scale",
"auto",
"--auto-reload",
"--title", "nrfwarch sim",
OUT,
],
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
)
except FileNotFoundError:
print("feh not found, writing PBM to " + OUT)
def cleanup(*_):
global feh_proc
if feh_proc and feh_proc.poll() is None:
feh_proc.terminate()
sys.exit(0)
def main():
signal.signal(signal.SIGTERM, cleanup)
signal.signal(signal.SIGINT, cleanup)
write_pbm(bytes([0xFF] * BUFSIZE))
launch_feh()
capturing = False
hex_buf = ""
frame_count = 0
for line in sys.stdin:
line = line.strip()
if line == FRAME_START:
capturing = True
hex_buf = ""
elif line == FRAME_END:
if capturing and hex_buf:
try:
data = bytes.fromhex(hex_buf)
if len(data) == BUFSIZE:
write_pbm(data)
frame_count += 1
print(f" frame {frame_count}", file=sys.stderr)
except ValueError:
pass
capturing = False
hex_buf = ""
elif capturing:
hex_buf += line
if __name__ == "__main__":
main()