Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OTA rework #3202

Open
wants to merge 1 commit into
base: feat/2.0.0
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions docs/guide/usage/mqtt_topics_and_messages.md
Original file line number Diff line number Diff line change
Expand Up @@ -418,6 +418,14 @@ See [OTA updates](./ota_updates.md).

See [OTA updates](./ota_updates.md).

#### zigbee2mqtt/bridge/request/device/ota_update/check/downgrade

See [OTA updates](./ota_updates.md).

#### zigbee2mqtt/bridge/request/device/ota_update/update/downgrade

See [OTA updates](./ota_updates.md).

#### zigbee2mqtt/bridge/request/device/configure

Allows to manually trigger a re-configure of the device. Should only be used when the device is not working as expected (e.g. not reporting certain values), not all devices can be configured (only when the definition has a `configure` in its [definition](https://github.com/Koenkk/zigbee-herdsman-converters/blob/master/devices)). Allowed payloads are `{"id": "deviceID"}` or `deviceID` where deviceID can be the `ieee_address` or `friendly_name` of the device. Example; request: `{"id": "my_remote"}` or `my_remote`, response: `{"data":{"id": "my_remote"},"status":"ok"}`.
Expand Down
119 changes: 77 additions & 42 deletions docs/guide/usage/ota_updates.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,98 +9,105 @@ This feature allows to update your Zigbee devices over-the-air.

::: tip TIP
Always check if the firmware update will bring you advantages. Firmware updates are NOT made for Zigbee2MQTT, but for working with apps and hubs from the brand.
In some cases the firmware update can cause that your device will react different then Zigbee2MQTT expects, making that you can't use it the way you want, at least until Zigbee2MQTT is changed to react to those changes.
In some cases the firmware update can cause your device to react differently then what Zigbee2MQTT expects, resulting in undesired behavior, no-longer accessible features, etc., at least until Zigbee2MQTT is updated to take those changes into account.
If you get annoyed by the notifications that there are updates available, then turn the automatic check off.
:::

Not all manufacturers make their updates available, below is a (not-complete) list of manufacturer/devices that support it:

- IKEA TRÅDFRI devices
- Ubisys devices
- Some Xiaomi devices
- Salus SP600 Smart plug
- Osram/Ledvance devices (not every firmware is made available by them, in case not you will see the following exception in the log `No image available for ...`)
- Philips Hue devices (not every firmware is made available by them, in case not you will see the following exception in the log `No image available for ...`)
- Jung ZLLxx5004M, Jung ZLLHS4 and Gira 2435-10
Gira does unfortunately not seem to offer firmware updates for their wall transmitter 2430-100 (which is very similar to the Jung ZLLxx5004M) and the update file for the Jung wall transmitter does not work for Gira (probably because the Gira wall transmitter only has 6 buttons instead of 8 on the Jung).
- Sengled devices
Not all manufacturers make their updates available, you can watch for new additions in [zigbee-OTA Releases](https://github.com/Koenkk/zigbee-OTA/releases), which, if available, include the changes in these new updates.

To check whether your specific device supports OTA updates via Zigbee2MQTT, go to the supported devices page, click on your device and look for the _OTA updates_ section.

## Automatic checking for available updates

Your zigbee devices can request a firmware update check. Zigbee2MQTT obliges this, and will automatically check if updates are available for your devices.
Your Zigbee devices can request a firmware update check. Upon reception of such a request, Zigbee2MQTT will automatically check if an update is available and reply to the device accordingly.

The update state will be published to `zigbee2mqtt/[DEVICE_FRIENDLY_NAME]`, example payload: `{"update": {"state": "available"}}`.
The possible states are:

- `available`: an update is available for this device
- `updating`: update is in progress. During this the progress in % and remaining time in seconds is also added to the payload, example: `{"update": {"state": "updating","progress":13.37,"remaining": 219}}`.
- `idle`: no update available/in progress
- `available`: An update is available for this device
- `updating`: Update is in progress. During this the progress in % and remaining time in seconds is also added to the payload, example: `{"update": {"state": "updating","progress":13.37,"remaining": 219}}`.
- `idle`: No update available/in progress

To protect privacy it is possible to limit how often third party servers may be contacted. You can set the minimum time that should pass between two firmware update checks, in minutes. The default is 1440 minutes (1 day). Here it is set to check at most every two days:
You can set the minimum time that should pass between two firmware update checks, in minutes. The default is 1440 minutes (1 day). Here it is set to check at most every two days:

```yaml
ota:
update_check_interval: 2880
```

It is also possible to completely ignore these device-initiated requests for updates checks by modifying the configuration.yaml file. In the example below, only manual firmware update checks will be possible:
It is also possible to completely ignore these device-initiated requests for updates checks by modifying the `configuration.yaml` file. In the example below, only manual firmware update checks will be possible:

```yaml
ota:
disable_automatic_update_check: true
```

_NOTE: there is also a property `update_available` which is deprecated_.

## Manually check if an update is available

To check if an update is available for your device send a message to `zigbee2mqtt/bridge/request/device/ota_update/check` with payload `{"id": "deviceID"}` or `deviceID` where deviceID can be the `ieee_address` or `friendly_name` of the device. Example; request: `{"id": "my_remote"}` or `my_remote`, response: `{"data":{"id": "my_remote","update_available":true},"status":"ok"}`. For battery powered end-devices you may need to trigger them by e.g. pushing a button right before checking for an OTA.
To check if an upgrade is available for your device send a message to `zigbee2mqtt/bridge/request/device/ota_update/check` with payload `{"id": "deviceID"}` or `deviceID` where deviceID can be the `ieee_address` or `friendly_name` of the device. Example; request: `{"id": "my_remote"}` or `my_remote`, response: `{"data":{"id": "my_remote","update_available":true},"status":"ok"}`. For battery powered end-devices you may need to trigger them by e.g. pushing a button right before checking for an OTA.

## Update to latest firmware
### Downgrade

Once an update is available you can update it by sending to `zigbee2mqtt/bridge/request/device/ota_update/update` with payload `{"id": "deviceID"}` or `deviceID` where deviceID can be the `ieee_address` or `friendly_name` of the device, example request: `{"id": "my_remote"}` or `my_remote`. Once the update is completed a response is send, example response: `{"data":{"id": "my_remote","from":{"software_build_id":1,"date_code":"20190101"},"to":{"software_build_id":2,"date_code":"20190102"}},"status":"ok"}`.
Same as above, but send the message to `zigbee2mqtt/bridge/request/device/ota_update/check/downgrade` instead.

An update typically takes +- 10 minutes. While a device is updating a lot of traffic is generated on the network, therefore it is not recommend to execute multiple updates at the same time.
## Update firmware

## Using the IKEA TRADFRI test server
When an update is available for your device, you can upgrade it by sending a message to `zigbee2mqtt/bridge/request/device/ota_update/update` with payload `{"id": "deviceID"}` or `deviceID` where deviceID can be the `ieee_address` or `friendly_name` of the device, example request: `{"id": "my_remote"}` or `my_remote`. Once the update is completed a response is send, example response: `{"data":{"id": "my_remote","from":{"software_build_id":1,"date_code":"20190101"},"to":{"software_build_id":2,"date_code":"20190102"}},"status":"ok"}`.

If IKEA TRADFRI devices are rejecting OTA updates, it is possible the OTA server is providing a corrupt file. The firmwares published on the IKEA **test** server can be used. In most cases, this is not needed and will result in slower / no OTA updates as the test server is not kept up to date. You can instruct Zigbee2MQTT to use the test server by adding the following to your `configuration.yaml`.
::: tip TIP
An update typically takes 10-20 minutes (although some devices may take a lot longer). While a device is updating a lot of traffic is generated on the network, therefore it is not recommended to execute multiple updates at the same time, and ideally to update while the network is less in-demand.
:::

**WARNING: Use at your own risk!**
### Downgrade

```yaml
ota:
ikea_ota_use_test_url: true
```
Same as above but send the message to `zigbee2mqtt/bridge/request/device/ota_update/update/downgrade` instead.

## Local OTA index and firmware files

OTA Index file is a list of firmware images available on a particular server. When checking if an update is available, Zigbee2MQTT determines current hardware and firmware version for a particular device, and then searches for a suitable upgrade image in the index file. Some vendors (such as IKEA Tradfri, Ledvance, Salus, Ubisys) use their proprietary index files, but the most of the devices use [Zigbee-OTA](https://github.com/Koenkk/zigbee-OTA) firmware repository with a [main index file](https://github.com/Koenkk/zigbee-OTA/blob/master/index.json).
An OTA index file is a list of firmware images available in designated locations. When checking if an update is available, Zigbee2MQTT determines current hardware and firmware version for a particular device, and then searches for a suitable upgrade image in the index file. Zigbee2MQTT uses the [Zigbee-OTA](https://github.com/Koenkk/zigbee-OTA) firmware repository with contains the [upgrade index file](https://github.com/Koenkk/zigbee-OTA/blob/master/index.json), and the [downgrade index file](https://github.com/Koenkk/zigbee-OTA/blob/master/index1.json).

Sometimes it is necessary to add a firmware image that is not on the main index. This could be helpful when developing a DIY device, or install a test/alternate image for a mass-produced device. In this case user can supply Zigbee2MQTT with an alternate index file, located locally or on a web server. This index file will point Zigbee2MQTT to the firmware image files. Records in the override OTA index file will override corresponding records in the main index, so that it is possible to alter the image for a particular device type.
Sometimes it is necessary to add a firmware image that is not in that repository. This could be helpful when developing a DIY device, or install a test/alternate image for a mass-produced device. In this case you can supply Zigbee2MQTT with an alternate index file, located locally or on a web server. This index file will point Zigbee2MQTT to the firmware image files. Records in the override OTA index file will take precedence over the records in the Zigbee-OTA repository, so that it is possible to alter the image for a particular device.

```yaml
ota:
zigbee_ota_override_index_location: my_index.json
```

Local index file is searched in the configuration directory (next to `configuration.yaml`). The file name could be also a full path to the file, taking into account that host file system may not be available when running Zigbee2MQTT inside a docker container. Alternatively, Zigbee2MQTT supports index files located on a remote HTTP(s) server. In this case `zigbee_ota_override_index_location` key should be an URL of the index file.
A local index file is searched in the data directory (next to `configuration.yaml`). The file name also could be a full path to the file, taking into account that the host file system may not be available when running Zigbee2MQTT in a virtualized environment (Docker, etc.). Alternatively, Zigbee2MQTT supports index files located on a remote HTTP(s) server. In this case `zigbee_ota_override_index_location` should point to the URL of the index file.

The override OTA index file shall have the same structure as the [main index file](https://github.com/Koenkk/zigbee-OTA/blob/master/index.json). To create the index file it is possible to use [add.js](https://github.com/Koenkk/zigbee-OTA/blob/master/scripts/add.js) script (follow instructions [here](https://github.com/Koenkk/zigbee-OTA)). Correct image location and image URL as necessary.
```yaml
ota:
zigbee_ota_override_index_location: https://example.com/ota/my_index.json
```

The override OTA index file shall have the same structure as the [Zigbee-OTA index file](https://github.com/Koenkk/zigbee-OTA/blob/master/index.json).

For local files, only image location is required through `url` (either a full path to the image file, or relative to the Zigbee2MQTT data directory). Zigbee2MQTT can derive the rest from the files themselves:

```json
[
{
"url": "./path/to/my/image.ota"
}
]
```

Firmware files can be located either on a web server, or on the local file system. In this case `url` field in the index file entry shall be either a full path to the image file, or relative to the Zigbee2MQTT configuration directory. In case of local image file, index entry can be simplified to only 'url' field. Other fields are still allowed, but if omitted corresponding information (firmware version, image type, manufacturer ID, etc) is read from the image file.
For hosted files, on top of `url`, all required metadata must be provided (`imageType`, `manufacturerCode`, `fileVersion`, all expected to match that of the file at `url`):

```json
[
{
"url": "HelloZigbee.ota"
"url": "https://example.com/path/to/my/image.ota",
"imageType": 1,
"manufactureCode": 1001,
"fileVersion": 321
}
]
```

Normally Zigbee2MQTT compares current device firmware with available images version, and allows flashing only firmwares with `fileVersion` that is higher than current. To force Zigbee2MQTT to use arbitrary version a `force` field can be used:
See [Zigbee-OTA README](https://github.com/Koenkk/zigbee-OTA/tree/master?tab=readme-ov-file#notes-for-maintainers--developers) if an image requires extra metadata.

Normally Zigbee2MQTT compares the current device's firmware version with the version of the available image, and allows flashing only if `fileVersion` is higher than the current one for upgrades, or lower for downgrades. To force Zigbee2MQTT to use an arbitrary version you can set `force` to `true`:

```json
[
Expand All @@ -111,10 +118,38 @@ Normally Zigbee2MQTT compares current device firmware with available images vers
]
```

Please note, even though Zigbee specification basically allows firmware version downgrade, some of the devices may reject older firmwares. This cannot be forced from Zigbee2MQTT side.
::: tip TIP
Even though Zigbee specification allows firmware downgrading, some devices may reject older firmware versions. Additionally, updating to a firmware of same version is not supported by Zigbee specification. This cannot be forced by Zigbee2MQTT.
:::

## Troubleshooting

- `Device didn't respond to OTA request` or `Update failed with reason: 'aborted by device'`: try restarting the device by disconnecting the power/battery for a few seconds and try again, make sure to activate the device by pressing a button on it right before sending the update request.
- For battery powered devices make sure that the battery is 70%+ as OTA updating is very power consuming. Some devices check for a minimum battery level prior to updating and refuse to update.
- Make sure your log level is set to "info" - when set to warning - the UI will not report the correct info.
- `Device didn't respond to OTA request` or `Update failed with reason: 'aborted by device'`: try restarting the device by disconnecting the power/battery for a few seconds, then try OTA again, make sure to activate the device by pressing a button on it right before sending the update request.
- For battery powered devices make sure that the battery is 70%+ as OTA updating is very power consuming. Some devices check for a minimum battery level prior to updating and will refuse to update if too low.
- Make sure your log level is set to `info`. When set to `warning` or `error`, frontend will not report some messages indicating the current OTA status.

## Advanced configuration

You can increase or decrease the default speed (the minimum delay between two chunks) at which Zigbee2MQTT responds during the update process to send chunks of images. The default is 250ms. A higher speed will result in faster OTA updates, but may require a far more stable network to avoid issues, crashes. A lower speed will result in slower OTA updates, but may noticeably increase reliability, and overall network stability.

```yaml
ota:
image_block_response_delay: 250
```

Minimum: 50

You can increase or decrease the size of image chunks sent by Zigbee2MQTT during the update process. The default is 50 bytes. The behavior is similar to `image_block_response_delay` regarding the effect of higher or lower values.

_Note that for some known combinations (manufacturer/version/etc.), expected sizes will always override this setting to ensure they work correctly._

```yaml
ota:
default_maximum_data_size: 50
```

Minimum: 10, Maximum: 100

::: warning ATTENTION
Some devices will refuse higher sizes than 50 bytes, some 64 bytes. Several network parameters must also be taken into account to derive this value. It is not recommended to change this setting unless you have a very good reason (instructed to do so in an issue for example).
:::