#!/bin/bash # diag-led.sh — LED matrix end-to-end diagnostic # Run on the board: just diag-led # Tests: router → MCU serial → draw_frame → OK # UDP 8082 → viz process → rchar increase set -euo pipefail PASS=0; FAIL=0 pass() { echo " ✓ $*"; PASS=$((PASS+1)); } fail() { echo " ✗ $*"; FAIL=$((FAIL+1)); } echo "=== LED Matrix Diagnostic ===" echo "" # --- Test 1: Router socket --- echo "1. Router socket" if [ -S /var/run/arduino-router.sock ]; then pass "socket /var/run/arduino-router.sock exists" else fail "router socket missing" fi # --- Test 2: arduino-router service --- echo "2. arduino-router service" if systemctl is-active arduino-router &>/dev/null; then pass "arduino-router is running" else fail "arduino-router not running" fi # --- Test 3: RPC connectivity --- echo "3. Router RPC connectivity" RPC_RESPONSE=$(python3 -c " import socket, msgpack try: s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) s.settimeout(3) s.connect('/var/run/arduino-router.sock') p = msgpack.Packer() s.sendall(p.pack([0, 99, 'get_status', ['']])) s.settimeout(1) resp = s.recv(256) s.close() print('OK:' + repr(resp[:60])) except Exception as e: print('FAIL:' + str(e)) " 2>&1) if echo "$RPC_RESPONSE" | grep -q "^OK:"; then pass "get_status responded" else fail "get_status: $RPC_RESPONSE" fi # --- Test 4: draw_frame --- echo "4. draw_frame RPC" FRAME_RESPONSE=$(python3 -c " import socket, msgpack, struct try: s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) s.settimeout(3) s.connect('/var/run/arduino-router.sock') p = msgpack.Packer() # Alternating columns test pattern bits = 0 for row in range(8): for col in range(0, 13, 2): bits |= 1 << (row * 13 + col) f0 = bits & 0xFFFFFFFF f1 = (bits >> 32) & 0xFFFFFFFF f2 = (bits >> 64) & 0xFFFFFFFF f3 = (bits >> 96) & 0xFFFFFFFF s.sendall(p.pack([0, 100, 'draw_frame', [str(f0), str(f1), str(f2), str(f3)]])) s.settimeout(1) resp = s.recv(128) s.close() if b'OK' in resp: print('OK') else: print('FAIL:' + repr(resp[:50])) except Exception as e: print('FAIL:' + str(e)) " 2>&1) if echo "$FRAME_RESPONSE" | grep -q "^OK"; then pass "draw_frame returned OK" else fail "draw_frame: $FRAME_RESPONSE" fi # --- Test 5: led-matrix-viz service --- echo "5. led-matrix-viz service" if systemctl is-active led-matrix-viz &>/dev/null; then pass "led-matrix-viz is running" else fail "led-matrix-viz not running" fi # --- Test 6: UDP receive (send note, check rchar) --- echo "6. UDP → viz → router (end-to-end)" VIZ_PID=$(pgrep -f 'python3.*led-matrix-viz' 2>/dev/null | head -1) if [ -z "$VIZ_PID" ]; then fail "viz process not found" else R1=$(sudo cat /proc/$VIZ_PID/io 2>/dev/null | grep rchar | awk '{print $2}') W1=$(sudo cat /proc/$VIZ_PID/io 2>/dev/null | grep wchar | awk '{print $2}') python3 -c " import socket s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) for n in [60, 64, 67, 72, 76, 79, 84]: s.sendto(f'midi 144 {n} 100;'.encode(), ('127.0.0.1', 8082)) s.close() " 2>/dev/null sleep 2 R2=$(sudo cat /proc/$VIZ_PID/io 2>/dev/null | grep rchar | awk '{print $2}') W2=$(sudo cat /proc/$VIZ_PID/io 2>/dev/null | grep wchar | awk '{print $2}') RDIFF=$((R2 - R1)) WDIFF=$((W2 - W1)) if [ "$RDIFF" -gt 0 ]; then pass "viz received +${RDIFF}r bytes, sent +${WDIFF}w bytes to router" else fail "viz rchar unchanged — not receiving UDP (r=$RDIFF, w=$WDIFF)" fi fi # --- Test 7: f_midi gadget --- echo "7. f_midi gadget status" if [ -f /proc/asound/card2/midi0 ]; then RX=$(grep "Rx bytes" /proc/asound/card2/midi0 | awk '{print $4}') pass "f_midi present (Rx=${RX} bytes)" else fail "f_midi gadget not found" fi # --- Test 8: midi-bridge forwarding --- echo "8. midi-bridge service" if systemctl is-active midi-bridge &>/dev/null; then MB_PID=$(pgrep -f 'python3.*midi-bridge' | head -1) pass "midi-bridge running (PID=$MB_PID)" else fail "midi-bridge not running" fi # --- Clear matrix, summary --- python3 -c " import socket, msgpack s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) s.settimeout(3) s.connect('/var/run/arduino-router.sock') p = msgpack.Packer() s.sendall(p.pack([0, 200, 'clear', []])) s.recv(128) s.close() " 2>/dev/null echo "" echo "==============================" if [ "$FAIL" -eq 0 ]; then echo " ALL CHECKS PASSED ($PASS/$((PASS+FAIL)))" echo " LED matrix chain is healthy." else echo " $PASS passed, $FAIL failed" fi echo "==============================" exit $FAIL