Ứng dụng web PWA điều khiển màn hình E-Ink thương hiệu DLG qua Bluetooth BLE, hỗ trợ hai chế độ: trực tiếp (Web Bluetooth API) và gateway (cầu BLE↔WiFi qua ESP32-C3). Được cải tiến và mở rộng từ epd.eled.top/213/.
| Tab | Chức năng |
|---|---|
| Cài Đặt | Kết nối BLE, đặt giờ, chọn chế độ hiển thị (đồng hồ/lịch), đảo màu, xoay, chế độ ngủ, số hiển thị bãi đỗ |
| Đếm Ngược | Chọn ngày đích, tùy chỉnh văn bản & font chữ (hỗ trợ font châu Á), kích thước font, xem trước canvas |
| Truyền Ảnh | Upload ảnh, chọn kích thước màn hình (2.13"/2.9"/4.2"/7.5"), thuật toán dithering (BWR/Floyd-Steinberg/Atkinson/Bayer/Stucki/Jarvis), điều chỉnh độ sáng/tương phản/bão hòa |
| Thiết Kế | Trình chỉnh sửa canvas với các phần tử: ảnh, text, hình chữ nhật, tròn, tam giác, đường thẳng, ngôi sao, mã QR, icon Material |
- Cầu BLE↔WiFi: Điều khiển màn hình E-Ink từ xa qua trình duyệt, không cần Bluetooth trên máy tính/điện thoại
- WiFi Manager: Tự động tạo AP "E-Ink Gateway" để cấu hình WiFi qua captive portal
- Đồng bộ NTP: Tự động đồng bộ thời gian từ Internet cho màn hình E-Ink
- Lập lịch (Scheduler): Lên lịch đồng bộ giờ, làm mới màn hình, hoặc chuyển chế độ theo cron
- Quản lý thiết bị: Lưu danh sách thiết bị BLE đã kết nối
- OTA Update: Cập nhật firmware qua WiFi (ArduinoOTA port 3232, password
eink+ HTTP upload/api/system/ota) - SSE Real-time: Phát trạng thái kết nối, sysinfo, log qua Server-Sent Events
Chế độ 1 (Trực tiếp):
[Trình duyệt] ──Web Bluetooth API──▶ [Màn hình E-Ink DLG]
Chế độ 2 (Gateway):
[Trình duyệt] ──HTTP/REST──▶ [ESP32-C3 Gateway] ──BLE──▶ [Màn hình E-Ink DLG]
│
├── NTP time sync
├── Scheduler (cron)
└── SSE real-time
webapp/
├── index.html # PWA entry point (giao diện tiếng Việt)
├── manifest.json # PWA manifest
├── sw.js # Service Worker (cache-first)
├── server.js # Node.js static file server (không dependencies)
├── Dockerfile # Docker image (node:22-alpine)
├── docker-compose.yml # Deploy với Docker Compose
├── css/
│ └── style.css # Material Design 3 (CSS variables)
├── js/
│ └── app.js # Toàn bộ logic frontend (Web Bluetooth, dithering, canvas editor)
├── icons/
│ ├── icon-192.svg
│ └── icon-512.svg
├── docs/
│ └── ble-api-guide.md # Tài liệu BLE API chi tiết (tiếng Việt)
└── esp32-ble-gateway/ # Firmware ESP32-C3 (PlatformIO)
├── platformio.ini # Cấu hình build: esp32-c3-devkitm-1, Arduino
├── partition.csv # Phân vùng OTA (4MB, 2 app slots)
├── scripts/
│ └── build_webapp.py # Gzip webapp → PROGMEM C arrays
├── src/
│ ├── main.cpp # Entry point: WiFiManager, OTA, wiring
│ ├── ble_gateway.* # BLE client: scan, connect, gửi lệnh/ảnh
│ ├── web_server.* # REST API + SSE + static files từ PROGMEM
│ ├── ntp_time.* # NTP sync + POSIX timezone mapping
│ ├── scheduler.* # Lập lịch cron (time-sync, refresh, clock-mode)
│ ├── storage.* # NVS Preferences wrapper
│ └── webapp.h # Tự sinh: file webapp đã nén Gzip (PROGMEM)
└── webapp/ # Bản sao frontend để nhúng vào firmware
├── index.html
├── css/style.css
├── js/app.js
├── js/api.js # REST API client cho ESP32 gateway
├── icons/
└── manifest.json
Bản web là ứng dụng PWA tĩnh (HTML/CSS/JS thuần). Có 3 cách deploy:
Yêu cầu: Docker & Docker Compose
# Clone repository
git clone <repo-url> eink-webapp
cd eink-webapp
# Build & chạy
docker compose up -d
# Hoặc build thủ công:
docker build -t eink-webapp .
docker run -d -p 3000:3000 --name eink-webapp --restart unless-stopped eink-webappỨng dụng chạy tại http://localhost:3000.
Deploy với registry riêng:
# Linux/macOS
export REGISTRY=your-registry.example.com
./build-and-push.sh v1.0.0
# Windows PowerShell
$env:REGISTRY='your-registry.example.com'
.\build-and-push.ps1 v1.0.0Sau đó cập nhật docker-compose.yml:
services:
eink-webapp:
image: your-registry.example.com/eink-webapp:latest
# ...Yêu cầu: Node.js ≥ 18
node server.js
# → http://localhost:3000server.js chỉ dùng Node built-in (http, fs, path) — không cần npm install.
Chép toàn bộ file tĩnh lên web server:
index.html, manifest.json, sw.js
css/style.css
js/app.js
icons/icon-192.svg, icons/icon-512.svg
Cấu hình Nginx ví dụ:
server {
listen 80;
server_name eink.example.com;
root /var/www/eink-webapp;
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
# Cache tĩnh 30 ngày cho assets có version hash
location ~* \.(js|css|svg|png|jpg|webp|ico)$ {
expires 30d;
add_header Cache-Control "public, immutable";
}
}⚠ Lưu ý bảo mật: Web Bluetooth API chỉ hoạt động trên HTTPS hoặc
localhost. Khi deploy production, phải dùng HTTPS (qua reverse proxy với SSL, hoặc CDN có HTTPS).
- ESP32-C3 (khuyến nghị: devkitm-1, 4MB Flash)
- Màn hình E-Ink DLG hỗ trợ BLE
- PlatformIO IDE (VS Code extension) hoặc PlatformIO Core CLI
- Python 3 (cho script
build_webapp.py) - Trình điều khiển USB CDC cho ESP32-C3
Trước khi build firmware, cần sinh file webapp.h từ thư mục webapp/:
cd esp32-ble-gateway
python scripts/build_webapp.pyScript này sẽ:
- Nén tất cả file trong
webapp/bằng Gzip (level 9) - Sinh
src/webapp.hchứa các mảnguint8_tđã nén dạng PROGMEM
Dùng VS Code + PlatformIO:
- Mở thư mục
esp32-ble-gateway/trong VS Code - Kết nối ESP32-C3 qua USB
- Nhấn PlatformIO: Build (✓) để build
- Nhấn PlatformIO: Upload (→) để flash
Dùng PlatformIO Core CLI:
cd esp32-ble-gateway
# Build
pio run
# Flash (thay COM_PORT bằng cổng thực tế)
pio run --target upload --upload-port /dev/ttyUSB0
# Monitor serial
pio device monitor --port /dev/ttyUSB0 --baud 115200- ESP32-C3 khởi động sẽ tạo AP "E-Ink Gateway" (mật khẩu: không có)
- Kết nối vào AP đó, captive portal sẽ tự mở (hoặc truy cập
http://192.168.4.1) - Chọn WiFi nhà, nhập mật khẩu
- (Tùy chọn) Cấu hình Timezone — mặc định
UTC+7(Việt Nam) - ESP32-C3 sẽ kết nối WiFi và sẵn sàng hoạt động
Sau khi kết nối WiFi, mở trình duyệt truy cập địa chỉ IP của ESP32-C3 (có thể xem trong serial monitor hoặc router DHCP).
Web app hiển thị giống hệt bản web online, nhưng giao tiếp qua REST API (/api/ble/*) thay vì Web Bluetooth trực tiếp.
Qua Arduino IDE / PlatformIO:
- Port: 3232
- Hostname:
eink-gateway - Password:
eink
Qua Web API:
curl -X POST http://<esp32-ip>/api/system/ota \
--data-binary @firmware.binLưu ý: Khi OTA thành công, ESP32-C3 tự động reboot vào firmware mới. Phân vùng OTA (app0/app1) đảm bảo rollback an toàn nếu firmware mới lỗi.
| Method | Path | Mô tả |
|---|---|---|
| GET | /api/ble/status |
Trạng thái kết nối BLE |
| POST | /api/ble/scan |
Quét thiết bị BLE |
| POST | /api/ble/connect |
Kết nối thiết bị BLE |
| POST | /api/ble/send |
Gửi lệnh/ảnh |
| GET | /api/time |
Lấy thời gian hiện tại |
| POST | /api/time/sync |
Đồng bộ giờ |
| POST | /api/time/timezone |
Đặt timezone |
| POST | /api/time/ntp-toggle |
Bật/tắt NTP |
| GET/POST | /api/schedules |
Quản lý lịch |
| GET/POST | /api/devices |
Quản lý thiết bị đã lưu |
| GET | /api/system |
Thông tin hệ thống (WiFi, uptime, heap) |
| POST | /api/system/reboot |
Khởi động lại |
| POST | /api/system/wifi-reset |
Xóa WiFi + reboot |
| POST | /api/system/ota |
Cập nhật firmware |
| GET | /api/events |
SSE real-time events |
- Trình duyệt hỗ trợ Web Bluetooth: Chỉ Chromium-based (Chrome, Edge, Opera). Firefox/Safari không hỗ trợ.
- HTTPS bắt buộc để dùng Web Bluetooth API ở chế độ trực tiếp (ngoại trừ localhost).
- Service Worker:
sw.jscache-first cho CSS/JS/icons, network-first cho HTML — đảm bảo PWA hoạt động offline với nội dung mới nhất. - ESP32-C3 Gateway tự động quét thiết bị BLE có prefix
DLGvà hỗ trợ auto-reconnect khi mất kết nối. - Scheduler dùng 5-field cron (phút/giờ/ngày/tháng/thứ) — tham khảo
esp32-ble-gateway/src/scheduler.cppđể biết thêm chi tiết.
- Dự án gốc: epd.eled.top/213/
- Web Bluetooth API: developer.mozilla.org/en-US/docs/Web/API/Web_Bluetooth_API
- PlatformIO: platformio.org
- Tài liệu BLE API: docs/ble-api-guide.md