You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

用Python在本地网络中自动发现ESP8266 NodeMCU设备IP地址

动态发现本地网络中的ESP8266设备并批量控制

问题背景

我有运行本地HTTP服务器的ESP8266 NodeMCU设备,已完成初始配置。目标是同步控制大量该设备,当前Python脚本可手动指定IP实现LED控制,但需动态发现本地网络中所有搭载相同固件的ESP8266设备IP,无需静态IP或设备端独特配置。曾尝试用socket模块查找以“ESP-”开头的主机名但无结果,需要适配Mac环境的解决方案。现有脚本如下:

#!/usr/bin/env python
import time
import sys
import socket
import requests

def myFunction():
    #This is what I have right now...
    ipAddresses = ["192.168.1.43", "192.168.1.44"]

    #
    #Instead, I need to search the local network for all the arduinos [ESP8266s] and append their address to the array.
    #

    for address in ipAddresses:
        TurnOnLED(address)

def TurnOnLED(address):
    try:
        r = requests.post('http://' + address + '/LedON')
        r.close()
    except requests.exceptions.ConnectionError:
        pass

#Main
def Main():
    try:
        print("Press CTRL-C to stop.")
        ON = True
        while ON:
            myFunction()
            time.sleep(60)
    except KeyboardInterrupt:
        sys.exit(0)

if __name__ == "__main__":
    Main()

适配Mac的解决方案

方法1:ARP扫描验证(无需修改设备固件)

Mac系统可通过arp -a命令获取本地网络ARP缓存表,提取活跃IP后,通过HTTP请求验证是否为目标ESP8266设备(比如请求专属接口或检查响应特征)。

修改后的完整脚本:

#!/usr/bin/env python
import time
import sys
import socket
import requests
import subprocess
import re

def discover_esp_devices():
    esp_ips = []
    # 执行arp命令获取本地网络设备列表
    result = subprocess.run(['arp', '-a'], capture_output=True, text=True)
    # 正则提取所有IP地址
    ip_pattern = re.compile(r'(\d+\.\d+\.\d+\.\d+)')
    ips = ip_pattern.findall(result.stdout)
    
    # 遍历IP,验证是否为ESP8266设备
    for ip in ips:
        try:
            # 可改为请求专属验证接口(如/device-info),判断响应特征提升准确性
            requests.get(f'http://{ip}/LedON', timeout=1)
            esp_ips.append(ip)
        except (requests.exceptions.ConnectionError, requests.exceptions.Timeout):
            continue
    return esp_ips

def myFunction():
    # 动态发现ESP设备IP
    ipAddresses = discover_esp_devices()
    print(f"Found {len(ipAddresses)} ESP devices: {ipAddresses}")

    for address in ipAddresses:
        TurnOnLED(address)

def TurnOnLED(address):
    try:
        r = requests.post(f'http://{address}/LedON')
        r.close()
    except requests.exceptions.ConnectionError:
        pass

#Main
def Main():
    try:
        print("Press CTRL-C to stop.")
        ON = True
        while ON:
            myFunction()
            time.sleep(60)
    except KeyboardInterrupt:
        sys.exit(0)

if __name__ == "__main__":
    Main()

方法2:UDP广播发现(效率更高,需极小修改设备固件)

在ESP8266固件中添加UDP广播响应逻辑:设备启动后监听指定UDP端口,收到广播指令时回复自身IP。Python端发送广播包并收集响应,可快速获取所有设备IP。

ESP8266固件新增核心代码:

#include <ESP8266WiFi.h>
#include <WiFiUdp.h>

WiFiUDP udp;
const int udpPort = 10000;

void setup() {
  // 原有WiFi初始化代码...
  udp.begin(udpPort);
}

void loop() {
  int packetSize = udp.parsePacket();
  if (packetSize) {
    char packetBuffer[255];
    int len = udp.read(packetBuffer, 255);
    if (len > 0) packetBuffer[len] = 0;
    
    // 识别发现指令并回复IP
    if (strcmp(packetBuffer, "DISCOVER_ESP") == 0) {
      udp.beginPacket(udp.remoteIP(), udp.remotePort());
      udp.print(WiFi.localIP().toString());
      udp.endPacket();
    }
  }
  // 原有loop代码...
}

对应Python发现函数:

def discover_esp_devices_via_udp():
    esp_ips = []
    broadcast_ip = '192.168.1.255'  # 根据你的子网修改
    udp_port = 10000

    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    sock.settimeout(2)
    sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)

    # 发送广播发现指令
    sock.sendto(b"DISCOVER_ESP", (broadcast_ip, udp_port))

    # 收集设备响应
    while True:
        try:
            data, addr = sock.recvfrom(1024)
            esp_ips.append(addr[0])
        except socket.timeout:
            break
    sock.close()
    return list(set(esp_ips))  # 去重

注意事项

  • ARP扫描依赖设备在ARP缓存中存在,刚上线的设备可能无法立即发现,可配合定时扫描
  • UDP广播需确保ESP8266与Mac在同一子网,广播地址需根据实际网络调整
  • 建议在ESP8266固件中添加专属响应标识,避免误识别其他HTTP设备

内容的提问来源于stack exchange,提问作者JeremiahDuane

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 09:05:23