Skip to content

Firmware update capability for OH Zwave binding#2024

Open
apella12 wants to merge 15 commits intoopenhab:mainfrom
apella12:firmware-update
Open

Firmware update capability for OH Zwave binding#2024
apella12 wants to merge 15 commits intoopenhab:mainfrom
apella12:firmware-update

Conversation

@apella12
Copy link
Copy Markdown
Contributor

Going to turn to draft. Putting out there for comment. I was primarily a challenge to see if I could get this done (with AI help). The Zwave-js app uses the file input. The is no central source that I know of, just files spread across MFG websites.

This is true to the Zwave spec and Tests work so far but relies on XML modification to get the firmware file into OH UI, so won't work with current jar build process (changes will get overridden). One thought would be to add the firmware configuration like the battery when to ZW DB is downloaded for devices that support FirmwareUpdate. There might be other options too. I have been advised that the Thing action is not input capable.

Other limitations are that I have only tested with .gbl files and zooz devices

@apella12 apella12 marked this pull request as draft March 18, 2026 01:14
@cdjackson
Copy link
Copy Markdown
Collaborator

Thanks. This would definately be cool to have, and I've only had a very quick look at this, but it doesn't look like this follows the OH firmware update concept? It looks like you're just using ZWave specific actions rather than the firmware update concept which I think is a bad idea as it means ZWave would be different to other bindings.

@apella12
Copy link
Copy Markdown
Contributor Author

Understand. I don't have any devices that use the OH firmware update concept to follow that logic. I did glance at your Zigbee fileProvider and it seems that it relies on a central DB (could be wrong). In ZWave the firmware files I have found are spread over the MFG sites. One example is Zooz (I have a lot of these), but aeotec has a similar support page.

Anyway, used the Zwave-js logic that starts with a file import (target 0 is the Zwave chip & I limited to that in the code above).
firmware file zwave-js

As noted, it works (with the testing so far), but I needed to modify the device XML, so is not aligned with the OH ZW DB update process (at least now anyway). Originally, I had hoped the Thing actions could be modified to pick up the file as that could be cleaner, but probably not sellable to the OH central committee as an alternative

@cdjackson
Copy link
Copy Markdown
Collaborator

It's not an issue with where the firmware comes from - the point is that there is a workflow for doing firmware updates, and the UI supports this workflow. There are 2 parts to the process - one is a firmware provider - this is just a class that provides firmware - it links thing types to firmware files, and when the UI/core asks for firmware, it provides the stream. It doesn't have to be backed by any specific repository - it could just use local files on the file system if you wanted, but there still needs to be a firmware provider.

Then there is additional functionality in the Thing itself to support the firmware update and status feedback to the UI.

I personally don't think it's a good idea to bake your own system and bypass the OH firmware upgrade system and just use thing actions.

@apella12
Copy link
Copy Markdown
Contributor Author

I did try for a while with the Firmware provider, but had issues (probably of my lack of knowledge) and I just wanted to get it working. I could take another look. Here is the AI response
firmwareProvider.txt
to "What was the problem I was having with the firmware provider?"
As to the OH structure, it seemed overly engineered to just update firmware. Maybe I'll just PR the ZWave part and leave the integration into OH for the future? That at least moves it closer.

@apella12
Copy link
Copy Markdown
Contributor Author

  1. I changed the way the firmware is loaded by extending the userdata/zwave folder. Much less complex that the config option. Still requires user to go and get it from MFG site and put it in the node's directory. 2) Added the download device firmware per the spec but couldn't test as none of my devices support it. There is a note in the docs that few devices support it, so left action as Hidden. 3) Ran more tests and made changes based on the issues primarily with battery devices. Have used hex, gbl and zip files across a half dozen zooz devices. 4) Didn't mean to disrespect the OH firmware update. ZW firmware seems more of a break-fix (or one-off) than a lifecycle with alerts about updates, etc.. 5) Still need review more, but largely in place (for the ZW binding part anyway)

@cdjackson
Copy link
Copy Markdown
Collaborator

I think it's fine to put the firmware in a local directory - no problem there, but you still need to support the FirmwareProvider I think - otherwise the UI doesn't know about the firmware and can't provide info to the user to allow them to manage the update.

My point about the OH firmware update lifecycle is that OH defines a mechanism to allow the user to start/stop firmware updates and to have visibility of what's happening. It's independent to the ZWave firmware update - the point is that in order to provide the same UX, you need to support these various interfaces for both firmware provision (FirmwareProvider) and the actual firmware update itself (FirmwareUpdateHandler).

@apella12
Copy link
Copy Markdown
Contributor Author

I do understand (sort of). However, I think the same UX experience ship has sailed with the plethora of rule languages now available for OH rules and the marketplace addons that have no real consistency requirement, except that they work for a range of OH versions. When I look at the forum today the issues mostly fall into those categories.
My efforts so far have been mainly to get the ZWave firmware update working consistently and fit into the binding framework. The specs manage to be both repetitive and unclear in some cases. I still have got to try some tests with security devices. So far, the firmware updates have all been unsecured.
My thinking is the ZW user is going to have to go out and get a firmware file. So, some of the lifecycle elements like "New Firmware Available" are kind of redundant. A manual start to the upgrade also seems natural in that situation. Also, although I have actually upgraded firmware a time or two, most of the tests are "upgrading" the same version that is already there. I did add a progress % on the UI page since it takes 5-15 minutes. I haven't tried to program a "Stop" the spec says to send a bad CRC. Most devices do not seem to advertise resume but need to start over. Bottom line it may be tricky to integrate/translate the OH firmware update handler features into how the Zwave spec handles those options, but I'll look.
The last thought is I do this when the weather is bad and we are finally getting Spring weather so will have more options to be outside (yard needs work).

@apella12
Copy link
Copy Markdown
Contributor Author

I need to do some more tests (it works, but there are AI code suggestions that needs to be reviewed). It now connects to the OH firmware framework.
Firmware updates go smoothly with direct connections but are troublesome over distances (3+ hops). There is extra code to handle delays, offline statuses and missed messages that help, but add complexity.
OHintegration2026-03-28 182849
I'm still using the Thing action for testing but will hide that when finished. (The OH framework won't let me update if I'm already at version.)

@cdjackson
Copy link
Copy Markdown
Collaborator

cdjackson commented Mar 30, 2026 via email

@apella12
Copy link
Copy Markdown
Contributor Author

I think I did support the user facing OH firmware concept with the FirmwareProvider (implemented in ZwaveLocalFirmwareProvider) and FirmwareUpdateHandler (implemented in the ThingHandler). The firmware file was ported from ZWave-js firmware update .ts code since I thought that would be most applicable. Certainly, if there is OH code that does the same, that would be a good enhancement.

Anyway, no worries, I'll clean up a bit in the next day or so to help anyone in the future (to not have to recreate the ZWave Firmware CC from the Specs) and close for now. It was a good learning experience for me.

@cdjackson
Copy link
Copy Markdown
Collaborator

cdjackson commented Mar 31, 2026 via email

@apella12
Copy link
Copy Markdown
Contributor Author

apella12 commented Mar 31, 2026 via email

@apella12 apella12 marked this pull request as ready for review April 1, 2026 13:16
@apella12
Copy link
Copy Markdown
Contributor Author

apella12 commented Apr 20, 2026

Probably should have left PR as draft while testing, but don't see major changes now. Pretty consistent behavior. Did have a problem with one device type but tried with Zwave-js and had the same issue, so don't think it is the code. Otherwise, tested Zooz and Aeotec with varies formats to completion. I have a few more to run when I get time.
EDIT: attached is a log of the start and end sections plus a picture version of node 59. At a high level there is an update of the FirmwareMD CC, then the initial exchanges before the fragment. I cut out the in-between fragments and captured the end. After success, I run a ping and get the new firmware information.

Node 59-part1 Node 59-part2

toplog4-19.txt

apella12 added 15 commits April 20, 2026 17:14
Firmware Update First steps. Ported zwave-js firmwareUpdateMD CC and fit into OH Zwave.

Signed-off-by: Bob Eckhoff <katmandodo@yahoo.com>
Introduce end-to-end firmware update support: add FirmwareFile (parser/extractor for BIN/HEX/GBL/Aeotec EXE/ZIP) and ZWaveFirmwareUpdateSession (handles metadata, fragment preparation, transmission and status handling). Integrate into ZWaveThingHandler: import and load firmware files from the "firmwareFile" configuration, store pending firmware, start a firmware update session via the updated action, and route incoming events to the session. Rename and adjust rule action in ZWaveThingActions (firmwareMetaDataRequestGet -> updateLoadedFirmware) and update handler behavior/messages. Add unit tests for firmware file parsing and session handling and minor related updates to command class/network event usage and resource files. This enables uploading and applying firmware to nodes and provides logging/network events for progress and failures;

Signed-off-by: Bob Eckhoff <katmandodo@yahoo.com>
Add robust firmware update lifecycle and sleep management: introduce a MD report wait timeout (12s) and scheduling logic in ZWaveFirmwareUpdateSession, start the timeout only when the node is awake, and handle node awake events to (re)schedule the timeout. Track firmware update activity on ZWaveNode via firmwareUpdateInProgress to temporarily bypass normal sleep/backstop logic while an update is in progress, provide setFirmwareUpdateInProgress() and forceSleep() helpers, and ensure the node flag is set/cleared on session start, success, and failure. Replace direct awake toggling in the transaction manager with node.forceSleep() on transport timeouts. Also remove an old version/sleepability check from ZWaveThingHandler.

Signed-off-by: Bob Eckhoff <katmandodo@yahoo.com>
Add robust error handling and abort support for firmware updates. Introduced ZWaveFirmwareUpdateSession.abort(reason) to cleanly fail an active session and updated prepareFragments(...) to return a boolean, using failFirmwareUpdate(...) on errors so the caller can stop the session when fragmentation fails. When starting a new update, the handler now aborts any active session that would be superseded. Also made ZWaveFirmwareUpdateCommandClass tolerate too-short payloads by logging and notifying listeners (instead of throwing), avoiding uncaught exceptions and ensuring listeners receive error info.
Signed-off-by: Bob Eckhoff <katmandodo@yahoo.com>
…ation

Introduce firmware download support and make firmware update flows more robust.

- Add ZWaveFirmwareDownloadSession to download firmware from nodes supporting Firmware Update MD CC v5+ and persist to userdata/zwave/firmware/node-<id>.
- Add RuleAction and ThingActions entry to trigger firmware download from the UI/actions.
- Enhance ZWaveFirmwareUpdateSession: improved timeouts, status-report handling, progress events, duplicate GET resend logic, and bookkeeping for transmitted fragments.
- Extend ZWaveFirmwareUpdateCommandClass with helper to send MD_GET, handle MD_REPORT responses for download, and ensure versionMax restored after deserialization.
- Update ZWaveThingHandler to load firmware from userdata repository (single-file policy), start/abort upload/download sessions, refresh CC version before update, and report progress/failure details in thing status.
- Add ZWaveNetworkEvent.Progress state and forward progress updates to UI.
- Ensure firmware folders are created/deleted by ZWaveNodeSerializer and add helpers for firmware file detection.
- Minor fixes: wakeup payload handling in ZWaveNode and logging level tweaks.

These changes add untested download support (hidden until validated) and improve reliability and observability of firmware updates.

Signed-off-by: Bob Eckhoff <katmandodo@yahoo.com>
Overall these changes are largely formatting, simplification, and small behavior fixes to improve clarity and robustness of firmware update handling.
Signed-off-by: Bob Eckhoff <katmandodo@yahoo.com>
Add a local Z-Wave firmware provider and refactor firmware update handling and tests.

- Introduce ZWaveLocalFirmwareProvider to expose local firmware files from {userdata}/zwave/firmware/node-<id> to the openHAB firmware UI, including filename-based version extraction and supported extensions.
- Enhance ZWaveFirmwareUpdateSession: add inactivity timeout watchdog, improved transaction failure handling and resend logic, concurrent-safe maps and volatile fields, status/invalidation helpers, progress rewinding and stepped 5% progress publishing, initial 1% progress event on first fragment, and helper accessors for current progress/state.
- Wire firmware update integration into ZWaveThingHandler: implement FirmwareUpdateHandler, add ProgressCallback support, restore/clear progress across status transitions, map firmware events to user-visible status and localized failure callbacks, and publish firmware version property.
- Add i18n message for firmware update errors and update README with Thing Firmware documentation.
- Update and add unit tests for session behavior, progress reporting, inactivity timeout, and ThingHandler firmware progress/callback handling.

Basically these changes integrate with the OH firmware structure, except the user needs to retrieve the appropriate firmware from the MFG site (not provided by all MFG or for all devices. The rest of the changes were to address the issues with zwave radio traffic during relatively long firmware updates and alert the user to what is happening.

Signed-off-by: Bob Eckhoff <katmandodo@yahoo.com>
Add documentation and small refactors across firmware classes; simplify format detection/extraction in FirmwareFile and remove placeholder metadata getters. Make ZWaveFirmwareDownloadSession.handleEvent return a single boolean expression. Harden ZWaveFirmwareUpdateSession protocol handling: add isOutOfSequenceForwardRequest and implicit-ACK handling for higher-fragment GETs, adjust UPDATE_MD_STATUS handling and logging, and add Javadoc for enums/states/events and fragment logic. Ensure firmware report transactions are sent with maxAttempts=1 in ZWaveFirmwareUpdateCommandClass. Minor cleanup in ZWaveLocalFirmwareProvider and ZWaveThingHandler imports/formatting. Update unit tests to reflect behavior changes and add tests for out-of-sequence GETs and implicit ACK scenarios.

Signed-off-by: Bob Eckhoff <katmandodo@yahoo.com>
Remove the exposed rule action for uploading firmware and its i18n labels; centralize firmware-start logic and harden firmware update sequencing and progress reporting. Key changes:

- Removed updateLoadedFirmware RuleAction and its static wrapper from ZWaveThingActions and removed related i18n strings.

Overall this commit improves reliability and UX of firmware updates by making progress reporting deterministic, preventing race conditions, and simplifying the public actions surface.

Signed-off-by: Bob Eckhoff <katmandodo@yahoo.com>
Also add java docs and explanations for clarity. Spotless on files that were modified.

Signed-off-by: Bob Eckhoff <katmandodo@yahoo.com>
Removed some duplication that was introduced because I was testing with 2 identical Zstick powered (only one active, but the other could pickup messages). Also adjusted the progress to work with offline node events and cover another issue that arose with a very distant node. (over 15minutes to update)
Signed-off-by: Bob Eckhoff <katmandodo@yahoo.com>
Significant refactor and robustness improvements to the Z-Wave firmware update session:

- Reworked state machine and start/abort flow; session now explicitly requests metadata on start and tracks active state.
- Introduced FirmwareMetadata record and revised FirmwareFragment handling; improved parsing of MD_REPORT (supports legacy V1/V2 and V3+ layouts).
- Consolidated status/request enums to use values from ZWaveFirmwareUpdateCommandClass and removed legacy internal enums.
- Improved handling of UPDATE_MD_GET: out-of-sequence detection, implicit ACK inference, duplicate GET suppression, and safer retry/resend logic.
- Better transaction-failure handling: detect failed firmware-related transactions and retry or fail the session according to state and timing windows.
- Added helpers for building MD request payloads, mapping request flags, fragment preparation and send logic, and more explicit timeout scheduling/cancellation.
- Adjusted timeout defaults and documented protocol-driven timing (inter-frame delay, fragment size fallback).

These changes aim to improve protocol compliance, resilience to transient link issues and multi-hop behavior, and make metadata handling more robust. Corresponding tests were updated to reflect new behavior.

Signed-off-by: Bob Eckhoff <katmandodo@yahoo.com>
Remove the inactivity watchdog from ZWaveFirmwareUpdateSession and simplify session timeout/ack handling (clean up constants, generation counters, schedule/cancel methods, and related calls). Improve handling/comments around UPDATE_MD_GET implicit ACKs and move/introduce getSteppedTransferProgressPercent. Refactor ZWaveThingHandler firmware flow: add robust repository loading and single-file validation, parse firmware file contents into pending fields with clear user-facing errors, relocate and tidy progress/callback helper methods, and adjust cancel/isUpdateExecutable behavior. Update tests to match the new session behavior and formatting; remove inactivity-related tests. Also drop an unused import in ZWaveController.

Signed-off-by: Bob Eckhoff <katmandodo@yahoo.com>
Delete the untested ZWaveFirmwareDownloadSession and remove the hidden downloadFirmwareFromNode action. Refactor ZWaveThingHandler to drop download session usage and significantly rewrite command handling and event routing (command conversion, channel lookup, message sending, configuration/association updates, state event handling, wakeup/node status handling). Update ZWaveFirmwareUpdateSession to schedule a version refresh after device restart and tidy up unused prepare-report state/enum entries. Improve local firmware filename version parsing in ZWaveLocalFirmwareProvider by enabling pattern matching and adding extra regexes to extract plain and dotted version formats.

Signed-off-by: Bob Eckhoff <katmandodo@yahoo.com>
Clarify and harden firmware update flow: enhance debug logging for ACK advancement and duplicate UPDATE_MD_GET handling to better describe sequential cases, and increase NOP/version refresh scheduling delays (delayedExecutor from 2s to 10s and added extra waitTimeSeconds offset) to reduce race conditions. Update unit test timeout to match the longer delay. Refactor ZWaveThingHandler: reorder firmware-related fields, replace direct callback identity check with Objects.equals, and add advanceFirmwareProgressTo helper to advance progress steps safely. Minor cleanup: move FirmwareDownloadStatus enum within ZWaveFirmwareUpdateCommandClass, tweak author tags in ZWaveNode, and trim incidental whitespace.

Signed-off-by: Bob Eckhoff <katmandodo@yahoo.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants