ledenet_api 0.1.11 → 1.0.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/Gemfile.lock +4 -2
- data/ledenet_api.gemspec +2 -0
- data/lib/ledenet/api.rb +46 -40
- data/lib/ledenet/device_discovery.rb +3 -2
- data/lib/ledenet/packets/empty_response.rb +6 -0
- data/lib/ledenet/packets/fields/checksum.rb +9 -0
- data/lib/ledenet/packets/set_power_request.rb +29 -0
- data/lib/ledenet/packets/status_request.rb +20 -0
- data/lib/ledenet/packets/status_response.rb +31 -0
- data/lib/ledenet/packets/update_color_request.rb +28 -0
- data/lib/ledenet/version.rb +1 -1
- metadata +22 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ac6a8e5411f0e6bdd37433ddc3d165ba94ca0320
|
4
|
+
data.tar.gz: a642b47d4663a5656a8b7db3f21eb55b8a317e77
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c9d8fd279d1e2b3f6574d2ec800a7e25cce533718bfdc61d5b3083099d6581c62f0981444d1a7f57ca5d296c7175aad64f53ab955b2e1880c4dd6056e96d7d17
|
7
|
+
data.tar.gz: f060415564c23e7adff09a80143703b18e1a023e175724469e8891c51d9cc391dfd2a5427b97b9dee6ff9df42d2233832320ea96c9da3aca5ee827b0bc7f99d1
|
data/Gemfile.lock
CHANGED
@@ -1,11 +1,13 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
ledenet_api (0.1.
|
4
|
+
ledenet_api (0.1.11)
|
5
|
+
bindata (>= 1.8)
|
5
6
|
|
6
7
|
GEM
|
7
8
|
remote: https://rubygems.org/
|
8
9
|
specs:
|
10
|
+
bindata (2.3.0)
|
9
11
|
diff-lcs (1.2.5)
|
10
12
|
rake (10.4.2)
|
11
13
|
rspec (3.3.0)
|
@@ -32,4 +34,4 @@ DEPENDENCIES
|
|
32
34
|
rspec
|
33
35
|
|
34
36
|
BUNDLED WITH
|
35
|
-
1.
|
37
|
+
1.11.2
|
data/ledenet_api.gemspec
CHANGED
@@ -18,6 +18,8 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
19
19
|
spec.require_paths = ["lib"]
|
20
20
|
|
21
|
+
spec.add_dependency 'bindata', '>= 2.3'
|
22
|
+
|
21
23
|
spec.add_development_dependency "bundler", "~> 1.10"
|
22
24
|
spec.add_development_dependency "rake", "~> 10.0"
|
23
25
|
spec.add_development_dependency "rspec"
|
data/lib/ledenet/api.rb
CHANGED
@@ -1,10 +1,13 @@
|
|
1
|
+
require 'ledenet/packets/set_power_request'
|
2
|
+
require 'ledenet/packets/status_request'
|
3
|
+
require 'ledenet/packets/update_color_request'
|
4
|
+
|
1
5
|
module LEDENET
|
2
6
|
class Api
|
3
|
-
API_PORT = 5577
|
4
|
-
|
5
7
|
DEFAULT_OPTIONS = {
|
6
8
|
reuse_connection: false,
|
7
|
-
max_retries: 3
|
9
|
+
max_retries: 3,
|
10
|
+
port: 5577
|
8
11
|
}
|
9
12
|
|
10
13
|
def initialize(device_address, options = {})
|
@@ -13,68 +16,69 @@ module LEDENET
|
|
13
16
|
end
|
14
17
|
|
15
18
|
def on
|
16
|
-
|
17
|
-
|
18
|
-
true
|
19
|
+
send_packet(LEDENET::Packets::SetPowerRequest.on_request)
|
19
20
|
end
|
20
21
|
|
21
22
|
def off
|
22
|
-
|
23
|
-
|
24
|
-
true
|
23
|
+
send_packet(LEDENET::Packets::SetPowerRequest.off_request)
|
25
24
|
end
|
26
25
|
|
27
26
|
def on?
|
28
|
-
|
27
|
+
status.on?
|
29
28
|
end
|
30
29
|
|
31
|
-
def
|
32
|
-
|
30
|
+
def update_rgb(r, g, b)
|
31
|
+
update_color_data(red: r, green: g, blue: b)
|
32
|
+
end
|
33
33
|
|
34
|
-
|
34
|
+
def update_warm_white(warm_white)
|
35
|
+
update_color_data(warm_white: warm_white)
|
36
|
+
end
|
35
37
|
|
36
|
-
|
38
|
+
def update_color_data(o)
|
39
|
+
updated_data = current_color.merge(o)
|
40
|
+
send_packet(LEDENET::Packets::UpdateColorRequest.new(updated_data))
|
37
41
|
end
|
38
42
|
|
39
|
-
def
|
40
|
-
|
43
|
+
def current_rgb
|
44
|
+
current_color_data.values_at(:red, :green, :blue)
|
41
45
|
end
|
42
46
|
|
43
|
-
def
|
44
|
-
|
47
|
+
def current_warm_white
|
48
|
+
current_color_data[:warm_white]
|
45
49
|
end
|
46
50
|
|
47
|
-
|
48
|
-
|
49
|
-
|
51
|
+
def current_color_data
|
52
|
+
status_response = status
|
53
|
+
color_data = %w{red green blue warm_white}.map do |x|
|
54
|
+
[x.to_sym, status_response.send(x)]
|
50
55
|
end
|
56
|
+
Hash[color_data]
|
57
|
+
end
|
51
58
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
# Example response:
|
57
|
-
# [129, 4, 35, 97, 33, 9, 11, 22, 33, 255, 3, 0, 0, 119]
|
58
|
-
# R G B WW ^--- LSB indicates on/off
|
59
|
-
flush_response(14)
|
60
|
-
end
|
61
|
-
end
|
59
|
+
def reconnect!
|
60
|
+
create_socket
|
61
|
+
true
|
62
|
+
end
|
62
63
|
|
63
|
-
|
64
|
-
|
65
|
-
|
64
|
+
def send_packet(packet)
|
65
|
+
socket_action do
|
66
|
+
@socket.write(packet.to_binary_s)
|
66
67
|
|
67
|
-
|
68
|
-
|
68
|
+
if packet.response_reader != LEDENET::Packets::EmptyResponse
|
69
|
+
packet.response_reader.read(@socket)
|
70
|
+
end
|
69
71
|
end
|
72
|
+
end
|
70
73
|
|
71
|
-
|
72
|
-
|
74
|
+
private
|
75
|
+
def status
|
76
|
+
send_packet(LEDENET::Packets::StatusRequest.new)
|
73
77
|
end
|
74
78
|
|
75
79
|
def create_socket
|
76
80
|
@socket.close unless @socket.nil? or @socket.closed?
|
77
|
-
@socket = TCPSocket.new(@device_address,
|
81
|
+
@socket = TCPSocket.new(@device_address, @options[:port])
|
78
82
|
end
|
79
83
|
|
80
84
|
def socket_action
|
@@ -92,7 +96,9 @@ module LEDENET
|
|
92
96
|
raise e
|
93
97
|
end
|
94
98
|
ensure
|
95
|
-
|
99
|
+
if !@socket.nil? && !@socket.closed? && !@options[:reuse_connection]
|
100
|
+
@socket.close
|
101
|
+
end
|
96
102
|
end
|
97
103
|
end
|
98
104
|
end
|
@@ -18,7 +18,8 @@ module LEDENET
|
|
18
18
|
DEFAULT_OPTIONS = {
|
19
19
|
expected_devices: 1,
|
20
20
|
timeout: 5,
|
21
|
-
expected_models: []
|
21
|
+
expected_models: [],
|
22
|
+
udp_port: 48899
|
22
23
|
}
|
23
24
|
|
24
25
|
# The WiFi controllers these things appear to use support a discovery protocol
|
@@ -31,7 +32,7 @@ module LEDENET
|
|
31
32
|
def self.discover_devices(options = {})
|
32
33
|
options = DEFAULT_OPTIONS.merge(options)
|
33
34
|
|
34
|
-
send_addr = ['<broadcast>',
|
35
|
+
send_addr = ['<broadcast>', options[:udp_port]]
|
35
36
|
send_socket = UDPSocket.new
|
36
37
|
send_socket.setsockopt(Socket::SOL_SOCKET, Socket::SO_BROADCAST, true)
|
37
38
|
send_socket.send('HF-A11ASSISTHREAD', 0, send_addr[0], send_addr[1])
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'bindata'
|
2
|
+
|
3
|
+
require 'ledenet/packets/fields/checksum'
|
4
|
+
require 'ledenet/packets/empty_response'
|
5
|
+
|
6
|
+
module LEDENET::Packets
|
7
|
+
class SetPowerRequest < BinData::Record
|
8
|
+
mandatory_parameter :on?
|
9
|
+
hide :checksum
|
10
|
+
|
11
|
+
uint8 :packet_id, value: 0x71
|
12
|
+
uint8 :power_status, value: ->() { on? ? 0x23 : 0x24 }
|
13
|
+
uint8 :remote_or_local, value: 0x0F
|
14
|
+
|
15
|
+
checksum :checksum, packet_data: ->() { snapshot }
|
16
|
+
|
17
|
+
def response_reader
|
18
|
+
LEDENET::Packets::EmptyResponse
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.on_request
|
22
|
+
SetPowerRequest.new(on?: true)
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.off_request
|
26
|
+
SetPowerRequest.new(on?: false)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'bindata'
|
2
|
+
|
3
|
+
require 'ledenet/packets/fields/checksum'
|
4
|
+
require 'ledenet/packets/status_response'
|
5
|
+
|
6
|
+
module LEDENET::Packets
|
7
|
+
class StatusRequest < BinData::Record
|
8
|
+
hide :checksum
|
9
|
+
|
10
|
+
uint8 :packet_id, value: 0x81
|
11
|
+
uint8 :payload1, value: 0x8A
|
12
|
+
uint8 :payload2, value: 0x8B
|
13
|
+
|
14
|
+
checksum :checksum, packet_data: ->() { snapshot }
|
15
|
+
|
16
|
+
def response_reader
|
17
|
+
LEDENET::Packets::StatusResponse
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'bindata'
|
2
|
+
|
3
|
+
require 'ledenet/packets/fields/checksum'
|
4
|
+
|
5
|
+
module LEDENET::Packets
|
6
|
+
class StatusResponse < BinData::Record
|
7
|
+
hide :checksum, :unused_payload
|
8
|
+
|
9
|
+
uint8 :packet_id, value: 0x81
|
10
|
+
uint8 :device_name
|
11
|
+
uint8 :power_status
|
12
|
+
|
13
|
+
# I'm not sure these are the correct field labels. Basing it off of some
|
14
|
+
# documentation that looks like it's for a slightly different protocol.
|
15
|
+
uint8 :mode
|
16
|
+
uint8 :run_status
|
17
|
+
uint8 :speed
|
18
|
+
|
19
|
+
uint8 :red
|
20
|
+
uint8 :green
|
21
|
+
uint8 :blue
|
22
|
+
uint8 :warm_white
|
23
|
+
|
24
|
+
uint16be :unused_payload, value: 0x0000
|
25
|
+
uint8 :checksum
|
26
|
+
|
27
|
+
def on?
|
28
|
+
(power_status & 0x01) == 0x01
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'bindata'
|
2
|
+
|
3
|
+
require 'ledenet/packets/fields/checksum'
|
4
|
+
require 'ledenet/packets/empty_response'
|
5
|
+
|
6
|
+
module LEDENET::Packets
|
7
|
+
class UpdateColorRequest < BinData::Record
|
8
|
+
hide :checksum
|
9
|
+
|
10
|
+
uint8 :packet_id, value: 0x31
|
11
|
+
|
12
|
+
uint8 :red
|
13
|
+
uint8 :green
|
14
|
+
uint8 :blue
|
15
|
+
uint8 :warm_white
|
16
|
+
|
17
|
+
uint8 :unused_payload, value: 0
|
18
|
+
|
19
|
+
# Not clear to me what difference this makes. Remote = 0xF0, Local = 0x0F
|
20
|
+
uint8 :remote_or_local, value: 0x0F
|
21
|
+
|
22
|
+
checksum :checksum, packet_data: ->() { snapshot }
|
23
|
+
|
24
|
+
def response_reader
|
25
|
+
LEDENET::Packets::EmptyResponse
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
data/lib/ledenet/version.rb
CHANGED
metadata
CHANGED
@@ -1,15 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ledenet_api
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Christopher Mullins
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-04-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bindata
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '2.3'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '2.3'
|
13
27
|
- !ruby/object:Gem::Dependency
|
14
28
|
name: bundler
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -68,6 +82,12 @@ files:
|
|
68
82
|
- ledenet_api.gemspec
|
69
83
|
- lib/ledenet/api.rb
|
70
84
|
- lib/ledenet/device_discovery.rb
|
85
|
+
- lib/ledenet/packets/empty_response.rb
|
86
|
+
- lib/ledenet/packets/fields/checksum.rb
|
87
|
+
- lib/ledenet/packets/set_power_request.rb
|
88
|
+
- lib/ledenet/packets/status_request.rb
|
89
|
+
- lib/ledenet/packets/status_response.rb
|
90
|
+
- lib/ledenet/packets/update_color_request.rb
|
71
91
|
- lib/ledenet/version.rb
|
72
92
|
- lib/ledenet_api.rb
|
73
93
|
homepage: http://www.github.com/sidoh/ledenet_api
|