Sunday, January 16, 2011

Writing udev rules

One annoying thing about having a USB-connected Vantage Pro2 weather station is that, occasionally, there is sufficient noise in the line that Linux drops the connection and immediately reconnects. The immediate reconnection is good. What's annoying is that Linux usually assigns it a different device name upon reconnection. So, if I configure my weather station software, weewx with the ttyUSB0 device name, I have to change the configured name after every reconnect (every few months) and risk losing data (though considering that the VP2 data logger keeps up to 2560 records, or 8+ days with a 5 minute interval, it's a small risk).

The solution to this problem is to use a custom udev rule. Udev allows you to do a variety of things with the /dev directory, including providing a single, consistent name for each USB device you connect (no matter what /dev name it gets assigned by the kernel). The following rule creates a symbolic link from /dev/vpro to the current device name for my VP2:

ACTION=="add", ATTRS{interface}=="CP2102 USB to UART Bridge Controller", SYMLINK+="vpro"
This says to add the "vpro" link whenever a device with a matching "interface" attribute is "add"ed (i.e. connected/attached). What's a little tricky about adding a udev rule is figuring out what attribute to match against so that the rule triggers on the device you want (and only that device). For that, you need to know what device name the kernel assigns (what /dev entry),

To find out what to match against, you need to get the information about the device. The following command provides that. You will need to replace /dev/ttyUSB0 with the device name that you are interested in.

udevadm info --attribute-walk --path $(udevadm info --query=path --name=/dev/ttyUSB0) 
The command will yield a hierarchy of information about the device. Information at the beginning is probably too minimal to be useful for matching; information at the bottom is probably too general and will match too many different devices. Look for something towards the top which sounds like it might describe the device. Use the key and value to write a rule like the one I gave above. Put this rule in a file named like 66-vpro.rules in
/etc/udev/rules.d
Note that the number must be two-digit and the extension must be rules. Make sure that the file is world-readable.

To test your rule, restart udev:

sudo /etc/init.d/udev restart
then unplug your device of interest, wait a second, and plug it back in. You should be able to see the effect of your rule. In my case, udev creates a /dev/vpro symlink to the kernel dev entry (e.g. /dev/ttyUSB0 for my VP2).

No comments:

Post a Comment