def test_parse_fail_schema4(self): data = """ { "stream_types": [ { "streams": [ { "start_datetime": "2018-01-01T00:00:01Z", "kw_total_avg": 411.899, "end_datetime": "2018-01-01T00:15:00Z" }, { "start_datetime": "2018-01-01T00:15:01Z", "kw_total_avg": 411.82892, "end_datetime": "2018-01-01T00:30:00Z" }, { "start_datetime": "2018-01-01T00:30:01Z", "kw_total_avg": 411.60704, "end_datetime": "2018-01-01T00:45:00Z" } ], "stream": "MONITOR" } ], "id": "abcd9876", "name": "Anodyne Industries LLC" } """ # stream should be stream_type with self.assertRaises(SchemaValidationFailure): parsers.parse_intervals(data, "MONITOR")
def test_parse_fail_schema2(self): data = """ { "stream_types": [ { "streams": [ { "start_datetime": "2018-01-01T00:00:01Z", "end_datetime": "2018-01-01T00:15:00Z" } ], "stream_type": "MONITOR" } ], "id": "abcd9876", "name": "Anodyne Industries LLC" } """ # Missing KW with self.assertRaises(SchemaValidationFailure): parsers.parse_intervals(data, "MONITOR")
def test_parse_fail_schema3(self): data = """ { "stream_types": [ { "streams": [ { "start_datetime": "2018-01-01T00:00:01Z", "kw_total_avg": "Help, I'm trapped in an interval factory...", "end_datetime": "2018-01-01T00:15:00Z" } ], "stream_type": "MONITOR" } ], "id": "abcd9876", "name": "Anodyne Industries LLC" } """ # KW not a number with self.assertRaises(SchemaValidationFailure): parsers.parse_intervals(data, "MONITOR")
def get_stream(self, site, start, end, stream_type, resolution_sec=900): """Retrieve a list of Interval nametuples from a time range. site - A Site nametuple specifying the meter. start - Start datetime (inclusive) end - End datetime (inclusive) resolution_sec - Time in seconds for each interval. The default (900) specifies 15 minute intervals. Valid values are be 900, 1800, or 3600. """ accum = [] url = self.api_base + site.link + "/streams" delta = relativedelta(months=1) _check_utc(start) _check_utc(end) # No point in polling for intervals before the stated start of the feed. t0 = max(start, site.start) t1 = min(end, t0 + delta) while t0 < t1 and t0 < end: params = { "start_datetime": _isoformat_time(t0), "end_datetime": _isoformat_time(t1), "resolution": resolution_sec, "stream_type": stream_type, } resp = requests.get( url, params=params, headers={"Authorization": "APIKEY %s" % self.api_key}, ) if resp.status_code == codes.ok: results = parser.parse_intervals(resp.text, stream_type) accum += results elif not (resp.status_code == codes.bad_request and "No data available" in resp.text): # The API isn't working, and it's not just because there is no interval data. Abort. msg = "Received unexpected API response. status_code: %d text: %s" raise ApiError(msg % (resp.status_code, resp.text)) t0 = t1 t1 = min(end, t0 + delta) return accum
def test_parse_success(self): """The STEM parser generates a list of intervals for JSON passing schema.""" data = """ { "stream_types": [ { "streams": [ { "start_datetime": "2018-01-01T00:00:01Z", "kw_total_avg": 411.899, "end_datetime": "2018-01-01T00:15:00Z" }, { "start_datetime": "2018-01-01T00:15:01Z", "kw_total_avg": 411.82892, "end_datetime": "2018-01-01T00:30:00Z" }, { "start_datetime": "2018-01-01T00:30:01Z", "kw_total_avg": 411.60704, "end_datetime": "2018-01-01T00:45:00Z" } ], "stream_type": "MONITOR" }, { "streams": [ { "start_datetime": "2018-01-01T00:00:01Z", "kw_total_avg": 1234, "end_datetime": "2018-01-01T00:15:00Z" }, { "start_datetime": "2018-01-01T00:15:01Z", "kw_total_avg": 6789, "end_datetime": "2018-01-01T00:30:00Z" }, { "start_datetime": "2018-01-01T00:30:01Z", "kw_total_avg": 10123, "end_datetime": "2018-01-01T00:45:00Z" } ], "stream_type": "CONVERTER" }, { "streams": [ { "start_datetime": "2018-02-01T00:00:01Z", "kw_total_avg": 422.899, "end_datetime": "2018-01-01T00:15:00Z" }, { "start_datetime": "2018-02-01T00:15:01Z", "kw_total_avg": 433.82892, "end_datetime": "2018-01-01T00:30:00Z" }, { "start_datetime": "2018-02-01T00:30:01Z", "kw_total_avg": 444.60704, "end_datetime": "2018-01-01T00:45:00Z" } ], "stream_type": "MONITOR" } ], "id": "abcd9876", "name": "Anodyne Industries LLC" } """ intervals = parsers.parse_intervals(data, "MONITOR") # Parser concatenates monitor records and drops all others. self.assertEqual(len(intervals), 6) self.assertEqual(intervals[1].start, datetime(2018, 1, 1, 0, 15, 1, tzinfo=UTC)) self.assertEqual(intervals[1].end, datetime(2018, 1, 1, 0, 30, 0, tzinfo=UTC)) self.assertEqual(intervals[1].kw, 411.82892)
def test_parse_fail_json(self): """The STEM parser raises an exception when the response is not JSON.""" data = """{abc123:""" with self.assertRaises(JsonParseFailure): parsers.parse_intervals(data, "MONITOR")