Google Cloud IoT Core wird am 16. August 2023 eingestellt. Weitere Informationen erhalten Sie von Ihrem Google Cloud-Account-Management-Team.

Befehle an Geräte senden

Sie können Cloud IoT Core verwenden, um Befehle an Geräte zu senden. Befehle sind vorübergehende, einmalige Anweisungen, die an Geräte gesendet werden, die mit Cloud IoT Core verbunden sind und das Befehlsthema abonniert haben.

Im Vergleich zu Gerätekonfigurationen sind Befehle schneller, können häufiger gesendet werden und sind unabhängig von anderen Cloud IoT Core-Features. Überlegen Sie sich bei der Wahl zwischen Befehlen und Konfigurationen, ob Sie Persistenz/Wissen im Zeitverlauf (Konfigurationen) benötigen oder Geschwindigkeit und/oder zeitgebundene Anweisungen (Befehle) bevorzugen.

Sie sind in folgenden Fällen nützlich:

  • Nachrichten zu einer bestimmten Zeit schnell an viele Geräte senden
  • Große Nachrichten zu einer bestimmten Zeit an viele Geräte senden
  • Zeitgebundene Anweisungen senden, die ablaufen sollen
  • Inkrementelle Geräteeinstellungen senden

Befehle haben folgende Eigenschaften:

  • Sie werden direkt an verbundene Geräte gesendet, die abonniert haben.
  • Sie werden nicht in Cloud IoT Core gespeichert.
  • Sie werden für Geräte verworfen, die beim Senden des Befehls nicht abonniert hatten und nicht verbunden waren.
  • Sie sind nicht eindeutig (Duplikate können gesendet werden, auch wenn dies unwahrscheinlich ist).
  • Sie werden in keiner bestimmten Reihenfolge gesendet, aber ungefähr in der Sendereihenfolge zugestellt.
  • Sie können ein beliebiges Format haben (Daten-Blob).

Derzeit unterstützt Cloud IoT Core nur Befehle über MQTT (nicht HTTP).

Befehle im Vergleich zu Konfigurationen

Cloud IoT Core unterstützt auch Gerätekonfigurationen. Konfigurationen sind konsistenter und dauerhafter als Befehle. Konfigurationen werden in Cloud IoT Core gespeichert. Bei Verwendung von MQTT wird die neueste Konfiguration schließlich an alle Geräte gesendet, die abonniert haben. Dies gilt auch für Geräte, die später abonnieren.

Die folgende Tabelle kann Ihnen helfen zu entscheiden, ob Sie einen Befehl oder eine Konfiguration verwenden:

Konfigurationen Befehle
Die letzte Konfiguration wird bis zur Bereitstellung wiederholt (MQTT). Wird für QoS 1 wiederholt, aber nicht garantiert.
Persistent, d. h., wenn ein Gerät später eine Verbindung (MQTT) oder Abfragen (HTTP) herstellt, wird trotzdem die neueste Konfiguration bereitgestellt. Nicht persistent; wird nur an Geräte gesendet, die zum beim Senden des Befehls verbunden sind.
Jede neue Version ersetzt die vorherige Version. Keine Beziehung oder Reihenfolge unter Befehlen.
Teilt einem Gerät mit, was es "sein" soll; entspricht Status in Cloud IoT Core. Teilt einem Gerät mit, was es zu einer bestimmten Zeit "tun" soll.
Höhere Latenz Geringere Latenz
In der Regel kleine Größe (max. 64 KB) Bis zu 256 KB
Beliebiges, benutzerdefiniertes Blob Beliebiges, benutzerdefiniertes Blob
1 Aktualisierung pro Sekunde und Gerät 1.000 pro Sek., pro Projekt (konfigurierbar)
2.500 pro Sek. und Registry

Da Befehle in Cloud IoT Core nicht dauerhaft gespeichert und nicht auf unbestimmte Zeit wiederholt werden, sollten Sie nicht davon ausgehen, dass Gerätetelemetrie- oder -statusdaten einen bestimmten Befehl widerspiegeln. Unter Umständen hat das Gerät den Befehl nicht erhalten oder er hat nachfolgende Befehle oder Konfigurationen erhalten. Befehle sind vorübergehend und nicht Teil der langfristigen Gerätedaten.

Verwenden Sie die Gerätelogik oder Clientanwendungen, um die Befehlsreihenfolge und Duplikate zu verwalten.

Befehl senden

Verwenden Sie die Google Cloud Console, gcloud oder die Cloud IoT Core API, um einen Befehl an ein Gerät zu senden.

Console

So senden Sie einen Befehl an ein Gerät:

  1. Rufen Sie in der Google Cloud Console die Seite Registrierungen auf.

    Zur Seite Registries

  2. Klicken Sie auf die ID der Registry für das Gerät.
  3. Klicken Sie im Registry-Menü links auf Geräte.
  4. Klicken Sie auf die ID des Geräts, an das Sie den Befehl senden möchten.
  5. Klicken Sie oben auf der Seite auf Befehl senden.
  6. Wählen Sie das Format des Befehls aus:

    • Text
    • Base64
  7. Geben Sie im Feld Befehlsdaten den Befehl ein.

  8. Geben Sie im Feld Unterordner den Namen eines Unterordners für diesen Befehl ein. Geräte, die das Platzhalterthema abonniert haben, erhalten Befehle, die an Unterordner gesendet werden.

  9. Klicken Sie auf Befehl senden.

gcloud

Führen Sie den Befehl gcloud iot devices commands send aus, um einen Befehl an ein Gerät zu senden:

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

Wenn die Befehlsdaten Sonderzeichen enthalten, verwenden Sie --command-file anstelle von --command-data.

API

Verwenden Sie die Methode "SendCommandToDevice", um einen Befehl zu senden.

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 = GsonFactory.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!"

Befehl empfangen

Um einen Befehl zu erhalten, muss ein Gerät:

  • Über das MQTT-Protokoll mit Cloud IoT Core verbunden sein.
  • Das MQTT-Thema /devices/{device-id}/commands/# (#-Platzhalter ist erforderlich) abonniert haben.

Wenn das Platzhalterthema abonniert wurde, empfängt das Gerät an devices/{device-id}/commands gesendete Befehle sowie Befehle, die an Unterordner gesendet werden (z. B. devices/{device-id}/commands/{subfolder}). Das Abonnieren eines bestimmten Unterordners wird nicht unterstützt.

Befehle werden an Geräte gesendet, die zu diesem Zeitpunkt verbunden sind und abonniert haben. Sie werden nicht für Geräte in die Warteschlange gestellt oder beibehalten, die zu einem späteren Zeitpunkt eine Verbindung herstellen und abonnieren.

Dienstqualität (Quality of Service, QoS)

Die Befehlsübermittlung hängt von der verwendeten Dienstqualitätsstufe ab:

QoS-Ebene Garantie
0 Keine Garantie (nur Best-Effort-Prinzip), selbst wenn die Anfrage OK zurückgibt.
1 Mindestens einmalige Zustellung garantiert, wenn für die sendCommandtoDevice-Anfrage OK zurückgegeben wird

Mit anderen Worten: Bei QoS 0 gilt eine Nachricht unabhängig von der Geräteantwort als erfolgreich, sobald sie gesendet wird. Bei QoS 1 bedeutet ein Erfolg, dass das Gerät die Nachrichtenzustellung bestätigt hat. Beachten Sie, dass "mindestens einmalige" Übermittlung bedeutet, dass das Gerät den Befehl mehrmals empfangen kann. Cloud IoT Core verfolgt nicht, wie oft der Befehl empfangen wurde.

Fehler

  • Wenn das Zeitlimit für den Befehl (60 Sekunden, wie unter Kontingente und Limits angegeben) erreicht wurde, wird DEADLINE_EXCEEDED zurückgegeben.

  • Wenn das Gerät nicht verbunden ist oder verbunden ist, aber nicht das MQTT-Platzhalterthema abonniert hat, wird FAILED_PRECONDITION zurückgegeben.

Logging

An Geräte gesendete Befehle sowie Bestätigungen von Geräten werden in Cloud Logging erfasst.

Preise

Befehle werden wie alle anderen über MQTT gesendeten Nachrichten abgerechnet. Weitere Informationen finden Sie unter Preise.