Skip to content

Commit 43c6330

Browse files
committed
add Greengrass IPC sample to publish to IoT Core
1 parent 1c0cf45 commit 43c6330

File tree

3 files changed

+165
-1
lines changed

3 files changed

+165
-1
lines changed

awsiot/greengrasscoreipc/__init__.py

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
# SPDX-License-Identifier: Apache-2.0.
3+
4+
import os
5+
from typing import Optional
6+
7+
from awscrt.io import (
8+
ClientBootstrap,
9+
DefaultHostResolver,
10+
EventLoopGroup,
11+
SocketDomain,
12+
SocketOptions,
13+
)
14+
from awsiot.eventstreamrpc import (
15+
Connection,
16+
LifecycleHandler,
17+
MessageAmendment,
18+
)
19+
from awsiot.greengrasscoreipc.client import GreengrassCoreIPCClient
20+
21+
22+
def connect(*,
23+
hostname: str=None,
24+
port=8033,
25+
authtoken: str=None,
26+
lifecycle_handler: Optional[LifecycleHandler]=None,
27+
timeout=10) -> GreengrassCoreIPCClient:
28+
"""
29+
Creates an IPC client and connects to the GreengrassCoreIPC service.
30+
31+
Args:
32+
hostname: Remote hostname, defaults to environment variable AWS_GG_NUCLEUS_DOMAIN_SOCKET_FILEPATH_FOR_COMPONENT
33+
port: Remote port
34+
authtoken: Authentication token, defaults to environment variable SVCUID
35+
lifecycle_handler: Handler for events over the course of this
36+
network connection. See :class:`LifecycleHandler` for more info.
37+
Handler methods will only be invoked if the connect attempt
38+
succeeds.
39+
timeout: The number of seconds to wait for establishing the connection.
40+
41+
Returns:
42+
Client for the GreengrassCoreIPC service.
43+
"""
44+
45+
if not authtoken:
46+
authtoken = os.environ["SVCUID"]
47+
if not hostname:
48+
hostname = os.environ["AWS_GG_NUCLEUS_DOMAIN_SOCKET_FILEPATH_FOR_COMPONENT"]
49+
if not lifecycle_handler:
50+
lifecycle_handler = LifecycleHandler()
51+
52+
elg = EventLoopGroup()
53+
resolver = DefaultHostResolver(elg)
54+
bootstrap = ClientBootstrap(elg, resolver)
55+
socket_options = SocketOptions()
56+
socket_options.domain = SocketDomain.Local
57+
amender = MessageAmendment.create_static_authtoken_amender(authtoken)
58+
59+
connection = Connection(
60+
host_name=hostname,
61+
port=port,
62+
bootstrap=bootstrap,
63+
socket_options=socket_options,
64+
connect_message_amender=amender,
65+
)
66+
connect_future = connection.connect(lifecycle_handler)
67+
connect_future.result(timeout)
68+
69+
return GreengrassCoreIPCClient(connection)

samples/README.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
* [shadow](#shadow)
55
* [fleet provisioning](#fleet-provisioning)
66
* [basic discovery](#basic-discovery)
7+
* [IPC with AWS IoT Greengrass to publish to AWS IoT Core](#ipc-greengrass)
78

89
## pubsub
910
This sample uses the
@@ -394,5 +395,11 @@ python3 fleetprovisioning.py --endpoint [your endpoint]-ats.iot.[region].amazona
394395

395396
## basic discovery
396397

397-
This sample intended for use directly with the
398+
This sample is intended for use directly with the
398399
[Getting Started with AWS IoT Greengrass](https://docs.aws.amazon.com/greengrass/latest/developerguide/gg-gs.html) guide.
400+
401+
## IPC with AWS IoT Greengrass to publish to AWS IoT Core
402+
403+
This sample is intended to be deployed as an AWS IoT Greengrass component and it will publish MQTT messages from the device to AWS IoT Core.
404+
405+
Source: `samples/ipc_greengrass.py`

samples/ipc_greengrass.py

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
# SPDX-License-Identifier: Apache-2.0.
3+
4+
"""
5+
This sample uses AWS IoT Greengrass v2 to publish messages from the device to
6+
the AWS IoT Core MQTT broker.
7+
8+
This example can be deployed as Greengrass v2 component and it will start
9+
publishing telemetry data as MQTT messages in periodic intervals. The IPC
10+
integration with Greegrass v2 allows this code to run without additional IoT
11+
certificates or secrets, because it directly communicates with Greengrass Core
12+
on the device.
13+
14+
See this page for more information on Greengrass v2 components:
15+
https://docs.aws.amazon.com/greengrass/v2/developerguide/create-components.html
16+
17+
See this page for more information on IPC in Greengrass v2:
18+
https://docs.aws.amazon.com/greengrass/v2/developerguide/interprocess-communication.html
19+
20+
To run the sample, create a new AWS IoT Greengrass component and deploy it to
21+
your device with the following recipe snippet to allow your device to publish to
22+
the AWS IoT Core MQTT broker:
23+
24+
```json
25+
...
26+
"ComponentConfiguration": {
27+
"DefaultConfiguration": {
28+
"accessControl": {
29+
"aws.greengrass.ipc.mqttproxy": {
30+
"Your.Component.Name:mqttproxy:1": {
31+
"policyDescription": "Allows access to publish to all AWS IoT Core topics.",
32+
"operations": [
33+
"aws.greengrass#PublishToIoTCore"
34+
],
35+
"resources": [
36+
"*"
37+
]
38+
}
39+
}
40+
}
41+
}
42+
},
43+
...
44+
```
45+
(replace `Your.Component.Name` with your component name)
46+
47+
You can use this recipe `Manifest` snippet to install Python and `AWS IoT Device
48+
SDK v2 for Python` as dependency:
49+
```json
50+
...
51+
"Manifests": [{
52+
...
53+
"Lifecycle": {
54+
"Install": {
55+
"RequiresPrivilege": true,
56+
"Script": "apt-get update --quiet && apt-get --yes install python3 python3-pip && pip3 install awsiotsdk"
57+
},
58+
...
59+
```
60+
"""
61+
62+
import json
63+
import time
64+
65+
import awsiot.greengrasscoreipc
66+
import awsiot.greengrasscoreipc.model as model
67+
68+
if __name__ == '__main__':
69+
ipc_client = awsiot.greengrasscoreipc.connect()
70+
71+
while True:
72+
telemetry_data = {
73+
"health": True,
74+
"battery_state_of_charge": 42.5,
75+
"location": {
76+
"longitude": 48.15743,
77+
"latitude": 11.57549,
78+
},
79+
}
80+
81+
op = ipc_client.new_publish_to_iot_core()
82+
op.activate(model.PublishToIoTCoreRequest(
83+
topic_name="my/iot/telemetry",
84+
qos=model.QOS.AT_LEAST_ONCE,
85+
payload=json.dumps(telemetry_data).encode(),
86+
))
87+
88+
time.sleep(5)

0 commit comments

Comments
 (0)