diff --git a/src/main.cpp b/src/main.cpp index 7ad1b68..22bfd20 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -40,9 +40,16 @@ void reconnectMQTT (); // MQTT重连函数 void checkWifiConnection (); // WiFi连接检查函数 void checkMqttConnection (); // MQTT连接检查函数 -bool parseHexJson (String jsonStr); // 解析16进制字符串并返回数据 +// bool parseHexJson (String jsonStr); // 解析16进制字符串并返回数据 bool parseCompactData (const char *data); // 解析紧凑型数据并返回数据 +bool getNanchangWeather (); // 获取天气信息并解析 + +// 天气API配置 +const char *weatherHost = "restapi.amap.com"; +const String API_KEY = "95f833b07d781a2531f5e1516f466515"; // 替换为实际API密钥 +const String LOCATION_ADCODE = "360113"; // 城市代码 + // MQTT相关配置信息 const char *mqtt_broker_addr = "mqtt.lovelyqi.cn"; // 服务器地址 const uint16_t mqtt_broker_port = 1883; // 服务端口号 @@ -75,6 +82,8 @@ setup () mqttClient.setServer (mqtt_broker_addr, mqtt_broker_port); // mqttClient.setBufferSize (mqtt_client_buff_size); mqttClient.setCallback (mqtt_callback); + + getNanchangWeather (); // 获取天气信息并解析 } void @@ -88,7 +97,8 @@ loop () String jsonStr = Serial.readStringUntil ('\n'); if (jsonStr.startsWith ("{")) { - parseHexJson (jsonStr); + // parseHexJson (jsonStr); + parseCompactData (jsonStr.c_str ()); } else { @@ -101,7 +111,7 @@ loop () // 维护MQTT连接 checkMqttConnection (); - // 3. 定时上传数据( xxx ms间隔 ) + // 定时上传数据( xxx ms间隔 ) static unsigned long lastUpload = 0; if (millis () - lastUpload > 500) { @@ -110,6 +120,14 @@ loop () lastUpload = millis (); } + // 定时获取温湿度信息( 5 s间隔 ) + static unsigned long lastGetTemp = 0; + if (millis () - lastGetTemp > 5000) + { + getNanchangWeather (); + lastGetTemp = millis (); + } + // 4. 处理低功耗需求 #ifdef LOW_POWER_MODE ESP.deepSleep (30e6); // 30秒深度睡眠 @@ -256,46 +274,46 @@ hex4ToUint (const char *p) } return val; } -// 输入示例:{"vol":1069,"cur":0037,"pwr":00E7,"tmp":0CA2,"hum":0BF6} -bool -parseHexJson (String jsonStr) -{ - // 键名位置查找(基于固定结构优化) - const char *key_pos[5] = { - strstr (jsonStr.c_str (), "\"vol\":"), // 电压位置 - strstr (jsonStr.c_str (), "\"cur\":"), // 电流位置 - strstr (jsonStr.c_str (), "\"pwr\":"), // 功率位置 - strstr (jsonStr.c_str (), "\"tmp\":"), // 温度位置 - strstr (jsonStr.c_str (), "\"hum\":") // 湿度位置 - }; +// // 输入示例:{"vol":1069,"cur":0037,"pwr":00E7,"tmp":0CA2,"hum":0BF6} +// bool +// parseHexJson (String jsonStr) +// { +// // 键名位置查找(基于固定结构优化) +// const char *key_pos[5] = { +// strstr (jsonStr.c_str (), "\"vol\":"), // 电压位置 +// strstr (jsonStr.c_str (), "\"cur\":"), // 电流位置 +// strstr (jsonStr.c_str (), "\"pwr\":"), // 功率位置 +// strstr (jsonStr.c_str (), "\"tmp\":"), // 温度位置 +// strstr (jsonStr.c_str (), "\"hum\":") // 湿度位置 +// }; - // 校验键名完整性 - for (uint8_t i = 0; i < 5; i++) - { - if (!key_pos[i]) - return false; - key_pos[i] += 5; // 跳过键名部分(如"vol":) - } +// // 校验键名完整性 +// for (uint8_t i = 0; i < 5; i++) +// { +// if (!key_pos[i]) +// return false; +// key_pos[i] += 5; // 跳过键名部分(如"vol":) +// } - // 逐字段解析(固定4字节长度) - sensorData.voltage = hex4ToUint (key_pos[0]) / 100; - Serial.println (key_pos[0]); - Serial.println (hex4ToUint ("109A")); - sensorData.current = hex4ToUint (key_pos[1]) / 100; - sensorData.power = hex4ToUint (key_pos[2]) / 100; - Serial.println (sensorData.power); - sensorData.temp = hex4ToUint (key_pos[3]) / 100; - sensorData.humidity = hex4ToUint (key_pos[4]) / 100; +// // 逐字段解析(固定4字节长度) +// sensorData.voltage = hex4ToUint (key_pos[0]) / 100; +// Serial.println (key_pos[0]); +// Serial.println (hex4ToUint ("109A")); +// sensorData.current = hex4ToUint (key_pos[1]) / 100; +// sensorData.power = hex4ToUint (key_pos[2]) / 100; +// Serial.println (sensorData.power); +// sensorData.temp = hex4ToUint (key_pos[3]) / 100; +// sensorData.humidity = hex4ToUint (key_pos[4]) / 100; - return true; -} +// return true; +// } // 接收端解析函数(返回解析成功状态) bool parseCompactData (const char *data) { // 格式验证(长度26字节:{xxxx,xxxx,xxxx,xxxx,xxxx}) - if ( data[0] != '{' || data[25] != '}') + if (data[0] != '{' || data[25] != '}') { Serial.println ("Failed to parse data, invalid format."); return false; @@ -333,14 +351,84 @@ parseCompactData (const char *data) sensorData.voltage = params[0] / 100.0f; sensorData.current = params[1] / 100.0f; sensorData.power = params[2] / 100.0f; - sensorData.temp = params[3] / 100.0f; - sensorData.humidity = params[4] / 100.0f; + // sensorData.temp = params[3] / 100.0f; + // sensorData.humidity = params[4] / 100.0f; - Serial.println (sensorData.voltage); - Serial.println (sensorData.current); - Serial.println (sensorData.power); - Serial.println (sensorData.temp); - Serial.println (sensorData.humidity); + // Serial.println (sensorData.voltage); + // Serial.println (sensorData.current); + // Serial.println (sensorData.power); + // Serial.println (sensorData.temp); + // Serial.println (sensorData.humidity); + return true; +} + +// 封装函数:获取南昌温湿度 +bool +getNanchangWeather () +{ + WiFiClient client; + const int httpPort = 80; + + if (!client.connect (weatherHost, httpPort)) + { + Serial.println ("Connection failed"); + return false; + } + + // 构建API请求URL + String url = "/v3/weather/weatherInfo?key=" + API_KEY + + "&city=" + LOCATION_ADCODE + "&extensions=base"; + + // 发送HTTP请求 + client.print (String ("GET ") + url + " HTTP/1.1\r\n" + "Host: " + + weatherHost + "\r\n" + "Connection: close\r\n\r\n"); + + // 等待响应 + unsigned long timeout = millis (); + while (client.available () == 0) + { + if (millis () - timeout > 500) + { + client.stop (); + return false; + } + } + + // 读取HTTP响应头 + while (client.available ()) + { + String line = client.readStringUntil ('\n'); + if (line == "\r") + { + break; + } + } + + // client.readStringUntil ('{'); + // String src = client.readStringUntil ('}'); + // Serial.println (src); + + // 解析JSON数据 + DynamicJsonDocument doc (1024); + DeserializationError error = deserializeJson (doc, client); + if (error) + { + Serial.print ("JSON解析失败: "); + Serial.println (error.c_str ()); + return false; + } + + // 提取温湿度数据 + JsonObject results_0 = doc["lives"][0]; + + + sensorData.temp = results_0["temperature_float"]; + sensorData.humidity = results_0["humidity_float"]; + + // Serial.print ("温度: " + String (sensorData.temp) + "°C"); + // Serial.println ("湿度: " + String (sensorData.humidity) + "%"); + + client.stop (); return true; } \ No newline at end of file