feat: Add v0.2 remote management — UDP commands, LED, NVS persistence
Firmware (app_main.c): - UDP command listener on port 5501 (configurable via Kconfig) - Commands: REBOOT, IDENTIFY, STATUS, RATE, POWER - LED status indicator on GPIO2 (off/slow/fast blink/solid) - NVS persistence for send_rate and tx_power settings - Refactored ping to support stop/restart for dynamic rate changes - TX power control via esp_wifi_set_max_tx_power() Pi-side tooling: - tools/esp-cmd: standalone Python3 UDP client for device management Tested on amber-maple (ESP32 v3.1) with ESP-IDF v5.5.2.
This commit is contained in:
54
tools/esp-cmd
Executable file
54
tools/esp-cmd
Executable file
@@ -0,0 +1,54 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Send management commands to ESP32 CSI devices over UDP."""
|
||||
|
||||
import socket
|
||||
import sys
|
||||
|
||||
DEFAULT_PORT = 5501
|
||||
TIMEOUT = 2.0
|
||||
|
||||
USAGE = """\
|
||||
Usage: esp-cmd <ip> <command> [args...]
|
||||
|
||||
Commands:
|
||||
STATUS Query device state (uptime, heap, RSSI, tx_power, rate)
|
||||
REBOOT Restart the ESP32
|
||||
IDENTIFY Blink LED solid for 5 seconds
|
||||
RATE <10-100> Set ping frequency in Hz (saved to NVS)
|
||||
POWER <2-20> Set TX power in dBm (saved to NVS)
|
||||
|
||||
Examples:
|
||||
esp-cmd 192.168.1.50 STATUS
|
||||
esp-cmd 192.168.1.50 RATE 50
|
||||
esp-cmd 192.168.1.50 POWER 10
|
||||
esp-cmd 192.168.1.50 REBOOT
|
||||
esp-cmd 192.168.1.50 IDENTIFY"""
|
||||
|
||||
|
||||
def main():
|
||||
if len(sys.argv) < 3 or sys.argv[1] in ("-h", "--help"):
|
||||
print(USAGE)
|
||||
sys.exit(0 if sys.argv[1:] and sys.argv[1] in ("-h", "--help") else 2)
|
||||
|
||||
ip = sys.argv[1]
|
||||
cmd = " ".join(sys.argv[2:]).strip()
|
||||
|
||||
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||
sock.settimeout(TIMEOUT)
|
||||
|
||||
try:
|
||||
sock.sendto(cmd.encode(), (ip, DEFAULT_PORT))
|
||||
data, _ = sock.recvfrom(512)
|
||||
print(data.decode().strip())
|
||||
except socket.timeout:
|
||||
print(f"ERR: no reply from {ip}:{DEFAULT_PORT} (timeout {TIMEOUT}s)", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
except OSError as e:
|
||||
print(f"ERR: {e}", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
finally:
|
||||
sock.close()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user