wemote 0.2.2 → 0.2.3
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.
- 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:
|