Merge branch 'master' into development

# Conflicts:
#	docs/changes.txt
This commit is contained in:
Tom Keffer
2021-02-23 06:09:21 -08:00
29 changed files with 201 additions and 163 deletions

View File

@@ -9,6 +9,7 @@
from __future__ import absolute_import
from __future__ import print_function
from six.moves import zip
try:
from PIL import ImageFont, ImageColor
except ImportError:
@@ -188,7 +189,7 @@ def scale(data_min, data_max, prescale=(None, None, None), nsteps=10):
return minscale, maxscale, interval
def scaletime(tmin_ts, tmax_ts) :
def scaletime(tmin_ts, tmax_ts):
"""Picks a time scaling suitable for a time plot.
tmin_ts, tmax_ts: The time stamps in epoch time around which the times will be picked.
@@ -246,16 +247,16 @@ def scaletime(tmin_ts, tmax_ts) :
>>> print(to_string(xmin), to_string(xmax), xinc)
2013-05-16 17:00:00 PDT (1368748800) 2013-05-17 08:00:00 PDT (1368802800) 7200
"""
if tmax_ts <= tmin_ts :
if tmax_ts <= tmin_ts:
raise weeplot.ViolatedPrecondition("scaletime called with tmax <= tmin")
tdelta = tmax_ts - tmin_ts
tmin_dt = datetime.datetime.fromtimestamp(tmin_ts)
tmax_dt = datetime.datetime.fromtimestamp(tmax_ts)
if tdelta <= 16 * 3600:
if tdelta <= 3*3600:
if tdelta <= 3 * 3600:
# For time intervals less than 3 hours, use an increment of 15 minutes
interval = 900
elif tdelta <= 12 * 3600:
@@ -272,72 +273,75 @@ def scaletime(tmin_ts, tmax_ts) :
stop_dt += datetime.timedelta(hours=1)
n_hours = int((tdelta + 3599) / 3600)
start_dt = stop_dt - datetime.timedelta(hours=n_hours)
elif tdelta <= 27 * 3600:
# A day plot is wanted. A time increment of 3 hours is appropriate
interval = 3 * 3600
# h is the hour of tmax_dt
h = tmax_dt.timetuple()[3]
# Subtract off enough to get to the lower 3-hour boundary from tmax:
stop_dt = tmax_dt.replace(minute=0, second=0, microsecond=0) - datetime.timedelta(hours = h % 3)
stop_dt = tmax_dt.replace(minute=0, second=0, microsecond=0) \
- datetime.timedelta(hours=h % 3)
# If tmax happens to lie on a 3 hour boundary we don't need to do anything. If not, we need
# to round up to the next 3 hour boundary:
if tmax_dt > stop_dt:
stop_dt += datetime.timedelta(hours=3)
# The stop time is one day earlier
start_dt = stop_dt - datetime.timedelta(days=1)
if tdelta == 27 * 3600 :
if tdelta == 27 * 3600:
# A "slightly more than a day plot" is wanted. Start 3 hours earlier:
start_dt -= datetime.timedelta(hours=3)
elif 27 * 3600 < tdelta <= 31 * 24 * 3600 :
elif 27 * 3600 < tdelta <= 31 * 24 * 3600:
# The time scale is between a day and a month. A time increment of one day is appropriate
start_dt = tmin_dt.replace(hour=0, minute=0, second=0, microsecond=0)
stop_dt = tmax_dt.replace(hour=0, minute=0, second=0, microsecond=0)
stop_dt = tmax_dt.replace(hour=0, minute=0, second=0, microsecond=0)
tmax_tt = tmax_dt.timetuple()
if tmax_tt[3]!=0 or tmax_tt[4]!=0 :
if tmax_tt[3] != 0 or tmax_tt[4] != 0:
stop_dt += datetime.timedelta(days=1)
interval = 24 * 3600
elif tdelta < 2 * 365.25 * 24 * 3600 :
# The time scale is between a month and 2 years. A time increment of a month is appropriate
elif tdelta <= 2 * 365.25 * 24 * 3600:
# The time scale is between a month and 2 years, inclusive. A time increment of a month
# is appropriate
start_dt = tmin_dt.replace(day=1, hour=0, minute=0, second=0, microsecond=0)
(year , mon, day) = tmax_dt.timetuple()[0:3]
if day != 1 :
year, mon, day = tmax_dt.timetuple()[0:3]
if day != 1:
mon += 1
if mon==13 :
if mon == 13:
mon = 1
year += 1
stop_dt = datetime.datetime(year, mon, 1)
# Average month length:
interval = 365.25/12 * 24 * 3600
else :
# The time scale is between a month and 2 years. A time increment of a year is appropriate
interval = 365.25 / 12 * 24 * 3600
else:
# The time scale is over 2 years. A time increment of six months is appropriate
start_dt = tmin_dt.replace(day=1, hour=0, minute=0, second=0, microsecond=0)
(year , mon, day) = tmax_dt.timetuple()[0:3]
if day != 1 or mon !=1 :
year, mon, day = tmax_dt.timetuple()[0:3]
if day != 1 or mon != 1:
day = 1
mon = 1
year += 1
stop_dt = datetime.datetime(year, mon, 1)
# Average year length
interval = 365.25 * 24 * 3600
# Average length of six months
interval = 365.25 * 24 * 3600 / 2.0
# Convert to epoch time stamps
start_ts = int(time.mktime(start_dt.timetuple()))
stop_ts = int(time.mktime(stop_dt.timetuple()))
stop_ts = int(time.mktime(stop_dt.timetuple()))
return start_ts, stop_ts, interval
return (start_ts, stop_ts, interval)
class ScaledDraw(object):
"""Like an ImageDraw object, but lines are scaled.
"""
def __init__(self, draw, imagebox, scaledbox):
"""Initialize a ScaledDraw object.
@@ -361,14 +365,15 @@ class ScaledDraw(object):
urs = scaledbox[1]
if urs[1] == lls[1]:
pass
self.xscale = float(lri[0] - uli[0]) / float(urs[0] - lls[0])
self.yscale = -float(lri[1] - uli[1]) / float(urs[1] - lls[1])
self.xscale = float(lri[0] - uli[0]) / float(urs[0] - lls[0])
self.yscale = -float(lri[1] - uli[1]) / float(urs[1] - lls[1])
self.xoffset = int(lri[0] - urs[0] * self.xscale + 0.5)
self.yoffset = int(uli[1] - urs[1] * self.yscale + 0.5)
self.draw = draw
def line(self, x, y, line_type='solid', marker_type=None, marker_size=8, maxdx=None, **options) :
self.draw = draw
def line(self, x, y, line_type='solid', marker_type=None, marker_size=8, maxdx=None,
**options):
"""Draw a scaled line on the instance's ImageDraw object.
x: sequence of x coordinates
@@ -391,39 +396,40 @@ class ScaledDraw(object):
"""
# Break the line up around any nulls or gaps between samples
for xy_seq in xy_seq_line(x, y, maxdx):
# Create a list with the scaled coordinates...
xy_seq_scaled = [(self.xtranslate(xc), self.ytranslate(yc)) for (xc,yc) in xy_seq]
# Create a list with the scaled coordinates...
xy_seq_scaled = [(self.xtranslate(xc), self.ytranslate(yc)) for (xc, yc) in xy_seq]
if line_type == 'solid':
# Now pick the appropriate drawing function, depending on the length of the line:
if len(xy_seq) == 1 :
if len(xy_seq) == 1:
self.draw.point(xy_seq_scaled, fill=options['fill'])
else :
else:
self.draw.line(xy_seq_scaled, **options)
if marker_type and marker_type.lower().strip() not in ['none', '']:
self.marker(xy_seq_scaled, marker_type, marker_size=marker_size, **options)
def marker(self, xy_seq, marker_type, marker_size=10, **options):
half_size = marker_size/2
marker=marker_type.lower()
half_size = marker_size / 2
marker = marker_type.lower()
for x, y in xy_seq:
if marker == 'cross':
self.draw.line([(x-half_size, y), (x+half_size, y)], **options)
self.draw.line([(x, y-half_size), (x, y+half_size)], **options)
self.draw.line([(x - half_size, y), (x + half_size, y)], **options)
self.draw.line([(x, y - half_size), (x, y + half_size)], **options)
elif marker == 'x':
self.draw.line([(x-half_size, y-half_size), (x+half_size, y+half_size)], **options)
self.draw.line([(x-half_size, y+half_size), (x+half_size, y-half_size)], **options)
self.draw.line([(x - half_size, y - half_size), (x + half_size, y + half_size)],
**options)
self.draw.line([(x - half_size, y + half_size), (x + half_size, y - half_size)],
**options)
elif marker == 'circle':
self.draw.ellipse([(x-half_size, y-half_size),
(x+half_size, y+half_size)], outline=options['fill'])
self.draw.ellipse([(x - half_size, y - half_size),
(x + half_size, y + half_size)], outline=options['fill'])
elif marker == 'box':
self.draw.line([(x-half_size, y-half_size),
(x+half_size, y-half_size),
(x+half_size, y+half_size),
(x-half_size, y+half_size),
(x-half_size, y-half_size)], **options)
def rectangle(self, box, **options) :
self.draw.line([(x - half_size, y - half_size),
(x + half_size, y - half_size),
(x + half_size, y + half_size),
(x - half_size, y + half_size),
(x - half_size, y - half_size)], **options)
def rectangle(self, box, **options):
"""Draw a scaled rectangle.
box: A pair of 2-way tuples, containing coordinates of opposing corners
@@ -431,33 +437,34 @@ class ScaledDraw(object):
options: passed on to draw.rectangle. Usually contains 'fill' (the color)
"""
box_scaled = [(coord[0]*self.xscale + self.xoffset + 0.5, coord[1]*self.yscale + self.yoffset + 0.5) for coord in box]
box_scaled = [(coord[0] * self.xscale + self.xoffset + 0.5,
coord[1] * self.yscale + self.yoffset + 0.5) for coord in box]
self.draw.rectangle(box_scaled, **options)
def vector(self, x, vec, vector_rotate, **options):
if vec is None:
if vec is None:
return
xstart_scaled = self.xtranslate(x)
ystart_scaled = self.ytranslate(0)
vecinc_scaled = vec * self.yscale
if vector_rotate:
vecinc_scaled *= complex(math.cos(math.radians(vector_rotate)),
math.sin(math.radians(vector_rotate)))
# Subtract off the x increment because the x-axis
# *increases* to the right, unlike y, which increases
# downwards
xend_scaled = xstart_scaled - vecinc_scaled.real
yend_scaled = ystart_scaled + vecinc_scaled.imag
self.draw.line(((xstart_scaled, ystart_scaled), (xend_scaled, yend_scaled)), **options)
def xtranslate(self, x):
return int(x * self.xscale + self.xoffset + 0.5)
def ytranslate(self, y):
return int(y * self.yscale + self.yoffset + 0.5)
@@ -509,7 +516,7 @@ def xy_seq_line(x, y, maxdx=None):
[(0, 0), (1, 10), (2, 20), (3, 30)]
[(5.1, 50), (6, 60), (7, 70), (8, 80), (9, 90)]
"""
line = []
last_x = None
for xy in zip(x, y):
@@ -526,6 +533,7 @@ def xy_seq_line(x, y, maxdx=None):
if len(line):
yield line
def pickLabelFormat(increment):
"""Pick an appropriate label format for the given increment.
@@ -541,16 +549,17 @@ def pickLabelFormat(increment):
"""
i_log = math.log10(increment)
if i_log < 0 :
if i_log < 0:
i_log = abs(i_log)
decimal_places = int(i_log)
if i_log != decimal_places :
if i_log != decimal_places:
decimal_places += 1
else :
else:
decimal_places = 0
return "%%.%df" % decimal_places
def get_font_handle(fontpath, *args):
"""Get a handle for a font path, caching the results"""
@@ -563,21 +572,24 @@ def get_font_handle(fontpath, *args):
return get_font_handle.fontCache[font_key]
font = None
if fontpath_str is not None :
try :
if fontpath_str is not None:
try:
if fontpath_str.endswith('.ttf'):
font = ImageFont.truetype(fontpath_str, *args)
else :
else:
font = ImageFont.load_path(fontpath_str)
except IOError :
except IOError:
pass
if font is None :
if font is None:
font = ImageFont.load_default()
if font is not None :
if font is not None:
get_font_handle.fontCache[font_key] = font
return font
get_font_handle.fontCache={}
return font
get_font_handle.fontCache = {}
def _rel_approx_equal(x, y, rel=1e-7):
"""Relative test for equality.
@@ -598,7 +610,7 @@ def _rel_approx_equal(x, y, rel=1e-7):
>>> rel_approx_equal(1e8, 1e8+1e-3)
True
"""
return abs(x-y) <= rel*max(abs(x), abs(y))
return abs(x - y) <= rel * max(abs(x), abs(y))
def tobgr(x):
@@ -612,8 +624,8 @@ def tobgr(x):
if x.startswith('0x'):
return int(x, 0)
try:
(r,g,b) = ImageColor.getrgb(x)
return r + g*256 + b*256*256
r, g, b = ImageColor.getrgb(x)
return r + g * 256 + b * 256 * 256
except ValueError:
try:
return int(x)
@@ -622,9 +634,9 @@ def tobgr(x):
"Colors must be specified as 0xBBGGRR, #RRGGBB, or standard color names." % x)
return x
if __name__ == "__main__":
import doctest
if not doctest.testmod().failed:
print("PASSED")

View File

@@ -32,14 +32,14 @@ Example:
[CheetahGenerator]
# How to specify search list extensions:
search_list_extensions = user.forecast.ForecastVariables, user.extstats.ExtStatsVariables
encoding = html_entities # html_entities, utf8, strict_ascii, or normalized_ascii
encoding = html_entities
[[SummaryByMonth]] # period
[[[NOAA_month]]] # report
encoding = utf8
encoding = normalized_ascii
template = NOAA-YYYY-MM.txt.tmpl
[[SummaryByYear]]
[[[NOAA_year]]]]
encoding = utf8
encoding = normalized_ascii
template = NOAA-YYYY.txt.tmpl
[[ToDate]]
[[[day]]]
@@ -335,7 +335,7 @@ class CheetahGenerator(weewx.reportengine.ReportGenerator):
normalized = unicodedata.normalize('NFD', unicode_string)
byte_string = normalized.encode('ascii', 'ignore')
else:
byte_string = unicode_string.encode('utf8')
byte_string = unicode_string.encode(encoding)
# Open in binary mode. We are writing a byte-string, not a string
with open(tmpname, mode='wb') as fd:

View File

@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
#
# Copyright (c) 2009-2020 Tom Keffer <tkeffer@gmail.com>
# Copyright (c) 2009-2021 Tom Keffer <tkeffer@gmail.com>
#
# See the file LICENSE.txt for your full rights.
#
@@ -32,7 +32,7 @@ from weewx.crc16 import crc16
log = logging.getLogger(__name__)
DRIVER_NAME = 'Vantage'
DRIVER_VERSION = '3.2.1'
DRIVER_VERSION = '3.2.2'
def loader(config_dict, engine):
@@ -107,12 +107,13 @@ class BaseWrapper(object):
if _resp == b'\n\r':
log.debug("Rude wake up of console successful")
return
print("Unable to wake up console... sleeping")
time.sleep(self.wait_before_retry)
print("Unable to wake up console... retrying")
except weewx.WeeWxIOError:
pass
log.debug("Retry #%d failed", count)
print("Unable to wake up console... sleeping")
time.sleep(self.wait_before_retry)
print("Unable to wake up console... retrying")
log.error("Unable to wake up console")
raise weewx.WakeupError("Unable to wake up Vantage console")

View File

@@ -717,7 +717,7 @@ class StdPWSWeather(StdRESTful):
"""Specialized version of the Ambient protocol for PWSWeather"""
# The URL used by PWSWeather:
archive_url = "http://www.pwsweather.com/pwsupdate/pwsupdate.php"
archive_url = "https://www.pwsweather.com/pwsupdate/pwsupdate.php"
def __init__(self, engine, config_dict):
super(StdPWSWeather, self).__init__(engine, config_dict)
@@ -756,7 +756,7 @@ class StdWOW(StdRESTful):
"""
# The URL used by WOW:
archive_url = "http://wow.metoffice.gov.uk/automaticreading"
archive_url = "https://wow.metoffice.gov.uk/automaticreading"
def __init__(self, engine, config_dict):
super(StdWOW, self).__init__(engine, config_dict)

View File

@@ -1,11 +1,11 @@
TEST MONTHLY CLIMATOLOGICAL SUMMARY for Jan 2010
NAME: Ĺōćāţĩőń with UTF8 characters
NAME: Location with UTF8 characters
ELEV: 328 feet LAT: 45-41.16 N LONG: 121-33.96 W
TEMPERATURE (°F), RAIN (in), WIND SPEED (mph)
TEMPERATURE (F), RAIN (in), WIND SPEED (mph)
HEAT COOL AVG
MEAN DEG DEG WIND DOM

View File

@@ -1,11 +1,11 @@
TEST MONTHLY CLIMATOLOGICAL SUMMARY for Feb 2010
NAME: Ĺōćāţĩőń with UTF8 characters
NAME: Location with UTF8 characters
ELEV: 328 feet LAT: 45-41.16 N LONG: 121-33.96 W
TEMPERATURE (°F), RAIN (in), WIND SPEED (mph)
TEMPERATURE (F), RAIN (in), WIND SPEED (mph)
HEAT COOL AVG
MEAN DEG DEG WIND DOM

View File

@@ -1,11 +1,11 @@
TEST MONTHLY CLIMATOLOGICAL SUMMARY for Mar 2010
NAME: Ĺōćāţĩőń with UTF8 characters
NAME: Location with UTF8 characters
ELEV: 328 feet LAT: 45-41.16 N LONG: 121-33.96 W
TEMPERATURE (°F), RAIN (in), WIND SPEED (mph)
TEMPERATURE (F), RAIN (in), WIND SPEED (mph)
HEAT COOL AVG
MEAN DEG DEG WIND DOM

View File

@@ -1,11 +1,11 @@
TEST MONTHLY CLIMATOLOGICAL SUMMARY for Apr 2010
NAME: Ĺōćāţĩőń with UTF8 characters
NAME: Location with UTF8 characters
ELEV: 328 feet LAT: 45-41.16 N LONG: 121-33.96 W
TEMPERATURE (°F), RAIN (in), WIND SPEED (mph)
TEMPERATURE (F), RAIN (in), WIND SPEED (mph)
HEAT COOL AVG
MEAN DEG DEG WIND DOM

View File

@@ -1,11 +1,11 @@
TEST MONTHLY CLIMATOLOGICAL SUMMARY for May 2010
NAME: Ĺōćāţĩőń with UTF8 characters
NAME: Location with UTF8 characters
ELEV: 328 feet LAT: 45-41.16 N LONG: 121-33.96 W
TEMPERATURE (°F), RAIN (in), WIND SPEED (mph)
TEMPERATURE (F), RAIN (in), WIND SPEED (mph)
HEAT COOL AVG
MEAN DEG DEG WIND DOM

View File

@@ -1,11 +1,11 @@
TEST MONTHLY CLIMATOLOGICAL SUMMARY for Jun 2010
NAME: Ĺōćāţĩőń with UTF8 characters
NAME: Location with UTF8 characters
ELEV: 328 feet LAT: 45-41.16 N LONG: 121-33.96 W
TEMPERATURE (°F), RAIN (in), WIND SPEED (mph)
TEMPERATURE (F), RAIN (in), WIND SPEED (mph)
HEAT COOL AVG
MEAN DEG DEG WIND DOM

View File

@@ -1,11 +1,11 @@
TEST MONTHLY CLIMATOLOGICAL SUMMARY for Jul 2010
NAME: Ĺōćāţĩőń with UTF8 characters
NAME: Location with UTF8 characters
ELEV: 328 feet LAT: 45-41.16 N LONG: 121-33.96 W
TEMPERATURE (°F), RAIN (in), WIND SPEED (mph)
TEMPERATURE (F), RAIN (in), WIND SPEED (mph)
HEAT COOL AVG
MEAN DEG DEG WIND DOM

View File

@@ -1,11 +1,11 @@
TEST MONTHLY CLIMATOLOGICAL SUMMARY for Aug 2010
NAME: Ĺōćāţĩőń with UTF8 characters
NAME: Location with UTF8 characters
ELEV: 328 feet LAT: 45-41.16 N LONG: 121-33.96 W
TEMPERATURE (°F), RAIN (in), WIND SPEED (mph)
TEMPERATURE (F), RAIN (in), WIND SPEED (mph)
HEAT COOL AVG
MEAN DEG DEG WIND DOM

View File

@@ -1,11 +1,11 @@
TEST MONTHLY CLIMATOLOGICAL SUMMARY for Sep 2010
NAME: Ĺōćāţĩőń with UTF8 characters
NAME: Location with UTF8 characters
ELEV: 328 feet LAT: 45-41.16 N LONG: 121-33.96 W
TEMPERATURE (°F), RAIN (in), WIND SPEED (mph)
TEMPERATURE (F), RAIN (in), WIND SPEED (mph)
HEAT COOL AVG
MEAN DEG DEG WIND DOM

View File

@@ -1,11 +1,11 @@
TEST MONTHLY CLIMATOLOGICAL SUMMARY for Jan 2010
NAME: Ĺōćāţĩőń with UTF8 characters
NAME: Location with UTF8 characters
ELEV: 100 meters LAT: 45-41.16 N LONG: 121-33.96 W
TEMPERATURE (°C), RAIN (mm), WIND SPEED (kph)
TEMPERATURE (C), RAIN (mm), WIND SPEED (kph)
HEAT COOL AVG
MEAN DEG DEG WIND DOM

View File

@@ -1,11 +1,11 @@
TEST MONTHLY CLIMATOLOGICAL SUMMARY for Feb 2010
NAME: Ĺōćāţĩőń with UTF8 characters
NAME: Location with UTF8 characters
ELEV: 100 meters LAT: 45-41.16 N LONG: 121-33.96 W
TEMPERATURE (°C), RAIN (mm), WIND SPEED (kph)
TEMPERATURE (C), RAIN (mm), WIND SPEED (kph)
HEAT COOL AVG
MEAN DEG DEG WIND DOM

View File

@@ -1,11 +1,11 @@
TEST MONTHLY CLIMATOLOGICAL SUMMARY for Mar 2010
NAME: Ĺōćāţĩőń with UTF8 characters
NAME: Location with UTF8 characters
ELEV: 100 meters LAT: 45-41.16 N LONG: 121-33.96 W
TEMPERATURE (°C), RAIN (mm), WIND SPEED (kph)
TEMPERATURE (C), RAIN (mm), WIND SPEED (kph)
HEAT COOL AVG
MEAN DEG DEG WIND DOM

View File

@@ -1,11 +1,11 @@
TEST MONTHLY CLIMATOLOGICAL SUMMARY for Apr 2010
NAME: Ĺōćāţĩőń with UTF8 characters
NAME: Location with UTF8 characters
ELEV: 100 meters LAT: 45-41.16 N LONG: 121-33.96 W
TEMPERATURE (°C), RAIN (mm), WIND SPEED (kph)
TEMPERATURE (C), RAIN (mm), WIND SPEED (kph)
HEAT COOL AVG
MEAN DEG DEG WIND DOM

View File

@@ -1,11 +1,11 @@
TEST MONTHLY CLIMATOLOGICAL SUMMARY for May 2010
NAME: Ĺōćāţĩőń with UTF8 characters
NAME: Location with UTF8 characters
ELEV: 100 meters LAT: 45-41.16 N LONG: 121-33.96 W
TEMPERATURE (°C), RAIN (mm), WIND SPEED (kph)
TEMPERATURE (C), RAIN (mm), WIND SPEED (kph)
HEAT COOL AVG
MEAN DEG DEG WIND DOM

View File

@@ -1,11 +1,11 @@
TEST MONTHLY CLIMATOLOGICAL SUMMARY for Jun 2010
NAME: Ĺōćāţĩőń with UTF8 characters
NAME: Location with UTF8 characters
ELEV: 100 meters LAT: 45-41.16 N LONG: 121-33.96 W
TEMPERATURE (°C), RAIN (mm), WIND SPEED (kph)
TEMPERATURE (C), RAIN (mm), WIND SPEED (kph)
HEAT COOL AVG
MEAN DEG DEG WIND DOM

View File

@@ -1,11 +1,11 @@
TEST MONTHLY CLIMATOLOGICAL SUMMARY for Jul 2010
NAME: Ĺōćāţĩőń with UTF8 characters
NAME: Location with UTF8 characters
ELEV: 100 meters LAT: 45-41.16 N LONG: 121-33.96 W
TEMPERATURE (°C), RAIN (mm), WIND SPEED (kph)
TEMPERATURE (C), RAIN (mm), WIND SPEED (kph)
HEAT COOL AVG
MEAN DEG DEG WIND DOM

View File

@@ -1,11 +1,11 @@
TEST MONTHLY CLIMATOLOGICAL SUMMARY for Aug 2010
NAME: Ĺōćāţĩőń with UTF8 characters
NAME: Location with UTF8 characters
ELEV: 100 meters LAT: 45-41.16 N LONG: 121-33.96 W
TEMPERATURE (°C), RAIN (mm), WIND SPEED (kph)
TEMPERATURE (C), RAIN (mm), WIND SPEED (kph)
HEAT COOL AVG
MEAN DEG DEG WIND DOM

View File

@@ -1,11 +1,11 @@
TEST MONTHLY CLIMATOLOGICAL SUMMARY for Sep 2010
NAME: Ĺōćāţĩőń with UTF8 characters
NAME: Location with UTF8 characters
ELEV: 100 meters LAT: 45-41.16 N LONG: 121-33.96 W
TEMPERATURE (°C), RAIN (mm), WIND SPEED (kph)
TEMPERATURE (C), RAIN (mm), WIND SPEED (kph)
HEAT COOL AVG
MEAN DEG DEG WIND DOM

View File

@@ -88,7 +88,7 @@
# Reports that summarize "by month"
#
[[[by_month]]]
encoding = utf8
encoding = normalized_ascii
template = bymonth-YYYY-MM.txt.tmpl
[[SummaryByYear]]

View File

@@ -7,13 +7,26 @@ The utility wee_database has new option --add-column and --rename-column for
adding and renaming columns in the database.
4.4.1 MM/DD/YYYY
Changed NOAA reports to use the 'normalized_ascii' encoding instead of 'utf8'
(which did not display correctly for most browsers). Fixes issue #646.
Plots longer than 2 years use a 6 month time increment.
Uploads to PWSWeather and WOW now use HTTPS. Fixes issue #650.
Fixed bug that prevented the Vantage driver from waiting before a wakeup retry.
Thanks to user Les Niles!
4.4.0 01/30/2021
StdWXCalculate can now do calculations for only LOOP packets, only archive
records, or both. PR #630. Thanks to user g-eddy!
Introduced aggregate types "avg_ge" and "avg_le". PR #631. Thanks again to user
g-eddy!
Introduced aggregate types "avg_ge" and "avg_le". PR #631. Thanks to user
edi-x!
NOAA reports now use a 'utf8' encoding instead of 'strict_ascii'. This will only
affect new installations. Fixes issue #644.

View File

@@ -1633,19 +1633,20 @@ db_manager.getSql("SELECT SUM(rain) FROM %s "\
# The CheetahGenerator creates files from templates. This section
# specifies which files will be generated from which template.
# Possible encodings are 'html_entities', 'utf8', 'strict_ascii', or 'normalized_ascii'
# Possible encodings include 'html_entities', 'strict_ascii', 'normalized_ascii',
# as well as those listed in https://docs.python.org/3/library/codecs.html#standard-encodings
encoding = html_entities
[[SummaryByMonth]]
# Reports that summarize "by month"
[[[NOAA_month]]]
encoding = utf8
encoding = normalized_ascii
template = NOAA/NOAA-%Y-%m.txt.tmpl
[[SummaryByYear]]
# Reports that summarize "by year"
[[[NOAA_year]]]
encoding = utf8
encoding = normalized_ascii
template = NOAA/NOAA-%Y.txt.tmpl
[[ToDate]]
@@ -1709,7 +1710,7 @@ db_manager.getSql("SELECT SUM(rain) FROM %s "\
[[SummaryByYear]]
# Reports that summarize "by year"
[[[NOAA_year]]]
encoding = utf8
encoding = normalized_ascii
template = NOAA/NOAA-%Y.txt.tmpl
</pre>
@@ -1738,7 +1739,7 @@ $record.dateTime $record.outTemp $record.outHumidity
[[SummaryByMonth]]
# Reports that summarize "by month"
[[[NOAA_month]]]
encoding = utf8
encoding = normalized_ascii
template = NOAA/NOAA-%Y-%m.txt.tmpl
</pre>
@@ -1767,7 +1768,7 @@ $record.dateTime $record.outTemp $record.outHumidity
[[SummaryByDay]]
# Reports that summarize "by day"
[[[NOAA_day]]]
encoding = utf8
encoding = normalized_ascii
template = NOAA/NOAA-%Y-%m-%d.txt.tmpl
</pre>
@@ -3498,7 +3499,8 @@ class MyStats(SearchList): # 1
# This section is used by the generator CheetahGenerator, and specifies
# which files are to be generated from which template.
# Possible encodings are 'html_entities', 'utf8', 'strict_ascii', or 'normalized_ascii'
# Possible encodings include 'html_entities', 'strict_ascii', 'normalized_ascii',
# as well as those listed in https://docs.python.org/3/library/codecs.html#standard-encodings
encoding = html_entities
<span class="highlight">search_list_extensions = user.stats.MyStats</span>
@@ -5909,8 +5911,10 @@ growing_base = 50.0, degree_F</pre>
<p>
As Cheetah goes through the template, it substitutes strings for all tag values. This option controls which
encoding to use for the new strings. The encoding can be chosen on a per file basis. There are 3 possible
choices:
encoding to use for the new strings. The encoding can be chosen on a per file basis. All of the encodings
listed in the Python documentation
<a href="https://docs.python.org/3/library/codecs.html#standard-encodings"><em>Standard Encodings</em></a>
are available, as well as these WeeWX-specific encodings:
</p>
<table class="indent">
<tbody>
@@ -5924,10 +5928,6 @@ growing_base = 50.0, degree_F</pre>
represented as <span class="code">&amp;#176;</span>)
</td>
</tr>
<tr>
<td class="code first_col">utf8</td>
<td>Non 7-bit characters will be represented in UTF-8.</td>
</tr>
<tr>
<td class="code first_col">strict_ascii</td>
<td>Non 7-bit characters will be ignored.</td>
@@ -5939,7 +5939,9 @@ growing_base = 50.0, degree_F</pre>
</tbody>
</table>
<p>
The encoding <span class="code">html_entities</span> is the default.
The encoding <span class="code">html_entities</span> is the default. Other common choices are <span
class="code">utf8</span>, <span class="code">cp1252</span> (<em>a.k.a.</em> Windows-1252), and <span
class="code">latin1</span>.
</p>
<p class="config_option" id="option_template">template</p>

View File

@@ -541,7 +541,7 @@ Version: 4.4
<td></td>
</tr>
<tr>
<td class="text_highlight" rowspan="14">Oregon Scientific</td>
<td class="text_highlight" rowspan="12">Oregon Scientific</td>
<td>WMR88</td>
<td>USB</td>
<td class="code">pyusb</td>
@@ -670,7 +670,7 @@ Version: 4.4
<td>Tested</td>
</tr>
<tr>
<td class="text_highlight" rowspan="3">Radio Shack</td>
<td class="text_highlight" rowspan="2">Radio Shack</td>
<td>63-256</td>
<td>USB</td>
<td class="code">pyusb</td>

View File

@@ -188,16 +188,24 @@ sudo apt-get install weewx</pre>
Z : start a shell to examine the situation
The default action is to keep your current version.
*** weewx.conf (Y/I/N/O/D/Z) [default=N] ?</pre>
<p>Choosing <span class='code'>I</span> (install the new version) will place the previous configuration in <span
class='code'>/etc/weewx/weewx.conf.dpkg-old</span> where it can be compared with the new version <span
class='code'>/etc/weewx/weewx.conf</span>
<p>
Choosing <span class="code">Y</span> or <span class='code'>I</span> (install the new version) will place
your old configuration in <span class='code'>/etc/weewx/weewx.conf.dpkg-old</span>, where it can be compared
with the new version in <span class='code'>/etc/weewx/weewx.conf</span>.
</p>
<p>Choosing <span class='code'>O</span> (keep the current version) will place the new configuration in <span
class='code'>/etc/weewx/weewx.conf.dpkg-new</span> where it can be compared with the old version <span
class='code'>/etc/weewx/weewx.conf</span>
<p>
Choosing <span class="code">N</span> or <span class='code'>O</span> (keep the current version) will place
the new configuration in <span class='code'>/etc/weewx/weewx.conf.X.Y.Z</span>, where <span class="code">X.Y.Z</span>
is the new version number. It can then be compared with your old version which will be in <span
class='code'>/etc/weewx/weewx.conf</span>.
</p>
<p class="note">
The vast majority of the time you will want to choose <span class="code">N</span> (the default), and keep
your old version of <span class="code">weewx.conf</span>.
</p>
<h1><a id="Upgrading_using_RPM_package">Upgrading using RPM package</a></h1>

View File

@@ -56,19 +56,20 @@
[CheetahGenerator]
# Possible encodings are 'html_entities', 'utf8', 'strict_ascii', or 'normalized_ascii'
# Possible encodings include 'html_entities', 'strict_ascii', 'normalized_ascii',
# as well as those listed in https://docs.python.org/3/library/codecs.html#standard-encodings
encoding = html_entities
[[SummaryByMonth]]
# Reports that summarize "by month"
[[[NOAA_month]]]
encoding = utf8
encoding = normalized_ascii
template = NOAA/NOAA-%Y-%m.txt.tmpl
[[SummaryByYear]]
# Reports that summarize "by year"
[[[NOAA_year]]]
encoding = utf8
encoding = normalized_ascii
template = NOAA/NOAA-%Y.txt.tmpl
[[ToDate]]

View File

@@ -25,19 +25,20 @@
[CheetahGenerator]
# Possible encodings are 'html_entities', 'utf8', 'strict_ascii', or 'normalized_ascii'
# Possible encodings include 'html_entities', 'utf8', 'strict_ascii', or 'normalized_ascii',
# as well as those listed in https://docs.python.org/3/library/codecs.html#standard-encodings
encoding = html_entities
[[SummaryByMonth]]
# Reports that summarize "by month"
[[[NOAA_month]]]
encoding = utf8
encoding = normalized_ascii
template = NOAA/NOAA-%Y-%m.txt.tmpl
[[SummaryByYear]]
# Reports that summarize "by year"
[[[NOAA_year]]]
encoding = utf8
encoding = normalized_ascii
template = NOAA/NOAA-%Y.txt.tmpl
[[ToDate]]