powercontroller9202 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/.gemtest ADDED
File without changes
data/History.txt ADDED
@@ -0,0 +1,3 @@
1
+ === 1.0.1 / 2013-01-10
2
+
3
+ * Code copied from running version, which wasn't under version control
data/Manifest.txt ADDED
@@ -0,0 +1,6 @@
1
+ History.txt
2
+ Manifest.txt
3
+ README.txt
4
+ Rakefile
5
+ lib/powercontroller9202.rb
6
+ test/test.rb
data/README.txt ADDED
@@ -0,0 +1,139 @@
1
+ = powercontroller9202
2
+
3
+ * https://github.com/rbur004/powercontroller9202
4
+
5
+ == DESCRIPTION:
6
+
7
+ A Ruby GEDCOM to communicate with an Aviosys Inc. 9202 IP Power Controller (and associated products (eg 9212)).
8
+
9
+ == FEATURES/PROBLEMS:
10
+
11
+ * see the status of the relays
12
+ * turns relays on and off without altering the saved state on power up
13
+ * turns relays on and off, and alters the saved state for next power up
14
+ * Toggles any or all relays
15
+
16
+ == SYNOPSIS:
17
+
18
+ require 'powercontroller9202'
19
+
20
+ #Default to relay off state being a power on state
21
+ pc = PowerController9202.new("192.168.249.128", "admin", "xxxxx")
22
+
23
+ #change so relay off state is a power off state
24
+ #pc = PowerController9202.new("192.168.249.128", "admin", "xxxxxx", false)
25
+
26
+ #8 relays, not 4
27
+ #relay off state is a power on state
28
+ #pc = PowerController9202.new("192.168.249.128", "admin", "xxxxxx", true, 8)
29
+
30
+ #Manually set the portmap. Nb portmap[0] is unused.
31
+ #pc = PowerController9202.new("192.168.249.128", "admin", "xxxxxx")
32
+ #pc.portmap = [0,0,2,5,7,1,3,4,6]
33
+ #pc.set_status #to update the status bitmap
34
+
35
+
36
+ puts pc.status.to_s #current relay states as array of 0's and 1's for relay off and on
37
+ puts pc.to_s(['server', 'modem', 'lights', 'tv']) #outputs relay status with names.
38
+ puts pc #Prints the relay status (Equivalent to puts pc.to_s )
39
+
40
+ exit #currently testing against an installed controller , as the test version failed.
41
+
42
+ #Power on means the relay switch the power on, even if the relay power is off
43
+ #Relay on, means the relay is powered, but that might mean the power is then off.
44
+ pc.ensureon #Turns all relays to the power on state (not saved)
45
+ pc.off([2,4]) #Turns relays 2 and 4 power off (not saved)
46
+ pc.on([2,4]) #Turns relays 2 and 4 power on (not saved)
47
+
48
+
49
+ pg.toggle_all #Turns power off for 5 seconds through all relays (understands my off is on)
50
+ pg.toggle_all(10) #Turns power on for 10 seconds through all relays (understands my off is on)
51
+
52
+
53
+ pc.toggle(1) #Turns power off for 5 seconds through relay 1(understands my off is on).
54
+ pc.toggle(1,10) #Turns power off for 10 seconds through relay 1 (understands my off is on)
55
+
56
+ pc.toggle([1,4]) #Turns power off for 5 seconds through relay 1 & 4 (understands my off is on)
57
+ pc.toggle([2,3],10) #Turns power off for 10 seconds through relays 2 & 3 (understands my off is on).
58
+
59
+ #Via the web form, rather thon SetIO
60
+ pc.reset_all #Sets relays to off state (Relays off, not necessarily power off)
61
+ #For mine, that is an on state as I want the failure state to be on
62
+ #The web interface shows them as off though.
63
+
64
+ #Via the web form, rather thon SetIO
65
+ pc.timer_toggle_all #Turns off the relays, then on again after 5 seconds
66
+ pc.timer_toggle_all(10) #Turns off the relays, then on again after 10 seconds
67
+
68
+ #Via the web form, rather thon SetIO
69
+ pc.on2(3) #Turns relay 3 power on and it shows up that way in the web interface.
70
+ #Hence will be set this way after the 9202 is power cycled.
71
+ pc.off2(2) #Turns relay 2 power off and it shows up that way in the web interface.
72
+ #Hence will be set this way after the 9202 is power cycled.
73
+
74
+
75
+
76
+ == REQUIREMENTS:
77
+
78
+ * require 'rubygems'
79
+ * require 'powercontroller9202'
80
+
81
+ == INSTALL:
82
+
83
+ * sudo gem install powercontroller9202
84
+
85
+ == LICENSE:
86
+
87
+ Distributed under the Ruby License.
88
+
89
+ Copyright (c) 2009
90
+
91
+ 1. You may make and give away verbatim copies of the source form of the
92
+ software without restriction, provided that you duplicate all of the
93
+ original copyright notices and associated disclaimers.
94
+
95
+ 2. You may modify your copy of the software in any way, provided that
96
+ you do at least ONE of the following:
97
+
98
+ a) place your modifications in the Public Domain or otherwise
99
+ make them Freely Available, such as by posting said
100
+ modifications to Usenet or an equivalent medium, or by allowing
101
+ the author to include your modifications in the software.
102
+
103
+ b) use the modified software only within your corporation or
104
+ organization.
105
+
106
+ c) rename any non-standard executables so the names do not conflict
107
+ with standard executables, which must also be provided.
108
+
109
+ d) make other distribution arrangements with the author.
110
+
111
+ 3. You may distribute the software in object code or executable
112
+ form, provided that you do at least ONE of the following:
113
+
114
+ a) distribute the executables and library files of the software,
115
+ together with instructions (in the manual page or equivalent)
116
+ on where to get the original distribution.
117
+
118
+ b) accompany the distribution with the machine-readable source of
119
+ the software.
120
+
121
+ c) give non-standard executables non-standard names, with
122
+ instructions on where to get the original software distribution.
123
+
124
+ d) make other distribution arrangements with the author.
125
+
126
+ 4. You may modify and include the part of the software into any other
127
+ software (possibly commercial). But some files in the distribution
128
+ may not have been written by the author, so that they are not under this terms.
129
+
130
+ 5. The scripts and library files supplied as input to or produced as
131
+ output from the software do not automatically fall under the
132
+ copyright of the software, but belong to whomever generated them,
133
+ and may be sold commercially, and may be aggregated with this
134
+ software.
135
+
136
+ 6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
137
+ IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
138
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
139
+ PURPOSE.
data/Rakefile ADDED
@@ -0,0 +1,11 @@
1
+ # -*- ruby -*-
2
+
3
+ require 'rubygems'
4
+ require 'hoe'
5
+
6
+ Hoe.spec 'powercontroller9202' do
7
+ self.rubyforge_name = 'powercontroller9202'
8
+ developer 'Rob Burrowes', 'r.burrowes@auckland.ac.nz'
9
+ remote_rdoc_dir = '' # Release to root
10
+ #extra_deps << 'whatevs'
11
+ end
@@ -0,0 +1,382 @@
1
+ require "net/http"
2
+ require 'uri'
3
+ require 'digest/md5'
4
+ require 'scanf'
5
+
6
+ #Extention to the Array class to extend Array in a cleaner manner.
7
+ class PowerController9202Array < Array
8
+ #Add the seed value to the enumerated array values
9
+ def inject_with_index(seed=nil)
10
+ if seed == nil
11
+ seed = self[0]
12
+ start = 1
13
+ else
14
+ start = 0
15
+ end
16
+ self[start..-1].each_with_index do |a,i|
17
+ seed = yield(seed,a,i)
18
+ end
19
+ return seed
20
+ end
21
+ end
22
+
23
+ #Aviosys Inc. 9202 IP Power Controller
24
+ #PowerController provides a ruby API to the web interface
25
+ #
26
+
27
+ class PowerController9202
28
+ VERSION = '1.0.2'
29
+
30
+ attr_accessor :host #Hostname or IP address of the power controller
31
+ attr_accessor :user #username to login as (admin)
32
+ attr_accessor :portmap #Defoults to 4 relay version, can be set to 8 relay version, or manually set through this accessor.
33
+ attr_reader :status #The relay state. Set this with #set_status if you manually change portmap.
34
+ attr_writer :password
35
+
36
+ PORTMAP4 = [0,0,2,5,7] #The 4 relay version of the 9202 (my two are like this)
37
+ PORTMAP8 = [0,0,1,2,3,4,5,6,7,8] #The 8 relay version of the 9212
38
+ RELAY_ON = 1
39
+ RELAY_OFF = 0
40
+
41
+ #PowerController.new saves the hostname, username and password and returns the instantiated class
42
+ # on_is_off means the relays conduct power in their off state.
43
+ # My default is to use the relay off state as power on
44
+ # and the relay on state as the power being off (just a wiring decision)
45
+ # This means that a powercontroller failure will leave the devices on,
46
+ # which is what I want.
47
+ # portmap maps the relay number to the web interface's numbering (position on the board)
48
+ # I have only have 4 relays installed and they are on Port 0, 2, 5 and 7
49
+ # Numbering for SetIO & GetIO use 1,2,3 and 4 as relay numbers,
50
+ # but the web uses the actual relay position on the board.
51
+ # PORTMAP maps 1..4 to the actual ports for the web interfaces commands,
52
+ # so Array index 0 is unused
53
+
54
+ def initialize(host, user, password, on_is_off=true, portmap=4 )
55
+ @host = host
56
+ @user = user
57
+ @password = password
58
+ @power_on = on_is_off ? RELAY_OFF : RELAY_ON
59
+ @power_off = on_is_off ? RELAY_ON : RELAY_OFF
60
+ @portmap = portmap == 4 ? PORTMAP4 : PORTMAP8
61
+ set_status
62
+ end
63
+
64
+ #Fetches the relay states and return as an array of 1's and 0's
65
+ #1 means the relay is powered (though you might be using the relay off state as power on)
66
+ #0 means the relay is unpowered (though you might be using the relay off state as power on)
67
+ def set_status
68
+ Net::HTTP.start(@host) do |http|
69
+ response = http.get("/GetP6?")
70
+ if response.code.to_i == 200
71
+ #print response.body
72
+ @status = PowerController9202Array.new(response.body.scanf("<html>P61=%d,P62=%d,P63=%d,P64=%d</html>"))
73
+ else
74
+ #print "Connection failed with error #{response.code}\n"
75
+ raise "Connection failed with error #{response.code}\n"
76
+ end
77
+ end
78
+ end
79
+
80
+
81
+ #'on' is short hand for tmp_change_state(outlet, @power_on)
82
+ #Using SetIO. Note that changes are lost after power cycle.
83
+ def on(outlet)
84
+ tmp_change_state(outlet, @power_on)
85
+ end
86
+
87
+ #'on' is short hand for tmp_change_state(outlet, @power_off)
88
+ #Using SetIO. Note that changes are lost after power cycle.
89
+ def off(outlet)
90
+ tmp_change_state(outlet, @power_off)
91
+ end
92
+
93
+ #Ensure_on will fetch each relays state, and turn the relay on, if it is off.
94
+ #Using SetIO. Note that changes are lost after power cycle.
95
+ def ensure_on
96
+ outlet = []
97
+ @status.each_with_index do |o,i|
98
+ if o == @power_off
99
+ outlet << i + 1
100
+ end
101
+ end
102
+ if outlet.length > 0 #We have relays to alter the state of
103
+ on(outlet)
104
+ end
105
+ end
106
+
107
+ #toggle turns a relay off, then back on again, so the device is power cycled.
108
+ #If the outlet argument is an array, all relays specified in the array are power cycled.
109
+ #The time the relay is off is defined by the argument sleep_time (defoult of 5 seconds)
110
+ def toggle(outlet, sleep_time=5)
111
+ off(outlet)
112
+ sleep sleep_time
113
+ on(outlet)
114
+ end
115
+
116
+ #Toggle_all power cycles all the relays.
117
+ #The time the relay is off is defined by the argument sleep_time (defoult of 5 seconds)
118
+ def toggle_all(sleep_time=5)
119
+ outlet = []
120
+ @portmap[1..-1].each_with_index { |x,i| outlet << i+1 }
121
+ toggle(outlet, sleep_time)
122
+ end
123
+
124
+
125
+ #Reset_all uses the web form reset of each relays to the OFF state
126
+ #This persists after a device reboot, where the earlier calls do not.
127
+ def reset_all
128
+ login
129
+ res = Net::HTTP.new(@host, 80).start do |http|
130
+
131
+ post = Net::HTTP::Post.new('/tgi/ioControl.tgi')
132
+ #setting post body this way, as set_form_data randomised the order and device expects fixed order.
133
+ post.body = "PinNo=P6_0&P60=Off&P60_TIMER=0&P60_TIMER_CNTL=Off&" +
134
+ "PinNo=P6_1&P61=Off&P61_TIMER=0&P61_TIMER_CNTL=Off&" +
135
+ "PinNo=P6_2&P62=Off&P62_TIMER=0&P62_TIMER_CNTL=Off&" +
136
+ "PinNo=P6_3&P63=Off&P63_TIMER=0&P63_TIMER_CNTL=Off&" +
137
+ "PinNo=P6_4&P64=Off&P64_TIMER=0&P64_TIMER_CNTL=Off&" +
138
+ "PinNo=P6_5&P65=Off&P65_TIMER=0&P65_TIMER_CNTL=Off&" +
139
+ "PinNo=P6_6&P66=Off&P66_TIMER=0&P66_TIMER_CNTL=Off&" +
140
+ "PinNo=P6_7&P67=Off&P67_TIMER=0&P67_TIMER_CNTL=Off&" +
141
+ "Reset=Reset"
142
+ headers = {
143
+ 'User-Agent' => 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9) Gecko/2008051206 Firefox/3.0',
144
+ 'Content-Type' => 'application/x-www-form-urlencoded',
145
+ 'Referer' => "http://#{@host}/ioControl_2e.htm",
146
+ 'Cookie' => @cookie
147
+ }
148
+
149
+ response = http.post('/tgi/ioControl.tgi', post.body, headers)
150
+ if(response.code.to_i == 200)
151
+ @status.collect! { |v| 0 }
152
+ end
153
+ #puts response.code
154
+ end
155
+ end
156
+
157
+ #timer_toggle_all calls the web form to turn off the relays for the time period
158
+ #The earlier toggle uses the SetIO call, with an, OFF, sleep, then ON call.
159
+ def timer_toggle_all(sleep_time=5)
160
+ login
161
+ p6 = ["On","On","On","On","On","On","On","On"]
162
+ p6_time = ["0", "0", "0", "0","0","0","0","0"]
163
+ p6_timer = ["On","On","On","On","On","On","On","On"]
164
+ @portmap[1..-1].each do |pm|
165
+ p6[pm] = @power_on == "Off"
166
+ p6_time[pm] = "#{sleep_time}"
167
+ end
168
+
169
+ res = Net::HTTP.new(@host, 80).start do |http|
170
+
171
+ post = Net::HTTP::Post.new('/tgi/ioControl.tgi')
172
+ post.body = "PinNo=P6_0&P60=#{p6[0]}&P60_TIMER=#{p6_time[0]}&P60_TIMER_CNTL=#{p6_timer[0]}" +
173
+ "&PinNo=P6_1&P61=#{p6[1]}&P61_TIMER=#{p6_time[1]}&P61_TIMER_CNTL=#{p6_timer[1]}" +
174
+ "&PinNo=P6_2&P62=#{p6[2]}&P62_TIMER=#{p6_time[2]}&P62_TIMER_CNTL=#{p6_timer[2]}" +
175
+ "&PinNo=P6_3&P63=#{p6[3]}&P63_TIMER=#{p6_time[3]}&P63_TIMER_CNTL=#{p6_timer[3]}" +
176
+ "&PinNo=P6_4&P64=#{p6[4]}&P64_TIMER=#{p6_time[4]}&P64_TIMER_CNTL=#{p6_timer[4]}" +
177
+ "&PinNo=P6_5&P65=#{p6[5]}&P65_TIMER=#{p6_time[5]}&P65_TIMER_CNTL=#{p6_timer[5]}" +
178
+ "&PinNo=P6_6&P66=#{p6[6]}&P66_TIMER=#{p6_time[6]}&P66_TIMER_CNTL=#{p6_timer[6]}" +
179
+ "&PinNo=P6_7&P67=#{p6[7]}&P67_TIMER=#{p6_time[7]}&P67_TIMER_CNTL=#{p6_timer[7]}" +
180
+ "&Apply=Apply"
181
+ # print post.body
182
+
183
+ headers = {
184
+ 'User-Agent' => 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9) Gecko/2008051206 Firefox/3.0',
185
+ 'Content-Type' => 'application/x-www-form-urlencoded',
186
+ 'Referer' => "http://#{@host}/ioControl_2e.htm",
187
+ 'Cookie' => @cookie
188
+ }
189
+
190
+ response = http.post('/tgi/ioControl.tgi', post.body, headers)
191
+ #puts response.code
192
+ end
193
+ end
194
+
195
+
196
+ #Timer_toggle uses the web interface's power cycling feature.
197
+ #
198
+ #I only have 4 relays installed and they are on Port 0, 2, 5 and 7
199
+ #Numbering for SetIO & GetIO use 1,2,3 and 4 as relay numbers
200
+ def timer_toggle(outlet, sleep_time=5) #
201
+ login
202
+
203
+ p6 = ["On","On","On","On","On","On","On","On"]
204
+ p6_time = ["0", "0", "0", "0","0","0","0","0"]
205
+ p6_timer = ["On","On","On","On","On","On","On","On"]
206
+ p6[@portmap[outlet]] = "Off"
207
+ p6_time[@portmap[outlet]] = "#{sleep_time}"
208
+
209
+ res = Net::HTTP.new(@host, 80).start do |http|
210
+
211
+ post = Net::HTTP::Post.new('/tgi/ioControl.tgi')
212
+ post.body = "PinNo=P6_0&P60=#{p6[0]}&P60_TIMER=#{p6_time[0]}&P60_TIMER_CNTL=#{p6_timer[0]}" +
213
+ "&PinNo=P6_1&P61=#{p6[1]}&P61_TIMER=#{p6_time[1]}&P61_TIMER_CNTL=#{p6_timer[1]}" +
214
+ "&PinNo=P6_2&P62=#{p6[2]}&P62_TIMER=#{p6_time[2]}&P62_TIMER_CNTL=#{p6_timer[2]}" +
215
+ "&PinNo=P6_3&P63=#{p6[3]}&P63_TIMER=#{p6_time[3]}&P63_TIMER_CNTL=#{p6_timer[3]}" +
216
+ "&PinNo=P6_4&P64=#{p6[4]}&P64_TIMER=#{p6_time[4]}&P64_TIMER_CNTL=#{p6_timer[4]}" +
217
+ "&PinNo=P6_5&P65=#{p6[5]}&P65_TIMER=#{p6_time[5]}&P65_TIMER_CNTL=#{p6_timer[5]}" +
218
+ "&PinNo=P6_6&P66=#{p6[6]}&P66_TIMER=#{p6_time[6]}&P66_TIMER_CNTL=#{p6_timer[6]}" +
219
+ "&PinNo=P6_7&P67=#{p6[7]}&P67_TIMER=#{p6_time[7]}&P67_TIMER_CNTL=#{p6_timer[7]}" +
220
+ "&Apply=Apply"
221
+
222
+ #a = post.body.split(/&PinNo/)
223
+ #a.each {|x| print "#{x}\n&PinNo" }
224
+
225
+ headers = {
226
+ 'User-Agent' => 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9) Gecko/2008051206 Firefox/3.0',
227
+ 'Content-Type' => 'application/x-www-form-urlencoded',
228
+ 'Referer' => "http://#{@host}/ioControl_2e.htm",
229
+ 'Cookie' => @cookie
230
+ }
231
+
232
+ response = http.post('/tgi/ioControl.tgi', post.body, headers)
233
+ #puts response.code
234
+ end
235
+ end
236
+
237
+ #'on2' is short hand for change_state(outlet, PowerController::ON)
238
+ #Uses the web interface, so unlike 'on', this persists after a device reboot
239
+ def on2(outlet) #Uses the web interfaces, not SetIO
240
+ change_state(outlet, @power_on == 1 ? "On" : "Off")
241
+ end
242
+
243
+ #'off2' is short hand for change_state(outlet, PowerController::ON)
244
+ #Uses the web interface, so unlike 'off', this persists after a device reboot
245
+ def off2(outlet) #Uses the web interfaces, not SetIO
246
+ change_state(outlet, @power_off == 0 ? "Off" : "On")
247
+ end
248
+
249
+ #Return a status string, with named ports specified in the port_names array.
250
+ def to_s(port_names = [nil,nil,nil,nil ])
251
+ @status.inject_with_index("") { |s,x,i| s + "Port #{i+1}=#{x==0 ? 'On' : 'Off'} #{if port_names[i] then port_names[i] end}\n" }
252
+ end
253
+
254
+ private
255
+ #change_state uses the web interface to turn relays On or Off
256
+ #This persists after a device reboot, where the earlier calls do not.
257
+ #
258
+ #More Useful is tmp_change_state, as this doesn't get saved on the device.
259
+ #
260
+ def change_state(outlet,state)
261
+ login
262
+
263
+ p6 = set_p6
264
+ p6_time = ["0", "0", "0", "0","0","0","0","0"]
265
+ p6_timer = ["On","On","On","On","On","On","On","On"]
266
+ if outlet.class == Array
267
+ outlet.each { |o| p6[@portmap[o]] = state }
268
+ else
269
+ p6[@portmap[outlet]] = state
270
+ end
271
+
272
+ res = Net::HTTP.new(@host, 80).start do |http|
273
+
274
+ post = Net::HTTP::Post.new('/tgi/ioControl.tgi')
275
+ post.body = "PinNo=P6_0&P60=#{p6[0]}&P60_TIMER=#{p6_time[0]}&P60_TIMER_CNTL=#{p6_timer[0]}" +
276
+ "&PinNo=P6_1&P61=#{p6[1]}&P61_TIMER=#{p6_time[1]}&P61_TIMER_CNTL=#{p6_timer[1]}" +
277
+ "&PinNo=P6_2&P62=#{p6[2]}&P62_TIMER=#{p6_time[2]}&P62_TIMER_CNTL=#{p6_timer[2]}" +
278
+ "&PinNo=P6_3&P63=#{p6[3]}&P63_TIMER=#{p6_time[3]}&P63_TIMER_CNTL=#{p6_timer[3]}" +
279
+ "&PinNo=P6_4&P64=#{p6[4]}&P64_TIMER=#{p6_time[4]}&P64_TIMER_CNTL=#{p6_timer[4]}" +
280
+ "&PinNo=P6_5&P65=#{p6[5]}&P65_TIMER=#{p6_time[5]}&P65_TIMER_CNTL=#{p6_timer[5]}" +
281
+ "&PinNo=P6_6&P66=#{p6[6]}&P66_TIMER=#{p6_time[6]}&P66_TIMER_CNTL=#{p6_timer[6]}" +
282
+ "&PinNo=P6_7&P67=#{p6[7]}&P67_TIMER=#{p6_time[7]}&P67_TIMER_CNTL=#{p6_timer[7]}" +
283
+ "&Apply=Apply"
284
+
285
+ #a = post.body.split(/&PinNo/)
286
+ #a.each {|x| print "#{x}\n&PinNo" }
287
+
288
+ headers = {
289
+ 'User-Agent' => 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9) Gecko/2008051206 Firefox/3.0',
290
+ 'Content-Type' => 'application/x-www-form-urlencoded',
291
+ 'Referer' => "http://#{@host}/ioControl_2e.htm",
292
+ 'Cookie' => @cookie
293
+ }
294
+
295
+ response = http.post('/tgi/ioControl.tgi', post.body, headers)
296
+
297
+ #puts response.code
298
+ if(response.code.to_i == 200)
299
+ if outlet.class == Array
300
+ outlet.each { |o| @status[o-1] = (state == "On" ? 0 : 1) }
301
+ else
302
+ @status[outlet-1] = (state == "On" ? 0 : 1)
303
+ end
304
+ end
305
+ end
306
+ end
307
+
308
+ #chonge_state1 takes arguments
309
+ # outlet, being the relay to change the state of power to the relay
310
+ #Uses SetIO. Note: changes are lost after power cycle of the 9202.
311
+ def tmp_change_state(outlet, state)
312
+ if outlet.class == Array
313
+ get_str = "/SetIO?"
314
+ outlet.each_with_index do |o,i|
315
+ get_str += "+" if i > 0
316
+ get_str += "P6#{o}=#{state}"
317
+ end
318
+ else
319
+ get_str = "/SetIO?P6#{outlet}=#{state}"
320
+ end
321
+
322
+ Net::HTTP.start(@host) do |http|
323
+ request = Net::HTTP::Get.new(get_str)
324
+ request.basic_auth @user, @password
325
+ response = http.request(request)
326
+ if response.code.to_i == 200
327
+ #print response.body
328
+ if outlet.class == Array
329
+ outlet.each { |o| @status[o-1] = state }
330
+ else
331
+ @status[outlet-1] = state
332
+ end
333
+
334
+ else
335
+ #print "Connection failed with error #{response.code}\n"
336
+ raise "Connection failed with error #{response.code}\n"
337
+ end
338
+ end
339
+ end
340
+
341
+ #Authenticates to the IP Powercontroller's web server
342
+ #Credentials were passed in to PowerController.new()
343
+ def login #web interface needs a special login
344
+ res = Net::HTTP.new(@host, 80).start do |http|
345
+ response = http.get("/")
346
+ if response.code.to_i == 200
347
+ challenge = response.body.scan(/NAME=\"Challenge\" VALUE=\n\"(.*)\">/)
348
+ else
349
+ #print "Connection failed with error #{response.code}\n"
350
+ raise "Connection failed with error #{response.code}\n"
351
+ return
352
+ end
353
+
354
+ #authorize
355
+ post = Net::HTTP::Post.new('/tgi/login.tgi')
356
+ post.set_form_data( {"Submitbtn" => "OK", "Username" => "admin", "Password" => "",
357
+ "Challenge" => "", "Response" => Digest::MD5.hexdigest("admin" + @password + challenge.to_s)} )
358
+
359
+ response = http.request(post)
360
+ if response == nil
361
+ raise "Failed: no response"
362
+ elsif response.code.to_i == 200
363
+ if (response_text = response.response['set-cookie']) != nil
364
+ @cookie = response_text.split(';')[0]
365
+ else
366
+ raise "Failed"
367
+ end
368
+ else
369
+ raise "Failed: #{response.code}"
370
+ end
371
+ #puts @cookie
372
+ end
373
+ end
374
+
375
+ # Sets up the p6 array with the devices active ports. Mine has only 4 of 8 available.
376
+ def set_p6
377
+ p6 = ["On","On","On","On","On","On","On","On"]
378
+ @status.each_with_index { |x,i| p6[@portmap[i+1]] = x == 1 ? "Off" : "On" }
379
+ return p6
380
+ end
381
+ end
382
+
data/test/test.rb ADDED
@@ -0,0 +1,56 @@
1
+ require '../lib/powercontroller9202.rb'
2
+
3
+ #Default to relay off state being a power on state
4
+ pc = PowerController9202.new("192.168.249.128", "admin", "xxxxx")
5
+
6
+ #change so relay off state is a power off state
7
+ #pc = PowerController9202.new("192.168.249.128", "admin", "xxxxxx", false)
8
+
9
+ #8 relays, not 4
10
+ #relay off state is a power on state
11
+ #pc = PowerController9202.new("192.168.249.128", "admin", "xxxxxx", true, 8)
12
+
13
+ #Manually set the portmap. Nb portmap[0] is unused.
14
+ #pc = PowerController9202.new("192.168.249.128", "admin", "xxxxxx")
15
+ #pc.portmap = [0,0,2,5,7,1,3,4,6]
16
+ #pc.set_status #to update the status bitmap
17
+
18
+
19
+ puts pc.status.to_s #current relay states as array of 0's and 1's for relay off and on
20
+ puts pc.to_s(['server', 'modem', 'lights', 'tv']) #outputs relay status with names.
21
+ puts pc #Prints the relay status (Equivalent to puts pc.to_s )
22
+
23
+ ######################### EXIT ########################
24
+ exit #currently testing against an installed controller , as the test version failed.
25
+
26
+ #Power on means the relay switch the power on, even if the relay power is off
27
+ #Relay on, means the relay is powered, but that might mean the power is then off.
28
+ pc.ensureon #Turns all relays to the power on state (not saved)
29
+ pc.off([2,4]) #Turns relays 2 and 4 power off (not saved)
30
+ pc.on([2,4]) #Turns relays 2 and 4 power on (not saved)
31
+
32
+
33
+ pg.toggle_all #Turns power off for 5 seconds through all relays (understands my off is on)
34
+ pg.toggle_all(10) #Turns power on for 10 seconds through all relays (understands my off is on)
35
+
36
+
37
+ pc.toggle(1) #Turns power off for 5 seconds through relay 1(understands my off is on).
38
+ pc.toggle(1,10) #Turns power off for 10 seconds through relay 1 (understands my off is on)
39
+
40
+ pc.toggle([1,4]) #Turns power off for 5 seconds through relay 1 & 4 (understands my off is on)
41
+ pc.toggle([2,3],10) #Turns power off for 10 seconds through relays 2 & 3 (understands my off is on).
42
+
43
+ #Via the web form, rather thon SetIO
44
+ pc.reset_all #Sets relays to off state (Relays off, not necessarily power off)
45
+ #For mine, that is an on state as I want the failure state to be on
46
+ #The web interface shows them as off though.
47
+
48
+ #Via the web form, rather thon SetIO
49
+ pc.timer_toggle_all #Turns off the relays, then on again after 5 seconds
50
+ pc.timer_toggle_all(10) #Turns off the relays, then on again after 10 seconds
51
+
52
+ #Via the web form, rather thon SetIO
53
+ pc.on2(3) #Turns relay 3 power on and it shows up that way in the web interface.
54
+ #Hence will be set this way after the 9202 is power cycled.
55
+ pc.off2(2) #Turns relay 2 power off and it shows up that way in the web interface.
56
+ #Hence will be set this way after the 9202 is power cycled.
metadata ADDED
@@ -0,0 +1,90 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: powercontroller9202
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.2
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Rob Burrowes
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-01-10 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rdoc
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '3.10'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: '3.10'
30
+ - !ruby/object:Gem::Dependency
31
+ name: hoe
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: '3.1'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: '3.1'
46
+ description: A Ruby GEDCOM to communicate with an Aviosys Inc. 9202 IP Power Controller
47
+ (and associated products (eg 9212)).
48
+ email:
49
+ - r.burrowes@auckland.ac.nz
50
+ executables: []
51
+ extensions: []
52
+ extra_rdoc_files:
53
+ - History.txt
54
+ - Manifest.txt
55
+ - README.txt
56
+ files:
57
+ - History.txt
58
+ - Manifest.txt
59
+ - README.txt
60
+ - Rakefile
61
+ - lib/powercontroller9202.rb
62
+ - test/test.rb
63
+ - .gemtest
64
+ homepage: https://github.com/rbur004/powercontroller9202
65
+ licenses: []
66
+ post_install_message:
67
+ rdoc_options:
68
+ - --main
69
+ - README.txt
70
+ require_paths:
71
+ - lib
72
+ required_ruby_version: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ required_rubygems_version: !ruby/object:Gem::Requirement
79
+ none: false
80
+ requirements:
81
+ - - ! '>='
82
+ - !ruby/object:Gem::Version
83
+ version: '0'
84
+ requirements: []
85
+ rubyforge_project: powercontroller9202
86
+ rubygems_version: 1.8.24
87
+ signing_key:
88
+ specification_version: 3
89
+ summary: A Ruby GEDCOM to communicate with an Aviosys Inc
90
+ test_files: []