limitless-led 0.0.4 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ffa1ba16ac8fc123b0f8f433de1f54b3c266ec2f
4
- data.tar.gz: d0ce26cf2bb3e727257a0136127b4ce9ecfaf428
3
+ metadata.gz: 6d1f24493fb0e1bf0d62283ed57df1023164eb0c
4
+ data.tar.gz: 80b13e7fc94f52ce3238d1a1700295daea7de6c5
5
5
  SHA512:
6
- metadata.gz: e3d8809d24f2921be6ee05b0edeae2091f7024796e1622c6150372bfaefd2eb734fba64f2b002047ee32807ad3e776496a921d57e582fc5e1ed7bf3bba282ec4
7
- data.tar.gz: e061ad0d1a1d47d8530066562434227ed0f8230f268021d5e8b8d56d9cef4dd4429a610872dfcb0065ef9d7188ed05afbe1d5f5dbb63b23513f31658843b9a32
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
- TODO: Write usage instructions here
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
- options[:port] = 8899
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('0.0.0.0', options[:port], LimitlessLed::Server)
21
+ EM.open_datagram_socket('localhost', options[:port], LimitlessLed::Server)
25
22
  end
@@ -2,10 +2,22 @@
2
2
 
3
3
  require 'limitless_led'
4
4
 
5
- # You can start the proxy server bin/server
6
- bridge = LimitlessLed::Bridge.new
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
@@ -5,3 +5,7 @@ require "limitless_led/logger"
5
5
  require "limitless_led/bridge"
6
6
  require "limitless_led/server"
7
7
 
8
+ module LimitlessLed
9
+ class CommandNotImplemented < StandardError; end
10
+ class UnknownCommand < StandardError; end
11
+ end
@@ -27,47 +27,18 @@ module LimitlessLed
27
27
  socket.send packet, 0
28
28
  end
29
29
 
30
- # This method dispatches the raw command in bytes to the proper method used
31
- # to run commands for the led the first byte in the command code tells the
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
- # Turn second byte int a value out of 360, this is because HSL color maps
58
- # the hue on a radial scale so the first and last values are the same color
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
- # log the color that the device would be set to
68
- # TODO: this should only happen with the bridge is initialized with the verbose parameter as true
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
@@ -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
- color = color.to_rgb
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
@@ -14,8 +14,22 @@ module LimitlessLed
14
14
  @bridge = LimitlessLed::Bridge.new(host: host, port: port)
15
15
  end
16
16
 
17
- def receive_data(command)
18
- @bridge.run command
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
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/ruby
2
2
 
3
3
  module LimitlessLed
4
- VERSION = "0.0.4"
4
+ VERSION = "0.1.0"
5
5
  end
@@ -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
+
@@ -0,0 +1,5 @@
1
+ require 'spec_helper'
2
+
3
+ describe LimitlessLed::Logger do
4
+
5
+ end
@@ -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
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-30 00:00:00.000000000 Z
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/limitless_led_spec.rb
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/limitless_led_spec.rb
135
+ - spec/bridge_spec.rb
136
+ - spec/logger_spec.rb
137
+ - spec/server_spec.rb
134
138
  - spec/spec_helper.rb
@@ -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
-