MINI-ZBDIM: fromZigbee converter throws "Expected one of: 1, 2, 3, 4, 5, got: '0'" when the device reports dimmingLightRate = 0
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 15.7k
- Forks
- 2k
- Avg merge
- 18h 55m
- Merged PRs (30d)
- 35
Description
What happened?
A freshly installed SONOFF MINI-ZBDIM reported dimmingLightRate = 0 before brightness calibration had been run. The dimming_light_rate enum lookup only accepts 1–5, so its fromZigbee converter throws on every attribute report:
[2026-09-18 12:28:44] debug: z2m: Received Zigbee message from 'Traphal 0', type 'attributeReport', cluster 'customClusterEwelink', data '{"16388":0,"16389":0,>
[2026-09-18 12:28:44] error: z2m: Exception while calling fromZigbee converter: Expected one of: 1, 2, 3, 4, 5, got: '0'}
(The payload line is truncated at 260 characters — that is how it was captured.)
The device was in calibration_status: uncalibrate, calibration_progress: 0 at the time.
After running the brightness calibration the device reports dimmingLightRate = 4 and the exception is gone: 588 state publishes for this device in the following 47 minutes, zero error: lines.
What did you expect to happen?
An out-of-range enum value reported by the device should not throw. Either the value is mapped to something meaningful, or the attribute is skipped — but the converter should not raise, and dimming_light_rate should not be left unpopulated for the whole time a new dimmer is uncalibrated.
How to reproduce it (minimal and precise)
- Pair a SONOFF MINI-ZBDIM and do not run Brightness Calibration.
- Watch the log at
debuglevel while the device sends itscustomClusterEwelinkattribute reports. - Every report that carries
dimmingLightRatelogsException while calling fromZigbee converter: Expected one of: 1, 2, 3, 4, 5, got: '0'. - Run the calibration; the exception stops.
Zigbee2MQTT version
2.14.1 (Home Assistant add-on 2.14.1-1)
Adapter firmware version
EmberZNet 8.0.2 [GA], build 397, EZSP 14
Adapter
Sonoff ZBDongle-E, ember
Setup
| Zigbee2MQTT version | 2.14.1 (Home Assistant add-on 2.14.1-1) |
| zigbee-herdsman | 10.9.2 |
| zigbee-herdsman-converters | 26.105.0 |
| Device | SONOFF MINI-ZBDIM (modelId: MINI-ZBDIM) |
| Device firmware | swBuildId: 1.0.5, dateCode: 20251205, zclVersion 8 |
Device database.db entry
No response
Debug log
No response
Notes
(Analysis and suggested solutions are AI-generated. They seem plausible, but I did no thorough verification.)
Root cause
The definition maps the attribute onto a 1–5 lookup, with no entry for 0 (src/devices/sonoff.ts#L11532-L11540):
m.enumLookup<"customClusterEwelink", SonoffEwelink>({
name: "dimming_light_rate",
lookup: {"1x": 1, "2x": 2, "3x": 3, "4x": 4, "5x": 5},
cluster: "customClusterEwelink",
attribute: "dimmingLightRate",
description: "Speed of brightness change via external switch.",
access: "ALL",
entityCategory: "config",
}),
enumLookup's default fromZigbee converter calls getFromLookupByValue without a default (src/lib/modernExtend.ts#L2818):
return {[expose.property]: getFromLookupByValue(value, lookup)};
and that helper throws when no default is supplied (src/lib/utils.ts#L673):
export function getFromLookupByValue(value: unknown, lookup: Record<string, unknown>, defaultValue: string = undefined): string {
for (const [key, val] of Object.entries(lookup)) {
if (val === value) {
return key;
}
}
if (defaultValue === undefined) {
throw new Error(`Expected one of: ${Object.values(lookup).join(", ")}, got: '${value}'`);
}
return defaultValue;
}
This is the only lookup in the MINI-ZBDIM definition whose values are 1, 2, 3, 4, 5, so the error message identifies the attribute unambiguously. The definition's other lookups are {edge: 0, pulse: 1, "double pulse": 3, "triple pulse": 4}, a start/stop byte-array lookup, and {uncalibrate: 0, cailbrating: 1, calibration_failed: 2, calibrated: 3} — the last one accepts 0, which is why calibration_status itself reports fine.
Impact
enumLookup builds its own fromZigbee converter, so the exception aborts only this one converter: dimming_light_rate is missing from the published state (and its Home Assistant entity stays empty) while the other attributes in the same frame are converted by their own converters. So the practical impact is an error: line per report plus one missing config value — not a loss of the whole state report. Still noisy enough to look like a real fault to someone who has just installed the device, which is exactly when it happens.
Affected model: MINI-ZBDIM only. dimming_light_rate occurs exactly once in sonoff.ts, inside the zigbeeModel: ["MINI-ZBDIM"] definition.
Suggested fix
Two options, smallest first:
- Device-specific.
enumLookupalready accepts anfzConvertoverride, so the MINI-ZBDIM definition can skip the uninitialised value rather than map it — keeping the exposed enum free of a bogus, settable0option (the expose is built fromObject.keys(lookup), which is also why simply addingunknown: 0to the lookup is not ideal: it would become selectable). - Generic hardening. Let
enumLookuppass a default intogetFromLookupByValue, or skip and log atwarninginstead of throwing, so that any device reporting an undocumented enum value degrades gracefully. This class of bug is not specific to SONOFF.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the MINI-ZBDIM definition in src/devices/sonoff.ts, then read enumLookup in src/lib/modernExtend.ts and getFromLookupByValue in src/lib/utils.ts. Verify the converter handles dimmingLightRate = 0 without throwing and that the resulting state behavior matches the chosen device-specific or generic fix.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- embedded-iot
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 68/100