<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" media="screen" href="/styles/xslt/rss.xslt"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:media="http://search.yahoo.com/mrss/" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:c9="http://channel9.msdn.com">
<channel>
	<title>Channel 9 - Entries tagged with Home Automation</title>
    <atom:link rel="self" type="application/rss+xml" href="http://channel9.msdn.com/Tags/home+automation/RSS"></atom:link>
    <itunes:summary></itunes:summary>
    <itunes:author>Microsoft</itunes:author>
    <itunes:subtitle></itunes:subtitle>
    <image>
      <url>http://mschnlnine.vo.llnwd.net/d1/Dev/App_Themes/C9/images/feedimage.png</url>
      <title>Channel 9 - Entries tagged with Home Automation</title>
      <link>http://channel9.msdn.com/Tags/home+automation</link>
    </image>
    <itunes:image href=""></itunes:image>
    <itunes:category text="Technology"></itunes:category>
    <description>Channel 9 keeps you up to date with the latest news and behind the scenes info from Microsoft that developers love to keep up with. From LINQ to SilverLight – Watch videos and hear about all the cool technologies coming and the people behind them.</description>
    <link>http://channel9.msdn.com/Tags/home+automation</link>
    <language>en</language>
    <pubDate>Wed, 19 Jun 2013 12:21:42 GMT</pubDate>
    <lastBuildDate>Wed, 19 Jun 2013 12:21:42 GMT</lastBuildDate>
    <generator>Rev9</generator>
    <c9:totalResults>15</c9:totalResults>
    <c9:pageCount>1</c9:pageCount>
    <c9:pageSize>25</c9:pageSize>
  <item>
      <title>Every Gadgeteer&#39;s dream? A Gadgeteer Home Automation System</title>
      <description><![CDATA[<p>Today's Hardware Friday project by a friend of the blog, Marco Minerva, shows how he, and with his help, us, can build a cool home automation system with some of our favorite tools.</p><h2><a href="http://mikedodaro.net/2012/09/17/gadgeteer-home-automation-system/" target="_blank">Gadgeteer Home Automation System</a></h2><blockquote><p>In this post I want to describe how to create a Home Automation System that puts together many of the modules and source code we talked about on this blog during the past months. In particular,&nbsp; we’ll create a Gadgeteer device that uses touch screen capabilities of <a href="http://www.ghielectronics.com/catalog/product/276">Display T35</a> to provide access to all the functionalities of the system.</p><p>So, let’s start. Connect the following modules to a <a href="http://www.ghielectronics.com/catalog/product/269">FEZ Spider Mainboard</a>:</p><ul><li><a href="http://www.ghielectronics.com/catalog/product/280">USB ClientDP</a>; </li><li><a href="http://www.ghielectronics.com/catalog/product/282">WiFi RS21</a>, to retrieve current time from the Internet; </li><li><a href="http://www.ghielectronics.com/catalog/product/276">Display T35</a>, to manage the system using touch; </li><li><a href="http://www.ghielectronics.com/catalog/product/271">SD Card</a>, to store the configuration file of the application; </li><li><a href="http://www.ghielectronics.com/catalog/product/344">Temp &amp; Humidity</a>, to show an example of information that can be acquired using sensors; </li><li><a href="http://www.ghielectronics.com/catalog/product/327">Relays</a>, to control eletrical devices; </li><li><a href="http://www.ghielectronics.com/catalog/product/283">Camera</a>, with which we can show, for example, people that ring our bell. </li></ul><p>You can see the result in following screenshot.</p><p><a href="http://files.channel9.msdn.com/wlwimages/ae054c0b4d7b402ab1239e6800c0220f/image%5B9%5D-25.png" target="_blank"><img title="image" src="http://files.channel9.msdn.com/wlwimages/ae054c0b4d7b402ab1239e6800c0220f/image_thumb%5B3%5D-68.png" alt="image" width="315" height="265" border="0"></a></p><p>Almost all the FEZ Spider sockets are filled. As said before, we’ll use source code from some articles that have been published on this blog. In particular:</p><ul><li><a href="http://mikedodaro.net/2011/12/14/xml-configuration-files-for-net-micro-framework-applications-english/">XML Configuration Files for .NET Micro Framework</a> </li><li><a href="http://mikedodaro.net/2011/11/20/synchronize-the-clock-with-a-reference-server-on-the-internet-english/">Synchronize the Clock with a Reference Server on the Internet</a> </li><li><a href="http://mikedodaro.net/2011/11/18/windows-like-interface-for-the-net-gadgeteer-display-english/">Windows-like Interface for the .NET Gadgeteer Display</a> </li></ul><p>Moreover, we need to create some custom fonts for the application. .NET Micro Framework SDK provides a <a href="http://msdn.microsoft.com/en-us/library/cc533019.aspx">command line tool</a> that allows to do this. Alternatively, you can use the <a href="http://informatix.miloush.net/microframework/Utilities/TinyFontTool.aspx">Tiny Font Tool GUI</a> to make things simpler. In the ZIP file attached to this article you can find all the fonts we’ll use.</p><p><a href="http://files.channel9.msdn.com/wlwimages/ae054c0b4d7b402ab1239e6800c0220f/image%5B3%5D-70.png" target="_blank"><img title="image" src="http://files.channel9.msdn.com/wlwimages/ae054c0b4d7b402ab1239e6800c0220f/image_thumb%5B1%5D-95.png" alt="image" width="171" height="364" border="0"></a></p><p>...</p></blockquote><p>This project goes into all the details, from build the hardware, coding it and constructing the UI</p><blockquote><p>Our application has three sections: <em>Temperature &amp; Humidity</em>, <em>Relays</em> and <em>Camera</em>. So, we need to create three menu items:</p><p>&nbsp;</p><p>&nbsp;</p>The result is shown in the following screenshot. <p><a href="http://files.channel9.msdn.com/wlwimages/ae054c0b4d7b402ab1239e6800c0220f/image%5B6%5D-53.png" target="_blank"><img title="image" src="http://files.channel9.msdn.com/wlwimages/ae054c0b4d7b402ab1239e6800c0220f/image_thumb%5B2%5D-78.png" alt="image" width="502" height="384" border="0"></a></p></blockquote><p>Here's a video of it in action.</p><p><object width="425" height="355"><param name="movie" value="http://www.youtube.com/v/e27-reYmXEg&hl=en"></param><param name="wmode" value="transparent"></param><embed src="http://www.youtube.com/v/e27-reYmXEg&hl=en" type="application/x-shockwave-flash" wmode="transparent" width="425" height="355"></embed></object></p><p>And as you would expect, the source available for download (<a href="http://mikedodaro.net/2012/09/17/gadgeteer-home-automation-system/" target="_blank">click through</a> and it's at the bottom of the page)</p> <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Tags/home+automation/RSS&WT.dl=0&WT.entryid=Entry:RSSView:e34d7a5b9fd64610b31ca0e901723c21">]]></description>
      <comments>http://channel9.msdn.com/coding4fun/blog/Every-Gadgeteers-dream-A-Gadgeteer-Home-Automation-System</comments>
      <itunes:summary>Today&#39;s Hardware Friday project by a friend of the blog, Marco Minerva, shows how he, and with his help, us, can build a cool home automation system with some of our favorite tools. Gadgeteer Home Automation SystemIn this post I want to describe how to create a Home Automation System that puts together many of the modules and source code we talked about on this blog during the past months. In particular,&amp;nbsp; we’ll create a Gadgeteer device that uses touch screen capabilities of Display T35 to provide access to all the functionalities of the system. So, let’s start. Connect the following modules to a FEZ Spider Mainboard: USB ClientDP; WiFi RS21, to retrieve current time from the Internet; Display T35, to manage the system using touch; SD Card, to store the configuration file of the application; Temp &amp;amp; Humidity, to show an example of information that can be acquired using sensors; Relays, to control eletrical devices; Camera, with which we can show, for example, people that ring our bell. You can see the result in following screenshot.  Almost all the FEZ Spider sockets are filled. As said before, we’ll use source code from some articles that have been published on this blog. In particular: XML Configuration Files for .NET Micro Framework Synchronize the Clock with a Reference Server on the Internet Windows-like Interface for the .NET Gadgeteer Display Moreover, we need to create some custom fonts for the application. .NET Micro Framework SDK provides a command line tool that allows to do this. Alternatively, you can use the Tiny Font Tool GUI to make things simpler. In the ZIP file attached to this article you can find all the fonts we’ll use.  ... This project goes into all the details, from build the hardware, coding it and constructing the UI Our application has three sections: Temperature &amp;amp; Humidity, Relays and Camera. So, we need to create three menu items: &amp;nbsp; &amp;nbsp; The result is shown in the following screenshot.  Here&#39;s a video of it in action.</itunes:summary>
      <link>http://channel9.msdn.com/coding4fun/blog/Every-Gadgeteers-dream-A-Gadgeteer-Home-Automation-System</link>
      <pubDate>Fri, 19 Oct 2012 13:00:00 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/coding4fun/blog/Every-Gadgeteers-dream-A-Gadgeteer-Home-Automation-System</guid>
      <media:thumbnail url="http://files.channel9.msdn.com/thumbnail/9efa809c-af3e-4476-923e-41783f58f645.png" height="75" width="100"></media:thumbnail>
      <media:thumbnail url="http://files.channel9.msdn.com/thumbnail/c1bb1ca2-d746-431b-85e3-82cd30f7a64e.png" height="166" width="220"></media:thumbnail>      
      <dc:creator>Greg Duncan</dc:creator>
      <itunes:author>Greg Duncan</itunes:author>
      <slash:comments>1</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/coding4fun/blog/Every-Gadgeteers-dream-A-Gadgeteer-Home-Automation-System/RSS</wfw:commentRss>
      <category>.NET Micro Framework</category>
      <category>C#</category>
      <category>Coding4Fun</category>
      <category>Home Automation</category>
      <category>.Net Gadgeteer</category>
    </item>
  <item>
      <title>Home Energy Monitoring</title>
      <description><![CDATA[ <p>Recently, the noise from the multiple servers running in the garage, the enormous energy bills, and my general sense of “I should do more to save the planet” outweighed my procrastination and led me to take action and reduce my energy consumption.</p><p>My first step was buying an Energy Monitor. After looking at a few different models, I spotted <a href="http://www.currentcost.net/buynowmain.html">one</a> with a USB cable that would allow me to “send the readings to a home PC.” Ohh! I could do something with the data instead of just looking at it on a handheld monitor. Interesting… </p><h2>Getting Started</h2><p>The first thing to do is install the monitor and the next thing is to install the <a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10068304/win_drivers.zip">drivers for the USB cable</a>—these allow the USB connection to present itself as a COM port and make it easy to interact with. </p><p>Next, test the basic functionality. To do this (and to see the data transfer in action) you will need a Terminal client. Open your terminal software, set the COM port to whatever the USB Cable driver surfaced as (typically COM 3), set the baud rate to 57600bps, 8 data bits, “none” for parity, 1 stop bit, and no handshaking. When you “open” the COM port you should now see an Xml string being received every six seconds (for example):</p><p><strong>HTML</strong><br><pre class="brush: html">&lt;msg&gt;
   &lt;src&gt;CC128-v0.11&lt;/src&gt;
   &lt;dsb&gt;00089&lt;/dsb&gt;
   &lt;time&gt;13:02:39&lt;/time&gt;
   &lt;tmpr&gt;18.7&lt;/tmpr&gt;
   &lt;sensor&gt;1&lt;/sensor&gt;
   &lt;id&gt;01234&lt;/id&gt;
   &lt;type&gt;1&lt;/type&gt;
   &lt;ch1&gt;
      &lt;watts&gt;00345&lt;/watts&gt;
   &lt;/ch1&gt;
   &lt;ch2&gt;
      &lt;watts&gt;02151&lt;/watts&gt;
   &lt;/ch2&gt;
   &lt;ch3&gt;
      &lt;watts&gt;00000&lt;/watts&gt;
   &lt;/ch3&gt;
&lt;/msg&gt;
</pre></p><p>The format of the Xml data can be found in <a href="http://www.currentcost.com/cc128/xml.htm">this document</a>, available on the CurrentCost website.</p><h2>Project Outline / Design</h2><p>Thinking about the project outline and design, I knew that I wanted to be able to make the received data readings available to multiple applications and websites. I also wanted to be able to tweet my energy usage every couple of hours, upload the data to some data tracking/recording web app, and be able to store the data myself so I could chart it at a later date. I also wanted the ability to see the real-time data when I was away from home, and I wanted to be able to use my phone as a kind of remote monitor.</p><p>I sketched out some ideas and came up with a design for a core Windows service that simply grabbed the data from the device, decoded it, and then passed it on to a number of modules/plugins, each of which used the data to complete a specific action. This kind of module/plugin/extension framework is a good candidate for <a href="http://msdn.microsoft.com/en-us/library/dd460648.aspx">the Managed Extension Framework (MEF)</a> in .NET 4.0:</p><p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10068304/image.png"><img title="image" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10068304/image_thumb.png" border="0" alt="image" width="500" height="342"></a></p><p>In fact, we'll be targeting the .NET 4.0 framework because we need some of the newer System.Composition namespace elements for the Managed Extension Framework to work.</p><h2>Step 1 – The Windows Service</h2><p>The Windows Service is the core of the application and needs a serial port connection to receive the data from the monitor, making it able to alert each of the plugins of the new reading.</p><h5>Coding the Service</h5><p>To begin coding the service, you must first create a new “Windows Service” project type. Then, change the class name to EnergyService and the ServiceName to EnergyService, add the serial port, and wire it up. To do this, you'll need a System.IO.Ports.SerialPort member variable in the class:</p><p><strong>C#</strong><br><pre class="brush: csharp">SerialPort comm;</pre></p><p>Create the object in the class constructor, and wire up the ‘DataReceived' event:</p><p><strong>C#</strong><br><pre class="brush: csharp">comm = new SerialPort(portName, baudRate, parity, dataBits, stopBits);
comm.DataReceived &#43;= new SerialDataReceivedEventHandler(SerialDataReceived);
</pre></p><p>Then, we pull the bytes from the serial port in the ‘SerialDataReceived' event handler and add them to a buffer, immediately checking the buffer to see if the bytes we have stored in there so far make up a full reading. If so, we process it. If we don't have a full reading, however, we simply wait for more bytes.</p><p><pre class="brush: csharp">void SerialDataReceived(object sender, SerialDataReceivedEventArgs e)
{
    rxBuffer &#43;= comm.ReadExisting();
    while (IsReading(rxBuffer))
    {
        // we have a reading (or partial reading), so let's process
        EnergyReading rdg = ExtractReading(ref rxBuffer);
        if (rdg.IsValid)
        {
            NotifyPlugins(rdg);
        }
    }
}

private EnergyReading ExtractReading(ref string rxBuffer)
{
    string rdgXml;
    int pos = rxBuffer.IndexOf(Environment.NewLine);
    rdgXml = rxBuffer.Substring(0, pos);
    rxBuffer = rxBuffer.Substring(pos &#43; 2);
    return new EnergyReading(rdgXml);
}</pre></p><h3>Debug</h3><p>I also added a debug feature allowing you to inject a reading every six seconds. To enable the debug mode, simply set “debug_enabled” to “true” in the appSettings section of the app.config file.</p><p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10068304/image_3.png"><img title="image" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10068304/image_thumb_3.png" border="0" alt="image" width="163" height="242"></a></p><h2>Parsing the Readings </h2><p>The xml text is passed to the constructor of the EnergyReading class and this parses the xml into the required properties, which gives us an object to pass around as needed. The EnergyReading class only extracts the timestamp, temperature and energy values, though there is scope for parsing much more, especially from the “history” readings (<a href="http://www.currentcost.com/cc128/xml.htm">see the Xml definition for more info</a>). <strong><em>Note:</em></strong><em> we also override the ToString() method so that we have a simple method of debugging the app/values.</em></p><p><strong>C#</strong><br><pre class="brush: csharp">class EnergyReading
{
    public DateTime TimeStamp { get; private set; }
    public float Energy { get; private set; }
    public float Temperature { get; private set; }
    public bool IsValid { get; private set; }

    public EnergyReading(string readingData)
    {
        TimeStamp = DateTime.MinValue;
        Energy = float.NaN;
        Temperature = float.NaN;
        IsValid = false;

        try
        {
            // parse the xml based reading
            XmlDocument xDoc = new XmlDocument();
            xDoc.LoadXml(readingData);

            XmlNode xNode = xDoc.SelectSingleNode(&quot;/msg/time&quot;);
            TimeStamp = DateTime.Parse(xNode.InnerText);
            xNode = xDoc.SelectSingleNode(&quot;/msg/tmpr&quot;);
            Temperature = float.Parse(xNode.InnerText);
            xNode = xDoc.SelectSingleNode(&quot;/msg/ch1/watts&quot;);
            Energy = int.Parse(xNode.InnerText);
            IsValid = true;
        }
        catch (Exception ex)
        {
            // invalid reading
            Debug.WriteLine(ex.Message);
        }
    }

    public override string ToString()
    {
        StringBuilder sb = new StringBuilder(TimeStamp.ToLongTimeString());
        sb.Append(&quot; - &quot;);
        sb.Append(Energy.ToString(&quot;N&quot;));
        sb.Append(&quot; Watts - &quot;);
        sb.Append(Temperature.ToString(&quot;N&quot;));
        sb.Append(&quot; Degrees&quot;);

        return sb.ToString();
    }
}
</pre></p><h2>Adding the Plugin Infrastructure</h2><p>Next up is adding the plumbing for the plugins. As previously mentioned, we will be using MEF, which makes it all incredibly simple.</p><p>Basically, we define an interface supported by all of the plugins, create a private variable of type IList&lt;PluginInterface&gt; and tag it with the [ImportMany] attribute (this holds our plugin objects), create a catalog of plugins (loaded from a specific directory), and then add that catalog to a CompositionContainer that automatically wires everything up for us. Sounds complex, but it only takes about 10 lines of code:</p><p><strong>C#</strong><br><pre class="brush: csharp">using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;

// snip....

CompositionContainer container;

// snip....

[ImportMany]
private IList&lt;IEnergyMonitorPlugin&gt; plugins { get; set; }

// snip....

private void LoadPlugins()
{
    string baseDir = AppDomain.CurrentDomain.BaseDirectory;
    DirectoryCatalog currDirCatalog = new DirectoryCatalog(baseDir);

    container = new CompositionContainer(currDirCatalog);
    container.ComposeParts(this);
}



</pre></p><p>Now that we have all of the plugins correctly wired up, we need to notify them. For the time being, we'll also leave a few lines of debugging messages in there:</p><p><strong>C#</strong><br><pre class="brush: csharp">private void NotifyPlugins(EnergyReading rdg)
{
    Debug.WriteLine(&quot;Notify : &quot; &#43; rdg.ToString());
    if (null != plugins)
    {
        foreach (IEnergyMonitorPlugin plugin in plugins)
        {
            try
            {
                Debug.WriteLine(&quot;Notify : &quot; &#43; plugin.Name);
                plugin.Notify(rdg);
            }
            catch (Exception ex)
            {
                Debug.WriteLine(&quot;Plugin '&quot; &#43; plugin.Name &#43; &quot;' : &quot; &#43; ex.Message);
            }
        }
    }
}
</pre></p><h3>Adding an Installer to the Windows Service</h3><p>Now that we have completed the Windows Service, we need to test it out. To do so, we need to install it, and for that we need to add an Installer Class, as well as adding both a ServiceInstaller and a ServiceProcessInstaller to the designer (set the ServiceProcessInstaller Account property to “Local System” and run the service under this account).</p><p>Installing a service is different than installing a normal application. Luckily, we can use .NET framework's InstallUtil.exe to simplify things. I like to set InstallUtil.exe up as an External Tool in Visual Studio when I'm working on Windows Service projects, which makes the whole process as simple as highlighting the Windows Service project and clicking on the Install (or Uninstall) option under the Tools menu:</p><p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10068304/image_4.png"><img title="image" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10068304/image_thumb_4.png" border="0" alt="image" width="474" height="460"></a></p><p>The configuration to set this up as an “external tool” is as follows:</p><blockquote><table border="0" cellspacing="0" cellpadding="2" width="500"><tbody><tr><td width="107" valign="top">Title</td><td width="393" valign="top">Install Service (.NET 4) <br></td></tr><tr><td width="107" valign="top">Command</td><td width="393" valign="top">C:\Windows\Microsoft.NET\Framework64\v4.0.30319\InstallUtil.exe </td></tr><tr><td width="107" valign="top">Arguments</td><td width="393" valign="top">/i &quot;$(ProjectDir)\bin\debug\$(TargetName)$(TargetExt)&quot; </td></tr><tr><td width="107" valign="top">&nbsp;</td><td width="393" valign="top">&nbsp;</td></tr><tr><td width="107" valign="top">Title</td><td width="393" valign="top">Uninstall Service (.NET 4) <br></td></tr><tr><td width="107" valign="top">Command</td><td width="393" valign="top">C:\Windows\Microsoft.NET\Framework64\v4.0.30319\InstallUtil.exe </td></tr><tr><td width="107" valign="top">Arguments</td><td width="393" valign="top">/i &quot;$(ProjectDir)\bin\debug\$(TargetName)$(TargetExt)&quot;</td></tr></tbody></table></blockquote><p>For 32-bit operating systems, change the <strong>Framework64</strong> folder name to <strong>Framework</strong>.</p><h3>Testing the Windows Service</h3><p>Once you start the service, if you open the Output windows in Visual Studio and view the output from Debug, you should start seeing the readings come in:</p><p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10068304/image_5.png"><img title="image" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10068304/image_thumb_5.png" border="0" alt="image" width="376" height="134"></a></p><p><strong>&nbsp;</strong></p><h2>Step 2 – The Twitter Plugin</h2><p>The first plugin we'll write is a simple Twitter poster. Every 60 minutes, this plugin will send a tweet with your machine name and the average energy use over the last hour.</p><p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10068304/image_6.png"><img title="image" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10068304/image_thumb_6.png" border="0" alt="image" width="203" height="345"></a></p><p>Next, create a new Class Library project and name it “TwitterPlugin.” Then add a reference to the “EnergyService_CSharp” project and have the class implement the IEnergyMonitorPlugin interface. We will also need to add some class variables to hold the last tweet time, energy total, and reading count. <br>As Twitter no longer supports Basic Auth for API calls we will need to use oAuth. For this we will use the excellent oAuth class developed by <a href="http://eran.sandler.co.il/">Eran Sandler</a> and extended by <a href="http://www.voiceoftech.com/swhitley/index.php/category/software-development/page/2/">Shannon Witley</a>.</p><p><strong>C#</strong><br><pre class="brush: csharp">[Export(typeof(IEnergyMonitorPlugin))]
public class TwitterPlugin : IEnergyMonitorPlugin
{
    double twInterval;
    double twEnergy = 0;
    int twReadings = 0;
    DateTime twLastTweet = DateTime.MinValue;
    oAuthTwitter _oAuth = new oAuthTwitter();
</pre></p><p>Next, we give the plugin values for “Name” and “Description” and set the DeInit() function to return true (this is a simple plugin so no deinitialization is needed). For the Init() function, we want to read from the app.config the twitter oAuth parameters, and the interval between tweets—remember, this plugin is loaded into the AppDomain of the service, so we need to add the entries to the app.config file of the service, not the app.config of the twitterplugin project/class.</p><p>The code looks like this:</p><p><strong>C#</strong><br><pre class="brush: csharp">bool IEnergyMonitorPlugin.Init()
{
    _oAuth.Token = GetSetting(&quot;twitterplugin_token&quot;, &quot;&quot;);
    _oAuth.TokenSecret = GetSetting(&quot;twitterplugin_tokensecret&quot;, &quot;&quot;);
    _oAuth.Pin = GetSetting(&quot;twitterplugin_pin&quot;, &quot;&quot;);

    twInterval = double.Parse(GetSetting(&quot;twitterplugin_interval&quot;, &quot;60&quot;));
    return true;
}

private string GetSetting(string key, string defaultValue)
{
    NameValueCollection appSettings = ConfigurationManager.AppSettings;
    string val = appSettings.Get(key);
    if (null == val)
    {
        val = defaultValue;
    }

    return val;
}
</pre></p><p>The crux of a plugin is the “Notify” function, and for this one we simply add the energy value to the total energy count and increase the reading count. We then check if more than 60 minutes have passed since the last tweet, and if so we send the tweet:</p><p><strong>C#</strong><br><pre class="brush: csharp">bool IEnergyMonitorPlugin.Notify(EnergyReading rdg)
{
    bool retVal = false;

    twEnergy &#43;= rdg.Energy;
    twReadings&#43;&#43;;

    if (twLastTweet.AddMinutes(twInterval) &lt; DateTime.Now)
    {
    // it's time to tweet
        retVal= SendTweet(
            string.Format(
                &quot;In the last {0} mins {1} has used an average of {2} watts&quot;, 
                twInterval, 
                Environment.MachineName, 
                (twEnergy/twReadings)));
        twEnergy = 0;
        twReadings = 0;
        twLastTweet = DateTime.Now;
        retVal = true;
    }

    return retVal;
}
</pre></p><p>Sending the tweet requires that we UrlEncode the message and then call the oAuthWebRequest method of the oAuth class with the post data as a parameter. </p><p><pre class="brush: csharp">private bool SendTweet(string tweet)
{
    bool retVal = false;
    try
    {
        string encTweet = System.Web.HttpUtility.UrlEncode(tweet);
        string xml = _oAuth.oAuthWebRequest(
            oAuthTwitter.Method.POST,
            &quot;http://twitter.com/statuses/update.xml&quot;,
            &quot;status=&quot; &#43; tweet);
        retVal = true;
    }
    catch (Exception ex)
    {
        System.Diagnostics.Debug.WriteLine(&quot;Error : &quot; &#43; ex.ToString());
    }

    return retVal;
}</pre></p><p>Now we have the Notify functionality of the TwitterPlugin completed. To get it working, simply copy the plugin to the same folder as the running Windows Service, edit the setting for “twitterplugin_interval” in the service app.config files, and restart the service. The tweets will not yet be accepted by Twitter as we have not yet authorized the application – for this we need user interaction so it is not something we do in the Windows Service. Instead we build a ConfigTool that uses MEF to load in each of the plugins and calls the “Configure” method. <br>We add a Windows Form to the TwitterPlugin, add a button that takes the user to a Twitter application authorization page, add a textbox that the user enters the PIN displayed on the webpage into and save the resulting oAuth Token and TokenSecret we get back from calling the AccessTokenGet method of the oAuth class. When we have all the oAuth parameters back we simply save them into the app.config file:</p><p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10068304/image_7.png"><img title="image" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10068304/image_thumb_7.png" border="0" alt="image" width="200" height="149"></a><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10068304/image_8.png"><img title="image" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10068304/image_thumb_8.png" border="0" alt="image" width="161" height="149"></a></p><p>If all is well, you should see tweets appearing every X minutes (depending on the interval you have set) along with your energy averages.</p><p>Now that we have completed our first plugin, it should be easy to see how simple it is to write further plugins. You might consider writing the energy values to a local database, sending Facebook updates, or posting to a dedicated service that uses API to store sensor or energy values, such as <a href="http://www.pachube.com">http://www.pachube.com</a> or <a href="http://www.enio.co.uk">http://www.enio.co.uk</a>.</p><p><strong>&nbsp;</strong></p><h2>Step 3 – The WebService and Plugin</h2><h4>The next stage we'll develop will give us a little more flexibility. Essentially, this stage consists of a RESTful Windows Communication Framework (WCF) Service and a corresponding WebSvcPlugin that we'll use to update the WCF Service with the latest readings. We'll also build a couple of client applications that will retrieve the reading from the WCF Service (one is a simple webpage using jQuery AJAX to get the reading from the WCF Service, and the other is a Windows Phone 7 application using a HttpWebRequest to get the reading from the WCF Service).</h4><p>The plugin and clients will need the WCF Service to be in place before they can be written, so we'll tackle the WCF Service first by adding an “ASP.NET Empty Web Application” project to the solution and calling it “EnergyMonitorWs”:<a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10068304/image_9.png"><img title="image" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10068304/image_thumb_9.png" border="0" alt="image" width="500" height="230"></a></p><p>Then we add a new “AJAX-enabled WCF Service” and name it EnergyMonitor.svc:</p><p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10068304/image_10.png"><img title="image" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10068304/image_thumb_10.png" border="0" alt="image" width="500" height="224"></a></p><h4>The WCF Service will expose OperationContracts that allow clients to set the current values and receive each of the values in either JSON or XML format. The current values will be stored in an HttpRuntime.Cache object, so we don't need to worry about persisting the reading data to MSSQL or the FileSystem.</h4><p>The cache object is in the System.Web.Caching namespace, so we'll need a reference to that. We'll also need to make sure we are working in AspNetCompatibility mode. To do so, we'll add the following attribute to the class:</p><p><strong>C#</strong><br><pre class="brush: csharp">[AspNetCompatibilityRequirements(
    RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
</pre></p><p>Now let's code the “SetCurrentValues” function, which exposes a “/set” endpoint and takes date, time, energy, and temperature as parameters on the HTTP GET querystring and stores them in the cache for an hour (this function should be called every 6 seconds, so caching each reading for up to an hour gives us plenty of room for failed updates). </p><p><strong>C#</strong><br><pre class="brush: csharp">[OperationContract]
[WebInvoke(
    Method=&quot;GET&quot;,
    UriTemplate=&quot;set?energy={energy}&amp;temp={temp}&amp;date={date}&amp;time={time}&quot;)]
public void SetCurrentValues(string energy, string temp, string date, string time)
{
    Cache cache = HttpRuntime.Cache;

    try
    {
        cache.Remove(&quot;energy&quot;);
        cache.Remove(&quot;temp&quot;);
        cache.Remove(&quot;date&quot;);
        cache.Remove(&quot;time&quot;);
    }
    catch { }

    cache.Add(
        &quot;energy&quot;, 
        energy, 
        null, 
        DateTime.Now.AddHours(1), 
        Cache.NoSlidingExpiration, 
        CacheItemPriority.Default, 
        null);
    cache.Add(
        &quot;temp&quot;, 
        temp, 
        null, 
        DateTime.Now.AddHours(1), 
        Cache.NoSlidingExpiration, 
        CacheItemPriority.Default, 
        null);
    cache.Add(
        &quot;date&quot;, 
        date, 
        null, 
        DateTime.Now.AddHours(1), 
        Cache.NoSlidingExpiration, 
        CacheItemPriority.Default, 
        null);
    cache.Add(
        &quot;time&quot;, 
        time, 
        null, 
        DateTime.Now.AddHours(1), 
        Cache.NoSlidingExpiration, 
        CacheItemPriority.Default, 
        null);

    return;
}
</pre></p><p>We want to make request functions available via a simple HTTP GET and we want to provide the option of JSON or XML as the response. Therefore, we add a “/json/{x}” endpoint and a “/xml/{x}” endpoint where {x} is the reading data we want (energy, temp, date or time):</p><p><strong>C#</strong><br><pre class="brush: csharp">[OperationContract]
[WebInvoke(
    Method = &quot;GET&quot;, 
    UriTemplate = &quot;xml/{value}&quot;)]
public string GetValueXml(string value)
{
    WebOperationContext.Current.OutgoingResponse.ContentType = &quot;text/xml&quot;;
    return GetValue(value.ToLower());
}

[OperationContract]
[WebInvoke(
    Method = &quot;GET&quot;, 
    UriTemplate = &quot;json/{value}&quot;, 
    ResponseFormat = WebMessageFormat.Json)]
public string GetValueJson(string value)
{
    return GetValue(value.ToLower());
}

private string GetValue(string key)
{
    Cache cache = HttpRuntime.Cache;

    string retVal = (string)cache.Get(key);
    if (null == retVal)
    {
        retVal = &quot;N/A&quot;;
    }

    return retVal;
}
</pre></p><p>Now that we have the WCF Service in place, we can build the plugin that updates it. This is another Class Library project that we add to the solution (this time naming it WebServicePlugin), again making sure it implements the IEnergyMonitor interface (you'll need to add a reference to the EnergyMonitor_CSharp for this).</p><p>Give the plugin a Name and Description and set the Init() and DeInit() functions to return true. Then, simply have the code in the “Notify” function create an HTTP GET request with the values in the querystring to the “/set” endpoint (the SetCurrentValues function). This can be accomplished with a System.Net.WebClient object:</p><p><strong>C#</strong><br><pre class="brush: csharp">bool IEnergyMonitorPlugin.Notify(EnergyReading rdg)
{
    bool retVal = false;

    DateTime ts = rdg.TimeStamp;

    string getUrl = baseUrl &#43; &quot;/set?&quot;;
    getUrl &#43;= &quot;energy=&quot; &#43; rdg.Energy.ToString() &#43; &quot;&amp;&quot;;
    getUrl &#43;= &quot;temp=&quot; &#43; rdg.Temperature.ToString() &#43; &quot;&amp;&quot;;
    getUrl &#43;= &quot;date=&quot; &#43; ts.ToString(&quot;dd/MM/yy&quot;) &#43; &quot;&amp;&quot;;
    getUrl &#43;= &quot;time=&quot; &#43; ts.ToShortTimeString();

    WebClient wc = new WebClient();

    try
    {
        wc.DownloadString(getUrl);
        retVal = true;
    }
    catch (Exception ex)
    {
        System.Diagnostics.Debug.WriteLine(
            &quot;Error (Notify) : &quot; &#43; ex.Message);
    }


bool IEnergyMonitorPlugin.Init()
{
    // get the base url from the (Service) app.config
    baseUrl = GetSetting(
        &quot;websvcplugin_baseurl&quot;, 
        &quot;http://localhost/EnergyMonWs.svc&quot;);
    return true;
}

// snip....


private string GetSetting(string key, string defaultValue)
{
    NameValueCollection appSettings = ConfigurationManager.AppSettings;
    string val = appSettings.Get(key);
    if (null == val)
    {
        val = defaultValue;
    }

    return val;
}
</pre></p><p>Now that we're done with the WCF Service and WebSvcPlugin, we need to work on the two WCF Service client applications.</p><h2>Step 4 – The WebService Html Page Client</h2><h4>We'll first tackle the html webpage with jQuery—a simple webpage that uses the jQuery library to make AJAX calls to our WCF Service to get the current values—by adding a new ‘HTML Page' to the EnergyMonitorWs project. To begin, name the page EnergyMonitor.htm.</h4><h4>Next, we'll add some html to the page. This html is linked to some CSS, giving us a simple remote version of the energy monitor:</h4><p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10068304/image_11.png"><img title="image" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10068304/image_thumb_11.png" border="0" alt="image" width="305" height="181"></a></p><h4>Then we use jQuery to call the WCF Service and update the actual values with real reading data. We also add a JavaScript timer to make the WCF Service calls every 15 seconds. Obviously, we need to reference the jQuery code and the CSS in the head section:</h4><p><strong>HTML</strong><br><pre class="brush: html">&lt;head&gt;
    &lt;title&gt;Energy Monitor - Ken Hughes&lt;/title&gt;
    &lt;script 
        src=&quot;scripts/jquery-1.4.1.js&quot; 
        type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    &lt;link 
        rel=&quot;Stylesheet&quot; href=&quot;css/style.css&quot; 
        type=&quot;text/css&quot; /&gt;
&lt;/head&gt;
</pre></p><p><strong>&nbsp;</strong></p><p>Then, after the main page display elements, we add the javascript code so the values are updated every 15 seconds:</p><p><strong>Javascript</strong><br><pre class="brush: js">function getReading(fname, elementid) {
    ajaxUrl = &quot;EnergyMonWs.svc/json/&quot; &#43; fname;
    $.ajax({
        type: &quot;GET&quot;,
        url: ajaxUrl,
        contentType: &quot;application/json; charset=utf-8&quot;,
        dataType: &quot;json&quot;,
        success: function (msg) {
            // Replace the div's content with the value returned.
            $(&quot;#&quot; &#43; elementid).text(msg);
        }
    });
}


function updateReadings() {
    getReading(&quot;temp&quot;, &quot;tempval&quot;);
    getReading(&quot;energy&quot;, &quot;energyval&quot;);
    getReading(&quot;time&quot;, &quot;timeval&quot;);
   
}

$(document).ready(function () {

    updateReadings();
    window.setInterval(function () {
        updateReadings();
    }, 15000);
});
</pre></p><h2>Step 5 – The WebService Windows Phone 7 Client</h2><p>The purpose of the Windows Phone 7 client is to act as a remote monitor. The client pulls its reading from the web service and updates a monitor-style display. To complete this part of the project, you will need to have the Windows Phone 7 Development tools installed.</p><p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10068304/image_12.png"><img title="image" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10068304/image_thumb_12.png" border="0" alt="image" width="292" height="539"></a></p><p>Begin by adding a new “Windows Phone Application” project and calling it “WinPhoneEnergyMonitor.” </p><p>First, in the constructor, add a Timer object, set the interval to 15 seconds, and have it call a function to update the screen values. This function calls the webservice for each value, receiving the latest reading data and updating the relevant TextBlock.</p><p>In Windows Phone 7, uses an asynchronous manner to call to things such as the WebClient and HttpWebRequest. Accordingly, we create a new WebClient object, assign a delegate to the “DownloadStringCompleted” event, and then call “DownloadStringAsync” with the relevant uri along with the TextBlock we want to update as the ‘userState' object. All of this allows us to update the correct item in the event handler.</p><p>The code looks like this:</p><p><strong>C#</strong><br><pre class="brush: csharp">private void UpdateScreen(object state)
{
    UpdateValueFromWebService(&quot;energy&quot;, this.energyValue);
    UpdateValueFromWebService(&quot;temp&quot;, this.tempValue);
    UpdateValueFromWebService(&quot;time&quot;, this.timeValue);
    UpdateValueFromWebService(&quot;date&quot;, this.dateValue);
}

private string UpdateValueFromWebService(string reading, TextBlock tb)
{
    string retVal = &quot;N/A&quot;;
    Uri uri = new Uri(baseUri &#43; &quot;/json/&quot; &#43; reading);

    try
    {
        WebClient wc = new WebClient();
        wc.DownloadStringCompleted &#43;= 
            new DownloadStringCompletedEventHandler(DownloadStringCompleted);
        wc.DownloadStringAsync(uri, tb);
    }
    catch (Exception ex)
    {
        System.Diagnostics.Debug.WriteLine(
            &quot;Error (UpdateValueFromWebService) : &quot; &#43; ex.Message);
    }

    return retVal;
}

void DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
    try
    {
        string val = e.Result.Replace(&quot;\&quot;&quot;, &quot;&quot;).Replace(&quot;\\&quot;, &quot;&quot;);
        System.Diagnostics.Debug.WriteLine(val);
        ((TextBlock)e.UserState).Text = val;
    }
    catch (Exception ex)
    {
        System.Diagnostics.Debug.WriteLine(
            &quot;Error (DownloadStringCompleted) : &quot; &#43; ex.Message);
    }
}
</pre></p><h2>Conclusion</h2><p>This was a really interesting project. Not only did it help me understand how much energy I was using (and help me reduce it), it also presented a software challenge covering a number of areas and technologies: Windows Service, WCF, Windows Phone 7, and javascript/jQuery.</p><p>I already have plans for a number of other plugins and new ways to visualize the usage data—keep an eye on the Codeplex site for updates.</p><p>If you want to try this out, the download link for the source code is at the top of the article!</p><h2>About The Author</h2><p>Ken Hughes is Chief Technical Officer at C2C Systems, a Microsoft Gold Partner ISV. He is passionate about technology, productivity, and automating <em>everything</em>. He stays up-to-date with and keeps his hand in new technologies by working on personal and open source projects such as <a href="http://www.dasblog.info/">dasBlog</a>. Contact information may be found on both his <a href="http://www.kapie.com">blog</a> and <a href="http://twitter.com/kjhughes">Twitter</a>.</p> <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Tags/home+automation/RSS&WT.dl=0&WT.entryid=Entry:RSSView:1d96a54fcf5c453abbe69e7600c88559">]]></description>
      <comments>http://channel9.msdn.com/coding4fun/articles/Home-Energy-Monitoring</comments>
      <itunes:summary> Recently, the noise from the multiple servers running in the garage, the enormous energy bills, and my general sense of “I should do more to save the planet” outweighed my procrastination and led me to take action and reduce my energy consumption. My first step was buying an Energy Monitor. After looking at a few different models, I spotted one with a USB cable that would allow me to “send the readings to a home PC.” Ohh! I could do something with the data instead of just looking at it on a handheld monitor. Interesting…  Getting StartedThe first thing to do is install the monitor and the next thing is to install the drivers for the USB cable—these allow the USB connection to present itself as a COM port and make it easy to interact with.  Next, test the basic functionality. To do this (and to see the data transfer in action) you will need a Terminal client. Open your terminal software, set the COM port to whatever the USB Cable driver surfaced as (typically COM 3), set the baud rate to 57600bps, 8 data bits, “none” for parity, 1 stop bit, and no handshaking. When you “open” the COM port you should now see an Xml string being received every six seconds (for example): HTML&amp;lt;msg&amp;gt;
   &amp;lt;src&amp;gt;CC128-v0.11&amp;lt;/src&amp;gt;
   &amp;lt;dsb&amp;gt;00089&amp;lt;/dsb&amp;gt;
   &amp;lt;time&amp;gt;13:02:39&amp;lt;/time&amp;gt;
   &amp;lt;tmpr&amp;gt;18.7&amp;lt;/tmpr&amp;gt;
   &amp;lt;sensor&amp;gt;1&amp;lt;/sensor&amp;gt;
   &amp;lt;id&amp;gt;01234&amp;lt;/id&amp;gt;
   &amp;lt;type&amp;gt;1&amp;lt;/type&amp;gt;
   &amp;lt;ch1&amp;gt;
      &amp;lt;watts&amp;gt;00345&amp;lt;/watts&amp;gt;
   &amp;lt;/ch1&amp;gt;
   &amp;lt;ch2&amp;gt;
      &amp;lt;watts&amp;gt;02151&amp;lt;/watts&amp;gt;
   &amp;lt;/ch2&amp;gt;
   &amp;lt;ch3&amp;gt;
      &amp;lt;watts&amp;gt;00000&amp;lt;/watts&amp;gt;
   &amp;lt;/ch3&amp;gt;
&amp;lt;/msg&amp;gt;
 The format of the Xml data can be found in this document, available on the CurrentCost website. Project Outline / DesignThinking about the project outline and design, I knew that I wanted to be able to make the received data readings available to multiple applications and websites. I also wanted to be able to tweet my e</itunes:summary>
      <link>http://channel9.msdn.com/coding4fun/articles/Home-Energy-Monitoring</link>
      <pubDate>Mon, 27 Sep 2010 14:43:11 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/coding4fun/articles/Home-Energy-Monitoring</guid>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/c4f/images/10068304_100.jpg" height="75" width="100"></media:thumbnail>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/c4f/images/10068304_220.jpg" height="165" width="220"></media:thumbnail>      
      <dc:creator>Ken Hughes </dc:creator>
      <itunes:author>Ken Hughes </itunes:author>
      <slash:comments>0</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/coding4fun/articles/Home-Energy-Monitoring/RSS</wfw:commentRss>
      <category>Hardware</category>
      <category>jQuery</category>
      <category>Windows Phone 7</category>
      <category>WP7</category>
      <category>Home Automation</category>
    </item>
  <item>
      <title>Shutdown/Restart/Logoff your PC using TweetMyPC</title>
      <description><![CDATA[
<p>In this article I will show you how you can use Twitter API to Shutdown/Restart/Logoff your PC remotely using VB.net.</p>
<h3>Introduction</h3>
<p>I have a very slow internet connection at home and most of the time Downloads takes hours to complete. I decided to write an application which will help me Shutdown my PC from a remote location. I wanted to use it to shutdown when I go out when some downloading
 is going on in my laptop. Instead of using a server and client architecture I decided to use Twitter API and use “My Timeline” to supply commands. One other reason to use Twitter is that I will be able to tweet from my mobile as well. I don't need to look
 for a computer with an internet connection when I am on the move.</p>
<h4>Why Yedda Twitter framework?</h4>
<p>The <a href="http://apiwiki.twitter.com/Twitter-API-Documentation">Twitter REST API</a> methods allow developers to access core Twitter data. This includes update timelines, status data, and user information. It's very easy to connect to Twitter and get
 user time line using .net. But I dint wanted to reinvent wheel and decided to use an existing Twitter library. Yedda Twitter framework is the best open source Twitter library available in the internet. You can learn more and download the library from
<a href="http://devblog.yedda.com/index.php/2007/05/16/twitter-c-library/">yedda's home page</a>.</p>
<h4>Designing the Interface</h4>
<p>I wanted the interface to be as simple as possible. Below is the screenshot of TweetMyPC's interface which does not have more than 2 Text Boxes, 1 Check Box, Label and a Button.</p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/9709252/clip_image001_2.jpg"><img title="clip_image001" border="0" alt="clip_image001" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/9709252/clip_image001_thumb.jpg" width="288" height="250"></a></p>
<p>The form also has a Notify Icon, Context Menu Strip and a Timer. Following are the names of all the controls in the form.</p>
<ul>
<li>From : <b>frmTweetMyPc</b> </li><li>Text Boxes : <b>txtUserName</b>, <b>txtPassword</b> </li><li>Button : <b>btnSave</b> </li><li>Check Box : <b>chkStartAutomatic</b> </li><li>Timer : <b>tmrTweet</b> (Interval : 10000) </li><li>Label : <b>lblSatus</b> </li></ul>
<p>There are few <a href="http://msdn.microsoft.com/en-us/library/saa62613(VS.80).aspx">
My.settings</a> properties to store user information. These properties are shown below.</p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/9709252/clip_image002_2.jpg"><img title="clip_image002" border="0" alt="clip_image002" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/9709252/clip_image002_thumb.jpg" width="388" height="139"></a></p>
<p><b>The Code</b><b> <br>
</b>Add the following code which minimizes the Form on Load and Enable Timer to check for Tweets every 1 minute.
</p>
<pre class="csharpcode"><span class="kwrd">Me</span>.WindowState = FormWindowState.Minimized
<span class="kwrd">Me</span>.ShowInTaskbar = <span class="kwrd">False</span>
tmrTweet.Enabled = True</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p></p>
<p>The following code in Button's Click event will validate Twitter username, Password and save it to My.Settings.</p>
<pre class="csharpcode"><span class="kwrd">If</span> txtUserName.Text.Trim = <span class="str">&quot;&quot;</span> <span class="kwrd">Then</span>
    lblSatus.Text = <span class="str">&quot;Please enter Twitter Username&quot;</span>
    txtUserName.Focus()
    <span class="kwrd">Exit</span> <span class="kwrd">Sub</span>
<span class="kwrd">End</span> <span class="kwrd">If</span>
<span class="kwrd">If</span> txtPassword.Text.Trim = <span class="str">&quot;&quot;</span> <span class="kwrd">Then</span>
    lblSatus.Text = <span class="str">&quot;Please enter Twitter Password&quot;</span>
    txtPassword.Focus()
    <span class="kwrd">Exit</span> <span class="kwrd">Sub</span>
<span class="kwrd">End</span> <span class="kwrd">If</span>

lblSatus.Text = <span class="str">&quot;&quot;</span>


<span class="rem">'Check for valid Username and Password and then Save Settings</span>
<span class="kwrd">Dim</span> objTwitter <span class="kwrd">As</span> <span class="kwrd">New</span> Yedda.Twitter
<span class="kwrd">Dim</span> Updates <span class="kwrd">As</span> XmlDocument

<span class="kwrd">Try</span> <span class="rem">'Try Logging in</span>
    Updates = objTwitter.GetUserTimelineAsXML(txtUserName.Text.Trim, txtPassword.Text.Trim)
    My.Settings.UserName = txtUserName.Text.Trim
    My.Settings.Password = txtPassword.Text.Trim
    <span class="kwrd">Me</span>.WindowState = FormWindowState.Minimized
    <span class="kwrd">Me</span>.ShowInTaskbar = <span class="kwrd">False</span>
    tmrTweet.Enabled = <span class="kwrd">True</span>
<span class="kwrd">Catch</span> ex <span class="kwrd">As</span> Exception
    MsgBox(<span class="str">&quot;Failed to Login to Twitter with the values supplied. Please check your login details.&quot;</span>)
    txtUserName.Focus()
    <span class="kwrd">Exit</span> <span class="kwrd">Sub</span>
<span class="kwrd">End</span> Try</pre>
<p>Yedda library is used to login to Twitter to check for valid username and password. The Label
<b>lblSatus</b> is used to display any error messages.</p>
<p>Add the following code to the Checkbox's <strong>CheckChanged</strong> event which will add the required registry keys to start this app on Window's startup</p>
<pre class="csharpcode"><span class="kwrd">If</span> chkStartAutomatic.Checked = <span class="kwrd">True</span> <span class="kwrd">Then</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; My.Settings.AutomaticStart = <span class="kwrd">True</span>
      <span class="kwrd">Dim</span> regKey <span class="kwrd">As</span> RegistryKey
      regKey = Registry.CurrentUser.OpenSubKey(<span class="str">&quot;Software\Microsoft\Windows\CurrentVersion\Run&quot;</span>, <span class="kwrd">True</span>)
      regKey.SetValue(Application.ProductName, Application.ExecutablePath)
      regKey.Close()
<span class="kwrd">Else</span>
      My.Settings.AutomaticStart = <span class="kwrd">False</span>
      <span class="kwrd">Dim</span> regKey <span class="kwrd">As</span> RegistryKey
      regKey = Registry.CurrentUser.OpenSubKey(<span class="str">&quot;Software\Microsoft\Windows\CurrentVersion\Run&quot;</span>, <span class="kwrd">True</span>)
      regKey.DeleteValue(Application.ProductName)
      regKey.Close()
<span class="kwrd">End</span> If</pre>
<p>The following code in Timer's Tick event will do the job of checking Twitter Timeline every one minute and Shutdown/Restart/Log off the system based on the Tweet.</p>
<pre class="csharpcode"><span class="kwrd">If</span> My.Settings.UserName.Trim = <span class="str">&quot;&quot;</span> <span class="kwrd">Then</span>
    <span class="kwrd">Exit</span> <span class="kwrd">Sub</span>
<span class="kwrd">Else</span>
    <span class="rem">'Check for new Tweet </span>
    <span class="kwrd">Dim</span> objTwitter <span class="kwrd">As</span> <span class="kwrd">New</span> Yedda.Twitter
    <span class="kwrd">Dim</span> Updates <span class="kwrd">As</span> XmlDocument
    <span class="kwrd">Dim</span> node <span class="kwrd">As</span> XmlNode
    <span class="kwrd">Try</span> <span class="rem">'Try Logging in</span>
        Updates = objTwitter.GetUserTimelineAsXML(My.Settings.UserName.Trim, My.Settings.Password.Trim)
        <span class="kwrd">Catch</span> ex <span class="kwrd">As</span> Exception
        MsgBox(<span class="str">&quot;Error : Failed to Login to Twitter with the values supplied. Please check your login details.&quot;</span>)
        <span class="kwrd">Exit</span> <span class="kwrd">Sub</span>
    <span class="kwrd">End</span> <span class="kwrd">Try</span>
    <span class="kwrd">Try</span>
        node = Updates.SelectSingleNode(<span class="str">&quot;/statuses/status/id&quot;</span>)
        <span class="kwrd">If</span> node.InnerText.Trim &lt;&gt; My.Settings.LastID.Trim <span class="kwrd">Then</span> 
            <span class="rem">'Compare the Tweet ID to check for new tweets</span>
            My.Settings.LastID = node.InnerText.Trim
            node = Updates.SelectSingleNode(<span class="str">&quot;/statuses/status/text&quot;</span>)
            ProcessTweet(node.InnerText.Trim)
          <span class="kwrd">End</span> <span class="kwrd">If</span>
    <span class="kwrd">Catch</span> ex <span class="kwrd">As</span> Exception
        <span class="kwrd">Exit</span> <span class="kwrd">Sub</span>
    <span class="kwrd">End</span> <span class="kwrd">Try</span>
<span class="kwrd">End</span> If</pre>
<p>If the Tweet is new then we process the tweet.</p>
<pre class="csharpcode"><span class="kwrd">Private</span> <span class="kwrd">Sub</span> ProcessTweet(<span class="kwrd">ByVal</span> Tweet <span class="kwrd">As</span> <span class="kwrd">String</span>)
    <span class="kwrd">If</span> Tweet = <span class="str">&quot;Shutdown&quot;</span> <span class="kwrd">Then</span>
        System.Diagnostics.Process.Start(<span class="str">&quot;shutdown&quot;</span>, <span class="str">&quot;-s -f -t 100&quot;</span>) <span class="rem">'Shutdown</span>
    <span class="kwrd">ElseIf</span> Tweet = <span class="str">&quot;Logoff&quot;</span> <span class="kwrd">Then</span>
        System.Diagnostics.Process.Start(<span class="str">&quot;shutdown&quot;</span>, <span class="str">&quot;-l -f -t 100&quot;</span>) <span class="rem">'Logoff</span>
    <span class="kwrd">ElseIf</span> Tweet = <span class="str">&quot;Restart&quot;</span> <span class="kwrd">Then</span>
        System.Diagnostics.Process.Start(<span class="str">&quot;shutdown&quot;</span>, <span class="str">&quot;-r -f -t 100&quot;</span>) <span class="rem">' Restart</span>
    <span class="kwrd">End</span> <span class="kwrd">If</span>
<span class="kwrd">End</span> Sub</pre>
<p>The Context Menu strip has two menu items. They are Edit Setting and Exit.</p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/9709252/clip_image003_2.jpg"><img title="clip_image003" border="0" alt="clip_image003" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/9709252/clip_image003_thumb.jpg" width="292" height="253"></a></p>
<p>Add the following code the “Edit Settings” Client event and Notify Icon's Mouse Double Click Event.
</p>
<pre class="csharpcode">tmrTweet.Enabled = <span class="kwrd">False</span>
txtUserName.Text = My.Settings.UserName.Trim
txtPassword.Text = My.Settings.Password.Trim
<span class="kwrd">If</span> My.Settings.AutomaticStart = <span class="kwrd">True</span> <span class="kwrd">Then</span> chkStartAutomatic.Checked = <span class="kwrd">True</span>
<span class="kwrd">Me</span>.WindowState = FormWindowState.Normal
<span class="kwrd">Me</span>.ShowInTaskbar = True</pre>
<p>TweetMyPC runs silently on startup. To Edit Settings double click/Right Click the notify icon.</p>
<h4>Working</h4>
<div id="scid:5737277B-5D6D-4f48-ABFC-DD9C333F4C5D:60558cb3-f672-4422-85cf-fea80c9effce" class="wlWriterEditableSmartContent">
<div id="28e191ed-c541-4d5a-85ef-992feaf927fd">
<div><a href="http://www.youtube.com/watch?v=yPxd2IwWjoU" target="_new"><img src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/9709252/video770b8dbba191.jpg" alt=""></a></div>
</div>
</div>
<h3>Conclusion</h3>
<p>Even though TweetMyPC is a simple app it has lot of interesting potential. Think about switching off your TV or washing machine using Twitter. It is possible with a little extra hardware and a simple .net program. TweetMyPC is free and open source. Feel
 free to download the sour code and add more functionality.</p>
<h3>About The Author</h3>
<p>Shoban Kumar is a Senior Software Engineer working for Allianz Cornhill India. Programming is his passion. He also writes about .net in
<a href="http://www.dotnetcurry.com/">http://www.dotnetcurry.com/</a> and an active participator in
<a href="http://stackoverflow.com/users/12178/shoban">stackoverflow</a> and speaker in
<a href="http://k-mug.org/">Microsoft user group</a> sessions. You also can follow him in
<a href="http://twitter.com/shobankr">Twitter</a>.</p>
 <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Tags/home+automation/RSS&WT.dl=0&WT.entryid=Entry:RSSView:4081804374e84ff6a1939e7600cc2876">]]></description>
      <comments>http://channel9.msdn.com/coding4fun/articles/ShutdownRestartLogoff-your-PC-using-TweetMyPC</comments>
      <itunes:summary>
In this article I will show you how you can use Twitter API to Shutdown/Restart/Logoff your PC remotely using VB.net. 
Introduction
I have a very slow internet connection at home and most of the time Downloads takes hours to complete. I decided to write an application which will help me Shutdown my PC from a remote location. I wanted to use it to shutdown when I go out when some downloading
 is going on in my laptop. Instead of using a server and client architecture I decided to use Twitter API and use “My Timeline” to supply commands. One other reason to use Twitter is that I will be able to tweet from my mobile as well. I don&#39;t need to look
 for a computer with an internet connection when I am on the move. 
Why Yedda Twitter framework?
The Twitter REST API methods allow developers to access core Twitter data. This includes update timelines, status data, and user information. It&#39;s very easy to connect to Twitter and get
 user time line using .net. But I dint wanted to reinvent wheel and decided to use an existing Twitter library. Yedda Twitter framework is the best open source Twitter library available in the internet. You can learn more and download the library from
yedda&#39;s home page. 
Designing the Interface
I wanted the interface to be as simple as possible. Below is the screenshot of TweetMyPC&#39;s interface which does not have more than 2 Text Boxes, 1 Check Box, Label and a Button. 
 
The form also has a Notify Icon, Context Menu Strip and a Timer. Following are the names of all the controls in the form. 

From : frmTweetMyPc Text Boxes : txtUserName, txtPassword Button : btnSave Check Box : chkStartAutomatic Timer : tmrTweet (Interval : 10000) Label : lblSatus 
There are few 
My.settings properties to store user information. These properties are shown below. 
 
The Code 
Add the following code which minimizes the Form on Load and Enable Timer to check for Tweets every 1 minute.
 
Me.WindowState = FormWindowState.Minimized
Me.ShowInTaskbar = False
tmrTweet.Enab</itunes:summary>
      <link>http://channel9.msdn.com/coding4fun/articles/ShutdownRestartLogoff-your-PC-using-TweetMyPC</link>
      <pubDate>Tue, 23 Jun 2009 16:01:00 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/coding4fun/articles/ShutdownRestartLogoff-your-PC-using-TweetMyPC</guid>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/c4f/images/9709252_100.jpg" height="75" width="100"></media:thumbnail>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/c4f/images/9709252_220.jpg" height="165" width="220"></media:thumbnail>      
      <dc:creator>Shoban Kumar </dc:creator>
      <itunes:author>Shoban Kumar </itunes:author>
      <slash:comments>10</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/coding4fun/articles/ShutdownRestartLogoff-your-PC-using-TweetMyPC/RSS</wfw:commentRss>
      <category>utility</category>
      <category>Windows</category>
      <category>Home Automation</category>
    </item>
  <item>
      <title>Controlling Your Festive Lights with the .NET Micro Framework</title>
      <description><![CDATA[
<table class="" cellspacing="0" cellpadding="2" width="470" border="0">
<tbody>
<tr>
</tr>
<tr>
<td class="" valign="top" width="105"><strong>Author:</strong></td>
<td class="" valign="top" width="363">Rob Miles: <a href="http://www.robmiles.com">
www.robmiles.com</a> </td>
</tr>
<tr>
<td class="" valign="top" width="105"><strong>Download:</strong></td>
<td class="" valign="top" width="363"><a title="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/9149635/festivelights1.0.zip" href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/9149635/festivelights1.0.zip">Download</a></td>
</tr>
<tr>
<td class="" valign="top" width="105"><strong>Software:</strong></td>
<td class="" valign="top" width="363">Visual Studio 2008 Express Edition or better,
<br>
<a href="http://www.microsoft.com/netmf/about/gettingstarted.mspx">.NET Micro Framework 3.0</a></td>
</tr>
<tr>
<td class="" valign="top" width="105"><strong>Hardware:</strong></td>
<td class="" valign="top" width="363"><a href="http://www.digi.com/products/embeddedsolutions/digiconnectme.jsp">Digi Connect-ME</a>
<br>
<a href="http://www.ghielectronics.com/embeddedmaster.php">GHI Electronics Embedded Master</a>
<br>
<a href="http://devicesolutions.net/Products/Tahoe.aspx">Devices Solutions Tahoe II
</a></td>
</tr>
<tr>
<td class="" valign="top" width="105"><strong>Time Required:</strong></td>
<td class="" valign="top" width="363">3 hours</td>
</tr>
<tr>
<td class="" valign="top" width="105"><strong>Cost:</strong></td>
<td class="" valign="top" width="363">30 dollars for lights plus the .NET Micro Framework device</td>
</tr>
</tbody>
</table>
<p>The Micro Framework is one of the newest kids on the .NET block, but it does something really rather wonderful. It brings embedded development within the reach of any C# programmer. If you know C# and love Visual Studio, you can now get started building
 hardware and controlling it with your software. Moreover, it lets developers achieve one of their most cherished dreams, to control their festive lights using programs that they have written. This project shows you how to do just that and adds an extra magical
 feature, in that you can make all your festive lights flash red whenever I, Rob Miles, make a new post on that most famous of blogs,
<a href="http://www.robmiles.com">www.robmiles.com</a>. </p>
<p>Actually, you can modify the code so that you can make your lights do most anything in response to an event that happens on the web. You could signal home that you are running late, send the weather forecast to your Christmas tree or explore any number of
 communication options. You might decide that this is so useful that you leave your decorations up all year round.</p>
<p>If you just want to play with the .NET Micro Framework and get a feel for how easy it is to create software for tiny devices you don't actually need to use any extra hardware at all. The project comes with a complete emulation of the lights display so that
 you can run the whole thing on your computer and learn how hardware and software can be made to work together without burning your fingers with a soldering iron.</p>
<p>However building the hardware will give you an understanding of how some simple electronic components can be controlled from C# and even how serial and parallel data transfer works. It is also great fun.</p>
<p>To get started you will need some hardware and some software. Let's take each in turn.</p>
<h1>Hardware</h1>
<h2>Processor Hardware</h2>
<p>The .NET Micro Framework lets you run C# programs on tiny embedded devices. There are a number of these available today, and they are getting progressively cheaper. You can base this project on any.NET Micro Framework device that has a network port and three
 or more output ports. The ones I'd recommend are:</p>
<ul>
<li>Digi Connect-ME: <a href="http://www.digi.com/products/embeddedsolutions/digiconnectme.jsp">
http://www.digi.com/products/embeddedsolutions/digiconnectme.jsp</a> </li><li>GHI Electronics Embedded Master: <a href="http://www.ghielectronics.com/embeddedmaster.php">
http://www.ghielectronics.com/embeddedmaster.php</a> </li><li>Devices Solutions Tahoe II: <a href="http://devicesolutions.net/Products/Tahoe.aspx">
http://devicesolutions.net/Products/Tahoe.aspx</a> </li></ul>
<p>I built the project for Digi Connect board but the code can be customised for any of the above platforms. The beauty of the .NET Micro Framework is that you hardly need to change your program even if the underlying hardware is completely replaced. The only
 thing you will have to do is adjust the code to target different output pins. I'll flag this part of the program up when we get to it.</p>
<p>The project as supplied runs on a special emulator that runs on the PC and behaves like a .NET Micro Framework device with lights connected, so you can get started exploring the code right away.</p>
<h2>Lights</h2>
<p>I'm keeping things deliberately low voltage for this project. This means that kids of all ages can have a go at building the hardware without messing around with mains. The lights that I used were supplied as lines of twenty leds wired up as four strands
 of five leds each. All the leds in each strand were the same colour. The lights were fitted with a little battery box which held three AA batteries and a tiny controller. To get my display I simply removed the battery box and connected the strands to my hardware.</p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/9149635/image.png"><img title="image" height="226" alt="image" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/9149635/image_thumb.png" width="324" border="0"></a>&nbsp;
<br>
<strong>Figure 1: My Battery Powered Lights</strong></p>
<p>You can do the same with any low power lighting kit that you wish to use. The drivers that I'm using can handle around 500 milliamps of continuous current and so you can connect a fair number of lights to each strand.
</p>
<h2>Buying the Lights</h2>
<p>The lights I used can be bought in the UK from Lights4Fun: www.lights4fun.co.uk and are called &quot;C-LED-4.5-M 20 Multi Coloured Battery Operated LED Fairy Lights&quot;. They are supplied with a battery box and controller that you can remove to connect to the Darlington
 drivers. I used an old 5 volt mobile phone charger to power the lights. If you search eBay for &quot;led christmas lights battery&quot; you should find plenty of suppliers.</p>
<h2>Driver Hardware</h2>
<p>We can't connect a .NET Micro Framework device directly to our lights. There are two reasons for this:</p>
<ol>
<li>The Micro Framework device will not be able to switch the amount of current that we need to drive the lights themselves.
</li><li>The Micro Framework device will not have enough outputs to control all the lights that we want to use.
</li></ol>
<p>This means that we need to make some hardware that goes between the processor and our lights. I actually don't see this as a problem. Making hardware is great fun, seeing something that you've built spring into life is very nice. The hardware we are going
 to use will provide a means by which we can control many hundreds of lights from a single Micro Framework board if we wish. It also has the ability to switch reasonable amounts of current, so you can use quite large numbers of lights if you wish. We are going
 to use two semiconductor components, a CD4094 Shift Register/Latch and a ULN2803 Octal Darlington Driver. A pair of these chips will allow us to control 8 outputs. If you want to control more outputs you simply get more chips and chain them together. For my
 version of the project I just used one of each chip, you can use as many as you like.The shift registers and Darlington amplifiers can be obtained in the UK from Maplin:
<a href="http://www.maplin.co.uk">www.maplin.co.uk</a>. The chip numbers and part numbers as are as follows: QW54J 4094 Shift Register, QY79L ULN2803A Darlington Driver. In the US you can obtain the components and breadboard from Digi-Key:
<a href="http://www.digikey.com">www.digikey.com</a>. </p>
<h2>Serial and Parallel Data</h2>
<p>You might be wondering how we can use just three output lines to control lots of lights. We are going to do this by using the three output lines to provide a
<i>serial</i> data stream which is converted by our hardware into <i>parallel</i> data that can be used to control our lights. This is a fundamental principle of digital electronics and is how, amongst many other things, computer networks transfer data.</p>
<p>We are going to use three signals which are called <b>clock</b>, <b>data</b> and
<b>latch</b>. Each of these can be set high (a voltage is present) or low (no voltage is present) by the .NET Micro Framework device under the control of our software. The signals are connected to the clock, data and latch inputs of our CD4094 shift register
 so that the program can talk to it.</p>
<p>The clock line triggers the shift register to do two things:</p>
<ol>
<li>Shift all the bits along to make room. </li><li>Sample the value of the data input and store this value in the space that was created.
</li></ol>
<p>To get a feel for how this works, take a look at Figure 2 below. It shows a shift register with a pattern of bits in it. The pattern is
<b>01100001</b>. Note that although this represents a number; it can also be regarded as a pattern of 0s and 1s in the shift register itself. The value 0 means 0 volts and the value 1 means some volts. These are the signals that will be used to control our
 lights. I'm going to call them 0 and 1 from now on. The Shift Register has Clock, Data and Latch signals connected and they are all set to 1. We can ignore the latch part of the chip for now.</p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/9149635/image_3.png"><img title="image" height="251" alt="image" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/9149635/image_thumb_3.png" width="500" border="0"></a>
</p>
<p><strong>Figure 2: A shift register and latch with some data in it</strong></p>
<p>When the clock signal changes from 1 to 0 this causes the shift register to perform the two steps described above. First the data is shifted along to the right. Note that this means that there is an &quot;empty&quot; location at the start of the register, and that
 the right most bit in the register &quot;falls off&quot; the register and disappears. Figure 3 shows how this works.</p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/9149635/image_4.png"><img title="image" height="236" alt="image" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/9149635/image_thumb_4.png" width="500" border="0"></a>
</p>
<p><strong>Figure 3: Shifting along the values in the shift register</strong></p>
<p>Once the shift has finished the shift register can copy the data signal into the empty bit at the left as shown in Figure 4 below.</p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/9149635/image_5.png"><img title="image" height="251" alt="image" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/9149635/image_thumb_5.png" width="500" border="0"></a>
<strong><br>
Figure 4: Storing the new data bit</strong></p>
<p>By repeating this process 8 times a program can load a new pattern of 8 bits into the shift register. Then it is time to latch the new value to control the lights. This is the point at which the lights will appear to change. When the latch value is changed
 from 0 to 1 this causes the chip to copy the value in the Shift Register into the latch, as shown in Figure 5 below.</p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/9149635/image_6.png"><img title="image" height="251" alt="image" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/9149635/image_thumb_6.png" width="500" border="0"></a>
</p>
<p><strong>Figure 5: Copying the shift register pattern into the latch.</strong></p>
<p>The latch is required so that the lights will not flicker as the new patterns are shifted into position. Each of the bits in the latch is connected to an output pin on the CD4094 which is used to switch a particular light colour on or off.</p>
<p>We need to create some C# that will provide the appropriate sequence of signals. It turns out that using the .NET Micro Framework to achieve this is actually very easy. The
<b>displayByte</b> method below sends an 8 bit value into a shift register and then latches it into the output. If you read through the code you can see how the clock, data and latch values are all set to true (high) or false (low) to first clock the data out
 and then trigger the latch to display the pattern on the lights. The input is an 8 bit byte value and the program uses a mask to pick out the value of each bit in turn and set the data output accordingly.</p>
<pre class="csharpcode"><span class="kwrd">private</span> <span class="kwrd">static</span> <span class="kwrd">void</span> displayByte(<span class="kwrd">byte</span> <span class="kwrd">value</span>)
{
    latchPort.Write(<span class="kwrd">false</span>);
    clockPort.Write(<span class="kwrd">false</span>);

    <span class="kwrd">byte</span> mask = 1;

    <span class="kwrd">for</span> (<span class="kwrd">int</span> i = 0; i &lt; 8; i&#43;&#43;)
    {
        <span class="kwrd">if</span> ((<span class="kwrd">value</span> &amp; mask) &gt; 0)
        {
            dataPort.Write(<span class="kwrd">true</span>);
        }
        <span class="kwrd">else</span>
        {
            dataPort.Write(<span class="kwrd">false</span>);
        }
        clockPort.Write(<span class="kwrd">true</span>);
        clockPort.Write(<span class="kwrd">false</span>);
        mask &lt;&lt;= 1;
    }
    latchPort.Write(<span class="kwrd">true</span>);
    latchPort.Write(<span class="kwrd">false</span>);
}</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>The <b>dataPort</b>, <b>clockPort</b> and <b>latchPort</b> variables are instances of the .NET Micro Framework class
<b>OutputPort</b>, which provides a method called <b>Write</b> which can be used to control the state of the output signal. We will consider how these are created a little later in the article.</p>
<p>The sample code for this project comes with a software emulator of the CD4094 which shows how it works. Figure 6 below shows that a new pattern is in the process of being shifted into the shift register, while the lights retain the previous one in the latch.
 The Clock and Data signals are high and the next statement will drop the Clock signal to add the next bit into the new pattern.</p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/9149635/image_7.png"><img title="image" height="303" alt="image" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/9149635/image_thumb_7.png" width="264" border="0"></a>
</p>
<p><strong>Figure 6: The light emulator</strong></p>
<p>This figure also shows that I have two bits in the pattern controlling a strand of each colour. You can single step through the displayByte method above and watch it perform this output.</p>
<p>You can use this technique every time you want to control a large number of outputs using a small number of output pins. The CD4094 has &quot;daisy chain&quot; inputs and outputs so that the devices can be connected in sequence. If I used two devices I could control
 16 bits, with three I could control 24 and so on. This would require only minimal changes to the software.</p>
<h2>Output Driver</h2>
<p>The CD4094 device will produce a signal output, but it is not really powerful enough to drive things like lights. To do this we need an amplifier and the ULN2803 Octal Darlington Driver is perfect for this. It is packaged as a single chip which contains
 8 pairs of transistors. Each transistor pair is wired in a &quot;Darlington&quot; configuration and can be used as a switch which is controlled by on output from the CD4094. When the transistors are turned on they allow current to pass through them and this will cause
 the lamps to light. The lights that I bought used a &quot;pull down&quot; arrangement to make them light up. All of the light emitting diode (LED) lamps had one end wired to a common line that was connected to the positive supply. To make the a chain of LEDs light the
 other end that controls that chain needed to be pulled down to the ground level. This is a common arrangement with lights like these. The ULN2803 driver has the transistors wired in an arrangement that allows it to pull signals low in this way. Figure 7 shows
 how this arrangement works. The resistor shown is actually wired into each LED in the set of lights that I used.</p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/9149635/image_8.png"><img title="image" height="201" alt="image" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/9149635/image_thumb_8.png" width="226" border="0"></a>
<br>
<strong>Figure 7: Lighting the LEDs</strong></p>
<h5>Complete Circuit</h5>
<p>The complete circuit shown in Figure 8 simply links each output of the CD4094 shift register to an input on the ULN2803 Darlington Driver. Note that there is no reason to link any particular bit with any other, the diagram shown is one which will translate
 most easily to a prototype &quot;breadboard&quot;.</p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/9149635/image_9.png"><img title="image" height="260" alt="image" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/9149635/image_thumb_9.png" width="500" border="0"></a>
<br>
<strong>Figure 8: The Complete Circuit</strong></p>
<p>The diagram just shows four lights connected to OUT1 from pin 18 of the ULN2803, the other 7 channels are connected in exactly the same way. Some of the pins can be left unconnected. Pins 9 and 10 of the CD4094 are only required if you are connecting multiple
 shift registers together and the common connection on pin 10 of the ULN2803 is not required. The Latch, Data and Clock signals on the CD4094 are connected to the output signals from the Micro Framework device.
</p>
<p>Figure 9 shows the completed circuit built up on a prototype breadboard. The chip on the left is the CD4094 and the one on the right is the ULN2803.</p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/9149635/image_10.png"><img title="image" height="331" alt="image" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/9149635/image_thumb_10.png" width="484" border="0"></a>
<strong><br>
Figure 9: The Completed Circuit</strong></p>
<p>The red wires carry the positive voltage from the power supply, which is connected to the top left of the circuit. The green wires are ground. Other coloured wires are used for signals. The Clock, Latch and Data signals are brought out to a connector which
 will fit a Digi-ME prototyping board.</p>
<h2>Selecting Lights</h2>
<p>Each bit in the value sent to the <b>displayByte</b> method and then into the shift register will be mapped to a particular chain of lights. The mapping of these is not particularly important, since you can use program constants to represent particular values.
 I wired the red signals to output pins 4 and 8. To light up just the red lights I used the value 0x88 which is the appropriate bit pattern. I then set up constants for all the other colors:</p>
<pre class="csharpcode"><span class="kwrd">const</span> <span class="kwrd">byte</span> GREEN = 0x11;
<span class="kwrd">const</span> <span class="kwrd">byte</span> BLUE = 0x22;
<span class="kwrd">const</span> <span class="kwrd">byte</span> YELLOW = 0x44;
<span class="kwrd">const</span> <span class="kwrd">byte</span> RED = 0x88;</pre>
<h2>Setting Up the Hardware</h2>
<p>The .NET Micro Framework provides a set of classes that can be used to represent the hardware in a system. The program uses instances of the
<b>OutputPort</b> class to represent the output pins. These are created in the method that sets up the hardware:</p>
<pre class="csharpcode"><span class="kwrd">const</span> Cpu.Pin clockPin = Cpu.Pin.GPIO_Pin0;
<span class="kwrd">const</span> Cpu.Pin dataPin = Cpu.Pin.GPIO_Pin1;
<span class="kwrd">const</span> Cpu.Pin latchPin = Cpu.Pin.GPIO_Pin2;

<span class="kwrd">static</span> OutputPort clockPort;
<span class="kwrd">static</span> OutputPort dataPort;
<span class="kwrd">static</span> OutputPort latchPort;

<span class="kwrd">private</span> <span class="kwrd">static</span> <span class="kwrd">void</span> setupOutputs()
{
    clockPort = <span class="kwrd">new</span> OutputPort(clockPin, <span class="kwrd">false</span>);
    dataPort = <span class="kwrd">new</span> OutputPort(dataPin, <span class="kwrd">false</span>);
    latchPort = <span class="kwrd">new</span> OutputPort(latchPin, <span class="kwrd">false</span>);
}</pre>
<p>In this version of the hardware I have connected pin 0 of the processor to the clock, pin 1 to the data and pin 2 to the latch. If you use different pins you can change the settings above.</p>
<h1>Software</h1>
<p>Now that we have working hardware we can consider how the software is to work. Note that this version of the program works correctly but lacks exception handlers that would make it truly robust. I've left these out to simplify the explanation. To make sense
 of this description you will need to have a copy of the program itself available for reference.</p>
<p>You can develop the code using Visual Studio 2008 Express edition, which you can download from
<a href="http://www.microsoft.com/express/">http://www.microsoft.com/express/</a>
</p>
<p>The software is written for the .NET Micro Framework 3.0 which you can download from
<a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=9356ed6f-f1f0-43ef-b21a-4644dd089b4a&amp;displaylang=en">
http://www.microsoft.com/downloads/details.aspx?FamilyID=9356ed6f-f1f0-43ef-b21a-4644dd089b4a&amp;displaylang=en</a>
</p>
<h2>Reading the Blog</h2>
<p>The program reads the RSS feed from a blog and looks for the <b>&lt;pubDate&gt;</b> value. This contains the date when the feed was last updated. Whenever this date changes the lights must flash red for a few seconds before resuming a random display. Users of
 the full .NET Framework can use the <b>HTTPRequest</b> class to build a <b>GET</b> command to be sent to a server. Unfortunately the .NET Micro Framework does not support this, so we have to access the web feed using socket based communication. This part of
 the program is heavily based on the <b>SocketClient</b> example supplied with the .NET Micro Framework.</p>
<pre class="csharpcode"><span class="rem">// This method requests a page from the specified server.</span>
<span class="kwrd">private</span> <span class="kwrd">static</span> String GetWebPage(String server, <span class="kwrd">string</span> webPage)
{
    <span class="kwrd">const</span> Int32 c_httpPort = 80;
    <span class="kwrd">const</span> Int32 c_microsecondsPerSecond = 1000000;

    <span class="rem">// Create a socket connection to the specified server and port.</span>
    <span class="kwrd">using</span> (Socket serverSocket = ConnectSocket(server, c_httpPort))
    {
        <span class="rem">// Send request to the server.</span>
        String request = <span class="str">&quot;GET &quot;</span>&#43; webPage &#43; 
             <span class="str">&quot; HTTP/1.1\r\nHost: &quot;</span> &#43; server &#43; 
             <span class="str">&quot;\r\nConnection: Close\r\n\r\n&quot;</span>;
        Byte[] bytesToSend = Encoding.UTF8.GetBytes(request);
        serverSocket.Send(bytesToSend, bytesToSend.Length, 0);

        <span class="rem">// Allocate a buffer to receive HTML chunks</span>
        Byte[] buffer = <span class="kwrd">new</span> Byte[1024];

        <span class="rem">// 'page' refers to the HTML data as it is built up.</span>
        String page = String.Empty; 

        <span class="rem">// Wait up to 30 seconds for initial data </span>
        <span class="rem">// Will throw exception if connection closed</span>
        DateTime timeoutAt = DateTime.Now.AddSeconds(30);
        <span class="kwrd">while</span> (serverSocket.Available == 0 &amp;&amp; 
               DateTime.Now &lt; timeoutAt)
        {
            System.Threading.Thread.Sleep(100);
        }

        <span class="rem">// Poll for data until 30 second time out</span>
        <span class="rem">// Returns true for data and connection closed</span>
        <span class="kwrd">while</span> (serverSocket.Poll(30 * c_microsecondsPerSecond,
                                 SelectMode.SelectRead))
        {
            <span class="rem">// Zero all bytes in the re-usable buffer</span>
            Array.Clear(buffer, 0, buffer.Length);

            <span class="rem">// Read a buffer-sized HTML chunk</span>
            Int32 bytesRead = serverSocket.Receive(buffer);

            <span class="rem">// If 0 bytes in buffer, then connection is closed, </span>
            <span class="rem">// or we have timed out</span>
            <span class="kwrd">if</span> (bytesRead == 0)
                <span class="kwrd">break</span>;

            <span class="rem">// Append the chunk to the string</span>
            page &#43;= <span class="kwrd">new</span> String(Encoding.UTF8.GetChars(buffer));
        }

        <span class="kwrd">return</span> page;   <span class="rem">// Return the complete string</span>
    }
}</pre>
<p>This method is called to fetch the journal RSS feed from my blog:</p>
<pre class="csharpcode"><span class="kwrd">string</span> address = <span class="str">&quot;www.robmiles.com&quot;</span>;
<span class="kwrd">string</span> name = <span class="str">&quot;/journal/rss.xml&quot;</span>;

<span class="kwrd">string</span> html = GetWebPage(address, name);</pre>
<p>You can use it to download from any RSS feed or page on the web. It will throw an exception if the page cannot be read. This version of my program does not perform exception handling however.</p>
<h2>Getting the Published Date</h2>
<p>The date is held in the form:</p>
<pre class="csharpcode"><span class="kwrd">&lt;</span><span class="html">pubDate</span><span class="kwrd">&gt;</span>Wed, 05 Nov 2008 22:38:52 &#43;0000<span class="kwrd">&lt;/</span><span class="html">pubDate</span><span class="kwrd">&gt;</span></pre>
<p>It would be enough just to record this content and check for changes in the text, but I decided that I might want to use the date information in a later version of the program and so I created some small helper methods to read numbers from the input string
 and a larger method to read the publish date itself:</p>
<pre class="csharpcode"><span class="kwrd">private</span> <span class="kwrd">static</span> DateTime getRecentPubDate(<span class="kwrd">string</span> html, <span class="kwrd">string</span> startTag)
{
    <span class="kwrd">int</span> index = html.IndexOf(startTag) ;

    <span class="kwrd">if</span> (index &lt; 0) 
        <span class="kwrd">throw</span> <span class="kwrd">new</span> Exception(<span class="str">&quot;Missing tag &quot;</span> &#43; startTag);

    index &#43;= startTag.Length;

    <span class="rem">// spin past the name of the day</span>
    <span class="kwrd">while</span> (index &lt; html.Length &amp;&amp; html[index] != <span class="str">','</span>) index&#43;&#43;;
    <span class="kwrd">if</span> (index == html.Length) 
        <span class="kwrd">throw</span> <span class="kwrd">new</span> Exception(<span class="str">&quot;Short publish date&quot;</span>);

    <span class="kwrd">int</span> dayValue = getInt(html, <span class="kwrd">ref</span> index, <span class="str">' '</span>);

    <span class="kwrd">string</span> monthName = getString(html, <span class="kwrd">ref</span> index, <span class="str">' '</span>);
    <span class="kwrd">int</span> monthValue = getMonth(monthName);

    <span class="kwrd">int</span> yearValue = getInt(html, <span class="kwrd">ref</span> index, <span class="str">' '</span>);
    <span class="kwrd">int</span> hourValue = getInt(html, <span class="kwrd">ref</span> index, <span class="str">':'</span>);
    <span class="kwrd">int</span> minuteValue = getInt(html, <span class="kwrd">ref</span> index, <span class="str">':'</span>);
    <span class="kwrd">int</span> secondValue = getInt(html, <span class="kwrd">ref</span> index, <span class="str">' '</span>);

    <span class="kwrd">return</span> <span class="kwrd">new</span> DateTime(yearValue, monthValue, dayValue, 
                        hourValue, minuteValue, secondValue);
}</pre>
<p>The main body of the program uses this method to extract the date out of the RSS feed. When a new date is found it is time to update the lights.</p>
<h2>Lights and Threads</h2>
<p>My first version of the program flashed the lights for a while and then checked to see if a new blog post had been made. This worked OK, but the process of loading the RSS feed from the server and checking the dates can take a few seconds, which meant that
 the flashing lights would freeze every now and then. This did not look very good, and so I decided to use two threads instead. One is in charge of flashing the lights in a random pattern and the other loads the RSS feed from my blog and checks the date of
 the most recent publication. </p>
<p>Note that the threading I am using is exactly the same as threading in the full .NET Framework.
</p>
<h2>Thread Communication</h2>
<p>The two threads communicate by means of a single boolean variable which is set to true when the blog alert is to take place. The display thread reads this flag and flashes the lights red if it is time to alert.
</p>
<pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">static</span> <span class="kwrd">bool</span> alert = <span class="kwrd">false</span>;

<span class="kwrd">public</span> <span class="kwrd">static</span> <span class="kwrd">void</span> flasher()
{
    setupOutputs();

    <span class="kwrd">while</span> (<span class="kwrd">true</span>)
    {
        randomDisplay(400, 10);
        <span class="kwrd">if</span> (alert)
        {
            alert = <span class="kwrd">false</span>;
            flashRed(600, 20);
        }
    }
}</pre>
<p>The methods <b>randomDisplay</b> and <b>flashRed</b> do exactly what you would expect. Each of them gets two numbers to control the lights. The first number gives the delay in milliseconds between flashes (a few hundred milliseconds giving best results).
 The second gives the number of times that the lights should be flashed before the method finishes.
<b>RandomDisplay</b> displays random colors, whereas <b>flashRed</b> is simply flashes the red lights. The
<b>alert</b> flag is cleared before the red lights are flashed so that the system will resume normal display after the alert.</p>
<p>The second thread in the system performs the blog download and date test behaviour. This all happens inside the
<b>Main</b> method:</p>
<pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">static</span> <span class="kwrd">void</span> Main()
{
    flashThread = <span class="kwrd">new</span> System.Threading.Thread(flasher);

    flashThread.Start();

    <span class="kwrd">string</span> address = <span class="str">&quot;www.robmiles.com&quot;</span>;
    <span class="kwrd">string</span> name = <span class="str">&quot;/journal/rss.xml&quot;</span>;

    String html = GetWebPage(address, name);

    DateTime lastUpdate = getRecentPubDate(html, <span class="str">&quot;&lt;pubDate&gt;&quot;</span>);

    Debug.Print(<span class="str">&quot;Initial Update Value : &quot;</span> &#43; lastUpdate.ToString());

    <span class="kwrd">while</span> (<span class="kwrd">true</span>)
    {
        System.Threading.Thread.Sleep(10000);

        html = GetWebPage(address, name);

        DateTime blogUpdate = getRecentPubDate(html, <span class="str">&quot;&lt;pubDate&gt;&quot;</span>);

        <span class="kwrd">if</span> (!blogUpdate.Equals(lastUpdate))
        {
            Debug.Print(<span class="str">&quot;Updated at : &quot;</span> &#43; blogUpdate.ToString());
            lastUpdate = blogUpdate;
            alert = <span class="kwrd">true</span>;
        }
    }
}</pre>
<p>To reduce the load on the network the system only checks the blog feed every 10 seconds.</p>
<h1>Future Work</h1>
<p>The program itself works fine, but the error handling is not wonderful. Although some of the methods used throw exceptions these are not caught anywhere, causing the blog reading thread to terminate. This does not stop the lights flashing, but it does mean
 that there will be no more alerts. However, it is not too hard to create a version which contains proper error handling and even flashes the lights different colors to indicate the alarm conditions. I have created a version that flashes the lights yellow every
 now and then if the network connection fails. There is also considerable scope for reading other web based sources and changing the output accordingly. Feel free to do all these things and make sure that you have fun.</p>
<h2>Thanks</h2>
<p>Thanks go to Ian Mitchell of Ormston Technology (<a href="http://www.ormtec.co.uk/">http://www.ormtec.co.uk/</a>) for doing such a great job of hardware design and build.</p>
 <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Tags/home+automation/RSS&WT.dl=0&WT.entryid=Entry:RSSView:90ff2e0eefa3449089ad9e7600cda780">]]></description>
      <comments>http://channel9.msdn.com/coding4fun/articles/Controlling-Your-Festive-Lights-with-the-NET-Micro-Framework</comments>
      <itunes:summary>





Author:
Rob Miles: 
www.robmiles.com 


Download:
Download


Software:
Visual Studio 2008 Express Edition or better,

.NET Micro Framework 3.0


Hardware:
Digi Connect-ME

GHI Electronics Embedded Master

Devices Solutions Tahoe II



Time Required:
3 hours


Cost:
30 dollars for lights plus the .NET Micro Framework device



The Micro Framework is one of the newest kids on the .NET block, but it does something really rather wonderful. It brings embedded development within the reach of any C# programmer. If you know C# and love Visual Studio, you can now get started building
 hardware and controlling it with your software. Moreover, it lets developers achieve one of their most cherished dreams, to control their festive lights using programs that they have written. This project shows you how to do just that and adds an extra magical
 feature, in that you can make all your festive lights flash red whenever I, Rob Miles, make a new post on that most famous of blogs,
www.robmiles.com.  
Actually, you can modify the code so that you can make your lights do most anything in response to an event that happens on the web. You could signal home that you are running late, send the weather forecast to your Christmas tree or explore any number of
 communication options. You might decide that this is so useful that you leave your decorations up all year round. 
If you just want to play with the .NET Micro Framework and get a feel for how easy it is to create software for tiny devices you don&#39;t actually need to use any extra hardware at all. The project comes with a complete emulation of the lights display so that
 you can run the whole thing on your computer and learn how hardware and software can be made to work together without burning your fingers with a soldering iron. 
However building the hardware will give you an understanding of how some simple electronic components can be controlled from C# and even how serial and parallel data transfer works. It is also great fun.</itunes:summary>
      <link>http://channel9.msdn.com/coding4fun/articles/Controlling-Your-Festive-Lights-with-the-NET-Micro-Framework</link>
      <pubDate>Fri, 28 Nov 2008 01:58:46 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/coding4fun/articles/Controlling-Your-Festive-Lights-with-the-NET-Micro-Framework</guid>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/c4f/images/9149635_100.jpg" height="75" width="100"></media:thumbnail>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/c4f/images/9149635_220.jpg" height="165" width="220"></media:thumbnail>      
      <dc:creator>Rob Miles</dc:creator>
      <itunes:author>Rob Miles</itunes:author>
      <slash:comments>6</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/coding4fun/articles/Controlling-Your-Festive-Lights-with-the-NET-Micro-Framework/RSS</wfw:commentRss>
      <category>.NET Micro Framework</category>
      <category>Hardware</category>
      <category>Robotics</category>
      <category>Home Automation</category>
      <category>Holiday</category>
      <category>.NET Microframework</category>
      <category>hardwarehacks</category>
    </item>
  <item>
      <title>Life|ware Launches New Media Servers</title>
      <description><![CDATA[ <p>At this year's CEDIA EXPO, the show put on by the trade association of home theater companies, <a href="http://www.cepro.com/article/lifeware_all_in_one_server_includes_media_center_51_surround_sound_and_zigb?utm_source=CEPWeekly&amp;utm_medium=email">Lifeware launched</a> a brand-new, all-in-one, <a href="http://www.cepro.com/article/exclusive_exceptional_innovation_to_ship_5_media_center_pcs/">Lifemedia Server </a>(LMS). This new server combines Windows Media Center with a 5.1 surround-sound amplifier and ZigBee control technology all within a single box. The LMS-170 line of media servers with ZigBee built in will allow the servers to communicate directly with Centralite's JetStream products, including dimmers, modules and switches. Whereas before they had to install a bridge in order to get the systems talking, the new servers will have direct communication. </p><p>There will be two models of the new server expected in the 1st quarter of 2009: the LMS-175 which will support dual Cable Cards (less than $4000) and the LMS-172 which has dual NTSC/ATSC tuners but no Cable Card support. No word on its price yet, only that it will be the less expensive of the two. </p><p>If you want to learn more about Life|ware, check out some of our earlier posts - we’ve mentioned them many times here on Channel 10. I reviewed their <a href="http://on10.net/blogs/sarahintampa/20349/Default.aspx">Home Automation software</a> back in December, <a href="http://on10.net/blogs/nic/Automate-your-home-with-LifeWare/Default.aspx">Nic visited them at CES 2008</a> and recorded footage of their e-home setup, and, more recently, Laura looked at their inclusion in <a href="http://on10.net/blogs/laura/Disney-Innoventions-Dream-Home/">Disney’s new Innovations Dream Home</a>. </p><p><em>(Image courtesy of </em><a href="http://www.cepro.com/article/lifeware_all_in_one_server_includes_media_center_51_surround_sound_and_zigb?utm_source=CEPWeekly&amp;utm_medium=email"><em>cepro.com</em></a><em>)</em></p> <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Tags/home+automation/RSS&WT.dl=0&WT.entryid=Entry:RSSView:df9c68b6863b48b394639e0e00a5ff61">]]></description>
      <comments>http://channel9.msdn.com/Blogs/coolstuff/Lifeware-Launches-New-Media-Servers</comments>
      <itunes:summary> At this year&#39;s CEDIA EXPO, the show put on by the trade association of home theater companies, Lifeware launched a brand-new, all-in-one, Lifemedia Server (LMS). This new server combines Windows Media Center with a 5.1 surround-sound amplifier and ZigBee control technology all within a single box. The LMS-170 line of media servers with ZigBee built in will allow the servers to communicate directly with Centralite&#39;s JetStream products, including dimmers, modules and switches. Whereas before they had to install a bridge in order to get the systems talking, the new servers will have direct communication.  There will be two models of the new server expected in the 1st quarter of 2009: the LMS-175 which will support dual Cable Cards (less than $4000) and the LMS-172 which has dual NTSC/ATSC tuners but no Cable Card support. No word on its price yet, only that it will be the less expensive of the two.  If you want to learn more about Life|ware, check out some of our earlier posts - we’ve mentioned them many times here on Channel 10. I reviewed their Home Automation software back in December, Nic visited them at CES 2008 and recorded footage of their e-home setup, and, more recently, Laura looked at their inclusion in Disney’s new Innovations Dream Home.  (Image courtesy of cepro.com) </itunes:summary>
      <link>http://channel9.msdn.com/Blogs/coolstuff/Lifeware-Launches-New-Media-Servers</link>
      <pubDate>Thu, 04 Sep 2008 12:34:00 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/Blogs/coolstuff/Lifeware-Launches-New-Media-Servers</guid>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/previewImages/320/on10_752e2120-4cc5-4f71-9064-e1422d122be3.jpg" height="0" width="0"></media:thumbnail>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/previewImages/85/on10_f080f767-3ac6-477e-adea-b7fd6b61fd14.jpg" height="64" width="85"></media:thumbnail>      
      <dc:creator>Sarah Perez</dc:creator>
      <itunes:author>Sarah Perez</itunes:author>
      <slash:comments>0</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/Blogs/coolstuff/Lifeware-Launches-New-Media-Servers/RSS</wfw:commentRss>
      <category>Media</category>
      <category>Media Center</category>
      <category>Media Center PC</category>
      <category>Home Automation</category>
      <category>servers</category>
      <category>Home Tech</category>
      <category>Home Entertainment</category>
    </item>
  <item>
      <title>Stall Status: Know before you go</title>
      <description><![CDATA[<span id="c4fmetadata">
<table cellspacing="0" cellpadding="1" width="100%" border="0">
<tbody>
<tr class="entry_overview">
<td width="50">&nbsp;<a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/8859880/icon.png"><img height="85" alt="icon" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/8859880/icon_thumb.png" width="75" border="0"></a>
</td>
<td><span class="entry_description">Stall Status is a Silverlight-based Vista Sidebar Gadget that uses the Z-Wave wireless protocol and door sensors to notify you of the occupied/available state of the bathroom stalls.</span></td>
</tr>
<tr>
<td colspan="2">
<div class="entry_author">Jerry Brunning</div>
<div class="entry_company"><a href="http://www.claritycon.com">Clarity Consulting, Inc</a></div>
<br>
<div class="entry_details"><b>Difficulty: </b><span class="entry_details_input">Easy</span></div>
<div class="entry_details"><b>Time Required:</b> <span class="entry_details_input">
1-3 hours</span></div>
<div class="entry_details"><b>Cost: </b><span class="entry_details_input">$50-$100</span></div>
<div class="entry_details"><b>Software: </b><span class="entry_details_input"><a href="http://www.microsoft.com/express/">Visual C# Express Edition</a></span></div>
<div class="entry_details"><b>Hardware: </b><span class="entry_details_input"><a href="http://www.controlthink.com/zwavesdk.htm">ControlThink Z-Wave SDK</a>,&nbsp;
<a href="http://www.amazon.com/Hawking-HRDS1-HomeRemote-Wireless-Window/dp/B0012W9EUW/ref=sr_1_1?ie=UTF8&amp;s=electronics&amp;qid=1218645148&amp;sr=8-1">
Hawking Technologies Z-Wave HRDS1 door sensor</a></span></div>
<div class="entry_details"><b>Download: </b><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/8859880/stallstatus_src.zip">Download</a>
<ul>
</ul>
</div>
</td>
</tr>
</tbody>
</table>
</span>
<h2>Stall Status </h2>
<p>Every now and then someone throws out an idea for a completely off-the-wall application that just has to be built. When Jon Rauschenberger, Clarity’s CTO, came into my office with his “brilliant idea” for a monitoring system to track the “occupied/available”
 state of our washroom stalls, I immediately recognized it as one of those moments. I had been doing some research on the Z-Wave wireless protocol for a client project earlier that week, and I thought “Stall Status” would be a fun way to get some hands on experience
 using Z-Wave.</p>
<p>In this article I will walk you through how to write managed code that interacts with Z-Wave devices. I’ll also show how to use Silverlight 2.0’s access policies to write “connected clients”: client applications that establish a persistent TCP connection
 to a remote server and thereby avoid having to poll the server for status changes. Finally, I’ll walk through the steps necessary to deploy a Silverlight 2.0 application as a Windows Vista Sidebar Gadget.</p>
<h3><b>What is Z-Wave?</b></h3>
<p>Z-Wave is a wireless communication protocol that works over radio frequency and is specifically designed for low-power, low-bandwidth usage scenarios. Typical usage scenarios for Z-Wave devices are monitoring and control applications – such as home automation.
 Available devices include door sensors, switches, and motors. Z-Wave devices are interoperable - devices labeled as Z-Wave compliant should all work together.</p>
<p>A Z-Wave network consists of one or more devices and a centralized controller. A controller can be a standalone (often hand held) hardware unit or a software-based kit. Devices on a Z-Wave network handle the routing of messages automatically without the
 need to set up pre-defined routes. This means that if you have several devices in your network that need to communicate together (e.g. a door sensor and an alarm), the devices can route messages through each other. This “mesh” communication capability allows
 you to extend the range of your network much farther than you would be able to if the devices all required direct connections to each other.&nbsp; For example, if you have three devices, A, B and C, device A can communicate with device C, even if C is outside of
 A's range, by routing its messages through device B.&nbsp; This all works automatically.</p>
<p>My simple Z-Wave network for Stall Status consists of door sensors to notify me when a stall door is opened and closed, and a software based controller. I used Hawking Technologies’ HRDS1 battery powered door sensors for each stall door in the washroom.
 The HRDS1 is considered an “occasionally on” device – it quietly sits in sleep mode until it detects an open/close event from the door. This is the same type of device you would use, for example, when building an alarm system for monitoring windows and doors.&nbsp;
 For the Z-Wave controller I used an excellent software-based controller and SDK from
<a href="http://www.controlthink.com/">ControlThink</a>, which you can purchase for $70. The controller consists of a USB dongle and a set of APIs for connecting to and communicating with devices. ControlThink includes a number of .Net sample applications,
 but be warned that the sample applications are not device specific, and the available devices usually assume you are integrating them into an existing hardware-controlled environment, so the documentation surrounding their usage tends to be sparse.</p>
<p>Using the ControlThink SDK is very straight forward. You simply plug in the USB dongle, reference their DLL from your .Net application, and connect to the controller with a single line of code. Once connected, you can manage your network by adding devices,
 removing devices, iterating the list of devices, etc. </p>
<p>I ended up writing three applications to support Stall Status:</p>
<ol>
<li>An administrative application for adding/removing/listing the Z-Wave devices on my network.&nbsp; This is called StallStatusAdmin.
</li><li>A Windows Service to listen for open/close events from the door sensors and notify any connected client.&nbsp; This is called StallStatusController.
</li><li>A Silverlight 2.0 client application (the end-user interface) that connects to the Windows Service to receive event notifications.&nbsp; This is called StallStatusSilverlight.
</li></ol>
<h3><b>Setting up the Z-Wave network</b></h3>
<p>The administration application is a simple Windows Forms EXE that allows me to manage the network by adding, removing and listing the devices. This is simple to do using the ControlThink SDK – in most cases involving just a couple lines of code. Each Z-Wave
 device has some mechanism to put the device into “programming mode” . The HRDS1 has a button on the back that when pressed, puts the device into programming mode and allows the device to accept programming codes from the controller.</p>
<p>Listing 1 shows how to add a device to the network. Adding a device consists of registering the device with the controller, and then creating a relationship between the controller and the device's association group to enable the device to route messages
 to the controller. Once a device is registered, the controller assigns a unique NodeID that we will use to differentiate the three sensors from each other.</p>
<p><em>C#</em></p>
<pre class="csharpcode">ZWaveController controller = Connect(); 
MessageBox.Show(<span class="str">&quot;After pressing OK, press the \&quot;programming\&quot; button on your device.&quot;</span>);
ZWaveDevice device = controller.AddDevice();
            
device.Groups[1].Clear();
device.Groups[1].Add(controller.Devices.GetByNodeID(controller.NodeID));</pre>
<pre class="csharpcode"><em>VB.Net</em></pre>
<pre class="csharpcode"><span class="kwrd">Dim</span> controller <span class="kwrd">As</span> ZWaveController = Connect()
MessageBox.Show(<span class="str">&quot;After pressing OK, press the &quot;</span><span class="str">&quot;programming&quot;</span><span class="str">&quot; button on your device.&quot;</span>)
<span class="kwrd">Dim</span> device <span class="kwrd">As</span> ZWaveDevice = controller.AddDevice()

device.Groups(1).Clear()
device.Groups(1).Add(controller.Devices.GetByNodeID(controller.NodeID))</pre>
<p><i>Listing 1 – Adding a device to the network.</i></p>
<p>&nbsp;</p>
<p>Getting a list of the registered devices on the network is as easy a iterating through the Devices collection on the controller.</p>
<p><span class="kwrd"><em>C#</em></span></p>
<pre class="csharpcode"><span class="kwrd">string</span> result = <span class="str">&quot;&quot;</span>;
ZWaveController controller = Connect();

<span class="kwrd">if</span> (controller.Devices.Count &gt; 0) {
   <span class="kwrd">foreach</span> (ZWaveDevice d <span class="kwrd">in</span> controller.Devices)    {
    result &#43;= d.GetType().ToString() &#43; <span class="str">&quot; as Node #&quot;</span> &#43; d.NodeID &#43; <span class="str">&quot; PollEnabled = &quot;</span> &#43; d.PollEnabled &#43; <span class="str">&quot;\r\n&quot;</span>;
   }
}
<span class="kwrd">else </span>{
   result = <span class="str">&quot;No devices found on the network&quot;</span>;                
}
MessageBox.Show(result);</pre>
<pre class="csharpcode"><span class="kwrd"><em>VB.Net</em></span></pre>
<pre class="csharpcode"><span class="kwrd">Dim</span> result <span class="kwrd">As</span> <span class="kwrd">String</span> = <span class="str">&quot;&quot;</span>
<span class="kwrd">Dim</span> controller <span class="kwrd">As</span> ZWaveController = Connect()

<span class="kwrd">If</span> controller.Devices.Count &gt; 0 <span class="kwrd">Then</span>
   <span class="kwrd">For</span> <span class="kwrd">Each</span> d <span class="kwrd">As</span> ZWaveDevice <span class="kwrd">In</span> controller.Devices
    result &amp;= d.<span class="kwrd">GetType</span>().ToString() &amp; <span class="str">&quot; as Node #&quot;</span> &amp; d.NodeID &amp; <span class="str">&quot; PollEnabled = &quot;</span> &amp; d.PollEnabled &amp; Constants.vbCrLf
   <span class="kwrd">Next</span> d
<span class="kwrd">Else</span>
   result = <span class="str">&quot;No devices found on the network&quot;</span>
<span class="kwrd">End</span> <span class="kwrd">If</span>
MessageBox.Show(result)</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><i>Listing 2 – Listing the devices in the network.</i></p>
<p><b></b></p>
<h3><b></b></h3>
<h3><b></b></h3>
<h3><b>Receiving Z-Wave Events</b></h3>
<p>Once the devices are registered on the network, they will send event notifications back to the controller each time the sensor is triggered. The next steps for us are to write code to receive the events and forward them to any client applications that are
 connected. To do this we’ll write a Windows Service that listens for events from the sensors.</p>
<p>All of the work for listening for events from the Z-Wave devices is handled for us by the ControlThink SDK. We simply connect to the controller and sink the LevelChanged event. We do this in our Run method, which is called from within our service’s OnStart
 function.</p>
<pre class="csharpcode"><span class="kwrd"><em>C#</em></span></pre>
<pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">void</span> Run() {
   <span class="kwrd">try</span>  {
       _controller = <span class="kwrd">new</span> ZWaveController();
       <span class="kwrd">try</span>  {
          _controller.Connect();
       }
       <span class="kwrd">catch</span> (Exception ex) {
          <span class="kwrd">throw</span> <span class="kwrd">new</span> Exception(<span class="str">&quot;Unable to connect.\r\n&quot;</span> &#43; ex.ToString());
       }

       _controller.LevelChanged &#43;= <span class="kwrd">new</span> ZWaveController.LevelChangedEventHandler(_controller_LevelChanged);

       _policyListener = <span class="kwrd">new</span> PolicyListener();
       _listener = <span class="kwrd">new</span> SocketListener();
       _listener.Port = 4530;
             
        <span class="kwrd">new</span> System.Threading.Thread(<span class="kwrd">new</span> System.Threading.ThreadStart(_listener.StartSocketServer)).Start();
        <span class="kwrd">new</span> System.Threading.Thread(<span class="kwrd">new</span> System.Threading.ThreadStart(_policyListener.StartSocketServer)).Start();
        <span class="kwrd">new</span> System.Threading.Thread(<span class="kwrd">new</span> System.Threading.ThreadStart(ClearRecent)).Start();
   }
   <span class="kwrd">catch</span> (Exception ex) {
       Logger.WriteException(ex);
   }
}</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style><style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><em>VB.Net</em></p>
<pre class="csharpcode"><span class="kwrd">Public</span> <span class="kwrd">Sub</span> Run()
   <span class="kwrd">Try</span>
       _controller = <span class="kwrd">New</span> ZWaveController()
       <span class="kwrd">Try</span>
          _controller.Connect()
       <span class="kwrd">Catch</span> ex <span class="kwrd">As</span> Exception
          <span class="kwrd">Throw</span> <span class="kwrd">New</span> Exception(<span class="str">&quot;Unable to connect.&quot;</span> &amp; Constants.vbCrLf &amp; ex.ToString())
       <span class="kwrd">End</span> <span class="kwrd">Try</span>

       <span class="kwrd">AddHandler</span> _controller.LevelChanged, <span class="kwrd">AddressOf</span> _controller_LevelChanged

       _policyListener = <span class="kwrd">New</span> PolicyListener()
       _listener = <span class="kwrd">New</span> SocketListener()
       _listener.Port = 4530

        <span class="kwrd">CType</span>(<span class="kwrd">New</span> System.Threading.Thread(<span class="kwrd">New</span> System.Threading.ThreadStart(<span class="kwrd">AddressOf</span> _listener.StartSocketServer)), System.Threading.Thread).Start()
        <span class="kwrd">CType</span>(<span class="kwrd">New</span> System.Threading.Thread(<span class="kwrd">New</span> System.Threading.ThreadStart(<span class="kwrd">AddressOf</span> _policyListener.StartSocketServer)), System.Threading.Thread).Start()
        <span class="kwrd">CType</span>(<span class="kwrd">New</span> System.Threading.Thread(<span class="kwrd">New</span> System.Threading.ThreadStart(<span class="kwrd">AddressOf</span> ClearRecent)), System.Threading.Thread).Start()
   <span class="kwrd">Catch</span> ex <span class="kwrd">As</span> Exception
       Logger.WriteException(ex)
   <span class="kwrd">End</span> <span class="kwrd">Try</span>
<span class="kwrd">End</span> Sub</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><i>Listing 3 – Listening for Z-Wave events when our service starts up.</i></p>
<p>&nbsp;</p>
<p>In addition to listening for events from the ZWave Controller, our Run method also sets up socket listeners for talking to the Silverlight client application, which we will talk about later. An important detail to note, however, is the use of threading in
 the Run method. Remember that this is called directly from our service’s OnStart code which we should not block - if you block OnStart, you’ll see the service stuck at “Starting...” in the Service Control Manager. Anything that will block or that is long running
 (such as a socket listener) needs to run on a separate thread.</p>
<p>When the controller detects that one of the sensors has changed its state, it throws the LevelChanged event to our service. Our service handles LevelChanged in the _controller_LevelChanged method. The signature for the LevelChanged event looks like this:</p>
<blockquote>
<pre class="csharpcode"><span class="kwrd">void</span> _controller_LevelChanged(<span class="kwrd">object</span> sender, ZWaveController.LevelChangedEventArgs e)</pre>
</blockquote>
<p>The LevelChangeEventArgs contains the original device that raised the event. We have three door sensors connected to our network. When any of them are triggered, LevelChanged is raised and we can inspect the LevelChangedEventArgs to get the NodeID of the
 unique identifier of the device. That’s all there is to interacting with the Z-Wave network.</p>
<h2>Silverlight 2.0</h2>
<p>Now that we’ve got the server infrastructure set up it is time to build a client application so we can actually start using Stall Status. I built the client application in Silverlight as an exercise to show how to use Silverlight 2.0’s access policy to make
 cross domain network calls from a Silverlight client application. I also knew that it is simple to deploy a Silverlight application as a Windows Vista Gadget, and the Sidebar was to be my preferred deployment model for the application.</p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/8859880/StallStatus2.png"><img height="149" alt="StallStatus2" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/8859880/StallStatus2_thumb.png" width="131" border="0"></a>
</p>
<p><i>Figure 1 – Stall Status interface</i></p>
<p>The main UI for the application is pretty simple – three ellipses, one for each stall, colored green if the stall is available and red if the stall is occupied. Most of the challenge with building the client piece has to do with connecting to the service
 and listening for updates. To do this, we create a persistent TCP connection and wait for data to be sent from the service over the socket. This is much better than a polling approach for an application like this because of the way the Z-Wave door sensors
 work. They are in sleep mode most of the time, and are only using power when they transmit a signal due to the door opening or closing. If we polled the devices frequently, it would kill the batteries in the device. Also, most of the time there is no change
 to the state of the doors, so polling would really be a waste.</p>
<p>Silverlight contains certain security mechanisms around network connectivity, especially TCP sockets. This is due to the fact that a Silverlight application runs in the context of the user’s browser, so special controls need to be in place to limit the type
 of connectivity that Silverlight applications can initiate. For socket-based connections, Silverlight 2.0 requires an access policy to be in place on the target server. This access policy essentially is a challenge/response mechanism that prevents a Silverlight
 application from connecting to an arbitrary server, potentially masquerading as the end user.</p>
<h3>Access Policy</h3>
<p>An Access Policy must be in place on the server for in order to enable a Silverlight 2.0 client to connect using sockets. The Silverlight framework handles all of the validation for the presence of the access policy, so your client application does not need
 to do anything. However, if the proper policy is not in place on the target server, Silverlight will throw an Access Denied exception, so your client application should be prepared to handle this situation. This is all very similar to how network access in
 Flash applications work. In fact, Silverlight can consume Flash policy files directly, as well as Silverlight policy files. In the Stall Status application, we’re going to be using Silverlight policy.</p>
<p>When a Silverlight application attempts to open a socket to a target server, Silverlight will automatically look for an access policy on the server by establishing a TCP connection over port 943, and sending a policy request. The policy request is simply
 an XML-style string: &lt;policy-file-request/&gt;. It is up to the author of the service that is receiving the request to ensure that they properly respond to this request, or else Silverlight will raise an exception on the client. All of this is described in detail
 in the <a href="http://msdn.microsoft.com/en-us/library/cc645032(VS.95).aspx">MSDN documentation</a> on the new network security restrictions in Silverlight 2.0.</p>
<p>In order to respond to a request for an access policy on our server, we need to implement a network listener on port 943 that responds to Silverlight’s policy file request.
<a href="http://weblogs.asp.net/dwahlin/archive/2008/04/10/pushing-data-to-a-silverlight-client-with-sockets-part-i.aspx">
Dan Wahlin</a> wrote a multi-part blog post showing exactly how to do this, and the listener I used for Stall Status, plus much of the other socket code, is copied from his example. I recommend reading his post - it is a great primer on writing TCP socket clients
 in Silverlight 2.0.</p>
<p>Our listener class run in our windows service and simply sets up a listener on port 943. When it receives a policy file request, it returns the appropriate response, as shown below.</p>
<blockquote>
<pre class="csharpcode"><span class="kwrd">&lt;?</span><span class="html">xml</span> <span class="attr">version</span><span class="kwrd">=&quot;1.0&quot;</span> <span class="attr">encoding</span> <span class="kwrd">=&quot;utf-8&quot;</span>?<span class="kwrd">&gt;</span>
<span class="kwrd">&lt;</span><span class="html">access-policy</span><span class="kwrd">&gt;</span>
  <span class="kwrd">&lt;</span><span class="html">cross-domain-access</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">policy</span><span class="kwrd">&gt;</span>
      <span class="kwrd">&lt;</span><span class="html">allow-from</span><span class="kwrd">&gt;</span>
        <span class="kwrd">&lt;</span><span class="html">domain</span> <span class="attr">uri</span><span class="kwrd">=&quot;*&quot;</span> <span class="kwrd">/&gt;</span>
      <span class="kwrd">&lt;/</span><span class="html">allow-from</span><span class="kwrd">&gt;</span>
      <span class="kwrd">&lt;</span><span class="html">grant-to</span><span class="kwrd">&gt;</span>
        <span class="kwrd">&lt;</span><span class="html">socket-resource</span> <span class="attr">port</span><span class="kwrd">=&quot;4530&quot;</span> <span class="attr">protocol</span><span class="kwrd">=&quot;tcp&quot;</span> <span class="kwrd">/&gt;</span>
      <span class="kwrd">&lt;/</span><span class="html">grant-to</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;/</span><span class="html">policy</span><span class="kwrd">&gt;</span>
  <span class="kwrd">&lt;/</span><span class="html">cross-domain-access</span><span class="kwrd">&gt;</span>
 <span class="kwrd">&lt;/</span><span class="html">access-policy</span><span class="kwrd">&gt;</span></pre>
</blockquote>
<p>This response tells Silverlight to allow incoming connections to port 4530, which is the port that our service is listening on to accept connections from our Silverlight client.</p>
<p>Why is this important? Well, without access policy in place, there is nothing that prevents a malicious Silverlight application from connecting to a server without permission. For example:</p>
<ul>
<li>Suppose you have an active session with your online bank. A malicious Silverlight application served up from Site A could attempt to connect to your bank using your existing login token (which may be stored as a cookie). With access policy in place, your
 bank would need to have a policy stating that it allowed Silverlight applications originating from Site A to connect to your bank.
</li><li>Suppose you connect to Site A and download a malicious Silverlight application. The application can potentially connect to your corporate intranet and because you are on a corporate domain, the Silverlight app impersonates you. With the access policy rules
 in place, this would be prevented. </li></ul>
<h3>Persistent client connections</h3>
<p>Now that we’ve got our access policy in place, we’re ready to code up our Silverlight client to connect to our server and wait for updates. Silverlight 2.0 can only connect using sockets over the port range 4502-4534. Our Windows Service uses 4530. It creates
 a listener on this port and then sits and waits for connections from our Silverlight clients.</p>
<p>C#</p>
<pre class="csharpcode">_listener = <span class="kwrd">new</span> TcpListener(IPAddress.Any, Port);
_listener.Start();
<span class="kwrd">while</span> (<span class="kwrd">true</span>)
{
   _waitEvent.Reset();
   _listener.BeginAcceptTcpClient(<span class="kwrd">new</span> AsyncCallback(OnBeginAccept), <span class="kwrd">null</span>);
   _waitEvent.WaitOne();
}</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><em>VB.Net</em></p>
<pre class="csharpcode">_listener = <span class="kwrd">New</span> TcpListener(IPAddress.Any, Port)
_listener.Start()
<span class="kwrd">Do</span>
   _waitEvent.Reset()
   _listener.BeginAcceptTcpClient(<span class="kwrd">New</span> AsyncCallback(<span class="kwrd">AddressOf</span> OnBeginAccept), <span class="kwrd">Nothing</span>)
   _waitEvent.WaitOne()
Loop</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><i>Listing 4 – Our main listener for client connections</i></p>
<p>&nbsp;</p>
<p>We’re using asynchronous sockets, so we’ve set up a delegate – OnBeginAccept – to accept and process our connections. The code to process the connects is listed below.</p>
<p><em>C#</em></p>
<pre class="csharpcode">_waitEvent.Set();
TcpListener listener = _listener;
TcpClient client = listener.EndAcceptTcpClient(ar);

<span class="kwrd">if</span> (client.Connected)
{
   Logger.WriteLine(<span class="str">&quot;Accepted a connection from &quot;</span> &#43; client.Client.RemoteEndPoint.ToString());

   StreamWriter writer = <span class="kwrd">new</span> StreamWriter(client.GetStream());
   writer.AutoFlush = <span class="kwrd">true</span>;
   _clients.Add(writer);
   writer.WriteLine(<span class="str">&quot;Connected.&quot;</span>);

   <span class="kwrd">if</span> (ClientConnected != <span class="kwrd">null</span>)
   {
     ClientConnected(<span class="kwrd">this</span>, <span class="kwrd">null</span>);
   }
}</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><em>VB.Net</em></p>
<pre class="csharpcode">_waitEvent.<span class="kwrd">Set</span>()
<span class="kwrd">Dim</span> listener <span class="kwrd">As</span> TcpListener = _listener
<span class="kwrd">Dim</span> client <span class="kwrd">As</span> TcpClient = listener.EndAcceptTcpClient(ar)

<span class="kwrd">If</span> client.Connected <span class="kwrd">Then</span>
   Logger.WriteLine(<span class="str">&quot;Accepted a connection from &quot;</span> &amp; client.Client.RemoteEndPoint.ToString())

   <span class="kwrd">Dim</span> writer <span class="kwrd">As</span> <span class="kwrd">New</span> StreamWriter(client.GetStream())
   writer.AutoFlush = <span class="kwrd">True</span>
   _clients.Add(writer)
   writer.WriteLine(<span class="str">&quot;Connected.&quot;</span>)

   <span class="kwrd">If</span> ClientConnected IsNot <span class="kwrd">Nothing</span> <span class="kwrd">Then</span>
     ClientConnected(<span class="kwrd">Me</span>, <span class="kwrd">Nothing</span>)
   <span class="kwrd">End</span> <span class="kwrd">If</span>
<span class="kwrd">End</span> If</pre>
<p><i>Listing 5 – Accepting a new client connection</i></p>
<p>&nbsp;</p>
<p>Here we are simply adding a StreamWriter for each connected client to a List. We do this so when we receive events from the door sensors, we can loop through this List and notify all of the clients. We notify them by writing a tokenized string to the StreamWriter.
 We also have code to remove any clients from the list if we fail to write to their stream. This way we can catch the situation where the client disconnected.</p>
<pre class="csharpcode"><span class="kwrd"><em>C#</em></span></pre>
<pre class="csharpcode"><span class="kwrd">for</span> (<span class="kwrd">int</span> i=_clients.Count-1;i&gt;=0;i--)
{
   <span class="kwrd">try</span>
   {
      _clients[i].WriteLine(eventText);
   }
   <span class="kwrd">catch</span> (Exception ex)
   {
      Logger.WriteException(ex);
      Logger.WriteLine(<span class="str">&quot;Removing client # &quot;</span> &#43; i &#43; <span class="str">&quot; because we failed to send them data.&quot;</span>);
      _clients.Remove(_clients[i]);
   }
}</pre>
<p><em>VB.Net</em></p>
<pre class="csharpcode"><span class="kwrd">For</span> i <span class="kwrd">As</span> <span class="kwrd">Integer</span> = _clients.Count-1 <span class="kwrd">To</span> 0 <span class="kwrd">Step</span> -1
   <span class="kwrd">Try</span>
      _clients(i).WriteLine(eventText)
   <span class="kwrd">Catch</span> ex <span class="kwrd">As</span> Exception
      Logger.WriteException(ex)
      Logger.WriteLine(<span class="str">&quot;Removing client # &quot;</span> &amp; i &amp; <span class="str">&quot; because we failed to send them data.&quot;</span>)
      _clients.Remove(_clients(i))
   <span class="kwrd">End</span> <span class="kwrd">Try</span>
<span class="kwrd">Next</span> i</pre>
<p><i>Listing 6 – Sending an update to all clients</i></p>
<p>&nbsp;</p>
<p>The text we pass to each client (represented in the code above by the eventText variable) is simply the NodeID of the sensor that triggered the event and the state (open/closed) on the sensor. The Silverlight client receives this text, parses it out, and
 updates the color of the ellipse accordingly.</p>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style><style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<pre class="csharpcode"><span class="kwrd"><em>C#</em></span></pre>
<pre class="csharpcode"><span class="kwrd">private</span> <span class="kwrd">void</span> UpdateText(<span class="kwrd">string</span> text)
{
    <span class="kwrd">string</span>[] parts = text.Split(<span class="str">' '</span>);

    <span class="kwrd">if</span> (parts.Length != 2) {
        <span class="kwrd">return</span>;
    }

    <span class="kwrd">int</span> stallNumber = Convert.ToInt32(parts[0]);
    <span class="kwrd">string</span> status = parts[1].ToLower();

    StatusIndicator thisStall = <span class="kwrd">null</span>;
    <span class="kwrd">switch</span> (stallNumber) {
        <span class="kwrd">case</span> 1:
            thisStall = <span class="kwrd">this</span>.Stall1;
            <span class="kwrd">break</span>;
        <span class="kwrd">case</span> 2:
            thisStall = <span class="kwrd">this</span>.Stall2;
            <span class="kwrd">break</span>;
        <span class="kwrd">default</span>:
            thisStall = <span class="kwrd">this</span>.Stall3;
            <span class="kwrd">break</span>;
    }

    <span class="kwrd">if</span> (status.Trim() == <span class="str">&quot;open&quot;</span>) {
        thisStall.Status = StallStatus.Open;
    }
    <span class="kwrd">else</span> <span class="kwrd">if</span> (status.Trim() == <span class="str">&quot;closed&quot;</span>) {
        thisStall.Status = StallStatus.Closed;
    }
    <span class="kwrd">else</span> <span class="kwrd">if</span> (status.Trim() == <span class="str">&quot;recent&quot;</span>) {
        thisStall.Status = StallStatus.Recent;
    }
    <span class="kwrd">else</span> {
        thisStall.Status = StallStatus.Unknown;
    }
}</pre>
<pre class="csharpcode"><em>VB.Net</em></pre>
<pre class="csharpcode"><span class="kwrd">Private</span> <span class="kwrd">Sub</span> UpdateText(<span class="kwrd">ByVal</span> text <span class="kwrd">As</span> <span class="kwrd">String</span>)
    <span class="kwrd">Dim</span> parts() <span class="kwrd">As</span> <span class="kwrd">String</span> = text.Split(<span class="str">&quot; &quot;</span>c)

    <span class="kwrd">If</span> parts.Length &lt;&gt; 2 <span class="kwrd">Then</span>
        <span class="kwrd">Return</span>
    <span class="kwrd">End</span> <span class="kwrd">If</span>

    <span class="kwrd">Dim</span> stallNumber <span class="kwrd">As</span> <span class="kwrd">Integer</span> = Convert.ToInt32(parts(0))
    <span class="kwrd">Dim</span> status <span class="kwrd">As</span> <span class="kwrd">String</span> = parts(1).ToLower()

    <span class="kwrd">Dim</span> thisStall <span class="kwrd">As</span> StatusIndicator = <span class="kwrd">Nothing</span>
    <span class="kwrd">Select</span> <span class="kwrd">Case</span> stallNumber
        <span class="kwrd">Case</span> 1
            thisStall = <span class="kwrd">Me</span>.Stall1
        <span class="kwrd">Case</span> 2
            thisStall = <span class="kwrd">Me</span>.Stall2
        <span class="kwrd">Case</span> <span class="kwrd">Else</span>
            thisStall = <span class="kwrd">Me</span>.Stall3
    <span class="kwrd">End</span> <span class="kwrd">Select</span>

    <span class="kwrd">If</span> status.Trim() = <span class="str">&quot;open&quot;</span> <span class="kwrd">Then</span>
        thisStall.Status = StallStatus.Open
    <span class="kwrd">ElseIf</span> status.Trim() = <span class="str">&quot;closed&quot;</span> <span class="kwrd">Then</span>
        thisStall.Status = StallStatus.Closed
    <span class="kwrd">ElseIf</span> status.Trim() = <span class="str">&quot;recent&quot;</span> <span class="kwrd">Then</span>
        thisStall.Status = StallStatus.Recent
    <span class="kwrd">Else</span>
        thisStall.Status = StallStatus.Unknown
    <span class="kwrd">End</span> <span class="kwrd">If</span>
<span class="kwrd">End</span> Sub</pre>
<p><i>Listing 7 – Receiving the update on the client from the server</i></p>
<p>&nbsp;</p>
<p>The only other thing the application contains is the concept of &quot;recently occupied&quot;. Once a stall has been vacated, we track it as recently occupied. This shows up on the client application as a yellow ellipse. To do this we keep track of a timestamp whenever
 the door opens.&nbsp; Our Service contains a dedicated thread that checks for doors opened more than 2 minutes ago. If it finds any, it changes the door's status from “Recent” to a status of “Opened”.</p>
<pre class="csharpcode"><span class="kwrd"><em>C#</em></span></pre>
<pre class="csharpcode"><span class="kwrd">private</span> <span class="kwrd">void</span> ClearRecent()
{
  <span class="kwrd">while</span> (!_wait.WaitOne(10000,<span class="kwrd">false</span>))
  {
    var q = from stall <span class="kwrd">in</span> _stalls
      <span class="kwrd">where</span> stall.Timestamp.AddMinutes(2) &lt; DateTime.Now &amp;&amp; stall.State.Equals(DoorState.Recent)
      select stall;

    <span class="kwrd">foreach</span> (Stall stall <span class="kwrd">in</span> q)
    {
      <span class="kwrd">if</span> (stall.State.Equals(DoorState.Recent)) {
        stall.State = DoorState.Open;
        Broadcast(stall.NodeID, DoorState.Open);
      }
    }
  }
}</pre>
<pre class="csharpcode"><em>VB.Net</em></pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<pre class="csharpcode"><span class="kwrd">Private</span> <span class="kwrd">Sub</span> ClearRecent()
  <span class="kwrd">Do</span> <span class="kwrd">While</span> <span class="kwrd">Not</span> _wait.WaitOne(10000,<span class="kwrd">False</span>)
    <span class="kwrd">Dim</span> q = From stall <span class="kwrd">In</span> _stalls _
            Where stall.Timestamp.AddMinutes(2) &lt; DateTime.Now <span class="kwrd">AndAlso</span> stall.State.Equals(DoorState.Recent) _
            <span class="kwrd">Select</span> stall

    <span class="kwrd">For</span> <span class="kwrd">Each</span> stall <span class="kwrd">As</span> Stall <span class="kwrd">In</span> q
      <span class="kwrd">If</span> stall.State.Equals(DoorState.Recent) <span class="kwrd">Then</span>
        stall.State = DoorState.Open
        Broadcast(stall.NodeID, DoorState.Open)
      <span class="kwrd">End</span> <span class="kwrd">If</span>
    <span class="kwrd">Next</span> stall
  <span class="kwrd">Loop</span>
<span class="kwrd">End</span> Sub</pre>
<p><i>Listing 8 – Clearing the “recently opened” flag</i></p>
<h2><b></b></h2>
<h2><b>Vista Sidebar Gadget</b></h2>
<p>Once I had the Service and Silverlight client apps written, it was time to deploy the client as a Vista Sidebar Gadget. This is actually pretty simple to do with a Silverlight application, but there are a couple things to work through for 64-bit versions
 of Vista.</p>
<p>Packaging a Silverlight application to run as a Gadget is not that different than running it locally or via a web page. You simple collect all of the files for your application, add a manifest file, zip them up, and rename the ZIP file so it has a .gadget
 file extension.</p>
<p>One easy way to create the manifest file is to start from an existing file from one of your existing gadgets. You can find your installed gadgets in the folder \Users\&lt;user name&gt;\AppData\Local\Microsoft\Windows Sidebar\Gadgets. Note that by default the AppData
 folder is hidden. Check the folders of any of your gadgets and you’ll see that they all contain an gadget.xml file. Copy one of these, open it, and make any changes that you need to. Most of the elements in the file are self explanatory, but for a full explanation,
 check out <a href="http://www.microsoft.com/technet/scriptcenter/topics/vista/gadgets-pt1.mspx#ENH">
this article</a>.</p>
<p>Once you’ve got your files and manifest packaged up, you can distribute your gadget. Users can run .gadget files directly in Vista and Vista automatically installs them into the sidebar.</p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/8859880/StallStatusGadget2.png"><img height="244" alt="StallStatusGadget2" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/8859880/StallStatusGadget2_thumb.png" width="164" border="0"></a>
</p>
<p><i>Figure 2 – Stall Status deployed as a Vista Sidebar gadget</i></p>
<p>One note with Silverlight-based gadgets and the 64-bit version of Windows Vista: Since Silverlight is a 32-bit application, you cannot directly host Silverlight-based gadgets in the 64-bit version of Sidebar.exe (which is the running by default on 64-bit
 Vista). As a work around, you can run the 32-bit version of Sidebar.exe, which is located in the \Program Files (x86)\Windows Sidebar\ folder.</p>
<p>As we’ve seen in this article it is easy to use .Net to control a Z-Wave network, and there are tons of creative uses for the technology. Writing network-enabled Silverlight applications has become much more powerful in Silverlight 2.0. And deploying Silverlight-based
 applications as Vista Sidebar Gadgets is pretty simple.</p>
<p></p>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style><style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style><style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style><style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style><style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style> <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Tags/home+automation/RSS&WT.dl=0&WT.entryid=Entry:RSSView:e26739758487407580bc9e7600ceb34b">]]></description>
      <comments>http://channel9.msdn.com/coding4fun/articles/Stall-Status-Know-before-you-go</comments>
      <itunes:summary>



&amp;nbsp;

Stall Status is a Silverlight-based Vista Sidebar Gadget that uses the Z-Wave wireless protocol and door sensors to notify you of the occupied/available state of the bathroom stalls.



Jerry Brunning
Clarity Consulting, Inc

Difficulty: Easy
Time Required: 
1-3 hours
Cost: $50-$100
Software: Visual C# Express Edition
Hardware: ControlThink Z-Wave SDK,&amp;nbsp;

Hawking Technologies Z-Wave HRDS1 door sensor
Download: Download








Stall Status 
Every now and then someone throws out an idea for a completely off-the-wall application that just has to be built. When Jon Rauschenberger, Clarity’s CTO, came into my office with his “brilliant idea” for a monitoring system to track the “occupied/available”
 state of our washroom stalls, I immediately recognized it as one of those moments. I had been doing some research on the Z-Wave wireless protocol for a client project earlier that week, and I thought “Stall Status” would be a fun way to get some hands on experience
 using Z-Wave. 
In this article I will walk you through how to write managed code that interacts with Z-Wave devices. I’ll also show how to use Silverlight 2.0’s access policies to write “connected clients”: client applications that establish a persistent TCP connection
 to a remote server and thereby avoid having to poll the server for status changes. Finally, I’ll walk through the steps necessary to deploy a Silverlight 2.0 application as a Windows Vista Sidebar Gadget. 
What is Z-Wave?
Z-Wave is a wireless communication protocol that works over radio frequency and is specifically designed for low-power, low-bandwidth usage scenarios. Typical usage scenarios for Z-Wave devices are monitoring and control applications – such as home automation.
 Available devices include door sensors, switches, and motors. Z-Wave devices are interoperable - devices labeled as Z-Wave compliant should all work together. 
A Z-Wave network consists of one or more devices and a centralized controller. A controller can b</itunes:summary>
      <link>http://channel9.msdn.com/coding4fun/articles/Stall-Status-Know-before-you-go</link>
      <pubDate>Wed, 13 Aug 2008 15:03:27 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/coding4fun/articles/Stall-Status-Know-before-you-go</guid>      
      <dc:creator>Jerry Brunning</dc:creator>
      <itunes:author>Jerry Brunning</itunes:author>
      <slash:comments>1</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/coding4fun/articles/Stall-Status-Know-before-you-go/RSS</wfw:commentRss>
      <category>utility</category>
      <category>Home Automation</category>
    </item>
  <item>
      <title>Home Automation with Microsoft Robotics Developer Studio 2008</title>
      <description><![CDATA[<span id="c4fmetadata">
<table cellspacing="0" cellpadding="1" width="100%" border="0">
<tbody>
<tr class="entry_overview">
<td width="50"></td>
<td>
<p>Typically we think of robots as machines from science fiction or as industrial robots such as those that build and paint cars. In the world of Microsoft Robotics Developer Studio, anything that has sensors and/or actuators can be considered a robot. In this
 article, we look at an automated house as a robot and apply the Decentralized Software Services model of Microsoft Robotics Studio to implementing some home automation tasks.</p>
</td>
</tr>
<tr>
<td colspan="2">
<div class="entry_author">Charles Stacy Harris III</div>
<br>
<div class="entry_details"><b>Difficulty: </b><span class="entry_details_input">Intermediate</span></div>
<div class="entry_details"><b>Time Required:</b> <span class="entry_details_input">
6-10 hours</span></div>
<div class="entry_details"><b>Cost: </b><span class="entry_details_input">$100-$200 for hardware (Optional, $0 if using only simulation)</span></div>
<div class="entry_details"><b>Software: </b><span class="entry_details_input">Visual Studio or Visual Studio Express, Microsoft Robotics Developer Studio 2008 CTP April,
<a href="http://www.controlthink.com/zwavesdk.htm">ControlThink Z-Wave PC SDK</a>
</span></div>
<div class="entry_details"><b>Hardware: </b><span class="entry_details_input">(All Optional) Elk M1G/M1EZ Security and Automation Panel, Z-Wave Dimmer Switches, Z-Wave Controller such as the ControlThink ThinkStick or equivalent.</span></div>
<div class="entry_details"><b>Download: </b><a href="http://www.codeplex.com/houserobot">Download</a>
<ul>
</ul>
</div>
</td>
</tr>
</tbody>
</table>
</span>
<h3>House, Robot</h3>
<p>Those of you who know me or who have read my previous Coding4Fun article <a href="http://blogs.msdn.com/coding4fun/archive/2007/10/05/5296972.aspx">
Home Automation with Windows Workflow</a>, know that I'm nuts about home automation. I'm even more passionate about robotics and I've wanted to try out some things with Microsoft Robotics Studio since the very first version. Recently I had a long weekend, so
 I spent a few hours putting together some simple home automation examples using Microsoft Robotics Developer Studio 2008 CTP April. Check out the
<a href="http://msdn2.microsoft.com/en-us/robotics/default.aspx">Microsoft Robotics Developer Center</a> for details on how to get the CTP.</p>
<p>The examples in this article duplicate what I did using Windows Workflow in my previous article, but instead use the Decentralized Software Services (DSS) approach of Microsoft Robotics, and Microsoft Visual Programming Language (VPL) for a simple way to
 write automation tasks. The <a href="http://msdn2.microsoft.com/en-us/robotics/default.aspx">
Microsoft Robotics Developer Center</a> contains a lot of detailed information about DSS, VPL, and the other technologies found in Microsoft Robotics Developer Studio. For now, let's just cover some basics. To get further along with the code in this article,
 you'll want to check out some of the excellent tutorials presented by the Microsoft Robotics team.</p>
<h3>Services, Messages, and Ports</h3>
<p>A DSS Service is the basic component upon which Microsoft Robotics applications are built. In fact, DSS services are a generic construct that can and have been used outside of the context of robotics. DSS services contain state and the service state is manipulated
 via messages sent to the service on a service port.</p>
<p>Messages sent to a service are structured .NET classes that may contain a message payload that determines how or even if state will be modified, or what part of a service state should be retrieved. There are also message that do not directly manipulate state,
 but may have some other side-effects. Services respond to messages such as CREATE, LOOKUP, UPDATE, etc. In addition, you can define messages that extend the semantics of the core messages.</p>
<p>Ports are the mechanism through which services communicate. Ports accept a set of message types that are defined by the service itself. In addition, ports are also used for outbound communication in situations such as subscribing to event notification from
 a service.</p>
<p>Again, there are excellent online resources for learning the details of Microsoft Robotics, DSS, and the underlying technologies for Microsoft Robotics developer Studio. You'll probably want basic familiarity with the Microsoft Robotics architecture including
 the Concurrency and Coordination Runtime (CCR) along with the notion of Arbiters and iterators.</p>
<h3>Robo-Moose</h3>
<p>The security and automation system in my house is centered on an Elk M1G alarm panel from
<a href="http://www.elkproducts.com/index.html">Elk Products Incorporated</a> . This panel allows for up to 208 input zones in the form of contact switches, motion sensors, and so on. It also allows for up to 208 outputs, on-board task scripting and many other
 features. One of the key features for my use is the capability of being able to monitor and control the panel via an Ethernet adaptor. So, my first order of business was to write a DSS service – the ElkService – to communicate with the Elk M1G via sockets.
 This ElkService exchanges messages with the Elk M1G via an ASCII protocol that is documented
<a href="http://www.elkproducts.com/products/m1/m1documentation.htm">here</a>. </p>
<p>The code that the ElkService uses to read from the Elk M1G hardware is shown below. Note that the code looks sequential, but is actually asynchronous. The StreamAdapter.Read method sets up a task to do an asynchronous IO operation and the line “yield return
 (Choice)ioResultPort;” returns this task to the runtime which is iterating over all tasks returned by ElkReader.</p>
<pre class="csharpcode"><span class="rem">/// &lt;summary&gt;</span>
<span class="rem">/// ElkReader opens a socket connection to the hardware panel. It then</span>
<span class="rem">/// enters a loop that</span>
<span class="rem">/// &lt;/summary&gt;</span>
<span class="rem">/// &lt;returns&gt;&lt;/returns&gt;</span>
<span class="kwrd">public</span> IEnumerator&lt;ITask&gt; ElkReader()
{
    Connect();

    <span class="rem">// Send a request to the Elk panel get a report of the entire zone status.</span>
    SendElkMessage(RequestStrings.ZoneStatus);

    <span class="kwrd">byte</span>[] buffer = <span class="kwrd">new</span> <span class="kwrd">byte</span>[256];

    <span class="kwrd">int</span> bytesRead = -1;
    Exception ex = <span class="kwrd">null</span>;

     <span class="kwrd">do</span>
    {
        var ioResultPort = StreamAdapter.Read(networkStream, buffer, 0, buffer.Length);

        <span class="kwrd">yield</span> <span class="kwrd">return</span> (Choice)ioResultPort;

        ex = ioResultPort;
        <span class="kwrd">if</span> (ex != <span class="kwrd">null</span>)
            <span class="kwrd">throw</span> ex;

        bytesRead = ioResultPort;
        <span class="kwrd">if</span> (bytesRead != 0)
            ProcessRawElkMessage(Encoding.ASCII.GetString(buffer, 0, bytesRead));

    } <span class="kwrd">while</span> (bytesRead != 0);
}</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>When the ElkService receives a packet from the hardware panel, it converts the packet from a string to a custom message containing the raw sensor data and posts the message to the main port of the ElkService itself. For example, when the service receives
 a “ZC” message from the hardware, it converts this to an UpdateRawZone message that contains the raw data from the security panel. This happens in the method ProcessRawElkMessage. Here is a fragment of that code:</p>
<pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">void</span> ProcessRawElkMessage(<span class="kwrd">string</span> message)
{
    <span class="kwrd">string</span> messageType = message.Substring(2, 2);

    <span class="kwrd">switch</span> (messageType)
    {
        <span class="kwrd">case</span> <span class="str">&quot;ZC&quot;</span>: <span class="rem">// Zone status change</span>
            var zoneState = <span class="kwrd">new</span> UpdateRawZoneRequest
            {
                Id = <span class="kwrd">byte</span>.Parse(message.Substring(4, 3)),
                State = <span class="kwrd">byte</span>.Parse(message.Substring(7, 1),
                              NumberStyles.HexNumber)
            };

            var updateZoneMessage = <span class="kwrd">new</span> UpdateRawZone();
            updateZoneMessage.Body = zoneState;

            _mainPort.Post(updateZoneMessage);
            <span class="kwrd">break</span>;
…</pre>
<p>UpdateRawZoneRequest is the message payload and is used to send data about a zone change event to a subscriber. UpdateRawZone is the actual message type that is transmitted on the port for the ElkService.</p>
<pre class="csharpcode">[DataContract]
[Description(<span class="str">&quot;UpdateRawZone Request Message Payload&quot;</span>)]
<span class="kwrd">public</span> <span class="kwrd">class</span> UpdateRawZoneRequest
{
    [DataMember]
    <span class="kwrd">public</span> <span class="kwrd">byte</span> Id { get; set; }

    [DataMember]
    <span class="kwrd">public</span> <span class="kwrd">byte</span> State { get; set; }
}


<span class="rem">/// &lt;summary&gt;</span>
<span class="rem">/// Update Elk zone status</span>
<span class="rem">/// &lt;/summary&gt;</span>
[Description(<span class="str">&quot;UpdateZone request message&quot;</span>)]
<span class="kwrd">public</span> <span class="kwrd">class</span> UpdateRawZone : Update&lt;UpdateRawZoneRequest,
        PortSet&lt;DefaultUpdateResponseType, Fault&gt;&gt;
{
}</pre>
<p>The message processing code can also be written a bit more compactly as:</p>
<pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">void</span> ProcessRawElkMessage(<span class="kwrd">string</span> message)
{
    <span class="kwrd">string</span> messageType = message.Substring(2, 2);

    <span class="kwrd">switch</span> (messageType)
    {
        <span class="kwrd">case</span> <span class="str">&quot;ZC&quot;</span>: <span class="rem">// Zone status change</span>
            var updateZoneMessage = <span class="kwrd">new</span> UpdateRawZone
            {
                Body = <span class="kwrd">new</span> UpdateRawZoneRequest
                {
                    Id = <span class="kwrd">byte</span>.Parse(message.Substring(4, 3)),
                    State = <span class="kwrd">byte</span>.Parse(message.Substring(7, 1),
                          NumberStyles.HexNumber)
                }
            };

            _mainPort.Post(updateZoneMessage);
            <span class="kwrd">break</span>;
…</pre>
<p>UpdateRawZoneHandler is a message receiver that is active on the main port and which responds to the update message by updating internal state, and notifying subscribers of the change in state.</p>
<pre class="csharpcode">[ServiceHandler(ServiceHandlerBehavior.Exclusive)]
<span class="kwrd">public</span> IEnumerator&lt;ITask&gt; UpdateRawZoneHandler(UpdateRawZone message)
{
    _state.ZoneStates[message.Body.Id - 1] = message.Body.State;

    SendNotification(_submgrPort, message);

    message.ResponsePort.Post(DefaultUpdateResponseType.Instance);

    <span class="kwrd">yield</span> <span class="kwrd">break</span>;
}</pre>
<h3>In the Zone</h3>
<p>The ElkService represents the core service that communicates with the Elk M1G hardware. The next service – ElkZoneSensor – represents a higher level “sensor array” that is attached to the Elk hardware. ElkZoneSensor “partners” with the ElkService. This means
 that the ElkZoneSensor relies on the ElkService to function. The DSS infrastructure will ensure that the ElkService is started if needed when starting the ElkZoneSensor service.</p>
<p>The ElkZoneSensor subscribes to updates from the ElkService for changes in the hardware zones. When these changes occur, the ElkService notifies the ElkZoneSensor which updates its state and notifies any of its subscribers. The ElkZoneSensor uses a higher
 level message – UpdateZone – that contains a sensor ID and an enumeration that describes the state of the sensor.</p>
<pre class="csharpcode">[DataContract]
<span class="kwrd">public</span> <span class="kwrd">class</span> Zone
{
    [DataMember]
    [Description(<span class="str">&quot;The Elk hardware zone id of the sensor&quot;</span>)]
    [DataMemberConstructor]
    <span class="kwrd">public</span> <span class="kwrd">byte</span> Id { get; set; }

    [DataMember]
    [Description(<span class="str">&quot;The Elk defined state of the sensor&quot;</span>)]
    <span class="kwrd">public</span> ZoneStatus Status { get; set; }
}</pre>
<h3>Candlepower</h3>
<p>The next services that we need for the robotic house are services to control the lights. In this case, I started with a
<i>generic</i> contract for the DSS service. A generic contract in DSS terms just defines the set of messages to which a service will respond and defines the port type on which those messages will be sent. The generic contract does not contain code to actually
 implement the service behavior. One of the benefits of a generic service contract is that you can specify the contract, write algorithms that use the contract, and later connect the generic service contracts to code that actually implements the behavior. This
 is very much like programming to an abstract interface in the object oriented world, and having multiple classes that actually implement the interface.</p>
<p>We start off with a generic service called the GenericDimmer that represents a dimmer switch and we implement two concrete services: the SimulatedDimmer and the ZWaveDimmer. SimulatedDimmer just logs a message to represent its state change. The ZWaveDimmer
 actually controls the lights via a hardware Z-Wave controller.</p>
<p>Here's what the GenericDimmer contract looks like:</p>
<pre class="csharpcode"><span class="kwrd">namespace</span> Robotics.GenericHouseControls.Dimmer
{


    <span class="rem">/// &lt;summary&gt;</span>
    <span class="rem">/// GenericDimmer Contract class</span>
    <span class="rem">/// &lt;/summary&gt;</span>
    <span class="kwrd">public</span> <span class="kwrd">sealed</span> <span class="kwrd">class</span> Contract
    {
        <span class="rem">/// &lt;summary&gt;</span>
        <span class="rem">/// The Dss Service contract</span>
        <span class="rem">/// &lt;/summary&gt;</span>
        [DataMember]
        <span class="kwrd">public</span> <span class="kwrd">const</span> String Identifier = <span class="str">&quot;http://schemas.tempuri.org/2008/04/generichousecontrolsdimmer.html&quot;</span>;
    }

    <span class="rem">/// &lt;summary&gt;</span>
    <span class="rem">/// The GenericDimmer State</span>
    <span class="rem">/// &lt;/summary&gt;</span>
    [DataContract]
    <span class="kwrd">public</span> <span class="kwrd">class</span> GenericDimmerState
    {
        [DataMember]
        [DataMemberConstructor(Order = 1)]
        <span class="kwrd">public</span> <span class="kwrd">int</span> Id;

        [DataMember]
        <span class="kwrd">public</span> <span class="kwrd">int</span> Level;
    }

    <span class="rem">/// &lt;summary&gt;</span>
    <span class="rem">/// GenericDimmer Main Operations Port</span>
    <span class="rem">/// &lt;/summary&gt;</span>
    [ServicePort(AllowMultipleInstances = <span class="kwrd">true</span>)]
    <span class="kwrd">public</span> <span class="kwrd">class</span> GenericDimmerOperations : PortSet&lt;DsspDefaultLookup, DsspDefaultDrop, Get, HttpGet, On, Off, SetLevel&gt;
    {
    }

    <span class="rem">/// &lt;summary&gt;</span>
    <span class="rem">/// GenericDimmer Get Operation</span>
    <span class="rem">/// &lt;/summary&gt;</span>
    <span class="kwrd">public</span> <span class="kwrd">class</span> Get : Get&lt;GetRequestType, PortSet&lt;GenericDimmerState, Fault&gt;&gt;
    {

        <span class="rem">/// &lt;summary&gt;</span>
        <span class="rem">/// GenericDimmer Get Operation</span>
        <span class="rem">/// &lt;/summary&gt;</span>
        <span class="kwrd">public</span> Get()
        {
        }

        <span class="rem">/// &lt;summary&gt;</span>
        <span class="rem">/// GenericDimmer Get Operation</span>
        <span class="rem">/// &lt;/summary&gt;</span>
        <span class="kwrd">public</span> Get(Microsoft.Dss.ServiceModel.Dssp.GetRequestType body) :
            <span class="kwrd">base</span>(body)
        {
        }

        <span class="rem">/// &lt;summary&gt;</span>
        <span class="rem">/// GenericDimmer Get Operation</span>
        <span class="rem">/// &lt;/summary&gt;</span>
        <span class="kwrd">public</span> Get(Microsoft.Dss.ServiceModel.Dssp.GetRequestType body, Microsoft.Ccr.Core.PortSet&lt;GenericDimmerState, W3C.Soap.Fault&gt; responsePort) :
            <span class="kwrd">base</span>(body, responsePort)
        {
        }
    }

    [DataContract]
    <span class="kwrd">public</span> <span class="kwrd">class</span> OnRequest
    {
    }

    [Description(<span class="str">&quot;Turn the switch on&quot;</span>)]
    <span class="kwrd">public</span> <span class="kwrd">class</span> On : Update&lt;OnRequest, PortSet&lt;DefaultUpdateResponseType, Fault&gt;&gt;
    {
    }

    [DataContract]
    <span class="kwrd">public</span> <span class="kwrd">class</span> OffRequest
    {
    }

    [Description(<span class="str">&quot;Turn the switch off&quot;</span>)]
    <span class="kwrd">public</span> <span class="kwrd">class</span> Off : Update&lt;OffRequest, PortSet&lt;DefaultUpdateResponseType, Fault&gt;&gt;
    {
    }

    [DataContract]
    <span class="kwrd">public</span> <span class="kwrd">class</span> SetLevelRequest
    {
        [DataMember]
        [DataMemberConstructor]
        <span class="kwrd">public</span> <span class="kwrd">int</span> Level { get; set; }
    }

    [Description(<span class="str">&quot;Set the dim level&quot;</span>)]
    <span class="kwrd">public</span> <span class="kwrd">class</span> SetLevel : Update&lt;SetLevelRequest, PortSet&lt;DefaultUpdateResponseType, Fault&gt;&gt;
    {
    }
}</pre>
<p>This code defines the contract only. Now to implement that contract we can run the DssNewService utility with the /implement switch and generate a service based on this contract. For example:
</p>
<p>dssnewservice /s:SimulatedDimmer /n:Robotics.HouseControls.SimulatedDimmer /i:GenericHouseControls.Y2008.M04.Proxy.dll</p>
<p>will generate a new service called SimulatedDimmer in the .NET namespace Robotics.HouseControls.SimulatedDimmer. The service will have a stubbed out implementation of the GenericDimmer contract including service startup code, state, and stubbed out message
 handlers.</p>
<p>Here's what the main service file looks like for the simulated dimmer after I added logging to the generated methods. I've also deleted some of the using statements for easier reading.</p>
<pre class="csharpcode"><span class="kwrd">using</span> pxdimmer = Robotics.GenericHouseControls.Dimmer.Proxy;

<span class="kwrd">namespace</span> Robotics.HouseControls.SimulatedDimmer
{


    <span class="rem">/// &lt;summary&gt;</span>
    <span class="rem">/// House Controls Service</span>
    <span class="rem">/// &lt;/summary&gt;</span>
    [DisplayName(<span class="str">&quot;Simulated Dimmer&quot;</span>)]
    [Description(<span class="str">&quot;The Simulated Dimmer Switch Service&quot;</span>)]
    [Contract(Contract.Identifier)]
    [AlternateContract(pxdimmer.Contract.Identifier)]
    <span class="kwrd">public</span> <span class="kwrd">class</span> SimulatedDimmerService : DsspServiceBase
    {

        <span class="rem">/// &lt;summary&gt;</span>
        <span class="rem">/// _state</span>
        <span class="rem">/// &lt;/summary&gt;</span>
        [ServiceState]
        [InitialStatePartner(Optional = <span class="kwrd">true</span>)]
        <span class="kwrd">private</span> pxdimmer.GenericDimmerState _state = <span class="kwrd">new</span> pxdimmer.GenericDimmerState();

        <span class="rem">/// &lt;summary&gt;</span>
        <span class="rem">/// _main Port</span>
        <span class="rem">/// &lt;/summary&gt;</span>
        [ServicePort(<span class="str">&quot;/simulateddimmer&quot;</span>, AllowMultipleInstances = <span class="kwrd">true</span>)]
        <span class="kwrd">private</span> pxdimmer.GenericDimmerOperations _mainPort = <span class="kwrd">new</span> pxdimmer.GenericDimmerOperations();


        <span class="rem">/// &lt;summary&gt;</span>
        <span class="rem">/// Default Service Constructor</span>
        <span class="rem">/// &lt;/summary&gt;</span>
        <span class="kwrd">public</span> SimulatedDimmerService(DsspServiceCreationPort creationPort) :
            <span class="kwrd">base</span>(creationPort)
        {
        }

        <span class="rem">/// &lt;summary&gt;</span>
        <span class="rem">/// Service Start</span>
        <span class="rem">/// &lt;/summary&gt;</span>
        <span class="kwrd">protected</span> <span class="kwrd">override</span> <span class="kwrd">void</span> Start()
        {
            <span class="kwrd">base</span>.Start();

            <span class="rem">// Add service specific initialization here.</span>
            LogInfo(<span class="kwrd">string</span>.Format(<span class="str">&quot;Dimmer State =&gt; Id:{0} Level:{1}&quot;</span>, _state.Id, _state.Level));
        }

        [ServiceHandler(ServiceHandlerBehavior.Concurrent)]
        <span class="kwrd">public</span> IEnumerator&lt;ITask&gt; OnHandler(pxdimmer.On update)
        {
            LogInfo(<span class="kwrd">string</span>.Format(<span class="str">&quot;Simulated Dimmer =&gt; Id:{0} On&quot;</span>, _state.Id));

            update.ResponsePort.Post(DefaultUpdateResponseType.Instance);
            <span class="kwrd">yield</span> <span class="kwrd">break</span>;
        }

        [ServiceHandler(ServiceHandlerBehavior.Concurrent)]
        <span class="kwrd">public</span> IEnumerator&lt;ITask&gt; OffHandler(pxdimmer.Off update)
        {
            LogInfo(<span class="kwrd">string</span>.Format(<span class="str">&quot;Simulated Dimmer =&gt; Id:{0} Off&quot;</span>, _state.Id));

            update.ResponsePort.Post(DefaultUpdateResponseType.Instance);
            <span class="kwrd">yield</span> <span class="kwrd">break</span>;
        }

        [ServiceHandler(ServiceHandlerBehavior.Exclusive)]
        <span class="kwrd">public</span> IEnumerator&lt;ITask&gt; SetLevelHandler(pxdimmer.SetLevel update)
        {           
            _state.Level = update.Body.Level;
            LogInfo(<span class="kwrd">string</span>.Format(<span class="str">&quot;Simulated Dimmer =&gt; Id:{0} Level:{1}&quot;</span>, _state.Id, update.Body.Level));

            update.ResponsePort.Post(DefaultUpdateResponseType.Instance);            
            <span class="kwrd">yield</span> <span class="kwrd">break</span>;
        }
    }
}</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>Check the code download for the implementation of the ZWaveDimmer. You'll find that it's pretty straightforward. It should be simple to write similar code if you use a different technology for lighting control. You just write a service that matches the GenericDimmer
 contract, and you should be able to configure the GenericDimmer using a manifest to point to the actual dimmer service. Check out the documentation in Microsoft Robotics Developer Studio for more information on manifests and how to use the manifest editor.</p>
<h3>Bulb On, Bulb Off!</h3>
<p>The “Hello, World” application for any home automation software that I've tested in my house has always been the automating of my pantry light. The pantry has a Z-Wave light switch inside and the pantry door has a contact switch that is connected to the
 Elk M1G. When the door is open, we want the light to turn on, and when the door is closed we want the light to turn off. Now that we have all the pieces for this, here's what the VPL diagram for this looks like:</p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/8544962/image.png"><img title="image" height="259" alt="image" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/8544962/image_thumb.png" width="500" border="0"></a>
</p>
<p>As you can see, it was also a relatively easy matter to add text-to-speech to announce the opening and closing of the pantry door. You may find out quickly that this is an annoyance to those in the testing areas – for me that was my kitchen – so it's nice
 to know that two quick hits of the delete key will also remove the text-to-speech. This is part of the beauty of the Microsoft Robotics programming model!</p>
<p>The second example shows how you can use a motion detector – in this case connected to zone 19 on the Elk – to trigger a light. The light comes on at a level that you control from the VPL code, and stays on for a duration that you can also control from the
 code. For the example, I set the timer to a pretty low level, but you can customize it. You could also add additional rules to only turn on the light at certain times, or better still connect an ambient light sensor to decide whether you should turn the light
 on.</p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/8544962/image_3.png"><img title="image" height="319" alt="image" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/8544962/image_thumb_3.png" width="500" border="0"></a>
</p>
<p>In this diagram, if motion is detected – that is zone 19 is triggered with a status of ViolatedOpen – the light is turned on at a low dim level and a timer is set. When the timer completes, the light is turned off. If, however, there is more motion before
 the timer completes, the SetTimer message will cancel the old timeout and restart the timer.</p>
<p>There are more VPL examples included in the download including an extra service that you can use to send email from your VPL code. I'm experimenting with using the email service to send me a text message whenever my alarm is armed or disarmed.</p>
<h3>Miscellanea</h3>
<p>Since I haven't had a lot of time to study the testing framework and simulation environments used by Microsoft Robotics, I included a service called the ElkTestDataPlayback service that allows me to replay the contents of a text file to simulate the ElkService
 getting actual data. This works pretty well for testing. The contents of the file are merely raw data captures that I made from the data sent by the Elk M1G panel. To use this service in VPL, you just drop it onto your diagram, configure it's TestDataFileName
 via “Set initial configuration” to point to a data file, and send it a message to start playback.</p>
<p><b>Important:</b> If you have the Elk hardware, you will want to uncomment the
<i>SpawnIterator(ElkReader)</i> line in the ElkService.Start method. I know this is a hack for now. It would probably be better to write a SimulatedElk service based on a generic service contract. If I have time, I will do that in the future. That would involve
 a lot more work than I had for this weekend project!</p>
<h3>TODO List</h3>
<p>Since this was my first foray into Microsoft Robotics Developer Studio and I had limited time to really explore the features in depth, there are a few things that I've left unimplemented. Here are some of the things that I would like to expand on in the
 future:</p>
<p>1. <b>Support for more of the Elk features:</b> Currently, I only support Zone Change notifications. Fuller support of the Elk hardware would not be difficult and would be beneficial to anyone wanting to use this on an ongoing basis. There's some stub code
 for a few other notifications if you want to add to the service.</p>
<p>2. <b>Generic contracts for the Elk M1G:</b> I didn't base the Elk services on generic contract because I'm not familiar with enough other types of security and automation panels to make the needed generalizations. It would be interesting to try to come
 up with something more generic. I thought about using the Generic Contact Sensor array, but I'm not sure that it models what we need. For example, a door contact is considered
<b><i>violated</i></b> when it's open, but a water sensor is considered <b><i>violated</i></b> when it's closed.</p>
<p>3. <b>Additional Z-Wave features:</b> I've left out notification for lighting level changes, support for scenes and a host of other features. There's so much more that's possible with full Z-Wave support.</p>
<p>4. <b>Refined Generic Contracts:</b> Generic contracts allow developers to write code that is independent of the final hardware. That is one of the major benefits of the model used by Microsoft Robotics. You could for example have a generic light switch
 for simulation and testing, and based on configuration you could plug in a Z-Wave switch or an Insteon switch when it's time to deploy the actual solution.</p>
<p>5. <b>Simulation Support:</b> One of the major benefits of Microsoft Robotics Developer Studio is the simulation environment. For example, if we had a motion detector in the simulation environment, we could test some of the algorithms that I presented above
 by having a simulated mobile robot “violate” the motion detector's zone and trigger the corresponding VPL code.</p>
<p>6. <b>Exception Handling:</b> As I build more on the code in this article, I'll add exception handling and retry logic. Microsoft Robotics has some extremely robust features such as Causalities that make handling exceptions in a concurrent environment much
 easier.</p>
<p>7. <b>HttpHandlers:</b> I have a start at code for handling HTTP requests in the ZWaveController service. Handling HTTP requests is handy for building client applications that access your services without themselves having to be DSS services.</p>
<p>Other experiments that might be fun to try include integrating your Microsoft Robotics controlled home with remote control applications that are based on WPF or Silverlight, or perhaps integrating control from a Windows Media Center PC or Windows Home Server.</p>
<p>I hope you enjoy Microsoft Robotics Developer Studio as much as I have. I look forward to seeing what other people build with this fantastic technology. If people are interested, I can continue to share my home automation experiments. I think Microsoft Robotics
 Developer Studio will be the major tool in my home automation toolbox for quite some time.</p>
<h3>Project Settings Note:</h3>
<p>You will have to modify the project settings for the projects included in the House.Robot solution since your installation of Microsoft Robotics Developer Studio will be in a different directory than mine. The DssProjectMigration.exe command line tool will
 make short work of this. Just run it with a parameter that specifies the directory you want it to search, and it will find all of the project files in that directory and subdirectories and convert them to be buildable with your installation settings.</p>
<p>If you use the ElkTestDataPlayback service, in the examples, you'll need to set the path to the location of the test data file either in the initial configuration for the component, or in a manifest that configures the component. Make sure that you
<b>do not</b> put quotes around the path name. I included a test data file from my system.</p>
 <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Tags/home+automation/RSS&WT.dl=0&WT.entryid=Entry:RSSView:57770cc07d4e4541ac5b9e7600cf847d">]]></description>
      <comments>http://channel9.msdn.com/coding4fun/articles/Home-Automation-with-Microsoft-Robotics-Developer-Studio-2008</comments>
      <itunes:summary>





Typically we think of robots as machines from science fiction or as industrial robots such as those that build and paint cars. In the world of Microsoft Robotics Developer Studio, anything that has sensors and/or actuators can be considered a robot. In this
 article, we look at an automated house as a robot and apply the Decentralized Software Services model of Microsoft Robotics Studio to implementing some home automation tasks. 




Charles Stacy Harris III

Difficulty: Intermediate
Time Required: 
6-10 hours
Cost: $100-$200 for hardware (Optional, $0 if using only simulation)
Software: Visual Studio or Visual Studio Express, Microsoft Robotics Developer Studio 2008 CTP April,
ControlThink Z-Wave PC SDK

Hardware: (All Optional) Elk M1G/M1EZ Security and Automation Panel, Z-Wave Dimmer Switches, Z-Wave Controller such as the ControlThink ThinkStick or equivalent.
Download: Download








House, Robot
Those of you who know me or who have read my previous Coding4Fun article 
Home Automation with Windows Workflow, know that I&#39;m nuts about home automation. I&#39;m even more passionate about robotics and I&#39;ve wanted to try out some things with Microsoft Robotics Studio since the very first version. Recently I had a long weekend, so
 I spent a few hours putting together some simple home automation examples using Microsoft Robotics Developer Studio 2008 CTP April. Check out the
Microsoft Robotics Developer Center for details on how to get the CTP. 
The examples in this article duplicate what I did using Windows Workflow in my previous article, but instead use the Decentralized Software Services (DSS) approach of Microsoft Robotics, and Microsoft Visual Programming Language (VPL) for a simple way to
 write automation tasks. The 
Microsoft Robotics Developer Center contains a lot of detailed information about DSS, VPL, and the other technologies found in Microsoft Robotics Developer Studio. For now, let&#39;s just cover some basics. To get further along with the code in th</itunes:summary>
      <link>http://channel9.msdn.com/coding4fun/articles/Home-Automation-with-Microsoft-Robotics-Developer-Studio-2008</link>
      <pubDate>Sat, 24 May 2008 03:56:55 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/coding4fun/articles/Home-Automation-with-Microsoft-Robotics-Developer-Studio-2008</guid>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/c4f/images/8544962_100.jpg" height="75" width="100"></media:thumbnail>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/c4f/images/8544962_220.jpg" height="165" width="220"></media:thumbnail>      
      <dc:creator>Charles Stacy Harris III</dc:creator>
      <itunes:author>Charles Stacy Harris III</itunes:author>
      <slash:comments>20</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/coding4fun/articles/Home-Automation-with-Microsoft-Robotics-Developer-Studio-2008/RSS</wfw:commentRss>
      <category>Hardware</category>
      <category>Robotics</category>
      <category>Home Automation</category>
    </item>
  <item>
      <title>Automate Your Home with Your Windows Home Server</title>
      <description><![CDATA[For home automation enthusiasts, <a href="http://www.wegotserved.co.uk/2008/03/19/mcontrol-for-windows-home-server-automate-your-home/">comes</a> a plugin for Windows Home Server called &quot;<a href="http://www.embeddedautomation.com/">Embedded Automation's mControl for Windows Home Server</a>.&quot; With this WHS plugin, you can configure and control everything in your home from lighting to AC to thermostats to security cameras from directly within WHS or from any other networked devices like Vista Media Center, Xbox 360, Windows Mobile phones, or any of the new Windows Media Center v2 Extenders. mControl can be used to control a couple of devices or it can be expanded to control all aspects of your home with no need to purchase additional software packages. All you need is mControl. You can download a free trial of mControl for WHS from <a href="http://www.embeddedautomation.com/EAHAmControl.htm">here</a> to try it out. <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Tags/home+automation/RSS&WT.dl=0&WT.entryid=Entry:RSSView:c7e7095f592246999f769e0e00960e05">]]></description>
      <comments>http://channel9.msdn.com/Blogs/coolstuff/Automate-Your-Home-with-Your-Windows-Home-Server</comments>
      <itunes:summary>For home automation enthusiasts, comes a plugin for Windows Home Server called &amp;quot;Embedded Automation&#39;s mControl for Windows Home Server.&amp;quot; With this WHS plugin, you can configure and control everything in your home from lighting to AC to thermostats to security cameras from directly within WHS or from any other networked devices like Vista Media Center, Xbox 360, Windows Mobile phones, or any of the new Windows Media Center v2 Extenders. mControl can be used to control a couple of devices or it can be expanded to control all aspects of your home with no need to purchase additional software packages. All you need is mControl. You can download a free trial of mControl for WHS from here to try it out.</itunes:summary>
      <link>http://channel9.msdn.com/Blogs/coolstuff/Automate-Your-Home-with-Your-Windows-Home-Server</link>
      <pubDate>Thu, 20 Mar 2008 16:33:00 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/Blogs/coolstuff/Automate-Your-Home-with-Your-Windows-Home-Server</guid>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/previewImages/320/on10_2984c151-630b-446e-a9ab-875a81b4a55e.jpg" height="0" width="0"></media:thumbnail>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/previewImages/85/on10_49c8c47e-1eb9-4d0a-8a50-919910853066.jpg" height="64" width="85"></media:thumbnail>      
      <dc:creator>Sarah Perez</dc:creator>
      <itunes:author>Sarah Perez</itunes:author>
      <slash:comments>0</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/Blogs/coolstuff/Automate-Your-Home-with-Your-Windows-Home-Server/RSS</wfw:commentRss>
      <category>Windows Home Server</category>
      <category>Home Automation</category>
      <category>WHS</category>
      <category>Plugins</category>
      <category>Plug-in</category>
    </item>
  <item>
      <title>Automate your home, AV with life|ware</title>
      <description><![CDATA[One of the most impressive displays at CES 2008 wasn't on the show floor. Instead of&nbsp;a traditional plasma-screens-and-pamphlets&nbsp;CES booth life|ware chose to build <strong><span>three</span></strong> fully functional&nbsp;<strong><span>homes</span></strong> out&nbsp;front of the Las Vegas Convention Center&nbsp;to show&nbsp;off&nbsp;the various home automation products and solutions they offer.<br><br>Jason from <a href="http://www.life-ware.com/index.php" target="_blank">life|ware </a>gave us a tour of the living room in one of the e-homes and showed us some very cool home automation solutions integrated with Windows Vista Media Center.<br><br>For more info on life|ware visit <a href="http://www.life-ware.com">http://www.life-ware.com</a> <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Tags/home+automation/RSS&WT.dl=0&WT.entryid=Entry:RSSView:d3ad5ca7153440a687069e0f00b89fcc">]]></description>
      <comments>http://channel9.msdn.com/Blogs/NicFill/Automate-your-home-with-LifeWare</comments>
      <itunes:summary>One of the most impressive displays at CES 2008 wasn&#39;t on the show floor. Instead of&amp;nbsp;a traditional plasma-screens-and-pamphlets&amp;nbsp;CES booth life|ware chose to build three fully functional&amp;nbsp;homes out&amp;nbsp;front of the Las Vegas Convention Center&amp;nbsp;to show&amp;nbsp;off&amp;nbsp;the various home automation products and solutions they offer.Jason from life|ware gave us a tour of the living room in one of the e-homes and showed us some very cool home automation solutions integrated with Windows Vista Media Center.For more info on life|ware visit http://www.life-ware.com</itunes:summary>
      <itunes:duration>371</itunes:duration>
      <link>http://channel9.msdn.com/Blogs/NicFill/Automate-your-home-with-LifeWare</link>
      <pubDate>Tue, 29 Jan 2008 09:48:00 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/Blogs/NicFill/Automate-your-home-with-LifeWare</guid>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/previewImages/320/on10_c5f9c5d8-0ee7-40e3-83b7-f4c956267cb5.jpg" height="0" width="0"></media:thumbnail>
      <media:thumbnail url="http://mschnlnine.vo.llnwd.net/d1/on10/3/5/7/0/2/CES2008Lifeware_small_on10.jpg" height="64" width="85"></media:thumbnail>
      <media:group>
        <media:content url="http://mschnlnine.vo.llnwd.net/d1/on10/3/5/7/0/2/CES2008Lifeware_2MB_on10.wmv" expression="full" duration="371" fileSize="116096184" type="video/x-ms-wmv" medium="video"></media:content>
        <media:content url="http://mschnlnine.vo.llnwd.net/d1/on10/3/5/7/0/2/CES2008Lifeware_on10.mp3" expression="full" duration="371" fileSize="2972862" type="audio/mp3" medium="audio"></media:content>
        <media:content url="http://mschnlnine.vo.llnwd.net/d1/on10/3/5/7/0/2/CES2008Lifeware_on10.mp4" expression="full" duration="371" fileSize="22299571" type="video/mp4" medium="video"></media:content>
        <media:content url="http://mschnlnine.vo.llnwd.net/d1/on10/3/5/7/0/2/CES2008Lifeware_on10.wma" expression="full" duration="371" fileSize="3018139" type="audio/x-ms-wma" medium="audio"></media:content>
        <media:content url="http://mschnlnine.vo.llnwd.net/d1/on10/3/5/7/0/2/CES2008Lifeware_on10.wmv" expression="full" duration="371" fileSize="23524895" type="video/x-ms-wmv" medium="video"></media:content>
        <media:content url="http://mschnlnine.vo.llnwd.net/d1/on10/3/5/7/0/2/CES2008Lifeware_Zune_on10.wmv" expression="full" duration="371" fileSize="29479803" type="video/x-ms-wmv" medium="video"></media:content>
        <media:content url="mms://mschnlnine.wmod.llnwd.net/a1809/d1/on10/3/5/7/0/2/CES2008Lifeware_s_on10.wmv" expression="full" duration="371" fileSize="211" type="video/x-ms-wmv" medium="video"></media:content>
      </media:group>      
      <enclosure url="http://mschnlnine.vo.llnwd.net/d1/on10/3/5/7/0/2/CES2008Lifeware_on10.wmv" length="23524895" type="video/x-ms-wmv"></enclosure>
      <dc:creator>Nic Fillingham</dc:creator>
      <itunes:author>Nic Fillingham</itunes:author>
      <slash:comments>0</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/Blogs/NicFill/Automate-your-home-with-LifeWare/RSS</wfw:commentRss>
      <category>CES</category>
      <category>Media Center</category>
      <category>Vista</category>
      <category>Windows Vista</category>
      <category>Home Automation</category>
      <category>HTPC</category>
      <category>CES 2008</category>
    </item>
  <item>
      <title>Life|ware Home Automation</title>
      <description><![CDATA[<a href="http://www.exceptionalinnovation.com/index.php">Life|ware</a> is a home automation system whose goal is to merge control of your home with access to all of your digital entertainment. You can integrate Life|ware into Windows Media Center and, from there, you can manage your music, your photos, your videos, watch DVDs, and you can even schedule and record TV shows. With the system's home automation features, you can manage your home's lighting, thermostats, security systems, and distribute music throughout the house. They also have something called &quot;Life|scenes&quot;, which can be used to set a mood using all of your home's systems. There are pre-recorded Life|scenes like &quot;I'm Here,&quot; &quot;Goodbye,&quot; or &quot;Party Time,&quot; or you can program your own. The Life|ware remote control recalls the simplicity of Media Center - you use the six same buttons (My TV, My Music, My Pictures, My Videos, Play DVD and Settings). You can use Life|Ware through your TV with a Media Center PC, but also through a Media Center Extender on Xbox 360, from a PC or notebook PC on your home network, or from a <a href="http://www.exceptionalinnovation.com/prod_lifepoint.php">Life|Point touch screen</a>. The touch screens are all-digital, HD panels available in 8.9&quot; or 12.1&quot; screen sizes and many different finishes, allowing them to seamlessly integrate into its surroundings in your home. The screens have an ambient light sensor that automatically adjusts screen brightness according to room lighting and an automatic touch-to-wake power saving mode. <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Tags/home+automation/RSS&WT.dl=0&WT.entryid=Entry:RSSView:07333d85ff574dc0a4759e0e0094f14a">]]></description>
      <comments>http://channel9.msdn.com/Blogs/coolstuff/Lifeware-Home-Automation</comments>
      <itunes:summary>Life|ware is a home automation system whose goal is to merge control of your home with access to all of your digital entertainment. You can integrate Life|ware into Windows Media Center and, from there, you can manage your music, your photos, your videos, watch DVDs, and you can even schedule and record TV shows. With the system&#39;s home automation features, you can manage your home&#39;s lighting, thermostats, security systems, and distribute music throughout the house. They also have something called &amp;quot;Life|scenes&amp;quot;, which can be used to set a mood using all of your home&#39;s systems. There are pre-recorded Life|scenes like &amp;quot;I&#39;m Here,&amp;quot; &amp;quot;Goodbye,&amp;quot; or &amp;quot;Party Time,&amp;quot; or you can program your own. The Life|ware remote control recalls the simplicity of Media Center - you use the six same buttons (My TV, My Music, My Pictures, My Videos, Play DVD and Settings). You can use Life|Ware through your TV with a Media Center PC, but also through a Media Center Extender on Xbox 360, from a PC or notebook PC on your home network, or from a Life|Point touch screen. The touch screens are all-digital, HD panels available in 8.9&amp;quot; or 12.1&amp;quot; screen sizes and many different finishes, allowing them to seamlessly integrate into its surroundings in your home. The screens have an ambient light sensor that automatically adjusts screen brightness according to room lighting and an automatic touch-to-wake power saving mode.</itunes:summary>
      <link>http://channel9.msdn.com/Blogs/coolstuff/Lifeware-Home-Automation</link>
      <pubDate>Mon, 24 Dec 2007 22:08:00 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/Blogs/coolstuff/Lifeware-Home-Automation</guid>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/previewImages/320/on10_c3a612cf-8075-4489-9a80-b71c14931412.jpg" height="0" width="0"></media:thumbnail>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/previewImages/85/on10_295ac5a7-ad4e-4d98-a4b7-906ecd671f54.jpg" height="64" width="85"></media:thumbnail>      
      <dc:creator>Sarah Perez</dc:creator>
      <itunes:author>Sarah Perez</itunes:author>
      <slash:comments>0</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/Blogs/coolstuff/Lifeware-Home-Automation/RSS</wfw:commentRss>
      <category>Media Center</category>
      <category>Home Automation</category>
      <category>MCE</category>
    </item>
  <item>
      <title>Home Automation Systems with Vista SideShow</title>
      <description><![CDATA[Superna Systems is a company that is <a href="http://www.sideshowdevices.com/superna-home-automation-gadgets-for-sideshow">making use of Vista's SideShow technology </a>in their home automation systems. With their <a href="http://www.supernasystems.com/products/software/controlware/">ControlWare</a> software for Vista, you can control your home's security system, lights, climate, music, and&nbsp;televsions. All of these can be controlled through your computer or&nbsp;through their&nbsp;SideShow devices such as color LCDs, <a href="http://www.supernasystems.com/products/touch_panels/">Touch Panels</a>, or even a Windows CE PDA.&nbsp;Dealers will be able to configure these gadgets to a&nbsp;customer's needs. With over 1500 drivers, Superna's media steaming works across a variety of formats and operating systems including Vista, Media Center, XP and Linux. <br><br>Another home automation company, <a href="http://lagotek.com/">Lagotek</a>, has also just debuted&nbsp;<a href="http://www.sideshowdevices.com/windows-vista-media-center-integration-and-sideshow-support">version 3.0 of their Home Intelligence Platform&nbsp;(HIP)</a>&nbsp;with Microsoft Windows Vista Media Center Integration and SideShow Support. HIP's integration with Vista enables users to control their homes from wall-mounted security systems, remote controls, or PDAs. Currently the Lagotek platform can automate climate control systems with multiple zones of heating and air conditioning, lighting, distributed audio, video monitoring, Media Center Control, and irrigation. <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Tags/home+automation/RSS&WT.dl=0&WT.entryid=Entry:RSSView:b109de0d2f9948f090899e0d00d82dd8">]]></description>
      <comments>http://channel9.msdn.com/Blogs/coolstuff/Home-Automation-Systems-with-Vista-SideShow</comments>
      <itunes:summary>Superna Systems is a company that is making use of Vista&#39;s SideShow technology in their home automation systems. With their ControlWare software for Vista, you can control your home&#39;s security system, lights, climate, music, and&amp;nbsp;televsions. All of these can be controlled through your computer or&amp;nbsp;through their&amp;nbsp;SideShow devices such as color LCDs, Touch Panels, or even a Windows CE PDA.&amp;nbsp;Dealers will be able to configure these gadgets to a&amp;nbsp;customer&#39;s needs. With over 1500 drivers, Superna&#39;s media steaming works across a variety of formats and operating systems including Vista, Media Center, XP and Linux. Another home automation company, Lagotek, has also just debuted&amp;nbsp;version 3.0 of their Home Intelligence Platform&amp;nbsp;(HIP)&amp;nbsp;with Microsoft Windows Vista Media Center Integration and SideShow Support. HIP&#39;s integration with Vista enables users to control their homes from wall-mounted security systems, remote controls, or PDAs. Currently the Lagotek platform can automate climate control systems with multiple zones of heating and air conditioning, lighting, distributed audio, video monitoring, Media Center Control, and irrigation.</itunes:summary>
      <link>http://channel9.msdn.com/Blogs/coolstuff/Home-Automation-Systems-with-Vista-SideShow</link>
      <pubDate>Wed, 01 Aug 2007 07:56:00 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/Blogs/coolstuff/Home-Automation-Systems-with-Vista-SideShow</guid>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/content/on10/blogs/superna2.jpg" height="240" width="320"></media:thumbnail>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/content/on10/entries/previewsmall/18468.jpg" height="64" width="85"></media:thumbnail>      
      <dc:creator>Sarah Perez</dc:creator>
      <itunes:author>Sarah Perez</itunes:author>
      <slash:comments>2</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/Blogs/coolstuff/Home-Automation-Systems-with-Vista-SideShow/RSS</wfw:commentRss>
      <category>Vista</category>
      <category>Windows Vista</category>
      <category>SideShow</category>
      <category>Home Automation</category>
    </item>
  <item>
      <title>Control Windows Media Center using a Windows Mobile 5 Device</title>
      <description><![CDATA[
<p>This article demonstrates how to use a smartphone running Windows Mobile 5 to remotely control a host machine running Windows Media Center. I will describe how to create an add-in application that runs within Windows Media Center, and how to create a Windows
 Mobile 5 application that you can use to communicate with the Media Center over a wireless internet connection. Finally, I will demonstrate how to use this implementation to manipulate Media Center using the Windows Media Center API.
</p>
<p><a href="http://blogs.claritycon.com/blogs/matt_ivers/default.aspx">Matt Ivers</a>
</p>
<p><b>Difficulty: </b>Intermediate </p>
<p><b>Time Required:</b> 6-10 hours</p>
<p><b>Cost: </b>$100-$200 </p>
<p><b>Software: </b><a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=dc6c00cb-738A-4B97-8910-5cd29ab5f8d9&amp;DisplayLang=en">Visual Basic or Visual C# Express Editions</a>,
<a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=A43EA0B7-B85F-4612-AA08-3BF128C5873E&amp;displaylang=en">
Windows Media Center SDK 5.0</a>, <a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=dc6c00cb-738A-4B97-8910-5cd29ab5f8d9&amp;DisplayLang=en">
Windows Mobile 5.0 Smartphone SDK</a> </p>
<p><b>Hardware: </b>Mobile device running Windows Mobile 5.0 </p>
<p><b>Download: </b><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/2632164/WMC_Remote_Code.zip">C# and VB.Net</a></p>
<ul>
</ul>
<h3>Introduction</h3>
Starting with Windows Media Center Edition 2005, Media Center added extensibility support through hosted add-in assemblies. By implementing an add-in interface and registering the assembly with Media Center, the add-in assembly is given access to the Microsoft.MediaCenter.Hosting.AddInHost
 object. Using this object model, an add-in assembly can programmatically inspect and manipulate various aspects of Windows Media Center. In addition to the exposed Media Center namespaces, the add-in has complete access to all the capabilities of the .NET
 Framework.
<p>&nbsp;</p>
<p>By combining the power of a Media Center add-in with a mobile device running Windows Mobile 5.0, we can extend the capabilities of a Media Center add-in even further. The add-in service I developed runs as a listener service within Windows Media Center on
 the host machine. It is initialized when Windows Media Center is started, runs invisibly in the background, and allows mobile devices to connect and submit requests to it. The mobile solution leverages an existing WiFi internet connection to communicate with
 the add-in via TCP socket connections. The mobile device runs a .NET Compact Framework 2.0 forms application designed for devices running Windows Mobile 5 or higher.</p>
<p>The included remote control application is capable of the following functionality:
</p>
<ul>
<li>Retrieve metadata about currently loaded media </li><li>Affect playback of currently loaded media – Play, Pause, Stop, Next Track, Previous Track
</li><li>Control Media Center volume </li><li>Retrieve a list of available media – Photos, Audio, Video </li><li>Explicitly load media for playback – Audio, Video </li></ul>
<h3>Creating a Windows Media Center add-in application</h3>
The first step in our implementation is creating an add-in that will run within Windows Media Center. This involves creating a new Windows Media Center Presentation Layer Application project, implementing an interface, signing the assembly, and creating a setup
 project to install the assembly and register it with Media center.
<p>&nbsp;</p>
<h4>Creating a new project – Windows Media Center Presentation Layer Application</h4>
Installing the Windows Media Center SDK makes this step simple. Once installed, you create this project like any other in Visual Studio:
<p><img border="0" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/2632164/1_Create_new_WMC_presentation_layer_.jpg" width="500" height="351">&nbsp;</p>
<p><em>Figure 1 - Creating the project</em></p>
<p>Using the Windows Media Center Presentation Layer Application project template yields the following project skeleton:</p>
<p><img border="0" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/2632164/2_AddIn_demo_project3.jpg" width="209" height="240">
</p>
<p><em>Figure&nbsp;2 - Solution Explorer for our new project</em></p>
<p>There are two files of interest here: AddIn.vb and App.xml. AddIn.vb contains our add-in class. Interface methods implemented in this class will be invoked by Windows Media Center when our add-in is launched. App.xml contains configuration information identifying
 our assemblies and add-in attributes. The setup project will use this XML to register our add-in with Windows Media Center during installation.
</p>
<h4>The AddIn class</h4>
Media Center add-in applications must implement two interfaces in order for Media Center to invoke them: Microsoft.MediaCenter.Hosting.IAddInEntryPoint, and Microsoft.MediaCenter.Hosting.IAddInModule. By using the project template, our add-in class already
 implements both (AddIn.vb):
<h5><span class="kwrd"><strong>Visual Basic</strong></span> .NET</h5>
<pre class="csharpcode"><span class="kwrd">Public</span> <span class="kwrd">Class</span> Class1
    <span class="kwrd">Implements</span> IAddInModule
    <span class="kwrd">Implements</span> IAddInEntryPoint

    <span class="rem">' Initialize (IAddInModule)</span>
    <span class="kwrd">Public</span> <span class="kwrd">Sub</span> Initialize(<span class="kwrd">ByVal</span> appInfo <span class="kwrd">As</span> Dictionary(Of <span class="kwrd">String</span>, <span class="kwrd">Object</span>), <span class="kwrd">ByVal</span> entryPointInfo <span class="kwrd">As</span> Dictionary(Of <span class="kwrd">String</span>, <span class="kwrd">Object</span>)) <span class="kwrd">Implements</span> IAddInModule.Initialize
        <span class="rem">' Initialization logic goes here</span>
    <span class="kwrd">End</span> <span class="kwrd">Sub</span>

    <span class="rem">' Uninitialize (IAddInModule)</span>
    <span class="kwrd">Public</span> <span class="kwrd">Sub</span> Uninitialize() <span class="kwrd">Implements</span> IAddInModule.Uninitialize
        <span class="rem">' Clean-up logic goes here</span>
    <span class="kwrd">End</span> <span class="kwrd">Sub</span>

    <span class="rem">' Launch (IAddInEntryPoint)</span>
    <span class="kwrd">Public</span> <span class="kwrd">Sub</span> Launch(<span class="kwrd">ByVal</span> host <span class="kwrd">As</span> AddInHost) <span class="kwrd">Implements</span> IAddInEntryPoint.Launch
        <span class="rem">' This is where normal execution begins</span>
    <span class="kwrd">End</span> <span class="kwrd">Sub</span>
<span class="kwrd">End</span> Class</pre>
<h5>Visual C#</h5>
<pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">class</span> Class1 : IAddInModule, IAddInEntryPoint 
{
    <span class="rem">//  Initialize (IAddInModule)</span>
    <span class="kwrd">public</span> <span class="kwrd">void</span> Initialize(Dictionary&lt;<span class="kwrd">string</span>, <span class="kwrd">object</span>&gt; appInfo, Dictionary&lt;<span class="kwrd">string</span>, <span class="kwrd">object</span>&gt; entryPointInfo)
    {
        <span class="rem">//  Initialization logic goes here</span>
    }    
    <span class="rem">//  Uninitialize (IAddInModule)</span>
    <span class="kwrd">public</span> <span class="kwrd">void</span> Uninitialize() 
    {
        <span class="rem">//  Clean-up logic goes here</span>
    }    
    <span class="rem">//  Launch (IAddInEntryPoint)</span>
    <span class="kwrd">public</span> <span class="kwrd">void</span> Launch(AddInHost host) 
    {
        <span class="rem">//  This is where normal execution begins</span>
    }
}
</pre>
<style type="text/css">
<!--
.csharpcode
	{background-color:#ffffff;
	font-family:consolas,"Courier New",courier,monospace;
	color:black;
	font-size:small}
.csharpcode 
	{background-color:#ffffff;
	font-family:consolas,"Courier New",courier,monospace;
	color:black;
	font-size:small}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	margin:0em;
	width:100%}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>The IAddInModule.Initialize and IAddInModule.Uninitialize interface methods are used by Media Center to signal the beginning and end of the add-in application's lifetime. Use Initialize to create any internal objects your application may require, and the
 Uninitialize to perform any clean-up. Keep in mind that since the add-in application runs within Media Center, it may decide to close your add-in application before it has a chance to exit on its own. In any case, Media Center will call the Uninitialize method
 and give the add-in a window of execution to exit as gracefully as possible. </p>
<p>The IAddInEntryPoint.Launch method is where normal execution code should begin. Media Center will pass an AddInHost object as an input parameter. Through this object, your add-in application can access all the features of the Media Center API.
</p>
<h4>Signing the assembly</h4>
Windows Media Center requires that all add-in assemblies be strongly-named. This requires that the assembly be signed using a key file. Thanks to Visual Studio 2005, signing an assembly is a straightforward process. From your add-in project's “Properties” menu,
 you can browse to the “Signing” tab to create a new strong name key file for the project:
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/2632164/3_Sign_an_assembly4.jpg"><img border="0" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/2632164/3_Sign_an_assembly_thumb2.jpg" width="500" height="327"></a>
</p>
<p><em>Figure 3 -&nbsp;Signing our assembly</em></p>
<p>Explicit instruction is also available here:<br>
<a href="http://msdn2.microsoft.com/en-us/library/ms247123(VS.80).aspx">How to: Sign an Assembly (Visual Studio)</a></p>
<h4>Tweaking the App.xml file</h4>
Media Center requires every add-in application to explicitly define a point of entry by which the application is to be launched. The App.xml file contains this configuration information. The Media Center project template used earlier generates the following
 sample:
<p>&nbsp;</p>
<pre class="csharpcode"><span class="kwrd">&lt;</span><span class="html">application</span> <span class="attr">title</span><span class="kwrd">=&quot;DemoProject&quot;</span> <span class="attr">id</span><span class="kwrd">=&quot;{f6dd1141-f288-46fe-bcdb-2d9c5ffd986e}&quot;</span><span class="kwrd">&gt;</span>
  <span class="kwrd">&lt;</span><span class="html">entrypoint</span> <span class="attr">id</span><span class="kwrd">=&quot;{31a15ce9-0487-43bc-94de-a43409129641}&quot;</span> 
              <span class="attr">addin</span><span class="kwrd">=&quot;DemoProject.Class1, DemoProject,Culture=Neutral,Version=6.0.6000.0&quot;</span>
              <span class="attr">title</span><span class="kwrd">=&quot;DemoProject&quot;</span>
              <span class="attr">description</span><span class="kwrd">=&quot;DemoProject&quot;</span>
              <span class="attr">ImageUrl</span><span class="kwrd">=&quot;.\AppIcon.png&quot;</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">category</span> <span class="attr">category</span><span class="kwrd">=&quot;More Programs&quot;</span><span class="kwrd">/&gt;</span>
  <span class="kwrd">&lt;/</span><span class="html">entrypoint</span><span class="kwrd">&gt;</span>
<span class="kwrd">&lt;/</span><span class="html">application</span><span class="kwrd">&gt;</span>
</pre>
<p>The XML definition specifies the add-in applications and their points of entry within Media Center. Add-in applications can be launched on demand from various locations within Media Center, such as from an icon in the “More Programs” group. A full listing
 of all the available points of entry can be found here. Add-in applications can also be launched in the background when Media Center starts. To indicate this, we specify “Background” in the “category” attribute. The “addin” attribute must also be modified
 to point to our add-in class in the format “Assemblyname.ClassName”. The “title”, “description”, and “ImageUrl” attributes are used primarily for on-demand add-ins.
</p>
<p>After making our changes, the Windows Media Center Remote application XML looks like this:</p>
<pre class="csharpcode"><span class="kwrd">&lt;</span><span class="html">application</span> <span class="attr">title</span><span class="kwrd">=&quot;WMCServerAddIn&quot;</span> <span class="attr">id</span><span class="kwrd">=&quot;{7b71a7ca-b459-4023-ab12-d5cc8c56b991}&quot;</span><span class="kwrd">&gt;</span>
  <span class="kwrd">&lt;</span><span class="html">entrypoint</span> <span class="attr">id</span><span class="kwrd">=&quot;{5fe9982b-ca4a-459e-b62c-40399e875d66}&quot;</span> 
              <span class="attr">addin</span><span class="kwrd">=&quot;WMCServerAddIn.ServerAddIn, WMCServerAddIn,Culture=Neutral,Version=6.0.6000.0&quot;</span>
              <span class="attr">title</span><span class="kwrd">=&quot;WMCServerAddIn&quot;</span>
              <span class="attr">description</span><span class="kwrd">=&quot;WMCServerAddIn&quot;</span>
              <span class="attr">ImageUrl</span><span class="kwrd">=&quot;.\AppIcon.png&quot;</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">category</span> <span class="attr">category</span><span class="kwrd">=&quot;Background&quot;</span><span class="kwrd">/&gt;</span>
  <span class="kwrd">&lt;/</span><span class="html">entrypoint</span><span class="kwrd">&gt;</span>
<span class="kwrd">&lt;/</span><span class="html">application</span><span class="kwrd">&gt;</span></pre>
<h4>Creating the setup project</h4>
<p>With a basic interface implementation complete and a configuration XML created, we are ready to create the setup project. The setup project will install our assemblies into the Global Assembly Cache and register our XML-defined entry point with Media Center.
 A full step-by-step walkthrough can be found here:</p>
<p><a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/MedctrSDK/htm/creatingawindowsinstallerfileforanaddin.asp">Creating a Windows Installer File for a Windows Media Center Add-in</a></p>
<p>Once the setup project is complete, it's time for a test. By using the Host.MediaCenterEnvironment.Dialog class off of the AddInHost object, we can present a dialog box to the user to ensure the add-in launches successfully. After compiling the solution,
 run the installer by right-clicking the setup project and choosing “Install”. Once installation has completed, run Windows Media Center. A few seconds after startup, the add-in is launched:</p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/2632164/4_Hello_world_demo_addin3.jpg"><img border="0" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/2632164/4_Hello_world_demo_addin_thumb1.jpg" width="500" height="374"></a>
</p>
<p><em>Figure 4 - Running our Hello World Media Center Add-in</em></p>
<h3>Creating a Windows Mobile 5.0 client application</h3>
The second step in our implementation is creating a .NET Compact Framework 2.0 forms application. This is a mobile application that will run on a mobile device running Windows Mobile 5 or higher.
<h4>Creating a new project – Windows Mobile CE 5.0 application</h4>
<p>Installing the Windows Mobile Smartphone SDK 5.0 makes this step simple. Once the SDK is installed, you can create a project in Visual Studio using the Windows CE 5.0 Project template.
</p>
<p>The only other typical setup required for developing mobile apps is to change the deployment settings to point to your WM5 device. This can be configured within the Visual Studio toolbar:
</p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/2632164/6_Deploying_to_mobile3.jpg"><img border="0" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/2632164/6_Deploying_to_mobile_thumb1.jpg" width="345" height="201"></a>
</p>
<p><em>Figure&nbsp;5 - changing the deployment settings to target the mobile device</em></p>
<h3>Implementing the Media Center Add-in service</h3>
With a test harness in place at both ends of the implementation, it was time to get to the real code. To facilitate the control of Media Center through the hosted add-in, the service requires a few key components. These include choosing a server / client conversation
 protocol, creating a multithreaded socket server, implementing object serialization, and implementing the programmatic manipulation of Media Center.
<h4>Implementing the socket server</h4>
<p>The socket server uses the Socket object from the System.Networking.Sockets namespace for all of its communications. The listener service begins by binding to the host machine's local address and listening on a port of your choosing. Once the socket is instantiated
 and bound to a local port, it begins listening for and accepting inbound connections. When a new connection is established, a target method BeginSocketConversation will be invoked on a new thread, where the actual communication between the two parties will
 take place. Once the new thread has been invoked, execution will continue in the AcceptConnections method. At this time the newly launched thread notifies the listener to begin accepting new connections again. A ManualResetEvent from the System.Threading namespace
 can be used to communicate changes in state between two or more threads. Here is the code implementation of the socket listener:
</p>
<h5><span class="kwrd">Visual Basic .NET</span></h5>
<pre class="csharpcode"><span class="kwrd">Private</span> <span class="kwrd">Sub</span> AcceptConnections()
        <span class="kwrd">Dim</span> localMachineInfo <span class="kwrd">As</span> IPHostEntry
        <span class="kwrd">Dim</span> localEndPoint <span class="kwrd">As</span> IPEndPoint
        <span class="kwrd">Dim</span> listener <span class="kwrd">As</span> <span class="kwrd">New</span> Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
        <span class="kwrd">Try</span>
            localMachineInfo = Dns.Resolve(<span class="kwrd">String</span>.Empty)
            localEndPoint = <span class="kwrd">New</span> IPEndPoint(localMachineInfo.AddressList(0), _port)
            listener.Bind(localEndPoint)
            listener.Listen(10)
            <span class="kwrd">While</span> <span class="kwrd">True</span>
                threadEvent.Reset()
                listener.BeginAccept(<span class="kwrd">New</span> AsyncCallback(<span class="kwrd">AddressOf</span> BeginSocketConversation), listener)
                threadEvent.WaitOne()
            <span class="kwrd">End</span> <span class="kwrd">While</span>
        <span class="kwrd">Catch</span> ex <span class="kwrd">As</span> Exception
          Log.Write(ex)
    <span class="kwrd">End</span> <span class="kwrd">Try</span>
<span class="kwrd">End</span> <span class="kwrd">Sub</span>
</pre>
<style type="text/css">
<!--
.csharpcode
	{background-color:#ffffff;
	font-family:consolas,"Courier New",courier,monospace;
	color:black;
	font-size:small}
.csharpcode 
	{background-color:#ffffff;
	font-family:consolas,"Courier New",courier,monospace;
	color:black;
	font-size:small}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	margin:0em;
	width:100%}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<h5>Visual C#</h5>
<pre class="csharpcode">Public Class Class1
    Implements IAddInModule
    Implements IAddInEntryPoint

    <span class="str">' Initialize (IAddInModule)
    Public Sub Initialize(ByVal appInfo As Dictionary(Of String, Object), ByVal entryPointInfo As Dictionary(Of String, Object)) Implements IAddInModule.Initialize
        '</span> Initialization logic goes here
    End Sub

    <span class="str">' Uninitialize (IAddInModule)
    Public Sub Uninitialize() Implements IAddInModule.Uninitialize
        '</span> Clean-up logic goes here
    End Sub

    <span class="str">' Launch (IAddInEntryPoint)
    Public Sub Launch(ByVal host As AddInHost) Implements IAddInEntryPoint.Launch
        '</span> This <span class="kwrd">is</span> <span class="kwrd">where</span> normal execution begins
    End Sub
End Class</pre>
<p>Once a connection has been established, the server begins to listen for inbound messages. When new data is received, it is parsed into a custom Message object for easy inspection by a consuming class. An event is then raised to any consuming classes, passing
 a reference to the newly created Message object. The server then resumes listening for new data on the same socket. Here is the code implementation:</p>
<h5>Visual Basic .NET</h5>
<pre class="csharpcode"><span class="kwrd">Private</span> <span class="kwrd">Sub</span> BeginSocketConversation(<span class="kwrd">ByVal</span> ar <span class="kwrd">As</span> IAsyncResult)
    threadEvent.<span class="kwrd">Set</span>()
    <span class="kwrd">RaiseEvent</span> ClientConnected()
    <span class="kwrd">Dim</span> listener <span class="kwrd">As</span> Socket = <span class="kwrd">CType</span>(ar.AsyncState, Socket)
    _socket = listener.EndAccept(ar)
    <span class="kwrd">Dim</span> buffer(PACKET_SIZE) <span class="kwrd">As</span> <span class="kwrd">Byte</span>
    <span class="kwrd">Dim</span> bytesReadCount <span class="kwrd">As</span> <span class="kwrd">Integer</span> = 0
    <span class="kwrd">While</span> <span class="kwrd">True</span>
        <span class="kwrd">Dim</span> sb <span class="kwrd">As</span> <span class="kwrd">New</span> System.Text.StringBuilder
        <span class="kwrd">Do</span>
            <span class="kwrd">Try</span>
                bytesReadCount = _socket.Receive(buffer, buffer.Length, SocketFlags.None)
            <span class="kwrd">Catch</span> ex <span class="kwrd">As</span> Exception
                _socket.Close()
                <span class="kwrd">Exit</span> <span class="kwrd">While</span>
            <span class="kwrd">End</span> <span class="kwrd">Try</span>
            sb.Append(System.Text.ASCIIEncoding.ASCII.GetString(buffer, 0, bytesReadCount))
        <span class="kwrd">Loop</span> <span class="kwrd">While</span> _socket.Available &gt; 0
        <span class="kwrd">Dim</span> requestMessage <span class="kwrd">As</span> <span class="kwrd">New</span> RequestMessage()
        requestMessage.DeSerialize(sb.ToString())
        <span class="kwrd">RaiseEvent</span> MessageReceived(requestMessage)
    <span class="kwrd">End</span> <span class="kwrd">While</span>
    <span class="kwrd">RaiseEvent</span> ClientDisconnected()
<span class="kwrd">End</span> <span class="kwrd">Sub</span></pre>
<h5><span class="kwrd">Visual C#</span></h5>
<pre class="csharpcode"><span class="kwrd">private</span> <span class="kwrd">void</span> BeginSocketConversation(IAsyncResult ar)
{
    threadEvent.Set();
    ClientConnected();
    Socket listener = ((Socket)(ar.AsyncState));
    _socket = listener.EndAccept(ar);
    <span class="kwrd">byte</span>[,] buffer;
    <span class="kwrd">int</span> bytesReadCount = 0;
    <span class="kwrd">while</span> (<span class="kwrd">true</span>)
    {
        System.Text.StringBuilder sb = <span class="kwrd">new</span> System.Text.StringBuilder();
        <span class="kwrd">for</span> (
        ; (_socket.Available &gt; 0);
        )
        {
            <span class="kwrd">try</span>
            {
                bytesReadCount = _socket.Receive(buffer, buffer.Length, SocketFlags.None);
            }
            <span class="kwrd">catch</span> (Exception ex)
            {
                _socket.Close();
                <span class="kwrd">break</span>;
            }
            sb.Append(System.Text.ASCIIEncoding.ASCII.GetString(buffer, 0, bytesReadCount));
        }
        RequestMessage requestMessage = <span class="kwrd">new</span> RequestMessage();
        requestMessage.DeSerialize(sb.ToString());
        MessageReceived(requestMessage);
    }
    ClientDisconnected();
}</pre>
<style type="text/css">
<!--
.csharpcode
	{background-color:#ffffff;
	font-family:consolas,"Courier New",courier,monospace;
	color:black;
	font-size:small}
.csharpcode 
	{background-color:#ffffff;
	font-family:consolas,"Courier New",courier,monospace;
	color:black;
	font-size:small}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	margin:0em;
	width:100%}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<h4>Object serialization</h4>
The limited resources of a mobile device require an efficient method of transferring data and commands between the device and the host machine. Due to their large size, the .NET remoting libraries and the binary serialization libraries provided by .NET 2.0
 are not available in the .NET Mobile Framework. I chose custom serialization to facilitate the transfer of objects. While less flexible, this enabled objects to be transferred using very little bandwidth.
<p>&nbsp;</p>
<h4>Implementing the AddIn.Launch method</h4>
<p>The custom server object created in the previous section encapsulates all the grunt work of socket-level protocol, accepting connections, serializing / deserializing message objects, and data transfer. Within the AddIn class implementation, all we have to
 do now is instantiate the Server class, indicating the port to listen on: </p>
<h5>Visual Basic .NET</h5>
<pre class="csharpcode"><span class="kwrd">Public</span> <span class="kwrd">Sub</span> Launch(<span class="kwrd">ByVal</span> host <span class="kwrd">As</span> AddInHost) <span class="kwrd">Implements</span> IAddInEntryPoint.Launch
    _wmcHost = host
    _waitForExit = <span class="kwrd">New</span> System.Threading.ManualResetEvent(<span class="kwrd">False</span>)
    _server.Start(DEFAULT_PORT)
    System.Threading.Thread.CurrentThread.Priority = Threading.ThreadPriority.Lowest
    _waitForExit.WaitOne()
<span class="kwrd">End</span> Sub</pre>
<style type="text/css">
<!--
.csharpcode
	{background-color:#ffffff;
	font-family:consolas,"Courier New",courier,monospace;
	color:black;
	font-size:small}
.csharpcode 
	{background-color:#ffffff;
	font-family:consolas,"Courier New",courier,monospace;
	color:black;
	font-size:small}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	margin:0em;
	width:100%}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<h5>Visual C#</h5>
<pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">void</span> Launch(AddInHost host) 
{
    _wmcHost = host;
    _waitForExit = <span class="kwrd">new</span> System.Threading.ManualResetEvent(<span class="kwrd">false</span>);
    _server.Start(DEFAULT_PORT);
    System.Threading.Thread.CurrentThread.Priority = Threading.ThreadPriority.Lowest;
    _waitForExit.WaitOne();
}</pre>
<p>We also perform two other critical tasks at this time. First, we assign a reference to the AddInHost to a private member variable for later use. Second, we reduce the priority of the add-in's main thread and use a ManualResetEvent to put it to sleep until
 Media Center is closed. The reason for this relates to the nature of an add-in's lifetime within Media Center. The Media Center add-in hosting process will only allow an add-in to execute for the duration of its Launch method. This means that as soon as the
 Launch method returns, the add-in and any child threads it has spawned will be terminated. For this reason, we must keep the add-in alive by blocking the Launch method from exiting.
</p>
<h4>Media Center manipulation</h4>
<p>Using the communications layer and socket listener developed in the previous sections, we can finally get to the task of performing something useful with the input requests. By subscribing to the custom Server object's MessageReceived event, the AddIn class's
 OnDataReceived method will automatically be invoked when a new request message is received from the listener:
</p>
<h5>Visual Basic .NET</h5>
<pre class="csharpcode"><span class="kwrd">Private</span> <span class="kwrd">Sub</span> OnDataReceived(<span class="kwrd">ByVal</span> message <span class="kwrd">As</span> RequestMessage) <span class="kwrd">Handles</span> _server.MessageReceived
    <span class="kwrd">Select</span> <span class="kwrd">Case</span> message.RequestAction
        <span class="kwrd">Case</span> RequestMessage.Action.PauseMedia
_wmcHost.MediaCenterEnvironment.MediaExperience.Transport.PlayRate = PlayRates.PLAYRATE_PAUSE
        <span class="kwrd">Case</span> RequestMessage.Action.VolumeUp
           _wmcHost.MediaCenterEnvironment.AudioMixer.VolumeUp()
        <span class="kwrd">Case</span> RequestMessage.Action.VolumeDown
           _wmcHost.MediaCenterEnvironment.AudioMixer.VolumeDown()
        <span class="kwrd">Case</span> RequestMessage.Action.NextMedia _wmcHost.MediaCenterEnvironment.MediaExperience.Transport.SkipForward()
        <span class="kwrd">Case</span> <span class="kwrd">Else</span>
    <span class="kwrd">End</span> <span class="kwrd">Select</span>
    SendAcknowledgement(message)
<span class="kwrd">End</span> <span class="kwrd">Sub</span></pre>
<h5>Visual C#</h5>
<pre class="csharpcode"><span class="kwrd">private</span> <span class="kwrd">void</span> OnDataReceived(RequestMessage message) 
{
    <span class="kwrd">switch</span> (message.RequestAction) 
    {
        <span class="kwrd">case</span> RequestMessage.Action.PauseMedia:
            _wmcHost.MediaCenterEnvironment.MediaExperience.Transport.PlayRate = PlayRates.PLAYRATE_PAUSE;
            <span class="kwrd">break</span>;
        <span class="kwrd">case</span> RequestMessage.Action.VolumeUp:
            _wmcHost.MediaCenterEnvironment.AudioMixer.VolumeUp();
            <span class="kwrd">break</span>;
        <span class="kwrd">case</span> RequestMessage.Action.VolumeDown:
            _wmcHost.MediaCenterEnvironment.AudioMixer.VolumeDown();
            <span class="kwrd">break</span>;
        <span class="kwrd">case</span> RequestMessage.Action.NextMedia:
            _wmcHost.MediaCenterEnvironment.MediaExperience.Transport.SkipForward();
            <span class="kwrd">break</span>;
    }
    SendAcknowledgement(message);
}</pre>
<style type="text/css">
<!--
.csharpcode
	{background-color:#ffffff;
	font-family:consolas,"Courier New",courier,monospace;
	color:black;
	font-size:small}
.csharpcode 
	{background-color:#ffffff;
	font-family:consolas,"Courier New",courier,monospace;
	color:black;
	font-size:small}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	margin:0em;
	width:100%}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>&nbsp;</p>
<p>The RequestMessage class shown above is a custom object, originally created by Windows Mobile 5 application running on a connected mobile device. The transport object was then serialized on the device, transmitted, deserialized in the listener service, and
 raised to the add-in class via the MessageReceived event. The RequestAction property is an enumerable type indicating the type of action to take within Media Center. The Media Center API exposed by the AddInHost object (_wmcHost) can then be used to actually
 perform the desired Media Center operation. Finally, we send an acknowledgement message to the mobile device.<br>
</p>
<h3>Implementing the Windows Mobile 5 remote client application</h3>
After completing the Media Center add-in, the mobile application is relatively simple by comparison. The remote application's role is to present the user with a user interface similar to that of an actual remote control. The remote application directs user
 input to the listener add-in, and displays any response data if necessary.
<p>&nbsp;</p>
<h4>Implementing the socket client</h4>
<p>The design of the socket client is much simpler than that of the socket server. All execution will be performed on the primary thread. The client begins by establishing a connection with an add-in server. Once established, the socket client sends and receives
 data synchronously over the socket. Consumers of the socket client need only call the Send method, which will return with the transactional response:
</p>
<h5>Visual Basic .NET</h5>
<pre class="csharpcode"><span class="kwrd">Public</span> <span class="kwrd">Function</span> Send(<span class="kwrd">ByVal</span> request <span class="kwrd">As</span> Message) <span class="kwrd">As</span> <span class="kwrd">String</span>
    <span class="kwrd">Dim</span> responseString <span class="kwrd">As</span> <span class="kwrd">String</span> = <span class="kwrd">Nothing</span>
    <span class="kwrd">Try</span>
        <span class="kwrd">If</span> ((<span class="kwrd">Not</span> (_socket) <span class="kwrd">Is</span> <span class="kwrd">Nothing</span>) _
                    <span class="kwrd">AndAlso</span> _socket.Connected) <span class="kwrd">Then</span>
            <span class="kwrd">Dim</span> requestString <span class="kwrd">As</span> <span class="kwrd">String</span> = request.Serialize
            Send(requestString)
            responseString = RecvSynchronous
            <span class="kwrd">Return</span> responseString
        <span class="kwrd">End</span> <span class="kwrd">If</span>
    <span class="kwrd">Catch</span> ex <span class="kwrd">As</span> Exception
        <span class="kwrd">Return</span> <span class="kwrd">Nothing</span>
    <span class="kwrd">End</span> <span class="kwrd">Try</span>
    <span class="kwrd">Return</span> responseString
<span class="kwrd">End</span> <span class="kwrd">Function</span>
</pre>
<h5>Visual C#</h5>
<pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">string</span> Send(Message request)
{
    <span class="kwrd">string</span> responseString = <span class="kwrd">null</span>;
    <span class="kwrd">try</span>
    {
        <span class="kwrd">if</span> (_socket != <span class="kwrd">null</span> &amp;&amp; _socket.Connected)
        {
            <span class="kwrd">string</span> requestString = request.Serialize();
            Send(requestString);
            responseString = RecvSynchronous();
            <span class="kwrd">return</span> responseString;
        }
    }
    <span class="kwrd">catch</span> (Exception ex)
    {
        <span class="kwrd">return</span> <span class="kwrd">null</span>;
    }
    <span class="kwrd">return</span> responseString;
}
</pre>
<style type="text/css">
<!--
.csharpcode
	{background-color:#ffffff;
	font-family:consolas,"Courier New",courier,monospace;
	color:black;
	font-size:small}
.csharpcode 
	{background-color:#ffffff;
	font-family:consolas,"Courier New",courier,monospace;
	color:black;
	font-size:small}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	margin:0em;
	width:100%}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<h4>Adding the UI layer</h4>
With the communications layer in place the next step in our remote implementation is the user interface. In this final stage, we hook up UI controls to construct the request messages that will be sent to the host service. However, before we do that we must
 first connect with the Media Center host machine. Here's a look at the connection configuration screen:
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/2632164/7_Config2.jpg"><img border="0" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/2632164/7_Config_thumb.jpg" width="239" height="319"></a>
</p>
<p><em>Figure 6 - The configuration screen on the mobile device</em></p>
<p>Once we've specified the host and port of our running Media Center add-in service, we can click the “Connect” button to initialize the TCP/IP socket connection. Using the TCP Client class developed earlier, the code required to handle this event is simple:</p>
<h5>Visual Basic .NET</h5>
<pre class="csharpcode"><span class="kwrd">Private</span> <span class="kwrd">Sub</span> btnConnect_Click(<span class="kwrd">ByVal</span> sender <span class="kwrd">As</span> <span class="kwrd">Object</span>, <span class="kwrd">ByVal</span> e <span class="kwrd">As</span> EventArgs)
    <span class="kwrd">Dim</span> host <span class="kwrd">As</span> <span class="kwrd">String</span> = <span class="kwrd">Me</span>.txtHost.Text.Trim
    <span class="kwrd">Dim</span> port <span class="kwrd">As</span> <span class="kwrd">String</span> = <span class="kwrd">Me</span>.txtPort.Text.Trim
    _client.Connect(host, Convert.ToInt32(port))
<span class="kwrd">End</span> Sub</pre>
<h5>Visual C#</h5>
<pre class="csharpcode"><span class="kwrd">private</span> <span class="kwrd">void</span> btnConnect_Click(<span class="kwrd">object</span> sender, EventArgs e)
{
     <span class="kwrd">string</span> host = <span class="kwrd">this</span>.txtHost.Text.Trim();
     <span class="kwrd">string</span> port = <span class="kwrd">this</span>.txtPort.Text.Trim();
     _client.Connect(host, Convert.ToInt32(port));
}</pre>
<style type="text/css">
<!--
.csharpcode
	{background-color:#ffffff;
	font-family:consolas,"Courier New",courier,monospace;
	color:black;
	font-size:small}
.csharpcode 
	{background-color:#ffffff;
	font-family:consolas,"Courier New",courier,monospace;
	color:black;
	font-size:small}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	margin:0em;
	width:100%}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>Once connected, the user can navigate the application using the provided tabs at the bottom of the screen. Since this application is intended to function as a remote control, there is a standard media control screen:</p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/2632164/8_Controls2.jpg"><img border="0" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/2632164/8_Controls_thumb.jpg" width="241" height="319"></a>
</p>
<p><em>Figure 8: The control screen on the mobile device</em></p>
<p>Nothing exotic here, but the basic media control functionality you'd expect from a remote is available. Here's a sample of the code required to support the “Stop” button's click event:</p>
<h5>Visual Basic .NET</h5>
<pre class="csharpcode"><span class="kwrd">Private</span> <span class="kwrd">Sub</span> btnConnect_Click(<span class="kwrd">ByVal</span> sender <span class="kwrd">As</span> <span class="kwrd">Object</span>, <span class="kwrd">ByVal</span> e <span class="kwrd">As</span> EventArgs)
    <span class="kwrd">Dim</span> host <span class="kwrd">As</span> <span class="kwrd">String</span> = <span class="kwrd">Me</span>.txtHost.Text.Trim
    <span class="kwrd">Dim</span> port <span class="kwrd">As</span> <span class="kwrd">String</span> = <span class="kwrd">Me</span>.txtPort.Text.Trim
    _client.Connect(host, Convert.ToInt32(port))
<span class="kwrd">End</span> Sub</pre>
<h5>Visual C#</h5>
<pre class="csharpcode"><span class="kwrd">private</span> <span class="kwrd">void</span> btnStop_Click(<span class="kwrd">object</span> sender, EventArgs e)
{
    RequestMessage message = <span class="kwrd">new</span> RequestMessage();
    message.RequestAction = RequestMessage.Action.StopMedia;
    message.Data = String.Empty;
    <span class="kwrd">string</span> responseString = client.Send(message);
    ResponseMessage response = <span class="kwrd">new</span> ResponseMessage(responseString);
}</pre>
<style type="text/css">
<!--
.csharpcode
	{background-color:#ffffff;
	font-family:consolas,"Courier New",courier,monospace;
	color:black;
	font-size:small}
.csharpcode 
	{background-color:#ffffff;
	font-family:consolas,"Courier New",courier,monospace;
	color:black;
	font-size:small}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	margin:0em;
	width:100%}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>The UI form uses the connected Client object to execute the Stop command. First, the form constructs a Request message, populating the type of action desired (StopMedia). Next, the Request message is passed to the Client class, where it is serialized for
 transport and sent over the connected TCP socket. From there, the running Media Center service will receive the request, perform the media stop, and send an acknowledgement. The Client then returns a Response message, which will contain a Boolean indicating
 if the request was successful or not. </p>
<p>On a Media Stop request, examining the Response object is not very informative. However, for other commands, the Media Center add-in service can be designed to return any kind of information required of the host. The Detail screen is a good example:
</p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/2632164/9_Detail2.jpg"><img border="0" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/2632164/9_Detail_thumb.jpg" width="240" height="321"></a>
</p>
<p><em>Figure 9 - The detail page&nbsp;</em> </p>
<p>When a song or video is currently playing, the above screen can be used to retrieve any metadata associated with it. The event handler for the screen's “Refresh” button looks similar in form to the Stop button's handler:
</p>
<h5>Visual Basic .NET</h5>
<pre class="csharpcode"><span class="kwrd">Private</span> <span class="kwrd">Sub</span> btnRefreshDetail_Click(<span class="kwrd">ByVal</span> sender <span class="kwrd">As</span> <span class="kwrd">Object</span>, <span class="kwrd">ByVal</span> e <span class="kwrd">As</span> EventArgs)
    <span class="kwrd">Dim</span> request <span class="kwrd">As</span> RequestMessage = <span class="kwrd">New</span> RequestMessage
    request.RequestAction = RequestMessage.Action.GetMediaMetadata
    <span class="kwrd">Dim</span> responseString <span class="kwrd">As</span> <span class="kwrd">String</span> = _client.Send(request)
    <span class="kwrd">Dim</span> response <span class="kwrd">As</span> MediaMetadataMessage = <span class="kwrd">New</span> MediaMetadataMessage(responseString)
    <span class="kwrd">For</span> <span class="kwrd">Each</span> item <span class="kwrd">As</span> MediaMetadataMessage.MediaMetadataItem <span class="kwrd">In</span> message.Data
        <span class="kwrd">If</span> ((<span class="kwrd">Not</span> (item.Value) <span class="kwrd">Is</span> <span class="kwrd">Nothing</span>) <span class="kwrd">AndAlso</span> (item.Value.Length &gt; 0)) <span class="kwrd">Then</span>
            <span class="kwrd">Me</span>.txtDetail.Text = (<span class="kwrd">Me</span>.txtDetail.Text &#43; (item.Key &#43; (<span class="str">&quot;: &quot;</span> &#43; item.Value)))
            <span class="kwrd">Me</span>.txtDetail.Text = (<span class="kwrd">Me</span>.txtDetail.Text &#43; <span class="str">&quot;&quot;</span> &amp; vbCrLf)
        <span class="kwrd">End</span> <span class="kwrd">If</span>
    <span class="kwrd">Next</span>
<span class="kwrd">End</span> Sub</pre>
<h5>Visual C#</h5>
<pre class="csharpcode"><span class="kwrd">private</span> <span class="kwrd">void</span> btnRefreshDetail_Click(<span class="kwrd">object</span> sender, EventArgs e)
{
    RequestMessage request = <span class="kwrd">new</span> RequestMessage();
    request.RequestAction = RequestMessage.Action.GetMediaMetadata;
    <span class="kwrd">string</span> responseString = _client.Send(request);
    MediaMetadataMessage response = <span class="kwrd">new</span> MediaMetadataMessage(responseString);
    <span class="kwrd">foreach</span> (MediaMetadataMessage.MediaMetadataItem item <span class="kwrd">in</span> message.Data) {
        <span class="kwrd">if</span> (item.Value != <span class="kwrd">null</span> &amp;&amp; item.Value.Length &gt; 0){
            <span class="kwrd">this</span>.txtDetail.Text &#43;= item.Key &#43; <span class="str">&quot;: &quot;</span> &#43; item.Value;
            <span class="kwrd">this</span>.txtDetail.Text &#43;= <span class="str">&quot;\r\n&quot;</span>;
        }
    }
}</pre>
<style type="text/css">
<!--
.csharpcode
	{background-color:#ffffff;
	font-family:consolas,"Courier New",courier,monospace;
	color:black;
	font-size:small}
.csharpcode 
	{background-color:#ffffff;
	font-family:consolas,"Courier New",courier,monospace;
	color:black;
	font-size:small}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	margin:0em;
	width:100%}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>This time, however, the Response object has a list of metadata keys and values, which are then enumerated and displayed in a textbox. This Response object was originally populated by the Media Center add-in service:
</p>
<h5>Visual Basic .NET</h5>
<pre class="csharpcode"><span class="kwrd">Private</span> <span class="kwrd">Sub</span> SendMediaMetadata()
    <span class="kwrd">Dim</span> response <span class="kwrd">As</span> <span class="kwrd">New</span> MediaMetadataMessage()
    <span class="kwrd">Dim</span> val <span class="kwrd">As</span> <span class="kwrd">String</span>
    <span class="kwrd">For</span> <span class="kwrd">Each</span> key <span class="kwrd">As</span> <span class="kwrd">String</span> <span class="kwrd">In</span> _wmcHost.MediaCenterEnvironment.MediaExperience.MediaMetadata.Keys
    val = _wmcHost.MediaCenterEnvironment.MediaExperience.MediaMetadata.Item(key).ToString()
    response.Data.Add(<span class="kwrd">New</span> MediaMetadataMessage.MediaMetadataItem(key, val))
    <span class="kwrd">Next</span>
    response.ResponseIndicator = MediaMetadataMessage.ResponseCode.Success
    _server.Send(response)
<span class="kwrd">End</span> Sub</pre>
<h5>Visual C#</h5>
<pre class="csharpcode"><span class="kwrd">private</span> <span class="kwrd">void</span> SendMediaMetadata() 
{
    MediaMetadataMessage response = <span class="kwrd">new</span> MediaMetadataMessage();
    <span class="kwrd">string</span> val;
    <span class="kwrd">foreach</span> (<span class="kwrd">string</span> key <span class="kwrd">in</span> _wmcHost.MediaCenterEnvironment.MediaExperience.MediaMetadata.Keys) 
    {
        val = _wmcHost.MediaCenterEnvironment.MediaExperience.MediaMetadata.Item[key].ToString();
        response.Data.Add(<span class="kwrd">new</span> MediaMetadataMessage.MediaMetadataItem(key, val));
    }
    response.ResponseIndicator = MediaMetadataMessage.ResponseCode.Success;
    _server.Send(response);
}</pre>
<style type="text/css">
<!--
.csharpcode
	{background-color:#ffffff;
	font-family:consolas,"Courier New",courier,monospace;
	color:black;
	font-size:small}
.csharpcode 
	{background-color:#ffffff;
	font-family:consolas,"Courier New",courier,monospace;
	color:black;
	font-size:small}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	margin:0em;
	width:100%}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>After receiving a request from the mobile device for the currently playing media's metadata, the Media Center add-in service constructs a list of custom objects (MediaMetadataItem). It populates this list by enumerating properties of the AddInHost object,
 through the namespace MediaCenterEnvironment.MediaExperience.MediaMetadata. It then sends this list on the Response object, where the mobile device will inspect and display the data, as shown above.
</p>
<p>The last feature that the mobile remote application provides is the ability to select specific media to play based on a list of available media on the host. This functionality is provided for audio, video, and images:
</p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/2632164/10_Music2.jpg"><img border="0" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/2632164/10_Music_thumb.jpg" width="240" height="320"></a>
<a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/2632164/11_Video2.jpg">
<img border="0" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/2632164/11_Video_thumb.jpg" width="240" height="320"></a>
</p>
<p><em>Figure 10 - Music and Video&nbsp;list management&nbsp;</em> </p>
<p>The mobile application requests the list of available media in a similar fashion to the Details screen implementation. The resulting list of files is then bound and displayed in a DataGrid. The Media Center add-in service can then be instructed to play individual
 songs or videos using the AddInHost's MediaCenterEnvironment.PlayMedia method. </p>
<h4><strong>Mobile Application UI design considerations</strong></h4>
<p>Developing on the mobile platform introduces design challenges not found in Windows Forms applications due to the small amount of screen real estate available. Many typical form layouts found in Windows Forms applications won't work well on a mobile device's
 small screen. When developing for a mobile application, try to keep the user interface as simple as possible. Window containers and managers such as a tabbed control enable the developer to functionally divide an application into logical components. This alleviates
 the clutter created by having too many controls in a single window. Also try to keep your text and controls as simple and large as possible. This makes the application easier to view and manipulate, especially in outdoor or bright conditions.</p>
<h3>Conclusion</h3>
<p>Once complete, the remote application gives you a level of control simply not available on hardware-based remote controls. I really enjoyed working on this application because it gave me a chance to integrate a number of different technologies into a single
 implementation. Be sure to download the code and take the remote for a spin. For those not familiar with all of the components used in this article (Media Center add-in services, socket communication, installer and assembly signing, etc.), don't be intimidated.
 The Microsoft-provided SDK packages for both parts of the solution make creating your own add-in projects a snap. Plus, the technical challenges unique to this project have already been overcome! Feel free to modify my implementation, or reuse the included
 socket classes to create an add-in all your own. Finally, please post feedback or questions here or at my
<a href="http://blogs.claritycon.com/blogs/matt_ivers/default.aspx">blog</a>.</p>
<h3>About the Author</h3>
<p>Matt Ivers is a software engineer at Chicago-based <a href="http://www.claritycon.com/">
Clarity Consulting</a>. He has extensive professional experience developing .NET solutions in both Visual C# .NET and VB.NET. Check him out at his
<a href="http://blogs.claritycon.com/blogs/matt_ivers/default.aspx">blog</a> or through the Clarity blog site,
<a href="http://blogs.claritycon.com/">Clarity Blogs</a>. </p>
<h3>References</h3>
<p><a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=A43EA0B7-B85F-4612-AA08-3BF128C5873E&amp;displaylang=en">Windows Media Center SDK 5.0</a><br>
<a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=dc6c00cb-738A-4B97-8910-5cd29ab5f8d9&amp;DisplayLang=en">Windows Mobile 5.0 Smartphone SDK</a>
</p>
<p><a href="http://msdn2.microsoft.com/en-us/library/ms247123(VS.80).aspx">How to: Sign an Assembly using Visual Studio 2005</a><br>
<a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/MedctrSDK/htm/creatingawindowsinstallerfileforanaddin.asp">How to: Create a Windows Installer File for a Windows Media Center Add-in</a>
</p>
<p><a href="http://msdn2.microsoft.com/en-gb/library/ms816327.aspx">Windows Media Center - SDK Overview</a><br>
<a href="http://msdn2.microsoft.com/en-us/library/bb189667.aspx">Windows Media Center - Understanding the Basics</a><br>
<a href="http://msdn2.microsoft.com/en-us/library/bb189733.aspx">Windows Media Center - Development Tools</a><br>
<a href="http://msdn.microsoft.com/smartclient/default.aspx?pull=/library/en-us/dnxpmce/html/positionchangeraddin.asp">Windows Media Center - AddIn example: &quot;Time Travel&quot;</a>
</p>
<p><a href="http://msdn2.microsoft.com/en-us/library/5w7b7x5f.aspx">Using an Asynchronous Server Socket</a></p>
 <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Tags/home+automation/RSS&WT.dl=0&WT.entryid=Entry:RSSView:5f3aee551c9a4099a3d29e7600d3e5ee">]]></description>
      <comments>http://channel9.msdn.com/coding4fun/articles/Control-Windows-Media-Center-using-a-Windows-Mobile-5-Device</comments>
      <itunes:summary>
This article demonstrates how to use a smartphone running Windows Mobile 5 to remotely control a host machine running Windows Media Center. I will describe how to create an add-in application that runs within Windows Media Center, and how to create a Windows
 Mobile 5 application that you can use to communicate with the Media Center over a wireless internet connection. Finally, I will demonstrate how to use this implementation to manipulate Media Center using the Windows Media Center API.
 
Matt Ivers
 
Difficulty: Intermediate  
Time Required: 6-10 hours 
Cost: $100-$200  
Software: Visual Basic or Visual C# Express Editions,

Windows Media Center SDK 5.0, 
Windows Mobile 5.0 Smartphone SDK  
Hardware: Mobile device running Windows Mobile 5.0  
Download: C# and VB.Net 


Introduction
Starting with Windows Media Center Edition 2005, Media Center added extensibility support through hosted add-in assemblies. By implementing an add-in interface and registering the assembly with Media Center, the add-in assembly is given access to the Microsoft.MediaCenter.Hosting.AddInHost
 object. Using this object model, an add-in assembly can programmatically inspect and manipulate various aspects of Windows Media Center. In addition to the exposed Media Center namespaces, the add-in has complete access to all the capabilities of the .NET
 Framework.
&amp;nbsp; 
By combining the power of a Media Center add-in with a mobile device running Windows Mobile 5.0, we can extend the capabilities of a Media Center add-in even further. The add-in service I developed runs as a listener service within Windows Media Center on
 the host machine. It is initialized when Windows Media Center is started, runs invisibly in the background, and allows mobile devices to connect and submit requests to it. The mobile solution leverages an existing WiFi internet connection to communicate with
 the add-in via TCP socket connections. The mobile device runs a .NET Compact Framework 2.0 forms application designed </itunes:summary>
      <link>http://channel9.msdn.com/coding4fun/articles/Control-Windows-Media-Center-using-a-Windows-Mobile-5-Device</link>
      <pubDate>Mon, 14 May 2007 17:08:00 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/coding4fun/articles/Control-Windows-Media-Center-using-a-Windows-Mobile-5-Device</guid>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/c4f/images/2632164_100.jpg" height="75" width="100"></media:thumbnail>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/c4f/images/2632164_220.jpg" height="165" width="220"></media:thumbnail>      
      <dc:creator>Matt Ivers</dc:creator>
      <itunes:author>Matt Ivers</itunes:author>
      <slash:comments>25</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/coding4fun/articles/Control-Windows-Media-Center-using-a-Windows-Mobile-5-Device/RSS</wfw:commentRss>
      <category>Media</category>
      <category>Home Automation</category>
      <category>audiovideo</category>
      <category>hardwarehacks</category>
    </item>
  <item>
      <title>Bill Gates at CES</title>
      <description><![CDATA[Bill Gates was kind enough to spend a few minutes with me talking about the future of the digital home, Tablet PCs, and technology. This was held in the Microsoft Partners Pavilion which was full of some of the coolest gadgets and gizmos that consumers will be drooling over this year.<br><br>Update: All the downloadable formats are now online.&nbsp;Get 'em while they're hot! <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Tags/home+automation/RSS&WT.dl=0&WT.entryid=Entry:RSSView:7cd77d270f20411586cb9e0f01021d54">]]></description>
      <comments>http://channel9.msdn.com/Blogs/LarryLarsen/Bill-Gates-at-CES-2007</comments>
      <itunes:summary>Bill Gates was kind enough to spend a few minutes with me talking about the future of the digital home, Tablet PCs, and technology. This was held in the Microsoft Partners Pavilion which was full of some of the coolest gadgets and gizmos that consumers will be drooling over this year.Update: All the downloadable formats are now online.&amp;nbsp;Get &#39;em while they&#39;re hot!</itunes:summary>
      <itunes:duration>448</itunes:duration>
      <link>http://channel9.msdn.com/Blogs/LarryLarsen/Bill-Gates-at-CES-2007</link>
      <pubDate>Mon, 08 Jan 2007 06:17:00 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/Blogs/LarryLarsen/Bill-Gates-at-CES-2007</guid>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/content/on10/entries/preview/ces2007_billgates_large_on10.jpg" height="240" width="320"></media:thumbnail>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/content/on10/entries/previewsmall/ces2007_billgates_small_on10.jpg" height="64" width="85"></media:thumbnail>
      <media:group>
        <media:content url="http://download.microsoft.com/download/7/3/3/733acbfd-ddde-436c-818b-d106d656e3a7/CES2007_BillGates_2MB_on10.wmv" expression="full" duration="448" fileSize="140760645" type="video/x-ms-wmv" medium="video"></media:content>
        <media:content url="http://download.microsoft.com/download/7/3/3/733acbfd-ddde-436c-818b-d106d656e3a7/CES2007_BillGates_on10.wmv" expression="full" duration="448" fileSize="28530586" type="video/x-ms-wmv" medium="video"></media:content>
        <media:content url="http://download.microsoft.com/download/7/3/3/733acbfd-ddde-436c-818b-d106d656e3a7/CES2007_BillGates_Zune_on10.wmv" expression="full" duration="448" fileSize="36136246" type="video/x-ms-wmv" medium="video"></media:content>
        <media:content url="http://on10.net/videos/CES2007_BillGates_on10.asx" expression="full" duration="448" fileSize="115" type="video/x-ms-wmv" medium="video"></media:content>
        <media:content url="http://on10.net/videos/CES2007_BillGates_s_on10.mp4" expression="full" duration="448" fileSize="29458039" type="video/mp4" medium="video"></media:content>
      </media:group>      
      <enclosure url="http://download.microsoft.com/download/7/3/3/733acbfd-ddde-436c-818b-d106d656e3a7/CES2007_BillGates_on10.wmv" length="28530586" type="video/x-ms-wmv"></enclosure>
      <dc:creator>Larry Larsen</dc:creator>
      <itunes:author>Larry Larsen</itunes:author>
      <slash:comments>8</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/Blogs/LarryLarsen/Bill-Gates-at-CES-2007/RSS</wfw:commentRss>
      <category>CES</category>
      <category>Media Center</category>
      <category>Tablet PC</category>
      <category>Home Automation</category>
    </item>
  <item>
      <title>Controlling Your Lights with Your PC</title>
      <description><![CDATA[
<p></p>
<p><b>Chris Walker<br>
ControlThink LC</b><b></b> </p>
<p><b>Difficulty: </b>Easy </p>
<p><b>Time Required:</b> 1-3 hours </p>
<p><b>Cost: </b>$50-$100 </p>
<p><b>Software: <a href="http://www.controlthink.com">Z-Wave PC SDK</a></b> </p>
<p><a href="http://msdn.com/express/"></a><strong>Hardware:</strong> <a href="http://www.controlthink.com">
Z-Wave PC SDK</a> </p>
<p><b>Download: </b></p>
<ul>
<li><a href="http://channel9.msdn.com/ShowPost.aspx?PostID=267636">C# Download</a>
</li><li><a href="http://channel9.msdn.com/ShowPost.aspx?PostID=267637">VB Download</a></li></ul>
<p><b>December 20, 2006</b> </p>
<p>Controlling your lights with a remote is pretty cool, but doing it from your PC opens up a whole world of fun possibilities.
</p>
<p>In this article, we'll add your computer to the Z-Wave network which we set up in the previous article. We'll run software to demonstrate how to set up and activate scenes with the PC. And then we'll see how easy it is to write our own code and totally personalize
 the system. </p>
<p><b>What you need</b> </p>
<p>For this project, you'll need a copy of ThinkEssentials, our Z-Wave PC SDK, and a compatible Z-Wave USB Stick. Here, we'll use the Z-Wave PC SDK bundle which includes all three. You can get it for $69 from
<a href="http://www.controlthink.com/">http://www.controlthink.com</a>. </p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/1337418/clip_image0014.jpg"><img height="160" alt="usbstick" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/1337418/clip_image0013.jpg" width="240" border="0"></a>Intermatic's
 HA22 USB Stick; we'll plug this into our computer. </p>
<p>Once you have the kit, simply plug the Z-Wave USB stick into your PC. If a USB extension cable was provided, plug the USB stick into it instead and then move the USB stick away from walls and metal objects for best reception. Finally, install the USB stick
 drivers and both software products (all of which are on the CD). </p>
<p>Now that the software and hardware are installed, we're ready to get started. </p>
<p><b>Adding your computer to the Z-Wave network</b> </p>
<p>To add your computer to the network we set up in the previous article, we'll use the ThinkEssentials software (although you can also join a network with a line or two of code—see the
<a href="http://channel9.msdn.com/ShowPost.aspx?PostID=267638">Z-Wave PC SDK Primer sample code</a> ). Go ahead and start the software up now. Then, switch to the Advanced Settings tab on the left side of the screen.
</p>
<p>If you haven't set up your Z-Wave network with a remote already, you could set it up with your PC instead--using the ThinkEssentials software or by writing some code. If you'd rather go that route, you can find full details in the
<a href="http://channel9.msdn.com/ShowPost.aspx?PostID=267638">Z-Wave PC SDK Primer</a> .
</p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/1337418/clip_image0024.gif"><img height="120" alt="AdvancedSettingsTab.gif" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/1337418/clip_image0023.gif" width="240" border="0"></a><br>
The ThinkEssentials Advanced Settings tab; we'll add our computer to the network here.
</p>
<p>On the Advanced Settings tab, click the “Join Existing Network” button. This will put our USB stick into a mode where it can be added into an existing network. On your HA09 (Tabletop Remote), flip open its lid and press and hold the INCLUDE button for a
 few seconds until it displays “COPY”. If you have an HA07 (Handy Remote) instead, hold down INCLUDE until the red and green LEDs start flashing. Finally, press the CHANNEL 1 ON button to start adding your PC to the network. This process may take five or ten
 seconds to get started. </p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/1337418/clip_image0034.jpg"><img height="120" alt="joinnetwork.jpg" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/1337418/clip_image0033.jpg" width="240" border="0"></a><br>
The JOIN EXISTING NETWORK button (left); holding the INCLUDE button (right) </p>
<p>Once your computer is added to the network, ThinkEssentials may close automatically and save the changes. Simply restart the software.
</p>
<p><b>Controlling your devices from the PC</b> </p>
<p>Switch to the Home tab in ThinkEssentials, and you'll see icons for each of your devices at the bottom-right corner of the window. To turn them on or off, simply click on them. Go ahead, try this now. If you have lamp modules or dimmable light switches,
 simply right-click on them for dimming options. </p>
<p>If you'd like, you can also draw your home's floor plan, set up mood lighting (scenes), set up scheduled events for those scenes, etc. I'll leave these to your experimentation; if you need any guidance, a shortcut to the User's Guide is included in the Start
 Menu Programs folder alongside the software. </p>
<p><b>Turning on lights from Visual Basic Express or Visual C# Express</b> </p>
<p>When you're done experimenting with the ThinkEssentials software, go ahead and close it so we can use the Z-Wave USB stick from Visual Studio Express. You can download Microsoft's Visual Studio Express. If you've set up any scheduled events, you'll need
 to right-click on the software's system tray icon and select “Exit” from the pop-up menu.
</p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/1337418/clip_image0044.jpg"><img height="96" alt="trayexit.jpg" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/1337418/clip_image0043.jpg" width="240" border="0"></a><br>
To completely shut down ThinkEssentials, right-click on its tray icon and click Exit.
</p>
<p>Now, we're ready to get started controlling our lights using Visual Studio Express. With Visual Studio Express, we can personalize our home in unlimited ways. For now, we'll start out simple and turn on the lights.
</p>
<p><b>Creating our Visual Basic Express and Visual C# Express project</b> </p>
<p>With this sample, we're going to turn on all of our lights. So to prepare for this sample, go ahead and turn off all the lights connected to Z-Wave devices (plug-in modules).
</p>
<p>Then, start up Visual Basic Express or Visual C# Express. Create a Windows Application named “TurnOnLights”. Once you've created the project, select “Add Reference…” from the Project menu, switch to the dialog's Browse tab, and then add in the ControlThink.ZWave.dll
 file that came with the Z-Wave PC SDK. If you don't know where it is, look in your Program Files folder for a ControlThink and Z-Wave PC SDK folder.
</p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/1337418/clip_image0054.gif"><img height="153" alt="addreference.gif" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/1337418/clip_image0053.gif" width="240" border="0"></a><br>
To add the Z-Wave assembly to the project, select Add Reference from the Project menu…
</p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/1337418/clip_image0064.gif"><img height="190" alt="BrowseForDll.gif" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/1337418/clip_image0063.gif" width="240" border="0"></a><br>
In the Add Reference dialog, change to the Browse tab and then add in ControlThink.ZWave.dll.
</p>
<p>Once you have added in the Z-Wave assembly, double-click on the default form; this should open up the Form_Load method in code. Once there, we'll create an instance of the ZWaveController object. This will let us connect to our Z-Wave network with the USB
 stick. In the Form_Load method, add the following code: </p>
<p><b>Visual Basic</b> </p>
<p>Dim zwaveController As New ControlThink.ZWave.ZWaveController() </p>
<p><b>Visual C#</b> </p>
<p>ControlThink.ZWave.ZWaveController zwaveController = new ControlThink.ZWave.ZWaveController();
</p>
<p>Next, we'll connect to the network. It only takes two lines of code to get “online” with the home.
</p>
<p><b>Visual Basic</b> </p>
<p>zwaveController.Connect() </p>
<p><b>Visual C#</b> </p>
<p>zwaveController.Connect(); </p>
<p>Now that we've created the necessary code to connect to the network through our Z-Wave USB stick, we'll add just a few more lines of code to turn on all the lights. Every device in our network is ultimately based on the ZWaveDevice object, and this class
 gives us the ability to turn on and off devices as well as change their dim level so we'll use it here.
</p>
<p>Let's also include a Try…Catch block here; our remotes and some other devices cannot be turned on and off and consequently throw an exception if we try.
</p>
<p><b>Visual Basic</b> </p>
<p>For Each device As ControlThink.ZWave.Devices.ZWaveDevice In zwaveController.Devices
</p>
<p>Try </p>
<p>device.PowerOn() </p>
<p>Catch ex As Exception </p>
<p>End Try </p>
<p>Next </p>
<p><b>Visual C#</b> </p>
<p><b><br>
</b>foreach(ControlThink.ZWave.Devices.ZWaveDevice device in zwaveController.Devices)
</p>
<p>{ </p>
<p>try </p>
<p>{ </p>
<p>device.PowerOn(); </p>
<p>} </p>
<p>catch(Exception ex) </p>
<p>{} </p>
<p>} </p>
<p>That's it. Run your code, and watch your lights turn on! </p>
<p>Of course, you can also turn everything off. To do that instead, just change the PowerOn method to PowerOff:
</p>
<p><b>Visual Basic</b> </p>
<p>For Each device As ControlThink.ZWave.Devices.ZWaveDevice In zwaveController.Devices
</p>
<p>Try </p>
<p>device.PowerOff() </p>
<p>Catch ex As Exception </p>
<p>End Try </p>
<p>Next </p>
<p><b>Visual C#</b> </p>
<p><b><br>
</b>foreach(ControlThink.ZWave.Devices.ZWaveDevice device in zwaveController.Devices)
</p>
<p>{ </p>
<p>try </p>
<p>{ </p>
<p>device.PowerOff(); </p>
<p>} </p>
<p>catch(Exception ex) </p>
<p>{} </p>
<p>} </p>
<p><b>What to try next</b> </p>
<p>Now that you've experienced the basics of using Z-Wave from Visual Studio Express, here are a few ideas you can use to personalize your own home:
</p>
<p>1. device.Level can be set to 0 for off, or 1-99 for dim levels (99 = full on).
</p>
<p>2. zwaveController.Devices is a collection of all the devices in your network. Each of those devices has a unique ID on the network called a Node ID. Access the devices individually by index, or use zwaveController.Devices.GetByNodeID(…) to access each device
 by its unique Node ID. </p>
<p>3. <a href="http://msdn.microsoft.com/coding4fun/windows/utility/article.aspx?articleid=908744&amp;title=Creating&#43;an&#43;Alarm&#43;Clock&#43;in&#43;the&#43;System&#43;Tray">
Alarm Clock</a> sample from Coding4Fun, and customize it to turns up the heating set point 30 minutes before the alarm goes off.
</p>
<p><b>About the author</b> </p>
<p>Chris Walker is President and Chief Software Architect of <a href="http://www.controlthink.com/">
ControlThink</a>, creator of the Z-Wave SDKs for .NET platforms, and is an outspoken advocate of reliable home control technology. He is determined to make home control technology easy to use and affordable for all homeowners.
<span>Chris Walker http://channel9.msdn.com/ShowPost.aspx?PostID=267636 http://channel9.msdn.com/ShowPost.aspx?PostID=267637 Easy $50-$100 1-3 hours Z-Wave PC SDK]]&gt; ]]&gt;</span></p>
 <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Tags/home+automation/RSS&WT.dl=0&WT.entryid=Entry:RSSView:0cf36b2e73ad4d449e4c9e7600d700c2">]]></description>
      <comments>http://channel9.msdn.com/coding4fun/articles/Controlling-Your-Lights-with-Your-PC</comments>
      <itunes:summary>
 
Chris Walker
ControlThink LC  
Difficulty: Easy  
Time Required: 1-3 hours  
Cost: $50-$100  
Software: Z-Wave PC SDK  
Hardware: 
Z-Wave PC SDK  
Download:  

C# Download
VB Download
December 20, 2006  
Controlling your lights with a remote is pretty cool, but doing it from your PC opens up a whole world of fun possibilities.
 
In this article, we&#39;ll add your computer to the Z-Wave network which we set up in the previous article. We&#39;ll run software to demonstrate how to set up and activate scenes with the PC. And then we&#39;ll see how easy it is to write our own code and totally personalize
 the system.  
What you need  
For this project, you&#39;ll need a copy of ThinkEssentials, our Z-Wave PC SDK, and a compatible Z-Wave USB Stick. Here, we&#39;ll use the Z-Wave PC SDK bundle which includes all three. You can get it for $69 from
http://www.controlthink.com.  
Intermatic&#39;s
 HA22 USB Stick; we&#39;ll plug this into our computer.  
Once you have the kit, simply plug the Z-Wave USB stick into your PC. If a USB extension cable was provided, plug the USB stick into it instead and then move the USB stick away from walls and metal objects for best reception. Finally, install the USB stick
 drivers and both software products (all of which are on the CD).  
Now that the software and hardware are installed, we&#39;re ready to get started.  
Adding your computer to the Z-Wave network  
To add your computer to the network we set up in the previous article, we&#39;ll use the ThinkEssentials software (although you can also join a network with a line or two of code—see the
Z-Wave PC SDK Primer sample code ). Go ahead and start the software up now. Then, switch to the Advanced Settings tab on the left side of the screen.
 
If you haven&#39;t set up your Z-Wave network with a remote already, you could set it up with your PC instead--using the ThinkEssentials software or by writing some code. If you&#39;d rather go that route, you can find full details in the
Z-Wave PC SDK Primer .
 

The ThinkEssentials Adva</itunes:summary>
      <link>http://channel9.msdn.com/coding4fun/articles/Controlling-Your-Lights-with-Your-PC</link>
      <pubDate>Wed, 20 Dec 2006 23:59:06 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/coding4fun/articles/Controlling-Your-Lights-with-Your-PC</guid>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/c4f/images/1337418_100.jpg" height="75" width="100"></media:thumbnail>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/c4f/images/1337418_220.jpg" height="165" width="220"></media:thumbnail>      
      <dc:creator>Chris Walker</dc:creator>
      <itunes:author>Chris Walker</itunes:author>
      <slash:comments>22</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/coding4fun/articles/Controlling-Your-Lights-with-Your-PC/RSS</wfw:commentRss>
      <category>Home Automation</category>
    </item>
  <item>
      <title>Decking Out Your Home Entertainment System with Theater-style Lighting</title>
      <description><![CDATA[<span id="c4fmetadata">
<table cellspacing="0" cellpadding="1" width="100%" border="0">
<tbody>
<tr class="entry_overview">
<td width="50"><img height="50" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/1088252/int_thumb.jpg" width="50"></td>
<td><span class="entry_description">This article walks through how to get that real movie theater feeling at home using the Intermatic HomeSettings Kit.</span></td>
</tr>
<tr>
<td colspan="2">
<div class="entry_author">Chris Walker</div>
<div class="entry_company"><a href="http://www.controlthink.com/">ControlThink LC</a></div>
<br>
<div class="entry_details"><b>Difficulty: </b><span class="entry_details_input">Easy</span></div>
<div class="entry_details"><b>Time Required:</b> <span class="entry_details_input">
Less than 1 hour</span></div>
<div class="entry_details"><b>Cost: </b><span class="entry_details_input">$100-$200</span></div>
<div class="entry_details"><b>Software: </b><span class="entry_details_input">None</span></div>
<div class="entry_details"><b>Hardware: </b><span class="entry_details_input"><a href="http://www.homesettings.com/">Intermatic Home Settings Kit</a></span></div>
<div class="entry_details">Video: <a href="http://channel9.msdn.com/ShowPost.aspx?PostID=259155">
Watch the Channel9 Video</a>&nbsp;</div>
</td>
</tr>
</tbody>
</table>
</span>
<p></p>
<p><b></b>&nbsp;</p>
<p>To deck out your home entertainment system, typical options include buying a bigger TV or a better speaker system. But for something really unique and cool, add automated lighting to yours for less than $100 to give it that real movie theater feeling.
</p>
<p>In just a few minutes, you'll be dimming the lights when movies start and will have the coolest system around!
</p>
<p><b>What you need<br>
</b>For this project, you'll need a Z-Wave® remote control and two Z-Wave plug-in lamp modules. Here, we'll use Intermatic®‘s HomeSettings™ Lighting Control Starter Kit (model HA101K). I found it for $99 at Lowes, although you can buy it at other retail stores
 or online. </p>
<p>You'll also need 4 AA batteries. </p>
<p>NOTE: if your lighting is built-in and controlled by switches, you can pick up Z-Wave light switches from any manufacturer and use them instead of the plug-in modules—but you'll want to follow the switches' installation instructions or hire an electrician
 to wire those up. </p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/1088252/image0012.jpg"><img height="333" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/1088252/image001_thumb.jpg" width="500" border="0"></a>
</p>
<p>Intermatic's HomeSettings Lighting Control Starter Kit (model HA101K) </p>
<p>You'll quickly notice that this system is wireless. There have been powerline home automation systems in the past, but those have often been plagued with reliability problems. But don't let that worry you: Z-Wave devices are wireless and will even act as
 mesh-networked repeaters automatically. If you're not familiar with how that works, just know that it's quite a reliable system.
</p>
<p><b>Hooking up the lights<br>
</b>Since we're using plug-in modules here, there's no need to break out voltage meters or screwdrivers. Simply plug the lamps into the modules and then plug the modules into the wall. Also, be sure to turn on the lamps themselves.
</p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/1088252/image0022.jpg"><img height="250" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/1088252/image002_thumb.jpg" width="500" border="0"></a>
</p>
<p>Plugging lamp into module (left); module plugged into wall outlet (right) </p>
<p><b>Adding the lights to the remote<br>
</b>Now, we just need to add the lamp modules to the remote control. Make sure there are batteries in the remote, and flip it open to reveal the INCLUDE and DELETE buttons.
</p>
<p>To add a lamp module to the remote, simply press and release the INCLUDE button. The display will show a small “INCL” indicator in the top-right corner of the LCD and will flash “TRANSMITTING.” Then, press the button on the lamp module. The remote should
 flash “SUCCESSFUL” indicating that it now recognizes your module. You have just paired the lamp module with your remote!
</p>
<p>Go ahead and repeat this now with your second lamp module. </p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/1088252/image0042.jpg"><img height="220" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/1088252/image004_thumb.jpg" width="500" border="0"></a>
</p>
<p>Pressing the INCLUDE button (left); pressing the button on the device (right) </p>
<p><b>Setting up the lighting scene<br>
</b>For our home theater experience, we want to fade the lights off when we start the movie and turn them back on just slightly when the movie is over so that we don't blind our movie-watching guests.
</p>
<p>Let's add the lamp modules to scene one on the remote. This is a quick three step process.
</p>
<p>NOTE: there are six sets of scene buttons (on and off for each scene) on this remote. Pressing the SHIFT button will switch to scenes 7 through 12, so make sure you're currently looking at scenes 1 through 6; if you're not, simply press the SHIFT button.
</p>
<p>First, simultaneously press and hold both the ON and OFF buttons for scene one. After holding down these two buttons for three or four seconds, the display will show “LEARN” in big text. Now, press and hold the INCLUDE button—and don't let go of it quite
 yet. </p>
<p>While you're holding down the INCLUDE button, press the button on the lamp module to include in this scene. If the lamp module is off or turns off, press the button on the lamp module again to turn it on. When the lamp is on, go ahead and release the INCLUDE
 button on the remote. That's it! </p>
<p>Now, go ahead and repeat this process for the other lamp module, again using scene one.
</p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/1088252/image0062.jpg"><img height="220" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/1088252/image006_thumb.jpg" width="500" border="0"></a>
</p>
<p><b><br>
</b>Pressing scene one's ON and OFF buttons (left)<b>; </b>pressing and holding the INCLUDE button (right)<b></b>
</p>
<p><b>Settling in for the ultimate home theater experience<br>
</b>Now it's time to grab your favorite movie and snack, gather your friends, and enjoy your new setup. To turn off the lights (with nifty ramping effect), press scene one's OFF button. When the movie is over, press the ON button. If you want to dim the lights
 up or down, simply hold down the scene's ON (dim up) or OFF (dim down) button respectively.
</p>
<p><b><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/1088252/image0082.jpg"><img height="327" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/1088252/image008_thumb.jpg" width="500" border="0"></a>
<br>
</b>Lights off! Pressing scene one's OFF button sets the mood for “Batman Begins”…<b></b>
</p>
<p><b>More cool things to do with your new setup<br>
</b>One of the great things about Z-Wave is that you can do new things with your existing devices and can add on new devices anytime. Here are a few cool things to do with your new setup:
</p>
<p>1. Set up a second scene with the lights at 20%; this will be good to switch to when the movie is over so you don't blind your friends.
</p>
<p>2. When I'm tired, getting out of bed wakes me up. Set up your bedroom instead and enjoy this new convenience when going to bed (or getting up!)
</p>
<p>3. For an even better home theater experience, wire up your overhead lights—or add in motorized blinds. If it has the Z-Wave logo on it, it'll work with your system.
</p>
<p><b>About the author<br>
</b>Chris Walker is President and Chief Software Architect of <a href="http://www.controlthink.com/">
ControlThink</a>, creator of the Z-Wave SDKs for .NET platforms, and is an outspoken advocate of reliable home control technology. He is determined to make home control technology affordable and available to the average homeowner.</p>
 <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Tags/home+automation/RSS&WT.dl=0&WT.entryid=Entry:RSSView:75b4bef67d9e46439d6a9e7600d834bd">]]></description>
      <comments>http://channel9.msdn.com/coding4fun/articles/Decking-Out-Your-Home-Entertainment-System-with-Theater-style-Lighting</comments>
      <itunes:summary>




This article walks through how to get that real movie theater feeling at home using the Intermatic HomeSettings Kit.



Chris Walker
ControlThink LC

Difficulty: Easy
Time Required: 
Less than 1 hour
Cost: $100-$200
Software: None
Hardware: Intermatic Home Settings Kit
Video: 
Watch the Channel9 Video&amp;nbsp;





 
&amp;nbsp; 
To deck out your home entertainment system, typical options include buying a bigger TV or a better speaker system. But for something really unique and cool, add automated lighting to yours for less than $100 to give it that real movie theater feeling.
 
In just a few minutes, you&#39;ll be dimming the lights when movies start and will have the coolest system around!
 
What you need
For this project, you&#39;ll need a Z-Wave&#174; remote control and two Z-Wave plug-in lamp modules. Here, we&#39;ll use Intermatic&#174;‘s HomeSettings™ Lighting Control Starter Kit (model HA101K). I found it for $99 at Lowes, although you can buy it at other retail stores
 or online.  
You&#39;ll also need 4 AA batteries.  
NOTE: if your lighting is built-in and controlled by switches, you can pick up Z-Wave light switches from any manufacturer and use them instead of the plug-in modules—but you&#39;ll want to follow the switches&#39; installation instructions or hire an electrician
 to wire those up.  

 
Intermatic&#39;s HomeSettings Lighting Control Starter Kit (model HA101K)  
You&#39;ll quickly notice that this system is wireless. There have been powerline home automation systems in the past, but those have often been plagued with reliability problems. But don&#39;t let that worry you: Z-Wave devices are wireless and will even act as
 mesh-networked repeaters automatically. If you&#39;re not familiar with how that works, just know that it&#39;s quite a reliable system.
 
Hooking up the lights
Since we&#39;re using plug-in modules here, there&#39;s no need to break out voltage meters or screwdrivers. Simply plug the lamps into the modules and then plug the modules into the wall. Also, be sure to turn on the lamps themsel</itunes:summary>
      <link>http://channel9.msdn.com/coding4fun/articles/Decking-Out-Your-Home-Entertainment-System-with-Theater-style-Lighting</link>
      <pubDate>Thu, 16 Nov 2006 16:22:35 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/coding4fun/articles/Decking-Out-Your-Home-Entertainment-System-with-Theater-style-Lighting</guid>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/c4f/images/1088252_100.jpg" height="75" width="100"></media:thumbnail>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/c4f/images/1088252_220.jpg" height="165" width="220"></media:thumbnail>      
      <dc:creator>Chris Walker</dc:creator>
      <itunes:author>Chris Walker</itunes:author>
      <slash:comments>0</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/coding4fun/articles/Decking-Out-Your-Home-Entertainment-System-with-Theater-style-Lighting/RSS</wfw:commentRss>
      <category>Hardware</category>
      <category>Home Automation</category>
    </item>    
</channel>
</rss>