Skip to content
Merged
Changes from all commits
Commits
Show all changes
280 commits
Select commit Hold shift + click to select a range
dba937b
feat: Bosch BSEN-W: re-work implementation to expose all official fea…
DerDreschner Oct 16, 2025
a583437
fix: Schneider Electric CCT5010-0001: disable power on behaviour http…
Koenkk Oct 16, 2025
88dc1c9
fix: Moes SFL02-Z-*: disable mcuSyncTime https://github.com/Koenkk/zi…
Koenkk Oct 16, 2025
57123c4
fix: Tuya TS0601_cover_11: fix integration https://github.com/Koenkk/…
Koenkk Oct 16, 2025
ec572dc
chore(master): release 25.47.0 (#10382)
Koenkk Oct 16, 2025
02082e4
fix: Tuya _TZ3000_okaz9tjs: fix configure failing https://github.com/…
Koenkk Oct 16, 2025
dabcc99
chore: update pull request template and external converter bot
Koenkk Oct 16, 2025
dc128aa
chore: fix pull request template link
Koenkk Oct 16, 2025
d65c60e
fix(ignore): Rename `ZigBee` -> `Zigbee` (#10384)
Koenkk Oct 16, 2025
da9b467
feat: Schneider Electric EKO07259: update temperature range for therm…
torhelge02 Oct 17, 2025
03fb93e
fix(detect): SPZB0001 20231019 as Eurotronic COZB0001 (#10386)
jkrenzer Oct 17, 2025
e346983
fix: Sinopé TH1123ZB-G2: fix energy value (#10389)
AlexandreJubert Oct 17, 2025
5e8c965
chore(master): release 25.48.0 (#10383)
Koenkk Oct 17, 2025
b09db91
feat(add): CZB01 (#10393)
joliam Oct 18, 2025
3b6911e
feat(add): 4099854295256 (#10395)
ekimetsord Oct 18, 2025
1af151b
fix(detect): Detect `_TZE284_aaeaifez` as Tuya ZWT198/ZWT100-BH (#10399)
danmastalka Oct 18, 2025
a6834e2
fix: Heiman: move custom cluster to zigbee-herdsman-converters (#10396)
madmalkav Oct 18, 2025
7bfa9aa
feat: Innr RCL 231 T: support OTA (#10401)
chris-1243 Oct 18, 2025
4adf2c7
feat(add): WS90 (#10402)
Peter-Maguire Oct 18, 2025
cc83b99
fix(detect): Detect `_TZE204_rbbx5mfq` as Tuya TS0601_illuminance_tem…
Koenkk Oct 18, 2025
e75535f
fix: PTVO: various improvements (#10408)
ptvoinfo Oct 18, 2025
786917d
fix: Bosch BSD-2 (Smoke alarm II): re-work implementation (#10404)
DerDreschner Oct 18, 2025
46a7f95
feat(add): WZDA1 (#10410)
Matthew99999 Oct 18, 2025
4eef5b7
feat(add): TS0601_smoke_co (#10329)
kjpg99 Oct 18, 2025
a236075
chore: add OIDC permission for tokenless publising
Koenkk Oct 18, 2025
92a7181
chore(master): release 25.49.0 (#10409)
Koenkk Oct 18, 2025
4e59d8c
feat(add): BB 287 C-2 (#10420)
michielstigter Oct 19, 2025
77fe737
feat(add): 929003853901 (#10406)
sergiodj Oct 19, 2025
5dd0cf1
feat(add): HS1CG_H (#10411)
CCZU1623 Oct 19, 2025
6afcafe
feat(add): 929003736501 (#10413)
giulianob Oct 19, 2025
b2810ca
feat(add): TZE200_t3xd7l44 (#10394)
adampaul012 Oct 19, 2025
5199563
feat(add): FC600NH (#10414)
mkrle Oct 19, 2025
8337f87
fix(detect): Detect `_TZ3000_uilitwsy` as Zemismart KES-606US-L3 (#10…
LucasHagen Oct 19, 2025
505858e
feat(add): S4EM-001PXCEU16 (#10419)
eXeDK Oct 19, 2025
bcea52c
feat(add): MIR-IL100-ZB (#10424)
yuanxin32323 Oct 19, 2025
b83b151
feat: Shelly: Improve Wi-Fi cluster attributes handling (#10423)
dan-danache Oct 19, 2025
b535d16
fix(ignore): fix configure failing for _TZ3000_okaz9tjs https://githu…
Koenkk Oct 19, 2025
0c6c9e9
fix: Girier JR-ZPM01: remove unsupported indicator mode (#10417)
Bjk8kds Oct 19, 2025
97a153a
chore(master): release 25.50.0 (#10421)
Koenkk Oct 19, 2025
eeb999a
feat(add): OSL 140 C (#10422)
cedrickrusche Oct 20, 2025
e3e850e
chore(deps): bump actions/setup-node from 5 to 6 (#10426)
dependabot[bot] Oct 20, 2025
c253c95
fix(ignore): bump the minor-patch group with 3 updates (#10427)
dependabot[bot] Oct 20, 2025
ca9d073
fix(ignore): Detect `_TZ3000_gjnozsaz` as TS011F_plug_1 https://githu…
Koenkk Oct 20, 2025
70c935a
fix: Moes ZHT-S03: adjust `temperature_delta` min and step value (#10…
Liionboy Oct 20, 2025
b8a012d
feat(add): E13, E12 (#10385)
1tigris1 Oct 20, 2025
eeb5025
fix(detect): Detect `_TZE200_gne0e6mk` as Tuya TS0601_dimmer_1_gang_1…
danivdijk99 Oct 20, 2025
970bbad
feat(add): VAV-256215-MOD1, VAV-256215-MOD2 (#10439)
AlexisPolegato Oct 20, 2025
5a3a416
fix(detect): Detect `_TZE204_debczeci` as iHsenso_TS0601_human_presen…
bfmatei Oct 20, 2025
fd4c8c8
fix(detect): Detect `SRACB_00.00.03.07TC` as Climax SRAC-23B-ZBSR htt…
Koenkk Oct 20, 2025
61fcd65
feat(add): TZE284_4cqhd2ha (#10443)
alimac87 Oct 20, 2025
1f9a2f1
chore(master): release 25.51.0 (#10445)
Koenkk Oct 20, 2025
e1fcc0e
fix: Tuya: disable `manuSpecificTuya.mcuSyncTime` for devices which d…
Koenkk Oct 20, 2025
6a3373e
fix(ignore): Tuya TS011F_plug_1: fix indicator mode https://github.co…
Koenkk Oct 21, 2025
443c2a2
fix(detect): Detect `_TZ3000_q8r0bbvy` as Tuya TS0001_power https://g…
Koenkk Oct 21, 2025
21404d9
fix: MultIr: update model from `MIR-IL100-ZB` to `MIR-IL100` (#10453)
yuanxin32323 Oct 21, 2025
7f2074e
fix: Tuya: migrate datapoint converters to modernExtend (#10454)
Koenkk Oct 21, 2025
b49da6c
chore(master): release 25.51.1 (#10449)
Koenkk Oct 21, 2025
392920f
fix(detect): Detect `_TZ3000_wn65ixz9` as Tuya TS0001_repeater (#10473)
tl-zigbee Oct 23, 2025
c6cbce7
fix: Candeo C210: fix commands always timing out (#10474)
asdfgeoff Oct 23, 2025
5b51f51
fix: Apply suggested fixes from Biome (#10481)
DerDreschner Oct 23, 2025
9ff38c2
feat(add): QS-Zigbee-SEC02-Mod, THERM_SLACKY_DIY_R0B, THERM_SLACKY_DI…
slacky1965 Oct 23, 2025
a7cb9b4
feat(add): ZBCO-AE-10X-EUR (#10462)
Jeroenll Oct 23, 2025
0b9685c
fix: Bosch: remove duplicate definition of `initTestMode` command in …
DerDreschner Oct 23, 2025
7247761
chore(master): release 25.52.0 (#10482)
Koenkk Oct 23, 2025
2baf941
feat: Aqara SRTS-A01: expose `local_temperature` (#10471)
allexoll Oct 24, 2025
1d55f75
feat(add): ICZB-IW21D (#10483)
stephanpesch Oct 24, 2025
3545ba2
feat: AVATTO TS0601_thermostat_14: improve integration (#10484)
ff12 Oct 24, 2025
2f0540b
fix: Remove empty `meta` from generated definition (#10497)
Koenkk Oct 24, 2025
beff44a
fix(ignore): fix SGS02Z detection https://github.com/Koenkk/zigbee-he…
Koenkk Oct 24, 2025
ecf6276
feat(add): ZBDongle-M (#10492)
CubeZ2mDeveloper Oct 24, 2025
36e1f2c
fix(detect): Detect TS0201 Zbeacon as Tuya ZY-ZTH02 (#10472)
tl-zigbee Oct 24, 2025
24632e5
fix(detect): Detect `ZY-ZTH02-z` as Tuya TS0201-z (#10493)
dbmaxpayne Oct 24, 2025
df322e6
feat(add): 4058075823976 (#10494)
gianmarco-mameli Oct 24, 2025
59fa4cc
chore(master): release 25.53.0 (#10496)
Koenkk Oct 24, 2025
6f1c809
feat: Tuya TS0601_water_meter: improve integration (#10469)
Liionboy Oct 25, 2025
d9fb5b3
feat(add): BB 282 C https://github.com/Koenkk/zigbee2mqtt/issues/29267
Koenkk Oct 25, 2025
72602d9
feat(add): MEG5779 (#10500)
Nailik Oct 25, 2025
847dac8
fix(detect): Detect `_TZE284_ltwbm23f` as Tuya TRV602Z (#10501)
bilgi-source Oct 25, 2025
dfe8337
feat(add): ZHT-PT01-M-MS (#10503)
perachemarc Oct 25, 2025
70f0e7c
fix(detect): Detect `_TZ3000_hy6ncvmw` as Tuya TS0222 (#10509)
tl-zigbee Oct 25, 2025
ebaf456
fix(ignore): fix https://github.com/Koenkk/zigbee-herdsman-converters…
Koenkk Oct 25, 2025
b2a0523
fix: use node:zlib for crc calc (#10511)
Nerivec Oct 25, 2025
995e90a
feat(add): HSC-ZW-EU (#10495)
Xenomes Oct 25, 2025
685b916
feat(add): TH-P1Z (#10513)
Gouar Oct 25, 2025
19bf166
fix: Fix `pilot_wire_mode` expose values (#10514)
Gouar Oct 25, 2025
b652c2f
fix: Remove duplicate `meta.multiEndpoint` from generated definition …
Koenkk Oct 25, 2025
b183346
chore: extend external converter issue bot
Koenkk Oct 25, 2025
7d481ec
fix: LiXee ZLinky: fix polling interval + improve option descriptions…
sbraz Oct 25, 2025
7c66d00
fix: LiXee ZLinky: handle empty TIC command list (#10519)
sbraz Oct 26, 2025
1af59fe
fix(detect): Detect `_TZE200_2pddnnrk` as HOBEIAN ZG-223Z (#10523)
eject-dream Oct 26, 2025
203c833
feat(add): BB 287 C https://github.com/Koenkk/zigbee-herdsman-convert…
Koenkk Oct 26, 2025
d740bd4
feat: Frient EMIZB-151: expose energy tiers (#10458)
Fabiancrg Oct 26, 2025
a49739d
feat(add): ZM16B (#10498)
segadora Oct 26, 2025
37f69a8
feat(add): 9290038561 (#10532)
jinnatar Oct 26, 2025
9eeebe6
feat(add): D5Z (#10530)
1tigris1 Oct 26, 2025
03a1809
fix: Woox R9077: disable color power on behaviour and do not disturb …
Koenkk Oct 26, 2025
a5c0e12
chore(master): release 25.54.0 (#10506)
Koenkk Oct 26, 2025
5c7d5a8
fix(ignore): bump the minor-patch group with 2 updates (#10534)
dependabot[bot] Oct 27, 2025
4fca83b
chore: fix external converter bot
Koenkk Oct 27, 2025
1a93759
fix(detect): Detect `_TZ3000_qorepo2x` as Tuya TS0001_power https://g…
Koenkk Oct 27, 2025
8e53a20
feat(add): BOT-R15W (#10537)
kovbalazs89 Oct 27, 2025
39b3f61
fix(detect): Detect `_TZE284_6fk3gewc` as WETEN PCI E https://github.…
Koenkk Oct 27, 2025
af6428e
feat(add): 929003808601 (#10539)
batamire Oct 27, 2025
6c82895
fix: Improve store (#10529)
Nerivec Oct 27, 2025
4b5470d
Revert "feat: Aqara SRTS-A01: expose `local_temperature` (#10471)"
Koenkk Oct 27, 2025
204f9b5
chore(master): release 25.55.0 (#10543)
Koenkk Oct 27, 2025
7913a15
fix(detect): Detect `_TZE284_fwondbzy` as Tuya TS0601_smart_human_pre…
Koenkk Oct 28, 2025
8af886e
fix(detect): Detect `_TZ3000_mh9px7cq` as iHseno _TZ3000_mh9px7cq (#1…
andrei-lazarov Oct 28, 2025
06e65fa
fix(detect): Detect `_TZ3000_ma3mhpx2` as Tuya TS0001_switch_1_gang h…
Koenkk Oct 28, 2025
6d144e0
feat(add): SNZB-02DR2 (#10546)
zmguko Oct 28, 2025
8d72013
fix(detect): Detect `_TZ3000_i9oy2rdq` as Tuya WHD02 https://github.c…
Koenkk Oct 28, 2025
04e0b23
feat(add): 9290038552 (#10548)
grooveborg Oct 28, 2025
00babed
fix(detect): Detect `_TZ3000_5bpeda8u` as Tuya SH-SC07 (#10549)
tl-zigbee Oct 28, 2025
ea19c1b
feat(add): _TZ3000_knoj8lpk (#10553)
andrei-lazarov Oct 28, 2025
6cf5798
feat(add): _TZ3000_mhhxxjrs (#10554)
andrei-lazarov Oct 28, 2025
3fcaad0
fix(detect): Detect `_TZE284_pcdmj88b` as Tuya TS0601_thermostat_4 ht…
Koenkk Oct 28, 2025
7deab07
feat: Tuya TS0001_switch_module: expose indicator mode (#10555)
andrei-lazarov Oct 28, 2025
69ccddd
chore(master): release 25.56.0 (#10556)
Koenkk Oct 28, 2025
413ecdb
fix: AVATTO ME167_1 `_TZE200_p3dbf6qs`: fix weekly schedule day mappi…
manu469 Oct 30, 2025
897525d
fix: Philips Datura: refactor models in devices list (#10559)
TronickDev Oct 30, 2025
3ae6944
fix: Moes ZG-101ZD: fix actions missing (#10562)
prehor Oct 30, 2025
456558d
fix: Fix duplicate poll when interval option changes https://github.c…
Koenkk Oct 30, 2025
4c07485
feat(add): ZS-302Z https://github.com/Koenkk/zigbee2mqtt/issues/29340
Koenkk Oct 30, 2025
c45e371
feat(add): MINI-ZB2GS, MINI-ZB2GS-L (#10459)
liangjia2019 Oct 30, 2025
2fdfc90
feat(add): 1245920 (#10565)
lucasteligioridis Oct 30, 2025
580e80f
fix(detect): Detect `_TZ3000_wijoqjk1` as Tuya TS0001_switch_1_gang (…
skdw Oct 30, 2025
444d586
fix(detect): Detect `_TZE284_loejka0i` as Nous D4Z https://github.com…
Koenkk Oct 30, 2025
6c0bf75
feat: Tuya TZE284_6teua268: improve integration (#10573)
ChristianGr1974 Oct 30, 2025
f62bc72
fix(ignore): Improve TS0601_water_meter (#10578)
Liionboy Oct 30, 2025
67b2fc0
feat(add): SSWM10-ZB (#10567)
christophersjchow Oct 30, 2025
b2d6641
feat(add): Dongle-LMG21 (#10581)
CubeZ2mDeveloper Oct 30, 2025
575be3b
fix: LiXee ZLinky: rename misspelt SMAXSN attributes (#10582)
sbraz Oct 30, 2025
cfa4c41
fix: Tuya ZG-204ZK and ZG-204ZM: various fixes (#10584)
13717033460 Oct 30, 2025
a2d9016
feat(add): 5042148P9 (#10585)
janchlebek Oct 30, 2025
a7941ac
fix: Zemismart ZMO-606-S2: improve integration (#10586)
bernardesarthur Oct 30, 2025
6aec6d1
fix(detect): Detect `_TZE204_vvvtcehj` as Roximo CRTZ01 (#10587)
maxustm Oct 30, 2025
3319f72
fix: Tuya TS0601_soil_3: fix battery % https://github.com/Koenkk/zigb…
Koenkk Oct 30, 2025
f0c3255
chore(master): release 25.57.0 (#10589)
Koenkk Oct 30, 2025
64e0b65
fix(ignore): Tuya: add some forgotten code to disable exposes functio…
Xenomes Oct 31, 2025
69a43b7
fix: Third Reality 3RSB02015Z: add `totalCycleTimes` and `lastRemaini…
3reality-support Oct 31, 2025
3b20763
fix(detect): Detect `_TZE284_vmcgja59` as Tuya ZYXH (#10593)
michalkowol Oct 31, 2025
901fae0
feat(add): ZTRV-ZX-TV02 (#10595)
danmyway Oct 31, 2025
af528f7
feat: Tuya TS0601_water_meter: expose more `fault` options (#10600)
Liionboy Oct 31, 2025
b1363f6
fix: Tuya TS011F_plug: use polling appVersion 192 (#10574)
singler Oct 31, 2025
f68244e
feat(add): SNZB-01M (#10563)
Oniums Oct 31, 2025
0244796
fix: Eurotronic CoZB_dha: expose `current_heating_setpoint` (#10606)
FrankBakkerNl Oct 31, 2025
d813d20
feat(add): TWC-R01 (#10516)
Gouar Oct 31, 2025
6019c81
feat(add): C3007 (#10597)
absent42 Oct 31, 2025
9ed79e3
chore(master): release 25.58.0 (#10605)
Koenkk Oct 31, 2025
8eede2c
fix(ignore): Code for disable the onOffCountdown for Tuya (#10618)
Xenomes Nov 1, 2025
a1e1240
feat(add): QAT44Z6 (#10619)
queroautomacao Nov 1, 2025
a1f04b2
Revert "feat(add): TWC-R01 (#10516)"
Koenkk Nov 1, 2025
7db45f8
chore(master): release 25.59.0 (#10622)
Koenkk Nov 1, 2025
ec79460
feat(add): 929004610602 (#10628)
dirsve Nov 2, 2025
b697329
feat(add): _TZE284_cwyqwqbf (#10630)
Fabiancrg Nov 2, 2025
4d3c668
fix(detect): Detect `_TZE200_cpmgn2cf` as Tuya TS0601_thermostat_2 (#…
freeDom- Nov 2, 2025
53f4613
feat(add): 170-01 (#10611)
bouwew Nov 2, 2025
7970ae5
feat(add): 300686 (#10599)
doncarloz1981 Nov 2, 2025
3b41fca
fix: iHsenso_TS0601_human_presence: rename PIR settings to sensitivit…
Bjk8kds Nov 2, 2025
51e509d
fix: Eurotronic SPZB0001: fix exposed setpoint https://github.com/Koe…
Koenkk Nov 2, 2025
c7e556c
fix: Tuya: fix various plugs detected as TS011F_plug_3 with polling i…
Koenkk Nov 2, 2025
bff7060
chore(master): release 25.60.0 (#10632)
Koenkk Nov 2, 2025
1f3f8dc
fix(ignore): fix typo https://github.com/Koenkk/zigbee2mqtt.io/pull/4357
Koenkk Nov 2, 2025
e3f9c60
feat(add): DOM-Z-105P https://github.com/Koenkk/zigbee2mqtt/issues/29383
Koenkk Nov 3, 2025
2924283
feat: Frient EMIZB-151: expose produced energy (#10634)
Fabiancrg Nov 3, 2025
628b8f7
fix: Add step size to transition https://github.com/Nerivec/zigbee2mq…
Koenkk Nov 3, 2025
f5e49e0
fix(ignore): bump the minor-patch group with 3 updates (#10637)
dependabot[bot] Nov 3, 2025
fa1ecd1
fix: Eurotronic SPZB0001: expose `current_heating_setpoint` before `…
FrankBakkerNl Nov 3, 2025
9e61a78
feat(add): BW-IS9 (#10591)
michelbalzer Nov 3, 2025
4fa1989
feat(add): SR-ZG2868EK7-DIM (#10640)
chris-1243 Nov 3, 2025
6fd39e4
feat(add): MC-z (#10645)
mrmaximas Nov 3, 2025
f2f5fe0
chore(master): release 25.61.0 (#10633)
Koenkk Nov 3, 2025
3789d15
fix: Tuya TS011F_plug_1: fix indicator mode missing https://github.co…
Koenkk Nov 4, 2025
a4b9ad5
feat(add): PSM-29ZBS (#10621)
srandier Nov 4, 2025
6ff025c
chore: Stello add notes about STLO-23 manu specific cluster (#10646)
ic-dev21 Nov 4, 2025
85dff2d
fix: PTVO: check meta property and supports genMultistateInput (#10654)
agav99 Nov 4, 2025
b420af0
feat(add): RM28-LE (#10652)
fals3illusion Nov 4, 2025
e616278
fix(detect): Detect `_TZE200_68nvbi09` as Zemismart ZM16EL-03/33 http…
Koenkk Nov 4, 2025
daba9ca
feat: MultIR MIR-IL100: expose illuminance (#10657)
yuanxin32323 Nov 4, 2025
28a53b0
fix: Tuya TS110E_2gang_2: fix switch type (#10658)
bernardesarthur Nov 4, 2025
65bc011
chore(master): release 25.62.0 (#10661)
Koenkk Nov 4, 2025
e24e4b3
fix: eWeLink CK-BL702-AL-01(7009_Z102LG03-1): fix light not turning o…
atamanishche Nov 5, 2025
e576814
feat(add): TS0004_fan_light_switch (#10626)
Chris971991 Nov 5, 2025
aa6e017
fix(detect): Detect `_TZE200_a1ovdobn` as Moes ZS-D1 https://github.c…
Koenkk Nov 5, 2025
7589490
fix: ZBeacon MC-z: various improvements (#10666)
mrmaximas Nov 5, 2025
b01b2ee
feat(add): 5110.80 (#10667)
chris-1243 Nov 5, 2025
6454360
fix: Candeo C210: enable default response (#10655)
dhc25 Nov 5, 2025
e9230c5
fix(detect): Detect `JETSTROM 3030 NA wall` as IKEA L2205 (#10670)
ronmcg Nov 5, 2025
230462a
fix: Aqara W100: use correct max values for temp_period and humi_peri…
MoeRT09 Nov 5, 2025
09a0bdb
feat(add): MTD285-ZB (#10642)
Bjk8kds Nov 5, 2025
df35fa0
chore(master): release 25.63.0 (#10671)
Koenkk Nov 5, 2025
d649e0c
fix(detect): Detect `_TZ3000_996rpfy6` as Tuya ZD06 (#10673)
tl-zigbee Nov 6, 2025
c7dfeac
feat(add): 4512791 (#10447)
xses79 Nov 6, 2025
a507ad7
feat(add): 5633030P9 (#10674)
chris-1243 Nov 6, 2025
c826c40
feat: Tonguo TOQCB2-80: expose `auto_reclosing` (#10676)
vdiogo Nov 6, 2025
2d0bf78
feat: Develco/Frient REXZB-111: re-work implementation (#10675)
antoineraulin Nov 6, 2025
d4a587e
feat: Shelly S4SW-002P16EU-SWITCH: support more features through RPC …
DataGhost Nov 6, 2025
1637eda
chore(master): release 25.64.0 (#10677)
Koenkk Nov 6, 2025
fc38911
fix: Aqara Z1: fix actions (#10680)
mirackle-spb Nov 7, 2025
b5f8056
fix(detect): Detect `_TZB210_yatkpuha` as MiBoxer E3-ZR (#10681)
gebus93 Nov 7, 2025
0263b80
fix(detect): Detect `Cuber ZLI Router` as SONOFF NSPanelP-Router (#10…
chris-1243 Nov 7, 2025
3c65461
fix: HOBEIAN ZG-302ZM: expose distance and fix sensitivity (#10683)
tl-zigbee Nov 7, 2025
a86c7a0
fix(detect): Detect `3AFE22010402102A` as Konke KK-WA-J01W (#10684)
CCZU1623 Nov 7, 2025
19489aa
fix: Wenzhi MTD285-ZB: various fixes (#10685)
Bjk8kds Nov 7, 2025
369366c
feat(add): QAT44Z6, QADZ4DIN (#10686)
queroautomacao Nov 7, 2025
f28ad12
chore(master): release 25.65.0 (#10687)
Koenkk Nov 7, 2025
856f63a
feat(add): 85000 (#10688)
Krautsalat94 Nov 9, 2025
7e7af46
feat(add): 929004608004 (#10690)
heintz Nov 9, 2025
6a4b449
fix: ZB-IR01 and ZB-TTS01: simplify description (#10692)
Bjk8kds Nov 9, 2025
168f9bc
feat(add): M9Pro (#10679)
markajm Nov 9, 2025
671f322
fix: Tuya CK-BL702-AL-01: update description https://github.com/Koenk…
Koenkk Nov 9, 2025
1b86983
fix(detect): Detect `eco-dim05-zigbee` as Eco-Dim.05 https://github.c…
Koenkk Nov 9, 2025
02fa467
fix: Tuya TS011F_plug_3: enable onOffCountdown (#10695)
andrei-lazarov Nov 9, 2025
989fe52
feat(add): BB 262 (#10697)
stevecostin Nov 9, 2025
3044908
feat(add): 929003597802 (#10698)
jstemberg Nov 9, 2025
aa10eb3
feat: LEDVANCE 4099854293276: support OTA https://github.com/Koenkk/z…
Koenkk Nov 9, 2025
474cda7
feat: Moes ZHT-SR: fix incorrect time (#10693)
AudreynHeadburn Nov 9, 2025
6f5cbdb
feat(add): 1871157 (#10694)
burmistrzak Nov 9, 2025
ee061c1
chore(master): release 25.66.0 (#10705)
Koenkk Nov 9, 2025
33ff0f8
fix(detect): Detect `_TZ3210_7vgttna6` as Tuya TS0001_fingerbot (#10707)
michi2005 Nov 9, 2025
637d806
feat(add): RDM005 (#10691)
brientim Nov 9, 2025
8a592cf
fix(ignore): bump the minor-patch group with 3 updates (#10710)
dependabot[bot] Nov 10, 2025
5ab97eb
feat: SONOFF TRVZB: add temporary mode (#10711)
liangjia2019 Nov 10, 2025
1bc8671
fix(detect): Detect `3AFE12010402102A` as Konke KK-WA-J01W (#10712)
CCZU1623 Nov 10, 2025
30f10fa
fix(detect): Detect `LTD022` as Philips 9290035842 (#10713)
preetpatel Nov 10, 2025
c10d98f
fix: Ronco RM28-LE: fix `work_state` (#10715)
fals3illusion Nov 10, 2025
dda4c91
chore(master): release 25.67.0 (#10708)
Koenkk Nov 10, 2025
d42bccc
feat(add): 929003853701 (#10718)
chris-1243 Nov 11, 2025
f7f4300
fix: Bosch BTH-RM: explicitly enable reporting (#10701)
burmistrzak Nov 11, 2025
df1d31e
feat(add): 929003856303 (#10716)
Wombatzoner Nov 11, 2025
cce8cfe
fix: OSRAM 4058075816459: fix actions for button 3 and 4 https://gith…
Koenkk Nov 12, 2025
ef9a87c
fix: SONOFF SNZB-02: move incorrect control entities to configuration…
blacknell Nov 12, 2025
5219645
feat(add): 3RSB01085Z (#10714)
3reality-support Nov 12, 2025
db94a15
feat: Aqara ZNJLBL01LM: support `reverse_direction` (#10724)
deiger Nov 12, 2025
a2b1ec0
fix(detect): Detect `_TZE200_4utwozi2` and `_TZE200_4utwoz2` as ME167…
RothBoy Nov 12, 2025
eff2928
chore(master): release 25.68.0 (#10720)
Koenkk Nov 12, 2025
8e9205f
Merge branch 'master' into fix-owon-device
jacky202509 Nov 13, 2025
d269d5e
feat(TS0601): add high-precision AC frequency (DP135) for 3-phase cla…
jacky202509 Nov 13, 2025
d7a4585
types: add optional applicationVersion to DummyDevice for exposes
jacky202509 Nov 13, 2025
584f045
Merge branch 'master' into fix-owon-device
jacky202509 Dec 26, 2025
1bf68a6
feat(owon): add AC221 IR device with one-key pairing support
jacky202509 Dec 26, 2025
7fa9c15
u
Koenkk Dec 26, 2025
abd143e
fix(owon): revert CB432 changes; align AC221 and SLC631 with review f…
jacky202509 Dec 31, 2025
454f87b
Merge branch 'master' into fix-owon-device
jacky202509 Dec 31, 2025
e2c1b0f
Improve typing
Koenkk Jan 1, 2026
2b6cd0d
Merge branch 'master' into fix-owon-device
jacky202509 Jan 4, 2026
c34a69b
feat(OWON): add WSP403 WSP402 using modernExtend with custom metering…
jacky202509 Jan 4, 2026
b8fab5e
[autofix.ci] apply automated fixes
autofix-ci[bot] Jan 4, 2026
65334f7
fix(owon): align WSP403 metering reporting with defaults
jacky202509 Jan 6, 2026
a0eee76
Apply suggestion from @Koenkk
Koenkk Jan 7, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
318 changes: 301 additions & 17 deletions src/devices/owon.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {Zcl} from "zigbee-herdsman";
import type {ClusterDefinition} from "zigbee-herdsman/dist/zspec/zcl/definition/tstype";
import * as fz from "../converters/fromZigbee";
import * as tz from "../converters/toZigbee";
import * as exposes from "../lib/exposes";
Expand All @@ -9,6 +10,99 @@ import type {DefinitionWithExtend, Fz, KeyValue, Tz} from "../lib/types";
const e = exposes.presets;
const ea = exposes.access;

interface OwonAcControl {
attributes: Record<string, never>;
commands: {
oneKeyPairingRequest: {oneKeyPairingStart: number}; // 0x00 end, 0x01 start
writePairingCode: {pairingCode: number};
readPairingCodeRequest: Record<string, never>;
};
commandResponses: never;
}

const owonExtendChecks = {
parseOneKeyPairingInput: (input: unknown) => {
const action = String(input).toLowerCase().trim();

let startParam: number;
if (action === "start" || action === "on" || action === "true") {
startParam = 0x01;
} else if (action === "end" || action === "off" || action === "false") {
startParam = 0x00;
} else {
throw new Error(`Invalid value for one_key_pairing: expected "start"/"on"/"true" or "end"/"off"/"false", got "${input}"`);
}

return {
payload: {
oneKeyPairingStart: startParam,
},
};
},

parsePairingCodeInput: (input: unknown) => {
if (input === undefined || input === null) {
throw new Error("pairing_code is required");
}

const codeStr = typeof input === "number" ? Math.trunc(input).toString() : String(input).trim();

if (!/^\d+$/.test(codeStr)) {
throw new Error(`Invalid pairing_code "${codeStr}", must be decimal number`);
}

const codeNum = Number(codeStr);

if (codeNum < 0 || codeNum > 65535) {
throw new Error(`Invalid pairing_code "${codeStr}", must be between 0 and 65535`);
}

return {
payload: {
pairingCode: codeNum,
},
};
},
};

const OwonClustersDefinition: {[s: string]: ClusterDefinition} = {
manuSpecificOwonAc: {
ID: 0xffac,
manufacturerCode: Zcl.ManufacturerCode.OWON_TECHNOLOGY_INC,
attributes: {},
commands: {
oneKeyPairingRequest: {
ID: 0x52,
parameters: [
{name: "oneKeyPairingStart", type: Zcl.DataType.UINT8}, // 0x00 end, 0x01 start
],
},
writePairingCode: {
ID: 0x20,
parameters: [{name: "pairingCode", type: Zcl.DataType.UINT16}],
},
readPairingCodeRequest: {
ID: 0x00,
parameters: [],
},
},
commandsResponse: {
oneKeyPairingResponse: {
ID: 0x52,
parameters: [{name: "receiveStatus", type: Zcl.DataType.UINT8}],
},
oneKeyPairingResultUpdate: {
ID: 0x80,
parameters: [],
},
readPairingCodeResponse: {
ID: 0x00,
parameters: [{name: "pairingCode", type: Zcl.DataType.UINT16}],
},
},
},
};

interface OwonFallDetection {
attributes: {
status: number;
Expand Down Expand Up @@ -185,6 +279,78 @@ const fzLocal = {
return result;
},
} satisfies Fz.Converter<"fallDetectionOwon", OwonFallDetection, ["attributeReport", "readResponse"]>,

owonAcOneKeyPairingResponse: {
cluster: "manuSpecificOwonAc",
type: ["commandOneKeyPairingResponse", "commandOneKeyPairingResultUpdate"],
convert: (model, msg, publish, options, meta) => {
if (msg.meta?.manufacturerCode !== Zcl.ManufacturerCode.OWON_TECHNOLOGY_INC) {
return {};
}

const payload: KeyValue = {};

if (msg.type === "commandOneKeyPairingResponse") {
const status = msg.data?.receiveStatus;
if (status !== undefined) {
payload.one_key_pairing_status = status === 0x00 ? "SUCCESS" : "FAILURE";
}
}

if (msg.type === "commandOneKeyPairingResultUpdate") {
let buffer: Buffer | undefined;

if (Buffer.isBuffer(msg.meta?.rawData)) {
buffer = msg.meta.rawData;
}

if (!buffer || buffer.length < 6) {
payload.one_key_pairing_result = {
count: 0,
codes_found: [],
};
return payload;
}

const payloadOffset = 5;
const count = buffer.readUInt8(payloadOffset);
const codes: number[] = [];

let offset = payloadOffset + 1;
for (let i = 0; i < count; i++) {
if (offset + 1 >= buffer.length) break;
codes.push(buffer.readUInt16LE(offset));
offset += 2;
}

payload.one_key_pairing_result = {
count,
codes_found: codes,
};
}

return payload;
},
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use satisfies Fz.Converter< with the custom cluster definition here

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adjusted to satisfies Fz.Converter for the manufacturer-specific cluster; command types are kept untyped as they are not part of ZCL definitions.

// biome-ignore lint/suspicious/noExplicitAny: third-party converter signature requires any
} satisfies Fz.Converter<"manuSpecificOwonAc", undefined, any>,

owonAcReadPairingCodeResponse: {
cluster: "manuSpecificOwonAc",
type: ["commandReadPairingCodeResponse"],
convert: (model, msg, publish, options, meta) => {
if (msg.data?.pairingCode !== undefined) {
const code = msg.data.pairingCode;
const displayCode = code === 0xffff ? null : code;

return {
pairing_code_current: displayCode,
};
}

return {};
},
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adjusted to satisfies Fz.Converter for the manufacturer-specific cluster; command types are kept untyped as they are not part of ZCL definitions.

// biome-ignore lint/suspicious/noExplicitAny: third-party converter signature requires any
} satisfies Fz.Converter<"manuSpecificOwonAc", undefined, any>,
};

const tzLocal = {
Expand Down Expand Up @@ -242,6 +408,50 @@ const tzLocal = {
);
},
} satisfies Tz.Converter,

owonAcOneKeyPairing: {
key: ["one_key_pairing"],
convertSet: async (entity, key, value, meta) => {
meta.state.one_key_pairing_status = null;
meta.state.one_key_pairing_result = null;
const commandWrapper = owonExtendChecks.parseOneKeyPairingInput(value);

await entity.command<"manuSpecificOwonAc", "oneKeyPairingRequest", OwonAcControl>(
"manuSpecificOwonAc",
"oneKeyPairingRequest",
commandWrapper.payload,
{disableDefaultResponse: true},
);
},
} satisfies Tz.Converter,

owonAcWritePairingCode: {
key: ["pairing_code"],
convertSet: async (entity, key, value, meta) => {
const commandWrapper = owonExtendChecks.parsePairingCodeInput(value);

meta.state.pairing_code = String(value);

await entity.command<"manuSpecificOwonAc", "writePairingCode", OwonAcControl>(
"manuSpecificOwonAc",
"writePairingCode",
commandWrapper.payload,
{disableDefaultResponse: true},
);
},
} satisfies Tz.Converter,

owonAcReadPairingCode: {
key: ["pairing_code_current"],
convertGet: async (entity, key, meta) => {
await entity.command<"manuSpecificOwonAc", "readPairingCodeRequest", OwonAcControl>(
"manuSpecificOwonAc",
"readPairingCodeRequest",
{},
{disableDefaultResponse: true},
);
},
} satisfies Tz.Converter,
};

export const definitions: DefinitionWithExtend[] = [
Expand All @@ -250,15 +460,29 @@ export const definitions: DefinitionWithExtend[] = [
model: "WSP402",
vendor: "OWON",
description: "Smart plug",
extend: [m.onOff(), m.electricityMeter({cluster: "metering"})],
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The device is now migrated to modernExtend.
Power-on behavior is intentionally disabled as WSP402 does not reliably support startUpOnOff.

A minimal configure() is kept only to customize metering reporting parameters,
which are not configurable via modernExtend in this codebase.

extend: [
m.onOff({powerOnBehavior: false}),
m.electricityMeter({
cluster: "metering",
}),

m.forcePowerSource({powerSource: "Mains (single phase)"}),
],
},
{
zigbeeModel: ["WSP403-E"],
model: "WSP403",
vendor: "OWON",
whiteLabel: [{vendor: "Oz Smart Things", model: "WSP403"}],
description: "Smart plug",
extend: [m.onOff(), m.electricityMeter({cluster: "metering"}), m.forcePowerSource({powerSource: "Mains (single phase)"})],
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use this instead of the configure/tozigbee/fromzigbee/expose

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The device is now migrated to modernExtend.
Power-on behavior is intentionally disabled as WSP403 does not reliably support startUpOnOff.

A minimal configure() is kept only to customize metering reporting parameters,
which are not configurable via modernExtend in this codebase.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A minimal configure() is kept only to customize metering reporting parameters,

To have a consistent experience, all devices should have the same reporting parameters unless there is a really good reason not to, is there one in this case?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The custom reporting parameters are added because WSP403 reports
metering data very infrequently with the default configuration.

In practice this results in delayed or missing power updates,
which makes real-time power monitoring unreliable for this device.

The adjusted reporting improves usability without increasing
network traffic significantly.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WSP403 reports metering data very infrequently

I don't understand, it should report with the same frequency as all other plugs right? The default can be found here:

// Report change with every 0.05A change

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right, thanks for pointing this out.

After reviewing modernExtend.electricityMeter(), it already configures
standard reporting for seMetering.
The custom configure() is not needed here and will be removed to keep
reporting consistent with other devices.

extend: [
m.onOff({powerOnBehavior: false}),
m.electricityMeter({
cluster: "metering",
}),

m.forcePowerSource({powerSource: "Mains (single phase)"}),
],
},
{
zigbeeModel: ["WSP404"],
Expand Down Expand Up @@ -331,6 +555,60 @@ export const definitions: DefinitionWithExtend[] = [
await reporting.thermostatAcLouverPosition(endpoint);
},
},
{
zigbeeModel: ["AC221"],
model: "AC221",
vendor: "OWON",
description: "AC controller / IR blaster",
extend: [m.deviceAddCustomCluster("manuSpecificOwonAc", OwonClustersDefinition.manuSpecificOwonAc)],
fromZigbee: [fz.fan, fz.thermostat, fzLocal.owonAcOneKeyPairingResponse, fzLocal.owonAcReadPairingCodeResponse],
toZigbee: [
tz.fan_mode,
tz.thermostat_system_mode,
tz.thermostat_occupied_heating_setpoint,
tz.thermostat_occupied_cooling_setpoint,
tz.thermostat_ac_louver_position,
tz.thermostat_local_temperature,
tzLocal.owonAcOneKeyPairing,
tzLocal.owonAcWritePairingCode,
tzLocal.owonAcReadPairingCode,
],

exposes: [
// --- One Key Pairing Exposes ---
e.enum("one_key_pairing", ea.SET, ["start", "end"]),
e.text("one_key_pairing_status", ea.STATE).withDescription("Status of the last one key pairing request command."),
e.text("one_key_pairing_result", ea.STATE).withDescription("Final result of one key pairing process (JSON string, device reported)."),
e
.numeric("pairing_code_current", ea.STATE_GET)
.withDescription("Currently set pairing code on the device (null if invalid)")
.withUnit("")
.withValueMin(0)
.withValueMax(65535),
e.text("pairing_code", ea.SET).withDescription("Manually write pairing code to device (decimal digits only, e.g. 123456)."),
e
.climate()
.withSystemMode(["off", "heat", "cool", "auto", "dry", "fan_only"])
.withSetpoint("occupied_heating_setpoint", 8, 30, 1)
.withSetpoint("occupied_cooling_setpoint", 8, 30, 1)
.withLocalTemperature(),
e.fan().withModes(["low", "medium", "high", "on", "auto"]),
],

configure: async (device, coordinatorEndpoint) => {
const endpoint = device.getEndpoint(1);
const binds = ["genBasic", "genIdentify", "genTime", "hvacThermostat", "hvacFanCtrl"];

await reporting.bind(endpoint, coordinatorEndpoint, binds);

await reporting.thermostatTemperature(endpoint, {min: 60, max: 600, change: 0.1});
await reporting.thermostatOccupiedHeatingSetpoint(endpoint);
await reporting.thermostatOccupiedCoolingSetpoint(endpoint);
await reporting.thermostatSystemMode(endpoint);

await reporting.fanMode(endpoint);
},
},
{
zigbeeModel: ["THS317"],
model: "THS317",
Expand Down Expand Up @@ -604,19 +882,19 @@ export const definitions: DefinitionWithExtend[] = [
ID: 0xfd00,
manufacturerCode: Zcl.ManufacturerCode.OWON_TECHNOLOGY_INC,
attributes: {
status: {ID: 0x0000, type: Zcl.DataType.ENUM8, write: true, max: 0xff},
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why was this removed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This attribute is now defined via deviceAddCustomCluster. In this typed definition write is not a supported property anymore, so it’s omitted while keeping the same functionality.

breathing_rate: {ID: 0x0002, type: Zcl.DataType.UINT8, write: true, max: 0xff},
location_x: {ID: 0x0003, type: Zcl.DataType.INT16, write: true, min: -32768},
location_y: {ID: 0x0004, type: Zcl.DataType.INT16, write: true, min: -32768},
bedUpperLeftX: {ID: 0x0100, type: Zcl.DataType.INT16, write: true, min: -32768},
bedUpperLeftY: {ID: 0x0101, type: Zcl.DataType.INT16, write: true, min: -32768},
bedLowerRightX: {ID: 0x0102, type: Zcl.DataType.INT16, write: true, min: -32768},
bedLowerRightY: {ID: 0x0103, type: Zcl.DataType.INT16, write: true, min: -32768},
doorCenterX: {ID: 0x0108, type: Zcl.DataType.INT16, write: true, min: -32768},
doorCenterY: {ID: 0x0109, type: Zcl.DataType.INT16, write: true, min: -32768},
leftFallDetectionRange: {ID: 0x010c, type: Zcl.DataType.UINT16, write: true, max: 0xffff},
rightFallDetectionRange: {ID: 0x010d, type: Zcl.DataType.UINT16, write: true, max: 0xffff},
frontFallDetectionRange: {ID: 0x010e, type: Zcl.DataType.UINT16, write: true, max: 0xffff},
status: {ID: 0x0000, type: Zcl.DataType.ENUM8},
breathing_rate: {ID: 0x0002, type: Zcl.DataType.UINT8},
location_x: {ID: 0x0003, type: Zcl.DataType.INT16},
location_y: {ID: 0x0004, type: Zcl.DataType.INT16},
bedUpperLeftX: {ID: 0x0100, type: Zcl.DataType.INT16},
bedUpperLeftY: {ID: 0x0101, type: Zcl.DataType.INT16},
bedLowerRightX: {ID: 0x0102, type: Zcl.DataType.INT16},
bedLowerRightY: {ID: 0x0103, type: Zcl.DataType.INT16},
doorCenterX: {ID: 0x0108, type: Zcl.DataType.INT16},
doorCenterY: {ID: 0x0109, type: Zcl.DataType.INT16},
leftFallDetectionRange: {ID: 0x010c, type: Zcl.DataType.UINT16},
rightFallDetectionRange: {ID: 0x010d, type: Zcl.DataType.UINT16},
frontFallDetectionRange: {ID: 0x010e, type: Zcl.DataType.UINT16},
},
commands: {},
commandsResponse: {},
Expand Down Expand Up @@ -648,13 +926,19 @@ export const definitions: DefinitionWithExtend[] = [
vendor: "OWON",
description: "Smart plug with doorbell press indicator",
extend: [
m.onOff({endpointNames: ["l1", "l2", "l3"]}),
m.deviceEndpoints({
endpoints: {
l1: 1,
l2: 2,
l3: 3,
},
}),
m.onOff({endpointNames: ["l1", "l2", "l3"], powerOnBehavior: false}),
m.iasZoneAlarm({
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use m.deviceEndpoints here (remove meta: {multiEndpoint: true}, and endpoint: (device) => ({l1: 1, l2: 2, l3: 3}),)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using m.deviceEndpoints handles multi-endpoint, so meta.multiEndpoint is not needed.
This device does not support the StartUpOnOff attribute, so powerOnBehavior is explicitly disabled.

zoneType: "contact",
zoneAttributes: ["alarm_2"],
}),
],
endpoint: (device) => ({l1: 1, l2: 2, l3: 3}),
configure: async (device, coordinatorEndpoint) => {
const ep2 = device.getEndpoint(2);
if (ep2) {
Expand Down