前回の続きです。
Greengrass側で動作するPythonプログラムからAWS IoT Coreへメッセージをパブリッシュできました。
公式ドキュメントがまだ整ってないのでちょっと大変でした。
https://docs.aws.amazon.com/greengrass/v2/developerguide/interprocess-communication.html#ipc-iot-core-mqtt
環境
ハード:Raspberry Pi 4
OS:Raspberry Pi OS(32bit)
ディレクトリ構成
RaspberryPi
$ tree
.
├── artifacts
│ └── com.example.HelloWorld
│ └── 1.0.0
│ ├── hello_world.py
│ └── ipc_utils.py
└── recipes
└── com.example.HelloWorld-1.0.0.yaml
ソース
- ipc_utils.py
これは公式ドキュメントにも記載があります。
ipc_utils.py
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0
import os
from awscrt.io import (
ClientBootstrap,
DefaultHostResolver,
EventLoopGroup,
SocketDomain,
SocketOptions,
)
from awsiot.eventstreamrpc import Connection, LifecycleHandler, MessageAmendment
TIMEOUT = 10
class IPCUtils:
def connect(self):
elg = EventLoopGroup()
resolver = DefaultHostResolver(elg)
bootstrap = ClientBootstrap(elg, resolver)
socket_options = SocketOptions()
socket_options.domain = SocketDomain.Local
amender = MessageAmendment.create_static_authtoken_amender(os.getenv("SVCUID"))
hostname = os.getenv("AWS_GG_NUCLEUS_DOMAIN_SOCKET_FILEPATH_FOR_COMPONENT")
connection = Connection(
host_name=hostname,
port=8033,
bootstrap=bootstrap,
socket_options=socket_options,
connect_message_amender=amender,
)
self.lifecycle_handler = LifecycleHandler()
connect_future = connection.connect(self.lifecycle_handler)
connect_future.result(TIMEOUT)
return connection
- hello_world.py
Javaのサンプルを参考に、頑張ってみました。
hello_world.py
import awsiot.greengrasscoreipc.client as client
import awsiot.greengrasscoreipc.model as model
from ipc_utils import IPCUtils
import json
print("Start Lambda !!!")
ipc_utils = IPCUtils()
connection = ipc_utils.connect()
ipc_client = client.GreengrassCoreIPCClient(connection)
message = {"hello": "world"}
message = json.dumps(message).encode('utf-8')
request = ipc_client.new_publish_to_iot_core()
publishMessage = model.PublishToIoTCoreRequest(topic_name='test/topic', qos='1', payload=message)
future = request.activate(publishMessage)
result = future.result(timeout=10.0)
print("Finish Lambda !!!")
- com.example.HelloWorld-1.0.0.yaml
レシピの書き方が大苦戦。。
accessControlのところはaws.greengrass.ipc.mqttproxy
、
operationsがaws.greengrass#PublishToIoTCore
、
resourcesがトピック名です。
Greengrass 1.0のころのサブスクリプションのイメージですね。
com.example.HelloWorld-1.0.0.yaml
---
RecipeFormatVersion: '2020-01-25'
ComponentName: com.example.HelloWorld
ComponentVersion: '1.0.0'
ComponentDescription: A component that publishes messages.
ComponentPublisher: Amazon
ComponentConfiguration:
DefaultConfiguration:
accessControl:
aws.greengrass.ipc.mqttproxy:
"com.example.HelloWorld:pubsub:1":
policyDescription: Allows access to publish to test/topic.
operations:
- "aws.greengrass#PublishToIoTCore"
resources:
- "test/topic"
Manifests:
- Lifecycle:
Install:
Timeout: 1000
Script: pip3 install awsiotsdk
Run: |
python3 {artifacts:path}/hello_world.py
デプロイ
Greengrass 2.0の特徴で、**「Lambdaにデプロイせずにローカルでデプロイできる」**機能があります。
RaspberryPi
sudo /greengrass/v2/bin/greengrass-cli \
--ggcRootPath=/greengrass/v2 \
deployment create \
--recipeDir recipes \
--artifactDir artifacts \
--merge "com.example.HelloWorld=1.0.0"
おめでとうございます!!!