milight 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +9 -0
- data/.travis.yml +5 -0
- data/Gemfile +8 -0
- data/LICENSE +22 -0
- data/README.md +61 -0
- data/Rakefile +10 -0
- data/bin/milight +36 -0
- data/lib/milight.rb +7 -0
- data/lib/milight/bridge_box.rb +168 -0
- data/lib/milight/bulb.rb +179 -0
- data/lib/milight/color.rb +21 -0
- data/lib/milight/command.rb +49 -0
- data/lib/milight/util.rb +21 -0
- data/lib/milight/version.rb +3 -0
- data/milight.gemspec +25 -0
- data/sample/light.rb +32 -0
- data/sample/wakeup_light.rb +41 -0
- metadata +104 -0
checksums.yaml
ADDED
@@ -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
|
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
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
|
+
|
data/README.md
ADDED
@@ -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
|
+
|
data/Rakefile
ADDED
data/bin/milight
ADDED
@@ -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
|
+
|
data/lib/milight.rb
ADDED
@@ -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
|
+
|
data/lib/milight/bulb.rb
ADDED
@@ -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
|
data/lib/milight/util.rb
ADDED
@@ -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
|
+
|
data/milight.gemspec
ADDED
@@ -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
|
data/sample/light.rb
ADDED
@@ -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: []
|