NAS-WR01ZE, vers l’infini et… Jeedom

Ce petit module Z-Wave a maintenant quelques années au compteur, mais reste toujours extrêmement pratique.
Parmi ses avantages : relevé de consommation, sa taille, son prix.
Son inconvénient : fiabilité des valeurs de consommation.

Attention, ne concerne que le module NAS-WR01ZE, pas le module NAS-WR01Z qui, lui, ne présente pas ce problème.Rapidement, on se rend compte que le module parle une autre langue et donne des valeurs négatives de consommations.

Méthode de filtrage les valeurs

La première parade pour éviter ces valeurs est de mettre une limite minimale à la commande « Consommation » en mettant « 0 ».
Génial, plus aucune valeur fantaisiste.
Oui, mais quand le module ne communique que des valeurs fantaisistes, plus aucune valeur au-dessus de 0 n’est fournit.

Méthode de recalcul

Quelques patchs sur d’autres solutions domotiques existent et je vais vous indiquer la marche à suivre, enfin celle que j’ai codée dans mon Jeedom, pour rattraper ces valeurs perdues.
Eh oui, la valeur n’est pas perdue, elle est juste mal interprétée.
Si on additionne 21474836.47 (c’est-à-dire (2^31-1)/100) à la valeur reçu, on se rend compte qu’on retrouve notre valeur de consommation.

Avant toute application, veuillez faire une sauvegarde de votre jeedom.
Le code supprime la valeur historisée et en crée une nouvelle.

Corriger à la volée

Dans un nouveau scénario pour corriger à la volée les prochaines valeurs, mettre en déclencheur provoqué la commande info/numeric de consommation.
Il est possible d’en mettre plusieurs, pour qu’elles passent toutes par ce scénario.
Ajouter un bloc SI/ALORS/SINON et mettre : triggerValue() != "" AND triggerValue() < 0
Et le bloc code suivant dans ALORS :

// Ce bloc est executé selon la commande déclencheur définie (commande Consommation en kWh) du module NAS-WR01ZE
// Recherche de la commande trigger
// supression de l'historique de cette mauvaise valeur
// recalcul de la nouvelle valeur
// ajout de la valeur calculée en déclenchant un nouvel évenement

$trigger = $scenario->getRealTrigger(); // et pas trigger() qui liste tous les déclencheurs
$cmdId = str_replace('#', '', $trigger);
$cmdTrig = cmd::byId($cmdId); // commande du déclenchement

$value = round((($cmdTrig->execCmd()*100)+2147483647)/100,2); // valeur corrigée

$cmdHistory = history::byCmdIdAtDatetime($cmdTrig->getId(), $cmdTrig->getCollectDate()); // objet history de cette valeur

$scenario->setLog("[T] Déclencheur         : " . $trigger);
$scenario->setLog("[C] Date collecte       : " . $cmdTrig->getCollectDate());
$scenario->setLog("[H] Valeurs history     : " . json_encode(utils::o2a($cmdHistory))); // contenu de l'objet

if (is_object($cmdHistory)) {
    $currentValue = $cmdHistory->getValue();
    $currentDatetime = $cmdHistory->getDatetime();
    $cmdHistory->remove(); //suppression de la valeur d'historique 
    $cmdTrig->event($value, $currentDatetime); //création de la valeur corrigée (pour déclencher toutes les actions en fonction de cette valeur (cache, return, event...) plutôt que juste remplacer la valeur de l'objet history)
    $scenario->setLog("[ID] Commande ID        : " . $cmdHistory->getCmd_id());
    $scenario->setLog("[-] Ancienne valeur     : " . $currentValue);
    $scenario->setLog("[?] Nouvelle valeur     : " . $value);
}

Ce qui donne ceci :

Reste plus qu’à attendre en surveillant le log de ce scénario et bingo :

Ancienne valeur : -21474461.49
Nouvelle valeur : 374.98
Et l’historique montre bien que la valeur est correcte, par rapport aux autres valeurs.

Corriger les valeurs historisées

Bon, c’est bien beau, à partir de maintenant les valeurs sont fiables, mais je me retrouve avec un historique de valeurs fantaisistes.
Je peux supprimer les anciennes valeurs négatives manuelles ou modifier ce même scénario.
Ajouter un bloc SI/ALORS/SINON et mettre : trigger() == "user".
Glisser ce bloc code dans ALORS :

// Ce bloc est executé manuellement via le scénario pour corriger toutes les valeurs erronées du module NAS-WR01ZE
// Recherche dans toutes les commandes déclencheur
// récupère toutes les valeurs d'historique
// supprime les mauvaises valeurs une à une
// recalcul de chaque nouvelle valeur
// ajout de cette valeur

$scenario->setLog("[X] Declencheurs " . json_encode($scenario->getTrigger()));

$triggers = $scenario->getTrigger();
foreach ($triggers as $trigger) { // parmi tous les déclencheurs listés
    $cmdId = str_replace('#', '', $trigger);
    $cmdTrig = cmd::byId($cmdId);
    $histories = array_reverse(history::all($cmdTrig->getId())); // récupère toutes les valeurs historique
    foreach ($histories as $history) { // pour chaque valeur
        $currentValue = $history->getValue();
        $currentDatetime = $history->getDatetime();
        if ($currentValue < 0) { // si la valeur est négative
            $value = round((($currentValue*100)+2147483647)/100,2); // valeur corrigée

            if ($value > 100000) continue; // valeurs lissées non prises en compte
            $scenario->setLog("[ID] Commande ID        : " . $history->getCmd_id());
            $scenario->setLog("[-] Ancienne valeur     : " . $currentValue);
            $scenario->setLog("[?] Nouvelle valeur     : " . $value);
            $history->setValue($value)->save(null, true); // on remplace directement la valeur, pas besoin de réaffecter le cache ou autre
            $scenario->setLog("[+] Confirmation valeur : " . $history->getValue());  
        }
    }
}

Ce qui donne :

Reste plus qu’à executer le scénario et voilà :

Ici, une valeur a été corrigée.

Pour plus de simplicité, voilà le template de scénario à importer :

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *