huebot 0.4.0 → 0.5.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 +9 -8
- data/bin/huebot +38 -8
- data/lib/huebot/bridge.rb +24 -0
- data/lib/huebot/cli.rb +33 -1
- data/lib/huebot/client.rb +131 -0
- data/lib/huebot/compiler.rb +5 -3
- data/lib/huebot/config.rb +41 -0
- data/lib/huebot/device_mapper.rb +2 -2
- data/lib/huebot/device_state.rb +7 -0
- data/lib/huebot/group.rb +23 -0
- data/lib/huebot/light.rb +23 -0
- data/lib/huebot/version.rb +1 -1
- data/lib/huebot.rb +6 -2
- metadata +12 -17
- data/lib/hue/LICENSE +0 -22
- data/lib/hue/bridge.rb +0 -140
- data/lib/hue/client.rb +0 -141
- data/lib/hue/editable_state.rb +0 -27
- data/lib/hue/errors.rb +0 -38
- data/lib/hue/group.rb +0 -181
- data/lib/hue/light.rb +0 -177
- data/lib/hue/scene.rb +0 -50
- data/lib/hue/translate_keys.rb +0 -21
- data/lib/hue/version.rb +0 -3
- data/lib/hue.rb +0 -13
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b919267fa7949b2e208ca3b62112c21f05aa1cb9e52a1cb175ab32a96e2b3411
|
4
|
+
data.tar.gz: 8ba14d33785521841fe31daff20786b6ead22592d15e3938b7b518202411b888
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 462cf2419a33689160a4471157b07302ab3fbbc48341903dde3d1c520f4cfc72a21fe6f1dc83262251270c692ad991aa04b666229f30b7218dc70d98f20ec398
|
7
|
+
data.tar.gz: 04c0e7d1fec4c384ceab06e022442ca90f9fefafbe0b15df9d6e3d8fd9db291ab16eca3af13e1db1edf0b8ea902e9d9e89bc36cdaa072e72fa956152db617c63
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Huebot
|
2
2
|
|
3
|
-
|
3
|
+
Program your Hue lights in YAML!
|
4
4
|
|
5
5
|
$ huebot run dimmer.yml --light="Office Desk"
|
6
6
|
|
@@ -34,17 +34,18 @@ The variable `$all` refers to all lights and/or groups passed in on the command
|
|
34
34
|
|
35
35
|
gem install huebot
|
36
36
|
|
37
|
-
|
37
|
+
Having trouble with Hue Bridge auto discovery? Me too. If you know your bridge's IP (and ideally have assigned it a static one), you can set it manually:
|
38
38
|
|
39
|
-
|
39
|
+
huebot set-ip <your bridge's IP>
|
40
40
|
|
41
|
-
|
41
|
+
Configuration is stored in `~/.config/huebot`.
|
42
42
|
|
43
|
-
##
|
43
|
+
## License
|
44
|
+
|
45
|
+
Huebot is licensed under the MIT license (see LICENSE file).
|
44
46
|
|
45
47
|
**TODO**
|
46
48
|
|
47
49
|
* Validate number of inputs against compiled programs
|
48
|
-
*
|
49
|
-
*
|
50
|
-
* Link to official Hue docs
|
50
|
+
* More explanation various features in Wiki
|
51
|
+
* More examples in Wiki
|
data/bin/huebot
CHANGED
@@ -9,15 +9,25 @@ require 'huebot/cli'
|
|
9
9
|
Huebot::CLI.tap { |cli|
|
10
10
|
case cli.get_cmd
|
11
11
|
when :ls
|
12
|
-
|
13
|
-
|
14
|
-
|
12
|
+
bridge, error = Huebot::Bridge.connect
|
13
|
+
if error
|
14
|
+
$stderr.puts error
|
15
|
+
exit 1
|
16
|
+
end
|
17
|
+
|
18
|
+
puts "Lights\n" + bridge.lights.map { |l| " #{l.id}: #{l.name}" }.join("\n") + \
|
19
|
+
"\nGroups\n" + bridge.groups.map { |g| " #{g.id}: #{g.name}" }.join("\n")
|
15
20
|
|
16
21
|
when :run
|
17
22
|
opts, sources = cli.get_input!
|
18
23
|
|
19
|
-
|
20
|
-
|
24
|
+
bridge, error = Huebot::Bridge.connect
|
25
|
+
if error
|
26
|
+
$stderr.puts error
|
27
|
+
exit 1
|
28
|
+
end
|
29
|
+
|
30
|
+
device_mapper = Huebot::DeviceMapper.new(bridge, opts.inputs)
|
21
31
|
compiler = Huebot::Compiler.new(device_mapper)
|
22
32
|
|
23
33
|
programs = sources.map { |src|
|
@@ -26,14 +36,19 @@ Huebot::CLI.tap { |cli|
|
|
26
36
|
found_errors, _found_warnings = cli.check! programs, $stderr
|
27
37
|
exit 1 if found_errors
|
28
38
|
|
29
|
-
bot = Huebot::Bot.new(
|
39
|
+
bot = Huebot::Bot.new(bridge)
|
30
40
|
programs.each { |prog| bot.execute prog }
|
31
41
|
|
32
42
|
when :check
|
33
43
|
opts, sources = cli.get_input!
|
34
44
|
|
35
|
-
|
36
|
-
|
45
|
+
bridge, error = Huebot::Bridge.connect
|
46
|
+
if error
|
47
|
+
$stderr.puts error
|
48
|
+
exit 1
|
49
|
+
end
|
50
|
+
|
51
|
+
device_mapper = Huebot::DeviceMapper.new(bridge, opts.inputs)
|
37
52
|
compiler = Huebot::Compiler.new(device_mapper)
|
38
53
|
|
39
54
|
programs = sources.map { |src|
|
@@ -43,6 +58,21 @@ Huebot::CLI.tap { |cli|
|
|
43
58
|
# TODO validate NUMBER of inputs against each program
|
44
59
|
exit (found_errors || found_warnings) ? 1 : 0
|
45
60
|
|
61
|
+
when :"set-ip"
|
62
|
+
ip = cli.get_args(num: 1).first
|
63
|
+
config = Huebot::Config.new
|
64
|
+
config["ip"] = ip
|
65
|
+
|
66
|
+
when :"clear-ip"
|
67
|
+
cli.get_args(num: 0)
|
68
|
+
config = Huebot::Config.new
|
69
|
+
config["ip"] = nil
|
70
|
+
|
71
|
+
when :unregister
|
72
|
+
cli.get_args(num: 0)
|
73
|
+
config = Huebot::Config.new
|
74
|
+
config.clear
|
75
|
+
|
46
76
|
else cli.help!
|
47
77
|
end
|
48
78
|
}
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Huebot
|
2
|
+
class Bridge
|
3
|
+
def self.connect(config = Huebot::Config.new)
|
4
|
+
client = Client.new(config)
|
5
|
+
error = client.connect
|
6
|
+
return nil, error if error
|
7
|
+
return new(client)
|
8
|
+
end
|
9
|
+
|
10
|
+
attr_reader :client
|
11
|
+
|
12
|
+
def initialize(client)
|
13
|
+
@client = client
|
14
|
+
end
|
15
|
+
|
16
|
+
def lights
|
17
|
+
client.get!("/lights").map { |(id, attrs)| Light.new(client, id, attrs) }
|
18
|
+
end
|
19
|
+
|
20
|
+
def groups
|
21
|
+
client.get!("/groups").map { |(id, attrs)| Group.new(client, id, attrs) }
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
data/lib/huebot/cli.rb
CHANGED
@@ -23,6 +23,31 @@ module Huebot
|
|
23
23
|
ARGV[0].to_s.to_sym
|
24
24
|
end
|
25
25
|
|
26
|
+
def self.get_args(min: nil, max: nil, num: nil)
|
27
|
+
args = ARGV[1..]
|
28
|
+
if num
|
29
|
+
if num != args.size
|
30
|
+
$stderr.puts "Expected #{num} args, found #{args.size}"
|
31
|
+
exit 1
|
32
|
+
end
|
33
|
+
elsif min and max
|
34
|
+
if args.size < min or args.size > max
|
35
|
+
$stderr.puts "Expected #{min}-#{max} args, found #{args.size}"
|
36
|
+
end
|
37
|
+
elsif min
|
38
|
+
if args.size < min
|
39
|
+
$stderr.puts "Expected at least #{num} args, found #{args.size}"
|
40
|
+
exit 1
|
41
|
+
end
|
42
|
+
elsif max
|
43
|
+
if args.size > max
|
44
|
+
$stderr.puts "Expected no more than #{num} args, found #{args.size}"
|
45
|
+
exit 1
|
46
|
+
end
|
47
|
+
end
|
48
|
+
args
|
49
|
+
end
|
50
|
+
|
26
51
|
#
|
27
52
|
# Parses and returns input from the CLI. Serious errors might result in the program exiting.
|
28
53
|
#
|
@@ -37,7 +62,7 @@ module Huebot
|
|
37
62
|
if files.empty? and !options.read_stdin
|
38
63
|
puts parser.help
|
39
64
|
exit 1
|
40
|
-
elsif (bad_paths = files.select { |p| !File.
|
65
|
+
elsif (bad_paths = files.select { |p| !File.exist? p }).any?
|
41
66
|
$stderr.puts "Cannot find #{bad_paths.join ', '}"
|
42
67
|
exit 1
|
43
68
|
else
|
@@ -107,6 +132,13 @@ Run program(s):
|
|
107
132
|
Validate programs and inputs:
|
108
133
|
huebot check file1.yml [file2.yml [file3.yml ...]] [options]
|
109
134
|
|
135
|
+
Manually set/clear the IP for your Hue Bridge (useful when on a VPN):
|
136
|
+
huebot set-ip 192.168.1.20
|
137
|
+
huebot clear-ip
|
138
|
+
|
139
|
+
Clear all connection config:
|
140
|
+
huebot unregister
|
141
|
+
|
110
142
|
Options:
|
111
143
|
).strip
|
112
144
|
opts.on("-lLIGHT", "--light=LIGHT", "Light ID or name") { |l| options.inputs << LightInput.new(l) }
|
@@ -0,0 +1,131 @@
|
|
1
|
+
require 'uri'
|
2
|
+
require 'net/http'
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
module Huebot
|
6
|
+
class Client
|
7
|
+
DISCOVERY_URI = URI(ENV["HUE_DISCOVERY_API"] || "https://discovery.meethue.com/")
|
8
|
+
Bridge = Struct.new(:id, :ip)
|
9
|
+
|
10
|
+
attr_reader :config
|
11
|
+
|
12
|
+
def initialize(config = Huebot::Config.new)
|
13
|
+
@config = config
|
14
|
+
@ip = config["ip"] # NOTE will usually be null
|
15
|
+
@username = nil
|
16
|
+
end
|
17
|
+
|
18
|
+
def connect
|
19
|
+
if config["ip"]
|
20
|
+
@ip = config["ip"]
|
21
|
+
elsif config["id"]
|
22
|
+
@ip = bridges.detect { |b| b.id == id }&.ip
|
23
|
+
return "Unable to find Hue Bridge '#{config["id"]}' on your network" if @ip.nil?
|
24
|
+
else
|
25
|
+
bridge = bridges.first
|
26
|
+
return "Unable to find a Hue Bridge on your network" if bridge.nil?
|
27
|
+
config["id"] = bridge.id
|
28
|
+
@ip = bridge.ip
|
29
|
+
end
|
30
|
+
|
31
|
+
if config["username"]
|
32
|
+
if valid_username? config["username"]
|
33
|
+
@username = config["username"]
|
34
|
+
else
|
35
|
+
return "Invalid Hue Bridge username '#{config["username"]}'"
|
36
|
+
end
|
37
|
+
else
|
38
|
+
username, error = register
|
39
|
+
return error if error
|
40
|
+
config["username"] = @username = username
|
41
|
+
end
|
42
|
+
nil
|
43
|
+
end
|
44
|
+
|
45
|
+
def get!(path)
|
46
|
+
resp, error = get path
|
47
|
+
raise error if error
|
48
|
+
resp
|
49
|
+
end
|
50
|
+
|
51
|
+
def get(path)
|
52
|
+
url = "http://#{@ip}/api"
|
53
|
+
url << "/#{@username}" if @username
|
54
|
+
url << path
|
55
|
+
req = Net::HTTP::Get.new(URI(url))
|
56
|
+
req_json req
|
57
|
+
end
|
58
|
+
|
59
|
+
def post!(path, body)
|
60
|
+
resp, error = post path, body
|
61
|
+
raise error if error
|
62
|
+
resp
|
63
|
+
end
|
64
|
+
|
65
|
+
def post(path, body)
|
66
|
+
url = "http://#{@ip}/api"
|
67
|
+
url << "/#{@username}" if @username
|
68
|
+
url << path
|
69
|
+
req = Net::HTTP::Post.new(URI(url))
|
70
|
+
req["Content-Type"] = "application/json"
|
71
|
+
req.body = body.to_json
|
72
|
+
req_json req
|
73
|
+
end
|
74
|
+
|
75
|
+
def put!(path, body)
|
76
|
+
resp, error = put path, body
|
77
|
+
raise error if error
|
78
|
+
resp
|
79
|
+
end
|
80
|
+
|
81
|
+
def put(path, body)
|
82
|
+
url = "http://#{@ip}/api"
|
83
|
+
url << "/#{@username}" if @username
|
84
|
+
url << path
|
85
|
+
req = Net::HTTP::Put.new(URI(url))
|
86
|
+
req["Content-Type"] = "application/json"
|
87
|
+
req.body = body.to_json
|
88
|
+
req_json req
|
89
|
+
end
|
90
|
+
|
91
|
+
def req_json(req)
|
92
|
+
resp = Net::HTTP.start req.uri.host, req.uri.port, {use_ssl: false} do |http|
|
93
|
+
http.request req
|
94
|
+
end
|
95
|
+
case resp.code.to_i
|
96
|
+
when 200..201
|
97
|
+
data = JSON.parse(resp.body)
|
98
|
+
if data[0] and (error = data[0]["error"])
|
99
|
+
return nil, error.fetch("description")
|
100
|
+
else
|
101
|
+
return data, nil
|
102
|
+
end
|
103
|
+
else
|
104
|
+
raise "Unexpected response from Bridge (#{resp.code}): #{resp.body}"
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
def bridges
|
109
|
+
req = Net::HTTP::Get.new(DISCOVERY_URI)
|
110
|
+
resp = Net::HTTP.start req.uri.host, req.uri.port, {use_ssl: true} do |http|
|
111
|
+
http.request req
|
112
|
+
end
|
113
|
+
JSON.parse(resp.body).map { |x|
|
114
|
+
Bridge.new(x.fetch("id"), x.fetch("internalipaddress"))
|
115
|
+
}
|
116
|
+
end
|
117
|
+
|
118
|
+
private
|
119
|
+
|
120
|
+
def valid_username?(username)
|
121
|
+
_resp, error = get("/#{username}")
|
122
|
+
!error
|
123
|
+
end
|
124
|
+
|
125
|
+
def register
|
126
|
+
resp, error = post "/", {"devicetype": "huebot"}
|
127
|
+
return nil, error if error
|
128
|
+
resp[0].fetch("success").fetch("username")
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
data/lib/huebot/compiler.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
module Huebot
|
2
2
|
class Compiler
|
3
|
+
DEVICE_FIELDS = %i(light lights group groups device devices).freeze
|
4
|
+
|
3
5
|
def initialize(device_mapper)
|
4
6
|
@device_mapper = device_mapper
|
5
7
|
end
|
@@ -130,9 +132,9 @@ module Huebot
|
|
130
132
|
end
|
131
133
|
state[:transitiontime] = t.delete("time") || t.delete(:time) || t.delete("transitiontime") || t.delete(:transitiontime) || 4
|
132
134
|
|
133
|
-
transition.state = t.merge(state).
|
134
|
-
|
135
|
-
|
135
|
+
transition.state = t.merge(state).each_with_object({}) { |(key, val), obj|
|
136
|
+
key = key.to_sym
|
137
|
+
obj[key] = val unless DEVICE_FIELDS.include? key
|
136
138
|
}
|
137
139
|
return errors, warnings, transition
|
138
140
|
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
require 'yaml'
|
3
|
+
|
4
|
+
module Huebot
|
5
|
+
class Config
|
6
|
+
def initialize(path = "~/.config/huebot")
|
7
|
+
@path = File.expand_path(path)
|
8
|
+
@dir = File.dirname(@path)
|
9
|
+
@dir_exists = File.exist? @dir
|
10
|
+
@config = File.exist?(@path) ? YAML.load_file(@path) : {}
|
11
|
+
end
|
12
|
+
|
13
|
+
def [](attr)
|
14
|
+
@config[attr.to_s]
|
15
|
+
end
|
16
|
+
|
17
|
+
def []=(attr, val)
|
18
|
+
if val.nil?
|
19
|
+
@config.delete(attr.to_s)
|
20
|
+
else
|
21
|
+
@config[attr.to_s] = val
|
22
|
+
end
|
23
|
+
write
|
24
|
+
end
|
25
|
+
|
26
|
+
def clear
|
27
|
+
@config.clear
|
28
|
+
write
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def write
|
34
|
+
unless @dir_exists
|
35
|
+
FileUtils.mkdir_p @dir
|
36
|
+
@dir_exists = true
|
37
|
+
end
|
38
|
+
File.write(@path, YAML.dump(@config))
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
data/lib/huebot/device_mapper.rb
CHANGED
@@ -2,8 +2,8 @@ module Huebot
|
|
2
2
|
class DeviceMapper
|
3
3
|
Unmapped = Class.new(StandardError)
|
4
4
|
|
5
|
-
def initialize(
|
6
|
-
all_lights, all_groups =
|
5
|
+
def initialize(bridge, inputs = [])
|
6
|
+
all_lights, all_groups = bridge.lights, bridge.groups
|
7
7
|
|
8
8
|
@lights_by_id = all_lights.reduce({}) { |a, l| a[l.id] = l; a }
|
9
9
|
@lights_by_name = all_lights.reduce({}) { |a, l| a[l.name] = l; a }
|
data/lib/huebot/group.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
module Huebot
|
2
|
+
class Group
|
3
|
+
include DeviceState
|
4
|
+
attr_reader :client, :id, :name
|
5
|
+
|
6
|
+
def initialize(client, id, attrs)
|
7
|
+
@client = client
|
8
|
+
@id = id
|
9
|
+
@name = attrs.fetch("name")
|
10
|
+
@attrs = attrs
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def state_url
|
16
|
+
url "/action"
|
17
|
+
end
|
18
|
+
|
19
|
+
def url(path)
|
20
|
+
"/groups/#{id}#{path}"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/lib/huebot/light.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
module Huebot
|
2
|
+
class Light
|
3
|
+
include DeviceState
|
4
|
+
attr_reader :client, :id, :name
|
5
|
+
|
6
|
+
def initialize(client, id, attrs)
|
7
|
+
@client = client
|
8
|
+
@id = id
|
9
|
+
@name = attrs.fetch("name")
|
10
|
+
@attrs = attrs
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def state_url
|
16
|
+
url "/state"
|
17
|
+
end
|
18
|
+
|
19
|
+
def url(path)
|
20
|
+
"/lights/#{id}#{path}"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/lib/huebot/version.rb
CHANGED
data/lib/huebot.rb
CHANGED
@@ -1,6 +1,10 @@
|
|
1
|
-
require 'hue'
|
2
|
-
|
3
1
|
module Huebot
|
2
|
+
autoload :Config, 'huebot/config'
|
3
|
+
autoload :Client, 'huebot/client'
|
4
|
+
autoload :Bridge, 'huebot/bridge'
|
5
|
+
autoload :DeviceState, 'huebot/device_state'
|
6
|
+
autoload :Light, 'huebot/light'
|
7
|
+
autoload :Group, 'huebot/group'
|
4
8
|
autoload :DeviceMapper, 'huebot/device_mapper'
|
5
9
|
autoload :Program, 'huebot/program'
|
6
10
|
autoload :Compiler, 'huebot/compiler'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: huebot
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jordan Hollinger
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-12-08 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Declare and run YAML programs for Philips Hue devices
|
14
14
|
email: jordan.hollinger@gmail.com
|
@@ -19,29 +19,24 @@ extra_rdoc_files: []
|
|
19
19
|
files:
|
20
20
|
- README.md
|
21
21
|
- bin/huebot
|
22
|
-
- lib/hue.rb
|
23
|
-
- lib/hue/LICENSE
|
24
|
-
- lib/hue/bridge.rb
|
25
|
-
- lib/hue/client.rb
|
26
|
-
- lib/hue/editable_state.rb
|
27
|
-
- lib/hue/errors.rb
|
28
|
-
- lib/hue/group.rb
|
29
|
-
- lib/hue/light.rb
|
30
|
-
- lib/hue/scene.rb
|
31
|
-
- lib/hue/translate_keys.rb
|
32
|
-
- lib/hue/version.rb
|
33
22
|
- lib/huebot.rb
|
34
23
|
- lib/huebot/bot.rb
|
24
|
+
- lib/huebot/bridge.rb
|
35
25
|
- lib/huebot/cli.rb
|
26
|
+
- lib/huebot/client.rb
|
36
27
|
- lib/huebot/compiler.rb
|
28
|
+
- lib/huebot/config.rb
|
37
29
|
- lib/huebot/device_mapper.rb
|
30
|
+
- lib/huebot/device_state.rb
|
31
|
+
- lib/huebot/group.rb
|
32
|
+
- lib/huebot/light.rb
|
38
33
|
- lib/huebot/program.rb
|
39
34
|
- lib/huebot/version.rb
|
40
35
|
homepage: https://github.com/jhollinger/huebot
|
41
36
|
licenses:
|
42
37
|
- MIT
|
43
38
|
metadata: {}
|
44
|
-
post_install_message:
|
39
|
+
post_install_message:
|
45
40
|
rdoc_options: []
|
46
41
|
require_paths:
|
47
42
|
- lib
|
@@ -56,8 +51,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
56
51
|
- !ruby/object:Gem::Version
|
57
52
|
version: '0'
|
58
53
|
requirements: []
|
59
|
-
rubygems_version: 3.
|
60
|
-
signing_key:
|
54
|
+
rubygems_version: 3.4.1
|
55
|
+
signing_key:
|
61
56
|
specification_version: 4
|
62
57
|
summary: Orchestration for Hue devices
|
63
58
|
test_files: []
|
data/lib/hue/LICENSE
DELETED
@@ -1,22 +0,0 @@
|
|
1
|
-
Copyright (c) 2013-2014 Sam Soffes, http://soff.es
|
2
|
-
|
3
|
-
MIT License
|
4
|
-
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
-
a copy of this software and associated documentation files (the
|
7
|
-
"Software"), to deal in the Software without restriction, including
|
8
|
-
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
-
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
-
permit persons to whom the Software is furnished to do so, subject to
|
11
|
-
the following conditions:
|
12
|
-
|
13
|
-
The above copyright notice and this permission notice shall be
|
14
|
-
included in all copies or substantial portions of the Software.
|
15
|
-
|
16
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
-
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
-
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
-
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
-
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
-
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
-
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|