eemeter.io.serializers

class eemeter.io.serializers.ArbitrarySerializer(parse_dates=False)[source]

Arbitrary data at arbitrary non-overlapping intervals. Often used for montly billing data. Records must all have the “start” key and the “end” key. Overlaps are not allowed and gaps will be filled with NaN.

For example:

>>> records = [
...     {
...         "start": datetime(2013, 12, 30, tzinfo=pytz.utc),
...         "end": datetime(2014, 1, 28, tzinfo=pytz.utc),
...         "value": 1180,
...     },
...     {
...         "start": datetime(2014, 1, 28, tzinfo=pytz.utc),
...         "end": datetime(2014, 2, 27, tzinfo=pytz.utc),
...         "value": 1211,
...         "estimated": True,
...     },
...     {
...         "start": datetime(2014, 2, 28, tzinfo=pytz.utc),
...         "end": datetime(2014, 3, 30, tzinfo=pytz.utc),
...         "value": 985,
...     },
... ]
...
>>> serializer = ArbitrarySerializer()
>>> df = serializer.to_dataframe(records)
>>> df
                            value estimated
2013-12-30 00:00:00+00:00  1180.0     False
2014-01-28 00:00:00+00:00  1211.0      True
2014-02-27 00:00:00+00:00     NaN     False
2014-02-28 00:00:00+00:00   985.0     False
2014-03-30 00:00:00+00:00     NaN     False
class eemeter.io.serializers.ArbitraryStartSerializer(parse_dates=False)[source]

Arbitrary start data at arbitrary non-overlapping intervals. Records must all have the “start” key. The last data point will be ignored unless an end date is provided for it. This is useful for data dated to future energy use, e.g. billing for delivered fuels.

For example:

>>> records = [
...     {
...         "start": datetime(2013, 12, 30, tzinfo=pytz.utc),
...         "value": 1180,
...     },
...     {
...         "start": datetime(2014, 1, 28, tzinfo=pytz.utc),
...         "value": 1211,
...         "estimated": True,
...     },
...     {
...         "start": datetime(2014, 2, 28, tzinfo=pytz.utc),
...         "value": 985,
...     },
... ]
...
>>> serializer = ArbitrarySerializer()
>>> df = serializer.to_dataframe(records)
>>> df
                            value estimated
2013-12-30 00:00:00+00:00  1180.0     False
2014-01-28 00:00:00+00:00  1211.0      True
2014-02-28 00:00:00+00:00     NaN     False
class eemeter.io.serializers.ArbitraryEndSerializer(parse_dates=False)[source]

Arbitrary end data at arbitrary non-overlapping intervals. Records must all have the “end” key. The first data point will be ignored unless a start date is provided for it. This is useful for data dated to past energy use, e.g. electricity or natural gas bills.

For example:

>>> records = [
...     {
...         "end": datetime(2013, 12, 30, tzinfo=pytz.utc),
...         "value": 1180,
...     },
...     {
...         "end": datetime(2014, 1, 28, tzinfo=pytz.utc),
...         "value": 1211,
...         "estimated": True,
...     },
...     {
...         "end": datetime(2014, 2, 28, tzinfo=pytz.utc),
...         "value": 985,
...     },
... ]
...
>>> serializer = ArbitrarySerializer()
>>> df = serializer.to_dataframe(records)
>>> df
                            value estimated
2013-12-30 00:00:00+00:00  1211.0      True
2014-01-28 00:00:00+00:00   985.0     False
2014-02-28 00:00:00+00:00     NaN     False

eemeter.io.parsers

class eemeter.io.parsers.ESPIUsageParser(xml)[source]

Parse ESPI XML files.

Basic usage:

>>> from eemeter.io.parsers import ESPIUsageParser
>>> with open("/path/to/example.xml") as f:
...     parser = ESPIUsageParser(f)
>>> energy_traces = list(parser.get_energy_traces())
Parameters:xml (str, filepath, file buffer) – XML data to parse
get_energy_traces(service_kind_default='electricity')[source]

Retrieve all energy trace records stored as IntervalReading elements in the given ESPI Energy Usage XML.

Energy records are grouped by interpretation and returned in EnergyTrace objects.

Parameters:service_kind_default (str) – Default fuel type to use in parser if ReadingType/commodity field is missing.
Yields:energy_trace (eemeter.structures.EnergyTrace) – Energy data traces as described in the xml file.
has_solar()[source]

Returns True if there is a “reverse” flow direction in this file, indicating presence of solar photo voltaics.

TODO: Verify that this is the correct way to determine this - are there false positives or false negatives? Is there a more straightforward flag to use somewhere else?