<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:blogger="http://schemas.google.com/blogger/2008" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" gd:etag="W/&quot;AkIGSXc6fyp7ImA9WhFSEEk.&quot;"><id>tag:blogger.com,1999:blog-3441881071717960329</id><updated>2013-06-12T07:48:48.917-07:00</updated><category term="ethics" /><category term="linux" /><category term="virtualization" /><category term="podcasts" /><category term="hacks" /><category term="gadgets" /><category term="entertainment" /><category term="programming" /><category term="misc" /><category term="mods" /><title>Teknynja</title><subtitle type="html">An uneasy mix of technology, science, religion and politics.</subtitle><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://www.teknynja.com/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://www.teknynja.com/" /><author><name>teknynja</name><uri>http://www.blogger.com/profile/04303366246283189216</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://bp1.blogger.com/_PabczFx81lo/R_oxf3Xq9DI/AAAAAAAAAAQ/GyX6b5FTGRY/S220/profile.png" /></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>23</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/Teknynja" /><feedburner:info uri="teknynja" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry gd:etag="W/&quot;AkIGSXc5cCp7ImA9WhFSEEk.&quot;"><id>tag:blogger.com,1999:blog-3441881071717960329.post-6028822014961343954</id><published>2013-06-09T14:05:00.000-07:00</published><updated>2013-06-12T07:48:48.928-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2013-06-12T07:48:48.928-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="linux" /><category scheme="http://www.blogger.com/atom/ns#" term="virtualization" /><title>Making kvm/qemu/libvirt Play Nice with PulseAudio on a Headless Ubuntu 12.04 Server</title><content type="html">
I've been running over a dozen virtual machines on my headless server for almost two years now, and for all that time I've always missed being able to hear the audio from those machines.  I would occasionally try to figure out how to make audio work over VNC, but never could find a solution on the Internet.  Finally last week I decided to at least get part-way there by getting the audio to play on the server's speaker port.

The first step was pretty easy – installing &lt;a href="http://www.pulseaudio.org/" target="_blank"&gt;PulseAudio&lt;/a&gt; on the server:

&lt;!-- HTML generated using hilite.me --&gt;&lt;div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"&gt;&lt;pre style="margin: 0; line-height: 125%"&gt;sudo apt-get install pulseaudio
&lt;/pre&gt;&lt;/div&gt;&lt;br/&gt;

Now from what I could gather on the Internet, it seems like I needed to run PulseAudio in system mode, despite all the warnings that it should probably not be run that way.  I figured that since I don't usually have any logged in users on the system, it would just be better to have it running all the time.  In order to do that, I edited the &lt;tt&gt;/etc/default/pulseaudio&lt;/tt&gt; file, and changed the following settings to:
&lt;br/&gt;&lt;br/&gt;

&lt;!-- HTML generated using hilite.me --&gt;&lt;div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"&gt;&lt;pre style="margin: 0; line-height: 125%"&gt;PULSEAUDIO_SYSTEM_START=1
DISALLOW_MODULE_LOADING=1
&lt;/pre&gt;&lt;/div&gt;&lt;br/&gt;

Then I added my user and the &lt;tt&gt;libvirt-qemu&lt;/tt&gt; user to the &lt;tt&gt;pulse-access&lt;/tt&gt; group:
&lt;br/&gt;&lt;br/&gt;

&lt;!-- HTML generated using hilite.me --&gt;&lt;div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"&gt;&lt;pre style="margin: 0; line-height: 125%"&gt;sudo adduser myuser pulse-access
sudo adduser libvirt-qemu pulse-access
&lt;/pre&gt;&lt;/div&gt;&lt;br/&gt;

You'll need to log out and back in again for the new group to be picked up on your shell.  Finally, I started the PulseAudio service:
&lt;br/&gt;&lt;br/&gt;

&lt;!-- HTML generated using hilite.me --&gt;&lt;div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"&gt;&lt;pre style="margin: 0; line-height: 125%"&gt;sudo service pulseaudio start
&lt;/pre&gt;&lt;/div&gt;&lt;br/&gt;

Now a quick test to make sure the sound subsystem was working:
&lt;br/&gt;&lt;br/&gt;

&lt;!-- HTML generated using hilite.me --&gt;&lt;div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"&gt;&lt;pre style="margin: 0; line-height: 125%"&gt;paplay test-sound.wav
&lt;/pre&gt;&lt;/div&gt;&lt;br/&gt;

In my case, I could barely hear the sound playing, so I did a &lt;tt&gt;pactl list sinks&lt;/tt&gt; to figure out which sink was being used, then issued &lt;tt&gt;pactl set-sink-volume 1 100%&lt;/tt&gt; to set the volume level of sink 1 to the maximum.  Now I could hear the sound just fine!
&lt;br/&gt;&lt;br/&gt;

The next hurdle was to get the sound from the virtual machines to play through PulseAudio.  It turns out there are quite a few obstacles to achieving that goal.  First off, libvirt automatically disables audio if you are using a VNC client!  It turns out to be fairly simple to fix that though, simply edit &lt;tt&gt;/etc/libvirt/qemu.conf&lt;/tt&gt; and change the following setting to:
&lt;br/&gt;&lt;br/&gt;

&lt;!-- HTML generated using hilite.me --&gt;&lt;div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"&gt;&lt;pre style="margin: 0; line-height: 125%"&gt;vnc_allow_host_audio = 1
&lt;/pre&gt;&lt;/div&gt;&lt;br/&gt;

Now I could see in the syslog file that libvirt/kvm was trying to use the PulseAudio subsytem, but &lt;a href="http://wiki.apparmor.net/index.php/Main_Page/" target="_blank"&gt;apparmor&lt;/a&gt; was blocking access to several key files/directories.  I never did find a working answer by Googling, but I worked out the following settings for the &lt;tt&gt;/etc/apparmor.d/abstractions/libvirt-qemu&lt;/tt&gt; file.  I changed &lt;tt&gt;/{dev,run}/shm r,&lt;/tt&gt; to &lt;tt&gt;/{dev,run}/shm rw,&lt;/tt&gt; then added &lt;tt&gt;/{dev,run}/shm/pulse* rw,&lt;/tt&gt; right after that line.  Finally I added &lt;tt&gt;/var/lib/libvirt/.pulse-cookie rwk,&lt;/tt&gt; (&lt;i&gt;note the trailing commas on those lines!&lt;/i&gt;) then told apparmor to reload the configuration:
&lt;br/&gt;&lt;br/&gt;

&lt;!-- HTML generated using hilite.me --&gt;&lt;div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"&gt;&lt;pre style="margin: 0; line-height: 125%"&gt;sudo invoke-rc.d apparmor reload
&lt;/pre&gt;&lt;/div&gt;&lt;br/&gt;

I fired off a Windows XP x32 guest, and was able to hear sound, but it was very distorted and choppy.  The solution to that was to change the sound hardware in the virtual machine's configuration file from &lt;tt&gt;&amp;lt;sound model='ac97'&amp;gt;&lt;/tt&gt; to &lt;tt&gt;&amp;lt;sound model='es1370'&amp;gt;&lt;/tt&gt;.  After that, I was getting perfect sound from my virtual machine!
&lt;br/&gt;&lt;br/&gt;
Now for a few caveats – it seems that changing any of the PulseAudio configuration or restarting the service while the virtual machine is running can cause problems like the sound no longer working, all the way to the virtual machine's OS hanging up trying to play sounds.  So once you started your virtual machine, leave things alone!  I have also been working on trying to forward the sound over the network to my workstation, but so far I am having mixed results with that.  Hopefully I'll have another post soon describing how to make that work.
&lt;br/&gt;&lt;br/&gt;
And here is the usual warning that goes with tweaking your system like this:  These instructions worked for me, but your mileage may vary.  Also, I won't be responsible if any of this causes your machine to stop working or catch on fire – but this stuff should be pretty straight-forward and not cause any serious issues that can't be reversed.  Hopefully my adventure will help you to enjoy hearing from your virtual machines.  If you have any questions or corrections, please feel free to post them in the comments.&lt;img src="http://feeds.feedburner.com/~r/Teknynja/~4/w4QXEOApZPQ" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.teknynja.com/feeds/6028822014961343954/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3441881071717960329&amp;postID=6028822014961343954" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3441881071717960329/posts/default/6028822014961343954?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3441881071717960329/posts/default/6028822014961343954?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Teknynja/~3/w4QXEOApZPQ/making-kvmqemulibvirt-play-nice-with.html" title="Making kvm/qemu/libvirt Play Nice with PulseAudio on a Headless Ubuntu 12.04 Server" /><author><name>teknynja</name><uri>http://www.blogger.com/profile/04303366246283189216</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://bp1.blogger.com/_PabczFx81lo/R_oxf3Xq9DI/AAAAAAAAAAQ/GyX6b5FTGRY/S220/profile.png" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.teknynja.com/2013/06/making-kvmqemulibvirt-play-nice-with.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkIGQ386eip7ImA9WhBaFkU.&quot;"><id>tag:blogger.com,1999:blog-3441881071717960329.post-8225924469321582568</id><published>2013-05-27T13:58:00.000-07:00</published><updated>2013-05-27T14:02:02.112-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2013-05-27T14:02:02.112-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="linux" /><category scheme="http://www.blogger.com/atom/ns#" term="programming" /><title>Time-Lapse Video Capture From Network Cameras (Linux)</title><content type="html">I have several network cameras watching the outside of my home, monitored by &lt;a href="http://www.zoneminder.com/" target="_blank"&gt;ZoneMinder&lt;/a&gt;. I have it set up so that when there is motion detected, it will record for several seconds and send me an email with stills of the incident. While this is nice and gives me a little peace-of-mind, I've always thought about having it record continuously. While it is easy enough to do in ZoneMinder, I didn't really want to use up that much storage recording video and then have to scroll through it to find anything interesting.&lt;br /&gt;
&lt;br /&gt;
The other day I saw a blog post where someone was using a Raspberry Pi and a webcam to do some time-lapse photography, and that sparked an idea that seemed easy enough to do in an afternoon – I could come up with a Python script to grab images from the network cameras at fixed intervals, and write them to a video file in order to generate a time-lapse video!&lt;br /&gt;
&lt;br /&gt;
The first step was to figure out how to build a video file a frame at a time using Python. I had played with the motion-jpeg (&lt;a href="http://en.wikipedia.org/wiki/Motion_JPEG" target="_blank"&gt;mjpeg&lt;/a&gt;) format in the past, which pretty much consists of jpeg images streamed one after the other in a file (sometimes with a boundary record between them). I discovered that I could simply capture and append jpeg images to a file and get a video file that could be read by a few video players and converters. Best of all, I could use a simple avconv (formerly ffmpeg) command to convert the mjpeg files to mp4, which is smaller and viewable by almost any player.&lt;br /&gt;
&lt;br /&gt;
Next, I wanted to be able to time-stamp each image so that I could tell when the video was created. For this I stumbled across the &lt;a href="http://www.pythonware.com/products/pil/" target="_blank"&gt;Python Imaging Library (PIL)&lt;/a&gt; which supports several image formats, including jpeg. Using it, I was able to select a font and write a time-stamp on each image as it was captured before adding it to the mjpeg video file. If it isn't already installed on your system, you can install it using &lt;pre&gt;sudo apt-get install python-imaging&lt;/pre&gt; for Debian-based systems or by using the appropriate package manager for your distro.&lt;br /&gt;
&lt;br /&gt;
With all the pieces in place, I developed a little Python script that periodically grabs images from several network cameras and builds a separate mjpeg file for each of them:&lt;br /&gt;
&lt;br /&gt;
talicam.py:&lt;br /&gt;
&lt;!-- HTML generated using hilite.me --&gt;&lt;div style="background: #f8f8f8; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"&gt;&lt;pre style="margin: 0; line-height: 125%"&gt;&lt;span style="color: #8f5902; font-style: italic"&gt;#!/usr/bin/python&lt;/span&gt;

&lt;span style="color: #8f5902; font-style: italic"&gt;# Number of seconds between frames:&lt;/span&gt;
&lt;span style="color: #000000"&gt;LAPSE_TIME&lt;/span&gt; &lt;span style="color: #ce5c00; font-weight: bold"&gt;=&lt;/span&gt; &lt;span style="color: #0000cf; font-weight: bold"&gt;30&lt;/span&gt;

&lt;span style="color: #8f5902; font-style: italic"&gt;# Name of truetype font file to use for timestamps (should be a monospace font!)&lt;/span&gt;
&lt;span style="color: #000000"&gt;FONT_FILENAME&lt;/span&gt; &lt;span style="color: #ce5c00; font-weight: bold"&gt;=&lt;/span&gt; &lt;span style="color: #4e9a06"&gt;&amp;quot;UbuntuMono-B.ttf&amp;quot;&lt;/span&gt;

&lt;span style="color: #8f5902; font-style: italic"&gt;# Format of timestamp on each frame&lt;/span&gt;
&lt;span style="color: #000000"&gt;TIMESTAMP_FORMAT&lt;/span&gt; &lt;span style="color: #ce5c00; font-weight: bold"&gt;=&lt;/span&gt; &lt;span style="color: #4e9a06"&gt;&amp;quot;%Y-%m-%d %H:%M:%S&amp;quot;&lt;/span&gt;

&lt;span style="color: #8f5902; font-style: italic"&gt;# Command to batch convert mjpeg to mp4 files:&lt;/span&gt;
&lt;span style="color: #8f5902; font-style: italic"&gt;#  for f in *.mjpeg; do echo $f ; avconv -r 30000/1001 -i &amp;quot;$f&amp;quot; &amp;quot;${f%mjpeg}mp4&amp;quot; 2&amp;gt;/dev/null ; done&lt;/span&gt;

&lt;span style="color: #204a87; font-weight: bold"&gt;import&lt;/span&gt; &lt;span style="color: #000000"&gt;urllib&lt;/span&gt;
&lt;span style="color: #204a87; font-weight: bold"&gt;import&lt;/span&gt; &lt;span style="color: #000000"&gt;sys&lt;/span&gt;&lt;span style="color: #ce5c00; font-weight: bold"&gt;,&lt;/span&gt; &lt;span style="color: #000000"&gt;time&lt;/span&gt;&lt;span style="color: #ce5c00; font-weight: bold"&gt;,&lt;/span&gt; &lt;span style="color: #000000"&gt;datetime&lt;/span&gt;
&lt;span style="color: #204a87; font-weight: bold"&gt;import&lt;/span&gt; &lt;span style="color: #000000"&gt;StringIO&lt;/span&gt;
&lt;span style="color: #204a87; font-weight: bold"&gt;import&lt;/span&gt; &lt;span style="color: #000000"&gt;Image&lt;/span&gt;&lt;span style="color: #ce5c00; font-weight: bold"&gt;,&lt;/span&gt; &lt;span style="color: #000000"&gt;ImageDraw&lt;/span&gt;&lt;span style="color: #ce5c00; font-weight: bold"&gt;,&lt;/span&gt; &lt;span style="color: #000000"&gt;ImageFont&lt;/span&gt;

&lt;span style="color: #204a87; font-weight: bold"&gt;class&lt;/span&gt; &lt;span style="color: #000000"&gt;Camera&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold"&gt;:&lt;/span&gt;
    &lt;span style="color: #204a87; font-weight: bold"&gt;def&lt;/span&gt; &lt;span style="color: #000000"&gt;__init__&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold"&gt;(&lt;/span&gt;&lt;span style="color: #3465a4"&gt;self&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold"&gt;,&lt;/span&gt; &lt;span style="color: #000000"&gt;name&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold"&gt;,&lt;/span&gt; &lt;span style="color: #000000"&gt;url&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold"&gt;,&lt;/span&gt; &lt;span style="color: #000000"&gt;filename&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold"&gt;):&lt;/span&gt;
        &lt;span style="color: #3465a4"&gt;self&lt;/span&gt;&lt;span style="color: #ce5c00; font-weight: bold"&gt;.&lt;/span&gt;&lt;span style="color: #000000"&gt;name&lt;/span&gt; &lt;span style="color: #ce5c00; font-weight: bold"&gt;=&lt;/span&gt; &lt;span style="color: #000000"&gt;name&lt;/span&gt;
        &lt;span style="color: #3465a4"&gt;self&lt;/span&gt;&lt;span style="color: #ce5c00; font-weight: bold"&gt;.&lt;/span&gt;&lt;span style="color: #000000"&gt;url&lt;/span&gt; &lt;span style="color: #ce5c00; font-weight: bold"&gt;=&lt;/span&gt; &lt;span style="color: #000000"&gt;url&lt;/span&gt;
        &lt;span style="color: #3465a4"&gt;self&lt;/span&gt;&lt;span style="color: #ce5c00; font-weight: bold"&gt;.&lt;/span&gt;&lt;span style="color: #000000"&gt;filename&lt;/span&gt; &lt;span style="color: #ce5c00; font-weight: bold"&gt;=&lt;/span&gt; &lt;span style="color: #000000"&gt;filename&lt;/span&gt;
        
    &lt;span style="color: #204a87; font-weight: bold"&gt;def&lt;/span&gt; &lt;span style="color: #000000"&gt;CaptureImage&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold"&gt;(&lt;/span&gt;&lt;span style="color: #3465a4"&gt;self&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold"&gt;):&lt;/span&gt;
        &lt;span style="color: #000000"&gt;camera&lt;/span&gt; &lt;span style="color: #ce5c00; font-weight: bold"&gt;=&lt;/span&gt; &lt;span style="color: #000000"&gt;urllib&lt;/span&gt;&lt;span style="color: #ce5c00; font-weight: bold"&gt;.&lt;/span&gt;&lt;span style="color: #000000"&gt;urlopen&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold"&gt;(&lt;/span&gt;&lt;span style="color: #3465a4"&gt;self&lt;/span&gt;&lt;span style="color: #ce5c00; font-weight: bold"&gt;.&lt;/span&gt;&lt;span style="color: #000000"&gt;url&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold"&gt;)&lt;/span&gt;
        &lt;span style="color: #000000"&gt;image_buffer&lt;/span&gt; &lt;span style="color: #ce5c00; font-weight: bold"&gt;=&lt;/span&gt; &lt;span style="color: #000000"&gt;StringIO&lt;/span&gt;&lt;span style="color: #ce5c00; font-weight: bold"&gt;.&lt;/span&gt;&lt;span style="color: #000000"&gt;StringIO&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold"&gt;()&lt;/span&gt;
        &lt;span style="color: #000000"&gt;image_buffer&lt;/span&gt;&lt;span style="color: #ce5c00; font-weight: bold"&gt;.&lt;/span&gt;&lt;span style="color: #000000"&gt;write&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold"&gt;(&lt;/span&gt;&lt;span style="color: #000000"&gt;camera&lt;/span&gt;&lt;span style="color: #ce5c00; font-weight: bold"&gt;.&lt;/span&gt;&lt;span style="color: #000000"&gt;read&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold"&gt;())&lt;/span&gt;
        &lt;span style="color: #000000"&gt;image_buffer&lt;/span&gt;&lt;span style="color: #ce5c00; font-weight: bold"&gt;.&lt;/span&gt;&lt;span style="color: #000000"&gt;seek&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold"&gt;(&lt;/span&gt;&lt;span style="color: #0000cf; font-weight: bold"&gt;0&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold"&gt;)&lt;/span&gt;
        &lt;span style="color: #000000"&gt;image&lt;/span&gt; &lt;span style="color: #ce5c00; font-weight: bold"&gt;=&lt;/span&gt; &lt;span style="color: #000000"&gt;Image&lt;/span&gt;&lt;span style="color: #ce5c00; font-weight: bold"&gt;.&lt;/span&gt;&lt;span style="color: #000000"&gt;open&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold"&gt;(&lt;/span&gt;&lt;span style="color: #000000"&gt;image_buffer&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold"&gt;)&lt;/span&gt;
        &lt;span style="color: #000000"&gt;camera&lt;/span&gt;&lt;span style="color: #ce5c00; font-weight: bold"&gt;.&lt;/span&gt;&lt;span style="color: #000000"&gt;close&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold"&gt;()&lt;/span&gt;
        &lt;span style="color: #204a87; font-weight: bold"&gt;return&lt;/span&gt; &lt;span style="color: #000000"&gt;image&lt;/span&gt;
        
    &lt;span style="color: #204a87; font-weight: bold"&gt;def&lt;/span&gt; &lt;span style="color: #000000"&gt;TimestampImage&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold"&gt;(&lt;/span&gt;&lt;span style="color: #3465a4"&gt;self&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold"&gt;,&lt;/span&gt; &lt;span style="color: #000000"&gt;image&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold"&gt;):&lt;/span&gt;
        &lt;span style="color: #000000"&gt;draw_buffer&lt;/span&gt; &lt;span style="color: #ce5c00; font-weight: bold"&gt;=&lt;/span&gt; &lt;span style="color: #000000"&gt;ImageDraw&lt;/span&gt;&lt;span style="color: #ce5c00; font-weight: bold"&gt;.&lt;/span&gt;&lt;span style="color: #000000"&gt;Draw&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold"&gt;(&lt;/span&gt;&lt;span style="color: #000000"&gt;image&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold"&gt;)&lt;/span&gt;
        &lt;span style="color: #000000"&gt;font&lt;/span&gt; &lt;span style="color: #ce5c00; font-weight: bold"&gt;=&lt;/span&gt; &lt;span style="color: #000000"&gt;ImageFont&lt;/span&gt;&lt;span style="color: #ce5c00; font-weight: bold"&gt;.&lt;/span&gt;&lt;span style="color: #000000"&gt;truetype&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold"&gt;(&lt;/span&gt;&lt;span style="color: #000000"&gt;FONT_FILENAME&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold"&gt;,&lt;/span&gt; &lt;span style="color: #0000cf; font-weight: bold"&gt;16&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold"&gt;)&lt;/span&gt;
        &lt;span style="color: #000000"&gt;timestamp&lt;/span&gt; &lt;span style="color: #ce5c00; font-weight: bold"&gt;=&lt;/span&gt; &lt;span style="color: #000000"&gt;datetime&lt;/span&gt;&lt;span style="color: #ce5c00; font-weight: bold"&gt;.&lt;/span&gt;&lt;span style="color: #000000"&gt;datetime&lt;/span&gt;&lt;span style="color: #ce5c00; font-weight: bold"&gt;.&lt;/span&gt;&lt;span style="color: #000000"&gt;now&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold"&gt;()&lt;/span&gt;
        &lt;span style="color: #000000"&gt;stamptext&lt;/span&gt; &lt;span style="color: #ce5c00; font-weight: bold"&gt;=&lt;/span&gt; &lt;span style="color: #4e9a06"&gt;&amp;quot;{0} - {1}&amp;quot;&lt;/span&gt;&lt;span style="color: #ce5c00; font-weight: bold"&gt;.&lt;/span&gt;&lt;span style="color: #000000"&gt;format&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold"&gt;(&lt;/span&gt;&lt;span style="color: #000000"&gt;timestamp&lt;/span&gt;&lt;span style="color: #ce5c00; font-weight: bold"&gt;.&lt;/span&gt;&lt;span style="color: #000000"&gt;strftime&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold"&gt;(&lt;/span&gt;&lt;span style="color: #000000"&gt;TIMESTAMP_FORMAT&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold"&gt;),&lt;/span&gt; &lt;span style="color: #3465a4"&gt;self&lt;/span&gt;&lt;span style="color: #ce5c00; font-weight: bold"&gt;.&lt;/span&gt;&lt;span style="color: #000000"&gt;name&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold"&gt;)&lt;/span&gt;
        &lt;span style="color: #000000"&gt;draw_buffer&lt;/span&gt;&lt;span style="color: #ce5c00; font-weight: bold"&gt;.&lt;/span&gt;&lt;span style="color: #000000"&gt;text&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold"&gt;((&lt;/span&gt;&lt;span style="color: #0000cf; font-weight: bold"&gt;5&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold"&gt;,&lt;/span&gt; &lt;span style="color: #0000cf; font-weight: bold"&gt;5&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold"&gt;),&lt;/span&gt; &lt;span style="color: #000000"&gt;stamptext&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold"&gt;,&lt;/span&gt; &lt;span style="color: #000000"&gt;font&lt;/span&gt;&lt;span style="color: #ce5c00; font-weight: bold"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;font&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold"&gt;)&lt;/span&gt;

    &lt;span style="color: #204a87; font-weight: bold"&gt;def&lt;/span&gt; &lt;span style="color: #000000"&gt;SaveImage&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold"&gt;(&lt;/span&gt;&lt;span style="color: #3465a4"&gt;self&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold"&gt;,&lt;/span&gt; &lt;span style="color: #000000"&gt;image&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold"&gt;):&lt;/span&gt;
        &lt;span style="color: #204a87; font-weight: bold"&gt;with&lt;/span&gt; &lt;span style="color: #204a87"&gt;open&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold"&gt;(&lt;/span&gt;&lt;span style="color: #3465a4"&gt;self&lt;/span&gt;&lt;span style="color: #ce5c00; font-weight: bold"&gt;.&lt;/span&gt;&lt;span style="color: #000000"&gt;filename&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold"&gt;,&lt;/span&gt; &lt;span style="color: #4e9a06"&gt;&amp;quot;a+b&amp;quot;&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold"&gt;)&lt;/span&gt; &lt;span style="color: #204a87; font-weight: bold"&gt;as&lt;/span&gt; &lt;span style="color: #000000"&gt;video_file&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold"&gt;:&lt;/span&gt;
            &lt;span style="color: #000000"&gt;image&lt;/span&gt;&lt;span style="color: #ce5c00; font-weight: bold"&gt;.&lt;/span&gt;&lt;span style="color: #000000"&gt;save&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold"&gt;(&lt;/span&gt;&lt;span style="color: #000000"&gt;video_file&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold"&gt;,&lt;/span&gt; &lt;span style="color: #4e9a06"&gt;&amp;quot;JPEG&amp;quot;&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold"&gt;)&lt;/span&gt;
            &lt;span style="color: #000000"&gt;video_file&lt;/span&gt;&lt;span style="color: #ce5c00; font-weight: bold"&gt;.&lt;/span&gt;&lt;span style="color: #000000"&gt;flush&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold"&gt;()&lt;/span&gt;

    &lt;span style="color: #204a87; font-weight: bold"&gt;def&lt;/span&gt; &lt;span style="color: #000000"&gt;Update&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold"&gt;(&lt;/span&gt;&lt;span style="color: #3465a4"&gt;self&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold"&gt;):&lt;/span&gt;
        &lt;span style="color: #000000"&gt;image&lt;/span&gt; &lt;span style="color: #ce5c00; font-weight: bold"&gt;=&lt;/span&gt; &lt;span style="color: #3465a4"&gt;self&lt;/span&gt;&lt;span style="color: #ce5c00; font-weight: bold"&gt;.&lt;/span&gt;&lt;span style="color: #000000"&gt;CaptureImage&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold"&gt;()&lt;/span&gt;
        &lt;span style="color: #3465a4"&gt;self&lt;/span&gt;&lt;span style="color: #ce5c00; font-weight: bold"&gt;.&lt;/span&gt;&lt;span style="color: #000000"&gt;TimestampImage&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold"&gt;(&lt;/span&gt;&lt;span style="color: #000000"&gt;image&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold"&gt;)&lt;/span&gt;
        &lt;span style="color: #3465a4"&gt;self&lt;/span&gt;&lt;span style="color: #ce5c00; font-weight: bold"&gt;.&lt;/span&gt;&lt;span style="color: #000000"&gt;SaveImage&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold"&gt;(&lt;/span&gt;&lt;span style="color: #000000"&gt;image&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold"&gt;)&lt;/span&gt;
        &lt;span style="color: #204a87; font-weight: bold"&gt;print&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold"&gt;(&lt;/span&gt;&lt;span style="color: #4e9a06"&gt;&amp;quot;Captured image from {0} camera to {1}&amp;quot;&lt;/span&gt;&lt;span style="color: #ce5c00; font-weight: bold"&gt;.&lt;/span&gt;&lt;span style="color: #000000"&gt;format&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold"&gt;(&lt;/span&gt;&lt;span style="color: #3465a4"&gt;self&lt;/span&gt;&lt;span style="color: #ce5c00; font-weight: bold"&gt;.&lt;/span&gt;&lt;span style="color: #000000"&gt;name&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold"&gt;,&lt;/span&gt; &lt;span style="color: #3465a4"&gt;self&lt;/span&gt;&lt;span style="color: #ce5c00; font-weight: bold"&gt;.&lt;/span&gt;&lt;span style="color: #000000"&gt;filename&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold"&gt;))&lt;/span&gt;


&lt;span style="color: #204a87; font-weight: bold"&gt;if&lt;/span&gt; &lt;span style="color: #000000"&gt;__name__&lt;/span&gt; &lt;span style="color: #ce5c00; font-weight: bold"&gt;==&lt;/span&gt; &lt;span style="color: #4e9a06"&gt;&amp;quot;__main__&amp;quot;&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold"&gt;:&lt;/span&gt;
    &lt;span style="color: #000000"&gt;cameras&lt;/span&gt; &lt;span style="color: #ce5c00; font-weight: bold"&gt;=&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold"&gt;[]&lt;/span&gt;
    &lt;span style="color: #000000"&gt;cameras&lt;/span&gt;&lt;span style="color: #ce5c00; font-weight: bold"&gt;.&lt;/span&gt;&lt;span style="color: #000000"&gt;append&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold"&gt;(&lt;/span&gt;&lt;span style="color: #000000"&gt;Camera&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold"&gt;(&lt;/span&gt;&lt;span style="color: #4e9a06"&gt;&amp;quot;porch&amp;quot;&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold"&gt;,&lt;/span&gt; &lt;span style="color: #4e9a06"&gt;&amp;quot;http://username:password@10.17.42.172/SnapshotJPEG?Resolution=640x480&amp;amp;Quality=Clarity&amp;quot;&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold"&gt;,&lt;/span&gt; &lt;span style="color: #4e9a06"&gt;&amp;quot;cam1.mjpeg&amp;quot;&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold"&gt;))&lt;/span&gt;
    &lt;span style="color: #000000"&gt;cameras&lt;/span&gt;&lt;span style="color: #ce5c00; font-weight: bold"&gt;.&lt;/span&gt;&lt;span style="color: #000000"&gt;append&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold"&gt;(&lt;/span&gt;&lt;span style="color: #000000"&gt;Camera&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold"&gt;(&lt;/span&gt;&lt;span style="color: #4e9a06"&gt;&amp;quot;driveway&amp;quot;&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold"&gt;,&lt;/span&gt; &lt;span style="color: #4e9a06"&gt;&amp;quot;http://username:password@10.17.42.174/SnapshotJPEG?Resolution=640x480&amp;amp;Quality=Clarity&amp;quot;&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold"&gt;,&lt;/span&gt; &lt;span style="color: #4e9a06"&gt;&amp;quot;cam2.mjpeg&amp;quot;&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold"&gt;))&lt;/span&gt;
    &lt;span style="color: #000000"&gt;cameras&lt;/span&gt;&lt;span style="color: #ce5c00; font-weight: bold"&gt;.&lt;/span&gt;&lt;span style="color: #000000"&gt;append&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold"&gt;(&lt;/span&gt;&lt;span style="color: #000000"&gt;Camera&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold"&gt;(&lt;/span&gt;&lt;span style="color: #4e9a06"&gt;&amp;quot;backyard&amp;quot;&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold"&gt;,&lt;/span&gt; &lt;span style="color: #4e9a06"&gt;&amp;quot;http://username:password@10.17.42.173/SnapshotJPEG?Resolution=640x480&amp;amp;Quality=Clarity&amp;quot;&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold"&gt;,&lt;/span&gt; &lt;span style="color: #4e9a06"&gt;&amp;quot;cam3.mjpeg&amp;quot;&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold"&gt;))&lt;/span&gt;
    &lt;span style="color: #000000"&gt;cameras&lt;/span&gt;&lt;span style="color: #ce5c00; font-weight: bold"&gt;.&lt;/span&gt;&lt;span style="color: #000000"&gt;append&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold"&gt;(&lt;/span&gt;&lt;span style="color: #000000"&gt;Camera&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold"&gt;(&lt;/span&gt;&lt;span style="color: #4e9a06"&gt;&amp;quot;sideyard&amp;quot;&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold"&gt;,&lt;/span&gt; &lt;span style="color: #4e9a06"&gt;&amp;quot;http://10.17.42.176/image/jpeg.cgi&amp;quot;&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold"&gt;,&lt;/span&gt; &lt;span style="color: #4e9a06"&gt;&amp;quot;cam4.mjpeg&amp;quot;&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold"&gt;))&lt;/span&gt;
    &lt;span style="color: #000000"&gt;cameras&lt;/span&gt;&lt;span style="color: #ce5c00; font-weight: bold"&gt;.&lt;/span&gt;&lt;span style="color: #000000"&gt;append&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold"&gt;(&lt;/span&gt;&lt;span style="color: #000000"&gt;Camera&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold"&gt;(&lt;/span&gt;&lt;span style="color: #4e9a06"&gt;&amp;quot;stairway&amp;quot;&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold"&gt;,&lt;/span&gt; &lt;span style="color: #4e9a06"&gt;&amp;quot;http://10.17.42.175/image/jpeg.cgi&amp;quot;&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold"&gt;,&lt;/span&gt; &lt;span style="color: #4e9a06"&gt;&amp;quot;cam5.mjpeg&amp;quot;&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold"&gt;))&lt;/span&gt;
    
    &lt;span style="color: #204a87; font-weight: bold"&gt;print&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold"&gt;(&lt;/span&gt;&lt;span style="color: #4e9a06"&gt;&amp;quot;Capturing images from {0} cameras every {1} seconds...&amp;quot;&lt;/span&gt;&lt;span style="color: #ce5c00; font-weight: bold"&gt;.&lt;/span&gt;&lt;span style="color: #000000"&gt;format&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold"&gt;(&lt;/span&gt;&lt;span style="color: #204a87"&gt;len&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold"&gt;(&lt;/span&gt;&lt;span style="color: #000000"&gt;cameras&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold"&gt;),&lt;/span&gt; &lt;span style="color: #000000"&gt;LAPSE_TIME&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold"&gt;))&lt;/span&gt;
    
    &lt;span style="color: #204a87; font-weight: bold"&gt;try&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold"&gt;:&lt;/span&gt;
        &lt;span style="color: #204a87; font-weight: bold"&gt;while&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold"&gt;(&lt;/span&gt;&lt;span style="color: #3465a4"&gt;True&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold"&gt;):&lt;/span&gt;
            &lt;span style="color: #204a87; font-weight: bold"&gt;for&lt;/span&gt; &lt;span style="color: #000000"&gt;camera&lt;/span&gt; &lt;span style="color: #204a87; font-weight: bold"&gt;in&lt;/span&gt; &lt;span style="color: #000000"&gt;cameras&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold"&gt;:&lt;/span&gt;
                &lt;span style="color: #000000"&gt;camera&lt;/span&gt;&lt;span style="color: #ce5c00; font-weight: bold"&gt;.&lt;/span&gt;&lt;span style="color: #000000"&gt;Update&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold"&gt;()&lt;/span&gt;
                
            &lt;span style="color: #000000"&gt;time&lt;/span&gt;&lt;span style="color: #ce5c00; font-weight: bold"&gt;.&lt;/span&gt;&lt;span style="color: #000000"&gt;sleep&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold"&gt;(&lt;/span&gt;&lt;span style="color: #000000"&gt;LAPSE_TIME&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold"&gt;)&lt;/span&gt;
            
    &lt;span style="color: #204a87; font-weight: bold"&gt;except&lt;/span&gt; &lt;span style="color: #cc0000; font-weight: bold"&gt;KeyboardInterrupt&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold"&gt;:&lt;/span&gt;
        &lt;span style="color: #204a87; font-weight: bold"&gt;print&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold"&gt;(&lt;/span&gt;&lt;span style="color: #4e9a06"&gt;&amp;quot;\nExit requested, terminating normally&amp;quot;&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold"&gt;)&lt;/span&gt;
        &lt;span style="color: #000000"&gt;sys&lt;/span&gt;&lt;span style="color: #ce5c00; font-weight: bold"&gt;.&lt;/span&gt;&lt;span style="color: #000000"&gt;exit&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold"&gt;(&lt;/span&gt;&lt;span style="color: #0000cf; font-weight: bold"&gt;0&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;br /&gt;
Notice the URLs supplied in the Camera constructors.  These are specific to each brand of camera, but you can usually find the format with a little Googling.  In my program above, the first three cameras are &lt;b&gt;Panasonic BL-C101A&lt;/b&gt; network cameras, the last two are a &lt;b&gt;D-Link DCS-930L&lt;/b&gt; and a &lt;b&gt;TrendNet TV-IP551W&lt;/b&gt; which both have very similar software and URLs.&lt;br /&gt;
&lt;br /&gt;
The font file referenced above needs to be located in the same directory as the Python script, and for best results should be a mono-space font.  I just grabbed the &lt;a href="http://font.ubuntu.com/" target="_blank"&gt;Ubuntu Monospace Bold&lt;/a&gt; TrueType font file for use here, but you could use anything you like.&lt;br /&gt;
&lt;br /&gt;
You will probably want to launch this as a background task so that it can run for extended periods of time. I have it running on the same server that runs my ZoneMinder setup, so it can run 24-7 collecting time-lapse video. I also wrote a quick little script file that iterates the mjpeg files it finds and converts them to mp4 for easier viewing and archiving:&lt;br /&gt;
&lt;br /&gt;
mjpeg2mp4:&lt;br /&gt;
&lt;!-- HTML generated using hilite.me --&gt;&lt;div style="background: #f8f8f8; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"&gt;&lt;pre style="margin: 0; line-height: 125%"&gt;&lt;span style="color: #8f5902; font-style: italic"&gt;#!/bin/bash&lt;/span&gt;

&lt;span style="color: #204a87"&gt;echo&lt;/span&gt; &lt;span style="color: #4e9a06"&gt;&amp;quot;Removing old files...&amp;quot;&lt;/span&gt;
rm -fv *.mp4

&lt;span style="color: #204a87"&gt;echo&lt;/span&gt; &lt;span style="color: #4e9a06"&gt;&amp;quot;Converting files to mp4...&amp;quot;&lt;/span&gt;
&lt;span style="color: #204a87; font-weight: bold"&gt;for &lt;/span&gt;f in *.mjpeg ; &lt;span style="color: #204a87; font-weight: bold"&gt;do&lt;/span&gt;
&lt;span style="color: #204a87; font-weight: bold"&gt;    &lt;/span&gt;&lt;span style="color: #000000"&gt;t&lt;/span&gt;&lt;span style="color: #ce5c00; font-weight: bold"&gt;=&lt;/span&gt;&lt;span style="color: #204a87; font-weight: bold"&gt;${&lt;/span&gt;&lt;span style="color: #000000"&gt;f&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold"&gt;%mjpeg&lt;/span&gt;&lt;span style="color: #204a87; font-weight: bold"&gt;}&lt;/span&gt;mp4
    &lt;span style="color: #204a87"&gt;echo&lt;/span&gt; &lt;span style="color: #4e9a06"&gt;&amp;quot;  Converting $f to $t&amp;quot;&lt;/span&gt;
    avconv -r 30000/1001 -i &lt;span style="color: #4e9a06"&gt;&amp;quot;$f&amp;quot;&lt;/span&gt; -q 5 &lt;span style="color: #4e9a06"&gt;&amp;quot;$t&amp;quot;&lt;/span&gt; 2&amp;gt;/dev/null
&lt;span style="color: #204a87; font-weight: bold"&gt;done&lt;/span&gt;

&lt;span style="color: #204a87"&gt;echo&lt;/span&gt; &lt;span style="color: #4e9a06"&gt;&amp;quot;Done!&amp;quot;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;br /&gt;
I had a lot of fun learning a few new tricks while working on this, and hopefully you can use it as a starting point for your own time-lapse adventure.  If you find this post useful, or have questions about how it works, please leave a comment below.&lt;img src="http://feeds.feedburner.com/~r/Teknynja/~4/uHVgbmWYeOg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.teknynja.com/feeds/8225924469321582568/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3441881071717960329&amp;postID=8225924469321582568" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3441881071717960329/posts/default/8225924469321582568?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3441881071717960329/posts/default/8225924469321582568?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Teknynja/~3/uHVgbmWYeOg/time-lapse-video-capture-from-network.html" title="Time-Lapse Video Capture From Network Cameras (Linux)" /><author><name>teknynja</name><uri>http://www.blogger.com/profile/04303366246283189216</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://bp1.blogger.com/_PabczFx81lo/R_oxf3Xq9DI/AAAAAAAAAAQ/GyX6b5FTGRY/S220/profile.png" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.teknynja.com/2013/05/time-lapse-video-capture-from-network.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CU4GRHs6cSp7ImA9WhJTFEQ.&quot;"><id>tag:blogger.com,1999:blog-3441881071717960329.post-1321926190512862297</id><published>2012-06-20T18:08:00.001-07:00</published><updated>2012-06-23T16:25:25.519-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-06-23T16:25:25.519-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="mods" /><category scheme="http://www.blogger.com/atom/ns#" term="hacks" /><title>Low-Voltage Controlled AC Power Strip</title><content type="html">&lt;br /&gt;
&lt;b&gt;NOTE: &amp;nbsp;This hack involves working with dangerous voltage levels, which can result in&amp;nbsp;&lt;/b&gt;&lt;b&gt;property damage, &lt;/b&gt;&lt;b&gt;injury, or&amp;nbsp;&lt;/b&gt;&lt;b&gt;death&lt;/b&gt;&lt;b&gt;! &amp;nbsp;Proceed at your own risk. &amp;nbsp;If you are not comfortable working with power circuits and wiring, you may want to consider using something like the &lt;a href="http://www.adafruit.com/products/268" target="_blank"&gt;PowerSwitch Tail II from Adafruit&lt;/a&gt;&amp;nbsp;instead.&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
As part of a larger project I'm working on, I needed a way to control five AC powered devices from a small microcontroller. &amp;nbsp;At work, we use &lt;a href="http://www.opto22.com/site/pr_selector.aspx?cid=7&amp;amp;qs=1003#10071003" target="_blank"&gt;Opto 22 G4 Solid State Relays&lt;/a&gt;&amp;nbsp;in our industrial control systems. &amp;nbsp;They are small and convenient to work with, but I was looking for something more compact. &amp;nbsp;Searching around the web, I noticed that many hobbyist were working with &lt;a href="http://sharp-world.com/products/device/lineup/data/pdf/datasheet/s108t02_e.pdf" target="_blank"&gt;Sharp S108T02&lt;/a&gt;&amp;nbsp;Solid State Relays, but doing a little research at &lt;a href="http://www.digikey.com/scripts/DkSearch/dksus.dll?vendor=0&amp;amp;keywords=S201S06V" target="_blank"&gt;Digikey&lt;/a&gt;&amp;nbsp;I decided to use the similar &lt;a href="http://sharp-world.com/products/device/lineup/data/pdf/datasheet/s101s06v_e.pdf" target="_blank"&gt;Sharp S201S06V&lt;/a&gt;&amp;nbsp;instead.&lt;br /&gt;
&lt;br /&gt;
&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-nI8T_qxo5_U/T-Jv5Q0mDkI/AAAAAAAAAFw/Jn9fvuvxfs8/s1600/psdiagram.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="148" src="http://4.bp.blogspot.com/-nI8T_qxo5_U/T-Jv5Q0mDkI/AAAAAAAAAFw/Jn9fvuvxfs8/s320/psdiagram.png" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;S201S06V Solid State Relay Diagram&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
Next, I needed to find a way to provide outlets to plug the controlled devices into. &amp;nbsp;I thought about using a project box and mounting three standard dual outlet wall sockets on it, then using a standard outlet cover on those. &amp;nbsp;That would work, but it would still be on the large side. &amp;nbsp;I then considered using a standard six outlet power strip. &amp;nbsp;I headed down to my local Home Depot to see what options I had there, and returned with a nice, metal cased &lt;a href="http://www.homedepot.com/Electrical-Electrical-Cords-Cord-Management-Surge-Protectors-Power-Strips-Converters/h_d1/N-5yc1vZbm60/R-100663221/h_d2/ProductDisplay" target="_blank"&gt;power strip&lt;/a&gt;. &amp;nbsp;I removed the four screws holding the bottom on and checked to see if my relays would fit:&lt;br /&gt;
&lt;br /&gt;
&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-3J2PP7hHsSw/T-Jwc6QLqUI/AAAAAAAAAF4/XtCBynBKzz8/s1600/powerstrip1.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="480" src="http://3.bp.blogspot.com/-3J2PP7hHsSw/T-Jwc6QLqUI/AAAAAAAAAF4/XtCBynBKzz8/s640/powerstrip1.jpg" width="640" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Ready for surgery&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
It looked like everything would fit! &amp;nbsp;As a bonus, mounting the relays flat against the bottom would allow the metal to act like a heat sink. &amp;nbsp;I measured to get them evenly spaced, drilled the mounting holes, and attached the relays using a bit of thermal compound for good heat transfer. &amp;nbsp;(I thought I would be able to attach the wires after the relays were mounted, but it turned out to be easier to do with them unmounted, so next time I would wait on the thermal compound).&lt;br /&gt;
&lt;br /&gt;
&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-cUU0fJp_IXw/T-Jwz7BqdcI/AAAAAAAAAGA/IryZCH05GxY/s1600/powerstrip2.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="480" src="http://2.bp.blogspot.com/-cUU0fJp_IXw/T-Jwz7BqdcI/AAAAAAAAAGA/IryZCH05GxY/s640/powerstrip2.jpg" width="640" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Power and control bus wiring&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
I started by soldering the common buses for the AC power and DC control lines, covering all the exposed wiring with heat shrink as I went. &amp;nbsp;Once I had the common wiring done, I added the individual AC output wiring using different colors for each – I picked colors that matched the low-voltage cable's colors. &amp;nbsp;For the low-voltage cable I just used the cable from an old PS/2 mouse that had a 6 pin DIN connector, which gave me 5 lines for control signals and 1 for ground. &amp;nbsp;The mouse cable works nicely here because it is long and flexible. &amp;nbsp;Before you start wiring the DC cable, &amp;nbsp;drill a hole in the upper part of the case near the power cable, big enough for an appropriate strain-relief. &amp;nbsp;Then run the cable through that hole, before you begin soldering it! &amp;nbsp;I also made sure to write down the sequence of wire colors on the DC cable that corresponded to the pin numbers on the DIN connector, so that I could attach the AC control wire colors in the same sequence.&lt;br /&gt;
&lt;br /&gt;
&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-cbRxdCcp28E/T-JxDbZ3QkI/AAAAAAAAAGI/i20bO08AhPM/s1600/powerstrip3.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="480" src="http://3.bp.blogspot.com/-cbRxdCcp28E/T-JxDbZ3QkI/AAAAAAAAAGI/i20bO08AhPM/s640/powerstrip3.jpg" width="640" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Added power control wiring&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
After getting all the AC and DC wiring attached to the solid state relays, I mounted everything to the bottom plate of the power strip, and routed the wires, with the inputs coming from the side where the power cable comes in, and the outputs at the opposite end. &amp;nbsp;As you can see, I also added some cable tie points to make sure the wires did not get pulled out or shorted.&lt;br /&gt;
&lt;br /&gt;
&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-nTeJ271ZmGQ/T-JxZyrujaI/AAAAAAAAAGQ/rTLE4B-h2vQ/s1600/powerstrip4.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="200" src="http://4.bp.blogspot.com/-nTeJ271ZmGQ/T-JxZyrujaI/AAAAAAAAAGQ/rTLE4B-h2vQ/s640/powerstrip4.jpg" width="640" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Solid state relays wired and mounted&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
Next, I removed the black “hot” bus from all but the outlet closest to the power cord, and broke the jumpers on the hot side between the top and bottom outlet of each outlet pair that connected them together. &amp;nbsp;I am leaving the outlet closest to the power cord always hot, so I have some place to plug in the project's controller. &amp;nbsp;I can still turn the entire thing on and off using the existing power switch. &amp;nbsp;Now that that the remaining five outlet's hot sides are disconnected, it's time to start wiring them up.&lt;br /&gt;
&lt;br /&gt;
Since these outlets use “slide in” connections intended for lower gauge solid core wire, and I am using smaller gauge stranded wire, I soldered the ends of the stranded wire to form a stiff end that would easily slide into the outlet connections. &amp;nbsp;You can sort of see the soldered end of the red wire in the next photo.&lt;br /&gt;
&lt;br /&gt;
&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-yaYlWiOfDnQ/T-Jxugw_3PI/AAAAAAAAAGY/y9U9-xDWsBg/s1600/powerstrip5.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="480" src="http://1.bp.blogspot.com/-yaYlWiOfDnQ/T-Jxugw_3PI/AAAAAAAAAGY/y9U9-xDWsBg/s640/powerstrip5.jpg" width="640" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Connecting the power wiring&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
Now I attach each of the AC control wires to the corresponding outlet, making sure to keep them in the same order as the relay (and DIN connector) wiring. &amp;nbsp;I cut each wire to the proper length, so that I wouldn't have a lot of extra wire to try and tuck inside. &amp;nbsp;Here it is all wired up:&lt;br /&gt;
&lt;br /&gt;
&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-hpORgKKryhc/T-JyGKEQO4I/AAAAAAAAAGg/rir7qQ1lJlY/s1600/powerstrip6.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="312" src="http://3.bp.blogspot.com/-hpORgKKryhc/T-JyGKEQO4I/AAAAAAAAAGg/rir7qQ1lJlY/s640/powerstrip6.jpg" width="640" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Ready to close&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
And now all assembled and ready to go with its new “tail”:&lt;br /&gt;
&lt;br /&gt;
&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-ZHP7C2VyZpI/T-JyVhq_XuI/AAAAAAAAAGo/_l9iT6Jx02Q/s1600/powerstrip7.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="300" src="http://3.bp.blogspot.com/-ZHP7C2VyZpI/T-JyVhq_XuI/AAAAAAAAAGo/_l9iT6Jx02Q/s640/powerstrip7.jpg" width="640" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Ready for work&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
Now I should note that the solid state relay inputs are simply LEDs, and require a current limiting resistor in series or you will destroy the devices. &amp;nbsp;In this design, those resistors are located on the controller board, but you could easily include them inside the power strip by soldering them inline with the DC control wires. &amp;nbsp;If you are going to use this with multiple projects, I would suggest including the resistors in the power strip to help protect the relays from damage.&lt;br /&gt;
&lt;br /&gt;
This hack worked out very nicely, and it's been working for several months without any issues. &amp;nbsp;Once again, since this project involves dangerous voltages, you should exercise extreme caution when building and using this hack. &amp;nbsp;I am not responsible if you decide to duplicate this project and you electrocute yourself, set your house on fire, or encounter some other mishap. &amp;nbsp;You have been warned.&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;b&gt;Update&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Several of the commenters over at &lt;a href="http://hackaday.com/" target="_blank"&gt;Hack a Day&lt;/a&gt;&amp;nbsp;noted that I didn't mention the solid state relays I'm using are only rated for 3 amps (and you would likely need a heat sink for that). &amp;nbsp;Although that is fine for my project, you probably shouldn't try to control your air conditioner using these devices! &amp;nbsp;You could do a similar hack using a larger power strip with more internal room and beefier solid state relays, and along the way provide either fusing or circuit breaker protection for the individual outlets.&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Teknynja/~4/isqJeRDjfbo" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.teknynja.com/feeds/1321926190512862297/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3441881071717960329&amp;postID=1321926190512862297" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3441881071717960329/posts/default/1321926190512862297?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3441881071717960329/posts/default/1321926190512862297?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Teknynja/~3/isqJeRDjfbo/low-voltage-controlled-ac-power-strip.html" title="Low-Voltage Controlled AC Power Strip" /><author><name>teknynja</name><uri>http://www.blogger.com/profile/04303366246283189216</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://bp1.blogger.com/_PabczFx81lo/R_oxf3Xq9DI/AAAAAAAAAAQ/GyX6b5FTGRY/S220/profile.png" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/-nI8T_qxo5_U/T-Jv5Q0mDkI/AAAAAAAAAFw/Jn9fvuvxfs8/s72-c/psdiagram.png" height="72" width="72" /><thr:total>3</thr:total><feedburner:origLink>http://www.teknynja.com/2012/06/low-voltage-controlled-ac-power-strip.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUMCRH84eip7ImA9WhVbFUo.&quot;"><id>tag:blogger.com,1999:blog-3441881071717960329.post-3140951410137141625</id><published>2012-06-01T07:22:00.000-07:00</published><updated>2012-06-01T10:57:45.132-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-06-01T10:57:45.132-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="mods" /><category scheme="http://www.blogger.com/atom/ns#" term="hacks" /><title>Let There Be Music</title><content type="html">&lt;br /&gt;
I needed to be able to play MP3 files as part of a larger project I'm working on. &amp;nbsp;I did a quick search on the Internet for embeddable MP3 player chips and circuits, but everything seemed a bit too expensive or too much work. &amp;nbsp;It was around then I saw &lt;a href="http://hackaday.com/2012/01/16/3-adds-sweet-tunes-to-your-project/" target="_blank"&gt;Hack a Day's&lt;/a&gt;&amp;nbsp;post pointing me to Gadget Gangster's Instructables article &lt;a href="http://www.instructables.com/id/Adding-MP3-to-your-project-for-300/" target="_blank"&gt;Adding MP3 to your project for $3.00&lt;/a&gt;. &amp;nbsp;Being the cheapskate that I am, $3 sounds great to me!&lt;br /&gt;
&lt;br /&gt;
A quick trip to &lt;a href="http://www.ebay.com/sch/i.html?_sop=15&amp;amp;_sacat=0&amp;amp;_nkw=mini+clip+mp3+player&amp;amp;rt=nc&amp;amp;LH_BIN=1" target="_blank"&gt;eBay&lt;/a&gt;&amp;nbsp;and I had two of these “mini-clip” players on the way. &amp;nbsp;I figured I should get an extra just in case I damage one while fooling around. &amp;nbsp; Before I began hacking the player, I tested it out to make sure it was operational and get an idea of how it behaves. &amp;nbsp;One of the things I discovered is that the USB interface is pretty flaky (at least when connected to a Linux system), so it was much easier and faster to transfer files onto it by writing directly to the MicroSD card using a card reader.&lt;br /&gt;
&lt;br /&gt;
&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-2wIRVdO741o/T8jBB8MXXJI/AAAAAAAAAEw/xIgVct0U01I/s1600/img0853.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="480" src="http://3.bp.blogspot.com/-2wIRVdO741o/T8jBB8MXXJI/AAAAAAAAAEw/xIgVct0U01I/s640/img0853.JPG" width="640" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Player liberated from its case&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
I cracked one open and took a look to see what it would take to hook into it. &amp;nbsp;One of the things I wanted to do is to be able to move this from prototype to finished product, or between projects. &amp;nbsp;The Instructables article showed discrete wires soldered to the board, which I could have brought out to some kind of connector. &amp;nbsp;After a bit of thought, I realized I could use a small 10 pin &lt;a href="http://en.wikipedia.org/wiki/Insulation-displacement_connector" target="_blank"&gt;IDC connector&lt;/a&gt;&amp;nbsp;and ribbon cable to allow me to plug it into a nice wire-wrappable header. &amp;nbsp;And with the extra pins, I could also supply power, and even pick off the audio!&lt;br /&gt;
&lt;br /&gt;
&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-qcNF4KgPi_Y/T8jBVQRmifI/AAAAAAAAAE4/rbo-pxaNJZs/s1600/img0859.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="400" src="http://2.bp.blogspot.com/-qcNF4KgPi_Y/T8jBVQRmifI/AAAAAAAAAE4/rbo-pxaNJZs/s400/img0859.JPG" width="300" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;After some minor surgery&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
First, I removed the power wires and also carefully removed the surface mount audio connector. &amp;nbsp;Somewhere in my lab I have the parts to build the IDC/ribbon cable assembly, but I found a pre-made one in my parts bin so I just cut it in half and started peeling back a few of the wires.&lt;br /&gt;
&lt;br /&gt;
&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-DAetb_bBjrA/T8jBdejZtuI/AAAAAAAAAFA/IEnlmvjsLHM/s1600/img0860.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="300" src="http://2.bp.blogspot.com/-DAetb_bBjrA/T8jBdejZtuI/AAAAAAAAAFA/IEnlmvjsLHM/s400/img0860.JPG" width="400" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;IDC cable ready for action&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&amp;nbsp;I started by connecting to the power pads (mostly because they were big and easy to get to). &amp;nbsp;This also conveniently allowed me to set the amount of overhang from the connector to the board. &amp;nbsp;I then cut and stripped the remaining three wires for that side and landed them onto the pads where the audio connector used to be. &amp;nbsp;Next, I flipped over the board and cut each of the wires to length and soldered them to the center of each button pad.&lt;br /&gt;
&lt;br /&gt;
&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-KxozQ6wUhRY/T8jOmzSJLNI/AAAAAAAAAFk/4ZUY1T36fyg/s1600/img08623.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="426" src="http://1.bp.blogspot.com/-KxozQ6wUhRY/T8jOmzSJLNI/AAAAAAAAAFk/4ZUY1T36fyg/s640/img08623.JPG" width="640" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Wires landed on board&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
&lt;div style="text-align: left;"&gt;
&lt;/div&gt;
&lt;div style="text-align: right;"&gt;
&lt;/div&gt;
Now with all the wires hooked up, it's time to test it out and see if I fried anything. &amp;nbsp;I wired up a 2x10 header on my main project (more about that in a future post) and wrote some quick code to “push” the buttons.&lt;br /&gt;
&lt;br /&gt;
&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-I8KG222eUqc/T8jB6zJnl7I/AAAAAAAAAFY/9O32NnYbOm4/s1600/img0865.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="480" src="http://2.bp.blogspot.com/-I8KG222eUqc/T8jB6zJnl7I/AAAAAAAAAFY/9O32NnYbOm4/s640/img0865.JPG" width="640" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;At home in the new project&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
I'm using a PIC18F4550 in this project, and using my favorite language – assembly. I love the challenge of hand-tuning code to make it as small and fast as possible, and that's not so easy with the PIC18F's! &amp;nbsp;Anyway, I wanted to drive the switch outputs &lt;a href="http://en.wikipedia.org/wiki/Open_collector" target="_blank"&gt;open collector&lt;/a&gt;&amp;nbsp;style, so for the switch outputs I initialize the ports by setting the switch TRIS bits and clearing the LAT output bits. &amp;nbsp;Then when I want to “press” a switch, I clear the the corresponding TRIS bit which drives the output low, and set a tick countdown timer. &amp;nbsp;When that timer expires about 200ms later, I set all the TRIS bits again to “float” the outputs and release all the switches.&lt;br /&gt;
&lt;br /&gt;
After checking to make sure the software was doing as I expected, I connected the MP3 player to the main project, powered it up, and out came music! &amp;nbsp;I then tested each of the switch functions, and the player responded as expected, pausing, playing, skipping forward and back, etc. &amp;nbsp;To my surprise, everything worked as expected. &amp;nbsp;The player has been working without any hiccups for several months, despite powering it with 5v instead of it's expected 3.7v battery, and shorting the switch inputs to ground instead of the other contact (although I expect that is the way it is wired anyway).&lt;br /&gt;
&lt;br /&gt;
I would like to thank &lt;a href="http://gadgetgangster.com/" target="_blank"&gt;Gadget Gangster&lt;/a&gt;&amp;nbsp;for sharing his cool tip to re-purpose cheap MP3 players for use in embedded projects, and &lt;a href="http://hackaday.com/" target="_blank"&gt;Hack a Day&lt;/a&gt;&amp;nbsp;for bringing it to my attention.&lt;img src="http://feeds.feedburner.com/~r/Teknynja/~4/aVH038d5C9Q" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.teknynja.com/feeds/3140951410137141625/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3441881071717960329&amp;postID=3140951410137141625" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3441881071717960329/posts/default/3140951410137141625?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3441881071717960329/posts/default/3140951410137141625?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Teknynja/~3/aVH038d5C9Q/let-there-be-music.html" title="Let There Be Music" /><author><name>teknynja</name><uri>http://www.blogger.com/profile/04303366246283189216</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://bp1.blogger.com/_PabczFx81lo/R_oxf3Xq9DI/AAAAAAAAAAQ/GyX6b5FTGRY/S220/profile.png" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/-2wIRVdO741o/T8jBB8MXXJI/AAAAAAAAAEw/xIgVct0U01I/s72-c/img0853.JPG" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://www.teknynja.com/2012/06/let-there-be-music.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CE4DRHY5cCp7ImA9WhdXFEg.&quot;"><id>tag:blogger.com,1999:blog-3441881071717960329.post-2241935942820249658</id><published>2011-08-27T06:28:00.000-07:00</published><updated>2011-08-27T06:49:35.828-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-08-27T06:49:35.828-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="linux" /><category scheme="http://www.blogger.com/atom/ns#" term="hacks" /><title>Hacking WebRunner to work with Firefox 6.0</title><content type="html">I have come to depend on &lt;a href="http://dev.salsitasoft.com/site/projects/" target="_blank"&gt;Salsita Software's WebRunner&lt;/a&gt; extension for Firefox that let's me create “applications” out of web sites.  It comes in especially handy when I want to be logged in with multiple identities on the same web site, as well has keeping an always open window on my &lt;a href="http://www.zoneminder.com/" target="_blank"&gt;Zoneminder&lt;/a&gt; cameras.
&lt;br /&gt;
&lt;br /&gt;When Firefox 6.0 was pushed out in Ubuntu, I was quite dismayed to find that when it checked add-ons and extensions for compatibility, WebRunner was not compatible, and furthermore, an updated version was not available.  I waited for around two weeks for &lt;a href="http://www.salsitasoft.com/" target="_blank"&gt;Salsita&lt;/a&gt; to update their software, but so far there's been nothing.  So I dug around in the .xpi file and came up with this hack to make the current version work with Firefox 6.  These instructions are for Ubuntu/Linux (since that is all I have running now), but the changes should be very similar for Windows as well.
&lt;br /&gt;
&lt;br /&gt;First download (but don't install/run) the latest .xpi file from &lt;a href="http://dev.salsitasoft.com/site/download/#webrunner" target="_blank"&gt;here&lt;/a&gt;.  Then open the file with an archive manager (&lt;a href="https://developer.mozilla.org/en/XPI" target="_blank"&gt;.xpi&lt;/a&gt; files are really just jar/zip files) and edit the file &lt;tt&gt;install.rdf&lt;/tt&gt;, changing the value of &lt;tt&gt;/RDF/Description/version&lt;/tt&gt; from &lt;tt&gt;5.0&lt;/tt&gt; to &lt;tt&gt;5.1&lt;/tt&gt;, and the value of &lt;tt&gt;/RDF/targetApplication/maxVersion&lt;/tt&gt; from &lt;tt&gt;5.*&lt;/tt&gt; to &lt;tt&gt;6.*&lt;/tt&gt;.  Next, edit the file &lt;tt&gt;stub/application.ini&lt;/tt&gt;, changing the value for &lt;tt&gt;MaxVersion&lt;/tt&gt; from &lt;tt&gt;5.0.*&lt;/tt&gt; to &lt;tt&gt;6.0.*&lt;/tt&gt;.  You may want to rename the .xpi file at this point to make it easier to keep track of it.
&lt;br /&gt;
&lt;br /&gt;Now update to Firefox 6.0 (if you haven't done so already) and remove the old WebRunner 5.0 extension, in Tools|Add-ons on the Extensions tab.  Close that dialog, and go to File|Open File... in Firefox and select your modified .xpi file.  It should install without complaint, indicating it is version 5.1 (&lt;span style="font-style:italic;"&gt;hopefully Salsita will version their next release higher than this&lt;/span&gt;).
&lt;br /&gt;
&lt;br /&gt;At this point, you can either re-create your web application shortcuts, or hack the existing ones to work with the updated extension.  To fix the current shortcuts and applications, modify the command for the shortcuts to point to firefox-6.0 instead of firefox-5.0.  Then for each application in your &lt;tt&gt;~/.webapps&lt;/tt&gt; directory, edit the &lt;tt&gt;appname@webrunner/stub/application.ini&lt;/tt&gt; file and change &lt;tt&gt;MaxVersion&lt;/tt&gt; from &lt;tt&gt;5.0.*&lt;/tt&gt; to &lt;tt&gt;6.0.*&lt;/tt&gt; and change &lt;tt&gt;GRE_HOME&lt;/tt&gt; to &lt;tt&gt;/usr/lib/firefox-6.0&lt;/tt&gt;.  Now try to launch your web application shortcuts and you should be good-to-go!
&lt;br /&gt;
&lt;br /&gt;As with most hacks, I make no guarantees that this won't in some way hose your Firefox installation or your entire computer, so attempt this at your own risk!  On the other hand, if you are like me and depend on the excellent WebRunner extension, this hack is a quick way to get it back in Firefox 6.   Make sure to leave comments if you have tried this under Windows and get it to work.&lt;img src="http://feeds.feedburner.com/~r/Teknynja/~4/GQKtBBSvI-E" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.teknynja.com/feeds/2241935942820249658/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3441881071717960329&amp;postID=2241935942820249658" title="4 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3441881071717960329/posts/default/2241935942820249658?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3441881071717960329/posts/default/2241935942820249658?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Teknynja/~3/GQKtBBSvI-E/hacking-webrunner-to-work-with-firefox.html" title="Hacking WebRunner to work with Firefox 6.0" /><author><name>teknynja</name><uri>http://www.blogger.com/profile/04303366246283189216</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://bp1.blogger.com/_PabczFx81lo/R_oxf3Xq9DI/AAAAAAAAAAQ/GyX6b5FTGRY/S220/profile.png" /></author><thr:total>4</thr:total><feedburner:origLink>http://www.teknynja.com/2011/08/hacking-webrunner-to-work-with-firefox.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0cEQ3Y6eip7ImA9Wx5XGE8.&quot;"><id>tag:blogger.com,1999:blog-3441881071717960329.post-2187287303919648075</id><published>2010-09-18T07:23:00.000-07:00</published><updated>2010-09-18T07:43:22.812-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-09-18T07:43:22.812-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="programming" /><title>Dependency Injection Using Nested Classes</title><content type="html">In my day job (lately it seems to be a 24 hour day) I do most of my work in C#, and all our new projects are implemented using &lt;a href="http://en.wikipedia.org/wiki/Test_driven_development" target="_blank"&gt;Test Driven Development&lt;/a&gt;.  Like most people doing TDD, we need to inject &lt;a href="http://martinfowler.com/articles/mocksArentStubs.html" target="_blank"&gt;mock/stub/dummy&lt;/a&gt; objects into our objects under test.  The traditional way to accomplish this is either via &lt;a href="http://martinfowler.com/articles/injection.html" target="_blank"&gt;Constructor Injection or Setter Injection&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;I have never been a fan of using setters to inject test objects, because it clutters the code with properties and methods that are only used for testing and are never used by production code.  At first, I relied on constructor injection, but would sometimes run into cases where I was passing in half a dozen or more objects into the constructor.  Many of these objects were simply helper classes that bundled up some functionality needed by the object under test only, and would never normally be used outside of that class.&lt;br /&gt;&lt;br /&gt;Over the last year we have evolved another way of injecting mock objects into our test objects – Nested Class Injection (or as we call it, “TestHook Injection”).  In C#, a nested class has access to it's containing class's private members, so we can use methods on the nested class to reach into the private details of the outer class.  Here is a simple example:&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;    public class ObjectUnderTest {&lt;br /&gt;&lt;br /&gt;        private IHelperObject _helper;&lt;br /&gt;&lt;br /&gt;        public ObjectUnderTest() {&lt;br /&gt;            _helper = new ProductionHelper();&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        public bool MethodToTest(int testNumber) {&lt;br /&gt;            return _helper.HelperMethod(testNumber);&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        public abstract class TestHook {&lt;br /&gt;&lt;br /&gt;            public static void InjectObjectHelper(ObjectUnderTest objectUnderTest, IHelperObject helper ) {&lt;br /&gt;                objectUnderTest._helper = helper;&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Now all the test related code is contained within the abstract TestHook class.  This class acts like the diagnostic connector on your car, allowing access to internal data and manufacturer's info without exposing it to the user.  In fact, you can even use conditional compilation to exclude the TestHook class in the release build to remove the “connector” if code size or security is an issue.&lt;br /&gt;&lt;br /&gt;Now when you are ready to test your objects, you can do something like:&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;        [Test]&lt;br /&gt;        public void Test_MethodToTest() {&lt;br /&gt;            ObjectUnderTest objectUnderTest = new ObjectUnderTest();&lt;br /&gt;&lt;br /&gt;            IHelperObject mockHelperObject = new MockHelperObject();&lt;br /&gt;            ObjectUnderTest.TestHook.InjectObjectHelper(objectUnderTest, mockHelperObject);&lt;br /&gt;&lt;br /&gt;            objectUnderTest.MethodToTest(12);&lt;br /&gt;&lt;br /&gt;            // Test expectations here...&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Note that I do not normally create my own mocks as shown above, I typically use &lt;a href="http://www.ayende.com/projects/rhino-mocks.aspx" target="_blank"&gt;Rhino Mocks&lt;/a&gt; to create mock objects, and &lt;a href="http://ninject.org/" target="_blank"&gt;Ninject&lt;/a&gt; as my &lt;a href="http://en.wikipedia.org/wiki/Inversion_of_control" target="_blank"&gt;IoC container&lt;/a&gt;.  The contrived examples above are just to show the basic technique of using a nested class to cleanly access the internals of an object for testing purposes.&lt;br /&gt;&lt;br /&gt;Now injecting objects like this is really only useful when those objects are only going to be used internally by the class under test.  If you need to pass in an instance of an object that is shared between multiple objects, traditional constructor or setter injection is fine, since that is actually part of the object's contract with the world.&lt;br /&gt;&lt;br /&gt;We have been using this technique for several months now, and it has resulted in cleaner production code, and more streamlined testing.  Our test setup methods are simpler now, because we only need to inject mocks in the tests that need them instead of in the common test setup method.&lt;br /&gt;&lt;br /&gt;I figured I should write this up since I have found the technique very useful, and a quick Google search  didn't turn up anything useful.  I expect this can be used in any language that supports nested classes where the nested class has access to the outer class's private member variables.  Let me know in the comments if you find this technique helpful, or have any improvements.  Thanks for stopping by!&lt;img src="http://feeds.feedburner.com/~r/Teknynja/~4/qZDWddP_PWw" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.teknynja.com/feeds/2187287303919648075/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3441881071717960329&amp;postID=2187287303919648075" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3441881071717960329/posts/default/2187287303919648075?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3441881071717960329/posts/default/2187287303919648075?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Teknynja/~3/qZDWddP_PWw/dependency-injection-using-nested.html" title="Dependency Injection Using Nested Classes" /><author><name>teknynja</name><uri>http://www.blogger.com/profile/04303366246283189216</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://bp1.blogger.com/_PabczFx81lo/R_oxf3Xq9DI/AAAAAAAAAAQ/GyX6b5FTGRY/S220/profile.png" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.teknynja.com/2010/09/dependency-injection-using-nested.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkUDRH07fCp7ImA9WxFXEE8.&quot;"><id>tag:blogger.com,1999:blog-3441881071717960329.post-8093278378197507863</id><published>2010-05-16T06:38:00.000-07:00</published><updated>2010-05-16T07:31:15.304-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-05-16T07:31:15.304-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="misc" /><category scheme="http://www.blogger.com/atom/ns#" term="entertainment" /><title>Me Day</title><content type="html">As a special treat for myself, I recently escaped from the Teknynja Cave to visit  &lt;a href="http://www.jpl.nasa.gov/events/open-house.cfm" target="”_blank”"&gt;JPL's 2010 Open House&lt;/a&gt;.  This was my first time visiting Jet Propulsion Laboratory or the open house event, and it was even better than I expected.  As a science and space enthusiast, there where plenty of things to see.  What I didn't expect was  the festival atmosphere and all the activities and displays for kids and families.  There was plenty of booths selling kettle corn, hamburgers &amp;amp; hot dogs, frozen lemonade and other treats, and the smells were like that of any “normal” festival.&lt;br /&gt;&lt;hr /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_PabczFx81lo/S-_4WEvjlLI/AAAAAAAAADQ/yKCvcgYKgBU/s1600/sfof.jpg"&gt;&lt;img style="display: block; margin: 0px auto 10px; text-align: center; cursor: pointer; width: 400px; height: 300px;" src="http://1.bp.blogspot.com/_PabczFx81lo/S-_4WEvjlLI/AAAAAAAAADQ/yKCvcgYKgBU/s400/sfof.jpg" alt="" id="BLOGGER_PHOTO_ID_5471865130392458418" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;My first stop of the day was the &lt;a href="http://www.nps.gov/history/nr/travel/aviation/ops.htm" target="”_blank”"&gt;Space Flight Operations Facility&lt;/a&gt;, the “Mission Control” room, where spacecraft like the Viking, Pioneer, Voyager and the Mars Rovers have been monitored and controlled.  It was exciting to see this room with so much history (and to be in the presence of so many computer monitors).&lt;br /&gt;&lt;br /&gt;&lt;hr /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_PabczFx81lo/S-_4ttU2jNI/AAAAAAAAADY/vPhHBmIgdWQ/s1600/ses.jpg"&gt;&lt;img style="float: left; margin: 0pt 10px 10px 0pt; cursor: pointer; width: 240px; height: 320px;" src="http://2.bp.blogspot.com/_PabczFx81lo/S-_4ttU2jNI/AAAAAAAAADY/vPhHBmIgdWQ/s320/ses.jpg" alt="" id="BLOGGER_PHOTO_ID_5471865536423300306" border="0" /&gt;&lt;br /&gt;&lt;/a&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_PabczFx81lo/S-_41C52vWI/AAAAAAAAADg/Tl6Ik4C8ZXw/s1600/ses_ctlrm.jpg"&gt;&lt;img style="display: right; margin: 0pt 0pt 10px 10px; cursor: pointer; width: 320px; height: 240px;" src="http://4.bp.blogspot.com/_PabczFx81lo/S-_41C52vWI/AAAAAAAAADg/Tl6Ik4C8ZXw/s320/ses_ctlrm.jpg" alt="" id="BLOGGER_PHOTO_ID_5471865662474730850" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Next up was a short shuttle bus trip to the 25 Foot Space Simulator facility, a giant environmental chamber that simulates the conditions found in space or on other planets.  Spacecraft are placed inside the simulator and subjected to the vacuum and heat of space.  You can walk around inside the huge chamber, and I also enjoyed checking out the control room for the simulator.&lt;br /&gt;&lt;hr /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_PabczFx81lo/S-_5Z-JaxJI/AAAAAAAAADo/XQ80dXxHMlc/s1600/asmfclty2.jpg"&gt;&lt;img style="display: block; margin: 0px auto 10px; text-align: center; cursor: pointer; width: 400px; height: 300px;" src="http://3.bp.blogspot.com/_PabczFx81lo/S-_5Z-JaxJI/AAAAAAAAADo/XQ80dXxHMlc/s400/asmfclty2.jpg" alt="" id="BLOGGER_PHOTO_ID_5471866296852989074" border="0" /&gt;&lt;/a&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_PabczFx81lo/S-_5jFGNNUI/AAAAAAAAADw/4haYU4SWswE/s1600/asmfclty1.jpg"&gt;&lt;img style="display: block; margin: 0px auto 10px; text-align: center; cursor: pointer; width: 400px; height: 171px;" src="http://3.bp.blogspot.com/_PabczFx81lo/S-_5jFGNNUI/AAAAAAAAADw/4haYU4SWswE/s400/asmfclty1.jpg" alt="" id="BLOGGER_PHOTO_ID_5471866453337388354" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;One of the highlights of my trip was visiting the Spacecraft Assembly Facility, a enormous clean room where JPL's probes and landers are built.  It was especially exciting for me to see the &lt;a href="http://marsprogram.jpl.nasa.gov/msl/" target="”_blank”"&gt;Mars Science Laboratory&lt;/a&gt; (still in several pieces), which is scheduled to arrive on Mars  in 2012.&lt;br /&gt;&lt;hr /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_PabczFx81lo/S-_6LAm8OhI/AAAAAAAAAD4/IQbxVBSAHaQ/s1600/wfpc.jpg"&gt;&lt;img style="display: block; margin: 0px auto 10px; text-align: center; cursor: pointer; width: 400px; height: 245px;" src="http://2.bp.blogspot.com/_PabczFx81lo/S-_6LAm8OhI/AAAAAAAAAD4/IQbxVBSAHaQ/s400/wfpc.jpg" alt="" id="BLOGGER_PHOTO_ID_5471867139327277586" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;The big draw for me though, was the Hubble &lt;a href="http://en.wikipedia.org/wiki/Wide_Field_and_Planetary_Camera_2" target="”_blank”"&gt;Wide Field Planetary Camera 2&lt;/a&gt; exhibit, which displays the actual camera that flew on the Hubble telescope from 2002 until 2009.  Being this close to actual space hardware was an amazing experience!  It is difficult to really see it in this photo, as it is enclosed in a protective nitrogen gas environment.  This exhibit is the centerpiece of the new museum on the JPL campus, that contains dozens of models of probes, rovers, and landers.&lt;br /&gt;&lt;hr /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_PabczFx81lo/S-_6ean1ISI/AAAAAAAAAEA/sPBWKRCFyW4/s1600/fabfclty.jpg"&gt;&lt;img style="display: block; margin: 0px auto 10px; text-align: center; cursor: pointer; width: 400px; height: 300px;" src="http://4.bp.blogspot.com/_PabczFx81lo/S-_6ean1ISI/AAAAAAAAAEA/sPBWKRCFyW4/s400/fabfclty.jpg" alt="" id="BLOGGER_PHOTO_ID_5471867472727843106" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;At this point in my visit, the lines were starting to get very long, but I didn't mind.  My next stop was the Spacecraft Fabrication Facility, where the components for spacecraft are machined and manufactured.  The amount of manufacturing and machining technology in this building is overwhelming, and the tables showing example parts was very impressive.&lt;br /&gt;&lt;hr /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_PabczFx81lo/S-_7GMCYatI/AAAAAAAAAEI/c0bMfB6cym0/s1600/dreamlab.jpg"&gt;&lt;img style="display: block; margin: 0px auto 10px; text-align: center; cursor: pointer; width: 400px; height: 300px;" src="http://2.bp.blogspot.com/_PabczFx81lo/S-_7GMCYatI/AAAAAAAAAEI/c0bMfB6cym0/s400/dreamlab.jpg" alt="" id="BLOGGER_PHOTO_ID_5471868156007443154" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;I finally ended up at the Micro Devices Laboratory, where they do everything from create nano-sized machines to electronic chip fabrication.  There was plenty to see there, but this room caught my eye -  this would be my dream office, with wires and electronic equipment everywhere.  Maybe someday...&lt;br /&gt;&lt;hr /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_PabczFx81lo/S-_7Tr5OM9I/AAAAAAAAAEQ/0cnMRY7zJ8A/s1600/rovers.jpg"&gt;&lt;img style="float: left; margin: 0pt 10px 10px 0pt; cursor: pointer; width: 150px; height: 200px;" src="http://2.bp.blogspot.com/_PabczFx81lo/S-_7Tr5OM9I/AAAAAAAAAEQ/0cnMRY7zJ8A/s200/rovers.jpg" alt="" id="BLOGGER_PHOTO_ID_5471868387897258962" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_PabczFx81lo/S-_7b8BOBDI/AAAAAAAAAEY/L3db7H2PztI/s1600/athlete.jpg"&gt;&lt;img style="display: right; margin: 0pt 0pt 10px 10px; cursor: pointer; width: 200px; height: 150px;" src="http://3.bp.blogspot.com/_PabczFx81lo/S-_7b8BOBDI/AAAAAAAAAEY/L3db7H2PztI/s200/athlete.jpg" alt="" id="BLOGGER_PHOTO_ID_5471868529664721970" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;hr/&gt;&lt;br /&gt;I wrapped up my trip taking in the architecture and the festival scene before hitting the “gift shop” to pick up a tee shirt and some swag for the kids.  I really only hit about half the activities at the open house, but saw what I came to see and more. I'll have to go again, and next time I'll probably bring the young'ins along as well.&lt;img src="http://feeds.feedburner.com/~r/Teknynja/~4/2oiI17b205s" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.teknynja.com/feeds/8093278378197507863/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3441881071717960329&amp;postID=8093278378197507863" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3441881071717960329/posts/default/8093278378197507863?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3441881071717960329/posts/default/8093278378197507863?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Teknynja/~3/2oiI17b205s/me-day.html" title="Me Day" /><author><name>teknynja</name><uri>http://www.blogger.com/profile/04303366246283189216</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://bp1.blogger.com/_PabczFx81lo/R_oxf3Xq9DI/AAAAAAAAAAQ/GyX6b5FTGRY/S220/profile.png" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/_PabczFx81lo/S-_4WEvjlLI/AAAAAAAAADQ/yKCvcgYKgBU/s72-c/sfof.jpg" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://www.teknynja.com/2010/05/me-day.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D08CR3c8fSp7ImA9WxBUGUo.&quot;"><id>tag:blogger.com,1999:blog-3441881071717960329.post-7911422825202899813</id><published>2010-03-07T07:13:00.000-08:00</published><updated>2010-03-07T07:31:06.975-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-03-07T07:31:06.975-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="linux" /><category scheme="http://www.blogger.com/atom/ns#" term="programming" /><title>std::string and sprintf</title><content type="html">Amongst the many projects I am currently juggling, one of them involves developing some C++ code for an embedded Linux project.  I've just hit an instance where I'd like to be able to use “printf” style formatting using std::string instances, but it can be pretty clumsy – I need to allocate buffer space for sprintf, invoke the function, and package up the result into another string.&lt;br /&gt;&lt;br /&gt;I did a quick search on the Internet and found many others looking for the same thing: “Is there a way I can use sprintf in c++ using std:strings?”  And invariably the answers were either &lt;ul&gt;&lt;br /&gt;  &lt;li&gt;“No”&lt;/li&gt;&lt;br /&gt;  &lt;li&gt;“Use std::ostringstream and c++'s built-in manipulators”&lt;/li&gt;&lt;br /&gt;  &lt;li&gt;“Use &lt;a href="http://www.boost.org/doc/libs/1_42_0/libs/format/doc/format.html" target="_blank"&gt;boost::format&lt;/a&gt;”&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;And they are all right!&lt;br /&gt;&lt;br /&gt;It turns out that you can't safely use the *printf style variable argument lists with C++, as only POD (Plain Old Data) types can be passed in the list.  Attempting to pass most other types will result in a segmentation fault at run time.  The official C++ way is to use ostringstream and the usual stream manipulators to format parameters, but for me, that make's writing tests more difficult because I need to “build” the expected streams exactly the same way in my test code.  The final method could work for me, except that this is an embedded project and I am trying to keep the number of libraries referenced to a minimum, since I need to build and include them on my target Linux system.&lt;br /&gt;&lt;br /&gt;So my solution was to accept the limitations of the printf function and write a wrapper function that hides the buffer setup and string creation:&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;#include &amp;lt;string&amp;gt;&lt;br /&gt;#include &amp;lt;stdarg.h&amp;gt;&lt;br /&gt;#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;&lt;br /&gt;string FormatString(const string&amp;amp; format, ...) {&lt;br /&gt;    char buffer[1024];&lt;br /&gt;&lt;br /&gt;    va_list arglist;&lt;br /&gt;    va_start(arglist, format);&lt;br /&gt;    int length = vsnprintf(buffer, sizeof(buffer), format.c_str(), arglist);&lt;br /&gt;    va_end(arglist);&lt;br /&gt;&lt;br /&gt;    return string(buffer, length);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;I've tucked this away in a nested namespace so I can invoke it easily when needed.  Now when I need formatted text I can just supply a c string or std::string format and my parameters, and get back a nice std::string instance in return.  But there's a catch!  I can't pass in a std::string as a parameter because the old-school c variable argument list can't handle objects.  If I try to do that, I will get a “&lt;tt&gt;warning: cannot pass objects of non-POD type 'struct std::string' through '...'; call will abort at runtime&lt;/tt&gt;” warning and a segmentation fault at runtime.  The work around (at least for std::string objects) is to invoke the &lt;tt&gt;c_str()&lt;/tt&gt; method on the string parameter instance.  So for example&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;    string argument = &amp;quot;a string instance&amp;quot;;&lt;br /&gt;    string result = FormatString(&amp;quot;I can format a %s parameter!&amp;quot;, argument.c_str());&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;allows me to supply std::string arguments as well.  The &lt;tt&gt;c_str()&lt;/tt&gt; function returns a pointer to a temporary buffer containing a c style string version of the string object's value.&lt;br /&gt;&lt;br /&gt;So now I have my template style formatting and I can move on with my project.  This project is my first foray into any substantial C++ programming, so if you seen any glaring problems or know a better solution, or if this little tip helped you too, please let me know by leaving a comment.&lt;img src="http://feeds.feedburner.com/~r/Teknynja/~4/PC-92viOmmI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.teknynja.com/feeds/7911422825202899813/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3441881071717960329&amp;postID=7911422825202899813" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3441881071717960329/posts/default/7911422825202899813?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3441881071717960329/posts/default/7911422825202899813?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Teknynja/~3/PC-92viOmmI/stdstring-and-sprintf.html" title="std::string and sprintf" /><author><name>teknynja</name><uri>http://www.blogger.com/profile/04303366246283189216</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://bp1.blogger.com/_PabczFx81lo/R_oxf3Xq9DI/AAAAAAAAAAQ/GyX6b5FTGRY/S220/profile.png" /></author><thr:total>2</thr:total><feedburner:origLink>http://www.teknynja.com/2010/03/stdstring-and-sprintf.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0cFQnw8eSp7ImA9WxNXGE8.&quot;"><id>tag:blogger.com,1999:blog-3441881071717960329.post-8652060734310429063</id><published>2009-10-06T04:09:00.000-07:00</published><updated>2009-10-06T04:36:53.271-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-06T04:36:53.271-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="linux" /><category scheme="http://www.blogger.com/atom/ns#" term="hacks" /><title>MonoDevelop Custom Color Schemes</title><content type="html">I have been playing with &lt;a href="http://monodevelop.com/"&gt;MonoDevelop&lt;/a&gt; 2.0 on Ubuntu on and off for a while now, but one of the things I find most annoying (other than not having &lt;a href="http://www.jetbrains.com/resharper/index.html"&gt;ReSharper&lt;/a&gt;) is there is no easy way to modify the colors used for syntax highlighting.  Sure, it has several pre-defined schemes you can choose from (Using Edit | Prefrences &gt; Text Editor &gt; Syntax Highlighting), but changing individual syntax element colors using the GUI is not possible.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_PabczFx81lo/SsspS87dIGI/AAAAAAAAADA/uG9Go_UI_2c/s1600-h/MonoDevelop-SyntaxHighlighting.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://2.bp.blogspot.com/_PabczFx81lo/SsspS87dIGI/AAAAAAAAADA/uG9Go_UI_2c/s400/MonoDevelop-SyntaxHighlighting.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5389446784648814690" /&gt;&lt;/a&gt;&lt;br /&gt;The reason I find this issue annoying is that I like to have comments and strings really stand out – in our shop we avoid comments as much as possible, and string constants are kept to a minimum, so I like to be able to see them easily in the code.  A few years ago, I started using “highlighter” background colors for comments and strings, and have become quite attached to them ever since.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_PabczFx81lo/Ssspeb4QsTI/AAAAAAAAADI/Y1EYyowau0Q/s1600-h/MonoDevelop-Highlighting.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 175px;" src="http://3.bp.blogspot.com/_PabczFx81lo/Ssspeb4QsTI/AAAAAAAAADI/Y1EYyowau0Q/s400/MonoDevelop-Highlighting.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5389446981935477042" /&gt;&lt;/a&gt;&lt;br /&gt;After many attempts to find a solution on the web, I finally found all the pieces I needed to make it happen.  The basic problem is that although MonoDevelop allows you to add new color schemes, the format of the scheme file is not well documented, and there are a few tricks you need to know to make it work correctly.  The existing schemes are embedded resources and not stand alone files, so they can't be easily viewed for reference.  Finally, I discovered this &lt;a href="http://ubuntuforums.org/showthread.php?t=349477"&gt;Ubuntu Forum thread&lt;/a&gt; that helped me find the solution. The first piece of the puzzle was discovering the &lt;a href="http://anonsvn.mono-project.com/viewvc/branches/monodevelop/main/2.0/src/addins/Mono.Texteditor/Styles/"&gt;color scheme XML source files&lt;/a&gt; in MonoDevelop's SVN tree.  Now I had some samples to go by.  Another useful tidbit from that thread was that the file name must end in "Style.xml" in order to work correctly.  I did not actually verify that this was required, but I did it just to be safe.  The rest came from a &lt;a href="http://monodevelop.com/Developers/Articles/Syntax_Mode_Definition"&gt;MonoDevelop Developer's Article&lt;/a&gt; page I stumbled across shortly thereafter.  One of the important things mentioned on that page is that you need to put the color scheme XML file in the &lt;code&gt;~/.config/syntaxmodes&lt;/code&gt; directory (although in my Ubuntu installation it is actually &lt;code&gt;~/.config/MonoDevelop/syntaxmodes&lt;/code&gt;).  Now I had everything I needed to start tweaking colors!&lt;br /&gt;&lt;br /&gt;The first thing I did was download the VisualStudioStyle.xml file and renamed it to TeknynjaStyle.xml.  Next I edited the file to change the &lt;code&gt;name&lt;/code&gt; and &lt;code&gt;_description&lt;/code&gt; attributes of the &lt;code&gt;EditorStyle&lt;/code&gt; tag so they would not clash with the existing styles in the GUI.  Finally, using the information from the MonoDevelop article and the existing examples, I modified the colors for comments and strings to get the highlighting I was looking for:&lt;br /&gt;&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;   &amp;lt;Style name="comment" color="black" bgColor="#ffff80"/&amp;gt;&lt;br /&gt;   &amp;lt;Style name="comment.doc" color="black" bgColor="#ff8040"/&amp;gt;&lt;br /&gt;   &amp;lt;Style name="comment.tag.doc" color="black" bgColor="#ff8040"/&amp;gt;&lt;br /&gt;&lt;br /&gt;   &amp;lt;Style name="text.preprocessor" color="purple"/&amp;gt;&lt;br /&gt;   &amp;lt;Style name="text.markup" color="skyblue"/&amp;gt;&lt;br /&gt;  &lt;br /&gt;   &amp;lt;Style name="constant" color="black"/&amp;gt;&lt;br /&gt;   &amp;lt;Style name="constant.language" color="keyword-blue"/&amp;gt;&lt;br /&gt;&lt;br /&gt;   &amp;lt;Style name="string" color="black" bgColor="#80ff80"/&amp;gt;&lt;br /&gt;   &amp;lt;Style name="string.single" color="black" bgColor="#80ff80"/&amp;gt;&lt;br /&gt;   &amp;lt;Style name="string.double" color="black" bgColor="#80ff80"/&amp;gt;&lt;br /&gt;   &amp;lt;Style name="string.other" color="black" bgColor="#80ff80"/&amp;gt;&lt;br /&gt;  &lt;br /&gt;   &amp;lt;Style name="keyword" color="keyword-blue"&amp;gt;&lt;br /&gt;       &amp;lt;Style name="type" color="#004080"/&amp;gt;&lt;br /&gt;   &amp;lt;/Style&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;I found the "bgColor" attribute by looking in one of the other color scheme files.  Then I copied my customized color scheme file to ~/.config/MonoDevelop/syntaxmodes, restarted MonoDevelop, and selected my color scheme.  I was able to tweak the colors by editing the XML file and restarting MonoDevelop until I achieved the scheme I was looking for.  Finally I had the highlighting I was used to in Visual Studio, and along with modifying some of my commonly used key bindings, I was able to make MonoDevelop feel a little more like "home".&lt;img src="http://feeds.feedburner.com/~r/Teknynja/~4/9PO2C4bQLZo" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.teknynja.com/feeds/8652060734310429063/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3441881071717960329&amp;postID=8652060734310429063" title="4 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3441881071717960329/posts/default/8652060734310429063?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3441881071717960329/posts/default/8652060734310429063?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Teknynja/~3/9PO2C4bQLZo/monodevelop-custom-color-schemes.html" title="MonoDevelop Custom Color Schemes" /><author><name>teknynja</name><uri>http://www.blogger.com/profile/04303366246283189216</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://bp1.blogger.com/_PabczFx81lo/R_oxf3Xq9DI/AAAAAAAAAAQ/GyX6b5FTGRY/S220/profile.png" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/_PabczFx81lo/SsspS87dIGI/AAAAAAAAADA/uG9Go_UI_2c/s72-c/MonoDevelop-SyntaxHighlighting.png" height="72" width="72" /><thr:total>4</thr:total><feedburner:origLink>http://www.teknynja.com/2009/10/monodevelop-custom-color-schemes.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUAMQH87eCp7ImA9WxJXEEs.&quot;"><id>tag:blogger.com,1999:blog-3441881071717960329.post-8081485099881297308</id><published>2009-06-03T14:08:00.001-07:00</published><updated>2009-06-03T14:16:21.100-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-06-03T14:16:21.100-07:00</app:edited><title>To Protect and Surf (dnsmasq and Whitelists)</title><content type="html">Contrary to popular rumor, I am still alive and very busy – from about October of last year until last month I have been buried at work (a good thing in this economy!).  Maybe now that I can see a little daylight, I can try to keep this blog updated a little more frequently.  Enough with the excuses and on with the post.&lt;br /&gt;&lt;br /&gt;The only person in this house that likes to spend more time on the computer than me is my 4 year old son. &lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_PabczFx81lo/SibmgL6DhUI/AAAAAAAAACo/FRe7Jj_gUE4/s1600-h/MJ_Tucker.jpg"&gt;&lt;img style="float:right; margin:10px 10px 10px 10px;cursor:pointer; cursor:hand;width: 320px; height: 320px;" src="http://4.bp.blogspot.com/_PabczFx81lo/SibmgL6DhUI/AAAAAAAAACo/FRe7Jj_gUE4/s320/MJ_Tucker.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5343211448548164930" /&gt;&lt;/a&gt; Most of the time he is content to play an old copy of &lt;a href=http://en.wikipedia.org/wiki/Monster_Truck_Madness_2 target=”_blank”&gt;Monster Truck Madness 2&lt;/a&gt; that I picked up years ago, but he also likes to spend time at &lt;a href=http://www.dan-dare.org/FreeFun/ target=”_blank”&gt;Dan-Dare.org&lt;/a&gt;, &lt;a href=http://atv.disney.go.com/playhouse/index.html target=”_blank”&gt;Playhouse Disney&lt;/a&gt;, &lt;a href=http://pbskids.org/ target=”_blank”&gt;PBS Kids&lt;/a&gt;, and several other sites.  The problem (other than trying to limit his time on the computer) is that he also likes to explore.  When he gets bored just playing the games, he's off checking out what each menu item and dialog box does.  He has explored all the configuration options in the monster truck game, and he is always playing with the volume control applet – I've spent plenty of time trying to undo his changes on the &lt;a href=http://www.teknynja.com/2008/04/vintage-tv-mod-part-i.html target=”_blank”&gt;kid's computer&lt;/a&gt;.  Lately, he has also taken to checking out the various links on the websites he visits.  A couple of times he has run in to inform us that we can get a free monster truck game, and when we go check on him he has wandered off to some obscure website.  Well, it happened again today, and although I've always known I would have to take action, today was the day to do something about it.&lt;br /&gt;&lt;br /&gt;Being the cheap bastard that I am, I needed a free solution that would keep him (or my 7 year old daughter) from visiting places on the web that I would rather not have them be for now.  I decided that what I need for now is a DNS forwarder with a whitelist, so that only the sites on the list can be accessed.  Although the following solution is fine for small kids, anyone with an 8088 for a brain can figure out how to get around this. Even so, it should work for us for the next few years.&lt;br /&gt;&lt;br /&gt;A little surfing pointed me to &lt;a href=http://thekelleys.org.uk/dnsmasq/doc.html target=”_blank”&gt;dnsmasq&lt;/a&gt;, a very popular dns forwarding server.  A little more research indicated that using it to whitelist domains was not easy – there is no built-in way to do it.  I found someone who listed a source patch to make it happen, but I didn't want to go to that extreme if I could avoid it.  Despite this, I went ahead and installed it on my file server (running Ubuntu, of course) using &lt;code&gt;sudo apt-get install dnsmasq&lt;/code&gt;.  Looking at all the options in the man page and in the /etc/dnsmasq.conf file was overwhelming at first, but it didn't take too long to figure things out.  One of the things I discovered was that you can assign specific outside DNS servers for specific domains.  I realized that if I blocked off any other way for it to resolve domain names except for this feature, I could use it like a whitelist!  A little experimenting proved that it did indeed work.  Here is the dnsmask.conf that I am using right now:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;domain-needed&lt;br /&gt;bogus-priv&lt;br /&gt;log-queries&lt;br /&gt;log-facility=/var/log/dnsmasq.log&lt;br /&gt;no-resolv&lt;br /&gt;interface=eth0&lt;br /&gt;&lt;br /&gt;# Add other name servers here, with domain specs if they are for&lt;br /&gt;# non-public domains.&lt;br /&gt;#server=/localnet/192.168.0.1&lt;br /&gt;server=/google.com/192.168.0.1&lt;br /&gt;server=/dan-dare.org/192.168.0.1&lt;br /&gt;server=/dan-dare.net/192.168.0.1&lt;br /&gt;server=/pbskids.org/192.168.0.1&lt;br /&gt;server=/playhousedisney.com/192.168.0.1&lt;br /&gt;server=/disney.go.com/192.168.0.1&lt;br /&gt;server=/starfall.com/192.168.0.1&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;The first few lines do the actual configuration of dnsmasq, domain-needed &amp; bogus-priv block Windows machines from passing noise traffic, log-queries &amp; log-facility tell dnsmasq to log all DNS requests to the /var/log/dnsmasq.log file (useful for determining the domains required by websites, but this can be turned off to save space), no-resolv tells it to ignore the resolv.conf file which usually lists the outside DNS servers to use, and finally interface tells the service which network interface to bind to.&lt;br /&gt;&lt;br /&gt;The rest of the “server” lines implement the whitelist, telling dnsmasq to look for the specified domain's IP address using the specified DNS server.  In this case, I simply pointed to the DNS server in my local network's router (192.168.0.1).  Any other domains are simply returned as being invalid.  To populate this list, I simply attempted to browse to the sites my children visit, and then looked in the /var/log/dnsmasq.log file to see what domains were being requested, then entered them into the dnsmasq.conf file.  After each update to the configuration file, I needed to &lt;code&gt;sudo /etc/init.d/dnsmasq restart&lt;/code&gt; to get the service to re-read the file.&lt;br /&gt;&lt;br /&gt;The final step was to change the DNS server address on the kid's computer to point to the file server's IP address, and that was it – now anytime they “accidentally” try to access a domain not in the list, they get a message saying the domain was not found.  Of course any computer-savvy person could simply set the DNS server to something else (like &lt;a href=http://www.opendns.com/ target=”_blank”&gt;OpenDNS&lt;/a&gt;!), but it will probably be a few years before my kids figure that out.  If they want to visit someplace new, I have to intervene (which is what I want).  In a few more years, I will have to be more creative to keep ahead of the kids and to keep my workload down updating the list – but for now this works for me.&lt;br /&gt;&lt;br /&gt;So hopefully, if there are other people like me searching for a way to add whitelisting to their dnsmasq forwarders, maybe this post will be a starting point.  If you have any questions, go ahead and leave me a comment or send me an email, I'll do my best to help.  And maybe if things slow down a little there will be more frequent posting around here as well.&lt;img src="http://feeds.feedburner.com/~r/Teknynja/~4/HfcGU3TdBJk" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.teknynja.com/feeds/8081485099881297308/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3441881071717960329&amp;postID=8081485099881297308" title="6 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3441881071717960329/posts/default/8081485099881297308?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3441881071717960329/posts/default/8081485099881297308?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Teknynja/~3/HfcGU3TdBJk/to-protect-and-surf-dnsmasq-and.html" title="To Protect and Surf (dnsmasq and Whitelists)" /><author><name>teknynja</name><uri>http://www.blogger.com/profile/04303366246283189216</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://bp1.blogger.com/_PabczFx81lo/R_oxf3Xq9DI/AAAAAAAAAAQ/GyX6b5FTGRY/S220/profile.png" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/_PabczFx81lo/SibmgL6DhUI/AAAAAAAAACo/FRe7Jj_gUE4/s72-c/MJ_Tucker.jpg" height="72" width="72" /><thr:total>6</thr:total><feedburner:origLink>http://www.teknynja.com/2009/06/to-protect-and-surf-dnsmasq-and.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEMHQ3c4fCp7ImA9WxRRFkw.&quot;"><id>tag:blogger.com,1999:blog-3441881071717960329.post-5728893080370922802</id><published>2008-09-28T07:10:00.000-07:00</published><updated>2008-09-28T07:33:52.934-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-09-28T07:33:52.934-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="linux" /><category scheme="http://www.blogger.com/atom/ns#" term="hacks" /><category scheme="http://www.blogger.com/atom/ns#" term="gadgets" /><title>Ubuntu Photo Frame</title><content type="html">&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_PabczFx81lo/SN-Q6MXyfnI/AAAAAAAAACI/IGfG5ALd6Z0/s1600-h/Teknynja-PhotoFrame.png"&gt;&lt;img style="float:left; margin:10px 10px 10px 10px;cursor:pointer; cursor:hand;" src="http://4.bp.blogspot.com/_PabczFx81lo/SN-Q6MXyfnI/AAAAAAAAACI/IGfG5ALd6Z0/s320/Teknynja-PhotoFrame.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5251075019965103730" /&gt;&lt;/a&gt;&lt;br /&gt;About two years ago I converted an old laptop into a photo frame for the living room. There are plenty of examples of how to do this floating around on the web these days, so I am not going to cover that here.  What I am going to talk about are the software aspects of this project, and my recent upgrade of my photo frame.&lt;br /&gt;&lt;br /&gt;The frame had been working fine for almost two years, but a few months ago I upgraded my WiFi network at the house to WPA (finally), but that meant that I could no longer transfer files to the frame because the WiFi card I was using in it only supported WEP.  Shortly after that, the frame started acting strangely, turning itself off about once a day, then finally not booting at all with the infamous “missing file” messages you get when Windows can't read the hard drive correctly.&lt;br /&gt;&lt;br /&gt;The original software setup for this project was Windows 2000 with a small .NET application I wrote to scan a directory and display pictures from it.  When it was time to display the next photo, the program would scan the directory and pick a new picture at random to display.  The laptop hardware did not have enough “horsepower” to handle any kind of transitions or fades between photos, so the program just displayed the next photo on the screen without any transitions.&lt;br /&gt;&lt;br /&gt;I brought the frame back to my cave, where I confirmed that the hard drive had indeed given out.  I ordered a SYBA SY-IDE2CF-NB25 Ultra IDE to Compact Flash Adapter from &lt;a href=http://www.starsurplus.com/ target=”_blank”&gt;StarSurplus&lt;/a&gt;, and with a 4GB Compact Flash card I had laying around, I now had a solid state hard drive for the frame.  I also ordered a &lt;a href=http://www.newegg.com/Product/Product.aspx?Item=N82E16833315047 target=”_blank”&gt;EDIMAX EW-7108PCg 802.11g/b Wireless LAN PC Card&lt;/a&gt; from NewEgg to allow WiFi access to the frame again.  I selected this card because it is well supported under Linux and it is very inexpensive.  Now that I had all the hardware ready, time to re-install the software.&lt;br /&gt;&lt;br /&gt;I wanted to use Ubuntu for this project, because I am familiar with it, and this would give me an opportunity to learn about doing a very minimal installation.  My goal was to use as little space on the flash drive as possible for the OS and supporting programs to leave room for photos.  After a few practice runs setting up the system and trying different programs, I came up with the following recipe.&lt;br /&gt;&lt;br /&gt;First, I installed Ubuntu Server, with the OpenSSH and Samba options.  The server edition of Ubuntu doesn't install any kind of GUI (just a command prompt) and none of the heavy applications like OpenOffice, Evolution, etc.  Then I got the Wifi card working (it wasn't detected during setup) and performed an upgrade to make sure I had the latest security patches. I setup Samba to allow access to the folder containing the pictures to be displayed.  Next I apt-get installed xorg, dnotify, and feh.  &lt;a href=http://freshmeat.net/projects/feh/ target="_blank"&gt;feh&lt;/a&gt; is a small, lightweight image display program for X.  While playing around with different configurations, I discovered that even under Ubuntu, this laptop just didn't have what it takes to display transitions between photos, and so feh fit the bill almost perfectly.&lt;br /&gt;&lt;br /&gt;I tweaked the xorg.conf file to prevent it from blanking the screen (I think it defaults to blank after 10 minutes), copied some photos to the frame, and fired off feh using xinit.  And my photo slide show started up!  The only problem with feh is that it only reads the files in the directory when it starts up, so if I add pictures to the directory later, I would have to restart the program in order for them to be shown.  So I created the following script using &lt;a href=http://manpages.ubuntu.com/manpages/hardy/man1/dnotify.html target="_blank"&gt;dnotify&lt;/a&gt; to restart the program whenever any files in the folder have changed.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;#!/bin/bash&lt;br /&gt;export HOME=/home/teknynja&lt;br /&gt;while true; do&lt;br /&gt;  killall -q feh&lt;br /&gt;  sleep 1&lt;br /&gt;  xinit /usr/bin/feh -rzFZD180 --hide-pointer /home/teknynja/Pictures &amp;&lt;br /&gt;  dnotify -MCDRro /home/teknynja/Pictures&lt;br /&gt;done&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;I made the script executable, and added a line to invoke the script from inside /etc/rc.local so that it would run when the system started up.  After a couple of days of testing in the cave, I put everything back together and it is now back in the living room, displaying our family photos once again.  It also has the added bonus of being completely silent, due to the solid state hard drive. The total space budget on the flash drive was 645MB for the OS and supporting programs, leaving around 3GB for photos, which is more than enough for now.&lt;br /&gt;&lt;br /&gt;Once again I warn the readers that I still have a lot to learn about Linux, so any constructive comments are appreciated.  If you have any questions or would like more details about this project, feel free to leave a comment and I will try to help you if I can.&lt;img src="http://feeds.feedburner.com/~r/Teknynja/~4/JpnYxekbKzQ" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.teknynja.com/feeds/5728893080370922802/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3441881071717960329&amp;postID=5728893080370922802" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3441881071717960329/posts/default/5728893080370922802?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3441881071717960329/posts/default/5728893080370922802?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Teknynja/~3/JpnYxekbKzQ/ubuntu-photo-frame.html" title="Ubuntu Photo Frame" /><author><name>teknynja</name><uri>http://www.blogger.com/profile/04303366246283189216</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://bp1.blogger.com/_PabczFx81lo/R_oxf3Xq9DI/AAAAAAAAAAQ/GyX6b5FTGRY/S220/profile.png" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/_PabczFx81lo/SN-Q6MXyfnI/AAAAAAAAACI/IGfG5ALd6Z0/s72-c/Teknynja-PhotoFrame.png" height="72" width="72" /><thr:total>1</thr:total><feedburner:origLink>http://www.teknynja.com/2008/09/ubuntu-photo-frame.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkcHQHw9eCp7ImA9WxRTGEo.&quot;"><id>tag:blogger.com,1999:blog-3441881071717960329.post-6390932736350505744</id><published>2008-09-08T05:43:00.000-07:00</published><updated>2008-09-08T05:47:11.260-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-09-08T05:47:11.260-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="linux" /><category scheme="http://www.blogger.com/atom/ns#" term="hacks" /><title>Obscure Ubuntu Tip: CRON User account has expired</title><content type="html">No, I haven't forgotten that I have a blog.  I've just been keeping busy with a lot going on at work, and a backlog of “projects” at home after finishing up the &lt;a href=http://www.teknynja.com/2008/06/kitchen-mod-update.html target=”_blank”&gt;kitchen project&lt;/a&gt;.  Some of those projects have involved getting down-and-dirty with Ubuntu, and I thought I would share a quick tip I discovered yesterday.&lt;br /&gt;&lt;br /&gt;I was looking through the system log (/var/log/syslog) on one of my servers and I noticed it was full of “CRON[xxxx]: User account has expired” messages.  A little searching on the web pointed to the fact that the root account had been locked.  While setting up this server, I had followed some instructions I found on the web that required me to unlock the root account, then re-lock it when I was done with the &lt;pre&gt;sudo passwd -l root&lt;/pre&gt; command.  Locking an account this way also causes the password to be expired, one of the results of which is the above mentioned log entries.  Most of the solutions I found on the web involved either unlocking the root again and giving it a long, random password, or manually editing the password files.  I think I've found the correct way to fix this though, by using the &lt;pre&gt;sudo chage -E-1 root&lt;/pre&gt; command, which sets the root's password to never expire.  (Note that the -1 is negative one, not dash L).  After using the above command, the system log showed normal CRON log entries, and the root account remained locked.&lt;br /&gt;&lt;br /&gt;I hope someone else will find this information to be of use. That's it for my very obscure Ubuntu tip.  Join me again soon for another exciting post.  I actually have a good sized list of topics to cover on the blog, so hopefully things will settle down and you will hear more from me soon.  Thanks for stopping by!&lt;img src="http://feeds.feedburner.com/~r/Teknynja/~4/inyhqXrOSGQ" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.teknynja.com/feeds/6390932736350505744/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3441881071717960329&amp;postID=6390932736350505744" title="13 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3441881071717960329/posts/default/6390932736350505744?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3441881071717960329/posts/default/6390932736350505744?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Teknynja/~3/inyhqXrOSGQ/obscure-ubuntu-tip-cron-user-account.html" title="Obscure Ubuntu Tip: CRON User account has expired" /><author><name>teknynja</name><uri>http://www.blogger.com/profile/04303366246283189216</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://bp1.blogger.com/_PabczFx81lo/R_oxf3Xq9DI/AAAAAAAAAAQ/GyX6b5FTGRY/S220/profile.png" /></author><thr:total>13</thr:total><feedburner:origLink>http://www.teknynja.com/2008/09/obscure-ubuntu-tip-cron-user-account.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0UHRHo8fip7ImA9WxdXF0g.&quot;"><id>tag:blogger.com,1999:blog-3441881071717960329.post-1674664025012652861</id><published>2008-06-29T08:39:00.000-07:00</published><updated>2008-06-29T10:07:15.476-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-06-29T10:07:15.476-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="gadgets" /><title>Picture Perfect</title><content type="html">&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp0.blogger.com/_PabczFx81lo/SGetLQDStMI/AAAAAAAAACA/_yw8BlI_ipo/s1600-h/canonsd870is.jpg"&gt;&lt;img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;" src="http://bp0.blogger.com/_PabczFx81lo/SGetLQDStMI/AAAAAAAAACA/_yw8BlI_ipo/s320/canonsd870is.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5217329102130951362" /&gt;&lt;/a&gt;&lt;br /&gt;This past Father's Day I received a shocking but pleasant surprise – a shiny new &lt;a href="http://www.amazon.com/gp/redirect.html?ie=UTF8&amp;location=http%3A%2F%2Fwww.amazon.com%2FCanon-PowerShot-SD870IS-Digital-Stabilized%2Fdp%2FB000V1XICU%3Fie%3DUTF8%26s%3Delectronics%26qid%3D1214753795%26sr%3D8-2&amp;tag=teknynja-20&amp;linkCode=ur2&amp;camp=1789&amp;creative=9325" target="_blank"&gt;Canon SD870IS ELPH&lt;/a&gt;&lt;img src="http://www.assoc-amazon.com/e/ir?t=teknynja-20&amp;amp;l=ur2&amp;amp;o=1" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" /&gt; point and shoot camera!  The shocking part was due to the fact that my wife never buys technology for me, because I am so picky about my gadgets.  The pleasant part is because I've been looking to replace our old SD200 that we've had for years.  We both loved that camera because of it's small size, ease of use, and fast response time (when you have two fast-moving little ones, it helps to have a camera that can capture an photo right when you press the shutter release).  We've also shot hours of video with the SD200, because even though we have a nice Sony camcorder, we never feel like lugging it around with us.  The video quality is more than acceptable and it allows us to capture moments we would never have been able to with something larger.  The SD200's 3.2 mega-pixel sensor worked fine for the kinds of shots we take.&lt;br /&gt;&lt;br /&gt;So enter the SD870IS.  The coolest feature about this camera is the “IS” at the end – Image Stabilization.  For normal shooting it helps eliminate blur and even works on the large, bright 3” screen. (I was always jealous of other camera's big screens when all I had was the SD200's 2.5” screen).  But the stabilization really comes in handy for shooting video.  With such a small device, shaking is always a problem on video.  The old camera's video always had a lot of shake and could be annoying to watch sometimes, but this new camera shoots nice, steady video that is wonderful to watch!  And for photos, the 8 mega-pixel sensor allows us do more with printing and cropping than we could ever do before.&lt;br /&gt;&lt;br /&gt;Over the years since the SD200 was introduced, Canon has added tons of cool little features to the software, too numerous to mention here, but several new shooting modes, and auto adjusting the image orientation while reviewing images are a couple of them that I really appreciate.  The SD870IS still has some of the same issues as it's older cousin, most notably it's mediocre low light performance  But overall, I am excited to have this cool new toy to play with, and I'm no longer lusting over the other cameras I see when we take the kids to Disneyland!  Thanks Honey!&lt;img src="http://feeds.feedburner.com/~r/Teknynja/~4/nu8McVgZnkc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.teknynja.com/feeds/1674664025012652861/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3441881071717960329&amp;postID=1674664025012652861" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3441881071717960329/posts/default/1674664025012652861?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3441881071717960329/posts/default/1674664025012652861?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Teknynja/~3/nu8McVgZnkc/picture-perfect.html" title="Picture Perfect" /><author><name>teknynja</name><uri>http://www.blogger.com/profile/04303366246283189216</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://bp1.blogger.com/_PabczFx81lo/R_oxf3Xq9DI/AAAAAAAAAAQ/GyX6b5FTGRY/S220/profile.png" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://bp0.blogger.com/_PabczFx81lo/SGetLQDStMI/AAAAAAAAACA/_yw8BlI_ipo/s72-c/canonsd870is.jpg" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://www.teknynja.com/2008/06/picture-perfect.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkcFR34yfSp7ImA9WxdQGUQ.&quot;"><id>tag:blogger.com,1999:blog-3441881071717960329.post-1432967435532131075</id><published>2008-06-17T12:30:00.000-07:00</published><updated>2008-06-20T13:33:36.095-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-06-20T13:33:36.095-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="hacks" /><title>Video Sedation</title><content type="html">&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp1.blogger.com/_PabczFx81lo/SFgTX4qQ3oI/AAAAAAAAABw/HgovAjmWaxM/s1600-h/sansa250.jpg" target="_blank"&gt;&lt;img style="float:left; margin:10px 10px 10px 10px;cursor:pointer; cursor:hand;" src="http://bp1.blogger.com/_PabczFx81lo/SFgTX4qQ3oI/AAAAAAAAABw/HgovAjmWaxM/s200/sansa250.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5212937869748919938" /&gt;&lt;/a&gt;&lt;br /&gt;During one of &lt;a href=http://www.woot.com/ target=”_blank”&gt;Woot&lt;/a&gt;'s last “Woot-Offs”, I picked up a couple of Sansa E250 media players for the kids to watch videos on when we need them to be calm and quite (like during visits to Ikea).  They each already have a &lt;a href=http://www.amazon.com/gp/search?ie=UTF8&amp;keywords=sansa%20shaker&amp;tag=teknynja-20&amp;index=blended&amp;linkCode=ur2&amp;camp=1789&amp;creative=9325 target="_blank"&gt;Sansa Shaker&lt;/a&gt;&lt;img src="http://www.assoc-amazon.com/e/ir?t=teknynja-20&amp;amp;l=ur2&amp;amp;o=1" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" /&gt; loaded with their favorite songs (Tucker seems very fond of his blue “radio”), but video is a much more effective way to keep them “sedated”.  In the past, I used my &lt;a href=http://en.wikipedia.org/wiki/HTC_Wizard target="_blank"&gt;T-Mobile MDA&lt;/a&gt; with several hours of their favorite movies loaded on it to keep them occupied – but they both had to share the screen and I didn't like the idea of them fondling my phone and possibly dropping or otherwise injuring it.&lt;br /&gt;&lt;br /&gt;For $30 bucks each during the woot-off, I figured I couldn't go wrong, so I ordered two of them.  I quickly discovered that the built-in firmware for these players could only handle video encoded using Apple Quicktime DLLs that I have so far managed to keep off my system.  Plus, the compression of the supported format was so bad that I could have only put a few minutes of video in the limited 2Gb of memory the devices contain.&lt;br /&gt;&lt;br&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href=http://www.rockbox.org/ target="_blank"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://bp2.blogger.com/_PabczFx81lo/SFgT-SIPLjI/AAAAAAAAAB4/-wK4BSO7Nb0/s200/rockbox.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5212938529420553778" /&gt;&lt;/a&gt;&lt;br&gt;&lt;br /&gt;Here's were &lt;a href=http://www.rockbox.org/ target=”_blank&gt;Rockbox&lt;/a&gt; saves the day.  Before I pressed the shiny “I Want One” button on Woot, I did a little research and discovered this project and found it supports the players I was about to purchase.  I went ahead an placed my order for two, then within hours of their arrival, I had the Rockbox firmware installed on them.  I played with the software, tweaking the many settings and options the firmware provides.&lt;br /&gt;&lt;br /&gt;Finally it was time to put some videos on the devices.  It took a while to figure out the optimal encoding options for these devices, but after playing around for a few hours I arrived at the following settings:&lt;br&gt;&lt;br /&gt;&lt;table border="1"&gt;&lt;br /&gt;  &lt;tr&gt;&lt;br /&gt;    &lt;td&gt;Video Encoding Format&lt;/td&gt;&lt;br /&gt;    &lt;td&gt;MPEG2 (RockBox only supports this for now)&lt;/td&gt;&lt;br /&gt;  &lt;/tr&gt;&lt;br /&gt;  &lt;tr&gt;&lt;br /&gt;    &lt;td&gt;Video Resolution&lt;/td&gt;&lt;br /&gt;    &lt;td&gt;224x176&lt;/td&gt;&lt;br /&gt;  &lt;/tr&gt;&lt;br /&gt;  &lt;tr&gt;&lt;br /&gt;    &lt;td&gt;Video Bitrate&lt;/td&gt;&lt;br /&gt;    &lt;td&gt;192 kbps&lt;/td&gt;&lt;br /&gt;  &lt;/tr&gt;&lt;br /&gt;  &lt;tr&gt;&lt;br /&gt;    &lt;td&gt;Video Frame Rate&lt;/td&gt;&lt;br /&gt;    &lt;td&gt;25 fps&lt;/td&gt;&lt;br /&gt;  &lt;/tr&gt;&lt;br /&gt;  &lt;tr&gt;&lt;br /&gt;    &lt;td&gt;Audio Encoding Format&lt;/td&gt;&lt;br /&gt;    &lt;td&gt;MPEG-1 Layer 2&lt;/td&gt;&lt;br /&gt;  &lt;/tr&gt;&lt;br /&gt;  &lt;tr&gt;&lt;br /&gt;    &lt;td&gt;Audio Samping Rate&lt;/td&gt;&lt;br /&gt;    &lt;td&gt;44100 Hz (other samping rates break mpeg 2 compatibility)&lt;/td&gt;&lt;br /&gt;  &lt;/tr&gt;&lt;br /&gt;  &lt;tr&gt;&lt;br /&gt;    &lt;td&gt;Audio Bitrate&lt;/td&gt;&lt;br /&gt;    &lt;td&gt;64 kb/s, Monophonic&lt;/td&gt;&lt;br /&gt;  &lt;/tr&gt;&lt;br /&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;Although this results in some serious visual artifacts, this is perfectly fine for the kids to watch (they haven't complained yet!).  These settings allow me to cram several hours of video onto the players.  The only thing I haven't figured out yet is how long the batteries last during video playback – the longest stretch of time the kids have watched the devices is about 90 minutes during a drive back from Grandma's House.&lt;br /&gt;&lt;br /&gt;I figured I should share this little tip in case anyone else needs to administer some “video sedation” of their own while out in the world.  As always, any tips and suggestions are always appreciated in the comments.&lt;img src="http://feeds.feedburner.com/~r/Teknynja/~4/cw_qFDedp3g" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.teknynja.com/feeds/1432967435532131075/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3441881071717960329&amp;postID=1432967435532131075" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3441881071717960329/posts/default/1432967435532131075?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3441881071717960329/posts/default/1432967435532131075?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Teknynja/~3/cw_qFDedp3g/video-sedation.html" title="Video Sedation" /><author><name>teknynja</name><uri>http://www.blogger.com/profile/04303366246283189216</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://bp1.blogger.com/_PabczFx81lo/R_oxf3Xq9DI/AAAAAAAAAAQ/GyX6b5FTGRY/S220/profile.png" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://bp1.blogger.com/_PabczFx81lo/SFgTX4qQ3oI/AAAAAAAAABw/HgovAjmWaxM/s72-c/sansa250.jpg" height="72" width="72" /><thr:total>1</thr:total><feedburner:origLink>http://www.teknynja.com/2008/06/video-sedation.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEICR3w7eSp7ImA9WxdQF0Q.&quot;"><id>tag:blogger.com,1999:blog-3441881071717960329.post-8069731123160049636</id><published>2008-06-17T11:39:00.000-07:00</published><updated>2008-06-18T05:36:06.201-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-06-18T05:36:06.201-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="mods" /><category scheme="http://www.blogger.com/atom/ns#" term="misc" /><title>Kitchen Mod Update</title><content type="html">&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp3.blogger.com/_PabczFx81lo/SFgFO7OumEI/AAAAAAAAAA0/F5bHCmjglfM/s1600-h/kitchen0617.jpg" target="_blank"&gt;&lt;img style="float:left; margin:10px 10px 10px 10px;cursor:pointer; cursor:hand;" src="http://bp3.blogger.com/_PabczFx81lo/SFgFO7OumEI/AAAAAAAAAA0/F5bHCmjglfM/s320/kitchen0617.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5212922322657122370" /&gt;&lt;/a&gt;&lt;br /&gt;Sorry I haven't been posting in a while, but once I got started on the kitchen, every free moment after work was devoted to it.  I finally finished all the tough stuff last week, all that's left to do is convert a can light in the ceiling to a hanging lamp that Kelly picked out at Ikea (where else?)  The granite people came out last week and attached the sub-tops and made templates, but we are still waiting for them to contact us so we can choose the layout.  But even with just the sub-tops (read plywood), life with an island in the kitchen is much better.  You can see more details on our kitchen project on &lt;a href=http://www.ikeafans.com/blogs/shire/ target=”_blank”&gt;Kelly's blog at IkeaFans&lt;/a&gt;.  It isn't up to date with the latest pics yet, but you can get an idea of what I've been up to the last few weeks.&lt;img src="http://feeds.feedburner.com/~r/Teknynja/~4/T7OCFBnT7yI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.teknynja.com/feeds/8069731123160049636/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3441881071717960329&amp;postID=8069731123160049636" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3441881071717960329/posts/default/8069731123160049636?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3441881071717960329/posts/default/8069731123160049636?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Teknynja/~3/T7OCFBnT7yI/kitchen-mod-update.html" title="Kitchen Mod Update" /><author><name>teknynja</name><uri>http://www.blogger.com/profile/04303366246283189216</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://bp1.blogger.com/_PabczFx81lo/R_oxf3Xq9DI/AAAAAAAAAAQ/GyX6b5FTGRY/S220/profile.png" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://bp3.blogger.com/_PabczFx81lo/SFgFO7OumEI/AAAAAAAAAA0/F5bHCmjglfM/s72-c/kitchen0617.jpg" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://www.teknynja.com/2008/06/kitchen-mod-update.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0UDRXwzfyp7ImA9WxZaF0Q.&quot;"><id>tag:blogger.com,1999:blog-3441881071717960329.post-2004595255997497782</id><published>2008-05-02T22:39:00.000-07:00</published><updated>2008-05-02T23:14:34.287-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-05-02T23:14:34.287-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="mods" /><title>Vintage TV Mod, Part III</title><content type="html">&lt;a href=http://www.teknynja.com/2008/04/vintage-tv-mod-part-ii.html&gt;Last time&lt;/a&gt;, I mounted the LCD display to the front panel and got a pretty good looking test out of it.  Now it's time to put the computer electronics and knobs on this thing.  &lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.mykrotek.com/teknynja/otv/otv_15_driveMounts.jpg"&gt;&lt;img style="float:left; margin:10px 10px 10px 10px;cursor:pointer; cursor:hand;width: 320px;" src="http://www.mykrotek.com/teknynja/otv/otv_15_driveMounts.jpg" border="0" alt="" /&gt;&lt;/a&gt;First up, I built up a bracket to hold the hard disc and CD-ROM drive.  This arrangement turned out to be nice and stable, and allowed me to use a vibration dampening 3.5” to 5.25” drive adapter kit to help keep the hard drive quite.  I then mounted the drive cage, mother board, and power supply to a piece of 1/4” MDF that I had pre-cut to fit inside the cabinet where the old chassis used to be, making sure to leave room for the LCD monitor. &lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.mykrotek.com/teknynja/otv/otv_16_subpanelLayout.jpg"&gt;&lt;img style="float:left; margin:10px 10px 10px 10px;cursor:pointer; cursor:hand;width: 320px;" src="http://www.mykrotek.com/teknynja/otv/otv_16_subpanelLayout.jpg" border="0" alt="" /&gt;&lt;/a&gt; I used a large, quite &lt;a href=http://www.zalman.co.kr/eng/main.asp&gt;Zalman&lt;/a&gt; CPU fan to keep noise to a minimum.  Once everything was mounted to the sub-panel, I placed it inside the cabinet and screwed it down.  Next, I built a small shelf for the bottom half of the cabinet where the speakers would sit.  A couple of lengths of aluminum L channel span the width of the cabinet, and a small piece of MDF forms the shelf.  I purchased a cheap 2.1 Logitech speaker system, and screwed the speakers to the shelf, facing out through the old speaker grill.  I put a piece of black electrical tape over the power lamp to keep it from showing through the grill cloth.&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.mykrotek.com/teknynja/otv/otv_17_speakerMount.jpg"&gt;&lt;img style="float:right; margin:10px 10px 10px 10px;cursor:pointer; cursor:hand;width: 320px;" src="http://www.mykrotek.com/teknynja/otv/otv_17_speakerMount.jpg" border="0" alt="" /&gt;&lt;/a&gt;&lt;br /&gt;Next, I purchase some potentiometers from the ultra cool surplus store &lt;a href=http://www.goldmine-elec.com/&gt;Electroncs Goldmine&lt;/a&gt;, three with a momentary push switch feature, and one dual potentiometer to be used as the volume control. &lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.mykrotek.com/teknynja/otv/otv_19_controlParts.jpg"&gt;&lt;img style="float:right; margin:10px 10px 10px 10px;cursor:pointer; cursor:hand;width: 320px;" src="http://www.mykrotek.com/teknynja/otv/otv_19_controlParts.jpg" border="0" alt="" /&gt;&lt;/a&gt; Two of the potentiometers were just dummys to hold the knobs, although they could be used for something in the future.  The remaining switch-pot was wired up to the power switch connections on the mother board, so I could turn the computer on and off by simply pressing the knob. &lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.mykrotek.com/teknynja/otv/otv_22_volumeWiring.jpg"&gt;&lt;img style="float:right; margin:10px 10px 10px 10px;cursor:pointer; cursor:hand;width: 320px;" src="http://www.mykrotek.com/teknynja/otv/otv_22_volumeWiring.jpg" border="0" alt="" /&gt;&lt;/a&gt; The dual potentiometer was wired up as an attenuator with a standard stereo 3.5mm plug on one side, and a 3.5mm stereo jack on the other side.  The plug then connected to the line out on the mother board, and the speakers plugged into the plug on the other end.  Now I have a nice physical volume control, just like the original set! &lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.mykrotek.com/teknynja/otv/otv_20_knobHack.jpg"&gt;&lt;img style="float:left; margin:10px 10px 10px 10px;cursor:pointer; cursor:hand;width: 320px;" src="http://www.mykrotek.com/teknynja/otv/otv_20_knobHack.jpg" border="0" alt="" /&gt;&lt;/a&gt; I had to grind off the back of the volume knob to get it to fit onto the short shaft of the audio pot, but the other shafts fit perfectly into the original knobs that came with the tv. &lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.mykrotek.com/teknynja/otv/otv_23_powerVolumeWiring.jpg"&gt;&lt;img style="float:left; margin:10px 10px 10px 10px;cursor:pointer; cursor:hand;width: 320px;" src="http://www.mykrotek.com/teknynja/otv/otv_23_powerVolumeWiring.jpg" border="0" alt="" /&gt;&lt;/a&gt; I used short pieces of aluminum L channel to mount the pots to the front panel, then adjusted the depth of the shafts using the nuts to get the knobs just the right distance from the front panel.&lt;br /&gt;Once I had all the mechanical aspects taken care of, I mounted a power strip to the under side of the chassis shelf and plugged everything into that, so I would only have one cord leaving the cabinet.  A WI-FI card was used for the network connection, and a wireless keyboard and mouse was added, so that only only the power cord came out of the back of the TV.  As a final touch, I mounted an amber LED at the bottom of the cabinet where the old power lamp used to be, and drove it off the Power LED connection on the motherboard.  I tracked down old &lt;a href=http://en.wikipedia.org/wiki/Indian_Head_test_card&gt;Indian Head test pattern&lt;/a&gt; for the desktop wallpaper, and it was done.  The kids have watched countless movies and hours of TV on the set via the &lt;a href=http://www.slingmedia.com/&gt;SlingBox&lt;/a&gt;, and an old, broken TV was given a new life.&lt;br/&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.mykrotek.com/teknynja/otv/otv_26_afterFront.jpg"&gt;&lt;img style="float:center; margin:10px 10px 10px 10px;cursor:pointer; cursor:hand;width: 320px;" src="http://www.mykrotek.com/teknynja/otv/otv_26_afterFront.jpg" border="0" alt="" /&gt;&lt;/a&gt;&lt;br/&gt;I hope this project inspires others to take the plunge and put computers in other unexpected places.  If you do, post a comment or send me an email to let me know about it.&lt;img src="http://feeds.feedburner.com/~r/Teknynja/~4/Z-7UsHb9kOo" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.teknynja.com/feeds/2004595255997497782/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3441881071717960329&amp;postID=2004595255997497782" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3441881071717960329/posts/default/2004595255997497782?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3441881071717960329/posts/default/2004595255997497782?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Teknynja/~3/Z-7UsHb9kOo/vintage-tv-mod-part-iii.html" title="Vintage TV Mod, Part III" /><author><name>teknynja</name><uri>http://www.blogger.com/profile/04303366246283189216</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://bp1.blogger.com/_PabczFx81lo/R_oxf3Xq9DI/AAAAAAAAAAQ/GyX6b5FTGRY/S220/profile.png" /></author><thr:total>3</thr:total><feedburner:origLink>http://www.teknynja.com/2008/05/vintage-tv-mod-part-iii.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0UER3g7eip7ImA9WxZaF0Q.&quot;"><id>tag:blogger.com,1999:blog-3441881071717960329.post-3553733987887578315</id><published>2008-04-26T04:59:00.000-07:00</published><updated>2008-05-02T23:13:26.602-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-05-02T23:13:26.602-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="linux" /><title>Ubuntu 8.04 Hardy Heron Synergy Client Setup</title><content type="html">In the Teknynja cave I have a MS Windows XP box with two monitors (my main development system) and a Ubuntu box with one monitor (my Internet offload system).  I use &lt;a href=http://synergy2.sourceforge.net/&gt;Synergy&lt;/a&gt; to control the Ubuntu system using XP's mouse and keyboard.  Since the Ubuntu box doesn't have a keyboard or mouse connected to it, a little hacking is required to get the Synergy client running before the login screen.  I've been doing this with my Ubuntu 7.04 system for a while, and now that I am setting up a &lt;a href=http://www.teknynja.com/2008/04/waiting-for-heron.html&gt;replacement Ubuntu 8.04&lt;/a&gt; system, I thought I would document the Synergy client setup for future reference.  It should be noted that I installed Ubuntu Hardy Heron from the Alternate CD, but that should not make a difference for this procedure.  I also assume that you already have the Synergy keyboard/mouse server configured and running somewhere on your network.&lt;br /&gt;&lt;br /&gt;First, install Synergy on the Ubuntu system using:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;sudo apt-get install synergy&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Then edit the gdm initialization file:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;sudo nano /etc/gdm/Init/Default&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;and add the following lines just before the “sysresources=/etc/X11/Xresources” line&lt;br /&gt;&lt;code&gt;&lt;br /&gt;/usr/bin/killall synergyc&lt;br /&gt;sleep 1&lt;br /&gt;/usr/bin/synergyc xxx.xxx.xxx.xxx&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;where xxx.xxx.xxx.xxx is the IP address of your server machine.&lt;br /&gt;&lt;br /&gt;Now edit the gdm pre-session file:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;sudo nano /etc/gdm/PreSession/Default&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;and and the following line just before the “XSETROOT='gdmwhich xsetroot'” line&lt;br /&gt;&lt;code&gt;&lt;br /&gt;/usr/bin/synergyc xxx.xxx.xxx.xxx&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Make sure the Synergy server is configured and running on your keyboard/mouse system, and reboot the Ubuntu system.  You should now be able to move the mouse over to the Ubuntu screen and login normally.&lt;br /&gt;&lt;br/&gt;&lt;br /&gt;Note that I still consider myself a Ubuntu/Linux noob, and so any improvements/comments/suggestions you have about this post are greatly appreciated.  Ymmv.  Most of the help I needed setting up this configuration came from the &lt;a href=https://help.ubuntu.com/community/SynergyHowto&gt;Ubuntu Synergy How To&lt;/a&gt; page.&lt;img src="http://feeds.feedburner.com/~r/Teknynja/~4/yI3QDOfr7IM" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.teknynja.com/feeds/3553733987887578315/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3441881071717960329&amp;postID=3553733987887578315" title="6 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3441881071717960329/posts/default/3553733987887578315?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3441881071717960329/posts/default/3553733987887578315?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Teknynja/~3/yI3QDOfr7IM/ubuntu-804-hardy-heron-synergy-client.html" title="Ubuntu 8.04 Hardy Heron Synergy Client Setup" /><author><name>teknynja</name><uri>http://www.blogger.com/profile/04303366246283189216</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://bp1.blogger.com/_PabczFx81lo/R_oxf3Xq9DI/AAAAAAAAAAQ/GyX6b5FTGRY/S220/profile.png" /></author><thr:total>6</thr:total><feedburner:origLink>http://www.teknynja.com/2008/04/ubuntu-804-hardy-heron-synergy-client.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEMDSX47cCp7ImA9WxVSGEg.&quot;"><id>tag:blogger.com,1999:blog-3441881071717960329.post-6870364477927393656</id><published>2008-04-25T12:08:00.000-07:00</published><updated>2009-01-13T06:21:18.008-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-01-13T06:21:18.008-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="mods" /><title>Vintage TV Mod, Part II</title><content type="html">In our &lt;a href=http://www.teknynja.com/2008/04/vintage-tv-mod-part-i.html&gt;last installment&lt;/a&gt;, I gutted the old television cabinet and prepared it for the updated electronics.  This time, I'll cover the real heart of this mod, the LCD display.&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.mykrotek.com/teknynja/otv/otv_09_facePrep.jpg"&gt;&lt;img style="float:right; margin:10px 10px 10px 10px;cursor:pointer; cursor:hand;width: 240px;" src="http://www.mykrotek.com/teknynja/otv/otv_09_facePrep.jpg" border="0" alt="" /&gt;&lt;/a&gt;I removed the old CRT bezel from the front panel of the TV, because even though it would have looked cool to have an old-fashioned round screen, it would have covered some of the essential parts of the display, like the menus and title bar controls.  I had an old 15” LCD monitor sitting out in the garage after I updated to a wide screen monitor on my workstation, so I grabbed it and checked to make sure that it would remember its power state when the AC was removed – I didn't want to have to be constantly pressing a button to turn the monitor on.&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.mykrotek.com/teknynja/otv/otv_10_lcdPrep.jpg"&gt;&lt;img style="float:left; margin:10px 10px 10px 10px;cursor:pointer; cursor:hand;width: 240px;" src="http://www.mykrotek.com/teknynja/otv/otv_10_lcdPrep.jpg" border="0" alt="" /&gt;&lt;/a&gt;After verifying that that the power worked as needed, I disassembled the monitor case and removed the screen and electronics.  I then used some standoffs to mount the control buttons on the back of the monitor, so I would be able to access them from inside the case once it was mounted in the cabinet.&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.mykrotek.com/teknynja/otv/otv_11_lcdButtons.jpg"&gt;&lt;img style="float:left; margin:10px 10px 10px 10px;cursor:pointer; cursor:hand;width: 240px;" src="http://www.mykrotek.com/teknynja/otv/otv_11_lcdButtons.jpg" border="0" alt="" /&gt;&lt;/a&gt;The actual display panel was a little bit smaller than the glass opening at the front of the TV, so I found a simple black picture frame to act as a bezel and mounted it to the front panel.  I was then able to use the original mounting tabs on the LCD panel to attach it to the picture frame.&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.mykrotek.com/teknynja/otv/otv_12_lcdTestFit.jpg"&gt;&lt;img style="float:right; margin:10px 10px 10px 10px;cursor:pointer; cursor:hand;width: 240px;" src="http://www.mykrotek.com/teknynja/otv/otv_12_lcdTestFit.jpg" border="0" alt="" /&gt;&lt;/a&gt;You could still see a little of the metal frame of the LCD panel inside the frame, but it didn't look too bad, and I'd rather be able to see all the pixels on the screen anyway.&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.mykrotek.com/teknynja/otv/otv_13_lcdMount.jpg"&gt;&lt;img style="float:right; margin:10px 10px 10px 10px;cursor:pointer; cursor:hand;width: 240px;" src="http://www.mykrotek.com/teknynja/otv/otv_13_lcdMount.jpg" border="0" alt="" /&gt;&lt;/a&gt;After getting everything mounted and placed back into the cabinet, I connected it up to power and a PC to see what the display would look like.  Of course, I had to try out an old black and white movie on the newly mounted screen – the effect was rather convincing!  Next time, on “This Old TV”, I'll show how I put the knobs back on and made them functional, as well as the replacement speakers for the set.&lt;br/&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.mykrotek.com/teknynja/otv/otv_14_lcdTest.jpg"&gt;&lt;img style="float:center; margin:10px 10px 10px 10px;cursor:pointer; cursor:hand;width: 320px;" src="http://www.mykrotek.com/teknynja/otv/otv_14_lcdTest.jpg" border="0" alt="" /&gt;&lt;/a&gt;&lt;img src="http://feeds.feedburner.com/~r/Teknynja/~4/V3NUDCMeK-M" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.teknynja.com/feeds/6870364477927393656/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3441881071717960329&amp;postID=6870364477927393656" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3441881071717960329/posts/default/6870364477927393656?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3441881071717960329/posts/default/6870364477927393656?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Teknynja/~3/V3NUDCMeK-M/vintage-tv-mod-part-ii.html" title="Vintage TV Mod, Part II" /><author><name>teknynja</name><uri>http://www.blogger.com/profile/04303366246283189216</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://bp1.blogger.com/_PabczFx81lo/R_oxf3Xq9DI/AAAAAAAAAAQ/GyX6b5FTGRY/S220/profile.png" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.teknynja.com/2008/04/vintage-tv-mod-part-ii.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0QMQn04cCp7ImA9WxZaF0Q.&quot;"><id>tag:blogger.com,1999:blog-3441881071717960329.post-9175352548468032641</id><published>2008-04-20T10:23:00.000-07:00</published><updated>2008-05-02T23:16:23.338-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-05-02T23:16:23.338-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="entertainment" /><title>“Time” to Geek</title><content type="html">One of my wife's friends traveled to England a few weeks ago, and brought back a special item that I requested.  Just in case my status as a geek was in question, this item should eliminate any doubts.  The item is my newly acquired Doctor Who 2008 Calendar.&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp1.blogger.com/_PabczFx81lo/SAt8qycNbfI/AAAAAAAAAAk/MFpXTBF9gP4/s1600-h/drwhocal2008.jpg"&gt;&lt;img style="float:right; margin:10px 10px 10px 10px;cursor:pointer; cursor:hand;" src="http://bp1.blogger.com/_PabczFx81lo/SAt8qycNbfI/AAAAAAAAAAk/MFpXTBF9gP4/s320/drwhocal2008.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5191380070011071986" /&gt;&lt;/a&gt;I know, the year is already a third over, but I've been eying this calendar since before Christmas.  The only reputable place I could find to order it online was Amazon UK, but the shipping was just too much.  So when my wife's friend asked if there was anything I wanted when she went to England, I didn't hesitate.  I have been a fan of the show since I was a young boy, watching episodes on Saturday mornings on the local PBS station, sometimes with my dad.&lt;br&gt;They say you imprint with your first doctor, which for me was Jon Pertwee, but my favorite doctor is actually Tom Baker, with his arrogant, Sherlock Holmes style.  There is plenty on the web written about &lt;a href=http://en.wikipedia.org/wiki/Doctor_Who&gt;Doctor Who&lt;/a&gt; and all the doctors, so I won't try to cover that ground again here.  The original series ended in 1989, but a new series started up again in 2005, and I still look forward to each episode.  I am also a big fan of the spin-off series &lt;a href=http://en.wikipedia.org/wiki/Torchwood&gt;Torchwood&lt;/a&gt;, which is a great show in it's own right.  Torchwood is a bit too adult for my little girl, but another Doctor Who spin-off, &lt;a href=http://en.wikipedia.org/wiki/Sarah_Jane_Adventures&gt;The Sarah Jane Adventures&lt;/a&gt; is aimed at the younger set and usually keeps my daughter on the edge of the couch.  And in case the whole Doctor Who thing doesn't cement my geek status, ask me to talk about &lt;a href=http://en.wikipedia.org/wiki/Red_Dwarf_%28TV_series%29&gt;Red Dwarf &lt;/a&gt;or &lt;a href=http://en.wikipedia.org/wiki/Blake%27s_7&gt;Blake's Seven&lt;/a&gt; some day.&lt;img src="http://feeds.feedburner.com/~r/Teknynja/~4/VSfRMLMdTBU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.teknynja.com/feeds/9175352548468032641/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3441881071717960329&amp;postID=9175352548468032641" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3441881071717960329/posts/default/9175352548468032641?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3441881071717960329/posts/default/9175352548468032641?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Teknynja/~3/VSfRMLMdTBU/time-to-geek.html" title="“Time” to Geek" /><author><name>teknynja</name><uri>http://www.blogger.com/profile/04303366246283189216</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://bp1.blogger.com/_PabczFx81lo/R_oxf3Xq9DI/AAAAAAAAAAQ/GyX6b5FTGRY/S220/profile.png" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://bp1.blogger.com/_PabczFx81lo/SAt8qycNbfI/AAAAAAAAAAk/MFpXTBF9gP4/s72-c/drwhocal2008.jpg" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://www.teknynja.com/2008/04/time-to-geek.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0MCR3s8eyp7ImA9WxZaF0Q.&quot;"><id>tag:blogger.com,1999:blog-3441881071717960329.post-4578343801654586612</id><published>2008-04-19T04:15:00.001-07:00</published><updated>2008-05-02T23:17:46.573-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-05-02T23:17:46.573-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="mods" /><category scheme="http://www.blogger.com/atom/ns#" term="misc" /><title>Vintage TV Mod, Part I</title><content type="html">&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://mykrotek.com/teknynja/otv/otv_01_beforeFront.jpg"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 200px;" src="http://mykrotek.com/teknynja/otv/otv_01_beforeFront.jpg" border="0" alt="" /&gt;&lt;/a&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://mykrotek.com/teknynja/otv/otv_02_beforeBack.jpg"&gt;&lt;img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 200px;" src="http://mykrotek.com/teknynja/otv/otv_02_beforeBack.jpg" border="0" alt="" /&gt;&lt;/a&gt;I've had this old 1943 RCA/Victor television set kicking around for many years now.  When I first got it, you could actually watch tv on it, but after a year or so, it stopped working (probably desperately in need of a complete capacitor replacement).  For years I was gonna do that as a project, but never got around to it.    The set was used mainly as something to set knick knacks on for a long time until I finally had an idea – I would turn it into a meda pc for the kids.  In the long run, it would probably be less work than fixing the old TV, and via my &lt;a href=http://www.slingmedia.com/go/slingbox.html&gt;Slingbox&lt;/a&gt;,  we would still be able to watch TV on it!&lt;br /&gt;&lt;br&gt;&lt;br /&gt;First, I needed to gut the cabinet to make room for the new components.&lt;br&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://mykrotek.com/teknynja/otv/otv_03_beforeGuts.jpg"&gt;&lt;img style="margin:10px 10px 10px 10px;cursor:pointer; cursor:hand;width: 200px;" src="http://mykrotek.com/teknynja/otv/otv_03_beforeGuts.jpg" border="0" alt="" /&gt;&lt;/a&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://mykrotek.com/teknynja/otv/otv_04_gutsRemoved.jpg"&gt;&lt;img style="margin:10px 10px 10px 10px;cursor:pointer; cursor:hand;width: 200px;" src="http://mykrotek.com/teknynja/otv/otv_04_gutsRemoved.jpg" border="0" alt="" /&gt;&lt;/a&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://mykrotek.com/teknynja/otv/otv_05_pictureTube.jpg"&gt;&lt;img style="margin:10px 10px 10px 10px;cursor:pointer; cursor:hand;height: 200px;" src="http://mykrotek.com/teknynja/otv/otv_05_pictureTube.jpg" border="0" alt="" /&gt;&lt;/a&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://mykrotek.com/teknynja/otv/otv_06_emptyCabinet.jpg"&gt;&lt;img style="margin:10px 10px 10px 10px;cursor:pointer; cursor:hand;width: 200px;" src="http://mykrotek.com/teknynja/otv/otv_06_emptyCabinet.jpg" border="0" alt="" /&gt;&lt;/a&gt;&lt;br&gt;These old TV's were built to be serviced, so getting the chassis out was simple, although I used a little extra caution around the old picture tube.  I didn't want it imploding all over me, and I might be able to sell it on eBay some day.&lt;br&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://mykrotek.com/teknynja/otv/otv_07_faceRemoved.jpg"&gt;&lt;img style="margin:10px 10px 10px 10px;cursor:pointer; cursor:hand;width: 200px;" src="http://mykrotek.com/teknynja/otv/otv_07_faceRemoved.jpg" border="0" alt="" /&gt;&lt;/a&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://mykrotek.com/teknynja/otv/otv_08_cabinetRepair.jpg"&gt;&lt;img style="margin:10px 10px 10px 10px;cursor:pointer; cursor:hand;width: 200px;" src="http://mykrotek.com/teknynja/otv/otv_08_cabinetRepair.jpg" border="0" alt="" /&gt;&lt;/a&gt;&lt;br&gt;Once gutted, I removed the front bezel and did a little repair to the side panel of the cabinet, which had come loose at some point.  I guess I could have attempted to restore the case since it is so scratched up, but since this was going to be used by the kids (and because I am very lazy), I decided to leave it in it's “vintage” condition.  In my next post, I'll cover getting the new LCD installed in the set.  Stay tuned!&lt;img src="http://feeds.feedburner.com/~r/Teknynja/~4/FtnDgokSfQM" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.teknynja.com/feeds/4578343801654586612/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3441881071717960329&amp;postID=4578343801654586612" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3441881071717960329/posts/default/4578343801654586612?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3441881071717960329/posts/default/4578343801654586612?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Teknynja/~3/FtnDgokSfQM/vintage-tv-mod-part-i.html" title="Vintage TV Mod, Part I" /><author><name>teknynja</name><uri>http://www.blogger.com/profile/04303366246283189216</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://bp1.blogger.com/_PabczFx81lo/R_oxf3Xq9DI/AAAAAAAAAAQ/GyX6b5FTGRY/S220/profile.png" /></author><thr:total>3</thr:total><feedburner:origLink>http://www.teknynja.com/2008/04/vintage-tv-mod-part-i.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0IGRXkzcCp7ImA9WxZaF0Q.&quot;"><id>tag:blogger.com,1999:blog-3441881071717960329.post-5929527955953475584</id><published>2008-04-13T06:39:00.000-07:00</published><updated>2008-05-02T23:18:44.788-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-05-02T23:18:44.788-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="mods" /><category scheme="http://www.blogger.com/atom/ns#" term="misc" /><title>Mod Home Mod</title><content type="html">&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp1.blogger.com/_PabczFx81lo/SAINpcOYkjI/AAAAAAAAAAc/cZoQSe3pClw/s1600-h/teknynja_kitchen.png"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;" src="http://bp1.blogger.com/_PabczFx81lo/SAINpcOYkjI/AAAAAAAAAAc/cZoQSe3pClw/s400/teknynja_kitchen.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5188724726286553650" /&gt;&lt;/a&gt;&lt;br /&gt;Well, it's official.  I'm gonna have to bust out my home-hacking skills.  My wife and I have finally ordered the cabinets for our kitchen remodel.  We've been planning to do this for over a year, but a long series of life events kept pushing it back.  But last Friday, we finally dropped off the kids with some friends, drove down to the San Diego &lt;a href=http://www.ikea.com/us/en/&gt;Ikea&lt;/a&gt;, and spent about an hour building the order once we got there.&lt;br /&gt;&lt;br /&gt;Of course, I have a few rants about this whole process.  First, I've been using the Ikea HomePlanner software to design and layout our kitchen.  This has to be one of the most frustrating pieces of software on the planet!  First off, it puts several artificial limits on how you can place items in the design.  For example, do you want to stack cabinets on top of each other? Sorry!  Well, there are a few workarounds you can use to try and get close to the layout you want, but they aren't very intuitive and still don't always give you the results you are looking for.  Next up is the fact that some items in the catalog can't be configured with all of the available colors, so the parts list has the wrong color called out for some items (along with the rendering not looking right).  Add to that the fact that even on my quad-core machine, it would take a 10-15 second nap every minute or two (I assume it was making some kind of backup) forcing you to wait and wait and wait.  And those backups were definitely needed, as about once each session, it would just completely crash!  I know what you are thinking, just another noob with some bizarre hardware/software configuration blaming the software for weird behavior – but I ran this app on several different machines, all with the same behavior.  And at &lt;a href=http://www.ikeafans.com/&gt;IkeaFans&lt;/a&gt;, there are plenty of tales of woe about this program.  Many have given up on it all together and use &lt;a href=http://www.sketchup.com/&gt;Google Sketchup&lt;/a&gt; instead.&lt;br /&gt;&lt;br /&gt;So after wrestling with the software, I finally save off a file to my USB flash drive, remembering that they have several customer PC's in the kitchen section of the store running the planner software.  We we arrive at the service desk, our Ikean asks if we have our plans from the designer and I say, “Sure, right here on this flash drive” to which he responds “We can't access flash drives from here.”  WTF?  Fortunately, my wife suggested printing out the plans just before we left, saying not everyone was as technically inclined as the Teknynja – I told her “Everyone uses flash drives.”, but printed out the plans just to be on the safe side.  I should just know that she is always right, and not even argue with her.  There is also the option to upload your plans directly to Ikea, but I was too lazy to create an account just for that!  This is apparently the only way to get your plans to Ikea for ordering.  It would be nice to know that before driving an hour to get to the store.&lt;br /&gt;&lt;br /&gt;Anyway, the cabinets should get here in about a week, and then we have a couple of weekends of other obligations before I start tearing out the old kitchen, fixing up the walls, and start building and installing cabinets.  I get to dust off my mechanical and woodworking skills for a little physical, real world hacking.  I'll keep you posted if anything interesting happens during this project.&lt;img src="http://feeds.feedburner.com/~r/Teknynja/~4/pRA5ClvFMnI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.teknynja.com/feeds/5929527955953475584/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3441881071717960329&amp;postID=5929527955953475584" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3441881071717960329/posts/default/5929527955953475584?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3441881071717960329/posts/default/5929527955953475584?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Teknynja/~3/pRA5ClvFMnI/mod-home-mod.html" title="Mod Home Mod" /><author><name>teknynja</name><uri>http://www.blogger.com/profile/04303366246283189216</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://bp1.blogger.com/_PabczFx81lo/R_oxf3Xq9DI/AAAAAAAAAAQ/GyX6b5FTGRY/S220/profile.png" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://bp1.blogger.com/_PabczFx81lo/SAINpcOYkjI/AAAAAAAAAAc/cZoQSe3pClw/s72-c/teknynja_kitchen.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://www.teknynja.com/2008/04/mod-home-mod.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUAHQnY-fip7ImA9WxZUF04.&quot;"><id>tag:blogger.com,1999:blog-3441881071717960329.post-6843660552715594109</id><published>2008-04-08T19:31:00.000-07:00</published><updated>2008-04-09T03:42:13.856-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-04-09T03:42:13.856-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="podcasts" /><category scheme="http://www.blogger.com/atom/ns#" term="ethics" /><title>Have Mercy On Me</title><content type="html">&lt;p style="margin-bottom: 0in;"&gt;I usually have a couple of hours to kill during my commute to and from work each day, so I end up listening to a lot of podcasts.  Today, on the way home I was listening to the latest from the &lt;a href="http://www.ethicalstl.org/"&gt;Ethical Society of St. Louis&lt;/a&gt;.  Each of their platform addresses inspires me to think a little more about how I go about living life, and I find the leader of the society, Kate Lovelady, conveys her thoughts and insights about ethical living and ideals in an entertaining, yet thought-provoking manner.  This week was the conclusion of her two part series, &lt;a href="http://www.ethicalstl.org/libraryaudio.html"&gt;“From Vengeance to Mercy”&lt;/a&gt;, where she addresses some of the over-arching elements of our society and how they cause us to diverge from a more ethical community.  I recommend these two addresses to anyone who would like a better understanding of forgiveness and mercy.  And for a weekly dose of thought-provoking, insightful, and interesting topics relating to ethics, subscribe to the whole &lt;a href="http://www.ethicalstl.org/podcasts.xml"&gt;feed&lt;/a&gt;.  I sure wish we had an organization like this around these parts!&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Teknynja/~4/iqCzbFmfHIU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.teknynja.com/feeds/6843660552715594109/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3441881071717960329&amp;postID=6843660552715594109" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3441881071717960329/posts/default/6843660552715594109?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3441881071717960329/posts/default/6843660552715594109?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Teknynja/~3/iqCzbFmfHIU/have-mercy-on-me.html" title="Have Mercy On Me" /><author><name>teknynja</name><uri>http://www.blogger.com/profile/04303366246283189216</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://bp1.blogger.com/_PabczFx81lo/R_oxf3Xq9DI/AAAAAAAAAAQ/GyX6b5FTGRY/S220/profile.png" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.teknynja.com/2008/04/have-mercy-on-me.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEEGSH8-cCp7ImA9WxZbF0w.&quot;"><id>tag:blogger.com,1999:blog-3441881071717960329.post-2740761253320265721</id><published>2008-04-07T16:24:00.000-07:00</published><updated>2008-04-20T10:30:29.158-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-04-20T10:30:29.158-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="linux" /><title>Waiting for Heron</title><content type="html">&lt;script src="http://www.ubuntu.com/files/countdown/display.js" type="text/javascript"&gt;&lt;/script&gt;&lt;br /&gt;The countdown to the release of Ubuntu Hardy Heron is on here.  I've had a couple of ex-windows boxes sitting around for the last couple of months, hard drives all cleaned off in preparation.  One of them used to be my main work machine at home, a 2.5Ghz P4 w/3G RAM, and the other was my home theater box running a 2.4Ghz hyper threading CPU with 2G of RAM.  And while the HTPC's replacement system, a 2.6Ghz Dual Core is now happily running MythTV over Ubuntu, the Quad-Core workstation replacement is still booting Windows XP (as my bread and butter is .NET development). &lt;p style="margin-bottom: 0in;"&gt;I've been playing around with Ubuntu for a little over a year now, and although I still consider myself a Linux noob, I feel pretty comfortable working and playing on those machines.  I have an older Pentium II machine sitting under my desk next to my workstation running Ubuntu with its monitor sitting next to my Window's two monitors, sharing the keyboard and mouse via Synergy – so I have quick and easy access to a Ubuntu box for experimentation. I also have a headless Ubuntu box in the garage streaming a distant radio station, so I can listen to it anywhere I have net access – at home, at work (about an hour commute from my house) or on the road via my MDA Smartphone.  I also have a very old laptop with Ubuntu on it, but I hardly use it since it is so underpowered anyway.&lt;/p&gt; &lt;p style="margin-bottom: 0in;"&gt;So when Hardy Heron is released on 24-Apr-2008, I'll be loading it onto my old workstation and replacing the Ubuntu box under my desk, and playing with all the latest wiz-bang Compiz graphics.  As for the old HTPC box, I will probably do a case transplant to move the hardware into something a little less cramped, load Ubuntu on it, and set it up for my wife, who is currently running on an old Win2K box.  And what I am going to do with the two old boxes I free up?  I'm not sure right now, but I'm almost positive they will be running Ubuntu as well!&lt;/p&gt; &lt;p style="margin-bottom: 0in;"&gt;Oh, yeah – welcome to Teknynja, and if you have any questions about the projects going on around here, please feel free to ask!&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Teknynja/~4/BsgO4CtMUGY" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.teknynja.com/feeds/2740761253320265721/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3441881071717960329&amp;postID=2740761253320265721" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3441881071717960329/posts/default/2740761253320265721?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3441881071717960329/posts/default/2740761253320265721?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Teknynja/~3/BsgO4CtMUGY/waiting-for-heron.html" title="Waiting for Heron" /><author><name>teknynja</name><uri>http://www.blogger.com/profile/04303366246283189216</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://bp1.blogger.com/_PabczFx81lo/R_oxf3Xq9DI/AAAAAAAAAAQ/GyX6b5FTGRY/S220/profile.png" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.teknynja.com/2008/04/waiting-for-heron.html</feedburner:origLink></entry></feed>
