Use AWS_PROFILE when working with AWS SDKs of all kinds

It turns out that if you set an environment variable named AWS_PROFILE, all AWS SDKs (including the CLI) will respect that value when looking for credentials for the current command.

Thanks to my brother, Ben, for pointing this out to me. It cleaned up a ton of boilerplate in some Ruby code I’ve been writing.

GPIO Button Handling on RaspberryPi in Ruby

I’ve working on adding some physical controls to my kitchen status display. The setup is very simple, and for a first-run all I wanted to be able to do was detect a button press, and run a script somewhere on the system.

I couldn’t find any existing code that does this (please point some out if you know of any), though there’s plenty of code out there for button handling in general.

Also, most of the code out there for doing GPIO work is either in C or Python, and I was hoping for a Ruby solution, or at least a solution that would be easy to wrap in Ruby.

In the end I learned about how to interface with the GPIO system on RPi via the filesystem.

From there, I found this code from Aaron Patterson using epoll to monitor for changes in the level on the monitored pin. That seemed like it would work, but the epoll gem seems to be unmaintained at this point. Instead, I went with the Sleepy Penguin gem, which provides an interface to the same underlying Linux filesystem events.

Lastly, I wanted my pin pulled high by default, and there’s no way to do that via Sysfs, so I ended up using the gpio utility to set the pin state and pull up resistor.

From there, I was able to run this little script, which will output the current state of the pin when it changes.

# install gpio command line tool
# gpio -g mode 16 up
require 'sleepy_penguin'

def watch pin, on:
  
  puts "Setup Export"
  File.binwrite "/sys/class/gpio/export", pin.to_s

  
  puts "Setup Edge"
  
  retries = 0
  begin
    
    File.binwrite "/sys/class/gpio/gpio#{pin}/edge", on
  rescue
    raise if retries > 3
    sleep 0.1
    retries += 1
    retry
  end

  puts "Read Value"
  
  fd = File.open "/sys/class/gpio/gpio#{pin}/value", 'r'
  yield fd.read.chomp

  puts "Setup epoll"

  epoll = SleepyPenguin::Epoll.new
  epoll.add fd, SleepyPenguin::Epoll::PRI

  puts "Start loop wait"
  loop do
    fd.seek 0, IO::SEEK_SET
    epoll.wait do
      # yield fd.read.chomp
      value = fd.read.chomp
      p value
    end
  end
ensure
  
  File.binwrite "/sys/class/gpio/unexport", pin.to_s
end

pin = 16

watch pin, on: 'both' do |value|
  p value
end

Still to come: debouncing, better handling of a change event, and hopefully wrapping it all up into something much easier to work with.