Configuring devices

With ClearBlade IoT Core, you can control a device by modifying its configuration. A device configuration is an arbitrary, user-defined data blob. After a configuration has been applied to a device, the device can report its state to ClearBlade IoT Core.

Device configuration works differently in the MQTT and HTTP bridges. See below for details.

For more information, see Devices, configuration, and state.

Limits

Configuration updates are limited to 1 update per second per device. However, for best results, device configuration should be updated much less often — at most, once every 10 seconds.

Protocol differences

MQTT

Devices using MQTT can subscribe to a special MQTT topic for configuration updates:

/devices/{device-id}/config

When a device subscribes to the configuration topic, the MQTT bridge responds with an MQTT SUBACK message, which contains the config topic’s granted QoS (0 or 1) or 128 if an error occurs.

After initially subscribing, the device receives the latest configuration in a message's payload. It will receive additional configuration updates as they are pushed to ClearBlade IoT Core.

Retrieving configuration updates on a device over MQTT code samples

Node.js
// const deviceId = `myDevice`; // const registryId = `myRegistry`; // const region = `us-central1`; // const algorithm = `RS256`; // const privateKeyFile = `./rsa_private.pem`; // const serverCertFile = `./roots.pem`; /**  * @see https://clearblade.atlassian.net/wiki/spaces/IC/pages/2210299905/Retargeting+Devices#Production-URL-%2F-URLs for a full URL list  */ // const mqttBridgeHostname = `us-central1-mqtt.clearblade.com`; // const mqttBridgePort = 8883; // const messageType = `events`; // const numMessages = 5; // The mqttClientId is a unique string that identifies this device. For ClearBlade // IoT Core, it must be in the format below. const mqttClientId = `projects/${projectId}/locations/${region}/registries/${registryId}/devices/${deviceId}`; // With ClearBlade IoT Core, the username field is ignored, however it must be // non-empty. The password field is used to transmit a JWT to authorize the // device. The "mqtts" protocol causes the library to connect using SSL, which // is required for Cloud IoT Core. const connectionArgs = {   host: mqttBridgeHostname,   port: mqttBridgePort,   clientId: mqttClientId,   username: "unused",   password: createJwt(projectId, privateKeyFile, algorithm),   protocol: "mqtts",   secureProtocol: "TLSv1_2_method",   ca: [readFileSync(serverCertFile)], }; // Create a client, and connect to the ClearBlade MQTT bridge. const iatTime = parseInt(Date.now() / 1000); const client = mqtt.connect(connectionArgs); // Subscribe to the /devices/{device-id}/config topic to receive config updates. // Config updates are recommended to use QoS 1 (at least once delivery) client.subscribe(`/devices/${deviceId}/config`, { qos: 1 }); // Subscribe to the /devices/{device-id}/commands/# topic to receive all // commands or to the /devices/{device-id}/commands/<subfolder> to just receive // messages published to a specific commands folder; we recommend you use // QoS 0 (at most once delivery) client.subscribe(`/devices/${deviceId}/commands/#`, { qos: 0 }); // The MQTT topic that this device will publish data to. The MQTT topic name is // required to be in the format below. The topic name must end in 'state' to // publish state and 'events' to publish telemetry. This differs from the // device registry's Cloud Pub/Sub topic. const mqttTopic = `/devices/${deviceId}/${messageType}`; client.on("connect", (success) => {   console.log("connect");   if (!success) {     console.log("Client not connected...");   } else if (!publishChainInProgress) {     publishAsync(mqttTopic, client, iatTime, 1, numMessages, connectionArgs);   } }); client.on("close", () => {   console.log("close");   shouldBackoff = true; }); client.on("error", (err) => {   console.log("error", err); }); client.on("message", (topic, message) => {   let messageStr = "Message received: ";   if (topic === `/devices/${deviceId}/config`) {     messageStr = "Config message received: ";   } else if (topic.startsWith(`/devices/${deviceId}/commands`)) {     messageStr = "Command message received: ";   }   messageStr += Buffer.from(message, "base64").toString("ascii");   console.log(messageStr); }); client.on("packetsend", () => {   // Logging packet send is very verbose }); // Once all the messages have been published, the connection to ClearBlade // IoT Core will be closed, and the process will exit. See the publishAsync method.

 

Python
import paho.mqtt.client as mqtt import datetime import ssl import jwt def create_jwt(project_id, private_key_file, algorithm):     """Creates a JWT (https://jwt.io) to establish an MQTT connection.     Args:      project_id: The cloud project ID this device belongs to      private_key_file: A path to a file containing an RSA256 or              ES256 private key.      algorithm: The encryption algorithm to use (RS256 or ES256)     Returns:         A JWT generated from the given project_id and private key, which         expires in 20 minutes. After 20 minutes, your client will be         disconnected, and a new JWT must be generated.     Raises:         ValueError: If the private_key_file does not contain a known key.     """     token = {         # The time that the token was issued at         "iat": datetime.datetime.now(tz=datetime.timezone.utc),         # The time the token expires.         "exp": datetime.datetime.now(tz=datetime.timezone.utc) + datetime.timedelta(minutes=20),         # The audience field should always be set to the GCP project id.         "aud": project_id,     }     # Read the private key file.     with open(private_key_file, "r") as f:         private_key = f.read()     print(         "Creating JWT using {} from private key file {}".format(             algorithm, private_key_file         )     )     return jwt.encode(token, private_key, algorithm=algorithm) def error_str(rc):     """Convert a Paho error to a human readable string."""     return "{}: {}".format(rc, mqtt.error_string(rc)) def on_connect(unused_client, unused_userdata, unused_flags, rc):     """Callback for when a device connects."""     print("on_connect", mqtt.connack_string(rc))     # After a successful connect, reset backoff time and stop backing off.     global should_backoff     global minimum_backoff_time     should_backoff = False     minimum_backoff_time = 1 def on_disconnect(unused_client, unused_userdata, rc):     """Paho callback for when a device disconnects."""     print("on_disconnect", error_str(rc))     # Since a disconnect occurred, the next loop iteration will wait with     # exponential backoff.     global should_backoff     should_backoff = True def on_publish(unused_client, unused_userdata, unused_mid):     """Paho callback when a message is sent to the broker."""     print("on_publish") def on_message(unused_client, unused_userdata, message):     """Callback when the device receives a message on a subscription."""     payload = str(message.payload.decode("utf-8"))     print(         "Received message '{}' on topic '{}' with Qos {}".format(             payload, message.topic, str(message.qos)         )     ) def get_client(     project_id,     cloud_region,     registry_id,     device_id,     private_key_file,     algorithm,     ca_certs,     mqtt_bridge_hostname,     mqtt_bridge_port, ):     """Create our MQTT client.     The client_id is a unique string that identifies this device.     For ClearBlade IoT Core, it must be in the format below.     """     client_id = "projects/{}/locations/{}/registries/{}/devices/{}".format(         project_id, cloud_region, registry_id, device_id     )     print("Device client_id is '{}'".format(client_id))     client = mqtt.Client(client_id=client_id)     # With ClearBlade IoT Core, the username field is ignored, and the     # password field is used to transmit a JWT to authorize the device.     client.username_pw_set(         username="unused", password=create_jwt(project_id, private_key_file, algorithm)     )     # Enable SSL/TLS support.     client.tls_set(ca_certs=ca_certs, tls_version=ssl.PROTOCOL_TLSv1_2)     # Register message callbacks. https://eclipse.org/paho/clients/python/docs/     # describes additional callbacks that Paho supports. In this example, the     # callbacks just print to standard out.     client.on_connect = on_connect     client.on_publish = on_publish     client.on_disconnect = on_disconnect     client.on_message = on_message     # Connect to the MQTT bridge.     client.connect(mqtt_bridge_hostname, mqtt_bridge_port)     # This is the topic on which the device will receive configuration updates.     mqtt_config_topic = "/devices/{}/config".format(device_id)     # Subscribe to the config topic.     client.subscribe(mqtt_config_topic, qos=1)     # The topic on which the device will receive commands.     mqtt_command_topic = "/devices/{}/commands/#".format(device_id)     # Subscribe to the commands topic, QoS 1 enables message acknowledgment.     print("Subscribing to {}".format(mqtt_command_topic))     client.subscribe(mqtt_command_topic, qos=0)     return client get_client(     "YOUR_PROJECT_ID",     "us-central1",     "YOUR_REGISTRY_ID",     "YOUR_DEVICE_ID",     "YOUR_DEVICE_PRIVATE_KEY_FILE",     "RS256",     "DigiCertGlobalRootCA.crt.pem",     "us-central1-mqtt.clearblade.com",     8883 )

HTTP

Devices must explicitly request new configurations if you're using the HTTP bridge.

Retrieving configuration updates on a device over HTTP code samples

Node.js

 

Python

Updating and reverting device configuration

Console

Update the device configuration

1. Go to the ClearBlade IoT Core console’s Registries page.

2. Click the registry ID that contains the device.

3. In the left registry menu, click Devices.

4. Click the device ID whose configuration you want to update.

5. Click the ellipsis (⋮) at the top-right of the page, then select Update device.

6. Select the configuration’s format (text, Base64) and paste the data in the configuration box.

7. Click SEND TO DEVICE.

See Protocol differences for how devices receive the new configuration.

Revert the device configuration to a previous version

1. Go to the Google Cloud console’s Registries page.

2. Click the registry ID that contains the device whose configuration you want to revert.

3. In the left registry menu, click Devices.

4. Click the device ID whose configuration you wish to revert.

5. Click CONFIGURATION & STATE. Use the checkboxes to display configuration history, state history, or both. By default, both are shown.

6. Click a row to get the full configuration or state data in JSON and the timestamp and version.

7. Click COMPARE to compare the configuration data with the state data. This view can help you debug configurations and ensure devices have acknowledged specific configuration versions if you use MQTT (the HTTP bridge does not support configuration acknowledgments).

8. Click the version you want to revert to. Select Text in the Format list to see a text version of the configuration details.

9. Click Revert, ensure you've selected the correct version, then click Revert.

API

To update or revert device configuration via the API, use the device modifyCloudToDeviceConfig method, specifying the new or previous configuration in the config field. You can specify a configuration when creating a device and then use modifyCloudToDeviceConfig to change it later.

Updating a device's configuration code samples

Node.js

 

C#

 

Python

 

Go

 

Reviewing device configuration

Console

1. Go to the Google Cloud console’s Registries page.

2. Click the registry ID that contains the device whose configuration you want to update.

3. In the left registry menu, click Devices.

4. Click the device ID whose configuration you want to update.

5. Click CONFIGURATION & STATE. Use the checkboxes to display configuration history, state history, or both. By default, both are shown.

6. Click a row to get the full configuration or state data in JSON and the timestamp and version.

7. Click COMPARE to compare the configuration data with the state data. This view can help you debug configurations and ensure devices have acknowledged specific configuration versions if you use MQTT (the HTTP bridge does not support configuration acknowledgments).

To review device configuration via the API, use a device configVersions.list request.

Review a device’s configuration code samples

Node.js

 

C#

 

Python

 

Go