How to update the firmware of ZigBee devices using Home Assistant

published Jan 15, 2023, last modified Jan 18, 2023

If your Home Assistant system uses ZHA (ZigBee Home Automation) this is how you do it.

How to update the firmware of ZigBee devices using Home Assistant

Configuration

Your Home Assistant ZHA subsystem must be configured for over-the-air updates (OTA).

  • Ensure you have declared the OTA path in the configuration setting zha/zigpy_config/ota/otau_directory in the configuration.yaml file.
    • This path should generally reside inside the configuration directory of Home Assistant (where your configuration.yaml file is).
    • Home Assistant will use this as scratch directory for auto-downloaded firmware, and you'll use it for manually-uploaded firmware.
    • Restart Home Assistant if you changed this setting.
  • If it does not exist yet, create the OTA directory in your Home Assistant machine.
    • Make sure that Home Assistant can both read from and write to this directory (e.g. make the Home Assistant user the owner of the directory).
    • In container / HASS OS setups, ownership may be a bit harder to determine.  In these cases, you should simply make the directory owned by the same numeric user ID as the parent directory, or use the Home Assistant file manager add-on to make it.

Here is a sample of the setting — a snippet from my own configuration.yaml file:

zha:
  zigpy_config:
    ota:
    otau_directory: /var/lib/assistant/ota
      ikea_provider: true

Preflight check

You will want to check the firmware version before you do this.

  • Open the device information page.
    • Go to Settings -> Devices -> Devices tab then click on your device in the list.
  • Click on the three dots menu button, then Manage ZigBee device.
  • On that screen, select the Basic cluster, and from the dropdown on the Attributes tab, select sw_build_id.
  • Push the Read attribute button.  You'll see a new Value pop up.  Write it down.
  • Now select the Ota cluster from the Clusters dropdown.  Then, from the Attributes of the selected cluster dropdown , select current_file_version.
  • Push the Read attribute button.  You'll see a new Value pop up.  Write it down.

With this information written down, you may proceed.

The process

  • Download the updated firmware of your device from the deconz site.
  • Copy the updated firmware file into the OTA directory using a file transfer program.  Restart Home Assistant after that (it is not clear to me whether Home Assistant picks up newly-uploaded files without a restart).
  • Open the Developer Tools on the left side panel of your Home Assistant, and jump to the Services tab.
  • In the text box of that screen, copy and paste the following text:
service: zha.issue_zigbee_cluster_command
data:
ieee: <device IEEE>
  endpoint_id: 11
  cluster_type: out
  command_type: client
  cluster_id: 25
  command: 0
  args:
    - 0
    - 100
  • Now replace the <device IEEE> in the text box with your device's IEEE address.  This information is available on the device information page — on that screen, click ZigBee info — the IEEE will reveal itself.
  • Push the Call service button.
  • Wait; the update will take roughly 5 minutes.
    • You'll be able to check updates on the device information page — you'll see Attribute updated events every once in a while on the Logbook section.
    • You can also see the progress in much more verbose form as follows:
      • Tail the Home Assistant log (the method depends on your type of Home Assistant setup)
      • From the Developer tools panel, Services tab, execute the logger.set_level service with the following code:
        service: logger.set_level
        data:
          zigpy.zcl: debug
        
  • Eventually the device will be updated.
    • When the device does, it will restart first, then rejoin your ZigBee network.
    • If the device has routing capabilities, other devices routed through it will be unavailable briefly, then they will rejoin the network as well.

Postflight check

Repeat the preflight check.  The values you collected first should have changed.  In particular, the sw_build_id should have changed to the version advertised by the page where you downloaded the firmware update.