mirror of
https://github.com/weewx/weewx.git
synced 2026-04-18 16:46:56 -04:00
10119 lines
420 KiB
HTML
10119 lines
420 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">
|
||
<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="css/ui-lightness/jquery-ui-1.10.4.custom.min.css" rel="stylesheet"/>
|
||
<link href="css/jquery.tocify.css" rel="stylesheet"/>
|
||
<link href="css/weewx_docs.css" rel="stylesheet"/>
|
||
</head>
|
||
|
||
<body>
|
||
|
||
<div class="sidebar">
|
||
<div class="doclist">
|
||
<a href="usersguide.htm">User's Guide</a><br/>
|
||
<a href="customizing.htm">Customization Guide</a><br/>
|
||
<a href="upgrading.htm">Upgrade Guide</a>
|
||
</div>
|
||
<div id="toc_controls"></div>
|
||
<div id="toc_parent">
|
||
<div id="toc">
|
||
<!-- The table of contents will be injected here -->
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="main">
|
||
|
||
<div class="header">
|
||
<div class="logoref">
|
||
<a href='http://weewx.com'>
|
||
<img src='images/logo-weewx.png' class='logo' align='right' alt="weewx logo"/>
|
||
</a><br/>
|
||
<span class='version'>
|
||
Version: 3.5.0
|
||
</span>
|
||
</div>
|
||
<div class="title"><span class="code">weewx</span> Customization Guide</div>
|
||
</div>
|
||
|
||
<div id="technical_content" class="content">
|
||
|
||
<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>
|
||
|
||
<h1 id="introduction">Introduction</h1>
|
||
|
||
<p>This document 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 <span class="code">skin.conf</span></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.</p>
|
||
|
||
<p>Most of the guide applies to any hardware, but the exact data types are
|
||
hardware-specific. Many examples use types 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. Future upgrades may
|
||
break any customizations you have done, particularly if they involve
|
||
the API (skin customizations tend to be more stable). </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>. Customization of reports may
|
||
require changes to a skin configuration file
|
||
<span class="code">skin.conf</span> or template files ending in
|
||
<span class="code">.tmpl</span>.
|
||
The <span class="code">weewx.conf</span> configuration file and the
|
||
<span class="code">skin.conf</span> configuration and template files
|
||
in the <span class='code'>skins</span> directory 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="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
|
||
file <span class="code">extensions.py</span> in the
|
||
<span class="code">user</span> directory. Because
|
||
the <span class="code">user</span> directory is preserved
|
||
through upgrades, you won't have to redo any changes you might
|
||
have made.</p>
|
||
|
||
<h2>Data architecture</h2>
|
||
|
||
<p>Weewx is data-driven. When the sensors spit out some data,
|
||
<span class="code">weewx</span> does something. The 'something'
|
||
might be to print out the data, or to generate an HTML report,
|
||
or to use FTP to copy a report to a web server, or to perform some
|
||
calculations using the data. These actions are called services.
|
||
</p>
|
||
|
||
<p>There are two
|
||
categories of data: LOOP and RECORD. The names are based on
|
||
conventions used by Davis Instruments. LOOP data are the sensor
|
||
readings, as fast as they can be obtained from the hardware. Usually
|
||
this means defining a polling interval, or doing a blocking
|
||
socket/serial read on the hardware so that the hardware itself
|
||
dictates the data collection interval. Each archive RECORD is an
|
||
aggregate of LOOP readings. If the hardware has a data logger, then
|
||
it generates the RECORD data. If not, then
|
||
<span class="code">weewx</span> generates each RECORD from LOOP data.
|
||
</p>
|
||
|
||
<p>A driver is Python code that communicates with the hardware. The driver
|
||
reads data from a serial port or a device on the USB or a network
|
||
interface. It handles any decoding of raw bits and bytes, and puts
|
||
the resulting data into LOOP packets and archive RECORDs. Whenever
|
||
possible, <span class="code">weewx</span> should work "out of the box"
|
||
with minimal configuration. However, in some cases the driver may
|
||
include code to configure and test the hardware, typically via the
|
||
<span class="code">wee_config</span> utility.</p>
|
||
|
||
<p>In many cases there are useful dependent variables that use the
|
||
primary variables emitted by the driver. For example, rain rate,
|
||
windchill, heatindex, humidex, apptemp, ET are all dependent
|
||
quantities - they require primary observations such as wind speed,
|
||
temperature, solar radiation. The firmware for some hardware
|
||
calculates dependent quantities. The <span class="code">weewx</span>
|
||
service <span class="code">StdWXCalculate</span> fills in the gaps and
|
||
determines whether to use a value from firmware or a calculation from
|
||
<span class="code">weewx</span>. Sometimes the firmware simply does
|
||
it wrong.</p>
|
||
|
||
<h2>LOOP packets <em>vs.</em> archive records</h2>
|
||
|
||
<p>Generally, there are two types of data that flow through weewx: LOOP packets, and archive records.</p>
|
||
|
||
<h3>LOOP packets</h3>
|
||
<p>LOOP packets are the raw data generated by the device driver. They get
|
||
their name from the Davis Instruments documentation. For some devices
|
||
they are generated at rigid intervals, such as every 2 seconds for the
|
||
Davis Vantage series, for others, irregularly, every 20 or 30 seconds
|
||
or so. LOOP packets may or may not contain all the data types. For
|
||
example, a packet may contain only temperature data, another only
|
||
barometric data, <em>etc.</em>. This kind of packet is called a
|
||
<em>partial record packet</em>. For other types of hardware (notably
|
||
the Vantage series), every LOOP packet contains every data type.</p>
|
||
|
||
<p>In summary, LOOP packets can be highly irregular, but they come in
|
||
frequently.</p>
|
||
|
||
<h3>Archive records</h3>
|
||
|
||
<p>By contrast, archive records are highly regular. They are generated at
|
||
regular intervals (generally every 5 to 30 minutes), and all contain
|
||
the same data types. They represent an <em>aggregation</em> of the
|
||
LOOP packets over the archive interval. The exact kind of aggregation
|
||
depends on the data type. For example, for temperature, it's generally
|
||
the average temperature over the interval. For rain, it's the sum of
|
||
rain over the interval. For battery status it's the last value in the
|
||
interval.</p>
|
||
|
||
<p>Some hardware is capable of generated its own archive records (the
|
||
Davis Vantage and Oregon Scientific WMR200 for example), but for most
|
||
hardware, weewx generates them.</p>
|
||
|
||
<p>It is the archive data that is put in the SQL database, although,
|
||
occasionally, the LOOP packets can be useful (such as for the Weather
|
||
Underground's "Rapidfire" mode, or for the
|
||
<a href="https://bitbucket.org/lirpa/mesowx">mesowx</a> realtime
|
||
display system.</p>
|
||
|
||
<h2>The weewx service 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 or archive data. The
|
||
default install of <span class="code">weewx</span> includes the
|
||
following services: </p>
|
||
<table id='default_services' class="indent" summary="Overview of the weewx architecture">
|
||
<caption>The standard weewx services</caption>
|
||
<tbody>
|
||
<tr class="first_row">
|
||
<td>Service</td>
|
||
<td>Function</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="code first_col">weewx.engine.StdTimeSynch</td>
|
||
<td>Arrange to have the clock on the station synchronized at regular
|
||
intervals.
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="code first_col">weewx.engine.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 first_col">weewx.engine.StdCalibrate</td>
|
||
<td>Adjust new LOOP and archive packets using calibration
|
||
expressions.
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="code first_col">weewx.engine.StdQC</td>
|
||
<td>Check quality of incoming data, making sure values fall within a
|
||
specified range.
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="code first_col">weewx.wxservices.StdWXCalculate</td>
|
||
<td>Calculate any missing, derived weather observation types, such a dewpoint,
|
||
windchill, or altimeter-corrected pressure.
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="code first_col">weewx.engine.StdArchive</td>
|
||
<td>Archive any new data to the SQL databases.</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="code first_col">weewx.restx.StdStationRegistry<br/>
|
||
weewx.restx.StdWunderground<br/>
|
||
weewx.restx.StdPWSweather<br/>
|
||
weewx.restx.StdCWOP<br/>
|
||
weewx.restx.StdWOW<br/>weewx.restx.StdAWEKAS
|
||
</td>
|
||
<td>Various <a href="http://en.wikipedia.org/wiki/Representational_State_Transfer">
|
||
RESTful services</a> (simple stateless client-server protocols),
|
||
such as the Weather Underground, CWOP, etc. Each launches its own, independent
|
||
thread, which manages the post.
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="code first_col">weewx.engine.StdPrint</td>
|
||
<td>Print out new LOOP and archive packets on the console.</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="code first_col">weewx.engine.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>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.engine.StdReport</span>,
|
||
the standard service for creating reports. This will be what most users
|
||
will want to customize, even if it means just changing 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" summary="Standard reports included in weewx">
|
||
<tbody>
|
||
<tr class="first_row">
|
||
<td>Report</td>
|
||
<td>Default functionality</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="code first_col">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 first_col">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 first_col">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 called
|
||
<span class='code'>skins</span> and referred to as
|
||
<a href="#" id="skin-root-description-target">
|
||
<span class="symcode">SKIN_ROOT</span></a>.
|
||
</p>
|
||
|
||
<div id="skin-root-description" title="SKIN_ROOT" style="display:none">
|
||
<p>The symbol <span class='code'>SKIN_ROOT</span> is a symbolic name
|
||
to the location of the directory where
|
||
your skins are located. It is not to be taken literally. Consult the
|
||
<a href="usersguide.htm#dir-layout-table">directory layout table</a>
|
||
in the User's Guide for its exact location, dependent on how you
|
||
installed weewx and what operating system you are using</p></div>
|
||
<script type="text/javascript">
|
||
$("#skin-root-description-target").click(
|
||
function () {
|
||
$("#skin-root-description").dialog({
|
||
position: {
|
||
my: "left top",
|
||
at: "right bottom",
|
||
of: "#skin-root-description-target"
|
||
}
|
||
});
|
||
return false; // Insures that the "link" isn't followed
|
||
});
|
||
</script>
|
||
|
||
<h3>Generators</h3>
|
||
|
||
<p>
|
||
To create their output, skins rely on one or more <em>Generators</em>,
|
||
which are what do the actual work, such as creating 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" summary="Generators included in weewx">
|
||
<tbody>
|
||
<tr class="first_row">
|
||
<td>Generator</td>
|
||
<td>Function</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="code first_col">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 first_col">weewx.imagegenerator.ImageGenerator</td>
|
||
<td>Generates graph plots.</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="code first_col">weewx.reportengine.FtpGenerator</td>
|
||
<td>Uploads data to a remote server using FTP.</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="code first_col">weewx.reportengine.RsyncGenerator</td>
|
||
<td>Uploads data to a remote server using rsync.</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="code first_col">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_section"><span class="code">[Generators]</span></a>.</p>
|
||
|
||
<h3>Templates</h3>
|
||
|
||
<p>
|
||
A template is a text file that is processed by a <em>template engine</em>
|
||
to create a new file. <span class="code">Weewx</span>
|
||
uses the <a href="http://www.cheetahtemplate.org">Cheetah</a>
|
||
template engine. The generator <span class="code">weewx.cheetahgenerator.CheetahGenerator</span>
|
||
is responsible for running Cheetah at appropriate times.
|
||
</p>
|
||
|
||
<p>A template may be used to generate HTML, XML, CSV,
|
||
Javascript, or any other type of text file. A template typically
|
||
contains variables that are replaced when creating the new file.
|
||
Templates may also contain simple programming logic.</p>
|
||
|
||
<p>
|
||
Each template file lives in the skin directory of the skin that
|
||
uses it. By convention, a template file ends with the <span
|
||
class="code">.tmpl</span> extension.
|
||
</p>
|
||
|
||
<h2 id="wee_reports">The tool wee_reports</h2>
|
||
|
||
<p>If you make changes, how do you know what the results will look like?
|
||
You could just run weewx and wait until the next reporting cycle kicks
|
||
off but, depending on your archive interval, that could be a 30 minute
|
||
wait or more.</p>
|
||
|
||
<p>The tool <span class="code">wee_reports</span> allows you to run a
|
||
report whenever you like. To use it, just run it from a command line,
|
||
with the location of your configuration file
|
||
<span class="code">weewx.conf</span> as the first argument. Optionally,
|
||
if you include a unix epoch timestamp as a second argument, then the
|
||
report will use that as the "Current" time; otherwise, the time of the
|
||
last record in the archive database will be used. Here is an example,
|
||
using 1 May 2014 00:00 PDT as the "Current" time.</p>
|
||
<pre class="tty"><span class="cmd">wee_reports weewx.conf 1398927600</span></pre>
|
||
|
||
<h2>The database</h2>
|
||
|
||
<p>
|
||
<span class='code'>Weewx</span> uses a single database to store and retrieve the records it needs.
|
||
It can be implemented by using either
|
||
<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.
|
||
</p>
|
||
|
||
<h3>Structure</h3>
|
||
|
||
<p>
|
||
Inside this database are several tables. The most important is the
|
||
<em>archive table</em>, a big flat table, holding one record for each
|
||
archive interval, keyed by <span class="code">dateTime</span>, the
|
||
time at the end of the archive interval. It looks something like this:
|
||
</p>
|
||
|
||
<table class="indent fixed_width">
|
||
<caption>Structure of the <span class="code">archive</span> database table</caption>
|
||
<tr class="code first_row">
|
||
<td>dateTime</td>
|
||
<td>usUnits</td>
|
||
<td>interval</td>
|
||
<td>barometer</td>
|
||
<td>pressure</td>
|
||
<td>altimeter</td>
|
||
<td>inTemp</td>
|
||
<td>outTemp</td>
|
||
<td>...</td>
|
||
</tr>
|
||
|
||
<tr class="code">
|
||
<td>1413937800</td>
|
||
<td>1</td>
|
||
<td>5</td>
|
||
<td>29.938</td>
|
||
<td><i>null</i></td>
|
||
<td><i>null</i></td>
|
||
<td>71.2</td>
|
||
<td>56.0</td>
|
||
<td>...</td>
|
||
</tr>
|
||
<tr class="code">
|
||
<td>1413938100</td>
|
||
<td>1</td>
|
||
<td>5</td>
|
||
<td>29.941</td>
|
||
<td><i>null</i></td>
|
||
<td><i>null</i></td>
|
||
<td>71.2</td>
|
||
<td>55.9</td>
|
||
<td>...</td>
|
||
</tr>
|
||
<tr class="code">
|
||
<td>...</td>
|
||
<td>...</td>
|
||
<td>...</td>
|
||
<td>...</td>
|
||
<td>...</td>
|
||
<td>...</td>
|
||
<td>...</td>
|
||
<td>...</td>
|
||
<td>...</td>
|
||
</tr>
|
||
</table>
|
||
|
||
<p>The first three columns are <em>required.</em> Here's what they mean:</p>
|
||
<table class="indent">
|
||
<tr class="first_row">
|
||
<td>Name</td>
|
||
<td>Meaning</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col"><span class="code">dateTime</span></td>
|
||
<td>The time at the end of the archive interval in <a
|
||
href="http://en.wikipedia.org/wiki/Unix_time">unix epoch
|
||
time</a>. This is the <em>primary key</em> in the database. It
|
||
must be unique, and it cannot be null.
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col"><span class="code">usUnits</span></td>
|
||
<td>The unit system the record is in. It cannot be null. See the
|
||
<em><a href="#units">Appendix: Units</a></em> for how these
|
||
systems are encoded.
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col"><span class="code">interval</span></td>
|
||
<td>The length of the archive interval in <em>minutes</em>.
|
||
It cannot be null.
|
||
</td>
|
||
</tr>
|
||
</table>
|
||
|
||
<p>
|
||
In addition to the main archive table, there are a number of
|
||
smaller tables inside the database, one for each observation type,
|
||
that hold <em>daily summaries</em> of the type. For example, the
|
||
minimum and maximum value seen during the day, and at what time.
|
||
These tables have names such as <span class="code">archive_day_outTemp</span>
|
||
or <span class="code">archive_day_barometer</span>. Their existence
|
||
is generally transparent to the user.
|
||
</p>
|
||
|
||
<h3 id="binding_names">Binding names</h3>
|
||
|
||
<p>
|
||
While most users will only need the one weather database that comes with <span
|
||
class="code">weewx</span>, the reporting engine allows you to use
|
||
multiple databases in the same report. For example, if you have installed
|
||
the <a href="https://github.com/weewx/weewx/wiki/cmon"><span
|
||
class="code">cmon</span></a> computer monitoring package, which uses its own
|
||
database, you may want to include some statistics or graphs about your
|
||
server in your reports, using that database.
|
||
</p>
|
||
|
||
<p>
|
||
An additional complication is that <span class="code">weewx</span> can use
|
||
more than one database implementation: SQLite or MySQL. Making
|
||
users specify in the templates not only which database to use,
|
||
but also which implementation, would be unreasonable.
|
||
</p>
|
||
|
||
<p>
|
||
The solution, like so many other problems in computer science, is to introduce
|
||
another level of indirection, a <em>database binding</em>. Rather than
|
||
specify which database to use, you specify which <em>binding</em> to use.
|
||
Bindings do not change with the database implementation, so, for example,
|
||
you know that <span class="code">wx_binding</span> will always point to
|
||
the weather database. Bindings are listed in section <a
|
||
href="usersguide.htm#DataBindings"><span class="code">[DataBindings]</span></a>
|
||
in <span class="code">weewx.conf</span>.
|
||
</p>
|
||
|
||
<p>
|
||
The standard weather database binding that <span class="code">weewx</span>
|
||
uses is <span class="code">wx_binding</span>. This is the binding that you
|
||
will be using most of the time and, indeed, it is the default. You rarely
|
||
have to specify it explicitly.
|
||
</p>
|
||
|
||
<h3>Programming interface</h3>
|
||
|
||
<p><span class='code'>weewx</span> includes a module called
|
||
<span class='code'>weedb</span> that provides a single interface for
|
||
many of the differences between database implementations such as SQLite
|
||
and MySQL. However, it is not uncommon to make direct SQL queries
|
||
within services or search list extensions. In such cases, the SQL
|
||
should be generic so that it will work with every type of database.</p>
|
||
|
||
<p>The database manager class provides methods to create, open, and
|
||
query a database. These are the canonical forms for obtaining a
|
||
database manager.</p>
|
||
|
||
<p>If you are opening a database from within a weewx service:</p>
|
||
<pre class='tty'>db_manager = self.engine.db_binder.get_manager(data_binding='name_of_binding', initialize=True)
|
||
|
||
# Sample query:
|
||
db_manager.getSql("SELECT SUM(rain) FROM %s "\
|
||
"WHERE dateTime>? AND dateTime<=?" % db_manager.table_name, (start_ts, stop_ts))</pre>
|
||
<p>If you are opening a database from within a weewx search list extension, you
|
||
will be passed in a function <span class="code">db_lookup()</span> as a parameter, which can
|
||
be used to bind to a database. By default, it returns a manager
|
||
bound to <span class="code">wx_binding</span>:</p>
|
||
<pre class='tty'>wx_manager = db_lookup() # Get default binding
|
||
other_manager = db_lookup(data_binding='some_other_binding') # Get an explicit binding
|
||
|
||
# Sample queries:
|
||
wx_manager.getSql("SELECT SUM(rain) FROM %s "\
|
||
"WHERE dateTime>? AND dateTime<=?" % wx_manager.table_name, (start_ts, stop_ts))
|
||
other_manager.getSql("SELECT SUM(power) FROM %s"\
|
||
"WHERE dateTime>? AND dateTime<=?" % other_manager.table_name, (start_ts, stop_ts))</pre>
|
||
<p>If opening a database from somewhere other than a service, and there
|
||
is no <span class="code">DBBinder</span> available:</p>
|
||
<pre class='tty'>db_manager = weewx.manager.open_manager_with_config(config_dict, data_binding='name_of_binding')
|
||
|
||
# Sample query:
|
||
db_manager.getSql("SELECT SUM(rain) FROM %s "\
|
||
"WHERE dateTime>? AND dateTime<=?" % db_manager.table_name, (start_ts, stop_ts))</pre>
|
||
<p>The <span class="code">DBBinder</span> caches managers, and thus database connections. It cannot
|
||
be shared between threads.</p>
|
||
|
||
<h2>Units</h2>
|
||
|
||
<p>The unit architecture in <span class='code'>weewx</span> is designed to
|
||
make basic unit conversions and display of units easy. It is not
|
||
designed to provide dimensional analysis, arbitrary conversions, and
|
||
indications of compatibility.</p>
|
||
|
||
<p>The <em>driver</em> reads observations from an instrument and converts
|
||
them, as necessary, into a standard set of units. The actual units
|
||
used by each instrument vary widely; some instruments use Metric
|
||
units, others use US Customary units, and many use a mixture. The
|
||
driver ensures that the units are consistent for storage in the
|
||
<span class='code'>weewx</span> database. By default, and to maintain
|
||
compatibility with <span class='code'>wview</span>, the database
|
||
units are US Customary.</p>
|
||
|
||
<p>Much of the <span class='code'>weewx</span> unit architecture is focused
|
||
on presenting data with the appropriate units. Although the units of the
|
||
data in the database are US Customary, they can be displayed in any
|
||
combination of unit systems.</p>
|
||
|
||
<p>Each <em>observation type</em> such as <span class='code'>outTemp</span>
|
||
or <span class='code'>pressure</span> may be associated with a
|
||
<em>unit group</em> such as <span class='code'>group_temperature</span> or
|
||
<span class='code'>group_pressure</span>. Each
|
||
unit group is associated with a <em>unit type</em> such
|
||
as <span class='code'>degree_F</span> or
|
||
<span class='code'>mbar</span>. The
|
||
<a href="#customizing_templates">template system</a>
|
||
uses this architecture to display the names of units and to convert
|
||
observations from one unit to another.</p>
|
||
|
||
<p>With this architecture one can easily create reports with, say, wind
|
||
measured in knots, rain measured in mm, and temperatures in degree
|
||
Celsius. Or one can create a single set of templates, but display
|
||
data in different unit systems with only a few stanzas in a configuration
|
||
file.</p>
|
||
|
||
<h1 id="customizing_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
|
||
<span class="code">skin.conf</span>.</p>
|
||
|
||
<p>Each skin will have a <span class="code">skin.conf</span> that defines
|
||
its default configuration. The examples in this guide refer to the
|
||
standard skin that comes with the distribution.</p>
|
||
|
||
<h3>
|
||
Changing options in <span class="code">skin.conf</span>
|
||
</h3>
|
||
|
||
<p>
|
||
With this approach, edit the skin configuration file with a text
|
||
editor. Changes made in this way will be used by <span
|
||
class="code">weewx</span> the next time it generates reports,
|
||
which is typically the next archive interval; there is no need to
|
||
restart <span class="code">weewx</span> to see the results of the
|
||
changes.
|
||
</p>
|
||
|
||
<p>
|
||
For the standard skin that comes with <span class="code">weewx</span>,
|
||
the file is <span class="code">skins/Standard/skin.conf</span>.
|
||
It includes many, many options that can be changed. For a complete list,
|
||
see the section <em><a href="#standard_skin">The Standard <span class="code">skin.conf</span></a></em>.
|
||
</p>
|
||
|
||
<p>
|
||
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_hour
|
||
group_speed2 = mile_per_hour2
|
||
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 the
|
||
<em><a href="#units">Appendix: 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 <a href="#Labels_Generic"><span class="code">[Labels][[Generic]]</span></a>
|
||
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>With this approach, you must restart <span class="code">weewx</span>
|
||
to see the effects of any changes.</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
|
||
</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 second (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="customizing_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 after an upgrade.</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 a
|
||
template file that contains:</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 generated 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 most general dot code for a "current" observation looks like: </p>
|
||
<pre class="tty">$current($data_binding=<em>binding_name</em>).<em>obstype</em>[.<em>optional_unit_conversion</em>][.<em>optional_formatting</em>]</pre>
|
||
<p>Where:</p>
|
||
|
||
<p class="indent">
|
||
<span class="code">binding_name</span> is a <em>binding name</em>
|
||
to a database. An example would be <span class="code">wx_binding</span>.
|
||
See the section <em><a href="#binding_names">Binding names</a></em>
|
||
for more details.
|
||
</p>
|
||
|
||
<p class="indent">
|
||
<span class="code">obstype</span> is an observation type, such as
|
||
<span class="code">barometer</span>. See
|
||
<em><a href="#archive_types">Appendix: 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>.
|
||
</p>
|
||
|
||
<p class="indent">
|
||
<span class="code">optional_formatting</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>.
|
||
</p>
|
||
|
||
<h3>Time period <span class="code">$latest</span></h3>
|
||
|
||
<p>Time period <span class="code">$latest</span> is very similar
|
||
to <span class="code">$current</span>, except that it uses
|
||
the last available timestamp in a database. Usually,
|
||
<span class="code">$current</span> and <span class="code">$latest</span> are the same,
|
||
but if a data binding points to a remote database, they may not be. See
|
||
the section <em><a href="#stupid_detail">Using multiple bindings</a></em>
|
||
for an example where this happened.</p>
|
||
|
||
<h3 id="general_aggregation_periods">Aggregation periods</h3>
|
||
|
||
<p>A dot code such as</p>
|
||
<pre class="tty">$week.rain.sum</pre>
|
||
<p>represents an <em>aggregation over time</em>, using a certain <em>aggregation type</em>.
|
||
In this example, the aggregation time is a week, and the aggregation type is summation.
|
||
So, this tag represents the total rainfall over a week.
|
||
</p>
|
||
|
||
<p>The most general dot code for an aggregation over time looks like:</p>
|
||
<pre class="tty">$<em>period</em>($data_binding=<em>binding_name</em>).<em>statstype</em>.<em>aggregation</em>[.<em>optional_unit_conversion</em>][.<em>optional_formatting</em>]</pre>
|
||
<p>Where:</p>
|
||
|
||
<p class="indent">
|
||
<span class="code">period</span> is the time period over which
|
||
the aggregation is to be done. Possible choices are listed in a table below.
|
||
</p>
|
||
|
||
<p class="indent">
|
||
<span class="code">binding_name</span> is a <em>binding name</em>
|
||
to a database. An example would be <span class="code">wx_binding</span>.
|
||
See the section <em><a href="#binding_names">Binding names</a></em>
|
||
for more details.
|
||
</p>
|
||
|
||
<p class="indent">
|
||
<span class="code">statstype</span> is a <em>statistical type</em>. This
|
||
is generally any observation type that appears in the database, as well
|
||
as a few synthetic types (such as heating and cooling degree-days). Not
|
||
all aggregations are supported for all types.
|
||
</p>
|
||
|
||
<p class="indent">
|
||
<span class="code">aggregation</span> is an <em>aggregation type</em>.
|
||
If you
|
||
ask for <span class="code">$month.outTemp.avg</span> you are asking for
|
||
the <em>average</em> outside temperature for the month. Possible
|
||
aggregation types are given in
|
||
<em><a href="#aggregation_types">Appendix: Aggregation types</a></em>.
|
||
</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>.
|
||
</p>
|
||
|
||
<p class="indent">
|
||
<span class="code">optional_formatting</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>.
|
||
</p>
|
||
|
||
<p>
|
||
There are several different <em>aggregation periods</em> that can be used:
|
||
</p>
|
||
<table class="indent" style="width:80%">
|
||
<tbody>
|
||
<tr class="first_row">
|
||
<td><em>Aggregation period</em></td>
|
||
<td>Example</td>
|
||
<td>Meaning</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col code">$hours_ago($hours_ago=<i>h</i>)</td>
|
||
<td class="code">$hours_ago($hours_ago=1).outTemp.avg</td>
|
||
<td>The average temperature last hour (1 hour ago).</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col code">$hour</td>
|
||
<td class="code">$hour.outTemp.maxtime</td>
|
||
<td>The time of the maximum temperature this hour.</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col code">$day</td>
|
||
<td class="code">$day.outTemp.max</td>
|
||
<td>Max temperature since midnight today.</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col code">$days_ago($days_ago=<i>d</i>)</td>
|
||
<td class="code">$days_ago($days_ago=2).outTemp.avg</td>
|
||
<td>The average temperature day before yesterday (2 days ago).</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col code">$yesterday</td>
|
||
<td class="code">$yesterday.outTemp.maxtime</td>
|
||
<td>The time of yesterday's maximum temperature.</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col code">$week</td>
|
||
<td class="code">$week.outTemp.max</td>
|
||
<td>This week's max temperature. The start of the week is set by option
|
||
<a href="usersguide.htm#week_start"><span class="code">week_start</span></a></td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col code">$month</td>
|
||
<td class="code">$month.outTemp.min</td>
|
||
<td>The minimum temperature since the start of the month.</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col code">$year</td>
|
||
<td class="code">$year.outTemp.max</td>
|
||
<td>The max temperature since the start of the year.</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col code">$rainyear</td>
|
||
<td class="code">$rainyear.rain.sum</td>
|
||
<td>The total rainfall for this rain year. The start of the rain year is
|
||
set by option <a href="usersguide.htm#rain_year_start"><span class="code">rain_year_start</span></a>.
|
||
</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<h3 id="unit_conversion_options">Unit conversion options</h3>
|
||
|
||
<p>The tag <span class="code">optional_unit_conversion</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 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 or nonsense conversion is asked for, <em>e.g.</em>, </p>
|
||
<pre class="tty">Today's minimum pressure in mbars: $day.barometer.min.mbar
|
||
or in degrees C: $day.barometer.min.degree_C
|
||
or in foobar units: $day.barometer.min.foobar
|
||
</pre>
|
||
<p>then the offending tag(s) will be put in the output: </p>
|
||
|
||
<p class="example_output">Today's minimum pressure in mbars: 1015.3<br/>
|
||
or in degrees C: $day.barometer.min.degree_C<br/>
|
||
or in foobar units: $day.barometer.min.foobar
|
||
</p>
|
||
|
||
<h3 id="formatting_options">Formatting options</h3>
|
||
|
||
<p>The tag <span class="code">optional_formatting</span> can be
|
||
used with either current observations or aggregations. It can be one of:
|
||
</p>
|
||
<table class="indent" summary="Formatting Options">
|
||
<caption>Optional formatting tags</caption>
|
||
<tbody>
|
||
<tr class="first_row">
|
||
<td>Optional formatting tag</td>
|
||
<td>Comment</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='text_highlight'>(no tag)</td>
|
||
<td>Value is returned as a string, formatted using an appropriate
|
||
string format from <span class="code">skin.conf</span>. A unit
|
||
label (e.g., <span class='code'>°F</span>) from <span class="code">skin.conf</span> is also attached
|
||
at the end.
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="code text_highlight">.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 (e.g., <span class='code'>°F</span>)
|
||
from <span class="code">skin.conf</span> will be attached at the end.
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="code text_highlight"><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 unit label will be attached.
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="code text_highlight">.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 (e.g., <span class='code'>°F</span>)
|
||
from <span class="code">skin.conf</span> will be attached at the end.
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="code text_highlight">.nolabel(<em>string_format, 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. No unit label will be attached at the end.
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="code text_highlight"><span class="code">.raw</span></td>
|
||
<td>Value is returned "as is" without being converted to a string
|
||
and without any formatting applied. This can be useful for doing
|
||
arithmetic directly within the templates. 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> </p>
|
||
<table class="indent" summary="Summary of formatting options">
|
||
<caption>Summary of formatting options</caption>
|
||
<tbody>
|
||
<tr class="first_row">
|
||
<td>Formatting Tag</td>
|
||
<td>Format Used</td>
|
||
<td>Label Used</td>
|
||
<td>NONE String</td>
|
||
<td>Returned Value</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col">(no tag)</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 first_col">.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 first_col">.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 first_col">.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 first_col">.nolabel</td>
|
||
<td>User-supplied</td>
|
||
<td>No label</td>
|
||
<td>Optional user-supplied</td>
|
||
<td>string</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="code first_col">.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">
|
||
<caption>Formatting options with expected results</caption>
|
||
<tbody>
|
||
<tr class="first_row">
|
||
<td>Tag</td>
|
||
<td>Result</td>
|
||
<td>Comment</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="code first_col">$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 first_col">$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 first_col">$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 first_col">$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 first_col">$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 first_col">$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 first_col">$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 first_col">$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 first_col">$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 first_col">$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 first_col">$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 first_col">$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 first_col">$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 first_col">$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 first_col">$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 first_col">$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 first_col">$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 first_col">$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 first_col">$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>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.</p>
|
||
|
||
<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</p>
|
||
<pre class="tty">$current.dateTime</pre>
|
||
<p>represents the <em>current time</em> (more properly, the time as of the end of the last archive
|
||
interval) and would produce something like</p>
|
||
<pre class="example_output">09-Jan-2010 12:50</pre>
|
||
<p> 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>
|
||
|
||
<p> For example, </p>
|
||
<pre class="tty">$month.dateTime</pre>
|
||
<p>produces</p>
|
||
|
||
<pre class="example_output">09-Jan-2010</pre>
|
||
<p>while</p>
|
||
<pre class="tty">$month.dateTime.format("%B %Y")</pre>
|
||
<p>produces</p>
|
||
|
||
<p class="example_output">January 2010</p>
|
||
|
||
<p>The returned string value will always be in <em>local time</em>. However, if you ask
|
||
for the raw value</p>
|
||
<pre class="tty">$current.dateTime.raw</pre>
|
||
|
||
<p>the returned value will be in 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. 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 changes in barometric pressure. Here are some examples:</p>
|
||
<table class="indent" style="width: 50%" summary="Examples of using unit formats">
|
||
<tbody>
|
||
<tr class="first_row">
|
||
<td>Tag</td>
|
||
<td>Results</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="code first_col">$trend.barometer</td>
|
||
<td class="code">-.05 inHg</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="code first_col">$trend($time_delta=3600).barometer</td>
|
||
<td class="code">-.02 inHg</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="code first_col">$trend.outTemp</td>
|
||
<td class="code">1.1 °C</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="code first_col">$trend.time_delta</td>
|
||
<td class="code">10800 secs</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="code first_col">$trend.time_delta.hour</td>
|
||
<td class="code">3 hrs</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<p>
|
||
Note how you can explicitly specify a value in the tag itself (2nd
|
||
example above). If you do not specify a value, then a default time
|
||
interval, set by option <span class="code"><a href="#trend">time_delta</a></span>
|
||
in the skin configuration file, will be used. This value can be retrieved
|
||
by using the syntax <span class="code">$trend.time_delta</span> (3rd
|
||
example above).
|
||
</p>
|
||
|
||
<p>For example, the template expression</p>
|
||
<pre class="tty">The barometer trend over $trend.time_delta.hour is $trend.barometer.format("%+.2f")</pre>
|
||
<p>would result in</p>
|
||
|
||
<p class="example_output">The barometer trend over 3 hrs is +.03 inHg.</p>
|
||
|
||
<h3>Tag <span class="code">$span</span></h3>
|
||
|
||
<p>The tag <span class="code">$span</span> allows aggregation over a user defined
|
||
period up to and including the current time. The most general dot code for a <span class="code">$span</span> tag looks like:</p>
|
||
|
||
<pre class="tty">$<em>span</em>([$data_binding=<em>binding_name</em>][,$optional_delta=<em>delta</em>]).<em>obstype</em>.<em>aggregation</em>[.<em>optional_unit_conversion</em>][.<em>optional_formatting</em>]</pre>
|
||
|
||
<p>Where:</p>
|
||
<p class="indent">
|
||
<span class="code">binding_name</span> is a <em>binding name</em>
|
||
to a database. An example would be <span class="code">wx_binding</span>.
|
||
See the section <em><a href="#binding_names">Binding names</a></em>
|
||
for more details.
|
||
</p>
|
||
|
||
<p class="indent">
|
||
<span class="code">$optional_delta=<em>delta</em></span> is one or more comma separated delta settings from the table below. If more than one delta setting is included then the period used for the aggregate is the sum of the individual delta settings. If no delta setting is included, or all included delta settings are zero, the returned aggregate is based on the current <span class="code">obstype</span> only.
|
||
</p>
|
||
|
||
<p class="indent">
|
||
<span class="code">obstype</span> is a observation type, such as <span class="code">outTemp</span>, that is supported by the <span class="code">$current</span> tag. See
|
||
<em><a href="#archive_types">Appendix: Archive Types</a></em> for a table of observation types
|
||
supported by the <span class="code">$current</span> tag.
|
||
</p>
|
||
|
||
<p class="indent">
|
||
<span class="code">aggregation</span> is an <em>aggregation type</em>.
|
||
Possible aggregation types are given in <em><a href="#aggregation_types">
|
||
Appendix: Aggregation types</a></em>.
|
||
</p>
|
||
|
||
<p class="indent">
|
||
<span class="code">optional_unit_conversion</span> is an optional unit
|
||
conversion tag. See the section <em><a href="#unit_conversion_options">
|
||
Unit Conversion Options</a></em>.
|
||
</p>
|
||
|
||
<p class="indent">
|
||
<span class="code">optional_formatting</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>.
|
||
</p>
|
||
<p>There are several different delta settings that can be used:</p>
|
||
<table class="indent" style="width:80%">
|
||
<tbody>
|
||
<tr class="first_row">
|
||
<td><em>Delta Setting</em></td>
|
||
<td>Example</td>
|
||
<td>Meaning</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col code">$time_delta=<i>seconds</i></td>
|
||
<td class="code">$span($time_delta=1800).outTemp.avg</td>
|
||
<td>The average temperature over the last immediate 30 minutes (1800 seconds).</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col code">$hour_delta=<i>hours</i></td>
|
||
<td class="code">$span($hour_delta=6).outTemp.avg</td>
|
||
<td>The average temperature over the last immediate 6 hours.</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col code">$day_delta=<i>days</i></td>
|
||
<td class="code">$span($day_delta=1).rain.sum</td>
|
||
<td>The total rainfall over the last immediate 24 hours.</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col code">$week_delta=<i>weeks</i></td>
|
||
<td class="code">$span($week_delta=2).barometer.max</td>
|
||
<td>The maximum barometric pressure over the last immediate 2 weeks.</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
|
||
<p>For example, the template expressions</p>
|
||
<pre class="tty">The total rainfall over the last 30 hours is $span($hour_delta=30).rain.sum</pre>
|
||
<p>and</p>
|
||
<pre class="tty">The total rainfall over the last 30 hours is $span($hour_delta=6, $day_delta=1).rain.sum</pre>
|
||
<p>would both result in</p>
|
||
|
||
<p class="example_output">The total rainfall over the last 30 hours is 1.24 in</p>
|
||
|
||
<h3>Tag <span class="code">$unit</span></h3>
|
||
|
||
<p>The type, label, and string formats for all units are also available, allowing
|
||
you to do highly customized labels: </p>
|
||
<table class="indent" style="width: 50%" summary="Examples of using unit formats">
|
||
<tbody>
|
||
<tr class="first_row">
|
||
<td>Tag</td>
|
||
<td>Results</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="code first_col">$unit.unit_type.outTemp</td>
|
||
<td class="code">degree_C</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="code first_col">$unit.label.outTemp</td>
|
||
<td class="code">°C</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="code first_col">$unit.format.outTemp</td>
|
||
<td class="code">%.1f</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<p>For example, the tag </p>
|
||
<pre class="tty">$day.outTemp.max.formatted$unit.label.outTemp</pre>
|
||
<p>would result in </p>
|
||
|
||
<p class="example_output">21.2°C</p>
|
||
|
||
<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>
|
||
Tag <span class="code">$obs</span>
|
||
</h3>
|
||
|
||
<p>
|
||
The labels used for the various observation types are available using tag
|
||
<span class="code">$obs</span>. These are basically the values given in
|
||
the skin dictionary, section <a href="#Labels_Generic"><span
|
||
class="code">[Labels][[Generic]]</span></a>.
|
||
</p>
|
||
<table class="indent" style="width: 50%"
|
||
summary="Example off using observation labels">
|
||
<tbody>
|
||
<tr class="first_row">
|
||
<td>Tag</td>
|
||
<td>Results</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="code first_col">$obs.label.outTemp</td>
|
||
<td class="code">Outside Temperature</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="code first_col">$obs.label.UV</td>
|
||
<td class="code">UV Index</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
|
||
|
||
<h3>Iteration</h3>
|
||
|
||
<p>It is possible to iterate over the following time periods:</p>
|
||
|
||
<table class="indent" style="Width: 50%"
|
||
summary="Iteration periods">
|
||
<tbody>
|
||
<tr class="first_row">
|
||
<td>Tag suffix</td>
|
||
<td>Results</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="code first_col">.hours</td>
|
||
<td>Iterate by hours</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="code first_col">.days</td>
|
||
<td>Iterate by days</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="code first_col">.months</td>
|
||
<td>Iterate by months</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="code first_col">.years</td>
|
||
<td>Iterate by years</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
|
||
<p>For example, the following template 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">Min, max temperatures by month
|
||
<span class="highlight">#for $month in $year.months</span>
|
||
$month.dateTime.format("%B"): Min, max temperatures: $month.outTemp.min $month.outTemp.max
|
||
<span class="highlight">#end for</span></pre>
|
||
<p>The result is:</p>
|
||
|
||
<p class="example_output">Min, max temperatures by month:<br/>
|
||
January: Min, max temperatures: 30.1°F 51.5°F<br/>
|
||
February: Min, max temperatures: 24.4°F 58.6°F<br/>
|
||
March: Min, max temperatures: 27.3°F 64.1°F<br/>
|
||
April: Min, max temperatures: 33.2°F 52.5°F<br/>
|
||
May: Min, max temperatures: N/A N/A<br/>
|
||
June: Min, max temperatures: N/A N/A<br/>
|
||
July: Min, max temperatures: N/A N/A<br/>
|
||
August: Min, max temperatures: N/A N/A<br/>
|
||
September: Min, max temperatures: N/A N/A<br/>
|
||
October: Min, max temperatures: N/A N/A<br/>
|
||
November: Min, max temperatures: N/A N/A<br/>
|
||
December: Min, max temperatures: N/A N/A</p>
|
||
|
||
<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 an example template:</p>
|
||
|
||
<pre class="tty">Current time is $current.dateTime
|
||
#if $almanac.hasExtras
|
||
Sunrise, transit, sunset: $almanac.sun.rise $almanac.sun.transit $almanac.sun.set
|
||
Moonrise, transit, moonset: $almanac.moon.rise $almanac.moon.transit $almanac.moon.set
|
||
Mars rise, transit, set: $almanac.mars.rise $almanac.mars.transit $almanac.mars.set
|
||
Azimuth, altitude of mars: $almanac.mars.az $almanac.mars.alt
|
||
Next new, full moon: $almanac.next_new_moon $almanac.next_full_moon
|
||
Next summer, winter solstice: $almanac.next_summer_solstice $almanac.next_winter_solstice
|
||
#else
|
||
Sunrise, sunset: $almanac.sunrise $almanac.sunset
|
||
#end if</pre>
|
||
|
||
<p>If pyephem is installed this would result in: </p>
|
||
|
||
<p class="example_output">Current time is 29-Mar-2011 09:20<br/>
|
||
Sunrise, transit, sunset: 06:51 13:11 19:30<br/>
|
||
Moonrise, transit, moonset: 04:33 09:44 15:04<br/>
|
||
Mars rise, transit, set: 06:35 12:30 18:26<br/>
|
||
Azimuth, altitude of mars: 124.354959275 26.4808431952<br/>
|
||
Next new, full moon: 03-Apr-2011 07:32 17-Apr-2011 19:43<br/>
|
||
Next summer, winter solstice: 21-Jun-2011 10:16 21-Dec-2011 21:29</p>
|
||
|
||
<p>Otherwise, a fallback of basic calculations is used, resulting in:</p>
|
||
|
||
<p class="example_output">Current time is 29-Mar-2011 09:20<br/>
|
||
Sunrise, sunset: 06:51 19:30</p>
|
||
|
||
<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" style="width:60%">
|
||
<caption>Calendar events</caption>
|
||
<tbody class="code">
|
||
<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 possible values for the <span class="code">attribute</span> tag
|
||
are listed in the following table:</p>
|
||
<table class="indent" style="width: 80%">
|
||
<caption>Attributes that can be used with heavenly bodies</caption>
|
||
<tbody class="code">
|
||
<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>
|
||
|
||
|
||
<h3>Wind</h3>
|
||
|
||
<p>
|
||
Wind deserves a few comments because it is stored in the database in two
|
||
different ways: as a set of scalars, and as a <em>vector</em> of speed and
|
||
direction. Here are the four wind-related scalars stored in the main archive
|
||
database:
|
||
</p>
|
||
<table class="indent">
|
||
<tbody>
|
||
<tr class="first_row">
|
||
<td><em>Archive type</em></td>
|
||
<td>Meaning</td>
|
||
<td>Valid contexts</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col"><span class="code">windSpeed</span></td>
|
||
<td>The average wind speed seen during the archive period.</td>
|
||
<td rowspan='4'>
|
||
<span class='code'>$current</span>,
|
||
<span class='code'>$latest</span>,
|
||
<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>
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col"><span class="code">windDir</span></td>
|
||
<td>If software record generation is used, this is the vector
|
||
average over the archive period. If hardware record generation is
|
||
used, the value is hardware dependent.
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col"><span class="code">windGust</span></td>
|
||
<td>The maximum (gust) wind speed seen during the archive period.</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col"><span class="code">windGustDir</span></td>
|
||
<td>The direction of the wind when the gust was observed.</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
|
||
<p>In addition, a wind vector is stored in the daily summaries.</p>
|
||
<table class="indent">
|
||
<tbody>
|
||
<tr class="first_row">
|
||
<td><em>Daily summary type</em></td>
|
||
<td>Meaning</td>
|
||
<td>Valid contexts</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col"><span class="code">wind</span></td>
|
||
<td>A vector composite of the wind. It includes information such
|
||
as the direction of the maximum gust, and the x- and y-vector
|
||
wind run.
|
||
</td>
|
||
<td>
|
||
<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>
|
||
</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<p class="note" style="display:inline-block">
|
||
<b>Note</b><br/>The vector is only stored in the daily
|
||
<em>summaries</em>, so unlike the scalar tags such as
|
||
<span class="code">windSpeed</span> or
|
||
<span class="code">windGust</span>, the tag
|
||
<span class="code">wind</span> can only be used in aggregations such as
|
||
<span class="code">$day</span>, <span class="code">$month</span>,
|
||
<i>etc.</i>
|
||
</p>
|
||
|
||
<p>Any of these can be used in your tags. Here are some examples:</p>
|
||
|
||
<table class="indent" style="width: 50%;">
|
||
<tbody>
|
||
<tr class="first_row">
|
||
<td><i>Tag</i></td>
|
||
<td>Meaning</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col"><span class="code">$current.windSpeed</span></td>
|
||
<td>The average wind speed over the most recent archive interval.</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col"><span class="code">$current.windDir</span></td>
|
||
<td>If software record generation is used, this is the vector
|
||
average over the archive interval. If hardware record generation is
|
||
used, the value is hardware dependent.
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col"><span class="code">$current.windGust</span></td>
|
||
<td>The maximum wind speed (gust) over the most recent archive interval.</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col"><span class="code">$current.windGustDir</span></td>
|
||
<td>The direction of the gust.</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col"><span class="code">$day.windSpeed.avg</span></td>
|
||
<td>The average wind speed since midnight. If the wind blows east
|
||
at 5 m/s for 2 hours, then west at 5 m/s for 2 hours, the average
|
||
wind speed is 5 m/s.
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col"><span class="code">$day.wind.avg</span></td>
|
||
<td>The average wind speed since midnight. Same as
|
||
<span class="code">$day.windSpeed.avg</span> above.
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col"><span class="code">$day.wind.vecavg</span></td>
|
||
<td>The <em>vector average</em> wind speed since midnight. If the
|
||
wind blows east at 5 m/s for 2 hours, then west at 5 m/s for 2
|
||
hours, the vector average wind speed is zero.
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col"><span class="code">$day.windSpeed.max</span></td>
|
||
<td>The max average wind speed. The wind is averaged over each of
|
||
the archive intervals. Then these numbers are averaged. Note that
|
||
this is <em>not</em> the same as the maximum observed wind speed.
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col"><span class="code">$day.windGust.max</span></td>
|
||
<td>The maximum observed wind speed since midnight, <i>i.e.,</i>
|
||
the maximum gust.
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col"><span class="code">$day.windDir.avg</span></td>
|
||
<td>Not a very useful quantity. This is the strict, arithmetic
|
||
average of all the compass wind direction. Probably not what you
|
||
want.
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col"><span class="code">$day.wind.vecdir</span></td>
|
||
<td>The direction of the vector averaged wind speed. If the wind
|
||
blows northwest for two hours, then southwest for two hours, the
|
||
vector averaged direction is west.
|
||
</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
|
||
<h2 id="defining_new_tags">Defining new tags</h2>
|
||
|
||
<p>
|
||
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>
|
||
|
||
<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>How the search list works</h3>
|
||
|
||
<p>
|
||
Let's start by taking a look at how the Cheetah <em>search list</em>
|
||
works.
|
||
</p>
|
||
|
||
<p>
|
||
The Cheetah template engine finds tags by scanning a search list, 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 in the
|
||
list in turn. For each object, it will first try using <span
|
||
class="code">foo</span> as an attribute, that is, it will try
|
||
evaluating <span class="code"><i>obj</i>.foo</span>. If that
|
||
raises an <span class="code">AttributeError</span> exception,
|
||
then it will try <span class="code">foo</span> as a key, that is
|
||
<span class="code"><i>obj</i>[key]</span>. If that raises a <span
|
||
class="code">KeyError</span> exception, then it moves on to
|
||
the next item in the list. The first match that does not raise
|
||
an exception is used. If no match is found, Cheetah raises a <span
|
||
class="code">NameMapper.NotFound</span> exception.
|
||
</p>
|
||
|
||
<h3 id="how_tags_work">How tags work</h3>
|
||
|
||
<p>
|
||
Now let's take a look at how the search list interacts with <span
|
||
class="code">weewx</span> tags. Let's start by looking at a
|
||
simple example: station altitude, available as the tag
|
||
</p>
|
||
<pre class="tty">
|
||
$station.altitude</pre>
|
||
|
||
<p>
|
||
As we saw in the previous section, Cheetah will run down the
|
||
search list, looking for an object with a key or attribute <span
|
||
class="code">station</span>. In the default search list, <span
|
||
class="code">weewx</span> includes one such object, an
|
||
instance of the class <span class="code">weewx.cheetahgenerator.Station</span>,
|
||
which has an attribute <span class="code">station</span>, so it
|
||
gets a hit on this object.
|
||
</p>
|
||
|
||
<p>
|
||
Cheetah will then try to evaluate the attribute <span
|
||
class="code">altitude</span> on this object. Class <span
|
||
class="code">Station</span> has such an attribute, so Cheetah
|
||
evaluates it.
|
||
</p>
|
||
|
||
<p>
|
||
What this attribute returns is not a raw value, say <span
|
||
class="code">700</span>, nor even a string. Instead, it
|
||
returns an instance of the class <span class="code">ValueHelper</span>,
|
||
a special class defined in module <span class="code">weewx.units</span>.
|
||
Internally, it holds not only the raw value, but also references
|
||
to the formats, labels, and conversion targets
|
||
you specified in your configuration file. Its job is to make sure
|
||
that the final output reflects these preferences. Cheetah doesn't know
|
||
anything about this class. What it needs, when it has finished
|
||
evaluating the expression <span class="code">$day.outTemp.max</span>
|
||
is a <em>string</em>. In order to convert the <span class="code">ValueHelper</span>
|
||
it has into a string, it does what every other Python object does when
|
||
faced with this problem: it calls the special method <span
|
||
class="code"><a style="text-decoration: none"
|
||
href="https://docs.python.org/2/reference/datamodel.html#object.__str__">__str__</a></span>.
|
||
Class <span class="code">ValueHelper</span> has a definition for
|
||
this method. Evaluating this function triggers the final steps
|
||
in this process. Any necessary unit conversions are done, then
|
||
formatting occurs and, finally, a label is attached. The result
|
||
is a string something like
|
||
</p>
|
||
|
||
<p class="example_output">700 feet</p>
|
||
|
||
<p>which is what Cheetah actually puts in the generated HTML
|
||
file. This is a good example of <em>lazy evaluation</em>. The
|
||
tags gather all the information they need, but don't do the final
|
||
evaluation until the last final moment, when the most
|
||
context is understood. Weewx uses this technique extensively.
|
||
</p>
|
||
|
||
<p>
|
||
Now let's look at a more complicated example, say the maximum temperature since midnight:
|
||
</p>
|
||
<pre class="tty">$day.outTemp.max</pre>
|
||
<p>
|
||
When this is evaluated by Cheetah, it actually produces a chain of
|
||
objects. At the top of this chain is class <span class="code">weewx.tags.TimeBinder</span>,
|
||
an instance of which is included in the default search list. Internally,
|
||
this instance stores the time of the desired report (usually the time of
|
||
the last archive record), a cache to the databases, a default data
|
||
binding, as well as references to the formatting and labelling options you
|
||
have chosen.
|
||
</p>
|
||
|
||
<p>
|
||
This instance is examined by Cheetah to see if it has an attribute <span
|
||
class="code">day</span>. It does and, when it is evaluated, it returns
|
||
the next class in the chain, an instance of <span class="code">weewx.tags.TimespanBinder</span>.
|
||
In addition to all the other things contained in its parent <span
|
||
class="code">TimeBinder</span>, class <span class="code">TimespanBinder</span> adds the desired time
|
||
period, that is, the time span from midnight to the current time.
|
||
</p>
|
||
|
||
<p>
|
||
Cheetah then continues on down the chain and tries to find the next
|
||
attribute, <span class="code">outTemp</span>. There is no such hard
|
||
coded attribute (hard coding all the conceivable different
|
||
observation types would be impossible!). Instead, class <span
|
||
class="code">TimespanBinder</span> defines the Python special method
|
||
<span class="code"> <a style="text-decoration: none"
|
||
href="https://docs.python.org/2/reference/datamodel.html#object.__getattr__">__getattr__</a></span>.
|
||
If Python cannot find a hard coded version of an attribute, and the
|
||
method <span class="code">__getattr__</span> exists, it will try it.
|
||
The definition provided by <span class="code">TimespanBinder</span>
|
||
returns an instance of the next class in the chain, <span
|
||
class="code">weewx.tags.ObservationBinder</span>, which not only
|
||
remembers all the previous stuff, but also adds the observation type,
|
||
<span class="code">outTemp</span>.
|
||
</p>
|
||
|
||
<p>
|
||
Cheetah then tries to evaluate an attribute <span class="code">max</span>
|
||
of this class. Now, finally, the chain ends. The attribute <span
|
||
class="code">max</span> triggers the actual calculation of the
|
||
value, using all the known parameters: the database binding to be hit,
|
||
the time span of interest, the observation type, and the type of
|
||
aggregation, querying the database as necessary. The database is not
|
||
actually hit until the last possible moment, after everything
|
||
needed to do the evalation is known.
|
||
</p>
|
||
|
||
<p>
|
||
Like our previous example, the results of the evaluation are then
|
||
packaged up in an instance of <span class="code">ValueHelper</span>,
|
||
which does the final conversion to the desired units, formats
|
||
the string, then adds a label. The results, something like
|
||
</p>
|
||
|
||
<p class="example_output">12°C</p>
|
||
|
||
<p>
|
||
are put in the generated HTML file. As you can see, a lot of
|
||
machinery is hidden behind the deceptively simple expression <span
|
||
class="code">$day.outTemp.max</span>!
|
||
</p>
|
||
|
||
<h3 id="extending_the_list">Extending the list</h3>
|
||
|
||
<p>
|
||
As mentioned, <span class="code">weewx</span> 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="code">examples/xsearch.py</span>: </p>
|
||
<pre class="tty">import datetime
|
||
import time
|
||
|
||
from weewx.cheetahgenerator import SearchList
|
||
from weewx.tags import TimespanBinder
|
||
from weeutil.weeutil import TimeSpan
|
||
|
||
class MyXSearch(SearchList): # 1
|
||
"""My search list extension"""
|
||
|
||
def __init__(self, generator): # 2
|
||
SearchList.__init__(self, generator)
|
||
|
||
def get_extension_list(self, timespan, db_lookup): # 3
|
||
"""Returns a search list extension with two additions.
|
||
|
||
Parameters:
|
||
timespan: An instance of weeutil.weeutil.TimeSpan. This will
|
||
hold the start and stop times of the domain of
|
||
valid times.
|
||
|
||
db_lookup: This is a function that, given a data binding
|
||
as its only parameter, will return a database manager
|
||
object.
|
||
"""
|
||
|
||
# First, create TimespanBinder object for all time. This one is easy
|
||
# because the object timespan already holds all valid times to be
|
||
# used in the report.
|
||
all_stats = TimespanBinder(timespan,
|
||
db_lookup,
|
||
formatter=self.generator.formatter,
|
||
converter=self.generator.converter) # 4
|
||
|
||
# Now get a TimespanBinder 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(timespan.stop) - \
|
||
datetime.timedelta(weeks=1) # 5
|
||
# Convert it to unix epoch time:
|
||
week_ts = time.mktime(week_dt.timetuple()) # 6
|
||
# Form a TimespanBinder object, using the time span we just
|
||
# calculated:
|
||
seven_day_stats = TimespanBinder(TimeSpan(week_ts, timespan.stop),
|
||
db_lookup,
|
||
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
|
||
|
||
# Finally, return our extension as a list:
|
||
return [search_list_extension] # 9</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 is not really necessary and does nothing except pass its
|
||
only parameter, <span class="code">generator</span>, a reference to the
|
||
calling generator, on 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_list()</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">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">db_lookup</span> This is a function
|
||
supplied by the generator. It takes a single argument, a
|
||
name of a binding. When called, it will return an instance of the database manager
|
||
class for that binding. The default for the function is whatever
|
||
binding you set with the option <span class="code">data_binding</span>
|
||
for this report, usually <span class="code">wx_binding</span>.
|
||
</li>
|
||
</ul>
|
||
</li>
|
||
<li>The class <span class="code">TimespanBinding</span> represents a
|
||
statistical calculation over a time period. We have already met it in
|
||
the introduction <em><a href="#how_tags_work">How tags work</a></em>.
|
||
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">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 database lookup function to be used. We simply pass in
|
||
<span class="code">db_lookup</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>, that is,
|
||
<span class="code">timespan</span>,
|
||
which 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">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">TimespanBinder</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>.
|
||
</li>
|
||
<li>Return the dictionary in a list</li>
|
||
</ol>
|
||
<p>The final step that we need to do 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>.
|
||
</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">TimespanBinding</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>
|
||
</table></pre>
|
||
<p>If you place a custom generator somewhere other than the 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>
|
||
|
||
|
||
<h2>Customizing images</h2>
|
||
|
||
<p>
|
||
The installed version of <span class="code">weewx</span> is configured to
|
||
generate a set of useful plots. But, what if you don't like how they look,
|
||
or you want to generate different plots, perhaps with different
|
||
aggregation types? This section covers how to do this.
|
||
</p>
|
||
|
||
<p>
|
||
Image generation is controlled by the section <span class="code">[ImageGenerator]</span>
|
||
in the skin configuration file <span class="code">skin.conf</span>. Let's
|
||
take a look at the beginning part of this section. It looks like this:
|
||
</p>
|
||
<pre class="tty">[ImageGenerator]
|
||
...
|
||
image_width = 300
|
||
image_height = 180
|
||
image_background_color = 0xf5f5f5
|
||
|
||
chart_background_color = 0xd8d8d8
|
||
chart_gridline_color = 0xa0a0a0
|
||
...</pre>
|
||
<p>
|
||
The options right under the section name <span class="code">[ImageGenerator]</span>
|
||
will apply to <em>all</em> plots, unless overridden in subsections. So,
|
||
unless otherwise changed, all plots will be 300 pixels in width, 180
|
||
pixels in height, and will have an RGB background color of 0xf5f5f5, a
|
||
very light gray (HTML color "WhiteSmoke"). The chart itself will have a
|
||
background color of 0xd8d8d8 (a little darker gray), and the gridlines
|
||
will be 0xa0a0a0 (still darker). The other options farther (not shown)
|
||
will also apply to all plots.
|
||
</p>
|
||
|
||
<h3>Time periods</h3>
|
||
|
||
<p>
|
||
After the "global" options at the top of section <span class="code">[ImageGenerator]</span>,
|
||
comes a set of sub-sections, one for each time period (day, week, month,
|
||
and year). These sub-sections define the nature of aggregation and plot
|
||
types for that time period. For example, here is a typical set of options
|
||
for sub-section <span class="code">[[month_images]]</span>. It controls
|
||
which "monthly" images will get generated, and what they will look like:
|
||
</p>
|
||
<pre class="tty"> [[month_images]]
|
||
x_label_format = %d
|
||
bottom_label_format = %m/%d/%y %H:%M
|
||
time_length = 2592000 # == 30 days
|
||
aggregate_type = avg
|
||
aggregate_interval = 10800 # == 3 hours
|
||
show_daynight = false
|
||
</pre>
|
||
<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 days
|
||
(format option <span class="code">%d</span>). The <span class="code">bottom_label_format</span>
|
||
is the format used to time stamp the image at the bottom. In this example,
|
||
it will show the time as something like<span class="code">10/25/09
|
||
15:35</span>. A plot will cover a nominal 30 days, and all items included in it
|
||
will use an aggregate type of averaging over 3 hours. Finally, by setting
|
||
option <span class="code">show_daynight</span> to <span class="code">false</span>,
|
||
we are requesting that day-night, shaded bands not be shown.
|
||
</p>
|
||
|
||
<h3>Image files</h3>
|
||
|
||
<p>
|
||
Within each time period 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. Like
|
||
elsewhere, the 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 total)</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 is 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.
|
||
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 of 'Rain (daily total)'.
|
||
The result of all this is the following plot:
|
||
</p>
|
||
|
||
<p>
|
||
<img src="images/sample_monthrain.png" alt="Sample monthly rain plot"/>
|
||
</p>
|
||
|
||
<h3 id="line_gaps">Line gaps</h3>
|
||
|
||
<p id="line_gap_fraction">If there is a time gap in the data, the option <span class="code">line_gap_fraction</span>
|
||
controls how line plots will be
|
||
drawn. Here's what a plot looks like without and
|
||
with this option being specified:</p>
|
||
|
||
<div class="center" style="width:80%;margin:0;">
|
||
<div style="float:left">
|
||
<img src="images/day-gap-not-shown.png" alt="Gap not shown"/>
|
||
|
||
<div class="image_caption"> No <span class="code">line_gap_fraction</span> specified</div>
|
||
</div>
|
||
<div>
|
||
<img src="images/day-gap-showing.png" alt="Gap showing"/>
|
||
|
||
<div class="image_caption"> With <span class="code">line_gap_fraction=0.01</span></div>
|
||
</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 id="including_same_sql_type_2x">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
|
||
<span style="text-decoration:line-through; color:red">[[[[outTemp]]]]</span> # 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]]]
|
||
[[[[avgTemp]]]]
|
||
data_type = outTemp
|
||
aggregate_type = avg
|
||
aggregate_interval = 3600
|
||
label = Avg. Temp.
|
||
[[[[outTemp]]]]</pre>
|
||
<p>Here, the first plot line has been given the name <span class="code">avgTemp</span>
|
||
to distinguish it from the second line <span class="code">outTemp</span>.
|
||
Any name will do — it just has to be different.
|
||
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
|
||
one hour smoothed average: </p>
|
||
|
||
<p>
|
||
<img alt="Daytime temperature with running average" src="images/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]]]]
|
||
data_type = outTemp
|
||
aggregate_type = min
|
||
label = Low Temperature</pre>
|
||
<p>This results in the plot <span class="code">yearhilow.png</span>:</p>
|
||
|
||
<p>
|
||
<img width="300" height="180" alt="Daily highs and lows"
|
||
src="images/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>
|
||
<img alt="hourly average wind vector overlaid with gust vectors"
|
||
src="images/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">[ImageGenerator]
|
||
...
|
||
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>
|
||
|
||
|
||
<h2>Using multiple bindings</h2>
|
||
|
||
<p>
|
||
It's easy to use more than one database in your reports. Here's an
|
||
example. In my office I have two consoles: a VantagePro2 connected to a
|
||
Dell Optiplex, and a WMR100N, connected to a Raspberry Pi. Each is
|
||
running <span class="code">weewx</span>. The Dell is using SQLite, the
|
||
RPi, MySQL.
|
||
</p>
|
||
|
||
<p>Suppose I wish to compare the inside temperatures of the two
|
||
consoles. How would I do that?</p>
|
||
|
||
<p>
|
||
It's easier to access MySQL across a network than SQLite, so let's run the
|
||
reports on the Dell, but access the RPi's MySQL database remotely. Here's
|
||
how the bindings and database sections of <span class="code">weewx.conf</span>
|
||
would look on the Dell:
|
||
</p>
|
||
<pre class="tty">[DataBindings]
|
||
# This section binds a data store to an actual database
|
||
|
||
[[wx_binding]]
|
||
# The database to be used - it should match one of the sections in [Databases]
|
||
database = archive_sqlite
|
||
# The name of the table within the database
|
||
table_name = archive
|
||
# The class to manage the database
|
||
manager = weewx.wxmanager.WXDaySummaryManager
|
||
# The schema defines to structure of the database contents
|
||
schema = schemas.wview.schema
|
||
|
||
<span class="highlight"> [[wmr100_binding]]
|
||
# Binding for my WMR100 on the RPi
|
||
database = rpi_mysql
|
||
# The name of the table within the database
|
||
table_name = archive
|
||
# The class to manage the database
|
||
manager = weewx.wxmanager.WXDaySummaryManager
|
||
# The schema defines to structure of the database contents
|
||
schema = schemas.wview.schema</span>
|
||
|
||
[Databases]
|
||
# This section binds to the actual database to be used
|
||
|
||
[[archive_sqlite]]
|
||
database_type = SQLite
|
||
database_name = weewx.sdb
|
||
|
||
<span class="highlight"> [[rpi_mysql]]
|
||
database_type = MySQL
|
||
database_name = weewx
|
||
host = rpi-bug</span>
|
||
|
||
[DatabaseTypes]
|
||
# This section defines defaults for the different types of databases.
|
||
|
||
[[SQLite]]
|
||
driver = weedb.sqlite
|
||
# Directory in which the database files are located
|
||
SQLITE_ROOT = %(WEEWX_ROOT)s/archive
|
||
|
||
[[MySQL]]
|
||
driver = weedb.mysql
|
||
# The host where the database is located
|
||
host = localhost
|
||
# The user name for logging in to the host
|
||
user = weewx
|
||
# The password for the user name
|
||
password = weewx
|
||
</pre>
|
||
|
||
<p>
|
||
The two additions have been <span class="highlight">highlighted</span>.
|
||
The first, <span class="code">[[wmr100_binding]]</span>, adds a new
|
||
binding called <span class="code">wmr10_binding</span>. It links ("binds")
|
||
to the new database, called <span class="code">rpi_mysql</span>, through
|
||
the option <span class="code">database</span>. It also defines some characteristics
|
||
of the binding, such as which manager is to be used and what its schema looks like.</p>
|
||
|
||
<p>The second addition, <span class="code">[[rpi-mysql]]</span> defines the new database.
|
||
Option <span class="code">database_type</span> is set to <span class="code">MySQL</span>,
|
||
indicating that it is a MySQL database.
|
||
Defaults for MySQL databases are defined in the section <span class="code">[[MySQL]]</span>.
|
||
The new database accepts all of them, except for <span class="code">host</span>,
|
||
which as been set to the remote host <span class="code">rpi-bug</span>,
|
||
the name of my Raspberry Pi.
|
||
</p>
|
||
|
||
<h3>Explicit binding in tags</h3>
|
||
|
||
<p>How do we use this new binding? First, let's do a text comparison,
|
||
using tags. Here's what our template looks like:</p>
|
||
<pre class="tty"><table>
|
||
<tr>
|
||
<td class="stats_label">Inside Temperature, Vantage</td>
|
||
<td class="stats_data">$current.inTemp</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="stats_label">Inside Temperature, WMR100</td>
|
||
<td class="stats_data">$latest<span class="highlight">($data_binding='wmr100_binding')</span>.inTemp</td>
|
||
</tr>
|
||
</table></pre>
|
||
|
||
<p>
|
||
The explicit binding to <span class="code">wmr100_binding</span> is
|
||
highlighted. This tells the reporting engine to override the default
|
||
binding specifed in <span class="code">[StdReport]</span>, generally <span
|
||
class="code">wx_binding</span>, and use <span class="code">wmr100_binding</span>
|
||
instead.
|
||
</p>
|
||
|
||
<p>This results in an HTML output that looks like:</p>
|
||
|
||
<div id="stats_group" class="indent">
|
||
<div class="stats example_output">
|
||
<table>
|
||
<tbody>
|
||
<tr>
|
||
<td class="stats_label">Inside Temperature, Vantage</td>
|
||
<td class="stats_data">68.7°F</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="stats_label">Inside Temperature, WMR100</td>
|
||
<td class="stats_data">68.9°F</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
|
||
<h3>Explicit binding in images</h3>
|
||
|
||
<p>How would we produce a graph of the two different temperatures? Here's
|
||
what the relevant section of the <span class="code">skin.conf</span> file would look like.</p>
|
||
<pre class="tty">[[[daycompare]]]
|
||
[[[[inTemp]]]]
|
||
label = Vantage inTemp
|
||
[[[[WMR100Temp]]]]
|
||
data_type = inTemp
|
||
data_binding = wmr100_binding
|
||
label = WMR100 inTemp</pre>
|
||
|
||
<p>
|
||
This will produce an image with name <span class="code">daycompare.png</span>,
|
||
with two plot lines. The first will be of the temperature from the
|
||
Vantage. It uses the default binding, <span class="code">wx_binding</span>,
|
||
and will be labeled <span class="code">Vantage inTemp</span>. The second
|
||
explicitly uses the <span class="code">wmr100_binding</span>. Because it
|
||
uses the same variable name (<span class="code">inTemp</span>) as the
|
||
first line, we had to explicitly specify it using option <span
|
||
class="code">data_type</span>, in order to avoid using the same
|
||
sub-section name twice (see the section <em><a
|
||
href="#including_same_sql_type_2x">Including the same SQL
|
||
type more than once in a plot</a></em> for details). It will be labeled <span
|
||
class="code">WMR100 inTemp</span>. The results look like this:
|
||
</p>
|
||
<img src='images/daycompare.png' alt="Comparing temperatures"/>
|
||
|
||
<h3 id="stupid_detail">Stupid detail</h3>
|
||
|
||
<p>
|
||
At first, I could not get this example to work. The problem turned out to
|
||
be that the RPi was processing things just a beat behind the Dell, so the
|
||
temperature for the "current" time wasn't ready when the Dell needed it. I
|
||
kept getting <span class="code">N/A</span>. To avoid this, I introduced
|
||
the tag <span class="code">$latest</span>, which uses the last available
|
||
timestamp in the binding, which may or may not be the same as what <span
|
||
class="code">$current</span> uses. That's why the example above uses
|
||
<span class="code">$latest</span> instead of <span class="code">$current</span>.
|
||
</p>
|
||
|
||
|
||
<h2 id="customizing_gen_time">Customizing the report generation time</h2>
|
||
|
||
<p>Normal <span class="code">weewx</span> operation is to run each report
|
||
defined in <span class="code">weewx.conf</span> every archive period.
|
||
Whilst this may suit most situations, there may be occasions when it
|
||
is desirable to run a report less frequently than every archive period.
|
||
For example, the archive interval might be 5 minutes, but you only want
|
||
to FTP files every 30 minutes, or once per day. In
|
||
such cases the <span class="code">report_timing</span> option can be
|
||
used to control when individual reports are run.
|
||
</p>
|
||
|
||
<h3>The <span class="code">report_timing</span> option</h3>
|
||
|
||
<p>The <span class="code">report_timing</span> option uses a CRON like
|
||
format to control when a report is to be run. Whilst a CRON like
|
||
format is used, the control of <span class="code">weewx</span> report
|
||
generation using the <span class="code">report_timing</span> option
|
||
is confined completely to <span class="code">weewx</span> and has no
|
||
interraction with the system CRON service.
|
||
</p>
|
||
|
||
<p>The <span class="code">report_timing</span> option consists of five,
|
||
space separated parameters as follows:
|
||
</p>
|
||
|
||
<pre class="tty">report_timing = minutes hours day_of_month months day_of_week</pre>
|
||
|
||
<p>
|
||
The <span class="code">report_timing</span> parameters are summarised
|
||
in the following table:
|
||
</p>
|
||
|
||
<table class="indent" summary="Report CRON parameters">
|
||
<tbody>
|
||
<tr class="first_row">
|
||
<td>Parameter</td>
|
||
<td width='20%'>Function</td>
|
||
<td>Allowable values</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="code first_col">minutes</td>
|
||
<td>Specifies the minutes of the hour when the report will be run</td>
|
||
<td>*, or<br>numbers in the range 0..59 inclusive</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="code first_col">hours</td>
|
||
<td>Specifies the hours of the day when the report will be run</td>
|
||
<td>*, or<br>numbers in the range 0..23 inclusive</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="code first_col">day_of_month</td>
|
||
<td>Specifies the days of the month when the report will be run</td>
|
||
<td>*, or<br>numbers in the range 1..31 inclusive</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="code first_col">months</td>
|
||
<td>Specifies the months of the year when the report will be run</td>
|
||
<td>*, or<br>numbers in the range 1..12 inclusive, or<br>abbreviated names
|
||
in the range jan..dec inclusive</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="code first_col">day_of_week</td>
|
||
<td>Specifies the days of the week when the report will be run</td>
|
||
<td>*, or<br>numbers in the range 0..7 inclusive (0,7 = Sunday, 1 =
|
||
Monday etc), or<br>abbreviated names in the range sun..sat inclusive</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
|
||
<p>The <span class="code">report_timing</span> option may only be used in
|
||
<span class="code">weewx.conf</span>. When set in the
|
||
<span class="code">[StdReport]</span> section of
|
||
<span class="code">weewx.conf</span> the option will apply to all
|
||
reports listed under <span class="code">[StdReport]</span>. When
|
||
specified within a report section, the option will override any setting
|
||
in <span class="code">[StdReport]</span> for that report. In this
|
||
manner it is possible to have different reports run at different times.
|
||
The following sample
|
||
<span class="code">weewx.conf</span> excerpt illustrates this:
|
||
</p>
|
||
|
||
<pre class="tty">
|
||
[StdReport]
|
||
|
||
# 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
|
||
|
||
# The database binding indicates which data should be used in reports.
|
||
data_binding = wx_binding
|
||
|
||
# Report timing parameter
|
||
report_timing = 0 * * * *
|
||
|
||
# Each of the following subsections defines a report that will be run.
|
||
|
||
[[AReport]]
|
||
skin = SomeSkin
|
||
|
||
[[AnotherReport]]
|
||
skin = SomeOtherSkin
|
||
report_timing = */10 * * * *</pre>
|
||
|
||
<p>In the above case, the <span class="code">[[AReport]]</span> report
|
||
would be generated under under control of the
|
||
<span class="code">0 * * * *</span> setting (on the hour) under
|
||
<span class="code">[StdReport]</span> and the
|
||
<span class="code">[[AnotherReport]]</span> report would be generated
|
||
under control of the <span class="code">*/10 * * * *</span> setting
|
||
(every 10 minutes) which has overriden the
|
||
<span class="code">[StdReport]</span> setting.
|
||
</p>
|
||
|
||
<h4>How <span class="code">report_timing</span> controls reporting</h4>
|
||
|
||
<p>The <span class="code">report_timing</span> option uses a CRON like
|
||
format to control when reports are run. The syntax and interpretation
|
||
of the <span class="code">report_timing</span> parameters used by
|
||
weewx is largely the same as the syntax and interpretation used by the
|
||
CRON service in many Unix and Unix-like operating systems. The syntax
|
||
and interpretation used to support the
|
||
<span class="code">report_timing</span> option is outlined below.
|
||
</p>
|
||
|
||
<p>When the <span class="code">report_timing</span> option is in use
|
||
<span class="code">weewx</span> will run a report when the minute, hour
|
||
and month of year parameters match the report time, and at least one of
|
||
the two day parameters (day of month or day of week) match the report time.
|
||
This means that non-existent times, such as "missing hours" during
|
||
daylight savings changeover, will never match, causing reports scheduled
|
||
during the "missing times" not to be run. Similarly, times that occur
|
||
more than once (again, during daylight savings changeover) will cause
|
||
matching reports to be run more than once.
|
||
</p>
|
||
|
||
<p class="note" style="display:inline-block; width:70%">
|
||
<b>Note</b><br/>Report time does not refer to the time at which the
|
||
report is run, but rather the date and time of the latest data the report
|
||
is based upon. If you like, it is the effective date and time of the
|
||
report. For normal <span class="code">weewx</span> operation, the report
|
||
time aligns with the <span class="code">dateTime</span> of the most recent
|
||
archive record. When reports are run using the
|
||
<span class="code">wee_reports</span> tool, the report time is either
|
||
the <span class="code">dateTime</span> of the most recent archive record
|
||
(the default) or the optional timestamp command line argument.
|
||
</p>
|
||
|
||
<p class="note" style="display:inline-block; width:70%">
|
||
<b>Note</b><br/>The day a report is to be run can be specified by two
|
||
parameters; day of month and/or day of week. If both parameters
|
||
are restricted (ie not an asterisk), the report will be run when either
|
||
field matches the current time. For example,<br>
|
||
<span class="code">report_timing = 30 4 1,15 * 5</span><br> would cause
|
||
the report to be run at 4:30am on the 1st and 15th of each month as well
|
||
as 4:30am every Friday.
|
||
</p>
|
||
|
||
<h4>The relationship between <span class="code">report_timing</span> and archive period</h4>
|
||
|
||
<p>A traditional CRON service has a resolution of one minute, meaning that
|
||
the CRON service checks each minute as to whether to execute any commands.
|
||
On the other hand, the <span class="code">weewx</span> report system checks
|
||
which reports are to be run once per archive period where the archive period
|
||
may be one minute, five minutes or some other user defined period.
|
||
Consequently, the <span class="code">report_timing</span> option may specify
|
||
a report to be run at some time that does not align with the
|
||
<span class="code">weewx</span> archive period. In cases where the
|
||
<span class="code">weewx</span> archive period is greater than one minute,
|
||
and provided a <span class="code">report_timing</span> option is set,
|
||
<span class="code">weewx</span> will check each minute boundary from the
|
||
current report time back until the report time of the previous report cycle.
|
||
If a match is found on <b>any</b> of these times the report will be run. For
|
||
example, on a <span class="code">weewx</span> system with a <b>five minute</b>
|
||
archive period the following <span class="code">report_timing</span> setting:
|
||
</p>
|
||
|
||
<pre class="tty">report_timing = 22 * * * *</pre>
|
||
|
||
<p>would cause the report to be run during the report cycle occurring at 25
|
||
minutes past each hour.
|
||
</p>
|
||
|
||
<h4>Lists, ranges and steps</h4>
|
||
|
||
<p>The <span class="code">report_timing</span> option supports lists, ranges
|
||
and steps for all parameters. Lists, ranges and steps may be used as follows:
|
||
</p>
|
||
|
||
<ul>
|
||
<li>Lists. A list is a set of numbers (or ranges) separated by commas,
|
||
for example 1,2,5,9 or 0-4,8-12. A match with any of the elements of
|
||
the list will result in a match for that particular parameter. If the
|
||
examples were applied to the minutes parameter, and subject to other
|
||
parameters in the <span class="code">report_timing</span> option, the
|
||
report would be run at minutes 1,2,5 and 9 and 0,1,2,3,4,8,9,10,11 and
|
||
12 respectively. Abbreviated month and day names cannot be used in a list.
|
||
</li>
|
||
|
||
<li>Ranges. Ranges are two numbers separated with a hyphen, for
|
||
example 8-11. The specified range is inclusive. A match with any of the
|
||
values included in the range will result in a match for that particular
|
||
parameter. If the example was applied to the hours parameter, and subject
|
||
to other parameters in the <span class="code">report_timing</span> option,
|
||
the report would be run at hours 8,9,10 and 11. A range may be included
|
||
as an element of a list. Abbreviated month and day names cannot be used
|
||
in a range.
|
||
</li>
|
||
|
||
<li>Steps. A step can be used in conjunction with a range or asterisk and
|
||
are denoted by a '/' followed by a number. Following a range with a step
|
||
specifies skips of the step number's value through the range. For example,
|
||
0-12/2 used in the hours parameter would, subject to other parameter in
|
||
the <span class="code">report_timing</span> option, run the report at
|
||
hours 0,2,4,6,8,12. Steps are also permitted after an asterisk in which
|
||
case the skips of the step number's value occur through the all possible
|
||
values of the parameter. For example, */3 can be used in the hours parameter
|
||
to, subject to other parameter in the <span class="code">report_timing</span>
|
||
option, run the report at hours 0,3,6,9,12,15,18 and 21.
|
||
</ul>
|
||
|
||
<h4>Nicknames</h4>
|
||
|
||
<p>The <span class="code">report_timing</span> option supports a number of
|
||
time specification 'nicknames'. These nicknames are prefixed by the '@'
|
||
character and replace the five parameters in the
|
||
<span class="code">report_timing</span> option. The nicknames supported
|
||
are:
|
||
</p>
|
||
|
||
<table class="indent" summary="Report CRON examples">
|
||
<tbody>
|
||
<tr class="first_row">
|
||
<td>Nickname</td>
|
||
<td>Effective <span class="code">report_timing</span> setting</td>
|
||
<td>When the report will be run</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="code first_col">@yearly<br>@annually</td>
|
||
<td>0 0 1 1 *</td>
|
||
<td>Once per year at midnight on 1 January.</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="code first_col">@monthly</td>
|
||
<td>0 0 1 * *</td>
|
||
<td>Monthly at midnight on the 1st of the month.</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="code first_col">@weekly</td>
|
||
<td>0 0 * * 0</td>
|
||
<td>Every week at midnight on Sunday.</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="code first_col">@daily</td>
|
||
<td>0 0 * * *</td>
|
||
<td>Every day at midnight.</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="code first_col">@hourly</td>
|
||
<td>0 * * * *</td>
|
||
<td>Every hour on the hour.</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
|
||
<h4><span class="code">report_timing</span> option examples</h4>
|
||
|
||
<p>CRON like settings can be at times difficult to understand due to the complex
|
||
combinations of parameters. The following table
|
||
shows a number of example <span class="code">report_timing</span> options
|
||
and the times when the report would be run.
|
||
</p>
|
||
|
||
<table class="indent" summary="report_timing examples">
|
||
<tbody>
|
||
<tr class="first_row">
|
||
<td><span class="code">report_timing</span></td>
|
||
<td>When the report will be run</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="code first_col">* * * * *</td>
|
||
<td>Every archive period. This setting is effectively the default
|
||
<span class="code">weewx</span> method of operation.</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="code first_col">25 * * * *</td>
|
||
<td>25 minutes past every hour.</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="code first_col">0 * * * *</td>
|
||
<td>Every hour on the hour.</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="code first_col">5 0 * * *</td>
|
||
<td>00:05 daily.</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="code first_col">25 16 * * *</td>
|
||
<td>16:25 daily.</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="code first_col">25 16 1 * *</td>
|
||
<td>16:25 on the 1st of each month.</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="code first_col">25 16 1 2 *</td>
|
||
<td>16:25 on the 1st of February.</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="code first_col">25 16 * * 0</td>
|
||
<td>16:25 each Sunday.</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="code first_col">*/10 * * * *</td>
|
||
<td>On the hour and 10, 20, 30, 40 and 50 mnutes past the hour.</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="code first_col">*/9 * * * *</td>
|
||
<td>On the hour and 9, 18, 27, 36, 45 and 54 minutes past the hour.</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="code first_col">*/10 */2 * * *</td>
|
||
<td>0, 10, 20, 30, 40 and 50 minutes after the even hour.</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="code first_col">* 6-17 * * *</td>
|
||
<td>Every archive period from 06:00 (inclusive) up until, but
|
||
excluding, 18:00.</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="code first_col">* 1,4,14 * * *</td>
|
||
<td>Every archive period in the hour starting 01:00 to 01:59, 04:00
|
||
to 04:59 amd 14:00 to 14:59 (Note excludes report times at
|
||
02:00, 05:00 and 15:00).</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="code first_col">0 * 1 * 0,3</td>
|
||
<td>On the hour on the first of the month and on the hour every
|
||
Sunday and Wednesday.</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="code first_col">* * 21,1-10/3 6 *</td>
|
||
<td>Every archive period on the 1st, 4th, 7th, 10th and 21st of June.</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="code first_col">@monthly</td>
|
||
<td>Midnight on the 1st of the month.</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
|
||
<h3>The <span class="code">wee_reports</span> tool and the <span class="code">report_timing</span> option</h3>
|
||
|
||
<p>The <a href="#wee_reports">wee_reports</a> tool allows
|
||
<span class="code">weewx</span> reports to be run independently of the main
|
||
<span class="code">weewx</span> program. Reports are run using the time of
|
||
the last record in the archive database as the "current" time (the default)
|
||
or optionally using a unix epoch timestamp command line argument as the
|
||
"current" time. Given the one off report and variable time nature of the
|
||
<a href="#wee_reports">wee_reports</a> tool, the
|
||
<span class="code">report_timing</span> option is ignored when using the
|
||
<a href="#wee_reports">wee_reports</a> tool.
|
||
</p>
|
||
|
||
<h1 id="standard_skin">The Standard <span class="code">skin.conf</span></h1>
|
||
|
||
<p>This section is a reference to the options appearing in the skin
|
||
configuration file. The default skin is the Standard skin, with a
|
||
skin configuration file located at
|
||
<span class="symcode">SKIN_ROOT</span><span class="code">/Standard/skin.conf</span>. </p>
|
||
|
||
<p>The most important options, the ones you are likely to have to
|
||
customize, are
|
||
<span class="config_important"><strong>highlighted</strong></span>.</p>
|
||
|
||
<p>It is worth noting that, like the main configuration file
|
||
<span class="code">weewx.conf</span>, UTF-8 is used throughout.
|
||
</p>
|
||
|
||
<h2 class="config_section" id="Extras">[Extras]</h2>
|
||
|
||
<p>This section is available to add any static tags you
|
||
might want to use in your templates.</p>
|
||
|
||
<h3>Example</h3>
|
||
|
||
<p>As an example, the Standard <span class="code">skin.conf</span>
|
||
file includes three options: </p>
|
||
<table class="indent" style="width:50%" summary="Tag Extras">
|
||
<tr class="first_row">
|
||
<td>Skin option</td>
|
||
<td>Template tag</td>
|
||
</tr>
|
||
<tr>
|
||
<td><span class="code">radar_img</span></td>
|
||
<td><span class="code">$Extras.radar_img</span></td>
|
||
</tr>
|
||
<tr>
|
||
<td><span class="code">radar_url</span></td>
|
||
<td><span class="code">$Extras.radar_url</span></td>
|
||
</tr>
|
||
<tr>
|
||
<td><span class="code">googleAnalyticsId</span></td>
|
||
<td><span class="code">$Extras.googleAnalyticsId</span></td>
|
||
</tr>
|
||
</table>
|
||
<p>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_img</span> to find them).
|
||
</p>
|
||
|
||
<p class="config_option">radar_img</p>
|
||
|
||
<p>Set to an URL to show a local radar image for you.</p>
|
||
|
||
<p class="config_option">radar_url</p>
|
||
|
||
<p>If the above radar image is clicked, the browser will go to
|
||
this URL. This is usually used to show a more detailed,
|
||
close-up, radar picture.
|
||
</p>
|
||
|
||
<p>For me in Oregon, setting the above two options to:</p>
|
||
<pre class="tty">
|
||
[Extras]
|
||
radar_img = http://radar.weather.gov/ridge/lite/N0R/RTX_loop.gif
|
||
radar_url = http://radar.weather.gov/ridge/radar.php?product=NCR&rid=RTX&loop=yes</pre>
|
||
<p>results in a nice image of a radar centered on Portland,
|
||
Oregon. When you click on it, it gives you a detailed, animated view.
|
||
If you live in the USA, take a look at
|
||
the <a href="http://radar.weather.gov/">NOAA radar website</a>
|
||
to find a nice one that will work for you. In other countries, you
|
||
will have to consult your local weather service.
|
||
</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 <em><a href="#units">Appendix: 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>, 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.</p>
|
||
|
||
<p> If the label includes two values, then the first is assumed to be the
|
||
singular form, the second the plural form. For example,</p>
|
||
<pre class="tty">foot = " foot", " feet"
|
||
...
|
||
day = " day", " days"
|
||
hour = " hour", " hours"
|
||
minute = " minute", " minutes"
|
||
second = " second", " seconds"</pre>
|
||
|
||
<p>This is particularly useful when <a href="#l11n_unit_labels">localizing the weewx and server uptimes</a>.</p>
|
||
|
||
<h3 class="config_section" id="Units_TimeFormats">[[TimeFormats]]</h3>
|
||
|
||
<p>This sub-section is used for time labels. It uses <a
|
||
href="http://docs.python.org/library/datetime.html#strftime-behavior">strftime()</a>
|
||
formats. The default looks like this:</p>
|
||
<pre class='tty'>
|
||
[[TimeFormats]]
|
||
# This section sets the string format to be used for each time scale.
|
||
# The values below will work in every locale, but may not look
|
||
# particularly attractive. See the Customizing Guide for alternatives.
|
||
|
||
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 <span class='code'>%x</span>, <span class='code'>%X</span>,
|
||
and <span class='code'>%A</span>
|
||
code locale dependent date, time, and weekday names, respectively.
|
||
Hence, if you set an appropriate environment variable <span class='code'>LANG</span>,
|
||
then the date and times should follow local conventions (see section
|
||
<a href="#environment_variable_LANG">Environment variable LANG</a>
|
||
for details on how to do this). However, they will not look particularly pretty
|
||
and you may want to change them. For example, I use this in the U.S.:
|
||
</p>
|
||
<pre class="tty">
|
||
[[TimeFormats]]
|
||
#
|
||
# More attractive formats that work in most Western countries.
|
||
#
|
||
day = %H:%M
|
||
week = %H:%M on %A
|
||
month = %d-%b-%Y %H:%M
|
||
year = %d-%b-%Y %H:%M
|
||
rainyear = %d-%b-%Y %H:%M
|
||
current = %d-%b-%Y %H:%M
|
||
ephem_day = %H:%M
|
||
ephem_year = %d-%b-%Y %H:%M</pre>
|
||
|
||
<p>The last two formats, <span class='code'>ephem_day</span> and
|
||
<span class='code'>ephem_year</span> allow the formatting to be set for almanac times
|
||
The first, <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" id="Labels_Generic">[[Generic]]</h3>
|
||
|
||
<p>This sub-section specifies default labels to be used for each observation
|
||
type. For example, options </p>
|
||
<pre class="tty">inTemp = Temperature inside the house
|
||
outTemp = Outside Temperature
|
||
UV = UV Index</pre>
|
||
<p>would cause the given labels to be used for plots of <span
|
||
class="code">inTemp</span> and <span class="code">outTemp</span>.
|
||
If no option is given, then the observation type itself will
|
||
be used (<em>e.g., </em><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>
|
||
|
||
<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 three block names
|
||
that have special meaning: <span class='code'>SummaryByMonth</span>,
|
||
<span class='code'>SummaryByYear</span>, and <span class='code'>ToDate</span>.
|
||
They 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</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">
|
||
<tbody>
|
||
<tr class="first_row">
|
||
<td>Encoding</td>
|
||
<td>Comments</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="code first_col">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 first_col">utf8</td>
|
||
<td>Non 7-bit characters will be represented in UTF-8.</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="code first_col">strict_ascii</td>
|
||
<td>Non 7-bit characters will be ignored.</td>
|
||
</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 <span class="code">stale_age</span>
|
||
is specified, then the file will be generated every 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 customize 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 test often. Use the tool
|
||
<span class="code"><a href="#wee_reports">wee_reports</a></span>
|
||
to test modifications to the generator configuration and/or the
|
||
template contents.</p>
|
||
|
||
<h3>The Standard skin templates</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_ascii</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_ascii</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">[ImageGenerator]</h2>
|
||
|
||
<p>This section describes the various options available to the image
|
||
generator.</p>
|
||
|
||
<div class="image image-right">
|
||
<img src="images/image_parts.png"
|
||
alt="Part names in a weewx image"/>
|
||
|
||
<div class="image_caption">Part names in a weewx image</div>
|
||
</div>
|
||
|
||
|
||
<h3>Overall options</h3>
|
||
|
||
<p>These are options that affect the overall image.</p>
|
||
|
||
<p class="config_option">
|
||
image_width<br/> image_height
|
||
</p>
|
||
|
||
<p>The width and height of the image in pixels. Optional. Default is 300
|
||
x 180 pixels.</p>
|
||
|
||
<p class="config_option">image_background_color</p>
|
||
|
||
<p>The background color of the whole image. Optional. Default is
|
||
<span class='code'>0xf5f5f5</span> ("SmokeGray")</p>
|
||
|
||
<p class="config_option">chart_background_color</p>
|
||
|
||
<p>The background color of the chart itself. Optional. Default is
|
||
<span class='code'>0xd8d8d8</span>.</p>
|
||
|
||
<p class="config_option">chart_gridline_color</p>
|
||
|
||
<p>The color of the chart grid lines. Optional. Default is
|
||
<span class='code'>0xa0a0a0</span></p>
|
||
|
||
<div class="image image-right" style="clear:right">
|
||
<img src="images/weektempdew.png" alt="Example of day/night bands"/>
|
||
|
||
<div class="image_caption">Example of day/night bands in a one
|
||
week image</div>
|
||
</div>
|
||
<p class="config_option">show_daynight</p>
|
||
|
||
<p>
|
||
Set to <span class="code">true</span> to show day/night bands in an image.
|
||
Otherwise, set to false. This only looks good with day or week plots.
|
||
Optional. Default is <span class="code">false</span>.
|
||
</p>
|
||
|
||
<p class="config_option">daynight_day_color</p>
|
||
|
||
<p>
|
||
The color to be used for the daylight band. Optional. Default is <span
|
||
class="code">0xffffff</span>.
|
||
</p>
|
||
|
||
<p class="config_option">daynight_night_color</p>
|
||
|
||
<p>
|
||
The color to be used for the nighttime band. Optional. Default is <span
|
||
class="code">0xf0f0f0</span>, a dark gray.
|
||
</p>
|
||
|
||
<p class="config_option">daynight_edge_color</p>
|
||
|
||
<p>
|
||
The color to be used in the transition zone between night and day.
|
||
Optional. Default is <span class="code">0xefefef</span>, a mid-gray.
|
||
</p>
|
||
|
||
|
||
<h3>Various label options</h3>
|
||
|
||
<p>These are options for the various labels used in the image.</p>
|
||
|
||
<p class="config_option">top_label_font_path</p>
|
||
|
||
<p>
|
||
The path to the font to be use for the top label. Optional. If not given,
|
||
or if <span class="code">weewx</span> cannot find the font, then the
|
||
default PIL font will be used.
|
||
</p>
|
||
|
||
<p class="config_option">top_label_font_size</p>
|
||
|
||
<p>The size of the top label in pixels. Optional. The default is
|
||
<span class='code'>10</span>.</p>
|
||
|
||
<p class="config_option">unit_label_font_path</p>
|
||
|
||
<p>
|
||
The path to the font to be use for the unit label. Optional. If not given,
|
||
or if <span class="code">weewx</span> cannot find the font, then the
|
||
default PIL font will be used.
|
||
</p>
|
||
|
||
<p class="config_option">unit_label_font_size</p>
|
||
|
||
<p>The size of the unit label in pixels. Optional. The default is
|
||
<span class='code'>10</span>.</p>
|
||
|
||
<p class="config_option">unit_label_font_color</p>
|
||
|
||
<p>The color of the unit label font. Optional. Default is
|
||
<span class='code'>black</span>.</p>
|
||
|
||
<p class="config_option">bottom_label_font_path</p>
|
||
|
||
<p>
|
||
The path to the font to be use for the bottom label. Optional. If not
|
||
given, or if <span class="code">weewx</span> cannot find the font, then
|
||
the default PIL font will be used.
|
||
</p>
|
||
|
||
<p class="config_option">bottom_label_font_size</p>
|
||
|
||
<p>The size of the bottom label in pixels. Optional. The default is
|
||
<span class='code'>10</span>.</p>
|
||
|
||
<p class="config_option">bottom_label_font_color</p>
|
||
|
||
<p>The color of the bottom label font. Optional. Default is
|
||
<span class='code'>black</span>.</p>
|
||
|
||
<p class="config_option">bottom_label_format</p>
|
||
|
||
<p>
|
||
The format to be used for the bottom label. It should be a <a
|
||
href="http://docs.python.org/library/datetime.html#strftime-strptime-behavior">
|
||
strftime format</a>. Optional. Default is
|
||
<span class="code">'%m/%d/%y %H:%M'</span>.
|
||
</p>
|
||
|
||
<p class="config_option">bottom_label_offset</p>
|
||
|
||
<p>
|
||
The margin of the bottom label from the bottom of the plot. Default is 3.
|
||
</p>
|
||
|
||
<p class="config_option">axis_label_font_path</p>
|
||
|
||
<p>
|
||
The path to the font to be use for the x- and y-axis labels. Optional. If not given,
|
||
or if <span class="code">weewx</span> cannot find the font, then the
|
||
default PIL font will be used.
|
||
</p>
|
||
|
||
<p class="config_option">axis_label_font_size</p>
|
||
|
||
<p>The size of the x- and y-axis labels in pixels. Optional. The default is
|
||
<span class='code'>10</span>.</p>
|
||
|
||
<p class="config_option">axis_label_font_color</p>
|
||
|
||
<p>The color of the x- and y-axis label font. Optional. Default is
|
||
<span class='code'>black</span>.</p>
|
||
|
||
<p class="config_option">x_label_format</p>
|
||
|
||
<p>The format to be used for the time labels on the x-axis. It should be a <a
|
||
href="http://docs.python.org/library/datetime.html#strftime-strptime-behavior">
|
||
strftime format</a>. Optional. If not given, a sensible format will be
|
||
chosen automatically.
|
||
</p>
|
||
|
||
|
||
<h3>Plot scaling options</h3>
|
||
|
||
<p class="config_option">time_length</p>
|
||
|
||
<p>
|
||
The nominal length of the time period to be covered in seconds. The exact
|
||
length of the x-axis is chosen by the plotting engine to cover this
|
||
period. Optional. Default is <span class="code">86400</span> (one day).
|
||
</p>
|
||
|
||
<p class="config_option">yscale</p>
|
||
|
||
<p>
|
||
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. Optional. Default is
|
||
<span class="code">None, None, None</span>. (Choose the y-axis minimum,
|
||
maximum, and minimum increment automatically.)
|
||
</p>
|
||
|
||
|
||
<h3>Compass rose options</h3>
|
||
|
||
<div class="image image-right" style="width:300px">
|
||
<img src="images/daywindvec.png"
|
||
alt="Example of a progressive vector plot"/>
|
||
|
||
<div class="image_caption">Example of a vector plot with a compass rose in the lower-left</div>
|
||
</div>
|
||
|
||
<p class="config_option">rose_label</p>
|
||
|
||
<p>
|
||
The label to be used in the compass rose to indicate due North. Optional.
|
||
Default is <span class="code">N</span>.
|
||
</p>
|
||
|
||
<p class="config_option">rose_label_font_path</p>
|
||
|
||
<p>
|
||
The path to the font to be use for the rose label (the letter "N,"
|
||
indicating North). Optional. If not given, or if <span class="code">weewx</span>
|
||
cannot find the font, then the default PIL font will be used.
|
||
</p>
|
||
|
||
<p class="config_option">rose_label_font_size</p>
|
||
|
||
<p>The size of the compass rose label in pixels. Optional. The default
|
||
is <span class="code">10</span>.</p>
|
||
|
||
<p class="config_option">rose_label_font_color</p>
|
||
|
||
<p>The color of the compass rose label. Optional. Default is the same
|
||
color as the rose itself.</p>
|
||
|
||
<p class="config_option">vector_rotate</p>
|
||
|
||
<p>
|
||
Causes the vectors to be rotated by this many degrees. Positive is clockwise.
|
||
If westerly winds dominate at your location (as they do at mine),
|
||
then you may want to specify <span
|
||
class="code">+90</span> for this option. This will cause the average vector
|
||
to point straight up, rather than lie flat against the x-axis. Optional.
|
||
The default is <span class='code'>0</span>.
|
||
</p>
|
||
|
||
|
||
<h3>Shared plot line options</h3>
|
||
|
||
<p>These are options shared by all the plot lines.</p>
|
||
|
||
<p class="config_option">chart_line_colors</p>
|
||
|
||
<p>
|
||
Each chart line is drawn in a different color. This option is a list of
|
||
those colors. If the number of lines exceeds the length of the list, then
|
||
the colors wrap around to the beginning of the list. NB: individual line
|
||
color can be overridden by using option <span class="code">color</span>.
|
||
Optional. In the case of bar charts, this is the color
|
||
of the outline of the bar. Default is
|
||
<span class="code">0xff0000, 0x00ff00, 0x0000ff</span>.
|
||
</p>
|
||
|
||
<p class="config_option">chart_fill_colors</p>
|
||
|
||
<p>
|
||
A list of the color to be used as the fill of the bar charts. Optional.
|
||
The default is to use the same color as the outline color (option
|
||
<span class="code">chart_line_colors</span>) above.
|
||
</p>
|
||
|
||
<p class="config_option">chart_line_width</p>
|
||
|
||
<p>
|
||
Each chart line can be drawn using a different line width. This option is a list of
|
||
these widths. If the number of lines exceeds the length of the list, then
|
||
the widths wrap around to the beginning of the list. NB: individual line
|
||
widths can be overridden by using option <span class="code">width</span>.
|
||
Optional. Default is <span class="code">1, 1, 1</span>.
|
||
</p>
|
||
|
||
|
||
<h3>Individual line options</h3>
|
||
|
||
<p>These are options that are set for individual lines.</p>
|
||
|
||
<p class="config_option">aggregate_type</p>
|
||
|
||
<p>
|
||
The default is to plot every data point, but this is
|
||
probably not a good idea for any plot longer than a day. By setting this
|
||
option, you can <em>aggregate</em> data by a set time interval. Available
|
||
aggregation types include <span class="code">avg</span>, <span
|
||
class="code">sum</span>, <span class="code">max</span>, <span
|
||
class="code">min</span>, <span class="code">count</span>, and
|
||
<span class="code">last</span>.
|
||
</p>
|
||
|
||
<p class="config_option">aggregate_interval</p>
|
||
|
||
<p>The time period over which the data should be aggregated. Required if
|
||
<span class="code">aggregate_type</span> has been set. </p>
|
||
|
||
<p class="config_option">plot_type</p>
|
||
|
||
<p>
|
||
The type of plot for this line. Choices are <span class="code">line</span>,
|
||
<span class="code">bar</span>, or <span class="code">vector</span>.
|
||
Optional. Default is <span class="code">line</span>.
|
||
</p>
|
||
|
||
<p class="config_option">color</p>
|
||
|
||
<p>
|
||
This option is to override the color for an individual line. Optional.
|
||
Default is to use the color in <span class="code">chart_line_colors</span>.
|
||
</p>
|
||
|
||
<p class="config_option">line_type</p>
|
||
|
||
<p>
|
||
The type of line to be used. Choices are <span class="code">solid</span>
|
||
or <span class="code">none</span>. Optional. Default is
|
||
<span class="code">solid</span>.
|
||
</p>
|
||
|
||
<p class="config_option">marker_type</p>
|
||
|
||
<p>
|
||
The type of marker to be used to marke each data point. Choices are <span
|
||
class="code">cross</span>, <span class="code">x</span>, <span
|
||
class="code">circle</span>, <span class="code">box</span>, or <span
|
||
class="code">none</span>. Optional. Default is
|
||
<span class="code">none</span>.
|
||
</p>
|
||
|
||
<p class="config_option">marker_size</p>
|
||
|
||
<p>
|
||
The size of the marker. Optional. Default is <span class="code">8</span>.
|
||
</p>
|
||
|
||
<p class="config_option">line_gap_fraction</p>
|
||
|
||
<p>
|
||
If there is a gap between data points bigger than this fractional amount
|
||
of the x-axis, then a gap will be drawn, rather than a connecting line.
|
||
See Section <em><a href="#line_gaps">Line gaps</a></em>. Optional. The
|
||
default is to always draw the line.
|
||
</p>
|
||
|
||
<p class="config_option">width</p>
|
||
|
||
<p>
|
||
This option is to override the line widthfor an individual line. Optional.
|
||
Default is to use the width in <span class="code">chart_line_width</span>.
|
||
</p>
|
||
|
||
<p class="config_option">label</p>
|
||
|
||
<p>The label to be used for this plot line in the top label. Optional.
|
||
The default is to use the SQL variable name.</p>
|
||
|
||
<p class="config_option">data_type</p>
|
||
|
||
<p>
|
||
The SQL data type to be used for this plot line. For more information,
|
||
see the section
|
||
<em><a href="#including_same_sql_type_2x">Including the same SQL type more than once in a plot</a></em>.
|
||
Optional. The default is to use the
|
||
section name.
|
||
</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>
|
||
|
||
<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>
|
||
|
||
<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 every time the generator runs.</p>
|
||
|
||
|
||
<h2 class="config_section" id="generators_section">[Generators]</h2>
|
||
|
||
<p>This section defines the list of generators that should be run.</p>
|
||
|
||
<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>
|
||
|
||
<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>What follows is a guide to localizing to a non-English language
|
||
and/or locale. There are two parts: translating to different languages
|
||
and modifying to reflect local conventions for displaying data.</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 the skin configuration</h2>
|
||
|
||
<p>Next, you will need to go through <span class="code">skin.conf</span>
|
||
to translate labels and modify formats to follow local conventions.
|
||
</p>
|
||
|
||
<p>You will probably want to change the generic labels used for the
|
||
observation types:</p>
|
||
<pre class="tty">[Labels]
|
||
...
|
||
[[Generic]]
|
||
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>
|
||
<p>The hemisphere abbreviations may have to be changed: </p>
|
||
<pre class="tty">[Labels]
|
||
hemispheres = N, S, E, W</pre>
|
||
<p>The wind ordinal directions may have to be changed: </p>
|
||
<pre class='tty'>[Units]
|
||
...
|
||
[[Ordinates]]
|
||
# The ordinal directions. The last one should be for no wind direction
|
||
directions = N, NNE, NE, ENE, E, ESE, SE, SSE, S, SSW, SW, WSW, W, WNW, NW, NNW, N/A </pre>
|
||
<p>Don't forget the moon phases:</p>
|
||
<pre class="tty">[Almanac]
|
||
moon_phases = New, Waxing crescent, First quarter, Waxing gibbous, Full, Waning gibbous, Last quarter, Waning crescent</pre>
|
||
<p id="l11n_unit_labels">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 a few exceptions, used to
|
||
label the weewx and server "uptimes",
|
||
which can be found in sub-section
|
||
<span class="code">[Units][[Labels]]</span></p>
|
||
<pre class="tty">[Units]
|
||
...
|
||
[[Labels]]
|
||
...
|
||
day = " day", " days"
|
||
hour = " hour", " hours"
|
||
minute = " minute", " minutes"
|
||
second = " second", " seconds"</pre>
|
||
<p>By default, the time formats will use the local convention specified
|
||
by the LANG environment variable. These can be modified individually
|
||
in the <span class='code'>[Units][[TimeFormats]]</span> section.</p>
|
||
<pre class='tty'>[Units]
|
||
[[TimeFormats]]
|
||
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>
|
||
|
||
<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="customizing_units">Customizing the Units</h1>
|
||
|
||
<h2>Defining new units and unit groups</h2>
|
||
<p>
|
||
To define new units and unit groups, extend the units dictionary. This
|
||
is typically done by adding Python code to the file
|
||
<span class='code'>user/extensions.py</span>
|
||
</p>
|
||
<p>
|
||
For example, to add the unit group <span class='code'>group_depth</span>
|
||
with unit <span class='code'>inch</span> in US unit system and unit
|
||
<span class='code'>cm</span> in Metric and MetricWX unit systems:
|
||
</p>
|
||
<pre class='tty'>import weewx.units
|
||
weewx.units.USUnits['group_depth'] = 'inch'
|
||
weewx.units.MetricUnits['group_depth'] = 'cm'
|
||
weewx.units.MetricWXUnits['group_depth'] = 'cm'</pre>
|
||
<p>
|
||
In this case, it is not necessary to specify the conversions for inch,
|
||
cm, and mm since those are already defined and used by the unit groups
|
||
<span class='code'>group_rain</span> and
|
||
<span class='code'>group_length</span>. But if the new units do not
|
||
yet exist in weewx.units, this is how they would be defined:
|
||
</p>
|
||
<pre class='tty'>import weewx.units
|
||
weewx.units.default_unit_format_dict['inch'] = '%.2f'
|
||
weewx.units.default_unit_format_dict['cm'] = '%.2f'
|
||
weewx.units.default_unit_format_dict['mm'] = '%.2f'
|
||
weewx.units.default_unit_label_dict['inch'] = ' in'
|
||
weewx.units.default_unit_label_dict['cm'] = ' cm'
|
||
weewx.units.default_unit_label_dict['mm'] = ' mm'
|
||
weewx.units.conversionDict['inch'] = {'cm': lambda x : x * 2.54,
|
||
'mm': lambda x : x * 25.4}
|
||
weewx.units.conversionDict['cm'] = {'inch': lambda x : x * 0.393700787,
|
||
'mm': lambda x : x * 10.0}
|
||
weewx.units.conversionDict['mm'] = {'inch': lambda x : x * .0393700787,
|
||
'cm': lambda x : x * 0.10}</pre>
|
||
<p>
|
||
Each unit requires a default format, a default label, and possibly a
|
||
conversion function that specifies how the units are converted between
|
||
unit systems.
|
||
</p>
|
||
|
||
<h2>Assigning units to an observation</h2>
|
||
<p>
|
||
To associate an observation with a unit group, extend the units
|
||
observation group dictionary. This is typically done by adding Python
|
||
code to the file <span class='code'>user/extensions.py</span>
|
||
</p>
|
||
<p>
|
||
For example, to associate the observation
|
||
<span class='code'>snow_depth</span> with the group
|
||
<span class='code'>group_depth</span>:
|
||
</p>
|
||
<pre class='tty'>import weewx.units
|
||
weewx.units.obs_group_dict['snow_depth'] = 'group_depth'</pre>
|
||
<p>
|
||
Once the observation has been associated with a unit group, the unit
|
||
labels and other dot-code syntax will work for that observation.
|
||
</p>
|
||
|
||
|
||
<h1 id="service_engine">Customizing the 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 class="warning">Please note that the API to the service engine may change in future versions!</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>See the table <a href="#default_services">Default services</a> above for a list
|
||
of the services that are normally run.</p>
|
||
|
||
<h2 id="Customizing_a_service">Customizing a service</h2>
|
||
|
||
<p>The service <span class="code">weewx.engine.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="code">user/myprint.py</span>:
|
||
</p>
|
||
<pre class="tty">from weewx.engine 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 <span class="code">service_list</span>, located in <span class="code">[Engine][[Services]]</span>:
|
||
</p>
|
||
<pre class="tty">[Engine]
|
||
[[Services]]
|
||
...
|
||
report_services = <span class="highlight">user.myprint.MyPrint</span>, weewx.engine.StdReport</pre>
|
||
<p>Note that the <span class="code">report_services</span> 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>
|
||
|
||
<h2 id="Adding_a_service">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, which 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="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.engine 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 raised 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 KeyError, 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
|
||
|
||
# Be prepared to catch an exception in the case that the expression contains
|
||
# a variable that is not in the record:
|
||
try: # NOTE 2
|
||
# 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 3
|
||
# 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()
|
||
except NameError, e:
|
||
# The record was missing a named variable. Write a debug message, then keep going
|
||
syslog.syslog(syslog.LOG_DEBUG, "alarm: %s" % e)
|
||
|
||
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 three 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, <span
|
||
class="code">weewx.NEW_ARCHIVE_RECORD</span> in this example, and a
|
||
member function, <span class="code">self.newArchiveRecord</span>. When
|
||
the event <span class='code'>NEW_ARCHIVE_RECORD</span> occurs,
|
||
the function <span class="code">self.newArchiveRecord</span> will be called. There
|
||
are many other events that can be interecepted. Look in the file
|
||
<span class="code">weewx/__init__.py</span>.
|
||
</li>
|
||
<li>Some hardware does not emit all possible observation types in every record. So,
|
||
it's possible that a record may be missing some types that are used in the expression.
|
||
This try block will catch the <span class="code">NameError</span> exception that would
|
||
be raised should this occur.
|
||
</li>
|
||
<li>This is where the test is done for 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>Note that units must be the same as whatever is being used in your database.
|
||
That is, the same as what you specified in option
|
||
<a href="usersguide.htm#option_target_unit"><span class="code">target_unit</span></a>.</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. This is done by adding your service name to the list <span class="code">report_services</span>,
|
||
located in <span class="code">[Engine][[Services]]</span>: </p>
|
||
<pre class="tty">[Engine]
|
||
[[Services]]
|
||
report_services = weewx.engine.StdPrint, weewx.engine.StdReport<span
|
||
class="highlight">, examples.alarm.MyAlarm</span></pre>
|
||
<p>Again, note that the option <span class="code">report_services</span> must be all on
|
||
one line — 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 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="code">wee_database</span>.</p>
|
||
|
||
<p>This utility also has the ability to check a SQLite version of the archive
|
||
database for embedded strings (where a float is expected).</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 cmd">wee_database --help</pre>
|
||
<p>This will result in an output that looks something like this:</p>
|
||
<pre class="tty">
|
||
Usage: wee_database --help
|
||
wee_database --create-archive
|
||
[CONFIG_FILE|--config=CONFIG_FILE]
|
||
[--binding=BINDING_NAME]
|
||
wee_database --drop-daily
|
||
[CONFIG_FILE|--config=CONFIG_FILE]
|
||
[--binding=BINDING_NAME]
|
||
wee_database --backfill-daily
|
||
[CONFIG_FILE|--config=CONFIG_FILE]
|
||
[--binding=BINDING_NAME]
|
||
[--trans-days=DAYS]
|
||
wee_database --reconfigure
|
||
[CONFIG_FILE|--config=CONFIG_FILE]
|
||
[--binding=BINDING_NAME]
|
||
wee_database --string-check
|
||
[CONFIG_FILE|--config=CONFIG_FILE]
|
||
[--binding=BINDING_NAME] [--fix]
|
||
wee_database --transfer
|
||
[CONFIG_FILE|--config=CONFIG_FILE]
|
||
[--binding=BINDING_NAME]
|
||
--dest-binding=BINDING_NAME
|
||
[--dry-run]
|
||
|
||
|
||
Configure the weewx databases. Most of these functions are handled
|
||
automatically by weewx, but they may be useful as a utility in special cases.
|
||
In particular, the 'reconfigure' option can be useful if you decide to add or
|
||
drop data types from the database schema or change unit systems and the
|
||
'transfer' option is useful if converting from one database type to another.
|
||
|
||
Options:
|
||
-h, --help show this help message and exit
|
||
--config=CONFIG_FILE Use configuration file CONFIG_FILE.
|
||
--create-archive Create the archive database.
|
||
--drop-daily Drop the daily summary tables from a database.
|
||
--backfill-daily Backfill a database with daily summaries.
|
||
--reconfigure Create a new archive database using configuration
|
||
information found in the configuration file. In
|
||
particular, the new database will use the unit system
|
||
found in option [StdConvert][target_unit]. The new
|
||
database will have the same name as the old database,
|
||
with a '_new' on the end.
|
||
--string-check Check a sqlite version of the archive database to see
|
||
whether it contains embedded strings.
|
||
--fix Fix any embedded strings in a sqlite database.
|
||
--transfer Transfer the weewx archive from source database to
|
||
destination database.
|
||
--binding=BINDING_NAME
|
||
The data binding. Default is 'wx_binding'.
|
||
--dest-binding=BINDING_NAME
|
||
The destination data binding.
|
||
--dry-run Print what would happen but do not do it.
|
||
--trans-days=DAYS Limit backfill transactions to no more than DAYS days
|
||
of archive data at a time. Default value is 5. May be
|
||
increased for a slight speed increase or reduced to
|
||
reduce memory usage.
|
||
|
||
If you are using a MySQL database it is assumed that you have the appropriate
|
||
permissions for the requested operation.
|
||
</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>The steps include:</p>
|
||
<ol>
|
||
<li>Create a custom service that retrieves the data</li>
|
||
<li>Add the new type to the archive database</li>
|
||
<li>Specify units for the new type</li>
|
||
<li>Use the new type in templates and plots</li>
|
||
</ol>
|
||
|
||
<h3>Create a custom service</h3>
|
||
|
||
<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">import weewx
|
||
from weewx.engine import StdService
|
||
|
||
class AddElectricity(StdService):
|
||
|
||
def __init__(self, engine, config_dict):
|
||
# Initialize my superclass first:
|
||
super(AddElectricity, self).__init__(engine, config_dict)
|
||
# Bind to any new archive record events:
|
||
self.bind(weewx.NEW_ARCHIVE_RECORD, self.new_archive_packet)
|
||
|
||
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>To make sure your service gets run, you need to add it to one of the
|
||
service lists in section <span class="code">[Engine]</span> in <span class="code">weewx.conf</span>. But where?
|
||
You want
|
||
to make sure it runs before the archiving service, so it must be
|
||
before option <span class="code">archive_services</span>. You do not want it to run
|
||
before the main loop runs, so it can't be in <span class="code">prep_services</span>. Probably
|
||
the best place is at the end of <span class="code">process_services</span>. When you're
|
||
done, your section <span class="code">[Engine]</span> will look something like this:</p>
|
||
<pre class="tty">
|
||
[Engine]
|
||
# This section configures the maine engine. It is for advanced customization.
|
||
|
||
[[Services]]
|
||
# These are the services the main engine should run:
|
||
prep_services = weewx.engine.StdTimeSynch
|
||
process_services = weewx.engine.StdConvert, weewx.engine.StdCalibrate, weewx.engine.StdQC, weewx.wxservices.StdWXCalculate<span
|
||
class="highlight">, user.electricity.AddElectricity</span>
|
||
archive_services = weewx.engine.StdArchive
|
||
restful_services = weewx.restx.StdStationRegistry, weewx.restx.StdWunderground, weewx.restx.StdPWSweather, weewx.restx.StdCWOP, weewx.restx.StdWOW, weewx.restx.StdAWEKAS
|
||
report_services = weewx.engine.StdPrint, weewx.engine.StdReport</pre>
|
||
|
||
<h3 id="add_archive_type">Add 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, <span class="code">weewx</span> won't know
|
||
where to store it. How would you add such
|
||
a type?
|
||
</p>
|
||
|
||
<p>The utility <span class="code">wee_database</span> can be used to do this. It will
|
||
create a new database that is similar to the old database, except it has the new type in its
|
||
schema.</p>
|
||
|
||
<p>Here's our general strategy:</p>
|
||
<ol>
|
||
<li>Extend the existing schema with the new type <span class="code">electricity</span>.</li>
|
||
<li>Modify the <span class="code">wx_binding</span> to use the new schema
|
||
instead of the old.
|
||
</li>
|
||
<li>Make sure you have the necessary permissions to create a new
|
||
database.
|
||
</li>
|
||
<li>Use the utility <span class="code">wee_database</span> to create the
|
||
new database and 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>
|
||
</ol>
|
||
<p>Here is the recipe that follows that strategy:</p>
|
||
<ol>
|
||
<li>
|
||
<p>
|
||
<strong>Add the new type to our existing schema.</strong> The weather
|
||
schema that comes with <span class="code">weewx</span> is the same as
|
||
what wview uses. It's located in the file <span class="code">schemas/wview.py</span>
|
||
— take a look at it now. We could just modify it <em>in situ</em>,
|
||
but that would run the risk of confusing the two versions.
|
||
Alternatively, we could copy the file over to a new location, and then
|
||
modify that. But, because our change is just a simple addition, we're
|
||
going to import the wview schema and just add on our new type. There's
|
||
also no reason to create a new file. Why not just do it in the file we
|
||
already have, <span class="code">user/electricity.py</span>? Add to
|
||
the bottom of the file:
|
||
</p> <pre class="tty">import schemas.wview
|
||
schema_with_electricity = schemas.wview.schema + [('electricity', 'REAL')]</pre>
|
||
<p>
|
||
This creates a new schema (it will have the name <span class="code">user.electricity.schema_with_electricity</span>),
|
||
that is just like the old one, except it has a new type <span
|
||
class="code">electricity</span> tacked on to the end.
|
||
</p>
|
||
</li>
|
||
<li>
|
||
<p>
|
||
<strong>Modify <span class="code">wx_binding</span>.
|
||
</strong> When it creates the new, modified database, <span class="code">wee_database</span>
|
||
needs to know to use your new schema instead of the old, wview schema.
|
||
You do this by changing the option <span class="code">schema</span> in
|
||
section <span class="code">[DataBindings]</span> in <span class="code">weewx.conf</span>.
|
||
It will look like this when you're done:
|
||
</p>
|
||
|
||
<pre class="tty">[DataBindings]
|
||
[[wx_binding]]
|
||
database = archive_sqlite
|
||
table_name = archive
|
||
manager = weewx.wxmanager.WXDaySummaryManager
|
||
<span class="highlight">schema = user.electricity.schema_with_electricity</span></pre>
|
||
</li>
|
||
|
||
<li>
|
||
<p>
|
||
<strong>Check permissions.</strong> <span class="code">wee_database</span> 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 create it. In particular, if you
|
||
are using MySQL, you will need <span class="code">CREATE</span>
|
||
privileges:
|
||
</p>
|
||
<pre class="tty">mysql> <span class="cmd">GRANT select, update, create, delete, insert ON weewx_new.* TO weewx@localhost;</span></pre>
|
||
</li>
|
||
<li>
|
||
<p>
|
||
<strong>Create and populate the new database.</strong>
|
||
Now run the utility <span class="code">wee_database</span>
|
||
with the <span class="code">--reconfigure</span> option and the path
|
||
to the configuration file:
|
||
</p>
|
||
|
||
<p class="tty cmd">wee_database weewx.conf --reconfigure</p>
|
||
|
||
<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>
|
||
</li>
|
||
<li>
|
||
<p>
|
||
<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 cmd">cd <span class="symcode">SQLITE_ROOT</span>
|
||
mv weewx.sdb_new weewx.sdb</pre>
|
||
<p>For MySQL:</p> <pre class="tty"><span class="cmd">mysql -u <username> --password=<mypassword></span>
|
||
mysql><span class="cmd"> DROP DATABASE weewx;</span> # Delete the old database
|
||
mysql><span class="cmd"> CREATE DATABASE weewx;</span> # Create a new one with the same name
|
||
mysql><span class="cmd"> RENAME TABLE weewx_new.archive TO weewx.archive;</span> # Rename to the nominal name</pre>
|
||
</li>
|
||
<li>
|
||
<p>
|
||
It's worth noting that there's actually a hidden, last step:
|
||
recreating the daily summaries inside the new database. This will be
|
||
done automatically by <span class="code">weewx</span> at the next
|
||
startup. Alternatively, it can be done manually using the <span
|
||
class="code">wee_database</span> utility and the <span
|
||
class="code">--backfill-daily</span> option:
|
||
</p>
|
||
<pre class="tty cmd">wee_database weewx.conf --backfill-daily</pre>
|
||
</li>
|
||
</ol>
|
||
|
||
<h3>Specify units for the new type</h3>
|
||
|
||
<p>To make unit conversions and formatting work automatically for the
|
||
new data type, the data type must be assigned a unit group.</p>
|
||
|
||
<p>Extend the units dictionary by adding entries in the file
|
||
<span class='code'>user/extensions.py</span></p>
|
||
<pre class='tty'>import weewx.units
|
||
weewx.units.obs_group_dict['voltage'] = 'group_volt'
|
||
weewx.units.obs_group_dict['electricity'] = 'group_power'</pre>
|
||
<p>This will make reports and plots use formats and conversions defined
|
||
for <span class='code'>group_volt</span> whenever they encounter data
|
||
with type <span class='code'>voltage</span>, and
|
||
<span class='code'>group_power</span> whenever they encounter data
|
||
with type <span class='code'>electricity</span>.</p>
|
||
|
||
<h3>Use 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">
|
||
<tbody>
|
||
<tr class="first_row">
|
||
<td>Tag</td>
|
||
<td>Meaning</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 are stored in the databases using US Customary units
|
||
and, normally, you don't care; it is an "implementation detail".
|
||
Data can always be displayed using any units you want. The
|
||
<a href="#customizing_reports">Customizing reports</a> section explains
|
||
how to do this. 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 copying it to a new
|
||
database, performing the unit conversion along the way. You then use this
|
||
new database.
|
||
</p>
|
||
|
||
<p>Here is the general strategy:</p>
|
||
<ol>
|
||
<li>Modify <span class="code">weewx.conf</span> to reflect your
|
||
choice of the new unit system to use. Your choices are <span
|
||
class='code'>US</span>, <span class="code">METRIC</span>, or <span
|
||
class="code">METRICWX</span>. See the
|
||
<em><a href="#units">Appendix: Units</a></em>
|
||
for the exact differences between these three choices.
|
||
</li>
|
||
<li>Make sure you have the necessary permissions to create the new
|
||
database.
|
||
</li>
|
||
<li>Use the utility <span class='code'>wee_database</span> to
|
||
create the new database and 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>
|
||
</ol>
|
||
<p>Here is the recipe that follows that strategy:</p>
|
||
<ol>
|
||
<li>
|
||
<p>
|
||
<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 = METRICWX</pre>
|
||
</li>
|
||
<li>
|
||
<p>
|
||
<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>
|
||
</li>
|
||
<li>
|
||
<p>
|
||
<strong>Create and populate the new database.</strong>
|
||
Now run the utility <span class="code">wee_database</span>
|
||
with the <span class="code">--reconfigure</span> option:
|
||
</p>
|
||
<pre class="tty cmd">wee_database weewx.conf --reconfigure</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="code">user/schemas.py</span>, and populate it with data
|
||
from the old database, while performing the unit conversion.
|
||
</p>
|
||
</li>
|
||
<li>
|
||
<p>
|
||
<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 cmd">cd <span class="symcode">SQLITE_ROOT</span>
|
||
mv weewx.sdb_new weewx.sdb</pre>
|
||
<p>For MySQL:</p> <pre class="tty"><span class="cmd">mysql -u <username> --password=<mypassword></span>
|
||
mysql><span class="cmd"> DROP DATABASE weewx;</span> # Delete the old database
|
||
mysql><span class="cmd"> CREATE DATABASE weewx;</span> # Create a new one with the same name
|
||
mysql><span class="cmd"> RENAME TABLE weewx_new.archive TO weewx.archive;</span> # Rename to the nominal name</pre>
|
||
</li>
|
||
<li>
|
||
<p>
|
||
It's worth noting that there's actually a hidden, last step:
|
||
recreating the daily summaries inside the new database. This will be
|
||
done automatically by <span class="code">weewx</span> at the next
|
||
startup. Alternatively, it can be done manually using the <span
|
||
class="code">wee_database</span> utility and the <span
|
||
class="code">--backfill-daily</span> option:
|
||
</p>
|
||
<pre class="tty cmd">wee_database weewx.conf --backfill-daily</pre>
|
||
</li>
|
||
</ol>
|
||
|
||
<h2>Dropping and rebuilding the daily summaries</h2>
|
||
|
||
<p>The tool <span class="code">wee_database</span> can also be used to drop the daily
|
||
summaries:</p>
|
||
<pre class="tty cmd">wee_database weewx.conf --drop-daily</pre>
|
||
<p>The summaries will automatically be rebuilt the next time <span class="code">weewx</span> starts,
|
||
or they can be rebuilt with the tool:</p>
|
||
<pre class="tty cmd">wee_database weewx.conf --backfill-daily</pre>
|
||
|
||
<h1 id="import">Importing observation data</h1>
|
||
|
||
<p>Some <span class="code">weewx</span> users will have historical data from
|
||
another source (eg other weather station software or a manually compiled
|
||
file) which they wish to import into <span class="code">weewx</span>.
|
||
Such data can, depending upon the source, be imported automatically
|
||
using the <span class="code">wee_import</span> utility. This section
|
||
details the use of the <span class="code">wee_import</span> utility.
|
||
</p>
|
||
|
||
<p>The <span class="code">wee_import</span> utility supports importing
|
||
observational data from the following sources:</p>
|
||
<ul>
|
||
<li>a single Comma Separated Values (CSV) format file</li>
|
||
<li>the historical observations of a Weather Underground personal
|
||
weather station</li>
|
||
<li>one or more Cumulus monthly log files</li>
|
||
</ul>
|
||
|
||
<h2 id='import_help'><span class="code">wee_import</span> help</h2>
|
||
|
||
<p>Before starting, it's worth running the utility with the
|
||
<span class="config_option">--help</span> flag to see how
|
||
<span class="code">wee_import</span> is used:</p>
|
||
|
||
<pre class="tty cmd">wee_import --help</pre>
|
||
|
||
<p>This will result in an output that looks something like this:</p>
|
||
|
||
<pre class="tty">Usage: wee_import --help
|
||
wee_import --version
|
||
wee_import --import-config=IMPORT_CONFIG_FILE
|
||
[--config=CONFIG_FILE]
|
||
[--date=YYYY/MM/DD|'YYYY/MM/DD hh:mm'|'YYYY/MM/DD (hh:mm)-YYYY/MM/DD (hh:mm)']
|
||
[--dry-run]
|
||
[--verbose]
|
||
[--log=-]
|
||
|
||
|
||
Import observation data into a weewx archive.
|
||
|
||
Options:
|
||
-h, --help show this help message and exit
|
||
--config=CONFIG_FILE Use weewx configuration file CONFIG_FILE.
|
||
--import-config=IMPORT_CONFIG_FILE
|
||
Use import configuration file IMPORT_CONFIG_FILE.
|
||
--dry-run Print what would happen but do not do it.
|
||
--date=YYYY-MM-DD Date or time to import as a string of form YYYY/MM/DD
|
||
or 'YYYY/MM/DD hh:mm'. A date range or date-time range
|
||
may be specified by separating two date strings or two
|
||
date-time strings with a hyphen. Arguments that
|
||
include hh:mm must be enclosed in quotation marks.
|
||
--log=- Control wee_import log output. By default log output
|
||
is sent to the same log file as used by weewx.
|
||
wee_import logging may be disabled by using '--
|
||
log=-'.Some weewx API log output cannot be controlled
|
||
by wee_import and will be sent to to the default log
|
||
file irrespective of the '--log' option.
|
||
--verbose Print useful extra output.
|
||
--version Display wee_import version number.
|
||
|
||
wee_import will import data from an external source into a weewx
|
||
archive. Daily summaries are updated as each archive record is
|
||
imported so there should be no need to separately drop and rebuild
|
||
the daily summaries using the wee_database utility.</pre>
|
||
|
||
<h2><span id='common_options'>Command line options</span></h2>
|
||
|
||
<p>The <span class="code">wee_import</span> command line options are
|
||
described in more detail below:</p>
|
||
|
||
<h4><span class="config_option">--config</span></h4>
|
||
|
||
<p>The utility is pretty good at "guessing" where your configuration file
|
||
<span class="code">weewx.conf</span> is, but if you've done an unusual
|
||
install, you may have to tell it explicitly. You can do this by using
|
||
the <span class="config_option">--config</span> option:</p>
|
||
|
||
<pre class="tty">wee_import --config=/this/folder/weewx.conf --import-config=/folder/import.conf
|
||
</pre>
|
||
|
||
<h4><span class="config_option">--import-config</span></h4>
|
||
|
||
<p><span class="code">wee_import</span> uses a secondary configuration file to
|
||
store various import parameters. The
|
||
<span class="config_option">--import-config</span> command line option
|
||
is mandatory for all imports. Example import configuration files for
|
||
each type of import supported by <span class="code">wee_import</span>
|
||
are provided in the <span class="code">util/import</span> folder. These
|
||
example files are best used by making a copy of the applicable example
|
||
file in a working directory and then modifying the duplicate file to
|
||
suit your needs. The <span class="config_option">--import-config</span>
|
||
command line option is used as follows:</p>
|
||
|
||
<pre class="tty">wee_import --import-config=/folder/import.conf
|
||
</pre>
|
||
|
||
<h4><span class="config_option">--dry-run</span></h4>
|
||
|
||
<p>The inclusion of the <span class="config_option">--dry-run</span> command
|
||
line option will cause the import to proceed but no actual data will be
|
||
saved to the database. This is a useful option to use when first
|
||
importing data.</p>
|
||
|
||
<pre class="tty">wee_import --import-config=/folder/import.conf --dry-run
|
||
</pre>
|
||
|
||
<h4><span class="config_option">--date</span></h4>
|
||
|
||
<p>The date-time range of records to be imported can be specified by use of
|
||
the <span class="config_option">--date</span> command line option. The
|
||
<span class="config_option">--date</span> command line option can
|
||
specify a single date, as single date-time, a date range or a date-time
|
||
range. The date format used is <span class="code">YYYY/MM/DD</span> and
|
||
the date-time format <span class="code">YYYY/MM/DD HH:MM</span>. A range
|
||
is specified by separating two date or date-time formats by a hyphen,
|
||
eg <span class="code">'2015/12/1-2015/12/30'</span>. Note that the
|
||
date-time or date-time range string must be enclosed in single or double
|
||
quotation marks. The effect of the different
|
||
<span class="config_option">--date</span> command line option values
|
||
is shown in the following table:</p>
|
||
|
||
<table class="indent" style="width:50%" summary="--date_option operation">
|
||
<tbody>
|
||
<tr class="first_row">
|
||
<td><span class="config_option">--date</span> command line option setting</td>
|
||
<td>Records imported for a CSV or Cumulus import</td>
|
||
<td>Records imported for a Weather Underground import</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="code first_col">omitted<br>(ie the default)</td>
|
||
<td>All available records</td>
|
||
<td>Todays records only</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="code first_col">--date 2015/12/22</td>
|
||
<td>All records from 2015/12/22 00:00 (inclusive) to 2015/12/23 00:00 (exclusive)</td>
|
||
<td>All records from 2015/12/22 00:00 (inclusive) to 2015/12/23 00:00 (exclusive)</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="code first_col">--date "2015/12/22 22:30"</td>
|
||
<td>The record timestamped 2015/12/22 22:30 only</td>
|
||
<td>The record timestamped 2015/12/22 22:30 only</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="code first_col">--date 2015/12/22-2016/02/20</td>
|
||
<td>All records from 2015/12/22 00:00 (inclusive) to 2016/2/21 00:00 (exclusive)</td>
|
||
<td>All records from 2015/12/22 00:00 (inclusive) to 2016/2/21 00:00 (exclusive)</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="code first_col">--date "2016/3/18 15:29-2016/6/20 22:00"</td>
|
||
<td>All records from 2016/3/18 15:29 (inclusive) to 2016/6/20 22:00 (exclusive)</td>
|
||
<td>All records from 2016/3/18 15:29 (inclusive) to 2016/6/20 22:00 (exclusive)</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
|
||
<p class="note" style="display:inline-block; width:70%">
|
||
<b>Note</b><br/>If the <span class="config_option">--date</span>
|
||
command line option is omitted the default is to import all available
|
||
records when importing from a CSV or Cumulus source or to import today's
|
||
records only when importing from Weather Underground.
|
||
</p>
|
||
|
||
<h4><span class="config_option">--log</span></h4>
|
||
|
||
<p>The <span class="config_option">--log</span> option controls the
|
||
<span class="code">wee_import</span> log output. Omitting the option
|
||
will result in <span class="code">wee_import</span> log output being
|
||
sent to the <span class="code">weewx</span> log file (nominally the
|
||
system log, refer to
|
||
<em><a href="usersguide.htm#monitoring">Monitoring <span class="code">weewx</span></a></em>
|
||
and
|
||
<em><a href="usersguide.htm#Where_to_find_things">Where to find things</a></em>
|
||
to find it). <span class="code">wee_import</span> log output can be
|
||
disabled by using <span class="config_option">--log=-</span>. The
|
||
<span class="config_option">--log</span> command line option is used as
|
||
follows:
|
||
</p>
|
||
|
||
<pre class="tty">wee_import --import-config=/folder/import.conf --log=-
|
||
</pre>
|
||
|
||
<h4><span class="config_option">--verbose</span></h4>
|
||
|
||
<p>Inclusion of the <span class="config_option">--verbose</span> command
|
||
line option will cause additional information to be printed during
|
||
<span class="code">wee_import</span> execution.</p>
|
||
|
||
<pre class="tty">wee_import --import-config=/folder/import.conf --verbose
|
||
</pre>
|
||
|
||
<h2>CSV observations</h2>
|
||
|
||
<p><span class="code">wee_import</span> can import observational data from
|
||
a single CSV file. To be imported by
|
||
<span class="code">wee_import</span>, the CSV source file must be
|
||
structured as follows:</p>
|
||
|
||
<ul>
|
||
<li>The file must have a header row consisting of a comma separated
|
||
list of field names. The field names can be any valid string as long
|
||
as each field name is unique within the list. There is no
|
||
requirement for the field names to be in any particular order as
|
||
long as the same order is used for the observations on each row in
|
||
the file. These field names will be mapped to
|
||
<span class="code">weewx</span> field names in the
|
||
<span class="code">[CSV]</span> section of the import configuration
|
||
file.</li>
|
||
|
||
<li>Observation data for a given date-time must be listed on a
|
||
single line with individual fields separated by a comma. The fields
|
||
must be in the same order as the field names in the header row.</li>
|
||
|
||
<li>Blank fields are represented by the use of white space or no
|
||
space only between commas.</li>
|
||
|
||
<li>There must a field that represents the date-time of the
|
||
observations on each line. This date-time field must be either a
|
||
Unix epoch timestamp or any date-time format that can be
|
||
represented using <em>
|
||
<a href="https://docs.python.org/2/library/datetime.html#strftime-and-strptime-behavior">Python strptime() format codes</a></em>.</li>
|
||
</ul>
|
||
|
||
<p>A CSV file suitable for import by <span class="code">wee_import</span>
|
||
may look like this:</p>
|
||
|
||
<pre class="tty">Time,Temp,Dewpoint,Press,WindDir,WindSpeed,WindGust,Hum,dailyrain,SolarRad
|
||
2016-02-01 00:00:00,13.5,9.2,1005.6,359,0.0,0.0,75,12.0,0.00
|
||
2016-02-01 00:05:00,13.4,9.3,1005.6,355,0.0,0.0,76,12.0,0.00
|
||
2016-02-01 00:10:00,13.3,9.4,1005.6,259,0.0,1.6,77,14.0,0.00
|
||
2016-02-01 00:20:00,13.2,9.4,1005.6,10,0.0,1.6,78,16.0,0.00
|
||
2016-02-01 00:25:00,13.2,9.6,1005.6,15,0.0,1.6,79,20.0,0.00
|
||
2016-02-01 00:30:00,13.1,9.6,1005.3,13,0.0,0.0,79,20.0,0.00
|
||
2016-02-01 00:35:00,13.1,9.7,1005.3,22,1.6,3.2,80,20.0,0.00
|
||
2016-02-01 00:40:00,13.0,9.6,1005.3,25,0.0,1.6,80,22.0,0.00
|
||
2016-02-01 00:45:00,12.9,9.8,1005.3,22,1.6,3.2,81,23.0,0.00
|
||
2016-02-01 00:50:00,12.9,9.7,1005.3,22,1.6,1.6,81,23.0,0.00</pre>
|
||
|
||
<h3><span class="code">weewx</span> archive fields populated during a CSV import</h3>
|
||
|
||
<p>The <span class="code">weewx</span> archive fields populated during a
|
||
CSV import depend on the CSV-to-<span class="code">weewx</span> field
|
||
mappings specified in <span class="code">[CSV]</span> section in the
|
||
import configuration file. If a valid field mapping exists, the
|
||
<span class="code">weewx</span> field exists in the
|
||
<span class="code">weewx</span> archive table schema and provided the
|
||
mapped CSV field contains valid data, then the corresponding
|
||
<span class="code">weewx</span> field will populated. Note that the CSV
|
||
import is the only import supported by
|
||
<span class="code">wee_import</span> that allows any
|
||
<span class="code">weewx</span> archive field to be populated.
|
||
</p>
|
||
|
||
<p class="note" style="display:inline-block; width:70%">
|
||
<b>Note</b><br/>The use of the
|
||
<span class="config_option">calc_missing</span> option in the import
|
||
configuration file (refer to
|
||
<em><a href="#csv_calc_missing">calc_missing</a></em>) may result in a
|
||
number of derived fields being calculated from the imported data. If
|
||
these derived fields exist in the in-use database schema they will be
|
||
saved to the database as well.
|
||
</p>
|
||
|
||
<h3>Importing observations from a CSV file</h3>
|
||
|
||
<p>To import observations from a CSV file:</p>
|
||
|
||
<ol>
|
||
<li>Ensure the source data file is in a folder accessible by the machine
|
||
that will run <span class="code">wee_import</span>. For the
|
||
purposes of these instructions the source data file
|
||
<span class="code">data.csv</span> located in the
|
||
<span class="code">/var/tmp</span> folder will be used.</li>
|
||
|
||
<li>As <span class="code">wee_import</span> will make alterations to the
|
||
<span class="code">weewx</span> database make a backup copy of the
|
||
<span class="code">weewx</span> database for use should the import
|
||
go awry.</li>
|
||
|
||
<li>If an import configuration file has not already been produced for
|
||
this CSV import, make a copy of the example CSV import configuration
|
||
file provided in the <span class="code">weewx/util/import</span>
|
||
directory. In this case we will make a copy of the example CSV
|
||
import configuration file and save it as
|
||
<span class="code">csv.conf</span> in the
|
||
<span class="code">/var/tmp</span> directory:</li>
|
||
|
||
<pre class="tty">$ cp /home/weewx/util/import/csv-example.conf /var/tmp/csv.conf
|
||
</pre>
|
||
|
||
<li>Confirm the <span class="code">source</span> option (refer to
|
||
<em><a href="#import_config_source"><span class="code">source</span></a></em>)
|
||
in the import configuration file <span class="code">csv.conf</span>
|
||
(refer to
|
||
<em><a href="#import_config">The configuration import configuration file</a></em>)
|
||
is set as follows:</li>
|
||
|
||
<pre class="tty">source = CSV</span></pre>
|
||
|
||
<li>Confirm the following options in the <span class="code">[CSV]</span>
|
||
section of the import configuration file
|
||
<span class="code">csv.conf</span> (refer to
|
||
<em><a href="#import_config">The import configuration file</a></em>)
|
||
are correctly set:</li>
|
||
|
||
<ul>
|
||
<li><strong><span class="code">file</span></strong>.
|
||
The full path and file name of the file containing the CSV
|
||
formatted data to be imported. For the example below we will
|
||
use the file <span class="code">/var/tmp/csv/data.csv</span>
|
||
as the CSV source data file. Refer to
|
||
<em><a href="#csv_file"><span class="code">file</span></a></em>.</li>
|
||
<li><strong><span class="code">interval</span></strong>.
|
||
Determines how the <span class="code">weewx</span> interval
|
||
field is derived. Refer to
|
||
<em><a href="#csv_interval"><span class="code">interval</span></a></em>.</li>
|
||
<li><strong><span class="code">qc</span></strong>. Determines
|
||
whether quality control checks are performed on the imported
|
||
data. Refer to
|
||
<em><a href="#csv_qc"><span class="code">qc</span></a></em>.</li>
|
||
<li><strong><span class="code">calc_missing</span></strong>.
|
||
Determines whether missing derived observations will be
|
||
calculated from the imported data. Refer to
|
||
<em><a href="#csv_calc_missing"><span class="code">calc_missing</span></a></em>.</li>
|
||
<li><strong><span class="code">tranche</span></strong>. The
|
||
number of records written to the
|
||
<span class="code">weewx</span> database in each transaction.
|
||
Refer to
|
||
<em><a href="#csv_tranche"><span class="code">tranche</span></a></em>.</li>
|
||
<li><strong><span class="code">UV_sensor</span></strong>.
|
||
Whether a UV sensor was installed when the source data was
|
||
produced. Refer to
|
||
<em><a href="#csv_UV"><span class="code">UV_sensor</span></a></em>.</li>
|
||
<li><strong><span class="code">solar_sensor</span></strong>.
|
||
Whether a solar radiation sensor was installed when the
|
||
source data was produced. Refer to
|
||
<em><a href="#csv_solar"><span class="code">solar_sensor</span></a></em>.</li>
|
||
<li><strong><span class="code">raw_datetime_format</span></strong>.
|
||
The format of the imported date time field. Refer to
|
||
<em><a href="#csv_raw_datetime_format"><span class="code">raw_datetime_format</span></a></em>.</li>
|
||
<li><strong><span class="code">rain</span></strong>. Determines
|
||
how the <span class="code">weewx</span> rain field is
|
||
derived. Refer to
|
||
<em><a href="#csv_rain"><span class="code">rain</span></a></em>.</li>
|
||
<li><strong><span class="code">wind_direction</span></strong>.
|
||
Determines how imported wind direction fields are
|
||
interpreted. Refer to
|
||
<em><a href="#csv_wind_direction"><span class="code">wind_direction</span></a></em>.</li>
|
||
<li><strong><span class="code">[[Map]]</span></strong>. Defines
|
||
the mapping between imported data fields and
|
||
<span class="code">weewx</span> archive fields. Also defines
|
||
the units of measure for each imported field. Refer to
|
||
<em><a href="#csv_map"><span class="code">[[Map]]</span></a></em>.</li>
|
||
</ul>
|
||
|
||
<li>When first importing data it is often prudent to do a dry run import
|
||
before any data is actually imported. A dry run import will perform
|
||
all steps of the import without actually writing imported data to
|
||
the <span class="code">weewx</span> database. In addition,
|
||
consideration should be given to any additional command line options
|
||
to be used such as <span class="code">--date</span>. The available
|
||
command line options are shown in the
|
||
<span class="code">wee_import --help</span> output above (refer to
|
||
<em><a href="#import_help">wee_import help</a></em>). Additional
|
||
details are also provided in the
|
||
<em><a href="#common_options">Command line options</a></em> section.
|
||
To perform a dry run import enter the following command:</li>
|
||
|
||
<pre class="tty">wee_import --import-config=/var/tmp/csv.conf --dry-run
|
||
</pre>
|
||
|
||
<p>This will result in a short preamble giving the user brief
|
||
details on the data source, its destination and some other
|
||
details on how the data will be processed. The import will then
|
||
be performed but no data is written to the
|
||
<span class="code">weewx</span> database. Upon completion a
|
||
brief summary of the records processed is provided. The output
|
||
should be similar to:
|
||
</p>
|
||
|
||
<pre class="tty">Starting wee_import...
|
||
A CSV import from source file '/var/tmp/data.csv' has been requested.
|
||
Using database binding 'wx_binding', which is bound to database 'weewx.sdb'
|
||
Destination table 'archive' unit system is '0x01' (US).
|
||
Any missing derived observations WILL be calculated.
|
||
All weewx UV fields will be set to None.
|
||
All weewx radiation fields will be set to None.
|
||
This is a dry run, imported data WILL NOT be saved to archive.
|
||
Starting dry run import ...
|
||
70685 records identified for import.
|
||
Records processed: 70685; Unique records: 70685; Last timestamp: 2010-09-04 04:20:00 AEST (1283538000)
|
||
Finished dry run import. 70685 records were processed and 70685 unique records would have been imported.
|
||
</pre>
|
||
|
||
<p class="note" style="display:inline-block; width:70%">
|
||
<b>Note</b><br/>As the <span class="code">weewx</span> database is
|
||
not altered when the <span class="code">--dry-run</span> command
|
||
line option is used, <span class="code">wee_import</span> log output
|
||
is suspended during a dry run import. In effect, the use of
|
||
<span class="code">--dry-run</span> is equivalent to
|
||
<span class="code">--dry-run --log=-</span>. During a dry run import
|
||
the only <span class="code">wee_import</span> output is that
|
||
displayed on <span class="code">stdout</span>(console).
|
||
</p>
|
||
|
||
<li>Once the dry run results are satisfactory the source data can be
|
||
imported using the following command:</li>
|
||
|
||
<pre class="tty">wee_import --import-config=/var/tmp/csv.conf</pre>
|
||
|
||
<p>This will result in a short preamble giving the user brief details
|
||
on the data source, its destination and some other details on how
|
||
the data will be processed. This output will vary slightly
|
||
depending on what command line options have been used. At the end
|
||
of the preamble the user will be prompted as to whether to proceed
|
||
or not with the import:</p>
|
||
|
||
<pre class="tty">Starting wee_import...
|
||
A CSV import from source file '/var/tmp/data.csv' has been requested.
|
||
Using database binding 'wx_binding', which is bound to database 'weewx.sdb'
|
||
Destination table 'archive' unit system is '0x01' (US).
|
||
Any missing derived observations WILL be calculated.
|
||
All weewx UV fields will be set to None.
|
||
All weewx radiation fields will be set to None.
|
||
This is NOT a dry run, imported data WILL be saved to archive.
|
||
Starting import ...
|
||
70685 records identified for import.
|
||
Proceeding will save all imported records in the weewx archive.
|
||
Are you sure you want to proceed (y/n)?
|
||
</pre>
|
||
|
||
<li>The preamble should be read carefully and if the import parameters
|
||
are acceptable enter <span class="code">y</span> to proceed with the
|
||
import or <span class="code">n</span> to abort the import. If the
|
||
import is aborted the user is informed of this and returned to the
|
||
command line. If the user proceeds with the import then the source
|
||
data will be imported, processed and saved in the
|
||
<span class="code">weewx</span> database. Information on the
|
||
progress of the import will be displayed similar to the following:
|
||
</li>
|
||
|
||
<pre class="tty">Records processed: 250; Unique records: 250; Last timestamp: 2010-02-09 19:25:00 AEST (1265707500)
|
||
</pre>
|
||
|
||
<p>The line commencing with <span class="code">Records processed</span>
|
||
should update as records are imported with progress information on
|
||
number of records processed, number of unique records imported and
|
||
the date time of the latest record processed. When the import is
|
||
complete a brief summary is displayed similar to the following:</p>
|
||
|
||
<pre class="tty">Records processed: 70685; Unique records: 70685; Last timestamp: 2010-09-04 04:20:00 AEST (1283538000)
|
||
Finished import. 70685 raw records resulted in 70685 unique records being processed in 56.98 seconds.
|
||
Whilst 70685 unique records were processed those with a timestamp already in the archive
|
||
will not have been imported. Confirm successful import in the weewx log file.
|
||
</pre>
|
||
|
||
<li>Whilst <span class="code">wee_import</span> will advise of the
|
||
number of records processed and the number of unique records found,
|
||
<span class="code">wee_import</span> does know how many, if any, of
|
||
the imported records were successfully saved to the database. The
|
||
user should look carefully through the
|
||
<span class="code">weewx</span> log file covering the
|
||
<span class="code">wee_import</span> session and take note of any
|
||
records that were not imported. The most common reason for imported
|
||
records not being saved to the database is because a record with
|
||
that timestamp already exists in the database, in such cases
|
||
something similar to following will be found in the log:</li>
|
||
|
||
<pre class="tty">
|
||
Aug 22 14:38:28 jessie2 weewx[863]: manager: unable to add record 2010-09-04 04:20:00 AEST (1283538000) to database 'weewx.sdb': UNIQUE constraint failed: archive.dateTime
|
||
</pre>
|
||
|
||
<p>In such cases the user should take note of the timestamp of the
|
||
record(s) concerned and make a decision about whether to delete the
|
||
pre-existing record and re-import the record or retain the
|
||
pre-existing record.</p>
|
||
|
||
<li>If errors were encountered, or the user suspects the
|
||
<span class="code">weewx</span> database has been contaminated with
|
||
incorrect data, then the imported data may be removed by:</li>
|
||
|
||
<ul>
|
||
<li>Manually deleting the contaminated data from the
|
||
<span class="code">weewx</span> archive database using SQL
|
||
commands. The simplicity of this process will depend on the
|
||
users ability to use SQL, the amount of data imported and
|
||
whether the imported data was dispersed amongst existing
|
||
data can be identified in a single block only. Once any
|
||
contaminated data has been removed the daily summary tables
|
||
will need to be dropped and rebuild using the
|
||
<span class="code">wee_database</span> utility (refer to
|
||
<em><a href="#Dropping_and_rebuilding_the_daily_summaries">Dropping and rebuilding the daily summaries</a></em>).
|
||
</li>
|
||
|
||
<li>If the imported data is the only data in an SQLite database
|
||
then the easiest method of removing the contaminated data
|
||
is to delete the SQLite database file.</li>
|
||
|
||
<li>If the above steps are not appropriate then the database
|
||
should be restored from the previously made backup.</li>
|
||
</ul>
|
||
</ol>
|
||
|
||
<h2>Weather Underground PWS observations</h2>
|
||
|
||
<p><span class="code">wee_import</span> can import observational data from
|
||
the daily history of a Weather Undeground PWS. A Weather Underground PWS
|
||
daily history provides weather station observations received by Weather
|
||
Underground for the PWS concerned on a day by day basis. As such, the
|
||
data is analogous to the <span class="code">weewx</span> archive table.
|
||
When <span class="code">wee_import</span> imports data from a Weather
|
||
Underground daily history each day is considered a 'period'.
|
||
<span class="code">wee_import</span> processes one period at a time in
|
||
chronological order (oldest to newest) and provides import summary data
|
||
on a per period basis.
|
||
</p>
|
||
|
||
<h3><span class="code">weewx</span> archive fields populated during a Weather Underground import</h3>
|
||
|
||
<p>A Weather Underground import will populate
|
||
<span class="code">weewx</span> archive fields as follows:</p>
|
||
|
||
<ul>
|
||
<li>Provided data exists for each field in the Weather Underground
|
||
PWS daily history, the following <span class="code">weewx</span>
|
||
archive fields will be directly populated by imported data:</p>
|
||
|
||
<ul>
|
||
<li><span class="code">dateTime</span></li>
|
||
<li><span class="code">barometer</span></li>
|
||
<li><span class="code">dewpoint</span></li>
|
||
<li><span class="code">outHumidity</span></li>
|
||
<li><span class="code">outTemp</span></li>
|
||
<li><span class="code">radiation</span></li>
|
||
<li><span class="code">rain</span></li>
|
||
<li><span class="code">windDir</span></li>
|
||
<li><span class="code">windGust</span></li>
|
||
<li><span class="code">windSpeed</span></li>
|
||
</ul>
|
||
|
||
<p class="note" style="display:inline-block; width:70%">
|
||
<b>Note</b><br/>If an appropriate field does not exist in
|
||
the Weather Underground daily history (eg
|
||
<span class="code">radiation</span> if no radiation sensor,
|
||
<span class="code">outHumidity</span> if
|
||
<span class="code">outHumidity</span> was never uploaded to
|
||
Weather Undeground) then the corresponding
|
||
<span class="code">weewx</span> archive field will be set
|
||
to <span class="code">None/NULL</span>.
|
||
</p>
|
||
|
||
<li>The following <span class="code">weewx</span> archive fields
|
||
will be populated from other settings or configuration
|
||
options:</li>
|
||
|
||
<ul>
|
||
<li><span class="code">interval</span></li>
|
||
<li><span class="code">usUnits</span></li>
|
||
</ul>
|
||
|
||
<li>The following <span class="code">weewx</span> archive fields
|
||
will be populated with values derived from the imported data
|
||
provided <span class="code">calc_missing = True</span> is
|
||
included in the <span class="code">[Wunder]</span> section of
|
||
the import configuration file being used and the field exists
|
||
in the in-use <span class="code">weewx</span> archive table
|
||
schema.</li>
|
||
|
||
<ul>
|
||
<li><span class="code">altimeter</span></li>
|
||
<li><span class="code">ET</span></li>
|
||
<li><span class="code">heatindex</span></li>
|
||
<li><span class="code">pressure</span></li>
|
||
<li><span class="code">rainRate</span></li>
|
||
<li><span class="code">windchill</span></li>
|
||
</ul>
|
||
|
||
<p class="note" style="display:inline-block; width:70%">
|
||
<b>Note</b><br/>The default setting of the
|
||
<span class="code">calc_missing</span> option is
|
||
<span class="code">True</span> so if the
|
||
<span class="code">calc_missing</span> option is omitted
|
||
from the <span class="code">[Wunder]</span> section the
|
||
same fields will be calculated and stored as if
|
||
<span class="code">calc_missing = True</span> had been used.
|
||
</p>
|
||
|
||
<p class="note" style="display:inline-block; width:70%">
|
||
<b>Note</b><br/>If
|
||
<span class="code">calc_missing = False</span> is included
|
||
in the <span class="code">[Wunder]</span> section of the
|
||
import configuration file being used then all of the above
|
||
fields will be set to <span class="code">None/NULL</span>.
|
||
</p>
|
||
</ul>
|
||
|
||
<h3>Importing observations from a Weather Underground PWS</h3>
|
||
|
||
<p>To import observations from the daily history of a Weather Underground
|
||
PWS:</p>
|
||
|
||
<ol>
|
||
<li>Obtain the weather station ID of the Weather Underground PWS from
|
||
which data is to be imported. The station ID will be a sequence of
|
||
numbers and upper case letters that is usually 11 or 12 characters
|
||
in length. For the purposes of these instructions a weather station
|
||
ID of <span class="code">ISTATION123</span> will be used.</li>
|
||
|
||
<li>As <span class="code">wee_import</span> will make alterations to the
|
||
<span class="code">weewx</span> database make a backup copy of the
|
||
<span class="code">weewx</span> database for use should the import
|
||
go awry.</li>
|
||
|
||
<li>If an import configuration file has not already been produced for
|
||
this Weather Underground import, make a copy of the example Weather
|
||
Underground import configuration file provided in the
|
||
<span class="code">weewx/util/import</span> directory. In this case
|
||
we will make a copy of the example Weather Underground import
|
||
configuration file and save it as
|
||
<span class="code">wunder.conf</span> in the
|
||
<span class="code">/var/tmp</span> directory:
|
||
|
||
<pre class="tty">$ cp /home/weewx/util/import/wunder-example.conf /var/tmp/wunder.conf
|
||
</pre>
|
||
|
||
<li>Confirm the <span class="code">source</span> option (refer to
|
||
<em><a href="#import_config_source"><span class="code">source</span></a></em>)
|
||
in the import configuration file
|
||
<span class="code">wunder.conf</span> (refer to
|
||
<em><a href="#import_config">The import configuration file</a></em>)
|
||
is set as follows:</li>
|
||
|
||
<pre class="tty">source = Wunder</span></pre>
|
||
|
||
<li>Confirm the following options in the
|
||
<span class="code">[Wunder]</span> section of the import
|
||
configuration file <span class="code">wunder.conf</span> (refer to
|
||
<em><a href="#import_config">The import configuration file</a></em>)
|
||
are correctly set:</li>
|
||
|
||
<ul>
|
||
<li><strong><span class="code">station_id</span></strong>.
|
||
The 11 or 12 character weather station ID of the Weather
|
||
Underground PWS that will be the source of the imported
|
||
data. Refer to
|
||
<em><a href="#wunder_station_id"><span class="code">station_id</span></a></em>.</li>
|
||
<li><strong><span class="code">interval</span></strong>.
|
||
Determines how the <span class="code">weewx</span> interval
|
||
field is derived. Refer to
|
||
<em><a href="#wunder_interval"><span class="code">interval</span></a></em>.</li>
|
||
<li><strong><span class="code">qc</span></strong>. Determines
|
||
whether quality control checks are performed on the imported
|
||
data. Refer to
|
||
<em><a href="#wunder_qc"><span class="code">qc</span></a></em>.</li>
|
||
|
||
<p class="note" style="display:inline-block; width:70%">
|
||
<b>Note</b><br/>As Weather Underground imports at times
|
||
contain nonsense values, particularly for fields for
|
||
which no data was uploaded to Weather Underground by the
|
||
PWS, the use of quality control checks on imported data
|
||
can prevent these nonsense values from being imported
|
||
and contaminating the <span class="code">weewx</span>
|
||
database.
|
||
</p>
|
||
|
||
<li><strong><span class="code">calc_missing</span></strong>.
|
||
Determines whether missing derived observations will be
|
||
calculated from the imported data. Refer to
|
||
<em><a href="#wunder_calc_missing"><span class="code">calc_missing</span></a></em>.</li>
|
||
<li><strong><span class="code">tranche</span></strong>. The
|
||
number of records written to the
|
||
<span class="code">weewx</span> database in each transaction.
|
||
Refer to
|
||
<em><a href="#wunder_tranche"><span class="code">tranche</span></a></em>.</li>
|
||
<li><strong><span class="code">wind_direction</span></strong>.
|
||
Determines how imported wind direction fields are
|
||
interpreted. Refer to
|
||
<em><a href="#wunder_wind_direction"><span class="code">wind_direction</span></a></em>.</li>
|
||
</ul>
|
||
|
||
<li>When first importing data it is often prudent to do a dry run import
|
||
before any data is actually imported. A dry run import will perform
|
||
all steps of the import without actually writing imported data to
|
||
the <span class="code">weewx</span> database. In addition,
|
||
consideration should be given to any additional command line options
|
||
to be used such as <span class="code">--date</span>. The available
|
||
command line options are shown in the
|
||
<span class="code">wee_import --help</span> output above (refer to
|
||
<em><a href="#import_help">wee_import help</a></em>). Additional
|
||
details are also provided in the
|
||
<em><a href="#common_options">Command line options</a></em> section.
|
||
To perform a dry run import enter the following command:</li>
|
||
|
||
<pre class="tty">wee_import --import-config=/var/tmp/wunder.conf --date="2016/01/20 22:30-2016/01/23 06:00" --dry-run
|
||
</pre>
|
||
|
||
<p class="note" style="display:inline-block; width:70%">
|
||
<b>Note</b><br/>If the <span class="code">--date</span> command
|
||
line option is omitted or a date (not date-time) range is used
|
||
during a Weather Underground import, then the current days
|
||
history data will be imported. This includes records timestamped
|
||
from <span class="code">00:00</span> (inclusive) at the start
|
||
of the day up to but NOT including the
|
||
<span class="code">00:00</span> record at the end of the last
|
||
day. As the timestamped record refers to observations of the
|
||
previous interval, such an import actually includes one record
|
||
with observations from the previous day (the
|
||
<span class="code">00:00</span> record at the start of the day).
|
||
Whilst this will not present a problem for
|
||
<span class="code">wee_import</span> as any records being
|
||
imported with a timestamp that already exists in the
|
||
<span class="code">weewx</span> database are ignored, the user
|
||
may wish to use the <span class="code">--date</span> option
|
||
with a suitable date-time range to precisely control which
|
||
records are imported.
|
||
</p>
|
||
|
||
<p class="note" style="display:inline-block; width:70%">
|
||
<b>Note</b><br/><span class="code">wee_import</span> obtains
|
||
Weather Underground daily history data one day at a time via a
|
||
HTTP request and as such the import of large time spans of data
|
||
may take some time. Such imports may be best handled as a series
|
||
of imports of smaller time spans.
|
||
</p>
|
||
|
||
<p>This will result in a short preamble giving the user brief details
|
||
on the data source, its destination and some other details on
|
||
how the data will be processed. The import will then be
|
||
performed but no data is written to the
|
||
<span class="code">weewx</span> database. Upon completion a
|
||
brief summary of the records processed is provided. The output
|
||
should be similar to:
|
||
</p>
|
||
|
||
<pre class="tty">Starting wee_import...
|
||
A Weather Underground import from station 'ISTATION123' has been requested.
|
||
Using database binding 'wx_binding', which is bound to database 'weewx.sdb'
|
||
Destination table 'archive' unit system is '0x01' (US).
|
||
Any missing derived observations WILL be calculated.
|
||
Observations timestamped after 2016-01-20 22:30:00 AEST (1453293000) and up to and
|
||
including 2016-01-23 06:00:00 AEST (1453492800) will be imported.
|
||
This is a dry run, imported data WILL NOT be saved to archive.
|
||
Starting dry run import ...
|
||
Records covering multiple periods have been identified for import.
|
||
Period 1 ...
|
||
Records processed: 18; Unique records: 18; Last timestamp: 2016-01-20 23:55:00 AEST (1453298100)
|
||
Period 2 ...
|
||
Records processed: 285; Unique records: 285; Last timestamp: 2016-01-21 23:55:00 AEST (1453384500)
|
||
Period 3 ...
|
||
Records processed: 288; Unique records: 288; Last timestamp: 2016-01-22 23:55:00 AEST (1453470900)
|
||
Period 4 ...
|
||
Records processed: 71; Unique records: 71; Last timestamp: 2016-01-23 06:00:00 AEST (1453492800)
|
||
Finished dry run import. 662 records were processed and 662 unique records would have been imported.
|
||
</pre>
|
||
|
||
<p class="note" style="display:inline-block; width:70%">
|
||
<b>Note</b><br/>As the <span class="code">weewx</span> database is
|
||
not altered when the <span class="code">--dry-run</span> command
|
||
line option is used, <span class="code">wee_import</span> log output
|
||
is suspended during a dry run import. In effect, the use of
|
||
<span class="code">--dry-run</span> is equivalent to
|
||
<span class="code">--dry-run --log=-</span>. During a dry run import
|
||
the only <span class="code">wee_import</span> output is that
|
||
displayed on <span class="code">stdout</span>(console).
|
||
</p>
|
||
|
||
<li>Once the dry run results are satisfactory the source data can be
|
||
imported using the following command:</li>
|
||
|
||
<pre class="tty">wee_import --import-config=/var/tmp/wunder.conf --date="2016/01/20 22:30-2016/01/23 06:00"
|
||
</pre>
|
||
|
||
<p>This will result in a short preamble giving the user brief details
|
||
on the data source, its destination and some other details on how
|
||
the data will be processed. This output will vary slightly
|
||
depending on what command line options have been used. At the end
|
||
of the preamble the user will be prompted as to whether to proceed
|
||
or not with the import:</p>
|
||
|
||
<pre class="tty">Starting wee_import...
|
||
A Weather Underground import from station 'ISTATION123' has been requested.
|
||
Using database binding 'wx_binding', which is bound to database 'weewx.sdb'
|
||
Destination table 'archive' unit system is '0x01' (US).
|
||
Any missing derived observations WILL be calculated.
|
||
Observations timestamped after 2016-01-20 22:30:00 AEST (1453293000) and up to and
|
||
including 2016-01-23 06:00:00 AEST (1453492800) will be imported.
|
||
This is NOT a dry run, imported data WILL be saved to archive.
|
||
Starting import ...
|
||
Records covering multiple periods have been identified for import.
|
||
Proceeding will save all imported records in the weewx archive.
|
||
Are you sure you want to proceed (y/n)?
|
||
</pre>
|
||
|
||
<p class="note" style="display:inline-block; width:70%">
|
||
<b>Note</b><br/><span class="code">wee_import</span> obtains
|
||
Weather Underground daily history data one day at a time via a HTTP
|
||
request and as such the import of large time spans of data may take
|
||
some time. Such imports may be best handled as a series of imports
|
||
of smaller time spans.
|
||
</p>
|
||
|
||
<li>The preamble should be read carefully and if the import parameters
|
||
are acceptable enter <span class="code">y</span> to proceed with the
|
||
import or <span class="code">n</span> to abort the import. If the
|
||
import is aborted the user is informed of this and returned to the
|
||
command line. If the user proceeds with the import then the source
|
||
data will be imported, processed and saved in the
|
||
<span class="code">weewx</span> database. Information on the
|
||
progress of the import will be displayed similar to the following:
|
||
</li>
|
||
|
||
<pre class="tty">Period 1 ...
|
||
Records processed: 18; Unique records: 18; Last timestamp: 2016-01-20 23:55:00 AEST (1453298100)
|
||
Period 2 ...
|
||
Records processed: 286; Unique records: 286; Last timestamp: 2016-01-21 23:55:00 AEST (1453384500)
|
||
</pre>
|
||
|
||
<p>The line commencing with <span class="code">Records processed</span>
|
||
should update as records are imported with progress information on
|
||
number of records processed, number of unique records imported and
|
||
the date time of the latest record processed. If the import spans
|
||
multiple days then a new <span class="code">Period</span> line is
|
||
created for each day. When the import is complete a brief summary
|
||
is displayed similar to the following:</p>
|
||
|
||
<pre class="tty">Finished import. 662 raw records resulted in 662 unique records being processed in 8.67 seconds.
|
||
Whilst 662 unique records were processed those with a timestamp already in the archive
|
||
will not have been imported. Confirm successful import in the weewx log file.
|
||
</pre>
|
||
|
||
<p class="note" style="display:inline-block; width:70%">
|
||
<b>Note</b><br/>It is not unusual to see a Weather Underground
|
||
import return a different number of records for the same import
|
||
performed at different times. If importing the current day this
|
||
could be because an additional record may have been added between
|
||
<span class="code">wee_import</span> runs. For periods before today,
|
||
this behaviour appears to be a vagary of Weather Underground. The
|
||
only solution appears to be to repeat the import with the same
|
||
<span class="code">--date</span> command line option setting and
|
||
observe whether the missing records are imported. Repeating the
|
||
import will not adversely affect any existing data as records with
|
||
timestamps that are already in the <span class="code">weewx</span>
|
||
archive will be ignored. It may; however, generated many
|
||
<span class="code">UNIQUE constraint failed: archive.dateTime</span>
|
||
messages in the <span class="code">weewx</span> log.
|
||
</p>
|
||
|
||
<li>Whilst <span class="code">wee_import</span> will advise of the
|
||
number of records processed and the number of unique records found,
|
||
<span class="code">wee_import</span> does know how many, if any, of
|
||
the imported records were successfully saved to the database. The
|
||
user should look carefully through the
|
||
<span class="code">weewx</span> log file covering the
|
||
<span class="code">wee_import</span> session and take note of any
|
||
records that were not imported. The most common reason for imported
|
||
records not being saved to the database is because a record with
|
||
that timestamp already exists in the database, in such cases
|
||
something similar to following will be found in the log:</li>
|
||
|
||
<pre class="tty">
|
||
Aug 22 14:38:28 jessie2 weewx[863]: manager: unable to add record 2010-09-04 04:20:00 AEST (1283538000) to database 'weewx.sdb': UNIQUE constraint failed: archive.dateTime
|
||
</pre>
|
||
|
||
<p>In such cases the user should take note of the timestamp of the
|
||
record(s) concerned and make a decision about whether to delete the
|
||
pre-existing record and re-import the record or retain the
|
||
pre-existing record.</p>
|
||
|
||
<li>If errors were encountered, or the user suspects the
|
||
<span class="code">weewx</span> database has been contaminated with
|
||
incorrect data, then the imported data may be removed by:</li>
|
||
|
||
<ul>
|
||
<li>Manually deleting the contaminated data from the
|
||
<span class="code">weewx</span> archive database using SQL
|
||
commands. The simplicity of this process will depend on the
|
||
users ability to use SQL, the amount of data imported and
|
||
whether the imported data was dispersed amongst existing
|
||
data or it can be identified in a single block only. Once
|
||
any contaminated data has been removed the daily summary
|
||
tables will need to be dropped and rebuild using the
|
||
<span class="code">wee_database</span> utility (refer to
|
||
<em><a href="#Dropping_and_rebuilding_the_daily_summaries">Dropping and rebuilding the daily summaries</a></em>).
|
||
</li>
|
||
|
||
<li>If the imported data is the only data in an SQLite database
|
||
then the easiest method of removing the contaminated data
|
||
is to delete the SQLite database file.</li>
|
||
|
||
<li>If the above steps are not appropriate then the database
|
||
should be restored from the previously made backup.</li>
|
||
</ul>
|
||
</ol>
|
||
|
||
<h2>Cumulus monthly log files</h2>
|
||
|
||
<p><span class="code">wee_import</span> can import observational data from
|
||
the one or more Cumulus monthly log files. A Cumulus monthly log file
|
||
records weather station observations for a single month. These files are
|
||
accumulated over time and can be considered analogous to the
|
||
<span class="code">weewx</span> archive table. When
|
||
<span class="code">wee_import</span> imports data from the Cumulus
|
||
monthly log files each log file is considered a 'period'.
|
||
<span class="code">wee_import</span> processes one period at a time in
|
||
chronological order (oldest to newest) and provides import summary
|
||
data on a per period basis.</p>
|
||
|
||
<h3><span class="code">weewx</span> archive fields populated during a Cumulus monthly log import</h3>
|
||
|
||
<p>A Cumulus monthly log file import will populate the
|
||
<span class="code">weewx</span> archive fields as follows:</p>
|
||
|
||
<ul>
|
||
<li>Provided data exists for each field in the Cumulus monthly
|
||
logs, the following <span class="code">weewx</span>
|
||
archive fields will be directly populated by imported data:</p>
|
||
|
||
<ul>
|
||
<li><span class="code">dateTime</span></li>
|
||
<li><span class="code">barometer</span></li>
|
||
<li><span class="code">dewpoint</span></li>
|
||
<li><span class="code">heatindex</span></li>
|
||
<li><span class="code">inHumidity</span></li>
|
||
<li><span class="code">inTemp</span></li>
|
||
<li><span class="code">outHumidity</span></li>
|
||
<li><span class="code">outTemp</span></li>
|
||
<li><span class="code">radiation</span></li>
|
||
<li><span class="code">rain</span> (Cumulus 1.9.4 or
|
||
later)</li>
|
||
<li><span class="code">rainRate</span></li>
|
||
<li><span class="code">UV</span></li>
|
||
<li><span class="code">windDir</span></li>
|
||
<li><span class="code">windGust</span></li>
|
||
<li><span class="code">windSpeed</span></li>
|
||
<li><span class="code">windchill</span></li>
|
||
</ul>
|
||
|
||
<p class="note" style="display:inline-block; width:70%">
|
||
<b>Note</b><br/>If a field in the Cumulus monthly log file
|
||
has no data then the corresponding
|
||
<span class="code">weewx</span> archive field will be set
|
||
to <span class="code">None/NULL</span>.
|
||
</p>
|
||
|
||
<li>The following <span class="code">weewx</span> archive fields
|
||
will be populated from other settings or configuration options:</li>
|
||
|
||
<ul>
|
||
<li><span class="code">interval</span></li>
|
||
<li><span class="code">usUnits</span></li>
|
||
</ul>
|
||
|
||
<li>The following <span class="code">weewx</span> archive fields
|
||
will be populated with values derived from the imported data
|
||
provided <span class="code">calc_missing = True</span> is
|
||
included in the <span class="code">[Cumulus]</span> section of
|
||
the import configuration file being used and the field exists
|
||
in the in-use <span class="code">weewx</span> archive table
|
||
schema.</li>
|
||
|
||
<ul>
|
||
<li><span class="code">altimeter</span></li>
|
||
<li><span class="code">ET</span></li>
|
||
<li><span class="code">pressure</span></li>
|
||
</ul>
|
||
|
||
<p class="note" style="display:inline-block; width:70%">
|
||
<b>Note</b><br/>The default setting of the
|
||
<span class="code">calc_missing</span> option is
|
||
<span class="code">True</span> so if the
|
||
<span class="code">calc_missing</span> option is omitted
|
||
from the <span class="code">[Cumulus]</span> section of the
|
||
import configuration file being used the same fields will
|
||
be calculated and stored as if
|
||
<span class="code">calc_missing = True</span> had been used.
|
||
</p>
|
||
|
||
<p class="note" style="display:inline-block; width:70%">
|
||
<b>Note</b><br/>If
|
||
<span class="code">calc_missing = False</span> is included
|
||
in the <span class="code">[Cumulus]</span> section of the
|
||
import configuration file being used then all of the above
|
||
fields will be set to <span class="code">None/NULL</span>.
|
||
</p>
|
||
</ul>
|
||
|
||
<h3>Importing observations from Cumulus monthly log files</h3>
|
||
|
||
<p>To import observations from one or more Cumulus monthly log files:</p>
|
||
|
||
<ol>
|
||
<li>Ensure the Cumulus monthly log file(s) to be used for the import
|
||
are located in a directory accessible by the machine that will run
|
||
<span class="code">wee_import</span>. For the purposes of these
|
||
instructions the Cumulus monthly log files will be located in the
|
||
<span class="code">/var/tmp/cumulus</span> folder. There are nine
|
||
monthly logs files covering the period November 2015 to July 2016
|
||
inclusive.</li>
|
||
|
||
<li>As <span class="code">wee_import</span> will make alterations to the
|
||
<span class="code">weewx</span> database make a backup copy of the
|
||
<span class="code">weewx</span> database for use should the import
|
||
go awry.</li>
|
||
|
||
<li>If an import configuration file has not already been produced for
|
||
this Cumulus import, make a copy of the example Cumulus import
|
||
configuration file provided in the
|
||
<span class="code">weewx/util/import</span> directory. In this case
|
||
we will make a copy of the example Cumulus import configuration file
|
||
and save it as <span class="code">cumulus.conf</span> in the
|
||
<span class="code">/var/tmp</span> directory:
|
||
|
||
<pre class="tty">$ cp /home/weewx/util/import/cumulus-example.conf /var/tmp/cumulus.conf
|
||
</pre>
|
||
|
||
<li>Confirm the <span class="code">source</span> option (refer to
|
||
<em><a href="#import_config_source"><span class="code">source</span></a></em>)
|
||
in the import configuration file
|
||
<span class="code">cumulus.conf</span> (refer to
|
||
<em><a href="#import_config">The import configuration file</a></em>)
|
||
is set as follows:</li>
|
||
|
||
<pre class="tty">source = Cumulus</span></pre>
|
||
|
||
<li>Confirm the following options in the
|
||
<span class="code">[Cumulus]</span> section of the import
|
||
configuration file <span class="code">cumulus.conf</span>
|
||
(refer to
|
||
<em><a href="#import_config">The import configuration file</a></em>)
|
||
are correctly set:</li>
|
||
|
||
<ul>
|
||
<li><strong><span class="code">directory</span></strong>.
|
||
The full path to the directory containing the Cumulus
|
||
monthly log files to be used as the source of the imported
|
||
data. Refer to
|
||
<em><a href="#cumulus_directory"><span class="code">directory</span></a></em>.</li>
|
||
<li><strong><span class="code">interval</span></strong>.
|
||
Determines how the <span class="code">weewx</span> interval
|
||
field is derived. Refer to
|
||
<em><a href="#cumulus_interval"><span class="code">interval</span></a></em>.</li>
|
||
<li><strong><span class="code">qc</span></strong>. Determines
|
||
whether quality control checks are performed on the imported
|
||
data. Refer to
|
||
<em><a href="#cumulus_qc"><span class="code">qc</span></a></em>.</li>
|
||
<li><strong><span class="code">calc_missing</span></strong>.
|
||
Determines whether missing derived observations will be
|
||
calculated from the imported data. Refer to
|
||
<em><a href="#cumulus_calc_missing"><span class="code">calc_missing</span></a></em>.</li>
|
||
<li><strong><span class="code">delimiter</span></strong>. The
|
||
field delimiter used in the Cumulus monthly log files.
|
||
Refer to
|
||
<em><a href="#cumulus_delimiter"><span class="code">delimiter</span></a></em>.</li>
|
||
<li><strong><span class="code">decimal</span></strong>. The
|
||
decimal point character used in the Cumulus monthly log
|
||
files. Refer to
|
||
<em><a href="#cumulus_decimal"><span class="code">decimal</span></a></em>.</li>
|
||
<li><strong><span class="code">tranche</span></strong>. The
|
||
number of records written to the
|
||
<span class="code">weewx</span> database in each transaction.
|
||
Refer to
|
||
<em><a href="#cumulus_tranche"><span class="code">tranche</span></a></em>.</li>
|
||
<li><strong><span class="code">UV_sensor</span></strong>.
|
||
Whether a UV sensor was installed when the source data was
|
||
produced. Refer to
|
||
<em><a href="#cumulus_UV"><span class="code">UV_sensor</span></a></em>.</li>
|
||
<li><strong><span class="code">solar_sensor</span></strong>.
|
||
Whether a solar radiation sensor was installed when the
|
||
source data was produced. Refer to
|
||
<em><a href="#cumulus_solar"><span class="code">solar_sensor</span></a></em>.</li>
|
||
<li><strong><span class="code">[[Units]]</span></strong>.
|
||
Defines the units used in the Cumulus monthly log files.
|
||
Refer to
|
||
<em><a href="#cumulus_units"><span class="code">[[Units]]</span></a></em>.</li>
|
||
</ul>
|
||
|
||
<li>When first importing data it is often prudent to do a dry run import
|
||
before any data is actually imported. A dry run import will perform
|
||
all steps of the import without actually writing imported data to
|
||
the <span class="code">weewx</span> database. In addition,
|
||
consideration should be given to any additional command line options
|
||
to be used such as <span class="code">--date</span>. The available
|
||
command line options are shown in the
|
||
<span class="code">wee_import --help</span> output above (refer to
|
||
<em><a href="#import_help">wee_import help</a></em>). Additional
|
||
details are also provided in the
|
||
<em><a href="#common_options">Command line options</a></em> section.
|
||
To perform a dry run import enter the following command:</li>
|
||
|
||
<pre class="tty">wee_import --import-config=/var/tmp/cumulus.conf --dry-run
|
||
</pre>
|
||
|
||
<p>This will result in a short preamble giving the user brief
|
||
details on the data source, its destination and some other
|
||
details on how the data will be processed. The import will then
|
||
be performed but no data is written to the
|
||
<span class="code">weewx</span> database. Upon completion a
|
||
brief summary of the records processed is provided. The output
|
||
should be similar to:
|
||
</p>
|
||
|
||
<pre class="tty">Starting wee_import...
|
||
An import from Cumulus monthly log files located in the '/var/tmp/cumulus' directory
|
||
has been requested.
|
||
Using database binding 'wx_binding', which is bound to database 'weewx.sdb'
|
||
Destination table 'archive' unit system is '0x01' (US).
|
||
Any missing derived observations WILL be calculated.
|
||
All weewx UV fields will be set to None.
|
||
All weewx radiation fields will be set to None.
|
||
This is a dry run, imported data WILL NOT be saved to archive.
|
||
Starting dry run import ...
|
||
Records covering multiple periods have been identified for import.
|
||
Period 1 ...
|
||
Records processed: 4189; Unique records: 4169; Last timestamp: 2015-12-01 09:40:00 AEST (1448926800)
|
||
Period 2 ...
|
||
Records processed: 4461; Unique records: 4461; Last timestamp: 2016-01-01 09:40:00 AEST (1451605200)
|
||
Period 3 ...
|
||
Records processed: 4458; Unique records: 4458; Last timestamp: 2016-02-01 09:40:00 AEST (1454283600)
|
||
Period 4 ...
|
||
Records processed: 3940; Unique records: 3940; Last timestamp: 2016-03-01 09:40:00 AEST (1456789200)
|
||
Period 5 ...
|
||
Records processed: 4061; Unique records: 4061; Last timestamp: 2016-04-01 09:40:00 AEST (1459467600)
|
||
Period 6 ...
|
||
Records processed: 4298; Unique records: 4292; Last timestamp: 2016-05-01 08:40:00 AEST (1462056000)
|
||
Period 7 ...
|
||
Records processed: 4380; Unique records: 4379; Last timestamp: 2016-06-01 08:40:00 AEST (1464734400)
|
||
Period 8 ...
|
||
Records processed: 4317; Unique records: 4317; Last timestamp: 2016-07-01 08:40:00 AEST (1467326400)
|
||
Period 9 ...
|
||
Records processed: 3544; Unique records: 3543; Last timestamp: 2016-07-26 17:00:00 AEST (1469516400)
|
||
Finished dry run import. 37648 records were processed and 37620 unique records would have been imported.
|
||
</pre>
|
||
|
||
<p class="note" style="display:inline-block; width:70%">
|
||
<b>Note</b><br/>The nine periods correspond to the nine monthly log
|
||
files used for this import.
|
||
</p>
|
||
|
||
<li>Once the dry run results are satisfactory the source data can be
|
||
imported using the following command:</li>
|
||
|
||
<pre class="tty">wee_import --import-config=/var/tmp/cumulus.conf
|
||
</pre>
|
||
|
||
<p>This will result in a short preamble giving the user brief details
|
||
on the data source, its destination and some other details on how
|
||
the data will be processed. This output will vary slightly
|
||
depending on what command line options have been used. At the end
|
||
of the preamble the user will be prompted as to whether to proceed
|
||
or not with the import:</p>
|
||
|
||
<pre class="tty">Starting wee_import...
|
||
An import from Cumulus monthly log files located in the '/var/tmp/cumulus' directory
|
||
has been requested.
|
||
Using database binding 'wx_binding', which is bound to database 'weewx.sdb'
|
||
Destination table 'archive' unit system is '0x01' (US).
|
||
Any missing derived observations WILL be calculated.
|
||
All weewx UV fields will be set to None.
|
||
All weewx radiation fields will be set to None.
|
||
This is NOT a dry run, imported data WILL be saved to archive.
|
||
Starting import ...
|
||
Records covering multiple periods have been identified for import.
|
||
Proceeding will save all imported records in the weewx archive.
|
||
</pre>
|
||
|
||
<p>If there is more than one Cumulus monthly log file then
|
||
<span class="code">wee_import</span> will provide summary
|
||
information on a per period basis during the import. In addition,
|
||
if the <span class="code">--date</span> command line option is used
|
||
then source data that falls outside the date or date range
|
||
specified with the <span class="code">--date</span> command line
|
||
option is ignored. In such cases the preamble may look similar
|
||
to:</p>
|
||
|
||
<pre class="tty">Starting wee_import...
|
||
An import from Cumulus monthly log files located in the '/var/tmp/cumulus' directory
|
||
has been requested.
|
||
Using database binding 'wx_binding', which is bound to database 'weewx.sdb'
|
||
Destination table 'archive' unit system is '0x01' (US).
|
||
Any missing derived observations WILL be calculated.
|
||
All weewx UV fields will be set to None.
|
||
All weewx radiation fields will be set to None.
|
||
Observations timestamped after 2016-02-12 00:00:00 AEST (1455199200) and up to and
|
||
including 2016-02-24 00:00:00 AEST (1456236000) will be imported.
|
||
This is NOT a dry run, imported data WILL be saved to archive.
|
||
Starting import ...
|
||
Period 1 - no records identified for import.
|
||
Period 2 - no records identified for import.
|
||
Period 3 - no records identified for import.
|
||
Proceeding will save all imported records in the weewx archive.
|
||
Are you sure you want to proceed (y/n)?
|
||
</pre>
|
||
|
||
<li>The preamble should be read carefully and if the import parameters
|
||
are acceptable enter <span class="code">y</span> to proceed with the
|
||
import or <span class="code">n</span> to abort the import. If the
|
||
import is aborted the user is informed of this and returned to the
|
||
command line. If the user proceeds with the import then the source
|
||
data will be imported, processed and saved in the
|
||
<span class="code">weewx</span> database. Information on the
|
||
progress of the import will be displayed similar to the following:
|
||
</li>
|
||
|
||
<pre class="tty">Records processed: 1599; Unique records: 1599; Last timestamp: 2016-02-24 00:00:00 AEST (1456236000)
|
||
</pre>
|
||
|
||
<p>Again if there is more than one Cumulus monthly log file and if the
|
||
<span class="code">--date</span> command line option is used then
|
||
the progress information may instead look similar to:</p>
|
||
|
||
<pre class="tty">Period 4 ...
|
||
Records processed: 2521; Unique records: 2521; Last timestamp: 2016-03-01 09:40:00 AEST (1456789200)
|
||
Period 5 ...
|
||
Records processed: 4061; Unique records: 4061; Last timestamp: 2016-04-01 09:40:00 AEST (1459467600)
|
||
Period 6 ...
|
||
Records processed: 3238; Unique records: 3232; Last timestamp: 2016-04-24 00:00:00 AEST (1461420000)
|
||
</pre>
|
||
|
||
<p>The line commencing with <span class="code">Records processed</span>
|
||
should update as records are imported with progress information on
|
||
number of records processed, number of unique records imported and
|
||
the date time of the latest record processed. If the import spans
|
||
multiple months (ie multiple monthly log files) then a new
|
||
<span class="code">Period</span> line is created for each month.
|
||
When the import is complete a brief summary is displayed similar to
|
||
the following:</p>
|
||
|
||
<pre class="tty">Finished import. 37648 raw records resulted in 37620 unique records being processed in 81.13 seconds.
|
||
Whilst 37620 unique records were processed those with a timestamp already in the archive
|
||
will not have been imported. Confirm successful import in the weewx log file.
|
||
</pre>
|
||
|
||
<li>Whilst <span class="code">wee_import</span> will advise of the
|
||
number of records processed and the number of unique records found,
|
||
<span class="code">wee_import</span> does know how many, if any, of
|
||
the imported records were successfully saved to the database. The
|
||
user should look carefully through the
|
||
<span class="code">weewx</span> log file covering the
|
||
<span class="code">wee_import</span> session and take note of any
|
||
records that were not imported. The most common reason for imported
|
||
records not being saved to the database is because a record with
|
||
that timestamp already exists in the database, in such cases
|
||
something similar to following will be found in the log:</li>
|
||
|
||
<pre class="tty">
|
||
Aug 22 14:38:28 jessie2 weewx[863]: manager: unable to add record 2010-09-04 04:20:00 AEST (1283538000) to database 'weewx.sdb': UNIQUE constraint failed: archive.dateTime
|
||
</pre>
|
||
|
||
<p>In such cases the user should take note of the timestamp of the
|
||
record(s) concerned and make a decision about whether to delete the
|
||
pre-existing record and re-import the record or retain the
|
||
pre-existing record.</p>
|
||
|
||
<li>If errors were encountered, or the user suspects the
|
||
<span class="code">weewx</span> database has been contaminated with
|
||
incorrect data, then the imported data may be removed by:</li>
|
||
|
||
<ul>
|
||
<li>Manually deleting the contaminated data from the
|
||
<span class="code">weewx</span> archive database using SQL
|
||
commands. The simplicity of this process will depend on the
|
||
users ability to use SQL, the amount of data imported and
|
||
whether the imported data was dispersed amongst existing
|
||
data can be identified in a single block only. Once any
|
||
contaminated data has been removed the daily summary tables
|
||
will need to be dropped and rebuild using the
|
||
<span class="code">wee_database</span> utility (refer to
|
||
<em><a href="#Dropping_and_rebuilding_the_daily_summaries">Dropping and rebuilding the daily summaries</a></em>).
|
||
</li>
|
||
|
||
<li>If the imported data is the only data in an SQLite database
|
||
then the easiest method of removing the contaminated data
|
||
is to delete the SQLite database file.</li>
|
||
|
||
<li>If the above steps are not appropriate then the database
|
||
should be restored from the previously made backup.</li>
|
||
</ul>
|
||
</ol>
|
||
|
||
<h2 id='import_config'>The import configuration file</h2>
|
||
|
||
<p><span class="code">wee_import</span> uses a secondary configuration file
|
||
to specify the import type and to store various options associated with
|
||
each import type. The import configuration file to be used during a
|
||
<span class="code">wee_import</span> session is specified at the
|
||
<span class="code">wee_import</span> command line using the mandatory
|
||
<span class="code">--import-config</span> command line option (refer to
|
||
<em><a href="#common_options">Command line options</a></em>). How the
|
||
user constructs the import configuration file is up to the user;
|
||
however, the recommended method is to copy one of the example import
|
||
configuration files located in the <span class="code">util/import</span>
|
||
folder, modify the configuration options in the newly copied file to
|
||
suit the import to be performed and then use this file as the import
|
||
configuration file.
|
||
</p>
|
||
|
||
<p>Following is the definitive guide to the options available in the import
|
||
configuration file. Default values are provided for a number of options,
|
||
meaning that if they are not listed in the import configuration file at
|
||
all <span class="code">wee_import</span> will pick sensible values.
|
||
When the documentation below gives a "default value" this is what it
|
||
means. What follows is organized by the different sections of the import
|
||
configuration file.
|
||
</p>
|
||
|
||
<h3 class="config_section">General</h3>
|
||
|
||
<p class='config_option' id='import_config_source'>source</p>
|
||
|
||
<p>The <span class="code">source</span> option determines the type of import
|
||
to be performed by <span class="code">wee_import</span>. The option
|
||
must be set to one of the following:
|
||
</p>
|
||
|
||
<ul>
|
||
<li><span class="code">CSV</span> to import from a single CSV format
|
||
file.</li>
|
||
<li><span class="code">Wunder</span> to import from a Weather
|
||
Underground PWS daily history.</li>
|
||
<li><span class="code">Cumulus</span> to import from one or more
|
||
Cumulus monthly log files.</li>
|
||
</ul>
|
||
<p>There is no default.</p>
|
||
|
||
<h3 class="config_section">[CSV]</h3>
|
||
|
||
<p>The <span class="config_section">[CSV]</span> section contains the
|
||
options relating to the import of observational data from a CSV format
|
||
file.
|
||
</p>
|
||
|
||
<p class='config_option' id='csv_file'>file</p>
|
||
|
||
<p>The file containing the CSV format data to be used as the source during
|
||
the import. Include full path and filename. There is no default.
|
||
</p>
|
||
|
||
<p class='config_option' id='csv_interval'>interval</p>
|
||
|
||
<p>Determines how the time interval (<span class="code">weewx</span>
|
||
archive table field <span class="code">interval</span>) between
|
||
successive observations is derived. The interval can be derived by one
|
||
of three methods:
|
||
</p>
|
||
|
||
<ul>
|
||
<li>The interval can be calculated as the time, rounded to the
|
||
nearest minute, between the date-time of successive records.
|
||
This method is suitable when the data was recorded at fixed
|
||
intervals and there are NO missing records in the source data.
|
||
Use of this method when there are missing records in the source
|
||
data can compromise the integrity of the
|
||
<span class="code">weewx</span> statistical data. Select this
|
||
method by setting <span class="code">interval = derive</span>.
|
||
</li>
|
||
<li>The interval can be set to the same value as the
|
||
<span class="code">archive_interval</span> setting under
|
||
<span class="code">[StdArchive]</span> in
|
||
<span class="code">weewx.conf</span>. This setting is useful if
|
||
the data was recorded at fixed intervals but there are some
|
||
missing records and the fixed interval is the same as the
|
||
<span class="code">archive_interval</span> setting under
|
||
<span class="code">[StdArchive]</span> in
|
||
<span class="code">weewx.conf</span>. Select this method by
|
||
setting <span class="code">interval = conf</span>.</li>
|
||
<li>The interval can be set to a fixed number of minutes. This
|
||
setting is useful if the source data was recorded at fixed
|
||
intervals but there are some missing records and the fixed
|
||
interval is different to the
|
||
<span class="code">archive_interval</span> setting under
|
||
<span class="code">[StdArchive]</span> in
|
||
<span class="code">weewx.conf</span>. Select this method by
|
||
setting <span class="code">interval = x</span> where
|
||
<span class="code">x</span> is an integer number of minutes.
|
||
</li>
|
||
</ul>
|
||
|
||
<p>The default value is <span class="code">derive</span>. If the CSV source
|
||
data records are equally spaced in time, but some records are missing,
|
||
then better result may be achieved using <span class="code">conf</span>
|
||
or a fixed interval setting.
|
||
</p>
|
||
|
||
<p class='config_option' id='csv_qc'>qc</p>
|
||
|
||
<p>Determines whether simple quality control checks are applied to imported
|
||
data. Setting <span class="code">qc = True</span> will result in
|
||
<span class="code">wee_import</span> applying the
|
||
<span class="code">weewx</span> <span class="code">StdQC</span> minimum
|
||
and maximum checks to any imported observations.
|
||
<span class="code">wee_import</span> quality control checks use the same
|
||
configuration settings, and operate in the same manner, as the
|
||
<span class="code">weewx</span> <span class="code">StdQC</span> service
|
||
(refer to the <a href="usersguide.htm#StdQC">[StdQC]</a> section of the
|
||
<a href="usersguide.htm">User's Guide</a>). If an observation falls
|
||
outside of the quality control range for that observation, then the
|
||
observation will be set to <span class="code">None</span>. The user will
|
||
be alerted through a short message to
|
||
<span class="code">stdout</span>(console) and the
|
||
<span class="code">weewx</span> log similar to:</p>
|
||
|
||
<pre class="tty">2016-01-12 10:00:00 AEST (1452556800) record value 'outTemp' 194.34 outside limits (0.0, 120.0)
|
||
</pre>
|
||
|
||
<p>As derived observations are calculated after the quality control check is applied, derived
|
||
observations are not subject to quality control checks. Setting
|
||
<span class="code">qc = False</span> will result in
|
||
<span class="code">wee_import</span> not applying quality control checks
|
||
to imported data. The default is <span class="code">True</span>.
|
||
</p>
|
||
|
||
<p class='config_option' id='csv_calc_missing'>calc_missing</p>
|
||
|
||
<p>Determines whether any missing derived observations will be calculated
|
||
from the imported data. Setting
|
||
<span class="code">calc_missing = True</span> will result in
|
||
<span class="code">wee_import</span> using the <span class="code">weewx</span>
|
||
<span class="code">StdWXCalculate</span> service to calculate any
|
||
missing derived observations from the imported data. Setting
|
||
<span class="code">calc_missing = False</span> will result in
|
||
<span class="code">weewx</span> leaving any missing derived observations
|
||
as <span class="code">None</span>. The observations that
|
||
<span class="code">StdWXCalculate</span> can calculate are listed in the
|
||
<a href="usersguide.htm#StdWXCalculate">[StdWXCalculate]</a> section
|
||
of the <a href="usersguide.htm">User's Guide</a>. The default is
|
||
<span class="code">True</span>.
|
||
</p>
|
||
|
||
<p class='config_option' id='csv_tranche'>tranche</p>
|
||
|
||
<p>To speed up database operations imported records are committed to
|
||
database in groups of records rather than individually. The size of the
|
||
group is set by the <span class="code">tranche</span> parameter.
|
||
Increasing the <span class="code">tranche</span> parameter may result
|
||
in a slight speed increase but at the expense of increased memory usage.
|
||
Decreasing the <span class="code">tranche</span> parameter will result
|
||
in less memory usage but at the expense of more frequent database access
|
||
and likely increased time to import. The default is
|
||
<span class="code">250</span> which should suit most users.
|
||
</p>
|
||
|
||
<p class='config_option' id='csv_UV'>UV_sensor</p>
|
||
|
||
<p><span class="code">weewx</span> records a
|
||
<span class="code">None/NULL</span> for UV when no UV sensor is
|
||
installed, whereas some weather station software records a value of 0
|
||
for UV index when there is no UV sensor installed. The
|
||
<span class="code">UV_sensor</span> parameter enables
|
||
<span class="code">wee_import</span> to distinguish between the case
|
||
where a UV sensor is present and the UV index is 0 and the case where
|
||
no UV sensor is present and UV index is 0.
|
||
<span class="code">UV_sensor = False</span> should be used when no UV
|
||
sensor was used in producing the source data.
|
||
<span class="code">UV_sensor = False</span> will result in
|
||
<span class="code">None/Null</span> being recorded in the
|
||
<span class="code">weewx</span> archive field
|
||
<span class="code">UV</span> irrespective of any UV observations in the
|
||
source data. <span class="code">UV_sensor = True</span> should be used
|
||
when a UV sensor was used in producing the source data.
|
||
<span class="code">UV_sensor = True</span> will result in UV
|
||
observations in the source data being stored in the
|
||
<span class="code">weewx</span> archive field
|
||
<span class="code">UV</span>. The default is
|
||
<span class="code">True</span>.
|
||
</p>
|
||
|
||
<p class='config_option' id='csv_solar'>solar_sensor</p>
|
||
|
||
<p><span class="code">weewx</span> records a
|
||
<span class="code">None/NULL</span> when no solar radiation sensor is
|
||
installed, whereas some weather station software records a value of 0
|
||
for solar radiation when there is no solar radiation sensor installed.
|
||
The <span class="code">solar_sensor</span> parameter enables
|
||
<span class="code">wee_import</span> to distinguish between the case
|
||
where a solar radiation sensor is present and solar radiation is 0 and
|
||
the case where no solar radiation sensor is present and solar radiation
|
||
is 0. <span class="code">solar_sensor = False</span> should be used
|
||
when no solar radiation sensor was used in producing the source data.
|
||
<span class="code">solar_sensor = False</span> will result in
|
||
<span class="code">None/Null</span> being recorded in the
|
||
<span class="code">weewx</span> archive field
|
||
<span class="code">radiation</span> irrespective of any solar radiation
|
||
observations in the source data.
|
||
<span class="code">solar_sensor = True</span> should be used when a
|
||
solar radiation sensor was used in producing the source data.
|
||
<span class="code">solar_sensor = True</span> will result in solar
|
||
radiation observations in the source data being stored in the
|
||
<span class="code">weewx</span> archive field
|
||
<span class="code">radiation</span>. The default is
|
||
<span class="code">True</span>.
|
||
</p>
|
||
|
||
<p class='config_option' id='csv_raw_datetime_format'>raw_datetime_format</p>
|
||
|
||
<p><span class="code">weewx</span> records each record with a unique unix
|
||
epoch timestamp, whereas many weather station applications or web
|
||
sources export observational data with a human readable date-time.
|
||
This human readable date-time is interpreted according to the format
|
||
set by the <span class="config_option">raw_datetime_format</span>
|
||
option. This option consists of <em>
|
||
<a href="https://docs.python.org/2/library/datetime.html#strftime-and-strptime-behavior">Python strptime() format codes</a>
|
||
</em> and literal characters to represent the date-time data being
|
||
imported. For example, if the source data uses the format
|
||
23 January 2015 15:34 then the appropriate setting for
|
||
<span class="config_option">raw_datetime_format</span> would be
|
||
<span class="code">%d %B %Y %H:%M</span>, 9:25:00 12/28/16 would use
|
||
<span class="code">%H:%M:%S %m/%d/%y</span>. If the source data provides
|
||
a unix epoch timestamp as the date-time field then the unix epoch
|
||
timestamp is used directly and the
|
||
<span class="config_option">raw_datetime_format</span> option is
|
||
ignored. The default is <span class="code">%Y-%m-%d %H:%M:%S</span>.
|
||
</p>
|
||
|
||
<p class='config_option' id='csv_rain'>rain</p>
|
||
|
||
<p><span class="code">weewx</span> records rainfall as the amount of rain
|
||
in the preceding archive period, so for a 5 minute archive period the
|
||
rain field in each archive record would contain the total rain that
|
||
fell in the previous 5 minutes. Many weather station applications
|
||
provide a daily or yearly total. <span class="code">wee_import</span>
|
||
can derive the <span class="code">weewx</span>
|
||
<span class="code">rain</span> field in one of two ways:
|
||
</p>
|
||
|
||
<ul>
|
||
<li>If the imported rain data is a running total then
|
||
<span class="code">wee_import</span> can derive the
|
||
<span class="code">weewx rain</span> field from successive
|
||
totals. For this method use
|
||
<span class="config_option">rain = cumulative</span>.
|
||
</li>
|
||
|
||
<li>If the imported rain data is a discrete value per date-time
|
||
period then <span class="config_option">rain = discrete</span>
|
||
should be used.
|
||
</li>
|
||
</ul>
|
||
</p>
|
||
|
||
<p class="note" style="display:inline-block; width:70%">
|
||
<b>Note</b><br/><span class="code">wee_import</span> only supports
|
||
cumulative rainfall data that resets on a midnight boundary, cumulative
|
||
rainfall data that resets at some other time; eg 9am, is not supported.
|
||
In such cases the rainfall data will need to be converted to either
|
||
reset on a midnight boundary or a discrete value per date-time period
|
||
and <span class="config_option">rain = discrete</span> used. The former
|
||
may be possible by selecting another rainfall field (if available) in
|
||
the source data, otherwise it will require manual manipulation of the
|
||
source data.
|
||
</p>
|
||
|
||
<p class='config_option' id='csv_wind_direction'>wind_direction</p>
|
||
|
||
<p><span class="code">weewx</span> records wind direction in degrees as a
|
||
number from 0 to 360 inclusive (no wind direction is recorded as
|
||
<span class="code">None/NULL</span>), whereas some data sources may
|
||
provide wind direction as number over a different range (eg -180 to
|
||
+180) or may use a particular value when there is no wind direction
|
||
(eg 0 may represent no wind direction and 360 may represent a northerly
|
||
wind, or -9999 (or some similar clearly invalid number) to represent
|
||
there being no wind direction). <span class="code">wee_import</span>
|
||
handles such variations in data by defining a range over which imported
|
||
wind direction values are accepted. Any value outside of this range is
|
||
treated as there being no wind direction and is recorded as
|
||
<span class="code">None/NULL</span>. Any value inside the range is
|
||
normalised to the range 0 to 360 inclusive (eg -180 would be normalised
|
||
to 180). The <span class="config_option">wind_direction</span> option
|
||
consists of two comma separated numbers of the format lower, upper where
|
||
lower and upper are inclusive. The operation of the
|
||
<span class="config_option">wind_direction</span> option is best
|
||
illustrated through the following table:
|
||
</p>
|
||
|
||
<table class="indent" style="width:50%" summary="wind_direction operation">
|
||
<tbody>
|
||
<tr class="first_row">
|
||
<td><span class="config_option">wind_direction</span> option setting</td>
|
||
<td>Source data wind direction value</td>
|
||
<td>Imported wind direction value</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="code first_col" rowspan='7'>0, 360</td>
|
||
<td>0</td>
|
||
<td>0</td>
|
||
</tr>
|
||
<tr>
|
||
<td>160</td>
|
||
<td>160</td>
|
||
</tr>
|
||
<tr>
|
||
<td>360</td>
|
||
<td>360</td>
|
||
</tr>
|
||
<tr>
|
||
<td>500</td>
|
||
<td><span class="code">None/NULL</span></td>
|
||
</tr>
|
||
<tr>
|
||
<td>-45</td>
|
||
<td><span class="code">None/NULL</span>/td>
|
||
</tr>
|
||
<tr>
|
||
<td>-9999</td>
|
||
<td><span class="code">None/NULL</span></td>
|
||
</tr>
|
||
<tr>
|
||
<td>No data</td>
|
||
<td><span class="code">None/NULL</span></td>
|
||
</tr>
|
||
<tr>
|
||
<td class="code first_col" rowspan='7'>-360, 360</td>
|
||
<td>0</td>
|
||
<td>0</td>
|
||
</tr>
|
||
<tr>
|
||
<td>160</td>
|
||
<td>160</td>
|
||
</tr>
|
||
<tr>
|
||
<td>360</td>
|
||
<td>360</td>
|
||
</tr>
|
||
<tr>
|
||
<td>500</td>
|
||
<td><span class="code">None/NULL</span></td>
|
||
</tr>
|
||
<tr>
|
||
<td>-45</td>
|
||
<td>315</td>
|
||
</tr>
|
||
<tr>
|
||
<td>-9999</td>
|
||
<td><span class="code">None/NULL</span></td>
|
||
</tr>
|
||
<tr>
|
||
<td>No data</td>
|
||
<td><span class="code">None/NULL</span></td>
|
||
</tr>
|
||
<tr>
|
||
<td class="code first_col" rowspan='7'>-180, 180</td>
|
||
<td>0</td>
|
||
<td>0</td>
|
||
</tr>
|
||
<tr>
|
||
<td>160</td>
|
||
<td>160</td>
|
||
</tr>
|
||
<tr>
|
||
<td>360</td>
|
||
<td><span class="code">None/NULL</span></td>
|
||
</tr>
|
||
<tr>
|
||
<td>500</td>
|
||
<td><span class="code">None/NULL</span></td>
|
||
</tr>
|
||
<tr>
|
||
<td>-45</td>
|
||
<td>315</td>
|
||
</tr>
|
||
<tr>
|
||
<td>-9999</td>
|
||
<td><span class="code">None/NULL</span></td>
|
||
</tr>
|
||
<tr>
|
||
<td>No data</td>
|
||
<td><span class="code">None/NULL</span></td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
|
||
<p>The default is <span class="config_option">0, 360</span>.
|
||
</p>
|
||
|
||
<p class='config_option' id='csv_map'>[[Map]]</p>
|
||
|
||
<p>The <span class='config_option'>[[Map]]</span> stanza defines the mapping
|
||
from the source data fields to <span class="code">weewx</span> archive
|
||
fields. The map consists of one row per field using the format:
|
||
</p>
|
||
|
||
<pre class="tty">weewx_archive_field_name = csv_field_name, weewx_unit_name
|
||
</pre>
|
||
|
||
<p>Where <span class="config_option">weewx_archive_field_name</span> is a
|
||
database field name in the <span class="code">weewx</span> archive table
|
||
schema, <span class="config_option">csv_field_name</span> is the name
|
||
of a field from the CSV file and
|
||
<span class="config_option">weewx_unit_name</span> is the
|
||
<span class="code">weewx</span> unit name of the units used by
|
||
<span class="config_option">csv_field_name</span>. This mapping allows
|
||
<span class="code">wee_import</span> to take a source data field, do
|
||
the appropriate unit conversion and store the resulting value in the
|
||
appropriate <span class="code">weewx</span> archive field. A mapping is
|
||
not required for every <span class="code">weewx</span> archive field
|
||
(eg the source may not provide inside temperature so no
|
||
<span class="code">inTemp</span> field mapping is required) and neither
|
||
does every CSV field need to be included in a mapping (eg the source
|
||
data field <span class="code">monthrain</span> may have no use if the
|
||
source data field <span class="code">dayrain</span> provides the data
|
||
for the <span class="code">weewx</span> archive
|
||
<span class="code">rain</span> field). Unused field mapping lines will
|
||
not be used and may be omitted.
|
||
</p>
|
||
|
||
<p class="note" style="display:inline-block; width:70%">
|
||
<b>Note</b><br/>Any <span class="code">weewx</span> archive fields that
|
||
are derived (eg <span class="code">dewpoint</span>) and for which there
|
||
is no field mapping may be calculated during import by use of the
|
||
<span class="config_option">calc_missing</span> option in the
|
||
<span class="code">[CSV]</span> section of the import configuration
|
||
file.
|
||
</p>
|
||
|
||
<h3 class="config_section">[Wunder]</h3>
|
||
|
||
<p>The <span class="config_option">[Wunder]</span> section contains the
|
||
options relating to the import of observational data from a Weather
|
||
Underground PWS daily history.
|
||
</p>
|
||
|
||
<p class='config_option' id='wunder_station_id'>station_id</p>
|
||
|
||
<p>The Weather Underground weather station ID of the PWS from which the
|
||
daily history will be imported. There is no default.
|
||
</p>
|
||
|
||
<p class='config_option' id='wunder_interval'>interval</p>
|
||
|
||
<p>Determines how the time interval (<span class="code">weewx</span>
|
||
database field <span class="code">interval</span>) between successive
|
||
observations is determined. This option is identical in operation to the
|
||
CSV <em><a href="#csv_interval">interval</a></em> option but applies to
|
||
Weather Underground imports only. As Weather Underground often skips
|
||
observation records when responding to a daily history query, the use of
|
||
<span class="config_option">interval = derive</span> may give incorrect
|
||
or inconsistent interval values. Better results may be obtained by using
|
||
<span class="config_option">interval = conf</span> if the current
|
||
<span class="code">weewx</span> installation has the same
|
||
<span class="code">archive_interval</span> as the Weather Underground
|
||
data, or by using <span class="config_option">interval = x</span> where
|
||
<span class="config_option">x</span> is the time interval in minutes
|
||
used to upload the Weather Underground data. The most appropriate
|
||
setting will depend on the completeness and (time) accuracy of the
|
||
Weather Underground data being imported.
|
||
</p>
|
||
|
||
<p>The default is <span class="code">derive</span>.</p>
|
||
|
||
<p class='config_option' id='wunder_qc'>qc</p>
|
||
|
||
<p>Determines whether simple quality control checks are applied to imported
|
||
data. This option is identical in operation to the CSV
|
||
<em><a href="#csv_qc">qc</a></em> option but applies to Weather
|
||
Underground imports only. As Weather Underground imports at times
|
||
contain nonsense values, particularly for fields for which no data was
|
||
uploaded to Weather Underground by the PWS, the use of quality control
|
||
checks on imported data can prevent these nonsense values from being
|
||
imported and contaminating the <span class="code">weewx</span> database.
|
||
The default is <span class="code">True</span>.
|
||
</p>
|
||
|
||
<p class='config_option' id='wunder_calc_missing'>calc_missing</p>
|
||
|
||
<p>Determines whether any missing derived observations will be calculated
|
||
from the imported data. This option is identical in operation to the
|
||
CSV <em><a href="#csv_calc_missing">calc_missing</a></em> option but
|
||
applies to Weather Underground imports only. The default is
|
||
<span class="code">True</span>.
|
||
</p>
|
||
|
||
<p class='config_option' id='wunder_tranche'>tranche</p>
|
||
|
||
<p>The number of records written to the <span class="code">weewx</span>
|
||
database in each transaction. This option is identical in operation to
|
||
the CSV <em><a href="#csv_tranche">tranche</a></em> option but applies
|
||
to Weather Underground imports only. The default is
|
||
<span class="code">250</span> which should suit most users.
|
||
</p>
|
||
|
||
<p class='config_option' id='wunder_wind_direction'>wind_direction</p>
|
||
|
||
<p>Determines the range of acceptable wind direction values in degrees.
|
||
This option is identical in operation to the CSV
|
||
<em><a href="#csv_wind_direction">wind_direction</a></em> option but
|
||
applies to Weather Underground imports only. The default is
|
||
<span class="config_option">0, 360</span> which should suit most users.
|
||
</p>
|
||
|
||
<h3 class="config_section">[Cumulus]</h3>
|
||
|
||
<p>The <span class="config_option">[Cumulus]</span> section contains the
|
||
options relating to the import of observational data from Cumulus
|
||
monthly log files.
|
||
</p>
|
||
|
||
<p class='config_option' id='cumulus_directory'>directory</p>
|
||
|
||
<p>The full path to the directory containing the Cumulus monthly log files
|
||
to be imported. Do not include a trailing /. There is no default.
|
||
</p>
|
||
|
||
<p class='config_option' id='cumulus_interval'>interval</p>
|
||
|
||
<p>Determines how the time interval (<span class="code">weewx</span>
|
||
database field <span class="code">interval</span>) between successive
|
||
observations is determined. This option is identical in operation to
|
||
the CSV <em><a href="#csv_interval">interval</a></em> option but
|
||
applies to Cumulus monthly log file imports only. As Cumulus monthly
|
||
log files can, at times, have missing entries, the use of
|
||
<span class="config_option">interval = derive</span> may give incorrect
|
||
or inconsistent interval values. Better results may be obtained by
|
||
using <span class="config_option">interval = conf</span> if the
|
||
<span class="config_option">archive_interval</span> for the current
|
||
<span class="code">weewx</span> installation is the same as the Cumulus
|
||
'data log interval' setting used to generate the Cumulus monthly log
|
||
files, or by using <span class="config_option">interval = x</span> where
|
||
<span class="config_option">x</span> is the time interval in minutes
|
||
used as the Cumulus 'data log interval' setting. The most appropriate
|
||
setting will depend on the completeness and (time) accuracy of the
|
||
Cumulus data being imported.
|
||
</p>
|
||
|
||
<p>The default is <span class="code">derive</span>.</p>
|
||
|
||
<p class='config_option' id='cumulus_qc'>qc</p>
|
||
|
||
<p>Determines whether simple quality control checks are applied to imported
|
||
data. This option is identical in operation to the CSV
|
||
<em><a href="#csv_qc">qc</a></em> option but applies to Cumulus imports
|
||
only. The default is <span class="code">True</span>.
|
||
</p>
|
||
|
||
<p class='config_option' id='cumulus_calc_missing'>calc_missing</p>
|
||
|
||
<p>Determines whether any missing derived observations will be calculated
|
||
from the imported data. This option is identical in operation to the
|
||
CSV <em><a href="#csv_calc_missing">calc_missing</a></em> option but
|
||
applies to Cumulus imports only. The default is
|
||
<span class="code">True</span>.
|
||
</p>
|
||
|
||
<p class='config_option' id='cumulus_delimiter'>delimiter</p>
|
||
|
||
<p>The character used as the field delimiter in the Cumulus monthly log
|
||
file. A comma is frequently used but it may be another character
|
||
depending on the settings on the machine that produced the Cumulus
|
||
monthly log files. This parameter must be included in quotation marks.
|
||
Default is <span class="config_option">','</span>.
|
||
</p>
|
||
|
||
<p class='config_option' id='cumulus_decimal'>decimal</p>
|
||
|
||
<p>The character used as the decimal point in the Cumulus monthly log files
|
||
A full stop is frequently used but it may be another character depending
|
||
on the settings on the machine that produced the Cumulus monthly log
|
||
files. This parameter must be included in quotation marks. Default is
|
||
<span class="config_option">'.'</span>.
|
||
</p>
|
||
|
||
<p class='config_option' id='cumulus_tranche'>tranche</p>
|
||
|
||
<p>The number of records are written to the <span class="code">weewx</span>
|
||
database in each transaction. This option is identical in operation to
|
||
the CSV <em><a href="#csv_tranche">tranche</a></em> option but applies
|
||
to Cumulus monthly log file imports only. The default is
|
||
<span class="config_option">250</span> which should suit most users.
|
||
</p>
|
||
|
||
<p class='config_option' id='cumulus_UV'>UV_sensor</p>
|
||
|
||
<p>The <span class="config_option">UV_sensor</span> parameter enables
|
||
<span class="code">wee_import</span> to distinguish between the case
|
||
where a UV sensor is present and the UV index is 0 and the case where
|
||
no UV sensor is present and UV index is 0. This option is identical in
|
||
operation to the CSV <em><a href="#csv_UV">UV_sensor</a></em> option
|
||
but applies to Cumulus monthly log file imports only. The default is
|
||
<span class="config_option">True</span>.
|
||
</p>
|
||
|
||
<p class='config_option' id='cumulus_solar'>solar_sensor</p>
|
||
|
||
<p>The <span class="config_option">solar_sensor</span> parameter enables
|
||
<span class="code">wee_import</span> to distinguish between the case
|
||
where a solar radiation sensor is present and the solar radiation is 0
|
||
and the case where no solar radiation sensor is present and solar
|
||
radiation is 0. This option is identical in operation to
|
||
the CSV <em><a href="#csv_solar">solar_sensor</a></em> option but
|
||
applies to Cumulus monthly log file imports only. The default is
|
||
<span class="config_option">True</span>.
|
||
</p>
|
||
|
||
<p class='config_option' id='cumulus_units'>[[Units]]</p>
|
||
|
||
<p>The <span class="config_option">[[Units]]</span> stanza defines the units
|
||
used in the Cumulus monthly log files. Units settings are required for
|
||
<span class="code">temperature</span>,
|
||
<span class="code">pressure</span>, <span class="code">rain</span> and
|
||
<span class="code">speed</span>. The format for each setting is:
|
||
</p>
|
||
|
||
<pre class="tty">obs_type = weewx_unit_name
|
||
</pre>
|
||
|
||
<p>Where <span class="code">obs_type</span> is one of
|
||
<span class="code">temperature</span>,
|
||
<span class="code">pressure</span>, <span class="code">rain</span> or
|
||
<span class="code">speed</span> and
|
||
<span class="code">weewx_unit_name</span> is the
|
||
<span class="code">weewx</span> unit name of the units used by that
|
||
particular <span class="code">obs_type</span>. As Cumulus supports a
|
||
different suite of possible units only a subset of the available
|
||
<span class="code">weewx</span> unit names can be used for some
|
||
settings.
|
||
</p>
|
||
|
||
<h1 id="porting">Porting to new hardware</h1>
|
||
|
||
<p>Naturally, this is an advanced topic but, nevertheless, I'd
|
||
like to encourage any Python wizards out there to give it a try. Of
|
||
course, I have selfish reasons for this: I don't want to
|
||
have to buy every weather station ever invented, and I don't want
|
||
my roof to look like a weather station farm!</p>
|
||
|
||
<h2>General guidelines</h2>
|
||
<p>
|
||
<ul>
|
||
<li>The driver should emit data as it receives it from the hardware (no caching).</li>
|
||
<li>The driver should emit only data it receives from the hardware (no "filling in the gaps").</li>
|
||
<li>The driver should not modify the data unless the modification is directly related to the
|
||
hardware (e.g., decoding a hardware-specific sensor value).</li>
|
||
<li>If the hardware flags "bad data", then the driver should emit a null
|
||
value for that datum (Python <span class="code">None</span>).</li>
|
||
<li>The driver should not calculate any derived variables (such as dewpoint). The service
|
||
<span class="code">StdWXService</span> will do that.</li>
|
||
<li>However, if the hardware emits a derived variable, then the driver should emit it.</li>
|
||
</ul>
|
||
</p>
|
||
|
||
<h2>Implement the driver</h2>
|
||
|
||
<p>Create a file in the user directory, say
|
||
<span class="code">mydriver.py</span>. This file will contain the
|
||
driver class as well as any hardware-specific code. Do not put it
|
||
in the <span class="code">weewx/drivers</span> directory or it will
|
||
be deleted when you upgrade weewx.</p>
|
||
|
||
<p>Inherit from the abstract base class
|
||
<span class="code">weewx.drivers.AbstractDevice</span>.
|
||
Try to implement as many of its methods as you can. At the
|
||
very minimum, you must implement the first three
|
||
methods, <span class="code">loader</span>,
|
||
<span class="code">hardware_name</span>,
|
||
and <span class="code">genLoopPackets</span>. </p>
|
||
|
||
<h3><span class="code">loader</span></h3>
|
||
|
||
<p>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>
|
||
|
||
<h3><span class="code">hardware_name</span></h3>
|
||
|
||
<p>Return a string with a short nickname for the hardware, such
|
||
as <span class="code">"ACME X90"</span></p>
|
||
|
||
<h3><span class="code">genLoopPackets</span></h3>
|
||
|
||
<p>This should be
|
||
a <a href="https://wiki.python.org/moin/Generators">generator
|
||
function</a> 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 for the
|
||
observation time and for the units used within the packet.</p>
|
||
<table class="indent" style="width: 60%">
|
||
<caption>Required keys</caption>
|
||
<tbody>
|
||
<tr>
|
||
<td class="code first_col">dateTime</td>
|
||
<td>The time of the observation in unix epoch time.</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="code first_col">usUnits</td>
|
||
<td>The unit system used. <span class="code">weewx.US</span> for US
|
||
customary, <span class="code">weewx.METRICWX</span>, or
|
||
<span class="code">weewx.METRIC</span> for metric. See
|
||
the file <span class="code">units.py</span>, dictionaries <span
|
||
class="code">USUnits</span>, <span class="code">MetricWXUnits</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, <span class="code">rain</span>.
|
||
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%">
|
||
<caption>Pressure types</caption>
|
||
<tbody>
|
||
<tr>
|
||
<td class="code first_col">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 first_col">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 first_col">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>
|
||
|
||
<h3><span class="code">genArchiveRecords()</span></h3>
|
||
|
||
<p>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.</p>
|
||
|
||
<p>However, 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>
|
||
|
||
<h3><span class="code">archive_interval</span></h3>
|
||
|
||
<p>If you implement function <span class="code">genArchiveRecords()</span>
|
||
above, then you should also implement <span class='code'>archive_interval</span>
|
||
as either an attribute, or as a <a
|
||
href="https://docs.python.org/2/library/functions.html#property">property
|
||
function</a>. It should return the archive
|
||
interval in seconds.</p>
|
||
|
||
<h3><span class="code">getTime()</span></h3>
|
||
|
||
<p>If your hardware has an onboard clock and supports reading
|
||
the time from it, then you may want to implement this
|
||
method. It takes no argument. It should return the time in
|
||
Unix Epoch Time. </p>
|
||
|
||
<h3><span class="code">setTime()</span></h3>
|
||
|
||
<p>If your hardware has an onboard clock and supports <em>setting</em>
|
||
it, then you may want to implement this method. It takes no
|
||
argument and does not need to return anything.</p>
|
||
|
||
<h3><span class="code">closePort()</span></h3>
|
||
|
||
<p>If the driver needs to close a serial port, terminate a
|
||
thread, close a database, or perform any other activity before
|
||
the application terminates, then you must supply this
|
||
function. <span class='code'>Weewx</span> will call it if it
|
||
needs to shut down your console (usually in the case of an
|
||
error).</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>The <span class='code'>fileparse</span> driver is perhaps the most
|
||
simple example of a <span class="code">weewx</span> driver. It reads
|
||
name-value pairs from a file and uses the values as sensor 'readings'.
|
||
The code is located in <span class="code">extensions/fileparse/bin/user/fileparse.py</span></p>
|
||
|
||
<p>Take a look at the simulator code
|
||
in <span class='code'>bin/weewx/drivers/simulator.py</span>. It's
|
||
dirt simple and you can easily play with it. Many people have
|
||
successfully used it as a starting point for writing their own
|
||
custom driver.</p>
|
||
|
||
<p>The Ultimeter (<span class="code">ultimeter.py</span>) and WMR100
|
||
(<span class="code">wmr100.py</span>) drivers illustrate how to
|
||
communicate with serial and USB hardware, respectively. They also
|
||
show different approaches for decoding data. Nevertheless,
|
||
they are pretty straightforward.</p>
|
||
|
||
<p>The driver for the Vantage series is by far the most complicated. It
|
||
actually multi-inherits from not only
|
||
<span class="code">AbstractDevice</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="extensions">Extensions</h1>
|
||
|
||
<p>
|
||
A key feature of <span class="code">weewx</span> is its ability to be
|
||
extended by installing 3rd party <em>extensions</em>.
|
||
Extensions are a way to package one or more customizations so they
|
||
can be installed and distributed as a functional group.
|
||
</p>
|
||
|
||
<p>Customizations typically fall into one of these categories:</p>
|
||
<ul>
|
||
<li>search list extension</li>
|
||
<li>template</li>
|
||
<li>skin</li>
|
||
<li>service</li>
|
||
<li>generator</li>
|
||
<li>driver</li>
|
||
</ul>
|
||
|
||
<p>Take a look at the
|
||
<a href="https://github.com/weewx/weewx/wiki">
|
||
<span class="code">weewx</span> wiki</a>
|
||
for a sampling of some of the extensions that are available.
|
||
</p>
|
||
|
||
<h2>
|
||
The utility <span class="code">wee_extension</span>
|
||
</h2>
|
||
|
||
<p>
|
||
The utility <span class="code">wee_extension</span> is used to add and
|
||
remove extensions. It's worth running with the
|
||
<span class="code">--help</span>
|
||
option to see how it is used:
|
||
</p>
|
||
|
||
<pre class="tty cmd">wee_extension --help</pre>
|
||
|
||
<p>This results in:</p>
|
||
|
||
<pre class="tty">
|
||
Usage: wee_extension --help
|
||
wee_extension --list
|
||
[CONFIG_FILE|--config=CONFIG_FILE]
|
||
wee_extension --install=(filename|directory)
|
||
[CONFIG_FILE|--config=CONFIG_FILE]
|
||
[--tmpdir==DIR] [--dry-run] [--verbosity=N]
|
||
wee_extension --uninstall=EXTENSION
|
||
[CONFIG_FILE|--config=CONFIG_FILE]
|
||
[--verbosity=N]
|
||
|
||
Install, list, and uninstall extensions to weewx.
|
||
|
||
Commands:
|
||
|
||
--list: Show installed extensions.
|
||
--install: Install the specified extension.
|
||
--uninstall: Uninstall the specified extension.
|
||
|
||
Options:
|
||
-h, --help show this help message and exit
|
||
--list Show installed extensions.
|
||
--install=FILENAME|DIRECTORY
|
||
Install the extension contained in FILENAME or
|
||
DIRECTORY. FILENAME must be an archive that contains a
|
||
packaged extension such as pmon.tar.gz. DIRECTORY
|
||
must be a packaged extension.
|
||
--uninstall=EXTENSION
|
||
Uninstall the extension with name EXTENSION.
|
||
--config=CONFIG_FILE Use configuration file CONFIG_FILE.
|
||
--tmpdir=DIR Use temporary directory DIR.
|
||
--bin-root=BIN_ROOT Look in BIN_ROOT for weewx executables.
|
||
--dry-run Print what would happen but do not do it.
|
||
--verbosity=N How much status to display, 0-3</pre>
|
||
|
||
<p>To install an extension:</p>
|
||
|
||
<pre class='tty cmd'>wee_extension --install extensions/basic
|
||
wee_extension --install basic.tar.gz</pre>
|
||
|
||
<p>To uninstall an extension:</p>
|
||
|
||
<p class='tty cmd'>wee_extension --uninstall basic</p>
|
||
|
||
<p>To list installed extensions:</p>
|
||
|
||
<p class='tty cmd'>wee_extension --list</p>
|
||
|
||
<p>The utility will make only the following changes:</p>
|
||
<ul>
|
||
<li>Modifications to <span class='code'>weewx.conf</span></li>
|
||
<li>Add/Remove directories in <span class='code'>skins</span></li>
|
||
<li>Add/Remove directories in <span class='code'>user</span></li>
|
||
</ul>
|
||
<p>The utility makes a copy of any file or directory that it
|
||
modifies or replaces. When installing, it creates a directory called
|
||
<span class='code'>installer</span> in the
|
||
<span class='code'>user</span> directory. The contents of the
|
||
<span class='code'>installer</span> directory are
|
||
used to enumerate and uninstall extensions.</p>
|
||
|
||
<h2>Installing an extension</h2>
|
||
|
||
<p>
|
||
Let's try installing a simple extension,
|
||
<a href="https://github.com/weewx/weewx/wiki/cmon"><em>cmon</em></a>,
|
||
used to monitor your computer.
|
||
</p>
|
||
|
||
<p>
|
||
First download it. You can either do this from the link given in the
|
||
wiki, or by using <span class="code">wget</span> (which you may have
|
||
to install):
|
||
</p>
|
||
<pre class="tty cmd">wget -P /var/tmp http://lancet.mit.edu/mwall/projects/weather/releases/weewx-cmon-0.7.tgz</pre>
|
||
|
||
<p>
|
||
This will put the tarfile <span class="code">weewx-cmon-0.7.tgz</span>
|
||
in the directory <span class="code">/var/tmp</span>.
|
||
</p>
|
||
|
||
<p>Now install the extension:</p>
|
||
<pre class="tty"><span class="cmd">wee_extension --install=/var/tmp/weewx-cmon-0.7.tgz</span>
|
||
Request to install '/var/tmp/weewx-cmon-0.7.tgz'
|
||
Extracting from tarball /var/tmp/weewx-cmon-0.7.tgz
|
||
Added new service user.cmon.ComputerMonitor to process_services
|
||
Saving installer file to /home/weewx/bin/weecfg/user/installer/cmon
|
||
Saved configuration dictionary. Backup copy at /home/weewx/weewx.conf.20150430130322
|
||
Finished installing extension '/var/tmp/weewx-cmon-0.7.tgz'</pre>
|
||
|
||
<p>The installer has done a number of things for you:</p>
|
||
<ol>
|
||
<li>It put a new skin, <span class="code">cmon</span>, in the
|
||
<span class="code">skins</span> subdirectory;
|
||
</li>
|
||
<li>It put a new service,
|
||
<span class="code">user.cmon.ComputerMonitor</span>,
|
||
in the list of services to be run by
|
||
<span class="code">weewx</span>;
|
||
</li>
|
||
<li>It defined a new database, <span class="code">cmon_sqlite</span>,
|
||
and a binding, <span class="code">cmon_binding</span>,
|
||
to that database;
|
||
</li>
|
||
<li>It added a top-level "stanza"
|
||
<span class="code">[ComputerMonitor]</span>
|
||
to your configuration file <span class="code">weewx.conf</span>,
|
||
that specifies the data binding <span class="code">cmon</span>
|
||
is to use.
|
||
</li>
|
||
<li>And, finally, it saved the details of how the extension was
|
||
installed so you can remove it later, should you choose to do so.
|
||
</li>
|
||
</ol>
|
||
|
||
<h2>Listing installed extensions</h2>
|
||
|
||
<p>The utility <span class="code">wee_extension</span> can tell you which
|
||
extensions you have installed:</p>
|
||
<pre class="tty"><span class="cmd">wee_extension --list</span>
|
||
Extension Name Version Description
|
||
cmon 0.7 Collect and display computer health indicators</pre>
|
||
<p>You can see it lists the extension we just installed, <span class="code">cmon</span>.</p>
|
||
|
||
<h2>Removing extensions</h2>
|
||
|
||
<p>You can remove an extension using the same tool:</p>
|
||
<pre class="tty"><span class="cmd">wee_extension --uninstall=cmon
|
||
wee_extension --list</span>
|
||
No extensions installed</pre>
|
||
|
||
<h2>Creating an extension</h2>
|
||
|
||
<p>Now that you have made some customizations, you might want to share
|
||
those changes with other <span class='code'>weewx</span> users. Put
|
||
your customizations into an extension to make installation, removal,
|
||
and distribution easier.</p>
|
||
|
||
<p>Here are a few guidelines for creating extensions:</p>
|
||
<ul>
|
||
<li>Extensions should not modify or depend upon existing skins.
|
||
An extension should include its own, standalone skin to illustrate
|
||
any templates, search list extension, or generator features.
|
||
</li>
|
||
<li>Extensions should not modify the database schemas.
|
||
If it requires data not found in the default databases, an
|
||
extension should provide its own database and schema.
|
||
</li>
|
||
</ul>
|
||
|
||
<h2>How to package an extension</h2>
|
||
|
||
<p>The structure of an extension mirrors that of
|
||
<span class='code'>weewx</span> itself. If the customizations include
|
||
a skin, the extension will have a skins directory. If the
|
||
customizations include python code, the extension will have a
|
||
<span class='code'>bin/user</span> directory.
|
||
</p>
|
||
|
||
<p>Each extension should also include:</p>
|
||
<ul>
|
||
<li><span class='code'>readme.txt</span> - a summary of
|
||
what the extension does, list of pre-requisites (if any), and
|
||
instructions for installing the extension manually
|
||
</li>
|
||
<li><span class='code'>changelog</span> - an enumeration of
|
||
changes in each release
|
||
</li>
|
||
<li><span class='code'>install.py</span> - python code used by the
|
||
<span class='code'>weewx</span> ExtensionInstaller
|
||
</li>
|
||
</ul>
|
||
<p>For example, here is the structure of a skin called
|
||
<span class='code'>basic</span>:</p>
|
||
|
||
<pre class='tty'>basic/
|
||
basic/changelog
|
||
basic/install.py
|
||
basic/readme.txt
|
||
basic/skins/
|
||
basic/skins/basic/
|
||
basic/skins/basic/basic.css
|
||
basic/skins/basic/current.inc
|
||
basic/skins/basic/favicon.ico
|
||
basic/skins/basic/hilo.inc
|
||
basic/skins/basic/index.html.tmpl
|
||
basic/skins/basic/skin.conf</pre>
|
||
|
||
<p>Here is the structure of a search list extension called
|
||
<span class='code'>xstats</span>:</p>
|
||
|
||
<pre class='tty'>xstats/
|
||
xstats/changelog
|
||
xstats/install.py
|
||
xstats/readme.txt
|
||
xstats/bin/
|
||
xstats/bin/user/
|
||
xstats/bin/user/xstats.py</pre>
|
||
|
||
<p>See the <span class='code'>extensions</span> directory of the
|
||
<span class='code'>weewx</span> source for examples.</p>
|
||
|
||
<p>To distribute an extension, simply create a compressed archive
|
||
of the extension directory.</p>
|
||
|
||
<p>For example, create the compressed archive for the
|
||
<span class='code'>basic</span> skin like this:</p>
|
||
|
||
<p class='tty cmd'>tar cvfz basic.tar.gz basic</p>
|
||
|
||
<h1 id="archive_types">Appendix: 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.
|
||
</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">
|
||
<caption>Archive types</caption>
|
||
<tbody>
|
||
<tr class="first_row">
|
||
<td>Archive Type</td>
|
||
<td style="width: 200px">SQL Type<br/>
|
||
<span style="font-size:80%">(appears in archive database)</span></td>
|
||
<td>Can be used <br/>
|
||
in plots
|
||
</td>
|
||
<td>Can be used <br/>
|
||
in tag <span class="code">$current</span></td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col code">altimeter</td>
|
||
<td>X</td>
|
||
<td>X</td>
|
||
<td>X</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col code">barometer</td>
|
||
<td>X</td>
|
||
<td>X</td>
|
||
<td>X</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col code">consBatteryVoltage</td>
|
||
<td>X</td>
|
||
<td>X</td>
|
||
<td>X</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col code">dateTime</td>
|
||
<td>X</td>
|
||
<td><br/>
|
||
</td>
|
||
<td>X (represents current time)</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col code">dewpoint</td>
|
||
<td>X</td>
|
||
<td>X</td>
|
||
<td>X</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col code">ET</td>
|
||
<td>X</td>
|
||
<td>X</td>
|
||
<td>X</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col code">extraHumid1</td>
|
||
<td>X</td>
|
||
<td>X</td>
|
||
<td>X</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col code">extraHumid2</td>
|
||
<td>X</td>
|
||
<td>X</td>
|
||
<td>X</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col code">extraTemp1</td>
|
||
<td>X</td>
|
||
<td>X</td>
|
||
<td>X</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col code">extraTemp2</td>
|
||
<td>X</td>
|
||
<td>X</td>
|
||
<td>X</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col code">extraTemp3</td>
|
||
<td>X</td>
|
||
<td>X</td>
|
||
<td>X</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col code">hail</td>
|
||
<td>X</td>
|
||
<td>X</td>
|
||
<td>X</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col code">hailRate</td>
|
||
<td>X</td>
|
||
<td>X</td>
|
||
<td>X</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col code">heatindex</td>
|
||
<td>X</td>
|
||
<td>X</td>
|
||
<td>X</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col code">heatingTemp</td>
|
||
<td>X</td>
|
||
<td>X</td>
|
||
<td>X</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col code">heatingVoltage</td>
|
||
<td>X</td>
|
||
<td>X</td>
|
||
<td>X</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col code">inHumidity</td>
|
||
<td>X</td>
|
||
<td>X</td>
|
||
<td>X</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col code">inTemp</td>
|
||
<td>X</td>
|
||
<td>X</td>
|
||
<td>X</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col code">inTempBatteryStatus</td>
|
||
<td>X</td>
|
||
<td>X</td>
|
||
<td>X</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col code">interval</td>
|
||
<td>X</td>
|
||
<td>X</td>
|
||
<td>X</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col code">leafTemp2</td>
|
||
<td>X</td>
|
||
<td>X</td>
|
||
<td>X</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col code">leafWet2</td>
|
||
<td>X</td>
|
||
<td>X</td>
|
||
<td>X</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col code">outHumidity</td>
|
||
<td>X</td>
|
||
<td>X</td>
|
||
<td>X</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col code">outTemp</td>
|
||
<td>X</td>
|
||
<td>X</td>
|
||
<td>X</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col code">outTempBatteryStatus</td>
|
||
<td>X</td>
|
||
<td>X</td>
|
||
<td>X</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col code">pressure</td>
|
||
<td>X</td>
|
||
<td>X</td>
|
||
<td>X</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col code">radiation</td>
|
||
<td>X</td>
|
||
<td>X</td>
|
||
<td>X</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col code">rain</td>
|
||
<td>X</td>
|
||
<td>X</td>
|
||
<td>X</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col code">rainBatteryStatus</td>
|
||
<td>X</td>
|
||
<td>X</td>
|
||
<td>X</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col code">rainRate</td>
|
||
<td>X</td>
|
||
<td>X</td>
|
||
<td>X</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col code">referenceVoltage</td>
|
||
<td>X</td>
|
||
<td>X</td>
|
||
<td>X</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col code">rxCheckPercent</td>
|
||
<td>X</td>
|
||
<td>X</td>
|
||
<td>X</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col code">soilMoist1</td>
|
||
<td>X</td>
|
||
<td>X</td>
|
||
<td>X</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col code">soilMoist2</td>
|
||
<td>X</td>
|
||
<td>X</td>
|
||
<td>X</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col code" style="height: 33px">soilMoist3</td>
|
||
<td>X</td>
|
||
<td>X</td>
|
||
<td>X</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col code">soilMoist4</td>
|
||
<td>X</td>
|
||
<td>X</td>
|
||
<td>X</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col code">soilTemp1</td>
|
||
<td>X</td>
|
||
<td>X</td>
|
||
<td>X</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col code">soilTemp2</td>
|
||
<td>X</td>
|
||
<td>X</td>
|
||
<td>X</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col code">soilTemp3</td>
|
||
<td>X</td>
|
||
<td>X</td>
|
||
<td>X</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col code">soilTemp4</td>
|
||
<td>X</td>
|
||
<td>X</td>
|
||
<td>X</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col code">supplyVoltage</td>
|
||
<td>X</td>
|
||
<td>X</td>
|
||
<td>X</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col code">txBatteryStatus</td>
|
||
<td>X</td>
|
||
<td>X</td>
|
||
<td>X</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col code">usUnits</td>
|
||
<td>X</td>
|
||
<td>X</td>
|
||
<td>X</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col code">UV</td>
|
||
<td>X</td>
|
||
<td>X</td>
|
||
<td>X</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col code">windvec</td>
|
||
<td> </td>
|
||
<td>X (special vector type)</td>
|
||
<td> </td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col code">windBatteryStatus</td>
|
||
<td>X</td>
|
||
<td>X</td>
|
||
<td>X</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col code">windDir</td>
|
||
<td>X</td>
|
||
<td>X</td>
|
||
<td>X</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col code">windGust</td>
|
||
<td>X</td>
|
||
<td>X</td>
|
||
<td>X</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col code">windGustDir</td>
|
||
<td>X</td>
|
||
<td>X</td>
|
||
<td>X</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col code">windSpeed</td>
|
||
<td>X</td>
|
||
<td>X</td>
|
||
<td>X</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col code">windchill</td>
|
||
<td>X</td>
|
||
<td>X</td>
|
||
<td>X</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
|
||
<h1 id="aggregation_types">Appendix: Aggregation types</h1>
|
||
|
||
<table class="indent">
|
||
<caption>Aggregation types</caption>
|
||
<tbody>
|
||
<tr class="first_row">
|
||
<td>Aggregation type</td>
|
||
<td>Meaning</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col code">avg</td>
|
||
<td>The average value in the aggregation period.</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col code">sum</td>
|
||
<td>The sum of values in the aggregation period.</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col code">count</td>
|
||
<td>The number of non-null values in the aggregation period.</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col code">min</td>
|
||
<td>The minimum value in the aggregation period.</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col code">mintime</td>
|
||
<td>The time of the minimum value.</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col code">max</td>
|
||
<td>The maximum value in the aggregation period.</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col code">maxtime</td>
|
||
<td>The time of the maximum value.</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col code">maxmin</td>
|
||
<td>The maximum daily minimum in the aggregation period. Aggregation period
|
||
must be one day or longer.
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col code">maxmintime</td>
|
||
<td>The time of the maximum daily minimum.</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col code">minmax</td>
|
||
<td>The minimum daily maximum in the aggregation period. Aggregation period
|
||
must be one day or longer.
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col code">minmaxtime</td>
|
||
<td>The time of the minimum daily maximum.</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col code">maxsum</td>
|
||
<td>The maximum daily sum in the aggregation period. Aggregation
|
||
period must be one day or longer.
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col code">maxsumtime</td>
|
||
<td>The time of the maximum daily sum.</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col code">meanmin</td>
|
||
<td>The average daily minimum in the aggregation period. Aggregation
|
||
period must be one day or longer.
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col code">meanmax</td>
|
||
<td>The average daily maximum in the aggregation period. Aggregation
|
||
period must be one day or longer.
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col code">gustdir</td>
|
||
<td>The direction of the max gust in the aggregation period.</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col code">last</td>
|
||
<td>The last value in the aggregation period.</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col code">lasttime</td>
|
||
<td>The time of the last value in the aggregation period.</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col code">max_ge(val)</td>
|
||
<td>The number of days where the maximum value is greater than or
|
||
equal to <em>val</em>. Aggregation period must be one day or longer.
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col code">max_le(val)</td>
|
||
<td>The number of days where the maximum value is less than or
|
||
equal to <em>val</em>. Aggregation period must be one day or longer.
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col code">min_ge(val)</td>
|
||
<td>The number of days where the minimum value is greater than or
|
||
equal to <em>val</em>. Aggregation period must be one day or longer.
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col code">min_le(val)</td>
|
||
<td>The number of days where the minimum value is less than or
|
||
equal to <em>val</em>. Aggregation period must be one day or longer.
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col code">sum_ge(val)</td>
|
||
<td>The number of days where the sum of value is greater than or
|
||
equal to <em>val</em>. Aggregation period must be one day or longer.
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col code">rms</td>
|
||
<td>The root mean square value in the aggregation period.</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col code">vecavg</td>
|
||
<td>The vector average speed in the aggregation period.</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col code">vecdir</td>
|
||
<td>The vector averaged direction during the aggregation period.</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
|
||
<h1 id="units">Appendix: Units</h1>
|
||
|
||
<p>Weewx offers three different <em>unit systems</em>:</p>
|
||
|
||
<table class="indent" style="width: 80%">
|
||
<caption>The standard unit systems used within weewx</caption>
|
||
<tr class="first_row">
|
||
<td>Name</td>
|
||
<td>Encoded value</td>
|
||
<td>Note</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col"><span class="code">US</span></td>
|
||
<td>0x01</td>
|
||
<td>U.S. Customary</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col"><span class="code">METRICWX</span></td>
|
||
<td>0x11</td>
|
||
<td>Metric, with rain related measurements in
|
||
<span class="code">mm</span> and speeds in
|
||
<span class="code">m/s</span>
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col"><span class="code">METRIC</span></td>
|
||
<td>0x10</td>
|
||
<td>Metric, with rain related measurements in
|
||
<span class="code">cm</span> and speeds in
|
||
<span class="code">km/hr</span>
|
||
</td>
|
||
</tr>
|
||
</table>
|
||
|
||
<p>The table below lists all the unit groups, their members, which
|
||
units are options for the group, and what the defaults are
|
||
for each standard unit system. </p>
|
||
<table class="indent" style="width:90%">
|
||
<caption>Unit groups, members and options</caption>
|
||
<tbody class="code">
|
||
<tr class="first_row">
|
||
<td>Group</td>
|
||
<td>Members</td>
|
||
<td>Unit options</td>
|
||
<td><span class="code">US</span></td>
|
||
<td><span class="code">METRICWX</span></td>
|
||
<td><span class="code">METRIC</span></td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col">group_altitude</td>
|
||
<td>altitude<br/>
|
||
cloudbase</td>
|
||
<td>foot <br/>
|
||
meter
|
||
</td>
|
||
<td>foot</td>
|
||
<td>meter</td>
|
||
<td>meter</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col">group_amp</td>
|
||
<td></td>
|
||
<td>amp</td>
|
||
<td>amp</td>
|
||
<td>amp</td>
|
||
<td>amp</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col">group_data</td>
|
||
<td></td>
|
||
<td>byte<br/>
|
||
bit</td>
|
||
<td>byte</td>
|
||
<td>byte</td>
|
||
<td>byte</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col">group_degree_day</td>
|
||
<td>cooldeg<br/>
|
||
heatdeg
|
||
</td>
|
||
<td>degree_F_day<br/>
|
||
degree_C_day
|
||
</td>
|
||
<td>degree_F_day</td>
|
||
<td>degree_C_day</td>
|
||
<td>degree_C_day</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col">group_direction</td>
|
||
<td>gustdir <br/>
|
||
vecdir <br/>
|
||
windDir <br/>
|
||
windGustDir
|
||
</td>
|
||
<td>degree_compass</td>
|
||
<td>degree_compass</td>
|
||
<td>degree_compass</td>
|
||
<td>degree_compass</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col">group_distance</td>
|
||
<td>windrun</td>
|
||
<td>mile<br/>
|
||
km</td>
|
||
<td>mile</td>
|
||
<td>km</td>
|
||
<td>km</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col">group_energy</td>
|
||
<td></td>
|
||
<td>watt_hour</td>
|
||
<td>watt_hour</td>
|
||
<td>watt_hour</td>
|
||
<td>watt_hour</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col">group_interval</td>
|
||
<td>interval</td>
|
||
<td>minute</td>
|
||
<td>minute</td>
|
||
<td>minute</td>
|
||
<td>minute</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col">group_length</td>
|
||
<td></td>
|
||
<td>inch<br/>
|
||
cm</td>
|
||
<td>inch</td>
|
||
<td>cm</td>
|
||
<td>cm</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col">group_moisture</td>
|
||
<td>soilMoist1 <br/>
|
||
soilMoist2 <br/>
|
||
soilMoist3 <br/>
|
||
soilMoist4
|
||
</td>
|
||
<td>centibar</td>
|
||
<td>centibar</td>
|
||
<td>centibar</td>
|
||
<td>centibar</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col">group_percent</td>
|
||
<td>extraHumid1 <br/>
|
||
extraHumid2 <br/>
|
||
inHumidity <br/>
|
||
outHumidity <br/>
|
||
rxCheckPercent
|
||
</td>
|
||
<td>percent</td>
|
||
<td>percent</td>
|
||
<td>percent</td>
|
||
<td>percent</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col">group_power</td>
|
||
<td></td>
|
||
<td>watt</td>
|
||
<td>watt</td>
|
||
<td>watt</td>
|
||
<td>watt</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col">group_pressure</td>
|
||
<td>barometer <br/>
|
||
altimeter <br/>
|
||
pressure
|
||
</td>
|
||
<td>inHg <br/>
|
||
mbar <br/>
|
||
hPa
|
||
</td>
|
||
<td>inHg</td>
|
||
<td>mbar</td>
|
||
<td>mbar</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col">group_radiation</td>
|
||
<td>radiation
|
||
</td>
|
||
<td>watt_per_meter_squared</td>
|
||
<td>watt_per_meter_squared</td>
|
||
<td>watt_per_meter_squared</td>
|
||
<td>watt_per_meter_squared</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col">group_rain</td>
|
||
<td>rain <br/>
|
||
ET <br/>
|
||
hail
|
||
</td>
|
||
<td>inch <br/>
|
||
cm <br/>
|
||
mm
|
||
</td>
|
||
<td>inch</td>
|
||
<td>mm</td>
|
||
<td>cm</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col">group_rainrate</td>
|
||
<td>rainRate <br/>
|
||
hailRate
|
||
</td>
|
||
<td>inch_per_hour <br/>
|
||
cm_per_hour <br/>
|
||
mm_per_hour
|
||
</td>
|
||
<td>inch_per_hour</td>
|
||
<td>mm_per_hour</td>
|
||
<td>cm_per_hour</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col">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>
|
||
<td>mile_per_hour</td>
|
||
<td>meter_per_second</td>
|
||
<td>km_per_hour</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col">group_speed2</td>
|
||
<td>rms <br/>
|
||
vecavg
|
||
</td>
|
||
<td>mile_per_hour2 <br/>
|
||
km_per_hour2 <br/>
|
||
knot2 <br/>
|
||
meter_per_second2
|
||
</td>
|
||
<td>mile_per_hour2</td>
|
||
<td>meter_per_second2</td>
|
||
<td>km_per_hour2</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col">group_temperature</td>
|
||
<td>appTemp <br/>
|
||
dewpoint <br/>
|
||
extraTemp1 <br/>
|
||
extraTemp2 <br/>
|
||
extraTemp3 <br/>
|
||
heatindex <br/>
|
||
heatingTemp <br/>
|
||
humidex <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>
|
||
<td>degree_F</td>
|
||
<td>degree_C</td>
|
||
<td>degree_C</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col">group_time</td>
|
||
<td>dateTime</td>
|
||
<td>unix_epoch <br/>
|
||
dublin_jd
|
||
</td>
|
||
<td>unix_epoch</td>
|
||
<td>unix_epoch</td>
|
||
<td>unix_epoch</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col">group_uv</td>
|
||
<td>UV</td>
|
||
<td>uv_index</td>
|
||
<td>uv_index</td>
|
||
<td>uv_index</td>
|
||
<td>uv_index</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col">group_volt</td>
|
||
<td>consBatteryVoltage <br/>
|
||
heatingVoltage <br/>
|
||
referenceVoltage <br/>
|
||
supplyVoltage
|
||
</td>
|
||
<td>volt</td>
|
||
<td>volt</td>
|
||
<td>volt</td>
|
||
<td>volt</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col">group_volume</td>
|
||
<td></td>
|
||
<td>cubic_foot<br/>
|
||
gallon<br/>
|
||
litre</td>
|
||
<td>gallon</td>
|
||
<td>litre</td>
|
||
<td>litre</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="first_col">group_NONE</td>
|
||
<td>NONE</td>
|
||
<td>NONE</td>
|
||
<td>NONE</td>
|
||
<td>NONE</td>
|
||
<td>NONE</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
|
||
<h1 id="station_data">Appendix: Station Data</h1>
|
||
|
||
<p>The following tables show which data are provided by the station
|
||
hardware and which are calculated by <span class='code'>weewx</span>.
|
||
</p>
|
||
|
||
<p class='station_data_key'>
|
||
<b>H</b> indicates data provided by <b>H</b>ardware<br/>
|
||
<b>D</b> indicates data calculated by the <b>D</b>river<br/>
|
||
<b>S</b> indicates data calculated by the StdWXCalculate <b>S</b>ervice<br/>
|
||
</p>
|
||
|
||
<h2 id="acurite_station_data">AcuRite</h2>
|
||
<table class='station_data'>
|
||
<caption>AcuRite station data</caption>
|
||
<tbody class='code'>
|
||
<tr class="first_row">
|
||
<td style='width:200px'>Observation</td>
|
||
<td>Loop</td>
|
||
<td>Archive</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>barometer</td>
|
||
<td>S</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>pressure</td>
|
||
<td>H</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>altimeter</td>
|
||
<td>S</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>inTemp</td>
|
||
<td>H</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>outTemp</td>
|
||
<td>H</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>inHumidity</td>
|
||
<td></td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>outHumidity</td>
|
||
<td>H</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>windSpeed</td>
|
||
<td>H</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>windDir</td>
|
||
<td>H</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>rain</td>
|
||
<td>H</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>rainRate</td>
|
||
<td>S</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>dewpoint</td>
|
||
<td>S</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>windchill</td>
|
||
<td>S</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>heatindex</td>
|
||
<td>S</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>rxCheckPercent</td>
|
||
<td>H</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>outTempBatteryStatus</td>
|
||
<td>H</td>
|
||
<td></td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<p class='station_data_key'>
|
||
Each packet contains a subset of all possible readings. For example, one type of packet contains <span
|
||
class='code'>windSpeed</span>, <span class='code'>windDir</span> and <span class='code'>rain</span>. A
|
||
different type of packet contains <span class='code'>windSpeed</span>, <span class='code'>outTemp</span> and
|
||
<span class='code'>outHumidity</span>.
|
||
</p>
|
||
|
||
<h2 id="cc3000_station_data">CC3000</h2>
|
||
<table class='station_data'>
|
||
<caption>CC3000 station data</caption>
|
||
<tbody class='code'>
|
||
<tr class="first_row">
|
||
<td style='width:200px'>Observation</td>
|
||
<td>Loop</td>
|
||
<td>Archive</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>barometer</td>
|
||
<td>S</td>
|
||
<td>S</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>pressure</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>altimeter</td>
|
||
<td>S</td>
|
||
<td>S</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>inTemp</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>outTemp</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>inHumidity</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>outHumidity</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>windSpeed</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>windDir</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>rain</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>rainRate</td>
|
||
<td>S</td>
|
||
<td>S</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>dewpoint</td>
|
||
<td>S</td>
|
||
<td>S</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>windchill</td>
|
||
<td>S</td>
|
||
<td>S</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>heatindex</td>
|
||
<td>S</td>
|
||
<td>S</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>radiation<sup>1</sup></td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>UV<sup>1</sup></td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>consBatteryVoltage</td>
|
||
<td>H</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>bkupBatteryVoltage</td>
|
||
<td>H</td>
|
||
<td></td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<p class='station_data_key'>
|
||
<sup>1</sup> The <span class='code'>radiation</span> and
|
||
<span class='code'>UV</span>
|
||
data are available only with the optional solar radiation sensor.
|
||
</p>
|
||
|
||
<h2 id="fo_station_data">Fine Offset</h2>
|
||
<table class='station_data'>
|
||
<caption>Fine Offset station data</caption>
|
||
<tbody class='code'>
|
||
<tr class="first_row">
|
||
<td style='width:200px'>Observation</td>
|
||
<td>Loop</td>
|
||
<td>Archive</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>barometer</td>
|
||
<td>S</td>
|
||
<td>S</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>pressure</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>altimeter</td>
|
||
<td>S</td>
|
||
<td>S</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>inTemp</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>outTemp</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>inHumidity</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>outHumidity</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>windSpeed</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>windDir</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>windGust</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>windGustDir</td>
|
||
<td>D</td>
|
||
<td>D</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>rain</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>rainRate</td>
|
||
<td>S</td>
|
||
<td>S</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>dewpoint</td>
|
||
<td>H/S</td>
|
||
<td>S</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>windchill</td>
|
||
<td>H/S</td>
|
||
<td>S</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>heatindex</td>
|
||
<td>H/S</td>
|
||
<td>S</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>radiation<sup>1</sup></td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>rxCheckPercent</td>
|
||
<td>H</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>outTempBatteryStatus</td>
|
||
<td>H</td>
|
||
<td></td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<p class='station_data_key'>
|
||
<sup>1</sup> The <span class='code'>radiation</span> data are available
|
||
only from 30xx stations.
|
||
These stations include a luminosity sensor, from which the radiation is
|
||
approximated.
|
||
</p>
|
||
|
||
<h2 id="te923_station_data">TE923</h2>
|
||
<table class='station_data'>
|
||
<caption>TE923 station data</caption>
|
||
<tbody class='code'>
|
||
<tr class="first_row">
|
||
<td style='width:200px'>Observation</td>
|
||
<td>Loop</td>
|
||
<td>Archive</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>barometer</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>pressure</td>
|
||
<td>S</td>
|
||
<td>S</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>altimeter</td>
|
||
<td>S</td>
|
||
<td>S</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>inTemp</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>outTemp</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>inHumidity</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>outHumidity</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>windSpeed</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>windDir</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>windGust</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>windGustDir</td>
|
||
<td>D</td>
|
||
<td>D</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>rain</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>rainRate</td>
|
||
<td>S</td>
|
||
<td>S</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>dewpoint</td>
|
||
<td>S</td>
|
||
<td>S</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>windchill</td>
|
||
<td>H/S</td>
|
||
<td>H/S</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>heatindex</td>
|
||
<td>S</td>
|
||
<td>S</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>UV<sup>1</sup></td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>extraTemp1</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>extraTemp2</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>extraTemp3</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>extraTemp4</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>extraHumid1</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>extraHumid2</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>extraHumid3</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>extraHumid4</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>txBatteryStatus</td>
|
||
<td>H</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>windBatteryStatus</td>
|
||
<td>H</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>rainBatteryStatus</td>
|
||
<td>H</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>outTempBatteryStatus</td>
|
||
<td>H</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>extraBatteryStatus1</td>
|
||
<td>H</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>extraBatteryStatus2</td>
|
||
<td>H</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>extraBatteryStatus3</td>
|
||
<td>H</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>extraBatteryStatus4</td>
|
||
<td>H</td>
|
||
<td></td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<p class='station_data_key'>
|
||
Some stations support up to 5 remote temperature/humidity sensors.
|
||
</p>
|
||
<p class='station_data_key'>
|
||
<sup>1</sup> The <span class='code'>UV</span> data are available only
|
||
with the optional solar radiation sensor.
|
||
</p>
|
||
|
||
<h2 id="ultimeter_station_data">Ultimeter</h2>
|
||
<table class='station_data'>
|
||
<caption>Ultimeter station data</caption>
|
||
<tbody class='code'>
|
||
<tr class="first_row">
|
||
<td style='width:200px'>Observation</td>
|
||
<td>Loop</td>
|
||
<td>Archive</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>barometer<sup>2</sup></td>
|
||
<td>H</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>pressure<sup>2</sup></td>
|
||
<td>S</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>altimeter<sup>2</sup></td>
|
||
<td>S</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>inTemp<sup>2</sup></td>
|
||
<td>H</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>outTemp</td>
|
||
<td>H</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>inHumidity<sup>2</sup></td>
|
||
<td>H</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>outHumidity</td>
|
||
<td>H</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>windSpeed</td>
|
||
<td>H</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>windDir</td>
|
||
<td>H</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>rain<sup>1</sup></td>
|
||
<td>H</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>rainRate<sup>1</sup></td>
|
||
<td>S</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>dewpoint</td>
|
||
<td>S</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>windchill</td>
|
||
<td>S</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>heatindex</td>
|
||
<td>S</td>
|
||
<td></td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<p class='station_data_key'>
|
||
<sup>1</sup> The <span class='code'>rain</span> and
|
||
<span class='code'>rainRate</span> are
|
||
available only on stations with the optional rain sensor.
|
||
</p>
|
||
|
||
<p class='station_data_key'>
|
||
<sup>2</sup> Pressure, inside temperature, and inside humidity data are
|
||
not available on all types of Ultimeter stations.
|
||
</p>
|
||
|
||
<h2 id="vantage_station_data">Vantage</h2>
|
||
<table class='station_data'>
|
||
<caption>Vantage station data</caption>
|
||
<tbody class='code'>
|
||
<tr class="first_row">
|
||
<td style='width:200px'>Observation</td>
|
||
<td>Loop</td>
|
||
<td>Archive</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>barometer</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>pressure</td>
|
||
<td>S</td>
|
||
<td>S</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>altimeter</td>
|
||
<td>S</td>
|
||
<td>S</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>inTemp</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>outTemp</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>inHumidity</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>outHumidity</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>windSpeed</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>windDir</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>windGust</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>windGustDir</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>rain</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>rainRate</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>dewpoint</td>
|
||
<td>S</td>
|
||
<td>S</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>windchill</td>
|
||
<td>S</td>
|
||
<td>S</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>heatindex</td>
|
||
<td>S</td>
|
||
<td>S</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>radiation</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>UV</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>extraTemp1</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>extraTemp2</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>extraTemp3</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>extraTemp4</td>
|
||
<td>H</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>extraTemp5</td>
|
||
<td>H</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>extraTemp6</td>
|
||
<td>H</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>extraTemp7</td>
|
||
<td>H</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>soilTemp1</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>soilTemp2</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>soilTemp3</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>soilTemp4</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>leafTemp1</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>leafTemp2</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>leafTemp3</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>leafTemp4</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>extraHumid1</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>extraHumid2</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>extraHumid3</td>
|
||
<td>H</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>extraHumid4</td>
|
||
<td>H</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>extraHumid5</td>
|
||
<td>H</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>extraHumid6</td>
|
||
<td>H</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>extraHumid7</td>
|
||
<td>H</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>soilMoist1</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>soilMoist2</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>soilMoist3</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>soilMoist4</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>leafWet1</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>leafWet2</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>leafWet3</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>leafWet4</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>txBatteryStatus</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>consBatteryVoltage</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
|
||
<h2 id="wmr100_station_data">WMR100</h2>
|
||
<table class='station_data'>
|
||
<caption>WMR100 station data</caption>
|
||
<tbody class='code'>
|
||
<tr class="first_row">
|
||
<td style='width:200px'>Observation</td>
|
||
<td>Loop</td>
|
||
<td>Archive</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>barometer</td>
|
||
<td>S</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>pressure</td>
|
||
<td>H</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>altimeter</td>
|
||
<td>S</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>inTemp</td>
|
||
<td>H</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>outTemp</td>
|
||
<td>H</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>inHumidity</td>
|
||
<td>H</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>outHumidity</td>
|
||
<td>H</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>windSpeed</td>
|
||
<td>H</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>windDir</td>
|
||
<td>H</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>windGust</td>
|
||
<td>H</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>rain</td>
|
||
<td>H</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>rainRate</td>
|
||
<td>H</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>dewpoint</td>
|
||
<td>S</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>windchill</td>
|
||
<td>S</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>heatindex</td>
|
||
<td>S</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>extraTemp1</td>
|
||
<td>H</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>extraTemp2</td>
|
||
<td>H</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>extraTemp3</td>
|
||
<td>H</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>UV</td>
|
||
<td>H</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>inTempBatteryStatus</td>
|
||
<td>H</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>outTempBatteryStatus</td>
|
||
<td>H</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>rainBatteryStatus</td>
|
||
<td>H</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>windBatteryStatus</td>
|
||
<td>H</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>uvBatteryStatus</td>
|
||
<td>H</td>
|
||
<td></td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<p class='station_data_key'>
|
||
Each packet contains a subset of all possible readings. For example, a temperature packet contains <span
|
||
class='code'>extraTempN</span> and <span class='code'>batteryStatusN</span>, a rain packet contains <span
|
||
class='code'>totalRain</span> and <span class='code'>rainRate</span>.
|
||
</p>
|
||
|
||
<h2 id="wmr200_station_data">WMR200</h2>
|
||
<table class='station_data'>
|
||
<caption>WMR200 station data</caption>
|
||
<tbody class='code'>
|
||
<tr class="first_row">
|
||
<td style='width:200px'>Observation</td>
|
||
<td>Loop</td>
|
||
<td>Archive</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>barometer</td>
|
||
<td>S</td>
|
||
<td>S</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>pressure</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>altimeter</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>inTemp</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>outTemp</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>inHumidity</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>outHumidity</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>windSpeed</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>windDir</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>windGust</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>rain</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>rainRate</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>dewpoint</td>
|
||
<td>S</td>
|
||
<td>S</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>windchill</td>
|
||
<td>H/S</td>
|
||
<td>H/S</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>heatindex</td>
|
||
<td>H/S</td>
|
||
<td>H/S</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>extraTemp1</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>extraTemp2</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>extraTemp3</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>extraHumid1</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>extraHumid2</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>extraHumid3</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>UV</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>outTempBatteryStatus</td>
|
||
<td>H</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>rainBatteryStatus</td>
|
||
<td>H</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>windBatteryStatus</td>
|
||
<td>H</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>uvBatteryStatus</td>
|
||
<td>H</td>
|
||
<td></td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<p class='station_data_key'>
|
||
Each packet contains a subset of all possible readings. For example, a temperature packet contains <span
|
||
class='code'>extraTempN</span> and <span class='code'>batteryStatusN</span>, a rain packet contains <span
|
||
class='code'>totalRain</span> and <span class='code'>rainRate</span>.
|
||
</p>
|
||
|
||
<h2 id="wmr300_station_data">WMR300</h2>
|
||
<table class='station_data'>
|
||
<caption>WMR300 station data</caption>
|
||
<tbody class='code'>
|
||
<tr class="first_row">
|
||
<td style='width:200px'>Observation</td>
|
||
<td>Loop</td>
|
||
<td>Archive</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>barometer</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>pressure</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>altimeter</td>
|
||
<td>S</td>
|
||
<td>S</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>inTemp</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>outTemp</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>inHumidity</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>outHumidity</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>windSpeed</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>windDir</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>windGust</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>rain</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>rainRate</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>dewpoint</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>windchill</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>heatindex</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>extraTemp1</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>extraTemp2</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>extraTemp3</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>extraHumid1</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>extraHumid2</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>extraHumid3</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<p class='station_data_key'>
|
||
Each packet contains a subset of all possible readings.
|
||
</p>
|
||
|
||
<h2 id="wmr9x8_station_data">WMR9x8</h2>
|
||
<table class='station_data'>
|
||
<caption>WMR9x8 station data</caption>
|
||
<tbody class='code'>
|
||
<tr class="first_row">
|
||
<td style='width:200px'>Observation</td>
|
||
<td>Loop</td>
|
||
<td>Archive</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>barometer</td>
|
||
<td>H</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>pressure</td>
|
||
<td>H</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>altimeter</td>
|
||
<td>S</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>inTemp</td>
|
||
<td>H</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>outTemp</td>
|
||
<td>H</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>inHumidity</td>
|
||
<td>H</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>outHumidity</td>
|
||
<td>H</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>windSpeed</td>
|
||
<td>H</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>windDir</td>
|
||
<td>H</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>windGust</td>
|
||
<td>H</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>windGustDir</td>
|
||
<td>H</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>rain</td>
|
||
<td>H</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>rainRate</td>
|
||
<td>H</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>dewpoint</td>
|
||
<td>S</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>windchill</td>
|
||
<td>H</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>heatindex</td>
|
||
<td>S</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>extraTemp1</td>
|
||
<td>H</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>extraTemp2</td>
|
||
<td>H</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>extraTemp3</td>
|
||
<td>H</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>extraHumid1</td>
|
||
<td>H</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>extraHumid2</td>
|
||
<td>H</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>extraHumid3</td>
|
||
<td>H</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>UV</td>
|
||
<td>H</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>inTempBatteryStatus</td>
|
||
<td>H</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>outTempBatteryStatus</td>
|
||
<td>H</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>rainBatteryStatus</td>
|
||
<td>H</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>windBatteryStatus</td>
|
||
<td>H</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>batteryStatusTH1</td>
|
||
<td>H</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>batteryStatusTH2</td>
|
||
<td>H</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>batteryStatusTH3</td>
|
||
<td>H</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>batteryStatusT1</td>
|
||
<td>H</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>batteryStatusT2</td>
|
||
<td>H</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>batteryStatusT3</td>
|
||
<td>H</td>
|
||
<td></td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<p class='station_data_key'>
|
||
Each packet contains a subset of all possible readings. For example, a temperature packet contains <span
|
||
class='code'>extraTempN</span> and <span class='code'>batteryStatusN</span>, a rain packet contains <span
|
||
class='code'>totalRain</span> and <span class='code'>rainRate</span>.
|
||
</p>
|
||
|
||
<h2 id="ws1_station_data">WS1</h2>
|
||
<table class='station_data'>
|
||
<caption>WS1 station data</caption>
|
||
<tbody class='code'>
|
||
<tr class="first_row">
|
||
<td style='width:200px'>Observation</td>
|
||
<td>Loop</td>
|
||
<td>Archive</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>barometer</td>
|
||
<td>S</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>pressure</td>
|
||
<td>H</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>altimeter</td>
|
||
<td>S</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>inTemp</td>
|
||
<td>H</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>outTemp</td>
|
||
<td>H</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>inHumidity</td>
|
||
<td>H</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>outHumidity</td>
|
||
<td>H</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>windSpeed</td>
|
||
<td>H</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>windDir</td>
|
||
<td>H</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>rain</td>
|
||
<td>H</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>rainRate</td>
|
||
<td>S</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>dewpoint</td>
|
||
<td>S</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>windchill</td>
|
||
<td>S</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>heatindex</td>
|
||
<td>S</td>
|
||
<td></td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
|
||
<h2 id="ws23xx_station_data">WS23xx</h2>
|
||
<table class='station_data'>
|
||
<caption>WS23xx station data</caption>
|
||
<tbody class='code'>
|
||
<tr class="first_row">
|
||
<td style='width:200px'>Observation</td>
|
||
<td>Loop</td>
|
||
<td>Archive</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>barometer</td>
|
||
<td>S</td>
|
||
<td>S</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>pressure</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>altimeter</td>
|
||
<td>S</td>
|
||
<td>S</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>inTemp</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>outTemp</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>inHumidity</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>outHumidity</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>windSpeed</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>windDir</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>windGust</td>
|
||
<td>D</td>
|
||
<td>D</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>windGustDir</td>
|
||
<td>D</td>
|
||
<td>D</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>rain</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>rainRate</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>dewpoint</td>
|
||
<td>H/S</td>
|
||
<td>H/S</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>windchill</td>
|
||
<td>H/S</td>
|
||
<td>H/S</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>heatindex</td>
|
||
<td>S</td>
|
||
<td>S</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
|
||
<h2 id="ws28xx_station_data">WS28xx</h2>
|
||
<table class='station_data'>
|
||
<caption>WS28xx station data</caption>
|
||
<tbody class='code'>
|
||
<tr class="first_row">
|
||
<td style='width:200px'>Observation</td>
|
||
<td>Loop</td>
|
||
<td>Archive</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>barometer</td>
|
||
<td>S</td>
|
||
<td>S</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>pressure</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>altimeter</td>
|
||
<td>S</td>
|
||
<td>S</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>inTemp</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>outTemp</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>inHumidity</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>outHumidity</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>windSpeed</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>windDir</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>windGust</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>windGustDir</td>
|
||
<td>D</td>
|
||
<td>D</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>rain</td>
|
||
<td>H</td>
|
||
<td>H</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>rainRate</td>
|
||
<td>H</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>dewpoint</td>
|
||
<td>S</td>
|
||
<td>S</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>windchill</td>
|
||
<td>H/S</td>
|
||
<td>H/S</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>heatindex</td>
|
||
<td>H/S</td>
|
||
<td>H/S</td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>rxCheckPercent</td>
|
||
<td>H</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>windBatteryStatus</td>
|
||
<td>H</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>rainBatteryStatus</td>
|
||
<td>H</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>outTempBatteryStatus</td>
|
||
<td>H</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td class='first_col'>inTempBatteryStatus</td>
|
||
<td>H</td>
|
||
<td></td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
|
||
</div>
|
||
|
||
<div class="footer">
|
||
<p class="copyright"> © <a href="copyright.htm">Copyright</a> Tom Keffer </p>
|
||
</div>
|
||
|
||
</div>
|
||
|
||
<!-- Our scripts load last so the content can load first -->
|
||
<script type="text/javascript" src="js/jquery-1.11.1.min.js"></script>
|
||
<script type="text/javascript" src="js/jquery-ui-1.10.4.custom.min.js"></script>
|
||
<script type="text/javascript" src="js/jquery.tocify-1.9.0.min.js"></script>
|
||
<script type="text/javascript" src="js/weewx.js"></script>
|
||
<script type="text/javascript" >
|
||
$(function () {
|
||
var level = get_default_level();
|
||
create_toc_control(level);
|
||
generate_toc(level);
|
||
});
|
||
</script>
|
||
|
||
</body>
|
||
</html>
|