peterhinch / micropython-mqtt

A 'resilient' asynchronous MQTT driver. Recovers from WiFi and broker outages.
MIT License
575 stars 126 forks source link

Use Mqtt_as from inside a class #20

Closed TrevisGordan closed 5 years ago

TrevisGordan commented 5 years ago

Hello Peter, I unsuccessfully tried to implement the MQTT class into an own class to control it. But so far it is not working and I don't understand why. It works to publish messages from inside a class but not to subscribe to topics or calling the callback-func.

This is the Full code. which should make it self-explanatory what I'm trying to archive (I hope).

Comment Notes:

  1. MQTTClient.LOGGING = True is the logging functionality described in the pull request.
  2. The Async callback works after the first pull request (more details there). BUT I also tried it with the master version of mqtt_as to make sure it is not conflicting.
  3. using the client in the class via self.client would make it obsolete to have a client argument but if i remove it, it will raise a TypeError, because it has this (self) argument in Line 511. https://github.com/peterhinch/micropython-mqtt/blob/73cac209a798bf31194fcd78c7c896e32e26e7ee/mqtt_as/mqtt_as.py#L511

Also: client.connect(), self.client.publish works. Any Help would be highly appreciated!

from mqtt_asx import MQTTClient
from config import config
import uasyncio as asyncio
import asyn
import logging

logging.basicConfig(level=logging.DEBUG)
log_mqtt = logging.getLogger("Mqtt")

SERVER = 'x.x.x.x'
DEVICE = "blind1"

# Sub topics
sub_cmd = "OPENBlind/{}/cmd/#".format(DEVICE)
sub_set = "OPENBlind/{}/settings/#".format(DEVICE)
# Publish topics
pub_sta = "OPENBlind/{}/state".format(DEVICE)
pub_cmd_pos_res = "OPENBlind/{}/cmd/pos/result".format(DEVICE)
pub_set_res = "OPENBlind/{}/settings/result".format(DEVICE)

class Mqtt():

    def __init__(self, motor, state):
        # # # # # # # # # # # #
        self.motor = motor
        self.state = state
        self.config = config
        # # # # # # # # # # # #
        self.config['subs_cb'] = self.callback
        self.config['connect_coro'] = self.conn_hnd
        self.config['server'] = SERVER
        # # # # # # # # # # # #
        MQTTClient.LOGGING = True # Note 1: Added Logging functionality -> (see pullreq)
        # MQTTClient.DEBUG = True
        self.client = MQTTClient(self.config)
        loop = asyncio.get_event_loop()
        log_mqtt.debug("Mqtt class Initiated")
        # # # # # # # # # # # #
        try:
            loop.run_until_complete(self.main())
        finally:
            self.client.close()  # Prevent LmacRxBlk:1 errors

    async def callback(self, topic, msg): # Note 2: Async Callback works after (See pullreq)
        log_mqtt.debug("Callback: {}, {}".format(topic,msg))
        await asyncio.sleep(1)
        print((topic, msg))

    async def conn_hnd(self, client): # Note 3: TypeError: line 511 function takes 1 positional arguments but 2 were given (self argument)
        await self.client.subscribe(sub_cmd, 1)
        await self.client.subscribe(sub_set, 1)
        log_mqtt.debug("Subscripedt To: CMD, SET")

    async def main(self):
        await self.client.connect()  # Con. from class works!
        # await self.conn_hnd(self.client) # <-- Note: i tried to start it manualy wich worked but did not call the callback. (with or without async.)
        # n = 0
        log_mqtt.debug("conected To client")
        await self.client.publish(pub_sta, 'Online', qos=1) # Pub. from class works!
        while True:
            pass

    def check_state(self):
        _, a, b = self.state()
        if a or b == 1:
            return False
        else:
            return True
rroemhild commented 5 years ago

Hi, maybe your main loop:

while True:
    pass

is blocking other routines. Try to use await asyncio.sleep(1) instead of pass.

TrevisGordan commented 5 years ago

Yes, Yes, Yes! - Of course! I can absolutely not believe it. I used the example code and commented it out, not thinking about it. I absolutely should have noticed it. Since there were no other RAM debug messages etc. - Thank you a lot!