<?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>MrBalky Heavy Industries &#187; hacks</title>
	<atom:link href="http://www.mrbalky.com/category/hacks/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.mrbalky.com</link>
	<description>Fat free with endorphins, anti-oxidants, bioflavonoids, creatine, glucosamine and caffeine!</description>
	<lastBuildDate>Mon, 07 Jun 2010 22:33:42 +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>Weather station &#8211; one last thing</title>
		<link>http://www.mrbalky.com/2010/05/09/weather-station-one-last-thing/</link>
		<comments>http://www.mrbalky.com/2010/05/09/weather-station-one-last-thing/#comments</comments>
		<pubDate>Sun, 09 May 2010 22:04:06 +0000</pubDate>
		<dc:creator>mrbalky</dc:creator>
				<category><![CDATA[experiments]]></category>
		<category><![CDATA[hacks]]></category>
		<category><![CDATA[te923]]></category>
		<category><![CDATA[weather]]></category>

		<guid isPermaLink="false">http://www.mrbalky.com/?p=538</guid>
		<description><![CDATA[It is also possible to read version and status information from the weather station, and the te923con application gives access to this data as well. It is formatted the same way as the weather data, and so was also trivial to process in PHP. I wrote a script that gets the station and sensor status, [...]]]></description>
			<content:encoded><![CDATA[<p>It is also possible to read version and status information from the weather station, and the <em>te923con</em> application gives access to this data as well.  It is formatted the same way as the weather data, and so was also trivial to process in PHP.  I wrote a script that gets the station and sensor status, and sends a notification email if one of the sensors has a low battery.  That script is also included in the <a href="/wp-content/uploads/te923.zip">te923 zip file</a>.  Again, I know my PHP skills are weak, so if you have improvements I&#8217;d be interested in them.</p>
<p>I scheduled it to run once a day at midnight:</p>
<pre><code>0 0 * * * sleep 30;php te923Status.php &lt;notify email address&gt;</code></pre>
<p>The 30 second sleep is intended to offset the status check from the normal weather data check that happens exactly on the minute.</p>
<p>Debian out of the box doesn&#8217;t relay mail to external domains, so I had to do another tweak here.  To enable forwarding, I reconfigured exim according to <a href="http://pkg-exim4.alioth.debian.org/README/README.Debian.etch.html ">http://pkg-exim4.alioth.debian.org/README/README.Debian.etch.html</a>.</p>
<p>It&#8217;s not really the proper way to create a real relay server, but since I&#8217;m behind a firewall and only using the server for this purpose, I didn&#8217;t feel it necessary to do more.  But the email does look suspicious to the receiving mail system, so if you send to an address outside your domain (like gmail, for example), the mail is likely to be determined as spam.  You&#8217;ll need to create whatever filters necessary at the recipient account to avoid this.</p>
<p>And that&#8217;s it so far.  I expect I&#8217;ll delve into <a href="http://oss.oetiker.ch/rrdtool/">RRDTool</a> and <a href="http://code.google.com/p/rrdweather/">RRDWeather</a> now to see if I can create graphs of readings Weather Underground does not (like humidity, for example).</p>
]]></content:encoded>
			<wfw:commentRss>http://www.mrbalky.com/2010/05/09/weather-station-one-last-thing/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Weather Station &#8211; fixing the bugs</title>
		<link>http://www.mrbalky.com/2010/05/09/weather-station-fixing-the-bugs/</link>
		<comments>http://www.mrbalky.com/2010/05/09/weather-station-fixing-the-bugs/#comments</comments>
		<pubDate>Sun, 09 May 2010 22:00:35 +0000</pubDate>
		<dc:creator>mrbalky</dc:creator>
				<category><![CDATA[experiments]]></category>
		<category><![CDATA[hacks]]></category>
		<category><![CDATA[te923]]></category>
		<category><![CDATA[weather]]></category>

		<guid isPermaLink="false">http://www.mrbalky.com/?p=479</guid>
		<description><![CDATA[The first thing I discovered is that the te923con application has a bug in decoding UV index data from the station. The index jumps from .9 to 10.0. A simple patch to te923_com.h is required. This diff output actually is a change to a single line that I split up for clarity here: @@ -138,7 [...]]]></description>
			<content:encoded><![CDATA[<p>The first thing I discovered is that the te923con application has a bug in decoding UV index data from the station.  The index jumps from .9 to 10.0.  A simple patch to te923_com.h is required.  This diff output actually is a change to a single line that I split up for clarity here:</p>
<pre><code>@@ -138,7 +138,7 @@
     }

     else {
-        data-&gt;uv = bcd2int( buf[18] &amp; 0x0F ) / 10.0 +
               bcd2int( buf[18] &amp; 0xF0 ) +
               bcd2int( buf[19] &amp; 0x0F ) * 10.0;
+        data-&gt;uv = bcd2int( buf[18] &amp; 0x0F ) / 10.0 +
               bcd2int( ( buf[18] &amp; 0xF0 ) &gt;&gt; 4 ) +
               bcd2int( buf[19] &amp; 0x0F ) * 10.0;
         data-&gt;_uv = 0;
     }</code></pre>
<p>The next thing to address is the permissions problem.  To this point, the only way to get data from the station was to be root.  Otherwise, you get this error:</p>
<pre><code>[mcp:…/te923/te923] te923con -D
Error while setting configuration (-1).</code></pre>
<p>This is a generic issue with USB devices, and I found an item on a wiki (<a href="http://wiki.openstreetmap.org/wiki/USB_Garmin_on_GNU/Linux#Fixing_Device_Permissions">http://wiki.openstreetmap.org/wiki/USB_Garmin_on_GNU/Linux#Fixing_Device_Permissions</a>) about GPS units that got me going.</p>
<p>That page discusses how to set the group ownership on the device, as well as the permissions on the device.  Long story short, I created the device rule set <em>/etc/udev/rules.d/99-te923.rules</em> (all on one line):</p>
<pre><code>ATTRS{idVendor}=="1130", ATTRS{idProduct}=="6801",
                    MODE="0660", GROUP="plugdev"</code></pre>
<p><em>idVendor</em> and <em>idProduct</em> identify the TE923 weather station, <em>mode</em> tells the USB driver to give read/write permissions to the user and group that owns the device, and <em>group</em> tells the driver to assign group ownership to &#8220;plugdev&#8221;.  My user on the machine is a member of that group so I should be OK.</p>
<p>Ask the system to reload the USB rulesets:</p>
<pre><code>[mcp:.../te923/te923] sudo udevadm control --reload_rules</code></pre>
<p>And now I can get valid data back from the unit without being root:</p>
<pre><code>[mcp:.../cwanek/cronjobs] te923con
1273414489::::59:::::::::1003.1:5.0:3:0:9:0.4:0.0:11.7:215</code></pre>
<p>Unfortunately, though, some readings (specifically current temp readings) are empty.  Even wide-open permissions on the device don&#8217;t help.  This doesn&#8217;t make sense to me, and I have not yet solved this issue, so I&#8217;m still stuck with being root to run <em>te923con</em>.  I&#8217;d love to know why it would work only partially.</p>
<p>Still, I don&#8217;t really want to have root&#8217;s crontab running the script, so I configured sudo to skip the password prompt for the group <em>plugdev</em> for the te928con application.  With <em>visudo</em>, add:</p>
<pre><code>%plugdev ALL=NOPASSWD: /usr/local/bin/te923con</code></pre>
<p>Moving on, the I was still not able to run <em>te923con</em> without removing the USB human interface device module (<em>sudo rmmod usbhid</em>).  While removing it allows access to the te923 station, it would also cause any other HID like a mouse or keyboard to stop functioning.  So the trick is to get the <em>usbhid</em> module to release just the weather station.</p>
<p>There are many sites that document how to get usbhid to unbind a device.  I found <a href="http://lwn.net/Articles/143397/">http://lwn.net/Articles/143397/</a>, which give me the following command:</p>
<pre><code>sudo bash -c "echo -n 2-1:1.0 &gt; /sys/bus/usb/drivers/usbhid/unbind"</code></pre>
<p><em>bash -c</em> is required so the shell redirection to <em>unbind</em> will succeed.</p>
<p>Digging deeper, I learned (<a href="http://reactivated.net/writing_udev_rules.html">http://reactivated.net/writing_udev_rules.html</a>) that you can configure the unbind to happen immediately after the device is connected, by using the &#8220;RUN=&#8221; option in the device rules file (this is all on one line in <em>/etc/udev/rules.d/99-te923.rules</em>):</p>
<pre><code>ATTRS{idVendor}=="1130", ATTRS{idProduct}=="6801",
    MODE="0660", GROUP="plugdev",
    RUN="/bin/sh -c 'echo -n $id:1.0 &gt; /sys/bus/usb/drivers/usbhid/unbind'"</code></pre>
<p>So now, apart from the missing data when running as a non-privileged user, the te923 weather station is coexisting with other USB devices, and I am able to schedule the upload script in my own user crontab.</p>
<p>There&#8217;s <a href="http://www.mrbalky.com/2010/05/09/weather-station-one-last-thing/">one last thing</a>&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.mrbalky.com/2010/05/09/weather-station-fixing-the-bugs/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Getting the weather station online</title>
		<link>http://www.mrbalky.com/2010/05/09/getting-the-weather-station-online/</link>
		<comments>http://www.mrbalky.com/2010/05/09/getting-the-weather-station-online/#comments</comments>
		<pubDate>Sun, 09 May 2010 21:55:49 +0000</pubDate>
		<dc:creator>mrbalky</dc:creator>
				<category><![CDATA[experiments]]></category>
		<category><![CDATA[hacks]]></category>
		<category><![CDATA[te923]]></category>
		<category><![CDATA[weather]]></category>

		<guid isPermaLink="false">http://www.mrbalky.com/?p=505</guid>
		<description><![CDATA[Weather Underground has a very simple data upload protocol published on their site at http://wiki.wunderground.com/index.php/PWS_-_Upload_Protocol. Because running child processes and fetching web pages is easy in PHP, I chose it for coding the application to read, parse and upload the weather data. (All of the code I wrote for this can be downloaded in a [...]]]></description>
			<content:encoded><![CDATA[<p>Weather Underground has a very simple data upload protocol published on their site at <a href="http://wiki.wunderground.com/index.php/PWS_-_Upload_Protocol">http://wiki.wunderground.com/index.php/PWS_-_Upload_Protocol</a>.  Because running child processes and fetching web pages is easy in PHP, I chose it for coding the application to read, parse and upload the weather data.  (All of the code I wrote for this can be <a href="/wp-content/uploads/te923.zip">downloaded in a zip file</a>.)</p>
<p>Sure, there are packages like <a href="http://code.google.com/p/rrdweather/">RRD Weather</a> that can do this too, but where&#8217;s the fun in that.</p>
<p>The <em>te923con</em> application returns most of the data included in the wunderground protocol directly, so it&#8217;s a simple matter of parsing it from the application output.  Weather Underground wants imperial units, but maybe someday I&#8217;ll want proper metric units, so I made it a parse option.</p>
<p>The weather station apparently does not return a calculated dew point, which is part of the upload protocol.  It turns out that calculating dew point is not straighforward.  But many people have implemented calculators.  A guy named <a href="http://www.decatur.de/">Wolfgang Kühn</a> <a href="http://www.decatur.de/javascript/dew/index.html">implemented one in javascript</a> that seemed very thorough, so I did a quick port of it to PHP.</p>
<p>The weather station also returns only the accumulated rainfall total since the station was started, so I implemented a simple array mechanism to retain historical data from the rain counter.  I can then calculate the &#8220;rain in last hour&#8221; and &#8220;rain since midnight&#8221; values required by the WUnderground protocol.</p>
<p>From there, it&#8217;s a simple matter to build the URL string for data upload, and a <em>file_get_contents</em> call to upload and get the success or failure result.</p>
<p>I save the rain counters and the other weather data as PHP code in a cache file that is reloaded with a PHP include the next time the script runs.</p>
<p>WUnderground can accept data as fast as once a second, but the weather station does not update from its sensors with anywhere near that frequency, so I felt scheduling upload once a minute via cron was more than often enough.  The script takes station id, password and cache file name on the command line (all on one line):</p>
<pre><code>* * * * * php te923WunderUpload.php &lt;station ID&gt;
                       &lt;wunderground password&gt; &lt;cache file name&gt;</code></pre>
<p>Because of the permissions issues with the USB device, for now this is scheduled in the root user&#8217;s crontab.</p>
<p>Now on to <a href="http://www.mrbalky.com/2010/05/09/weather-station-fixing-the-bugs/">fixing the bugs</a>&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.mrbalky.com/2010/05/09/getting-the-weather-station-online/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Weather station &#8211; my new toy</title>
		<link>http://www.mrbalky.com/2010/05/09/weather-station-tinkering/</link>
		<comments>http://www.mrbalky.com/2010/05/09/weather-station-tinkering/#comments</comments>
		<pubDate>Sun, 09 May 2010 21:53:00 +0000</pubDate>
		<dc:creator>mrbalky</dc:creator>
				<category><![CDATA[experiments]]></category>
		<category><![CDATA[hacks]]></category>
		<category><![CDATA[te923]]></category>
		<category><![CDATA[weather]]></category>

		<guid isPermaLink="false">http://www.mrbalky.com/?p=477</guid>
		<description><![CDATA[For some reason I can&#8217;t explain, I&#8217;ve wanted a weather station for years. A piece in Wired last month pushed me over the edge and I picked up the Honeywell TE923W. It&#8217;s relatively cheap, and while not as good as a Davis, accurate enough for me. The problem with this station, though, is that it&#8217;s [...]]]></description>
			<content:encoded><![CDATA[<p>For some reason I can&#8217;t explain, I&#8217;ve wanted a weather station for years.  A piece in <a href="http://www.wired.com/">Wired</a>  last month pushed me over the edge and I picked up the <a href="http://honeywellweatherstations.com/TE923W.html">Honeywell TE923W</a>.  It&#8217;s relatively cheap, and while not as good as a <a href="http://www.davisnet.com/weather/products/weather_product.asp?pnum=06152">Davis</a>, accurate enough for me.</p>
<p><a href="http://www.mrbalky.com/wp-content/uploads/te923w003-1.gif"><img src="http://www.mrbalky.com/wp-content/uploads/te923w003-1.gif" alt="" title="te923w003 - 1" width="382" height="278" class="alignnone size-full wp-image-500" /></a></p>
<p>The problem with this station, though, is that it&#8217;s a USB station, and Linux is not supported by the software that ships with it.  But I figured I could find a way around that, and indeed I could, but it wasn&#8217;t so straightforward.  Along the way I learned some arcane details about USB on Debian Linux.  This series of posts is something of a blow-by-blow of the process.</p>
<p>The hardest part was already done for me by <a href="http://www.fukz.de/">Sebastian John</a> who created an application that reads the current raw data from the station.  The source is available at <a href="http://te923.fukz.org/index">http://te923.fukz.org/index</a>.  Building the source requires libusb, and the site links to it, but I was able to build with the vanilla libusb-dev installed by apt-get:</p>
<pre><code>apt-get install libusb-dev</code></pre>
<p>The build creates the executable <em>te923con</em>, which I then installed in <em>/usr/local/bin</em>.</p>
<p>The first time I tried to run it, I got the following error message:</p>
<pre><code>[mcp:…/te923/te923] te923con -D
Error while setting configuration (-1).</code></pre>
<p>This indicates insufficient privileges to access the USB device, so to get things going I ran the te923con application as root.  That got me to the next error:</p>
<pre><code>[mcp:.../te923/te923] sudo ./te923con -D
Error while setting configuration (-16).</code></pre>
<p>The dmesg shows the following error (all on one line):</p>
<pre><code>[24464516.452385] usb 2-1: usbfs: interface 0 claimed
                    by usbhid while 'te923con' sets config #1</code></pre>
<p>It seems that the TE923 registers itself as a human interface device (HID) for some reason, so the OS tries to treat it a such.  The author of a package of code that creates a web view for the TE923 has the solution on his blog, though without explanation of the problem or why: <a href="http://firewall.haringstad.com/TE923-Frontend/blog/TE923-Frontend-Info/TE923-Frontend%20Blog/B9EF42CC-F942-41DE-ABDF-461549FEFB46.html">http://firewall.haringstad.com/TE923-Frontend/blog/TE923-Frontend-Info/TE923-Frontend%20Blog/B9EF42CC-F942-41DE-ABDF-461549FEFB46.html</a></p>
<p>He removes the usbhid kernel module:</p>
<pre><code>sudo rmmod usbhid</code></pre>
<p>And success:</p>
<pre><code>[mcp:.../te923/te923] sudo ./te923con -D
[DEBUG] got |07|00|0a|0a|00|0a|0a|00|
[DEBUG] got |07|0a|0a|00|0a|30|00|af|
[DEBUG] got |07|3d|03|57|c0|28|00|35|
[DEBUG] got |05|00|0a|b2|00|66|00|35|
[DEBUG] got |01|5a|0a|b2|00|66|00|35|
[DEBUG] got |02|28|82|b2|00|66|00|35|
[DEBUG] got |07|37|64|c0|96|0a|00|0a|
[DEBUG] got |07|0a|00|0a|0a|00|0a|0a|
[DEBUG] got |07|00|0a|30|00|af|3d|03|
[DEBUG] got |07|57|c0|28|00|35|00|0a|
[DEBUG] got |03|b2|00|66|00|35|00|0a|
[DEBUG] TMP 0 BUF[00]=28 BUF[01]=82 BUF[02]=37
[DEBUG] TMP 1 BUF[03]=64 BUF[04]=c0 BUF[05]=96
[DEBUG] TMP 2 BUF[06]=0a BUF[07]=00 BUF[08]=0a
[DEBUG] TMP 3 BUF[09]=0a BUF[10]=00 BUF[11]=0a
[DEBUG] TMP 4 BUF[12]=0a BUF[13]=00 BUF[14]=0a
[DEBUG] TMP 5 BUF[15]=0a BUF[16]=00 BUF[17]=0a
[DEBUG] UVX   BUF[18]=30 BUF[19]=00
[DEBUG] PRESS BUF[20]=af BUF[21]=3d
[DEBUG] STAT  BUF[22]=03
[DEBUG] WCHIL BUF[23]=57 BUF[24]=c0
[DEBUG] WGUST BUF[25]=28 BUF[26]=00
[DEBUG] WSPEE BUF[27]=35 BUF[28]=00
[DEBUG] WDIR  BUF[29]=0a
[DEBUG] RAINC BUF[29]=00 BUF[30]=b2 BUF[31]=00
1272059734:22.80:37:6.40:96:::::::::986.9:3.0:3:0:10:1.6:1.3:5.7:178</code></pre>
<p>Hooray!  There are still a few problems to work out with the device interface, and there is a bug in the te923con application to fix, but now I have a working interface to my weather station.  Next up, <a href="http://www.mrbalky.com/2010/05/09/getting-the-weather-station-online/">getting the weather data</a> onto <a href="http://www.wunderground.com/">Weather Underground</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.mrbalky.com/2010/05/09/weather-station-tinkering/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Access -&gt; MySQL</title>
		<link>http://www.mrbalky.com/2009/10/23/access-mysql/</link>
		<comments>http://www.mrbalky.com/2009/10/23/access-mysql/#comments</comments>
		<pubDate>Fri, 23 Oct 2009 19:54:09 +0000</pubDate>
		<dc:creator>mrbalky</dc:creator>
				<category><![CDATA[experiments]]></category>
		<category><![CDATA[hacks]]></category>

		<guid isPermaLink="false">http://www.mrbalky.com/?p=460</guid>
		<description><![CDATA[Long, long ago I hacked together a Java app that imports the freedb CD info files from my local drive to an MS Access database. The CD ripper application I use creates a local freedb with a file for each CD I rip (all of them). So importing from that freedb to a database seemed [...]]]></description>
			<content:encoded><![CDATA[<p>Long, long ago I hacked together a Java app that imports the <a href="http://www.freedb.org/">freedb</a> CD info files from my local drive to an <a href="http://en.wikipedia.org/wiki/Microsoft_Access">MS Access</a> database.  The CD ripper application I use creates a local freedb with a file for each CD I rip (all of them).  So importing from that freedb to a database seemed a natural thing to do.</p>
<p>Access was all that I had access (heh) to, and it had a &#8220;music collection&#8221; database template, so with slight modification to the template that&#8217;s what I used.</p>
<p>Well now, I no longer have access (heh) to Access, Access is a <a href="http://www.urbandictionary.com/define.php?term=PITA">PITA</a>, and I already have <a href="http://www.mysql.com/">MySQL</a> available on my home server, so I figured it was time to finally migrate.</p>
<p>I found a handy application called <a href="http://www.navicat.com/">Navicat</a> (fully functional trial), that will import directly from the Access .MDB file to a MySQL database.</p>
<p>While Navicat mostly worked, I was not quite done.  The import did not properly get the auto_increment attribute on the tables&#8217; &#8216;id&#8217; column.  Also, the Access database tables had spaces in their names which is kind of a drag.  Fortunately both were easily solved by exporting from MySQL to text using mysqldump, editing the .sql file that resulted, and then reimporting to MySQL from the .sql file.</p>
<p>Sure it&#8217;s a ridiculous thing nobody in their right mind will ever have to do, but I&#8217;m not in my right mind.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.mrbalky.com/2009/10/23/access-mysql/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>DIY headset locker for Rock Shox Pike</title>
		<link>http://www.mrbalky.com/2009/05/19/diy-headset-locker-for-rock-shox-pike/</link>
		<comments>http://www.mrbalky.com/2009/05/19/diy-headset-locker-for-rock-shox-pike/#comments</comments>
		<pubDate>Tue, 19 May 2009 19:52:07 +0000</pubDate>
		<dc:creator>mrbalky</dc:creator>
				<category><![CDATA[bike]]></category>
		<category><![CDATA[hacks]]></category>

		<guid isPermaLink="false">http://www.mrbalky.com/?p=362</guid>
		<description><![CDATA[This might work for other Rock Shox forks too&#8230; My new Pike&#8217;s steerer tube has a cap in the bottom with a threaded hole the same size as a standard headset bolt (M6). Instead of pounding a star nut into the steerer, it&#8217;s exteremely easy use this cap as the bottom of a headset locker [...]]]></description>
			<content:encoded><![CDATA[<p>This might work for other Rock Shox forks too&#8230;</p>
<p>My new Pike&#8217;s steerer tube has a cap in the bottom with a threaded hole the same size as a standard headset bolt (M6).  Instead of pounding a star nut into the steerer, it&#8217;s exteremely easy use this cap as the bottom of a headset locker like the <a href="http://www.oneal.com/catalog/product_info.php?cPath=2_19&#038;products_id=590">Azonic Headlock</a> or <a href="http://www.use1.com/products/safe-t/ ">USE Safe-T</a>.</p>
<p>Required parts (in addition to headset, stem, spacers, etc.):<br />
M6 threaded rod (shortest I could buy was 3 feet)<br />
M6 coupler nut<br />
Total cost about $5.</p>
<p>Insert the rod to measure the correct length.  I threaded the rod through the bottom of the steerer tube until half an inch or so was protruding out the top of the tube.  This took some time to thread the 10&#8243; of rod through; I could have done an initial cut to an estimation of length to save myself some time, I suppose.<br />
<img src="http://www.mrbalky.com/wp-content/uploads/img_1182-209x300.jpg" alt="img_1182" title="img_1182" width="209" height="300" class="aligncenter size-medium wp-image-364" /><br />
<img src="http://www.mrbalky.com/wp-content/uploads/img_1181-300x258.jpg" alt="img_1181" title="img_1181" width="300" height="258" class="aligncenter size-medium wp-image-363" /></p>
<p>Add coupler nut, headset cap and original stem bolt.  Thread the nut on the rod first, headset cap on original stem bolt, and then stem bolt into the coupler nut as well.<br />
<img src="http://www.mrbalky.com/wp-content/uploads/img_1183-300x289.jpg" alt="img_1183" title="img_1183" width="300" height="289" class="aligncenter size-medium wp-image-367" /><br />
<img src="http://www.mrbalky.com/wp-content/uploads/img_1184-300x296.jpg" alt="img_1184" title="img_1184" width="300" height="296" class="aligncenter size-medium wp-image-368" /></p>
<p>Tighten down the headset cap so there is no play or extra space in the steerer stack.  Mark the point where the rod emerges from the bottom of the steerer tube.  Take it all apart again, and cut the rod at the mark with a hacksaw.<br />
<img src="http://www.mrbalky.com/wp-content/uploads/img_1185-182x300.jpg" alt="img_1185" title="img_1185" width="182" height="300" class="aligncenter size-medium wp-image-370" /><br />
<img src="http://www.mrbalky.com/wp-content/uploads/img_1186-268x300.jpg" alt="img_1186" title="img_1186" width="268" height="300" class="aligncenter size-medium wp-image-371" /></p>
<p>Put it all together with the headset cap back on original bolt, coupler to original bolt, then threaded rod into coupler.  You may want to use some removable threadlocker on the coupler to make it behave more like a single bolt when it&#8217;s in the steerer.  Tighten the original stem bolt tightly into the coupler; it&#8217;ll butt up against the threaded rod.<br />
<img src="http://www.mrbalky.com/wp-content/uploads/img_1188-300x108.jpg" alt="img_1188" title="img_1188" width="300" height="108" class="aligncenter size-medium wp-image-374" /><br />
Drop the whole thing into the steerer tube, thread it into the bottom cap, then tighten the bolt to the torque specs of your headset.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.mrbalky.com/2009/05/19/diy-headset-locker-for-rock-shox-pike/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Follow my TiVo on Twitter</title>
		<link>http://www.mrbalky.com/2009/02/24/follow-my-tivo-on-twitter/</link>
		<comments>http://www.mrbalky.com/2009/02/24/follow-my-tivo-on-twitter/#comments</comments>
		<pubDate>Tue, 24 Feb 2009 16:14:53 +0000</pubDate>
		<dc:creator>mrbalky</dc:creator>
				<category><![CDATA[hacks]]></category>
		<category><![CDATA[tivo]]></category>
		<category><![CDATA[twitter]]></category>

		<guid isPermaLink="false">http://www.mrbalky.com/?p=338</guid>
		<description><![CDATA[The other night my friend Bob mentioned somebody had set up a Twitter account for their TiVo. After thinking about it for a second I said something like &#8220;that&#8217;s almost trivial&#8221;. Naturally I had to see if it really was trivial, which in fact it turned out to be. @mrbalkytivo is busier than I am. [...]]]></description>
			<content:encoded><![CDATA[<p>The other night my friend Bob mentioned somebody had set up a <a href="http://twitter.com">Twitter</a> account for their <a href="http://www.tivo.com/">TiVo</a>.  After thinking about it for a second I said something like &#8220;that&#8217;s almost trivial&#8221;.</p>
<p>Naturally I had to see if it really was trivial, which in fact it turned out to be.  <a href="http://twitter.com/mrbalkytivo">@mrbalkytivo</a> is busier than <a href="https://twitter.com/mrbalky">I</a> am.</p>
<p>Put <a href="http://www.mrbalky.com/wp-content/uploads/tweettivophp.txt">tweetTivo.php</a> someplace to be called by cron.</p>
<p>class_tivo_xml.php is not written by me and is required.  <a href="http://www.google.com/search?q=class_tivo_xml">Google it up</a>.  Figuring out how to get the XML info from the TiVo is left as an exercise for the reader.</p>
<p>The script will tweet about any new recording that starts, including TiVo suggestions, which are not always reflective of my taste, but then again, neither are many of MrsBalky&#8217;s choices.  I thought about enhancing the script to skip suggestions, but grew bored and drifted away.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.mrbalky.com/2009/02/24/follow-my-tivo-on-twitter/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>TwitPic upload hack</title>
		<link>http://www.mrbalky.com/2009/01/13/twitpic-upload-hack/</link>
		<comments>http://www.mrbalky.com/2009/01/13/twitpic-upload-hack/#comments</comments>
		<pubDate>Wed, 14 Jan 2009 01:46:48 +0000</pubDate>
		<dc:creator>mrbalky</dc:creator>
				<category><![CDATA[experiments]]></category>
		<category><![CDATA[hacks]]></category>
		<category><![CDATA[cygwin]]></category>
		<category><![CDATA[twitpic]]></category>
		<category><![CDATA[twitter]]></category>

		<guid isPermaLink="false">http://www.mrbalky.com/?p=304</guid>
		<description><![CDATA[Some Twitter users have been using TwitPic to link photos to tweets. I, on the other hand, have been using Flickr and Snipr. It&#8217;s a PITA, so I&#8217;m giving TwitPic a whirl. Sadly, Digsby, does not support TwitPic, and I&#8217;m not installing yet another app. TwitPic has an API, so I rolled my own simple [...]]]></description>
			<content:encoded><![CDATA[<p>Some <a href="http://twitter.com">Twitter</a> users have been using <a href="http://twitpic.com/">TwitPic</a> to link photos to tweets.  I, on the other hand, have been using Flickr and <a href="http://snipr.com/">Snipr</a>.  It&#8217;s a PITA, so I&#8217;m giving TwitPic a whirl.  Sadly, <a href="http://www.digsby.com/">Digsby</a>, does not support TwitPic, and I&#8217;m not installing yet another app.</p>
<p>TwitPic has an <a href="http://twitpic.com/api.do">API</a>, so I rolled my own simple uploader with <a href="http://www.cygwin.com/">cygwin</a> and <a href="http://curl.haxx.se/">curl</a>.  There&#8217;s no doubt in my mind that I&#8217;ve reinvented the wheel here&#8230;</p>
<p><em>Standard disclaimer applies: this is quick n’ dirty(tm)</em>:</p>
<pre>
<code>#!/bin/bash

# curl executable.  I'm a PC.
CURL=C:/cygwin/bin/curl

# The upload script that will accept the data
UPLOAD_URL=http://twitpic.com/api/uploadAndPost

# Snag stuff off the command line
TWITTER_USER=$1
TWITTER_PW=$2
PHOTO=`cygpath -m "$3"`
TWEET_MSG=$4

# Prompt for message if it's not given
if [ "$TWEET_MSG" = "" ]; then
   read -p "Tweet msg: " TWEET_MSG
fi

# Go
echo Uploading...
$CURL \
  --form username=$TWITTER_USER \
  --form password=$TWITTER_PW \
  --form media=@"$PHOTO" \
  --form message="$TWEET_MSG" $UPLOAD_URL

# Wait for user to read result message
echo
read -p "Press &lt;enter&gt; to continue" bogus</code>
</pre>
<p>Create a desktop shortcut with uid and password:</p>
<pre><code>C:\cygwin\bin\sh.exe ~/twitpic.sh --userid-- --password--</code></pre>
<p>Now just drag and drop the photo onto the desktop shortcut.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.mrbalky.com/2009/01/13/twitpic-upload-hack/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Hate the iGoogle left-side navigation?</title>
		<link>http://www.mrbalky.com/2008/12/12/hate-the-igoogle-left-side-navigation/</link>
		<comments>http://www.mrbalky.com/2008/12/12/hate-the-igoogle-left-side-navigation/#comments</comments>
		<pubDate>Fri, 12 Dec 2008 22:33:20 +0000</pubDate>
		<dc:creator>mrbalky</dc:creator>
				<category><![CDATA[google]]></category>
		<category><![CDATA[hacks]]></category>

		<guid isPermaLink="false">http://www.mrbalky.com/?p=247</guid>
		<description><![CDATA[Hate that it takes up screen real estate for no reason? Find Gmail canvas view as unusable as I do? Check out all that unused grey space: The last straw for me today was to discover that they put chat in the navigation bar, and it was impossible to turn off. I found a groups [...]]]></description>
			<content:encoded><![CDATA[<p>Hate that it takes up screen real estate for no reason?  Find Gmail canvas view as unusable as I do?</p>
<p>Check out all that unused grey space:<br />
<img src="http://www.mrbalky.com/wp-content/uploads/igoogle-157x300.jpg" alt="igoogle" title="igoogle" width="157" height="300" class="aligncenter size-medium wp-image-248" /><br />
The last straw for me today was to discover that they put chat in the navigation bar, and it was impossible to turn off.  I found a groups <a href="http://groups.google.com/group/Google_Web_Search_Help-Personalizing/browse_thread/thread/6254593b117f2f54/0a5e341fb4ccce9a?q=mrbalky&#038;lnk=ol&#038;">forum thread</a> where I could actually register my discontent, and found this little gem:</p>
<p><a href="http://www.google.com/ig?hl=all">http://www.google.com/ig?hl=all</a></p>
<p>Add that &#8220;?hl=all&#8221; to the end of the URL, and hooray!  Tabs on top again!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.mrbalky.com/2008/12/12/hate-the-igoogle-left-side-navigation/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Some things you do just because you can</title>
		<link>http://www.mrbalky.com/2008/10/24/some-things-you-do-just-because-you-can/</link>
		<comments>http://www.mrbalky.com/2008/10/24/some-things-you-do-just-because-you-can/#comments</comments>
		<pubDate>Fri, 24 Oct 2008 16:35:33 +0000</pubDate>
		<dc:creator>mrbalky</dc:creator>
				<category><![CDATA[experiments]]></category>
		<category><![CDATA[hacks]]></category>
		<category><![CDATA[sonos]]></category>

		<guid isPermaLink="false">http://www.mrbalky.com/?p=214</guid>
		<description><![CDATA[Need another Sonos controller? Hack together openlink, perl, sonosweb and iphone sonos: I had to go through Perl dependency hell (Perl really is an abomination) to get sonosweb working on the linkstation, but it works pretty well now. Throw in a little DD-WRT and ssh and you can really mess with your S.O. by changing [...]]]></description>
			<content:encoded><![CDATA[<p>Need another <a href="http://www.sonos.com/">Sonos</a> <a href="http://www.sonos.com/whattobuy/controllers/CR100/default.aspx">controller</a>?</p>
<p>Hack together <a href="http://buffalo.nas-central.org/index.php?title=Projects/OpenLink">openlink</a>, <a href="http://www.perl.org/">perl</a>, <a href="http://www.purple.org/sonos/">sonosweb</a> and <a href="http://www.nowsms.com/download/sonoswebiphone.zip">iphone sonos</a>:<br />
<a href="http://www.mrbalky.com/wp-content/uploads/ipod-sonos.jpg"><img src="http://www.mrbalky.com/wp-content/uploads/ipod-sonos-300x175.jpg" alt="" title="sonos on the itouch" width="300" height="175" class="alignnone size-medium wp-image-215" /></a></p>
<p>I had to go through Perl dependency hell (Perl really is an abomination) to get sonosweb working on the <a href="http://www.buffalotech.com/products/network-storage/linkstation/">linkstation</a>, but it works pretty well now.</p>
<p>Throw in a little <a href="http://www.sonos.com/whattobuy/controllers/CR100/default.aspx">DD-WRT</a> and <a href="http://www.openssh.com/">ssh</a> and you can really mess with your S.O. by changing the music at home from the office.</p>
<p>Now I need to write up how I got through the seven circles of dependency hell before I forget.  It took more than a quarter to Charon.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.mrbalky.com/2008/10/24/some-things-you-do-just-because-you-can/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>What to do when iTunes hoses your USB port</title>
		<link>http://www.mrbalky.com/2008/05/02/what-to-do-when-itunes-hoses-your-usb-port/</link>
		<comments>http://www.mrbalky.com/2008/05/02/what-to-do-when-itunes-hoses-your-usb-port/#comments</comments>
		<pubDate>Fri, 02 May 2008 13:35:46 +0000</pubDate>
		<dc:creator>mrbalky</dc:creator>
				<category><![CDATA[hacks]]></category>
		<category><![CDATA[itunes]]></category>

		<guid isPermaLink="false">http://www.mrbalky.com/?p=86</guid>
		<description><![CDATA[For whatever reason, iTunes sometimes just screws up the the USB device I plug my iPod into. It&#8217;s toast, and no device will work; not the iPod, not a flash drive, nothing. No amount of being careful with iTunes and &#8220;ejecting&#8221; the iPod will help. Rebooting the computer fixes it, but this happens with such [...]]]></description>
			<content:encoded><![CDATA[<p>For whatever reason, iTunes sometimes just screws up the the USB device I plug my iPod into.  It&#8217;s toast, and no device will work; not the iPod, not a flash drive, nothing.  No amount of being careful with iTunes and &#8220;ejecting&#8221; the iPod will help.</p>
<p>Rebooting the computer fixes it, but this happens with such regularity I&#8217;d be rebooting several times a day.</p>
<p>But I discovered that if you disable the USB port/device, and then enable it again, the problem is also fixed.  Going through the device management dialogs is incredibly cumbersome, so I wrote a script.</p>
<p>fixusb.bat:</p>
<pre>
<code>@echo off
echo "disabling usb device..."
devcon disable "@USB\VID_0424&amp;PID_2504\5&amp;18F4DAC0&amp;0&amp;5"
echo.
echo "enabling usb device..."
devcon enable "@USB\VID_0424&amp;PID_2504\5&amp;18F4DAC0&amp;0&amp;5"
echo.
pause</code>
</pre>
<p>The <code>@USB\VID_...</code> bit is the USB device ID.  To get the device ID, you&#8217;ll have to go to the Device Manager dialog.  Figure out which device the iPod is attached to (I don&#8217;t remember exactly how I did this; sorry).  Then on the &#8220;Details&#8221; tab of the device &#8220;Properties&#8221; dialog you can get the &#8220;Device Instance Id&#8221;.</p>
<p>I have to use this all the time, so put a shortcut to it on the desktop.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.mrbalky.com/2008/05/02/what-to-do-when-itunes-hoses-your-usb-port/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Presta inflator on the cheap</title>
		<link>http://www.mrbalky.com/2008/04/10/instructables/</link>
		<comments>http://www.mrbalky.com/2008/04/10/instructables/#comments</comments>
		<pubDate>Thu, 10 Apr 2008 19:15:22 +0000</pubDate>
		<dc:creator>mrbalky</dc:creator>
				<category><![CDATA[bike]]></category>
		<category><![CDATA[hacks]]></category>

		<guid isPermaLink="false">http://www.mrbalky.com/2008/04/10/instructables/</guid>
		<description><![CDATA[One of the best things I got from my brother when he moved out of his huge house into a small apartment was his compressor. It&#8217;s amazing how useful air is. So most bike tires these days have presta valves, which are not nearly so easy to deal with as schraeder valves like those on [...]]]></description>
			<content:encoded><![CDATA[<p>One of the best things I got from my brother when he moved out of his huge house into a small apartment was his compressor.  It&#8217;s amazing how useful air is.</p>
<p>So most bike tires these days have <a href="http://en.wikipedia.org/wiki/Presta_valve">presta valves</a>, which are not nearly so easy to deal with as <a href="http://en.wikipedia.org/wiki/Schrader_valve">schraeder valves</a> like those on cars.  There are adapters that sort of convert presta to schraeder, but they&#8217;re kind of a cumbersome, and I wanted something more convenient.  Surfing around, I found <a href="http://www.prestaflator.com/">a tool</a> that does it commercially available for $50.</p>
<p>But since I already have a blower tool, and I&#8217;m terminally cheap, I decided to try build one for less.</p>
<p>Voila:<br />
<img src='http://www.mrbalky.com/wp-content/uploads/5.jpg' alt='5.jpg' /></p>
<p>And just screwing around a little, I turned it into an <a href="http://www.instructables.com/id/Presta-and-schraeder-compressor-tool/">Instructable</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.mrbalky.com/2008/04/10/instructables/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Custom iPod Touch icon</title>
		<link>http://www.mrbalky.com/2008/01/18/custom-ipod-touch-icon/</link>
		<comments>http://www.mrbalky.com/2008/01/18/custom-ipod-touch-icon/#comments</comments>
		<pubDate>Fri, 18 Jan 2008 15:44:26 +0000</pubDate>
		<dc:creator>mrbalky</dc:creator>
				<category><![CDATA[hacks]]></category>
		<category><![CDATA[tips]]></category>

		<guid isPermaLink="false">http://www.mrbalky.com/2008/01/18/custom-ipod-touch-icon/</guid>
		<description><![CDATA[Thanks to a post over at Laughing Squid, bookmark MrBalky on your iPod Touch (or the less cool iPhone) and revel in the awesomeness: Of course, everyone is doing it.]]></description>
			<content:encoded><![CDATA[<p>Thanks to a <a href="http://laughingsquid.com/creating-a-custom-iphone-webclip-icon-for-your-website/">post</a> over at <a href="http://laughingsquid.com/">Laughing Squid</a>, bookmark MrBalky on your iPod Touch (or the less cool iPhone) and revel in the awesomeness:</p>
<p><img src='http://www.mrbalky.com/wp-content/uploads/2008/01/ipod.jpg' alt='itouch' /></p>
<p>Of course, <a href="http://www.boingboing.net/2008/01/17/boing-boing-iphoneip.html">everyone</a> is <a href="http://vjarmy.com/archives/2008/01/howto_iphone_webclip_icons.php">doing</a> <a href="http://playgroundblues.com/posts/2008/jan/15/iphone-bookmark-iconage/">it</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.mrbalky.com/2008/01/18/custom-ipod-touch-icon/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The TiVo widget</title>
		<link>http://www.mrbalky.com/2008/01/02/the-tivo-widget/</link>
		<comments>http://www.mrbalky.com/2008/01/02/the-tivo-widget/#comments</comments>
		<pubDate>Wed, 02 Jan 2008 16:04:30 +0000</pubDate>
		<dc:creator>mrbalky</dc:creator>
				<category><![CDATA[hacks]]></category>
		<category><![CDATA[tivo]]></category>

		<guid isPermaLink="false">http://www.mrbalky.com/2008/01/02/the-tivo-widget/</guid>
		<description><![CDATA[The TiVo now playing list has been a &#8220;feature&#8221; on the right-hand side of this blog for a couple years now. Todd has been admiring it for his blog for some time, but the poor fellow only had Series 3 TiVos, which had networking features turned off so he couldn&#8217;t do the same. Now that [...]]]></description>
			<content:encoded><![CDATA[<p>The <a href="http://www.mrbalky.com/mrbalky/tivo/?tivo=cew">TiVo now playing list</a> has been a &#8220;feature&#8221; on the right-hand side of this blog for a couple years now.</p>
<p><a href="http://falseprecision.typepad.com/">Todd</a> has been admiring it for his blog for some time, but the poor fellow only had <a href="https://www3.tivo.com/store/boxdetails.do?boxName=300hourseries3hd&#038;boxsku=R64825">Series 3 TiVos</a>, which had networking features turned off so he couldn&#8217;t do the same.  Now that TiVo has seen fit to turn that feature on in the S3s, I found I had to clean up the code so he could <a href="http://falseprecision.typepad.com/my_weblog/2007/12/tivo-blog-widge.html">use it</a> over on his blog.</p>
<p>As Todd says, sometimes you have to build things just because you can.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.mrbalky.com/2008/01/02/the-tivo-widget/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SAC alert &#8220;application&#8221;</title>
		<link>http://www.mrbalky.com/2007/12/18/sac-alert-widget/</link>
		<comments>http://www.mrbalky.com/2007/12/18/sac-alert-widget/#comments</comments>
		<pubDate>Tue, 18 Dec 2007 20:39:21 +0000</pubDate>
		<dc:creator>mrbalky</dc:creator>
				<category><![CDATA[hacks]]></category>

		<guid isPermaLink="false">http://www.mrbalky.com/2007/12/18/sac-alert-widget/</guid>
		<description><![CDATA[During the recovery from my previously mentioned osteotomy, I&#8217;ve been spending lots of time chatting with my physical therapist Larry Meyer. He&#8217;s an interesting and personable guy (and is really handling my PT well). In my dozens of appointments, we&#8217;ve talked about lots of stuff, including Lijit, Christmas presents, and something near and very dear [...]]]></description>
			<content:encoded><![CDATA[<p>During the recovery from my previously mentioned osteotomy, I&#8217;ve been spending lots of time chatting with my physical therapist Larry Meyer.  He&#8217;s an interesting and personable guy (and is really handling my PT well).  In my dozens of appointments, we&#8217;ve talked about lots of stuff, including <a href="http://www.lijit.com/">Lijit</a>, Christmas presents, and something near and very dear to me, bargain hunting.</p>
<p>Along the way, I mentioned <a href="http://www.steepandcheap.com/">Steep &#038; Cheap</a>, which is basically like the <a href="http://www.woot.com">woot</a> of outdoor gear.  They have single deal after single deal, about every 20 minutes or so, all day long.  It&#8217;s fine for me because I work at a computer all day long and can see each deal as soon as it is posted.  But Larry is not at a computer, though he does have access to one.</p>
<p>What Larry does have, though, is a pager with an email address.  It got me to thinking, so I hacked together a little PHP code, mixed it gently with <a href="http://www.cygwin.com">cygwin</a> cron, to poll the SAC deal feed.  If the deal changes, the application will send him a page.</p>
<p>So far, he&#8217;s not tired of the constant buzzing on his hip.</p>
<p>Here it is.  <em>Standard disclaimer applies: this is quick n’ dirty(tm)</em>:</p>
<pre>
<code>&lt;?
// Requires PEAR::Mail
require_once( 'Mail.php' );

$sac_rss = "http://www.steepandcheap.com/steepcheap/rss.xml";
$item_element = "ITEM";
$have_item = FALSE;
$in_item = FALSE;
$current_element = "";
$message = "";
$statusFile = "sacdeal.txt";

$to_list = array( "pager_email_address" );

$from = 'SAC Alert &lt;sacalert@my.hosting.company&gt;';
$subject = 'SAC deal alert';

$host = 'smtp.server.name';
$username = 'smtp.userid';
$password = 'smtp.password';

$to = "";
foreach( $to_list as $emailaddy )
{
  $to .= "$emailaddy, ";
}
echo "$to\n";

function startElement( $parser, $name, $attrs )
{
  global $current_element, $have_item, $in_item, $item_element;
  $current_element = $name;
  if ( $name == $item_element )
    $in_item = TRUE;
}

function endElement( $parser, $name )
{
  global $current_element, $have_item, $in_item, $item_element;
  $current_element = "";
  if ( $name == $item_element )
  {
    $in_item = FALSE;
    $have_item = TRUE;
  }
}

function elementData( $parser, $text )
{
  global $current_element, $have_item, $in_item, $message;
  if ( $in_item &amp;&amp; !$have_item )
  {
    // the message content is only the title or the price
    if ( $current_element == "TITLE" || $current_element == "SAC:PRICE" )
      $message .= "$text\n";
  }
}

$xml_parser = xml_parser_create();
xml_set_element_handler( $xml_parser, "startElement", "endElement" );
xml_set_character_data_handler( $xml_parser, "elementData" );

// fetch the feed content and parse it
$xml = file_get_contents( $sac_rss );
xml_parse( $xml_parser, $xml );
xml_parser_free($xml_parser);

// compare the current item in the feed to the last one we sent email about
$oldcontents = file_get_contents( $statusFile );
if ( $oldcontents != $message )
{
  $headers = array( 'From' =&gt; $from,
                    'To' =&gt; $to,
                    'Subject' =&gt; $subject );

  $smtpParams = array( 'host' =&gt; $host,
                       'auth' =&gt; true,
                       'username' =&gt; $username,
                       'password' =&gt; $password );

  $smtp = Mail::factory( 'smtp', $smtpParams );

  $mail = $smtp-&gt;send( $to, $headers, $message );

  echo $message;
  if (PEAR::isError($mail))
  {
    echo( $mail-&gt;getMessage() . "\n" );
  }
  else
  {
    echo( "Message successfully sent!\n" );
    file_put_contents( $statusFile, $message );
  }
}
else
{
  echo "same deal as last time\n";
}
?&gt;</code>
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.mrbalky.com/2007/12/18/sac-alert-widget/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
