def on_message(mosq, userdata, msg): """ Message received from the broker """ topic = msg.topic payload = str(msg.payload) logging.debug("Message received on %s: %s" % (topic, payload)) hosts = None title = "Notification" # Try to find matching settings for this topic for sub in conf['topichost'].keys(): if paho.topic_matches_sub(sub, topic): hosts = conf['topichost'][sub] break for sub in conf['topictitle'].keys(): if paho.topic_matches_sub(sub, topic): title = conf['topictitle'][sub] break for host in hosts: logging.debug("Sending XBMC notification to %s [%s]..." % (host, title)) xbmchost = conf['xbmchost'][host] notify_xbmc(xbmchost, title, payload)
def mqtt_on_message(self, client, userdata, msg): srv_type = None if mqtt.topic_matches_sub(str(self.service_answer_topic), msg.topic): srv_type = "answer" else: for service_sub in self.service_routing: if mqtt.topic_matches_sub(service_sub, msg.topic): srv_type = self.service_routing[service_sub].typ break if not srv_type: self.logger.error("no registered service for msg topic %s", msg.topic) return if srv_type == 'channel': self.service_routing[service_sub].queue.put(msg) elif srv_type in ['server', 'answer']: tp = Topic(msg.topic) assert tp.client_id == self.my_clientid pkt = json.loads(msg.payload.decode('utf-8')) pkt['_topic'] = msg.topic self.logger.debug("mqtt_on_message %s %s", msg.topic, str(pkt)[:70]+"...") if srv_type is 'answer': self.receive_answer(pkt, int(tp.task_id)) elif srv_type is 'server': self.dispatch_service(tp.service, pkt)
def __on_message( self, client, userdata, message ): """Executed when an mqtt arrives """ text = message.payload.decode( "utf-8" ) print( 'Received message "{}"'.format( text ) ) if( mqtt.topic_matches_sub( self.mqttParams.subscribeTopic, message.topic ) ): if( text.find( AlarmCommand.ARM_HOME.name ) > -1 ): self.__arm( Status( StatusMain.ARMED_HOME ) ) elif( text.find( AlarmCommand.ARM_AWAY.name ) > -1 ): self.__arm( Status( StatusMain.ARMED_AWAY ) ) elif( text.find( AlarmCommand.DISARM.name ) > -1 ): self.__disarm( text ) else: print( 'Unknown command: [{0}]'.format( text ) ) else: # check for trigger when alarm in one of specific statuses if( self.status.main in [ StatusMain.ARMED_AWAY, StatusMain.ARMED_HOME ] ): triggers = [] if( StatusMain.ARMED_AWAY == self.armStatus ): triggers = self.armedAway.triggers elif( StatusMain.ARMED_HOME == self.armStatus ): triggers = self.armedHome.triggers for t in triggers: for o in t.topics: if( mqtt.topic_matches_sub( o, message.topic ) and re.search( t.regex, text ) is not None ): self.__logTrigger( message ) self.__trigger( message, t.notify ) elif( self.status.main in [ StatusMain.ACTIVATED, StatusMain.TRIGGERED ] ): #when already activated or triggered just log the trigger event self.__logTrigger( message )
def on_message(self, client, userdata, msg): topic_segments = msg.topic.split("/") if (mqtt.topic_matches_sub(self.status_topic, msg.topic)): item_name = topic_segments[self.status_item_index] self.status_callback(item_name, msg.payload.decode('utf-8')) elif (mqtt.topic_matches_sub(self.command_topic, msg.topic)): item_name = topic_segments[self.command_item_index] self.command_callback(item_name, msg.payload.decode('utf-8'))
def _deal_msg(): topic = msg.topic _log.info("msg topic: %s, payload:%s" % (topic, msg.payload)) try: if mqtt.topic_matches_sub(self.REPLY_TOPIC_MODEL, topic): self.handle_reply_msg(msg) elif mqtt.topic_matches_sub(self.REQUEST_TOPIC_MODEL,topic): self.handle_request_msg(msg) else: _log.warning("handle_unkwon_msg") self.handle_unkwon_msg(msg) except Exception as e: _log.error("on_mqtt_msg error: %s" % str(traceback.format_exc())) raise e
def on_message(self,client, userdata, message): self.logger.warning("Warning: Uncaptured message topic received: \n\t*Topic '%s'\n\t*Message:'%s'"%(message.topic,message.payload.strip())) self.logger.warning("\tIf this happens, make sure to bind the message to a function if subscribed to it.") # client.topic_matches_sub("cv/+","cv/a") if topic_matches_sub(self._subscribed_topics["receiver_response_targeted"] , message.topic): self.logger.info("on_message TODO sloppy fallback. Captured direct response from %s", message.topic.split('/')[-1])
def __on_message(self, client, userdata, message): """Executed when an mqtt arrives cmd format: "email": { "from": "sender", "to": "recipient", "subject": "the subject", "body": "the body" } "im": { "recipients": [ "jabber id of each recipient e.g. [email protected]" ], "message": "the message" } "phonecall": [ phonenumber1, phonenumber2, ..., phonenumberN ] #currently not supported "sms": { "text": "the message", "phones": [ phonenumber1, phonenumber2, ..., phonenumberN ] } """ text = message.payload.decode("utf-8") print('Received message "{}"'.format(text).encode('utf-8')) if (mqtt.topic_matches_sub(self.mqttParams.subscribeTopic, message.topic)): try: cmds = json.loads(text) except ValueError, e: print('"{}" is not a valid json text, exiting.'.format(text)) return # try: if ('email' in cmds and cmds['email'] is not None): #note: Email.To param must be a list of recipients (even if it contains only one element ) # self.email( Email( cmds[ 'email' ][ 'From' ], cmds[ 'email' ][ 'To' ], cmds[ 'email' ][ 'subject' ], cmds[ 'email' ][ 'body' ] ) ) pass if ('im' in cmds and cmds['im'] is not None): # wiCmds[ 'im' ] = InstantMessage( cmds[ 'im' ][ 'recipients' ], cmds[ 'im' ][ 'message' ] ) # wiCmds[ 'im ' ] = jsonpickle.decode( json.dumps( cmds[ 'im' ] ) ) iMessage = jsonpickle.decode(json.dumps(cmds['im'])) print('Will send im to:{}, message:{}'.format( iMessage.recipients, iMessage.message.encode('utf-8'))) self.im(iMessage)
def on_message(self, state, event): topic = event.cargo[MQTT_EVENT_TOPIC] if topic_matches_sub(self.job_pending_response, topic): payload = json.loads(event.cargo[MQTT_EVENT_PAYLOAD]) in_progress_job_executions = filter_upparat_job_exectutions( payload["jobs"].get(JOBS_IN_PROGRESS, [])) queued_job_executions = filter_upparat_job_exectutions( payload["jobs"].get(JOBS_QUEUED, [])) # If there are jobs available go to job selection state if in_progress_job_executions or queued_job_executions: logger.debug("Job executions available.") self.publish( Event( JOBS_AVAILABLE, **{ JOB_EXECUTION_SUMMARIES: { JOB_EXECUTION_SUMMARIES_PROGRESS: in_progress_job_executions, JOB_EXECUTION_SUMMARIES_QUEUED: queued_job_executions, } }))
def on_message(self, state, event): topic = event.cargo[MQTT_EVENT_TOPIC] payload = json.loads(event.cargo[MQTT_EVENT_PAYLOAD]) # Handle accepted pending jobs executions if topic_matches_sub(self.get_pending_job_executions_response, topic): in_progress_job_executions = filter_upparat_job_exectutions( payload.get(IN_PROGRESS_JOBS, [])) queued_job_executions = filter_upparat_job_exectutions( payload.get(QUEUED_JOBS, [])) # If there are jobs available go to prepare state if in_progress_job_executions or queued_job_executions: logger.debug("Job executions available.") self.publish( Event( JOBS_AVAILABLE, **{ JOB_EXECUTION_SUMMARIES: { JOB_EXECUTION_SUMMARIES_PROGRESS: in_progress_job_executions, JOB_EXECUTION_SUMMARIES_QUEUED: queued_job_executions, } })) else: logger.debug("No pending job executions available.") return self.publish(Event(NO_JOBS_PENDING))
def on_stream_message_cb (self, client, obj, msg): """ This callback function will be used for Thrift streaming messages and won't be encoded in JSON Format but the thrift wire format. The read method corresponding to this data structure needs to be used to decode the data @param client: the client instance for this callback @param obj: the private user data as set in Client() or userdata_set() @param msg: an instance of Message. This is a class with members topic, payload, qos, retain """ payload = msg.payload topic = msg.topic callback_called = False for cbs in self.handlers: if cbs != '#': if mqtt.topic_matches_sub(cbs, topic): for cb in self.handlers.get(cbs, []): cb(payload) callback_called = True if callback_called == False: for cb in self.handlers.get('#', []): logger.debug('Sending data to callback %s' % cb) cb(payload)
def __on_message(self, client, obj, msg): """ A message has been received from a server :param client: Client that received the message :param obj: *Unused* :param msg: A Message bean """ try: # Get the topic topic = msg.topic # Get all listeners matching this topic all_listeners = set() for subscription, listeners in self._topics.items(): if paho.topic_matches_sub(subscription, topic): all_listeners.update(listeners) # Notify them using the pool self._pool.enqueue(self.__notify_listeners, all_listeners, topic, msg.payload, msg.qos) except KeyError: # No listener for this topic pass
def _on_message_cb(client, obj, msg): """ This method will invoke the specified callback handler by the client app when a notification is received by the app based on the notification type. :param client: the client instance for this callback :param obj: the private user data as set in Client() or userdata_set() :param msg: an instance of Message. This is a class with members topic, payload, qos, retain """ payload = msg.payload topic = msg.topic json_data = None decoder = json.JSONDecoder() json_data, end = decoder.raw_decode(payload) if json_data is None: logger.error('Received event has invalid JSON format') logger.error('Received payload: %s' % payload) if len(payload) != end: logger.error('Received event has additional invalid JSON format') logger.error('It has the following additional content: %s' % payload[end:]) callback_called = False for cbs in handlers: if cbs != '#': if mqtt.topic_matches_sub(cbs, topic): for cb in handlers.get(cbs, []): cb(json_data) callback_called = True if callback_called is False: for cb in handlers.get('#', []): logger.debug('Sending data to callback %s' % cb) cb(json_data)
def _mqtt_on_message(self, client, userdata, message): logging.debug('mqtt_on_message %s %s', message.topic, message.payload) payload = message.payload.decode('utf-8') try: payload = json.loads(payload, use_decimal=True) except Exception as e: raise logging.error(e) if self.on_message: self.on_message(self, message.topic, payload) if self._response_topic and topic_matches_sub(self._response_topic, message.topic): response = {"payload": payload, "topic": message.topic} if self._response_list: if not self._response: self._response = [] self._response.append(response) else: self._response = response self._response_condition = 0
def on_message_cb(client, obj, msg): global handlers payload = msg.payload topic = msg.topic json_data = None json_data, end = decoder.raw_decode(payload) if json_data is None: logger.error('Received event has invalid JSON format') logger.error('Received payload: %s' % payload) if len(payload) != end: logger.error('Received event has additional invalid JSON format') logger.error('It has the following additional content: %s' % payload[end:]) callback_called = False for cbs in handlers: if cbs != '#': if mqtt.topic_matches_sub(cbs, topic): for cb in handlers.get(cbs, []): cb(json_data) callback_called = True if callback_called == False: for cb in handlers.get('#', []): logger.debug('Sending data to callback %s' % cb) cb(json_data)
def on_message(mosq, userdata, msg): """ Message received from the broker """ topic = msg.topic payload = str(msg.payload) logging.debug("Message received on %s: %s" % (topic, payload)) if msg.retain == 1: if cf.skipretained: logging.debug("Skipping retained message on %s" % topic) return # Try to find matching settings for this topic for section in get_sections(): # Get the topic for this section (usually the section name but optionally overridden) match_topic = get_topic(section) if paho.topic_matches_sub(match_topic, topic): logging.debug("Section [%s] matches message on %s. Processing..." % (section, topic)) # Check for any message filters if is_filtered(section, topic, payload): logging.debug("Filter in section [%s] has skipped message on %s" % (section, topic)) continue targetlist = cf.getlist(section, 'targets') if type(targetlist) != list: logging.error("Target definition in section [%s] is incorrect" % section) cleanup(0) return for t in targetlist: logging.debug("Message on %s going to %s" % (topic, t)) # Each target is either "service" or "service:target" # If no target specified then notify ALL targets service = t target = None # Check if this is for a specific target if t.find(':') != -1: try: service, target = t.split(':', 2) except: logging.warn("Invalid target %s - should be 'service:target'" % (t)) continue if not service in service_plugins: logging.error("Invalid configuration: topic %s points to non-existing service %s" % (topic, service)) return sendtos = None if target is None: sendtos = get_service_targets(service) else: sendtos = [target] for sendto in sendtos: job = Job(1, service, section, topic, payload, sendto) q_in.put(job) return
def on_message(mosq, userdata, msg): """ Message received from the broker """ topic = msg.topic payload = str(msg.payload) logging.debug("Message received on %s: %s" % (topic, payload)) if msg.retain == 1: if cf.skipretained: logging.debug("Skipping retained message on %s" % topic) return # Try to find matching settings for this topic for section in get_sections(): # Get the topic for this section (usually the section name but optionally overridden) match_topic = get_topic(section) if paho.topic_matches_sub(match_topic, topic): logging.debug("Section [%s] matches message on %s. Processing..." % (section, topic)) # Check for any message filters if is_filtered(section, topic, payload): logging.debug("Filter in section [%s] has skipped message on %s" % (section, topic)) continue # Send the message to any targets specified send_to_targets(section, topic, payload)
def _on_message(client, userdata, msg): print(msg.topic + ' ' + str(msg.payload)) for subscriber in _subscribers: if paho_client.topic_matches_sub(sub=subscriber['topic'], topic=msg.topic): subscriber['handler'](msg.payload)
def on_message(mosq, userdata, msg): """ Message received from the broker """ topic = msg.topic payload = str(msg.payload) logging.debug("Message received on %s: %s" % (topic, payload)) username = conf['mailusername'] password = conf['mailpassword'] recipients = conf['recipient'] subject = None # Try to find matching settings for this topic for sub in conf['topicsubject'].keys(): if paho.topic_matches_sub(sub, topic): subject = conf['topicsubject'][sub] break if subject is None: return for recipient in recipients: logging.debug("Sending email to %s [%s]..." % (recipient, subject)) send_mail(username, password, [recipient], subject, payload)
def get_subscriptions(self, topic): """ Find the subscriptions that match the given topic :param topic: Topic to check :return: list of found subscriptions """ return [self.subscriptions[t] for t in self.subscriptions if mqtt.topic_matches_sub(t, topic)]
def on_message(mosq, userdata, msg): """ Message received from the broker """ topic = msg.topic payload = msg.payload logger.debug("Message received on %s: %s" % (topic, payload)) if msg.retain == 1: if cf.skipretained: logger.debug("Skipping retained message on %s" % topic) return # Try to find matching settings for this topic for section in context.get_sections(): # Get the topic for this section (usually the section name but optionally overridden) match_topic = context.get_topic(section) if paho.topic_matches_sub(match_topic, topic): logger.debug("Section [%s] matches message on %s. Processing..." % (section, topic)) # Check for any message filters if context.is_filtered(section, topic, payload): logger.debug("Filter in section [%s] has skipped message on %s" % (section, topic)) continue # Send the message to any targets specified send_to_targets(section, topic, payload)
def __on_message(self, client, obj, msg): # pylint: disable=W0613 """ A message has been received from a server :param client: Client that received the message :param obj: *Unused* :param msg: A Message bean """ try: # Get the topic topic = msg.topic # Get all listeners matching this topic all_listeners = set() for subscription, listeners in self._topics.items(): if paho.topic_matches_sub(subscription, topic): all_listeners.update(listeners) # Notify them using the pool self._pool.enqueue( self.__notify_listeners, all_listeners, topic, msg.payload, msg.qos, ) except KeyError: # No listener for this topic pass
def _get_vehicle_type(self, topic: str): # Make sure we only ingest desired event and vehicle types for event, vehicle in itertools.product(self.event_types, self.vehicle_types): if mqtt.topic_matches_sub( f"/hfp/v2/journey/ongoing/{event}/{vehicle}/#", topic): return vehicle
def on_subscription(self, state, event): topic = event.cargo[MQTT_EVENT_TOPIC] # Get pending job executions once subscribed to accepted_job_executions_topic if topic_matches_sub(self.get_pending_job_executions_response, topic): self.mqtt_client.publish(get_pending_job_executions( settings.broker.thing_name), qos=1)
def on_message(mosq, userdata, msg): sock = userdata['sock'] host = userdata['carbon_server'] port = userdata['carbon_port'] lines = [] now = int(time.time()) map = userdata['map'] # Find out how to handle the topic in this message: slurp through # our map for t in map: if paho.topic_matches_sub(t, msg.topic): # print "%s matches MAP(%s) => %s" % (msg.topic, t, map[t]) # Must we rename the received msg topic into a different # name for Carbon? In any case, replace MQTT slashes (/) # by Carbon periods (.) (type, remap) = map[t] if remap is None: carbonkey = msg.topic.replace('/', '.') else: carbonkey = remap.replace('/', '.') logging.debug("CARBONKEY is [%s]" % carbonkey) if type == 'n': '''Number: obtain a float from the payload''' try: number = float(msg.payload) #lines.append("%s %f %d" % (carbonkey, number, now)) lines.append("%s %f" % (carbonkey, number)) except ValueError: logging.info("Topic %s contains non-numeric payload [%s]" % (msg.topic, msg.payload)) return elif type == 'j': '''JSON: try and load the JSON string from payload and use subkeys to pass to Carbon''' try: st = json.loads(msg.payload) for k in st: if is_number(st[k]): #lines.append("%s.%s %f %d" % (carbonkey, k, float(st[k]), now)) lines.append("%s.%s %f" % (carbonkey, k, float(st[k]))) except: logging.info("Topic %s contains non-JSON payload [%s]" % (msg.topic, msg.payload)) return else: logging.info("Unknown mapping key [%s]", type) return message = '\n'.join(lines) + '\n' logging.debug("%s", message) sock.sendto(message, (host, port))
def _on_message(client, userdata, message): callbacks_to_run = [] for sub in _topic_callbacks.keys(): if topic_matches_sub(sub, message.topic): callbacks_to_run += _topic_callbacks[sub] for callback in callbacks_to_run: threading.Thread(target=callback, args=(message.topic, message.payload)).start()
def _matched_server(self, req_topic): regs = self._reg_servers matched = [] for topic, data in regs.items(): if Mqtt.topic_matches_sub(data[2], req_topic): matched.append(data) return matched
def _match_subscriber(self, sub_topic): subs = self._reg_subscribes matched = [] for topic, data in subs.items(): if Mqtt.topic_matches_sub(topic, sub_topic): matched.append(data) return matched
def on_message(self, client, userdata, msg): # Find correct rule from RuleList # Pass message JSON Payload to Rule for action # Loop through RuleList and find if message topic applies for aRule in self.RuleList: if mqtt.topic_matches_sub(aRule.getTopic(), msg.topic): aRule.message_in(msg=msg)
def on_message(client, userdata, msg): try: # find the sensor matching the topic for sensor_id in self.sensors: sensor = self.sensors[sensor_id] if mqtt.topic_matches_sub(sensor["topic"], msg.topic): self.log_debug("received " + str(msg.payload) + " for " + sensor_id + " on topic " + str(msg.topic)) # if JSON payload is expected if "key" in sensor: try: data = json.loads(msg.payload) if sensor["key"] not in data: return # apply the filter if any if "filter" in sensor: search = {} if "&" in sensor["filter"]: key_values = sensor["filter"].split( "&") else: key_values = [sensor["filter"]] for key_value in key_values: if "=" not in key_value: continue key, value = key_value.split("=") search[key] = value # check if the output matches the search string found = True for key, value in search.iteritems(): # check every key/value pair if key not in data: found = False if key in data and str(value).lower( ) != str(data[key]).lower(): found = False # not matching, skip to the next sensor if not found: continue value = data[sensor["key"]] except Exception, e: self.log_warning( "Unable to parse JSON payload " + str(msg.payload) + ": " + exception.get(e)) return # else consider the entire payload else: value = msg.payload # prepare the message message = Message(self) message.recipient = "controller/hub" message.command = "IN" message.args = sensor_id message.set("value", value) # send the measure to the controller self.send(message) except Exception, e: self.log_warning("runtime error during on_message(): " + exception.get(e)) return
def get_messagefilter(topic): ''' Find the message filter from the topic ''' filter = None if 'filtermap' in conf: for key in conf['filtermap'].keys(): if paho.topic_matches_sub(key, topic): filter = conf['filtermap'][key] break return filter
def topic_matches(cls, subscription_filter, topic): """ Checks if the given topic matches the given subscription filter :param subscription_filter: A MQTT subscription filter :param topic: A topic :return: True if the topic matches the filter """ return paho.topic_matches_sub(subscription_filter, topic)
def get_messagefmt(topic): ''' Find the message format from the topic ''' fmt = None if 'formatmap' in conf: for key in conf['formatmap'].keys(): if paho.topic_matches_sub(key, topic): fmt = conf['formatmap'][key] break return fmt
def on_message(mosq, userdata, msg): sock = userdata['sock'] lines = [] now = int(time.time()) map = userdata['map'] # Find out how to handle the topic in this message: slurp through # our map for t in map: if paho.topic_matches_sub(t, msg.topic): # print "%s matches MAP(%s) => %s" % (msg.topic, t, map[t]) # Must we rename the received msg topic into a different # name for Carbon? In any case, replace MQTT slashes (/) # by Carbon periods (.) (type, remap) = map[t] if remap is None: carbonkey = msg.topic.replace('/', '.') else: if '#' in remap: remap = remap.replace('#', msg.topic.replace('/', '.')) carbonkey = remap.replace('/', '.') logging.debug("CARBONKEY is [%s]" % carbonkey) if type == 'n': '''Number: obtain a float from the payload''' try: number = float(msg.payload) lines.append("%s %f %d" % (carbonkey, number, now)) except ValueError: logging.info("Topic %s contains non-numeric payload [%s]" % (msg.topic, msg.payload)) return elif type == 'j': '''JSON: try and load the JSON string from payload and use subkeys to pass to Carbon''' try: st = json.loads(msg.payload) for k in st: if is_number(st[k]): lines.append("%s.%s %f %d" % (carbonkey, k, float(st[k]), now)) except: logging.info("Topic %s contains non-JSON payload [%s]" % (msg.topic, msg.payload)) return else: logging.info("Unknown mapping key [%s]", type) return message = '\n'.join(lines) + '\n' logging.debug("%s", message) sock.sendto(message, (CARBON_SERVER, CARBON_PORT))
def get_priority(topic): ''' Find the "priority" (for pushover) from the topic. ''' priority = None if 'prioritymap' in conf: for key in conf['prioritymap'].keys(): if paho.topic_matches_sub(key, topic): priority = conf['prioritymap'][key] break return priority
def on_message(self, client, userdata, msg): try: self.mu.acquire() for k in self.callbacks: if mqtt.topic_matches_sub(k, msg.topic): self.callbacks[k](msg) except: traceback.print_exc() finally: self.mu.release()
def on_message(client, userdata, msg): userdata.idMap_lock.acquire() try: for key in userdata.idMap.keys(): if(mqtt.topic_matches_sub(key, str(msg.topic))): # check for wildcard matching ino_id = userdata.idMap[key] userdata.msgQ.put(str(ino_id) + " " + str(msg.payload)) # protocol-style convention needed except BaseException as e: # ignore clean session = false: msg from pre-subscribed topics pass userdata.idMap_lock.release()
def get_title(topic): ''' Find the "title" (for pushover) or "subject" (for smtp) from the topic. ''' title = None if 'titlemap' in conf: for key in conf['titlemap'].keys(): if paho.topic_matches_sub(key, topic): title = conf['titlemap'][key] break return title
def get_subscriptions(self, topic): """ Find the subscriptions that match the given topic :param topic: Topic to check :return: list of found subscriptions """ return [ self.subscriptions[t] for t in self.subscriptions if mqtt.topic_matches_sub(t, topic) ]
def _on_mqtt_message(self, client, userdata, msg): if not client == self._mqtt: return from paho.mqtt.client import topic_matches_sub for subscription in self._mqtt_subscriptions: topic, callback, args, kwargs = subscription if topic_matches_sub(topic, msg.topic): args = [msg.topic, msg.payload] + args kwargs.update(dict(retained=msg.retain, qos=msg.qos)) callback(*args, **kwargs)
def _callTriggers(self, topic, data): for t in self.triggers: #print("testing topic: %s %s" % (t[0], topic) ) if mqtt.topic_matches_sub(t[0], topic): #print "Trigger matches: %s %s" % (t[0] , t[1] ) if (t[2]): # wants json #print("decoding json") #pprint(data) data = self._decodeJSON(str(data)) #pprint(data) t[1](topic, data)
def process_data(self, topic, value): for subscription, key in self.key_mapping.items(): if topic_matches_sub(subscription, topic): send_to_zabbix([Metric(MQTT_AGENT_HOST_NAME, key, value)], ZABBIX_SERVER_HOST, ZABBIX_SERVER_PORT ) return True logging.error("No such subscription: {}".format(topic)) return False
def on_mqtt_message(self, client, obj, message): if message.retain: return self.logger.info( "topic %s, payload: %s" % (message.topic, "[binary]" if len(message.payload) > 10 else message.payload)) for sensor in self.sensors: if topic_matches_sub(sensor.topic, message.topic): return sensor.process(message.topic, message.payload) pass
def on_message(mosq, userdata, msg): """ Message received from the broker """ topic = msg.topic payload = str(msg.payload) logging.debug("Message received on %s: %s" % (topic, payload)) # Try to find matching settings for this topic for sub in conf['topics']: if paho.topic_matches_sub(sub, topic): tweet(payload[0:138]) break
def _on_message(self, mqttc, userdata, msg): """ 接收消息处理 :param mqttc: :param userdata: :param msg: :return: """ #logger.info("MQTTCallback::on_message, mqttc:%s, userdata:%s, topic:%s, payload:%s" % (self, userdata, msg.topic, msg.payload)) [handle_fun(self, userdata=userdata, topic=msg.topic, payload=msg.payload) for sub, handle_fun in self.topic_to_fun_dic.items() if topic_matches_sub(sub, msg.topic)] return True
def get_topic_data(topic): ''' Find out if there is a function in topicdatamap{} for adding topic into data. If there is, invoke that and return a dict of it ''' data = None if 'topicdatamap' in conf: for key in conf['topicdatamap'].keys(): if paho.topic_matches_sub(key, topic): func = conf['topicdatamap'][key] if hasattr(func, '__call__'): try: data = func(topic) except Exception, e: logging.warn("Cannot invoke func(%s): %s" % (topic, str(e))) break
def on_message(mosq, userdata, msg): # print "%s (qos=%s, r=%s) %s" % (msg.topic, str(msg.qos), msg.retain, str(msg.payload)) topic = msg.topic payload = msg.payload if paho.topic_matches_sub('ypom/+/+', topic): prefix, toidentifier, fromidentifier = topic.split('/', 3) try: u_from = userlist[fromidentifier] u_to = userlist[toidentifier] tst, msg = u_from.decrypt(msg.payload) msg = msg.decode('utf-8') print u'%s: %s [%s]' % (u_from.identifier, msg, tst) except: raise print "SOMETHING WRONG"
def mqtt_on_message(self, mqttc, obj, msg): if mqtt.topic_matches_sub("basement/mist/confirm/#", msg.topic): self.onmsg_pi(msg) elif mqtt.topic_matches_sub("basement/mist/errors/#", msg.topic): self.onmsg_error(msg)
payload = str(msg.payload) logging.debug("Message received on %s: %s" % (topic, payload)) # Check for any message filters filter = get_messagefilter(topic) if hasattr(filter, '__call__'): try: if filter(topic, payload): logging.debug("Message on %s has been filtered. Skipping." % (topic)) return except Exception, e: logging.warn("Cannot invoke filter(%s): %s" % (topic, str(e))) # Try to find matching settings for this topic for key in conf['topicmap'].keys(): if paho.topic_matches_sub(key, topic): targetlist = conf['topicmap'][key] logging.debug("Topic [%s] going to %s" % (topic, targetlist)) for t in targetlist: # Each target is either "service" or "service:target" # If no target specified then notify ALL targets service = t target = None # Check if this is for a specific target if t.find(':') != -1: try: service, target = t.split(':', 2) except: logging.warn("Invalid target %s - should be 'service:target'" % (t))
def on_message(self,mosq, userdata, msg): sock = self.sock host = self.carbon_server port = self.carbon_port lines = [] now = int(time.time()) # Find out how to handle the topic in this message: slurp through # our map for t in self.map: if paho.topic_matches_sub(t, msg.topic): # print "%s matches MAP(%s) => %s" % (msg.topic, t, self.map[t]) # Must we rename the received msg topic into a different # name for Carbon? In any case, replace MQTT slashes (/) # by Carbon periods (.) (type, remap) = self.map[t] if remap is None: carbonkey = msg.topic.replace('/', '.').replace(',','_') else: carbonkey = remap.replace('/', '.') logging.debug("CARBONKEY is [%s]" % carbonkey) if type == 'n': '''Number: obtain a float from the payload''' try: number = float(msg.payload) lines.append("%s %f %d" % (carbonkey, number, now)) except ValueError: logging.info("Topic %s contains non-numeric payload [%s]" % (msg.topic, msg.payload)) return elif type == 'j': '''JSON: try and load the JSON string from payload and use subkeys to pass to Carbon''' try: st = json.loads(msg.payload) # get timestamp fron json or set it to now # todo : optional seconds and milliseconds try: ts=time.strptime(st.pop("t",time.strftime("%Y-%m-%dT%H:%M:%S",time.gmtime(now))),"%Y-%m-%dT%H:%M:%S") timestamp=int(time.mktime(ts)) except: #timestamp=now raise for k in st: if is_number(st[k]): lines.append("%s.%s %f %d" % (carbonkey, k, float(st[k]), timestamp)) except: logging.info("Topic %s contains non-JSON payload [%s]" % (msg.topic, msg.payload)) return else: logging.info("Unknown mapping key [%s]", type) return message = '\n'.join(lines) + '\n' logging.debug("%s", message) self.sock.sendto(message, (host, port))
# Get list of topics from ACL table and compare. Caveat: %c escapes are # not supported here and will thus not match. track_authorized = False message = "Not authorized" status = 403 try: query = (Acl.select(Acl). where( (Acl.username == username) )) for s in query.naive(): sub = s.topic new_sub = sub.replace('%u', username) matches = paho.topic_matches_sub(sub, topic) log.debug("sub %s (%s) => %s" % (sub, new_sub, matches)) if matches: track_authorized = True status = 200 break except Exception, e: log.error("Can't query ACL: %s" % (str(e))) if nrecs is None or int(nrecs) < 1: nrecs = 50 if nrecs > 600: nrecs = 600
def on_message(mosq, userdata, msg): sock = userdata['sock'] host = userdata['carbon_host'] port = userdata['carbon_port'] now = int(time.time()) tuples = ([]) map = userdata['map'] # Find out how to handle the topic in this message: slurp through # our map for t in map: if paho.topic_matches_sub(t, msg.topic): # print "%s matches MAP(%s) => %s" % (msg.topic, t, map[t]) # Must we rename the received msg topic into a different # name for Carbon? In any case, replace MQTT slashes (/) # by Carbon periods (.) (type, remap) = map[t] if remap is None: carbonkey = msg.topic.replace('/', '.') else: carbonkey = remap.replace('/', '.') logging.debug("CARBONKEY is [%s]" % carbonkey) if type == 'n': '''Number: obtain a float from the payload''' try: number = float(msg.payload) tuples.append((carbonkey, (now,number))) except ValueError: logging.info("Topic %s contains non-numeric payload [%s]" % (msg.topic, msg.payload)) return elif type == 'j': '''JSON: try and load the JSON string from payload and use subkeys to pass to Carbon''' try: st = json.loads(msg.payload) for k in st: if is_number(st[k]): tuples.append(("%s.%s" % (carbonkey, k), (now,float(st[k])))) except: logging.info("Topic %s contains non-JSON payload [%s]" % (msg.topic, msg.payload)) return else: logging.info("Unknown mapping key [%s]", type) return # prepare data package = pickle.dumps(tuples, 1) size = struct.pack('!L', len(package)) logging.debug("%s", str(tuples)) # send to carbon pickle try: sent = sock.sendall(size) except: sent = 0 if sent == 0: logging.error("Error sending data to carbon server via TCP") try: sent = sock.sendall(package) except: sent = 0 if sent == 0: logging.error("Error sending data to carbon server via TCP")
else: sublist.append('#') # Find distinct topic, tid combinations in Locations table and # let Paho check if subscription matches topiclist = [] tidlist = [] query = (Location.select(Location.tid, Location.topic) .distinct() .order_by(Location.tid) ) for q in query: for sub in sublist: if paho.topic_matches_sub(sub, q.topic): tidlist.append(q.tid) topiclist.append(q.topic) log.debug("User {0} gets tidlist={1}".format(username, ",".join(tidlist))) return sorted(set(tidlist)) def getinventorytopics(username): ''' username is probably a logged-in user. Obtain a list of TIDs that user is allowed to see ''' # First, get a list of ACL topics the user is authorized for. If the # `username' is a superuser, add '#' to the subscription list, so # that paho matches that as true in any case. (Superusers possibly # don't have ACL entries in the database.)
def on_message(client, userdata, msg): userdata.idMap_lock.acquire() try: for key in userdata.idMap.keys(): if mqtt.topic_matches_sub(key.topic, str(msg.topic)): # check for wildcard matching idMap_entry = userdata.idMap[key] if idMap_entry.get_is_ThingShadow(): # A ThingShadow-related new message # find out the clientToken JSON_dict = json.loads(str(msg.payload)) my_clientToken = JSON_dict.get(u'clientToken') msg_Version = JSON_dict.get(u'version') # could be None # look up this clientToken in req_Map to check timeout userdata.req_Map_lock.acquire() # NO timeout if my_clientToken in userdata.req_Map and my_clientToken == key.clientToken: my_Type = userdata.req_Map[my_clientToken].getType() my_ThingName = userdata.req_Map[my_clientToken].getThingName() del userdata.req_Map[my_clientToken] # now check ref_cnt_Map_get/update to see if necessary to unsub need2unsub = False # check version, see if this is a message containing version regarding thisThingName if msg_Version is not None and userdata.thisThingNameVersionControl.thisThingName == my_ThingName: if msg_Version > userdata.thisThingNameVersionControl.currLocalVersion: userdata.thisThingNameVersionControl.currLocalVersion = msg_Version # new message, update thisThingName version topic_accept = "$aws/things/" + my_ThingName + "/shadow/" + my_Type + "/accepted" topic_reject = "$aws/things/" + my_ThingName + "/shadow/" + my_Type + "/rejected" if my_Type == "get": new_ref_CNT = userdata.ref_cnt_Map_get[my_ThingName] - 1 if new_ref_CNT == 0: # need to unsub need2unsub = True else: userdata.ref_cnt_Map_get[my_ThingName] = new_ref_CNT elif my_Type == "update": new_ref_CNT = userdata.ref_cnt_Map_update[my_ThingName] - 1 if new_ref_CNT == 0: # need to unsub need2unsub = True else: userdata.ref_cnt_Map_update[my_ThingName] = new_ref_CNT elif my_Type == "delete": # should reset version number if it is an accepted DELETE msg_topic_str = str(msg.topic) msg_pieces = msg_topic_str.split('/') if msg_pieces[5] == "accepted": # if it is an accepted DELETE userdata.thisThingNameVersionControl.currLocalVersion = 0 # reset local version number new_ref_CNT = userdata.ref_cnt_Map_delete[my_ThingName] - 1 if new_ref_CNT == 0: # need to unsub need2unsub = True else: userdata.ref_cnt_Map_delete[my_ThingName] = new_ref_CNT else: # broken Type pass # by this time, we already have idMap_lock if need2unsub: userdata._iot_mqtt_client_handler.unsubscribe(topic_accept) new_key = idMap_key(topic_accept, my_clientToken) if userdata.idMap.get(new_key) is not None: del userdata.idMap[new_key] userdata._iot_mqtt_client_handler.unsubscribe(topic_reject) new_key = idMap_key(topic_reject, my_clientToken) if userdata.idMap.get(new_key) is not None: del userdata.idMap[new_key] # add the feedback to msgQ ino_id = idMap_entry.get_ino_id() userdata.msgQ.put(str(ino_id) + " " + str(msg.payload)) # protocol-style convention needed # timeout, ignore this message else: pass userdata.req_Map_lock.release() elif idMap_entry.get_is_delta(): # a delta message, need to check version userdata.req_Map_lock.acquire() JSON_dict = json.loads(str(msg.payload)) msg_Version = JSON_dict.get(u'version') # see if the version from the message is newer/bigger regarding thisThingName # parse out to see what thing name of this delta message is... msg_topic_str = str(msg.topic) msg_pieces = msg_topic_str.split('/') msg_ThingName = msg_pieces[2] # now we have thingName... if msg_Version is not None and msg_ThingName == userdata.thisThingNameVersionControl.thisThingName: if msg_Version <= userdata.thisThingNameVersionControl.currLocalVersion: pass # ignore delta message with old version number else: # now add this delta message to msgQ # update local version userdata.thisThingNameVersionControl.currLocalVersion = msg_Version ino_id = idMap_entry.get_ino_id() userdata.msgQ.put(str(ino_id) + " " + str(msg.payload)) userdata.req_Map_lock.release() else: # A normal new message ino_id = idMap_entry.get_ino_id() userdata.msgQ.put(str(ino_id) + " " + str(msg.payload)) # protocol-style convention needed except BaseException: # ignore clean session = false: msg from pre-subscribed topics pass userdata.idMap_lock.release()
def send_to_targets(section, topic, payload): if cf.has_section(section) == False: logging.warn("Section [%s] does not exist in your INI file, skipping message on %s" % (section, topic)) return dispatcher_dict = cf.getdict(section, 'targets') if type(dispatcher_dict) == dict: def get_key(item): # precede a key with the number of topic levels and then use reverse alphabetic sort order # '+' is after '#' in ascii table # caveat: for instance space is allowed in topic name but will be less specific than '+', '#' # so replace '#' with first ascii character and '+' with second ascii character # http://public.dhe.ibm.com/software/dw/webservices/ws-mqtt/mqtt-v3r1.html#appendix-a # item[0] represents topic. replace wildcard characters to ensure the right order modified_topic = item[0].replace('#', chr(0x01)).replace('+', chr(0x02)) levels = len(item[0].split('/')) # concatenate levels with leading zeros and modified topic and return as a key return "{:03d}{}".format(levels, modified_topic) # produce a sorted list of topic/targets with longest and more specific first sorted_dispatcher = sorted(dispatcher_dict.items(), key=get_key, reverse=True) for match_topic, targets in sorted_dispatcher: if paho.topic_matches_sub(match_topic, topic): # hocus pocus, let targets become a list targetlist = targets if type(targets) == list else [targets] logging.debug("Most specific match %s dispatched to %s" % (match_topic, targets)) # first most specific topic matches then stops processing break else: # Not found then no action. This could be configured intentionally. logging.debug("Dispatcher definition does not contain matching topic/target pair in section [%s]" % section) return else: targetlist = cf.getlist(section, 'targets') if type(targetlist) != list: # if targets is neither dict nor list logging.error("Target definition in section [%s] is incorrect" % section) cleanup(0) return for t in targetlist: logging.debug("---------------- %s ------------------" % (t)) logging.debug("Message on %s going to %s" % (topic, t)) # Each target is either "service" or "service:target" # If no target specified then notify ALL targets service = t target = None # Check if this is for a specific target if t.find(':') != -1: try: service, target = t.split(':', 2) except: logging.warn("Invalid target %s - should be 'service:target'" % (t)) continue if not service in service_plugins: logging.error("Invalid configuration: topic %s points to non-existing service %s" % (topic, service)) return sendtos = None if target is None: sendtos = get_service_targets(service) else: sendtos = [target] for sendto in sendtos: job = Job(1, service, section, topic, payload, sendto) q_in.put(job)
def test_not_matching(self, sub, topic): assert not client.topic_matches_sub(sub, topic)