Files
klubhaus-doorbell/scripts/detect-device.sh

161 lines
3.8 KiB
Bash
Executable File

#!/bin/bash
#
# detect-device.sh - Detect which doorbell board is connected
#
# Uses two methods:
# 1. Firmware query (if flashed): sends "board" command, expects "[BOARD] xxx"
# 2. Hardware probe (fallback): uses esptool to query chip type and flash size
#
# Usage: ./scripts/detect-device.sh [port]
# If no port specified, tries common ports: /dev/ttyUSB0 /dev/ttyACM0
set -e
# Configuration
TIMEOUT_FIRMWARE=2
TIMEOUT_HARDWARE=5
# Known boards and their characteristics
declare -A BOARD_CHIP=(
["esp32-s3-lcd-43"]="ESP32-S3"
["esp32-32e"]="ESP32"
["esp32-32e-4"]="ESP32"
)
# Find available serial ports
find_ports() {
local ports=()
for p in /dev/ttyUSB0 /dev/ttyUSB1 /dev/ttyACM0 /dev/ttyACM1; do
if [ -e "$p" ]; then
ports+=("$p")
fi
done
printf '%s\n' "${ports[@]}"
}
# Query firmware for board name
query_firmware() {
local port="$1"
# Try using Python for more reliable serial communication
local output
output=$(python3 -c "
import serial
import time
try:
s = serial.Serial('$port', 115200, timeout=$TIMEOUT_FIRMWARE)
time.sleep(0.5)
s.write(b'board\r\n')
time.sleep($TIMEOUT_FIRMWARE)
print(s.read(200).decode('utf-8', errors='ignore'))
s.close()
except:
pass
" 2>/dev/null || true)
# Look for [BOARD] xxx pattern
if echo "$output" | grep -q '\[BOARD\]'; then
local board
board=$(echo "$output" | grep '\[BOARD\]' | sed 's/.*\[BOARD\] //' | tr -d '\r\n')
if [ -n "$board" ]; then
echo "$board"
return 0
fi
fi
return 1
}
# Hardware probe using esptool
probe_hardware() {
local port="$1"
# Get chip info
local chip_info
chip_info=$(timeout "$TIMEOUT_HARDWARE" esptool --port "$port" chip_id 2>/dev/null || true)
if [ -z "$chip_info" ]; then
return 1
fi
# Check for ESP32-S3
if echo "$chip_info" | grep -q "ESP32-S3"; then
echo "esp32-s3-lcd-43"
return 0
fi
# For ESP32, check flash size
if echo "$chip_info" | grep -q "ESP32"; then
local flash_size
flash_size=$(echo "$chip_info" | grep -i "flash size" | grep -oE '[0-9]+' | head -1 || echo "0")
if [ -n "$flash_size" ] && [ "$flash_size" -ge 8 ]; then
# 8MB+ flash - likely esp32-32e-4
echo "esp32-32e-4 (or esp32-32e)"
return 0
else
# 4MB or less - likely esp32-32e
echo "esp32-32e (or esp32-32e-4)"
return 0
fi
fi
return 1
}
# Main detection logic
detect() {
local port="$1"
# Try firmware query first (100% accurate if firmware responds)
echo "Trying firmware query on $port..." >&2
local result
result=$(query_firmware "$port" || true)
if [ -n "$result" ]; then
echo "Detected via firmware: $result"
return 0
fi
# Fall back to hardware probe
echo "Trying hardware probe on $port..." >&2
result=$(probe_hardware "$port" || true)
if [ -n "$result" ]; then
echo "Detected via hardware: $result"
return 0
fi
echo "No device detected on $port" >&2
return 1
}
# Entry point
main() {
local target_port="$1"
if [ -n "$target_port" ]; then
# Specific port requested
if [ ! -e "$target_port" ]; then
echo "Error: Port $target_port does not exist" >&2
exit 1
fi
detect "$target_port"
else
# Auto-detect: try all available ports
local found=0
for port in $(find_ports); do
if detect "$port"; then
found=1
break
fi
done
if [ "$found" -eq 0 ]; then
echo "No doorbell device detected" >&2
exit 1
fi
fi
}
main "$@"