diff --git a/CHANGELOG.md b/CHANGELOG.md index 1995ef3..6343126 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -79,6 +79,33 @@ each fix ships with the check, report or document that would have surfaced it. ### Fixed +- The toner forecast was reading the wrong end of the window. Zabbix applies a + query's `limit` to the whole answer rather than to each item, and combined + with an ascending sort that kept the OLDEST rows: a four-cartridge printer + polled every five minutes writes over 100k readings in 90 days, so a "90 day" + forecast was fitted to the first few days of the window and nothing since. + That is where "4 days left" beside a cartridge at 20% came from - the rate + was real, it just described a cartridge thrown away in May. Long windows now + read hourly trends, which is the table meant for this and is a tenth of the + rows; short ones read raw history, newest first, with a budget scaled per + item. +- The forecast now counts down from the level it displays. It showed the live + reading but computed days-left from the last stored one, so the two could + disagree by a whole cartridge. A live level far above the stored run is + treated as a swap that happened since the last reading rather than as a + collapse in the burn rate. +- A cartridge at or below 5% reads as empty rather than as a slow drain. At 1% + losing a tenth of a point a day the arithmetic said ten days; the printer is + out of toner, and it is the first thing that should be ordered. +- Days-left in the forecast is per cartridge again. It was rendered in a cell + spanning the printer's rows, which put the printer's soonest figure beside + every supply it had - a cartridge at 20% displaying "4 days" that belonged to + the black beside it, and a cartridge at 1% displaying weeks that belonged to + nothing on that row at all. +- Supplies typed as floats were dropped from the forecast on any printer that + also had an integer-typed one. The two live in different Zabbix history + tables and the fetch stopped at whichever answered first, so half a printer's + cartridges silently had no history at all. - A shop-floor PC that reported the machine number of a machine ShopDB already knew got a 500 from the collector, on every report, forever. The reported machine number was being written to the PC's own `assets.assetnumber`, which diff --git a/plugins/printers/api/asset_routes.py b/plugins/printers/api/asset_routes.py index c979609..2b9ba9f 100644 --- a/plugins/printers/api/asset_routes.py +++ b/plugins/printers/api/asset_routes.py @@ -1541,16 +1541,18 @@ def supplies_forecast(): if not supplies: continue itemids = [s['itemid'] for s in supplies if s.get('itemid')] - history = service.gethistory(itemids, days=days) + history = service.getlevelhistory(itemids, days=days) analysed = [] for supply in supplies: points = history.get(str(supply.get('itemid')), []) - detail = analyse(points) + # The live read is the level the report shows, so it is also the + # level the countdown is computed from - history lags a poll, and a + # row whose level and days-left came from different moments reads + # as broken. + detail = analyse(points, currentlevel=supply.get('level')) detail['name'] = supply.get('name') detail['color'] = supply.get('color') - # Trust the live read for the level; history can lag a poll behind. - detail['currentlevel'] = supply.get('level', detail['currentlevel']) analysed.append(detail) entry = { diff --git a/plugins/printers/frontend/views/TonerForecast.vue b/plugins/printers/frontend/views/TonerForecast.vue index e42ac0f..8d557ab 100644 --- a/plugins/printers/frontend/views/TonerForecast.vue +++ b/plugins/printers/frontend/views/TonerForecast.vue @@ -55,7 +55,14 @@ + fast is ordered before one sitting at 8% that never moves. + + Days left is per CARTRIDGE, not per printer. It used to span + the printer's rows, so every supply displayed the soonest one + of them - a cartridge at 20% sat beside "4 days" that belonged + to the black next to it. The printer number still decides + where the printer sorts; it does not label a row it is not + about. -->