OTA: LEDVANCE (0x1189) bulb rejects 50-byte image blocks with MALFORMED_COMMAND after requesting 63 bytes

Open Beginner friendly
#1,965 3 comments 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 1 day

Nobody has claimed this yet.

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
75/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
python

Research direction

Start in zigpy/ota/manager.py at _image_block_size_for_manufacturer, and compare how the Legrand manufacturer is handled with the LEDVANCE behavior described in the issue. Check the OTA image block tests and run the relevant tests after locating them. Done means LEDVANCE's requested 63-byte block is honored and the tests cover the response size.

Written by the indexing model from the issue text.

Description

Problem

A LEDVANCE Zigbee bulb (model LEDVANCE DIM, sold as LEDVANCE SMART+ Filament Classic E27, dimmable) cannot be updated via ZHA. The update aborts right at the first image block and Home Assistant reports Update was not successful: <Status.TIMEOUT: 148>. This is reproducible on every attempt and happens with both bulbs of this model that I have.

The bulb requests image blocks with maximum_data_size=63. zigpy caps all manufacturers except a few at 50 bytes (_image_block_size_for_manufacturer in zigpy/ota/manager.py) and answers with a 50-byte block. The bulb immediately rejects that response with DefaultResponse(command_id=5, status=MALFORMED_COMMAND). It looks like this firmware only accepts a block of exactly the size it requested, similar to the Telink case that was handled for other devices.

Device / image
  • Manufacturer: LEDVANCE, manufacturer code 4489 (0x1189)
  • Model: LEDVANCE DIM
  • Image type: 111 (0x006F), hardware version 2
  • Current file version: 0x02176550 (35087696)
  • Offered file version: 0x03177310 (51868432), from the Ledvance provider (https://api.update.ledvance.com/v1/zigbee/firmwares)
Environment
  • Home Assistant 2026.11.1 (HAOS)
  • zigpy 2.4.1, zha 2.4.3, zigpy-znp 1.1.1
  • Coordinator: SMLIGHT SLZB-MR3U, CC2674P10 radio with Z-Stack firmware 20261110, connected via TCP (socket://…:7638)
  • The bulb is joined directly to the coordinator, link quality is good, and normal on/off/level commands work reliably
Log excerpt (debug)
17:42:02.446 [0x4F26:1:0x0019] Received ZCL frame: '01 02 01 01 89 11 6f 00 50 65 17 02 02 00'
17:42:02.446 [0x4F26:1:0x0019] Decoded ZCL frame: Ota:QueryNextImageCommand(field_control=<QueryNextImageCommandFieldControl.HardwareVersion: 1>, manufacturer_code=4489, image_type=111, current_file_version=35087696, hardware_version=2)

18:01:31.019 [0x4F26:1:0x0019] Received ZCL frame: '01 52 03 02 89 11 6f 00 10 73 17 03 00 00 00 00 3f 00 00'
18:01:31.020 [0x4F26:1:0x0019] Decoded ZCL frame: Ota:ImageBlockCommand(field_control=<ImageBlockCommandFieldControl.MinimumBlockPeriod: 2>, manufacturer_code=4489, image_type=111, file_version=51868432, file_offset=0, maximum_data_size=63, minimum_block_period=0)
18:01:31.021 [0x4F26:1:0x0019] Sending reply: ImageBlockResponseCommand(status=<Status.SUCCESS: 0>, manufacturer_code=4489, image_type=111, file_version=51868432, file_offset=0, image_data=<50 bytes>)
18:01:33.072 [0x4F26:1:0x0019] Received ZCL frame: '00 4d 0b 05 80'
18:01:33.073 [0x4F26:1:0x0019] Decoded ZCL frame: Ota:DefaultResponse(command_id=5, status=<Status.MALFORMED_COMMAND: 128>)

18:01:34.010 [0x4F26:1:0x0019] Decoded ZCL frame: Ota:ImageBlockCommand(..., file_offset=0, maximum_data_size=63, ...)
18:01:34.012 [0x4F26:1:0x0019] Sending reply: ImageBlockResponseCommand(status=<Status.ABORT: 149>)

Further attempts afterwards end with OTA image_block handler exception / zigpy_znp.exceptions.InvalidCommandResponse: Unsuccessful request status code: <Status.APS_NO_ACK: 183> and finally Update was not successful: <Status.TIMEOUT: 148> in Home Assistant.

Possible fix

Treat LEDVANCE (4489) like Legrand (4129) in _image_block_size_for_manufacturer, i.e. honor the requested block size. I have not patched this locally, so I can't confirm 63-byte blocks go through over ZNP. I'm happy to test a branch or provide more logs.

Dominant language
Python
Stars
1.1k
Forks
217
Avg merge
21h 53m
Merged PRs (30d)
9

Getting set up

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from zigpy/zigpy

All issues in zigpy/zigpy

Similar issues

More Python issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.