Saturday, January 16, 2010
Linux on the Real User's Desktop: TV Tuners
Thursday, January 7, 2010
Terminal Clients and Retro Fun
I won’t go into the story of why I wanted this except to say that computers existed before the proliferation of the Internet, and sometimes it’s fun to go back in time. In this case, I’ve been using a large number of terminal (telnet) client packages: PuTTY, the generic telnet built into Windows, the telnet clients that come with GNOME and KDE, and so forth.
One issue I discovered is that none of them are set up to display ASCII line drawing characters, so any ANSI art comes out as a complete cluster**** of umlauts and twirliecues.
The magic answer: Code Page 437
Yes, that’s the answer. The problem is, most clients don’t support it anymore because it’s not even close to Unicode compliant.
So, the workaround? Set your terminal’s code page translation to one of the following:
860 (Portugese)
861 (Icelandic)
862 (Hebrew)
865 (Nordic)
I’ve been using CP 862 in all my Linux clients without issue.
In PuTTY, however, you can go to the code translation section of the window menu and type “CP437” into the code page translation box, and you get exactly what you need.
This seems to be a common problem for us old-timers, and the answers aren’t really easy to find. (I spent well over an hour on this stupid thing just so I could getting a spinning ASCII prompt.) Hopefully this saves someone else a headache or two.
Tuesday, January 5, 2010
Barcodes! Ack!
Alas, I've found a use for them -- of all places -- in the home. There is no escape.
After digging into a recent project a little deeper, I've discovered that this is by no means an original idea, but my implementation is independent of anyone else's efforts, so I'll share a little bit of that here.
What I'm attempting to do is run my home in a similar fashion as do many of today's manufacturing facilities: lean. (If you're not familiar with the philosophy, Wikipedia covers lean manufacturing quite well.) This project meshes well with one of my aims toward a more minimalist lifestyle, thus the work.
The idea is to inventory all food items in the house, and keep them stocked at optimum levels with a minimum amount of effort. I know, some people can whip up a grocery list in their head and just be done with it. I'm not one of those people.
My grocery shopping is done at odd times (and usually not even on the same day of the week), so I find it difficult to establish how many of a certain thing I need. When I discover I have the extra time to squeeze in a trip to the store, the last thing I want to do is squander that time running home to take an inventory of what I have. The result is that I'm constantly overstocked on one thing, and completely out of something else. Not very lean.
So my goal is to set up a grocery store scanner in my house. More literally, right next to the garbage can. Every time I use something up, I scan the barcode as I throw the empty wrapper or container away. When I scan the barcode, an attached computer looks up the product in a database, then adds that item to a list of things I need to buy the next time I run to the store. When I’m there, I can have this little doodad e-mail my list to me, which I can retrieve from my phone, and I’m ready to shop.
There are certain concerns I have about initial implementation. Do I scan in my entire inventory, adjust my optimum levels, and let the list fit my ideal inventory from that point forward? Or do I watch for patterns in my consumption and let the software generate my list for me based on recent trends?
All that aside, I ran into my first obstacle this morning while testing out part of my system. There are three major barcode schemes used on U.S. packaging: UPC-A (12 digits), UPC-E (a 6-8 character compressed form of UPC-A), and EAN (a 13-character "global" scheme, which also includes country of origin). EAN is also referenced as UCC-13. The database I'm using to look all these products up only indexes by EAN. Unfortunately, the two versions of UPC are quite prevalent, and of those, many of the smaller items I buy use UPC-E. What now?
Turns out, there is a rather clunky way to convert UPC-E to UPC-A. From there, and according to what I've been able to determine, converting from UPC-A to EAN is as simple as prefixing the string with a U.S. country code (a zero). But getting from UPC-E to UPC-A was the tough part.
I found a couple functions while sifting around online, but they were mainly written in Javascript, and were at least partially broken or not very well factored down. I needed PHP, and I wanted it clean. This function is what I pieced together, using a fairly solid foundation written in Javascript by Rob Williams on the TAL Technologies website as a jumping off point.
function convert_UPCE_to_UPCA($upce) { // Make sure its actually a numeric code -- nothing else is valid if(!is_numeric($upce)) { // Not a valid UPC-E code: exit return($upce); } else { switch (strlen($upce)) { case 6: // Perfect... Leave as-is break; case 7: case 8: // Trim leading digit (and trailing checksum, if present) $upce = substr($upce, 1, 6); break; default: // Any other length is not a valid UPC-E code: exit return($upce); } switch ($upce[5]) { // The sixth character (element 5 in the string) tells us how to decompress case "0": case "1": case "2": $mfr_number = $upce[0].$upce[1].$upce[5]."00"; $item_number = "00".$upce[2].$upce[3].$upce[4]; break; case "3": $mfr_number = $upce[0].$upce[1].$upce[2]."00"; $item_number = "000".$upce[3].$upce[4]; break; case "4": $mfr_number = $upce[0].$upce[1].$upce[2].$upce[3]."0"; $item_number = "0000".$upce[4]; break; default: $mfr_number = $upce[0].$upce[1].$upce[2].$upce[3].$upce[4]; $item_number = "00000".$upce[5]; break; } // Prefix the new UPC-A code with a "0" to denote format, then // add the remainder of the manufacturer and item codes $msg = "0".$mfr_number.$item_number; // Append the checksum digit -- should always equal the UPC-E checksum $msg .= calc_check_digit($msg); // Return the final result return($msg); } }
You'll notice at the end that there's a reference to a function calc_check_digit() that I didn't include above. I discovered that the checksum digit in UPC-A should always be the same as the one provided in a UPC-E barcode. The cheap way to do that is to simply copy it if you have it, but since we sometimes don't (and even if it's provided, we lopped it off at the beginning of the function anyway), here's one solution:
// Calculates the checksum digit // UPCA checksum digit should always be the same as the UPCE digit function calc_check_digit($msg) { // Initialize the checksum $check = 0; // Loop through the message for($x = 1; $x <= 11; $x++) { // Even position digits multiplied by 9, odd by 7 $check = $check + (intval(substr($msg, ($x - 1), 1)) * (9 - (2 * ($x % 2)))); } // Checksum is the modulus of 10 return($check % 10); }
So, we've re-created the checksum. (The "$x % 2" above just returns a boolean value that tells us whether $x is odd or even, so we multiply 2 by either a 1 or 0 and subtract the resulting product from 9. It looks a little funny, but it’s compact, and I love compact.)
We can feed our final EAN into the database lookup, and voila!, out pops our item, complete with description, size per container, &c. If I really want to go crazy, I can assign cost-per-item in the database as well, so that when the system e-mails me my grocery list, I’ll know exactly how much I’ll be spending before I even set foot into the store. Man, would that be slick!
If anyone is interested in more of the project details, leave me a comment, and I’ll post a bit more. There’s a lot more currently rolling on this than just barcodes!