The main entities of this repo are Robot and KC (Robot Coordinator). KC always knows the state of the Robot (will be described later how). When the robot becomes idle KC sends new order to the robot (operation 1) in the following format:
{
"order_id": order_id,
'ingredients': [...]
}
All communication here and further happens via MQTT. The Robot listens to the corresponding MQTT topic (robots/Robot1/process_order
) and starts "preparing" the order. During this simulation, the robot sends updates of its internal state (shadow) to the IoT Core (operation 2). The state of the robot is represented with the following fields:
{
'thing_name': Robot1,
'idle': False,
'order_id': 14,
'paused': False,
}
KC monitors changes in the Robot's shadow (operation 3) and knows when it becomes idle. On the schema above and in the description only one Robot was used. But the setup works with multiple robots at one time in the same fashion. For this, you need to run multiple Robot scripts (see below).
KC logs
Subscribing to topic '$aws/things/+/shadow/update/accepted'...
Subscribed with QoS.AT_LEAST_ONCE
Robot Robot1 is idle: True
Sending next order 63 to the robot Robot1
Robot Robot1 is idle: False
Robot Robot1 is idle: False
Robot Robot1 is idle: False
Robot Robot1 is idle: False
Robot Robot1 is idle: True
Robot logs
Subscribing to topic 'robots/Robot1/process_order'...
Subscribed with QoS.AT_LEAST_ONCE
Send shadow update request with order_id None.
Received message from topic 'robots/Robot1/process_order': b'{"order_id": 63, "ingredients": [{"material": "chicken", "quantity": 120, "unit": "g"}]}'
Send shadow update request with order_id 63.
Send shadow update request with order_id 63.
Send shadow update request with order_id 63.
Send shadow update request with order_id 63.
Send shadow update request with order_id None.
Python 3.8.1
Docker 19.03.5
Make sure, you've created the Greengrass group, added devices, and set up subscriptions.
To run Greengrass Core via docker:
docker run --rm --init -it --name aws-iot-greengrass \
--entrypoint /greengrass-entrypoint.sh \
-v /path/to/<hash>-setup/certs:/greengrass/certs \
-v /path/to/<hash>-setup/config:/greengrass/config \
-v /path/to/logs:/greengrass/ggc/var/log \
-v /path/to/<hash>/deployment:/greengrass/ggc/deployment \
-p 8883:8883 \
amazon/aws-iot-greengrass:latest
logs
and deployment
should be empty before the first start.
Now you can deploy your Greengrass setup to the local core.
In order to run KC, please type:
python kc.py \
--endpoint <endpoint> \
--cert /path/to/<hash>-setup/certs/<hash>.cert.pem \
--key /path/to/<hash>-setup/certs/<hash>.private.key \
--root-ca /path/to/group.ca.pem \
--client-id <KC-thing-name>
Few notes here:
<endpoint>
should point to local ip address (e.g. 127.0.0.1). The exact value can be determined fromsamples/basic_discovery.py
- group.ca.pem should be Greengrass group certificate and not root AWS .pem file in case you use local endpoint. To obtain it check
samples/basic_discovery.py
- client-id value should be equal to AWS Thing name.
- port in the script should be excplicitly set to 8883 (or your custom port)
- QoS inside local network communication should be set to 0 (AT_MOST_ONCE)
In a similar way you can start Robot simulator(s):
python robot.py \
--endpoint <endpoint> \
--cert /path/to/<robot-hash>-setup/<robot-hash>.cert.pem \
--key /path/to/<robot-hash>-setup/<robot-hash>.private.key \
--thing-name <robot-thing-name> \
--root-ca /path/to/group.ca.pem \
--client-id <robot-thing-name>
thing-name
is not ARN but the short name of the AWS IoT device.
https://youtu.be/wFeoKhVg-PM?t=627
https://docs.aws.amazon.com/iot/latest/developerguide/device-shadow-mqtt.html
https://github.com/aws/aws-iot-device-sdk-python-v2/tree/master/samples