huebot 0.4.0 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +101 -31
- data/bin/huebot +60 -27
- data/lib/huebot/bot.rb +82 -39
- data/lib/huebot/bridge.rb +24 -0
- data/lib/huebot/cli/helpers.rb +170 -0
- data/lib/huebot/cli/runner.rb +78 -0
- data/lib/huebot/cli.rb +2 -107
- data/lib/huebot/client.rb +132 -0
- data/lib/huebot/compiler/api_v1.rb +285 -0
- data/lib/huebot/compiler.rb +12 -148
- data/lib/huebot/config.rb +41 -0
- data/lib/huebot/device_mapper.rb +40 -26
- data/lib/huebot/device_state.rb +11 -0
- data/lib/huebot/group.rb +30 -0
- data/lib/huebot/light.rb +30 -0
- data/lib/huebot/program.rb +71 -21
- data/lib/huebot/version.rb +1 -1
- data/lib/huebot.rb +9 -24
- metadata +44 -18
- 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
@@ -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
@@ -1,51 +1,65 @@
|
|
1
1
|
module Huebot
|
2
2
|
class DeviceMapper
|
3
|
-
Unmapped = Class.new(
|
3
|
+
Unmapped = Class.new(Error)
|
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 }
|
10
10
|
@groups_by_id = all_groups.reduce({}) { |a, g| a[g.id] = g; a }
|
11
11
|
@groups_by_name = all_groups.reduce({}) { |a, g| a[g.name] = g; a }
|
12
|
-
@devices_by_var = inputs.each_with_index.
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
a
|
12
|
+
@devices_by_var = inputs.each_with_index.each_with_object({}) { |(x, idx), obj|
|
13
|
+
obj[idx + 1] =
|
14
|
+
case x
|
15
|
+
when Light::Input then @lights_by_id[x.val.to_i] || @lights_by_name[x.val]
|
16
|
+
when Group::Input then @groups_by_id[x.val.to_i] || @groups_by_name[x.val]
|
17
|
+
else raise Error, "Invalid input: #{x}"
|
18
|
+
end || raise(Unmapped, "Could not find #{x.class.name[8..-6].downcase} with id or name '#{x.val}'")
|
20
19
|
}
|
21
20
|
@all = @devices_by_var.values
|
22
21
|
end
|
23
22
|
|
23
|
+
def each
|
24
|
+
if block_given?
|
25
|
+
@all.each { |device| yield device }
|
26
|
+
else
|
27
|
+
@all.each
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
24
31
|
def light!(id)
|
25
|
-
|
26
|
-
when Integer
|
27
|
-
@lights_by_id[id]
|
28
|
-
when String
|
29
|
-
@lights_by_name[id]
|
30
|
-
end || (raise Unmapped, "Unmapped light '#{id}'")
|
32
|
+
@lights_by_id[id] || @lights_by_name[id] || (raise Unmapped, "Unmapped light '#{id}'")
|
31
33
|
end
|
32
34
|
|
33
35
|
def group!(id)
|
34
|
-
|
35
|
-
when Integer
|
36
|
-
@groups_by_id[id]
|
37
|
-
when String
|
38
|
-
@groups_by_name[id]
|
39
|
-
end || (raise Unmapped, "Unmapped group '#{id}'")
|
36
|
+
@groups_by_id[id] || @groups_by_name[id] || (raise Unmapped, "Unmapped group '#{id}'")
|
40
37
|
end
|
41
38
|
|
42
39
|
def var!(id)
|
43
40
|
case id
|
44
|
-
when
|
41
|
+
when :all
|
45
42
|
@all
|
46
43
|
else
|
47
|
-
@devices_by_var[id]
|
48
|
-
end
|
44
|
+
@devices_by_var[id] || (raise Unmapped, "Unmapped device '#{id}'")
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def missing_lights(names)
|
49
|
+
names - @lights_by_name.keys
|
50
|
+
end
|
51
|
+
|
52
|
+
def missing_groups(names)
|
53
|
+
names - @groups_by_name.keys
|
54
|
+
end
|
55
|
+
|
56
|
+
def missing_vars(vars)
|
57
|
+
missing = vars - @devices_by_var.keys
|
58
|
+
if @all.any?
|
59
|
+
missing - [:all]
|
60
|
+
else
|
61
|
+
missing
|
62
|
+
end
|
49
63
|
end
|
50
64
|
end
|
51
65
|
end
|
data/lib/huebot/group.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
module Huebot
|
2
|
+
class Group
|
3
|
+
#
|
4
|
+
# Struct for specifying a Group input (id or name)
|
5
|
+
#
|
6
|
+
# @attr val [Integer|String] id or name
|
7
|
+
#
|
8
|
+
Input = Struct.new(:val)
|
9
|
+
|
10
|
+
include DeviceState
|
11
|
+
attr_reader :client, :id, :name
|
12
|
+
|
13
|
+
def initialize(client, id, attrs)
|
14
|
+
@client = client
|
15
|
+
@id = id.to_i
|
16
|
+
@name = attrs.fetch("name")
|
17
|
+
@attrs = attrs
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def state_change_url
|
23
|
+
url "/action"
|
24
|
+
end
|
25
|
+
|
26
|
+
def url(path = "")
|
27
|
+
"/groups/#{id}#{path}"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
data/lib/huebot/light.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
module Huebot
|
2
|
+
class Light
|
3
|
+
#
|
4
|
+
# Struct for specifying a Light input (id or name)
|
5
|
+
#
|
6
|
+
# @attr val [Integer|String] id or name
|
7
|
+
#
|
8
|
+
Input = Struct.new(:val)
|
9
|
+
|
10
|
+
include DeviceState
|
11
|
+
attr_reader :client, :id, :name
|
12
|
+
|
13
|
+
def initialize(client, id, attrs)
|
14
|
+
@client = client
|
15
|
+
@id = id.to_i
|
16
|
+
@name = attrs.fetch("name")
|
17
|
+
@attrs = attrs
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def state_change_url
|
23
|
+
url "/state"
|
24
|
+
end
|
25
|
+
|
26
|
+
def url(path = "")
|
27
|
+
"/lights/#{id}#{path}"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
data/lib/huebot/program.rb
CHANGED
@@ -1,32 +1,82 @@
|
|
1
1
|
module Huebot
|
2
2
|
class Program
|
3
|
-
|
4
|
-
|
3
|
+
#
|
4
|
+
# Struct for storing a program's Intermediate Representation and source filepath.
|
5
|
+
#
|
6
|
+
# @attr tokens [Hash]
|
7
|
+
# @attr filepath [String]
|
8
|
+
# @attr api_version [Float] API version
|
9
|
+
#
|
10
|
+
Src = Struct.new(:tokens, :filepath, :api_version) do
|
11
|
+
def default_name
|
12
|
+
File.basename(filepath, ".*")
|
13
|
+
end
|
14
|
+
end
|
5
15
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
@errors = []
|
23
|
-
@warnings = []
|
16
|
+
module AST
|
17
|
+
Node = Struct.new(:instruction, :children, :errors, :warnings)
|
18
|
+
|
19
|
+
Transition = Struct.new(:state, :devices, :sleep)
|
20
|
+
SerialControl = Struct.new(:loop, :sleep)
|
21
|
+
ParallelControl = Struct.new(:loop, :sleep)
|
22
|
+
|
23
|
+
InfiniteLoop = Struct.new(:pause)
|
24
|
+
CountedLoop = Struct.new(:n, :pause)
|
25
|
+
TimerLoop = Struct.new(:hours, :minutes, :pause)
|
26
|
+
DeadlineLoop = Struct.new(:stop_time, :pause)
|
27
|
+
|
28
|
+
DeviceRef = Struct.new(:ref)
|
29
|
+
Light = Struct.new(:name)
|
30
|
+
Group = Struct.new(:name)
|
31
|
+
NoOp = Struct.new(:x)
|
24
32
|
end
|
25
33
|
|
34
|
+
attr_accessor :name
|
35
|
+
attr_accessor :api_version
|
36
|
+
attr_accessor :data
|
37
|
+
|
26
38
|
def valid?
|
27
39
|
errors.empty?
|
28
40
|
end
|
29
41
|
|
30
|
-
|
42
|
+
# Returns all light names hard-coded into the program
|
43
|
+
def light_names(node = data)
|
44
|
+
devices(AST::Light).uniq.map(&:name)
|
45
|
+
end
|
46
|
+
|
47
|
+
# Returns all group names hard-coded into the program
|
48
|
+
def group_names(node = data)
|
49
|
+
devices(AST::Group).uniq.map(&:name)
|
50
|
+
end
|
51
|
+
|
52
|
+
# Returns all device refs (e.g. $all, $1, $2) in the program
|
53
|
+
def device_refs(node = data)
|
54
|
+
devices(AST::DeviceRef).uniq.map(&:ref)
|
55
|
+
end
|
56
|
+
|
57
|
+
def errors(node = data)
|
58
|
+
node.children.reduce(node.errors) { |errors, child|
|
59
|
+
errors + child.errors
|
60
|
+
}
|
61
|
+
end
|
62
|
+
|
63
|
+
def warnings(node = data)
|
64
|
+
node.children.reduce(node.warnings) { |warnings, child|
|
65
|
+
warnings + child.warnings
|
66
|
+
}
|
67
|
+
end
|
68
|
+
|
69
|
+
private
|
70
|
+
|
71
|
+
def devices(type, node = data)
|
72
|
+
case node.instruction
|
73
|
+
when AST::Transition
|
74
|
+
node.instruction.devices.select { |d| d.is_a? type }
|
75
|
+
when AST::SerialControl, AST::ParallelControl
|
76
|
+
node.children.map { |n| devices type, n }.flatten
|
77
|
+
else
|
78
|
+
[]
|
79
|
+
end
|
80
|
+
end
|
31
81
|
end
|
32
82
|
end
|
data/lib/huebot/version.rb
CHANGED
data/lib/huebot.rb
CHANGED
@@ -1,31 +1,16 @@
|
|
1
|
-
require 'hue'
|
2
|
-
|
3
1
|
module Huebot
|
2
|
+
Error = Class.new(StandardError)
|
3
|
+
|
4
|
+
autoload :Config, 'huebot/config'
|
5
|
+
autoload :Client, 'huebot/client'
|
6
|
+
autoload :CLI, 'huebot/cli'
|
7
|
+
autoload :Bridge, 'huebot/bridge'
|
8
|
+
autoload :DeviceState, 'huebot/device_state'
|
9
|
+
autoload :Light, 'huebot/light'
|
10
|
+
autoload :Group, 'huebot/group'
|
4
11
|
autoload :DeviceMapper, 'huebot/device_mapper'
|
5
12
|
autoload :Program, 'huebot/program'
|
6
13
|
autoload :Compiler, 'huebot/compiler'
|
7
14
|
autoload :Bot, 'huebot/bot'
|
8
15
|
autoload :VERSION, 'huebot/version'
|
9
|
-
|
10
|
-
#
|
11
|
-
# Struct for storing a program's Intermediate Representation and source filepath.
|
12
|
-
#
|
13
|
-
# @attr ir [Hash]
|
14
|
-
# @attr filepath [String]
|
15
|
-
#
|
16
|
-
ProgramSrc = Struct.new(:ir, :filepath)
|
17
|
-
|
18
|
-
#
|
19
|
-
# Struct for specifying a Light input (id or name)
|
20
|
-
#
|
21
|
-
# @attr val [Integer|String] id or name
|
22
|
-
#
|
23
|
-
LightInput = Struct.new(:val)
|
24
|
-
|
25
|
-
#
|
26
|
-
# Struct for specifying a Group input (id or name)
|
27
|
-
#
|
28
|
-
# @attr val [Integer|String] id or name
|
29
|
-
#
|
30
|
-
GroupInput = Struct.new(:val)
|
31
16
|
end
|
metadata
CHANGED
@@ -1,15 +1,43 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: huebot
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.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:
|
12
|
-
dependencies:
|
11
|
+
date: 2023-12-18 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: minitest
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '5.0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '5.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '13.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '13.0'
|
13
41
|
description: Declare and run YAML programs for Philips Hue devices
|
14
42
|
email: jordan.hollinger@gmail.com
|
15
43
|
executables:
|
@@ -19,29 +47,27 @@ extra_rdoc_files: []
|
|
19
47
|
files:
|
20
48
|
- README.md
|
21
49
|
- 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
50
|
- lib/huebot.rb
|
34
51
|
- lib/huebot/bot.rb
|
52
|
+
- lib/huebot/bridge.rb
|
35
53
|
- lib/huebot/cli.rb
|
54
|
+
- lib/huebot/cli/helpers.rb
|
55
|
+
- lib/huebot/cli/runner.rb
|
56
|
+
- lib/huebot/client.rb
|
36
57
|
- lib/huebot/compiler.rb
|
58
|
+
- lib/huebot/compiler/api_v1.rb
|
59
|
+
- lib/huebot/config.rb
|
37
60
|
- lib/huebot/device_mapper.rb
|
61
|
+
- lib/huebot/device_state.rb
|
62
|
+
- lib/huebot/group.rb
|
63
|
+
- lib/huebot/light.rb
|
38
64
|
- lib/huebot/program.rb
|
39
65
|
- lib/huebot/version.rb
|
40
66
|
homepage: https://github.com/jhollinger/huebot
|
41
67
|
licenses:
|
42
68
|
- MIT
|
43
69
|
metadata: {}
|
44
|
-
post_install_message:
|
70
|
+
post_install_message:
|
45
71
|
rdoc_options: []
|
46
72
|
require_paths:
|
47
73
|
- lib
|
@@ -56,8 +82,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
56
82
|
- !ruby/object:Gem::Version
|
57
83
|
version: '0'
|
58
84
|
requirements: []
|
59
|
-
rubygems_version: 3.
|
60
|
-
signing_key:
|
85
|
+
rubygems_version: 3.4.1
|
86
|
+
signing_key:
|
61
87
|
specification_version: 4
|
62
88
|
summary: Orchestration for Hue devices
|
63
89
|
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.
|
data/lib/hue/bridge.rb
DELETED
@@ -1,140 +0,0 @@
|
|
1
|
-
module Hue
|
2
|
-
class Bridge
|
3
|
-
# ID of the bridge.
|
4
|
-
attr_reader :id
|
5
|
-
|
6
|
-
# Name of the bridge. This is also its uPnP name, so will reflect the
|
7
|
-
# actual uPnP name after any conflicts have been resolved.
|
8
|
-
attr_accessor :name
|
9
|
-
|
10
|
-
# IP address of the bridge.
|
11
|
-
attr_reader :ip
|
12
|
-
|
13
|
-
# MAC address of the bridge.
|
14
|
-
attr_reader :mac_address
|
15
|
-
|
16
|
-
# IP Address of the proxy server being used.
|
17
|
-
attr_reader :proxy_address
|
18
|
-
|
19
|
-
# Port of the proxy being used by the bridge. If set to 0 then a proxy is
|
20
|
-
# not being used.
|
21
|
-
attr_reader :proxy_port
|
22
|
-
|
23
|
-
# Software version of the bridge.
|
24
|
-
attr_reader :software_version
|
25
|
-
|
26
|
-
# Contains information related to software updates.
|
27
|
-
attr_reader :software_update
|
28
|
-
|
29
|
-
# An array of whitelisted user IDs.
|
30
|
-
attr_reader :ip_whitelist
|
31
|
-
|
32
|
-
# Network mask of the bridge.
|
33
|
-
attr_reader :network_mask
|
34
|
-
|
35
|
-
# Gateway IP address of the bridge.
|
36
|
-
attr_reader :gateway
|
37
|
-
|
38
|
-
# Whether the IP address of the bridge is obtained with DHCP.
|
39
|
-
attr_reader :dhcp
|
40
|
-
|
41
|
-
def initialize(client, hash)
|
42
|
-
@client = client
|
43
|
-
unpack(hash)
|
44
|
-
end
|
45
|
-
|
46
|
-
# Current time stored on the bridge.
|
47
|
-
def utc
|
48
|
-
json = get_configuration
|
49
|
-
DateTime.parse(json['utc'])
|
50
|
-
end
|
51
|
-
|
52
|
-
# Indicates whether the link button has been pressed within the last 30
|
53
|
-
# seconds.
|
54
|
-
def link_button_pressed?
|
55
|
-
json = get_configuration
|
56
|
-
json['linkbutton']
|
57
|
-
end
|
58
|
-
|
59
|
-
# This indicates whether the bridge is registered to synchronize data with a
|
60
|
-
# portal account.
|
61
|
-
def has_portal_services?
|
62
|
-
json = get_configuration
|
63
|
-
json['portalservices']
|
64
|
-
end
|
65
|
-
|
66
|
-
def refresh
|
67
|
-
json = get_configuration
|
68
|
-
unpack(json)
|
69
|
-
@lights = nil
|
70
|
-
@groups = nil
|
71
|
-
@scenes = nil
|
72
|
-
end
|
73
|
-
|
74
|
-
def lights
|
75
|
-
@lights ||= begin
|
76
|
-
json = JSON(Net::HTTP.get(URI.parse(base_url)))
|
77
|
-
json['lights'].map do |key, value|
|
78
|
-
Light.new(@client, self, key, value)
|
79
|
-
end
|
80
|
-
end
|
81
|
-
end
|
82
|
-
|
83
|
-
def add_lights
|
84
|
-
uri = URI.parse("#{base_url}/lights")
|
85
|
-
http = Net::HTTP.new(uri.host)
|
86
|
-
response = http.request_post(uri.path, nil)
|
87
|
-
(response.body).first
|
88
|
-
end
|
89
|
-
|
90
|
-
def groups
|
91
|
-
@groups ||= begin
|
92
|
-
json = JSON(Net::HTTP.get(URI.parse("#{base_url}/groups")))
|
93
|
-
json.map do |id, data|
|
94
|
-
Group.new(@client, self, id, data)
|
95
|
-
end
|
96
|
-
end
|
97
|
-
end
|
98
|
-
|
99
|
-
def scenes
|
100
|
-
@scenes ||= begin
|
101
|
-
json = JSON(Net::HTTP.get(URI.parse("#{base_url}/scenes")))
|
102
|
-
json.map do |id, data|
|
103
|
-
Scene.new(@client, self, id, data)
|
104
|
-
end
|
105
|
-
end
|
106
|
-
end
|
107
|
-
|
108
|
-
private
|
109
|
-
|
110
|
-
KEYS_MAP = {
|
111
|
-
:id => :id,
|
112
|
-
:ip => :internalipaddress,
|
113
|
-
:name => :name,
|
114
|
-
:proxy_port => :proxyport,
|
115
|
-
:software_update => :swupdate,
|
116
|
-
:ip_whitelist => :whitelist,
|
117
|
-
:software_version => :swversion,
|
118
|
-
:proxy_address => :proxyaddress,
|
119
|
-
:mac_address => :macaddress,
|
120
|
-
:network_mask => :netmask,
|
121
|
-
:portal_services => :portalservices,
|
122
|
-
}
|
123
|
-
|
124
|
-
def unpack(hash)
|
125
|
-
KEYS_MAP.each do |local_key, remote_key|
|
126
|
-
value = hash[remote_key.to_s]
|
127
|
-
next unless value
|
128
|
-
instance_variable_set("@#{local_key}", value)
|
129
|
-
end
|
130
|
-
end
|
131
|
-
|
132
|
-
def get_configuration
|
133
|
-
JSON(Net::HTTP.get(URI.parse("#{base_url}/config")))
|
134
|
-
end
|
135
|
-
|
136
|
-
def base_url
|
137
|
-
"http://#{ip}/api/#{@client.username}"
|
138
|
-
end
|
139
|
-
end
|
140
|
-
end
|