How to update IKEA TIMMERFLOTTE Matter-over-Thread firmware without DIRIGERA or Home Assistant
I wanted to update an IKEA TIMMERFLOTTE temperature / humidity sensor manually, without using a DIRIGERA hub and without involving Home Assistant. This is possible with standard Matter tooling: chip-tool as the controller and the Linux chip-ota-provider-app from connectedhomeip as a temporary OTA provider on the same Matter fabric as the device. The relevant upstream Matter docs cover the Linux OTA Provider flow, the OTA Requestor flow, and the public DCL lookup path.
Executive summary
The short version is:
- download the TIMMERFLOTTE
.otaimage - build
chip-toolandchip-ota-provider-app - verify the OTA header
- read the current firmware version from the device
- start the OTA provider
- commission that provider into the same Matter fabric
- add the provider ACL
- point the TIMMERFLOTTE to that provider
- trigger the OTA check
- keep the provider running until the transfer completes
TIMMERFLOTTE is listed by CSA as a Matter product, and current field reports show firmware 1.0.21 being delivered over Matter OTA, with the image fetched from IKEA’s OTA host after DCL-driven discovery.
Important caveats
This is not the “consumer path.” It is a manual Matter OTA workflow using the upstream reference tools. It assumes that:
- your TIMMERFLOTTE is already commissioned into the same Matter fabric used by your
chip-tool - your Thread network is stable enough for a battery-powered sleepy end device to stay reachable
- you are comfortable with
connectedhomeipon Linux
Also note: the DCL is the discovery source, but the actual TIMMERFLOTTE 1.0.21 image currently appears to be hosted on IKEA’s OTA server, not directly on the CSA site.
Prerequisites
You need:
- a Linux host on the same LAN / Thread backbone as your Matter fabric
- a working
connectedhomeipcheckout - compiled
chip-tool - compiled
chip-ota-provider-app - the TIMMERFLOTTE node ID on your fabric
- the long discriminator you want to use for the temporary OTA provider
In my example below:
- TIMMERFLOTTE node ID =
0xf29 - OTA provider node ID =
0x50 - OTA provider discriminator =
3127
The Linux OTA Provider and Requestor sample flows are documented upstream in the Matter project.
Step 1: Download the OTA image
The public Matter DCL exposes model-version endpoints like this:
GET /dcl/model/versions/{vid}/{pid}
GET /dcl/model/versions/{vid}/{pid}/{softwareVersion}
The public Main-Net observer is:
https://on.dcl.csa-iot.org
For TIMMERFLOTTE, the CSA product listing gives:
- Vendor ID
0x117C=4476 - Product ID
0x8005=32773
You can inspect the model-version entry like this:
curl -s https://on.dcl.csa-iot.org/dcl/model/versions/4476/32773/16777237
For TIMMERFLOTTE firmware 1.0.21, current controller logs show the OTA image being downloaded from this URL:
mkdir -p ~/matter-updates
wget -O ~/matter-updates/timmerflotte-1.0.21.ota \
'https://ota.matter.ikea.com/files/4476_32773_16777237_717586db-6590-43e5-b557-2c8507f55041.ota'
That exact download path is visible in current Matter controller logs for the 1.0.18 → 1.0.21 update flow.
Step 2: Build the tools
From the root of your connectedhomeip checkout:
cd ~/connectedhomeip
source scripts/activate.sh
scripts/examples/gn_build_example.sh examples/chip-tool out/debug
scripts/examples/gn_build_example.sh examples/ota-provider-app/linux out/debug chip_config_network_layer_ble=false
That is the current upstream Linux example build flow for these tools.
If activate.sh fails because the environment is incomplete, bootstrap first:
cd ~/connectedhomeip
./scripts/checkout_submodules.py --shallow --recursive
source scripts/bootstrap.sh
source scripts/activate.sh
Step 3: Verify the OTA header
Before serving the image, inspect it:
cd ~/connectedhomeip
python3 src/app/ota_image_tool.py show ~/matter-updates/timmerflotte-1.0.21.ota
The Linux OTA Provider expects a proper Matter OTA image header and uses that metadata when advertising the update.
Step 4: Read the current firmware version
Before starting the update, confirm what the TIMMERFLOTTE is currently running. The Basic Information cluster exposes the software version and version string.
cd ~/connectedhomeip
./out/debug/chip-tool basicinformation read software-version 0xf29 0
./out/debug/chip-tool basicinformation read software-version-string 0xf29 0
If the device is still on the older firmware, you should see that reflected here before proceeding.
Step 5: Start the Linux OTA Provider
Open a second terminal and start the provider. Leave it running.
cd ~/connectedhomeip
./out/debug/chip-ota-provider-app \
--filepath ~/matter-updates/timmerflotte-1.0.21.ota \
--discriminator 3127 \
--secured-device-port 5541 \
--KVS /tmp/chip_kvs_ota_provider_timmerflotte
The Linux sample OTA Provider serves the image supplied with --filepath.
Step 6: Commission the OTA Provider into the same fabric
Choose a free node ID for the temporary provider, for example 0x50:
cd ~/connectedhomeip
./out/debug/chip-tool pairing onnetwork-long 0x50 20202021 3127
The provider must be on the same fabric as the TIMMERFLOTTE requestor, otherwise the requestor will not use it.
Step 7: Add the provider ACL
The OTA Provider needs an ACL that allows OTA Provider cluster access. First read the current ACL:
cd ~/connectedhomeip
./out/debug/chip-tool accesscontrol read acl 0x50 0
Then write an ACL that preserves your existing administrator entry and adds an OTA Provider access entry. A typical example is:
cd ~/connectedhomeip
./out/debug/chip-tool accesscontrol write acl \
'[{"fabricIndex":1,"privilege":5,"authMode":2,"subjects":[112233],"targets":null},
{"fabricIndex":1,"privilege":3,"authMode":2,"subjects":null,"targets":[{"cluster":41,"endpoint":null,"deviceType":null}]}]' \
0x50 0
Do not blindly copy the admin subject 112233; adjust it to match your own controller / fabric if needed. The important part is not to remove your existing admin ACL entry while adding the OTA Provider access rule. The ACL requirement is explicitly called out in the OTA Provider docs.
Step 8: Point the TIMMERFLOTTE to that provider
Now write the DefaultOTAProviders attribute on the requestor:
cd ~/connectedhomeip
./out/debug/chip-tool otasoftwareupdaterequestor write default-otaproviders \
'[{"providerNodeID":80,"endpoint":0}]' \
0xf29 0
Here 80 is decimal for 0x50. This is one of the standard Matter ways to direct a requestor to a specific OTA provider.
Step 9: Trigger the OTA check
Now actively announce the provider to the TIMMERFLOTTE:
cd ~/connectedhomeip
./out/debug/chip-tool otasoftwareupdaterequestor announce-otaprovider \
0x50 0 0 0 0xf29 0
This is the upstream test flow used to make a requestor check the specified provider immediately.
Step 10: Watch the provider logs
Keep the provider process running. If everything lines up, the TIMMERFLOTTE should:
- query the provider
- see that a newer version is available
- start the BDX transfer
- download the image
- apply the update
- reboot
That is the intended OTA requestor/provider behavior in the Matter sample flow.
Step 11: Verify the new firmware version
After the device reboots and rejoins cleanly, read the version again:
cd ~/connectedhomeip
./out/debug/chip-tool basicinformation read software-version 0xf29 0
./out/debug/chip-tool basicinformation read software-version-string 0xf29 0
If the update succeeded, these values should now reflect the newer firmware.
Known pitfalls
1. Different fabric
This is the most common trap. If your TIMMERFLOTTE is on a different Matter fabric than the one used by this chip-tool, the OTA Provider flow will not work. The provider, the controller, and the requestor must all line up on the same fabric.
2. Battery / sleepy end device behavior
TIMMERFLOTTE is battery-powered and behaves like a sleepy Thread end device, so it may not react instantly. In practice, it helps to keep it close to the OTBR or another stable Thread router, use fresh batteries, and wake it after announce-otaprovider by interacting with it or briefly reinserting the batteries. This is practical operating advice rather than an IKEA-published procedure, but it matches current field behavior reports.
3. ACL mistakes
If you overwrite the provider ACL incorrectly, the provider may become inaccessible or the OTA flow may silently fail. Always read the current ACL first and preserve the admin entry. The need for the OTA Provider ACL is documented upstream.
4. Bad OTA file
If the .ota file does not contain a valid Matter OTA header, the provider will not advertise it correctly. Always run ota_image_tool.py show first.
Useful checks if nothing happens
Check that the requestor has a default provider configured:
cd ~/connectedhomeip
./out/debug/chip-tool otasoftwareupdaterequestor read default-otaproviders 0xf29 0
Check that the provider ACL is really present:
cd ~/connectedhomeip
./out/debug/chip-tool accesscontrol read acl 0x50 0
Check the current version again:
cd ~/connectedhomeip
./out/debug/chip-tool basicinformation read software-version 0xf29 0
./out/debug/chip-tool basicinformation read software-version-string 0xf29 0
How it works:
Matter OTA uses a secure, version-controlled update flow: the device’s OTA Requestor checks a trusted OTA Provider for a newer firmware image, verifies the Matter OTA header and version metadata, then downloads the new firmware into the inactive application partition in flash. Many Matter node controllers, including ESP32-class devices, use two app partitions (ota_0 and ota_1): one holds the currently running firmware, while the other is used as the update target. After the download, the bootloader switches boot to the newly written partition and restarts the device. If the new firmware boots and passes its self-check, it is confirmed as valid; if not, the bootloader can roll back to the previous working partition. Other flash areas such as bootloader, partition table, NVS, and custom data partitions remain separate and are not automatically overwritten.
Conclusion
So yes: you can update an IKEA TIMMERFLOTTE over Matter/Thread without DIRIGERA and without Home Assistant. The recipe is to fetch the OTA image, run the upstream Linux OTA Provider, commission it into the same fabric, give it the right ACL, point the requestor at it, and then trigger the OTA check manually. The public DCL is the discovery layer, while the actual TIMMERFLOTTE 1.0.21 binary currently appears to be fetched from IKEA’s OTA host.
