web_power_switch 0.0.1

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.
data/.gitignore ADDED
@@ -0,0 +1,6 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
5
+ *.swp
6
+ *~
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in web_power_switch.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011 Marketfish
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,8 @@
1
+ Web Power Switch
2
+ ================
3
+
4
+ Web Power Switch is a Ruby gem for viewing and managing ports of a Web Power
5
+ Switch III, built by Digital Loggers, Inc.
6
+
7
+ For more details on the hardware check the
8
+ [product page](http://www.digital-loggers.com/lpc.html).
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
@@ -0,0 +1,3 @@
1
+ class WebPowerSwitch
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,85 @@
1
+ require 'net/http'
2
+ require 'uri'
3
+ require 'nokogiri'
4
+
5
+ class WebPowerSwitch
6
+ class CommunicationError < StandardError
7
+ attr_reader :response
8
+ def initialize(response)
9
+ @response = response
10
+ end
11
+ end
12
+
13
+ class Outlet < Struct.new(:name, :number, :status); end
14
+
15
+ def initialize(address='192.168.0.100', port=80,
16
+ user='admin', password='1234', options={})
17
+ @address, @port, @user, @password = address, port, user, password
18
+ @options = options
19
+ end
20
+
21
+ def status
22
+ if @options[:cache_status]
23
+ @jacks ||= parse_socket_status geturl('/index.htm')
24
+ else
25
+ parse_socket_status geturl('/index.htm')
26
+ end
27
+ end
28
+
29
+ [:on, :off, :ccl].each do |method|
30
+ define_method(method) do |outlet|
31
+ if outlet = valid_outlet(outlet)
32
+ clear_status
33
+ response = geturl("/outlet?#{outlet}=#{method.to_s.upcase}")
34
+ else
35
+ raise ArgumentError, "Not a valid outlet"
36
+ end
37
+ end
38
+ end
39
+
40
+ private
41
+ def valid_outlet(outlet)
42
+ status if @jacks.nil? || @jacks.empty?
43
+ outlet_str = outlet.to_s.downcase
44
+ return outlet_str if outlet_str == "a"
45
+ return outlet.to_i if (1..8).include? outlet.to_i
46
+ if good_outlet = find_outlet(outlet)
47
+ return good_outlet.number
48
+ end
49
+ return false
50
+ end
51
+
52
+ def clear_status
53
+ @jacks = nil
54
+ end
55
+
56
+ def find_outlet(name)
57
+ @jacks.select {|j| j.name.downcase == name.downcase }.first
58
+ end
59
+
60
+ def parse_socket_status(response)
61
+ html = Nokogiri::HTML response.body
62
+ rows = html.css('table')[5].css('tr').slice(2, 8)
63
+
64
+ return rows.inject([]) do |jacks, row|
65
+ number, name, status = row.css('td').map {|t| t.text.strip }
66
+ outlet = Outlet.new(name, number.to_i, status.downcase.to_sym)
67
+ jacks << outlet
68
+ end
69
+ end
70
+
71
+ def geturl(page)
72
+ response = nil
73
+ Net::HTTP.start(@address, @port) do |http|
74
+ req = Net::HTTP::Get.new(page)
75
+ req.basic_auth @user, @password
76
+ response = http.request(req)
77
+ end
78
+
79
+ if response.class == Net::HTTPOK
80
+ return response
81
+ else
82
+ raise CommunicationError.new(response), "Could not talk to powerswitch: code #{response.code}"
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,233 @@
1
+ ---
2
+ - !ruby/struct:VCR::HTTPInteraction
3
+ request: !ruby/struct:VCR::Request
4
+ method: :get
5
+ uri: <%= "http://#{user}:#{password}@#{address}:#{port}/index.htm" %>
6
+ body:
7
+ headers:
8
+ authorization:
9
+ - Basic YWRtaW46MTIzNA==
10
+ response: !ruby/struct:VCR::Response
11
+ status: !ruby/struct:VCR::ResponseStatus
12
+ code: 200
13
+ message: OK
14
+ headers:
15
+ content-type:
16
+ - text/html
17
+ cache control:
18
+ - No-store
19
+ expires:
20
+ - Mon, 06 Jan 1990 00:00:01 GMT
21
+ pragma:
22
+ - no-cache
23
+ set-cookie:
24
+ - DLILPC=""; Version=1; Max-Age=0; Path=/
25
+ body: |
26
+ <html>
27
+ <head>
28
+ <META NAME="ROBOTS" CONTENT="NOINDEX, NOFOLLOW">
29
+
30
+ <META HTTP-EQUIV="Refresh" CONTENT="300">
31
+ <title>Outlet Control - Web Power Switch III</title></head>
32
+ <!-- state=ff lock=00 -->
33
+
34
+ <body alink="#0000FF" vlink="#0000FF">
35
+ <FONT FACE="Arial, Helvetica, Sans-Serif">
36
+ <table width="100%" cellspacing=0 cellpadding=0>
37
+ <tr>
38
+ <td valign=top width="17%" height="100%">
39
+
40
+ <!-- menu -->
41
+ <table width="100%" height="100%" align=center border=0 cellspacing=1 cellpadding=0>
42
+ <tr><td valign=top bgcolor="#F4F4F4">
43
+ <table width="100%" cellpadding=1 cellspacing=5>
44
+
45
+ <tr><td align=center>
46
+
47
+ <table><tr><td><a href="http://www.digital-loggers.com/8.html"><img src=logo.gif width=195 height=65 border=0 alt="Digital Loggers, Inc"></a></td>
48
+
49
+ <td><b><font size=-1>Ethernet Power Controller</font></b></td></tr></table>
50
+ <hr>
51
+ </td></tr>
52
+
53
+
54
+
55
+ <tr><td nowrap><b><a href="/index.htm">Outlet Control</a></b></td></tr>
56
+ <tr><td nowrap><b><a href="/admin.htm">Setup</a></b></td></tr>
57
+ <tr><td nowrap><b><a href="/script.htm">Scripting</a></b></td></tr>
58
+
59
+
60
+
61
+
62
+
63
+ <tr><td nowrap><b><a href="/ap.htm">AutoPing</a></b></td></tr>
64
+ <tr><td nowrap><b><a href="/syslog.htm">System Log</a></b></td></tr>
65
+ <tr><td nowrap><b><a href="/logout">Logout</a></b></td></tr>
66
+ <tr><td nowrap><b><a href="/help/">Help</a></b></td></tr>
67
+
68
+ <tr><td><hr></td></tr>
69
+
70
+
71
+ <tr><td><b><a href="http://www.digital-loggers.com/5.html">Manual</a></b></td></tr>
72
+
73
+ <tr><td><b><a href="http://www.digital-loggers.com/6.html">FAQ</a></b></td></tr>
74
+
75
+ <tr><td><b><a href="http://www.digital-loggers.com/7.html">Product Information</a></b></td></tr>
76
+
77
+ <tr><td><b><a href="http://www.digital-loggers.com/8.html">Digital Loggers, Inc.</a></b></td></tr>
78
+
79
+
80
+ </table>
81
+ </td></tr>
82
+
83
+
84
+ <tr><td valign=bottom height="100%" bgcolor="#F4F4F4">
85
+ <small>Version 1.4.3 (Mar 14 2010 / 18:25:22) 8AA39795-B6EF1CE7</small>
86
+ </td></tr>
87
+ <tr><td valign=bottom height="100%" bgcolor="#F4F4F4">
88
+ <small>S/N:0000333967</small>
89
+ </td></tr>
90
+
91
+ </table>
92
+ <!-- /menu -->
93
+
94
+ </td>
95
+ <td valign=top width="83%">
96
+
97
+ <!-- heading table -->
98
+ <table width="100%" align=center border=0 cellspacing=1 cellpadding=3>
99
+ <tr><td bgcolor=red>&nbsp;</td></tr><tr><td align=center><h1>We recommend that you change the password!</h1></td></tr><tr><td bgcolor=red>&nbsp;</td></tr>
100
+ <tr>
101
+ <th bgcolor="#DDDDFF" align=left>
102
+ Controller: Web Power Switch III
103
+ </th>
104
+ </tr>
105
+
106
+ <tr bgcolor="#FFFFFF" align=left>
107
+ <td>
108
+ Uptime: 94:00:49 <!-- 338449s up -->
109
+ </td>
110
+ </tr>
111
+
112
+ </table>
113
+ <!-- /heading table -->
114
+
115
+ <br>
116
+
117
+ <!-- individual control table -->
118
+ <table width="100%" align=center border=0 cellspacing=1 cellpadding=3>
119
+
120
+ <tr>
121
+ <td bgcolor="#DDDDFF" colspan=5 align=left>
122
+ Individual Control
123
+ </td>
124
+ </tr>
125
+
126
+ <!-- heading rows -->
127
+ <tr bgcolor="#DDDDDD">
128
+ <th>#</th>
129
+ <th align=left>Name</th>
130
+ <th align=left>State</th>
131
+ <th align=left colspan=2>Action</th>
132
+ </tr>
133
+ <!-- /heading rows -->
134
+
135
+
136
+
137
+
138
+ <tr bgcolor="#F4F4F4"><td align=center>1</td>
139
+ <td>Outlet 1</td><td>
140
+ <b><font color=green>ON</font></b></td><td>
141
+ <a href=outlet?1=OFF>Switch OFF</a>
142
+ </td><td>
143
+ <a href=outlet?1=CCL>Cycle</a>
144
+ </td></tr>
145
+
146
+
147
+ <tr bgcolor="#F4F4F4"><td align=center>2</td>
148
+ <td>Outlet 2</td><td>
149
+ <b><font color=green>ON</font></b></td><td>
150
+ <a href=outlet?2=OFF>Switch OFF</a>
151
+ </td><td>
152
+ <a href=outlet?2=CCL>Cycle</a>
153
+ </td></tr>
154
+
155
+
156
+ <tr bgcolor="#F4F4F4"><td align=center>3</td>
157
+ <td>Outlet 3</td><td>
158
+ <b><font color=green>ON</font></b></td><td>
159
+ <a href=outlet?3=OFF>Switch OFF</a>
160
+ </td><td>
161
+ <a href=outlet?3=CCL>Cycle</a>
162
+ </td></tr>
163
+
164
+
165
+ <tr bgcolor="#F4F4F4"><td align=center>4</td>
166
+ <td>Outlet 4</td><td>
167
+ <b><font color=green>ON</font></b></td><td>
168
+ <a href=outlet?4=OFF>Switch OFF</a>
169
+ </td><td>
170
+ <a href=outlet?4=CCL>Cycle</a>
171
+ </td></tr>
172
+
173
+
174
+ <tr bgcolor="#F4F4F4"><td align=center>5</td>
175
+ <td>Outlet 5</td><td>
176
+ <b><font color=green>ON</font></b></td><td>
177
+ <a href=outlet?5=OFF>Switch OFF</a>
178
+ </td><td>
179
+ <a href=outlet?5=CCL>Cycle</a>
180
+ </td></tr>
181
+
182
+
183
+ <tr bgcolor="#F4F4F4"><td align=center>6</td>
184
+ <td>Outlet 6</td><td>
185
+ <b><font color=green>ON</font></b></td><td>
186
+ <a href=outlet?6=OFF>Switch OFF</a>
187
+ </td><td>
188
+ <a href=outlet?6=CCL>Cycle</a>
189
+ </td></tr>
190
+
191
+
192
+ <tr bgcolor="#F4F4F4"><td align=center>7</td>
193
+ <td>Outlet 7</td><td>
194
+ <b><font color=green>ON</font></b></td><td>
195
+ <a href=outlet?7=OFF>Switch OFF</a>
196
+ </td><td>
197
+ <a href=outlet?7=CCL>Cycle</a>
198
+ </td></tr>
199
+
200
+
201
+ <tr bgcolor="#F4F4F4"><td align=center>8</td>
202
+ <td>Outlet 8</td><td>
203
+ <b><font color=green>ON</font></b></td><td>
204
+ <a href=outlet?8=OFF>Switch OFF</a>
205
+ </td><td>
206
+ <a href=outlet?8=CCL>Cycle</a>
207
+ </td></tr>
208
+
209
+
210
+ </table>
211
+ <!-- /individual control table -->
212
+
213
+ <br>
214
+
215
+ <table width="100%" align=center border=0 cellspacing=1 cellpadding=3>
216
+ <tr><td bgcolor="#DDDDFF" align=left>Master Control</td></tr>
217
+
218
+ <tr><td bgcolor="#F4F4F4" align=left><a href=outlet?a=OFF>All outlets OFF</a></td></tr>
219
+ <tr><td bgcolor="#F4F4F4" align=left><a href=outlet?a=ON>All outlets ON</a></td></tr>
220
+ <tr><td bgcolor="#F4F4F4" align=left><a href=outlet?a=CCL>Cycle all outlets</a></td></tr>
221
+ <tr><td align=center>Sequence delay: 1 sec.</td></tr>
222
+
223
+ </table>
224
+
225
+
226
+ </td>
227
+ </tr>
228
+ </table>
229
+
230
+ </body>
231
+ </html>
232
+
233
+ http_version: "1.0"
@@ -0,0 +1,8 @@
1
+ require File.dirname(__FILE__) + '/../lib/web_power_switch'
2
+ require 'vcr'
3
+
4
+
5
+ VCR.config do |c|
6
+ c.cassette_library_dir = 'spec/fixtures/vcr_cassettes'
7
+ c.stub_with :webmock
8
+ end
@@ -0,0 +1,36 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+ describe WebPowerSwitch do
4
+ before(:each) do
5
+ @address = ENV['WPS_ADDRESS'] || 'localhost'
6
+ @port = ENV['WPS_PORT'] || '8080'
7
+ @user = ENV['WPS_USER'] || 'admin'
8
+ @password = ENV['WPS_PASSWORD'] || 'password'
9
+ end
10
+
11
+ it "should take a IP, port, user and password" do
12
+ wps = WebPowerSwitch.new(@address, @port, @user, @password)
13
+ end
14
+
15
+ it "should connect successfully to power supply" do
16
+ wps = WebPowerSwitch.new(@address, @port, @user, @password)
17
+ VCR.use_cassette('status',
18
+ :erb => { :address => @address, :port => @port, :user => @user, :password => @password },
19
+ :match_requests_on => [:uri, :method, :body] ) do
20
+ response = wps.status
21
+
22
+ end
23
+ end
24
+ context "#status" do
25
+ it "should returns a hash with each sockets current status" do
26
+ wps = WebPowerSwitch.new(@address, @port, @user, @password)
27
+ VCR.use_cassette('status',
28
+ :erb => { :address => @address, :port => @port, :user => @user, :password => @password },
29
+ :match_requests_on => [:uri, :method, :body] ) do
30
+ response = wps.status
31
+ expected = 8.times.inject([]) {|m,i| m << WebPowerSwitch::Outlet.new("Outlet #{i+1}", i+1, :on)}
32
+ response.should == expected
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,26 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "web_power_switch/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "web_power_switch"
7
+ s.version = WebPowerSwitch::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Kyle Burckhard"]
10
+ s.email = ["kyle@marketfish.com"]
11
+ s.homepage = ""
12
+ s.summary = %q{Controls a Web Power Supply by DLI}
13
+ s.description = %q{API and binary to control ports and check status of a Web Power Supply from Data Loggers Inc.}
14
+
15
+ s.rubyforge_project = "web_power_switch"
16
+
17
+ s.files = `git ls-files`.split("\n")
18
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
+ s.require_paths = ["lib"]
21
+
22
+ s.add_dependency 'nokogiri'
23
+ s.add_development_dependency 'rspec', '>2.0.0'
24
+ s.add_development_dependency 'vcr', '~>1.10.0'
25
+ s.add_development_dependency 'webmock'
26
+ end
metadata ADDED
@@ -0,0 +1,110 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: web_power_switch
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.0.1
6
+ platform: ruby
7
+ authors:
8
+ - Kyle Burckhard
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2011-06-03 00:00:00 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: nokogiri
17
+ prerelease: false
18
+ requirement: &id001 !ruby/object:Gem::Requirement
19
+ none: false
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "0"
24
+ type: :runtime
25
+ version_requirements: *id001
26
+ - !ruby/object:Gem::Dependency
27
+ name: rspec
28
+ prerelease: false
29
+ requirement: &id002 !ruby/object:Gem::Requirement
30
+ none: false
31
+ requirements:
32
+ - - ">"
33
+ - !ruby/object:Gem::Version
34
+ version: 2.0.0
35
+ type: :development
36
+ version_requirements: *id002
37
+ - !ruby/object:Gem::Dependency
38
+ name: vcr
39
+ prerelease: false
40
+ requirement: &id003 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: 1.10.0
46
+ type: :development
47
+ version_requirements: *id003
48
+ - !ruby/object:Gem::Dependency
49
+ name: webmock
50
+ prerelease: false
51
+ requirement: &id004 !ruby/object:Gem::Requirement
52
+ none: false
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: "0"
57
+ type: :development
58
+ version_requirements: *id004
59
+ description: API and binary to control ports and check status of a Web Power Supply from Data Loggers Inc.
60
+ email:
61
+ - kyle@marketfish.com
62
+ executables: []
63
+
64
+ extensions: []
65
+
66
+ extra_rdoc_files: []
67
+
68
+ files:
69
+ - .gitignore
70
+ - Gemfile
71
+ - LICENSE
72
+ - README.md
73
+ - Rakefile
74
+ - lib/web_power_switch.rb
75
+ - lib/web_power_switch/version.rb
76
+ - spec/fixtures/vcr_cassettes/status.yml
77
+ - spec/spec_helper.rb
78
+ - spec/web_power_switch_spec.rb
79
+ - web_power_switch.gemspec
80
+ homepage: ""
81
+ licenses: []
82
+
83
+ post_install_message:
84
+ rdoc_options: []
85
+
86
+ require_paths:
87
+ - lib
88
+ required_ruby_version: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ">="
92
+ - !ruby/object:Gem::Version
93
+ version: "0"
94
+ required_rubygems_version: !ruby/object:Gem::Requirement
95
+ none: false
96
+ requirements:
97
+ - - ">="
98
+ - !ruby/object:Gem::Version
99
+ version: "0"
100
+ requirements: []
101
+
102
+ rubyforge_project: web_power_switch
103
+ rubygems_version: 1.7.2
104
+ signing_key:
105
+ specification_version: 3
106
+ summary: Controls a Web Power Supply by DLI
107
+ test_files:
108
+ - spec/fixtures/vcr_cassettes/status.yml
109
+ - spec/spec_helper.rb
110
+ - spec/web_power_switch_spec.rb