wemote 0.2.2 → 0.2.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/wemote.rb +2 -0
- data/lib/wemote/collection/insight.rb +12 -0
- data/lib/wemote/insight.rb +90 -0
- data/lib/wemote/switch.rb +39 -30
- data/lib/wemote/version.rb +1 -1
- data/lib/wemote/xml.rb +7 -1
- data/wemote.gemspec +3 -0
- data/xml/get_binary_state.xml +1 -2
- data/xml/get_insight_params.xml +6 -0
- data/xml/set_binary_state.xml +1 -2
- metadata +27 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 50907f96c202b14aff7fbac722c9133a3c4860f5
|
4
|
+
data.tar.gz: 2fa839d4ce9819d5223f078b08464906556bcfb1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 352264a9e37d2d4e3e54e1925b751e2d37adb277cfd7e6b818864afd3315fa0f332bd836242f5d2f7e8c1fecc6571761c214eac4126c9c6f1143e37236a8047f
|
7
|
+
data.tar.gz: c7a62b670905ff95356342c2886d76f61cc21e2384c0da60abff32fea4fb267b503faa7ac8482d208fb66151cf5e91ebf9523a6f2aac787addde5a39c3769c1e
|
data/lib/wemote.rb
CHANGED
@@ -2,7 +2,9 @@ require_relative './wemote/version'
|
|
2
2
|
|
3
3
|
module Wemote
|
4
4
|
require_relative './wemote/collection/switch'
|
5
|
+
require_relative './wemote/collection/insight'
|
5
6
|
require_relative './wemote/switch'
|
7
|
+
require_relative './wemote/insight'
|
6
8
|
require_relative './wemote/client'
|
7
9
|
require_relative './wemote/xml'
|
8
10
|
|
@@ -0,0 +1,90 @@
|
|
1
|
+
require 'socket'
|
2
|
+
require 'ipaddr'
|
3
|
+
require 'timeout'
|
4
|
+
require 'ssdp'
|
5
|
+
|
6
|
+
module Wemote
|
7
|
+
|
8
|
+
# This class encapsulates an individual Wemo Insight. It provides methods for
|
9
|
+
# getting and setting the insight's state, as well as a {#toggle!} method for
|
10
|
+
# convenience. Finally, it provides the {#poll} method, which accepts a block
|
11
|
+
# to be executed any time the insight changes state.
|
12
|
+
class Insight < Switch
|
13
|
+
|
14
|
+
GET_HEADERS_POWER = {
|
15
|
+
"SOAPACTION" => '"urn:Belkin:service:insight:1#GetInsightParams"',
|
16
|
+
"Content-type" => 'text/xml; charset="utf-8"'
|
17
|
+
}
|
18
|
+
|
19
|
+
class << self
|
20
|
+
|
21
|
+
def device_type
|
22
|
+
'urn:Belkin:device:insight:1'
|
23
|
+
end
|
24
|
+
|
25
|
+
# Returns all Insight detected on the local network
|
26
|
+
#
|
27
|
+
# @param [Boolean] refresh Refresh and redetect Insight
|
28
|
+
# @return [Array] all Insight on the network
|
29
|
+
def all(refresh=false)
|
30
|
+
@insights = nil if refresh
|
31
|
+
@insights ||= Wemote::Collection::Insight.new(discover)
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
# Turn the Insight on or off, based on its current state
|
37
|
+
def toggle!
|
38
|
+
on? or standby? ? off! : on!;
|
39
|
+
end
|
40
|
+
|
41
|
+
# Return whether the Insight is standby
|
42
|
+
#
|
43
|
+
# @return [Boolean]
|
44
|
+
def standby?
|
45
|
+
get_state == :standby;
|
46
|
+
end
|
47
|
+
|
48
|
+
def power
|
49
|
+
get_insight_params()[:power]
|
50
|
+
end
|
51
|
+
|
52
|
+
def energy
|
53
|
+
get_insight_params()[:energy]
|
54
|
+
end
|
55
|
+
|
56
|
+
def on_today
|
57
|
+
get_insight_params()[:on_today]
|
58
|
+
end
|
59
|
+
|
60
|
+
private
|
61
|
+
|
62
|
+
def get_state
|
63
|
+
case get_binary_state()
|
64
|
+
when '0'
|
65
|
+
:off
|
66
|
+
when '1'
|
67
|
+
:on
|
68
|
+
when '8'
|
69
|
+
:standby
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def get_insight_params
|
74
|
+
response = begin
|
75
|
+
client.post("http://#{@host}:#{@port}/upnp/control/insight1",Wemote::XML.get_insight_params,GET_HEADERS_POWER)
|
76
|
+
rescue Exception
|
77
|
+
client.post("http://#{@host}:#{@port}/upnp/control/insight1",Wemote::XML.get_insight_params,GET_HEADERS_POWER)
|
78
|
+
end
|
79
|
+
params = response.body.match(/<InsightParams>(.*)<\/InsightParams>/)[1].split('|')
|
80
|
+
{
|
81
|
+
value: (params[0].to_i == 0 ? :off : :on),
|
82
|
+
energy: (params[8].to_i / 60000000.0).ceil,
|
83
|
+
power: (params[7].to_i / 1000.0).round,
|
84
|
+
on_today: (params[3].to_i / 60.0).floor
|
85
|
+
}
|
86
|
+
end
|
87
|
+
|
88
|
+
|
89
|
+
end
|
90
|
+
end
|
data/lib/wemote/switch.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'socket'
|
2
2
|
require 'ipaddr'
|
3
3
|
require 'timeout'
|
4
|
+
require 'ssdp'
|
4
5
|
|
5
6
|
module Wemote
|
6
7
|
|
@@ -10,8 +11,6 @@ module Wemote
|
|
10
11
|
# to be executed any time the switch changes state.
|
11
12
|
class Switch
|
12
13
|
|
13
|
-
GOOGLE_IP = "64.233.187.99"
|
14
|
-
|
15
14
|
GET_HEADERS = {
|
16
15
|
"SOAPACTION" => '"urn:Belkin:service:basicevent:1#GetBinaryState"',
|
17
16
|
"Content-type" => 'text/xml; charset="utf-8"'
|
@@ -23,6 +22,11 @@ module Wemote
|
|
23
22
|
}
|
24
23
|
|
25
24
|
class << self
|
25
|
+
|
26
|
+
def device_type
|
27
|
+
'urn:Belkin:device:controllee:1'
|
28
|
+
end
|
29
|
+
|
26
30
|
# Returns all Switches detected on the local network
|
27
31
|
#
|
28
32
|
# @param [Boolean] refresh Refresh and redetect Switches
|
@@ -40,14 +44,15 @@ module Wemote
|
|
40
44
|
all.detect{|s|s.name == name}
|
41
45
|
end
|
42
46
|
|
43
|
-
|
47
|
+
protected
|
44
48
|
|
45
49
|
def discover
|
46
|
-
|
47
|
-
|
48
|
-
self.new(
|
49
|
-
end
|
50
|
+
finder = SSDP::Consumer.new timeout: 3, first_only: false
|
51
|
+
finder.search(service: self.device_type).map do |device|
|
52
|
+
self.new(device[:address], device[:params]['LOCATION'].match(/:([0-9]{1,5})\//)[1])
|
53
|
+
end
|
50
54
|
end
|
55
|
+
|
51
56
|
end
|
52
57
|
|
53
58
|
attr_accessor :name
|
@@ -57,24 +62,38 @@ module Wemote
|
|
57
62
|
set_meta
|
58
63
|
end
|
59
64
|
|
65
|
+
def device_type
|
66
|
+
'urn:Belkin:device:controllee:1'
|
67
|
+
end
|
68
|
+
|
60
69
|
# Turn the Switch on or off, based on its current state
|
61
|
-
def toggle
|
70
|
+
def toggle!
|
71
|
+
on? ? off! : on!
|
72
|
+
end
|
62
73
|
|
63
74
|
# Turn the Switch off
|
64
|
-
def off
|
75
|
+
def off!
|
76
|
+
set_state(0)
|
77
|
+
end
|
65
78
|
|
66
79
|
# Turn the Switch on
|
67
|
-
def on
|
80
|
+
def on!
|
81
|
+
set_state(1)
|
82
|
+
end
|
68
83
|
|
69
84
|
# Return whether the Switch is off
|
70
85
|
#
|
71
86
|
# @return [Boolean]
|
72
|
-
def off
|
87
|
+
def off?
|
88
|
+
get_state == :off
|
89
|
+
end
|
73
90
|
|
74
91
|
# Return whether the Switch is on
|
75
92
|
#
|
76
93
|
# @return [Boolean]
|
77
|
-
def on
|
94
|
+
def on?
|
95
|
+
get_state == :on
|
96
|
+
end
|
78
97
|
|
79
98
|
# Monitors the state of the Switch via polling, and yields to the block
|
80
99
|
# given with the updated state.
|
@@ -111,15 +130,19 @@ module Wemote
|
|
111
130
|
async ? poller : poller.join
|
112
131
|
end
|
113
132
|
|
114
|
-
|
133
|
+
protected
|
115
134
|
|
116
135
|
def get_state
|
136
|
+
self.get_binary_state() == '1' ? :on : :off
|
137
|
+
end
|
138
|
+
|
139
|
+
def get_binary_state
|
117
140
|
response = begin
|
118
141
|
client.post("http://#{@host}:#{@port}/upnp/control/basicevent1",Wemote::XML.get_binary_state,GET_HEADERS)
|
119
142
|
rescue Exception
|
120
143
|
client.post("http://#{@host}:#{@port}/upnp/control/basicevent1",Wemote::XML.get_binary_state,GET_HEADERS)
|
121
144
|
end
|
122
|
-
response.body.match(/<BinaryState>(\d)<\/BinaryState>/)[1]
|
145
|
+
response.body.match(/<BinaryState>(\d)<\/BinaryState>/)[1]
|
123
146
|
end
|
124
147
|
|
125
148
|
def set_state(state)
|
@@ -135,22 +158,8 @@ module Wemote
|
|
135
158
|
end
|
136
159
|
|
137
160
|
def set_meta
|
138
|
-
|
139
|
-
|
140
|
-
@name = response.body.match(/<friendlyName>([^<]+)<\/friendlyName>/)[1]
|
141
|
-
else
|
142
|
-
for port in 49152..49156
|
143
|
-
begin
|
144
|
-
response = nil
|
145
|
-
Timeout::timeout(1){ response = client.get("http://#{@host}:#{port}/setup.xml") }
|
146
|
-
@name = response.body.match(/<friendlyName>([^<]+)<\/friendlyName>/)[1]
|
147
|
-
@port = port
|
148
|
-
break
|
149
|
-
rescue Exception
|
150
|
-
end
|
151
|
-
end
|
152
|
-
end
|
161
|
+
response = client.get("http://#{@host}:#{@port}/setup.xml")
|
162
|
+
@name = response.body.match(/<friendlyName>([^<]+)<\/friendlyName>/)[1]
|
153
163
|
end
|
154
|
-
|
155
164
|
end
|
156
165
|
end
|
data/lib/wemote/version.rb
CHANGED
data/lib/wemote/xml.rb
CHANGED
@@ -4,7 +4,8 @@ module Wemote
|
|
4
4
|
xml_path = File.join(File.dirname(__FILE__),'/../../xml')
|
5
5
|
TEMPLATES = {
|
6
6
|
get_binary_state: File.read(File.join(xml_path,'get_binary_state.xml')),
|
7
|
-
set_binary_state: File.read(File.join(xml_path,'set_binary_state.xml'))
|
7
|
+
set_binary_state: File.read(File.join(xml_path,'set_binary_state.xml')),
|
8
|
+
get_insight_params: File.read(File.join(xml_path,'get_insight_params.xml'))
|
8
9
|
}
|
9
10
|
|
10
11
|
# @return [String] The required XML body for a Wemo binary state request
|
@@ -18,6 +19,11 @@ module Wemote
|
|
18
19
|
TEMPLATES[:set_binary_state].gsub("{{1}}",state.to_s)
|
19
20
|
end
|
20
21
|
|
22
|
+
def get_insight_params
|
23
|
+
TEMPLATES[:get_insight_params]
|
24
|
+
end
|
25
|
+
|
26
|
+
|
21
27
|
end
|
22
28
|
end
|
23
29
|
end
|
data/wemote.gemspec
CHANGED
@@ -18,4 +18,7 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
19
19
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
20
20
|
spec.require_paths = ["lib"]
|
21
|
+
|
22
|
+
spec.add_dependency 'ssdp', '~> 1.1', '>= 1.1.6'
|
23
|
+
|
21
24
|
end
|
data/xml/get_binary_state.xml
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
<?xml version="1.0" encoding="utf-8"?>
|
2
|
-
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"
|
3
|
-
s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
|
2
|
+
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
|
4
3
|
<s:Body>
|
5
4
|
<u:GetBinaryState xmlns:u="urn:Belkin:service:basicevent:1"/>
|
6
5
|
</s:Body>
|
@@ -0,0 +1,6 @@
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
2
|
+
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
|
3
|
+
<s:Body>
|
4
|
+
<u:GetInsightParams xmlns:u="urn:Belkin:service:insight:1"></u:GetInsightParams>
|
5
|
+
</s:Body>
|
6
|
+
</s:Envelope>
|
data/xml/set_binary_state.xml
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
<?xml version="1.0" encoding="utf-8"?>
|
2
|
-
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"
|
3
|
-
s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
|
2
|
+
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
|
4
3
|
<s:Body>
|
5
4
|
<u:SetBinaryState xmlns:u="urn:Belkin:service:basicevent:1">
|
6
5
|
<BinaryState>{{1}}</BinaryState>
|
metadata
CHANGED
@@ -1,15 +1,35 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: wemote
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kevin Gisi
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
12
|
-
dependencies:
|
11
|
+
date: 2018-03-01 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: ssdp
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.1'
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 1.1.6
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - "~>"
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '1.1'
|
30
|
+
- - ">="
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 1.1.6
|
13
33
|
description: Wemote is a Ruby-agnostic gem for Wemo light switches
|
14
34
|
email:
|
15
35
|
- kevin@kevingisi.com
|
@@ -25,7 +45,9 @@ files:
|
|
25
45
|
- Rakefile
|
26
46
|
- lib/wemote.rb
|
27
47
|
- lib/wemote/client.rb
|
48
|
+
- lib/wemote/collection/insight.rb
|
28
49
|
- lib/wemote/collection/switch.rb
|
50
|
+
- lib/wemote/insight.rb
|
29
51
|
- lib/wemote/switch.rb
|
30
52
|
- lib/wemote/version.rb
|
31
53
|
- lib/wemote/xml.rb
|
@@ -33,6 +55,7 @@ files:
|
|
33
55
|
- spec/wemote/switch_spec.rb
|
34
56
|
- wemote.gemspec
|
35
57
|
- xml/get_binary_state.xml
|
58
|
+
- xml/get_insight_params.xml
|
36
59
|
- xml/set_binary_state.xml
|
37
60
|
homepage: https://github.com/gisikw/wemote
|
38
61
|
licenses:
|
@@ -54,11 +77,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
54
77
|
version: '0'
|
55
78
|
requirements: []
|
56
79
|
rubyforge_project:
|
57
|
-
rubygems_version: 2.
|
80
|
+
rubygems_version: 2.6.14
|
58
81
|
signing_key:
|
59
82
|
specification_version: 4
|
60
83
|
summary: Wemote is a Ruby-agnostic gem for Wemo light switches
|
61
84
|
test_files:
|
62
85
|
- spec/spec_helper.rb
|
63
86
|
- spec/wemote/switch_spec.rb
|
64
|
-
has_rdoc:
|