<?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.Ken-Hughes/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.Ken-Hughes/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.Ken-Hughes/Posts</link>
    <language>en</language>
    <pubDate>Thu, 23 May 2013 21:41:02 GMT</pubDate>
    <lastBuildDate>Thu, 23 May 2013 21:41:02 GMT</lastBuildDate>
    <generator>Rev9</generator>
    <c9:totalResults>1</c9:totalResults>
    <c9:pageCount>1</c9:pageCount>
    <c9:pageSize>25</c9:pageSize>
  <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/Niners/c4f.Ken-Hughes/Posts/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>    
</channel>
</rss>