This website was originally written in Ruby and hosted on the Raspberry Pi. It's now archived at GitHub for posterity!

Remote Ruby with LIRC

Not to be confused with "IRC", LIRC stands for Linux Infrared Remote Control. It is, as you might have guessed from the name, a suite of tools and drivers geared at getting your infrared remote gear to work with Linux.

Now, alas, I can not regale you with tales of custom-built IR recievers because I happened to have a Philips eHome Infrared Reciever knocking about from an old media-center PC. Getting it to work with Debian on the Pi was a little tricky, however, and this is an exercise I will leave to you. I'd rather talk about getting the working remote doing fancy things in Ruby. Ultimately, though, I didn't really get it working myself; bootc came to my rescue with his cutting-edge kernel for the Pi, which supported my reciever out of the box.

You also need to set up your remote, and for that you can either delve into the pre-configured remotes and hope yours is there, or fire up irrecord and record and name each button.

Once working, the fun begins. LIRC comes with some handy tools which do a number of nifty things in response to remote control button presses. irpty emulates a terminal and forwards remote commands to whatever application you choose to run inside it, irexec can execute commands in response to button presses, and most useful of all for Ruby is ircat which outputs commands to STDOUT.

All of these utilities require a config file which stipulates which command is executed in response to which button. This is usually at ~/.lircrc and has a simple syntax which is well documented at lirc.org. Here's a snippet from mine, specifically for ircat:

begin button = ok prog = clock config = blink end begin button = stop prog = clock config = exit end

I've kept it simple, touching only 3 of the available options. The only mystifying option, "prog", is the program name which I pass into ircat, and effectively creates a group of commands for that particular application. "button" is the name of the remote button, and "config" is the string that ircat will print to its STDOUT in response to that button. Easy!

Now, I mentioned passing a program name to ircat, this should match the program name that you've used in your settings. Ultimately you will be doing something like this from Ruby: "ircat clock --config=/home/pi/.lircrc"

The config file is referenced explicitly because I run clock.rb as root so it can access the GPIO.

I suspect you're eager to see how this works in Ruby, so here we go ( excuse my gratuitous overuse of @@ class variables ):

require 'pty'

@@commands = Array.new

# Spawn an ircat thread for sexy remote commands
if @@ircat.nil?
  @@ircat = Thread.start do
    PTY.spawn("ircat clock --config=/home/pi/.lircrc") do |r,w,pid|
      @@pid = pid
        r.each { |line| @@commands.push line.chomp! }
      end
  end
end

The code really is as simple as it looks. Start a new thread and use PTY to run the ircat "prog". Every time ircat outputs a command to its STDOUT, PTY will slurp it up and append it to the end of the @@commands queue using Array.push. The .chomp! removes any nasty trailing spaces and makes checking the commands simpler.

To process the commands simply .shift ( grab the first item of ) the array, and run it through a case statement or run it through a command processor. Once you've got the command, acting on it is the easy bit. As an example, I used commands to enable my remote to play/pause the clock, and turn on/off individual LEDs ( with the number keys ). The possibilities are endless once you've hooked your script up to an IR remote.

« Back to index Posted on 2012-06-20 by