def test_mqtt_telemetry(): # Create receiver sub = Client(clean_session=True) # def on_message(client, userdata, message): # data = message.payload # print(message) on_message_mock = mock.Mock() sub.on_message = on_message_mock sub.connect(cfg.TELEMETRY_MQTT_BROKER_HOST) sub.loop_start() name = "donkey/%s/telemetry" % cfg.TELEMETRY_DONKEY_NAME sub.subscribe(name) t = MqttTelemetry(cfg, default_inputs=['angle'], default_types=['float']) t.publish() timestamp = t.report({'speed': 16, 'voltage': 12}) t.run(33.3) assert t.qsize == 2 time.sleep(1.5) t.publish() assert t.qsize == 0 time.sleep(0.5) res = str.encode( '[{"ts": %s, "values": {"speed": 16, "voltage": 12, "angle": 33.3}}]' % timestamp) assert on_message_mock.call_args_list[0][0][2].payload == res
class MqttSubscriber(BaseSubscriber): def __init__(self, *args, **kwargs): self.client = None self.message = None self.f = open("time_taken_mqtt.txt", "a+") def connect(self, host="localhost", port=5000, topic="test"): print("Connected") self.client = Client() self.client.connect(host=host) self.client.on_message = self.recv_message self.client.on_subscribe = self.on_subscribe self.client.subscribe(topic) self.client.loop_forever() def on_subscribe(self, *args, **kwargs): print("Subscribed") def recv_message(self, client, userdata, message): print(message.payload) message = json.loads(message.payload) latency = time() - message["sentAt"] msg_size = len(message["message"].encode('utf-8')) self.f.write("{} : {}\n".format(msg_size, latency)) print("Message received : {} size is {} in {}".format( message, msg_size, str(latency))) def close(self): pass
def _on_connect(self, client: mqtt.Client, userdata: Any, flags, rc): _LOGGER.debug("Connected with result code %d", rc) self._disconnected.clear() self._connected.set() client.subscribe(self._status_topic) for callback in self._callbacks: callback(MessageType.STATE)
def _on_connect(self, mqttc: mqtt.Client, user_data: Any, flags, rc): logger.debug(f"connect flags->{flags}, rc->{rc}") if rc == 0: for (key, value) in self.mq_config.source_topic.items(): mqttc.subscribe(value) elif rc == CONNECT_FAILED_NOT_AUTHORISED: self.__run_mqtt()
class MqttController: def __init__(self): self.client = Client() self.client.on_connect = self.__on_connect self.client.on_message = self.__on_message self.evtCallback: Optional[EventCallback] = None def connect(self, connectCallback, host, port=1883, keepalive=60): log.info("Trying to connect MQTT client.") self.connectCallback = connectCallback self.client.connect(host, port, keepalive) self.client.loop_start() def disconnect(self): self.client.loop_stop() self.client.disconnect() def setCallback(self, callback: EventCallback): self.evtCallback = callback def delCallback(self): self.evtCallback = None def __on_connect(self, client, userdata, flags, rc): log.info("MQTT client connected, registering subscriptions.") self.client.subscribe("/baresip/event") self.connectCallback() def __on_message(self, client, userdata, msg: MQTTMessage): log.info("MQTT message received for path=%s.", msg.topic) log.debug("payload=%s", msg.payload) # parse message try: msgObj = json.loads(msg.payload) evtType = EventType[msgObj["type"]] # notify respective callback cb = self.evtCallback if cb is not None: log.debug("Calling event callback in a thread.") t = threading.Thread(target=lambda: cb(evtType, msgObj)) t.start() else: log.debug("No callback registered.") except JSONDecodeError: log.error("Received invalid JSON message.") except KeyError: log.warn("Received unhandled type code or type code is missing.") def send_command(self, msg): log.debug("Trying to send message %s to phone.", msg) info = self.client.publish("/baresip/command/", msg) log.debug("Waiting for publish") log.debug(info.rc) info.wait_for_publish() if info.rc != MQTT_ERR_SUCCESS: log.error("Failed to publish message") else: log.debug("Message sent successfully.")
def on_connect(client: mqtt.Client, userdata: dict, _flags: dict, rc: int) -> None: """ Callback handler for MQTT connect to server """ the_queue = userdata['queue'] debug = userdata['debug'] if rc == 0: if debug: print(f'Connected to MQTT server on {MQTT_HOST}...') for this_topic in MQTT_TOPICS: client.subscribe(this_topic) if debug: print(f'Subscribed to {this_topic}') # Start the timer so we will check the message queue over and over... the_queue.start_timer() else: print(f'Error: Could not connect to {MQTT_HOST}: RC is {rc}') sys.exit(0)
def mqtt_on_connect(client: mqtt.Client, userdata: List[str], flags: dict, rc: int, props: Properties = None) -> None: """ MQTT Callback for when client receives connection-acknowledgement response from MQTT server. :param client: Class instance of connection to server :param userdata: User-defined data passed to callbacks :param flags: Response flags sent by broker :param rc: Connection result, Successful = 0 :param props: MQTTv5 properties object """ print( f"Connected with result code {rc} -> {mqtt.connack_string(rc)}, properties: {props}" ) # Subscribing in on_connect() allows us to renew subscriptions if disconnected if rc == 0 and isinstance(userdata, list): if all(isinstance(t, str) for t in userdata): client.subscribe([(t.lower(), SubscribeOptions) for t in userdata]) print( f"{client} listening on `{'`, `'.join(t.lower() for t in userdata)}`" ) return print( "Error in on_connect. Expected topic to be type a list of strings." )
class PahoClient(MQTTClientBase): def __init__(self, host: str, port: int, keepalive: int): self._client = Client() self._host = host self._port = port self._keepalive = keepalive self._on_message, self._on_connect, self._subscription_topics = None, None, [] def connect(self, subscription_topics: List[str], on_connect=None, on_message=None): self._client.on_connect = self.__connected self._client.on_message = self.__message_received self._on_message, self._on_connect, self._subscription_topics = on_message, on_connect, subscription_topics self._client.connect(self._host, self._port, self._keepalive) def __connected(self): for topic in self._subscription_topics: self._client.subscribe(topic) if self._on_connect: self._on_connect() def __message_received(self, client: Client, userdata, msg): if self._on_message: self._on_message(msg) def loop_background(self): self._client.loop_start()
def _on_connect(client: Client, userdata: Any, flags: Any, rc: int): """Set up a callback function to ensure the connection to Server was successful""" logger.info(f'Connected with result code {rc}.') # Subscribing in on_connect means that if we lose connection and reconnect # then subscriptions will be renewed client.subscribe('$SYS/#')
def on_connect(mqttc: mqtt.Client, inlfuxc, flags, rc): logging.info(f"MQTT connection established ({rc})") # subscribe to match signal cbor messages topic_matched_cbor = "jonas-rpi-00001/radiotracking/matched/cbor" mqttc.subscribe(topic_matched_cbor) mqttc.message_callback_add(topic_matched_cbor, on_matched_cbor) logging.info(f"Subscribed to {topic_matched_cbor}")
class MQTTSnipsComponent(SnipsComponent): """A Snips component using the MQTT protocol directly. Attributes: snips (:class:`.SnipsConfig`): The Snips configuration. mqtt (`paho.mqtt.client.Client`_): The MQTT client object. .. _`paho.mqtt.client.Client`: https://www.eclipse.org/paho/clients/python/docs/#client """ def _connect(self): """Connect with the MQTT broker referenced in the Snips configuration file. """ self.mqtt = Client() self.mqtt.on_connect = self._subscribe_topics connect(self.mqtt, self.snips.mqtt) def _start(self): """Start the event loop to the MQTT broker so the component starts listening to MQTT topics and the callback methods are called. """ self.mqtt.loop_forever() def _subscribe_topics(self, client, userdata, flags, connection_result): """Subscribe to the MQTT topics we're interested in. Each method with an attribute set by a :func:`snipskit.decorators.mqtt.topic` decorator is registered as a callback for the corresponding topic. """ for name in dir(self): callable_name = getattr(self, name) if hasattr(callable_name, 'topic'): self.mqtt.subscribe(getattr(callable_name, 'topic')) self.mqtt.message_callback_add(getattr(callable_name, 'topic'), callable_name) def publish(self, topic, payload, json_encode=True): """Publish a payload on an MQTT topic on the MQTT broker of this object. Args: topic (str): The MQTT topic to publish the payload on. payload (str): The payload to publish. json_encode (bool, optional): Whether or not the payload is a dict that will be encoded as a JSON string. The default value is True. Set this to False if you want to publish a binary payload as-is. Returns: :class:`paho.mqtt.MQTTMessageInfo`: Information about the publication of the message. .. versionadded:: 0.5.0 """ if json_encode: payload = json.dumps(payload) return self.mqtt.publish(topic, payload)
class MQTTClient(object): """Manages Paho MQTT client lifecycle and callbacks""" def __init__(self, config: dict, message_processor=None): self.config = config self.client = Client( client_id=config.mqtt_client, clean_session=config.mqtt_clean_session, userdata={"client": config.mqtt_client}, ) self.client.username_pw_set(config.mqtt_username, config.mqtt_password) if self.config.mqtt_debug: self.client.on_log = self._on_log self.client.on_connect = self._on_connect self.client.on_subscribe = self._on_subscribe self.client.on_message = self._on_message self.client.on_publish = self._on_publish self.client.on_disconnect = self._on_disconnect self.client.connect(config.mqtt_host, config.mqtt_port, 60) if message_processor: self.message_processor = message_processor def _on_log(self, client, userdata, level, buf): click.echo(f"{buf}, origin: {userdata['client']}") def _on_connect(self, client, userdata, flags, rc): click.echo(f"Connected {userdata['client']}, result code: {str(rc)} {str(flags)}") click.echo(f"Subscribing to all topics...") self.client.subscribe(self.config.mqtt_topics) def _on_subscribe(self, client, userdata, mid, granted_qos): click.echo(f"Subscribed {userdata['client']}, mid: {mid}, granted qos: {granted_qos}") click.echo(f"Listening for {userdata['client']} messages...") def _on_disconnect(self, client, userdata, rc): click.echo(f"Disconnected {userdata['client']}, result code: {str(rc)}") def _on_message(self, client, userdata, msg): if hasattr(self, "message_processor"): self.message_processor(client, userdata, msg) else: click.echo(f"Topic: {msg.topic}, Mid: {msg.mid}, Payload: {msg.payload.decode('utf-8')}") def _on_publish(self, client, userdata, mid): click.echo(f"Published by {userdata['client']}, mid: {mid}") def listen(self): try: self.client.loop_forever() except KeyboardInterrupt: click.echo(f"Received KeyboardInterrupt, disconnecting {self.config.mqtt_client}") self.client.disconnect()
def mqtt_on_connect(client: mqtt.Client, userdata, flags, rc): logging.debug('Connected to MQTT at %s:%d', _parsed_args.mqtt_host, _parsed_args.mqtt_port) mqtt_publish_discovery() mqtt_publish_lwt_online() client.subscribe(_mqtt_topics['sub']) logging.debug('Completed registration to MQTT')
def mqtt_on_connect(self, client: mqtt.Client, userdata, flags, rc): for device in self._devices: client.subscribe([ (self._mqtt_topics['sub'].format(device.mac_address, data_field.name), 0) for data_field in fields(device.get_all_properties()) ]) # Subscribe to subscription updates. client.subscribe('$SYS/broker/log/M/subscribe/#')
def _on_connect(client: mqtt.Client, userdata: Any, flags, rc): _LOGGER.debug("Connected with result code %d", rc) nonlocal error if rc == mqtt.CONNACK_REFUSED_BAD_USERNAME_PASSWORD: error = DysonInvalidCredential elif rc != mqtt.CONNACK_ACCEPTED: error = DysonConnectionRefused else: client.subscribe(self._status_topic) self._connected.set()
def _on_connect(client: mqtt.Client, userdata: Any, flags, rc): _LOGGER.debug("Connected with result code %d", rc) nonlocal error if rc == 4: error = DysonInvalidCredential elif rc != 0: error = DysonConnectionRefused else: client.subscribe(self._status_topic) self._connected.set()
def on_connect(client: mqtt_client.Client, userdata, flags, rc): if rc == 0: client.subscribe("+/devices/+/up", qos=2) elif rc == 3: # Server isn't available, retry later print("Server isn't available") else: # Error in config print("Error in config") client.disconnect()
def run(self): LOG.critical("Starting") mqtt_channels = { e.name: e for e in self.get_channels_by_application("MQTTSubscriber") } LOG.critical("mqtt_channels: {}".format(dir(mqtt_channels))) for channel_name, channel in mqtt_channels.items(): LOG.critical("CHANNEL NAME: {}".format(channel_name)) LOG.critical("CHANNEL: {}".format(dir(channel))) ip_address = channel.protocol_config.app_specific_config[ 'ip_address'] port = channel.protocol_config.app_specific_config['port'] if ip_address not in self.mqtt_clients: client = MQTTClient() self.mqtt_clients[ip_address] = client if not hasattr(client, 'channels'): setattr(client, 'channels', {}) self.mqtt_clients[ip_address].channels[ channel.protocol_config.app_specific_config['topic']] = channel def on_message(client, userdata, msg): """ Default on_message function for tunable logging. """ LOG.debug( "userdata: {} dup: {} info: {} mid: {} payload: {} qos: {} retain: {} state: {} timestamp: {} topic: {}" .format(userdata, msg.dup, msg.info, msg.mid, msg.payload, msg.qos, msg.retain, msg.state, msg.timestamp, msg.topic)) for ch in client.channels: if topic_matches_sub(ch, msg.topic): LOG.critical("{}->{} got {}".format( client, client.channels[ch].name, msg.payload)) client.channels[ch].put_sample(msg.payload) self.mqtt_clients[ip_address].on_message = on_message self.mqtt_clients[ip_address].connect(ip_address, port) for client in self.mqtt_clients.values(): client.loop_start() for channel in client.channels: client.subscribe(channel) while not self.is_stopped(): time.sleep(0.25) for client in self.mqtt_clients.values(): client.loop_stop() LOG.critical("{} HAS BEEN STOPPED.".format(self.name))
class mqtt_Sub(Task): def on_connect(self, client, userdata, flags, rc): print('on connect rc', rc) def on_connect1(self, client, userdata, flags, rc): print('on connect rc', rc) def on_message(self, client, userdata, msg): device = eval(str(msg.payload)[2:-1]) print(device) sub = SubDevice.objects.create( subdevice_name=device["create_params"][0]["subdevice_name"], subdevice_type=device["create_params"][0]["subdevice_type"], subdevice_position=device["create_params"][0] ["subdevice_position"], subdevice_model=device["create_params"][0]["subdevice_model"], subdevice_remark=device["create_params"][0]["subdevice_remark"]) sub.save() def on_publish(self, client, userdata, mid): print('on publish mid', mid) def on_subscrib(self, client, userdata, mid, qos): print('on subscribe mid', mid) def on_disconnect(self, client, userdata, rc): print("disconnect reconnect later!") def cnct(self): print("连接MQTT...") # 5、整理得到的結果提取 username,password,port,host # try: username = "******" password = "******" port = 1883 host = "10.129.7.199" self.mqttClient = Client(client_id="F1334790") self.mqttClient.on_connect = self.on_connect self.mqttClient.on_message = self.on_message self.mqttClient.on_publish = self.on_publish self.mqttClient.on_subscribe = self.on_subscrib self.mqttClient.on_disconnect = self.on_disconnect self.mqttClient.username_pw_set(username=username, password=password) self.mqttClient.connect(port=port, host=host, keepalive=90) self.mqttClient.loop_start() print("MQTT连接OK ----") # except Exception as e: # print("MQTT连接异常:", e) # time.sleep(3) def get_data(self): self.cnct() self.mqttClient.subscribe(topic="/data/EdgeBox/gateway/create", qos=1)
def run_mqtt_listener(): mqtt_broker_url = '167.86.108.163' MQTT_HOST = os.getenv('MQTT_HOST', mqtt_broker_url) client_name = 'mqtt-csw-importer' topic = 'update_csw' print("Sono partito") print("->167.86.108.163") print("->mqtt-csw-importer") def _on_connect(client, userdata, flags, rc): print("Connesso con successo al topic", topic) def _on_log(client, userdata, level, buf): # print("log", level, buf) pass def _on_message(client, userdata, message): message = str(message.payload.decode("utf-8")) payload = json.loads(message)['rndt_xml'] print('received event', payload) print( '----ENDED------------------------------------------------------') cmd = 'pycsw-admin.py -c load_records -f /etc/pycsw/pycsw.cfg -p /home/pycsw/datatemp' filename = "/home/pycsw/datatemp/temp1.xml" try: with open(filename, 'w') as file: file.write(payload) execute(cmd) # execute('rm -f ' + filename) except Exception as e: print('Exception', e) try: client = Client(client_id='{}_{}'.format(client_name, random.randint(1, 10000)), clean_session=True) print('Connecting to MQTT broker at ') client.connect(MQTT_HOST) except ConnectionRefusedError as e: print('Connection refused by MQTT broker at ') raise ConnectionRefusedError client.on_connect = _on_connect client.on_message = _on_message client.on_log = _on_log client.subscribe(topic) client.loop_forever() # client.loop_start() print('loop started')
def on_connect(self, client: mqtt.Client, userdata: Any, flags: int, rc: int) -> None: client.subscribe(Topic.SESSION_STARTED) client.subscribe(Topic.TEXT_CAPTURED) client.subscribe(Topic.INTENT_PARSED) client.subscribe(Topic.INTENT_NOT_RECOGNIZED) client.subscribe(Topic.TTS_SAY) client.subscribe(Topic.SESSION_ENDED) self.update_state(RhasspyState.connected)
def _on_connect(self, client: Client, user_data, flags, reason_code, properties=None): logger.info(f"Connected with reason code {reason_code}") sub_topic = f"{self.sub_topic_root}/#" logger.info(f"Subscribing to: {sub_topic}") client.subscribe(sub_topic) client.will_set(f"label_servers/status/{self.host_name}", json.dumps({"online": False}))
def on_connect(mqttc: mqtt.Client, inlfuxc, flags, rc): schedule.run_pending() logging.info(f"MQTT connection established ({rc})") # subscribe to signal cbor messages topic_signal_cbor = "+/radiotracking/device/+/cbor" mqttc.subscribe(topic_signal_cbor) mqttc.message_callback_add(topic_signal_cbor, on_signal_cbor) logging.info(f"Subscribed to {topic_signal_cbor}") # subscribe to match signal cbor messages topic_matched_cbor = "+/radiotracking/matched/cbor" mqttc.subscribe(topic_matched_cbor) mqttc.message_callback_add(topic_matched_cbor, on_matched_cbor) logging.info(f"Subscribed to {topic_matched_cbor}") # subscribe to log csv messages topic_log_csv = "+/radiotracking/log/csv" mqttc.subscribe(topic_log_csv) mqttc.message_callback_add(topic_log_csv, on_log_csv) logging.info(f"Subscribed to {topic_log_csv}") # subscribe to util messages topic_mqtt_util = "+/mqttutil/#" mqttc.subscribe(topic_mqtt_util) mqttc.message_callback_add(topic_mqtt_util, on_mqtt_util) logging.info(f"Subscribed to {topic_mqtt_util}")
class MqttClientConnector(): _host = None _port = None _brokerAddr = None _mqttClient = None #Allow user to use this constructor to pass custom callBack methods def __init__(self, host, port, on_connect, on_message, on_publish, on_subscribe): self._brokerAddr = host + ":" + str(port) self._host = host self._port = port self._mqttClient = Client() self._mqttClient.on_connect = on_connect self._mqttClient.on_message = on_message self._mqttClient.on_publish = on_publish self._mqttClient.on_subscribe = on_subscribe def connect(self): try: print("Connecting to broker:" + self._brokerAddr + ".....") self._mqttClient.connect(self._host, self._port, 60) self._mqttClient.loop_start() except Exception as e: print("Cloud not connect to broker " + self._brokerAddr + " " + str(e)) def disconnect(self): self._mqttClient.disconnect() self._mqttClient.loop_stop() def publishMessage(self, topic, message, qos): print("Publishing message:" + message + " to broker: " + self._brokerAddr + " Topic:" + topic) self._mqttClient.publish(topic, message, qos) def subscribeTopic(self, topic, qos): print("Subscribing to topic:" + topic + ".....") self._mqttClient.subscribe(topic, qos)
def subscribe(self, mqttclient: MqttClient) -> None: super().subscribe(mqttclient) mqttclient.subscribe(self.stateTopic) mqttclient.subscribe(self.heatingTopic) mqttclient.subscribe(self.setpointTopic) mqttclient.subscribe(self.ackAlarmTopic) for topic in self.tempReferences: mqttclient.subscribe(topic)
def mqtt_handler(): global mqtt_client Client.connected_flag = False mqtt_client = Client() mqtt_client.on_connect = on_connect mqtt_client.on_message = on_message mqtt_client.loop_start() mqtt_client.connect(host=MQTT_ADDR, port=MQTT_PRT) while not mqtt_client.connected_flag: # wait in loop print("In wait loop") time.sleep(1) # subscribe all rooms, using MQTT single layer wildcard mqtt_client.subscribe(topic='%s/+' % ORDER_STATUS) mqtt_client.loop_forever() mqtt_client.disconnect()
def __init__(self, client: mclient.Client, topic: str, callback, logger: logging.Logger, QOS=0): super().__init__() if not callable(callback): raise AttributeError("callback muss aufrufbar sein.") self.name = "MsgThr" self.setDaemon(False) self._cancel_new_when_running = False self._sleeping = True self._callback = callback self._message_queue = queue.Queue() self._logger = logger.getChild("mmThread-{}".format(topic)) self._mutex = thr.Lock() self.start() client.subscribe(topic, qos=QOS) client.message_callback_add(topic, self.__mqtt_callback) self._kill = False
def execute(self, chat_id, args): client = Client(userdata=self.user_data) connect_result = client.connect(self.config["server"]) if not connect_result == MQTT_ERR_SUCCESS: raise Exception( "Client connection error {}".format(connect_result)) topics = self.get_topic_list() for topic in topics: (subs_result, subs_id) = client.subscribe(topic) client.on_message = self.on_message if not subs_result == MQTT_ERR_SUCCESS: raise Exception("Subscription error {}".format(subs_result)) time_start = time.time() while True: client.loop() if self.user_data["messages_received"] >= len(topics): break if time.time() - time_start > 10: break self.bot.sendMessage(chat_id, self.format_output())
def _on_connect(self, client: paho_mqtt.Client, user_data: Any, flags: Dict[str, Any], reason_code: Union[int, paho_mqtt.ReasonCodes], properties: Optional[paho_mqtt.Properties] = None) -> None: logging.info("MQTT Client Connected") if reason_code == 0: subs = [(k, v[0]) for k, v in self.subscribed_topics.items()] if subs: res, msg_id = client.subscribe(subs) if msg_id is not None: sub_fut: asyncio.Future = asyncio.Future() topics = list(self.subscribed_topics.keys()) sub_fut.add_done_callback( BrokerAckLogger(topics, "subscribe")) self.pending_acks[msg_id] = sub_fut self.connect_evt.set() else: if isinstance(reason_code, int): err_str = paho_mqtt.connack_string(reason_code) else: err_str = reason_code.getName() self.server.set_failed_component("mqtt") self.server.add_warning(f"MQTT Connection Failed: {err_str}")
def onMQTTConnected(client: Client, data, flas, rc): """Mqtt服务器连接成功回调函数 :param client: paho mqtt对象 :type client: obj :param data: 私有用户消息 :type data: obj :param flas: Broker返回的连接标志 :type flas: obj :param rc: 连接结果 :type rc: Int """ # TODO: hardcoded Topic. need make it configuable later client.subscribe("testHome/rpc", qos=2) logger.info('successfully connect to remote mqtt broker')
class Messenger(object): """ MQTT client for Herald transport. """ def __init__(self, peer): """ Initialize client :param peer: The peer behind the MQTT client. :return: """ self.__peer = peer self.__mqtt = MqttClient() self.__mqtt.on_connect = self._on_connect self.__mqtt.on_disconnect = self._on_disconnect self.__mqtt.on_message = self._on_message self.__callback_handler = None self.__WILL_TOPIC = "/".join( (TOPIC_PREFIX, peer.app_id, RIP_TOPIC)) def __make_uid_topic(self, subtopic): """ Constructs a complete UID topic. :param subtopic: The UID :return: Fully qualified topic :rtype : str """ return "/".join( (TOPIC_PREFIX, self.__peer.app_id, UID_TOPIC, subtopic)) def __make_group_topic(self, subtopic): """ Constructs a complete group topic. :param subtopic: The group name :return: Fully qualified topic :rtype : str """ return "/".join( (TOPIC_PREFIX, self.__peer.app_id, GROUP_TOPIC, subtopic)) def __handle_will(self, message): if self.__callback_handler and self.__callback_handler.on_peer_down: self.__callback_handler.on_peer_down( message.payload.decode('utf-8')) else: _log.debug("Missing callback for on_peer_down.") def _on_connect(self, *args, **kwargs): """ Handles a connection-established event. :param args: unnamed arguments :param kwargs: named arguments :return: """ _log.info("Connection established.") _log.debug("Subscribing for topic %s.", self.__make_uid_topic(self.__peer.uid)) self.__mqtt.subscribe(self.__make_uid_topic(self.__peer.uid)) self.__mqtt.subscribe(self.__make_group_topic("all")) self.__mqtt.subscribe(self.__WILL_TOPIC) for group in self.__peer.groups: _log.debug("Subscribing for topic %s.", self.__make_group_topic(group)) self.__mqtt.subscribe(self.__make_group_topic(group)) if self.__callback_handler and self.__callback_handler.on_connected: self.__callback_handler.on_connected() else: _log.warning("Missing callback for on_connect.") def _on_disconnect(self, *args, **kwargs): """ Handles a connection-lost event. :param args: unnamed arguments :param kwargs: named arguments :return: """ _log.info("Connection lost.") if self.__callback_handler and self.__callback_handler.on_disconnected: self.__callback_handler.on_disconnected() def _on_message(self, client, data, message): """ Handles an incoming message. :param client: the client instance for this callback :param data: the private user data :param message: an instance of MQTTMessage :type message: paho.mqtt.client.MQTTMessage :return: """ _log.info("Message received.") if message.topic == self.__WILL_TOPIC: self.__handle_will(message) return if self.__callback_handler and self.__callback_handler.on_message: self.__callback_handler.on_message(message.payload.decode('utf-8')) else: _log.warning("Missing callback for on_message.") def fire(self, peer_uid, message): """ Sends a message to another peer. :param peer_uid: Peer UID :param message: Message content :return: """ self.__mqtt.publish( self.__make_uid_topic(peer_uid), message, 1 ) def fire_group(self, group, message): """ Sends a message to a group of peers. :param group: Group's name :param message: Message content :return: """ self.__mqtt.publish( self.__make_group_topic(group), message, 1 ) def set_callback_listener(self, listener): """ Sets callback listener. :param listener: the listener :return: """ self.__callback_handler = listener def login(self, username, password): """ Set credentials for an MQTT broker. :param username: Username :param password: Password :return: """ self.__mqtt.username_pw_set(username, password) def connect(self, host, port): """ Connects to an MQTT broker. :param host: broker's host name :param port: broker's port number :return: """ _log.info("Connecting to MQTT broker at %s:%s ...", host, port) self.__mqtt.will_set(self.__WILL_TOPIC, self.__peer.uid, 1) self.__mqtt.connect(host, port) self.__mqtt.loop_start() def disconnect(self): """ Diconnects from an MQTT broker. :return: """ _log.info("Disconnecting from MQTT broker...") self.__mqtt.publish(self.__WILL_TOPIC, self.__peer.uid, 1) self.__mqtt.loop_stop() self.__mqtt.disconnect()
class MqttApplication(Application): """ An abstract base Application for running some type of MQTT client-based Application. """ def __init__(self, broker, hostname=None, hostport=1883, username=None, password=None, keepalive=60, **kwargs): super(MqttApplication, self).__init__(broker=broker, **kwargs) self._client = MqttClient() self._client.on_connect = \ lambda mqtt_client, obj, rc: self._on_connect(mqtt_client, obj, rc) self._client.on_disconnect = \ lambda mqtt_client, obj, rc: self._on_disconnect(mqtt_client, obj, rc) self._client.on_publish = \ lambda mqtt_client, obj, mid: self._on_publish(mqtt_client, obj, mid) self._client.on_subscribe = \ lambda mqtt_client, userdata, mid, qos: self._on_subscribe(mqtt_client, mid, qos) self._client.on_message = \ lambda mqtt_client, userdata, msg: self._on_message(mqtt_client, msg.payload, msg.topic, msg.qos, msg.retain) self._hostname = hostname self._hostport = hostport self._username = username self._password = password self._keepalive = keepalive self._is_connected = False @property def is_connected(self): return self._is_connected # Your API for pub-sub via MQTT: def mqtt_publish(self, raw_data, topic, **kwargs): """ Publishes the given data to the specified topic. :param raw_data: :type raw_data: str :param topic: :param kwargs: e.g. qos, retain; passed to self._client.publish :return: err_code, msg_id """ return self._client.publish(topic, raw_data, **kwargs) def mqtt_subscribe(self, topic, **kwargs): """ Subscribes to the specified topic. :param topic: :param kwargs: e.g. qos; passed to self._client.publish :return: err_code, msg_id """ return self._client.subscribe(topic, **kwargs) # To make use of either publish or subscribe, make sure to implement these! def _on_publish(self, mqtt_client, obj, mid): log.debug("MQTT app %s published msg %d: %s" % (self.name, mid, obj)) def _on_subscribe(self, mqtt_client, mid, qos): log.debug("MQTT app %s subscribe response msg %d: qos=%s" % (self.name, mid, qos)) def _on_message(self, mqtt_client, payload, topic, qos, retain): """Called when a message arrives on a topic we subscribed to.""" log.debug("MQTT app %s received message on topic %s: %s" % (self.name, topic, payload)) # You may want to override these functions in your concrete Application, but make sure to call super()! def _on_connect(self, mqtt_client, obj, rc): log.debug("MQTT app %s connected: %s" % (self.name, str(rc))) # need to start AFTER connecting, which is async! self._is_connected = True def _on_disconnect(self, mqtt_client, obj, rc): # sink will try reconnecting once EventReporter queries if it's available. self._is_connected = False log.debug("MQTT app %s disconnected: %s" % (self.name, str(rc))) def _try_connect(self): if self._username is not None and self._password is not None: self._client.username_pw_set(self._username, self._password) try: # NOTE: this is an async connection! self._client.connect(self._hostname, self._hostport, self._keepalive) self._client.loop_start() except socket.gaierror: return False return True def on_start(self): super(MqttApplication, self).on_start() return self._try_connect()
class PipaMQTTClient(object): def __init__(self, client_id, host, port=1883, **kwargs): self._logger = logging.getLogger("gsensors.PipaMQTTClient") self._host = host self._port = port self._mqtt_client = Client(client_id=client_id, clean_session=False) self._mqtt_client.on_connect = self.on_connect self._mqtt_client.on_disconnect = self.on_disconnect self._mqtt_client.on_message = self.on_message self.worker = None self.worker_runner = None self.topics_sources = {} self.running = False self.connected = False def publish(self, topic, payload=None, qos=0, retain=False): # check connected if not self.connected: raise RuntimeError("MQTT client not connected ! ") if not self.running: raise RuntimeError("MQTT client not running ! ") self._mqtt_client.publish(topic, payload=payload, qos=qos, retain=retain) def PublishAction(self, topic, payload=None, retain=False): if payload is None: def _action(source, value): data = "%s" % value self._logger.debug("publish %s: %s" % (topic, data)) self.publish(topic, payload=data, retain=retain) else: def _action(*args, **kwargs): self._logger.debug("publish %s: %s" % (topic, payload)) self.publish(topic, payload=payload, retain=retain) return _action def on_disconnect(self, client, userdata, rc): self._logger.error("Disconnected with result code: "+str(rc)) self.connected = False self.connect() def on_connect(self, client, userdata, flags, rc): if rc == 0: self._logger.info("Connected to MQTT broker") self.connected = True # Subscribing in on_connect() means that if we lose the connection and # reconnect then subscriptions will be renewed. #client.subscribe("$SYS/#") #client.subscribe("#") for topic in self.topics_sources.keys(): client.subscribe(topic) else: self._logger.error("Connection fail with error: %s" % rc) def on_message(self, client, userdata, msg): self._logger.debug("get a msg %s: %s" % (msg.topic, msg.payload)) if msg.topic in self.topics_sources: source = self.topics_sources[msg.topic] source.update(msg) def register_source(self, source, topic): # check that topic has no wildcard assert "#" not in topic if topic in self.topics_sources: raise ValueError("topic already monitored") self.topics_sources[topic] = source self._mqtt_client.subscribe(topic) return source def connect(self): self.worker_runner = gevent.spawn(self._connect) def _connect(self): while not self.connected: try: #self._mqtt_client.reinitialise() self._mqtt_client.connect(host=self._host, port=self._port, keepalive=60) except socket.error as err: self._logger.error("Imposible to connect to MQTT: %s" % err) self._logger.info("Will retry in 2 seconds") gevent.sleep(2) def wait_connected(self): while not self.connected: gevent.sleep(1) def start(self): if self.running: return self.running = True self.worker = gevent.spawn(self._mqtt_loop) self.connect() def _mqtt_loop(self): while self.running: self._mqtt_client.loop(timeout=0.02) gevent.sleep(0.01)
class JMSClient(object): """Class JMSClient """ _mh = None _client = None _host = None _port = None _user = None _passw = None _verbose = None _is_connected = None _messages = [] def __init__(self, verbose=False): """Class constructor Called when the object is initialized Args: verbose (bool): verbose mode """ try: self._mh = MasterHead.get_head() self._client = Client() self._client.on_message = self._on_message self._verbose = verbose if (self._verbose): self._client.on_log = self._on_log except MQTTException as ex: self._mh.demsg('htk_on_error', ex, self._mh.fromhere()) @property def client(self): """ MQTT client property getter """ return self._client @property def host(self): """ server host property getter """ return self._host @property def port(self): """ server port property getter """ return self._port @property def user(self): """ username property getter """ return self._user @property def passw(self): """ user password property getter """ return self._passw @property def verbose(self): """ verbose property getter """ return self._verbose @property def is_connected(self): """ is_connected property getter """ return self._is_connected def _on_log(self, client, obj, level, string): """ Callback for on_log event """ print(string) def _on_message(self, client, obj, msg): """ Callback for on_message event """ self._messages.append(msg.payload.decode()) def connect(self, host, port=1883, user=None, passw=None, timeout=10): """Method connects to server Args: host (str): hostname port (str): port user (str): username passw (str): password timeout (int): timeout Returns: bool: result Raises: event: jms_before_connect event: jms_after_connected """ try: msg = 'host:{0}, port:{1}, user:{2}, passw:{3}, timeout:{4}'.format( host, port, user, passw, timeout) self._mh.demsg('htk_on_debug_info', self._mh._trn.msg( 'htk_jms_connecting', msg), self._mh.fromhere()) ev = event.Event( 'jms_before_connect', host, port, user, passw, timeout) if (self._mh.fire_event(ev) > 0): host = ev.argv(0) port = ev.argv(1) user = ev.argv(2) passw = ev.argv(3) timeout = ev.argv(4) self._host = host self._port = port self._user = user self._passw = passw if (ev.will_run_default()): if (self._user != None): self._client.username_pw_set(self._user, self._passw) setdefaulttimeout(timeout) self._client.connect(self._host, self._port) self._is_connected = True self._mh.demsg('htk_on_debug_info', self._mh._trn.msg( 'htk_jms_connected'), self._mh.fromhere()) ev = event.Event('jms_after_connect') self._mh.fire_event(ev) return True except (MQTTException, error, ValueError) as ex: self._mh.demsg('htk_on_error', ex, self._mh.fromhere()) return False def disconnect(self): """Method disconnects from server Args: none Returns: bool: result """ try: self._mh.demsg('htk_on_debug_info', self._mh._trn.msg( 'htk_jms_disconnecting'), self._mh.fromhere()) if (not self._is_connected): self._mh.demsg('htk_on_warning', self._mh._trn.msg( 'htk_jms_not_connected'), self._mh.fromhere()) return False else: self._client.disconnect() self._is_connected = False self._mh.demsg('htk_on_debug_info', self._mh._trn.msg( 'htk_jms_disconnected'), self._mh.fromhere()) return True except (MQTTException, error, ValueError) as ex: self._mh.demsg('htk_on_error', ex, self._mh.fromhere()) return False def send(self, destination_name, message): """Method sends message Args: destination_name (str): topic name message (str): message Returns: bool: result Raises: event: jms_before_send event: jms_after_send """ try: msg = 'destination_name:{0}, message:{1}'.format( destination_name, message) self._mh.demsg('htk_on_debug_info', self._mh._trn.msg( 'htk_jms_sending_msg', msg), self._mh.fromhere()) if (not self._is_connected): self._mh.demsg('htk_on_warning', self._mh._trn.msg( 'htk_jms_not_connected'), self._mh.fromhere()) return False ev = event.Event('jms_before_send', destination_name, message) if (self._mh.fire_event(ev) > 0): destination_name = ev.argv(0) message = ev.argv(1) if (ev.will_run_default()): res, id = self._client.publish(destination_name, message) if (res != 0): self._mh.demsg('htk_on_error', self._mh._trn.msg( 'htk_jms_sending_error'), self._mh.fromhere()) self._mh.demsg('htk_on_debug_info', self._mh._trn.msg( 'htk_jms_msg_sent'), self._mh.fromhere()) ev = event.Event('jms_after_send') self._mh.fire_event(ev) return True except (MQTTException, error, ValueError) as ex: self._mh.demsg('htk_on_error', ex, self._mh.fromhere()) return False def receive(self, destination_name, cnt=1, timeout=10): """Method receives messages Args: destination_name (str): queue name cnt (int): count of messages timeout (int): timeout to receive message Returns: list: messages Raises: event: jms_before_receive event: jms_after_receive """ try: msg = 'destination_name:{0}, count:{1}'.format( destination_name, cnt) self._mh.demsg('htk_on_debug_info', self._mh._trn.msg( 'htk_jms_receiving_msg', msg), self._mh.fromhere()) if (not self._is_connected): self._mh.demsg('htk_on_warning', self._mh._trn.msg( 'htk_jms_not_connected'), self._mh.fromhere()) return None ev = event.Event('jms_before_receive', destination_name, cnt) if (self._mh.fire_event(ev) > 0): destination_name = ev.argv(0) cnt = ev.argv(1) if (ev.will_run_default()): res, id = self._client.subscribe(destination_name) if (res != 0): self._mh.demsg('htk_on_error', self._mh._trn.msg( 'htk_jms_sending_error'), self._mh.fromhere()) return None res = 0 cnt_before = 0 start = time() while (res == 0): res = self._client.loop() cnt_after = len(self._messages) if (cnt_after > cnt_before and cnt_after < cnt): cnt_before = cnt_after elif (cnt_after == cnt or time() > start + timeout): res = -1 messages = self._messages self._client.unsubscribe(destination_name) self._messages = [] self._mh.demsg('htk_on_debug_info', self._mh._trn.msg( 'htk_jms_msg_received', len(messages)), self._mh.fromhere()) ev = event.Event('jms_after_receive') self._mh.fire_event(ev) return messages except (MQTTException, error, ValueError) as ex: self._mh.demsg('htk_on_error', ex, self._mh.fromhere()) return None