hue_switch 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: de98ca6559d56e0a56b9b9388f5b81b50ba92595
4
+ data.tar.gz: 670efbf7d7ebe27988d7a7773d870d1ba41ef2cd
5
+ SHA512:
6
+ metadata.gz: 7bb3d29d1fa11c37da5570de9fec03fff39260d95bf95b818a3cd75ab3b023a9dbf5566102a3e5a56045f5df352d6c2f6d18b490433650e114bd50ba68e88837
7
+ data.tar.gz: 9dbd6c526a1c8dc25c3898f07b83deeef021c04dffd4cba7798ddece13137324dae04d2409523021980787dd38c54d97550c74113a0edc90ad0d2c7c84150004
data/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
data/.travis.yml ADDED
@@ -0,0 +1,3 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.2.1
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in hue_switch.gemspec
4
+ gemspec
data/README.md ADDED
@@ -0,0 +1,159 @@
1
+ ## Installation
2
+
3
+ Add this line to your application's Gemfile:
4
+
5
+ ```ruby
6
+ gem 'hue_switch'
7
+ ```
8
+
9
+ And then execute:
10
+
11
+ $ bundle
12
+
13
+ Or install it yourself as:
14
+
15
+ $ gem install hue_switch
16
+
17
+ ## Usage
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.
19
+
20
+ NOTE: The first time you run this gem, you'll need to press the link button on the bridge immediately beforehand. If you don't, you'll get an error telling you to do so and try again.
21
+
22
+ Why is this different from other wrappers? 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, random colors, etc.) For example, a switch could be three random lights, rotating through random colors (or colors in a range.) If you turn the switch off, the lights go off. Turn it on, and they continue to cycle through colors.
23
+
24
+ You'll need to replace USER constant with a string representing an authorized user on your Hue bridge.
25
+
26
+ Colors can be specified by
27
+
28
+ 1. Color name (pink, red, blue, etc) including Hue color names (reading, energize, etc.)
29
+
30
+ 2. Numeric value of hue [0-65535], or mired color value [0-500]
31
+
32
+
33
+ ###Create a Switch
34
+
35
+ Basic case, an on-off switch for all lights
36
+ ```ruby
37
+ switch = Switch.new {}
38
+ ```
39
+
40
+ Then
41
+ ```ruby
42
+ switch.on
43
+ switch.off
44
+ ```
45
+
46
+ ###Switch to control a group.
47
+
48
+ ```ruby
49
+ switch = Switch.new do
50
+ group :kitchen
51
+ color :blue
52
+ saturation 255
53
+ brightness 120
54
+ fade 10 #specified in seconds
55
+ end
56
+ ```
57
+ Use `group :all` to specify all lights.
58
+
59
+ ###Switch to control a scene
60
+
61
+ ```ruby
62
+ switch = Switch.new do
63
+ scene :dinner
64
+ end
65
+ ```
66
+
67
+ ###Switch to control one or more individually specified lights.
68
+
69
+ ```ruby
70
+ switch = Switch.new do
71
+ lights :bedside, :floor, :table
72
+ hue 27000
73
+ brightness 120
74
+ end
75
+ ```
76
+ ###Modify Switch
77
+
78
+ After the switch is created, you can modify it:
79
+ ```ruby
80
+ switch.group :fireplace
81
+ switch.color :red
82
+ ```
83
+ You can assign a new group, scene, or set of individual lights to a switch
84
+
85
+ ####Or reset it
86
+
87
+ ```ruby
88
+ switch.reset
89
+ ```
90
+
91
+ ###Schedule the lights
92
+
93
+ Switches can be scheduled:
94
+
95
+ ```ruby
96
+ switch.schedule :on, "8:30 tonight"
97
+ switch.schedule :off, "in three minutes" # "tomorrow", "next week"
98
+ ```
99
+
100
+ If you don't specify :on, :off, or a time, schedule will default to turning on the current switch state in 24 hours.
101
+
102
+ ####Delete the schedule[s] created by the switch:
103
+
104
+ ```ruby
105
+ switch.delete_schedules!
106
+ ```
107
+
108
+ ###Save Switch as a Hue Scene
109
+
110
+ Just specify a name (words must be join with a hyphen.)
111
+
112
+ The scene will be assigned to the group the switch is currently controlling (or all the lights if a group hasn't been assigned to the switch.)
113
+
114
+ All features of the Switch (fade, group, color, etc) will be saved in the scene attributes.
115
+
116
+ ```ruby
117
+ switch.save_scene "my-switch"
118
+ ```
119
+
120
+
121
+ ###Switches can be dynamic:
122
+ ```ruby
123
+ switch.colorloop # to cycle through colors
124
+ switch.alert # to flash lights once
125
+ switch.long_alert # to flash lights for 30 seconds
126
+ ```
127
+ then `switch.on`
128
+
129
+ In addition
130
+
131
+ ```ruby
132
+ switch.random_colors # to loop through random colors
133
+ ```
134
+ Hue, saturation, and brightness can be changed while the switch is cycling. If turned off, the switch will still be dynamic when turned back on.
135
+
136
+ Speed and color range can optionally be assigned
137
+ ```ruby
138
+ switch.random_colors range: 20000..28000 #cycles through greens, roughly
139
+ ```
140
+ Stops dynamic effects.
141
+ ```ruby
142
+ switch.colorloop :stop
143
+ switch.alert :stop
144
+ switch.random_colors :stop
145
+
146
+
147
+ ## Development
148
+
149
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `bin/console` for an interactive prompt that will allow you to experiment.
150
+
151
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release` to create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
152
+
153
+ ## Contributing
154
+
155
+ 1. Fork it ( https://github.com/[my-github-username]/hue_switch/fork )
156
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
157
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
158
+ 4. Push to the branch (`git push origin my-new-feature`)
159
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "hue_switch"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start
data/bin/setup ADDED
@@ -0,0 +1,7 @@
1
+ #!/bin/bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+
5
+ bundle install
6
+
7
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,27 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'hue_switch/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "hue_switch"
8
+ spec.version = HueSwitch::VERSION
9
+ spec.authors = ["sarkonovich"]
10
+ spec.email = ["sarkonovich@ at gmail dot com"]
11
+
12
+ spec.summary = "A gem to easily control Hue lights"
13
+ spec.homepage = "http://www.github.com/sarkonovich"
14
+
15
+
16
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
17
+ spec.bindir = "exe"
18
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.required_ruby_version = '>= 1.9.3'
22
+ spec.add_dependency 'chronic', '~> 0.10.0'
23
+ spec.add_dependency 'chronic_duration', '~> 0'
24
+ spec.add_dependency 'httparty', '~> 0.13.0'
25
+ spec.add_development_dependency "bundler", "~> 1.9"
26
+ spec.add_development_dependency "rake", "~> 10.0"
27
+ end
data/lib/hue_switch.rb ADDED
@@ -0,0 +1,252 @@
1
+ require 'chronic'
2
+ require 'chronic_duration'
3
+ require 'httparty'
4
+
5
+ class Switch
6
+
7
+ attr_accessor :description, :lights_array, :_group, :body, :schedule_params, :schedule_ids, :effect, :effect_state, :effect_thread, :switch_state
8
+
9
+ def initialize(description = "", _group = 0, &block)
10
+
11
+ @user = "1234567890"
12
+ @ip = HTTParty.get("https://www.meethue.com/api/nupnp").first["internalipaddress"]
13
+ unless HTTParty.get("http://#{@ip}/api/#{@user}/config").include?("whitelist")
14
+ if HTTParty.post("http://#{@ip}/api", :body => ({:devicetype => "Hue_Switch", :username=>"1234567890"}).to_json).first.include?("error")
15
+ raise "You need to press the link button on the bridge and run again"
16
+ end
17
+ end
18
+
19
+ @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} ; puts @mired_colors
21
+ @scenes = [] ; HTTParty.get("http://#{@ip}/api/#{@user}/scenes").keys.each { |k| @scenes.push(k) if k =~ /^\D*$/ }
22
+ @groups = {} ; HTTParty.get("http://#{@ip}/api/#{@user}/groups").each { |k,v| @groups["#{v['name']}".downcase.gsub(' ','_')] = k } ; @groups["all"] = "0"
23
+ @lights = {} ; HTTParty.get("http://#{@ip}/api/#{@user}/lights").each { |k,v| @lights["#{v['name']}".downcase] = k }
24
+
25
+ switch_state = switch_state
26
+ self.lights_array = []
27
+ self.effect_thread = []
28
+ self.effect = ""
29
+ self.effect_state = :off
30
+ self.schedule_ids = []
31
+ self.schedule_params = nil
32
+ self.description = description
33
+ self._group = :all
34
+ self.body = {}
35
+ instance_eval(&block) if block_given?
36
+ end
37
+
38
+ def hue (numeric_value)
39
+ self.body.delete(:scene)
40
+ self.body.delete(:ct)
41
+ self.body[:hue] = numeric_value
42
+ self.on
43
+ end
44
+
45
+ def mired (numeric_value)
46
+ self.body.delete(:scene)
47
+ self.body.delete(:hue)
48
+ self.body[:ct] = numeric_value
49
+ self.on
50
+ end
51
+
52
+ def color(color_name)
53
+ self.body.delete(:scene)
54
+ self.body.delete(:ct)
55
+ self.body.delete(:hue)
56
+ @colors.keys.include?(color_name.to_sym) ?
57
+ self.body[:hue] = @colors[color_name.to_sym] : self.body[:ct] = @mired_colors[color_name.to_sym]
58
+ self.on
59
+ end
60
+
61
+ def saturation(depth)
62
+ self.body.delete(:scene)
63
+ self.body[:sat] = depth
64
+ self.on
65
+ end
66
+
67
+ def brightness(depth)
68
+ self.body.delete(:scene)
69
+ self.body[:bri] = depth
70
+ self.on
71
+ end
72
+
73
+ def fade(in_seconds)
74
+ self.body[:transitiontime] = in_seconds * 10
75
+ end
76
+
77
+ def lights(*args)
78
+ self.lights_array = []
79
+ self._group = nil
80
+ self.body.delete(:groups)
81
+ self.body.delete(:scene)
82
+ args.each { |l| self.lights_array.push @lights[l.to_s] if @lights.keys.include?(l.to_s) }
83
+ self.switch_state = "off"
84
+ self.on
85
+ end
86
+
87
+ def group(group_name)
88
+ self.lights_array = []
89
+ self.body.delete(:scene)
90
+ self._group = @groups[group_name.to_s]
91
+ self.switch_state = "off"
92
+ self.on
93
+ end
94
+
95
+ def scene(scene_name)
96
+ self.lights_array = []
97
+ self._group = 0
98
+ self.body.delete(:groups)
99
+ self.body[:scene] = scene_name.to_s
100
+ self.switch_state = "off"
101
+ self.on
102
+ end
103
+
104
+ def save_scene (scene_name)
105
+ self.fade 2 if self.body[:transitiontime] == nil
106
+ if self._group.empty?
107
+ light_group = HTTParty.get("http://10.100.100.3/api/#{@user}/groups/0")["lights"]
108
+ else
109
+ light_group = HTTParty.get("http://10.100.100.3/api/#{@user}/groups/#{self._group}")["lights"]
110
+ end
111
+ params = {name: scene_name, lights: light_group, transitiontime: self.body[:transitiontime]}
112
+ response = HTTParty.put("http://#{@ip}/api/#{@user}/scenes/#{scene_name}", :body => params.to_json)
113
+ if response.first.keys[0] == "success"
114
+ puts "Scene created!"
115
+ else
116
+ puts "Error: scene was NOT created!"
117
+ end
118
+ end
119
+
120
+ def on
121
+ if self.switch_state != "on"
122
+ self.switch_state = "on"
123
+ self.body[:on] = true
124
+ end
125
+
126
+ if self.lights_array.any?
127
+ self.lights_array.each { |l| HTTParty.put("http://#{@ip}/api/#{@user}/lights/#{l}/state", :body => (self.body).to_json) }
128
+ elsif self.body.include?(:scene)
129
+ HTTParty.put("http://#{@ip}/api/#{@user}/groups/#{self._group}/action", :body => (self.body.select { |s| s == :scene }).to_json)
130
+ else
131
+ HTTParty.put("http://#{@ip}/api/#{@user}/groups/#{self._group}/action", :body => (self.body).to_json)
132
+ end
133
+
134
+ #restart switch custom dynamic effects after switch is turned back on
135
+ if !self.effect.empty? && !self.effect_thread.last.alive?
136
+ self.effect_thread.each { |t| self.effect_thread.delete t if !t.alive?}
137
+ self.send(self.effect, :start) if !self.effect.nil?
138
+ end
139
+ # Don't keep sending "on" signal to lights as suggested by Hue API
140
+ self.body.delete(:on)
141
+ end
142
+
143
+ def off
144
+ # Stop Switch custom dynamic effects
145
+ if self.effect_state == :start
146
+ self.effect_thread.last.kill
147
+ self.effect_state = :stop
148
+ end
149
+ if self.switch_state != "off"
150
+ self.switch_state = "off"
151
+ self.body[:on] = false
152
+ end
153
+ if self.lights_array.any?
154
+ self.lights_array.each { |l| HTTParty.put("http://#{@ip}/api/#{@user}/lights/#{l}/state", :body => (self.body).to_json) }
155
+ elsif !self.body[:scene].nil?
156
+ (HTTParty.get("http://#{@ip}/api/#{@user}/scenes"))[self.body[:scene]]["lights"].each do |l|
157
+ HTTParty.put("http://#{@ip}/api/#{@user}/lights/#{l}/state", :body => ({:on=>false}).to_json)
158
+ end
159
+ else
160
+ HTTParty.put("http://#{@ip}/api/#{@user}/groups/#{self._group}/action", :body => (self.body).to_json)
161
+ end
162
+ end
163
+
164
+ def schedule(on_or_off = :default, set_time = "tomorrow")
165
+ if set_time.scan(/ seconds?| minutes?| hours?| days?| weeks?/).any?
166
+ set_time = Time.now + ChronicDuration.parse(set_time)
167
+ set_time = set_time.to_s.split(' ')[0..1].join(' ').sub(' ',"T")
168
+ else
169
+ set_time = Chronic.parse(set_time).to_s.split(' ')[0..1].join(' ').sub(' ',"T")
170
+ end
171
+
172
+ if on_or_off != :default
173
+ on_or_off = on_or_off == :on ? true : false
174
+ self.body[:on]=on_or_off
175
+ end
176
+
177
+ if Chronic.parse(set_time) < Time.now
178
+ p "You've scheduled this in the past"
179
+ else
180
+ self.schedule_params = {:name=>"Hue_Switch Alarm",
181
+ :description=>"",
182
+ :localtime=>"#{set_time}",
183
+ :status=>"enabled",
184
+ :autodelete=>true
185
+ }
186
+ if self.lights_array.any?
187
+ self.schedule_params[:name]= "Hue_Switch Alarm Light Set"
188
+ lights_array.each do |l|
189
+ self.schedule_params[:command] = {:address=>"/api/#{@user}/lights/#{l}/state", :method=>"PUT", :body=>self.body}
190
+ self.schedule_ids.push(HTTParty.post("http://#{@ip}/api/#{@user}/schedules", :body => (self.schedule_params).to_json))
191
+ end
192
+ elsif !self.body[:scene].nil?
193
+ self.schedule_params[:command] = {:address=>"/api/#{@user}/groups/#{self._group}/action", :method=>"PUT", :body=>self.body.reject { |s| s == :scene }}
194
+ self.schedule_ids.push(HTTParty.post("http://#{@ip}/api/#{@user}/schedules", :body => (self.schedule_params).to_json))
195
+ else
196
+ self.schedule_params[:command] = {:address=>"/api/#{@user}/groups/#{self._group}/action", :method=>"PUT", :body=>self.body}
197
+ self.schedule_ids.push(HTTParty.post("http://#{@ip}/api/#{@user}/schedules", :body => (self.schedule_params).to_json))
198
+ end
199
+ end
200
+ end
201
+
202
+ def delete_schedules!
203
+ self.schedule_ids.flatten!
204
+ self.schedule_ids.each { |k|
205
+ id = k["success"]["id"] if k.include?("success")
206
+ HTTParty.delete("http://#{@ip}/api/#{@user}/schedules/#{id}")
207
+ }
208
+ self.schedule_ids = []
209
+ end
210
+
211
+ def reset
212
+ self._group = 0
213
+ self.body = {}
214
+ self.schedule_params = nil
215
+ end
216
+
217
+ # Switches can be dynamic
218
+ def colorloop(state = :on)
219
+ state == :on ? self.body[:effect] = "colorloop" : self.body[:effect] = "none"
220
+ self.on
221
+ end
222
+
223
+ def alert(state = :on)
224
+ state == :on ? self.body[:alert] = "select" : self.body[:alert] = "none"
225
+ self.on
226
+ end
227
+
228
+ def long_alert(state = :on)
229
+ state == :on ? self.body[:alert] = "lselect" : self.body[:alert] = "none"
230
+ self.on
231
+ end
232
+
233
+ def random_colors(state = :start, range: 0..65500)
234
+ if state == :stop
235
+ self.effect = ""
236
+ self.effect_thread = []
237
+ self.effect_state = :stop
238
+ else
239
+ self.effect_state = state
240
+ self.effect = __method__.to_s
241
+ self.fade 2
242
+ Thread.new do
243
+ self.effect_thread.push Thread.list.last
244
+ while self.effect_state == :start do
245
+ self.body[:hue] = rand(range)
246
+ sleep (self.body[:transitiontime] / 10) + 0.5
247
+ self.on
248
+ end
249
+ end
250
+ end
251
+ end
252
+ end
@@ -0,0 +1,3 @@
1
+ module HueSwitch
2
+ VERSION = "0.9.0"
3
+ end
metadata ADDED
@@ -0,0 +1,123 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: hue_switch
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.9.0
5
+ platform: ruby
6
+ authors:
7
+ - sarkonovich
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2015-05-27 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: chronic
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 0.10.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 0.10.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: chronic_duration
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: httparty
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 0.13.0
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 0.13.0
55
+ - !ruby/object:Gem::Dependency
56
+ name: bundler
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '1.9'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '1.9'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rake
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '10.0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '10.0'
83
+ description:
84
+ email:
85
+ - sarkonovich@ at gmail dot com
86
+ executables: []
87
+ extensions: []
88
+ extra_rdoc_files: []
89
+ files:
90
+ - ".gitignore"
91
+ - ".travis.yml"
92
+ - Gemfile
93
+ - README.md
94
+ - Rakefile
95
+ - bin/console
96
+ - bin/setup
97
+ - hue_switch.gemspec
98
+ - lib/hue_switch.rb
99
+ - lib/hue_switch/version.rb
100
+ homepage: http://www.github.com/sarkonovich
101
+ licenses: []
102
+ metadata: {}
103
+ post_install_message:
104
+ rdoc_options: []
105
+ require_paths:
106
+ - lib
107
+ required_ruby_version: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - ">="
110
+ - !ruby/object:Gem::Version
111
+ version: 1.9.3
112
+ required_rubygems_version: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - ">="
115
+ - !ruby/object:Gem::Version
116
+ version: '0'
117
+ requirements: []
118
+ rubyforge_project:
119
+ rubygems_version: 2.4.6
120
+ signing_key:
121
+ specification_version: 4
122
+ summary: A gem to easily control Hue lights
123
+ test_files: []