Troubleshooting
weewx-loopdata manual · weewx-loopdata on GitHub · Report an issue
Symptoms below, roughly in the order they turn up. If you already have a log line in hand and want to know what it means, skip to What LoopData writes to the log — which is also the fastest way to find out where loop-data.txt is actually landing, and which observations your station reports.
No page at <weewx-url>/loopdata/
The sample report’s HTML is generated by the normal WeeWX report cycle, which typically runs every 5 minutes. Wait for a cycle to complete after installing and restarting.
The sample panel’s indicator isn’t LIVE
The sample skin diagnoses its own data feed:
| Indicator | Meaning |
|---|---|
OFFLINE | The fetch itself failed — the web server is unreachable. |
NO DATA (HTTP 404) — check loop_data_file | The web server answered, but not with the file. The classic cause: loop_data_dir points outside the web server’s tree (say /dev/shm) with nothing configured to serve it, or the skin’s loop_data_file Extras option doesn’t match where the file actually lands. Keeping the file outside the web root is a perfectly good arrangement — it just has to be served and named; see Where the loop-data file should live. |
BAD DATA — check loop_data_file | The web server answered with something, but not with this page’s data. Three causes: the body isn’t json at all — usually a catch-all web server rule serving an HTML page at that URL; the json has no entry for this report, meaning an older loopdata is running or this report does not declare its fields; or the entry is there but carries no current.dateTime.raw, so there is no packet timestamp to age — declare the field, and note the gauges themselves still draw meanwhile. |
| A growing age readout | The file is served but not being rewritten — check that weewxd is running and the log for loopdata errors; if you rsync, see below. The age is measured against the web server’s clock, not the browser’s, so a device with the wrong time is not the cause. |
A later successful poll rewrites the indicator to LIVE.
loop-data.txt stopped being written, and the log shows a traceback
If the traceback ends in a TypeError about an unexpected keyword argument 'texts', you are running a WeeWX earlier than 5.3 with a loopdata earlier than 6.10 and at least one almanac field among your declared fields. WeeWX 5.3 renamed the argument LoopData passes the almanac, and older versions reject it — the LoopData thread stops at the first loop packet, though weewxd itself keeps running, so a page just freezes at its last values. Upgrade to loopdata 6.10 or later, which passes whichever argument the running WeeWX takes; dropping the almanac fields from your declaration also clears it.
Values are missing from loop-data.txt, and the log blames DEFAULT_TIME_FORMAT
If part of the file is absent and the log carries an AttributeError about weewx.units having no attribute DEFAULT_TIME_FORMAT, you are running loopdata 7.4 on a WeeWX earlier than 5.3. Upgrade to loopdata 7.4.1 or later. WeeWX 5.3 gave a name to the format a time falls back on and 7.4 read it; the releases before it have the format but not the name.
What goes missing depends on how the fields were declared, and so does the log line. A report that declares its own fields loses its whole entry, and the log names the report: Could not render report <name>; its values are omitted. A station still on the deprecated [LoopData] [[Include]] fields line loses the flat keys at the top level of the file instead, and its log line names that line rather than a report: Could not render [LoopData] [[Include]] fields; its values are omitted. Either way it is every packet, and only where a field holding a time is declared – which is why some values can be there and others not.
The panel shows readouts but no needles, bands or windrose
Since 7.0 the panel reads its own report’s entry in loop-data.txt, which its skin.conf declares in full, so an old station-wide fields line can no longer starve it. If a panel is half-dead anyway — text readouts, but no needles, min–max bands or windrose — look at the LoopDataReport entry in the file: a [[[LoopData]]] [[[[fields]]]] section under the report’s stanza in weewx.conf replaces the skin’s group of the same name, so a group named there that lists fewer fields than the skin’s costs the panel whatever it left out.
One gauge has no needle, and the others are fine
The panel draws no needle for a value it doesn’t have, so that gauge’s .raw field isn’t in the report’s entry in loop-data.txt. What each gauge reads lists the fields gauge by gauge; look up the missing one and check the file for it.
Two things put it there. One is a group override under the report’s stanza in weewx.conf that dropped the field — the case above.
Otherwise the field is declared but had no value, and a field with no value is omitted from loop-data.txt entirely (see Missing data) — the same reason the wind compass loses its needle while windDir is null in a calm. If it never appears, your station isn’t reporting that observation in loop packets, which is a station or driver matter rather than a LoopData one; the obstypes.current line LoopData logs at startup says what it does report.
A field I declared never appears in loop-data.txt
In roughly descending order of likelihood:
- You looked at the top level of the file. Since 7.0 a declared field is under its report’s name; the top level carries only the report entries — and, on a station upgraded from before 7.0, the flat keys of the old
[[Include]]fields line. See Declaring fields. - The report is disabled. A report with
enable = falsedeclares nothing, so its entry is absent. This catches out theScriptDatareport in particular: LoopData ships it disabled, so declaring fields under it without also settingenable = truewrites nothing at all. The startup log lists every report LoopData is serving — if yours isn’t there, that is why. - The declaration is not being read.
[LoopData]in askin.confmust hold a[[fields]]section of named groups; a barefields =line there is refused with a warning (see below). The startup log names every declaring report and its field count. - The data is missing. A field with no value is omitted — a trend before enough packets have arrived, or an observation your station doesn’t report. This is by design; see Missing data (and
string()for forcing emission). To see what your station actually reports, look at theobstypes.currentline LoopData logs at startup — see What LoopData writes to the log. - The aggregate needs the database, and the observation isn’t in it. Aggregates implemented via xtypes (e.g. weewx-purple’s
pm2_5_aqi) are ignored for every period, today included; only current values work for such observations. See the field reference. - The entry was split at a comma. A formatting call or almanac tag containing a comma must be quoted in the declaration — in
skin.confor in weewx.conf — or ConfigObj splits it into two bogus fields. See the quoting note. - An incompatible unit override. A unit that doesn’t belong to the observation’s unit group (e.g.
day.outTemp.avg.beaufort) causes the field to be omitted. A unit registered by another extension is recognized only if that extension initializes before LoopData. - It is an
alltimespan property, and the station has not archived yet.alltime.start,alltime.end,alltime.lengthandalltime.dateTimeneed the archive’s earliest record. On a station where WeeWX and LoopData were installed together, the archive is empty when LoopData starts, so those four are omitted until the first archive record is written — one archive interval, five minutes by default — after which they appear on their own. Nothing to do but wait one cycle.alltimeaggregates such asalltime.outTemp.maxare not affected, nor is any other period. See Span properties. - A removed grammar. The experimental
windrun_<dir>types were removed in 6.0; fields naming them are ignored. See the migration mapping.
Also check the WeeWX log around startup: loopdata logs every field it does not recognize, naming the report that declared it, and lists the observations it is tracking — see What LoopData writes to the log.
Values stay English on a translated page
The page’s labels and the live values translate independently — labels follow the report’s lang at generation time, values follow the language of the report that declared them, on every packet (see Translations). So if trend.barometer.desc is stuck at Rising Slowly — or moon phases, compass ordinates or almanac names stay English — on an otherwise translated page, check the value side:
- The declaring report’s skin must carry a lang file with the needed strings. The sample report ships them for every language loopdata ships. A page still reading the old flat keys takes its values from
target_report, and pointing that at another extension’s report — say, weewx-celestial’sCelestialReport— leaves the barometer descriptions English in every language, because that skin’s dictionary has no barometer phrases. - The report’s stanza must set
lang(or inherit it from[StdReport] [[Defaults]]). - Restart weewxd — a report’s texts are read once at startup.
- Month names and the decimal point are a separate matter. Those come from the machine’s locale rather than from a lang file, and
lang = deis not a locale name — so a fully German page can still sayJuneand12.3, on the report’s own pages just as much as inloop-data.txt. See Month names and decimal points. Values rendered in the wrong language altogether, changing from one packet to the next, was a defect fixed in 7.4. - This needs loopdata 6.4 or later.
Aggregate values look slightly off
Check [[LoopFrequency]] seconds. It is the weight given to each live loop packet in the accumulators, and the only weight that comes from your configuration — everything seeded from the database at startup carries the archive’s own weights. A wrong value therefore skews time-weighted aggregates, and it does so in a particular pattern worth recognizing: an average is off only while the period still holds both seeded and live data, so it corrects itself when the period rolls over, whereas windrun and the windrose time and distance bins scale with the error and stay wrong. Minima and maxima are never affected. 2.0 is right for a Davis Vantage; if your driver polls on a schedule you set, use that interval. See [[LoopFrequency]].
My driver acts strangely with loopdata
LoopData is targeted at a particular kind of driver — see the driver note under Installation.
Rsync problems
See Syncing to a remote server — including why occasional timeout errors in the log are normal, how to make them disappear with ssh control master multiplexing, and how the time bounds keep a dead remote from stalling loop processing.
What LoopData writes to the log
LoopData logs under user.loopdata. Every message below is one it can write; the errors all mean something you can act on.
Errors — LoopData is refusing to do something you asked for
| Message | What it means |
|---|---|
No fields to write: no enabled report declares [LoopData] [[fields]] and there is no [LoopData] [[Include]] fields line. LoopData is exiting. | Nothing asked for anything. Every report’s skin.conf lacks a [[fields]] declaration (or the declaring reports are disabled) and the old fields line is absent. LoopData does not start. See Declaring fields. |
Could not find target_report: <name>. The [LoopData] [[Include]] fields line cannot be rendered and is ignored. | target_report names a report that isn’t in [StdReport]. Check the spelling and that the report is defined (it does not need enable = true). Any declaring reports are still served; the old fields line is not. |
Could not build target_report <name>. The [LoopData] [[Include]] fields line cannot be rendered and is ignored. | The report is defined but its configuration could not be assembled — its skin.conf or lang file has a syntax error; the exception on the same line says which. Any declaring reports are still served; the old fields line is not. |
Could not set up target_report <name> for the [LoopData] [[Include]] fields line, which is ignored. | The report exists but something in it broke the fields line’s setup — a time_delta that is not a number, say; the exception on the same line says what. Any declaring reports are still served. |
No fields to write: no enabled report declares [LoopData] [[fields]] and the [LoopData] [[Include]] fields line could not be set up (see above). LoopData is exiting. | The fields line is present but one of the two errors above dropped it, and nothing else declares. Fix the error above. LoopData does not start. |
Could not render <name>; its values are omitted. | A report’s fields could not be rendered for a packet — most often a skin asking for something this station cannot supply in the form asked for; the exception and a traceback follow. That report’s entry is dropped and every other report keeps being written, so the file stays live. Logged once, not on every packet. |
Could not build report <name>, skipping it. | The report’s configuration could not be assembled — most often a skin.conf or lang file with a syntax error; the exception follows on the same line. That report is not served; the others are. |
Could not set up report <name>, skipping it. | The report’s configuration was read but its declaration could not be prepared; the exception follows on the same line. That report is not served; the others are. |
Report <name> is named like a field on the [[Include]] fields line; the report overwrites the field in the output. | A report whose name equals a field string on the old fields line — its entry and that flat key would share a name. Rename one of them. |
Error in LoopData setup. LoopData is exiting. | Something else in [LoopData] could not be parsed; the exception follows on the same line. LoopData does not start — nothing is written. |
Ignoring malformed almanac field: <field> | An almanac field didn’t parse — usually an unquoted entry that ConfigObj split at a comma, or a non-numeric keyword. That one field is dropped; the rest still work. |
Ignoring malformed station field: <field> | Same, for a station field. |
Ignoring non-numeric windrose_bands: <spec> | A windrose_bands edge isn’t a number. The default bands are used. |
Ignoring windrose_bands (need ascending, non-negative edges): <spec> | The edges are out of order or negative. The default bands are used. |
LoopData does not recognize how this WeeWX formats values; times and numbers will render under the locale weewxd runs, not the locale of the report. | Written at startup. LoopData renders each report’s times and numbers under that report’s own locale, so that a month name and a decimal point match the report’s own pages; it does that by taking over one piece of WeeWX’s formatting, and this WeeWX’s does not look the way LoopData expects. Nothing is lost — every field is still written, and times and numbers simply follow whichever locale weewxd itself runs under, as they did before 7.4. Only a station whose reports set a lang that resolves to a different locale than weewxd’s own sees any difference. Please report it, naming your WeeWX version. |
rsync_data: Caught exception <class>: <error> | An rsync of loop-data.txt to the remote failed; the class and message say why. Occasional timeouts are normal and are covered, with what to do about them, under Syncing to a remote server. Constant failures mean the remote, the path or the ssh credentials — the local file is written either way. |
round requires a WeeWX with weeutil.weeutil.rounder | A field used round(n) on a WeeWX too old to support it. Drop the round(n), or upgrade WeeWX. |
LoopData thread is not running; loop packets are ignored from here on and the loop-data file will not update again. | The thread that writes the file died on an earlier packet, or never started — its traceback, or the Error in LoopData setup line, is above this one in the log and is the thing to fix. weewxd itself keeps running, so a page simply freezes at its last values. Logged once; restart weewxd after fixing the cause. |
Unable to shut down LoopData thread | Written while weewxd was stopping, or rebuilding its engine after a driver error: the writer thread did not finish within twenty seconds, usually because it was in the middle of an rsync to a remote that was not answering. The stop or restart goes ahead without it. The one consequence is that a LoopData temp file may be left in loop_data_dir; it is harmless and can be deleted. |
Warnings — something to fix, but LoopData carries on
| Message | What it means |
|---|---|
The [LoopData] [[Include]] fields line and [[Formatting]] target_report are deprecated ... FINISH THE MIGRATION ... | Written at startup while the old station-wide fields line is present. Nothing is broken and the line is honored as it always was — but it is the last thing standing between you and the 7.0 model, and it costs a little on every packet. Once every extension whose pages read the file is upgraded, finish the migration; see Finishing the migration, which gives the command line for each way of installing WeeWX. |
No report <name>; a relative loop_data_dir is relative to [StdReport] HTML_ROOT (<dir>). A page expecting the file beside itself will not find it there ... | The [[LoopDataReport]] section (or the report named by target_report) is missing, so a relative loop_data_dir has nothing to be relative to and the file lands at the top of the reports tree. Put the section back — the next upgrade would — using enable = false if you do not want the page; or set loop_data_dir explicitly. |
Report <name> has an unreadable enable (...); treating it as enabled. | Some report’s enable is not a boolean. LoopData carries on; WeeWX’s own report engine will complain about the same line every cycle. |
[[Formatting]] target_report = <name> is deprecated with the [[Include]] fields line, and with no fields line it does one thing only ... | The fields line is gone but a target_report other than LoopDataReport remains, and it is what a relative loop_data_dir is relative to. Set loop_data_dir to an absolute path before the release that removes target_report, or the file moves. |
[LoopData] windrose_bands is deprecated: it bands the rose of target_report (<name>) and no other ... | Written at startup while windrose_bands sits under [LoopData]. It still bands that one report’s rose, as it did before 7.0; every other report’s takes the defaults. Put it on that report’s stanza instead — finishing the migration does exactly that. |
Ignoring unrecognized field <field> (report <name>) | A declared field is in none of loopdata’s grammars — a typo, most often. That one field is dropped; the rest of the report’s fields still work. |
Ignoring [LoopData] fields in report <name>: declare fields as named groups in a [[fields]] section, not as a single fields = line. | The skin’s skin.conf wrote fields = directly under [LoopData]. The declaration is a [[fields]] sub-section of named groups; that report declares nothing until it is fixed. |
Ignoring [LoopData] [[fields]] [[[<group>]]] in report <name>: a group is a line of fields, not a section. | A group was written as a sub-section. Each group is one name = field, field, ... line. |
Ignoring skip_if_older_than = <n> (must be at least 1); using the default of 3. | [[RsyncSpec]] skip_if_older_than is zero, negative or blank. Below 1 it would ship every packet however late — the backlog the option exists to prevent. The default of 3 seconds is used; set a value of at least 1. The value is quoted as you wrote it, so a fractional setting shows as you typed it rather than as the whole number it converts to. |
Informational — usually normal, occasionally a clue
| Message | What it means |
|---|---|
StdArchive writes binding <a> but reports read <b>; the alltime span start is read from <b> at startup only. | Written at startup on the unusual station whose [StdArchive] data_binding differs from [StdReport] data_binding. LoopData cannot tell which archive an incoming record belongs to, so it does not use archive records to keep the alltime span start current; it uses the reading taken when the accumulators were built. The only effect is on a station with an empty archive at startup, where alltime’s span properties then wait for a restart. |
LoopData file is: <path> | Written at startup. The quickest way to confirm where loop-data.txt is actually landing — check this first when the page reports NO DATA (HTTP 404). |
<n> of the <m> [[Include]] fields are declared by report <name> (its target_report) and are rendered once, for both. | Written at startup on an upgraded station: the fields line lists what its target report’s skin now declares itself, so those are computed once and copied flat rather than rendered twice. Normal; the line goes in a later release. |
report <name>: <n> fields (<n> almanac, <n> station), trend window <n>s, windrose bands [...] | Written at startup, one line per declaring report (and one for the old fields line, if present): what each report asked for and the two settings of its own that reach the accumulators. |
trend accumulators : [...] / windrose bands <key>: ... | Written at startup: the accumulators the reports’ trend windows and band edges resolved to. More than one trend accumulator means a report whose time_delta differs from the others’; likewise for the bands. |
obstypes.current : [...], obstypes.day : [...], … | Written at startup, one line per period: exactly which observations LoopData is tracking. This is also the answer to “what can I declare?” — anything in obstypes.current is in your station’s loop packets. |
Cannot evaluate almanac field <field>: <error> | The field parsed but the almanac could not answer it — commonly a body or attribute the installed almanac doesn’t provide. See Almanac fields. |
Cannot evaluate station field <field>: <error> | As above, for $station attributes. |
Ignoring <field> for <period> time period as this observation has no day accumulator. | An aggregate was requested for an observation WeeWX doesn’t keep daily summaries for — see aggregates via xtypes. |
Cannot calculate windrun. / Cannot calculate beaufort. | A packet lacked the wind data needed for that derivation. Occasional lines are normal; constant ones mean your station isn’t reporting wind. |
skipping packet (<time>) with age: <seconds> | An rsync was skipped because the data was older than skip_if_older_than. Normal in moderation — see Syncing to a remote server. |
Ignoring future-dated archive record: <record> | An archive record timestamped in the future was skipped while seeding accumulators — usually a clock that has since been corrected. |
time_delta of <n> specified, LoopData will use max value of 259200. | A report’s trend window exceeds three days; LoopData capped it. See the trend window. |
Still stuck?
Open an issue at github.com/chaunceygardiner/weewx-loopdata/issues with your [LoopData] section, the report’s declaration (its skin.conf [LoopData] section, or the [[[LoopData]]] section under its stanza in weewx.conf) and the relevant WeeWX log lines — including the report <name>: <n> fields ... lines LoopData writes at startup, which say what it actually read.