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

<channel>
	<title>WiredPrairie &#187; Coding</title>
	<atom:link href="http://www.wiredprairie.us/blog/index.php/archives/category/coding/feed" rel="self" type="application/rss+xml" />
	<link>http://www.wiredprairie.us/blog</link>
	<description>A little bit of everything: software, apps, usability, programming, design and whatever else</description>
	<lastBuildDate>Sun, 05 Feb 2012 23:36:56 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>WPF &amp;  System.Windows.Baml2006.TypeConverterMarkupExtension &quot;The image format is unrecognized&quot;</title>
		<link>http://www.wiredprairie.us/blog/index.php/archives/1528</link>
		<comments>http://www.wiredprairie.us/blog/index.php/archives/1528#comments</comments>
		<pubDate>Sun, 05 Feb 2012 23:36:56 +0000</pubDate>
		<dc:creator>Aaron</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[WPF]]></category>

		<guid isPermaLink="false">http://www.wiredprairie.us/blog/?p=1528</guid>
		<description><![CDATA[If you recently added an icon to your WPF project (any .NET version, including .NET 3.5, and .NET 4.0) and it has support for an alpha channel (often referred to as the Vista icon format), stop. Why? Your WPF application won’t run on the latest service pack of XP as it’s not capable of decoding [...]]]></description>
			<content:encoded><![CDATA[<p><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: right; border-top: 0px; border-right: 0px; padding-top: 0px" title="SNAGHTML4534e6a2" border="0" alt="SNAGHTML4534e6a2" align="right" src="http://www.wiredprairie.us/blog/wp-content/uploads/2012/02/SNAGHTML4534e6a2.png" width="242" height="216" />If you recently added an icon to your WPF project (any .NET version, including .NET 3.5, and .NET 4.0) and it has support for an alpha channel (often referred to as the Vista icon format), <strong>stop</strong>. Why? Your WPF application won’t run on the latest service pack of XP as it’s not capable of decoding the format unfortunately. It’s a very frustrating error and a stupid &quot;feature that Microsoft overlooked. I’ve hit this a few times unfortunately. </p>
<p>To fix, remove all of the alpha channel images from the ICO file and recompile.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.wiredprairie.us/blog/index.php/archives/1528/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Alternative to ApplicationSettings in .NET</title>
		<link>http://www.wiredprairie.us/blog/index.php/archives/1524</link>
		<comments>http://www.wiredprairie.us/blog/index.php/archives/1524#comments</comments>
		<pubDate>Wed, 01 Feb 2012 13:52:31 +0000</pubDate>
		<dc:creator>Aaron</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[Settings]]></category>
		<category><![CDATA[WinForms]]></category>
		<category><![CDATA[WPF]]></category>

		<guid isPermaLink="false">http://www.wiredprairie.us/blog/?p=1524</guid>
		<description><![CDATA[After dealing with lost settings, an unclear upgrade path, and my own confusion surrounding the magic of Settings in a .NET client application, I decided to build my own. You’re probably familiar with this UI in Visual Studio. It hasn’t changed much since it was first created: A list of properties, data type, scope and [...]]]></description>
			<content:encoded><![CDATA[<p>After dealing with lost settings, an unclear upgrade path, and my own confusion surrounding the magic of <a href="http://msdn.microsoft.com/en-us/library/system.configuration.applicationsettingsbase.aspx">Settings</a> in a .NET client application, I decided to build my own. </p>
<p>You’re probably familiar with this UI in Visual Studio. It hasn’t changed much since it was first created:</p>
<p><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto; padding-top: 0px" title="image" border="0" alt="image" src="http://www.wiredprairie.us/blog/wp-content/uploads/2012/02/image.png" width="420" height="322" /></p>
<p>A list of properties, data type, scope and a default value. Admittedly, it makes things simple. However, with my WPF .NET application that I created a few years ago (<a href="http://www.wiredprairie.us/SnugUp/">SnugUp</a>), I’ve always been troubled by the magic of the settings. It was too easy to get in a situation where a user would loose their settings doing uninstalls, reinstalls, upgrades. </p>
<p>While I’m sure it’s possible to make the built in settings classes to work, it wasn’t worth the effort for me to understand them and learn what the nuances of where they’re placed, how to do a decent upgrade, how not to loose them, etc. </p>
<p>In the SnugUp WPF UI, the code uses a two-way bindings to directly edit the settings of the application (like: &quot;{Binding AppSettings.DebugMode}&quot;). It was simple, and all I needed. It’s handy that ApplicationSettingsBase implements the INotifyPropertyChanged interface which WPF needs for simple two-way data bindings.</p>
<p>My solution, which I admit is heavier than the original as it requires a large additional assembly is to use <a href="http://james.newtonking.com/pages/json-net.aspx">JSON.NET</a> as the serializer/deserializer for a new settings class I created.</p>
<p>So, the basic pattern:</p>
<div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper">
<div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet">
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum1">   1:</span> <span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> ApplicationSettings : INotifyPropertyChanged</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum2">   2:</span> {</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum3">   3:</span>     <span style="color: #0000ff">public</span> <span style="color: #0000ff">event</span> PropertyChangedEventHandler PropertyChanged;</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum4">   4:</span>&#160; </pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum5">   5:</span>     <span style="color: #0000ff">private</span> <span style="color: #0000ff">bool</span> _debugMode;</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum6">   6:</span>     <span style="color: #0000ff">private</span> <span style="color: #0000ff">string</span> _albumNameFormat;</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum7">   7:</span>     <span style="color: #0000ff">private</span> <span style="color: #0000ff">string</span> _extraFileExtensions;</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum8">   8:</span>     <span style="color: #0000ff">private</span> <span style="color: #0000ff">bool</span> _automaticRun;</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum9">   9:</span>     <span style="color: #0000ff">private</span> <span style="color: #0000ff">string</span> _galleryCreationSubCategory;</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum10">  10:</span>     <span style="color: #0000ff">private</span> <span style="color: #0000ff">bool</span> _filenameOnlyCheck;</pre>
<p><!--CRLF--></div>
</div>
<p>Properties created the standard way for INotifyPropertyChaged:</p>
<div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper">
<div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet">
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum1">   1:</span> <span style="color: #0000ff">private</span> DateTime _nextUpdateCheck;</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum2">   2:</span> <span style="color: #0000ff">public</span> DateTime NextUpdateCheck</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum3">   3:</span> {</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum4">   4:</span>     get { <span style="color: #0000ff">return</span> _nextUpdateCheck; }</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum5">   5:</span>     set</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum6">   6:</span>     {</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum7">   7:</span>         <span style="color: #0000ff">if</span> (_nextUpdateCheck != <span style="color: #0000ff">value</span>)</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum8">   8:</span>         {</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum9">   9:</span>             _nextUpdateCheck = <span style="color: #0000ff">value</span>;</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum10">  10:</span>             RaisePropertyChanged(<span style="color: #006080">&quot;NextUpdateCheck&quot;</span>);</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum11">  11:</span>         }</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum12">  12:</span>     }</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum13">  13:</span> }</pre>
<p><!--CRLF--></div>
</div>
<p>I wanted a predictable path for storing settings (so it would be easy to document and backup for users). I used the AssemblyCompany attribute and the AssemblyProduct attribute as the folder names:</p>
<div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper">
<div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet">
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum1">   1:</span> <span style="color: #0000ff">internal</span> <span style="color: #0000ff">static</span> <span style="color: #0000ff">string</span> GetSettingsDirectory()</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum2">   2:</span> {</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum3">   3:</span>     <span style="color: #0000ff">string</span> path = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum4">   4:</span>     var attrs = Assembly.GetEntryAssembly().GetCustomAttributes(<span style="color: #0000ff">typeof</span>(AssemblyCompanyAttribute), <span style="color: #0000ff">false</span>);</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum5">   5:</span>     <span style="color: #0000ff">if</span> (attrs.Length == 1)</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum6">   6:</span>     {</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum7">   7:</span>         path = Path.Combine(path, ((AssemblyCompanyAttribute)attrs[0]).Company);</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum8">   8:</span>&#160; </pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum9">   9:</span>     }</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum10">  10:</span>     attrs = Assembly.GetEntryAssembly().GetCustomAttributes(<span style="color: #0000ff">typeof</span>(AssemblyProductAttribute), <span style="color: #0000ff">false</span>);</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum11">  11:</span>     <span style="color: #0000ff">if</span> (attrs.Length == 1)</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum12">  12:</span>     {</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum13">  13:</span>         path = Path.Combine(path, ((AssemblyProductAttribute)attrs[0]).Product);</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum14">  14:</span>     }</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum15">  15:</span>     <span style="color: #0000ff">return</span> path;              </pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum16">  16:</span> }</pre>
<p><!--CRLF--></div>
</div>
<p>In this WPF application, in the AssemblyInfo.cs file, the attributes are set as follows:</p>
<div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper">
<div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet">
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum1">   1:</span> [assembly: AssemblyCompany(<span style="color: #006080">&quot;WiredPrairie.us&quot;</span>)]</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum2">   2:</span> [assembly: AssemblyProduct(<span style="color: #006080">&quot;SnugUp&quot;</span>)]</pre>
<p><!--CRLF--></div>
</div>
<p>On my machine, that maps to this path:</p>
<p><strong>d:\Users\Aaron\AppData\Roaming\WiredPrairie.us\SnugUp\</strong></p>
<p>Loading settings then is straightforward using JSON.NET:</p>
<div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper">
<div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet">
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum1">   1:</span> <span style="color: #0000ff">public</span> <span style="color: #0000ff">static</span> ApplicationSettings Load(<span style="color: #0000ff">string</span> filename)</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum2">   2:</span> {</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum3">   3:</span>     ApplicationSettings settings = <span style="color: #0000ff">null</span>;</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum4">   4:</span>     var directory = GetSettingsDirectory();</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum5">   5:</span>     var path = Path.Combine(directory, filename);</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum6">   6:</span>&#160; </pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum7">   7:</span>     <span style="color: #0000ff">if</span> (File.Exists(path))</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum8">   8:</span>     {</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum9">   9:</span>         <span style="color: #0000ff">string</span> fileData = File.ReadAllText(path);</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum10">  10:</span>         <span style="color: #0000ff">try</span></pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum11">  11:</span>         {</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum12">  12:</span>             settings = JsonConvert.DeserializeObject&lt;ApplicationSettings&gt;(fileData, <span style="color: #0000ff">new</span> JsonSerializerSettings { });</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum13">  13:</span>         }</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum14">  14:</span>         <span style="color: #0000ff">catch</span> { }</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum15">  15:</span>     }</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum16">  16:</span>     <span style="color: #0000ff">if</span> (settings == <span style="color: #0000ff">null</span>)</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum17">  17:</span>     {</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum18">  18:</span>         settings = <span style="color: #0000ff">new</span> ApplicationSettings();</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum19">  19:</span>         SetDefaults(settings);</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum20">  20:</span>         <span style="color: #008000">// initialize settings once</span></pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum21">  21:</span>         Save(settings, filename);</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum22">  22:</span>     }</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum23">  23:</span>     <span style="color: #0000ff">return</span> settings;</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum24">  24:</span> }</pre>
<p><!--CRLF--></div>
</div>
<p>In my code, if the settings file didn’t exist or fails to serialize into something meaningful, a new settings file is created with a few defaults. (I haven’t decided what to do when there’s an exception when reading the file, hence the empty catch).</p>
<p>Saving the settings is just as easy:</p>
<div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper">
<div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet">
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum1">   1:</span> <span style="color: #0000ff">public</span> <span style="color: #0000ff">static</span> <span style="color: #0000ff">void</span> Save(ApplicationSettings settings, <span style="color: #0000ff">string</span> filename)</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum2">   2:</span> {</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum3">   3:</span>     Debug.Assert(settings != <span style="color: #0000ff">null</span>);</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum4">   4:</span>     var directory = GetSettingsDirectory();</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum5">   5:</span>     var path = Path.Combine(directory, filename);</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum6">   6:</span>&#160; </pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum7">   7:</span>     JsonConvert.SerializeObject(settings);</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum8">   8:</span>&#160; </pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum9">   9:</span>     <span style="color: #0000ff">if</span> (!Directory.Exists(directory))</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum10">  10:</span>     {</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum11">  11:</span>         Directory.CreateDirectory(directory);</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum12">  12:</span>     }</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum13">  13:</span>&#160; </pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum14">  14:</span>     var fileData = JsonConvert.SerializeObject(settings, Formatting.Indented, <span style="color: #0000ff">new</span> JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore, DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate });</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum15">  15:</span>     <span style="color: #0000ff">try</span></pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum16">  16:</span>     {</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum17">  17:</span>         <span style="color: #0000ff">using</span> (StreamWriter writer = File.CreateText(path))</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum18">  18:</span>         {</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum19">  19:</span>             writer.Write(fileData);</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum20">  20:</span>             writer.Close();</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum21">  21:</span>         }</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum22">  22:</span>     }</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum23">  23:</span>     <span style="color: #0000ff">catch</span> { }</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum24">  24:</span> }</pre>
<p><!--CRLF--></div>
</div>
<p>The SerializeObject method returns a string which is then written to a file using a StreamWriter. </p>
<p>I added a Save method to the instance of the ApplicationSettings:</p>
<div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper">
<div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet">
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum1">   1:</span> <span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> Save()</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum2">   2:</span> {</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum3">   3:</span>     ApplicationSettings.Save(<span style="color: #0000ff">this</span>);</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum4">   4:</span> }</pre>
<p><!--CRLF--></div>
</div>
<p>This preserved the functionality that exists in the built in Settings support in .NET (which was being used in my application). </p>
<p>By keeping all of the property names the same and making a few tweaks to the types of some fields in my application, I had swapped out the entire “settings” infrastructure in about 45 minutes. </p>
<p>I’m planning some other JSON activities within my application, so the overhead of using JSON.NET is acceptable. </p>
<p>The best part of this alternative is that there isn’t any magic. It’s all easy to manage. Further, I can easily modify my installer to properly handle/update, etc., the settings file with just a few clicks. </p>
<p>I’m not going back to the built-in .NET settings support again. I’ve learned my lesson.&#160; <img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://www.wiredprairie.us/blog/wp-content/uploads/2012/02/wlEmoticon-smile.png" /></p>
<p>What have you done for “user” settings?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.wiredprairie.us/blog/index.php/archives/1524/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>.NET API for Nest Thermostat</title>
		<link>http://www.wiredprairie.us/blog/index.php/archives/1449</link>
		<comments>http://www.wiredprairie.us/blog/index.php/archives/1449#comments</comments>
		<pubDate>Tue, 10 Jan 2012 02:50:22 +0000</pubDate>
		<dc:creator>Aaron</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[General]]></category>
		<category><![CDATA[API]]></category>
		<category><![CDATA[CSharp]]></category>
		<category><![CDATA[Nest]]></category>
		<category><![CDATA[Thermostat]]></category>

		<guid isPermaLink="false">http://www.wiredprairie.us/blog/?p=1449</guid>
		<description><![CDATA[I just finished a preliminary read-only (think version 0.1) wrapper around the Nest Thermostat API that is used by their mobile phone and web applications. As Nest doesn’t have a formal API yet, the code could break at any time and may not be suitable for any use. However, it is working today. The project [...]]]></description>
			<content:encoded><![CDATA[<p>I just finished a preliminary <strong>read-only</strong> (think version 0.1) wrapper around the Nest Thermostat API that is used by their mobile phone and web applications. As Nest doesn’t have a formal API yet, the code could break at any time and may not be suitable for any use. However, it is working today. <img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://www.wiredprairie.us/blog/wp-content/uploads/2012/01/wlEmoticon-smile3.png" /></p>
<p>The project is hosted on <a href="https://github.com/wiredprairie/Nest-Thermostat-DotNET-API">GitHub</a>. It uses <a href="http://james.newtonking.com/pages/json-net.aspx">JSON.NET</a> for parsing the return values from the Nest servers.</p>
<p>There are three projects, with the lib containing the assembly that is used by the two test applications. One is a console app and the other a simple WPF application:</p>
<p><a href="http://www.wiredprairie.us/blog/wp-content/uploads/2012/01/SNAGHTML88bff0b3.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="SNAGHTML88bff0b3" border="0" alt="SNAGHTML88bff0b3" src="http://www.wiredprairie.us/blog/wp-content/uploads/2012/01/SNAGHTML88bff0b3_thumb.png" width="424" height="332" /></a></p>
<p>(My thermostats are named Zero, One, and Two).</p>
<p>If there’s interest, I plan on adding some methods to the library which allow modification of data (such as the current temperature), and ideally, support for live updates from the devices if I can make sense of the data that is <a href="http://www.wiredprairie.us/blog/index.php/archives/1442">returned</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.wiredprairie.us/blog/index.php/archives/1449/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Nest Thermostat API/Protocol</title>
		<link>http://www.wiredprairie.us/blog/index.php/archives/1442</link>
		<comments>http://www.wiredprairie.us/blog/index.php/archives/1442#comments</comments>
		<pubDate>Sun, 08 Jan 2012 17:21:05 +0000</pubDate>
		<dc:creator>Aaron</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[General]]></category>
		<category><![CDATA[API]]></category>
		<category><![CDATA[Nest]]></category>
		<category><![CDATA[Protocol]]></category>
		<category><![CDATA[Thermostat]]></category>

		<guid isPermaLink="false">http://www.wiredprairie.us/blog/?p=1442</guid>
		<description><![CDATA[While Nest Labs hasn’t released a formal (documented &#38; supported) API, I thought I’d do a bit of digging to see how they’re using the network and what might be achievable. A few things are going on, the majority as you’d probably expect. The web interface is using a long polling technique apparently to watch [...]]]></description>
			<content:encoded><![CDATA[<p>While Nest Labs hasn’t released a formal (documented &amp; supported) API, I thought I’d do a bit of digging to see how they’re using the network and what might be achievable.</p>
<p>A few things are going on, the majority as you’d probably expect.</p>
<p>The web interface is using a long polling technique apparently to watch for updates to the schedule, temperature, etc. </p>
<p><a href="http://www.wiredprairie.us/blog/wp-content/uploads/2012/01/image7.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: block; float: none; margin-left: auto; border-top: 0px; margin-right: auto; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.wiredprairie.us/blog/wp-content/uploads/2012/01/image_thumb7.png" width="381" height="225" /></a></p>
<p>I haven’t determined what the frequency is though, or the wait time. It’s very inconsistent, even when I wouldn’t expect much new “live” data to be available on the network, it frequently updates and polls again.</p>
<p>There are a few constants set in the HOME page script:</p>
<pre class="csharpcode">C.ABSENT_USER_THRESHOLD     = +(<span class="str">'300'</span>) || 0;  <span class="rem">// seconds</span>
C.DEAD_DEVICE_THRESHOLD     = +(<span class="str">'300'</span>) || 0;  <span class="rem">// seconds</span>
C.pollingInterval           = +(<span class="str">'2500'</span>) || 0;       <span class="rem">// ms</span>
C.WEATHER_POLLING_INTERVAL  = +(<span class="str">'120000'</span>) || 0; <span class="rem">// ms</span></pre>
<style type="text/css">
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
<p>If the C.pollingInterval value were for the subscribe endpoint mentioned above, I’d see a LOT more calls than I do – so I’m still not clear how the polling interval is decided.</p>
<p>The API calls, for the most part are using JSONP syntax over an HTTPS connection.</p>
<p>The most frequent request is to “subscribe.” It sends as part of the GET request a large block of encoded JSON (using encodeURIComponent and then JSON.stringify). </p>
<p>I&#8217;m not familiar with the key/value system that they’re using (it may just be something they’ve constructed in-house – although given the number of <a href="http://www.wiredprairie.us/blog/index.php/archives/1397">open source JavaScript</a> libraries they’re using, I thought someone might recognize it):</p>
<p>“<strong>key</strong>”, “{<strong>actualkey</strong>}.{<strong>value</strong>}”</p>
<p>I don’t understand why they’ve redundantly specified “key” in a list of keys when it’s evident that the <em>actual key<strong> </strong></em>is contained within the value as a delimited string. It’s more data to send and more data to parse this way. So, again, maybe it’s based on some DB or model system I’m not familiar with. (Anyone recognize it?)</p>
<p>I’ve substituted the actual values (as they are serial numbers of my devices) with text representations of what the value represented below:</p>
<pre class="csharpcode">{<span class="str">&quot;keys&quot;</span>:
    [{<span class="str">&quot;key&quot;</span>:<span class="str">&quot;user.#USERID#&quot;</span>,
        <span class="str">&quot;version&quot;</span>:209478897,<span class="str">&quot;timestamp&quot;</span>:1324159145000},
    {<span class="str">&quot;key&quot;</span>:<span class="str">&quot;user_alert_dialog.#USERID#&quot;</span>,
        <span class="str">&quot;version&quot;</span>:-1320296685,<span class="str">&quot;timestamp&quot;</span>:1325967612000},
    {<span class="str">&quot;key&quot;</span>:<span class="str">&quot;structure.#STRUCTURE-GUID#&quot;</span>,
        <span class="str">&quot;version&quot;</span>:656192675,<span class="str">&quot;timestamp&quot;</span>:1325967612000},
    {<span class="str">&quot;key&quot;</span>:<span class="str">&quot;device.#DEVICE 1 SERIAL NUMBER#&quot;</span>,
        <span class="str">&quot;version&quot;</span>:1485027516,<span class="str">&quot;timestamp&quot;</span>:1326034984000},
    {<span class="str">&quot;key&quot;</span>:<span class="str">&quot;shared.#DEVICE 1 SERIAL NUMBER#&quot;</span>,
        <span class="str">&quot;version&quot;</span>:588844038,<span class="str">&quot;timestamp&quot;</span>:1326034818000},
    {<span class="str">&quot;key&quot;</span>:<span class="str">&quot;schedule.#DEVICE 1 SERIAL NUMBER#&quot;</span>,
        <span class="str">&quot;version&quot;</span>:1187107985,<span class="str">&quot;timestamp&quot;</span>:1326005677000},
    {<span class="str">&quot;key&quot;</span>:<span class="str">&quot;track.#DEVICE 1 SERIAL NUMBER#&quot;</span>,
        <span class="str">&quot;timestamp&quot;</span>:1326035650601,<span class="str">&quot;version&quot;</span>:1041047847},
    {<span class="str">&quot;key&quot;</span>:<span class="str">&quot;device.#DEVICE 2 SERIAL NUMBER#&quot;</span>,
        <span class="str">&quot;version&quot;</span>:149169270,<span class="str">&quot;timestamp&quot;</span>:1326034820000},
    {<span class="str">&quot;key&quot;</span>:<span class="str">&quot;shared.#DEVICE 2 SERIAL NUMBER#&quot;</span>,
        <span class="str">&quot;version&quot;</span>:659841570,<span class="str">&quot;timestamp&quot;</span>:1326034820000},
    {<span class="str">&quot;key&quot;</span>:<span class="str">&quot;schedule.#DEVICE 2 SERIAL NUMBER#&quot;</span>,
        <span class="str">&quot;version&quot;</span>:-2016290692,<span class="str">&quot;timestamp&quot;</span>:1326005625000},
    {<span class="str">&quot;key&quot;</span>:<span class="str">&quot;track.#DEVICE 2 SERIAL NUMBER#&quot;</span>,
        <span class="str">&quot;timestamp&quot;</span>:1326035650862,<span class="str">&quot;version&quot;</span>:528978433},
    {<span class="str">&quot;key&quot;</span>:<span class="str">&quot;device.#DEVICE 3 SERIAL NUMBER#&quot;</span>,
        <span class="str">&quot;version&quot;</span>:1637112547,<span class="str">&quot;timestamp&quot;</span>:1326035399000},
    {<span class="str">&quot;key&quot;</span>:<span class="str">&quot;shared.#DEVICE 3 SERIAL NUMBER#&quot;</span>,
        <span class="str">&quot;version&quot;</span>:760504326,<span class="str">&quot;timestamp&quot;</span>:1326035397000},
    {<span class="str">&quot;key&quot;</span>:<span class="str">&quot;schedule.#DEVICE 3 SERIAL NUMBER#&quot;</span>,
        <span class="str">&quot;version&quot;</span>:-314552357,<span class="str">&quot;timestamp&quot;</span>:1326003402000},
    {<span class="str">&quot;key&quot;</span>:<span class="str">&quot;track.#DEVICE 3 SERIAL NUMBER#&quot;</span>,
        <span class="str">&quot;version&quot;</span>:-645931164,<span class="str">&quot;timestamp&quot;</span>:1326035531802}]}&quot;</pre>
<p>We’ve got three thermostats, so there are always three sets of subscription requests for each call to <strong>subscribe.</strong> </p>
<p>Using my iPad, I adjusted the set point for our second story (#DEVICE 2#) down one degree Fahrenheit (to 67°).</p>
<p>Within approximately a second, the most recent pending <strong>subscribe</strong> request returned with a far more interesting payload:</p>
<pre class="csharpcode">
jQuery17108417355176061392_1326035646750(
    { <span class="str">&quot;status&quot;</span>: 200,
        <span class="str">&quot;headers&quot;</span>: {
            <span class="str">&quot;X-nl-skv-key&quot;</span>: <span class="str">&quot;shared.#DEVICE 2 SERIAL NUMBER#&quot;</span>,
            <span class="str">&quot;X-nl-skv-version&quot;</span>: 869022424,
            <span class="str">&quot;X-nl-skv-timestamp&quot;</span>: 1326038279000,
            <span class="str">&quot;X-nl-service-timestamp&quot;</span>: 1326038279825
        },
        <span class="str">&quot;payload&quot;</span>: {
            <span class="str">&quot;current_temperature&quot;</span>: 19.98,
            <span class="str">&quot;hvac_fan_state&quot;</span>: <span class="kwrd">false</span>,
            <span class="str">&quot;name&quot;</span>: <span class="str">&quot;TWO&quot;</span>, <span class="str">&quot;hvac_heat_x2_state&quot;</span>: <span class="kwrd">false</span>,
            <span class="str">&quot;hvac_ac_state&quot;</span>: <span class="kwrd">false</span>,
            <span class="str">&quot;can_cool&quot;</span>: <span class="kwrd">true</span>,
            <span class="str">&quot;auto_away&quot;</span>: 0,
            <span class="str">&quot;compressor_lockout_enabled&quot;</span>: <span class="kwrd">false</span>,
            <span class="str">&quot;target_temperature_low&quot;</span>: 16.66667,
            <span class="str">&quot;target_temperature_high&quot;</span>: 26.66667,
            <span class="str">&quot;compressor_lockout_timeout&quot;</span>: 0,
            <span class="str">&quot;hvac_heater_state&quot;</span>: <span class="kwrd">false</span>,
            <span class="str">&quot;hvac_aux_heater_state&quot;</span>: <span class="kwrd">false</span>,
            <span class="str">&quot;target_temperature&quot;</span>: 19.44444,
            <span class="str">&quot;can_heat&quot;</span>: <span class="kwrd">true</span>,
            <span class="str">&quot;target_temperature_type&quot;</span>: <span class="str">&quot;heat&quot;</span>,
            <span class="str">&quot;target_change_pending&quot;</span>: <span class="kwrd">true</span>
        }
    });</pre>
<p>
<style type="text/css">
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
<p>Everything above is needed to update the current state of the UI. As you can see, the current temperature (returned as Celsius apparently) is 19.98 (67.964°F). The current temperature as displayed on the thermostat and the web UI was 68.</p>
<p><em>Seeing these return values makes me think that they may be using Ruby and Rails (as the naming convention tends to follow Rails naming using underscores between words). I know for example, I wouldn’t name variables/columns that way when building a C#/JavaScript MVC project.</em></p>
<p><font color="#333333">Rather than just a delta payload of what’s changed, they’ve currently opted for a full update of all information related to the thermostat state. </font></p>
<p><font color="#333333">Several seconds later, a much larger payload was returned to a <strong>subscribe </strong>request:</font></p>
<pre class="csharpcode"><span class="str">&quot;status&quot;</span>: 200,
<span class="str">&quot;headers&quot;</span>: {
    <span class="str">&quot;X-nl-skv-key&quot;</span>: <span class="str">&quot;device.#DEVICE 2 SERIAL NUMBER#&quot;</span>,
    <span class="str">&quot;X-nl-skv-version&quot;</span>: -2086438581,
    <span class="str">&quot;X-nl-skv-timestamp&quot;</span>: 1326038378000,
    <span class="str">&quot;X-nl-service-timestamp&quot;</span>: 1326038379023
},
<span class="str">&quot;payload&quot;</span>: {
    <span class="str">&quot;ob_orientation&quot;</span>: <span class="str">&quot;O&quot;</span>,
    <span class="str">&quot;upper_safety_temp&quot;</span>: 1000.0,
    <span class="str">&quot;forced_air&quot;</span>: <span class="kwrd">true</span>,
    <span class="str">&quot;creation_time&quot;</span>: 1324142042019,
    <span class="str">&quot;switch_preconditioning_control&quot;</span>: <span class="kwrd">false</span>,
    <span class="str">&quot;click_sound&quot;</span>: <span class="str">&quot;on&quot;</span>,
    <span class="str">&quot;leaf&quot;</span>: <span class="kwrd">false</span>, <span class="str">&quot;user_brightness&quot;</span>: <span class="str">&quot;auto&quot;</span>,
    <span class="str">&quot;learning_state&quot;</span>: <span class="str">&quot;steady&quot;</span>,
    <span class="str">&quot;heat_pump_comp_threshold&quot;</span>: -1000.0,
    <span class="str">&quot;local_ip&quot;</span>: <span class="str">&quot;10.0.0.205&quot;</span>,
    <span class="str">&quot;backplate_serial_number&quot;</span>: <span class="str">&quot;#SHOULD BE DEVICE 2 SERIAL NUMBER, BUT ISN'T?#&quot;</span>,
    <span class="str">&quot;capability_level&quot;</span>: 1.03,
    <span class="str">&quot;postal_code&quot;</span>: <span class="str">&quot;#POSTALCODE#&quot;</span>,
    <span class="str">&quot;upper_safety_temp_enabled&quot;</span>: <span class="kwrd">false</span>,
    <span class="str">&quot;heat_pump_aux_threshold&quot;</span>: 10.0,
    <span class="str">&quot;lower_safety_temp_enabled&quot;</span>: <span class="kwrd">true</span>,
    <span class="str">&quot;serial_number&quot;</span>: <span class="str">&quot;#DEVICE 2 SERIAL NUMBER#&quot;</span>,
    <span class="str">&quot;temperature_lock&quot;</span>: <span class="kwrd">false</span>,
    <span class="str">&quot;learning_time&quot;</span>: 1002,
    <span class="str">&quot;current_version&quot;</span>: <span class="str">&quot;1.0.4&quot;</span>,
    <span class="str">&quot;model_version&quot;</span>: <span class="str">&quot;Diamond-1.10&quot;</span>,
    <span class="str">&quot;backplate_bsl_info&quot;</span>: <span class="str">&quot;BSL&quot;</span>,
    <span class="str">&quot;auto_away_enable&quot;</span>: <span class="kwrd">true</span>,
    <span class="str">&quot;heat_pump_comp_threshold_enabled&quot;</span>: <span class="kwrd">false</span>,
    <span class="str">&quot;fan_mode&quot;</span>: <span class="str">&quot;auto&quot;</span>,
    <span class="str">&quot;range_enable&quot;</span>: <span class="kwrd">false</span>,
    <span class="str">&quot;temperature_scale&quot;</span>: <span class="str">&quot;F&quot;</span>,
    <span class="str">&quot;backplate_mono_info&quot;</span>: <span class="str">&quot;TFE (BP_DVT) 3.5.2 (ehs@ubuntu) 2011-11-05 12:00:00&quot;</span>,
    <span class="str">&quot;backplate_bsl_version&quot;</span>: <span class="str">&quot;1.1&quot;</span>,
    <span class="str">&quot;equipment_type&quot;</span>: <span class="str">&quot;gas&quot;</span>,
    <span class="str">&quot;range_mode&quot;</span>: <span class="kwrd">false</span>,
    <span class="str">&quot;lower_safety_temp&quot;</span>: 7.0,
    <span class="str">&quot;has_fan&quot;</span>: <span class="kwrd">true</span>,
    <span class="str">&quot;hvac_wires&quot;</span>: <span class="str">&quot;Heat,Cool,Fan,Common Wire,Rc&quot;</span>,
    <span class="str">&quot;learning_mode&quot;</span>: <span class="kwrd">true</span>,
    <span class="str">&quot;away_temperature_high&quot;</span>: 32.0,
    <span class="str">&quot;switch_system_off&quot;</span>: <span class="kwrd">false</span>,
    <span class="str">&quot;time_to_target&quot;</span>: 1326039444,
    <span class="str">&quot;away_temperature_low&quot;</span>: 14.444444444444445,
    <span class="str">&quot;current_humidity&quot;</span>: 45,
    <span class="str">&quot;mac_address&quot;</span>: <span class="str">&quot;#MACADDR#&quot;</span>,
    <span class="str">&quot;backplate_mono_version&quot;</span>: <span class="str">&quot;3.5.2&quot;</span>,
    <span class="str">&quot;has_aux_heat&quot;</span>: <span class="kwrd">false</span>,
    <span class="str">&quot;type&quot;</span>: <span class="str">&quot;TBD&quot;</span>,
    <span class="str">&quot;hvac_pins&quot;</span>: <span class="str">&quot;W1,Y1,C,Rc,G&quot;</span>,
    <span class="str">&quot;has_heat_pump&quot;</span>: <span class="kwrd">false</span>,
    <span class="str">&quot;heat_pump_aux_threshold_enabled&quot;</span>: <span class="kwrd">true</span>,
    <span class="str">&quot;battery_level&quot;</span>: 3.945,
    <span class="str">&quot;target_time_confidence&quot;</span>: 1.0
}</pre>
<style type="text/css">
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
<p>A few things to note:</p>
<li><strong>Upper_safety_temperature </strong>is just a bit beyond my comfort zone at 1832°F. I don’t know why it’s sending a value like that to the client, and why it’s stupidly high.</li>
<li>The backplate serial number doesn’t match with the thermostat according to the payload response. I don’t know why this might be as I confirmed that the numbers matched through visual inspection of the device just now.</li>
<li>The majority of these details are exposed in one way or another in the details area of the web UI.</li>
<li>Time to target (payload.time_to_target) is unusual in that it’s a JavaScript Date value, divided by 1000. So, in the example above, the time to target is: <strong>new Date(1326039444 * 1000).toString() = &gt;&quot;Sun Jan 08 2012 10:17:24 GMT-0600 (Central Standard Time)&quot;</strong></li>
<p>Next, a payload is returned with the new status:</p>
<pre class="csharpcode"><span class="str">&quot;status&quot;</span>: 200,
<span class="str">&quot;headers&quot;</span>: {
    <span class="str">&quot;X-nl-skv-key&quot;</span>: <span class="str">&quot;shared.#DEVICE 2 SERIAL NUMBER#&quot;</span>,
    <span class="str">&quot;X-nl-skv-version&quot;</span>: 1689916148,
    <span class="str">&quot;X-nl-skv-timestamp&quot;</span>: 1326038378000,
    <span class="str">&quot;X-nl-service-timestamp&quot;</span>: 1326038379151
},
<span class="str">&quot;payload&quot;</span>: {
    <span class="str">&quot;hvac_fan_state&quot;</span>: <span class="kwrd">false</span>,
    <span class="str">&quot;name&quot;</span>: <span class="str">&quot;TWO&quot;</span>,
    <span class="str">&quot;hvac_heat_x2_state&quot;</span>: <span class="kwrd">false</span>,
    <span class="str">&quot;hvac_ac_state&quot;</span>: <span class="kwrd">false</span>,
    <span class="str">&quot;can_cool&quot;</span>: <span class="kwrd">true</span>,
    <span class="str">&quot;auto_away&quot;</span>: 0,
    <span class="str">&quot;compressor_lockout_enabled&quot;</span>: <span class="kwrd">false</span>,
    <span class="str">&quot;target_temperature_low&quot;</span>: 16.66667,
    <span class="str">&quot;current_temperature&quot;</span>: 19.53,
    <span class="str">&quot;target_temperature_high&quot;</span>: 26.66667,
    <span class="str">&quot;compressor_lockout_timeout&quot;</span>: 0,
    <span class="str">&quot;target_change_pending&quot;</span>: <span class="kwrd">false</span>,
    <span class="str">&quot;hvac_aux_heater_state&quot;</span>: <span class="kwrd">false</span>,
    <span class="str">&quot;target_temperature&quot;</span>: 20.55556,
    <span class="str">&quot;can_heat&quot;</span>: <span class="kwrd">true</span>,
    <span class="str">&quot;target_temperature_type&quot;</span>: <span class="str">&quot;heat&quot;</span>,
    <span class="str">&quot;hvac_heater_state&quot;</span>: <span class="kwrd">true</span>
}</pre>
<style type="text/css">
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
<p>Here, the <strong>hvac_heater_state</strong> is set to <strong>true</strong>. The furnace is on.</p>
<p>A little while later, that value is set to <strong>false.</strong></p>
<p>Occasionally, the payload includes the complete schedule for the thermostat. I’m not going to reproduce the entire payload here as it’s too large, and quite boring. Here’s a snippet of what it returns:</p>
<pre class="csharpcode"><span class="str">&quot;schedule&quot;</span>: {
    <span class="str">&quot;#DEVICE 2 SERIAL NUMBER#&quot;</span>: {
        <span class="str">&quot;$version&quot;</span>: 1187107985,
        <span class="str">&quot;$timestamp&quot;</span>: 1326005677000,
        <span class="str">&quot;name&quot;</span>: <span class="str">&quot;One Current Schedule&quot;</span>,
        <span class="str">&quot;days&quot;</span>: {
            <span class="str">&quot;0&quot;</span>: {
                <span class="str">&quot;0&quot;</span>: {
                    <span class="str">&quot;type&quot;</span>: <span class="str">&quot;HEAT&quot;</span>,
                    <span class="str">&quot;temp&quot;</span>: 14.445,
                    <span class="str">&quot;time&quot;</span>: 0,
                    <span class="str">&quot;entry_type&quot;</span>: <span class="str">&quot;continuation&quot;</span>
                },
                <span class="str">&quot;1&quot;</span>: {
                    <span class="str">&quot;type&quot;</span>: <span class="str">&quot;HEAT&quot;</span>,
                    <span class="str">&quot;temp&quot;</span>: 14.445,
                    <span class="str">&quot;time&quot;</span>: 27900,
                    <span class="str">&quot;entry_type&quot;</span>: <span class="str">&quot;setpoint&quot;</span>
                },
                <span class="str">&quot;2&quot;</span>: {
                    <span class="str">&quot;type&quot;</span>: <span class="str">&quot;HEAT&quot;</span>,
                    <span class="str">&quot;temp&quot;</span>: 20.556,
                    <span class="str">&quot;time&quot;</span>: 63000,
                    <span class="str">&quot;entry_type&quot;</span>: <span class="str">&quot;setpoint&quot;</span>
                },
                <span class="str">&quot;3&quot;</span>: {
                    <span class="str">&quot;type&quot;</span>: <span class="str">&quot;HEAT&quot;</span>,
                    <span class="str">&quot;temp&quot;</span>: 14.445,
                    <span class="str">&quot;time&quot;</span>: 70200,
                    <span class="str">&quot;entry_type&quot;</span>: <span class="str">&quot;setpoint&quot;</span>
                }
            },
            <span class="str">&quot;1&quot;</span>: {
                <span class="str">&quot;0&quot;</span>: {
                    <span class="str">&quot;type&quot;</span>: <span class="str">&quot;HEAT&quot;</span>,
                    <span class="str">&quot;temp&quot;</span>: 14.445,
                    <span class="str">&quot;time&quot;</span>: 0,
                    <span class="str">&quot;entry_type&quot;</span>: <span class="str">&quot;continuation&quot;</span>
                },
                <span class="str">&quot;1&quot;</span>: {
                    <span class="str">&quot;type&quot;</span>: <span class="str">&quot;HEAT&quot;</span>,
                    <span class="str">&quot;temp&quot;</span>: 18.889,
                    <span class="str">&quot;time&quot;</span>: 20700,
                    <span class="str">&quot;entry_type&quot;</span>: <span class="str">&quot;setpoint&quot;</span>
                },</pre>
<style type="text/css">
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
</p>
<p>It’s a basic table structure. The first set point of the day is at 0, and is a “continuation.” These don’t show up in the UI. </p>
<p>Here’s what the day 1 looks like on the Nest thermostat UI:</p>
<p><a href="http://www.wiredprairie.us/blog/wp-content/uploads/2012/01/image8.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: block; float: none; margin-left: auto; border-top: 0px; margin-right: auto; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.wiredprairie.us/blog/wp-content/uploads/2012/01/image_thumb8.png" width="500" height="37" /></a></p>
<p>When changing a temperature setpoint, I’m a bit disappointed to see that the entire schedule is sent with every request apparently. I just wouldn’t have expected that given that the more setpoints that there are, the bigger the payload must be. The UI is often sluggish when rapidly making adjustments in the schedule, and this could be one of the factors.</p>
<p>In the example below (which I’ve snipped most of the payload sent again as a JSONP request), I’ve set the first set point to 57F. </p>
<pre class="csharpcode">    <span class="str">&quot;payload&quot;</span>: {
        <span class="str">&quot;days&quot;</span>: {
            <span class="str">&quot;0&quot;</span>: {
                <span class="str">&quot;0&quot;</span>: {
                    <span class="str">&quot;type&quot;</span>: <span class="str">&quot;HEAT&quot;</span>,
                    <span class="str">&quot;temp&quot;</span>: 14.685,
                    <span class="str">&quot;time&quot;</span>: 0,
                    <span class="str">&quot;entry_type&quot;</span>: <span class="str">&quot;continuation&quot;</span>
                },
                <span class="str">&quot;1&quot;</span>: {
                    <span class="str">&quot;type&quot;</span>: <span class="str">&quot;HEAT&quot;</span>,
                    <span class="str">&quot;temp&quot;</span>: 15.000444444444444,
                    <span class="str">&quot;time&quot;</span>: 24300,
                    <span class="str">&quot;entry_type&quot;</span>: <span class="str">&quot;setpoint&quot;</span>
                },</pre>
<p>For the JSONP requests sent as “MAKE CHANGE” (easily could have been PUT), they each contained the following attributes as shown below. All JSONP requests are apparently routed on the web server using “headers” rather than a RESTful URL based system:</p>
<pre class="csharpcode">    },
    <span class="str">&quot;headers&quot;</span>: {
        <span class="str">&quot;X-nl-client-timestamp&quot;</span>: 1326041210566,
        <span class="str">&quot;X-nl-session-id&quot;</span>: <span class="str">&quot;#SESSION ID#&quot;</span>,
        <span class="str">&quot;X-nl-protocol-version&quot;</span>: 1,
        <span class="str">&quot;Authorization&quot;</span>: <span class="str">&quot;Basic #BASIC AUTH#&quot;</span>
    },
    <span class="str">&quot;path&quot;</span>: <span class="str">&quot;/v1/put/schedule.#DEVICE 2 SERIAL NUMBER#&quot;</span>,
    <span class="str">&quot;redir&quot;</span>: <span class="str">&quot;https://home.nest.com/post_jsonp&quot;</span>,
    <span class="str">&quot;jsonp&quot;</span>: <span class="str">&quot;4_&quot;</span>
}</pre>
<p>It’s RESTful in spirit as there is a route (“path”), but it’s managed by some internal routing engine. (Now, I think that they’re not using Ruby and Rails). </p>
<p>For something simple, like changing the current temperature of a thermostat, the request is thankfully simple:</p>
<pre class="csharpcode">{
    <span class="str">&quot;payload&quot;</span>: {
        <span class="str">&quot;shared&quot;</span>: {
            <span class="str">&quot;#DEVICE 2 SERIAL NUMBER#&quot;</span>: {
                <span class="str">&quot;target_temperature&quot;</span>: 18.333333333333336
            }
        }
    },
    <span class="str">&quot;headers&quot;</span>: {
        <span class="str">&quot;X-nl-client-timestamp&quot;</span>: 1326041744556,
        <span class="str">&quot;X-nl-session-id&quot;</span>: <span class="str">&quot;#SESSION ID#&quot;</span>,
        <span class="str">&quot;X-nl-protocol-version&quot;</span>: 1,
        <span class="str">&quot;Authorization&quot;</span>: <span class="str">&quot;Basic #BASIC AUTH#&quot;</span>
    },
    <span class="str">&quot;path&quot;</span>: <span class="str">&quot;/v1/put&quot;</span>,
    <span class="str">&quot;redir&quot;</span>: <span class="str">&quot;https://home.nest.com/post_jsonp&quot;</span>,
    <span class="str">&quot;jsonp&quot;</span>: <span class="str">&quot;14_&quot;</span>
}</pre>
<p>While, I haven’t taken the time to try to write a custom UI for this undocumented API yet, it looks like it should be relatively easy to do, especially as it relates to the schedule and current temperature settings. I know there’s been some Siri proxy stuff that’s been written – but I don’t have any interest in trying to get that to work.</p>
<p>As with most APIs like this, the trick is often getting authorization correct. For Nest, it appears that making a POST request to <strong>https://home.nest.com/accounts/login/</strong> with <strong>username</strong> and <strong>password</strong> as form data, that the server responds with 2 cookies:</p>
<ol>
<li>sessionid == used in X-nl-session-id in headers</li>
<li>cztoken == used as the Authorization in headers (prepended with the text “Basic “</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://www.wiredprairie.us/blog/index.php/archives/1442/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Ember.JS and EZdata, and Rails</title>
		<link>http://www.wiredprairie.us/blog/index.php/archives/1430</link>
		<comments>http://www.wiredprairie.us/blog/index.php/archives/1430#comments</comments>
		<pubDate>Sat, 07 Jan 2012 19:39:24 +0000</pubDate>
		<dc:creator>Aaron</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[General]]></category>
		<category><![CDATA[Ember.JS]]></category>
		<category><![CDATA[Rails]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[SproutCore]]></category>

		<guid isPermaLink="false">http://www.wiredprairie.us/blog/?p=1430</guid>
		<description><![CDATA[I’ve been trying to do some additional work on my ember.js extension for data management. At the same time though, I’ve been trying (to learn and) build a simple Ruby on Rails web demo application using the new JavaScript library. There have been more than a few things that have mystified me about the framework [...]]]></description>
			<content:encoded><![CDATA[<p>I’ve been trying to do some additional work on my <a href="http://www.wiredprairie.us/blog/index.php/archives/1377">ember.js extension for data</a> management. At the same time though, I’ve been trying (to learn and) build a simple <a href="http://rubyonrails.org/">Ruby on Rails</a> web demo application using the new JavaScript library. There have been more than a few things that have mystified me about the framework and the structuring of an application. One aspect in particular was how to best manage foreign keys and join tables with the ActiveRecord class (and the corresponding SQL tables). So many tutorials have the same lame example of: a CART, an ORDER, a CUSTOMER …, that it’s often difficult to apply the same patterns to a more interesting system. </p>
<p>I started simple this time. </p>
<p>I wanted a PERSON class and a GIFT class.</p>
<p><a href="http://www.wiredprairie.us/blog/wp-content/uploads/2012/01/image6.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: block; float: none; margin-left: auto; border-top: 0px; margin-right: auto; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.wiredprairie.us/blog/wp-content/uploads/2012/01/image_thumb6.png" width="399" height="159" /></a></p>
<p>A Person has been given gifts and may give gifts (and a few other common attributes). </p>
<pre class="csharpcode"><span class="kwrd">class</span> CreatePeople &lt; ActiveRecord::Migration
  def change
    create_table :people do |t|
      t.string :first_name
      t.string :last_name
      t.<span class="kwrd">date</span> :date_of_birth
      t.string :email_address

      t.timestamps
    <span class="kwrd">end</span>
  <span class="kwrd">end</span>
<span class="kwrd">end</span></pre>
<p>One of the things that I can’t decide if I like is the automatic pluralization of words, especially People/Person. I would have been content with a Persons table, but when creating a model, by default (as I’m aware it can be overridden), a Person is mapped to a table called “People.” </p>
<p>The second table, Gifts is very simple:</p>
<pre class="csharpcode"><span class="kwrd">class</span> CreateGifts &lt; ActiveRecord::Migration
  def change
    create_table :gifts do |t|
      t.string :description
      t.<span class="kwrd">integer</span> :from_person_id
      t.<span class="kwrd">integer</span> :to_person_id
      t.timestamps
    <span class="kwrd">end</span>
  <span class="kwrd">end</span>
end</pre>
<style type="text/css">
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
<style type="text/css">
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
<p>As I thought I might want a richer structure for the Gift class in the future, I did not use the more standard “person_id” name for the foreign key column that maps a gift to a Person. I wanted the column name to be more obvious what it was. Additionally, I needed two columns that both mapped to a “Person&quot;, so I couldn’t have both be called “person_id” anyway.</p>
<p>By deviating from the normal pattern, there are a few expectations when defining the ActiveRecord class. It was these expectations that weren’t clear to me (especially with examples).</p>
<p>The Ruby class for Gift is defined like so:</p>
<pre class="csharpcode"><span class="kwrd">class</span> Gift &lt; ActiveRecord::Base
  belongs_to :from_person, :class_name =&gt; &quot;Person&quot;, :foreign_key =&gt; &quot;from_person_id&quot;
  belongs_to :to_person, :class_name =&gt; &quot;Person&quot;, :foreign_key =&gt; &quot;to_person_id&quot;
<span class="kwrd">end</span></pre>
<style type="text/css">
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
<style type="text/css">
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
<p>and the Person:</p>
<pre class="csharpcode"><span class="kwrd">class</span> Person &lt; ActiveRecord::Base
  has_many  :gifts_given , :class_name =&gt; &quot;Gift&quot;, :foreign_key =&gt; &quot;from_person_id&quot;
  has_many  :gifts, :foreign_key =&gt; &quot;to_person_id&quot;
<span class="kwrd">end</span></pre>
<style type="text/css">
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
<p>The key (and the ‘ah ha’ moment for me) was the use of the foreign_key parameter to the on the has_many and belongs_to associations. </p>
<p>In the Gift class, I included the <strong>belongs_to</strong> association macro. In this case, <strong>:from_person</strong> is the name of the rich accessor method (which looks like a property in other languages) that will be added to the Gift class. Using the symbol <strong>:class_name</strong> is like a class finding assistant. Without it, the Rails framework assumes that there would be a class named “FromPerson.” Of course, that would fail. By specifying “Person,” I’ve indicated to Rails that the class it should map to is called “Person” which I defined earlier. The <strong>:foreign_key</strong> symbol and value indicates which column in the backing table has the value which will map to an instance of a Person. In the SQL table, I added a “<strong>from_person_id</strong>” column and this points at that as the “from_person_id” column is the foreign key to the People table. (The same is true for <strong>:to_person</strong>.) </p>
<p>Looking at the Person class, it is using another common association macro, <strong>:has_many</strong>. <strong>:Has_many</strong> when used here, is indicating that a Person may have zero or more “gifts.” The new accessor method is named <strong>gifts </strong>(by using <strong>:gifts</strong>). Here, too, you’ll specify the name of the foreign_key. Again, repeat this for the <strong>:gifts_given</strong> automatically added accessor method. One interesting thing is that only :<strong>gifts_given </strong>requires the :<strong>class_name</strong> to be specified. The reason is that Rails automatically maps <strong>:gifts </strong>to the Gifts class (by way of naming). The :gifts_given cannot be automatically mapped, so you need to give (sigh) it a little help.</p>
<p>Here’s a little test:</p>
<pre class="csharpcode">&gt;&gt; jason = Person.find(1)
  Person Load (18.0ms)  SELECT <span class="str">&quot;people&quot;</span>.* FROM <span class="str">&quot;people&quot;</span> WHERE <span class="str">&quot;people&quot;</span>.<span class="str">&quot;id&quot;</span> = ? LIMIT 1  [[<span class="str">&quot;id&quot;</span>, 1]]
#&lt;Person id: 1, first_name: <span class="str">&quot;Jason&quot;</span>, last_name: <span class="str">&quot;Bourne&quot;</span>, date_of_birth: nil, email_address: nil, created_at: <span class="str">&quot;2012-01-06 13:47:40&quot;</span>, updated_at: <span class="str">&quot;2012-01-07 03:10:29&quot;</span>&gt;
&gt;&gt; jason.gifts_given
  Gift Load (0.0ms)  SELECT <span class="str">&quot;gifts&quot;</span>.* FROM <span class="str">&quot;gifts&quot;</span> WHERE <span class="str">&quot;gifts&quot;</span>.<span class="str">&quot;from_person_id&quot;</span> = 1
[#&lt;Gift id: 1, description: <span class="str">&quot;Machine Gun&quot;</span>, from_person_id: 1, to_person_id: 4, created_at: <span class="str">&quot;2012-01-07 14:39:17&quot;</span>, updated_at: <span class="str">&quot;2012-01-07 14:39:17&quot;</span>&gt;]
&gt;&gt; jason.gifts_given[0].to_person.first_name
<span class="str">&quot;Magnum&quot;</span>
  Person Load (0.0ms)  SELECT <span class="str">&quot;people&quot;</span>.* FROM <span class="str">&quot;people&quot;</span> WHERE <span class="str">&quot;people&quot;</span>.<span class="str">&quot;id&quot;</span> = 4 LIMIT 1
&gt;&gt; jason.gifts_given[0].to_person.gifts
  [#&lt;Gift id: Gift Load (1.0ms)1  SELECT <span class="str">&quot;gifts&quot;</span>.* FROM <span class="str">&quot;gifts&quot;</span> WHERE <span class="str">&quot;gifts&quot;</span>.<span class="str">&quot;to_person_id&quot;</span> = 4
, description: <span class="str">&quot;Machine Gun&quot;</span>, from_person_id: 1, to_person_id: 4, created_at: <span class="str">&quot;2012-01-07 14:39:17&quot;</span>, updated_at: <span class="str">&quot;2012-01-07 14:39:17&quot;</span>&gt;]
&gt;&gt; jason.gifts_given[0].to_person.gifts[0].from_person.first_name
  Person Load (0.0ms)  SELECT <span class="str">&quot;people&quot;</span>.* FROM <span class="str">&quot;people&quot;</span> WHERE <span class="str">&quot;people&quot;</span>.<span class="str">&quot;id&quot;</span> = 1 LIMIT 1
<span class="str">&quot;Jason&quot;</span></pre>
<p>I added two people: Jason, and Magnum, and one gift before executing the code above. Jason, as you should be able to follow, gave a wonderful gift to Magnum. As you can see, by using the automatically added accessor methods by way of the association macros described above, I was able to traverse the database structure very easily when mapped to a few simple objects. </p>
<p>One plus of experimenting and testing with the console while using Rails/Ruby in this case is that the output includes the SQL commands that are executed when the various method calls are made. Here’s an example where I rolled multiple calls into one chained call:</p>
<pre class="csharpcode">&gt;&gt; jason = Person.find(1).gifts_given[0].to_person.first_name
  Person Load (19.0ms)  SELECT <span class="str">&quot;people&quot;</span>.* FROM <span class="str">&quot;people&quot;</span> WHERE <span class="str">&quot;people&quot;</span>.<span class="str">&quot;id&quot;</span> = ? LIMIT 1  [[<span class="str">&quot;id&quot;</span>, 1]]
  Gift Load (0.0ms)  SELECT <span class="str">&quot;gifts&quot;</span>.* FROM <span class="str">&quot;gifts&quot;</span> WHERE <span class="str">&quot;gifts&quot;</span>.<span class="str">&quot;from_person_id&quot;</span> = 1
<span class="str">&quot;Magnum&quot;</span>
  Person Load (0.0ms)  SELECT <span class="str">&quot;people&quot;</span>.* FROM <span class="str">&quot;people&quot;</span> WHERE <span class="str">&quot;people&quot;</span>.<span class="str">&quot;id&quot;</span> = 4 LIMIT 1</pre>
<style type="text/css">
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
]]></content:encoded>
			<wfw:commentRss>http://www.wiredprairie.us/blog/index.php/archives/1430/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A post not related to Nest thermostat hardware&#8230;.</title>
		<link>http://www.wiredprairie.us/blog/index.php/archives/1397</link>
		<comments>http://www.wiredprairie.us/blog/index.php/archives/1397#comments</comments>
		<pubDate>Wed, 04 Jan 2012 03:02:20 +0000</pubDate>
		<dc:creator>Aaron</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[General]]></category>
		<category><![CDATA[Nest]]></category>

		<guid isPermaLink="false">http://www.wiredprairie.us/blog/?p=1397</guid>
		<description><![CDATA[I typed in https://www.nest.com this evening and instead of the nice looking Nest.com web site, I got this: What?! I hadn’t actually noticed that I’d typed https at first, so I was a bit baffled for a moment. After closer investigation, Nest doesn’t have HTTPS apparently for their marketing/support web site setup on their Amazon [...]]]></description>
			<content:encoded><![CDATA[<p>I typed in <a href="https://www.nest.com">https://www.nest.com</a> this evening and instead of the nice looking Nest.com web site, I got this:</p>
<p><a href="http://www.wiredprairie.us/blog/wp-content/uploads/2012/01/SNAGHTML69c9dbf8.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="SNAGHTML69c9dbf8" border="0" alt="SNAGHTML69c9dbf8" src="http://www.wiredprairie.us/blog/wp-content/uploads/2012/01/SNAGHTML69c9dbf8_thumb.png" width="424" height="360" /></a></p>
<p>What?! I hadn’t actually noticed that I’d typed https at first, so I was a bit baffled for a moment. After closer investigation, Nest doesn’t have HTTPS apparently for their marketing/support web site setup on their Amazon CloudFront account (which is what cloudfront.net is).</p>
<p>They really should fix that. <img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://www.wiredprairie.us/blog/wp-content/uploads/2012/01/wlEmoticon-smile1.png" /></p>
<p>I was having some serious performance issues with their remote access web site earlier. It was barely usable. </p>
<p>That inspired me to dig a little to see what JavaScript libraries they might be using, the chatter on the network, etc. Here’s what I dug up.</p>
<p>JavaScript libraries:</p>
<ol>
<li><a href="http://jquery.com/">Jquery</a> 1.7</li>
<li><a href="http://raphaeljs.com/">Raphael</a> (for doing vector graphics using SVG or VML)</li>
<li><a href="http://jqueryui.com/">Jquery UI</a></li>
<li><a href="https://github.com/DmitryBaranovskiy/eve/blob/master/eve.js">eve.js</a> (a “javascript events library”)</li>
<li><a href="https://github.com/btburnett3/jquery.ui.spinner">jquery.ui.spinner</a></li>
<li><a href="https://github.com/tdreyno/iphone-style-checkboxes/">iphone style checkboxes</a> (or maybe a variation on this…it’s very similar)</li>
<li><a href="http://documentcloud.github.com/backbone/">backbone.js</a></li>
<li><a href="http://documentcloud.github.com/underscore">underscore.js</a></li>
<li><a href="http://www.modernizr.com">modernizer</a> (1.6)</li>
<li><a href="http://www.zachstronaut.com">jquery-animate-css-rotate</a></li>
<li><a href="http://http://www.sanraul.com)">jquery double tap plugin</a></li>
<li><a href="http://malsup.com/jquery/form/">jquery form plugin</a></li>
<li><a href="http://abeautifulsite.net/notebook/68">jquery right click plugin</a></li>
<li><a href="http://http://brandonaaron.net)">jquery mouse wheel support</a></li>
</ol>
<p>An interesting DIV and solution to a problem with web fonts (found on their main page):</p>
<pre class="csharpcode"><span class="kwrd">&lt;</span><span class="html">div</span> <span class="attr">id</span><span class="kwrd">=&quot;digits&quot;</span><span class="kwrd">&gt;</span>
  <span class="rem">&lt;!--  Some browsers suffer unfortunate lag the first time they</span>
<span class="rem">        draw text in fonts loaded over the network. We pre-render</span>
<span class="rem">        these digits to avoid this lag, and this gets removed at</span>
<span class="rem">        the same time the loading message is removed. --&gt;</span>
  1234567890
<span class="kwrd">&lt;/</span><span class="html">div</span><span class="kwrd">&gt;</span></pre>
<p>And a method for activating DEBUG mode:</p>
<pre class="csharpcode">N.DEBUG = (<span class="str">'False'</span> == <span class="str">'True'</span>) || (document.location.search.indexOf(<span class="str">'debug'</span>) &gt; -1) || (C.USERNAME.indexOf(<span class="str">'@nestlabs.'</span>) &gt; -1);</pre>
<p>
<style type="text/css">
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
<p>Thus, to activate DEBUG mode on your nest, simply navigate to here:</p>
<p><a href="https://home.nest.com/home?debug">https://home.nest.com/home?debug</a></p>
<p>Brings up a slightly scary option for debugging. Be careful with this – I didn’t try ANY of the options, so it’s at your own risk.</p>
<p><a href="http://www.wiredprairie.us/blog/wp-content/uploads/2012/01/image1.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.wiredprairie.us/blog/wp-content/uploads/2012/01/image_thumb1.png" width="210" height="162" /></a></p>
<p>Also, interestingly it adds a WEATHER tab:</p>
<p><a href="http://www.wiredprairie.us/blog/wp-content/uploads/2012/01/image2.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.wiredprairie.us/blog/wp-content/uploads/2012/01/image_thumb2.png" width="502" height="170" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.wiredprairie.us/blog/index.php/archives/1397/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>EzData for Ember.js</title>
		<link>http://www.wiredprairie.us/blog/index.php/archives/1377</link>
		<comments>http://www.wiredprairie.us/blog/index.php/archives/1377#comments</comments>
		<pubDate>Sun, 01 Jan 2012 23:59:14 +0000</pubDate>
		<dc:creator>Aaron</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[binding]]></category>
		<category><![CDATA[Ember.JS]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[SproutCore]]></category>
		<category><![CDATA[templates]]></category>

		<guid isPermaLink="false">http://www.wiredprairie.us/blog/?p=1377</guid>
		<description><![CDATA[Previous post: Entity reference I’ve been extending my original post (above) in an effort to create a simple entity system using Ember.js (SproutCore 2.0). While it’s grown in sophistication, it is far from complete. The project is now located on GitHub. This is the introduction, from the readme on GitHub. EmberJS &#8211; EZData EZData is [...]]]></description>
			<content:encoded><![CDATA[<p>Previous post: <a href="http://www.wiredprairie.us/blog/index.php/archives/1345">Entity reference</a></p>
<p>I’ve been extending my original post (above) in an effort to create a simple entity system using <a href="http://emberjs.com/">Ember.js</a> (SproutCore 2.0). While it’s grown in sophistication, it is far from complete. <img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://www.wiredprairie.us/blog/wp-content/uploads/2012/01/wlEmoticon-smile.png" /></p>
<p>The project is now located on G<a href="https://github.com/wiredprairie/ember-ezdata">itHub</a>.</p>
<p>This is the introduction, from the readme on GitHub.</p>
<h3>EmberJS &#8211; EZData</h3>
<p>EZData is a library intended to a simple way of accessing data from a relational database when using <a href="http://emberjs.com/">Ember.js</a>. It will never try to be everything to everyone. <img src='http://www.wiredprairie.us/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  Instead, it&#8217;s intended to be small, efficient, and easy to learn and use javascript library.</p>
<p>The basic functionality is that it&#8217;s designed to manipulate individual entities (or Records), not a complex object structure that is often stored as JavaScript objects. This mirrors what&#8217;s found in many web systems today in the data model.</p>
<p>Right now, the project is brand new and quite in flux.</p>
<h4>Essentials</h4>
<p>Create types by calling <code>Entity.define</code> (instead of the typical Ember.Object.extend).</p>
<pre>DemoApp.Person = Entity.define(Entity, &quot;Person&quot;, {
    firstName:String,
    lastName:String,
    DOB:Date,

    fullName:function () {
        return this.get('lastName') + &quot;, &quot; + this.get('firstName');
    }.property('firstName', 'lastName')
});</pre>
<p>This will create a new Class internally by using <code>Ember.extend</code> but it also does some other magic (e.g., creating a data store for all entities of a given type). First and foremost, by calling <code>define</code>, it&#8217;s expected that you&#8217;re mirroring a relational data structure of some sort which may have foreign key relationships to other tables.</p>
<p>In the example above, the <code>Person</code> entity is expected to have the following columns in a database table:</p>
<ul>
<li>id =&gt; Number (from the basic Entity type) </li>
<li>firstName =&gt; String </li>
<li>lastName =&gt; String </li>
<li>DOB =&gt; DOB</li>
</ul>
<p>Each property is assigned the basic data type that it will contain. The data type is used for linking and serialization.</p>
<h4>Linking</h4>
<p>The second example is a <code>Gift</code>:</p>
<pre>DemoApp.Gift = Entity.define(Entity, &quot;Gift&quot;, {
    from:DemoApp.Person
});</pre>
<p>The Gift class is more interesting as one of the properties links to another type/Class (Person). As a direct connection to a Person as an object instance isn&#8217;t possible in traditional relational tables, some automatic linking occurs by declaring this linkage.</p>
<p>The <code>from</code> property is mapped to a second, hidden property that is only used for the foreign key relationship. By default, the hidden property will be called<code>fromPersonId</code>. This can be overridden by creating a custom naming function, replacing the default stored at<code>Entity.Settings.FOREIGN_KEY_GENERATOR_FUNCTION</code>.</p>
<p>By making the linkage between the two types in the way demonstrated above, the standard Ember.js handlebar templating engine (and automatic value updating) features just work (see <code>from.fullName</code> below).</p>
<pre>{{#each gifts}}
&lt;tr&gt;
    &lt;td&gt;
        {{ name }}
    &lt;/td&gt;
    &lt;td&gt;
        {{ excitement }}
    &lt;/td&gt;
    &lt;td&gt;
        {{ from.fullName }}
    &lt;/td&gt;
&lt;/tr&gt;</pre>
<p>The <code>fullName</code> property of Person is a computed property, and continues to work as expected.</p>
<h4>Getting the Data</h4>
<p>If you want to retrieve a list from one of the data stores (or data tables), it&#8217;s a simple as calling the <code>live</code> function for one of the stores.</p>
<p>In the example below, there are two live collections. The first returns all of the gifts, and the second only returns gifts that have a lowercase letter <code>o</code> in the name.</p>
<pre>// create some &quot;live&quot; connections to the data store
DemoApp.mainController.set('gifts', Entity.Stores.get(DemoApp.Gift).live());
// create a live connection with a filter (returns true if it contains the letter 'o')
DemoApp.mainController.set('giftsFiltered', Entity.Stores.get(DemoApp.Gift).live(
    function () {
        return this.get('name').indexOf('o') &gt; -1;
    }));</pre>
<p>To get access to one of the automatically created data stores, call <code>Entity.Stores.get({Class})</code> where <code>{Class}</code> is the type that was created using the<code>define</code> method.</p>
<h4>Notes / Cautions</h4>
<p>Right now, all entities are required to have a property called id and be of type Number.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.wiredprairie.us/blog/index.php/archives/1377/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Creating a simple Entity Reference system for Ember.js</title>
		<link>http://www.wiredprairie.us/blog/index.php/archives/1345</link>
		<comments>http://www.wiredprairie.us/blog/index.php/archives/1345#comments</comments>
		<pubDate>Thu, 29 Dec 2011 03:04:46 +0000</pubDate>
		<dc:creator>Aaron</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[General]]></category>
		<category><![CDATA[EmberJS]]></category>
		<category><![CDATA[SproutCore]]></category>

		<guid isPermaLink="false">http://www.wiredprairie.us/blog/?p=1345</guid>
		<description><![CDATA[I had some data stored in a structure similar to this: Nothing too fancy. A table of Gift(s) and a table of Person(s). Each gift had a foreign key relationship to a Person (the person who “gave” the gift). Since some people may give several gifts, I didn’t want to load the same data multiple [...]]]></description>
			<content:encoded><![CDATA[<p>I had some data stored in a structure similar to this:</p>
<p><a href="http://www.wiredprairie.us/blog/wp-content/uploads/2011/12/image7.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.wiredprairie.us/blog/wp-content/uploads/2011/12/image_thumb7.png" width="391" height="187" /></a></p>
<p>Nothing too fancy. A table of Gift(s) and a table of Person(s). Each gift had a foreign key relationship to a Person (the person who “gave” the gift). </p>
<p>Since some people may give several gifts, I didn’t want to load the same data multiple times (each gift shouldn’t have the person’s name for example spelled out). I wanted to build a RESTful web service to return the gifts and persons as independent queries, with the resulting JavaScript objects being very similar to the original data storage in the database.</p>
<p>Using <a href="http://www.emberjs.com/">Ember.JS</a> I built a small demonstration of <strong>one way</strong> that this could be done. I am aware of the <em>in-progress</em> data library for ember.js on <a href="https://github.com/emberjs/data">github</a>, but it was way more than I wanted (or needed). Furthermore, I found it more far complex than I wanted (and I’m not particularly fond of the syntax it requires). So, I created a simple system that I’ll likely expand upon over time and post here.</p>
<p>Here’s the very basic demo using handlebars templates (a core feature of Ember.js).</p>
<pre class="csharpcode"><span class="kwrd">&lt;!</span><span class="html">DOCTYPE</span> <span class="attr">html</span><span class="kwrd">&gt;</span>

<span class="kwrd">&lt;</span><span class="html">html</span><span class="kwrd">&gt;</span>
<span class="kwrd">&lt;</span><span class="html">head</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">title</span><span class="kwrd">&gt;Demo2-EmberJS</span><span class="kwrd">&lt;/</span><span class="html">title</span><span class="kwrd">&gt;</span>
<span class="kwrd">&lt;/</span><span class="html">head</span><span class="kwrd">&gt;</span>
<span class="kwrd">&lt;</span><span class="html">body</span><span class="kwrd">&gt;</span>

    <span class="kwrd">&lt;</span><span class="html">script</span> <span class="attr">type</span><span class="kwrd">=&quot;text/x-handlebars&quot;</span> <span class="attr">data-template-name</span><span class="kwrd">=&quot;gifts&quot;</span><span class="kwrd">&gt;</span>
      &lt;h1&gt;{{ giftReason }}&lt;/h1&gt;
      &lt;table&gt;
          &lt;thead&gt;
          &lt;tr&gt;
              &lt;td&gt;Description&lt;/td&gt;
              &lt;td&gt;Thrill&lt;/td&gt;
              &lt;td&gt;From&lt;/td&gt;
          &lt;/tr&gt;
          &lt;/thead&gt;
          {{#each gifts}}
          &lt;tr&gt;
              &lt;td&gt;
                  {{ name }}
              &lt;/td&gt;
              &lt;td&gt;
                  {{ excitement }}
              &lt;/td&gt;
              &lt;td&gt;
                  {{ person.fullName }}
              &lt;/td&gt;
          &lt;/tr&gt;
          {{/each}}
      &lt;/table&gt;
    <span class="kwrd">&lt;/</span><span class="html">script</span><span class="kwrd">&gt;</span>

    &lt;script src=<span class="str">&quot;demo2/jquery-1.7.1.js&quot;</span> type=<span class="str">&quot;text/javascript&quot;</span>&gt;&lt;/script&gt;
    &lt;script src=<span class="str">&quot;demo2/ember-0.9.3.js&quot;</span> type=<span class="str">&quot;text/javascript&quot;</span>&gt;&lt;/script&gt;
    &lt;script src=<span class="str">&quot;demo2/app.js&quot;</span> type=<span class="str">&quot;text/javascript&quot;</span>&gt;<span class="kwrd">&lt;/</span><span class="html">script</span><span class="kwrd">&gt;</span>
<span class="kwrd">&lt;/</span><span class="html">body</span><span class="kwrd">&gt;</span>
<span class="kwrd">&lt;/</span><span class="html">html</span><span class="kwrd">&gt;</span></pre>
<style type="text/css">
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
<p>And here is the content of app.js file referenced above (the other files can be downloaded from the web):</p>
<pre class="csharpcode"><span class="kwrd">var</span> Demo2App;
Demo2App = Ember.Application.create();
window.Demo2App = Demo2App;

<span class="rem">// standard class that has an 'id' property</span>
<span class="kwrd">var</span> Entity = Ember.Object.extend({
    id:<span class="kwrd">null</span>
});

(<span class="kwrd">function</span> () {
    Ember.entityRef = <span class="kwrd">function</span> (property, type) {
        <span class="rem">// auto build connection if property is in the form</span>
        <span class="rem">// of 'typenameID' if type is not specified</span>
        <span class="kwrd">if</span> (arguments.length === 1 &amp;&amp; property) {
            <span class="kwrd">var</span> l = property.length;
            <span class="kwrd">if</span> (l &gt; 2 &amp;&amp; property.substr(l - 2).toLowerCase() === <span class="str">'id'</span>) {
                type = property.substr(0, l - 2);
            } <span class="kwrd">else</span> {
                <span class="kwrd">throw</span> <span class="kwrd">new</span> Error(<span class="str">&quot;Type not specified, and cannot automatically determine store name. Referenced property name must end with Id.&quot;</span>);
            }
        }
        <span class="kwrd">var</span> fn = <span class="kwrd">new</span> Function(<span class="str">&quot;return Demo2App.Stores.find('&quot;</span> + type + <span class="str">&quot;', this.get('&quot;</span> + property + <span class="str">&quot;')); &quot;</span>);
        <span class="kwrd">return</span> Ember.computed(fn).property(property);
    };
})();

<span class="rem">/*</span>
<span class="rem"> Class definitions</span>
<span class="rem"> */</span>

Demo2App.Person = Entity.extend({
    firstName:<span class="str">''</span>,
    lastName:<span class="str">''</span>,

    fullName:<span class="kwrd">function</span> () {
        <span class="kwrd">return</span> <span class="kwrd">this</span>.get(<span class="str">'lastName'</span>) + <span class="str">&quot;, &quot;</span> + <span class="kwrd">this</span>.get(<span class="str">'firstName'</span>);
    }.property(<span class="str">'firstName'</span>, <span class="str">'lastName'</span>)
});

Demo2App.Gift = Ember.Object.extend({
    personId:<span class="kwrd">null</span>,
    person:Ember.entityRef(<span class="str">'personId'</span>)
});

<span class="rem">// build in a data store API</span>
(<span class="kwrd">function</span> () {
    <span class="rem">// within a closure, we'll store the current stores</span>

    <span class="kwrd">var</span> stores = {};

    <span class="kwrd">var</span> Store = Ember.Object.extend({
        name:<span class="kwrd">null</span>,
        _data:<span class="kwrd">null</span>,
        add:<span class="kwrd">function</span> (obj) {
            <span class="kwrd">if</span> (!obj) {
                <span class="kwrd">return</span>;
            }
            <span class="kwrd">if</span> (!obj.id) {
                <span class="kwrd">return</span>;
            }
            <span class="kwrd">this</span>.get(<span class="str">'_data'</span>)[obj.id] = obj;
        },
        remove:<span class="kwrd">function</span> (obj) {
            <span class="kwrd">if</span> (!obj) {
                <span class="kwrd">return</span>;
            }
            <span class="kwrd">if</span> (!obj.id) {
                <span class="kwrd">return</span>;
            }
            <span class="kwrd">var</span> data = <span class="kwrd">this</span>.get(<span class="str">'_data'</span>);
            delete data[obj.id];
        },

        find:<span class="kwrd">function</span> (id) {
            <span class="kwrd">if</span> (!id) {
                <span class="kwrd">return</span>;
            }
            <span class="kwrd">return</span> <span class="kwrd">this</span>.get(<span class="str">'_data'</span>)[id];
        }
    });

    Demo2App.Stores = Demo2App.Stores || {};

    Demo2App.Stores.create = <span class="kwrd">function</span> (name, options) {
        name = name.toLowerCase();
        <span class="kwrd">var</span> s = Store.create({
            name:name
        });
        s.set(<span class="str">'_data'</span>, {});
        stores[name] = s;
        <span class="kwrd">return</span> s;
    };

    Demo2App.Stores.get = <span class="kwrd">function</span> (name) {
        name = name.toLowerCase();
        <span class="kwrd">return</span> stores[name];
    };

    Demo2App.Stores.remove = <span class="kwrd">function</span> (name) {
        name = name.toLowerCase();
        delete stores[name];
    };

    Demo2App.Stores.clear = <span class="kwrd">function</span> (name) {
        name = name.toLowerCase();
        stores[name].set(<span class="str">'_data'</span>, {});
    };

    Demo2App.Stores.find = <span class="kwrd">function</span> (name, id) {
        <span class="kwrd">var</span> ds = Demo2App.Stores.get(name);
        <span class="kwrd">var</span> entity = ds.find(id);
        <span class="kwrd">if</span> (entity) {
            <span class="kwrd">return</span> entity;
        }
        <span class="kwrd">return</span> <span class="kwrd">null</span>;
    }

})();

<span class="kwrd">var</span> personsDS = Demo2App.Stores.create(<span class="str">'person'</span>);
personsDS.add(Demo2App.Person.create({
    id:<span class="str">&quot;123&quot;</span>,
    firstName:<span class="str">&quot;Aaron&quot;</span>,
    lastName:<span class="str">&quot;Bourne&quot;</span>
})
);

personsDS.add(Demo2App.Person.create({
    id:<span class="str">&quot;234&quot;</span>,
    firstName:<span class="str">&quot;Bonnie&quot;</span>,
    lastName:<span class="str">&quot;Highways&quot;</span>
})
);

personsDS.add(Demo2App.Person.create({
    id:<span class="str">&quot;345&quot;</span>,
    firstName:<span class="str">&quot;Daddy&quot;</span>,
    lastName:<span class="str">&quot;Peacebucks&quot;</span>
})
);

personsDS.add(Demo2App.Person.create({
    id:<span class="str">&quot;456&quot;</span>,
    firstName:<span class="str">&quot;Cotton&quot;</span>,
    lastName:<span class="str">&quot;Kandi&quot;</span>
})
);

Demo2App.mainController = Ember.Object.create({

    gifts:Ember.ArrayController.create({
        content:[],

        newGift:<span class="kwrd">function</span> (details) {
            <span class="kwrd">var</span> gift = Demo2App.Gift.create(details);
            <span class="kwrd">this</span>.addObject(gift);
            <span class="kwrd">return</span> gift;
        }
    })
});

<span class="kwrd">var</span> giftsView = Ember.View.create({
    templateName:<span class="str">'gifts'</span>,
    giftsBinding:<span class="str">'Demo2App.mainController.gifts'</span>,
    giftReason:<span class="str">'Birthday 2011'</span>
});

<span class="kwrd">var</span> moreGifts = [
    { name:<span class="str">'Book'</span>, excitement:<span class="str">'3'</span>, personId:<span class="str">'123'</span> },
    { name:<span class="str">'Shirt'</span>, excitement:<span class="str">'1'</span>, personId:<span class="str">'234'</span>},
    { name:<span class="str">'Game System'</span>, excitement:<span class="str">'5'</span>, personId:<span class="str">'123'</span>},
    { name:<span class="str">'Movie'</span>, excitement:<span class="str">'4'</span>, personId:<span class="str">'345'</span>},
    { name:<span class="str">'Gift Card'</span>, excitement:<span class="str">'3'</span>, personId:<span class="str">'123'</span>},
    { name:<span class="str">'MP3 Player'</span>, excitement:<span class="str">'3'</span>, personId:<span class="str">'456'</span>},
    { name:<span class="str">'Tie'</span>, excitement:<span class="str">'1'</span>, personId:<span class="str">'456'</span>},
    { name:<span class="str">'Candy'</span>, excitement:<span class="str">'3'</span>, personId:<span class="str">'234'</span>},
    { name:<span class="str">'Coffee'</span>, excitement:<span class="str">'3'</span>, personId:<span class="str">'123'</span>},
    { name:<span class="str">'Blanket'</span>, excitement:<span class="str">'2'</span>, personId:<span class="str">'456'</span>},
    { name:<span class="str">'Camera'</span>, excitement:<span class="str">'4'</span>, personId:<span class="str">'234'</span>},
    { name:<span class="str">'Phone'</span>, excitement:<span class="str">'5'</span>, personId:<span class="str">'234'</span>},
    { name:<span class="str">'Socks'</span>, excitement:<span class="str">'1'</span>, personId:<span class="str">'123'</span>},
    { name:<span class="str">'Game'</span>, excitement:<span class="str">'5'</span>, personId:<span class="str">'456'</span>}
];

<span class="kwrd">var</span> moreGiftsIndex = moreGifts.length;

$(<span class="kwrd">function</span> () {

    <span class="kwrd">function</span> addMoreGifts() {
        moreGiftsIndex--;
        <span class="kwrd">if</span> (moreGiftsIndex &gt;= 0) {
            Demo2App.mainController.gifts.newGift(moreGifts[moreGiftsIndex]);
        }
        setTimeout(addMoreGifts, 2000);
    }

    giftsView.append();
    addMoreGifts();
});</pre>
<p>Here’s a few details about the JavaScript code. #1, it’s got very little in the way of error checking. I’ll add that later. And if you use it, you should add it. <img src='http://www.wiredprairie.us/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Recall the simple data model with each gift having a foreign key reference to a person. If you look at each Gift, it contains keys that mirror the DB: <strong>name</strong>, <strong>excitement</strong>, and <strong>personId</strong>. All 3 are handled as strings. The Person class has an Id, <strong>lastName</strong>, and <strong>firstName</strong>.</p>
<p>When creating the Ember Gift class, I made a connection to the Person class using a new function I added called <strong>entityRef</strong>.</p>
<pre class="csharpcode">Demo2App.Gift = Ember.Object.extend({
    personId:<span class="kwrd">null</span>,
    person:Ember.entityRef(<span class="str">'personId'</span>) <span class="rem">// [3]</span>
});</pre>
<style type="text/css">
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
<style type="text/css">
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
<p>As you can see on line [3] above, a <strong>person</strong> property is declared not with a value, but as a function. Ember.js includes support for computed properties which, when properly used, return a computed value and can be automatically updated when a dependency is established between the function and the values the computed property requires. Following is the code for the <strong>entityRef </strong>function.</p>
<pre class="csharpcode">(<span class="kwrd">function</span> () {
    Ember.entityRef = <span class="kwrd">function</span> (property, type) {
        <span class="rem">// auto build connection if property is in the form</span>
        <span class="rem">// of 'typenameID' if type is not specified</span>
        <span class="kwrd">if</span> (arguments.length === 1 &amp;&amp; property) {   <span class="rem">// [1]</span>
            <span class="kwrd">var</span> l = property.length;
            <span class="kwrd">if</span> (l &gt; 2 &amp;&amp; property.substr(l - 2).toLowerCase() === <span class="str">'id'</span>) {
                type = property.substr(0, l - 2);
            } <span class="kwrd">else</span> {
                <span class="kwrd">throw</span> <span class="kwrd">new</span> Error(<span class="str">&quot;Type not specified, and cannot automatically determine store name. Referenced property name must end with Id.&quot;</span>);
            }
        }
        <span class="kwrd">var</span> fn = <span class="kwrd">new</span> Function(<span class="str">&quot;return Demo2App.Stores.find('&quot;</span> + type + <span class="str">&quot;', this.get('&quot;</span> + property + <span class="str">&quot;')); &quot;</span>);
        <span class="kwrd">return</span> Ember.computed(fn).property(property);
    };
})();</pre>
<style type="text/css">
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
<style type="text/css">
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
<p>Thankfully, the entityRef function doesn’t need to do much, and much of what it does is make it easy to make a connection automatically between the local data store and the source property by using a simple naming convention. </p>
<p>Starting at [1], the code makes a simple attempt at doing an “auto-map” when a type isn’t specified specifically. In this case, when “personId” is passed to the function, it chops the “Id” off and uses “person” as the name of the data store automatically. It <strong>doesn’t validate </strong>the name or anything sophisticated (as I said, it’s light on error checking), but it works when everything is specified correctly. In this case, there’s a “person” data store created in the JavaScript code created a little bit later.</p>
<pre class="csharpcode"><span class="kwrd">var</span> personsDS = Demo2App.Stores.create(<span class="str">'person'</span>);</pre>
<style type="text/css">
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
<p>Once the data store type name is located, it creates a new function which returns the object by Id stored in the named data store. That function is wrapped in an Ember computed function, and then the dependency on the “personId” is established. Both of these features are core to the Ember JavaScript library (check out the <a href="http://www.emberjs.com/">Ember JavaScript library</a> web site for more information). While they may look a bit strange if you’re not familiar with Ember, trust me, they’re perfectly normal. <img src='http://www.wiredprairie.us/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>The remaining code is standard Ember JavaScript code with the addition of a simple data store object that manages objects by Id. </p>
<p>Have fun!</p>
<p>(And if you haven’t transitioned from the earlier SproutCore 2.0 betas to Ember, this code should work with a tiny bit of namespace fixing).</p>
]]></content:encoded>
			<wfw:commentRss>http://www.wiredprairie.us/blog/index.php/archives/1345/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Sending an email using SMTP in .NET 4.0</title>
		<link>http://www.wiredprairie.us/blog/index.php/archives/1216</link>
		<comments>http://www.wiredprairie.us/blog/index.php/archives/1216#comments</comments>
		<pubDate>Wed, 13 Jul 2011 12:50:49 +0000</pubDate>
		<dc:creator>Aaron</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[SMTP]]></category>

		<guid isPermaLink="false">http://www.wiredprairie.us/blog/index.php/archives/1216</guid>
		<description><![CDATA[I had need of sending embedded images within an e-mail. .NET has had a few handy classes for sending an email using SMTP for a few versions. While there were a few examples floating around the internet, none were as clean and easy to follow as I expected. So, I decided to create a simple [...]]]></description>
			<content:encoded><![CDATA[<p>I had need of sending embedded images within an e-mail. .NET has had a few handy classes for sending an email using SMTP for a few versions. While there were a few examples floating around the internet, none were as clean and easy to follow as I expected. So, I decided to create a simple sample application in C# which demonstrates how to embed an image (or other content) in a email that contains both plain text and HTML content. It’s really not difficult. A number of examples ignore the fact that almost all of the objects need to be disposed, so I corrected that. This code is intentionally written synchronously to keep the sample simpler and easier to follow (and I didn’t need asynchronous sending for my learning exercise). </p>
<p><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.wiredprairie.us/blog/wp-content/uploads/2011/07/image.png" width="289" height="142" /></p>
<p>Above is the output (if you happen to have a picture of NYC). The example code uses Gmail as the SMTP host (it has the settings that generally work for gmail in most situations, including using SSL).</p>
<pre class="code"><span style="color: blue">using </span>System;
<span style="color: blue">using </span>System.Collections.Generic;
<span style="color: blue">using </span>System.Linq;
<span style="color: blue">using </span>System.Text;
<span style="color: blue">using </span>System.Net.Mail;
<span style="color: blue">using </span>System.Net;
<span style="color: blue">using </span>System.Net.Mime;

<span style="color: blue">namespace </span>TestEmailAttachments
{
    <span style="color: blue">public class </span><span style="color: #2b91af">EmailSettings
    </span>{
        <span style="color: blue">public string </span>ToAddress { <span style="color: blue">get</span>; <span style="color: blue">set</span>; }
        <span style="color: blue">public string </span>FromAddress { <span style="color: blue">get</span>; <span style="color: blue">set</span>; }
        <span style="color: blue">public string </span>AccountName { <span style="color: blue">get</span>; <span style="color: blue">set</span>; }
        <span style="color: blue">public string </span>AccountPassword { <span style="color: blue">get</span>; <span style="color: blue">set</span>; }
    }

    <span style="color: blue">class </span><span style="color: #2b91af">Program
    </span>{
        <span style="color: blue">static void </span>Main(<span style="color: blue">string</span>[] args)
        {
            <span style="color: #2b91af">EmailSettings </span>settings = <span style="color: blue">new </span><span style="color: #2b91af">EmailSettings</span>()
            {
                ToAddress = <span style="color: #a31515">&quot;sample@example.com&quot;</span>,
                FromAddress = <span style="color: #a31515">&quot;sender@example.com&quot;</span>,
                AccountName = <span style="color: #a31515">&quot;sample@example.com&quot;</span>,
                AccountPassword = <span style="color: #a31515">&quot;mypa$$w0rd$ux&quot;
            </span>};
            SendEmail(settings);
            <span style="color: #2b91af">Console</span>.WriteLine(<span style="color: #a31515">&quot;Done&quot;</span>);
            <span style="color: #2b91af">Console</span>.ReadKey();
        }

        <span style="color: blue">static void </span>SendEmail(<span style="color: #2b91af">EmailSettings </span>settings)
        {
            <span style="color: blue">if </span>(settings == <span style="color: blue">null</span>) { <span style="color: blue">throw new </span><span style="color: #2b91af">ArgumentNullException</span>(<span style="color: #a31515">&quot;need settings!&quot;</span>);  }
            <span style="color: green">// Almost everything used my the mail system is disposable
            // so, we'll use 'using' liberally
            </span><span style="color: blue">using </span>(<span style="color: #2b91af">MailMessage </span>mail = <span style="color: blue">new </span><span style="color: #2b91af">MailMessage</span>())
            {
                <span style="color: green">//set the e-mail address
                </span>mail.From = <span style="color: blue">new </span><span style="color: #2b91af">MailAddress</span>(settings.FromAddress);
                mail.To.Add(settings.ToAddress);

                <span style="color: green">//set the subject
                </span>mail.Subject = <span style="color: #a31515">&quot;New York City!&quot;</span>;

                <span style="color: green">// create some content
                </span><span style="color: blue">string </span>textPlain = <span style="color: #a31515">&quot;I'm sorry, but you won't see the pretty photos inline. Look for an attachment.&quot;</span>;
                <span style="color: blue">string </span>textHtml = <span style="color: #a31515">&quot;Here is an embedded image.&lt;img src=cid:NewYorkCity1&gt;&quot;</span>;

                <span style="color: green">// setup the alternate views (so different type of e-mail clients can see the content)
                </span><span style="color: blue">using </span>(<span style="color: #2b91af">AlternateView
                        </span>plainView = <span style="color: #2b91af">AlternateView</span>.CreateAlternateViewFromString(textPlain, <span style="color: blue">null</span>,
                            <span style="color: #2b91af">MediaTypeNames</span>.<span style="color: #2b91af">Text</span>.Plain),
                        htmlView = <span style="color: #2b91af">AlternateView</span>.CreateAlternateViewFromString(textHtml, <span style="color: blue">null</span>,
                            <span style="color: #2b91af">MediaTypeNames</span>.<span style="color: #2b91af">Text</span>.Html) )
                {
                    <span style="color: green">//create the LinkedResource (embedded image)
                    </span><span style="color: blue">using </span>(<span style="color: #2b91af">LinkedResource </span>photo =
                        <span style="color: blue">new </span><span style="color: #2b91af">LinkedResource</span>(<span style="color: #a31515">@&quot;D:\Temp\nyc2009\NewYorkCity (1 of 1).jpg&quot;</span>))
                    {
                        <span style="color: green">// the content id here must match the content id used in the html as the 'cid:NNNNNNNN'
                        </span>photo.ContentId = <span style="color: #a31515">&quot;NewYorkCity1&quot;</span>;
                        <span style="color: green">// set the content type to match the image (in this case, it's a jpeg)
                        </span>photo.ContentType = <span style="color: blue">new </span><span style="color: #2b91af">ContentType</span>(<span style="color: #2b91af">MediaTypeNames</span>.<span style="color: #2b91af">Image</span>.Jpeg)
                            { Name = <span style="color: #a31515">&quot;NewYorkCity (1 of 1).jpg&quot; </span>};

                        <span style="color: green">// the htmlView needs the resource
                        </span>htmlView.LinkedResources.Add(photo);

                        <span style="color: green">// add each view to the alternate views collection
                        </span>mail.AlternateViews.Add(plainView);
                        mail.AlternateViews.Add(htmlView);

                        <span style="color: green">// send the message, again diposable
                        </span><span style="color: blue">using </span>(<span style="color: #2b91af">SmtpClient </span>smtp = <span style="color: blue">new </span><span style="color: #2b91af">SmtpClient</span>())
                        {
                            <span style="color: green">// these are gmail settings... you'll need to adjust them as needed
                            </span>smtp.EnableSsl = <span style="color: blue">true</span>;
                            smtp.Host = <span style="color: #a31515">&quot;smtp.gmail.com&quot;</span>;
                            smtp.Port = 587;
                            smtp.UseDefaultCredentials = <span style="color: blue">false</span>;
                            smtp.Credentials = <span style="color: blue">new </span><span style="color: #2b91af">NetworkCredential</span>(settings.AccountName,
                                settings.AccountPassword);
                            smtp.Send(mail);
                        }
                    }
                }
            }
        }
    }
}</pre>
<p>Use this only for good. <img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://www.wiredprairie.us/blog/wp-content/uploads/2011/07/wlEmoticon-smile.png" /></p>
]]></content:encoded>
			<wfw:commentRss>http://www.wiredprairie.us/blog/index.php/archives/1216/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Return of syntax highlighting and code completion for KnockoutJS in VS2010 (when using Razor)</title>
		<link>http://www.wiredprairie.us/blog/index.php/archives/1204</link>
		<comments>http://www.wiredprairie.us/blog/index.php/archives/1204#comments</comments>
		<pubDate>Fri, 01 Apr 2011 01:35:03 +0000</pubDate>
		<dc:creator>Aaron</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[MVC]]></category>
		<category><![CDATA[Razor]]></category>

		<guid isPermaLink="false">http://www.wiredprairie.us/blog/index.php/archives/1204</guid>
		<description><![CDATA[OK, admittedly, this is a workaround for an issue where the syntax of jQuery Templates (used by KnockoutJS) doesn’t lend itself to the most pleasant editing experience in Visual Studio, but eh. This was inspired after talking with Ryan a bit and seeing a recent post on his new web site. Here’s what I came [...]]]></description>
			<content:encoded><![CDATA[<p>OK, admittedly, this is a workaround for an issue where the syntax of <a href="http://api.jquery.com/jquery.tmpl/">jQuery Templates</a> (used by <a href="http://knockoutjs.com/">KnockoutJS</a>) doesn’t lend itself to the most pleasant editing experience in Visual Studio, but eh.</p>
<p>This was inspired after talking with Ryan a bit and seeing a recent <a href="http://www.knockmeout.net/2011/03/using-external-jquery-template-files.html">post</a> on his new web site. Here’s what I came up with.</p>
<p>Following a similar pattern to the <a href="http://msdn.microsoft.com/en-us/library/dd410596.aspx">BeginForm</a> Helper, I created a “Template” helper. It’s simple to use as the code below demonstrates (the example is taken from the KnockoutJS web site).</p>
<pre class="code"><span style="color: blue">&lt;</span><span style="color: maroon">div </span><span style="color: red">data-bind</span><span style="color: blue">='template: &quot;personTemplate&quot;'&gt; &lt;/</span><span style="color: maroon">div</span><span style="color: blue">&gt;

</span><span style="background: yellow">@</span><span style="color: blue">using </span>(Html.Template(<span style="color: #a31515">&quot;personTemplate&quot;</span>))
{ <span style="background: yellow">&lt;text&gt;</span>
    ${ name } is ${ age } years old
    <span style="color: blue">&lt;</span><span style="color: maroon">button </span><span style="color: red">data-bind</span><span style="color: blue">='click: makeOlder'&gt;</span>Make older<span style="color: blue">&lt;/</span><span style="color: maroon">button</span><span style="color: blue">&gt;
</span><span style="background: yellow">&lt;/text&gt;</span> }

<span style="color: blue">&lt;</span><span style="color: maroon">script </span><span style="color: red">type</span><span style="color: blue">='text/javascript'&gt;
    var </span>viewModel = {
        name: ko.observable(<span style="color: maroon">'Bert'</span>),
        age: ko.observable(78),
        makeOlder: <span style="color: blue">function </span>() {
            <span style="color: blue">this</span>.age(<span style="color: blue">this</span>.age() + 1);
        }
    };
    ko.applyBindings(viewModel);
<span style="color: blue">&lt;/</span><span style="color: maroon">script</span><span style="color: blue">&gt;

</span></pre>
<p>Sometimes, the Razor compiler/engine is confused by the template syntax however, so to work around that, you’ll need to add the &lt;text&gt;…&lt;/text&gt; block to prevent the template syntax from being parsed as Razor syntax. The example above shouldn’t require it. The one that causes problems I’ve found mostly right now is the conditional {{ if }} block which apparently looks like Razor/C# code, and fails. The &lt;text&gt; tag syntax isn’t tragic. The most annoying part is that it highlights as bright yellow.</p>
<p>The Template Helper emits the start and end &lt;script&gt; tags appropriately. There’s an optional second parameter that allows the developer to override the default of the type being text/html.</p>
<pre class="code"><span style="color: blue">using </span>System;
<span style="color: blue">using </span>System.Collections.Generic;
<span style="color: blue">using </span>System.Linq;
<span style="color: blue">using </span>System.Web;
<span style="color: blue">using </span>System.Web.Mvc;

<span style="color: blue">namespace </span>TestMVC.Web
{
    <span style="color: blue">public static class </span><span style="color: #2b91af">MvcExtensions
    </span>{
        <span style="color: gray">/// &lt;summary&gt;
        /// </span><span style="color: green">Automatically generates a script block, useful for non-typical script
        </span><span style="color: gray">/// </span><span style="color: green">tags that have HTML content inside (like those in jquery templates for example)
        </span><span style="color: gray">/// </span><span style="color: green">Always use this within using statement as Dispose must be called to properly close
        </span><span style="color: gray">/// </span><span style="color: green">the script tag.
        </span><span style="color: gray">/// &lt;/summary&gt;
        /// &lt;param name=&quot;helper&quot;&gt;</span><span style="color: green">Html Helper object</span><span style="color: gray">&lt;/param&gt;
        /// &lt;param name=&quot;id&quot;&gt;</span><span style="color: green">The ID for the generated script tag.</span><span style="color: gray">&lt;/param&gt;
        /// &lt;returns&gt;</span><span style="color: green">TemplateBlock object which must be disposed to properly emit
        </span><span style="color: gray">/// </span><span style="color: green">the necessary script tags.</span><span style="color: gray">&lt;/returns&gt;
        </span><span style="color: blue">public static </span><span style="color: #2b91af">TemplateBlock </span>Template(<span style="color: blue">this </span><span style="color: #2b91af">HtmlHelper </span>helper, <span style="color: blue">string </span>id)
        {
            <span style="color: blue">return </span>Template(helper, id, <span style="color: #a31515">&quot;&quot;</span>);
        }

        <span style="color: gray">/// &lt;summary&gt;
        /// </span><span style="color: green">Automatically generates a script block, useful for non-typical script
        </span><span style="color: gray">/// </span><span style="color: green">tags that have HTML content inside (like those in jquery templates for example)
        </span><span style="color: gray">/// </span><span style="color: green">Always use this within using statement as Dispose must be called to properly close
        </span><span style="color: gray">/// </span><span style="color: green">the script tag.
        </span><span style="color: gray">/// &lt;/summary&gt;
        /// &lt;param name=&quot;helper&quot;&gt;</span><span style="color: green">Html Helper object</span><span style="color: gray">&lt;/param&gt;
        /// &lt;param name=&quot;id&quot;&gt;</span><span style="color: green">The ID for the generated script tag.</span><span style="color: gray">&lt;/param&gt;
        /// &lt;param name=&quot;type&quot;&gt;</span><span style="color: green">Defaults to text/html, but may be overriden by setting
        </span><span style="color: gray">/// </span><span style="color: green">this parameter.</span><span style="color: gray">&lt;/param&gt;
        /// &lt;returns&gt;</span><span style="color: green">TemplateBlock object which must be disposed to properly emit
        </span><span style="color: gray">/// </span><span style="color: green">the necessary script tags.</span><span style="color: gray">&lt;/returns&gt;
        </span><span style="color: blue">public static </span><span style="color: #2b91af">TemplateBlock </span>Template(<span style="color: blue">this </span><span style="color: #2b91af">HtmlHelper </span>helper, <span style="color: blue">string </span>id, <span style="color: blue">string </span>type)
        {
            <span style="color: blue">return new </span><span style="color: #2b91af">TemplateBlock</span>(helper.ViewContext, id, type);
        }

    }

    <span style="color: blue">public class </span><span style="color: #2b91af">TemplateBlock </span>: <span style="color: #2b91af">IDisposable
    </span>{
        <span style="color: blue">private bool </span>_disposed = <span style="color: blue">false</span>;
        <span style="color: blue">public </span><span style="color: #2b91af">ViewContext </span>ViewContext { <span style="color: blue">get</span>; <span style="color: blue">private set</span>; }

        <span style="color: blue">public </span>TemplateBlock(<span style="color: #2b91af">ViewContext </span>context, <span style="color: blue">string </span>id, <span style="color: blue">string </span>type)
        {
            <span style="color: blue">this</span>.ViewContext = context;
            type = <span style="color: blue">string</span>.IsNullOrWhiteSpace(type) ? <span style="color: #a31515">&quot;text/html&quot; </span>: type;
            context.Writer.Write(<span style="color: #a31515">&quot;&lt;script type='{0}' id='{1}'&gt;\n&quot;</span>, type, id);
        }

        <span style="color: blue">private void </span>Disposing(<span style="color: blue">bool </span>disposing)
        {
            <span style="color: blue">if </span>(!_disposed)
            {
                _disposed = <span style="color: blue">true</span>;
                ViewContext.Writer.Write(<span style="color: #a31515">&quot;&lt;/script&gt;\n&quot;</span>);
            }
        }
        <span style="color: blue">public void </span>Dispose()
        {
            <span style="color: blue">this</span>.Disposing(<span style="color: blue">true</span>);
        }
    }

}</pre>
<p>Enjoy.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.wiredprairie.us/blog/index.php/archives/1204/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

