Skip to content

Commit 7265849

Browse files
committed
add Greengrass IPC sample to publish to IoT Core
1 parent dc07d9b commit 7265849

File tree

3 files changed

+170
-1
lines changed

3 files changed

+170
-1
lines changed

awsiot/greengrasscoreipc/__init__.py

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
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+
ipc_socket: str=None,
24+
authtoken: str=None,
25+
lifecycle_handler: Optional[LifecycleHandler]=None,
26+
timeout=10.0) -> GreengrassCoreIPCClient:
27+
"""
28+
Creates an IPC client and connects to the GreengrassCoreIPC service.
29+
30+
Args:
31+
ipc_socket: Path to the Unix domain socket of Greengrass Nucleus, defaults to
32+
environment variable AWS_GG_NUCLEUS_DOMAIN_SOCKET_FILEPATH_FOR_COMPONENT
33+
authtoken: Authentication token, defaults to environment variable SVCUID
34+
lifecycle_handler: Handler for events over the course of this
35+
network connection. See :class:`LifecycleHandler` for more info.
36+
Handler methods will only be invoked if the connect attempt
37+
succeeds.
38+
timeout: The number of seconds to wait for establishing the connection.
39+
40+
Returns:
41+
Client for the GreengrassCoreIPC service.
42+
"""
43+
44+
if not ipc_socket:
45+
ipc_socket = os.environ["AWS_GG_NUCLEUS_DOMAIN_SOCKET_FILEPATH_FOR_COMPONENT"]
46+
if not authtoken:
47+
authtoken = os.environ["SVCUID"]
48+
if not lifecycle_handler:
49+
lifecycle_handler = LifecycleHandler()
50+
51+
elg = EventLoopGroup(num_threads=1)
52+
resolver = DefaultHostResolver(elg)
53+
bootstrap = ClientBootstrap(elg, resolver)
54+
socket_options = SocketOptions()
55+
socket_options.domain = SocketDomain.Local
56+
amender = MessageAmendment.create_static_authtoken_amender(authtoken)
57+
58+
connection = Connection(
59+
host_name=ipc_socket,
60+
port=0, # dummy port number, not needed for Unix domain sockets
61+
bootstrap=bootstrap,
62+
socket_options=socket_options,
63+
connect_message_amender=amender,
64+
)
65+
connect_future = connection.connect(lifecycle_handler)
66+
connect_future.result(timeout)
67+
68+
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: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
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+
import os
65+
66+
import awsiot.greengrasscoreipc
67+
import awsiot.greengrasscoreipc.model as model
68+
69+
if __name__ == '__main__':
70+
ipc_client = awsiot.greengrasscoreipc.connect()
71+
72+
while True:
73+
telemetry_data = {
74+
"timestamp": int(round(time.time() * 1000)),
75+
"battery_state_of_charge": 42.5,
76+
"location": {
77+
"longitude": 48.15743,
78+
"latitude": 11.57549,
79+
},
80+
}
81+
82+
op = ipc_client.new_publish_to_iot_core()
83+
op.activate(model.PublishToIoTCoreRequest(
84+
topic_name="my/iot/{}/telemetry".format(os.getenv("AWS_IOT_THING_NAME")),
85+
qos=model.QOS.AT_LEAST_ONCE,
86+
payload=json.dumps(telemetry_data).encode(),
87+
))
88+
try:
89+
result = op.get_response().result(timeout=5.0)
90+
print("successfully published message:", result)
91+
except Exception as e:
92+
print("failed to publish message:", e)
93+
94+
time.sleep(5)

0 commit comments

Comments
 (0)