Cho ESP32 công bố toggle, slider, lựa chọn và ô nhập để Waze Mod chỉnh cấu hình bằng transaction Apply/ACK nguyên tử.
Thiết bị HLP/1 có thể tự công bố các cài đặt cho Waze Mod. Android chỉ dựng giao diện, giữ thay đổi ở dạng bản nháp và gửi một transaction nguyên tử khi người dùng bấm Áp dụng trên HUD. Thiết bị vẫn là nguồn dữ liệu chuẩn: tự kiểm tra, lưu bền vững, tăng revision rồi mới xác nhận.
Phần mở rộng này dùng được với cả BLE GATT và Bluetooth Classic SPP, hoàn toàn tùy chọn và
tương thích ngược. Nếu thiết bị không gửi một schema hoàn chỉnh sau hi, phần cài đặt riêng của
thiết bị sẽ để trống.

Kiểm thử trên Redmi K30 (Android 11), kết nối Ubuntu FakeHUD qua BLE GATT. Các control do HUD khai báo; app không định nghĩa sẵn chúng.

Cùng một schema còn có selection, số nguyên và text. Dòng “Đã lưu trên thiết bị” chỉ xuất hiện sau
khi app nhận đúng cfg_ack thành công.
Android ESP32 / HUD
| ----------- hi -----------> |
| <-------- cfg_begin -------- |
| <-------- cfg_item --------- | lặp đúng count lần
| <--------- cfg_end --------- |
| |
| người dùng chỉnh bản nháp |
| |
| ------ cfg_set_begin ------> |
| -------- cfg_set ----------> | một message cho mỗi mục
| ------ cfg_set_commit -----> |
| <---------- cfg_ack -------- | chỉ sau validate + lưu bền vững
hi; caps của app có device_config.cfg_begin, đúng count message cfg_item, rồi cfg_end. Tất
cả phải có cùng rev.rev, rồi gửi cfg_ack.tx. Mỗi lúc chỉ có một transaction
đang chờ và app timeout sau 10 giây.hi. HUD phải công bố schema và giá trị đã lưu hiện tại.
Android cố ý không lưu schema thuộc sở hữu thiết bị.Xem HLP/1 §2.6 để đọc đặc tả wire chính thức.
Mỗi item bắt buộc có v, t:"cfg_item", rev, id, kind, label và value đúng kiểu.
description là tùy chọn.
kind | Kiểu value | Field bổ sung | Ghi chú |
|---|---|---|---|
toggle | boolean | — | Công tắc bật/tắt. |
slider | integer | min, max, step | Giá trị phải trong khoảng và khớp bước. |
selection | string | options:[{value,label}] | Giá trị phải thuộc danh sách option. |
integer | integer | tùy chọn min, max | Ô nhập số có giới hạn. |
text | string | tùy chọn maxLength | UI trim khoảng trắng và giới hạn theo schema. |
Giới hạn an toàn hiện tại:
maxLength lớn hơn;ID là hợp đồng tương thích. Hãy giữ brightness là brightness qua các bản firmware; chỉ dịch
label. Khi thay đổi cấu trúc schema, phải tăng rev.
Mở mã nguồn đầy đủ ngay trong trình xem source của trang tài liệu:
shared/hlp_device_config.hshared/hlp_device_config.cHai file nằm tại docs/examples_for_hud_link/esp32-hlp-spp/shared/. Cả project BLE và SPP mẫu đều
compile chung module này.
Khởi tạo sau NVS:
ESP_ERROR_CHECK(nvs_flash_init());
hlp_device_config_init();
Đưa các dòng HLP hoàn chỉnh qua parser dùng chung. Khi nhận hi, module gọi
hlp_device_config_publish() và phát giá trị đang lưu:
{"v":1,"t":"cfg_begin","rev":7,"count":2,"title":"Cấu hình HUD"}
{"v":1,"t":"cfg_item","rev":7,"id":"brightness","kind":"slider","label":"Độ sáng","value":70,"min":10,"max":100,"step":5}
{"v":1,"t":"cfg_item","rev":7,"id":"theme","kind":"selection","label":"Giao diện","value":"auto","options":[{"value":"auto","label":"Tự động"},{"value":"night","label":"Ban đêm"}]}
{"v":1,"t":"cfg_end","rev":7}
Không xen kẽ hai chuỗi schema. hi có thể lặp khi reconnect hoặc thương lượng lại, vì vậy việc công
bố phải idempotent.
Android gửi toàn bộ form, không phải delta:
{"v":1,"t":"cfg_set_begin","tx":12,"rev":7,"count":2}
{"v":1,"t":"cfg_set","tx":12,"id":"brightness","value":95}
{"v":1,"t":"cfg_set","tx":12,"id":"theme","value":"night"}
{"v":1,"t":"cfg_set_commit","tx":12}
Firmware nên xử lý như sau:
rev cũ, count sai, ID trùng/lạ và giá trị không hợp lệ.cfg_set_begin.cfg_set, chỉ ghi vào staging.{"v":1,"t":"cfg_ack","tx":12,"ok":true,"rev":8}
Nếu lỗi, giữ nguyên active config và trả lý do ngắn:
{"v":1,"t":"cfg_ack","tx":12,"ok":false,"field":"brightness","error":"invalid value"}
Không ACK thành công trước khi lưu bền vững xong. Nếu không, điện thoại có thể báo đã lưu nhưng HUD mất giá trị sau lần khởi động kế tiếp.
Sample có năm field (show_eta, brightness, theme, offset, label) chỉ để demo đủ mọi loại UI.
Với firmware sản phẩm:
device_config_t bằng cấu hình thật của thiết bị.CFG_COUNT và các item trong hlp_device_config_publish().hlp_device_config_handle().Nếu sản phẩm không có cấu hình chỉnh sửa, đừng gửi schema cfg_*. Khu vực cấu hình HUD trong Waze
Mod sẽ tự để trống đúng theo thiết kế.
hi/reconnect.rev và count đồng nhất trên toàn bộ schema.ok:false và không thay active config.Luồng tham chiếu đã được smoke-test ngày 09/08/2026 với Waze Mod V9 Beta 8, Redmi K30 chạy Android 11 và Ubuntu FakeHUD qua BLE GATT:
hi;tx=1, rev=1, count=5);Hai ảnh phía trên được chụp từ chính lần kiểm thử này.