AWS IoT Greengrass Version 1 於 2023 年 6 月 30 日進入延長生命週期階段。如需詳細資訊,請參閱 AWS IoT Greengrass V1 維護政策。在此日期之後, AWS IoT Greengrass V1 不會發佈提供功能、增強功能、錯誤修正或安全修補程式的更新。在 上執行的裝置 AWS IoT Greengrass V1 不會中斷,且會繼續運作並連線至雲端。我們強烈建議您遷移至 AWS IoT Greengrass Version 2 ,這會新增重要的新功能,並支援其他平台。
本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。
Modbus-RTU 通訊協定配接器
Modbus-RTU 通訊協定配接器連接器會輪詢來自中 Modbus RTU 裝置的資訊AWS IoT Greengrass群組。
此連接器會從使用者定義的 Lambda 函數接收 Modbus RTU 請求的參數。它會傳送對應的請求,然後從目標裝置發佈回應做為 MQTT 訊息。
此連接器具有下列版本。
版本 |
ARN |
---|---|
3 |
|
2 |
|
1 |
|
如需版本變更的詳細資訊,請參閱 Changelog。
要求
此連接器有下列要求:
連接器參數
此連接器支援下列參數:
ModbusSerialPort-ResourceId
-
代表實體 Modbus 序列埠的本機裝置資源 ID。
注意
此連接器已授予資源的讀寫存取權。
中的顯示名稱AWS IoT主控台:Modbus 序列埠資源
必要:
true
類型:
string
有效模式:
.+
ModbusSerialPort
-
裝置上實體 Modbus 序列埠的絕對路徑。這是指定給 Modbus 本機裝置資源的來源路徑。
中的顯示名稱AWS IoT主控台:Modbus 序列埠資源的來源路徑
必要:
true
類型:
string
有效模式:
.+
建立範例連接器 (AWS CLI)
以下 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 函數具有長期生命週期。
在 中AWS IoT Greengrass主控台,您可以從群組中新增連接器連接器(憑證已建立!) 頁面上的名稱有些許差異。如需詳細資訊,請參閱 Greengrass 連接器入門 (主控台)。
注意
在部署 Modbus-RTU 通訊協定配接器連接器後,您可以使用AWS IoT Things Graph以協調群組中裝置之間的互動。如需詳細資訊,請參閱「」Modbus中的AWS IoT Things Graph使用者指南。
輸入資料
此連接器會在 MQTT 主題上接受使用者定義 Lambda 函數的 Modbus RTU 請求參數。輸入訊息必須是 JSON 格式。
- 訂閱中的主題篩選條件
-
modbus/adapter/request
- 訊息屬性
-
請求訊息隨著其所代表的 Modbus RTU 請求類型而不同。所有請求需要下列屬性:
-
在
request
物件中:-
operation
。 要執行的作業名稱。例如,指定"operation": "ReadCoilsRequest"
以讀取線圈。這個值必須是 Unicode 字串。如需支援的作業,請參閱 Modbus RTU 請求和回應。 -
device
。 請求的目標裝置。此值必須介於0 - 247
之間。
-
-
id
屬性。請求的 ID。這個值用於重複資料刪除,並在所有回應的id
屬性中依現狀傳回,包括錯誤回應。這個值必須是 Unicode 字串。
注意
如果您的請求中包含地址欄位,則必須將該值指定為整數。例如
"address": 1
。要包含在請求中的其他參數取決於操作。除了 CRC (另外處理),所有請求參數都是必要。如需範例,請參閱範例請求和回應。
-
- 範例輸入:讀取線圈請求
-
{ "request": { "operation": "ReadCoilsRequest", "device": 1, "address": 1, "count": 1 }, "id": "TestRequest" }
輸出資料
此連接器將回應發佈到傳入 Modbus RTU 請求。
- 訂閱中的主題篩選條件
-
modbus/adapter/response
- 訊息屬性
-
回應訊息的格式根據對應的請求和回應狀態而不同。如需範例,請參閱範例請求和回應。
注意
寫入操作的回應只是請求的回響。雖然寫入回應沒有傳回有意義的資訊,建議檢查回應的狀態。
每個回應含有以下屬性:
在
response
物件中:-
status
。 請求的狀態。狀態可以是下列其中一個值: -
device
。 請求傳送到的裝置。 -
operation
。 傳送的請求類型。 -
payload
。 傳回的回應內容。如果status
是No Response
,此物件只包含error
屬性和錯誤描述 (例如,"error": "[Input/Output] No Response received from the remote unit"
)。
-
id
屬性。用於資料重複刪除的請求 ID。
- 輸出範例:Success
-
{ "response" : { "status" : "success", "device": 1, "operation": "ReadCoilsRequest", "payload": { "function_code": 1, "bits": [1] } }, "id" : "TestRequest" }
- 輸出範例:Failure (失敗)
-
{ "response" : { "status" : "fail", "error_message": "Internal Error", "error": "Exception", "device": 1, "operation": "ReadCoilsRequest", "payload": { "function_code": 129, "exception_code": 2 } }, "id" : "TestRequest" }
如需更多範例,請參閱 範例請求和回應。
Modbus RTU 請求和回應
此連接器接受 Modbus RTU 請求參數做為輸入資料,並發佈回應做為輸出資料。
以下是支援的常見操作。
請求中的作業名稱 | 回應中的函數代碼 |
---|---|
ReadCoilsRequest | 01 |
ReadDiscreteInputsRequest | 02 |
ReadHoldingRegistersRequest | 03 |
ReadInputRegistersRequest | 04 |
WriteSingleCoilRequest | 05 |
WriteSingleRegisterRequest | 06 |
WriteMultipleCoilsRequest | 15 |
WriteMultipleRegistersRequest | 16 |
MaskWriteRegisterRequest | 22 |
ReadWriteMultipleRegistersRequest | 23 |
以下是受支援操作的範例請求和回應。
- 讀取線圈
請求範例:
{ "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" }
注意
這個回應中傳回的暫存器是要讀取的暫存器。
當請求格式有效但請求未順利完成時會發生例外。在此情況下,回應包含下列資訊:
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" }
此連接器會在 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" }
使用範例
使用下列高階步驟,設定可用來試用連接器的範例 Python 3.7 Lambda 函數。
注意
-
如果您使用其他 Python 運行時間,則可以建立從 Python 3.x 到 Python 3.7 的符號連結。
-
連接器入門 (主控台) 和 連接器入門 (CLI) 主題包含詳細步驟,說明如何設定和部署範例 Twilio 通知連接器。
確定您符合連接器的要求。
-
建立並發佈將輸入資料傳送至連接器的 Lambda 函數。
將範例程式碼儲存為 PY 檔案。下載並解壓縮AWS IoT GreengrassSDK。然後,建立在根層級包含 PY 檔案和
greengrasssdk
資料夾的 zip 套件。此 zip 套件是您上傳至的部署套件AWS Lambda。建立 Python 3.7 Lambda 函數後,請發佈函數版本並建立別名。
-
設定 Greengrass 群組。
-
部署群組。
-
在 中AWS IoT主控台、測試頁面中,訂閱輸出資料主題以檢視來自連接器的狀態訊息。範例 Lambda 函數具有長時間的生命周期,而且在部署完群組後會立即開始傳送訊息。
完成測試後,您可以將 Lambda 生命週期設為隨需 (或
"Pinned": false
在 CLI 中設為) 並部署群組。這會讓函數停止傳送訊息。
範例
下列範例 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
授權
Modbus RTU 通訊協定介面卡連接器包含以下第三方軟體/授權:
此連接器會在Greengrass Core 軟體授權合約
Changelog
下表說明連接器每個版本的變更。
版本 |
變更 |
---|---|
3 |
已將 Lambda 執行時間升級至 Python 3.7,這會改變執行時間要求。 |
2 |
更新的連接器 ARNAWS 區域支援 t。 改善錯誤記錄。 |
1 |
初始版本。 |
Greengrass 群組一次只能包含連接器的一個版本。若要取得有關升級連接器版本的資訊,請參閱升級連接器版本。