python
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 | import socket import threading import json from flask import Flask from concurrent.futures import ThreadPoolExecutor import time wark_bstate = 0 def handle_device_data(device_id, data): if device_id = = 'class1' : temperature = data.get( 'temperature' ) humidity = data.get( 'humidity' ) print (f "Device 1 - Temperature: {temperature}, Humidity: {humidity}" ) elif device_id = = 'class2' : smoke_level = data.get( 'smoke' ) print (f "Device 2 - Smoke Level: {smoke_level}" ) elif device_id = = 'class3' : light_intensity = data.get( 'light' ) print (f "Device 3 - Light Intensity: {light_intensity}" ) else : print (f "Unknown device ID: {device_id}" ) # 处理客户端连接的函数 def handle_client(client_socket): while True : try : if wark_bstate = = 1 : print ( "TCP服务器client_socket 结束" ) break # 接收数据长度(4字节) data_length_bytes = client_socket.recv( 4 ) if not data_length_bytes: break # 将数据长度转换为整数 data_length = int .from_bytes(data_length_bytes, byteorder = 'big' ) # 接收JSON数据 json_data = client_socket.recv(data_length).decode( 'utf-8' ) if not json_data: break # 解析JSON数据 data = json.loads(json_data) # 判断数据是否存在 if "device_ID" not in data or "sensor_class" not in data : print ( "Error: Incomplete data received" ) continue # 或者根据需求执行其他逻辑 device_id = data.get( "device_ID" ) sensor_class = data.get( "sensor_class" ) # 打印解析结果 print (f "Device ID: {device_id}" ) print (f "Device ID: {sensor_class}" ) handle_device_data(sensor_class,data) except Exception as e: print (f "Error: {e}" ) break # 关闭客户端连接 client_socket.close() # 启动TCP服务器 def start_server(ip, port): server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server.bind((ip, port)) server.listen( 5 ) print (f "Server started on {ip}:{port}" ) # 使用线程池限制最大线程数 with ThreadPoolExecutor(max_workers = 10 ) as executor: while True : if wark_bstate = = 1 : print ( "TCP服务器结束" ) break client_socket, addr = server.accept() print (f "Connection from {addr}" ) # 提交任务到线程池 executor.submit(handle_client, client_socket) # 启动Flask服务器 def start_flask_server(): app = Flask(__name__) @app .route( '/' ) def index(): return "Hello from Flask!" app.run(host = '0.0.0.0' , port = 5000 ) if __name__ = = "__main__" : # 启动TCP服务器的线程 tcp_thread = threading.Thread(target = start_server, args = ( "0.0.0.0" , 8080 )) tcp_thread.daemon = True # 设置为伴随线程 tcp_thread.start() # 启动Flask服务器的线程 flask_thread = threading.Thread(target = start_flask_server) flask_thread.daemon = True # 设置为伴随线程 flask_thread.start() # 主线程等待(实际上它们会一直运行,直到主线程退出) try : while True : time.sleep( 2 ) print ( "主线程..." ) pass except KeyboardInterrupt: wark_bstate = 1 print ( "Main thread interrupted. Exiting..." ) |
可以修改代码 目前只在上电时候 连接一次
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 | #include <Preferences.h> #include <WiFi.h> #include <ArduinoJson.h> #include <DHT.h> String Device_ID = "ESP32_xxx" ; String wifi_name = "love" ; String wifi_pwd = "love123456" ; String sensor_class = "class1" ; / / 定义常量和全局变量 #define DHTPIN 4 // DHT传感器连接的引脚 #define DHTTYPE DHT11 // DHT11传感器类型 DHT dht(DHTPIN, DHTTYPE); Preferences preferences; WiFiClient client; char sever_ip[ 16 ] = "192.168.1.103" ; / / 默认IP地址 int sever_port = 8080 ; / / 默认端口 bool newIPPortReceived = false; / / 标记是否收到新的IP和端口 String deviceID; / / 设备出厂 ID / / 生成设备 ID String generateDeviceID() { / / 生成一个唯一的 ID ,例如基于MAC地址 String mac = WiFi.macAddress(); mac.replace( ":" , ""); Device_ID = "ESP32_" + mac; return Device_ID; } / / 处理AT指令 void processATCommand(String command) { if (command.startsWith( "AT+IP=" )) { String newIP = command.substring( 6 ); newIP.toCharArray(sever_ip, 16 ); preferences.putString( "ip" , newIP); newIPPortReceived = true; Serial.println( "New IP set: " + newIP); } else if (command.startsWith( "AT+PORT=" )) { int newPort = command.substring( 8 ).toInt(); sever_port = newPort; preferences.putInt( "port" , newPort); newIPPortReceived = true; Serial.println( "New Port set: " + String(newPort)); } else if (command.startsWith( "AT+WIFINAME=" )) { String newWIFINAME = command.substring( 12 ); wifi_name = newWIFINAME; preferences.putString( "wifi_name" , newWIFINAME); newIPPortReceived = true; Serial.println( "New WIFINAME set: " + String(newWIFINAME)); } else if (command.startsWith( "AT+WIFIPWD=" )) { String newWIFIPWD = command.substring( 11 ); wifi_pwd = newWIFIPWD; preferences.putString( "wifi_pwd" , newWIFIPWD); newIPPortReceived = true; Serial.println( "New WIFIPWDrt set: " + String(newWIFIPWD)); } else { Serial.println( "Unknown command" ); } } / / 连接TCP服务器 void connectToServer() { if (client.connect(sever_ip, sever_port)) { Serial.println( "Connected to server" ); } else { Serial.println( "Connection failed" ); } } / / 发送温湿度数据 void sendSensorData() { float humidity = dht.readHumidity(); float temperature = dht.readTemperature(); if (isnan(humidity) || isnan(temperature)) { Serial.println( "Failed to read from DHT sensor!" ); return ; } / / 创建JSON对象 StaticJsonDocument< 200 > jsonDoc; jsonDoc[ "device_ID" ] = deviceID; / / 添加设备 ID jsonDoc[ "sensor_class" ] = sensor_class; jsonDoc[ "temperature" ] = temperature; jsonDoc[ "humidity" ] = humidity; String msg = "temperature:" + String(temperature) + " humidity: " + String(humidity); Serial.println(msg); / / 序列化JSON char jsonBuffer[ 200 ]; serializeJson(jsonDoc, jsonBuffer); / / 计算JSON数据长度 int dataLength = strlen(jsonBuffer); / / 发送数据长度( 4 字节) if (client.connected()) { client.write((uint8_t * )&dataLength, sizeof(dataLength)); / / 发送JSON数据 client. print (jsonBuffer); Serial.println( "Data sent: " + String(jsonBuffer)); } else { Serial.println( "Client not connected" ); } / / client.stop(); } / / 初始化设置 void setup() { Serial.begin( 115200 ); dht.begin(); / / 初始化Pr preferences.begin( "wifi-config" , false); / / 从Preferences中读取保存的IP和端口 String savedIP = preferences.getString( "ip" , sever_ip); / / 如果没有该元素则返回默认值 "555" int savedPort = preferences.getInt( "port" , 8080 ); String wifi_name_ = preferences.getString( "wifi_name" , String(wifi_name)); / / 如果没有该元素则返回默认值 "555" String wifi_pwd_ = preferences.getString( "wifi_pwd" , String(wifi_pwd)); savedIP.toCharArray(sever_ip, 16 ); sever_port = savedPort; / / 读取或生成设备 ID deviceID = preferences.getString( "deviceID" , ""); if (deviceID = = "") { deviceID = generateDeviceID(); / / 生成唯一 ID preferences.putString( "deviceID" , deviceID); / / 保存 ID } Serial.println( "Device ID: " + deviceID); Serial.println( "Saved IP: " + String(sever_ip)); Serial.println( "Saved Port: " + String(sever_port)); Serial.println( "Saved wifi_name_: " + String(wifi_name_)); Serial.println( "Saved wifi_pwd_: " + String(wifi_pwd_)); / / 连接WiFi WiFi.begin(wifi_name_.c_str(), wifi_pwd_.c_str()); while (WiFi.status() ! = WL_CONNECTED) { delay( 500 ); Serial. print ( "." ); } Serial.println( "WiFi connected" ); / / 连接TCP服务器 connectToServer(); } / / 主循环 void loop() { / / 检查是否有新的AT指令 if (Serial.available()) { String command = Serial.readStringUntil( '\n' ); processATCommand(command); } / / 如果收到新的IP和端口,重新连接服务器 if (newIPPortReceived) { connectToServer(); newIPPortReceived = false; / / 软件重启 Serial.println( "即将重启..." ); ESP.restart(); } / / 每 2 秒发送一次温湿度数据 static unsigned long lastSendTime = 0 ; if (millis() - lastSendTime > = 2000 ) { sendSensorData(); lastSendTime = millis(); } } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
2022-02-16 VIM3开发(4)项目应用
2022-02-16 VIM3开发(3)系统配置
2022-02-16 VIM3开发(2)系统安装,升级和备份
2022-02-16 VIM3开发(1)资料地址和硬件介绍
2022-02-16 Ubuntu 开启自启动脚本以及带图形界面脚本(imshow())
2022-02-16 Linux Systemd常见命令以及创建开机自启服务