diff options
author | Ebus-at-dockstar <ebus@dockstar> | 2013-03-25 10:24:28 +0100 |
---|---|---|
committer | Ebus-at-dockstar <ebus@dockstar> | 2013-03-25 10:24:43 +0100 |
commit | 862282ce99760832d3e9e5b4b1171b861105e004 (patch) | |
tree | 0e229418e391917b79d42a8bdee46fb7a8612895 /heap/ebus/__init__.py | |
parent | 9522cdffa94f278eb5e1894600535986e22c2890 (diff) | |
download | ebus-alt-862282ce99760832d3e9e5b4b1171b861105e004.tar.gz ebus-alt-862282ce99760832d3e9e5b4b1171b861105e004.zip |
move old stuff away
Diffstat (limited to 'heap/ebus/__init__.py')
-rw-r--r-- | heap/ebus/__init__.py | 172 |
1 files changed, 172 insertions, 0 deletions
diff --git a/heap/ebus/__init__.py b/heap/ebus/__init__.py new file mode 100644 index 0000000..8d4e6ac --- /dev/null +++ b/heap/ebus/__init__.py @@ -0,0 +1,172 @@ +# -*- coding: utf-8 -*- +import asynchat +import asyncore +import socket +import sys +import logging + +import os +from lxml import objectify +from lxml import etree + +logger = logging.getLogger("ebus.core") +logger.setLevel(logging.INFO) + +class UnknownPacketException(Exception): + pass + +class EbusPacket(object): + EBUS_SPECIFICATION = os.path.join(os.path.dirname(__file__), "ebus_specification.xml") + ebus_xml = objectify.parse(open(EBUS_SPECIFICATION)) + + @staticmethod + def address_to_type(address): + d=[dev.get("type") for dev in EbusPacket.ebus_xml.xpath("/ebus/devices/device[@address=$address]", + address="#x%.2x"%address)] + return len(d)>0 and d[0] or None + + def __init__(self, source, destination, primary_command, secondary_command): + self.source = source + self.destination = destination + self.primary_command = primary_command + self.secondary_command = secondary_command + + def __str__(self): + #XXX self.length only in subclasses + return "<%-18s name=\"%s\" source=\"0x%.2x\" destination=\"0x%.2x\" primary=0x%x secondary=0x%x length=0x%x>" % \ + (self.__class__.__name__, self.name(), self.source, self.destination, \ + self.primary_command, self.secondary_command, self.length) + + def get_packet_description(self): + p=EbusPacket.ebus_xml.xpath("/ebus/packets/packet[@primary=$primary and @secondary=$secondary]", + primary="#x%.2x"%self.primary_command, + secondary="#x%.2x"%self.secondary_command) + if len(p)>0 and p[0] is not None: + return p[0] + else: + raise UnknownPacketException("Unknown Packet, primary_command=#x%.2x secondary_command=#x%.2x" % ( + self.primary_command, + self.secondary_command)) + + def get_source_name(self): + s=EbusPacket.ebus_xml.xpath("/ebus/devices/device[@address=$address]", + address="#x%.2x"%self.source) + return len(s)>0 and s[0].get("name") or None + + def get_destination_name(self): + d=EbusPacket.ebus_xml.xpath("/ebus/devices/device[@address=$address]", + address="#x%.2x"%self.destination) + return len(d)>0 and d[0].get("name") or None + + def name(self): + return self.get_packet_description().get("name") + + def description(self): + return self.get_packet_description().get("description") + + +class EbusMasterMaster(EbusPacket): + def __init__(self, source, destination, primary_command, secondary_command, data): + EbusPacket.__init__(self, source, destination, primary_command, secondary_command) + self.length = len(data) + self.data = data + +class EbusMasterSlave(EbusPacket): + def __init__(self, source, destination, primary_command, secondary_command, request, response): + EbusPacket.__init__(self, source, destination, primary_command, secondary_command) + self.length = len(request) + self.request = request + self.response = response + + self.data = self.request #XXX + +class EbusBroadcast(EbusPacket): + def __init__(self, source, destination, primary_command, secondary_command, data): + EbusPacket.__init__(self, source, destination, primary_command, secondary_command) + self.length = len(data) + self.data = data + + +class EbusReader(asynchat.async_chat): + def __init__(self): + asynchat.async_chat.__init__(self) + self.set_terminator("") + self.create_socket(socket.AF_INET, socket.SOCK_STREAM) + self.connect(("10.2.2.200", 7970)) + + self.packetIndex = 0 + self.buf = "" + self.debug = False + + def collect_incoming_data(self,data): + for it in range(len(data)): + if data[it] == "\xaa": + if it+1 < len(data) and data[it+1] != "\xaa": + self._parse(self.buf) + self.buf = "" + self.packetIndex = 0 + else: + self.buf += data[it] + self.packetIndex = self.packetIndex + 1 + #print "%.2x [%d]" % (ord(data[it]),self.packetIndex) + + def _parse(self,dataRaw): + #0xaa bug + i = 0 + data = "" + while (i+1) < len(dataRaw): + if ord(dataRaw[i]) == 0xa9 and ord(dataRaw[i+1]) == 0x01: + data += "\xaa" + i = i + 1 + elif ord(dataRaw[i]) == 0xa9 and ord(dataRaw[i+1]) == 0x00: + data += "\xa9" + i = i + 1 + else: + data += dataRaw[i] + i = i + 1 + + if len(data) < 2: + logger.critical("Daten Gaga") + return + source = ord(data[0]) + sourceType = EbusPacket.address_to_type(source) + destination = ord(data[1]) + destinationType = EbusPacket.address_to_type(destination) + + if len(data) < 9: + logger.critical("Unvollständige Daten") + return + + primaryCommand = ord(data[2]) + secondaryCommand = ord(data[3]) + payloadLength = ord(data[4]) + payload = data[5:5+payloadLength] + + if self.debug: + print "\033[1;31m%.2x %.2x\033[1;m \033[1;33m%.2x %.2x\033[1;m \033[1;30m%.2x\033[1;m \033[1;45m%s\033[1;m" % ( + source, + destination, + primaryCommand, + secondaryCommand, + payloadLength, + " ".join(map(lambda byte: "%.2x"%ord(byte), payload))) + + + try: + if sourceType == 'master' and destinationType == 'master': + p = EbusMasterMaster(source, destination, primaryCommand, secondaryCommand, payload) + self.handle_ebus(p) + elif sourceType == 'master' and destinationType == 'slave': + p = EbusMasterSlave(source, destination, primaryCommand, secondaryCommand, payload, None) #FIXME + logger.info("SKIP MASTER-SLAVE") + elif sourceType == 'master' and destinationType == 'broadcast': + p = EbusBroadcast(source, destination, primaryCommand, secondaryCommand, payload) + self.handle_ebus(p) + else: + logger.warning("SKIP source=%s sourceType=%s destination=%s destType=%s" % \ + (source, sourceType, destination, destinationType)) + except UnknownPacketException,e: + print e + + def handle_ebus(self,ebus_packet): + logger.critical("unhandled ebus_packet") |