Besoin d'aide a l'integration d'un thermostat on supporté par Zigbee2MQTT

Mon problème

Bonjour,

Je viens d’emménager dnas mon nouvel appartement, équipé de radiateurs connectables.
Ces radiateurs ont le module thermostat suivant :

Leur intégration wifi sur une appli mobile marche asez bien, mais c’est loin d’être l’idéal en terme de vie privée, et ce n’est évidemment pas intégré à mon système HA. (l’appli dépend de la marque du radiateur, mais en pratique ce sont toutes des forks du celle du vendeur du thermostat)

Mais fort heursement, le thermostat est indiqué comme compatible Zigbee.
Je me rends compte alors :

  • il n’est pas supporté dans la banque d’appareils Zigbee2MQTT
  • j’ai essayé un appareilalge via ZHA, mais je n’ai accès qu’a la valeur de température ambiante. Aucun controle posible du thermostat, ce qui est a contrario possible via leur appli et connecton Wifi.

J’essaye donc de suivre le tuto d’intégration d’appareils non supportés :

Seulement, je galère un peu !
Mon fichier .js de configuration est pour l’instant le suivant (j’ai utilisé le converter thermostat par défaut) :

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 extend = require('zigbee-herdsman-converters/lib/extend');
const e = exposes.presets;
const ea = exposes.access;

const definition = {
    zigbeeModel: ['PH25'], // The model ID from: Device with modelID 'lumi.sens' is not supported.
    model: 'PH25', // Vendor model number, look on the device for a model number
    vendor: 'Imhotep creation', // Vendor of the device (only used for documentation and startup logging)
    description: 'Heater thermostat', // Description of the device, copy from vendor site. (only used for documentation and startup logging)
    fromZigbee: [fz.thermostat], // added from log and following converter https://github.com/Koenkk/zigbee-herdsman-converters/blob/master/converters/fromZigbee.js
    toZigbee: [], // Should be empty, unless device can be controlled (e.g. lights, switches).
    exposes: [e.temperature()], // Defines what this device exposes, used for e.g. Home Assistant discovery and in the frontend
};

module.exports = definition;

Du coup : j’arrive a récupérer la température locale et la consigne de température via la console de dev

Mais impossible d’écrire une consigne,
Ce qui semble normal, car :
toZigbee: [],

seulement, si je change cette ligne par :
toZigbee: [tz.thermostat],
Alors Z2m ne se lance plus. Voici le log d’erreur au démarrage :

[17:49:52] INFO: Preparing to start...
[17:49:52] INFO: Socat not enabled
[17:49:53] INFO: Starting Zigbee2MQTT...
/app/node_modules/zigbee-herdsman-converters/index.js:91
        if (converter.options) {
                      ^
TypeError: Cannot read properties of undefined (reading 'options')
    at Object.addDefinition [as addDeviceDefinition] (/app/node_modules/zigbee-herdsman-converters/index.js:91:23)
    at new ExternalConverters (/app/lib/extension/externalConverters.ts:15:17)
    at new Controller (/app/lib/controller.ts:84:58)
    at start (/app/index.js:106:18)

Du coup je sèche.

Second problème, je n’arrive pas a sortir en expose les data que je vois en consile dev.
e.temperature() renvoie toujours null, et toutes mes tentatives de modifier cette ligne font crasher Z2m au démarrage.

Je planche vraiement, et ça m’embète pas mal. :confused:
Avez-vous une aide à m’apporter pour ajouter proprement cete appareil à Z2M ?

Merci d’avance

PS : j’ai contacté en amont le fabriquant pour avoir son aide, mais il fait visiblement la sourde oreille.
PSS : voici pour info ce à quoi ressemble l’onglet « état » de l’appareil sous Zigbee2mqtt:

{
    "linkquality": 87,
    "local_temperature": 17.96,
    "max_heat_setpoint_limit": 19,
    "min_heat_setpoint_limit": 5,
    "occupied_cooling_setpoint": null,
    "occupied_heating_setpoint": 15.5,
    "temperature_setpoint_hold": false,
    "unoccupied_heating_setpoint": null
}

Ma configuration


System Information

version core-2023.1.7
installation_type Home Assistant OS
dev false
hassio true
docker true
user root
virtualenv false
python_version 3.10.7
os_name Linux
os_version 5.15.90
arch x86_64
timezone Europe/Paris
config_dir /config
Home Assistant Community Store
GitHub API ok
GitHub Content ok
GitHub Web ok
GitHub API Calls Remaining 4996
Installed Version 1.31.0
Stage running
Available Repositories 1247
Downloaded Repositories 5
Home Assistant Cloud
logged_in false
can_reach_cert_server ok
can_reach_cloud_auth ok
can_reach_cloud ok
Home Assistant Supervisor
host_os Home Assistant OS 9.5
update_channel stable
supervisor_version supervisor-2023.03.1
agent_version 1.4.1
docker_version 20.10.22
disk_total 30.8 GB
disk_used 7.9 GB
healthy true
supported true
board ova
supervisor_api ok
version_api ok
installed_addons Grafana (8.1.0), InfluxDB (4.5.0), File editor (5.5.0), Node-RED (14.1.0), Mosquitto broker (6.1.3), Zigbee2MQTT (1.30.2-1), Terminal & SSH (9.6.1)
Dashboards
dashboards 1
resources 2
views 2
mode storage
Recorder
oldest_recorder_run 6 mars 2023 à 11:02
current_recorder_run 19 mars 2023 à 11:25
estimated_db_size 579.19 MiB
database_engine sqlite
database_version 3.38.5
___

Bonjour,

j’ai pu avancer (un tout petit peu) sur mon fichier .js de configuration, en me basant sur des exemples trouvés sur le net:

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 extend = require('zigbee-herdsman-converters/lib/extend');
const e = exposes.presets;
const ea = exposes.access;

const definition = {
    zigbeeModel: ['PH25'], // The model ID from: Device with modelID 'lumi.sens' is not supported.
    model: 'PH25', // Vendor model number, look on the device for a model number
    vendor: 'Imhotep creation', // Vendor of the device (only used for documentation and startup logging)
    description: 'Heater thermostat', // Description of the device, copy from vendor site. (only used for documentation and startup logging)
    fromZigbee: [fz.thermostat], // added from log and following converter https://github.com/Koenkk/zigbee-herdsman-converters/blob/82acbbae0dff40269c935921f50bd03fc303b3ea/converters/fromZigbee.js
    toZigbee: [tz.thermostat_local_temperature, tz.thermostat_occupancy, tz.thermostat_occupied_heating_setpoint], // Should be empty, unless device can be controlled (e.g. lights, switches).
    exposes: [exposes.climate().withSetpoint('occupied_heating_setpoint', 7, 30, 1).withLocalTemperature()], // Defines what this device exposes, used for e.g. Home Assistant discovery and in the frontend
};

module.exports = definition;

Du coup, je peux dorénavant définir la valeur du point de consigne de chauffage occupé via la console de développement. Le thermostat est effectivement mis à jour, avec un nouveau point de consigne de température (pour une courte période cependant, car le thermostat revient à un « réglage » après un certain temps). Les réglages sont « auto » (c’est à dire programmé), « comfort », « eco » ou « Frost protection ».

Premier problème, je n’arrive pas mettre en expose les données que je vois dans la console de développement.

Deuxième problème : je n’ai aucune idée d’où trouver les réglages de température (auto, confort, eco, etc) dont j’ai besoin pour construire efficacement un programme de chauffage intelligent (HA). Comme je l’ai dit précédemment, la modification du point de consigne de la température est considérée comme une annulation temporaire du point de consigne par défaut des paramètres actuels.

Merci d’avance pour votre aide.

Re-bonjour,

J’ai demandé de l’aide à ChatGPT, afin - sait-on jamais- de me débloquer.

Mon fichier .js ressemble maintenant à ça :

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 extend = require('zigbee-herdsman-converters/lib/extend');
const e = exposes.presets;
const ea = exposes.access;

const definition = {
    zigbeeModel: ['PH25'], // The model ID from: Device with modelID 'lumi.sens' is not supported.
    model: 'PH25', // Vendor model number, look on the device for a model number
    vendor: 'Imhotep creation', // Vendor of the device (only used for documentation and startup logging)
    description: 'Heater thermostat', // Description of the device, copy from vendor site. (only used for documentation and startup logging),
fromZigbee: [fz.thermostat, fz.hvac_user_interface],
toZigbee: [
tz.thermostat_local_temperature,
tz.thermostat_system_mode,
tz.thermostat_occupied_heating_setpoint,
tz.thermostat_unoccupied_heating_setpoint,
tz.thermostat_occupied_cooling_setpoint,
tz.thermostat_running_state,
],
exposes: [
exposes.climate()
.withSetpoint('occupied_heating_setpoint', 7, 28, 0.5)
.withLocalTemperature()
.withSystemMode(['off', 'heat', 'auto'])
.withRunningState(['idle', 'heat']),
],
configure: async (device, coordinatorEndpoint, logger) => {
const endpoint = device.getEndpoint(1);
await reporting.bind(endpoint, coordinatorEndpoint, ['genPowerCfg', 'hvacThermostat']);
await reporting.thermostatTemperature(endpoint);
await reporting.thermostatRunningState(endpoint);
await reporting.thermostatOccupiedHeatingSetpoint(endpoint);
await reporting.thermostatUnoccupiedHeatingSetpoint(endpoint);
},
};

module.exports = definition;

Pour autant, pas d’évolution du coté des exposes.

Cependant, ChatGPT m’a suggéré d’aller voir du coté de MQTT explorer, pour avoir l’intégralité des messages transmis.
J’ai donc installé le plugin, qui effectivement affiche l’intégralité des appareils et logs.

Et je me rends alors comtpe que mon radiateur n’est pas dans la liste des appareils !


(aucune adresse IEEE ne correspond à mon radiateur. j’ai déconnecté puis ré-appairé le radiateur, pour le même résultat).

Pour autant, il est connecté sous le plugin zigbee2mqtt de home assistant. Et lorsque j’écris ou lis la propriété « OccupiedHeatinSetPoint », j’ai bien un log dans Z2mqtt, et je vois bien ce même log dans zigbee2mqtt/bridge/logging.

Y-a-t’il quelque chose à regarder du coté de la connexion de mon radiateur, qui expliquerait que je n’ai aucun expose ?

Salut.
J’avais pas vu le sujet et j’ai pas forcement beaucoup de conseils mais :
Vois-tu quels sont les ID qui sont utilisés lors de l’appairage ?

il faut s’assurer que ça matche sinon ton converter ne sera pas utilisé

Ensuite, n’y a-t-il pas une matériel identique (sous une autre marque) dans z2M ?
ça permettrai de faire un ‹ alias › plutôt qu’un nouveau matériel complet (et de deviner les entrypoints)

Je n’ai pas trouvé de matériel identique sou une autre marque, donc je m’inspire de ce que je trouve, car au départ je n’y connais absolument rien :slight_smile: (et la société Imothep creation ne répond pas à mes sollicitations).

Concernant les IDs :Bon sang c’était juste ça !! :slight_smile:

Du coup j’ai mes exposes affichées, et le device disponible dans mqtt explorer.
je vais donc essayer pas a pas de configurer le bazar ! je vais pas mal galéré je pense, et il est possible que je revienne vers vous encore :).

merci !

1 « J'aime »

Suite à l’aide qui m’a été apportée, je peux dorénavent avoir des exposes fonctionnelles, comme la température de consigne.

Cependant, l’intégration est loin d’être optimale.
en effet, je n’arrive pas à récupérer ou assigner le mode sélectionné su le thermostat : « auto » , « comfort », « eco » ou « Frost protection ».

J’ai branché les expose suivant :

exposes:
[
    exposes.climate()
    .withSetpoint('occupied_heating_setpoint', 7, 28, 0.5)
    .withLocalTemperature()
    .withLocalTemperatureCalibration()
    .withSystemMode(['off', 'auto','cool','heat', 'fan_only','dry']) // 'emergency_heating','precooling','sleep'
    .withRunningState(['idle', 'heat', 'cool'])
    .withControlSequenceOfOperation(['cooling_only','cooling_with_reheat','heating_only','heating_with_reheat','cooling_and_heating_4-pipes','cooling_and_heating_4-pipes_with_reheat']), 
    e.occupancy(),
],

Sauf erreur de ma part, ce qui m’intéresse, c’est SystemMode. J’ai défini les enum d’après la doc de Zigbee2mqtt, pour déjà voir ce que ca pouvait donner.
Sauf que :

  • seul le mode Off éteint le thermostat. tout autre mode le rallume. (ca c’est normal a vrai dire).
  • le choix des autrees modes n’a aucune incidence sur le mode effectif du thermostat
  • si je change manuellement le mode sur le thermostat, je ne vois aucun changement quand MQTT explorer.

Avez-vous des idées pour trouver comment avancer sur cette intégration des modes de chauffage ?

Merci d’avance !

Je suis loin d’être un expert mais si je compare avec le fil pilote legrand, la déclaration des modes est différente et passe pas un enum

    {
        zigbeeModel: [' Cable outlet\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000' +
            '\u0000\u0000'],
        model: '064882',
        vendor: 'Legrand',
        description: 'Cable outlet with pilot wire and consumption measurement',
        ota: ota.zigbeeOTA,
        fromZigbee: [fz.legrand_cluster_fc01, fz.legrand_cable_outlet_mode, fz.on_off, fz.electrical_measurement, fz.power_on_behavior],
        toZigbee: [tz.legrand_deviceMode, tz.legrand_cableOutletMode, tz.on_off, tz.electrical_measurement_power, tz.power_on_behavior],
        exposes: [exposes.binary('device_mode', ea.ALL, 'pilot_on', 'pilot_off'),
            exposes.enum('cable_outlet_mode', ea.ALL, ['comfort', 'comfort-1', 'comfort-2', 'eco', 'frost_protection', 'off']),
            exposes.switch().withState('state', true, 'Works only when the pilot wire is deactivated'),
            e.power().withAccess(ea.STATE_GET),
            e.power_apparent(),
            e.power_on_behavior().withDescription(`Controls the behavior when the device is powered on. Works only when the pilot wire is
                deactivated`)],
        configure: async (device, coordinatorEndpoint, logger) => {
            const endpoint = device.getEndpoint(1);
            await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff', 'haElectricalMeasurement', 'manuSpecificLegrandDevices2']);
            await reporting.onOff(endpoint);
            await reporting.readEletricalMeasurementMultiplierDivisors(endpoint);
            await reporting.activePower(endpoint);
            await reporting.apparentPower(endpoint);
        },
    },thLocalTemperature()
    .withLocalTemperatureCalibration()
    .withSystemMode(['off', 'auto','cool','heat', 'fan_only','dry']) // 'emergency_heating','precooling','sleep'
    .withRunningState(['idle', 'heat', 'cool'])
    .withControlSequenceOfOperation(['cooling_only','cooling_with_reheat','heating_only','heating_with_reheat','cooling_and_heating_4-pipes','cooling_and_heating_4-pipes_with_reheat']), 
    e.occupancy(),
],

C’est pê différent pour un thermostat mais j’en ai pas sous la main

1 « J'aime »

Je ne sais pas comment avancer afin de bien configurer l’ensemble, donc je me suis dit que regarder ce que renvoyait le thermostat lors de l’appui sur les touches physyiques (changement de mode par exemple) pouvait donner sur MQTTExplorer.

J’ai activé le loggin debug du Brocker MQTT, et sors du changement de mode via l’appui sur une touche, j’obtiens ceci sous MQTTExplorer (logging):

{"level":"debug","message":"Received Zigbee message from '0x540f57fffebab25a', type 'attributeReport', cluster 'hvacThermostat', data '{\"16384\":2}' from endpoint 1 with groupID 0"}

{"level":"debug","message":"Received Zigbee message from '0x540f57fffebab25a', type 'attributeReport', cluster 'hvacThermostat', data '{}' from endpoint 1 with groupID 0"}

{"level":"info","message":"MQTT publish: topic 'zigbee2mqtt/0x540f57fffebab25a', payload '{\"abs_max_heat_setpoint_limit\":30,\"abs_min_heat_setpoint_limit\":5,\"control_sequence_of_operation\":\"cooling_only\",\"linkquality\":87,\"local_temperature\":18.01,\"local_temperature_calibration\":null,\"max_heat_setpoint_limit\":19,\"min_heat_setpoint_limit\":5,\"occupancy\":true,\"occupied_heating_setpoint\":15.5,\"pi_heating_demand\":null,\"remote_sensing\":{\"local_temperature\":\"internally\",\"occupancy\":\"internally\",\"outdoor_temperature\":\"internally\"},\"running_state\":null,\"system_mode\":\"off\",\"unoccupied_heating_setpoint\":null}'"}
{"level":"debug","message":"Received Zigbee message from '0x540f57fffebab25a', type 'attributeReport', cluster 'hvacThermostat', data '{\"maxHeatSetpointLimit\":1200}' from endpoint 1 with groupID 0"}

Ce qui m’intéresse - je pense- sont les 2 premiers log. Le 3e dépend de la configuration du converter, donc ne nous donne pas plus d’info que ce que l’on avait déjà.

Par contre, je n’ai aucune idée de savoir si le 2 premiers logs nous donnent des infos utiles à exploiter, et comment les exploiter :confused: .

Salut,

Je ne sais pas mais la notion de groupe existe dans zigbee… Du coup c’est pê l’envoi d’une info pour gérer cette fonction là. Pas utile pour toi pour l’instant à mon avis

Qaund tu parles de groupe, tu parles de ça ? :

Parce que si ce n’est pas effectivement utile, comment réussir à connaitre les infos renvoyées et attendues par le thermostat pour changer de mode (sans aide du fabricant) ?

Oui c’est à ce que je pense.
En théorie ça pourrait servir à actionner la chaudière avec certains modes
Dans ton cas pas le premier besoin

1 « J'aime »

Je tourne toujours en rond, et pas moyen de savoir comment est configuré la gestion des modes du thermostat.

Du coup, j’ai tenté l’option de débrancher complètement le converter.js, et de regarder de nouveau les logs bruts de z2mqtt lors du changement manuel de mode.

J’obtiens ceci :

debug 2023-04-28 16:57:00Received Zigbee message from 'Radiateur', type 'attributeReport', cluster 'hvacThermostat', data '{}' from endpoint 1 with groupID 0

debug 2023-04-28 16:57:01Received Zigbee message from 'Radiateur', type 'attributeReport', cluster 'hvacThermostat', data '{"16384":2}' from endpoint 1 with groupID 0

debug 2023-04-28 16:59:00Received Zigbee message from 'Radiateur', type 'attributeReport', cluster 'hvacThermostat', data '{"localTemp":2103}' from endpoint 1 with groupID 0

debug 2023-04-28 16:59:10Received Zigbee message from 'Radiateur', type 'attributeReport', cluster 'hvacThermostat', data '{"occupiedHeatingSetpoint":1100}' from endpoint 1 with groupID 0

debug 2023-04-28 16:59:11Received Zigbee message from 'Radiateur', type 'attributeReport', cluster 'hvacThermostat', data '{"occupiedHeatingSetpoint":1100}' from endpoint 1 with groupID 0

debug 2023-04-28 16:59:12Received Zigbee message from 'Radiateur', type 'attributeReport', cluster 'hvacThermostat', data '{"maxHeatSetpointLimit":1200}' from endpoint 1 with groupID 0

debug 2023-04-28 16:59:12Received Zigbee message from 'Radiateur', type 'attributeReport', cluster 'hvacThermostat', data '{"maxHeatSetpointLimit":1200}' from endpoint 1 with groupID 0

debug 2023-04-28 16:59:13Received Zigbee message from 'Radiateur', type 'attributeReport', cluster 'hvacThermostat', data '{}' from endpoint 1 with groupID 0

debug 2023-04-28 16:59:14Received Zigbee message from 'Radiateur', type 'attributeReport', cluster 'hvacThermostat', data '{"16384":3}' from endpoint 1 with groupID 0

Je me demande donc maintennat s’il ne faut pas regarder du coté de ces lignes :
Received Zigbee message from 'Radiateur', type 'attributeReport', cluster 'hvacThermostat', data '{"16384":3}' from endpoint 1 with groupID

Oui c’est possible que 16384 corresponde au mode et que 2/3 soit des valeurs de delui-ci.
Par contre je ne connais pas assez z2m et le module pour aller plus loin.
As-tu essayé le github de z2m ? Tu peux toujours poster une issue avec le début de ton converter, tu devrais avoir y croiser des plus experts que nous dans le domaine

Je vais faire ça merci !!

Déjà grace a toi, j’ai pu réduire le spectre de mes questions, donc ca a été trèèès utile !

Merci !

1 « J'aime »

Après avoir posté sur Github, le forum anglophone de HA, Reddit, je n’ai recu aucune aide supplémentaire.
Alors, c’est bien le propre des forums communautaire d’être tributaire du temps, compétences et intérêt des internautes pour son sujet, mais j’avoue bloquer définitivement sur mon problème…

Avez-vous d’autres pistes en tête pour trouver une aide utile ?

Pas spécialement d’autres idées… Relancer de temps en temps, attendre…
C’est le problème du matériel un peu confidentiel (et/ou acheté avant sa compatibilité pleine et entière), on est tributaire de pleins d’éléments extérieurs

Bonjour,
Je cherche un thermostat. Celui-ci à l’air bien comparé à ce que j’ai déjà essayé.
Avez-vous réussit son intégration?
Ou se le procurer?
Cordialement

Je n’ai pas anvancé sur son intégration.

En l’état, j’arrive a le piloter, mais via une modification de la température de consigne, pas en changeant le mode. Alors ca « marche », mais ce n’ai pas 100% propre, car je bypass ainsi pas mal d’options intégrées au thermostat, comme l’arret auto du chauffage en cas d’ouverture des fénêtres.

Quant au thermostat en lui même, il est top!

faudrait peut etre que je renalce le fabricant en lui pointant tous les forums que j’ai sollicité, et en lui partangeant mes brouillons de converter

Je viens de re-regarder la doc du fabricant:

Normalemnt, le thermostat est PILOTABLE en zigbee. Personellemnt je n’avais pas réussi vie ZHA, amsi peut-être devrais-je retenter (il faudra attendre le 07/07, date a partir de laquelle je retrouve mon réseau pour pouvoir retravailler dans HA).

Question : Y-a-t’il moyen d’accéder aux « fichiers de configuration » de l’appareil sous Zigbee ? Je veux dire : peut-on extraire l’équivalent du converter Z2mqtt, sous zigbee, afin d’avoir des infos utiles pour Z2mqtt ?

Cela en à l’air, mais pas moyen de trouver un vendeur