> For the complete documentation index, see [llms.txt](https://apps.developer.homey.app/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://apps.developer.homey.app/wireless/z-wave/z-wave-firmware-updates.md).

# Z-Wave Firmware Updates

Homey supports the Z-Wave Firmware Update Metadata Command Class. With this command class it is possible for Homey to update the firmware that is running on Z-Wave devices. Your app can provide firmware files, and Homey takes care of installing the firmware to the device.

{% hint style="warning" %}
Z-Wave firmware updates are supported since Homey firmware v13.2.0, and is available for Homey Pro (Early 2023, 2026, mini), Homey Self-Hosted Server, and Homey Cloud. You need at least Homey Mobile App v9.10.0 or higher in order to start updates.
{% endhint %}

### Getting Started <a href="#getting-started" id="getting-started"></a>

You can add firmware updates to your drivers. To do this, you'll need to gather the firmware files for your devices and create a `/drivers/<driver_id>/driver.firmware.compose.json` file. The `driver.firmware.compose.json` file contains metadata for Homey to be able to select the correct update for your devices.

For more information on the Z-Wave Firmware Update Metadata Command Class, refer to the [Z-Wave specification](https://z-wavealliance.org/development-resources-overview/specification-for-developers/).

{% hint style="info" %}
The `homey app driver firmware` Homey CLI command will take you through creating or updating the `driver.firmware.compose.json` file. (Requires `homey` v4.3.0 or higher.)
{% endhint %}

#### File Structure <a href="#file-structure" id="file-structure"></a>

The `driver.firmware.compose.json` contains the following fields:

* `updates`: A list of all firmware updates for the devices of this driver.
* `wakeInstruction`: A description of how a Sleepy End Device (e.g battery-powered devices) can be made active by the user to start the firmware update. This field is not required for non-sleepy devices (takes a [Translation Object](https://apps.developer.homey.app/~/changes/1149/the-basics/app/internationalization)).

**Updates**

Each item in `updates` describes a firmware update for specific Zigbee devices. Every update contains the following fields:

* `version`: The version of this firmware in `<major>.<minor>.<patch>` format.
* `changelog`: A brief description of the changes in this update (takes a [Translation Object](https://apps.developer.homey.app/~/changes/1149/the-basics/app/internationalization)).
* `device`: An object with the `manufacturerId`, `productTypeId` and `productId` combination that identifies the target device(s) for this update.
  * A driver can target multiple devices (see [Z-Wave Manifest](/wireless/z-wave.md#manifest)). This field allows making a firmware update only available for a specific subset of those devices.
  * Add a `hardwareVersion` field to make an update available for specific hardware versions of the device. When added, the field must match the device's reported hardware version through the Version Command Class.
* `files`: A list of firmware update files included in this update.
  * In most cases, you'll only have a single file for your update.
* `applicableTo`: A semver comparison string that determines whether the current version of the device can install this update. (E.g. `>1.2.3`).

#### Update Files

Each entry in `updates[].files` describes one firmware file. The following metadata fields are required for each file:

* `targetId`: The target chip of this file, if you have only a single file this is `0`.
* `size`: The file size in bytes.
* `name`: The file name. The file itself must be stored in `/drivers/<driver_id>/assets/firmware/<file name>`.
* `integrity`: A hash of the file in the format `<hash_name>:<hex_encoded_hash>`.
  * The following hash types are supported: `sha256`, `sha384`, `sha512`, `sha512-256`, `sha3-256`, `sha3-384`, `sha3-512`, `blake2b512`, `blake2s256`.

{% hint style="info" %}
The `homey app driver firmware` command will automatically fill in the `size`, `name`, and `integrity` fields for you. You'll have to provide the file's `targetId`.
{% endhint %}

Optionally you can add the following field to limit where a firmware update is available:

* `region`: The Z-Wave region where this file should be applied. If not set, it is applied globally.
  * Possible values are:
    * `ANZ`: Australia/New Zealand (919.8 MHz / 921.4 MHz)
    * `CN`: China (868.4 MHz)
    * `EU`: Europe (868.4 MHz / 869.85 MHz)
    * `HK`: Hong Kong (919.8 MHz)
    * `IL`: Israel (916 MHz)
    * `IN`: India (865.2 MHz)
    * `JP`: Japan (922.5 MHz / 923.9 MHz / 926.3 MHz)
    * `KR`: Korea (920.9 MHz / 921.7 MHz / 923.1 MHz)
    * `RU`: Russia (869 MHz)
    * `US`: United States of America (908.4 MHz / 916 MHz)

{% hint style="danger" %}
Not providing the region when this is required can cause Homey to install an update to a device in the wrong region, which can make the device unusable in the user's region.
{% endhint %}

The firmware file that is provided by the Homey app, should be the file that can be directly transferred to the Z-Wave device. Homey does not do any pre-processing of the file before sending it to the device. Homey cannot validate that it is a proper firmware file, because Z-Wave doesn't have a specification-defined file format for firmware files.

{% hint style="info" %}
When you upload your Homey App, the firmware files are stored separately from your App. Only when Homey starts installing an update for a device, it will download the required files.
{% endhint %}

### Example

Putting everything together, a `driver.firmware.compose.json` file with a single update will look like this:

{% code title="/driver/\<driver\_id>/driver.firmware.compose.json" %}

```json
{
  "wakeInstruction": {
    "en": "Hold the internal button for three seconds."
  },
  "updates": [
    {
      "version": "1.3.0",
      "changelog": {
        "en": "- Fixes issue X\n- Adds feature Y\n- Deprecates feature Z"
      },
      "device": {
        "manufacturerId": 1234,
        "productTypeId": [1, 2],
        "productId": [3, 4]
      },
      "files": [
        {
          "targetId": 0,
          "size": 262144,
          "name": "AwesomeSensor_v1.3.4.bin",
          "integrity": "sha256:dac89981aeb5352a8ddce9fbb5ab3ad5bff88d17e2f7937cc90947301ccfedd2"
        }
      ]
    }
  ]
}
```

{% endcode %}

#### Firmware Version <a href="#firmware-files" id="firmware-files"></a>

Homey uses the Version Command Class to determine the device's current firmware version.

* **If the device supports `VERSION_ZWAVE_SOFTWARE_GET`:** The firmware version is derived from the `Application Version` field of the `VERSION_ZWAVE_SOFTWARE_REPORT`. The version is formatted as `<byte_1>.<byte_2>.<byte_3>`.
* **If the device only supports `VERSION_GET`:** The firmware version is derived from the `Application Version` and `Application Sub Version` fields of the `VERSION_REPORT`. The patch field is always treated as `0`, resulting in the format `<application_version>.<application_sub_version>.0`.

#### Firmware Files <a href="#firmware-files" id="firmware-files"></a>

Homey Apps are responsible for delivering the correct firmware files to the appropriate devices. Before shipping a firmware update in your Homey App, ensure the following:

* **Device targeting:** Verify that each firmware file is mapped to the correct device(s). Delivering a firmware file to an incompatible device can cause irreversible damage or render it unresponsive.
* **End-to-end testing:** Test the full update flow on the intended physical hardware. Confirm that Homey can correctly initiate, transfer, and complete the firmware update process.
* **Validation before release:** Do not add a firmware update to your app until both of the above have been verified. Untested firmware updates should never reach end users.

## Update Selection

Homey will select the firmware for your device based on the following:

1. The `updates[].device` field must match the device's reported `manufacturerId`, `productTypeId`, and `productId`.
2. One of the files in an update should match the currently used Z-Wave region.
3. The device's current version should match the update's `applicableTo` field.

If multiple updates are found for the device, the update with the highest `version` field will be selected.

### Multiple Firmware Files

Some devices might require multiple firmware files for a single update (e.g. when it also needs to update the firmware of another chip in the device). If your device requires this, add multiple files to the update with different `targetId`s. Homey will automatically start sending a file for the next `targetId` after a previous one was completed.

### Update Failures <a href="#update-failures" id="update-failures"></a>

Firmware updates can fail. Homey considers an update failed in the following cases:

* **Explicit abort:** The device reports an error status during image transfer, actively aborting the update.
* **Stalled transfer:** The device stops requesting firmware chunks before the transfer is complete.
* **No reconnection:** The device fails to rejoin the Z-Wave network within the expected timeframe after a file has been fully transferred.

In all failure cases, the user will be notified via the firmware update screen and can retry the installation.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://apps.developer.homey.app/wireless/z-wave/z-wave-firmware-updates.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
