smart-home/tcp_receiver.py
2026-02-26 09:16:34 +08:00

137 lines
5.5 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
TCP接收程序 - 替换UDP接收用于测试ESP32的TCP发送功能
完全保留原有数据解析逻辑,仅替换传输层接口
"""
import socket
import json
import time
from datetime import datetime
def log_message(message):
"""打印带时间戳的日志"""
timestamp = datetime.now().strftime("%H:%M:%S.%f")[:-3]
print(f"[{timestamp}] {message}")
def start_tcp_server():
"""启动TCP服务器接收ESP32发送的数据"""
# 配置和ESP32端一致
TCP_HOST = '0.0.0.0' # 监听所有网卡
TCP_PORT = 8888
BUFFER_SIZE = 1024
# 创建TCP服务器套接字
tcp_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
tcp_server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # 允许端口重用
try:
tcp_server.bind((TCP_HOST, TCP_PORT))
tcp_server.listen(5) # 监听最多5个连接
log_message(f"✅ TCP接收服务器已启动监听端口 {TCP_PORT}")
log_message(f"📡 等待ESP32连接...")
while True:
try:
# 等待ESP32客户端连接
client_conn, client_addr = tcp_server.accept()
log_message(f"🔗 来自 {client_addr} 的连接已建立")
# 处理客户端连接
handle_client(client_conn, client_addr)
except KeyboardInterrupt:
log_message("⏹️ 收到中断信号,正在关闭服务器...")
break
except Exception as e:
log_message(f"⚠️ 接受连接时发生异常:{e}")
time.sleep(1)
except Exception as e:
log_message(f"❌ 启动TCP服务器失败{e}")
finally:
tcp_server.close()
log_message("🔌 TCP服务器已关闭")
def handle_client(client_conn, client_addr):
"""处理单个客户端连接"""
log_message(f"📡 开始处理来自 {client_addr} 的数据...")
try:
while True:
# 接收数据
data = client_conn.recv(1024)
if not data:
log_message(f"❌ 客户端 {client_addr} 连接已断开")
break
# 解析数据复用原有UDP的解析逻辑无需修改
try:
# 尝试解析为JSON热成像状态数据
json_str = data.decode('utf-8')
json_data = json.loads(json_str)
# 提取设备ID
device_id = json_data.get('device_id', '未知设备')
# 提取PIR和Radar状态
pir_status = "有人" if json_data.get('pir', 0) == 1 else "无人"
radar_status = "有人" if json_data.get('radar', 0) == 1 else "无人"
# 提取温度数据16宫格
grid_temps = json_data.get('grid', [])
if len(grid_temps) >= 16:
avg_temp = sum(grid_temps) / len(grid_temps)
log_message(f"📊 [{device_id}] 热成像数据: PIR={pir_status}, Radar={radar_status}, 平均温度={avg_temp:.1f}°C")
log_message(f"🌡️ [{device_id}] 16宫格温度: {[f'{t:.1f}' for t in grid_temps[:4]]}")
else:
log_message(f"📊 [{device_id}] 传感器状态: PIR={pir_status}, Radar={radar_status}")
except json.JSONDecodeError:
# 不是JSON数据可能是二进制热成像数据或AI检测结果
if len(data) == 513: # 热成像分包数据
packet_num = data[0]
log_message(f"🖼️ 热成像数据包 #{packet_num}: {len(data)}字节")
elif len(data) == 17: # AI检测结果数据
packet_num = data[0]
score = data[1]
x, y, w, h = data[2], data[3], data[4], data[5]
cx, cy = data[6], data[7]
heater_on = bool(data[8])
heater_burst = bool(data[9])
danger_temp = bool(data[10])
burning = bool(data[11])
log_message(f"🤖 AI检测结果 #{packet_num}: 人员({score}%@{x},{y},{w}x{h}), 热源({cx},{cy})")
log_message(f"🔥 火灾状态: 加热器={heater_on}, 异常升温={heater_burst}, 危险温度={danger_temp}, 燃烧={burning}")
else:
log_message(f"📦 未知数据格式: {len(data)}字节 - {data.hex()[:32]}...")
except Exception as parse_error:
log_message(f"⚠️ 数据解析异常: {parse_error}")
log_message(f"📦 原始数据: {data.hex()[:64]}...")
except Exception as e:
log_message(f"❌ 处理客户端 {client_addr} 时发生异常:{e}")
finally:
client_conn.close()
log_message(f"🔌 与 {client_addr} 的连接已关闭")
def main():
"""主函数"""
print("=" * 70)
print("🔬 TCP接收程序 - 替换UDP接收测试ESP32 TCP发送功能")
print("📡 完全保留原有数据解析逻辑,仅替换传输层接口")
print("=" * 70)
try:
start_tcp_server()
except KeyboardInterrupt:
log_message("⏹️ 程序被用户中断")
except Exception as e:
log_message(f"💥 程序异常: {str(e)}")
if __name__ == "__main__":
main()