From e040c47ecf6fbaee85c383fcf0731fd80f0792f1 Mon Sep 17 00:00:00 2001 From: brendan <2bndy5@gmail.com> Date: Sat, 18 Jul 2020 14:03:16 -0700 Subject: [PATCH 1/6] api doc's param & code-block display correctly --- adafruit_minimqtt/adafruit_minimqtt.py | 33 +++++++++++++++++++------- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/adafruit_minimqtt/adafruit_minimqtt.py b/adafruit_minimqtt/adafruit_minimqtt.py index 08953f0d..b74c1c72 100755 --- a/adafruit_minimqtt/adafruit_minimqtt.py +++ b/adafruit_minimqtt/adafruit_minimqtt.py @@ -91,9 +91,9 @@ class MMQTTException(Exception): def set_socket(sock, iface=None): """Helper to set the global socket and optionally set the global network interface. + :param sock: socket object. :param iface: internet interface object - """ global _the_sock # pylint: disable=invalid-name, global-statement _the_sock = sock @@ -105,6 +105,7 @@ def set_socket(sock, iface=None): class MQTT: """MQTT Client for CircuitPython + :param str broker: MQTT Broker URL or IP Address. :param int port: Optional port definition, defaults to 8883. :param str username: Username for broker authentication. @@ -114,7 +115,6 @@ class MQTT: :param bool is_ssl: Sets a secure or insecure connection with the broker. :param bool log: Attaches a logger to the MQTT client, defaults to logging level INFO. :param int keep_alive: KeepAlive interval between the broker and the MiniMQTT client. - """ # pylint: disable=too-many-arguments,too-many-instance-attributes, not-callable, invalid-name, no-member @@ -201,11 +201,11 @@ def deinit(self): def will_set(self, topic=None, payload=None, qos=0, retain=False): """Sets the last will and testament properties. MUST be called before connect(). + :param str topic: MQTT Broker topic. :param str payload: Last will disconnection payload. :param int qos: Quality of Service level. :param bool retain: Specifies if the payload is to be retained when it is published. - """ if self.logger is not None: self.logger.debug("Setting last will properties") @@ -225,9 +225,9 @@ def will_set(self, topic=None, payload=None, qos=0, retain=False): def add_topic_callback(self, mqtt_topic, callback_method): """Registers a callback_method for a specific MQTT topic. + :param str mqtt_topic: MQTT topic. :param str callback_method: Name of callback method. - """ if mqtt_topic is None or callback_method is None: raise ValueError("MQTT topic and callback method must both be defined.") @@ -235,8 +235,8 @@ def add_topic_callback(self, mqtt_topic, callback_method): def remove_topic_callback(self, mqtt_topic): """Removes a registered callback method. - :param str mqtt_topic: MQTT topic. + :param str mqtt_topic: MQTT topic. """ if mqtt_topic is None: raise ValueError("MQTT Topic must be defined.") @@ -271,8 +271,8 @@ def _handle_on_message(self, client, topic, message): # pylint: disable=too-many-branches, too-many-statements, too-many-locals def connect(self, clean_session=True): """Initiates connection with the MQTT Broker. - :param bool clean_session: Establishes a persistent session. + :param bool clean_session: Establishes a persistent session. """ self._sock = _the_sock.socket() self._sock.settimeout(15) @@ -411,6 +411,7 @@ def ping(self): # pylint: disable=too-many-branches, too-many-statements def publish(self, topic, msg, retain=False, qos=0): """Publishes a message to a topic provided. + :param str topic: Unique topic identifier. :param str msg: Data to send to the broker. :param int msg: Data to send to the broker. @@ -419,16 +420,19 @@ def publish(self, topic, msg, retain=False, qos=0): :param int qos: Quality of Service level for the message. Example of sending an integer, 3, to the broker on topic 'piVal'. + .. code-block:: python mqtt_client.publish('topics/piVal', 3) Example of sending a float, 3.14, to the broker on topic 'piVal'. + .. code-block:: python mqtt_client.publish('topics/piVal', 3.14) Example of sending a string, 'threepointonefour', to the broker on topic piVal. + .. code-block:: python mqtt_client.publish('topics/piVal', 'threepointonefour') @@ -509,27 +513,32 @@ def publish(self, topic, msg, retain=False, qos=0): def subscribe(self, topic, qos=0): """Subscribes to a topic on the MQTT Broker. This method can subscribe to one topics or multiple topics. + :param str topic: Unique MQTT topic identifier. :param int qos: Quality of Service level for the topic, defaults to zero. :param tuple topic: Tuple containing topic identifier strings and qos level integers. :param list topic: List of tuples containing topic identifier strings and qos. Example of subscribing a topic string. + .. code-block:: python mqtt_client.subscribe('topics/ledState') Example of subscribing to a topic and setting the qos level to 1. + .. code-block:: python mqtt_client.subscribe('topics/ledState', 1) Example of subscribing to topic string and setting qos level to 1, as a tuple. + .. code-block:: python mqtt_client.subscribe(('topics/ledState', 1)) Example of subscribing to multiple topics with different qos levels. + .. code-block:: python mqtt_client.subscribe([('topics/ledState', 1), ('topics/servoAngle', 0)]) @@ -583,15 +592,18 @@ def subscribe(self, topic, qos=0): def unsubscribe(self, topic): """Unsubscribes from a MQTT topic. + :param str topic: Unique MQTT topic identifier. :param list topic: List of tuples containing topic identifier strings. Example of unsubscribing from a topic string. + .. code-block:: python mqtt_client.unsubscribe('topics/ledState') Example of unsubscribing from multiple topics. + .. code-block:: python mqtt_client.unsubscribe([('topics/ledState'), ('topics/servoAngle')]) @@ -645,6 +657,7 @@ def unsubscribe(self, topic): def reconnect(self, resub_topics=True): """Attempts to reconnect to the MQTT broker. + :param bool resub_topics: Resubscribe to previously subscribed topics. """ if self.logger is not None: @@ -672,7 +685,6 @@ def loop_forever(self): next major release. Please see examples/minimqtt_pub_sub_blocking.py for an example of creating a blocking loop which can handle wireless network events. - """ while True: if self._sock.connected: @@ -681,7 +693,6 @@ def loop_forever(self): def loop(self): """Non-blocking message loop. Use this method to check incoming subscription messages. - """ if self._timestamp == 0: self._timestamp = time.monotonic() @@ -744,6 +755,7 @@ def _recv_len(self): def _send_str(self, string): """Packs and encodes a string to a socket. + :param str string: String to write to the socket. """ self._sock.send(struct.pack("!H", len(string))) @@ -755,6 +767,7 @@ def _send_str(self, string): @staticmethod def _check_topic(topic): """Checks if topic provided is a valid mqtt topic. + :param str topic: Topic identifier """ if topic is None: @@ -769,6 +782,7 @@ def _check_topic(topic): @staticmethod def _check_qos(qos_level): """Validates the quality of service level. + :param int qos_level: Desired QoS level. """ if isinstance(qos_level, int): @@ -803,6 +817,7 @@ def mqtt_msg(self): @mqtt_msg.setter def mqtt_msg(self, msg_size): """Sets the maximum MQTT message payload size. + :param int msg_size: Maximum MQTT payload size. """ if msg_size < MQTT_MSG_MAX_SZ: @@ -811,6 +826,7 @@ def mqtt_msg(self, msg_size): ### Logging ### def attach_logger(self, logger_name="log"): """Initializes and attaches a logger to the MQTTClient. + :param str logger_name: Name of the logger instance """ self.logger = logging.getLogger(logger_name) @@ -818,6 +834,7 @@ def attach_logger(self, logger_name="log"): def set_logger_level(self, log_level): """Sets the level of the logger, if defined during init. + :param string log_level: Level of logging to output to the REPL. """ if self.logger is None: From 78c6515358f05c573f89670374fa727c5a1761f5 Mon Sep 17 00:00:00 2001 From: brendan <2bndy5@gmail.com> Date: Sat, 18 Jul 2020 14:59:42 -0700 Subject: [PATCH 2/6] (+) example & ref-to-example --- adafruit_minimqtt/adafruit_minimqtt.py | 13 +++++++------ docs/examples.rst | 10 ++++++++++ 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/adafruit_minimqtt/adafruit_minimqtt.py b/adafruit_minimqtt/adafruit_minimqtt.py index b74c1c72..99302554 100755 --- a/adafruit_minimqtt/adafruit_minimqtt.py +++ b/adafruit_minimqtt/adafruit_minimqtt.py @@ -200,7 +200,7 @@ def deinit(self): self.disconnect() def will_set(self, topic=None, payload=None, qos=0, retain=False): - """Sets the last will and testament properties. MUST be called before connect(). + """Sets the last will and testament properties. MUST be called before `connect()`. :param str topic: MQTT Broker topic. :param str payload: Last will disconnection payload. @@ -681,10 +681,11 @@ def loop_forever(self): method if you want to run a program forever. Code below a call to this method will NOT execute. - NOTE: This method is depreciated and will be removed in the - next major release. Please see examples/minimqtt_pub_sub_blocking.py - for an example of creating a blocking loop which can handle wireless - network events. + .. note:: This method is depreciated and will be removed in the + next major release. Please see + `examples/minimqtt_pub_sub_blocking.py `_ + for an example of creating a blocking loop which can handle wireless + network events. """ while True: if self._sock.connected: @@ -835,7 +836,7 @@ def attach_logger(self, logger_name="log"): def set_logger_level(self, log_level): """Sets the level of the logger, if defined during init. - :param string log_level: Level of logging to output to the REPL. + :param str log_level: Level of logging to output to the REPL. """ if self.logger is None: raise MMQTTException( diff --git a/docs/examples.rst b/docs/examples.rst index 847e6bb1..c7fbaf6c 100644 --- a/docs/examples.rst +++ b/docs/examples.rst @@ -6,3 +6,13 @@ Ensure your device works with this simple test. .. literalinclude:: ../examples/minimqtt_simpletest.py :caption: examples/minimqtt_simpletest.py :linenos: + +Basic forever loop +------------------ + +This example shows how to write a loop that runs forever +& can handle disconnect/re-connect events. + +.. literalinclude:: ../examples/minimqtt_pub_sub_blocking.py + :caption: examples/minimqtt_pub_sub_blocking.py + :linenos: From 58e7b8380da6363973168476cbd0d30e2ba37afa Mon Sep 17 00:00:00 2001 From: brendan <2bndy5@gmail.com> Date: Sat, 18 Jul 2020 20:19:40 -0700 Subject: [PATCH 3/6] docs say QoS-2 unsupported & logger lvl options --- adafruit_minimqtt/adafruit_minimqtt.py | 59 ++++++++++++++++---------- 1 file changed, 36 insertions(+), 23 deletions(-) diff --git a/adafruit_minimqtt/adafruit_minimqtt.py b/adafruit_minimqtt/adafruit_minimqtt.py index 99302554..cfee61c5 100755 --- a/adafruit_minimqtt/adafruit_minimqtt.py +++ b/adafruit_minimqtt/adafruit_minimqtt.py @@ -193,9 +193,7 @@ def __exit__(self, exception_type, exception_value, traceback): self.deinit() def deinit(self): - """De-initializes the MQTT client and disconnects from - the mqtt broker. - + """De-initializes the MQTT client and disconnects from the mqtt broker. """ self.disconnect() @@ -203,9 +201,15 @@ def will_set(self, topic=None, payload=None, qos=0, retain=False): """Sets the last will and testament properties. MUST be called before `connect()`. :param str topic: MQTT Broker topic. - :param str payload: Last will disconnection payload. - :param int qos: Quality of Service level. - :param bool retain: Specifies if the payload is to be retained when it is published. + :param int,float,str payload: Last will disconnection payload. + payloads of type int & float are converted to a string. + :param int qos: Quality of Service level, defaults to + zero. Conventional options are ``0`` (send at least once), ``1`` + (send at most once), or ``2`` (send exactly once). + + .. note:: Only options ``1`` or ``0`` are QoS levels supported by this library. + :param bool retain: Specifies if the payload is to be retained when + it is published. """ if self.logger is not None: self.logger.debug("Setting last will properties") @@ -226,7 +230,7 @@ def will_set(self, topic=None, payload=None, qos=0, retain=False): def add_topic_callback(self, mqtt_topic, callback_method): """Registers a callback_method for a specific MQTT topic. - :param str mqtt_topic: MQTT topic. + :param str mqtt_topic: MQTT topic identifier. :param str callback_method: Name of callback method. """ if mqtt_topic is None or callback_method is None: @@ -236,7 +240,7 @@ def add_topic_callback(self, mqtt_topic, callback_method): def remove_topic_callback(self, mqtt_topic): """Removes a registered callback method. - :param str mqtt_topic: MQTT topic. + :param str mqtt_topic: MQTT topic identifier string. """ if mqtt_topic is None: raise ValueError("MQTT Topic must be defined.") @@ -249,8 +253,7 @@ def remove_topic_callback(self, mqtt_topic): def on_message(self): """Called when a new message has been received on a subscribed topic. - Expected method signature is: - on_message(client, topic, message) + Expected method signature is ``on_message(client, topic, message)`` """ return self._on_message @@ -300,8 +303,7 @@ def connect(self, clean_session=True): raise MMQTTException("Invalid broker address defined.", e) # Fixed Header - fixed_header = bytearray() - fixed_header.append(0x10) + fixed_header = bytearray([0x10]) # NOTE: Variable header is # MQTT_HDR_CONNECT = bytearray(b"\x04MQTT\x04\x02\0\0") @@ -413,11 +415,13 @@ def publish(self, topic, msg, retain=False, qos=0): """Publishes a message to a topic provided. :param str topic: Unique topic identifier. - :param str msg: Data to send to the broker. - :param int msg: Data to send to the broker. - :param float msg: Data to send to the broker. + :param str,int,float msg: Data to send to the broker. :param bool retain: Whether the message is saved by the broker. - :param int qos: Quality of Service level for the message. + :param int qos: Quality of Service level for the message, defaults to + zero. Conventional options are ``0`` (send at least once), ``1`` + (send at most once), or ``2`` (send exactly once). + + .. note:: Only options ``1`` or ``0`` are QoS levels supported by this library. Example of sending an integer, 3, to the broker on topic 'piVal'. @@ -514,10 +518,16 @@ def subscribe(self, topic, qos=0): """Subscribes to a topic on the MQTT Broker. This method can subscribe to one topics or multiple topics. - :param str topic: Unique MQTT topic identifier. - :param int qos: Quality of Service level for the topic, defaults to zero. - :param tuple topic: Tuple containing topic identifier strings and qos level integers. - :param list topic: List of tuples containing topic identifier strings and qos. + :param str,tuple,list topic: Unique MQTT topic identifier string. If + this is a `tuple`, then the tuple should contain topic identifier + string and qos level integer. If this is a `list`, then each list + element should be a tuple containing a topic identifier string and + qos level integer. + :param int qos: Quality of Service level for the topic, defaults to + zero. Conventional options are ``0`` (send at least once), ``1`` + (send at most once), or ``2`` (send exactly once). + + .. note:: Only options ``1`` or ``0`` are QoS levels supported by this library. Example of subscribing a topic string. @@ -593,8 +603,9 @@ def subscribe(self, topic, qos=0): def unsubscribe(self, topic): """Unsubscribes from a MQTT topic. - :param str topic: Unique MQTT topic identifier. - :param list topic: List of tuples containing topic identifier strings. + :param str,list topic: Unique MQTT topic identifier string or a list + of tuples, where each tuple contains an MQTT topic identier + string. Example of unsubscribing from a topic string. @@ -804,7 +815,7 @@ def _set_interface(self): def is_connected(self): """Returns MQTT client session status as True if connected, raises - a MMQTTException if False. + a `MMQTTException` if `False`. """ if self._sock is None or self._is_connected is False: raise MMQTTException("MiniMQTT is not connected.") @@ -837,6 +848,8 @@ def set_logger_level(self, log_level): """Sets the level of the logger, if defined during init. :param str log_level: Level of logging to output to the REPL. + Acceptable options are ``DEBUG``, ``INFO``, ``WARNING``, or + ``ERROR``. """ if self.logger is None: raise MMQTTException( From 882b634657717ab945531fc5e4e47275ec198007 Mon Sep 17 00:00:00 2001 From: brendan <2bndy5@gmail.com> Date: Sat, 18 Jul 2020 22:19:17 -0700 Subject: [PATCH 4/6] fixed QoS level brief explaination --- adafruit_minimqtt/adafruit_minimqtt.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/adafruit_minimqtt/adafruit_minimqtt.py b/adafruit_minimqtt/adafruit_minimqtt.py index cfee61c5..5c86d1e0 100755 --- a/adafruit_minimqtt/adafruit_minimqtt.py +++ b/adafruit_minimqtt/adafruit_minimqtt.py @@ -204,8 +204,8 @@ def will_set(self, topic=None, payload=None, qos=0, retain=False): :param int,float,str payload: Last will disconnection payload. payloads of type int & float are converted to a string. :param int qos: Quality of Service level, defaults to - zero. Conventional options are ``0`` (send at least once), ``1`` - (send at most once), or ``2`` (send exactly once). + zero. Conventional options are ``0`` (send at most once), ``1`` + (send at least once), or ``2`` (send exactly once). .. note:: Only options ``1`` or ``0`` are QoS levels supported by this library. :param bool retain: Specifies if the payload is to be retained when @@ -418,8 +418,8 @@ def publish(self, topic, msg, retain=False, qos=0): :param str,int,float msg: Data to send to the broker. :param bool retain: Whether the message is saved by the broker. :param int qos: Quality of Service level for the message, defaults to - zero. Conventional options are ``0`` (send at least once), ``1`` - (send at most once), or ``2`` (send exactly once). + zero. Conventional options are ``0`` (send at most once), ``1`` + (send at least once), or ``2`` (send exactly once). .. note:: Only options ``1`` or ``0`` are QoS levels supported by this library. @@ -524,8 +524,8 @@ def subscribe(self, topic, qos=0): element should be a tuple containing a topic identifier string and qos level integer. :param int qos: Quality of Service level for the topic, defaults to - zero. Conventional options are ``0`` (send at least once), ``1`` - (send at most once), or ``2`` (send exactly once). + zero. Conventional options are ``0`` (send at most once), ``1`` + (send at least once), or ``2`` (send exactly once). .. note:: Only options ``1`` or ``0`` are QoS levels supported by this library. From ca55c6705ce9c3897c2be5fc06236a616818e370 Mon Sep 17 00:00:00 2001 From: brendan <2bndy5@gmail.com> Date: Mon, 20 Jul 2020 18:28:10 -0700 Subject: [PATCH 5/6] reverted some changes per request --- adafruit_minimqtt/adafruit_minimqtt.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/adafruit_minimqtt/adafruit_minimqtt.py b/adafruit_minimqtt/adafruit_minimqtt.py index 5c86d1e0..5d43c0b6 100755 --- a/adafruit_minimqtt/adafruit_minimqtt.py +++ b/adafruit_minimqtt/adafruit_minimqtt.py @@ -115,8 +115,8 @@ class MQTT: :param bool is_ssl: Sets a secure or insecure connection with the broker. :param bool log: Attaches a logger to the MQTT client, defaults to logging level INFO. :param int keep_alive: KeepAlive interval between the broker and the MiniMQTT client. - """ + """ # pylint: disable=too-many-arguments,too-many-instance-attributes, not-callable, invalid-name, no-member def __init__( self, @@ -193,8 +193,7 @@ def __exit__(self, exception_type, exception_value, traceback): self.deinit() def deinit(self): - """De-initializes the MQTT client and disconnects from the mqtt broker. - """ + """De-initializes the MQTT client and disconnects from the mqtt broker.""" self.disconnect() def will_set(self, topic=None, payload=None, qos=0, retain=False): @@ -303,7 +302,8 @@ def connect(self, clean_session=True): raise MMQTTException("Invalid broker address defined.", e) # Fixed Header - fixed_header = bytearray([0x10]) + fixed_header = bytearray() + fixed_header.append(0x10) # NOTE: Variable header is # MQTT_HDR_CONNECT = bytearray(b"\x04MQTT\x04\x02\0\0") From c57ec62af6dd5f84d456a4be03919af178f91700 Mon Sep 17 00:00:00 2001 From: brendan <2bndy5@gmail.com> Date: Mon, 20 Jul 2020 18:35:47 -0700 Subject: [PATCH 6/6] satisfy black linter --- adafruit_minimqtt/adafruit_minimqtt.py | 1 + 1 file changed, 1 insertion(+) diff --git a/adafruit_minimqtt/adafruit_minimqtt.py b/adafruit_minimqtt/adafruit_minimqtt.py index 5d43c0b6..656c8c0a 100755 --- a/adafruit_minimqtt/adafruit_minimqtt.py +++ b/adafruit_minimqtt/adafruit_minimqtt.py @@ -117,6 +117,7 @@ class MQTT: :param int keep_alive: KeepAlive interval between the broker and the MiniMQTT client. """ + # pylint: disable=too-many-arguments,too-many-instance-attributes, not-callable, invalid-name, no-member def __init__( self,