Merci @pierre-gilles pour l’accompagnement et pour comprendre ce qui pouvait rendre Gladys Plus instable.
Origine du problème
Pour expliquer à tout le monde en détail, j’ai un thermostat connecté de la marque Sinopé (Sinopé TH1123ZB control via MQTT | Zigbee2MQTT), qui aurait un bug l’empêchant de m’envoyer les valeurs de consommation. Donc quand le chauffage s’allume, il m’affiche toujours « 0 W » consommé en instantanné.
Comme la période de chauffe se faire par 15 secondes, il fallait que je récupère cette valeur très régulièrement pour par rater un cycle.
Solution de contournement avec une scène (cause du problème avec Gladys Plus)
J’avais créé une scène comme l’image suivante, mais appliqué à 3x thermostats (là on en voit qu’un seul). Cette scène s’exécutait toutes les 5 secondes.
Gladys localement ne bronchait pas, ça tournait bien sans instabilité et sans trop utiliser les ressources CPU. Mais lorsque j’utilisais Gladys Plus, c’était une autre histoire, j’avais parfois des lenteurs jusqu’à 30 secondes pour commander une prise !!
Solution définitive
Pour forcer mes thermostats à renvoyer leurs données à jour régulièrement, sans demander à Gladys de faire le travail, puisque ça provoque des effets de bords, j’ai fait la même chose, mais avec Zigbee2MQTT directement.
Extensions
Zigbee2MQTT propose un système d’extensions, permettant d’ajouter des fonctionnalités. Il faut écrire du code en javascript, qui sera exécuté suivant différents événements.
Dans mon cas, j’ai fait en sorte que toutes les 5 secondes, mes trois thermostats soit forcé d’être mis à jour sur leurs valeurs de consommation électrique.
Résultat, plus de lenteurs sur Gladys et j’ai bien mes données régulièrement.
Voici le code en texte :
class ForceUpdateSinopeExtension{
constructor(zigbee, mqtt, state, publishEntityState, eventBus, settings, logger) {
logger.info('Loaded ForceUpdateSinopeExtension');
this.mqttBaseTopic = settings.get().mqtt.base_topic;
this.eventBus = eventBus;
this.mqtt = mqtt;
this.eventBus.on('stateChange', this.onStateChange.bind(this), this.constructor.name);
// List of devices to update
this.devices = [
'bureau-thermostat-sinope',
'piecedevie-thermostat-sinope',
'chambreenfant-thermostat-sinope'
];
this.lastMessageTime = Date.now() / 1000;
}
async onStateChange() {
const now = Date.now() / 1000; // get current time in seconds
if (now - this.lastMessageTime >= 5) { // check if 5 seconds have passed since last message
this.lastMessageTime = now;
console.log('----> Forcing updates of sinope devices (every 5 sec).');
// update all values from a list
for (const device of this.devices) {
const topic = `${this.mqttBaseTopic}/${device}/get`;
const data = {
'power': true,
'voltage': true,
'current': true,
'energy': true
}
this.mqtt.onMessage(topic, JSON.stringify(data));
}
}
}
async onMQTTMessage(topic, message) {
// console.log({topic, message});
}
async stop() {
this.eventBus.removeListeners(this.constructor.name);
}
}
module.exports = ForceUpdateSinopeExtension;