milight 0.2.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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: e3e8344aaa8ad7deb994a84f912d00f7ff12cf25
4
+ data.tar.gz: 50464a893318e56f13339df22857df680e7834f3
5
+ SHA512:
6
+ metadata.gz: ec1ff3073876baa5deabd457ab963901b09452067e64263d48df8ec378258d5ad684dce52d7c0e69f991f6e61a7f20852f84d337cb045388888b97f1148b689f
7
+ data.tar.gz: 569487c0539325798cf7124038d88ef9df7a157b736ff2baf1930a10bc6bb14e78cc8b0ab4b0488e5e373d33cef76ad9231ad8801020d4d3383c529fa1797201
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
@@ -0,0 +1,5 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.2.*
4
+ before_install: gem install bundler -v 1.11.2
5
+ script: bundle exec rake test
data/Gemfile ADDED
@@ -0,0 +1,8 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in ruby-milight.gemspec
4
+ gemspec
5
+
6
+ group :test do
7
+ gem 'coveralls', require: false
8
+ end
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2015 Ippei Kato
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
@@ -0,0 +1,61 @@
1
+ # Milight
2
+
3
+ [![Build Status](https://travis-ci.org/beco-ippei/ruby-milight.svg?branch=master)](https://travis-ci.org/beco-ippei/ruby-milight)
4
+ [![Coverage Status](https://coveralls.io/repos/github/beco-ippei/ruby-milight/badge.svg)](https://coveralls.io/github/beco-ippei/ruby-milight)
5
+
6
+ A ruby wrapper project for milight api.
7
+
8
+ controller ruby-api for milight or limitless-led
9
+ (milight and limitless-led and easy-bulb is
10
+ same bridge-box controllable products)
11
+
12
+ ## API Document
13
+ http://www.limitlessled.com/dev/
14
+
15
+ ## Installation
16
+
17
+ Add this line to your application's Gemfile:
18
+
19
+ ```ruby
20
+ gem 'milight'
21
+ ```
22
+
23
+ And then execute:
24
+
25
+ $ bundle
26
+
27
+ Or install it yourself as:
28
+
29
+ $ gem install milight
30
+
31
+
32
+ # components
33
+ * local controller (working on LAN)
34
+ * [may be not] gateway server (working on Internet)
35
+
36
+ components messaging each other.
37
+ use web-socket ??
38
+
39
+ ---
40
+
41
+ # TODO
42
+ setup
43
+ ---
44
+ * ?) connect bridge-box and setup wifi config
45
+ or configure by Appli
46
+ * ~~get bridge-box IP-Address (from LAN)~~
47
+ * configure this app (make or overwrite config file ?)
48
+
49
+ boot local-controller / env
50
+ ---
51
+ * load config
52
+ * get bridge-box network segment (24bit)
53
+ * server url
54
+ * bulb controller
55
+ * lib/bulb.rb
56
+ * and tests
57
+ * sample app
58
+ * controll by groups
59
+
60
+ ... writing.
61
+
@@ -0,0 +1,10 @@
1
+ require "bundler/gem_tasks"
2
+ require "rake/testtask"
3
+
4
+ Rake::TestTask.new(:test) do |t|
5
+ t.libs << "test"
6
+ t.libs << "lib"
7
+ t.test_files = FileList['test/**/*_test.rb']
8
+ end
9
+
10
+ task :default => :spec
@@ -0,0 +1,36 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
4
+
5
+ SETUP = %w[setup]
6
+ CONSOLE = %w[console c]
7
+ all_cmd = SETUP + CONSOLE
8
+
9
+ cmd = ARGV[0]
10
+ unless cmd
11
+ puts <<-DESC
12
+ sub-command must set
13
+ valid commands are #{all_cmd.join ','}
14
+ DESC
15
+ exit
16
+ end
17
+
18
+ require 'milight'
19
+
20
+ #TODO add group to bulb
21
+ case cmd.downcase.to_sym
22
+ when :setup
23
+ require 'milight/bridge_box'
24
+ Milight::BridgeBox.setup
25
+
26
+ when :console, :c
27
+ require "irb"
28
+ IRB.start
29
+
30
+ else
31
+ puts <<-DESC
32
+ sub-command '#{cmd}' is invalid.
33
+ valid commands are #{all_cmd.join ','}
34
+ DESC
35
+ end
36
+
@@ -0,0 +1,7 @@
1
+ require "milight/version"
2
+
3
+ require "milight/command"
4
+ require "milight/color"
5
+ require "milight/bulb"
6
+ require "milight/util"
7
+
@@ -0,0 +1,168 @@
1
+ require 'milight'
2
+ require 'readline'
3
+ require "socket"
4
+
5
+ module Milight::BridgeBox
6
+ MILIGHT_WIFI = /^10\.10\.100\.[0-9]+$/
7
+ SERVER_IP = '10.10.100.254'
8
+ RECEIVE_IP = "0.0.0.0"
9
+ PORT = '48899'
10
+
11
+ def self.setup
12
+ puts "-- Please connect wifi 'milight_XXXXXXX'."
13
+
14
+ if self.wait_connection true
15
+ puts '... milight connected.'
16
+ else
17
+ puts <<DESC
18
+ milight wifi connection timeout (1min)
19
+ if milight wifi not found, initialize your controller box.
20
+ DESC
21
+ exit 1
22
+ end
23
+
24
+ sock = self.socket
25
+
26
+ t1 = Thread.new do
27
+ self.wait_wscan_results
28
+ end
29
+
30
+ sleep 1
31
+ puts '-- send command: WSCAN ....'
32
+ sock.command "Link_Wi-Fi"
33
+ sock.command "+ok"
34
+ sock.command "AT+WSCAN\r"
35
+
36
+ t1.join
37
+
38
+ wlans = t1.value.split "\n"
39
+
40
+ wlans.shift # ignore header
41
+ ssids = wlans.map do |line|
42
+ ch, ssid, _, sec, _ = line.split ','
43
+ if ssid.is_a?(String) && ssid.length > 1
44
+ {ch: ch, ssid: ssid, sec: sec}
45
+ end
46
+ end.compact
47
+
48
+ ssid = self.choice_ssid ssids
49
+ puts "-- set wifi SSID : '#{ssid[:ssid]}'"
50
+ sock.command "AT+WSSSID=#{ssid[:ssid]}\r"
51
+
52
+ key = self.security_key
53
+ puts "-- set wifi security key : '#{key}'"
54
+ sock.command "AT+WSKEY=WPA2PSK,AES,#{key}\r"
55
+
56
+ sock.command "AT+WMODE=STA\r"
57
+ sock.command "AT+Z\r"
58
+ sock.command "AT+Q\r"
59
+
60
+ sock.close
61
+
62
+
63
+ if self.wait_connection false
64
+ puts <<DESC
65
+ ... miligt wifi disconnected.
66
+ check your controller box led!
67
+
68
+ DESC
69
+ else
70
+ puts ' milight wifi connection still connected'
71
+ exit 1
72
+ end
73
+ end
74
+
75
+ def self.wait_connection(milight = true)
76
+ 20.times do
77
+ sleep 3
78
+ if ipaddr = Milight::Util.current_ipaddr
79
+ print '.'
80
+ else
81
+ print '-'
82
+ end
83
+
84
+ if self.milight_wifi?(ipaddr) == milight
85
+ return true
86
+ end
87
+ end
88
+ false
89
+ end
90
+
91
+ def self.milight_wifi? ipaddr
92
+ !(ipaddr && MILIGHT_WIFI =~ ipaddr).nil?
93
+ end
94
+
95
+ def self.socket
96
+ sock = UDPSocket.open
97
+ sock.setsockopt(
98
+ Socket::SOL_SOCKET,
99
+ Socket::SO_BROADCAST,
100
+ 1
101
+ )
102
+ def sock.command msg
103
+ self.send msg, 0, SERVER_IP, PORT
104
+ end
105
+ sock
106
+ end
107
+
108
+ def self.wait_wscan_results
109
+ puts '-- waiting receive response: WSCAN ....'
110
+ rsock = UDPSocket.new
111
+ rsock.bind(RECEIVE_IP, PORT)
112
+ string = nil
113
+
114
+ sel = IO::select([rsock])
115
+ if sel != nil
116
+ sel[0].each do |s|
117
+ data = s.recvfrom_nonblock(65535)
118
+ string = data[0].chomp!
119
+ end
120
+ else
121
+ puts '-- not received ....'
122
+ exit 1
123
+ end
124
+ rsock.close
125
+ string.gsub(/\+ok=\n/, '')
126
+ end
127
+
128
+ def self.choice_ssid ssids
129
+ puts '', '-'*20
130
+ puts " no: 'ssid' (security types)"
131
+ ssids.each.with_index do |s, idx|
132
+ num = '%#2d' % (idx+1)
133
+ puts " #{num}: '#{s[:ssid]}' (#{s[:sec]})"
134
+ end
135
+ puts '-'*20, ''
136
+ puts <<-DESC
137
+ Choise your SSID(no).
138
+ but if your Access point not found, restart app
139
+ DESC
140
+
141
+ while true
142
+ msg = ">> input your SSID no(1-#{ssids.size-1}) > "
143
+ num = Readline.readline(msg).chomp.to_i
144
+ if num == 0
145
+ next # 0 or nil (not a number)
146
+ elsif !(1..ssids.size).cover? num
147
+ puts <<-MSG
148
+ invalid number : '#{num}'
149
+ exit.
150
+ MSG
151
+ exit 0
152
+ end
153
+ return ssids[num-1]
154
+ end
155
+ end
156
+
157
+ def self.security_key
158
+ while true
159
+ msg = '>> Input security key > '
160
+ key = Readline.readline(msg).chomp
161
+ if key != ""
162
+ return key
163
+ end
164
+ end
165
+ end
166
+
167
+ end
168
+
@@ -0,0 +1,179 @@
1
+ require 'socket'
2
+ require 'ipaddr'
3
+
4
+ module Milight
5
+ class Bulb
6
+ def initialize(group: :all, ip: nil, port: 8899)
7
+ self.group = group
8
+ self.ip = ip
9
+ @port = port
10
+
11
+ @debugger = lambda {|_| }
12
+ end
13
+
14
+ #TODO: move to anywhere...
15
+ def debugger=(type)
16
+ @debugger = case type
17
+ when :puts
18
+ lambda {|msg|
19
+ puts " - debug :: #{msg}"
20
+ }
21
+ else
22
+ lambda {|_| }
23
+ end
24
+ debug "set debug - #{type}"
25
+ end
26
+
27
+ def debug(msg)
28
+ @debugger.call msg
29
+ end
30
+
31
+ def on
32
+ command Command::LED_ON[@group]
33
+ end
34
+
35
+ def disco(attr = nil)
36
+ case attr && attr.to_sym
37
+ when nil
38
+ command Command::DISCO_MODE
39
+ when :faster, :fast
40
+ command Command::DISCO_SPEED_FASTER
41
+ when :slower, :slow
42
+ command Command::DISCO_SPEED_SLOWER
43
+ else
44
+ debug "invalid disco attribute: '#{attr}'"
45
+ end
46
+ end
47
+
48
+ def off
49
+ command Command::LED_OFF[@group]
50
+ end
51
+
52
+ # white-command 100ms followed by 'on-command'
53
+ def white
54
+ self.on
55
+ command Command::WHITE[@group]
56
+ end
57
+
58
+ # night-command 100ms followed by 'off-command'
59
+ def night
60
+ self.off
61
+ command Command::NIGHT[@group]
62
+ end
63
+
64
+ # for colors
65
+ Color.constants.each do |color|
66
+ color_name = color.downcase
67
+ define_method color_name.to_sym do
68
+ color_code = defined_color color
69
+ self.on
70
+ command Command::SET_COLOR, color_code
71
+ end
72
+ end
73
+
74
+ def color_value=(val)
75
+ if code = color_code(val)
76
+ self.on
77
+ command Command::SET_COLOR, code
78
+ else
79
+ debug "invalid color value '#{val}'"
80
+ end
81
+ end
82
+
83
+ def bright(persent)
84
+ if val = brightness(persent.to_i)
85
+ self.on
86
+ command Command::BRIGHTENESS, val
87
+ else
88
+ debug "invalid persent value '#{persent}'"
89
+ end
90
+ end
91
+
92
+ def full_bright
93
+ self.bright 50
94
+ end
95
+
96
+ def dark
97
+ self.bright 0
98
+ end
99
+
100
+ private
101
+
102
+ def ip=(ipaddr)
103
+ unless ipaddr
104
+ raise "ip is not allowed nil"
105
+ end
106
+ IPAddr.new ipaddr # just validate
107
+ @ipaddr = ipaddr
108
+ end
109
+
110
+ def group=(group)
111
+ if group == :all
112
+ @group = :all
113
+ elsif (1..5).cover? group
114
+ @group = "group#{group}".to_sym
115
+ else
116
+ raise 'invalid group. use :all or 1..5'
117
+ end
118
+ end
119
+
120
+ def brightness(persent)
121
+ if (0..100).cover? persent
122
+ sprintf(
123
+ '%02d',
124
+ 2 + 25 * persent.to_i / 100
125
+ )
126
+ end
127
+ end
128
+
129
+ def defined_color(method)
130
+ name = method.upcase.to_sym
131
+ if Color.constants.include? name
132
+ Color.const_get(name)
133
+ else
134
+ nil
135
+ end
136
+ end
137
+
138
+ # parse color code ("00" .. "ff")
139
+ # valid color-value is 0..255
140
+ def color_code(val)
141
+ if val.is_a? String
142
+ code = val
143
+ val = code.hex
144
+ val = -1 if val == 0 && code != '00'
145
+ elsif val.is_a? Fixnum
146
+ code = val
147
+ val = val.to_i
148
+ code = '%02x' % val
149
+ else
150
+ return nil
151
+ end
152
+
153
+ if (0..255).cover? val
154
+ code
155
+ else
156
+ nil
157
+ end
158
+ end
159
+
160
+ def command(cmd, value = '00')
161
+ debug "cmd : #{cmd} / #{value}"
162
+ msg = message cmd, value
163
+
164
+ #TODO: initialize first ?
165
+ sock = UDPSocket.open
166
+ sock.setsockopt(
167
+ Socket::SOL_SOCKET,
168
+ Socket::SO_BROADCAST,
169
+ 1
170
+ )
171
+ sock.send(msg, 0, @ipaddr, @port)
172
+ end
173
+
174
+ def message(cmd, value)
175
+ [cmd, value, "55"].map(&:to_s)
176
+ .map(&:hex).pack "C*"
177
+ end
178
+ end
179
+ end
@@ -0,0 +1,21 @@
1
+ module Milight
2
+ module Color
3
+ VIOLET = '00'
4
+ ROYAL_BLUE = '10'
5
+ BLUE = ROYAL_BLUE # alias
6
+ BABY_BLUE = '20'
7
+ AQUA = '30'
8
+ MINT = '40'
9
+ SEAFOAM_GREEN = '50'
10
+ GREEN = '60'
11
+ LIME_GREEN = '70'
12
+ YELLOW = '80'
13
+ YELLOW_ORANGE = '90'
14
+ ORANGE = 'a0'
15
+ RED = 'b0'
16
+ PINK = 'c0'
17
+ FUSIA = 'd0'
18
+ LILAC = 'e0'
19
+ LAVENDAR = 'f0'
20
+ end
21
+ end
@@ -0,0 +1,49 @@
1
+ module Milight
2
+ module Command
3
+ SET_COLOR = '40'
4
+
5
+ LED_ON = {
6
+ all: '42',
7
+ group1: '45',
8
+ group2: '47',
9
+ group3: '49',
10
+ group4: '4B',
11
+ }
12
+
13
+ LED_OFF = {
14
+ all: '41',
15
+ group1: '46',
16
+ group2: '48',
17
+ group3: '4A',
18
+ group4: '4C',
19
+ }
20
+
21
+ DISCO_SPEED_SLOWER = '43'
22
+ DISCO_SPEED_FASTER = '44'
23
+ DISCO_MODE = '4D'
24
+ DISCO_MODE_NEXT = '27'
25
+ DISCO_MODE_PREVIOUS = '28'
26
+
27
+ #TODO: not RGB?
28
+ WARM_WHITE_INCREASE = '3E'
29
+ COOL_WHITE_INCREASE = '3F'
30
+
31
+ BRIGHTENESS = '4E'
32
+
33
+ NIGHT = {
34
+ all: 'C1',
35
+ group1: 'C6',
36
+ group2: 'C8',
37
+ group3: 'CA',
38
+ group4: 'CC',
39
+ }
40
+
41
+ WHITE = {
42
+ all: 'C2',
43
+ group1: 'C5',
44
+ group2: 'C7',
45
+ group3: 'C9',
46
+ group4: 'CB',
47
+ }
48
+ end
49
+ end
@@ -0,0 +1,21 @@
1
+ module Milight
2
+ module Util
3
+ def self.current_ipaddr
4
+ matched = /inet\ addr:([0-9\.]*)/.match wlan_config
5
+ matched[1] if matched
6
+ end
7
+
8
+ def self.broadcast_addr
9
+ matched = /Bcast:([0-9\.]*)/.match wlan_config
10
+ matched[1] if matched
11
+ end
12
+
13
+ private
14
+
15
+ #TODO: modularize for env/os.
16
+ def self.wlan_config
17
+ %x[LANG=C ifconfig wlan]
18
+ end
19
+ end
20
+ end
21
+
@@ -0,0 +1,3 @@
1
+ module Milight
2
+ VERSION = "0.2.0"
3
+ end
@@ -0,0 +1,25 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'milight/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "milight"
8
+ spec.version = Milight::VERSION
9
+ spec.authors = ["beco-ippei"]
10
+ spec.email = ["beco.ippei@gmail.com"]
11
+
12
+ spec.summary = %q{A ruby controller for Mi-Light LED bulb.}
13
+ spec.description = %q{}
14
+ spec.homepage = "https://github.com/beco-ippei/ruby-milight"
15
+ spec.license = "MIT"
16
+
17
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
18
+ spec.bindir = "bin"
19
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
20
+ spec.require_paths = ["lib"]
21
+
22
+ spec.add_development_dependency "bundler", "~> 1.11"
23
+ spec.add_development_dependency "rake", "~> 10.0"
24
+ spec.add_development_dependency "minitest", "~> 5.0"
25
+ end
@@ -0,0 +1,32 @@
1
+ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
2
+
3
+ require 'milight'
4
+
5
+ ipaddr = ENV['IPADDR']
6
+
7
+ group = (g = ARGV.shift) == 'all' ? :all : g.to_i
8
+ bulb = Milight::Bulb.new ip: ipaddr, group: group
9
+
10
+ cmd = ARGV.shift
11
+ val = ARGV.shift
12
+
13
+ case cmd.downcase
14
+ when 'on'
15
+ bulb.on
16
+ when 'off'
17
+ bulb.off
18
+ when 'color'
19
+ bulb.send val.to_sym
20
+ when 'color-list'
21
+ puts Milight::Color.constants
22
+ .map(&:downcase).join ', '
23
+ when 'dark'
24
+ bulb.dark
25
+ when 'bright'
26
+ bulb.bright val.to_i
27
+ when 'night'
28
+ bulb.night
29
+ when 'disco'
30
+ bulb.disco val
31
+ end
32
+
@@ -0,0 +1,41 @@
1
+ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
2
+
3
+ require 'milight'
4
+
5
+ ipaddr = ENV['IPADDR']
6
+ interval = 3 * 60 # 3min
7
+
8
+ bulb = Milight::Bulb.new ip: ipaddr
9
+
10
+ if ARGV[0] == 'prepare'
11
+ puts 'prepare for wakeup-light'
12
+ [:on, :dark, :lime_green, :off].each do |cmd|
13
+ bulb.send(cmd)
14
+ sleep 2
15
+ end
16
+ exit
17
+ end
18
+
19
+ # light on (night-mode)
20
+ [
21
+ [:night],
22
+ [:on, :dark, :lime_green],
23
+ [[:bright, 10]],
24
+ [[:bright, 20]],
25
+ [:white],
26
+ [[:bright, 30]],
27
+ [:full_bright],
28
+ [:disco],
29
+ ].each do |commands|
30
+ commands.each do |cmd|
31
+ bulb.send(*cmd)
32
+ sleep 1.5
33
+ end
34
+ sleep interval
35
+ end
36
+
37
+ sleep 10 * 60 # 10min
38
+ bulb.dark
39
+ sleep 2
40
+ bulb.off
41
+
metadata ADDED
@@ -0,0 +1,104 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: milight
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
5
+ platform: ruby
6
+ authors:
7
+ - beco-ippei
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-02-19 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.11'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.11'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: minitest
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '5.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '5.0'
55
+ description: ''
56
+ email:
57
+ - beco.ippei@gmail.com
58
+ executables:
59
+ - milight
60
+ extensions: []
61
+ extra_rdoc_files: []
62
+ files:
63
+ - ".gitignore"
64
+ - ".travis.yml"
65
+ - Gemfile
66
+ - LICENSE
67
+ - README.md
68
+ - Rakefile
69
+ - bin/milight
70
+ - lib/milight.rb
71
+ - lib/milight/bridge_box.rb
72
+ - lib/milight/bulb.rb
73
+ - lib/milight/color.rb
74
+ - lib/milight/command.rb
75
+ - lib/milight/util.rb
76
+ - lib/milight/version.rb
77
+ - milight.gemspec
78
+ - sample/light.rb
79
+ - sample/wakeup_light.rb
80
+ homepage: https://github.com/beco-ippei/ruby-milight
81
+ licenses:
82
+ - MIT
83
+ metadata: {}
84
+ post_install_message:
85
+ rdoc_options: []
86
+ require_paths:
87
+ - lib
88
+ required_ruby_version: !ruby/object:Gem::Requirement
89
+ requirements:
90
+ - - ">="
91
+ - !ruby/object:Gem::Version
92
+ version: '0'
93
+ required_rubygems_version: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - ">="
96
+ - !ruby/object:Gem::Version
97
+ version: '0'
98
+ requirements: []
99
+ rubyforge_project:
100
+ rubygems_version: 2.5.1
101
+ signing_key:
102
+ specification_version: 4
103
+ summary: A ruby controller for Mi-Light LED bulb.
104
+ test_files: []