Gestion Thermostats dans Homebridge

Bonjour,

J’utilise le plugin-thermostat dans Jeedom et il est transmis au plugin-homebridge. Jusque la tout va bien cela fonctionne.
J’utilise en été le lock pour verrouiller le thermostat de chauffage et en hiver sur celui de clim (j’ai quand même des alertes qui remontent par moment).
Loic m’a dit qu’il n’était pas préco d’utiliser le lock sur de longues périodes mais plutôt de activer/désactiver le thermostat.
Le problème c’est qu’en désactivant le thermostat, il faut relancer le démon homebridge pour être pris en compte et idem pour la réactivation. (ce point est facilement contournable avec un scénario)
Ensuite lors de la réactivation, les thermostats ne sont plus dans les bonnes pièces…

J’imagine donc cette solution de contournement : créer un thermostat Virtuel qui est toujours actif et qui commande en été le thermostat de chauffage (mode temporel) et l’été la clim (mode hystérésis). En gros le virtuel piloterait le thermostat du plugin-thermostat de façon transparente.

Avant de me lancer à fond dans ce projet, je voulais voir avec vous si vous n’aviez pas une meilleure solution.

Merci

Hello,

en effet la désactivation d’un équipement ne crée pas d’evenement (à ma connaissance) dans jeedom. donc je ne reçois pas l’info et ne supprime pas l’équipement.

C’est même pire que ça car l’objet n’apparait plus dans la liste (ce qui se comprend bien).

C’est pour cela que je me dis que de faire un virtuel ça peut résoudre mon problème. Pour les pièces sans clim je maintiendrai le lock sur le virtuel (et le thermostat du plugin-thermostat sera quant à lui désactivé).

Maintenant, il faut que je me lance pour arrivé à gérer tout ça un peu dynamiquement. Si j’y arrive, je mettrais un peu de détail sur ma solution.

oui bonne idée.

Je vais avoir besoin d’un peu d’assistance.
Je n’arrive pas à mettre en place les Mode dans homebridge avec un virtuel.

Je m’explique j’ai fais ces 3 commandes :

Pour la commande Mode de type Info j’ai sélectionné « Thermostat Mode » dans les Type générique :

Et pour les commandes Action, j’ai choisi aussi « Thermostat Mode »

J’ai l’impression d’être raccord avec la doc (mais je dois rater qqch) :

Si je teste depuis Jeedom les Modes ça fonctionne le thermostat s’active bien dans l’application Maison. En revanche depuis mon iDevice ça n’est pas pris en compte comme si l’information ne remontait pas dans Jeedom.

Si je choisi Autom. depuis mon iPhone, l’interface s’active, je peux changer la consigne (qui remonte bien dans la cmdid 10382. Puis quelques seconde après le thermostat revient en mode arrêt.

La commande de Mode n’a pas changée et est restée sur « Off »

[7/30/2024, 2:18:36 PM] [MyHome] [DEBUG] set target mode: 3
[7/30/2024, 2:18:36 PM] [MyHome] [DEBUG] set AUTO 27.5
[7/30/2024, 2:18:36 PM] [MyHome] [INFO] [Commande envoyée à Jeedom] cmdId:10382 action:TargetHeatingCoolingState value: 27.5 generic:undefined response:[]

Si j’active le mode Aucun depuis Jeedom et que je souhaite désactiver depuis l’iPhone ça marche pas non plus :

Au début l’interface Eteint le thermostat mais quelques secondes après il revient sur Autom.
Dans Jeedom, le mode est resté sur Aucun.

[7/30/2024, 2:23:47 PM] [MyHome] [DEBUG] set target mode: 0
[7/30/2024, 2:23:47 PM] [MyHome] [INFO] [Commande envoyée à Jeedom] cmdId:10383 action:TargetHeatingCoolingState value: 0 generic:undefined response:{"value":26.5,"collectDate":"2024-07-30 14:19:19"}

J’avoue me sentir un peu bête, je dois rater un paramètre mais je ne le vois pas.

Voici le debugInfo du thermostat :

{
    "id": "818",
    "name": "Thermostat test",
    "logicalId": "",
    "generic_type": null,
    "object_id": "11",
    "eqType_name": "virtual",
    "isVisible": "0",
    "isEnable": "1",
    "configuration": {
        "createtime": "2024-07-30 09:02:38",
        "autorefresh": "",
        "updatetime": "2024-07-30 13:18:57",
        "battery_type": "",
        "battery_danger_threshold": "",
        "battery_warning_threshold": ""
    },
    "timeout": null,
    "category": {
        "heating": "0",
        "security": "0",
        "energy": "0",
        "light": "0",
        "opening": "0",
        "automatism": "0",
        "multimedia": "0",
        "default": "0"
    },
    "display": {
        "backGraph::info": "",
        "backGraph::color": "#4572a7",
        "backGraph::format": "month",
        "backGraph::height": "",
        "backGraph::type": "areaspline",
        "parameters": []
    },
    "order": "9999",
    "comment": "",
    "tags": "",
    "status": {
        "lastCommunication": "2024-07-30 14:23:01",
        "timeout": 0,
        "enableDatime": "2024-07-30 09:25:59",
        "warning": 0,
        "danger": 0
    },
    "cache": [],
    "commands": [
        {
            "id": "10379",
            "logicalId": "",
            "generic_type": "THERMOSTAT_TEMPERATURE",
            "eqType": "virtual",
            "name": "Température",
            "order": "0",
            "type": "info",
            "subType": "numeric",
            "eqLogic_id": "818",
            "isHistorized": "0",
            "unite": "°C",
            "configuration": {
                "calcul": "#3244#",
                "returnStateValue": "",
                "returnStateTime": "",
                "updateCmdId": "",
                "minValue": "",
                "maxValue": "",
                "timeline::enable": "0",
                "timeline::folder": "",
                "influx::enable": "0",
                "influx::namecmd": "",
                "influx::nameEq": "",
                "influx::nameVal": "",
                "interact::auto::disable": "0",
                "calculValueOffset": "",
                "historizeRound": "",
                "jeedomCheckCmdOperator": "==",
                "jeedomCheckCmdTest": "",
                "jeedomCheckCmdTime": "",
                "historizeMode": "avg",
                "history::smooth": "",
                "historyPurge": "",
                "denyValues": "",
                "repeatEventManagement": "never",
                "jeedomPushUrl": "",
                "alert::messageReturnBack": "0",
                "actionCheckCmd": [],
                "jeedomPreExecCmd": [],
                "jeedomPostExecCmd": []
            },
            "template": {
                "dashboard": "core::default",
                "mobile": "core::default"
            },
            "display": {
                "invertBinary": "0",
                "showStatsOnmobile": 0,
                "showStatsOndashboard": 0,
                "showNameOndashboard": "1",
                "showNameOnmobile": "1",
                "showIconAndNamedashboard": "0",
                "showIconAndNamemobile": "0",
                "forceReturnLineBefore": "0",
                "forceReturnLineAfter": "0",
                "parameters": []
            },
            "value": "#3244#",
            "isVisible": "1",
            "alert": {
                "warningif": "",
                "warningduring": "",
                "dangerif": "",
                "dangerduring": ""
            }
        },
        {
            "id": "10378",
            "logicalId": "refresh",
            "generic_type": null,
            "eqType": "virtual",
            "name": "Rafraichir",
            "order": "1",
            "type": "action",
            "subType": "other",
            "eqLogic_id": "818",
            "isHistorized": "0",
            "unite": "",
            "configuration": [],
            "template": {
                "dashboard": "core::default",
                "mobile": "core::default"
            },
            "display": [],
            "value": null,
            "isVisible": "1",
            "alert": []
        },
        {
            "id": "10382",
            "logicalId": "",
            "generic_type": "THERMOSTAT_SET_SETPOINT",
            "eqType": "virtual",
            "name": "ThermostatConsigne",
            "order": "1",
            "type": "action",
            "subType": "slider",
            "eqLogic_id": "818",
            "isHistorized": "0",
            "unite": "",
            "configuration": {
                "virtualAction": "1",
                "infoName": "Consigne",
                "value": "",
                "updateCmdId": "",
                "updateCmdToValue": "",
                "minValue": "10",
                "maxValue": "38",
                "listValue": "",
                "calcul": "",
                "infoId": "10383",
                "timeline::enable": "0",
                "timeline::folder": "",
                "interact::auto::disable": "0",
                "calculValueOffset": "",
                "actionConfirm": "0",
                "actionCodeAccess": "",
                "alreadyInState": "",
                "actionCheckCmd": [],
                "jeedomPreExecCmd": [],
                "jeedomPostExecCmd": [],
                "lastCmdValue": "26.5"
            },
            "template": {
                "dashboard": "core::default",
                "mobile": "core::default"
            },
            "display": {
                "showNameOndashboard": "1",
                "showNameOnmobile": "1",
                "showIconAndNamedashboard": "0",
                "showIconAndNamemobile": "0",
                "forceReturnLineBefore": "0",
                "forceReturnLineAfter": "0",
                "parameters": []
            },
            "value": "",
            "isVisible": "1",
            "alert": []
        },
        {
            "id": "10383",
            "logicalId": "",
            "generic_type": "THERMOSTAT_SETPOINT",
            "eqType": "virtual",
            "name": "Consigne",
            "order": "2",
            "type": "info",
            "subType": "numeric",
            "eqLogic_id": "818",
            "isHistorized": "0",
            "unite": "°C",
            "configuration": {
                "virtualAction": 1,
                "calcul": "",
                "returnStateValue": "",
                "returnStateTime": "",
                "updateCmdId": "",
                "minValue": "10",
                "maxValue": "38",
                "timeline::enable": "0",
                "timeline::folder": "",
                "influx::enable": "0",
                "influx::namecmd": "",
                "influx::nameEq": "",
                "influx::nameVal": "",
                "interact::auto::disable": "0",
                "calculValueOffset": "",
                "historizeRound": "",
                "jeedomCheckCmdOperator": "==",
                "jeedomCheckCmdTest": "",
                "jeedomCheckCmdTime": "",
                "historizeMode": "avg",
                "history::smooth": "",
                "historyPurge": "",
                "denyValues": "",
                "repeatEventManagement": "never",
                "jeedomPushUrl": "",
                "alert::messageReturnBack": "0",
                "actionCheckCmd": [],
                "jeedomPreExecCmd": [],
                "jeedomPostExecCmd": []
            },
            "template": {
                "dashboard": "core::default",
                "mobile": "core::default"
            },
            "display": {
                "showStatsOnmobile": 0,
                "showStatsOndashboard": 0,
                "invertBinary": "0",
                "showNameOndashboard": "1",
                "showNameOnmobile": "1",
                "showIconAndNamedashboard": "0",
                "showIconAndNamemobile": "0",
                "forceReturnLineBefore": "0",
                "forceReturnLineAfter": "0",
                "parameters": []
            },
            "value": "",
            "isVisible": "1",
            "alert": {
                "warningif": "",
                "warningduring": "",
                "dangerif": "",
                "dangerduring": ""
            }
        },
        {
            "id": "10385",
            "logicalId": "",
            "generic_type": "THERMOSTAT_MODE",
            "eqType": "virtual",
            "name": "Mode",
            "order": "3",
            "type": "info",
            "subType": "string",
            "eqLogic_id": "818",
            "isHistorized": "0",
            "unite": "",
            "configuration": {
                "calcul": "",
                "returnStateValue": "",
                "returnStateTime": "",
                "updateCmdId": "",
                "minValue": "",
                "maxValue": "",
                "timeline::enable": "0",
                "timeline::folder": "",
                "influx::enable": "0",
                "influx::namecmd": "",
                "influx::nameEq": "",
                "influx::nameVal": "",
                "interact::auto::disable": "0",
                "calculValueOffset": "",
                "jeedomCheckCmdOperator": "==",
                "jeedomCheckCmdTest": "",
                "jeedomCheckCmdTime": "",
                "historyPurge": "",
                "denyValues": "",
                "repeatEventManagement": "never",
                "jeedomPushUrl": "",
                "alert::messageReturnBack": "0",
                "actionCheckCmd": [],
                "jeedomPreExecCmd": [],
                "jeedomPostExecCmd": [],
                "virtualAction": 1
            },
            "template": {
                "dashboard": "core::default",
                "mobile": "core::default"
            },
            "display": {
                "invertBinary": "0",
                "showNameOndashboard": "1",
                "showNameOnmobile": "1",
                "showIconAndNamedashboard": "0",
                "showIconAndNamemobile": "0",
                "forceReturnLineBefore": "0",
                "forceReturnLineAfter": "0",
                "parameters": []
            },
            "value": "",
            "isVisible": "1",
            "alert": {
                "warningif": "",
                "warningduring": "",
                "dangerif": "",
                "dangerduring": ""
            }
        },
        {
            "id": "10386",
            "logicalId": "",
            "generic_type": "THERMOSTAT_SET_MODE",
            "eqType": "virtual",
            "name": "Off",
            "order": "4",
            "type": "action",
            "subType": "other",
            "eqLogic_id": "818",
            "isHistorized": "0",
            "unite": "",
            "configuration": {
                "virtualAction": "1",
                "infoName": "Mode",
                "value": "Off",
                "updateCmdId": "",
                "updateCmdToValue": "",
                "minValue": "",
                "maxValue": "",
                "listValue": "",
                "calcul": "",
                "infoId": "10385",
                "timeline::enable": "0",
                "timeline::folder": "",
                "interact::auto::disable": "0",
                "actionConfirm": "0",
                "actionCodeAccess": "",
                "alreadyInState": "",
                "actionCheckCmd": [],
                "jeedomPreExecCmd": [],
                "jeedomPostExecCmd": []
            },
            "template": {
                "dashboard": "core::default",
                "mobile": "core::default"
            },
            "display": {
                "showNameOndashboard": "1",
                "showNameOnmobile": "1",
                "showIconAndNamedashboard": "0",
                "showIconAndNamemobile": "0",
                "forceReturnLineBefore": "0",
                "forceReturnLineAfter": "0",
                "parameters": []
            },
            "value": "",
            "isVisible": "1",
            "alert": []
        },
        {
            "id": "10388",
            "logicalId": "",
            "generic_type": "THERMOSTAT_SET_MODE",
            "eqType": "virtual",
            "name": "Aucun",
            "order": "5",
            "type": "action",
            "subType": "other",
            "eqLogic_id": "818",
            "isHistorized": "0",
            "unite": "",
            "configuration": {
                "virtualAction": "1",
                "infoName": "Mode",
                "value": "Aucun",
                "updateCmdId": "",
                "updateCmdToValue": "",
                "minValue": "",
                "maxValue": "",
                "listValue": "",
                "calcul": "",
                "infoId": "10385",
                "timeline::enable": "0",
                "timeline::folder": "",
                "interact::auto::disable": "0",
                "actionConfirm": "0",
                "actionCodeAccess": "",
                "alreadyInState": "",
                "actionCheckCmd": [],
                "jeedomPreExecCmd": [],
                "jeedomPostExecCmd": []
            },
            "template": {
                "dashboard": "core::default",
                "mobile": "core::default"
            },
            "display": {
                "showNameOndashboard": "1",
                "showNameOnmobile": "1",
                "showIconAndNamedashboard": "0",
                "showIconAndNamemobile": "0",
                "forceReturnLineBefore": "0",
                "forceReturnLineAfter": "0",
                "parameters": []
            },
            "value": "",
            "isVisible": "1",
            "alert": []
        }
    ]
}

merci d’avance

PS : J’ai bien redémarré le deamon.

Pour les types génériques gère ça dans homebridge, pas dans les paramètres de la commande dans Jeedom.

Le plus simple est dans le plugin virtuel de cloner un équipement comme ça tout est bien fait.

Les commandes des modes doivent s’appeler exactement comme dans le plugin Thermostat.

Merci beaucoup, j’ai rappliqué les même types génériques depuis le plugin-homebridge, enregistré et relancé le deamon et ça marche !

Je met une capture si ça peut aider (car dans le plugin thermostat, on n’a pas le détail des commandes mais tout fonctionne bien)

PS : Je comptais justement finaliser le virtuel et ensuite le cloner quand tout sera fonctionnel sur ma version de test.

Je parlais plus de cloner le thermostat dans le virtuel, c’est peut-etre pas le bon terme attend je vérifie…

ha ça s’appelle « importer un équipement »
image

Merci, je ne connaissais pas cette fonctionnalité, c’est top et plus ça fais gagner beaucoup de temp.

A quoi sert ces commandes verouillage ?

Dans l’interface, je ne vois pas l’info remonter et je peux modifier les infos du thermostat en le remettant sur Autom. puis ensuite j’ai le verrou du thermostat qui n’accepte pas les changements côté Jeedom du coup le plugin se réactualise avec les valeurs vérouillées.

image

Si cela n’est pas utile, je ne reprendrais pas ces commandes pour juste me concentré sur le minimum (Éteint, Autom.) tant qu’Apple ne gère pas plus de mode, il faut que je réfléchisse à une logique pour Cool et Heat (avec la bascule été/hiver afin de trouver les modes logique à mon usage sans se poser trop de question…)

Avant c’était supporté dans Maison , ils l’ont retiré.

Mais tu peux toujours l’utiliser dans l’application Eve.

merci pour l’info, c’est vrai que j’ai installé Eve il y a pas longtemps ça a l’air plus réactif que l’application Maison. J’attend de voir la prochaine version d’iOS pour basculer.

Sinon pour revenir à mon thermostat, je crois que j’ai fini par trouver la solution. Je vais tester ça prochainement en condition réelle.

J’ai créé une fonction dans user.function.class.php

public static function SwitchThermostat($thermostatAssistant, $thermostatChauffage, $thermostatClimatisation, $modeThermostatSaison){

    // Objet Thermostat utilisé par homebridge
    $eqLogicThermostat = eqLogicByJeedomId($thermostatAssistant);
    $eqLogicThermostatName = $eqLogicThermostat->getHumanName();
    $cmdInfoConsigne = cmd::byString('#' . $eqLogicThermostatName . '[Consigne]#');
    $cmdActionThermostat = cmd::byString('#' . $eqLogicThermostatName . '[Thermostat]#');
	$cmdInfoMode = cmd::byString('#' . $eqLogicThermostatName . '[Mode]#');
	$cmdActionOff = cmd::byString('#' . $eqLogicThermostatName . '[Off]#');
    
    // Récupération de la saison (mode été ou hiver)
    $cmdMode = cmd::byString($modeThermostatSaison);
    $modeEtat = $cmdMode->execCmd();
    
    if ($modeEtat == 'Hiver') {
      $eqLogicThermostatSaison = eqLogicByJeedomId($thermostatChauffage);
    }
    else{
      $eqLogicThermostatSaison = eqLogicByJeedomId($thermostatClimatisation);
    }
    
    // Thermostat actif pour la saison (plugin-thermostat)
    $eqLogicThermostatSaisonName = $eqLogicThermostatSaison->getHumanName();
    
    $cmdSaisonInfoConsigne = cmd::byString('#' . $eqLogicThermostatSaisonName . '[Consigne]#');
    $cmdSaisonActionThermostat = cmd::byString('#' . $eqLogicThermostatSaisonName . '[Thermostat]#');
	$cmdSaisonInfoMode = cmd::byString('#' . $eqLogicThermostatSaisonName . '[Mode]#');
	$cmdSaisonActionOff = cmd::byString('#' . $eqLogicThermostatSaisonName . '[Off]#');

    // Mettre à jour la configuration du thermostat
    $cmdInfoConsigne->setConfiguration('calcul', '#'.$cmdSaisonInfoConsigne->getId().'#');
    $cmdInfoConsigne->setValue($cmdSaisonInfoConsigne->getId());
    
    $cmdActionThermostat->setConfiguration('infoName', '#'.$cmdSaisonActionThermostat->getId().'#');
    $cmdActionThermostat->setValue($cmdSaisonActionThermostat->getId());
    
    $cmdInfoMode->setConfiguration('calcul', '#'.$cmdSaisonInfoMode->getId().'#');
    $cmdInfoMode->setValue($cmdSaisonInfoMode->getId());
    
    $cmdActionOff->setConfiguration('infoName', '#'.$cmdSaisonActionOff->getId().'#');
	$cmdActionOff->setValue($cmdSaisonActionOff->getId());
    
    // Sauvegarder les changements
    $cmdInfoConsigne->save();
    $cmdActionThermostat->save();
    $cmdInfoMode->save();
    $cmdActionOff->save();
    $eqLogicThermostat->save();
    
    return "$eqLogicThermostatName - Passage en mode $modeEtat avec les commandes du thermostat : $eqLogicThermostatSaisonName";
  }

private static function eqLogicByJeedomId($value){
      // Retourne l'identifiant d'un objet à partir de son id
      // Dans un scénario on renseigne #[Piece][Objet]# en paramètre
      // arrivé dans la fonction c'est sous la forme #eqLogic127#
    
    $pos = strpos($value,'eqLogic');
    if ($pos !== false){
      $jeedomId = str_replace('eqLogic', '', str_replace('#', '', $value));
      $eqLogic = eqLogic::byId($jeedomId);
      
      return $eqLogic;
    }

    return null;
  }

Pour l’utiliser dans un scénario, j’utilise par exemple cette fonction comme ça :

Le premier paramètre est le thermostat virtuel qui sera utilisé par homebridge
Le second paramètre est le thermostat de chauffage (utilisé en hiver par jeedom)
Le troisième paramètre est le thermostat de climatisation (uilisé en été par jeedom)
Le quatrième est mon Mode (Été / Hiver) permettant de faire la bascule automatiquement

Je remplace les commandes : Consigne, Thermostat, Mode et Off

Après c’est amené à évoluer pour rajouter le verrouillage par exemple et des modes qui serait commun au 2 thermostats.

J’ai volontairement pas repris toutes les commandes pour mes tests.

Voici le virtuel en question :

J’espère que ça pourra aider d’autres personnes, si vous avez des remarques sur le code je suis preneur, je suis pas expert php. J’ai certainement fais compliqué pour des choses qui sont plus simple :slight_smile:

@nebz,
J’ai une question dans la doc il est indiqué que la température ambiante n’est pas obligatoire pour le thermostat mais si je ne la met pas, le thermostat affiche 0,0° en gros à la place de 24,0° sur ma capture
image
Sais-tu si c’est paramétrable dans l’application Maison ?

Ce qui est aussi étonnant c’est d’avoir une température arrondi alors que homebridge envoie bien la bonne info.

Dans l’application Eve je la retrouve bien 23,9…
image

Je te remercie encore pour ton aide avant que le sujet soit complètement clos. Merci aussi pour ton plugin qui est top !

Bonne soirée

Oui pas obligatoire pour avoir un composant fonctionnel dans maison, certains ne mettent que une consigne par exemple (pour les valves thermostatiques). Donc oui il affiche zéro logique. Non on ne peut pas modifier comme on veut pour ce qui est dans l’app maison.

Oui l’app maison arrondît…

Merci, je m’en doutais un peu, croisons les doigts pour qu’ils améliorent ça dans la prochaine version sinon faudra que je bascule vers l’application eve et que je montre ça à ma femme.

Bonne journée

Moi je la préfère, j’utilise « Maison » que pour les certaines automations.

Et tu peux y afficher beaucoup plus de types génériques. Et des graphs.



Comment fais-tu pour avoir les graphiques dans l’application eve ?

Il faut activer dans la config du plugin homebridge

Merci, je viens de l’activer. Je pensais que c’étais dans EVE qu’il y avait option en alpha lol.