micropython-ota


Namemicropython-ota JSON
Version 2.1.0 PyPI version JSON
download
home_page
SummaryMicropython library for upgrading code over-the-air (OTA)
upload_time2023-01-31 20:40:34
maintainer
docs_urlNone
authorOliver Gregorius
requires_python
license
keywords ota microcontroller micropython
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # micropython-ota

[![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/olivergregorius/micropython_ota/build.yml?branch=main&label=Python%20Build&logo=github)](https://github.com/olivergregorius/micropython_ota/actions/workflows/build.yml)
[![Python Versions](https://img.shields.io/pypi/pyversions/micropython-ota?label=Python)](https://pypi.org/project/micropython-ota/)
[![GitHub](https://img.shields.io/github/license/olivergregorius/micropython_ota?label=License)](https://github.com/olivergregorius/micropython_ota/blob/HEAD/LICENSE)
[![PyPI](https://img.shields.io/pypi/v/micropython-ota?label=PyPI)](https://pypi.org/project/micropython-ota/)

## Introduction

Micropython library for upgrading code over-the-air (OTA)

## Preparation

For OTA updates to work an HTTP/HTTPS server like Apache or nGinx is required to be running and accessible by the device. This server can serve multiple devices
and multiple projects at once. There are two supported directory structures of which one must be provided for the OTA updates to work:

1. Version as prefix (default)
    ```
    server-root/
    |- <project_name>/
    |  |- version
    |  |- <version>_<filename1>
    |  |- <version>_<filename2>
    |  |- ...
    |- <project_name>/
       |- version
       |- <version>_<filename1>
       |- <version>_<filename2>
       |- ...
    ```

2. Version as subdirectory (by setting the parameter `use_version_prefix` to `False`, see [Usage](#usage))
    ```
    server-root/
    |- <project_name>/
    |  |- version
    |  |- <version_subdir>
    |     |- <filename1>
    |     |- <filename2>
    |     |- ...
    |- <project_name>/
       |- version
       |- <version_subdir>
          |- <filename1>
          |- <filename2>
          |- ...
    ```

For each project a directory must exist in the server's document root. Inside this directory a file "version" exists containing the version-tag to be pulled
by the devices, e.g. `v1.0.0`. The source code files to be pulled by the devices are placed either right next to the version-file, prefixed by the version-tag,
or in a subdirectory named with the version-tag.
This structure also provides the ability to do a rollback by simply changing the version-tag in the version-file to an older version-tag, as long as the
relevant source code files still reside in the expected location.

In the following example two projects "sample" and "big_project" are configured, using the default, version-prefixed directory structure:

```
server-root/
|- sample/
|  |- version <-- containing v1.0.1
|  |- v1.0.0_boot.py
|  |- v1.0.0_main.py
|  |- v1.0.1 boot.py
|  |- v1.0.1 main.py
|- big_project/
   |- version <-- containing v1.0.0
   |- v1.0.0_boot.py
   |- v1.0.0_main.py
   |- v1.0.0_data.py
```

## Installation

The library can be installed using [upip](https://docs.micropython.org/en/latest/reference/glossary.html#term-upip) or
[mip](https://docs.micropython.org/en/latest/reference/packages.html). Ensure that the device is connected to the network.

### Installation using upip (Micropython < 1.19)

```python
import upip
upip.install('micropython-ota')
```

### Installation using mip (Micropython >= 1.19)

#### Py-file

```python
import mip
mip.install('github:olivergregorius/micropython_ota/micropython_ota.py')
```

#### Cross-compiled mpy-file

**NOTE**: Set the release_version variable accordingly.

```python
import mip
release_version='vX.Y.Z'
mip.install(f'https://github.com/olivergregorius/micropython_ota/releases/download/{release_version}/micropython_ota.mpy')
```

## Usage

This library provides two methods for

1. handling code updates during boot (`ota_update`) and
2. checking for code updates at regular intervals (`check_for_ota_update`).

The `ota_update` method might be called in the boot.py file, right after the network connection has been established:

```python
import micropython_ota

# connect to network

ota_host = 'http://192.168.2.100'
project_name = 'sample'
filenames = ['boot.py', 'main.py']

micropython_ota.ota_update(ota_host, project_name, filenames, use_version_prefix=True, hard_reset_device=True, soft_reset_device=False, timeout=5)
```

That's it. On boot the library retrieves the version-file from `http://192.168.2.100/sample/version` and evaluates its content against a locally persisted
version-file. (Of course, on the first run the local version-file does not exist, yet. This is treated as a new version being available.)
If the versions differ, the source code files listed in `filenames` are updated accordingly and on success the local version-file is updated as well. If the
`use_version_prefix` is set to True (default) the library expects the 'Version as prefix' directory structure on the server, otherwise it expects the 'Version
as subdirectory' directory structure (see [Preparation](#preparation)). If the `hard_reset_device`-flag is set to `True` (default) the device will be reset
after the successful update by calling `machine.reset()`. For just soft-resetting the device the flag `soft_reset_device` can be set to `True` (defaults to
`False`), taking precedence. This will call the `machine.soft_reset()`-method. The timeout can be set accordingly, by default its value is 5 seconds.

For regular checking for code updates the method `check_for_ota_update` might be called in the course of the regular application logic in main.py, e.g.:

```python
import micropython_ota
import utime

ota_host = 'http://192.168.2.100'
project_name = 'sample'

while True:
    # do some other stuff
    utime.sleep(10)
    micropython_ota.check_for_ota_update(ota_host, project_name, soft_reset_device=False, timeout=5)
```

In this case on each iteration the library checks for a new version as described above and resets the device if a new version is available. By default a
hard-reset is performed (by calling `machine.reset()`). By setting the flag `soft_reset_device` to `True` (defaults to `False`) the device will just be
soft-reset (by calling `machine.soft_reset()`). After the reset the `ota_update`-method called in the boot.py performs the actual update. This method accepts
the timeout setting, too, by default it is set to 5 seconds.

## HTTP(S) Basic Authentication

`ota_update()` and `check_for_ota_update()` methods allow optional `user` and `passwd` parameters.  When specified the library performs a basic authentication
against the server hosting the source files.  Use of HTTPS (versus HTTP) is very highly recommended when using basic authentication as, otherwise, the resulting
username and password are sent as plain text i.e. completely unsecure.

Here is the same example as above, but using HTTPS and Basic Authentication:

```python
import micropython_ota

# connect to network

ota_host = 'https://example.com'
project_name = 'sample'
filenames = ['boot.py', 'main.py']
user = 'otauser'
passwd = 'topsecret' # it's best to place this credential is a secrets.py file

micropython_ota.ota_update(ota_host, project_name, filenames, user=user, passwd=passwd, use_version_prefix=True, hard_reset_device=True, soft_reset_device=False, timeout=5)
```

There are plenty of tutorials online on how to set up secured HTTP file access on your webserver, but the basic steps are:
- get and install an SSL certificate (Let's Encrypt is by far the best choice)
- enable HTTPS access on your web server
- prevent directories from listing files
- enable HTTP Basic Authentication password protection on target directories

            

Raw data

            {
    "_id": null,
    "home_page": "",
    "name": "micropython-ota",
    "maintainer": "",
    "docs_url": null,
    "requires_python": "",
    "maintainer_email": "",
    "keywords": "OTA,Microcontroller,Micropython",
    "author": "Oliver Gregorius",
    "author_email": "oliver@gregorius.dev",
    "download_url": "https://files.pythonhosted.org/packages/6d/5c/17f4b88f98dd0312e7f8ba8c6f25fbf4625da69b5eb50c12a9785b79bcca/micropython_ota-2.1.0.tar.gz",
    "platform": null,
    "description": "# micropython-ota\n\n[![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/olivergregorius/micropython_ota/build.yml?branch=main&label=Python%20Build&logo=github)](https://github.com/olivergregorius/micropython_ota/actions/workflows/build.yml)\n[![Python Versions](https://img.shields.io/pypi/pyversions/micropython-ota?label=Python)](https://pypi.org/project/micropython-ota/)\n[![GitHub](https://img.shields.io/github/license/olivergregorius/micropython_ota?label=License)](https://github.com/olivergregorius/micropython_ota/blob/HEAD/LICENSE)\n[![PyPI](https://img.shields.io/pypi/v/micropython-ota?label=PyPI)](https://pypi.org/project/micropython-ota/)\n\n## Introduction\n\nMicropython library for upgrading code over-the-air (OTA)\n\n## Preparation\n\nFor OTA updates to work an HTTP/HTTPS server like Apache or nGinx is required to be running and accessible by the device. This server can serve multiple devices\nand multiple projects at once. There are two supported directory structures of which one must be provided for the OTA updates to work:\n\n1. Version as prefix (default)\n    ```\n    server-root/\n    |- <project_name>/\n    |  |- version\n    |  |- <version>_<filename1>\n    |  |- <version>_<filename2>\n    |  |- ...\n    |- <project_name>/\n       |- version\n       |- <version>_<filename1>\n       |- <version>_<filename2>\n       |- ...\n    ```\n\n2. Version as subdirectory (by setting the parameter `use_version_prefix` to `False`, see [Usage](#usage))\n    ```\n    server-root/\n    |- <project_name>/\n    |  |- version\n    |  |- <version_subdir>\n    |     |- <filename1>\n    |     |- <filename2>\n    |     |- ...\n    |- <project_name>/\n       |- version\n       |- <version_subdir>\n          |- <filename1>\n          |- <filename2>\n          |- ...\n    ```\n\nFor each project a directory must exist in the server's document root. Inside this directory a file \"version\" exists containing the version-tag to be pulled\nby the devices, e.g. `v1.0.0`. The source code files to be pulled by the devices are placed either right next to the version-file, prefixed by the version-tag,\nor in a subdirectory named with the version-tag.\nThis structure also provides the ability to do a rollback by simply changing the version-tag in the version-file to an older version-tag, as long as the\nrelevant source code files still reside in the expected location.\n\nIn the following example two projects \"sample\" and \"big_project\" are configured, using the default, version-prefixed directory structure:\n\n```\nserver-root/\n|- sample/\n|  |- version <-- containing v1.0.1\n|  |- v1.0.0_boot.py\n|  |- v1.0.0_main.py\n|  |- v1.0.1 boot.py\n|  |- v1.0.1 main.py\n|- big_project/\n   |- version <-- containing v1.0.0\n   |- v1.0.0_boot.py\n   |- v1.0.0_main.py\n   |- v1.0.0_data.py\n```\n\n## Installation\n\nThe library can be installed using [upip](https://docs.micropython.org/en/latest/reference/glossary.html#term-upip) or\n[mip](https://docs.micropython.org/en/latest/reference/packages.html). Ensure that the device is connected to the network.\n\n### Installation using upip (Micropython < 1.19)\n\n```python\nimport upip\nupip.install('micropython-ota')\n```\n\n### Installation using mip (Micropython >= 1.19)\n\n#### Py-file\n\n```python\nimport mip\nmip.install('github:olivergregorius/micropython_ota/micropython_ota.py')\n```\n\n#### Cross-compiled mpy-file\n\n**NOTE**: Set the release_version variable accordingly.\n\n```python\nimport mip\nrelease_version='vX.Y.Z'\nmip.install(f'https://github.com/olivergregorius/micropython_ota/releases/download/{release_version}/micropython_ota.mpy')\n```\n\n## Usage\n\nThis library provides two methods for\n\n1. handling code updates during boot (`ota_update`) and\n2. checking for code updates at regular intervals (`check_for_ota_update`).\n\nThe `ota_update` method might be called in the boot.py file, right after the network connection has been established:\n\n```python\nimport micropython_ota\n\n# connect to network\n\nota_host = 'http://192.168.2.100'\nproject_name = 'sample'\nfilenames = ['boot.py', 'main.py']\n\nmicropython_ota.ota_update(ota_host, project_name, filenames, use_version_prefix=True, hard_reset_device=True, soft_reset_device=False, timeout=5)\n```\n\nThat's it. On boot the library retrieves the version-file from `http://192.168.2.100/sample/version` and evaluates its content against a locally persisted\nversion-file. (Of course, on the first run the local version-file does not exist, yet. This is treated as a new version being available.)\nIf the versions differ, the source code files listed in `filenames` are updated accordingly and on success the local version-file is updated as well. If the\n`use_version_prefix` is set to True (default) the library expects the 'Version as prefix' directory structure on the server, otherwise it expects the 'Version\nas subdirectory' directory structure (see [Preparation](#preparation)). If the `hard_reset_device`-flag is set to `True` (default) the device will be reset\nafter the successful update by calling `machine.reset()`. For just soft-resetting the device the flag `soft_reset_device` can be set to `True` (defaults to\n`False`), taking precedence. This will call the `machine.soft_reset()`-method. The timeout can be set accordingly, by default its value is 5 seconds.\n\nFor regular checking for code updates the method `check_for_ota_update` might be called in the course of the regular application logic in main.py, e.g.:\n\n```python\nimport micropython_ota\nimport utime\n\nota_host = 'http://192.168.2.100'\nproject_name = 'sample'\n\nwhile True:\n    # do some other stuff\n    utime.sleep(10)\n    micropython_ota.check_for_ota_update(ota_host, project_name, soft_reset_device=False, timeout=5)\n```\n\nIn this case on each iteration the library checks for a new version as described above and resets the device if a new version is available. By default a\nhard-reset is performed (by calling `machine.reset()`). By setting the flag `soft_reset_device` to `True` (defaults to `False`) the device will just be\nsoft-reset (by calling `machine.soft_reset()`). After the reset the `ota_update`-method called in the boot.py performs the actual update. This method accepts\nthe timeout setting, too, by default it is set to 5 seconds.\n\n## HTTP(S) Basic Authentication\n\n`ota_update()` and `check_for_ota_update()` methods allow optional `user` and `passwd` parameters.  When specified the library performs a basic authentication\nagainst the server hosting the source files.  Use of HTTPS (versus HTTP) is very highly recommended when using basic authentication as, otherwise, the resulting\nusername and password are sent as plain text i.e. completely unsecure.\n\nHere is the same example as above, but using HTTPS and Basic Authentication:\n\n```python\nimport micropython_ota\n\n# connect to network\n\nota_host = 'https://example.com'\nproject_name = 'sample'\nfilenames = ['boot.py', 'main.py']\nuser = 'otauser'\npasswd = 'topsecret' # it's best to place this credential is a secrets.py file\n\nmicropython_ota.ota_update(ota_host, project_name, filenames, user=user, passwd=passwd, use_version_prefix=True, hard_reset_device=True, soft_reset_device=False, timeout=5)\n```\n\nThere are plenty of tutorials online on how to set up secured HTTP file access on your webserver, but the basic steps are:\n- get and install an SSL certificate (Let's Encrypt is by far the best choice)\n- enable HTTPS access on your web server\n- prevent directories from listing files\n- enable HTTP Basic Authentication password protection on target directories\n",
    "bugtrack_url": null,
    "license": "",
    "summary": "Micropython library for upgrading code over-the-air (OTA)",
    "version": "2.1.0",
    "split_keywords": [
        "ota",
        "microcontroller",
        "micropython"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "6d5c17f4b88f98dd0312e7f8ba8c6f25fbf4625da69b5eb50c12a9785b79bcca",
                "md5": "021122a895473ce51edd283c726d61a9",
                "sha256": "f340caa81d88ff78365daa255adcafd79fa4d880ed58ce779748e87d6f9f3973"
            },
            "downloads": -1,
            "filename": "micropython_ota-2.1.0.tar.gz",
            "has_sig": false,
            "md5_digest": "021122a895473ce51edd283c726d61a9",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": null,
            "size": 4205,
            "upload_time": "2023-01-31T20:40:34",
            "upload_time_iso_8601": "2023-01-31T20:40:34.603290Z",
            "url": "https://files.pythonhosted.org/packages/6d/5c/17f4b88f98dd0312e7f8ba8c6f25fbf4625da69b5eb50c12a9785b79bcca/micropython_ota-2.1.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2023-01-31 20:40:34",
    "github": false,
    "gitlab": false,
    "bitbucket": false,
    "lcname": "micropython-ota"
}
        
Elapsed time: 0.51405s