# Node-RED: nối OPC UA và Modbus sang MQTT khi FDE vào nhà máy của khách

> Bạn nối node trong một buổi chiều là xong, nhưng một phép chia bị quên hay một editor bỏ ngỏ vẫn đủ làm hỏng buổi demo đầu tiên ở xưởng.

Bản gốc: https://fdetimes.net/vi/cong-cu/node-red-noi-modbus-opc-ua-mqtt-du-lieu-nha-may/

Một cảm biến nhiệt độ đọc qua Modbus có thể trả về con số 350. FlowFuse dùng đúng ví dụ này để nhắc rằng nhiệt độ thật là 35,0°C. Thử hình dung buổi demo đầu tiên ở xưởng mà dashboard báo lò đang ở 350 độ: chỉ một phép chia bị quên là đủ làm hỏng nó.

Nếu bạn là FDE triển khai sản phẩm dữ liệu hay AI cho khách hàng sản xuất, câu hỏi đầu tiên gần như lúc nào cũng vậy: làm sao lấy được số đo từ PLC? Thiết bị nói Modbus hoặc OPC UA, còn hệ thống của bạn muốn nhận MQTT.

Node-RED là một cách nhanh để bắc cây cầu đó. Đây là công cụ lập trình theo luồng có gốc từ nhóm Emerging Technology Services của IBM, trình soạn thảo chạy ngay trên trình duyệt: bạn nối node thay vì viết một service từ đầu. Nhưng nó có vài cái bẫy bạn nên biết trước ngày lên xưởng.

## Phần nào có sẵn, phần nào phải cài?

MQTT có sẵn. Cookbook của Node-RED hướng dẫn dùng node MQTT in hoặc MQTT out, kèm một config node để khai báo broker. Nếu broker local đang mở, bạn đặt host là localhost và giữ cổng 1883. Broker có bảo mật thì phải cấu hình thêm.

Phía thiết bị thì phải cài. FlowFuse lưu ý Node-RED không đi kèm node Modbus. Gói node-red-contrib-modbus hỗ trợ cả Modbus TCP lẫn serial, cài qua Palette Manager hoặc lệnh npm install. Với OPC UA, gói node-red-contrib-opcua xây trên thư viện node-opcua và được cài bằng npm trong thư mục Node-RED.

Tài liệu chính thức có một chi tiết dễ quên: cài gói xong, bạn phải khởi động lại Node-RED thì nó mới nhận các node vừa thêm. Nếu làm trên gateway đang chạy của khách, bạn nên báo trước với người vận hành về lần restart này.

## Modbus: một thanh ghi, một phép chia

Theo hướng dẫn của Chipkin, thanh ghi Modbus chỉ là số nguyên 16-bit, không mang đơn vị cũng không có dấu thập phân. Ý nghĩa của con số nằm trong register map của thiết bị. Khi bảng này ghi độ phân giải 0.1, bạn chia giá trị thô cho 10.

Thử hình dung register map của khách có một dòng như sau: cảm biến lò 1, một holding register, kiểu số nguyên 16-bit, độ phân giải 0.1, đơn vị °C. Node Modbus đọc về 350. Nếu publish thẳng con số đó, dashboard sẽ báo lò đang ở 350 độ.

Vì thế flow tối thiểu có bốn chặng. Node Modbus đọc thanh ghi, function node quy đổi, MQTT out publish lên một topic có cấu trúc, cuối cùng broker nhận dữ liệu. Đoạn dưới đây chỉ là ví dụ minh họa và giả định giá trị thô đã nằm sẵn trong msg.payload:

```js
// Hệ số lấy từ register map: độ phân giải 0.1 → chia cho 10
const raw = msg.payload;          // ví dụ: 350
msg.payload = raw / 10;           // 35.0 (°C)
msg.topic = "nhamay/lo-1/nhiet-do";
return msg;
```

Số 10 trong đoạn code không tự dưng mà có. Nó lấy từ register map, và bạn phải xin khách bảng này cho từng thiết bị.

## Float 32-bit: hai thanh ghi, thứ tự do hãng quyết định

Phần khó hơn là float 32-bit. Mỗi giá trị chiếm hai thanh ghi, và Chipkin lưu ý rằng mỗi hãng sắp thứ tự hai thanh ghi này một kiểu. Bạn chỉ giải mã đúng khi khớp được thứ tự của chính thiết bị đó.

Lấy một ví dụ tự tính: 35,0 viết theo chuẩn float 32-bit là 0x420C0000. Nếu thiết bị gửi word cao trước, node Modbus sẽ đọc về hai số nguyên [16908, 0], vì 0x420C bằng 16908. Đoạn minh họa dưới đây ghép hai thanh ghi lại thành 4 byte rồi đọc ra số thực:

```js
// Giả định register map ghi: float 32-bit, word cao trước
const [hi, lo] = msg.payload;     // ví dụ: [16908, 0]
const buf = Buffer.alloc(4);
buf.writeUInt16BE(hi, 0);
buf.writeUInt16BE(lo, 2);
msg.payload = buf.readFloatBE(0); // 35
return msg;
```

Với một hãng khác gửi word thấp trước, payload sẽ là [0, 16908]. Nếu vẫn dùng đoạn code trên, bạn nhận về một số cực nhỏ gần bằng 0 thay vì 35. Cách sửa chỉ là đổi chỗ hai dòng write, nhưng bạn phải biết thứ tự từ register map hoặc thử với một giá trị đã biết trước.

Khi gặp dữ liệu nhiều kiểu hoặc phải đổi byte, FlowFuse gợi ý dùng node buffer-parser thay vì tự viết code. Dù chọn cách nào, hãy đối chiếu kết quả với màn hình HMI của khách trước khi tin con số.

## OPC UA: endpoint, READ, rồi MQTT

Hướng dẫn từng bước của FlowFuse cho OPC UA khá ngắn. Bạn kéo node OpcUa-Client vào flow, bấm dấu "+" cạnh ô Endpoint rồi nhập URL của OPC UA server đang chạy. Nếu server không bật bảo mật, policy có thể để None.

Tiếp theo, bạn chọn kiểu hành động READ, rồi nối đầu ra của node sang một node mqtt out trỏ vào broker. Sau ba thao tác ấy, giá trị đọc từ server đã lên tới topic MQTT.

Để policy là None chỉ hợp lúc thử nghiệm. Vì vậy, trước ngày lên xưởng, bạn nên cùng kỹ sư nhà máy liệt kê endpoint, các biến cần lấy cùng đơn vị của chúng, và hỏi xem server có bật bảo mật không. Danh sách này mới là phần tốn công, còn nối node thì nhẹ hơn nhiều.

## Bốn lỗi hay gặp khi lên xưởng

Bốn lỗi dưới đây đáng để bạn in ra mang theo mỗi chuyến đi:

| Lỗi | Chuyện gì xảy ra | Cách tránh |
|---|---|---|
| Publish giá trị thô | Dashboard hiện 350 thay vì 35,0°C | Quy đổi theo register map, với float 32-bit thì khớp thứ tự thanh ghi của hãng |
| Để editor ở cấu hình mặc định | Ai vào được mạng cũng sửa được flow | Bỏ comment adminAuth trong settings.js, rồi chuyển sang HTTPS |
| Thiếu gói khi mạng OT không có internet | Không cài được node Modbus hay OPC UA tại chỗ | Chuẩn bị sẵn gói và cài thử trước ngày lên xưởng |
| Node.js cũ | Gói Modbus không chạy | Gói cần Node.js 22 trở lên và Node-RED 4 trở lên, còn Node-RED khuyến nghị Node 24.x |

Lỗi thứ hai cần nói kỹ hơn. Tài liệu bảo mật của Node-RED nói rõ editor mặc định không được bảo vệ, nên chỉ hợp với mạng tin cậy. Ở nhà máy, như vậy nghĩa là ai vào được mạng cũng chỉnh được flow đang nối với thiết bị.

**Điểm mấu chốt:** Cầu nối dữ liệu dựng nhanh đến đâu cũng phải được khóa trước khi bạn rời xưởng.

Lỗi thứ ba đến từ cách cài đặt. Dù dùng palette hay npm, bạn đều phải tải gói về. Nếu mạng OT của khách không ra được internet, đến hôm lên xưởng mới phát hiện thì đã muộn.

Lỗi thứ tư cũng nên kiểm tra từ xa: Node-RED 5.x cần tối thiểu Node.js 22, nên một gateway cũ có thể phải nâng cấp trước.

## Học gì trước, và ghi gì vào CV?

Nên học MQTT trước (topic, broker, cách đặt tên), tiếp đến cách Modbus lưu dữ liệu trong thanh ghi, và để OPC UA sau cùng. Trong lúc học, hãy đọc kỹ settings.js để biết cấu hình bảo mật nằm ở đâu.

Khi đọc job description, những cụm như OT/IT integration, MQTT hay PLC data cho thấy công việc sẽ cần đúng loại cầu nối này. Trong CV, một dòng cụ thể như "dựng bridge Modbus và OPC UA sang MQTT, quy đổi register theo register map, bật adminAuth và HTTPS" thuyết phục hơn nhiều so với "có kinh nghiệm IoT".

Bạn có thể luyện cả chuỗi này ngay trên laptop. Dùng một inject node phát số 350 thay cho thiết bị thật, cho qua function node ở trên rồi publish 35,0 lên broker local ở cổng 1883. Sau đó thử inject [16908, 0] qua đoạn giải mã float, đổi thành [0, 16908] để thấy kết quả sai trông thế nào, rồi bật adminAuth và đăng nhập lại editor.

Node-RED không phải phần hào nhoáng nhất của một dự án AI cho nhà máy. Nhưng nếu dữ liệu qua nó bị sai đơn vị, mọi mô hình phía sau cũng sai theo.

**Thử ngay tuần này:**

- Cài Node-RED 4 trở lên trên Node.js 22 trở lên, thêm node-red-contrib-modbus, dùng inject node phát số 350 rồi publish 35,0 lên broker local ở cổng 1883
- Bỏ comment adminAuth trong settings.js, đặt mật khẩu và thử đăng nhập lại editor
- Viết một checklist trước khi lên xưởng: phiên bản Node.js, Node-RED, các gói contrib cần mang theo, register map và danh sách endpoint OPC UA cần xin khách

## Nguồn

- [About : Node-RED](https://nodered.org/about/)

- [Securing Node-RED : Node-RED](https://nodered.org/docs/user-guide/runtime/securing-node-red)

- [How to Bridge Modbus to MQTT: Step-by-Step Guide](https://flowfuse.com/blog/2024/12/publishing-modbus-data-to-uns)

- [Modbus Scaling & Data Conversion Guide](https://docs.chipkin.com/articles/modbus-scaling-and-data-conversion-guide/)

- [BiancoRoyal/node-red-contrib-modbus (GitHub)](https://github.com/BiancoRoyal/node-red-contrib-modbus)

- [node-red-contrib-opcua : Node-RED Library](https://flows.nodered.org/node/node-red-contrib-opcua)

- [Bridging OPC UA Data to MQTT with Node-RED (2026)](https://flowfuse.com/blog/2024/08/opc-ua-to-mqtt-with-node-red/)

- [Supported Node versions](https://nodered.org/docs/faq/node-versions)

- [Adding nodes to the palette : Node-RED](https://nodered.org/docs/user-guide/runtime/adding-nodes)

- [Connect to an MQTT Broker, Node-RED Cookbook](https://cookbook.nodered.org/mqtt/connect-to-broker)
