mirror of
https://github.com/weewx/weewx.git
synced 2026-04-18 16:46:56 -04:00
* 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 (commit4acf752) * 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 commit03c3e4ef57 (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.
448 lines
26 KiB
HTML
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>"Fast enough" 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 "pythonic" 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 "micro-kernel" 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 — 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 "Current
|
|
Conditions" 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 "<span class="code">/etc/init.d/weewx
|
|
stop</span>" 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 "hard" 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 — 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 "<span class="code">None</span>"</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, "Greenwich" or "Zulu")
|
|
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 "unix time," or "unix epoch time." 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 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,
|
|
'degree_C', 'group_temperature')</span>.
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
|
|
</div> <!--- end technical_content -->
|
|
|
|
|
|
<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>
|
|
|
|
<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>
|