How to subscribe to multiple MQTT topics?

All ESP8266 boards running MicroPython.
Official boards are the Adafruit Huzzah and Feather boards.
Target audience: MicroPython users with an ESP8266 board.
Post Reply
marine_hm
Posts: 16
Joined: Mon Oct 18, 2021 10:45 am
Location: USA: Eastern NC
Contact:

How to subscribe to multiple MQTT topics?

Post by marine_hm » Thu Dec 09, 2021 2:37 am

I'm struggling. I'm going to keep at it until I get there!
Here's my code so far:

Code: Select all

# *****ASSIGN VARIABLES*****************#
# RELAY 1
rel1 = machine.Pin(05, machine.Pin.OUT) # ASSIGN OBJECT NAME TO GPIO PIN 05(D1), OBJECT IS AN OUTPUT.
rel1(0)  # TURN OFF RELAY AT STARTUP
topic = "Relay1"  # MQTT TOPIC SUCH AS: upstairs/hallway/light1.


# RELAY 2
rel2 = machine.Pin(04, machine.Pin.OUT) # ASSIGN OBJECT NAME TO GPIO PIN 04(D2), OBJECT IS AN OUTPUT.
rel2(0)  # TURN OFF RELAY AT STARTUP
topic = "Relay2"  # MQTT TOPIC SUCH AS: upstairs/hallway/light2.


message = ""
# True when new message is received in callback
new = False

# ******** CAN I SKIP THE TWO "TOPICS" ABOVE? ********


# DEFINE CALLBACK TO KEEP CHECKING FOR NEW MESSAGES
def MQTT_callback(topic, msg):
    global new
    global message
    print("received: ",topic,msg)
    message = msg
    new = True
    
    
# GIVE CLIENT A PROPER NAME, INTRODUCE CLIENT TO MQTT BROKER
SERVER = "192.168.1.13"
client = MQTTClient("ESP8266_Relay", SERVER) # EACH CLIENT MUST HAVE A UNIQUE "NAME/ID"
                                       # NAME CAN BE SOMETHING LIKE "ESP_SENSOR_2"

# CONNECT CLIENT TO MQTT BROKER
try:
    client.connect()
#    print(client.connect())  # This just results in printing a 0  DO I NEED IT?
    client.set_callback(MQTT_callback)
    client.subscribe("Relay1"), ("Relay2") # This subscribes to just "Relay2"
    
        # TRYING TO SUBSCRIBE TO MULTIPLE TOPICS#
#    client.subscribe(topic)  # ******** This works with single topic *******
#    client.subscribe("Relay1") + ("Relay2") # This does NOT work
#    client.subscribe("Relay1") & ("Relay2") # This does NOT work
#    client.subscribe[(("Relay1"), ("Relay2"))] # This does NOT work
#    client.subscribe[(("Relay1") + ("Relay2"))] # This does NOT work
    

    print("Connected to MQTT Server and subscribed to: ", topic)
    mqtt = True
except:
    print("MQTT connect failed")
    mqtt = False


###### NEED TO FIGURE OUT HOW TO CHECK FOR 2 TOPICS ###########
# LOOP IF WIFI AND MQTT CONNECTION WAS SUCCESSFUL 
while wlan.isconnected() and mqtt:
    try:
        client.check_msg()
        if new:
            print("New message: ",message)
            rel1(int(message))  # TELL OBJECT "relay1", (int EXPECT A NUMBER, (message: 0=OFF, 1=ON))
            new = False
    except:
        print("Client check failed ...")
    time.sleep(1)
print("Wifi disconnected or MQTT could not connect")

# ******** I'm thinking on the lines of: ********
#    if:
#        topic=="Relay1"
#        rel1(int(message))  # TELL OBJECT "relay1", (int EXPECT A NUMBER, (message: 0=OFF, 1=ON))

#    elif: 
#        topic=="Relay2"
#        rel2(int(message))  # TELL OBJECT "relay2", (int EXPECT A NUMBER, (message: 0=OFF, 1=ON))
Any help would be greatly appreciated!

User avatar
pythoncoder
Posts: 5956
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: How to subscribe to multiple MQTT topics?

Post by pythoncoder » Thu Dec 09, 2021 10:30 am

Assuming you're using one of the official MQTT libraries try:

Code: Select all

    client.subscribe(b"Relay1")
    client.subscribe(b"Relay2")
Another option is to have one topic and signal your intent with different messages.
Peter Hinch
Index to my micropython libraries.

marine_hm
Posts: 16
Joined: Mon Oct 18, 2021 10:45 am
Location: USA: Eastern NC
Contact:

Re: How to subscribe to multiple MQTT topics?

Post by marine_hm » Thu Dec 09, 2021 3:39 pm

When I do that, it says it's subscribed to Relay2.

Maybe I did it right with this and it's only saying subscribed to relay2 but actually subscribing to both?

client.subscribe("Relay1"), ("Relay2")

I was too focused on just the REPL and not the outcome when run, sending messages to the MQTT server.

I will give it a try and let you know in either case. Thank you!!!!
Running both scenarios.

Your code:
client.subscribe(b"Relay1")
client.subscribe(b"Relay2")
My Code:
client.subscribe("Relay1"), ("Relay2")

Results in the same outcome. Both topics activate rel1 (PinIO 05)

I want topic "Relay1" to affect PinIO05 (rel1), topic "Relay2" affect PinIO 04 (rel2)

IF topic "Relay1" then rel1: msg()
IF topic "Relay2" then rel2: msg()

Am I even close? Thanks for helping!

marine_hm
Posts: 16
Joined: Mon Oct 18, 2021 10:45 am
Location: USA: Eastern NC
Contact:

Re: How to subscribe to multiple MQTT topics?

Post by marine_hm » Fri Dec 10, 2021 2:42 pm

To show you how it was done using Arduino IDE:
Once subscribed to both topics, then activate each Relay separately.

Code: Select all

    // ******************* RELAY 1 *****************************
  if (strcmp(topic, "Relay1") == 0) {
    for (int i = 0; i < length; i++) {
      char receivedChar = (char)payload[i];
      if (receivedChar == '0') {
        Serial.println (F("Relay1 ON"));
        digitalWrite(relay1Pin, HIGH);
      }
      if (receivedChar == '1') {
        Serial.println (F("Relay1 OFF"));
        digitalWrite(relay1Pin, LOW);
      }
    }
  }
  // ******************* RELAY 2 *****************************
  if (strcmp(topic, "Relay2") == 0) {
    for (int i = 0; i < length; i++) {
      char receivedChar = (char)payload[i];
      if (receivedChar == '0') {
        Serial.println (F("Relay2 ON"));
        digitalWrite(relay2Pin, HIGH);
      }
      if (receivedChar == '1') {
        Serial.println (F("Relay2 OFF"));
        digitalWrite(relay2Pin, LOW);
      }
    }
  }
Any insight how to do that in Micropython would be greatly appreciated. Thanks

marine_hm
Posts: 16
Joined: Mon Oct 18, 2021 10:45 am
Location: USA: Eastern NC
Contact:

Re: How to subscribe to multiple MQTT topics?

Post by marine_hm » Fri Dec 10, 2021 2:49 pm

Hmmmm.
Another option is to have one topic and signal your intent with different messages.
You mean something like?:
Topic = Relay

Messages =
  • Relay1OFF
    Relay1ON
    Relay2ON
    Relay2OFF
I would then need 4 "IF msg==:" statements?

User avatar
pythoncoder
Posts: 5956
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: How to subscribe to multiple MQTT topics?

Post by pythoncoder » Fri Dec 10, 2021 5:22 pm

Yes.

It's possible that the official MQTT library doesn't work with multiple subscriptions. It has various bugs and limitations which is why I and Kevin Köck developed mqtt_as. This does support multiple subscriptions.
Peter Hinch
Index to my micropython libraries.

marine_hm
Posts: 16
Joined: Mon Oct 18, 2021 10:45 am
Location: USA: Eastern NC
Contact:

Re: How to subscribe to multiple MQTT topics?

Post by marine_hm » Tue Dec 28, 2021 2:02 pm

I and Kevin Köck developed mqtt_as. This does support multiple subscriptions.
Please excuse my ignorance. But, is mqtt_as a module? I am using Thonny. How do I get mqtt_as onto my microcontroller as part of Micropython? Does that just import on THAT microcontroller and I have to import it on every microcontroller I want to use the mqtt_as?

marine_hm
Posts: 16
Joined: Mon Oct 18, 2021 10:45 am
Location: USA: Eastern NC
Contact:

Re: How to subscribe to multiple MQTT topics?

Post by marine_hm » Tue Dec 28, 2021 2:10 pm

Yeah, I think that was a senior moment. I clicked on the link. Then I copied the mqtt_as.py, saved it both on my pc and the microcontroller. Now, How to incorporate that into my script....? Don't answer that just yet, I'm thinking out loud. If you don't hear from me for a week or two, then, I may need some help. Nothing worse than someone asking for help and not even trying. I'll be back!!!

Cheers! :D

Post Reply