Files
weewx/docs/devnotes.htm
Bill Richter 93436a927c once again try to update my fork (#2)
* Got test suites working again.

* Updated TODO

* indicate specific firmware for cc3000

* clarify rainwise firmware

* Further refinement

- max and maxtime now updated
- reworked the progress function, now a method in the class

Have left __main__ code in that has been used for testing windSpeed
recalculation fix

* indicate when calibrations are ignored

* Now emits the barometer trend in LOOP packets as field 'trendIcon'

Vantage only.

* Updated TODO guide, reflecting this morning's phone call.

* Presses on, despite database error

* Simplified patching by moving metadata code to DaySummaryManager

* Got rid of _getVersion()

Can now get it from _read_metadata

* Remove interval weighting fix from weewx startup

Refer TODO.txt

* Update TODO.txt

* added write timeout to ultimeter driver

* better logging when cc3000 loses contact with sensors

* document some of the channel, sensor, and logger specifics for the wmr100/wmr200 hardware

* Removed the p word, patch.py is now database.py, rejigged wee_database as per skype and followup emails

- progress function for fixes included as a method in base class that
can be overridden
- much changing of logging to give consistent results/output
- believe I retained Tom's recent changes to patch.py (commit 4acf752)

* Picks daily summary weights on the basis of database version

* Rewrote the backfill routine (again)

* wee_database now uses new version of backfill_day_summary

* Fixed problem that prevented cold startup

* Revised to reflect latest wee_database incantation

* Modified weighting fix

Should not mess with lessUpdate
Delete lastWeightPatch after successful patch

* Check to make sure the daily summaries have not been partially updated.

* Revised to reflect latest wee_database incantation

* Revised wee_database and interval weighting paras, added windSpeed recalc para

* Removed vacuum

* Updated what has been done and committed

* Better diagnostics with partial update of the daily summaries.

* MySQL now uses transaction isolation level READ COMMITTED

* Add .config (#204)

* Changed semantics of "$last_xxx" tags.

* Template test updates including fixing issue #201 (#205)

* Add .config

* Standardise test skin for index.html.tml to remove "%x %X" locale dependent formatting. Note: Used 24 hour time as AM/PM can also be locale dependent.

Also include fixes for line formatting in some other test files and expected results.

* sysctlbyname is not available on every platform, so catch AttributeError too, otherwise cheetah fails with a name error

* Got rid of tabs

* update usb mode info for acurite models

* Removed intervalgenRoundTS and archiveDaysAgoSpan.

* Simplified tags. Got template test working again.

* Somehow, style "indent" got lost

* Documented new "$ago" tags.

* Documented $ago options, as well as .start and .end

* Update changes doc

* Stupid typo

* use markdown instead of html for README

* indenting seems to confuse markdown's handling of urls

* Left over $last_day in $spans example (#206)

* Add .config

* Standardise test skin for index.html.tml to remove "%x %X" locale dependent formatting. Note: Used 24 hour time as AM/PM can also be locale dependent.

Also include fixes for line formatting in some other test files and expected results.

* Left over $last_day in $spans example.

* a user-specified sensor_map will update, not replace, the default sensor_map

* Updated the upgrade guide.

* ensure that weewx-multi works on deb and rpm as well as setup.py

* document the sensor mapping changes

* Added comprehensive example to customizing guide.

* Updated TODO

* Got the weighting update to work on MySQL

* added crude caching of pressure in wmr300

* Fixed typo

* Fixed little errors. Consistently use "tag", instead of "dot code."

* no altimeter, just pressure and barometer

* Fixed little HTML problems.

* Reformatted, in anticipation of a refactoring of some sections.

* Fixed location of 'Version'

So it works with automatic replacement of 'Version'

* initial experiment with different fonts

* override jquery-ui hijacking of toc font family

* bring header highlighting to h2 to correlate with toc.  reduce post-header margins.

* fix some table header cruft.  prevent indent sections from overflowing right margin.  let the table cells breath.

* fix broken tty formatting

* Checkpoint

Work in progress.

* Refined examples of creating new units and groups

* Polishing. Or, maybe fiddling?

* minor css fixes.  rearrange troubleshooting sections about pressure.

* minor cleanup to readme

* Fixed test suites

Add MySQL back to template tests.

* Reworked the iteration examples.

* Corrected and clarified the units used in the "electricity" example.

* remove write_timeout since naming is inconsistent between pyserial versions and there is no backward compatibility

* remove write_timeout from ultimeter

* Minor changes to users guide

* increase body size to 100%.  background for code.  weeWX in titles.  true bold for monospace.  prep for direct font comparisons.

* Clarified the role of encoding

* update utilities guide with suggested wee_database descriptions and args

* more compaction

* increase margins on html examples.  use droid serif for html examples.

* Clarified a few things

* decode weewx into weeWX

* include transaction limit defaults

* eliminate transaction-limit

* weeWX fixes in install pages.  more fixes to utilities.

* missed a few code spans

* fix version label alignment

* use only major.minor for docs

* Fix error where import fields that are None can cause Source.mapRawData() to crash in some cases

* Updated TODO and NEW_FEATURES

* There will be no daykeys if the daily summaries have been dropped.

* Restructure usage string, hard code transaction days

* dry-run goes with fix-strings, not check-strings

* Log daily summary version

* No need to check for weewx.debug

* include examples in manifest

* added examples and extensions to data_files

* do not install sample extensions

* Can now specify date field separator for Cumulus imports, weewx -> weeWX

* Clarified option strings

* Rudimentary test of selective daily summary rebuild

* No longer allows selective rebuild of the daily summaries

if the summaries are not complete

* Hardwired UTF-8 encoding, but with a warning comment.

* Hardwired UTF-8 encoding, but with a warning comment.

* Documented Cumulus import separator config option

* Added comments about Tools.

* Changed to execute in user environment

* Ported to PyMySQL as an alternative to python-mysqldb

See https://github.com/PyMySQL/PyMySQL for a description of PyMySQL

* Recognize additional MySQL "Can't connect" error

* Fixed error in test suites

Subsequent tests depended on ordering of a dictionary.

* pymysql seems to have problems connecting via file socket

unless it is told explicitly about it.

* Workaround for pypy compiler

* Defaults now support MySQLdb over pymysql

* Fixed bug in record augmentation.

The augmentation was happening without giving StdConvert a chance to do
its thing.

* More clear msg when encountering an ImportError

* Clarified the relationship between archive period and report_timing option, aded note regarding primacy of the report cycle

* Reverted back to MySQLdb only version.

* Changed config option names but never changed the code!

* One transaction for updating daily high/lows and archive record

Formerly, these were done in two transactions.

* v3.7.0a2

* Adjustable value for how long to wait after a bad uploader login.

Option retry_login. Fixes issue #212.

* Fixed Cumulus import rain field issue

wee_import will try to use field 26(AA) - midnight reset daily rainfall
but if not available due it will revert to field 9(J) or 11(L)

* Switched back to __str__ when extracting string out of template.

.respond() doesn't seem to encode Unicode characters properly

* Fix errors in wee_import WU step-by-step, remove Cumulus version caveat on rain

* Now uses dedicated test users 'weewx1' and 'weewx2'

* Formal check of the various MySQLdb exceptions.

* Added sqlite3 exceptions.

* Reworked check_strings() output (#213)

Reworked check_strings() screen and syslog output:
- now gives progress ala --rebuild-daily
- syslog is silent for --check-strings and --fix-strings with --dry-run
- left 'Preparing' (rather than 'Starting') but added 'this may take a
while' as there is a significant delay in dbmanager.genBatchRows()
initialising at line 619 (well there was for 400k records)

* reduce debug log spewage in wmr300 driver

* Finished formal test of errors

* First cut at V3.7 exception hierarchy

* Ported the weedb sqlite driver to the new exception hierarchy.

* Ported MySQLdb to the new database exception hierarchy.

* windSpeed fix now gracefully handles no windSpeed summary table, tweaked --update output/logging

* Now picks up absence of windSpeed daily summary

* The weedb Connection object can now be used in a "with" clause.

* The weedb Cursor object can now be used in a "with" clause.

* V3.7.0a3

* more code removal

* code formatting only

* use apt instructions for debian installs

* Reworked --wee-database section of Utilities Guide to reflect current wee-database operation

- revised usage
- reword --rebuild-daily
- reword --check
- reword --update

* More details on upgrading

* Moved start time to just before applying the patch

* Accumulator is now initialized with override values from weewx.conf

* Added sentences about wee_import/interval and weight patching multiple dbs

* remove extensions from rpm and deb packages

* v3.7.0b1

* Cleaned up some HTML warnings.

* must do a try loop at the read level so we can skip the no data 'errors' and return empty buffer so that a subsequent write will get the station to talk again

* Slightly more robust mechanism for decoding last time a file was FTP'd.

* adjust wording of weighting description

* added examples

* simplify

* fixed typo

* fixed typo

* read /etc/default before bailing out

* make init script work properly with /etc/default/weewx

* make output consistent

* more simplification

* keep PEP happy

* avoid resource consumption from slow reports by extending the StdReport.max_wait.  provide log messages when it happens.

* new features have move to the roadmap

* no more todo items left

* do not emit default sensor_map to the config

* aborted attempt to get additional battery status

* bump to 3.7.0b2

* do recipe using wget instead of curl

* forgot the O option to wget

* do not warn when calibrations are ignored - the implementation resulted in too many log entries

* get rid of tabs

* added notes about wmr300 rain counter and logger

* added norwegian 'no data available' as 'Ingen data er tilgjengelige'

* simplify.  eliminate more passive voice and gerunds.

* avoid run-on

* provide better feedback for operational errors.  make manager logging more consistent.

* fix typo in wmr300 ConfEditor

* decode heatindex and windchill from wmr300 sensor outputs

* fixed bad extract_signed invocation

* fixed wmr* partial packets note

* added mysqldb install instructions to userguide

* minor html fixes

* added link to wee_extension

* clarify acurite sensor transmission periods.

* added battery status for all wmr100 remote t/h sensors

* added battery status for all wmr100 remote t sensors

* document changes to wmr100, wmr200, wmr9x8 drivers.  fix 'Calculatios' typo.

* fixed inverted wmr200 battery status

* rename fault_out to out_fault to match pattern of other faults

* make battery status labels consistent across all wmr drivers

* wmr300 driver moves from rc to 0.18

* bump to 3.7.0b3

* css fixes: neutralize the glaring yellow; brighten the note green to more closely match the tone of warning red; @media tweaks to match font changes.

* fix column title

* distinguish selection color from code color

* fixed shift bug in weewx-multi

* Fixed (I think) issue #219

* update logwatch script to properly handle revised generator log messages

refer commit
03c3e4ef57 (diff-3cefdd7265f340e9683b0a2d0417b70f)

* normalize the quick-start

* Merge branch 'development', remote branch 'origin'

* fix layout table width on installation pages

* v3.7.0b4

* use released_versions instead of previous_versions

* Merge branch 'development', remote branch 'origin'

* parameterize release rule.  make release rule idempotent.

* replace cheetahtemplate.org with pythonhosted.org

* wee_database --help output was slightly different to reality

* Removed BOM at beginning of customizing.htm

* wee_database --help output was slightly different to reality

* Reworded comment on whether to --update daily summaries.

* cater for change in manager log output

* remove misleading windGustDir info

* bump to 3.7.0

* Added date to change log

* escape the dollars in release target

* fixed log syntax

* adjust log level for wmr100 bad usb report

* emit rapidfire cache info only when debug >= 3

* enable post_interval overrides for WOW uploader

* Fixes issue #230, exception when using Rapidfire with metric units

* Added StdRESTbase back in.

It seems that some uploaders still depend on it.

* Fixed problem that prevented a MySQL port from being specified.

* Added antialias GIF to list of files to be installed.

* Make sure GIF files get uploaded

* distribute examples in a single directory

* distinguish docs/examples vs examples

* Fixed bug that prevented a port from being specified for MySQL installations.

* Removed redundant change log entry

* Add MySQL Error 2003 to exceptions (#234)

* Added PR #234 to change log

* Documented change in location of the examples

* update examples paths in remaining guides.  explicitly list all path changes for examples.

* By default, autocommit is now enabled for the MySQL driver. Fixes issue #237.

Included regression test.
2017-03-20 00:41:34 -07:00

448 lines
26 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>
<title>weewx: Developer's Notes</title>
<meta http-equiv="Content-Language" content="en-us"/>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<link rel="stylesheet" href="css/ui-lightness/jquery-ui-1.10.4.custom.min.css"/>
<link rel="stylesheet" href="css/jquery.tocify.css"/>
<link rel="stylesheet" href="css/weewx_docs.css"/>
<link rel="icon" href="images/favicon.png" type="image/png"/>
</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="hardware.htm">Hardware Guide</a><br/>
<a href="utilities.htm">Utilities Guide</a><br/>
<a href="upgrading.htm">Upgrade Guide</a><br/>
<a href="devnotes.htm">Notes for Developers</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.7
</span>
</div>
<div class="title">
Notes for Developers of the weeWX Weather System
</div>
</div>
<div id="technical_content" class="content">
<p>This guide is intended for developers contributing to the open source project weeWX.
</p>
<h1>Goals</h1>
<p>The primary design goals of weeWX are:</p>
<ul>
<li>Architectural simplicity. No semaphores, no named pipes, no
inter-process communications, no complex multi-threading to
manage.
</li>
<li>Extensibility. Make it easy for the user to add new features or to modify existing features.
</li>
<li>&quot;Fast enough&quot; In any design decision, architectural simplicity and elegance trump speed.
</li>
<li>One code base. A single code base should be used for all platforms, all weather stations, all reports,
and any combination of features. Ample configuration and customization options should be provided so the
user does not feel tempted to start hacking code. At worse, the user may have to subclass, which is much
easier to port to newer versions of the code base, than customizing the base code.
</li>
<li>Minimal dependencies. The code should rely on a minimal
number of external packages, so the user does not have to go
chase them down all over the Web before getting started.
</li>
<li>Simple data model. The implementation should use a very
simple data model that is likely to support many different
types of hardware.
</li>
<li>A &quot;pythonic&quot; code base. The code should be written
so others will find idioms that they recognize.
</li>
</ul>
<h1>Strategies</h1>
<p>To meet these goals, the following strategies were used: </p>
<ul>
<li>A &quot;micro-kernel&quot; design. The weeWX engine actually does very little.
Its primary job is to load and run <em> services</em> at runtime, making it easy for users to add or
subtract features.
</li>
<li>A largely stateless design style. For example, many of the processing routines read the data they need
directly from the database, rather than caching it and sharing with other routines. While this means the
same data may be read multiple times, it also means the only point of possible cache incoherence is
through the database, where transactions are easily controlled. This greatly reduces the chances of
corrupting the data, making it much easier to understand and modify the code base.
</li>
<li>Isolated data collection and archiving. The code for
collecting and archiving data run in a single thread that is
simple enough that it is unlikely to crash. The report
processing is where most mistakes are likely to happen, so
isolate that in a separate thread. If it crashes, it will not
affect the main data thread.
</li>
<li>A powerful configuration parser. The
<a href="http://www.voidspace.org.uk/python/configobj.html">ConfigObj</a> module, by Michael Foord and
Nicola
Larosa, was chosen to read the configuration file. This allows many options that might otherwise have to
go in the code to go instead in a configuration file.
</li>
<li>A powerful templating engine. The
<a href="http://pythonhosted.org/Cheetah/">Cheetah</a> module
was chosen for generating html and other types of files from
templates. Cheetah
allows <em>search list extensions</em> to be defined, making it easy to extend weeWX with new template
tags. Unfortunately, as of 2016, Cheetah has not been updated in many years (indeed, the Cheetah website
seems to be dead). Fortunately, Cheetah seems to be very robust, with only a few well-known bugs that
are easiy worked around, so we will likely continue to use it for the foreseeable future.
</li>
<li>Pure Python. The code base is 100% Python &mdash; no underlying C libraries need be built to install
weeWX. This also means no Makefiles are needed.
</li>
</ul>
<p>While weeWX is nowhere near as fast at generating images and HTML as its
predecessor, <span class="code">wview</span> (this is partially because weeWX uses
fancier fonts and a much more powerful templating engine), it is fast enough for all platforms but the
slowest. I run it regularly on a 500 MHz machine where generating the 9 images used in the &quot;Current
Conditions&quot; page takes just under 2 seconds (compared with 0.4 seconds for <span
class="code">wview</span>). </p>
<p>Unfortunately, the architectural goal of one code base is likely to be broken with the arrival of Python
V3.X. It has so many changes that are not backwards compatible with V2.X, that a separate code base will
most likely be needed. My intention is to stick with the V2.X versions until V3.X is so widespread it cannot
be ignored, then make a permanent switch. Given the slow adoption rate of V3.X this is unlikely to happen
anytime soon. In any case, I doubt the transition will affect the average weeWX
user. </p>
<p>All writes to the databases are protected by transactions. You can kill the program at any time (either
Control-C if run directly or &quot;<span class="code">/etc/init.d/weewx
stop</span>&quot; if run as a daemon) without fear of corrupting the databases. </p>
<p>The code makes ample use of exceptions to insure graceful recovery from problems such as network outages. It
also monitors socket and console timeouts, restarting whatever it was working on several times before giving
up. In the case of an unrecoverable console error (such as the console not responding at all), the program
waits 60 seconds then restarts the program from the top.</p>
<p>Any &quot;hard&quot; exceptions, that is those that do not involve network and console timeouts and are most
likely due to a logic error, are logged, reraised, and ultimately cause thread termination. If this happens
in the main thread (not likely due to its simplicity), then this causes program termination. If it happens
in the report processing thread (much more likely), then only the generation of reports will be
affected &mdash; the main thread will continue downloading data off the instrument and putting them in the
database. You can fix the problem at your leisure, without worrying about losing any data. </p>
<h1>Units</h1>
<p>In general, there are three different areas where the unit system makes a difference: </p>
<ol>
<li>On the weather station hardware. Different manufacturers use different unit systems for their hardware.
The Davis Vantage series use U.S. Customary units exclusively, Fine Offset and LaCrosse stations use
metric, while Oregon Scientific, Peet Bros, and Hideki stations use a mishmash of US and metric.
</li>
<li>In the database. Either US or Metric can be used.</li>
<li>In the presentation (i.e., html and image files).</li>
</ol>
<p>The general strategy is that measurements are converted by service <span class="code">StdConvert</span> as
they come off the weather station into a target unit system, then stored internally in the database in that
unit system. Then, as they come off the database to be used for a report, they are converted into a target
unit, specified by the skin. </p>
<h1>Value &quot;<span class="code">None</span>&quot;</h1>
<p>The Python special value <span class="code">None</span> is used throughout to signal a missing data point.
All functions must be written to expect it. </p>
<p>Device drivers should be written to emit <span class="code">None</span> if a data value is bad (perhaps
because of a failed checksum). If the hardware simply doesn't support it, then the driver should not emit a
value at all.</p>
<p>However, the time value must never be <span class="code">None</span>. This is because it is used as the
primary key in the SQL database. </p>
<h1>Time</h1>
<p>WeeWX stores all data in UTC (roughly, &quot;Greenwich&quot; or &quot;Zulu&quot;)
time. However, usually one is interested in weather events in local time and want image and HTML generation
to reflect that. Furthermore, most weather stations are configured in local time. This requires that many
data times be converted back and forth between UTC and local time. To avoid tripping up over time zones and
daylight savings time, weeWX generally uses Python routines to do this conversion.
Nowhere in the code base is there any explicit recognition of DST. Instead, its presence is implicit in the
conversions. At times, this can cause the code to be relatively inefficient. </p>
<p>For example, if one wanted to plot something every 3 hours in UTC time, it would be very simple: to get the
next plot point, just add 10,800 to the epoch time: </p>
<pre class="tty">next_ts = last_ts + 10800 </pre>
<p>But, if one wanted to plot something for every 3 hours <em>in local time</em> (that is, at 0000, 0300, 0600,
etc.), despite a possible DST change in the middle, then things get a bit more complicated. One could modify
the above to recognize whether a DST transition occurs sometime between <span class="code">last_ts</span>
and the next three hours and, if so, make the necessary adjustments. This is generally what <span
class="code">wview</span> does. WeeWX takes a different approach and
converts from UTC to local, does the arithmetic, then converts back. This is inefficient, but bulletproof
against changes in DST algorithms, etc: </p>
<pre class="tty">time_dt = datetime.datetime.fromtimestamp(last_ts)
delta = datetime.timedelta(seconds=10800)
next_dt = time_dt + delta
next_ts = int(time.mktime(next_dt.timetuple()))</pre>
<p>Other time conversion problems are handled in a similar manner. </p>
<h1>Internationalization</h1>
<p>Generally, weewx does not make much use of Unicode. This is because the Python 2.x libraries do not always
handle it correctly. In particular, the function <span class="code">time.strftime()</span> completely fails
when handed a Unicode string with a non-ASCII character. As this function is often used by extensions,
working around this bug is an unfair expectation on extension writers. So, we generally avoid Unicode.</p>
<p>Instead, weeWX mostly uses regular strings, with any non-ASCII characters encoded as UTF-8. </p>
<p>An exception to this general rule is the image generator, which holds labels internally in Unicode, because
that is the encoding expected by most fonts.</p>
<p>The document <i><a
href="https://www.joelonsoftware.com/2003/10/08/the-absolute-minimum-every-software-developer-absolutely-positively-must-know-about-unicode-and-character-sets-no-excuses/">The
Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character
Sets</a></i> by Joel Spolsky, is highly recommended if you are just starting to work with UTF-8 and Unicode.
</p>
<h1>Exceptions</h1>
<p>In general, your code should not simply swallow an exception. For example, this is bad form:</p>
<pre class="tty">
try:
os.rename(oldname, newname)
except:
pass</pre>
<p>While the odds are that if an exception happens it will be because the file <span class="code">oldname</span>
does not exist, that is not guaranteed. It could be because of a keyboard interrupt, or a corrupted file
system, or something else. Instead, you should test explicitly for any expected exception, and let the rest
go by:</p>
<pre class="tty">
try:
os.rename(oldname, newname)
except OSError:
pass</pre>
<p>WeeWX has a few specialized exception types, used to rationalized all the different types of exceptions that
could be thrown by the underlying libraries. In particular, low-level I/O code can raise a myriad of
exceptions, such as USB errors, serial errors, network connectivity errors, <i>etc.</i> All device drivers
should catch these exceptions and convert them into an exception of type <span
class="code">WeeWxIOError</span> or one of its subclasses.</p>
<h1>Code style</h1>
<p>Generally, we try to follow the <a href="https://www.python.org/dev/peps/pep-0008/">PEP 8 style guide</a>,
but there are <em>many</em> exceptions. In particular, many older weeWX function names use camelCase, but
PEP 8 calls for snake_case. Please use snake_case for new code.</p>
<p>Most modern code editors, such as Eclipse, or PyCharm, have the ability to automatically format code.
Resist the temptation and <em>don't use this feature!</em> Two reasons:</p>
<ul>
<li>Unless all developers use the same tool, using the same settings, we will just thrash back and
forth between slightly different versions.
</li>
<li>Automatic formatters play a useful role, but some of what they do are really trivial changes,
such as removing spaces in otherwise blank lines. Now if someone is trying to figure out what
real, syntactic changes you have made, s/he will have to wade through all those
extraneous "changed lines," trying to find the important stuff.
</li>
</ul>
<p>If you are working with a file where the formatting is so ragged that you really must do
a reformat, then do it as a separate commit. This allows the formatting changes to be clearly
distinguished from more functional changes.</p>
<p>When invoking functions or instantiating classes, use the fully qualified name. Don't do this:</p>
<pre class="tty" style="opacity: 0.5">from datetime import dt
now = dt()</pre>
<p>Instead, do this:</p>
<pre class="tty">import datetime
now = datetime.datetime()</pre>
<h1>Tools</h1>
<h2>Python</h2>
<p><a href="http://www.eclipse.org/">Eclipse</a>, with the
<a href="http://pydev.org/">PyDev Python extension</a>, is highly recommended.
It's free, easy to customize and extremely powerful. </p>
<p><a href="http://www.jetbrains.com/pycharm/">JetBrain's PyCharm</a> is also good,
but it costs money. Where it really shines is if you use a framework
such as Django, or Backbone, but weeWX does not use any of these, so there is no real need
for PyCharm's extra functionality when working with weeWX.</p>
<h2>HTML and Javascript</h2>
<p>For HTML, <a href="http://www.jetbrains.com/webstorm/?fromMenu">JetBrain's WebStorm</a>
used to be the undisputed master. However, in recent years, I've found
that Eclipse's <a href="https://eclipse.org/webtools/">"Web Development Tools"</a>
to be its equal, or even better, particularly when working with
long HTML documents like the Customizing Guide.</p>
<p>However, if you are working with Javascript, particularly if you're using a framework
like NodeJS or ExpressJS, there is no contest: WebStorm is the way to go.</p>
<h1>Glossary</h1>
<p>This is a glossary of terminology used throughout the code. </p>
<table style="width: 95%" class='indent'>
<caption>Terminology used in weeWX</caption>
<tr class="first_row">
<td>Name</td>
<td>Description</td>
</tr>
<tr>
<td class="text_highlight">archive interval</td>
<td>WeeWX does not store the raw data that comes off a weather station. Instead, it aggregates the data
over a length of time, the <em>archive interval</em>, and then stores that.
</td>
</tr>
<tr>
<td class="text_highlight">archive record</td>
<td>While <em>packets</em> are raw data that comes off the weather station, <em>records</em> are data
aggregated by time. For example, temperature may be the average temperature over an <em>archive
interval</em>. These are the data stored in the SQL database
</td>
</tr>
<tr>
<td class="text_highlight code">config_dict</td>
<td>All configuration information used by weeWX is stored in the <em>configuration file</em>, usually
with the name <span class="code">weewx.conf</span>. By convention, when this file is read into the
program, it is called <span class="code">config_dict</span>, an instance of the class <span
class="code">configobj.ConfigObj</span>.
</td>
</tr>
<tr>
<td class="text_highlight">datetime</td>
<td>An instance of the Python object <span class="code">datetime.datetime</span>. Variables of type
datetime usually have a suffix <span class="code">_dt</span>.
</td>
</tr>
<tr>
<td class="text_highlight">db_dict</td>
<td>A dictionary with all the data necessary to bind to a database. An example for SQLite would be <span
class="code">
{'driver':'db.sqlite',
'root':'/home/weewx',
'database_name':'archive/weewx.sdb'}</span>, an example for MySQL would be <span class="code">{
'driver':'db.mysql',
'host':'localhost',
'user':'weewx',
'password':'mypassword',
'database_name':'weewx'}</span>.
</td>
</tr>
<tr>
<td class="text_highlight">epoch time</td>
<td>Sometimes referred to as &quot;unix time,&quot; or &quot;unix epoch time.&quot; The number of
seconds since the epoch, which is 1 Jan 1970 00:00:00 UTC. Hence, it always represents UTC (well...
after adding a few leap seconds. But, close enough). This is the time used in the databases and
appears as type <span class="code">
dateTime</span> in the SQL schema, perhaps an unfortunate name because of the similarity to the completely
unrelated Python type <span class="code">datetime</span>. Very easy to manipulate, but it is a big
opaque number.
</td>
</tr>
<tr>
<td class="text_highlight">LOOP packet</td>
<td>The real-time data coming off the weather station. The terminology "LOOP" comes from the Davis
series. A LOOP packet can contain all observation types, or it may contain only some of them
("Partial packet").
</td>
</tr>
<tr>
<td class="text_highlight">observation&nbsp;type</td>
<td>A physical quantity measured by a weather station (<i>e.g.</i>, <span class="code">outTemp</span>)
or something derived from it (<i>e.g.</i>, <span class="code">dewpoint</span>).
</td>
</tr>
<tr>
<td class="text_highlight code">skin_dict</td>
<td>All configuration information used by a particular skin is stored in the <em>skin configuration
file</em>, usually with the name <span class="code">skin.conf</span>. By convention, when this file
is read into the program, it is called <span class="code">skin_dict</span>, an instance of the class
<span class="code">configobj.ConfigObj</span>.
</td>
</tr>
<tr>
<td class="text_highlight">SQL type</td>
<td>A type that appears in the SQL database. This usually looks something like <span class="code">outTemp</span>,
<span class="code">barometer</span>, <span class="code">extraTemp1</span>, and so on.
</td>
</tr>
<tr>
<td class="text_highlight">standard unit system</td>
<td>A complete set of units used together. Either <span class="code">US</span>, <span class="code">METRIC</span>,
or <span class="code">METRICWX</span>.
</td>
</tr>
<tr>
<td class="text_highlight">time stamp</td>
<td>A variable in unix epoch time. Always in UTC. Variables carrying a time stamp usually have a suffix
<span class="code">_ts</span>.
</td>
</tr>
<tr>
<td class="text_highlight">tuple-time</td>
<td>An instance of the Python object <span class="code">
<a href="http://docs.python.org/2/library/time.html#time.struct_time">
time.struct_time</a></span>. This is a 9-wise tuple that represent a time. It could be in either local
time or UTC, though usually the former. See module <span class="code">
<a href="http://docs.python.org/2/library/time.html">time</a></span> for more information. Variables
carrying tuple time usually have a suffix <span class="code">_tt</span>.
</td>
</tr>
<tr>
<td class="text_highlight">value tuple</td>
<td>A 3-way tuple. First element is a value, second element the unit type the value is in, the third the
unit group. An example would be <span class="code">(21.2,
&#39;degree_C&#39;, &#39;group_temperature&#39;)</span>.
</td>
</tr>
</table>
</div> <!--- end technical_content -->
<div class="footer">
<p class="copyright"> &copy; <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>
<script type="text/javascript">
function showtab(tab, id) {
document.getElementById(tab + '-deb').style.display = 'none';
document.getElementById(tab + '-rpm').style.display = 'none';
document.getElementById(tab + '-macos').style.display = 'none';
document.getElementById(tab + '-setup').style.display = 'none';
document.getElementById(tab + '-' + id).style.display = 'block';
document.getElementById(tab + '-tab-deb').className = 'tab';
document.getElementById(tab + '-tab-rpm').className = 'tab';
document.getElementById(tab + '-tab-macos').className = 'tab';
document.getElementById(tab + '-tab-setup').className = 'tab';
document.getElementById(tab + '-tab-' + id).className = 'tab selected';
}
</script>
</body>
</html>