Scaleway DocumentationIoTIoT HubAPI/CLI
Configuring IoT Hub routes

Jump toUpdate content

Configuring IoT Hub routes via the API

Requirements:

Routes are integrations with the Scaleway ecosystem: they can forward MQTT messages to Scaleway services.

The documentation is there: IoT Hub Routes

S3 Route

The S3 route allows you to put the payload of MQTT messages directly into Scaleway’s Object Storage.

Important:

This section is an addition to the Getting started doc above, make sure to follow it first!

BUCKET="my-bucket-$RANDOM" # Buckets are globally unique, suffix with a random number
REGION="fr-par"
PREFIX="iot/messages"
# Create the bucket
s3cmd mb --region "$REGION" "s3://$BUCKET"
# Grant write access to IoT Hub S3 Route Service to your bucket
s3cmd setacl --region "$REGION" "s3://$BUCKET" --acl-grant=write:555c69c3-87d0-4bf8-80f1-99a2f757d031:555c69c3-87d0-4bf8-80f1-99a2f757d031
# Create the IoT Hub S3 Route
curl -sS -H "X-Auth-Token: $SCW_SECRET_KEY" -d '{
"hub_id": "'$(jq -r '.id' hub.json)'",
"name": "my-s3-route",
"topic": "hello/world",
"bucket_region": "'$REGION'",
"bucket_name": "'$BUCKET'",
"object_prefix": "'$PREFIX'",
"strategy": "per_topic"
}' $IOT_API/routes/s3 | jq

The output will contain something like:

{
"id": "e0d1e048-6f67-4c2d-8911-a75f0ef4d787",
"name": "my-s3-route",
"organization_id": "<your organization ID>",
"hub_id": "a15ddd5b-ff73-4fb3-b043-1c9176dae295",
"topic": "hello/world",
"created_at": "2018-12-13T15:17:22.052005Z",
"bucket_region": "fr-par",
"bucket_name": "my-bucket",
"object_prefix": "iot/messages",
"strategy": "per_topic"
}

Now you may publish and see the result!

sleep 5 # wait a little for the route to start
mosquitto_pub \
-h $(jq -r '.endpoint' hub.json) \
-i $(jq -r '.device.id' dev2.json) \
-t hello/world \
-m 'Hello, world!'

An object iot/messages/hello/world should now be stored in your bucket with “hello world” as contents.

s3cmd get --region "$REGION" "s3://$BUCKET/$PREFIX/hello/world"
cat world

Database Route

Database route allows you to store messages in your database.

When creating such a route for one of you hubs, you need to specify a topic (wildcards are allowed), a database (with valid credentials) and a query to execute. That query may contains \$TOPIC and \$PAYLOAD variables.

The route will subscribe on this hub to this topic, and execute the query onto the given database for each received message:

  • First, \$TOPIC and \$PAYLOAD are replaced with the topic and payload of the received MQTT message,
  • Then the generated query is executed

NOTE: The topic database field must be a of text type, and payload a bytea

For now, we support only PostgreSQL database system. You can use a Scaleway Database instance, or any other PostgreSQL instance publicly accessible.

Let’s practice

As a prerequisite, you must have a working PostgreSQL database, with valid credentials (username and password).

# Database settings
DBHOST=<your db host>
DBPORT=<your db port>
DBNAME=<your db name>
DBUSER=<your db user>
DBPASS=<your db password>

# Create the target database table
psql -h $DBHOST --port $DBPORT -U $DBUSER -d $DBNAME -c '
CREATE TABLE messages (
time timestamp,
topic text,
payload bytea
)
'

# Create the IoT Hub Database Route
# The query will insert message topic and payload with current timestamp
curl -sS -H "X-Auth-Token: $SCW_SECRET_KEY" -d '{
"name": "my first database route",
"hub_id": "'$(jq -r '.id' hub.json)'",
"topic": "hello/world",
"query": "INSERT INTO messages VALUES (NOW(), $TOPIC, $PAYLOAD)",
"database": {
"host": "'$DBHOST'",
"port": '$DBPORT',
"dbname": "'$DBNAME'",
"username": "'$DBUSER'",
"password": "'$DBPASS'"
}
}' $IOT_API/routes/database | jq

The output will contain something like

{
"id": "486944d3-848e-4886-8945-938fbb828aa6",
"name": "my first database route",
"organizationId": "<your organization id>",
"hubId": "<your hub id>",
"topic": "hello/world",
"createdAt": "2019-10-11T13:58:42.710Z",
"query": "INSERT INTO messages VALUES (NOW(), $TOPIC, $PAYLOAD)",
"database": {
"host": "127.0.0.1",
"port": 5432,
"dbname": "route_tests",
"username": "jdoe",
"password": ""
}
}

Now you can publish a message and checks it is inserted into the message table.

sleep 5 # wait a little for the route to start
mosquitto_pub \
-h $(jq -r '.endpoint' hub.json) \
-i $(jq -r '.device.id' dev2.json) \
-t hello/world \
-m 'Hello, world!'
psql -h $DBHOST --port $DBPORT -U $DBUSER -d $DBNAME -c "SELECT * FROM messages"

More advanced examples are available on the database route tips & tricks page.

Rest Route

Rest route allows you call any http(s) endpoint on received MQTT message. You can choose the HTTP verb use to call your REST uri, as well as adding extra headers.

We can see what a rest route would publish on a rest API by simply listening to the port 80 on a public IP.

You can use a Scaleway instance, or any other machine with a public IP address.

On the machine, as root, lauch the following command:

nc -p 80 -l

Define a variable with the public IP address of your server

RESTHOST=<the_public_ip_address>

Let’s create the route

# Create the IoT Hub Rest Route
curl -sS -H "X-Auth-Token: $SCW_SECRET_KEY" -d '{
"name": "my first rest route",
"hub_id": "'$(jq -r '.id' hub.json)'",
"topic": "hello/world",
"verb": "post",
"uri": "http://'$RESTHOST'/",
"headers": {
"X-My-Header": "Tutorial"
}
}' $IOT_API/routes/rest | jq

Now you can publish a message and checks it triggers a request on the server:

sleep 5 # wait a little for the route to start
mosquitto_pub \
-h $(jq -r '.endpoint' hub.json) \
-i $(jq -r '.device.id' dev2.json) \
-t hello/world \
-m 'Hello, world!'

On your server the above nc output should be:

POST / HTTP/1.1
Host: <the_public_ip_address>
User-Agent: Go-http-client/1.1
Content-Length: 13
X-Mqtt-Retain: false
X-Mqtt-Topic: hello/world
X-My-Header: Tutorial
Accept-Encoding: gzip

Hello, world!