initial working env
This commit is contained in:
154
greenbutton/resources.py
Normal file
154
greenbutton/resources.py
Normal file
@@ -0,0 +1,154 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
import bisect
|
||||
import functools
|
||||
|
||||
from .utils import *
|
||||
from .enums import *
|
||||
from .objects import *
|
||||
|
||||
class Resource(object):
|
||||
def __init__(self, entry):
|
||||
self.link_self = getLink(entry, 'self')
|
||||
self.link_up = getLink(entry, 'up')
|
||||
self.link_related = getLink(entry, 'related', True)
|
||||
self.title = getEntity(entry, 'atom:title', lambda e: e.text)
|
||||
|
||||
def __repr__(self):
|
||||
return '<%s (%s)>' % (self.__class__.__name__, self.title or self.link_self)
|
||||
|
||||
def isParentOf(self, other):
|
||||
return other.link_self in self.link_related or other.link_up in self.link_related
|
||||
|
||||
|
||||
class UsagePoint(Resource):
|
||||
def __init__(self, entry, meterReadings=[]):
|
||||
super(UsagePoint, self).__init__(entry)
|
||||
obj = entry.find('./atom:content/espi:UsagePoint', ns)
|
||||
self.roleFlags = getEntity(obj, 'espi:roleFlags', lambda e: int(e.text, 16))
|
||||
self.status = getEntity(obj, 'espi:status', lambda e: int(e.text))
|
||||
self.serviceCategory = getEntity(obj, './espi:ServiceCategory/espi:kind',
|
||||
lambda e: ServiceKind(int(e.text)))
|
||||
|
||||
self.meterReadings = set()
|
||||
for mr in meterReadings:
|
||||
if self.isParentOf(mr):
|
||||
self.addMeterReading(mr)
|
||||
|
||||
self.localTimeParameters = None
|
||||
|
||||
def addMeterReading(self, meterReading):
|
||||
assert self.isParentOf(meterReading)
|
||||
self.meterReadings.add(meterReading)
|
||||
meterReading.usagePoint = self
|
||||
|
||||
def addLocalTimeParameters(self, localTimeParameters):
|
||||
assert self.isParentOf(localTimeParameters)
|
||||
self.localTimeParameters = localTimeParameters
|
||||
|
||||
|
||||
class MeterReading(Resource):
|
||||
def __init__(self, entry, usagePoints=[], readingTypes=[], intervalBlocks=[]):
|
||||
super(MeterReading, self).__init__(entry)
|
||||
|
||||
self.usagePoint = None
|
||||
self.readingType = None
|
||||
self.intervalBlocks = []
|
||||
for up in usagePoints:
|
||||
if up.isParentOf(self):
|
||||
up.addMeterReading(self)
|
||||
for rt in readingTypes:
|
||||
if self.isParentOf(rt):
|
||||
self.setReadingType(rt)
|
||||
for ib in intervalBlocks:
|
||||
if self.isParentOf(ib):
|
||||
self.addIntervalBlock(r)
|
||||
|
||||
@property
|
||||
def intervalReadings(self):
|
||||
for ib in self.intervalBlocks:
|
||||
for ir in ib.intervalReadings:
|
||||
yield ir
|
||||
|
||||
def setReadingType(self, readingType):
|
||||
assert self.isParentOf(readingType)
|
||||
assert self.readingType is None or self.readingType.link_self == readingType.link_self
|
||||
self.readingType = readingType
|
||||
readingType.meterReading = self
|
||||
|
||||
def addIntervalBlock(self, intervalBlock):
|
||||
assert self.isParentOf(intervalBlock)
|
||||
bisect.insort(self.intervalBlocks, intervalBlock)
|
||||
intervalBlock.meterReading = self
|
||||
|
||||
|
||||
class ReadingType(Resource):
|
||||
def __init__(self, entry, meterReadings=[]):
|
||||
super(ReadingType, self).__init__(entry)
|
||||
self.meterReading = None
|
||||
|
||||
obj = entry.find('./atom:content/espi:ReadingType', ns)
|
||||
self.accumulationBehaviour = getEntity(obj, 'espi:accumulationBehaviour',
|
||||
lambda e: AccumulationBehaviourType(int(e.text)))
|
||||
self.commodity = getEntity(obj, 'espi:commodity',
|
||||
lambda e: CommodityType(int(e.text)))
|
||||
self.consumptionTier = getEntity(obj, 'espi:consumptionTier',
|
||||
lambda e: ConsumptionTierType(int(e.text)))
|
||||
self.currency = getEntity(obj, 'espi:currency',
|
||||
lambda e: CurrencyCode(int(e.text)))
|
||||
self.dataQualifier = getEntity(obj, 'espi:dataQualifier',
|
||||
lambda e: DataQualifierType(int(e.text)))
|
||||
self.defaultQuality = getEntity(obj, 'espi:defaultQuality',
|
||||
lambda e: QualityOfReading(int(e.text)))
|
||||
self.flowDirection = getEntity(obj, 'espi:flowDirection',
|
||||
lambda e: FlowDirectionType(int(e.text)))
|
||||
self.intervalLength = getEntity(obj, 'espi:intervalLength', lambda e: int(e.text))
|
||||
self.kind = getEntity(obj, 'espi:kind', lambda e: KindType(int(e.text)))
|
||||
self.phase = getEntity(obj, 'espi:phase', lambda e: PhaseCode(int(e.text)))
|
||||
self.powerOfTenMultiplier = getEntity(obj, 'espi:powerOfTenMultiplier',
|
||||
lambda e: int(e.text))
|
||||
self.timeAttribute = getEntity(obj, 'espi:timeAttribute',
|
||||
lambda e: TimeAttributeType(int(e.text)))
|
||||
self.tou = getEntity(obj, 'espi:tou', lambda e: TOUType(int(e.text)))
|
||||
self.uom = getEntity(obj, 'espi:uom', lambda e: UomType(int(e.text)))
|
||||
|
||||
for mr in meterReadings:
|
||||
if mr.isParentOf(self):
|
||||
mr.setReadingType(self)
|
||||
|
||||
|
||||
class LocalTimeParameters(Resource):
|
||||
def __init__(self, entry, usagePoints=[]):
|
||||
super(LocalTimeParameters, self).__init__(entry)
|
||||
self.localTimeParameters = None
|
||||
|
||||
obj = entry.find('./atom:content/espi:LocalTimeParameters', ns)
|
||||
self.tzOffset = getEntity(obj, 'espi:tzOffset', lambda e: int(e.text))
|
||||
|
||||
for up in usagePoints:
|
||||
if up.isParentOf(self):
|
||||
up.addLocalTimeParameters(self)
|
||||
|
||||
|
||||
@functools.total_ordering
|
||||
class IntervalBlock(Resource):
|
||||
def __init__(self, entry, meterReadings=[]):
|
||||
super(IntervalBlock, self).__init__(entry)
|
||||
self.meterReading = None
|
||||
|
||||
obj = entry.find('./atom:content/espi:IntervalBlock', ns)
|
||||
self.interval = getEntity(obj, 'espi:interval', lambda e: DateTimeInterval(e))
|
||||
self.intervalReadings = sorted([IntervalReading(ir, self) for ir in obj.findall('espi:IntervalReading', ns)])
|
||||
|
||||
for mr in meterReadings:
|
||||
if mr.isParentOf(self):
|
||||
mr.addIntervalBlock(self)
|
||||
|
||||
def __eq__(self, other):
|
||||
if not isinstance(other, IntervalBlock):
|
||||
return False
|
||||
return self.link_self == other.link_self
|
||||
|
||||
def __lt__(self, other):
|
||||
return self.interval < other.interval
|
||||
|
||||
Reference in New Issue
Block a user