update IP footer
This commit is contained in:
@@ -116,6 +116,8 @@ Sau khi đã có cấu hình:
|
|||||||
| **2 – Model** | Top 6 model: requests, tokens, failed |
|
| **2 – Model** | Top 6 model: requests, tokens, failed |
|
||||||
| **3 – Hourly** | 6 giờ gần nhất: requests, tokens |
|
| **3 – Hourly** | 6 giờ gần nhất: requests, tokens |
|
||||||
|
|
||||||
|
- **Footer màn hình** (dưới cùng, trang nào cũng có):
|
||||||
|
- Hiển thị: `Config: http://<IP_ESP32>` – truy cập địa chỉ này để đổi API URL / WiFi mà không cần reset
|
||||||
- **Đèn RGB onboard (GPIO 48)**:
|
- **Đèn RGB onboard (GPIO 48)**:
|
||||||
- 🔵 **Xanh dương** = fetch dữ liệu thành công
|
- 🔵 **Xanh dương** = fetch dữ liệu thành công
|
||||||
- 🟢 **Xanh lá** = chuyển trang hiển thị
|
- 🟢 **Xanh lá** = chuyển trang hiển thị
|
||||||
@@ -123,6 +125,18 @@ Sau khi đã có cấu hình:
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## 🔄 Cập nhật API URL không cần restart
|
||||||
|
|
||||||
|
Khi bạn đổi API URL trên trang Config (`http://<IP_ESP32>` → "Cập nhật API URL"):
|
||||||
|
|
||||||
|
1. ESP32 lưu URL mới vào Preferences (bộ nhớ không bay hơi)
|
||||||
|
2. ESP32 **fetch dữ liệu mới ngay lập tức** (không cần chờ 60s hay restart)
|
||||||
|
3. Màn hình cập nhật với dữ liệu từ API URL mới
|
||||||
|
|
||||||
|
> Trước đây phải restart thủ công để có URL mới. Giờ đã tự động.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## 🔧 Troubleshooting
|
## 🔧 Troubleshooting
|
||||||
|
|
||||||
| Vấn đề | Nguyên nhân / Khắc phục |
|
| Vấn đề | Nguyên nhân / Khắc phục |
|
||||||
|
|||||||
@@ -74,6 +74,7 @@ int g_hourCount = 0;
|
|||||||
// ── State flags ───────────────────────────────────
|
// ── State flags ───────────────────────────────────
|
||||||
volatile bool g_dataReady = false;
|
volatile bool g_dataReady = false;
|
||||||
volatile bool g_apMode = false;
|
volatile bool g_apMode = false;
|
||||||
|
volatile bool g_fetchNow = false; // flag yêu cầu fetch ngay
|
||||||
int g_page = 0;
|
int g_page = 0;
|
||||||
#define TOTAL_PAGES 4
|
#define TOTAL_PAGES 4
|
||||||
|
|
||||||
@@ -207,6 +208,17 @@ void tft_showFetchError() {
|
|||||||
tftUnlock();
|
tftUnlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ── Footer hiển thị IP để truy cập trang Config ──
|
||||||
|
void drawFooter() {
|
||||||
|
// Vẽ thanh footer ở 16px dưới cùng
|
||||||
|
tft.drawFastHLine(0, SCREEN_HEIGHT-17, SCREEN_WIDTH, COLOR_HEADER);
|
||||||
|
tft.setTextSize(1); tft.setTextColor(COLOR_CYAN);
|
||||||
|
tft.setCursor(6, SCREEN_HEIGHT-13);
|
||||||
|
tft.print("Config: http://");
|
||||||
|
tft.setTextColor(COLOR_ORANGE);
|
||||||
|
tft.print(WiFi.localIP().toString());
|
||||||
|
}
|
||||||
|
|
||||||
// ── Vẽ 4 trang dữ liệu ───────────────────────────
|
// ── Vẽ 4 trang dữ liệu ───────────────────────────
|
||||||
void drawPage0() {
|
void drawPage0() {
|
||||||
// Tổng quan
|
// Tổng quan
|
||||||
@@ -318,6 +330,9 @@ void drawCurrentPage() {
|
|||||||
case 2: drawPage2(); break;
|
case 2: drawPage2(); break;
|
||||||
case 3: drawPage3(); break;
|
case 3: drawPage3(); break;
|
||||||
}
|
}
|
||||||
|
if (!g_apMode) {
|
||||||
|
drawFooter();
|
||||||
|
}
|
||||||
tftUnlock();
|
tftUnlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -544,7 +559,8 @@ void handleSave() {
|
|||||||
void handleUpdate() {
|
void handleUpdate() {
|
||||||
if (server.hasArg("api")) strncpy(g_api_url, server.arg("api").c_str(), sizeof(g_api_url)-1);
|
if (server.hasArg("api")) strncpy(g_api_url, server.arg("api").c_str(), sizeof(g_api_url)-1);
|
||||||
savePrefs();
|
savePrefs();
|
||||||
server.send(200, "text/plain", "API URL da cap nhat!");
|
g_fetchNow = true; // yêu cầu fetch ngay với API URL mới
|
||||||
|
server.send(200, "text/plain", "API URL da cap nhat! Dang lay du lieu moi...");
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleReset() {
|
void handleReset() {
|
||||||
@@ -595,7 +611,13 @@ void fetch_task(void* pv) {
|
|||||||
tft_showFetchError();
|
tft_showFetchError();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
vTaskDelay(60000 / portTICK_PERIOD_MS);
|
// Nếu có yêu cầu fetch ngay (sau khi đổi API URL), không delay 60s
|
||||||
|
if (g_fetchNow) {
|
||||||
|
g_fetchNow = false;
|
||||||
|
vTaskDelay(500 / portTICK_PERIOD_MS); // đợi ngắn rồi fetch tiếp
|
||||||
|
} else {
|
||||||
|
vTaskDelay(60000 / portTICK_PERIOD_MS);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user