wemote 0.1.0 → 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.
- checksums.yaml +4 -4
- data/.coveralls.yml +1 -0
- data/.travis.yml +5 -0
- data/Gemfile +5 -4
- data/README.md +12 -8
- data/lib/wemote.rb +1 -1
- data/lib/wemote/client.rb +92 -0
- data/lib/wemote/switch.rb +18 -12
- data/lib/wemote/version.rb +1 -1
- data/spec/spec_helper.rb +2 -2
- data/spec/wemote/switch_spec.rb +8 -7
- data/wemote.gemspec +2 -4
- metadata +6 -18
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b18903132febc3de01e2796ce0b7adde752b030f
|
4
|
+
data.tar.gz: 07503eba981f501449f2b6f86afb90baca0ad7c7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3313aa5e43f3394d505f9a2b6c7dbfe06dc6f49effaaea8b86e43542e93f5cb4583793631b34cd6fac99be1aa3440e4ca3b9b40320a8d4ba36fea52418e1662a
|
7
|
+
data.tar.gz: ad62e4b4497c8509246861e52479b677ce495d1859103fbd67823552af6b92f346ad7972cd1dbc8f54e1b7129aa52429172691be75eb2331e639bd09e879b237
|
data/.coveralls.yml
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
service_name: travis-ci
|
data/.travis.yml
CHANGED
data/Gemfile
CHANGED
@@ -1,9 +1,10 @@
|
|
1
1
|
source 'https://rubygems.org'
|
2
|
-
|
3
|
-
# Specify your gem's dependencies in manticore.gemspec
|
4
2
|
gemspec
|
5
3
|
|
6
|
-
|
7
|
-
gem 'manticore', git: 'git://github.com/cheald/manticore.git'
|
4
|
+
# Commented out until I can determine a way to set engine-specific dependencies
|
5
|
+
# gem 'manticore', git: 'git://github.com/cheald/manticore.git'
|
6
|
+
#gem 'typhoeus'
|
7
|
+
gem 'coveralls', :require => false
|
8
|
+
gem 'httparty'
|
8
9
|
gem 'rspec'
|
9
10
|
gem 'rake'
|
data/README.md
CHANGED
@@ -1,20 +1,20 @@
|
|
1
|
-
# Wemote [](https://travis-ci.org/gisikw/wemote)[](https://coveralls.io/r/gisikw/wemote)
|
1
|
+
# Wemote [](https://travis-ci.org/gisikw/wemote) [](http://badge.fury.io/rb/wemote) [](https://coveralls.io/r/gisikw/wemote) [](https://codeclimate.com/github/gisikw/wemote)
|
2
2
|
|
3
|
-
Wemote is an interface for controlling WeMo light switches (and possibly outlets in the future). Unlike other implementations, it does not rely upon `playful` for upnp discovery, which makes it compatible with
|
3
|
+
Wemote is an interface for controlling WeMo light switches (and possibly outlets in the future). Unlike other implementations, it does not rely upon `playful` for upnp discovery, which makes it compatible with alternative Ruby engines, such as JRuby.
|
4
4
|
|
5
5
|
## Installation
|
6
6
|
|
7
|
-
|
7
|
+
Add this line to your application's Gemfile:
|
8
8
|
|
9
|
-
|
9
|
+
gem 'wemote'
|
10
10
|
|
11
11
|
And then execute:
|
12
12
|
|
13
|
-
$
|
13
|
+
$ bundle
|
14
14
|
|
15
|
-
|
15
|
+
Or install it yourself as:
|
16
16
|
|
17
|
-
$ gem install wemote
|
17
|
+
$ gem install wemote
|
18
18
|
|
19
19
|
## Usage
|
20
20
|
|
@@ -32,7 +32,7 @@ switch = Wemote::Switch.find('Kitchen Switch') #=> #<Remo::Switch:0x27f33aef @ho
|
|
32
32
|
|
33
33
|
Given a Switch instance, you can call the following methods:
|
34
34
|
```ruby
|
35
|
-
switch.
|
35
|
+
switch.get_state #=> [:off,:on]
|
36
36
|
switch.off? #=> [true,false]
|
37
37
|
switch.on? #=> [true,false]
|
38
38
|
switch.on!
|
@@ -40,6 +40,10 @@ switch.off!
|
|
40
40
|
switch.toggle!
|
41
41
|
```
|
42
42
|
|
43
|
+
## Performance
|
44
|
+
|
45
|
+
Wemote is designed to be performant - and as such, it will leverage the best HTTP library available for making requests. Currently, Wemote will use (in order of preference): `manticore`, `typhoeus`, `httparty`, and finally (miserably) `net/http`. Because you probably like things fast too, we recommend you `gem install manticore` on JRuby, or `gem install typhoeus` on another engine. In order to keep the gem as flexible as possible, none of these are direct dependencies. They just make Wemote happy and fast.
|
46
|
+
|
43
47
|
## Contributing
|
44
48
|
|
45
49
|
1. Fork it
|
data/lib/wemote.rb
CHANGED
@@ -0,0 +1,92 @@
|
|
1
|
+
module Wemote
|
2
|
+
class Client
|
3
|
+
|
4
|
+
def self.technique
|
5
|
+
@technique ||= begin
|
6
|
+
constants.collect {|const_name| const_get(const_name)}.select {|const| const.class == Module}.detect do |mod|
|
7
|
+
fulfilled = false
|
8
|
+
begin
|
9
|
+
mod.const_get(:DEPENDENCIES).map{|d|require d}
|
10
|
+
fulfilled = true
|
11
|
+
rescue LoadError
|
12
|
+
end
|
13
|
+
fulfilled
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
module Manticore
|
19
|
+
DEPENDENCIES = ['manticore']
|
20
|
+
|
21
|
+
def get(*args)
|
22
|
+
_get(::Manticore,*args).call
|
23
|
+
end
|
24
|
+
|
25
|
+
def post(*args)
|
26
|
+
_post(::Manticore,*args).call
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
module Typhoeus
|
32
|
+
DEPENDENCIES = ['typhoeus']
|
33
|
+
|
34
|
+
def get(*args)
|
35
|
+
_get(::Typhoeus,*args)
|
36
|
+
end
|
37
|
+
|
38
|
+
def post(*args)
|
39
|
+
_post(::Typhoeus,*args)
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
|
44
|
+
module HTTParty
|
45
|
+
DEPENDENCIES = ['httparty']
|
46
|
+
|
47
|
+
def get(*args)
|
48
|
+
_get(::HTTParty,*args)
|
49
|
+
end
|
50
|
+
|
51
|
+
def post(*args)
|
52
|
+
_post(::HTTParty,*args)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
module NetHTTP
|
57
|
+
DEPENDENCIES = ['net/http','uri']
|
58
|
+
|
59
|
+
def get(url,body=nil,headers=nil)
|
60
|
+
uri = URI.parse(url)
|
61
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
62
|
+
request = Net::HTTP::Get.new(uri.request_uri)
|
63
|
+
headers.map{|k,v|request[k]=v} if headers
|
64
|
+
response = http.request(request)
|
65
|
+
end
|
66
|
+
|
67
|
+
def post(url,body=nil,headers=nil)
|
68
|
+
uri = URI.parse(url)
|
69
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
70
|
+
request = Net::HTTP::Post.new(uri.request_uri)
|
71
|
+
headers.map{|k,v|request[k]=v} if headers
|
72
|
+
(request.body = body) if body
|
73
|
+
response = http.request(request)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def initialize
|
78
|
+
extend Wemote::Client.technique
|
79
|
+
end
|
80
|
+
|
81
|
+
private
|
82
|
+
|
83
|
+
def _get(lib,url,body=nil,headers=nil)
|
84
|
+
lib.get(url,{body:body,headers:headers})
|
85
|
+
end
|
86
|
+
|
87
|
+
def _post(lib,url,body=nil,headers=nil)
|
88
|
+
lib.post(url,{body:body,headers:headers})
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|
92
|
+
end
|
data/lib/wemote/switch.rb
CHANGED
@@ -37,19 +37,26 @@ EOF
|
|
37
37
|
|
38
38
|
private
|
39
39
|
|
40
|
-
def
|
40
|
+
def ssdp_socket
|
41
41
|
socket = UDPSocket.new
|
42
|
-
|
43
|
-
|
44
|
-
socket.setsockopt(Socket::IPPROTO_IP, Socket::IP_ADD_MEMBERSHIP, membership)
|
42
|
+
socket.setsockopt(Socket::IPPROTO_IP, Socket::IP_ADD_MEMBERSHIP, IPAddr.new(MULTICAST_ADDR).hton + IPAddr.new(BIND_ADDR).hton)
|
45
43
|
socket.setsockopt(Socket::IPPROTO_IP, Socket::IP_MULTICAST_TTL, 1)
|
46
44
|
socket.setsockopt(Socket::SOL_SOCKET, Socket::SO_REUSEPORT, 1)
|
47
45
|
socket.bind(BIND_ADDR,PORT)
|
46
|
+
socket
|
47
|
+
end
|
48
48
|
|
49
|
+
def fetch_switches
|
50
|
+
socket = ssdp_socket
|
49
51
|
switches = []
|
50
52
|
|
51
53
|
3.times { socket.send(DISCOVERY, 0, MULTICAST_ADDR, PORT) }
|
52
54
|
|
55
|
+
# The following is a bit silly, but is necessary for JRuby support,
|
56
|
+
# which seems to have some issues with socket interruption.
|
57
|
+
# If you have a working JRuby solution that doesn't require this
|
58
|
+
# kind of hackery, by all means, submit a pull request!
|
59
|
+
|
53
60
|
sleep 1
|
54
61
|
|
55
62
|
parser = Thread.start do
|
@@ -86,31 +93,30 @@ EOF
|
|
86
93
|
|
87
94
|
def get_state
|
88
95
|
response = begin
|
89
|
-
client.post("http://#{@host}:#{@port}/upnp/control/basicevent1"
|
96
|
+
client.post("http://#{@host}:#{@port}/upnp/control/basicevent1",Wemote::XML.get_binary_state,GET_HEADERS)
|
90
97
|
rescue Exception
|
91
|
-
client.post("http://#{@host}:#{@port}/upnp/control/basicevent1"
|
98
|
+
client.post("http://#{@host}:#{@port}/upnp/control/basicevent1",Wemote::XML.get_binary_state,GET_HEADERS)
|
92
99
|
end
|
93
100
|
response.body.match(/<BinaryState>(\d)<\/BinaryState>/)[1] == '1' ? :on : :off
|
94
101
|
end
|
95
102
|
|
96
103
|
def set_state(state)
|
97
104
|
begin
|
98
|
-
client.post("http://#{@host}:#{@port}/upnp/control/basicevent1"
|
105
|
+
client.post("http://#{@host}:#{@port}/upnp/control/basicevent1",Wemote::XML.set_binary_state(state),SET_HEADERS)
|
99
106
|
rescue Exception
|
100
|
-
client.post("http://#{@host}:#{@port}/upnp/control/basicevent1"
|
107
|
+
client.post("http://#{@host}:#{@port}/upnp/control/basicevent1",Wemote::XML.set_binary_state(state),SET_HEADERS)
|
101
108
|
end
|
102
109
|
end
|
103
110
|
|
104
111
|
private
|
105
112
|
|
106
113
|
def client
|
107
|
-
@client ||=
|
114
|
+
@client ||= Wemote::Client.new
|
108
115
|
end
|
109
116
|
|
110
117
|
def set_meta
|
111
|
-
client.get("http://#{@host}:#{@port}/setup.xml")
|
112
|
-
|
113
|
-
end
|
118
|
+
response = client.get("http://#{@host}:#{@port}/setup.xml")
|
119
|
+
@name = response.body.match(/<friendlyName>([^<]+)<\/friendlyName>/)[1]
|
114
120
|
end
|
115
121
|
|
116
122
|
end
|
data/lib/wemote/version.rb
CHANGED
data/spec/spec_helper.rb
CHANGED
data/spec/wemote/switch_spec.rb
CHANGED
@@ -9,8 +9,8 @@ describe Wemote::Switch do
|
|
9
9
|
|
10
10
|
describe '.find' do
|
11
11
|
it 'should return an instance whose name matches the argument' do
|
12
|
-
client =
|
13
|
-
client.stub(
|
12
|
+
client = Wemote::Client.new
|
13
|
+
client.stub(:get).and_return(double('response',{body:'<friendlyName>Test Switch</friendlyName>'}))
|
14
14
|
Wemote::Switch.any_instance.stub(:client).and_return(client)
|
15
15
|
switch = Wemote::Switch.new('fakehost','1234')
|
16
16
|
Wemote::Switch.instance_variable_set(:@switches,[switch])
|
@@ -22,8 +22,8 @@ describe Wemote::Switch do
|
|
22
22
|
|
23
23
|
describe 'instance methods' do
|
24
24
|
before do
|
25
|
-
client =
|
26
|
-
client.stub(
|
25
|
+
client = Wemote::Client.new
|
26
|
+
client.stub(:get).and_return(double('response',body:'<friendlyName>Test Switch</friendlyName>'))
|
27
27
|
Wemote::Switch.any_instance.stub(:client).and_return(client)
|
28
28
|
@switch = Wemote::Switch.new('fakehost','1234')
|
29
29
|
end
|
@@ -74,16 +74,17 @@ describe Wemote::Switch do
|
|
74
74
|
|
75
75
|
describe 'get_state' do
|
76
76
|
it 'should return the binary state of the switch' do
|
77
|
-
|
77
|
+
|
78
|
+
@switch.client.stub(:post).and_return(double('response',body:'<BinaryState>1</BinaryState>'))
|
78
79
|
@switch.get_state.should == :on
|
79
|
-
@switch.client.stub(
|
80
|
+
@switch.client.stub(:post).and_return(double('response',body:'<BinaryState>0</BinaryState>'))
|
80
81
|
@switch.get_state.should == :off
|
81
82
|
end
|
82
83
|
end
|
83
84
|
|
84
85
|
describe 'set_state' do
|
85
86
|
it 'should set the binary state of the switch' do
|
86
|
-
@switch.client.stub(
|
87
|
+
@switch.client.stub(:post).and_return(double('response',body:'Called'))
|
87
88
|
@switch.set_state(1).body.should == 'Called'
|
88
89
|
end
|
89
90
|
end
|
data/wemote.gemspec
CHANGED
@@ -8,8 +8,8 @@ Gem::Specification.new do |spec|
|
|
8
8
|
spec.version = Wemote::VERSION
|
9
9
|
spec.authors = ["Kevin Gisi"]
|
10
10
|
spec.email = ["kevin@kevingisi.com"]
|
11
|
-
spec.description = %q{Wemote is a
|
12
|
-
spec.summary = %q{Wemote is a
|
11
|
+
spec.description = %q{Wemote is a Ruby-agnostic gem for Wemo light switches}
|
12
|
+
spec.summary = %q{Wemote is a Ruby-agnostic gem for Wemo light switches}
|
13
13
|
spec.homepage = "https://github.com/gisikw/wemote"
|
14
14
|
spec.license = "MIT"
|
15
15
|
spec.platform = 'ruby'
|
@@ -18,6 +18,4 @@ 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 "manticore", "~> 0.2.1"
|
23
21
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: wemote
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kevin Gisi
|
@@ -9,28 +9,15 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
date: 2014-03-06 00:00:00.000000000 Z
|
12
|
-
dependencies:
|
13
|
-
-
|
14
|
-
name: manticore
|
15
|
-
version_requirements: !ruby/object:Gem::Requirement
|
16
|
-
requirements:
|
17
|
-
- - ~>
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: 0.2.1
|
20
|
-
requirement: !ruby/object:Gem::Requirement
|
21
|
-
requirements:
|
22
|
-
- - ~>
|
23
|
-
- !ruby/object:Gem::Version
|
24
|
-
version: 0.2.1
|
25
|
-
prerelease: false
|
26
|
-
type: :runtime
|
27
|
-
description: Wemote is a JRuby-friendly API for Wemo light switches
|
12
|
+
dependencies: []
|
13
|
+
description: Wemote is a Ruby-agnostic gem for Wemo light switches
|
28
14
|
email:
|
29
15
|
- kevin@kevingisi.com
|
30
16
|
executables: []
|
31
17
|
extensions: []
|
32
18
|
extra_rdoc_files: []
|
33
19
|
files:
|
20
|
+
- .coveralls.yml
|
34
21
|
- .gitignore
|
35
22
|
- .travis.yml
|
36
23
|
- Gemfile
|
@@ -38,6 +25,7 @@ files:
|
|
38
25
|
- README.md
|
39
26
|
- Rakefile
|
40
27
|
- lib/wemote.rb
|
28
|
+
- lib/wemote/client.rb
|
41
29
|
- lib/wemote/switch.rb
|
42
30
|
- lib/wemote/version.rb
|
43
31
|
- lib/wemote/xml.rb
|
@@ -69,7 +57,7 @@ rubyforge_project:
|
|
69
57
|
rubygems_version: 2.2.2
|
70
58
|
signing_key:
|
71
59
|
specification_version: 4
|
72
|
-
summary: Wemote is a
|
60
|
+
summary: Wemote is a Ruby-agnostic gem for Wemo light switches
|
73
61
|
test_files:
|
74
62
|
- spec/spec_helper.rb
|
75
63
|
- spec/wemote/switch_spec.rb
|