Skip to content

Instantly share code, notes, and snippets.

@Koenkk
Last active January 1, 2026 13:54
Show Gist options
  • Select an option

  • Save Koenkk/bfd4c3d1725a2cccacc11d6ba51008ba to your computer and use it in GitHub Desktop.

Select an option

Save Koenkk/bfd4c3d1725a2cccacc11d6ba51008ba to your computer and use it in GitHub Desktop.
Zigbee2MQTT latest-dev changelog

Improvements

  • #29730 Add action bridge/request API (@Nerivec)
  • #29750 Add new bind/reporting/map features (@Nerivec)
  • #26823 Allow scheduling OTA on device request (@Nerivec)
  • #27851 Allow to disable internal frontend UI serving for standalone serving (@Nerivec)
  • #26811 Availability improvements (@Nerivec)
  • #27164 New health extension & extras in bridge/info (@Nerivec)
  • #27489 WindFront new frontend support (@Nerivec)

Fixes

  • #27194 Add icon example to settings schema (@andy-vdg)
  • #27163 Add interview state (@Koenkk)
  • #28843 Add pi cooling demand to Home Assistant auto discovery (@dvandonkelaar)
  • #29754 Add port 8080 EXPOSE to container (@lxfrdl)
  • #28202 Always unlink node_modules symlinks on stop (@Nerivec)
  • #27551 API missing a few request endpoints (@Nerivec)
  • #30137 Biome floating promises detection (@Nerivec)
  • #27690 Bump Alpine to 3.22 (@Koenkk)
  • #27032 Do not call start() on extensions twice when starting (@pyos)
  • #27025 Don't allow publishing wildcards in MQTT topic (@Koenkk)
  • #27397 Don't copy external JS to dist folder (@Koenkk)
  • #30216 Don't fail to start when removing old log directory fails (@Koenkk)
  • #27348 Drop Node 18 support, add 24 (@Koenkk)
  • #27892 Erroneous Health OS memory percent calculation (@Nerivec)
  • #28013 Exit with code 2 when adapters disconnects (@Koenkk)
  • #28583 Fix DatabaseEntry with ID 'X' does not exist when adding device to delete group ID (@Koenkk)
  • #29322 Fix onEvent called twice first time when device options are changed (@Koenkk)
  • #27333 Fix bind/unbind by coordinator ieeeAddr not working (@Koenkk)
  • #27691 Fix devices not immediately marked as offline when timeout expires (@Koenkk)
  • #27519 Fix import error on Windows (ERR_UNSUPPORTED_ESM_URL_SCHEME) (@kirovilya)
  • #29354 Fix input onboarding environment variable disabled check (@jetersen)
  • #26988 Fix settings being overwriting when env var is set to a ref (@Koenkk)
  • #27961 Fix settings schema defaults (@Nerivec)
  • #27702 Generate group ID if empty string given (@Nerivec)
  • #27093 Guard against ZHC throwing (@Nerivec)
  • #27520 HA integration for external sensors Aqara W100 (@kirovilya)
  • #28364 Handle empty or null Home Assistant name in device settings (@SixFive7)
  • #29936 Home Assistant: Accept multiple access levels for current_humidity source property (@burmistrzak)
  • #29842 Home Assistant: expose current_humidity for climate devices exposing humidity (@burmistrzak)
  • #29211 Home Assistant: fix device and group configuration URL (@Koenkk)
  • #29188 Home Assistant: make PI heating demand from writable (@DerDreschner)
  • #28192 Home Assistant: set icon and state class for orientation sensors (@mik-laj)
  • #30014 Home Assistant: Translate boolean to state topic for current_humidity_topic (@burmistrzak)
  • #28329 Home Assistant: use "occupancy" device_class for human presence sensors (@jspiros)
  • #28560 HomeAssistant: add default_entity_id to discovery message (@Koenkk)
  • #28132 Ignore symbolic links in data during backup (@robvanoostenrijk)
  • #27988 Improve startup settings validation (@Nerivec)
  • #27308 Improve update script (@0xdefec71f)
  • #30324 Log dir tz format not working on some systems (@Nerivec)
  • #27837 Log error message when external JS fails to load (@Boris-c)
  • #28546 Make windfront the default frontend (@Koenkk)
  • #27150 Migrate to Biome (@Nerivec)
  • #27063 OnEvent fixes (@Nerivec)
  • #27225 Only send JSON state over WebSocket (@Koenkk)
  • #30297 Proper timezone in logs dir (@Nerivec)
  • #28076 Publish definition source in bridge/devices (@Nerivec)
  • #28057 Publish endpoint names in bridge/devices (@Nerivec)
  • #28160 Remove 60 MB (28%) of dev dependencies from Docker image (@krkk)
  • #30065 Remove extra > in onboarding (@Bi11)
  • #28797 Remove Moment.js dependency (@Koenkk)
  • #29131 Rename ZigBee -> Zigbee (@Koenkk)
  • #27642 Rename fix typo in backoff settings (@Koenkk)
  • #29854 Reporting payload detection fixes (@Nerivec)
  • #29284 Require at least Node ^20.15.0 (@Koenkk)
  • #29285 Require at least Node ^22.2.0 (@Koenkk)
  • #27386 Rerun onboarding if Z2M start failed after previous onboarding (@Nerivec)
  • #28209 Set minimum for some settings (@Nerivec)
  • #27983 Set MQTT retain and qos=1 on (re)connect (@megapearl)
  • #28257 Support for new ZH typing (@Nerivec)
  • #27332 Trim name on rename (@Koenkk)
  • #27984 Update to refactored zhc api and fix onEvent(stop) not being called when device is force removed (@Koenkk)
  • #27641 Update zigbee2mqtt-windfront to 1.0.4 (@Nerivec)
  • #28389 Update zigbee2mqtt-windfront to 2.0.0 (@Nerivec)
  • #25417 Use Alpine 3.21 for arm v6 and v7 (@Koenkk)
  • #27105 Use Map for State (@Nerivec)
  • #28011 Various fixes to align behaviors (+add benchmarks for dev) (@Nerivec)
  • #27880 Various Windfront frontend improvements (@nerivec)

Windfront

Frontend

New supported devices

This release adds support for 0 devices:

Fixed device detections

Changelog generator error

@K-SDaniel
Copy link

Hi there, can we please add support for the Aqara T2 RGB version? I was able to add it but can't modify the power-on behavior.

export default {
zigbeeModel: ['lumi.light.agl003'],
model: 'lumi.light.agl003',
vendor: 'Aqara',
description: 'Automatically generated definition',
extend: [m.deviceEndpoints({"endpoints":{"1":1,"21":21}}), m.light({"colorTemp":{"range":[111,500]},"color":true}), m.electricityMeter()],
meta: {"multiEndpoint":true},
};
aqara

@dimolutionman
Copy link

Hi,
could someone please add the Shelly 2PM Gen 4?

Thanks!!

https://www.shelly.com/de/products/shelly-2pm-gen4

IMG_7615

Cheers,
Dimo

@noxyomdion
Copy link

Can you please add:

Model: TS0601
Vendor: _TZE284_aai5grix

ZigBee 24G Radar

@bernardesarthur
Copy link

Can you please add:

Model: TS0601 Vendor: _TZE284_aai5grix

ZigBee 24G Radar

Please open a issue here.

@AkdM
Copy link

AkdM commented Aug 8, 2025

Hello,
Can you please add:

Model: TS0601
Vendor: _TZE284_d0ypnbvn
Smart water/gas valve

It's the same as TS0601_TZE204_d0ypnbvn.

Thank you!

@Kaktus317
Copy link

Kaktus317 commented Aug 11, 2025

Hi, I can see people requests in this post, not sure if this is appropriate place so sorry if not in advance. I would love to ask for support for Aqara Floor Heating Thermostat W500.

Manufacturer: Aqara Model: UT‑A01D

Note. It seems like the Aqara Floor Heating Thermostat W100 (TH‑S04D) is already supported and from my knowledge these two models are identical but one (W500) can be mounted on the wall only to the power circuit, the second one (W100) works with battery. From newbie perspective I believe it should not be hard to add something similar, but I am probably wrong. Thank you!

I am looking forward to this as well.

@AmitSmall
Copy link

Hello, can you please add:
Zigbee Model: TS0601
Vendor: _TZE284_7a5ob7xq
WhatsApp Image 2025-08-14 at 16 44 00_27252968
Smart lights / shutters switch

@maiandrei
Copy link

maiandrei commented Sep 5, 2025

Hi!
Please add Tongou RCBO TOQSMR1, similar to TOWSMR1
image

It might seem a little confusing, as the picture shows the same TOWSMR1, but there is a tiny difference:
image
TOQSMR1 is Type AC RCBO and identifies with vendor: '_TZE204_432zhuwe',
TOWSMR1 is Type A RCBO and identifies with vendor: '_TZE284_432zhuwe' and others.

OR it might be enough to add "_TZE204_432zhuwe" to fingerprint for TOWSMR1?

export default {
    zigbeeModel: ['TS0601'],
    model: 'TS0601',
    vendor: '_TZE204_432zhuwe',
    description: 'Automatically generated definition',
    extend: [],
    meta: {},
};

Meanwhile, for n00bs like me:

  1. Using Studio Code Server or other editor, locate zigbee2mqttt/configuration.yaml and add (pay attention to indentation):
external_converters:
  - rcbo_tongou.js
  1. Create a new folder external_converters . Here you create the new rcbo_tongou.js file: /homeassistant/zigbee2mqtt/external_converters/rcbo_tongou.js and

  2. Paste this code into the new file:

const fz = require('zigbee-herdsman-converters/converters/fromZigbee');
const tz = require('zigbee-herdsman-converters/converters/toZigbee');
const exposes = require('zigbee-herdsman-converters/lib/exposes');
const reporting = require('zigbee-herdsman-converters/lib/reporting');
const modernExtend = require('zigbee-herdsman-converters/lib/modernExtend');
const e = exposes.presets;
const ea = exposes.access;
const tuya = require('zigbee-herdsman-converters/lib/tuya');

const definition = {
    // Since a lot of Tuya devices use the same modelID, but use different datapoints
    // it's necessary to provide a fingerprint instead of a zigbeeModel
    fingerprint: [
        {
            // The model ID from: Device with modelID 'TS0601' is not supported
            // You may need to add \u0000 at the end of the name in some cases
            modelID: 'TS0601',
            // The manufacturer name from: Device with modelID 'TS0601' is not supported.
            manufacturerName: '_TZE204_432zhuwe',
        },
    ],
    model: 'TO-Q-SMR1-40JZT',
    vendor: 'Tongou',
    description: 'Single-phase RCBO 30-100mA 1-40A (DIN Module)',
    fromZigbee: [tuya.fz.datapoints],
    toZigbee: [tuya.tz.datapoints],
    onEvent: tuya.onEvent({
        respondToMcuVersionResponse: false,
        queryIntervalSeconds: 10,
        }),
    configure: tuya.configureMagicPacket,
    exposes: [
        tuya.exposes.switch(), 
        e.energy(), 
        e.temperature(), 
        e.power(), 
        e.voltage(), 
        e.current(),
        e.numeric("leakage_current", ea.STATE).withUnit("mA").withDescription("Current leakage"),
        e
            .enum("event", ea.STATE, [
                "normal",
                "over_current_trip",
                "over_power_trip",
                "high_temp_trip",
                "over_voltage_trip",
                "under_voltage_trip",
                "over_current_alarm",
                "over_power_alarm",
                "high_temp_alarm",
                "over_voltage_alarm",
                "under_voltage_alarm",
                "remote_on",
                "remote_off",
                "manual_on",
                "manual_off",
                "leakage_trip",
                "leakage_alarm",
                "restore_default",
                "automatic_closing",
                "electricity_shortage",
                "electricity_shortage_alarm",
                "timing_switch_On",
                "timing_switch_off",
            ])
            .withDescription("Last event of the device"),
        e.enum("over_current_setting", ea.STATE_SET, ["Ignore", "Alarm", "Trip"]).withDescription("Over current setting"),
        e
            .numeric("over_current_threshold", ea.STATE_SET)
            .withUnit("A")
            .withDescription("Setup the value on the device")
            .withValueMin(1)
            .withValueMax(40),
        e.enum("over_voltage_setting", ea.STATE_SET, ["Ignore", "Alarm", "Trip"]).withDescription("Over voltage setting"),
        e
            .numeric("over_voltage_threshold", ea.STATE_SET)
            .withUnit("V")
            .withDescription("Setup value on the device")
            .withValueMin(240)
            .withValueMax(295),
        e.enum("under_voltage_setting", ea.STATE_SET, ["Ignore", "Alarm", "Trip"]).withDescription("Under voltage setting"),
        e
            .numeric("under_voltage_threshold", ea.STATE_SET)
            .withUnit("V")
            .withDescription("Setup value on the device")
            .withValueMin(145)
            .withValueMax(220),
        e.enum("leakage_setting", ea.STATE_SET, ["Ignore", "Alarm", "Trip"]).withDescription("Leakage setting"),
        e
            .numeric("leakage_threshold", ea.STATE_SET)
            .withUnit("mA")
            .withDescription("Setup value on the device")
            .withValueMin(30)
            .withValueMax(100),
        e.enum("temperature_setting", ea.STATE_SET, ["Ignore", "Alarm", "Trip"]).withDescription("Temperature setting"),
        e
            .numeric("temperature_threshold", ea.STATE_SET)
            .withUnit("°C")
            .withDescription("Setup value on the device")
            .withValueMin(-25)
            .withValueMax(100),
        e.enum("over_power_setting", ea.STATE_SET, ["Ignore", "Alarm", "Trip"]).withDescription("Over power setting"),
        e
            .numeric("over_power_threshold", ea.STATE_SET)
            .withUnit("W")
            .withDescription("Setup value on the device")
            .withValueMin(1)
            .withValueMax(25000),
        e
            .binary("auto_reclosing", ea.STATE_SET, "ON", "OFF")
            .withLabel("Auto reclosing")
            .withDescription(
                "When the circuit breaker trips due to voltage protection, it will automatically close when the circuit voltage returns to normal",
            ),
        e
            .binary("overcurrent_recloser", ea.STATE_SET, "ON", "OFF")
            .withLabel("Overcurrent Recloser")
            .withDescription(
                "When the circuit breaker trips due to overcurrent protection, it will automatically close when the circuit voltage returns to normal",
            ),
        e
            .binary("leakage_recloser", ea.STATE_SET, "ON", "OFF")
            .withLabel("Leakage Recloser")
            .withDescription(
                "When the circuit breaker trips due to leakage protection, it will automatically close when the circuit voltage returns to normal",
            ),
        e
            .binary("overpower_recloser", ea.STATE_SET, "ON", "OFF")
            .withLabel("Overpower Recloser")
            .withDescription(
                "When the circuit breaker trips due to overpower protection, it will automatically close when the circuit voltage returns to normal",
            ),
        e.binary("restore_default", ea.STATE_SET, "ON", "OFF").withDescription("Turn ON to restore default settings"),
    ],
    meta: {
        tuyaDatapoints: [
            [1, "energy", tuya.valueConverter.divideBy100],
            [6, null, tuya.valueConverter.phaseVariant2], // voltage and current
            [15, "leakage_current", tuya.valueConverter.raw],
            [16, "state", tuya.valueConverter.onOff],
            [
                110,
                "event",
                tuya.valueConverterBasic.lookup({
                    normal: 0,
                    over_current_trip: 1,
                    over_power_trip: 2,
                    high_temp_trip: 3,
                    over_voltage_trip: 4,
                    under_voltage_trip: 5,
                    over_current_alarm: 6,
                    over_power_alarm: 7,
                    high_temp_alarm: 8,
                    over_voltage_alarm: 9,
                    under_voltage_alarm: 10,
                    remote_on: 11,
                    remote_off: 12,
                    manual_on: 13,
                    manual_off: 14,
                    leakage_trip: 15,
                    leakage_alarm: 16,
                    restore_default: 17,
                    automatic_closing: 18,
                    electricity_shortage: 19,
                    electricity_shortage_alarm: 20,
                    timing_switch_on: 21,
                    timing_switch_off: 22,
                }),
            ],
            [
                102,
                "over_voltage_setting",
                tuya.valueConverterBasic.lookup({
                    Ignore: tuya.enum(0),
                    Alarm: tuya.enum(1),
                    Trip: tuya.enum(2),
                }),
            ],
            [
                103,
                "under_voltage_setting",
                tuya.valueConverterBasic.lookup({
                    Ignore: tuya.enum(0),
                    Alarm: tuya.enum(1),
                    Trip: tuya.enum(2),
                }),
            ],
            [
                104,
                "over_current_setting",
                tuya.valueConverterBasic.lookup({
                    Ignore: tuya.enum(0),
                    Alarm: tuya.enum(1),
                    Trip: tuya.enum(2),
                }),
            ],
            [
                105,
                "over_power_setting",
                tuya.valueConverterBasic.lookup({
                    Ignore: tuya.enum(0),
                    Alarm: tuya.enum(1),
                    Trip: tuya.enum(2),
                }),
            ],
            [
                107,
                "temperature_setting",
                tuya.valueConverterBasic.lookup({
                    Ignore: tuya.enum(0),
                    Alarm: tuya.enum(1),
                    Trip: tuya.enum(2),
                }),
            ],
            [
                108,
                "leakage_setting",
                tuya.valueConverterBasic.lookup({
                    Ignore: tuya.enum(0),
                    Alarm: tuya.enum(1),
                    Trip: tuya.enum(2),
                }),
            ],
            [112, "auto_reclosing", tuya.valueConverter.onOff],
            [113, "restore_default", tuya.valueConverter.onOff],
            [114, "over_current_threshold", tuya.valueConverter.raw],
            [115, "over_voltage_threshold", tuya.valueConverter.raw],
            [116, "under_voltage_threshold", tuya.valueConverter.raw],
            [117, "leakage_threshold", tuya.valueConverter.raw],
            [118, "temperature_threshold", tuya.valueConverter.divideBy10],
            [119, "over_power_threshold", tuya.valueConverter.raw],
            [131, "temperature", tuya.valueConverter.divideBy10],
            [143, "overcurrent_recloser", tuya.valueConverter.onOff],
            [144, "leakage_recloser", tuya.valueConverter.onOff],
            [145, "overpower_recloser", tuya.valueConverter.onOff],
        ],
    },
};

module.exports = definition;
  1. Restart Zigbee2MQTT addon;

  2. Enjoy!

This is the AC Type device
This is the A Type device
S123a0b45a6514275b539130772da995dd

@frohaut
Copy link

frohaut commented Sep 8, 2025

Hi
I purchased this module
https://fr.aliexpress.com/item/1005009242917566.html?spm=a2g0o.order_list.order_list_main.34.607a5e5bGE77fU&gatewayAdapt=glo2fra
it doesn't seem to be supported, do you have a planned update for this module?
Best regards,
Franck
export default {
zigbeeModel: ['TS0601'],
model: 'TS0601',
vendor: '_TZE284_mxujdmxo',
description: 'Automatically generated definition',
extend: [],
meta: {},
};

@Ankhwatcher
Copy link

@maiandrei Thanks for the guide!

I managed to get mine working by following it. I did have to use your original onEvent: tuya.onEventSetTime, // Add this if you are getting no converter for 'commandMcuSyncTime' though.

Otherwise Zigbee2Mqtt kept renaming my file to tongou.js.invalid.

@xion2000
Copy link

Hi purchased this Zigbee Room Thermostat recently and unfortunately it's not currently supported
https://www.aliexpress.com/item/1005007126805419.html?spm=a2g0o.order_list.order_list_main.28.6b2c18024rzB2W
Zigbee Model: TS0601
Zigbee Manufacturer: _TZE284_zjhoqbrd
Hope it can be added and I'm struggling to sort out a work around
Regards
Graham

@maiandrei
Copy link

maiandrei commented Sep 23, 2025

@maiandrei Thanks for the guide!

I managed to get mine working by following it. I did have to use your original onEvent: tuya.onEventSetTime, // Add this if you are getting no converter for 'commandMcuSyncTime' though.

Otherwise Zigbee2Mqtt kept renaming my file to tongou.js.invalid.

You're right, 2 days later I found the devices unsupported and the file invalid.
With that version of onEvent I didn't receive any feedback from device in HA. Do you?
Now I copied code from https://github.com/Koenkk/zigbee-herdsman-converters/blob/eb0faa7c71c6c184cb925f20145c5b2c619fae79/src/devices/tuya.ts#L14797
and, for the moment, everything is OK again.

@BelkinDzmitry
Copy link

Hello! I have 4 gang+2 scene (6 buttons) switch.
Not supported yet. Can you add it?

zigbeeModel: ['TS0601'],
model: 'TS0601',
vendor: '_TZE200_mk3mlurj',
description: 'CombZSwitch4A2',

@bugac
Copy link

bugac commented Sep 24, 2025

Please add to supported list:

https://www.aliexpress.com/item/1005009024318979.html

`const {iasZoneAlarm, temperature, humidity, battery, illuminance} = require('zigbee-herdsman-converters/lib/modernExtend');

const definition = {
zigbeeModel: ['TS0601'],
model: 'TS0601',
vendor: '_TZE200_rhgsbacq',
description: 'Automatically generated definition',
extend: [iasZoneAlarm({"zoneType":"generic","zoneAttributes":["alarm_1","alarm_2","tamper","battery_low"]}), temperature(), humidity(), battery(), illuminance()],
meta: {},
};

module.exports = definition;`

image

@MattiaMarchiorato
Copy link

Hi purchased this Zigbee Room Thermostat recently and unfortunately it's not currently supported https://www.aliexpress.com/item/1005007126805419.html?spm=a2g0o.order_list.order_list_main.28.6b2c18024rzB2W Zigbee Model: TS0601 Zigbee Manufacturer: _TZE284_zjhoqbrd Hope it can be added and I'm struggling to sort out a work around Regards Graham

i have the same problem

@xion2000
Copy link

Hi purchased this Zigbee Room Thermostat recently and unfortunately it's not currently supported https://www.aliexpress.com/item/1005007126805419.html?spm=a2g0o.order_list.order_list_main.28.6b2c18024rzB2W Zigbee Model: TS0601 Zigbee Manufacturer: _TZE284_zjhoqbrd Hope it can be added and I'm struggling to sort out a work around Regards Graham

i have the same problem

I've managed to get it working with zigbee2mqtt using an external converter

I named to file "_TZE284_zjhoqbrd.js"
then put it in /homeassistant/zigbee2mqtt/external_converters/

Below is the contents of the .js file

const fz = require('zigbee-herdsman-converters/converters/fromZigbee');
const tz = require('zigbee-herdsman-converters/converters/toZigbee');
const exposes = require('zigbee-herdsman-converters/lib/exposes');
const reporting = require('zigbee-herdsman-converters/lib/reporting');
const modernExtend = require('zigbee-herdsman-converters/lib/modernExtend');
const e = exposes.presets;
const ea = exposes.access;
const tuya = require('zigbee-herdsman-converters/lib/tuya');

const definition = {
// Since a lot of Tuya devices use the same modelID, but use different datapoints
// it's necessary to provide a fingerprint instead of a zigbeeModel
fingerprint: [
{
// The model ID from: Device with modelID 'TS0601' is not supported
// You may need to add \u0000 at the end of the name in some cases
modelID: 'TS0601',
// The manufacturer name from: Device with modelID 'TS0601' is not supported.
manufacturerName: '_TZE284_zjhoqbrd',
},
],
model: 'TS0601_ZWT198',
vendor: 'Tuya',
icon: '/icons/ts0601_zwt198.jpg',
description: 'Central Heating Thermostat',
fromZigbee: [tuya.fz.datapoints],
toZigbee: [tuya.tz.datapoints],
onEvent: tuya.onEventSetTime, // Add this if you are getting no converter for 'commandMcuSyncTime'
configure: tuya.configureMagicPacket,
exposes: [
e.binary("factory_reset", ea.STATE_SET, "ON", "OFF").withDescription("Full factory reset, use with caution!"),
e.child_lock(),
e.temperature_sensor_select(["internal", "external", "both"]),
e
.climate()
.withSystemMode(["off", "heat"], ea.STATE_SET)
.withPreset(["manual", "auto", "temporary_manual"])
.withSetpoint("current_heating_setpoint", 5, 35, 0.5, ea.STATE_SET)
.withRunningState(["idle", "heat"], ea.STATE)
.withLocalTemperature(ea.STATE)
.withLocalTemperatureCalibration(-9.9, 9.9, 0.1, ea.STATE_SET),
e.binary("frost_protection", ea.STATE_SET, "ON", "OFF").withDescription("Antifreeze function"),
e
.max_temperature_limit()
.withUnit("°C")
.withValueMin(15)
.withValueMax(90)
.withValueStep(0.5)
.withPreset("default", 60, "Default value")
.withDescription("Maximum upper temperature"),
e
.numeric("deadzone_temperature", ea.STATE_SET)
.withUnit("°C")
.withValueMax(10)
.withValueMin(0.1)
.withValueStep(0.1)
.withPreset("default", 1, "Default value")
.withDescription("The delta between local_temperature (5<t<35)and current_heating_setpoint to trigger Heat"),
e.enum("backlight_mode", ea.STATE_SET, ["off", "low", "medium", "high"]).withDescription("Intensity of the backlight"),
e.enum("working_day", ea.STATE_SET, ["disabled", "6-1", "5-2", "7"]).withDescription("Workday setting"),
e.text("schedule_weekday", ea.STATE_SET).withDescription("Workdays (6 times hh:mm/cc.c°C)"),
e
.text("schedule_holiday", ea.STATE_SET)
.withDescription("Holidays (2 times hh:mm/cc.c°C)"),
// ============== exposes for found, but not functional datapoints:
/*
e.min_temperature_limit() // dp 16
.withValueMin(5)
.withValueMax(15)
.withValueStep(0.5)
.withPreset('default', 10, 'Default value')
.withDescription('dp16 is listed in Tuya, but no communication from device'),

    e.binary('dp105', ea.STATE_SET, 'ON', 'OFF')
        .withDescription('dp105 is not listed in Tuya, but device sends datapoint, binary: true/false'),

    e.binary('dp111', ea.STATE_SET, 'ON', 'OFF')
        .withDescription('dp111 is not listed in Tuya, but device sends datapoint, binary: true/false'),
    */
],
meta: {
    tuyaDatapoints: [
        [1, "system_mode", tuya.valueConverterBasic.lookup({heat: true, off: false})],
        [2, "current_heating_setpoint", tuya.valueConverter.divideBy10],
        [3, "local_temperature", tuya.valueConverter.divideBy10],
        [
            4,
            "preset",
            tuya.valueConverterBasic.lookup((_, device) => {
                // https://github.com/Koenkk/zigbee2mqtt/issues/21353#issuecomment-1938328429
                // https://github.com/Koenkk/zigbee2mqtt/issues/28035
                if (device.manufacturerName === "_TZE204_lzriup1j" || device.manufacturerName === "_TZE204_gops3slb") {
                    return {
                        auto: tuya.enum(1),
                        manual: tuya.enum(0),
                        temporary_manual: tuya.enum(2),
                    };
                }
                return {
                    auto: tuya.enum(0),
                    manual: tuya.enum(1),
                    temporary_manual: tuya.enum(2),
                };
            }),
        ],
        [9, "child_lock", tuya.valueConverter.lockUnlock],
        [11, "faultalarm", tuya.valueConverter.raw],
        [15, "max_temperature_limit", tuya.valueConverter.divideBy10],
        [19, "local_temperature_calibration", tuya.valueConverter.localTempCalibration3],
        [
            101,
            "running_state",
            tuya.valueConverterBasic.lookup({
                heat: tuya.enum(1),
                idle: tuya.enum(0),
            }),
        ],
        [102, "frost_protection", tuya.valueConverter.onOff],
        [103, "factory_reset", tuya.valueConverter.onOff],
        [
            104,
            "working_day",
            tuya.valueConverterBasic.lookup((_, device) => {
                // https://github.com/Koenkk/zigbee2mqtt/issues/23979
                if (device.manufacturerName === "_TZE200_viy9ihs7") {
                    return {
                        disabled: tuya.enum(0),
                        "6-1": tuya.enum(1),
                        "5-2": tuya.enum(2),
                        "7": tuya.enum(3),
                    };
                }
                return {
                    disabled: tuya.enum(0),
                    "6-1": tuya.enum(2),
                    "5-2": tuya.enum(1),
                    "7": tuya.enum(3),
                };
            }),
        ],
        [
            106,
            "sensor",
            tuya.valueConverterBasic.lookup({
                internal: tuya.enum(0),
                external: tuya.enum(1),
                both: tuya.enum(2),
            }),
        ],
        [107, "deadzone_temperature", tuya.valueConverter.divideBy10],
        [109, null, tuya.valueConverter.ZWT198_schedule],
        [109, "schedule_weekday", tuya.valueConverter.ZWT198_schedule],
        [109, "schedule_holiday", tuya.valueConverter.ZWT198_schedule],
        [110, "backlight_mode", tuya.valueConverter.backlightModeOffLowMediumHigh],
        // ============== found but not functional datapoints:

        // [16, 'min_temperature_limit', tuya.valueConverter.divideBy10],  // datapoint listed in Tuya, but no communication from device
        // [105, 'dp105', tuya.valueConverter.onOff],                      // not listed in Tuya, but device sends datapoint
        // [111, 'dp111', tuya.valueConverter.onOff],                      // not listed in Tuya, but device sends datapoint

        // These are the schedule values in bytes, 8 periods in total (4 bytes per period).
        // For each period:
        // 1st byte: hour
        // 2nd byte: minute
        // 3rd, 4th bytes: temperature multiplied by 10
        // On the device last 2 periods are ignored if schedule_mode is 7day. When schedule_mode is disabled,
        // scheduling can't be configured at all on the device.
        // For example, if schedule_mode is weekday/sat+sun and this byte array is received:
        // [6,10,1,144,8,10,0,170,11,40,0,170,12,40,0,170,17,10,0,230,22,10,0,170,8,5,0,200,23,0,0,160]
        // Then the schedule is:
        // Mon-Fri: 6:10 --> 40C, 8:10 --> 17C, 11:40 --> 17C, 12:40 --> 17C, 17:10 --> 23C, 22:10 --> 17C
        // Sat-Sun: 8:05 --> 20C, 23:00 --> 16C
    ],
},

};

module.exports = definition;

@MattiaMarchiorato
Copy link

@xion2000 many thanks, is working!

@rytecbe
Copy link

rytecbe commented Sep 26, 2025

@xion2000 thank you very much to made this and info where to place this in the system. It worked for me too. The only thing which is not showing is the battery, I don't have it connected with an USB-C cable but working with 3x AAA batteries.
Is there a possibility to have this info working in your file?

@douternitou
Copy link

douternitou commented Oct 7, 2025

Hi,

I just purchased the EcoDim DIM.06 dimmer but found that is not supported yet.
Would it be possible to add this one?
Thanks in advance.

https://www.123led.nl/EcoDim-Zigbee-stekkerdimmer-0-100W-Fase-afsnijding-RC-EcoDim-DIM-06-i7926-t4329.html

image image

{
"description": "Automatically generated definition",
"exposes": [
{
"features": [
{
"access": 7,
"description": "On/off state of this light",
"label": "State",
"name": "state",
"property": "state",
"type": "binary",
"value_off": "OFF",
"value_on": "ON",
"value_toggle": "TOGGLE"
},
{
"access": 7,
"description": "Brightness of this light",
"label": "Brightness",
"name": "brightness",
"property": "brightness",
"type": "numeric",
"value_max": 254,
"value_min": 0
}
],
"type": "light"
},
{
"access": 2,
"description": "Triggers an effect on the light (e.g. make light blink for a few seconds)",
"label": "Effect",
"name": "effect",
"property": "effect",
"type": "enum",
"values": [
"blink",
"breathe",
"okay",
"channel_change",
"finish_effect",
"stop_effect"
]
},
{
"access": 7,
"category": "config",
"description": "Controls the behavior when the device is powered on after power loss",
"label": "Power-on behavior",
"name": "power_on_behavior",
"property": "power_on_behavior",
"type": "enum",
"values": [
"off",
"on",
"toggle",
"previous"
]
},
{
"access": 1,
"category": "diagnostic",
"description": "Link quality (signal strength)",
"label": "Linkquality",
"name": "linkquality",
"property": "linkquality",
"type": "numeric",
"unit": "lqi",
"value_max": 255,
"value_min": 0
}
],
"model": "eco-dim06-zigbee",
"options": [
{
"access": 2,
"description": "Controls the transition time (in seconds) of on/off, brightness, color temperature (if applicable) and color (if applicable) changes. Defaults to 0 (no transition).",
"label": "Transition",
"name": "transition",
"property": "transition",
"type": "numeric",
"value_min": 0
},
{
"access": 2,
"description": "State actions will also be published as 'action' when true (default false).",
"label": "State action",
"name": "state_action",
"property": "state_action",
"type": "binary",
"value_off": false,
"value_on": true
}
],
"source": "generated",
"supports_ota": false,
"vendor": "EcoDim BV"
}

@xion2000
Copy link

@xion2000 thank you very much to made this and info where to place this in the system. It worked for me too. The only thing which is not showing is the battery, I don't have it connected with an USB-C cable but working with 3x AAA batteries. Is there a possibility to have this info working in your file?

I have mine working of batteries only also and have the same problem with batteries NOT showing in Zigbee2MQTT unfortunately

@mattia9508
Copy link

Buonasera a tutti, chiedo gentilmente se è possibile aggiungere il seguente dispositivo:

image

https://italian.alibaba.com/product-detail/subject-1600753083531.html?from=share&ckvia=share_80DFED87F71A45E98E35F2B59887F5D0&needReward=true

export default {
zigbeeModel: ['TS0601'],
model: 'TS0601',
vendor: '_TZE204_o9d1hdma',
description: 'Automatically generated definition',
extend: [],
meta: {},
};

il dispositivo in questione è praticamente identico ad un dispositivo presente nella lista dispositivi supportati, ne ho 6 in casa mi piacerebbe tantissimo vederli funzionare
https://www.zigbee2mqtt.io/devices/AE-669K.html

Grazie per il vostro prezioso aiuto

Mattia

@MattiaMarchiorato
Copy link

@mattia9508 ciao,

puoi usare un external converter

guarda qui

@mattia9508
Copy link

mattia9508 commented Oct 13, 2025 via email

@Norbertcb
Copy link

Bonjour
Pouvez vous ajouter cet appareil SMT10020 de schneider svp, c'est un capteur d'echauffement des cables

@lalik77
Copy link

lalik77 commented Oct 23, 2025

Hi can you add motion and light sensor.
This is the generated external converter :

const {identify, iasZoneAlarm, battery, illuminance} = require('zigbee-herdsman-converters/lib/modernExtend');


const definition = {
    zigbeeModel: ['TS0601'],
    model: 'TS0601',
    vendor: '_TZE200_na5qlzow',
    description: 'Automatically generated definition',
    extend: [identify(), iasZoneAlarm({"zoneType":"generic","zoneAttributes":["alarm_1","alarm_2","tamper","battery_low"]}), battery(), illuminance()],
    meta: {},
};

module.exports = definition;
2025-10-20_19-06-18 2025-10-20_19-24-36

@raduten
Copy link

raduten commented Oct 26, 2025

Another tuya temp/humidity with clock device

export default {
zigbeeModel: ['TS0601'],
model: 'TS0601',
vendor: '_TZE284_cwyqwqbf',
description: 'Automatically generated definition',
extend: [],
};
image

@jeanlouisbiset
Copy link

Hello can you add the necessary definition for an AVATTO ZDMS16-2
It is a Zigbee Module 2 channels Dimmer.
This is the generated external converter :

{
"last_seen": "2025-11-04T18:34:39.089Z",
"linkquality": 160,
"device": {
"applicationVersion": 78,
"dateCode": "",
"friendlyName": "0xa4c1385b98ce2ed7",
"hardwareVersion": 1,
"ieeeAddr": "0xa4c1385b98ce2ed7",
"manufacturerID": 4417,
"manufacturerName": "_TZE284_jtbgusdc",
"networkAddress": 12724,
"powerSource": "Mains (single phase)",
"stackVersion": 0,
"type": "Router",
"zclVersion": 3
}
}

const definition = {
zigbeeModel: ['TS0601'],
model: 'TS0601',
vendor: '_TZE284_jtbgusdc',
description: 'Automatically generated definition',
extend: [],
meta: {},
};

module.exports = definition;

Thanks for your efforts.
Kind regards.

@bernardesarthur
Copy link

Hello can you add the necessary definition for an AVATTO ZDMS16-2 It is a Zigbee Module 2 channels Dimmer. This is the generated external converter :

{ "last_seen": "2025-11-04T18:34:39.089Z", "linkquality": 160, "device": { "applicationVersion": 78, "dateCode": "", "friendlyName": "0xa4c1385b98ce2ed7", "hardwareVersion": 1, "ieeeAddr": "0xa4c1385b98ce2ed7", "manufacturerID": 4417, "manufacturerName": "_TZE284_jtbgusdc", "networkAddress": 12724, "powerSource": "Mains (single phase)", "stackVersion": 0, "type": "Router", "zclVersion": 3 } }

const definition = { zigbeeModel: ['TS0601'], model: 'TS0601', vendor: '_TZE284_jtbgusdc', description: 'Automatically generated definition', extend: [], meta: {}, };

module.exports = definition;

Thanks for your efforts. Kind regards.

That manufacturerID is already supported. Are you using the last version of Zigbee2MQTT?

@jeanlouisbiset
Copy link

Reading your answer I went back to my Jeedom and saw that my Zigbee2MQTT version was 1.42.0.
I upgraded to 2.6.3 and then miracle, the module is correctly working.
Many thanks for your quick reaction. I will now buy several modules to go further.
Have a nice day!
Zigbee2MQTT WindFront

@Frikk
Copy link

Frikk commented Nov 23, 2025

Could anyone more skilled than me in Z2M add the new Namron Zigbee Thermostat?
Article No: 4512776
Name: Namron Zigbee termostat for panelovn PRO hvit
Product page link: https://www.elektroimportoren.no/namron-zigbee-termostat-for-panelovn-pro-hvit/4512776/Product.html

I have a Namron Zigbee panel heater released before the new thermostats + oven line were released. I suspect this new thermostat would act much the same way as the existing Namron 540139X would (https://www.zigbee2mqtt.io/devices/540139X.html)

If i could help in any way, please let me know.

Generated external definition (from Z2M Dev Console)

import * as m from 'zigbee-herdsman-converters/lib/modernExtend';

export default {
    zigbeeModel: ['Panel Heater'],
    model: 'Panel Heater',
    vendor: 'NAMRON AS',
    description: 'Automatically generated definition',
    extend: [m.electricityMeter()],
};
{
    "description": "Automatically generated definition",
    "exposes": [
        {
            "access": 5,
            "description": "Instantaneous measured power",
            "label": "Power",
            "name": "power",
            "property": "power",
            "type": "numeric",
            "unit": "W"
        },
        {
            "access": 5,
            "description": "Measured electrical potential value",
            "label": "Voltage",
            "name": "voltage",
            "property": "voltage",
            "type": "numeric",
            "unit": "V"
        },
        {
            "access": 5,
            "description": "Instantaneous measured electrical current",
            "label": "Current",
            "name": "current",
            "property": "current",
            "type": "numeric",
            "unit": "A"
        },
        {
            "access": 5,
            "description": "Sum of consumed energy",
            "label": "Energy",
            "name": "energy",
            "property": "energy",
            "type": "numeric",
            "unit": "kWh"
        },
        {
            "access": 1,
            "category": "diagnostic",
            "description": "Link quality (signal strength)",
            "label": "Linkquality",
            "name": "linkquality",
            "property": "linkquality",
            "type": "numeric",
            "unit": "lqi",
            "value_max": 255,
            "value_min": 0
        }
    ],
    "model": "Panel Heater",
    "options": [
        {
            "access": 2,
            "description": "Calibrates the power value (percentual offset), takes into effect on next report of device.",
            "label": "Power calibration",
            "name": "power_calibration",
            "property": "power_calibration",
            "type": "numeric",
            "value_step": 0.1
        },
        {
            "access": 2,
            "description": "Number of digits after decimal point for power, takes into effect on next report of device. This option can only decrease the precision, not increase it.",
            "label": "Power precision",
            "name": "power_precision",
            "property": "power_precision",
            "type": "numeric",
            "value_max": 3,
            "value_min": 0
        },
        {
            "access": 2,
            "description": "Calibrates the voltage value (percentual offset), takes into effect on next report of device.",
            "label": "Voltage calibration",
            "name": "voltage_calibration",
            "property": "voltage_calibration",
            "type": "numeric",
            "value_step": 0.1
        },
        {
            "access": 2,
            "description": "Number of digits after decimal point for voltage, takes into effect on next report of device. This option can only decrease the precision, not increase it.",
            "label": "Voltage precision",
            "name": "voltage_precision",
            "property": "voltage_precision",
            "type": "numeric",
            "value_max": 3,
            "value_min": 0
        },
        {
            "access": 2,
            "description": "Calibrates the current value (percentual offset), takes into effect on next report of device.",
            "label": "Current calibration",
            "name": "current_calibration",
            "property": "current_calibration",
            "type": "numeric",
            "value_step": 0.1
        },
        {
            "access": 2,
            "description": "Number of digits after decimal point for current, takes into effect on next report of device. This option can only decrease the precision, not increase it.",
            "label": "Current precision",
            "name": "current_precision",
            "property": "current_precision",
            "type": "numeric",
            "value_max": 3,
            "value_min": 0
        },
        {
            "access": 2,
            "description": "Calibrates the energy value (percentual offset), takes into effect on next report of device.",
            "label": "Energy calibration",
            "name": "energy_calibration",
            "property": "energy_calibration",
            "type": "numeric",
            "value_step": 0.1
        },
        {
            "access": 2,
            "description": "Number of digits after decimal point for energy, takes into effect on next report of device. This option can only decrease the precision, not increase it.",
            "label": "Energy precision",
            "name": "energy_precision",
            "property": "energy_precision",
            "type": "numeric",
            "value_max": 3,
            "value_min": 0
        }
    ],
    "source": "generated",
    "supports_ota": false,
    "vendor": "NAMRON AS"
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment