micropython-umqtt.robust2


Namemicropython-umqtt.robust2 JSON
Version 2.2.0 PyPI version JSON
download
home_pagehttps://github.com/fizista/micropython-umqtt.robust2
SummaryMQTT client for MicroPython ("robust" version).
upload_time2023-04-27 10:23:23
maintainerNone
docs_urlNone
authorWojciech Banaś
requires_pythonNone
licenseMIT
keywords mqtt micropython
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            .. role:: bash(code)
   :language: bash

.. role:: python(code)
   :language: python

umqtt.robust2
=============

umqtt.robust2 is a MQTT client for MicroPython. (Note that it uses some
MicroPython shortcuts and doesn't work with CPython). It consists of
two submodules: umqtt.simple2_ and umqtt.robust2_. umqtt.robust2_ is built
on top of umqtt.simple2_.

Features of this library
------------------------
* allows you to resume connection with the MQTT broker
* allows you to send unsent messages when you resume a connection
* allows you to subscribe to all previously subscribed topics once the connection is resumed
* is resistant to errors in connections
* you have clear information about the type of errors

Differences between umqtt.robust and umqtt.robust2
--------------------------------------------------

* allows for easy programming of different strategies to maintain communication with the MQTT broker
* works without blocking app
* in case of network problems, it can send the data itself at a later time
* we have the ability to track down errors
* is larger than the previous one, so I recommend compiling this
  library to MPY files (especially for esp8266)

Problems and solutions
----------------------
* ImportError: no module named 'umqtt.robust2'

  Versions of micropython from http://micropython.org/download/ since version 1.12 include
  the umqtt library, which conflicts with the current library.
  To avoid conflicts, you need to change the order of importing libraries.
  You need to import the '/lib' libraries first and then the system libraries.
  Just add the following lines of code to the boot.py file:

.. code-block:: python

    import sys
    sys.path.reverse()

How and where to install this code?
-----------------------------------
This library requires the umqtt.simple2_ library.
Therefore, please read this required library first,
and then you can install this one.

You can install using the upip:

.. code-block:: python

    import upip
    upip.install("micropython-umqtt.robust2")

or

.. code-block:: bash

    micropython -m upip install -p modules micropython-umqtt.robust2


You can also clone this repository, and install it manually:

.. code-block:: bash

    git clone https://github.com/fizista/micropython-umqtt.robust2.git

Manual installation gives you more possibilities:

* You can compile this library into MPY files using the :bash:`compile.sh` script.
* You can remove comments from the code with the command: :bash:`python setup.py minify`
* You can of course copy the code as it is, if you don't mind.

**Please note that the PyPi repositories contain optimized code (no comments).**

**For more detailed information about API please see the source code
(which is quite short and easy to review) and provided examples.**

What does it mean to be "robust" ?
----------------------------------

Modern computing systems are sufficiently complex and have multiple
points of failure. Consider for example that nothing will work if
there's no power (mains outage or battery ran out). As you may imagine,
umqtt.robust2 won't help you with your flat battery. Most computing
systems are now networked, and communication is another weak link.
This is especially true for wireless communications. If two of your
systems can't connect reliably communicate via WiFi, umqtt.robust2
can't magically resolve that (but it may help with intermittent
WiFi issues).

What umqtt.robust2 tries to do is very simple - if while trying to
perform some operation, it detects that connection to MQTT breaks,
it tries to reconnect to it. That's good direction towards "robustness",
but the problem that there is no single definition of what "robust"
is. Let's consider following usecase:

1. A temperature reading gets transmitted once a minute. Then the
best option in case of a transmission error might be not doing
anything at all - in a minute, another reading will be transmitted,
and for slowly-changing parameter like a temperature, a one-minute
lost reading is not a problem. Actually, if the sending device is
battery-powered, any connection retries will just drain battery and
make device "less robust" (it will run out of juice sooner and more
unexpectedly, which may be a criteria for "robustness").

We can also cache some of the results, as far as memory allows,
until we try to connect again. This will increase the reliability
of data delivery.

2. If there's a button, which communicates its press event, then
perhaps it's really worth to retry to deliver this event (a user
expects something to happen when they press the button, right?).
But if a button is battery-power, unconstrained retries won't do
much good still. Consider mains power outage for several hours,
MQTT server down all this time, and battery-powered button trying
to re-publish event every second. It will likely drain battery
during this time, which is very non-robust. Perhaps, if a press
isn't delivered in 15 seconds, it's no longer relevant (depending
on what press does, the above may be good for a button turning
on lights, but not for something else!)

3. Finally, let's consider security sensors, like a window broken
sensor. That's the hardest case. Apparently, those events are
important enough to be delivered no matter what. But if done with
short, dumb retries, it will only lead to quick battery drain. So,
a robust device would retry, but in smart manner, to let battery
run for as long as possible, to maximize the chance of the message
being delivered.

Let's sum it up:

a) There's no single definition of what "robust" is. It depends on
   a particular application.
b) Robustness is a complex measure, it doesn't depend on one single
   feature, but rather many different features working together.
   Consider for example that to make button from the case 2 above
   work better, it would help to add a visual feedback, so a user
   knew what happens.

As you may imagine, umqtt.robust2 doesn't, and can't, cover all possible
"robustness" scenarios, nor it alone can make your MQTT application
"robust". Rather, it's a barebones example of how to reconnect to an
MQTT server in case of a connection error. As such, it's just one
of many steps required to make your app robust, and majority of those
steps lie on *your application* side. With that in mind, any realistic
application would subclass umqtt.robust2.MQTTClient class and override
add_msg_to_send() and reconnect() methods and will use the
socket_timeout/message_timeout parameters to suit particular usage scenario.
It may even happen that umqtt.robust2 won't even suit your needs, and you
will need to implement your "robust" handling from scratch.


Persistent and non-persistent MQTT servers
------------------------------------------

Consider an example: you subscribed to some MQTT topics, then connection
went down. If we talk "robust", then once you reconnect, you want any
messages which arrived when the connection was down, to be still delivered
to you. That requires retainment and persistency enabled on MQTT server.
As umqtt.robust2 tries to achieve as much "robustness" as possible, it
makes a requirement that the MQTT server it communicates to has persistency
enabled. This include persistent sessions, meaning that any client
subscriptions are retained across disconnect, and if you subscribed once,
you no longer need to resubscribe again on next connection(s). This makes
it more robust, minimizing amount of traffic to transfer on each connection
(the more you transfer, the higher probability of error), and also saves
battery power.

However, not all broker offer true, persistent MQTT support:

* If you use self-hosted broker, you may need to configure it for
  persistency. E.g., a popular open-source broker Mosquitto requires
  following line::

    persistence true

  to be added to ``mosquitto.conf``. Please consult documentation of
  your broker.

* Many so-called "cloud providers" offer very limited subset of MQTT for
  their free/inexpensive tiers. Persistence and QoS are features usually
  not supported. It's hard to achieve any true robustness with these
  demo-like offerings, and umqtt.robust2 isn't designed to work with them.


.. _umqtt.simple2: https://github.com/fizista/micropython-umqtt.simple2
.. _umqtt.robust2: https://github.com/fizista/micropython-umqtt.robust2
            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/fizista/micropython-umqtt.robust2",
    "name": "micropython-umqtt.robust2",
    "maintainer": null,
    "docs_url": null,
    "requires_python": null,
    "maintainer_email": null,
    "keywords": "mqtt micropython",
    "author": "Wojciech Bana\u015b",
    "author_email": "fizista+umqtt.robust2@gmail.com",
    "download_url": "https://files.pythonhosted.org/packages/cc/63/e60608a0d92b3a4b4da75643bce9ec0907b78a72ea1c9688d19765f0d89b/micropython-umqtt.robust2-2.2.0.tar.gz",
    "platform": null,
    "description": ".. role:: bash(code)\n   :language: bash\n\n.. role:: python(code)\n   :language: python\n\numqtt.robust2\n=============\n\numqtt.robust2 is a MQTT client for MicroPython. (Note that it uses some\nMicroPython shortcuts and doesn't work with CPython). It consists of\ntwo submodules: umqtt.simple2_ and umqtt.robust2_. umqtt.robust2_ is built\non top of umqtt.simple2_.\n\nFeatures of this library\n------------------------\n* allows you to resume connection with the MQTT broker\n* allows you to send unsent messages when you resume a connection\n* allows you to subscribe to all previously subscribed topics once the connection is resumed\n* is resistant to errors in connections\n* you have clear information about the type of errors\n\nDifferences between umqtt.robust and umqtt.robust2\n--------------------------------------------------\n\n* allows for easy programming of different strategies to maintain communication with the MQTT broker\n* works without blocking app\n* in case of network problems, it can send the data itself at a later time\n* we have the ability to track down errors\n* is larger than the previous one, so I recommend compiling this\n  library to MPY files (especially for esp8266)\n\nProblems and solutions\n----------------------\n* ImportError: no module named 'umqtt.robust2'\n\n  Versions of micropython from http://micropython.org/download/ since version 1.12 include\n  the umqtt library, which conflicts with the current library.\n  To avoid conflicts, you need to change the order of importing libraries.\n  You need to import the '/lib' libraries first and then the system libraries.\n  Just add the following lines of code to the boot.py file:\n\n.. code-block:: python\n\n    import sys\n    sys.path.reverse()\n\nHow and where to install this code?\n-----------------------------------\nThis library requires the umqtt.simple2_ library.\nTherefore, please read this required library first,\nand then you can install this one.\n\nYou can install using the upip:\n\n.. code-block:: python\n\n    import upip\n    upip.install(\"micropython-umqtt.robust2\")\n\nor\n\n.. code-block:: bash\n\n    micropython -m upip install -p modules micropython-umqtt.robust2\n\n\nYou can also clone this repository, and install it manually:\n\n.. code-block:: bash\n\n    git clone https://github.com/fizista/micropython-umqtt.robust2.git\n\nManual installation gives you more possibilities:\n\n* You can compile this library into MPY files using the :bash:`compile.sh` script.\n* You can remove comments from the code with the command: :bash:`python setup.py minify`\n* You can of course copy the code as it is, if you don't mind.\n\n**Please note that the PyPi repositories contain optimized code (no comments).**\n\n**For more detailed information about API please see the source code\n(which is quite short and easy to review) and provided examples.**\n\nWhat does it mean to be \"robust\" ?\n----------------------------------\n\nModern computing systems are sufficiently complex and have multiple\npoints of failure. Consider for example that nothing will work if\nthere's no power (mains outage or battery ran out). As you may imagine,\numqtt.robust2 won't help you with your flat battery. Most computing\nsystems are now networked, and communication is another weak link.\nThis is especially true for wireless communications. If two of your\nsystems can't connect reliably communicate via WiFi, umqtt.robust2\ncan't magically resolve that (but it may help with intermittent\nWiFi issues).\n\nWhat umqtt.robust2 tries to do is very simple - if while trying to\nperform some operation, it detects that connection to MQTT breaks,\nit tries to reconnect to it. That's good direction towards \"robustness\",\nbut the problem that there is no single definition of what \"robust\"\nis. Let's consider following usecase:\n\n1. A temperature reading gets transmitted once a minute. Then the\nbest option in case of a transmission error might be not doing\nanything at all - in a minute, another reading will be transmitted,\nand for slowly-changing parameter like a temperature, a one-minute\nlost reading is not a problem. Actually, if the sending device is\nbattery-powered, any connection retries will just drain battery and\nmake device \"less robust\" (it will run out of juice sooner and more\nunexpectedly, which may be a criteria for \"robustness\").\n\nWe can also cache some of the results, as far as memory allows,\nuntil we try to connect again. This will increase the reliability\nof data delivery.\n\n2. If there's a button, which communicates its press event, then\nperhaps it's really worth to retry to deliver this event (a user\nexpects something to happen when they press the button, right?).\nBut if a button is battery-power, unconstrained retries won't do\nmuch good still. Consider mains power outage for several hours,\nMQTT server down all this time, and battery-powered button trying\nto re-publish event every second. It will likely drain battery\nduring this time, which is very non-robust. Perhaps, if a press\nisn't delivered in 15 seconds, it's no longer relevant (depending\non what press does, the above may be good for a button turning\non lights, but not for something else!)\n\n3. Finally, let's consider security sensors, like a window broken\nsensor. That's the hardest case. Apparently, those events are\nimportant enough to be delivered no matter what. But if done with\nshort, dumb retries, it will only lead to quick battery drain. So,\na robust device would retry, but in smart manner, to let battery\nrun for as long as possible, to maximize the chance of the message\nbeing delivered.\n\nLet's sum it up:\n\na) There's no single definition of what \"robust\" is. It depends on\n   a particular application.\nb) Robustness is a complex measure, it doesn't depend on one single\n   feature, but rather many different features working together.\n   Consider for example that to make button from the case 2 above\n   work better, it would help to add a visual feedback, so a user\n   knew what happens.\n\nAs you may imagine, umqtt.robust2 doesn't, and can't, cover all possible\n\"robustness\" scenarios, nor it alone can make your MQTT application\n\"robust\". Rather, it's a barebones example of how to reconnect to an\nMQTT server in case of a connection error. As such, it's just one\nof many steps required to make your app robust, and majority of those\nsteps lie on *your application* side. With that in mind, any realistic\napplication would subclass umqtt.robust2.MQTTClient class and override\nadd_msg_to_send() and reconnect() methods and will use the\nsocket_timeout/message_timeout parameters to suit particular usage scenario.\nIt may even happen that umqtt.robust2 won't even suit your needs, and you\nwill need to implement your \"robust\" handling from scratch.\n\n\nPersistent and non-persistent MQTT servers\n------------------------------------------\n\nConsider an example: you subscribed to some MQTT topics, then connection\nwent down. If we talk \"robust\", then once you reconnect, you want any\nmessages which arrived when the connection was down, to be still delivered\nto you. That requires retainment and persistency enabled on MQTT server.\nAs umqtt.robust2 tries to achieve as much \"robustness\" as possible, it\nmakes a requirement that the MQTT server it communicates to has persistency\nenabled. This include persistent sessions, meaning that any client\nsubscriptions are retained across disconnect, and if you subscribed once,\nyou no longer need to resubscribe again on next connection(s). This makes\nit more robust, minimizing amount of traffic to transfer on each connection\n(the more you transfer, the higher probability of error), and also saves\nbattery power.\n\nHowever, not all broker offer true, persistent MQTT support:\n\n* If you use self-hosted broker, you may need to configure it for\n  persistency. E.g., a popular open-source broker Mosquitto requires\n  following line::\n\n    persistence true\n\n  to be added to ``mosquitto.conf``. Please consult documentation of\n  your broker.\n\n* Many so-called \"cloud providers\" offer very limited subset of MQTT for\n  their free/inexpensive tiers. Persistence and QoS are features usually\n  not supported. It's hard to achieve any true robustness with these\n  demo-like offerings, and umqtt.robust2 isn't designed to work with them.\n\n\n.. _umqtt.simple2: https://github.com/fizista/micropython-umqtt.simple2\n.. _umqtt.robust2: https://github.com/fizista/micropython-umqtt.robust2",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "MQTT client for MicroPython (\"robust\" version).",
    "version": "2.2.0",
    "split_keywords": [
        "mqtt",
        "micropython"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "cc63e60608a0d92b3a4b4da75643bce9ec0907b78a72ea1c9688d19765f0d89b",
                "md5": "1252e3db03917bb22dcecbe0697d2123",
                "sha256": "da3a09a570868d8e4ae6d2fad475230f6f2b130b45711be6873f83b10ebd4a6c"
            },
            "downloads": -1,
            "filename": "micropython-umqtt.robust2-2.2.0.tar.gz",
            "has_sig": false,
            "md5_digest": "1252e3db03917bb22dcecbe0697d2123",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": null,
            "size": 5676,
            "upload_time": "2023-04-27T10:23:23",
            "upload_time_iso_8601": "2023-04-27T10:23:23.153939Z",
            "url": "https://files.pythonhosted.org/packages/cc/63/e60608a0d92b3a4b4da75643bce9ec0907b78a72ea1c9688d19765f0d89b/micropython-umqtt.robust2-2.2.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2023-04-27 10:23:23",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "github_user": "fizista",
    "github_project": "micropython-umqtt.robust2",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": false,
    "lcname": "micropython-umqtt.robust2"
}
        
Elapsed time: 0.06020s