S-DoorBell : connecter sa sonnette à Constellation avec un ESP8266 ou comment protéger le sommeil de son enfant, la sonnette propulsée dans Constellation !
Avec l’arrivée d’un enfant beaucoup de chose change dans la vie d’un nouveau parent, à commencer par les projets connectés ! Loin de moi l’idée d’équiper mon fils de différents capteurs, c’est la maison qui s’adapte à cette nouvelle organisation familiale en gérant de nouvelle chose comme la température de sa chambre, l’état de sa veilleuse, son volet, l’aération et qualité de l’air, etc…
Bref une maison qui prend soin de nous et automatise un grand nombre de petites actions que nous réalisons au quotidien.
Comme vous le savez un nouveau-né dort beaucoup et avec son arrivée beaucoup de visites à programmer avec les amis ou la famille. Dès lors une phrase revient souvent : « ne sonne pas, bébé dort ! ». Mais entre les livreurs, le facteur et les oublis des proches, il y a forcément des cas où la sonnette vient perturber la sieste du petit.
Alors en bon adapte du DIY et équipé d’une plateforme d’interconnexion des applications, services et objets connectés telle que Constellation il devient facile et rapide d’apporter une solution intelligente à ce problème. Et de fil en aiguille, avec la souplesse qu’offre Constellation, une simple sonnette branchée sur un ESP8266 et connectée à Constellation ouvre la voix à une multitude de possibilité !
Découvrons ensemble comment propulser une sonnette dans une Constellation
Pour information, la toute première version de cet article avait été publié dans le magazine Programmez! n°200 paru en Octobre 2016.
Informatiser une sonnette
La première étape consiste à pouvoir échanger informatiquement avec notre sonnette, c’est-à-dire savoir quand quelqu’un sonne mais aussi pouvoir agir sur le carillon.
Il existe des interphones IP comme celui de Linkcom ou d’Helios qui se comporte comme des clients SIP, c’est-à-dire que lorsque quelqu’un sonne, c’est un appel VoIP qui est déclenché avec la vidéo et son. Le principal problème de ce genre de portier est le prix, comptez de 750€ à 1500€, un peu cher pour une sonnette ! Il existe aussi des portiers Wifi (non VoIP) un peu plus abordables comme celui de Konx (169€) ou DoorBird (à partir de 350 euros) mais il faudra cependant bien étudier ce que l’API vous propose si vous souhaitez l’intégrer dans vos projets.
Sans opter pour un portier onéreux, vous pouvez mettre une simple sonnette filaire ou sans fil. Côté sans fil, vous pouvez partir sur une sonnette Chacon (30 euros le kit) couplée à un RFXCOM (émetteur/récepteur 443Mhz). Il existe d’ailleurs dans le catalogue des packages Constellation le connecteur RFXCOM vous permettant de contrôler le carillon, des prises Somfy, récupérer les données des capteurs météo Oregon, La Crosse, ou autres, des détecteurs de fumée ou sonnettes Chacon, etc…
Dans mon cas, j’ai déjà une simple sonnette filaire installée avec un bouton poussoir à l’extérieur et un carillon 220V dans le salon.
Pour comprendre son fonctionnement, le carillon dans le salon est alimenté en 220V et envoie une tension de 12V au bouton poussoir de la sonnette. Lorsque l’on appuie sur la sonnette, cela ferme la boucle et le carillon sonne, c’est aussi simple que cela !
Si retire le cache, voici la vue intérieure du carillon installé dans mon salon. On voit la phase (fil rouge) et le neutre (fil bleu) sur la gauche et du câble téléphonique qui transporte le 12V vers la sonnette permettant de faire sonner le carillon.
Côté rue, une simple sonnette qui se comporte comme un bouton poussoir “pour faire le lien” entre les fils jaune et orange :
De ce fait mon idée pour informatiser la sonnette est créer une simple « passerelle » entre le bouton poussoir de la sonnette et le carillon. En quelque sorte, un « Man-in-the-middle » pour intercepter l’ordre de sonner !
Il nous faut simplement connecter la sonnette sur un GPIO pour savoir quand quelqu’un sonne et un relais pour ouvrir/fermer la boucle du carillon afin d’activer de la sonnerie. On aurait pu utiliser un transistor comme un MOFSET mais ne connaissant pas les spécifications de mon carillon actuel j’ai opté pour un simple relais que j’avais en stock dans mon atelier !
Côté matériel, le plus simple et le moins onéreux est d’utiliser des puces ESP8266 bien entendu. Lecteur de ce blog, vous connaissez bien cette puce que j’ai pu vous présenter à maintes reprises avec pleins de projets comme mon compteur d’électricité, ma passerelle IR, et bien d’autre chose sur le portail développeur Constellation.
Pour rappel l’ESP8266 est un microcontrôleur avec une connectivité Wifi pour un cout avoisinant les 2€ et çà tombe bien, car il est complètement intégré dans Constellation avec une librairie Arduino permettant de l’interconnecter avec vos applications, services et autres objets quelque soit la technologie que vous utilisez.
Pour la partie électronique, nous créons une carte avec six connecteurs :
- deux pour l’alimentation (5V)
- deux pour connecter le bouton poussoir de la sonnette
- deux autres pour le retour vers le carillon (via la sortie du relais)
L’ESP8266 sera alimenté en 3,3V à travers un régulateur de tension (LD33v). Le bouton poussoir sera connecté sur la GPIO0 en pull-down et pour activer le carillon nous utiliserons un relais 5V piloté par un transistor via la GPIO2.
Le tout résumé dans un schéma :
Côté “hardware”
Pour la réalisation, je commence par découper une plaque epoxy de la taille de mon boitier ABS (environ 8cm sur 5cm pour 2cm d’épaisseur) et dispose les 6 borniers :
Une fois l’usinage du boitier réalisé, il ne reste plus qu’à souder et connecter tous nos composants. J’utilise comme d’habitude des headers 4×2 pour “déposer” un ESP-01 sur le PCB :
Une fois la carte prête, j’utiliserai ma carte de programmation que je vous avais présenté dans cet article pour développer et tester le microprogramme :
Quand tout est prêt et testé, il ne restera plus qu’à connecter notre carte “entre la sonnette et la carillon”, alimenter le boitier en 5V et à accrocher çà proprement !
Dans mon cas, j’ai de la chance, le câble entre la sonnette et le carillon passe par le tableau électrique où je dispose d’un transformateur 5V sur rail DIN. Bref, il m’a juste fallut couper le câble en deux pour pouvoir le connecter sur mon boitier, le tout étant proprement “planqué” dans l’armoire du tableau électrique de la maison !
La vue intérieure de notre boitier avec l’ESP-01 :
Côté “software”
Pour la programmation de l’ESP8266, nous allons utiliser l’IDE Arduino. Pour les détails techniques, n’hésitez pas à consulter cet article.
Dans le « setup() », commençons tout d’abord par initialiser nos deux GPIO : la « 0 » en sortie (vers le carillon) et la « 2 » en entrée pour le bouton de la sonnette.
1 2 3 | // Setup I/O pinMode(PIN_BELL, OUTPUT); pinMode(PIN_BUTTON, INPUT); |
On aura bien entendu déclaré dans l’entête de notre ficher les deux constantes suivantes :
1 2 3 | /* HW Constants */ const int PIN_BELL = 3; const int PIN_BUTTON = 2; |
Dans la boucle principale, il suffit de mesurer l’état de l’entrée. Si quelqu’un sonne, l’entrée sera à l’état bas (pull-down dans notre montage) et donc il suffira de déclencher le relais pour faire sonner le carillon.
1 2 3 4 5 6 | if (digitalRead(PIN_BUTTON) == LOW) { // On sonne, faire sonner le carillon! digitalWrite(PIN_BELL, HIGH); delay(1000); digitalWrite(PIN_BELL, LOW); } |
Et voilà, en quelques lignes de code avec un ESP8266, comment s’interfacer avec une simple sonnette filaire !
Dans la “vrai vie” il faut “debouncer” ! En effet, dans le code ci-dessus tant que le visiteur maintient le doigt sur la sonnette l’état est “LOW”. De plus une interférence peut aussi faire permuter l’état de l’I/O pendant quelques micro/millisecondes.
Le code ci-dessous permet de gérer tout çà ! Lorsque quelqu’un sonnera, on invoquera une et une seule fois la méthode “onPressButton” qui se chargera de faire sonner le carillon avec le relais comme vu ci-dessus.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | void checkButtonState() { static int buttonState; // the current reading from the input pin static int lastButtonState = LOW; // the previous reading from the input pin static long lastDebounceTime = 0; // the last time the output pin was toggled static long debounceDelay = 50; // the debounce time; increase if the output flickers int reading = digitalRead(PIN_BUTTON); if (reading != lastButtonState) { lastDebounceTime = millis(); } if ((millis() - lastDebounceTime) > debounceDelay) { if (reading != buttonState) { buttonState = reading; if (buttonState == LOW) { onPressButton(); // Do something here !!!! } } } lastButtonState = reading; } |
Connecter la sonnette à Constellation
Donc maintenant on a un ESP8266 callé entre la sonnette et le carillon avec un petit bout de code Arduino capable de “détecter” lorsque quelqu’un sonne à la porte pour faire sonner le carillon !
La prochaine étape consiste donc à connecter la sonnette à la plateforme Constellation ce qui, avec un ESP8266, est très facile !
Pour cela, commencez tout d’abord par connecter l’ESP au réseau Wifi de la maison :
1 2 3 | #include <ESP8266WiFi.h> const char* ssid = "MON SSID"; const char* password = "my_password_wifi"; |
Dans la méthode « setup », il suffira d’invoquer la méthode “WiFi.begin” pour connecter notre ESP8266 au réseau Wifi et on attendra que la connexion réseau soit établie avant de continuer :
1 2 3 4 5 6 7 8 9 10 | // Connect to Wifi Serial.print("Connecting to "); Serial.println(ssid); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println("WiFi connected. IP: "); Serial.println(WiFi.localIP()); |
Dans l’entête de notre code, nous allons également déclarer un client Constellation basé sur le client Wifi de l’ESP (classe WiFiClient). On précisera dans la déclaration l’adresse du serveur Constellation ainsi que son port TCP et le nom de la sentinelle, le nom du package ainsi que sa clé d’accès :
1 2 | #include <Constellation.h> Constellation<WiFiClient> constellation("monserveur.constellation.lan", 8088, "ESP-DoorBell", "DoorBell", "maaccesskey"); |
« ESP-DoorBell » étant le nom de la sentinelle et « DoorBell » le nom du package d’un point de vue Constellation. Il faudra bien sûr avoir déclaré notre accès au niveau de notre Constellation :
Pour plus d’information à ce sujet, n’hesitez pas à suivre le Hello World ici.
Une fois notre ESP connecté à Constellation, nous pouvons par exemple utiliser les méthodes WriteInfo/Error/Warn pour envoyer en temps réel les logs de notre ESP sur le bus Constellation :
1 | constellation.writeInfo("On sonne à la porte!"); |
Ainsi depuis la Console Constellation (ou depuis n’importe quel package connecté au hub de contrôle) on peut suivre en temps réel notre ESP :
Au-delà de produire du log on peut surtout invoquer des actions des autres packages de votre Constellation !
Par exemple, dans notre code Arduino on pourrait envoyer une notification sur notre smartphone via le package PushBullet par la simple ligne :
1 | constellation.sendMessage("Package", "PushBullet", "SendPush", "{ Title: 'Sonnette', Message:'On sonne à la porte' }"); |
Résultat la notification arrivera sur tous vos devices connectés au service PushBullet (iOS, Android, Chrome, Windows, etc..) lorsque quelqu’un sonne chez vous :
Tout çà avec seulement quelques lignes de code Arduino grâce à Constellation, magique non ?
Pour rappel, dans Constellation chaque package que ce soit une application, un service ou un objet connecté, peut exposer des méthodes qu’on appelle des MessageCallbacks. Ces MessagesCallbacks sont tous référencés et décrits dans Constellation ce qui permet depuis les API ou la Console Constellation, de lister l’ensemble des MC d’une Constellation avec une interface de test :
C’est ainsi qu’un package comme PushBullet ou encore Pushover, expose des MessagesCallbacks permettant d’envoyer des notifications. Cela permet ainsi à n’importe quel système connecté dans Constellation, comme notre ESP8266, d’invoquer cette méthode et d’envoyer des notifications avec une simple ligne de code.
D’ailleurs, le MessageCallbacks Explorer dispose même d’un générateur de code :
On dispose désormais, avec ces quelques lignes de code, d’une sonnette capable de nous envoyer une notification lorsque l’on sonne ! Très bien, mais allons encore plus loin !
Notifier l’utilisateur “où qu’il soit, quoi qu’il fasse”
Comme vous l’aurez compris, avec Constellation à partir du moment où un package expose des actions dans la Constellation, tout le monde peut en profiter ! Ainsi en une ligne de code, votre Arduino/ESP peut contrôler votre thermostat Nest, la domotique Z-Wave, redémarrer votre NUC, piloter les lampes Hue, ouvrir une porte de garage ou même le toit ouvrant de votre Tesla !
Cependant dans notre cas il n’est pas très judicieux de mettre cette « logique » en dur dans l’ESP par le simple fait que la programmation d’un ESP demande de le démonter pour flasher le microprogramme depuis l’IDE Arduino alors qu’à l’inverse, avec Constellation les packages Windows et Linux sont automatiquement déployable à la volée sur vos sentinelles.
C’est pourquoi dans notre cas, il est préférable de mettre la logique du scénario « on sonne à la porte » dans un package C# ou Python par exemple de façon à pouvoir le faire évoluer plus facilement sans avoir besoin de reprogrammer notre ESP.
Pour ce faire, l’ESP8266 va simplement envoyer un message « PushButton » sans argument à destination d’un groupe que l’on va nommer « DoorBell». Pour cela remplaçons l’envoi du message au package PushBullet par la ligne :
1 | constellation.sendMessage("Group", "DoorBell", "PushButton", "{}"); |
Ainsi n’importe quel système connecté dans votre Constellation, que ce soit un package .NET, Python, une page JavaScript, un script Powershell, une autre puce ESP ou Arduino, un Gadgeteer, (etc, etc…), peut s’abonner à ce groupe et recevoir le message « PushButton » pour savoir si quelqu’un sonne chez vous !
Envoie de la notification PushBullet depuis un code C# connecté à la sonnette
Créons alors un package Constellation en C# avec le SDK Constellation pour Visual Studio :
Ajoutons simplement une méthode « PushButton » décorée de l’attribut « MessageCallback » pour recevoir les messages de notre ESP (plus d’info ici). Il faudra également avoir abonné notre package au groupe « DoorBell » où l’ESP envoi son message PushButton. On peut le faire directement depuis la Console Constellation dans la configuration du package ou soit explicitement dans le code (plus d’info ici).
Pour reprendre le même fonctionnel, envoyons une notification PushBullet depuis notre package C# lorsque l’on sonne à la porte. En C# il suffit de créer un « proxy dynamique » et d’envoyer le message « SendPush » comme si vous invoquez une méthode C# du même nom :
1 2 3 4 5 6 | [MessageCallback] public void PushButton() { // Quelqu'un sonne à la porte ! PackageHost.CreateMessageProxy("PushBullet").SendPush(new { Title = "Sonnette", Message = "On sonne à la porte" }); } |
Il suffit maintenant de déployer notre package sur une sentinelle de votre Constellation directement depuis Visual Studio.
Ce qui est intéressant ici, et que comme vous le constatez avec seulement 2 lignes de code C#, on a une méthode .NET qui sera invoquée par notre ESP8266 quand quelqu’un sonne et qui lui même invoquera le MC “PushBullet”.
On a donc le même résultat à savoir une notification sur PushBullet quand on sonne, mais tout la logique est dans le code C# facilement éditable ! Si maintenant vous devez changer le scénario, il vous suffira de mettre à jour votre code C# et de redéployer votre package modifié dans votre Constellation toujours depuis votre IDE Visual Studio sans avoir à sortir votre tournevis !
Ici j’ai réalisé le “cerveau” en C#/.NET mais j’aurais pu aussi bien l’écrire en Python avec l’API Python ou bien en Javascript sur un Node-JS. On aurait pu aussi utiliser votre propre technologie via l’API HTTP Rest.
Notification sur la TV avec Kodi, via une voix de synthèse (TTS) sur le multi-room ou encore avec des appels lumineux sur vos lampes Hue ou autres !
Bien entendu on pourrait aller plus loin qu’envoyer une simple notification sur le smartphone comme par exemple baisser le son de l’ampli ou de la TV, allumer la lumière de l’entrée, démarrer le flux vidéo de la caméra à l’entrée, afficher une notification sur la TV si l’utilisateur regarde un film.
Pour cela, il suffit de se servir dans le MessageCallbacks Explorer et de générer le code !
Faire clignoter les lampes Hue du salon
Par exemple, j’ai dans mon salon des lampes connectées Hue et le package Hue configuré dans ma Constellation. Je découvre donc un MC nommé “ShowAlert” permettant de faire clignoter des lampes d’une certaine couleur pendant un certain temps :
Avec le générateur de code, je sélectionne le langage “C#” et j’obtiens différentes façon d’invoquer le MC :
Ainsi, dès que l’on sonne, je vais faire clignoter certaines lampes de la maison en vert pendant 2 secondes, tout çà avec la simple ligne :
1 | PackageHost.CreateMessageProxy("Hue").ShowAlert(1, 0, 255, 0, 2000); |
Notification vocale avec S-Sound
Dans le même registre, mon système audio multi-room nommé S-Sound et présenté ici me mets à disposition un MC “Speech” permettant d’annoncer oralement un texte (TTS). Il y a des instances de ce package S-Sound un peu partout (Cuisine, Salon, Salle de bain, mon bureau, l’entrée, etc..).
Ainsi depuis mon code C# qui réagit lorsque l’on sonne, je pourrais simplement diffuser un message message vocale par la ligne :
1 | PackageHost.CreateMessageProxy("SSound-Cuisine").Speech("On sonne à la porte"); |
Comme tous les packages S-Sound sont ajoutés implicitement dans le groupe “SSound”, je peux aussi diffuser ce message vocale dans toutes les pièces de la maison par la ligne :
1 | PackageHost.CreateMessageProxy(MessageScope.ScopeType.Group, "SSound").Speech("On sonne à la porte"); |
Notification sur l’écran Kodi
En clair vous avez maintenant compris le principe : découvrir les MC disponible dans une Constellation pour exploiter leurs capacités en quelques lignes !
Je dispose chez moi de media-centers sous Kodi (ex. XBMC) sur les différents écrans de la maison. Le package Kodi pour Constellation expose un MC “ShowNotification” permettant d’afficher un message à l’écran.
De ce fait, il devient très simple d’afficher également un message sur l’écran de la télévision lorsque quelqu’un sonne :
1 2 3 4 5 | PackageHost.CreateMessageProxy("Xbmc").ShowNotification("TV Salon", new { Title = "Sonnette", Message = "On sonne à la porte" }); |
Il y a même un MC “PlayPause” où vous pourrez mettre en pause votre film automatiquement dès lors que l’on sonne chez vous ! Pratique quand les pizzas arrivent en plein milieu de votre fim
Et sinon : utiliser la sonnette comme système de notification ?
On peut aussi exposer des méthodes de notre ESP8266. Par exemple on pourrait ajouter un MessageCallback “StrikeBell” avec en paramètre le temps pendant lequel faire sonner le carillon. Et hop, avec une lambda C++ et la librairie Constellation votre méthode Arduino sera accessible pour tout le monde !
Pour ce faire, dans l’initialisation de l’ESP, déclarons notre MC avec le code suivant :
1 2 3 4 5 6 | // StrikeBell MessageCallback constellation.registerMessageCallback("StrikeBell", MessageCallbackDescriptor().setDescription("Strike the bell").addParameter<short>("delay"), [](JsonObject& json) { strikeBell(json["Data"].as<short>()); }); |
Si l’on reprend notre package C#, il suffira d’envoyer le message « StrikeBell » au package « DoorBell » avec la ligne suivante :
1 | PackageHost.CreateMessageProxy("DoorBell").StrikeBell(); |
Encore une fois, n’importe quel système connecté à Constellation peu importe le langage ou la technologie de développement, va pouvoir envoyer un message à notre ESP et déclencher le carillon à la demande !
Et bien entendu, cette méthode de votre Arduino sera déclarée et visible dans toute la Constellation :
Facile non ?
Notifier l’utilisateur intelligemment “où qu’il soit, quoi qu’il fasse”
Revenons-en au titre de notre sous-chapitre : “Notifier l’utilisateur où qu’il soit, quoi qu’il fasse”.
Jusqu’à présent nous avons exploiter l’un des grands principes de Constellation : les MessageCallbacks, c’est à dire la capacité d’exposer et référencer dans Constellation des fonctions/méthodes de nos applications/services/objets quelque soit le langage utilisé.
L’autre grand concept est le StateObject. Je cite :
Les StateObjects sont des objets de données produits et publiés par des packages qu’ils soient “réels” ou “virtuels” d’une Constellation. Ils représentent des variables de type simple (numérique, chaîne de caractère, booléen, etc..) ou de type complexe (objet formaté en JSON). Les StateObjects sont tous stockés sur le serveur Constellation et peuvent être interrogés par n’importe quels packages ou consommateurs de la Constellation (sauf si des autorisations restreignent l’accès).
En d’autre terme chaque package publie des variables qu’on appelle des StateObject et qu’on peut inclure dans notre code quelque soit le langage et cela en temps réel !
Fin de 2014 je vous présentais l’intégration de mon système d’alarme Paradox dans Constellation, où chaque zone est représentée dans Constellation par un StateObject.
Avec l’API .NET pour ne prendre que cet exemple, il suffit d’ajouter une propriété avec l’attribut “StateObjectLink” pour lier la dite propriété (au sens variable de mon code) à un StateObject (plus d’info ici). Par exemple :
1 2 | [StateObjectLink("Paradox", "ZoneInfo9")] public StateObjectNotifier SalonSensor { get; set; } |
Ainsi dans mon code, ici C#, j’ai dans la propriété “SalonSensor” les données du capteur de mouvement du salon en temps réel dans mon code !
Comme les MessageCallbacks, je peux utiliser la Console Constellation pour découvrir et visualiser en temps réel les StateObjects produits par l’ensemble des packages de ma Constellation.
Par exemple, l’ensemble des StateObjects produits par mon système d’alarme :
Avec par exemple, le détail de la zone “Salon” :
Ainsi on peut facilement exploiter et réagir par rapport aux évènements de l’environnement. Par exemple le code suivant :
1 2 3 4 5 6 7 | this.SalonSensor.ValueChanged += (s, e) => { if ((bool)this.SalonSensor.DynamicValue.IsOpen) { // Lors d'un mouvement dans le salon } }; |
Ici on peut facilement réagir dès lors qu’il y a un mouvement dans le salon, dans mon cas depuis un code C#, mais on peut faire la même chose avec du Python, Arduino, etc. tant qu’on est connecté à Constellation.
On peut donc “consulter” l’état d’un objet ou système dans une Constellation facilement et réagir à tout changement en temps réel !
Dans notre cas, voici quelques exemples de ce qu’il est possible de faire :
Notifier sur le(s) bon(s) media-center(s)
L’état des différents Kodi/XBMC sont publiés par le package XBMC. Par exemple, l’état actuel du média-center du salon :
Il est déconnecté, pas besoin donc d’envoyer une notification sur ce device et même si il était connecté (propriété IsConnected) faut-il encore qu’il y ait un media en cours (propriété PlayerState pour l’état de la lecture et/ou PlayerItem pour savoir ce qu’il se joue) !
On peut par exemple considérer qu’un média de type “musique” ne veut pas forcement dire que l’utilisateur regarde l’écran, c’est même peu probable ! En revanche, avec un media de type “Serie” ou “Film” on est a peu près sur d’avoir quelqu’un devant !
On viendrait donc dans le code déclarer une propriété de type collection (car on a potentiellement plusieurs XBMC dans la maison) liée aux différents StateObjects du package “Xbmc” :
1 2 | [StateObjectLink(Package = "Xbmc")] public StateObjectCollectionNotifier XBMCs { get; set; } |
On pourrait donc écrire quelque chose comme :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | // Pour tous les media-centers XBMC foreach (var xbmc in this.XBMCs) { // Si le XBMC est connecté et en cours de lecteur (et que le media n'est pas une musique) if (xbmc.DynamicValue.IsConnected && xbmc.DynamicValue.PlayerState != null && xbmc.DynamicValue.PlayerItem.type != "song") { // Log PackageHost.WriteInfo($"Le media-center {xbmc.DynamicValue.Name} est en cours de lecture d'un media video, on push une notification !"); // Show Notification sur le XBMC PackageHost.CreateMessageProxy("Xbmc").ShowNotification(xbmc.DynamicValue.Name, new NotificationRequest() { Title = "On sonne !", Message = "On vient de sonner à la porte" }); } } |
Ainsi on viendrait notifier l’utilisateur sur la (ou les) TV sur laquelle il regarde un média vidéo et cela très facilement grace aux API Constellation et aux notions de StateObjects et MessageCallbacks !
Notifier sur le système vocal de la salle de bain si un utilisateur est présent
Comme expliqué ci-dessus, mon système audio S-Sound me permet entre d’autre de diffuser des messages vocaux via du TTS (Text to Speech). Pratique, on peut par exemple prévenir oralement que quelqu’un sonne mais faut-il encore qu’il y ait quelqu’un dans la pièce en question où le message sonore sera diffusé !
Prenons l’exemple de la salle de bain, je prends ma douche et je voudrais savoir si quelqu’un sonne à porte ! Pour savoir si un utilisateur est dans sa douche je pourrais me servir du StateObject représentant la consommation d’eau :
Tout le scénario a été présenté dans mon post sur ma solution S-Energy mais pour résumer si il y a une consommation constante pendant un certain temps, je peux en déduire qu’un utilisateur est dans sa douche (ou son bain) et donc faire le TTS dans cette pièce.
Dans mon cas, comme la salle de bain est assez sombre, l’éclairage est quasi-systématiquement allumé quand quelqu’un est dans cette pièce (qu’il se douche ou non d’ailleurs).
Sachant que l’éclairage de la salle de bain est connecté en Z-Wave via un micromodule Fibaro FGD à une box Vera, elle même connectée à Constellation, j’ai un StateObject représentant cet éclairage :
Ainsi si quelqu’un sonne, je peux diffuser le message vocale dans cette pièce seulement si l’éclairage est allumé, soit deux lignes de code :
1 2 3 4 5 6 | // Si la lumière de la Salle de bain est ouverte if (this.EclairagesSdB.DynamicValue.Status) { // TTS dans la Salle de bain PackageHost.CreateMessageProxy("SSound-SalleDeBain").Speech("On sonne à la porte"); } |
Bien entendu, pour inclure l’état de l’éclairage de la salle de bain dans mon code C# j’ai déclaré la propriété suivante :
1 2 | [StateObjectLink("Vera", "Eclairages SdB")] public StateObjectNotifier EclairagesSdB { get; set; } |
C’est aussi facile que cela
Notifier sur le lampe Hue si l’utilisateur est dans le salon
Je vous parlais de mon infrastructure réseau basée sur des équipements Mikrotik. L’article ne l’évoque pas, mais j’ai chez moi un réseau de bornes Wifi de type wAP AC interconnectées sur le routeur central via CAPSMAN.
L’intérêt est que cet équipement est qu’il est connecté dans Constellation via le package Mikrotik qui produit différents StateObjects sur l’état de mon routeur, les baux DHCP, les interfaces réseau du routeur, les adresses IP, etc… et aussi sur la liste des clients Wifi connectés !
Et pour chaque client j’ai connaissance de la borne sur laquelle il est connecté. Je peux donc en quelque sorte, et de manière grossière, géolocaliser mes utilisateurs dans la maison. Pour ma part c’est assez précis car je porte une montre connectée qui se connecte sur le Wifi.
Ainsi si un de nos smartphones ou bien ma montre sont connectés sur la borne WAP01 (celle du salon) ou la WAP02 (celle de la salle à manger) alors que quelqu’un sonne, je déclenche les alertes lumineuses sur les Hue.
Notifier l’utilisateur dans le jardin
Toujours le même principe : on suit les StateObjects pour comprendre l’environnement.
Ici j’ai deux StateObjects remontés par mon système d’alarme qui représente la porte côté salle à manger et côté buanderie, les deux portes d’accès vers mon jardin. Si l’une d’entre elles est ouverte c’est qu’il y a probabilité d’avoir un utilisateur dans le jardin.
On peut aussi, comme ci-dessus, introspecter le StateObject des clients Wifi dans la mesure où la borne WAP06 est le point d’accès du jardin.
Autrement dit si une des deux portes est ouverte avec un smartphone connecté sur la borne WAP06, on peut déclencher un appel lumineux avec les éclairages LED du jardin piloter par Z-Wave (device Z-Wave également connecté à Constellation vous l’aurez compris).
Notification dans la maison, seulement si on est là !
Jusqu’à présent on conditionne toutes nos notifications en fonction de différents StateObjects et il y en a un que j’ai oublié de mentionner, surement le plus important : l’état de l’alarme que je peux inclure dans mon code C# par la ligne :
1 2 | [StateObjectLink("Paradox", "AreaInfo1")] public StateObjectNotifier AreaStatus { get; set; } |
Ici la propriété “AreaStatus” dans mon code C# sera liée au StateObject “AreaInfo1” du package Paradox, c’est à dire à l’état du secteur principal de mon alarme qui ressemble à cela :
On y trouve deux propriétés très importantes : “IsFullArmed” et “IsStayArmed” permettant de savoir si l’alarme est complètement ou partiellement armée. Ainsi toute les notifications listées ci-dessus ne doivent être lancées que si l’alarme n’est pas armée, autrement c’est soit qu’on dort, soit que nous sommes absent du domicile, inutile alors de chercher à faire du TTS, clignoter des éclairages, etc… !
1 2 3 4 5 6 7 8 | if (this.AreaStatus.DynamicValue.IsFullArmed == false && this.AreaStatus.DynamicValue.IsStayArmed == false) { // Alarme désarmée, on peut lancer des notifications sur les équipements de la maison } else { // Soit on dort, soit on est absent ! Ne rien faire } |
Intégration de la caméra extérieure
Continuons notre projet : jusqu’à présent lorsqu’on sonne on peut venir notifier l’utilisateur selon différentes modalités en fonction d’un tas de condition.
On peut aller plus loin en affichant la personne qui vient de sonner à la manière d’un simple visiophone.
Pour cela j’ai différentes cameras analogiques (connectées à un DVR-IP) et numériques (sur IP) agrégées sur l’excellent ZoneMinder.
Chose intéressante, il existe depuis la version 1.29 de ZoneMinder, une API que vient exploiter le package ZoneMinder pour remonter l’état de chaque camera dans des StateObjects Constellation et aussi envoyer des messages dans des groupes Constellation en cas d’alarme. Le package expose aussi des MessageCallbacks permettant de déclencher / annuler des alarmes ou même changer la fonction d’une caméra.
Ainsi dans mes StateObjects j’aurais à ma disposition l’ensemble des informations pour chaque caméra dont l’URI du flux de la vidéo avec les bons jeton de sécurité :
Je peux donc dans mon code C#, ajouter deux propriétés : une liée au StateObject du système ZoneMinder (qui me permettra de récupérer l’URI de base) et l’autre pour le StateObject de la caméra nommée Rue :
1 2 3 4 5 | [StateObjectLink("ZoneMinder", "Rue")] public StateObjectNotifier Camera { get; set; } [StateObjectLink("ZoneMinder", "Host")] public StateObjectNotifier Host { get; set; } |
Ainsi dans mon code, l’URL pour récupérer le snapshot de la caméra actuel est simplement la concaténation de l’URI de base de ZoneMinder avec le “path” de la camera sur lequel j’ajoute le paramètre “mode=single” pour obtenir un JPG (snapshot) :
1 | string snapshotUri = this.Host.DynamicValue.URI + this.Camera.DynamicValue.StreamPath + "&mode=single"; |
Cela tombe bien car sur les MessageCallbacks exposés par le package PushBullet, il y a une méthode “PushFile” permettant d’envoyer un fichier, donc des images :
De ce fait, mon code C# pour envoyer la notification PushBullet deviendra :
1 | PackageHost.CreateMessageProxy("PushBullet").PushFile(snapshotUri, "On sonne !"); |
Et hop, lorsque l’on sonne notre ESP-01 envoie un message au groupe “DoorBell”, pour lequel notre code C# invoquera un tas d’action, dont faire clignoter des lampes Hue si des utilisateurs sont dans le salon, afficher des messages sur les TV si un media vidéo est en cours, etc.. mais aussi envoyer la capture d’image de la camera de la rue à tous nos devices (PC, Android, iPhone, etc..) :
La notification ainsi que l’image sont même synchronisées sur ma montre Samsung Gear :
Génial non ?
Intégration de la sonnette sur le miroir de l’entrée
Vous connaissez surement mon miroir connecté nommé “The Mirror” est présenté à la Geek Is In Da House en février 2014 lors des Microsoft Techdays 2014.
Je l’avais d’ailleurs retravaillé à l’été 2014 avec un “compute” externalisé dans un coffret installé dans le garage. L’interface a bien changé depuis, plus sobre avec juste les informations nécessaires! Il s’agit d’une application WPF automatiquement déployée sur la Sentinelle Constellation du miroir grâce au concept d’orchestration de Constellation.
Comme je l’expliquais dans cet article, le miroir est “réveillé” dès lorsqu’il y a du mouvement dans l’entrée et mis en veille après 3 minutes d’inactivé.
L’activé dans l’entrée est connue grâce au StateObject représentant le capteur de mouvement de l’entrée et le réveil du miroir est possible avec paquet magique (Wake on Lan) envoyé grâce au package “NetworkTools” qui expose un MessageCallback “WakeUp” !
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | [StateObjectLink("Paradox", "ZoneInfo12")] public StateObjectNotifier MouvementEntree { get; set; } public override void OnStart() { this.MouvementEntree.ValueChanged += (s, e) => { // Si le capteur de l'entrée est "ouvert" if ((bool)e.NewState.DynamicValue.IsOpen) { // Envoyer un ordre de Wake up PackageHost.CreateMessageProxy("NetworkTools").WakeUp("44:8a:5b:a3:15:db"); }; }; } |
Ainsi le miroir est constamment allumé dès que nous sommes dans l’entrée mais se met en veille dès qu’il n’y a plus personne !
L’interface WPF affiche différents StateObjects comme le temps de trajet pour se rendre au travail (package GoogleTraffic), la météo dans l’heure et dans la journée (package ForecastIO), l’état de l’alarme (package Paradox), l’agenda de la journée (package Exchange), la fête du jour (package DayInfo), etc…
Dans notre cas on a découvert ci-dessus que les caméras agrégées dans ZoneMinder étaient représentées dans des StateObjects sur Constellation. Il serait donc possible d’afficher le flux de la vidéo en direct sur le miroir dès lors que quelqu’un sonne !
L’interface du miroir étant réalisée en WPF, je vais commencer par ajouter un composant “image” dans ma vue XAML :
1 | <Image Grid.Column="0" Grid.Row="1" Grid.ColumnSpan="3" HorizontalAlignment="Center" Name="CameraImage" Width="640" Height="480" Visibility="Hidden" /> |
Par défaut “cette image” est cachée. Pour décoder le flux MJPEG depuis mon application WPF je vais utiliser la librairie MJPEG-Decoder.
Dans le code C# du miroir je vais ajouter le StateObject du système ZoneMinder ainsi que les StateObjects de TOUTES les cameras (StateObjectCollection sur les StateObjects de type” ZoneMinder.Monitor”) :
1 2 3 4 5 | [StateObjectLink("ZoneMinder", "Host")] public StateObjectNotifier ZoneMinder { get; set; } [StateObjectLink(Package = "ZoneMinder", Type = "ZoneMinder.Monitor")] public StateObjectCollectionNotifier Cameras { get; set; } |
Ainsi j’ai donc dans mon code toutes les informations sur toutes mes caméras !
Au chargement de l’interface j’initialise le décodeur MJPEG pour affecter chaque frame décodée sur l’image que nous avons placé sur la vue XAML :
1 2 3 4 5 6 | // Init MJPEG decoder this.mjpeg = new MjpegDecoder(); this.mjpeg.FrameReady += (s, frame) => { this.CameraImage.Source = frame.BitmapImage; }; |
Il ne reste plus qu’à prendre l’URI du stream d’une des cameras et de l’envoyer dans le décodeur MJPEG. Pour cela nous allons exposer un MessageCallback pour que l’n’importe quel système connecté dans Constellation puisse choisir la camera à afficher sur l’écran !
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | [MessageCallback] public void ShowCamera(string cameraName, bool visible = true) { // On affiche l'image sur l'interface si il faut afficher une camera (visible == true) this.Dispatcher.BeginInvoke(new Action(() => this.CameraImage.Visibility = visible ? Visibility.Visible : Visibility.Hidden)); // Si on affiche une camera if (visible) { // Si lecture en cours ... if (this.mjpeg != null) { // On stop le decodeur MJPEG this.mjpeg.StopStream(); } // On récupere le StateObject ZoneMinder de la camera à afficher var camera = this.Cameras[name: cameraName].FirstOrDefault(); if (camera == null) { // Si la camera est inconnu, on sort ! PackageHost.WriteError($"Invalid camera name : {cameraName}"); return; } // On démarre le décodeur MJPEG sur l'URI de la camera connue dans les StateObjects this.mjpeg.ParseStream(new Uri(this.ZoneMinder.DynamicValue.URI + camera.DynamicValue.StreamPath)); } else // si on cache la camera { // On stop le decodeur MJPEG this.mjpeg.StopStream(); } } |
Pour ma part j’ai une version un peu plus complète avec la notion de “timeout” qu’on spécifie dans la signature de notre MessageCallback, par défaut égal à 2 minutes et 30 secondes (150 secondes) :
1 2 | [MessageCallback] public void ShowCamera(string cameraName, bool visible = true, int timeout = 150000) |
Cela permet d’arrêter le flux de la vidéo automatiquement après ce delai !
Pour la faire courte j’ai un tache asynchrone qui démarre avec le décodeur MJPEG et qui attend (Delay) l’expiration du timeout afin de fermer le flux de la camera (on rappelle juste notre MC avec le paramètre visible à false). Il y a également un CancellationToken pour annuler cette tache si notre MC a été rappelé entre temps pour switcher de camera ou cacher la camera !
1 2 3 4 5 6 7 8 9 | // Hide camera after timeout this.cancelClosingWebcam = new CancellationTokenSource(); Task.Delay(timeout, this.cancelClosingWebcam.Token).ContinueWith(task => { if (!task.IsCanceled && this.CameraImage.Visibility == Visibility.Visible) { this.ShowCamera(cameraName, false); } }); |
J’ai donc maintenant un MessageCallback “ShowCamera” sur mon package “TheMirror” qui me permet d’afficher le flux vidéo d’une camera sur l’interface du miroir avec une notion de timeout :
Ainsi dans mon programme C# qui gère le scénario de la sonnette, en plus de lancer un tas de notification sur PushBullet, Xbmc/Kodi, les lampes Hue & co, on peut invoquer notre MessageCallback ci-dessus pour afficher le flux de la camera extérieure nommée “Rue” :
1 | PackageHost.CreateMessageProxy("TheMirror.UI").ShowCamera("Rue", true); |
Dans la vrai vie, le code est un peu plus complet car je gère également l’état du miroir ! En effet, si le miroir est réveillé le MC est instantanément invoqué et donc le flux de la camera s’affiche sur notre miroir. Mais souvenez-vous que si il n’y a pas de mouvement pendant un certain temps dans mon entrée, le “cerveau de la maison” met en veille le miroir.
Ainsi quand on sonne, il faut d’abord savoir si le miroir est connecté ou non. Si il l’est on invoque le MessageCallback comme ci-dessus, sinon il faut d’abord le réveiller et attendre qu’il soit connecté avant d’invoquer le MessageCallback.
1 2 3 4 5 6 7 8 9 10 11 | if (miroirConnecte == false) { // Miroir non connecté, on le réveille this.openWebcamOnMirrorConnected = true; PackageHost.CreateMessageProxy("NetworkTools").WakeUp("44:8a:5b:a3:15:db"); } else { // Sinon on invoque le MC "ShowCamera" PackageHost.CreateMessageProxy("TheMirror.UI").ShowCamera("Rue", true); } |
L’état du miroir est connu par la variable booléenne “miroirConnecte” qu’on synchronise en s’abonnant à l’évènement “SentinelUpdate”. Ainsi lorsque la sentinelle du miroir (nommée PC-MIRROR_UI) se connecte (ou déconnecte) on met simplement à jour notre variable :
1 2 3 4 5 6 7 | PackageHost.ControlManager.SentinelUpdated += (s, e) => { if (e.Sentinel.Description.SentinelName == "PC-MIRROR_UI") { miroirConnecte = e.Sentinel.IsConnected; } } |
Lorsque l’on sonne alors que le miroir est en veille, on le réveille via le MC “WakeUp” sur le package “NetworkTools” et on affecte la valeur “true” à la variable locale “openWebcamOnMirrorConnected”. Il ne reste plus qu’à attendre que le package du miroir (c’est à dire l’application WPF) se connecte sur Constellation pour invoquer le MC “ShowCamera” :
1 2 3 4 5 6 7 8 9 10 | PackageHost.ControlManager.PackageStateUpdated += (s, e) => { // Si on doit afficher la camera et que le package TheMirror vient de se connecter et est bien démarré if (this.openWebcamOnMirrorConnected && e.PackageName == "TheMirror.UI" && e.IsConnected && e.State == Constellation.PackageState.Started) { this.openWebcamOnMirrorConnected = false; // Sinon on invoque le MC "ShowCamera" PackageHost.CreateMessageProxy("TheMirror.UI").ShowCamera("Rue", true); } } |
Et voilà le tour est joué, le miroir se réveillera si besoin et affichera le flux vidéo de la camera extérieure dès lors qu’on sonne à la porte ! Cool!
Mais allons un (encore) cran plus loin
On va automatiquement arrêter le flux vidéo sur le miroir dès que l’on ouvre la porte pour ne pas surprendre notre invité Pour cela rien de plus simple !
D’abord on ajoute notre StateObject représentant la porte d’entrée dans le code C# du miroir :
1 2 | [StateObjectLink("Paradox", "ZoneInfo13")] public StateObjectNotifier PorteEntree { get; set; } |
Ensuite il suffit juste d’ajouter un handler sur l’évènement “ValueChanged”, c’est à dire à chaque mise à jour de notre StateObject. Sur les StateObjects des zones de l’alarme Paradox, on a une propriété “IsOpen” pour connaitre l’état de la zone.
Ainsi il suffit juste de s’abonner et de vérifier que la zone soit ouverte (= la porte est ouverte) afin de fermer le flux de la camera en invoquant notre méthode “ShowCamera” avec le paramètre “visible = false”.
1 2 3 4 5 6 7 | this.PorteEntree.ValueChanged += (s, e) => { if (e.NewState.DynamicValue.IsOpen) { this.ShowCamera("Rue", false); } }; |
On obtient ainsi une intégration complète pour ne pas dire parfaite entre le miroir, la sonnette et les cameras ZoneMinder
Protéger le sommeil de votre enfant : la sonnette muette mais connectée !
Jusqu’à présent nous avons une sonnette connectée à Constellation avec laquelle il est possible d’invoquer le carillon à la demande et où chaque appuie sur le bouton poussoir de la sonnette déclenche un message dans un groupe à partir duquel les participants de la Constellation peuvent interagir pour envoyer des notifications sur votre smartphone par exemple, allumer la lumière, prendre une photo de l’entrée, réveiller le miroir, etc…!
Maintenant et pour revenir au cœur du problème à savoir « protéger le sommeil » de votre enfant, nous allons simplement « désactiver » l’activation du carillon lorsque l’on sonne : en clair un mode « muet » !
Revenons-en donc à notre code Arduino/C++ de notre ESP8266 et ajoutons simplement le code suivant :
1 2 3 4 5 6 7 8 | // SetMute MessageCallback constellation.registerMessageCallback("SetMute", MessageCallbackDescriptor().setDescription("Set the mute mode").addParameter<bool>("mute"), [](JsonObject& json) { mute = json["Data"].as<boolean>(); constellation.pushStateObject("IsMute", mute); constellation.writeInfo("Setting mode to: %s", (mute ? "Mute" : "Unmute")); }); |
En fait, on ajoute un MessageCallback sur notre ESP8266 nommé “SetMute” et qui prend en paramètre un booléen.
Lorsque l’on invoque ce MC, on vient juste mettre à jour la variable globale “mute” et on publie également l’état actuel dans un StateObject “IsMute” permettant à tout le monde de connaitre l’état courant de la sonnette.
De ce fait on peut par exemple ajouter un bouton sur mon interface S-Panel (une application Cordova exploitant la librairie AngularJS pour Constellation) me permettant de contrôler le mode muet de ma sonnette depuis un smartphone, une tablette ou un ordinateur :
Comme tous le MessageCallbacks sont référencés sur votre Constellation, on retrouvera notre MC “SetMute” dans le MessageCallbacks Explorer :
Comme mon dashboard domotique est développé en AngularJS, il me suffit de cliquer sur le générateur de code et de selectionner le langage “AngularJS” :
Ainsi sans trop d’effort, pour définir le « mode muet » de l’ESP depuis ma code Javascript/Angular, il suffira d’une ligne :
1 | constellation.sendMessage({ Scope: 'Package', Args: [ 'DoorBell' ] }, 'SetMute', isMute); |
Toujours depuis mon code Javascript, je vais m’abonner à tous les StateObjects du package “DoorBell” par la ligne :
1 | constellation.requestSubscribeStateObjects("*", "DoorBell", "*", "*"); |
Pour le reste, il ne s’agit que de faire un peu d’HTML :
1 2 3 4 5 6 7 8 9 | <a ng-click="constellation.sendMessage({ Scope: 'Package', Args: [ 'DoorBell' ] }, 'SetMute', !DoorBell.IsMute.Value)"> <div class="cont"> <div class="info-user"> <li aria-hidden="true" class="fa fa-{{ DoorBell.IsMute.Value ? 'bell-slash' : 'bell' }}"></li> </div> <bold ng-hide="DoorBell.IsMute.Value">ON</bold> <bold ng-show="DoorBell.IsMute.Value"><bad>MUTE</bad></bold> </div> </a> |
Et voilà notre dashboard S-Panel développé en Javascript capable de piloter le mode muet de notre sonnette :
Côté ESP8266, faut-il encore exploiter la variable “mute” ! Lorsque l’on va sonner (après debounce), on vient simplement mettre un log dans Constellation, on envoie ensuite le message “PushButton” sur le groupe “DoorBell” pour que l’ensemble des scénarios décrit ci-dessus se déclenche et on va seulement invoquer la méthode “strikeBell” responsable de faire claquer le relais (donc de déclencher le carillon) si et seulement si la variable “mute” n’est pas vrai !
Autrement dit en “mute” la sonnette fait comme d’habitude à l’exception du déclenchement du carillon !
1 2 3 4 5 6 7 8 9 10 | void onPressButton() { // Log constellation.writeInfo("Button pressed!"); // Send message constellation.sendMessage(Group, "DoorBell", "PushButton", "{}"); // Strike Bell is not mute if(!mute) { strikeBell(); } } |
Ainsi, j’ai maintenant la possibilité de couper à la demande le carillon tout en conservant le fonctionnel lorsque quelqu’un sonne, comme recevoir une notification sur mon smartphone.
Dans mon code final, le nom du groupe, ici “DoorBell”, peut être modifier dans les settings Constellation pour plus de flexibilité. Pour plus d’information à propos des settings, rendez-vous ici.
Automatisation jusqu’au bout !
Pour aller encore plus loin, on va déclencher le mode muet de manière automatique lors que mon fils dort !
Cette information je peux la connaitre grâce à l’état de son volet! En effet, si mon fils fait sa sieste ou sa nuit son volet est forcément fermé, soit complètement ou soit avec quelques lames entrouvertes, le seuil fixé étant à un niveau d’ouverture inférieur à 15%.
Le volet électrique étant piloté par un micromodule Z-Wave appairé à une Vera elle-même connectée à Constellation, je connais l’état de chaque volet (et des autres devices Z-Wave) grâce aux StateObjects.
Avec la Console Constellation, je peux utiliser l’explorateur de State Object pour introspecter en temps réel les StateObjects de ma Constellation.
Ici, le StateObject nommé « Volet Chambre 1 » de type « VeraNet.WindowCovering » contient différentes informations dont son état Ouvert/Fermé (Status) et son niveau d’ouverture (Level). A l’heure où j’écris ces lignes, son volet est ouvert à 61%.
Pour exploiter cette information dans notre package C#, ajoutons une propriété .NET que vous allons lier à ce StateObject en ajoutant l’attribut « StateObjectLink » de la façon suivante :
1 2 | [StateObjectLink("Vera", "Volet Chambre 1")] public StateObjectNotifier VoletChambre1 { get; set; } |
Dès lors votre propriété .NET est « synchronisée » en temps réel avec l’état du volet et il nous suffit d’une ligne de code C# pour définir le mode « muet » de la sonnette si le volet est ouvert à moins de 15% :
1 2 3 | this.VoletChambre1.ValueChanged += (s, e) => { PackageHost.CreateMessageProxy("DoorBell").SetMute(this.VoletChambre1.DynamicValue.Level < 15); }; |
Lorsque la propriété « VoletChambre1 » est mise à jour, c’est-à-dire lorsque le StateObject qui représente l’état du volet est mis à jour par le package Vera, on envoie le message « SetMute » au package « DoorBell » en passant en paramètre un booléen qui est à « vrai » si le niveau d’ouverture du volet est inférieur à 15%.
Et voilà comment en une ligne de code, le fait de fermer son volet désactive automatiquement le carillon de la sonnette et le réactive par lui-même dès que l’on rouvre le volet laissant ainsi mon fils dormir tranquillement
Le mot de la fin, enfin
On arrive au terme de notre article ! Comme vous avez pu le découvrir, l’idée de base était de connecter une sonnette dans Constellation.
Grace aux ESP8266, ces petits microprocesseurs surpuissants dotés d’une connexion WIfi et grâce à la plateforme Constellation, on a pu très facilement et rapidement intégrer notre sonnette dans la “maison connectée”.
Ainsi dès que quelqu’un sonne, l’évènement circule dans Constellation de sorte que n’importe quelle application, service ou objet puisse régir à cet évènement que vous soyez développeurs .NET, Python, JS, etc… De même notre sonnette expose également des méthodes, ces fameux MessageCallbacks pour pouvoir définir un mode “muet” ou même déclencher le carillon à la demande !
Partant de là, on a pu intégrer complètement la sonnette dans les différents systèmes de la maison en rajoutant quelques lignes par-ci par-la de manière transparente car tout est StateObject ou MessageCallback créant ainsi l’intelligence ambiante.
C’est ainsi que la sonnette communique implicitement avec les mediacenter Kodi, avec les lampes Hue, avec le miroir, les cameras, les smartphones, PC, etc… !
D’un point de vue usage j’ai pu très rapidement modéliser exactement ce dont j’avais besoin : être notifier “où que je sois et quoi que je fasse” lorsque quelqu’un sonne mais aussi et surtout éviter de réveiller mon fils lorsqu’il dort et tout cela de la façon la plus naturelle soit-il !
Constellation débride complètement les possibilités de ce qu’il est possible de faire en offrant un bac à sable où tout système peut facilement interagir avec les autres rendant possible une multitude d’usage.
Pour la petite histoire, cette “sonnette” était présente sur le stand Constellation lors des Microsoft Experiences aux côtés d’un tas de devices interconnectées ! J’ai donc était littéralement spammé sur ma montre des photos de vos visiteurs dont voici un petit extrait
Pour interconnecter vos applications, services et objets connectés, n’hésitez pas à vous rendre sur le portail développeur Constellation.
Trackback: S-DoorBell : connecter sa sonnette à Constellation avec un ESP8266 ou comment protéger le sommeil de son enfant, la sonnette propu... - La veille de sarakha63 - La Domotique de Sarakha63
Martres
Bonjour je vous soumets mon problème . Je possède un interphone vidéo capteur CCD couleur et j’aurai voulu capter les vidéo sur mon moniteur pour les transmettre à ma livebox afin de pouvoir les enregistrer sur mon PC . Si toutefois quelqu’un peut m’éguiller Merci
Trackback: Dossier spécial sur la maison intelligente et Constellation dans le numéro d’été du magazine Programmez! dans vos kiosques partout en France - Sebastien.warin.fr