Example #1
0
    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")
Example #2
0
    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)
Example #3
0
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
Example #4
0
    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)
Example #5
0
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)