-
Notifications
You must be signed in to change notification settings - Fork 211
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add Greengrass V2 IPC samples using new IPC-Client V2
- Loading branch information
Showing
12 changed files
with
593 additions
and
54 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
# Greengrass V2 samples using AWS IoT Device SDK v2 for Python | ||
|
||
You can find the full API documentation for the Greengrass V2 IPC interface using the Python SDK here: https://aws.github.io/aws-iot-device-sdk-python-v2/awsiot/greengrasscoreipc.html | ||
|
||
## Sample: Low-Level IPC | ||
|
||
Folder: `low_level_ipc/` | ||
|
||
Once installed and running, this sample publishes messages to AWS IoT Core. It uses the low-level Greengrass v2 [Inter-Process-Communication API](https://docs.aws.amazon.com/greengrass/v2/developerguide/interprocess-communication.html). | ||
|
||
See the other samples for higher-level APIs to reduce the amount of code you have to write and maintain. | ||
|
||
## Sample: Publish/Subscribe to the cloud with AWS IoT Core | ||
|
||
Folder: `pubsub_cloud` | ||
|
||
Once installed and running, this sample subscribes to the `hello/world` topic. You can use the [MQTT Test Client](https://console.aws.amazon.com/iot/home#/test) to publish a message to this topic, while also subscribing to `hello/world/response` in the MQTT Test Client. The Greengrass device will receive the message and reply back on the response topic. | ||
|
||
## Sample: Public/Subscribe on the local device between Greengrass components | ||
|
||
Folder: `pubsub_local` | ||
|
||
Once installed and running, this sample subscribes to the `hello/world` topic. You can use a second component to publish a message and receive a reply message on the `hello/world/response` topic. These messages are **not** sent to AWS IoT Core (the cloud). This pub/sub mechanism is only connecting different components running on the same Greengrass device. You can use the Greegrass CLI to publish or subscribe to these local topics: | ||
|
||
* `greengrass-cli pubsub sub --topic hello/world/response` | ||
* `greengrass-cli pubsub pub --topic hello/world --message Hi!` | ||
|
||
## Sample: Shadow Management | ||
|
||
Folder: `shadows` | ||
|
||
Once installed and running, this sample will retrieve a named shadow `special_shadow` when the component first starts executing, and then periodically update the shadow document with a new reported state every few seconds. | ||
|
||
This component depends on the [AWS-provided ShadowManager component](https://docs.aws.amazon.com/greengrass/v2/developerguide/shadow-manager-component.html#shadow-manager-component-configuration). You [need to configure](https://docs.aws.amazon.com/greengrass/v2/developerguide/shadow-manager-component.html#shadow-manager-component-configuration) it to synchronize named shadows from the local device to the cloud: | ||
|
||
```yaml | ||
strategy: | ||
type: realTime | ||
synchronize: | ||
coreThing: | ||
namedShadows: | ||
- special_shadow | ||
direction: betweenDeviceAndCloud | ||
``` | ||
## Sample: Deployment Configuration | ||
Folder: `deployment_configuration` | ||
|
||
Once installed and running, this sample will retrieve the component's deployment configuration and start a web server based on the provided parameters. Re-deploying with different parameters will update the component and upon restart of the Python process, it will start the web server based on these new parameters. | ||
|
||
## Deployment Helpers | ||
|
||
Deploy component locally using Greengrass CLI: | ||
|
||
```bash | ||
func gg_deploy() { | ||
COMPONENT_NAME=$(sed -nr 's/ComponentName: ([a-zA-Z.-_]+)/\1/p' recipe.yaml) | ||
COMPONENT_VERSION=$(sed -nr 's/ComponentVersion: (.+)/\1/p' recipe.yaml | tr -d '"' | tr -d "'") | ||
mkdir -p build/artifacts/$COMPONENT_NAME/$COMPONENT_VERSION/ | ||
command cp code.py build/artifacts/$COMPONENT_NAME/$COMPONENT_VERSION/ | ||
mkdir -p build/recipes/ | ||
command cp recipe.yaml build/recipes/$COMPONENT_NAME.yaml | ||
RECIPES=$PWD/build/recipes | ||
ARTIFACTS=$PWD/build/artifacts | ||
sudo /greengrass/v2/bin/greengrass-cli deployment create \ | ||
--recipeDir=$RECIPES \ | ||
--artifactDir=$ARTIFACTS \ | ||
--merge=$COMPONENT_NAME=$COMPONENT_VERSION | ||
} | ||
func gg_remove() { | ||
COMPONENT_NAME=$(sed -nr 's/ComponentName: ([a-zA-Z.-_]+)/\1/p' recipe.yaml) | ||
sudo /greengrass/v2/bin/greengrass-cli deployment create \ | ||
--recipeDir=$RECIPES \ | ||
--artifactDir=$ARTIFACTS \ | ||
--remove=$COMPONENT_NAME | ||
} | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
#!/usr/bin/env python3 | ||
|
||
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
# SPDX-License-Identifier: Apache-2.0. | ||
|
||
import time | ||
import os | ||
import http.server | ||
import socketserver | ||
|
||
from awsiot.greengrasscoreipc.clientv2 import GreengrassCoreIPCClientV2 | ||
|
||
client = GreengrassCoreIPCClientV2() | ||
thing_name = os.environ["AWS_IOT_THING_NAME"] | ||
|
||
|
||
def main(): | ||
# https://docs.aws.amazon.com/greengrass/v2/developerguide/ipc-component-configuration.html | ||
config = client.get_configuration().value | ||
|
||
print("This component was deployed with the following configuration:", config) | ||
|
||
# example use case that takes component configuration as arguments for a webserver | ||
host = config["Webserver"]["Host"] | ||
port = config["Webserver"]["Port"] | ||
directory = config["Webserver"]["Directory"] | ||
|
||
os.chdir(directory) | ||
|
||
Handler = http.server.SimpleHTTPRequestHandler | ||
|
||
with socketserver.TCPServer((host, port), Handler) as httpd: | ||
print(f"serving at {host}:{port} ...") | ||
httpd.serve_forever() | ||
|
||
|
||
if __name__ == "__main__": | ||
# Once we enter here, we know: | ||
# * all dependencies are available (imports succeeded) | ||
# * IPC Client created | ||
# * AWS_IOT_THING_NAME environment variable is available | ||
# This should be sufficient to consider this component `running` and the deployment will be completed. | ||
# If any of these failed, the component will be `broken`, and the deployment might roll-back or report the error. | ||
# Once the component is `running`, we need to try as hard as possible to keep it alive and running. | ||
while True: | ||
try: | ||
main() | ||
except Exception as e: | ||
print("ERROR", e) | ||
time.sleep(5) |
25 changes: 25 additions & 0 deletions
25
samples/greengrass_v2/deployment_configuration/recipe.yaml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
# recipe reference: https://docs.aws.amazon.com/greengrass/v2/developerguide/component-recipe-reference.html | ||
--- | ||
RecipeFormatVersion: "2020-01-25" | ||
ComponentName: com.example.greengrass_ipc.python.deployment_configuration | ||
ComponentVersion: "1.0.0" | ||
ComponentDescription: Greengrass IPC SDK component example | ||
ComponentPublisher: Amazon | ||
ComponentConfiguration: | ||
DefaultConfiguration: | ||
Webserver: | ||
Host: "127.0.0.1" | ||
Port: 8080 | ||
Directory: "/greengrass/v2/packages/" | ||
Manifests: | ||
- Platform: | ||
os: linux | ||
Lifecycle: | ||
Install: | ||
RequiresPrivilege: true | ||
Script: | | ||
apt-get update | ||
apt-get install --yes python3 python3-pip | ||
python3 -m pip install "awsiotsdk>=1.15.0" | ||
Run: | | ||
python3 -u {artifacts:path}/code.py |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
#!/usr/bin/env python3 | ||
|
||
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
# SPDX-License-Identifier: Apache-2.0. | ||
|
||
import json | ||
import time | ||
import os | ||
import random | ||
|
||
import awsiot.greengrasscoreipc | ||
import awsiot.greengrasscoreipc.model as model | ||
|
||
ipc_client = awsiot.greengrasscoreipc.connect() | ||
thing_name = os.environ["AWS_IOT_THING_NAME"] | ||
|
||
|
||
def send_telemetry(): | ||
telemetry_data = { | ||
"timestamp": int(time.time()), | ||
"battery_state_of_charge": random.random() * 99.9, | ||
"location": { | ||
"longitude": 48.15743 + random.random() / 10.0, | ||
"latitude": 11.57549 + random.random() / 10.0, | ||
}, | ||
} | ||
|
||
op = ipc_client.new_publish_to_iot_core() | ||
op.activate( | ||
model.PublishToIoTCoreRequest( | ||
topic_name=f"my/iot/{thing_name}/telemetry", | ||
qos=model.QOS.AT_LEAST_ONCE, | ||
payload=json.dumps(telemetry_data).encode(), | ||
) | ||
) | ||
try: | ||
result = op.get_response().result(timeout=5.0) | ||
print("successfully published message:", result) | ||
except Exception as e: | ||
print("failed to publish message:", e) | ||
|
||
|
||
def main(): | ||
while True: | ||
send_telemetry() | ||
time.sleep(5) | ||
|
||
|
||
if __name__ == "__main__": | ||
# Once we enter here, we know: | ||
# * all dependencies are available (imports succeeded) | ||
# * IPC Client created | ||
# * AWS_IOT_THING_NAME environment variable is available | ||
# This should be sufficient to consider this component `running` and the deployment will be completed. | ||
# If any of these failed, the component will be `broken`, and the deployment might roll-back or report the error. | ||
# Once the component is `running`, we need to try as hard as possible to keep it alive and running. | ||
while True: | ||
try: | ||
main() | ||
except Exception as e: | ||
print("ERROR", e) | ||
time.sleep(5) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
# recipe reference: https://docs.aws.amazon.com/greengrass/v2/developerguide/component-recipe-reference.html | ||
--- | ||
RecipeFormatVersion: "2020-01-25" | ||
ComponentName: com.example.greengrass_ipc.python.low_level_ipc | ||
ComponentVersion: "1.0.0" | ||
ComponentDescription: Greengrass IPC SDK component example | ||
ComponentPublisher: Amazon | ||
ComponentConfiguration: | ||
DefaultConfiguration: | ||
accessControl: | ||
# see https://docs.aws.amazon.com/greengrass/v2/developerguide/ipc-iot-core-mqtt.html | ||
"aws.greengrass.ipc.mqttproxy": | ||
"com.example.greengrass_ipc.python.low_level_ipc:mqttproxy:1": | ||
policyDescription: Allow access to publish/subscribe to all topics on AWS IoT Core. | ||
operations: | ||
- "aws.greengrass#PublishToIoTCore" | ||
- "aws.greengrass#SubscribeToIoTCore" | ||
resources: | ||
- "*" # CHANGE ME: scope down based on principle of least privilege | ||
Manifests: | ||
- Platform: | ||
os: linux | ||
Lifecycle: | ||
Install: | ||
RequiresPrivilege: true | ||
Script: | | ||
apt-get update | ||
apt-get install --yes python3 python3-pip | ||
python3 -m pip install "awsiotsdk>=1.15.0" | ||
Run: | | ||
python3 -u {artifacts:path}/code.py |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
#!/usr/bin/env python3 | ||
|
||
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
# SPDX-License-Identifier: Apache-2.0. | ||
|
||
import time | ||
import os | ||
import json | ||
|
||
from awsiot.greengrasscoreipc.clientv2 import GreengrassCoreIPCClientV2 | ||
from awsiot.greengrasscoreipc.model import QOS, IoTCoreMessage | ||
|
||
client = GreengrassCoreIPCClientV2() | ||
thing_name = os.environ["AWS_IOT_THING_NAME"] | ||
|
||
|
||
def on_stream_event(message: IoTCoreMessage): | ||
print(f"Message received:", message) | ||
reply = { | ||
"pong": "sending back what was received", | ||
"topic": message.message.topic_name, | ||
"payload": message.message.payload.decode(), | ||
} | ||
|
||
print("Sending pong message back:", reply) | ||
resp = client.publish_to_iot_core( | ||
topic_name="hello/world/response", | ||
qos=QOS.AT_LEAST_ONCE, | ||
payload=json.dumps(reply), | ||
) | ||
print(resp) | ||
|
||
|
||
def main(): | ||
print(f"Running pubsub-cloud sample for thing: {thing_name}") | ||
topic_name = "hello/world" | ||
|
||
print(f"Subscribing to AWS IoT Core topic {topic_name}") | ||
resp, op = client.subscribe_to_iot_core( | ||
topic_name=topic_name, | ||
qos=QOS.AT_LEAST_ONCE, | ||
on_stream_event=on_stream_event, | ||
) | ||
print(resp, op) | ||
|
||
while True: | ||
time.sleep(999) # wait for incoming messages | ||
|
||
|
||
if __name__ == "__main__": | ||
# Once we enter here, we know: | ||
# * all dependencies are available (imports succeeded) | ||
# * IPC Client created | ||
# * AWS_IOT_THING_NAME environment variable is available | ||
# This should be sufficient to consider this component `running` and the deployment will be completed. | ||
# If any of these failed, the component will be `broken`, and the deployment might roll-back or report the error. | ||
# Once the component is `running`, we need to try as hard as possible to keep it alive and running. | ||
while True: | ||
try: | ||
main() | ||
except Exception as e: | ||
print("ERROR", e) | ||
time.sleep(5) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
# recipe reference: https://docs.aws.amazon.com/greengrass/v2/developerguide/component-recipe-reference.html | ||
--- | ||
RecipeFormatVersion: "2020-01-25" | ||
ComponentName: com.example.greengrass_ipc.python.pubsub_cloud | ||
ComponentVersion: "1.0.0" | ||
ComponentDescription: Greengrass IPC SDK component example | ||
ComponentPublisher: Amazon | ||
ComponentConfiguration: | ||
DefaultConfiguration: | ||
accessControl: | ||
# see https://docs.aws.amazon.com/greengrass/v2/developerguide/ipc-iot-core-mqtt.html | ||
"aws.greengrass.ipc.mqttproxy": | ||
"com.example.greengrass_ipc.python.pubsub_cloud:mqttproxy:1": | ||
policyDescription: Allow access to publish/subscribe to all topics on AWS IoT Core. | ||
operations: | ||
- "aws.greengrass#PublishToIoTCore" | ||
- "aws.greengrass#SubscribeToIoTCore" | ||
resources: | ||
- "*" # CHANGE ME: scope down based on principle of least privilege | ||
Manifests: | ||
- Platform: | ||
os: linux | ||
Lifecycle: | ||
Install: | ||
RequiresPrivilege: true | ||
Script: | | ||
apt-get update | ||
apt-get install --yes python3 python3-pip | ||
python3 -m pip install "awsiotsdk>=1.15.0" | ||
Run: | | ||
python3 -u {artifacts:path}/code.py |
Oops, something went wrong.