BBB 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
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