ZHA Firmware Update Guide

I recently needed to update a few switches from an older firmware to the latest via ZHA on Home Assistant and couldn’t find a direct guide, so I wanted to contribute to the community on how I accomplished it. Please realize that I’m intentionally making this a “guide for dummies” to remove any ambiguity for non tech-savvy folk, and forgive me for some of the explanations that delve deeper into simple tasks that some of us already know.

ZHA supports OTA (Over the Air) updates for Inovelli switches, but this needs to be enabled via configuration YAML changes. From your HA install, navigate to “File editor” and ensure you’re editing the configuration.yaml file. Insert the following:

      inovelli_provider: true
      otau_directory: /config/zigpy_ota

Indentation matters with YAML, so be sure you copy and paste the literal text from above.

Then click the “Browse Filesystem” button at the top of the File editor UI, and click “New folder”. In the prompt, type zigpy_ota

What you’ve done, at this point, is configured ZHA to enable OTA updated for Inovelli switches and scan the OTA folder for matching binaries to update. All we need now is the binary to update to!

For 2.15, this is currently found in the beta folder of the inovelli github repository. While this is marked as beta, Inovelli is currently shipping new switches with this firmware (and I’m running several of them without problems) so it can be considered “production” at this point.

For firmware 2.15, use the following link: 2.15. Click “Download raw file” from the Github page, which will retrieve a file named VZM31-SN_2.15.ota

Back in Home Assistant’s File Editor, navigate to the newly created folder named zigpy_ota by clicking the Folder icon at the top and selecting the directory named that. Then click the “Upload file” icon from the same page, and select the file you downloaded from Github earlier.

Now you need to restart Home Assistant to effectively reboot ZHA to reconfigure and scan for the new OTA files for your switch. You can do this via the “Settings → System → Corner Power Icon → Restart Home Assistant”

HA will start back up and the OTA won’t happen immediately. Time for a cuppa. Eventually, your switch will start showing the firmware progress LED (displayed as a slow blink effect), assuming your switch has the Firmware progress LED setting enabled (it is by default). This update takes time: while the file is less than a megabyte, zigbee is a slow transmission protocol; give the switch around 30 minutes to update.

After the LED on the switch is done flickering a progress bar, check/refresh the device in ZHA. To check the version string, click the “hamburger” icon next to the Reconfigure text on the device page and select Manage zigbee device.

Pick the Basic “Cluster” from the dropdown that appears, and select the sw_build_id attribute. Click Read. If the device updated successfully, you should see 2.15.

At this point, your switch is on the most recent firmware. Congrats! However, you may be missing some of the new entities which recent firmwares exposes (for example, Led scaling mode). There may be a better way, but I personally just chose to remove my switches from ZHA by clicking the same “hamburger” icon mentioned above and selecting “Remove”, and then re-adding the device via ZHA (like you originally did to add it). This will cause HA to reinterview the switch and generate all new parameters as entities. This may effect existing automations/etc, so be aware before doing so (I’m not entirely sure on this part).

I hope this helps! If screenshots/etc would help anybody, or if any part is unclear, please respond to this post and I’ll gladly edit/update with additional clarification and steps and images. Happy ZHA switching!

FYI, these are enabling 2 ways of handling the updates. If you want automatic OTA updates that grab the firmware directly from Inovelli, that first line enables them. If you’re looking to push a file locally, you can leave that out or put it in but set it to the default of “inovelli_provider: false” so you don’t have your switches automatically update when you’re not expecting it. Local pushes just need that otau_directory parameter set.

You can also kick off the update sooner post-restart if you want. Grab the IEEE from the device page, go to developer tools and issuing the following to prompt it to check immediately -

service: zha.issue_zigbee_cluster_command
  ieee: "xx:xx:xx:xx:xx:xx:xx:xx"
  endpoint_id: 1
  cluster_id: 25
  cluster_type: out
  command: 0
  command_type: client
    - 0
    - 100
1 Like

I was literally searching for this last night as I was running into an issue that looks like was resolved by newer firmware (I was still on the original shipping firmware).

I took a few screenshots along the way that I think might help less technical users. After work today I’ll review & clean up so you can add them if you want.

The one thing that might be good to add is that in HA the firmware version is given in hex (I assume, didn’t actually try converting it) and not decimal; ie, HA will show 0x0102020f for firmware and not 2.15.

Yup. I’d read reports from other users that the current auto OTA update won’t pull 2.15 since it resides in the beta directory at the moment, so included the manual steps for download and placement on HA. I also wanted the inovelli_provider to be true, as I’m a weirdo who is fine with auto updates surprising me once they release. Thanks for describing this better, though, since others may not prefer that.

I also did this, and it did seem to work… the args on that payload are apparently deprecated and HA throws warnings in logs, but it did work!

The method I outline for retrieving the build_id param in the cluster bindings actually will show the decimal version number, FYI. But yup; the ZHA device page will show that hex.

I also don’t mind adding some screenshots of my own, if they help anybody. But if you already have some handy, I’d be happy to toss them into the OP on this thread! Thanks!

When I get some time I should grab the updated params and update the docs too, but yeah that’s what’s listed on the integration page :slight_smile:

Hello @justinlindh,

Thanks for this write-up. It inspired me to look into what firmware I had on my switches. Turns out, my 7 switches are running 2.11.

As a result, I followed your instructions step-by-step. Unfortunately, I ran into some hiccups. First, for months now I have had the OTA update line in the YAML set to true. However, in that time I never received and OTA update. Naturally, I tried your method of pushing them locally (download file, restarting HA, etc.). After some time, the updates were never pushed. Then I tried @chack 's solution which did initiate the update as I saw the visual prompts. Despite the warnings in the logs about the args, the updates appear to have completed.

However, I am still seeing a 2.11 firmware version even after restarting and shutting HA down completely. Would you have any idea as to what I am overlooking here? It is likely something so simply.

Thanks in advance.

[Update 9.4.23]
After some time, the updates began pushing automatically - albeit at the same time. I believe this flooded my zigbee network which resulted in numerous failures. I kept trying to cluster command approach one at a time, and eventually this method did work.

Apologies, but I just haven’t run into that specific issue yet, so I’m not entirely sure. Generally, that’s where I’d start enabling debug logging.

Reading your update, though, sounds like you were eventually able to get it working. Awesome! I hadn’t considered too many simultaneous updates to be something that could be a problem, but I’ve only updated 2 switches at a time so far. Good to know, though, since future firmware pushes might repro that same issue for me and others!

Thank you for the guide, however I would prefer to just have the update done automatically. Is there any reason 2.15 is still in beta if it is being installed in production devices?

Following up on the dev tool update code, the following is the way to format the cluster command for updating without getting the error about args being deprecated.

PLEASE NOTE - this will only work for the VZM31-SN and the file version lines up with 2.15 (only expect the last 2 characters to change for other versions), the VZM35-SN fan switch as an example uses a different image_type field. I also haven’t tested if this lets you check for a specific upgrade that may let you pick a higher version but not the newest (older versions weren’t supported by zigpy last I checked, it’s part of the firmware update validation).

service: zha.issue_zigbee_cluster_command
  ieee: "xx:xx:xx:xx:xx:xx:xx:xx"
  endpoint_id: 1
  cluster_id: 25
  cluster_type: out
  command: 0
  command_type: client
    payload_type: 0x00
    query_jitter: 100
    manufacturer_code: 4655
    image_type: 257
    new_file_version: 16908815
1 Like