170 lines
4.6 KiB
Bash
170 lines
4.6 KiB
Bash
#!/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
|