161 lines
3.8 KiB
Bash
Executable File
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 "$@"
|