Hướng dẫn cấu hình ThingsBoard (việc cần làm phía bạn)
⚠️ Tài liệu này đã lỗi thời một phần. Nó mô tả kiến trúc cũ (một tài
khoản tenant global, ThingsBoard là “source of truth”, ingest token global).
Hệ thống hiện dùng connector per-organization: mỗi tổ chức tự cấu hình
ThingsBoard của họ từ UI, credentials lưu mã hoá trong DB, ingest token
sinh riêng cho từng kết nối. Các phần dưới đã được cập nhật endpoint/token
cho đúng mô hình per-org, nhưng phần bối cảnh kiến trúc cần được viết lại đầy
đủ (theo dõi ở issue refresh riêng).
Tài liệu này liệt kê những việc bạn cần tự làm để tích hợp ThingsBoard. Phần code đã xong và test đầy đủ; những mục dưới đây là cấu hình hạ tầng / ThingsBoard, không nằm trong code.
Cập nhật: container ThingsBoard (
hmpiot_tb_core, imagethingsboard/tb-postgres) giờ nằm trongdocker-compose.infra.ymlvà đượcmake dev/make dev-infratự khởi động cùng Postgres/Redis — không cần chạydocker runtay nữa (mục 2 dưới đây, tài khoản tenant demo, cũng được image tự tạo sẵn ở lần boot đầu, mất vài phút). Các mục còn lại (ingest token, rule chain, backfill, firmware) vẫn là việc cấu hình thủ công.
Bối cảnh kiến trúc: Hệ thống HMP là companion chạy song song ThingsBoard (TB).
- Thiết bị (ESP32) publish telemetry trực tiếp lên TB bằng access token riêng của từng device.
- Telemetry “source of truth” nằm ở ThingsBoard; TimescaleDB của backend chỉ là bản sao đồng bộ + phục vụ các tính năng companion.
- Frontend đọc TB trực tiếp (per-user). Backend dùng một tài khoản tenant để đọc telemetry / gửi RPC / chạy automation & alert / tạo device.
1. Cấu hình kết nối ThingsBoard (per-organization)
Không còn biến môi trường global cho ThingsBoard. Mỗi tổ chức tự cấu hình kết nối ThingsBoard của mình:
- Base URL, username, password của ThingsBoard được nhập từ màn hình cấu hình integration trong HMP và lưu mã hoá trong DB (bảng
integration_connections, mã hoá bằngINTEGRATION_ENCRYPTION_KEY). - Ingest token được sinh tự động cho từng kết nối khi bạn kết nối integration (không phải secret đặt trong
.env). Token này dùng ở headerx-ingest-tokencủa webhook Rule Engine và xác định tổ chức tương ứng.
Việc duy nhất liên quan
.envlàINTEGRATION_ENCRYPTION_KEY(khoá AES-256 base64 32 byte) để mã hoá/giải mã credentials các kết nối.
2. Tài khoản tenant trên ThingsBoard
Backend đăng nhập TB bằng credentials tenant (cấu hình per-org ở mục 1, lưu mã hoá trong DB) để:
- Tạo device khi bạn tạo device từ phía HMP.
- Đọc telemetry (latest / history / export).
- Gửi lệnh RPC xuống device.
- Kiểm tra trạng thái online/offline (thuộc tính
active).
Việc cần làm: đảm bảo tài khoản tenant này tồn tại và đăng nhập được trên TB CE của bạn. (Mặc định TB là tenant@thingsboard.org / tenant — nên đổi mật khẩu cho production.)
3. Cấu hình Rule Chain để đẩy telemetry về backend (webhook)
Vì thiết bị publish thẳng lên TB, backend không còn nhận telemetry qua MQTT nữa. Để automation engine + ngưỡng cảnh báo (threshold alerts) của HMP hoạt động realtime, cần cấu hình Rule Engine của TB forward telemetry về backend.
Endpoint nhận của backend
POST http://<host-backend>:3000/api/v1/integrations/thingsboard/ingest
Header: x-ingest-token: <ingest token per-org của kết nối>
Content-Type: application/json
Body:
{
"deviceName": "SN-2024-001", // = serial number của device (chính là tên device trên TB)
"ts": 1705143600000, // optional, epoch milliseconds
"values": { "ph": 7.2, "temperature": 28.5 }
}
- Trả về
202 Accepted{ "accepted": true }nếu device khớp;{ "accepted": false }nếu chưa biết device. - Sai/thiếu
x-ingest-token→401.
Các bước trên TB (Rule Chains → Root Rule Chain hoặc chain riêng)
- Mở Rule chains → chọn chain xử lý telemetry (thường là Root Rule Chain).
- Sau node “Save Timeseries” (hoặc nhánh “Post telemetry”), thêm một node “REST API Call”.
- Cấu hình node REST API Call:
- Endpoint URL pattern:
http://<host-backend>:3000/api/v1/integrations/thingsboard/ingest - Request method:
POST - Headers: thêm
x-ingest-token= ingest token per-org của kết nối;Content-Type=application/json
- Endpoint URL pattern:
- Dùng một node “Transform Script” (đặt trước REST API Call) để map message TB về đúng body backend cần:
// metadata.deviceName là tên device trên TB (= serial number) var newMsg = { deviceName: metadata.deviceName, ts: metadata.ts ? parseInt(metadata.ts) : new Date().getTime(), values: msg }; return { msg: newMsg, metadata: metadata, msgType: msgType }; - Nối:
... → Transform Script → REST API Call. Lưu & deploy rule chain.
Nếu
<host-backend>là máy host còn TB chạy trong Docker, dùnghttp://host.docker.internal:3000thay cholocalhost.
4. Mapping device giữa HMP và ThingsBoard
- Khi bạn tạo device từ HMP, backend sẽ tự tạo device tương ứng trên TB (tên TB =
serialNumber), lấy vềtb_device_id+ access token và lưu vào DB. Nếu tạo trên DB thất bại, device vừa tạo trên TB sẽ được xoá tự động (không để lại rác). - Access token mà backend lấy về chính là token để firmware thiết bị đăng nhập MQTT của TB. Lấy token này gán vào firmware ESP32.
⚠️ Device cũ (tạo trước khi migrate)
Các device đã tồn tại trước đợt migrate sẽ có tb_device_id = null và sẽ bị bỏ qua ở các luồng RPC / đọc telemetry / kiểm tra online. Cần backfill: tạo/nối các device này với device tương ứng trên TB rồi lưu tb_device_id + access token.
Nói mình nếu bạn muốn mình viết script backfill cho các device cũ.
5. Firmware thiết bị (ESP32)
- Mỗi device publish telemetry trực tiếp lên TB theo chuẩn TB:
Host: <THINGSBOARD_HOST> Port: 1883 MQTT Username: <access token của device> (password để trống) Topic: v1/devices/me/telemetry Payload: {"ph": 7.2, "temperature": 28.5} - Access token lấy ở mục 4 (do backend tạo). Đây là điểm khác biệt lớn so với EMQX cũ (dùng
server/server-secret). - RPC: device subscribe
v1/devices/me/rpc/request/+để nhận lệnh do backend gửi qua TB.
6. Dọn EMQX (đã bỏ khỏi project)
- Backend không còn dùng EMQX nữa.
docker-compose*.ymlđã gỡ serviceemqx+ volume + biếnMQTT_BROKER_URL. - Container EMQX dev (
hmpiot_emqx_dev) đang chạy trên máy bạn (host port 1884) có thể dừng/gỡ nếu không dùng việc khác:docker rm -f hmpiot_emqx_dev - Lưu ý: container ThingsBoard
hmpiot_tb_corecủa bạn đang chiếm host port 1883 — đây là MQTT cho thiết bị publish lên TB, giữ nguyên.
7. Kiểm tra sau khi cấu hình
- Health check — backend báo trạng thái TB:
curl http://localhost:3000/api/v1/health # services.thingsboard phải = "ok" (trước đây là services.mqtt) - Thử ingest webhook (giả lập Rule Engine):
curl -X POST http://localhost:3000/api/v1/integrations/thingsboard/ingest \ -H "x-ingest-token: <ingest token per-org của kết nối>" \ -H "Content-Type: application/json" \ -d '{"deviceName":"SN-2024-001","values":{"ph":7.2,"temperature":28.5}}' # mong đợi: 202 {"accepted":true} (device phải tồn tại trong tổ chức của token) - Tạo 1 device mới từ HMP → kiểm tra trên TB dashboard thấy device mới (tên = serial) và lấy được access token.
- Gửi RPC / điều khiển gateway từ HMP → device nhận được lệnh qua TB.
Tóm tắt việc cần làm
- Cấu hình kết nối ThingsBoard per-org từ UI và lấy ingest token của kết nối.
- Xác nhận tài khoản tenant TB đăng nhập được.
- Cấu hình Rule Chain (Transform Script + REST API Call) đẩy telemetry về
/api/v1/integrations/thingsboard/ingest. - Backfill
tb_device_idcho các device cũ (nếu có). - Nạp access token TB vào firmware ESP32.
- (Tuỳ chọn) Gỡ container
hmpiot_emqx_dev. - Chạy các bước kiểm tra ở mục 7.