> For the complete documentation index, see [llms.txt](https://innoway.gitbook.io/innoway/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://innoway.gitbook.io/innoway/tinh-nang/custom-adapter/mqtt.md).

# MQTT

Adapter với giao thức MQTT cho phép người dùng tự định nghĩa các topic hoặc kết nối với broker MQTT bên ngoài hoặc của Innoway, subscribe và nhận bản tin từ các broker đó và đưa vào luồng xử lí của [thing](/innoway/tinh-nang/quan-li-nghiep-vu/quan-li-thing.md) và [nghiệp vụ](/innoway/tinh-nang/quan-li-nghiep-vu.md) gắn vào adapter. Từ đó khách hàng có thể trực tiếp sử dụng nền tảng Innoway mà không cần cập nhật firmware thiết bị. Các bản tin gửi lên broker hiện tại sẽ được đóng gói dưới dạng string theo kiểu dữ liệu người dùng chọn (json/hex/text) và chuyển tiếp và được xử lí trên nền tảng Innoway.

## Khái quát về cách hoạt động

<figure><img src="/files/coMlpIMmDWoNNn0fMuK8" alt=""><figcaption></figcaption></figure>

Adapter sẽ thực hiện lắng nghe các bản tin từ topic mà người dùng tự định nghĩa, sau đó dữ liệu sẽ được gửi đến Thing để thực hiện các nghiệp vụ xử lý dữ liệu.

Các nghiệp vụ(Service) trong Thing được người dùng tự định nghĩa, cách triển khai 1 hay nhiều nghiệp vụ hoàn toàn do nhu cầu của người dùng.

## Bắt đầu sử dụng

### 1.1. Tạo Thing

Thing đại diện cho một hoặc một nhóm các nghiệp vụ, để tạo Thing vui lòng tham khảo [Quản lí Thing](/innoway/tinh-nang/quan-li-nghiep-vu/quan-li-thing.md)

<figure><img src="/files/LnVcgJuPev2vcxvVdvUH" alt=""><figcaption></figcaption></figure>

### 1.2. Tạo nghiệp vụ (service)

Sau khi tạo Thing, chuyển sang tab "Nghiệp vụ" để tạo nghiệp vụ mới, để tạo nghiệp vụ mới vui lòng tham khảo [Quản lí nghiệp vụ(Service)](/innoway/tinh-nang/quan-li-nghiep-vu/quan-li-nghiep-vu-service.md).

Trước tiên hãy thử nghiệp với một nghiệp vụ với tính năng cơ bản. Đoạn code dưới đây thực hiện tác vụ cơ bản của MQTT Adapter: Lấy thông tin topic bản tin đến và publish bản tin tới một topic khác.

```javascript
let entityInfoObj = JSON.parse(entityInfo);  // Chuyển json thành object trong JavaScript
let topic = entityInfoObj.topic;  // topic bên trong entityInfo, được khai báo trong phần biến đầu vào
let msgs =  { // Tạo messages phản hồi
  msg: 'hello ' + topic
}
await Adapter().SendMqttResponse({  // Hàm gửi MQTT do nền tảng tích hợp sẵn
  topic: 'adapter/response', 
  message: JSON.stringify(msgs)
}); 
return msgs;  // Trả về messages nếu cần
```

<figure><img src="/files/Yq3hnjdDAqRv5tGoZ9WZ" alt=""><figcaption></figcaption></figure>

{% hint style="success" %}
Khi sử dụng kết hợp nghiệp vụ với Adapter, sẽ có 2 biến đầu vào đặc biệt mà nền tảng đã tạo sẵn chứa các thông tin quan trong:&#x20;

* entityInfo : Chứa thông các thông tin của adapter, topic gửi đến ... (định dạng json)
* payload : Chứa dữ liệu người dùng gửi lên (định dạng json)
  {% endhint %}

```json
{
  "entityInfo": {
    "adapter_id": "881a679b-8497-4f8b-8d8f-cacdaeba860e",
    "createdBy": "69eb79d2-f96a-4dc8-b2f1-163ce83b3ae2",
    "destination": "adapter-2",
    "grpc_address": "adapter-2.viot-adapter:8957",
    "handle_msg_svc": "device_message_processing",
    "name": "adapter_mqtt_demo",
    "owner": "69eb79d2-f96a-4dc8-b2f1-163ce83b3ae2",
    "project_id": "489822f5-0f8e-437a-abea-26cb0f23a9a7",
    "sub_topic_regex": "adapter/topic0,adapter/topic1",
    "thing_id": "0204a9b7-2a7f-438a-99af-29a265ef5ee0",
    "topic": "adapter/topic1",
    "user_id": "69eb79d2-f96a-4dc8-b2f1-163ce83b3ae2"
  },
  "payload": {
    "msg": "Messages from topic1"
  }
}
```

{% hint style="success" %}
Khi sử dụng trong JavaScript cần sử dụng JSON.parse() chuyển từ json sang Object để có thể truy cập vào các trường dữ liệu
{% endhint %}

<figure><img src="/files/0Dh9OS5QfX8Qa7vABPBZ" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
Các SDK thực thi các nghiệp vụ liên quan đến gửi publiish mqtt, thiết bị, thuộc tính, adapter,... có thể tham khảo tại [Tài liệu SDK](/innoway/tai-lieu/sdk.md).
{% endhint %}

### 1.3. Tạo adapter mqtt

Sau khi tạo thành công Thing và Nghiệp vụ, thực hiện tạo mới một Adapter MQTT, chọn mục "Adapter" tại sidebar và chọn tạo mới:

<figure><img src="/files/aN69pm2YXaGxnylg8aGN" alt=""><figcaption></figcaption></figure>

Trong ví dụ này chỉ dùng MQTT broker của nền tảng nên "Tùy chọn MQTT broker" sẽ là mặc định

<figure><img src="/files/nmoosJWMxqC9icDcj7VM" alt=""><figcaption></figcaption></figure>

### 1.4. Thử nghiệm với MQTT Explorer

<figure><img src="/files/yv9YHURSAFzHgFtcm9Bs" alt=""><figcaption><p>Thực hiện kết nối tới MQTT broker và subscribe các topic</p></figcaption></figure>

<figure><img src="/files/PBWEEOXgmTDuczDUylgr" alt=""><figcaption><p>Gửi bản tin tới adapter/topic1 và nhận phản hồi hởi topic adapter/response</p></figcaption></figure>

<figure><img src="/files/4HX7mDt5AxYz3yETsTRh" alt=""><figcaption><p>Gửi bản tin tới adapter/topic0 và nhận phản hồi hởi topic adapter/response</p></figcaption></figure>

## Ví dụ cập nhật thuộc tính của thiết bị thông qua Adapter

Thông qua thực hiện các bước ở phân trên người dung đã tạo được một luồng gửi nhận cơ bản với adapter, để thực hiện cập nhật thuộc tính của một thiết bị bất kì trên Innoway có thể thực hiện theo các bước sau

### 2.1. Thiết lập topic mqtt

* Để có thể cập nhật thuộc tính của một thiết bị, yêu cầu phải có device\_id(ID của thiết bị muốn cập nhật)
* Trong ví dụ này, device\_id sẽ được chèn vào trong topic để dễ dàng định danh thiết bị dựa trên topic gửi về adapter

{% hint style="info" %}
Định dạng topic (ví dụ) : adapter/device/<mark style="color:red;">{device\_id}</mark>/update
{% endhint %}

* Định dạng topic trên chỉ là ví dụ trong hướng dẫn này, trong thực tế topic có thể tùy ý người dùng định nghĩa

Thực hiện thêm/sửa topic tại giao diện sửa adapter

<figure><img src="/files/EijLJz3DJIZjGr3aJd34" alt=""><figcaption><p>Thêm topic mới cho adapter</p></figcaption></figure>

* Thêm topic mới “adapter/device/+/update” để thực hiện nắng nghe tất cả các topic có dạng là : adapter/device/<mark style="color:red;">{device\_id hoặc thông tin người dùng tự định nghĩa}</mark>/update
* Click ✓ để lưu lại thay đổi

Để lấy được device\_id của thiết bị, truy cập vào mục thiết bị tại quản lý tổ chức

* ID của thiết bị có dạng một chuỗi 32 kí tự(không tính "-")
* ví dụ : <mark style="color:yellow;">75dc47c5-1101-4260-bf2d-521e7c68939a</mark>

<figure><img src="/files/x94vmzL8dCqxjaKS7OW1" alt=""><figcaption><p>Lấy ID của thiết bị</p></figcaption></figure>

### 2.2. Sửa nghiệp vụ

Thực hiện theo các bước sau&#x20;

<figure><img src="/files/XvkA4nacnOUN0xHRM6Yg" alt=""><figcaption><p>Danh sách Thing</p></figcaption></figure>

* Click vào tên Thing để xem danh sách nghiệp vụ

<figure><img src="/files/TZQqw6J7mXgFgZ5CuTmW" alt=""><figcaption><p>Danh sách ngiệp vụ</p></figcaption></figure>

* Click vào biểu tượng cây bút để xem và sửa nghiệp vụ
* Tại đây đang hiển thị code của nghiệp vụ được tạo từ phần đầu hướng dẫn, thực hiện sửa code để có luồng xử lý data như mong muốn

<figure><img src="/files/ODirotHZz2xLIiqB5qRd" alt=""><figcaption></figcaption></figure>

Thêm biến đầu vào payload (chứa dữ liệu người dùng/thiết bị gửi lên)

```typescript
// Đây là phần code của nghiệp vụ

let entityInfoObj = JSON.parse(entityInfo) // Chuyển entityInfo thành object trong JavaScript
let topic = entityInfoObj.topic      // Lấy thông tin topic từ entityInfo

var parts = topic.split("/");   // Tách topic thành các chuỗi nhỏ để dễ dàng xử lý

var deviceId = parts[2]         // Lấy deviceId từ topic, tùy người dùng định nghĩa, 
                                // trong ví dụ này deviceId nằm tại vị trí thứ 3 trong topic
                                // vd : adapter/device/{deviceId}/update

let mqttPayload = JSON.parse(payload); // Chuyển payload thành object trong JavaScript

// Tạo biến chứa các thông tin của thuộc tính muốn thêm mới hoặc cập nhật
// vd : "RSSI" sẽ là tên hiển thị trong danh sách thuộc tính của thiết bị
//      mqttPayload.RSSI sẽ là giá trị của "RSSI"
Update = {
  "RSSI" : mqttPayload.RSSI,   
  "temp": mqttPayload.temp      
}

// logged = false : không lưu lịch sử cập nhật thuộc tính
// logged = true  : lưu lịch sử cập nhật thuộc tính
let logged = false  

// Thực hiện cập nhật thuộc tính thông qua hàm UpsertAttributes
// Tham số cần truyền vào bao gồm deviceId, Update, logged
await Thing(deviceId).UpsertAttributes(Update, {logged: logged});

// Gửi phản về topic 'adapter/response'
await Adapter().SendMqttResponse({
  topic: 'adapter/response', 
  message: JSON.stringify("Update attributes done")
});

// Trả về thông tin thuộc tính cập nhật
return Update;
```

Thing(id: string).UpsertAttributes(attrs: {\[key: string]: any}, {logged: boolean}) là hàm được cung cấp bởi nền tảng Innoway, hàm được sử dụng để cập nhật giá trị của một hoặc nhiều thuộc tính của một thiết bị. Để xem toàn bộ các hàm được hỗ trợ bởi Innoway, vui lòng truy cập [https://app.gitbook.com/o/503tfg1ajFL2TCfLn9hI/s/dHTLVKzo80twFgwBzfnj/\~/changes/140/tai-lieu/sdk](/innoway/tai-lieu/sdk.md)

### 2.3. Gửi dữ liệu từ mqtt explorer và kiểm tra nghiệp vụ

Sau khi hoàn thành sửa nghiệp, thực hiện đẩy dữ liệu mong muốn từ MQTT lên adapter theo topic như đã thiết lập ở phần 2.1

<figure><img src="/files/7FhEnW8fClunObhh3IQn" alt=""><figcaption><p>Publish dữ liệu vào topic mới </p></figcaption></figure>

<figure><img src="/files/1sHYcDTFnXlmyYw77S1m" alt=""><figcaption><p>Adapter hoàn thành quá trình xử lý và gửi phản hồi</p></figcaption></figure>

* Để kiểm tra lại lịch sử bản tin đã gửi lên adapter, người dùng có thể truy cập vào mục "Lịch sử thực thi nghiệp vụ"

<figure><img src="/files/3cgoVaZiVk7maNEdNben" alt=""><figcaption></figcaption></figure>

* Tại đây sẽ hiển thị danh sách các bản tin được nhận vào bởi adapter cùng dữ liệu đầu vào, đầu ra và trạng thái xử lý

<figure><img src="/files/XZx6qMVrMODd0GJyd2m4" alt=""><figcaption></figcaption></figure>

* Nếu trạng thái xử lý là <mark style="color:red;">Thất bại</mark> người dùng có thể click vào biểu tượng đôi mắt để xem lỗi cụ thể(nếu có)

<figure><img src="/files/PHJymTQARXIBSiiSl91g" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/2wAXMCXeCFMKMCXvWnxu" alt=""><figcaption></figcaption></figure>

* Cuối cùng truy cập vào giao diện quản lý thuộc tính thiết bị để xem giá trị thuộc tính sau khi cập nhật

<figure><img src="/files/3sONrDzcFthwuxnMf1Yy" alt=""><figcaption></figcaption></figure>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://innoway.gitbook.io/innoway/tinh-nang/custom-adapter/mqtt.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
