|
#!/bin/sh |
|
################################################################################################## |
|
# Install and bootstrap thin-edge.io to enable AWS communication |
|
# |
|
# Usage: |
|
# ./tedge-aws-bootstrap.sh |
|
# |
|
# Checkout the following links for more guidance on how to setup AWS and connect thin-edge.io to it. |
|
# |
|
# Publish message from aws to device |
|
## Send message to device |
|
# |
|
# 1. Open the AWS IoT Console |
|
# 2. Select the device you wish to interact with |
|
# 3. Open the "MQTT test client" under the "Activity" tab |
|
# 4. Select "Publish to a topic" |
|
# 5. Send the following message |
|
# |
|
# Publish to Topic (from the cloud) |
|
# |
|
# ``` |
|
# $aws/things/tedge_0001/shadow/cmd/testme |
|
# ``` |
|
# |
|
# Payload |
|
# |
|
# ``` |
|
# { |
|
# "message": "Hello from AWS IoT console" |
|
# } |
|
# ``` |
|
# |
|
# Example what is received on the device |
|
# |
|
# ``` |
|
# [aws/shadow/cmd/testme] { |
|
# "message": "Hello from AWS IoT console" |
|
# } |
|
# ``` |
|
# |
|
# Links: |
|
# * Example AWS policy: https://raw.githubusercontent.com/thin-edge/thin-edge.io/main/docs/src/tutorials/aws-example-policy.json |
|
# * Documentation: https://thin-edge.github.io/thin-edge.io/start/connect-aws/ |
|
################################################################################################## |
|
|
|
set -e |
|
|
|
# Defaults: Or set via env variables |
|
AWS_URL=${AWS_URL:-example-ats.iot.us-east-1.amazonaws.com} |
|
DEVICE_SN="${DEVICE_SN:-}" |
|
INSTALL_TEDGE="${INSTALL_TEDGE:-0}" |
|
DRY_RUN=${DRY_RUN:-} |
|
|
|
# Set shell used by the script (can be overwritten during dry run mode) |
|
sh_c='sh -c' |
|
|
|
# Helpers |
|
info() { echo "INFO: $*"; } |
|
error() { echo "ERROR: $*"; } |
|
help() { |
|
cat <<EOT |
|
Configure thin-edge.io to connect to AWS IoT Core |
|
|
|
USAGE |
|
$0 --url <aws_url> [--device-id <device_id>] [--update] |
|
|
|
ARGUMENTS |
|
--url STRING AWS IoT Core URL |
|
--device-id STRING Device id. Defaults to the currently configured device.id by thin-edge.io |
|
--update Update thin-edge.io before bootstrapping. Turned off by default, though |
|
thin-edge.io will still be installed if it is not already installed. |
|
--dry-run Run a dry run, don't change anything |
|
-h | --help Show this help |
|
|
|
EXAMPLES |
|
# Configure AWS on a device which is already has a device certificate |
|
$0 --url a1vto0hq4ubn5m-ats.iot.us-east-1.amazonaws.com |
|
|
|
# Update thin-edge.io version and configure AWS |
|
$0 --url a1vto0hq4ubn5m-ats.iot.us-east-1.amazonaws.com --update |
|
|
|
# Pass aws url and device id as arguments |
|
$0 --url a1vto0hq4ubn5m-ats.iot.us-east-1.amazonaws.com --device-id mydevice01 |
|
|
|
# Use defaults (defined in the script) |
|
$0 |
|
EOT |
|
|
|
} |
|
|
|
is_root() { |
|
user="$(id -un 2>/dev/null || true)" |
|
[ "$user" = "root" ] |
|
} |
|
command_exists() { |
|
command -v "$@" > /dev/null 2>&1 |
|
} |
|
is_dry_run() { |
|
if [ -z "$DRY_RUN" ]; then |
|
return 1 |
|
else |
|
return 0 |
|
fi |
|
} |
|
|
|
# |
|
# Arg parsing |
|
# |
|
POSITIONAL_ARGS="" |
|
|
|
while [ $# -gt 0 ]; do |
|
case $1 in |
|
--url) |
|
AWS_URL="$2" |
|
shift |
|
;; |
|
--device-id) |
|
DEVICE_SN="$2" |
|
shift |
|
;; |
|
--update) |
|
INSTALL_TEDGE=1 |
|
;; |
|
--dry-run) |
|
DRY_RUN=1 |
|
;; |
|
--help|-h) |
|
help |
|
exit 0 |
|
;; |
|
--*|-*) |
|
echo "Unknown flag $1" |
|
exit 1 |
|
;; |
|
*) |
|
POSITIONAL_ARGS="POSITIONAL_ARGS $1" |
|
;; |
|
esac |
|
shift |
|
done |
|
|
|
# shellcheck disable=SC2086 |
|
set -- ${POSITIONAL_ARGS} # restore positional parameters |
|
|
|
if [ $# -gt 1 ]; then |
|
error "Unexpected positional arguments" |
|
help |
|
exit 1 |
|
fi |
|
|
|
if [ -z "$AWS_URL" ]; then |
|
error "aws.url is not set" |
|
help |
|
exit 3 |
|
fi |
|
|
|
# Force installation of thin-edge.io if the tedge binary is not present |
|
if ! command_exists tedge; then |
|
info "thin-edge.io is not installed, so it will be installed automatically" |
|
INSTALL_TEDGE=1 |
|
fi |
|
|
|
# Check if the existing set |
|
if [ -z "$DEVICE_SN" ]; then |
|
DEVICE_SN="$(tedge config get device.id 2>/dev/null)" |
|
fi |
|
|
|
if [ -z "$DEVICE_SN" ]; then |
|
info "Using default device.id" |
|
DEVICE_SN="thin-edge-aws-demo01" |
|
fi |
|
|
|
configure_shell() { |
|
# Check if has sudo rights or if it can be requested |
|
user="$(id -un 2>/dev/null || true)" |
|
sh_c='sh -c' |
|
if [ "$user" != 'root' ]; then |
|
if command_exists sudo; then |
|
sh_c='sudo -E sh -c' |
|
elif command_exists su; then |
|
sh_c='su -c' |
|
else |
|
cat >&2 <<-EOF |
|
Error: this installer needs the ability to run commands as root. |
|
We are unable to find either "sudo" or "su" available to make this happen. |
|
EOF |
|
exit 1 |
|
fi |
|
fi |
|
|
|
if is_dry_run; then |
|
sh_c="echo" |
|
fi |
|
} |
|
|
|
check_aws_url() { |
|
if command_exists ping; then |
|
info "Checking if aws.url is reachable using ping" |
|
if ping -c 1 "$AWS_URL"; then |
|
info "aws.url is reachable" |
|
else |
|
error "aws.url is not reachable! Check the above command output for more details." |
|
echo "You may need to check if the DNS is configured correctly. Consider using 8.8.8.8 or 1.1.1.1 if you are still having problems" |
|
echo "Or alternatively set the ip address for the host in /etc/hosts" |
|
exit 2 |
|
fi |
|
else |
|
info "Skipping aws.url check as ping is not installed" |
|
fi |
|
} |
|
|
|
install_tedge() { |
|
export DRY_RUN="$DRY_RUN" |
|
curl -fsSL https://thin-edge.io/install.sh | sh -s |
|
} |
|
|
|
|
|
configure_device() { |
|
EXISTING_URL=$(tedge config get aws.url 2>/dev/null) |
|
|
|
if [ "$EXISTING_URL" != "$AWS_URL" ]; then |
|
$sh_c "tedge config set aws.url '$AWS_URL'" |
|
else |
|
echo "aws.url is already set to ${AWS_URL}" |
|
fi |
|
|
|
EXISTING_DEVICEID=$(tedge config get device.id 2>/dev/null) |
|
if [ "$EXISTING_DEVICEID" != "$DEVICE_SN" ]; then |
|
$sh_c "tedge cert remove || true" |
|
$sh_c "tedge cert create --device-id '${DEVICE_SN}'" |
|
else |
|
echo "device.id is already set to ${DEVICE_SN}" |
|
fi |
|
|
|
# Show device certificate so user can upload it to AWS |
|
echo "-----------------------------------------------------------------------" |
|
echo "Certificate" |
|
echo "" |
|
echo "DeviceID: $(tedge config get device.id 2>/dev/null)" |
|
echo "" |
|
$sh_c "cat '$(tedge config get device.cert.path 2>/dev/null)'" |
|
echo "-----------------------------------------------------------------------" |
|
|
|
# Don't prompt if not in interactive mode |
|
if [ -t 0 ] ; then |
|
echo "" |
|
echo "1. Open the AWS IoT Console in your web browser" |
|
echo "2. Navigate to Manage > All devices > Things" |
|
echo "3. Click Create things" |
|
echo "4. Click Create single thing" |
|
echo "5. Enter '$DEVICE_SN' as the thing name, then click Next" |
|
echo "6. Select 'Use my certificate' and 'CA is not registered with AWS IoT'" |
|
echo "7. Copy the certificate (shown above) to a local file, then upload it to AWS IoT Console" |
|
echo "" |
|
echo "" |
|
|
|
printf "Press <ENTER> to continue/connect" |
|
read -r REPLY |
|
fi |
|
} |
|
|
|
connect_aws() { |
|
$sh_c "tedge reconnect aws" |
|
} |
|
|
|
publish_messages() { |
|
# |
|
# Examples how to publish to AWS (either via thin-edge or directly to AWS topic) |
|
# |
|
TOPIC_ROOT=$(tedge config get mqtt.topic_root) |
|
TOPIC_ID=$(tedge config get mqtt.device_topic_id) |
|
tedge mqtt pub "$TOPIC_ROOT/$TOPIC_ID/m/example" '{"temperature": 20}' |
|
tedge mqtt pub "$TOPIC_ROOT/$TOPIC_ID/e/example" '{"text": "Example event","custom":{"data":1}}' |
|
|
|
# Or custom messages directly via the bridge |
|
tedge mqtt pub aws/shadow/testme '{ "custom": "Some custom data", "isAlarm": false}' |
|
} |
|
|
|
main() { |
|
configure_shell |
|
if [ "$INSTALL_TEDGE" = "1" ]; then |
|
install_tedge |
|
fi |
|
check_aws_url |
|
configure_device |
|
connect_aws |
|
publish_messages |
|
} |
|
|
|
# |
|
# Entrypoint |
|
# |
|
main |