Release RC1.0.5

This commit is contained in:
clear committed 2026-05-08 13:52:26 +08:00
1 parent d0ac50ecc7
commit 97c43d282c
3 files changed
+68 -11

No files matched your search

Binary file not shown.
+7 -9
View File
@@ -4,7 +4,7 @@
ClearESP WindSensors 是基于 `ESP32-C3` 的 RS485 风速风向传感器采集网关固件,面向现场部署、批量站号配置、Web 运维和 MQTT 上报场景。
当前固件版本:`RC1.0.4`
当前固件版本:`RC1.0.5`
## 主要功能
@@ -209,7 +209,7 @@ AP 名称格式:
```json
{
"mac": "B43A455471D4",
"firmware_version": "RC1.0.4",
"firmware_version": "RC1.0.5",
"uptime_ms": 123456,
"sensors": [
{
@@ -241,11 +241,9 @@ platformio run
platformio run -t upload
```
## RC1.0.4 变更
## RC1.0.5 变更
- MQTT 仅保留 `/realtime` 上报与页面展示
- 系统状态页显示固件版本
- 云服务页 OTA 卡片改为现场可用的检查更新 / 下载升级流程
- OTA 页面不再向用户展示项目地址或固件直链
- 补齐 OTA 检查与升级接口
- 修正文档中文乱码并同步更新说明
- 修正 OTA 检查接口地址错误,解决检查更新返回 `HTTP 404`
- 云服务页将 OTA 卡片调整到最顶部,与 MQTT 区域分开显示
- OTA 最新版本展示统一按 `RCx.y.z` 风格显示
- 同步更新版本说明与文档
+61 -2
View File
@@ -30,8 +30,10 @@ constexpr uint32_t MODBUS_RESPONSE_TIMEOUT_MS = 500;
constexpr uint32_t WIFI_RETRY_INTERVAL_MS = 15000;
constexpr uint32_t WIFI_CONNECT_TIMEOUT_MS = 20000;
constexpr bool ENABLE_BOOT_DIAGNOSTICS = false;
constexpr char FIRMWARE_VERSION[] = "RC1.0.4";
constexpr char FIRMWARE_VERSION[] = "RC1.0.5";
constexpr char OTA_PROJECT_URL[] = "http://107.173.157.41:3000/clear/wind_vt_esp32";
constexpr char OTA_LATEST_RELEASE_API_URL[] =
"http://107.173.157.41:3000/api/v1/repos/clear/wind_vt_esp32/releases/latest";
constexpr uint16_t MQTT_DEFAULT_PORT = 1883;
constexpr uint32_t MQTT_RETRY_INTERVAL_MS = 10000;
constexpr uint32_t MQTT_PUBLISH_INTERVAL_MS = 1000;
@@ -598,6 +600,16 @@ const char WEB_PAGE[] PROGMEM = R"HTML(
<section id="page-cloud" class="panel page">
<h2>&#20113;&#26381;&#21153;</h2>
<div class="stack">
<div class="api-card">
<div class="label">OTA</div>
<div class="subtext" id="otaIntro">OTA 需要设备先连接外部 WiFi。检测到新版本后,可直接下载并升级。</div>
<div class="subtext" id="otaSummary">当前固件版本 -- | 最新版本 --</div>
<div class="subtext" id="otaStatusText" style="color:#cfe7de;">--</div>
<div class="actions">
<button id="btnOtaCheck" class="action ghost" onclick="checkOtaUpdate()">检查更新</button>
<button id="btnOtaUpdate" class="action" onclick="startOtaUpdate()">下载并升级</button>
</div>
</div>
<div class="subtext">
&#37197;&#32622; MQTT &#26381;&#21153;&#22120;&#21518;&#65292;&#35774;&#22791;&#20250;&#33258;&#21160;&#36830;&#25509;&#24182;&#19978;&#25253;&#20256;&#24863;&#22120;&#21015;&#34920;&#19982;&#23454;&#26102;&#25968;&#25454;&#12290;&#19978;&#25253;&#20869;&#23481;&#20250;&#24102;&#19978;&#35774;&#22791; MAC&#65292;&#29992;&#20110;&#21306;&#20998;&#35774;&#22791;&#36523;&#20221;&#12290;
</div>
@@ -990,10 +1002,57 @@ const char WEB_PAGE[] PROGMEM = R"HTML(
}
}
function cleanupDuplicateOtaNodes() {
const duplicatedIds = ['otaSummary', 'otaStatusText', 'btnOtaCheck', 'btnOtaUpdate'];
duplicatedIds.forEach((id) => {
const nodes = document.querySelectorAll(`[id="${id}"]`);
nodes.forEach((node, index) => {
if (index > 0) {
const card = node.closest('.api-card');
if (card) {
card.remove();
} else {
node.remove();
}
}
});
});
}
function renderOtaPanel(data) {
const intro = document.getElementById('otaIntro');
const summary = document.getElementById('otaSummary');
const status = document.getElementById('otaStatusText');
const btnCheck = document.getElementById('btnOtaCheck');
const btnUpdate = document.getElementById('btnOtaUpdate');
const latestVersion = data.otaLatestVersion
? (data.otaLatestVersion.startsWith('v') ? `RC${data.otaLatestVersion.slice(1)}` : data.otaLatestVersion)
: '--';
if (intro) {
intro.textContent = 'OTA 需要设备先连接外部 WiFi。检测到新版本后,可直接下载并升级。';
}
if (summary) {
summary.textContent = `当前固件版本 ${data.firmwareVersion} | 最新版本 ${latestVersion}`;
}
if (status) {
status.textContent = data.otaStatus || '--';
}
if (btnCheck) {
btnCheck.disabled = busy;
btnCheck.textContent = '检查更新';
}
if (btnUpdate) {
btnUpdate.disabled = busy || !data.otaUpdateAvailable;
btnUpdate.textContent = '下载并升级';
}
}
document.addEventListener('visibilitychange', () => {
scheduleRefresh(document.hidden ? 1200 : 100);
});
document.addEventListener('DOMContentLoaded', () => {
cleanupDuplicateOtaNodes();
const ssidInput = document.getElementById('wifiSsid');
const passInput = document.getElementById('wifiPass');
[ssidInput, passInput].forEach((input) => {
@@ -1610,7 +1669,7 @@ bool fetchLatestOtaRelease(String &latestTag, String &latestBin, String &error)
HTTPClient http;
WiFiClient client;
const String url = String(OTA_PROJECT_URL) + "/api/v1/repos/clear/wind_vt_esp32/releases/latest";
const String url = OTA_LATEST_RELEASE_API_URL;
if (!http.begin(client, url)) {
error = "无法建立 OTA 检查连接";
return false;