Gérer et afficher ses caméras IP dans Jeedom sans le plugin « Caméra »

Salut,

Dans cet article je vous propose de découvrir comment gérer et afficher des caméras IP (webcam) dans Jeedom, sans utiliser le plugin officiel « Caméra ».

En effet, le plugin officiel, payant et offrant de nombreuses fonctionnalités avancées, n’est pas nécessaire pour faire des choses assez simples avec des caméras IP, comme par exemple:

  1. Afficher l’image (une miniature) d’une caméra avec un rafraichissement automatique

  2. Piloter la caméra: la faire tourner, activer ou désactiver l’infrarouge, etc.

Tout ceci peut se faire simplement avec le plugin « Script » et un widget personnalisé. Nous allons voir comment.

Principe


Toute caméra IP digne de ce nom possède une API (Application Programming Interface), en général accessible en HTTP, permettant de s’interfacer avec elle de façon programmatique (c’est à dire avec du code, et pas un bonhomme qui clique manuellement sur des boutons). Cette API permet au minimum de récupérer un snapshot de l’image de la caméra, et également bien souvent de la piloter, de la configurer, etc.

A titre d’exemple, ma caméra Foscam FI9821P expose son API via l’interface http://ip_camera:88/cgi-bin/CGIProxy.fcgi

La documentation de cette interface peut être trouvée en ligne sur le site du constructeur, par exemple ici pour ma caméra Foscam. En consultant cette documentation, on trouve facilement quels appels faire pour commander la caméra ou pour accéder à sa configuration. A titre d’illustration, voici deux appels possibles :

  1. Prendre un snapshot (une image) instantané de la caméra:
    http://ip_caméra:88/cgi-bin/CGIProxy.fcgi?cmd=snapPicture2&usr=username&pwd=password
  2. Activer les leds infrarouge:
    http://ip_caméra:88/cgi-bin/CGIProxy.fcgi?cmd=openInfraLed&usr=username&pwd=password

Évidemment, pour des raisons de sécurité, l’accès à cette interface nécessite un nom d’utilisateur et un mot de passe (définit préalablement dans l’interface d’administration de la caméra).

Sur cette base, on voit se distinguer les deux types de commandes classiques que l’on connait pour tout équipement dans Jeedom:

  • Les commandes de type « Action »: tourne la caméra, allume les leds infrarouge.
  • Les commandes de type « Info »: renvoi moi une image de la caméra

L’idée, tout simple, est donc d’utiliser le plugin « Script » pour créer de toute pièce un équipement avec les commandes de type « Action » permettant d’actionner la caméra, et une commande de type « Info » qui retournera la valeur de l’image. Pour finir, on utilisera un widget personnalisé pour afficher l’image et surtout la rafraichir.

On verra qu’il y a une subtilité importante pour la partie récupération de l’image et son rafraichissement automatique dans le navigateur, mais j’explique tout ça dans la partie implémentation.

Implémentation


1/ Création de l’équipement de type « Script »

Il faut tout d’abord installer, si ce n’est déjà fait, le plugin « Script », depuis le market Jeedom. Ensuite il faut ajouter un nouvel objet de type Script (menu « Plugins->Programmation->Script » puis « Ajouter »). Appelons l’équipement, par exemple, « Webcam maison »:

Notez bien qu’il est inutile de mettre une auto-actualisation par cron, c’est même déconseillé puisque l’on a pas besoin d’actualiser en permanence l’image de la caméra, tant qu’on ne la regarde pas. L’actualisation de l’affichage de l’image sera géré par un widget spécifique que l’on va créer pour l’occasion.

2/ Création des commandes de type « Action »

Nous allons d’abord créer les commandes d’action de la caméra, c’est à dire les commandes qui permettent, par exemple, de la faire bouger (pour les caméras motorisées) ou d’activer/désactiver les leds infrarouges, etc.

Pour cela il faut aller sur l’onglet « Commandes », puis:

  • Cliquer sur « Ajouter une commande script »
  • Type de script « HTTP »
  • Type de commande « Action »
  • puis l’on met l’URL de l’API correspondant à la commande que l’on souhaite envoyer à la caméra.

Exemple avec une position que j’ai préalablement créé et enregistré dans l’interface d’administration de la caméra:

Et on continue comme ça, en créant toutes les commandes d’action que l’on souhaite, on peut également assigner une icône représentative de la commande.

Pour ma part, à titre d’exemple, j’ai quatre commandes de type « Action » :

  1. Bouge la caméra en position « salon »
  2. Bouge la caméra en position « salle à manger »
  3. Allume les leds infrarouge
  4. Éteins les leds infrarouge

Pour toutes ces commandes j’utilise le widget d’affichage de base (c’est à dire que je ne change rien), j’utilise également des variables globales à  Jeedom pour stocker le nom d’utilisateur et le mot de passe pour se connecter à la caméra, c’est tout à fait optionnel mais ça évite d’avoir à le changer partout le jour où je décide d’en changer.

3/ Création de la commande « Info »

Les commandes de type « Info » sont celles qui permettent de remonter à Jeedom la valeur d’un équipement. Pour le cas d’une caméra, l’équipement n’a qu’une seule commande de type « Info », c’est la commande qui retournera la valeur de l’image.

Il faut savoir que pour les commandes de type « Info », Jeedom supporte 3 types de valeur de retour:

  1. Valeur de type « binaire » (que l’on devrait plutôt appeler booléen pour éviter les confusions), utilisée pour les états, c’est à dire que ce type de valeur de retour doit être 0 ou 1.
  2. Valeur de type « numérique », c’est à dire un nombre.
  3. Valeur de type « autre », qui est en fait une chaine de caractères.

Or, lorsque l’on demande à une caméra IP, via son API, de nous renvoyer un « snapshot » de l’image de la caméra, celle-ci nous retourne un gros bloc de données binaires représentant l’image au format JPEG, ou PNG selon les caméras. A priori Jeedom ne sait pas gérer ce type de données de retour, mais ça n’est pas grave car nous n’allons pas utiliser directement l’URL d’API de la caméra pour récupérer l’image.

A la place, nous allons créer un script PHP qui se chargera de récupérer l’image de la caméra et de la retourner, mais ce script PHP sera appelé directement par le navigateur (et non pas par Jeedom comme c’est normalement le cas) via le widget spécifique.

Alors c’est parti:

  1. Cliquer sur « Ajouter une commande script »
  2. Type « Script »
  3. Type de commande « Info« 
  4. puis cliquer sur le bouton « Nouveau Script », le nommer « snapshot.php » par exemple (l’extension .php est importante),
  5. pour finir coller le code ci-dessous:
<?php
// Le nom d'utilisateur et le mot de passe pour se connecter à votre caméra IP
$username='votre_utilisateur_camera';
$password='votre_mot_de_passe_camera';

// Mettez ici l'URL propre à votre modèle de caméra permettant de récupérer un snapshot
// Exemple pour ma Foscam FI9821P:
$url="http://192.168.0.10:88/cgi-bin/CGIProxy.fcgi?cmd=snapPicture2&usr=".$username."&pwd=".$password;
$handler = curl_init($url); curl_setopt_array( $handler, array( CURLOPT_RETURNTRANSFER => true,
    CURLOPT_USERPWD => $username.":".$password
  )
);

$data = curl_exec($handler);
curl_close($handler);

// Si ce script a été appelé en ligne de commande (c'est le cas lorsque on utilise un scénario par exemple)
if (defined('STDIN')) {
  echo base64_encode($data); // on retourne l'image encodé en base64, c'est à dire un chaine de caractère que l'on peut utiliser dans Jeedom
}
// Sinon, c'est que le script a été appelé par le navigateur, par le widget d'affichage de l'image.
else {
  header('Content-Type: image/jpeg');
  echo $data;
}
?>

Dans ce script, vous devrez modifier 3 choses:

  1. Le nom d’utilisateur et le mot de passe à utiliser pour se connecter à votre caméra
  2. L’URL de l’API permettant de récupérer un snapshot

Une fois le script PHP enregistré, la commande ressemble à ça:

3/ Création du widget d’affichage spécifique

Nous allons maintenant créer le widget qui sera en charge d’afficher l’image de la caméra retournée par le script PHP précédemment créé et de rafraichir cette image.

Pour créer un nouveau widget, cliquer sur le menu « Plugins->Programmation->Widget », puis sur le bouton « Ajouter un widget ». Il faut alors remplir les champs demandés comme suit, vous pouvez bien sûr changer le nom du widget, mais souvenez-vous en pour la suite:

Cliquer ensuite sur « Ajouter », et coller le code suivant comme code du widget:

<div class="cmd tooltips cmd-widget" data-type="info" data-subtype="other" data-cmd_id="#id#" title="">
<a target="_blank" href="#OnClick#">
<img class="iconCmd#id#" src="plugins/script/core/ressources/snapshot.php" height="#ImageHeight#" width="#ImageWidth#">
</a>
</div>
<script>
function startImageRefresh () {
setInterval(function() {
$(".iconCmd#id#").attr("src","plugins/script/core/ressources/snapshot.php?"+ new Date().getTime())
}, 5000);
}
startImageRefresh ();
</script>

Dans ce code, on utilise plusieurs paramètres qui sont passés au widget au niveau des paramètres d’affichage de la commande, en particulier on utilise:

  1. #ImageHeight# et #ImageWidth# qui permettent de spécifier la taille de l’image à afficher
  2. #OnClick# qui est une URL arbitraire qui s’ouvre lorsque l’on clique sur l’image de la caméra, par exemple on pourrait mettre le lien vers l’interface de visualisation de la caméra

Et puis il y a la fréquence de rafraichissement de l’image qui est ici fixé à 5 secondes (5000 millisecondes dans le code) que vous pouvez bien entendu modifier, avec parcimonie car il n’est pas dit que Jeedom suivra si la vitesse de rafraichissement est trop élevée.

Sauvegardez le widget, il ne reste plus qu’à l’appliquer à la commande « Info » avec les paramètres nécessaires.

4/ Application du widget à la commande « Info » de la webcam

Pour se faire, on retourne sur l’équipement « Script » de notre caméra, puis au niveau de la commande « Info » (celle sur laquelle on a définit le script PHP), on clique sur les paramètres avancés (les 3 petits engrenages), et dans l’onglet Affichage, on spécifie:

  1. Le choix du Widget d’affichage pour la version « Dashboard » pour lequel on choisit le widget précédemment créé (WebcamSnapshot)
  2. Les 3 paramètres utilisés par le widget:
    1. ImageHeight: la hauteur en pixel de l’image à afficher. Il n’est pas nécessaire que cela soit la taille réelle de l’image retournée par la caméra, mais plutôt la taille de l’image miniature que vous souhaitez afficher.
    2. ImageWidth: largeur en pixel de l’image à afficher.
    3. OnClick: une URL vers laquelle on sera redirigé si l’on clique sur l’image

Résultat


Juste pour montrer que tout ça fonctionne, voici une capture d’écran de mon widget d’affichage de ma caméra IP, avec les différentes commandes de contrôle de la caméra:

(oui, c’est le bordel chez moi, et en plus la pièce est en travaux 🙂 )

Conclusion


Je vous ai montré comment utiliser le plugin « Script », un bout de code en PHP, et un widget spécifique pour afficher et gérer simplement une caméra IP.

Il faut savoir que j’ai un peu simplifié le script PHP que je vous ai montré ici, dans la réalité le mien est légèrement adapté pour prendre en compte un paramètre, tant en ligne de commande qu’en appel web, afin de piloter plusieurs caméras (dont l’API est différente en plus), tout en ayant un seul script PHP et un seul widget pour tout afficher.

Je n’ai pas non plus détaillé ici à quoi me sert la partie retour de l’image encodée en base64 lorsque le script est appelé en ligne de commande, je pourrai l’expliquer sur le forum Jeedom, mais en gros je m’en sers dans mes interactions et scénarios pour récupérer l’image et me l’envoyer par notification Pushbullet ou mail.

Publicités

15 réflexions sur “Gérer et afficher ses caméras IP dans Jeedom sans le plugin « Caméra »

  1. Acidam 23 avril 2019 / 11 h 07 min

    Bonjour,

    merci pour ce tuto au top
    Par contre de puis la derniere mise a jour Jeedom, l’image n’apparait plus dans le widget
    Merci pour votre aide

    cordialement

    J'aime

  2. patator 20 mars 2019 / 0 h 38 min

    Super tuto, merci !
    j’essaye de récupérer le widget sur l’app mobile jeedom mais sans succés – j’arrive à récupérer mon objet caméra et le script Caméras Extérieur…j’ai bien créé un dashboard pour l’app mais rien à faire, impossible d’obtenir une image sur l’app…
    une idée ?

    merci

    J'aime

  3. fab 6 mars 2019 / 11 h 26 min

    SUper article et cela fonctionne parfaitement !
    Je suis également intéressé par la partie envoi capture par mail ou pushbullet 🙂

    Aimé par 1 personne

  4. jerome 23 février 2019 / 9 h 00 min

    super merci pour ton tuto!!! j’ai mis ça en lace ça fonctionne nikel par contre quand tu as 2 camera comment procède tu? j’ai dupliqué et change le nom du snapshot.php car ça fasait doublon, j’ai bien les 2 cameras mais sur un j’ai un mix des 2 images

    J'aime

  5. Civodul 18 janvier 2019 / 22 h 03 min

    Salut,
    Merci pour le tuto.
    J’ai réussi à intégrer ma caméra Bluestork IPCAM (assez ancienne), en utilisant le déplacement du fichier php pour le problème de droit d’accés.
    Bonne continuation

    J'aime

  6. Christophe 27 novembre 2018 / 17 h 14 min

    Bonjour et merci pour cette explication très intéressante.
    J’ai un peu galéré pour le faire fonctionner car j’ai rencontré deux problèmes:
    – la ligne de commande vers ma caméra Foscam qui était: http://192.168.1.104/snapshot.cgi?user=« .$username. »&pwd= ».$password
    – les droits sur le script snapshot (même sans le fichier .htaccess), j’ai fini par le déplacer dans /var/www/html/snapshot.php.
    suivi des modifications du chemin dans le script et le widget.

    Mais bon, il faut bien savoir s’adapter!

    J'aime

  7. Sigalou 22 septembre 2018 / 8 h 02 min

    Bonjour,

    J’ai bien suivi toute l’explication, j’ai même simplifié au maximum avec un fichier jpeg directement dans le dossier plugins/script/core/ressources, mais je m’aperçois que j’ai un forbidden, l’accès au fichier dans plugins/script/core/ressources est bloqué et l’affichage ne fonctionne pas.
    J’ai lu qu’il y avait eu des restrictions depuis les toutes dernières version de jeedom (pour des questions de sécurité)

    Vous avez constaté le même chose ? ou je fais fausse route ?
    Merci pour ces explications !!

    J'aime

    • arno0x0x 22 septembre 2018 / 8 h 31 min

      Bonjour,

      En effet, très peu de temps après que j’ai publié cet article, l’équipe Jeedom a sorti une mise à jour du plugin « script » dont la seule modification est d’empêcher l’exécution des scripts via des appels HTTP dans le répertoire « plugins/script/core/ressources ». Chercheraient-ils à empêcher les Jeedomiens de se passer de leur plugin payant « Caméra » ?

      Pour autant, la correction est simple:
      Il suffit de supprimer (ou de renommer, histoire de le garder au cas où) le fichier « plugins/script/core/ressources/.htaccess ». Après cela, le script fonctionne.

      Il faudrait que je mette à jour cet article avec cette explication, et aussi que je réponde aux autres commentaires… mais je manque de temps !

      Cordialement,
      Arno

      J'aime

  8. BeBeL 30 août 2018 / 13 h 07 min

    Bonjour,
    J’aimerais savoir comment vous faites pour envoyer la photo par email…?
    Merci

    J'aime

    • BeBeL 3 septembre 2018 / 14 h 09 min

      Bonjour,

      Je me permets de préciser ma question étant donné que je n’ai pas de réponse.
      Je possède un détecteur de mouvement et une caméra foscam. Je souhaiterai que lorsque le détecteur de mouvement s’active, qu’un script prenne une photo avec la caméra, et l’envoi par email… Avez vous une piste à me donner pour étudier cela ??

      Merci

      Julien

      J'aime

  9. Ben 14 août 2018 / 1 h 14 min

    Bonsoir,

    Je suis interessé par l’envoi des snapshot par mail, possible d’avoir une explication ?

    Merci

    J'aime

  10. Gérard BINELLI 20 juin 2018 / 10 h 47 min

    Bonjour,

    Cet article me donne espoir de pouvoir modifier mon affichage de caméra sur Jeedom.

    J’aurais besoin d’un peu d’aide:

    J’ai 2 caméras IP, l’une surveillant ma voiture, l’autre celle du visiophone.

    La caméra parking est toujours affichée

    En activant une entrée quelconque par l’appel du visiophone je voudrais basculer l’image du visiophone pendant environ 10 secondes à la place de celle du parking.

    Pensez vous que ce soit possible avec un script

    Je vous remercie d’avance pour votre réponse

    Cordialement

    J'aime

  11. yafau42 9 juin 2018 / 16 h 21 min

    Bonjour,
    merci pour cet article
    Pourriez vous précisez pour le Onclick car je n’arrive pas à avoir l’image dans le widget pourtant j’ai une foscam Fi9803P

    Merci

    J'aime

    • arno0x0x 10 juin 2018 / 16 h 41 min

      Le paramètre « OnClick » est optionnel et n’a rien à voir avec l’affichage de l’image dans le widget. C’est juste un lien que sera ouvert lorsque l’on clique sur l’image. Typiquement, on mettrait l’URL d’accès à l’interface de la webcam, ou quelque chose comme ça.
      Si l’image de votre Foscam ne s’affiche pas, il peut y avoir plusieurs raisons:
      1. L’URL d’accès au snapshot de l’image n’est pas la bonne (à vérifier en l’ouvrant dans un onglet d’un navigateur)
      2. Le couple username/password n’est pas le bon dans le script PHP. Mais ce point peut être validé par l’étape « 1 » ci-dessus.
      3. La machine sur laquelle tourne Jeedom n’a pas d’accès réseau à votre webcam (routeur WiFi qui fait du NAT, ce genre de chose)

      Il ne faut pas oublier de paramétrer trois variables dans le script PHP que je fourni:
      1. Le username
      2. Le password
      3. L’URL d’accès au snapshot de l’image de votre webcam

      En espérant vous mettre sur la piste.
      Tout ces points doivent bien sûr être validés et testés au préalable dans un navigateur

      J'aime

      • FRÉDÉRIC TRYNISZEWSKI 2 septembre 2018 / 19 h 05 min

        Bonjour,
        Le script fonctionne très bien dans un fichier html et un fichier PHP (sur un serveur web)
        Mais je n’ai aucune image sur jeedom.
        auriez vous une explication ?
        voici le PHP
        true,
        CURLOPT_USERPWD => $username. »: ».$password
        )
        );

        $data = curl_exec($handler);
        curl_close($handler);

        // Si ce script a été appelé en ligne de commande (c’est le cas lorsque on utilise un scénario par exemple)
        if (defined(‘STDIN’)) {
        echo base64_encode($data); // on retourne l’image encodé en base64, c’est à dire un chaine de caractère que l’on peut utiliser dans Jeedom
        }
        // Sinon, c’est que le script a été appelé par le navigateur, par le widget d’affichage de l’image.
        else {
        header(‘Content-Type: image/jpeg’);
        echo $data;
        }
        ?>
        le widget est le votre.(c’est le code que j’ai mis dans ma page html de test qui fonctionne très bien)
        Merci d’avance
        et bravo pour votre idée !

        J'aime

Répondre

Entrez vos coordonnées ci-dessous ou cliquez sur une icône pour vous connecter:

Logo WordPress.com

Vous commentez à l'aide de votre compte WordPress.com. Déconnexion /  Changer )

Photo Google

Vous commentez à l'aide de votre compte Google. Déconnexion /  Changer )

Image Twitter

Vous commentez à l'aide de votre compte Twitter. Déconnexion /  Changer )

Photo Facebook

Vous commentez à l'aide de votre compte Facebook. Déconnexion /  Changer )

Connexion à %s