Update your device firmware written in MicroPython over the air. Suitable for private and/or larger projects with many files.
Compatibility:
- v0.1 requires MicroPython 1.17 - 1.20
- v0.2 requires MicroPython 1.21 or newer
Other OTA updaters, notably rdehuyss/micropython-ota-updater, smysnk/micropython-ota-updater and RangerDigital/senko, update code from a particular branch on GitHub. This OTA is different in the following aspects:
- update from any HTTP(S) server with no hardcoded endpoints, allowing you to keep control of your hosting without dependencies
- no need for GitHub account
- no need to make your code public or pay for private repos
- replaces files in-place without storing uncompressed new firmware in flash
- replaces files in the root of the filesystem
- downloads new firmware as a single compressed .tar.gz file which is more efficient for a larger number of files
- compares SHA256 hash of the new firmware file but not of individual files (optional)
- checks if there is sufficient available free space in the file system (optional)
- compares firmware version: the content of
version
file from MicroPython device file system and the version published on your server stored inlatest
file, see details below
Install using MicroPython mip
>>> import mip
>>> mip.install('github:mkomon/uota')
or using mpremote
mpremote mip install github:mkomon/uota
Copy uota.py to the root directory or "lib" directory of your device.
Drop the following files into the root of your project:
- uota.cfg
- must be a valid Python dictionary with the following keys:
url
- base HTTP or HTTPS URL where to look for new firmware
- ends with a trailing slash
tmp_filename
- the new firmware will be stored in a file of this name
- this file is deleted automatically after
excluded_files
- files or directories with matching names will be skipped and not overwritten with new versions. Keep local device configuration such as wifi credentials or certificates from being overwritten.
delete
- items are file/directory names as strings, these will be deleted after new firmware is installed
- this configuration option is loaded after the new firmware is installed to perform any cleanup that may be needed
- 'user' and 'password' (optional)
- Support for basic http authentication
- must be a valid Python dictionary with the following keys:
version
- the current version of the firmware
- version check can be disabled by passing
version_check=False
argument touota.check_for_updates()
Publish new firmware on your HTTP(S) server as two files:
- firmware file of any name
- a TAR file compressed with gzip, the content will be downloaded and unpacked directly into the root of the filesystem of your MicroPython device
- can be created with
tar -czf firmware.tar.gz *
shell command on any Linux/UNIX/MacOS system
latest
- a text file with the following fields separated by a semicolon:
- version
- new firmware filename available on the server
- required amount of additional free space in flash, measured in kB (optional)
- SHA256 hash of the new firmware file (optional, but makes the previous item mandatory)
- valid examples:
- 2.0.1;firmware.tar.gz
- 2.0.1;firmware.tar.gz;2
- 2.0.1;firmware.tar.gz;0;8870f8b3bd8b54437f0a7f721cd3f3fe208e60638dcf36a9f4efe31dab58c548
- invalid examples:
- firmware.tar.gz
- 2.0.1;firmware.tar.gz;8870f8b3bd8b54437f0a7f721cd3f3fe208e60638dcf36a9f4efe31dab58c548
- a text file with the following fields separated by a semicolon:
And then use uota
in your project as follows. You must connect to wifi yourself as uota
expects a working wifi connection to function.
import uota
import machine
...
from connect_wifi import connect_wifi
connect_wifi()
...
if do_ota_update and uota.check_for_updates():
uota.install_new_firmware()
machine.reset()
MicroPython's built-in SSL package does not support checking server certificate or authenticating the client with the server using certificates. uOTA can perform certificate pinning by checking the hash of server-side private key, if ucertpin is installed.
Certificate pinning is disabled by default. To enable it make ucertpin available for import and pass pubkey_hash=b'---your-SHA256-hash-value---'
argument to uota.check_for_updates
:
>>> import uota
>>> uota.check_for_updates() # no certificate pinning
new version 0.3 is available
True
>>> uota.check_for_updates(pubkey_hash=b'abc') # certificate pinning with incorrect hash
Certificate pinning failed, the hash of server public key does not match. Aborting the update.
False