Sommaire
Dans cet article nous allons découvrir comment contrôler l’ambiance lumineuse d’une pièce équipée d’ampoules connectées avec un simple interrupteur mural.
L’idée est à la fois de pouvoir allumer ou éteindre toutes les ampoules de la pièce à partir de l’interrupteur mais également de pouvoir sélectionner une ambiance lumineuse en fonction des circonstances, par exemple pour un salon : ambiance « réception », ambiance « soirée », ambiance « Ciné », ambiance « Feu de cheminée », etc…
Prérequis
- Un serveur Constellation
- Des lampes ou ampoules connectées, ici des Philips Hue
- Un interrupteur mural connecté, ici un interrupteur Legrand relié à un module Z-Wave Fibaro FGS-211
- Le SDK Constellation pour Visual Studio
Etape 1 : connecter un interrupteur mural
La première étape consiste donc à intégrer un interrupteur dans Constellation. Avec la polyvalence de la plateforme Constellation, il y a mille et une manière d’y parvenir.
Pour ma part, j’ai conservé les interrupteurs existants de la gamme Mosaic Legrand. Il s’agit pour être exacte d’un double bouton poussoir.
Pour le rendre connecté, j’ai ajouté un micro-module de la marque Fibaro spécialement conçu pour être intégré dans la boite d’encastrement juste derrière l’interrupteur.
Ce module Fibaro est un FGS-211 connecté en Z-Wave et disposant de deux relais en sortie pilotant des charges jusqu’à 1500W et de deux entrées. Dans mon cas, il n’y a aucune charge connectée sur ce module, il me sert juste de »capteur ».
Je rappelle aussi que les ampoules Philips Hue doivent être constamment alimentées en 220v de façon à être pilotable même après avoir fermé les lumières !
Le module Fibaro est simplement connecté sur le réseau électrique 220v pour son alimentation et aux deux boutons poussoir Legrand de la façon suivante :
Cela permettant d’avoir deux boutons connectés sur le même interrupteur : l’un servira pour allumer ou éteindre toutes les lumières du salon et l’autre permettra de changer la configuration lumineuse de la pièce.
Ce module Fibaro a été appairé sur mon contrôleur Z-Wave qui est une Vera Lite. Après avoir déployé le package Vera sur une des sentinelles de ma Constellation, on obtient différents StateObjects représentant l’état en temps réel de chaque device Z-Wave et des MessageCallbacks permettant de les piloter.
Les deux relais du FGS-221 sont considérés comme deux devices distincts de type « Switchs » (On ou Off). On a donc deux StateObjects dans Constellation pour représenter l’état de ces deux relais. Chacun de ces StateObjects contient la propriété « Status », un booléen indiquant si le relais est ouvert ou fermé.
On peut permuter l’état du relais informatiquement parlant par la Vera (ou par Constellation via le MessageCallback « SetSwitchState » du package Vera) ou directement en appuyant sur les boutons poussoirs.
Ainsi dès lors que l’utilisateur va appuyer sur l’un des boutons poussoirs, l’état du relais changera et donc le StateObject le représentant sera également mis à jour dans votre Constellation. On pourra donc s’abonner à ces deux StateObjects via l’API.NET, Python, Arduino ou autre pour réagir à ces changements d’état, par exemple pour allumer ou éteindre les ampoules Hue.
Etape 2 : connecter des lampes
Deuxième étape pour mener à bien notre projet : connecter des lampes dans Constellation. Il y a différentes solutions comme nous avons pu le découvrir dans cet autre tutoriel : solutions DIY, prises connectées en Wifi, RF, en Z-Wave, lampes ou ampoules connectées en Wifi, en ZeeBee, etc.. etc..
Dans mon cas, j’ai équipé les huit appliques de mon salon avec des ampoules Philips Hue.
Toutes les ampoules communiquent en ZeeBee à un pont Ethernet, nommé le bridge (à gauche de la photo ci-dessus). Grace au package Hue, vous disposez de différents MessageCallbacks pour contrôler chaque lampes Hue (état, intensité lumineuse, couleur, effet, etc..) et d’un StateObject par luminaire représentant son état en temps réel.
Etape 3 : synchroniser l’interrupteur avec les lampes
Passons au chose sérieuse, nous avons d’un côté deux StateObjects nous indiquant l’état des deux relais qu’on contrôle par les boutons poussoirs et de l’autre des MessageCallbacks nous permettant de contrôler les ampoules Hue du salon, reste juste à faire le lien !
Pour cela nous allons créer un package .NET en C# depuis Visual Studio.
Dans la classe principale (Program), nous allons ajouter deux StateObjectLinks, c’est à dire des propriétés dans notre code liées aux StateObjects représentant les états des interrupteurs :
1 2 3 4 5 |
[StateObjectLink("Vera", "Interrupteur Hue 1")] public StateObjectNotifier InterrupteurHue1 { get; set; } [StateObjectLink("Vera", "Interrupteur Hue 2")] public StateObjectNotifier InterrupteurHue2 { get; set; } |
Nous allons commencer par le bouton de gauche, c’est à dire l’interrupteur n°1 qui se chargera d’allumer ou d’éteindre toutes les ampoules du salon.
Pour cela nous allons attacher un « handler » qui réagira à la mise à jour du StateObject « Interrupteur Hue 1 ». Le handler commencera par vérifier que l’état à bien changé, c’est à dire que la propriété « Status » du « OldState » versus le « NewState » est bien différente (le StateObject peut être mis à jour par exemple dans le cas d’un « poll » Z-Wave à intervalle régulier sans pour autant que son Status ait changé !).
Ensuite on invoque simplement le MessageCallback « SetState » du package Hue. Le 1er argument est le n° de la lampe, 0 indiquant « toutes les lampes » et le 2ème argument est l’état (On ou Off) de la lampe. Ici on passera l’état du relais (propriété du Status).
1 2 3 4 5 6 7 |
this.InterrupteurHue1.ValueChanged += (s, e) => { if ((bool)e.OldState.DynamicValue.Status != (bool)e.NewState.DynamicValue.Status) { PackageHost.CreateMessageProxy("Hue").SetState(0, (bool)e.NewState.DynamicValue.Status); } }; |
Ainsi dès que vous appuyez sur le bouton poussoir de gauche, le relais change d’état donc le code ci-dessus est invoqué ce qui allumera ou éteindra toutes vos lampes Hue !
Et voilà comment en quelques lignes on peut synchroniser des choses ensembles ! Au final, on obtient un interrupteur connecté pilotant plusieurs ampoules connectées.
Une fois votre package testé et validé, vous pouvez le publier dans votre Constellation et le déployer sur une de vos sentinelles (voir le guide). Simple et efficace !
Etape 4 : contrôler les ambiances lumineuses
Ce que nous avons fait jusqu’à présent est relativement simple : on synchronise simplement l’état du relais Fibaro (piloté par l’interrupteur) à l’état (state On/Off) des lampes Hue.
Le MessageCallback « SetState » allume ou éteint des lampes Hue. Dans le cas d’un allumage, les lampes reprendront leurs dernières configurations en terme de couleur et d’intensité.
Il existe d’autre MC sur ce package comme le SetColor, SetBrightness, ou le Set qui combine les 3 en un en prenant en paramètre à la fois l’état, la couleur et l’intensité.
Nous allons donc perfectionner notre package en utilisant un setting au format JSON pour décrire nos différentes ambiances lumineuses. L’interrupteur de gauche ne se contentera plus de faire un simple SetState sur chaque lampe mais appliquera la configuration dite par défaut que nous pourrons à tout moment mettre à jour dans les settings depuis la Console.
L’interrupteur n°2 quant à lui, celui de droite, servira pour appliquer la configuration suivante de façon cyclique (arrivé à la dernière, on revient au début).
Commençons d’abord par définir nos configurations lumineuses dans un setting JSON.
Créer des « configurations lumineuses »
Pour cela je vous propose de créer une page Web pour générer le setting de configuration sur base de l’état actuelle de vos lampes.
En clair, avec l’application officielle Hue, réglez vos lampes pour créer l’ambiance lumineuse souhaitée et en temps réel notre page Web générera l’objet JSON représentant votre configuration.
Nous allons simplement créer un simple page HTML en y ajoutant le module Constellation / AngularJS comme vu ici.
Lorsque nous sommes connecté, on enregistre un StateObjectLink sur tous les StateObjects du type « Q42.HueApi.Light » du package Hue. Pour chaque lampe Hue, on stocke la valeur du StateObject dans une variable de scope nommée « lights » :
1 2 3 4 5 |
constellation.registerStateObjectLink("*", "Hue", "*", "Q42.HueApi.Light", function (stateObject) { $scope.$apply(function () { $scope.lights[stateObject.Name] = stateObject.Value; }); }); |
Ainsi l’état de chacune de nos lampes sera synchronisée en temps réel dans cette variable Javascript.
Maintenant dans le code HTML, générons une liste pour afficher le nom de chaque lampe, son ID, son état (on/off), sa couleur (Hue et Saturation) et son intensité (bri) avec un « ng-repeat » Angular :
1 2 3 |
<ul> <li ng-repeat="(name, value) in lights" title="{{value}}">{{name}} = #{{value.id}} On:{{value.state.on}} Hue:{{value.state.hue}} Sat:{{value.state.sat}} Bri:{{value.state.bri}}</li> </ul> |
C’est aussi simple que cela !
Maintenant ajoutons une méthode « ExportCurrentConfig » qu’on appellera dans notre StateObjectLink dès qu’un StateObject est mis à jour :
1 2 3 4 5 6 7 8 |
$scope.ExportCurrentConfig = function() { var config = { ConfigName: "MyConfig", Lights: []}; for(var name in $scope.lights) { var value = $scope.lights[name]; config.Lights.push({ id: value.id, state: value.state.on, hue: value.state.hue, sat:value.state.sat, bri:value.state.bri }); } $scope.strConfigs = JSON.stringify([ config ]).replace(/"/g, "'"); }; |
On crée un objet avec une propriété « ConfigName » pour nommer notre configuration et un tableau « Lights » qu’on remplit avec l’état connu de chaque lampe. Pour finir on « stringify » notre objet en JSON qu’on affichera ensuite dans un « textarea » sur la page :
Il ne reste plus qu’à générer différentes configurations notre « extracteur » pour la suite de notre tutoriel.
Le code complet de la page :
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 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml" ng-app="hue"> <head> <title>Hue Configuration</title> <script type="text/javascript" src="/Scripts/jquery-2.1.3.min.js"></script> <script type="text/javascript" src="/Scripts/angular.min.js"></script> <script type="text/javascript" src="/Scripts/jquery.signalR-2.2.0.min.js"></script> <script type="text/javascript" src="/Scripts/Constellation-1.8.1.js"></script> <script type="text/javascript" src="/Scripts/ngConstellation-1.8.1.js"></script> <script> var hue = angular.module('hue', ['ngConstellation']) .controller('HueController', ['$scope', 'constellationConsumer', function ($scope, constellation) { $scope.lights = {}; $scope.strConfigs = ""; constellation.initializeClient("http://xxxxxxx:8088/", "demo123", "Hue Configurator"); $scope.ExportCurrentConfig = function() { var config = { ConfigName: "MyConfig", Lights: []}; for(var name in $scope.lights) { var value = $scope.lights[name]; config.Lights.push({ id: value.id, state: value.state.on, hue: value.state.hue, sat:value.state.sat, bri:value.state.bri }); } $scope.strConfigs = JSON.stringify([ config ]).replace(/"/g, "'"); }; constellation.onConnectionStateChanged(function (change) { if (change.newState === $.signalR.connectionState.connected) { console.log("Connected"); constellation.registerStateObjectLink("*", "Hue", "*", "Q42.HueApi.Light", function (stateObject) { $scope.$apply(function () { $scope.lights[stateObject.Name] = stateObject.Value; $scope.ExportCurrentConfig(); }); }); } else if (change.newState === $.signalR.connectionState.disconnected) { constellation.connect(); } }); constellation.connect(); }]); </script> </head> <body> <ul> <li ng-repeat="(name, value) in lights" title="{{value}}">{{name}} = #{{value.id}} On:{{value.state.on}} Hue:{{value.state.hue}} Sat:{{value.state.sat}} Bri:{{value.state.bri}}</li> </ul> <hr/> <p>Current configuration :</p> <textarea rows="40" cols="50">{{strConfigs}}</textarea> </body> </html> |
Activer les configurations depuis interrupteur
Premièrement nous allons déclarer dans le manifeste de notre package (PackageInfo.xml) le setting « Hue.Configuration » par la ligne :
1 |
<Setting name="Hue.Configurations" type="JsonObject" isRequired="true" description="Configurations lumineuses" /> |
Le contenu de ce setting sera un tableau des différentes configurations générées par notre extracteur ci-dessus.
Pour ma part voici mes configurations à titre d’exemple :
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 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 |
[ { 'ConfigName':'Blanc chaud', 'DefaultConfig':true, 'Lights':[ { 'id':'1', 'state':true, 'hue':6479, 'sat':252, 'bri':254 }, { 'id':'2', 'state':true, 'hue':13907, 'sat':187, 'bri':179 }, { 'id':'3', 'state':true, 'hue':13907, 'sat':187, 'bri':254 }, { 'id':'4', 'state':true, 'hue':14101, 'sat':180, 'bri':141 }, { 'id':'5', 'state':true, 'hue':14101, 'sat':180, 'bri':254 }, { 'id':'6', 'state':true, 'hue':14101, 'sat':180, 'bri':161 }, { 'id':'7', 'state':true, 'hue':12778, 'sat':219, 'bri':120 }, { 'id':'8', 'state':true, 'hue':12778, 'sat':219, 'bri':254 } ] }, { 'ConfigName':'Film du soir', 'Lights':[ { 'id':'1', 'state':true, 'hue':7157, 'sat':243, 'bri':104 }, { 'id':'2', 'state':false, 'hue':13907, 'sat':187, 'bri':179 }, { 'id':'3', 'state':true, 'hue':13122, 'sat':211, 'bri':80 }, { 'id':'4', 'state':true, 'hue':12778, 'sat':219, 'bri':142 }, { 'id':'5', 'state':true, 'hue':13122, 'sat':211, 'bri':80 }, { 'id':'6', 'state':false, 'hue':14101, 'sat':180, 'bri':161 }, { 'id':'7', 'state':false, 'hue':13122, 'sat':211, 'bri':120 }, { 'id':'8', 'state':false, 'hue':4712, 'sat':241, 'bri':254 } ] }, { 'ConfigName':'Cheminée', 'Lights':[ { 'id':'2', 'state':false, 'hue':7980, 'sat':252, 'bri':79 }, { 'id':'8', 'state':true, 'hue':4712, 'sat':241, 'bri':254 }, { 'id':'5', 'state':true, 'hue':13122, 'sat':211, 'bri':91 }, { 'id':'4', 'state':false, 'hue':7862, 'sat':252, 'bri':53 }, { 'id':'3', 'state':true, 'hue':13122, 'sat':211, 'bri':91 }, { 'id':'6', 'state':true, 'hue':8774, 'sat':252, 'bri':56 }, { 'id':'7', 'state':true, 'hue':13122, 'sat':211, 'bri':120 }, { 'id':'1', 'state':true, 'hue':6196, 'sat':247, 'bri':104 } ] }, { 'ConfigName':'Tout éteind', 'OffConfig':true, 'Lights':[ { 'id':'1', 'state':false, 'hue':7157, 'sat':243, 'bri':104 }, { 'id':'2', 'state':false, 'hue':13907, 'sat':187, 'bri':179 }, { 'id':'3', 'state':false, 'hue':3584, 'sat':252, 'bri':254 }, { 'id':'4', 'state':false, 'hue':12778, 'sat':219, 'bri':142 }, { 'id':'5', 'state':false, 'hue':13122, 'sat':211, 'bri':80 }, { 'id':'6', 'state':false, 'hue':14101, 'sat':180, 'bri':161 }, { 'id':'7', 'state':false, 'hue':12778, 'sat':219, 'bri':120 }, { 'id':'8', 'state':false, 'hue':12778, 'sat':219, 'bri':254 } ] } ] |
Vous remarquerez que j’ai ajouté sur la première configuration la propriété « DefaultConfig = true » et « OffConfig =true » sur la dernière. On se servira de ces deux propriétés pour savoir quelles sont les configurations à appliquer en cas de « On » et de « Off » sur notre interrupteur n°1.
Le setting est de type « JsonObject », on aura donc un bel éditeur dans la Console Constellation pour le déclarer ou le modifier. Pour vos développements vous pouvez aussi utiliser le fichier App.config.
Pour revenir à notre code C#, nous allons tout d’abord déclarer les variables privées suivantes :
1 2 |
private int currentConfigurationId = 0, defaultConfigurationId = 0, offConfigurationId = 0; private List<dynamic> hueConfiguration = new List<dynamic>(); |
Dans la méthode démarrage (OnStart) on charge notre setting JSON dans la variable « hueConfiguration » avec la méthode « GetSettingAsJson » puis on récupère dans ce tableau l’index de la configuration « Default » et « Off » par la méthode .NET « FindIndex » :
1 2 3 |
hueConfiguration = new List<dynamic>(PackageHost.GetSettingAsJsonObject("Hue.Configurations")); defaultConfigurationId = this.hueConfiguration.FindIndex(c => c.DefaultConfig == true); offConfigurationId = this.hueConfiguration.FindIndex(c => c.OffConfig == true); |
Créons maintenant la méthode « ApplyHueConfiguration » qui se chargera d’appliquer la configuration sur nos lampes Hue.
En quelques mots elle itère sur chaque « Light » de la configuration spécifiée par son index puis invoque le MessageCallback « Set » du package Hue en passant l’ID de la lampe avec son état (state, hue/sat et brightness). La configuration courante est sauvegardée dans la variable « currentConfigurationId« .
Il est aussi possible de spécifier optionnellement l’index de la configuration à exclure ce qui aura pour action d’appliquer automatique la configuration suivante.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
private int ApplyHueConfigration(List<dynamic> configurationList, int configIdx, int configToExclude = -1) { // Si la config selectionnée est à exclure ... if (configToExclude >= 0 && configIdx == configToExclude) { // On passe à la configuration suivante : return this.ApplyHueConfigration(configurationList, (configIdx + 1) % configurationList.Count, configToExclude); } else { // On récupere la configuration à partir de son Index var config = configurationList[configIdx]; PackageHost.WriteInfo("Applying Hue configuration '{0}'", config.ConfigName); // On applique la configuration en invoquant le MC "Set" à chaque lampe this.currentConfigurationId = configIdx; foreach (dynamic hue in config.Lights) { PackageHost.CreateMessageProxy("Hue").Set(hue.id, hue.state, hue.hue, hue.sat, hue.bri); Thread.Sleep(100); } // On retourne l'Index de la configuration appliquée return configIdx; } } |
Maintenant modifions notre handler sur le StateObjectLink « InterrupteurHue1 » que nous avons créé précédemment.
Dès que cet interrupteur change d’état on applique la configuration « Default » ou « Off » en fonction de l’état du relais FGS-211 correspondant. On prendra garde de ne rien faire si l’interrupteur change à « On » alors que l’état des lampes n’est pas éteint et inversement, on ne fera rien si l’interrupteur change à « Off » alors que les lampes sont déjà éteintes.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
this.InterrupteurHue1.ValueChanged += (s, e) => { // Si InterrupteurHue1 change d'état if ((bool)e.OldState.DynamicValue.Status != (bool)e.NewState.DynamicValue.Status) { if ((bool)e.NewState.DynamicValue.Status && this.currentConfigurationId != offConfigurationId) { // Ne rien faire si InterrupteurHue1 = ON et que la configuration actuelle n'est pas "tout eteint" ! return; } else if ((bool)e.NewState.DynamicValue.Status == false && this.currentConfigurationId == offConfigurationId) { // Ne rien faire si InterrupteurHue1 = OFF et que la configuration actuelle est déjà "tout eteint" ! return; } else { // Autrement on applique la configuration "default" si InterrupteurHue1 = ON ou "off" si InterrupteurHue1 = Off this.ApplyHueConfigration(hueConfiguration, (bool)e.NewState.DynamicValue.Status ? defaultConfigurationId : offConfigurationId); } } }; |
Maintenant pour le deuxième interrupteur, dès qu’il changera d’état, deux cas :
- Si l’interrupteur n°1 n’est pas allumé, on invoque le MC « SetSwitchState » du package Vera pour l’allumer. Ainsi son SO sera mis à jour et donc le code ci-dessus sera invoqué pour appliquer la configuration « Default » (synchronisation parfaite entre l’état du relais Fibaro et nos lampes)
- Si l’interrupteur n°1 est déjà allumé, on appelle notre méthode « ApplyHueConfiguration » en spécifiant l’index de la prochaine configuration et en excluant la configuration « tout éteint » (Off)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
// On permute les configurations avec InterrupteurHue2 this.InterrupteurHue2.ValueChanged += (s, e) => { // Si InterrupteurHue2 change d'état if ((bool)e.OldState.DynamicValue.Status != (bool)e.NewState.DynamicValue.Status) { // Si InterrupteurHue1 = OFF, on l'allume pour garder InterrupteurHue1 syncrhonisé ! if ((bool)this.InterrupteurHue1.DynamicValue.Status == false) { // Cela déclenchera le handler ci-dessus ce qui appliquera la configuration "default". PackageHost.CreateMessageProxy("Vera").SetSwitchState(new { DeviceID = (int)this.InterrupteurHue1.DynamicValue.Id, State = true }); } else // Si InterrupteurHue1 est déjà ON { // ON applique la configuration suivante de facon cyclique en excluant la configuration " tout éteint" this.ApplyHueConfigration(hueConfiguration, (this.currentConfigurationId + 1) % hueConfiguration.Count, configToExclude: offConfigurationId); } } }; |
Ainsi on a bien l’interrupteur n°1 qui contrôle le relais n° 1 du Fibaro, lui même parfaitement synchronisé avec nos lampes. Si le relais est éteint, on applique la configuration « OffConfig » de notre setting et si le relais est allumé, on applique la configuration « DefaultConfig ».
Quand on appuie sur l’interrupteur n°2, on permute l’état du relais n° 2 du Fibaro ce qui applique donc, de manière cyclique, les différentes configurations de notre setting sur nos lampes Hue.
On peut modifier comme bon nous semble le setting depuis la Console Constellation pour changer la configuration par défaut, ajouter ou supprimer de nouvelles ambiances ou modifier celles existantes ! De même, si ajoutez des lampes dans votre pièce vous n’aurez qu’à les déclarer dans votre JSON;
De plus, avec n’importe quelle application ou contrôleur Z-Wave comme un Minimote par exemple, vous pouvez contrôler l’interrupteur n°1 qui se synchronisera parfaitement avec vos lampes Hue !
Pour aller plus loin
Ajoutons une dernière méthode nommée « ApplyHueConfiguration » qui accepte en paramètre le nom de la configuration à appliquer. On l’invoque avec le nom de la configuration (et non l’index) et elle se chargera d’appliquer cette configuration si elle existe bien dans votre setting.
Une fois n’est pas coutume, on enverra des messages au package Vera pour synchroniser l’état du relais n°1 si nécessaire.
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 |
[MessageCallback] public int ApplyHueConfigration(string configName) { // On récupere l'ID de la configuration à partir de son nom int configId = this.hueConfiguration.FindIndex(c => c.ConfigName == configName); if (configId >= 0) { // On synchronise l'interrupteur Fibaro avec les lampes (sens Hue -> Fibaro) if (configId != offConfigurationId && (bool)this.InterrupteurHue1.DynamicValue.State == false) { PackageHost.CreateMessageProxy("Vera").SetSwitchState(new { DeviceID = (int)this.InterrupteurHue1.DynamicValue.Id, State = true }); } else if (configId == offConfigurationId && (bool)this.InterrupteurHue1.DynamicValue.State == true) { PackageHost.CreateMessageProxy("Vera").SetSwitchState(new { DeviceID = (int)this.InterrupteurHue1.DynamicValue.Id, State = false }); } // On applique la configuration return this.ApplyHueConfigration(hueConfiguration, configId); } else { return configId; } } |
Vous remarquerez que nous avons ajouté l’attribut [MessageCallback] sur cette méthode ce qui veut dire que votre package exposera cette méthode, que l’on nomme MessageCallback, pour toute votre Constellation.
C’est à dire que n’importe quel autre package C#, Python, un script Powershell ou Bash, un Arduino ou ESP8266, une page Web, etc… Tous pourront envoyer un message à votre package pour appliquer des configurations lumineuses sur vos lampes Hue en fonction des configurations que nous avez configuré dans votre setting !
Super tuto !
J’aimerais bien faire la même chose mais je n’ai pas de neutre. Est ce réalisable avec un fgd-212 et peut être un bypass ?