Skip to content

Commit

Permalink
Shuffle things for clarity
Browse files Browse the repository at this point in the history
  • Loading branch information
vladistan committed Aug 9, 2024
1 parent f00c6d4 commit f8d10ec
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 58 deletions.
54 changes: 51 additions & 3 deletions src/greenbutton_objects/orig_objects/objects.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
from dataclasses import dataclass, field
from datetime import datetime, timedelta
from decimal import Decimal
from typing import List, Optional, Tuple

import greenbutton_objects.data.espi as espi
from greenbutton_objects.orig_objects import ServiceKind
from greenbutton_objects.orig_objects.enums import QualityOfReading
from greenbutton_objects.orig_objects.enums import UNIT_SYMBOL_DESCRIPTIONS, QualityOfReading, UnitSymbol
from greenbutton_objects.util import get_value


Expand Down Expand Up @@ -53,9 +54,30 @@ class IntervalReading:

__cached_value: Optional[float] = None

@property
def start(self) -> datetime:
if self.time_period is None:
return datetime.utcfromtimestamp(0)
# The type checking is ignored for the lines below
# because these conditions should never happen
# unfortunately some providers produce feeds that are not compatible
# with the defined XSD schema
if type(self.time_period.start) is str: # type: ignore
time_start = datetime.utcfromtimestamp(int(Decimal(self.time_period.start))) # type: ignore
elif type(self.time_period.start) is int: # type: ignore
time_start = datetime.utcfromtimestamp(self.time_period.start) # type: ignore
else:
time_start = self.time_period.start
return time_start

@property
def value(self) -> float:
if self.__cached_value is None and self.reading_type is not None and self.parent is not None:
if (
self.__cached_value is None
and self.reading_type is not None
and self.parent is not None
and self.parent.multiplier is not None
):
self.__cached_value = self.raw_value * self.parent.multiplier
else:
raise ValueError("Cannot auto scale raw_value. Not enough data")
Expand Down Expand Up @@ -90,10 +112,36 @@ class MeterReading:
readings: Tuple[IntervalReading, ...] = field(default_factory=tuple)
intervalBlock: Tuple[IntervalBlock, ...] = field(default_factory=tuple)

def patch(self):
__uom_symbol = None
__uom_description = None

def patch(self) -> None:
for r in self.readings:
r.reading_type = self.reading_type

@property
def uom_symbol(self) -> str:
if self.__uom_symbol is None:
self.__set_unit_of_measure()
return self.__uom_symbol # type: ignore

@property
def uom_description(self) -> str:
if self.__uom_description is None:
self.__set_unit_of_measure()
return self.__uom_description # type: ignore

def __set_unit_of_measure(self) -> None:
uom_value = get_value(
self.reading_type.uom,
src_type=espi.UnitSymbolKindValue,
dest_type=UnitSymbol,
missing_val=UnitSymbol.MISSING,
)
uom_strs = UNIT_SYMBOL_DESCRIPTIONS[uom_value.value].split(",")
self.__uom_description = uom_strs[0]
self.__uom_symbol = uom_strs[-1]


@dataclass
class UsagePoint:
Expand Down
65 changes: 10 additions & 55 deletions src/greenbutton_objects/parse.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#!/usr/bin/python
from datetime import datetime, timedelta
from decimal import Decimal
from datetime import timedelta
from math import isnan

from xsdata.formats.dataclass.context import XmlContext
Expand All @@ -11,13 +10,7 @@
import greenbutton_objects.orig_objects as ob
from greenbutton_objects.atom.href_tree import HRefForest
from greenbutton_objects.atom.object_tree import ObjectForest
from greenbutton_objects.data.espi import (
ReadingType,
UnitSymbolKindValue,
)
from greenbutton_objects.feed.feed import ObjectFeed
from greenbutton_objects.orig_objects.enums import UNIT_SYMBOL_DESCRIPTIONS
from greenbutton_objects.util import get_value


def parse_feed(filename: str) -> ObjectFeed:
Expand Down Expand Up @@ -53,63 +46,25 @@ def parse_feed_representation(feed: ObjectFeed) -> str:

# Get meter readings containers and elements
for mr in up.meter_readings:
reading_type = mr.reading_type

uom_description, uom_symbol = get_uom_symbol(reading_type)

result.append("Meter Reading (%s) %s:" % (mr.title, uom_description))
result.append("Meter Reading (%s) %s:" % (mr.title, mr.uom_description))
result.append("\n")

for reading in mr.readings:
io = reading

time_start = get_block_start_period(io)

result.append(
" %s, %s: %g%s"
% (
time_start.strftime("%Y-%m-%d %H:%M:%S+00:00"),
str(timedelta(seconds=io.time_period.duration)), # type: ignore
io.value,
uom_symbol,
reading.start.strftime("%Y-%m-%d %H:%M:%S+00:00"),
str(timedelta(seconds=reading.time_period.duration)), # type: ignore
reading.value,
mr.uom_symbol,
)
)
if not isnan(io.cost):
result.append("(%s%s)" % ("$", io.cost / 100000))
if not isnan(reading.cost):
result.append("(%s%s)" % ("$", reading.cost / 100000))
# TODO: Hard-coding $ for now as current code does
# not handle currency correctly
if io.quality_of_reading != ob.QualityOfReading.MISSING:
result.append(" [%s]" % io.quality_of_reading.name)
if reading.quality_of_reading != ob.QualityOfReading.MISSING:
result.append(" [%s]" % reading.quality_of_reading.name)
result.append("\n\n")

return "".join(result)


def get_block_start_period(io: ob.IntervalReading) -> datetime:
if io.time_period is None:
return datetime.utcfromtimestamp(0)
# The type checking is ignored for the lines below
# because these conditions should never happen
# unfortunately some providers produce feeds that are not compatible
# with the defined XSD schema
if type(io.time_period.start) is str: # type: ignore
time_start = datetime.utcfromtimestamp(int(Decimal(io.time_period.start))) # type: ignore
elif type(io.time_period.start) is int: # type: ignore
time_start = datetime.utcfromtimestamp(io.time_period.start) # type: ignore
else:
time_start = io.time_period.start
return time_start


def get_uom_symbol(reading_type: ReadingType) -> tuple[str, str]:
uom_value = get_value(
reading_type.uom,
src_type=UnitSymbolKindValue,
dest_type=ob.UnitSymbol,
missing_val=ob.UnitSymbol.MISSING,
)
uom_strs = UNIT_SYMBOL_DESCRIPTIONS[uom_value.value].split(",")
uom_description = uom_strs[0]
uom_symbol = uom_strs[-1]

return uom_description, uom_symbol

0 comments on commit f8d10ec

Please sign in to comment.