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))
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))
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) )
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))
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))
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
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))
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
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))
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))
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)