rustle 0.1.1 → 0.1.2
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +12 -0
- data/lib/rustle/debug_port.rb +18 -0
- data/lib/rustle/exceptions.rb +9 -0
- data/lib/rustle/frame.rb +8 -0
- data/lib/rustle/receiver.rb +25 -26
- data/lib/rustle/strip.rb +7 -2
- data/lib/rustle/version.rb +1 -1
- data/lib/rustle.rb +3 -0
- data/spec/color_spec.rb +28 -39
- data/spec/frame_spec.rb +16 -0
- data/spec/receiver_spec.rb +28 -1
- data/spec/strip_spec.rb +33 -0
- metadata +6 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5471958598d61f4dc25f459bdad141ada82b1bd0
|
4
|
+
data.tar.gz: 9f0f17ec4a82206000b729e697bffd7778848d68
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6744cbf1557218443148fc94c02f3728af062d97320202323d234e2251415a8696fb2369b2ec9d9401519e4cb5250b621a8a982ff153337f8f317847b6e240b7
|
7
|
+
data.tar.gz: 41a86f55fa7681a319da9853a3dcd3c06aa392daeac3cc91dadbb5cada709ae7a298e6c4d90e6dd3e4e5850b6907a45c45229b13aceb2314fc4f33bab1648368
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,17 @@
|
|
1
1
|
# Rustle Changelog
|
2
2
|
|
3
|
+
## 0.1.2
|
4
|
+
|
5
|
+
#### New
|
6
|
+
|
7
|
+
* Much more spec coverage.
|
8
|
+
* Invalid data handling
|
9
|
+
* **Debug mode**: to make specs easier, Receiver objects can be set to debug mode, in which no actual data will be sent to the Arduino, and instead will be returned as arrays.
|
10
|
+
|
11
|
+
#### Deprecated
|
12
|
+
|
13
|
+
* The old DSL-style Receiver instantiation syntax. See the documentation for Receiver#initialize because the syntax is now quite different.
|
14
|
+
|
3
15
|
## 0.1.1
|
4
16
|
|
5
17
|
#### New
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Rustle
|
2
|
+
# = DebugPort
|
3
|
+
#
|
4
|
+
# This class's purpose is simply to provide a mock serial port for debugging
|
5
|
+
# purposes. Instead of writing to an actual TTY connection, it simply
|
6
|
+
# deserializes and returns the values passed into it. It's convenient because
|
7
|
+
# it allows one to test without requiring a physical Arduino.
|
8
|
+
class DebugPort
|
9
|
+
# @param [String] string the string of chars to be written to the mock
|
10
|
+
# serial port
|
11
|
+
#
|
12
|
+
# @return [Array<Fixnum>] an array containing the deserialized values found
|
13
|
+
# in +string+
|
14
|
+
def write(string)
|
15
|
+
string.chars.map(&:ord)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
data/lib/rustle/exceptions.rb
CHANGED
@@ -7,4 +7,13 @@ module Rustle
|
|
7
7
|
|
8
8
|
# Raised when a user provides an invalid hexadecimal color
|
9
9
|
class InvalidHexColorCode < Error; end
|
10
|
+
|
11
|
+
# Raised when a user does not provide a receiver when instantiating a strip
|
12
|
+
class ReceiverNotFound < Error; end
|
13
|
+
|
14
|
+
# Raised when a user does not specify the number of LEDs for a strip
|
15
|
+
class NumLEDsInvalid < Error; end
|
16
|
+
|
17
|
+
# Raised when a user tries to provide data that is not an array of {Color} objects
|
18
|
+
class InvalidLEDArray < Error; end
|
10
19
|
end
|
data/lib/rustle/frame.rb
CHANGED
@@ -28,6 +28,8 @@ module Rustle
|
|
28
28
|
# @param [Array] leds n array of {Color} objects, whose length is the same
|
29
29
|
# as the number of LEDs connected to the strip.
|
30
30
|
def initialize(leds)
|
31
|
+
validate_leds(leds)
|
32
|
+
|
31
33
|
@leds = leds
|
32
34
|
end
|
33
35
|
|
@@ -38,5 +40,11 @@ module Rustle
|
|
38
40
|
def serialize
|
39
41
|
@leds.map(&:serialize).join + 255.chr
|
40
42
|
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
def validate_leds(arr)
|
47
|
+
raise InvalidLEDArray unless arr.all? { |l| l.is_a? Color }
|
48
|
+
end
|
41
49
|
end
|
42
50
|
end
|
data/lib/rustle/receiver.rb
CHANGED
@@ -11,10 +11,7 @@ module Rustle
|
|
11
11
|
#
|
12
12
|
# The Receiver class is initialized using a block.
|
13
13
|
#
|
14
|
-
# bedroom_arduino = Rustle::Receiver.new
|
15
|
-
# port_file "/dev/[PORT_FILE]"
|
16
|
-
# num_leds 30
|
17
|
-
# end
|
14
|
+
# bedroom_arduino = Rustle::Receiver.new("/dev/[PORT_FILE]")
|
18
15
|
#
|
19
16
|
# Your port file can be found using the Arduino IDE.
|
20
17
|
class Receiver
|
@@ -23,29 +20,33 @@ module Rustle
|
|
23
20
|
# @return [Strip] the strip associated with the Receiver
|
24
21
|
attr_reader :strip
|
25
22
|
|
26
|
-
# Initializes a new receiver.
|
23
|
+
# Initializes a new receiver.
|
27
24
|
#
|
28
25
|
# @example
|
29
|
-
# kitchen_arduino = Rustle::Receiver.new
|
30
|
-
#
|
31
|
-
# num_leds 60
|
32
|
-
# end
|
26
|
+
# kitchen_arduino = Rustle::Receiver.new("/deb/tty.usbmodem411",
|
27
|
+
# num_leds: 30, baud: 921_600, debug: false)
|
33
28
|
#
|
34
|
-
# @
|
29
|
+
# @param [String] port_file the location of serial port file. It can be
|
35
30
|
# found in the Arduino IDE (or via Ino).
|
36
|
-
# @
|
31
|
+
# @param [Fixnum] baud the serial baud rate (make sure it matches the one in
|
37
32
|
# your sketch)
|
38
|
-
# @
|
33
|
+
# @param [Fixnum] num_leds the total number of LEDs connected to your
|
39
34
|
# receiver. Note that this attribute only affects how the {Strip} object
|
40
35
|
# is instantiated; the number of LEDs is not actually stored in the
|
41
36
|
# Receiver object.
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
37
|
+
# @param [Boolean] debug whether or not to enable debug mode. See
|
38
|
+
# {DebugPort}.
|
39
|
+
def initialize(port_file = nil, baud: 921_600, num_leds: 30, debug: false)
|
40
|
+
@port_file = port_file
|
41
|
+
@baud = baud
|
42
|
+
@debug = debug
|
43
|
+
@strip = Strip.new(self, num_leds)
|
47
44
|
|
48
45
|
init_serialport
|
46
|
+
|
47
|
+
# Sending a blank frame upon initialization seems to fix all timing
|
48
|
+
# constraint problems.
|
49
|
+
@strip.off!
|
49
50
|
end
|
50
51
|
|
51
52
|
# Serializes +frame+ and sends it off to the the serial port. +push_frame+
|
@@ -58,16 +59,14 @@ module Rustle
|
|
58
59
|
|
59
60
|
private
|
60
61
|
|
61
|
-
#
|
62
|
-
def port_file(file); @port_file = file; end
|
63
|
-
def baud(int); @baud = int; end
|
64
|
-
def num_leds(count)
|
65
|
-
@strip = Strip.new(self, count)
|
66
|
-
end
|
67
|
-
|
68
|
-
# Instantiates a new serial port
|
62
|
+
# Instantiates a new port
|
69
63
|
def init_serialport
|
70
|
-
|
64
|
+
if @debug
|
65
|
+
@port = DebugPort.new
|
66
|
+
else
|
67
|
+
raise PortFileNotSpecified if @debug == false
|
68
|
+
@port = SerialPort.new @port_file, @baud, 8, 1, SerialPort::NONE
|
69
|
+
end
|
71
70
|
end
|
72
71
|
end
|
73
72
|
end
|
data/lib/rustle/strip.rb
CHANGED
@@ -3,7 +3,7 @@ require 'active_support/inflector'
|
|
3
3
|
module Rustle
|
4
4
|
# = Strips
|
5
5
|
#
|
6
|
-
# The Strip class' purpose is to respond to requests to change the color of
|
6
|
+
# The Strip class's purpose is to respond to requests to change the color of
|
7
7
|
# the physical strip, and send changes to the {Receiver} when appropriate.
|
8
8
|
# All Strip objects also have a buffer, which is simply an array of {Frame}
|
9
9
|
# objects. Calling any method which advances to the next frame causes the
|
@@ -27,6 +27,9 @@ module Rustle
|
|
27
27
|
@receiver = receiver
|
28
28
|
@num_leds = num_leds
|
29
29
|
@queue = []
|
30
|
+
|
31
|
+
raise ReceiverNotFound unless receiver.is_a? Receiver
|
32
|
+
raise NumLEDsInvalid unless @num_leds && @num_leds > 0
|
30
33
|
end
|
31
34
|
|
32
35
|
# @return [Frame] the next frame in the buffer. If the buffer only has one
|
@@ -56,6 +59,7 @@ module Rustle
|
|
56
59
|
|
57
60
|
# Turns off all LEDs on the strip
|
58
61
|
def off!
|
62
|
+
sleep 0.0025
|
59
63
|
@queue << Frame.new([Color.new(0,0,0)] * @num_leds)
|
60
64
|
next_frame!
|
61
65
|
end
|
@@ -64,6 +68,7 @@ module Rustle
|
|
64
68
|
#
|
65
69
|
# @param [Color] color
|
66
70
|
def to(color)
|
71
|
+
sleep 0.0025
|
67
72
|
@queue << Frame.new([color] * @num_leds)
|
68
73
|
next_frame!
|
69
74
|
end
|
@@ -89,7 +94,7 @@ module Rustle
|
|
89
94
|
# :fade_to => FadeToTransition
|
90
95
|
klass = "#{klass.to_s.camelize}Transition".constantize
|
91
96
|
|
92
|
-
klass.new(self, duration, opts)
|
97
|
+
klass.new(self, duration, opts)
|
93
98
|
end
|
94
99
|
end
|
95
100
|
end
|
data/lib/rustle/version.rb
CHANGED
data/lib/rustle.rb
CHANGED
@@ -4,10 +4,13 @@ require "rustle/receiver"
|
|
4
4
|
require "rustle/strip"
|
5
5
|
require "rustle/color"
|
6
6
|
require "rustle/frame"
|
7
|
+
|
7
8
|
require "rustle/transition"
|
8
9
|
require "rustle/transitions/wipe_to_transition"
|
9
10
|
require "rustle/transitions/fade_to_transition"
|
11
|
+
|
10
12
|
require "rustle/exceptions"
|
13
|
+
require "rustle/debug_port"
|
11
14
|
|
12
15
|
module Rustle
|
13
16
|
FRAME_RATE = 60
|
data/spec/color_spec.rb
CHANGED
@@ -8,49 +8,38 @@ describe Rustle::Color do
|
|
8
8
|
let(:color_with_invalid_params) { Rustle::Color.new(-100,1000,0) }
|
9
9
|
|
10
10
|
it "corrects negative rgb values to zero" do
|
11
|
-
(color_with_invalid_params.r).
|
11
|
+
expect(color_with_invalid_params.r).to eq(0)
|
12
12
|
end
|
13
13
|
|
14
14
|
it "corrects very large rgb values to 255" do
|
15
|
-
(color_with_invalid_params.g).
|
15
|
+
expect(color_with_invalid_params.g).to eq(255)
|
16
16
|
end
|
17
17
|
|
18
18
|
it "makes no changes to rgb values between 0 and 255" do
|
19
19
|
color1 = Rustle::Color.new(0,0,0)
|
20
|
-
(color1.r).
|
21
|
-
(color1.g).
|
22
|
-
(color1.b).
|
20
|
+
expect(color1.r).to eq(0)
|
21
|
+
expect(color1.g).to eq(0)
|
22
|
+
expect(color1.b).to eq(0)
|
23
23
|
|
24
24
|
color2 = Rustle::Color.new(255,255,255)
|
25
|
-
(color2.r).
|
26
|
-
(color2.g).
|
27
|
-
(color2.b).
|
25
|
+
expect(color2.r).to eq(255)
|
26
|
+
expect(color2.g).to eq(255)
|
27
|
+
expect(color2.b).to eq(255)
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
31
31
|
describe "#to_a" do
|
32
32
|
it "returns an array" do
|
33
|
-
(color.to_a).
|
33
|
+
expect(color.to_a).to be_a(Array)
|
34
34
|
end
|
35
35
|
|
36
36
|
it "the array has the correct [r,g,b] values" do
|
37
|
-
(color.to_a).
|
37
|
+
expect(color.to_a).to eq([128,128,128])
|
38
38
|
end
|
39
39
|
|
40
40
|
it "rounds decimal values down to the nearest whole number" do
|
41
41
|
fractional_rgbs = Rustle::Color.rgb(0.5,10.7,99.9)
|
42
|
-
(fractional_rgbs.to_a).
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
describe "#to_s" do
|
47
|
-
it "returns a string with information about the color" do
|
48
|
-
(color.to_s).should eq("rgb(128, 128, 128)")
|
49
|
-
end
|
50
|
-
|
51
|
-
it "pads strings so that even small rgb values align properly" do
|
52
|
-
other_color = Rustle::Color.rgb(0,1,2)
|
53
|
-
(other_color.to_s).should eq("rgb( 0, 1, 2)")
|
42
|
+
expect(fractional_rgbs.to_a).to eq([0, 10, 99])
|
54
43
|
end
|
55
44
|
end
|
56
45
|
|
@@ -60,11 +49,11 @@ describe Rustle::Color do
|
|
60
49
|
let(:colorB) { Rustle::Color.rgb(0, 0, 0) }
|
61
50
|
|
62
51
|
it "returns true if the reciever and parameter objects hold equivalent rgb values" do
|
63
|
-
(colorA.eql?(another_colorA)).
|
52
|
+
expect(colorA.eql?(another_colorA)).to be_true
|
64
53
|
end
|
65
54
|
|
66
55
|
it "returns false if the reciever and parameter objects differ in rgb values" do
|
67
|
-
(colorA.eql?(colorB)).
|
56
|
+
expect(colorA.eql?(colorB)).to be_false
|
68
57
|
end
|
69
58
|
end
|
70
59
|
|
@@ -75,11 +64,11 @@ describe Rustle::Color do
|
|
75
64
|
let (:badass) { Rustle::Color.hex "BADA55" }
|
76
65
|
|
77
66
|
it "creates a color object" do
|
78
|
-
(badass).
|
67
|
+
expect(badass).to be_a(Rustle::Color)
|
79
68
|
end
|
80
69
|
|
81
70
|
it "has the proper rgb values" do
|
82
|
-
(badass).
|
71
|
+
expect(badass).to eql(badass_rgb)
|
83
72
|
end
|
84
73
|
end
|
85
74
|
|
@@ -87,11 +76,11 @@ describe Rustle::Color do
|
|
87
76
|
let(:badass) { Rustle::Color.hex "#BADA55" }
|
88
77
|
|
89
78
|
it "creates a color object" do
|
90
|
-
(badass).
|
79
|
+
expect(badass).to be_a(Rustle::Color)
|
91
80
|
end
|
92
81
|
|
93
82
|
it "has the right rgb values" do
|
94
|
-
(badass).
|
83
|
+
expect(badass).to eql(badass_rgb)
|
95
84
|
end
|
96
85
|
end
|
97
86
|
|
@@ -100,18 +89,18 @@ describe Rustle::Color do
|
|
100
89
|
let(:bad_rgb) { Rustle::Color.rgb 187, 170, 221 }
|
101
90
|
|
102
91
|
it "creates a color object" do
|
103
|
-
(bad_hex).
|
92
|
+
expect(bad_hex).to be_a(Rustle::Color)
|
104
93
|
end
|
105
94
|
|
106
95
|
it "should have the correct rgb values" do
|
107
|
-
(bad_hex).
|
96
|
+
expect(bad_hex).to eql(bad_rgb)
|
108
97
|
end
|
109
98
|
end
|
110
99
|
|
111
100
|
it "is case insensitive" do
|
112
101
|
first_badass = Rustle::Color.hex "#BADa55"
|
113
102
|
second_badass = Rustle::Color.hex "#badA55"
|
114
|
-
(first_badass).
|
103
|
+
expect(first_badass).to eql(second_badass)
|
115
104
|
end
|
116
105
|
|
117
106
|
it "raises an error when given an invalid color code string" do
|
@@ -127,14 +116,14 @@ describe Rustle::Color do
|
|
127
116
|
# HSV: 260 (260), saturation: 23 (23.0769), value: 87 (86.6667)
|
128
117
|
|
129
118
|
it "produces a color object" do
|
130
|
-
hsb.
|
119
|
+
expect(hsb).to be_a(Rustle::Color)
|
131
120
|
end
|
132
121
|
|
133
122
|
it "has the correct rgb properties" do
|
134
123
|
# Use be_within to give some allowance for rounting errors
|
135
|
-
(hsb.r).
|
136
|
-
(hsb.g).
|
137
|
-
(hsb.b).
|
124
|
+
expect(hsb.r).to be_within(3).of(rgb.r)
|
125
|
+
expect(hsb.g).to be_within(3).of(rgb.g)
|
126
|
+
expect(hsb.b).to be_within(3).of(rgb.b)
|
138
127
|
end
|
139
128
|
end
|
140
129
|
|
@@ -142,14 +131,14 @@ describe Rustle::Color do
|
|
142
131
|
let(:hsb) { Rustle::Color.hsb 180, 0.5, 0.8 }
|
143
132
|
|
144
133
|
it "returns an array of [h,s,v] coordinates" do
|
145
|
-
color.to_hsb.
|
134
|
+
expect(color.to_hsb).to be_a(Array)
|
146
135
|
end
|
147
136
|
|
148
137
|
it "should have the (approximate) [h,s,v] coordinates" do
|
149
138
|
hsb_arr = hsb.to_hsb
|
150
|
-
hsb_arr[0].
|
151
|
-
hsb_arr[1].
|
152
|
-
hsb_arr[2].
|
139
|
+
expect(hsb_arr[0]).to be_within(1).of(180)
|
140
|
+
expect(hsb_arr[1]).to be_within(0.1).of(0.5)
|
141
|
+
expect(hsb_arr[2]).to be_within(0.1).of(0.8)
|
153
142
|
end
|
154
143
|
|
155
144
|
end
|
data/spec/frame_spec.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Rustle::Frame do
|
4
|
+
describe "initialization" do
|
5
|
+
it "should require a valid array of LEDs" do
|
6
|
+
valid = [Rustle::Color.rgb(255, 0, 0)] * 5
|
7
|
+
invalid = ["poop"] * 5
|
8
|
+
|
9
|
+
expect { Rustle::Frame.new(invalid) }
|
10
|
+
.to raise_error(Rustle::InvalidLEDArray)
|
11
|
+
|
12
|
+
expect { Rustle::Frame.new(valid) }
|
13
|
+
.not_to raise_error
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
data/spec/receiver_spec.rb
CHANGED
@@ -1,5 +1,32 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Rustle::Receiver do
|
4
|
-
|
4
|
+
describe "#initialize" do
|
5
|
+
let(:receiver) do
|
6
|
+
Rustle::Receiver.new(nil, num_leds: 30, debug: true)
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should intantiate a Strip with the appropriate number of LEDs" do
|
10
|
+
expect(receiver.strip).to be_a(Rustle::Strip)
|
11
|
+
expect(receiver.strip.num_leds).to eq(30)
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should only require a portfile when not in debug mode" do
|
15
|
+
expect { Rustle::Receiver.new(nil, debug: false) }
|
16
|
+
.to raise_error(Rustle::PortFileNotSpecified)
|
17
|
+
expect { Rustle::Receiver.new(nil, debug: true) }
|
18
|
+
.not_to raise_error
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe "#push_frame" do
|
23
|
+
let(:receiver) do
|
24
|
+
Rustle::Receiver.new(nil, num_leds: 30, debug: true)
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should send a frame to the port" do
|
28
|
+
frame = Rustle::Frame.new([Rustle::Color.new(0,0,0)] * 30)
|
29
|
+
expect(receiver.push_frame(frame)).to have(91).items
|
30
|
+
end
|
31
|
+
end
|
5
32
|
end
|
data/spec/strip_spec.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Rustle::Strip do
|
4
|
+
context "when initializing" do
|
5
|
+
it "should require a receiver" do
|
6
|
+
expect { Rustle::Strip.new(nil, 30) }.to raise_error(Rustle::ReceiverNotFound)
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should require an LED count" do
|
10
|
+
receiver = Rustle::Receiver.new(nil, debug: true)
|
11
|
+
expect { Rustle::Strip.new(receiver, nil) }.to raise_error(Rustle::NumLEDsInvalid)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
describe "queue" do
|
16
|
+
let(:strip) { Rustle::Receiver.new(nil, num_leds: 5, debug: true).strip }
|
17
|
+
|
18
|
+
it "should be initialized with a black frame" do
|
19
|
+
expect(strip.current_frame).to_not be_nil
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should be initialized with a black frame" do
|
23
|
+
frame = Rustle::Frame.new [Rustle::Color.new(255, 0, 0)] * 5
|
24
|
+
|
25
|
+
strip.queue_frames [frame]
|
26
|
+
expect(strip.next_frame).to_not be_nil
|
27
|
+
|
28
|
+
# After advancing to the next frame, there shouldn't be a next_frame
|
29
|
+
strip.next_frame!
|
30
|
+
expect(strip.next_frame).to eq(strip.current_frame)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rustle
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrew Hamon
|
@@ -117,6 +117,7 @@ files:
|
|
117
117
|
- Rakefile
|
118
118
|
- lib/rustle.rb
|
119
119
|
- lib/rustle/color.rb
|
120
|
+
- lib/rustle/debug_port.rb
|
120
121
|
- lib/rustle/exceptions.rb
|
121
122
|
- lib/rustle/frame.rb
|
122
123
|
- lib/rustle/receiver.rb
|
@@ -129,8 +130,10 @@ files:
|
|
129
130
|
- rustle_logo.png
|
130
131
|
- sketches/basic.ino
|
131
132
|
- spec/color_spec.rb
|
133
|
+
- spec/frame_spec.rb
|
132
134
|
- spec/receiver_spec.rb
|
133
135
|
- spec/spec_helper.rb
|
136
|
+
- spec/strip_spec.rb
|
134
137
|
homepage: ''
|
135
138
|
licenses:
|
136
139
|
- MIT
|
@@ -158,6 +161,8 @@ specification_version: 4
|
|
158
161
|
summary: Control an individually-addressable RGB LED strip in Ruby.
|
159
162
|
test_files:
|
160
163
|
- spec/color_spec.rb
|
164
|
+
- spec/frame_spec.rb
|
161
165
|
- spec/receiver_spec.rb
|
162
166
|
- spec/spec_helper.rb
|
167
|
+
- spec/strip_spec.rb
|
163
168
|
has_rdoc:
|