﻿<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Tag Fibaro - Constellation</title>
	<atom:link href="https://developer.myconstellation.io/tag/fibaro/feed/" rel="self" type="application/rss+xml" />
	<link>https://developer.myconstellation.io/tag/fibaro/</link>
	<description>Votre plateforme d&#039;interconnexion</description>
	<lastBuildDate>Thu, 19 Apr 2018 05:06:39 +0000</lastBuildDate>
	<language>fr-FR</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.0.11</generator>

<image>
	<url>https://developer.myconstellation.io/wp-content/uploads/2016/02/256x256-e1457476015859.png</url>
	<title>Tag Fibaro - Constellation</title>
	<link>https://developer.myconstellation.io/tag/fibaro/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Synchroniser un interrupteur mural avec des ampoules connectées et contrôler l&#8217;ambiance lumineuse de votre pièce</title>
		<link>https://developer.myconstellation.io/tutorials/synchroniser-interrupteur-mural-ampoules-connectee/</link>
					<comments>https://developer.myconstellation.io/tutorials/synchroniser-interrupteur-mural-ampoules-connectee/#comments</comments>
		
		<dc:creator><![CDATA[Sebastien Warin]]></dc:creator>
		<pubDate>Mon, 15 May 2017 23:12:13 +0000</pubDate>
				<category><![CDATA[Tutoriels]]></category>
		<category><![CDATA[Fibaro]]></category>
		<category><![CDATA[Ampoules]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Package]]></category>
		<category><![CDATA[Vera]]></category>
		<category><![CDATA[Z-Wave]]></category>
		<category><![CDATA[Hue]]></category>
		<category><![CDATA[Lampe]]></category>
		<guid isPermaLink="false">https://developer.myconstellation.io/?p=4853</guid>

					<description><![CDATA[<p>Dans cet article nous allons découvrir comment contrôler l&#8217;ambiance lumineuse d&#8217;une pièce équipée d&#8217;ampoules connectées avec un simple interrupteur mural. L&#8217;idée est à la fois de pouvoir allumer ou éteindre toutes les ampoules de la pièce à partir de l’interrupteur</p>
<p>The post <a rel="nofollow" href="https://developer.myconstellation.io/tutorials/synchroniser-interrupteur-mural-ampoules-connectee/">Synchroniser un interrupteur mural avec des ampoules connectées et contrôler l&rsquo;ambiance lumineuse de votre pièce</a> appeared first on <a rel="nofollow" href="https://developer.myconstellation.io">Constellation</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>Dans cet article nous allons découvrir comment contrôler l&rsquo;ambiance lumineuse d&rsquo;une pièce équipée d&rsquo;ampoules connectées avec un simple interrupteur mural.</p>
<p>L&rsquo;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&#8230;</p>
<p align="center"><a href="https://developer.myconstellation.io/wp-content/uploads/2017/05/Hue1.gif"><img class="colorbox-4853"  loading="lazy" style="background-image: none; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-width: 0px;" title="Hue1" src="https://developer.myconstellation.io/wp-content/uploads/2017/05/Hue1_thumb-gap.jpg" data-gif="https://developer.myconstellation.io/wp-content/uploads/2017/05/Hue1_thumb.gif" alt="Hue1" width="150" height="266" border="0" /></a></p>
<h3>Prérequis</h3>
<ul>
<li>Un serveur Constellation</li>
<li>Des lampes ou ampoules connectées, ici des Philips Hue</li>
<li>Un interrupteur mural connecté, ici un interrupteur Legrand relié à un module Z-Wave Fibaro FGS-211</li>
<li>Le SDK Constellation pour Visual Studio</li>
</ul>
<h3>Etape 1 : connecter un interrupteur mural</h3>
<p>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&rsquo;y parvenir.</p>
<p>Pour ma part, j&rsquo;ai conservé les interrupteurs existants de la gamme Mosaic Legrand. Il s&rsquo;agit pour être exacte d&rsquo;un double bouton poussoir.</p>
<p>Pour le rendre connecté, j&rsquo;ai ajouté un micro-module de la marque Fibaro spécialement conçu pour être intégré dans la boite d&rsquo;encastrement juste derrière l’interrupteur.</p>
<p>Ce module Fibaro est un FGS-211 connecté en Z-Wave et disposant de deux relais en sortie pilotant des charges jusqu&rsquo;à 1500W et de deux entrées. Dans mon cas, il n&rsquo;y a aucune charge connectée sur ce module, il me sert juste de »capteur ».</p>
<p>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 !</p>
<p>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 :</p>
<p style="text-align: center;"><a href="https://developer.myconstellation.io/wp-content/uploads/2017/05/image-87.png"><img loading="lazy" class="alignnone colorbox-4853" style="background-image: none; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-width: 0px;" title="Connexion du FGS-211" src="https://developer.myconstellation.io/wp-content/uploads/2017/05/image_thumb-86.png" alt="Connexion du FGS-211" width="450" height="321" border="0" /></a></p>
<p>Cela permettant d&rsquo;avoir deux boutons connectés sur le même interrupteur : l&rsquo;un servira pour allumer ou éteindre toutes les lumières du salon et l&rsquo;autre permettra de changer la configuration lumineuse de la pièce.</p>
<p style="text-align: center;"><img loading="lazy" class="aligncenter colorbox-4853" style="background-image: none; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-width: 0px;" title="image" src="https://developer.myconstellation.io/wp-content/uploads/2017/05/image-86.png" alt="image" width="240" height="232" border="0" /></p>
<p style="text-align: left;">Ce module Fibaro a été appairé sur mon contrôleur Z-Wave qui est une Vera Lite. Après avoir déployé le package <a href="/package-library/vera/">Vera </a>sur une des sentinelles de ma Constellation, on obtient différents StateObjects représentant l&rsquo;état en temps réel de chaque device Z-Wave et des MessageCallbacks permettant de les piloter.</p>
<p style="text-align: left;">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&rsquo;é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é.</p>
<p style="text-align: center;" align="center"><a href="https://developer.myconstellation.io/wp-content/uploads/2017/05/image-89.png"><img loading="lazy" class="aligncenter colorbox-4853" style="background-image: none; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-width: 0px;" title="StateObject du FGS-211" src="https://developer.myconstellation.io/wp-content/uploads/2017/05/image_thumb-88.png" alt="StateObject du FGS-211" width="354" height="293" border="0" /></a></p>
<p style="text-align: left;">On peut permuter l&rsquo;état du relais informatiquement parlant par la Vera (ou par Constellation via le MessageCallback « <em>SetSwitchState</em> » du package Vera) ou directement en appuyant sur les boutons poussoirs.</p>
<p>Ainsi dès lors que l&rsquo;utilisateur va appuyer sur l&rsquo;un des boutons poussoirs, l&rsquo;état du relais changera et donc le StateObject le représentant sera également mis à jour dans votre Constellation. On pourra donc s&rsquo;abonner à ces deux StateObjects via l&rsquo;API.NET, Python, Arduino ou autre pour réagir à ces changements d&rsquo;état, par exemple pour allumer ou éteindre les ampoules Hue.</p>
<h3>Etape 2 : connecter des lampes</h3>
<p>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 <a href="/tutorials/synchroniser-lampe-bureau-avec-session-windows/#Etape_1_piloter_une_lampe_par_Constellation">cet autre tutoriel</a> : solutions DIY, prises connectées en Wifi, RF, en Z-Wave, lampes ou ampoules connectées en Wifi, en ZeeBee, etc.. etc..</p>
<p>Dans mon cas, j&rsquo;ai équipé les huit appliques de mon salon avec des ampoules Philips Hue.</p>
<p style="text-align: center;"><a href="https://developer.myconstellation.io/wp-content/uploads/2017/05/hue.jpg"><img loading="lazy" class="aligncenter colorbox-4853" style="background-image: none; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-width: 0px;" title="hue" src="https://developer.myconstellation.io/wp-content/uploads/2017/05/hue_thumb.jpg" alt="hue" width="400" height="210" border="0" /></a></p>
<p style="text-align: left;">Toutes les ampoules communiquent en ZeeBee à un pont Ethernet, nommé le bridge (à gauche de la photo ci-dessus). Grace au package <a href="/package-library/hue/">Hue</a>, vous disposez de différents MessageCallbacks pour contrôler chaque lampes Hue (état, intensité lumineuse, couleur, effet, etc..) et d&rsquo;un StateObject par luminaire représentant son état en temps réel.</p>
<p style="text-align: center;" align="center"><a href="https://developer.myconstellation.io/wp-content/uploads/2017/05/image-90.png"><img class="colorbox-4853"  loading="lazy" style="background-image: none; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-width: 0px;" title="StateObject d'une ampoule Hue" src="https://developer.myconstellation.io/wp-content/uploads/2017/05/image_thumb-89.png" alt="StateObject d'une ampoule Hue" width="354" height="258" border="0" /></a></p>
<p style="text-align: center;" align="center"><a href="https://developer.myconstellation.io/wp-content/uploads/2017/05/image-91.png"><img class="colorbox-4853"  loading="lazy" style="background-image: none; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-width: 0px;" title="MessageCallbacks du package Hue" src="https://developer.myconstellation.io/wp-content/uploads/2017/05/image_thumb-90.png" alt="MessageCallbacks du package Hue" width="354" height="358" border="0" /></a></p>
<h3>Etape 3 : synchroniser l’interrupteur avec les lampes</h3>
<p>Passons au chose sérieuse, nous avons d’un côté deux StateObjects nous indiquant l&rsquo;état des deux relais qu&rsquo;on contrôle par les boutons poussoirs et de l&rsquo;autre des MessageCallbacks nous permettant de contrôler les ampoules Hue du salon, reste juste à faire le lien !</p>
<p>Pour cela nous allons <a href="https://developer.myconstellation.io/getting-started/creez-votre-premier-package-constellation-en-csharp/">créer un package .NET en C#</a> depuis Visual Studio.</p>
<p>Dans la classe principale (<em>Program</em>), nous allons ajouter deux <a href="https://developer.myconstellation.io/client-api/net-package-api/consommer-des-stateobjects/">StateObjectLinks</a>, c’est à dire des propriétés dans notre code liées aux StateObjects représentant les états des interrupteurs :</p>
<p></p><pre class="crayon-plain-tag">[StateObjectLink("Vera", "Interrupteur Hue 1")]
public StateObjectNotifier InterrupteurHue1 { get; set; }

[StateObjectLink("Vera", "Interrupteur Hue 2")]
public StateObjectNotifier InterrupteurHue2 { get; set; }</pre><p></p>
<p>Nous allons commencer par le bouton de gauche, c&rsquo;est à dire l&rsquo;interrupteur n°1 qui se chargera d&rsquo;allumer ou d’éteindre toutes les ampoules du salon.</p>
<p>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&rsquo;état à bien changé, c&rsquo;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&rsquo;un « poll » Z-Wave à intervalle régulier sans pour autant que son Status ait changé !).</p>
<p>Ensuite on invoque simplement le MessageCallback « <em>SetState</em> » du package Hue. Le 1er argument est le n° de la lampe, 0 indiquant « toutes les lampes » et le 2ème argument est l&rsquo;état (On ou Off) de la lampe. Ici on passera l&rsquo;état du relais (propriété du Status).</p>
<p></p><pre class="crayon-plain-tag">this.InterrupteurHue1.ValueChanged += (s, e) =&gt;
{
    if ((bool)e.OldState.DynamicValue.Status != (bool)e.NewState.DynamicValue.Status)
    {
        PackageHost.CreateMessageProxy("Hue").SetState(0, (bool)e.NewState.DynamicValue.Status);
    }
};</pre><p></p>
<p>Ainsi dès que vous appuyez sur le bouton poussoir de gauche, le relais change d&rsquo;état donc le code ci-dessus est invoqué ce qui allumera ou éteindra toutes vos lampes Hue !</p>
<p>Et voilà comment en quelques lignes on peut synchroniser des choses ensembles ! Au final, on obtient un interrupteur connecté pilotant plusieurs ampoules connectées.</p>
<p>Une fois votre package testé et validé, vous pouvez <a href="/constellation-platform/constellation-sdk/publier-package-visual-studio/">le publier</a> dans votre Constellation et le déployer sur une de vos sentinelles (<a href="/getting-started/creez-votre-premier-package-constellation-en-csharp/#Publier_son_package_dans_Constellation">voir le guide</a>). Simple et efficace !</p>
<h3>Etape 4 : contrôler les ambiances lumineuses</h3>
<p>Ce que nous avons fait jusqu&rsquo;à présent est relativement simple : on synchronise simplement l&rsquo;état du relais Fibaro (piloté par l’interrupteur) à l&rsquo;état (state On/Off) des lampes Hue.</p>
<p>Le MessageCallback « <em>SetState</em> » allume ou éteint des lampes Hue. Dans le cas d&rsquo;un allumage, les lampes reprendront leurs dernières configurations en terme de couleur et d&rsquo;intensité.</p>
<p style="text-align: left;">Il existe d&rsquo;autre MC sur ce package comme le <em>SetColor</em>, <em>SetBrightness</em>, ou le <em>Set</em> qui combine les 3 en un en prenant en paramètre à la fois l&rsquo;état, la couleur et l&rsquo;intensité.</p>
<p style="text-align: left;">Nous allons donc perfectionner notre package en utilisant <a href="/client-api/net-package-api/settings/">un setting au format JSON</a> pour décrire nos différentes ambiances lumineuses. L’interrupteur de gauche ne se contentera plus de faire un simple <em>SetState</em> sur chaque lampe mais appliquera la configuration dite par défaut que nous pourrons à tout moment mettre à jour dans les settings depuis la Console.</p>
<p style="text-align: left;">L&rsquo;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).</p>
<p align="center"><img class="colorbox-4853"  loading="lazy" title="Hue2" src="https://developer.myconstellation.io/wp-content/uploads/2017/05/Hue2_thumb-gap.jpg" data-gif="https://developer.myconstellation.io/wp-content/uploads/2017/05/Hue2_thumb.gif" alt="Hue2" width="150" height="266" border="0" /></p>
<p style="text-align: left;" align="center">Commençons d&rsquo;abord par définir nos configurations lumineuses dans un setting JSON.</p>
<h4>Créer des « configurations lumineuses »</h4>
<p>Pour cela je vous propose de créer une page Web pour générer le setting de configuration sur base de l&rsquo;état actuelle de vos lampes.</p>
<p>En clair, avec l&rsquo;application officielle Hue, réglez vos lampes pour créer l&rsquo;ambiance lumineuse souhaitée et en temps réel notre page Web générera l&rsquo;objet JSON représentant votre configuration.</p>
<p>Nous allons simplement créer un simple page HTML en y ajoutant le module Constellation / AngularJS <a href="/client-api/javascript-api/consommer-constellation-angular-js/">comme vu ici</a>.</p>
<p>Lorsque nous sommes connecté, on enregistre un StateObjectLink sur tous les StateObjects du type « <em>Q42.HueApi.Light</em> » du package Hue. Pour chaque lampe Hue, on stocke la valeur du StateObject dans une variable de scope nommée « lights » :</p>
<p></p><pre class="crayon-plain-tag">constellation.registerStateObjectLink("*", "Hue", "*", "Q42.HueApi.Light", function (stateObject) { 
    $scope.$apply(function () {
        $scope.lights[stateObject.Name] = stateObject.Value;
    });
});</pre><p></p>
<p>Ainsi l&rsquo;état de chacune de nos lampes sera synchronisée en temps réel dans cette variable Javascript.</p>
<p>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 :</p>
<p></p><pre class="crayon-plain-tag">&lt;ul&gt;
    &lt;li ng-repeat="(name, value) in lights" title="{{value}}"&gt;{{name}} = #{{value.id}} On:{{value.state.on}} Hue:{{value.state.hue}} Sat:{{value.state.sat}} Bri:{{value.state.bri}}&lt;/li&gt;
&lt;/ul&gt;</pre><p></p>
<p>C&rsquo;est aussi simple que cela !</p>
<p>Maintenant ajoutons une méthode « <em>ExportCurrentConfig</em> » qu&rsquo;on appellera dans notre StateObjectLink dès qu&rsquo;un StateObject est mis à jour :</p>
<p></p><pre class="crayon-plain-tag">$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, "'");
};</pre><p></p>
<p>On crée un objet avec une propriété « <em>ConfigName</em> » pour nommer notre configuration et un tableau « <em>Lights</em> » qu&rsquo;on remplit avec l&rsquo;état connu de chaque lampe. Pour finir on « <em>stringify</em> » notre objet en JSON qu&rsquo;on affichera ensuite dans un « <em>textarea</em> » sur la page :</p>
<p align="center"><a href="https://developer.myconstellation.io/wp-content/uploads/2017/05/image-88.png"><img class="colorbox-4853"  loading="lazy" style="background-image: none; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-width: 0px;" title="image" src="https://developer.myconstellation.io/wp-content/uploads/2017/05/image_thumb-87.png" alt="image" width="454" height="274" border="0" /></a></p>
<p style="text-align: left;" align="center">Il ne reste plus qu&rsquo;à générer différentes configurations notre « extracteur » pour la suite de notre tutoriel.</p>
<p style="text-align: left;" align="center">Le code complet de la page :</p>
<p></p><pre class="crayon-plain-tag">&lt;!DOCTYPE html&gt;
&lt;html xmlns="http://www.w3.org/1999/xhtml" ng-app="hue"&gt;
&lt;head&gt;
    &lt;title&gt;Hue Configuration&lt;/title&gt;
        
    &lt;script type="text/javascript" src="/Scripts/jquery-2.1.3.min.js"&gt;&lt;/script&gt;
    &lt;script type="text/javascript" src="/Scripts/angular.min.js"&gt;&lt;/script&gt;
    &lt;script type="text/javascript" src="/Scripts/jquery.signalR-2.2.0.min.js"&gt;&lt;/script&gt;
    &lt;script type="text/javascript" src="/Scripts/Constellation-1.8.1.js"&gt;&lt;/script&gt;
    &lt;script type="text/javascript" src="/Scripts/ngConstellation-1.8.1.js"&gt;&lt;/script&gt; 
    
    &lt;script&gt;
        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();
            }]);
    &lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;ul&gt;
        &lt;li ng-repeat="(name, value) in lights" title="{{value}}"&gt;{{name}} = #{{value.id}} On:{{value.state.on}} Hue:{{value.state.hue}} Sat:{{value.state.sat}} Bri:{{value.state.bri}}&lt;/li&gt;
    &lt;/ul&gt;
    &lt;hr/&gt;
    &lt;p&gt;Current configuration :&lt;/p&gt;
    &lt;textarea rows="40" cols="50"&gt;{{strConfigs}}&lt;/textarea&gt;
    
&lt;/body&gt;
&lt;/html&gt;</pre><p></p>
<h4>Activer les configurations depuis interrupteur</h4>
<p>Premièrement nous allons déclarer dans le <a href="/concepts/package-manifest/">manifeste de notre package</a> (<em>PackageInfo.xml</em>) le setting « <em>Hue.Configuration</em> » par la ligne :</p>
<p></p><pre class="crayon-plain-tag">&lt;Setting name="Hue.Configurations" type="JsonObject" isRequired="true" description="Configurations lumineuses" /&gt;</pre><p></p>
<p>Le contenu de ce setting sera un tableau des différentes configurations générées par notre extracteur ci-dessus.</p>
<p>Pour ma part voici mes configurations à titre d&rsquo;exemple :</p>
<p></p><pre class="crayon-plain-tag">[
   {
      '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
         }
      ]
   }
]</pre><p></p>
<p>Vous remarquerez que j&rsquo;ai ajouté sur la première configuration la propriété « <em>DefaultConfig = true</em> » et « <em>OffConfig =true</em> » 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.</p>
<p>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 <a href="/client-api/net-package-api/settings/">fichier App.config</a>.</p>
<p align="center"><a href="https://developer.myconstellation.io/wp-content/uploads/2017/05/image-92.png"><img class="colorbox-4853"  loading="lazy" style="background-image: none; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border: 0px;" title="Configuration du setting" src="https://developer.myconstellation.io/wp-content/uploads/2017/05/image_thumb-91.png" alt="Configuration du setting" width="454" height="278" border="0" /></a></p>
<p>Pour revenir à notre code C#, nous allons tout d&rsquo;abord déclarer les variables privées suivantes :</p>
<p></p><pre class="crayon-plain-tag">private int currentConfigurationId = 0, defaultConfigurationId = 0, offConfigurationId = 0;
private List&lt;dynamic&gt; hueConfiguration = new List&lt;dynamic&gt;();</pre><p></p>
<p>Dans la méthode démarrage (<em>OnStart</em>) on charge notre setting JSON dans la variable « <em>hueConfiguration</em> » avec la méthode « <em>GetSettingAsJson</em> » puis on récupère dans ce tableau l&rsquo;index de la configuration « Default » et « Off » par la méthode .NET « <em>FindIndex</em> » :</p>
<p></p><pre class="crayon-plain-tag">hueConfiguration = new List&lt;dynamic&gt;(PackageHost.GetSettingAsJsonObject("Hue.Configurations"));
defaultConfigurationId = this.hueConfiguration.FindIndex(c =&gt; c.DefaultConfig == true);
offConfigurationId = this.hueConfiguration.FindIndex(c =&gt; c.OffConfig == true);</pre><p></p>
<p>Créons maintenant la méthode « <em>ApplyHueConfiguration</em> » qui se chargera d&rsquo;appliquer la configuration sur nos lampes Hue.</p>
<p>En quelques mots elle itère sur chaque « <em>Light</em> » de la configuration spécifiée par son index puis invoque le MessageCallback « <em>Set</em> » du package Hue en passant l&rsquo;ID de la lampe avec son état (state, hue/sat et brightness). La configuration courante est sauvegardée dans la variable « <em>currentConfigurationId</em>« .</p>
<p>Il est aussi possible de spécifier optionnellement l&rsquo;index de la configuration à exclure ce qui aura pour action d&rsquo;appliquer automatique la configuration suivante.</p>
<p></p><pre class="crayon-plain-tag">private int ApplyHueConfigration(List&lt;dynamic&gt; configurationList, int configIdx, int configToExclude = -1)
{
    // Si la config selectionnée est à exclure ...
    if (configToExclude &gt;= 0 &amp;&amp; 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;
    }
}</pre><p></p>
<p>Maintenant modifions notre handler sur le StateObjectLink « InterrupteurHue1 » que nous avons créé précédemment.</p>
<p>Dès que cet interrupteur change d&rsquo;état on applique la configuration « Default » ou « Off » en fonction de l&rsquo;état du relais FGS-211 correspondant. On prendra garde de ne rien faire si l&rsquo;interrupteur change à « On » alors que l&rsquo;état des lampes n&rsquo;est pas éteint et inversement, on ne fera rien si l&rsquo;interrupteur change à « Off » alors que les lampes sont déjà éteintes.</p>
<p></p><pre class="crayon-plain-tag">this.InterrupteurHue1.ValueChanged += (s, e) =&gt;
{
    // Si InterrupteurHue1 change d'état
    if ((bool)e.OldState.DynamicValue.Status != (bool)e.NewState.DynamicValue.Status)
    {
        if ((bool)e.NewState.DynamicValue.Status &amp;&amp; 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 &amp;&amp; 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);
        }
    }
};</pre><p></p>
<p>Maintenant pour le deuxième interrupteur, dès qu&rsquo;il changera d&rsquo;état, deux cas :</p>
<ul>
<li>Si l&rsquo;interrupteur n°1 n&rsquo;est pas allumé, on invoque le MC « <em>SetSwitchState</em> » du package Vera pour l&rsquo;allumer. Ainsi son SO sera mis à jour et donc le code ci-dessus sera invoqué pour appliquer la configuration « Default » (synchronisation parfaite entre l&rsquo;état du relais Fibaro et nos lampes)</li>
<li>Si l&rsquo;interrupteur n°1 est déjà allumé, on appelle notre méthode « <em>ApplyHueConfiguration</em> » en spécifiant l&rsquo;index de la prochaine configuration et en excluant la configuration « tout éteint » (Off)</li>
</ul>
<p></p><pre class="crayon-plain-tag">// On permute les configurations avec InterrupteurHue2
this.InterrupteurHue2.ValueChanged += (s, e) =&gt;
{
    // 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);
        }
    }
};</pre><p></p>
<p>Ainsi on a bien l&rsquo;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 ».</p>
<p>Quand on appuie sur l&rsquo;interrupteur n°2, on permute l&rsquo;é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.</p>
<p>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&rsquo;aurez qu&rsquo;à les déclarer dans votre JSON;</p>
<p>De plus, avec n&rsquo;importe quelle application ou contrôleur Z-Wave comme un Minimote par exemple, vous pouvez contrôler l&rsquo;interrupteur n°1 qui se synchronisera parfaitement avec vos lampes Hue !</p>
<h4>Pour aller plus loin</h4>
<p>Ajoutons une dernière méthode nommée « <em>ApplyHueConfiguration</em> » qui accepte en paramètre le nom de la configuration à appliquer. On l&rsquo;invoque avec le nom de la configuration (et non l&rsquo;index) et elle se chargera d&rsquo;appliquer cette configuration si elle existe bien dans votre setting.</p>
<p>Une fois n&rsquo;est pas coutume, on enverra des messages au package Vera pour synchroniser l&rsquo;état du relais n°1 si nécessaire.</p>
<p></p><pre class="crayon-plain-tag">[MessageCallback]
public int ApplyHueConfigration(string configName)
{
    // On récupere l'ID de la configuration à partir de son nom
    int configId = this.hueConfiguration.FindIndex(c =&gt; c.ConfigName == configName);
    if (configId &gt;= 0)
    {
        // On synchronise l'interrupteur Fibaro avec les lampes (sens Hue -&gt; Fibaro)
        if (configId != offConfigurationId &amp;&amp; (bool)this.InterrupteurHue1.DynamicValue.State == false)
        {
            PackageHost.CreateMessageProxy("Vera").SetSwitchState(new { DeviceID = (int)this.InterrupteurHue1.DynamicValue.Id, State = true });
        }
        else if (configId == offConfigurationId &amp;&amp; (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;
    }
}</pre><p></p>
<p>Vous remarquerez que nous avons ajouté l&rsquo;attribut <em>[MessageCallback]</em> sur cette méthode ce qui veut dire que votre package exposera cette méthode, que l&rsquo;on nomme <em>MessageCallback</em>, pour toute votre Constellation.</p>
<p>C&rsquo;est à dire que n&rsquo;importe quel autre package C#, Python, un script Powershell ou Bash, un Arduino ou ESP8266, une page Web, etc&#8230; 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 !</p>
<p>The post <a rel="nofollow" href="https://developer.myconstellation.io/tutorials/synchroniser-interrupteur-mural-ampoules-connectee/">Synchroniser un interrupteur mural avec des ampoules connectées et contrôler l&rsquo;ambiance lumineuse de votre pièce</a> appeared first on <a rel="nofollow" href="https://developer.myconstellation.io">Constellation</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://developer.myconstellation.io/tutorials/synchroniser-interrupteur-mural-ampoules-connectee/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
	</channel>
</rss>

<!--
Performance optimized by W3 Total Cache. Learn more: https://www.boldgrid.com/w3-total-cache/?utm_source=w3tc&utm_medium=footer_comment&utm_campaign=free_plugin

Mise en cache de page à l’aide de Disk: Enhanced 

Served from: developer.myconstellation.io @ 2026-01-23 11:56:53 by W3 Total Cache
-->