async def init_client(self, cbpi): async with Client("localhost", will=Will(topic="cbpi/diconnect", payload="MY CLIENT")) as client: async with client.filtered_messages("cbpi/#") as messages: await client.subscribe("cbpi/#") async for message in messages: await self.cbpi.actor.on("YwGzXvWMpmbLb6XobesL8n")
async def run(self) -> None: event = partial(self._event, None) self._proto.add_listener(event, ["SmlGetListResponse"]) await self._proto.connect() p = urlparse(self._cfg["broker"], scheme="mqtt") if p.scheme not in ("mqtt", "mqtts") or not p.hostname: raise ValueError tls_context = None if p.scheme == "mqtts": tls_context = ssl.create_default_context() will = Will( await self._base_topic("availability"), payload=b"offline", qos=2, retain=True, ) self._proto.remove_listener(event, ["SmlGetListResponse"]) async with Client( p.hostname, port=p.port or p.scheme == "mqtt" and 1883 or 8883, username=p.username, password=p.password, logger=logger, tls_context=tls_context, will=will, ) as mqtt: watchdog_callback = partial(self._publish_availability, mqtt) self._wdt.start(watchdog_callback) event = partial(self._event, mqtt) self._proto.add_listener(event, ["SmlGetListResponse"]) if self._cfg["hass"]: await self._publish_hass_config(mqtt) await self._run_mainloop(mqtt) self._proto.remove_listener(event, ["SmlGetListResponse"]) self._wdt.stop() await self._publish_availability(mqtt, False)
async def _connect(): global MQTT, CONNECT, PUBS_FAILED_SINCE, WAIT_BETWEEN_CONNECTS # We don't publish anything if we just analyze the data from the reader if sml2mqtt._args.ARGS.analyze: return None while True: try: await asyncio.sleep(WAIT_BETWEEN_CONNECTS) will_topic = CONFIG.mqtt.topics.get_topic( CONFIG.mqtt.topics.last_will) MQTT = Client(hostname=CONFIG.mqtt.connection.host, port=CONFIG.mqtt.connection.port, username=CONFIG.mqtt.connection.user if CONFIG.mqtt.connection.user else None, password=CONFIG.mqtt.connection.password if CONFIG.mqtt.connection.password else None, will=Will(will_topic, payload='OFFLINE')) log.debug( f'Connecting to {CONFIG.mqtt.connection.host}:{CONFIG.mqtt.connection.port}' ) await MQTT.connect() log.debug('Success!') # signal that we are online await publish(will_topic, 'ONLINE') WAIT_BETWEEN_CONNECTS = 0 PUBS_FAILED_SINCE = None break except MqttError as e: WAIT_BETWEEN_CONNECTS = min(180, max(1, WAIT_BETWEEN_CONNECTS) * 2) log.error(f'{e} ({e.__class__.__name__})') except Exception: WAIT_BETWEEN_CONNECTS = min(180, max(1, WAIT_BETWEEN_CONNECTS) * 2) for line in traceback.format_exc().splitlines(): log.error(line) return None CONNECT = None
async def init_client(self, cbpi): async def log_messages(messages, template): async for message in messages: print(template.format(message.payload.decode())) async def cancel_tasks(tasks): for task in tasks: if task.done(): continue task.cancel() try: await task except asyncio.CancelledError: pass async with AsyncExitStack() as stack: tasks = set() stack.push_async_callback(cancel_tasks, tasks) self.client = Client("localhost", will=Will(topic="cbpi/diconnect", payload="CBPi Server Disconnected")) await stack.enter_async_context(self.client) topic_filters = ("cbpi/sensor/#", "cbpi/actor/#") for topic_filter in topic_filters: # Log all messages that matches the filter manager = self.client.filtered_messages(topic_filter) messages = await stack.enter_async_context(manager) task = asyncio.create_task(self.handle_message(messages)) tasks.add(task) messages = await stack.enter_async_context( self.client.unfiltered_messages()) task = asyncio.create_task(self.handle_unfilterd_message(messages)) tasks.add(task) await self.client.subscribe("cbpi/#") await asyncio.gather(*tasks)
DEFAULT_LIGHT_TIMEOUT = 12 * 60 * 60 # все команды на включение света должны выполняются в форме TEMPORARY_ON с # дефолтным временем 12 часов на случай если кто-то забыл выключить свет он гарантировано выключится через 12 часов PREFIX = cfg['mqtt_prefix'] HA_PREFIX = f'homeassistant/{PREFIX}' ERR_PREFIX = f'{PREFIX}/err' ONLINE_TOPIC = f'{HA_PREFIX}/online' OFFLINE = dict( topic=ONLINE_TOPIC, payload='offline', ) MQTT_CONF = { 'hostname': cfg['mqtt_host'], 'username': cfg['mqtt_user'], 'password': cfg['mqtt_password'], 'will': Will(**OFFLINE) } RECONNECT_TIME = 10 SWITCH_RESPONSE = f'{PREFIX}/s/{{ch}}' SWITCH_SUBSCRIPTION = f'{PREFIX}/s/+/set' RAW_RESPONSE = f'{PREFIX}/r/{{ch}}' RAW_SUBSCRIPTION = f'{PREFIX}/r/+/cmd' noolite = noo.Noolite(tty_name=cfg['serial_port'], loop=loop) motions = {} def parse_msg(msg): payload = msg.payload ch = int(msg.topic.split('/')[-2]) data = json.loads(payload)
async def init_client(self, cbpi): async def cancel_tasks(tasks): for task in tasks: if task.done(): continue task.cancel() try: await task except asyncio.CancelledError: pass while True: try: async with AsyncExitStack() as stack: self.tasks = set() stack.push_async_callback(cancel_tasks, self.tasks) self.client = Client(self.host, port=self.port, username=self.username, password=self.password, will=Will(topic="cbpi/diconnect", payload="CBPi Server Disconnected")) await stack.enter_async_context(self.client) for topic_filter in self.topic_filters: topic = topic_filter[0] method = topic_filter[1] manager = self.client.filtered_messages(topic) messages = await stack.enter_async_context(manager) task = asyncio.create_task(method(messages)) self.tasks.add(task) for topic_filter in self.topic_filters: topic = topic_filter[0] await self.client.subscribe(topic) self.logger.info("MQTT Connected to {}:{}".format(self.host, self.port)) await asyncio.gather(*self.tasks) except MqttError as e: self.logger.error("MQTT Exception: {}".format(e)) except Exception as e: self.logger.error("MQTT General Exception: {}".format(e)) await asyncio.sleep(5)