Skip to content

Commit

Permalink
cleaning up gpio interface
Browse files Browse the repository at this point in the history
  • Loading branch information
brundage committed Dec 4, 2016
1 parent ca569fc commit 294f9dc
Show file tree
Hide file tree
Showing 9 changed files with 75 additions and 112 deletions.
6 changes: 3 additions & 3 deletions bin/thermostat
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ def relative_humidity_percent; @sensor.rh; end
Thermostat.logger.level = :debug

@sensor = RubyI2C::Device::SI70XX.new
puts "It is #{temperature} with #{relative_humidity_percent.to_f}% relative humidity making the heat index #{heat_index}"
puts "It is #{temperature >> "tempF"} with #{relative_humidity_percent.to_f}% relative humidity making the heat index #{heat_index >> "tempF"}"

cool_controller = Thermostat::HardwareController::RaspberryPi::Relay.new(22)
cool_controller = Thermostat::HardwareController::RaspberryPi::Relay.new(17)
heat_controller = Thermostat::HardwareController::RaspberryPi::Relay.new(27)
fan_controller = Thermostat::HardwareController::RaspberryPi::Relay.new(17)
fan_controller = Thermostat::HardwareController::RaspberryPi::Relay.new(22)

thermostat = Thermostat::Simple.new cooling_controller: cool_controller,
fanning_controller: fan_controller,
Expand Down
17 changes: 0 additions & 17 deletions lib/thermostat/controller.rb

This file was deleted.

26 changes: 3 additions & 23 deletions lib/thermostat/hardware_controller/raspberry_pi.rb
Original file line number Diff line number Diff line change
@@ -1,33 +1,18 @@
class Thermostat::HardwareController
module RaspberryPi
extend Forwardable
include Thermostat::Logger

autoload :GPIO, File.join('thermostat', 'hardware_controller', 'raspberry_pi', 'gpio')
autoload :PinCleaner, File.join('thermostat', 'hardware_controller', 'raspberry_pi', 'pin_cleaner')
autoload :Relay, File.join('thermostat', 'hardware_controller', 'raspberry_pi', 'relay')


def self.gpio; GPIO; end


def self.included(mod)
gpio.set_warnings(false)
end


def clean_up(pin)
gpio.clean_up pin
end


def gpio
Thermostat::HardwareController::RaspberryPi::GPIO
end
def_delegators :GPIO, *GPIO.delegatable_methods


def initialize_pin(pin, **args)
logger.debug(self.class.name) { "Setting pin #{pin} as #{args[:as]} initialized #{args[:initialize]}" }
gpio.setup pin, as: args[:as], initialize: args[:initialize]
setup pin, as: args[:as], initialize: args[:initialize]
end


Expand All @@ -37,10 +22,5 @@ def opposite(direction)
nil
end


def set_numbering(numbering)
gpio.set_numbering numbering if numbering
end

end
end
30 changes: 26 additions & 4 deletions lib/thermostat/hardware_controller/raspberry_pi/gpio.rb
Original file line number Diff line number Diff line change
@@ -1,17 +1,39 @@
module Thermostat::HardwareController::RaspberryPi
module DelegatableMethods
def delegatable_methods
[ :clean_up, :rpi_gpio_loaded?, :setup, :set_high, :set_low, :set_numbering, :set_warnings ]
end
end

begin
require 'rpi_gpio'
GPIO = RPi::GPIO
GPIO = ::RPi::GPIO
GPIO.set_warnings false
module ::RPi::GPIO
extend DelegatableMethods
extend self
def rpi_gpio_loaded?; true; end
end

rescue RuntimeError => e
if( e.message =~ /this gem can only be run on a Raspberry Pi/ )

Thermostat.logger.warn(self.class.name) { "Couldn't load rpi_gpio library (#{e}) - using dummy GPIO" }

module GPIO
def self.clean_up(*); end
def self.set_numbering(*); end
def self.set_warnings(*); end
extend DelegatableMethods
extend self

delegatable_methods.each do |m|
define_method(m) { |*| }
end

def rpi_gpio_loaded?; false; end

end
else
raise e

end
end
end
4 changes: 2 additions & 2 deletions lib/thermostat/hardware_controller/raspberry_pi/relay.rb
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ def open_direction


def toggle(dir)
logger.debug(self.class.name) { "sending #{dir} on pin #{pin} to the gpio" }
gpio.send "set_#{dir}", pin
logger.debug(self.class.name) { "sending set_#{dir} on pin #{pin}" }
send "set_#{dir}", pin
end

end
Expand Down
18 changes: 15 additions & 3 deletions lib/thermostat/simple.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
class Thermostat
class Simple < Controller
class Simple
# Basic 4 and 5-wire thermostats
include Thermostat::Logger

autoload :StateMachine, File.join('thermostat', 'simple', 'state_machine')

Expand All @@ -22,7 +23,9 @@ def heat; switch_to :heating; end
def off; switch_to :idle; end


def cooldown_passed?; true; end
def cooldown_passed?
true
end


def toggle(switch)
Expand All @@ -44,13 +47,22 @@ def toggle(switch)
cooling_controller.off
heating_controller.off
else
logger.debug(self.class.name) { "Don't know how to toggle #{switch} to #{state}" }
logger.error(self.class.name) { "Don't know how to toggle #{switch} to #{state}" }
end
end

private

attr_accessor :cooling_controller, :fanning_controller, :heating_controller, :state_machine

def switch_to(setting)
logger.debug(self.class.name) { "Switching to #{setting}" }
if( state_machine.can_transition_to? setting )
state_machine.transition_to(setting)
else
logger.debug(self.class.name) { "State machine won't allow it" }
end
end

end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
describe Thermostat::HardwareController::RaspberryPi::GPIO do

let(:subject) { described_class }

described_class.delegatable_methods.each do |m|
it "has a #{m} method" do
expect(subject).to respond_to(m)
end
end

context 'testing if the real library was loaded' do
let(:result) { subject.rpi_gpio_loaded? ? :be_truthy : :be_falsey }
it "if the library #{described_class.rpi_gpio_loaded? ? "was" : "wasn't"} loaded, #rpi_gpio_loaded? should #{described_class.rpi_gpio_loaded? ? :be_truthy : :be_falsey}" do
expect(subject.rpi_gpio_loaded?).to send(result)
end
end

end
Original file line number Diff line number Diff line change
@@ -1,21 +1,9 @@
describe Thermostat::HardwareController::RaspberryPi::Relay do

let(:default_close_direction) { :low }
let(:gpio) { double :gpio,
clean_up: nil,
setup: nil,
set_high: nil,
set_low: nil,
set_numbering: nil
}
let(:pin) { nil }
let(:pull) { nil }

before do
allow_any_instance_of(Thermostat::HardwareController::RaspberryPi).to receive(:gpio).and_return(gpio)
end


context 'with no initialization' do
it 'raises an ArgumentError' do
expect{ described_class.new }.to raise_error(ArgumentError)
Expand All @@ -39,8 +27,8 @@
end

shared_examples_for 'opening or closing' do
it "sends the correct direction to the gpio" do
expect(gpio).to have_received(pull)
it "sends itself the correct direction" do
expect(subject).to have_received(pull)
end
end

Expand All @@ -51,6 +39,7 @@
let(:pull) { "set_#{dir == :close ? close_direction : open_direction}" }
let(:subject) { described_class.new pin, close_direction: close_direction }
before do
allow(subject).to receive(pull)
subject.send dir
end

Expand Down
51 changes: 5 additions & 46 deletions spec/cases/thermostat/hardware_controller/raspberry_pi_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,6 @@

let(:klass) { Class.new { include Thermostat::HardwareController::RaspberryPi } }
let(:subject) { klass.new }
let(:gpio) { double :gpio, clean_up: nil, setup: nil, set_numbering: nil }

before do
allow(subject).to receive(:gpio).and_return(gpio)
end


describe 'opposites' do
it 'opposite of :high is :low' do
Expand All @@ -24,47 +18,12 @@
end


describe 'setting up numbering' do
let(:numbering) { :bcm }

before do
subject.set_numbering numbering
end

it 'passes #set_numbering along to the gpio' do
expect(gpio).to have_received(:set_numbering).with(numbering)
end

end


describe 'initializing pins' do
let(:init) { :high }
let(:mode) { :output }
let(:pin) { 1 }

before do
subject.initialize_pin pin, as: mode, initialize: init
context 'forwarding to the gpio' do
[ :clean_up, :setup, :set_numbering, :set_warnings ].each do |m|
it "has a #{m}" do
expect(subject).to respond_to m
end
end

it 'calls gpio#setup' do
expect(gpio).to have_received(:setup)
end

end


describe 'clean up' do
let(:pin) { 1 }

before do
subject.clean_up pin
end

it 'passes #clean_up to the gpio' do
expect(gpio).to have_received(:clean_up).with(pin)
end

end

end

0 comments on commit 294f9dc

Please sign in to comment.