

支援終止通知：2026 年 10 月 7 日 AWS 將停止 的支援 AWS IoT Greengrass Version 1。2026 年 10 月 7 日之後，您將無法再存取 AWS IoT Greengrass V1 資源。如需詳細資訊，請造訪[從 遷移 AWS IoT Greengrass Version 1](https://docs.aws.amazon.com/greengrass/v2/developerguide/migrate-from-v1.html)。

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# Modbus-RTU 通訊協定轉接器連接器
<a name="modbus-protocol-adapter-connector"></a>

Modbus-RTU 通訊協定轉接器[連接器](connectors.md)會從 AWS IoT Greengrass 群組中的 Modbus RTU 裝置輪詢資訊。

此連接器會從使用者定義的 Lambda 函數接收 Modbus RTU 請求的參數。它會傳送對應的請求，然後從目標裝置發佈回應做為 MQTT 訊息。

此連接器具有下列版本。


| 版本 | ARN | 
| --- | --- | 
| 3 | `arn:aws:greengrass:{{region}}::/connectors/ModbusRTUProtocolAdapter/versions/3` | 
| 2 | `arn:aws:greengrass:{{region}}::/connectors/ModbusRTUProtocolAdapter/versions/2` | 
| 1 | `arn:aws:greengrass:{{region}}::/connectors/ModbusRTUProtocolAdapter/versions/1` | 

如需版本變更的詳細資訊，請參閱 [Changelog](#modbus-protocol-adapter-connector-changelog)。

## 要求
<a name="modbus-protocol-adapter-connector-req"></a>

此連接器有下列要求：

------
#### [ Version 3 ]
+ <a name="conn-req-ggc-v1.9.3"></a>AWS IoT Greengrass 核心軟體 v1.9.3 或更新版本。
+ <a name="conn-req-py-3.7-and-3.8"></a>安裝在核心裝置上並新增至 PATH 環境變數的 [Python](https://www.python.org/) 3.7 或 3.8 版。
**注意**  <a name="use-runtime-py3.8"></a>
若要使用 Python 3.8，請執行下列命令來建立從預設 Python 3.7 安裝資料夾到已安裝 Python 3.8 二進位檔的符號連結。  

  ```
  sudo ln -s {{path-to-python-3.8}}/python3.8 /usr/bin/python3.7
  ```
這會設定您的裝置以符合 AWS IoT Greengrass的 Python 需求。
+ <a name="conn-modbus-req-physical-connection"></a> AWS IoT Greengrass 核心與 Modbus 裝置之間的實體連線。核心必須透過序列埠 (例如 USB 連接埠) 實際連接到 RTU Modbus 網路。
+ <a name="conn-modbus-req-serial-port-resource"></a>Greengrass 群組中的[本機裝置資源](access-local-resources.md)，指向實體 Modbus 序列連接埠。
+ <a name="conn-modbus-req-user-lambda"></a>使用者定義的 Lambda 函數，會將 Modbus RTU 請求參數傳送至此連接器。此請求參數必須符合預期模式，且包含 Modbus RTU 網路上目標裝置的 ID 和地址。如需詳細資訊，請參閱[輸入資料](#modbus-protocol-adapter-connector-data-input)。

------
#### [ Versions 1 - 2 ]
+ <a name="conn-req-ggc-v1.7.0"></a>AWS IoT Greengrass 核心軟體 v1.7 或更新版本。
+ 安裝在核心裝置上並新增至 PATH 環境變數的 [Python](https://www.python.org/) 2.7 版。
+ <a name="conn-modbus-req-physical-connection"></a> AWS IoT Greengrass 核心與 Modbus 裝置之間的實體連線。核心必須透過序列埠 (例如 USB 連接埠) 實際連接到 RTU Modbus 網路。
+ <a name="conn-modbus-req-serial-port-resource"></a>Greengrass 群組中的[本機裝置資源](access-local-resources.md)，指向實體 Modbus 序列埠。
+ <a name="conn-modbus-req-user-lambda"></a>使用者定義的 Lambda 函數，會將 Modbus RTU 請求參數傳送至此連接器。此請求參數必須符合預期模式，且包含 Modbus RTU 網路上目標裝置的 ID 和地址。如需詳細資訊，請參閱[輸入資料](#modbus-protocol-adapter-connector-data-input)。

------

## 連接器參數
<a name="modbus-protocol-adapter-connector-param"></a>

此連接器支援下列參數：

`ModbusSerialPort-ResourceId`  
代表實體 Modbus 序列埠的本機裝置資源 ID。  
此連接器已授予資源的讀寫存取權。
 AWS IoT 主控台中的顯示名稱：**Modbus 序列連接埠資源**  
必要：`true`  
類型：`string`  
有效模式： `.+`

`ModbusSerialPort`  
裝置上實體 Modbus 序列埠的絕對路徑。這是指定給 Modbus 本機裝置資源的來源路徑。  
 AWS IoT 主控台中的顯示名稱：**Modbus 序列連接埠資源的來源路徑**  
必要：`true`  
類型：`string`  
有效模式： `.+`

### 建立範例連接器 (AWS CLI)
<a name="modbus-protocol-adapter-connector-create"></a>

下列 CLI 命令`ConnectorDefinition`會使用包含 Modbus-RTU 通訊協定轉接器連接器的初始版本來建立 。

```
aws greengrass create-connector-definition --name MyGreengrassConnectors --initial-version '{
    "Connectors": [
        {
            "Id": "MyModbusRTUProtocolAdapterConnector",
            "ConnectorArn": "arn:aws:greengrass:{{region}}::/connectors/ModbusRTUProtocolAdapter/versions/3",
            "Parameters": {
                "ModbusSerialPort-ResourceId": "MyLocalModbusSerialPort",
                "ModbusSerialPort": "{{/path-to-port}}"
            }
        }
    ]
}'
```

**注意**  
此連接器中的 Lambda 函數具有[長期生命週期](lambda-functions.md#lambda-lifecycle)。

在 AWS IoT Greengrass 主控台中，您可以從群組的連接器頁面新增**連接器**。如需詳細資訊，請參閱[Greengrass 連接器入門 (主控台)](connectors-console.md)。

**注意**  
部署 Modbus-RTU 通訊協定轉接器連接器之後，您可以使用 AWS IoT Things Graph 來協調 群組中裝置之間的互動。如需詳細資訊，請參閱*AWS IoT Things Graph 《 使用者指南*》中的 [Modbus](https://docs.aws.amazon.com/thingsgraph/latest/ug/iot-tg-protocols-modbus.html)。

## 輸入資料
<a name="modbus-protocol-adapter-connector-data-input"></a>

此連接器接受 MQTT 主題上使用者定義 Lambda 函數的 Modbus RTU 請求參數。輸入訊息必須是 JSON 格式。

<a name="topic-filter"></a>**訂閱中的主題篩選條件**  
`modbus/adapter/request`

**訊息屬性**  
請求訊息隨著其所代表的 Modbus RTU 請求類型而不同。所有請求需要下列屬性：  
+ 在 `request` 物件中：
  + `operation`。 要執行的操作名稱。例如，指定 `"operation": "ReadCoilsRequest"` 以讀取線圈。這個值必須是 Unicode 字串。如需支援的作業，請參閱 [Modbus RTU 請求和回應](#modbus-protocol-adapter-connector-requests-responses)。
  + `device`。 請求的目標裝置。此值必須介於 `0 - 247` 之間。
+ `id` 屬性。請求的 ID。這個值用於重複資料刪除，並在所有回應的 `id` 屬性中依現狀傳回，包括錯誤回應。這個值必須是 Unicode 字串。
如果您的請求中包含地址欄位，則必須將該值指定為整數。例如 `"address": 1`。
要包含在請求中的其他參數取決於操作。除了 CRC (另外處理)，所有請求參數都是必要。如需範例，請參閱 [範例請求和回應](#modbus-protocol-adapter-connector-examples)。

**範例輸入：讀取線圈請求**  

```
{
    "request": {
        "operation": "ReadCoilsRequest",
    	"device": 1,
    	"address": 1,
    	"count": 1
    },
    "id": "TestRequest"
}
```

## 輸出資料
<a name="modbus-protocol-adapter-connector-data-output"></a>

此連接器將回應發佈到傳入 Modbus RTU 請求。

<a name="topic-filter"></a>**訂閱中的主題篩選條件**  
`modbus/adapter/response`

**訊息屬性**  
回應訊息的格式根據對應的請求和回應狀態而不同。如需範例，請參閱 [範例請求和回應](#modbus-protocol-adapter-connector-examples)。  
寫入操作的回應只是請求的回響。雖然寫入回應沒有傳回有意義的資訊，建議檢查回應的狀態。
每個回應含有以下屬性：  
+ 在 `response` 物件中：
  + `status`。 請求的狀態。狀態可以是下列其中一個值：
    + `Success`。 請求有效、傳送至 Modbus RTU 網路，並傳回回應。
    + `Exception`。 請求有效、傳送至 Modbus RTU 網路，並傳回例外狀況回應。如需詳細資訊，請參閱[回應狀態：例外](#modbus-protocol-adapter-connector-response-exception)。
    + `No Response`。 請求無效，連接器在透過 Modbus RTU 網路傳送請求之前發現錯誤。如需詳細資訊，請參閱[回應狀態：沒有回應](#modbus-protocol-adapter-connector-response-noresponse)。
  + `device`。 傳送請求的裝置。
  + `operation`。 已傳送的請求類型。
  + `payload`。 傳回的回應內容。如果 `status` 是 `No Response`，此物件只包含 `error` 屬性和錯誤描述 (例如，`"error": "[Input/Output] No Response received from the remote unit"`)。
+ `id` 屬性。用於資料重複刪除的請求 ID。

**範例輸出：成功**  

```
{
    "response" : {
        "status" : "success",
        "device": 1,
    	"operation": "ReadCoilsRequest",
    	"payload": {
        	"function_code": 1,
        	"bits": [1]
    	}
     },
     "id" : "TestRequest"
}
```

**範例輸出：失敗**  

```
{
    "response" : {
        "status" : "fail",
        "error_message": "Internal Error",
        "error": "Exception",
        "device": 1,
    	"operation": "ReadCoilsRequest",
    	"payload": {
        	"function_code": 129,
        	"exception_code": 2
    	}
     },
     "id" : "TestRequest"
}
```
如需更多範例，請參閱[範例請求和回應](#modbus-protocol-adapter-connector-examples)。

## Modbus RTU 請求和回應
<a name="modbus-protocol-adapter-connector-requests-responses"></a>

此連接器接受 Modbus RTU 請求參數做為[輸入資料](#modbus-protocol-adapter-connector-data-input)，並發佈回應做為[輸出資料](#modbus-protocol-adapter-connector-data-output)。

以下是支援的常見操作。


| 請求中的作業名稱 | 回應中的函數代碼 | 
| --- | --- | 
| ReadCoilsRequest | 01 | 
| ReadDiscreteInputsRequest | 02 | 
| ReadHoldingRegistersRequest | 03 | 
| ReadInputRegistersRequest | 04 | 
| WriteSingleCoilRequest | 05 | 
| WriteSingleRegisterRequest | 06 | 
| WriteMultipleCoilsRequest | 15 | 
| WriteMultipleRegistersRequest | 16 | 
| MaskWriteRegisterRequest | 22 | 
| ReadWriteMultipleRegistersRequest | 23 | 

### 範例請求和回應
<a name="modbus-protocol-adapter-connector-examples"></a>

以下是受支援操作的範例請求和回應。

讀取線圈  
**請求範例：**  

```
{
    "request": {
        "operation": "ReadCoilsRequest",
    	"device": 1,
    	"address": 1,
    	"count": 1
    },
    "id": "TestRequest"
}
```
**回應範例：**  

```
{
    "response": {
        "status": "success",
        "device": 1,
    	"operation": "ReadCoilsRequest",
    	"payload": {
        	"function_code": 1,
        	"bits": [1]
    	}
     },
     "id" : "TestRequest"
}
```

讀取離散輸入  
**請求範例：**  

```
{
    "request": {
        "operation": "ReadDiscreteInputsRequest",
        "device": 1,
        "address": 1,
        "count": 1
    },
    "id": "TestRequest"
}
```
**回應範例：**  

```
{
    "response": {
        "status": "success",
        "device": 1,
        "operation": "ReadDiscreteInputsRequest",
        "payload": {
            "function_code": 2,
            "bits": [1]
        }
     },
     "id" : "TestRequest"
}
```

讀取保留暫存器  
**請求範例：**  

```
{
    "request": {
        "operation": "ReadHoldingRegistersRequest",
    	"device": 1,
    	"address": 1,
    	"count": 1
    },
    "id": "TestRequest"
}
```
**回應範例：**  

```
{
    "response": {
        "status": "success",
        "device": 1,
    	"operation": "ReadHoldingRegistersRequest",
    	"payload": {
    	    "function_code": 3,
            "registers": [20,30]
    	}
     },
     "id" : "TestRequest"
}
```

讀取輸入暫存器  
**請求範例：**  

```
{
    "request": {
        "operation": "ReadInputRegistersRequest",
    	"device": 1,
    	"address": 1,
    	"value": 1
    },
    "id": "TestRequest"
}
```

寫入單一線圈  
**請求範例：**  

```
{
    "request": {
        "operation": "WriteSingleCoilRequest",
    	"device": 1,
    	"address": 1,
    	"value": 1
    },
    "id": "TestRequest"
}
```
**回應範例：**  

```
{
    "response": {
        "status": "success",
        "device": 1,
    	"operation": "WriteSingleCoilRequest",
    	"payload": {
    	    "function_code": 5,
    	    "address": 1,
    	    "value": true
    	}
     },
     "id" : "TestRequest"
```

寫入單一暫存器  
**請求範例：**  

```
{
    "request": {
        "operation": "WriteSingleRegisterRequest",
    	"device": 1,
    	"address": 1,
    	"value": 1
    },
    "id": "TestRequest"
}
```

寫入多個線圈  
**請求範例：**  

```
{
    "request": {
        "operation": "WriteMultipleCoilsRequest",
    	"device": 1,
    	"address": 1,
    	"values": [1,0,0,1]
    },
    "id": "TestRequest"
}
```
**回應範例：**  

```
{
    "response": {
        "status": "success",
        "device": 1,
    	"operation": "WriteMultipleCoilsRequest",
    	"payload": {
    	    "function_code": 15,
    	    "address": 1,
    	    "count": 4
    	}
     },
     "id" : "TestRequest"
}
```

寫入多個暫存器  
**請求範例：**  

```
{
    "request": {
        "operation": "WriteMultipleRegistersRequest",
    	"device": 1,
    	"address": 1,
    	"values": [20,30,10]
    },
    "id": "TestRequest"
}
```
**回應範例：**  

```
{
    "response": {
        "status": "success",
        "device": 1,
    	"operation": "WriteMultipleRegistersRequest",
    	"payload": {
    	    "function_code": 23,
    	    "address": 1,
       		"count": 3
    	}
     },
     "id" : "TestRequest"
}
```

遮罩寫入暫存器  
**請求範例：**  

```
{
    "request": {
        "operation": "MaskWriteRegisterRequest",
    	"device": 1,
    	"address": 1,
        "and_mask": 175,
        "or_mask": 1
    },
    "id": "TestRequest"
}
```
**回應範例：**  

```
{
    "response": {
        "status": "success",
        "device": 1,
    	"operation": "MaskWriteRegisterRequest",
    	"payload": {
    	    "function_code": 22,
            "and_mask": 0,
            "or_mask": 8
    	}
     },
     "id" : "TestRequest"
}
```

讀寫多個暫存器  
**請求範例：**  

```
{
    "request": {
        "operation": "ReadWriteMultipleRegistersRequest",
    	"device": 1,
    	"read_address": 1,
        "read_count": 2,
        "write_address": 3,
        "write_registers": [20,30,40]
    },
    "id": "TestRequest"
}
```
**回應範例：**  

```
{
    "response": {
        "status": "success",
        "device": 1,
    	"operation": "ReadWriteMultipleRegistersRequest",
    	"payload": {
    	    "function_code": 23,
    	    "registers": [10,20,10,20]
    	}
     },
     "id" : "TestRequest"
}
```
這個回應中傳回的暫存器是要讀取的暫存器。

### 回應狀態：例外
<a name="modbus-protocol-adapter-connector-response-exception"></a>

當請求格式有效但請求未順利完成時會發生例外。在此情況下，回應包含下列資訊：
+ `status` 設定為 `Exception`。
+ `function_code` 等於請求的函數碼 \+ 128。
+ `exception_code` 包含例外碼。如需詳細資訊，請參閱 Modbus 例外碼。

**範例**：

```
{
    "response" : {
        "status" : "fail",
        "error_message": "Internal Error",
        "error": "Exception",
        "device": 1,
    	"operation": "ReadCoilsRequest",
    	"payload": {
        	"function_code": 129,
        	"exception_code": 2
    	}
     },
     "id" : "TestRequest"
}
```

### 回應狀態：沒有回應
<a name="modbus-protocol-adapter-connector-response-noresponse"></a>

此連接器會在 Modbus 請求上執行驗證檢查。例如，它檢查是否格式無效和遺漏欄位。如果驗證失敗，連接器不會傳送請求。而是傳回包含以下資訊的回應：
+ `status` 設定為 `No Response`。
+ `error` 包含錯誤的原因。
+ `error_message` 包含錯誤訊息。

**範例**：

```
{
    "response" : {
        "status" : "fail",
        "error_message": "Invalid address field. Expected <type 'int'>, got <type 'str'>",
        "error": "No Response",
        "device": 1,
    	"operation": "ReadCoilsRequest",
    	"payload": {
        	"error": "Invalid address field. Expected <type 'int'>, got <type 'str'>"
    	}
     },
     "id" : "TestRequest"
}
```

如果請求的目標是不存在的裝置，或 Modbus RTU 網路沒有作用，您可能會收到 `ModbusIOException` (使用「沒有回應」格式)。

```
{
    "response" : {
        "status" : "fail",
        "error_message": "[Input/Output] No Response received from the remote unit",
        "error": "No Response",
        "device": 1,
    	"operation": "ReadCoilsRequest",
    	"payload": {
        	"error": "[Input/Output] No Response received from the remote unit"
    	}
     },
     "id" : "TestRequest"
}
```

## 用量範例
<a name="modbus-protocol-adapter-connector-usage"></a>

<a name="connectors-setup-intro"></a>使用下列高階步驟來設定範例 Python 3.7 Lambda 函數，您可以用來嘗試連接器。

**注意**  <a name="connectors-setup-get-started-topics"></a>
如果您使用其他 Python 執行期，則可以建立從 Python3.x 到 Python 3.7 的符號連結。
[連接器入門 (主控台)](connectors-console.md) 和 [連接器入門 (CLI)](connectors-cli.md) 主題包含詳細步驟，說明如何設定和部署範例 Twilio 通知連接器。

1. 確定您符合連接器的[要求](#modbus-protocol-adapter-connector-req)。

1. <a name="connectors-setup-function"></a>建立並發佈 Lambda 函數，將輸入資料傳送至連接器。

   將[範例程式碼](#modbus-protocol-adapter-connector-usage-example)儲存為 PY 檔案。<a name="connectors-setup-function-sdk"></a>下載並解壓縮[AWS IoT Greengrass 適用於 Python 的 Core SDK](lambda-functions.md#lambda-sdks-core)。然後，建立在根層級包含 PY 檔案和 `greengrasssdk` 資料夾的 zip 套件。此 zip 套件是您上傳至 的部署套件 AWS Lambda。

   <a name="connectors-setup-function-publish"></a>建立 Python 3.7 Lambda 函數後，發佈函數版本並建立別名。

1. 設定 Greengrass 群組。

   1. <a name="connectors-setup-gg-function"></a>依別名新增 Lambda 函數 （建議）。將 Lambda 生命週期設定為長期 （或在 CLI `"Pinned": true`中）。

   1. <a name="connectors-setup-device-resource"></a>新增必要的本機裝置資源，並授予 Lambda 函數的讀取/寫入存取權。

   1. 新增連接器並設定其[參數](#modbus-protocol-adapter-connector-param)。

   1. 新增訂閱，允許連接器在支援主題篩選條件上接收[輸入資料](#modbus-protocol-adapter-connector-data-input)並傳送[輸出資料](#modbus-protocol-adapter-connector-data-output)。
      + <a name="connectors-setup-subscription-input-data"></a>將 Lambda 函數設定為來源，將連接器設定為目標，並使用支援的輸入主題篩選條件。
      + <a name="connectors-setup-subscription-output-data"></a>將連接器設為來源、將 AWS IoT Core 設為目標，並使用支援的輸出主題篩選條件。您可以使用此訂閱在 AWS IoT 主控台中檢視狀態訊息。

1. <a name="connectors-setup-deploy-group"></a>部署群組。

1. <a name="connectors-setup-test-sub"></a>在 AWS IoT 主控台**的測試**頁面上，訂閱輸出資料主題，以檢視連接器的狀態訊息。Lambda 函數範例為長期函數，並在部署群組後立即開始傳送訊息。

   完成測試後，您可以將 Lambda 生命週期設定為隨需 （或在 CLI `"Pinned": false`中） 並部署群組。這會讓函數停止傳送訊息。

### 範例
<a name="modbus-protocol-adapter-connector-usage-example"></a>

下列範例 Lambda 函數會將輸入訊息傳送至連接器。

```
import greengrasssdk
import json

TOPIC_REQUEST = 'modbus/adapter/request'

# Creating a greengrass core sdk client
iot_client = greengrasssdk.client('iot-data')

def create_read_coils_request():
	request = {
		"request": {
			"operation": "ReadCoilsRequest",
			"device": 1,
			"address": 1,
			"count": 1
		},
		"id": "TestRequest"
	}
	return request

def publish_basic_request():
	iot_client.publish(payload=json.dumps(create_read_coils_request()), topic=TOPIC_REQUEST)

publish_basic_request()

def lambda_handler(event, context):
	return
```

## 授權
<a name="modbus-protocol-adapter-connector-license"></a>

Modbus-RTU 通訊協定轉接器連接器包含下列第三方軟體/授權：
+ [pymodbus](https://github.com/riptideio/pymodbus/blob/master/README.rst)/BSD
+ [pyserial](https://github.com/pyserial/pyserial)/BSD

此連接器根據 [Greengrass 核心軟體授權合約](https://greengrass-release-license.s3.us-west-2.amazonaws.com/greengrass-license-v1.pdf)發行。

## 變更記錄
<a name="modbus-protocol-adapter-connector-changelog"></a>

下表說明每個版本連接器的變更。


| 版本 | 變更 | 
| --- | --- | 
| 3 | <a name="upgrade-runtime-py3.7"></a>將 Lambda 執行時間升級至 Python 3.7，這會變更執行時間需求。 | 
| 2 | 更新連接器 ARN 以取得 AWS 區域 支援。<br />改善錯誤記錄。 | 
| 1 | 初始版本。 | 

<a name="one-conn-version"></a>Greengrass 群組一次只能包含一個版本的連接器。若要取得有關升級連接器版本的資訊，請參閱[升級連接器版本](connectors.md#upgrade-connector-versions)。

## 另請參閱
<a name="modbus-protocol-adapter-connector-see-also"></a>
+ [使用 Greengrass 連接器來整合服務和通訊協定](connectors.md)
+ [Greengrass 連接器入門 (主控台)](connectors-console.md)
+ [Greengrass 連接器入門 (CLI)](connectors-cli.md)