mirror of
https://github.com/weewx/weewx.git
synced 2026-04-18 16:46:56 -04:00
4918 lines
195 KiB
HTML
4918 lines
195 KiB
HTML
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
|
<!-- $Id$ -->
|
|
<head>
|
|
<meta content="en-us" http-equiv="Content-Language" />
|
|
<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
|
|
<title>weewx: Customization Guide</title>
|
|
<link href="weewx_docs.css" rel="stylesheet" />
|
|
<script src="jquery.min.js" type="text/javascript"></script>
|
|
<script src="jquery.toc-1.1.4.min.js" type="text/javascript"></script>
|
|
<style>
|
|
table#stattypes td {
|
|
width: 60px;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
|
|
<a href='http://weewx.com'>
|
|
<img src='logo-weewx.png' class='logo' align='right' />
|
|
</a>
|
|
<h1 class="title">Customizing weewx<br />
|
|
<span class="version"> Version:
|
|
2.5.0
|
|
</span>
|
|
</h1>
|
|
|
|
<h1>Table of Contents</h1>
|
|
<div id="toc"></div>
|
|
<div id="technical_content">
|
|
<h1 id="introduction">Introduction</h1>
|
|
<p>
|
|
This document covers the customization of <span class="code">weewx</span>.
|
|
It assumes that you have read and are reasonably familiar with
|
|
the <a href="usersguide.htm"> Users Guide</a>.
|
|
</p>
|
|
<p>
|
|
It starts with an overview of the architecture of weewx. If you
|
|
are only interested in customizing the generated reports you can
|
|
probably skip the overview and proceed directly to the section <em>
|
|
<a href="#standard_skin"> The Standard skin configuration
|
|
file</a>
|
|
</em>. With this approach you can easily add new plot images, change
|
|
the titles of images, change the units used in the reports, and
|
|
so on.
|
|
</p>
|
|
<p>However, if your goal is a specialized application, such as
|
|
adding alarms, RSS feeds, etc., then it would be worth your
|
|
while to read about the internal architecture and how to
|
|
customize it.</p>
|
|
<p>Most of the guide will cover any weather hardware, but the
|
|
exact data types are specific to the Davis Vantage series.
|
|
Unless you are using an unusual type you are unlikely to run
|
|
into trouble.</p>
|
|
<p class="warning">
|
|
<strong>Warning!</strong><br /> <span class="code">weewx</span>
|
|
is still an experimental system and, as such, its internal
|
|
design is subject to change. Be prepared to do updates to any
|
|
code or customization you do!
|
|
</p>
|
|
<h2>Overview of the weewx architecture</h2>
|
|
<p>
|
|
At a high-level, <span class="code">weewx</span> consists of an
|
|
engine class called <span class="code">StdEngine</span>. It is
|
|
responsible for loading "<em>services</em>", then arranging for
|
|
them to be called when key events occur, such as the arrival of
|
|
LOOP data. The default install of <span class="code">
|
|
weewx</span> includes the following services:
|
|
</p>
|
|
<table class="indent" style="width: 80%"
|
|
summary="Overview of the weewx architecture">
|
|
<tbody>
|
|
<tr>
|
|
<td><strong>Service</strong></td>
|
|
<td><strong>Function</strong></td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">weewx.wxengine.StdConvert</td>
|
|
<td>Converts the units of the input to a target unit
|
|
system (such as US or Metric).</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">weewx.wxengine.StdCalibrate</td>
|
|
<td>Adjust new LOOP and archive packets using
|
|
calibration expressions.</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">weewx.wxengine.StdQC</td>
|
|
<td>Check quality of incoming data, making sure values
|
|
fall within a specified range.</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">weewx.wxengine.StdArchive</td>
|
|
<td>Archive any new data to the SQL databases.</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">weewx.wxengine.StdTimeSynch</td>
|
|
<td>Arrange to have the clock on the station
|
|
synchronized at regular intervals.</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">weewx.wxengine.StdPrint</td>
|
|
<td>Print out new LOOP and archive packets on the
|
|
console.</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">weewx.wxengine.StdRESTful</td>
|
|
<td>Start a thread to manage <a
|
|
href="http://en.wikipedia.org/wiki/Representational_State_Transfer">
|
|
RESTful</a> (simple stateless client-server protocols)
|
|
connections; such as those used by the Weather Underground
|
|
or CWOP.
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">weewx.wxengine.StdReport</td>
|
|
<td>Launch a new thread to do report processing after a
|
|
new archive record arrives. Reports do things such as
|
|
generate HTML files, generate images, or FTP/rsync files
|
|
to a web server. New reports can be added easily by the
|
|
user.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p>
|
|
It is easy to extend old services or to add new ones. The source
|
|
distribution includes an example new service called "<span
|
|
class="code">MyAlarm</span>," which sends an email when an
|
|
arbitrary expression evaluates <span class="code"> True</span>.
|
|
These advanced topics are covered later in the section <em><a
|
|
href="#service_engine"> Customizing the weewx service
|
|
engine</a></em>.
|
|
</p>
|
|
<h2 id="Standard_reporting_service_StdReport">
|
|
The standard reporting service, <span class="code">StdReport</span>
|
|
</h2>
|
|
<p>
|
|
For the moment, let us focus on the last service, <span
|
|
class="code"> weewx.wxengine.StdReport</span>, the standard
|
|
service for creating reports. This will be what most users will
|
|
want to customize even if it means changing just a few options.
|
|
</p>
|
|
<h3>Reports</h3>
|
|
<p>
|
|
The Standard Report Service runs zero or more <em>Reports.</em>
|
|
The specific reports which get run are set in the configuration
|
|
file <span class="code">weewx.conf</span>, in section <span
|
|
class="code"> [StdReport]</span>.
|
|
</p>
|
|
<p>
|
|
The default distribution of <span class="code">weewx</span>
|
|
includes three reports:
|
|
</p>
|
|
<table class="indent" style="width: 80%"
|
|
summary="Standard reports included in weewx">
|
|
<tbody>
|
|
<tr>
|
|
<td><strong>Report</strong></td>
|
|
<td><strong>Default functionality</strong></td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">StandardReport</td>
|
|
<td>Generates day, week, month and year "to-date"
|
|
summaries in HTML, as well as the plot images to go along
|
|
with them. Also generates NOAA monthly and yearly
|
|
summaries.</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">FTP</td>
|
|
<td>Arranges to upload everything in the <span
|
|
class="symcode"> $HTML_ROOT</span> directory up to a
|
|
remote webserver.
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">RSYNC</td>
|
|
<td>Like FTP, but uses rsync for transferring files to
|
|
a remote webserver.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p>Note that the FTP and RSYNC "reports" are a funny kind of
|
|
report in that it they do not actually generate anything.
|
|
Instead, they use the reporting service engine to arrange for
|
|
things to be transferred to a remote server.</p>
|
|
<h3>Skins</h3>
|
|
<p>
|
|
Each report has a <em>Skin</em> associated with it. For most
|
|
reports, the relationship with the skin is an obvious one: it
|
|
contains the templates, any auxiliary files such as background
|
|
GIFs or CSS style sheets, and a <em>skin configuration file</em>,
|
|
<span class="code"> skin.conf</span>. If you will, the skin
|
|
controls the <em>look and feel </em> of the report. Note that
|
|
more than one report can use the same skin. For example, you
|
|
might want to run a report that uses US Customary units, then
|
|
run another report against the same skin, but using metric units
|
|
and put the results in a different place. All this is possible
|
|
by either overriding configuration options in the <span
|
|
class="code">weewx</span> configuration file <span
|
|
class="code">weewx.conf</span> or the skin configuration file
|
|
<span class="code">skin.conf</span>.
|
|
</p>
|
|
<p>Like all reports, the FTP and RSYNC "Reports" also use a
|
|
skin, and include a skin configuration file, although they are
|
|
quite minimal.</p>
|
|
<p>
|
|
Skins live in their own directory located in <span
|
|
class="symcode"> $SKIN_ROOT</span>.
|
|
</p>
|
|
<h3>Generators</h3>
|
|
<p>
|
|
To create their output, skins rely on one or more <em>Generators,</em>
|
|
code that actually create useful things such as HTML files or
|
|
plot images. Generators can also copy files around or FTP/rsync
|
|
them to remote locations. The default install of <span
|
|
class="code">weewx</span> includes the following generators:
|
|
</p>
|
|
<table class="indent" style="width: 80%"
|
|
summary="Generators included in weewx">
|
|
<tbody>
|
|
<tr>
|
|
<td><strong>Generator</strong></td>
|
|
<td><strong>Function</strong></td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">weewx.cheetahgenerator.CheetahGenerator</td>
|
|
<td>Generates files from templates, using the Cheetah
|
|
template engine. Used to generate HTML and text files.</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">weewx.imagegenerator.ImageGenerator</td>
|
|
<td>Generates graph plots.</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">weewx.reportengine.FtpGenerator</td>
|
|
<td>Uploads data to a remote server using FTP.</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">weewx.reportengine.RsyncGenerator</td>
|
|
<td>Uploads data to a remote server using rsync.</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">weewx.reportengine.CopyGenerator</td>
|
|
<td>Copies files locally.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p>
|
|
Note that the three generators <span class="code">FtpGenerator</span>,
|
|
<span class="code">RsyncGenerator</span>, and <span class="code">
|
|
CopyGenerator</span> do not actually generate anything having to do
|
|
with the presentation layer. Instead, they just move files
|
|
around.
|
|
</p>
|
|
<p>
|
|
Which generators are to be run for a given skin is specified in
|
|
the skin's configuration file <span class="code">skin.conf</span>,
|
|
in section <a href="#generators"><span class="code">
|
|
[Generators]</span></a>.
|
|
</p>
|
|
<h2>Databases</h2>
|
|
<p>
|
|
There are two databases used by <span class="code">weewx</span>,
|
|
which can be implemented either by using <a
|
|
href="http://www.sqlite.org/"> SQLITE3</a>, an open-source,
|
|
lightweight SQL database, or <a href="http://www.mysql.com/">
|
|
MySQL</a>, an open-source, full-featured database server, or some
|
|
combination of the two of them.
|
|
</p>
|
|
<ul>
|
|
<li>The <em>archive database</em>, given symbolic name '<span
|
|
class="code">archive_database</span>'. It is a big flat table,
|
|
one record for each archive interval, keyed by <span
|
|
class="code">dateTime</span>, the time at the end of the
|
|
archive interval.
|
|
</li>
|
|
<li>The <em>statistical database</em>, given symbolic name
|
|
'<span class="code">stats_database</span>'. It consists of a
|
|
separate table for each observation type (that is, one for '<span
|
|
class="code">outTemp</span>', one for '<span class="code">barometer</span>',
|
|
<em>etc.</em>), each containing one record per day, keyed by
|
|
the start time of the day.
|
|
</li>
|
|
</ul>
|
|
<p>
|
|
How these abstract databases are bound to the real database is
|
|
covered in the <a href="usersguide.htm">Weewx User's Guide</a>,
|
|
in section '<a href="usersguide.htm#StdArchive">[StdArchive]</a>'.
|
|
</p>
|
|
<p>
|
|
The important thing to remember is that the archive database
|
|
contains a record for every archive interval and, as such,
|
|
represents the <em>current conditions</em> at the time of the
|
|
observation. By contrast, the statistical database represents
|
|
the <em>aggregation of conditions over a day</em>. That is, it
|
|
contains the daily minimum, maximum, and the time of the minimum
|
|
and maximum, for each observation type. As you can imagine, the
|
|
statistical database is much smaller because it represents only
|
|
a summary of the data.
|
|
</p>
|
|
<p>
|
|
The archive database is used for both generating plot data and
|
|
in template generation (where it appears as tag <span
|
|
class="code">$current</span>). The statistical database is
|
|
used only in template generation (where it appears as tags <span
|
|
class="code">$day</span>, <span class="code">$week</span>, <span
|
|
class="code">$month</span>, <span class="code">$year</span>,
|
|
and <span class="code">$rainyear</span>, depending on the
|
|
aggregation time period).
|
|
</p>
|
|
|
|
<h2>Where to put customizations</h2>
|
|
<p>
|
|
For configuration changes, simply modify the <span class="code">weewx</span>
|
|
configuration file <span class="code">weewx.conf</span>, and
|
|
possibly modify the skin configuration file <span class="code">skin.conf</span>
|
|
as described later in this document. These files will be
|
|
preserved when you upgrade.
|
|
</p>
|
|
<p>Other customizations require new Python code or
|
|
modifications of example code. Where should you put the code? If
|
|
you simply modify the examples in place, then your changes will
|
|
be overwritten the next time you do an upgrade.</p>
|
|
<p>
|
|
A better idea is to put the code in the <span class="symcode">$BIN_ROOT</span><span
|
|
class="code">/user</span>, directory. For example, copy
|
|
example code from the <span class="code">examples</span>
|
|
directory to the <span class="code">user</span> directory, then
|
|
modify it there. If your modification does not contain much
|
|
code, consider putting it in the extensions.py file in the <span
|
|
class="code">user</span> directory. The <span class="code">user</span>
|
|
directory is preserved through upgrades, so you won't have to
|
|
redo any changes you might have made.
|
|
</p>
|
|
|
|
<h1 id="reports">Customizing reports</h1>
|
|
<p>This section discusses the two general strategies for
|
|
customizing reports: by changing options in one or more
|
|
configuration file, or by changing the template files. The
|
|
former is generally easier, but occasionally the latter is
|
|
necessary.</p>
|
|
<h2>Changing options</h2>
|
|
<p>
|
|
Changing an option means either modifying the main configuration
|
|
file <span class="code">weewx.conf</span>, or the skin
|
|
configuration file for the standard skin that comes with the
|
|
distribution (nominally, file <span class="symcode">
|
|
$SKIN_ROOT</span><span class="code">/Standard/skin.conf</span>).
|
|
</p>
|
|
<h3>Changing options in <span class="code">skin.conf</span></h3>
|
|
<p>
|
|
With this approach, the user edits the skin configuration file
|
|
for the standard skin that comes with <span class="code">weewx</span>,
|
|
located in <span class="symcode"> $SKIN_ROOT</span><span
|
|
class="code">/Standard/skin.conf</span>, using a text editor.
|
|
For example, suppose you wish to use metric units in the
|
|
presentation layer, instead of the default US Customary Units.
|
|
The section that controls units is <span class="code">[Units][[Groups]]</span>.
|
|
It looks like this:
|
|
</p>
|
|
<pre class="tty">[Units]
|
|
[[Groups]]
|
|
group_altitude = foot
|
|
group_degree_day = degree_F_day
|
|
group_direction = degree_compass
|
|
group_moisture = centibar
|
|
group_percent = percent
|
|
group_pressure = inHg
|
|
group_radiation = watt_per_meter_squared
|
|
group_rain = inch
|
|
group_rainrate = inch_per_hour
|
|
group_speed = mile_per_second
|
|
group_speed2 = mile_per_second2
|
|
group_temperature = degree_F
|
|
group_uv = uv_index
|
|
group_volt = volt</pre>
|
|
<p>To use metric units, you would edit this section to read:</p>
|
|
<pre class="tty">[Units]
|
|
[[Groups]]
|
|
<span class="highlight"> group_altitude = meter</span>
|
|
<span class="highlight"> group_degree_day = degree_C_day</span>
|
|
group_direction = degree_compass
|
|
group_moisture = centibar
|
|
group_percent = percent
|
|
<span class="highlight"> group_pressure = mbar</span>
|
|
group_radiation = watt_per_meter_squared
|
|
<span class="highlight"> group_rain = mm</span>
|
|
<span class="highlight"> group_rainrate = mm_per_hour</span>
|
|
<span class="highlight"> group_speed = meter_per_second</span>
|
|
<span class="highlight"> group_speed2 = meter_per_second2</span>
|
|
<span class="highlight"> group_temperature = degree_C</span>
|
|
group_uv = uv_index
|
|
group_volt = volt</pre>
|
|
<p>
|
|
The options that were changed have been <span class="highlight">
|
|
highlighted </span>. Details of the various unit options
|
|
are given in <em><a href="#units"> Appendix B: Units</a></em>.
|
|
</p>
|
|
<p>
|
|
Other options are available, such as changing the text label for
|
|
various observation types. For example, suppose your weather
|
|
console is actually located in a barn, not indoors, and you want
|
|
the plot for the temperature at the console to be labeled "Barn
|
|
Temperature," rather than the default "Inside Temperature." This
|
|
can be done by changing the "<span class="code">inTemp</span>"
|
|
option located in section <span class="code">
|
|
[Labels][[Generic]]</span> from the default
|
|
</p>
|
|
<pre class="tty">[Units]
|
|
[[Generic]]
|
|
inTemp = Inside Temperature
|
|
outTemp = Outside Temperature
|
|
...</pre>
|
|
<p>to:</p>
|
|
<pre class="tty">[Units]
|
|
[[Generic]]
|
|
<span class="highlight"> inTemp = Barn Temperature</span>
|
|
outTemp = Outside Temperature
|
|
...</pre>
|
|
<h3>Overriding options in <span class="code">skin.conf</span> from <span class="code">weewx.conf</span></h3>
|
|
<p>
|
|
This approach is very similar, except that instead of changing
|
|
the skin configuration file directly, you override its options
|
|
by editing the main configuration file, <span class="code">weewx.conf</span>.
|
|
The advantage of this approach is that you can use the same skin
|
|
to produce several different output, each with separate options.
|
|
</p>
|
|
<p>
|
|
Revisiting our example, suppose you want two reports, one in US
|
|
Customary, the other in Metric. The former will go in the
|
|
directory <span class="symcode"> $HTML_ROOT</span>, the latter
|
|
in a directory, <span class="symcode"> $HTML_ROOT</span><span
|
|
class="code">/metric</span>. If you just simply modify <span
|
|
class="code">skin.conf</span>, you can get one, but not both
|
|
at the same time. Alternatively, you could create a whole new
|
|
skin by copying all the files to a new skin directory then
|
|
editing the new <span class="code">skin.conf</span>. The trouble
|
|
with this approach is that you would then have <em>two</em>
|
|
skins you would have to maintain. If you change something, you
|
|
have to remember to change it in both places.
|
|
</p>
|
|
<p>
|
|
But, there's a better approach: reuse the same skin, but
|
|
override some of its options. Here is what your <span
|
|
class="code">[StdReport]</span> section in <span class="code">weewx.conf</span>
|
|
would look like:
|
|
</p>
|
|
<pre class="tty">[StdReport]
|
|
#
|
|
# This section specifies what reports, using which skins, are to be generated.
|
|
#
|
|
|
|
# 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
|
|
|
|
# This report will use US Customary Units
|
|
[[USReport]]
|
|
# It is based on the Standard skin
|
|
skin = Standard
|
|
|
|
# This report will use metric units:
|
|
[[MetricReport]]
|
|
# It is also based on the Standard skin:
|
|
skin = Standard
|
|
# However, override where the results will go and put them in a directory:
|
|
HTML_ROOT = public_html/metric
|
|
|
|
# And override the options that were not in metric units
|
|
[[[Units]]]
|
|
[[[[Groups]]]]
|
|
group_altitude = meter
|
|
group_pressure = mbar
|
|
group_rain = mm
|
|
group_rainrate = mm_per_hour
|
|
group_speed = meter_per_second
|
|
group_speed2 = meter_per_second2
|
|
group_temperature = degree_C
|
|
|
|
[[FTP]]
|
|
...
|
|
... (as before) </pre>
|
|
<p>
|
|
We have done two things different from the stock reports. First
|
|
(1), we have renamed the first report from <span class="code">StandardReport</span>
|
|
to <span class="code">USReport</span> for clarity; and (2) we
|
|
have introduced a new report <span class="code">MetricReport</span>,
|
|
just like the first, except it puts its results in a different
|
|
spot and uses different units. Both use the same skin, the <span
|
|
class="code">Standard</span> skin.
|
|
</p>
|
|
<h2 id="templates">Customizing templates</h2>
|
|
<p>
|
|
If you cannot achieve the results you need by changing a
|
|
configuration option, you may have to modify the templates that
|
|
come with <span class="code"> weewx</span>, or write your own.
|
|
</p>
|
|
<p>
|
|
Template modifications are preserved across upgrades (indeed,
|
|
everything in the <span class="code">./skins</span> directory is
|
|
preserved), so you don't have to worry about losing changes.
|
|
</p>
|
|
<p>
|
|
Template generation is done using the <a
|
|
href="http://www.cheetahtemplate.org/"> Cheetah</a> templating
|
|
engine. This is a very powerful engine, which essentially lets
|
|
you have the full semantics of Python available in your
|
|
templates. As this would make the templates incomprehensible to
|
|
anyone but a Python programmer, <span class="code">weewx</span>
|
|
adopts a very small subset of its power.
|
|
</p>
|
|
|
|
<h3>The dot code</h3>
|
|
<p>The key construct is a 'dot' code, specifying what value
|
|
you want. For example:</p>
|
|
<pre class="tty">$month.outTemp.max
|
|
$month.outTemp.maxtime
|
|
$current.outTemp</pre>
|
|
<p>would code the max outside temperature for the month, the
|
|
time it occurred, and the current outside temperature,
|
|
respectively. So, an HTML file that looks like</p>
|
|
<pre class="tty"><html>
|
|
<head>
|
|
<title>Current conditions</title>
|
|
</head>
|
|
<body>
|
|
<p>Current temperature = $current.outTemp</p>
|
|
<p>Max for the month is $month.outTemp.max, which occurred at $month.outTemp.maxtime</p>
|
|
</body>
|
|
</html></pre>
|
|
<p>
|
|
would be all you need for a very simple HTML page that would
|
|
display the text (assuming that the unit group for temperature
|
|
is <span class="code"> degree_F</span>):
|
|
</p>
|
|
<p class="example_output">
|
|
Current temperature = 51.0°F <br /> Max for the month is
|
|
68.8°F, which occurred at 07-Oct-2009 15:15
|
|
</p>
|
|
<p>
|
|
The format that was used to format the temperature (<span
|
|
class="code">51.0</span>) is specified in section <span
|
|
class="code"><a href="#Units_StringFormats">
|
|
[Units][[StringFormat]]</a></span>. The unit label <span class="code">°F</span>
|
|
is from section <span class="code"><a
|
|
href="#Units_Labels">[Units][[Labels]]</a></span>, while the time
|
|
format is from <span class="code"><a
|
|
href="#Units_TimeFormats"> [Units][[TimeFormats]]</a></span>.
|
|
</p>
|
|
<p>As we saw above, the dot codes can be very simple:</p>
|
|
<pre class="tty">## Output max outside temperature using an appropriate format and label:
|
|
$month.outTemp.max</pre>
|
|
<p>
|
|
Most of the time, the dot code will "do the right thing" and is
|
|
all you will need. However, <span class="code">weewx</span>
|
|
offers extensive customization of the generate output for
|
|
specialized applications such as XML RSS feeds, or ridgidly
|
|
formatted reports (such as the NOAA reports). This section
|
|
specifies the various options available.
|
|
</p>
|
|
<p>There are two different versions of the dot code, depending
|
|
on whether the data is "current", or an aggregation over time.
|
|
However, both versions are similar.</p>
|
|
|
|
<h3>Time period <span class="code">$current</span></h3>
|
|
<p>
|
|
Time period <span class="code">$current</span> represents a <em>current
|
|
observation</em>. An example would be the current barometric
|
|
pressure:
|
|
</p>
|
|
<pre class="tty">$current.barometer</pre>
|
|
<p>The dot code for a current observation looks like:</p>
|
|
<pre class="tty"><em>$current.obstype[.optional_unit_conversion][.optional_formatting]</em></pre>
|
|
<p>Where:</p>
|
|
<p class="indent">
|
|
<span class="code"><em>obstype</em></span> is an observation
|
|
type, such as <span class="code">barometer</span>. See <em>
|
|
<a href="#archive_types">Appendix A, Archive Types</a>
|
|
</em> for a table of observation types valid for time period <span
|
|
class="code"> current.</span>
|
|
</p>
|
|
<p class="indent">
|
|
<span class="code">optional_unit_conversion</span> is an
|
|
optional unit conversion tag. If provided, the results will be
|
|
converted into the specified units, otherwise the default units
|
|
specified in the skin configuration file (in section <span
|
|
class="code">[Units][[Groups]]</span>) will be used. See the
|
|
section <em><a href="#unit_conversion_options">Unit
|
|
Conversion Options</a></em> below.
|
|
</p>
|
|
<p class="indent">
|
|
<span class="code"><em>optional_formatting</em></span> is an
|
|
optional formatting tag that controls how the value will appear.
|
|
See the section <em><a href="#formatting_options">Formatting
|
|
Options</a></em> below.
|
|
</p>
|
|
|
|
<h3 id="Aggregation_periods_day_etc">
|
|
Aggregation periods <span class="code">$day</span>, <span
|
|
class="code">$week</span>, <span class="code">$month</span>, <span
|
|
class="code">$year</span>, <span class="code">$rainyear</span>
|
|
</h3>
|
|
<p>
|
|
The other time periods represent an <em>aggregation over
|
|
time</em>. In addition to the time period over which the
|
|
aggregation will occur, they also require an <em>aggregation
|
|
type</em>. An example would be the week's total precipitation
|
|
(where the aggregation type is <span class="code"><em>
|
|
sum</em></span>):
|
|
</p>
|
|
<pre class="tty">$week.rain.sum</pre>
|
|
<p>The dot code for an aggregation over time looks like:</p>
|
|
<pre class="tty"><em>$period.statstype.aggregation[.optional_unit_conversion][.optional_formatting]</em></pre>
|
|
<p>Where:</p>
|
|
<p class="indent">
|
|
<span class="code"><em>period</em></span> is the time period
|
|
over which the aggregation is to be done. Possible choices are <span
|
|
class="code">day</span>, <span class="code">week</span>, <span
|
|
class="code"> month</span>, <span class="code">year</span>, <span
|
|
class="code">rainyear</span>.
|
|
</p>
|
|
<p class="indent">
|
|
<span class="code"><em>statstype</em></span> is a statistical
|
|
type. See <em><a href="#statistical_types">Appendix C,
|
|
Statistical Types</a></em>, for a table of statistical types.
|
|
</p>
|
|
<p class="indent">
|
|
<span class="code"><em>aggregation</em></span> is an aggregation
|
|
type. This is something like '<span class="code">min</span>', '<span
|
|
class="code">sum</span>', '<span class="code">mintime</span>'.
|
|
If you ask for <span class="code">$month.outTemp.avg</span> you
|
|
are asking for the <em>average</em> outside temperature for the
|
|
month. The table <em> <a href="#statistical_types">Appendix
|
|
C: Statistical Types</a></em> shows what aggregation types are
|
|
available for which types.
|
|
</p>
|
|
<p class="indent">
|
|
<span class="code">optional_unit_conversion</span> is an
|
|
optional unit conversion tag. If provided, the results will be
|
|
converted into the specified units, otherwise the default units
|
|
specified in the skin configuration file (in section <span
|
|
class="code">[Units][[Groups]]</span>) will be used. See the
|
|
section <em><a href="#unit_conversion_options">Unit
|
|
Conversion Options</a></em> below.
|
|
</p>
|
|
<p class="indent">
|
|
<span class="code"><em>optional_formatting</em></span> is an
|
|
optional formatting tag that controls how the value will appear.
|
|
See the section <em><a href="#formatting_options">Formatting
|
|
Options</a></em> below.
|
|
</p>
|
|
|
|
<h3 id="unit_conversion_options">Unit conversion options</h3>
|
|
<p>
|
|
The tag <span class="code"><em>optional_unit_conversion</em></span>
|
|
can be used with either current observations or aggregations. If
|
|
supplied, the results will be converted to the specified units.
|
|
For example, if you have set <span class="code">group_pressure</span>
|
|
to inches of mercury (<span class="code">inHg</span>), then the
|
|
tag
|
|
</p>
|
|
<pre class="tty">Today's average pressure=$day.barometer.avg </pre>
|
|
<p>would normally give a result such as</p>
|
|
<p class="example_output">Today's average pressure=30.05 inHg
|
|
</p>
|
|
<p>
|
|
However, if you add "<span class="code">mbar</span>" to the end,
|
|
</p>
|
|
<pre class="tty">$day.barometer.avg.mbar </pre>
|
|
<p>then the results will be in millibars:</p>
|
|
<p class="example_output">Today's average pressure=1017.5 mbar
|
|
</p>
|
|
<h4>Wind ordinals</h4>
|
|
<p>Using this method, you can output compass ordinals for wind
|
|
direction. For example, the template</p>
|
|
<pre class="tty">Current wind direction is $current.windDir ($current.windDir.ordinal_compass)</pre>
|
|
<p>would result in:</p>
|
|
<p class="example_output">Current wind direction is 138° (SW)</p>
|
|
<p>
|
|
The ordinal abbreviations that are used are set by option <span
|
|
class="code"> directions</span> in the skin configuration file
|
|
<span class="code">skin.conf</span>.
|
|
</p>
|
|
<h4>Illegal conversions</h4>
|
|
<p>
|
|
If an inappropriate conversion is asked for, <em>e.g.</em>,
|
|
</p>
|
|
<pre class="tty">Today's average pressure=$day.barometer.degree_C </pre>
|
|
<p>then the offending tag will be put in the output:</p>
|
|
<p class="example_output">Today's average
|
|
pressure=$day.barometer.degree_C</p>
|
|
|
|
<h3 id="formatting_options">Formatting options</h3>
|
|
<p>
|
|
The tag <span class="code"><em>optional_formatting</em></span>
|
|
can be used with either current observations or aggregations. It
|
|
can be one of:
|
|
</p>
|
|
<table class="indent" style="width: 90%" summary="Formatting Options">
|
|
<tbody>
|
|
<tr>
|
|
<td><strong>Optional Formatting Tag</strong></td>
|
|
<td><strong>Comment</strong></td>
|
|
</tr>
|
|
<tr>
|
|
<td><em>(no tag)</em></td>
|
|
<td>Value is returned as a string, formatted using an
|
|
appropriate string format from <span class="code">skin.conf</span>.
|
|
A unit label from <span class="code">skin.conf</span> is
|
|
also attached at the end.
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">.string(<em>NONE_string</em>)
|
|
</td>
|
|
<td>Value is returned as a string, formatted using an
|
|
appropriate string format from <span class="code">skin.conf</span>.
|
|
If the value is <span class="code">None</span>, the string
|
|
<span class="code"> NONE_string</span> will be substituted
|
|
if given, otherwise the value for <span class="code">
|
|
NONE</span> in <span class="code"> <a
|
|
href="#Units_StringFormats">
|
|
[Units][[StringFormats]]</a>
|
|
</span> will be used. A unit label from <span class="code">
|
|
skin.conf</span> will be attached at the end.
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code"><span class="code">.formatted</span></td>
|
|
<td>Value is returned as a string, formatted using an
|
|
appropriate string format and <span class="code">None</span>
|
|
value from <span class="code">skin.conf</span>. No label.
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">.format(<em>string_format</em>, <em>NONE_string</em>)
|
|
</td>
|
|
<td>Value is returned as a string, using the string
|
|
format specified with <em>string_format</em>. If the value
|
|
is <span class="code">None</span>, the string <span
|
|
class="code">NONE_string</span> will be substituted if
|
|
given, otherwise the value for <span class="code">NONE</span>
|
|
in <span class="code"> <a
|
|
href="#Units_StringFormats">
|
|
[Units][[StringFormats]]</a>
|
|
</span> will be used. A unit label from <span class="code">
|
|
skin.conf</span> will be attached at the end.
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">.nolabel(string_format, NONE_string)</td>
|
|
<td>Value is returned as a string, using the string
|
|
format specified with <em>string_format</em>. If the value
|
|
is <span class="code">None</span>, the string <span
|
|
class="code">NONE_string</span> will be substituted if
|
|
given, otherwise the value for <span class="code">NONE</span>
|
|
in <span class="code"> <a
|
|
href="#Units_StringFormats">
|
|
[Units][[StringFormats]]</a>
|
|
</span> will be used. No label will be attached at the end.
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code"><span class="code">.raw</span></td>
|
|
<td>Value is returned "as is" without being converted
|
|
to a string and without any formatting applied. You must
|
|
be prepared to deal with a <span class="code">None</span>
|
|
value unless the value is converted directly to a string.
|
|
In this case, it will be converted to the empty string (<span
|
|
class="code">''</span>)
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p>Summary:</p>
|
|
<table class="indent" style="width: 80%"
|
|
summary="Summary of formatting options">
|
|
<tbody>
|
|
<tr>
|
|
<td><strong>Formatting Tag</strong></td>
|
|
<td><strong>Format Used</strong></td>
|
|
<td><strong>Label Used</strong></td>
|
|
<td><strong>NONE String</strong></td>
|
|
<td><strong>Returned Value</strong></td>
|
|
</tr>
|
|
<tr>
|
|
<td><em>(no tag)</em></td>
|
|
<td>From <span class="code">skin.conf</span></td>
|
|
<td>From <span class="code">skin.conf</span></td>
|
|
<td>From <span class="code">skin.conf</span></td>
|
|
<td>string</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">.string</td>
|
|
<td>From <span class="code">skin.conf</span></td>
|
|
<td>From <span class="code">skin.conf</span></td>
|
|
<td>Optional user-supplied</td>
|
|
<td>string</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">.formatted</td>
|
|
<td>From <span class="code">skin.conf</span></td>
|
|
<td>No label</td>
|
|
<td>From <span class="code">skin.conf</span></td>
|
|
<td>string</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">.format</td>
|
|
<td>User-supplied</td>
|
|
<td>From <span class="code">skin.conf</span></td>
|
|
<td>Optional user-supplied</td>
|
|
<td>string</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">.nolabel</td>
|
|
<td>User-supplied</td>
|
|
<td>No label</td>
|
|
<td>Optional user-supplied</td>
|
|
<td>string</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">.raw</td>
|
|
<td>None</td>
|
|
<td>No label</td>
|
|
<td>None</td>
|
|
<td>native value</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p>Here are some examples with the expected results:</p>
|
|
<table class="indent"
|
|
summary="Formatting options with expected results">
|
|
<tbody>
|
|
<tr>
|
|
<td><strong>Tag</strong></td>
|
|
<td><strong>Result</strong></td>
|
|
<td><strong>Comment</strong></td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">$current.outTemp</td>
|
|
<td class="code">45.2°F</td>
|
|
<td>String formatting and label from <span class="code">skin.conf</span></td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">$current.outTemp.string</td>
|
|
<td class="code">45.2°F</td>
|
|
<td>String formatting and label from <span class="code">skin.conf</span></td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">$current.UV.string</td>
|
|
<td class="code">N/A</td>
|
|
<td>This example assumes that the instrument has no UV
|
|
sensor, resulting in a <span class="code">None</span>
|
|
value. The string specified by <span class="code">NONE</span>
|
|
in <span class="code"> <a
|
|
href="#Units_StringFormats">[Units][[StringFormats]]</a></span>
|
|
is substituted.
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">$current.UV.string("No UV")</td>
|
|
<td class="code">No UV</td>
|
|
<td>This example assumes that the instrument has no UV
|
|
sensor, resulting in a <span class="code">None</span>
|
|
value. The string supplied by the user is substituted.
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">$current.outTemp.formatted</td>
|
|
<td class="code">45.2</td>
|
|
<td>String formatting from <span class="code">skin.conf</span>;
|
|
no label
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">$current.outTemp.format("%.3f")</td>
|
|
<td class="code">45.200°F</td>
|
|
<td>Specified string format used; label from <span
|
|
class="code"> skin.conf</span>.
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">$current.dateTime</td>
|
|
<td class="code">02-Apr-2010 16:25</td>
|
|
<td>Time formatting and label from <span class="code">skin.conf</span></td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">$current.dateTime.format("%H:%M")</td>
|
|
<td class="code">16:25</td>
|
|
<td>Specified time format used; label from <span
|
|
class="code"> skin.conf</span>.
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">$current.dateTime.raw</td>
|
|
<td class="code">1270250700</td>
|
|
<td>Unix epoch time, converted to string by template
|
|
engine.</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">$current.outTemp.raw</td>
|
|
<td class="code">45.2</td>
|
|
<td>Float returned, converted to string by template
|
|
engine.</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">$month.dateTime</td>
|
|
<td class="code">01-Apr-2010 00:00</td>
|
|
<td>Time formatting and label from <span class="code">skin.conf</span></td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">$month.outTemp.avg</td>
|
|
<td class="code">40.8°F</td>
|
|
<td>String formatting and label from <span class="code">skin.conf</span></td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">$month.outTemp.avg.string</td>
|
|
<td class="code">40.8°F</td>
|
|
<td>Time formatting and label from <span class="code">skin.conf</span></td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">$month.UV.avg.string</td>
|
|
<td class="code">N/A</td>
|
|
<td>This example assumes that the instrument has no UV
|
|
sensor, resulting in a <span class="code">None</span>
|
|
value. The string specified by <span class="code">NONE</span>
|
|
in <span class="code"> <a
|
|
href="#Units_StringFormats">[Units][[StringFormats]]</a></span>
|
|
is substituted.
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">$month.UV.avg.string("No UV")</td>
|
|
<td class="code">No UV</td>
|
|
<td>This example assumes that the instrument has no UV
|
|
sensor, resulting in a <span class="code">None</span>
|
|
value. The string supplied by the user is substituted.
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">$month.outTemp.avg.formatted</td>
|
|
<td class="code">40.8</td>
|
|
<td>String formatting from <span class="code">skin.conf</span>;
|
|
no label
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">$month.outTemp.avg.format("%.3f")</td>
|
|
<td class="code">40.759°F</td>
|
|
<td>Specified string format used; no label</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">$month.outTemp.avg.raw</td>
|
|
<td class="code">40.7589690722</td>
|
|
<td>Float returned, converted to string by template
|
|
engine</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">$month.UV.avg.raw</td>
|
|
<td class="code"><em>(empty)</em></td>
|
|
<td><span class="code">None</span> value converted to
|
|
empty string by template engine.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p>Note:</p>
|
|
<ul>
|
|
<li>Tags that take an argument (such as <span class="code">
|
|
.string(NONE_string)</span>) do not require parenthesis if the
|
|
argument is omitted.Thus, you can specify either <span
|
|
class="code"> $month.outTemp.string()</span> or <span
|
|
class="code">$month.outTemp.string</span>, if you want the
|
|
default value of <span class="code">NONE_string</span>. They
|
|
produce the same results.
|
|
</li>
|
|
</ul>
|
|
<h3>Type <span class="code">dateTime</span></h3>
|
|
<p>
|
|
While not an observation type, in many ways the time of an
|
|
observation, <span class="code">dateTime</span>, can be treated
|
|
as one. A tag such as <span class="code">$current.dateTime</span>
|
|
represents the <em>current time</em> (more properly, the time as
|
|
of the end of the last archive interval). Similarly, a tag such
|
|
as <span class="code">$month.dateTime</span> represents the
|
|
start time of the month. Like true observation types, explicit
|
|
formats can be specified, except that they require a <a
|
|
href="http://docs.python.org/library/datetime.html#strftime-strptime-behavior">
|
|
strftime() <em>time format</em>
|
|
</a>, rather than a <em>string format:</em>
|
|
</p>
|
|
<pre class="tty">$month.dateTime.format("%B %Y)</pre>
|
|
<p>produces</p>
|
|
<pre class="tty">January 2010</pre>
|
|
<p>
|
|
The returned string value will always be in <em>local time</em>.
|
|
</p>
|
|
<p>
|
|
The raw value of <span class="code">dateTime</span> is Unix
|
|
Epoch Time (number of seconds since 00:00:00 UTC 1 Jan 1970, <em>i.e.</em>,
|
|
a large number), which you must convert yourself to local time.
|
|
It is guaranteed to never be <span class="code">None</span>, so
|
|
you don't worry have to worry about handling a <span
|
|
class="code">None</span> value.
|
|
</p>
|
|
<h3>Tag <span class="code">$trend</span></h3>
|
|
<p>
|
|
The tag <span class="code">$trend</span> is available for time
|
|
trends, such as barometer trends. Here are some examples:
|
|
</p>
|
|
<table class="indent" style="width: 40%"
|
|
summary="Examples of using unit formats">
|
|
<tbody>
|
|
<tr>
|
|
<td><strong>Tag</strong></td>
|
|
<td><strong>Results</strong></td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">$trend.barometer</td>
|
|
<td class="code">-.02 inHg</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">$trend.outTemp</td>
|
|
<td class="code">1.1°C</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">$trend.time_delta</td>
|
|
<td class="code">10800 secs</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">$trend.time_delta.hour</td>
|
|
<td class="code">3 hrs</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p>
|
|
Note that the time delta over which the trend is calculated is
|
|
also available. This time delta is set by an option in the skin
|
|
configuration file, <span class="code"><a href="#trend">time_delta</a></span>.
|
|
</p>
|
|
<p>As a summary, the template expression</p>
|
|
<pre class="tty"><p>The barometer trend over $trend.time_delta.hour is $trend.barometer.format("%+.2f").</p></pre>
|
|
<p>would result in</p>
|
|
<p class="example_output">The barometer trend over 3 hrs is
|
|
+.02 inHg.</p>
|
|
<h3>Tag <span class="code">$unit</span></h3>
|
|
<p>The unit type, label, and string formats are also
|
|
available, allowing you to do highly customized labels:</p>
|
|
<table class="indent" style="width: 40%"
|
|
summary="Examples of using unit formats">
|
|
<tbody>
|
|
<tr>
|
|
<td><strong>Tag</strong></td>
|
|
<td><strong>Results</strong></td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">$unit.unit_type.outTemp</td>
|
|
<td class="code">degree_C</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">$unit.label.outTemp</td>
|
|
<td class="code">°C</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">$unit.format.outTemp</td>
|
|
<td class="code">%.1f</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p>As a summary, the tag</p>
|
|
<pre class="tty">$day.outTemp.max.formatted$unit.label.outTemp</pre>
|
|
<p>would result in</p>
|
|
<pre class="tty">21.2°C</pre>
|
|
<p>
|
|
(assuming metric values have been specified for <span
|
|
class="code"> group_temperature</span>), essentially
|
|
reproducing the results of the simpler tag <span class="code">$day.outTemp.max</span>.
|
|
</p>
|
|
<h3>Iteration</h3>
|
|
<p>
|
|
For dot codes using an aggregation (<em>e.g.</em>, <span
|
|
class="code"> $day</span>, <span class="code">$week</span>, <span
|
|
class="code">$month</span>, <span class="code">$year</span>, <span
|
|
class="code">$rainyear</span>, then the aggregation period can
|
|
be iterated over by day or month. These are the only two
|
|
iteration periods available as of this version.
|
|
</p>
|
|
<p>
|
|
This example uses a Cheetah '<span class="code">for</span>' loop
|
|
to iterate over all months in a year, printing out each month's
|
|
min and max temperature (the iteration loop is <span
|
|
class="highlight"> highlighted </span>):
|
|
</p>
|
|
<pre class="tty"><html>
|
|
<head>
|
|
<title>Year stats by month</title>
|
|
</head>
|
|
<body>
|
|
<p>Min, max temperatures by month:</p>
|
|
<span class="highlight"> #for $month in $year.months</span>
|
|
<p>$month.dateTime.format("%B"): Min, max temperatures: $month.outTemp.min $month.outTemp.max</p>
|
|
<span class="highlight"> #end for</span>
|
|
</body>
|
|
</html></pre>
|
|
<p>Produces results:</p>
|
|
<pre class="tty">Min, max temperatures by month:
|
|
January: Min, max temperatures: 30.1°F 51.5°F
|
|
February: Min, max temperatures: 24.4°F 58.6°F
|
|
March: Min, max temperatures: 27.3°F 64.1°F
|
|
April: Min, max temperatures: 33.2°F 52.5°F
|
|
May: Min, max temperatures: N/A N/A
|
|
June: Min, max temperatures: N/A N/A
|
|
July: Min, max temperatures: N/A N/A
|
|
August: Min, max temperatures: N/A N/A
|
|
September: Min, max temperatures: N/A N/A
|
|
October: Min, max temperatures: N/A N/A
|
|
November: Min, max temperatures: N/A N/A
|
|
December: Min, max temperatures: N/A N/A</pre>
|
|
<p>
|
|
See the NOAA template files <span class="code">NOAA/NOAA-YYYY.txt.tmpl</span>
|
|
and <span class="code">NOAA/NOAA-YYYY-MM.txt.tmpl</span> for
|
|
examples using iteration, as well as explicit formatting.
|
|
</p>
|
|
<h3>Almanac</h3>
|
|
<p>
|
|
If module <a href="http://rhodesmill.org/pyephem">pyephem</a>
|
|
has been installed, then <span class="code">weewx</span> can
|
|
generate extensive almanac information for the Sun, Moon, Venus,
|
|
Mars, Jupiter, and other heavenly bodies, including their rise,
|
|
transit and set times, as well as their azimuth and altitude.
|
|
Other information is also available.
|
|
</p>
|
|
<p>Here is a small sampling:</p>
|
|
<pre class="tty"><html>
|
|
<head>
|
|
<title>Almanac data</title>
|
|
</head>
|
|
<body>
|
|
<p>Current time is $current.dateTime<p>
|
|
#if $almanac.hasExtras
|
|
<p>Sunrise, transit, sunset: $almanac.sun.rise $almanac.sun.transit $almanac.sun.set</p>
|
|
<p>Moonrise, transit, moonset: $almanac.moon.rise $almanac.moon.transit $almanac.moon.set</p>
|
|
<p>Mars rise, transit, set: $almanac.mars.rise $almanac.mars.transit $almanac.mars.set</p>
|
|
<p>Azimuth, altitude of mars: $almanac.mars.az $almanac.mars.alt</p>
|
|
<p>Next new, full moon: $almanac.next_new_moon $almanac.next_full_moon</p>
|
|
<p>Next summer, winter solstice: $almanac.next_summer_solstice $almanac.next_winter_solstice</p>
|
|
#else
|
|
<p>Sunrise, sunset: $almanac.sunrise $almanac.sunset</p>
|
|
#end if
|
|
</body>
|
|
</html></pre>
|
|
<p>If your installation has pyephem installed this would
|
|
result in:</p>
|
|
<pre class="tty">Current time is 29-Mar-2011 09:20
|
|
Sunrise, transit, sunset: 06:51 13:11 19:30
|
|
Moonrise, transit, moonset: 04:33 09:44 15:04
|
|
Mars rise, transit, set: 06:35 12:30 18:26
|
|
Azimuth, altitude of mars: 124.354959275 26.4808431952
|
|
Next new, full moon: 03-Apr-2011 07:32 17-Apr-2011 19:43
|
|
Next summer, winter solstice: 21-Jun-2011 10:16 21-Dec-2011 21:29</pre>
|
|
<p>Otherwise, a fallback position is used, resulting in</p>
|
|
<pre class="tty">Current time is 29-Mar-2011 09:20
|
|
Sunrise, sunset: 06:51 19:30</pre>
|
|
<p>
|
|
As shown in the example, you can test whether this extended
|
|
almanac information is available with the value <span
|
|
class="code"> $almanac.hasExtras</span>.
|
|
</p>
|
|
<p>The almanac information falls in two categories:</p>
|
|
<ul>
|
|
<li>Calendar events</li>
|
|
<li>Heavenly bodies</li>
|
|
</ul>
|
|
<p>We will cover each of these separately.</p>
|
|
<h4>Calendar events</h4>
|
|
<p>
|
|
"Calendar events" do not require a heavenly body. They cover
|
|
things such as "<span class="code">next_solstice</span>", or "<span
|
|
class="code">next_first_quarter_moon</span>". The syntax here
|
|
is
|
|
</p>
|
|
<pre class="tty">$almanac.next_solstice</pre>
|
|
<p>or</p>
|
|
<pre class="tty">$almanac.next_first_quarter_moon</pre>
|
|
<p>Here is a table of the information that falls into this
|
|
category:</p>
|
|
<table class="indent code" style="width: 60%">
|
|
<tbody>
|
|
<tr>
|
|
<td>previous_equinox</td>
|
|
<td>next_equinox</td>
|
|
<td>previous_solstice</td>
|
|
<td>next_solstice</td>
|
|
</tr>
|
|
<tr>
|
|
<td>previous_autumnal_equinox</td>
|
|
<td>next_autumnal_equinox</td>
|
|
<td>previous_vernal_equinox</td>
|
|
<td>next_vernal_equinox</td>
|
|
</tr>
|
|
<tr>
|
|
<td>previous_winter_solstice</td>
|
|
<td>next_winter_solstice</td>
|
|
<td>previous_summer_solstice</td>
|
|
<td>next_summer_solstice</td>
|
|
</tr>
|
|
<tr>
|
|
<td>previous_new_moon</td>
|
|
<td>next_new_moon</td>
|
|
<td>previous_first_quarter_moon</td>
|
|
<td>next_first_quarter_moon</td>
|
|
</tr>
|
|
<tr>
|
|
<td>previous_full_moon</td>
|
|
<td>next_full_moon</td>
|
|
<td>previous_last_quarter_moon</td>
|
|
<td>next_last_quarter_moon</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<h4>Heavenly bodies</h4>
|
|
<p>The second category does require a heavenly body. This
|
|
covers queries such as, "When does Jupiter rise?" or, "When does
|
|
the sun transit?" Examples are</p>
|
|
<pre class="tty">$almanac.jupiter.rise</pre>
|
|
<p>or</p>
|
|
<pre class="tty">$almanac.sun.transit</pre>
|
|
<p>
|
|
To accurately calculate these times, <span class="code">weewx</span>
|
|
automatically uses the present temperature and pressure to
|
|
calculate refraction effects. However, you can override these
|
|
values, which will be necessary if you wish to match the almanac
|
|
times published by the Naval Observatory <a
|
|
href="http://rhodesmill.org/pyephem/rise-set.html">as
|
|
explained in the pyephem documentation</a>. For example, to match
|
|
the sunrise time as published by the Observatory, instead of
|
|
</p>
|
|
<pre class="tty">$almanac.sun.rise</pre>
|
|
<p>use</p>
|
|
<pre class="tty">$almanac(pressure=0, horizon=-34.0/60.0).sun.rise</pre>
|
|
<p>By setting pressure to zero we are bypassing the refraction
|
|
calculations and manually setting the horizon to be 34
|
|
arcminutes lower than the normal horizon. This is what the Navy
|
|
uses.</p>
|
|
<p>
|
|
If you wish to calculate the start of civil twilight, you can
|
|
set the horizon to -6 degrees, and also tell <span class="code">weewx</span>
|
|
to use the center of the sun (instead of the upper limb, which
|
|
it normally uses) to do the calcuation:
|
|
</p>
|
|
<pre class="tty">$almanac(pressure=0, horizon=-6).sun(use_center=1).rise</pre>
|
|
<p>The general syntax is:</p>
|
|
<pre class="tty">$almanac(pressure=<em>pressure</em>, horizon=<em>horizon</em>,
|
|
temperature=<em>temperature_C</em>).<em>heavenly_body</em>(use_center=[01]).<em>attribute</em></pre>
|
|
<p>As you can see, in addition to the horizon angle, you can
|
|
also override atmospheric pressure and temperature (degrees
|
|
Celsius).</p>
|
|
<p>
|
|
PyEphem offers an extensive list of objects that can be used for
|
|
the <span class="code"><em>heavenly_body</em></span> tag. All
|
|
the planets and many stars are in the list.
|
|
</p>
|
|
<p>
|
|
The <span class="code">attribute</span> tag can be one of
|
|
</p>
|
|
<table class="indent code" style="width: 60%">
|
|
<tbody>
|
|
<tr>
|
|
<td>az</td>
|
|
<td>alt</td>
|
|
<td>a_ra</td>
|
|
<td>a_dec</td>
|
|
</tr>
|
|
<tr>
|
|
<td>g_ra</td>
|
|
<td>ra</td>
|
|
<td>g_dec</td>
|
|
<td>dec</td>
|
|
</tr>
|
|
<tr>
|
|
<td>elong</td>
|
|
<td>radius</td>
|
|
<td>hlong</td>
|
|
<td>hlat</td>
|
|
</tr>
|
|
<tr>
|
|
<td>sublat</td>
|
|
<td>sublong</td>
|
|
<td>next_rising</td>
|
|
<td>next_setting</td>
|
|
</tr>
|
|
<tr>
|
|
<td>next_transit</td>
|
|
<td>next_antitransit</td>
|
|
<td>previous_rising</td>
|
|
<td>previous_setting</td>
|
|
</tr>
|
|
<tr>
|
|
<td>previous_transit</td>
|
|
<td>previous_antitransit</td>
|
|
<td>rise</td>
|
|
<td>set</td>
|
|
</tr>
|
|
<tr>
|
|
<td>transit</td>
|
|
<td></td>
|
|
<td></td>
|
|
<td></td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<h2 id="defining_new_tags">Defining new tags</h2>
|
|
In the section on <em><a href="#templates">Customizing
|
|
templates</a></em>, we have seen how you can change a template and make
|
|
use of the various tags available such as <span class="code">$day.outTemp.max</span>
|
|
for the maximum outside temperature for the day. But, what if you
|
|
want to introduce some new data for which no tag is available?
|
|
<p>
|
|
If you wish to introduce a static tag, that is, one that will
|
|
not change with time (such as a Google analytics Tracker ID, or
|
|
your name), then this is very easy: simply put it in section <span
|
|
class="code"><a href="#Extras">[Extras]</a></span> in the skin
|
|
configuration file. More information on how to do this can be
|
|
found there.
|
|
</p>
|
|
<p>
|
|
But, what if you wish to introduce a more dynamic tag, one that
|
|
requires some calculation, or perhaps uses the database? Simply
|
|
putting it in the <span class="code">[Extras]</span> section
|
|
won't do, because then it cannot change.
|
|
</p>
|
|
<p>
|
|
The answer is to write a <em>search list extension</em>.
|
|
</p>
|
|
<h3>Search list</h3>
|
|
<p>
|
|
The Cheetah template engine (which <span class="code">weewx</span>
|
|
uses) finds tags by scanning a <em>search list</em>, a
|
|
Python list of objects. For example, for a tag <span
|
|
class="code">$foo</span>, the engine will scan down the list,
|
|
trying each object <span class="code">obj</span> in turn. First
|
|
it tries using <span class="code">foo</span> as an attribute,
|
|
that is, <span class="code">obj.foo</span>. If that raises an
|
|
exception <span class="code"> AttributeError</span>, then it
|
|
will try <span class="code">foo</span> as a key, that is <span
|
|
class="code">obj[key]</span>. If that raises a <span
|
|
class="code">KeyError</span>, then it moves on to the next
|
|
item in the list. The first match that does not raise an
|
|
exception is returned. If no match is found, it raises a <span
|
|
class="code">NameMapper.NotFound</span> exception.
|
|
</p>
|
|
<h3>Extending the list</h3>
|
|
<p>Weewx comes with a number of objects already in the search
|
|
list, but you can extend it. To do so, you should have some
|
|
familiarity with Python, in particular, how to write new classes
|
|
and member functions for them.</p>
|
|
<p>
|
|
Let's look at an example. The regular version of <span
|
|
class="code"> weewx</span> offers statistical summaries by
|
|
day, week, month, and year. Suppose we would like to add two
|
|
more:
|
|
</p>
|
|
<ul>
|
|
<li>All-time statistics. This would allow us to display
|
|
statistics such as the all-time high or low temperature seen
|
|
at your station;</li>
|
|
<li>Seven days statistics. While <span class="code">weewx</span>
|
|
offers the tag <span class="code">$week</span>, this is
|
|
statistics <em>since Sunday at midnight</em>. We would like to
|
|
have statistics for a full week, that is since midnight seven
|
|
days ago.
|
|
</li>
|
|
</ul>
|
|
<p>
|
|
This example is included in the distribution as <span
|
|
class="symcode"> $BIN_ROOT</span><span class="code">/examples/xsearch.py</span>:
|
|
</p>
|
|
<pre class="tty">import datetime
|
|
import time
|
|
|
|
from weewx.cheetahgenerator import SearchList
|
|
from weewx.stats import TimeSpanStats
|
|
from weeutil.weeutil import TimeSpan
|
|
|
|
class MyXSearch(SearchList): #1
|
|
|
|
def __init__(self, generator): #2
|
|
SearchList.__init__(self, generator)
|
|
|
|
def get_extension(self, valid_timespan, archivedb, statsdb): #3
|
|
|
|
# First, get a TimeSpanStats object for all time. This one is easy
|
|
# because the object valid_timespan already holds all valid times to be
|
|
# used in the report.
|
|
all_stats = TimeSpanStats(valid_timespan,
|
|
statsdb,
|
|
formatter=self.generator.formatter,
|
|
converter=self.generator.converter) # 4
|
|
|
|
# Now get a TimeSpanStats object for the last seven days. This one we
|
|
# will have to calculate. First, calculate the time at midnight, seven
|
|
# days ago. The variable week_dt will be an instance of datetime.date.
|
|
week_dt = datetime.date.fromtimestamp(valid_timespan.stop) - datetime.timedelta(weeks=1) #5
|
|
# Now convert it to unix epoch time:
|
|
week_ts = time.mktime(week_dt.timetuple()) # 6
|
|
# Now form a TimeSpanStats object, using the time span we just calculated:
|
|
seven_day_stats = TimeSpanStats(TimeSpan(week_ts, valid_timespan.stop),
|
|
statsdb,
|
|
formatter=self.generator.formatter,
|
|
converter=self.generator.converter) #7
|
|
|
|
# Now create a small dictionary with keys 'alltime' and 'seven_day':
|
|
search_list_extension = {'alltime' : all_stats,
|
|
'seven_day' : seven_day_stats} # 8
|
|
|
|
return search_list_extension</pre>
|
|
<p>Going through the example, line by line:</p>
|
|
<ol>
|
|
<li>Create a new class called <span class="code">MyXSearch</span>,
|
|
which will inherit from class <span class="code">SearchList</span>.
|
|
All search list extensions inherit from this class.
|
|
</li>
|
|
<li>Create an initializer for our new class. In this case,
|
|
the initializer does nothing except pass its only parameter, <span
|
|
class="code">generator</span>, a reference to the calling
|
|
generator, to its superclass, <span class="code">SearchList</span>.
|
|
The superclass will store it in <span class="code">self</span>.
|
|
</li>
|
|
<li>Override member function <span class="code">get_extension()</span>.
|
|
This function will be called when the generator is ready to
|
|
accept your new search list extension. The parameters that
|
|
will be passed in are:
|
|
<ul>
|
|
<li><span class="code">self</span> Python's way of
|
|
indicating the instance we are working with;</li>
|
|
<li><span class="code">valid_timespan</span> An
|
|
instance of the utility class <span class="code">TimeSpan</span>.
|
|
This will contain the valid start and ending times used by
|
|
the template. Normally, this is all valid times;</li>
|
|
<li><span class="code">archivedb</span> An instance of
|
|
<span class="code">weewx.archive.Archive</span>, holding
|
|
the archive database;</li>
|
|
<li><span class="code">statsdb</span> An instance of <span
|
|
class="code">weewx.stats.StatsDb</span>, holding the
|
|
statistical database.</li>
|
|
</ul>
|
|
</li>
|
|
<li>The class <span class="code">TimeSpanStats</span>
|
|
represents a statistical calculation over a time period. In
|
|
our case, we will set it up to represent the statistics over
|
|
all possible times. The class takes 4 parameters.
|
|
<ul>
|
|
<li>The first is the timespan over which the
|
|
calculation is to be done. Here, we have a lucky
|
|
coincidence: the variable <span class="code">valid_timespan</span>
|
|
already holds a <span class="code">TimeSpan</span> object
|
|
representing the domain of all valid timespans, so we
|
|
simply pass it in.
|
|
</li>
|
|
<li>The second is the statistical database the
|
|
calculation is to be run against. We simply pass in <span
|
|
class="code">statsdb</span>.
|
|
</li>
|
|
<li>The third should be an instance of class <span
|
|
class="code">weewx.units.Formatter</span>, which contains
|
|
information about how the results should be formatted. We
|
|
just pass in the formatter set up by the generator, <span
|
|
class="code">self.generator.formatter</span>.
|
|
</li>
|
|
<li>The fourth should be an instance of <span
|
|
class="code">weewx.units.Converter</span>, which contains
|
|
information about the target units (<em>e.g.</em>, "<span
|
|
class="code">degree_C</span>") that are to be used. Again,
|
|
we just pass in the instance set up by the generator, <span
|
|
class="code">self.generator.converter</span>.
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
</ol>
|
|
<p>
|
|
That one was relatively easy because we already had an instance
|
|
of <span class="code">TimeSpan</span>, <span class="code">valid_timespan</span>,
|
|
that represented the time over which we wanted to do the
|
|
calculations. Setting up an instance that will work for the last
|
|
seven days is a bit trickier. Continuing our example...
|
|
</p>
|
|
<ol start="5">
|
|
<li>The object <span class="code">valid_timespan</span>
|
|
holds the domain of all valid times, but in order to calculate
|
|
statistics for the last seven days, we need not the earliest
|
|
valid time, but the time at midnight seven days ago. So, we do
|
|
a little Python date arithmetic to calculate this. The object
|
|
<span class="code">week_dt</span> will be an instance of <span
|
|
class="code">datetime.date</span>.
|
|
</li>
|
|
<li>We convert it to unix epoch time.</li>
|
|
<li>Now we are ready to initialize an appropriate <span
|
|
class="code">TimeSpanStats</span> object. It's the same as in
|
|
step #4, except we use our new timespan object.
|
|
</li>
|
|
<li>Create a small dictionary with two keys, '<span
|
|
class="code">alltime</span>', and '<span class="code">seven_day</span>'
|
|
and return it.
|
|
</li>
|
|
</ol>
|
|
<p>
|
|
The last step is to tell the template engine where to find our
|
|
extension. You do that by going into the skin configuration
|
|
file, <span class="code">skin.conf</span>, and adding the option
|
|
<span class="code">search_list_extensions</span> with our new
|
|
extension. When you're done, it will look something like this:
|
|
</p>
|
|
<pre class="tty">[CheetahGenerator]
|
|
# 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', or 'strict_ascii'
|
|
encoding = html_entities
|
|
|
|
<span class="highlight">search_list_extensions = examples.xsearch.MyXSearch</span>
|
|
|
|
[[SummaryByMonth]]
|
|
...
|
|
</pre>
|
|
<p>
|
|
Our addition has been <span class="highlight"> highlighted </span>.
|
|
Note that it is in the section <span class="code">[CheetahGenerator]</span>.
|
|
(This section was called <span class="code">
|
|
[FileGenerator]</span> in earlier versions of <span class="code">weewx</span>,
|
|
a name which will still work.)
|
|
</p>
|
|
<p>
|
|
Now, if the Cheetah engine encounters the tag <span class="code">
|
|
$alltime</span>, it will scan the search list, looking for an
|
|
attribute or key that matches <span class="code">alltime</span>.
|
|
When it gets to the little dictionary we provided, it will find
|
|
a matching key, allowing it to retrieve the appropriate <span
|
|
class="code">TimeSpanStats</span> object.
|
|
</p>
|
|
<p>With this approach, you can now include "all time" or
|
|
"seven day" statistics in your HTML templates:</p>
|
|
<pre class="tty">...
|
|
<table>
|
|
<tr>
|
|
<td>Maximum temperature to date: </td>
|
|
<td>$alltime.outTemp.max</td>
|
|
</tr>
|
|
<tr>
|
|
<td>Minimum temperature to date: </td>
|
|
<td>$alltime.outTemp.min
|
|
</tr>
|
|
<tr>
|
|
<td>Rain over the last seven days: </td>
|
|
<td>$seven_day.rain.sum
|
|
</tr>
|
|
... (more table entries)</pre>
|
|
<p>
|
|
If you place a custom generator somewhere other than the <span
|
|
class="symcode">$BIN_ROOT</span> hierarchy where <span
|
|
class="code">weewxd</span> resides, you may have to specify
|
|
its location in the environment variable <span class="code">PYTHONPATH</span>
|
|
in the shell where you start weewx:
|
|
</p>
|
|
<pre class="tty">export PYTHONPATH=/home/me/secret_location</pre>
|
|
|
|
<h1 id="standard_skin">Customizing skins: the Standard skin</h1>
|
|
<p>
|
|
This section is a reference to the options appearing in the
|
|
Standard skin configuration file, found in <span class="symcode">$SKIN_ROOT</span><span
|
|
class="code">/Standard/skin.conf</span>.
|
|
</p>
|
|
<p>
|
|
It is worth noting that, like the main configuration file <span
|
|
class="code">weewx.conf</span>, UTF-8 is used throughout. The
|
|
most important options are up near the top of the file. The
|
|
truly important ones, the ones you are likely to have to
|
|
customize for your station, are <span class="config_important"><strong>
|
|
highlighted</strong></span>.
|
|
</p>
|
|
|
|
<h2 class="config_section" id="Extras">[Extras]</h2>
|
|
<p>This section is available to you to add any static tags
|
|
that you might want to be available in the templates.</p>
|
|
|
|
<h3>An Example: the Standard skin</h3>
|
|
<p>
|
|
As an example, the Standard <span class="code">skin.conf</span>
|
|
file includes two options: <span class="code">radar_url</span>,
|
|
which is available as tag <span class="code">$Extras.radar_url</span>,
|
|
and <span class="code">googleAnalyticsId</span>, available as
|
|
tag <span class="code">$Extras.googleAnalyticsId</span>. If you
|
|
take a look at the template <span class="code">index.html.tmpl</span>
|
|
you will see examples of testing for these tags (search the file
|
|
for the string <span class="code">radar_url</span> or <span
|
|
class="code">googleAnalyticsId</span> to find them).
|
|
</p>
|
|
<p class="config_option">radar_url</p>
|
|
<p>If set, the NOAA radar image will be displayed. If
|
|
commented out, no image will be displayed.</p>
|
|
<p class="config_option">googleAnalyticsId</p>
|
|
<p>
|
|
If you have a <a href="http://www.google.com/analytics/">Google
|
|
Analytics ID</a>, you can set it here. The Google Analytics
|
|
Javascript code will then be included, enabling analytics of
|
|
your website usage. If commented out, the code will not be
|
|
included.
|
|
</p>
|
|
|
|
<h3>Extending <span class="code">[Extras]</span></h3>
|
|
<p>Other tags can be added in a similar manner, including
|
|
sub-sections. For example, say you have added a video camera and
|
|
you would like to add a still image with a hyperlink to a page
|
|
with the video. You want all of these options to be neatly
|
|
contained in a sub-section.</p>
|
|
<pre class="tty">[Extras]
|
|
[[video]]
|
|
still = video_capture.jpg
|
|
hyperlink = <a href="http://www.eatatjoes.com/video.html">http://www.eatatjoes.com/video.html</a></pre>
|
|
<p>Then in your template you could refer to these as:</p>
|
|
<pre class="tty"><a href="$Extras.video.hyperlink">
|
|
<img src="$Extras.video.still" alt="Video capture"/>
|
|
</a></pre>
|
|
<h2 class="config_section">[Units]</h2>
|
|
<p>This section deals with Units and their formatting.</p>
|
|
<h3 class="config_section">[[Groups]]</h3>
|
|
<p>
|
|
This sub-section lists all the <em>Unit Groups</em> and
|
|
specifies which unit system is to be used for each one of them.
|
|
</p>
|
|
<p>
|
|
As there are many different observational measurement types
|
|
(such as '<span class="code">outTemp</span>', '<span
|
|
class="code">barometer</span>', etc.) used in <span
|
|
class="code">weewx</span> (more than 50 at last count), it
|
|
would be tedious, not to say possibly inconsistent, to specify a
|
|
different measurement system for each one of them. At the other
|
|
extreme, requiring all of them to be "U.S. Customary" or
|
|
"Metric" seems overly restrictive. <span class="code">Weewx</span>
|
|
has taken a middle route and divided all the different
|
|
observation types into 12 different "<em>unit groups</em>." A
|
|
unit group is something like "<span class="code">group_temperature</span>."
|
|
It represents the measurement system to be used by all
|
|
observation types that are measured in temperature, such as
|
|
inside temperature (type '<span class="code">inTemp</span>'),
|
|
outside temperature ('<span class="code">outTemp</span>'),
|
|
dewpoint ('<span class="code">dewpoint</span>'), wind chill ('<span
|
|
class="code">windchill</span>'), and so on. If you decide that
|
|
you want unit group <span class="code"> group_temperature</span>
|
|
to be measured in "<span class="code">degree_C</span>" then you
|
|
are saying <em>all</em> members of its group will be reported in
|
|
degrees Celsius.
|
|
</p>
|
|
<p>
|
|
Note that the unit system is always specified in the singular.
|
|
That is, specify "<span class="code">degree_C</span>" or "<span
|
|
class="code">foot</span>", not "<span class="code">degrees_C</span>"
|
|
or "<span class="code">feet</span>". See the Appendix <em>
|
|
<a href="#units">Units</a>
|
|
</em> for more information, including a concise summary of the
|
|
groups, their members, and which options can be used for each
|
|
group.
|
|
</p>
|
|
<p class="config_important">
|
|
<a class="config_option" id="group_altitude"> group_altitude</a>
|
|
</p>
|
|
<p>
|
|
Which measurement unit to be used for altitude. Possible options
|
|
are '<span class="code">foot</span>' or '<span class="code">meter</span>'.
|
|
</p>
|
|
<p class="config_option">group_direction</p>
|
|
<p>
|
|
Which measurement unit to be used for direction. The only option
|
|
is "<span class="code">degree_compass</span>".
|
|
</p>
|
|
<p class="config_option">group_moisture</p>
|
|
<p>
|
|
The measurement unit to be used for soil moisture. The only
|
|
option is "<span class="code">centibar</span>."
|
|
</p>
|
|
<p class="config_option">group_percent</p>
|
|
<p>
|
|
The measurement unit to be used for percentages. The only option
|
|
is "<span class="code">percent</span>".
|
|
</p>
|
|
<p class="config_important">group_pressure</p>
|
|
<p>
|
|
The measurement unit to be used for pressure. Possible options
|
|
are one of "<span class="code">inHg</span>" (inches of mercury),
|
|
"<span class="code">mbar</span>", or "<span class="code">hPa</span>."
|
|
</p>
|
|
<p class="config_option">group_radiation</p>
|
|
<p>
|
|
The measurement unit to be used for radiation. The only option
|
|
is "<span class="code">watt_per_meter_squared</span>."
|
|
</p>
|
|
<p class="config_important">group_rain</p>
|
|
<p>
|
|
The measurement unit to be used for precipitation. Options are "<span
|
|
class="code">inch</span>", "<span class="code">cm</span>," or
|
|
"<span class="code">mm</span>."
|
|
</p>
|
|
<p class="config_important">group_rainrate</p>
|
|
<p>
|
|
The measurement unit to be used for rate of precipitation.
|
|
Possible options are one of "<span class="code">inch_per_hour</span>",
|
|
"<span class="code">cm_per_hour</span>", or "<span class="code">mm_per_hour</span>".
|
|
</p>
|
|
<p class="config_important">group_speed</p>
|
|
<p>
|
|
The measurement unit to be used for wind speeds. Possible
|
|
options are one of "<span class="code">mile_per_hour</span>", "<span
|
|
class="code">km_per_hour</span>", "<span class="code">knot</span>",
|
|
or "<span class="code">meter_per_second</span>."
|
|
</p>
|
|
<p class="config_important">group_speed2</p>
|
|
<p>
|
|
This group is similar to <span class="code">group_speed</span>,
|
|
but is used for calculated wind speeds which typically have a
|
|
slightly higher resolution. Possible options are one "<span
|
|
class="code">mile_per_hour2</span>", "<span class="code">km_per_hour2</span>",
|
|
"<span class="code">knot2</span>", or "<span class="code">meter_per_second2</span>".
|
|
</p>
|
|
<p>
|
|
<a class="config_important" id="group_temperature">group_temperature</a>
|
|
</p>
|
|
<p>
|
|
The measurement unit to be used for temperatures. Options are "<span
|
|
class="code">degree_F</span>" or "<span class="code">degree_C</span>."
|
|
</p>
|
|
<p class="config_option">group_volt</p>
|
|
<p>
|
|
The measurement unit to be used for voltages. The only option is
|
|
"<span class="code">volt</span>."
|
|
</p>
|
|
<h3 class="config_section" id="Units_StringFormats">[[StringFormats]]</h3>
|
|
<p>This sub-section is used to specify what string format is
|
|
to be used for each unit when a quantity needs to be converted
|
|
to a string. Typically, this happens with y-axis labeling on
|
|
plots and for statistics in HTML file generation. For example,
|
|
the options</p>
|
|
<pre class="tty">degree_C = %.1f
|
|
inch = %.2f</pre>
|
|
<p>
|
|
would specify that the given string formats are to be used when
|
|
formatting any temperature measured in degrees Celsius or any
|
|
precipitation amount measured in inches, respectively. The <a
|
|
href="http://docs.python.org/library/string.html#format-specification-mini-language">
|
|
formatting codes are those used by Python</a>, a, and are very
|
|
similar to C's <span class="code">sprintf()</span> codes.
|
|
</p>
|
|
<p>
|
|
You can also specify what string to use for an invalid or
|
|
unavailable measurement (value '<span class="code">None</span>').
|
|
For example,
|
|
</p>
|
|
<pre class="tty">NONE = " N/A "</pre>
|
|
<h3 class="config_section" id="Units_Labels">[[Labels]]</h3>
|
|
<p>This sub-section specifies what label is to be used for
|
|
each measurement unit type. For example, the options</p>
|
|
<pre class="tty">degree_F = °F
|
|
inch = ' in'</pre>
|
|
<p>
|
|
would cause all temperatures to have unit labels <span
|
|
class="code">°F</span> and all precipitation to have labels <span
|
|
class="code">in</span>. If any special symbols are to be used
|
|
(such as the degree sign above) they should be encoded in UTF-8.
|
|
This is generally what most text editors use if you
|
|
cut-and-paste from a character map. Labels used in plot images
|
|
will be converted to Latin-1 first (this is all the Python
|
|
Imaging Library can handle).
|
|
</p>
|
|
<h3 class="config_section" id="Units_TimeFormats">[[TimeFormats]]</h3>
|
|
<p>
|
|
This sub-section is used for date and time labels, using <a
|
|
href="http://docs.python.org/library/datetime.html#strftime-behavior">
|
|
strftime()</a> formats. The values that come with the default <span
|
|
class="code"> skin.conf</span> will work for most locales, <a
|
|
href="#Environment_variable_LANG">provided you set the
|
|
environment variable LANG</a> before running <span class="code">weewx</span>.
|
|
</p>
|
|
<p>While they give acceptable results in all locales, the
|
|
defaults are not the most attractive. For example, the format
|
|
used for the month summary is</p>
|
|
<pre class="tty">month = %x %X</pre>
|
|
<p>which (in the U.S. locale) results in something that looks
|
|
like</p>
|
|
<p class="example_output">11/09/09 05:20:00 PM</p>
|
|
<p>You may wish to do something fancier. For example, try this
|
|
one</p>
|
|
<pre class="tty">month = %d-%b-%Y %H:%M</pre>
|
|
<p>which results in a label that looks like:</p>
|
|
<p class="example_output">06-Oct-2009 15:20</p>
|
|
<p>
|
|
Section <span class="code">[[TimeFormats]]</span> also allows
|
|
the formatting to be set for almanac times:
|
|
</p>
|
|
<pre class="tty">ephem_day = %X
|
|
ephem_year = %x %X</pre>
|
|
<p>
|
|
The first of these, <span class="code">ephem_day</span>, is used
|
|
for almanac times within the day, such as sunrise or sunset. The
|
|
second, <span class="code">ephem_year</span>, is used for
|
|
almanac times within the year, such as the next equinox or full
|
|
moon.
|
|
</p>
|
|
<h3 class="config_section">[[Ordinates]]</h3>
|
|
<p class="config_option">directions</p>
|
|
<p>
|
|
Set to the abbreviations to be used for ordinal directions. By
|
|
default, this is <span class="code">N, NNE, NE, ENE, E,
|
|
ESE, SE, SSE, S, SSW, SW, WSW, W, WNW, NW, NNW, N</span>.
|
|
</p>
|
|
<h3 class="config_section">[[DegreeDays]]</h3>
|
|
<p class="config_important">
|
|
heating_base <br /> cooling_base
|
|
</p>
|
|
<p>Set to the base temperature for calculating heating and
|
|
cooling degree-days, along with the unit to be used. Examples:</p>
|
|
<pre class="tty">heating_base = 65.0, degree_F
|
|
cooling_base = 20.0, degree_C</pre>
|
|
<h3 class="config_section" id="trend">[[Trend]]</h3>
|
|
<p class="config_option">time_delta</p>
|
|
<p>Set to the time difference over which you want trends to be
|
|
calculated. The default is 3 hours.</p>
|
|
<p class="config_option">time_grace</p>
|
|
<p>
|
|
When searching for a previous record to be used in calculating a
|
|
trend, a record within this amount of <span class="code">time_delta</span>
|
|
will be accepted. Default is 300 seconds.
|
|
</p>
|
|
<h2 class="config_section">[Labels]</h2>
|
|
<p>This section sets the various labels to use.</p>
|
|
<p class="config_option">hemispheres</p>
|
|
<p>
|
|
Comma separated list for the labels to be used for the four
|
|
hemispheres. The default is "<span class="code">N, S, E,
|
|
W</span>".
|
|
</p>
|
|
<p class="config_option">latlon_formats</p>
|
|
<p>Comma separated list for the formatting to be used when
|
|
converting latitude and longitude to strings. There should be
|
|
three elements:</p>
|
|
<ol>
|
|
<li>The format to be used for whole degrees of latitude</li>
|
|
<li>The format to be used for whole degrees of longitude</li>
|
|
<li>The format to be used for minutes.</li>
|
|
</ol>
|
|
<p>This allows you to decide whether or not you want leading
|
|
zeroes. The default includes leading zeroes and is "%02d",
|
|
"%03d", "%05.2f"</p>
|
|
<h3 class="config_section">[[Generic]]</h3>
|
|
<p>This sub-section specifies default labels to be used for
|
|
each SQL type. For example, options</p>
|
|
<pre class="tty">inTemp = Temperature inside the house
|
|
outTemp = Outside Temperature</pre>
|
|
<p>
|
|
would cause the given labels to be used for plots involving SQL
|
|
types <span class="code">inTemp</span> and <span class="code">outTemp</span>.
|
|
</p>
|
|
<h2 class="config_section">[Almanac]</h2>
|
|
<p>This section controls what text to use for the almanac. It
|
|
consists of only one entry</p>
|
|
<p class="config_option">moon_phases</p>
|
|
<p>
|
|
This option is a comma separated list of labels to be used for
|
|
the eight phases of the moon. Default is "<span class="code">New,
|
|
Waxing crescent, First quarter, Waxing gibbous, Full, Waning
|
|
gibbous, Last quarter, Waning crescent</span>".
|
|
</p>
|
|
|
|
<h2 class="config_section">[CheetahGenerator]</h2>
|
|
<p>
|
|
This section is used by generator <span class="code">weewx.cheetahgenerator.CheetahGenerator</span>
|
|
and controls text generation from templates, specifically which
|
|
files are to be produced from which template.
|
|
</p>
|
|
<p>
|
|
Before V2.5, this section was called <span class="code">[FileGenerator]</span>.
|
|
Older versions and names are 100% backwards compatible.
|
|
</p>
|
|
<h3>Overview of file generation</h3>
|
|
<p>
|
|
Files are generated from templates, and each template is
|
|
identified by the <span class="config_option">template</span>
|
|
parameter.
|
|
</p>
|
|
<p>
|
|
Each template file is named something like <span class="code"><em>D/F.E.tmpl</em></span>,
|
|
where <span class="code">D</span> is the (optional) directory
|
|
the template sits in and will also be the directory the results
|
|
will be put in, and <span class="code"> F.E</span> is the
|
|
generated file name. So, given a template file with name <span
|
|
class="code"> Acme/index.html.tmpl</span>, the results will be
|
|
put in <span class="symcode"> $HTML_ROOT</span><span
|
|
class="code">/Acme/index.html</span>.
|
|
</p>
|
|
<p>The configuration for a group of templates will look
|
|
something like this:</p>
|
|
<pre class="tty">[CheetahGenerator]
|
|
[[index]]
|
|
template = index.html.tmpl
|
|
[[textfile]]
|
|
template = filename.txt.tmpl
|
|
[[xmlfile]]
|
|
template = filename.xml.tmpl</pre>
|
|
<p>
|
|
There can be only one <span class="config_option">template</span>
|
|
in each block. In most cases, the block name does not matter -
|
|
it is used only to isolate each template. However, there are two
|
|
block names that have speacial meaning: SummaryByMonth and
|
|
SummaryByYear. These are described below.
|
|
</p>
|
|
<p>The file generator runs on each new archive record. In a
|
|
default weewx installation, that would be every 5 minutes.</p>
|
|
<p>
|
|
Cheetah processes each template to generate a file. Cheetah
|
|
follows any logic defined by directives such as <span
|
|
class="code">for</span> or <span class="code">if ...
|
|
else</span>, and it replaces variables such as <span class="code">$Extras.radar_url</span>
|
|
or <span class="code">$current.outTemp.max</span>.
|
|
</p>
|
|
<p>Variables are defined by objects in weewx. Some variables
|
|
are static, others are linked to data in databases. The list of
|
|
variables can be extended.</p>
|
|
|
|
<h3>File generation options</h3>
|
|
<p class="config_option">search_list</p>
|
|
<p>
|
|
This is the list of search list objects that will be scanned by
|
|
the template engine, looking for tags. See the section <em>
|
|
<a href="#defining_new_tags">Defining new tags</a>
|
|
</em> and the <a
|
|
href="http://cheetahtemplate.org/docs/users_guide_html/users_guide.html">
|
|
Cheetah documentation</a> for details on search lists. If no <span
|
|
class="config_option"> search_list</span> is specified, a
|
|
default list will be used. The default list is:
|
|
</p>
|
|
<pre class="tty">search_list = weewx.cheetahgenerator.Almanac, weewx.cheetahgenerator.Station, weewx.cheetahgenerator.Stats, weewx.cheetahgenerator.UnitInfo, weewx.cheetahgenerator.Extras, weewx.cheetahgenerator.Current</pre>
|
|
<p class="config_option">search_list_extensions</p>
|
|
<p>
|
|
This defines one or more search list objects that will be
|
|
appended to the <span class="config_option">search_list</span>.
|
|
For example, the following adds alltime and forecast variables
|
|
to the search list.
|
|
</p>
|
|
<pre class="tty">search_list_extensions = examples.xsearch.MyXSearch, user.forecast.ForecastVariables</pre>
|
|
<p class="config_option">encoding</p>
|
|
<p>This option controls which encoding is to be used for the
|
|
generated output. The encoding can be specified for individual
|
|
files. There are 3 possible choices:</p>
|
|
<table class="indent" style="width: 90%">
|
|
<tbody>
|
|
<tr>
|
|
<td><strong>Encoding</strong></td>
|
|
<td><strong>Comments</strong></td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">html_entities</td>
|
|
<td>Non 7-bit characters will be represented as HTML
|
|
entities (<em>e.g.</em>, the degree sign will be
|
|
represented as <span class="code">&#176;</span>)
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">utf8</td>
|
|
<td>Non 7-bit characters will be represented in UTF-8.</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">strict_ascii</td>
|
|
<td>Non 7-bit characters will be ignored.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p>
|
|
The encoding <span class="code">html_entities</span> is the
|
|
default.
|
|
</p>
|
|
<p class="config_option">template</p>
|
|
<p>
|
|
The name of a template file. A template filename must end with <span
|
|
class="code">.tmpl</span>. Filenames are case-sensitive. If
|
|
the template filename has the letters <span class="code">YYYY</span>
|
|
or <span class="code">MM</span> in its name, these will be
|
|
substituted for the year and month, respectively. So, a template
|
|
with the name <span class="code">summary-YYYY-MM.html.tmpl</span>
|
|
would have name <span class="code">summary-2010-03.html</span>
|
|
for the month of March, 2010.
|
|
</p>
|
|
<p class="config_option">stale_age</p>
|
|
<p>File staleness age, in seconds. If the file is older than
|
|
this age it will be generated from the template. If no stale_age
|
|
is specified the file will be generated each time the generator
|
|
runs.</p>
|
|
<p class="config_option">[[SummaryByMonth]]</p>
|
|
<p>
|
|
The <span class="code">SummaryByMonth</span> section defines
|
|
some special behavior. Each template in this section will be
|
|
used multiple times, each time with a different per-month
|
|
timespan. Be sure to include <span class="code"> YYYY</span> and
|
|
<span class="code">MM</span> in the filename of any template in
|
|
this section.
|
|
</p>
|
|
<p class="config_option">[[SummaryByYear]]</p>
|
|
<p>
|
|
The <span class="code">SummaryByYear</span> section defines some
|
|
special behavior. Each template in this section will be used
|
|
multiple times, each time with a different per-year timespan. Be
|
|
sure to include <span class="code"> YYYY</span> in the filename
|
|
of any template in this section.
|
|
</p>
|
|
|
|
<h3>Customizing file generation</h3>
|
|
<p>The best way to customization file generation is to make a
|
|
copy of a working report/skin, then make incremental changes.</p>
|
|
<p>
|
|
When there is an error during template generation, the error
|
|
will show up in the log file. Many errors are obvious - Cheetah
|
|
will display a line number and list the template file in which
|
|
the error occurred. In some cases the error reporting is rather
|
|
obscure. So make small changes and tests often. Use <span
|
|
class="code">wee_report</span> to test modifications to the
|
|
generator configuration and/or the template contents.
|
|
</p>
|
|
|
|
<h3>An Example: the Standard skin</h3>
|
|
<p>
|
|
Here is the <span class="code">[CheetahGenerator]</span> section
|
|
from the Standard <span class="code">skin.conf</span>
|
|
</p>
|
|
|
|
<pre class="tty">[CheetahGenerator]
|
|
# This section is used by the generator CheetahGenerator, and specifies
|
|
# which files are to be generated from which template.
|
|
|
|
encoding = html_entities
|
|
|
|
[[SummaryByMonth]]
|
|
# Reports that summarize "by month"
|
|
[[[NOAA_month]]]
|
|
encoding = strict_ascii
|
|
template = NOAA/NOAA-YYYY-MM.txt.tmpl
|
|
|
|
[[SummaryByYear]]
|
|
# Reports that summarize "by year"
|
|
[[[NOAA_year]]]
|
|
encoding = strict_ascii
|
|
template = NOAA/NOAA-YYYY.txt.tmpl
|
|
|
|
[[ToDate]]
|
|
# Reports that show statistics "to date", such as day-to-date,
|
|
# week-to-date, month-to-date, etc.
|
|
[[[day]]]
|
|
template = index.html.tmpl
|
|
|
|
[[[week]]]
|
|
template = week.html.tmpl
|
|
|
|
[[[month]]]
|
|
template = month.html.tmpl
|
|
|
|
[[[year]]]
|
|
template = year.html.tmpl
|
|
|
|
[[[RSS]]]
|
|
template = RSS/weewx_rss.xml.tmpl
|
|
|
|
[[[Mobile]]]
|
|
template = mobile.html.tmpl</pre>
|
|
|
|
<p>The Standard skin contains three different kinds of
|
|
generated output:</p>
|
|
<ol>
|
|
<li>Summary by Month. The Standard skin uses <span
|
|
class="code">SummaryByMonth</span> to produce NOAA summaries,
|
|
one for each month, as a simple text file.
|
|
</li>
|
|
<li>Summary by Year. The Standard skin uses <span
|
|
class="code">SummaryByYear</span> to produce NOAA summaries,
|
|
one for each year, as a simple text file.
|
|
</li>
|
|
<li>Summary "To Date". The Standard skin produce reports
|
|
for the day, week, month, and year-to-date observations. These
|
|
files are HTML. The first, the daily summary (output filename
|
|
is <span class="code">index.html</span>), includes a drop-down
|
|
list that displays the NOAA month and yearly summaries.
|
|
</li>
|
|
</ol>
|
|
<p>
|
|
The encoding for text files is <span class="code">strict_ansii</span>,
|
|
whereas the encoding for html files is <span class="code">html_entities</span>.
|
|
In the Standard skin this is specified by declaring <span
|
|
class="code">encoding = html_entities</span> at the top level
|
|
of <span class="code"> [CheetahGenerator]</span> then <span
|
|
class="code">encoding = strict_ansii</span> for each text
|
|
file.
|
|
</p>
|
|
<p>
|
|
Other than <span class="code">SummaryByMonth</span> and <span
|
|
class="code">SummaryByYear</span>, the section names are
|
|
arbitrary. <span class="code">ToDate</span> could just as well
|
|
have been called <span class="code">files_to_date</span>, and
|
|
the sections <span class="code">day</span>, <span class="code">week</span>,
|
|
and <span class="code">month</span> could just as well have been
|
|
called <span class="code">tom</span>, <span class="code">dick</span>,
|
|
and <span class="code">harry</span>.
|
|
</p>
|
|
|
|
<h2 class="config_section">[CopyGenerator]</h2>
|
|
<p>
|
|
This section is used by generator <span class="code">
|
|
weewx.reportengine.CopyGenerator</span> and controls which files are
|
|
to be copied over from the skin directory to the destination
|
|
directory. Think of it as "file generation," except that rather
|
|
than going through the template engine, the files are simply
|
|
copied over.
|
|
</p>
|
|
|
|
<h3>Copy generator options</h3>
|
|
<p class="config_option">copy_once</p>
|
|
<p>This option controls which files get copied over on the
|
|
first invocation of the report engine service. Typically, this
|
|
is things such as style sheets or background GIFs. Wildcards can
|
|
be used.</p>
|
|
<p class="config_option">copy_always</p>
|
|
<p>This is a list of files that should be copied on every
|
|
invocation. Wildcards can be used.</p>
|
|
|
|
<h3>An Example: the Standard skin</h3>
|
|
<p>
|
|
Here is the <span class="code">[CopyGenerator]</span> section
|
|
from the Standard <span class="code">skin.conf</span>
|
|
</p>
|
|
<pre class="tty">[CopyGenerator]
|
|
# This section is used by the generator CopyGenerator
|
|
|
|
# List of files to be copied only the first time the generator runs
|
|
copy_once = backgrounds/*, weewx.css, mobile.css, favicon.ico
|
|
|
|
# List of files to be copied each time the generator runs
|
|
# copy_always = </pre>
|
|
<p>The Standard skin includes some background images, CSS
|
|
files, and icons that need to be copied once. There are no files
|
|
that need to be copied each time the generator runs.</p>
|
|
|
|
<h2 class="config_section">[ImageGenerator]</h2>
|
|
<p>
|
|
This section is used by generator <span class="code">
|
|
weewx.reportengine.ImageGenerator</span> and controls which images
|
|
(plots) get generated and with which options. While complicated,
|
|
it is extremely flexible and powerful.
|
|
</p>
|
|
<h3>Time periods</h3>
|
|
<p>
|
|
The section consists of one or more sub-sections, one for each
|
|
time period (day, week, month, and year). These sub-sections
|
|
define the nature of aggregation and plot types for the time
|
|
period. For example, here is a typical set of options for
|
|
sub-section <span class="code">[[month_images]]</span>,
|
|
controlling how images that cover a month period are generated:
|
|
</p>
|
|
<pre class="tty">[[month_images]]
|
|
x_label_format = %d
|
|
bottom_label_format = %x %X
|
|
time_length = 2592000 # == 30 days
|
|
aggregate_type = avg
|
|
aggregate_interval = 10800 # == 3 hours</pre>
|
|
<p>Here's a description of these options.</p>
|
|
<p>
|
|
The option <span class="code">x_label_format</span> gives a <a
|
|
href="http://docs.python.org/library/datetime.html#strftime-behavior">
|
|
strftime()</a> type format for the x-axis. In this example, it
|
|
will only show the day of the month (format option "<span
|
|
class="code">%d</span>").
|
|
</p>
|
|
<p>
|
|
The <span class="code">bottom_label_format</span> is the format
|
|
used for the time stamp at the bottom of the image. In this
|
|
example, it has been specified as <span class="code">"%x %X"</span>,
|
|
which will use date and time formatting appropriate for your
|
|
locale, <a href="#Environment_variable_LANG">provided you
|
|
set environment variable LANG first</a>. For example, in the U.S.,
|
|
it will show the time as <span class="code">10/25/09 05:20:00 PM</span>,
|
|
while in Europe it might show <span class="code">25/10/09
|
|
17:20:00</span>.
|
|
</p>
|
|
<p>
|
|
The option <span class="code">time_length = 2592000</span>
|
|
says that the plot will cover a nominal 30 days.
|
|
</p>
|
|
<p>
|
|
The option <span class="code">aggregate_type = avg</span>
|
|
says that each point in the plot will be the average over a time
|
|
period. The option <span class="code">aggregate_interval = 10800</span>
|
|
says that time period will be 3 hours.
|
|
</p>
|
|
<h3>Image files</h3>
|
|
<p>
|
|
Within each sub-section is another nesting, one for each image
|
|
to be generated. The title of each sub-sub-section is the
|
|
filename to be used for the image. Finally, at one additional
|
|
nesting level (!) are the logical names of all the line types to
|
|
be drawn in the image. Values specified in the level above can
|
|
be overridden. For example, here is a typical set of options for
|
|
sub-sub-section <span class="code"> [[[monthrain]]]</span>:
|
|
</p>
|
|
<pre class="tty">[[[monthrain]]]
|
|
plot_type = bar
|
|
yscale = None, None, 0.02
|
|
[[[[rain]]]]
|
|
aggregate_type = sum
|
|
aggregate_interval = 86400
|
|
label = Rain (daily avg)</pre>
|
|
<p>
|
|
This will generate an image file with name <span class="code">
|
|
monthrain.png</span>. It will be a bar plot. Option <span
|
|
class="code"> yscale</span> controls the y-axis scaling — if
|
|
left out, the scale will automatically be chosen. However, in
|
|
this example we are choosing to exercise some degree of control
|
|
by specifying values explicitly. The option takes a 3-way tuple
|
|
(<span class="code">ylow</span>, <span class="code">
|
|
yhigh</span>, <span class="code">min_interval</span>), where <span
|
|
class="code">ylow</span> and <span class="code">yhigh</span>
|
|
are the minimum and maximum y-axis values, respectively, and <span
|
|
class="code">min_interval</span> is the minimum tick interval.
|
|
If set to '<span class="code">None</span>', the corresponding
|
|
value will be automatically chosen. So, in this example, the
|
|
setting
|
|
</p>
|
|
<pre class="tty">yscale = None, None, 0.02</pre>
|
|
<p>
|
|
will cause <span class="code">weewx</span> to pick sensible y
|
|
minimum and maximum values, but require that the tick increment
|
|
(<span class="code">min_interval</span>) be at least 0.02.
|
|
</p>
|
|
<p>
|
|
Continuing on with the example above, there will be only one
|
|
plot "line" (it will actually be a series of bars) and it will
|
|
have logical name "<span class="code">rain</span>". Because we
|
|
have not said otherwise, the SQL data type to be used for this
|
|
line will be the same as its logical name, that is, <span
|
|
class="code">rain</span>, but this can be overridden (see
|
|
below). The aggregation type will be summing (overriding the
|
|
averaging specified in sub-section <span class="code">[[month_images]]</span>),
|
|
so you get the total rain over the aggregate period (rather than
|
|
the average) over an aggregation interval of 86,400 seconds (one
|
|
day). The plot line will be titled with the indicated label ('<span
|
|
class="code">Rain (daily avg)</span>')
|
|
</p>
|
|
<p>
|
|
If there is a time gap in the data, the options <span
|
|
class="code"> line_gap_fraction</span> and <span class="code">bar_gap_fraction</span>
|
|
control how it will be drawn. The former, <span class="code">line_gap_fraction</span>,
|
|
is used for line graphs, the latter, <span class="code">bar_gap_fraction</span>,
|
|
for bar graphs. Here's what the resultant plots look like
|
|
without and with this option being specified:
|
|
</p>
|
|
<div class="center" style="width: 80%; margin: 0 auto;">
|
|
<div style="float: left">
|
|
<img width="334" height="197" src="day-gap-not-shown.png"
|
|
alt="Gap not shown" />
|
|
<p class="caption">
|
|
No <span class="code">line_gap_fraction</span> specified
|
|
</p>
|
|
</div>
|
|
<div>
|
|
<img width="334" height="197" src="day-gap-showing.png"
|
|
alt="Gap showing" />
|
|
<p class="caption">
|
|
With <span class="code">line_gap_fraction=0.01</span>
|
|
</p>
|
|
</div>
|
|
</div>
|
|
<div style="clear: both"></div>
|
|
<h3>Including more than one SQL type in a plot</h3>
|
|
<p>More than one SQL type can be included in a plot. For
|
|
example, here is how to generate a plot with the week's outside
|
|
temperature as well as dewpoint:</p>
|
|
<pre class="tty">[[[monthtempdew]]]
|
|
[[[[outTemp]]]]
|
|
[[[[dewpoint]]]]</pre>
|
|
<p>
|
|
This would create an image in file <span class="code">monthtempdew.png</span>
|
|
that includes a line plot of both outside temperature and
|
|
dewpoint.
|
|
</p>
|
|
<h3>Including the same SQL type more than once in a plot</h3>
|
|
<p>
|
|
Another example. Say you want a plot of the day's temperature,
|
|
overlaid with hourly averages. Here, you are using the same data
|
|
type ('<span class="code">outTemp</span>') for both plot lines,
|
|
the first with averages, the second without. If you do the
|
|
obvious it won't work:
|
|
</p>
|
|
<pre class="tty">## WRONG ##
|
|
[[[daytemp_with_avg]]]
|
|
[[[[outTemp]]]]
|
|
aggregate_type = avg
|
|
aggregate_interval = 3600
|
|
[[[[outTemp]]]] # OOPS! The same section name appears more than once!</pre>
|
|
<p>
|
|
The option parser does not allow the same section name ('<span
|
|
class="code">outTemp</span>' in this case) to appear more than
|
|
once at a given level in the configuration file, so an error
|
|
will be declared (technical reason: formally, the sections are
|
|
an unordered dictionary). If you wish for the same SQL type to
|
|
appear more than once in a plot then there is a trick you must
|
|
know: use option <span class="code">data_type</span>. This will
|
|
override the default action that the logical line name is used
|
|
for the SQL type. So, our example would look like this:
|
|
</p>
|
|
<pre class="tty">[[[daytemp_with_avg]]]
|
|
[[[[a_logical_name]]]]
|
|
data_type = outTemp
|
|
aggregate_type = avg
|
|
aggregate_interval = 3600
|
|
label = Avg. Temp.
|
|
[[[[outTemp]]]]</pre>
|
|
<p>
|
|
Here, the first logical line has been given the name "<span
|
|
class="code">a_logical_name</span>" to distinguish it from the
|
|
second line "<span class="code">outTemp</span>". We have
|
|
specified that the first line will use data type <span
|
|
class="code"> outTemp</span> and that it will use averaging
|
|
over a one hour period. The second also uses <span class="code">outTemp</span>,
|
|
but will not use averaging.
|
|
</p>
|
|
<p>The result is a nice plot of the day's temperature,
|
|
overlaid with a 3-hour smoothed average:</p>
|
|
<p class="center">
|
|
<img width="300" height="180"
|
|
alt="Daytime temperature with running average"
|
|
src="daytemp_with_avg.png" />
|
|
</p>
|
|
<p>One more example. This one shows daily high and low
|
|
temperatures for a year:</p>
|
|
<pre class="tty">[[year_images]]
|
|
...
|
|
[[[yearhilow]]]
|
|
[[[[hi]]]]
|
|
data_type = outTemp
|
|
aggregate_type = max
|
|
label = High
|
|
[[[[low]]]]
|
|
date_type = outTemp
|
|
aggregate_type = min
|
|
label = Low Temperature</pre>
|
|
<p>
|
|
This results in the plot <span class="code">yearhilow.png</span>:
|
|
</p>
|
|
<p class="center">
|
|
<img width="300" height="180" alt="Daily highs and lows"
|
|
src="yearhilow.png" />
|
|
</p>
|
|
<h3>Progressive vector plots</h3>
|
|
<p>
|
|
<span class="code">Weewx</span> can produce progressive vector
|
|
plots as well as the more conventional x-y plots. To produce
|
|
these, use plot type '<span class="code">vector</span>'. You
|
|
need a vector type to produce this kind of plot. There are two:
|
|
'<span class="code">windvec</span>', and '<span class="code">windgustvec</span>'.
|
|
While they do not actually appear in the SQL database, <span
|
|
class="code">weewx</span> understands that they represent
|
|
special vector-types. The first, '<span class="code">windvec</span>',
|
|
represents the average wind in an archive period, the second, '<span
|
|
class="code">windgustvec</span>' the max wind in an archive
|
|
period. Here's how to produce a progressive vector for one week
|
|
that shows the hourly biggest wind gusts, along with hourly
|
|
averages:
|
|
</p>
|
|
<pre class="tty">[[[weekgustoverlay]]]
|
|
aggregate_interval = 3600
|
|
[[[[windvec]]]]
|
|
label = Hourly Wind
|
|
plot_type = vector
|
|
aggregate_type = avg
|
|
[[[[windgustvec]]]]
|
|
label = Gust Wind
|
|
plot_type = vector
|
|
aggregate_type = max</pre>
|
|
<p>
|
|
This will produce an image file with name <span class="code">
|
|
weekgustoverlay.png</span>. It will consist of two progressive vector
|
|
plots, both using hourly aggregation (3,600 seconds). For the
|
|
first set of vectors, the hourly average will be used. In the
|
|
second, the max of the gusts will be used:
|
|
</p>
|
|
<p class="center">
|
|
<img width="300" height="180"
|
|
alt="hourly average wind vector overlaid with gust vectors"
|
|
src="weekgustoverlay.png" />
|
|
</p>
|
|
<p>
|
|
By default, the sticks in the progressive wind plots point
|
|
towards the wind source. That is, the stick for a wind from the
|
|
west will point left. If you have a chronic wind direction (as I
|
|
do), you may want to rotate the default direction so that all
|
|
the vectors do not line up over the x-axis, overlaying each
|
|
other. Do this by using option <span class="code">
|
|
vector_rotate</span>. For example, with my chronic westerlies, I set
|
|
<span class="code"> vector_rotate</span> to 90.0 for the plot
|
|
above, so winds out of the west point straight up.
|
|
</p>
|
|
<p>
|
|
If you use this kind of plot (the out-of-the-box version of <span
|
|
class="code"> weewx</span> includes daily, weekly, monthly,
|
|
and yearly progressive wind plots), a small compass rose will be
|
|
put in the lower-left corner of the image to show the
|
|
orientation of North.
|
|
</p>
|
|
<h3>Overriding values</h3>
|
|
<p>
|
|
Remember that values at any level can override values specified
|
|
at a higher level. For example, say you want to generate the
|
|
standard plots, but for a few key observation types such as
|
|
barometer, you want to also generate some oversized plots to
|
|
give you extra detail, perhaps for an HTML popup. The standard <span
|
|
class="code">weewx.conf</span> file specifies plot size of
|
|
300x180 pixels, which will be used for all plots unless
|
|
overridden:
|
|
</p>
|
|
<pre class="tty">[Images]
|
|
...
|
|
image_width = 300
|
|
image_height = 180</pre>
|
|
<p>
|
|
The standard plot of barometric pressure will appear in <span
|
|
class="code"> daybarometer.png</span>:
|
|
</p>
|
|
<pre class="tty">[[[daybarometer]]]
|
|
[[[[barometer]]]] </pre>
|
|
<p>
|
|
We now add our special plot of barometric pressure, but specify
|
|
a larger image size. This image will be put in file <span
|
|
class="code"> daybarometer_big.png</span>.
|
|
</p>
|
|
<pre class="tty">[[[daybarometer_big]]]
|
|
image_width = 600
|
|
image_height = 360
|
|
[[[[barometer]]]]</pre>
|
|
|
|
<h3>An Example: the Standard skin</h3>
|
|
<p>
|
|
Here is part of the <span class="code">[ImageGenerator]</span>
|
|
section from the Standard <span class="code">skin.conf</span>
|
|
</p>
|
|
<pre class="tty">[ImageGenerator]
|
|
image_width = 300
|
|
image_height = 180
|
|
...
|
|
plot_type = line # default to line, can be overridden at any level
|
|
aggregate_type = none # default to none, can be overridden at any level
|
|
width = 1 # default to skinny lines
|
|
time_length = 86400 # == 24 hours
|
|
|
|
[[day_images]]
|
|
x_label_format = %H:%M
|
|
bottom_label_format = %x %X
|
|
time_length = 97200 # == 27 hours
|
|
|
|
[[[daybarometer]]]
|
|
[[[[barometer]]]]
|
|
|
|
[[[dayrain]]]
|
|
# Make sure the y-axis increment is at least 0.02 for the rain plot
|
|
yscale = None, None, 0.02
|
|
plot_type = bar
|
|
[[[[rain]]]]
|
|
aggregate_type = sum
|
|
aggregate_interval = 3600
|
|
label = Rain (hourly total)
|
|
|
|
[[[daywinddir]]]
|
|
# Hardwire in the y-axis scale for wind direction
|
|
yscale = 0.0, 360.0, 45.0
|
|
[[[[windDir]]]]
|
|
|
|
[[[daywindvec]]]
|
|
[[[[windvec]]]]
|
|
plot_type = vector
|
|
|
|
[[[dayradiation]]]
|
|
[[[[radiation]]]]
|
|
|
|
[[week_images]]
|
|
x_label_format = %d
|
|
bottom_label_format = %x %X
|
|
time_length = 604800 # == 7 days
|
|
aggregate_type = avg
|
|
aggregate_interval = 3600
|
|
|
|
[[[weekbarometer]]]
|
|
[[[[barometer]]]]
|
|
|
|
[[[weekrain]]]
|
|
yscale = None, None, 0.02
|
|
plot_type = bar
|
|
[[[[rain]]]]
|
|
aggregate_type = sum
|
|
aggregate_interval = 86400
|
|
label = Rain (daily total)
|
|
|
|
[[[weekwinddir]]]
|
|
yscale = 0.0, 360.0, 45.0
|
|
[[[[windDir]]]]
|
|
|
|
[[[weekwindvec]]]
|
|
[[[[windvec]]]]
|
|
plot_type = vector
|
|
|
|
[[[weekradiation]]]
|
|
[[[[radiation]]]]
|
|
|
|
...
|
|
</pre>
|
|
<p>The Standard skin defines many different types of plots.
|
|
Note that each plot will be created only if there are data that
|
|
match the definition. For example, if a station does not produce
|
|
radiation data, no radiation images will be generated. This
|
|
means that a single report can be used for many different
|
|
stations, even if the stations have different sensors or
|
|
capabilities.</p>
|
|
|
|
<h2 class="config_section" id="generators">[Generators]</h2>
|
|
<p>This section defines the generators that should be run as
|
|
well as options for specific generators.</p>
|
|
|
|
<h3>Generator options</h3>
|
|
<p class="config_option">generator_list</p>
|
|
<p>This option controls which generators get run for this
|
|
skin. It is a comma separated list. The generators will be run
|
|
in this order.</p>
|
|
|
|
<h3>An Example: the Standard skin</h3>
|
|
<p>
|
|
Here is the <span class="code">[Generators]</span> section from
|
|
the Standard <span class="code">skin.conf</span>
|
|
</p>
|
|
<pre class="tty">[Generators]
|
|
generator_list = weewx.cheetahgenerator.CheetahGenerator, weewx.imagegenerator.ImageGenerator, weewx.reportengine.CopyGenerator</pre>
|
|
<p>The Standard skin uses three generators: CheetahGenerator,
|
|
ImageGenerator, and CopyGenerator.</p>
|
|
|
|
<h1 id="localization">Localization</h1>
|
|
<p>Weewx has been designed to make localization fairly
|
|
straightforward. What follows is a guide to localizing to a
|
|
non-English language and/or locale.</p>
|
|
<h2>Translate the templates</h2>
|
|
<p>
|
|
First, you will need to go through the templates and translate
|
|
to your target language. Obvious text strings such as "<span
|
|
class="code">Current Weather Conditions</span>" will need to
|
|
be translated.
|
|
</p>
|
|
<h2>Modify skin.conf to reflect local conventions</h2>
|
|
<p>
|
|
Next, you will need to go through <span class="code">skin.conf</span>
|
|
and modify options to follow local conventions. This includes
|
|
dates and labels.
|
|
</p>
|
|
<h3>Dates</h3>
|
|
<p>
|
|
The date and time formats used in the default distribution of <span
|
|
class="code">weewx</span> are locale independent, so they
|
|
should be OK.
|
|
</p>
|
|
<pre class="tty"> [[TimeFormats]]
|
|
#
|
|
# This section sets the string format to be used for
|
|
# each time scale.
|
|
#
|
|
day = %X
|
|
week = %X (%A)
|
|
month = %x %X
|
|
year = %x %X
|
|
rainyear = %x %X
|
|
current = %x %X
|
|
ephem_day = %X
|
|
ephem_year = %x %X</pre>
|
|
<p>The specifiers "%X" and "%x" say to format the time and
|
|
date, respectively, in a way that is suitable for your locale.</p>
|
|
<p>The bottom label format used in plots should also be OK:</p>
|
|
<pre class="tty">bottom_label_format = %x %X</pre>
|
|
<h3>Labels</h3>
|
|
<p>There are several almanac labels that may need to be
|
|
changed. These include:</p>
|
|
<pre class="tty">hemisphere = N, S, E, W</pre>
|
|
<p>and</p>
|
|
<pre class="tty">moon_phases = New, Waxing crescent, First quarter, Waxing gibbous, Full, Waning gibbous, Last quarter, Waning crescent</pre>
|
|
<p>Most of the unit labels either follow ISO conventions, or
|
|
are unlikely to be used outside English speaking countries (an
|
|
example would be "foot"). But, there are two exceptions:</p>
|
|
<pre class="tty">hour = " hrs"
|
|
second = " secs"</pre>
|
|
<p>You will also have to change the generic labels given to
|
|
your weather observations:</p>
|
|
<pre class="tty">barometer = Barometer
|
|
dewpoint = Dew Point
|
|
heatindex = Heat Index
|
|
inHumidity = Inside Humidity
|
|
inTemp = Inside Temperature
|
|
outHumidity = Outside Humidity
|
|
outTemp = Outside Temperature
|
|
radiation = Radiation
|
|
rain = Rain
|
|
rainRate = Rain Rate
|
|
rxCheckPercent = ISS Signal Quality
|
|
windDir = Wind Direction
|
|
windGust = Gust Speed
|
|
windGustDir = Gust Direction
|
|
windSpeed = Wind Speed
|
|
windchill = Wind Chill
|
|
windgustvec = Gust Vector
|
|
windvec = Wind Vector
|
|
extraTemp1 = Pond Temperature</pre>
|
|
<h2 id="Environment_variable_LANG">
|
|
Environment variable <span class="code"> LANG</span>
|
|
</h2>
|
|
<p>
|
|
Finally, you will need to set the environment variable <span
|
|
class="code"> LANG</span> to reflect your locale. For example,
|
|
assuming you set
|
|
</p>
|
|
<pre class="tty">$ export LANG=es_ES.UTF-8</pre>
|
|
<p>
|
|
before running <span class="code">weewx</span>, then the local
|
|
Spanish names for days of the week and months of the year will
|
|
be used. The decimal point for numbers will also be modified
|
|
appropriately.
|
|
</p>
|
|
<h1 id="service_engine">
|
|
Customizing the <span class="code">weewx</span> service engine
|
|
</h1>
|
|
<p>This is an advanced topic intended for those who wish to
|
|
try their hand at extending the internal engine in weewx. You
|
|
should have a passing familiarity with Python or, at least, be
|
|
willing to learn it.</p>
|
|
<p>
|
|
<em>Please note that the service engine is likely to change
|
|
in future versions! </em>
|
|
</p>
|
|
<p>
|
|
At a high level, <span class="code">weewx</span> consists of an
|
|
<em> engine</em> that is responsible for managing a set of <em>services</em>.
|
|
A service consists of a Python class which binds its member
|
|
functions to various <em> events</em>. The engine arranges to
|
|
have the bound member function called when a specific event
|
|
happens, such as a new LOOP packet arriving.
|
|
</p>
|
|
<p>To customize, you can</p>
|
|
<ul>
|
|
<li>Customize a service</li>
|
|
<li>Add a service</li>
|
|
</ul>
|
|
<p>
|
|
The default install of <span class="code">weewx</span> includes
|
|
the following services, shown in the order they are normally
|
|
run:
|
|
</p>
|
|
<table class="indent" style="width: 80%">
|
|
<tbody>
|
|
<tr>
|
|
<td><strong>Service</strong></td>
|
|
<td><strong>Function</strong></td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">weewx.wxengine.StdConvert</td>
|
|
<td>Converts the units of the input to a target unit
|
|
system (such as US or Metric).</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">weewx.wxengine.StdCalibrate</td>
|
|
<td>Adjust new LOOP and archive packets using
|
|
calibration expressions.</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">weewx.wxengine.StdQC</td>
|
|
<td>Check that observation values fall within a
|
|
specified range.</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">weewx.wxengine.StdArchive</td>
|
|
<td>Archive any new data to the SQL databases.</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">weewx.wxengine.StdTimeSynch</td>
|
|
<td>Arrange to have the clock on the console
|
|
synchronized at regular intervals.</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">weewx.wxengine.StdPrint</td>
|
|
<td>Print out new LOOP and archive packets on the
|
|
console.</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">weewx.wxengine.StdRESTful</td>
|
|
<td>Start a thread to manage <a
|
|
href="http://en.wikipedia.org/wiki/Representational_State_Transfer">
|
|
RESTful</a> (simple stateless client-server protocols)
|
|
connections; such as those used by the Weather Underground
|
|
or PWSweather.
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">weewx.wxengine.StdReport</td>
|
|
<td>Launch a new thread to do report processing after a
|
|
new archive record arrives. Reports do things such as
|
|
generate HTML files, generate images, or FTP/rsync files
|
|
to a web server. New reports can be added easily by the
|
|
user.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<h2>Customizing a Service</h2>
|
|
<p>
|
|
The service <span class="code">weewx.wxengine.StdPrint</span>
|
|
prints out new LOOP and archive packets to the console when they
|
|
arrive. By default, it prints out the entire record, which
|
|
generally includes a lot of possibly distracting information and
|
|
can be rather messy. Suppose you do not like this, and want it
|
|
to print out only the time, barometer reading, and the outside
|
|
temperature whenever a new LOOP packet arrives. This could be
|
|
done by subclassing the default print service <span class="code">
|
|
StdPrint</span> and overriding member function <span class="code">new_loop_packet()</span>.
|
|
</p>
|
|
<p>
|
|
Create the file <span class="symcode">$BIN_ROOT</span><span
|
|
class="code">/user/myprint.py</span>:
|
|
</p>
|
|
<pre class="tty">from weewx.wxengine import StdPrint
|
|
from weeutil.weeutil import timestamp_to_string
|
|
|
|
class MyPrint(StdPrint):
|
|
|
|
# Override the default new_loop_packet member function:
|
|
def new_loop_packet(self, event):
|
|
packet = event.packet
|
|
print "LOOP: ", timestamp_to_string(packet['dateTime']),
|
|
"BAR=", packet.get('barometer', 'N/A'),
|
|
"TEMP=", packet.get('outTemp', 'N/A')</pre>
|
|
<p>
|
|
This service substitutes a new implementation for the member
|
|
function <span class="code">new_loop_packet</span>. This
|
|
implementation prints out the time, then the barometer reading
|
|
(or '<span class="code">N/A</span>' if it is not available) and
|
|
the outside temperature (or '<span class="code">N/A</span>').
|
|
</p>
|
|
<p>
|
|
You then need to specify that your print service class should be
|
|
loaded instead of the default <span class="code">StdPrint</span>
|
|
service. This is done by substituting your service name for <span
|
|
class="code">StdPrint</span> in the list of reporting services,
|
|
found in option <span class="code">report_services</span>,
|
|
located in <span class="code"> [Engines][[WxEngine]]</span>. When you're done,
|
|
it will look something like this:
|
|
</p>
|
|
<pre class="tty">
|
|
[Engines]
|
|
# This section configures the internal weewx engines.
|
|
# It is for advanced customization.
|
|
|
|
[[WxEngine]]
|
|
# The list of services the main weewx engine should run:
|
|
prep_services = weewx.wxengine.StdTimeSynch
|
|
process_services = weewx.wxengine.StdConvert, weewx.wxengine.StdCalibrate, weewx.wxengine.StdQC
|
|
archive_services = weewx.wxengine.StdArchive,
|
|
restful_services = weewx.restx.StdWunderground, weewx.restx.StdPWSweather, weewx.restx.StdCWOP, weewx.restx.StdStationRegistry
|
|
report_services = <span class="highlight">weewx.wxengine.StdPrint, </span>weewx.wxengine.StdReport</pre>
|
|
|
|
|
|
<h2>Adding a Service</h2>
|
|
<p>
|
|
Suppose there is no service that can be easily customized for
|
|
your needs. In this case, a new one can easily be created by
|
|
subclassing off the abstract base class <span class="code">StdService</span>,
|
|
and then adding the functionality you need. Here is an example
|
|
that implements an alarm that sends off an email when an
|
|
arbitrary expression evaluates <span class="code">True</span>.
|
|
This example is included in the standard distribution in
|
|
directory <span class="symcode">$BIN_ROOT</span><span
|
|
class="code">/examples</span>.
|
|
</p>
|
|
<p>
|
|
File <span class="code">examples/alarm.py</span>:
|
|
</p>
|
|
<pre class="tty">import time
|
|
import smtplib
|
|
from email.mime.text import MIMEText
|
|
import threading
|
|
import syslog
|
|
|
|
import weewx
|
|
from weewx.wxengine import StdService
|
|
from weeutil.weeutil import timestamp_to_string, option_as_list
|
|
|
|
# Inherit from the base class StdService:
|
|
class MyAlarm(StdService):
|
|
"""Custom service that sounds an alarm if an arbitrary expression evaluates true"""
|
|
|
|
def __init__(self, engine, config_dict):
|
|
# Pass the initialization information on to my superclass:
|
|
super(MyAlarm, self).__init__(engine, config_dict)
|
|
|
|
# This will hold the time when the last alarm message went out:
|
|
self.last_msg_ts = 0
|
|
|
|
try:
|
|
# Dig the needed options out of the configuration dictionary.
|
|
# If a critical option is missing, an exception will be thrown and
|
|
# the alarm will not be set.
|
|
self.expression = config_dict['Alarm']['expression']
|
|
self.time_wait = int(config_dict['Alarm'].get('time_wait', 3600))
|
|
self.smtp_host = config_dict['Alarm']['smtp_host']
|
|
self.smtp_user = config_dict['Alarm'].get('smtp_user')
|
|
self.smtp_password = config_dict['Alarm'].get('smtp_password')
|
|
self.SUBJECT = config_dict['Alarm'].get('subject', "Alarm message from weewx")
|
|
self.FROM = config_dict['Alarm'].get('from', 'alarm@weewx.com')
|
|
self.TO = option_as_list(config_dict['Alarm']['mailto'])
|
|
syslog.syslog(syslog.LOG_INFO, "alarm: Alarm set for expression: \"%s\"" % self.expression)
|
|
|
|
# If we got this far, it's ok to start intercepting events:
|
|
self.bind(weewx.NEW_ARCHIVE_RECORD, self.newArchiveRecord) # NOTE 1
|
|
|
|
except Exception, e:
|
|
syslog.syslog(syslog.LOG_INFO, "alarm: No alarm set. %s" % e)
|
|
|
|
def newArchiveRecord(self, event):
|
|
"""Gets called on a new archive record event."""
|
|
|
|
# To avoid a flood of nearly identical emails, this will do
|
|
# the check only if we have never sent an email, or if we haven't
|
|
# sent one in the last self.time_wait seconds:
|
|
if not self.last_msg_ts or abs(time.time() - self.last_msg_ts) >= self.time_wait :
|
|
# Get the new archive record:
|
|
record = event.record
|
|
# Evaluate the expression in the context of the event archive record.
|
|
# Sound the alarm if it evaluates true:
|
|
if eval(self.expression, None, record): # NOTE 2
|
|
# Sound the alarm!
|
|
# Launch in a separate thread so it doesn't block the main LOOP thread:
|
|
t = threading.Thread(target = MyAlarm.soundTheAlarm, args=(self, record))
|
|
t.start()
|
|
# Record when the message went out:
|
|
self.last_msg_ts = time.time()
|
|
|
|
def soundTheAlarm(self, rec):
|
|
"""This function is called when the given expression evaluates True."""
|
|
|
|
# Get the time and convert to a string:
|
|
t_str = timestamp_to_string(rec['dateTime'])
|
|
|
|
# Log it in the system log:
|
|
syslog.syslog(syslog.LOG_INFO, "alarm: Alarm expression \"%s\" evaluated True at %s" % (self.expression, t_str))
|
|
|
|
# Form the message text:
|
|
msg_text = "Alarm expression \"%s\" evaluated True at %s\nRecord:\n%s" % (self.expression, t_str, str(rec))
|
|
# Convert to MIME:
|
|
msg = MIMEText(msg_text)
|
|
|
|
# Fill in MIME headers:
|
|
msg['Subject'] = self.SUBJECT
|
|
msg['From'] = self.FROM
|
|
msg['To'] = ','.join(self.TO)
|
|
|
|
# Create an instance of class SMTP for the given SMTP host:
|
|
s = smtplib.SMTP(self.smtp_host)
|
|
try:
|
|
# Some servers (eg, gmail) require encrypted transport.
|
|
# Be prepared to catch an exception if the server
|
|
# doesn't support it.
|
|
s.ehlo()
|
|
s.starttls()
|
|
s.ehlo()
|
|
syslog.syslog(syslog.LOG_DEBUG, " **** using encrypted transport")
|
|
except smtplib.SMTPException:
|
|
syslog.syslog(syslog.LOG_DEBUG, " **** using unencrypted transport")
|
|
|
|
try:
|
|
# If a username has been given, assume that login is required for this host:
|
|
if self.smtp_user:
|
|
s.login(self.smtp_user, self.smtp_password)
|
|
syslog.syslog(syslog.LOG_DEBUG, " **** logged in with user name %s" % (self.smtp_user,))
|
|
|
|
# Send the email:
|
|
s.sendmail(msg['From'], self.TO, msg.as_string())
|
|
# Log out of the server:
|
|
s.quit()
|
|
except Exception, e:
|
|
syslog.syslog(syslog.LOG_ERR, "alarm: SMTP mailer refused message with error %s" % (e,))
|
|
raise
|
|
|
|
# Log sending the email:
|
|
syslog.syslog(syslog.LOG_INFO, " **** email sent to: %s" % self.TO) </pre>
|
|
<p>
|
|
This service expects all the information it needs to be in the
|
|
configuration file <span class="code">weewx.conf</span> in a new
|
|
section called <span class="code">[Alarm]</span>. So, add the
|
|
following lines to your configuration file:
|
|
</p>
|
|
<pre class="tty">[Alarm]
|
|
expression = "outTemp < 40.0"
|
|
time_wait = 3600
|
|
smtp_host = smtp.mymailserver.com
|
|
smtp_user = myusername
|
|
smtp_password = mypassword
|
|
mailto = auser@adomain.com, anotheruser@someplace.com
|
|
from = me@mydomain.com
|
|
subject = "Alarm message from weewx!"</pre>
|
|
<p>
|
|
There are two important points to be noted in this example, each
|
|
marked with a "<span class="code">NOTE</span>" flag in the code.
|
|
</p>
|
|
<ol>
|
|
<li>Here is where the binding happens between an event,
|
|
weewx.NEW_ARCHIVE_RECORD in this example, and a member
|
|
function, self.newArchiveRecord. There are other events that
|
|
can be interecepted. Look in the file <span class="symcode">$BIN_ROOT</span><span
|
|
class="code">/weewx/__init__.py</span>.
|
|
</li>
|
|
<li>This is where the test is done of whether or not to
|
|
sound the alarm. The <span class="code">[Alarm]</span>
|
|
configuration options specify that the alarm be sounded when "<span
|
|
class="code">outTemp < 40.0</span>" evaluates <span
|
|
class="code">True</span>, that is when the outside temperature
|
|
is below 40.0 degrees. Any valid Python expression can be
|
|
used, although the only variables available are those in the
|
|
current archive record.
|
|
</li>
|
|
</ol>
|
|
<p>Another example expression could be:</p>
|
|
<pre class="tty">expression = "outTemp < 32.0 and windSpeed > 10.0"</pre>
|
|
<p>In this case, the alarm is sounded if the outside
|
|
temperature drops below freezing and the wind speed is greater
|
|
than 10.0.</p>
|
|
<p>
|
|
Option <span class="code">time_wait</span> is used to avoid a
|
|
flood of nearly identical emails. The new service will wait this
|
|
long before sending another email out.
|
|
</p>
|
|
<p>
|
|
Email will be sent through the SMTP host specified by option <span
|
|
class="code"> smtp_host</span>. The recipient(s) are specified
|
|
by the comma separated option <span class="code">mailto</span>.
|
|
</p>
|
|
<p>
|
|
Many SMTP hosts require user login. If this is the case, the
|
|
user and password are specified with options <span class="code">smtp_user</span>
|
|
and <span class="code">smtp_password</span>, respectively.
|
|
</p>
|
|
<p>
|
|
The last two options, "<span class="code">from</span>" and "<span
|
|
class="code">subject</span>" are optional. If not supplied, <span
|
|
class="code">weewx</span> will supply something sensible.
|
|
Note, however, that some mailers require a valid "from" email
|
|
address and the one <span class="code">weewx</span> supplies may
|
|
not satisfy its requirements.
|
|
</p>
|
|
<p>
|
|
To make this all work, you must tell the engine to load this new
|
|
service. You must also make sure it gets its events at the right
|
|
time. Because this is a kind of "reporting" service, that is, it
|
|
consumes and interprets archived data, it is best put among the
|
|
other reporting services, specified by option <span class="code">report_services</span>,
|
|
located in section <span class="code">[Engines][[WxEngine]]</span>.
|
|
When you're done, that section will look something like this:
|
|
</p>
|
|
<pre class="tty">[Engines]
|
|
# This section configures the internal weewx engines.
|
|
# It is for advanced customization.
|
|
|
|
[[WxEngine]]
|
|
# The list of services the main weewx engine should run:
|
|
prep_services = weewx.wxengine.StdTimeSynch
|
|
process_services = weewx.wxengine.StdConvert, weewx.wxengine.StdCalibrate, weewx.wxengine.StdQC
|
|
archive_services = weewx.wxengine.StdArchive,
|
|
restful_services = weewx.restx.StdWunderground, weewx.restx.StdPWSweather, weewx.restx.StdCWOP, weewx.restx.StdStationRegistry
|
|
report_services = weewx.wxengine.StdPrint, weewx.wxengine.StdReport<span class="highlight">, examples.alarm.MyAlarm</span></pre>
|
|
<p>
|
|
Note that each of these lists must be all on one line.
|
|
Unfortunately, the parser <span class="code">ConfigObj</span> does
|
|
not allow options to be continued on to following lines.
|
|
</p>
|
|
<p>
|
|
In addition to the example above, the distribution also includes
|
|
a low-battery alarm (<span class="code">lowBattery.py</span>),
|
|
which is similar, except that it intercepts LOOP events (instead
|
|
of archiving events).
|
|
</p>
|
|
<h1 id="archive_database">Customizing the archive database</h1>
|
|
<p>
|
|
For most users the default database will work just fine. It has
|
|
the added advantage of being compatible with the wview database.
|
|
Nevertheless, there may be occasions where you may want to add a
|
|
SQL type to your database, or change its unit system. This
|
|
section shows you how to do this, using the utility <span
|
|
class="symcode">$BIN_ROOT</span><span class="code">/wee_config_database</span>.
|
|
</p>
|
|
<p>
|
|
Before starting, it's worth running the utility with the <span
|
|
class="code"> --help</span> flag to see how it is used:
|
|
</p>
|
|
<pre class="tty"><span class="symcode">$BIN_ROOT</span>/wee_config_database --help</pre>
|
|
<h2>Adding a new observation type</h2>
|
|
<p>Suppose you have installed an electric meter at your house
|
|
and you wish to correlate electrical usage with the weather. The
|
|
meter has some sort of connection to your computer, allowing you
|
|
to download the consumption. At the end of every archive
|
|
interval you want to sample the meter for the electricity
|
|
consumed during the interval, then store the results in the
|
|
archive database, along with the weather data. How would you do
|
|
this?</p>
|
|
<p>
|
|
First, you would write a custom service that retrieves the
|
|
electrical consumption data and adds it to the archive record.
|
|
See the section <a href="#service_engine">Customizing the
|
|
weewx service engine</a> for details on how to write a custom
|
|
service. However, when you are done it will look something like
|
|
this:
|
|
</p>
|
|
<p>File <span class="code">user/electricity.py</span>:</p>
|
|
<pre class="tty">class AddElectricity(StdService):
|
|
|
|
def new_archive_packet(self, event):
|
|
|
|
(code that downloads the consumption data from the connection to the meter)
|
|
|
|
event.record['electricity'] = retrieved_value</pre>
|
|
<p>
|
|
This adds a new key '<span class="code">electricity</span>' to
|
|
the record dictionary and sets it equal to some value. As an
|
|
aside, if you do something like this, you would want to make
|
|
sure that the code to retrieve the current electrical
|
|
consumption does not delay very long so it does not slow down
|
|
the main loop. If it's going to cause a delay of more than a
|
|
couple seconds you might want to put it in a separate thread and
|
|
feed the results to <span class="code">AddElectricity</span>
|
|
through a queue.
|
|
</p>
|
|
<p>
|
|
As usual, to make sure your new service actually gets run, you
|
|
must include it in one of the service lists in section <span
|
|
class="code">[Engine][[WxEngine]]</span> of <span class="code">weewx.conf</span>.
|
|
Because your service will <em>produce</em> new data, it's
|
|
important that it be included before the archiving services.
|
|
Hence, it's best included amongst the other services that produce
|
|
and process data, in the list <span class="code">process_service</span>.
|
|
When you're done, the section would look something like this:
|
|
</p>
|
|
<pre class="tty">
|
|
[Engines]
|
|
# This section configures the internal weewx engines.
|
|
# It is for advanced customization.
|
|
|
|
[[WxEngine]]
|
|
# The list of services the main weewx engine should run:
|
|
prep_services = weewx.wxengine.StdTimeSynch
|
|
process_services = weewx.wxengine.StdConvert, weewx.wxengine.StdCalibrate, weewx.wxengine.StdQC<span class="highlight">, user.electricity.AddElectricity</span>
|
|
archive_services = weewx.wxengine.StdArchive,
|
|
restful_services = weewx.restx.StdWunderground, weewx.restx.StdPWSweather, weewx.restx.StdCWOP, weewx.restx.StdStationRegistry
|
|
report_services = weewx.wxengine.StdPrint, weewx.wxengine.StdReport</pre>
|
|
|
|
<h3 id="add_archive_type">Adding a new type to the archive database</h3>
|
|
<p>
|
|
So, now you have created a new observation type, '<span
|
|
class="code">electricity</span>'. Trouble is, there is no
|
|
corresponding type in the schema of the SQL database and,
|
|
therefore, it won't be stored there. How would you add such a
|
|
type?
|
|
</p>
|
|
<p>Here's our general strategy:</p>
|
|
<ol>
|
|
<li>Add a new type to the database schema.</li>
|
|
<li>Make sure you have the necessary permissions to create
|
|
the new database.</li>
|
|
<li>Populate it with data from the old database.</li>
|
|
<li>Shuffle databases around so <span class="code">weewx</span>
|
|
will use the new database.
|
|
</li>
|
|
<li>Modify the stats database so it includes the new type
|
|
as well (Optional).</li>
|
|
</ol>
|
|
<p>
|
|
1. <strong>Adding a new type to the schema.</strong> When
|
|
creating a database the schema is obtained from file <span
|
|
class="symcode">$BIN_ROOT</span><span class="code">/user/schemas.py</span>.
|
|
Take a look at it now. You will see a list called <span
|
|
class="code">defaultArchiveSchema</span> that holds all the
|
|
observation names and their SQL types. It looks something like:
|
|
</p>
|
|
<pre class="tty">defaultArchiveSchema = [('dateTime', 'INTEGER NOT NULL UNIQUE PRIMARY KEY'),
|
|
('usUnits', 'INTEGER NOT NULL'),
|
|
('interval', 'INTEGER NOT NULL'),
|
|
('barometer', 'REAL'),
|
|
('pressure', 'REAL'),
|
|
('altimeter', 'REAL'),
|
|
('inTemp', 'REAL'),
|
|
('outTemp', 'REAL'),
|
|
...
|
|
('inTempBatteryStatus', 'REAL')]</pre>
|
|
<p>
|
|
Let's modify it to add our new type, '<span class="code">electricity</span>'.
|
|
Now it looks like this:
|
|
</p>
|
|
<pre class="tty">defaultArchiveSchema = [('dateTime', 'INTEGER NOT NULL UNIQUE PRIMARY KEY'),
|
|
('usUnits', 'INTEGER NOT NULL'),
|
|
('interval', 'INTEGER NOT NULL'),
|
|
('barometer', 'REAL'),
|
|
('pressure', 'REAL'),
|
|
('altimeter', 'REAL'),
|
|
('inTemp', 'REAL'),
|
|
('outTemp', 'REAL'),
|
|
...
|
|
<span class="highlight"> ('electricity', 'REAL'),</span>
|
|
('inTempBatteryStatus', 'REAL')]</pre>
|
|
<p>
|
|
The new line has been <span class="highlight"> highlighted </span>.
|
|
</p>
|
|
<p>
|
|
2. <strong>Check permissions.</strong> The reconfiguration
|
|
utility will create a new database with the same name as the
|
|
old, except with the suffix '<span class="code">_new</span>'
|
|
attached to the end. Make sure you have the necessary
|
|
permissions to do this. In particular, if you are using MySQL,
|
|
you will need '<span class="code">CREATE</span>' privileges.
|
|
</p>
|
|
<p>
|
|
3. <strong>Run <span class="code">wee_config_database</span>.
|
|
</strong> Now run the utility <span class="code">wee_config_database</span>
|
|
with the <span class="code">--reconfigure</span> option and the
|
|
path to the configuration file:
|
|
</p>
|
|
<pre class="tty"><span class="symcode">$BIN_ROOT</span>/wee_config_database --reconfigure <span
|
|
class="symcode">$CONFIG_ROOT</span>/weewx.conf</pre>
|
|
<p>
|
|
This will create a new database (nominally, <span class="code">
|
|
weewx.sdb_new</span> if you are using sqlite, <span class="code">weewx_new</span>
|
|
if you are using MySQL) using the new schema and populate it
|
|
with data from the old database.
|
|
</p>
|
|
<p>
|
|
4. <strong>Shuffle the databases.</strong> Now arrange things so
|
|
<span class="code">weewx</span> can find the new database.
|
|
</p>
|
|
<p class="warning">
|
|
<strong>Warning!</strong><br /> Make a backup of the data
|
|
before doing any of the next steps!
|
|
</p>
|
|
<p>
|
|
You can either shuffle the databases around so the new database
|
|
has the same name as the old database, or edit <span
|
|
class="code">weewx.conf</span> to use the new database name.
|
|
To do the former:
|
|
</p>
|
|
<p>For sqlite:</p>
|
|
<pre class="tty">cd <span class="symcode">$SQLITE_ROOT</span>
|
|
mv weewx.sdb_new weewx.sdb</pre>
|
|
<p>For MySQL:</p>
|
|
<pre class="tty">mysql -u <username> --password=<mypassword>
|
|
<span class="prompt">mysql></span> DROP DATABASE weewx; # Drops the old database
|
|
<span class="prompt">mysql></span> CREATE DATABASE weewx; # Create a new one with the same name
|
|
<span class="prompt">mysql></span> RENAME TABLE weewx_new.archive TO weewx.archive; # Rename to the nominal name</pre>
|
|
<p>
|
|
5. <strong>Modify the stats database.</strong> At this point,
|
|
you can use the new observation type in the plots. However, if
|
|
you wish to use it in the statistical summaries, you will also
|
|
have to add it to the stats database. To do this, add the type
|
|
to the Python list <span class="code"> stats_types</span>, which
|
|
can be found in <span class="symcode">$BIN_ROOT</span><span
|
|
class="code">/user/schemas.py</span>, so it reads something
|
|
like this:
|
|
</p>
|
|
<pre class="tty">stats_types = ['barometer', 'inTemp', 'outTemp',
|
|
'inHumidity', 'outHumidity',
|
|
'rainRate', 'rain', 'dewpoint', 'windchill', 'heatindex', 'ET',
|
|
'radiation', 'UV', 'extraTemp1', 'rxCheckPercent', 'wind',
|
|
<span class="highlight">'electricity'</span>]</pre>
|
|
<p>
|
|
Now delete the stats database (nominally <span class="code">stats.sdb</span>
|
|
for sqlite, <span class="code">stats</span> for MySQL). Weewx
|
|
will automatically rebuild it, including your new type.
|
|
</p>
|
|
<h3>Using the new type</h3>
|
|
<p>Now you've added a new type. How do you use it?</p>
|
|
<p>
|
|
Pretty much like any other type. For example, to do a plot of
|
|
the month's electric consumption, totaled by day, add this
|
|
section to the <span class="code">[[month_images]]</span>
|
|
section of <span class="code"> skin.conf</span>:
|
|
</p>
|
|
<pre class="tty">[[[monthelectric]]]
|
|
[[[[electricity]]]]
|
|
aggregate_type = sum
|
|
aggregate_interval = 86400
|
|
label = Electric consumption (daily total)</pre>
|
|
<p>
|
|
This will cause the generation of an image <span class="code">
|
|
monthelectric.png</span>, showing a plot of each day's consumption
|
|
for the past month.
|
|
</p>
|
|
<p>If you wish to use the new type in the templates, it will
|
|
be available using the same syntax as any other type. Here are
|
|
some other tags that might be useful:</p>
|
|
<table class="indent" style="width: 80%">
|
|
<tbody>
|
|
<tr>
|
|
<td><strong>Tag</strong></td>
|
|
<td><strong>Meaning</strong></td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">$day.electricity.sum</td>
|
|
<td>Total consumption since midnight</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">$year.electricity.sum</td>
|
|
<td>Total consumption since the first of the year</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">$year.electricity.max</td>
|
|
<td>The most consumed during any archive period</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">$year.electricity.maxsum</td>
|
|
<td>The most consumed during a day</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">$year.electricity.maxsumtime</td>
|
|
<td>The day it happened.</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">$year.electricity.sum_ge(5.0)</td>
|
|
<td>The number of days where more than 5.0 kWH of
|
|
energy was consumed.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<h2 id="Changing_the_unit_system">Changing the unit system</h2>
|
|
<p>Normally, data is stored in the databases using US
|
|
Customary units and, normally, you don't care --- data can
|
|
always be displayed using any units you choose. It's an
|
|
"implementation detail." Nevertheless, there may be special
|
|
situations where you wish to store the data in Metric units. For
|
|
example, you may need to allow direct programmatic access to the
|
|
databases from another piece of software that expects metric
|
|
units.</p>
|
|
<p>
|
|
Weewx does not allow you to change the database unit system
|
|
midstream. You can't start with one unit system then, in the
|
|
middle of the database, switch to another. See the section <span
|
|
class="code"> <a href="usersguide.htm#StdConvert">
|
|
[StdConvert]</a></span> in the Weewx User's Guide. However, you can
|
|
reconfigure the database by coping it to a new database,
|
|
performing the unit conversion along the way. You then use this
|
|
new database.
|
|
</p>
|
|
<p>
|
|
The steps are pretty much the same as <a
|
|
href="#add_archive_type"> Adding a New Type to the
|
|
ArchiveDatabase</a>, described above.
|
|
</p>
|
|
<ol>
|
|
<li>Modify <span class="code">weewx.conf</span> to reflect
|
|
your choice of the new unit system to use.
|
|
</li>
|
|
<li>Make sure you have the necessary permissions to create
|
|
the new database.</li>
|
|
<li>Populate it with data from the old database.</li>
|
|
<li>Shuffle databases around so <span class="code">weewx</span>
|
|
will use the new database.
|
|
</li>
|
|
<li>Rebuild the stats database to use the new unit system.</li>
|
|
</ol>
|
|
<p>
|
|
1. <strong>Modify <span class="code">weewx.conf</span>.
|
|
</strong> Edit the configuration file to change option <span class="code">target_unit</span>
|
|
in section <span class="code"><a
|
|
href="usersguide.htm#StdConvert"> [StdConvert]</a></span> to reflect
|
|
your choice. If you are switching to metric units, the option
|
|
will look like
|
|
</p>
|
|
<pre class="tty">[StdConvert]
|
|
target_unit = METRIC</pre>
|
|
<p>
|
|
2. <strong>Check permissions.</strong> The reconfiguration
|
|
utility will create a new database with the same name as the
|
|
old, except with the suffix '<span class="code">_new</span>'
|
|
attached to the end. Make sure you have the necessary
|
|
permissions to do this. In particular, if you are using MySQL,
|
|
you will need '<span class="code">CREATE</span>' privileges.
|
|
</p>
|
|
<p>
|
|
3. <strong>Run <span class="code">wee_config_database</span>.
|
|
</strong> Now run the utility <span class="code">wee_config_database</span>
|
|
with the <span class="code">--reconfigure</span> option:
|
|
</p>
|
|
<pre class="tty"><span class="symcode">$BIN_ROOT</span>/wee_config_database --reconfigure <span
|
|
class="symcode">$CONFIG_ROOT</span>/weewx.conf</pre>
|
|
<p>
|
|
This will create a new database (nominally, <span class="code">
|
|
weewx.sdb_new</span> if you are using sqlite, <span class="code">weewx_new</span>
|
|
if you are using MySQL), using the schema found in <span
|
|
class="symcode">$BIN_ROOT</span><span class="code">/user/schemas.py</span>,
|
|
and populate it with data from the old database, while
|
|
performing the unit conversion.
|
|
</p>
|
|
<p>
|
|
4. <strong>Shuffle the databases.</strong> This is identical to
|
|
the description above.
|
|
</p>
|
|
<p>
|
|
5. <strong>Recreate the stats database.</strong> Delete the
|
|
stats database, then let <span class="code">weewx</span>
|
|
regenerate it. It will use the new unit system.
|
|
</p>
|
|
<h1 id="porting">Porting to new weather station hardware</h1>
|
|
<p>Naturally, this is an advanced topic but, nevertheless, I'd
|
|
really like to encourage any Python wizards out there to give it
|
|
a try. Of course, I have selfish reasons for encouraging you: I
|
|
don't want to have to go out and buy every type of hardware
|
|
there is! It's expensive and my roof would look like a weather
|
|
station farm.</p>
|
|
<p>Here's the general strategy for doing a port.</p>
|
|
<h2>Implement the driver</h2>
|
|
<p>
|
|
Inherit from the abstract base class <span class="code">weewx.abstractstation.AbstractStation</span>.
|
|
Try to implement as many of its methods as you can. At the very
|
|
minimum, you must implement <span class="code">hardware_name</span>
|
|
and <span class="code">genLoopPackets</span>.
|
|
</p>
|
|
<p>
|
|
<span class="code">hardware_name</span>: Return a string with a
|
|
short nickname for the hardware, such as "<span class="code">ACME
|
|
X90</span>"
|
|
</p>
|
|
<p>
|
|
<span class="code">genLoopPackets</span>: This should be a
|
|
generator function that yields loop packets, one after another.
|
|
Don't worry about stopping it: the engine will do this when an
|
|
archive record is due. A loop packet is a dictionary. At the
|
|
very minimum it must contain keys
|
|
</p>
|
|
<table class="indent" style="width: 60%">
|
|
<tbody>
|
|
<tr>
|
|
<td class="code">dateTime</td>
|
|
<td>The time of the observation in unix epoch time.</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">usUnits</td>
|
|
<td>The unit system used. <span class="code">weewx.US</span>
|
|
for US customary, <span class="code">weewx.METRIC</span>
|
|
for metric. See the file <span class="code">units.py</span>,
|
|
dictionaries <span class="code">USUnits</span> and <span
|
|
class="code">MetricUnits</span> for the exact definition
|
|
of each.
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p>
|
|
Then include any observation types you have in the dictionary.
|
|
Every packet need not contain the same set of observation types.
|
|
Different packets can use different unit systems, but all
|
|
observations within a packet must use the same unit system. If
|
|
your hardware has an error and you don't have a value, you can
|
|
either leave it out of the dictionary or (preferred) set its
|
|
value to <span class="code">None</span>.
|
|
</p>
|
|
<p>
|
|
A couple of observation types are tricky. In particular, rain.
|
|
Generally, <span class="code">weewx</span> expects to see a
|
|
packet with the amount of rain that fell in that packet period
|
|
included as observation '<span class="code">rain</span>'. It
|
|
then sums up all the values to get the total rainfall and emits
|
|
that in the archive record. If your hardware does not provide
|
|
this value, you might have to infer it from changes in whatever
|
|
value it provides, for example changes in the daily or monthly
|
|
rainfall. I know this is not the best solution, but it is the
|
|
most general solution. Any alternatives are welcome!
|
|
</p>
|
|
<p>
|
|
Wind is another tricky one. It is actually broken up into four
|
|
different observations: '<span class="code">windSpeed</span>', '<span
|
|
class="code">windDir</span>', '<span class="code">windGust</span>',
|
|
and '<span class="code">windGustDir</span>'. Supply as many as
|
|
you can. The directions should be compass directions in degrees
|
|
(0=North, 90=East, etc.).
|
|
</p>
|
|
<p>Be careful when reporting pressure. There are three
|
|
observations related to pressure. Some stations report only the
|
|
station pressure, others calculate and report sea level
|
|
pressures.</p>
|
|
<table class="indent" style="width: 60%">
|
|
<tbody>
|
|
<tr>
|
|
<td class="code">pressure</td>
|
|
<td>The <em>Station Pressure</em> (SP), which is the
|
|
raw, absolute pressure measured by the station. This is
|
|
the true barometric pressure for the station.
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">barometer</td>
|
|
<td>The <em>Sea Level Pressure</em> (SLP) obtained by
|
|
correcting the <em> Station Pressure</em> for altitude and
|
|
local temperature. This is the pressure reading most
|
|
commonly used by meteorologist to track weather systems at
|
|
the surface, and this is the pressure that is uploaded to
|
|
weather services by <span class="code">weewx</span>. It is
|
|
the station pressure reduced to mean sea level using local
|
|
altitude and local temperature.
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">altimeter</td>
|
|
<td>The <em>Altimeter Setting</em> (AS) obtained by
|
|
correcting the <em>Station Pressure</em> for altitude.
|
|
This is the pressure reading most commonly heard in
|
|
weather reports. It is not the true barometric pressure of
|
|
a station, but rather the station pressure reduced to mean
|
|
sea level using altitude and an assumed temperature
|
|
average.
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p></p>
|
|
<p>
|
|
<span class="code">genArchiveRecords:</span> If your hardware
|
|
does not have an archive record logger, then <span class="code">weewx</span>
|
|
can do the record generation for you. It will automatically
|
|
collect all the types it sees in your loop packets then emit a
|
|
record with the averages (in some cases the sum or max value) of
|
|
all those types. If it doesn't see a type, then it won't appear
|
|
in the emitted record. If your hardware does have a logger, then
|
|
you should implement method <span class="code">genArchiveRecords</span>
|
|
as well. It should be a generator function that returns all the
|
|
records since a given time.
|
|
</p>
|
|
<p>
|
|
<span class="code">closePort:</span> If the driver needs to
|
|
close a serial port, terminate a thread, close a database, or
|
|
perform any other activity before the application terminates, do
|
|
it in this method.
|
|
</p>
|
|
<p>
|
|
<span class="code">loader:</span> This is a factory function
|
|
that returns an instance of your driver. It has two arguments:
|
|
the configuration dictionary, and a reference to the weewx
|
|
engine.
|
|
</p>
|
|
<h2>Define the configuration</h2>
|
|
<p>
|
|
You then include a new section in the configuration file <span
|
|
class="code"> weewx.conf</span> that includes any options your
|
|
driver needs. It should also include an entry '<span
|
|
class="code">driver</span>' that points to where your driver
|
|
can be found. Set option <span class="code">station_type</span>
|
|
to your new section type and your driver will be loaded.
|
|
</p>
|
|
<h2>Examples</h2>
|
|
<p>
|
|
Take a look at the simulator code in <span class="code">simulator.py</span>
|
|
for a dirt simple example of a driver. The next most complicated
|
|
is the driver for the WMR100 series, located in <span
|
|
class="code">wmr100.py</span>. The driver for the Vantage
|
|
series is by far the most complicated. It actually
|
|
multi-inherits from not only <span class="code">AbstractStation</span>,
|
|
but also <span class="code">StdService</span>. That is, it also
|
|
participates in the engine as a service.
|
|
</p>
|
|
<p>Naturally, there are a lot of subtleties that I've glossed
|
|
over in this high-level description. If you're game, give it a
|
|
try - I'm happy to help you out!</p>
|
|
<h1 id="archive_types">Appendix A: Archive Types</h1>
|
|
<p>
|
|
<em>Archive types</em> are weather observations that have come
|
|
from your instrument and been stored in the <em>archive
|
|
database</em>, a SQL database. They represent the <em>current
|
|
conditions</em> as of some time. They are available to be used in
|
|
two places:
|
|
</p>
|
|
<ul>
|
|
<li>In your template files as a tag with period <span
|
|
class="code"> $current</span>. Hence, the tag <span
|
|
class="code">$current.outTemp</span> represents the latest
|
|
current outside temperature. There is no aggregation involved
|
|
(see <a href="#statistical_types">statistical types</a> for
|
|
aggregation).
|
|
</li>
|
|
<li>In your plot graphs. Here, a line in the graph
|
|
represents the set of current observations over a time period.
|
|
While each plot point in a graph may represent an aggregation,
|
|
do not confuse this aggregation with the statistical
|
|
aggregation. The former is done with the archive database, the
|
|
latter with the statistical database.</li>
|
|
</ul>
|
|
<p>
|
|
The following table shows all the possible archive types and
|
|
whether they can be used in tag <span class="code">$current</span>
|
|
or in a plot. Note that just because a type appears in the table
|
|
does not necessarily mean that it is available for <em>your</em>
|
|
station setup. That would depend on whether your instrument
|
|
supports the type.
|
|
</p>
|
|
<table class="indent" style="width: 80%">
|
|
<tbody>
|
|
<tr>
|
|
<td><strong>Archive Type</strong></td>
|
|
<td style="width: 200px"><strong>SQL Type</strong> <br />
|
|
<span style="font-size: 80%">(appears in archive
|
|
database)</span></td>
|
|
<td><strong>Can be used <br /> in plots
|
|
</strong></td>
|
|
<td><strong>Can be used <br /> in tag <span
|
|
class="code">$current</span></strong></td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">altimeter</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">barometer</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">consBatteryVoltage</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">dateTime</td>
|
|
<td>X</td>
|
|
<td><br /></td>
|
|
<td>X (represents current time)</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">dewpoint</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">ET</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">extraHumid1</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">extraHumid2</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">extraTemp1</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">extraTemp2</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">extraTemp3</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">hail</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">hailRate</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">heatindex</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">heatingTemp</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">heatingVoltage</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">inHumidity</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">inTemp</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">inTempBatteryStatus</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">interval</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">leafTemp2</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">leafWet2</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">outHumidity</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">outTemp</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">outTempBatteryStatus</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">pressure</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">radiation</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">rain</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">rainBatteryStatus</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">rainRate</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">referenceVoltage</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">rxCheckPercent</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">soilMoist1</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">soilMoist2</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code" style="height: 33px">soilMoist3</td>
|
|
<td style="height: 33px">X</td>
|
|
<td style="height: 33px">X</td>
|
|
<td style="height: 33px">X</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">soilMoist4</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">soilTemp1</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">soilTemp2</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">soilTemp3</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">soilTemp4</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">supplyVoltage</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">txBatteryStatus</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">usUnits</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">UV</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">windvec</td>
|
|
<td></td>
|
|
<td>X (special vector type)</td>
|
|
<td></td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">windBatteryStatus</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">windDir</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">windGust</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">windGustDir</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">windSpeed</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">windchill</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<h1 id="units">Appendix B: Units</h1>
|
|
<p>The table below lists all the unit groups, their members,
|
|
and which units are options for the group.</p>
|
|
<table class="indent" style="width: 60%">
|
|
<tbody>
|
|
<tr>
|
|
<td><strong>Group</strong></td>
|
|
<td><strong>Members</strong></td>
|
|
<td><strong>Unit options</strong></td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">group_altitude</td>
|
|
<td class="code">altitude</td>
|
|
<td class="code">foot <br /> meter
|
|
</td>
|
|
</tr>
|
|
<tr class="code">
|
|
<td>group_degree_day</td>
|
|
<td>cooldeg<br /> heatdeg
|
|
</td>
|
|
<td>degree_F_day<br /> degree_C_day
|
|
</td>
|
|
</tr>
|
|
<tr class="code">
|
|
<td>group_direction</td>
|
|
<td>gustdir <br /> vecdir <br /> windDir <br />
|
|
windGustDir
|
|
</td>
|
|
<td>degree_compass</td>
|
|
</tr>
|
|
<tr class="code">
|
|
<td>group_interval</td>
|
|
<td>interval</td>
|
|
<td>minute</td>
|
|
</tr>
|
|
<tr class="code">
|
|
<td>group_moisture</td>
|
|
<td>soilMoist1 <br /> soilMoist2 <br /> soilMoist3 <br />
|
|
soilMoist4
|
|
</td>
|
|
<td>centibar</td>
|
|
</tr>
|
|
<tr class="code">
|
|
<td>group_percent</td>
|
|
<td>extraHumid1 <br /> extraHumid2 <br /> inHumidity
|
|
<br /> outHumidity <br /> rxCheckPercent
|
|
</td>
|
|
<td>percent</td>
|
|
</tr>
|
|
<tr class="code">
|
|
<td>group_pressure</td>
|
|
<td>barometer <br /> altimeter <br /> pressure
|
|
</td>
|
|
<td>inHg <br /> mbar <br /> hPa
|
|
</td>
|
|
</tr>
|
|
<tr class="code">
|
|
<td>group_radiation</td>
|
|
<td>UV <br /> radiation
|
|
</td>
|
|
<td>watt_per_meter_squared</td>
|
|
</tr>
|
|
<tr class="code">
|
|
<td>group_rain</td>
|
|
<td>rain <br /> ET <br /> hail
|
|
</td>
|
|
<td>in <br /> cm <br /> mm
|
|
</td>
|
|
</tr>
|
|
<tr class="code">
|
|
<td>group_rainrate</td>
|
|
<td>rainRate <br /> hailRate
|
|
</td>
|
|
<td>in_per_hour <br /> cm_per_hour <br /> mm_per_hour
|
|
</td>
|
|
</tr>
|
|
<tr class="code">
|
|
<td>group_speed</td>
|
|
<td>wind <br /> windGust <br /> windSpeed <br />
|
|
windgustvec <br /> windvec
|
|
</td>
|
|
<td>mile_per_hour <br /> km_per_hour <br /> knot <br />
|
|
meter_per_second
|
|
</td>
|
|
</tr>
|
|
<tr class="code">
|
|
<td>group_speed2</td>
|
|
<td>rms <br /> vecavg
|
|
</td>
|
|
<td>mile_per_hour2 <br /> km_per_hour2 <br /> knot2 <br />
|
|
meter_per_second2
|
|
</td>
|
|
</tr>
|
|
<tr class="code">
|
|
<td>group_temperature</td>
|
|
<td>dewpoint <br /> extraTemp1 <br /> extraTemp2 <br />
|
|
extraTemp3 <br /> heatindex <br /> heatingTemp <br />
|
|
inTemp <br /> leafTemp1 <br /> leafTemp2 <br /> outTemp
|
|
<br /> soilTemp1 <br /> soilTemp2 <br /> soilTemp3 <br />
|
|
soilTemp4 <br /> windchill
|
|
</td>
|
|
<td>degree_F <br /> degree_C
|
|
</td>
|
|
</tr>
|
|
<tr class="code">
|
|
<td>group_time</td>
|
|
<td>dateTime</td>
|
|
<td>unix_epoch <br /> dublin_jd
|
|
</td>
|
|
</tr>
|
|
<tr class="code">
|
|
<td>group_uv</td>
|
|
<td>UV</td>
|
|
<td>uv_index</td>
|
|
</tr>
|
|
<tr class="code">
|
|
<td>group_volt</td>
|
|
<td>consBatteryVoltage <br /> heatingVoltage <br />
|
|
referenceVoltage <br /> supplyVoltage
|
|
</td>
|
|
<td>volt</td>
|
|
</tr>
|
|
<tr class="code">
|
|
<td>group_NONE</td>
|
|
<td>NONE</td>
|
|
<td>NONE</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<h1 id="statistical_types">Appendix C: Statistical Types</h1>
|
|
<p>
|
|
Most of the templates are devoted to reporting <em>statistical
|
|
types</em>, such as temperature, wind, or rainfall, using various <em>aggregates</em>,
|
|
such as min, max, or sum. These are called <em>aggregations</em>,
|
|
because they are a summary of lots of underlying data. However,
|
|
only certain aggregates make sense for certain statistical
|
|
types. For example, heat degree days is defined on a daily
|
|
basis, so while the day's average temperature is meaningful, the
|
|
day's heating degree days do not.
|
|
</p>
|
|
<p>
|
|
The following table defines which aggregates are available to be
|
|
used in your template for which statistical types (assuming your
|
|
station supports them and you have specified that it be stored
|
|
in your stats database. See section <span class="code"><a
|
|
href="usersguide.htm#Stats"> [Stats]</a></span> in the <span
|
|
class="code">weewx.conf</span> configuration file).
|
|
</p>
|
|
<table class="indent" id="stattypes">
|
|
<tbody>
|
|
<tr>
|
|
<td><strong>Type</strong></td>
|
|
<td class="code">min</td>
|
|
<td class="code">mintime</td>
|
|
<td class="code">max</td>
|
|
<td class="code">maxtime</td>
|
|
<td class="code">avg</td>
|
|
<td class="code">sum</td>
|
|
<td class="code">rms</td>
|
|
<td class="code">vecavg</td>
|
|
<td class="code">vecdir</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">barometer</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td></td>
|
|
<td></td>
|
|
<td></td>
|
|
<td></td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">inTemp</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td></td>
|
|
<td></td>
|
|
<td></td>
|
|
<td></td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">outTemp</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td></td>
|
|
<td></td>
|
|
<td></td>
|
|
<td></td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">inHumidity</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td></td>
|
|
<td></td>
|
|
<td></td>
|
|
<td></td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">outHumidity</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td></td>
|
|
<td></td>
|
|
<td></td>
|
|
<td></td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">wind</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td></td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">rain</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td></td>
|
|
<td></td>
|
|
<td></td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">dewpoint</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td></td>
|
|
<td></td>
|
|
<td></td>
|
|
<td></td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">windchill</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td></td>
|
|
<td></td>
|
|
<td></td>
|
|
<td></td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">heatindex</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td></td>
|
|
<td></td>
|
|
<td></td>
|
|
<td></td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">heatdeg</td>
|
|
<td></td>
|
|
<td></td>
|
|
<td></td>
|
|
<td></td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td></td>
|
|
<td></td>
|
|
<td></td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">cooldeg</td>
|
|
<td></td>
|
|
<td></td>
|
|
<td></td>
|
|
<td></td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td></td>
|
|
<td></td>
|
|
<td></td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">ET</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td></td>
|
|
<td></td>
|
|
<td></td>
|
|
<td></td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">radiation</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td></td>
|
|
<td></td>
|
|
<td></td>
|
|
<td></td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">UV</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td></td>
|
|
<td></td>
|
|
<td></td>
|
|
<td></td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">extraTemp1 <br /> extraTemp2 <br />
|
|
extraTemp3
|
|
</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td></td>
|
|
<td></td>
|
|
<td></td>
|
|
<td></td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">soilTemp1 <br /> soilTemp2 <br />
|
|
soilTemp3
|
|
</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td></td>
|
|
<td></td>
|
|
<td></td>
|
|
<td></td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">leafTemp1 <br /> leafTemp2
|
|
</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td></td>
|
|
<td></td>
|
|
<td></td>
|
|
<td></td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">extraHumid1 <br /> extraHumid2
|
|
</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td></td>
|
|
<td></td>
|
|
<td></td>
|
|
<td></td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">soilMoist1 <br /> soilMoist2 <br />
|
|
soilMoist3 <br /> soilMoist4
|
|
</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td></td>
|
|
<td></td>
|
|
<td></td>
|
|
<td></td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">leafWet1 <br /> leafWet2
|
|
</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td></td>
|
|
<td></td>
|
|
<td></td>
|
|
<td></td>
|
|
</tr>
|
|
<tr>
|
|
<td class="code">rxCheckPercent</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td></td>
|
|
<td></td>
|
|
<td></td>
|
|
<td></td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<h1 id="packet_types">Appendix D: Packet Types</h1>
|
|
<p>
|
|
<em>Packets</em> are the raw data coming off the instrument (as
|
|
opposed to <em>records</em>, which are stored on the database).
|
|
The observation types available in a packet are useful when
|
|
setting <em><a href="usersguide.htm#StdQC"> quality
|
|
control rules</a></em> and when doing <em> <a
|
|
href="usersguide.htm#Calibrate"> calibrations</a></em>.
|
|
</p>
|
|
<p>
|
|
They may also be useful if you are writing your own custom
|
|
service. In particular, for subclasses of <span class="code">StdService</span>,
|
|
member function <span class="code">newLoopPacket</span> is
|
|
called when new LOOP packets arrive, and member function <span
|
|
class="code">newArchivePacket</span> is called when new
|
|
archive packets arrive. For both functions, the only argument
|
|
(besides <span class="code">self</span>) is a dictionary, where
|
|
the key is the type listed below, and the value is the
|
|
observation value.
|
|
</p>
|
|
<p>
|
|
See the guide from <em> <a
|
|
href="http://www.davisnet.com/support/weather/download/VantageSerialProtocolDocs_v250.pdf">
|
|
Vantage Pro and Pro2 Serial Communications Reference</a></em>
|
|
(available on the Davis website) for more information about
|
|
these types.
|
|
</p>
|
|
<table class="indent" style="width: 60%">
|
|
<tbody>
|
|
<tr>
|
|
<td><strong>Type</strong></td>
|
|
<td><strong>Loop packet</strong></td>
|
|
<td><strong>Archive Packet</strong></td>
|
|
<td width="15%"><strong>US</strong></td>
|
|
<td width="15%"><strong>METRIC</strong></td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="code">barometer</span></td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td><br /></td>
|
|
<td><br /></td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="code">consBatteryVoltage</span></td>
|
|
<td>X</td>
|
|
<td><br /></td>
|
|
<td>volt</td>
|
|
<td>volt</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="code">dateTime</span></td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td><br /></td>
|
|
<td><br /></td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="code">dayET</span></td>
|
|
<td>X</td>
|
|
<td><br /></td>
|
|
<td><br /></td>
|
|
<td><br /></td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="code">dayRain</span></td>
|
|
<td>X</td>
|
|
<td><br /></td>
|
|
<td>in</td>
|
|
<td>cm</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="code">dewpoint</span></td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>F</td>
|
|
<td>C</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="code">ET</span> (hourly)</td>
|
|
<td><br /></td>
|
|
<td>X</td>
|
|
<td><br /></td>
|
|
<td><br /></td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="code">extraAlarm1</span></td>
|
|
<td>X</td>
|
|
<td><br /></td>
|
|
<td><br /></td>
|
|
<td><br /></td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="code">extraAlarm2</span></td>
|
|
<td>X</td>
|
|
<td><br /></td>
|
|
<td><br /></td>
|
|
<td><br /></td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="code">extraAlarm3</span></td>
|
|
<td>X</td>
|
|
<td><br /></td>
|
|
<td><br /></td>
|
|
<td><br /></td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="code">extraAlarm4</span></td>
|
|
<td>X</td>
|
|
<td><br /></td>
|
|
<td><br /></td>
|
|
<td><br /></td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="code">extraAlarm5</span></td>
|
|
<td>X</td>
|
|
<td><br /></td>
|
|
<td><br /></td>
|
|
<td><br /></td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="code">extraAlarm6</span></td>
|
|
<td>X</td>
|
|
<td><br /></td>
|
|
<td><br /></td>
|
|
<td><br /></td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="code">extraAlarm7</span></td>
|
|
<td>X</td>
|
|
<td><br /></td>
|
|
<td><br /></td>
|
|
<td><br /></td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="code">extraAlarm8</span></td>
|
|
<td>X</td>
|
|
<td><br /></td>
|
|
<td><br /></td>
|
|
<td><br /></td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="code">extraHumid1</span></td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>%</td>
|
|
<td>%</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="code">extraHumid2</span></td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>%</td>
|
|
<td>%</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="code">extraHumid3</span></td>
|
|
<td>X</td>
|
|
<td><br /></td>
|
|
<td>%</td>
|
|
<td>%</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="code">extraHumid4</span></td>
|
|
<td>X</td>
|
|
<td><br /></td>
|
|
<td>%</td>
|
|
<td>%</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="code">extraHumid5</span></td>
|
|
<td>X</td>
|
|
<td><br /></td>
|
|
<td>%</td>
|
|
<td>%</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="code">extraHumid6</span></td>
|
|
<td>X</td>
|
|
<td><br /></td>
|
|
<td>%</td>
|
|
<td>%</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="code">extraHumid7</span></td>
|
|
<td>X</td>
|
|
<td><br /></td>
|
|
<td>%</td>
|
|
<td>%</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="code">extraTemp1</span></td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>F</td>
|
|
<td>C</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="code">extraTemp2</span></td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>F</td>
|
|
<td>C</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="code">extraTemp3</span></td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>F</td>
|
|
<td>C</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="code">extraTemp4</span></td>
|
|
<td>X</td>
|
|
<td><br /></td>
|
|
<td>F</td>
|
|
<td>C</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="code">extraTemp5</span></td>
|
|
<td>X</td>
|
|
<td><br /></td>
|
|
<td>F</td>
|
|
<td>C</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="code">extraTemp6</span></td>
|
|
<td>X</td>
|
|
<td><br /></td>
|
|
<td>F</td>
|
|
<td>C</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="code">extraTemp7</span></td>
|
|
<td>X</td>
|
|
<td><br /></td>
|
|
<td>F</td>
|
|
<td>C</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="code">forecastIcon</span></td>
|
|
<td>X</td>
|
|
<td><br /></td>
|
|
<td><br /></td>
|
|
<td><br /></td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="code">forecastRule</span></td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td><br /></td>
|
|
<td><br /></td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="code">heatIndex</span></td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>F</td>
|
|
<td>C</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="code">highOutTemp</span></td>
|
|
<td><br /></td>
|
|
<td>X</td>
|
|
<td>F</td>
|
|
<td>C</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="code">highRadiation</span></td>
|
|
<td><br /></td>
|
|
<td>X</td>
|
|
<td><br /></td>
|
|
<td><br /></td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="code">highUV</span></td>
|
|
<td><br /></td>
|
|
<td>X</td>
|
|
<td><br /></td>
|
|
<td><br /></td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="code">inHumidity</span></td>
|
|
<td>X</td>
|
|
<td><br /></td>
|
|
<td>%</td>
|
|
<td>%</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="code">inTemp</span></td>
|
|
<td>X</td>
|
|
<td><br /></td>
|
|
<td>F</td>
|
|
<td>C</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="code">interval</span></td>
|
|
<td><br /></td>
|
|
<td>X</td>
|
|
<td>minute</td>
|
|
<td>minute</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="code">insideAlarm</span></td>
|
|
<td>X</td>
|
|
<td><br /></td>
|
|
<td><br /></td>
|
|
<td><br /></td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="code">leafTemp1</span></td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>F</td>
|
|
<td>C</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="code">leafTemp2</span></td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>F</td>
|
|
<td>C</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="code">leafTemp3</span></td>
|
|
<td>X</td>
|
|
<td><br /></td>
|
|
<td>F</td>
|
|
<td>C</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="code">leafTemp4</span></td>
|
|
<td>X</td>
|
|
<td><br /></td>
|
|
<td>F</td>
|
|
<td>C</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="code">leafWet1</span></td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td><br /></td>
|
|
<td><br /></td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="code">leafWet2</span></td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td><br /></td>
|
|
<td><br /></td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="code">leafWet3</span></td>
|
|
<td>X</td>
|
|
<td><br /></td>
|
|
<td><br /></td>
|
|
<td><br /></td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="code">leafWet4</span></td>
|
|
<td>X</td>
|
|
<td><br /></td>
|
|
<td><br /></td>
|
|
<td><br /></td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="code">lowOutTemp</span></td>
|
|
<td><br /></td>
|
|
<td>X</td>
|
|
<td>F</td>
|
|
<td>C</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="code">monthET</span></td>
|
|
<td>X</td>
|
|
<td><br /></td>
|
|
<td><br /></td>
|
|
<td><br /></td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="code">monthRain</span></td>
|
|
<td>X</td>
|
|
<td><br /></td>
|
|
<td>in</td>
|
|
<td>cm</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="code">outHumidity</span></td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>%</td>
|
|
<td>%</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="code">outTemp</span></td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>F</td>
|
|
<td>C</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="code">outsideAlarm1</span></td>
|
|
<td>X</td>
|
|
<td><br /></td>
|
|
<td><br /></td>
|
|
<td><br /></td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="code">outsideAlarm2</span></td>
|
|
<td>X</td>
|
|
<td><br /></td>
|
|
<td><br /></td>
|
|
<td><br /></td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="code">radiation</span></td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td><br /></td>
|
|
<td><br /></td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="code">rain</span></td>
|
|
<td><br /></td>
|
|
<td>X</td>
|
|
<td>in</td>
|
|
<td>cm</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="code">rainAlarm</span></td>
|
|
<td>X</td>
|
|
<td><br /></td>
|
|
<td><br /></td>
|
|
<td><br /></td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="code">rainRate</span></td>
|
|
<td>X</td>
|
|
<td><br /></td>
|
|
<td>in/hr</td>
|
|
<td>cm/hr</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="code">rxCheckPercent</span></td>
|
|
<td><br /></td>
|
|
<td>X</td>
|
|
<td>%</td>
|
|
<td>%</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="code">soilLeafAlarm1</span></td>
|
|
<td>X</td>
|
|
<td><br /></td>
|
|
<td><br /></td>
|
|
<td><br /></td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="code">soilLeafAlarm2</span></td>
|
|
<td>X</td>
|
|
<td><br /></td>
|
|
<td><br /></td>
|
|
<td><br /></td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="code">soilLeafAlarm3</span></td>
|
|
<td>X</td>
|
|
<td><br /></td>
|
|
<td><br /></td>
|
|
<td><br /></td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="code">soilLeafAlarm4</span></td>
|
|
<td>X</td>
|
|
<td><br /></td>
|
|
<td><br /></td>
|
|
<td><br /></td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="code">soilMoist1</span></td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>%</td>
|
|
<td>%</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="code">soilMoist2</span></td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>%</td>
|
|
<td>%</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="code">soilMoist3</span></td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>%</td>
|
|
<td>%</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="code">soilMoist4</span></td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>%</td>
|
|
<td>%</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="code">soilTemp1</span></td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>F</td>
|
|
<td>C</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="code">soilTemp2</span></td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>F</td>
|
|
<td>C</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="code">soilTemp3</span></td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>F</td>
|
|
<td>C</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="code">soilTemp4</span></td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td>F</td>
|
|
<td>C</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="code">stormRain</span></td>
|
|
<td>X</td>
|
|
<td><br /></td>
|
|
<td><br /></td>
|
|
<td><br /></td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="code">stormStart</span></td>
|
|
<td>X</td>
|
|
<td><br /></td>
|
|
<td><br /></td>
|
|
<td><br /></td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="code">sunrise</span></td>
|
|
<td>X</td>
|
|
<td><br /></td>
|
|
<td><br /></td>
|
|
<td><br /></td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="code">sunset</span></td>
|
|
<td>X</td>
|
|
<td><br /></td>
|
|
<td><br /></td>
|
|
<td><br /></td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="code">txBatteryStatus</span></td>
|
|
<td>X</td>
|
|
<td><br /></td>
|
|
<td><br /></td>
|
|
<td><br /></td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="code">usUnits</span></td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td><br /></td>
|
|
<td><br /></td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="code">UV</span></td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td><br /></td>
|
|
<td><br /></td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="code">windChill</span></td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td><br /></td>
|
|
<td>C</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="code">windDir</span></td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td><br /></td>
|
|
<td><br /></td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="code">windGust</span></td>
|
|
<td><br /></td>
|
|
<td>X</td>
|
|
<td><br /></td>
|
|
<td>km/h</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="code">windGustDir</span></td>
|
|
<td><br /></td>
|
|
<td>X</td>
|
|
<td><br /></td>
|
|
<td><br /></td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="code">windSpeed10</span></td>
|
|
<td>X</td>
|
|
<td><br /></td>
|
|
<td><br /></td>
|
|
<td><br /></td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="code">windSpeed</span></td>
|
|
<td>X</td>
|
|
<td>X</td>
|
|
<td><br /></td>
|
|
<td>km/h</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="code">yearET</span></td>
|
|
<td>X</td>
|
|
<td><br /></td>
|
|
<td><br /></td>
|
|
<td><br /></td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="code">yearRain</span></td>
|
|
<td>X</td>
|
|
<td><br /></td>
|
|
<td><br /></td>
|
|
<td>cm</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<p class="copyright">
|
|
© <a href="copyright.htm">Copyright</a> Tom Keffer
|
|
</p>
|
|
|
|
<script type="text/javascript">
|
|
$('#toc').toc({
|
|
exclude : 'h4, h5, h6',
|
|
autoId : true,
|
|
context : '#technical_content',
|
|
numerate: true
|
|
});
|
|
|
|
</script>
|
|
</body>
|
|
</html>
|