--- /dev/null
+#!/usr/bin/python
+# $Id$
+import socket
+import logging
+
+class Netzdose:
+ """Netzwerksteckdose aus der c't"""
+ START_CMD = 0x41
+ STOP_CMD = 0x42
+
+ CMD_READRELAIS = 0x81
+ CMD_SETRELAIS = 0x80
+
+ CMD_LENGTH = 8
+
+ def __init__(self, host='morefx.dyndns.org', port=10001):
+ self.host = host
+ self.port = port
+ self.connected = False
+ socket.setdefaulttimeout(10)
+
+ def connect(self):
+ """Baue die Verbindung zum Netzwerkstecker auf"""
+ log = logging.getLogger()
+ if self.connected:
+ log.info("Wir sind schon mit jemandem verbunden.")
+ return True
+ try:
+ self.socket = socket.socket()
+ self.socket.connect( (socket.gethostbyname(self.host), self.port) )
+ self.connected = True
+ except Exception, e:
+ log = logging.getLogger()
+ log.error("Fehler beim Verbinden mit %s:%s %s" % (self.host, self.port, e) )
+ self.connected = False
+ return False
+ return True
+
+ def disconnect(self):
+ """Unterbreche die Verbindung zum Netzwerkstecker"""
+ log = logging.getLogger()
+ if self.connected:
+ try:
+ self.socket.close()
+ except Exception, e:
+ log.error("Konnte Socket nicht richtig schliessen: %s" % (e) )
+ self.connected = False
+
+ def setRelais(self, relais, disconnect = True):
+ """Setze das Relais mit der Nummer 'nummer'"""
+ log = logging.getLogger()
+ try:
+ state = self.readRelais(disconnect=False)
+ position = (1<<relais)
+ if state & position:
+ state = state & (~position)
+ else:
+ state = state | position
+ relaisCmd = "%c%c%c\0\0\0\0%c" % (Netzdose.START_CMD, Netzdose.CMD_SETRELAIS, state, Netzdose.STOP_CMD)
+ if self.connect():
+ try:
+ log.info("sende an %s den Befehl %s" % (self.host, relaisCmd))
+ self.socket.send(relaisCmd)
+ answer = self.socket.recv(Netzdose.CMD_LENGTH)
+ except Exception, e:
+ log.error("Fehler beim Versenden: %s" % (e) )
+ else:
+ log.info("Habe %s erhalten" % answer)
+ if disconnect: self.disconnect()
+ except Exception, e:
+ log.error("Fehler beim Schalten von Relais %s: %s" % (relais, e) )
+
+ def readRelais(self, relais = False, disconnect = True):
+ """Lese das Relais mit der Nummer 'relais'
+ oder kompletten Status, wenn keine Nummer mitgegeben
+ """
+ log = logging.getLogger()
+ relaisCmd = "%c%c\0\0\0\0\0%c" % (Netzdose.START_CMD, Netzdose.CMD_READRELAIS, Netzdose.STOP_CMD)
+ answer = 0
+ try:
+ if self.connect():
+ log.info("Sende an %s den Befehl %s" % (self.host, relaisCmd))
+ self.socket.send(relaisCmd)
+ answer = self.socket.recv(Netzdose.CMD_LENGTH)
+ if disconnect: self.disconnect()
+ except Exception, e:
+ log.error("Fehler beim Lesen des Relais %s: %s" % (relais, e))
+ raise("Relaislesefehler")
+ if relais:
+ log.info("Gebe Zustand fuer Relais %s aus: %s" % (nummer, ord(answer[2] & (1<<relais))) )
+ return ord(answer[2]) & (1<<relais)
+ else:
+ log.info("Gebe Zustand fuer alle Relais aus: %s" % ord(answer[2]) )
+ return ord(answer[2])
+
+ def __str__(self):
+ log = logging.getLogger()
+ stateStr = ""
+ try:
+ state = self.readRelais()
+ for i in range(0,7):
+ if state & (1<<i):
+ stateStr += 'x'
+ else:
+ stateStr += '0'
+ except Exception, e:
+ log.error("Fehler beim holen des Status: %s", e)
+ stateStr = "-FEHLER-"
+ return "%s:%s => %s" % (self.host, self.port, stateStr)
+
+if __name__ == '__main__':
+ """Testen, ob die Klasse funzt"""
+ import time
+
+ # Initialisiere den Logger
+ logging.basicConfig(level = logging.INFO)
+
+ # hole eine Standard Netzdose (steht bei Christian)
+ box = Netzdose()
+
+ print box
+ time.sleep(0.5)
+
+ # Lese den Zustand aus
+ state = box.readRelais(disconnect=False)
+ for i in range(0,7):
+ if (state & (1<<i)):
+ print "Schalter %s ist an" % i
+ else:
+ print "Schalter %s ist aus" % i
+
+ print "Toggle Relais 0"
+ box.setRelais(relais = 0,disconnect=False)
+
+ # und lese den Zustand erneut aus
+ state = box.readRelais()
+ for i in range(0,7):
+ if (state & (1<<i)):
+ print "Schalter %s ist an" % i
+ else:
+ print "Schalter %s ist aus" % i