Unable to F/W update IKEA batt. powered buttons (ZHA)

I’ve spent countless hours trying to update my huge amount of IKEA battery powered buttons to no avail.
They tend to suck up batteries really fast.
I’ve searched the forum on how to update the firmware but nothing seems to work for me.

Details are:

Using a conbee2 stick (3m USB ext. cable) on the ZHA stack.

"home_assistant": {
    "installation_type": "Home Assistant OS",
    "version": "2023.11.2",
    "dev": false,
    "hassio": true,
    "virtualenv": false,
    "python_version": "3.11.6",
    "docker": true,
    "arch": "x86_64",
    "os_name": "Linux",
    "os_version": "6.1.59",
    "supervisor": "2023.11.3",
    "host_os": "Home Assistant OS 11.1",
    "docker_version": "24.0.6",
    "chassis": "embedded",
    "run_as_root": true
  }

configuration.yaml

zha:
  zigpy_config:
  #source_routing: true
    ota:
      otau_directory: /config/zigpy_ota
      ikea_provider: true
      ledvance_provider: true

The specifics of my zigbee culprit IKEA device are:

TRADFRI on/off switch af IKEA of Sweden
Firmware: 0x23079631
Nwk: 0x54a7
Device Type: EndDevice
LQI: 255
RSSI: -61
Strømkilde: Battery or Unknown
Quirk: zhaquirks.ikea.twobtnremote.IkeaTradfriRemote2Btn

"attribute_name": "sw_build_id",
"value": "2.3.079"

my “\config\zigpy_ota” folder has the file:
“10005778-tradfri_onoff_controller-24.4.6-prod.ota.ota.signed”
(+ alot of other files as well.)

This FW file should bring the device up to version :
0x24040006
but it’s stuck at
0x23079631

Also to rule out battery issues during this session I have unplugged the batt. and instead powered up the IKEA button using a DC power supply.
It works fine. button presses are registered. Nothing broken so far.

So when I carry out this service command on the corresponding ieee:
(During the process I am repeatedly clicking on the on/off button on the device itself in order to prevent it from sleeping.)

service: zha_toolkit.ota_notify
data:
  ieee: REDACTED
  tries: 100

I get this response:


zha_toolkit_version: v1.1.6
zigpy_version: 0.59.0
zigpy_rf_version: 0.21.1
ieee_org:
  - 17
  - 38
  - 137
  - 254
  - 255
  - 172
  - 51
  - 188
ieee: REDACTED
command: ota_notify
command_data: null
start_time: "2023-11-21T11:29:46.670724+00:00"
errors: []
params:
  dir: 0
  tries: 100
  expect_reply: true
  args: []
  read_before_write: true
  read_after_write: true
PAR:
  cmd_id: null
  endpoint_id: null
  dst_endpoint_id: null
  cluster_id: null
  attr_id: null
  attr_type: null
  attr_val: null
  code: null
  min_interval: null
  max_interval: null
  reportable_change: null
  dir: 0
  manf: null
  tries: 100
  expect_reply: true
  args: []
  state_id: null
  state_attr: null
  state_value_template: null
  force_update: false
  allow_create: false
  event_success: null
  event_fail: null
  event_done: null
  fail_exception: false
  read_before_write: true
  read_after_write: true
  write_if_equal: false
  csvfile: null
  csvlabel: null
  download: null
  path: null
  use_cache: false
result: null
success: true

looking at the home-assitant.log file I get this:
(do note: I’ve filtered away irrelevant log entries)

2023-11-21 12:42:42.429 DEBUG (MainThread) [custom_components.zha_toolkit] event_data {'zha_toolkit_version': 'v1.1.6', 'zigpy_version': '0.59.0', 'zigpy_rf_version': '0.21.1', 'ieee_org': REDACTED, 'ieee': 'REDACTED', 'command': 'ota_notify', 'command_data': None, 'start_time': '2023-11-21T11:42:38.098264+00:00', 'errors': [], 'params': {'dir': 0, 'tries': 100, 'expect_reply': True, 'args': [], 'read_before_write': True, 'read_after_write': True}, 'PAR': {'cmd_id': None, 'endpoint_id': None, 'dst_endpoint_id': None, 'cluster_id': None, 'attr_id': None, 'attr_type': None, 'attr_val': None, 'code': None, 'min_interval': None, 'max_interval': None, 'reportable_change': None, 'dir': 0, 'manf': None, 'tries': 100, 'expect_reply': True, 'args': [], 'state_id': None, 'state_attr': None, 'state_value_template': None, 'force_update': False, 'allow_create': False, 'event_success': None, 'event_fail': None, 'event_done': None, 'fail_exception': False, 'read_before_write': True, 'read_after_write': True, 'write_if_equal': False, 'csvfile': None, 'csvlabel': None, 'download': None, 'path': None, 'use_cache': False}, 'result': None, 'success': True}

2023-11-21 12:42:42.874 DEBUG (MainThread) [zigpy.application] Received a packet: ZigbeePacket(timestamp=datetime.datetime(2023, 11, 21, 11, 42, 42, 874929, tzinfo=datetime.timezone.utc), src=AddrModeAddress(addr_mode=<AddrMode.NWK: 2>, address=0x54A7), src_ep=1, dst=AddrModeAddress(addr_mode=<AddrMode.NWK: 2>, address=0x0000), dst_ep=1, source_route=None, extended_timeout=False, tsn=None, profile_id=260, cluster_id=6, data=Serialized[b'\x01\x10\x01'], tx_options=<TransmitOptions.NONE: 0>, radius=0, non_member_radius=0, lqi=255, rssi=-61)
2023-11-21 12:42:42.875 DEBUG (MainThread) [zigpy.zcl] [0x54A7:1:0x0006] Received ZCL frame: b'\x01\x10\x01'
2023-11-21 12:42:42.875 DEBUG (MainThread) [zigpy.zcl] [0x54A7:1:0x0006] Decoded ZCL frame header: ZCLHeader(frame_control=FrameControl(frame_type=<FrameType.CLUSTER_COMMAND: 1>, is_manufacturer_specific=0, direction=<Direction.Server_to_Client: 0>, disable_default_response=0, reserved=0, *is_cluster=True, *is_general=False), tsn=16, command_id=1, *direction=<Direction.Server_to_Client: 0>)
2023-11-21 12:42:42.875 DEBUG (MainThread) [zigpy.zcl] [0x54A7:1:0x0006] Decoded ZCL frame: OnOff:on()
2023-11-21 12:42:42.875 DEBUG (MainThread) [zigpy.zcl] [0x54A7:1:0x0006] Received command 0x01 (TSN 16): on()
2023-11-21 12:42:42.876 DEBUG (MainThread) [zigpy.zcl] [0x54A7:1:0x0006] No explicit handler for cluster command 0x01: on()
2023-11-21 12:42:43.963 DEBUG (MainThread) [zigpy.application] Received a packet: ZigbeePacket(timestamp=datetime.datetime(2023, 11, 21, 11, 42, 43, 963019, tzinfo=datetime.timezone.utc), src=AddrModeAddress(addr_mode=<AddrMode.NWK: 2>, address=0x54A7), src_ep=1, dst=AddrModeAddress(addr_mode=<AddrMode.NWK: 2>, address=0x0000), dst_ep=1, source_route=None, extended_timeout=False, tsn=None, profile_id=260, cluster_id=6, data=Serialized[b'\x01\x11\x01'], tx_options=<TransmitOptions.NONE: 0>, radius=0, non_member_radius=0, lqi=255, rssi=-61)
2023-11-21 12:42:43.963 DEBUG (MainThread) [zigpy.zcl] [0x54A7:1:0x0006] Received ZCL frame: b'\x01\x11\x01'
2023-11-21 12:42:43.963 DEBUG (MainThread) [zigpy.zcl] [0x54A7:1:0x0006] Decoded ZCL frame header: ZCLHeader(frame_control=FrameControl(frame_type=<FrameType.CLUSTER_COMMAND: 1>, is_manufacturer_specific=0, direction=<Direction.Server_to_Client: 0>, disable_default_response=0, reserved=0, *is_cluster=True, *is_general=False), tsn=17, command_id=1, *direction=<Direction.Server_to_Client: 0>)
2023-11-21 12:42:43.964 DEBUG (MainThread) [zigpy.zcl] [0x54A7:1:0x0006] Decoded ZCL frame: OnOff:on()
2023-11-21 12:42:43.964 DEBUG (MainThread) [zigpy.zcl] [0x54A7:1:0x0006] Received command 0x01 (TSN 17): on()
2023-11-21 12:42:43.964 DEBUG (MainThread) [zigpy.zcl] [0x54A7:1:0x0006] No explicit handler for cluster command 0x01: on()
2023-11-21 12:42:44.142 DEBUG (MainThread) [homeassistant.components.zha.core.device] [0x3F8F](lumi.sensor_magnet): Device seen - marking the device available and resetting counter
2023-11-21 12:42:44.143 DEBUG (MainThread) [homeassistant.components.zha.core.device] [0x3F8F](lumi.sensor_magnet): Update device availability -  device available: True - new availability: True - changed: False
2023-11-21 12:42:44.163 DEBUG (MainThread) [homeassistant.components.zha.core.device] [0x5377](lumi.sensor_wleak.aq1): last_seen is 44279840.19995642 seconds ago and ping attempts have been exhausted, marking the device unavailable
2023-11-21 12:42:44.164 DEBUG (MainThread) [homeassistant.components.zha.core.device] [0x5377](lumi.sensor_wleak.aq1): Update device availability -  device available: False - new availability: False - changed: False
2023-11-21 12:42:44.507 DEBUG (MainThread) [zigpy.application] Received a packet: ZigbeePacket(timestamp=datetime.datetime(2023, 11, 21, 11, 42, 44, 507041, tzinfo=datetime.timezone.utc), src=AddrModeAddress(addr_mode=<AddrMode.NWK: 2>, address=0x54A7), src_ep=1, dst=AddrModeAddress(addr_mode=<AddrMode.NWK: 2>, address=0x0000), dst_ep=1, source_route=None, extended_timeout=False, tsn=None, profile_id=260, cluster_id=25, data=Serialized[b'\x01\x12\x06\x00|\x11\xc5\x11\x06\x00\x04$'], tx_options=<TransmitOptions.NONE: 0>, radius=0, non_member_radius=0, lqi=255, rssi=-61)
2023-11-21 12:42:44.507 DEBUG (MainThread) [zigpy.zcl] [0x54A7:1:0x0019] Received ZCL frame: b'\x01\x12\x06\x00|\x11\xc5\x11\x06\x00\x04$'
2023-11-21 12:42:44.507 DEBUG (MainThread) [zigpy.zcl] [0x54A7:1:0x0019] Decoded ZCL frame header: ZCLHeader(frame_control=FrameControl(frame_type=<FrameType.CLUSTER_COMMAND: 1>, is_manufacturer_specific=0, direction=<Direction.Server_to_Client: 0>, disable_default_response=0, reserved=0, *is_cluster=True, *is_general=False), tsn=18, command_id=6, *direction=<Direction.Server_to_Client: 0>)
2023-11-21 12:42:44.508 DEBUG (MainThread) [zigpy.zcl] [0x54A7:1:0x0019] Decoded ZCL frame: Ota:upgrade_end(status=<Status.SUCCESS: 0>, manufacturer_code=4476, image_type=4549, file_version=604241926)
2023-11-21 12:42:44.508 DEBUG (MainThread) [zigpy.zcl] [0x54A7:1:0x0019] Received command 0x06 (TSN 18): upgrade_end(status=<Status.SUCCESS: 0>, manufacturer_code=4476, image_type=4549, file_version=604241926)
2023-11-21 12:42:44.509 DEBUG (MainThread) [zigpy.zcl] [0x54A7:1:0x0019] OTA upgrade_end handler for 'IKEA of Sweden TRADFRI on/off switch': status=Status.SUCCESS, manufacturer_id=4476, image_type=4549, file_version=604241926
2023-11-21 12:42:44.509 DEBUG (MainThread) [zigpy.zcl] [0x54A7:1:0x0019] Sending reply header: ZCLHeader(frame_control=FrameControl(frame_type=<FrameType.CLUSTER_COMMAND: 1>, is_manufacturer_specific=False, direction=<Direction.Client_to_Server: 1>, disable_default_response=1, reserved=0, *is_cluster=True, *is_general=False), tsn=18, command_id=7, *direction=<Direction.Client_to_Server: 1>)
2023-11-21 12:42:44.509 DEBUG (MainThread) [zigpy.zcl] [0x54A7:1:0x0019] Sending reply: upgrade_end_response(manufacturer_code=4476, image_type=4549, file_version=604241926, current_time=0, upgrade_time=0)
2023-11-21 12:42:45.353 DEBUG (MainThread) [zigpy.application] Received a packet: ZigbeePacket(timestamp=datetime.datetime(2023, 11, 21, 11, 42, 45, 353906, tzinfo=datetime.timezone.utc), src=AddrModeAddress(addr_mode=<AddrMode.NWK: 2>, address=0x54A7), src_ep=1, dst=AddrModeAddress(addr_mode=<AddrMode.NWK: 2>, address=0x0000), dst_ep=1, source_route=None, extended_timeout=False, tsn=None, profile_id=260, cluster_id=25, data=Serialized[b'\x00\x12\x0b\x07\x01'], tx_options=<TransmitOptions.NONE: 0>, radius=0, non_member_radius=0, lqi=255, rssi=-61)
2023-11-21 12:42:45.355 DEBUG (MainThread) [zigpy.zcl] [0x54A7:1:0x0019] Received ZCL frame: b'\x00\x12\x0b\x07\x01'
2023-11-21 12:42:45.355 DEBUG (MainThread) [zigpy.zcl] [0x54A7:1:0x0019] Decoded ZCL frame header: ZCLHeader(frame_control=FrameControl(frame_type=<FrameType.GLOBAL_COMMAND: 0>, is_manufacturer_specific=0, direction=<Direction.Server_to_Client: 0>, disable_default_response=0, reserved=0, *is_cluster=False, *is_general=True), tsn=18, command_id=11, *direction=<Direction.Server_to_Client: 0>)
2023-11-21 12:42:45.356 DEBUG (MainThread) [zigpy.zcl] [0x54A7:1:0x0019] Decoded ZCL frame: Ota:Default_Response(command_id=7, status=<Status.FAILURE: 1>)

I should also mention that I have been able to update some other none-IKEA (bulbs) just fine.
But these IKEA buttons are a real nightmare.

I’ve tried to have the button connected to the coordinator directly sitting 10cm from it.
I’ve also tried to connect it through another IKEA router. A LED driver (powersupply).
Same ordeal :frowning:

I guess I could just buy the official IKEA GW and have all my IKEA devices route through that.
Or buy some other zigbee buttons. Sigh.

Hi,

It looks like you’ve done a lot of debug to look at updates, so my suggestion would be to post a linked GitHub issue for the ZHA folks to look at.

I posted here, then raised an issue, and the devs were quite helpful (likely as we’ve both done the leg work and not posting something trivial).

The only thing I can spot comparing your ZHA configuration.yaml snippet, is yours has a path, whereas mine doesn’t. Mine did have a custom quirks path, but once the release was made, it wasn’t needed so got removed.

# Manual config to enable Zigbee firmware updates
# https://www.home-assistant.io/integrations/zha
zha:
  zigpy_config:
    ota:
      ikea_provider: true                        # Auto update Trådfri devices
      ledvance_provider: true                    # Auto update LEDVANCE/OSRAM devices
      salus_provider: true                       # Auto update SALUS/Computime devices
      #otau_directory: /path/to/your/ota/folder  # Utilize .ota files to update everything else
  # https://github.com/zigpy/zha-device-handlers/discussions/693#discussioncomment-857274
  #custom_quirks_path: /config/custom_zha_quirks/

Note that even with things all confirmed working, an upgrade takes about 1-2 DAYS. Although my 5-button remotes have had good battery life for about a year, I’ve still got a new 2-button IKEA remote that doesn’t pair with ZHA so not everything works!

If this helps, :heart: this post!

1 Like