<?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>Hi My Name is Peter Vieth</title>
	<atom:link href="http://petervieth.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://petervieth.com</link>
	<description>...and I build things</description>
	<lastBuildDate>Tue, 14 Feb 2012 07:59:56 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Workflow Engines and Android</title>
		<link>http://petervieth.com/2012/02/13/workflow-engines-and-android/</link>
		<comments>http://petervieth.com/2012/02/13/workflow-engines-and-android/#comments</comments>
		<pubDate>Tue, 14 Feb 2012 07:56:19 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Android]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[jBpm]]></category>
		<category><![CDATA[workflow]]></category>

		<guid isPermaLink="false">http://petervieth.com/?p=610</guid>
		<description><![CDATA[jBoss jBpm is a well established workflow engine. I tried running a minimal jBpmn engine on Android but found that unfortunately to do even basic tasks like loading a bpmn process definition file, jBpm has rather extensive dependencies on drools. Drools doesn&#8217;t work well on Android because it compiles bytecode at runtime which is incompatible <a href="http://petervieth.com/2012/02/13/workflow-engines-and-android/"> read more <span class="meta-nav">&#187;</span></a>]]></description>
			<content:encoded><![CDATA[<p>jBoss jBpm is a well established workflow engine. I tried running a minimal jBpmn engine on Android but found that unfortunately to do even basic tasks like loading a bpmn process definition file, jBpm has rather extensive dependencies on drools. Drools doesn&#8217;t work well on Android because it compiles bytecode at runtime which is incompatible with Android&#8217;s Dalvik bytecode. jBpm doesn&#8217;t need to load a process from a defintion file&#8211; you can create one with Java using the jBpm process api (also called fluent). The process api approach is pretty smooth, but defeats the point of workflow which is to leave business logic out of code and contain it in configuration files. JBoss also appears to have neglected the process api in the past year (more on this in a future post).</p>
<p>First, some background. I&#8217;ve been working with workflow engines since 2003 when I first used Sun&#8217;s Process Manager at Accelere, Inc. It&#8217;s a great idea&#8211; separate business logic from the actual implementation, in much the same way separation of presentation from code has become a standard idea for web development. But the Process Manager product was awful, and the quality of workflow engines hadn&#8217;t improve much by the time I left Accelere in 2008 (we used uEngine, which was immature at the time but quite reliable in our testing). JBoss was working on jBpm which looked promising, but was still quite klunky. I reviewed the state of ppen source workflow products recently and workflow engines are now much improved.</p>
<p>I checked out three workflow engines: jBpm v5.3, Activi, and worktoken. I started with jBpm because of my prior experience with it. Frankly, all three are very similar when you get down to usage. Processes are defined in bpmn files, which are fairly consistent nowadays. To use a process, the Java code generally follows the sequence:</p>
<ol>
<li>load a knowledge base/dictionary/whatever the product calls its process and rule repository</li>
<li>register with the knowledge base your java code which handles execution of custom nodes</li>
<li>create a session with that knowledge base</li>
<li>use the session object to start a process defined in the knowledge base</li>
</ol>
<p>Custom nodes implement an interface that requires some execute function (named differently in different workflow engines). An object is provided to access workflow state information. jBpm also defines mappings of process variables to custom node inputs and outputs and pre and post actions. This, I was to find later, is a big problem on Android.</p>
<p>The jBpm documentation (for v5.3) is very good. Read the first few chapters and you&#8217;ll be prepared to use any of these workflow engines, which is good because the documentation for the others is not so good.</p>
<p>Kris Verlaenen has an <a href="http://blog.athico.com/2011/03/jbpm5-lightweight-running-on-android.html">excellent, short blog post </a>on using jBpm on Android. I got it running but it uses the jBpm process API to define a process. I really need to be able to load from a bpmn file. How hard could that be?</p>
<p>About 30 hours later, I can say, it&#8217;s very hard.</p>
<p>I sort of knew what I was in for. Abhay Chaware has a <a href="http://tech-voyage.blogspot.com/2011/06/getting-rule-engine-to-work-on-mobile.html">blog post detailing the hurdles</a> he passed through to try and run drools on Android. I don&#8217;t need to use Drools, but as it turns out, it&#8217;s unavoidable.</p>
<p>First, note that just the code needed to load a bpmn file already causes a pretty hefty size and performance penalty for the resulting apk. So, if you need a minimally sized app, forget about it.</p>
<p>The crux of the problem is that the Dalvik VM on Android uses a different bytecode than Sun&#8217;s Java VM. Compiling in Eclipse doesn&#8217;t generate Dalvik bytecode&#8211; rather, part of the build process is to convert the Sun bytecode to Dalvik bytecode. The tool actually unpacks everything and converts it. This is a pretty heavy operation for Eclipse it seems, and it can take a while for the project to build, even on my i7 laptop. The problem with using Drools on Android is that Drools compiles code at runtime into the Sun format, so to run on Android we either need to prevent Drools compiling anything at runtime or ideally get Drools to compile to Dalvik bytecode. The latter is out of the scope of this effort, so I took a stab at the former.</p>
<p>Here are the steps:<br />
0a) Bump Eclipse max memory to at least 1gb.. It is possible to get Kris&#8217; example running with just 512 megs, but Eclipse kept crashing once I added any more jars to my project.<br />
0b) Remove any java code from the bpmn file. Set all dialects to MVEL.<br />
1) Add drools-compiler jar to project&#8230; copy file into lib then use Add Jar button in Eclipse (use add ext jar, after building once, it seems to allow you to use add jar&#8230; go figure)<br />
2) Error generating final archive: Found duplicate file for APK: build.properties<br />
The build process unpacks all the jars together, and when they contain files with identical names, the unpacking fails.<br />
Open up the jar files in lib in winrar and delete build.properties as its not needed<br />
3) Add jbpm-bpmn2.jar to be able to process bpmn2 files<br />
4) Add 
<pre class="brush: java; title: ; notranslate">super.onCreate(savedInstanceState) to Kris' sample</pre>
<p>5) Add antlr-runtime and jbpm-flow-builder</p>
<p>6) Won&#8217;t load bpmn file due to not being able to find a &#8220;validating saxparser implementation&#8221;<br />
Luckily, you can turn this off with</p>
<pre class="brush: java; title: ; notranslate">System.setProperty(&quot;drools.schema.validating&quot;, &quot;false&quot;);</pre>
<p>7) Now it can&#8217;t find x-stream&#8211; this is a 431k jar. Add it.<br />
 <img src='http://petervieth.com/wp-includes/images/smilies/icon_cool.gif' alt='8)' class='wp-smiley' /> Now it will die on the mvel2 parser and then throw some errors about the bpmn file (because mvel compilation failed)<br />
01-31 11:06:44.315: W/dalvikvm(22877): Exception Ljava/lang/StringIndexOutOfBoundsException; thrown while initializing Lorg/mvel2/compiler/AbstractParser;<br />
This error is generated on line 168 in org.mvel2.compiler.AbstractParser which gets the system property java.version and parses the first 3 chars to check against 1.5 without first checking that the property!=null (oops! rookie mistake). On Android, this system property is not available. You can get around this easily by just pushing the Java version on your own.</p>
<pre class="brush: java; title: ; notranslate">System.setProperty(&quot;java.version&quot;, &quot;1.6&quot;);</pre>
<p>9) Now I had a problem with my timer node. It claimed that it had no delay&#8230; but it does have a delay, so I removed it for now.<br />
Guess I may have to make my own delay task&#8230; oh well.<br />
10) Now I get an NPE (which I can&#8217;t seem to reproduce here due to mod_security on my webhost). The offending line in buildProcess has to do with PackageBuilder and java dialect, so I went back and set the default dialect to mvel instead (I am not using Java, stuff off builder!).<br />
11) I still got other NPE&#8217;s. Surrender time.<br />
So, even though I&#8217;d cleared out all the Java in my process definition, and passed the other hurdles, it seems that some run time compilation still occurs when loading a bpmn file, and the resulting code can&#8217;t be run on Android. If you know what&#8217;s causing it, drop me an email or comment.</p>
<p>Even if I were to pass these hurdles, additional challenges remain. Abhay ran into out of heap memory problems. Besides that, persistence would be difficult. There is no official JDBC driver for Android&#8217;s SQLite database. While jBpm doesn&#8217;t tightly integrate with persistence, Activiti and worktoken do, using JPA which makes coding straightforward&#8211; as long as you have a jdbc driver.</p>
<p>It still might be possible to have a non-persistent jBpm running on Android relatively painlessly. Parsing a bpmn file with Android&#8217;s SAXParser, while tedious, wouldn&#8217;t be hard; then the process API could be used to construct the process. You might even write some code to persist processes using the unofficial Android SQLite libraries. But because of these challenges, it sure seems much easier to run the workflow engine server side.</p>
<p>There are two different general applications of workflow: for interface screen flow and business process coordination. Screen flow doesn&#8217;t really require persistence and the complicated processes of business process coordination, so jBpm might still be a good way to quickly create an application with many screens and wire up the flow. Also, latency is a huge issue, so server side workflow is not a good idea for this application. But for business process coordination, a full jBpm setup will provide much more value. If your business process can stand the latency of client-server communications and the possible network connectivity issues of communication with a wireless device, this is the way to go.</p>
<p>30 hours later, its too bad I couldn&#8217;t get it working, but I&#8217;ve got my head back into workflow and generally, I like what I see. Stay tuned!</p>
]]></content:encoded>
			<wfw:commentRss>http://petervieth.com/2012/02/13/workflow-engines-and-android/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Heater and A/C Controls Not Working on a &#8217;99 Honda Accord</title>
		<link>http://petervieth.com/2012/01/29/heater-and-ac-controls-not-working-on-a-99-honda-accord/</link>
		<comments>http://petervieth.com/2012/01/29/heater-and-ac-controls-not-working-on-a-99-honda-accord/#comments</comments>
		<pubDate>Sun, 29 Jan 2012 20:00:23 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Repair]]></category>

		<guid isPermaLink="false">http://petervieth.com/?p=604</guid>
		<description><![CDATA[Symptoms Only the blower motor speed knob works. None of the vent or A/C buttons or their lights work. Quick solution On the underside of the board, just jumper the input (leftmost) leg of the 78dl05 voltage regulator in the middle of the board to the positive leg of capacitor C1. That&#8217;s it. Long story <a href="http://petervieth.com/2012/01/29/heater-and-ac-controls-not-working-on-a-99-honda-accord/"> read more <span class="meta-nav">&#187;</span></a>]]></description>
			<content:encoded><![CDATA[<h3>Symptoms</h3>
<p>Only the blower motor speed knob works. None of the vent or A/C buttons or their lights work.</p>
<h3>Quick solution</h3>
<p>On the underside of the board, just jumper the input (leftmost) leg of the 78dl05 voltage regulator in the middle of the board to the positive leg of capacitor C1. That&#8217;s it.</p>
<h3>Long story</h3>
<p>Since the whole panel went dead all of a sudden, with nothing working, I pried open the module with a small flat head screwdriver, and pulled the knobs off.</p>
<p>I tested the 5v regulator which supplies 5v power using the 12v from the battery. The part is 78dl05 and it is in the middle of the board.<br />
It was not outputting 5v, so I next checked if it was receiving 12v.<br />
Pin 1 Input (12v)<br />
Pin 2 output (5v)<br />
Pin 3 Common (ground)</p>
<p>Pin 1 of the harness is +12v, and the ground pin is in the very middle all by itself. The board was receiving +12v. So that means that there is an open circuit somewhere between the regulator and the connector.</p>
<p>So I traced back from the input leg of the 78dl05 to the connector CN1. The first through hole was covered in greenish blue corrosion. It is located underneath a rubber strip directly below the 78DL05, which is why I didn&#8217;t spot it immediately. I wouldn&#8217;t be surprised if this is how most of these boards fail.</p>
<p>The only other thing between the input leg and the connector CN1 is a capacitor, C1. It looked fine (wasn&#8217;t burst or leaking). I could have attempted to fix the through hole in the board, but it would likely die again, so I decided to just jumped the input leg to the capacitor, which provides a handy place to solder to.</p>
<p>I jumped the positive side of C1 to the input leg of the 78dl05 (left most leg, labeled in+ on the top side of the board) and then plugged it back into the harness, turned the car on, voila, all works fine.</p>
<p>$293 for the part from the Honda dealer and probably $100 more in labor&#8211; you can do it yourself in 15 minutes if you have a soldering iron ($12 from Radioshack) and a couple of screw drivers. Stupid simple.</p>
<p>See Bowzer&#8217;s directions for removal of the unit&#8211; it really is only a few screws!</p>
<p>http://www.driveaccord.net/forums/showthread.php?t=32057</p>
<blockquote><p><a href="http://petervieth.com/wp-content/uploads/2012/01/board-backside.jpg"><img class="aligncenter size-medium wp-image-605" title="Backside of the AC Heater Control Unit board" src="http://petervieth.com/wp-content/uploads/2012/01/board-backside-300x87.jpg" alt="" width="300" height="87" /></a><a href="http://petervieth.com/wp-content/uploads/2012/01/board-top.jpg"><img class="aligncenter size-medium wp-image-606" title="board top" src="http://petervieth.com/wp-content/uploads/2012/01/board-top-300x101.jpg" alt="" width="300" height="101" /></a>I just fixed a 2000 Accord LX with this snafu. The good news is that this is as close to plug and play for a fix as you can get.</p>
<p>You can look up how to access the radio for detailed directions but in a nutshell:<br />
- Remove plastic shroud/surround in center of dash<br />
*remove 2 screws at bottom<br />
*FOr third scres, it&#8217;s hidden behind the clock. Using a thin bladed knife (I used a kitchen knife wrapped in a paper ticcue to avoid scratshing) or screwdriver, pry the bottom of the clock out and pull the unit out. Unplug the wires and set aside. Take out 3rd screw behind in dash. Lift shroud from bottom out.<br />
- AC control unit is mounted to the back of the shroud.<br />
*Disconnect the 2 wiring harnesses from AC control unit.<br />
*Remove the 5 mounting screws and remove AC unit panel.<br />
*Before mounting new unit, lug in the 2 wiring harnesses and check operation&#8230;you should be good to go if the original part was the failure.<br />
- Replace pieces in reverse order</p>
<p>Easy-Peasy&#8230;be careful and patient with those plastic pieces so you don&#8217;t scratch them.</p></blockquote>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://petervieth.com/2012/01/29/heater-and-ac-controls-not-working-on-a-99-honda-accord/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PhoneGap 1.3 &amp; PhoneGap: Beginner&#8217;s Guide</title>
		<link>http://petervieth.com/2012/01/04/phonegap-1-3-phonegap-beginners-guide/</link>
		<comments>http://petervieth.com/2012/01/04/phonegap-1-3-phonegap-beginners-guide/#comments</comments>
		<pubDate>Thu, 05 Jan 2012 05:06:32 +0000</pubDate>
		<dc:creator>peter</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Editorial]]></category>
		<category><![CDATA[Hacking]]></category>

		<guid isPermaLink="false">http://petervieth.com/?p=593</guid>
		<description><![CDATA[Late in 2011 I was contacted by Packt Publishing regarding one of their new publications on the PhoneGap framework.  Apparently my rather negative review of the PhoneGap framework came to their attention and they wanted me to take another shot at developing with it after reading their book.  I still believe PhoneGap is a great <a href="http://petervieth.com/2012/01/04/phonegap-1-3-phonegap-beginners-guide/"> read more <span class="meta-nav">&#187;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Late in 2011 I was contacted by Packt Publishing regarding one of their new publications on the PhoneGap framework.  Apparently my rather negative review of the PhoneGap framework came to their attention and they wanted me to take another shot at developing with it after reading their book.  I still believe PhoneGap is a great idea, so I agreed to go for it.</p>
<p>What follows is part tutorial, part book review.  After a solid day, I&#8217;ve only scratched the surface of what PhoneGap can do.</p>
<p>Briefly, PhoneGap: Beginner&#8217;s Guide is written in a very informal way to keep the reader&#8217;s attention.  It avoids going super in depth into any topic.  This is good, as I read it in bed; I would surely have fallen asleep with a dry, technical encyclopedia of a book.  However, it can also be bad.  Some of the jokes are just weird.  There&#8217;s some really awkward grammar.  But I don&#8217;t really care.  I&#8217;m an impatient developer: give me some options with pros and cons and some code samples and let&#8217;s get to work.  The cover itself says: &#8220;Learn by doing: less theory, more results.&#8221;  I&#8217;m down with that.</p>
<h3>Installation</h3>
<p>I read carefully through the first third of the book, as this covers the basics of PhoneGap.  Originally, I had spun my wheels for several days just trying to get a PhoneGap project off the ground.  The book covers the major steps of setting up each development environment without resorting to a step by step list.  You need to have some clue about setting up environment variables and unzipping archives.  I appreciate this, as it cuts down on the &#8220;noise&#8221;.  I already have a working Android dev environment and don&#8217;t need to set it up again step by step&#8211; I just need to know what&#8217;s important for PhoneGap to work.  The book also covers PhoneGap development for iOS and BlackBerry.</p>
<p>The resources a year ago for PhoneGap were simply incomplete and contradictory, so I was excited to have an actual working procedure in my hands. When I sat down with PhoneGap: Beginners Guide,  I followed the steps and downloaded the portable git, the Ruby 7zip archive, and then added java/bin and ant/bin, ruby/bin, git/bin to my path.  So far, it all seemed to work.  The next step was to get DroidGap in the path&#8211; but as it turns out, between the time the book was written and now, PhoneGap has changed yet again and the DroidGap ruby script is no longer available.  This is actually a blessing.  PhoneGap seems to have earned its own Apache project and all the  Ruby rubbish has been tossed out.  All you need to do is download the PhoneGap sample (which contains all the files you need) and set up an Eclipse project.  Easy.  It&#8217;s too bad the book doesn&#8217;t include the information, but I&#8217;m glad I can now just skip this painful step.</p>
<h3>Running the Demo</h3>
<p>Not surprisingly, the ready to go out of the box sample application isn&#8217;t ready to go out of the box because someone hasn&#8217;t kept it up to date.  My head spins&#8211; how can you sour the first impression of customers with your product by not fixing a few lines in some sample source code when releasing code?  Anyway, the fixes are straightforward:</p>
<ol>
<li>Remove the stock activity import</li>
<li>Remove the import com.phonegap.*</li>
<li>Add an import line for DroidGap:  import com.phonegap.DroidGap</li>
<li>Add the phonegap jar to the project&#8217;s build path</li>
<li>The tutorial says to choose a target of 2.2 or 2.3 for the project; it actually needs to be 2.3 minimum</li>
</ol>
<p>I hooked up my Android phone, hit the run button and voila, the sample application ran on my phone.  It was time to do some development.</p>
<h3>Writing A New Application</h3>
<h4>Problem</h4>
<p>With installation out of the way, it&#8217;s time to build something useful.  I wanted to try out one of the chapters in the book on coding in PhoneGap.  I visited many breweries in 2011, and a common problem was finding nearby breweries.  You can hardly throw a rock in the Pacific Northwest without hitting a microbrewery (ok, not quite, but it&#8217;s not unusual to have half a dozen in a decent sized town).  Say I&#8217;m in Seattle walking down the street&#8211; where should I go?</p>
<p>My go to resource has been <a href="http://www.beermapping.com">beermapping.com</a>, but it is unfortunately extremely painful to use on a mobile browser, so unless you&#8217;ve got a laptop handy or planned the trip out beforehand, you&#8217;re out of luck.  Sure would be nice to use geolocation and the <a href="http://beermapping.com/api/reference/">beermapping.com API</a> to answer my question in one click!</p>
<p>Accessing an API is one of the first samples in the PhoneGap: Beginner&#8217;s Guide, so I figured this would be a good test.</p>
<h4>Solution</h4>
<div id="attachment_594" class="wp-caption aligncenter" style="width: 310px"><a href="http://petervieth.com/wp-content/uploads/2012/01/mock-up.jpg"><img class="size-medium wp-image-594" title="mock up" src="http://petervieth.com/wp-content/uploads/2012/01/mock-up-300x260.jpg" alt="" width="300" height="260" /></a><p class="wp-caption-text">Here&#39;s a mockup of the application created in PowerPoint</p></div>
<p>&nbsp;</p>
<p>PhoneGap: Beginner&#8217;s Guide page 70 has a sample application which queries a web service.  Let&#8217;s add that to the PhoneGap sample application to get started.  Before the web service code can be added:</p>
<ol>
<li>Open the res/values/strings.xml and change the application name to Find Breweries</li>
<li>Replace res/drawable/icon.png with something <a href="http://www.bradfitzpatrick.com/weblog/395/free-beer-mug-icons-for-the-buy-me-a-beer-plugin/">more appropriate</a></li>
<li>Open up assets/www/index.html and change the h1, h2 text</li>
<li>Then delete pretty much everything else except the info div and one button</li>
<li>Change the remaining button to call findBeer() in it&#8217;s onclick event</li>
<li>Change the info div to have one h4 containing a span with id=&#8221;location&#8221; and a span with id=&#8221;result_summary&#8221;</li>
<li>Add a table with id=&#8221;breweries&#8221;</li>
<li>Open main.js and delete all the functions except getLocation and init.</li>
<li>Change the one line in init() to call getLocation instead</li>
<li>Change the suc() function inside getLocation to be:
<pre>document.getElementById("location").innerHTML = (p.coords.latitude + " " + p.coords.longitude);</pre>
</li>
</ol>
<p>At this point, give the app a whirl.  It ought to load and display your GPS coordinates.</p>
<h4>Geolocation</h4>
<p>First things first, since the beermapping API needs a city name and state, we need to determine this information from the GPS coordinates.  For this, we need web services.</p>
<p>You can use Google&#8217;s reverse lookup, but you need an API key and the TOS requires you to display that data on a map.  I don&#8217;t want a map.  Yahoo has a free geolocation service, but the api key application form wants a web address, so that&#8217;s a no go too. Luckily, Geonames.org <a href="http://ws.geonames.org/findNearestAddress?lat=37.56&amp;lng=-122.3" target="_blank">provides a rate limited lookup</a>.  All we need to do is update getLocation to get the response and parse it.</p>
<p>You can query Geonames.org&#8217;s service using the XMLHttpRequest code on page 71 of PhoneGap: Beginner&#8217;s Guide.  Add some parsing of the responseXML and we now have the city name and state.</p>
<pre>var currentLocation = null; // variable to store current location</pre>
<pre>var getLocation = function() {
	console.log("Getting location");
    var suc = function(p) {
    	console.log("Getting location coords succeeded; performing geolocation lookup");
    	var geolocationUrl = "http://ws.geonames.org/findNearestAddress?lat=" + p.coords.latitude + "&amp;lng=" + p.coords.longitude;
        var req = new XMLHttpRequest();
        req.onreadystatechange = function() {
        	if (this.readyState == 4) {
        		if (this.status == 200 || this.status == 0) {
        			console.log("Geolocation success");
        			var data = this.responseXML;
        			var cityNames = data.getElementsByTagName("placename");
        			var stateNames = data.getElementsByTagName("adminCode1");
        			// do something
        			currentLocation = cityNames[0].firstChild.nodeValue + ", " + stateNames[0].firstChild.nodeValue;
        			document.getElementById("location").innerHTML = currentLocation + ".";
        		} else {
        			document.getElementById("location").innerHTML = "(not found, error: " + this.status + ")";
        			console.log("Geolocation error: " + this.status);
        			fail("Geolocation error: " + this.status);
        		}
        	}
        }
        req.open("GET", geolocationUrl, true);
        req.send();

    };
    var locFail = function() {
    	console.log("Getting location coords failed");
    };
    navigator.geolocation.getCurrentPosition(suc, locFail);
};</pre>
<p>Hit the run button.</p>
<div id="attachment_595" class="wp-caption aligncenter" style="width: 190px"><a href="http://petervieth.com/wp-content/uploads/2012/01/device-2012-01-04-183429.png"><img class="size-medium wp-image-595" title="device-2012-01-04-183429" src="http://petervieth.com/wp-content/uploads/2012/01/device-2012-01-04-183429-180x300.png" alt="" width="180" height="300" /></a><p class="wp-caption-text">This is what the application now looks like.</p></div>
<h4>Listing Breweries</h4>
<p>The next step is to query the beermapping API using the information returned by Geonames.</p>
<p>Create a findBeer() function and copy the XMLHttpRequest code from getLocation. I made some edits:</p>
<ol>
<li>Update the URL to hit the beermapping loccity API instead of Geonames</li>
<li>Don&#8217;t forget to update the API key in the code below</li>
<li>I added a check that the responseXML isn&#8217;t null</li>
<li>I added DOM code to create a table</li>
<li>After the query is done, info gets updated with the number of results found</li>
</ol>
<pre>var findBeer = function() {
	console.log("Getting brewery list");
	var api_key = "YOUR API KEY GOES HERE";
	var beermappingUrl = "http://beermapping.com/webservice/loccity/" + api_key + "/" + currentLocation;
    var req = new XMLHttpRequest();
    req.onreadystatechange = function() {
    	if (this.readyState == 4) {
    		if ((this.status == 200 || this.status == 0) &amp;&amp; this.responseXML!=null) {
    			console.log("Brewery query success");
    			var data = this.responseXML;
    			var breweryNames = data.getElementsByTagName("name");
    			var streets = data.getElementsByTagName("street");
    			var phones = data.getElementsByTagName("phone");
    			var ratings = data.getElementsByTagName("overall");

    			// If there are results...
    			if(breweryNames.length!=0) {
	    			// Create the header row
	    			var tbl = document.getElementById("breweries");
					var newRow = tbl.insertRow(-1);
					var newCell0 = newRow.insertCell(0);
					newCell0.innerHTML = "Name";
					var newCell1 = newRow.insertCell(1);
					newCell1.innerHTML = "Address";
					var newCell2 = newRow.insertCell(2);
					newCell2.innerHTML = "Rating";

					// Fill the table with data
	    			for(var i=0; i &lt; breweryNames.length; i++) {
	    				var newRow = tbl.insertRow(-1);
	    				var newCell0 = newRow.insertCell(0);
	    				newCell0.innerHTML = breweryNames[i].firstChild.nodeValue;
	    				var newCell1 = newRow.insertCell(1);
	    				newCell1.innerHTML = streets[i].firstChild.nodeValue + ", " +
											phones[i].firstChild.nodeValue;
	    				var newCell2 = newRow.insertCell(2);
	    				newCell2.innerHTML = ratings[i].firstChild.nodeValue;
	    			}
	    			document.getElementById("result_summary").innerHTML = "Listing " + breweryNames.length + " breweries.";
    			} else {
    				// If there are no results
    				document.getElementById("result_summary").innerHTML = "No breweries found!";
    			}
    		} else {
    			document.getElementById("breweries").innerHTML = "&lt;tr&gt;&lt;td&gt;Error: " + this.status + "&lt;/td&gt;&lt;/tr&gt;";
    			console.log("Brewery query error: " + this.status);
    			fail("Brewery query error: " + this.status);

    		}
    	}
    }
    req.open("GET", beermappingUrl, true);
    req.send();
}</pre>
<p>Run the application again. As it turns out, there aren&#8217;t any breweries in San Mateo, so I&#8217;ve hardcoded Hood River, OR into the query just to see some interesting results.</p>
<div id="attachment_596" class="wp-caption aligncenter" style="width: 190px"><a href="http://petervieth.com/wp-content/uploads/2012/01/device-2012-01-04-204129.png"><img class="size-medium wp-image-596" title="device-2012-01-04-204129" src="http://petervieth.com/wp-content/uploads/2012/01/device-2012-01-04-204129-180x300.png" alt="" width="180" height="300" /></a><p class="wp-caption-text">Full Sail and Double Mountain are awesome</p></div>
<h3>Conclusions</h3>
<p>PhoneGap has come a long way in the past year.  I still wonder how it holds up for larger applications, but at least now it&#8217;s easy to find out.  I can&#8217;t wait to convert my HTML5 based mobile web pages into native Android apps.</p>
<p>PhoneGap: A Beginner&#8217;s Guide offers no-nonsense samples for many of the everyday functions your mobile applications will need.  It also provides advice on what to ignore and  what to consider now that you&#8217;re HTML5 is not targeting the usual IE, Firefox, or Chrome.  It&#8217;s a handy thing to have on the desk while coding.  I think this outweighs its weaknesses in polish.</p>
<p>The sample application above has a number of improvements to be made.</p>
<ol>
<li>Search nearby cities</li>
<li>Don&#8217;t enable the find button until the location is determined (the PhoneGap book has a chapter on CSS&#8211; look there)</li>
<li>Update the stylesheet to taste</li>
<li>Rip all the unneeded permissions and features out of the Android Manifest.  We just need internet access and location permissions.</li>
</ol>
<p>Source code is available here: <a href="http://petervieth.com/wp-content/uploads/2012/01/FindBreweries.zip">FindBreweries</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://petervieth.com/2012/01/04/phonegap-1-3-phonegap-beginners-guide/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Facebook is Making Us Dumb</title>
		<link>http://petervieth.com/2011/12/21/facebook-is-making-us-dumb/</link>
		<comments>http://petervieth.com/2011/12/21/facebook-is-making-us-dumb/#comments</comments>
		<pubDate>Wed, 21 Dec 2011 20:04:21 +0000</pubDate>
		<dc:creator>peter</dc:creator>
				<category><![CDATA[Editorial]]></category>
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://petervieth.com/?p=563</guid>
		<description><![CDATA[Lolz, here iz a pic of my cat sleeping. A sad consequence of the ad supported internet is that websites have an incentive to waste your time. Facebook has mastered time wastage, and, in pursuit of a top spot in the social network race, Google may one day figure out how to kill hours of <a href="http://petervieth.com/2011/12/21/facebook-is-making-us-dumb/"> read more <span class="meta-nav">&#187;</span></a>]]></description>
			<content:encoded><![CDATA[<blockquote><p>Lolz, here iz a pic of my cat sleeping.</p></blockquote>
<p>A sad consequence of the ad supported internet is that websites have an incentive to waste your time. Facebook has mastered time wastage, and, in pursuit of a top spot in the social network race, Google may one day figure out how to kill hours of your time too; that is, if you aren&#8217;t spending all day on Facebook by then.</p>
<p><em>But but, I thought the internet would lead to a richer, better life!</em> All I can say for you, dear reader: you&#8217;re mucked. How did we get to this sad state?</p>
<h3>Part 1: Time Suck</h3>
<p>This all started innocently enough with news websites and movie and game reviews being split over multiple pages so that you, the user, would have to load more webpages and see more ads. It was easy though unsophisticated.</p>
<p>Lately, advertising has gotten much more personalized; it&#8217;s all about targeting ads to the right people. Google got the ball rolling with AdSense. Google associates your searches with you, and if you&#8217;ve got GMail, it can read your email and target ads better. It&#8217;s not perfect, but it doesn&#8217;t try to sell Viagra to 7 year olds, which is what would have happened in the old days (the dark ages 10 years ago).</p>
<p>The impact to Google&#8217;s bottom line? When a business wants to advertise through Google, they&#8217;ll pay more for Google user&#8217;s eyeballs because the business knows Google targets advertising better, so each view is more likely to lead to a return for the business.</p>
<p>Google has completely missed the boat on social networks though (or rather, it has launched a few, which promptly sank). Basically, the information you share with friends is much more useful for targeting ads; hence, it&#8217;s worth more. I recall a presentation at Google IO conference a few years ago where the presenter showed the value to advertisers of each user of Google, Facebook, Myspace, Yahoo, etc. Facebook was already leaping past Google even though it had a smaller user base. Yahoo et al weren&#8217;t even close.</p>
<p>While Google floundered, MySpace got an early lead, but it&#8217;s juvenile interface was a turn off to anyone over 15. Facebook swooped in and got critical mass and has been expanding ever since&#8211; and getting more value out of you by offering additional features. Status updates and friends are the core of Facebook, but there are a lot of features on the periphery to flesh out Facebook&#8217;s database about you.</p>
<p>For example, turns out, knowing the nature of the relationship between you and your &#8220;friends&#8221; is valuable&#8211; so Facebook has a feature to specify which &#8220;friends&#8221; are family members, spouses, etc. This is sold as a cool feature to communicate to the world your most important relationships. For Facebook, it&#8217;s a way to rake in extra cash.</p>
<p>Facebook and The Social Networks need your data. They have to find ways to get you to voluntarily fork it over (or involuntarily&#8211; Facebook recently accepted 20 years of monitoring by the US government as punishment for its privacy shenanigans). This is why social networks nag you to &#8220;complete your profile&#8221; or something along those lines when you sign up. The incomplete status bar is a constant reminder that you have unfinished business, that you are incomplete until you fill out your profile. Come on, fill it out already! Zuckerberg needs new kitchen counter tops!</p>
<p>And really, the more you are around on a social networking site, the more likely you are to hand over data. Facebook recently stopped sending email notifications of activity on your wall&#8211; ostensibly to &#8220;bother&#8221; you less&#8211; but actually because you now need to compulsively check Facebook to see if anything has happened.  It&#8217;s even worse that you aren&#8217;t notified of replies to your comments on other folk&#8217;s walls, so you need to troll throw all your friends walls for those conversation to continue.  Normally, systems evolve from requiring baby sitting to being smart and efficient&#8211; but Facebook is headed backwards, on purpose. Facebook does still contact you&#8211; but only if you don&#8217;t check Facebook enough, with a teaser that &#8220;you have unread notifications on Facebook!&#8221;</p>
<p>It&#8217;s not just Facebook that has time wastage figured out. Zynga has carefully combined gaming and social networks to suck users in, convincing them to babysit virtual farms, fish, and any number of other things just to keep your eyeballs.</p>
<p>These time wasting companies have shot to super stardom while the old guard of the internet (like the Goog) languish in the land of value driven business models. What&#8217;s a poor Google to do?</p>
<h3>Part 2: Promoting Shallow Discourse</h3>
<p>Remember blogs? Oh yeah, what you&#8217;re reading now. They were the &#8220;in&#8221; thing before social networking (actually, Livejournal combined blogging and a network of friends but has stagnated since). Blogs are a similar idea to status updates, just much more&#8230; wordy. And with that comes a problem&#8211; the number of people writing blogs is much less than the number of people reading them because, well, it just takes a while to write a blog post worth reading. So while a blog author divulges a lot of information which could be mined for advertising, there&#8217;s a whole untapped set of users who are just passively participating in the scene by only reading blogs.</p>
<p>The notable exception to this sea of passive users are the comments section.  Comments on blog posts can get quite lively and have many participants. The comments are usually limited in length by the software for practical reasons, so a sentence or two will usually suffice. Quite easy to post, anyone can do it.</p>
<p>Ah-hah!</p>
<p>So Facebook and Twitter have taken the comments section from blogs and made that the entire core of their platform. Forget the whole blog post thing with it&#8217;s lengthy content and Microsoft Word like interface. We don&#8217;t need that crap. Twitter has a famous 144 character limit on its Tweets and no formatting at all, lest you should try and convey too much information at once.</p>
<p>The unfortunate part is that is really difficult to convey anything deep and meaningful in 144 characters. The only hope is to post a link to a blog post or a video; The Social Networks don&#8217;t provide a platform for hosting those, so if you&#8217;d like to generate something deep and meaningful, go look elsewhere and come back when you&#8217;re done.</p>
<p>So, by restricting our conversation to 144 characters at a time, The Social Networks have left us unable to communicate anything deep and meaningful.</p>
<h3>Part 3: Guidance for the Next Big Thing (Someone Please Make Us Smarter!)</h3>
<p>The really tragic thing is that we have more technology than ever before to create new things. Video development is a breeze with new cameras, software, and Youtube for sharing. Recording music no longer takes a studio, just a decent PC (or tablet). Open source has made all sorts of software and hardware hacking ridiculously easy. A whole generation of massively technology enabled people is growing up, but all they have to organize their thoughts and efforts are stupid 144 character status updates. Taking an idea from conception to maturity takes patience and depth, which The Social Networks cannot provide.</p>
<p>For me, this is most painfully obvious with film making. There are so many videos on Youtube showcasing amazing talent&#8211; but a lot of it is just wanking with technology; rather than a proliferation of story telling, we have a proliferation of demonstrations of camera techniques, editing tricks, etc. The open source community has actually achieved great real world effect, rallying around projects and sticking with them over time.  The technology to create ideas, organize people around those ideas, and to develop those ideas hasn&#8217;t gone mainstream.  I&#8217;m not surprised &#8212; the community tools they have used are relatively cumbersome.</p>
<p>Are you a hot new social network looking for an edge over the current players?  Let me make a modest suggestion: build tools that enable us to become smarter, not dumber.  You can still drive eyeballs to your site by helping your users do really awesome things.  We humans have an innate desire to be a part of something bigger than ourselves, but it&#8217;s really hard still to become a part of something. You can change that!</p>
<p>Google, for god sakes, don&#8217;t just copy Facebook with Google+: think about how cool ideas and projects are born, and then provide the tools for users to make them reality.</p>
<h3>Conclusion</h3>
<p>I thought for sure that if I see one more stupid cat picture on Facebook, I would certainly quit. But I haven&#8217;t. I know it&#8217;s bad for me, but like pizza, I just keep going back for another slice. Well, Facebook has billions of dollars of resources to refine the drug and keep us junkies hooked, so maybe I shouldn&#8217;t feel so despondent.  I can&#8217;t help feeling we could be doing so much more with our lives!</p>
<p>But that&#8217;s not what The Social Networks are about. As long as businesses make money off your time above all else, they&#8217;ll have no reason to respect it. They&#8217;ll keep your eyeballs on their website not by going deep, but by going Hollywood, shallower and with more special effects. And if lowering the level of discourse means more users, so be it.</p>
<p>Stay stupid my friends!</p>
]]></content:encoded>
			<wfw:commentRss>http://petervieth.com/2011/12/21/facebook-is-making-us-dumb/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>CocoaMojo Prototype Mark II</title>
		<link>http://petervieth.com/2011/10/18/cocoamojo-prototype-mark-ii/</link>
		<comments>http://petervieth.com/2011/10/18/cocoamojo-prototype-mark-ii/#comments</comments>
		<pubDate>Wed, 19 Oct 2011 02:20:57 +0000</pubDate>
		<dc:creator>peter</dc:creator>
				<category><![CDATA[Chocolate]]></category>
		<category><![CDATA[Custom Builds]]></category>
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://petervieth.com/?p=406</guid>
		<description><![CDATA[CocoaMojo Mark I made a giant mess in the kitchen, leaving a layer of bean shell on the floor and all nearby surfaces. After discussions with a colleague who used to work in industrial automation, we decided a winnower based on blowing air would always make a mess. The best solution was to go from <a href="http://petervieth.com/2011/10/18/cocoamojo-prototype-mark-ii/"> read more <span class="meta-nav">&#187;</span></a>]]></description>
			<content:encoded><![CDATA[<p>CocoaMojo Mark I made a giant mess in the kitchen, leaving a layer of bean shell on the floor and all nearby surfaces. After discussions with a colleague who used to work in industrial automation, we decided a winnower based on blowing air would always make a mess. The best solution was to go from blow to suck&#8211; and the best way to get the shell bits and dust out would be to suck with a cyclonic separator. This uses a cylinder with an intake at the top and a cone at the bottom and a blower motor to create a cyclone within the cylinder. Depending on the tuning of the apparatus, some material falls down to the bottom of the cone while the rest is sucked upwards and away. The separator can be tuned by varying the angle of the cone wall and size of the cylinder.</p>
<p>That said, finding a cyclonic separator is not so easy, and building one would be challenging also (stainless steel conical fermentation vessels for brewing could possibly work, but the shape of the cone cannot be customized). A close approximation would be a shop vac.</p>
<p>So the hunt was on for a suitable shop vac.</p>
<p>I went to Home Depot and Lowes and purchased four shop vacs, ranging in size from 2/3HP to 3.5HP and attached them to the CocoaMojo Mark I. Lowes had much better prices for equivalent rated vacs, so the only shop vac I purchased at Home Depot was the one which mounts on a 5 gallon bucket.</p>
<p>The results: even the &#8220;3.5HP&#8221; vac could not suck with enough force to winnow large cocoa bean chunks using the Mark I&#8217;s 4 inch pipe. I put quotes around 3.5HP because my old Craftsman 3.5HP had sufficient power&#8230; but the Lowes brand vac did not provide equivalent performance. I wasn&#8217;t willing to sacrifice the Craftsman for CocoaMojo so I needed another solution. I figured the suction power was based on the cross sectional area of the pipe. So I switched to 3 inch PVC. This has about 3/5 of the cross sectional area of 4 inch pipe.</p>
<div id="attachment_561" class="wp-caption aligncenter" style="width: 235px"><a href="http://petervieth.com/wp-content/uploads/2011/10/IMG_9490.jpg"><img class="size-medium wp-image-561" title="IMG_9490" src="http://petervieth.com/wp-content/uploads/2011/10/IMG_9490-225x300.jpg" alt="" width="225" height="300" /></a><p class="wp-caption-text">Testing different lengths of pipe</p></div>
<p>Surprisingly, the Lowes 2.5HP vac was conveniently smaller and performed as well as the Lowes 3.5HP shop vac, so I used the smaller of the two. The Home Depot vacs were just too expensive for their performance and the bucket head vac was terribly under powered.</p>
<p>The results were very encouraging.  It would surely take some tuning, but I was not finding much nib in the shop vac and most of the shells were sucked away from the nib.  I told Mike about progress and we decided to try running a batch of cocoa beans through the whole process.  I modified the existing frame to accept the 3&#8243; pipe and got ready to grind some beans&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://petervieth.com/2011/10/18/cocoamojo-prototype-mark-ii/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Cocoa Bean Winnower Prototype Mark I</title>
		<link>http://petervieth.com/2011/10/18/cocoa-bean-winnower-prototype-mark-i/</link>
		<comments>http://petervieth.com/2011/10/18/cocoa-bean-winnower-prototype-mark-i/#comments</comments>
		<pubDate>Wed, 19 Oct 2011 02:05:19 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Chocolate]]></category>
		<category><![CDATA[Custom Builds]]></category>
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://petervieth.com/?p=404</guid>
		<description><![CDATA[Mike Winnike, founder of Happy Goat Caramels in San Francisco (look for it at Draegers and other fancy food stores), was looking to expand into goat milk caramel chocolate and in need of an apparatus to separate cocoa nibs from cocoa shell after the beans are roasted and cracked. So he came to me. Briefly, <a href="http://petervieth.com/2011/10/18/cocoa-bean-winnower-prototype-mark-i/"> read more <span class="meta-nav">&#187;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Mike Winnike, founder of Happy Goat Caramels in San Francisco (look for it at Draegers and other fancy food stores), was looking to expand into goat milk caramel chocolate and in need of an apparatus to separate cocoa nibs from cocoa shell after the beans are roasted and cracked. So he came to me.</p>
<p>Briefly, <a href="http://www.tis-gdv.de/tis_e/ware/genuss/kakao/kakao.htm">cocoa beans</a> grow in pods near the equator. The pods are harvested by farmers and the outer husk removed, leaving a pile of beans. The beans are piled up and covered to ferment, which oxidizes many of the bitter tannins and, due to the heat inside the piles, also prevents the beans from germinating (not unlike how grains are prepared for beer production). The beans are then dried in the sun to prevent them from spoiling due to moisture.</p>
<p>The beans have a hard center (nib) and a somewhat soft shell on the outside. The beans are oven roasted to bring out additional flavor and to dry the shell. The roasted bean is easy to crack in a grinder. The result is a pile of nib chunks and shell chunks that must be sorted.</p>
<p>Sorting manually is extremely time consuming, so for anything more than small quantities of chocolate production, an automated solution is needed.</p>
<p>A quick Google search turned up several winnower designs. My favorite thread was on The Chocolate Life about using some PVC tubing and a blower motor. The idea is to dump the output from the grinder down a tube which has a blower motor at the bottom. The lighter chaff escapes out of the tube while the heavier nibs continue and fall to the bottom. That&#8217;s the idea, anyway.</p>
<p>Mike provided an industrial sized &#8220;can fan&#8221; he had purchased.  I went to Home Depot and got 4 inch PVC tubing and some T joints. I built a reducer from the can fan&#8217;s 6 inch output to 4 inch PVC (mostly from duct table), a butterfly valve to vary the fan power, and a gate valve for the bean input.</p>
<p>You can see the results documented in video here.</p>
<p>The winnower definitely worked but it took several passes to sort the beans. Also, the machine was very messy and tended to blow beans out of the input hole&#8211; leaving the gate valve closed and throwing a handful of beans in, then shutting the gate again was the best way to use it. The creator of the winnower on The Chocolate Life forum had pictures of himself using it outdoors, but this seemed rather impractical for Mike&#8217;s apartment in San Francisco.</p>
<p>No, a second prototype would be needed&#8230;</p>
<div id="attachment_559" class="wp-caption aligncenter" style="width: 235px"><a href="http://petervieth.com/wp-content/uploads/2011/10/IMG_9488.jpg"><img class="size-medium wp-image-559" title="IMG_9488" src="http://petervieth.com/wp-content/uploads/2011/10/IMG_9488-225x300.jpg" alt="" width="225" height="300" /></a><p class="wp-caption-text">Yours truly with the Mark I Winnower</p></div>
]]></content:encoded>
			<wfw:commentRss>http://petervieth.com/2011/10/18/cocoa-bean-winnower-prototype-mark-i/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Bending Acrylic</title>
		<link>http://petervieth.com/2011/06/08/bending-acrylic/</link>
		<comments>http://petervieth.com/2011/06/08/bending-acrylic/#comments</comments>
		<pubDate>Wed, 08 Jun 2011 07:35:24 +0000</pubDate>
		<dc:creator>peter</dc:creator>
				<category><![CDATA[Project]]></category>
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://petervieth.com/?p=551</guid>
		<description><![CDATA[Really, it ain't that hard.]]></description>
			<content:encoded><![CDATA[<p>Some people say you need an oven and form to bend acrylic, slowly raising the temperature until the acrylic assumes the shape of the form, and then lowering the temperature slowly for the acrylic to set correctly.</p>
<p>I say all you need is a heat gun and some patience.  The oven and mold are good, only because they don&#8217;t get impatient.</p>
<p>I stuck an acrylic rod into the head of an EMT bender and put it in the oven at 200F for 15 minutes.  I forget the actual temperature that acrylic melts, but I doubt it mattered as the oven&#8217;s birthdate roughly coincides with the Apollo moon landings and so the temperature knob has fallen out of calibration.<br />
<div id="attachment_552" class="wp-caption alignright" style="width: 310px"><a href="http://petervieth.com/wp-content/uploads/2011/06/bent-acrylic-1.jpg"><img class="size-medium wp-image-552" title="Bent acrylic" src="http://petervieth.com/wp-content/uploads/2011/06/bent-acrylic-1-300x235.jpg" alt="" width="300" height="235" /></a><p class="wp-caption-text">Bent acrylic sanded on one side</p></div><br />
In the end I overheated the acrylic.  How do I know? Bubbles formed inside.  Since these rods are decorative, it&#8217;s actually a cool effect!</p>
<p>I tried again with the range instead of the oven.  After about 30 seconds, I got impatient and cranked the heat all the way up.  Another half minute later the acrylic blistered and started to bend in my hands.  The result was pretty ugly, though functional.</p>
<p>So, somewhere in there is a happy medium.  I suspect around 10 minutes would do the trick.  If you can&#8217;t stand around for 10 minutes with a heat gun or oven range, then make a mold or jig.</p>
]]></content:encoded>
			<wfw:commentRss>http://petervieth.com/2011/06/08/bending-acrylic/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Android Open Accessory Development Kit</title>
		<link>http://petervieth.com/2011/06/08/android-open-accessory-development-kit/</link>
		<comments>http://petervieth.com/2011/06/08/android-open-accessory-development-kit/#comments</comments>
		<pubDate>Wed, 08 Jun 2011 07:08:12 +0000</pubDate>
		<dc:creator>peter</dc:creator>
				<category><![CDATA[Events]]></category>
		<category><![CDATA[Hacking]]></category>
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://petervieth.com/?p=547</guid>
		<description><![CDATA[Official support for controlling hardware via Android handsets is here.  I'm not impressed.]]></description>
			<content:encoded><![CDATA[<p>While at the Maker Faire, I stopped by the Google display positioned on prime territory by the entrance, a location occupied by Ford last year (the carmaker didn&#8217;t bother with a presence this year).  I had missed all the lectures by then, though two cargo containers with exhibits remained, plus a handful of multi colored folding chairs which attendees sat in. One container was dedicated to Sketchup, while the other showcased some projects, including one based on the Android Open Accessory Development Kit.<a href="http://petervieth.com/wp-content/uploads/2011/06/P1020118.jpg"><img class="alignright size-medium wp-image-548" title="Android Open Accessory Development Kit" src="http://petervieth.com/wp-content/uploads/2011/06/P1020118-300x206.jpg" alt="" width="300" height="206" /></a></p>
<p>I was excited to see this development.  So far, I&#8217;d only had success controlling other devices from Android via Bluetooth.  I picked up the attached NexusOne and tried the demo, but it crashed.  I found the program and ran it again, and it crashed again.  Ok, fine, so when I got home I <a href="http://developer.android.com/guide/topics/usb/adk.html">googled the kit</a>.</p>
<p>A little background: my own project, an Internet connected beer fridge, needed to not only connect to the Internet, but control real world things.  The Arduino can do the latter, but connecting to the internet isn&#8217;t really possible with the available shields.  The Arduino doesn&#8217;t really have the muscle to deal with the internet, either.  I needed another device to handle the internet, one that could talk to Arduino.  I&#8217;d had success with Arduino and a NexusOne via Bluetooth before.  But the NexusOne is a really expensive device, especially compared to the Arduino, so I opted for a Linksys router instead this time.  $8 at a thrift store, and $30 brand new. Can&#8217;t beat that. But it&#8217;s not a polished, super reliable system (yet).</p>
<p>With the weight of Google behind this effort, maybe the extra $250 might be a cheap investment for high quality code and hardware. Then I read the &#8220;How the ADK board implements the Android Accessory protocol&#8221; section.  Ouch.</p>
<p>The really great thing about Arduino is that just about anyone can learn to program the thing.  You can write a program with less than a dozen lines that does something useful.</p>
<p>In my effort to attach the Linksys router, I strove to keep things as simple as possible.   The communication between the router and Arduino is really simple: the Arduino tells the router the status of pins, the router runs a script where the status of output pins can be calculated based on the input pins.  For a temperature sensor, it looks something like this: digital_pin[01]=(analog_pin[00]/1024)*500-273.  The updated pins get sent back to the Arduino.  Simple.</p>
<p>With the Android Open Accessory Development Kit, you&#8217;re looking at about 100 lines of code just to have the Arduino handshake with the phone to set up a connection.  If you&#8217;re using an Arduino, it&#8217;s because you don&#8217;t have time for that crap.</p>
<p>Luckily, my conclusion requires only one word:</p>
<p>Fail.</p>
]]></content:encoded>
			<wfw:commentRss>http://petervieth.com/2011/06/08/android-open-accessory-development-kit/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Smart Meter Hacking</title>
		<link>http://petervieth.com/2011/04/01/smart-meter-hacking/</link>
		<comments>http://petervieth.com/2011/04/01/smart-meter-hacking/#comments</comments>
		<pubDate>Fri, 01 Apr 2011 07:26:08 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Green]]></category>
		<category><![CDATA[Hacking]]></category>
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://petervieth.com/?p=543</guid>
		<description><![CDATA[I've been trying to see if there is a way to read energy usage information from the smart meter PG&#038;E installed at my home.]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been trying to see if there is a way to read energy usage information from the smart meter PG&amp;E installed at my home, instead of resorting to an inductive clamp device like the TED (which costs $200+).  The meter is a Landis Gyr Focus AXR SD.  I found a <a href="http://www.defranchiseoncor.org/SmartMeters/Landis-Gyr_Focus_AX_Manual_NY_State.pdf">manual for the AX-SD</a> online.</p>
<p>The meter has an IR port on the front which can be read using a device attached to a triangle shaped raised area.  However, the meter can also be programmed this way, so it seems unlikely PG&amp;E would have left this port wide open for me to attach something to it.</p>
<p>There are several ways for smart meters to &#8220;phone home&#8221;:</p>
<ul>
<li>Modulation over power lines</li>
<li>WiFi/WiMax (IP based)</li>
<li>Cell phone network</li>
<li>Short range point to point wireless</li>
<li>Private wireless network (RF mesh)</li>
</ul>
<p>PG&amp;E uses the latter two strategies.  The smart meter talks to nearby meters via a private RF mesh network running at 915mhz.  Each meter in the mesh network not only generates data (hourly, btw), it acts as a repeater for other nearby meters.  PG&amp;E has placed network access points around the state which capture the data on the mesh network and send it over a secure cellular network back to PG&amp;E.  The system supports two way communications.  The natural gas meter is less sophisticated, and only supports one way communication to a data collector unit which send data over to PG&amp;E via  cell network.  <a href="http://webcache.googleusercontent.com/search?q=cache:-hTp2eYyGaIJ:www.pge.com/myhome/customerservice/meter/smartmeter/howitworks/+pg%26e+rf+mesh&amp;cd=1&amp;hl=en&amp;ct=clnk&amp;gl=us&amp;source=www.google.com">Read more at this now defunct PG&amp;E page</a> (thanks Google webcache!).  The page may be defunct because it <a href="http://1hope.org/hopeblog/?p=1061">suggests that the RF mesh network is unencrypted</a>.  Oops.</p>
<p>Can I tap into this RF mesh network? <a href="http://www.blackhat.com/presentations/bh-usa-09/MDAVIS/BHUSA09-Davis-AMI-SLIDES.pdf">Yes, you can</a>.  But the details have been redacted.</p>
<p>Apparently, the electricity smart meters also contain a ZigBee radio, but this is <a href="http://gigaom.com/cleantech/pge-picks-2-consumer-energy-partners-opower/">not yet being used</a>.  It would be nice if DIY hobbyists could access this information, but it doesn&#8217;t seem likely, does it?</p>
<p>Naturally, with all these RF devices around us, it&#8217;s time to put on your <a href="http://gigaom.com/cleantech/pge%E2%80%99s-smart-meter-opt-out-plan-what%E2%80%99s-next/">tin foil hat</a> and head for the hills.</p>
<p>Oddly, the natural gas meter has no wires running to it, so it must be running on battery power.  A short range Zigbee device which spends most of its time in standby mode would hardly use any power at all.  Since the meter will only be accessed once a month, it could run for a long time!  However, I have to wonder if it&#8217;s possible to kill a meter by sending requests to it, preventing the radio from going to sleep?</p>
<p>Read more on smart meters around the world at <a href="http://en.wikipedia.org/wiki/Smart_meter">Wikipedia</a>.</p>
<p>Analog makes a <a href="http://www.analog.com/library/analogdialogue/archives/43-01/smart_metering.html">radio for smart meter RF mesh networks</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://petervieth.com/2011/04/01/smart-meter-hacking/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP REST Web Services</title>
		<link>http://petervieth.com/2011/02/01/php-rest-web-services/</link>
		<comments>http://petervieth.com/2011/02/01/php-rest-web-services/#comments</comments>
		<pubDate>Tue, 01 Feb 2011 17:53:30 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://petervieth.com/?p=541</guid>
		<description><![CDATA[I've created plenty of REST web services in Java, but never any in PHP.  ]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve created plenty of REST web services in Java, but never any in PHP.  Netbeans has a really awesome generator for both the REST web services and entity beans for database objects when using Java.  You just step through a wizard and Voila!  True, it&#8217;s not very smart about foreign keys, but it&#8217;s way faster than coding by hand.</p>
<p>But there is no such wizard for PHP.</p>
<p>Many people are confused by REST.  There is nothing magic about REST.  Just like your old RPC calls, which are like function calls over the internet.  With REST, you use HTTP commands (GET, POST, PUT, DELETE, etc) to specify what operation you&#8217;d like to perform.  </p>
<p>For example, think about a user.  You might make separate classes to handle fetching user info, creating users, updating users, and deleting users.  With a REST web service, you stuff all those in one file and do a switch based on GET, POST, etc.  </p>
<p>I found an <a href="http://blog.garethj.com/2009/02/building-a-restful-web-application-with-php/">excellent blog post</a> on a REST web service base class.  Just extend it for your classes.</p>
<p>Note there are some mistakes in the comments about how to instantiate the class.  I did this for the user class I created:</p>
<pre>
// Instantiate the class
$service = new UserRestService("GET, POST, UPDATE, DELETE");
$service->handleRawRequest($_SERVER, $_GET, $_POST);
</pre>
<p>You could also just go with a PHP framework&#8230; but it seemed like overkill for a 3 page, 2 DB table application!</p>
]]></content:encoded>
			<wfw:commentRss>http://petervieth.com/2011/02/01/php-rest-web-services/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

