Fix bug that prevents group_deltatime from being used by timespans

Fixes issue #808.
This commit is contained in:
Tom Keffer
2022-11-06 13:51:00 -08:00
parent 2639c6ca46
commit 209fd34026
13 changed files with 154 additions and 29 deletions

View File

@@ -1,5 +1,5 @@
#
# Copyright (c) 2009-2021 Tom Keffer <tkeffer@gmail.com>
# Copyright (c) 2009-2022 Tom Keffer <tkeffer@gmail.com>
#
# See the file LICENSE.txt for your full rights.
#
@@ -392,7 +392,7 @@ class AlmanacBinder(object):
visible = (time_setting_djd - time_rising_djd) * weewx.units.SECS_PER_DAY
return weewx.units.ValueHelper(ValueTuple(visible, "second", "group_deltatime"),
context="short_delta",
context="day",
formatter=self.almanac.formatter,
converter=self.almanac.converter)
@@ -409,7 +409,7 @@ class AlmanacBinder(object):
# Take the difference
diff = today_visible.raw - then_visible.raw
return weewx.units.ValueHelper(ValueTuple(diff, "second", "group_deltatime"),
context="brief_delta",
context="hour",
formatter=self.almanac.formatter,
converter=self.almanac.converter)

View File

@@ -1,6 +1,6 @@
# coding: utf-8
#
# Copyright (c) 2019-2021 Tom Keffer <tkeffer@gmail.com>
# Copyright (c) 2019-2022 Tom Keffer <tkeffer@gmail.com>
#
# See the file LICENSE.txt for your rights.
#
@@ -221,10 +221,15 @@ log_failure = False
current = %x %X
ephem_day = %X
ephem_year = %x %X
brief_delta = "%(minute)d%(minute_label)s, %(second)d%(second_label)s"
short_delta = "%(hour)d%(hour_label)s, %(minute)d%(minute_label)s, %(second)d%(second_label)s"
long_delta = "%(day)d%(day_label)s, %(hour)d%(hour_label)s, %(minute)d%(minute_label)s"
delta_time = "%(day)d%(day_label)s, %(hour)d%(hour_label)s, %(minute)d%(minute_label)s"
[[DeltaTimeFormats]]
current = "%(minute)d%(minute_label)s, %(second)d%(second_label)s"
hour = "%(minute)d%(minute_label)s, %(second)d%(second_label)s"
day = "%(hour)d%(hour_label)s, %(minute)d%(minute_label)s, %(second)d%(second_label)s"
week = "%(day)d%(day_label)s, %(hour)d%(hour_label)s, %(minute)d%(minute_label)s"
month = "%(day)d%(day_label)s, %(hour)d%(hour_label)s, %(minute)d%(minute_label)s"
year = "%(day)d%(day_label)s, %(hour)d%(hour_label)s, %(minute)d%(minute_label)s"
[[Ordinates]]

View File

@@ -1,5 +1,5 @@
#
# Copyright (c) 2009-2021 Tom Keffer <tkeffer@gmail.com>
# Copyright (c) 2009-2022 Tom Keffer <tkeffer@gmail.com>
#
# See the file LICENSE.txt for your full rights.
#
@@ -92,7 +92,7 @@ class Station(object):
delta_time = time.time() - weewx.launchtime_ts if weewx.launchtime_ts else None
return weewx.units.ValueHelper(value_t=(delta_time, "second", "group_deltatime"),
context="long_delta",
context="month",
formatter=self.formatter,
converter=self.converter)
@@ -101,7 +101,7 @@ class Station(object):
"""Lazy evaluation of the server uptime."""
os_uptime_secs = _os_uptime()
return weewx.units.ValueHelper(value_t=(os_uptime_secs, "second", "group_deltatime"),
context="long_delta",
context="month",
formatter=self.formatter,
converter=self.converter)

View File

@@ -575,6 +575,11 @@
<td>Test for a bad aggregation type on a $day tag: $day.outTemp.foo</td>
<td>$day.outTemp.foo</td>
</tr>
</tr>
<tr>
<td>Test for sunshineDur: $day.sunshineDur.sum</td>
<td>7 hours, 0 minutes, 0 seconds</td>
</tr>
</table>
<hr/>

View File

@@ -575,6 +575,11 @@
<td>Test for a bad aggregation type on a $day tag: $day.outTemp.foo</td>
<td>$day.outTemp.foo</td>
</tr>
</tr>
<tr>
<td>Test for sunshineDur: $day.sunshineDur.sum</td>
<td>7 Stunden, 0 Minuten, 0 Sekunden</td>
</tr>
</table>
<hr/>

View File

@@ -1,6 +1,6 @@
#
#
# Copyright (c) 2009-2019 Tom Keffer <tkeffer@gmail.com>
# Copyright (c) 2009-2022 Tom Keffer <tkeffer@gmail.com>
#
# See the file LICENSE.txt for your full rights.
#
@@ -193,6 +193,7 @@ def genFakeRecords(start_ts=start_ts, stop_ts=stop_ts, interval=interval,
record['rain'] = 0.0
record['radiation'] = max(amplitude * 800 * math.sin(daily_phase - math.pi / 2.0), 0)
record['radiation'] *= 0.5 * (math.cos(annual_phase + math.pi) + 1.5)
record['sunshineDur'] = interval if record['radiation'] else 0.0
# Make every 71st observation (a prime number) a null. This is a deterministic algorithm, so it
# will produce the same results every time.

View File

@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
#
# Copyright (c) 2009-2021 Tom Keffer <tkeffer@gmail.com>
# Copyright (c) 2009-2022 Tom Keffer <tkeffer@gmail.com>
#
# See the file LICENSE.txt for your full rights.
#
@@ -23,7 +23,7 @@ from six.moves import map
import configobj
import gen_fake_data
import schemas.wview_small
import tst_schema
import weeutil.logger
import weeutil.weeutil
import weewx.manager
@@ -39,7 +39,7 @@ weeutil.logger.setup('test_daily', {})
os.environ['TZ'] = 'America/Los_Angeles'
time.tzset()
day_keys = [x[0] for x in schemas.wview_small.schema['day_summaries']]
day_keys = [x[0] for x in tst_schema.schema['day_summaries']]
# Find the configuration file. It's assumed to be in the same directory as me:
config_path = os.path.join(os.path.dirname(__file__), "testgen.conf")

View File

@@ -575,6 +575,11 @@ FALSE#slurp
<td>Test for a bad aggregation type on a \$day tag: \$day.outTemp.foo</td>
<td>$day.outTemp.foo</td>
</tr>
</tr>
<tr>
<td>Test for sunshineDur: \$day.sunshineDur.sum</td>
<td>$day.sunshineDur.sum</td>
</tr>
</table>
<hr/>

View File

@@ -6,7 +6,7 @@
# #
###############################################################################
# #
# Copyright (c) 2009, 2010, 2011, 2021 Tom Keffer <tkeffer@gmail.com> #
# Copyright (c) 2009 - 2022 Tom Keffer <tkeffer@gmail.com> #
# #
# See the file LICENSE.txt for your full rights. #
# #
@@ -117,7 +117,7 @@ version = test
# The class to manage the database
manager = weewx.manager.DaySummaryManager
# For the schema, use the "small" schema. It is much faster.
schema = schemas.wview_small.schema
schema = tst_schema.schema
[[alt_binding]]
# The database to be used - it should match one of the sections in [Databases]
@@ -127,7 +127,7 @@ version = test
# The class to manage the database
manager = weewx.wxmanager.WXDaySummaryManager
# For the "alternate" database, use the "small" schema.
schema = schemas.wview_small.schema
schema = tst_schema.schema
[Databases]

View File

@@ -0,0 +1,38 @@
#
# Copyright (c) 2019-2022 Tom Keffer <tkeffer@gmail.com>
#
# See the file LICENSE.txt for your full rights.
#
table = [('dateTime', 'INTEGER NOT NULL UNIQUE PRIMARY KEY'),
('usUnits', 'INTEGER NOT NULL'),
('interval', 'INTEGER NOT NULL'),
('altimeter', 'REAL'),
('barometer', 'REAL'),
('dewpoint', 'REAL'),
('ET', 'REAL'),
('heatindex', 'REAL'),
('inHumidity', 'REAL'),
('inTemp', 'REAL'),
('outHumidity', 'REAL'),
('outTemp', 'REAL'),
('pressure', 'REAL'),
('radiation', 'REAL'),
('rain', 'REAL'),
('rainRate', 'REAL'),
('rxCheckPercent', 'REAL'),
('sunshineDur', 'REAL'),
('UV', 'REAL'),
('windchill', 'REAL'),
('windDir', 'REAL'),
('windGust', 'REAL'),
('windGustDir', 'REAL'),
('windSpeed', 'REAL'),
]
day_summaries = [(e[0], 'scalar') for e in table
if e[0] not in ('dateTime', 'usUnits', 'interval')] + [('wind', 'VECTOR')]
schema = {
'table': table,
'day_summaries' : day_summaries
}

View File

@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
#
# Copyright (c) 2009-2021 Tom Keffer <tkeffer@gmail.com>
# Copyright (c) 2009-2022 Tom Keffer <tkeffer@gmail.com>
#
# See the file LICENSE.txt for your full rights.
#
@@ -572,7 +572,8 @@ class Formatter(object):
def __init__(self, unit_format_dict = None,
unit_label_dict = None,
time_format_dict = None,
ordinate_names = None):
ordinate_names = None,
deltatime_format_dict = None):
"""
Args:
@@ -583,12 +584,15 @@ class Formatter(object):
time_format_dict (dict): Key is a context (e.g., 'week'), value is a
strftime format (e.g., "%d-%b-%Y %H:%M").
ordinate_names(list): A list containing ordinal compass names (e.g., ['N', 'NNE', etc.]
deltatime_format_dict (dict): Key is a context (e.g., 'week'), value is a deltatime
format string (e.g., "%(minute)d%(minute_label)s, %(second)d%(second_label)s")
"""
self.unit_format_dict = unit_format_dict or {}
self.unit_label_dict = unit_label_dict or {}
self.time_format_dict = time_format_dict or {}
self.ordinate_names = ordinate_names or DEFAULT_ORDINATE_NAMES
self.deltatime_format_dict = deltatime_format_dict or {}
@staticmethod
def fromSkinDict(skin_dict):
@@ -614,10 +618,16 @@ class Formatter(object):
except KeyError:
ordinate_names = {}
try:
deltatime_format_dict = skin_dict['Units']['DeltaTimeFormats']
except KeyError:
deltatime_format_dict = {}
return Formatter(unit_format_dict,
unit_label_dict,
time_format_dict,
ordinate_names)
ordinate_names,
deltatime_format_dict)
def get_format_string(self, unit):
"""Return a suitable format string."""
@@ -747,14 +757,10 @@ class Formatter(object):
addLabel = False
elif val_t[2] == "group_deltatime":
# Get a delta-time format string. Use a default if the user did not supply one:
if useThisFormat is None:
# For group_deltatime formatting, the default context cannot be 'current'.
# Change it to something sensible.
if context == 'current':
context = 'delta_time'
format_string = self.time_format_dict.get(context, DEFAULT_DELTATIME_FORMAT)
else:
if useThisFormat:
format_string = useThisFormat
else:
format_string = self.deltatime_format_dict.get(context, DEFAULT_DELTATIME_FORMAT)
# Now format the delta time, using the function delta_secs_to_string:
val_str = self.delta_secs_to_string(val_t[0], format_string)
addLabel = False
@@ -1629,7 +1635,9 @@ def get_default_formatter():
unit_format_dict=weewx.defaults.defaults['Units']['StringFormats'],
unit_label_dict=weewx.defaults.defaults['Units']['Labels'],
time_format_dict=weewx.defaults.defaults['Units']['TimeFormats'],
ordinate_names=weewx.defaults.defaults['Units']['Ordinates']['directions'])
ordinate_names=weewx.defaults.defaults['Units']['Ordinates']['directions'],
deltatime_format_dict=weewx.defaults.defaults['Units']['DeltaTimeFormats']
)
return formatter

View File

@@ -11,6 +11,10 @@ Different wake-up strategy for the Vantage console.
Do not write config_path and entry_path to updated configuration dictionary.
Fixes issue #806.
Fix bug that prevents group_deltatime from being used by timespans. Users
who used custom formatting for delta times will be affected. See the Upgrade
Guide. Fixes issue #808.
4.9.1 10/25/2022
Fix problem with `wind` for older versions of sqlite.

View File

@@ -250,6 +250,60 @@ sudo apt-get install weewx</pre>
<h1><a id="Instructions_for_specific_versions">Instructions for specific versions</a></h1>
<h2>Upgrading to V4.10</h2>
<h3>Changes for custom delta time formats</h3>
<p>
The bad news is that fixing issue <a href="https://github.com/weewx/weewx/issues/808">#808</a> required
introducing a separate dictionary for members of group <span class="code">group_deltatime</span>. This
means that if you specified custom formats under <span class="code">[Units]/[[TimeFormats]]</span>, then
you will have to move them to the new section <span class="code">[Units]/[[DeltaTimeFormats]]</span>.
Very few users should be affected as being able to set custom delta time formats is an undocumented feature.
</p>
<p>
The good news is that the contexts they now use have more standard names. The table below summarizes:
</p>
<table>
<tr class="first_row">
<td style='width:50%'>V4.9 and earlier</td>
<td>4.10</td>
</tr>
<tr>
<td>
<pre class='tty'>
def __init__(self, altitude_vt, latitude_f, longitude_f,
[[TimeFormats]]
...
current = %x %X
ephem_day = %X
ephem_year = %x %X
<span class="removed">brief_delta = "%(minute)d%(minute_label)s, %(second)d%(second_label)s"</span>
<span class="removed">short_delta = "%(hour)d%(hour_label)s, %(minute)d%(minute_label)s, %(second)d%(second_label)s"</span>
<span class="removed">long_delta = "%(day)d%(day_label)s, %(hour)d%(hour_label)s, %(minute)d%(minute_label)s"</span>
<span class="removed">delta_time = "%(day)d%(day_label)s, %(hour)d%(hour_label)s, %(minute)d%(minute_label)s"</span>
</pre>
</td>
<td>
<pre class='tty'>
[[TimeFormats]]
...
current = %x %X
ephem_day = %X
ephem_year = %x %X
<span class="added">[[DeltaTimeFormats]]</span>
<span class="added">current = "%(minute)d%(minute_label)s, %(second)d%(second_label)s"</span>
<span class="added">hour = "%(minute)d%(minute_label)s, %(second)d%(second_label)s"</span>
<span class="added">day = "%(hour)d%(hour_label)s, %(minute)d%(minute_label)s, %(second)d%(second_label)s"</span>
<span class="added">week = "%(day)d%(day_label)s, %(hour)d%(hour_label)s, %(minute)d%(minute_label)s"</span>
<span class="added">month = "%(day)d%(day_label)s, %(hour)d%(hour_label)s, %(minute)d%(minute_label)s"</span>
<span class="added">year = "%(day)d%(day_label)s, %(hour)d%(hour_label)s, %(minute)d%(minute_label)s"</span>
</pre>
</td>
</tr>
</table>
<h2>Upgrading to V4.9</h2>
<h3><span class="code">wee_reports</span> may require <span class="code">--epoch</span> option.</h3>
<p>