Amazon IoT Greengrass Version 1 2023 年 6 月 30 日进入延长寿命阶段。有关更多信息,请参阅 Amazon IoT Greengrass V1 维护策略。在此日期之后,将 Amazon IoT Greengrass V1 不会发布提供功能、增强功能、错误修复或安全补丁的更新。在上面运行的设备 Amazon IoT Greengrass V1 不会中断,将继续运行并连接到云端。我们强烈建议您迁移到 Amazon IoT Greengrass Version 2,这样可以添加重要的新功能并支持其他平台。
本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。
Modbus-RTU 协议适配器连接器
Modbus-RTU 协议适配器连接器从 Amazon IoT Greengrass 组中的 Modbus RTU 设备轮询信息。
此连接器从用户定义的 Lambda 函数接收 Modbus RTU 请求的参数。它发送相应的请求,然后从目标设备发布响应作为 MQTT 消息。
此连接器具有以下版本。
版本 |
ARN |
---|---|
3 |
|
2 |
|
1 |
|
有关版本更改的信息,请参阅更改日志。
要求
此连接器具有以下要求:
连接器参数
此连接器支持以下参数:
ModbusSerialPort-ResourceId
-
表示物理 Modbus 串行端口的本地设备资源的 ID。
注意
连接器被授予对该资源的读写访问权限。
Amazon IoT 控制台中的显示名称:Modbus 串行端口资源
必需:
true
类型:
string
有效模式:
.+
ModbusSerialPort
-
设备上的物理 Modbus 串行端口的绝对路径。这是为 Modbus 本地设备资源指定的源路径。
Amazon IoT 控制台中的显示名称:Modbus 串口资源的源路径
必需:
true
类型:
string
有效模式:
.+
创建连接器示例 (Amazon 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 函数的生命周期很长。
在 Amazon IoT Greengrass 控制台中,您可以从组的连接器页面添加连接器。有关更多信息,请参阅 Greengrass 连接器入门(控制台)。
注意
部署 Modbus-RTU 协议适配器连接器后,您可以使用 Amazon IoT Things Graph 协调组中设备之间的交互。有关更多信息,请参阅 Amazon IoT Things Graph 用户指南中的 Modbus。
输入数据
此连接器从用户定义的 Lambda 函数接受关于 MQTT 主题的 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。
- 示例输出:成功
-
{ "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 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 运行时,您可以创建从 Python3.x 到 Python 3.7 的符号链接。
-
连接器入门(控制台) 和 连接器入门 (CLI) 主题包含详细步骤,说明如何配置和部署示例 Twilio 通知连接器。
确保满足连接器的要求。
-
创建并发布将输入数据发送到连接器的 Lambda 函数。
将示例代码保存为 PY 文件。下载并解压适用于 Python 的 Amazon IoT Greengrass Core 软件开发工具包。然后,创建一个 zip 包,其中在根级别包含 PY 文件和
greengrasssdk
文件夹。此 zip 包是您上传到 Amazon Lambda 的部署包。创建 Python 3.7 Lambda 函数后,请发布函数版本并创建别名。
-
配置 Greengrass 组。
-
部署组。
-
在 Amazon IoT 控制台中,在测试页面上,订阅输出数据主题以查看连接器中的状态消息。示例 Lambda 函数是长时间生存的,并且在部署组后立即开始发送消息。
完成测试后,您可以将 Lambda 生命周期设置为按需(或在 CLI 中设置为
"Pinned": false
)并部署组。这会阻止函数发送消息。
示例
以下示例 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 软件许可协议
更改日志
下表介绍每个版本连接器的更改。
版本 |
更改 |
---|---|
3 |
已将 Lambda 运行时升级到 Python 3.7,这会更改运行时要求。 |
2 |
更新了连接器 ARN 以获得 Amazon Web Services 区域 支持。 改进了错误日志记录。 |
1 |
首次发布。 |
Greengrass 组在一个时间上只能包含一个版本的连接器。有关升级连接器版本的信息,请参阅升级连接器版本。