FUT035Z+ (`_TZB210_ue01a0s2`): `FUT035ZrfColorTemp` overwrites color_temp with a stale value a few seconds after a set
I maintainer di solito rispondono entro 1 giorno
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 4/5
- Tempo stimato
- 3-5 giorni
- Idoneità per principianti
- 58/100
- Tipo di issue
- Bug
- Chiarezza
- Specificata chiaramente
- Stato di attività
- Attiva
- Stack tecnologico
- typescript
- Ambito
- backend
Direzione di ricerca
Start by reading the FUT035ZrfColorTemp converter added in PR #12900 and the TS0502B definition that registers it. Trace how raw lightingColorCtrl frames update color_temp, then check how the real colorTemperature attribute can be read after a set. Done means Zigbee2MQTT keeps the commanded value after the delayed status burst while preserving RF color temperature sync.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
What happened?
After updating from an older version, I noticed some of my lights stopped adjusting with Adaptive Lighting in Home assistant, and I noticed the lights shortly report wrong colour temp, (light itself has the correct colour). I fed the logs to LLM, and to me the observations check, and the proposed solution fixed the issue for me (I don't have the RF remote).
Apart from the logs, below is fully written by the LLM.
Setting color_temp on a MiBoxer FUT035Z+ (TS0502B, _TZB210_ue01a0s2) works at first: Zigbee2MQTT publishes the new value and the light changes to it. About 4–6 seconds later, Zigbee2MQTT publishes a different color_temp without any command being sent, for example 462 after setting 400.
The light itself does not change and stays at the requested value. Only the published state is wrong. Reading the attribute back (zigbee2mqtt/<device>/get with {"color_temp": ""}) returns the correct value.
The cause is fzLocal.FUT035ZrfColorTemp, added in #12900 ("fix: sync FUT035Z+ RF color temperature"). After a color temperature command, the device sends two raw lightingColorCtrl frames (attribute 0xF102):
- Immediately after the command. The last two bytes hold the new value.
- About 4 s later, as part of a burst of Tuya status reports (
genOnOff,tuyaRgbMode,genLevelCtrl0xF000,lightingColorCtrl0xE000,0xE100). Here the last two bytes hold a stale value.
FUT035ZrfColorTemp reads the last two bytes of every raw frame as a color temperature, so the second frame overwrites the correct state:
| Frame | Last two bytes | Raw (0–1000) | 500 - raw*347/1000 |
|---|---|---|---|
| 10:37:59 | 32,1 |
288 | 400 (correct) |
| 10:38:04 | 110,0 |
110 | 462 (stale) |
Apart from the sequence number and the last two bytes, the two frames are byte-for-byte identical. The stale frame therefore can't be told apart from a real RF update by its contents alone.
What did you expect to happen?
color_temp should stay at the value that was set, as it did before #12900 (it worked correctly in Zigbee2MQTT 2.6.3).
How to reproduce it (minimal and precise)
- Pair a MiBoxer FUT035Z+ with manufacturer
_TZB210_ue01a0s2. No RF remote is needed. - Publish
{"color_temp": 500}tozigbee2mqtt/<device>/setand wait for it to settle. - Publish
{"color_temp": 400}tozigbee2mqtt/<device>/set. - Zigbee2MQTT publishes
color_temp: 400. - About 4–6 s later, Zigbee2MQTT publishes a different
color_temp(462 in the log below). The light does not visibly change. - Publish
{"color_temp": ""}tozigbee2mqtt/<device>/get. It returns the correct value (400) again.
This happens on both of my FUT035Z+ controllers. It happens with transition: 0 too, and changing the colorTemperature reporting interval doesn't help.
Zigbee2MQTT version
2.14.3
Adapter firmware version
20250321
Adapter
some cc2652 dongle, I've forgotten which
Setup
Docker, image koenkk/zigbee2mqtt:2.14.3
Host: Linux 5.15.0-191-generic #201-Ubuntu SMP Fri Aug 7 18:39:04 UTC 2026 x86_64 x86_64 x86_64 GNU/Linux Ubuntu 22.04.5 LTS
Device: MiBoxer FUT035Z+ (TS0502B), manufacturer _TZB210_ue01a0s2, 2 units
Device database.db entry
No response
Debug log
Setting color_temp 500 → 400 (Home Assistant discovery publishes omitted):
[2026-11-04 10:37:59] debug: z2m: Publishing 'set' 'color_temp' to 'counter-1'
[2026-11-04 10:37:59] info: z2m:mqtt: MQTT publish: topic 'zigbee2mqtt/counter-1', payload '{"brightness":255,"color_mode":"color_temp","color_temp":400,"do_not_disturb":false,"linkquality":131,"state":"ON"}'
[2026-11-04 10:37:59] debug: z2m: Received Zigbee message from 'counter-1', type 'raw', cluster 'lightingColorCtrl', data '{"data":[8,117,10,2,241,72,12,1,0,0,0,232,3,232,3,232,3,32,1],"type":"Buffer"}' from endpoint 1 with groupID 0
[2026-11-04 10:37:59] info: z2m:mqtt: MQTT publish: topic 'zigbee2mqtt/counter-1', payload '{"brightness":255,"color_mode":"color_temp","color_temp":400,"do_not_disturb":false,"linkquality":131,"state":"ON"}'
[2026-11-04 10:38:03] debug: z2m: Received Zigbee message from 'counter-1', type 'attributeReport', cluster 'genOnOff', data '{"onOff":1}' from endpoint 1 with groupID 0
[2026-11-04 10:38:03] info: z2m:mqtt: MQTT publish: topic 'zigbee2mqtt/counter-1', payload '{"brightness":255,"color_mode":"color_temp","color_temp":400,"do_not_disturb":false,"linkquality":131,"state":"ON"}'
[2026-11-04 10:38:03] debug: z2m: Received Zigbee message from 'counter-1', type 'attributeReport', cluster 'lightingColorCtrl', data '{"tuyaRgbMode":0}' from endpoint 1 with groupID 0
[2026-11-04 10:38:03] info: z2m:mqtt: MQTT publish: topic 'zigbee2mqtt/counter-1', payload '{"brightness":255,"color_mode":"color_temp","color_temp":400,"do_not_disturb":false,"linkquality":131,"state":"ON"}'
[2026-11-04 10:38:03] debug: z2m: Received Zigbee message from 'counter-1', type 'attributeReport', cluster 'genLevelCtrl', data '{"61440":1000}' from endpoint 1 with groupID 0
[2026-11-04 10:38:03] info: z2m:mqtt: MQTT publish: topic 'zigbee2mqtt/counter-1', payload '{"brightness":255,"color_mode":"color_temp","color_temp":400,"do_not_disturb":false,"linkquality":131,"state":"ON"}'
[2026-11-04 10:38:03] debug: z2m: Received Zigbee message from 'counter-1', type 'attributeReport', cluster 'lightingColorCtrl', data '{"57344":110}' from endpoint 1 with groupID 0
[2026-11-04 10:38:03] info: z2m:mqtt: MQTT publish: topic 'zigbee2mqtt/counter-1', payload '{"brightness":255,"color_mode":"color_temp","color_temp":400,"do_not_disturb":false,"linkquality":131,"state":"ON"}'
[2026-11-04 10:38:04] debug: z2m: Received Zigbee message from 'counter-1', type 'attributeReport', cluster 'lightingColorCtrl', data '{"tuyaRgbMode":0}' from endpoint 1 with groupID 0
[2026-11-04 10:38:04] info: z2m:mqtt: MQTT publish: topic 'zigbee2mqtt/counter-1', payload '{"brightness":255,"color_mode":"color_temp","color_temp":400,"do_not_disturb":false,"linkquality":131,"state":"ON"}'
[2026-11-04 10:38:04] debug: z2m: Received Zigbee message from 'counter-1', type 'attributeReport', cluster 'genLevelCtrl', data '{"61440":1000}' from endpoint 1 with groupID 0
[2026-11-04 10:38:04] info: z2m:mqtt: MQTT publish: topic 'zigbee2mqtt/counter-1', payload '{"brightness":255,"color_mode":"color_temp","color_temp":400,"do_not_disturb":false,"linkquality":116,"state":"ON"}'
[2026-11-04 10:38:04] debug: z2m: Received Zigbee message from 'counter-1', type 'attributeReport', cluster 'lightingColorCtrl', data '{"57600":4295032832000}' from endpoint 1 with groupID 0
[2026-11-04 10:38:04] info: z2m:mqtt: MQTT publish: topic 'zigbee2mqtt/counter-1', payload '{"brightness":255,"color_mode":"color_temp","color_temp":400,"do_not_disturb":false,"linkquality":127,"state":"ON"}'
[2026-11-04 10:38:04] debug: z2m: Received Zigbee message from 'counter-1', type 'raw', cluster 'lightingColorCtrl', data '{"data":[8,127,10,2,241,72,12,1,0,0,0,232,3,232,3,232,3,110,0],"type":"Buffer"}' from endpoint 1 with groupID 0
[2026-11-04 10:38:04] info: z2m:mqtt: MQTT publish: topic 'zigbee2mqtt/counter-1', payload '{"brightness":255,"color_mode":"color_temp","color_temp":462,"do_not_disturb":false,"linkquality":102,"state":"ON"}'
### Notes
### Proposed solution
Keep RF sync, but don't take the raw value at face value:
1. **Preferred: treat the raw frame as a hint and read the real attribute.** When a raw `0xF102` frame arrives, don't publish `color_temp` from it. Instead, schedule a debounced read of `lightingColorCtrl.colorTemperature`, for example 1–2 s after the last raw frame. In my testing a read always returns the correct value after a Zigbee2MQTT set. Someone with an RF remote would need to confirm that the read also returns the value after an RF change. If it doesn't, use option 2.
2. **Alternative: ignore raw frames shortly after a Zigbee2MQTT command.** Record a timestamp, e.g. in `globalStore`, whenever `color_temp`/`state`/`brightness` is set through Zigbee2MQTT. In `FUT035ZrfColorTemp`, ignore raw frames that arrive within about 10 s of it. An RF change made within that window would be missed until the next one.
### Workaround (confirmed)
I tested an external converter that is identical to the built-in TS0502B definition except that `fromZigbee: [fzLocal.FUT035ZrfColorTemp]` is removed. With it in place, `color_temp` stays at the value that was set, on both controllers. This confirms that `FUT035ZrfColorTemp` is the cause. It's a usable workaround for anyone who doesn't use an RF remote:
```js
import * as tuya from "zigbee-herdsman-converters/lib/tuya";
export default {
fingerprint: tuya.fingerprint("TS0502B", ["_TZB210_ue01a0s2"]),
model: "FUT035Z+",
vendor: "MiBoxer",
description: "Dual white LED controller (no RF color temp sync)",
extend: [
tuya.modernExtend.tuyaLight({
colorTemp: {range: [153, 500]},
configureReporting: true,
}),
],
configure: async (device, coordinatorEndpoint) => {
device.getEndpoint(1).saveClusterAttributeKeyValue("lightingColorCtrl", {
colorCapabilities: 16,
});
await tuya.configureMagicPacket(device, coordinatorEndpoint);
},
};
- Lingua principale
- TypeScript
- Stelle
- 15.8k
- Fork
- 2.1k
- Merge medio
- 1g 6h
- PR unite (30g)
- 38
Preparare l'ambiente
Avvia il container di sviluppo del progetto nel browser, con il tuo account GitHub.
- Nessun Dockerfile né file Docker Compose
- Nessun modello di pull request
- Leggi la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di Koenkk/zigbee2mqtt
-
[Feature request]: OTA for generated definitions of devices with an OTA client clusterForse già presa @jabla l’ha presa 1 giorno fa. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 80/100
Koenkk/zigbee2mqtt#33684 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
new device support
Difficoltà 2/5 1-3 ore Idoneità per principianti 70/100
Koenkk/zigbee2mqtt#33674 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
[Feature request]: Support espzb adapter (ESP Zigbee SDK v2, ESP32-S31)Forse già presa Una pull request collegata a questa issue è aperta o già unita. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 76/100
Koenkk/zigbee2mqtt#33668 ·
I maintainer di solito rispondono entro 1 giorno
-
problem
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 76/100
Koenkk/zigbee2mqtt#33645 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 83/100
Koenkk/zigbee2mqtt#33613 · 2 commenti ·
I maintainer di solito rispondono entro 1 giorno
Tutte le issue di Koenkk/zigbee2mqtt
Issue simili
-
bug parity
Difficoltà 2/5 1-3 ore Idoneità per principianti 70/100
WenyuChiou/agent-board#1489 ·
I maintainer di solito rispondono entro 1 giorno
-
area: bazaar bug complexity: medium
Difficoltà 2/5 1-3 ore Idoneità per principianti 74/100
accensa/x402-facilitator-stellar#779 ·
I maintainer di solito rispondono entro 1 giorno
-
bug good first issue P4 size:S web-ui
Difficoltà 2/5 Mezza giornata Idoneità per principianti 85/100
josephfung/curia#2600 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 62/100
cloudflare/partykit#444 ·