mirror of
https://github.com/weewx/weewx.git
synced 2026-06-09 09:35:19 -04:00
Checkpoint
This commit is contained in:
274
merge.conf
274
merge.conf
@@ -1,274 +0,0 @@
|
||||
############################################################################################
|
||||
# #
|
||||
# #
|
||||
# FTP CONFIGURATION FILE #
|
||||
# #
|
||||
# #
|
||||
############################################################################################
|
||||
# #
|
||||
# Copyright (c) 2010 Tom Keffer <tkeffer@gmail.com> #
|
||||
# #
|
||||
# See the file LICENSE.txt for your full rights. #
|
||||
# #
|
||||
############################################################################################
|
||||
#
|
||||
# $Revision: 164 $
|
||||
# $Author: tkeffer $
|
||||
# $Date: 2010-03-16 16:16:04 -0700 (Tue, 16 Mar 2010) $
|
||||
#
|
||||
############################################################################################
|
||||
|
||||
# This isn't really a "report". Instead, we use the report engine to run an FTP service.
|
||||
|
||||
# The list of generators that are part of this report:
|
||||
generator_list = weewx.reportengine.Ftp,
|
||||
skin = Ftp
|
||||
debug = 0
|
||||
socket_timeout = 20
|
||||
version = 1.6.0
|
||||
[Station]
|
||||
|
||||
#
|
||||
# This section is for information about your station
|
||||
#
|
||||
|
||||
# Root directory of the weewx file hierarchy for this station:
|
||||
WEEWX_ROOT = /home/tkeffer/workspace/weewx
|
||||
|
||||
location = "Hood River, Oregon"
|
||||
|
||||
# Latitude, longitude in decimal degrees
|
||||
latitude = 45.686
|
||||
longitude = -121.566
|
||||
|
||||
# Altitude of the station in the same units as group_altitude (see section 'Units')
|
||||
altitude = 700
|
||||
|
||||
rain_year_start = 10
|
||||
radar_url = http://radar.weather.gov/ridge/lite/N0R/RTX_loop.gif
|
||||
|
||||
# Base temperature for heating days, in the same units as group_temperature:
|
||||
heating_base = 65
|
||||
# Base temperature for cooling days, in the same units as group_temperature:
|
||||
cooling_base = 65
|
||||
|
||||
# Start of week (0=Monday, 6 = Sunday)
|
||||
week_start = 6
|
||||
|
||||
# Set to hemisphere abbreviations suitable for your location:
|
||||
hemispheres = N, S, E, W
|
||||
|
||||
# How often to check the clock on the weather station for drift (in seconds)
|
||||
clock_check = 14400
|
||||
|
||||
# Set to 1 (one) to cache LOOP data, otherwise zero. Most people
|
||||
# will want to set this to one unless you have a specialized application
|
||||
cache_loop_data = 1
|
||||
|
||||
# Set to type of station (e.g., 'VantagePro' for a Davis VantagePro or VantagePro2)
|
||||
# Must match section name below.
|
||||
station_type = VantagePro
|
||||
[VantagePro]
|
||||
|
||||
#
|
||||
# This section is for configuration info for a Davis VantagePro or
|
||||
# VantagePro2
|
||||
#
|
||||
|
||||
# Its port.
|
||||
#
|
||||
# Ubuntu and SuSE:
|
||||
# /dev/ttyUSB0 is a common USB port name
|
||||
# /dev/ttyS0 a common serial port name
|
||||
port = /dev/ttyUSB0
|
||||
#port = /dev/ttyS0
|
||||
|
||||
# Its baud rate (usually 19200)
|
||||
baudrate = 19200
|
||||
|
||||
# Archive interval in seconds for your station. (Used only when configuring
|
||||
# the station; otherwise it is downloaded from the station)
|
||||
archive_interval = 300
|
||||
|
||||
# The id of your ISS station (usually 1)
|
||||
iss_id = 1
|
||||
|
||||
# How long to wait (in seconds) before processing new archive data
|
||||
archive_delay = 15
|
||||
|
||||
# How long to wait for a response from the station before giving up (in
|
||||
# seconds; must be greater than 2)
|
||||
timeout = 5
|
||||
|
||||
# How long to wait before trying again (in seconds)
|
||||
wait_before_retry = 1.2
|
||||
|
||||
# How many times to try before giving up:
|
||||
max_retries = 4
|
||||
|
||||
# How much it can drift before we will correct it (in seconds):
|
||||
max_drift = 5
|
||||
|
||||
# What unit system to use on the station. 1=US Customary (the only one the VP
|
||||
# supports)
|
||||
unit_system = 1
|
||||
[FTP]
|
||||
|
||||
#
|
||||
# This section is for configuring FTP uploads to a remote web server.
|
||||
#
|
||||
# If you wish to do this, make sure the following four lines are uncommented
|
||||
# and filled out somewhere in this section:
|
||||
# user = replace with your username
|
||||
# password = replace with your password
|
||||
# server = replace with your server name, e.g, www.threefools.org
|
||||
# path = replace with the destination root directory on your server (e.g., '/weather)
|
||||
|
||||
# Set to 1 to use passive mode, zero for active mode:
|
||||
passive = 1
|
||||
|
||||
# How many times to try to transfer a file before giving up:
|
||||
max_retries = 3
|
||||
[Wunderground]
|
||||
[Archive]
|
||||
|
||||
#
|
||||
# This section is for configuration info about the sqlite3 archive database
|
||||
#
|
||||
|
||||
# The path to the database, relative to the WEEWX_ROOT directory
|
||||
archive_file = archive/weewx.sdb
|
||||
|
||||
# What unit system to use in the database. 1=US Customary (the only
|
||||
# one supported now)
|
||||
unit_system = 1
|
||||
[Stats]
|
||||
|
||||
#
|
||||
# This section is for configuration info about the sqlite3 statistical
|
||||
# database
|
||||
#
|
||||
|
||||
# Path to the statistics database, relative to the WEEWX_ROOT directory:
|
||||
stats_file = archive/stats.sdb
|
||||
|
||||
# The types for which Hi/Low statistics will be kept. Types not listed will
|
||||
# not be available for HTML pages and other stats. Note that while most
|
||||
# types correspond to their SQL counterpart, 'wind' is a special type that
|
||||
# replaces windSpeed and windGust. It can answer queries such as dominant
|
||||
# wind directions, etc. If not given, statistics will be kept for all
|
||||
# possible types, resulting in a possibly much bigger than necessary stats
|
||||
# database.
|
||||
|
||||
stats_types = wind, barometer, inTemp, outTemp, inHumidity, outHumidity, rainRate, rain, dewpoint, windchill, heatindex, ET, radiation, UV, extraTemp1, rxCheckPercent
|
||||
[Units]
|
||||
|
||||
#
|
||||
# This section is for managing the selection and formatting of units.
|
||||
#
|
||||
|
||||
[[Groups]]
|
||||
#
|
||||
# For each group of measurements, this section sets what units to use for it.
|
||||
# NB: The unit is always in the singular. I.e., 'mile_per_hour', NOT 'miles_per_hour'
|
||||
#
|
||||
group_altitude = foot# Options are 'foot' or 'meter'
|
||||
group_direction = degree_compass
|
||||
group_moisture = centibar
|
||||
group_percent = percent
|
||||
group_pressure = inHg# Options are 'inHg', 'mbar', or 'hPa'
|
||||
group_radiation = watt_per_meter_squared
|
||||
group_rain = inch# Options are 'inch', 'cm', or 'mm'
|
||||
group_rainrate = inch_per_hour# Options are 'inch_per_hour', 'cm_per_hour', or 'mm_per_hour'
|
||||
group_speed = mile_per_hour# Options are 'mile_per_hour', 'km_per_hour', 'knot', or 'meter_per_second'
|
||||
group_speed2 = mile_per_hour2# Options are 'mile_per_hour2', 'km_per_hour2', 'knot2', or 'meter_per_second2'
|
||||
group_temperature = degree_F# Options are 'degree_F' or 'degree_C'
|
||||
group_volt = volt
|
||||
|
||||
[[StringFormats]]
|
||||
#
|
||||
# This section sets the string formatting for each type of unit.
|
||||
#
|
||||
centibar = %.0f
|
||||
cm = %.2f
|
||||
cm_per_hour = %.2f
|
||||
degree_C = %.1f
|
||||
degree_compass = %.0f
|
||||
degree_F = %.1f
|
||||
foot = %.0f
|
||||
hPa = %.1f
|
||||
inHg = %.3f
|
||||
inch = %.2f
|
||||
inch_per_hour = %.2f
|
||||
km_per_hour = %.0f
|
||||
km_per_hour2 = %.1f
|
||||
knot = %.0f
|
||||
knot2 = %.1f
|
||||
mbar = %.1f
|
||||
meter = %.0f
|
||||
meter_per_second = %.0f
|
||||
meter_per_second2 = %.1f
|
||||
mile_per_hour = %.0f
|
||||
mile_per_hour2 = %.1f
|
||||
mm = %.1f
|
||||
mm_per_hour = %.1f
|
||||
percent = %.0f
|
||||
volt = %.1f
|
||||
watt_per_meter_squared = %.0f
|
||||
|
||||
[[Labels]]
|
||||
#
|
||||
# This section sets a label to be used for each type of unit.
|
||||
#
|
||||
centibar = cb
|
||||
cm = cm
|
||||
cm_per_hour = cm/hr
|
||||
degree_C = \xb0C
|
||||
degree_compass = \xb0
|
||||
degree_F = \xb0F
|
||||
foot = feet
|
||||
hPa = hPa
|
||||
inHg = inHg
|
||||
inch = in
|
||||
inch_per_hour = in/hr
|
||||
km_per_hour = kph
|
||||
km_per_hour2 = kph
|
||||
knot = knots
|
||||
knot2 = knots
|
||||
mbar = mbar
|
||||
meter = meters
|
||||
meter_per_second = m/s
|
||||
meter_per_second2 = m/s
|
||||
mile_per_hour = mph
|
||||
mile_per_hour2 = mph
|
||||
mm = mm
|
||||
mm_per_hour = mm/hr
|
||||
percent = %
|
||||
volt = V
|
||||
watt_per_meter_squared = W/m\xb2
|
||||
[Reports]
|
||||
|
||||
#
|
||||
# Where the skins reside, relative to WEEWX_ROOT:
|
||||
#
|
||||
SKIN_ROOT = skins
|
||||
|
||||
#
|
||||
# Where the generated reports should go, relative to WEEWX_ROOT:
|
||||
#
|
||||
HTML_ROOT = public_html
|
||||
|
||||
# Each subsection represents a report you wish to run:
|
||||
[[Report1]]
|
||||
skin = Standard
|
||||
|
||||
[[FTP]]
|
||||
skin = Ftp
|
||||
[Engines]
|
||||
|
||||
# This section configures the internal weewx engines. It is for advanced customization.
|
||||
|
||||
[[WxEngine]]
|
||||
# The list of services the main weewx engine should run:
|
||||
service_list = weewx.wxengine.StdWunderground, weewx.wxengine.StdCatchUp, weewx.wxengine.StdTimeSynch, weewx.wxengine.StdPrint, weewx.wxengine.StdProcess
|
||||
|
||||
@@ -12,9 +12,9 @@
|
||||
# #
|
||||
############################################################################################
|
||||
#
|
||||
# $Revision: 164 $
|
||||
# $Author: tkeffer $
|
||||
# $Date: 2010-03-16 16:16:04 -0700 (Tue, 16 Mar 2010) $
|
||||
# $Revision$
|
||||
# $Author$
|
||||
# $Date$
|
||||
#
|
||||
############################################################################################
|
||||
|
||||
|
||||
@@ -73,7 +73,7 @@ generator_list = weewx.reportengine.ByMonth, weewx.reportengine.ByYear, weewx.re
|
||||
# This is things like NOAA summaries by month.
|
||||
#
|
||||
[[NOAA_month]]
|
||||
template = NOAA/NOAA_month.txt.tmpl
|
||||
template = NOAA/NOAA-YYYY-MM.txt.tmpl
|
||||
destination_dir = NOAA
|
||||
|
||||
############################################################################################
|
||||
@@ -85,7 +85,7 @@ generator_list = weewx.reportengine.ByMonth, weewx.reportengine.ByYear, weewx.re
|
||||
# This is things like NOAA summaries by year.
|
||||
#
|
||||
[[NOAA_year]]
|
||||
template = NOAA_year.txt.tmpl
|
||||
template = NOAA/NOAA-YYYY.txt.tmpl
|
||||
destination_dir = NOAA
|
||||
|
||||
############################################################################################
|
||||
|
||||
@@ -14,7 +14,7 @@ import time
|
||||
import math
|
||||
import ImageFont
|
||||
import configobj
|
||||
|
||||
from htmlentitydefs import codepoint2name
|
||||
|
||||
def min_no_None(seq):
|
||||
"""Searches sequence of tuples, returning tuple where the first member was a minimum.
|
||||
@@ -536,6 +536,21 @@ def latlon_string(ll, hemi):
|
||||
min = frac * 60.0
|
||||
return ("%d" % (deg,), "%0.2f" % (min,), hemi[0] if ll >= 0 else hemi[1])
|
||||
|
||||
def htmlescape(instring):
|
||||
"""Escape all entities and non-7bit characters."""
|
||||
|
||||
outlist = []
|
||||
for c in instring:
|
||||
n = ord(c)
|
||||
if n < 128:
|
||||
outlist.append(c)
|
||||
else:
|
||||
if n in codepoint2name:
|
||||
outlist.append("&%s;" % codepoint2name[n])
|
||||
else:
|
||||
outlist.append("&#%d;" % n)
|
||||
return ''.join(outlist)
|
||||
|
||||
def _get_object(module_class, *args, **kwargs):
|
||||
"""Given a path to a class, instantiates an instance of the class with the given args and returns it."""
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ version = 1.6.0
|
||||
#
|
||||
|
||||
# Root directory of the weewx file hierarchy for this station:
|
||||
WEEWX_ROOT = /home/tkeffer/workspace/weewx
|
||||
WEEWX_ROOT = /home/weewx
|
||||
|
||||
location = "Hood River, Oregon"
|
||||
|
||||
@@ -301,8 +301,8 @@ version = 1.6.0
|
||||
[[Report1]]
|
||||
skin = Standard
|
||||
|
||||
[[FTP]]
|
||||
skin = Ftp
|
||||
#[[FTP]]
|
||||
# skin = Ftp
|
||||
|
||||
############################################################################################
|
||||
|
||||
|
||||
@@ -30,14 +30,10 @@ class GenFiles(object):
|
||||
"""Base class for generator classes that generate files"""
|
||||
|
||||
def __init__(self, report_dict):
|
||||
|
||||
self.report_dict = report_dict
|
||||
self.initStation(report_dict)
|
||||
self.initStats(report_dict)
|
||||
self.initUnits(report_dict)
|
||||
self.moonphases = report_dict['Almanac'].get('moon_phases')
|
||||
# self.initNoaa(report_dict)
|
||||
# self.initHtml(report_dict)
|
||||
|
||||
def initStation(self, report_dict):
|
||||
# station holds info such as 'altitude', 'latitude', etc. It seldom changes
|
||||
@@ -54,192 +50,149 @@ class GenFiles(object):
|
||||
def initUnits(self, report_dict):
|
||||
self.unitTypeDict = weewx.units.getUnitTypeDict(report_dict)
|
||||
|
||||
def _prepGen(self, subreport_dict):
|
||||
|
||||
accum_dict = weeutil.weeutil.accumulateLeaves(subreport_dict)
|
||||
|
||||
template = os.path.join(self.report_dict['Station']['WEEWX_ROOT'],
|
||||
self.report_dict['Reports']['SKIN_ROOT'],
|
||||
accum_dict['skin'],
|
||||
accum_dict['template'])
|
||||
destination_dir = os.path.join(self.report_dict['Station']['WEEWX_ROOT'],
|
||||
self.report_dict['Reports']['HTML_ROOT'],
|
||||
accum_dict['destination_dir'])
|
||||
try:
|
||||
# Create the directory that is to receive the generated files. If
|
||||
# it already exists an exception will be thrown, so be prepared to
|
||||
# catch it.
|
||||
os.makedirs(destination_dir)
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
return (template, destination_dir)
|
||||
|
||||
class GenByMonth(GenFiles):
|
||||
"""Class for generating reports that run 'by month.'"""
|
||||
|
||||
def run(self):
|
||||
|
||||
def generate(self, start_ts, stop_ts):
|
||||
|
||||
for subreport in self.report_dict['ByMonth'].sections:
|
||||
print "starting GenByMonth subreport ", subreport
|
||||
|
||||
accum_dict = weeutil.weeutil.accumulateLeaves(self.report_dict['ByMonth'][subreport])
|
||||
|
||||
(template, destination_dir) = self._prepGen(self.report_dict['ByMonth'][subreport])
|
||||
|
||||
template = os.path.join(self.report_dict['Station']['WEEWX_ROOT'],
|
||||
self.report_dict['Reports']['SKIN_ROOT'],
|
||||
accum_dict['skin'],
|
||||
accum_dict['template'])
|
||||
destination_dir = os.path.join(self.report_dict['Station']['WEEWX_ROOT'],
|
||||
self.report_dict['Reports']['HTML_ROOT'],
|
||||
accum_dict['destination_dir'])
|
||||
print "Using template ", template
|
||||
print "Putting results in ", destination_dir
|
||||
|
||||
ngen = 0
|
||||
t1 = time.time()
|
||||
|
||||
# Loop through all months, looking for reports that need to be
|
||||
# generated.
|
||||
for monthSpan in weeutil.weeutil.genMonthSpans(start_ts, stop_ts):
|
||||
# Calculate the file name for this month
|
||||
_month_start_tt = time.localtime(monthSpan.start)
|
||||
_filename = os.path.basename(template).replace('YYYY', "%4d" % _month_start_tt[0]).replace('MM', "%02d" % _month_start_tt[1]).replace('.tmpl','')
|
||||
_fullpath = os.path.join(destination_dir, _filename)
|
||||
print "ByMonth output will go to path ", _fullpath
|
||||
|
||||
# If the file doesn't exist, or it is the last month, then
|
||||
# we must generate it
|
||||
if not os.path.exists(_fullpath) or monthSpan.includesArchiveTime(stop_ts):
|
||||
|
||||
searchList = self.getSearchList(monthSpan)
|
||||
# Run everything through the template engine
|
||||
text = Cheetah.Template.Template(file = template, searchList = searchList)
|
||||
# Open up the file that is to be created:
|
||||
file = open(_fullpath, mode='w')
|
||||
# Write it out
|
||||
print >> file, text
|
||||
# Close it
|
||||
file.close()
|
||||
ngen += 1
|
||||
|
||||
t2 = time.time()
|
||||
elapsed_time = t2 - t1
|
||||
syslog.syslog(syslog.LOG_INFO, """genfiles: generated %d "ByMonth" files in %.2f seconds""" % (ngen, elapsed_time))
|
||||
|
||||
def getSearchList(self, monthSpan):
|
||||
"""Return the searchList for the Cheetah Template engine for month NOAA reports.
|
||||
|
||||
Can easily be overridden to add things to the search list.
|
||||
"""
|
||||
month_start_tt = time.localtime(monthSpan.start)
|
||||
# Form a suitable name for the month:
|
||||
(_yr, _mo) = month_start_tt[0:2]
|
||||
monthName = time.strftime("%b", month_start_tt)
|
||||
|
||||
# Get the stats for this month from the database:
|
||||
monthStats = weewx.stats.TimespanStats(self.statsdb, monthSpan, self.unitTypeDict)
|
||||
|
||||
searchList = [{'station' : self.station,
|
||||
'year_name' : _yr,
|
||||
'month_name' : monthName,
|
||||
'month' : monthStats}]
|
||||
return searchList
|
||||
|
||||
class GenByYear(GenFiles):
|
||||
"""Class for generating reports that run 'by year.'"""
|
||||
|
||||
def generate(self, start_ts, stop_ts):
|
||||
for subreport in self.report_dict['ByYear'].sections:
|
||||
print "starting GenByYear subreport ", subreport
|
||||
|
||||
(template, destination_dir) = self._prepGen(self.report_dict['ByYear'][subreport])
|
||||
|
||||
ngen = 0
|
||||
t1 = time.time()
|
||||
|
||||
# Loop through all months, looking for reports that need to be
|
||||
# generated.
|
||||
for yearSpan in weeutil.weeutil.genYearSpans(start_ts, stop_ts):
|
||||
# Calculate the file name for this month
|
||||
_month_start_tt = time.localtime(yearSpan.start)
|
||||
_filename = os.path.basename(template).replace('YYYY', "%4d" % _month_start_tt[0]).replace('.tmpl','')
|
||||
_fullpath = os.path.join(destination_dir, _filename)
|
||||
print "ByYear output will go to path ", _fullpath
|
||||
|
||||
# If the file doesn't exist, or it is the last month, then
|
||||
# we must generate it
|
||||
if not os.path.exists(_fullpath) or yearSpan.includesArchiveTime(stop_ts):
|
||||
|
||||
searchList = self.getSearchList(yearSpan)
|
||||
# Run everything through the template engine
|
||||
text = Cheetah.Template.Template(file = template, searchList = searchList)
|
||||
# Open up the file that is to be created:
|
||||
file = open(_fullpath, mode='w')
|
||||
# Write it out
|
||||
print >> file, text
|
||||
# Close it
|
||||
file.close()
|
||||
ngen += 1
|
||||
|
||||
t2 = time.time()
|
||||
elapsed_time = t2 - t1
|
||||
syslog.syslog(syslog.LOG_INFO, """genfiles: generated %d "ByYear" files in %.2f seconds""" % (ngen, elapsed_time))
|
||||
|
||||
def getSearchList(self, yearSpan):
|
||||
"""Return the searchList for the Cheetah Template engine for By Year reports.
|
||||
|
||||
Can easily be overridden to add things to the search list.
|
||||
"""
|
||||
|
||||
_yr = time.localtime(yearSpan.start)[0]
|
||||
|
||||
yearStats = weewx.stats.TimespanStats(self.statsdb, yearSpan, self.unitTypeDict)
|
||||
|
||||
searchList = [{'station' : self.station,
|
||||
'year_name' : _yr,
|
||||
'year' : yearStats}]
|
||||
|
||||
return searchList
|
||||
|
||||
class GenToDate(GenFiles):
|
||||
"""Class for generating "to date" reports, such as daily, weekly, monthly,
|
||||
and yearly summaries."""
|
||||
|
||||
|
||||
|
||||
def initNoaa(self, report_dict):
|
||||
# Get the directory holding the NOAA templates
|
||||
self.noaa_template_dir = os.path.join(report_dict['Station']['WEEWX_ROOT'],
|
||||
report_dict['NOAA'].get('template_root', 'templates'))
|
||||
|
||||
# Get the directory that will hold the generated NOAA reports:
|
||||
self.noaa_dir = os.path.join(report_dict['Station']['WEEWX_ROOT'],
|
||||
report_dict['NOAA'].get('noaa_dir', 'public_html/NOAA'))
|
||||
|
||||
try:
|
||||
# Create the directory that is to receive the generated files. If
|
||||
# it already exists an exception will be thrown, so be prepared to
|
||||
# catch it.
|
||||
os.makedirs(self.noaa_dir)
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
|
||||
def initHtml(self, report_dict):
|
||||
|
||||
# Get the directory holding the templates
|
||||
self.html_template_dir = os.path.join(report_dict['Station']['WEEWX_ROOT'],
|
||||
report_dict['HTML'].get('template_root', 'templates'))
|
||||
# Get the directories that will hold the generated HTML files:
|
||||
self.html_dir = os.path.join(report_dict['Station']['WEEWX_ROOT'],
|
||||
report_dict['HTML'].get('html_root', 'public_html'))
|
||||
|
||||
# Get an appropriate formatter:
|
||||
self.formatter = weewx.formatter.Formatter(weewx.units.getStringFormatDict(report_dict),
|
||||
weewx.units.getHTMLLabelDict(report_dict),
|
||||
report_dict['HTML']['Time'])
|
||||
|
||||
try:
|
||||
# Create the directory that is to receive the generated files. If
|
||||
# it already exists an exception will be thrown, so be prepared to
|
||||
# catch it.
|
||||
os.makedirs(self.html_dir)
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
self.template_list = ('index', 'week', 'month', 'year')
|
||||
|
||||
def initAlmanac(self, celestial_ts):
|
||||
""" Initialize an instance of weeutil.Almanac.Almanac for the station's
|
||||
lat and lon, and for a specific time.
|
||||
|
||||
celestial_ts: The timestamp of the time for which the Almanac is to
|
||||
be initialized.
|
||||
def generate(self, currentRec, stop_ts):
|
||||
"""
|
||||
# almanac holds celestial information (sunrise, phase of moon). Its celestial
|
||||
# data slowly changes.
|
||||
self.almanac = weeutil.Almanac.Almanac(celestial_ts,
|
||||
self.station.latitude_f,
|
||||
self.station.longitude_f,
|
||||
self.moonphases)
|
||||
|
||||
def generateNoaa(self, start_ts, stop_ts):
|
||||
""" Generate NOAA yearly and monthly reports.
|
||||
|
||||
start_ts: The timestamp of the earliest data to be included.
|
||||
|
||||
stop_ts: The report will be current as of this timestamp."""
|
||||
|
||||
self.generateNoaaYears(start_ts, stop_ts)
|
||||
self.generateNoaaMonths(start_ts, stop_ts)
|
||||
|
||||
def generateNoaaYears(self, start_ts, stop_ts):
|
||||
""" Generate NOAA yearly reports.
|
||||
|
||||
start_ts: A timestamp within the year of the first report to be
|
||||
generated.
|
||||
|
||||
stop_ts: A timestamp within the year of the last report to be
|
||||
generated."""
|
||||
|
||||
|
||||
ngen = 0
|
||||
t1 = time.time()
|
||||
|
||||
# This is the template to be used to generate the yearly reports:
|
||||
noaa_year_template_file = os.path.join(self.noaa_template_dir, "NOAA_year.tmpl")
|
||||
|
||||
# Loop through all months, looking for reports that need to be
|
||||
# generated.
|
||||
for yearSpan in weeutil.weeutil.genYearSpans(start_ts, stop_ts):
|
||||
|
||||
_yr = time.localtime(yearSpan.start)[0]
|
||||
_filename = "NOAA-%d.txt" % _yr
|
||||
_fullpath = os.path.join(self.noaa_dir, _filename)
|
||||
|
||||
# If the file doesn't exist, or it is the last year, then
|
||||
# we must generate it
|
||||
if not os.path.exists(_fullpath) or yearSpan.includesArchiveTime(stop_ts):
|
||||
|
||||
searchList = self.get_Year_SearchList(yearSpan, stop_ts)
|
||||
|
||||
# Run everything through the template engine
|
||||
text = Cheetah.Template.Template(file = noaa_year_template_file, searchList = searchList)
|
||||
# Open up the file that is to be created:
|
||||
file = open(_fullpath, mode='w')
|
||||
# Write it out
|
||||
print >> file, text
|
||||
# Close it
|
||||
file.close()
|
||||
ngen += 1
|
||||
|
||||
t2 = time.time()
|
||||
elapsed_time = t2 - t1
|
||||
syslog.syslog(syslog.LOG_INFO, "gennoaa: generated %d NOAA year files in %.2f seconds" % (ngen, elapsed_time))
|
||||
|
||||
def generateNoaaMonths(self, start_ts, stop_ts):
|
||||
""" Generate NOAA monthly reports.
|
||||
|
||||
start_ts: A timestamp within the month of the first report to be
|
||||
generated.
|
||||
|
||||
stop_ts: A timestamp within the month of the last report to be
|
||||
generated."""
|
||||
|
||||
ngen = 0
|
||||
t1 = time.time()
|
||||
|
||||
# This is the template to be used to generate the monthly reports:
|
||||
noaa_month_template_file = os.path.join(self.noaa_template_dir, "NOAA_month.tmpl")
|
||||
|
||||
# Loop through all months, looking for reports that need to be
|
||||
# generated.
|
||||
for monthSpan in weeutil.weeutil.genMonthSpans(start_ts, stop_ts):
|
||||
# Calculate the file name for this month
|
||||
_month_start_tt = time.localtime(monthSpan.start)
|
||||
_filename = "NOAA-%d-%02d.txt" % _month_start_tt[0:2]
|
||||
_fullpath = os.path.join(self.noaa_dir, _filename)
|
||||
|
||||
# If the file doesn't exist, or it is the last month, then
|
||||
# we must generate it
|
||||
if not os.path.exists(_fullpath) or monthSpan.includesArchiveTime(stop_ts):
|
||||
|
||||
searchList = self.get_Month_SearchList(monthSpan, stop_ts)
|
||||
# Run everything through the template engine
|
||||
text = Cheetah.Template.Template(file = noaa_month_template_file, searchList = searchList)
|
||||
# Open up the file that is to be created:
|
||||
file = open(_fullpath, mode='w')
|
||||
# Write it out
|
||||
print >> file, text
|
||||
# Close it
|
||||
file.close()
|
||||
ngen += 1
|
||||
|
||||
t2 = time.time()
|
||||
elapsed_time = t2 - t1
|
||||
syslog.syslog(syslog.LOG_INFO, "gennoaa: generated %d NOAA monthly files in %.2f seconds" % (ngen, elapsed_time))
|
||||
|
||||
def generateHtml(self, currentRec, stop_ts):
|
||||
"""Generate HTML pages.
|
||||
|
||||
currentRec: A dictionary containing current observation. Key is a type
|
||||
('outTemp', 'barometer', etc.), value the value of the
|
||||
variable. Usually, this is an archive record.
|
||||
@@ -247,32 +200,57 @@ class GenToDate(GenFiles):
|
||||
stop_ts: A timestamp. The HTML files generated will be current as of
|
||||
this time."""
|
||||
|
||||
self.initAlmanac(stop_ts)
|
||||
|
||||
searchList = self.get_Html_SearchList(currentRec, stop_ts)
|
||||
|
||||
ngen = 0
|
||||
t1 = time.time()
|
||||
|
||||
# Generate for each HTML template:
|
||||
for template in self.template_list:
|
||||
|
||||
# Here's the full path to the template file:
|
||||
template_file = os.path.join(self.html_template_dir, template + ".tmpl")
|
||||
# Get an appropriate formatter:
|
||||
self.formatter = weewx.formatter.Formatter(weewx.units.getStringFormatDict(self.report_dict),
|
||||
weewx.units.getHTMLLabelDict(self.report_dict),
|
||||
self.report_dict['Labels']['Time'])
|
||||
|
||||
self.initAlmanac(stop_ts)
|
||||
|
||||
searchList = self.getSearchList(currentRec, stop_ts)
|
||||
|
||||
for subreport in self.report_dict['ToDate'].sections:
|
||||
print "starting GenToDate subreport ", subreport
|
||||
|
||||
(template, destination_dir) = self._prepGen(self.report_dict['ToDate'][subreport])
|
||||
|
||||
print "GenToDate template is ", template, "; destination dir is ", destination_dir
|
||||
|
||||
#===================================================================
|
||||
# Here's where the heavy lifting occurs. Use Cheetah to actually
|
||||
# generate the files. It will use introspection on the searchList to
|
||||
# populate the parameters in the template file.
|
||||
# ===================================================================
|
||||
html = Cheetah.Template.Template(file = template_file, searchList = searchList)
|
||||
html = Cheetah.Template.Template(file = template, searchList = searchList)
|
||||
|
||||
file = open(os.path.join(self.html_dir, template + ".html"), mode='w')
|
||||
print >> file, html
|
||||
ngen += 1
|
||||
|
||||
|
||||
elapsed_time = time.time() - t1
|
||||
syslog.syslog(syslog.LOG_INFO, "genhtml: generated %d HTML pages in %.2f seconds" % (ngen, elapsed_time))
|
||||
syslog.syslog(syslog.LOG_INFO, "genhtml: generated %d 'toDate' pages in %.2f seconds" % (ngen, elapsed_time))
|
||||
|
||||
def initAlmanac(self, celestial_ts):
|
||||
""" Initialize an instance of weeutil.Almanac.Almanac for the station's
|
||||
lat and lon, and for a specific time.
|
||||
|
||||
celestial_ts: The timestamp of the time for which the Almanac is to
|
||||
be initialized.
|
||||
"""
|
||||
self.moonphases = self.report_dict['Almanac'].get('moon_phases')
|
||||
|
||||
# almanac holds celestial information (sunrise, phase of moon). Its celestial
|
||||
# data slowly changes.
|
||||
self.almanac = weeutil.Almanac.Almanac(celestial_ts,
|
||||
self.station.latitude_f,
|
||||
self.station.longitude_f,
|
||||
self.moonphases)
|
||||
|
||||
|
||||
|
||||
|
||||
def get_existing_NOAA_reports(self):
|
||||
@@ -295,42 +273,8 @@ class GenToDate(GenFiles):
|
||||
year_list.append(_file[5:9])
|
||||
return (month_list, year_list)
|
||||
|
||||
def get_Year_SearchList(self, yearSpan, stop_ts):
|
||||
"""Return the searchList for the Cheetah Template engine for year NOAA reports.
|
||||
|
||||
Can easily be overridden to add things to the search list.
|
||||
"""
|
||||
|
||||
_yr = time.localtime(yearSpan.start)[0]
|
||||
|
||||
yearStats = weewx.stats.TimespanStats(self.statsdb, yearSpan, self.unitTypeDict)
|
||||
|
||||
searchList = [{'station' : self.station,
|
||||
'year_name' : _yr,
|
||||
'year' : yearStats}]
|
||||
|
||||
return searchList
|
||||
|
||||
def get_Month_SearchList(self, monthSpan, stop_ts):
|
||||
"""Return the searchList for the Cheetah Template engine for month NOAA reports.
|
||||
|
||||
Can easily be overridden to add things to the search list.
|
||||
"""
|
||||
month_start_tt = time.localtime(monthSpan.start)
|
||||
# Form a suitable name for the month:
|
||||
(_yr, _mo) = month_start_tt[0:2]
|
||||
monthName = time.strftime("%b", month_start_tt)
|
||||
|
||||
# Get the stats for this month from the database:
|
||||
monthStats = weewx.stats.TimespanStats(self.statsdb, monthSpan, self.unitTypeDict)
|
||||
|
||||
searchList = [{'station' : self.station,
|
||||
'year_name' : _yr,
|
||||
'month_name' : monthName,
|
||||
'month' : monthStats}]
|
||||
return searchList
|
||||
|
||||
def get_Html_SearchList(self, currentRec, stop_ts):
|
||||
def getSearchList(self, currentRec, stop_ts):
|
||||
"""Return the searchList for the Cheetah Template engine for HTML generation.
|
||||
|
||||
Can easily be overridden to add things to the search list.
|
||||
|
||||
@@ -86,7 +86,7 @@ class StdReportEngine(threading.Thread):
|
||||
for generator in generator_list:
|
||||
try:
|
||||
# Instantiate an instance of the class
|
||||
obj = weeutil.weeutil._get_object(generator, report_dict)
|
||||
obj = weeutil.weeutil._get_object(generator, report_dict, self.gen_ts)
|
||||
# Call its start() method
|
||||
obj.start()
|
||||
|
||||
@@ -100,8 +100,9 @@ class StdReportEngine(threading.Thread):
|
||||
|
||||
class ReportGenerator(object):
|
||||
"""Base class for all reports."""
|
||||
def __init__(self, report_dict):
|
||||
def __init__(self, report_dict, gen_ts):
|
||||
self.report_dict = report_dict
|
||||
self.gen_ts = gen_ts
|
||||
|
||||
def start(self):
|
||||
self.run()
|
||||
@@ -114,15 +115,46 @@ class ByMonth(ReportGenerator):
|
||||
|
||||
def run(self):
|
||||
print "Running ByMonth reports..."
|
||||
# Open up the main database archive
|
||||
archiveFilename = os.path.join(self.report_dict['Station']['WEEWX_ROOT'],
|
||||
self.report_dict['Archive']['archive_file'])
|
||||
archive = weewx.archive.Archive(archiveFilename)
|
||||
|
||||
stop_ts = archive.lastGoodStamp() if self.gen_ts is None else self.gen_ts
|
||||
start_ts = archive.firstGoodStamp()
|
||||
byMonth = weewx.genfiles.GenByMonth(self.report_dict)
|
||||
byMonth.run()
|
||||
byMonth.generate(start_ts, stop_ts)
|
||||
|
||||
class ByYear(ReportGenerator):
|
||||
"""Creates yearly reports, such as NOAA reports."""
|
||||
|
||||
def run(self):
|
||||
print "Running ByYear reports..."
|
||||
# Open up the main database archive
|
||||
archiveFilename = os.path.join(self.report_dict['Station']['WEEWX_ROOT'],
|
||||
self.report_dict['Archive']['archive_file'])
|
||||
archive = weewx.archive.Archive(archiveFilename)
|
||||
|
||||
stop_ts = archive.lastGoodStamp() if self.gen_ts is None else self.gen_ts
|
||||
start_ts = archive.firstGoodStamp()
|
||||
byYear = weewx.genfiles.GenByYear(self.report_dict)
|
||||
byYear.generate(start_ts, stop_ts)
|
||||
|
||||
class ToDate(ReportGenerator):
|
||||
"""Creates snapshot statistical reports."""
|
||||
|
||||
def run(self):
|
||||
print "Running ToDate reports..."
|
||||
# Open up the main database archive
|
||||
archiveFilename = os.path.join(self.report_dict['Station']['WEEWX_ROOT'],
|
||||
self.report_dict['Archive']['archive_file'])
|
||||
archive = weewx.archive.Archive(archiveFilename)
|
||||
|
||||
stop_ts = archive.lastGoodStamp() if self.gen_ts is None else self.gen_ts
|
||||
currentRec = archive.getRecord(stop_ts, weewx.units.getUnitTypeDict(self.report_dict))
|
||||
toDate = weewx.genfiles.GenToDate(self.report_dict)
|
||||
toDate.generate(currentRec, stop_ts)
|
||||
|
||||
class Images(ReportGenerator):
|
||||
"""Creates plots"""
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
"""
|
||||
|
||||
import weewx
|
||||
import weeutil.weeutil
|
||||
|
||||
# This data structure maps types to a "unit class"
|
||||
unitGroups = {"barometer" : "group_pressure",
|
||||
@@ -180,7 +181,7 @@ def getLabel(config_dict, type):
|
||||
|
||||
def getHTMLLabel(config_dict, type):
|
||||
"""Extract an HTML unit label (e.g., "°F") for a specific type"""
|
||||
return config_dict['HTML']['UnitLabels'][getUnitType(config_dict, type)]
|
||||
return weeutil.weeutil.htmlescape(getLabel(config_dict, type))
|
||||
|
||||
def getStringFormatDict(config_dict):
|
||||
"""Return a dictionary of suitable string formats for all types."""
|
||||
|
||||
Reference in New Issue
Block a user