From 793a6f53242e635ce5e410dbfa148c4073f341c4 Mon Sep 17 00:00:00 2001 From: Tom Keffer Date: Fri, 5 Mar 2021 12:38:36 -0800 Subject: [PATCH] Fixed problem where iterating over a time period with aggregation would wrongly include the record on the left. --- bin/weewx/tests/test_database.py | 28 ++++++++++++++++++---------- bin/weewx/tests/test_series.py | 6 +++--- bin/weewx/xtypes.py | 2 +- docs/changes.txt | 3 +++ 4 files changed, 25 insertions(+), 14 deletions(-) diff --git a/bin/weewx/tests/test_database.py b/bin/weewx/tests/test_database.py index 2980d5ea..e804395c 100644 --- a/bin/weewx/tests/test_database.py +++ b/bin/weewx/tests/test_database.py @@ -50,16 +50,18 @@ def temperfunc(i): return 68.0 + 0.1*i def expected_record(irec): - _record = {'dateTime': timefunc(irec), 'interval': interval, 'usUnits' : 1, + _record = {'dateTime': timefunc(irec), 'interval': int(interval/60), 'usUnits' : 1, 'outTemp': temperfunc(irec), 'barometer': barfunc(irec), 'inTemp': 70.0 + 0.1*irec} return _record def gen_included_recs(timevec, start_ts, stop_ts, agg_interval): - for stamp in weeutil.weeutil.intervalgen(start_ts, stop_ts, agg_interval): - included = [] + """Generator function that marches down a set of aggregation intervals. Each yield returns + the set of records included in that interval.""" + for span in weeutil.weeutil.intervalgen(start_ts, stop_ts, agg_interval): + included = set() for (irec, ts) in enumerate(timevec): - if stamp[0] < ts <= stamp[1]: - included.append(irec) + if span[0] < ts <= span[1]: + included.add(irec) yield included def genRecords(): @@ -224,11 +226,17 @@ class Common(object): # Now try fetching them as vectors: with weewx.manager.Manager.open(self.archive_db_dict) as archive: - barvec = archive.getSqlVectors((start_ts, stop_ts), 'barometer') - # Recall that barvec will be a 3-way tuple. The first element is the vector of starting - # times, the second the vector of ending times, and the third the data vector. - self.assertEqual(barvec[1], ([timefunc(irec) for irec in range(nrecs)], "unix_epoch", "group_time")) - self.assertEqual(barvec[2], ([barfunc(irec) for irec in range(nrecs)], "inHg", "group_pressure")) + # Return the values between start_ts and stop_ts, exclusive on the left, + # inclusive on the right. + # Recall that barvec returns a 3-way tuple of VectorTuples. + start_vt, stop_vt, data_vt = archive.getSqlVectors((start_ts, stop_ts), 'barometer') + # Build the expected series of stop times and data values. Note that the very first + # value in the database (at timestamp start_ts) is not included, so it should not be + # included in the expected results either. + expected_stop = [timefunc(irec) for irec in range(1, nrecs)] + expected_data = [barfunc(irec) for irec in range(1, nrecs)] + self.assertEqual(stop_vt, (expected_stop, "unix_epoch", "group_time")) + self.assertEqual(data_vt, (expected_data, "inHg", "group_pressure")) # Now try fetching the vectora gain, but using aggregation. # Start by setting up a generator function that will return the records to be diff --git a/bin/weewx/tests/test_series.py b/bin/weewx/tests/test_series.py index 9b08ae5d..2b4a3cf8 100644 --- a/bin/weewx/tests/test_series.py +++ b/bin/weewx/tests/test_series.py @@ -96,9 +96,9 @@ class Common(object): start_vec, stop_vec, data_vec = weewx.xtypes.get_series('outTemp', TimeSpan(start_ts, stop_ts), db_manager) - self.assertEqual(len(start_vec[0]), (stop_ts - start_ts) / gen_fake_data.interval + 1) - self.assertEqual(len(stop_vec[0]), (stop_ts - start_ts) / gen_fake_data.interval + 1) - self.assertEqual(len(data_vec[0]), (stop_ts - start_ts) / gen_fake_data.interval + 1) + self.assertEqual(len(start_vec[0]), (stop_ts - start_ts) / gen_fake_data.interval) + self.assertEqual(len(stop_vec[0]), (stop_ts - start_ts) / gen_fake_data.interval) + self.assertEqual(len(data_vec[0]), (stop_ts - start_ts) / gen_fake_data.interval) def test_get_series_archive_agg_rain_sum(self): """Test a series of daily aggregated rain totals""" diff --git a/bin/weewx/xtypes.py b/bin/weewx/xtypes.py index fa166767..bf79900a 100644 --- a/bin/weewx/xtypes.py +++ b/bin/weewx/xtypes.py @@ -158,7 +158,7 @@ class ArchiveTable(XType): # No aggregation sql_str = "SELECT dateTime, %s, usUnits, `interval` FROM %s " \ - "WHERE dateTime >= ? AND dateTime <= ?" % (obs_type, db_manager.table_name) + "WHERE dateTime > ? AND dateTime <= ?" % (obs_type, db_manager.table_name) std_unit_system = None diff --git a/docs/changes.txt b/docs/changes.txt index 5d6ed002..15e68168 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -16,6 +16,9 @@ Thanks to user Les Niles! Changed the way of expressing the old "wview" schema to the new V4 way. Hopefully, this will lead to fewer support issues. Fixes issue #651. +Fixed problem where iterating over a time period without an aggregation would +wrongly include the record on the left. + 4.4.0 01/30/2021