Welcome to the Pycom forum Forum
    • \[\[global:header.categories\]\]
    • \[\[global:header.recent\]\]
    • \[\[global:header.tags\]\]
    • \[\[global:header.popular\]\]
    • Login

    Explore Pybytes | Official Documentation | Report a Firmware Bug/Issue | GitHub

    MQTT with 2 subscribes

    Scheduled Pinned Locked Moved MicroPython
    mqtt
    16 Posts 3 Posters 3.5k Views 3 Watching
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • L Offline
      luc hanneuse
      last edited by luc hanneuse

      Hi,
      I'm new to micropython. I've taken several examples on this forum, assemble them and succeed to subscribe to 2 differents mqtt topics. But how can I put the differnts message in 2 variables like sensor21 and sensor31 ?

      from mqtt import MQTTClient
      import machine
      import time
      import pycom
      
      def sub_cb(topic, msg):
         print(msg)
      
      wlan = WLAN(mode=WLAN.STA)
      wlan.connect("wifi", auth=(WLAN.WPA2, "pass"), timeout=5000)
      
      while not wlan.isconnected():
          machine.idle()
      print("Connected to Wifi\n")
      
      client = MQTTClient("device_id", "192.168.0.20",user="pi", password="raspberry", port=1883)
      
      client.set_callback(sub_cb)
      client.connect()
      
      wifiaddress = ((str(wlan.ifconfig()[:1]))[2:])[:-3]
      client.publish(topic="lopy/ip", msg=wifiaddress)
      
      client.subscribe(topic="pi/sensor21/temperature")
      client.subscribe(topic="pi/sensor31/temperature")
      
      def t3_publication(topic, msg):
          print (topic, ':', msg)
          #pycom.rgbled(0xff00)
      
      client.set_callback(t3_publication)
      
      while True:
          client.check_msg()
      

      Thanks

      L 1 Reply Last reply Reply Quote 0
      • L Offline
        luc hanneuse @luc hanneuse
        last edited by

        @luc-hanneuse
        anyone ?

        L C 2 Replies Last reply Reply Quote 0
        • L Offline
          livius @luc hanneuse
          last edited by

          @luc-hanneuse
          what is your output from
          print (topic, ':', msg)?

          think about people first, then computers

          L 1 Reply Last reply Reply Quote 0
          • L Offline
            luc hanneuse @livius
            last edited by

            @livius
            So it subscribes correctly to the 2 topics. But I can't succeed in putting each message in a different variable.

            Here is my output :
            b'pi/sensor21/temperature' : b'21.00'
            b'pi/sensor31/temperature' : b'25'

            L 1 Reply Last reply Reply Quote 0
            • L Offline
              luc hanneuse @luc hanneuse
              last edited by

              @luc-hanneuse

              I've tried this, but I got an error message.

              one="pi/sensor21/temperature"
              two="pi/sensor31/temperature"
              
              client.subscribe(topic=one)
              client.subscribe(topic=two)
              
              def mytopic(topic, msg):
                  print (topic, ':', msg)
              
                  if topic == one:
                      b = (msg[0]-48)*10+(msg[1]-48)
              
                  if topic == two:
                      c = (msg[0]-48)*10+(msg[1]-48)
                  s.send(bytes([b,c]))
                  #print("Sigfox sent\n")
              
              L 1 Reply Last reply Reply Quote 0
              • L Offline
                livius @luc hanneuse
                last edited by livius

                @luc-hanneuse
                what is the error message?
                and to convert from text to number simply do

                v2=float(v)
                

                or if you need only integer part

                v2=int(float(v))
                

                think about people first, then computers

                L 1 Reply Last reply Reply Quote 0
                • L Offline
                  luc hanneuse @livius
                  last edited by luc hanneuse

                  @livius
                  For the conversion, It doesn't work :

                  v2=float(v)
                  

                  I've got an error
                  can't convert bytes to float

                  v2=int(v)
                  

                  I've got an error
                  ValueError: invalid syntax for integer with base 10

                  For the previous code, the error is
                  NameError: local variable referenced before assignment

                  L 1 Reply Last reply Reply Quote 0
                  • C Offline
                    chumelnicu @luc hanneuse
                    last edited by

                    @luc-hanneuse Try to pack that two data (temperatures ) in to json format and publising after to MQTT broker

                    L 1 Reply Last reply Reply Quote 0
                    • L Offline
                      luc hanneuse @chumelnicu
                      last edited by

                      @chumelnicu

                      It comes from different devices publishing each one their temperatures.

                      1 Reply Last reply Reply Quote 0
                      • L Offline
                        livius @luc hanneuse
                        last edited by

                        @luc-hanneuse said in MQTT with 2 subscribes:

                        For the previous code, the error is
                        NameError: local variable referenced before assignment

                        You got this error because you do this

                        s.send(bytes([b,c]))
                        

                        but in the code you have if variants and one of two "b" or "c" is unassigned
                        because you got 2 events - look how your code work by changing it to:

                        def mytopic(topic, msg):
                            print("---start---")
                            print (topic, ':', msg)
                        

                        is your output now like this?

                        "---start---"
                        b'pi/sensor21/temperature' : b'21.00'
                        "---start---"
                        b'pi/sensor31/temperature' : b'25'
                        

                        you must put b and c outside of procedure
                        and inside test if both "b" and "c" have values and only then send it
                        but this can also cause minssing values if you got only "b" and once again "b" and next "c"
                        PS> about simple conversion i am writing about string, if it is a bytes then
                        you must catch it e.g. v2=float(str(v))
                        but your way should work also byte-48{0ascii} *10...

                        think about people first, then computers

                        L 1 Reply Last reply Reply Quote 1
                        • L Offline
                          luc hanneuse @livius
                          last edited by

                          @livius said in MQTT with 2 subscribes:

                          you must put b and c outside of procedure

                          How can I get those variable out of "def"?

                          L 1 Reply Last reply Reply Quote 0
                          • L Offline
                            livius @luc hanneuse
                            last edited by

                            @luc-hanneuse said in MQTT with 2 subscribes:

                            How can I get those variable out of "def"?

                            msg_b= None
                            msg_c= None
                            
                            def mytopic(topic, msg):
                              global msg_b
                              global msg_c
                              ...
                            

                            think about people first, then computers

                            1 Reply Last reply Reply Quote 0
                            • L Offline
                              luc hanneuse
                              last edited by

                              Finally some improvements, thanks for your help.
                              I succeed to subscribe to several topics and get some results.

                              topic_sub=["pi/sensor21/temperature","pi/sensor40/temperature","pi/sensor02/temperature","pi/sensor12/in_01","pi/sensor12/out_01"]
                              topic_length=len(topic_sub)
                              val= [0,0,0,0,0] #should be a better way to create this array from topic_length
                              update = None # used if you want to send a signal without waiting the 800s cycle
                              
                              for i in range(0, topic_length):
                                  client.subscribe(topic=topic_sub[i])
                              
                              def mytopic(topic, msg):
                                  global update
                                  global topic_length
                                  global topic_sub
                                  global val
                              
                                  if ubinascii.hexlify(topic) == ubinascii.hexlify(topic_sub[0]):
                                      val[0] = (msg[0]-48)*10+(msg[1]-48) #ascii-to-int, to be improved
                                      val[0] = val[0] % 255 #sure to be a byte
                              
                                  if ubinascii.hexlify(topic) == ubinascii.hexlify(topic_sub[1]):
                                      val[1] = (msg[0]-48)*10+(msg[1]-48) #ascii-to-int, to be improved
                                      val[1] = val[1] % 255 #sure to be a byte
                              
                                  if ubinascii.hexlify(topic) == ubinascii.hexlify(topic_sub[2]):
                                      val[2] = (msg[0]-48)*10+(msg[1]-48) #ascii-to-int, to be improved
                                      val[2] = val[2] % 255 #sure to be a byte
                              
                                  if ubinascii.hexlify(topic) == ubinascii.hexlify(topic_sub[3]):
                                      val[3] = (msg[0]-48) #ascii-to-int, to be improved
                                      update = 1
                              
                                  if ubinascii.hexlify(topic) == ubinascii.hexlify(topic_sub[4]):
                                      val[4] = (msg[0]-48) #ascii-to-int, to be improved
                                      update = 1
                              
                              client.set_callback(mytopic)
                              
                              chrono = Timer.Chrono()
                              chrono.start()
                              
                              while True:
                                  client.check_msg()
                                  if chrono.read()%60 < 5 and blink == 0:#just a blinking
                                      pycom.rgbled(0x0064)
                                      blink = 1
                                      print(".")
                              
                                  if chrono.read()%60 > 5 and blink == 1:#just a blinking
                                      pycom.rgbled(0x0000)
                                      blink = 0
                                      print("-")
                              
                                  if chrono.read() > 800:#wait 800s to avoid the sigfox message limit per day
                                      pycom.rgbled(0x007f00)
                                      s.send(bytes(val))
                                      print("Sigfox sent\n")
                                      chrono.reset()
                                      pycom.rgbled(0x0000)
                              
                                  if update == 1:#send immediately if update is triger
                                      pycom.rgbled(0x007f00)
                                      s.send(bytes(val))
                                      print("Sigfox sent\n")
                                      chrono.reset()
                                      update = 0
                                      pycom.rgbled(0x0000)
                              

                              But the exact nature of the result of topic and message are unknown. Is it a string, a byte,... ?
                              Most conversions don't works. I've tried float() or int() and get errors

                              I still have errors, certainly related to that problem :
                              And I've got the following message error when

                              s.send(bytes(val))
                              #val is filled with the several message of the topics
                              

                              The packet is correctly sent, but the program quit with the following error message OSError: [Errno 100] ENETDOWN

                              When I send the following code, I've no error

                              val = [1,2,3,4,5]
                              s.send(bytes(val))
                              
                              L 1 Reply Last reply Reply Quote 0
                              • L Offline
                                livius @luc hanneuse
                                last edited by

                                @luc-hanneuse said in MQTT with 2 subscribes:

                                unknown. Is it a string, a byte,... ?

                                unknown = None?
                                if yes than it mean no value at all.

                                And before send put print command to see what you tried to send

                                print(str(val))
                                s.send(bytes(val))
                                

                                and if you still have problem show what was printed

                                think about people first, then computers

                                L 1 Reply Last reply Reply Quote 0
                                • L Offline
                                  luc hanneuse @livius
                                  last edited by

                                  @livius

                                  The "topic" and "message" variables are created by the mqtt library.
                                  And yes, those variables don't react like string, byte,... most of the variables conversion don't work. That's why I called them "unknown".

                                  I've already print them, but that doesn't help to clarify the type of variable.

                                  L 1 Reply Last reply Reply Quote 0
                                  • L Offline
                                    livius @luc hanneuse
                                    last edited by

                                    @luc-hanneuse
                                    first you can try to test if it is None

                                    if v==None:
                                    

                                    and also you can test for type by:

                                    type(v)
                                    

                                    think about people first, then computers

                                    1 Reply Last reply Reply Quote 0

                                    Hello! It looks like you're interested in this conversation, but you don't have an account yet.

                                    Getting fed up of having to scroll through the same posts each visit? When you register for an account, you'll always come back to exactly where you were before, and choose to be notified of new replies (either via email, or push notification). You'll also be able to save bookmarks and upvote posts to show your appreciation to other community members.

                                    With your input, this post could be even better 💗

                                    Register Login
                                    • 1 / 1
                                    • First post
                                      Last post

                                    Pycom on Twitter

                                    Pycom