I *may* have found the regression. It’s new in beta3 and it’s a full table scan of the archive table on every report cycle. beta3 adds a local-AQI path to bin/user/new_belchertown.py. The core helper: def _archive_latest_numeric(archive_manager, column_name): row = archive_manager.getSql( f"SELECT dateTime, {column_name} FROM archive " f"WHERE {column_name} IS NOT NULL " "ORDER BY dateTime DESC LIMIT 1" ) _archive_local_aqi_payload() calls it for pm2_5_aqi, and if that comes back empty, falls through to _archive_pm25_nowcast_payload(), which calls it again for pm2_5. Neither function exists in 2.0 — all of this is new. dateTime is the archive table’s INTEGER PRIMARY KEY, so SQLite walks backwards from the newest row. If the column has recent data it stops on the first row and costs nothing. If the column exists in the schema but is empty, SQLite has to read every row in the table to prove there’s no non-NULL value anywhere. That’s a full scan, disk-bound, holding a SQLite read lock for its entire duration — which is what blocks the archive writer and produces “database is locked”. It’s gated on aqi_enabled, which defaults to 0. Your log shows “Xweather AQI fallback cached to forecast.json”, so you have it on. I measured this on my own system — WeeWX 5.4.0, Pi 5, 785,666 archive records (~7.5 years), NVMe. Same query shape, comparing a populated column against an empty one: populated column (pm2_5): 0.001 s empty column (hail), warm: 0.219 s empty column (hail), cold: 1.120 s The cold number is after dropping caches. User CPU time is identical between the warm and cold runs, so the extra second is purely waiting on disk. Scaling to 13 years is roughly 1.75x my row count, so ~2 s per query cold, ~4 s for the pair. On slower storage — an ordinary SD card, where random page reads are an order of magnitude worse than NVMe — that could easily be 15-30 s per query. Two queries would confirm it on your database: .timer on SELECT dateTime, pm2_5_aqi FROM archive WHERE pm2_5_aqi IS NOT NULL ORDER BY dateTime DESC LIMIT 1; SELECT dateTime, pm2_5 FROM archive WHERE pm2_5 IS NOT NULL ORDER BY dateTime DESC LIMIT 1; A parse error means the column isn’t in your schema and that one is harmless. A fast result means the column has recent data. A slow result is the bug. BTW, storing pm2_5_aqi in the database is a guaranteed way to get the wrong answer for AQI. AQI is defined as a formula to be applied to the average pm2.5 for any given time period. It is NOT defined as the average of AQI calculations over said time period. I had a recent discussion with a user of one of my air quality sensor extensions. By adding AQI to the db, which he did, he was disabling the XType which comes with the weewx-purple, weewx-airlink and weewx-airgradient extensions that would properly calculate the AQI. And it saved virtually no time in getting the wrong answer. All of the time is the database access and it's doing the same accesses either way--one is getting AQI, the other pm2.5. On Aug 4, 2026, at 8:10 AM, John Kline <[email protected]> wrote: -- You received this message because you are subscribed to the Google Groups "weewx-user" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To view this discussion visit https://groups.google.com/d/msgid/weewx-user/7F373317-AC5E-471F-B6D9-1949B69F8031%40johnkline.com. |
- Re: [weewx-user] catching the 'why' of engine.... Greg Troxel
- Re: [weewx-user] catching the 'why' of engine.... 'John Kline' via weewx-user
- Re: [weewx-user] catching the 'why' of engine.... matthew wall
- Re: [weewx-user] catching the 'why' of engine.... 'John Kline' via weewx-user
- Re: [weewx-user] catching the 'why' of engine.... [email protected]
- Re: [weewx-user] catching the 'why' of engine.... 'John Kline' via weewx-user
- Re: [weewx-user] catching the 'why' of engine.... 'John Kline' via weewx-user
- Re: [weewx-user] catching the 'why' of engine.... [email protected]
- Re: [weewx-user] catching the 'why' of engine.... 'John Kline' via weewx-user
- Re: [weewx-user] catching the 'why' of engine.... 'John Kline' via weewx-user
- Re: [weewx-user] catching the 'why' of engine.... 'John Kline' via weewx-user
- Re: [weewx-user] catching the 'why' of engine.... 'John Kline' via weewx-user
- Re: [weewx-user] catching the 'why' of engine.... [email protected]
- Re: [weewx-user] catching the 'why' of engine.... 'John Kline' via weewx-user
- Re: [weewx-user] catching the 'why' of engine.... Tom Keffer
- Re: [weewx-user] catching the 'why' of engine.... 'John Kline' via weewx-user
- Re: [weewx-user] catching the 'why' of engine.... Tom Keffer
- Re: [weewx-user] catching the 'why' of engine.... Vince Skahan
- Re: [weewx-user] catching the 'why' of engine.... 'John Kline' via weewx-user
- Re: [weewx-user] catching the 'why' of engine.... [email protected]
- Re: [weewx-user] catching the 'why' of engine.... 'John Kline' via weewx-user
