Modbus-RTU 프로토콜 어댑터 커넥터 - AWS IoT Greengrass

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 Protocol Adapter 커넥터는 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를 참조하십시오.

요구 사항

이 커넥터에는 다음과 같은 요구 사항이 있습니다.

Version 3
  • AWS IoT Greengrass 코어 소프트웨어 v1.9.3 이상.

  • 코어 디바이스에 설치되고 PATH 환경 변수에 추가된 Python 버전 3.7 또는 3.8입니다.

    참고

    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 요구 사항을 충족하도록 디바이스가 구성됩니다.

  • AWS IoT Greengrass 코어와 Modbus 디바이스 간의 물리적 연결입니다. 코어는 직렬 포트(예: USB 포트)를 통해 Modbus RTU 네트워크에 물리적으로 연결해야 합니다.

  • 물리적 Modbus 직렬 포트를 가리키는 Greengrass 그룹의 로컬 디바이스 리소스입니다.

  • Modbus RTU 요청 파라미터를 이 커넥터에 전송하는 사용자 정의 Lambda 함수입니다. 요청 파라미터는 예상 패턴을 따라야 하며 Modbus RTU 네트워크에 있는 대상 디바이스의 ID와 주소를 포함해야 합니다. 자세한 내용은 입력 데이터 섹션을 참조하세요.

Versions 1 - 2
  • AWS IoT Greengrass 코어 소프트웨어 v1.7 이상.

  • 코어 디바이스에 설치되고 PATH 환경 변수에 추가된 Python 버전 3.7입니다.

  • AWS IoT Greengrass와 Modbus 장치 간의 물리적 연결입니다. 코어는 직렬 포트(예: USB 포트)를 통해 Modbus RTU 네트워크에 물리적으로 연결해야 합니다.

  • 물리적 Modbus 직렬 포트를 가리키는 Greengrass 그룹의 로컬 디바이스 리소스입니다.

  • Modbus RTU 요청 파라미터를 이 커넥터에 전송하는 사용자 정의 Lambda 함수입니다. 요청 파라미터는 예상 패턴을 따라야 하며 Modbus RTU 네트워크에 있는 대상 디바이스의 ID와 주소를 포함해야 합니다. 자세한 내용은 입력 데이터 섹션을 참조하세요.

커넥터 파라미터

이 커넥터는 다음 파라미터를 지원합니다.

ModbusSerialPort-ResourceId

물리적 Modbus 직렬 포트를 나타내는 로컬 디바이스 리소스의 ID입니다.

참고

이 커넥터에는 리소스에 대한 쓰기 전용 액세스 권한이 부여됩니다.

AWS IoT 콘솔의 표시 이름: Modbus 직렬 포트 리소스

필수: true

형식: string

유효한 패턴: .+

ModbusSerialPort

디바이스에 있는 물리적 Modbus 직렬 포트의 절대 경로입니다. Modbus 로컬 디바이스 리소스에 대해 지정된 소스 경로입니다.

AWS IoT 콘솔의 표시 이름: Modbus 직렬 포트 리소스의 소스 경로

필수: true

형식: string

유효한 패턴: .+

커넥터 만들기 예(AWS CLI)

다음 CLI 명령은 Modbus-RTU Protocol Adapter 커넥터가 포함된 초기 버전을 사용하여 ConnectorDefinition을 생성합니다.

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 Protocol Adapter 커넥터를 배포한 후 AWS IoT Things Graph를 사용하여 그룹의 디바이스 간의 상호 작용을 조정할 수 있습니다. 자세한 내용을 알아보려면 AWS IoT Things Graph사용 설명서Modbus를 참조하세요.

입력 데이터

이 커넥터는 MQTT 주제에 대한 사용자 정의 Lambda 함수로부터 Modbus RTU 요청 파라미터를 수락합니다. 입력 메시지는 JSON 형식이어야 합니다.

구독의 주제 필터

modbus/adapter/request

메시지 속성

요청 메시지는 메시지가 나타내는 Modbus RTU 요청 유형에 따라 다릅니다. 다음은 모든 요청에 필수적인 속성입니다.

  • request 객체에서:

    • operation. 실행할 작업의 이름입니다. 예를 들어, 코일을 읽도록 "operation": "ReadCoilsRequest"를 지정합니다. 이 값은 유니코드 문자열이어야 합니다. 지원되는 작업 목록은 Modbus RTU 요청 및 응답 단원을 참조하십시오.

    • device. 요청의 대상 디바이스입니다. 이 값은 0 - 247 범위여야 합니다.

  • id 속성입니다. 요청의 ID입니다. 이 값은 데이터 중복 제거에 사용되며 오류 응답을 포함하여 모든 응답의 id 속성에 있는 그대로 반환됩니다. 이 값은 유니코드 문자열이어야 합니다.

참고

요청에 주소 필드가 포함된 경우 값을 정수로 지정해야 합니다. 예: "address": 1.

요청에 포함할 다른 파라미터는 작업에 따라 다릅니다. 따로 처리되는 CRC를 제외하고 모든 요청 파라미터가 필수입니다. 예를 보려면 예제 요청 및 응답 섹션을 참조하세요.

입력 예: 코일 요청 읽기
{ "request": { "operation": "ReadCoilsRequest", "device": 1, "address": 1, "count": 1 }, "id": "TestRequest" }

출력 데이터

이 커넥터는 수신 Modbus RTU 요청에 대한 응답을 게시합니다.

구독의 주제 필터

modbus/adapter/response

메시지 속성

응답 메시지의 형식은 해당 요청 및 응답 상태에 따라 다릅니다. 예를 보려면 예제 요청 및 응답 섹션을 참조하세요.

참고

쓰기 작업에 대한 응답은 단순히 요청의 에코일 뿐입니다. 쓰기 응답에 대해 의미 있는 정보가 반환되지 않더라도 응답의 상태를 확인하는 것이 좋습니다.

모든 응답에는 다음 속성이 포함됩니다.

  • response 객체에서:

    • status. 요청 상태입니다. 상태는 다음 값 중 하나일 수 있습니다.

      • Success. 요청이 올바르고, Modbus RTU 네트워크에 전송되었으며, 응답이 반환되었습니다.

      • Exception. 요청이 올바르고, Modbus RTU 네트워크에 전송되었으며, 예외 응답이 반환되었습니다. 자세한 내용은 응답 상태: 예외 섹션을 참조하세요.

      • No Response. 요청이 잘못되었고, 요청이 Modbus RTU 네트워크를 통해 전송되기 전에 커넥터에서 오류가 발견되었습니다. 자세한 내용은 응답 상태: 응답 없음 섹션을 참조하세요.

    • device. 요청이 전송된 디바이스입니다.

    • operation. 전송된 요청 유형입니다.

    • payload. 반환된 응답 콘텐츠입니다. statusNo 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" }
참고

이 응답에서 반환된 레지스터는 읽은 레지스터입니다.

요청 형식이 올바르지만 요청이 성공적으로 완료되지 않으면 예외가 발생합니다. 이 경우 응답에는 다음 정보가 포함됩니다.

  • statusException으로 설정됩니다.

  • 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 요청에 대해 확인 점검을 수행합니다. 예를 들어 잘못된 형식과 누락된 필드가 있는지 점검합니다. 확인이 실패하면 커넥터는 요청을 전송하지 않습니다. 그 대신 다음 정보가 포함된 응답을 반환합니다.

  • statusNo 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 알림 커넥터를 구성하고 배포하는 방법을 보여주는 자세한 단계가 포함되어 있습니다.

  1. 커넥터에 대한 요구 사항을 충족하는지 확인합니다.

  2. 입력 데이터를 커넥터로 보내는 Lambda 함수를 생성하고 게시합니다.

    예제 코드를 PY 파일로 저장합니다. Python용 AWS IoT Greengrass 코어 SDK를 다운로드하고 압축을 풉니다. 그런 다음 루트 수준에서 PY 파일과 greengrasssdk 폴더를 포함하는 zip 패키지를 생성합니다. 이 zip 패키지는 AWS Lambda에 업로드하는 배포 패키지입니다.

    Python 3.7 Lambda 함수를 생성한 후 함수 버전을 게시하고 별칭을 만듭니다.

  3. Greengrass 그룹을 구성합니다.

    1. 별칭으로 Lambda 함수를 추가합니다(권장). Lambda 수명 주기를 수명이 긴 함수(또는 CLI의 "Pinned": true)로 구성합니다.

    2. 필요한 로컬 디바이스 리소스를 추가하고 Lambda 함수에 대한 읽기/쓰기 액세스 권한을 부여합니다.

    3. 커넥터를 추가하고 해당 파라미터를 구성합니다.

    4. 커넥터가 입력 데이터를 수신하고 지원되는 주제 필터에서 출력 데이터를 전송할 수 있도록 허용하는 구독을 추가합니다.

      • Lambda 함수를 소스로, 커넥터를 대상으로 설정하고 지원되는 입력 주제 필터를 사용합니다.

      • 커넥터를 소스로, AWS IoT Core를 대상으로 설정하고 지원되는 출력 주제 필터를 사용합니다. 이 구독을 사용하여 AWS IoT에서 상태 메시지를 확인합니다.

  4. 그룹을 배포합니다.

  5. AWS 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 Protocol Adapter 커넥터에는 다음 타사 소프트웨어/라이선스가 포함되어 있습니다.

이 커넥터는 Greengrass 코어 소프트웨어 라이선스 계약에 따라 릴리스됩니다.

Changelog

다음 표에서는 의 각 릴리스에서 변경된 중요 사항에 대해 설명합니다.

버전

변경

3

Lambda 런타임 요구 사항을 변경하는 Python 3.7로 런타임을 업그레이드했습니다.

2

AWS 리전 지원용 커넥터 ARN이 업데이트됨.

오류 로깅을 개선함.

1

최초 릴리스.

Greengrass 그룹은 한 번에 하나의 커넥터 버전만 포함할 수 있습니다. 커넥터 버전 업그레이드에 대한 자세한 내용은 커넥터 버전 업그레이드 단원을 참조하십시오.

다음 사항도 참조하세요.