diff options
author | yvesf <yvesf-git@xapek.org> | 2010-08-15 22:54:27 +0200 |
---|---|---|
committer | yvesf <yvesf-git@xapek.org> | 2010-08-15 22:54:27 +0200 |
commit | 7ff580a6fe60f7e3ea160f7b181ff0fa934453ce (patch) | |
tree | 55ea82fdffaaf50ed099f3bc663cb083952d1fc5 | |
parent | 3e70cb0892a703888e913ee5a1545f488a22a4a3 (diff) | |
download | ebus-alt-7ff580a6fe60f7e3ea160f7b181ff0fa934453ce.tar.gz ebus-alt-7ff580a6fe60f7e3ea160f7b181ff0fa934453ce.zip |
So 15. Aug 22:54:27 CEST 2010
-rwxr-xr-x | bin/ebus_dump.py | 28 | ||||
-rw-r--r-- | ebus/__init__.py | 51 | ||||
-rw-r--r-- | ebus/model/__init__.py | 19 | ||||
-rw-r--r-- | ebus/model/sql.py | 95 |
4 files changed, 111 insertions, 82 deletions
diff --git a/bin/ebus_dump.py b/bin/ebus_dump.py index bfae56e..a437b0d 100755 --- a/bin/ebus_dump.py +++ b/bin/ebus_dump.py @@ -2,15 +2,33 @@ # -*- coding:utf8 -*- import asyncore from ebus import EbusReader +from ebus.model.sql import ModelBase, EbusSQL, Value +from ebus.model.sql import EbusSQL +from sqlalchemy import create_engine +from sqlalchemy.orm import sessionmaker + +engine = create_engine('sqlite:///:memory:', echo=True) +#engine = create_engine("postgresql://yvesf:iii@10.2.2.13:5432/yvesf", echo=True) + +ModelBase.metadata.create_all(engine) + +Session = sessionmaker() +Session.configure(bind=engine) +session = Session() + class MyEbusReader(EbusReader): def __init__(self,*args,**kwargs): EbusReader.__init__(self,*args,**kwargs) - self.debug=True - + self.debug = True + self.sql = EbusSQL(session) def handle_ebus(self,ebus_packet): - if ebus_packet.values() != dict(): - print ebus_packet + for field in self.sql.get_values(ebus_packet): + session.add(field) MyEbusReader() -asyncore.loop() +try: + asyncore.loop() +except KeyboardInterrupt: + for data in session.query(Value).all(): + print data diff --git a/ebus/__init__.py b/ebus/__init__.py index 832e9ff..58192b9 100644 --- a/ebus/__init__.py +++ b/ebus/__init__.py @@ -8,13 +8,16 @@ import os from lxml import objectify from lxml import etree +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 EbusXMLMixin.ebus_xml.xpath("/ebus/devices/device[@address=$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 @@ -26,29 +29,28 @@ class EbusPacket(object): 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 %s>" % \ + 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, \ - " ".join(map(lambda name: "%s=%s" % (name, self.values()[name]),self.values()))) + self.primary_command, self.secondary_command, self.length) def get_packet_description(self): - p=EbusXMLMixin.ebus_xml.xpath("/ebus/packets/packet[@primary=$primary and @secondary=$secondary]", + 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 "Unknown Packet, primary_command=#x%.2 secondary_command=#x%.2" % ( + raise UnknownPacketException("Unknown Packet, primary_command=#x%.2x secondary_command=#x%.2x" % ( self.primary_command, - self.secondardy_command) + self.secondary_command)) def _get_source_name(self): - s=EbusXMLMixin.ebus_xml.xpath("/ebus/devices/device[@address=$address]", + s=EbusPacket.ebus_xml.xpath("/ebus/devices/device[@address=$address]", address="#x%.2x"%self.source) return len(s)>0 and s[0] or None def _get_destination_name(self): - d=EbusXMLMixin.ebus_xml.xpath("/ebus/devices/device[@address=$address]", + d=EbusPacket.ebus_xml.xpath("/ebus/devices/device[@address=$address]", address="#x%.2x"%self.destination) return len(d)>0 and d[0] or None @@ -123,9 +125,9 @@ class EbusReader(asynchat.async_chat): print "GAGA" return source = ord(data[0]) - sourceType = EbusXMLMixin.address_to_type(source) + sourceType = EbusPacket.address_to_type(source) destination = ord(data[1]) - destinationType = EbusXMLMixin.address_to_type(destination) + destinationType = EbusPacket.address_to_type(destination) if len(data) < 9: print >>sys.stderr, "Unvollständige Daten" @@ -146,18 +148,21 @@ class EbusReader(asynchat.async_chat): " ".join(map(lambda byte: "%.2x"%ord(byte), payload))) - 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 - print >>sys.stderr, "SKIP MASTER-SLAVE" - elif sourceType == 'master' and destinationType == 'broadcast': - p = EbusBroadcast(source, destination, primaryCommand, secondaryCommand, payload) - self.handle_ebus(p) - else: - print >>sys.stderr, "SKIP source=%s sourceType=%s destination=%s destType=%s" % \ - (source, sourceType, destination, destinationType) + 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 + print >>sys.stderr, "SKIP MASTER-SLAVE" + elif sourceType == 'master' and destinationType == 'broadcast': + p = EbusBroadcast(source, destination, primaryCommand, secondaryCommand, payload) + self.handle_ebus(p) + else: + print >>sys.stderr, "SKIP source=%s sourceType=%s destination=%s destType=%s" % \ + (source, sourceType, destination, destinationType) + except UnknownPacketException,e: + print e def handle_ebus(self,ebus_packet): print >>sys.stderr, "unhandled ebus_packet" diff --git a/ebus/model/__init__.py b/ebus/model/__init__.py index ecdf3bc..1e2d080 100644 --- a/ebus/model/__init__.py +++ b/ebus/model/__init__.py @@ -1,3 +1,4 @@ +# -*- coding:utf8 -*- class DataField(object): def __init__(self, name, offset): self.name = name @@ -5,20 +6,20 @@ class DataField(object): def value(self,data): raise NotImplemented() - class Data1b(DataField): - """ +class Data1b(DataField): + """ Beispiel für die Berechnung: if ((x & 80h) == 80h) // y negativ y = - [dez(!x) + 1] else y = dez(x) """ - def value(self,data): - x = ord(data[self.offset]) - if x & 0x80 == 0x80: - return (-1) * (0xff^x + 1) - else: - return x + def value(self,data): + x = ord(data[self.offset]) + if x & 0x80 == 0x80: + return (-1) * (0xff^x + 1) + else: + return x class Data1c(DataField): def value(self,data): @@ -81,7 +82,7 @@ class Byte(DataField): class ByteEnum(DataField): def __init__(self, name, offset, values): - fields.DataField.__init__(self, name, offset) + DataField.__init__(self, name, offset) self.values = values def value(self, data): diff --git a/ebus/model/sql.py b/ebus/model/sql.py index fa9b479..630e31c 100644 --- a/ebus/model/sql.py +++ b/ebus/model/sql.py @@ -3,6 +3,7 @@ from datetime import datetime from sqlalchemy import Column, Integer, Float, DateTime, String, ForeignKey from sqlalchemy.orm import relationship, backref from sqlalchemy.ext.declarative import declarative_base +from ebus import model ModelBase = declarative_base() @@ -18,7 +19,7 @@ class Sensor(ModelBase): self.description = description def __repr__(self): - return "<Sensor('%s','%s','%s')>" % (self.id, self.name, self.description) + return "<Sensor(id='%s',name='%s',description='%s')>" % (self.id, self.name, self.description) # http://www.sqlalchemy.org/docs/05/reference/ext/declarative.html#inheritance-configuration class Value(ModelBase): @@ -37,7 +38,8 @@ class Value(ModelBase): self.sensor = sensor def __repr__(self): - return "<Value('%s','%s','%s','%s'>" % (self.id, self.sensor, self.value, self.timestamp) + return "<Value(id='%s',sensor='%s',value='%s',timestamp='%s'>" % ( + self.id, self.sensor, self.value(), self.timestamp) def value(self): raise NotImplementedException() @@ -76,53 +78,56 @@ class ValueString(Value): return self.value_string -class EbusPacketSQL(object): +class EbusSQL(object): def __init__(self,session): self.session = session def get_values(self,packet): packet_description = packet.get_packet_description() - sensor_name = packet._get_source_name() + sensor_name = str(packet._get_source_name()) sensor = self.session.query(Sensor) \ - .filter(Sensor.name==sensor_name) - - if packet is None: - return - - for field in packet_description.fields: - name = field.name - offset = int(field.offset) - if not name: - continue - elif field.tag == "bit": - yield ValueInt(sensor, \ - fields.Bit(name, offset).value()) - elif field.tag == "byte": - yield ValueInt(sensor, \ - fields.Byte(name, offset).value()) - elif field.tag == "word": - yield ValueInt(sensor, \ - fields.Word(name, offset).value()) - elif field.tag == "data1b": - yield ValueInt(sensor, \ - fields.Data1b(name, offset).value()) - elif field.tag == "data1c": - yield ValueInt(sensor, \ - fields.Data1c(name, offset).value()) - elif field.tag == "data2b": - yield ValueInt(sensor, \ - fields.Data2b(name, offset).value()) - elif field.tag == "data2c": - yield ValueInt(sensor, - fields.Data2c(name, offset).value()) - elif field.tag == "bcd": - yield ValueString(sensor, - fields.Bcd(name, offset).value()) - elif field.tag == "byteEnum": - options = dict(map(lambda opt: ( int(opt.get("value")[2:],16), opt.get("name")), - field.xpath("./option"))) - yield ValueString(sensor, - fields.ByteEnum(name, offset, options).value()) - else: - print "Unsupported field-type %s" % (name) + .filter(Sensor.name==sensor_name).first() + if sensor is None: + sensor = Sensor(sensor_name) + self.session.add(sensor) + + for field in packet_description.fields.iterchildren(): + try: + name = field.get("name") + offset = int(field.get("offset")) + if not name: + continue + elif field.tag == "bit": + yield ValueInt(sensor, \ + model.Bit(name, offset).value(packet.data)) + elif field.tag == "byte": + yield ValueInt(sensor, \ + model.Byte(name, offset).value(packet.data)) + elif field.tag == "word": + yield ValueInt(sensor, \ + model.Word(name, offset).value(packet.data)) + elif field.tag == "data1b": + yield ValueInt(sensor, \ + model.Data1b(name, offset).value(packet.data)) + elif field.tag == "data1c": + yield ValueInt(sensor, \ + model.Data1c(name, offset).value(packet.data)) + elif field.tag == "data2b": + yield ValueInt(sensor, \ + model.Data2b(name, offset).value(packet.data)) + elif field.tag == "data2c": + yield ValueInt(sensor, + model.Data2c(name, offset).value(packet.data)) + elif field.tag == "bcd": + yield ValueString(sensor, + model.Bcd(name, offset).value(packet.data)) + elif field.tag == "byteEnum": + options = dict(map(lambda opt: ( int(opt.get("value")[2:],16), opt.get("name")), + field.xpath("./option"))) + yield ValueString(sensor, + model.ByteEnum(name, offset, options).value(packet.data)) + else: + print "Unsupported field-type %s" % (name) + except Exception,e: + print "skip",e |