End-to-end example

If you haven't already, review the MQTT client samples, read the device management samples, and complete the Quickstart before continuing.

In this example, you'll build a simple but complete virtual IoT system. The virtual devices in this system publish temperature data on their telemetry feeds, and a server consumes the telemetry data from a Cloud Pub/Sub topic. The server then decides whether to turn on or off the individual devices' fans, via a Cloud IoT Core configuration update.


In this example, a device's temperature increases by 1 degree every second if the fan is off, and decreases by 1 degree every second if the fan is on. Devices publish their temperature data as a JSON serialized string in the form:

{ 'temperature': 12 }

— where 12 is the temperature reported by the device. In the example, this is a synthetic value, but in a real application the value could be read from a temperature sensor.

The server code consumes these messages from the registry's Cloud Pub/Sub topic. If a device reports a temperature of greater than 10, the server tells the device to turn on its fan, and if a device's temperature is below 0, the server tells the device to turn off its fan. Configuration is sent from the server to the device as a JSON serialized string in the form:

{ 'fan_on' : true/false }

The following diagram gives a simplified illustration how data flows through the example system. Note that all of the events in the diagram occur asynchronously.

Cloud IoT end-to-end example diagram

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

Create a service account

The server in this example must authenticate itself to Cloud IoT Core. It can do so through a service account configured with the appropriate credentials.

To create a service account:

  1. Use Cloud Console to create a service account:
    1. Click Select, then select a project to use for the service account.
    2. Click Create service account.
    3. Name the account e2e-example and click Create.
    4. Select the role Project > Editor and click Continue.
    5. Click Create key.
    6. Under Key type, select JSON and click Create.
    7. Save this key to the same directory as the 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.

Install dependencies

From within the iot/api-client/end_to_end_example directory, install the dependencies needed to run the server:

sudo 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.

Start the server

To start the server for this example, use the command below, substituting your project ID and a Cloud Pub/Sub subscription (you can use the same subscription you created in the Quickstart).

python cloudiot_pubsub_example_server.py \
    --project_id=PROJECT_ID \
    --pubsub_subscription=PUBSUB_SUBSCRIPTION \

The server simulates the code that would be running in the cloud and consuming data from multiple devices.

Create the devices

Now create one or more virtual devices in your project. You can use multiple registries, but all of the devices must be in the same project. For information on creating devices, refer to the device management samples.

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 cloudiot_pubsub_example_mqtt_device.py \
    --project_id=PROJECT_ID \
    --registry_id=REGISTRY_ID \
    --device_id=DEVICE_ID \
    --private_key_file=rsa_private.pem \

You should now see the devices publishing their temperature data, and the server instructing the devices to turn on and off their fans. Try running many instances of cloudiot_pubsub_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.


  • If you run the device code and it fails to respond or responds with a network error, your firewall may be blocking Python from connecting via port 8883 (the default port). To resolve this issue, run the code again, but pass the --mqtt_bridge_port flag and set its value to 443.

  • If you run the device code and it responds with a connection error, pass the --cloud_region flag and set its value to a new region. In the current release of Cloud IoT Core, the available regions are us-central1, europe-west1, and asia-east1. The device code defaults to --cloud_region=us-central1.

  • If you run the server code and encounter a 429 status code with the message "'Config update denied for device with id 'device-id'. A device's config can only be updated at most once every 1s'", there may be a backlog of messages from the device in the Pub/Sub queue. To resolve this issue, clear the queue by pulling all of the device's messages (for example, by running gcloud pubsub subscriptions pull --auto-ack projects/PROJECT_ID/subscriptions/PUBSUB_SUBSCRIPTION --limit=MESSAGES), and then run the server code again.

  • If you're unable to install the libraries in requirements.txt, you may be missing cffi dependencies. To install them, run:

    sudo apt-get install build-essential libssl-dev libffi-dev python-dev