BBB 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/lib/BBB.rb CHANGED
@@ -2,12 +2,26 @@ require "json"
2
2
  require "stringio"
3
3
 
4
4
  require "BBB/version"
5
+ require "BBB/configuration"
5
6
 
6
- require "BBB/circuit"
7
- require "BBB/exceptions"
8
7
  require "BBB/pins"
9
8
  require "BBB/components"
9
+ require "BBB/attachable"
10
+ require "BBB/circuit"
11
+ require "BBB/exceptions"
10
12
  require "BBB/application"
11
13
 
12
14
  module BBB
15
+
16
+ def self.configuration
17
+ Configuration.instance
18
+ end
19
+
20
+ def self.escape_test(&block)
21
+ old_mode = configuration.test_mode
22
+ configuration.test_mode = false
23
+ yield
24
+ configuration.test_mode = old_mode
25
+ end
26
+
13
27
  end
@@ -1,17 +1,23 @@
1
1
  module BBB
2
2
  class Application
3
3
  include Attachable
4
+ include Components
4
5
 
6
+ ##
7
+ # Start the application by activating the components and
8
+ # load the run loop.
9
+ #
5
10
  def start
6
- activate_components
7
11
  loop do
8
12
  run
9
13
  end
10
14
  end
11
15
 
12
- def activate_components
13
- end
14
-
16
+ ##
17
+ # The run funciton gets called as part of the run loop on every iteration.
18
+ # This is where you put your main application code that needs to be
19
+ # evaluaded.
20
+ #
15
21
  def run
16
22
  raise NotImplementedError
17
23
  end
@@ -0,0 +1,77 @@
1
+ module BBB
2
+ module Attachable
3
+ module ClassMethods
4
+
5
+ def class_components
6
+ @class_components ||= {}
7
+ end
8
+
9
+ def class_component_groups
10
+ @class_component_groups ||= Hash.new { |hash, key| hash[key] = [] }
11
+ end
12
+
13
+ ##
14
+ # Attach a component of a certain type to the circuit
15
+ #
16
+ # @param component [Class] The class of the object you # want to attach.
17
+ # @param opts [Hash] Hash of options that setup the component
18
+ #
19
+ # @option opts [Symbol] :pin The pin position for the component
20
+ # @option opts [Array<Symbol>] :pins The list of pin numbers used on the
21
+ # circuit.
22
+ # @options opts [Symbol] :as The name of the component
23
+ #
24
+ def attach(object, opts={})
25
+ name = opts.delete(:as)
26
+ group = opts.delete(:group)
27
+
28
+ class_components[name] = object
29
+ define_method_for_object(object, name, opts)
30
+
31
+ define_method_for_group(group)
32
+ add_to_group(name, group) if group
33
+ end
34
+
35
+ def define_method_for_object(component, name, opts)
36
+ define_method(name) do
37
+ value = components[name]
38
+ return value if value
39
+
40
+ object = self.class.class_components[name]
41
+ value = object.kind_of?(Class) ? object.new(opts) : object
42
+ components[name] = value
43
+ end
44
+ end
45
+
46
+ def define_method_for_group(group_name)
47
+ return if group_name.nil? || respond_to?(group_name)
48
+ define_method(group_name) do
49
+ if component_groups[group_name].empty?
50
+ component_groups[group_name] = self.class.class_component_groups[group_name]
51
+ end
52
+
53
+ component_groups[group_name].map do |component_name|
54
+ self.send(component_name)
55
+ end
56
+ end
57
+ end
58
+
59
+ def add_to_group(component_name, group_name)
60
+ class_component_groups[group_name] << component_name
61
+ end
62
+
63
+ end
64
+
65
+ def self.included(base)
66
+ base.extend(ClassMethods)
67
+ end
68
+
69
+ def components
70
+ @components ||= {}
71
+ end
72
+
73
+ def component_groups
74
+ @component_groups ||= Hash.new { |hash, key| hash[key] = [] }
75
+ end
76
+ end
77
+ end
@@ -1,51 +1,4 @@
1
1
  module BBB
2
- module Attachable
3
- module ClassMethods
4
-
5
- def class_components
6
- @class_components ||= {}
7
- end
8
-
9
- ##
10
- # Attach a component of a certain type to the circuit
11
- #
12
- # @param component [Class] The class of the object you # want to attach.
13
- # @param opts [Hash] Hash of options that setup the component
14
- #
15
- # @option opts [Symbol] :pin The pin position for the component
16
- # @option opts [Array<Symbol>] :pins The list of pin numbers used on the
17
- # circuit.
18
- # @options opts [Symbol] :as The name of the component
19
- #
20
- def attach(object, opts={})
21
- name = opts.delete(:as)
22
- class_components[name] = object
23
- define_method_for_object(object, name)
24
- end
25
-
26
- def define_method_for_object(component, name)
27
- define_method(name) do
28
- value = components[name]
29
- return value if value
30
-
31
- object = self.class.class_components[name]
32
- value = object.kind_of?(Class) ? object.new : object
33
-
34
- components[name] = value
35
- end
36
- end
37
- end
38
-
39
- def self.included(base)
40
- base.extend(ClassMethods)
41
- end
42
-
43
- def components
44
- @components ||= {}
45
- end
46
-
47
- end
48
-
49
2
  ##
50
3
  # The idea here is to attach a piece of equipment to a circuit.
51
4
  #
@@ -59,6 +12,13 @@ module BBB
59
12
  # boards. For example by mapping P8_3 on BBB to P1 on an Arduino.
60
13
  #
61
14
  class Circuit
15
+ attr_reader :options
16
+
62
17
  include Attachable
18
+ include Components
19
+
20
+ def initialize(options={})
21
+ @options = options
22
+ end
63
23
  end
64
24
  end
@@ -1,10 +1,55 @@
1
1
  module BBB
2
2
  module Components
3
3
  class Button
4
+ attr_reader :status
5
+ attr_accessor :release_callbacks, :press_callbacks
6
+
4
7
  include Pinnable
5
8
 
6
9
  uses BBB::Pins::DigitalInputPin
7
10
 
11
+ def initialize(options={})
12
+ @status = :released
13
+ @release_callbacks = []
14
+ @press_callbacks = []
15
+ end
16
+
17
+ def pressed?
18
+ status == :pressed
19
+ end
20
+
21
+ def released?
22
+ !pressed
23
+ end
24
+
25
+ def press!
26
+ old_state = status
27
+ @status = :pressed
28
+ on_press if old_state != status
29
+ end
30
+
31
+ def release!
32
+ old_state = status
33
+ @status = :released
34
+ on_release if old_state != status
35
+ end
36
+
37
+ def update(value=pin.high?)
38
+ value == true ? press! : release!
39
+ end
40
+
41
+ def on_release(&block)
42
+ @release_callbacks.each{ |c| c.call(status) }
43
+ end
44
+
45
+ def on_press(&block)
46
+ if block_given?
47
+ @press_callbacks << block
48
+ else
49
+ @press_callbacks.each{ |c| c.call(status) }
50
+ end
51
+ end
52
+
8
53
  def high?
9
54
  pin.on?
10
55
  end
@@ -14,11 +59,6 @@ module BBB
14
59
  !high
15
60
  end
16
61
  alias_method :off?, :low?
17
-
18
- def status
19
- pin.status
20
- end
21
- alias_method :state, :status
22
62
  end
23
63
  end
24
64
  end
@@ -17,7 +17,7 @@ module BBB
17
17
  # period of the pin. Use the "after pin initialization" method for that.
18
18
  #
19
19
  def initialize(options={})
20
- set_options
20
+ set_options(options)
21
21
 
22
22
  @period = options.fetch(:period, 20e6)
23
23
  @speed = 0
@@ -49,6 +49,25 @@ module BBB
49
49
  pin.off?
50
50
  end
51
51
 
52
+
53
+ ##
54
+ # Returns the status of the current led
55
+ #
56
+ def status
57
+ on? ? :on : :off
58
+ end
59
+
60
+ ##
61
+ # Toggle the led between on and off
62
+ #
63
+ def toggle!
64
+ if on?
65
+ off!
66
+ elsif off?
67
+ on!
68
+ end
69
+ end
70
+
52
71
  end
53
72
  end
54
73
  end
@@ -130,49 +130,6 @@ module BBB
130
130
  @axis[:y].update(bytes[1])
131
131
  end
132
132
 
133
- class Button
134
- attr_reader :status
135
- attr_accessor :release_callbacks, :press_callbacks
136
-
137
- def initialize
138
- @status = :released
139
- @release_callbacks = []
140
- @press_callbacks = []
141
- end
142
-
143
- def pressed?
144
- status == :pressed
145
- end
146
-
147
- def press!
148
- @status = :pressed
149
- on_press if old_state != status
150
- end
151
-
152
- def release!
153
- old_state = status
154
- @status = :released
155
- on_release if old_state != status
156
- end
157
-
158
- def released?
159
- !pressed
160
- end
161
-
162
- def update(value)
163
- value == true ? release! : press!
164
- end
165
-
166
- def on_release
167
- @release_callbacks.each{ |c| c.call(status) }
168
- end
169
-
170
- def on_press
171
- @press_callbacks.each{ |c| c.call(status) }
172
- end
173
-
174
- end
175
-
176
133
  class ControlAxis
177
134
  attr_accessor :value
178
135
  attr_accessor :change_callbacks
@@ -147,7 +147,10 @@ module BBB
147
147
  # @param options [Hash]
148
148
  #
149
149
  def set_options(options)
150
- @positions = [options.fetch(:pin, nil)].compact
150
+ @positions = [options[:pin],
151
+ options[:pins],
152
+ options[:position],
153
+ options[:path]].flatten.compact
151
154
  end
152
155
  end
153
156
  end
@@ -27,11 +27,15 @@ module BBB
27
27
 
28
28
  attr_reader :gyro, :positions
29
29
 
30
+ ##
31
+ # the WMP uses I2C pins, so you can give it a name like "I2C2_SDA"
32
+ #
30
33
  def initialize(options = {})
31
34
  @started = false
32
35
  @calibrated = false
33
36
  @gyro = Gyro.new
34
37
  @positions = [options.fetch(:i2c, nil)].compact
38
+ @extension = options[:extension]
35
39
  end
36
40
 
37
41
  def start
@@ -0,0 +1,14 @@
1
+ require 'singleton'
2
+
3
+ module BBB
4
+ class Configuration
5
+ include Singleton
6
+
7
+ attr_accessor :test_mode
8
+
9
+ def initialize
10
+ @test_mode = false
11
+ end
12
+ end
13
+ end
14
+
@@ -37,7 +37,7 @@ module BBB
37
37
  # @return [Boolean]
38
38
  #
39
39
  def mock?
40
- @mock ||= @opts.fetch(:mock, false)
40
+ @mock ||= @opts.fetch(:mock, BBB.configuration.test_mode)
41
41
  end
42
42
 
43
43
  ##
@@ -1,3 +1,3 @@
1
1
  module BBB
2
- VERSION = "0.2.0"
2
+ VERSION = "0.3.0"
3
3
  end
@@ -6,23 +6,45 @@ describe BBB::Application do
6
6
  lambda { BBB::Application.new }.should_not raise_exception
7
7
  end
8
8
 
9
+ it "it responds to start" do
10
+ BBB::Application.new.respond_to?(:start).should be_true
11
+ end
12
+
13
+ it "start calls run" do
14
+ app = BBB::Application.new
15
+ app.should_receive(:run).and_raise(StopIteration)
16
+ app.start
17
+ end
18
+
19
+ it "run raises NotImplementedError" do
20
+ app = BBB::Application.new
21
+ lambda { app.run }.should raise_error(NotImplementedError)
22
+ end
23
+
9
24
  class TestLedCircuit < BBB::Circuit
10
- attach BBB::Components::Led, as: :led
25
+ attach Led, as: :led
11
26
  end
12
27
 
13
- class TestConnectionApp < BBB::Application
28
+ class TestCircuitConnectionApp < BBB::Application
14
29
  attach TestLedCircuit, as: :circuit
15
30
  end
16
31
 
17
32
  it "attaches virtual pins to board pins" do
18
- app = TestConnectionApp.new
33
+ app = TestCircuitConnectionApp.new
19
34
  app.circuit.respond_to?(:led).should be_true
20
35
  app.circuit.led.respond_to?(:on!).should be_true
21
36
  end
22
37
 
23
- class FunctionsInApp < BBB::Application
24
- attach TestLedCircuit.new, as: :circuit
38
+ class TestBasicApp < BBB::Application
39
+ attach Led, as: :led
40
+ end
25
41
 
42
+ it "adds helper functions to applications" do
43
+ app = TestBasicApp.new
44
+ app.respond_to?(:led).should be_true
45
+ end
46
+
47
+ class FunctionsInApp < BBB::Application
26
48
  def run
27
49
  raise StopIteration
28
50
  end