weewx-forecast 5.1 teaches the comparison plot generator to honor the shutdown flag WeeWX 5.5 hands to report generators, so stopping WeeWX no longer waits on a report in progress. It also fixes the compare report failing whenever there is no forecast data to plot, and two problems on the shutdown and error paths of forecast downloads. There are no weewx.conf or database changes, and reports look exactly the same. This is a drop-in upgrade from 5.0.1 — just reinstall and restart WeeWX.
What's fixed
Stopping WeeWX no longer has to wait for the compare report's plots. WeeWX 5.5 hands each report generator a flag that is set when weewxd is shutting down, and expects generators to quit as soon as they can. ForecastPlotGenerator ignored it, so a shutdown arriving mid-report waited for every comparison plot to be drawn first. It now checks the flag while scanning the forecast database and while collecting data, and passes it on to WeeWX's image generator, which checks it between plots — plotting is where the time goes. Earlier WeeWX releases have no such flag and are unaffected; the extension still runs on them unchanged.
The compare report failed when there was nothing to plot. If a forecast source had not been downloaded yet, was misspelled, or had no issue within the report's issued_since window, the generator handed WeeWX's image generator a zero or negative time span. Every plot then threw weeplot.ViolatedPrecondition: scaletime called with tmax <= tmin, once per report cycle, and no images were produced. The generator now notices that it has nothing to plot, logs generator abort: no forecast data to plot (check the source and issued_since settings), and stops.
WeeWX could not shut down during a forecast update under single_thread = True. weewxd stops by raising Terminate from its SIGTERM handler, inside whatever the main thread is running; the forecast update's exception handler swallowed it and logged it as a forecast failure, so the shutdown request went missing and weewxd kept running until something killed it. Terminate is now handed back. The threaded default (single_thread = False, what nearly everyone runs) was never affected — signals only reach the main thread.
A failed forecast download reported the wrong error. If fetching a forecast raised, the handler that was supposed to log it raised UnboundLocalError instead: it reports the database configuration, which is not looked up until after the forecast arrives. The real error was lost and the exception escaped the update. It is now logged as intended.
The comparison generator's scratch database moved out of /var/tmp. It now lives beside the station's own databases (SQLITE_ROOT — typically /home/weewx/archive/fpg.sdb). The file is deleted and recreated on every run, so two weewx instances on one machine used to fight over the single /var/tmp/fpg.sdb; each now has its own. There is nothing to configure. A MySQL-only station has no SQLITE_ROOT and gets a pid-stamped file in the system temp directory instead. A leftover /var/tmp/fpg.sdb from an earlier version is no longer used and can be deleted.
The comparison generator's tests checked nothing. They ran against an empty forecast database, so every one of them passed while the generator produced no plots at all — the report engine logs whatever a generator throws and carries on, so the failures never surfaced. The tests now build a forecast database with real data and assert which plots come out. That is how the no-plot failure above was found.
Requirements
Python 3
WeeWX 4 or 5
For tide forecasts, the xtide package (see the README for how to build xtide 2.16)