Tuesday, April 20, 2010

USB Panic Button with Linux and Python

This article describes how to use a USB Panic Button with Python. The panic button is a pushbutton that can be read over USB. Unfortunately, it only comes with drivers for Windows, so using it with Linux is a bit of a challenge. I found a Perl library that can read the Panic Button using low-level USB operations, so I ported that simple library to Python.

First, download and install PyUSB. (You may also need to install python-devel.)

Next, dowwnload my PanicButton library.

Finally, use the library. The API is very simple: create a button object with PanicButton(), and then call read() on the button to see if the button is pressed. For example, the following code will print "Pressed" when the button is pressed. (I know, a button like this should be more dramatic...)

import PanicButton
import time

button = PanicButton.PanicButton()

while 1:
  if button.read():
    print "Pressed"
  time.sleep(.5)
A couple caveats. First, you need to run the Python code as root in order to access the device. (Maybe you can get around this with udev magic, but I couldn't.) Second, the button actually triggers when it is released, not when it is pressed.

How the library works

By running lsusb, you can see that the Panic Button's USB id is 1130:0202. We use the PyUSB library to get a device object:
class PanicButton:
  def __init__(self):
    # Device is: ID 1130:0202 Tenx Technology, Inc. 
    self.dev = usb.core.find(idVendor=0x1130, idProduct=0x0202)
The Linux kernel grabs the device and makes it into a hidraw device, so we need to detach that kernel driver before using the device:
    try:
      self.dev.detach_kernel_driver(0)
    except Exception, e:
      pass # already unregistered
Reading the status of the device is done through a USB control transfer. All the magic numbers come from the PanicButton Perl library. See details (translated from German).
  def read(self):
    return self.dev.ctrl_transfer(bmRequestType=0xA1, bRequest=1, wValue=0x300, data_or_wLength=8, timeout=500)[0]
Hopefully this will be of help to anyone trying to interface the USB Panic Button through Python.

Tuesday, April 13, 2010

Spanish vocabulary from "Harry Potter y la piedra filosofal"

Recently, I've been attempting to improve my Spanish by reading Harry Potter y la piedra filosofal, the Spanish version of Harry Potter and the Sorcerer's Stone. It's definitely improving my vocabulary, as there are many words I've needed to look up. I've listed many of them below, in the hopes this list may be helpful to others as well.

To make this slightly more relevant to my usual topic of programming languages, I've added Javascript that will show or hide the English translations, which will also show up if you hover over a link. (See the end for explanation of the Javascript.)

How the Javascript works

I'm including some programming content for my regular blog readers, since this is a bit off topic. If you're interested in the Spanish, you can stop reading here :-)

I have two CSS classes, one for the enabled text, and one for the disabled text. I simply change the color to show and hide the text. The #f6f6f6 color is to match the background of my blog page, which isn't quite white.

<style TYPE="text/css"> 
       .enabled {color: black}
       .disabled {color: #f6f6f6}
</style>
Next, each word entry has a span tag around the English text that I want to show or hide:
<a href="http://..." title="to add">añadir</a>
<span class="enabled"> - to add</span>
Then, I have a Javscript function that will toggle the class for each span tag. It simply loops through all the span tags switching ones with the enabled class to the disabled class and vice versa. Other span tags are left alone.
<script language="JavaScript">
function toggle() {
 elts = document.getElementsByTagName("span");
 for (var i = 0; i < elts.length; i++) {
  if (elts[i].className == "enabled") {
   elts[i].className = "disabled";
  } else if (elts[i].className == "disabled") {
   elts[i].className = "enabled";
  }
 }
}
</script>
Finally, the button calls the Javascript toggle routine to toggle the visibility.
<button onclick="toggle();">Show/Hide English</button>

Viking Dishwasher Fault Codes

Here are Viking Dishwasher error codes for anyone who needs them. I was visting family over Easter and the Viking dishwasher quit working - it would run a bit and then stop, with two indicator lights flashing. Inconveniently, the service guy claimed he couldn't come to fix it for two weeks. I knew these flashing lights must be error codes, but I couldn't find the error codes listed anywhere on the internet. It turns out that the fault codes are in the instruction manual for the DFUD041 and DFUD141 dishwashers, but in case anyone is looking for them online, here's a summary. One or more of the mode lights to the right of "PROG" will flash, indicating the problem:
Viking dishwasher control panel
"Heavy" (the pot) flashes - too much water in dishwasher. Contact service.
"Light china" (the wine glass) flashes - A fault with the water inlet. Make sure the water valve is open.
"Quick" (the wine glass with arrows above) flashes - valve leakage. Contact service.
"Pots/Pans" (the pot with an underline) and "Heavy" (the pot) both flash - blocked drain. Remove and clean the coarse strainer. Unscrew and clean the fine strainer. Lift out and clean the fine filter. Make sure the drain hose is not kinked. Make sure the air gap is not clogged. This picture shows the strainers and filter:
Viking dishwasher strainers

The dishwasher's problem turned out to be a blocked drain - specifically a whole almond caught in the strainer. After removing that and cleaning the filters, the dishwasher worked properly and we didn't need to wash the dishes by hand.

Hopefully this information will be helpful if your Viking dishwasher isn't running properly.