示例#1
0
 async def __init__(self, uri="mqtt://localhost:1883"):
     if "://" not in uri:
         uri = "mqtt://" + uri
     self.uri = uri
     self.subscriptions = {}
     self.mqtt = MQTTClient(config={"auto_reconnect": False})
     for key in logging.Logger.manager.loggerDict:
         if key.startswith("hbmqtt"):
             logging.getLogger(key).setLevel(logging.WARNING)
     await self.mqtt.connect(self.uri)
     asyncio.ensure_future(self._loop())
示例#2
0
async def test_coro():
    C = MQTTClient()
    await C.connect("mqtt://test.mosquitto.org/")
    tasks = [
        asyncio.ensure_future(C.publish("a/b", b"TEST MESSAGE WITH QOS_0")),
        asyncio.ensure_future(
            C.publish("a/b", b"TEST MESSAGE WITH QOS_1", qos=QOS_1)),
        asyncio.ensure_future(
            C.publish("a/b", b"TEST MESSAGE WITH QOS_2", qos=QOS_2)),
    ]
    await asyncio.wait(tasks)
    logger.info("messages published")
    await C.disconnect()
示例#3
0
文件: main.py 项目: afra/v4runa
    async def wait_kick_space(self):
        """
        The external device will publish a mqtt event.
        This function handles this event.
        """

        self.mqcli = MQTTClient(config=MQTT_CONFIG, loop=self.loop)
        while True:
            try:
                await self.mqcli.connect('mqtt://localhost/')
                await self.mqcli.subscribe([
                    ('afra/door', QOS_2),
                    ])
            except:
                LOG.warning("mqtt: failed to connect. Retrying in 10 seconds.")
                await asyncio.sleep(10)
                continue
            LOG.info("mqtt: connected")

            while True:
                try:
                    message = await self.mqcli.deliver_message()
                    LOG.info("mqtt: delivered a message")
                    # TODO: ignoring the payload for now
                    await self.store.set('door_kicked_timestamp', datetime.now().timestamp())
                    await self.check_state_change()
                except ClientException as ce:
                    LOG.warning("mqtt: failed to connect. Retrying in 10 seconds.")
                    break
示例#4
0
async def test_client_subscribe_twice(broker, mock_plugin_manager):
    client = MQTTClient()
    ret = await client.connect("mqtt://127.0.0.1/")
    assert ret == 0
    await client.subscribe([("/topic", QOS_0)])

    # Test if the client test client subscription is registered
    assert "/topic" in broker._subscriptions
    subs = broker._subscriptions["/topic"]
    assert len(subs) == 1
    (s, qos) = subs[0]
    assert s == client.session
    assert qos == QOS_0

    await client.subscribe([("/topic", QOS_0)])
    assert len(subs) == 1
    (s, qos) = subs[0]
    assert s == client.session
    assert qos == QOS_0

    await client.disconnect()
    await asyncio.sleep(0.1)

    mock_plugin_manager.assert_has_calls(
        [
            call().fire_event(
                EVENT_BROKER_CLIENT_SUBSCRIBED,
                client_id=client.session.client_id,
                topic="/topic",
                qos=QOS_0,
            )
        ],
        any_order=True,
    )
示例#5
0
async def _client_publish(topic, data, qos, retain=False):
    pub_client = MQTTClient()
    ret = await pub_client.connect("mqtt://127.0.0.1/")
    assert ret == 0
    ret = await pub_client.publish(topic, data, qos, retain)
    await pub_client.disconnect()
    return ret
示例#6
0
async def uptime_coro():
    C = MQTTClient()
    await C.connect("mqtt://*****:*****@0.0.0.0:1883")
    # await C.connect('mqtt://0.0.0.0:1883')
    # Subscribe to '$SYS/broker/uptime' with QOS=1
    await C.subscribe(
        [
            ("data/memes", QOS_1),  # Topic allowed
            ("data/classified", QOS_1),  # Topic forbidden
            ("repositories/amqtt/master", QOS_1),  # Topic allowed
            ("repositories/amqtt/devel", QOS_1),  # Topic forbidden
            ("calendar/amqtt/releases", QOS_1),  # Topic allowed
        ]
    )
    logger.info("Subscribed")
    try:
        for i in range(1, 100):
            message = await C.deliver_message()
            packet = message.publish_packet
            print(
                "%d: %s => %s"
                % (i, packet.variable_header.topic_name, str(packet.payload.data))
            )
        await C.unsubscribe(["$SYS/broker/uptime", "$SYS/broker/load/#"])
        logger.info("UnSubscribed")
        await C.disconnect()
    except ClientException as ce:
        logger.error("Client exception: %s" % ce)
async def main(influx_client):
    mqtt_url = os.environ.get("MQTT_URL", "mqtt://localhost/")
    mqtt_topic = os.environ.get("MQTT_TOPIC", "/home/ble-deduped")

    client = MQTTClient()

    print("Connecting", mqtt_url)
    global last_receive_timestamp
    try:
        await client.connect(mqtt_url)
        print("Connected")
    except Exception as e:
        print("Connection failed: %s" % e)
        asyncio.get_event_loop().stop()
    await client.subscribe([
        (mqtt_topic, QOS_0),
    ])
    print("Subscribed")
    while True:
        message = await client.deliver_message()
        data = message.data
        ble_msg = json.loads(data)
        receiver_mac = ble_msg['receiver_mac']
        mac = ble_msg['address']['address']
        rssi = ble_msg['rssi']
        data = ble_msg['service_data'] or ble_msg['mfg_data']
        if data is not None:
            data = bytes(
                data, 'iso-8859-1'
            )  # it was encoded as codepoints for transport over JSON

        # TODO Should be async, but doesn't matter much with a handful of ruuvitags
        handle_message(influx_client, receiver_mac, mac, rssi, data, ble_msg)
        last_receive_timestamp = time.time()
示例#8
0
async def test_connect_ws():
    broker = Broker(broker_config, plugin_namespace="amqtt.test.plugins")
    await broker.start()
    client = MQTTClient()
    await client.connect("ws://127.0.0.1:8080/")
    assert client.session is not None
    await client.disconnect()
    await broker.shutdown()
示例#9
0
async def test_client_publish_retain_delete(broker):
    pub_client = MQTTClient()
    ret = await pub_client.connect("mqtt://127.0.0.1/")
    assert ret == 0
    await pub_client.publish("/topic", b"", QOS_0, retain=True)
    await pub_client.disconnect()
    await asyncio.sleep(0.1)
    assert "/topic" not in broker._retained_messages
示例#10
0
async def test_client_publish_invalid_topic(broker):
    assert broker.transitions.is_started()
    pub_client = MQTTClient()
    ret = await pub_client.connect("mqtt://127.0.0.1/")
    assert ret == 0

    await pub_client.publish("/+", b"data", QOS_0)
    await asyncio.sleep(0.1)
    await pub_client.disconnect()
示例#11
0
class ServerConnection:
    """MQTT Client."""
    async def __init__(self, uri="mqtt://localhost:1883"):
        if "://" not in uri:
            uri = "mqtt://" + uri
        self.uri = uri
        self.subscriptions = {}
        self.mqtt = MQTTClient(config={"auto_reconnect": False})
        for key in logging.Logger.manager.loggerDict:
            if key.startswith("hbmqtt"):
                logging.getLogger(key).setLevel(logging.WARNING)
        await self.mqtt.connect(self.uri)
        asyncio.ensure_future(self._loop())

    async def _loop(self):
        """Connection handling loop."""
        while True:
            try:
                if self.subscriptions:
                    await self.mqtt.subscribe([
                        (t, qos) for t, (_, qos) in self.subscriptions.items()
                    ])
                while True:
                    message = await self.mqtt.deliver_message()
                    topic = message.publish_packet.variable_header.topic_name
                    payload = message.publish_packet.payload.data.decode()
                    callback = self.subscriptions.get(
                        topic, (self.message_handler, ))[0]
                    asyncio.ensure_future(callback(topic, payload))
            except KeyboardInterrupt:
                break
            except asyncio.CancelledError:
                break
            finally:
                await self.mqtt.disconnect()
            await asyncio.sleep(1)
            await self.mqtt.reconnect()

    async def pub(self, topic, payload, qos=0):
        """Publish message on topic."""
        if isinstance(payload, dict) or isinstance(payload, list):
            payload = json.dumps(payload)
        asyncio.ensure_future(
            self.mqtt.publish(topic,
                              str(payload).encode(), qos))

    async def sub(self, topic, callback, qos=0):
        """Subscribe to topic with callback."""
        self.subscriptions[topic] = (callback, qos)
        await self.mqtt.subscribe([(topic, qos)])
        LOGGER.info("Subscribed to topic %s", topic)

    async def message_handler(self, topic, payload):
        """Default message handler."""
        LOGGER.info("Message on unknown topic: %s : {%s}", topic, payload)
示例#12
0
async def test_client_connect_clean_session_false(broker):
    client = MQTTClient(client_id="", config={"auto_reconnect": False})
    return_code = None
    try:
        await client.connect("mqtt://127.0.0.1/", cleansession=False)
    except ConnectException as ce:
        return_code = ce.return_code
    assert return_code == 0x02
    assert client.session.client_id not in broker._sessions
    await client.disconnect()
    await asyncio.sleep(0.1)
示例#13
0
async def test_reconnect_ws_retain_username_password():
    broker = Broker(broker_config, plugin_namespace="amqtt.test.plugins")
    await broker.start()
    client = MQTTClient()
    await client.connect("ws://*****:*****@127.0.0.1:8080/")
    assert client.session is not None
    await client.disconnect()
    await client.reconnect()

    assert client.session.username is not None
    assert client.session.password is not None
    await broker.shutdown()
示例#14
0
async def test_coro2():
    try:
        C = MQTTClient()
        await C.connect("mqtt://test.mosquitto.org:1883/")
        await C.publish("a/b", b"TEST MESSAGE WITH QOS_0", qos=0x00)
        await C.publish("a/b", b"TEST MESSAGE WITH QOS_1", qos=0x01)
        await C.publish("a/b", b"TEST MESSAGE WITH QOS_2", qos=0x02)
        logger.info("messages published")
        await C.disconnect()
    except ConnectException as ce:
        logger.error("Connection failed: %s" % ce)
        asyncio.get_event_loop().stop()
示例#15
0
async def test_client_publish_retain(broker):
    pub_client = MQTTClient()
    ret = await pub_client.connect("mqtt://127.0.0.1/")
    assert ret == 0
    await pub_client.publish("/topic", b"data", QOS_0, retain=True)
    await pub_client.disconnect()
    await asyncio.sleep(0.1)
    assert "/topic" in broker._retained_messages
    retained_message = broker._retained_messages["/topic"]
    assert retained_message.source_session == pub_client.session
    assert retained_message.topic == "/topic"
    assert retained_message.data == b"data"
    assert retained_message.qos == QOS_0
示例#16
0
async def test_deliver():
    data = b"data"
    broker = Broker(broker_config, plugin_namespace="amqtt.test.plugins")
    await broker.start()
    client = MQTTClient()
    await client.connect("mqtt://127.0.0.1/")
    assert client.session is not None
    ret = await client.subscribe([
        ("test_topic", QOS_0),
    ])
    assert ret[0] == QOS_0
    client_pub = MQTTClient()
    await client_pub.connect("mqtt://127.0.0.1/")
    await client_pub.publish("test_topic", data, QOS_0)
    await client_pub.disconnect()
    message = await client.deliver_message()
    assert message is not None
    assert message.publish_packet is not None
    assert message.data == data
    await client.unsubscribe(["$SYS/broker/uptime"])
    await client.disconnect()
    await broker.shutdown()
示例#17
0
async def test_unsubscribe():
    broker = Broker(broker_config, plugin_namespace="amqtt.test.plugins")
    await broker.start()
    client = MQTTClient()
    await client.connect("mqtt://127.0.0.1/")
    assert client.session is not None
    ret = await client.subscribe([
        ("$SYS/broker/uptime", QOS_0),
    ])
    assert ret[0] == QOS_0
    await client.unsubscribe(["$SYS/broker/uptime"])
    await client.disconnect()
    await broker.shutdown()
示例#18
0
async def test_client_subscribe_invalid(broker):
    sub_client = MQTTClient()
    await sub_client.connect("mqtt://127.0.0.1")
    ret = await sub_client.subscribe([
        ("+", QOS_0),
        ("+/tennis/#", QOS_0),
        ("sport+", QOS_0),
        ("sport/+/player1", QOS_0),
    ])
    assert ret == [QOS_0, QOS_0, 0x80, QOS_0]

    await asyncio.sleep(0.1)
    await sub_client.disconnect()
    await asyncio.sleep(0.1)
示例#19
0
async def test_deliver_timeout():
    broker = Broker(broker_config, plugin_namespace="amqtt.test.plugins")
    await broker.start()
    client = MQTTClient()
    await client.connect("mqtt://127.0.0.1/")
    assert client.session is not None
    ret = await client.subscribe([
        ("test_topic", QOS_0),
    ])
    assert ret[0] == QOS_0
    with pytest.raises(asyncio.TimeoutError):
        await client.deliver_message(timeout=2)
    await client.unsubscribe(["$SYS/broker/uptime"])
    await client.disconnect()
    await broker.shutdown()
示例#20
0
 def __init__(self):
     self.client = MQTTClient(loop=loop,
                              config={
                                  "auto_reconnect": True,
                                  "reconnect_retries": 5000,
                                  "reconnect_max_interval": 120,
                                  "keep_alive": 60,
                                  "default_qos": 0
                              })
     self.work_handler = WorkHandler(config.worker,
                                     self.client,
                                     send_work_result,
                                     work_server_error_callback,
                                     logger=logger)
     self.running = False
     self.server_online = False
示例#21
0
def main(*args, **kwargs):
    if sys.version_info[:2] < (3, 7):
        logger.fatal("Error: Python 3.7+ is required")
        sys.exit(-1)

    arguments = docopt(__doc__, version=amqtt.__version__)
    # print(arguments)
    formatter = "[%(asctime)s] :: %(levelname)s - %(message)s"

    if arguments["-d"]:
        level = logging.DEBUG
    else:
        level = logging.INFO
    logging.basicConfig(level=level, format=formatter)

    if arguments["-c"]:
        config = read_yaml_config(arguments["-c"])
    else:
        config = read_yaml_config(
            os.path.join(
                os.path.dirname(os.path.realpath(__file__)), "default_client.yaml"
            )
        )
        logger.debug("Using default configuration")
    loop = asyncio.get_event_loop()

    client_id = arguments.get("-i", None)
    if not client_id:
        client_id = _gen_client_id()

    if arguments["-k"]:
        config["keep_alive"] = int(arguments["-k"])

    if (
        arguments["--will-topic"]
        and arguments["--will-message"]
        and arguments["--will-qos"]
    ):
        config["will"] = dict()
        config["will"]["topic"] = arguments["--will-topic"]
        config["will"]["message"] = arguments["--will-message"].encode("utf-8")
        config["will"]["qos"] = int(arguments["--will-qos"])
        config["will"]["retain"] = arguments["--will-retain"]

    client = MQTTClient(client_id=client_id, config=config, loop=loop)
    loop.run_until_complete(do_pub(client, arguments))
    loop.close()
示例#22
0
async def test_coro():
    try:
        C = MQTTClient()
        await C.connect("mqtt://0.0.0.0:1883")
        await C.publish("data/classified", b"TOP SECRET", qos=0x01)
        await C.publish("data/memes", b"REAL FUN", qos=0x01)
        await C.publish("repositories/amqtt/master",
                        b"NEW STABLE RELEASE",
                        qos=0x01)
        await C.publish("repositories/amqtt/devel",
                        b"THIS NEEDS TO BE CHECKED",
                        qos=0x01)
        await C.publish("calendar/amqtt/releases", b"NEW RELEASE", qos=0x01)
        logger.info("messages published")
        await C.disconnect()
    except ConnectException as ce:
        logger.error("Connection failed: %s" % ce)
        asyncio.get_event_loop().stop()
示例#23
0
async def test_client_connect(broker, mock_plugin_manager):
    client = MQTTClient()
    ret = await client.connect("mqtt://127.0.0.1/")
    assert ret == 0
    assert client.session.client_id in broker._sessions
    await client.disconnect()

    await asyncio.sleep(0.01)

    mock_plugin_manager.assert_has_calls(
        [
            call().fire_event(EVENT_BROKER_CLIENT_CONNECTED,
                              client_id=client.session.client_id),
            call().fire_event(EVENT_BROKER_CLIENT_DISCONNECTED,
                              client_id=client.session.client_id),
        ],
        any_order=True,
    )
示例#24
0
async def test_client_subscribe_publish(broker):
    sub_client = MQTTClient()
    await sub_client.connect("mqtt://127.0.0.1")
    ret = await sub_client.subscribe([("/qos0", QOS_0), ("/qos1", QOS_1),
                                      ("/qos2", QOS_2)])
    assert ret == [QOS_0, QOS_1, QOS_2]

    await _client_publish("/qos0", b"data", QOS_0)
    await _client_publish("/qos1", b"data", QOS_1)
    await _client_publish("/qos2", b"data", QOS_2)
    await asyncio.sleep(0.1)
    for qos in [QOS_0, QOS_1, QOS_2]:
        message = await sub_client.deliver_message()
        assert message is not None
        assert message.topic == "/qos%s" % qos
        assert message.data == b"data"
        assert message.qos == qos
    await sub_client.disconnect()
    await asyncio.sleep(0.1)
示例#25
0
async def test_client_publish(broker, mock_plugin_manager):
    pub_client = MQTTClient()
    ret = await pub_client.connect("mqtt://127.0.0.1/")
    assert ret == 0

    ret_message = await pub_client.publish("/topic", b"data", QOS_0)
    await pub_client.disconnect()
    assert broker._retained_messages == {}

    await asyncio.sleep(0.1)

    mock_plugin_manager.assert_has_calls(
        [
            call().fire_event(
                EVENT_BROKER_MESSAGE_RECEIVED,
                client_id=pub_client.session.client_id,
                message=ret_message,
            ),
        ],
        any_order=True,
    )
示例#26
0
async def test_client_subscribe_publish_dollar_topic_2(broker):
    sub_client = MQTTClient()
    await sub_client.connect("mqtt://127.0.0.1")
    ret = await sub_client.subscribe([("+/monitor/Clients", QOS_0)])
    assert ret == [QOS_0]

    await _client_publish("test/monitor/Clients", b"data", QOS_0)
    message = await sub_client.deliver_message()
    assert message is not None

    await _client_publish("$SYS/monitor/Clients", b"data", QOS_0)
    await asyncio.sleep(0.1)
    message = None
    try:
        message = await sub_client.deliver_message(timeout=2)
    except asyncio.TimeoutError:
        pass
    except RuntimeError as e:
        # The loop is closed with pending tasks. Needs fine tuning.
        log.warning(e)
    assert message is None
    await sub_client.disconnect()
    await asyncio.sleep(0.1)
示例#27
0
async def test_client_publish_retain_subscribe(broker):
    sub_client = MQTTClient()
    await sub_client.connect("mqtt://127.0.0.1", cleansession=False)
    ret = await sub_client.subscribe([("/qos0", QOS_0), ("/qos1", QOS_1),
                                      ("/qos2", QOS_2)])
    assert ret == [QOS_0, QOS_1, QOS_2]
    await sub_client.disconnect()
    await asyncio.sleep(0.1)

    await _client_publish("/qos0", b"data", QOS_0, retain=True)
    await _client_publish("/qos1", b"data", QOS_1, retain=True)
    await _client_publish("/qos2", b"data", QOS_2, retain=True)
    await sub_client.reconnect()
    for qos in [QOS_0, QOS_1, QOS_2]:
        log.debug("TEST QOS: %d" % qos)
        message = await sub_client.deliver_message()
        log.debug("Message: " + repr(message.publish_packet))
        assert message is not None
        assert message.topic == "/qos%s" % qos
        assert message.data == b"data"
        assert message.qos == qos
    await sub_client.disconnect()
    await asyncio.sleep(0.1)
示例#28
0
async def uptime_coro():
    C = MQTTClient()
    await C.connect("mqtt://test.mosquitto.org/")
    # Subscribe to '$SYS/broker/uptime' with QOS=1
    await C.subscribe(
        [
            ("$SYS/broker/uptime", QOS_1),
            ("$SYS/broker/load/#", QOS_2),
        ]
    )
    logger.info("Subscribed")
    try:
        for i in range(1, 100):
            message = await C.deliver_message()
            packet = message.publish_packet
            print(
                "%d: %s => %s"
                % (i, packet.variable_header.topic_name, str(packet.payload.data))
            )
        await C.unsubscribe(["$SYS/broker/uptime", "$SYS/broker/load/#"])
        logger.info("UnSubscribed")
        await C.disconnect()
    except ClientException as ce:
        logger.error("Client exception: %s" % ce)
示例#29
0
#
# This sample shows how to publish messages to broker using different QOS
# Debug outputs shows the message flows
#

logger = logging.getLogger(__name__)

config = {
    "will": {
        "topic": "/will/client",
        "message": b"Dead or alive",
        "qos": 0x01,
        "retain": True,
    },
}
C = MQTTClient(config=config)


# C = MQTTClient()
async def test_coro():
    await C.connect("mqtts://test.mosquitto.org/", cafile="mosquitto.org.crt")
    tasks = [
        asyncio.ensure_future(C.publish("a/b", b"TEST MESSAGE WITH QOS_0")),
        asyncio.ensure_future(
            C.publish("a/b", b"TEST MESSAGE WITH QOS_1", qos=QOS_1)),
        asyncio.ensure_future(
            C.publish("a/b", b"TEST MESSAGE WITH QOS_2", qos=QOS_2)),
    ]
    await asyncio.wait(tasks)
    logger.info("messages published")
    await C.disconnect()
示例#30
0
async def run(voc, config):

    logging.getLogger("amqtt.client.plugins.packet_logger_plugin").setLevel(
        logging.WARNING)

    client_id = "voc_{hostname}_{time}".format(hostname=hostname(),
                                               time=time())

    mqtt = MQTTClient(client_id=client_id)
    url = config.get("mqtt_url")

    if url:
        _LOGGER.debug("Using MQTT url from voc.conf")
    else:
        _LOGGER.debug("Using MQTT url from mosquitto_pub")
        mqtt_config = read_mqtt_config()
        try:
            username = mqtt_config["username"]
            password = mqtt_config["password"]
            host = mqtt_config["host"]
            port = mqtt_config["port"]
            url = "mqtts://{username}:{password}@{host}:{port}".format(
                username=username, password=password, host=host, port=port)
        except Exception as e:
            exit(e)

    entities = {}

    async def mqtt_task():
        try:
            await mqtt.connect(url, cleansession=False, cafile=certifi.where())
            _LOGGER.info("Connected to MQTT server")
        except ConnectException as e:
            exit("Could not connect to MQTT server: %s" % e)
        while True:
            _LOGGER.debug("Waiting for messages")
            try:
                message = await mqtt.deliver_message()
                packet = message.publish_packet
                topic = packet.variable_header.topic_name
                payload = packet.payload.data.decode("ascii")
                _LOGGER.debug("got message on %s: %s", topic, payload)
                Entity.route_message(topic, payload)
            except ClientException as e:
                _LOGGER.error("MQTT Client exception: %s", e)

    asyncio.create_task(mqtt_task())  # pylint:disable=no-member

    interval = int(config["interval"])
    _LOGGER.info("Polling VOC every %d seconds", interval)
    while True:
        available = await voc.update(journal=True)
        wait_list = []
        for vehicle in voc.vehicles:
            if vehicle not in entities:
                _LOGGER.debug("creating vehicle %s", vehicle)

                dashboard = vehicle.dashboard(**config)

                entities[vehicle] = [
                    Entity(mqtt, instrument, config)
                    for instrument in dashboard.instruments
                ]
            for entity in entities[vehicle]:
                _LOGGER.debug("%s: %s", entity.instrument.full_name,
                              entity.state)
                wait_list.append(entity.publish_discovery())
                wait_list.append(entity.publish_availability(available))
                if available:
                    wait_list.append(entity.publish_state())

        await asyncio.gather(*wait_list)
        _LOGGER.debug("Waiting for new VOC update in %d seconds", interval)
        await asyncio.sleep(interval)