210 lines
7.8 KiB
Python
210 lines
7.8 KiB
Python
#!/usr/bin/env python3
|
||
# -*- coding: utf-8 -*-
|
||
"""
|
||
ESP32设备ID获取工具
|
||
通过HTTP API远程获取ESP32硬件标识符,无需烧录固件
|
||
"""
|
||
|
||
import requests
|
||
import json
|
||
import time
|
||
from datetime import datetime
|
||
|
||
class ESP32DeviceManager:
|
||
def __init__(self, device_ip="192.168.1.3", port=80):
|
||
self.device_ip = device_ip
|
||
self.port = port
|
||
self.base_url = f"http://{device_ip}:{port}/api/device"
|
||
|
||
def log_message(self, message):
|
||
"""打印带时间戳的日志"""
|
||
timestamp = datetime.now().strftime("%H:%M:%S.%f")[:-3]
|
||
print(f"[{timestamp}] {message}")
|
||
|
||
def get_device_id(self):
|
||
"""获取设备ID(简化版)"""
|
||
try:
|
||
response = requests.get(f"{self.base_url}/id", timeout=5)
|
||
if response.status_code == 200:
|
||
data = response.json()
|
||
return data
|
||
else:
|
||
self.log_message(f"❌ 获取设备ID失败: HTTP {response.status_code}")
|
||
return None
|
||
except requests.exceptions.RequestException as e:
|
||
self.log_message(f"❌ 网络请求失败: {e}")
|
||
return None
|
||
|
||
def get_device_info(self):
|
||
"""获取完整设备信息"""
|
||
try:
|
||
response = requests.get(f"{self.base_url}/info", timeout=10)
|
||
if response.status_code == 200:
|
||
data = response.json()
|
||
return data
|
||
else:
|
||
self.log_message(f"❌ 获取设备信息失败: HTTP {response.status_code}")
|
||
return None
|
||
except requests.exceptions.RequestException as e:
|
||
self.log_message(f"❌ 网络请求失败: {e}")
|
||
return None
|
||
|
||
def get_device_status(self):
|
||
"""获取设备状态"""
|
||
try:
|
||
response = requests.get(f"{self.base_url}/status", timeout=5)
|
||
if response.status_code == 200:
|
||
data = response.json()
|
||
return data
|
||
else:
|
||
self.log_message(f"❌ 获取设备状态失败: HTTP {response.status_code}")
|
||
return None
|
||
except requests.exceptions.RequestException as e:
|
||
self.log_message(f"❌ 网络请求失败: {e}")
|
||
return None
|
||
|
||
def register_device(self, server_url, device_name=None, location=None):
|
||
"""向远程服务器注册设备"""
|
||
try:
|
||
payload = {
|
||
"server_url": server_url,
|
||
"device_name": device_name or f"ESP32设备_{self.device_ip}",
|
||
"location": location or "未知位置"
|
||
}
|
||
|
||
response = requests.post(f"{self.base_url}/register",
|
||
json=payload, timeout=10)
|
||
if response.status_code == 200:
|
||
data = response.json()
|
||
return data
|
||
else:
|
||
self.log_message(f"❌ 设备注册失败: HTTP {response.status_code}")
|
||
return None
|
||
except requests.exceptions.RequestException as e:
|
||
self.log_message(f"❌ 网络请求失败: {e}")
|
||
return None
|
||
|
||
def display_device_info(self, info):
|
||
"""格式化显示设备信息"""
|
||
if not info:
|
||
return
|
||
|
||
print("\n" + "="*60)
|
||
print("🔍 ESP32设备硬件信息")
|
||
print("="*60)
|
||
|
||
# 基本标识信息
|
||
print(f"🆔 设备ID: {info.get('device_id', 'N/A')}")
|
||
print(f"📡 MAC地址: {info.get('mac_address', 'N/A')}")
|
||
print(f"🔢 数字ID: {info.get('numeric_id', 'N/A')} (0x{info.get('numeric_id', 0):08X})")
|
||
|
||
# 芯片信息
|
||
print(f"🔧 芯片型号: {info.get('chip_model', 'N/A')}")
|
||
print(f"📋 芯片版本: {info.get('chip_revision', 'N/A')}")
|
||
print(f"⚡ CPU核心: {info.get('chip_cores', 'N/A')}")
|
||
print(f"💾 Flash大小: {info.get('flash_size_bytes', 0) / (1024*1024):.1f} MB")
|
||
|
||
# 固件信息
|
||
print(f"🚀 项目名称: {info.get('project_name', 'N/A')}")
|
||
print(f"📦 固件版本: {info.get('firmware_version', 'N/A')}")
|
||
print(f"📅 编译日期: {info.get('compile_date', 'N/A')}")
|
||
print(f"⏰ 编译时间: {info.get('compile_time', 'N/A')}")
|
||
|
||
# 系统状态
|
||
uptime = info.get('uptime_seconds', 0)
|
||
hours = uptime // 3600
|
||
minutes = (uptime % 3600) // 60
|
||
seconds = uptime % 60
|
||
print(f"⏱️ 运行时间: {hours:02d}:{minutes:02d}:{seconds:02d}")
|
||
print(f"🧠 空闲内存: {info.get('free_heap_bytes', 0) / 1024:.1f} KB")
|
||
|
||
print("="*60)
|
||
print("✅ 所有ID均为芯片出厂烧录,全球唯一!")
|
||
print("="*60)
|
||
|
||
def main():
|
||
"""主函数 - 演示各种获取方式"""
|
||
print("🔍 ESP32设备ID获取工具")
|
||
print("=" * 50)
|
||
|
||
# 创建设备管理器
|
||
manager = ESP32DeviceManager("192.168.1.3") # 您的ESP32 IP地址
|
||
|
||
print("\n📋 方法1:获取设备ID(快速)")
|
||
print("-" * 30)
|
||
device_id_info = manager.get_device_id()
|
||
if device_id_info:
|
||
print(f"🆔 设备ID: {device_id_info.get('device_id')}")
|
||
print(f"🔢 数字ID: {device_id_info.get('numeric_id')} (0x{device_id_info.get('numeric_id', 0):08X})")
|
||
|
||
print("\n📋 方法2:获取完整设备信息")
|
||
print("-" * 30)
|
||
device_info = manager.get_device_info()
|
||
if device_info:
|
||
manager.display_device_info(device_info)
|
||
|
||
print("\n📋 方法3:获取设备状态")
|
||
print("-" * 30)
|
||
device_status = manager.get_device_status()
|
||
if device_status:
|
||
print(f"🆔 设备ID: {device_status.get('device_id')}")
|
||
print(f"⏱️ 运行时间: {device_status.get('uptime_seconds')} 秒")
|
||
print(f"🧠 空闲内存: {device_status.get('free_heap_bytes', 0) / 1024:.1f} KB")
|
||
print(f"📶 WiFi连接: {'✅ 已连接' if device_status.get('wifi_connected') else '❌ 未连接'}")
|
||
if device_status.get('wifi_connected'):
|
||
print(f"📡 WiFi SSID: {device_status.get('wifi_ssid', 'N/A')}")
|
||
print(f"📶 信号强度: {device_status.get('wifi_rssi', 'N/A')} dBm")
|
||
|
||
# 演示设备注册(可选)
|
||
print("\n📋 方法4:设备注册演示")
|
||
print("-" * 30)
|
||
register_result = manager.register_device(
|
||
server_url="http://your-server.com/api/devices",
|
||
device_name="厨房热成像监控",
|
||
location="厨房"
|
||
)
|
||
if register_result:
|
||
print(f"✅ 设备注册成功: {register_result.get('message')}")
|
||
print(f"🆔 注册设备ID: {register_result.get('device_id')}")
|
||
|
||
def scan_devices():
|
||
"""扫描网络中的ESP32设备"""
|
||
print("\n🔍 扫描网络中的ESP32设备...")
|
||
print("-" * 40)
|
||
|
||
# 扫描常见的ESP32 IP范围
|
||
base_ip = "192.168.1."
|
||
found_devices = []
|
||
|
||
for i in range(1, 255):
|
||
ip = f"{base_ip}{i}"
|
||
try:
|
||
manager = ESP32DeviceManager(ip)
|
||
device_id_info = manager.get_device_id()
|
||
if device_id_info:
|
||
found_devices.append({
|
||
'ip': ip,
|
||
'device_id': device_id_info.get('device_id'),
|
||
'numeric_id': device_id_info.get('numeric_id')
|
||
})
|
||
print(f"✅ 发现设备: {ip} - ID: {device_id_info.get('device_id')}")
|
||
except:
|
||
pass # 忽略连接失败的IP
|
||
|
||
print(f"\n📊 扫描完成,发现 {len(found_devices)} 个ESP32设备")
|
||
return found_devices
|
||
|
||
if __name__ == "__main__":
|
||
try:
|
||
main()
|
||
|
||
# 可选:扫描网络设备
|
||
scan_choice = input("\n是否扫描网络中的其他ESP32设备?(y/N): ")
|
||
if scan_choice.lower() == 'y':
|
||
scan_devices()
|
||
|
||
except KeyboardInterrupt:
|
||
print("\n⏹️ 程序被用户中断")
|
||
except Exception as e:
|
||
print(f"\n💥 程序异常: {str(e)}")
|