<?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>Coding 4 Fun</title>
    <atom:link rel="self" type="application/rss+xml" href="http://channel9.msdn.com/coding4fun/rss"></atom:link>
    <generator>Rev9</generator>
    <description></description>
    <link>http://channel9.msdn.com/coding4fun/rss</link>
    <language>en</language>
	<item>
    <title>Mouse with your mind...</title>
    <description><![CDATA[<p>Recently on the <a href="http://channel9.msdn.com/coding4fun/kinect" target="_blank">Coding4Fun Kinect Gallery</a> I highlighted a couple Kinect -&gt; Mouse projects, <a href="http://channel9.msdn.com/coding4fun/kinect/Is-that-a-mouse-on-your-face-Or-your-face-acting-as-a-mouse-Both-FaceMouse" target="_blank">Is that a mouse on your face? Or your face acting as a mouse? Both? FaceMouse</a>, <a href="http://channel9.msdn.com/coding4fun/kinect/KinectMouse" target="_blank">KinectMouse</a>. And while I don't usually highlight commercial, non-source available projects I thought this pretty cool.</p><p>But what if you don't have a Kinect? Or use of your hands? Or have limited movement or space?</p><p>You all know I have this thing for <a href="http://emotiv.com" target="_blank">Emotiv</a>. So lets put all this together.</p><p>What if you could...</p><h2><a href="http://futuretechblog.com/?p=110" target="_blank">Use your brain as mouse control (with EPOC by Emotiv)</a></h2><blockquote><p>Can you imagine that there is an easier way to control the mouse, than with your head? The answer could be: With your mind.</p><p>Electroencephalography (EEG) was already established in 1924. In the past it was used mainly for medical reasons. But now you can also use this technology, to control your computer.</p><h6><strong><em>Emotiv EPOC</em></strong></h6><p><em><a href="http://www.emotiv.com/">Emotiv</a></em> has developed a Neuroheadset called <em>EPOC</em>. It reads your brainwaves and on this ground it is able to detect your current feelings like boredom, frustration, meditation and excitement. Your mind sends also certain signal patterns when your face is showing facial expressions. So <em>EPOC</em> can detect facial expressions like smiling, lowering and raising your eyebrows, clenching your teeths or blinking your eyes. This is quite similar to the facial expression detection, which is provided by <em>Kinect for Windows</em> SDK. Furthermore <em>EPOC</em> has a Gyroscope, which recognizes your head movement very accurate. So we developed a version of <em>FaceMouse</em> especially for <em>EPOC</em>.</p><h6><em><strong>FaceMouse for EPOC</strong></em></h6><p>You can replace your mouse with <em>Emotiv EPOC</em>, the revolutionary brain computer interface. Within Emotiv Control Panel there is already a Mouse Emulator which uses the <em>EPOC</em> Gyroscope to control the cursor of your mouse. <em>EmoKey</em>, an app developed by <em>Emotiv</em>, provides basic functionality for clicking by using <em>EPOC</em>, but this method has several disadvantages:</p><ul><li>In <em>EmoKey</em> clicks are sometimes not executed correctly in special kinds of application windows. </li><li>It is not possible to send a scroll command with <em>EmoKey</em>. </li></ul><p><em>FaceMouse for EPOC</em> sends mouseclicks directly to the operating system, independent from the currently active application window. Also it is possible to scroll or drag &amp; drop, which is not possible with <em>EmoKey</em>.</p><p>Just activate the Mouse Emulator in <em>Emotiv</em> Control Panel and use this simple App. It is the easiest way to replace your mouse with <em>EPOC</em>.</p></blockquote><h2><a href="http://emotiv.com/store/apps/applications/130/49234" target="_blank">FaceMouse</a></h2><blockquote><p>This is a small Windows application, which enhances the possibilities to use EPOC as mouse control. Within Emotiv Control Panel you find a Mouse Emulator which uses the EPOC Gyroskop to control the cursor of your mouse. EmoKey provides basic functionality for clicking by using EPOC, but this method has several disadvantages:</p><p>In EmoKey clicks are sometimes not executed correctly in special kinds of application windows. Also it is not possible to send a scroll command with EmoKey.</p><p>This application sends mouseclicks directly to the operating system, independent from the currently active application window. Also it is possible to scroll or point &amp; click. FaceMouse uses data from Expressiv Suite.</p><p>Just activate the Mouse Emulator in Emotiv Control Panel and use this simple App. It is the easiest way to replace your mouse with EPOC.</p><p><img title="image" src="http://files.channel9.msdn.com/wlwimages/ae054c0b4d7b402ab1239e6800c0220f/image%5B2%5D-132.png" alt="image" width="463" height="244" border="0"></p></blockquote><p>Mouse control with your face, head and mind... That's just cool</p> <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/coding4fun/rss&WT.dl=0&WT.entryid=Entry:RSSView:b04e9ca7f9a84b7394f2a1bb013a763f">]]></description>
    <comments>http://channel9.msdn.com/coding4fun/blog/Mouse-with-your-mind</comments>
    <link>http://channel9.msdn.com/coding4fun/blog/Mouse-with-your-mind</link>
    <itunes:summary>Recently on the Coding4Fun Kinect Gallery I highlighted a couple Kinect -&amp;gt; Mouse projects, Is that a mouse on your face? Or your face acting as a mouse? Both? FaceMouse, KinectMouse. And while I don&#39;t usually highlight commercial, non-source available projects I thought this pretty cool. But what if you don&#39;t have a Kinect? Or use of your hands? Or have limited movement or space? You all know I have this thing for Emotiv. So lets put all this together. What if you could... Use your brain as mouse control (with EPOC by Emotiv)Can you imagine that there is an easier way to control the mouse, than with your head? The answer could be: With your mind. Electroencephalography (EEG) was already established in 1924. In the past it was used mainly for medical reasons. But now you can also use this technology, to control your computer. Emotiv EPOCEmotiv has developed a Neuroheadset called EPOC. It reads your brainwaves and on this ground it is able to detect your current feelings like boredom, frustration, meditation and excitement. Your mind sends also certain signal patterns when your face is showing facial expressions. So EPOC can detect facial expressions like smiling, lowering and raising your eyebrows, clenching your teeths or blinking your eyes. This is quite similar to the facial expression detection, which is provided by Kinect for Windows SDK. Furthermore EPOC has a Gyroscope, which recognizes your head movement very accurate. So we developed a version of FaceMouse especially for EPOC. FaceMouse for EPOCYou can replace your mouse with Emotiv EPOC, the revolutionary brain computer interface. Within Emotiv Control Panel there is already a Mouse Emulator which uses the EPOC Gyroscope to control the cursor of your mouse. EmoKey, an app developed by Emotiv, provides basic functionality for clicking by using EPOC, but this method has several disadvantages: In EmoKey clicks are sometimes not executed correctly in special kinds of application windows. It is not possible t</itunes:summary>
    <pubDate>Fri, 17 May 2013 13:00:00 GMT</pubDate>
    <guid isPermaLink="false">http://channel9.msdn.com/coding4fun/blog/Mouse-with-your-mind</guid>
    <dc:creator>Greg Duncan</dc:creator>
    <category>coding4fun</category>
    <category>emotiv+systems</category>
  </item>
	<item>
    <title>&quot;Building a Real Application with Kinect&quot; from John Sonmez and pluralsight</title>
    <description><![CDATA[<p>While I don't usually highlight stuff you have to pay for (though they do offer a great free trial), this is the first course of this nature at <a href="http://www.pluralsight.com/" target="_blank">pluralsight</a> and since it covers our favorite hardware device, well, I can make an exception this time.</p><h2><a href="http://blog.pluralsight.com/2013/05/01/new-course-building-a-real-application-with-kinect/" target="_blank">New course: Building a Real Application with Kinect</a></h2><blockquote><p><strong><a href="http://pluralsight.com/training/Authors/Details/john-sonmez">John Sonmez</a> has published a new course: <a href="http://www.pluralsight.com/training/Courses/TableOfContents/building-real-kinect-application">Building a Real Application with Kinect</a></strong></p><p><em>Have you played with Microsoft Kinect? Do you think it’s legit? Wouldn’t it be awesome if you could write your own Kinect enabled applications to take advantage of this awesome piece of technology? Well, I have great news… <a href="http://feeds.feedburner.com/MakingTheComplexSimple">John</a> has written a course so you can&nbsp; </em></p><p>In this course he will walk you through the creation of a real application using the Kinect. You’ll be building a Fruit Ninja clone called Shape Ninja which will be capable of detecting chopping gestures and responding to audio commands. You will start off by learning a little bit about the Kinect itself and the <a href="http://www.microsoft.com/en-us/kinectforwindows/develop/">Kinect SDK</a>. Then, John shows you just how easy it is to get color image and depth data from the Kinect. You’ll make your application be able to detect and respond to a chopping gesture. He wraps things up by teaching you how to use the Microsoft Speech Platform SDK in combination with the Kinect’s audio sensors to implement real voice commands for our application.</p><p>If you’ve been waiting to check out the Kinect, but you didn’t know where to start, or perhaps you thought it would be difficult to learn; this course will get you up and running with the Kinect in no time. <a href="http://www.pluralsight.com/training/Courses/TableOfContents/building-real-kinect-application">Click here</a> to get started now. We hope you enjoy the course!</p></blockquote><p><strong>Project Information URL:</strong> <a title="http://blog.pluralsight.com/2013/05/01/new-course-building-a-real-application-with-kinect/" href="http://blog.pluralsight.com/2013/05/01/new-course-building-a-real-application-with-kinect/">http://blog.pluralsight.com/2013/05/01/new-course-building-a-real-application-with-kinect/</a>, <a title="http://www.pluralsight.com/training/Courses/TableOfContents/building-real-kinect-application" href="http://www.pluralsight.com/training/Courses/TableOfContents/building-real-kinect-application">http://www.pluralsight.com/training/Courses/TableOfContents/building-real-kinect-application</a></p><p><a href="http://www.pluralsight.com/training/Courses/TableOfContents/building-real-kinect-application" target="_blank"><img title="image" src="http://files.channel9.msdn.com/wlwimages/f1dda9cc6de74512b7c19f0101402403/image%5B24%5D-2.png" alt="image" width="692" height="608" border="0"></a></p><p><a href="http://www.pluralsight.com/training/Courses/TableOfContents/building-real-kinect-application" target="_blank"><img title="image" src="http://files.channel9.msdn.com/wlwimages/f1dda9cc6de74512b7c19f0101402403/image%5B23%5D-2.png" alt="image" width="687" height="491" border="0"></a></p><p><a href="http://www.pluralsight.com/training/Courses/TableOfContents/building-real-kinect-application" target="_blank"><img title="image" src="http://files.channel9.msdn.com/wlwimages/f1dda9cc6de74512b7c19f0101402403/image%5B22%5D-2.png" alt="image" width="696" height="491" border="0"></a></p><p><a href="http://www.pluralsight.com/training/Courses/TableOfContents/building-real-kinect-application" target="_blank"><img title="image" src="http://files.channel9.msdn.com/wlwimages/f1dda9cc6de74512b7c19f0101402403/image%5B21%5D-5.png" alt="image" width="705" height="519" border="0"></a></p><p><a href="http://www.pluralsight.com/training/Courses/TableOfContents/building-real-kinect-application" target="_blank"><img title="image" src="http://files.channel9.msdn.com/wlwimages/f1dda9cc6de74512b7c19f0101402403/image%5B20%5D-5.png" alt="image" width="686" height="514" border="0"></a></p><p>Contact Information:</p><ul><li>Blog: <a title="http://blog.pluralsight.com/2013/05/01/new-course-building-a-real-application-with-kinect/" href="http://blog.pluralsight.com">http://blog.pluralsight.com</a> </li><li>Twitter: <a href="https://twitter.com/pluralsight" target="_blank">@pluralsight</a> </li></ul> <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/coding4fun/rss&WT.dl=0&WT.entryid=Entry:RSSView:06f40f2e24ea422dbf1ea1bb0145550d">]]></description>
    <comments>http://channel9.msdn.com/coding4fun/kinect/Building-a-Real-Application-with-Kinect-from-John-Sonmez-and-pluralsight</comments>
    <link>http://channel9.msdn.com/coding4fun/kinect/Building-a-Real-Application-with-Kinect-from-John-Sonmez-and-pluralsight</link>
    <itunes:summary>While I don&#39;t usually highlight stuff you have to pay for (though they do offer a great free trial), this is the first course of this nature at pluralsight and since it covers our favorite hardware device, well, I can make an exception this time. New course: Building a Real Application with KinectJohn Sonmez has published a new course: Building a Real Application with Kinect Have you played with Microsoft Kinect? Do you think it’s legit? Wouldn’t it be awesome if you could write your own Kinect enabled applications to take advantage of this awesome piece of technology? Well, I have great news… John has written a course so you can&amp;nbsp;  In this course he will walk you through the creation of a real application using the Kinect. You’ll be building a Fruit Ninja clone called Shape Ninja which will be capable of detecting chopping gestures and responding to audio commands. You will start off by learning a little bit about the Kinect itself and the Kinect SDK. Then, John shows you just how easy it is to get color image and depth data from the Kinect. You’ll make your application be able to detect and respond to a chopping gesture. He wraps things up by teaching you how to use the Microsoft Speech Platform SDK in combination with the Kinect’s audio sensors to implement real voice commands for our application. If you’ve been waiting to check out the Kinect, but you didn’t know where to start, or perhaps you thought it would be difficult to learn; this course will get you up and running with the Kinect in no time. Click here to get started now. We hope you enjoy the course! Project Information URL: http://blog.pluralsight.com/2013/05/01/new-course-building-a-real-application-with-kinect/, http://www.pluralsight.com/training/Courses/TableOfContents/building-real-kinect-application      Contact Information: Blog: http://blog.pluralsight.com Twitter: @pluralsight </itunes:summary>
    <pubDate>Fri, 17 May 2013 13:00:00 GMT</pubDate>
    <guid isPermaLink="false">http://channel9.msdn.com/coding4fun/kinect/Building-a-Real-Application-with-Kinect-from-John-Sonmez-and-pluralsight</guid>
    <dc:creator>Greg Duncan</dc:creator>
    <category>coding4fun</category>
    <category>kinect</category>
    <category>training</category>
  </item>
	<item>
    <title>The Green Screen without a Green Screen - &quot;Kinect No Need 4 Green&quot;</title>
    <description><![CDATA[<p>As promised on Tuesday, here's this week's second project by David Renton, this time with him showing off (with code) how to do a &quot;green screen&quot; without a green screen...</p><h2><a href="http://drenton72.wordpress.com/2013/05/10/kinect-no-need-4-green-the-green-screen-without-a-green-screen/" target="_blank">Kinect No Need 4 Green – The Green Screen without a Green Screen</a></h2><blockquote><p>This little piece of software allows you to produce easily, quickly and cheaply the type of picture that you would normally need a proper green screen setup to create. The software uses a Kinect for Windows or Kinect for XBOX360 device connected to a Windows 7 or 8 pc.</p><p>All you need to do is stand in front of the device and it will cut you out. You can choose between different backdrops, which you can add to by copying your own pictures (JPEG or PNG) into the PICTURES sub-folder. You can zoom in &amp; out and move the cut out image using the keyboard or by on-screen controls.&nbsp; You can take snapshot pictures of what is displayed in the window and these pictures are saved into the SNAPSHOTS sub-folder.</p><p><strong>The keyboard controls are as below:-</strong><br>SPACE bar takes a snapshot photo<br>W,A,S,D keys move the cut-out image left, right, up and down<br>&#43; and – keys zoom the cut-out image in and out<br>UP and DOWN keys allow you to adjust the viewing angle of the Kinect Device<br>LEFT and RIGHT keys allow you to choose the backdrop picture<br>M toggles mirroring mode on and off<br>F11 toggles full screen mode on and off<br>C toggles depth cut off mode on and off. This mode changes the way Kinect cuts the image out, by cutting out based on the distance from Kinect, rather than trying to cut out individual people. When in this mode the &lt; key and the &gt; key allow you to adjust the cut off distance.</p></blockquote><p><strong>Project Information URL:</strong> <a title="http://drenton72.wordpress.com/2013/05/10/kinect-no-need-4-green-the-green-screen-without-a-green-screen/" href="http://drenton72.wordpress.com/2013/05/10/kinect-no-need-4-green-the-green-screen-without-a-green-screen/">http://drenton72.wordpress.com/2013/05/10/kinect-no-need-4-green-the-green-screen-without-a-green-screen/</a></p><p><strong>Project Download URL:</strong> <a href="http://sdrv.ms/10xlMO3">Click here to download</a> No Need 4 Green version 1</p><p><strong>Project Source URL:</strong> <a href="http://sdrv.ms/10xlUgD">Click here to download </a>No Need 4 Green version 1 with C# source code</p><p><object width="425" height="355"><param name="movie" value="http://www.youtube.com/v/wcsi567BLN4&hl=en"></param><param name="wmode" value="transparent"></param><embed src="http://www.youtube.com/v/wcsi567BLN4&hl=en" type="application/x-shockwave-flash" wmode="transparent" width="425" height="355"></embed></object></p><p><a href="http://files.channel9.msdn.com/wlwimages/f1dda9cc6de74512b7c19f0101402403/image%5B2%5D-247.png" target="_blank"><img title="image" src="http://files.channel9.msdn.com/wlwimages/f1dda9cc6de74512b7c19f0101402403/image_thumb-244.png" alt="image" width="507" height="288" border="0"></a></p><p><a href="http://files.channel9.msdn.com/wlwimages/f1dda9cc6de74512b7c19f0101402403/image%5B5%5D-150.png" target="_blank"><img title="image" src="http://files.channel9.msdn.com/wlwimages/f1dda9cc6de74512b7c19f0101402403/image_thumb%5B1%5D-159.png" alt="image" width="520" height="306" border="0"></a></p><p>Contact Information:</p><ul><li>Blog: <a href="http://drenton72.wordpress.com">http://drenton72.wordpress.com</a> </li><li>Twitter: <a href="https://twitter.com/#!/drenton72">@drenton72</a> </li></ul><p><strong>Update: </strong>Since the writing of this post David has already released a v2!</p><h2><a href="http://drenton72.wordpress.com/2013/05/12/kinect-noneed4green-v2/">Kinect NoNeed4Green&nbsp;v2</a></h2><blockquote><p>I've already made some changes to my NoNeed4Green, so here is version 2. The main addition being the facility to add foreground pictures. The foreground pictures have their own sub-folder called foreground and they use PNG files only, as you need images with transparent backgrounds for it to work. This allows you to put objects in front of the live cut-outs of people as well as having a background behind them. This lets you do things like putting someone behind the desk of the oval office or behind the desk of the BBC newsroom or on the bow of the Titanic. You can also now resize and move all 3 layers. Layer 1 is the background, layer 2 is the live cut-outs of people, while layer 3 are the foreground objects.</p><p>...</p><p>There is a few new keyboard controls as well :-</p><p>H toggles between hiding all on-screen buttons and revealing them. Keys 1,2,3 select layers 1,2 and 3 to allow you to move and resize them.</p><p>...</p></blockquote><p><strong>Project Information URL:</strong> <a href="http://drenton72.wordpress.com/2013/05/12/kinect-noneed4green-v2/">http://drenton72.wordpress.com/2013/05/12/kinect-noneed4green-v2/</a></p><p><strong>Project Download URL:</strong> <a title="NoNeed4Green v2" href="http://sdrv.ms/10xlMO3" target="_blank">Click here to download</a> No Need 4 Green version 2</p><p><strong>Project Source URL:</strong> <a title="NoNeed4Green v2" href="http://sdrv.ms/10xlMO3" target="_blank">Click here to download</a> No Need 4 Green version 2</p> <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/coding4fun/rss&WT.dl=0&WT.entryid=Entry:RSSView:dea34d2a511e4dd99adba1bb01429044">]]></description>
    <comments>http://channel9.msdn.com/coding4fun/kinect/The-Green-Screen-without-a-Green-Screen-Kinect-No-Need-4-Green</comments>
    <link>http://channel9.msdn.com/coding4fun/kinect/The-Green-Screen-without-a-Green-Screen-Kinect-No-Need-4-Green</link>
    <itunes:summary>As promised on Tuesday, here&#39;s this week&#39;s second project by David Renton, this time with him showing off (with code) how to do a &amp;quot;green screen&amp;quot; without a green screen... Kinect No Need 4 Green – The Green Screen without a Green ScreenThis little piece of software allows you to produce easily, quickly and cheaply the type of picture that you would normally need a proper green screen setup to create. The software uses a Kinect for Windows or Kinect for XBOX360 device connected to a Windows 7 or 8 pc. All you need to do is stand in front of the device and it will cut you out. You can choose between different backdrops, which you can add to by copying your own pictures (JPEG or PNG) into the PICTURES sub-folder. You can zoom in &amp;amp; out and move the cut out image using the keyboard or by on-screen controls.&amp;nbsp; You can take snapshot pictures of what is displayed in the window and these pictures are saved into the SNAPSHOTS sub-folder. The keyboard controls are as below:-SPACE bar takes a snapshot photoW,A,S,D keys move the cut-out image left, right, up and down&amp;#43; and – keys zoom the cut-out image in and outUP and DOWN keys allow you to adjust the viewing angle of the Kinect DeviceLEFT and RIGHT keys allow you to choose the backdrop pictureM toggles mirroring mode on and offF11 toggles full screen mode on and offC toggles depth cut off mode on and off. This mode changes the way Kinect cuts the image out, by cutting out based on the distance from Kinect, rather than trying to cut out individual people. When in this mode the &amp;lt; key and the &amp;gt; key allow you to adjust the cut off distance. Project Information URL: http://drenton72.wordpress.com/2013/05/10/kinect-no-need-4-green-the-green-screen-without-a-green-screen/ Project Download URL: Click here to download No Need 4 Green version 1 Project Source URL: Click here to download No Need 4 Green version 1 with C# source code    Contact Information: Blog: http://drenton72.wordpress.com Twitter: @drenton72</itunes:summary>
    <pubDate>Thu, 16 May 2013 13:00:00 GMT</pubDate>
    <guid isPermaLink="false">http://channel9.msdn.com/coding4fun/kinect/The-Green-Screen-without-a-Green-Screen-Kinect-No-Need-4-Green</guid>
    <dc:creator>Greg Duncan</dc:creator>
    <category>csharp</category>
    <category>coding4fun</category>
    <category>kinect</category>
  </item>
	<item>
    <title>NUIverse - Reach out and touch...</title>
    <description><![CDATA[<p>I don't normally blog about projects that don't have source, but this project from Dr. Dave is just cool so I'm making an exception. Plus since it has an extensibility model, I guess that makes it code'able? Kind of? Anyway, it's cool and it's fun...</p><p>What?</p><h2><a href="http://nuiverse.com/" target="_blank">NUIverse</a></h2><blockquote><p>NUIverse is an application, written to give me a sandbox for exploring “Natural User Interaction” with a large, multi-dimensional dataset. This build for the <a href="http://www.microsoft.com/en-us/pixelsense/default.aspx">Samsung SUR40 with Microsoft PixelSense</a> demonstrates multi-touch gestures, multi-user and multi-directional UI, and object-interaction with transparent Byte Tags. This site provides brief instructions for installing, using, and configuring NUIverse.</p><p>NUIverse is not intented as an accurate simulation of the solar system and surrounding universe, since it was written in my spare time and the focus was on interaction rather than accuracy. There are many existing applications available for this purpose, such as <a href="http://www.worldwidetelescope.org/">Microsoft WorldWide Telescope</a>, <a href="http://shatters.net/celestia/">Celestia</a>, <a href="http://en.spaceengine.org/">Space Engine</a> etc.</p><p>The following video shows the application demonstrated on a <a href="http://www.microsoft.com/en-us/pixelsense/default.aspx">Samsung SUR40 with Microsoft PixelSense</a> at <a href="http://www.digitalwpc.com/">WPC 2012</a>.</p><p><object width="425" height="355"><param name="movie" value="http://www.youtube.com/v/jod6rfV7tBs&hl=en"></param><param name="wmode" value="transparent"></param><embed src="http://www.youtube.com/v/jod6rfV7tBs&hl=en" type="application/x-shockwave-flash" wmode="transparent" width="425" height="355"></embed></object></p></blockquote><h2><a href="http://drdave.co.uk/blog/2013/4/2/nuiverse-for-windows">NUIverse for Windows</a></h2><blockquote><p>As <a href="http://drdave.co.uk/blog/2013/2/9/windows-multitouch-and-xna">previously</a> discussed, my manipulation processor now supports WM_TOUCH messages, which means that I can do native multitouch on both Windows 7 and Windows 8. I have therefore updated NUIverse for a Windows-release, as shown below in Figure 1.</p><p>There are some key differences to the PixelSense-release, as follows:</p><ul><li>No support for tagged objects, since it does not use the Surface 2.0 runtime, nor require PixelSense hardware (though it will run on the latter outside of the Surface Shell). </li><li>Since horizontal form-factor multitouch hardware is generally less-common than vertical form-factors, I have added a single-orientation configuration setting. This is true by default, since even if mounted horizontally, many touchscreens will not deliver the multitouch performance required for simultaneous multi-user interaction. </li><li>Since the Surface Shell added chrome to close the application and by default the application runs full-screen, either drag in a menu control (see note below) and use the exit menu, or press ESC if a keyboard is present. </li></ul><p>One of the current issues when running a full-screen desktop app on Windows 8 is that the operating system captures initial touches used for edge-swipes. If touch is maintained after an initial edge-swipe, further edge-swipes are not captured and therefore will add NUIverse controls to the screen. An alternative is to touch the screen and simultaneously edge-swipe, or to use two fingers when edge-swiping.</p><p>Several key configuration settings (in NUIverse.exe.config) are worth mentioning. Note that there is no graphical interface for these settings, and that the configuration file needs to be edited by hand (I would recommend saving a copy first):</p><ul><li>PixelWidth and PixelHeight control the resolution used for both windowed and full-screen mode. </li><li>FullScreen controls whether the application runs full-screen (true) or windowed (false). </li><li>For the configuration settings specified in mm to work correctly, set PixelsPerMm to the appropriate value, taking account physical screen size and either PixelWidth or PixelHeight (square pixels are assumed). </li></ul><p>To install NUIverse for Windows, proceed as folows:</p><ol><li>Install the <a href="http://www.microsoft.com/en-us/download/details.aspx?id=20914">XNA 4.0 runtime</a>. </li><li>Download and extract <a href="http://drdave.co.uk/downloads/nuiverse/NUIverse_Windows_0.9.4840.zip">NUIverse for Windows</a> (2.75Mb) to a suitable location. </li><li>Low-resolution textures for several planets and moons are included, but extras can be created or downloaded from <a href="http://nuiverse.com/">http://nuiverse.com</a>. </li></ol></blockquote><p>Here's a snap of the app running on my Windows 8 notebook;</p><p><img title="image" src="http://files.channel9.msdn.com/wlwimages/ae054c0b4d7b402ab1239e6800c0220f/image%5B2%5D-131.png" alt="image" width="500" height="285" border="0"></p><p>I said there was extensibility?</p><h2><a href="http://drdave.co.uk/blog/2013/1/20/extensibility-model-part-2">Extensibility Model Part 2</a></h2><blockquote><p>I <a href="http://drdave.co.uk/blog/2012/4/22/extensibility-model">previously</a> mentioned that I had implemented an extensibility model, and thought it useful to discuss an example of adding a simple model to earth orbit, as shown below in Figure 1 (further images of which are in the <a href="http://drdave.co.uk/gallery/nuiverse">gallery</a>).</p><p><img title="image" src="http://files.channel9.msdn.com/wlwimages/ae054c0b4d7b402ab1239e6800c0220f/image%5B5%5D-70.png" alt="image" width="500" height="300" border="0"></p><p>Figure 1. Model added to earth orbit. Colonial Raptor model (based on new TV series) by Coxxon.</p><p>The &quot;extra&quot; is defined as a folder containing the following items:</p><ul><li>A model in XNB format. XNA has built-in content importers for .x and .fbx (2009.1) formats. </li><li>An optional pair of textures for both diffuse and emissive textures. These are standard image files. </li><li>An XML file defining the &quot;extra&quot;, in this case as shown below in Listing 1. </li></ul><p><img title="image" src="http://files.channel9.msdn.com/wlwimages/ae054c0b4d7b402ab1239e6800c0220f/image%5B8%5D-66.png" alt="image" width="500" height="183" border="0"></p><p>This configuration file specifies that the model should be added to the planetoid &quot;earth&quot; in the &quot;solar&quot; system, both of which are defined in system.xml configuration file.</p><p>In order to scale the model correctly, a scale factor is applied to normalize the model to unit length. This can either be applied in the XML scale attribute, or specified in the XNA content processor scale attribute, in which case the XML attribute can be set to 1. A size attribute then defines the maximum length of the model in km. The <a href="http://en.battlestarwiki.org/wiki/Raptor">Colonial Raptor</a> shown in Figure 1 was defined with a size of 8.6m.</p><p>The textures are defined in sub-folders &quot;texture&quot; and &quot;emissive&quot;. If an emissive texture is not available, an all-black image (e.g. JPEG file) can be used.</p><p>The rotation period defines how long it takes for the model to rotate while orbiting the planetoid. If this is the same as the P orbital element, then the same face of the model is presented to the planetoid throughout the orbit. The remaining standard orbital elements specify that the model is in a circular equatorial orbit at an altitude of 500km (the earth has a radius of 6,371km).</p></blockquote><p>Make sure you read through the rest of his <a href="http://drdave.co.uk/blog/category/nuiverse" target="_blank">NUIverse</a>, and <a href="http://drdave.co.uk/blog" target="_blank">other</a>, articles as they are very interesting and informative... (like his <a href="http://drdave.co.uk/blog/2013/4/18/holographic-recordings" target="_blank">holographic Princes Leia recording</a> post... that's just cool!)</p> <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/coding4fun/rss&WT.dl=0&WT.entryid=Entry:RSSView:705640a5622f435fb3dba1bb01309719">]]></description>
    <comments>http://channel9.msdn.com/coding4fun/blog/NUIverse-Reach-out-and-touch</comments>
    <link>http://channel9.msdn.com/coding4fun/blog/NUIverse-Reach-out-and-touch</link>
    <itunes:summary>I don&#39;t normally blog about projects that don&#39;t have source, but this project from Dr. Dave is just cool so I&#39;m making an exception. Plus since it has an extensibility model, I guess that makes it code&#39;able? Kind of? Anyway, it&#39;s cool and it&#39;s fun... What? NUIverseNUIverse is an application, written to give me a sandbox for exploring “Natural User Interaction” with a large, multi-dimensional dataset. This build for the Samsung SUR40 with Microsoft PixelSense demonstrates multi-touch gestures, multi-user and multi-directional UI, and object-interaction with transparent Byte Tags. This site provides brief instructions for installing, using, and configuring NUIverse. NUIverse is not intented as an accurate simulation of the solar system and surrounding universe, since it was written in my spare time and the focus was on interaction rather than accuracy. There are many existing applications available for this purpose, such as Microsoft WorldWide Telescope, Celestia, Space Engine etc. The following video shows the application demonstrated on a Samsung SUR40 with Microsoft PixelSense at WPC 2012.  NUIverse for WindowsAs previously discussed, my manipulation processor now supports WM_TOUCH messages, which means that I can do native multitouch on both Windows 7 and Windows 8. I have therefore updated NUIverse for a Windows-release, as shown below in Figure 1. There are some key differences to the PixelSense-release, as follows: No support for tagged objects, since it does not use the Surface 2.0 runtime, nor require PixelSense hardware (though it will run on the latter outside of the Surface Shell). Since horizontal form-factor multitouch hardware is generally less-common than vertical form-factors, I have added a single-orientation configuration setting. This is true by default, since even if mounted horizontally, many touchscreens will not deliver the multitouch performance required for simultaneous multi-user interaction. Since the Surface Shell added chrome to close the</itunes:summary>
    <pubDate>Wed, 15 May 2013 13:00:00 GMT</pubDate>
    <guid isPermaLink="false">http://channel9.msdn.com/coding4fun/blog/NUIverse-Reach-out-and-touch</guid>
    <dc:creator>Greg Duncan</dc:creator>
    <category>coding4fun</category>
    <category>multitouch</category>
    <category>xna</category>
  </item>
	<item>
    <title>Two Kinects, Less Occlusion</title>
    <description><![CDATA[<p>Today's inspirational video comes to us via the team at <a href="http://secondstory.com" target="_blank">Second Story</a> where they show off some of the work they are doing with using two Kinects at the same time...</p><h2>Lose your Occlusion</h2><blockquote><p>Depth-sensing cameras like the Kinect give us the opportunity to mix physical environments and virtual environments, creating new immersive experiences. In this Second Story Labs experiment, we demonstrate how the use of multiple cameras helps solve problems with occlusion or “holes” the use of a single camera creates.</p><p>If you’ve ever worked with a Microsoft Kinect, you know that occlusion is no laughing matter. It’s responsible for gaping holes in people’s chests, disappearing necks, the noseless faces of zombies. Humans are full of convexities, and to a Kinect that means that we are also full of holes. We’ve dealt with this in lots of creative ways—filling in gaps with best estimates, “blurring” data, hiding holes with smoke and mirrors. But the best and perhaps most obvious solution to the dilemma of occlusion is simply to add more Kinects. A second gunman, if you will, shooting from an angle that will cover the first Kinect’s blind spot.</p><p>In this case, we are calibrating two Kinects in space about a meter apart and angled inward toward their subject. This way we can “see” our way around noses, arms, and other pesky occlusions. Then all we have to do is combine their data into a single mesh, and the rest is up to our imaginations.</p><p>At full resolution, we can actually get a pretty accurate model of a person’s face. And all of this is being rendered in real time, so that a user’s reality can be “augmented” while they interact. Here we have added three-dimensional models and rain particles to the virtual space to put the user into an imaginary landscape.</p></blockquote><p><strong>Project Information URL:</strong> <a title="http://blog.secondstory.com/2013/03/18/lose-your-occlusion-2/" href="http://blog.secondstory.com/2013/03/18/lose-your-occlusion-2/">http://blog.secondstory.com/2013/03/18/lose-your-occlusion-2/</a></p><p><object width="400" height="220"><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id=61381629&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=&amp;fullscreen=1" /><embed src="http://vimeo.com/moogaloop.swf?clip_id=61381629&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=&amp;fullscreen=1" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="400" height="220"></embed></object><p><a href="http://vimeo.com/61381629">from Vimeo</a>.</p></p><p>Contact Information:</p><ul><li>Blog: <a title="http://blog.secondstory.com/" href="http://blog.secondstory.com/">http://blog.secondstory.com/</a> </li><li>Twitter: <a href="https://twitter.com/2storypdx" target="_blank">@2storypdx</a> </li></ul> <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/coding4fun/rss&WT.dl=0&WT.entryid=Entry:RSSView:cb1e3d3b4d5941a589c5a1bb01408ecd">]]></description>
    <comments>http://channel9.msdn.com/coding4fun/kinect/Two-Kinects-Less-Occlusion</comments>
    <link>http://channel9.msdn.com/coding4fun/kinect/Two-Kinects-Less-Occlusion</link>
    <itunes:summary>Today&#39;s inspirational video comes to us via the team at Second Story where they show off some of the work they are doing with using two Kinects at the same time... Lose your OcclusionDepth-sensing cameras like the Kinect give us the opportunity to mix physical environments and virtual environments, creating new immersive experiences. In this Second Story Labs experiment, we demonstrate how the use of multiple cameras helps solve problems with occlusion or “holes” the use of a single camera creates. If you’ve ever worked with a Microsoft Kinect, you know that occlusion is no laughing matter. It’s responsible for gaping holes in people’s chests, disappearing necks, the noseless faces of zombies. Humans are full of convexities, and to a Kinect that means that we are also full of holes. We’ve dealt with this in lots of creative ways—filling in gaps with best estimates, “blurring” data, hiding holes with smoke and mirrors. But the best and perhaps most obvious solution to the dilemma of occlusion is simply to add more Kinects. A second gunman, if you will, shooting from an angle that will cover the first Kinect’s blind spot. In this case, we are calibrating two Kinects in space about a meter apart and angled inward toward their subject. This way we can “see” our way around noses, arms, and other pesky occlusions. Then all we have to do is combine their data into a single mesh, and the rest is up to our imaginations. At full resolution, we can actually get a pretty accurate model of a person’s face. And all of this is being rendered in real time, so that a user’s reality can be “augmented” while they interact. Here we have added three-dimensional models and rain particles to the virtual space to put the user into an imaginary landscape. Project Information URL: http://blog.secondstory.com/2013/03/18/lose-your-occlusion-2/ from Vimeo.  Contact Information: Blog: http://blog.secondstory.com/ Twitter: @2storypdx </itunes:summary>
    <pubDate>Wed, 15 May 2013 13:00:00 GMT</pubDate>
    <guid isPermaLink="false">http://channel9.msdn.com/coding4fun/kinect/Two-Kinects-Less-Occlusion</guid>
    <dc:creator>Greg Duncan</dc:creator>
    <category>coding4fun</category>
    <category>kinect</category>
  </item>
	<item>
    <title>Getting started with Cinder for Windows Store Apps</title>
    <description><![CDATA[<h1>What is different on Windows 8</h1><p>Legacy software written for Windows 7 and prior targeted the traditional Windows API, often referred to as Win32. They resulting apps would be a combination of an executable, assets and libraries. The Windows 8 operating system introduces a new type of application, called a Windows Store app. The new architecture is called Windows Runtime, or WinRT for short. Windows Store apps are written exclusively against this new WinRT architecture.</p><p>Windows 7 and prior only had one mode of interacting with software, launching the application's executable from the desktop or file path. Windows 8 now defaults to a Windows Runtime start screen, where Windows Store apps are presented and can be accessed through their respective Live Tiles. An application's Live Tile is registered automatically when that app is installed from the Windows Store. If a user needs to access legacy software that hasn't been migrated to the new Windows Store format, they can still get to the desktop from the Start Screen.</p><p>Windows desktops and laptops have traditionally run on Intel processors, referred to frequently as x86 or x64 machines. However, in parallel with the release of Windows 8, an optimized version of the operating system designed for mobile ARM based devices was released called Windows RT. Windows RT devices, however, will not run legacy Win32 software, nor can you develop Win32 software for content.</p><p>So unlike a Windows 8 computer, which is optimized for the Windows Store apps written against WinRT but still provides access to Win32 software from the desktop, Windows RT devices do not.</p><h2>What about the Microsoft Surface?</h2><p>There are two versions of the Microsoft Surface. The first version runs the Windows RT operating system and uses an ARM CPU. The Surface Pro, however, is an x64 device and runs Windows Pro 8. Both devices are optimized for Windows Store apps, but the Surface Pro is a fully featured computer as well, allowing you to install Visual Studio, Photoshop, or whatever else you wish. You can think of the Microsoft Surface as a light, long lasting consumer consumption device, whereas the Surface Pro is a powerful, mobile content creation device and netbook equivalent.</p><h2>What's up with Cinder and DirectX?</h2><p>Cinder is a cross platform framework for C&#43;&#43; design engineering. In order to run and Apple, Android and Windows devices prior to Windows 8, the rendering libraries leveraged OpenGL as the open source, cross platform solution.</p><p>Even though DirectX has been Microsoft's preferred rendering solution for advanced graphics programming, Windows traditionally provided both DirectX and OpenGL support from the desktop. However, Windows 8 Store applications are now exclusively DirectX based, to maximize reusability across the entire domain of Microsoft experiences including Windows Phone, Windows RT, Windows 8, and gaming. This means that Cinder apps that leverage OpenGL for their rendering will not work as Windows Store apps.</p><p>To get a Cinder project running as a Windows Store app, the Cinder project needs to leverage a DirectX render instead of the default OpenGL renderer.</p><p>Both OpenGL and DirectX have undergone significant changes over the years, with DirectX migrating away from the simpler fixed function pipeline of OpenGL early on. As hardware and software continue to advance, both libraries continue to progress in their own distinct ways. Windows 8 Store apps leverage the most recent version of DirectX 11.1, which itself has some breaking changes from DirectX 11, most notably is the loss of D3DX, a very popular helper library.</p><p>As this document targets using Cinder for Windows Store apps, we will be using DirectX 11.1. Whereas you could have a DirectX renderer for desktop based Cinder experiences, because of the history and community support behind the existing OpenGL render, it would be a difficult choice to argue. However, to create a Windows Store app, DirectX 11.1 must be used as the underlying rendering technology in the Cinder framework.</p><h2>What about Visual Studio?</h2><p>Previous versions of Cinder were written to make it easy to use for Visual Studio 2010, and targeted Win32 applications. Since Windows Store apps require targeting the WinRT architecture, this has changed.</p><p>To develop software for Window Store 8, you need to use Visual Studio 2012. We will be walking through the setup assuming you have downloaded the free version of the software, Visual Studio Express 2012.</p><p>You should know, however ,that the professional versions of Visual Studio 2012 comes with several new features for professional graphics engineering, including a robust graphics debugger, DirectX support, visual shader editors, and tools for working with virtual models and objects.</p><h1>Enough theory, lets get started</h1><p>To create Windows Store apps, you need to have Windows 8 installed and running at least Visual Studio Express 2012 for Windows 8. Do not download Visual Studio Express 2012 for Web, Phone or Desktop. We are targeting Windows 8 here.</p><h2>Setting up Visual Studio Express 2012 for Windows 8</h2><p>Once you have a copy of Windows 8 running natively or on a virtual machine from another Operating System, you can get the bytes for Visual Express 2012 for Windows here:</p><p><a href="http://www.microsoft.com/visualstudio/eng/products/visual-studio-express-products">http://www.microsoft.com/visualstudio/eng/products/visual-studio-express-products</a></p><p>&nbsp;</p><p><img src="http://files.channel9.msdn.com/thumbnail/0048ca79-f2da-492e-9a3f-95c9702684b4.jpg" alt=""></p><p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</p><p>When the installer has finished and you launch the application, you will be taken to a registration screen. If you choose not to register, Visual Studio Express 2012 will expire after 30 days. Go ahead and register the product.</p><p>&nbsp;</p><p><img src="http://files.channel9.msdn.com/thumbnail/a419c0e3-f757-42a9-9ec4-8e330bee7658.jpg" alt=""></p><p>&nbsp;</p><p>Once registration is complete, Visual Studio will launch for the first time. In order to create a Windows Store app, you need to setup a Developer license. A developer license allows you to develop, install and test apps on your computer before submitting them to the Microsoft store for publishing and deployment to the community.</p><p>At this time, it would also be a good idea to go to the menu item <em>Tools</em> &gt; <em>Extensions and Updates</em> and check for any updates to Visual Studio as well:</p><p>&nbsp;</p><p><img src="http://files.channel9.msdn.com/thumbnail/2705a27b-9cdd-4bf3-a381-49f4777946c2.jpg" alt=""></p><p>&nbsp;</p><h2>Grabbing the Git branch</h2><p>Now that we have Windows 8 and Visual Studio Express 2012 setup, our next step is getting the correct Cinder bits on our machine. Since this is still under development, we need to pull from the correct developer branch of Cinder from Cinder's GitHub account.</p><p>The professional version of Visual Studio 2012 allows for rich Git integration, but the free Express version doesn't support this, so you will need to have a standalone Git client if you choose to use the Express version of Visual Studio. If so, we recommend downloading the GitHub client, which installs both itself and helpful Git utilities.</p><p>You can download the GitHub client here:</p><p><a href="https://help.github.com/articles/set-up-git">https://help.github.com/articles/set-up-git</a></p><p>&nbsp;</p><p><img src="http://files.channel9.msdn.com/thumbnail/fe30b214-1c5d-4942-957c-2ba8f40133d9.jpg" alt=""></p><p>&nbsp;</p><p>After the GitHub client is installed, you may find it helpful to enter or setup your account. However, you should be able to pull the project if you just want to get up and running quickly using the Git Shell as explained further below.</p><p>As a community developed, open source project, Cinder separates the stable, official version of its Cinder framework from newer branches that developers setup as they program future functionality. WinRT support for Cinder is currently being developed off of one of these feature branches, with the goal of integrating in to a future iteration of the master project.</p><p>So we will need to clone the Cinder project locally, which defaults to the <strong><em>master</em></strong> branch, and then explicitly move to the <strong><em>dx_rt</em></strong> branch to get to the version under development that also includes support for Windows Store 8 projects.</p><p>To clone Cinder, either open your Git enabled Power Shell in the directory you want to use and type:</p><p>git clone <a href="https://github.com/cinder/Cinder.git">https://github.com/cinder/Cinder.git</a></p><p>&nbsp;</p><p>Or open a browser and go to the Cinder project page on GitHub.com. There you will see a<em> Clone In Windows </em>button that should launch the GitHub client automatically and start the local cloning process:</p><p><a href="https://github.com/cinder/Cinder/tree/dx_rt">https://github.com/cinder/Cinder/tree/dx_rt</a></p><p>&nbsp;</p><p>&nbsp;<img src="http://files.channel9.msdn.com/thumbnail/703d1546-6609-4d59-b020-d05a3f59b0df.jpg" alt="" width="640"></p><p>&nbsp;</p><p>This should take several minutes to download the Cinder project and open it in your GitHub client. Once it appears as a line item in your GitHub client, you can right click the repository icon and select open a shell here. We will do the rest of the commands from the Power Shell directly.</p><p>&nbsp;</p><p>If you look at your command prompt and you are still on the <strong><em>master</em></strong> branch, you can switch to the <strong><em>dx_rt</em></strong> branch by typing the following:</p><p>git checkout dx_rt</p><p>Or if you prefer to use the GitHub client you installed, you can switch from the master branch to the <strong><em>dx_rt</em></strong> branch from there as well.</p><p><img src="http://files.channel9.msdn.com/thumbnail/d65f1cfb-3968-485f-8d09-51dc76caff6e.jpg" alt="" width="640">&nbsp;</p><p>If you are using the GitHub client, though, it would probably be a good idea to switch to a command shell for the next steps. You can do that from the client directly by right clicking on project's list item like so:</p><p>&nbsp;</p><p><img src="http://files.channel9.msdn.com/thumbnail/460dcc05-2888-40e0-aae2-a1cea99d9239.jpg" alt="" width="640"></p><p>&nbsp;</p><p>The <strong><em>master</em></strong>, <strong><em>dev </em></strong>and <strong><em>dx_rt </em></strong>branches all require you to also install certain Boost libraries to the Cinder project directory before you can compile the Cinder framework. However, on the <strong><em>dx_rt</em></strong> branch we will be using, this process has been greatly automated for you. So once you've switched to the <strong><em>dx_rt </em></strong>branch, type in the following two commands to download the required Boost libraries that are compatible with this particular branch of Cinder for Windows Store:</p><p>git submodule init</p><p>git submodule update</p><p>This may take a few minutes, but once it is done you should be ready to open the Cinder project and compile it for use.</p><p>&nbsp;</p><h2>Compiling Cinder for Windows Store apps</h2><p>Once you have pulled the Cinder project from its GitHub repository, switched to the <strong><em>dx_rt</em></strong> branch that contains the bits for working on Windows Store apps, and run the submodules that download the additional Boost dependencies, you are ready to open up the Cinder solution to compile the library.</p><p>&nbsp;</p><p><img src="http://files.channel9.msdn.com/thumbnail/a66457b6-468f-4bf1-9519-a4529c3c7879.jpg" alt="" width="652">&nbsp;&nbsp;</p><p>&nbsp;</p><p>Go to where GitHub cloned the Cinder project, the default is <em>Libraries\Documents\GitHub\Cinder</em>. There you will find multiple version of the Cinder framework separated by development environment. You should see the xcode and vc10 solutions, but you will also three additional folders. Vc11 provides support for compiling Cinder for Visual Studio 2012, but still using OpenGL and thus limited to Desktop mode. VC11-DirectX is provides support for compiling Cinder for Visual Studio 2012 using DirectX 11 but also for Desktop mode. We will be focusing on the third option, the winrt folder. This is the solution that supports Windows Store apps and development.</p><p>Launch <em>Cinder/winrt/cinder.sln</em> and the Cinder project should open up in Visual Studio 2012 automatically. If you are using the professional version of Visual Studio 2012, you can Batch Build all the versions you need. Since we are using the Express edition in this walkthrough, though, we will Build individually the debug and release versions of the Cinder library we need.</p><p>We will build the debug version of the framework by making sure that our Solution Configuration in the toolbar is set to <em>Debug</em> and the Solution Platform is set to <em>Win32</em>.</p><p>&nbsp;</p><p><img src="http://files.channel9.msdn.com/thumbnail/82fa3597-f0e6-49d9-848e-de9aff315ceb.jpg" alt=""></p><p>&nbsp;</p><p>To build the solution, simply go to the Build menu option and select Build Solution.</p><p><img src="http://files.channel9.msdn.com/thumbnail/c52db37b-b8d4-4e16-bcfb-9c829b7f1f31.jpg" alt="">&nbsp;</p><p>&nbsp;</p><p>Some warnings may pop up, but there should be no errors. Once that is done, you will find a new file in the Cinder project directory under:</p><p><em>..\Cinder\lib\winrt\Win32\Debug\cinder.lib</em></p><p>This is the Cinder library your Windows Store projects will link to when you are programming and debugging your application. Now we need to rebuild this framework to provide a release version of this same framework. Going back to the Cinder project, and on the toolbar change the Solution Configuration option from Debug to Release and Build the solution again.</p><p>You now have a Debug and Release version of the Cinder framework and are ready to start creating Windows Store programs against it for any Windows 8 device, including the Surface Pro. However, any WindowsRT device, such as the non-Pro version of Surface, will be running on ARM and so you would need to follow the above steps targeting the ARM platform instead of just the Win32 platform.</p><h2>Testing out the Library</h2><p>At this point, you are ready to explore the collection of DirectX samples created specifically for Windows Store apps. You can find various projects for Windows Store in the DirectX folder inside the samples folder. For our initial test, we will open the following sample:</p><p><em>..\Cinder\samples\DirectX\_winrtBasic\winrt\winrtBasic.sln</em></p><p>When you open the solution in Visual Studio Express 2012, you will find basicApp.cpp in the Solution Explorer. This contains all the code we need to start using the Cinder framework.</p><p>&nbsp;</p><p><img src="http://files.channel9.msdn.com/thumbnail/504bbec1-6d8f-487c-b5fb-1199864a8535.jpg" alt=""></p><p>&nbsp;</p><p>The code in this sample illustrates a few basic tasks, including loading an image from the assets folder and using it as a texture, loading fonts and displaying them on the screen, handling mouse events, drawing various geometries and implementing a basic follower easing algorithm in the update() call.</p><p>Once you're looked over the code, you can press <strong>F5</strong> or the Play button on the main toolbar to run the program on the machine. If you compiled both the <strong><em>Debug</em></strong> and <strong><em>Release</em></strong> versions of the framework, you can select either Solution Configuration. <strong>You will find a significant increase in speed in <em>Release</em> mode over <em>Debug</em> mode</strong>.</p><p>&nbsp;</p><p><img src="http://files.channel9.msdn.com/thumbnail/65935f93-a608-4311-b598-782a209d4021.jpg" alt=""></p><p>&nbsp;</p><p>You will also notice that the program has automatically installed its own Live Tile on your Start Screen, which you can use to launch the program again whenever you wish.</p><p>&nbsp;</p><p><img src="http://files.channel9.msdn.com/thumbnail/73de0647-b976-43ac-bcba-e3db94dfa117.jpg" alt=""></p><p>&nbsp;</p><p>&nbsp;Congratulations! You should now be ready to start exploring Cinder for Windows Store apps.</p><p>&nbsp;</p><p>@rickbarraza</p><p>&nbsp;</p><p>You can learn more about this branch by going to the Cinder forums found here:</p><p><a href="https://forum.libcinder.org/#Topic/23286000001540037">https://forum.libcinder.org/#Topic/23286000001540037</a></p><p>&nbsp;</p><p>&nbsp;</p> <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/coding4fun/rss&WT.dl=0&WT.entryid=Entry:RSSView:27305f8a61ab4b7e8809a1be01440cfe">]]></description>
    <comments>http://channel9.msdn.com/coding4fun/articles/Getting-started-with-Cinder-for-Windows-Store-Apps</comments>
    <link>http://channel9.msdn.com/coding4fun/articles/Getting-started-with-Cinder-for-Windows-Store-Apps</link>
    <itunes:summary>What is different on Windows 8Legacy software written for Windows 7 and prior targeted the traditional Windows API, often referred to as Win32. They resulting apps would be a combination of an executable, assets and libraries. The Windows 8 operating system introduces a new type of application, called a Windows Store app. The new architecture is called Windows Runtime, or WinRT for short. Windows Store apps are written exclusively against this new WinRT architecture. Windows 7 and prior only had one mode of interacting with software, launching the application&#39;s executable from the desktop or file path. Windows 8 now defaults to a Windows Runtime start screen, where Windows Store apps are presented and can be accessed through their respective Live Tiles. An application&#39;s Live Tile is registered automatically when that app is installed from the Windows Store. If a user needs to access legacy software that hasn&#39;t been migrated to the new Windows Store format, they can still get to the desktop from the Start Screen. Windows desktops and laptops have traditionally run on Intel processors, referred to frequently as x86 or x64 machines. However, in parallel with the release of Windows 8, an optimized version of the operating system designed for mobile ARM based devices was released called Windows RT. Windows RT devices, however, will not run legacy Win32 software, nor can you develop Win32 software for content. So unlike a Windows 8 computer, which is optimized for the Windows Store apps written against WinRT but still provides access to Win32 software from the desktop, Windows RT devices do not. What about the Microsoft Surface?There are two versions of the Microsoft Surface. The first version runs the Windows RT operating system and uses an ARM CPU. The Surface Pro, however, is an x64 device and runs Windows Pro 8. Both devices are optimized for Windows Store apps, but the Surface Pro is a fully featured computer as well, allowing you to install Visual Studio, Photoshop,</itunes:summary>
    <pubDate>Tue, 14 May 2013 22:20:52 GMT</pubDate>
    <guid isPermaLink="false">http://channel9.msdn.com/coding4fun/articles/Getting-started-with-Cinder-for-Windows-Store-Apps</guid>
    <dc:creator>Rick Barraza</dc:creator>
  </item>
	<item>
    <title>MissionControl - A Flexible API for Remote Device Control</title>
    <description><![CDATA[<p>In a race to optimize everything, developers often go to extremes to build software that performs routine tasks. MissionControl is a system that allows users to program a control center that stores interfaces with attached hardware sensors, allowing the users to control any other devices that can be activated via the underlying protocol. For demo purposes, the MissionControl build at this point is compatible with the Phidgets IR hybrid sensor.</p><p>The system has two core components:</p><ul><li>A server application, which is a Win32 console application that handles incoming queries and returns data to the connected clients. This application runs on the desktop machine with the connected sensor. </li><li>The Windows Phone application that sends requests to the target server and can trigger a variety of pre-programmed commands. </li></ul><h1>The Basics</h1><h3>Hardware and Communication Infrastructure</h3><p>One of the most important parts of the project is the signal capture and replication hardware. For the purposes of this project, I decided to use a dual-mode <a href="http://www.phidgets.com/products.php?product_id=1055_0">Phidgets IR sensor</a>. It supports both IR code capture and subsequent replication. From a user’s perspective, this device also eliminates a substantial code-learning overhead as well as the potential error rate. Instead of searching for a device-specific hexadecimal sequence that later has to be transformed in a working IR code, the user simply has to point his remote control at the sensor and press the button that he wants accessible from a mobile device. Given that the capturing software is running on the target machine, once the sensor detects that a code can be repeated within an acceptable precision range, it will be automatically captured and stored, with all required transformations worked out in the backend using the free Phidgets SDK.</p><h3><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image0026.jpg"><img title="clip_image002" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image002_thumb3.jpg" alt="clip_image002" width="368" height="246" border="0"></a></h3><p>Even though I can, I don’t have to handle the binary code content received through the sensor—the Phidgets .NET libraries carry built-in types that contain all the processed metadata that I will discuss later in this article.</p><p>This sensor is connected through a USB port to a machine that acts as a communication gateway. This server should have port 6169 open for inbound connections.</p><p><strong>NOTE:</strong> <em>The port number can be changed, but you have to keep it consistent between your server and client applications.</em></p><p>The communication between the phone and the computer running the client is performed via a TCP channel—<a href="http://en.wikipedia.org/wiki/Internet_socket">sockets</a> are used to perform the initial connections and serialized data transfer. You can see the generalized data flow between the devices that are involved in the procedure in the graphic below:</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image0046.jpg"><img title="clip_image004" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image004_thumb3.jpg" alt="clip_image004" width="520" height="289" border="0"></a></p><p>The server (desktop client) handles the local storage and release of all incoming IR codes. The mobile client has to know the location of the server—once specified and confirmed, it can send one of the pre-defined commands to it and either query the server for existing command groups (sets) or invoke one of the stored IR codes. When I pass data between devices, I use JSON for the serializable components. The data is also processed before being sent in order to speed-up the process—for example, on the server side the sets are serialized together with the associated codes. Like this:</p><p><pre class="brush: js">
[
{
    &quot;Name&quot;:&quot;batman&quot;,
    &quot;IsList&quot;:false,
    &quot;Commands&quot;:[
    {
        &quot;Name&quot;:&quot;test command&quot;,
        &quot;Code&quot;:{
            &quot;Mask&quot;:{
                &quot;BitSize&quot;:12,
                &quot;CodeData&quot;:&quot;AAA=&quot;
            },
            &quot;BitSize&quot;:12,
            &quot;Encoding&quot;:2,
            &quot;CarrierFrequency&quot;:38000,
            &quot;DutyCycle&quot;:50,
            &quot;Gap&quot;:44761,
            &quot;Header&quot;:[
            2374,
            606
            ],
            &quot;CodeData&quot;:&quot;DJA=&quot;,
            &quot;MinRepeat&quot;:5,
            &quot;One&quot;:[
            1189,
            606
            ],
            &quot;Repeat&quot;:null,
            &quot;Trail&quot;:0,
            &quot;Zero&quot;:[
            582,
            606
            ]
        }
    },
    {
        &quot;Name&quot;:&quot;turn off&quot;,
        &quot;Code&quot;:{
            &quot;Mask&quot;:{
                &quot;BitSize&quot;:12,
                &quot;CodeData&quot;:&quot;AAA=&quot;
            },
            &quot;BitSize&quot;:12,
            &quot;Encoding&quot;:2,
            &quot;CarrierFrequency&quot;:38000,
            &quot;DutyCycle&quot;:50,
            &quot;Gap&quot;:44770,
            &quot;Header&quot;:[
            2360,
            613
            ],
            &quot;CodeData&quot;:&quot;DJA=&quot;,
            &quot;MinRepeat&quot;:5,
            &quot;One&quot;:[
            1169,
            613
            ],
            &quot;Repeat&quot;:null,
            &quot;Trail&quot;:0,
            &quot;Zero&quot;:[
            585,
            613
            ]
        }
    }
    ]
}
]
</pre></p><p>The inherent problem with the JSON data above is the fact that the phone client does not need the information related to the code binary sequence and all the metadata that goes with it. So it is effectively stripped down and reduced to the names of the sets (when a list of sets is requested) and commands (when a list of commands is requested).</p><h3>The Data Model</h3><p>As you saw from the description above, the server organizes individual infrared codes in sets. A single set is a bundle of codes that may or may not be related to each other—ultimately, this is the user’s decision. A good example of using sets is organizing IR commands by rooms, devices or code types. Each set has a unique name on the server, therefore eliminating the possibility of a request conflict.</p><p>Each set stores individual commands built around the <strong>Command</strong> model:</p><p><pre class="brush: csharp">
namespace Coding4Fun.MissionControl.API.Models 
{ 
    public class Command 
    { 
        public Command() 
        { 
        } 
    
    public string Name { get; set; }     
    public SerializableIRCode Code { get; set; } 
    } 
}
</pre></p><p>Despite the obvious <strong>Name</strong> property, you can see that I am using a <strong>SerializableIRCode</strong> instance that is specific to each model. Before going any further, I need to mention that the Phidgets SDK offers the <strong>IRLearnedCode</strong> model to store code contents. I could have used it instead, but there is an issue that prevents me from doing that—there is no public constructor defined for <strong>IRLearnedCode</strong>, therefore there is no way to serialize it, either with the built-in .NET serialization capabilities or JSON.NET, which I am using in the context of the project.</p><p>Instead, I have this:</p><p><pre class="brush: csharp">
using Phidgets; 
namespace Coding4Fun.MissionControl.API.Models 
{     
    public class SerializableIRCode     
    {         
        public SerializableIRCode()         
        { 
            
        } 
        
    IRLearnedCode code;         
    public ToggleMask Mask { get; set; } 
    public int BitSize { get; set; } 
    public Phidgets.IRCodeInfo.IREncoding Encoding { get; set; } 
    public int CarrierFrequency { get; set; } 
    public int DutyCycle { get; set; } 
    public int Gap { get; set; } 
    public int[] Header { get; set; } 
    public byte[] CodeData { get; set; } 
    public int MinRepeat { get; set; } 
    public int[] One { get; set; } 
    public int[] Repeat { get; set; } 
    public int Trail { get; set; } 
    public int[] Zero { get; set; } 
    }     
}
</pre></p><p>It is an almost identical 1:1 copy of the original class, storing both the layout of the IR code and additional information related to its replication mechanism. You can learn more about each property listed in the model above by reading the <a href="http://www.phidgets.com/docs/IR_Remote_Control_Primer">official document on the topic</a>.</p><p><strong>ToggleMask</strong>, the identity bit carrier that helps marking the code as repeated or not, is also implemented through a built-in Phidgets SDK model, and it has the same problem as <strong>IRLearnedCode</strong>. I implemented this model to replace it in the serializable code:</p><p><pre class="brush: csharp">
namespace Coding4Fun.MissionControl.API.Models 
{ 
    public class ToggleMask 
    { 
        public ToggleMask() 
        { 
            
        } 

    public int BitSize { get; set; }         
    public byte[] CodeData { get; set; } 
    } 
}
</pre></p><p>I also needed an easy way to store all sets at once and carry all associated codes in a single instance retrieved from the storage. Here is the <strong>Set</strong> class:</p><p><pre class="brush: csharp">
namespace Coding4Fun.MissionControl.API.Models 
{     
    public class Set 
    { 
        public Set() 
        { 
            Commands = new List&lt;Command&gt;(); 
        } 
        
    public string Name { get; set; } 
    public bool IsList { get; set; } 
    public List&lt;Command&gt; Commands { get; set; } 
    } 
}
</pre></p><p>Notice that there is an <strong>IsList</strong> flag that allows me to specify how to display this specific list on the connecting device. This adds some level of flexibility for situations where the user wants to build a virtual remote for closely-related keys, such as digits. With that in mind, displaying those as a list might be inconvenient, wasting visual space on the client. But if the flag is set to false, the list can be displayed as a pad.</p><p>Also, when the server performs the data exchange, it provides a single “envelope” that allows the connecting device to easily understand what the server is trying to do:</p><p><pre class="brush: csharp">
namespace Coding4Fun.MissionControl.API.Models 
{     
    public class ServerResponse     
    {     
    public string Identifier { get; set; }     
    public string Marker { get; set; }     
    public string Content { get; set; }     
    } 
}
</pre></p><p>The <strong>Identifier</strong> property carries the server IP address. That way, when a device receives a response, it is able to either accept it, because it knows that a response is requested from a target location, or discard it because the user is no longer using the specific server.</p><p><strong>Marker</strong> carries the command type of the sent command, therefore giving the Windows Phone application a hint as to what to do with the data. The server can send the following commands:</p><ul><li><em>SET_LIST</em> – returns the list of sets that are currently available on the server. </li><li><em>SET_COMMANDS<strong>:</strong>SET_NAME<strong>:</strong>IS_LIST</em> – returns the list of commands that are associated with a given set that is currently stored on the server. </li><li><em>NOTIFICATION</em> – send a simple notification to the client; no further action is required. </li></ul><p>Last but not least, <strong>Content</strong> is used to push the necessary data that is associated with the given <strong>Marker</strong>. It can be either a JSON-based string that lists the sets or commands, or a plain-text message that is used as an alert for the end-user.</p><h1>Server Architecture</h1><p>The server is the only component of this entire system that does all the heavy lifting. It learns commands, stores them and then generates new IR signal requests, as controlled from any of the connected clients. Let’s take a closer look at what happens behind the scenes—to start, I am going to document the network infrastructure.</p><h3>The Network Layer</h3><p>In order to be a reliable system, the server needs to be always ready to accept an incoming connection. For that purpose, it is possible to use the <a href="http://msdn.microsoft.com/en-us/library/system.net.sockets.tcplistener.aspx">TcpListener</a> class—an “always on” receiver that can handle incoming TCP connections. I integrated it in my <strong>CoreStarter</strong> class that is used to start the listener when the application is launched:</p><p><pre class="brush: csharp">
namespace Coding4Fun.MissionControl.API 
{ 
    public class CoreStarter 
    { 
        static TcpListener listener; 
        
        public static void LaunchSocket()     
        {     
            Console.WriteLine(&quot;Starting socket server on port {0}...&quot;, Constants.DEFAULT_PORT); 
            listener = new TcpListener(NetworkHelper.GetLocalIPAddress(), Constants.DEFAULT_PORT); 
            listener.Start(); 
            
            for (int i = 0; i &lt; Constants.MAX_CONCURRENT_CLIENTS; i&#43;&#43;) 
            {     
                Thread socketThread = new Thread(new ThreadStart(ListenForData));     
                socketThread.Start(); 
            } 
        } 
        
        private static void ListenForData() 
        { 
            Console.WriteLine(&quot;Listener thread started.&quot;); 

            while (true) 
            { 
                Socket acceptedSocket = listener.AcceptSocket(); 
                using (MemoryStream coreStream = new MemoryStream()) 
                {     
                    try 
                    { 
                        Console.WriteLine(&quot;Incoming connection: {0}&quot;, acceptedSocket.RemoteEndPoint); 
                        
                        using (Stream sourceStream = new NetworkStream(acceptedSocket)) 
                        {     
                            sourceStream.ReadTimeout = Constants.SOCKET_READ_TIMEOUT; 
                            
                            byte[] buffer = new byte[Constants.DEFAULT_BUFFER_SIZE]; 
                            int i; 
                
                            while ((i = sourceStream.Read(buffer, 0, buffer.Length)) != 0) 
                            { 
                                coreStream.Write(buffer, 0, i); 
                            } 
                        } 
                    } 
                    catch 
                    { 
                        string data = Encoding.ASCII.GetString(coreStream.ToArray()); 
        
                        CommandHelper.InterpretCommand(data, acceptedSocket.RemoteEndPoint.ToString()); 
                    } 
                } 
            } 
        } 
    } 
}
</pre></p><p>When <strong>LaunchSocket</strong> is called, the listener is activated on the current machine. As I mentioned above, the port number can be arbitrarily assigned, but has to be consistent between connecting apps in order for the TCP links to be established. Because I expect that more than one device will be connecting to the service at a time, the listener is set as active across a constant number of threads.</p><p><strong>NOTE:</strong> By default, a there is a maximum limit of 5 simultaneous clients. Although this number can be adjusted, be aware of the requirements of each environment in which a limited number of potential devices can connect. Even though the performance footprint of each thread is minimal, it can have a negative effect if used in unnecessarily large instances.</p><p><strong>ListenForData</strong> is used to read the incoming stream. When an inbound connection is accepted, the data is read with the help of a fixed content buffer. Then a read timeout is specified to prevent situations where the stream was completely read but the application still waits to pull non-existent data. Once the timeout milestone is hit, an exception is thrown, which marks the end of the stream—at this point, the plain text data that was received (remember that both the server and client exchange text data only) is passed to the command interpreter—<strong>CommandHelper</strong>, with a reference to the source of the command.</p><p>The commands from the device are passed as serialized key-value pairs (<a href="http://msdn.microsoft.com/en-us/library/5tbh8a42.aspx">KeyValuePair&lt;T, T&gt;</a>), the key being the command with any possible suffixes, and the value being the contents of the command itself that helps the server identify the specific item in the local storage.</p><p><strong>InterpretCommand</strong>,in this case, does three things sequentially:</p><ol><li>Deserialize the incoming string and create a <strong>KeyValuePair&lt;string,string&gt;</strong> instance. </li><li>Process the command and check whether it is recognizable. </li><li>Send a response to the client, if deemed necessary by the command type. </li></ol><p>The serialization and deserialization is done via <a href="http://james.newtonking.com/projects/json-net.aspx">JSON.NET</a>. You can install this package in your console managed Win32 project and the Windows Phone application project via NuGet:</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image0056.gif"><img title="clip_image005" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image005_thumb3.gif" alt="clip_image005" width="553" height="65" border="0"></a></p><p>The deserialization step is as simple as one line of C# code:</p><p><pre class="brush: csharp">
KeyValuePair&lt;string, string&gt; result = JsonConvert.DeserializeObject&lt;KeyValuePair&lt;string, string&gt;&gt;(rawCommand.Remove(0, rawCommand.IndexOf('{')));
</pre></p><p>The string is sanitized to ensure that only JSON content is being passed to the serializer.</p><p>Because of a relatively limited command set, I can put together the entire interpretation stack like this:</p><p><pre class="brush: csharp">
// Get the initial list of sets on the target server
if (result.Key == Constants.COMMAND_INIT)
{
    SendSets(sourceLocation);
}
// Create a new set on the target server
else if (result.Key.Contains(Constants.COMMAND_CREATE_SET))
{
    CreateSet(result, sourceLocation);
    SendSets(sourceLocation);
}
// Get the commands that are associated with a given set.
else if (result.Key == Constants.COMMAND_GET_COMMANDS)
{
    SendCommands(result.Value, sourceLocation);
}
// The client requested the server to learn a new command.
else if (result.Key.Contains(Constants.COMMAND_LEARN_COMMAND))
{
    LearnCommand(result, sourceLocation);
}
// The client requested one of the commands to be executed on the 
// target server.
else if (result.Key.Contains(Constants.COMMAND_EXECUTE))
{
    ExecuteCommand(result);
}
// The client has requested a set to be deleted from the target server.
else if (result.Key == Constants.COMMAND_DELETE_SET)
{
    DeleteSet(result.Value);
    SendSets(sourceLocation);
}
// The client has requested a set to be deleted from the target server.
else if (result.Key.Contains(Constants.COMMAND_DELETE_COMMAND))
{
    DeleteCommand(result);
    SendCommands(result.Key.Split(new char[] { ':' })[1], sourceLocation);
}
</pre></p><p>All commands are constants, declared in the local helper class:</p><p><pre class="brush: csharp">
public const string COMMAND_INIT = &quot;INIT&quot;; 

public const string COMMAND_CREATE_SET = &quot;CREATE_SET&quot;; 

public const string COMMAND_GET_COMMANDS = &quot;GET_COMMANDS&quot;; 

public const string COMMAND_LEARN_COMMAND = &quot;LEARN_COMMAND&quot;; 

public const string COMMAND_EXECUTE = &quot;EXECUTE&quot;; 

public const string COMMAND_DELETE_SET = &quot;DELETE_SET&quot;;
public const string COMMAND_DELETE_COMMAND = &quot;DELETE_COMMAND&quot;;
</pre></p><p>Notice that these are not the commands that the server sends back, but rather the commands it receives from connecting Windows Phone devices.</p><p>Let’s now take a look at the breakdown for each command.</p><p><strong>SendSets:</strong></p><p><pre class="brush: csharp">
/// &lt;summary&gt; 
/// Send the list of sets to the client that requested those. 
/// &lt;/summary&gt; 
/// &lt;param name=&quot;sourceLocation&quot;&gt;The location of the requesting client.&lt;/param&gt; 
private static void SendSets(string sourceLocation) 
{ 
    Console.WriteLine(&quot;Received an initial set query from {0}&quot;, sourceLocation);     
    ServerResponse response = new ServerResponse(); 
    response.Marker = &quot;SET_LIST&quot;; 
    response.Content = JsonConvert.SerializeObject(StorageHelper.GetRawSetNames()); 
    response.Identifier = NetworkHelper.GetLocalIPAddress().ToString(); 
    NetworkHelper.SendData(sourceLocation, JsonConvert.SerializeObject(response)); 
    Console.WriteLine(&quot;Sent the set list to {0}&quot;, sourceLocation);     
}
</pre></p><p>When this command is received, the server does not have to do much processing. It is only invoked when the client establishes the initiating link and needs to know what possible sets it can get from the target machine. The request is logged in the console and a server response is prepared that contains a serialized list of set names, which is later serialized as well and sent back to the source machine location.</p><p><strong>StorageHelper</strong> and <strong>NetworkHelper</strong> will be documented later in this article.</p><p><strong>CreateSet:</strong></p><p><pre class="brush: csharp">
/// &lt;summary&gt; 
/// Create a new set and store it on the local server. 
/// &lt;/summary&gt; 
/// &lt;param name=&quot;result&quot;&gt;The original deserialized command.&lt;/param&gt; 
/// &lt;param name=&quot;sourceLocation&quot;&gt;The location of the requesting client.&lt;/param&gt; 
private static void CreateSet(KeyValuePair&lt;string,string&gt; result, string sourceLocation) 
{ 
    bool isSuccessful = false; 
    string[] data = result.Key.Split(new char[] { ':' }); 
    
    Console.WriteLine(&quot;There is an attempt to create the {0} set from {1}.&quot;, result.Value, sourceLocation); 
    
    if (data[1].ToLower() == &quot;list&quot;) 
        isSuccessful = StorageHelper.AddSet(result.Value); 
    else 
        isSuccessful = StorageHelper.AddSet(result.Value, false); 
    
    if (isSuccessful) 
        Console.WriteLine(&quot;The {0} set was successfully created.&quot;, result.Value); 
    else 
        Console.WriteLine(&quot;Something happened and the {0} set was not created.&quot;, result.Value);     
}
</pre></p><p>When a mobile device attempts to create a new set on the server, it sends a command in the following format:</p><p><strong>CREATE_SET</strong>:<strong>list/pad</strong>, <strong>SET_NAME</strong></p><p>CreateSet will get the type of the set that was created, will check whether a set with the same name already exists and will either create it or ignore the command altogether. No notification is sent to the connecting device, but either the failure or the success of the command is registered in the local console.</p><p><strong>SendCommands:</strong></p><p><pre class="brush: csharp">
/// &lt;summary&gt;
/// Send a list of commands that are associated with the pushed set.
/// &lt;/summary&gt;
/// &lt;param name=&quot;setName&quot;&gt;The original deserialized command.&lt;/param&gt;
/// &lt;param name=&quot;sourceLocation&quot;&gt;The location of the requesting client.&lt;/param&gt;
private static void SendCommands(string setName, string sourceLocation)
{
    Console.WriteLine(&quot;There was a request to get the commands for the {0} set from {1}.&quot;, setName, sourceLocation);
    
    bool isList = StorageHelper.IsSetAList(setName);
    
    ServerResponse response = new ServerResponse();
    response.Marker = string.Format(&quot;SET_COMMANDS:{0}:{1}&quot;, setName, isList);
    response.Identifier = NetworkHelper.GetLocalIPAddress().ToString();
    response.Content = JsonConvert.SerializeObject(StorageHelper.GetRawCommandNames(setName));
    
    NetworkHelper.SendData(sourceLocation, JsonConvert.SerializeObject(response));
    
    Console.WriteLine(&quot;Command list for the {0} set were sent to {1}.&quot;, setName, sourceLocation);
}
</pre></p><p>Commands are sent in the same manner as sets—once the set is recognized, the names of the associated commands are retrieved and serialized inside a <strong>ServerResponse</strong> instance and then pushed back to the requesting device.</p><p><strong>LearnCommand:</strong></p><p><pre class="brush: csharp">
/// &lt;summary&gt; 
/// Learn a new command and store it on the target server. 
/// &lt;/summary&gt; 
/// &lt;param name=&quot;result&quot;&gt;The original deserialized command.&lt;/param&gt; 
/// &lt;param name=&quot;sourceLocation&quot;&gt;The location of the requesting client.&lt;/param&gt; 
private static void LearnCommand(KeyValuePair&lt;string,string&gt; result, string sourceLocation) 
{     
    Console.WriteLine(&quot;[!] Server in COMMAND LEARNING MODE! Point the remote towards the sensor and send a command.&quot;); 
    
    string[] data = result.Key.Split(new char[] { ':' });     
    var set = StorageHelper.GetSingleSet(StorageHelper.GetSets(), data[1]); 
    
    if (set != null)     
    {     
        if ((from c in set.Commands where c.Name == result.Value select c).FirstOrDefault() != null) 
        {     
            Console.WriteLine(&quot;Cannot learn command {0} for the following set: {1}. Command already exists.&quot;, data[1], result.Value); 
            
            ServerResponse response = new ServerResponse();     
            response.Marker = &quot;NOTIFICATION&quot;;     
            response.Identifier = NetworkHelper.GetLocalIPAddress().ToString(); 
            response.Content = &quot;We could not save the following command - &quot; &#43; result.Value &#43; &quot;. It already exists in the set.&quot;; 
            
            NetworkHelper.SendData(sourceLocation, JsonConvert.SerializeObject(response));     
        } 
        else 
        { 
            if (sensor == null) 
                sensor = new IR(); 
            
            sensor.open(-1); 

            sensor.waitForAttachment(); 
    
            sensor.Learn &#43;= (sender, args) =&gt; 
            { 
                Console.WriteLine(&quot;[!] Server learned the command and is no longer in COMMAND LEARNING MODE.&quot;); 
                IRLearnedCode code = args.LearnedCode; 
                code.CodeInfo.MinRepeat = 5; 
            
                Command command = new Command(); 
                command.Name = result.Value; 
                command.Code = IRCodeWorker.GetSerializableIRCode(code); 
                
                StorageHelper.AddCommand(command, set.Name); 
                
                ServerResponse response = new ServerResponse(); 
                response.Marker = &quot;NOTIFICATION&quot;; 
                response.Identifier = NetworkHelper.GetLocalIPAddress().ToString(); 
                response.Content = &quot;The following command has been stored: &quot; &#43; result.Value; 
                
                NetworkHelper.SendData(sourceLocation, JsonConvert.SerializeObject(response)); 
            }; 
        } 
    } 
}
</pre></p><p>Once a request was received that the server needs to learn a new command, an initial verification is done to make sure that the requested command name and set are not already taken. If neither the command nor the set exist, both will be created.</p><p>After the basic setup is complete, the IR sensor is activated and will be waiting for the command to be learned. The way it works is quite simple – the sensor will remain in learning mode until the point where it recognizes a command without error, being 100% sure that it can be reproduced internally. You will need to point your remote towards the sensor and hold the button you want captured for one or two seconds in order for the command to be learned.</p><p><strong>NOTE:</strong> To ensure that a proper transmission is done, I manually set the minimal repeat value to 5. This is the number of times the sensor will fire the same code towards the target. That is the optimal value for a target device to receive the code if the remote is pointed directly at it without necessarily triggering the same command twice or more.</p><p>After the command is learned, the code is processed and transformed into a serializable instance. The connecting client is then notified about whether the command was learned.</p><p><strong>ExecuteCommand:</strong></p><p><pre class="brush: csharp">
/// &lt;summary&gt; 
/// Execute one of the commands currently stored on the local server. 
/// &lt;/summary&gt; 
/// &lt;param name=&quot;result&quot;&gt;The original deserialized command.&lt;/param&gt; 
private static void ExecuteCommand(KeyValuePair&lt;string,string&gt; result) 
{ 
    string[] data = result.Key.Split(new char[] { ':' }); 

    var set = StorageHelper.GetSingleSet(StorageHelper.GetSets(), data[1]); 
    
    if (set != null) 
    {     
        var command = StorageHelper.GetSingleCommand(StorageHelper.GetCommands(set.Name), result.Value); 

        IRLearnedCode code = IRCodeWorker.GetLearnedCode(command.Code); 
        
        if (sensor == null) 
            sensor = new IR(); 

        sensor.open(-1); 
        sensor.waitForAttachment(); 
        sensor.transmit(code.Code, code.CodeInfo); 
        sensor.close(); 
    } 
}
</pre></p><p>Command execution relies on the hardware sensor. The phone sends a command execution request in the following format:</p><p><strong>EXECUTE</strong>:<strong>SET_NAME</strong>, <strong>COMMAND_NAME</strong></p><p>Once the command is parsed out and found in the local storage, the IR code is transformed back to a model that is recognizable by the Phidgets SDK and transmitted towards the location where the sensor is pointed at the time of the execution.</p><p><strong>DeleteSet:</strong></p><p><pre class="brush: csharp">
/// &lt;summary&gt; 
/// Delete a single set and all the associated commands 
/// &lt;/summary&gt; 
/// &lt;param name=&quot;target&quot;&gt;The name of the set.&lt;/param&gt; 
private static void DeleteSet(string target) 
{ 
    var sets = StorageHelper.GetSets(); 
    var targetSet = StorageHelper.GetSingleSet(sets, target); 
    
    if (targetSet != null) 
    { 
        StorageHelper.RemoveSet(sets, targetSet); 
    } 
}
</pre></p><p>When deleting a set, only the name of the set should be specified. The user will get a warning on the client side that requires a confirmation of the deletion. The server will blindly execute the command.</p><p><strong>DeleteCommand:</strong></p><p><pre class="brush: csharp">
private static void DeleteCommand(KeyValuePair&lt;string, string&gt; result)
{
    var sets = StorageHelper.GetSets();
    string setName = result.Key.Split(new char[] {':'})[1];
    var targetSet = StorageHelper.GetSingleSet(sets, setName);
    var command = (from c in targetSet.Commands where c.Name == result.Value select c).FirstOrDefault();
    
    if (command != null)
    {
        targetSet.Commands.Remove(command);
        StorageHelper.SerializeSets(sets);
    }
}
</pre></p><p>Not only can the user remove entire sets, but he can also target specific commands from a given set. Once a <strong>DELETE_COMMAND</strong> directive is recognized, the set name is parsed out from the original string, that follows the <strong>DELETE_COMMAND:SET_NAME, COMMAND_NAME</strong> format, and a simple LINQ query extracts the command instance, removes it and stores the set content on the local hard drive.</p><p>Notice that for some commands, particularly for set creation, deletion and command deletion, the server will return a list of the remaining items. The contents will be automatically updated on the devices, which will be waiting for that response. This measure was deliberately introduced to minimize the chances of a user triggering a command that was already deleted or trying to query a previously removed set.</p><h3>Transforming Codes</h3><p>You might have noticed that I am using <strong>IRCodeWorker.GetSerializableCodeType</strong> to transform a Phidgets SDK native IR code model into a serializable one. This is a helper function that performs a field copy of the existing object. Because of the differences in the model structure, it has to be done manually:</p><p><pre class="brush: csharp">
public static SerializableIRCode GetSerializableIRCode(IRLearnedCode code) 
{ 
    SerializableIRCode sCode = new SerializableIRCode();     
    sCode.BitSize = code.Code.BitCount;     
    sCode.Encoding = code.CodeInfo.Encoding;     
    sCode.CarrierFrequency = code.CodeInfo.CarrierFrequency;     
    sCode.CodeData = code.Code.Data;     
    sCode.DutyCycle = code.CodeInfo.DutyCycle;     
    sCode.Gap = code.CodeInfo.Gap;     
    sCode.Header = code.CodeInfo.Header;     
    sCode.MinRepeat = 5;     
    sCode.One = code.CodeInfo.One;     
    sCode.Repeat = code.CodeInfo.Repeat;     
    sCode.Trail = code.CodeInfo.Trail;     
    sCode.Zero = code.CodeInfo.Zero;     
    sCode.Mask = new ToggleMask()     
    {         
        BitSize = code.CodeInfo.ToggleMask.BitCount,         
        CodeData = code.CodeInfo.ToggleMask.Data         
    }; 
    
    return sCode;     
}
</pre></p><p>The reverse process is easier because I can pass each of the existing properties to the <strong>IRCodeInfo</strong> constructor. The only difference is the fact that I need to use Reflection to create an instance of <strong>IRLearnedCode</strong> because there is no public constructor defined and a dynamic object has to be created:</p><p><pre class="brush: csharp">
internal static IRLearnedCode GetLearnedCode(SerializableIRCode serializableIRCode) 
{ 
    IRCode code = new IRCode(serializableIRCode.CodeData, serializableIRCode.BitSize);     
    IRCodeInfo info = new IRCodeInfo(serializableIRCode.Encoding, serializableIRCode.BitSize, serializableIRCode.Header,     
    serializableIRCode.Zero, serializableIRCode.One, serializableIRCode.Trail, serializableIRCode.Gap, serializableIRCode.Repeat, 
serializableIRCode.MinRepeat, serializableIRCode.Mask.CodeData, IRCodeInfo.IRCodeLength.Constant,
serializableIRCode.CarrierFrequency, serializableIRCode.DutyCycle); 
    
    object[] parameters = new object[] { code, info }; 
    
    BindingFlags flags = BindingFlags.NonPublic | BindingFlags.Instance; 
    object instantType = Activator.CreateInstance(typeof(IRLearnedCode), flags, null, parameters, null); 

    return (IRLearnedCode)instantType; 
}
</pre></p><h3>Command and Set Management</h3><p>Looking back at the code that I put together for the command interpreter, there is one class that does all local content manipulation—<strong>StorageHelper</strong>. This is a simple class that performs LINQ queries on set as well as command collections, and makes sure that all the changes are preserved in the <strong>sets.xml</strong> file in the application folder that is used as the only storage place for all the content that is being manipulated by the server.</p><p><pre class="brush: csharp">
namespace Coding4Fun.MissionControl.API.Helpers 
{ 
    public class StorageHelper 
    { 
        
        /// &lt;summary&gt; 
        /// Lists all available sets that are currently stored on the server.         
        /// &lt;/summary&gt; 
        /// &lt;returns&gt;List of sets on the machine.&lt;/returns&gt;         
        internal static List&lt;Set&gt; GetSets()         
        {             
            List&lt;Set&gt; sets = null; 
            
            string rawContent = GetRawSets();             
            sets = JsonConvert.DeserializeObject&lt;List&lt;Set&gt;&gt;(rawContent); 
            
            return sets;             
        } 
        
        /// &lt;summary&gt;         
        /// Returns the list of commands that are associated with the given set.         
        /// &lt;/summary&gt;         
        /// &lt;param name=&quot;setName&quot;&gt;The name of the target set.&lt;/param&gt;         
        /// &lt;returns&gt;List of commands associated with the given set.&lt;/returns&gt;         
        internal static List&lt;Command&gt; GetCommands(string setName)         
        {             
            List&lt;Command&gt; commandList = null; 
            
            var sets = GetSets(); 
            
            Set singleSet = null;             
            if (sets != null)             
                singleSet = (from c in sets where c.Name == setName select c).FirstOrDefault(); 
            
            if (singleSet != null)         
            {         
                commandList = singleSet.Commands;     
            } 
            
            return commandList; 
        } 
        
        /// &lt;summary&gt;     
        /// Gets the list of names for the commands in the requested set. 
        /// &lt;/summary&gt; 
        /// &lt;param name=&quot;setName&quot;&gt;The name of the target set.&lt;/param&gt; 
        /// &lt;returns&gt;List of commands associated with the given set.&lt;/returns&gt; 
        internal static List&lt;string&gt; GetRawCommandNames(string setName) 
        { 
            List&lt;Command&gt; commandList = GetCommands(setName); 
            
            List&lt;string&gt; stringSet = null; 
            
            if (commandList != null) 
            {     
                stringSet = commandList.Select(x =&gt; x.Name).ToList();     
            } 
            
            return stringSet;     
        } 
        
        /// &lt;summary&gt; 
        /// Get the list of names for all sets on the local server. 
        /// &lt;/summary&gt; 
        /// &lt;returns&gt;List of sets on the machine.&lt;/returns&gt; 
        internal static List&lt;string&gt; GetRawSetNames() 
        {     
            List&lt;Set&gt; sets = GetSets(); 
            
            List&lt;string&gt; stringSet = null; 
    
            if (sets != null) 
            {     
                stringSet = sets.Select(x =&gt; x.Name).ToList();     
            } 
            
            return stringSet; 
        } 
        
        /// &lt;summary&gt; 
        /// Get the raw string contents of sets.xml. Should only be used in the 
        /// context of this class. 
        /// &lt;/summary&gt; 
        /// &lt;returns&gt;JSON string representing stored sets and commands.&lt;/returns&gt; 
        internal static string GetRawSets() 
        { 
            string sets = string.Empty; 
            
            if (File.Exists(&quot;sets&quot;)) 
            { 
                using (StreamReader reader = new StreamReader(File.OpenRead(&quot;sets&quot;))) 
                { 
                    sets = reader.ReadToEnd(); 
                } 
            } 
            else 
            { 
                FileStream stream = File.Create(&quot;sets.xml&quot;); 
                
                stream.Close();     
            } 
            
            return sets; 
        } 
        
        /// &lt;summary&gt; 
        /// Check whether a set is marked with a IsList flag. 
        /// &lt;/summary&gt; 
        /// &lt;param name=&quot;setName&quot;&gt;The name of the target set.&lt;/param&gt; 
        /// &lt;returns&gt;TRUE - set is a list. FALSE - set is not a list.&lt;/returns&gt; 
        internal static bool IsSetAList(string setName) 
        { 
            bool isList = true; 
            var sets = GetSets(); 
            Set set = null; 

            if (sets != null) 
                set = (from c in sets where c.Name == setName select c).FirstOrDefault(); 
            
            if (set != null) 
                isList = set.IsList; 
            
            return isList;     
        } 
        
        /// &lt;summary&gt; 
        /// Serialize the set collection to sets.xml 
        /// &lt;/summary&gt; 
        /// &lt;param name=&quot;sets&quot;&gt;Collection to be serialized.&lt;/param&gt; 
        /// &lt;returns&gt;true if sets are serialized.&lt;/returns&gt; 
        private static bool SerializeSets(List&lt;Set&gt; sets) 
        { 
            try 
            { 
                using (StreamWriter writer = new StreamWriter(&quot;sets.xml&quot;, false)) 
                {     
                    string data = JsonConvert.SerializeObject(sets); 
            
                    writer.Write(data); 
                } 
                
                return true; 
            } 
            catch 
            {     
                return false;     
            } 
        } 
        
        /// &lt;summary&gt; 
        /// Add a new set to the existing global set collection. 
        /// &lt;/summary&gt; 
        /// &lt;param name=&quot;name&quot;&gt;Set name.&lt;/param&gt; 
        /// &lt;returns&gt;true if successfully added set.&lt;/returns&gt; 
        internal static bool AddSet(string name, bool isList = true) 
        { 
            var sets = GetSets(); 

            if (sets == null) 
                sets = new List&lt;Set&gt;(); 
            
            var singleSet = GetSingleSet(sets, name); 

            if (singleSet == null) 
                sets.Add(new Set { Name = name, IsList = isList }); 
            
            if (SerializeSets(sets)) 
                return true; 
            else 
                return false; 
        } 
        
        /// &lt;summary&gt; 
        /// Retrieves a single set from a collection that has a specific name. 
        /// &lt;/summary&gt; 
        /// &lt;param name=&quot;sets&quot;&gt;The source collection from which to extract the set.&lt;/param&gt; 
        /// &lt;param name=&quot;name&quot;&gt;The name of the set to get.&lt;/param&gt; 
        /// &lt;returns&gt;An instance of the found set, if any.&lt;/returns&gt; 
        internal static Set GetSingleSet(List&lt;Set&gt; sets, string name) 
        { 
            if (sets != null) 
                return (from c in sets where c.Name == name select c).FirstOrDefault(); 
            else 
                return null; 
        } 
        
        /// &lt;summary&gt; 
        /// Add a IR command to an existing set. If the set is not found, it will be created. 
        /// &lt;/summary&gt; 
        /// &lt;param name=&quot;command&quot;&gt;The command instance to be added.&lt;/param&gt; 
        /// &lt;param name=&quot;targetSet&quot;&gt;The name of the target set.&lt;/param&gt; 
        /// &lt;returns&gt;true if the command was successfully added.&lt;/returns&gt; 
        internal static bool AddCommand(Command command, string targetSet) 
        { 
            var sets = GetSets(); 
            
            if (sets == null) 
                sets = new List&lt;Set&gt;(); 
            
            var singleSet = GetSingleSet(sets, targetSet); 
            
            if (singleSet == null) 
                singleSet = new Set { Name = targetSet }; 
            
            var singleCommand = (from c in singleSet.Commands where c.Name == command.Name select c).FirstOrDefault(); 
            
            if (singleCommand == null) 
            { 
                singleSet.Commands.Add(command); 
                
                if (SerializeSets(sets)) 
                    return true; 
                else 
                    return false; 
            } 
            else 
                return false; 
        } 
        
        /// &lt;summary&gt; 
        /// Retrieve a single command instance from one of the sets on the local server. 
        /// &lt;/summary&gt; 
        /// &lt;param name=&quot;commands&quot;&gt;Original list of commands.&lt;/param&gt; 
        /// &lt;param name=&quot;name&quot;&gt;Name of the command to be retrieved.&lt;/param&gt; 
        /// &lt;returns&gt;An instance of the command, if found. NULL if not.&lt;/returns&gt; 
        internal static Command GetSingleCommand(List&lt;Command&gt; commands, string name) 
        { 
            if (commands != null) 
                return (from c in commands where c.Name == name select c).FirstOrDefault(); 
            else 
                return null; 
        } 
        
        /// &lt;summary&gt; 
        /// Remove a set from a local machine. 
        /// &lt;/summary&gt; 
        /// &lt;param name=&quot;sets&quot;&gt;Original list of sets.&lt;/param&gt; 
        /// &lt;param name=&quot;targetSet&quot;&gt;Name of the set to remove.&lt;/param&gt; 
        internal static void RemoveSet(List&lt;Set&gt; sets, Set targetSet) 
        { 
            sets.Remove(targetSet); 
            
            SerializeSets(sets); 
        } 
    } 
}
</pre></p><h2>Sending Data Back to the Client</h2><p><strong>SendData</strong> in the <strong>NetworkHelper</strong> class handles all outbound connections. Here is its structure:</p><p><pre class="brush: csharp">
/// &lt;summary&gt; 
/// Send data to the target network machine. 
/// &lt;/summary&gt; 
/// &lt;param name=&quot;destination&quot;&gt;The target machine IP.&lt;/param&gt; 
/// &lt;param name=&quot;data&quot;&gt;Data to be sent, in string format.&lt;/param&gt; 
/// &lt;param name=&quot;sanitizeIp&quot;&gt;Determines whether to remove the port from the given IP string.&lt;/param&gt; 
public static void SendData(string destination, string data, bool sanitizeIp = true) 
{ 
    using (Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)) 
    {     
        string completeIp = string.Empty; 
        
        if (sanitizeIp)     
            completeIp = destination.Remove(destination.IndexOf(&quot;:&quot;), destination.Length - destination.IndexOf(&quot;:&quot;)); 
        
        client.Connect(completeIp, 6169); 
        client.Send(Encoding.UTF8.GetBytes(data));     
    }     
}
</pre></p><p>A new stream socket is created in order to connect to the target machine over the TCP pipe. If IP sanitization is enabled, the port is stripped from the address in order to pass a valid IP. A <strong>Socket</strong> instance cannot directly handle IPs of the format:</p><p><strong><em>255.255.255.0:PORT_NUMBER</em></strong></p><p>Later, in a synchronous manner, a connection is established and the data is sent.</p><p>At this point, you can see that the barebones service offers a flexible way to manage content. It can be accessed by any application type as long as the server can be accessed and the application can send commands in the pre-defined format and the content requested is actually located on the target server. This allows for high levels of extensibility and interoperability, as the server usage is not limited to a single platform. If I decide to create a Windows Store application that would allow me to control my TV, I simply need to add socket connection layer that will send plain strings to the machine where the IR sensor is connected.</p><p>Similarly, if some functionality needs to be added, it is possible to do so without ever touching the client applications. A modification in the endpoint will be reflected with no direct effect on all connection applications as long as all handled returned and requested values are preserved. The only additional requirement is that if the client applications want to take advantage of newly introduced capabilities, they need to have an updated command transmission layer for the new command types.</p><p>In <strong>Program.cs</strong>, I simply need to start the server through the <strong>CoreStarter</strong> class:</p><p><pre class="brush: csharp">
namespace Coding4Fun.MissionControl.API 
{ 
    class Program     
    {         
        static void Main(string[] args)         
        {             
            Console.WriteLine(&quot;Coding4Fun MissionControl Server&quot;);             
            CoreStarter.LaunchSocket();             
        }         
    }     
}
</pre></p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image0076.jpg"><img title="clip_image007" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image007_thumb3.jpg" alt="clip_image007" width="527" height="267" border="0"></a></p><h1>Mobile client overview</h1><p>The mobile client does not have the capability to send commands directly to the IR sensor. Instead, it connects to a remote machine that has the IR sensor plugged in and attempts to invoke a command from the list returned by the service. A single mobile client can support control over multiple servers.</p><p><strong>NOTE:</strong> Make sure that at the time of working with the Windows Phone client, the server is actually running on your local machine. To make it easier to test, also open port 6169 for incoming connections in Windows Firewall.</p><p>When building a Windows Phone application, make sure you have the <a href="http://developer.windowsphone.com/en-us/downloadsdk">proper version of the SDK installed</a>, as well as a <a href="http://en.wikipedia.org/wiki/Second_Level_Address_Translation">SLAT-compatible</a> machine if you plan on testing the application in the emulator.</p><h2>Networking Infrastructure</h2><p>The Windows Phone application also relies on a network infrastructure somewhat similar to that of the server. There is a TCP listener that is created when the application is started:</p><p><pre class="brush: csharp">
// Code to execute when the application is launching (eg, from Start) 
// This code will not execute when the application is reactivated 
private void Application_Launching(object sender, LaunchingEventArgs e) 
{ 
    ServiceSerializer.DeserializeServices(); 
    
    listener.OnClientConnected &#43;= listener_OnClientConnected; 
    listener.Start(6169); 
}
</pre></p><p>Here, listener is an instance of <strong>TcpSocketListener</strong>—a custom class designed to handle incoming network connections:</p><p><pre class="brush: csharp">
namespace Coding4Fun.MissionControl.WP.Network 
{ 
    public class TcpSocketListener : SocketConnectorBase     
    {     
        StreamSocketListener coreSocket; 
        
        public async void Start(int port)     
        {     
            coreSocket = new StreamSocketListener();         
            coreSocket.ConnectionReceived &#43;= coreSocket_ConnectionReceived; 
            
            try     
            {         
                await coreSocket.BindServiceNameAsync(port.ToString());         
            }     
            catch (Exception ex) 
            {     
                Debug.WriteLine(ex.Message); 
                
                coreSocket.Dispose();     
                coreSocket = null; 
                OnConnectionCompleted(new ConnectionEventArgs { IsSuccessful = false, DeviceID = string.Empty }); 
            } 
        } 
        
        async void coreSocket_ConnectionReceived(StreamSocketListener sender, StreamSocketListenerConnectionReceivedEventArgs args) 
        { 
            Debug.WriteLine(&quot;Connection received!&quot;); 
            
            DataReader reader = new DataReader(args.Socket.InputStream); 
            
            try 
            { 
                while (true) 
                { 
                    StringBuilder builder = new StringBuilder(); 
        
                    uint actualLength = 1; 

                    while (actualLength &gt; 0) 
                    {     
                        actualLength = await reader.LoadAsync(256); 
                        builder.Append(reader.ReadString(actualLength)); 
                    } 
                    
                    OnConnectionCompleted(new ConnectionEventArgs 
                    { 
                        Socket = args.Socket, 
                        IsSuccessful = true, 
                        DeviceID = args.Socket.Information.RemoteHostName.DisplayName, 
                        Token = builder.ToString() 
                    }); 
                    break; 
                } 
            } 
            catch (Exception exception) 
            { 
                Debug.WriteLine(exception.Message); 
                
                OnConnectionCompleted(new ConnectionEventArgs { IsSuccessful = false }); 
            } 
        } 
    } 
}
</pre></p><p>A <strong>StreamSocketListener</strong> is used for the connection core. When a connection is received, a continuous loop reads the entire contents of the incoming stream. <strong>OnConnectionCompleted</strong> is declared in the base class—<strong>SocketConnectorBase</strong>.</p><p><pre class="brush: csharp">
namespace Coding4Fun.MissionControl.WP.Network 
{ 
    public class SocketConnectorBase 
    { 
        public event EventHandler&lt;ConnectionEventArgs&gt; OnClientConnected; 
        public virtual void OnConnectionCompleted(ConnectionEventArgs connectionArgs) 
        { 
            if (OnClientConnected != null) 
            { 
                OnClientConnected(this, connectionArgs); 
            } 
        } 
        
        public event EventHandler&lt;bool&gt; OnSendCompletedEvent; 
        public virtual void OnSendCompleted(bool succeeded) 
        { 
            if (OnSendCompletedEvent != null) 
            { 
                OnSendCompletedEvent(this, succeeded); 
            } 
        } 
    } 
    
    public class ConnectionEventArgs : EventArgs 
    { 
        public StreamSocket Socket { get; set; }     
        public string DeviceID { get; set; }     
        public string Token { get; set; }     
        public bool IsSuccessful { get; set; }     
    } 
}
</pre></p><p><strong>ConnectionEventArgs</strong> here is used to identify the content that is passed to the client. <strong>DeviceID</strong> gives access to the source IP, <strong>IsSuccessful</strong> tells the developer whether the established connection is active and the <strong>Token</strong> carries the raw string if any was received.</p><p>Sending data is simplified to the maximum with the help of the <strong>SocketClient</strong> class, which relies on a <a href="http://msdn.microsoft.com/en-us/library/windows/apps/windows.networking.sockets.streamsocket.aspx">StreamSocket</a> instance that handles outbound connections and writing to the output stream:</p><p><pre class="brush: csharp">
namespace Coding4Fun.MissionControl.WP.Network 
{ 
    public class SocketClient : SocketConnectorBase 
    {     
        StreamSocket _socket; 
        
        public SocketClient() 
        {     
            _socket = new StreamSocket();     
        } 
        
        public SocketClient(StreamSocket socket) 
        {     
            _socket = socket;     
        } 
        
        public async void Connect(string hostName, int portNumber) 
        { 
            try 
            { 
                await _socket.ConnectAsync(new HostName(hostName), portNumber.ToString(), SocketProtectionLevel.PlainSocket); 
            
                OnConnectionCompleted(new ConnectionEventArgs { IsSuccessful = true }); 
            } 
            catch (Exception ex) 
            {     
                Debug.WriteLine(ex.Message); 
                
                OnConnectionCompleted(new ConnectionEventArgs { IsSuccessful = false });     
            } 
        } 
        
        public async void Send(string dataToSend) 
        { 
            try 
            {     
                using (DataWriter writer = new DataWriter(_socket.OutputStream)) 
                { 
                    // Write the length of the binary data that is being 
                    // sent to the client. 
                    writer.WriteUInt32((UInt32)dataToSend.Length); 
                    
                    writer.WriteString(dataToSend); 
        
                    // Send the actual data. 
                    await writer.StoreAsync(); 
                    
                    writer.DetachStream(); 
                    
                    OnSendCompleted(true); 
                } 
            } 
            catch 
            { 
                _socket.Dispose();     
                _socket = null;     
                OnSendCompleted(false);     
            }     
        }     
    }     
}
</pre></p><p>As with the listener class, <strong>SocketClient</strong> supports <strong>OnConnectionCompleted</strong> to notify the application that the connection attempt completed.</p><p>Back in <strong>App.xaml.cs</strong>, the data from the incoming connection captured by the <strong>TcpSocketListener</strong> instance is passed to the <strong>ResponseHelper</strong> class:</p><p><pre class="brush: csharp">
void listener_OnClientConnected(object sender, ConnectionEventArgs e) 
{ 
    ResponseHelper.HandleIncomingResponse(e.Token); 
}
</pre></p><p>This class reads the possible three commands sent by the server and interprets them, creating internal collections from the raw data if the current server IP matches the one obtained in the <strong>ServerResponse</strong> (the same model in the desktop application):</p><p><pre class="brush: csharp">
using Coding4Fun.MissionControl.WP.Models;
using Coding4Fun.MissionControl.WP.ViewModels;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Windows;

namespace Coding4Fun.MissionControl.WP.Misc
{
        public class ResponseHelper
        {
                public static void HandleIncomingResponse(string rawResponse)
                {
                        if (rawResponse != null)
                        {
                                ServerResponse response = JsonConvert.DeserializeObject&lt;ServerResponse&gt;(rawResponse);
                
                                if (response.Marker == Constants.COMMAND_SERVER_NOTIFICATION)
                                {
                                        Deployment.Current.Dispatcher.BeginInvoke(() =&gt;
                                        {
                                                MessageBox.Show(response.Content, &quot;Server Response&quot;, MessageBoxButton.OK);
                                        });
                                }
                                else
                                {
                                        if (CommonViewModel.Instance.IsWaiting)
                                        {
                                                if (response.Identifier == CommonViewModel.Instance.CurrentServer.Location)
                                                {
                                                        // returns the list of sets that are associated with the current server.
                                                        if (response.Marker == Constants.COMMAND_SERVER_SET_LIST)
                                                        {
                                
                                                                List&lt;string&gt; items = JsonConvert.DeserializeObject&lt;List&lt;string&gt;&gt;(response.Content);
                                
                                                                if (items != null)
                                                                {
                                                                        List&lt;Group&lt;string&gt;&gt; groupedItems = Group&lt;string&gt;.CreateGroups(items,
                                                                        CultureInfo.CurrentCulture, (string s) =&gt; { return s[0].ToString(); }, true);
                                                                        SetsPageViewModel.Instance.Sets = groupedItems;
                                                                }
                                                                else
                                                                {
                                                                        SetsPageViewModel.Instance.Sets = new List&lt;Group&lt;string&gt;&gt;();
                                                                }
                                
                                                                Deployment.Current.Dispatcher.BeginInvoke(() =&gt;
                                                                    {
                                                                            CommonViewModel.Instance.IsWaiting = false;
                                    
                                                                            if (!App.RootFrame.CurrentSource.ToString().Contains(&quot;SetsPage&quot;))
                                                                            {
                                                                                    App.RootFrame.Navigate(new Uri(&quot;/Views/SetsPage.xaml&quot;, UriKind.Relative));
                                                                            }
                                                                    });
                                
                                                        }
                                                        // returns the list of commands associated with a given set.
                                                        else if (response.Marker.Contains(Constants.COMMAND_SERVER_SET_COMMANDS))
                                                        {
                                                            string[] data = response.Marker.Split(new char[] { ':' });
                                                                if (data[1] == CommonViewModel.Instance.CurrentSet)
                                                                {
                                                                        bool isList = false;
                                                                        bool.TryParse(data[2].ToLower(), out isList);
                                    
                                                                        if (isList)
                                                                        {
                                                                                CommonViewModel.Instance.CurrentSetType = &quot;list&quot;;
                                                                        }
                                                                        else
                                                                        {
                                                                                CommonViewModel.Instance.CurrentSetType = &quot;pad&quot;;
                                                                        }
                                    
                                                                        CommandsPageViewModel.Instance.Commands = new System.Collections.ObjectModel.ObservableCollection&lt;string&gt;(JsonConvert.DeserializeObject&lt;List&lt;string&gt;&gt;(response.Content));
                                    
                                                                        Deployment.Current.Dispatcher.BeginInvoke(() =&gt;
                                                                            {
                                                                                    CommonViewModel.Instance.IsWaiting = false;
                                                                                    App.RootFrame.Navigate(new Uri(&quot;/Views/CommandsPage.xaml&quot;, UriKind.Relative));
                                                                            });
                                                                }
                                                        }
                                                }
                                        }
                                }
                        }
                }
        }
}
</pre></p><p>If the response comes from a server that is different than the one that is currently active, the data is discarded as the user no longer needs it. Also, for specific commands, the mobile application will be on standby, waiting for a response (unless the user decides to cancel the request) – the <strong>IsWaiting</strong> flag is an application-wide indicator that a pending server action is in the queue.</p><p>Same as with the server, the commands in the Windows Phone application are represented through pre-defined constants:</p><p><pre class="brush: csharp">
public const string COMMAND_SERVER_SET_LIST = &quot;SET_LIST&quot;; 

public const string COMMAND_SERVER_SET_COMMANDS = &quot;SET_COMMANDS&quot;; 

public const string COMMAND_SERVER_NOTIFICATION = &quot;NOTIFICATION&quot;;
</pre></p><p>Let’s now take a closer look at how it is handled internally to build the visual layer.</p><h4>Handling the Data</h4><p>The first thing users will see when the application is launched is the list of registered servers:</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/wp_ss_20130507_0003%5B4%5D.png"><img title="wp_ss_20130507_0003" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/wp_ss_20130507_0003_thumb%5B2%5D.png" alt="wp_ss_20130507_0003" width="288" height="480" border="0"></a></p><p>This is <strong>ServiceListPage.xaml</strong>. The list of servers that were added is retrieved from the isolated storage on application startup, with the help of the standard serialization routine implemented in the <a href="https://coding4fun.codeplex.com/">Coding4Fun Toolkit</a>—specifically, its storage subset (you can get it <a href="http://nuget.org/packages/Coding4Fun.Toolkit.Storage/">via NuGet</a>):</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image0116.jpg"><img title="clip_image011" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image011_thumb3.jpg" alt="clip_image011" width="535" height="61" border="0"></a></p><p>The one-liner that initializes the internal server collection is as follows:</p><p><pre class="brush: csharp">
MainPageViewModel.Instance.Servers = Serialize.Open&lt;ObservableCollection&lt;Server&gt;&gt;(Constants.SERVERS_FILE);
</pre></p><p>&nbsp;</p><p>Here, the <strong>SERVERS_FILE</strong> constant is equal to <strong>servers.xml</strong>. It is a good idea to use constants for file names in order to be able to later modify the location through a single change instead of digging through the many source files in a solution to find references to the old location.</p><p>The user can define an unlimited number of servers, as long as he can access those. There is no restriction on the location of the server itself—it can work with the desktop in your room just as well as with a PC on the other end of the world (yes, this was tested).</p><p>When adding a new server, the user is redirected to <strong>AddServicePage.xaml</strong>, where he can fill in connection details, as well as the location of an image that would help him identify that specific item in the general list:</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/wp_ss_20130423_0005%5B4%5D.png"><img title="wp_ss_20130423_0005" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/wp_ss_20130423_0005_thumb%5B2%5D.png" alt="wp_ss_20130423_0005" width="288" height="480" border="0"></a></p><p>Once data entry is complete, it is validated internally to make sure that the server is not already registered with the same name and location. If the validation step passes, the server is added to the list of local access points and the user is returned back to the server selection page:</p><p><pre class="brush: csharp">
private void AttemptAddService()
{
        if (!string.IsNullOrWhiteSpace(txtName.Text) &amp;&amp; !string.IsNullOrWhiteSpace(txtLocation.Text))
        {
                Server server = new Server
                    {
                            Name = txtName.Text,
                            Location = txtLocation.Text,
                            ImageURL = !string.IsNullOrWhiteSpace(txtAvatar.Text) ? txtAvatar.Text : string.Empty
                    };
        
                if (!CollectionHelper.CheckServerExists(server))
                {
                        MainPageViewModel.Instance.Servers.Add(server);
            
                        Serialize.Save(Constants.SERVERS_FILE, MainPageViewModel.Instance.Servers);
                        NavigationService.GoBack();
                }
                else
                {
                        Alert.Send(&quot;The service with this name or location is already registered.&quot;);
                }
        }
        else
        {
                Alert.Send(&quot;The service needs a name and a location.&quot;);
        }
}
</pre></p><p>When a server selection is made by the user, it is necessary to show <strong>SetsPage.xaml</strong>. However, it is necessary to also check whether the server is active or not prior to the actual navigation. With the help of internal bindings, I am doing it through a <strong>RelayCommand</strong>:</p><p><pre class="brush: csharp">
public RelayCommand SelectServerCommand { get; private set; }
private async void SelectServer(object server)
{
        CommonViewModel.Instance.IsWaiting = true;
        CommonViewModel.Instance.CurrentServer = (Server)server;
    
        bool result = await CommonViewModel.Instance.CommandClient.SendCommand(CommonViewModel.Instance.CurrentServer.Location, 
        Constants.COMMAND_SERVER_HELLO, string.Empty);
        if (!result)
        {
                Alert.Send(Constants.MESSAGE_SERVER_CONNECT_FAIL);
                CommonViewModel.Instance.CurrentServer = null;
        
                CommonViewModel.Instance.IsWaiting = false;
        }
}
</pre></p><p>&nbsp;</p><p><strong>COMMAND_SERVER_HELLO</strong> represents the initial handshake command that I mentioned earlier—it requests the list of sets on the target server. To streamline command processing, <strong>CommandClient</strong> is used and wraps around the <strong>SocketClient</strong> class, giving me the possibility to call <strong>SendCommand</strong> with the command metadata without having to explicitly handle socket interactions in my views:</p><p><pre class="brush: csharp">
namespace Coding4Fun.MissionControl.WP.Network 
{     
    public class CommandClient     
    {     
        private SocketClient client; 
        
        public Task&lt;bool&gt; SendCommand(string key, string value, Action&lt;bool&gt; onCompleted = null) 
        {     
            var taskCompletionSource = new TaskCompletionSource&lt;bool&gt;(); 
            
            client = new SocketClient();     
            client.OnClientConnected &#43;= (s, args) =&gt;     
            {     
                if (args.IsSuccessful)     
                {     
                    string data = JsonConvert.SerializeObject(new KeyValuePair&lt;string, string&gt;(key, value));     
                    client.Send(data);     
                } 
            
                taskCompletionSource.SetResult(args.IsSuccessful); 
                client = null; 
            }; 
            
            client.Connect(Binder.Instance.CurrentService.Location, 6169); 
            return taskCompletionSource.Task;     
        } 
    } 
}
</pre></p><p>From here on, <strong>ResponseHelper</strong> is once again involved, grouping all the data alphabetically—remember this call:</p><p><pre class="brush: csharp">
// returns the list of sets that are associated with the current server. 
if (response.Marker == Constants.COMMAND_SERVER_SET_LIST) 
{     
    List&lt;string&gt; items = JsonConvert.DeserializeObject&lt;List&lt;string&gt;&gt;(response.Content);     
    if (items != null) 
    {     
        List&lt;Group&lt;string&gt;&gt; groupedItems = Group&lt;string&gt;.CreateGroups(items,     
    CultureInfo.CurrentCulture, (string s) =&gt; { return s[0].ToString(); }, true);     
        Binder.Instance.Sets = groupedItems;     
    } 
    else 
    {     
        Binder.Instance.Sets = new List&lt;Group&lt;string&gt;&gt;();     
    } 
}
</pre></p><p>&nbsp;</p><p>The grouped collection is later bound to a <a href="http://msdn.microsoft.com/en-us/library/windowsphone/develop/jj244365(v=vs.105).aspx">LongListSelector</a> instance:</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/wp_ss_20130507_0001%5B4%5D.png"><img title="wp_ss_20130507_0001" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/wp_ss_20130507_0001_thumb%5B2%5D.png" alt="wp_ss_20130507_0001" width="288" height="480" border="0"></a></p><p>For each handshake call to the server, the set collection will be re-initialized, in case the server was updated by another device while the user was not taking any actions.</p><p>Adding a set takes the user to <strong>AddSetPage.xaml</strong>, where the user input is once again validated and the appropriate command sent to the currently selected server:</p><p><pre class="brush: csharp">
private async void AttemptAddSet()
{
        if (!string.IsNullOrWhiteSpace(txtName.Text))
        {
                this.Focus();
        
                bool commandSent = await CommonViewModel.Instance.CommandClient.SendCommand(CommonViewModel.Instance.CurrentServer.Location, 
                    string.Format(Constants.COMMAND_CREATE_SET, ((ListPickerItem)lstType.SelectedItem).Content.ToString()), txtName.Text);
                if (!commandSent)
                {
                        Alert.Send(Constants.MESSAGE_SERVER_CONNECT_FAIL);
                }
                else
                {
                        CommonViewModel.Instance.IsWaiting = true;
                        NavigationService.GoBack();
                }
        }
        else
        {
                Alert.Send(Constants.MESSAGE_NO_NAME_FAIL);
        }
}
</pre></p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/wp_ss_20130430_0002%5B4%5D-1.png"><img title="wp_ss_20130430_0002" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/wp_ss_20130430_0002_thumb%5B2%5D-1.png" alt="wp_ss_20130430_0002" width="288" height="480" border="0"></a></p><p>The end-user is also able to specify whether the new set is a list or a pad. Since the server does not explicitly define the type of a set beyond marking whether it’s a list, it is possible to have an arbitrary type here.</p><p>To give you an idea of what it looks like in the current release of MissionControl, here is the pad representation of a set of commands:</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/wp_ss_20130507_0002%5B13%5D.png"><img title="wp_ss_20130507_0002" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/wp_ss_20130507_0002_thumb%5B11%5D.png" alt="wp_ss_20130507_0002" width="288" height="480" border="0"></a></p><p>It is a convenient way to display buttons for typical actions, such as channel switching through digits. Since we can safely assume many of those will be tapped sequentially, a list would be inconvenient to scroll through.</p><p>On the other hand, some remote control commands work well with a list because no sequences are invoked most of the time:</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/wp_ss_20130507_0004%5B4%5D.png"><img title="wp_ss_20130507_0004" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/wp_ss_20130507_0004_thumb%5B2%5D.png" alt="wp_ss_20130507_0004" width="288" height="480" border="0"></a></p><p>If the pad is not desired, it can easily be swapped with another design and internal template - the appearance is swapped dynamically and is not hard-bound to a string value.</p><p>Once a set is selected, a connection attempt is made to the current server in order to check whether there is still a communication channel available with the resource that fetched the initial list of commands. If a connection is established, the server will also return a set of commands that are available in the set at the time of the request.</p><p><pre class="brush: csharp">
private async void AttemptLoadCommands()
{
        bool commandSent = await CommonViewModel.Instance.CommandClient.SendCommand(CommonViewModel.Instance.CurrentServer.Location,
            Constants.COMMAND_GET_COMMANDS, CommonViewModel.Instance.CurrentSet);
        if (!commandSent)
        {
                Alert.Send(Constants.MESSAGE_SERVER_CONNECT_FAIL);
                CommonViewModel.Instance.IsWaiting = false;
        }
}
</pre></p><p>You’ve probably already noticed that both for commands and sets, the initial routine verifies the connection to the server. The server might go dark after the set list is loaded, therefore rendering any attempt to process other commands impossible. To avoid scenarios in which the user is waiting for a response from a server that doesn’t run, the user is notified before being redirected to the subsequent view, if the connection fails. That way unnecessary navigation passes are out of the picture.</p><p>If the user selects a command from one of the lists demonstrated above, an <strong>EXECUTE</strong> directive is issued via the <strong>CommandClient</strong> class:</p><p><pre class="brush: csharp">
private async void lstCommands_SelectionChanged(object sender, SelectionChangedEventArgs e) 
{ 
    if (lstCommands.SelectedItem != null)
    { 
        string selectedItem = lstCommands.SelectedItem.ToString(); 
        
        CommandClient commandClient = new CommandClient(); 
        bool commandSent = await commandClient.SendCommand(string.Format(Constants.COMMAND_EXECUTE, 
        
        Binder.Instance.CurrentSet), selectedItem); 
    
        if (!commandSent) 
        {     
            Alert.Send(Constants.MESSAGE_SERVER_CONNECT_FAIL);     
        } 
        
        lstCommands.SelectedItem = null; 
    } 
}
</pre></p><p>Once the server receives the command, it will send it to the target without additional notifications being released to the connecting client.</p><p>When it comes to learning a new remote control code in <strong>LearnCodePage.xaml</strong>, the procedure is exactly the same as with any other part of the server communication process — a <strong>LEARN_CODE</strong> command is sent to the server with the associated set and new command name, and the server will wait for incoming IR input, leaving the connecting device free (no waiting lock is issued):</p><p><pre class="brush: csharp">
private async void AttemptLearnCode()
{
        if (!string.IsNullOrWhiteSpace(txtName.Text))
        {
                CommonViewModel.Instance.IsWaiting = true;
                this.Focus();
        
                bool commandSent = await CommonViewModel.Instance.CommandClient.SendCommand(CommonViewModel.Instance.CurrentServer.Location,
                    string.Format(Constants.COMMAND_LEARN_NEW, CommonViewModel.Instance.CurrentSet), txtName.Text);
                if (!commandSent)
                {
                        Alert.Send(Constants.MESSAGE_SERVER_CONNECT_FAIL);
                }
                else
                {
                        Alert.Send(Constants.MESSAGE_COMMAND_LEARN_WAIT);
                        NavigationService.GoBack();
                }
        
                CommonViewModel.Instance.IsWaiting = false;
        }
        else
        {
                Alert.Send(Constants.MESSAGE_NO_NAME_FAIL);
        }
}
</pre></p><p>Once the server learns a new command — if, and only if, the user still works in the context of the same server — an alert will be displayed, telling the user whether the command was successfully learned.</p><p>For convenience purposes, I also implemented a quick launch panel, where frequently-used commands can be placed. Whenever a user wants to add something here, he will tap-and-hold on an existing command in any of the sets that are available for any given server, and select the &quot;add to quick launch&quot; option. Once completed, the stored commands will be available on the main page, even when the user is not directly connected to the server that carries the command:</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/wp_ss_20130507_0005%5B4%5D.png"><img title="wp_ss_20130507_0005" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/wp_ss_20130507_0005_thumb%5B2%5D.png" alt="wp_ss_20130507_0005" width="288" height="480" border="0"></a></p><p>Because this interaction layer is placed outside the boundaries of a single server or set, I needed to create a special data model to store the quick commands and the related connection information, that would let me call the server even when it is not the currently selected one:</p><p><pre class="brush: csharp">
namespace Coding4Fun.MissionControl.WP.Models
{
        public class Favorite
        {
            public string CommandName { get; set; }
            public string ParentSet { get; set; }
            public string ServerLocation { get; set; }
        }
}
</pre></p><p>Same as with the list of servers, the list of favorites is deserialized on application startup:</p><p><pre class="brush: csharp">
MainPageViewModel.Instance.Favorites = Serialize.Open&lt;ObservableCollection&lt;Favorite&gt;&gt;(Constants.FAVORITES_FILE);
</pre></p><p>&nbsp;</p><p>Logically, we would also need to have a way to eliminate trailing commands for servers or sets that have been removed, since those can no longer be invoked or might have a different meaning on servers that were added and have the same IP as the previous owner. This is easily done with a simple LINQ expression that is passed to <strong>RemoveTrailingFavorites </strong>in the <strong>CollectionHelper </strong>class:</p><p><pre class="brush: csharp">
internal static void RemoveTrailingFavorites(Func&lt;Favorite,bool&gt; predicate)
{
        var favorites = MainPageViewModel.Instance.Favorites.Where(predicate).ToList();
    
        if (favorites.Count() &gt; 0)
        {
                foreach (var favorite in favorites)
                {
                        Deployment.Current.Dispatcher.BeginInvoke(() =&gt;
                            {
                                    MainPageViewModel.Instance.Favorites.Remove(favorite);
                            });
                }
        
                Serialize.Save(Constants.FAVORITES_FILE, MainPageViewModel.Instance.Favorites);
        }
}
</pre></p><p>A typical usage scenario is reflected in the server removal snippet:</p><p><pre class="brush: csharp">
public static bool RemoveServer(Server server)
{
        try
        {
                RemoveTrailingFavorites(x=&gt; x.ServerLocation == server.Location);
        
                MainPageViewModel.Instance.Servers.Remove(server);
        
                Serialize.Save(Constants.SERVERS_FILE, MainPageViewModel.Instance.Servers);
        
                return true;
        }
        catch
        {
                return false;
        }
}
</pre></p><p>Because an <a href="http://msdn.microsoft.com/en-us/library/ms668604(v=vs.95).aspx" target="_blank">ObservableCollection&lt;T&gt;</a> is used for both the list of servers and quick launch commands, the view will be instantly updated to reflect the changes.</p><h1>Improvements to the project</h1><p>This specific project relies on a hybrid IR transmitter and receiver, which is not exactly cheap. As a step forward for this project, it can be adapted to use a central microcontroller that acts as a server (e.g. <a href="http://www.netduino.com/" target="_blank">Netduino</a>) and a series of IR emitters (instead of using a composite receiver/emitter) connected to it. Reduced cost for the IR infrastructure is key, as not every single component needs the capability to learn IR commands. You can have a single command capturing endpoint and multiple transmitters. This will also eliminate the need for a desktop client, since the server on the microcontroller can be built to be accessible via a web-browser.</p><p>Another important aspect not covered in this article is security. With the current workflow, anyone who has direct access to the server IP is able to do anything he wants with the data handled by the server. I am basing my writing on the assumption that you are testing the application on a secure local network and that the the odds of something like this happening are close to zero. However, for other environments where tampering with a server might be unacceptable, consider implementing a layer of security between the server and the client.</p><h2>Conclusion</h2><p>With affordable microcontrollers and sensors, home and office automation can be a nice bonus resulting from little investment. This article covers the implementation of a proof-of-concept server and application that can be easily extended and adapted to a variety of environments and devices.</p> <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/coding4fun/rss&WT.dl=0&WT.entryid=Entry:RSSView:b029d939c55f459c9663a1b70159bff4">]]></description>
    <comments>http://channel9.msdn.com/coding4fun/articles/MissionControl-A-Flexible-API-for-Remote-Device-Control</comments>
    <link>http://channel9.msdn.com/coding4fun/articles/MissionControl-A-Flexible-API-for-Remote-Device-Control</link>
    <itunes:summary>In a race to optimize everything, developers often go to extremes to build software that performs routine tasks. MissionControl is a system that allows users to program a control center that stores interfaces with attached hardware sensors, allowing the users to control any other devices that can be activated via the underlying protocol. For demo purposes, the MissionControl build at this point is compatible with the Phidgets IR hybrid sensor. The system has two core components: A server application, which is a Win32 console application that handles incoming queries and returns data to the connected clients. This application runs on the desktop machine with the connected sensor. The Windows Phone application that sends requests to the target server and can trigger a variety of pre-programmed commands. The BasicsHardware and Communication InfrastructureOne of the most important parts of the project is the signal capture and replication hardware. For the purposes of this project, I decided to use a dual-mode Phidgets IR sensor. It supports both IR code capture and subsequent replication. From a user’s perspective, this device also eliminates a substantial code-learning overhead as well as the potential error rate. Instead of searching for a device-specific hexadecimal sequence that later has to be transformed in a working IR code, the user simply has to point his remote control at the sensor and press the button that he wants accessible from a mobile device. Given that the capturing software is running on the target machine, once the sensor detects that a code can be repeated within an acceptable precision range, it will be automatically captured and stored, with all required transformations worked out in the backend using the free Phidgets SDK. Even though I can, I don’t have to handle the binary code content received through the sensor—the Phidgets .NET libraries carry built-in types that contain all the processed metadata that I will discuss later in this article. </itunes:summary>
    <pubDate>Mon, 13 May 2013 15:12:48 GMT</pubDate>
    <guid isPermaLink="false">http://channel9.msdn.com/coding4fun/articles/MissionControl-A-Flexible-API-for-Remote-Device-Control</guid>
    <dc:creator>Clint Rutkas, Den Delimarsky</dc:creator>
    <category>networking</category>
    <category>windows</category>
    <category>windows-phone</category>
  </item>
	<item>
    <title>Ludus Windows 8 Game Starter Kit - Pleasing the Platformer in you...</title>
    <description><![CDATA[<p>Todays' project by Christer Kaitila is a kit that will help you quickly and easily build Windows 8 Platform games. Almost painfully easy to create games... If you've ever wanted to create your own platform game, and you've got a weekend, this kit is just for you...</p><h2><a href="http://wootstudio.ca/win8platstarter" target="_blank">Windows 8 Platformer Game Starter Kit</a></h2><blockquote><p><a href="http://wootstudio.ca/win8platstarter" target="_blank"><img title="image" src="http://files.channel9.msdn.com/wlwimages/ae054c0b4d7b402ab1239e6800c0220f/image%5B7%5D-39.png" alt="image" width="500" height="284" border="0"></a></p><p>Platformer Game Starter Kit<small>(includes 2 HTML5-based examples)</small></p><p>Don't start from scratch. Our Platformer Game Starter Kit for Windows 8 will get you going with full code &amp; free game art.</p><h4>How</h4><hr><p>Feel free to take the examples, mix them up and build your own great game for the Windows Store following these steps:</p><ol><li><a href="http://msdn.microsoft.com/en-us/windows/apps/br229516">Download your free Visual Studio for Windows 8</a> for all the tools you will need. </li><li>Download the <a href="http://wootstudio.ca/win8platstarter">Platformer Game Starter Kit</a>. </li><li>Mix it up and build your own epic game. </li><li><a href="https://appdev.microsoft.com/StorePortals/en-us/Account/Signup/Start/">Open a Windows Store Developer Account.</a> </li><li><a href="http://manager1201.agilitycms.com/Dialogs/wootstudio@microsoft.com">Let us know about it</a> and we can even give you free advice on making it great and help pass store certification. </li><li>Publish it to the Windows Store. </li></ol><p>We know everyone is not a game artist, so we have provided you with some free game art and other places you can find royalty-free art for your game.</p><p><a href="http://wootstudio.ca/win8platstarter" target="_blank"><img title="image" src="http://files.channel9.msdn.com/wlwimages/ae054c0b4d7b402ab1239e6800c0220f/image%5B6%5D-67.png" alt="image" width="500" height="285" border="0"></a></p></blockquote><h2><a href="https://github.com/Mcfunkypants/Ludus" target="_blank">Ludus Game Starter Kit</a></h2><blockquote><p>An HTML5 Platformer Game Starter Kit for Windows8 Store</p><p>by Christer (McFunkypants) Kaitila <a href="http://mcfunkypants.com/">http://mcfunkypants.com</a></p><p>Source: <a href="https://github.com/mcfunkypants/ludus">https://github.com/mcfunkypants/ludus</a></p><p>Demos: <a href="http://www.mcfunkypants.com/ludus">http://www.mcfunkypants.com/ludus</a></p><p>Welcome to Ludus, brave adventurer!</p><p>Ludus is a dirt-simple game engine that uses html5 canvas. It was designed specifically for mario/sonic style platformer games but could be used for any genre with minimal changes. It boasts great performance, and requires only free tools.</p><p>The word Ludus means PLAY/GAME/TRAINING in latin. The Ludus engine is designed to be a great way to learn to make games.</p><p>Sure, there are bigger and more complex game engines.</p><p>This one is designed to be easy to play around with.</p><p>Why? It was created to run real-world games that have a beginning, middle, and end. It was optimized to run on less powerful systems and touch-screen tablets. It is simple, but goes beyond the level of a &quot;tech demo&quot; to encapsulate all the required functionality you might need to make a polished game, such as GUI and sound.</p><p>...</p><p>IT'S POSSIBLE TO MAKE A GAME USING LUDUS IN A WEEKEND.</p><p>You could make your own game just by changing the artwork: it is possible to make a new game without ever touching a line of code. All you would need to do is modify the .png and .mp3 art assets as well as the level#.js level data files.</p><p>The best tool to create in-game worlds is TILED (<a href="http://www.mapeditor.org/">http://www.mapeditor.org</a>) which exports data in .json format.</p><p>Check out the example .tmx source files and see if you can make your own game! Once you've made a level, export as .json and then run the _buildlevels.bat file to convert JSON to JSONP data to a new level#.js file.</p><p>The one important thing to remember is that each layer is important. The order matters. The bottom-most layer is for regular world tiles that the player will collide with. The rest are for pickups, bouncy platforms, dangerous spikes, and so on.</p><p>Additionally, you should modify the game settings in the MAP MENU -&gt; MAP PROPERTIES dialog. Gravity, speed and the player's starting position are all stored there.</p><p>HACKING THE SOURCE CODE</p><p>The only source code file you will want to modify, if you choose to start coding, is ludus.js. Inside, you'll notice all sorts of variables at the top which you can modify to your heart's content. Note that some of these variables are overwritten by whatever is defined inside the level data.</p><p>With regard to the structure of the code, the most important thing to know is that the game is controlled by STATE objects.</p><p>Each state (title screen, in-game, and between level transitions) is a class object that has a .setup(), .update() and .draw() function. You could add new states for things like boss battles, inventory screens or a high score table.</p><p>See these class constructors: function TitleScreenState() function LevelTransitionScreenState() function PlayState()</p><p>HAVE FUN!</p><p>...</p></blockquote><p>Let's take a peek at the two included example games (In Visual Studio of course!)...</p><p><img title="image" src="http://files.channel9.msdn.com/wlwimages/ae054c0b4d7b402ab1239e6800c0220f/image%5B10%5D-38.png" alt="image" width="500" height="270" border="0"></p><p><img title="image" src="http://files.channel9.msdn.com/wlwimages/ae054c0b4d7b402ab1239e6800c0220f/image%5B16%5D-26.png" alt="image" width="500" height="270" border="0"></p><p>Both games ran for me the first time with no issues and were fun (in a platformer kind of way). Sure there's only 3 levels, but hey, if there was too much done it would take all the coding fun away!</p><p>So either start from scratch or copy off of these, this kit and the provided free artwork, framework and code will have you building your next great Windows 8 game...</p> <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/coding4fun/rss&WT.dl=0&WT.entryid=Entry:RSSView:f3c2e08dcdbd40af9106a1bb0129a6a1">]]></description>
    <comments>http://channel9.msdn.com/coding4fun/blog/Ludus-Windows-8-Game-Starter-Kit-Pleasing-the-Platformer-in-you</comments>
    <link>http://channel9.msdn.com/coding4fun/blog/Ludus-Windows-8-Game-Starter-Kit-Pleasing-the-Platformer-in-you</link>
    <itunes:summary>Todays&#39; project by Christer Kaitila is a kit that will help you quickly and easily build Windows 8 Platform games. Almost painfully easy to create games... If you&#39;ve ever wanted to create your own platform game, and you&#39;ve got a weekend, this kit is just for you... Windows 8 Platformer Game Starter Kit Platformer Game Starter Kit(includes 2 HTML5-based examples) Don&#39;t start from scratch. Our Platformer Game Starter Kit for Windows 8 will get you going with full code &amp;amp; free game art. HowFeel free to take the examples, mix them up and build your own great game for the Windows Store following these steps: Download your free Visual Studio for Windows 8 for all the tools you will need. Download the Platformer Game Starter Kit. Mix it up and build your own epic game. Open a Windows Store Developer Account. Let us know about it and we can even give you free advice on making it great and help pass store certification. Publish it to the Windows Store. We know everyone is not a game artist, so we have provided you with some free game art and other places you can find royalty-free art for your game.  Ludus Game Starter KitAn HTML5 Platformer Game Starter Kit for Windows8 Store by Christer (McFunkypants) Kaitila http://mcfunkypants.com Source: https://github.com/mcfunkypants/ludus Demos: http://www.mcfunkypants.com/ludus Welcome to Ludus, brave adventurer! Ludus is a dirt-simple game engine that uses html5 canvas. It was designed specifically for mario/sonic style platformer games but could be used for any genre with minimal changes. It boasts great performance, and requires only free tools. The word Ludus means PLAY/GAME/TRAINING in latin. The Ludus engine is designed to be a great way to learn to make games. Sure, there are bigger and more complex game engines. This one is designed to be easy to play around with. Why? It was created to run real-world games that have a beginning, middle, and end. It was optimized to run on less powerful systems and touch-screen tablets. It</itunes:summary>
    <pubDate>Mon, 13 May 2013 13:00:00 GMT</pubDate>
    <guid isPermaLink="false">http://channel9.msdn.com/coding4fun/blog/Ludus-Windows-8-Game-Starter-Kit-Pleasing-the-Platformer-in-you</guid>
    <dc:creator>Greg Duncan</dc:creator>
    <category>coding4fun</category>
    <category>html5</category>
    <category>javascript</category>
    <category>game+development</category>
    <category>windows+8</category>
    <category>windows+store+app</category>
  </item>
	<item>
    <title>Philips Hue Lighting Controller</title>
    <description><![CDATA[<h3><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image002%5B3%5D-9.jpg"><img title="clip_image002" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image002_thumb-10.jpg" alt="clip_image002" width="605" height="341" border="0"></a></h3><p>So Philips recently introduced their Hue Connected Bulbs: an easy-to-use set of LED light bulbs and Wi-Fi connected bridge which allows you to dynamically change the color of your home lighting using their iOS or Android app. What’s particularly cool is that the bridge has a web API which you can access to set the colors of each bulb with your own app.</p><p>We at <a href="http://untitlednet.com">untitled network</a> developed our own Philips Hue app called Oni: light Control, which is&nbsp;currently available on the <a href="http://www.windowsphone.com/en-us/store/app/oni-light-control/c8199c0b-3976-4a3b-9275-2d3a803f68ab">Windows Phone Store</a>. In addition to allowing you to set the color of your home lighting with defined “Moods”, the app also allows you to do the same using your phone’s built in voice commands or inexpensive NFC stickers. Here’s a demo of the Oni: Light Control in action:</p><p><object width="425" height="355"><param name="movie" value="http://www.youtube.com/v/bJUqLPvlJS0&hl=en"></param><param name="wmode" value="transparent"></param><embed src="http://www.youtube.com/v/bJUqLPvlJS0&hl=en" type="application/x-shockwave-flash" wmode="transparent" width="425" height="355"></embed></object></p><p><object width="425" height="355"><param name="movie" value="http://www.youtube.com/v/n00gZqQj5wk&hl=en"></param><param name="wmode" value="transparent"></param><embed src="http://www.youtube.com/v/n00gZqQj5wk&hl=en" type="application/x-shockwave-flash" wmode="transparent" width="425" height="355"></embed></object></p><p>I’m going to show you how you can develop your own app using the color picker from the Coding4Fun Toolkit for Windows Phone and the Json.Net library from Newtonsoft. These libraries can be found on NuGet, but you’ll obviously need the Philips Hue Connected Bulbs kit to test things out.</p><p><strong>Getting Started:</strong></p><p>The Philips Hue API uses a restful JSON interface you can access using any http client. Documentation on all of the supported methods by the Philips Hue bridge can be found at <a href="http://blog.ef.net/2012/11/02/philips-hue-api.html">http://blog.ef.net/2012/11/02/philips-hue-api.html</a>.</p><p>To get started, you’ll need authorized access to your bridge’s API. Once the bridge has successfully established a network connection with your router, discover its internal IP address via the URL: <a href="http://www.meethue.com/api/nupnp">http://www.meethue.com/api/nupnp</a></p><p>You should get a response similar to:</p><p><pre class="brush: csharp">[{&quot;id&quot;:&quot;ffss00fffe123456&quot;,&quot;internalipaddress&quot;:&quot;192.168.1.100&quot;,&quot;macaddress&quot;:&quot;0aa:bb:cc:dd:00:11&quot;}]
</pre></p><p>Note the internalipaddress value and use the IP to access the bridge’s API directly the with the URL <a href="http://192.168.1.100/api">http://192.168.1.100/api</a></p><p>Now, since we haven’t registered a user for authorization, attempting to access the hub will return an error from the bridge:</p><p><pre class="brush: csharp">
[{&quot;error&quot;:{&quot;type&quot;:1,&quot;address&quot;:&quot;/&quot;,&quot;description&quot;:&quot;unauthorized user&quot;}}]
</pre></p><p>To register a new user, we’ll first POST the username we wish to use.</p><p><pre class="brush: csharp">
var client = new WebClient();
 
//our uri to perform registration
var uri = new Uri(string.Format(&quot;http://{0}/api&quot;, HostnameTextBox.Text));
 
//create our registration object, along with username and description
var reg = new
{
    username = UsernameTextBox.Text,
    devicetype = &quot;Coding4Fun Hue Light Project&quot;
};
 
var jsonObj = JsonConvert.SerializeObject(reg);
 
 
//decide what to do with the response we get back from the bridge
client.UploadStringCompleted &#43;= (o, args) =] Dispatcher.BeginInvoke(() =]
{
    try
    {
        ResponseTextBox.Text = args.Result;
    }
    catch (Exception ex)
    {
        ResponseTextBox.Text = ex.Message;
    }
});
 
//Invoke a POST to the bridge
client.UploadStringAsync(uri, jsonObj);
</pre></p><p>Note the response we get back from our hub will be</p><p><pre class="brush: csharp">
[{&quot;error&quot;:{&quot;type&quot;:101,&quot;address&quot;:&quot;&quot;,&quot;description&quot;:&quot;link button not pressed&quot;}}]
</pre></p><p>This is because bridge requires you to first push the link button before new registrations can be made. After pushing the button and invoking the registration function again, you should receive the following result from the bridge:</p><p><pre class="brush: csharp">
[{&quot;success&quot;:{&quot;username&quot;:&quot;coding4fun&quot;}}]
</pre></p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/settingScreen%5B2%5D.png"><img title="settingScreen" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/settingScreen_thumb.png" alt="settingScreen" width="288" height="480" border="0"></a></p><p><strong>Setting the Bulb Color:</strong></p><p>We should now be able to access all methods on the bridge. You can get all of the configuration details, including all of the bulbs and their statuses with the same base url: <a href="http://192.168.1.100/api/coding4fun">http://192.168.1.100/api/coding4fun</a></p><p>Now comes the fun part. There are three color modes in which you can use to set the color of your bulbs:</p><ul><li><strong>hue &amp; sat:</strong> ‘hue’ is a color range between 0-65535 which represent 182.04*degrees, ‘sat’ is saturation with a range of 0-254 </li><li><strong>xy:</strong> are coordinates in the CIE 1931 space </li><li><strong>ct:</strong> is a color temperature expressed in mireds from 154 to 500, coolest to warmest respectfully </li></ul><p><em>Source: </em><a href="http://rsmck.co.uk/hue"><em>http://rsmck.co.uk/hue</em></a></p><p>We’ll be setting the colors of our bulbs using hue &amp; saturation parameters. Luckily, the Coding4Fun Toolkit for Windows Phone has three awesome color picker controls and some useful color extensions which makes setting the bulb colors a breeze. We start by building our state object – a list of parameters we want our bulb to be set to. Then we use the PUT verb to set the light with the following URL: http://{BRIGE-IPADDRESS}/api/coding4fun/lights/1/state</p><p>The “1” in the url is the 1-based index of the bulb you want to set.</p><p><pre class="brush: csharp">
//Get the HSV Value from the currently selected color
var hsv = LightColorSlider.Color.GetHSV();
 
//build our State object
var state = new
{
    on = true,
    hue = (int)(hsv.Hue * 182.04), //we convert the hue value into degrees by multiplying the value by 182.04
    sat = (int)(hsv.Saturation * 254)
};
 
//convert it to json:
var jsonObj = JsonConvert.SerializeObject(state);
 
//set the api url to set the state
var uri = new Uri(string.Format(&quot;http://{0}/api/{1}/lights/{2}/state&quot;, HostnameTextBox.Text, UsernameTextBox.Text, LightIndexTextBox.Text));
 
var client = new WebClient();
 
//decide what to do with the response we get back from the bridge
client.UploadStringCompleted &#43;= (o, args) =&gt; Dispatcher.BeginInvoke(() =&gt;
{
    try
    {
        ResponseTextBox.Text = args.Result;
    }
    catch (Exception ex)
    {
        ResponseTextBox.Text = ex.Message;
    }
     
});
 
//Invoke the PUT method to set the state of the bulb
client.UploadStringAsync(uri, &quot;PUT&quot;, jsonObj);
</pre></p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/colorScreen%5B2%5D.png"><img title="colorScreen" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/colorScreen_thumb.png" alt="colorScreen" width="288" height="480" border="0"></a></p><p>That’s it! Be sure to check out all of the other functions the (other functions the Hue API supports) at <a href="http://developers.meethue.com/index.html">http://developers.meethue.com/index.html</a></p><p><strong>Bio</strong>:<br><a href="http://channel9.msdn.com/Niners/unt1tled">Jarem Archer</a> is a self-taught Software Developer and UX Designer. He’s part of a small team at <a href="http://untitlednet.com">untitled network</a> who have a passion for video games, digital motion, entertainment and gadgets. Follow him on Twitter at <a href="http://twitter.com/unt1tled">http://twitter.com/unt1tled</a>.</p> <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/coding4fun/rss&WT.dl=0&WT.entryid=Entry:RSSView:5f2b34e566b542fb8fefa1860129d903">]]></description>
    <comments>http://channel9.msdn.com/coding4fun/articles/Philips-Hue-Lighting-Controller</comments>
    <link>http://channel9.msdn.com/coding4fun/articles/Philips-Hue-Lighting-Controller</link>
    <itunes:summary>So Philips recently introduced their Hue Connected Bulbs: an easy-to-use set of LED light bulbs and Wi-Fi connected bridge which allows you to dynamically change the color of your home lighting using their iOS or Android app. What’s particularly cool is that the bridge has a web API which you can access to set the colors of each bulb with your own app. We at untitled network developed our own Philips Hue app called Oni: light Control, which is&amp;nbsp;currently available on the Windows Phone Store. In addition to allowing you to set the color of your home lighting with defined “Moods”, the app also allows you to do the same using your phone’s built in voice commands or inexpensive NFC stickers. Here’s a demo of the Oni: Light Control in action:   I’m going to show you how you can develop your own app using the color picker from the Coding4Fun Toolkit for Windows Phone and the Json.Net library from Newtonsoft. These libraries can be found on NuGet, but you’ll obviously need the Philips Hue Connected Bulbs kit to test things out. Getting Started: The Philips Hue API uses a restful JSON interface you can access using any http client. Documentation on all of the supported methods by the Philips Hue bridge can be found at http://blog.ef.net/2012/11/02/philips-hue-api.html. To get started, you’ll need authorized access to your bridge’s API. Once the bridge has successfully established a network connection with your router, discover its internal IP address via the URL: http://www.meethue.com/api/nupnp You should get a response similar to: [{&amp;quot;id&amp;quot;:&amp;quot;ffss00fffe123456&amp;quot;,&amp;quot;internalipaddress&amp;quot;:&amp;quot;192.168.1.100&amp;quot;,&amp;quot;macaddress&amp;quot;:&amp;quot;0aa:bb:cc:dd:00:11&amp;quot;}]
 Note the internalipaddress value and use the IP to access the bridge’s API directly the with the URL http://192.168.1.100/api Now, since we haven’t registered a user for authorization, attempting to access the hub will return an error from the bridge: 
[{&amp;quot;error&amp;quot;:{&amp;quot;type</itunes:summary>
    <pubDate>Mon, 08 Apr 2013 15:17:51 GMT</pubDate>
    <guid isPermaLink="false">http://channel9.msdn.com/coding4fun/articles/Philips-Hue-Lighting-Controller</guid>
    <dc:creator>Clint Rutkas, Jarem Archer</dc:creator>
    <category>csharp</category>
    <category>hardware</category>
    <category>windows+phone</category>
  </item>
	<item>
    <title>Maelstrom</title>
    <description><![CDATA[<p><img src="http://files.channel9.msdn.com/thumbnail/c010a504-2675-4851-886c-ab6c060cd86a.jpg" alt=""></p><p>Introduced at <a href="http://www.buildwindows.com">//build/ 2012</a>, Maelstrom is Coding4Fun's latest creation.&nbsp; Step up to the podium and battle against your opponent in full-on stereoscopic 3D!&nbsp; Learn how it was made <a href="http://channel9.msdn.com/coding4fun/articles/Maelstrom-An-Overview">here</a>.</p><p><strong>How to Play</strong></p><p>Each player stands at a podium containing a 27&quot; touch-screen, 2 cameras mounted side-by-side for stereoscopic 3D, a rumble floor, and LED lighting.&nbsp; After some smack-talking to each other, players tap their screen to begin.&nbsp; After the countdown, a ball is launched into the arena.&nbsp; Players move their fingers around on the touch-screen to move the paddle in the 3D arena and return their opponent's volley.&nbsp; If the ball hits one of the glowing blue tiles, it will split into a maelstrom of 3 separate balls which will be tricky to handle.&nbsp; A player can also charge up their paddle by moving it quickly across the screen to send the ball flying back at their opponent in a quick burst.&nbsp; The first to score 7 points wins!&nbsp; If you can imagine what &quot;ridiculously over-engineered 3D Pong&quot; might look like, you can imagine Maelstrom!</p><p><strong>The Hardware</strong></p><p>Each game podium contains a <a href="http://www.lenovo.com/products/us/desktop/ideacentre/a-series/a720/">Lenovo A720</a> 27&quot; touch screen PC used to control the player's paddle.&nbsp; Lighting along the side rails reacts to the gameplay.&nbsp; Additionally, the platform under each player's feet rumbles thanks to a&nbsp;<a href="https://www.sparkfun.com/products/9715">Sparkfun MP3 Trigger</a> and bass boosters controlled with a <a href="http://netduino.com/">Netduino Plus</a>.&nbsp; The game is projected to a huge screen with an <a href="http://optomausa.com/products/detail/GT750E">Optoma GT750E</a> 3D projector and 3D shutter glasses.&nbsp; Each podium also contains two <a href="http://www.axis.com/products/cam_m1014/">Axis M1014</a> MJPEG cameras pointed at the player to complete the 3D experience.</p><p><strong>The Software</strong></p><p>The game is a Windows Store DirectX 11.1 game written in C&#43;&#43;.&nbsp; DX11.1 provides full stereoscopic 3D support for any 3D-capable display device, be it a projector, an LCD TV, or anything else.</p><p>The game controller is a C# / XAML Windows Store application which connects to the &quot;game console&quot; via a standard socket connection.&nbsp; The Netduino Plus corrdinates all of the hardware with a C# .NET Micro Framework application. &nbsp;All of these tie together into a seamless multiplayer experience!</p><p>Source code and an article on how we built it all will be coming soon on Coding4Fun...</p><p><strong>Video</strong></p><p>You can find a very quick video of the game being played at //build/ 2012 <a href="http://channel9.msdn.com/Blogs/BrianPeek/Maelstrom">here</a>.</p><p><strong>Photos</strong></p><p><strong><img src="http://files.channel9.msdn.com/thumbnail/6fb9a6fb-1915-456f-8881-152a50616ca1.jpg" alt=""></strong></p><p><img src="http://files.channel9.msdn.com/thumbnail/2b918810-9856-4ebf-81ae-9a126adbf77f.JPG" alt=""></p><p><img src="http://files.channel9.msdn.com/thumbnail/46356c8c-2d95-4267-8068-5e7e847177d3.JPG" alt=""></p><p><img src="http://files.channel9.msdn.com/thumbnail/db7c782f-8303-4a82-90d2-eeebcfe905f2.JPG" alt=""></p><p><strong>Attributions</strong></p><ul><li>Music track - <a href="http://soundcloud.com/neosvsatm/bullet">&quot;FatLoad- The Bullet(no master)&quot; by FreaK NeoS</a> </li><li>Sound effects &#43; music editing - <a href="http://davidwallimann.com/">David Wallimann</a> </li><li>DirectX shaders - <a href="http://geekswithblogs.net/mikebmcl/Default.aspx">Michael McLaughlin</a> </li></ul> <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/coding4fun/rss&WT.dl=0&WT.entryid=Project:RSSView:4df9cec1b71348b2afe6a0fa000d7be2">]]></description>
    <comments>http://channel9.msdn.com/coding4fun/projects/Maelstrom</comments>
    <link>http://channel9.msdn.com/coding4fun/projects/Maelstrom</link>
    <itunes:summary> Introduced at //build/ 2012, Maelstrom is Coding4Fun&#39;s latest creation.&amp;nbsp; Step up to the podium and battle against your opponent in full-on stereoscopic 3D!&amp;nbsp; Learn how it was made here. How to Play Each player stands at a podium containing a 27&amp;quot; touch-screen, 2 cameras mounted side-by-side for stereoscopic 3D, a rumble floor, and LED lighting.&amp;nbsp; After some smack-talking to each other, players tap their screen to begin.&amp;nbsp; After the countdown, a ball is launched into the arena.&amp;nbsp; Players move their fingers around on the touch-screen to move the paddle in the 3D arena and return their opponent&#39;s volley.&amp;nbsp; If the ball hits one of the glowing blue tiles, it will split into a maelstrom of 3 separate balls which will be tricky to handle.&amp;nbsp; A player can also charge up their paddle by moving it quickly across the screen to send the ball flying back at their opponent in a quick burst.&amp;nbsp; The first to score 7 points wins!&amp;nbsp; If you can imagine what &amp;quot;ridiculously over-engineered 3D Pong&amp;quot; might look like, you can imagine Maelstrom! The Hardware Each game podium contains a Lenovo A720 27&amp;quot; touch screen PC used to control the player&#39;s paddle.&amp;nbsp; Lighting along the side rails reacts to the gameplay.&amp;nbsp; Additionally, the platform under each player&#39;s feet rumbles thanks to a&amp;nbsp;Sparkfun MP3 Trigger and bass boosters controlled with a Netduino Plus.&amp;nbsp; The game is projected to a huge screen with an Optoma GT750E 3D projector and 3D shutter glasses.&amp;nbsp; Each podium also contains two Axis M1014 MJPEG cameras pointed at the player to complete the 3D experience. The Software The game is a Windows Store DirectX 11.1 game written in C&amp;#43;&amp;#43;.&amp;nbsp; DX11.1 provides full stereoscopic 3D support for any 3D-capable display device, be it a projector, an LCD TV, or anything else. The game controller is a C# / XAML Windows Store application which connects to the &amp;quot;game console&amp;quot; via a standard socket connection.&amp;nbsp; T</itunes:summary>
    <pubDate>Fri, 09 Nov 2012 19:13:00 GMT</pubDate>
    <guid isPermaLink="false">http://channel9.msdn.com/coding4fun/projects/Maelstrom</guid>
    <dc:creator>Brian Peek, Clint Rutkas, Dan Fernandez, Rick Barraza</dc:creator>
    <category>csharp</category>
    <category>c++</category>
    <category>coding4fun</category>
    <category>directx-11</category>
    <category>hardware</category>
    <category>xaml</category>
    <category>windows+8</category>
  </item>
	<item>
    <title>Project Detroit: OBD-II Manager</title>
    <description><![CDATA[<p>Read diagnostic information from your car and display it on a slick instrument cluster dashboard!</p><p>The <a href="http://obd.codeplex.com/"><strong>OBD-II Manager</strong></a> project is the OBD-II sub-system and instrument cluster application from the <a href="http://channel9.msdn.com/coding4fun/detroit">Project Detroit Mustang</a> we built with West Coast Customs.&nbsp; If you're not familiar with this project, you can find out more about it <a href="http://channel9.msdn.com/coding4fun/detroit">here</a> and <a href="http://channel9.msdn.com/Blogs/Vector/The-400-horsepower-device">here</a>.</p><p>OBD stands for On-Board Diagnostics.&nbsp; In the world of cars, this can be thought of as the computer which has a variety of data points which can be queried, such as speed, fuel level, and even trouble codes that relate to the check engine light.&nbsp; If you've ever taken your car in for service, your service center has hooked up the car to a computer via the OBD port to get the status of the car and what may not be working properly.&nbsp;</p><p>This project contains a library you can use to integrate OBD data into your application, as well as a modified version of the actual Instrument Cluster application used in the Project Detroit car which shows how the library can be used.</p><p><strong>More Information</strong></p><ul><li><a href="http://channel9.msdn.com/coding4fun/articles/Project-Detroit-How-to-Read-Your-Cars-Engine-Data-with-OBD-II">Coding4Fun Article</a> </li><li><a href="http://channel9.msdn.com/coding4fun/detroit">Project Detroit</a> </li><li><a href="http://www.scantool.net/scan-tools/pc-based/obdlink-sx.html">OBD-II to USB cable</a> (ELM323/327-based OBD-II to USB cable) </li><li><a href="http://en.wikipedia.org/wiki/OBD-II#OBD-II">More information on OBD-II</a> </li><li><a href="http://elmelectronics.com/DSheets/ELM327DS.pdf">ELM323/327 Datasheet</a> </li></ul><p><strong>Instrument Cluster Screenshots</strong></p><p><a href="http://files.channel9.msdn.com/thumbnail/b964d3a7-3494-4f60-9ffd-98e10f57cfdc.png" rel="lightbox"><img src="http://files.channel9.msdn.com/thumbnail/b964d3a7-3494-4f60-9ffd-98e10f57cfdc.png" alt=""></a></p><p><a href="http://files.channel9.msdn.com/thumbnail/ffbfa48f-e04b-400d-a79d-058641ed3642.png" rel="lightbox"><img src="http://files.channel9.msdn.com/thumbnail/ffbfa48f-e04b-400d-a79d-058641ed3642.png" alt=""></a></p><p><a href="http://files.channel9.msdn.com/thumbnail/a77f1db4-746d-4743-8e1b-9f0cc5618a84.png" rel="lightbox"><img src="http://files.channel9.msdn.com/thumbnail/a77f1db4-746d-4743-8e1b-9f0cc5618a84.png" alt=""></a></p> <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/coding4fun/rss&WT.dl=0&WT.entryid=Project:RSSView:4afca774455e450bbbd8a02e013f8ee0">]]></description>
    <comments>http://channel9.msdn.com/coding4fun/projects/Project-Detroit-OBD-II-Manager</comments>
    <link>http://channel9.msdn.com/coding4fun/projects/Project-Detroit-OBD-II-Manager</link>
    <itunes:summary>Read diagnostic information from your car and display it on a slick instrument cluster dashboard! The OBD-II Manager project is the OBD-II sub-system and instrument cluster application from the Project Detroit Mustang we built with West Coast Customs.&amp;nbsp; If you&#39;re not familiar with this project, you can find out more about it here and here. OBD stands for On-Board Diagnostics.&amp;nbsp; In the world of cars, this can be thought of as the computer which has a variety of data points which can be queried, such as speed, fuel level, and even trouble codes that relate to the check engine light.&amp;nbsp; If you&#39;ve ever taken your car in for service, your service center has hooked up the car to a computer via the OBD port to get the status of the car and what may not be working properly.&amp;nbsp; This project contains a library you can use to integrate OBD data into your application, as well as a modified version of the actual Instrument Cluster application used in the Project Detroit car which shows how the library can be used. More Information Coding4Fun Article Project Detroit OBD-II to USB cable (ELM323/327-based OBD-II to USB cable) More information on OBD-II ELM323/327 Datasheet Instrument Cluster Screenshots    </itunes:summary>
    <pubDate>Mon, 09 Apr 2012 19:23:00 GMT</pubDate>
    <guid isPermaLink="false">http://channel9.msdn.com/coding4fun/projects/Project-Detroit-OBD-II-Manager</guid>
    <dc:creator>Brian Peek, Dan Fernandez</dc:creator>
    <category>coding4fun</category>
    <category>hardware</category>
    <category>project+detroit</category>
  </item>
	<item>
    <title>BoxingBots: Kinect-Driven Pneumatic Boxing Robots</title>
    <description><![CDATA[<p><a title="Boxing Robots!" href="http://files.channel9.msdn.com/wlwimages/ae054c0b4d7b402ab1239e6800c0220f/IMG_0296%5B5%5D.jpg" rel="lightbox"><img title="IMG_0296" src="http://files.channel9.msdn.com/wlwimages/ae054c0b4d7b402ab1239e6800c0220f/IMG_0296_thumb%5B2%5D.jpg" alt="IMG_0296" width="640" height="480" border="0"></a></p><p>At the SXSW Interactive Opening Party hosted by Frog Design and Microsoft, the Coding4Fun team has unveiled their latest invention, BoxingBots!</p><p>With BoxingBots you are the controller except this time, forget the screen. You’re controlling a 6-foot tall metal robot that’s trying to punch out your opponent’s 6-foot tall machine. It’s Real Steel in real time.</p><h3>Video Demo</h3><p>Watch Laura Foy's video of the <a href="http://channel9.msdn.com/posts/Boxing-Bots-at-South-by-South-West">BoxingBots in action</a>!</p><p>BoxingBots combines Kinect’s motion sensing technology with pneumatic robots in a 6-foot square ring. Two players face off to try to knock each other’s blocks off.</p><h3>Each robot has</h3><ul><li>1 On-board laptop PC </li><li>70 programmatic LEDs in the head and chest controlled by a Phidgets LED controller board </li><li>2 2.5 gallon tanks of compressed air @ 150 PSI </li><li>8 12-volt 17amp batteries </li><li>2 Roboteq motor controllers that power the four omni-directional wheels </li><li>2 5&quot; stroke cylinders that punches/retracts the arms </li><li>1 6' stroke cylinder that lifts the head when the robot is knocked out </li><li>2 button switches on the chest that are triggered by punches and a Phidget 8/8/8 interface board that controls the relays and buttons switches </li></ul><p>&nbsp;</p><h3>How gameplay happens</h3><ul><li>Each robot's on-board PC receive commands over the network from the Admin PC for movement, punches, score, etc </li><li>Each player stands in front of a Kinect for Windows-enabled PC that interprets their gestures (punch, move in a direction, strafe, rotate) and sends that as a command to the Admin PC </li><li>The Admin PC manages the game, including pausing, reset, starting, sending commands to the robots and receiving damage data from the robots when the robot has been punched </li></ul><p>&nbsp;</p><h3>Photos</h3><p>&nbsp;</p><p><a href="http://files.channel9.msdn.com/wlwimages/ae054c0b4d7b402ab1239e6800c0220f/IMG_0290%5B5%5D.jpg"><img title="IMG_0290" src="http://files.channel9.msdn.com/wlwimages/ae054c0b4d7b402ab1239e6800c0220f/IMG_0290_thumb%5B2%5D.jpg" alt="IMG_0290" width="360" height="480"></a></p><p>&nbsp;</p><p>&nbsp;</p><p><a href="http://files.channel9.msdn.com/wlwimages/ae054c0b4d7b402ab1239e6800c0220f/IMG_0291%5B5%5D.jpg"><img title="IMG_0291" src="http://files.channel9.msdn.com/wlwimages/ae054c0b4d7b402ab1239e6800c0220f/IMG_0291_thumb%5B2%5D.jpg" alt="IMG_0291" width="640" height="480" border="0"></a></p><p><a href="http://files.channel9.msdn.com/wlwimages/ae054c0b4d7b402ab1239e6800c0220f/IMG_0292%5B5%5D.jpg"><img title="IMG_0292" src="http://files.channel9.msdn.com/wlwimages/ae054c0b4d7b402ab1239e6800c0220f/IMG_0292_thumb%5B2%5D.jpg" alt="IMG_0292" width="640" height="480" border="0"></a></p><p><a href="http://files.channel9.msdn.com/wlwimages/ae054c0b4d7b402ab1239e6800c0220f/IMG_0295%5B7%5D.jpg"><img title="IMG_0295" src="http://files.channel9.msdn.com/wlwimages/ae054c0b4d7b402ab1239e6800c0220f/IMG_0295_thumb%5B1%5D.jpg" alt="IMG_0295" width="640" height="480" border="0"></a></p><p><a href="http://files.channel9.msdn.com/wlwimages/ae054c0b4d7b402ab1239e6800c0220f/IMG_0298%5B3%5D.jpg"><img title="IMG_0298" src="http://files.channel9.msdn.com/wlwimages/ae054c0b4d7b402ab1239e6800c0220f/IMG_0298_thumb.jpg" alt="IMG_0298" width="640" height="480" border="0"></a></p><p><a href="http://files.channel9.msdn.com/wlwimages/ae054c0b4d7b402ab1239e6800c0220f/IMG_0300%5B3%5D.jpg"><img title="IMG_0300" src="http://files.channel9.msdn.com/wlwimages/ae054c0b4d7b402ab1239e6800c0220f/IMG_0300_thumb.jpg" alt="IMG_0300" width="640" height="480" border="0"></a></p> <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/coding4fun/rss&WT.dl=0&WT.entryid=Project:RSSView:d7eb062302294149a870a011001cbec0">]]></description>
    <comments>http://channel9.msdn.com/coding4fun/projects/BoxingBots</comments>
    <link>http://channel9.msdn.com/coding4fun/projects/BoxingBots</link>
    <itunes:summary> At the SXSW Interactive Opening Party hosted by Frog Design and Microsoft, the Coding4Fun team has unveiled their latest invention, BoxingBots! With BoxingBots you are the controller except this time, forget the screen. You’re controlling a 6-foot tall metal robot that’s trying to punch out your opponent’s 6-foot tall machine. It’s Real Steel in real time. Video DemoWatch Laura Foy&#39;s video of the BoxingBots in action! BoxingBots combines Kinect’s motion sensing technology with pneumatic robots in a 6-foot square ring. Two players face off to try to knock each other’s blocks off. Each robot has1 On-board laptop PC 70 programmatic LEDs in the head and chest controlled by a Phidgets LED controller board 2 2.5 gallon tanks of compressed air @ 150 PSI 8 12-volt 17amp batteries 2 Roboteq motor controllers that power the four omni-directional wheels 2 5&amp;quot; stroke cylinders that punches/retracts the arms 1 6&#39; stroke cylinder that lifts the head when the robot is knocked out 2 button switches on the chest that are triggered by punches and a Phidget 8/8/8 interface board that controls the relays and buttons switches &amp;nbsp; How gameplay happensEach robot&#39;s on-board PC receive commands over the network from the Admin PC for movement, punches, score, etc Each player stands in front of a Kinect for Windows-enabled PC that interprets their gestures (punch, move in a direction, strafe, rotate) and sends that as a command to the Admin PC The Admin PC manages the game, including pausing, reset, starting, sending commands to the robots and receiving damage data from the robots when the robot has been punched &amp;nbsp; Photos&amp;nbsp;  &amp;nbsp; &amp;nbsp;      </itunes:summary>
    <pubDate>Sun, 11 Mar 2012 02:00:00 GMT</pubDate>
    <guid isPermaLink="false">http://channel9.msdn.com/coding4fun/projects/BoxingBots</guid>
    <dc:creator>Brian Peek, Clint Rutkas, Dan Fernandez, Rick Barraza</dc:creator>
  </item>    
</channel>
</rss>