0

pyportal and mqtt
Moderators: adafruit_support_bill, adafruit

Forum rules
If you're posting code, please make sure your code does not include your Adafruit IO Active Key or WiFi network credentials.
Please be positive and constructive with your questions and comments.

Re: pyportal and mqtt

by brubell on Mon Apr 19, 2021 10:11 am

ssl and socketpool are part of the "native wifi" modules for hardware like the ESP32-S2. The PyPortal has externally connected WiFi and uses the ESP32SPI library (which includes similar files) instead.

brubell
 
Posts: 1377
Joined: Fri Jul 17, 2015 10:33 pm

Re: pyportal and mqtt

by oldblackcrow on Mon Apr 19, 2021 4:19 pm

Thank you! So, any hypothesis yet?

oldblackcrow
 
Posts: 221
Joined: Tue Jun 20, 2017 5:54 pm

Re: pyportal and mqtt

by oldblackcrow on Sat Apr 24, 2021 10:13 am

GeneticCowboy on Discord gave me the following lines to add to log the errors in the code.

Code: Select all | TOGGLE FULL SIZE
logger = logging.getLogger('test')  # debugging mqtt
mqtt_client.logger = logger  # debugging mqtt


Here is the full code with those lines added:

Code: Select all | TOGGLE FULL SIZE
# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries
# SPDX-License-Identifier: MIT
 
import time
import adafruit_esp32spi.adafruit_esp32spi_socket as socket
import adafruit_pyportal
import adafruit_logging as logging
 
import adafruit_minimqtt.adafruit_minimqtt as MQTT
 
pyportal = adafruit_pyportal.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 = secrets["aio_username"] + "/feeds/photocell"
 
### 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
    """
    print("New message on topic {0}: {1}".format(topic, message))
 
 
# 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["aio_username"],
    password=secrets["aio_key"],
    is_ssl=False,
)

logger = logging.getLogger('test')  # debugging mqtt
mqtt_client.logger = logger  # debugging mqtt

# 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()
 
photocell_val = 0
while True:
    # Poll the message queue
    mqtt_client.loop()
 
    # Send a new message
    print("Sending photocell value: %d" % photocell_val)
    mqtt_client.publish(mqtt_topic, photocell_val)
    photocell_val += 1
    time.sleep(1)



Here is the result:

code.py output:
No SD card found: no SD card
Connecting to WiFi...
Connecting to AP Ross Family
Connected!
199.524: DEBUG - Attempting to establish MQTT connection...
199.527: INFO - Establishing an INSECURE connection to https://io.adafruit.com:1883
Traceback (most recent call last):
File "code.py", line 75, in <module>
File "adafruit_minimqtt/adafruit_minimqtt.py", line 437, in connect
File "adafruit_minimqtt/adafruit_minimqtt.py", line 240, in _get_connect_socket
File "adafruit_esp32spi/adafruit_esp32spi_socket.py", line 42, in getaddrinfo
File "adafruit_esp32spi/adafruit_esp32spi.py", line 610, in get_host_by_name
RuntimeError: Failed to request hostname

Code done running.

This information is beyond my comprehension, so can you parse this out for me?

Thank you!

oldblackcrow
 
Posts: 221
Joined: Tue Jun 20, 2017 5:54 pm

Re: pyportal and mqtt

by oldblackcrow on Sat Apr 24, 2021 12:17 pm

If I change the # Set up a MiniMQTT Client to the following, as in this example viewtopic.php?f=56&t=163005&p=802073&hilit=pyportal+mqtt#p802073

Code: Select all | TOGGLE FULL SIZE
mqtt_client = MQTT.MQTT(
    broker = secrets['broker'],
    port = 8883,
    username = secrets['aio_username'],
    password = secrets['aio_key'],
)


Then I get the following error message:

code.py output:
No SD card found: no SD card
Connecting to WiFi...
Connecting to AP Ross Family
Connected!
2164.88: DEBUG - Attempting to establish MQTT connection...
2164.88: INFO - Establishing a SECURE SSL connection to https://io.adafruit.com:8883
Traceback (most recent call last):
File "code.py", line 75, in <module>
File "adafruit_minimqtt/adafruit_minimqtt.py", line 437, in connect
File "adafruit_minimqtt/adafruit_minimqtt.py", line 240, in _get_connect_socket
File "adafruit_esp32spi/adafruit_esp32spi_socket.py", line 42, in getaddrinfo
File "adafruit_esp32spi/adafruit_esp32spi.py", line 610, in get_host_by_name
RuntimeError: Failed to request hostname

Code done running.

oldblackcrow
 
Posts: 221
Joined: Tue Jun 20, 2017 5:54 pm

Re: pyportal and mqtt

by oldblackcrow on Mon Apr 26, 2021 7:41 am

Seems we are stuck on this as well? Maybe @MakerMelissa can help? She's amazing and helped with a similar issue. Ironic that an IOT device can't do IOT.

oldblackcrow
 
Posts: 221
Joined: Tue Jun 20, 2017 5:54 pm

Re: pyportal and mqtt

by brubell on Mon May 03, 2021 10:30 am

Could you try this - it doesn't rely on the PyPortal class at all...

Code: Select all | TOGGLE FULL SIZE
# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries
# SPDX-License-Identifier: MIT

import time
import board
import busio
from digitalio import DigitalInOut
import neopixel
from adafruit_esp32spi import adafruit_esp32spi
from adafruit_esp32spi import adafruit_esp32spi_wifimanager
import adafruit_esp32spi.adafruit_esp32spi_socket as socket

import adafruit_minimqtt.adafruit_minimqtt as MQTT

### 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

# If you are using a board with pre-defined ESP32 Pins:
esp32_cs = DigitalInOut(board.ESP_CS)
esp32_ready = DigitalInOut(board.ESP_BUSY)
esp32_reset = DigitalInOut(board.ESP_RESET)

# If you have an externally connected ESP32:
# esp32_cs = DigitalInOut(board.D9)
# esp32_ready = DigitalInOut(board.D10)
# esp32_reset = DigitalInOut(board.D5)

spi = busio.SPI(board.SCK, board.MOSI, board.MISO)
esp = adafruit_esp32spi.ESP_SPIcontrol(spi, esp32_cs, esp32_ready, esp32_reset)
"""Use below for Most Boards"""
status_light = neopixel.NeoPixel(
    board.NEOPIXEL, 1, brightness=0.2
)  # Uncomment for Most Boards
"""Uncomment below for ItsyBitsy M4"""
# status_light = dotstar.DotStar(board.APA102_SCK, board.APA102_MOSI, 1, brightness=0.2)
# Uncomment below for an externally defined RGB LED
# import adafruit_rgbled
# from adafruit_esp32spi import PWMOut
# RED_LED = PWMOut.PWMOut(esp, 26)
# GREEN_LED = PWMOut.PWMOut(esp, 27)
# BLUE_LED = PWMOut.PWMOut(esp, 25)
# status_light = adafruit_rgbled.RGBLED(RED_LED, BLUE_LED, GREEN_LED)
wifi = adafruit_esp32spi_wifimanager.ESPSPI_WiFiManager(esp, secrets, status_light)

### Feeds ###

# Setup a feed named 'photocell' for publishing to a feed
photocell_feed = secrets["aio_username"] + "/feeds/photocell"

# Setup a feed named 'onoff' for subscribing to changes
onoff_feed = secrets["aio_username"] + "/feeds/onoff"

### 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! Listening for topic changes on %s" % onoff_feed)
    # Subscribe to all changes on the onoff_feed.
    client.subscribe(onoff_feed)


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


def message(client, topic, message):
    # This method is called when a topic the client is subscribed to
    # has a new message.
    print("New message on topic {0}: {1}".format(topic, message))


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

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

# Set up a MiniMQTT Client
mqtt_client = MQTT.MQTT(
    broker="io.adafruit.com",
    username=secrets["aio_username"],
    password=secrets["aio_key"],
)

# 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.
print("Connecting to Adafruit IO...")
mqtt_client.connect()

photocell_val = 0
while True:
    # Poll the message queue
    mqtt_client.loop()

    # Send a new message
    print("Sending photocell value: %d..." % photocell_val)
    mqtt_client.publish(photocell_feed, photocell_val)
    print("Sent!")
    photocell_val += 1
    time.sleep(5)

brubell
 
Posts: 1377
Joined: Fri Jul 17, 2015 10:33 pm

Re: pyportal and mqtt

by oldblackcrow on Mon May 03, 2021 11:04 am

YES that worked! That is sending information TO AIO... Now I need to make it READ from AIO. But, hey this is a quantum leap! THANK YOU!

Question: If I put this into the UI code (https://learn.adafruit.com/making-a-pyp ... -displayio), do you think it would work or would calling the PyPortal at the beginning of the UI code negate the code you just posted?

Thanks again!!

oldblackcrow
 
Posts: 221
Joined: Tue Jun 20, 2017 5:54 pm

Re: pyportal and mqtt

by oldblackcrow on Mon May 03, 2021 2:37 pm

Never mind... got everything working!

Thank you for all your help and sorry for any negative comments. You and your team rock!

oldblackcrow
 
Posts: 221
Joined: Tue Jun 20, 2017 5:54 pm

Re: pyportal and mqtt

by oldblackcrow on Mon May 03, 2021 6:09 pm

I posted the issue with the UI example (viewtopic.php?f=60&t=175420&p=870550#p870550) but just so it's documented, I'll note it on this as well.

The code you posted does work beautifully, however, the whole point of this was to integrate the code with the example UI code (https://learn.adafruit.com/making-a-pyp ... -full-code)... I did not mention that in this thread... and since that does call on the PyPortal, I don't think there's a work-a-round... unless you know?

oldblackcrow
 
Posts: 221
Joined: Tue Jun 20, 2017 5:54 pm

Re: pyportal and mqtt

by brubell on Wed May 05, 2021 10:58 am

Now I need to make it READ from AIO. But, hey this is a quantum leap! THANK YOU!


You'd want to use the get() function which can obtain the last published value on a feed:
https://circuitpython.readthedocs.io/pr ... O_MQTT.get

For more info about why this function is used:
https://io.adafruit.com/api/docs/mqtt.h ... ned-values

The code you posted does work beautifully, however, the whole point of this was to integrate the code with the example UI code (https://learn.adafruit.com/making-a-pyp ... -full-code)... I did not mention that in this thread... and since that does call on the PyPortal, I don't think there's a work-a-round... unless you know?

I'm going to ask Melissa about this.

brubell
 
Posts: 1377
Joined: Fri Jul 17, 2015 10:33 pm

Re: pyportal and mqtt

by oldblackcrow on Thu May 06, 2021 10:46 am

No worries... @Neradoc#2644 on discord has solved this issue.

The code he gave has been modified to the following:

Code: Select all | TOGGLE FULL SIZE
import time
import random
from adafruit_pyportal import PyPortal

pyportal = PyPortal()
pyportal.network.connect()

key = "rx"
latest_id = "rx"

while True:
    feed = pyportal.get_io_feed(key)
    client = pyportal.network._get_io_client()
    last = client.receive_data(key)
    the_id = last['id']
    if the_id != latest_id:
        print("New value:",last['value'])
        latest_id = the_id
    time.sleep(5)


His original code was posted here: https://gist.github.com/Neradoc/0093bac ... 18e4950f1d

Thanks to all of you for all your help on this!

oldblackcrow
 
Posts: 221
Joined: Tue Jun 20, 2017 5:54 pm

Re: pyportal and mqtt

by brubell on Thu May 06, 2021 4:28 pm

No problem, glad it's sorted :)

brubell
 
Posts: 1377
Joined: Fri Jul 17, 2015 10:33 pm

Please be positive and constructive with your questions and comments.