remove unnecessary debug messages
[pcucontrol.git] / pcucontrol / models / IPAL.py
1 from pcucontrol.reboot import *
2
3 class IPAL(PCUControl):
4         """ 
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!
8         """
9         supported_ports = [9100,23,80]
10
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))
14         
15         def recv_noblock(self, s, count):
16                 import errno
17
18                 try:
19                         # TODO: make sleep backoff, before stopping.
20                         time.sleep(8)
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])
28                         else:
29                                 # TODO: not other exceptions.
30                                 raise Exception(e)
31                 return ret
32
33         #def run(self, node_port, dryrun):
34         #       if self.type == Transport.IPAL:
35         #               ret = self.run_ipal(node_port, dryrun)
36         #               if ret != 0:
37         #                       ret2 = self.run_telnet(node_port, dryrun)
38         #                       if ret2 != 0:
39         #                               return ret
40         #                       return ret2
41         #               return ret
42         #       elif self.type == Transport.TELNET:
43         #               return self.run_telnet(node_port, dryrun)
44         #       else:
45         #               raise ExceptionNoTransport("Unimplemented Transport for IPAL")
46         
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)
52                 self.transport.ifThenSend("Password >", "\r\n\r\n", ExceptionNotFound)
53                 # Login
54                 self.transport.ifThenSend("Password >", self.password, ExceptionPassword)
55                 self.transport.write("\r\n\r\n")
56                 if not dryrun: # P# - Pulse relay
57                         #print "node_port %s" % node_port
58                         self.transport.ifThenSend("Enter >", 
59                                                         "P%s"%node_port, 
60                                                         ExceptionNotFound)
61                         #print "send newlines"
62                         self.transport.write("\r\n\r\n")
63                         #print "after new lines"
64                 # Get the next prompt
65                 #print "wait for enter"
66                 self.transport.ifElse("Enter >", ExceptionTimeout)
67                 #print "closing "
68                 self.transport.close()
69                 return 0
70
71         def run_ipal(self, node_port, dryrun):
72                 import errno
73
74                 power_on = False
75
76                 #print "open socket"
77                 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
78                 try:
79                         #print "connect"
80                         s.connect((self.host, 9100))
81                 except socket.error, e:
82                         s.close()
83                         if e[0] == errno.ECONNREFUSED:
84                                 # cannot connect to remote host
85                                 raise ExceptionNotFound(e[1])
86                         elif e[0] == errno.ETIMEDOUT:
87                                 raise ExceptionTimeout(e[1])
88                         else:
89                                 # TODO: what other conditions are there?
90                                 raise Exception(e)
91                                 
92                 # get current status
93                 #print "Checking status"
94                 s.send(self.format_msg("", 'O'))
95                 ret = self.recv_noblock(s, 8)
96                 #print "Current status is '%s'" % ret
97
98                 if ret == '':
99                         raise Exception("Status returned 'another session already open' on %s %s : %s" % (self.host, node_port, ret))
100                                 
101                 if node_port < len(ret):
102                         status = ret[node_port]
103                         if status == '1':
104                                 # up
105                                 power_on = True
106                         elif status == '0':
107                                 # down
108                                 power_on = False
109                         elif status == '6':
110                                 raise ExceptionPort("IPAL reported 'Cable Error' on %s socket %s : %s" % (self.host, node_port, ret))
111                         else:
112                                 raise Exception("Unknown status for PCU %s socket %s : %s" % (self.host, node_port, ret))
113                 else:
114                         raise Exception("Mismatch between configured port and PCU %s status: %s %s" % (self.host, node_port, ret))
115                         
116
117                 if not dryrun:
118                         if power_on:
119                                 #print "Pulsing %s" % node_port
120                                 s.send(self.format_msg("%s" % node_port, 'P'))
121                         else:
122                                 # NOTE: turn power on ; do not pulse the port.
123                                 #print "Power was off, so turning on ..."
124                                 s.send(self.format_msg("%s" % node_port, 'E'))
125                                 #s.send(self.format_msg("%s" % node_port, 'P'))
126
127                         #print "Receiving response."
128                         ret = self.recv_noblock(s, 8)
129                         #print "Current status is '%s'" % ret
130
131                         if node_port < len(ret):
132                                 status = ret[node_port]
133                                 if status == '1':
134                                         # up
135                                         power_on = True
136                                 elif status == '0':
137                                         # down
138                                         power_on = False
139                                 elif status == '6':
140                                         raise ExceptionPort("IPAL reported 'Cable Error' on %s socket %s : %s" % (self.host, node_port, ret))
141                                 else:
142                                         raise Exception("Unknown status for PCU %s socket %s : %s" % (self.host, node_port, ret))
143                         else:
144                                 raise Exception("Mismatch between configured port and PCU %s status: %s %s" % (self.host, node_port, ret))
145
146                         if power_on:
147                                 return 0
148                         else:
149                                 return "Failed Power On"
150
151                 s.close()
152                 return 0