Mqtt subscribe.simple in BGE

Hi guys. I try to subscribe to topic and get one value from it but i suppose that subscribe.simple don’t want work with me. I wanna do this in really simple way. Can anybody help me if I maybe do something wrong in my script or do you know any ideas how to change subsribe.simple in something working?

from paho.mqtt import subscribe
import json
from bge import logic
import stay
import go

owner = logic.getCurrentController().owner

def get_measurement():
    message = subscribe.simple('measurements', hostname="IP", port=PORT)
    data = json.loads(message.payload)
    measurement = int(data["value"])
    return measurement

def stay_or_go():
    Xspeed, Yspeed, Zspeed = owner.getLinearVelocity(True)
    if Zspeed == 0:
        if get_measurement() == 0:
            stay()
        if get_measurement() > 0:
            go()

if __name__ == "__main__":
    stay_or_go()

I can’t help you with this, no clue what paho does/is, but do have a suggestion.

in module or rather function mode (def) you should always include the owner in it.

so this:

should be inside the function. And at the same time you can let the function create the controller, so you get:

def stay_or_go(cont):
    owner = cont.owner
    Xspeed, Yspeed, Zspeed = owner.getLinearVelocity(True)
    if Zspeed == 0:
        if get_measurement() == 0:
            stay()
        if get_measurement() > 0:
            go()

Everything outside of functions wil only be run once, and only when the script is called for the first time. this in turn will block the usage of this script on multiple objects, if you include it, every object running the script get’s his own ‘id’.

What does the stack trace say?

Also, this isn’t a BGE question, this is a paho.mqtt question. Might get a better response from whoever maintains that package.

subscribe.simple('measurements', hostname="IP", port=PORT)

"IP" is an invalid hostname and PORT is not defined.

Hostname is meant to be either an actual IP or some network name that can be resolved.

Port is supposed to be the TCP or UDP port of the server you wish to subscribe to.

Also, the following code looks very odd to me:

import stay
import go

# [...]

        if get_measurement() == 0:
            stay()
        if get_measurement() > 0:
            go()

import statements usually return Module instances, which are not callable.

I’d go one further than “odd” and call that a bug that will annoy for possibly weeks until it’s finally noticed that half the measurements are not recorded.

        measurement = get_measurement()
        if measurement == 0:
            stay()
        elif measurement > 0:
            go()

I just had a look at the documentation for this thing. It’s a full networking library.
http://www.eclipse.org/paho/clients/python/docs/
There is no way random syntax/logic questions here are going to help teach OP how to do networking in Python.

For starters, there isn’t a defined a callback, but there are multiple subscriptions to messages.

I’d recommend learning how to use this library properly outside of BGE first, then we can help you with how to add your networking code to BGE without freezing up the interface and crashing the program.

Thank you! :slight_smile: I will add it :slight_smile:

Stack trace don’t give me any error, it just don’t get any value from mqtt subscribe. But when I run it from e.g. terminal using python outside blender i have this value :slight_smile: seems to me like in blender we can not use subscribe.simple but maybe im wrong…

@WKnight02 I can not share real value of IP and PORT :slight_smile: thats why it looks like that… :slight_smile: in blender i have real value :slight_smile:

This 2 imports: stay and go this is my python files from the same projects and it should work :wink: for other things it works for me :slight_smile:

@TheDave hehe thx but im pretty sure that i can use paho.mqtt outside blender quit good :wink:

K, so I get that you edited the file before posting it here.

Well, if it works outside of Blender and when in Blender it doesn’t work then you should put print statement in places where you expect the code to go. Cheap debugging.

On the other hand, @Cotaks explained something that I did not see in your code.

The syntax you used:

if __name__ == '__main__':
    # meh

Works well when running scripts using a Python interpreter indeed.

But when working with BGE, you might want to do like Cotaks said and have some Python Controller Function:

def pycontroller_entrypoint(controller):
    owner = controller.owner
    # do stuff

Then in order to trigger it in Blender, you need to setup a Python Controller in module mode, and point to your function like python_module.pycontroller_entrypoint.

Understand that at this point, the function is handling the logic of the BGE controller, so to do anything, you need to correctly setup your sensors.

The function you’re calling is blocking, so you should notice significant framerate issues while running it. Is the BGE entirely locked up when you run it? If you don’t notice any frame rate issues, then could Zspeed never be equal to 0, thus never running the code? Keep in mind that 0.00000203 is not equal to 0.

There are very few practical differences between running code in BGE vs in the terminal.

^ this. So much this. Can’t count how many times this has pointed out a logic flaw that I never expected.