<?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</title>
    <atom:link rel="self" type="application/rss+xml" href="http://channel9.msdn.com/Niners/c4f.Charles-Stacy-Harris-III/Posts/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</title>
      <link>http://channel9.msdn.com/Niners/c4f.Charles-Stacy-Harris-III/Posts</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/Niners/c4f.Charles-Stacy-Harris-III/Posts</link>
    <language>en</language>
    <pubDate>Wed, 19 Jun 2013 07:37:38 GMT</pubDate>
    <lastBuildDate>Wed, 19 Jun 2013 07:37:38 GMT</lastBuildDate>
    <generator>Rev9</generator>
    <c9:totalResults>1</c9:totalResults>
    <c9:pageCount>1</c9:pageCount>
    <c9:pageSize>25</c9:pageSize>
  <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/Niners/c4f.Charles-Stacy-Harris-III/Posts/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>    
</channel>
</rss>