1 from pcucontrol.reboot import *
3 class IPAL(PCUControl):
5 This now uses a proprietary format for communicating with the PCU. I
6 prefer it to Telnet, and Web access, since it's much lighter weight
7 and, more importantly, IT WORKS!! HHAHHHAHAHAHAHAHA!
9 supported_ports = [9100,23,80]
11 def format_msg(self, data, cmd):
12 esc = chr(int('1b',16))
13 return "%c%s%c%s%c" % (esc, self.password, esc, data, cmd) # esc, 'q', chr(4))
15 def recv_noblock(self, s, count):
19 # TODO: make sleep backoff, before stopping.
21 ret = s.recv(count, socket.MSG_DONTWAIT)
22 except socket.error, e:
23 if e[0] == errno.EAGAIN:
24 #raise Exception(e[1])
25 raise ExceptionNotFound(e[1])
26 elif e[0] == errno.ETIMEDOUT:
27 raise ExceptionTimeout(e[1])
29 # TODO: not other exceptions.
33 #def run(self, node_port, dryrun):
34 # if self.type == Transport.IPAL:
35 # ret = self.run_ipal(node_port, dryrun)
37 # ret2 = self.run_telnet(node_port, dryrun)
42 # elif self.type == Transport.TELNET:
43 # return self.run_telnet(node_port, dryrun)
45 # raise ExceptionNoTransport("Unimplemented Transport for IPAL")
47 def run_telnet(self, node_port, dryrun):
48 # TELNET version of protocol...
49 self.transport.open(self.host)
50 ## XXX Some iPals require you to hit Enter a few times first
51 self.transport.ifThenSend("Password >", "\r\n\r\n", ExceptionNotFound)
53 self.transport.ifThenSend("Password >", self.password, ExceptionPassword)
54 self.transport.write("\r\n\r\n")
55 if not dryrun: # P# - Pulse relay
56 print "node_port %s" % node_port
57 self.transport.ifThenSend("Enter >",
61 self.transport.write("\r\n\r\n")
62 print "after new lines"
64 print "wait for enter"
65 self.transport.ifElse("Enter >", ExceptionTimeout)
67 self.transport.close()
70 def run_ipal(self, node_port, dryrun):
76 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
79 s.connect((self.host, 9100))
80 except socket.error, e:
82 if e[0] == errno.ECONNREFUSED:
83 # cannot connect to remote host
84 raise ExceptionNotFound(e[1])
85 elif e[0] == errno.ETIMEDOUT:
86 raise ExceptionTimeout(e[1])
88 # TODO: what other conditions are there?
92 print "Checking status"
93 s.send(self.format_msg("", 'O'))
94 ret = self.recv_noblock(s, 8)
95 print "Current status is '%s'" % ret
98 raise Exception("Status returned 'another session already open' on %s %s : %s" % (self.host, node_port, ret))
100 if node_port < len(ret):
101 status = ret[node_port]
109 raise ExceptionPort("IPAL reported 'Cable Error' on %s socket %s : %s" % (self.host, node_port, ret))
111 raise Exception("Unknown status for PCU %s socket %s : %s" % (self.host, node_port, ret))
113 raise Exception("Mismatch between configured port and PCU %s status: %s %s" % (self.host, node_port, ret))
118 print "Pulsing %s" % node_port
119 s.send(self.format_msg("%s" % node_port, 'P'))
121 # NOTE: turn power on ; do not pulse the port.
122 print "Power was off, so turning on ..."
123 s.send(self.format_msg("%s" % node_port, 'E'))
124 #s.send(self.format_msg("%s" % node_port, 'P'))
126 print "Receiving response."
127 ret = self.recv_noblock(s, 8)
128 print "Current status is '%s'" % ret
130 if node_port < len(ret):
131 status = ret[node_port]
139 raise ExceptionPort("IPAL reported 'Cable Error' on %s socket %s : %s" % (self.host, node_port, ret))
141 raise Exception("Unknown status for PCU %s socket %s : %s" % (self.host, node_port, ret))
143 raise Exception("Mismatch between configured port and PCU %s status: %s %s" % (self.host, node_port, ret))
148 return "Failed Power On"