hue_switch 1.0.2 → 1.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +27 -22
- data/hue_switch.gemspec +1 -1
- data/lib/hue_switch/version.rb +1 -1
- data/lib/hue_switch.rb +156 -141
- metadata +8 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a855176711f1ab01897ae965d6945e3aec5be9ad
|
4
|
+
data.tar.gz: 2366d5667f67a30c5017f4d340358ac49df08f7f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 249948fbb69223becc3ba6cfae193fe3afaa0628d884de860c971c25b7b53b02c2296100e756e244e20944a30cd62cf88ee8bd538d3349c55f205214bee13e2d
|
7
|
+
data.tar.gz: ee818b3127438d7e426dd31f703f61d8e2ac6fd1243fc2e3d56cf22eea08928f9ede9ec9671c09280633f7ce2264a08ff41229fa5ed706e6204c0cf9d612d557
|
data/README.md
CHANGED
@@ -12,7 +12,7 @@ Or install it yourself as:
|
|
12
12
|
|
13
13
|
$ gem install hue_switch
|
14
14
|
|
15
|
-
#####Note: There are significant changes between .9 versions and 1.0.0. Some basic commands work slightly differently. Random Colors have been removed.
|
15
|
+
#####Note: There are significant changes between .9 versions and 1.0.0. Some basic commands work slightly differently. Random Colors have been removed. Version 1.0.0 includes a new method -- #voice -- that allows most Switch methods to be passed as a string. Please see end of README for details.
|
16
16
|
|
17
17
|
## Usage
|
18
18
|
A Hue Switch is designed control Hue lights, groups, and scenes. You can schedule a Switch. You can save a Switch as a Hue Scene on the bridge.
|
@@ -23,7 +23,7 @@ Why is this different from other wrappers?
|
|
23
23
|
|
24
24
|
1. Hue-Switch is not designed to give full access to Hue API, but to make access to basic operations super easy. A Hue Switch can be assigned an existing group, scene, or one or more individual lights. Switches can be scheduled easily. Color effects can be added (color loop, long and short alerts etc.) For example, a switch could be three random lights on a colorloop. If you turn the switch off, the lights go off. Turn it on, and they continue to cycle through colors.
|
25
25
|
|
26
|
-
2. Hue-Switch comes with a utility method (dare I call it a DSL?), #voice. The voice method allows access to (almost) all of the Switch class funtionality with a single string. See below for important differences when using the #voice method
|
26
|
+
2. Hue-Switch comes with a utility method (dare I call it a DSL?), #voice. The voice method allows access to (almost) all of the Switch class funtionality with a single string. See below for important differences when using the #voice method.
|
27
27
|
|
28
28
|
###Create a Switch
|
29
29
|
|
@@ -48,7 +48,7 @@ switch = Switch.new do
|
|
48
48
|
fade 10 #specified in seconds
|
49
49
|
end
|
50
50
|
```
|
51
|
-
Then switch.on
|
51
|
+
Then `switch.on`
|
52
52
|
|
53
53
|
Colors can be specified by
|
54
54
|
|
@@ -56,6 +56,13 @@ Colors can be specified by
|
|
56
56
|
|
57
57
|
2. Numeric value of hue [0-65535], or mired color value [0-500]
|
58
58
|
|
59
|
+
```ruby
|
60
|
+
switch.mired 250
|
61
|
+
switch.hue 45000
|
62
|
+
switch.color :green
|
63
|
+
switch.color :concentrate
|
64
|
+
```
|
65
|
+
|
59
66
|
Groups are indicated by **:lights**, single lights by **:light**.
|
60
67
|
|
61
68
|
A switch can control multiple individual lights, even if they are not in a group.
|
@@ -98,14 +105,11 @@ switch.reset
|
|
98
105
|
Switches can be scheduled:
|
99
106
|
|
100
107
|
```ruby
|
101
|
-
switch.schedule :on, "
|
108
|
+
switch.schedule :on, "eight thirty tonight"
|
109
|
+
switch.schedule :on, "June 9 at 08:00"
|
102
110
|
switch.schedule :off, "in three minutes" # "tomorrow", "next week"
|
103
111
|
```
|
104
112
|
|
105
|
-
1. If you don't specify :on, :off, or a time, schedule will default to turning on the current switch state in 24 hours.
|
106
|
-
2. Lights will flash once to let you know the scene was successfully sceduled.
|
107
|
-
3. Schedules can be set a week up to a week ahead of time. You can specify days of the week (e.g, monday, next tuesday) but you cannot specify a date.
|
108
|
-
|
109
113
|
####Delete the schedule(s) created by the switch:
|
110
114
|
|
111
115
|
```ruby
|
@@ -113,9 +117,9 @@ switch.delete_schedules!
|
|
113
117
|
```
|
114
118
|
###Dynamic Effects:
|
115
119
|
```ruby
|
116
|
-
switch.colorloop # to cycle through colors
|
117
|
-
switch.alert
|
118
|
-
switch.
|
120
|
+
switch.colorloop :start # to cycle through colors
|
121
|
+
switch.alert :short # to flash lights once
|
122
|
+
switch.alert :long # to flash lights for 30 seconds
|
119
123
|
```
|
120
124
|
Then `switch.on`
|
121
125
|
|
@@ -130,20 +134,20 @@ The voice method takes a single string and is meant to control the Switch class
|
|
130
134
|
|
131
135
|
Because #voice takes a string meant to be spoken, there are important differences between using switch and switch.voice:
|
132
136
|
|
133
|
-
1. switch.voice takes no numeric inputs. Brightness and Saturation are set on a scale of one to ten. Fade times for lights are similarly specified in words by seconds. See examples below.
|
137
|
+
1. switch.voice takes no numeric inputs. Brightness and Saturation are set on a scale of one to ten. Fade times for lights are similarly specified in words by seconds. See examples below. Scheduling has some restrictions.
|
134
138
|
2. Colors can only be specified by name (i.e., 'hue 40000' is not available using #voice).
|
135
139
|
3. Only a single light can be specified after a 'light' command.
|
136
|
-
4.
|
140
|
+
4. \#reset and #delete_scenes! methods not available with #voice
|
137
141
|
5. **Changes take effect immediately.** Using the #voice method, you don't need to send a separate "on" command for switch properties to be sent to the lights. So:
|
138
142
|
|
139
143
|
```ruby
|
140
|
-
switch.color :blue
|
144
|
+
switch.color :blue ; switch.on
|
141
145
|
switch.lights :kitchen ; switch.saturation 255 ; switch.brightness 127 ; switch.on
|
142
146
|
```
|
143
147
|
is now
|
144
148
|
```ruby
|
145
149
|
switch.voice "color blue"
|
146
|
-
|
150
|
+
switch.voice "kitchen lights saturation ten brightness five"
|
147
151
|
```
|
148
152
|
###Examples
|
149
153
|
#####Recall a scene
|
@@ -156,20 +160,21 @@ Will save the current light configuration to a scene on the bridge.
|
|
156
160
|
```ruby
|
157
161
|
switch.voice "save scene as romantic dinner"
|
158
162
|
```
|
159
|
-
|
160
|
-
|
163
|
+
note: scenes saved with \#voice will be affect all lights.
|
164
|
+
######Schedules
|
165
|
+
Scheduling syntax is extremely flexible. Any command can be scheduled. With \#voice you can schedule up to a week ahead of time (e.g., "next Monday") and dates ("June 22") are not supported
|
161
166
|
```ruby
|
162
167
|
switch.voice "schedule kitchen lights color blue in ten minutes"
|
163
168
|
switch.voice "start colorloop bedside light schedule at eight fifty three next Friday"
|
164
169
|
switch.voice "romantic scene schedule tomorrow at eight in the evening"
|
165
170
|
switch.voice "schedule purple paradise scene thursday evening at eight forty five"
|
166
171
|
```
|
167
|
-
|
172
|
+
######Dynamic Effects:
|
168
173
|
```ruby
|
169
|
-
"living room lights short alert" [flash lights in the group once]
|
170
|
-
"long alert table light" [flash light for 30 seconds]
|
171
|
-
"brightness five fireplace lights start colorloop"
|
172
|
-
"fireplace lights stop colorloop"
|
174
|
+
switch.voice "living room lights short alert" [flash lights in the group once]
|
175
|
+
switch.voice "long alert table light" [flash light for 30 seconds]
|
176
|
+
switch.voice "brightness five fireplace lights start colorloop"
|
177
|
+
switch.voice "fireplace lights stop colorloop"
|
173
178
|
```
|
174
179
|
|
175
180
|
|
data/hue_switch.gemspec
CHANGED
@@ -27,5 +27,5 @@ Gem::Specification.new do |spec|
|
|
27
27
|
spec.add_dependency 'numbers_in_words', '~> 0.2.0'
|
28
28
|
spec.add_development_dependency "bundler", "~> 1.9"
|
29
29
|
spec.add_development_dependency "rake", "~> 10.0"
|
30
|
-
spec.add_development_dependency 'rspec', '~> 2.4.0'
|
30
|
+
spec.add_development_dependency 'rspec', '~> 2.4', '>=2.4.0'
|
31
31
|
end
|
data/lib/hue_switch/version.rb
CHANGED
data/lib/hue_switch.rb
CHANGED
@@ -10,43 +10,47 @@ class Switch
|
|
10
10
|
|
11
11
|
@user = "1234567890"
|
12
12
|
@ip = HTTParty.get("https://www.meethue.com/api/nupnp").first["internalipaddress"]
|
13
|
+
|
14
|
+
authorize_user
|
15
|
+
populate_switch
|
16
|
+
|
17
|
+
self.lights_array = []
|
18
|
+
self.schedule_ids = []
|
19
|
+
self.schedule_params = nil
|
20
|
+
self.command = ""
|
21
|
+
self._group = "0"
|
22
|
+
self.body = {}
|
23
|
+
instance_eval(&block) if block_given?
|
24
|
+
end
|
25
|
+
|
26
|
+
def authorize_user
|
13
27
|
unless HTTParty.get("http://#{@ip}/api/#{@user}/config").include?("whitelist")
|
14
28
|
if HTTParty.post("http://#{@ip}/api", :body => ({:devicetype => "Hue_Switch", :username=>"1234567890"}).to_json).first.include?("error")
|
15
29
|
raise "You need to press the link button on the bridge and run again"
|
16
30
|
end
|
17
31
|
end
|
18
|
-
|
32
|
+
end
|
33
|
+
|
34
|
+
def populate_switch
|
19
35
|
@colors = {red: 65280, pink: 56100, purple: 52180, violet: 47188, blue: 46920, turquoise: 31146, green: 25500, yellow: 12750, orange: 8618}
|
20
|
-
@mired_colors = {candle: 500, relax: 467, reading: 346, neutral: 300, concentrate: 231, energize: 136}
|
36
|
+
@mired_colors = {candle: 500, relax: 467, reading: 346, neutral: 300, concentrate: 231, energize: 136}
|
21
37
|
@scenes = [] ; HTTParty.get("http://#{@ip}/api/#{@user}/scenes").keys.each { |k| @scenes.push(k) }
|
22
38
|
@groups = {} ; HTTParty.get("http://#{@ip}/api/#{@user}/groups").each { |k,v| @groups["#{v['name']}".downcase] = k } ; @groups["all"] = "0"
|
23
39
|
@lights = {} ; HTTParty.get("http://#{@ip}/api/#{@user}/lights").each { |k,v| @lights["#{v['name']}".downcase] = k }
|
24
|
-
|
25
|
-
self.lights_array = []
|
26
|
-
self.schedule_ids = []
|
27
|
-
self.schedule_params = nil
|
28
|
-
self.command = ""
|
29
|
-
self._group = :all
|
30
|
-
self.body = {}
|
31
|
-
instance_eval(&block) if block_given?
|
32
40
|
end
|
33
41
|
|
34
42
|
def hue (numeric_value)
|
35
|
-
|
36
|
-
self.body.delete(:ct)
|
43
|
+
clear_attributes
|
37
44
|
self.body[:hue] = numeric_value
|
38
45
|
end
|
39
46
|
|
40
47
|
def mired (numeric_value)
|
41
|
-
|
42
|
-
self.body.delete(:hue)
|
48
|
+
clear_attributes
|
43
49
|
self.body[:ct] = numeric_value
|
44
50
|
end
|
45
51
|
|
46
52
|
def color(color_name)
|
47
|
-
|
48
|
-
self.body.delete(:ct)
|
49
|
-
self.body.delete(:hue)
|
53
|
+
clear_attributes
|
50
54
|
@colors.keys.include?(color_name.to_sym) ?
|
51
55
|
self.body[:hue] = @colors[color_name.to_sym] : self.body[:ct] = @mired_colors[color_name.to_sym]
|
52
56
|
end
|
@@ -61,14 +65,19 @@ class Switch
|
|
61
65
|
self.body[:bri] = depth
|
62
66
|
end
|
63
67
|
|
68
|
+
def clear_attributes
|
69
|
+
self.body.delete(:scene)
|
70
|
+
self.body.delete(:ct)
|
71
|
+
self.body.delete(:hue)
|
72
|
+
end
|
73
|
+
|
64
74
|
def fade(in_seconds)
|
65
75
|
self.body[:transitiontime] = in_seconds * 10
|
66
76
|
end
|
67
77
|
|
68
78
|
def light (*args)
|
69
79
|
self.lights_array = []
|
70
|
-
self._group =
|
71
|
-
self.body.delete(:groups)
|
80
|
+
self._group = ""
|
72
81
|
self.body.delete(:scene)
|
73
82
|
args.each { |l| self.lights_array.push @lights[l.to_s] if @lights.keys.include?(l.to_s) }
|
74
83
|
end
|
@@ -80,80 +89,101 @@ class Switch
|
|
80
89
|
end
|
81
90
|
|
82
91
|
def scene(scene_name)
|
92
|
+
clear_attributes
|
83
93
|
self.lights_array = []
|
84
|
-
self._group = 0
|
85
|
-
self.body.delete(:groups)
|
86
|
-
self.body.delete(:hue)
|
87
|
-
self.body.delete(:ct)
|
94
|
+
self._group = "0"
|
88
95
|
self.body[:scene] = scene_name.to_s
|
89
96
|
end
|
90
97
|
|
98
|
+
def confirm
|
99
|
+
params = {:alert => 'select'}
|
100
|
+
HTTParty.put("http://#{@ip}/api/#{@user}/groups/0/action" , :body => params.to_json)
|
101
|
+
end
|
102
|
+
|
91
103
|
def save_scene(scene_name)
|
104
|
+
scene_name.gsub!(' ','-')
|
92
105
|
self.fade 2 if self.body[:transitiontime] == nil
|
93
|
-
if self._group.
|
106
|
+
if self._group.empty?
|
94
107
|
light_group = HTTParty.get("http://#{@ip}/api/#{@user}/groups/0")["lights"]
|
95
108
|
else
|
96
109
|
light_group = HTTParty.get("http://#{@ip}/api/#{@user}/groups/#{self._group}")["lights"]
|
97
110
|
end
|
98
|
-
scene_name.gsub!(' ','-')
|
99
111
|
params = {name: scene_name, lights: light_group, transitiontime: self.body[:transitiontime]}
|
100
112
|
response = HTTParty.put("http://#{@ip}/api/#{@user}/scenes/#{scene_name}", :body => params.to_json)
|
101
|
-
if response.first.keys[0] == "success"
|
102
|
-
|
103
|
-
|
104
|
-
|
113
|
+
confirm if response.first.keys[0] == "success"
|
114
|
+
end
|
115
|
+
|
116
|
+
def lights_on_off
|
117
|
+
self.lights_array.each { |l| HTTParty.put("http://#{@ip}/api/#{@user}/lights/#{l}/state", :body => (self.body).to_json) }
|
118
|
+
end
|
119
|
+
|
120
|
+
def group_on_off
|
121
|
+
HTTParty.put("http://#{@ip}/api/#{@user}/groups/#{self._group}/action", :body => (self.body.reject { |s| s == :scene }).to_json)
|
122
|
+
end
|
123
|
+
|
124
|
+
def scene_on_off
|
125
|
+
if self.body[:on] == true
|
126
|
+
HTTParty.put("http://#{@ip}/api/#{@user}/groups/#{self._group}/action", :body => (self.body.select { |s| s == :scene }).to_json)
|
127
|
+
elsif self.body[:on] == false
|
128
|
+
# turn off individual lights in the scene
|
129
|
+
(HTTParty.get("http://#{@ip}/api/#{@user}/scenes"))[self.body[:scene]]["lights"].each do |l|
|
130
|
+
puts self.body
|
131
|
+
HTTParty.put("http://#{@ip}/api/#{@user}/lights/#{l}/state", :body => (self.body).to_json)
|
132
|
+
end
|
105
133
|
end
|
106
134
|
end
|
107
135
|
|
108
136
|
def on
|
109
137
|
self.body[:on]=true
|
110
|
-
if self.lights_array.any?
|
111
|
-
|
112
|
-
|
113
|
-
HTTParty.put("http://#{@ip}/api/#{@user}/groups/#{self._group}/action", :body => (self.body.select { |s| s == :scene }).to_json)
|
114
|
-
else
|
115
|
-
HTTParty.put("http://#{@ip}/api/#{@user}/groups/#{self._group}/action", :body => (self.body).to_json)
|
116
|
-
end
|
138
|
+
lights_on_off if self.lights_array.any?
|
139
|
+
group_on_off if (!self._group.empty? && self.body[:scene].nil?)
|
140
|
+
scene_on_off if !self.body[:scene].nil?
|
117
141
|
end
|
118
142
|
|
119
143
|
def off
|
120
|
-
self.body[:on]
|
121
|
-
if self.lights_array.any?
|
122
|
-
|
123
|
-
|
124
|
-
(HTTParty.get("http://#{@ip}/api/#{@user}/scenes"))[self.body[:scene]]["lights"].each do |l|
|
125
|
-
HTTParty.put("http://#{@ip}/api/#{@user}/lights/#{l}/state", :body => ({:on=>false}).to_json)
|
126
|
-
end
|
127
|
-
else
|
128
|
-
HTTParty.put("http://#{@ip}/api/#{@user}/groups/#{self._group}/action", :body => (self.body).to_json)
|
129
|
-
end
|
144
|
+
self.body[:on]=false
|
145
|
+
lights_on_off if self.lights_array.any?
|
146
|
+
group_on_off if (!self._group.empty? && self.body[:scene].nil?)
|
147
|
+
scene_on_off if !self.body[:scene].nil?
|
130
148
|
end
|
131
149
|
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
150
|
+
# Parses times in words (e.g., "eight forty five") to standard HH:MM format
|
151
|
+
|
152
|
+
def numbers_to_times(numbers)
|
153
|
+
numbers.map!(&:in_numbers)
|
154
|
+
numbers.map!(&:to_s)
|
155
|
+
numbers.push("0") if numbers[1] == nil
|
156
|
+
numbers = numbers.shift + ':' + (numbers[0].to_i + numbers[1].to_i).to_s
|
157
|
+
numbers.gsub!(':', ':0') if numbers.split(":")[1].length < 2
|
158
|
+
numbers
|
159
|
+
end
|
160
|
+
|
161
|
+
def parse_time(string)
|
162
|
+
string.sub!(" noon", " twelve in the afternoon")
|
163
|
+
string.sub!("midnight", "twelve in the morning")
|
164
|
+
time_modifier = string.downcase.scan(/(evening)|(night|tonight)|(afternoon)|(pm)|(a.m.)|(morning)|(today)/).flatten.compact.first
|
165
|
+
guess = Time.now.strftime('%H').to_i >= 12 ? "p.m." : "a.m."
|
166
|
+
time_modifier = time_modifier.nil? ? guess : time_modifier
|
167
|
+
day_modifier = string.scan(/(tomorrow)|(next )?(monday|tuesday|wednesday|thursday|friday|saturday|sunday)/).flatten.compact.join(' ')
|
168
|
+
numbers_in_words = string.scan(Regexp.union((1..59).map(&:in_words)))
|
169
|
+
set_time = numbers_to_times(numbers_in_words)
|
170
|
+
set_time = Chronic.parse(day_modifier + ' ' + set_time + ' ' + time_modifier)
|
171
|
+
end
|
137
172
|
|
173
|
+
def set_time(string)
|
138
174
|
if string.scan(/ seconds?| minutes?| hours?| days?| weeks?/).any?
|
139
175
|
set_time = Time.now + ChronicDuration.parse(string)
|
176
|
+
elsif string.scan(/\d/).any?
|
177
|
+
set_time = Chronic.parse(string)
|
140
178
|
else
|
141
|
-
|
142
|
-
string.sub!("midnight", "twelve in the morning")
|
143
|
-
time_modifier = string.downcase.scan(/(evening)|(night|tonight)|(afternoon)|(pm)|(a.m.)|(morning)|(today)/).flatten.compact.first
|
144
|
-
guess = Time.now.strftime('%H').to_i >= 12 ? "p.m." : "a.m."
|
145
|
-
time_modifier = time_modifier.nil? ? guess : time_modifier
|
146
|
-
day_modifier = string.scan(/(tomorrow)|(next )?(monday|tuesday|wednesday|thursday|friday|saturday|sunday)/).flatten.compact.join(' ')
|
147
|
-
set_time = string.scan(Regexp.union((1..59).map(&:in_words)))
|
148
|
-
set_time.map!(&:in_numbers)
|
149
|
-
set_time.map!(&:to_s)
|
150
|
-
set_time.push("0") if set_time[1] == nil
|
151
|
-
set_time = set_time.shift + ':' + (set_time[0].to_i + set_time[1].to_i).to_s
|
152
|
-
set_time.gsub!(':', ':0') if set_time.split(":")[1].length < 2
|
153
|
-
set_time = Chronic.parse(day_modifier + ' ' + set_time + ' ' + time_modifier)
|
154
|
-
p set_time
|
179
|
+
set_time = parse_time(string)
|
155
180
|
end
|
181
|
+
end
|
156
182
|
|
183
|
+
def schedule (on_or_off = :default, string)
|
184
|
+
self.body[:on] = true if on_or_off == :on
|
185
|
+
self.body[:on] = false if on_or_off == :off
|
186
|
+
set_time = set_time(string)
|
157
187
|
if set_time < Time.now
|
158
188
|
p "You've scheduled this in the past"
|
159
189
|
else
|
@@ -165,23 +195,14 @@ class Switch
|
|
165
195
|
:autodelete=>true
|
166
196
|
}
|
167
197
|
if self.lights_array.any?
|
168
|
-
self.schedule_params[:name]= "Hue_Switch Alarm Light Set"
|
169
198
|
lights_array.each do |l|
|
170
199
|
self.schedule_params[:command] = {:address=>"/api/#{@user}/lights/#{l}/state", :method=>"PUT", :body=>self.body}
|
171
|
-
self.schedule_ids.push(HTTParty.post("http://#{@ip}/api/#{@user}/schedules", :body => (self.schedule_params).to_json))
|
172
200
|
end
|
173
|
-
elsif !self.body[:scene].nil?
|
174
|
-
self.schedule_params[:command] = {:address=>"/api/#{@user}/groups/#{self._group}/action", :method=>"PUT", :body=>self.body }
|
175
|
-
self.schedule_ids.push(HTTParty.post("http://#{@ip}/api/#{@user}/schedules", :body => (self.schedule_params).to_json))
|
176
201
|
else
|
177
202
|
self.schedule_params[:command] = {:address=>"/api/#{@user}/groups/#{self._group}/action", :method=>"PUT", :body=>self.body}
|
178
|
-
self.schedule_ids.push(HTTParty.post("http://#{@ip}/api/#{@user}/schedules", :body => (self.schedule_params).to_json))
|
179
203
|
end
|
180
|
-
|
181
|
-
|
182
|
-
params = {:alert => 'select'}
|
183
|
-
HTTParty.put("http://#{@ip}/api/#{@user}/groups/0/action" , :body => params.to_json)
|
184
|
-
end
|
204
|
+
self.schedule_ids.push(HTTParty.post("http://#{@ip}/api/#{@user}/schedules", :body => (self.schedule_params).to_json))
|
205
|
+
confirm if self.schedule_ids.flatten.last.include?("success")
|
185
206
|
end
|
186
207
|
end
|
187
208
|
|
@@ -214,94 +235,88 @@ class Switch
|
|
214
235
|
|
215
236
|
def reset
|
216
237
|
self.command = ""
|
217
|
-
self._group = 0
|
238
|
+
self._group = "0"
|
218
239
|
self.body = {}
|
219
240
|
self.schedule_params = nil
|
220
241
|
end
|
221
242
|
|
222
|
-
#The following two methods are required to use Switch
|
243
|
+
#The following two methods are required to use Switch with Zach Feldman's Alexa-home*
|
223
244
|
def wake_words
|
224
|
-
["light", "lights", "scene", "seen"
|
245
|
+
["light", "lights", "scene", "seen"]
|
225
246
|
end
|
226
247
|
|
227
248
|
def process_command (command)
|
228
249
|
command.sub!("color loop", "colorloop")
|
229
250
|
command.sub!("too", "two")
|
251
|
+
command.sub!("for", "four")
|
230
252
|
command.sub!(/a half$/, 'thirty seconds')
|
231
253
|
self.voice command
|
232
254
|
end
|
233
255
|
|
234
|
-
#
|
235
|
-
def
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
if string.include?('scene')
|
245
|
-
scene_name.gsub!(' ','-') if scene_name.size > 1
|
246
|
-
scene_name.gsub!(/schedule-?/,'') if scene_name.include?('schedule')
|
247
|
-
puts scene_name
|
248
|
-
self.send("scene", scene_name)
|
256
|
+
#The rest of the methods allow access to most of the Switch class functionality by supplying a single string.
|
257
|
+
def parse_leading(methods)
|
258
|
+
methods.each do |l|
|
259
|
+
capture = (self.command.match (/\b#{l}\s\w+/)).to_s.split(' ')
|
260
|
+
method = capture[0]
|
261
|
+
value = capture[1]
|
262
|
+
value = value.in_numbers if value.scan(Regexp.union( (1..10).map {|k| k.in_words} ) ).any?
|
263
|
+
value = ((value.to_f/10.to_f)*255).to_i if (value.class == Fixnum) && (l != "fade")
|
264
|
+
self.send( method, value )
|
249
265
|
end
|
266
|
+
end
|
250
267
|
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
value = value.in_numbers if value.scan(Regexp.union( (1..10).map {|k| k.in_words} ) ).any?
|
257
|
-
value = ((value.to_f/10.to_f)*255).to_i if (value.class == Fixnum) && (l != "fade")
|
258
|
-
self.send( method, value )
|
259
|
-
end
|
260
|
-
end
|
268
|
+
def parse_trailing(method)
|
269
|
+
all_keys = Regexp.union((@groups.keys + @lights.keys).flatten)
|
270
|
+
value = self.command.match(all_keys).to_s
|
271
|
+
self.send( method.first, value )
|
272
|
+
end
|
261
273
|
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
all_keys = Regexp.union(all_keys)
|
269
|
-
value = string.match (all_keys).to_s
|
270
|
-
self.send( "#{t}", value )
|
271
|
-
end
|
274
|
+
def parse_dynamic(methods)
|
275
|
+
methods.each do |d|
|
276
|
+
capture = (self.command.match (/\w+ #{d}\b/)).to_s.split(' ')
|
277
|
+
method = capture[1]
|
278
|
+
value = capture[0].to_sym
|
279
|
+
self.send( method, value )
|
272
280
|
end
|
281
|
+
end
|
273
282
|
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
+
def parse_scene(scene_name)
|
284
|
+
scene_name.gsub!(' ','-') if scene_name.size > 1
|
285
|
+
scene_name.gsub!(/schedule-?/,'') if scene_name.include?('schedule')
|
286
|
+
self.send("scene", scene_name)
|
287
|
+
end
|
288
|
+
|
289
|
+
def parse_save_scene
|
290
|
+
save_scene = self.command.partition(/save (scene|seen) as /).last
|
291
|
+
self.send( "save_scene", save_scene)
|
292
|
+
end
|
283
293
|
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
294
|
+
def parse_voice(string)
|
295
|
+
trailing = string.split(' ') & %w[lights light]
|
296
|
+
leading = string.split(' ') & %w[hue brightness saturation fade color]
|
297
|
+
dynamic = string.split(' ') & %w[colorloop alert]
|
298
|
+
scene_name = string.partition(" scene").first
|
288
299
|
|
289
|
-
if !
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
300
|
+
parse_scene(scene_name) if string.include?(" scene") && !string.include?("save")
|
301
|
+
parse_leading(leading) if leading.any?
|
302
|
+
parse_trailing(trailing) if trailing.any?
|
303
|
+
parse_dynamic(dynamic) if dynamic.any?
|
304
|
+
parse_save_scene if self.command.scan(/save (scene|seen) as/).length > 0
|
305
|
+
end
|
306
|
+
|
307
|
+
def voice(string)
|
308
|
+
self.reset
|
309
|
+
self.command << string
|
310
|
+
string.gsub!('schedule','')
|
311
|
+
|
312
|
+
parse_voice(string)
|
296
313
|
|
297
314
|
if self.command.include?("schedule")
|
298
|
-
if string.include?(
|
299
|
-
|
300
|
-
elsif string.include?(" off")
|
301
|
-
self.body[:on] = false
|
302
|
-
end
|
315
|
+
self.body[:on] = true if string.include?(' on')
|
316
|
+
self.body[:on] = false if string.include?(' off')
|
303
317
|
self.send("schedule", string)
|
304
|
-
|
305
|
-
|
318
|
+
else
|
319
|
+
string.include?(' off') ? self.send("off") : self.send("on")
|
320
|
+
end
|
306
321
|
end
|
307
322
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hue_switch
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- sarkonovich
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-06-
|
11
|
+
date: 2015-06-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: chronic
|
@@ -99,6 +99,9 @@ dependencies:
|
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
100
100
|
requirements:
|
101
101
|
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '2.4'
|
104
|
+
- - ">="
|
102
105
|
- !ruby/object:Gem::Version
|
103
106
|
version: 2.4.0
|
104
107
|
type: :development
|
@@ -106,6 +109,9 @@ dependencies:
|
|
106
109
|
version_requirements: !ruby/object:Gem::Requirement
|
107
110
|
requirements:
|
108
111
|
- - "~>"
|
112
|
+
- !ruby/object:Gem::Version
|
113
|
+
version: '2.4'
|
114
|
+
- - ">="
|
109
115
|
- !ruby/object:Gem::Version
|
110
116
|
version: 2.4.0
|
111
117
|
description: A 'switch' controls Hue lights, groups, or scenes. Switches can be scheduled,
|