Waze ModWaze Mod
ESP32Tính năngẢnh thực tếTải xuốngCài đặtChangelogLưu ýFAQỦng hộ
Download

Waze Mod

Dành cho tài xế Việt Nam.

© 2026 Waze Mod. Waze Mod Extended không liên kết chính thức với Waze hoặc Google.

Hướng dẫn cài đặtFAQAdmin
Developer docsESP32 · HLP/1

Tự build HUD.Waze lo dữ liệu.

Nhận tốc độ, giới hạn, hướng rẽ, ETA và cảnh báo trực tiếp trên ESP32 qua Bluetooth Classic hoặc BLE—không cần build lại Waze.

512 B

frame tối đa

≤ 4 Hz

BLE update

1 s

heartbeat

3 s

HUD báo mất tín hiệu

Serial monitorLIVE

$ idf.py -p COM5 monitor

{"v":1,"t":"s","nav":1,"spd":47,"lim":50,"trn":3,"dst":120}

SPP / BLEJSON LinesESP-IDF
Tổng quanĐổi trang ↓
Tổng quanESP32 BLEClassic SPPVí dụ BLEVí dụ SPPHLP/1 protocolCấu hình thiết bịDuy trì kết nốiPhía AndroidPhần cứngXử lý lỗiKiểm thử

Pin map / tài liệu

Bắt đầu

Tổng quan

Kết nối

ESP32 BLEClassic SPP

Code mẫu

Ví dụ BLEVí dụ SPP

Giao thức

HLP/1 protocolCấu hình thiết bịDuy trì kết nối

Tham chiếu

Phía AndroidPhần cứngXử lý lỗiKiểm thử
ESP32HLP/1README.md

Bắt đầu với Waze HUD Link

Kiến trúc, luồng dữ liệu và sketch tối thiểu để ESP32 nhận trạng thái điều hướng từ Waze.

Tải trang Markdown.MDTải bộ tài liệu cho AIDOCS + SOURCE

1. Là gì

HudLink là bộ producer nằm trong mod Waze (com.waze.gw.HudLink). Nó gom trạng thái HUD trực tiếp — tốc độ, giới hạn tốc độ, hướng rẽ kế, khoảng cách, đường hiện tại/kế, ETA, vùng đo tốc độ trung bình — thành JSON mỗi dòng (giao thức HLP/1) rồi đẩy qua một transport tới HUD ngoài. App hiện hỗ trợ Bluetooth Classic SPP và BLE GATT bằng cùng frame HLP/1.

Vì dữ liệu tách rời khỏi việc vẽ, bạn chế HUD tùy ý mà không phải build lại Waze. Nó còn tiếp tục đẩy dữ liệu kể cả khi màn điện thoại TẮT → dùng HUD ngoài cho phép tắt/giảm màn (mát hơn, đỡ pin).

2. Kiến trúc

HLP / source
Tiến trình Waze ──(hook smali)──► trạng thái Gateway.hud*
                                       │
                                       ▼
                      HudLinkService + HudConnectionManager
                                       │  snapshot HLP/1
                          ┌────────────┴────────────┐
                          ▼                         ▼
                BLE GATT (1–4 Hz)        Classic SPP (1–10 Hz)
                          │                         │
                          └──────────► HUD ngoài ◄──────────┘
  • Foreground service HudLinkService sở hữu transport, handshake, writer và vòng kết nối lại. Hook nóng onSpeedo chỉ gửi yêu cầu khôi phục service theo cách idempotent và có giới hạn nhịp khi Android tạo lại process Waze.
  • HudStateSnapshot đọc các field Gateway.hud* và phát snapshot đầy đủ mỗi message (không phải delta), nên mất một gói không làm hỏng trạng thái bên nhận.
  • Phát khi có thay đổi và vẫn phát state không đổi ít nhất mỗi giây. BLE được giới hạn trong 1–4 Hz; Classic SPP mặc định 8 Hz và nhận yêu cầu tối đa 10 Hz.

3. Bật lên

Preferences (file SharedPreferences waze_hud_gw):

keykiểumặc địnhý nghĩa
hud_linkboolfalsebật service HUD Link
hud_link_logboolfalselog payload HLP RX/TX đã kết nối dưới tag WazeHudLink
hud_link_transportint00 tự động, 1 Classic SPP, 2 BLE GATT
hud_link_device_addressstrrỗngđịa chỉ Bluetooth chính xác đã chọn
hud_link_device_namestrrỗngtên hiển thị của thiết bị đã chọn
hud_link_device_transportintkhông cótransport lưu cùng thiết bị; picker đồng thời mirror sang hud_link_transport

Mở Cài đặt Mod → Thiết bị → HUD Link, cấp quyền Thiết bị lân cận khi được hỏi, chọn đúng transport/thiết bị rồi bật HUD Link. Thiết bị Classic phải được pair trong Cài đặt Android trước; thiết bị BLE được tìm trong picker của app theo HLP service UUID cố định.

Bật log không tạo transport giả, nên không thể phát stream nếu chưa kết nối thiết bị. Khi chẩn đoán với thiết bị thật, chỉ bật hud_link_log tạm thời rồi xem:

HLP / source
adb logcat -s WazeHudLink WazeHudLink-BLE
# {"v":1,"t":"s","nav":0,"spd":47,"lim":50,...,"st":"Nguyễn Trãi","ts":124890}

Preference cũ hud_link_dev chỉ dùng để migrate. App chỉ chuyển nó thành một thiết bị bonded cụ thể khi tìm được đúng một kết quả không mơ hồ.

4. Luồng dữ liệu (HLP/1)

Mỗi dòng là 1 object JSON, UTF-8, kết bằng \n. Mọi message: {"v":1,"t":"...", ...}. Xem HLP_v1.md cho spec đầy đủ (handshake dev/hi, thương lượng năng lực, versioning).

Message trạng thái ("t":"s") — các field HUD cần:

keyđơn vị / khoảngý nghĩa
nav0/1đang dẫn đường theo tuyến
spdkm/htốc độ hiện tại
limkm/h, 0 = không cógiới hạn tốc độ
over0/1đang vượt tốc (quá ngưỡng của mod)
trnenum rẽ §4.1hướng rẽ kế tiếp
trn2enum rẽ §4.1hướng rẽ sau đó ("rồi…")
dstmét, -1 = không cókhoảng cách tới hướng rẽ kế
exit≥0số lối ra ở vòng xuyến
stchuỗiđường hiện tại (đang đi)
st2chuỗiđường kế tiếp (rẽ vào)
eta"HH:MM"giờ đến dự kiến
rminphútthời gian còn lại
rkmkm (1 chữ số)quãng đường còn lại
avg0/1đang trong vùng cấm vượt (VN — xem note)
avgL/avgR/avgPm / km/h / %vùng: còn lại / tốc độ khuyến nghị / phần trăm
alrenum alert §4.2biển/cảnh báo gần nhất (0 = không)
alrDmét, -1 = không cókhoảng cách tới biển gần nhất
alrVkm/hgiá trị của biển gần nhất (giới hạn sắp tới cho biển giảm tốc)
alrsmảngtối đa 4 biển kế [{k,d,v}], gần→xa (opt-in)
tsmsuptime producer (kiểm cũ/mới, thứ tự)

Quy ước vắng: 0 cho lim/exit/avg*; -1 cho dst. alrV/alrs omit hẳn khi không có. Thiếu key ⇒ dùng giá trị mặc định.

Vùng cấm vượt (avg). VN không có camera đo tốc độ trung bình; editor tag hình học đó thành cấm vượt, Waze vẫn giao dưới dạng "avg-speed zone". Hiện biển cấm vượt + đếm ngược avgL, đừng vẽ camera. / Vietnam has no average-speed cameras; render a no-passing sign, not a camera.

Cảnh báo (alr/alrs). Khi có cảnh báo, alr/alrD/alrV mô tả biển gần nhất và mirror alrs[0] (consumer không parse mảng vẫn có biển gần nhất). alrs = danh sách đầy đủ (≤4, gần→xa), opt-in — phải khai alrs trong dev.want.fields mới nhận. Trong alrs, key loại là k (không phải t — t là key loại-message ở envelope): [{"k":2,"d":300},{"k":8,"d":800,"v":40}]. alrV/v chỉ có với biển mang giá trị (giảm tốc → giới hạn mới); còn lại omit. Enum alert: 1 police · 2 camera tốc · 3 camera đèn đỏ · 4 hazard · 5 tai nạn · 6 kẹt xe · 7 đóng đường · 8 giảm tốc (v=giới hạn mới) · 9 cấm vượt.

Enum rẽ (trn,trn2): 0 không · 1 đi thẳng · 2 trái · 3 phải · 4/5 chếch trái/phải · 6/7 gắt trái/phải · 8 quay đầu · 10-12 vòng xuyến / trái / phải (dùng exit) · 13/14 giữ trái/phải · 15/16 ra nhánh trái/phải · 17 đến nơi. (Bảng đầy đủ ở HLP_v1.md §4.1.)

5. Viết bên nhận (ESP32, Bluetooth SPP)

Sketch Arduino tối thiểu — đọc dòng, parse, vẽ:

HLP / source
#include "BluetoothSerial.h"
#include <ArduinoJson.h>

BluetoothSerial SerialBT;

void setup() {
  Serial.begin(115200);
  SerialBT.begin("WazeHUD");          // điện thoại kết nối tới tên này
}

void loop() {
  static char line[512];
  static size_t n = 0;
  while (SerialBT.available()) {
    char c = SerialBT.read();
    if (c == '\n') {                  // đã đủ 1 message HLP
      line[n] = 0; n = 0;
      StaticJsonDocument<512> doc;
      if (deserializeJson(doc, line)) continue;   // bỏ dòng hỏng, resync ở '\n' kế
      const char* t = doc["t"] | "";
      if (strcmp(t, "s") == 0) {
        int   spd = doc["spd"] | 0;
        int   lim = doc["lim"] | 0;
        int   trn = doc["trn"] | 0;
        int   dst = doc["dst"] | -1;
        const char* st = doc["st"] | "";
        // TODO: vẽ spd / lim / bitmap mũi tên theo trn / dst / st …
      }
    } else if (n < sizeof(line) - 1) {
      line[n++] = c;
    } else {
      n = 0;                          // tràn → resync
    }
  }
}

Bên nhận có thể (tùy chọn) gửi khai báo dev để thương lượng rate/fields; nếu im lặng, producer tự đẩy default hợp lý sau 500 ms (xem HLP_v1.md §2.5).

6. Trạng thái

  • Producer: HLP/1 đã có trên Classic SPP bảo mật và BLE GATT.
  • Ví dụ ESP32: đã có raw receiver BLE/SPP, framing giới hạn, handshake và ping/pong.
  • Firmware sản phẩm: decoder field, driver màn hình và renderer tùy thuộc thiết bị.
Tiếp ESP32 BLE

Trên trang này

1. Là gì2. Kiến trúc3. Bật lên4. Luồng dữ liệu (HLP/1)5. Viết bên nhận (ESP32, Bluetooth SPP)6. Trạng thái