Simple ruby wrapper for Delcom build lights on Linux
This isn’t particularly new – I wrote this code a while ago, but it never got “finished” so I never wrote it up…
Many agile dev teams use Delcom USB build lights:
http://delcomproducts.com/productdetails.asp?productnum=804005
Coding for these is apparently quite complex… unless you are on a recent-ish Linux machine, in which case it’s amazingly trivial.
When you plug the light in, if you have the right modules loaded, you’ll get a set of magic files in a directory somewhere under:
/sys/bus/usb/drivers/usbled – on my PC with my light they show up under /sys/bus/usb/drivers/usbled/7-2:1.0, and you only need to care about 3 little virtual files:
-rw-rw-rw- 1 root root 4096 2010-02-12 16:26 blue -rw-rw-rw- 1 root root 4096 2010-02-12 16:26 green -rw-rw-rw- 1 root root 4096 2010-02-12 16:26 red
Those 3 files control the 3 components of the light. You can set or get the colour trivially from the shell, once you know the name:
$ cat /sys/bus/usb/drivers/usbled/7-2:1.0/blue 0 $ echo "1" > /sys/bus/usb/drivers/usbled/7-2:1.0/blue # Blam! The light goes blue! $ cat /sys/bus/usb/drivers/usbled/7-2:1.0/blue 1 $ echo "1" > /sys/bus/usb/drivers/usbled/7-2:1.0/red # and now the light goes purple - red + blue!
That’s really all you need to know – you can read, and write, the red/green/blue elements of the light. A little ruby wrapper I wrote makes for nicer colour names, and automatically works out the path to the light (ok, it just finds the first directory that looks right in the usbled path…):
#!/usr/bin/env ruby
class UsbLight
COLOURNAMES = {
:black => [0,0,0],
:red => [1,0,0],
:green => [0,1,0],
:blue => [0,0,1],
:cyan => [0,1,1],
:magenta => [1,0,1],
:yellow => [1,1,0],
:white => [1,1,1]
}
def initialize
@usbledpath = '/sys/bus/usb/drivers/usbled'
@usbleddev = Dir.new(@usbledpath).find { |f| f =~ /^\d-\d.*/ }
raise "Can't find device in #{@usbledpath}" unless @usbleddev
@usbled = File.join(@usbledpath,@usbleddev)
@lights = {}
%w(red green blue).each do |light|
@lights[light] = File.join(@usbled,light)
raise "can't read #{light} light" unless File.readable?(@lights[light])
raise "can't write #{light} light" unless File.writable?(@lights[light])
end
end
def colour
lights = [read_light("red"),read_light("green"),read_light("blue")]
colour_pattern = COLOURNAMES.detect { |colour, pattern| pattern == lights }
raise "bad colour combo: #{lights.inspect}" if colour_pattern.nil?
colour_pattern[0]
end
def colour=(name)
lights = COLOURNAMES[name.to_sym]
raise "unknown lamp colour: #{name}" unless lights
write_light("red",lights[0])
write_light("green",lights[1])
write_light("blue",lights[2])
end
def off
self.colour = :black
end
private
def read_light(name)
File.new(@lights[name]).read.to_i
end
def write_light(name,value)
open(@lights[name],"w") do |f|
f.puts(value.to_s)
end
end
end
I have a Hudson watcher that uses this to set the light colour – but that’s a subject for another post!
April 8th, 2010 at 10:34 am
Just a note – if using a recent Delcom light, you should check out the ruby driver at http://github.com/ileitch/delcom_904008_driver – apparently the linux kernel doesn’t support new lights (yet!)