Oui, c’est bien pour cela que j’avais opté pour ce modèle. Mais soit j’ai eu une très ancienne version de firmware, soit au contraire un nouveau modèle. Je pense plutôt pour cette seconde option, car j’ai trouvé 2 références au modèle exact (_TZE284_aaeaifez) sur le GitHub Z2M, et les posts datent de 2 semaines seulement.
https://github.com/koenkk/zigbee2mqtt/issues/29062
https://github.com/Koenkk/zigbee-herdsman-converters/issues/10397
Il y a peut-être une solution avec une définition externe et/ou la branche développement.
Du coup, comme il y a de l’activité sur ce produit, je vais peux-être les conserver et attendre de voir ce que ça donne.
[EDIT] Suite de mes pérégrinations.
J’ai essayé le “external converteur” fourni dans le deuxième lien ci-dessus et cela fonctionne ! Il y a cependant une petite modification à apporter, sinon les modes auto/manu sont inversés. Donc pour ceux qui veulent tenter l’expérience:
- création du fichier /homeassistant/zigbee2mqtt/external_converters/zwt100_custom.js (pour information, /homeassistant = /config) avec le code ci-dessous
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 tuya = require('zigbee-herdsman-converters/lib/tuya');
const e = exposes.presets;
const ea = exposes.access;
const definition = {
fingerprint: tuya.fingerprint("TS0601", [
"_TZE200_viy9ihs7",
"_TZE204_lzriup1j",
"_TZE204_xnbkhhdr",
"_TZE284_xnbkhhdr",
"_TZE204_oh8y8pv8",
"_TZE204_gops3slb",
"_TZE284_gops3slb",
"_TZE284_aaeaifez",
]),
model: "ZWT198/ZWT100-BH",
vendor: "Tuya",
description: "Wall thermostat",
extend: [tuya.modernExtend.tuyaBase({dp: true, respondToMcuVersionResponse: false})],
whiteLabel: [tuya.whitelabel("AVATTO", "WT-100-BH", "Wall thermostat", ["_TZE204_gops3slb", "_TZE284_gops3slb"])],
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" ||
device.manufacturerName === "_TZE284_aaeaifez"
) {
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;
- Modification du fichier /homeassistant/zigbee2mqtt/configuration.yaml. Ajouter :
external_converters:
- external_converters/zwt100_custom.js
Le code ci-dessus diffère de celui de GitHub par l’ajout de :
|| device.manufacturerName === "_TZE284_aaeaifez"
dans la boucle ‘if’ du tuyaDataPoint [4] (il y a d’autres modèles qui semblent être également inversés).
Et hop :
Je continue les tests au cas où quelque chose ne fonctionnerait pas (et dans ca cas, je complèterai ce post), mais en ce qui me concerne : résolu 
[EDIT2] Bon, je crois que j’ai définitivement la loose. Après tout ces efforts pour le faire fonctionner, il n’est plus disponible ou alors au double du prix sur Amaz* 