refactor(doorbell-touch): add build harness with monitor agent and board-specific setup
This commit is contained in:
98
scripts/monitor-agent.sh
Executable file
98
scripts/monitor-agent.sh
Executable file
@@ -0,0 +1,98 @@
|
||||
#!/usr/bin/env bash
|
||||
# Monitor agent - multiplexed serial monitor for AI interaction
|
||||
# Usage: ./scripts/monitor-agent.sh <board>
|
||||
#
|
||||
# Outputs:
|
||||
# - /tmp/doorbell-$BOARD.jsonl - JSON Lines log {"ts":123.456,"line":"..."}
|
||||
# - /tmp/doorbell-$BOARD-state.json - Current device state
|
||||
# - /tmp/doorbell-$BOARD-cmd.fifo - Command pipe (echo 'cmd' > fifo)
|
||||
#
|
||||
# Usage:
|
||||
# tail -f /tmp/doorbell-$BOARD.jsonl # Watch logs
|
||||
# echo 'dashboard' > /tmp/doorbell-$BOARD-cmd.fifo # Send command
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
BOARD="${1:-esp32-32e-4}"
|
||||
source "./boards/$BOARD/board-config.sh"
|
||||
source ./scripts/lockfile.sh
|
||||
|
||||
acquire_lock || exit 1
|
||||
|
||||
SERIAL="$PORT"
|
||||
LOGFILE="/tmp/doorbell-$BOARD.jsonl"
|
||||
STATEFILE="/tmp/doorbell-$BOARD-state.json"
|
||||
CMDFIFO="/tmp/doorbell-$BOARD-cmd.fifo"
|
||||
SCREENSOCK="doorbell-$BOARD"
|
||||
|
||||
# Cleanup
|
||||
cleanup() {
|
||||
screen -S "$SCREENSOCK" -X quit 2>/dev/null || true
|
||||
rm -f "$CMDFIFO"
|
||||
}
|
||||
trap cleanup EXIT
|
||||
|
||||
# Create command FIFO
|
||||
rm -f "$CMDFIFO"
|
||||
mkfifo "$CMDFIFO"
|
||||
|
||||
# Initialize state
|
||||
echo '{"screen":"BOOT","deviceState":"BOOTED","backlightOn":false}' > "$STATEFILE"
|
||||
|
||||
# Start screen in detached mode with logging
|
||||
# -L: enable logging
|
||||
# -Logfile: specify log file
|
||||
# -d -m: create detached
|
||||
# -S: session name
|
||||
screen -L -Logfile "$LOGFILE.raw" -d -m -S "$SCREENSOCK" "$SERIAL" 115200
|
||||
|
||||
# Give screen time to start
|
||||
sleep 1
|
||||
|
||||
# Reader: parse raw screen log -> JSON Lines + state
|
||||
(
|
||||
exec >>"$LOGFILE" 2>&1
|
||||
last_screen_line=""
|
||||
while IFS= read -r line; do
|
||||
# Skip duplicate/corrupted lines
|
||||
[[ "$line" == "$last_screen_line" ]] && continue
|
||||
last_screen_line="$line"
|
||||
|
||||
# Only process non-empty lines
|
||||
[[ -z "$line" ]] && continue
|
||||
|
||||
TS=$(date +%s.%3N)
|
||||
printf '{"ts":%s,"line":"%s"}\n' "$TS" "$line"
|
||||
|
||||
# Parse state changes
|
||||
case "$line" in
|
||||
*"[STATE]"*"→ OFF"*) echo '{"screen":"OFF"}' > "$STATEFILE" ;;
|
||||
*"[STATE]"*"→ DASHBOARD"*) echo '{"screen":"DASHBOARD"}' > "$STATEFILE" ;;
|
||||
*"[STATE]"*"→ ALERT"*) echo '{"screen":"ALERT"}' > "$STATEFILE" ;;
|
||||
*"[STATE]"*"→ BOOT"*) echo '{"screen":"BOOT"}' > "$STATEFILE" ;;
|
||||
*"[ADMIN]"*"dashboard"*) echo '{"screen":"DASHBOARD"}' > "$STATEFILE" ;;
|
||||
*"[ADMIN]"*"off"*) echo '{"screen":"OFF"}' > "$STATEFILE" ;;
|
||||
esac
|
||||
done < "$LOGFILE.raw"
|
||||
) &
|
||||
READER_PID=$!
|
||||
|
||||
# Writer: command FIFO -> screen session
|
||||
(
|
||||
while IFS= read -r cmd < "$CMDFIFO"; do
|
||||
# Send command to screen session
|
||||
screen -S "$SCREENSOCK" -X stuff "$cmd^M"
|
||||
echo "[SENT] $cmd"
|
||||
done
|
||||
) &
|
||||
WRITER_PID=$!
|
||||
|
||||
echo "Monitor agent started (BOARD=$BOARD):"
|
||||
echo " Log: $LOGFILE"
|
||||
echo " State: $STATEFILE"
|
||||
echo " Cmd: echo 'dashboard' > $CMDFIFO"
|
||||
echo ""
|
||||
echo "Press Ctrl+C to exit"
|
||||
|
||||
# Wait for reader
|
||||
wait "$READER_PID" || true
|
||||
Reference in New Issue
Block a user