Aller au contenu
jpr105

Piloter le projecteur de la caméra « Présence » de chez Netatmo depuis la Home Center

Recommended Posts

Bonjour,

 

Voilà un moment que je cherchais le moyen de piloter les projecteurs de mes caméras « Présence » (j'en ai une côté cour et une autre côté jardin).
C'est chose faite et je partage ma solution si cela peut aider quelqu'un.

 

Tout d'abord merci à @KiboOst, qui « sévit » sur le forum jeedom, pour son excellent « php-simpleNetatmoAPI ».
D'après ce que j'ai compris il s'agit d'un travail de reverse engineering qui s'est terminé par un retour aux API Netatmo ... sauf, qu'en fouillant dans les API officielles de Netatmo, je n'ai trouvé nulle part le moyen de piloter l'allumage du projecteur et encore moins de gérer sa luminosité !

 

Donc ma solution :

  1. - Côté Serveur (mon Raspberry)
    1.     installation des composants de « php-simpleNetatmoAPI » sur mon Raspberry
    2.     création d'un fichier TXT de paramétrage de l'API et des projecteurs
    3.     écriture d'un script PHP destiné à exécuter une action sur un projecteur
  2. - Côté Home Center
    1.     création d'un VD pour piloter mes 2 projecteurs simultanément
    2.     ... outil prêt pour une utilisation future, ex : allumer tous les extérieurs de la maison en cas de fête et/ou d'intrusion

 

Un peu de contenu si cela vous intéresse :

  • Côté HC2, le VD et ses icônes
  • Côté Raspberry, le fichier TXT et le script PHP

 

Et voilou ... enjoy

Cordialement - Jean-Paul

 

Le VD

 

p.png?size=2048x1536&size_mode=3    p.png?size=2048x1536&size_mode=3    p.png?size=2048x1536&size_mode=3     p.png?size=2048x1536&size_mode=3    p.png?size=2048x1536&size_mode=3

 

L'export du VD est disponible en fichier joint.

 

Sur le Raspberry

 

1 - Fichier texte de paramètrages

User=..........
Password=..........
ClientId=..........
ClientSecret=..........
Projo1Home=3
Projo1Name=Présence avant
Projo2Home=1
Projo2Name=Présence arrière

2 - Script PHP

<?php

//--------------------------------------------------------------------------------------------------
//
// Script de commande du projecteur d'une caméra Presence Netatmo
//
// Inspiration : https://github.com/KiboOst/php-simpleNetatmoAPI
//
// Principe :
// 1 - Les infos de connexion sont enregistrées dans un fichier texte sur ce serveur
//     . les 4 premières lignes sont dédiées à la connexion à l'API Netatmo
//     . puis une paire de lignes par caméra (ligne 1 = code 'Maison', ligne 2 = nom 'Présence')
// 2 - Pour connaître les 'Home' et 'Name' des projecteurs :
//     . ne saisir que les 4 premières lignes dans le fichier texte
//     . lancer le script comme ceci : /ProjoAutoOnOff.php?projo=1&action=on
//     . lire ce qui s'affiche
//     . rechercher "Si le nombre de projecteurs est égal à zéro" dans le code
//     . débloquer/dupliquer les lignes en commentaires en remplacant 'xx' par le/les codes 'Maison'
// 3 - En entrée : 
//     . le numéro du projecteur à piloter (1 ou 2 ... ou plus)
//     . la commande à envoyer au projecteur ('auto', 'on' et 'off')
// 4 - En sortie :
//     . commande OK
//     . commande non effectuée car le projo est déjà à l'état demandé
//     . autre (erreur)
//
//--------------------------------------------------------------------------------------------------

$Verbose = false;

/* Validation du code action */

$Action = $_GET["action"];

if (strlen($Action) == 0) {
    exit('Missing action code');
    } else {
    if ($Action != 'auto' and $Action != 'on' and $Action != 'off') {
    exit('Invalid action code');
    } 
}

if ($Verbose) {echo 'Code action ----> ', $Action, '<br>';}

/* Récupération du numéro de projecteur */

$NumProjo = $_GET["projo"];

if (strlen($NumProjo) == 0) {
    exit('Missing floodlight number');
}

if ($Verbose) {echo 'Numéro de projecteur ----> ', $NumProjo, '<br>';}


/* Ouverture du fichier des infos de connexion au routeur et retourne un tableau contenant une ligne par élément */

$lines = file('ProjosCredentials.txt');
$NbLines = count($lines);

if ($Verbose) {
    foreach ($lines as $lineNumber => $lineContent)
    {
    echo $lineNumber,' ',$lineContent, '<br>';
    }
    echo 'Nombre de lignes : ', $NbLines, '<br>';
}

/* Vérification du nombre de lignes */

if (($NbLines % 2) == 1) {
  exit('Invalid line number (odd)');
}
  
/* Chargement des variables de connexion */

$Netatmo_User = "";
$Netatmo_Psw = "";
$Netatmo_ClientID = "";
$Netatmo_ClientSecret = "";

/* ----> Netatmo User */

$mystring = trim($lines[0]);
$findme   = 'User=';
$pos = strpos($mystring, $findme);

if ($pos === false) {
    echo "La chaîne '$findme' ne se trouve pas dans la chaîne '$mystring'", '<br>';
    exit('Error retrieving Netatmo User');
    } else {
    if ($pos <> 0) {
    echo 'La chaîne ', $findme, ' n\'est pas au début de ', $mystring, '<br>';
    exit('Error retrieving Netatmo User');
    } else {
    if ($Verbose) {echo "La chaine '$findme' a été trouvée dans la chaîne '$mystring' et débute à la position $pos", '<br>';}
    $Netatmo_User = substr($mystring, strlen($findme));
    }
}

/* ----> Netatmo Password */

$mystring = trim($lines[1]);
$findme   = 'Password=';
$pos = strpos($mystring, $findme);

if ($pos === false) {
    echo "La chaîne '$findme' ne se trouve pas dans la chaîne '$mystring'", '<br>';
    exit('Error retrieving Netatmo Password');
    } else {
    if ($pos <> 0) {
    echo 'La chaîne ', $findme, ' n\'est pas au début de ', $mystring, '<br>';
    exit('Error retrieving Netatmo Password');
    } else {
    if ($Verbose) {echo "La chaine '$findme' a été trouvée dans la chaîne '$mystring' et débute à la position $pos", '<br>';}
    $Netatmo_Psw = substr($mystring, strlen($findme));
    }
}

/* ----> Netatmo Client ID */

$mystring = trim($lines[2]);
$findme   = 'ClientId=';
$pos = strpos($mystring, $findme);

if ($pos === false) {
    echo "La chaîne '$findme' ne se trouve pas dans la chaîne '$mystring'", '<br>';
    exit('Error retrieving Netatmo Client ID');
    } else {
    if ($pos <> 0) {
    echo 'La chaîne ', $findme, ' n\'est pas au début de ', $mystring, '<br>';
    exit('Error retrieving Netatmo Client ID');
    } else {
    if ($Verbose) {echo "La chaine '$findme' a été trouvée dans la chaîne '$mystring' et débute à la position $pos", '<br>';}
    $Netatmo_ClientID = substr($mystring, strlen($findme));
    }
}

/* ----> Netatmo Client Secret */

$mystring = trim($lines[3]);
$findme   = 'ClientSecret=';
$pos = strpos($mystring, $findme);

if ($pos === false) {
    echo "La chaîne '$findme' ne se trouve pas dans la chaîne '$mystring'", '<br>';
    exit('Error retrieving Netatmo Client Secret');
    } else {
    if ($pos <> 0) {
    echo 'La chaîne ', $findme, ' n\'est pas au début de ', $mystring, '<br>';
    exit('Error retrieving Netatmo Client Secret');
    } else {
    if ($Verbose) {echo "La chaine '$findme' a été trouvée dans la chaîne '$mystring' et débute à la position $pos", '<br>';}
    $Netatmo_ClientSecret = substr($mystring, strlen($findme));
    }
}

/* Chargement des numéros de projecteurs */

$i = 4;
$NbProjo = 0;
$TabProjo = array();

while ($i < $NbLines) {
    $NbProjo = $NbProjo + 1;
    $mystring = trim($lines[$i]);
    $findme = 'Projo' . $NbProjo . 'Home=';
    $pos = strpos($mystring, $findme);
    if ($pos === false) {
        echo "La chaîne '$findme' ne se trouve pas dans la chaîne '$mystring'", '<br>';
        exit('Error retrieving Floodlight' . $NbProjo . ' Home');
        } else {
        if ($pos <> 0) {
        echo 'La chaîne ', $findme, ' n\'est pas au début de ', $mystring, '<br>';
        exit('Error retrieving Floodlight' . $NbProjo . ' Home');
        } else {
        if ($Verbose) {echo "La chaine '$findme' a été trouvée dans la chaîne '$mystring' et débute à la position $pos", '<br>';}
        $TabProjo[$NbProjo][1] = substr($mystring, strlen($findme));
        }
    }
    $i = $i + 1;
    $mystring = trim($lines[$i]);
    $findme = 'Projo' . $NbProjo . 'Name=';
    $pos = strpos($mystring, $findme);
    if ($pos === false) {
        echo "La chaîne '$findme' ne se trouve pas dans la chaîne '$mystring'", '<br>';
        exit('Error retrieving Floodlight' . $NbProjo . ' Name');
        } else {
        if ($pos <> 0) {
        echo 'La chaîne ', $findme, ' n\'est pas au début de ', $mystring, '<br>';
        exit('Error retrieving Floodlight' . $NbProjo . ' Name');
        } else {
        if ($Verbose) {echo "La chaine '$findme' a été trouvée dans la chaîne '$mystring' et débute à la position $pos", '<br>';}
        $TabProjo[$NbProjo][2] = substr($mystring, strlen($findme));
        }
    }
    $i = $i + 1;
 }    

if ($Verbose) {
    echo 'Netatmo User = ', $Netatmo_User, '<br>';
    echo 'Netatmo Password = ', $Netatmo_Psw, '<br>';
    echo 'Client ID = ', $Netatmo_ClientID, '<br>';
    echo 'Client Secret = ', $Netatmo_ClientSecret, '<br>';
    echo 'Nombre de projecteurs = ', $NbProjo, '<br>';
    echo 'Table des projecteurs :', '<br>';
    for ($i=1; $i<=$NbProjo; $i++)
       {
        echo 'Presence', $i, ' Home = ', $TabProjo[$i][1], ' - Presence', $i, ' Name = ', $TabProjo[$i][2], '<br/>';  
       };
}

// Si le nombre de projecteurs est égal à zéro on récupère les infos "Homes"

if ($NbProjo == 0) {

	require($_SERVER['DOCUMENT_ROOT']."/php-simpleNetatmoAPI/class/splNetatmoAPI.php");
	$_splNetatmo = new splNetatmoAPI($Netatmo_User, $Netatmo_Psw, $Netatmo_ClientID, $Netatmo_ClientSecret);
	if (isset($_splNetatmo->error)) die($_splNetatmo->error);
	
	// Liste des maisons avec le nombre de caméras rattachées
	
	$homes = $_splNetatmo->getHomes();
	echo "<pre><br>homes:<br>".json_encode($homes, JSON_PRETTY_PRINT)."</pre><br>";
	
	// --------------------------------------------------------------------------------------------------------------------------------
	// Remplacer 'xx' dans l'instruction suivante par le code maison obtenu et décommenter les lignes pour obtenir les infos 'Présence'
	//
	// $_splNetatmo = new splNetatmoAPI($Netatmo_User, $Netatmo_Psw, $Netatmo_ClientID, $Netatmo_ClientSecret, xx);
	// $Cameras = $_splNetatmo->getPresenceCameras();
	// echo "<pre>Cameras:<br>".json_encode($Cameras, JSON_PRETTY_PRINT)."</pre><br>";
	// ---------------------------------------------------------------------------------------------------------------------------------
	
	exit ('Please enter the projectors codes (House and Name)');
}

/* Validation du numéro de projecteur */

if ($NumProjo < 1 or $NumProjo > $NbProjo) {
    exit('Invalid floodlight number');
}

// C'est parti

/* Récupération du statut du projecteur */

require($_SERVER['DOCUMENT_ROOT']."/php-simpleNetatmoAPI/class/splNetatmoAPI.php");

$ProjoHome = $TabProjo[$NumProjo][1];
$ProjoName = $TabProjo[$NumProjo][2];
$_splNetatmo = new splNetatmoAPI($Netatmo_User, $Netatmo_Psw, $Netatmo_ClientID, $Netatmo_ClientSecret, $ProjoHome);
$Cameras = $_splNetatmo->getPresenceCameras();
$StatusProjo = $Cameras[$ProjoName]['light_mode_status'];

if ($Verbose) {
    echo "<pre>Cameras :<br>".json_encode($Cameras, JSON_PRETTY_PRINT)."</pre><br>";
    echo "Status du projo '", $ProjoName, "' de la maison '", $ProjoHome, "' = ", $StatusProjo, '<br>';
}

/* Si le projo est déjà à l'état demandé on ne fait rien */

if ($Action == $StatusProjo) {
    if ($Verbose) {echo 'Changement du status du projecteur inutile - On arrête', '<br>';}
    exit('Floodlight already set');
}

/* On passe le projo à l'état demandé */

$_splNetatmo->setLightMode($ProjoName, $Action);

if ($Verbose) {echo "Projecteur passé à '", $Action, "'", '<br>';}
exit('Floodlight set');

?>

 

Projecteurs_Caméras.vfib.json

  • Like 1

Partager ce message


Lien à poster
Partager sur d’autres sites

Merci ;-)

 

Tu n'avais pas deja fait le script en LUA pour la Présence ? Pas moyen depuis l'API en lua pour le projecteur ?

Dommage.

 

beau boulot

Partager ce message


Lien à poster
Partager sur d’autres sites

Non je n'avais rien trouvé sur le projo dans les API ... peut-être mal cherché :huh:

 

En tout cas, depuis qu'elles (les caméras Netatmo) sont passées compatibles HomeKit et que je peux dire « SIRI allume le projecteur du jardin » ça m'a un peu énervé et j'ai repris mes recherches pour en arriver là :60:

  • Haha 1

Partager ce message


Lien à poster
Partager sur d’autres sites

Bonjour jpr105, 

Je déterre un topic de mais je galère avec Présence !

Donc si tu es encore sur le forum, je veux bien un petit coup de pouce de ta part pour comprendre le fonctionnement.

Merci.

Partager ce message


Lien à poster
Partager sur d’autres sites

Bonjour @Yorino

Oui je suis toujours là, en quoi puis-je t’aider ?

Cordialement

Partager ce message


Lien à poster
Partager sur d’autres sites

Cool !

 

1/ Alors je viens de voir ton VD, il y a 2 variables qui je pense sont à créer pour définir le chemin d'accès au script PHP si j'ai bien compris.

HC2_AuxServer_IP

HC2_AuxServer_Port

 

2/ Pour le fichier txt de configuration, tu lui donnes un nom en particulier ?  Chez toi il me semble  'ProjosCredentials.txt'  non ?

(Je ne maitrise pas du tout le PHP, mais j'essaye de le déchiffrer quand même…)

 

3/ Quand tu dis "des composants de « php-simpleNetatmoAPI »", dans mon cas ceci sera sur un Synology, est-ce obligatoire ou bien ton script PHP se suffit à lui tout seul ?

 

Je vais essayer de mettre en place ceci ce Week-end, je prépare le terrain là..  ;-)

Merci d'avance, 

 

 

Partager ce message


Lien à poster
Partager sur d’autres sites

Bonjour,

 

1) et 2) tout bon

 

Pour le point 3 je t'ai fait une copie d'écran. Le principe est que le PHP trouve tous les fichiers dont il a besoin. Donc tout est dans le répertoire /html chez moi ... à toi de voir comment c'est organisé sur le Syno

 

May The Force Be With You

 

Cordialement

 

 

Capture d’écran 2020-01-03 à 15.10.45.png

Partager ce message


Lien à poster
Partager sur d’autres sites

Ok merci pour ta réponse, je vais regarder et je te tiens informé.

Partager ce message


Lien à poster
Partager sur d’autres sites

Bon bah message lorsque je lance la commande PHP pour identifier les caméras :  " Can't connect to Netatmo Server."

Dans le fichier txt, les login, MDP etc... tu les mets brutes, sans "xxxx" ou 'xxxx' ?

 

Et je me pose la question si mon Synology à bien accès au Web….

Il l'a car je peux faire les mise à jour DSM etc.. mais est-ce que client Web peut y avoir accès aucune idée. 

Avez vous une technique pour tester ceci ? Un code PHP de test par exemple ?

 

Modifié par Yorino
Compléments d'info

Partager ce message


Lien à poster
Partager sur d’autres sites

Oui les mots de passe et login sont en clair.

 

Sur le Syno n’oublie pas d’activer Web Station, c’est lui qui va installer ton serveur Web et faire en sorte que tes scripts PHP s’exécutent.

 

Petit exemple trouvé sur le Net ci-après pour tester ton install ... à adapter bien sûr :

Trouver la version de PHP via phpinfo()

Si vous souhaitez vérifier de façon fiable la version qui est activée sur un domaine procédez comme il suit :

  • Connectez vous par ftp sur l'espace web concerné.
  • Créez un fichier phpinfo.php à la racine du site (répertoire httpdocs).  <--- pour toi ce sera le dossier "web" créé par Web Station
  • Ouvrir le fichier phpinfo.php
  • Saisissez le code suivant :
    <?php
    phpinfo();
    ?>
  • Enregistrez le fichier phpinfo.php.
  • Fermer l'éditeur de texte (ou le fichier).
  • Ouvrez le fichier phpinfo.php avec votre navigateur web : http://.....urldevotresite...../phpinfo.php
  • Vous pourrez alors voir la version de PHP ainsi que les modules activés, les valeurs du php.ini, htaccess, ...
Modifié par jpr105

Partager ce message


Lien à poster
Partager sur d’autres sites

Web Station est bien activé.

D'ailleurs le script php s'execute bien dans la mesure ou il me retourne une réponse.

Là ou j'ai un doute, c'est sur le fait que je n'ai pas configuré le syno pour qu'il soit accessible depuis l'extérieur.... Je pense que le blocage vient de la.

Il faut que je regarde comment configurer ceci et mettre en place les redirections sur les routeurs de la box.

 

@Lazer si tu passes par la, je crois que tu as un syno aussi, tu peux sans doute me conseiller. ;-)

Modifié par Yorino

Partager ce message


Lien à poster
Partager sur d’autres sites

Tu as bien généré les infos de connexion sur dev.netatmo.com ?

Le 31/10/2018 à 10:29, jpr105 a dit :

ClientId=..........

ClientSecret=..........

Partager ce message


Lien à poster
Partager sur d’autres sites

oui.

J'ai déja connecté la station météeo sur la HC2 et ceci fonctionne.

Partager ce message


Lien à poster
Partager sur d’autres sites

Alors j'avance doucement, si j'héberge les scripts sur un domaine chez OVH, j'ai un retour quand je lance la commande pour identifier le nom de la maison.

Donc j'ai bien un problème avec le Synology.

 

Je pense que je vais donc m'orienter vers la solution de l'hébergement des scripts sur mon domaine chez OVH.

En même temps, c'est pas moins sécure que le Synology héberger à la maison...

 

 

Partager ce message


Lien à poster
Partager sur d’autres sites

Bonjour,

 

Je ne sais pas si cela peut t'aider mais il me revient que j'avais eu des problèmes de droits lors de l'install d'un site web WordPress sur mon Syno.

J'avais du faire ça 

root@SynoJPR_2015:~# chown -R http:http /volume1/web/xxxxxxx
root@SynoJPR_2015:~# chmod -R 775 /volume1/web/xxxxxxx
root@SynoJPR_2015:~# exit

Peut-être une piste B)

Partager ce message


Lien à poster
Partager sur d’autres sites

Hello, 

Bon pour tenir au courant de mes avancées sur cette gestion de Présence….

 

Alors je suis parti sur le principe d'héberger les scripts PHP sur mon domaine chez OVH. Ne souhaitant pas ouvrir mon Synology vers l'extérieur plus qu'il ne l'est déjà.

=> C'est ok

 

Je me suis ensuite servi de ton script de base pour comprendre comment fonctionnait l'énorme boulot fournit par KiBoOst.

J'ai réussi à comprendre que l'on pouvait envoyer la commande que l'on souhaite en appelant le script depuis une URL et en passant des paramètres dans cette URL.

Et c'est là ou j'ai pris un chemin différent, car je ne souhaitais pas héberger un fichier avec tous les identifiants en clair NetAtmo sur un site web….

J'ai donc choisi une solution qui consiste :

- Héberger effectivement une partie des identifiants sur le site Web, mais dans un fichier php crypté. (C'est toujours un peu plus sécurisé qu'un txt)

- Passer l'autre partie des identifiants à partir de l'URL envoyer pour exécuter le script (URL en HTTPS), mais en ayant pris soin de mettre un discriminant dans ces derniers qui sera ensuite recorrigé par le script php lors de l'exécution.

Alors oui je sais, ce n'est pas le top du top, mais ceci permet quand même de rendre le truc un peu plus complexe à déchiffrer au cas où...

 

Voilà, à l'heure actuelle j'arrive à allumer/éteindre de façon basique et sans contrôle d'état les caméras depuis uns scène du HC2.

 

Prochaines étapes =>

- Etoffer le script PHP sur le serveur pour gérer le contrôle d'état de la caméra avant la modification.

- Regarder comment gérer Welcome (lui dire par exemple que tout le monde est parti quand j'active une scène ou via géoloc)

- Gérer une sorte de mode panique de l'éclairage en cas de problème. (incendie par exemple, faire clignoter les caméras…)

 

J'avance et je partage ensuite.

A+

 

Partager ce message


Lien à poster
Partager sur d’autres sites

juste ce message pour dire MMMMMMMMMMMMMMMEEEEEEEEEEEEERRRRRRRRRRRRRRRRRRRCCCCCCCCCCCCCIIIIIIIII jpr et KiboOst pour le partage.

 

C'est un boulot de dingue ce truc et cela marche nickel.

 

Enfin heureusement que ceci soit possible !!!

 

Suis tout heureux :-)

 

Pour info: 

J'ai pu récupérer l'etat du projo et l'etat de la surveillance via ceci:

 

$StatusProjo = $Cameras[$ProjoName]['light_mode_status']; 
 
$StatusProjo = $Cameras[$ProjoName]['status'];

 

et utiliser la fonction setMonitoring pour activer/desactiver la surveillance

 

$_splNetatmo->setMonitoring($ProjoName$Action);
 

 

  • Like 1

Partager ce message


Lien à poster
Partager sur d’autres sites

Merci, content que cela ait servi :60:

 

Pour info j'ai un peu "poussé" la solution et je peux :

  • dire « Alexa, allume dehors » ... et dans ce cas j'allume mes deux Présence et mes deux lampes extérieures (FGS-212)

--> merci HA-BRIDGE

  • et je suis prêt à intégrer cette fonctionnalité dans mon système d'alarme ... que je finirai un jour 

 

Merci Lorenzo, merci pour les deux nouvelles fonctionnalité

Modifié par jpr105

Partager ce message


Lien à poster
Partager sur d’autres sites

×