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

Add software update capability #709

Merged
merged 39 commits into from
Jul 15, 2024
Merged

Conversation

agners
Copy link
Collaborator

@agners agners commented May 18, 2024

This adds software update capability to the Python Matter Server.

As it stands, the implementation does the following things:

  1. Check the DCL for software updates for a particular device
  2. If an update is available, it downloads the firmware locally
  3. Prepares the OTA Provider on the Matter fabric (using the Linux OTA Provider example app)
    3a. On first use, the OTA Provider App is first commissioned to the fabric
  4. Notifies the node about the availability of the OTA Provider and the update

The node then communicates directly with the OTA Provider. Progress of the update can be observed in the OTA Software Update Requestor Cluster of the device being updated.

There are a few things which still need to be sorted out:

  • Lifecycle management of the OTA Provider App needs improvement (termination not working/adding more updates)
  • Potential candidates need to be better checked if they are indeed compatible (minApplicableSoftwareVersion/maxApplicableSoftwareVersion)
  • Checksum of the update files needs to be checked after download
  • Split between update check and update apply
  • Handle multiple update calls for the same node
  • Support updates from testnet DCL

@agners agners marked this pull request as draft May 18, 2024 07:54
@olavt
Copy link

olavt commented May 18, 2024

Will there be some new API-commands available to control this?

@olavt
Copy link

olavt commented May 19, 2024

It would be nice if these steps where totally independent:

  1. Check the DCL for software updates for a particular device
  2. If an update is available, it downloads the firmware locally

I would like them to be:

  1. Check the DCL for software updates for a particular device
  2. If an update is available go to step 3
  3. Download a firmware file from a given location (either one from the one specified by the DCL or any other location)

The reason I want this is to be able to test firmware updates for devices in development, which is not yet published to the DCL. Then step 1 and 2 would be bypassed.

It would be nice with a separate API-function for each of the steps.

@marcelveldt
Copy link
Contributor

TODO:

  • add separate api command to check for updates
  • periodic check for node updates - set flag on matterNodeData
  • Show "update available" in Matter UI
  • HA update entity attached to the flag + manual service call to check for updates
  • The check for updates should implement throttling (HA has helpers for that)

@agners agners force-pushed the add-software-update-capability branch from 745ff7d to b43b024 Compare May 24, 2024 09:25
@agners
Copy link
Collaborator Author

agners commented May 24, 2024

Will there be some new API-commands available to control this?

Yes,

It would be nice if these steps where totally independent:

1. Check the DCL for software updates for a particular device

2. If an update is available, it downloads the firmware locally

Yes, I intend to split this two operations. It is a bit a question of what the reference will be to apply the update. I intend to use the software version number (in integer format) as reference, as this should be unique. So the commands will be:

  {
    "command": "check_node_update",
    "args": {
      "node_id": 50
    }
  }

This will return information about the software, the exact format is tbd (currently a raw dump of the JSON data returned by the DCL).

Then with this command the update will get applied:

  {
    "command": "update_node",
    "args": {
      "node_id": 50,
      "software_version": 123,
    }
  }

Will then start the node update.

I would like them to be:

1. Check the DCL for software updates for a particular device

2. If an update is available go to step 3

3. Download a firmware file from a given location (either one from the one specified by the DCL or any other location)

The reason I want this is to be able to test firmware updates for devices in development, which is not yet published to the DCL. Then step 1 and 2 would be bypassed.

Agreed, we'll need to have a way to support non-DCL updates. In fact, for testing I already need this (I've now added hardcoded updates for the OTA Requestor example).

There are various use cases, from just not in DCL but online, to just an update file from somewhere. Each of these cases need some metadata to match the update file with the right devices. The metadata should probably closely follow the DCL format.

For online ones, we could probably just pass it through the WebSocket API as well, essentially how you suggest. But I don't think this will cover all use cases. 🤔

@agners agners added the new-feature New feature or request label May 24, 2024
@agners agners force-pushed the add-software-update-capability branch 2 times, most recently from c6e19e2 to bb700de Compare June 5, 2024 14:01
@agners
Copy link
Collaborator Author

agners commented Jun 5, 2024

image

image

@agners agners force-pushed the add-software-update-capability branch from b649d5a to 21ea899 Compare June 12, 2024 07:09
@agners agners force-pushed the add-software-update-capability branch 2 times, most recently from 0bf4bc5 to 7f5460b Compare June 24, 2024 21:58
@agners agners changed the title WIP: Add software update capability Add software update capability Jun 24, 2024
@agners agners marked this pull request as ready for review June 24, 2024 21:59
@agners agners force-pushed the add-software-update-capability branch from 8c22aa5 to 0764463 Compare June 25, 2024 07:53
Dockerfile Outdated Show resolved Hide resolved
Dockerfile Outdated Show resolved Hide resolved
Check if there is a software update available using DCL software update
information.
The OTA provider downloads the updates and prepares them so Matter
devices can consume them.
Use the OTA Provider example app to implement a OTA provider. The
example app supports a JSON update descriptor file to manage update
metadata. Tested with the OTA Requestor app.
@agners agners force-pushed the add-software-update-capability branch from 0764463 to 9ed6840 Compare July 11, 2024 17:04
Start and commission OTA Provider App when necessary. Use random
discriminator and passcode. Store the Node ID of the OTA Provider
App once setup for fast re-use.
Verify that the DCL software update is indeed applicable to the
currently software running on the device. Add test coverage as
well.
Add global check for update where we can insert hardcoded updates or
updates from other sources in the future.
@marcelveldt marcelveldt marked this pull request as draft July 13, 2024 08:54
@marcelveldt
Copy link
Contributor

Can you mark it as ready once its entirely complete ? Then we'll do one final review (and hopefully the merge)

@agners agners marked this pull request as ready for review July 15, 2024 11:29
Copy link
Contributor

@marcelveldt marcelveldt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good!

@marcelveldt marcelveldt merged commit dc35816 into main Jul 15, 2024
4 checks passed
@marcelveldt marcelveldt deleted the add-software-update-capability branch July 15, 2024 13:29
@stefa168
Copy link

Sorry for chiming in, not sure if this is the best place or if this would be feasible, but: would the updates feature also support firmware downgrading, or that depends on the software on the matter devices?

@agners
Copy link
Collaborator Author

agners commented Jul 15, 2024

Sorry for chiming in, not sure if this is the best place or if this would be feasible, but: would the updates feature also support firmware downgrading, or that depends on the software on the matter devices?

No, downgrading is not supported by Matter OTA. From the standard:

OTA Requestors SHALL only upgrade to numerically newer versions and OTA Providers SHALL
only ever provide a numerically newer Software Image than a Node’s current version number (see
SoftwareVersion). Any functional rollback SHALL be affected by the Vendor creating a Software
Image with a newer (higher) version number, but whose binary contents may match prior func­
tionality.

@nerijus
Copy link

nerijus commented Jul 15, 2024

I've built docker image from git main branch and started it - how do I get update notification? It seems there is update available for my device (Aqara Window and Door Sensor P2), about an hour after docker container restart passed, but I don't see any notification in HA.

@TheJulianJES
Copy link
Contributor

@nerijus You won't see a notification in HA, as the HA core PR is not merged yet:

@nerijus
Copy link

nerijus commented Jul 15, 2024

Thanks; is there a possibility to upgrade manually from command line from within python-matter-server docker shell?

@nerijus
Copy link

nerijus commented Jul 15, 2024

I updated files from home-assistant/core#120304 manually (and a few other files like select.py, strings.json), but now after restarting HA I get:

Error occurred loading flow for integration matter: cannot import name 'UpdateCheckError' from 'matter_server.common.errors' (/usr/local/lib/python3.12/site-packages/matter_server/common/errors.py)

@marcelveldt
Copy link
Contributor

Just have a little bit of patience folks until this is available. It will also be added as a button the the matter server's own debug UI. The changes for HA core need some more adjustments before we merge them but plan is still to get it done on time for the next beta.

@olavt
Copy link

olavt commented Jul 16, 2024

I would like to test the new software update capability.

What is the high level flow (which commands to use) if I provide my own firmware file?

@JoseAntonioMG
Copy link

I'm using HomeAssistant and Matter-Server with thread devices, everything works fine. I would like to be able to perform OTA updates to the devices but I don't have an account in DCL, is there a possibility to update the firmware of the devices added in HomeAssistant through Matter-Server locally? for example by indicating to Matter-Server a path where the update files are. Is there such a possibility?

I have seen that in the Matter-Server configuration there is an option to add "--ota-provider-dir", but I don't know how it works. Is this option the correct one to indicate a path where the update files are saved? How do you indicate that path?

thanks

@hoppel118
Copy link

@JoseAntonioMG Look here:

#833

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
new-feature New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants