From 862282ce99760832d3e9e5b4b1171b861105e004 Mon Sep 17 00:00:00 2001 From: Ebus-at-dockstar Date: Mon, 25 Mar 2013 10:24:28 +0100 Subject: move old stuff away --- heap/ebus/model/__init__.py | 99 +++++++++++++++++++++++++++++++ heap/ebus/model/sql.py | 138 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 237 insertions(+) create mode 100644 heap/ebus/model/__init__.py create mode 100644 heap/ebus/model/sql.py (limited to 'heap/ebus/model') diff --git a/heap/ebus/model/__init__.py b/heap/ebus/model/__init__.py new file mode 100644 index 0000000..f6a44b9 --- /dev/null +++ b/heap/ebus/model/__init__.py @@ -0,0 +1,99 @@ +# -*- coding:utf8 -*- +class DataField(object): + def __init__(self, name, offset): + self.name = name + self.offset = offset + def value(self,data): + raise NotImplemented() + +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 + +class Data1c(DataField): + def value(self,data): + return ord(data[self.offset])/2.0 + +class Data2c(DataField): + """ + Beispiel für die Berechnung: + if ((x & 8000h) == 8000h) // y negativ + y = - [dez(High_Byte(!x)) 16 + dez(High_Nibble (Low_Byte (!x))) + + (dez(Low_Nibble (Low_Byte (!x))) +1 ) / 16] + else // y positiv + y = dez(High_Byte(x)) 16 + dez(High_ Nibble (Low Byte (x))) + + dez(Low_ Nibble (Low Byte (x))) / 16 + """ + def value(self,data): + lowByte = ord(data[self.offset]) + highByte = ord(data[self.offset+1]) + n_highByte = 0xff ^ highByte + n_lowByte = 0xff ^ lowByte + n_lowByteHighNibble = n_lowByte >> 4 + n_lowByteLowNibble = 0x0f & n_lowByte + if (0x8000 & (highByte<<8 | lowByte)) == 0x8000: + return (-1) * ( (n_highByte<<4 + n_lowByteHighNibble + (n_lowByteLowNibble+1)) / 16.0 ) + else: + return highByte*16 + (lowByte>>4) + (0x0f & lowByte)/16.0 + +class Data2b(DataField): + """ + if ((x&8000h) == 8000h) // y negativ + y = - [dez(High_Byte(!x)) + (dez(Low_Byte(!x)) + 1) / 256] + else // y positiv + y = dez(High_Byte (x)) + dez(Low_Byte (x)) / 256 + """ + def value(self,data): + highByte = ord(data[self.offset+1]) + lowByte = ord(data[self.offset]) + n_highByte = 0xff ^ highByte + n_lowByte = 0xff ^ lowByte + if (0x8000 & (highByte<<8 | lowByte)) == 0x8000: + return (-1) * (n_highByte + (n_lowByte+1)/256.0) + else: + return highByte + lowByte/256.0 + +class Bit(DataField): + def value(self, data): + return ord(data[self.offset]) == 0x1 + +class Word(DataField): + def value(self, data): + lb, hb = data[self.offset], data[self.offset+1] + return ord(lb) + (ord(hb)<<8) + +class Bcd(DataField): + """ + y = dez(High_Nibble(x))*10 + dez(Low_Nibble(x)) + """ + def value(self, data): + byte = ord(data[self.offset]) + return (byte >> 4) * 10 + (byte & 0xf) + +class Byte(DataField): + def value(self, data): + return ord(data[self.offset]) + + +class ByteEnum(DataField): + def __init__(self, name, offset, values): + DataField.__init__(self, name, offset) + self.values = values + + def value(self, data): + value = ord(data[self.offset]) + if self.values.has_key(value): + return self.values[value] + else: + return None diff --git a/heap/ebus/model/sql.py b/heap/ebus/model/sql.py new file mode 100644 index 0000000..75ebd0c --- /dev/null +++ b/heap/ebus/model/sql.py @@ -0,0 +1,138 @@ +# -*- coding: utf-8 -*- +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() + +class Sensor(ModelBase): + __tablename__ = 'sensor' + + id = Column(Integer, primary_key=True) + name = Column(String) + description = Column(String, default="") + + def __init__(self, name, description=""): + self.name = name + self.description = description + + def __repr__(self): + return "" % (self.id, self.name, self.description) + +# http://www.sqlalchemy.org/docs/05/reference/ext/declarative.html#inheritance-configuration +class Value(ModelBase): + __tablename__ = 'value' + + id = Column(Integer, primary_key=True) + timestamp = Column(DateTime,index=True) + sensor_id = Column(Integer,ForeignKey("sensor.id"),index=True) + sensor = relationship(Sensor, backref=backref('values', order_by=timestamp)) + + discriminator = Column('type', String(50)) + __mapper_args__ = {'polymorphic_on': discriminator} + + def __init__(self, sensor, timestamp=None): + if not timestamp: + timestamp = datetime.now() + self.timestamp = timestamp + self.sensor = sensor + + def __repr__(self): + return "" % ( + self.id, self.sensor, self.value(), self.timestamp) + + def value(self): + raise NotImplementedException() + +class ValueFloat(Value): + __mapper_args__ = {'polymorphic_identity': 'float'} + value_float = Column(Float(precision=4)) + + def __init__(self, sensor, value, timestamp=None): + Value.__init__(self, sensor, timestamp) + self.value_float = value + + def value(self): + return self.value_float + +class ValueInt(Value): + __mapper_args__ = {'polymorphic_identity': 'int'} + value_int = Column(Integer) + + def __init__(self, sensor, value, timestamp=None): + Value.__init__(self, sensor, timestamp) + self.value_int = value + + def value(self): + return self.value_int + +class ValueString(Value): + __mapper_args__ = {'polymorphic_identity': 'string'} + value_string = Column(String) + + def __init__(self, sensor, value, timestamp=None): + Value.__init__(self, sensor, timestamp) + self.value_string = value + + def value(self): + return self.value_string + + +class EbusSQL(object): + def __init__(self,session): + self.session = session + + def get_values(self,packet): + packet_description = packet.get_packet_description() + packet_source_name = packet.get_source_name() + packet_name = packet.name() + for field in packet_description.fields.iterchildren(): + try: + name = field.get("name") + offset = int(field.get("offset")) + if not name: + continue + + sensor_name = "%s.%s.%s" % (packet_source_name, packet_name, name ) + sensor = self.session.query(Sensor) \ + .filter(Sensor.name==sensor_name).first() + if sensor is None: + sensor = Sensor(sensor_name) + self.session.add(sensor) + + if field.tag == "bit": + yield ValueInt(sensor, \ + model.Bit(name, offset).value(packet.data) and 1 or 0) + 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 ValueFloat(sensor, \ + model.Data1b(name, offset).value(packet.data)) + elif field.tag == "data1c": + yield ValueFloat(sensor, \ + model.Data1c(name, offset).value(packet.data)) + elif field.tag == "data2b": + yield ValueFloat(sensor, \ + model.Data2b(name, offset).value(packet.data)) + elif field.tag == "data2c": + yield ValueFloat(sensor, + model.Data2c(name, offset).value(packet.data)) + elif field.tag == "bcd": + yield ValueInt(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 + -- cgit v1.2.1