The code sets 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()

The following code block consists of MQTT callback methods. For an explanation of how these methods work, 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))

Whenever the relay feed receives new data, the on_relay_msg function executes. If the value on the feed is evaluated to be "morning", the light is turned on. Alternatively, if the value on the feed is evaluated to be "night", the light is turned off. 

def on_relay_msg(client, topic, message):
    # Method called whenever user/feeds/relay has a new value
    if message == "morning":
        print("Morning - turning outlet ON")
        power_pin.value = True
    elif message == "night":
        print("Night - turning outlet OFF")
        power_pin.value = False
    else:
        print("Unexpected value received on relay feed.")

Next, the code connects to the WiFi network and set up a MQTT client to connect to Adafruit IO's MQTT broker with your credentials. An Adafruit IO MQTT client instance is initialized using the MiniMQTT client instance.

# Initialize MQTT interface with the esp interface
MQTT.set_socket(socket, esp)

# Initialize a new MQTT Client object
mqtt_client = MQTT.MQTT(
    broker="io.adafruit.com",
    username=secrets["aio_username"],
    password=secrets["aio_key"],
)

# Initialize an Adafruit IO MQTT Client
io = IO_MQTT(mqtt_client)

Sets up the callback methods above by connecting them to the client's default callback properties. 

# Connect the callback methods defined above to Adafruit IO
io.on_connect = connected
io.on_disconnect = disconnected
io.on_subscribe = subscribe
io.on_unsubscribe = unsubscribe
io.on_message = on_message

Connect to the Adafruit IO MQTT broker and subscribe to the relay feed.

# Connect to Adafruit IO
print("Connecting to Adafruit IO...")
io.connect()

The on_relay_msg method is not a default Adafruit IO callback method, so it's added as a custom callback. This method will execute on_relay_msg whenever a new value is obtained by the relay feed.

# Add a callback to the relay feed
client.add_topic_callback(feed_relay, on_relay_msg)

Subscribes to all messages on the relay feed and obtains the most recent value of the relay feed.

# Subscribe to all messages on the relay feed
io.subscribe("relay")

# Get the most recent value on the relay feed
io.get("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.

# Start a blocking loop to check for new messages
while True:
    try:
        io.loop()
    except (ValueError, RuntimeError) as e:
        print("Failed to get data, retrying\n", e)
        wifi.reset()
        io.reconnect()
        continue
    time.sleep(0.5)

This guide was first published on Sep 29, 2020. It was last updated on Sep 29, 2020.

This page (CircuitPython Code Walkthrough) was last updated on Apr 18, 2021.

Text editor powered by tinymce.