You can use Cloud IoT Core to send commands to devices. Commands are transitory, one-time directives sent to devices that are connected to Cloud IoT Core and subscribed to the commands topic.
Compared to device configurations, commands are faster, can be sent more frequently, and are independent of other Cloud IoT Core features. When choosing between commands and configurations, consider whether you need persistence/knowledge over time (configurations) or prefer speed and/or time-bound directives (commands).
Commands can be useful when you want to:
- Send messages quickly to many devices at a specific time
- Send large-volume messages to many devices at a specific time
- Send time-bound directives that should expire
- Send incremental device settings
Commands have the following characteristics:
- Directly sent to subscribed, connected devices
- Not persisted in Cloud IoT Core
- Dropped for devices that are not subscribed and connected at the time the command is sent
- Not unique (duplicates may be sent, though this is unlikely)
- Not sent in any particular order (but delivered roughly in the send order)
- In any format (blob of data)
Currently, Cloud IoT Core supports commands over MQTT only (not HTTP).
Commands compared to configurations
Cloud IoT Core also supports device configurations. Configurations are more consistent and permanent than commands. Configurations are persisted in Cloud IoT Core and, when using MQTT, the latest configuration is eventually delivered to all subscribed devices — even devices that subscribe later.
The following table can help you decide whether to use a command or a configuration:
Configurations | Commands |
---|---|
Latest config is retried until delivered (MQTT) | Retried for QoS 1, but not guaranteed to be delivered |
Persistent, so if a device connects (MQTT) or polls (HTTP) later, the most recent configuration will still be delivered | Not persistent; delivered only to devices connected at the time the command is sent |
Each new version replaces the previous version | No relationship or order among commands |
Tells a device what to "be"; corresponds to state in Cloud IoT Core | Tells a device what to "do" at a specific time |
Higher latency | Lower latency |
Typically small (max 64 KB) in size | Up to 256 KB |
Arbitrary, user-defined blob | Arbitrary, user-defined blob |
1 update per sec, per device | 1,000 per sec, per project (configurable) 2,500 per sec, per registry |
Because commands are not persisted in Cloud IoT Core and are not retried indefinitely, you should not expect device telemetry or state data to reflect a particular command. The device may not have received the command, or it may have received subsequent commands or configurations. Commands are intended to be transitory and are not part of long-term device data.
To manage command ordering and duplicates, use device logic or client applications.
Sending a command
To send a command to a device, use Cloud Console, gcloud, or the Cloud IoT Core API.
Console
To send a command to a device:
- Go to the Registries page in Cloud Console.
- Click the ID of the registry for the device.
- In the registry menu on the left, click Devices.
- Click the ID of the device you want to send the command to.
- At the top of the page, click Send command.
Select the format of the command:
- Text
- Base64
In the Command data field, enter the command.
In the optional Subfolder field, enter the name of a subfolder for this command. Devices that are subscribed to the wildcard topic will receive commands sent to subfolders.
Click Send command.
gcloud
To send a command to a device, run the
gcloud iot devices commands send
command:
gcloud iot devices commands send \ { --command-file=COMMAND_FILE | --command-data=COMMAND_DATA } \ --region=REGION \ --registry=REGISTRY_ID \ --device=DEVICE_ID \ [--subfolder=SUBFOLDER]\
If the command data contains special characters, use --command-file
rather
than --command-data
.
API
Use the SendCommandToDevice method to send a command.
C#
Go
Java
Node.js
PHP
Python
Ruby
Python
Receiving a command
To receive a command, a device must:
- Be connected to Cloud IoT Core using the MQTT protocol
- Be subscribed to the MQTT topic
/devices/{device-id}/commands/#
(the # wildcard is required)
By subscribing to the wildcard topic, the device will receive commands sent to
devices/{device-id}/commands
, as well as commands sent to subfolders
(such as devices/{device-id}/commands/{subfolder}
). Subscribing to a specific
subfolder is not supported.
Commands are delivered to devices that are connected and subscribed at that specific time. They are not queued or preserved for devices that connect and subscribe at a later time.
Quality of service (QoS)
Command delivery depends on the QoS level you're using:
QoS level | Guarantee |
---|---|
0 | No guarantee (best effort only), even when the request returns OK |
1 | At-least-once delivery guaranteed if the sendCommandtoDevice request returns OK |
In other words, at QoS 0, a message is considered successful as soon as it is sent, regardless of the device response. At QoS 1, success means the device has acknowledged the message delivery. Note that "at-least-once" delivery means the device may receive the command multiple times; Cloud IoT Core does not track how many times the command was received.
Errors
If the command timeout (60 sec, as noted in Quotas and limits) is reached,
DEADLINE_EXCEEDED
is returned.If the device is not connected, or is connected but is not subscribed to the MQTT wildcard topic,
FAILED_PRECONDITION
is returned.
Logging
Commands sent to devices, as well as acknowledgments by devices, are logged in Stackdriver Logging.
Pricing
Commands are billed like all other messages sent over MQTT. For details, see Pricing.