Go green with 5 lines of Ruby

by aaron

I decided to go “green” last weekend and spend a little time reducing the energy consumption of my computer. See, I’ve always left my desktop computer on at home while I’ve been at work or asleep. I’m sort of lazy and suspend never really worked that well in Ubuntu.

After upgrading to 8.04 and finding suspend working, I decided to overcome the “lazy” excuse and write a script that automagically suspends my computer after I’ve left and turns it back on before I come back. Now I never have to think about it (if I’m in a rush) and I can still significantly reduce energy consumption.

Here’s the meat:

#!/usr/bin/ruby
require 'time'
wake_time = Time.parse(ARGV[0])
wake_time += 24 * 60 * 60 if wake_time < Time.now
File.open('/proc/acpi/alarm', 'w') {|f| f << wake_time.utc.strftime('%Y-%m-%d %H:%M:%S')}
system('/etc/acpi/sleep.sh force')

This just takes a single argument representing the next time the computer should start up, sets up the ACPI to wake up at that time, and then suspends the computer.

I have 2 cron jobs set up to use this script:

45 09 * * 1,2,3,4,5 /home/aaron/Projects/Personal/green/sleep.rb 19:00:00
00 02 * * * /home/aaron/Projects/Personal/green/sleep.rb 07:45:00

This means the computer will always be off between 9:45am and 7:00pm on weekdays and between 2:00am and 7:45am every day. Now, sometimes I work late, so if you’re on Ubuntu and use Gnome, here’s a little extension of the script that will display a dialog and give you a chance to cancel the automatic shutdown:

#!/usr/bin/ruby
require 'time'
require 'timeout'
require 'gtk2'
 
begin
  # Wait a few minutes before going on in case we're working late
  Timeout::timeout(5 * 60) do
    dialog = Gtk::Dialog.new('Still awake?', nil, nil, [Gtk::Stock::OK, Gtk::Dialog::RESPONSE_NONE])
    dialog.signal_connect('response') do
      # User is still around
      dialog.destroy
      Gtk.main_quit
    end
    dialog.resize(200, 51)
    dialog.show_all
    Gtk.main
  end
rescue Timeout::Error
  # Time to go to sleep
 
  # Write the time that we're going to wake up next
  wake_time = Time.parse(ARGV[0])
  wake_time += 24 * 60 * 60 if wake_time < Time.now
  File.open('/proc/acpi/alarm', 'w') {|f| f << wake_time.utc.strftime('%Y-%m-%d %H:%M:%S')}
 
  # Suspend the computer
  system('/etc/acpi/sleep.sh force')
end

Every little bit counts ;)

P.S. The dialog extension needs a windowing environment, so I set up KAlarm to replace the cron jobs.

P.P.S. Disclaimer, be careful, blah blah .. you know the story.

Comments

2 Responses to “Go green with 5 lines of Ruby”

  1. Hugh on May 22nd, 2008 6:33 am

    This is great, ruby in general though is not that ‘green’ using a lot of CPU cycles which is a shame. 1.9 should help this situation however.

  2. aaron on May 27th, 2008 9:19 pm

    Hugh: That’s an interesting point :) I wonder if anyone’s done a graph of what programming languages are the “greenest”…

Leave a Reply