limitless-led 0.0.4 → 0.1.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.
- checksums.yaml +4 -4
- data/README.md +21 -1
- data/bin/server +5 -8
- data/examples/demo.rb +18 -6
- data/lib/limitless_led.rb +4 -0
- data/lib/limitless_led/bridge.rb +8 -37
- data/lib/limitless_led/logger.rb +11 -2
- data/lib/limitless_led/server.rb +16 -2
- data/lib/limitless_led/version.rb +1 -1
- data/spec/bridge_spec.rb +83 -0
- data/spec/logger_spec.rb +5 -0
- data/spec/server_spec.rb +41 -0
- metadata +8 -4
- data/spec/limitless_led_spec.rb +0 -44
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6d1f24493fb0e1bf0d62283ed57df1023164eb0c
|
4
|
+
data.tar.gz: 80b13e7fc94f52ce3238d1a1700295daea7de6c5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dc3eef7c107828f3bb958d84e88e3f9fde501668205db6e8ecf045abc40bc12948dc840fc6ba86ff68f038c45c8b1a3667c0eec2a963e1d1a766f29aa627bcba
|
7
|
+
data.tar.gz: abfc458f4eb38b41404b03a1fe733f24720c06f5b909224d737578e9d3abaffae0bd3307d3b9359ac76ec4f20ff9accb1990571f364ee2b1dbc797cfcbeafbd2
|
data/README.md
CHANGED
@@ -18,7 +18,27 @@ Or install it yourself as:
|
|
18
18
|
|
19
19
|
## Usage
|
20
20
|
|
21
|
-
|
21
|
+
``` ruby
|
22
|
+
require 'limitless_led'
|
23
|
+
|
24
|
+
# If you don't have a LimitlessLED handy you can start the development
|
25
|
+
# server by running bin/server, it logs to stdout
|
26
|
+
bridge = LimitlessLed::Bridge.new(host: 'localhost', port: 8899)
|
27
|
+
|
28
|
+
# Send in hex like this:
|
29
|
+
bridge.color "#ff0000"
|
30
|
+
|
31
|
+
# You can send a triple
|
32
|
+
bridge.color "#f00"
|
33
|
+
|
34
|
+
# Again if you don't have the LimitlessLED, you can create an instance
|
35
|
+
# of the development server, we run it in an eventmachine reactor loop
|
36
|
+
# in bin/server
|
37
|
+
server = LimitlessLed::Server.new(host: 'localhost', port: 8899)
|
38
|
+
|
39
|
+
# Then you can see what the server does when it receives messages
|
40
|
+
server.receive_data("\x40\x00\xff")
|
41
|
+
```
|
22
42
|
|
23
43
|
## Contributing
|
24
44
|
|
data/bin/server
CHANGED
@@ -4,15 +4,12 @@ require 'optparse'
|
|
4
4
|
require 'eventmachine'
|
5
5
|
require 'limitless_led'
|
6
6
|
|
7
|
-
options = {}
|
7
|
+
options = { port: 8899 }
|
8
8
|
|
9
|
-
optparse = OptionParser.new do|opts|
|
9
|
+
optparse = OptionParser.new do |opts|
|
10
10
|
opts.banner = "Usage: server [options]"
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
opts.on( '-p', '--port [PORT]', "Optional port" ) do|f|
|
15
|
-
options[:port] = f
|
11
|
+
opts.on('-p', '--port [PORT]', "Optional port") do |port|
|
12
|
+
options[:port] = port
|
16
13
|
end
|
17
14
|
end
|
18
15
|
|
@@ -21,5 +18,5 @@ optparse.parse!
|
|
21
18
|
puts ">> Starting Limitless LED Server running on port: #{options[:port]}"
|
22
19
|
|
23
20
|
EM.run do
|
24
|
-
EM.open_datagram_socket('
|
21
|
+
EM.open_datagram_socket('localhost', options[:port], LimitlessLed::Server)
|
25
22
|
end
|
data/examples/demo.rb
CHANGED
@@ -2,10 +2,22 @@
|
|
2
2
|
|
3
3
|
require 'limitless_led'
|
4
4
|
|
5
|
-
#
|
6
|
-
|
5
|
+
# If you don't have a LimitlessLED handy you can start the development
|
6
|
+
# server by running bin/server, it logs to stdout
|
7
|
+
bridge = LimitlessLed::Bridge.new(host: 'localhost', port: 8899)
|
8
|
+
|
9
|
+
# Send in hex like this:
|
10
|
+
bridge.color "#ff0000"
|
11
|
+
|
12
|
+
# You can send a triple
|
13
|
+
bridge.color "#f00"
|
14
|
+
|
15
|
+
# Again if you don't have the LimitlessLED, you can create an instance
|
16
|
+
# of the development server
|
17
|
+
server = LimitlessLed::Server.new(host: 'localhost', port: 8899)
|
18
|
+
|
19
|
+
# Then you can see what the server does when it receives messages
|
20
|
+
server.receive_data("\x40\x00\xff")
|
21
|
+
|
22
|
+
|
7
23
|
|
8
|
-
(0..255).each do |int|
|
9
|
-
bridge.send_packet "\x40#{ int.to_s(16).hex.chr }\x55"
|
10
|
-
sleep 0.025
|
11
|
-
end
|
data/lib/limitless_led.rb
CHANGED
data/lib/limitless_led/bridge.rb
CHANGED
@@ -27,47 +27,18 @@ module LimitlessLed
|
|
27
27
|
socket.send packet, 0
|
28
28
|
end
|
29
29
|
|
30
|
-
# This
|
31
|
-
#
|
32
|
-
# real led which command to expect, most commands are 3-4 bytes long total
|
33
|
-
# and always end with 0x55
|
34
|
-
def run(input)
|
35
|
-
command = input.bytes
|
36
|
-
|
37
|
-
case command.first
|
38
|
-
when 64
|
39
|
-
color command[1]
|
40
|
-
when 65..77
|
41
|
-
raise 'command not implemented'
|
42
|
-
else
|
43
|
-
log "invalid command received: #{command.first}: #{command}"
|
44
|
-
end
|
45
|
-
|
46
|
-
end
|
47
|
-
|
48
|
-
private
|
49
|
-
|
50
|
-
# this receives and integer as the color value from 0-255, this value
|
51
|
-
# maps directly to the dial on the limitless-led controller and app where
|
52
|
-
# the color at 12 o'clock is 0, the colors are mapped clockwise around
|
53
|
-
# the dial with 255 being almost the same color as 0, this is because the
|
54
|
-
# color space we are using is HSL.
|
30
|
+
# This sets the color of the LED with a hex value for the color the packets
|
31
|
+
# are sent to the socket for the command
|
55
32
|
def color(color)
|
56
33
|
|
57
|
-
#
|
58
|
-
|
59
|
-
color = color.to_f / 255.0 * 360.0
|
60
|
-
|
61
|
-
# Rotate 90 degrees and flip to match dial ui on device
|
62
|
-
hue = color - 90
|
63
|
-
|
64
|
-
# Return the color
|
65
|
-
color = Color::HSL.new( hue, 90, 50)
|
34
|
+
# receive color as string like #ff0000 or a triplet
|
35
|
+
color = Color::RGB.from_html(color).to_hsl
|
66
36
|
|
67
|
-
#
|
68
|
-
|
69
|
-
log_color color
|
37
|
+
# Transform color into value out of 255
|
38
|
+
hue = color.hue / 360.0 * 255.0
|
70
39
|
|
40
|
+
# send command
|
41
|
+
send_packet "\x40#{ hue.to_i.chr }\x55"
|
71
42
|
end
|
72
43
|
|
73
44
|
end
|
data/lib/limitless_led/logger.rb
CHANGED
@@ -7,10 +7,19 @@ module LimitlessLed
|
|
7
7
|
puts "#{DateTime.now.to_s} : #{message}"
|
8
8
|
end
|
9
9
|
|
10
|
+
# this receives and integer as the color value from 0-255, this value
|
11
|
+
# maps directly to the dial on the limitless-led controller and app where
|
12
|
+
# the color at 12 o'clock is 0, the colors are mapped clockwise around
|
13
|
+
# the dial with 255 being almost the same color as 0, this is because the
|
14
|
+
# color space we are using is HSL.
|
10
15
|
def log_color(color)
|
11
16
|
|
12
|
-
#
|
13
|
-
|
17
|
+
# Turn second byte int a value out of 360, this is because HSL color maps
|
18
|
+
# the hue on a radial scale so the first and last values are the same color
|
19
|
+
hue= color.to_f / 255.0 * 360.0
|
20
|
+
|
21
|
+
# Return the color
|
22
|
+
color = Color::HSL.new( hue, 100, 50).to_rgb
|
14
23
|
|
15
24
|
# Get each channel and prepare for loggers output
|
16
25
|
red = color.r * 255
|
data/lib/limitless_led/server.rb
CHANGED
@@ -14,8 +14,22 @@ module LimitlessLed
|
|
14
14
|
@bridge = LimitlessLed::Bridge.new(host: host, port: port)
|
15
15
|
end
|
16
16
|
|
17
|
-
|
18
|
-
|
17
|
+
# This method dispatches the raw command in bytes to the proper method used
|
18
|
+
# to run commands for the led the first byte in the command code tells the
|
19
|
+
# real led which command to expect, most commands are 3-4 bytes long total
|
20
|
+
# and always end with 0x55
|
21
|
+
def receive_data(input)
|
22
|
+
command = input.bytes
|
23
|
+
|
24
|
+
case command.first
|
25
|
+
when 64
|
26
|
+
log_color command[1]
|
27
|
+
when 65..77
|
28
|
+
raise LimitlessLed::CommandNotImplemented
|
29
|
+
else
|
30
|
+
raise LimitlessLed::UnknownCommand
|
31
|
+
end
|
32
|
+
|
19
33
|
end
|
20
34
|
|
21
35
|
end
|
data/spec/bridge_spec.rb
ADDED
@@ -0,0 +1,83 @@
|
|
1
|
+
# Tests should cover these commands, which can also be found here:
|
2
|
+
# http://www.limitlessled.com/dev/
|
3
|
+
|
4
|
+
# All UDP Commands are 3 Bytes. First byte is from the list below, plus a fixed 2 byte suffix of 0x00 (decimal: 0) and 0x55 (decimal: 85)
|
5
|
+
# i.e. to turn all RGBW COLOR LimitlessLED Smart lights to ON then send the TCP/IP UDP packet of: 0x42 0x00 0x55
|
6
|
+
#
|
7
|
+
# Hexidecimal (byte) Decimal (integer)
|
8
|
+
#
|
9
|
+
# RGBW COLOR LED ALL OFF 0x41 65
|
10
|
+
# RGBW COLOR LED ALL ON 0x42 66
|
11
|
+
#
|
12
|
+
# DISCO SPEED SLOWER 0x43 67
|
13
|
+
# DISCO SPEED FASTER 0x44 68
|
14
|
+
#
|
15
|
+
# GROUP 1 ALL ON 0x45 69 (SYNC/PAIR RGB+W Bulb within 2 seconds of Wall Switch Power being turned ON)
|
16
|
+
# GROUP 1 ALL OFF 0x46 70
|
17
|
+
# GROUP 2 ALL ON 0x47 71 (SYNC/PAIR RGB+W Bulb within 2 seconds of Wall Switch Power being turned ON)
|
18
|
+
# GROUP 2 ALL OFF 0x48 72
|
19
|
+
# GROUP 3 ALL ON 0x49 73 (SYNC/PAIR RGB+W Bulb within 2 seconds of Wall Switch Power being turned ON)
|
20
|
+
# GROUP 3 ALL OFF 0x4A 74
|
21
|
+
# GROUP 4 ALL ON 0x4B 75 (SYNC/PAIR RGB+W Bulb within 2 seconds of Wall Switch Power being turned ON)
|
22
|
+
# GROUP 4 ALL OFF 0x4C 76
|
23
|
+
#
|
24
|
+
# DISCO MODE 0x4D 77
|
25
|
+
#
|
26
|
+
# SET COLOR TO WHITE (GROUP ALL) 0x42 100ms followed by: 0xC2
|
27
|
+
# SET COLOR TO WHITE (GROUP 1) 0x45 100ms followed by: 0xC5
|
28
|
+
# SET COLOR TO WHITE (GROUP 2) 0x47 100ms followed by: 0xC7
|
29
|
+
# SET COLOR TO WHITE (GROUP 3) 0x49 100ms followed by: 0xC9
|
30
|
+
# SET COLOR TO WHITE (GROUP 4) 0x4B 100ms followed by: 0xCB
|
31
|
+
|
32
|
+
|
33
|
+
require 'spec_helper'
|
34
|
+
|
35
|
+
describe LimitlessLed::Bridge do
|
36
|
+
|
37
|
+
let(:params) { {} }
|
38
|
+
subject { LimitlessLed::Bridge.new(params) }
|
39
|
+
|
40
|
+
describe 'can be initialized with default values' do
|
41
|
+
its(:host) { should == 'localhost' }
|
42
|
+
its(:port) { should == 8899 }
|
43
|
+
end
|
44
|
+
|
45
|
+
describe 'can be initialized with a host and port' do
|
46
|
+
let(:params) { { host: '192.168.100.100', port: 6666 } }
|
47
|
+
|
48
|
+
its(:host) { should == '192.168.100.100' }
|
49
|
+
its(:port) { should == 6666 }
|
50
|
+
end
|
51
|
+
|
52
|
+
describe '#color' do
|
53
|
+
it 'changes color' do
|
54
|
+
subject.send(:send_packet, "\x40\xFF\x55")
|
55
|
+
|
56
|
+
# true.should be_true
|
57
|
+
# subject.should_receive(:send_packet).with("\x40\xFF\x55")
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
describe '#send_packet' do
|
62
|
+
it 'should create a new socket and send the packet' do
|
63
|
+
|
64
|
+
fake_socket = double(:fake_udp_socket)
|
65
|
+
fake_socket.should_receive(:connect).with( subject.host, subject.port )
|
66
|
+
fake_socket.should_receive(:send).with("\x40\xFF\x55", 0)
|
67
|
+
|
68
|
+
UDPSocket.should_receive(:new) { fake_socket }
|
69
|
+
|
70
|
+
subject.send(:send_packet, "\x40\xFF\x55")
|
71
|
+
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'should raise an exception when improperly formed commands are sent' do
|
75
|
+
# subject.send(:send_packet, "\x40\xFF\x55")
|
76
|
+
# subject.should_receive(:new) { fake_socket }
|
77
|
+
should raise_error(HipChat::UnknownResponseCode)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
82
|
+
|
83
|
+
|
data/spec/logger_spec.rb
ADDED
data/spec/server_spec.rb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
# Tests should cover these commands, which can also be found here:
|
2
|
+
# http://www.limitlessled.com/dev/
|
3
|
+
|
4
|
+
# All UDP Commands are 3 Bytes. First byte is from the list below, plus a fixed 2 byte suffix of 0x00 (decimal: 0) and 0x55 (decimal: 85)
|
5
|
+
# i.e. to turn all RGBW COLOR LimitlessLED Smart lights to ON then send the TCP/IP UDP packet of: 0x42 0x00 0x55
|
6
|
+
#
|
7
|
+
# Hexidecimal (byte) Decimal (integer)
|
8
|
+
#
|
9
|
+
# RGBW COLOR LED ALL OFF 0x41 65
|
10
|
+
# RGBW COLOR LED ALL ON 0x42 66
|
11
|
+
#
|
12
|
+
# DISCO SPEED SLOWER 0x43 67
|
13
|
+
# DISCO SPEED FASTER 0x44 68
|
14
|
+
#
|
15
|
+
# GROUP 1 ALL ON 0x45 69 (SYNC/PAIR RGB+W Bulb within 2 seconds of Wall Switch Power being turned ON)
|
16
|
+
# GROUP 1 ALL OFF 0x46 70
|
17
|
+
# GROUP 2 ALL ON 0x47 71 (SYNC/PAIR RGB+W Bulb within 2 seconds of Wall Switch Power being turned ON)
|
18
|
+
# GROUP 2 ALL OFF 0x48 72
|
19
|
+
# GROUP 3 ALL ON 0x49 73 (SYNC/PAIR RGB+W Bulb within 2 seconds of Wall Switch Power being turned ON)
|
20
|
+
# GROUP 3 ALL OFF 0x4A 74
|
21
|
+
# GROUP 4 ALL ON 0x4B 75 (SYNC/PAIR RGB+W Bulb within 2 seconds of Wall Switch Power being turned ON)
|
22
|
+
# GROUP 4 ALL OFF 0x4C 76
|
23
|
+
#
|
24
|
+
# DISCO MODE 0x4D 77
|
25
|
+
#
|
26
|
+
# SET COLOR TO WHITE (GROUP ALL) 0x42 100ms followed by: 0xC2
|
27
|
+
# SET COLOR TO WHITE (GROUP 1) 0x45 100ms followed by: 0xC5
|
28
|
+
# SET COLOR TO WHITE (GROUP 2) 0x47 100ms followed by: 0xC7
|
29
|
+
# SET COLOR TO WHITE (GROUP 3) 0x49 100ms followed by: 0xC9
|
30
|
+
# SET COLOR TO WHITE (GROUP 4) 0x4B 100ms followed by: 0xCB
|
31
|
+
|
32
|
+
require 'spec_helper'
|
33
|
+
|
34
|
+
describe LimitlessLed::Server do
|
35
|
+
|
36
|
+
let(:params) { {} }
|
37
|
+
subject { LimitlessLed::Server.new(params) }
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: limitless-led
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Joseph Silvashy
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-
|
11
|
+
date: 2013-12-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -103,7 +103,9 @@ files:
|
|
103
103
|
- lib/limitless_led/server.rb
|
104
104
|
- lib/limitless_led/version.rb
|
105
105
|
- limitless_led.gemspec
|
106
|
-
- spec/
|
106
|
+
- spec/bridge_spec.rb
|
107
|
+
- spec/logger_spec.rb
|
108
|
+
- spec/server_spec.rb
|
107
109
|
- spec/spec_helper.rb
|
108
110
|
homepage: ''
|
109
111
|
licenses:
|
@@ -130,5 +132,7 @@ signing_key:
|
|
130
132
|
specification_version: 4
|
131
133
|
summary: Control the LimitlessLED
|
132
134
|
test_files:
|
133
|
-
- spec/
|
135
|
+
- spec/bridge_spec.rb
|
136
|
+
- spec/logger_spec.rb
|
137
|
+
- spec/server_spec.rb
|
134
138
|
- spec/spec_helper.rb
|
data/spec/limitless_led_spec.rb
DELETED
@@ -1,44 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe LimitlessLed do
|
4
|
-
|
5
|
-
let(:params) { {} }
|
6
|
-
|
7
|
-
subject { LimitlessLed::Bridge.new(params) }
|
8
|
-
|
9
|
-
describe 'can be initialized with default values' do
|
10
|
-
its(:host) { should == 'localhost' }
|
11
|
-
its(:port) { should == 8899 }
|
12
|
-
end
|
13
|
-
|
14
|
-
describe 'can be initialized with a host and port' do
|
15
|
-
let(:params) { { host: '192.168.100.100', port: 6666 } }
|
16
|
-
|
17
|
-
its(:host) { should == '192.168.100.100' }
|
18
|
-
its(:port) { should == 6666 }
|
19
|
-
end
|
20
|
-
|
21
|
-
describe '#color' do
|
22
|
-
it 'changes color' do
|
23
|
-
true.should be_true
|
24
|
-
# subject.should_receive(:send_packet).with("\x40\xFF\x55")
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
describe '#send_packet' do
|
29
|
-
it 'should create a new socket and send the packet' do
|
30
|
-
|
31
|
-
fake_socket = double(:fake_udp_socket)
|
32
|
-
fake_socket.should_receive(:connect).with( subject.host, subject.port )
|
33
|
-
fake_socket.should_receive(:send).with('stuff', 0)
|
34
|
-
|
35
|
-
UDPSocket.should_receive(:new) { fake_socket }
|
36
|
-
|
37
|
-
subject.send(:send_packet, 'stuff')
|
38
|
-
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
end
|
43
|
-
|
44
|
-
|