First commit of lavapdu code
diff --git a/apcdrivers.py b/apcdrivers.py
new file mode 100644
index 0000000..b7e882f
--- /dev/null
+++ b/apcdrivers.py
@@ -0,0 +1,130 @@
+__author__ = 'matt'
+
+from driver import PDUDriver
+
+class apc7952(PDUDriver):
+    def _pdu_logout(self):
+        self._back_to_main()
+        print("Logging out")
+        self.connection.send("4\r")
+
+    def _back_to_main(self):
+        print("Returning to main menu")
+        self.connection.expect('>')
+        for i in range(1,20):
+            #print("Sending escape character")
+            self.connection.send("\x1B")
+            self.connection.send("\r")
+            res = self.connection.expect(["4- Logout","> "])
+            if res == 0:
+                print("Back at main menu")
+                break
+        #self.connection.send("\r")
+        #self.connection.expect("4- Logout")
+        #self.connection.expect("> ")
+
+    def _enter_outlet(self, outlet):
+        self.connection.expect("Press <ENTER> to continue...")
+        self.connection.send("\r")
+        self.connection.expect("> ")
+        self.connection.send(outlet)
+        self.connection.send("\r")
+
+    def _port_interaction(self, command, port_number):
+        print("Attempting command: %s port: %i" % (command, port_number))
+        ### make sure in main menu here
+        self._back_to_main()
+        self.connection.send("\r")
+        self.connection.expect("1- Device Manager")
+        self.connection.expect("> ")
+        self.connection.send("1\r")
+        res = self.connection.expect(["3- Outlet Control/Configuration","2- Outlet Control","2- Outlet Management"])
+        if res == 0:
+            self.connection.send("3\r")
+            self._enter_outlet(port_number)
+        elif res == 1:
+            self.connection.send("2\r")
+            self._enter_outlet(port_number)
+        elif res == 2:
+            self.connection.send("2\r")
+        res = self.connection.expect(["1- Control Outlet", "1- Outlet Control/Configuration"])
+        self.connection.expect("> ")
+        self.connection.send("1\r")
+        res = self.connection.expect(["> ","Press <ENTER> to continue..."])
+        if res == 1:
+            print("Stupid paging thingmy detected, pressing enter")
+            self.connection.send("\r")
+        print("We should now be at the outlet list")
+        self.connection.send("%s\r" % port_number)
+        self.connection.send("1\r")
+        self.connection.expect("3- Immediate Reboot")
+        self.connection.expect("> ")
+        if command == "reboot":
+            self.connection.send("3\r")
+            self.connection.expect("Immediate Reboot")
+            self._do_it()
+        elif command == "delayed":
+            self.connection.send("6\r")
+            self.connection.expect("Delayed Reboot")
+            self._do_it()
+        elif command == "on":
+            self.connection.send("1\r")
+            self.connection.expect("Immediate On")
+            self._do_it()
+        elif command == "off":
+            self.connection.send("2\r")
+            self.connection.expect("Immediate Off")
+            self._do_it()
+        else:
+            print("Unknown command!")
+
+    def _do_it(self):
+        self.connection.expect("Enter 'YES' to continue or <ENTER> to cancel :")
+        self.connection.send("YES\r")
+        self.connection.expect("Press <ENTER> to continue...")
+        self.connection.send("\r")
+
+    def port_delayed(self, port_number):
+        self._port_interaction("delayed", port_number)
+
+    def port_on(self, port_number):
+        self._port_interaction("on", port_number)
+
+    def port_off(self, port_number):
+        self._port_interaction("off", port_number)
+
+    def port_reboot(self, port_number):
+        self._port_interaction("reboot", port_number)
+
+class apc8959(PDUDriver):
+    connection = None
+
+    def _pdu_logout(self):
+        print("logging out")
+        self.connection.send("\r")
+        self.connection.send("exit")
+        self.connection.send("\r")
+        print("done")
+
+    def _pdu_get_to_prompt(self):
+        self.connection.send("\r")
+        self.connection.expect ('apc>')
+
+    def _port_interaction(self, command, port_number):
+        print("Attempting %s on port %i" % (command, port_number))
+        self._pdu_get_to_prompt()
+        self.connection.sendline(self.pdu_commands[command] + (" %i" % port_number))
+        self.connection.expect("E000: Success")
+        print("done")
+
+    def port_delayed(self, port_number):
+        self._port_interaction("delayed", port_number)
+
+    def port_on(self, port_number):
+        self._port_interaction("on", port_number)
+
+    def port_off(self, port_number):
+        self._port_interaction("off", port_number)
+
+    def port_reboot(self, port_number):
+        self._port_interaction("reboot", port_number)
\ No newline at end of file
diff --git a/driver.py b/driver.py
new file mode 100644
index 0000000..ca840be
--- /dev/null
+++ b/driver.py
@@ -0,0 +1,9 @@
+__author__ = 'matt'
+
+class PDUDriver():
+    connection = None
+    pdu_commands = {"off":"olOff","on":"olOn","reboot":"olReboot","delayed":"olDlyReboot"}
+
+    def __init__(self, connection):
+        self.connection = connection
+
diff --git a/engine.py b/engine.py
new file mode 100644
index 0000000..4f18c2e
--- /dev/null
+++ b/engine.py
@@ -0,0 +1,65 @@
+import pexpect
+import sys
+import os
+from apcdrivers import apc8959
+from apcdrivers import apc7952
+
+class PDUEngine():
+    connection = None
+    pdu_commands = {"off":"olOff","on":"olOn","reboot":"olReboot","delayed":"olDlyReboot"}
+    prompt = 0
+    driver = None
+
+    def __init__(self, pdu_hostname, pdu_telnetport = 23):
+        self.connection = pexpect.spawn("/usr/bin/telnet %s %d" % (pdu_hostname, pdu_telnetport))
+        #self.connection.logfile_read = sys.stdout
+        self._pdu_login("apc","apc")
+        if self.prompt == 0:
+            print("Found a v5 prompt")
+            self.driver = apc8959(self.connection)
+        elif self.prompt == 1:
+            print("Found a v3 prompt")
+            self.driver = apc7952(self.connection)
+        else:
+            print("Unknown prompt!")
+
+    def is_busy(self):
+        if os.path.exists("/proc/%i" % self.connection.pid):
+            return True
+        return False
+
+    def close(self):
+        self.driver._pdu_logout()
+        self.connection.close(True)
+
+    def _pdu_login(self, username, password):
+        print("attempting login with username %s, password %s" % (username,password))
+        self.connection.send("\r")
+        self.connection.expect ("User Name :")
+        self.connection.send("apc\r")
+        self.connection.expect("Password  :")
+        self.connection.send("apc\r")
+        self.prompt = self.connection.expect(["apc>", ">"])
+        #print("prompt: %s" % self.prompt)
+
+
+if __name__ == "__main__":
+    pe1 = PDUEngine("pdu15")
+    pe1.driver.port_off(22)
+    pe1.driver.port_on(22)
+    pe1.close()
+    pe2 = PDUEngine("pdu14")
+    pe2.driver.port_off(6)
+    pe2.driver.port_on(6)
+    pe2.close()
+    pe3 = PDUEngine("pdu01")
+    pe3.driver.port_reboot(1)
+    pe3.driver.port_off(1)
+    pe3.driver.port_on(1)
+    pe3.close()
+    pe4 = PDUEngine("pdu02")
+    pe4.driver.port_reboot(8)
+    pe4.driver.port_off(8)
+    pe4.driver.port_on(8)
+    pe4.close()
+
diff --git a/pdurunner.py b/pdurunner.py
new file mode 100644
index 0000000..28a9d6e
--- /dev/null
+++ b/pdurunner.py
@@ -0,0 +1,45 @@
+import sqlite3
+import time
+from engine import PDUEngine
+
+
+conn = sqlite3.connect('pdu.db', check_same_thread = False)
+c = conn.cursor()
+
+class PDURunner():
+    def get_one(self):
+        c.execute("SELECT * FROM pdu_queue ORDER BY id asc limit 1")
+        res = c.fetchone()
+        if res:
+            id,hostname,port,request = res
+            print(id, hostname, request, port)
+            res = self.do_job(hostname,port,request)
+            self.delete_row(id)
+
+    def delete_row(self, id):
+        print("deleting row %i" % id)
+        c.execute("delete from pdu_queue where id=%i" % id)
+        conn.commit()
+
+    def do_job(self, hostname, port, request):
+        pe = PDUEngine(hostname, 23)
+        if request == "reboot":
+            pe.driver.port_reboot(port)
+        elif request == "on":
+            pe.driver.port_on(port)
+        elif request == "off":
+            pe.driver.port_off(port)
+        elif request == "delayed":
+            pe.driver.port_delayed(port)
+        else:
+            print("Unknown request type: %s" % request)
+
+    def run_me(self):
+        print("Starting up the PDURunner")
+        while 1:
+            self.get_one()
+            time.sleep(1)
+
+if __name__ == "__main__":
+    p = PDURunner()
+    p.run_me()
\ No newline at end of file
diff --git a/socketserver.py b/socketserver.py
new file mode 100644
index 0000000..bf72fd7
--- /dev/null
+++ b/socketserver.py
@@ -0,0 +1,57 @@
+import SocketServer
+import sqlite3
+import logging
+
+logging.basicConfig(level=logging.DEBUG)
+log = logging.getLogger(__name__)
+conn=sqlite3.connect('pdu.db', check_same_thread = False)
+c=conn.cursor()
+
+class ListenerServer():
+    HOST='0.0.0.0'
+    PORT=16421
+
+    def __init__(self):
+        ### read loglevel here
+        self.server = TCPServer((self.HOST, self.PORT), TCPRequestHandler)
+        log.info("listening on %s:%s" % (self.HOST, self.PORT))
+        self.create_db()
+
+    def create_db(self):
+        sql = "create table if not exists pdu_queue (id integer primary key, hostname text, port int, request text)"
+        log.debug("Creating pdu_queue table: %s" % sql)
+        c.execute(sql)
+        conn.commit()
+
+    def start(self):
+        print("Starting the ListenerServer")
+        self.server.serve_forever()
+
+class TCPRequestHandler(SocketServer.BaseRequestHandler):
+    "One instance per connection.  Override handle(self) to customize action."
+    def insert_request(self, data):
+        array = data.split(" ")
+        hostname = array[0]
+        port = int(array[1])
+        request = array[2]
+        sql = "insert into pdu_queue values (NULL,'%s',%i,'%s')" % (hostname,port,request)
+        log.debug("executing sql: %s" % sql)
+        c.execute(sql)
+        conn.commit()
+
+    def handle(self):
+        data = self.request.recv(4096).strip()
+        #write to sql db here
+        log.debug("got request: %s" % data)
+        self.insert_request(data)
+        self.request.sendall("ack\n")
+        self.request.close()
+
+class TCPServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
+    allow_reuse_address = True
+    daemon_threads = True
+    pass
+
+if __name__ == "__main__":
+    ss = ListenerServer()
+    ss.start()
\ No newline at end of file