Google is discontinuing support for Google Cloud IoT Core on August 16, 2023. On this date, existing PyPortal IoT Planters will not work. If you are attempting this project for the first time or need to migrate your project to another IoT Platform, we suggest following a guide for the AWS IoT Planter (, Azure IoT Planter (, or the Adafruit IO IoT Planter (

Connecting to Google Cloud IoT Core

When the PyPortal starts up, it will first load the gcp_splash.bmp image in the images folder on your CIRCUITPY drive. This is a "loading screen" while the code waits for the fonts and display objects load on the screen.

Opening the REPL will help you view what's happening in the code. First, the code attempts to load the PyPortal's graphical interface

Loading GCP Graphics...
Displaying splash screen
Set icon to  /images/gcp_splash.bmp
Setting up labels...
Graphics loaded!

Next, the code will create a JWT. This will take a while as the code needs to grab the network time, generate a JWT, and sign the JWT with your private key. 

Generating JWT...

Once the JWT is created, the code will attempt to connect to Google Cloud IoT.

Connecting to WiFi...
Attempting to connect to

When the PyPortal connects with Google Cloud, it'll print out that it's connected and attempt to subscribe to the device's default command topic (more on this later!)

Connected to Google Cloud IoT!
Flags: 0
RC: 0
Subscribed to /devices/pyportal/commands/# with QOS level 1

Viewing Sensor data on PyPortal

You should see the PyPortal display update to display the temperature value and moisture level.

The status indicator at the bottom of the PyPortal will display when it's sending data to Google IoT. The PyPortal only sends data to Google Cloud IoT every SENSOR_DELAY minutes. Adjust this value in the code to increase or decrease the delay.

Viewing Data from Google Cloud Platform

You can view the data published to the feeds by your CircuitPython device. Navigate to the Pub/Sub page for your project at

In the topic list, click the topic used by your IoT Core Registry.  

Next to Topic details, click Pull Messages

Select the Cloud Pub/Sub subscription you created earlier and click PULL.

You should see the message, along with the device identifier and the time which the PyPortal published the message.  

You can also view the MQTT commands sent from your PyPortal to Google Cloud. From the device page, click View logs next to Stackdriver Logging.

While the code is running on the PyPortal, the Logger displays incoming MQTT commands.

If your code is idle (you aren't publishing data or subscribing to topics), you should see the device pinging the MQTT broker every 59 seconds (MiniMQTT sets this by default). The device does this to remain connected to the broker (effectively telling it, "hey, I'm still here!").

Sending Commands from Google IoT Core to your PyPortal

If your plant is parched, you can water it from across the world! Google Cloud IoT Core supports cloud-to-device communication. The provided code automatically subscribes to the default command topic (commands/#). Any incoming command will be handled by the code's message() method.

Let's water your plant!

With your PyPortal connected to Cloud IoT Core, navigate to the Device details page. Click the SEND COMMAND button on the IoT Core page header.

The Send Command API allows you to send command data as either plaintext or base64-encoded text. 

A typical rule-of-thumb in building internet-of-things projects is to send data as a single command, even if you're sending multiple commands.

To do this, you'll use the JSON file format to construct a command containing information about the pump. The resulting JSON command will look something like the following:

{"power":  true, "pump_time": 3}

with power representing the pump's state and pump_time representing the duration the pump is on for (in seconds).

Now that you have a command, enter the command into the Command data text field and click SEND COMMAND to send your command to the PyPortal.

You should see the message appear in the CircuitPython REPL:

Turning pump on for 3 seconds...
Plant watered!
Turning pump off

The pump should also turn on and water the plant for the duration you specified.

The pump we're using is a peristaltic type pump - the pump squishes the silicone tubing that contains the liquid instead of impelling it directly. This pump will take a while to move water into the tube, compress it, and push it out the other tube for your plant.

When sending a water pump message to your PyPortal - consider how long this process will take. You could send a message with a large time to determine this value. This'll value depends on a few factors including the length of your tubing and the power of your pump's motor.

That's it - you have a working IoT Planter powered by Google Cloud IoT Core and CircuitPython! The next section will discuss how this code works.

This guide was first published on Aug 28, 2019. It was last updated on Apr 15, 2024.

This page (Code Usage) was last updated on Apr 09, 2024.

Text editor powered by tinymce.