Device Management Samples

The samples on this page show you how to programmatically manage devices using the Cloud IoT Core API.

Create a device with EC credentials

The following code shows you how to create a device with Elliptic Curve (EC) credentials.

C#

public static object CreateEsDevice(string projectId, string cloudRegion, string registryId, string deviceId, string keyPath)
{
    var cloudIot = CreateAuthorizedClient();
    var parent = $"projects/{projectId}/locations/{cloudRegion}/registries/{registryId}";

    try
    {
        String keyText = File.ReadAllText(keyPath);
        Device body = new Device()
        {
            Id = deviceId
        };
        body.Credentials = new List<DeviceCredential>();
        body.Credentials.Add(new DeviceCredential()
        {
            PublicKey = new PublicKeyCredential()
            {
                Key = keyText,
                Format = "ES256_PEM"
            },
        });

        var device = cloudIot.Projects.Locations.Registries.Devices.Create(body, parent).Execute();
        Console.WriteLine("Device created: ");
        Console.WriteLine($"{device.Id}");
        Console.WriteLine($"\tBlocked: {device.Blocked == true}");
        Console.WriteLine($"\tConfig version: {device.Config.Version}");
        Console.WriteLine($"\tName: {device.Name}");
        Console.WriteLine($"\tState:{device.State}");
    }
    catch (Google.GoogleApiException e)
    {
        Console.WriteLine(e.Message);
        if (e.Error != null) return e.Error.Code;
        return -1;
    }
    return 0;
}

Go

// 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
}

keyBytes, err := ioutil.ReadFile(keyPath)
if err != nil {
	return nil, err
}

device := cloudiot.Device{
	Id: deviceID,
	Credentials: []*cloudiot.DeviceCredential{
		{
			PublicKey: &cloudiot.PublicKeyCredential{
				Format: "ES256_PEM",
				Key:    string(keyBytes),
			},
		},
	},
}

parent := fmt.Sprintf("projects/%s/locations/%s/registries/%s", projectID, region, registry)
response, err := client.Projects.Locations.Registries.Devices.Create(parent, &device).Do()
if err != nil {
	return nil, err
}

fmt.Println("Successfully created device.")

Java

/** Create a device that is authenticated using ES256. */
public static void createDeviceWithEs256(String deviceId, String publicKeyFilePath,
    String projectId, String cloudRegion, String registryName)
    throws GeneralSecurityException, IOException {
  GoogleCredential credential =
      GoogleCredential.getApplicationDefault().createScoped(CloudIotScopes.all());
  JsonFactory jsonFactory = JacksonFactory.getDefaultInstance();
  HttpRequestInitializer init = new RetryHttpInitializerWrapper(credential);
  final CloudIot service = new CloudIot.Builder(
      GoogleNetHttpTransport.newTrustedTransport(),jsonFactory, init)
      .setApplicationName(APP_NAME).build();

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

  PublicKeyCredential publicKeyCredential = new PublicKeyCredential();
  final String key = Files.toString(new File(publicKeyFilePath), Charsets.UTF_8);
  publicKeyCredential.setKey(key);
  publicKeyCredential.setFormat("ES256_PEM");

  DeviceCredential devCredential  = new DeviceCredential();
  devCredential.setPublicKey(publicKeyCredential);

  System.out.println("Creating device with id: " + deviceId);
  Device device = new Device();
  device.setId(deviceId);
  device.setCredentials(Arrays.asList(devCredential));

  Device createdDevice =
      service
          .projects()
          .locations()
          .registries()
          .devices()
          .create(registryPath, device)
          .execute();

  System.out.println("Created device: " + createdDevice.toPrettyString());
}

Node.js

// Client retrieved in callback
// getClient(serviceAccountJson, function(client) {...});
// const cloudRegion = 'us-central1';
// const deviceId = 'my-es-device';
// const projectId = 'adjective-noun-123';
// const registryId = 'my-registry';
const parentName = `projects/${projectId}/locations/${cloudRegion}`;
const registryName = `${parentName}/registries/${registryId}`;
const body = {
  id: deviceId,
  credentials: [
    {
      publicKey: {
        format: 'ES256_PEM',
        key: fs.readFileSync(esCertificateFile).toString()
      }
    }
  ]
};

const request = {
  parent: registryName,
  resource: body
};

client.projects.locations.registries.devices.create(request, (err, data) => {
  if (err) {
    console.log('Could not create device');
    console.log(err);
  } else {
    console.log('Created device');
    console.log(data);
  }
});

PHP

use Google\Cloud\Iot\V1\DeviceManagerClient;
use Google\Cloud\Iot\V1\Device;
use Google\Cloud\Iot\V1\DeviceCredential;
use Google\Cloud\Iot\V1\PublicKeyCredential;
use Google\Cloud\Iot\V1\PublicKeyFormat;

/**
 * Create a new device with the given id, using ES256 for
 * authentication.
 *
 * @param string $registryId IOT Device Registry ID
 * @param string $deviceId IOT Device ID
 * @param string $publicKeyFile Path to public ES256 key file.
 * @param string $projectId (optional) Google Cloud project ID
 * @param string $location (Optional) Google Cloud region
 */
function create_es_device(
    $registryId,
    $deviceId,
    $publicKeyFile,
    $projectId,
    $location = 'us-central1'
) {
    print('Creating new ES256 Device' . PHP_EOL);

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

    $publicKey = (new PublicKeyCredential())
        ->setFormat(PublicKeyFormat::ES256_PEM)
        ->setKey(file_get_contents($publicKeyFile));

    $credential = (new DeviceCredential())
        ->setPublicKey($publicKey);

    $device = (new Device())
        ->setId($deviceId)
        ->setCredentials([$credential]);

    $device = $deviceManager->createDevice($registryName, $device);

    printf('Device: %s : %s' . PHP_EOL,
        $device->getNumId(),
        $device->getId());
}

Python

This sample uses the Google API Client Library for Python.
def create_es256_device(
        service_account_json, project_id, cloud_region, registry_id,
        device_id, public_key_file):
    """Create a new device with the given id, using ES256 for
    authentication."""
    registry_name = 'projects/{}/locations/{}/registries/{}'.format(
            project_id, cloud_region, registry_id)

    client = get_client(service_account_json)
    with io.open(public_key_file) as f:
        public_key = f.read()

    # Note: You can have multiple credentials associated with a device.
    device_template = {
        'id': device_id,
        'credentials': [{
            'publicKey': {
                'format': 'ES256_PEM',
                'key': public_key
            }
        }]
    }

    devices = client.projects().locations().registries().devices()
    return devices.create(parent=registry_name, body=device_template).execute()

Ruby

# project_id  = "Your Google Cloud project ID"
# location_id = "The Cloud region the registry is located in"
# registry_id = "The registry to create a device in"
# device_id   = "The identifier of the device to create"
# cert_path   = "The path to the EC certificate"

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}/registries/#{registry_id}"

device = Cloudiot::Device.new
device.id = device_id

pubkey = Google::Apis::CloudiotV1::PublicKeyCredential.new
pubkey.key = File.read(cert_path)
pubkey.format = "ES256_PEM"

cred = Google::Apis::CloudiotV1::DeviceCredential.new
cred.public_key = pubkey

device.credentials = [cred]

# Create the device
device = iot_client.create_project_location_registry_device parent, device

puts "Device: #{device.id}"
puts "\tBlocked: #{device.blocked}"
puts "\tLast Event Time: #{device.last_event_time}"
puts "\tLast State Time: #{device.last_state_time}"
puts "\tName: #{device.name}"

Create a device with RSA credentials

The following sample shows you how to create a device with RSA credentials.

C#

public static object CreateRsaDevice(string projectId, string cloudRegion, string registryId, string deviceId, string keyPath)
{
    var cloudIot = CreateAuthorizedClient();
    var parent = $"projects/{projectId}/locations/{cloudRegion}/registries/{registryId}";

    try
    {
        String keyText = File.ReadAllText(keyPath);
        Device body = new Device()
        {
            Id = deviceId
        };
        body.Credentials = new List<DeviceCredential>();
        body.Credentials.Add(new DeviceCredential()
        {
            PublicKey = new PublicKeyCredential()
            {
                Key = keyText,
                Format = "RSA_X509_PEM"
            },
        });

        var device = cloudIot.Projects.Locations.Registries.Devices.Create(body, parent).Execute();
        Console.WriteLine("Device created: ");
        Console.WriteLine($"{device.Id}");
        Console.WriteLine($"\tBlocked: {device.Blocked == true}");
        Console.WriteLine($"\tConfig version: {device.Config.Version}");
        Console.WriteLine($"\tName: {device.Name}");
        Console.WriteLine($"\tState:{device.State}");
    }
    catch (Google.GoogleApiException e)
    {
        Console.WriteLine(e.Message);
        if (e.Error != null) return e.Error.Code;
        return -1;
    }
    return 0;
}

Go

// 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
}

keyBytes, err := ioutil.ReadFile(keyPath)
if err != nil {
	return nil, err
}

device := cloudiot.Device{
	Id: deviceID,
	Credentials: []*cloudiot.DeviceCredential{
		{
			PublicKey: &cloudiot.PublicKeyCredential{
				Format: "RSA_X509_PEM",
				Key:    string(keyBytes),
			},
		},
	},
}

parent := fmt.Sprintf("projects/%s/locations/%s/registries/%s", projectID, region, registry)
response, err := client.Projects.Locations.Registries.Devices.Create(parent, &device).Do()
if err != nil {
	return nil, err
}

fmt.Println("Successfully created device.")

Java

/** Create a device that is authenticated using RS256. */
public static void createDeviceWithRs256(String deviceId, String certificateFilePath,
                                         String projectId, String cloudRegion,
                                         String registryName)
    throws GeneralSecurityException, IOException {
  GoogleCredential credential =
      GoogleCredential.getApplicationDefault().createScoped(CloudIotScopes.all());
  JsonFactory jsonFactory = JacksonFactory.getDefaultInstance();
  HttpRequestInitializer init = new RetryHttpInitializerWrapper(credential);
  final CloudIot service = new CloudIot.Builder(
      GoogleNetHttpTransport.newTrustedTransport(),jsonFactory, init)
      .setApplicationName(APP_NAME).build();

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

  PublicKeyCredential publicKeyCredential = new PublicKeyCredential();
  String key = Files.toString(new File(certificateFilePath), Charsets.UTF_8);
  publicKeyCredential.setKey(key);
  publicKeyCredential.setFormat("RSA_X509_PEM");

  DeviceCredential devCredential = new DeviceCredential();
  devCredential.setPublicKey(publicKeyCredential);

  System.out.println("Creating device with id: " + deviceId);
  Device device = new Device();
  device.setId(deviceId);
  device.setCredentials(Arrays.asList(devCredential));
  Device createdDevice =
      service
          .projects()
          .locations()
          .registries()
          .devices()
          .create(registryPath, device)
          .execute();

  System.out.println("Created device: " + createdDevice.toPrettyString());
}

Node.js

// Client retrieved in callback
// getClient(serviceAccountJson, function(client) {...});
// const cloudRegion = 'us-central1';
// const deviceId = 'my-rsa-device';
// const projectId = 'adjective-noun-123';
// const registryId = 'my-registry';
const parentName = `projects/${projectId}/locations/${cloudRegion}`;
const registryName = `${parentName}/registries/${registryId}`;
const body = {
  id: deviceId,
  credentials: [
    {
      publicKey: {
        format: 'RSA_X509_PEM',
        key: fs.readFileSync(rsaCertificateFile).toString()
      }
    }
  ]
};

const request = {
  parent: registryName,
  resource: body
};

console.log(JSON.stringify(request));

client.projects.locations.registries.devices.create(request, (err, data) => {
  if (err) {
    console.log('Could not create device');
    console.log(err);
  } else {
    console.log('Created device');
    console.log(data);
  }
});

PHP

use Google\Cloud\Iot\V1\DeviceManagerClient;
use Google\Cloud\Iot\V1\Device;
use Google\Cloud\Iot\V1\DeviceCredential;
use Google\Cloud\Iot\V1\PublicKeyCredential;
use Google\Cloud\Iot\V1\PublicKeyFormat;

/**
 * Create a new device with the given id, using RS256 for
 * authentication.
 *
 * @param string $registryId IOT Device Registry ID
 * @param string $deviceId IOT Device ID
 * @param string $certificateFile Path to RS256 certificate file.
 * @param string $projectId (optional) Google Cloud project ID
 * @param string $location (Optional) Google Cloud region
 */
function create_rsa_device(
    $registryId,
    $deviceId,
    $certificateFile,
    $projectId,
    $location = 'us-central1'
) {
    print('Creating new RS256 Device' . PHP_EOL);

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

    $publicKey = (new PublicKeyCredential())
        ->setFormat(PublicKeyFormat::RSA_X509_PEM)
        ->setKey(file_get_contents($certificateFile));

    $credential = (new DeviceCredential())
        ->setPublicKey($publicKey);

    $device = (new Device())
        ->setId($deviceId)
        ->setCredentials([$credential]);

    $device = $deviceManager->createDevice($registryName, $device);

    printf('Device: %s : %s' . PHP_EOL,
        $device->getNumId(),
        $device->getId());
}

Python

This sample uses the Google API Client Library for Python.
def create_rs256_device(
        service_account_json, project_id, cloud_region, registry_id, device_id,
        certificate_file):
    """Create a new device with the given id, using RS256 for
    authentication."""
    registry_name = 'projects/{}/locations/{}/registries/{}'.format(
            project_id, cloud_region, registry_id)

    client = get_client(service_account_json)
    with io.open(certificate_file) as f:
        certificate = f.read()

    # Note: You can have multiple credentials associated with a device.
    device_template = {
        'id': device_id,
        'credentials': [{
            'publicKey': {
                'format': 'RSA_X509_PEM',
                'key': certificate
            }
        }]
    }

    devices = client.projects().locations().registries().devices()
    return devices.create(parent=registry_name, body=device_template).execute()

Ruby

# project_id  = "Your Google Cloud project ID"
# location_id = "The Cloud region the registry is located in"
# registry_id = "The registry to create a device in"
# device_id   = "The identifier of the device to create"
# cert_path   = "The path to the RSA certificate"

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}/registries/#{registry_id}"

credential = Google::Apis::CloudiotV1::DeviceCredential.new
credential.public_key = Google::Apis::CloudiotV1::PublicKeyCredential.new
credential.public_key.format = "RSA_X509_PEM"
credential.public_key.key = File.read(cert_path)

device = Cloudiot::Device.new
device.id = device_id
device.credentials = [credential]

# Create the device
device = iot_client.create_project_location_registry_device parent, device

puts "Device: #{device.id}"
puts "\tBlocked: #{device.blocked}"
puts "\tLast Event Time: #{device.last_event_time}"
puts "\tLast State Time: #{device.last_state_time}"
puts "\tName: #{device.name}"

Create a device without authentication credentials

You can provision a device without credentials, as shown in the following sample:

C#

public static object CreateUnauthDevice(string projectId, string cloudRegion, string registryId, string deviceId)
{
    var cloudIot = CreateAuthorizedClient();
    // The resource name of the location associated with the key rings.
    var parent = $"projects/{projectId}/locations/{cloudRegion}/registries/{registryId}";

    try
    {
        Device body = new Device()
        {
            Id = deviceId
        };
        var device = cloudIot.Projects.Locations.Registries.Devices.Create(body, parent).Execute();
        Console.WriteLine("Device created: ");
        Console.WriteLine($"{device.Id}");
        Console.WriteLine($"\tBlocked: {device.Blocked == true}");
        Console.WriteLine($"\tConfig version: {device.Config.Version}");
        Console.WriteLine($"\tName: {device.Name}");
        Console.WriteLine($"\tState:{device.State}");
    }
    catch (Google.GoogleApiException e)
    {
        Console.WriteLine(e.Message);
        if (e.Error != null) return e.Error.Code;
        return -1;
    }
    return 0;
}

Go

// 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
}

device := cloudiot.Device{
	Id: deviceID,
}
parent := fmt.Sprintf("projects/%s/locations/%s/registries/%s", projectID, region, registry)
response, err := client.Projects.Locations.Registries.Devices.Create(parent, &device).Do()
if err != nil {
	return nil, err
}

fmt.Println("Successfully created device.")

Java

/**
 * Create a device that has no credentials.
 *
 * <p>This is a valid way to construct a device, however until it is patched with a credential the
 * device will not be able to connect to Cloud IoT.
 */
public static void createDeviceWithNoAuth(String deviceId, String projectId, String cloudRegion,
                                          String registryName)
    throws GeneralSecurityException, IOException {
  GoogleCredential credential =
      GoogleCredential.getApplicationDefault().createScoped(CloudIotScopes.all());
  JsonFactory jsonFactory = JacksonFactory.getDefaultInstance();
  HttpRequestInitializer init = new RetryHttpInitializerWrapper(credential);
  final CloudIot service = new CloudIot.Builder(
      GoogleNetHttpTransport.newTrustedTransport(),jsonFactory, init)
      .setApplicationName(APP_NAME).build();

  final String registryPath = "projects/" + projectId + "/locations/" + cloudRegion
      + "/registries/" + registryName;

  System.out.println("Creating device with id: " + deviceId);
  Device device = new Device();
  device.setId(deviceId);
  device.setCredentials(new ArrayList<DeviceCredential>());
  Device createdDevice =
      service
          .projects()
          .locations()
          .registries()
          .devices()
          .create(registryPath, device)
          .execute();

  System.out.println("Created device: " + createdDevice.toPrettyString());
}

Node.js

// Client retrieved in callback
// getClient(serviceAccountJson, function(client) {...});
// const cloudRegion = 'us-central1';
// const deviceId = 'my-unauth-device';
// const projectId = 'adjective-noun-123';
// const registryId = 'my-registry';
console.log('Creating device:', deviceId);
const parentName = `projects/${projectId}/locations/${cloudRegion}`;
const registryName = `${parentName}/registries/${registryId}`;

const request = {
  parent: registryName,
  resource: {id: deviceId}
};

client.projects.locations.registries.devices.create(request, (err, data) => {
  if (err) {
    console.log('Could not create device');
    console.log(err);
  } else {
    console.log('Created device');
    console.log(data);
  }
});

PHP

use Google\Cloud\Iot\V1\DeviceManagerClient;
use Google\Cloud\Iot\V1\Device;

/**
 * Create a new device without authentication.
 *
 * @param string $registryId IOT Device Registry ID
 * @param string $deviceId IOT Device ID
 * @param string $projectId Google Cloud project ID
 * @param string $location (Optional) Google Cloud region
 */
function create_unauth_device(
    $registryId,
    $deviceId,
    $projectId,
    $location = 'us-central1'
) {
    print('Creating new Device without authentication' . PHP_EOL);

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

    $device = (new Device())
        ->setId($deviceId);

    $device = $deviceManager->createDevice($registryName, $device);

    printf('Device: %s : %s' . PHP_EOL,
        $device->getNumId(),
        $device->getId());
}

Python

This sample uses the Google API Client Library for Python.
def create_unauth_device(
        service_account_json, project_id, cloud_region, registry_id,
        device_id):
    """Create a new device without authentication."""
    registry_name = 'projects/{}/locations/{}/registries/{}'.format(
            project_id, cloud_region, registry_id)

    client = get_client(service_account_json)
    device_template = {
        'id': device_id,
    }

    devices = client.projects().locations().registries().devices()
    return devices.create(parent=registry_name, body=device_template).execute()

Ruby

# project_id  = "Your Google Cloud project ID"
# location_id = "The Cloud region the registry is located in"
# registry_id = "The registry to create a device in"
# device_id   = "The identifier of the device to create"

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}/registries/#{registry_id}"

device = Cloudiot::Device.new
device.id = device_id

# Create the device
device = iot_client.create_project_location_registry_device parent, device

puts "Device: #{device.id}"
puts "\tBlocked: #{device.blocked}"
puts "\tLast Event Time: #{device.last_event_time}"
puts "\tLast State Time: #{device.last_state_time}"
puts "\tName: #{device.name}"

List devices in a registry

The following sample show you how to list the devices in a registry:

C#

public static object ListDevices(string projectId, string cloudRegion, string registryId)
{
    var cloudIot = CreateAuthorizedClient();
    // The resource name of the location associated with the key rings.
    var parent = $"projects/{projectId}/locations/{cloudRegion}/registries/{registryId}";
    try
    {
        var result = cloudIot.Projects.Locations.Registries.Devices.List(parent).Execute();
        Console.WriteLine("Devices: ");
        result.Devices.ToList().ForEach(response =>
        {
            Console.WriteLine($"{response.Id}");
            Console.WriteLine($"\t{response.Config}");
            Console.WriteLine($"\t{response.Name}");
        });
    }
    catch (Google.GoogleApiException e)
    {
        Console.WriteLine(e.Message);
        return e.Error.Code;
    }
    return 0;
}

Go

// 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
}

parent := fmt.Sprintf("projects/%s/locations/%s/registries/%s", projectID, region, registry)
response, err := client.Projects.Locations.Registries.Devices.List(parent).Do()
if err != nil {
	return nil, err
}

fmt.Println("Devices:")
for _, device := range response.Devices {
	fmt.Println("\t", device.Id)
}

Java

/** Print all of the devices in this registry to standard out. */
public static void listDevices(String projectId, String cloudRegion, String registryName) throws
    GeneralSecurityException, IOException {
  GoogleCredential credential =
      GoogleCredential.getApplicationDefault().createScoped(CloudIotScopes.all());
  JsonFactory jsonFactory = JacksonFactory.getDefaultInstance();
  HttpRequestInitializer init = new RetryHttpInitializerWrapper(credential);
  final CloudIot service = new CloudIot.Builder(
      GoogleNetHttpTransport.newTrustedTransport(),jsonFactory, init)
      .setApplicationName(APP_NAME).build();

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

  List<Device> devices =
      service
          .projects()
          .locations()
          .registries()
          .devices()
          .list(registryPath)
          .execute()
          .getDevices();

  if (devices != null) {
    System.out.println("Found " + devices.size() + " devices");
    for (Device d : devices) {
      System.out.println("Id: " + d.getId());
      if (d.getConfig() != null) {
        // Note that this will show the device config in Base64 encoded format.
        System.out.println("Config: " + d.getConfig().toPrettyString());
      }
      System.out.println();
    }
  } else {
    System.out.println("Registry has no devices.");
  }
}

Node.js

// Client retrieved in callback
// getClient(serviceAccountJson, function(client) {...});
// const cloudRegion = 'us-central1';
// const projectId = 'adjective-noun-123';
// const registryId = 'my-registry';
const parentName = `projects/${projectId}/locations/${cloudRegion}`;
const registryName = `${parentName}/registries/${registryId}`;

const request = {
  parent: registryName
};

client.projects.locations.registries.devices.list(request, (err, data) => {
  if (err) {
    console.log('Could not list devices');
    console.log(err);
  } else {
    console.log('Current devices in registry:', data['devices']);
  }
});

PHP

use Google\Cloud\Iot\V1\DeviceManagerClient;

/**
 * List all devices in the registry.
 *
 * @param string $registryId IOT Device Registry ID
 * @param string $projectId Google Cloud project ID
 * @param string $location (Optional) Google Cloud region
 */
function list_devices(
    $registryId,
    $projectId,
    $location = 'us-central1'
) {
    print('Listing devices' . PHP_EOL);

    // Instantiate a client.
    $deviceManager = new DeviceManagerClient();

    // Format the full registry path
    $registryName = $deviceManager->registryName($projectId, $location, $registryId);

    // Call the API
    $devices = $deviceManager->listDevices($registryName);

    // Print the result
    foreach ($devices->iterateAllElements() as $device) {
        printf('Device: %s : %s' . PHP_EOL,
            $device->getNumId(),
            $device->getId());
    }
}

Python

This sample uses the Google API Client Library for Python.
def list_devices(
        service_account_json, project_id, cloud_region, registry_id):
    """List all devices in the registry."""
    print('Listing devices')
    registry_path = 'projects/{}/locations/{}/registries/{}'.format(
            project_id, cloud_region, registry_id)
    client = get_client(service_account_json)
    devices = client.projects().locations().registries().devices(
            ).list(parent=registry_path).execute().get('devices', [])

    for device in devices:
            print('Device: {} : {}'.format(
                    device.get('numId'),
                    device.get('id')))

    return devices

Ruby

# project_id  = "Your Google Cloud project ID"
# location_id = "The Cloud region the registry is located in"
# registry_id = "The registry to list devices from"

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
resource = "projects/#{project_id}/locations/#{location_id}/registries/#{registry_id}"

# List the devices in the provided region
response = iot_client.list_project_location_registry_devices(
  resource
)

puts "Devices:"
if response.devices && response.devices.any?
  response.devices.each { |device| puts "\t#{device.id}" }
else
  puts "\tNo device registries found in this region for your project."
end

Get a device

The following sample shows you how to retrieve a device and its metadata from a device registry:

C#

public static object GetDevice(string projectId, string cloudRegion, string registryId, string deviceId)
{
    var cloudIot = CreateAuthorizedClient();
    // The resource name of the location associated with the key rings.
    var name = $"projects/{projectId}/locations/{cloudRegion}/registries/{registryId}/devices/{deviceId}";

    try
    {
        var device = cloudIot.Projects.Locations.Registries.Devices.Get(name).Execute();
        Console.WriteLine("Device: ");
        Console.WriteLine($"{device.Id}");
        Console.WriteLine($"\tBlocked: {device.Blocked == true}");
        Console.WriteLine($"\tConfig version: {device.Config.Version}");
        Console.WriteLine($"\tFirst Credential Expiry: {device.Credentials.First().ExpirationTime}");
        Console.WriteLine($"\tLast State Time:{device.LastStateTime}");
        Console.WriteLine($"\tName: {device.Name}");
        Console.WriteLine($"\tState:{device.State}");
    }
    catch (Google.GoogleApiException e)
    {
        Console.WriteLine(e.Message);
        if (e.Error != null) return e.Error.Code;
        return -1;
    }
    return 0;
}

Go

// 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
}

path := fmt.Sprintf("projects/%s/locations/%s/registries/%s/devices/%s", projectID, region, registry, device)
response, err := client.Projects.Locations.Registries.Devices.Get(path).Do()
if err != nil {
	return nil, err
}

fmt.Println("\tId: ", response.Id)
for _, credential := range response.Credentials {
	fmt.Println("\t\tCredential Expire: ", credential.ExpirationTime)
	fmt.Println("\t\tCredential Type: ", credential.PublicKey.Format)
	fmt.Println("\t\t--------")
}
fmt.Println("\tLast Config Ack: ", response.LastConfigAckTime)
fmt.Println("\tLast Config Send: ", response.LastConfigSendTime)
fmt.Println("\tLast Event Time: ", response.LastEventTime)
fmt.Println("\tLast Heartbeat Time: ", response.LastHeartbeatTime)
fmt.Println("\tLast State Time: ", response.LastStateTime)
fmt.Println("\tNumId: ", response.NumId)

return response, err

Java

/** Retrieves device metadata from a registry. **/
public static Device getDevice(String deviceId, String projectId, String cloudRegion,
                               String registryName) throws GeneralSecurityException, IOException {
  GoogleCredential credential =
      GoogleCredential.getApplicationDefault().createScoped(CloudIotScopes.all());
  JsonFactory jsonFactory = JacksonFactory.getDefaultInstance();
  HttpRequestInitializer init = new RetryHttpInitializerWrapper(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);

  System.out.println("Retrieving device " + devicePath);
  return service.projects().locations().registries().devices().get(devicePath).execute();
}

Node.js

// Client retrieved in callback
// getClient(serviceAccountJson, function(client) {...});
// const cloudRegion = 'us-central1';
// const deviceId = 'my-device';
// const projectId = 'adjective-noun-123';
// const registryId = 'my-registry';
const parentName = `projects/${projectId}/locations/${cloudRegion}`;
const registryName = `${parentName}/registries/${registryId}`;
const request = {
  name: `${registryName}/devices/${deviceId}`
};

client.projects.locations.registries.devices.get(request, (err, data) => {
  if (err) {
    console.log('Could not find device:', deviceId);
    console.log(err);
  } else {
    console.log('Found device:', deviceId);
    console.log(data);
  }
});

PHP

use Google\Cloud\Iot\V1\DeviceManagerClient;
use Google\Cloud\Iot\V1\PublicKeyFormat;

/**
 * Retrieve the device with the given id.
 *
 * @param string $registryId IOT Device Registry ID
 * @param string $deviceId IOT Device ID
 * @param string $projectId Google Cloud project ID
 * @param string $location (Optional) Google Cloud region
 */
function get_device(
    $registryId,
    $deviceId,
    $projectId,
    $location = 'us-central1'
) {
    print('Getting device' . PHP_EOL);

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

    $device = $deviceManager->getDevice($deviceName);

    $formats = [
        PublicKeyFormat::UNSPECIFIED_PUBLIC_KEY_FORMAT => 'unspecified',
        PublicKeyFormat::RSA_X509_PEM => 'RSA_X509_PEM',
        PublicKeyFormat::ES256_PEM => 'ES256_PEM',
        PublicKeyFormat::RSA_PEM => 'RSA_PEM',
        PublicKeyFormat::ES256_X509_PEM => 'ES256_X509_PEM',
    ];

    printf('ID: %s' . PHP_EOL, $device->getId());
    printf('Name: %s' . PHP_EOL, $device->getName());
    foreach ($device->getCredentials() as $credential) {
        print('Certificate:' . PHP_EOL);
        printf('    Format: %s' . PHP_EOL,
            $formats[$credential->getPublicKey()->getFormat()]);
        printf('    Expiration: %s' . PHP_EOL,
            $credential->getExpirationTime()->toDateTime()->format('Y-m-d H:i:s'));
    }
    printf('Data: %s' . PHP_EOL, $device->getConfig()->getBinaryData());
    printf('Version: %s' . PHP_EOL, $device->getConfig()->getVersion());
    printf('Update Time: %s' . PHP_EOL,
        $device->getConfig()->getCloudUpdateTime()->toDateTime()->format('Y-m-d H:i:s'));
}

Python

This sample uses the Google API Client Library for Python.
def get_device(
        service_account_json, project_id, cloud_region, registry_id,
        device_id):
    """Retrieve the device with the given id."""
    print('Getting device')
    client = get_client(service_account_json)
    registry_name = 'projects/{}/locations/{}/registries/{}'.format(
            project_id, cloud_region, registry_id)

    device_name = '{}/devices/{}'.format(registry_name, device_id)
    devices = client.projects().locations().registries().devices()
    device = devices.get(name=device_name).execute()

    print('Id : {}'.format(device.get('id')))
    print('Name : {}'.format(device.get('name')))
    print('Credentials:')
    if device.get('credentials') is not None:
        for credential in device.get('credentials'):
            keyinfo = credential.get('publicKey')
            print('\tcertificate: \n{}'.format(keyinfo.get('key')))
            print('\tformat : {}'.format(keyinfo.get('format')))
            print('\texpiration: {}'.format(credential.get('expirationTime')))

    print('Config:')
    print('\tdata: {}'.format(device.get('config').get('data')))
    print('\tversion: {}'.format(device.get('config').get('version')))
    print('\tcloudUpdateTime: {}'.format(device.get('config').get(
            'cloudUpdateTime')))

    return device

Ruby

# project_id  = "Your Google Cloud project ID"
# location_id = "The Cloud region the registry is located in"
# registry_id = "The registry to get a device from"
# device_id   = "The identifier of the device to get"

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}"

# List the devices in the provided region
device = iot_client.get_project_location_registry_device(
  resource
)

puts "Device: #{device.id}"
puts "\tBlocked: #{device.blocked}"
puts "\tLast Event Time: #{device.last_event_time}"
puts "\tLast State Time: #{device.last_state_time}"
puts "\tName: #{device.name}"
puts "\tCertificate formats:"
if device.credentials
  device.credentials.each { |cert| puts "\t\t#{cert.public_key.format}"}
else
  puts "\t\tNo certificates for device"
end

Get device state

The following examples show you how to retrieve device state from a device registry:

C#

public static object GetDeviceStates(string projectId, string cloudRegion, string registryId, string deviceId)
{
    var cloudIot = CreateAuthorizedClient();

    // The resource name of the location associated with the key rings.
    var name = $"projects/{projectId}/locations/{cloudRegion}/registries/{registryId}/devices/{deviceId}";

    try
    {
        Console.WriteLine("States: ");
        var res = cloudIot.Projects.Locations.Registries.Devices.States.List(name).Execute();
        res.DeviceStates.ToList().ForEach(state =>
        {
            Console.WriteLine($"\t{state.UpdateTime}: {state.BinaryData}");
        });
    }
    catch (Google.GoogleApiException e)
    {
        Console.WriteLine(e.Message);
        if (e.Error != null) return e.Error.Code;
        return -1;
    }
    return 0;
}

Go

// 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
}

path := fmt.Sprintf("projects/%s/locations/%s/registries/%s/devices/%s", projectID, region, registry, device)
response, err := client.Projects.Locations.Registries.Devices.States.List(path).Do()
if err != nil {
	return nil, err
}

fmt.Println("Successfully retrieved device states!")

for _, state := range response.DeviceStates {
	fmt.Println(state.UpdateTime, " : ", state.BinaryData)
}

Java

/** Retrieves device metadata from a registry. **/
public static List<DeviceState> getDeviceStates(
    String deviceId, String projectId, String cloudRegion, String registryName)
    throws GeneralSecurityException, IOException {
  GoogleCredential credential =
      GoogleCredential.getApplicationDefault().createScoped(CloudIotScopes.all());
  JsonFactory jsonFactory = JacksonFactory.getDefaultInstance();
  HttpRequestInitializer init = new RetryHttpInitializerWrapper(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);

  System.out.println("Retrieving device states " + devicePath);

  ListDeviceStatesResponse resp  = service
      .projects()
      .locations()
      .registries()
      .devices()
      .states()
      .list(devicePath).execute();

  return resp.getDeviceStates();
}

Node.js

// Client retrieved in callback
// getClient(serviceAccountJson, function(client) {...});
// const cloudRegion = 'us-central1';
// const deviceId = 'my-device';
// const projectId = 'adjective-noun-123';
// const registryId = 'my-registry';
const parentName = `projects/${projectId}/locations/${cloudRegion}`;
const registryName = `${parentName}/registries/${registryId}`;
const request = {
  name: `${registryName}/devices/${deviceId}`
};

client.projects.locations.registries.devices.states.list(request,
  (err, data) => {
    if (err) {
      console.log('Could not find device:', deviceId);
      console.log(err);
    } else {
      console.log('State:', data);
    }
  });

PHP

use Google\Cloud\Iot\V1\DeviceManagerClient;

/**
 * Retrieve a device's state blobs.
 *
 * @param string $registryId IOT Device Registry ID
 * @param string $deviceId IOT Device ID
 * @param string $projectId Google Cloud project ID
 * @param string $location (Optional) Google Cloud region
 */
function get_device_state(
    $registryId,
    $deviceId,
    $projectId,
    $location = 'us-central1'
) {
    print('Getting device state' . PHP_EOL);

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

    $response = $deviceManager->listDeviceStates($deviceName);

    foreach ($response->getDeviceStates() as $state) {
        print('State:' . PHP_EOL);
        printf('    Data: %s' . PHP_EOL, $state->getBinaryData());
        printf('    Update Time: %s' . PHP_EOL,
            $state->getUpdateTime()->toDateTime()->format('Y-m-d H:i:s'));
    }
}

Python

This sample uses the Google API Client Library for Python.
def get_state(
        service_account_json, project_id, cloud_region, registry_id,
        device_id):
    """Retrieve a device's state blobs."""
    client = get_client(service_account_json)
    registry_name = 'projects/{}/locations/{}/registries/{}'.format(
            project_id, cloud_region, registry_id)

    device_name = '{}/devices/{}'.format(registry_name, device_id)
    devices = client.projects().locations().registries().devices()
    state = devices.states().list(name=device_name, numStates=5).execute()

    print('State: {}\n'.format(state))

    return state

Ruby

# project_id  = "Your Google Cloud project ID"
# location_id = "The Cloud region the registry is located in"
# registry_id = "The registry to get device states from"
# device_id   = "The identifier of the device to get states for"

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}"

# List the configurations for the provided device
res = iot_client.list_project_location_registry_device_states(
  resource
)
if res.device_states
  res.device_states.each do |state|
    puts "#{state.update_time}: #{state.binary_data}"
  end
else
  puts "No state messages"
end

Patch a device with EC credentials

The following sample shows you how to patch a device with Elliptic Curve (EC) credentials:

C#

public static object PatchEsDevice(string projectId, string cloudRegion, string registryId, string deviceId, string keyPath)
{
    var cloudIot = CreateAuthorizedClient();
    var name = $"projects/{projectId}/locations/{cloudRegion}/registries/{registryId}/devices/{deviceId}";

    try
    {
        String keyText = File.ReadAllText(keyPath);
        Device body = new Device();
        body.Credentials = new List<DeviceCredential>();
        body.Credentials.Add(new DeviceCredential()
        {
            PublicKey = new PublicKeyCredential()
            {
                Key = keyText,
                Format = "ES256_PEM"
            },
        });

        var req = cloudIot.Projects.Locations.Registries.Devices.Patch(body, name);
        req.UpdateMask = "credentials";
        var device = req.Execute();
        Console.WriteLine("Device patched: ");
        Console.WriteLine($"{device.Id}");
        Console.WriteLine($"\tBlocked: {device.Blocked == true}");
        Console.WriteLine($"\tConfig version: {device.Config.Version}");
        Console.WriteLine($"\tName: {device.Name}");
        Console.WriteLine($"\tState:{device.State}");
    }
    catch (Google.GoogleApiException e)
    {
        Console.WriteLine(e.Message);
        if (e.Error != null) return e.Error.Code;
        return -1;
    }
    return 0;
}

Go

// 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
}

keyBytes, err := ioutil.ReadFile(keyPath)
if err != nil {
	return nil, err
}

device := cloudiot.Device{
	Id: deviceID,
	Credentials: []*cloudiot.DeviceCredential{
		{
			PublicKey: &cloudiot.PublicKeyCredential{
				Format: "ES256_PEM",
				Key:    string(keyBytes),
			},
		},
	},
}

parent := fmt.Sprintf("projects/%s/locations/%s/registries/%s/devices/%s", projectID, region, registry, deviceID)
response, err := client.Projects.Locations.Registries.Devices.
	Patch(parent, &device).UpdateMask("credentials").Do()
if err != nil {
	return nil, err
}

fmt.Println("Successfully patched device.")

Java

/** Patch the device to add an ES256 key for authentication. */
public static void patchEs256ForAuth(String deviceId, String publicKeyFilePath, String projectId,
                                     String cloudRegion, String registryName)
    throws GeneralSecurityException, IOException {
  GoogleCredential credential =
      GoogleCredential.getApplicationDefault().createScoped(CloudIotScopes.all());
  JsonFactory jsonFactory = JacksonFactory.getDefaultInstance();
  HttpRequestInitializer init = new RetryHttpInitializerWrapper(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);

  PublicKeyCredential publicKeyCredential = new PublicKeyCredential();
  String key = Files.toString(new File(publicKeyFilePath), Charsets.UTF_8);
  publicKeyCredential.setKey(key);
  publicKeyCredential.setFormat("ES256_PEM");

  DeviceCredential devCredential = new DeviceCredential();
  devCredential.setPublicKey(publicKeyCredential);

  Device device = new Device();
  device.setCredentials(Arrays.asList(devCredential));

  Device patchedDevice =
      service
          .projects()
          .locations()
          .registries()
          .devices()
          .patch(devicePath, device)
          .setUpdateMask("credentials")
          .execute();

  System.out.println("Patched device is " + patchedDevice.toPrettyString());
}

Node.js

// Client retrieved in callback
// getClient(serviceAccountJson, function(client) {...});
// const cloudRegion = 'us-central1';
// const deviceId = 'my-es-device';
// const projectId = 'adjective-noun-123';
// const registryId = 'my-registry';
const parentName =
    `projects/${projectId}/locations/${cloudRegion}`;
const registryName = `${parentName}/registries/${registryId}`;
const request = {
  name: `${registryName}/devices/${deviceId}`,
  updateMask: 'credentials',
  resource: {
    credentials: [
      {
        publicKey: {
          format: 'ES256_PEM',
          key: fs.readFileSync(esPublicKeyFile).toString()
        }
      }
    ]
  }
};

client.projects.locations.registries.devices.patch(request, (err, data) => {
  if (err) {
    console.log('Error patching device:', deviceId);
    console.log(err);
  } else {
    console.log('Patched device:', deviceId);
    console.log(data);
  }
});

PHP

use Google\Cloud\Iot\V1\DeviceManagerClient;
use Google\Cloud\Iot\V1\Device;
use Google\Cloud\Iot\V1\DeviceCredential;
use Google\Cloud\Iot\V1\PublicKeyCredential;
use Google\Cloud\Iot\V1\PublicKeyFormat;
use Google\Protobuf\FieldMask;

/**
 * Patch the device to add an ES256 public key to the device.
 *
 * @param string $registryId IOT Device Registry ID
 * @param string $deviceId IOT Device ID
 * @param string $publicKeyFile Path to public ES256 key file.
 * @param string $projectId Google Cloud project ID
 * @param string $location (Optional) Google Cloud region
 */
function patch_es(
    $registryId,
    $deviceId,
    $publicKeyFile,
    $projectId,
    $location = 'us-central1'
) {
    print('Patch device with ES256 certificate' . PHP_EOL);

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

    $publicKey = (new PublicKeyCredential())
        ->setFormat(PublicKeyFormat::ES256_PEM)
        ->setKey(file_get_contents($publicKeyFile));

    $credential = (new DeviceCredential())
        ->setPublicKey($publicKey);

    $device = (new Device())
        ->setName($deviceName)
        ->setCredentials([$credential]);

    $updateMask = (new FieldMask())
        ->setPaths(['credentials']);

    $device = $deviceManager->updateDevice($device, $updateMask);
    printf('Updated device %s' . PHP_EOL, $device->getName());
}

Python

This sample uses the Google API Client Library for Python.
def patch_es256_auth(
        service_account_json, project_id, cloud_region, registry_id,
        device_id, public_key_file):
    """Patch the device to add an ES256 public key to the device."""
    print('Patch device with ES256 certificate')
    client = get_client(service_account_json)
    registry_path = 'projects/{}/locations/{}/registries/{}'.format(
            project_id, cloud_region, registry_id)

    with io.open(public_key_file) as f:
        public_key = f.read()

    patch = {
        'credentials': [{
            'publicKey': {
                'format': 'ES256_PEM',
                'key': public_key
            }
        }]
    }

    device_name = '{}/devices/{}'.format(registry_path, device_id)

    return client.projects().locations().registries().devices().patch(
            name=device_name, updateMask='credentials', body=patch).execute()

Ruby

# project_id  = "Your Google Cloud project ID"
# location_id = "The Cloud region the registry is located in"
# registry_id = "The registry to create a device in"
# device_id = "The identifier of the device to patch"
# cert_path = "The path to the EC certificate"

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}/registries/#{registry_id}"
path = "#{parent}/devices/#{device_id}"

pubkey= Google::Apis::CloudiotV1::PublicKeyCredential.new
pubkey.key = File.read(cert_path)
pubkey.format = "ES256_PEM"

cred = Google::Apis::CloudiotV1::DeviceCredential.new
cred.public_key = pubkey

device = Cloudiot::Device.new
device.credentials = [cred]

# Patch the device
device = iot_client.patch_project_location_registry_device(
  path, device, update_mask: "credentials"
)

puts "Device: #{device.id}"
puts "\tBlocked: #{device.blocked}"
puts "\tLast Event Time: #{device.last_event_time}"
puts "\tLast State Time: #{device.last_state_time}"
puts "\tName: #{device.name}"
puts "\tCertificate formats:"
if device.credentials
  device.credentials.each { |cert| puts "\t\t#{cert.public_key.format}"}
else
  puts "\t\tNo certificates for device"
end

Patch a device with RSA credentials

The following sample shows you how to patch a device with RSA credentials:

C#

public static object PatchRsaDevice(string projectId, string cloudRegion, string registryId, string deviceId, string keyPath)
{
    var cloudIot = CreateAuthorizedClient();
    var name = $"projects/{projectId}/locations/{cloudRegion}/registries/{registryId}/devices/{deviceId}";

    try
    {
        String keyText = File.ReadAllText(keyPath);
        Device body = new Device();
        body.Credentials = new List<DeviceCredential>();
        body.Credentials.Add(new DeviceCredential()
        {
            PublicKey = new PublicKeyCredential()
            {
                Key = keyText,
                Format = "RSA_X509_PEM"
            },
        });

        var req = cloudIot.Projects.Locations.Registries.Devices.Patch(body, name);
        req.UpdateMask = "credentials";
        var device = req.Execute();
        Console.WriteLine("Device patched: ");
        Console.WriteLine($"{device.Id}");
        Console.WriteLine($"\tBlocked: {device.Blocked == true}");
        Console.WriteLine($"\tConfig version: {device.Config.Version}");
        Console.WriteLine($"\tName: {device.Name}");
        Console.WriteLine($"\tState:{device.State}");
    }
    catch (Google.GoogleApiException e)
    {
        Console.WriteLine(e.Message);
        if (e.Error != null) return e.Error.Code;
        return -1;
    }
    return 0;
}

Go

// 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
}

keyBytes, err := ioutil.ReadFile(keyPath)
if err != nil {
	return nil, err
}

device := cloudiot.Device{
	Id: deviceID,
	Credentials: []*cloudiot.DeviceCredential{
		{
			PublicKey: &cloudiot.PublicKeyCredential{
				Format: "RSA_X509_PEM",
				Key:    string(keyBytes),
			},
		},
	},
}

parent := fmt.Sprintf("projects/%s/locations/%s/registries/%s/devices/%s", projectID, region, registry, deviceID)
response, err := client.Projects.Locations.Registries.Devices.
	Patch(parent, &device).UpdateMask("credentials").Do()
if err != nil {
	return nil, err
}

fmt.Println("Successfully patched device.")

Java

/** Patch the device to add an RSA256 key for authentication. */
public static void patchRsa256ForAuth(String deviceId, String publicKeyFilePath, String projectId,
                                      String cloudRegion,
                                      String registryName)
    throws GeneralSecurityException, IOException {
  GoogleCredential credential =
      GoogleCredential.getApplicationDefault().createScoped(CloudIotScopes.all());
  JsonFactory jsonFactory = JacksonFactory.getDefaultInstance();
  HttpRequestInitializer init = new RetryHttpInitializerWrapper(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);

  PublicKeyCredential publicKeyCredential = new PublicKeyCredential();
  String key = Files.toString(new File(publicKeyFilePath), Charsets.UTF_8);
  publicKeyCredential.setKey(key);
  publicKeyCredential.setFormat("RSA_X509_PEM");

  DeviceCredential devCredential = new DeviceCredential();
  devCredential.setPublicKey(publicKeyCredential);

  Device device = new Device();
  device.setCredentials(Arrays.asList(devCredential));

  Device patchedDevice =
      service
          .projects()
          .locations()
          .registries()
          .devices()
          .patch(devicePath, device)
          .setUpdateMask("credentials")
          .execute();

  System.out.println("Patched device is " + patchedDevice.toPrettyString());
}

Node.js

// Client retrieved in callback
// getClient(serviceAccountJson, function(client) {...});
// const cloudRegion = 'us-central1';
// const deviceId = 'my-rsa-device';
// const projectId = 'adjective-noun-123';
// const registryId = 'my-registry';
const parentName =
    `projects/${projectId}/locations/${cloudRegion}`;
const registryName = `${parentName}/registries/${registryId}`;
const request = {
  name: `${registryName}/devices/${deviceId}`,
  updateMask: 'credentials',
  resource: {
    credentials: [
      {
        publicKey: {
          format: 'RSA_X509_PEM',
          key: fs.readFileSync(rsaPublicKeyFile).toString()
        }
      }
    ]
  }
};

client.projects.locations.registries.devices.patch(request, (err, data) => {
  if (err) {
    console.log('Error patching device:', deviceId);
    console.log(err);
  } else {
    console.log('Patched device:', deviceId);
    console.log(data);
  }
});

PHP

use Google\Cloud\Iot\V1\DeviceManagerClient;
use Google\Cloud\Iot\V1\Device;
use Google\Cloud\Iot\V1\DeviceCredential;
use Google\Cloud\Iot\V1\PublicKeyCredential;
use Google\Cloud\Iot\V1\PublicKeyFormat;
use Google\Protobuf\FieldMask;

/**
 * Patch the device to add an RSA256 public key to the device.
 *
 * @param string $registryId IOT Device Registry ID
 * @param string $deviceId IOT Device ID
 * @param string $certificateFile Path to RS256 certificate file.
 * @param string $projectId Google Cloud project ID
 * @param string $location (Optional) Google Cloud region
 */
function patch_rsa(
    $registryId,
    $deviceId,
    $certificateFile,
    $projectId,
    $location = 'us-central1'
) {
    print('Patch device with RSA256 certificate' . PHP_EOL);

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

    $publicKey = (new PublicKeyCredential())
        ->setFormat(PublicKeyFormat::RSA_X509_PEM)
        ->setKey(file_get_contents($certificateFile));

    $credential = (new DeviceCredential())
        ->setPublicKey($publicKey);

    $device = (new Device())
        ->setName($deviceName)
        ->setCredentials([$credential]);

    $updateMask = (new FieldMask())
        ->setPaths(['credentials']);

    $device = $deviceManager->updateDevice($device, $updateMask);
    printf('Updated device %s' . PHP_EOL, $device->getName());
}

Python

This sample uses the Google API Client Library for Python.
def patch_rsa256_auth(
        service_account_json, project_id, cloud_region, registry_id, device_id,
        public_key_file):
    """Patch the device to add an RSA256 public key to the device."""
    print('Patch device with RSA256 certificate')
    client = get_client(service_account_json)
    registry_path = 'projects/{}/locations/{}/registries/{}'.format(
            project_id, cloud_region, registry_id)

    with io.open(public_key_file) as f:
        public_key = f.read()

    patch = {
        'credentials': [{
            'publicKey': {
                'format': 'RSA_X509_PEM',
                'key': public_key
            }
        }]
    }

    device_name = '{}/devices/{}'.format(registry_path, device_id)

    return client.projects().locations().registries().devices().patch(
            name=device_name, updateMask='credentials', body=patch).execute()

Ruby

# project_id  = "Your Google Cloud project ID"
# location_id = "The Cloud region the registry is located in"
# registry_id = "The registry to create a device in"
# device_id   = "The identifier of the device to patch"
# cert_path   = "The path to the RSA certificate"

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}/registries/#{registry_id}"
path   = "#{parent}/devices/#{device_id}"

credential = Google::Apis::CloudiotV1::DeviceCredential.new
credential.public_key = Google::Apis::CloudiotV1::PublicKeyCredential.new
credential.public_key.format = "RSA_X509_PEM"
credential.public_key.key = File.read(cert_path)

device = Cloudiot::Device.new
device.credentials = [credential]

# Create the device
device = iot_client.patch_project_location_registry_device(
  path, device, update_mask: "credentials"
)

puts "Device: #{device.id}"
puts "\tBlocked: #{device.blocked}"
puts "\tLast Event Time: #{device.last_event_time}"
puts "\tLast State Time: #{device.last_state_time}"
puts "\tName: #{device.name}"
puts "\tCertificate formats:"
if device.credentials
  device.credentials.each { |cert| puts "\t\t#{cert.public_key.format}"}
else
  puts "\t\tNo certificates for device"
end

Delete a device

The following sample shows you how to delete a device from a registry:

C#

public static object DeleteDevice(string projectId, string cloudRegion, string registryId, string deviceId)
{
    var cloudIot = CreateAuthorizedClient();
    // The resource name of the location associated with the key rings.
    var name = $"projects/{projectId}/locations/{cloudRegion}/registries/{registryId}/devices/{deviceId}";

    try
    {
        var res = cloudIot.Projects.Locations.Registries.Devices.Delete(name).Execute();
        Console.WriteLine($"Removed device: {deviceId}");
    }
    catch (Google.GoogleApiException e)
    {
        Console.WriteLine(e.Message);
        if (e.Error != null) return e.Error.Code;
        return -1;
    }
    return 0;
}

Go

// 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
}

path := fmt.Sprintf("projects/%s/locations/%s/registries/%s/devices/%s", projectID, region, registry, deviceID)
response, err := client.Projects.Locations.Registries.Devices.Delete(path).Do()
if err != nil {
	return nil, err
}

fmt.Println("Deleted device!")

Java

/** Delete the given device from the registry. */
public static void deleteDevice(String deviceId, String projectId, String cloudRegion,
                                String registryName)
    throws GeneralSecurityException, IOException {
  GoogleCredential credential =
      GoogleCredential.getApplicationDefault().createScoped(CloudIotScopes.all());
  JsonFactory jsonFactory = JacksonFactory.getDefaultInstance();
  HttpRequestInitializer init = new RetryHttpInitializerWrapper(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);

  System.out.println("Deleting device " + devicePath);
  service.projects().locations().registries().devices().delete(devicePath).execute();
}

Node.js

// Client retrieved in callback
// getClient(serviceAccountJson, function(client) {...});
// const cloudRegion = 'us-central1';
// const projectId = 'adjective-noun-123';
// const registryId = 'my-registry';
const parentName = `projects/${projectId}/locations/${cloudRegion}`;
const registryName = `${parentName}/registries/${registryId}`;
const request = {
  name: `${registryName}/devices/${deviceId}`
};

client.projects.locations.registries.devices.delete(request, (err, data) => {
  if (err) {
    console.log('Could not delete device:', deviceId);
    console.log(err);
  } else {
    console.log('Successfully deleted device:', deviceId);
    console.log(data);
    if (cb) {
      cb();
    }
  }
});

PHP

use Google\Cloud\Iot\V1\DeviceManagerClient;

/**
 * Delete the device with the given id.
 *
 * @param string $registryId IOT Device Registry ID
 * @param string $deviceId IOT Device ID
 * @param string $projectId Google Cloud project ID
 * @param string $location (Optional) Google Cloud region
 */
function delete_device(
    $registryId,
    $deviceId,
    $projectId,
    $location = 'us-central1'
) {
    print('Deleting Device' . PHP_EOL);

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

    $response = $deviceManager->deleteDevice($deviceName);

    printf('Deleted %s' . PHP_EOL, $deviceName);
}

Python

This sample uses the Google API Client Library for Python.
def delete_device(
        service_account_json, project_id, cloud_region, registry_id,
        device_id):
    """Delete the device with the given id."""
    print('Delete device')
    client = get_client(service_account_json)
    registry_name = 'projects/{}/locations/{}/registries/{}'.format(
            project_id, cloud_region, registry_id)

    device_name = '{}/devices/{}'.format(registry_name, device_id)

    devices = client.projects().locations().registries().devices()
    return devices.delete(name=device_name).execute()

Ruby

# project_id  = "Your Google Cloud project ID"
# location_id = "The Cloud region the registry is located in"
# registry_id = "The registry to create a device in"
# device_id   = "The identifier of the device to create"

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}"
device_path = "#{parent}/registries/#{registry_id}/devices/#{device_id}"

# Create the device
res = iot_client.delete_project_location_registry_device(
  device_path
)

puts "Deleted device."

Send a large file to a device

As noted in Quotas and Limits, you cannot directly send a configuration file to a device if the file is larger than 64 KB. However, you might have a file you want to send, such as a firmware update, that is larger than 64 KB. To bypass the 64 KB limit, you can upload and store the file in Cloud Storage, and then notify the device when the file is available. The device can then download the file from Cloud Storage.

The following sample shows how to:

  1. Upload a file to Cloud Storage
  2. Make the file publicly readable so that the device can access it. Note that whether you make the file publicly readable or not depends on your security model. Cloud Storage offers several access control options you can use to control access to your Cloud Storage buckets and objects.
  3. Send the file's location (as a Cloud Storage bucket and object URL) to the device's configuration topic via the modifyCloudToDeviceConfig method
  4. On the device, retrieve the file from the URL sent to the configuration topic and download it
  5. Request the device's most recent configuration to make sure that the file was correctly uploaded to Cloud Storage and sent to the device

The device in this sample primarily uses MQTT, but also requires HTTP to download the file from Cloud Storage.

Download the example

Download the example files and set your current directory:

git clone https://github.com/GoogleCloudPlatform/python-docs-samples
cd python-docs-samples/iot/api-client/gcs_file_to_device

Create your credentials

Before running the example, complete the following steps:

  1. Create a service account named gcs2iot-example.
    1. Select the role Project Editor.
    2. Select Furnish a new private key.
    3. Under Key type, select JSON.
    4. Save this key to the same directory as the two example Python files, and rename it service_account.json.
  2. Download Google's CA root certificate into the same directory as the example files. You can optionally set the location of the certificate with the --ca_certs flag.

Create the devices

  1. From within the iot/api-client/gcs_file_to_device directory, install the dependencies needed to run the example:

    pip install -r requirements.txt
    

    For more information on setting up your Python development environment, such as installing pip on your system, see the Python Development Environment Setup Guide.

  2. Create one or more devices in your project. You can use multiple registries, but all of the devices must be in the same project.

  3. For each device, open a terminal window and run the following code. This simulates the code that would be running on a device, publishing its telemetry data and updating its configuration based on the logic of the server.

python gcs_example_mqtt_device.py \
    --project_id=PROJECT_ID \
    --registry_id=REGISTRY_ID \
    --device_id=DEVICE_ID \
    --private_key_file=rsa_private.pem \
    --algorithm=RS256

You should now see the device publishing messages. In the next section, the devices will download a file from Cloud Storage.

Start the server

  1. Create a new file, called gcs_source_file.txt in the iot/api-client/gcs_file_to_device directory and save it. This file is used for demonstrative purposes and is the file you will send to Cloud Storage and download on a device. In a practical scenario, this file might be a ~1 MB or larger configuration file that a device would download and then use to self-update its firmware.

    echo "This file will go from Cloud Storage to a device." > gcs_source_file.txt
    

  2. While the device code is running and the device is publishing messages, run the server to send a file to Cloud Storage and forward the file's URL to the device's configuration topic.

python gcs_send_to_device.py \
    --project_id=PROJECT_ID \
    --bucket_name=BUCKET_NAME \
    --source_file_name=gcs_source_file.txt \
    --gcs_file_name=GCS_FILE_NAME \
    --destination_file_name=DESTINATION_FILE_NAME \
    --registry_id=REGISTRY_ID \
    --device_id=DEVICE_ID \
    --service_account_json=service_account.json

You should now see the server uploading a file to a Cloud Storage bucket and sending the location of the file as a URL to the device's configuration topic. You should also see the device downloading the file from the URL.

Try running many instances of gcs_example_mqtt_device.py at the same time, using different devices. If you rerun the code with the same device, the first device will be disconnected.

Was this page helpful? Let us know how we did:

Send feedback about...

Google Cloud Internet of Things Core