예제 #1
0
파일: basic.py 프로젝트: lsta/pai
    def _mqtt_handle_notifications(self, prep: ParsedMessage):
        topics = prep.topics
        try:
            level = EventLevel.from_name(topics[2].upper())
        except Exception as e:
            logger.error(e)
            return

        ps.sendNotification(Notification(sender=self.name, message=prep.content, level=level))
예제 #2
0
    async def _mqtt_handle_partition_control(self, prep: ParsedMessage):
        topics, element, command = prep
        command = cfg.MQTT_COMMAND_ALIAS.get(command, command)

        if command.startswith('code_toggle-'):
            tokens = command.split('-')
            if len(tokens) < 2:
                logger.warning("Invalid token length {}".format(len(tokens)))
                return

            if tokens[1] not in cfg.MQTT_TOGGLE_CODES:
                logger.warning("Invalid toggle code {}".format(tokens[1]))
                return

            if element.lower() == 'all':
                command = 'arm'

                for k, v in self.partitions.items():
                    # If "all" and a single partition is armed, default is
                    # to disarm
                    for k1, v1 in self.partitions[k].items():
                        if (k1 == 'arm' or k1 == 'exit_delay' or k1 == 'entry_delay') and v1:
                            command = 'disarm'
                            break

                    if command == 'disarm':
                        break

            elif element in self.partitions:
                if ('arm' in self.partitions[element] and self.partitions[element]['arm']) \
                        or ('exit_delay' in self.partitions[element] and self.partitions[element]['exit_delay']):
                    command = 'disarm'
                else:
                    command = 'arm'
            else:
                logger.warning("Element {} not found".format(element))
                return

            ps.sendNotification(
                Notification(
                    sender="mqtt",
                    message="Command by {}: {}".format(cfg.MQTT_TOGGLE_CODES[tokens[1]], command),
                    level=EventLevel.INFO
                )
            )

        logger.info("Partition command: {} = {}".format(element, command))
        if not await self.alarm.control_partition(element, command):
            logger.warning("Partition command refused: {}={}".format(element, command))
예제 #3
0
    def received_message(self, message):
        """ Handle Pushbullet message. It should be a command """
        logger.debug("Received Message {}".format(message))

        try:
            message = json.loads(str(message))
        except:
            logger.exception("Unable to parse message")
            return

        if message["type"] == "tickle" and message["subtype"] == "push":
            now = time.time()
            pushes = self.pb.get_pushes(
                modified_after=int(now) - 20, limit=1, filter_inactive=True
            )
            for p in pushes:

                # Ignore messages send by us
                if p.get("direction") == "self" and p.get("title") == "pai":
                    # logger.debug('Ignoring message sent')
                    continue

                if p.get("direction") == "outgoing" or p.get("dismissed"):
                    # logger.debug('Ignoring outgoing dismissed')
                    continue

                if (
                    p.get("sender_email_normalized") in cfg.PUSHBULLET_CONTACTS
                    or p.get("direction") == "self"
                ):
                    future = asyncio.run_coroutine_threadsafe(
                        self.interface.handle_command(p.get("body")),
                        self.interface.alarm.work_loop,
                    )
                    ret = future.result(10)

                    m = "PB {}: {}".format(p.get("sender_email_normalized"), ret)
                    logger.info(m)
                else:
                    m = "PB {} (UNK): {}".format(
                        p.get("sender_email_normalized"), p.get("body")
                    )
                    logger.warning(m)

                self.send_message(m)
                ps.sendNotification(
                    Notification(sender=self.name, message=m, level=EventLevel.INFO)
                )
예제 #4
0
    def handle_message(self, timestamp, source, groupID, message, attachments):
        """ Handle Signal message. It should be a command """

        logger.debug("Received Message {} {} {} {} {}".format(
            timestamp, message, groupID, message, attachments))

        if source in cfg.SIGNAL_CONTACTS:
            ret = self.handle_command(message)

            m = "Signal {} : {}".format(source, ret)
            logger.info(m)
        else:
            m = "Signal {} (UNK): {}".format(source, message)
            logger.warning(m)

        self.send_message(m, EventLevel.INFO)
        ps.sendNotification(
            Notification(sender=self.name, message=m, level=EventLevel.INFO))
예제 #5
0
파일: pushbullet.py 프로젝트: lsta/pai
    def received_message(self, message):
        """ Handle Pushbullet message. It should be a command """
        logger.debug("Received Message {}".format(message))

        try:
            message = json.loads(str(message))
        except:
            logger.exception("Unable to parse message")
            return

        if message['type'] == 'tickle' and message['subtype'] == 'push':
            now = time.time()
            pushes = self.pb.get_pushes(modified_after=int(now) - 20,
                                        limit=1,
                                        filter_inactive=True)
            for p in pushes:

                # Ignore messages send by us
                if p.get('direction') == 'self' and p.get('title') == 'pai':
                    #logger.debug('Ignoring message sent')
                    continue

                if p.get('direction') == 'outgoing' or p.get('dismissed'):
                    #logger.debug('Ignoring outgoing dismissed')
                    continue

                if p.get('sender_email_normalized'
                         ) in cfg.PUSHBULLET_CONTACTS or p.get(
                             'direction') == 'self':
                    ret = self.interface.handle_command(p.get('body'))

                    m = "PB {}: {}".format(p.get('sender_email_normalized'),
                                           ret)
                    logger.info(m)
                else:
                    m = "PB {} (UNK): {}".format(
                        p.get('sender_email_normalized'), p.get('body'))
                    logger.warning(m)

                self.send_message(m)
                ps.sendNotification(
                    Notification(sender=self.name,
                                 message=m,
                                 level=EventLevel.INFO))
예제 #6
0
    def process_cusd(self, message: str) -> None:
        idx = message.find(' ')
        if idx < 0:
            return

        tokens = json.loads(f'[{message[idx:]}]', strict=False)

        code = tokens[0]
        if code == 1:
            logger.info("Modem registered into network")
            ps.sendNotification(
                Notification(sender=self.name,
                             message="Modem registered into network",
                             level=EventLevel.INFO))
        elif code == 4:
            logger.warning("CUSD code not supported")
            return
        else:
            return
예제 #7
0
    def handle_message(self, timestamp, source, message):
        """ Handle GSM message. It should be a command """

        logger.debug("Received message: {} {} {}".format(
            timestamp, source, message))

        if source in cfg.GSM_CONTACTS:
            ret = self.handle_command(message)

            m = "FROM {}: {}".format(source, ret)
            logger.info(m)
        else:
            m = "INVALID SENDER: {}".format(message)
            logger.warning(m)

        ps.sendNotification(
            Notification(sender=self.name,
                         message=message,
                         level=EventLevel.INFO))
예제 #8
0
    async def data_received(self, data):

        if len(data) == 0:
            return

        if not self.modem_connected:
            return

        logger.debug("Data received: {}".format(data))

        data = data.decode().strip()

        # Ignore this as it is a status message of a successful operation
        if data == 'OK':
            return

        # Ups... log
        if data.startswith('ERROR'):
            logger.warning("Got error from Modem: {}".format(data))
            return

        # Process message from modem
        tokens = data.split('"')
        for i in range(len(tokens)):
            tokens[i] = tokens[i].strip()

        if len(tokens) <= 0:
            return

        if tokens[0] == '+CMT:':
            source = tokens[1]
            timestamp = datetime.datetime.strptime(tokens[5].split('+')[0],
                                                   '%y/%m/%d,%H:%M:%S')
            message = tokens[6]
            self.handle_message(timestamp, source, message)
        elif tokens[0].startswith('+CUSD:'):
            ps.sendNotification(
                Notification(sender=self.name,
                             message=tokens[1],
                             level=EventLevel.INFO))

        return True
예제 #9
0
파일: signal.py 프로젝트: jakezp/pai-1
    def handle_message(self, timestamp, source, groupID, message, attachments):
        """ Handle Signal message. It should be a command """

        logger.debug("Received Message {} {} {} {} {}".format(
            timestamp, message, groupID, message, attachments))

        if source in cfg.SIGNAL_CONTACTS:
            future = asyncio.run_coroutine_threadsafe(
                self.handle_command(message), self.alarm.work_loop)
            ret = future.result(10)

            m = "Signal {} : {}".format(source, ret)
            logger.info(m)
        else:
            m = "Signal {} (UNK): {}".format(source, message)
            logger.warning(m)

        self.send_message(m, EventLevel.INFO)
        ps.sendNotification(
            Notification(sender=self.name, message=m, level=EventLevel.INFO))
예제 #10
0
    def handle_message(self, timestamp: str, source: str,
                       message: str) -> None:
        """ Handle GSM message. It should be a command """

        logger.debug("Received: {} {} {}".format(timestamp, source, message))

        if source in cfg.GSM_CONTACTS:
            future = asyncio.run_coroutine_threadsafe(
                self.handle_command(message), self.alarm.work_loop)
            ret = future.result(10)

            m = "GSM {}: {}".format(source, ret)
            logger.info(m)
        else:
            m = "GSM {} (UNK): {}".format(source, message)
            logger.warning(m)

        self.send_message(m, EventLevel.INFO)
        ps.sendNotification(
            Notification(sender=self.name, message=m, level=EventLevel.INFO))
예제 #11
0
파일: basic.py 프로젝트: torretahacs/pai
    async def _mqtt_handle_partition_control(self, prep: ParsedMessage):
        topics, element, command = prep

        if cfg.MQTT_CHALLENGE_SECRET is not None:
            command, user = self._validate_command_with_challenge(command)
            if command is None:
                return
        else:
            command, user = _extract_command_user(command)

        command = cfg.MQTT_COMMAND_ALIAS.get(command, command)

        if command.startswith("code_toggle-"):
            tokens = command.split("-")
            if len(tokens) < 2:
                logger.warning("Invalid token length {}".format(len(tokens)))
                return

            if tokens[1] not in cfg.MQTT_TOGGLE_CODES:
                logger.warning("Invalid toggle code {}".format(tokens[1]))
                return

            if element.lower() == "all":
                command = "arm"

                for k, v in self.partitions.items():
                    # If "all" and a single partition is armed, default is
                    # to disarm
                    for k1, v1 in self.partitions[k].items():
                        if (k1 == "arm" or k1 == "exit_delay"
                                or k1 == "entry_delay") and v1:
                            command = "disarm"
                            break

                    if command == "disarm":
                        break

            elif element in self.partitions:
                if ("arm" in self.partitions[element]
                        and self.partitions[element]["arm"]) or (
                            "exit_delay" in self.partitions[element]
                            and self.partitions[element]["exit_delay"]):
                    command = "disarm"
                else:
                    command = "arm"
            else:
                logger.warning("Element {} not found".format(element))
                return

            ps.sendNotification(
                Notification(
                    sender="mqtt",
                    message="Command by {}: {}".format(
                        cfg.MQTT_TOGGLE_CODES[tokens[1]], command),
                    level=EventLevel.INFO,
                ))

        message = "Partition command: {}={} user: {}".format(
            element, command, user)
        logger.info(message)
        self._publish_command_status(message)

        if not await self.alarm.control_partition(element, command):
            message = "Partition command refused: {}={} user: {}".format(
                element, command, user)
            logger.warning(message)
        else:
            message = "Partition command accepted: {}={} user: {}".format(
                element, command, user)

        self._publish_command_status(message)