Scénario ouverture / fermeture volet roulant en fonction présence / azimuth / nuit

Bonjour à tous,

Je souhaite vous partager ici un petit script PHP que j’ai écrit permettant de gérer la position des volets roulant.
Le script permet de gérer la position des volets roulant en fonction de :

  • La présence humaine dans la maison
  • Le coucher / lever du soleil
  • La position azimuth du soleil

Le script est une fonction PHP à mettre dans le fichier:

user.function.class.php

Ce fichier peut être retrouvé via l’éditeur de fichier

<?php

/* This file is part of Jeedom.
 *
 * Jeedom is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Jeedom is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Jeedom. If not, see <http://www.gnu.org/licenses/>.
 */

/* * ***************************Includes********************************* */
require_once __DIR__ . '/../../core/php/core.inc.php';

class userFunction
{

    public static function plop($_arg1 = '')
    {
        return 'Argument 1 : ' . $_arg1;
    }

    public static function gestionVolet(
        $voletParametreDefaut,
        $voletParametrePresence,
        $voletParametreNuit,
        $voletParametreAzimuth
   ) {
        $nom_volet = $voletParametreDefaut->nomVolet;
        $cmdPositionVoletEtatStr = $voletParametreDefaut->cmdPositionVoletEtatStr;
        $cmdPositionVoletActionStr = $voletParametreDefaut->cmdPositionVoletActionStr;
        $cmd_position_volet_etat = cmd::byString($cmdPositionVoletEtatStr);
        $cmd_position_volet_action = cmd::byString($cmdPositionVoletActionStr);
        $etat_volet = $cmd_position_volet_etat->execCmd();

        if ($voletParametrePresence != null) {
            $cmd_presence = cmd::byString($voletParametrePresence->cmdPresenceStr);
            $presence = $cmd_presence->execCmd();
            $cmd_temperature_max_jour = cmd::byString($voletParametrePresence->cmdTempMaxJourStr);
            $temps_max = $cmd_temperature_max_jour->execCmd();
            if ($presence == 0 && $temps_max > $voletParametrePresence->tempMinPresence) {
                if ($etat_volet != $voletParametrePresence->positionVoletAbsence) {
                    $options = array('slider' => $voletParametrePresence->positionVoletAbsence);
                    $cmd_position_volet_action->execCmd($options, $cache = 0);
                    return 'Application etat départ sur volet';
                }
                else {
                    return 'Etat départ déjà appliqué';
                }
            }
        }
        if ($voletParametreNuit != null) {
            $cmd_coucher_coleil = cmd::byString($voletParametreNuit->cmdCoucherSoletStr);
            $cmd_aube_civile = cmd::byString($voletParametreNuit->cmdAubeCivileStr);

            $aube = $cmd_aube_civile->execCmd();
            $coucher_soleil = $cmd_coucher_coleil->execCmd();
            $current_hour = date('H');
            $current_min = date('i');
            $current_time = $current_hour . $current_min;
            if ($aube > $current_time || $coucher_soleil < $current_time) {
                if ($etat_volet != $voletParametreNuit->positionVoletNuit) {
                    $options = array('slider' => $voletParametreNuit->positionVoletNuit);
                    $cmd_position_volet_action->execCmd($options, $cache = 0);
                    return 'Application etat nuit sur volet';
                }
                else {
                    return 'Etat nuit déjà appliqué';
                }
            }
        }
        if ($voletParametreAzimuth != null) {
            $cmd_azimuth_soleil = cmd::byString($voletParametreAzimuth->cmdAzimuthSoleilStr);
            $cmd_pourcentage_nuage = cmd::byString($voletParametreAzimuth->cmdCouvertureNuageuseStr);
            $cmd_elevation_soleil = cmd::byString($voletParametreAzimuth->cmdElevationSoleilStr);
            $cmd_temperature_max_jour = cmd::byString($voletParametreAzimuth->cmdTempMaxJourStr);
            $temps_max = $cmd_temperature_max_jour->execCmd();
            if ($temps_max < $voletParametreAzimuth->tempMinActivation) {
                if ($etat_volet != $voletParametreDefaut->positionVoletOuvert) {
                    $options = array('slider' => $voletParametreDefaut->positionVoletOuvert);
                    $cmd_position_volet_action->execCmd($options, $cache = 0);
                    return 'Température max inférieure au minimum application état ouvert';
                }
                else {
                    return 'Etat déjà appliqué température max inférieure au minimum';
                }
            }

            $azimuth_soleil = $cmd_azimuth_soleil->execCmd();
            $elevation_sol = $cmd_elevation_soleil->execCmd();
            $alpha = (pi() / 180) * $elevation_sol;
            $gamma = (pi() / 180) * ($voletParametreAzimuth->azimuthFen - $azimuth_soleil);
            $hauteur = ($voletParametreAzimuth->distanceOmbrage / cos($gamma)) * tan($alpha);

            if ($alpha <= 0 || abs($gamma) >= ((pi() / 180) * $voletParametreAzimuth->angleVision)) {
                if ($etat_volet != $voletParametreDefaut->positionVoletOuvert) {
                    $options = array('slider' => $voletParametreDefaut->positionVoletOuvert);
                    $cmd_position_volet_action->execCmd($options, $cache = 0);
                    return 'Soleil hors fenêtre application état ouvert';
                } else {
                    return 'Etat ouvert déjà appliqué soleil hors fenêtre';
                }
            }

            $nuage = $cmd_pourcentage_nuage->execCmd();
            if ($nuage >= $voletParametreAzimuth->pourcentageNuageMax) {
                if ($etat_volet != $voletParametreDefaut->positionVoletOuvert) {
                    $options = array('slider' => $voletParametreDefaut->positionVoletOuvert);
                    $cmd_position_volet_action->execCmd($options, $cache = 0);
                    return 'Couverture nuageuse supérieure application état ouvert';
                } else {
                    return 'Etat ouvert déjà appliqué couverture nuageuse';
                }
            }

            $percent = round(max(min(100 * ($hauteur / $voletParametreAzimuth->tailleFen), $voletParametreDefaut->positionVoletOuvert), round(100 * ($voletParametreAzimuth->hauteurEncombrement / $voletParametreAzimuth->tailleFen))));
            if ($etat_volet != $percent) {
                $options = array('slider' => $percent);
                $cmd_position_volet_action->execCmd($options, $cache = 0);
                return 'Application etat ensoleillement sur volet ' . $percent;
            }
        }
        else {
            if ($etat_volet != $voletParametreDefaut->positionVoletOuvert) {
                log::add('CustomVolet', 'info', $nom_volet . ' Ouverture du volet');
                $options = array('slider' => $voletParametreDefaut->positionVoletOuvert);
                $cmd_position_volet_action->execCmd($options, $cache = 0);
                return 'Ouverture du volet';
            }
        }
        return 'Aucune modification etat sur volet';
    }
}

class VoletParametresDefaut
{
    public $positionVoletFermee;
    public $positionVoletOuvert;
    public $cmdPositionVoletEtatStr;
    public $cmdPositionVoletActionStr;
}

class VoletParametresPresence
{
    public $positionVoletAbsence;
    public $cmdPresenceStr;
    public $cmdTempMaxJourStr;
    public $tempMinPresence;
}

class VoletParametresNuit
{
    public $cmdCoucherSoletStr;
    public $cmdAubeCivileStr;
    public $positionVoletNuit;
}

class VoletParametresAzimuth
{
    public $cmdAzimuthSoleilStr;
    public $cmdTempMaxJourStr;
    public $cmdCouvertureNuageuseStr;
    public $cmdElevationSoleilStr;
    public $azimuthFen;
    public $tailleFen;
    public $hauteurEncombrement;
    public $distanceOmbrage;
    public $pourcentageNuageMax;
    public $tempMinActivation;
    public $angleVision;
}

Un petit exemple d’utilisation de cette fonction
Je possède un volet roulant dans ma cuisine et je souhaite que la position du volet roulant puisse s’adapter au soleil. Voici le scénario pour mon volet roulant:

Ce scénario est appelé:

Voici le bloc code de ce scénario:

require_once dirname(__FILE__) . '/../../data/php/user.function.class.php';

$default = new VoletParametresDefaut();
$default->positionVoletFermee = 0;
$default->positionVoletOuvert =  99;
// Commande remontant l'état du positionnement du volet
$default->cmdPositionVoletEtatStr = '#[Salon][Volet cage][Etat]#';
// Commande permetant d'effectuer une action de type slider sur le positionnement du volet
$default->cmdPositionVoletActionStr = '#[Salon][Volet cage][Positionnement]#';


// ------ MODE PRESENCE ------ //
$presence = new VoletParametresPresence();
// Position à appliquer lors d'une absence
$presence->positionVoletAbsence = 30;
// Commande remontant la présence dans la maison. 1 si quelqu'un est présent 0 si la maison est vide
$presence->cmdPresenceStr = '#[Maison][Presence][Presence globale]#';
// Commande plugin Météo france remontant la température maximale pour la journée
$presence->cmdTempMaxJourStr = '#[Maison][Météo][Météo du Jour - Aujourdhui - Température Maximum]#';
// Température minimum pour laquelle la gestion de la présence s'applique.
// En dessous de cette température, les volets ne se fermeront plus lors d'une absence
$presence->tempMinPresence = 10;


// ------ MODE NUIT ------ //
$nuit = new VoletParametresNuit();
// Commande plugin héliotrope lorsque l'heure actuelle sera supérieur au coucher du soleil, le volet passera en mode nuit
$nuit->cmdCoucherSoletStr = '#[Maison][Position soleil][Coucher du Soleil]#';
// Commande plugin héliotrope lorsque l'heure actuelle sera inférieure àl'aube civile, le volet passera en mode nuit
$nuit->cmdAubeCivileStr = '#[Maison][Position soleil][Aube Civile]#';
// Position du volet à appliquer lorsque l'on passe en mode nuit
$nuit->positionVoletNuit = 0;


// ------ MODE POSITION SOLEIL ------ //
$azimuth = new VoletParametresAzimuth();
// Commande plugin héliotrope remontant la position azimuth du soleil
$azimuth->cmdAzimuthSoleilStr = '#[Maison][Position soleil][Azimuth 360 du Soleil]#';
// Commande plugin Météo france remontant la température maximale pour la journée
$azimuth->cmdTempMaxJourStr = '#[Maison][Météo][Météo du Jour - Aujourdhui - Température Maximum]#';
// Commande plugin Météo france remontant le poucentage de couverture nuageuse
$azimuth->cmdCouvertureNuageuseStr = '#[Maison][Météo][Météo Actuellement - Couverture Nuageuse]#';
// Commande plugin héliotrope remontant l'altitude du soleil
$azimuth->cmdElevationSoleilStr = '#[Maison][Position soleil][Altitude du Soleil]#';
// Position azimuth de la fenêtre à récupérer sur https://osmcompass.com/
// L'azimuth doit être perpandiculaire à la fenêtre
// Le sens en degrée compte. Les dégrées sont dans le sens des aiguille d'une montre avec 0 au nord, 90 à l'est, 180 au sud, 270 à l'ouest
$azimuth->azimuthFen = 207;
// Taille en m de la fenêtre.
$azimuth->tailleFen = 2;
// hauteur en m d'un éventuel encombrement en face de la fenêtre qui ferait de l'ombre naturellement
// Ici j'ai une haie qui fait à peu prêt 1m
$azimuth->hauteurEncombrement = 1.5;
// La distance à partir de laquelle l'ombrage doit commencer au sol
// Dans mon cas je ne veux que très peu de soleil au sol, l'ombre doit donc commencer à 0,1m.
$azimuth->distanceOmbrage = 0.5;
// Le mode position du soleil ne s'applique que si la couverture nuageuse est inférieure à la valeur ci dessous
$azimuth->pourcentageNuageMax = 70;
// Le mode position du soleil ne s'applique que si la température maximale de la journée est supérieure à la valeur ci dessous
$azimuth->tempMinActivation = 26;
// Angle gauche et droite a partir du milieu de la fenêtre pour lesquels le soleil est visible
$azimuth->angleVision = 60;


$message = userFunction::gestionVolet($default, $presence, $nuit, $azimuth);
$scenario->setLog($message);

J’ai annoté ce scénario ce qui devrait aiguiller sur comment utiliser les différents paramètres.
Je me suis servie de cette source pour le code de position du soleil:

Pour récupérer l’azimuth de votre fenêtre. L’azimuth

Maintenant assez rapidement des explications sur l’utilisation de la fonction PHP dans un scénario.

  1. L’import du fichier user.

Pour pouvoir utiliser la fonction PHP dans le scénario, il faut au préalable importer ce fichier dans le scénario.

require_once dirname(__FILE__) . '/../../data/php/user.function.class.php';
  1. Ajout du paramètre défaut
    Ce paramètre est OBLIGATOIRE et se configure de la manière suivante:
$default = new VoletParametresDefaut();
$default->positionVoletFermee = 0;
$default->positionVoletOuvert =  99;
// Commande remontant l'état du positionnement du volet
$default->cmdPositionVoletEtatStr = '#[Salon][Volet cage][Etat]#';
// Commande permetant d'effectuer une action de type slider sur le positionnement du volet
$default->cmdPositionVoletActionStr = '#[Salon][Volet cage][Positionnement]#';
  1. Ajout du paramètre présence

Ce paramètre est optionnel et se configure de la manière suivante:

// ------ MODE PRESENCE ------ //
$presence = new VoletParametresPresence();
// Position à appliquer lors d'une absence
$presence->positionVoletAbsence = 30;
// Commande remontant la présence dans la maison. 1 si quelqu'un est présent 0 si la maison est vide
$presence->cmdPresenceStr = '#[Maison][Presence][Presence globale]#';
// Commande plugin Météo france remontant la température maximale pour la journée
$presence->cmdTempMaxJourStr = '#[Maison][Météo][Météo du Jour - Aujourdhui - Température Maximum]#';
// Température minimum pour laquelle la gestion de la présence s'applique.
// En dessous de cette température, les volets ne se fermeront plus lors d'une absence
$presence->tempMinPresence = 10;

Si aucune présence ET que la température prévue aujourd’hui est supérieur au minimum indiqué alors le volet se fermera à la position indiquée.

  1. Ajout du paramètre nuit

Ce paramètre est optionnel et se configure de la manière suivante:

// ------ MODE NUIT ------ //
$nuit = new VoletParametresNuit();
// Commande plugin héliotrope lorsque l'heure actuelle sera supérieur au coucher du soleil, le volet passera en mode nuit
$nuit->cmdCoucherSoletStr = '#[Maison][Position soleil][Coucher du Soleil]#';
// Commande plugin héliotrope lorsque l'heure actuelle sera inférieure àl'aube civile, le volet passera en mode nuit
$nuit->cmdAubeCivileStr = '#[Maison][Position soleil][Aube Civile]#';
// Position du volet à appliquer lorsque l'on passe en mode nuit
$nuit->positionVoletNuit = 0;

Entre le coucher du soleil et l’aube civile, le script fermera le volet à la position indiquée.

  1. Ajout du paramètre position du soleil

Ce paramètre est optionnel et se configure de la manière suivante:

// ------ MODE POSITION SOLEIL ------ //
$azimuth = new VoletParametresAzimuth();
// Commande plugin héliotrope remontant la position azimuth du soleil
$azimuth->cmdAzimuthSoleilStr = '#[Maison][Position soleil][Azimuth 360 du Soleil]#';
// Commande plugin Météo france remontant la température maximale pour la journée
$azimuth->cmdTempMaxJourStr = '#[Maison][Météo][Météo du Jour - Aujourdhui - Température Maximum]#';
// Commande plugin Météo france remontant le poucentage de couverture nuageuse
$azimuth->cmdCouvertureNuageuseStr = '#[Maison][Météo][Météo Actuellement - Couverture Nuageuse]#';
// Commande plugin héliotrope remontant l'altitude du soleil
$azimuth->cmdElevationSoleilStr = '#[Maison][Position soleil][Altitude du Soleil]#';
// Position azimuth de la fenêtre à récupérer sur https://osmcompass.com/
// L'azimuth doit être perpandiculaire à la fenêtre
// Le sens en degrée compte. Les dégrées sont dans le sens des aiguille d'une montre avec 0 au nord, 90 à l'est, 180 au sud, 270 à l'ouest
$azimuth->azimuthFen = 207;
// Taille en m de la fenêtre.
$azimuth->tailleFen = 2;
// hauteur en m d'un éventuel encombrement en face de la fenêtre qui ferait de l'ombre naturellement
// Ici j'ai une haie qui fait à peu prêt 1m
$azimuth->hauteurEncombrement = 1.5;
// La distance à partir de laquelle l'ombrage doit commencer au sol
// Dans mon cas je ne veux que très peu de soleil au sol, l'ombre doit donc commencer à 0,1m.
$azimuth->distanceOmbrage = 0.5;
// Le mode position du soleil ne s'applique que si la couverture nuageuse est inférieure à la valeur ci dessous
$azimuth->pourcentageNuageMax = 70;
// Le mode position du soleil ne s'applique que si la température maximale de la journée est supérieure à la valeur ci dessous
$azimuth->tempMinActivation = 26;
// Angle gauche et droite a partir du milieu de la fenêtre pour lesquels le soleil est visible
$azimuth->angleVision = 60;

Si la température de la journée est inférieure à la valeur indiquée, le volet ne se ferme pas
Si le pourcentage d’encombrement nuageux est supérieur à la valeur indiquée, le volet ne se ferme pas
Si le soleil ne situe pas dans la fenêtre, le volet ne se ferme pas
Pour les autres cas, on calcule la position du soleil et on ferme le volet en conséquence.

  1. Appelle de la fonction gestion

La fonction de gestion des volets s’appelle de la manière suivante:

$message = userFunction::gestionVolet($default, $presence, $nuit, $azimuth);
$scenario->setLog($message);

La fonction renvoie un message que j’affiche dans les logs du scénario. Cela me permet d’avoir un état des lieu de ce qu’il s’est passé sur mon volet roulant.

La fonction peut recevoir 4 paramètres: défaut, présence, nuit et azimuth.
défaut est obligatoire pour le fonctionnement et les 3 autres sont optionnel.

Exemple, je ne veux avoir que de la gestion de présence:

userFunction::gestionVolet($default, $presence, null,  null);

Exemple, je ne veux avoir que de la gestion de nuit:

userFunction::gestionVolet($default, null, $nuit,  null);

Exemple, je veux nuit ET présence:

userFunction::gestionVolet($default, $presence, $nuit,  null);

Il existe déjà des plugins sur ce sujet donc je n’ai pas vraiment envie de créer le mien.
L’idée de ce post est de rendre ce scénario évolutif dans la communauté et de le rendre accessible comme peuvent être les blueprints sur HA.
J’aimerais bien rajouter un blocage / déblocage du scénario en fonction d’une action manuelle mais cela viendra plus tard.

Bon dimanche !

Lien Github:

MAJ script: 29/02/2023 18h15

7 « J'aime »

Bonjour et merci pour ce partage

1 « J'aime »

Hello et merci pour ce partage,
Le top avec un scénario de suntracking comme tu le fais c’est de gérer également l’inclinaison des lamelles de stores vénitiens.

Merci pour le partage!

1 « J'aime »

Si vous voulez il y a aussi des plugin pour faire cela
Gestion des volets de mika nt28 et Gestion volet .
Quel différence avec les plugin?

Cette différence

1 « J'aime »