Set up the PyPortal's D3 pin as a DigitalInOut object and set the direction to output.
# Set up a pin for controlling the relay power_pin = DigitalInOut(board.D3) power_pin.switch_to_output()
Now, set up the relay feed as a string variable named feed_relay
### Feeds ### # Set up a feed named Relay for subscribing to the relay feed on Adafruit IO feed_relay = os.getenv("AIO_USERNAME") + "/feeds/relay"
The following code snippet consists of MQTT callback methods. For an explanation of how these methods function, please see this section of the MQTT in CircuitPython guide.
### Code ### # Define callback methods which are called when events occur # pylint: disable=unused-argument, redefined-outer-name def connected(client, userdata, flags, rc): # This function will be called when the client is connected # successfully to the broker. print("Connected to Adafruit IO!") def disconnected(client, userdata, rc): # This method is called when the client is disconnected print("Disconnected from Adafruit IO!") def subscribe(client, userdata, topic, granted_qos): # This method is called when the client subscribes to a new feed. print("Subscribed to {0}".format(topic)) def unsubscribe(client, userdata, topic, pid): # This method is called when the client unsubscribes from a feed. print("Unsubscribed from {0} with PID {1}".format(topic, pid)) def on_message(client, topic, message): # Method callled when a client's subscribed feed has a new value. print("New message on topic {0}: {1}".format(topic, message))
When the Adafruit IO feed Your-AIO-Username/feeds/relay receives new data, the following method executes and evaluates the value on the feed.
If the value is "ON", the relay is turned on by setting the pin high. If the value is "OFF", the relay is turned off by setting the pin low.
def on_relay_msg(client, topic, value): # Called when relay feed obtains a new value print("Turning Relay %s"%value) if value == "ON": power_pin.value = True elif value == "OFF": power_pin.value = False else: print("Unexpected value received on relay feed.")
Next, connect to the WiFi network and set up a MQTT client to connect to Adafruit IO's MQTT broker with your credentials.
pool = adafruit_connection_manager.get_radio_socketpool(esp) ssl_context = adafruit_connection_manager.get_radio_ssl_context(esp) # Set up a MiniMQTT Client client = MQTT.MQTT( broker="io.adafruit.com", username=os.getenv("AIO_USERNAME"), password=os.getenv("AIO_KEY"), socket_pool=pool, ssl_context=ssl_context, )
Now, set up the callback methods above by connecting them to the client's default callback properties.
# Setup the callback methods above client.on_connect = connected client.on_disconnect = disconnected client.on_subscribe = subscribe client.on_unsubscribe = unsubscribe client.on_message = on_message
The on_relay_message
method is not a default MiniMQTT client callback, so it's added as a custom callback, which will execute on_relay_msg()
when new data is received.
# Add a callback to the relay feed client.add_topic_callback(feed_relay, on_relay_msg)
Connect to the Adafruit IO MQTT broker and subscribe to the relay feed.
# Connect the client to Adafruit IO print("Connecting to Adafruit IO...") client.connect() # Subscribe to all updates on relay feed client.subscribe(feed_relay)
The code within the while True
loop will check for new messages on the relay feed every 50 milliseconds. If there's an issue with the network connection, the WiFi connection will reset and the MQTT client will reconnect to Adafruit IO.
while True: try: # Poll for new messages on feed_relay client.loop() except (ValueError, RuntimeError) as e: print("Failed to get data, retrying\n", e) wifi.reset() client.reconnect() continue time.sleep(0.05)
Page last edited March 12, 2025
Text editor powered by tinymce.