PyPortal and MQTT help needed - network problem?

CircuitPython on hardware including Adafruit's boards, and CircuitPython libraries using Blinka on host computers.

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
User avatar
prcutler
 
Posts: 5
Joined: Tue Jun 29, 2021 5:13 pm

PyPortal and MQTT help needed - network problem?

Post by prcutler »

I have two CircuitPython programs for my PyPortal, that I've adapted from Learn guides. Both programs both work individually, but not when I combine them. The first connects and subscribes to a MQTT broker and a topic. The second uses the PyPortal() class to fetch an image, have it converted by Adafruit IO, and display on the PyPortal.

I think the error is related to the PyPortal's networking and socket - MQTT has the socket in use, and blocks pyportal.fetch() from using the network. Or at least that's my best guess.

The code is below, and on line 90 I have

Code: Select all

MQTT.set_socket(socket, pyportal.network._wifi.esp)
and then pyportal.fetch is called when a message is received resulting in the following error. If anyone has any suggestions, please let me know and thanks in advance.

--Paul

Code: Select all

Auto-reload is on. Simply save files over USB to run them or enter REPL to disable.
code.py output:
Connecting to WiFi...
Connecting to AP Dispatch
Connected!
Subscribing to albumart
New message on topic albumart: Ping!
Retrieving data...Traceback (most recent call last):
  File "code.py", line 117, in <module>
  File "adafruit_minimqtt/adafruit_minimqtt.py", line 805, in loop
  File "adafruit_minimqtt/adafruit_minimqtt.py", line 860, in _wait_for_msg
  File "adafruit_minimqtt/adafruit_minimqtt.py", line 411, in _handle_on_message
  File "code.py", line 58, in message
  File "adafruit_pyportal/__init__.py", line 307, in fetch
  File "adafruit_portalbase/network.py", line 478, in fetch
  File "adafruit_requests.py", line 864, in get
  File "adafruit_requests.py", line 710, in request
  File "adafruit_requests.py", line 563, in _get_socket
RuntimeError: Sending request failed

And here's the code:

Code: Select all

# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries
# SPDX-License-Identifier: MIT

import time
import board
import adafruit_esp32spi.adafruit_esp32spi_socket as socket
import adafruit_pyportal

import adafruit_minimqtt.adafruit_minimqtt as MQTT

from adafruit_pyportal import PyPortal

### WiFi ###

# Get wifi details and more from a secrets.py file
try:
    from secrets import secrets
except ImportError:
    print("WiFi secrets are kept in secrets.py, please add them there!")
    raise
        

# ------------- MQTT Topic Setup ------------- #
mqtt_topic = "albumart"

### 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("Subscribing to %s" % (mqtt_topic))
    client.subscribe(mqtt_topic)


def disconnected(client, userdata, rc):
    # This method is called when the client is disconnected
    print("Disconnected from MQTT Broker!")


def message(client, topic, message):
    """Method callled when a client's subscribed feed has a new
    value.
    :param str topic: The topic of the feed with a new value.
    :param str message: The new value
    """
    if message == "Ping!":
        print("New message on topic {0}: {1}".format(topic, message))

        #try:
        
        response = pyportal.fetch()
        print("Response is", response)
        #except RuntimeError as e:
        #    print("Some error occurred, retrying! -", e)



# Setup the PyPortal
# Set up where we'll be fetching data from
DATA_SOURCE = "https://silversaucer.com/album/data"

response = None
# There's a few different places we look for data in the photo of the day
image_location = ["image_url"]
artist = ["artist"]
album = ["album"]

# the current working directory (where this file is)
cwd = ("/"+__file__).rsplit('/', 1)[0]
pyportal = PyPortal(url=DATA_SOURCE,
                    json_path=(artist, album),
                    status_neopixel=board.NEOPIXEL,
                    default_bg=cwd+"/nasa_background.bmp",
                    text_font=cwd+"/fonts/Arial-12.bdf",
                    text_position=((85, 260), (85, 280)),
                    text_color=(0xFFFFFF, 0xFFFFFF),
                    text_maxlen=(50, 50), # cut off characters
                    image_json_path=image_location,
                    image_resize=(320, 320),
                    image_position=(80, 0))

# Connect to WiFi
print("Connecting to WiFi...")
pyportal.network.connect()
print("Connected!")

# Initialize MQTT interface with the esp interface
# pylint: disable=protected-access
MQTT.set_socket(socket, pyportal.network._wifi.esp)

# Set up a MiniMQTT Client
mqtt_client = MQTT.MQTT(
    broker=secrets["broker"],
    username=secrets["user"],
    password=secrets["pass"],
    is_ssl=False,
)

# Setup the callback methods above
mqtt_client.on_connect = connected
mqtt_client.on_disconnect = disconnected
mqtt_client.on_message = message

# Connect the client to the MQTT broker.
mqtt_client.connect()


while True:
# Poll the message queue
    mqtt_client.loop()
    time.sleep(1)

Locked
Please be positive and constructive with your questions and comments.

Return to “Adafruit CircuitPython”