Google Cloud IoT Core verrà ritirato il 16 agosto 2023. Per saperne di più, contatta il team dedicato al tuo account Google Cloud.

Invio di comandi ai dispositivi

Mantieni tutto organizzato con le raccolte Salva e classifica i contenuti in base alle tue preferenze.

Puoi utilizzare Cloud IoT Core per inviare comandi ai dispositivi. I comandi sono istruzioni transitorie e una tantum inviate ai dispositivi connessi a Cloud IoT Core e abbonati all'argomento dei comandi.

Rispetto alle configurazioni dei dispositivi, i comandi sono più veloci, possono essere inviati più frequentemente e sono indipendenti dalle altre funzionalità di Cloud IoT Core. Quando scegli tra comandi e configurazioni, valuta se hai bisogno di persistenza/conoscenza nel tempo (configurazioni) o se preferisci istruzioni relative a velocità e/o vincoli temporali (comandi).

I comandi possono essere utili quando vuoi:

  • Inviare messaggi rapidamente a più dispositivi in un momento specifico
  • Inviare messaggi di grandi quantità a molti dispositivi in un momento specifico
  • Invia istruzioni con limitazioni di tempo che devono scadere
  • Inviare impostazioni incrementali del dispositivo

I comandi hanno le seguenti caratteristiche:

  • Messaggio inviato direttamente ai dispositivi connessi a cui è stato sottoscritto un abbonamento
  • Non persistente in Cloud IoT Core
  • Ignorata per i dispositivi non abbonati e connessi al momento dell'invio del comando
  • Non univoco (possono essere inviati duplicati, anche se è improbabile)
  • Non inviato in nessun ordine (ma consegnato all'incirca nell'ordine di invio)
  • In qualsiasi formato (blob di dati)

Attualmente, Cloud IoT Core supporta i comandi solo su MQTT (non su HTTP).

Comandi rispetto alle configurazioni

Cloud IoT Core supporta anche le configurazioni dei dispositivi. Le configurazioni sono più coerenti e permanenti rispetto ai comandi. Le configurazioni vengono mantenute in Cloud IoT Core e, quando si utilizza MQTT, l'ultima configurazione viene alla fine inviata a tutti i dispositivi abbonati, inclusi quelli che si abbonano in seguito.

La tabella seguente può aiutarti a decidere se utilizzare un comando o una configurazione:

Configurazioni Comandi
Riprova la configurazione più recente fino alla pubblicazione (MQTT) Hai provato a provare QoS 1, ma la pubblicazione non è garantita
Persistente, quindi se un dispositivo si connette (MQTT) o esegue un sondaggio (HTTP) in un secondo momento, la configurazione più recente verrà comunque consegnata Non permanente; consegnato soltanto ai dispositivi connessi al momento dell'invio del comando
Ogni nuova versione sostituisce quella precedente Nessun rapporto o ordine tra i comandi
Indica a un dispositivo cosa "essere"; corrisponde allo stato in Cloud IoT Core Indica a un dispositivo l'azione da eseguire in un momento specifico
Latenza più elevata Minore latenza
Dimensione standard (64 kB) Fino a 256 kB
blob arbitrario definito dall'utente blob arbitrario definito dall'utente
1 aggiornamento al secondo per dispositivo 1000 al secondo, per progetto (configurabile)
2500 al secondo, per registro

Poiché i comandi non vengono conservati in Cloud IoT Core e non vengono ripetuti, non dovresti aspettarti che dati di telemetria o stato del dispositivo rispecchino un particolare comando. È possibile che il dispositivo non abbia ricevuto il comando o che abbia ricevuto comandi o configurazioni successivi. I comandi sono progettati per essere transitori e non fanno parte dei dati a lungo termine dei dispositivi.

Per gestire l'ordinamento dei comandi e i duplicati, utilizza le applicazioni logiche o client del dispositivo.

Invio di un comando

Per inviare un comando a un dispositivo, utilizza la console Google Cloud, gcloud o l'API Cloud IoT Core.

Console

Per inviare un comando a un dispositivo:

  1. Vai alla pagina Registry nella console Google Cloud.

    Vai alla pagina Registry

  2. Fai clic sull'ID del registro relativo al dispositivo.
  3. Nel menu del Registro di sistema a sinistra, fai clic su Dispositivi.
  4. Fai clic sull'ID del dispositivo a cui vuoi inviare il comando.
  5. Nella parte superiore della pagina, fai clic su Send Command (Invia comando).
  6. Seleziona il formato del comando:

    • Testo
    • Base64
  7. Inserisci il comando nel campo Dati dei comandi.

  8. Nel campo facoltativo Subfolder (Sottocartella), inserisci il nome di una sottocartella per questo comando. I dispositivi abbonati all'argomento con caratteri jolly riceveranno i comandi inviati alle sottocartelle.

  9. Fai clic su Invia comando.

gcloud

Per inviare un comando a un dispositivo, esegui questo comando: gcloud iot devices commands send:

gcloud iot devices commands send \
    { --command-file=COMMAND_FILE | --command-data=COMMAND_DATA } \
    --region=REGION  \
    --registry=REGISTRY_ID \
    --device=DEVICE_ID \
    [--subfolder=SUBFOLDER]\

Se i dati del comando contengono caratteri speciali, utilizza --command-file invece di --command-data.

API

Utilizza il metodo SendCommandToDevice per inviare un comando.

C#

public static object SendCommand(string deviceId, string projectId,
    string cloudRegion, string registryName, string data)
{
    var cloudIot = CreateAuthorizedClient();

    var devicePath = String.Format("projects/{0}/locations/{1}/registries/{2}/devices/{3}",
        projectId, cloudRegion, registryName, deviceId);
    // Data sent through the wire has to be base64 encoded.
    SendCommandToDeviceRequest req = new SendCommandToDeviceRequest()
    {
        BinaryData = Convert.ToBase64String(Encoding.UTF8.GetBytes(data))
    };

    Console.WriteLine("Sending command to {0}\n", devicePath);

    var res =
        cloudIot.Projects.Locations.Registries.Devices.SendCommandToDevice(req, devicePath).Execute();

    Console.WriteLine("Command response: " + res.ToString());
    return 0;
}

Go


// sendCommand sends a command to a device listening for commands.
func sendCommand(w io.Writer, projectID string, region string, registryID string, deviceID string, sendData string) (*cloudiot.SendCommandToDeviceResponse, error) {
	// Authorize the client using Application Default Credentials.
	// See https://g.co/dv/identity/protocols/application-default-credentials
	ctx := context.Background()
	httpClient, err := google.DefaultClient(ctx, cloudiot.CloudPlatformScope)
	if err != nil {
		return nil, err
	}
	client, err := cloudiot.New(httpClient)
	if err != nil {
		return nil, err
	}

	req := cloudiot.SendCommandToDeviceRequest{
		BinaryData: b64.StdEncoding.EncodeToString([]byte(sendData)),
	}

	name := fmt.Sprintf("projects/%s/locations/%s/registries/%s/devices/%s", projectID, region, registryID, deviceID)

	response, err := client.Projects.Locations.Registries.Devices.SendCommandToDevice(name, &req).Do()
	if err != nil {
		return nil, err
	}

	fmt.Fprintln(w, "Sent command to device")

	return response, nil
}

Java

protected static void sendCommand(
    String deviceId, String projectId, String cloudRegion, String registryName, String data)
    throws GeneralSecurityException, IOException {
  GoogleCredentials credential =
      GoogleCredentials.getApplicationDefault().createScoped(CloudIotScopes.all());
  JsonFactory jsonFactory = JacksonFactory.getDefaultInstance();
  HttpRequestInitializer init = new HttpCredentialsAdapter(credential);
  final CloudIot service =
      new CloudIot.Builder(GoogleNetHttpTransport.newTrustedTransport(), jsonFactory, init)
          .setApplicationName(APP_NAME)
          .build();

  final String devicePath =
      String.format(
          "projects/%s/locations/%s/registries/%s/devices/%s",
          projectId, cloudRegion, registryName, deviceId);

  SendCommandToDeviceRequest req = new SendCommandToDeviceRequest();

  // Data sent through the wire has to be base64 encoded.
  Base64.Encoder encoder = Base64.getEncoder();
  String encPayload = encoder.encodeToString(data.getBytes(StandardCharsets.UTF_8.name()));
  req.setBinaryData(encPayload);
  System.out.printf("Sending command to %s%n", devicePath);

  service
      .projects()
      .locations()
      .registries()
      .devices()
      .sendCommandToDevice(devicePath, req)
      .execute();

  System.out.println("Command response: sent");
}

Node.js

// const cloudRegion = 'us-central1';
// const deviceId = 'my-device';
// const commandMessage = 'message for device';
// const projectId = 'adjective-noun-123';
// const registryId = 'my-registry';
const iot = require('@google-cloud/iot');
const iotClient = new iot.v1.DeviceManagerClient({
  // optional auth parameters.
});

async function sendCommand() {
  // Construct request
  const formattedName = iotClient.devicePath(
    projectId,
    cloudRegion,
    registryId,
    deviceId
  );

  const binaryData = Buffer.from(commandMessage);

  const request = {
    name: formattedName,
    binaryData: binaryData,
  };

  const [response] = await iotClient.sendCommandToDevice(request);
  console.log('Sent command: ', response);
}

sendCommand();

PHP

use Google\Cloud\Iot\V1\DeviceManagerClient;

/**
 * Sends a command to a device.
 *
 * @param string $registryId IOT Device Registry ID
 * @param string $deviceId IOT Device ID
 * @param string $command The command sent to a device
 * @param string $projectId Google Cloud project ID
 * @param string $location (Optional) Google Cloud region
 */
function send_command_to_device(
    $registryId,
    $deviceId,
    $command,
    $projectId,
    $location = 'us-central1'
) {
    print('Sending command to device' . PHP_EOL);

    // Instantiate a client.
    $deviceManager = new DeviceManagerClient();
    $deviceName = $deviceManager->deviceName($projectId, $location, $registryId, $deviceId);

    // Response empty on success
    $deviceManager->sendCommandToDevice($deviceName, $command);

    printf('Command sent' . PHP_EOL);
}

Python

print("Sending command to device")
client = iot_v1.DeviceManagerClient()
device_path = client.device_path(project_id, cloud_region, registry_id, device_id)

# command = 'Hello IoT Core!'
data = command.encode("utf-8")

return client.send_command_to_device(
    request={"name": device_path, "binary_data": data}
)

Ruby

# project_id  = "Your Google Cloud project ID"
# location_id = "The Cloud region the registry is located in"
# registry_id = "The registry containing the device to send commands to"
# device_id   = "The identifier of the device to send commands to"
# data        = "The command, e.g. {move: forward} to send to the device"

require "google/apis/cloudiot_v1"

# Initialize the client and authenticate with the specified scope
Cloudiot   = Google::Apis::CloudiotV1
iot_client = Cloudiot::CloudIotService.new
iot_client.authorization = Google::Auth.get_application_default(
  "https://www.googleapis.com/auth/cloud-platform"
)

# The resource name of the location associated with the project
parent   = "projects/#{project_id}/locations/#{location_id}"
resource = "#{parent}/registries/#{registry_id}/devices/#{device_id}"

command_req = Cloudiot::SendCommandToDeviceRequest.new
command_req.binary_data = data

# Set configuration for the provided device
iot_client.send_project_location_registry_device_command_to_device resource, command_req

puts "Command sent!"

Ricezione di un comando

Per ricevere un comando, un dispositivo deve:

  • Essere connesso a Cloud IoT Core utilizzando il protocollo MQTT
  • Iscriviti all'argomento MQTT /devices/{device-id}/commands/# (è richiesto il carattere jolly #)

Abbonandosi all'argomento con caratteri jolly, il dispositivo riceverà i comandi inviati a devices/{device-id}/commands, nonché i comandi inviati a sottocartelle (ad esempio devices/{device-id}/commands/{subfolder}). L'iscrizione a una sottocartella specifica non è supportata.

I comandi vengono inviati ai dispositivi connessi e abbonati in un momento specifico. Non vengono messi in coda o conservati per i dispositivi che si connettono e abbonati in un secondo momento.

Qualità del servizio (QoS)

La distribuzione dei comandi dipende dal livello QoS che stai utilizzando:

Livello QoS Garanzia
0 Nessuna garanzia (solo tentativo migliore), anche quando la richiesta restituisce OK
1 Consegna "almeno una volta" garantita se la richiesta sendcommandtoDevice restituisce OK

In altre parole, a QoS 0 un messaggio viene considerato non appena viene inviato, indipendentemente dalla risposta del dispositivo. In QoS 1, l'esito positivo indica che il dispositivo ha confermato la consegna del messaggio. Tieni presente che la consegna "almeno una volta" significa che il dispositivo può ricevere il comando più volte; Cloud IoT Core non monitora il numero di volte in cui il comando è stato ricevuto.

Errori

  • Se viene raggiunto il timeout del comando (60 sec, come indicato in Quote e limiti), DEADLINE_EXCEEDED viene ripristinato.

  • Se il dispositivo non è connesso o è connesso, ma non è iscritto all'argomento carattere jolly MQTT, viene restituito FAILED_PRECONDITION.

Logging

I comandi inviati ai dispositivi, nonché le conferme dei dispositivi, vengono registrati in Cloud Logging.

Prezzi

I comandi vengono fatturati come tutti gli altri messaggi inviati tramite MQTT. Per i dettagli, consulta Prezzi.