ledenet_api 1.2.2 → 1.4.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 +33 -1
- data/bin/ledenet-ufo +15 -15
- data/lib/ledenet/api.rb +55 -12
- data/lib/ledenet/function_speed.rb +36 -0
- data/lib/ledenet/functions.rb +6 -1
- data/lib/ledenet/packets/set_function_request.rb +2 -21
- data/lib/ledenet/packets/status_response.rb +1 -1
- data/lib/ledenet/version.rb +1 -1
- data/lib/ledenet_api.rb +1 -0
- metadata +2 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f8da932bc83469d8b334561d08eabd1030db8849
|
4
|
+
data.tar.gz: 2f241cab885aa1cfc4ef122724a918d919f1b9d6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6eed4e0f31aa24481f0991d2d868ca297cb6441626f80dbb8091b3e6f1a0e13a31a78bd2607c7fe0abbd7dab2c0f10f8c248388e059665464f4d820999dafbc3
|
7
|
+
data.tar.gz: 098e2b9799d91d21d3f07c829493937f4da485979072613afa373ff902a41f09372c4f5cf5ce997f2960779a42f55c4b52e8d3f2c9fe9eeeb6aa7d62a3b3615d
|
data/README.md
CHANGED
@@ -39,9 +39,11 @@ $ ledenet-ufo
|
|
39
39
|
-w, --warm-white [VALUE] Set warm white to VALUE
|
40
40
|
--on Turn on the controller
|
41
41
|
--off Turn off the controller
|
42
|
-
-l, --list Prints a list of available devices and
|
42
|
+
-l, --list Prints a list of available devices and exits
|
43
43
|
-s, --status Prints status as JSON
|
44
44
|
-h, --help Prints this help message
|
45
|
+
--function-id [VALUE] Set function id to VALUE
|
46
|
+
-f, --function [VALUE] Set function to VALUE.
|
45
47
|
```
|
46
48
|
|
47
49
|
When using it, you can specify the IP address, hardware (mac) address, or let `ledenet_api` choose an arbitrary device on the local network (this would work well if you only have one).
|
@@ -76,6 +78,12 @@ $ ledenet-ufo --on -r 200 -g 0 -b 255 --warm-white 0 --status
|
|
76
78
|
$ ledenet-ufo --off
|
77
79
|
```
|
78
80
|
|
81
|
+
#### Set function
|
82
|
+
|
83
|
+
```
|
84
|
+
$ ledenet-ufo --function seven_color_cross_fade --speed 10
|
85
|
+
```
|
86
|
+
|
79
87
|
### Ruby API
|
80
88
|
|
81
89
|
#### Device discovery
|
@@ -161,3 +169,27 @@ api.update_color_data(red: 100)
|
|
161
169
|
|
162
170
|
api.update_color_data(blue: 255, warm_white: 0)
|
163
171
|
```
|
172
|
+
|
173
|
+
#### Functions
|
174
|
+
|
175
|
+
The UFO devices ship with 20 pre-programmed lighting functions. ledenet_api has support for these:
|
176
|
+
|
177
|
+
```ruby
|
178
|
+
LEDENET::Functions.all_functions
|
179
|
+
#=> [:SEVEN_COLOR_CROSS_FADE, :RED_GRADUAL_CHANGE, :GREEN_GRADUAL_CHANGE, :BLUE_GRADUAL_CHANGE, :YELLOW_GRADUAL_CHANGE, :CYAN_GRADUAL_CHANGE, :PURPLE_GRADUAL_CHANGE, :WHITE_GRADUAL_CHANGE, :RED_GREEN_CROSS_FADE, :RED_BLUE_CROSS_FADE, :SEVEN_COLOR_STROBE_FLASH, :RED_STROBE_FLASH, :GREEN_STROBE_FLASH, :BLUE_STROBE_FLASH, :YELLOW_STROBE_FLASH, :CYAN_STROBE_FLASH, :PURPLE_STROBE_FLASH, :WHITE_STROBE_FLASH, :SEVEN_COLOR_JUMPING_CHANGE, :GREEN_BLUE_CROSS_FADE]
|
180
|
+
```
|
181
|
+
|
182
|
+
```ruby
|
183
|
+
fn = LEDENET::Functions::SEVEN_COLOR_CROSS_FADE
|
184
|
+
speed = 0 # very slow
|
185
|
+
|
186
|
+
api.update_function(fn, speed)
|
187
|
+
|
188
|
+
api.update_function(:blue_green_cross_fade, 100) # Very fast
|
189
|
+
```
|
190
|
+
|
191
|
+
To quit the function and return to a constant color, simply update a color value:
|
192
|
+
|
193
|
+
```ruby
|
194
|
+
api.update_color_data(warm_white: 255)
|
195
|
+
```
|
data/bin/ledenet-ufo
CHANGED
@@ -99,12 +99,6 @@ if options[:list] && options.count > 1
|
|
99
99
|
exit 1
|
100
100
|
end
|
101
101
|
|
102
|
-
if options[:function].nil? != options[:speed].nil?
|
103
|
-
warn "--funciton and --speed must be specified together. You provide " <<
|
104
|
-
"one without also providing the other."
|
105
|
-
exit 1
|
106
|
-
end
|
107
|
-
|
108
102
|
begin
|
109
103
|
if options[:list]
|
110
104
|
devices = LEDENET.discover_devices(expected_devices: 1000)
|
@@ -136,22 +130,28 @@ begin
|
|
136
130
|
|
137
131
|
api = LEDENET::Api.new(ip)
|
138
132
|
|
139
|
-
api.set_power(options[:on?]) unless options[:on?].nil?
|
140
|
-
|
141
133
|
color_params = options.select do |k,_|
|
142
134
|
%w{red green blue warm_white}.include?(k.to_s)
|
143
135
|
end
|
144
|
-
api.update_color_data(color_params) unless color_params.empty?
|
145
136
|
|
146
|
-
if options[:
|
147
|
-
api.
|
137
|
+
if !options[:on?].nil?
|
138
|
+
api.set_power(options[:on?])
|
148
139
|
end
|
149
140
|
|
150
|
-
if
|
151
|
-
|
152
|
-
|
141
|
+
if color_params.any?
|
142
|
+
api.update_color_data(color_params)
|
143
|
+
end
|
153
144
|
|
154
|
-
|
145
|
+
if options[:function]
|
146
|
+
api.update_function(options[:function])
|
147
|
+
end
|
148
|
+
|
149
|
+
if options[:speed]
|
150
|
+
api.update_function_speed(options[:speed])
|
151
|
+
end
|
152
|
+
|
153
|
+
if options[:print_status?]
|
154
|
+
puts api.status.to_json
|
155
155
|
end
|
156
156
|
end
|
157
157
|
rescue Exception => e
|
data/lib/ledenet/api.rb
CHANGED
@@ -16,6 +16,13 @@ module LEDENET
|
|
16
16
|
@options = DEFAULT_OPTIONS.merge(options)
|
17
17
|
end
|
18
18
|
|
19
|
+
def status
|
20
|
+
response = request_status
|
21
|
+
status = { is_on: on?(response) }
|
22
|
+
status.merge!(current_color_data(response))
|
23
|
+
status.merge!(current_function_data(response))
|
24
|
+
end
|
25
|
+
|
19
26
|
def on
|
20
27
|
send_packet(LEDENET::Packets::SetPowerRequest.on_request)
|
21
28
|
end
|
@@ -28,8 +35,8 @@ module LEDENET
|
|
28
35
|
v ? on : off
|
29
36
|
end
|
30
37
|
|
31
|
-
def on?
|
32
|
-
|
38
|
+
def on?(response = request_status)
|
39
|
+
response.on?
|
33
40
|
end
|
34
41
|
|
35
42
|
def update_rgb(r, g, b)
|
@@ -53,20 +60,47 @@ module LEDENET
|
|
53
60
|
current_color_data[:warm_white]
|
54
61
|
end
|
55
62
|
|
56
|
-
def current_color_data
|
57
|
-
|
58
|
-
color_data = %w{red green blue warm_white}.map do |x|
|
59
|
-
[x.to_sym, status_response.send(x)]
|
60
|
-
end
|
61
|
-
Hash[color_data]
|
63
|
+
def current_color_data(response = request_status)
|
64
|
+
select_status_keys(response, *%w{red green blue warm_white})
|
62
65
|
end
|
63
66
|
|
64
|
-
def update_function(fn
|
67
|
+
def update_function(fn)
|
65
68
|
if fn.is_a?(String) or fn.is_a?(Symbol)
|
66
69
|
fn = LEDENET::Functions.const_get(fn.upcase)
|
67
70
|
end
|
71
|
+
update_function_data(function_id: fn)
|
72
|
+
end
|
68
73
|
|
69
|
-
|
74
|
+
def update_function_speed(s)
|
75
|
+
update_function_data(speed: s)
|
76
|
+
end
|
77
|
+
|
78
|
+
def update_function_data(o)
|
79
|
+
o = {}.merge(o)
|
80
|
+
current_data = current_function_data
|
81
|
+
updated_data = {
|
82
|
+
function_id: current_data[:function_id],
|
83
|
+
speed: current_data[:speed_packet_value]
|
84
|
+
}
|
85
|
+
|
86
|
+
if o[:speed]
|
87
|
+
speed = LEDENET::FunctionSpeed.from_value(o.delete(:speed))
|
88
|
+
updated_data[:speed] = speed.packet_value
|
89
|
+
end
|
90
|
+
updated_data.merge!(o)
|
91
|
+
|
92
|
+
send_packet(LEDENET::Packets::SetFunctionRequest.new(updated_data))
|
93
|
+
end
|
94
|
+
|
95
|
+
def current_function_data(response = request_status)
|
96
|
+
raw_function_data = select_status_keys(response, *%w{mode speed})
|
97
|
+
function_data = {
|
98
|
+
running_function?: raw_function_data[:mode] != LEDENET::Functions::NO_FUNCTION,
|
99
|
+
speed: FunctionSpeed.from_packet_value(raw_function_data[:speed]).value,
|
100
|
+
speed_packet_value: raw_function_data[:speed],
|
101
|
+
function_name: LEDENET::Functions.value_of(raw_function_data[:mode]),
|
102
|
+
function_id: raw_function_data[:mode]
|
103
|
+
}
|
70
104
|
end
|
71
105
|
|
72
106
|
def reconnect!
|
@@ -85,8 +119,17 @@ module LEDENET
|
|
85
119
|
end
|
86
120
|
|
87
121
|
private
|
88
|
-
def
|
89
|
-
|
122
|
+
def select_status_keys(status_response, *keys)
|
123
|
+
color_data = keys.map do |x|
|
124
|
+
[x.to_sym, status_response.send(x)]
|
125
|
+
end
|
126
|
+
Hash[color_data]
|
127
|
+
end
|
128
|
+
|
129
|
+
def request_status
|
130
|
+
s = send_packet(LEDENET::Packets::StatusRequest.new)
|
131
|
+
puts s.inspect
|
132
|
+
s
|
90
133
|
end
|
91
134
|
|
92
135
|
def create_socket
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module LEDENET
|
2
|
+
class FunctionSpeed
|
3
|
+
# Speed range exposed through API
|
4
|
+
INTERFACE_SPEED_RANGE = (1..100)
|
5
|
+
|
6
|
+
# Speed value is in [0x01, 0x1F], with 0x00 being the fastest.
|
7
|
+
PACKET_SPEED_RANGE = (0x01..0x1F)
|
8
|
+
|
9
|
+
attr_reader :value
|
10
|
+
|
11
|
+
def initialize(value)
|
12
|
+
@value = value
|
13
|
+
end
|
14
|
+
|
15
|
+
def packet_value
|
16
|
+
FunctionSpeed.convert_range(value, INTERFACE_SPEED_RANGE, PACKET_SPEED_RANGE)
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.from_value(value)
|
20
|
+
FunctionSpeed.new(value)
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.from_packet_value(value)
|
24
|
+
v = FunctionSpeed.convert_range(value, PACKET_SPEED_RANGE, INTERFACE_SPEED_RANGE)
|
25
|
+
FunctionSpeed.new(v)
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
def self.convert_range(value, from, to)
|
30
|
+
scaled_speed = (value / (from.max.to_f / to.max)).round
|
31
|
+
scaled_speed = [to.min, scaled_speed].max
|
32
|
+
scaled_speed = [to.max, scaled_speed].min
|
33
|
+
to.max - scaled_speed
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
data/lib/ledenet/functions.rb
CHANGED
@@ -20,11 +20,16 @@ module LEDENET
|
|
20
20
|
CYAN_STROBE_FLASH = 0x35,
|
21
21
|
PURPLE_STROBE_FLASH = 0x36,
|
22
22
|
WHITE_STROBE_FLASH = 0x37,
|
23
|
-
SEVEN_COLOR_JUMPING_CHANGE = 0x38
|
23
|
+
SEVEN_COLOR_JUMPING_CHANGE = 0x38,
|
24
|
+
NO_FUNCTION = 0x61
|
24
25
|
]
|
25
26
|
|
26
27
|
def self.all_functions
|
27
28
|
LEDENET::Functions.constants.reject { |x| x == :VALUES }
|
28
29
|
end
|
30
|
+
|
31
|
+
def self.value_of(i)
|
32
|
+
all_functions.select { |x| self.const_get(x) == i }.first
|
33
|
+
end
|
29
34
|
end
|
30
35
|
end
|
@@ -5,30 +5,11 @@ require 'ledenet/packets/empty_response'
|
|
5
5
|
|
6
6
|
module LEDENET::Packets
|
7
7
|
class SetFunctionRequest < BinData::Record
|
8
|
-
VALID_SPEED_RANGE = (0..100)
|
9
|
-
|
10
|
-
# Speed value is in [0x00, 0x20], with 0x00 being the fastest.
|
11
|
-
PACKET_SPEED_RANGE = (0x00..0x20)
|
12
|
-
|
13
8
|
hide :checksum
|
14
|
-
mandatory_parameter :function_id
|
15
|
-
mandatory_parameter :speed
|
16
9
|
|
17
10
|
uint8 :packet_id, value: 0x61
|
18
|
-
uint8 :
|
19
|
-
|
20
|
-
uint8 :speed_val, value: ->() do
|
21
|
-
if !VALID_SPEED_RANGE.include?(speed)
|
22
|
-
raise "Speed should be between #{VALID_SPEED_RANGE.min} and #{VALID_SPEED_RANGE.max}"
|
23
|
-
end
|
24
|
-
|
25
|
-
scaled_speed = (speed / (VALID_SPEED_RANGE.max / PACKET_SPEED_RANGE.max)).round
|
26
|
-
scaled_speed = [PACKET_SPEED_RANGE.min, scaled_speed].max
|
27
|
-
scaled_speed = [PACKET_SPEED_RANGE.max, scaled_speed].min
|
28
|
-
|
29
|
-
PACKET_SPEED_RANGE.max - scaled_speed
|
30
|
-
end
|
31
|
-
|
11
|
+
uint8 :function_id
|
12
|
+
uint8 :speed
|
32
13
|
uint8 :remote_or_local, value: 0x0F
|
33
14
|
checksum :checksum, packet_data: ->() { snapshot }
|
34
15
|
|
data/lib/ledenet/version.rb
CHANGED
data/lib/ledenet_api.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ledenet_api
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Christopher Mullins
|
@@ -98,6 +98,7 @@ files:
|
|
98
98
|
- ledenet_api.gemspec
|
99
99
|
- lib/ledenet/api.rb
|
100
100
|
- lib/ledenet/device_discovery.rb
|
101
|
+
- lib/ledenet/function_speed.rb
|
101
102
|
- lib/ledenet/functions.rb
|
102
103
|
- lib/ledenet/packets/empty_response.rb
|
103
104
|
- lib/ledenet/packets/fields/checksum.rb
|