3

I try to pass values from MQTT to Kivy dashboard with a navigation drawler.

Can someone give me a hint how I can change the variables? Here is my sample code. MQTT is working. I use Python 3.6.6 and 1.10.1.

mainmenu.py

from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button
from kivy.garden.navigationdrawer import NavigationDrawer
from kivy.properties import StringProperty
import paho.mqtt.client as mqtt

class Drawer(NavigationDrawer):
    vartext1 = StringProperty("Button")
    vartext2 = StringProperty("Text")

class MainMenuApp(App):
    def build(self):
        return Drawer()

    def on_start(self):
        topic = "kivy/#"

        def onConnect(client, userdata, flags, rc):
            mqttc.subscribe(topic, 0)

        def onMessage(client, userdata, msg):
            msg.payload = msg.payload.decode("utf-8")
            print ("[INFO   ] [MQTT        ] topic: " + msg.topic +" msg: "+ msg.payload)
            if msg.topic == "kivy/button":
                vartext1 = msg.payload

            if msg.topic == "kivy/text":
                vartext2 = msg.payload

        mqttc = mqtt.Client(client_id="kivy-client", clean_session=True)
        mqttc.on_connect      = onConnect 
        mqttc.on_message      = onMessage
        mqttc.connect("10.0.0.104", 1883, keepalive=60, bind_address="")
        mqttc.loop_start() # start loop to process callbacks! (new thread!)

if __name__ == "__main__":
    MainMenuApp().run()

mainmenu.kv

<Drawer>:
    # Side panel
    BoxLayout:
        padding: 30
        Button:
            text: root.vartext1
    # Main panel
    BoxLayout:
        padding: 30
        Label:
            text: root.vartext2
eyllanesc
  • 235,170
  • 19
  • 170
  • 241

2 Answers2

4

You can pass "self" parameter to mqtt.Client constructor like this:

parameters = {'self': self}
mqttc = mqtt.Client(client_id="kivy-client", clean_session=True, userdata = parameters)

and now inside onMessage procedure you can access that parameters:

userdata['self'].vartext1 = msg.payload

So your mainmenu.py file should looks like that:

from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button
from kivy.garden.navigationdrawer import NavigationDrawer
from kivy.properties import StringProperty
import paho.mqtt.client as mqtt

class Drawer(NavigationDrawer):
    vartext1 = StringProperty("Button")
    vartext2 = StringProperty("Text")

class MainMenuApp(App):
    def build(self):
        return Drawer()

    def on_start(self):
        topic = "kivy/#"

        def onConnect(client, userdata, flags, rc):
            mqttc.subscribe(topic, 0)

        def onMessage(client, userdata, msg):
            msg.payload = msg.payload.decode("utf-8")
            print ("[INFO   ] [MQTT        ] topic: " + msg.topic +" msg: "+ msg.payload)
            if msg.topic == "kivy/button":
                userdata['self'].vartext1 = msg.payload

            if msg.topic == "kivy/text":
                userdata['self'].vartext2 = msg.payload

        parameters = {'self': self}
        mqttc = mqtt.Client(client_id="kivy-client", clean_session=True, userdata = parameters)
        mqttc.on_connect      = onConnect 
        mqttc.on_message      = onMessage
        mqttc.connect("10.0.0.104", 1883, keepalive=60, bind_address="")
        mqttc.loop_start() # start loop to process callbacks! (new thread!)

if __name__ == "__main__":
    MainMenuApp().run()
Mike Olszak
  • 373
  • 6
  • 12
0

Think there is missing a .root for userdata['self'] in your problem.

At least for me, it worked when I made the following change.

Replace

userdata['self'].vartext2 = msg.payload 

to

userdata['self'].root.vartext2 = msg.payload
Nandu Raj
  • 2,072
  • 9
  • 20
Jens Dittmar
  • 1
  • 1
  • 1