Troubleshooting
weewx-celestial manual · weewx-celestial on GitHub · Report an issue
Find the symptom. Almost every problem here is wiring rather than astronomy, and the page’s badge names most of them itself — see Reading the page for what each badge state means. In any state but LIVE the page stands as the report drew it, or where the last packet left it — the countdown chips and rosters advance only with loop packets — so a page that is entirely still is telling you to read the badge.
There is no page at celestial/
The HTML is generated by the normal WeeWX report cycle, typically every five minutes. Wait one cycle after installing and restarting.
If it still isn’t there, check that the report is enabled ([StdReport] [[CelestialReport]] enable = true) and look in the weewxd log for a generation error from CelestialReport. A template failure is only ever logged — the report cycle carries on and weectl report run still exits reporting success — so the log is the place to look, not the console.
On WeeWX 5.2, upgrade to 8.1.2 or later. Versions 7.2 through 8.1.1 cannot generate this page at all on WeeWX 5.2: they read body names from the report’s [Almanac] section, which WeeWX only began providing in 5.3. The log shows Ignoring template index.html.tmpl above a traceback ending in KeyError: 'Texts' (with PyEphem installed) or cannot find 'texts' (without it). 8.1.2 falls back to English body names there and the page generates normally.
The badge says NO DATA (HTTP 404) — check loop_data_file
The page found your web server but not the loop-data file. This is the single most common problem, and it is a path mismatch between two extensions:
- The skin fetches
loop_data_file, a URL relative to this report’s HTML_ROOT. - weewx-loopdata writes to
[[FileSpec]] loop_data_dir, a path relative to its sample report’s HTML_ROOT (itstarget_reportwhere one is still set,LoopDataReportotherwise).
The installer derives the first from the second, so the likeliest reason you are reading this is that it could not: weewx-loopdata was installed after this extension, or the file lands outside your reports tree. Re-running the install reads your configuration as it now stands and names the value it makes:
weectl extension install weewx-celestial.zip -y
It will not rewrite a loop_data_file that is already there — yours may be answering a web-server alias it cannot see — so when it reports a disagreement, the change is yours to make. Set loop_data_file to wherever loopdata writes, and confirm the web server actually serves it:
curl -sI http://localhost/loopdata/loop-data.txt | head -1
A file on disk that no URL reaches is the classic failure — loopdata writing into /dev/shm with no alias is the usual version of it, and Where the loop-data file should live has the alias to pair with it.
If your pages live on a remote web server, loop-data.txt has to reach it at loop cadence, not archive cadence. weewx-loopdata can rsync it on every packet; see its manual. A stale file on the far end shows up here as a badge age that climbs and resets, never reaching LIVE.
The badge says OFFLINE, or BAD DATA
OFFLINE means the fetch itself failed — the browser could not reach the server at all. Check that the web server is up and, if the page is served over HTTPS, that the loop-data URL is too: a mixed-content block looks exactly like an outage.
BAD DATA means the file was served but could not be parsed as json. Look at it directly (head -c 300 loop-data.txt). A truncated or half-written file usually means something other than loopdata is writing there.
It also means a file that parsed but carries no CelestialReport entry — the browser console says no "CelestialReport" entry in loop_data_file. weewx-loopdata 7.0 writes each declaring report’s fields under the report’s name, and this page reads its own; a file without it is an older weewx-loopdata (the installer refuses to run beside one, but a downgrade gets past it), or this report disabled, or renamed without its declaration. Look at the file’s top-level keys (python3 -c "import json; print(list(json.load(open('loop-data.txt'))))").
And it means an entry that carries no current.dateTime.raw. The page times everything by the station’s own clock, which that field carries, so a record without it is ignored whole and the browser console says so. The skin’s declaration always includes it; only a clock group of your own in the report’s stanza could override it away.
The badge age keeps climbing
The page is fine; the feed stopped. In order: is weewxd running, is weewx-loopdata still configured and enabled, and is the file’s modification time advancing?
ls -l --time-style=full-iso /home/weewx/public_html/loopdata/loop-data.txt # your loop_data_dir
If the timestamp is advancing but the page’s age is not resetting, the browser is being served a cached copy — check for a caching proxy between you and the file.
The badge reads a few seconds and never LIVE
A number that stands rather than climbs — 8s ago, steady, while the page plainly updates — means the packets are arriving but each one reaches the web server that many seconds after the station wrote it. The badge says LIVE up to six seconds, and publishing loop-data.txt costs well under one, so any standing number at all means the publish path is in trouble: an rsync running on a schedule instead of on every packet, a transfer that cannot finish before the next packet, or a station and web server whose clocks disagree. Check the clocks first — the record is stamped by the station and read against the web server’s clock, so skew between them lands here whatever the transfer is doing.
The badge says CLICK-ME
Working as designed: the page stops polling after expiration_time hours so an unattended browser does not poll for ever. Click to resume, or raise expiration_time in weewx.conf — uncommenting it first if your stanza has it commented out, as a fresh install now writes it. Appending ?pageUpdate=<page_update_pwd> to the URL disables expiration for that view — the password is visible in the page source, so treat it as a convenience, not a secret.
The star field is frozen
The dome’s stars and constellation figures come from backdrops the station regenerates every report cycle; the open page refetches one a minute (see How it stays live). When those stop arriving the page keeps the last good sky, and from 8.3.1 it also stops nudging the marks over it — a frozen dome is honestly old, while live marks crossing a motionless star field draw a sky that never existed — and posts a line under the panel:
Star field frozen — this sky is from 14:05 (reason) · what to check
The reason is the last refetch’s outcome, and it says where to look:
| The line says | What it means | What to check |
|---|---|---|
no newer backdrop has arrived | The fetches are succeeding; the file they return is old | The station: is the report still running each archive interval? Are dome-svg*.txt mtimes moving? Is the fragment generator failing? (see below) |
dome-svg-3.txt returns HTTP 404 (or another status, and whichever fragment was asked for) | That fragment is not being served next to the page | Whether the files exist in HTML_ROOT, and whether whatever publishes your site (rsync, FTP) carries .txt as well as .html. The named file is the one that failed — a deploy that dropped only the numbered fragments leaves dome-svg.txt itself serving perfectly |
dome-svg-3.txt is not a sky fragment | Something answers, but it is not SVG | A web server returning an error page with status 200 |
dome-svg.txt is empty | The file is there and has nothing in it | If it names a numbered slot, the page is asking for a slot beyond the current archive interval — harmless, and it corrects itself on the next cycle. If it names dome-svg.txt itself, the station is writing no backdrop at all: check that weewx-skyfield is serving the report (the dome would show an install hint), and that a report cycle has run since the last restart. Before 8.3.2 a station with a non-default group_interval emptied every fragment — upgrade if you are on anything earlier |
no response for dome-svg-3.txt | The request failed, or hung until it timed out | The network between browser and server; a page left open through a server restart |
dome-svg.txt is stamped ahead of the station's clock | The station answered, and the sky it sent depicts a time the station’s own loop packets have not reached | The clock that stamps your archive records against the one weewxd runs on — see below. Nothing is wrong with the report: it is generating backdrops perfectly, and the page is refusing them because it will not draw a sky from the future |
Two things this is not. The LIVE badge is a different instrument: it watches loop_data_file, which is usually a different URL in a different directory, so a healthy badge says nothing about the fragments (and a frozen star field says nothing about your loop data). And a dead loop feed does not raise this line at all — the backdrop’s age is measured against the station’s clock, which the loop packets carry, so that the viewer’s own clock can never freeze a healthy sky; when the feed stops, or never started, the badge is the fault to read, and the dome’s marks stop by themselves.
If it says no newer backdrop has arrived and the files are being written
On the station:
# Are the fragments being rewritten each report cycle? Run twice, a
# cycle apart -- the timestamps should move.
ls -l <HTML_ROOT>/celestial/dome-svg*.txt
# Did a fragment fail to render? The generator logs which one and
# why, and leaves the PREVIOUS file in place -- which looks exactly
# like a frozen sky.
sudo journalctl -u weewx | grep -iE 'celestial_page|dome|pass-chart'
If you set report_timing on this report, this is the line you will see. The Celestial skin does not support a report_timing that makes its reports run less often than the archive interval — see Report timing is not supported. The backdrops are written by the report cycle, so a report throttled to run hourly on a five-minute archive leaves the page holding a backdrop up to an hour old, which is past the staleness limit: the dome freezes and this line stands, permanently. Nothing is broken; the page simply cannot tell a deliberately slow report apart from a station that has stopped. Remove the report_timing line and the dome runs normally again. Nothing needs configuring, and the dome resumes stepping as soon as a backdrop lands.
If it says stamped ahead of the station's clock
Check your station’s clock — specifically, whether the clock that stamps your archive records agrees with the one weewxd is running on.
The page works out which backdrop it wants from the time your loop packets carry, and it refuses any backdrop depicting a time your station has not reached yet — that refusal is what stops it drawing a sky from the future. If a hardware console’s clock runs fast, its archive records are stamped ahead of the loop packets, so every backdrop looks like the future to the page and is refused. Ahead by more than one archive interval, none is ever accepted, and after three cycles the dome freezes.
This is a misconfigured station rather than a fault in the page, and it is worth fixing on its own account: every archive record you are storing carries the same wrong time. WeeWX checks a Vantage console’s clock periodically and logs the result:
grep "Clock error" /var/log/syslog | tail
A healthy station reads a second or two. Anything approaching a minute deserves attention; more than one archive interval will freeze the dome as described.
The line names this case as its own from 8.4. Earlier versions marked the fetch healthy before refusing the answer, so the panel read no newer backdrop has arrived — which sent readers looking for a report cycle that was running the whole time.
A panel shows an install hint instead of a chart
The almanac WeeWX has registered cannot serve that panel. The page degrades on purpose rather than failing:
| What you see | What it means |
|---|---|
| The Geocentric shows a hint | Neither weewx-skyfield nor PyEphem is registered — the built-in almanac serves none of the positions the Celestial page needs |
| The dome shows a hint | weewx-skyfield is not installed or not registered |
| The dome draws, but no satellites | No [Skyfield] [[Satellites]] are configured |
| No comets on the dial | No [Skyfield] [[Comets]] are configured |
| The Proxima Centauri row is empty | PyEphem is serving the page; its star catalog lacks Proxima |
| The dome says could not be drawn — see the weewxd log | Different from the hint above: weewx-skyfield is registered, and its drawing came back empty anyway. The log says why — that is the only place the reason exists |
The full table is under the almanac tiers. The page’s footer always names the almanac that actually computed it, which is the quickest way to confirm which tier you are on.
A panel says its fields are not declared
Four lines a panel can carry in place of, or above, what it draws. They are about configuration, not about the almanac, and each one names its own fix; the weewxd log carries the same fault once per report cycle, with the detail. A panel in this state first-paints correctly from the report and then never moves, which is the failure these lines exist to explain.
| The panel says | What happened | What to do |
|---|---|---|
This page’s report does not name the … panel in celestial_panels | celestial_panels names the panels a page embeds — normally in that skin’s own skin.conf, or in the report’s stanza where a station overrides it — and this one is not among them, so nothing declared its live fields | Add the panel to celestial_panels (in whichever of the two the report is reading; the weewxd log names it), re-run weectl extension install, restart weewxd |
This page’s report carries an invalid celestial_panels | The key names something that is not a panel (the four are countdown, geocentric, dome, pass), or it sits under [[Defaults]] or at [StdReport]’s top level, where WeeWX would merge it into every report | Fix or move the key — the log names it — then re-run the installer and restart weewxd |
| This page’s report’s field declaration is out of date | The panels are named, but the satellites/comets groups in weewx.conf are not what the installer would write now — a satellite edited into [Skyfield] by hand, or one re-added by a weewx-skyfield upgrade after --remove-satellite | Re-run weectl extension install (or the --add-satellite/--add-comet utility), restart weewxd |
The page’s fragment set is missing or invalid in [CelestialFragments] | The dome or pass call names a set the skin does not declare, or the skin declares sets but none on the dome-svg prefix and the call named none. Never answered with the default set, deliberately | Declare the set, or correct the set= name in the page — the log names it |
The bundled Celestial page can show the third of these: an 8.5 station whose [Skyfield] sets were edited by hand has a declaration the installer would now write differently. Re-running the install and restarting weewxd is the whole fix, and it is worth doing — the undeclared satellite or comet has no live layer until you do.
The first, second and fourth belong to a page in a skin of your own; the bundled page names all four panels itself and declares its own fragment set.
A countdown chip never appears
Three different causes, in the order worth checking:
- Its field is not in the feed. Check this report’s entry of
loop-data.txtfor the key (see the verification commands in Installation), and compare against the Fields reference — every chip’s field ships declared in the skin, so a missing key means loopdata has not read the declaration (restart weewxd) or cannot compute it (next). - The almanac cannot compute it. The meteor shower and supermoon chips come from weewx-skyfield; on PyEphem or the built-in almanac they are simply omitted, one log line per field at startup.
- The event is more than 30 days out. The equinox/solstice, perihelion/aphelion, supermoon, eclipse and comet-perihelion chips are windowed guests by design.
A satellite row says no usable orbital elements
weewx-skyfield could not fetch or parse that satellite’s elements, or the cached ones have expired. Check the weewxd log around startup for the CelesTrak fetch, confirm the NORAD number is right (search CelesTrak), and give it a restart — elements are fetched shortly after start and refreshed every few hours.
A satellite is configured but never has a pass
Check its inclination against your latitude. A satellite’s orbital inclination bounds the latitudes it can ever appear over; one that never crosses your sky will honestly report no passes for ever. The roster is not broken — it is telling you the truth.
Also worth knowing: most passes are not visible passes. The “next pass overhead” roster counts every pass; the Next Visible Pass panel only counts the ones where the satellite is sunlit against a dark enough sky.
A comet’s row and diamond are empty
The Minor Planet Center dropped that comet from its element file — faded comets are removed routinely. The page renders honest absence rather than a fabricated position. Remove it with --remove-comet if you don’t expect it back, or leave it: it will return if the MPC republishes elements.
theme = light and the page is still dark
Three things to check, in this order:
- Where the option sits.
themeis a report option, besidelang— not inside[[[Extras]]]. In[[[Extras]]]it is simply ignored. - Whether the report has regenerated. The plate is baked in at generation time (there is nothing in the browser to switch), so the change appears on the next report cycle. Reload after that; if the page still looks dark, reload once more — the stylesheet is version-tagged, but a proxy may hold the old page itself.
- Whether weewx-skyfield is installed. The light plate is the paper the sky dome and Next Visible Pass chart are drawn on, and those come from weewx-skyfield. Without it the page has no charts to match and stays dark whatever the option says — the same tier where the panels show an install hint.
Case does not matter (theme = Light is light), but a value that is not one of the three (theme = paper, theme = white) leaves the page dark rather than failing the report — a page that generates in the wrong plate beats a page that does not generate — and says so in the log:
WARNING user.celestial: The Celestial report has an unusable theme option;
rendering the dark plate. Valid values are dark, light and auto.
The page looks unstyled — the dial is solid black discs
A stylesheet did not reach the browser. The page loads two: celestial.css, which carries the panels, and celestial-page.css, which carries the page’s own surfaces — its background, header, section cards and footer. Solid black discs where the dial should be is the first one missing; panels that look right on a page that has lost its background and card borders is the second.
Both are deployed by WeeWX’s CopyGenerator, which re-copies them on the report’s first run after a restart, and the page version-tags their URLs so browsers refetch them. So: restart weewxd, then reload the page. If it persists, confirm both files exist in the report’s HTML_ROOT and are served (a 404 on either produces exactly its own half of this).
Every chart is drawn twice, one above the other
Since 9.6 each sky chart is generated twice — a drawing for a desk and a drawing for a phone, in the one fragment — and the stylesheet shows whichever fits the width the chart is rendered at. Seeing both means the stylesheet the browser is using does not know about the second one, so nothing is hidden. On the pass chart you will also see its dated head line twice, which is the quickest way to recognize it.
It is the same cause as the entry above and the same cure: restart weewxd so the report’s first run re-copies celestial.css, then reload the page. A browser is unlikely to be the culprit on the bundled page, because its asset URLs carry the release version (celestial.css?v=9.6) and a new version is a new URL.
If you embed these panels in a skin of your own, this is the symptom to expect after upgrading the extension and not re-copying the assets into your skin: copy_once faithfully re-copies whatever is in your skin directory, which is still the old stylesheet. Copy celestial.css and celestial.js out of skins/Celestial/ again, and version-tag their URLs — see Embedding the panels.
weewxd will not start after upgrading
Look for this in the log, and remove the entry it names:
[Engine] [[Services]]
data_services = ..., user.celestial.Celestial
That registration is a leftover from 2.x. 6.x tolerated it with a stub; 7.0 deleted the stub, so a stale entry now stops the engine. Removing it is the whole fix — this extension has run no service since 6.0.
Values never tick, and there are no motion trails
Rates need two loop packets. For the first refresh_rate seconds after a page load nothing moves, by design. If it never starts moving, the feed is delivering the same packet repeatedly — check that refresh_rate (commented out in a stanza a fresh install wrote, in which case the skin’s 2 seconds is in force) matches loopdata’s write cadence (2 seconds for the Vantage driver) rather than being much shorter than it.
The countdown chips and the satellite rosters are not this symptom: they advance on each loop packet — every refresh_rate seconds, not every second — by design. On a page of your own that passes countdown=False to config_script, this extension’s chips do not advance at all: that switch is for a countdown row your own script keeps current.
Times are in the wrong zone
The page shows the station’s timezone, detected at report time from the machine that generates the report, so every viewer sees station time. There is no option to change it.
If the times are wrong, that machine’s own zone is wrong, or the page could not learn it. It is read from the TZ environment variable weewxd runs under, then from /etc/localtime where that is a symlink into the zoneinfo tree, then from /etc/timezone — the same order the machine itself resolves a zone, so that a weewxd started with TZ set reports the zone it is actually keeping time in. When none of the three names a zone, or when the name is one this browser does not know, the page falls back to the viewer’s local zone and the javascript console says so.
A TZ holding a POSIX rule rather than a zone name (CST6CDT rather than America/Chicago) is the one case the page cannot follow: weewxd keeps time by it, but there is no zone name to send to the browser. Set TZ to a zoneinfo name if you set it at all.
Earlier releases had a time_zone option in the report’s [[[Extras]]]. It is gone. A line left over from then is ignored, and weewxd logs a warning naming it, on every report cycle, until you delete it; if it said browser, the page no longer follows the viewer’s zone.
The translation did not take
Four separate things can be meant by this:
- Nothing changed at all.
langtakes effect when the page is next generated, not on the next loop packet. Wait a report cycle. - Everything translated except the body names.
[Almanac]display names — the bodies, and the satellites and comets — need WeeWX 5.3 or later; 5.2 never hands that section to the almanac. The rest of the page translates normally and the bodies readMoon,Jupiter,Proxima. See Translations. - Labels translated, live values did not. Loop-data values follow this report’s language — weewx-loopdata 7.0 renders each report’s entry with that report’s own
[Almanac]— but it reads the report’s configuration at startup, so alangchanged while it runs takes effect at the next weewxd restart. See Translations. - My edits vanished after an upgrade.
weectl extension installoverwritesskins/Celestial/, including itslang/files. Put local overrides inweewx.confas[[[Texts]]]/[[[Almanac]]]entries under the report or[[Defaults]], where they survive and are merged over the shipped files.
Nothing here matches
Two commands worth having before asking for help — what the feed actually carries, and what the log said:
# the paths below are examples -- use your own loop_data_dir
python3 -c "import json; d=json.load(open('/home/weewx/public_html/loopdata/loop-data.txt'))['CelestialReport']; print(sorted(k for k in d if k.startswith('almanac')))"
grep -i -e celestial -e loopdata -e skyfield /var/log/syslog | tail -40
# or, where journald has replaced the syslog file:
journalctl -u weewx --no-pager | grep -i -e celestial -e loopdata -e skyfield | tail -40
That second command answers the version question too: from 8.3.1 the skin announces itself at the first report that renders the page after a restart —
INFO user.celestial_sky: Celestial version is 8.3.1.
— and it is the version of the skin that actually rendered the page, which is the one worth reporting. It is logged once, not every cycle, so look near the restart rather than at the tail of the log; it speaks again only if the version changes, which is how a later upgrade announces itself without a restart. Installing over a running weewxd never changes the code weewxd has already imported, so the line that follows an install is the one after your restart. (Before 8.3.1 this extension had no service and never named itself at all; weectl extension list is the fallback.)
Then open an issue with both, your WeeWX version, and the versions of weewx-celestial, weewx-loopdata and weewx-skyfield.