<?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>Contact and Coil &#187; Software</title>
	<atom:link href="http://www.contactandcoil.com/category/software/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.contactandcoil.com</link>
	<description>Nearly In Control</description>
	<lastBuildDate>Sat, 04 Feb 2012 21:00:46 +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>OWI-535 Robot Arm with USB Controller from C# and .NET</title>
		<link>http://www.contactandcoil.com/automation/home-automation/owi-535-robot-arm-with-usb-controller-from-c-and-net/</link>
		<comments>http://www.contactandcoil.com/automation/home-automation/owi-535-robot-arm-with-usb-controller-from-c-and-net/#comments</comments>
		<pubDate>Sat, 04 Feb 2012 21:00:46 +0000</pubDate>
		<dc:creator>Scott Whitlock</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[Home Automation]]></category>
		<category><![CDATA[c#]]></category>
		<category><![CDATA[libusbdotnet]]></category>
		<category><![CDATA[owi-535]]></category>
		<category><![CDATA[robot-arm]]></category>

		<guid isPermaLink="false">http://www.contactandcoil.com/?p=1014</guid>
		<description><![CDATA[<div class="addthis_toolbox addthis_default_style " addthis:url='http://www.contactandcoil.com/automation/home-automation/owi-535-robot-arm-with-usb-controller-from-c-and-net/' addthis:title='OWI-535 Robot Arm with USB Controller from C# and .NET '  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div>I got the OWI-535 &#8220;Robot Arm Edge&#8221; 5-Axis robot arm and USB Controller add-on for Christmas: The robot arm comes as a kit that you assemble yourself, and my 3 year old and I had lots of fun putting it together (it helped to have some tiny fingers around, honestly). It comes with a manual [...]<div class="addthis_toolbox addthis_default_style addthis_32x32_style" addthis:url='http://www.contactandcoil.com/automation/home-automation/owi-535-robot-arm-with-usb-controller-from-c-and-net/' addthis:title='OWI-535 Robot Arm with USB Controller from C# and .NET ' ><a class="addthis_button_preferred_1"></a><a class="addthis_button_preferred_2"></a><a class="addthis_button_preferred_3"></a><a class="addthis_button_preferred_4"></a><a class="addthis_button_compact"></a></div>]]></description>
			<content:encoded><![CDATA[<div class="addthis_toolbox addthis_default_style " addthis:url='http://www.contactandcoil.com/automation/home-automation/owi-535-robot-arm-with-usb-controller-from-c-and-net/' addthis:title='OWI-535 Robot Arm with USB Controller from C# and .NET '  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div><p>I got the OWI-535 &#8220;Robot Arm Edge&#8221; 5-Axis robot arm and USB Controller add-on for Christmas:</p>
<p><center><br />
<iframe src="http://rcm.amazon.com/e/cm?lt1=_blank&#038;bc1=000000&#038;IS2=1&#038;bg1=FFFFFF&#038;fc1=000000&#038;lc1=0000FF&#038;t=moms4mom00-20&#038;o=1&#038;p=8&#038;l=as4&#038;m=amazon&#038;f=ifr&#038;ref=ss_til&#038;asins=B0017OFRCY" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"></iframe><iframe src="http://rcm.amazon.com/e/cm?lt1=_blank&#038;bc1=000000&#038;IS2=1&#038;bg1=FFFFFF&#038;fc1=000000&#038;lc1=0000FF&#038;t=moms4mom00-20&#038;o=1&#038;p=8&#038;l=as4&#038;m=amazon&#038;f=ifr&#038;ref=ss_til&#038;asins=B0028MBWS2" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"></iframe><br />
</center></p>
<p>The robot arm comes as a kit that you assemble yourself, and my 3 year old and I had lots of fun putting it together (it helped to have some tiny fingers around, honestly).  It comes with a manual controller that allows you to rotate all 4 joints, plus the gripper.  It&#8217;s fun to play around with, but let&#8217;s be honest, everyone wants to hook it up to their computer.</p>
<p>Unfortunately the software that comes with the USB controller works on Windows 7, but &#8220;32-bit only&#8221;.  That was a little annoying, but hey, I didn&#8217;t really want to stick with their canned software anyway.  I figured I would see if I could get it to work from C#.  I was surprised to find a great site by Dr. Andrew Davison in Thailand who wrote some Java code as part of his site for his book <a href="http://fivedots.coe.psu.ac.th/~ad/jg" onclick="pageTracker._trackPageview('/outgoing/fivedots.coe.psu.ac.th/_ad/jg?referer=');">Killer Game Programming in Java</a> (chapter <a href="http://fivedots.coe.psu.ac.th/~ad/jg/nui06/index.html" onclick="pageTracker._trackPageview('/outgoing/fivedots.coe.psu.ac.th/_ad/jg/nui06/index.html?referer=');">NUI-6 Controlling a Robot Arm</a>, which doesn&#8217;t appear in the book).  Surprisingly he went as far as to do the inverse kinematic equations so you can give the arm a set of X,Y,Z co-ordinates (in mm) in &#8220;world frame&#8221; and it will calculate all the join angles to get to that location, and then used timed moves to get the arm into that position.</p>
<p>His Java library uses libusb-win32, and that library has a .NET equivalent called <a href="http://sourceforge.net/projects/libusbdotnet/" onclick="pageTracker._trackPageview('/outgoing/sourceforge.net/projects/libusbdotnet/?referer=');">LibUsbDotNet</a>.  The API&#8217;s don&#8217;t appear to be the same, but thankfully I managed to find a thread on SourceForge about <a href="http://sourceforge.net/apps/phpbb/libusbdotnet/viewtopic.php?f=3&#038;t=75" onclick="pageTracker._trackPageview('/outgoing/sourceforge.net/apps/phpbb/libusbdotnet/viewtopic.php?f=3_038_t=75&amp;referer=');">controlling the OWI-535 using LibUsbDotNet</a>.  So, over the course of a couple of nights, after the kids went to bed, I ported Dr. Davison&#8217;s Java code over to C# (quite easy actually) and replaced the libusb-win32 calls with LibUsbDotNet API calls.  It worked!</p>
<p>Here is the .NET solution that I wrote called <a href='http://www.contactandcoil.com/wp-content/uploads/TestOwi535.zip'>TestOwi535</a>.  I used Visual C# 2010 Express Edition to write it, so that&#8217;s free.  Also, you <i>must download and install LibUsbDotNet first and run the USB InfWizard first to generate a .inf file (you have to do this with the robot arm plugged in and turned on), and then use that .inf file to install LibUsbDotNet as the driver</i> (technically you&#8217;re installing libusb-win32 as the driver and LibUsbDotNet is just the C# wrapper).</p>
<p>If you right click on the C# project in the solution explorer, you&#8217;ll find 3 options for startup object: MainClass is the original code I found in the SourceForge thread, but it&#8217;s just proof of concept code and only moves one joint in one direction for a second.  The ArmCommunicator class is an interactive console application that allows you to move all joints (and control the gripper and light) by typing in keyboard commands.  Finally the RobotArm class is the full inverse kinematics thing.  In the last case, make sure you start with the arm at the zero position (base pointing away from the battery compartment, and all joints in-line straight up in the air, gripper pointing directly up, and gripper open).  It will do a move to the table, to the front right of the arm, close the gripper, and then move back to zero and open the gripper.</p>
<p>Unfortunately that&#8217;s where you start to see the obvious deficiency of the arm: it has no position feedback.  That means even though it tracks its position in the code, the physical position eventually drifts away from the internal position tracking, and the arm eventually doesn&#8217;t know where it is (it&#8217;s just using timed moves).  One of the biggest areas where you could improve it is to change the joint rates so that it knows that the joints move faster when going down than when going up.</p>
<p>Still, it&#8217;s a neat little toy for the price.  I&#8217;m going to start hunting around for a way to add joint position feedback, as that would really improve the performance.  I also want to rewrite a new module from the ground up that allows concurrent joint moves (this one only moves one joint at a time).  Ideally you want to control this thing in &#8220;gripper frame&#8221; instead of &#8220;world frame&#8221;.</p>
<p>Happy hacking!</p>
<div class="addthis_toolbox addthis_default_style addthis_32x32_style" addthis:url='http://www.contactandcoil.com/automation/home-automation/owi-535-robot-arm-with-usb-controller-from-c-and-net/' addthis:title='OWI-535 Robot Arm with USB Controller from C# and .NET ' ><a class="addthis_button_preferred_1"></a><a class="addthis_button_preferred_2"></a><a class="addthis_button_preferred_3"></a><a class="addthis_button_preferred_4"></a><a class="addthis_button_compact"></a></div>]]></content:encoded>
			<wfw:commentRss>http://www.contactandcoil.com/automation/home-automation/owi-535-robot-arm-with-usb-controller-from-c-and-net/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Google&#8217;s Self-Driving Car</title>
		<link>http://www.contactandcoil.com/software/googles-self-driving-car/</link>
		<comments>http://www.contactandcoil.com/software/googles-self-driving-car/#comments</comments>
		<pubDate>Tue, 08 Nov 2011 11:43:00 +0000</pubDate>
		<dc:creator>Scott Whitlock</dc:creator>
				<category><![CDATA[Software]]></category>
		<category><![CDATA[google]]></category>
		<category><![CDATA[self-driving-car]]></category>

		<guid isPermaLink="false">http://www.contactandcoil.com/?p=963</guid>
		<description><![CDATA[<div class="addthis_toolbox addthis_default_style " addthis:url='http://www.contactandcoil.com/software/googles-self-driving-car/' addthis:title='Google&#8217;s Self-Driving Car '  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div>Google has been developing a self-driving car. It&#8217;s abnormal for a company to go completely outside of its comfort zone when designing new products, so why would Google go into the automotive control system industry? They claim it&#8217;s to improve safety. They&#8217;ve also offered the pragmatic assertion that &#8220;people just want it&#8221;. Google is a [...]<div class="addthis_toolbox addthis_default_style addthis_32x32_style" addthis:url='http://www.contactandcoil.com/software/googles-self-driving-car/' addthis:title='Google&#8217;s Self-Driving Car ' ><a class="addthis_button_preferred_1"></a><a class="addthis_button_preferred_2"></a><a class="addthis_button_preferred_3"></a><a class="addthis_button_preferred_4"></a><a class="addthis_button_compact"></a></div>]]></description>
			<content:encoded><![CDATA[<div class="addthis_toolbox addthis_default_style " addthis:url='http://www.contactandcoil.com/software/googles-self-driving-car/' addthis:title='Google&#8217;s Self-Driving Car '  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div><p>Google has been developing a <a href="http://www.wheels.ca/article/794356" onclick="pageTracker._trackPageview('/outgoing/www.wheels.ca/article/794356?referer=');">self-driving car</a>.</p>
<p>It&#8217;s abnormal for a company to go completely outside of its comfort zone when designing new products, so why would Google go into the automotive control system industry?  They claim it&#8217;s to improve safety.  They&#8217;ve also offered the pragmatic assertion that &#8220;people just want it&#8221;.</p>
<p>Google is a web company.  It makes <i>huge</i> gobs of money from advertising, and advertising scales with web traffic.  Google&#8217;s designing a self-driving car so that <i>drivers can spend their commute time surfing the web on mobile devices</i>.  That&#8217;s the only explanation that makes sense.</p>
<p>Not that I mind, of course&#8230; I&#8217;d love to be able to read on the way to work.  When can I buy my self-driving car?  Can I get one that&#8217;s subsidized by ads?</p>
<div class="addthis_toolbox addthis_default_style addthis_32x32_style" addthis:url='http://www.contactandcoil.com/software/googles-self-driving-car/' addthis:title='Google&#8217;s Self-Driving Car ' ><a class="addthis_button_preferred_1"></a><a class="addthis_button_preferred_2"></a><a class="addthis_button_preferred_3"></a><a class="addthis_button_preferred_4"></a><a class="addthis_button_compact"></a></div>]]></content:encoded>
			<wfw:commentRss>http://www.contactandcoil.com/software/googles-self-driving-car/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The Skyscraper, the Great Wall, and the Tree</title>
		<link>http://www.contactandcoil.com/software/the-skyscraper-the-great-wall-and-the-tree/</link>
		<comments>http://www.contactandcoil.com/software/the-skyscraper-the-great-wall-and-the-tree/#comments</comments>
		<pubDate>Tue, 27 Sep 2011 02:20:02 +0000</pubDate>
		<dc:creator>Scott Whitlock</dc:creator>
				<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://www.contactandcoil.com/?p=953</guid>
		<description><![CDATA[<div class="addthis_toolbox addthis_default_style " addthis:url='http://www.contactandcoil.com/software/the-skyscraper-the-great-wall-and-the-tree/' addthis:title='The Skyscraper, the Great Wall, and the Tree '  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div>One World Trade Center will be a 105 story super-skyscraper when completed. It&#8217;s estimated total cost is $3.1 Billion. When it&#8217;s complete, how much would it cost to add the 106th story? Would it be 105th of $3.1 Billion? No. The building was constructed from the ground up to be a certain height. The maximum [...]<div class="addthis_toolbox addthis_default_style addthis_32x32_style" addthis:url='http://www.contactandcoil.com/software/the-skyscraper-the-great-wall-and-the-tree/' addthis:title='The Skyscraper, the Great Wall, and the Tree ' ><a class="addthis_button_preferred_1"></a><a class="addthis_button_preferred_2"></a><a class="addthis_button_preferred_3"></a><a class="addthis_button_preferred_4"></a><a class="addthis_button_compact"></a></div>]]></description>
			<content:encoded><![CDATA[<div class="addthis_toolbox addthis_default_style " addthis:url='http://www.contactandcoil.com/software/the-skyscraper-the-great-wall-and-the-tree/' addthis:title='The Skyscraper, the Great Wall, and the Tree '  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div><p><a href="http://en.wikipedia.org/wiki/One_World_Trade_Center" onclick="pageTracker._trackPageview('/outgoing/en.wikipedia.org/wiki/One_World_Trade_Center?referer=');">One World Trade Center</a> will be a 105 story super-skyscraper when completed.  It&#8217;s estimated total cost is $3.1 Billion.</p>
<p>When it&#8217;s complete, how much would it cost to add the 106th story?  Would it be 105th of $3.1 Billion?  No.  The building was constructed from the ground up to be a certain height.  The maximum height depends on the ground it&#8217;s sitting on, the foundation, the first floor, and so on.  Each of those would need to be strengthened to add one more story.</p>
<p>It&#8217;s possible to engineer a building so that you can add more floors later, but that means over-engineering the foundation and the structure.</p>
<p>Contrast the building of a skyscraper with the building of the Great Wall in China.  The Great Wall is infinitely scalable.  It stretches for many thousands of kilometers, and each additional kilometer probably cost less than the one before because the builders became more skilled as they worked.</p>
<p>The difference between the skyscraper and the Great Wall is all about dependencies.  In the case of the skyscraper, every story depends on everything below it.  In the case of the Great Wall, each section of wall only depends on the ground underneath, and the sections of wall on either side.  If one section is faulty, you can easily demolish it and rebuild it.  If one section is in the wrong place, you only have to rebuild a copy of sections to go around the obstacle.</p>
<p>When you&#8217;re building the Great Wall, you can probably take an experienced stonemason and have him start laying stone on the first day, without much thought about the design.  With a skyscraper, it&#8217;s the opposite.  You spend years designing before you ever break ground.</p>
<p>When people first started to write software, they built it like the Great Wall.  Just start writing code.  The program gets longer and longer.  Unfortunately, complex programs don&#8217;t have linear dependencies.  Each part of the code tends to have dependencies on every other part.  Out of this came two things: the <a href="http://en.wikipedia.org/wiki/Waterfall_model" onclick="pageTracker._trackPageview('/outgoing/en.wikipedia.org/wiki/Waterfall_model?referer=');">Waterfall</a> model, and <a href="http://en.wikipedia.org/wiki/Modular_programming" onclick="pageTracker._trackPageview('/outgoing/en.wikipedia.org/wiki/Modular_programming?referer=');">Modular programming</a>.  While modular programming was a success at reducing dependencies, and eventually led to object-oriented (and message-oriented) programming, the Waterfall model was eventually supplanted by Agile methodologies.</p>
<p>The software developed by Agile methodologies is neither like the Great Wall (there are still many inter-dependencies) and yet nothing like the traditional skyscraper (because the many dependencies are loosely coupled).  </p>
<p>Agile software grows organically, like a tree.  You can cut off a limb that&#8217;s no longer useful, or grow in a new direction when you must.</p>
<p>Many programmers seem to think that Agile means you don&#8217;t have to design.  This isn&#8217;t true.  A tree still has an architecture.  It&#8217;s just a more flexible architecture than a skyscraper.  Instead of building each new layer on top of the layers beneath it, you build a scaffolding structure that supports each module independently.</p>
<p>The scaffolding is made up of <a href="http://en.wikipedia.org/wiki/SOLID_(object-oriented_design)" onclick="pageTracker._trackPageview('/outgoing/en.wikipedia.org/wiki/SOLID_object-oriented_design?referer=');">the SOLID</a> principles like the single responsibility principle, and dependency injection, but it also consists of external structures like automated unit tests.  If Agile software is like a tree, you spend more time on the trunk than the branches and more time on the branches than the leaves.  The advantage is that none of the leaves are directly connected, so you can move them.  That&#8217;s what it means to be Agile.</p>
<p>What are the trade-offs?  Agile enthusiasts seem to think that every other methodology is dead, but that&#8217;s not true.  You can still go higher, faster, with a skyscraper, or get started sooner with the Great Wall.</p>
<p>Embedded control systems for automobiles are still built like a skyscraper.  That&#8217;s because the requirements should be very well known, and future changes are unlikely.  On the other hand, you&#8217;d be surprised how many businesses run significant portions of their businesses on top of Excel spreadsheets.  That&#8217;s typical Great Wall methodology.  It works as long as complexity stays low.</p>
<p>Use Agile when you need complexity <i>and</i> flexibility.</p>
<div class="addthis_toolbox addthis_default_style addthis_32x32_style" addthis:url='http://www.contactandcoil.com/software/the-skyscraper-the-great-wall-and-the-tree/' addthis:title='The Skyscraper, the Great Wall, and the Tree ' ><a class="addthis_button_preferred_1"></a><a class="addthis_button_preferred_2"></a><a class="addthis_button_preferred_3"></a><a class="addthis_button_preferred_4"></a><a class="addthis_button_compact"></a></div>]]></content:encoded>
			<wfw:commentRss>http://www.contactandcoil.com/software/the-skyscraper-the-great-wall-and-the-tree/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Editing Logic is Business Logic</title>
		<link>http://www.contactandcoil.com/software/editing-logic-is-business-logic/</link>
		<comments>http://www.contactandcoil.com/software/editing-logic-is-business-logic/#comments</comments>
		<pubDate>Wed, 07 Sep 2011 01:19:25 +0000</pubDate>
		<dc:creator>Scott Whitlock</dc:creator>
				<category><![CDATA[Software]]></category>
		<category><![CDATA[business-logic]]></category>
		<category><![CDATA[entity-model]]></category>
		<category><![CDATA[n-tier]]></category>

		<guid isPermaLink="false">http://www.contactandcoil.com/?p=948</guid>
		<description><![CDATA[<div class="addthis_toolbox addthis_default_style " addthis:url='http://www.contactandcoil.com/software/editing-logic-is-business-logic/' addthis:title='Editing Logic is Business Logic '  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div>If you&#8217;re writing an &#8220;n-tier&#8221; application then you typically split your application into layers, like the &#8220;GUI layer&#8221;, &#8220;business logic layer&#8221;, and &#8220;data layer&#8221;. Even within those layers we typically have more divisions. One of the advantages of this architecture is that you can swap out your outer layers. You should be able to switch [...]<div class="addthis_toolbox addthis_default_style addthis_32x32_style" addthis:url='http://www.contactandcoil.com/software/editing-logic-is-business-logic/' addthis:title='Editing Logic is Business Logic ' ><a class="addthis_button_preferred_1"></a><a class="addthis_button_preferred_2"></a><a class="addthis_button_preferred_3"></a><a class="addthis_button_preferred_4"></a><a class="addthis_button_compact"></a></div>]]></description>
			<content:encoded><![CDATA[<div class="addthis_toolbox addthis_default_style " addthis:url='http://www.contactandcoil.com/software/editing-logic-is-business-logic/' addthis:title='Editing Logic is Business Logic '  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div><p>If you&#8217;re writing an &#8220;n-tier&#8221; application then you typically split your application into layers, like the &#8220;GUI layer&#8221;, &#8220;business logic layer&#8221;, and &#8220;data layer&#8221;.  Even within those layers we typically have more divisions.</p>
<p>One of the advantages of this architecture is that you can swap out your outer layers.  You should be able to switch from SQL Server to MySQL and all your changes should be confined to the data layer.  You should be able to run a web interface in parallel with your desktop GUI just by writing another set of modules in the GUI layer.</p>
<p>This all sounds great in principle, so you start building your application and you run into problems.  Here&#8217;s the typical scenario:</p>
<p><i>Business rule: one salesperson can be associated with one or more regions.</i></p>
<p><i>Business rule: each salesperson has exactly one &#8220;home region&#8221;, which must be one of their associated regions.</i></p>
<p>Now you go and build your entity model, and it probably looks like a SalesPerson class that inherits from the Employee class.  There&#8217;s a many-to-many association between SalesPerson and Region.  The relationship class (SalesPersonRegion) might have a boolean property called HomeRegion (there are other ways to model it, but that&#8217;s a typical and simple way).</p>
<p>Now, you can enforce these constraints on your entity model by making sure that you provide at least one Region in your SalesPerson constructor, and you make that the home region by default.  You provide a SetHomeRegion method that throws an exception if you pass in a non-associated region, and you throw an exception if you try to dissociate the home region.  If you do all this well, then your model is always consistent, and you can reason about your model knowing certain &#8220;invariant&#8221; conditions (as they&#8217;re called) are always true.</p>
<p>All of that, by the way, lives in the Domain Model, which is part of your Business Logic Layer.</p>
<p>Now let&#8217;s build our GUI where we can edit a SalesPerson.  Obviously the GUI stuff goes in the GUI layer.  Depending on your architecture, you might split up your GUI layer into &#8220;View&#8221; and &#8220;ViewModel&#8221; layers (if you use WPF) or &#8220;View&#8221; and &#8220;Controller&#8221; layers (if you&#8217;re using ASP.NET MVC).</p>
<p>Now unless you really don&#8217;t care about your users, this edit screen is going to have a Save and a Cancel button.  The user is typically free to manipulate data on the screen in ways that don&#8217;t necessarily make sense to our business rules, but that&#8217;s OK as long as we don&#8217;t let them save until they get it right.  Plus, they can just cancel and throw away all their edits.</p>
<p>My first mistake when I ran into this situation was assuming that I could just use the entities as my &#8220;scratch-pad&#8221; objects, letting the user manipulate them.  In fact the powerful data binding features of WPF makes you think you can get away with this.  Everyone wants to just bind their WPF controls directly to their entity model.  <strong>It doesn&#8217;t work.</strong>  Ok, let me be a little more specific&#8230; <i>It works great for readonly screens</i>, but <strong>it doesn&#8217;t work for editing screens.</strong></p>
<p>To do this right, you need another model of the data during the editing process.  <i>This other model has slightly different business rules than the entity model you already wrote.</i>  For instance, in our example above about editing a SalesPerson, maybe you want to displays a list of possible regions on the right, let the user drag associated regions into a list on the left, drag out regions to dissociate them, and perhaps each region on the left has a radio button next to it allowing you to select the home region.  During the editing process it might be perfectly legitimate to have no associated regions, or no home region selected.  Unfortunately if you try to use your existing entity model to hold your data structure in the background, you can&#8217;t model this accurately.</p>
<p>There&#8217;s more than one way to solve this.  Some programmers move the business rules out of the entity model and into a Validation service.  Therefore your entity model allows you to build an invalid model, but you can&#8217;t commit those changes into the model unless it passes the validation.  This approach has two problems: one, your entity model no longer enforces the &#8220;invariant&#8221; conditions that make it a little easier to work with (you have to test for validity every time someone hands you an entity), and two, certain data access layers, like NHibernate, automatically default to a mode where all entity changes are immediately candidates for flushing to the database.  Using an entity you loaded from the database as a scratch pad for edits gets complicated.  Technically you can disconnect it from the database, but then it gets confusing&#8230; is this entity real or a scratchpad?</p>
<p>Some other programmers move this logic into the ViewModel or Controller (both of which are in the GUI layer).  This is where it gets ugly, for me.  It&#8217;s true that the &#8220;edit model&#8221; is better separated from the &#8220;entity model&#8221;, but somewhere there has to be logic that maps from one to the other.  When we load up our screen for editing a SalesPerson, we need to map the SalesPerson entity and relationships into the edit model, and when the user clicks Save, first we have to validate that the edit model can be successfully mapped into the entity model, and if it can&#8217;t then give the user a friendly hint about what needs to be fixed.  If it can be mapped, then we do it.  Do you see the problem?  The sticky point is the Validation step.  <i>Validation logic is business logic.</i>  Most MVVM implementations I&#8217;ve seen essentially make the ViewModel the de-facto edit model, and they stuff the validation logic into the ViewModel as well.  I think this is wrong.  Business logic doesn&#8217;t belong in the GUI layer.</p>
<p>All of the following belongs in the business logic layer: the entity model, the edit model, the mapping logic from one to the other and back, and the validation logic.</p>
<p>If you follow this method, then WPF&#8217;s data binding starts to make sense again.  You can map directly to the entity model if you have a read-only screen, and you can map to the edit model for your editing screens.  (In my opinion, many situations call for both an &#8220;add model&#8221; and an &#8220;edit model&#8221; because the allowable actions when you&#8217;re adding something might be different than when you&#8217;re editing one that already exists&#8230; but that&#8217;s not a big deal.)</p>
<p>I apologize if this is all obvious to you, but I really wish someone would have explained this to me sooner.  <img src='http://www.contactandcoil.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<div class="addthis_toolbox addthis_default_style addthis_32x32_style" addthis:url='http://www.contactandcoil.com/software/editing-logic-is-business-logic/' addthis:title='Editing Logic is Business Logic ' ><a class="addthis_button_preferred_1"></a><a class="addthis_button_preferred_2"></a><a class="addthis_button_preferred_3"></a><a class="addthis_button_preferred_4"></a><a class="addthis_button_compact"></a></div>]]></content:encoded>
			<wfw:commentRss>http://www.contactandcoil.com/software/editing-logic-is-business-logic/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ladder Logic vs. C#</title>
		<link>http://www.contactandcoil.com/automation/industrial-automation/ladder-logic-vs-c/</link>
		<comments>http://www.contactandcoil.com/automation/industrial-automation/ladder-logic-vs-c/#comments</comments>
		<pubDate>Tue, 17 May 2011 03:48:57 +0000</pubDate>
		<dc:creator>Scott Whitlock</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[Industrial Automation]]></category>
		<category><![CDATA[ladder-logic]]></category>
		<category><![CDATA[productivity]]></category>

		<guid isPermaLink="false">http://www.contactandcoil.com/?p=826</guid>
		<description><![CDATA[<div class="addthis_toolbox addthis_default_style " addthis:url='http://www.contactandcoil.com/automation/industrial-automation/ladder-logic-vs-c/' addthis:title='Ladder Logic vs. C# '  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div>PC programming and PLC programming are radically different paradigms. I know I&#8217;ve talked about this before, but I wanted to explore something that perplexes me&#8230; why do so many PC programmers hate ladder logic when they are first introduced to it? Ladder logic programmers don&#8217;t seem to have the same reaction when they&#8217;re introduced to [...]<div class="addthis_toolbox addthis_default_style addthis_32x32_style" addthis:url='http://www.contactandcoil.com/automation/industrial-automation/ladder-logic-vs-c/' addthis:title='Ladder Logic vs. C# ' ><a class="addthis_button_preferred_1"></a><a class="addthis_button_preferred_2"></a><a class="addthis_button_preferred_3"></a><a class="addthis_button_preferred_4"></a><a class="addthis_button_compact"></a></div>]]></description>
			<content:encoded><![CDATA[<div class="addthis_toolbox addthis_default_style " addthis:url='http://www.contactandcoil.com/automation/industrial-automation/ladder-logic-vs-c/' addthis:title='Ladder Logic vs. C# '  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div><p>PC programming and PLC programming are radically different paradigms.  I know I&#8217;ve talked about this before, but I wanted to explore something that perplexes me&#8230; why do so many PC programmers hate ladder logic when they are first introduced to it?  Ladder logic programmers don&#8217;t seem to have the same reaction when they&#8217;re introduced to a language like VB or C.</p>
<p>I mean, PC programmers really look down their noses at ladder logic.  Here&#8217;s one <a href="http://stackoverflow.com/questions/1361396/being-a-better-more-efficient-plc-programmer/1361562#1361562" onclick="pageTracker._trackPageview('/outgoing/stackoverflow.com/questions/1361396/being-a-better-more-efficient-plc-programmer/1361562_1361562?referer=');">typical quote</a>:</p>
<p><i>Relay Ladder Logic is a fairly primitive langauge. Its hard to be as productive. Most PLC programmers don&#8217;t use subroutines; its almost as if the PLC world is one that time and software engineering forgot. You can do well by applying simple software engineering methods as a consequence, e.g., define interfaces between blocks of code, even if abstractly.</i></p>
<p>I&#8217;m sorry, but I don&#8217;t buy that.  Ladder logic and, say C#, are designed for solving problems in two very different domains.  In industrial automation, we prefer logic that&#8217;s easy to troubleshoot without taking down the system.</p>
<p>In the world of C#, troubleshooting is usually done in an offline environment.  </p>
<p>My opinion is that Ladder Logic looks a lot like &#8220;polling&#8221; and every PC programmer knows that polling is bad, because it&#8217;s an inefficient use of processor power.  PC programmers prefer event-driven programming, which is how all modern GUI frameworks react to user-initiated input.  They want to see something that says, &#8220;when input A turns on, turn on output B&#8221;.  If you&#8217;re familiar with control systems, your first reaction to that statement is, &#8220;sure, but what if B depends on inputs C, D, and E as well&#8221;?  You&#8217;re right &#8211; it doesn&#8217;t scale, and that&#8217;s the first mistake most people make when starting with event-driven programming: they put all their logic in the event handlers (yeah, I did that too).</p>
<p>Still, there are lots of situations where ladder logic is so much more concise than say, C#, at implementing the same functionality, I just don&#8217;t buy all the hate directed at ladder logic.  I decided to describe it with an example.  Take this relatively simple ladder logic rung:</p>
<p><img src="http://www.contactandcoil.com/wp-content/uploads/SimpleLadderLogic.png" alt="" title="Simple Ladder Logic" width="254" height="138" class="aligncenter size-full wp-image-827" /></p>
<p>What would it take to implement the same <i>logic</i> in C#?  You could say all you really need to write is D = ((A &#038;&#038; B) || D) &#038;& C; but that&#8217;s not exactly true.  When you&#8217;re writing an object oriented program, you have to follow the <a href="http://en.wikipedia.org/wiki/Solid_(object-oriented_design)" onclick="pageTracker._trackPageview('/outgoing/en.wikipedia.org/wiki/Solid_object-oriented_design?referer=');">SOLID</a> principles.  We need to separate our concerns.  Any experienced C# programmer will say that we need to encapsulate this logic in a class (let&#8217;s call it &#8220;DController&#8221; &#8211; things that contain business logic in C# applications are frequently called Controller or Manager).  We also have to make sure that DController only depends on abstract interfaces.  In this case, the logic depends on access to three inputs and one output.  I&#8217;ve gone ahead and defined those interfaces:</p>
<p>[csharp]<br />
    public interface IDiscreteInput<br />
    {<br />
        bool GetValue();<br />
        event EventHandler InputChanged;<br />
    }</p>
<p>    public interface IDiscreteOutput<br />
    {<br />
        void SetValue(bool value);<br />
    }<br />
[/csharp]</p>
<p>Simple enough.  Our controller needs to be able to get the value of an input, and be notified when any input changes.  It needs to be able to change the value of the output.</p>
<p>In order to follow the D in the SOLID principles, we have to inject the dependencies into the DController class, so it has to look something like this:</p>
<p>[csharp]<br />
    internal class DController<br />
    {<br />
        public DController(IDiscreteInput inputA,<br />
            IDiscreteInput inputB, IDiscreteInput inputC,<br />
            IDiscreteOutput outputD)<br />
        {<br />
        }<br />
    }<br />
[/csharp]</p>
<p>That&#8217;s a nice little stub of a class.  Now, as an experienced C# developer, I follow test-driven development, or TDD.  Before I can write any actual logic, I have to write a test that fails.  I break open my unit test suite, and write my first test:</p>
<p>[csharp]<br />
        [TestMethod]<br />
        public void Writes_initial_state_of_false_to_outputD_when_initial_inputs_are_all_false()<br />
        {<br />
            var mockInput = MockRepository.GenerateStub&lt;IDiscreteInput&gt;();<br />
            mockInput.Expect(i =&gt; i.GetValue()).Return(false);<br />
            var mockOutput = MockRepository.GenerateStrictMock&lt;IDiscreteOutput&gt;();<br />
            mockOutput.Expect(o =&gt; o.SetValue(false));</p>
<p>            var test = new DController(mockInput, mockInput, mockInput, mockOutput);</p>
<p>            mockOutput.VerifyAllExpectations();<br />
        }<br />
[/csharp]</p>
<p>Ok, so what&#8217;s going on here?  First, I&#8217;m using a mocking framework called Rhino Mocks to generate &#8220;stub&#8221; and &#8220;mock&#8221; objects that implement the two dependency interfaces I defined earlier.  This first test just checks that the first thing my class does when it starts up is to write a value to output D (in this case, false, because all the inputs are false).  When I run my test it fails, because my DController class doesn&#8217;t actually call the SetValue method on my output object.  That&#8217;s easy enough to remedy:</p>
<p>[csharp]<br />
    internal class DController<br />
    {<br />
        public DController(IDiscreteInput inputA, IDiscreteInput inputB,<br />
            IDiscreteInput inputC, IDiscreteOutput outputD)<br />
        {<br />
            if (outputD == null) throw new ArgumentOutOfRangeException(&quot;outputD&quot;);<br />
            outputD.SetValue(false);<br />
        }<br />
    }<br />
[/csharp]</p>
<p>That&#8217;s the simplest logic I can write to make the test pass.  I always set the value of the output to false when I start up.  Since I&#8217;m calling a method on a dependency, I also have to include a guard clause in there to check for null, or else my tools like ReSharper might start complaining at me.</p>
<p>Now that my tests pass, I need to add some more tests.  My second test validates when my output should turn on (only when all three inputs are on).  In order to write this test, I had to write a helper class called MockDiscreteInputPatternGenerator.  I won&#8217;t go into the details of that class, but I&#8217;ll just say it&#8217;s over 100 lines long, just so that I can write a reasonably fluent test:</p>
<p>[csharp]<br />
        [TestMethod]<br />
        public void Inputs_A_B_C_must_all_be_true_for_D_to_turn_on()<br />
        {<br />
            MockDiscreteInput inputA;<br />
            MockDiscreteInput inputB;<br />
            MockDiscreteInput inputC;<br />
            MockDiscreteOutput outputD;</p>
<p>            var tester = new MockDiscreteInputPatternGenerator()<br />
                .InitialCondition(out inputA, false)<br />
                .InitialCondition(out inputB, false)<br />
                .InitialCondition(out inputC, false)<br />
                .CreateSimulatedOutput(out outputD)<br />
                .AssertThat(outputD).ShouldBe(false)</p>
<p>                .Then(inputA).TurnsOn()<br />
                .AssertThat(outputD).ShouldBe(false)</p>
<p>                .Then(inputB).TurnsOn()<br />
                .AssertThat(outputD).ShouldBe(false)</p>
<p>                .Then(inputA).TurnsOff()<br />
                .AssertThat(outputD).ShouldBe(false)</p>
<p>                .Then(inputC).TurnsOn()<br />
                .AssertThat(outputD).ShouldBe(false)</p>
<p>                .Then(inputB).TurnsOff()<br />
                .AssertThat(outputD).ShouldBe(false)</p>
<p>                .Then(inputA).TurnsOn()<br />
                .AssertThat(outputD).ShouldBe(false)</p>
<p>                .Then(inputB).TurnsOn()<br />
                .AssertThat(outputD).ShouldBe(true); // finally turns on</p>
<p>            var test = new DController(inputA, inputB, inputC, outputD);</p>
<p>            tester.Execute();<br />
        }<br />
[/csharp]</p>
<p>What this does is cycle through all the combinations of inputs that <i>don&#8217;t</i> cause the output to turn on, and then I finally turn them all on, and verify that it did turn on in that last case.</p>
<p>I&#8217;ll spare you the other two tests.  One check that the output initializes to on when all the inputs are on initially, and the last test checks the conditions that turn the output off (only C turning off, with A and B having no effect).  In order to get all of these tests to pass, here&#8217;s my final version of the DController class:</p>
<p>[csharp]<br />
    internal class DController<br />
    {<br />
        private readonly IDiscreteInput inputA;<br />
        private readonly IDiscreteInput inputB;<br />
        private readonly IDiscreteInput inputC;<br />
        private readonly IDiscreteOutput outputD;</p>
<p>        private bool D; // holds last state of output D</p>
<p>        public DController(IDiscreteInput inputA, IDiscreteInput inputB,<br />
            IDiscreteInput inputC, IDiscreteOutput outputD)<br />
        {<br />
            if (inputA == null) throw new ArgumentOutOfRangeException(&quot;inputA&quot;);<br />
            if (inputB == null) throw new ArgumentOutOfRangeException(&quot;inputB&quot;);<br />
            if (inputC == null) throw new ArgumentOutOfRangeException(&quot;inputC&quot;);<br />
            if (outputD == null) throw new ArgumentOutOfRangeException(&quot;outputD&quot;);</p>
<p>            this.inputA = inputA;<br />
            this.inputB = inputB;<br />
            this.inputC = inputC;<br />
            this.outputD = outputD;</p>
<p>            inputA.InputChanged += new EventHandler((s, e) =&gt; setOutputDValue());<br />
            inputB.InputChanged += new EventHandler((s, e) =&gt; setOutputDValue());<br />
            inputC.InputChanged += new EventHandler((s, e) =&gt; setOutputDValue());</p>
<p>            setOutputDValue();<br />
        }</p>
<p>        private void setOutputDValue()<br />
        {<br />
            bool A = inputA.GetValue();<br />
            bool B = inputB.GetValue();<br />
            bool C = inputC.GetValue();</p>
<p>            bool newValue = ((A &amp;&amp; B) || D) &amp;&amp; C;<br />
            outputD.SetValue(newValue);<br />
            D = newValue;<br />
        }<br />
    }<br />
[/csharp]</p>
<p>So if you&#8217;re just counting the DController class itself, that&#8217;s approaching 40 lines of code, and the only really important line is this:</p>
<p>[csharp]<br />
    bool newValue = ((A &amp;&amp; B) || D) &amp;&amp; C;<br />
[/csharp]</p>
<p>It&#8217;s true that as you wrote more logic, you&#8217;d refactor more and more repetitive code out of the Controller classes, but ultimately most of the overhead never really goes away.  The best you&#8217;re going to do is develop some kind of domain specific language which might look like this:</p>
<p>[csharp]<br />
    var dController = new OutputControllerFor(outputD)<br />
        .WithInputs(inputA, inputB, inputC)<br />
        .DefinedAs((A, B, C, D) =&gt; ((A &amp;&amp; B) || D) &amp;&amp; C);<br />
[/csharp]</p>
<p>&#8230;or maybe&#8230;</p>
<p>[csharp]<br />
    var dController = new OutputControllerFor(outputD)<br />
        .WithInputs(inputA, inputB, inputC)<br />
        .TurnsOnWhen((A, B, C) =&gt; A &amp;&amp; B &amp;&amp; C)<br />
        .StaysOnWhile((A, B, C) =&gt; C);<br />
[/csharp]</p>
<p>&#8230;and how is that any better than the original ladder logic?  That&#8217;s not even getting into the fact that you wouldn&#8217;t be able to use breakpoints in C# when doing online troubleshooting.  This code would be a real pain to troubleshoot if the sensor connected to inputA was becoming flaky.  With ladder logic, you can just glance at it and see the current values of A, B, C, and D.</p>
<p>Testing: the C# code is complex enough that it <i>needs</i> tests to prove that it works right, but the ladder logic is so simple, so declarative, that it&#8217;s obvious to any Controls Engineer or Electrician exactly what it does: turn on when A, B, and C are all on, and then stay on until C turns off.  It doesn&#8217;t need a test!</p>
<p>Time-wise: it took me about a minute to get the ladder editor open and write that ladder logic, but about an hour to put together this C# example in Visual Studio.</p>
<p>So, I think when someone gets a hate on for ladder logic, it just has to be fear.  Ladder logic is a great tool to have in your toolbox.  Certainly <i>don&#8217;t</i> use ladder logic to write an ERP system, but <i>do</i> use it for discrete control.</p>
<div class="addthis_toolbox addthis_default_style addthis_32x32_style" addthis:url='http://www.contactandcoil.com/automation/industrial-automation/ladder-logic-vs-c/' addthis:title='Ladder Logic vs. C# ' ><a class="addthis_button_preferred_1"></a><a class="addthis_button_preferred_2"></a><a class="addthis_button_preferred_3"></a><a class="addthis_button_preferred_4"></a><a class="addthis_button_compact"></a></div>]]></content:encoded>
			<wfw:commentRss>http://www.contactandcoil.com/automation/industrial-automation/ladder-logic-vs-c/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>The Payback on Automated Unit Tests</title>
		<link>http://www.contactandcoil.com/software/the-payback-on-automated-unit-tests/</link>
		<comments>http://www.contactandcoil.com/software/the-payback-on-automated-unit-tests/#comments</comments>
		<pubDate>Tue, 10 May 2011 03:57:41 +0000</pubDate>
		<dc:creator>Scott Whitlock</dc:creator>
				<category><![CDATA[Software]]></category>
		<category><![CDATA[productivity]]></category>
		<category><![CDATA[tdd]]></category>

		<guid isPermaLink="false">http://www.contactandcoil.com/?p=807</guid>
		<description><![CDATA[<div class="addthis_toolbox addthis_default_style " addthis:url='http://www.contactandcoil.com/software/the-payback-on-automated-unit-tests/' addthis:title='The Payback on Automated Unit Tests '  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div>I&#8217;m a Test-Driven Development (TDD) convert now. All of the &#8220;business logic&#8221; (aka &#8220;domain logic&#8221;), and more than 95% of my framework logic is covered by automated unit tests because I write the test before I write the code, and I only write enough code to pass the failing test. It&#8217;s really hard to find [...]<div class="addthis_toolbox addthis_default_style addthis_32x32_style" addthis:url='http://www.contactandcoil.com/software/the-payback-on-automated-unit-tests/' addthis:title='The Payback on Automated Unit Tests ' ><a class="addthis_button_preferred_1"></a><a class="addthis_button_preferred_2"></a><a class="addthis_button_preferred_3"></a><a class="addthis_button_preferred_4"></a><a class="addthis_button_compact"></a></div>]]></description>
			<content:encoded><![CDATA[<div class="addthis_toolbox addthis_default_style " addthis:url='http://www.contactandcoil.com/software/the-payback-on-automated-unit-tests/' addthis:title='The Payback on Automated Unit Tests '  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div><p>I&#8217;m a <a href="http://en.wikipedia.org/wiki/Test-driven_development" onclick="pageTracker._trackPageview('/outgoing/en.wikipedia.org/wiki/Test-driven_development?referer=');">Test-Driven Development</a> (TDD) convert now.  All of the &#8220;business logic&#8221; (aka &#8220;domain logic&#8221;), and more than 95% of my framework logic is covered by automated unit tests because I write the test before I write the code, and I only write enough code to pass the failing test.</p>
<p>It&#8217;s really hard to find anyone talking about a measurable ROI for unit testing, but it does happen.  <a href="http://collaboration.csc.ncsu.edu/laurie/Papers/TDDpaperv8.pdf" onclick="pageTracker._trackPageview('/outgoing/collaboration.csc.ncsu.edu/laurie/Papers/TDDpaperv8.pdf?referer=');">This study</a> says it took, on average, 16% longer to develop the initial application using TDD than it did using normal development methods.  <a href="http://research.microsoft.com/en-us/groups/ese/nagappan_tdd.pdf" onclick="pageTracker._trackPageview('/outgoing/research.microsoft.com/en-us/groups/ese/nagappan_tdd.pdf?referer=');">This one</a> reported &#8220;management estimates&#8221; of 15% to 35% longer development times using test-driven development.  Both studies reported very significant reduction in defects.  The implication is that the payback comes somewhere in the maintenance phase.</p>
<p>From personal experience I would say that as I gain experience with TDD, I get much faster at it.  At the beginning it was probably doubling my development time, but now I&#8217;m closer to the estimates in the studies above.  I&#8217;ve also shifted a bit from &#8220;whitebox testing&#8221; (where you test every little inner function) to more &#8220;blackbox testing&#8221;/&#8221;integration testing&#8221; where you test at a much higher level.  I find that writing your tests at a higher level means you write fewer tests, and they&#8217;re more resilient to refactoring (when you change the design of your software later to accommodate new features).</p>
<h2>A Long Term Investment</h2>
<p>It&#8217;s hard to justify TDD because the extra investment of effort seems a lot more real and substantial than the rather flimsy value of quality.  We can measure hours easily, but quality, not so much.  That means we have a bias in our measurements.</p>
<p>Additionally, if and when TDD pays us back, it&#8217;s in the future.  It&#8217;s probably not in this fiscal year.  Just like procrastination, avoiding TDD pays off now.  As humans, we&#8217;re wired to value immediate value over long term value.  Sometimes that works against us.</p>
<h2>A Theory of TDD ROI</h2>
<p>I&#8217;m going to propose a model of how the ROI works in TDD.  This is scientific, in that you&#8217;ll be able to make falsifiable predictions based on this model.</p>
<p>Start out with your software and draw out the major modules that are relatively separate from each other.  Let&#8217;s say you&#8217;re starting with a simple CRUD application that just shows you data from a database and lets you Create, Read, Update, and Delete that data.  Your modules might look like this:</p>
<ul>
<li>Contact Management</li>
<li>Inventory Management</li>
</ul>
<p>If you go and implement this using TDD vs. <i>not</i> using TDD, I suspect you&#8217;ll see a typical 15% to 35% increase in effort using the TDD methodology.  That&#8217;s because the architecture is relatively flat and there&#8217;s minimal interaction.  Contact Management and Inventory Management don&#8217;t have much to do with each other.  Now let&#8217;s implement two more modules:</p>
<ul>
<li>Orders</li>
<li>Purchasing</li>
</ul>
<p>These two new modules are also relatively independent, but they both depend on the Contact Management and Inventory Management modules.  That just added 4 dependency relationships.  The software is getting more complex, and more difficult to understand the effect of small changes.  The latter modules can still be changed relatively safely because nothing much depends on them, but the first two can start to cause trouble.</p>
<p>Now let&#8217;s add a Permissions module.  Obviously this is a &#8220;cross cutting&#8221; concern &#8211; everything depends on the permissions module.  Since we had 4 existing modules, we&#8217;ve just added another 4 dependency relationships.</p>
<p>Ok, now we&#8217;ll add a Reporting module.  It depends on the 4 original modules, and it also needs Permissions information, so we&#8217;ve added another 5 dependency relationships.</p>
<p>Are you keeping count?  We&#8217;re at 13 relationships now with just 6 modules.</p>
<p>Now let&#8217;s say we have to add a function that will find all customers (Contact Module) who have a specific product on order (Orders) that came from some manufacturer (Purchasing and Contact Management) and a certain Lot # (Inventory) and print a report (Reporting Module).  Obviously this will only be available to certain people (Permissions).    </p>
<p>That means you have to touch all 6 modules to make this change.  Perhaps while you&#8217;re messing around in the Inventory Management module you notice that the database structure isn&#8217;t going to support this new feature. Maybe you have a many-to-one relationship where you realize we really should have used a many-to-many relationship.  You change the database schema, and you change the Inventory Module, but instead of just re-testing that module, you now have to fully re-test all the modules that depend on it: Orders, Purchasing, and Reports.  It&#8217;s likely we made assumptions about that relationship in those modules.  What if we need to change those?  Does the effect cascade to all the modules in the software?  Likely.</p>
<p>It doesn&#8217;t take long to get to the point where you need to do a 100% regression test of your entire application.  How many new features potentially touch all modules?  How long does it take to do a full regression test?  That&#8217;s your payback.  </p>
<p>You can measure the regression test time, and if you use a tool like <a href="http://www.ndepend.com/" onclick="pageTracker._trackPageview('/outgoing/www.ndepend.com/?referer=');">NDepend</a> you can measure and graph the dependencies of an existing application.  Using your source control history, you can go back and determine how many different modules were touched by each new feature and bug fix since the beginning of time.  You should be able to calculate:</p>
<ul>
<li>How much time it takes to regression test each module</li>
<li>Probability of each module changing during an &#8220;average&#8221; change</li>
<li>The set of modules to regression test for any given module changing</li>
</ul>
<p>Given that, you can figure out the average time to regression test the average change.</p>
<p>Obviously, the average regression test time must be longer than 15% to 35% of the time it took to write the feature (assuming you&#8217;ll keep following TDD practices during the maintenance phase).  The amount of time it takes to test <b>in excess</b> of that is payback against the initial 15% to 35% extra you spend developing the application in the first place.</p>
<h2>What kind of numbers are we talking about?</h2>
<p>Let&#8217;s run some numbers.  A lot of places say 30 to 50% of software development time is spent testing.  Let&#8217;s assume 50% is for the apps with &#8220;very interconnected dependencies&#8221;.  Also, let&#8217;s say our team spends an extra 33% premium to use a TDD methodology.</p>
<p>Now take a project that would originally take 6 months to develop and test, but with TDD the development took about 33% longer, so +2 months.  The average change takes 3 days to code and test, or 4 days with TDD.  Let&#8217;s say the regression test on something that took 6 months to develop (<i>personal experience &#8211; a 3 month project had a regression test plan that was about 1 day to run through</i>) would have to be about 2 days.</p>
<p>Without TDD, a feature would take 3 days to write and test, and then 2 days to do a full regression test.  Using TDD, it would take 4 days to write and test, but zero time to regression test, so you gain a day.</p>
<p>Therefore, since you had to invest an extra 2 months (40 days assuming one developer) in the first place to do TDD, you&#8217;d see a break-even once you were in the maintenance phase and had implemented about 40 changes, each taking 4 days, which means 160 days.  That&#8217;s about 8 months.  That ignores the fact that regression test time keeps increasing as you add more features.</p>
<p>Obviously your numbers will vary.  The biggest factor is the ratio of regression test time vs. the time it takes you to implement a new feature.  More dependencies means more regression testing.  </p>
<h2>Conclusion</h2>
<p>If you have a very flat architecture with few dependencies, then the TDD payback is longer (if there even is a payback).  On the other hand, if you have highly interdependent software (modules built on top of other modules), TDD pays you back quickly.</p>
<div class="addthis_toolbox addthis_default_style addthis_32x32_style" addthis:url='http://www.contactandcoil.com/software/the-payback-on-automated-unit-tests/' addthis:title='The Payback on Automated Unit Tests ' ><a class="addthis_button_preferred_1"></a><a class="addthis_button_preferred_2"></a><a class="addthis_button_preferred_3"></a><a class="addthis_button_preferred_4"></a><a class="addthis_button_compact"></a></div>]]></content:encoded>
			<wfw:commentRss>http://www.contactandcoil.com/software/the-payback-on-automated-unit-tests/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>A Very Fast Tutorial on Open Source Licenses</title>
		<link>http://www.contactandcoil.com/software/a-very-fast-tutorial-on-open-source-licenses/</link>
		<comments>http://www.contactandcoil.com/software/a-very-fast-tutorial-on-open-source-licenses/#comments</comments>
		<pubDate>Fri, 06 May 2011 03:07:44 +0000</pubDate>
		<dc:creator>Scott Whitlock</dc:creator>
				<category><![CDATA[Software]]></category>
		<category><![CDATA[copyright]]></category>
		<category><![CDATA[open-source]]></category>

		<guid isPermaLink="false">http://www.contactandcoil.com/?p=797</guid>
		<description><![CDATA[<div class="addthis_toolbox addthis_default_style " addthis:url='http://www.contactandcoil.com/software/a-very-fast-tutorial-on-open-source-licenses/' addthis:title='A Very Fast Tutorial on Open Source Licenses '  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div>I&#8217;ve written a bit of open source software lately, and I did a lot of learning about open source licenses. Unfortunately, after you learn a lot about a topic, you tend to subconsciously assume everyone knows what you do. In the interest of catching you all up, here&#8217;s a cheat sheet with some practical tips: [...]<div class="addthis_toolbox addthis_default_style addthis_32x32_style" addthis:url='http://www.contactandcoil.com/software/a-very-fast-tutorial-on-open-source-licenses/' addthis:title='A Very Fast Tutorial on Open Source Licenses ' ><a class="addthis_button_preferred_1"></a><a class="addthis_button_preferred_2"></a><a class="addthis_button_preferred_3"></a><a class="addthis_button_preferred_4"></a><a class="addthis_button_compact"></a></div>]]></description>
			<content:encoded><![CDATA[<div class="addthis_toolbox addthis_default_style " addthis:url='http://www.contactandcoil.com/software/a-very-fast-tutorial-on-open-source-licenses/' addthis:title='A Very Fast Tutorial on Open Source Licenses '  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div><p>I&#8217;ve written a bit of open source software lately, and I did a lot of learning about open source licenses.  Unfortunately, after you learn a lot about a topic, you tend to subconsciously assume everyone knows what you do.  In the interest of catching you all up, here&#8217;s a cheat sheet with some practical tips:</p>
<p><i>Note: I use the terms &#8220;proprietary&#8221; and &#8220;commercial&#8221; with specific meanings.  &#8220;Commercial&#8221; means an application that isn&#8217;t open-source and you sell copies of it for money.  &#8220;Proprietary&#8221; includes &#8220;commercial&#8221; but also includes software that is only used internally, never sold.</i></p>
<h2>BSD or MIT/X11 Licenses</h2>
<h3>Sometimes called the &#8220;Academic&#8221; Licenses</h3>
<p>Technically it&#8217;s the &#8220;revised&#8221; BSD license, but it&#8217;s been around so long that it&#8217;s just the BSD license now.  It&#8217;s pretty much equivalent to the MIT/X11 license.  These are considered to be the least restrictive, &#8220;do-anything-you-want&#8221; licenses as long as you keep the original notice on the code, display the copyright notice in your program, and don&#8217;t infer the author is endorsing your product.  Also, it has a disclaimer saying they&#8217;re not responsible for anything you do with it.  Standard stuff.</p>
<p>You can use this code in proprietary software, and you can use it in a GPL&#8217;d work (the common term for this is &#8220;GPL-compatible&#8221;.)</p>
<h2>Apache 2.0</h2>
<p>The Apache 2.0 license is similar in use to the BSD license, but it adds a patent grant.  That is, it specifically states that if the authors hold any patents that cover the code, you can still use this code and be safe from that.  Some might argue that BSD <i>implies</i> the patent grant, but it&#8217;s not specific, so Apache 2.0 makes it specific.</p>
<p>You can use it in proprietary software, and it is GPL-compatible, but only with version 3 of the GPL.</p>
<h2>Mozilla Public License 1.1 and the Common Development and Distribution License</h2>
<h3>a.k.a. MPL 1.1 and CDDL</h3>
<p>CDDL was based on the MPL 1.1.</p>
<p>These are your &#8220;weak copyleft&#8221; licenses, copyleft meaning some part of the derived work also has to be released under the same license.  What it means is that you can use this code in a proprietary application, but if you make any changes to the code you included, you have to release that code publicly (but not the code of your entire work).  The CDDL defines the boundary at the source file, so if you change one of the original files, you have to release that back.</p>
<p>These are <i>not</i> compatible with the GPL.</p>
<h2>MS-PL</h2>
<h3>Microsoft Public License</h3>
<p>You&#8217;ll see this license a lot if you do much .NET coding.  A lot of the stuff you find on MS&#8217;s open source site, CodePlex, is MS-PL licensed.  The short of it is that you can use it in proprietary applications, but it&#8217;s not GPL-compatible (by design &#8211; MS hates Linux).  It&#8217;s also <i>not</i> copyleft at all.</p>
<h2>GPL</h2>
<h3>Your strong copyleft</h3>
<p>The GPL is the one everyone loves to hate, but it&#8217;s also popular because the Linux kernel is released under the GPLv2 license, and many/most of the tools of the Linux community are GPL-based.</p>
<p>Unlike the previous licenses, if you take <i>any</i> code from a GPL&#8217;d program and include it in your own project, you&#8217;re making a &#8220;derived work&#8221; and you must agree to release your entire derived work under the same license (or a later version if the author specifically says you can).  That means you can&#8217;t use GPL&#8217;d code in your commercial application (but you can use it in internal applications).</p>
<p>The reason some programmers are so annoyed by it is that they&#8217;re at work Googling for some code to solve their problem, realize someone has written an open source library to do exactly what they want and they get all excited.  Then they check the license and their heart drops because it&#8217;s GPL and they realize they can&#8217;t use it.  A small minority go as far as to send <i>hate mail</i> to the author.  (As someone who has released some GPL&#8217;d code, I&#8217;ve received my share of this hate mail, and I find it very silly.  I&#8217;m offering something for free, under certain conditions, and you are free to take it or leave it.)  What most programmers don&#8217;t seem to understand is that if you email the author, they&#8217;d probably be willing to sell you a commercial license for the code so you could use it in your program.</p>
<h2>LGPL</h2>
<h3>The weak copyleft version</h3>
<p>The &#8220;L&#8221; originally stood for library, but now it stands for &#8220;lesser&#8221;.  It kind of works like the CDDL, but it defines the boundary at the &#8220;library&#8221; rather than the source file.  It basically says you can use this library, even in a commercial application, but if you make any changes to it, you must release your new version of the library under the same (or newer&#8230;) license.</p>
<p>It also adds a restriction that some people overlook &#8211; you must also provide the users of your application the ability to replace the LGPL&#8217;d library with a newer or modified version of that library.  Usually this means providing the binaries and compilation instructions.  Consider the difficulty of meeting this obligation if your derived work is firmware on an embedded device.  Version 3 of the GPL and LGPL make it very clear that you must allow your users all the tools needed to replace the software <i>on the device</i>.  This was a reaction to the TiVo, which used GPL&#8217;d code, and released the code publicly, but didn&#8217;t allow anyone to further modify the code and update their TiVo&#8217;s with it.</p>
<p>The other thing you have to worry about is copying code.  If you copy any code from the library into your main project, then your project becomes a derived work, and you&#8217;re essentially forced to release your whole application under the LGPL.  Programmers don&#8217;t worry about this too much, but legal departments do.</p>
<h2>AGPL</h2>
<h3>Affero?</h3>
<p>It turns out you can take GPL&#8217;d code, run it on a server as a web application, make all the changes you want, and never release your code because you&#8217;re not &#8220;distributing&#8221; the derived work, and distribution is what triggers the GPL.  (Google has it&#8217;s own version of Linux that it never had to release because it only uses it internally).</p>
<p>This ticked off some people who were writing GPL&#8217;d blogging and other website type software, so someone came up with the AGPL.  This changes the triggering clause, so if you are using the AGPL&#8217;d code in a website, you have to make any changes public.</p>
<h2>Conclusion</h2>
<p>Those are the major licenses you&#8217;ll run into.  If you&#8217;re writing commercial software, you want to look for BSD, MIT/X11, Apache 2.0, MS-PL, MPL 1.1 or CDDL code.  You can also use LGPL&#8217;d code, but watch out for the extra restrictions.</p>
<p>If the proprietary software you&#8217;re writing is only for internal use, or you&#8217;re writing it &#8220;for hire&#8221; for another company that will only use it internally, then you&#8217;re safe to use GPL&#8217;d or LGPL&#8217;d code because you won&#8217;t trigger the distribution clause.  Just be sure that you make this clear to your management/customer before you go down this path.  If they decide they want to sell the software later, they&#8217;ll have a mess to clean up.</p>
<p>If you&#8217;re writing open source code then you need to pick a license.  A BSD license is the easiest, and it&#8217;s great for little utility libraries because anyone can use it.  If you&#8217;re writing an application and you want to protect against some company taking the application, adding a bunch of new features that make it incompatible, and then releasing and charging for it without ever giving you anything, then you should choose the GPL (or AGPL if it&#8217;s a web application).</p>
<div class="addthis_toolbox addthis_default_style addthis_32x32_style" addthis:url='http://www.contactandcoil.com/software/a-very-fast-tutorial-on-open-source-licenses/' addthis:title='A Very Fast Tutorial on Open Source Licenses ' ><a class="addthis_button_preferred_1"></a><a class="addthis_button_preferred_2"></a><a class="addthis_button_preferred_3"></a><a class="addthis_button_preferred_4"></a><a class="addthis_button_compact"></a></div>]]></content:encoded>
			<wfw:commentRss>http://www.contactandcoil.com/software/a-very-fast-tutorial-on-open-source-licenses/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Insteon and X10 Home Automation from .NET</title>
		<link>http://www.contactandcoil.com/automation/home-automation/insteon-and-x10-home-automation-from-net/</link>
		<comments>http://www.contactandcoil.com/automation/home-automation/insteon-and-x10-home-automation-from-net/#comments</comments>
		<pubDate>Sun, 17 Apr 2011 22:41:43 +0000</pubDate>
		<dc:creator>Scott Whitlock</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[Home Automation]]></category>
		<category><![CDATA[.net]]></category>
		<category><![CDATA[fluentdwelling]]></category>
		<category><![CDATA[insteon]]></category>
		<category><![CDATA[x10]]></category>

		<guid isPermaLink="false">http://www.contactandcoil.com/?p=761</guid>
		<description><![CDATA[<div class="addthis_toolbox addthis_default_style " addthis:url='http://www.contactandcoil.com/automation/home-automation/insteon-and-x10-home-automation-from-net/' addthis:title='Insteon and X10 Home Automation from .NET '  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div>I&#8217;ve been playing with my new Smarthome 2413U PowerLinc Modem plus some Smarthome 2456S3 ApplianceLinc modules and two old X10 modules I had sitting around. Insteon is a vast improvement over the X10 technology for home automation. X10 always had problems with messages getting &#8220;lost&#8221;, and it was really slow, sometimes taking up to a [...]<div class="addthis_toolbox addthis_default_style addthis_32x32_style" addthis:url='http://www.contactandcoil.com/automation/home-automation/insteon-and-x10-home-automation-from-net/' addthis:title='Insteon and X10 Home Automation from .NET ' ><a class="addthis_button_preferred_1"></a><a class="addthis_button_preferred_2"></a><a class="addthis_button_preferred_3"></a><a class="addthis_button_preferred_4"></a><a class="addthis_button_compact"></a></div>]]></description>
			<content:encoded><![CDATA[<div class="addthis_toolbox addthis_default_style " addthis:url='http://www.contactandcoil.com/automation/home-automation/insteon-and-x10-home-automation-from-net/' addthis:title='Insteon and X10 Home Automation from .NET '  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div><p>I&#8217;ve been playing with my new <a href="http://www.amazon.com/gp/product/B002XA8XNQ/ref=as_li_ss_tl?ie=UTF8&#038;tag=soapauto-20&#038;linkCode=as2&#038;camp=1789&#038;creative=390957&#038;creativeASIN=B002XA8XNQ" onclick="pageTracker._trackPageview('/outgoing/www.amazon.com/gp/product/B002XA8XNQ/ref=as_li_ss_tl?ie=UTF8_038_tag=soapauto-20_038_linkCode=as2_038_camp=1789_038_creative=390957_038_creativeASIN=B002XA8XNQ&amp;referer=');">Smarthome 2413U PowerLinc Modem</a><img src="http://www.assoc-amazon.com/e/ir?t=&#038;l=as2&#038;o=1&#038;a=B002XA8XNQ" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" /> plus some <a href="http://www.amazon.com/gp/product/B0015ROPTO/ref=as_li_ss_tl?ie=UTF8&#038;tag=soapauto-20&#038;linkCode=as2&#038;camp=1789&#038;creative=390957&#038;creativeASIN=B0015ROPTO" onclick="pageTracker._trackPageview('/outgoing/www.amazon.com/gp/product/B0015ROPTO/ref=as_li_ss_tl?ie=UTF8_038_tag=soapauto-20_038_linkCode=as2_038_camp=1789_038_creative=390957_038_creativeASIN=B0015ROPTO&amp;referer=');">Smarthome 2456S3 ApplianceLinc</a><img src="http://www.assoc-amazon.com/e/ir?t=&#038;l=as2&#038;o=1&#038;a=B0015ROPTO" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" /> modules and two old X10 modules I had sitting around.</p>
<p>Insteon is a vast improvement over the X10 technology for home automation.  X10 always had problems with messages getting &#8220;lost&#8221;, and it was really slow, sometimes taking up to a second for the light to actually turn on.  Insteon really seems to live up to its name; the signals seem to get there immediately (to a human, anyway).  Insteon also offers &#8220;dual-band&#8221; technology, meaning the signals are sent both over the electrical wiring of the house, and over a wireless network.  On top of this, Insteon implements &#8220;mesh networking&#8221;, acknowledgements, and retries.  The mesh networking means that even if two devices can&#8217;t directly communicate, if an intermediate device can see both, it will relay the signal.</p>
<p>Now, where Insteon seems to have improved leaps and bounds on the hardware, the software support is abysmal.  That&#8217;s not because there&#8217;s anything wrong with the API, but because they&#8217;ve put the Software Development Kit (SDK) behind a hefty license fee, not to mention a rather <a href="http://www.insteon.net/sdk/forum/DeveloperLicenseAgreement.html" onclick="pageTracker._trackPageview('/outgoing/www.insteon.net/sdk/forum/DeveloperLicenseAgreement.html?referer=');">evil license agreement</a>.  Basically it would preclude you from using any of their examples or source code in an open source project.  Plus, they only offer support if you&#8217;ve purchased their SDK.</p>
<p>So, I&#8217;ve decided to offer free technical support to anyone using a 2413U for non-commercial purposes.  If you want help with this thing, by all means, email me, post comments at the end of this post, whatever.  I&#8217;ll be glad to help you.</p>
<p>Let&#8217;s start by linking to all the useful information about Insteon that they haven&#8217;t completely wiped off the internet (yet):</p>
<ul>
<li><a href="http://www.smarthome.com/manuals/2412sdevguide.pdf" onclick="pageTracker._trackPageview('/outgoing/www.smarthome.com/manuals/2412sdevguide.pdf?referer=');">Insteon Modem Developer&#8217;s Guide</a> &#8211; this is for the 2412S, which is the chip at the heart of the 2413U, so it&#8217;s the bible for this device</li>
<li><a href="http://www.insteon.net/pdf/INSTEON_Command_Tables_20070925a.pdf" onclick="pageTracker._trackPageview('/outgoing/www.insteon.net/pdf/INSTEON_Command_Tables_20070925a.pdf?referer=');">Insteon Command Tables</a> &#8211; vital info about the actual inter-device commands that get passed back and forth</li>
<li><a href="http://rs.cs.iastate.edu/smarthome/documents/Manuals%20and%20Tutorials/Insteon/INSTEON_Developers_Guide_20051014a.pdf" onclick="pageTracker._trackPageview('/outgoing/rs.cs.iastate.edu/smarthome/documents/Manuals_20and_20Tutorials/Insteon/INSTEON_Developers_Guide_20051014a.pdf?referer=');">Insteon Developers&#8217; Guide</a> &#8211; note it&#8217;s hosted at a university, not the manufacturer</li>
<li><a href="http://www.insteon.net/pdf/INSTEON_DevCats_and_Product_Keys_20081008.pdf" onclick="pageTracker._trackPageview('/outgoing/www.insteon.net/pdf/INSTEON_DevCats_and_Product_Keys_20081008.pdf?referer=');">Insteon Device Categories and Product Keys</a> &#8211; a couple years out of date, but full of great information</li>
<li><a href="http://www.madreporite.com/insteon/Insteon_device_list.htm" onclick="pageTracker._trackPageview('/outgoing/www.madreporite.com/insteon/Insteon_device_list.htm?referer=');">Another great Insteon Device List</a></li>
</ul>
<p>Now how did I find all this information?  Google.  SmartHome (the Insteon people) don&#8217;t seem to provide links to any of this information from their home or (non-walled) support pages, but they either let Google crawl them, or other companies or organizations have posted them on their sites (I first found the modem developer&#8217;s guide on Aartech&#8217;s site, for instance).  Once you get one document, they tend to make references to the titles of other documents, so you could start to Google for the other ones by title.  Basically, it was a pain, but that&#8217;s how it was done.</p>
<p>Now, whether you buy the 2413S (serial) or 2413U (USB), they&#8217;re both using the 2412S internally, which is an RS232 device.  The 2413U just includes an FTDI USB-to-Serial converter, and you can get the drivers for this for free (you want the VCP driver).  It just ends up making the 2413U look like another COM port on your PC (in my case, COM4).</p>
<p>So, assuming you know how to open a serial port from .NET, and you got done reading all that documentation, you&#8217;d realize that if you wanted to turn on a light (say you had a switched lamp module at Insteon address &#8220;AA.BB.CC&#8221;), you&#8217;d want to send it this sequence of bytes (where 0x means hex):</p>
<ul>
<li>0&#215;02 &#8211; start of message to PLM</li>
<li>0&#215;62 &#8211; send Insteon message over the network</li>
<li>0xAA &#8211; high byte of Insteon ID</li>
<li>0xBB &#8211; middle byte</li>
<li>0xCC &#8211; low byte of Insteon ID</li>
<li>0x0F &#8211; Flags (meaning: direct message, max hops)</li>
<li>0&#215;12 &#8211; Command byte 1 &#8211; means &#8220;turn on lighting device&#8221;</li>
<li>0xFF &#8211; Command byte 2 &#8211; intensity level &#8211; full on</li>
</ul>
<p>&#8230; after which the 2413U should respond with:</p>
<p>0&#215;02, 0&#215;62, 0xAA, 0xBB, 0xCC, 0x0F, 0&#215;12, 0xFF, 0&#215;06</p>
<p>&#8230; which is essentially just echoing back what it received, and adding a 0&#215;06, which means &#8220;acknowledge&#8221;.</p>
<p>At that point, the 2413U has started transmitting the message over the Insteon network, so now you have to wait for the device itself to reply (if it does&#8230; someone might have unplugged it, after all).  If you do get a response, it will look like this:</p>
<ul>
<li>0&#215;02 &#8211; start of message from 2413U</li>
<li>0&#215;50 &#8211; means received Insteon message</li>
<li>0xAA &#8211; high byte of peer Insteon ID</li>
<li>0xBB &#8211; middle byte</li>
<li>0xCC &#8211; low byte of peer Insteon ID</li>
<li>0x?? &#8211; high byte of your 2413U Insteon ID</li>
<li>0x?? &#8211; middle byte of your 2413U Insteon ID</li>
<li>0x?? &#8211; low byte of your 2413U Insteon ID</li>
<li>0&#215;20 &#8211; Flags &#8211; means Direct Message Acknowledgement</li>
<li>0&#215;12 &#8211; Command 1 echo&#8217;d back</li>
<li>0xFF &#8211; Command 2 echo&#8217;d back</li>
</ul>
<p>If you get all that back, you have one successful transaction.  Your light show now be on!  Whew, that&#8217;s a lot of overhead though, and that&#8217;s just the code to turn on a light!  There are dozens of other commands you can send and receive.  I didn&#8217;t want to be bit-twiddling for hours on end, so I created a little helper library called <a href="http://soapboxautomation.com/products/fluentdwelling/" onclick="pageTracker._trackPageview('/outgoing/soapboxautomation.com/products/fluentdwelling/?referer=');">FluentDwelling</a> so now you can write code like this:</p>
<p>[csharp]<br />
var plm = new Plm(&quot;COM4&quot;); // manages the 2413U<br />
DeviceBase device;<br />
if(plm.TryConnectToDevice(&quot;AA.BB.CC&quot;, out device))<br />
{<br />
    // The library will return an instance of a<br />
    // SwitchedLightingControl because it connects<br />
    // to it and asks it what it is<br />
    var light = device as SwitchedLightingControl;<br />
    light.TurnOn();<br />
}<br />
[/csharp]</p>
<p>I think that&#8217;s a little simpler.  <a href="http://soapboxautomation.com/products/fluentdwelling/" onclick="pageTracker._trackPageview('/outgoing/soapboxautomation.com/products/fluentdwelling/?referer=');">FluentDwelling</a> is free to download, open-sourced under the GPLv3, and includes a full unit test suite.</p>
<p>It also supports the older X10 protocol, in case you have some of those lying around:</p>
<p>[csharp]<br />
plm.Network.X10<br />
    .House(&quot;A&quot;)<br />
    .Unit(2)<br />
    .Command(X10Command.On);<br />
[/csharp]</p>
<p>There are quite a few Insteon-compatible devices out there.  In addition to lighting controls, there is a <a href="http://www.amazon.com/gp/product/B001BMOGEM/ref=as_li_ss_tl?ie=UTF8&#038;tag=soapauto-20&#038;linkCode=as2&#038;camp=1789&#038;creative=390957&#038;creativeASIN=B001BMOGEM" onclick="pageTracker._trackPageview('/outgoing/www.amazon.com/gp/product/B001BMOGEM/ref=as_li_ss_tl?ie=UTF8_038_tag=soapauto-20_038_linkCode=as2_038_camp=1789_038_creative=390957_038_creativeASIN=B001BMOGEM&amp;referer=');">Sprinkler Controller</a><img src="http://www.assoc-amazon.com/e/ir?t=&#038;l=as2&#038;o=1&#038;a=B001BMOGEM" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" />, <a href="http://www.amazon.com/gp/product/B000OJ0VK6/ref=as_li_ss_tl?ie=UTF8&#038;tag=soapauto-20&#038;linkCode=as2&#038;camp=1789&#038;creative=390957&#038;creativeASIN=B000OJ0VK6" onclick="pageTracker._trackPageview('/outgoing/www.amazon.com/gp/product/B000OJ0VK6/ref=as_li_ss_tl?ie=UTF8_038_tag=soapauto-20_038_linkCode=as2_038_camp=1789_038_creative=390957_038_creativeASIN=B000OJ0VK6&amp;referer=');">Discrete I/O Modules</a><img src="http://www.assoc-amazon.com/e/ir?t=&#038;l=as2&#038;o=1&#038;a=B000OJ0VK6" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" />, a <a href="http://www.amazon.com/gp/product/B002CJ0MZK/ref=as_li_ss_tl?ie=UTF8&#038;tag=soapauto-20&#038;linkCode=as2&#038;camp=1789&#038;creative=390957&#038;creativeASIN=B002CJ0MZK" onclick="pageTracker._trackPageview('/outgoing/www.amazon.com/gp/product/B002CJ0MZK/ref=as_li_ss_tl?ie=UTF8_038_tag=soapauto-20_038_linkCode=as2_038_camp=1789_038_creative=390957_038_creativeASIN=B002CJ0MZK&amp;referer=');">Rain Sensor</a><img src="http://www.assoc-amazon.com/e/ir?t=&#038;l=as2&#038;o=1&#038;a=B002CJ0MZK" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" />, and even a <a href="http://www.amazon.com/gp/product/B003CT3T04/ref=as_li_ss_tl?ie=UTF8&#038;tag=soapauto-20&#038;linkCode=as2&#038;camp=1789&#038;creative=390957&#038;creativeASIN=B003CT3T04" onclick="pageTracker._trackPageview('/outgoing/www.amazon.com/gp/product/B003CT3T04/ref=as_li_ss_tl?ie=UTF8_038_tag=soapauto-20_038_linkCode=as2_038_camp=1789_038_creative=390957_038_creativeASIN=B003CT3T04&amp;referer=');">Pool and Spa Controller</a><img src="http://www.assoc-amazon.com/e/ir?t=&#038;l=as2&#038;o=1&#038;a=B003CT3T04" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" />.  That&#8217;s just getting started!</p>
<div class="addthis_toolbox addthis_default_style addthis_32x32_style" addthis:url='http://www.contactandcoil.com/automation/home-automation/insteon-and-x10-home-automation-from-net/' addthis:title='Insteon and X10 Home Automation from .NET ' ><a class="addthis_button_preferred_1"></a><a class="addthis_button_preferred_2"></a><a class="addthis_button_preferred_3"></a><a class="addthis_button_preferred_4"></a><a class="addthis_button_compact"></a></div>]]></content:encoded>
			<wfw:commentRss>http://www.contactandcoil.com/automation/home-automation/insteon-and-x10-home-automation-from-net/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Upgrading a Legacy VB6 Program to .NET</title>
		<link>http://www.contactandcoil.com/software/dotnet/upgrading-a-legacy-vb6-program-to-net/</link>
		<comments>http://www.contactandcoil.com/software/dotnet/upgrading-a-legacy-vb6-program-to-net/#comments</comments>
		<pubDate>Thu, 07 Apr 2011 03:12:59 +0000</pubDate>
		<dc:creator>Scott Whitlock</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[.net]]></category>
		<category><![CDATA[agile]]></category>
		<category><![CDATA[project-management]]></category>
		<category><![CDATA[risk]]></category>
		<category><![CDATA[vb6]]></category>

		<guid isPermaLink="false">http://www.contactandcoil.com/?p=748</guid>
		<description><![CDATA[<div class="addthis_toolbox addthis_default_style " addthis:url='http://www.contactandcoil.com/software/dotnet/upgrading-a-legacy-vb6-program-to-net/' addthis:title='Upgrading a Legacy VB6 Program to .NET '  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div>There is a lot of code out there written in VB6, running just fine. If you&#8217;re someone who has to maintain it, then at some point you&#8217;ll ask yourself, &#8220;should we just bite the bullet and upgrade this to .NET?&#8221; There is, so far, no end-of-life issue on the horizon. VB6 applications will run on [...]<div class="addthis_toolbox addthis_default_style addthis_32x32_style" addthis:url='http://www.contactandcoil.com/software/dotnet/upgrading-a-legacy-vb6-program-to-net/' addthis:title='Upgrading a Legacy VB6 Program to .NET ' ><a class="addthis_button_preferred_1"></a><a class="addthis_button_preferred_2"></a><a class="addthis_button_preferred_3"></a><a class="addthis_button_preferred_4"></a><a class="addthis_button_compact"></a></div>]]></description>
			<content:encoded><![CDATA[<div class="addthis_toolbox addthis_default_style " addthis:url='http://www.contactandcoil.com/software/dotnet/upgrading-a-legacy-vb6-program-to-net/' addthis:title='Upgrading a Legacy VB6 Program to .NET '  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div><p>There is a lot of code out there written in VB6, running just fine.  If you&#8217;re someone who has to maintain it, then at some point you&#8217;ll ask yourself, &#8220;should we just bite the bullet and upgrade this to .NET?&#8221;</p>
<p>There is, so far, no end-of-life issue on the horizon.  VB6 applications will run on Windows 7, and Microsoft has vowed to support the VB6 runtime through the life of Windows 7.  That will be a while, so there&#8217;s no hurry.</p>
<p>First, you need to do a cost-benefit to determine if it&#8217;s worth upgrading.  That&#8217;s a pretty big task right there.  What do you gain by moving to .NET?  Certainly you gain a much richer ecosystem of utilities, libraries, persistence layers, test frameworks, etc.  You&#8217;ll also find it easier to hire developers who have .NET on their resume.  It&#8217;s pretty hard to find a copy of Visual Studio 6 these days, unless you have an MSDN subscription.  .NET features like lambda expressions, LINQ, and reflection are also big productivity boosters if you spend the time to become proficient with them.  These are all valid points, but they&#8217;re hard to measure.  </p>
<p>You&#8217;re going to need to do some ballpark estimates.  I&#8217;ve actually been doing some conversions lately, so I have some real experience to throw at it.  Take any VB6 application, and it&#8217;ll take you 1/3 to 1/2 of the original development time to rewrite it in .NET with the same feature set (using test-driven development).  That&#8217;s my estimate&#8230; do what you will with it.  So, how much maintenance work are you doing, and how much more efficient would you be after the conversion?</p>
<p>So let&#8217;s take an application that took one programmer 6 months to write, and then you&#8217;ve been maintaining it in 50% of your time for the last year.  So there are 12 months of development in the existing application.  By my estimate you&#8217;ll need to spend 4 to 6 months rewriting.  Let&#8217;s say you&#8217;re twice as fast after the conversion (if you didn&#8217;t have unit tests before and you use test-driven development during the conversion, the unit tests alone should make you this much more productive, not to mention the improvements in the IDE and the full object-oriented support).  In that case, the payback period is 8 to 12 months of actual planned development.  If you have that much work ahead of you, and you can afford to put off working on new features entirely for half that time, you&#8217;ll break even.  </p>
<p>That&#8217;s still a really big investment.  The problem is that you won&#8217;t have anything to show for it for half that time.  It&#8217;s surprising how quickly management could lose faith in your endeavor if they a) don&#8217;t really understand what you&#8217;re doing and b) don&#8217;t see any tangible results for months.</p>
<p>There are alternatives to the all-or-nothing rewrite.  First, you can use a conversion tool to convert the VB6 to VB.NET.  The one that comes with Visual Studio 2005 is notoriously bad, but some of the <a href="http://www.artinsoft.com/pr_vbcompanion.aspx" onclick="pageTracker._trackPageview('/outgoing/www.artinsoft.com/pr_vbcompanion.aspx?referer=');">commercially developed ones</a> are apparently much better.  Still, given VB6&#8242;s laughably bad support for the object-oriented programming paradigm, the code you get out of the conversion is going to smell more like VB6 than .NET.  It will get you done faster, probably more than twice as fast, so it&#8217;s still an option.  However you won&#8217;t get a chance to re-architect the software or normalize the database, etc., in the process. </p>
<p>The other alternative to the &#8220;big rewrite&#8221; is to do the upgrade in an &#8220;agile&#8221; manner.  Take some time to break the software into smaller modules, each of which can be upgraded in about one month or less.  This will significantly lengthen the amount of time it takes you to finish the project, but you&#8217;ll have something tangible to show after each month.  Most managers can wait this long.  This approach has its problems too: you need to write a lot of code to interact between the VB6 and .NET code.  It can be tricky.</p>
<p><b>Normalizing a Database</b></p>
<p>If you&#8217;re in a position where you have a database as a backing store, and you need to make major database structure changes, this must affect your decision.  The &#8220;big rewrite&#8221; is the most friendly to database changes: you just write a single conversion script that upgrades the existing database in-place, and you write your new version against the new schema.  You have a clean slate, so you can clean up all the crufty problems in the old schema.</p>
<p>On the other hand, if you&#8217;re just using a conversion tool to automatically convert from VB6 to .NET, you can&#8217;t change the schema.</p>
<p>If you take the middle road (&#8220;agile&#8221;), you can change the database structure at the same time, but it&#8217;s much more difficult than in the &#8220;big rewrite&#8221;.  As you upgrade each module, it makes sense to modify the database structure underlying that module, but unless you&#8217;re really lucky, you&#8217;ll have parts of other modules left in VB6-land that are dependent upon database tables that are changing.  That means you&#8217;ll have the same problem anyone without a really good data access layer (or object-relational persistence layer) has when they go to change the database schema:</p>
<p>You have a whole bunch of code that looks like this: <code>sql = "SELECT MY_COL1, MY_COL2 FROM MY_TABLE JOIN..."</code></p>
<p>Assuming you don&#8217;t have unit test coverage, how do you find all the places in your code that need to be changed when you normalize <code>MY_COL2</code> out of one table into another?  Of course you can start with a search and replace, but if you really have a database normalization problem, then you probably have duplicate column names all over the place.  How many tables have a column called <code>CODE</code> or <code>STATUS</code>?  There are many pathological cases where a simple text search is going to find too many matches and you&#8217;ll spend hours tracking down all the places where the code might change just because of one column being moved or renamed.</p>
<p>The most pathological case is where you have, for instance, two columns like <code>CONTACT1</code> and <code>CONTACT2</code> in the same table, and somewhere in the code it says <code>sql = "UPDATE MY_TABLE SET CONTACT" &#038; ContactNumber &#038; " = '" &#038; SomeValue &#038; "'"</code>.  You&#8217;re doing to have a hard time finding that column name, no matter what you do.</p>
<p>You need to develop a smarter system.  I&#8217;ve tried a couple of different approaches.  I tried one system where I auto-generated unique constants for all of my table and column names in my database, and then I wrote a script that went through my source code and literally replaced all of the instances of table or column names <em>inside of strings</em> with the constants.  When I changed the database, I regenerated the list of constants, and the compiler was able to catch all the dependencies.  Unfortunately, this method has some deficiencies: the resulting SQL statements are more difficult to read, and when you go and make changes to these statements you have to be disciplined enough to use the generated constants for the table and column names, or you break the system.  Overall, it saves a lot of time if you have a lot of database changes to make, but costs extra time if you have to write new code.</p>
<p>I tried a different variation of the system where instead of replacing the table and column names in the string directly, I added auxiliary statements nearby that used the constants for the table and column names, and these would generate compile errors if a dependency changed.  This made the code easier to read, but had problems of its own.</p>
<p>I don&#8217;t have a perfect answer for this problem, but if you have any SQL strings embedded in your legacy VB6 application, and you want to do big changes to your database, I can tell you that you <em>must</em> build a tool for yourself.</p>
<p><b>Summary</b></p>
<p>If you really must convert your application from VB6 to .NET then make sure you go into it with your eyes wide open.  Engage management in a frank discussion.  Make sure you get a strong commitment.  If they waffle at all, walk away.  The last thing anyone wants is a half-converted piece of software.</p>
<p>Still, I&#8217;m here to tell you that it is possible, and if you do your homework, there can be a real payback.  Good luck!</p>
<div class="addthis_toolbox addthis_default_style addthis_32x32_style" addthis:url='http://www.contactandcoil.com/software/dotnet/upgrading-a-legacy-vb6-program-to-net/' addthis:title='Upgrading a Legacy VB6 Program to .NET ' ><a class="addthis_button_preferred_1"></a><a class="addthis_button_preferred_2"></a><a class="addthis_button_preferred_3"></a><a class="addthis_button_preferred_4"></a><a class="addthis_button_compact"></a></div>]]></content:encoded>
			<wfw:commentRss>http://www.contactandcoil.com/software/dotnet/upgrading-a-legacy-vb6-program-to-net/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Intro to Mercurial (Hg) Version Control for the Automation Professional</title>
		<link>http://www.contactandcoil.com/automation/industrial-automation/intro-to-mercurial-hg-version-control-for-the-automation-professional/</link>
		<comments>http://www.contactandcoil.com/automation/industrial-automation/intro-to-mercurial-hg-version-control-for-the-automation-professional/#comments</comments>
		<pubDate>Tue, 14 Dec 2010 02:00:55 +0000</pubDate>
		<dc:creator>Scott Whitlock</dc:creator>
				<category><![CDATA[Industrial Automation]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[hg]]></category>
		<category><![CDATA[version-control]]></category>

		<guid isPermaLink="false">http://www.contactandcoil.com/?p=663</guid>
		<description><![CDATA[<div class="addthis_toolbox addthis_default_style " addthis:url='http://www.contactandcoil.com/automation/industrial-automation/intro-to-mercurial-hg-version-control-for-the-automation-professional/' addthis:title='Intro to Mercurial (Hg) Version Control for the Automation Professional '  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div>There&#8217;s a tool in the PC programming world that nobody would live without, but almost nobody in the PLC or Automation World uses: version control systems. Even most PC programmers shun version control at first, until someone demonstrates it for them, and then they&#8217;re hooked. Version control is great for team collaboration, but most individual [...]<div class="addthis_toolbox addthis_default_style addthis_32x32_style" addthis:url='http://www.contactandcoil.com/automation/industrial-automation/intro-to-mercurial-hg-version-control-for-the-automation-professional/' addthis:title='Intro to Mercurial (Hg) Version Control for the Automation Professional ' ><a class="addthis_button_preferred_1"></a><a class="addthis_button_preferred_2"></a><a class="addthis_button_preferred_3"></a><a class="addthis_button_preferred_4"></a><a class="addthis_button_compact"></a></div>]]></description>
			<content:encoded><![CDATA[<div class="addthis_toolbox addthis_default_style " addthis:url='http://www.contactandcoil.com/automation/industrial-automation/intro-to-mercurial-hg-version-control-for-the-automation-professional/' addthis:title='Intro to Mercurial (Hg) Version Control for the Automation Professional '  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div><p>There&#8217;s a tool in the PC programming world that nobody would live without, but almost nobody in the PLC or Automation World uses: version control systems.  Even most PC programmers shun version control at first, until someone demonstrates it for them, and then they&#8217;re hooked.  Version control is great for team collaboration, but most individual programmers working on a project use it just for themselves.  It&#8217;s that good.  I decided since most of you are in the automation industry, I&#8217;d give you a brief introduction to my favourite version control system: <a href="http://mercurial.selenic.com/" onclick="pageTracker._trackPageview('/outgoing/mercurial.selenic.com/?referer=');">Mercurial</a>.</p>
<p>It&#8217;s called &#8220;Mercurial&#8221; and always pronounced that way, but it&#8217;s frequently referred to by the acronym &#8220;Hg&#8221;, referring to the element &#8220;Mercury&#8221; in the periodic table.</p>
<p>Mercurial has a lot of advantages:</p>
<ul>
<li><b>It&#8217;s free.</b>  So are all of the best version control systems actually.  Did I mention it&#8217;s the favourite tool of PC programmers?  Did I mention PC programmers don&#8217;t like to pay for stuff?  They write their own tools and release them online as open source.</li>
<li><b>It&#8217;s distributed.</b>  There are currently two &#8220;distributed version control systems&#8221;, or DVCS, vying for supremacy: Hg and Git.  Distributed means you don&#8217;t need a connection to the server all the time, so you can work offline.  This is great if you work from a laptop with limited connectivity, which is why I think it&#8217;s perfect for automation professionals.  Both Hg and Git are great.  The best comparison I&#8217;ve heard is that Hg is like James Bond and Git is like MacGyver.  I&#8217;ll let you interpret that&#8230;</li>
<li><b>It has great tools.</b>  By default it runs from the command line, but you never have to do that.  I&#8217;ll show you <a href="http://tortoisehg.bitbucket.org/" onclick="pageTracker._trackPageview('/outgoing/tortoisehg.bitbucket.org/?referer=');">TortoiseHg</a>, a popular Windows shell that lets you manage your versioned files inside of a normal Windows Explorer window.  Hg also sports integration into popular IDEs.</li>
</ul>
<p>I&#8217;ll assume you&#8217;ve downloaded TortoiseHg and installed it.  It&#8217;s small and also free.  In fact, it comes bundled with Mercurial, so you only have to install one program.</p>
<p>Once that&#8217;s done, follow me&#8230;</p>
<p>First, I created a new Folder on my desktop called My New Repository:</p>
<p><img src="http://www.contactandcoil.com/wp-content/uploads/My-New-Repository.png" alt="" title="My New Repository" width="85" height="94" class="aligncenter size-full wp-image-664" /></p>
<p>Now, right click on the folder.  You&#8217;ll notice that TortoiseHg has added a new submenu to your context menu:</p>
<p><img src="http://www.contactandcoil.com/wp-content/uploads/My-New-Repository-Right-Click.png" alt="" title="My New Repository - Right Click" width="514" height="539" class="aligncenter size-full wp-image-665" /></p>
<p>In the new TortoiseHg submenu, click on &#8220;Create Repository Here&#8221;.  What&#8217;s a Repository?  It&#8217;s just Hg nomenclature for a folder on your computer (or on a network drive) that&#8217;s version controlled.  When you try to create a new repository, it asks you this question:</p>
<p><img src="http://www.contactandcoil.com/wp-content/uploads/My-New-Repository-Right-Click-Confirm.png" alt="" title="My New Repository - Right Click - Confirm" width="431" height="160" class="aligncenter size-full wp-image-667" /></p>
<p>Just click the Create button.  That does two things.  It creates a sub-folder in the folder you right-clicked on called &#8220;.hg&#8221;.  It also creates a &#8220;.hgignore&#8221; file.  Ignore the .hgignore file for now.  You can use it to specify certain patterns of files that you don&#8217;t want to track.  You don&#8217;t need it to start with.</p>
<p>The .hg folder is where Mercurial stores all of its version history (including the version history of all files in this repository, including all files in all subdirectories).  This is a particularly nice feature about Mercurial&#8230; if you want to &#8220;un-version&#8221; a directory, you just delete the .hg folder.  If you want to make a copy of a repository, you just copy the entire repository folder, including the .hg subdirectory.  That means you&#8217;ll get the <em>entire</em> history of all the files.  You can zip it up and send it to a friend.</p>
<p>Now here&#8217;s the cool part&#8230; after you send it to your friend, he can make a change to the files while you make changes to your copy, you can both commit your changes to your local copies, and you can merge the changes together later.  (The merge is very smart, and actually does a line-by-line merge in the case of text files, CSV files, etc., which works really well for PC programming.  Unfortunately if your files use a proprietary binary format, like Excel or a PLC program, Mercurial can&#8217;t merge them, but will at least track versions for you.  If the vendor provides a proprietary merge tool, you can configure Mercurial to open that tool to merge the two files.)</p>
<p>Let&#8217;s try an example.  I want to start designing a new automation cell, so I&#8217;ll just sketch out some rough ideas in Notepad:</p>
<pre>
Line 1
  - Conveyor
    - Zone 1
    - Zone 2
    - Zone 3
  - Robot
    - Interlocks
    - EOAT
    - Vision System
  - Nut Feeder
</pre>
<p>I save it as a file called &#8220;Line 1.txt&#8221; in my repository folder.  At this point I&#8217;ve made changes to the files in my repository (by adding a file) but I haven&#8217;t &#8220;committed&#8221; those changes.  A commit is like a light-weight restore point.  You can always roll back to <em>any</em> commit point in the entire history of the repository, or roll forward to any commit point.  (You can also &#8220;back out&#8221; a single commit even if it was several changes ago, which is a very cool feature.)  It&#8217;s a good idea to commit often.</p>
<p>To commit using TortoiseHg, just right click anywhere in your repository window and click the &#8220;Hg Commit&#8230;&#8221; menu item in the context menu.  You&#8217;ll see a screen like this:</p>
<p><img src="http://www.contactandcoil.com/wp-content/uploads/Commit.png" alt="" title="Commit" width="491" height="491" class="aligncenter size-full wp-image-669" /></p>
<p>It looks a bit weird, but it&#8217;s showing you all the changes you&#8217;ve made since your &#8220;starting point&#8221;.  Since this is a brand new repository, your starting point is just an empty directory.  Once you complete this commit, you&#8217;ll have created a new starting point, and it will track all changes after the commit.  However, you can move your starting point back and forth to any commit point by using the Update command (which I&#8217;ll show you later).</p>
<p>The two files in the Commit dialog box show up with question marks beside them.  That means it knows that it hasn&#8217;t seen these files before, but it&#8217;s not sure if you want to include them in the repository.  In this case you want to include both (notice that the .hgignore file is also a versioned file in the repository&#8230; that&#8217;s just how it works).  Right click on each one and click the Add item from the context menu.  You&#8217;ll notice that it changes the question mark to an &#8220;A&#8221;.  That means the file is being added to the repository during this commit.</p>
<p>In the box at the top, you have to enter some description of the change you&#8217;re making.  In this case, I&#8217;ll say &#8220;Adding initial Line 1 layout&#8221;.  Now click the Commit button in the upper left corner.  That&#8217;s it, the file is now committed in the repository.  Close the commit window.</p>
<p>Now go back to your repository window in Windows Explorer.  You&#8217;ll notice that they now have green checkmark icons next to them (if you&#8217;re using Vista or Windows 7, sometimes you have to go into or out of the directory, come back in, and press F5 to see it update):</p>
<p><img src="http://www.contactandcoil.com/wp-content/uploads/Added-Files.png" alt="" title="Added Files" width="160" height="69" class="aligncenter size-full wp-image-670" /></p>
<p>The green checkmark means the file is exactly the same as your starting point.  Now let&#8217;s try editing it.  I&#8217;ll open it and add a Zone 4 to the conveyor:</p>
<pre>
Line 1
  - Conveyor
    - Zone 1
    - Zone 2
    - Zone 3
    - Zone 4
  - Robot
    - Interlocks
    - EOAT
    - Vision System
  - Nut Feeder
</pre>
<p>The icon in Windows Explorer for my &#8220;Line 1.txt&#8221; file immediately changed from a green checkmark to a red exclamation point.  This means it&#8217;s a tracked file and that file no longer matches the starting point:</p>
<p><img src="http://www.contactandcoil.com/wp-content/uploads/Edited-File.png" alt="" title="Edited File" width="160" height="69" class="aligncenter size-full wp-image-671" /></p>
<p>Notice that it&#8217;s actually comparing the contents of the file, because if you go back into the file and remove the line for Zone 4, it will eventually change the icon back to a green checkmark!</p>
<p>Now that we&#8217;ve made a change, let&#8217;s commit that.  Right click anywhere in the repository window again and click &#8220;Hg Commit&#8230;&#8221;:</p>
<p><img src="http://www.contactandcoil.com/wp-content/uploads/Commit-Edit.png" alt="" title="Commit Edit" width="490" height="492" class="aligncenter size-full wp-image-672" /></p>
<p>Now it&#8217;s showing us that &#8220;Line 1.txt&#8221; has been <em>Modified</em> (see the M beside it) and it even shows us a snapshot of the change.  The box in the bottom right corner shows us that we added a line for Zone 4, and even shows us a few lines before and after so we can see where we added it.  This is enough information for Mercurial to track this change even if we applied this change in a different order than other subsequent changes.  Let&#8217;s finish this commit, and then I&#8217;ll give you an example.  Just enter a description of the change (&#8220;Added Zone 4 to Conveyor&#8221;) and commit it, then close the commit window.</p>
<p>Now right-click in the repository window and click on Hg Repository Explorer in the context menu:</p>
<p><img src="http://www.contactandcoil.com/wp-content/uploads/Repository-Explorer.png" alt="" title="Repository Explorer" width="536" height="571" class="aligncenter size-full wp-image-673" /></p>
<p>This is showing us the entire history of this repository.  I&#8217;ve highlighted the last commit, so it&#8217;s showing a list of files that were affected by that commit, and since I selected the file on the left, it shows the summary of the changes for that file on the right.</p>
<p>Now for some magic.  We can go back to before the last commit.  You do this by right-clicking on the bottom revision (that says &#8220;Adding initial Line 1 layout&#8221;) and selecting &#8220;Update&#8230;&#8221; from the context menu.  You&#8217;ll get a confirmation popup, so just click the Update button on that.  Now the bottom revision line is highlighted in the repository explorer meaning the old version has become your &#8220;starting point&#8221;.  Now go and open the &#8220;Line 1.txt&#8221; file.  You&#8217;ll notice that Zone 4 has been removed from the Conveyor (don&#8217;t worry if the icons don&#8217;t keep up on Vista or Win7, everything is working fine behind the scenes).</p>
<p>Let&#8217;s assume that after the first commit, I gave a copy of the repository to someone, (so they have a copy without Zone 4), and they made a change to the same file.  Maybe they added some detail to the Nut Feeder section:</p>
<pre>
Line 1
  - Conveyor
    - Zone 1
    - Zone 2
    - Zone 3
  - Robot
    - Interlocks
    - EOAT
    - Vision System
  - Nut Feeder
    - 120VAC, 6A
</pre>
<p>Then they committed their change.  Now, how do their changes make it back into your repository?  That&#8217;s by using a feature called Synchronize.  It&#8217;s pretty simple if you have a copy of both on your computer, or if each of you have a copy, and you also have a &#8220;master&#8221; copy of the repository on the server, and you can each see the copy on the server.  What happens is they &#8220;Push&#8221; their changes to the server copy, and then you &#8220;Pull&#8221; their change over to your copy.  (Too much detail for this blog post, so I&#8217;ll leave that to you as an easy homework assignment).  What you&#8217;ll end up with, when you look at the repository explorer, is something like this:</p>
<p><img src="http://www.contactandcoil.com/wp-content/uploads/Repository-Explorer-Branch.png" alt="" title="Repository Explorer - Branch" width="536" height="571" class="aligncenter size-full wp-image-674" /></p>
<p>You can clearly see that we have a <em>branch</em>.  We both made our changes to the initial commit, so now we&#8217;ve forked it.  This is OK.  We just have to do a merge.  In a distributed version control system, merges are normal and fast.  (They&#8217;re fast because it does all the merge logic locally, which is faster than sending everything to a central server).</p>
<p>You can see that we&#8217;re still on the version that&#8217;s bolded (&#8220;Added Zone 4 to Conveory&#8221;).  The newer version, on top, is the one with the Nut Feeder change from our friend.  In order to merge that change with ours, just right click on <em>their</em> version and click &#8220;Merge With&#8230;&#8221; from the context menu.  That will give you a pop-up.  It should be telling you, in a long winded fashion, that you&#8217;re merging the &#8220;other&#8221; version into your &#8220;local&#8221; version.  That&#8217;s what you always want.  Click Merge.  It will give you another box with the result of the merge, and in this case it was successful because there were no conflicts.  Now click Commit.  This actually creates a new version in your repository with both changes, and then updates your local copy to that merged version.  Now take a look at the &#8220;Line 1.txt&#8221; file:</p>
<pre>
Line 1
  - Conveyor
    - Zone 1
    - Zone 2
    - Zone 3
    - Zone 4
  - Robot
    - Interlocks
    - EOAT
    - Vision System
  - Nut Feeder
    - 120VAC, 6A
</pre>
<p>It has both changes, cleanly merged into a single file.  Cool, right!?</p>
<p>What&#8217;s the catch?  Well, if the two changes are too close together, it opens a merge tool where it shows you the original version before either change, the file with one change applied, the file with the other change applied, and then a workspace at the bottom where you can choose what you want to do (apply one, the other, both, none, or custom edit it yourself).  That can seem tedious, but it happens rarely if the people on your project are working on separate areas most of the time, and the answer of how to merge them is usually pretty obvious.  Sometimes you actually have to pick up the phone and ask them what they were doing in that area.  Since the alternative is one person overwriting someone else&#8217;s changes wholesale, this is clearly better.</p>
<p>Mercurial has a ton of other cool features.  You can name your branches different names.  For example, I keep a &#8220;Release&#8221; branch that&#8217;s very close to the production code where I can make &#8220;emergency&#8221; fixes and deploy them quickly, and then I have a &#8220;Development&#8221; branch where I do major changes that take time to stabilize.  I continuously merge the Release branch into the Development branch during development, so that all bug fixes make it into the new major version, but the unstable code in the Development branch doesn&#8217;t interfere with the production code until it&#8217;s ready.  I colour-code these Red and Blue respectively so you can easily see the difference in the repository explorer.</p>
<p>I use the .hgignore file to ignore my active configuration files (like settings.ini, for example).  That means I can have my release and development branches in two different folders on my computer, and each one has a different configuration file (for connecting to different databases, or using different file folders for test data).  Mercurial doesn&#8217;t try to add or merge them.</p>
<p>It even has the ability to do &#8220;Push&#8221; and &#8220;Pull&#8221; operations over HTTP, or email.  It has a built-in HTTP server so you can turn your computer into an Hg server, and your team can Push or Pull updates to or from your repository.  </p>
<p>I hope this is enough to whet your appetite.  If you have questions, please email me.  Also, you can check out this more in-depth tutorial, though it focuses on the command-line version: <a href="http://hginit.com/" onclick="pageTracker._trackPageview('/outgoing/hginit.com/?referer=');">hginit</a>.</p>
<div class="addthis_toolbox addthis_default_style addthis_32x32_style" addthis:url='http://www.contactandcoil.com/automation/industrial-automation/intro-to-mercurial-hg-version-control-for-the-automation-professional/' addthis:title='Intro to Mercurial (Hg) Version Control for the Automation Professional ' ><a class="addthis_button_preferred_1"></a><a class="addthis_button_preferred_2"></a><a class="addthis_button_preferred_3"></a><a class="addthis_button_preferred_4"></a><a class="addthis_button_compact"></a></div>]]></content:encoded>
			<wfw:commentRss>http://www.contactandcoil.com/automation/industrial-automation/intro-to-mercurial-hg-version-control-for-the-automation-professional/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

