def main(): global args, write_api parser = ArgumentParser(description=__doc__) parser.add_argument("--host", default='localhost', help='hostname of mqtt broker') parser.add_argument( "-t", action='append', default=['velogen/raw'], help='MQTT topic to subscribe to. Can be put multiple times.') parser.add_argument("-d", action='store_true', help='enable debug output') parser.add_argument("--user", default=None, help="username") parser.add_argument("--pw", default=None, help="password") args = parser.parse_args() client = Client() client.on_connect = on_connect client.on_disconnect = on_disconnect client.on_message = on_message if args.user is not None and args.pw is not None: client.username_pw_set(args.user, args.pw) client.connect(args.host) # For influxdb2 only db = InfluxDBClient(url='http://localhost:8086', token=token, debug=args.d) write_api = db.write_api(write_options=SYNCHRONOUS) while True: client.loop(timeout=1.0)
def main(): global args parser = ArgumentParser(description=__doc__) parser.add_argument( "--host", default='localhost', help='hostname of mqtt broker' ) parser.add_argument( "--topic", default='velogen/raw', help='comma separated list of MQTT topics to subscribe to' ) args = parser.parse_args() c = Client() c.on_connect = on_connect c.on_disconnect = on_disconnect c.on_message = on_message c.connect(args.host) atexit.register(commit) while True: ts = datetime.now().timestamp() for tp, rts in rx_ts_dict.items(): if rts is not None: # dump to file after 30 s of silence if ts - rts > 30: clean_write(tp) rx_ts_dict[tp] = None c.loop(1.0)
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 run(mqtt_client: paho.Client) -> None: """ Reads any messages from the queue and publishing them to the MQTT broker. """ # Keep batches small, only send the latest X messages. The rest will be trimmed (in case of delay). message_queue = queue.Message.objects.all().order_by( '-pk')[0:settings.DSMRREADER_MQTT_MAX_MESSAGES_IN_QUEUE] if not message_queue: return logger.debug('MQTT: Processing %d message(s)', len(message_queue)) for current in message_queue: logger.debug('MQTT: Publishing queued message (#%s) for %s: %s', current.pk, current.topic, current.payload) message_info = mqtt_client.publish( topic=current.topic, payload=current.payload, qos=settings.DSMRREADER_MQTT_QOS_LEVEL, retain=True) loop_result = mqtt_client.loop(0.1) # Detect any networking errors early. if loop_result != paho.MQTT_ERR_SUCCESS: signal_reconnect() raise RuntimeError( 'MQTT: Client loop() failed, requesting restart...') # Always True when using QoS 0 (as designed). For QoS 1 and 2 however, this BLOCKS further processing and # message deletion below, until the broker acknowledges the message was received. # Networking errors should terminate this loop as well, along with a request for restart. while not message_info.is_published(): logger.debug( 'MQTT: Waiting for message (#%s) to be marked published by broker', current.pk) loop_result = mqtt_client.loop(0.5) # Prevents infinite loop on connection errors. if loop_result != paho.MQTT_ERR_SUCCESS: signal_reconnect() raise RuntimeError( 'MQTT: Client loop() failed, requesting restart to prevent waiting forever...' ) logger.debug('MQTT: Deleting published message (#%s) from queue', current.pk) current.delete() # Delete any overflow in messages. queue.Message.objects.all().delete()
def run_client(settings): def on_connect(*args, **kwargs): print("connected") def on_message(*args, **kwargs): print("message received", args, kwargs) client = MQTTClient() client.on_connect = on_connect client.on_message = on_message client.connect(server, settings["mqtt_settings"]["port"], 60) t0 = time.time() while True: time.sleep(1) client.loop() td = time.time() - t0 f = lambda x: np.log(x / 10) * 10 + 50 data = '{"meat_temp": %.1f, "oven_temp": %.1f}' % (f(td), f(td + 100)) print("publishing data") client.publish("test_topic", data)
def test_run_success(self, load_subscribed_topics_mock, isdir_mock): # mock function call to load subscribed topics load_subscribed_topics_mock.return_value = MagicMock() input = [0, 0, 1] isdir_mock.return_value = True loop_mock = MagicMock() loop_mock.side_effect = input client_mock = Client(MagicMock()) client_mock.connect = MagicMock() client_mock.loop = loop_mock mqtt_client = MQTT(client_mock) mqtt_client.run() self.assertEqual(client_mock.connect.call_count, 1) self.assertEqual(client_mock.loop.call_count, len(input))
class HotWord(object): def __init__(self): self.received_lamp_state = None self.color_database = json.load(open('color.json')) self.client = Client(client_id='google_home') self.client.on_connect = self.on_connect self.client.connect('localhost', port=1883, keepalive=60) self._wait_for_lamp_state() self.client.loop_start() def _receive_lamp_state(self, client, userdata, message): print(message.payload) self.received_lamp_state = json.loads(message.payload.decode("utf-8")) def on_connect(self, client, userdata, flags, rc): client.message_callback_add('/lamp/changed', self._receive_lamp_state) client.subscribe('/lamp/changed', qos=1) def _wait_for_lamp_state(self): for i in range(10): if self.received_lamp_state: return self.client.loop(0.05) raise Exception("Timeout waiting for lamp state") def process_device_actions(self, event, device_id): if 'inputs' in event.args: for i in event.args['inputs']: if i['intent'] == 'action.devices.EXECUTE': for c in i['payload']['commands']: for device in c['devices']: if device['id'] == device_id: if 'execution' in c: for e in c['execution']: if 'params' in e: yield e['command'], e['params'] else: yield e['command'], None def process_event(self, event, device_id): """Pretty prints events. Prints all events that occur with two spaces between each new conversation and a single space between turns of a conversation. Args: event(event.Event): The current event to process. device_id(str): The device ID of the new instance. """ if event.type == EventType.ON_CONVERSATION_TURN_STARTED: print() print(event) if (event.type == EventType.ON_CONVERSATION_TURN_FINISHED and event.args and not event.args['with_follow_on_turn']): print() if event.type == EventType.ON_DEVICE_ACTION: for command, params in self.process_device_actions( event, device_id): print('Do command', command, 'with params', str(params)) if command == "action.devices.commands.OnOff": if params['on']: self.received_lamp_state['client'] = 'google_home' self.received_lamp_state['on'] = True print('Turning the LED on.') else: self.received_lamp_state['client'] = 'google_home' self.received_lamp_state['on'] = False print('Turning the LED off.') self.client.publish('/lamp/set_config', json.dumps(self.received_lamp_state), qos=1) if command == "action.devices.commands.ColorAbsolute": if params['color']: print("hello it is me color") color = params['color'].get('name') hue = self.color_database[color]['hue'] saturation = self.color_database[color]['saturation'] self.received_lamp_state['color']['h'] = round(hue, 2) self.received_lamp_state['color']['s'] = round( saturation, 2) self.received_lamp_state['client'] = 'google_home' self.client.publish('/lamp/set_config', json.dumps( self.received_lamp_state), qos=1) if command == "action.devices.commands.BrightnessAbsolute": if params['brightness']: print("hello") brightness = (params['brightness']) / 100 print(brightness) self.received_lamp_state['brightness'] = brightness self.received_lamp_state['client'] = 'google_home' self.client.publish('/lamp/set_config', json.dumps( self.received_lamp_state), qos=1) sleep(0.1) self.client.loop_stop() def register_device(self, project_id, credentials, device_model_id, device_id): """Register the device if needed. Registers a new assistant device if an instance with the given id does not already exists for this model. Args: project_id(str): The project ID used to register device instance. credentials(google.oauth2.credentials.Credentials): The Google OAuth2 credentials of the user to associate the device instance with. device_model_id(str): The registered device model ID. device_id(str): The device ID of the new instance. """ base_url = '/'.join( [DEVICE_API_URL, 'projects', project_id, 'devices']) device_url = '/'.join([base_url, device_id]) session = google.auth.transport.requests.AuthorizedSession(credentials) r = session.get(device_url) print(device_url, r.status_code) if r.status_code == 404: print('Registering....') r = session.post(base_url, data=json.dumps({ 'id': device_id, 'model_id': device_model_id, 'client_type': 'SDK_LIBRARY' })) if r.status_code != 200: raise Exception('failed to register device: ' + r.text) print('\rDevice registered.') def main(self): parser = argparse.ArgumentParser( formatter_class=argparse.RawTextHelpFormatter) parser.add_argument('--credentials', type=existing_file, metavar='OAUTH2_CREDENTIALS_FILE', default=os.path.join( os.path.expanduser('~/.config'), 'google-oauthlib-tool', 'credentials.json'), help='Path to store and read OAuth2 credentials') parser.add_argument('--device_model_id', type=str, metavar='DEVICE_MODEL_ID', required=True, help='The device model ID registered with Google') parser.add_argument( '--project_id', type=str, metavar='PROJECT_ID', required=False, help='The project ID used to register device instances.') parser.add_argument('-v', '--version', action='version', version='%(prog)s ' + Assistant.__version_str__()) args = parser.parse_args() with open(args.credentials, 'r') as f: credentials = google.oauth2.credentials.Credentials(token=None, **json.load(f)) with Assistant(credentials, args.device_model_id) as assistant: events = assistant.start() print('device_model_id:', args.device_model_id + '\n' + 'device_id:', assistant.device_id + '\n') if args.project_id: register_device(args.project_id, credentials, args.device_model_id, assistant.device_id) for event in events: self.process_event(event, assistant.device_id)
class MQTTClient: """ mqtt客户端的父类 """ def __init__(self, host, port, client_id=None, clean_session=False, keepalive=60): self.client = Client() if client_id: self.client._client_id = client_id self.client._clean_session = False self.host = host self.port = port self.keepalive = keepalive self.connected = False self.client.on_connect = self._on_connect self.client.on_message = self._on_message self.client.on_log = self._on_log def connect(self, user='******', password='******'): rc = 1 if self.connected: return 0 self.client.username_pw_set(user, password) try: rc = self.client.connect(self.host, self.port, self.keepalive) assert rc == 0, ConnectionRefusedError self.connected = True except ConnectionRefusedError: log.error('Retry after 1 second.') return rc def disconnect(self): self.connected = False self.client.disconnect() def loop(self, timeout=None): if timeout: self.client.loop(timeout=timeout) else: self.client.loop_forever() def loop_start(self): return self.client.loop_start() def publish(self, topic, data={}, qos=1): (rc, final_mid) = self.client.publish(topic, json.dumps(data), qos=qos) return rc, final_mid def _on_connect(self, client, userdata, flags, rc): pass def _on_message(self, client, userdata, msg): pass def _on_log(self, client, userdata, level, buf): return buf
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
import time from paho.mqtt.client import Client def on_message(c, userdata, mesg): print "message: %s %s %s" % (userdata, mesg.topic, mesg.payload) client = Client(client_id="my_id", userdata="user1") client.connect("172.27.246.86") client.on_message = on_message client.subscribe("temp_value") while True: client.loop() time.sleep(1)
def IniciarVerificacaoDeAtualizacao(client: mqtt.Client): while True: client.loop() time.sleep(1)
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 Mqtt(Abstract): def __init__(self, service_info=None): self.connected = False self.client = None self.queue = Queue() super().__init__(service_info) def start(self): self.connect() self.receive_msgs() def stop(self): self.stop_receiving_msgs() self.disconnect() def add_stream(self, stream): self.streams[stream.name] = stream def remove_stream(self, name): if name in self.streams.keys(): self.streams.pop(name) def remove_all_streams(self): self.streams = {} def is_connected(self): if self.client and self.connected: return True return False def connect(self): if not self.client: host = self.service_info['host'] port = self.service_info['port'] self.client = Client() self.client.on_message = self.on_mqtt_msg self.client.on_connect = self.on_connect self.client.on_disconnect = self.on_disconnect self.client.connect(host, port, 60) def on_connect(self, client, userdata, flags, rc): self.connected = True def disconnect(self): if self.client: self.client.disconnect() def on_disconnect(self, client, userdata, rc): self.client = None self.connected = False def send_msg(self, msg, tx_info=None): if self.client: topic = None if tx_info: topic = tx_info['topic'] elif self.service_info: topic = self.service_info['publish']['default_topic'] if self.client and topic: self.client.publish(topic, msg) else: raise MqttError('Cannot send message without a client') def receive_msgs(self): topics = self.service_info['subscribe']['topics'] if self.client: for t in topics: self.client.subscribe(t, 0) sub_type = self.service_info['subscribe']['type'] if sub_type == 'blocking': self.client.loop_forever() elif sub_type == 'unblocking': self.client.loop_start() elif sub_type == 'polled': self.client.loop(self.service_info['subscribe']['loop_time']) else: self.client.loop(.1) else: raise MqttError('Cannot receive message without a client') def stop_receiving_msgs(self): topics = self.service_info['subscribe']['topics'] if self.client: for t in topics: self.client.unsubscribe(t) self.client.loop_stop() def handle_msg(self): msg = self.queue.get() print(f'Received: {msg["topic"]}::{msg["msg"]}') data = super().handle_msg(msg) for k, s in self.streams.items(): events = [] for d in data: timestamp = d.timestamp sample = getattr(d, s.handle) events.append(Event(timestamp, sample)) s.handle_msg(events) def on_mqtt_msg(self, client, userdata, msg): payload = {} payload['topic'] = msg.topic payload['msg'] = msg.payload self.queue.put(payload) self.handle_msg()
class Mqtt(): def __init__(self, app=None): self.app = app self.client = Client() self.refresh_time = 1.0 self.topics = [] self.mqtt_thread = Thread(target=self._loop_forever) self.mqtt_thread.daemon = True if app is not None: self.init_app(app) def init_app(self, app): self.refresh_time = app.config.get('MQTT_REFRESH_TIME', 1.0) self._connect( username=app.config.get('MQTT_USERNAME'), password=app.config.get('MQTT_PASSWORD'), broker_url=app.config.get('MQTT_BROKER_URL', 'localhost'), broker_port=app.config.get('MQTT_BROKER_PORT', 1883) ) def _connect(self, username, password, broker_url, broker_port): if not self.mqtt_thread.is_alive(): if username is not None: self.client.username_pw_set(username, password) res = self.client.connect(broker_url, broker_port) if res == 0: self.mqtt_thread.start() def _disconnect(self): self.client.disconnect() def _loop_forever(self): while True: time.sleep(self.refresh_time) self.client.loop(timeout=1.0, max_packets=1) def on_topic(self, topic: str): """ Decorator to add a callback function that is called when a certain topic has been published. The callback function is expected to have the following form: `handle_topic(client, userdata, message)` :parameter topic: a string specifying the subscription topic to subscribe to **Example usage:** :: @on_topic('home/mytopic') def handle_mytopic(client, userdata, message): print('Received message on topic {}: {}' .format(message.topic, message.payload.decode())) """ def decorator(handler): self.client.message_callback_add(topic, handler) return handler return decorator def subscribe(self, topic: str, qos: int=0): """ Subscribe to a certain topic. :param topic: a string specifying the subscription topic to subscribe to. :param qos: the desired quality of service level for the subscription. Defaults to 0. A topic is a UTF-8 string, which is used by the broker to filter messages for each connected client. A topic consists of one or more topic levels. Each topic level is separated by a forward slash (topic level separator). **Topic example:** `myhome/groundfloor/livingroom/temperature` """ # TODO: add support for list of topics # don't subscribe if already subscribed if topic in self.topics: return # try to subscribe result, mid = self.client.subscribe(topic, qos) # if successful add to topics if result == MQTT_ERR_SUCCESS: self.topics.append(topic) return result def unsubscribe(self, topic: str): """ Unsubscribe from a single topic. :param topic: a single string that is the subscription topic to unsubscribe from """ # don't unsubscribe if not in topics if topic not in self.topics: return result, mid = self.client.unsubscribe(topic) # if successful remove from topics if result == MQTT_ERR_SUCCESS: self.topics.remove(topic) return result def unsubscribe_all(self): """ Unsubscribe from all topics. """ topics = self.topics[:] for topic in topics: self.unsubscribe(topic) def publish(self, topic: str, payload: bytes=None, qos: int=0, retain: bool=False) -> Tuple[int, int]: """ Send a message to the broker. :param topic: the topic that the message should be published on :param payload: the actual message to send. If not given, or set to None a zero length message will be used. Passing an int or float will result in the payload being converted to a string representing that number. If you wish to send a true int/float, use struct.pack() to create the payload you require. :param qos: the quality of service level to use :param retain: if set to True, the message will be set as the "last known good"/retained message for the topic :returns: Returns a tuple (result, mid), where result is MQTT_ERR_SUCCESS to indicate success or MQTT_ERR_NO_CONN if the client is not currently connected. mid is the message ID for the publish request. """ return self.client.publish(topic, payload, qos, retain) def on_message(self): """ Decorator to handle all messages that have been subscribed. **Example Usage:** :: @mqtt.on_message() def handle_messages(client, userdata, message): print('Received message on topic {}: {}' .format(message.topic, message.payload.decode())) """ def decorator(handler): self.client.on_message = handler return handler return decorator