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 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()
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
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, )
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
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()
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()
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
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()
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)
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)
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()
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()
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
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()
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()
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)
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()
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
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()
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()
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, )
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)
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, )
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)
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)
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)
# # 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()
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)