<?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>The Nuclear Bunny Blog &#187; Technology</title>
	<atom:link href="http://blog.nuclearbunny.org/category/technology/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.nuclearbunny.org</link>
	<description>Blah, blah, blah...</description>
	<lastBuildDate>Thu, 15 Jul 2010 04:45:23 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>You Don&#8217;t Need Flash for Rich Graphs on a Web Page</title>
		<link>http://blog.nuclearbunny.org/2010/04/11/you-dont-need-flash-for-rich-graphs-on-a-web-page/</link>
		<comments>http://blog.nuclearbunny.org/2010/04/11/you-dont-need-flash-for-rich-graphs-on-a-web-page/#comments</comments>
		<pubDate>Sun, 11 Apr 2010 21:35:33 +0000</pubDate>
		<dc:creator>chadwick</dc:creator>
				<category><![CDATA[Jobs]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Zenoss]]></category>
		<category><![CDATA[flash]]></category>
		<category><![CDATA[graphs]]></category>
		<category><![CDATA[html5]]></category>
		<category><![CDATA[ria]]></category>

		<guid isPermaLink="false">http://blog.nuclearbunny.org/?p=593</guid>
		<description><![CDATA[Adobe&#8217;s Flash has a lot of uses, but one of the most impressive to me has been the the creation of interactive graphs on a web page. One just has to visit Google Finance to see a great example of this in action; it&#8217;s fast, effective and fits seemlessly within the rest of the page. [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.adobe.com/flashplatform/">Adobe&#8217;s Flash</a> has a lot of uses, but one of the most impressive to me has been the the creation of interactive graphs  on a web page. One just has to visit <a href="http://www.google.com/finance?q=NASDAQ:GOOG" target="_blank">Google Finance</a> to see a great example of this in action; it&#8217;s fast, effective and fits seemlessly within the rest of the page.</p>
<p>Many times, however, Flash isn&#8217;t an appropriate technology to use. If you&#8217;re an open-source product like Zenoss, Flash presents a licensing issue. If you&#8217;re targeting mobile platforms like the <a href="http://www.apple.com/iphone/">iPhone</a>, Flash isn&#8217;t available. And, sometimes, you may just not like Flash; it does have it&#8217;s own security problems and overhead, for example. What&#8217;s a web developer to do? Enter HTML5 to the rescue&#8230;</p>
<p><a href="http://en.wikipedia.org/wiki/Html5" target="_blank">HTML5</a> is not yet an approved standard, but it&#8217;s well on its way and surprisingly well-supported by the browser community already. One of the nice new features provided in HTML5 is the <a href="http://en.wikipedia.org/wiki/Canvas_element" target="_blank">canvas element</a> which allows for two-dimensional drawing functionality. Between this new feature and JavaScript, we should be able to create a rich graph display.</p>
<p>To get started, we&#8217;ll first need to create an HTML document that has the structure we&#8217;re after and a place for our drawing canvas to reside.</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot;&gt;
  &lt;head&gt;
    &lt;title&gt;Rich Graph Example using HTML5's Canvas Element&lt;/title&gt;
  &lt;/head&gt;
  &lt;body&gt;
    &lt;h1&gt;Rich Graph Example using HTML5's Canvas Element&lt;/h1&gt;
    &lt;canvas id=&quot;graph1&quot; width=&quot;500&quot; height=&quot;200&quot;&gt;
      This text is displayed if your browser sucks.
    &lt;/canvas&gt;
  &lt;/body&gt;
&lt;/html&gt;</pre></div></div>

<p>Next, we&#8217;ll need some JavaScript to do the work of creating the actual graph display. First, we&#8217;ll need to get a reference to the canvas DOM element and then ask it for it&#8217;s 2D drawing context:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">    <span style="color: #003366; font-weight: bold;">var</span> graph1 <span style="color: #339933;">=</span> document.<span style="color: #660066;">getElementById</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'graph1'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #003366; font-weight: bold;">var</span> context <span style="color: #339933;">=</span> graph1.<span style="color: #660066;">getContext</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'2d'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Next, we&#8217;ll need to define the raw data used to display the graph. We&#8217;re going to assume a set of CPU processor time measurements with 5-minute measurement intervals, much like you would see in <a href="http://www.zenoss.com/">Zenoss</a> or other systems management application.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">    <span style="color: #006600; font-style: italic;">// Raw data, such as what might come back from a server query.</span>
    data <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span>
      <span style="color: #009900;">&#123;</span> value<span style="color: #339933;">:</span> <span style="color: #CC0000;">9.9430</span><span style="color: #339933;">,</span> time<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">new</span> Date<span style="color: #009900;">&#40;</span><span style="color: #CC0000;">2010</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">4</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">9</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">7</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">50</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
      <span style="color: #009900;">&#123;</span> value<span style="color: #339933;">:</span> <span style="color: #CC0000;">0.0000</span><span style="color: #339933;">,</span> time<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">new</span> Date<span style="color: #009900;">&#40;</span><span style="color: #CC0000;">2010</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">4</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">9</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">7</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">55</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
      <span style="color: #009900;">&#123;</span> value<span style="color: #339933;">:</span> <span style="color: #CC0000;">0.0000</span><span style="color: #339933;">,</span> time<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">new</span> Date<span style="color: #009900;">&#40;</span><span style="color: #CC0000;">2010</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">4</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">9</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">8</span><span style="color: #339933;">,</span> 00<span style="color: #339933;">,</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
      <span style="color: #009900;">&#123;</span> value<span style="color: #339933;">:</span> <span style="color: #CC0000;">0.0000</span><span style="color: #339933;">,</span> time<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">new</span> Date<span style="color: #009900;">&#40;</span><span style="color: #CC0000;">2010</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">4</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">9</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">8</span><span style="color: #339933;">,</span> 05<span style="color: #339933;">,</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
      <span style="color: #009900;">&#123;</span> value<span style="color: #339933;">:</span> <span style="color: #CC0000;">5.5828</span><span style="color: #339933;">,</span> time<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">new</span> Date<span style="color: #009900;">&#40;</span><span style="color: #CC0000;">2010</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">4</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">9</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">8</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">10</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
      <span style="color: #009900;">&#123;</span> value<span style="color: #339933;">:</span> <span style="color: #CC0000;">1.0000</span><span style="color: #339933;">,</span> time<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">new</span> Date<span style="color: #009900;">&#40;</span><span style="color: #CC0000;">2010</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">4</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">9</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">8</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">15</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
      <span style="color: #009900;">&#123;</span> value<span style="color: #339933;">:</span> <span style="color: #CC0000;">25.3120</span><span style="color: #339933;">,</span> time<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">new</span> Date<span style="color: #009900;">&#40;</span><span style="color: #CC0000;">2010</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">4</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">9</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">8</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">20</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
      <span style="color: #009900;">&#123;</span> value<span style="color: #339933;">:</span> <span style="color: #CC0000;">45.8210</span><span style="color: #339933;">,</span> time<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">new</span> Date<span style="color: #009900;">&#40;</span><span style="color: #CC0000;">2010</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">4</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">9</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">8</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">25</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
      <span style="color: #009900;">&#123;</span> value<span style="color: #339933;">:</span> <span style="color: #CC0000;">98.3211</span><span style="color: #339933;">,</span> time<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">new</span> Date<span style="color: #009900;">&#40;</span><span style="color: #CC0000;">2010</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">4</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">9</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">8</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">30</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
      <span style="color: #009900;">&#123;</span> value<span style="color: #339933;">:</span> <span style="color: #CC0000;">96.1290</span><span style="color: #339933;">,</span> time<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">new</span> Date<span style="color: #009900;">&#40;</span><span style="color: #CC0000;">2010</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">4</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">9</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">8</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">35</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
      <span style="color: #009900;">&#123;</span> value<span style="color: #339933;">:</span> <span style="color: #CC0000;">94.9128</span><span style="color: #339933;">,</span> time<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">new</span> Date<span style="color: #009900;">&#40;</span><span style="color: #CC0000;">2010</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">4</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">9</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">8</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">40</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
      <span style="color: #009900;">&#123;</span> value<span style="color: #339933;">:</span> <span style="color: #CC0000;">98.3219</span><span style="color: #339933;">,</span> time<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">new</span> Date<span style="color: #009900;">&#40;</span><span style="color: #CC0000;">2010</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">4</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">9</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">8</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">45</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
      <span style="color: #009900;">&#123;</span> value<span style="color: #339933;">:</span> <span style="color: #CC0000;">32.4912</span><span style="color: #339933;">,</span> time<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">new</span> Date<span style="color: #009900;">&#40;</span><span style="color: #CC0000;">2010</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">4</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">9</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">8</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">50</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
    <span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #006600; font-style: italic;">// Calculate the maximums in the provided data.</span>
    <span style="color: #003366; font-weight: bold;">var</span> maxY <span style="color: #339933;">=</span> <span style="color: #CC0000;">0.0</span><span style="color: #339933;">;</span>
    <span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> i <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> data.<span style="color: #660066;">length</span><span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      maxY <span style="color: #339933;">=</span> Math.<span style="color: #660066;">max</span><span style="color: #009900;">&#40;</span>data<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span>.<span style="color: #660066;">value</span><span style="color: #339933;">,</span> maxY<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #003366; font-weight: bold;">var</span> dataMaxY <span style="color: #339933;">=</span> Math.<span style="color: #660066;">ceil</span><span style="color: #009900;">&#40;</span>maxY<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #003366; font-weight: bold;">var</span> dataMaxX <span style="color: #339933;">=</span> data.<span style="color: #660066;">length</span><span style="color: #339933;">;</span></pre></div></div>

<p>Now, we have to calculate where we can start drawing on the canvas and how many pixels equal one coordinate in our user space data. The more elaborate legends we&#8217;ll want to use on the graph, the more these calculations will matter as we leave space for drawing text around the actual graph.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">    <span style="color: #006600; font-style: italic;">// define a font to use for legends</span>
    <span style="color: #003366; font-weight: bold;">var</span> fontHeight <span style="color: #339933;">=</span> <span style="color: #CC0000;">20</span><span style="color: #339933;">;</span>
    <span style="color: #003366; font-weight: bold;">var</span> font <span style="color: #339933;">=</span> <span style="color: #3366CC;">&quot;12px/20px arial, sans-serif&quot;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #003366; font-weight: bold;">var</span> xStart <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span>
    <span style="color: #003366; font-weight: bold;">var</span> yStart <span style="color: #339933;">=</span> fontHeight <span style="color: #339933;">*</span> <span style="color: #CC0000;">2</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// leave room for 2 lines of text at the bottom</span>
    <span style="color: #003366; font-weight: bold;">var</span> xEnd <span style="color: #339933;">=</span> graph1.<span style="color: #660066;">width</span><span style="color: #339933;">;</span>
    <span style="color: #003366; font-weight: bold;">var</span> yEnd <span style="color: #339933;">=</span> graph1.<span style="color: #660066;">height</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #006600; font-style: italic;">// Determine how many pixel units equal one user space coordinate.</span>
    <span style="color: #003366; font-weight: bold;">var</span> xStep <span style="color: #339933;">=</span> dataMaxX <span style="color: #339933;">/</span> <span style="color: #009900;">&#40;</span>xEnd <span style="color: #339933;">-</span> xStart<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #003366; font-weight: bold;">var</span> yStep <span style="color: #339933;">=</span> dataMaxY <span style="color: #339933;">/</span> <span style="color: #009900;">&#40;</span>yEnd <span style="color: #339933;">-</span> yStart<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #006600; font-style: italic;">// Create an array of 2D points to represent the user space</span>
    <span style="color: #006600; font-style: italic;">// coordinates of each data item.</span>
    points <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> Array<span style="color: #009900;">&#40;</span>data.<span style="color: #660066;">length</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> i <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> data.<span style="color: #660066;">length</span><span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #003366; font-weight: bold;">var</span> x <span style="color: #339933;">=</span> i <span style="color: #339933;">/</span> xStep <span style="color: #339933;">+</span> xStart<span style="color: #339933;">;</span>
      <span style="color: #003366; font-weight: bold;">var</span> y <span style="color: #339933;">=</span> data<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span>.<span style="color: #660066;">value</span> <span style="color: #339933;">/</span> yStep <span style="color: #339933;">+</span> yStart<span style="color: #339933;">;</span>
      points<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span> x<span style="color: #339933;">:</span> x<span style="color: #339933;">,</span> y<span style="color: #339933;">:</span> y <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span></pre></div></div>

<p>Now we get to the actual drawing of the graph. This is straight-forward 2D drawing that should be familiar to anyone who has done it with other technology.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">    <span style="color: #006600; font-style: italic;">// Save the graphics context before we begin mucking with it.</span>
    context.<span style="color: #660066;">save</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #006600; font-style: italic;">// Create a transform so that the graph portion of the chart can be</span>
    <span style="color: #006600; font-style: italic;">// drawn using a bottom-left origin instead of the default upper-left.</span>
    context.<span style="color: #660066;">translate</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">0</span><span style="color: #339933;">,</span> yEnd<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    context.<span style="color: #660066;">scale</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">1.0</span><span style="color: #339933;">,</span> <span style="color: #339933;">-</span><span style="color: #CC0000;">1.0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #006600; font-style: italic;">// Draw our path using the appropriate color.</span>
    context.<span style="color: #660066;">beginPath</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    context.<span style="color: #660066;">strokeStyle</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">'black'</span><span style="color: #339933;">;</span>
    context.<span style="color: #660066;">lineWidth</span> <span style="color: #339933;">=</span> <span style="color: #CC0000;">5</span><span style="color: #339933;">;</span>
    context.<span style="color: #660066;">moveTo</span><span style="color: #009900;">&#40;</span>points<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#93;</span>.<span style="color: #660066;">x</span><span style="color: #339933;">,</span> points<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#93;</span>.<span style="color: #660066;">y</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> i <span style="color: #339933;">=</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> points.<span style="color: #660066;">length</span><span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      context.<span style="color: #660066;">lineTo</span><span style="color: #009900;">&#40;</span>points<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span>.<span style="color: #660066;">x</span><span style="color: #339933;">,</span> points<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span>.<span style="color: #660066;">y</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    context.<span style="color: #660066;">stroke</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    context.<span style="color: #660066;">restore</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>At this stage, we can render a simple line-graph using JavaScript and an HTML5 canvas element. Now about making it rich and interactive? We&#8217;ll need to add some mouse event handling. We&#8217;ll do something simple here: as the mouse moves along the x-axis of the graph we&#8217;ll find the current data point based solely on its x-position. This technique is more useful to an end-user and saves the calculation of finding how close a point is to a line segment.</p>
<p>Mouse events are still rather browser specific, so the calculations presented here to determine the offset of the mouse inside of the canvas are simplified and will not work in all scenarios.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">    graph1.<span style="color: #660066;">addEventListener</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'mousemove'</span><span style="color: #339933;">,</span> mouseWatcher<span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #003366; font-weight: bold;">function</span> mouseWatcher<span style="color: #009900;">&#40;</span>evt<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #006600; font-style: italic;">// Get the mouse position relative to the canvas element. This stuff</span>
      <span style="color: #006600; font-style: italic;">// is still gnarly across browsers. Here we're assuming we need to</span>
      <span style="color: #006600; font-style: italic;">// figure out the offset the canvas has in the client area, so our</span>
      <span style="color: #006600; font-style: italic;">// mouse position is really relative to the canvas, not the client area.</span>
      <span style="color: #003366; font-weight: bold;">var</span> x <span style="color: #339933;">=</span> graph1.<span style="color: #660066;">offsetLeft</span> <span style="color: #339933;">+</span> evt.<span style="color: #660066;">clientX</span><span style="color: #339933;">;</span>
      <span style="color: #003366; font-weight: bold;">var</span> y <span style="color: #339933;">=</span> graph1.<span style="color: #660066;">height</span> <span style="color: #339933;">+</span> graph1.<span style="color: #660066;">offsetTop</span> <span style="color: #339933;">-</span> evt.<span style="color: #660066;">clientY</span><span style="color: #339933;">;</span>
&nbsp;
      <span style="color: #006600; font-style: italic;">// Get the data point at this X position</span>
      <span style="color: #003366; font-weight: bold;">var</span> foundPoint <span style="color: #339933;">=</span> <span style="color: #339933;">-</span><span style="color: #CC0000;">1</span><span style="color: #339933;">;</span>
      <span style="color: #003366; font-weight: bold;">var</span> x1 <span style="color: #339933;">=</span> points<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#93;</span>.<span style="color: #660066;">x</span><span style="color: #339933;">;</span>
      <span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> i <span style="color: #339933;">=</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> points.<span style="color: #660066;">length</span><span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #003366; font-weight: bold;">var</span> x2 <span style="color: #339933;">=</span> points<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span>.<span style="color: #660066;">x</span><span style="color: #339933;">;</span>
        <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>x <span style="color: #339933;">&gt;=</span> x1 <span style="color: #339933;">&amp;&amp;</span> x <span style="color: #339933;">&lt;=</span> x2<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
          foundPoint <span style="color: #339933;">=</span> i<span style="color: #339933;">-</span><span style="color: #CC0000;">1</span><span style="color: #339933;">;</span>
          <span style="color: #000066; font-weight: bold;">break</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
      <span style="color: #009900;">&#125;</span>
&nbsp;
      <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>foundPoint <span style="color: #339933;">&gt;=</span> <span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        txt <span style="color: #339933;">=</span> <span style="color: #3366CC;">&quot;&quot;</span> <span style="color: #339933;">+</span> data<span style="color: #009900;">&#91;</span>foundPoint<span style="color: #009900;">&#93;</span>.<span style="color: #660066;">value</span>.<span style="color: #660066;">toFixed</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">2</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">&quot; @ &quot;</span> <span style="color: #339933;">+</span> data<span style="color: #009900;">&#91;</span>foundPoint<span style="color: #009900;">&#93;</span>.<span style="color: #660066;">time</span>.<span style="color: #660066;">toDateString</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #006600; font-style: italic;">// draw a new information line in the legend</span>
        context.<span style="color: #660066;">save</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        context.<span style="color: #660066;">font</span> <span style="color: #339933;">=</span> font<span style="color: #339933;">;</span>
        context.<span style="color: #660066;">clearRect</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">0</span><span style="color: #339933;">,</span> yEnd <span style="color: #339933;">-</span> fontHeight<span style="color: #339933;">,</span> xEnd<span style="color: #339933;">,</span> fontHeight<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        context.<span style="color: #660066;">fillText</span><span style="color: #009900;">&#40;</span>txt<span style="color: #339933;">,</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">,</span> yEnd<span style="color: #339933;">,</span> xEnd<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        context.<span style="color: #660066;">restore</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span></pre></div></div>

<p>And that&#8217;s it. Over your Sunday morning coffee you can write a simple, yet effective, interactive graph display using HTML and JavaScript alone. Clearly, a tremendous amount of work remains to make the graphs beautiful and robust, but luckily a large number of people are already working on libraries to do this work for us.</p>
<p>Internet Explorer will not yet display canvas elements natively, but luckily this problem is being <a href="http://blog.vlad1.com/2008/07/30/no-browser-left-behind/">solved</a> for us.</p>
<p>There are other problems, too. Today, for example, the font measurement abilities in the HTML5 specification are lacking.</p>
<p>If you want to see the example in action click <a href='http://blog.nuclearbunny.org/wp-content/uploads/2010/04/canvas-graphs.html'>here.</a> View the source in your browser to see the final source code to the example. A screenshot of the example is below.</p>
<p><a href="http://blog.nuclearbunny.org/wp-content/uploads/2010/04/Screen-shot-2010-04-11-at-16.44.55.png"><img src="http://blog.nuclearbunny.org/wp-content/uploads/2010/04/Screen-shot-2010-04-11-at-16.44.55.png" alt="" title="Screen shot of graph" width="666" height="277" class="aligncenter size-full wp-image-616" /></a></p>

<div class="sociable">
<div class="sociable_tagline">
<strong>Share and Enjoy:</strong>
</div>
<ul>
	<li class="sociablefirst"><a rel="nofollow"  href="http://digg.com/submit?phase=2&amp;url=http%3A%2F%2Fblog.nuclearbunny.org%2F2010%2F04%2F11%2Fyou-dont-need-flash-for-rich-graphs-on-a-web-page%2F&amp;title=You%20Don%27t%20Need%20Flash%20for%20Rich%20Graphs%20on%20a%20Web%20Page&amp;bodytext=Adobe%27s%20Flash%20has%20a%20lot%20of%20uses%2C%20but%20one%20of%20the%20most%20impressive%20to%20me%20has%20been%20the%20the%20creation%20of%20interactive%20graphs%20%20on%20a%20web%20page.%20One%20just%20has%20to%20visit%20Google%20Finance%20to%20see%20a%20great%20example%20of%20this%20in%20action%3B%20it%27s%20fast%2C%20effective%20and%20fits%20seemles" title="Digg"><img src="http://blog.nuclearbunny.org/wp-content/plugins/sociable/images/digg.png" title="Digg" alt="Digg" class="sociable-hovers" /></a></li>
	<li><a rel="nofollow"  href="http://www.stumbleupon.com/submit?url=http%3A%2F%2Fblog.nuclearbunny.org%2F2010%2F04%2F11%2Fyou-dont-need-flash-for-rich-graphs-on-a-web-page%2F&amp;title=You%20Don%27t%20Need%20Flash%20for%20Rich%20Graphs%20on%20a%20Web%20Page" title="StumbleUpon"><img src="http://blog.nuclearbunny.org/wp-content/plugins/sociable/images/stumbleupon.png" title="StumbleUpon" alt="StumbleUpon" class="sociable-hovers" /></a></li>
	<li><a rel="nofollow"  href="http://delicious.com/post?url=http%3A%2F%2Fblog.nuclearbunny.org%2F2010%2F04%2F11%2Fyou-dont-need-flash-for-rich-graphs-on-a-web-page%2F&amp;title=You%20Don%27t%20Need%20Flash%20for%20Rich%20Graphs%20on%20a%20Web%20Page&amp;notes=Adobe%27s%20Flash%20has%20a%20lot%20of%20uses%2C%20but%20one%20of%20the%20most%20impressive%20to%20me%20has%20been%20the%20the%20creation%20of%20interactive%20graphs%20%20on%20a%20web%20page.%20One%20just%20has%20to%20visit%20Google%20Finance%20to%20see%20a%20great%20example%20of%20this%20in%20action%3B%20it%27s%20fast%2C%20effective%20and%20fits%20seemles" title="del.icio.us"><img src="http://blog.nuclearbunny.org/wp-content/plugins/sociable/images/delicious.png" title="del.icio.us" alt="del.icio.us" class="sociable-hovers" /></a></li>
	<li><a rel="nofollow"  href="http://www.google.com/bookmarks/mark?op=edit&amp;bkmk=http%3A%2F%2Fblog.nuclearbunny.org%2F2010%2F04%2F11%2Fyou-dont-need-flash-for-rich-graphs-on-a-web-page%2F&amp;title=You%20Don%27t%20Need%20Flash%20for%20Rich%20Graphs%20on%20a%20Web%20Page&amp;annotation=Adobe%27s%20Flash%20has%20a%20lot%20of%20uses%2C%20but%20one%20of%20the%20most%20impressive%20to%20me%20has%20been%20the%20the%20creation%20of%20interactive%20graphs%20%20on%20a%20web%20page.%20One%20just%20has%20to%20visit%20Google%20Finance%20to%20see%20a%20great%20example%20of%20this%20in%20action%3B%20it%27s%20fast%2C%20effective%20and%20fits%20seemles" title="Google Bookmarks"><img src="http://blog.nuclearbunny.org/wp-content/plugins/sociable/images/googlebookmark.png" title="Google Bookmarks" alt="Google Bookmarks" class="sociable-hovers" /></a></li>
	<li class="sociablelast"><a rel="nofollow"  href="http://www.facebook.com/share.php?u=http%3A%2F%2Fblog.nuclearbunny.org%2F2010%2F04%2F11%2Fyou-dont-need-flash-for-rich-graphs-on-a-web-page%2F&amp;t=You%20Don%27t%20Need%20Flash%20for%20Rich%20Graphs%20on%20a%20Web%20Page" title="Facebook"><img src="http://blog.nuclearbunny.org/wp-content/plugins/sociable/images/facebook.png" title="Facebook" alt="Facebook" class="sociable-hovers" /></a></li>
</ul>
</div>
]]></content:encoded>
			<wfw:commentRss>http://blog.nuclearbunny.org/2010/04/11/you-dont-need-flash-for-rich-graphs-on-a-web-page/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>An Early iPad Review</title>
		<link>http://blog.nuclearbunny.org/2010/04/05/an-early-ipad-review/</link>
		<comments>http://blog.nuclearbunny.org/2010/04/05/an-early-ipad-review/#comments</comments>
		<pubDate>Tue, 06 Apr 2010 01:33:11 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[iPad]]></category>

		<guid isPermaLink="false">http://blog.nuclearbunny.org/2010/04/05/an-early-ipad-review/</guid>
		<description><![CDATA[I&#8217;ve been using the iPad heavily for 2 days now. There is an awful lot of potential in this device, ands there is no doubt that the best is yet to come. If you are already an iPhone user, the iPad will simultaneously feel familiar but also so incredibly rich and powerful compared to it&#8217;s [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been using the iPad heavily for 2 days now. There is an awful lot of potential in this device, ands there is no doubt that the best is yet to come. </p>
<p>If you are already an iPhone user, the iPad will simultaneously feel familiar but also so incredibly rich and powerful compared to it&#8217;s little brother. The extra screen real estate is in itself nice, but more importantly is how the iPhone OS&#8217;s approach to user interaction makes use of this extra room. </p>
<p>For example, the Mail app shows each message in full screen glory, but with a fast overlay window to show message and folder navigation. The usability effect is wonderful. Using Safari is now like browsing on a regular computer, except with a multi-touch interface. </p>
<p>I don&#8217;t play very many games on the iPhone or iPad, but the Words With Friends game (think Scrabble) is almost worth getting an iPad for just to play it. I suspect the casual gaming crowd I&#8217;ll a have a lot to look forward to with their new toy. </p>
<p>Battery life on the iPad has been better than I expected. A little over 48 hour into ownership and I&#8217;m down to 10% battery life. I&#8217;ve used it a lot, including a lot of reading, so it seems to hold up well there. While it does not compare to the extra long battery life of a Kindle, the device does so much more it seems like a good trade-off. </p>
<p>As far as being an e-reader, I like the iPad better than the Kindle DX (that I normally read from), but not as much as the regular Kindle 2. That device is sized so well, and the battery life is so good, it&#8217;s easy to see it remaining the king of its segment for a while. That said, I am a guy, so i like big screens, and here the iPad wins over the DX. The iPad is a touch heavier, but it still feels natural to hold. A minor, but very nice feature in the iPad is the physical orientation lock button, something which the DX has as a software feature that is hard to use. </p>
<p>I plan on using my iPad as a replacement for my laptop for casual computing. It seems like it is going to do that job well. They keyboard is easy enough to use even for this blog entry, and the heavy writers out there may find the keyboard dock option even better than lugging around a laptop. </p>

<div class="sociable">
<div class="sociable_tagline">
<strong>Share and Enjoy:</strong>
</div>
<ul>
	<li class="sociablefirst"><a rel="nofollow"  href="http://digg.com/submit?phase=2&amp;url=http%3A%2F%2Fblog.nuclearbunny.org%2F2010%2F04%2F05%2Fan-early-ipad-review%2F&amp;title=An%20Early%20iPad%20Review&amp;bodytext=I%27ve%20been%20using%20the%20iPad%20heavily%20for%202%20days%20now.%20There%20is%20an%20awful%20lot%20of%20potential%20in%20this%20device%2C%20ands%20there%20is%20no%20doubt%20that%20the%20best%20is%20yet%20to%20come.%20%0A%0AIf%20you%20are%20already%20an%20iPhone%20user%2C%20the%20iPad%20will%20simultaneously%20feel%20familiar%20but%20also%20so%20incre" title="Digg"><img src="http://blog.nuclearbunny.org/wp-content/plugins/sociable/images/digg.png" title="Digg" alt="Digg" class="sociable-hovers" /></a></li>
	<li><a rel="nofollow"  href="http://www.stumbleupon.com/submit?url=http%3A%2F%2Fblog.nuclearbunny.org%2F2010%2F04%2F05%2Fan-early-ipad-review%2F&amp;title=An%20Early%20iPad%20Review" title="StumbleUpon"><img src="http://blog.nuclearbunny.org/wp-content/plugins/sociable/images/stumbleupon.png" title="StumbleUpon" alt="StumbleUpon" class="sociable-hovers" /></a></li>
	<li><a rel="nofollow"  href="http://delicious.com/post?url=http%3A%2F%2Fblog.nuclearbunny.org%2F2010%2F04%2F05%2Fan-early-ipad-review%2F&amp;title=An%20Early%20iPad%20Review&amp;notes=I%27ve%20been%20using%20the%20iPad%20heavily%20for%202%20days%20now.%20There%20is%20an%20awful%20lot%20of%20potential%20in%20this%20device%2C%20ands%20there%20is%20no%20doubt%20that%20the%20best%20is%20yet%20to%20come.%20%0A%0AIf%20you%20are%20already%20an%20iPhone%20user%2C%20the%20iPad%20will%20simultaneously%20feel%20familiar%20but%20also%20so%20incre" title="del.icio.us"><img src="http://blog.nuclearbunny.org/wp-content/plugins/sociable/images/delicious.png" title="del.icio.us" alt="del.icio.us" class="sociable-hovers" /></a></li>
	<li><a rel="nofollow"  href="http://www.google.com/bookmarks/mark?op=edit&amp;bkmk=http%3A%2F%2Fblog.nuclearbunny.org%2F2010%2F04%2F05%2Fan-early-ipad-review%2F&amp;title=An%20Early%20iPad%20Review&amp;annotation=I%27ve%20been%20using%20the%20iPad%20heavily%20for%202%20days%20now.%20There%20is%20an%20awful%20lot%20of%20potential%20in%20this%20device%2C%20ands%20there%20is%20no%20doubt%20that%20the%20best%20is%20yet%20to%20come.%20%0A%0AIf%20you%20are%20already%20an%20iPhone%20user%2C%20the%20iPad%20will%20simultaneously%20feel%20familiar%20but%20also%20so%20incre" title="Google Bookmarks"><img src="http://blog.nuclearbunny.org/wp-content/plugins/sociable/images/googlebookmark.png" title="Google Bookmarks" alt="Google Bookmarks" class="sociable-hovers" /></a></li>
	<li class="sociablelast"><a rel="nofollow"  href="http://www.facebook.com/share.php?u=http%3A%2F%2Fblog.nuclearbunny.org%2F2010%2F04%2F05%2Fan-early-ipad-review%2F&amp;t=An%20Early%20iPad%20Review" title="Facebook"><img src="http://blog.nuclearbunny.org/wp-content/plugins/sociable/images/facebook.png" title="Facebook" alt="Facebook" class="sociable-hovers" /></a></li>
</ul>
</div>
]]></content:encoded>
			<wfw:commentRss>http://blog.nuclearbunny.org/2010/04/05/an-early-ipad-review/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>My Zenoss Development Environment &#8211; Part 3</title>
		<link>http://blog.nuclearbunny.org/2009/10/22/my-zenoss-development-environment-part-3/</link>
		<comments>http://blog.nuclearbunny.org/2009/10/22/my-zenoss-development-environment-part-3/#comments</comments>
		<pubDate>Thu, 22 Oct 2009 22:01:01 +0000</pubDate>
		<dc:creator>chadwick</dc:creator>
				<category><![CDATA[Jobs]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Zenoss]]></category>
		<category><![CDATA[eclipse]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[work]]></category>

		<guid isPermaLink="false">http://blog.nuclearbunny.org/?p=545</guid>
		<description><![CDATA[In Part 1 of this series we discussed getting an initial Zenoss environment checked out and running on a Mac OS X or Ubuntu system. In Part 2 we discussed how to configure Eclipse to use the Zenoss source. In this part, we&#8217;ll discuss how to handle day-to-day operations such as branch management and working [...]]]></description>
			<content:encoded><![CDATA[<p>In <a href="../2009/10/22/my-zenoss-development-environment-part-1/" target="_blank">Part 1</a> of this series we discussed getting an initial <a href="http://www.zenoss.com/" target="_blank">Zenoss</a> environment checked out and running on a <a href="http://www.apple.com/macosx/" target="_blank">Mac OS X </a>or <a href="http://www.ubuntu.com/" target="_blank">Ubuntu</a> system. In <a href="http://blog.nuclearbunny.org/2009/10/22/my-zenoss-development-environment-part-2/" target="_self">Part 2</a> we discussed how to configure <a href="http://www.eclipse.org/" target="_blank">Eclipse</a> to use the Zenoss source. In this part, we&#8217;ll discuss how to handle day-to-day operations such as branch management and working with multiple versions.</p>
<h2>Branch-Based Development</h2>
<p>At Zenoss we do all development, including bug fixes and small maintenance tasks, in a private development branch within the subversion repository. This allows us to independently work-on changes, check-them into the repository for safe-keeping, and then perform code reviews with team members without having to share files or using <a href="http://pastebin.com/" target="_blank">pastebin</a> style tools (even though we do both at times).</p>
<ol>
<li>Create a branch within your user&#8217;s sandbox. In this example, I&#8217;ve decided to name the sandbox <code>new-widget</code> to identify what I&#8217;m working on. If I were fixing a defect, I&#8217;d use the defect number from the defect tracking system. Create the branch by copying the trunk folder to the sandbox branch. In Subversion this is a low-overhead operation and doesn&#8217;t actually copy files.<code><br />
svn copy http://dev.zenoss.org/svn/trunk http://dev.zenoss.org/svn/sandboxen/cgibbons/new-widget -m " * Copying trunk to sandbox branch."<br />
</code></li>
<li>Switch your working directory to use the new sandbox branch. You can do this either from the command-line or using Eclipse. From the command line, you&#8217;d do the following:<code><br />
cd $HOME/zenoss/core<br />
svn switch http://dev.zenoss.org/svn/sandboxen/cgibbons/new-widget<br />
</code>From within Eclipse, secondary-click on the <code>core</code> project and choose <em>Switch to Another Branch/Tag/Revision&#8230;</em> option from the Team menu. On the dialog that appears, enter in the sandbox URL. After switching, your Eclipse will show the new location next to the core project item.<br />
<a rel="attachment wp-att-549" href="http://blog.nuclearbunny.org/2009/10/22/my-zenoss-development-environment-part-3/picture-8/"><img class="aligncenter size-full wp-image-549" title="svn switch" src="http://blog.nuclearbunny.org/wp-content/uploads/2009/10/Picture-8.png" alt="svn switch" width="670" height="491" /></a></li>
</ol>
<p>Once your development environment has been switched, you can make changes and commit to the Subversion repository as desired. If you&#8217;re unsure if you are in the right branch, you can always use the <code>svn info</code> command to see which directory is being used.</p>
<h2>Merging Branches</h2>
<p>Once you have completed changes in a branch and have had them reviewed by a peer, it is time to merge them into trunk (or another branch, if using a maintenance release). Merging can be tricky, but a consistent process can make it much easier to handle.</p>
<ol>
<li>Change your working directory to a checked-out and clean version of the branch you want to merge into. For example, I keep a <code>$HOME/zenoss/clean-trunk</code> directory that I never make changes to, except for merging.</li>
<li>Determine the base working revision of your working branch. There are a variety of ways to do this, but one of the best is to view the revision log graph within the Trac system directly. For example, for the branch discussed above we can browse to <a href="http://dev.zenoss.org/trac/log/sandboxen/cgibbons/new-widget" target="_blank">http://dev.zenoss.org/trac/log/sandboxen/cgibbons/new-widget/</a> and see that revision <strong>15513</strong> is the base.</li>
<li>Perform a dry-run on the merge to get a general idea of what the changes into the branch will be. You should see your expected changes, plus any conflicts from changes to the other branch while you have been working in the sandbox branch.<code><br />
svn merge --dry-run --revision <strong>15513</strong>:HEAD <strong>http://dev.zenoss.org/svn/sandboxen/cgibbons/new-widget</strong> .<br />
</code></li>
<li>If the merge results look satisfactory, rerun the command without the dry-run argument.</li>
<li>Look at the final merge results using <code>svn status</code> and <code>svn diff</code>, and once you&#8217;re ready, issue an <code>svn commit</code>.</li>
</ol>
<h2>Multiple Branches and Zenoss Configuration</h2>
<p>As you switch between branches you will often render your Zenoss configuration useless.  Resetting your database after each branch switch is usually a good practice, and being able to quickly recreate any test data you may need makes this process less painful.</p>
<p>After switching a branch, my process is usually the following:</p>
<ol>
<li>Shutdown zenoss and restart only zeo.<code><br />
zenoss stop<br />
zeoctl start</code></li>
<li>Run the zenwipe script from the inst source directory.<code><br />
$HOME/zenoss/inst/zenwipe.sh --no-prompt</code></li>
<li>Run <code>zenmigrate</code> to install any database changes available within the current branch.</li>
</ol>
<p>Depending upon the task at hand, I may install additional ZenPacks and add new devices through the command-line if those are needed. Helper scripts, such as <code>install-windows.sh</code> to install of the Windows ZenPacks and create several local test devices in the instance, are useful tools to have for your typical configurations.</p>

<div class="sociable">
<div class="sociable_tagline">
<strong>Share and Enjoy:</strong>
</div>
<ul>
	<li class="sociablefirst"><a rel="nofollow"  href="http://digg.com/submit?phase=2&amp;url=http%3A%2F%2Fblog.nuclearbunny.org%2F2009%2F10%2F22%2Fmy-zenoss-development-environment-part-3%2F&amp;title=My%20Zenoss%20Development%20Environment%20-%20Part%203&amp;bodytext=In%20Part%201%20of%20this%20series%20we%20discussed%20getting%20an%20initial%20Zenoss%20environment%20checked%20out%20and%20running%20on%20a%20Mac%20OS%20X%20or%20Ubuntu%20system.%20In%20Part%202%20we%20discussed%20how%20to%20configure%20Eclipse%20to%20use%20the%20Zenoss%20source.%20In%20this%20part%2C%20we%27ll%20discuss%20how%20to%20handle%20da" title="Digg"><img src="http://blog.nuclearbunny.org/wp-content/plugins/sociable/images/digg.png" title="Digg" alt="Digg" class="sociable-hovers" /></a></li>
	<li><a rel="nofollow"  href="http://www.stumbleupon.com/submit?url=http%3A%2F%2Fblog.nuclearbunny.org%2F2009%2F10%2F22%2Fmy-zenoss-development-environment-part-3%2F&amp;title=My%20Zenoss%20Development%20Environment%20-%20Part%203" title="StumbleUpon"><img src="http://blog.nuclearbunny.org/wp-content/plugins/sociable/images/stumbleupon.png" title="StumbleUpon" alt="StumbleUpon" class="sociable-hovers" /></a></li>
	<li><a rel="nofollow"  href="http://delicious.com/post?url=http%3A%2F%2Fblog.nuclearbunny.org%2F2009%2F10%2F22%2Fmy-zenoss-development-environment-part-3%2F&amp;title=My%20Zenoss%20Development%20Environment%20-%20Part%203&amp;notes=In%20Part%201%20of%20this%20series%20we%20discussed%20getting%20an%20initial%20Zenoss%20environment%20checked%20out%20and%20running%20on%20a%20Mac%20OS%20X%20or%20Ubuntu%20system.%20In%20Part%202%20we%20discussed%20how%20to%20configure%20Eclipse%20to%20use%20the%20Zenoss%20source.%20In%20this%20part%2C%20we%27ll%20discuss%20how%20to%20handle%20da" title="del.icio.us"><img src="http://blog.nuclearbunny.org/wp-content/plugins/sociable/images/delicious.png" title="del.icio.us" alt="del.icio.us" class="sociable-hovers" /></a></li>
	<li><a rel="nofollow"  href="http://www.google.com/bookmarks/mark?op=edit&amp;bkmk=http%3A%2F%2Fblog.nuclearbunny.org%2F2009%2F10%2F22%2Fmy-zenoss-development-environment-part-3%2F&amp;title=My%20Zenoss%20Development%20Environment%20-%20Part%203&amp;annotation=In%20Part%201%20of%20this%20series%20we%20discussed%20getting%20an%20initial%20Zenoss%20environment%20checked%20out%20and%20running%20on%20a%20Mac%20OS%20X%20or%20Ubuntu%20system.%20In%20Part%202%20we%20discussed%20how%20to%20configure%20Eclipse%20to%20use%20the%20Zenoss%20source.%20In%20this%20part%2C%20we%27ll%20discuss%20how%20to%20handle%20da" title="Google Bookmarks"><img src="http://blog.nuclearbunny.org/wp-content/plugins/sociable/images/googlebookmark.png" title="Google Bookmarks" alt="Google Bookmarks" class="sociable-hovers" /></a></li>
	<li class="sociablelast"><a rel="nofollow"  href="http://www.facebook.com/share.php?u=http%3A%2F%2Fblog.nuclearbunny.org%2F2009%2F10%2F22%2Fmy-zenoss-development-environment-part-3%2F&amp;t=My%20Zenoss%20Development%20Environment%20-%20Part%203" title="Facebook"><img src="http://blog.nuclearbunny.org/wp-content/plugins/sociable/images/facebook.png" title="Facebook" alt="Facebook" class="sociable-hovers" /></a></li>
</ul>
</div>
]]></content:encoded>
			<wfw:commentRss>http://blog.nuclearbunny.org/2009/10/22/my-zenoss-development-environment-part-3/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>My Zenoss Development Environment &#8211; Part 2</title>
		<link>http://blog.nuclearbunny.org/2009/10/22/my-zenoss-development-environment-part-2/</link>
		<comments>http://blog.nuclearbunny.org/2009/10/22/my-zenoss-development-environment-part-2/#comments</comments>
		<pubDate>Thu, 22 Oct 2009 19:26:36 +0000</pubDate>
		<dc:creator>chadwick</dc:creator>
				<category><![CDATA[Jobs]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Zenoss]]></category>
		<category><![CDATA[eclipse]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[work]]></category>

		<guid isPermaLink="false">http://blog.nuclearbunny.org/?p=511</guid>
		<description><![CDATA[In Part 1 of this series we discussed getting an initial Zenoss environment checked out and running on a Mac OS X or Ubuntu system. In this part, we&#8217;ll discuss configuring Eclipse to use this environment. Mac OS X Prerequisites Install Eclipse Classic 3.5.x Mac Cocoa 32-bit. Ubuntu Prerequisites Install the Sun Java JDK. Why? [...]]]></description>
			<content:encoded><![CDATA[<p>In <a href="http://blog.nuclearbunny.org/2009/10/22/my-zenoss-development-environment-part-1/" target="_blank">Part 1</a> of this series we discussed getting an initial <a href="http://www.zenoss.com/" target="_blank">Zenoss</a> environment checked out and running on a <a href="http://www.apple.com/macosx/" target="_blank">Mac OS X </a>or <a href="http://www.ubuntu.com/" target="_blank">Ubuntu</a> system. In this part, we&#8217;ll discuss configuring <a href="http://www.eclipse.org/" target="_blank">Eclipse</a> to use this environment.</p>
<h2>Mac OS X Prerequisites</h2>
<ol>
<li>Install <a href="http://www.eclipse.org/downloads/" target="_blank">Eclipse Classic</a> 3.5.x Mac <a href="http://blog.zvikico.com/2009/06/eclipse-galileo-for-mac-cocoa-or-carbon.html" target="_blank">Cocoa 32-bit</a>.</li>
</ol>
<h2>Ubuntu Prerequisites</h2>
<ol>
<li>Install the Sun Java JDK. <strong>Why?</strong> Eclipse is a Java application and requires a full-fledged Java environment to run properly.<code><br />
sudo apt-get -y install sun-java6-jdk<br />
</code></li>
<li>Install <a href="http://www.eclipse.org/downloads/" target="_blank">Eclipse Classic</a> 3.5.x Linux 32-bit.</li>
</ol>
<h2>Eclipse Configuration</h2>
<ol>
<li>In part one, we created a Zenoss root project directory of <code>$HOME/zenoss</code> &#8211; use that directory, or the one you created, for the rest of these steps.</li>
<li>Launch Eclipse and configure it to use the Zenoss root project directory. <strong>Why?</strong> Eclipse needs a workspace directory to keep track of configuration settings for a group of related projects. By placing the workspace directory inside of the Zenoss root workspace, we can separate the requirements for a Zenoss workspace from other projects you may be using.<a rel="attachment wp-att-484" href="http://blog.nuclearbunny.org/2009/10/22/my-zenoss-development-environment-part-1/eclipse-workspace-2/"><img title="eclipse-workspace" src="http://blog.nuclearbunny.org/wp-content/uploads/2009/10/eclipse-workspace1.png" alt="eclipse-workspace" width="677" height="324" /></a></li>
<li>Install the <a href="http://pydev.org/" target="_blank">PyDev</a> plug-in for Eclipse. <strong>Why?</strong> PyDev provides Python language support to Eclipse.
<ol>
<li>Go to the Help Menu and choose<em> Install New Software</em>.</li>
<li>In the Available Software dialog, choose <em>Add</em> and enter in <code>http://pydev.org/updates/</code> as the Location and close the dialog. Eclipse will return to the Available Software dialog.<a rel="attachment wp-att-498" href="http://blog.nuclearbunny.org/2009/10/22/my-zenoss-development-environment-part-1/picture-5/"><img title="PyDev" src="http://blog.nuclearbunny.org/wp-content/uploads/2009/10/Picture-5.png" alt="PyDev" width="555" height="260" /></a></li>
<li>Software matching PyDev will appear in the dialog; pick the <em>PyDev</em> option but do not pick <em>PyDev Mylyn Integration</em>. Click <em>Next</em> and install the plug-in.</li>
</ol>
<p><a rel="attachment wp-att-500" href="http://blog.nuclearbunny.org/2009/10/22/my-zenoss-development-environment-part-1/picture-6-2/"><img title="PyDev" src="http://blog.nuclearbunny.org/wp-content/uploads/2009/10/Picture-61.png" alt="PyDev" width="725" height="643" /></a></li>
<li>Install the <a href="http://subclipse.tigris.org/" target="_blank">Subclipse</a> plug-in. <strong>Why?</strong> Subclipse allows you to work with the Subversion version control system directly from within Eclipse.
<ol>
<li>In the Available Software dialog add the Subclipse plug-in update site: <code>
<p>http://subclipse.tigris.org/update_1.6.x</p>
<p></code></li>
<li>In the Available Software dialog, choose the <em>Subclipse</em>, <em>Subversion Client Adapter</em>, <em>Subversion JavaHL Native Library Adapter</em> and the <em>Subversion Revision Graph </em>items.<a rel="attachment wp-att-553" href="http://blog.nuclearbunny.org/2009/10/22/my-zenoss-development-environment-part-2/picture-5-2/"><img class="aligncenter size-full wp-image-553" title="Subclipse" src="http://blog.nuclearbunny.org/wp-content/uploads/2009/10/Picture-51.png" alt="Subclipse" width="798" height="742" /></a></li>
</ol>
</li>
<li>Go to the Window menu, choose Open Perspective and then SVN Repository Exploring (you may have to choose Other&#8230; to see this option).</li>
<li>Choose the New Repository Location button in the SVN Repositories panel. Add the Zenoss SVN site at <code>http://dev.zenoss.org/svn</code></li>
<li>Open the SVN repository and select the <code>trunk</code> folder. Secondary-click the folder and choose the <em>Checkout&#8230; </em>option. Be sure to change the Depth option to be <em>Only this item</em> so that we don&#8217;t check out any of the sub-folders of trunk just yet (many of the folders within trunk are not needed for development, but we want to keep the directory structure). In the next dialog you will be asked to choose a Project Wizard. Open the Pydev tree item and select the <em>Pydev Project</em> option.<a rel="attachment wp-att-554" href="http://blog.nuclearbunny.org/2009/10/22/my-zenoss-development-environment-part-2/picture-6-3/"><img class="aligncenter size-full wp-image-554" title="svn checkout" src="http://blog.nuclearbunny.org/wp-content/uploads/2009/10/Picture-62.png" alt="svn checkout" width="605" height="556" /></a></li>
<li>Create the project in the Pydev Project dialog:
<ol>
<li>Use <code>core</code> as the project name and use the default location. This should create a core project at <code>$HOME/zenoss/core</code>.</li>
<li>Make sure the <em>Python</em> project type is selected.</li>
<li>Select<em> 2.4</em> as the Python Grammar version.</li>
<li>Uncheck the <em>Create default &#8216;src&#8217; folder..</em>. option.</li>
<li>Click the Click here to <em>configure an interpreter not listed&#8230;</em> option in order to add the python interpreter built by the Zenoss installation scripts.
<ol>
<li>In the Preferences Dialog, choose the Interpreter &#8211; Python item underneath Pydev and select the <em>New&#8230;</em> button to add a new Python interpreter.</li>
<li>Browse to the <code>$ZENHOME/bin</code> directory and choose the <code>python2.4</code> executable from that directory.</li>
<li>Name the interpreter <code>python-2.4</code>, <code>zenoss-python</code> or some other variant.</li>
<p><a rel="attachment wp-att-529" href="http://blog.nuclearbunny.org/2009/10/22/my-zenoss-development-environment-part-2/picture-13/"><img class="aligncenter size-full wp-image-529" title="Picture 13" src="http://blog.nuclearbunny.org/wp-content/uploads/2009/10/Picture-13.png" alt="Picture 13" width="632" height="303" /></a>After the new Python interpreter has been added, return to the Pydev Project dialog and choose that interpreter from the list and then click <em>Finish</em> to create the project.</ol>
</li>
<li>Update the <code>core</code> folder from the command-line SVN client so you can selectively pull the sub-folders of the core project and not all of them:<code><br />
cd $HOME/zenoss/core<br />
svn update Products<br />
</code></li>
<li>Move the Products directory the installation checked out and create a symbolic link to the one updated above. <strong>Why?</strong> This allows the Products source tree to be worked on from Eclipse and then also used by the Zenoss run-time.<code><br />
cd $ZENHOME<br />
mv Products Products.old<br />
ln -s $HOME/zenoss/core/Products Products</code></li>
<li>Return to Eclipse and choose the <em>Refresh</em> option from the File menu so that Eclipse notices the updated directory and builds necessary dependencies.</li>
<li>Secondary-click on the core project folder in Eclipse and choose <em>Properties</em>. Choose the <em>PyDev &#8211; PYTHONPATH</em> item and add source folders so PyDev can reference the project from within itself.
<ol>
<li>In the Source Folders tab choose the <em>Add source folder</em> button and pick the root <code>core</code> folder from the provided list.<a rel="attachment wp-att-532" href="http://blog.nuclearbunny.org/2009/10/22/my-zenoss-development-environment-part-2/picture-2/"><img class="aligncenter size-full wp-image-532" title="Picture 2" src="http://blog.nuclearbunny.org/wp-content/uploads/2009/10/Picture-2.png" alt="Picture 2" width="860" height="617" /></a></li>
<li>In the External Libraries tab choose the <em>Add source folder</em> button and choose the <code>$ZENHOME/lib/python</code> directory.<a rel="attachment wp-att-533" href="http://blog.nuclearbunny.org/2009/10/22/my-zenoss-development-environment-part-2/picture-3/"><img class="aligncenter size-full wp-image-533" title="Picture 3" src="http://blog.nuclearbunny.org/wp-content/uploads/2009/10/Picture-3.png" alt="Picture 3" width="860" height="617" /></a></li>
</ol>
</li>
</ol>
<p>At this point, your Eclipse project should allow you to navigate between dependencies within the Zenoss project. You can also simultaneously switch between using the Team feature within Eclipse to update and manage Subversion or do so using the command-line svn client.</p>
<h2>Next&#8230;</h2>
<p>In <a href="http://blog.nuclearbunny.org/2009/10/22/my-zenoss-development-environment-part-3/" target="_blank">Part 3</a> of this series, we&#8217;ll discuss how to manage day-to-day activities such as creating sandbox branches for changes and dealing with multiple versions are done from within the same environment.</li>
</ol>

<div class="sociable">
<div class="sociable_tagline">
<strong>Share and Enjoy:</strong>
</div>
<ul>
	<li class="sociablefirst"><a rel="nofollow"  href="http://digg.com/submit?phase=2&amp;url=http%3A%2F%2Fblog.nuclearbunny.org%2F2009%2F10%2F22%2Fmy-zenoss-development-environment-part-2%2F&amp;title=My%20Zenoss%20Development%20Environment%20-%20Part%202&amp;bodytext=In%20Part%201%20of%20this%20series%20we%20discussed%20getting%20an%20initial%20Zenoss%20environment%20checked%20out%20and%20running%20on%20a%20Mac%20OS%20X%20or%20Ubuntu%20system.%20In%20this%20part%2C%20we%27ll%20discuss%20configuring%20Eclipse%20to%20use%20this%20environment.%0D%0AMac%20OS%20X%20Prerequisites%0D%0A%0D%0A%09Install%20Eclipse%20C" title="Digg"><img src="http://blog.nuclearbunny.org/wp-content/plugins/sociable/images/digg.png" title="Digg" alt="Digg" class="sociable-hovers" /></a></li>
	<li><a rel="nofollow"  href="http://www.stumbleupon.com/submit?url=http%3A%2F%2Fblog.nuclearbunny.org%2F2009%2F10%2F22%2Fmy-zenoss-development-environment-part-2%2F&amp;title=My%20Zenoss%20Development%20Environment%20-%20Part%202" title="StumbleUpon"><img src="http://blog.nuclearbunny.org/wp-content/plugins/sociable/images/stumbleupon.png" title="StumbleUpon" alt="StumbleUpon" class="sociable-hovers" /></a></li>
	<li><a rel="nofollow"  href="http://delicious.com/post?url=http%3A%2F%2Fblog.nuclearbunny.org%2F2009%2F10%2F22%2Fmy-zenoss-development-environment-part-2%2F&amp;title=My%20Zenoss%20Development%20Environment%20-%20Part%202&amp;notes=In%20Part%201%20of%20this%20series%20we%20discussed%20getting%20an%20initial%20Zenoss%20environment%20checked%20out%20and%20running%20on%20a%20Mac%20OS%20X%20or%20Ubuntu%20system.%20In%20this%20part%2C%20we%27ll%20discuss%20configuring%20Eclipse%20to%20use%20this%20environment.%0D%0AMac%20OS%20X%20Prerequisites%0D%0A%0D%0A%09Install%20Eclipse%20C" title="del.icio.us"><img src="http://blog.nuclearbunny.org/wp-content/plugins/sociable/images/delicious.png" title="del.icio.us" alt="del.icio.us" class="sociable-hovers" /></a></li>
	<li><a rel="nofollow"  href="http://www.google.com/bookmarks/mark?op=edit&amp;bkmk=http%3A%2F%2Fblog.nuclearbunny.org%2F2009%2F10%2F22%2Fmy-zenoss-development-environment-part-2%2F&amp;title=My%20Zenoss%20Development%20Environment%20-%20Part%202&amp;annotation=In%20Part%201%20of%20this%20series%20we%20discussed%20getting%20an%20initial%20Zenoss%20environment%20checked%20out%20and%20running%20on%20a%20Mac%20OS%20X%20or%20Ubuntu%20system.%20In%20this%20part%2C%20we%27ll%20discuss%20configuring%20Eclipse%20to%20use%20this%20environment.%0D%0AMac%20OS%20X%20Prerequisites%0D%0A%0D%0A%09Install%20Eclipse%20C" title="Google Bookmarks"><img src="http://blog.nuclearbunny.org/wp-content/plugins/sociable/images/googlebookmark.png" title="Google Bookmarks" alt="Google Bookmarks" class="sociable-hovers" /></a></li>
	<li class="sociablelast"><a rel="nofollow"  href="http://www.facebook.com/share.php?u=http%3A%2F%2Fblog.nuclearbunny.org%2F2009%2F10%2F22%2Fmy-zenoss-development-environment-part-2%2F&amp;t=My%20Zenoss%20Development%20Environment%20-%20Part%202" title="Facebook"><img src="http://blog.nuclearbunny.org/wp-content/plugins/sociable/images/facebook.png" title="Facebook" alt="Facebook" class="sociable-hovers" /></a></li>
</ul>
</div>
]]></content:encoded>
			<wfw:commentRss>http://blog.nuclearbunny.org/2009/10/22/my-zenoss-development-environment-part-2/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>My Zenoss Development Environment &#8211; Part 1</title>
		<link>http://blog.nuclearbunny.org/2009/10/22/my-zenoss-development-environment-part-1/</link>
		<comments>http://blog.nuclearbunny.org/2009/10/22/my-zenoss-development-environment-part-1/#comments</comments>
		<pubDate>Thu, 22 Oct 2009 17:05:46 +0000</pubDate>
		<dc:creator>chadwick</dc:creator>
				<category><![CDATA[Jobs]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Zenoss]]></category>
		<category><![CDATA[eclipse]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[work]]></category>

		<guid isPermaLink="false">http://blog.nuclearbunny.org/?p=469</guid>
		<description><![CDATA[Over the past 18 months the developers at Zenoss have used a variety of development environments and methods to productively work with Zenoss, but there are a lot of best practices that have emerged out of this diversity. I develop Zenoss primarily on Mac OS X, with some work done on Ubuntu when necessary. I [...]]]></description>
			<content:encoded><![CDATA[<p>Over the past 18 months the developers at <a href="http://www.zenoss.com/" target="_blank">Zenoss</a> have used a variety of development environments and methods to productively work with Zenoss, but there are a lot of best practices that have emerged out of this diversity.</p>
<p>I develop Zenoss primarily on <a href="http://www.apple.com/macosx/" target="_blank">Mac OS X</a>, with some work done on <a href="http://www.ubuntu.com/" target="_blank">Ubuntu</a> when necessary. I normally use <a href="http://www.eclipse.org/" target="_blank">Eclipse</a> as my development editor, although I&#8217;ll often just use <a href="http://www.vim.org/" target="_blank">vim</a> when doing quick changes or bug fixes. In either case, careful setup of the Zenoss environment is key to being able to productively work with both the new development version and with the shipping versions that require maintenance.</p>
<p>The environment you get by default when you check out the source version of Zenoss from the source repository, or from a source tarball, is not necessarily setup in the best way to develop productively using tools like Eclipse.</p>
<p>The rest of this post will document how both my Mac OS X and Ubuntu environments are initially configured so that a working source Zenoss installation is realized.</p>
<h2>Mac OS X Prerequisites</h2>
<p>These prerequisite instructions assume Mac OS X 10.5 Leopard; 10.6 Snow Leopard will not be able to compile Zenoss&#8217;s third-party dependencies, so an additional work-around is required for that platform until Zenoss moves to <a href="http://www.python.org/download/releases/2.6/" target="_blank">Python 2.6</a>.</p>
<ol>
<li>Install <a href="http://developer.apple.com/technology/xcode.html" target="_blank">Xcode</a>. <strong>Why?</strong> Installs the GNU C/C++ compiler and other command-line development tools needed to build dependencies used by Zenoss.</li>
<li>Install <a href="http://www.open.collab.net/downloads/community/" target="_blank">Universal Subversion 1.6.x from CollabNet Community</a>.<strong>Why?</strong> Leopard only comes with Subversion 1.4.x. This version is not compatible with the Subclipse plug-in for Eclipse that will be used later. In order to be able to use both the command-line and Eclipse Subversion versions simultaneously on the same checked our source, the release of subversion should match. This installation will place the Subversion binaries in <code>/opt/subversion</code> and should automatically add it to your <code>PATH</code>.</li>
<li> Install <a href="http://dev.mysql.com/downloads/" target="_blank">MySQL Community Edition 5.1 32-bit</a>. <strong>Why?</strong> Zenoss needs MySQL for storage of event data.</li>
</ol>
<h2>Ubuntu Prerequisites</h2>
<p>These prerequisite instructions assume Ubuntu 9.04 32-bit Desktop Edition. Installing the server edition or one with different options may require additional prerequisites to be installed.</p>
<ol>
<li>Install Subversion. <strong>Why?</strong> Working with the Zenoss product in source form requires Subversion to access the source repositories (it is also possible to build directly from a source tarball, but this is not discussed here).<br />
<code>sudo apt-get -y install subversion<br />
</code></li>
<li>Install MySQL. <strong>Why?</strong> Zenoss needs MySQL for storage of event data.<br />
<code>sudo apt-get -y install mysql-client mysql-server libmysqlclient15-dev<br />
</code></li>
<li>Install additional development environment tools. <strong>Why?</strong> Zenoss third-party dependencies require several binaries to be built from source.<br />
<code>sudo apt-get -y install patch make vim gcc g++ autoconf</code></li>
<li>Install SNMP support. <strong>Why</strong>? Zenoss requires SNMP libraries for monitoring, and having a local SNMP agent is useful for testing.<code><br />
sudo apt-get -y install libsnmp-base snmp snmpd</code></li>
<li>Install Liberation TrueType fonts. <strong>Why?</strong> Graphs generated by RRDtool will not contain the correct glyphs without this font package.<code><br />
sudo apt-get -y install ttf-liberation</code></li>
</ol>
<h2>Environment Configuration</h2>
<p>Configuring Eclipse will require determining where you want to work with your Zenoss installation, and installing Eclipse plug-ins to provide the features required for Python and Subversion support.</p>
<ol>
<li>Create your Zenoss root directory:<code><br />
mkdir $HOME/zenoss<br />
</code></li>
<li>Create and run a <code>setup.sh</code> script that will configure needed environment variables for zenoss. This script can be started from your log in profile if desired.<code><br />
cd $HOME/zenoss<br />
cat &gt; zenoss-config.sh &lt;&lt;EOF<br />
ZENHOME=$HOME/zenoss/zenhome<br />
PYTHONPATH=$ZENHOME/lib/python<br />
PATH=\$ZENHOME/bin:\$PATH<br />
export ZENHOME PYTHONPATH PATH<br />
EOF<br />
chmod +x zenoss-config.sh<br />
. zenoss-config.sh<br />
mkdir $ZENHOME<br />
</code></li>
<li>Checkout the Zenoss source installation tree. <strong>Why?</strong> This tree is used to bootstrap the installation from the source repository and create a running Zenoss installation. We&#8217;ll need this before we modify it to fit the needs of our development environment.<code><br />
svn co http://dev.zenoss.org/svn/trunk/inst inst<br />
</code></li>
<li>Run the installation script to checkout, compile, and configure a zenoss environment. If you need to customize your MySQL configuration at all do not use the <code>--no-prompt</code> argument.<code><br />
cd inst<br />
./install.sh --no-prompt<br />
</code></li>
<li>Modify the <code>zensocket</code> file to be setuid root. <strong>Why?</strong> Some of the Zenoss daemons use a privileged port and making the file owned by root and accessible by the Zenoss user allows the daemons to be run as a non-priviledged user but still use the privileged port.<code><br />
sudo chown root:`id -g` $ZENHOME/bin/zensocket<br />
sudo chmod 04750 $ZENHOME/bin/zensocket<br />
</code></li>
</ol>
<p>At this point, you should have running zeo and zope processes and be able to log on to the local Zenoss instance. Your Zenoss root directory should look similar to the following:<br />
<a rel="attachment wp-att-491" href="http://blog.nuclearbunny.org/2009/10/22/my-zenoss-development-environment-part-1/picture-4/"><img class="aligncenter size-full wp-image-491" title="zenoss workspace" src="http://blog.nuclearbunny.org/wp-content/uploads/2009/10/Picture-4.png" alt="zenoss workspace" width="492" height="393" /></a></p>
<h2>Next&#8230;</h2>
<p>In <a title="Part 2" href="http://blog.nuclearbunny.org/2009/10/22/my-zenoss-development-environment-part-2/" target="_self">Part 2</a> of this series, we&#8217;ll download and configure the Eclipse IDE.</p>

<div class="sociable">
<div class="sociable_tagline">
<strong>Share and Enjoy:</strong>
</div>
<ul>
	<li class="sociablefirst"><a rel="nofollow"  href="http://digg.com/submit?phase=2&amp;url=http%3A%2F%2Fblog.nuclearbunny.org%2F2009%2F10%2F22%2Fmy-zenoss-development-environment-part-1%2F&amp;title=My%20Zenoss%20Development%20Environment%20-%20Part%201&amp;bodytext=Over%20the%20past%2018%20months%20the%20developers%20at%20Zenoss%20have%20used%20a%20variety%20of%20development%20environments%20and%20methods%20to%20productively%20work%20with%20Zenoss%2C%20but%20there%20are%20a%20lot%20of%20best%20practices%20that%20have%20emerged%20out%20of%20this%20diversity.%0D%0A%0D%0AI%20develop%20Zenoss%20primaril" title="Digg"><img src="http://blog.nuclearbunny.org/wp-content/plugins/sociable/images/digg.png" title="Digg" alt="Digg" class="sociable-hovers" /></a></li>
	<li><a rel="nofollow"  href="http://www.stumbleupon.com/submit?url=http%3A%2F%2Fblog.nuclearbunny.org%2F2009%2F10%2F22%2Fmy-zenoss-development-environment-part-1%2F&amp;title=My%20Zenoss%20Development%20Environment%20-%20Part%201" title="StumbleUpon"><img src="http://blog.nuclearbunny.org/wp-content/plugins/sociable/images/stumbleupon.png" title="StumbleUpon" alt="StumbleUpon" class="sociable-hovers" /></a></li>
	<li><a rel="nofollow"  href="http://delicious.com/post?url=http%3A%2F%2Fblog.nuclearbunny.org%2F2009%2F10%2F22%2Fmy-zenoss-development-environment-part-1%2F&amp;title=My%20Zenoss%20Development%20Environment%20-%20Part%201&amp;notes=Over%20the%20past%2018%20months%20the%20developers%20at%20Zenoss%20have%20used%20a%20variety%20of%20development%20environments%20and%20methods%20to%20productively%20work%20with%20Zenoss%2C%20but%20there%20are%20a%20lot%20of%20best%20practices%20that%20have%20emerged%20out%20of%20this%20diversity.%0D%0A%0D%0AI%20develop%20Zenoss%20primaril" title="del.icio.us"><img src="http://blog.nuclearbunny.org/wp-content/plugins/sociable/images/delicious.png" title="del.icio.us" alt="del.icio.us" class="sociable-hovers" /></a></li>
	<li><a rel="nofollow"  href="http://www.google.com/bookmarks/mark?op=edit&amp;bkmk=http%3A%2F%2Fblog.nuclearbunny.org%2F2009%2F10%2F22%2Fmy-zenoss-development-environment-part-1%2F&amp;title=My%20Zenoss%20Development%20Environment%20-%20Part%201&amp;annotation=Over%20the%20past%2018%20months%20the%20developers%20at%20Zenoss%20have%20used%20a%20variety%20of%20development%20environments%20and%20methods%20to%20productively%20work%20with%20Zenoss%2C%20but%20there%20are%20a%20lot%20of%20best%20practices%20that%20have%20emerged%20out%20of%20this%20diversity.%0D%0A%0D%0AI%20develop%20Zenoss%20primaril" title="Google Bookmarks"><img src="http://blog.nuclearbunny.org/wp-content/plugins/sociable/images/googlebookmark.png" title="Google Bookmarks" alt="Google Bookmarks" class="sociable-hovers" /></a></li>
	<li class="sociablelast"><a rel="nofollow"  href="http://www.facebook.com/share.php?u=http%3A%2F%2Fblog.nuclearbunny.org%2F2009%2F10%2F22%2Fmy-zenoss-development-environment-part-1%2F&amp;t=My%20Zenoss%20Development%20Environment%20-%20Part%201" title="Facebook"><img src="http://blog.nuclearbunny.org/wp-content/plugins/sociable/images/facebook.png" title="Facebook" alt="Facebook" class="sociable-hovers" /></a></li>
</ul>
</div>
]]></content:encoded>
			<wfw:commentRss>http://blog.nuclearbunny.org/2009/10/22/my-zenoss-development-environment-part-1/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Why is my car&#8217;s satellite navigation system so stupid?</title>
		<link>http://blog.nuclearbunny.org/2009/09/18/why-is-my-cars-satellite-navigation-system-so-stupid/</link>
		<comments>http://blog.nuclearbunny.org/2009/09/18/why-is-my-cars-satellite-navigation-system-so-stupid/#comments</comments>
		<pubDate>Fri, 18 Sep 2009 23:57:27 +0000</pubDate>
		<dc:creator>chadwick</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[Cars]]></category>
		<category><![CDATA[gps]]></category>
		<category><![CDATA[lame]]></category>
		<category><![CDATA[rant]]></category>

		<guid isPermaLink="false">http://blog.nuclearbunny.org/?p=474</guid>
		<description><![CDATA[I have two different late model (a 2006 and a 2007) GM vehicles with satellite navigation systems. Both are manufactured for GM by Denso, although they clearly have different implementations and features. The one thing they both share, however, is blatant stupidity when calculating routes. I travel quite a bit between Houston and Austin and [...]]]></description>
			<content:encoded><![CDATA[<p>I have two different late model (a 2006 and a 2007) GM vehicles with satellite navigation systems. Both are manufactured for GM by Denso, although they clearly have different implementations and features. The one thing they both share, however, is blatant stupidity when calculating routes.</p>
<p>I travel quite a bit between Houston and Austin and there are really only three reasonable ways to go: US-290; I-10 &amp; TX-71; or I-10 &amp; TX-183. Over the years my preference has moved from US-290 to I-10 &amp; TX-71 as traffic along US-290 has increased on the eastern fridges of the Austin area, but the distance and time between the two is very similar and really it depends upon where in Austin you might be headed.</p>
<p><img class="alignright" style="border: 1px solid black; margin: 2px;" title="GM GPS Route" src="http://farm3.static.flickr.com/2622/3913527957_5875c4fbf4.jpg" alt="" width="300" height="225" /></p>
<p>The GPS systems in my cars have three route options when you pick a destination: fastest, shortest and other. In both cars, the route displayed is none of the above three, but instead a long, out-of-the-way route of I-10 to Seguin before heading north on TX-123 to San Marcos, and then heading into Austin on I-35. This option is a whopping 222 miles with an estimated travel time of 3 hours and 39 minutes.</p>
<p>Now, the fastest route is usually not the shortest. Route calculations are supposed to take into account the actual speeds of the road segments involved, and since interstate highways are almost always faster than anything else, there is a natural preference to these roads. In this case, however, the calculation is way off. Taking I-10 to US-71 (via US-59 &amp; TX-8 inside of Houston for those familiar with the area) is only 166 miles and estimated to take 3 hours 29 minutes according to Google. Likewise, taking US-290 is only 168 miles and estimated to take 3 hours 22 minutes.</p>
<p>Of course these time estimates are usually worst case scenario. Driving a few miles per hour over the speed limit I often make my trip in 2 hours and 30 minutes; worst case has been 3 hours and 10 minutes when driving 55 as an experiment (a painful one at that).</p>
<p>What about the shortest route option in the GPS system? That does actually route you onto I-10 &amp; US-71 in this example, but the shortest route calculations are always incredibly stupid, too. They will often take you onto side streets for half a mile or less just to maintain the shortest possible distance. Once, when driving through Memphis, TN, the GM GPS took us on and off the interstate highway three times when driving through town, often for just a couple of blocks, just to maintain the shortest distance. Granted this is a clear example of a GPS system not being there to replace your own intelligence, but if you don&#8217;t know the town&#8230;</p>
<p>In the early days of consumer-level GPS systems, one of the common problems was having accurate speed data for different road segments. In western states especially, secondary highways often have the same speed limits as interstate highways. In Texas, the past 20 years has seen many of these highways improved so they route around the smaller towns, rather than going through them and stopping at every light. Consequently it is often better to take these roads than the interstates whenever possible. If the GM GPS systems do not have accurate speed data then it can account for some of this behavior, but not all.</p>
<p>On my normal route, once you finally hit TX-71 and the GPS decides you mean it, suddenly the estimated arrival time drops dramatically along with the distance. Is it computing this arrival time based upon your actual speed so far, or based upon the speed data of the road?</p>
<p>Over the years I&#8217;ve gone from absolutely wanting a satnav system in the car to wishing mine didn&#8217;t. I get much better results using a smart phone with Google Maps to get a general idea of the route to take and then consulting with it now and then if things get tricky. But for the most part, they seem poorly done enough that they just get in the way rather than help. Will the newer generations out now that provide real-time traffic data and have hard-disk based data improve their logic and performance enough that these problems are solved?</p>
<p>One final note for embedded systems developers: you don&#8217;t get to break the interactive response time rule of 250ms just because you are writing code for an embedded system.</p>

<div class="sociable">
<div class="sociable_tagline">
<strong>Share and Enjoy:</strong>
</div>
<ul>
	<li class="sociablefirst"><a rel="nofollow"  href="http://digg.com/submit?phase=2&amp;url=http%3A%2F%2Fblog.nuclearbunny.org%2F2009%2F09%2F18%2Fwhy-is-my-cars-satellite-navigation-system-so-stupid%2F&amp;title=Why%20is%20my%20car%27s%20satellite%20navigation%20system%20so%20stupid%3F&amp;bodytext=I%20have%20two%20different%20late%20model%20%28a%202006%20and%20a%202007%29%20GM%20vehicles%20with%20satellite%20navigation%20systems.%20Both%20are%20manufactured%20for%20GM%20by%20Denso%2C%20although%20they%20clearly%20have%20different%20implementations%20and%20features.%20The%20one%20thing%20they%20both%20share%2C%20however%2C%20is%20bl" title="Digg"><img src="http://blog.nuclearbunny.org/wp-content/plugins/sociable/images/digg.png" title="Digg" alt="Digg" class="sociable-hovers" /></a></li>
	<li><a rel="nofollow"  href="http://www.stumbleupon.com/submit?url=http%3A%2F%2Fblog.nuclearbunny.org%2F2009%2F09%2F18%2Fwhy-is-my-cars-satellite-navigation-system-so-stupid%2F&amp;title=Why%20is%20my%20car%27s%20satellite%20navigation%20system%20so%20stupid%3F" title="StumbleUpon"><img src="http://blog.nuclearbunny.org/wp-content/plugins/sociable/images/stumbleupon.png" title="StumbleUpon" alt="StumbleUpon" class="sociable-hovers" /></a></li>
	<li><a rel="nofollow"  href="http://delicious.com/post?url=http%3A%2F%2Fblog.nuclearbunny.org%2F2009%2F09%2F18%2Fwhy-is-my-cars-satellite-navigation-system-so-stupid%2F&amp;title=Why%20is%20my%20car%27s%20satellite%20navigation%20system%20so%20stupid%3F&amp;notes=I%20have%20two%20different%20late%20model%20%28a%202006%20and%20a%202007%29%20GM%20vehicles%20with%20satellite%20navigation%20systems.%20Both%20are%20manufactured%20for%20GM%20by%20Denso%2C%20although%20they%20clearly%20have%20different%20implementations%20and%20features.%20The%20one%20thing%20they%20both%20share%2C%20however%2C%20is%20bl" title="del.icio.us"><img src="http://blog.nuclearbunny.org/wp-content/plugins/sociable/images/delicious.png" title="del.icio.us" alt="del.icio.us" class="sociable-hovers" /></a></li>
	<li><a rel="nofollow"  href="http://www.google.com/bookmarks/mark?op=edit&amp;bkmk=http%3A%2F%2Fblog.nuclearbunny.org%2F2009%2F09%2F18%2Fwhy-is-my-cars-satellite-navigation-system-so-stupid%2F&amp;title=Why%20is%20my%20car%27s%20satellite%20navigation%20system%20so%20stupid%3F&amp;annotation=I%20have%20two%20different%20late%20model%20%28a%202006%20and%20a%202007%29%20GM%20vehicles%20with%20satellite%20navigation%20systems.%20Both%20are%20manufactured%20for%20GM%20by%20Denso%2C%20although%20they%20clearly%20have%20different%20implementations%20and%20features.%20The%20one%20thing%20they%20both%20share%2C%20however%2C%20is%20bl" title="Google Bookmarks"><img src="http://blog.nuclearbunny.org/wp-content/plugins/sociable/images/googlebookmark.png" title="Google Bookmarks" alt="Google Bookmarks" class="sociable-hovers" /></a></li>
	<li class="sociablelast"><a rel="nofollow"  href="http://www.facebook.com/share.php?u=http%3A%2F%2Fblog.nuclearbunny.org%2F2009%2F09%2F18%2Fwhy-is-my-cars-satellite-navigation-system-so-stupid%2F&amp;t=Why%20is%20my%20car%27s%20satellite%20navigation%20system%20so%20stupid%3F" title="Facebook"><img src="http://blog.nuclearbunny.org/wp-content/plugins/sociable/images/facebook.png" title="Facebook" alt="Facebook" class="sociable-hovers" /></a></li>
</ul>
</div>
]]></content:encoded>
			<wfw:commentRss>http://blog.nuclearbunny.org/2009/09/18/why-is-my-cars-satellite-navigation-system-so-stupid/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>IcyBee needs a new maintainer</title>
		<link>http://blog.nuclearbunny.org/2009/09/03/icybee-needs-a-new-maintainer/</link>
		<comments>http://blog.nuclearbunny.org/2009/09/03/icybee-needs-a-new-maintainer/#comments</comments>
		<pubDate>Thu, 03 Sep 2009 23:16:05 +0000</pubDate>
		<dc:creator>chadwick</dc:creator>
				<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Technology]]></category>

		<guid isPermaLink="false">http://blog.nuclearbunny.org/?p=472</guid>
		<description><![CDATA[The IcyBee project is a client for the ICB chat network with a graphical user interface and written in the Java language for cross-platform portability. The current version of the software has several years of stability behind it and few user requests, but there is always more work to do. The project is currently hosted [...]]]></description>
			<content:encoded><![CDATA[<p>The <a href="http://www.nuclearbunny.org/icybee/" target="_blank">IcyBee project</a> is a client for the <a href="http://www.icb.net/" target="_blank">ICB chat network</a> with a graphical user interface and written in the Java language for cross-platform portability. The current version of the software has several years of stability behind it and few user requests, but there is always more work to do. The project is currently hosted on <a href="http://sourceforge.net/projects/icybee/" target="_blank">SourceForge</a> and all of the source is already available.</p>
<p>I&#8217;m looking for a maintainer that will take the reins of the project from me and give the project some much needed love as time and platforms march on. If interested, drop a comment on this post and we can discuss the possibility.</p>

<div class="sociable">
<div class="sociable_tagline">
<strong>Share and Enjoy:</strong>
</div>
<ul>
	<li class="sociablefirst"><a rel="nofollow"  href="http://digg.com/submit?phase=2&amp;url=http%3A%2F%2Fblog.nuclearbunny.org%2F2009%2F09%2F03%2Ficybee-needs-a-new-maintainer%2F&amp;title=IcyBee%20needs%20a%20new%20maintainer&amp;bodytext=The%20IcyBee%20project%20is%20a%20client%20for%20the%20ICB%20chat%20network%20with%20a%20graphical%20user%20interface%20and%20written%20in%20the%20Java%20language%20for%20cross-platform%20portability.%20The%20current%20version%20of%20the%20software%20has%20several%20years%20of%20stability%20behind%20it%20and%20few%20user%20request" title="Digg"><img src="http://blog.nuclearbunny.org/wp-content/plugins/sociable/images/digg.png" title="Digg" alt="Digg" class="sociable-hovers" /></a></li>
	<li><a rel="nofollow"  href="http://www.stumbleupon.com/submit?url=http%3A%2F%2Fblog.nuclearbunny.org%2F2009%2F09%2F03%2Ficybee-needs-a-new-maintainer%2F&amp;title=IcyBee%20needs%20a%20new%20maintainer" title="StumbleUpon"><img src="http://blog.nuclearbunny.org/wp-content/plugins/sociable/images/stumbleupon.png" title="StumbleUpon" alt="StumbleUpon" class="sociable-hovers" /></a></li>
	<li><a rel="nofollow"  href="http://delicious.com/post?url=http%3A%2F%2Fblog.nuclearbunny.org%2F2009%2F09%2F03%2Ficybee-needs-a-new-maintainer%2F&amp;title=IcyBee%20needs%20a%20new%20maintainer&amp;notes=The%20IcyBee%20project%20is%20a%20client%20for%20the%20ICB%20chat%20network%20with%20a%20graphical%20user%20interface%20and%20written%20in%20the%20Java%20language%20for%20cross-platform%20portability.%20The%20current%20version%20of%20the%20software%20has%20several%20years%20of%20stability%20behind%20it%20and%20few%20user%20request" title="del.icio.us"><img src="http://blog.nuclearbunny.org/wp-content/plugins/sociable/images/delicious.png" title="del.icio.us" alt="del.icio.us" class="sociable-hovers" /></a></li>
	<li><a rel="nofollow"  href="http://www.google.com/bookmarks/mark?op=edit&amp;bkmk=http%3A%2F%2Fblog.nuclearbunny.org%2F2009%2F09%2F03%2Ficybee-needs-a-new-maintainer%2F&amp;title=IcyBee%20needs%20a%20new%20maintainer&amp;annotation=The%20IcyBee%20project%20is%20a%20client%20for%20the%20ICB%20chat%20network%20with%20a%20graphical%20user%20interface%20and%20written%20in%20the%20Java%20language%20for%20cross-platform%20portability.%20The%20current%20version%20of%20the%20software%20has%20several%20years%20of%20stability%20behind%20it%20and%20few%20user%20request" title="Google Bookmarks"><img src="http://blog.nuclearbunny.org/wp-content/plugins/sociable/images/googlebookmark.png" title="Google Bookmarks" alt="Google Bookmarks" class="sociable-hovers" /></a></li>
	<li class="sociablelast"><a rel="nofollow"  href="http://www.facebook.com/share.php?u=http%3A%2F%2Fblog.nuclearbunny.org%2F2009%2F09%2F03%2Ficybee-needs-a-new-maintainer%2F&amp;t=IcyBee%20needs%20a%20new%20maintainer" title="Facebook"><img src="http://blog.nuclearbunny.org/wp-content/plugins/sociable/images/facebook.png" title="Facebook" alt="Facebook" class="sociable-hovers" /></a></li>
</ul>
</div>
]]></content:encoded>
			<wfw:commentRss>http://blog.nuclearbunny.org/2009/09/03/icybee-needs-a-new-maintainer/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Review: Garmin Forerunner 310XT</title>
		<link>http://blog.nuclearbunny.org/2009/08/23/review-garmin-forerunner-310xt/</link>
		<comments>http://blog.nuclearbunny.org/2009/08/23/review-garmin-forerunner-310xt/#comments</comments>
		<pubDate>Mon, 24 Aug 2009 04:33:27 +0000</pubDate>
		<dc:creator>chadwick</dc:creator>
				<category><![CDATA[Cycling]]></category>
		<category><![CDATA[Running]]></category>
		<category><![CDATA[Sports]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[gps]]></category>

		<guid isPermaLink="false">http://blog.nuclearbunny.org/?p=460</guid>
		<description><![CDATA[I recently purchased a Garmin Forerunner 310XT training device for use while running, cycling, and hopefully swimming. The Forerunner 310XT is a new device from Garmin, and their first multi-sport device that is waterproof and can be used for swimming, and thus triathlons. For the past several years I have been using a Polar S725X [...]]]></description>
			<content:encoded><![CDATA[<p><img class="alignright" style="border: 1px solid black; margin: 0.5em;" title="Garmin Forerunner 310XT" src="http://farm4.static.flickr.com/3663/3850263793_20ffeae36a.jpg" alt="" width="225" height="300" />I recently purchased a <a href="https://buy.garmin.com/shop/shop.do?pID=27335&amp;ra=true" target="_blank">Garmin Forerunner 310XT</a> training device for use while running, cycling, and hopefully swimming. The Forerunner 310XT is a new device from Garmin, and their first multi-sport device that is waterproof and can be used for swimming, and thus triathlons.</p>
<p>For the past several years I have been using a Polar S725X multi-sport training device for both running and cycling. The rest of this review will compare and contrast to the Polar device since that is what I am most familiar. I have not used other GPS-based training devices before, so comparisons with those are left as an exercise for the readers.</p>
<p>The 310XT uses GPS to calculate your location and speed. You can then upload your data via your computer to <a href="http://connect.garmin.com/" target="_blank">Garmin&#8217;s Connect website</a>, <a href="http://www.garmin.com/products/trainingcenter/" target="_blank">Garmin&#8217;s Training Center software</a>, or other third-party options. After uploading you can view a map of your route, categorize and describe your activity. With the Connect website, you can easily share your activity via variety of methods, and even export the route into <a href="http://earth.google.com/" target="_blank">Google Earth</a>.</p>
<p>Like most of Garmin&#8217;s training devices, you can pair the 310XT with a variety of other devices that communicate using the <a href="http://www.thisisant.com/ant/ant-in-sport" target="_self">ANT+ Sport</a> protocol. The 310XT will receive and record data from heart-rate monitors, bicycle speed &amp; cadence sensors, foot-pods, and even power meters such as the <a href="http://www.saris.com/" target="_blank">Saris PowerTap</a>. The collected data is then joined with your route data and transmitted along with it.</p>
<p><img class="alignleft" style="border: 1px solid black; margin: 0.5em;" title="GSC-10 Speed/Cadence sensor" src="http://farm3.static.flickr.com/2666/3851058724_09d59988ea.jpg" alt="" width="225" height="300" />The bicycle sensor option from Garmin is a combination speed &amp; cadence sensor that mounts on the rear chainstay. This design allows one sensor unit to have two separate magnets for both the crank and the rear wheel. Compared to the Polar solution, this is much cleaner and easier to mount than two separate sensor units. The Polar cadence sensor, especially, is difficult to mount on some of the modern carbon downtubes, so the Garmin solution is a welcome change.</p>
<p>The speed sensor augments the GPS data so that accurate speed is recorded even when GPS signal is not available or accurate.  Garmin also sells an optional foot pod sensor that accomplishes the same when running without GPS signal, such as inside on a treadmill. I haven&#8217;t used this sensor yet as where I have run has had great GPS reception thus far.</p>
<p>I used a foot pod sensor with my Polar to keep track of my speed and distance while running. The downside of this type of solution is the relative inaccuracy of the data. I&#8217;d often see 10 to 20% margin of error, even after calibrating the foot pod.</p>
<p>My concern with a GPS-based training device would be the accuracy of the signal, especially when running under under a lot of foliage. So far, the 310XT has proven itself more than capable in this regard, and much better than other GPS devices I have used in the past. Viewing the recorded route data I&#8217;ve found very little error in position so far, and only a little bit with elevation, even when running underneath trees and bridges.</p>
<p>Like all GPS devices, the 310XT must determine its position when it is powered on. If you start up the 310XT inside, or where there is poor GPS signal, it can take a very long time to determine initial position, if it all. This can be an annoyance when you&#8217;re ready to start your training and you don&#8217;t have a solid 3-dimensional fix yet. The 310XT lets you begin your timer and start your activity before it has GPS signal, but it can sometimes take surprisingly long to get that initial fix. Another disadvantage of not having a fix is you won&#8217;t have accurate local time until then, either.</p>
<p>The Garmin 310XT has a rechargeable battery, but battery life is only approximately 20 hours of usage. My Polar S725X, by comparison, has a watch-style battery that has lasted over 5 years. In practice, a rechargeable battery solution works great, but may present a problem on multi-day activities where there is no opportunity to recharge.</p>
<p>Transmitting the data from the training device to your computer is done via a USB dongle that uses the ANT protocol. Garmin provides drivers and software for both PCs running Windows and Macs running OS X. The Polar solution uses an infrared based receiver that is much more difficult to work with as it requires line of sight between the training device and the infrared receiver, and Polar does not provide a software option for Macs.</p>
<p>For most users, Garmin&#8217;s software solutions are stellar compared to Polar&#8217;s. The big win here is Garmin&#8217;s Connect website which allows you to easily view your data online, share it with friends, and upload your data from a variety of different computers. <a href="http://connect.garmin.com/activity/11656145" target="_blank">Sharing your data</a> is trivial, and allows your friends to view your routes, as well as being able to search for routes from others near you. The Connect website represents a modern solution for the social Internet, a great solution for most users.</p>
<p>Where the Polar software shines is for advanced heart-rate based training, especially with coaching assistance. Polar&#8217;s software is designed to easily share your data with a coach and receive training programs with them. Additionally, both the software and the Polar device have much more advanced features for heart-rate based training. For example, with the Polar I can run several tests to determine if I am over-training, or even what an estimate of my current VO2max. The Garmin solution only has different heart rate zones, more than adequate for most users, but you do get the impression the Polar has more science behind it.</p>
<p>The 310XT supports multiple bike settings, each with its own odometer. I find this feature in particular compelling as I like to keep track of my mileage for each bike separately, and as far as I could tell the Polar S725X always combined bike mileage for all bikes it had configured, rather than a separate odometer for each one. With the GPS based tracking, you don&#8217;t even necessarily need a speed/cadence sensor and you can still keep track of your bike&#8217;s mileage. This is especially compelling for mountain biking, where the rough trails often render a traditional bike computer useless.</p>
<p>So far, the Garmin Forerunner 310XT has been a fantastic training tool and I haven&#8217;t missed using the Polar S725X yet.</p>

<div class="sociable">
<div class="sociable_tagline">
<strong>Share and Enjoy:</strong>
</div>
<ul>
	<li class="sociablefirst"><a rel="nofollow"  href="http://digg.com/submit?phase=2&amp;url=http%3A%2F%2Fblog.nuclearbunny.org%2F2009%2F08%2F23%2Freview-garmin-forerunner-310xt%2F&amp;title=Review%3A%20Garmin%20Forerunner%20310XT&amp;bodytext=I%20recently%20purchased%20a%20Garmin%20Forerunner%20310XT%20training%20device%20for%20use%20while%20running%2C%20cycling%2C%20and%20hopefully%20swimming.%20The%20Forerunner%20310XT%20is%20a%20new%20device%20from%20Garmin%2C%20and%20their%20first%20multi-sport%20device%20that%20is%20waterproof%20and%20can%20be%20used%20for%20swimmin" title="Digg"><img src="http://blog.nuclearbunny.org/wp-content/plugins/sociable/images/digg.png" title="Digg" alt="Digg" class="sociable-hovers" /></a></li>
	<li><a rel="nofollow"  href="http://www.stumbleupon.com/submit?url=http%3A%2F%2Fblog.nuclearbunny.org%2F2009%2F08%2F23%2Freview-garmin-forerunner-310xt%2F&amp;title=Review%3A%20Garmin%20Forerunner%20310XT" title="StumbleUpon"><img src="http://blog.nuclearbunny.org/wp-content/plugins/sociable/images/stumbleupon.png" title="StumbleUpon" alt="StumbleUpon" class="sociable-hovers" /></a></li>
	<li><a rel="nofollow"  href="http://delicious.com/post?url=http%3A%2F%2Fblog.nuclearbunny.org%2F2009%2F08%2F23%2Freview-garmin-forerunner-310xt%2F&amp;title=Review%3A%20Garmin%20Forerunner%20310XT&amp;notes=I%20recently%20purchased%20a%20Garmin%20Forerunner%20310XT%20training%20device%20for%20use%20while%20running%2C%20cycling%2C%20and%20hopefully%20swimming.%20The%20Forerunner%20310XT%20is%20a%20new%20device%20from%20Garmin%2C%20and%20their%20first%20multi-sport%20device%20that%20is%20waterproof%20and%20can%20be%20used%20for%20swimmin" title="del.icio.us"><img src="http://blog.nuclearbunny.org/wp-content/plugins/sociable/images/delicious.png" title="del.icio.us" alt="del.icio.us" class="sociable-hovers" /></a></li>
	<li><a rel="nofollow"  href="http://www.google.com/bookmarks/mark?op=edit&amp;bkmk=http%3A%2F%2Fblog.nuclearbunny.org%2F2009%2F08%2F23%2Freview-garmin-forerunner-310xt%2F&amp;title=Review%3A%20Garmin%20Forerunner%20310XT&amp;annotation=I%20recently%20purchased%20a%20Garmin%20Forerunner%20310XT%20training%20device%20for%20use%20while%20running%2C%20cycling%2C%20and%20hopefully%20swimming.%20The%20Forerunner%20310XT%20is%20a%20new%20device%20from%20Garmin%2C%20and%20their%20first%20multi-sport%20device%20that%20is%20waterproof%20and%20can%20be%20used%20for%20swimmin" title="Google Bookmarks"><img src="http://blog.nuclearbunny.org/wp-content/plugins/sociable/images/googlebookmark.png" title="Google Bookmarks" alt="Google Bookmarks" class="sociable-hovers" /></a></li>
	<li class="sociablelast"><a rel="nofollow"  href="http://www.facebook.com/share.php?u=http%3A%2F%2Fblog.nuclearbunny.org%2F2009%2F08%2F23%2Freview-garmin-forerunner-310xt%2F&amp;t=Review%3A%20Garmin%20Forerunner%20310XT" title="Facebook"><img src="http://blog.nuclearbunny.org/wp-content/plugins/sociable/images/facebook.png" title="Facebook" alt="Facebook" class="sociable-hovers" /></a></li>
</ul>
</div>
]]></content:encoded>
			<wfw:commentRss>http://blog.nuclearbunny.org/2009/08/23/review-garmin-forerunner-310xt/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Connecting to Apple Push Notification Services using Python &amp; Twisted</title>
		<link>http://blog.nuclearbunny.org/2009/05/11/connecting-to-apple-push-notification-services-using-python-twisted/</link>
		<comments>http://blog.nuclearbunny.org/2009/05/11/connecting-to-apple-push-notification-services-using-python-twisted/#comments</comments>
		<pubDate>Mon, 11 May 2009 15:34:01 +0000</pubDate>
		<dc:creator>chadwick</dc:creator>
				<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[apns]]></category>
		<category><![CDATA[cloud]]></category>
		<category><![CDATA[iphone]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[twisted]]></category>

		<guid isPermaLink="false">http://blog.nuclearbunny.org/?p=384</guid>
		<description><![CDATA[One of the exciting features of the upcoming iPhone 3.0 operating system is the ability for a device to receive a notification message from your own application that is relayed by Apple&#8217;s network cloud. This feature allows the iPhone to channel all out-of-band communication into a narrow channel that is low impact on the device [...]]]></description>
			<content:encoded><![CDATA[<p>One of the exciting features of the upcoming <a href="http://www.apple.com/iphone/preview-iphone-os/" target="_blank">iPhone 3.0</a> operating system is the ability for a device to receive a notification message from your own application that is relayed by Apple&#8217;s network cloud. This feature allows the iPhone to channel all out-of-band communication into a narrow channel that is low impact on the device from a power, security and usability point-of-view.</p>
<p>As an application developer, you are responsible for two pieces to make this new notification service work: the actual application that runs on the iPhone OS, and a provider service that both communicates with the device and directly to Apple&#8217;s cloud.</p>
<p>In a typical flow, the application on an iPhone device issues an API call to request notifications for the identifier that the developer has assigned to the application. In response to that API call, Apple&#8217;s servers provide the device with a binary token value that uniquely identifies the device &amp; installation combination (for security reasons, the device token is reset if the device is reset, so it is not a one-to-one mapping to the actual hardware). Next, the application must connect to the developer&#8217;s provider servers and provide it with the device token it has received from apple. The provider can now use the device token when communicating back to the <a href="http://developer.apple.com/iphone/program/sdk/apns.html" target="_blank">Apple Push Notification Service (APNS)</a> cloud.</p>
<p>A provider implementation has very little work to do to inform APNS of a device update. Most of the effort in a provider will be in the actual framework of the application itself, and managing what information should be sent to a device. A common implementation will be for a provider to both communicate with the APNS server cloud and also to the application&#8217;s own network services and effectively become a protocol translator. Such a heavily network based application like that is a perfect match for the <a href="http://www.python.org/" target="_blank">Python</a> language and the <a href="http://twistedmatrix.com/" target="_blank">Twisted</a> framework.</p>
<p>A provider to APNS link is very simple: a secure-socket connection (SSL) is made to a APNS server and then simple messages are sent by the provider whenever a notification needs to be sent to the device. The APNS server does not respond or acknowledge the message. Every so often (Apple recommends once an hour), the provider server should connect to a web server that will dump a list of device tokens that are no longer valid (as in the device has uninstalled the application). This is the provider&#8217;s only feedback mechanism outside of communicating directly with a device.</p>
<p>The first step is to setup an SSL connection to the APNS servers. By following the directions on Apple&#8217;s developer portal, you can create a certificate and private key that are assigned to your application identifier. This certificate &amp; private key must then be used when connecting to the APNS servers as an authentication mechanism.</p>
<p>One caveat  - the Mac OS X Keychain Access application does not directly export certificates and private keys in Private Enhanced Mail (.pem)  format, which is what the <a href="http://www.openssl.org/" target="_blank">OpenSSL</a> implementation we use with Twisted will want, but luckily there&#8217;s an easy mechanism to convert if you export the files as Personal Information Exchange (.p12) format. The following two commands can be used to convert the .p12 files into .pem files using the built-in openssl command on Mac OS X or most Linux distributions:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">openssl pkcs12 <span style="color: #660033;">-in</span> cred.p12 <span style="color: #660033;">-out</span> certkey.pem <span style="color: #660033;">-nodes</span> <span style="color: #660033;">-clcerts</span>
openssl pkcs12 <span style="color: #660033;">-in</span> pkey.p12 <span style="color: #660033;">-out</span> pkey.pem <span style="color: #660033;">-nodes</span> <span style="color: #660033;">-clcerts</span></pre></div></div>

<p>Now that we have our SSL files in the proper format, we can build our <code>ClientContextFactory</code> object that will be used by Twisted to initiate a connection to the APNS servers:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">class</span> APNSClientContextFactory<span style="color: black;">&#40;</span>ClientContextFactory<span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #008000;">self</span>.<span style="color: black;">ctx</span> = SSL.<span style="color: black;">Context</span><span style="color: black;">&#40;</span>SSL.<span style="color: black;">SSLv3_METHOD</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">ctx</span>.<span style="color: black;">use_certificate_file</span><span style="color: black;">&#40;</span>APNS_SSL_CERTIFICATE_FILE<span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">ctx</span>.<span style="color: black;">use_privatekey_file</span><span style="color: black;">&#40;</span>APNS_SSL_PRIVATE_KEY_FILE<span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> getContext<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">self</span>.<span style="color: black;">ctx</span></pre></div></div>

<p>We&#8217;ll also need a <code>ClientFactory</code> object that will be used to build the <code>Protocol</code> object whenever a connection is established to a server:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">class</span> APNSClientFactory<span style="color: black;">&#40;</span>ClientFactory<span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">def</span> buildProtocol<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, addr<span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;Connected to APNS Server %s:%u&quot;</span> <span style="color: #66cc66;">%</span> <span style="color: black;">&#40;</span>addr.<span style="color: black;">host</span>, addr.<span style="color: black;">port</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">return</span> APNSProtocol<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> clientConnectionLost<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, connector, reason<span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;Lost connection. Reason: %s&quot;</span> <span style="color: #66cc66;">%</span> reason
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> clientConnectionFailed<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, connector, reason<span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;Connection failed. Reason: %s&quot;</span> <span style="color: #66cc66;">%</span> reason</pre></div></div>

<p>Next, we&#8217;ll need the actual <code>Protocol</code> object that will format messages and queue them to the server. For APNS, we don&#8217;t receive any responses so that half of the protocol goes unused.</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">class</span> APNSProtocol<span style="color: black;">&#40;</span>Protocol<span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">def</span> sendMessage<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, deviceToken, payload<span style="color: black;">&#41;</span>:
        <span style="color: #808080; font-style: italic;"># notification messages are binary messages in network order</span>
        <span style="color: #808080; font-style: italic;"># using the following format:</span>
        <span style="color: #808080; font-style: italic;"># &amp;lt;1 byte command&amp;gt; &amp;lt;2 bytes length&amp;gt; &amp;lt;2 bytes length&amp;gt;</span>
&nbsp;
        fmt = <span style="color: #483d8b;">&quot;!cH32sH%ds&quot;</span> <span style="color: #66cc66;">%</span> <span style="color: #008000;">len</span><span style="color: black;">&#40;</span>payload<span style="color: black;">&#41;</span>
        command = <span style="color: #483d8b;">'<span style="color: #000099; font-weight: bold;">\x</span>00'</span>
        msg = <span style="color: #dc143c;">struct</span>.<span style="color: black;">pack</span><span style="color: black;">&#40;</span>fmt, command, <span style="color: #ff4500;">32</span>, deviceToken,
                          <span style="color: #008000;">len</span><span style="color: black;">&#40;</span>payload<span style="color: black;">&#41;</span>, payload<span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">transport</span>.<span style="color: black;">write</span><span style="color: black;">&#40;</span>msg<span style="color: black;">&#41;</span></pre></div></div>

<p>And finally, we&#8217;ll need the main code to kick everything off for the test:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">if</span> __name__ == <span style="color: #483d8b;">'__main__'</span>:
    reactor.<span style="color: black;">connectSSL</span><span style="color: black;">&#40;</span>APNS_SERVER_HOSTNAME,
                       APNS_SERVER_PORT,
                       APNSClientFactory<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>,
                       APNSClientContextFactory<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
    reactor.<span style="color: black;">run</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>From here, the Python and Twisted combination can be easily extended to handle multiple protocols and convert between them as needed. For example, one of the commonly expected use cases of the new push feature will be instant messaging (IM) clients that will need to provide a proxy between the device and the IM servers and the APNS servers in order to notify a device of outstanding messages.</p>
<p>The full Python script containing the above excerpts can be downloaded here:</p>
<p><a rel="attachment wp-att-455" href="http://blog.nuclearbunny.org/2009/05/11/connecting-to-apple-push-notification-services-using-python-twisted/test-apns-blog/">test-apns-blog</a></p>

<div class="sociable">
<div class="sociable_tagline">
<strong>Share and Enjoy:</strong>
</div>
<ul>
	<li class="sociablefirst"><a rel="nofollow"  href="http://digg.com/submit?phase=2&amp;url=http%3A%2F%2Fblog.nuclearbunny.org%2F2009%2F05%2F11%2Fconnecting-to-apple-push-notification-services-using-python-twisted%2F&amp;title=Connecting%20to%20Apple%20Push%20Notification%20Services%20using%20Python%20%26%20Twisted&amp;bodytext=One%20of%20the%20exciting%20features%20of%20the%20upcoming%20iPhone%203.0%20operating%20system%20is%20the%20ability%20for%20a%20device%20to%20receive%20a%20notification%20message%20from%20your%20own%20application%20that%20is%20relayed%20by%20Apple%27s%20network%20cloud.%20This%20feature%20allows%20the%20iPhone%20to%20channel%20all%20o" title="Digg"><img src="http://blog.nuclearbunny.org/wp-content/plugins/sociable/images/digg.png" title="Digg" alt="Digg" class="sociable-hovers" /></a></li>
	<li><a rel="nofollow"  href="http://www.stumbleupon.com/submit?url=http%3A%2F%2Fblog.nuclearbunny.org%2F2009%2F05%2F11%2Fconnecting-to-apple-push-notification-services-using-python-twisted%2F&amp;title=Connecting%20to%20Apple%20Push%20Notification%20Services%20using%20Python%20%26%20Twisted" title="StumbleUpon"><img src="http://blog.nuclearbunny.org/wp-content/plugins/sociable/images/stumbleupon.png" title="StumbleUpon" alt="StumbleUpon" class="sociable-hovers" /></a></li>
	<li><a rel="nofollow"  href="http://delicious.com/post?url=http%3A%2F%2Fblog.nuclearbunny.org%2F2009%2F05%2F11%2Fconnecting-to-apple-push-notification-services-using-python-twisted%2F&amp;title=Connecting%20to%20Apple%20Push%20Notification%20Services%20using%20Python%20%26%20Twisted&amp;notes=One%20of%20the%20exciting%20features%20of%20the%20upcoming%20iPhone%203.0%20operating%20system%20is%20the%20ability%20for%20a%20device%20to%20receive%20a%20notification%20message%20from%20your%20own%20application%20that%20is%20relayed%20by%20Apple%27s%20network%20cloud.%20This%20feature%20allows%20the%20iPhone%20to%20channel%20all%20o" title="del.icio.us"><img src="http://blog.nuclearbunny.org/wp-content/plugins/sociable/images/delicious.png" title="del.icio.us" alt="del.icio.us" class="sociable-hovers" /></a></li>
	<li><a rel="nofollow"  href="http://www.google.com/bookmarks/mark?op=edit&amp;bkmk=http%3A%2F%2Fblog.nuclearbunny.org%2F2009%2F05%2F11%2Fconnecting-to-apple-push-notification-services-using-python-twisted%2F&amp;title=Connecting%20to%20Apple%20Push%20Notification%20Services%20using%20Python%20%26%20Twisted&amp;annotation=One%20of%20the%20exciting%20features%20of%20the%20upcoming%20iPhone%203.0%20operating%20system%20is%20the%20ability%20for%20a%20device%20to%20receive%20a%20notification%20message%20from%20your%20own%20application%20that%20is%20relayed%20by%20Apple%27s%20network%20cloud.%20This%20feature%20allows%20the%20iPhone%20to%20channel%20all%20o" title="Google Bookmarks"><img src="http://blog.nuclearbunny.org/wp-content/plugins/sociable/images/googlebookmark.png" title="Google Bookmarks" alt="Google Bookmarks" class="sociable-hovers" /></a></li>
	<li class="sociablelast"><a rel="nofollow"  href="http://www.facebook.com/share.php?u=http%3A%2F%2Fblog.nuclearbunny.org%2F2009%2F05%2F11%2Fconnecting-to-apple-push-notification-services-using-python-twisted%2F&amp;t=Connecting%20to%20Apple%20Push%20Notification%20Services%20using%20Python%20%26%20Twisted" title="Facebook"><img src="http://blog.nuclearbunny.org/wp-content/plugins/sociable/images/facebook.png" title="Facebook" alt="Facebook" class="sociable-hovers" /></a></li>
</ul>
</div>
]]></content:encoded>
			<wfw:commentRss>http://blog.nuclearbunny.org/2009/05/11/connecting-to-apple-push-notification-services-using-python-twisted/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>iPod installation in the car</title>
		<link>http://blog.nuclearbunny.org/2009/05/03/ipod-installation-in-the-car/</link>
		<comments>http://blog.nuclearbunny.org/2009/05/03/ipod-installation-in-the-car/#comments</comments>
		<pubDate>Mon, 04 May 2009 04:16:33 +0000</pubDate>
		<dc:creator>chadwick</dc:creator>
				<category><![CDATA[Cars]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[corvette]]></category>
		<category><![CDATA[ipod]]></category>
		<category><![CDATA[music]]></category>

		<guid isPermaLink="false">http://blog.nuclearbunny.org/?p=362</guid>
		<description><![CDATA[Due to recent negative events with XM Radio&#8217;s customer service, I no longer have an XM subscription in any of my vehicles. In the truck there is an auxiliary input jack, so feeding music from an iPod is a no-brainer. But in the Corvette, there was no such option. GM never really provided a great [...]]]></description>
			<content:encoded><![CDATA[<p>Due to recent negative events with XM Radio&#8217;s customer service, I no longer have an XM subscription in any of my vehicles. In the truck there is an auxiliary input jack, so feeding music from an iPod is a no-brainer. But in the Corvette, there was no such option. GM never really provided a great solution for it, but luckily the aftermarket came to the rescue.</p>
<p>One of the better options is a device called the <a href="http://www.coastaletech.com/CORVETTEIPOD.htm" target="_blank">Lockpick</a> that intelligently interfaces with the various radio interfaces in GM vehicles. The Corvette Lockpick they provide interfaces directly with the navigation radio in all 6th generation Corvettes so I ordered it to try it out.</p>
<p>Installation turned out to be incredibly simple. The unit ties into the wiring harness that feeds the XM Radio brain. In the convertible model, the brain is hidden behind the waterfall, located between the seats. Removing the waterfall is straight-forward, and then you are left with a simple wire routing problem.</p>
<p>In the end, I decided to locate the Lockpick unit itself on the carpeted area behind the waterfall. I used sticky-tape velcro to keep the unit attached to the carpet, and then ran the wiring harness to the XM Radio unit in order to attach the Y-connector that feeds into the Lockpick itself. The wiring harness that connects to the iPod also has to be routed, and I decided in the end to locate the iPod in the glove box rather than the center console. Access to the center console would require some cutting for a clean installtion look, and plus it tends to get rather hot inside so I was worried about shortening the life of the iPod a bit too much to locate it there.</p>
<p>Luckily the glove box had a space for a switch that wasn&#8217;t installed with my option packages, so it made a perfect place to feed the wiring harness. From there, I routed the wiring harness into the dash and then underneath the center console and feed it directly to the waterfall area. The final result is a perfectly clean and hidden installation with no permanent modifications needed to the car.</p>
<p>The Lockpick unit itself works great, although the control system is a quirky. The lower right-hand button in the XM Radio menu activates the iPod. Once activated, the Category up and down buttons control your playlist selection, and then seek forward and back buttons control the current song playing within the playlist. The info button displays the song information as you would expect. It&#8217;s quirky, but works extremely well.</p>

<a href='http://blog.nuclearbunny.org/2009/05/03/ipod-installation-in-the-car/p4280003/' title='p4280003'><img width="150" height="112" src="http://blog.nuclearbunny.org/wp-content/uploads/2009/05/p4280003.jpg" class="attachment-thumbnail" alt="glovebox" title="p4280003" /></a>
<a href='http://blog.nuclearbunny.org/2009/05/03/ipod-installation-in-the-car/p4280004/' title='p4280004'><img width="150" height="112" src="http://blog.nuclearbunny.org/wp-content/uploads/2009/05/p4280004.jpg" class="attachment-thumbnail" alt="wiring routing" title="p4280004" /></a>
<a href='http://blog.nuclearbunny.org/2009/05/03/ipod-installation-in-the-car/p4280005/' title='p4280005'><img width="150" height="112" src="http://blog.nuclearbunny.org/wp-content/uploads/2009/05/p4280005.jpg" class="attachment-thumbnail" alt="wiring underneath the center console" title="p4280005" /></a>
<a href='http://blog.nuclearbunny.org/2009/05/03/ipod-installation-in-the-car/p4280008/' title='p4280008'><img width="150" height="112" src="http://blog.nuclearbunny.org/wp-content/uploads/2009/05/p4280008.jpg" class="attachment-thumbnail" alt="lockpick unit" title="p4280008" /></a>
<a href='http://blog.nuclearbunny.org/2009/05/03/ipod-installation-in-the-car/p4280009/' title='p4280009'><img width="150" height="112" src="http://blog.nuclearbunny.org/wp-content/uploads/2009/05/p4280009.jpg" class="attachment-thumbnail" alt="iPod glovebox" title="p4280009" /></a>


<div class="sociable">
<div class="sociable_tagline">
<strong>Share and Enjoy:</strong>
</div>
<ul>
	<li class="sociablefirst"><a rel="nofollow"  href="http://digg.com/submit?phase=2&amp;url=http%3A%2F%2Fblog.nuclearbunny.org%2F2009%2F05%2F03%2Fipod-installation-in-the-car%2F&amp;title=iPod%20installation%20in%20the%20car&amp;bodytext=Due%20to%20recent%20negative%20events%20with%20XM%20Radio%27s%20customer%20service%2C%20I%20no%20longer%20have%20an%20XM%20subscription%20in%20any%20of%20my%20vehicles.%20In%20the%20truck%20there%20is%20an%20auxiliary%20input%20jack%2C%20so%20feeding%20music%20from%20an%20iPod%20is%20a%20no-brainer.%20But%20in%20the%20Corvette%2C%20there%20was%20no" title="Digg"><img src="http://blog.nuclearbunny.org/wp-content/plugins/sociable/images/digg.png" title="Digg" alt="Digg" class="sociable-hovers" /></a></li>
	<li><a rel="nofollow"  href="http://www.stumbleupon.com/submit?url=http%3A%2F%2Fblog.nuclearbunny.org%2F2009%2F05%2F03%2Fipod-installation-in-the-car%2F&amp;title=iPod%20installation%20in%20the%20car" title="StumbleUpon"><img src="http://blog.nuclearbunny.org/wp-content/plugins/sociable/images/stumbleupon.png" title="StumbleUpon" alt="StumbleUpon" class="sociable-hovers" /></a></li>
	<li><a rel="nofollow"  href="http://delicious.com/post?url=http%3A%2F%2Fblog.nuclearbunny.org%2F2009%2F05%2F03%2Fipod-installation-in-the-car%2F&amp;title=iPod%20installation%20in%20the%20car&amp;notes=Due%20to%20recent%20negative%20events%20with%20XM%20Radio%27s%20customer%20service%2C%20I%20no%20longer%20have%20an%20XM%20subscription%20in%20any%20of%20my%20vehicles.%20In%20the%20truck%20there%20is%20an%20auxiliary%20input%20jack%2C%20so%20feeding%20music%20from%20an%20iPod%20is%20a%20no-brainer.%20But%20in%20the%20Corvette%2C%20there%20was%20no" title="del.icio.us"><img src="http://blog.nuclearbunny.org/wp-content/plugins/sociable/images/delicious.png" title="del.icio.us" alt="del.icio.us" class="sociable-hovers" /></a></li>
	<li><a rel="nofollow"  href="http://www.google.com/bookmarks/mark?op=edit&amp;bkmk=http%3A%2F%2Fblog.nuclearbunny.org%2F2009%2F05%2F03%2Fipod-installation-in-the-car%2F&amp;title=iPod%20installation%20in%20the%20car&amp;annotation=Due%20to%20recent%20negative%20events%20with%20XM%20Radio%27s%20customer%20service%2C%20I%20no%20longer%20have%20an%20XM%20subscription%20in%20any%20of%20my%20vehicles.%20In%20the%20truck%20there%20is%20an%20auxiliary%20input%20jack%2C%20so%20feeding%20music%20from%20an%20iPod%20is%20a%20no-brainer.%20But%20in%20the%20Corvette%2C%20there%20was%20no" title="Google Bookmarks"><img src="http://blog.nuclearbunny.org/wp-content/plugins/sociable/images/googlebookmark.png" title="Google Bookmarks" alt="Google Bookmarks" class="sociable-hovers" /></a></li>
	<li class="sociablelast"><a rel="nofollow"  href="http://www.facebook.com/share.php?u=http%3A%2F%2Fblog.nuclearbunny.org%2F2009%2F05%2F03%2Fipod-installation-in-the-car%2F&amp;t=iPod%20installation%20in%20the%20car" title="Facebook"><img src="http://blog.nuclearbunny.org/wp-content/plugins/sociable/images/facebook.png" title="Facebook" alt="Facebook" class="sociable-hovers" /></a></li>
</ul>
</div>
]]></content:encoded>
			<wfw:commentRss>http://blog.nuclearbunny.org/2009/05/03/ipod-installation-in-the-car/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
