The P1S reports a slicer toggle in a small 4-6 key update frame, not a full
status report, so the badge only changed after a Force Refresh. The probe
capture showed home_flag bit 10 flipping with each toggle and no stray flips
while idle. Once a full report has arrived without cfg, bit 10 is now read
from every status frame that carries home_flag. Small frames are still
ignored before that, and printers that send cfg keep reading cfg alone.
Removes the home_flag probe log.
When a spool ran out mid-print and the printer carried on from the backup
spool, the queue card still named the original slot and marked it Empty.
The printer status now carries the print's tray change log, and the card
shows the tray that took over: one outside the job's mapping, right after
the mapped tray it replaced, followed through a backup that ran out in
turn. Queued jobs still warn about an empty slot.
The printer card called getArchives(printer.id, 1, 0), which sends
project_id=1&limit=0, so every card got an empty list: no "Last:" line
and no Good/Reject prompt from #1898. Cards now share one request to the
new GET /archives/last-per-printer, which returns the archive each
printer ran last (by run start, since a reprint reuses its archive row)
without the duplicate scan the full listing runs.
File Manager and Archives thumbnails load lazily instead of all at once.
Stopping the event loop cancels the printer callbacks still pending.
_schedule_async's done-callback then called result(), which raises
concurrent.futures.CancelledError. Unlike asyncio's, that one is an
Exception, so it was logged as "Exception in scheduled callback" with
a traceback. Two support packages show it as the last line before a
restart.
Return early on a cancelled future, as core/tasks.py already does. A
callback that raised is still logged as an error.
On a dual-nozzle printer with several AMS on one extruder, tray_now is a
local slot. On every filament change it arrives about a second before
the extruder's snow, and the fallback filled the gap with the bare slot,
i.e. AMS 0. Support packages show 2,416 of these across H2C, H2D and
H2D Pro, 2,291 of them landing in the tray change log.
Resolve the slot from the printer's mapping field first, narrowed to the
active extruder's units when two trays share it. When that doesn't
decide, keep the current tray until snow names the new one.
/assets was served uncompressed and without Cache-Control, so phones
downloaded the full 11 MB bundle and revalidated it on every load. Text
assets are now gzip-compressed once per file and kept in memory, and
files with a content hash in their name are marked immutable. The
pdf.js runtime data has no hash and is revalidated instead.
-----
Load pages and languages when they are needed (#3175)
Every page and all 15 languages were one 11 MB script. Pages are now
separate files loaded on first open, and only English is bundled; the
language in use loads before the first render. A tab left on an older
build reloads once when a file is gone, after the server answers
again, so a kiosk is never left on the browser's connection error page.
The service worker serves hashed files from its cache and drops the
previous build's files.
Posts to the server's /message endpoint with the app token in the
X-Gotify-Key header. Each event's priority level is sent to Gotify as
0, 2, 5, 8 or 10, set in the same per-event priority section ntfy uses.
Events without a level go out at 5. The snapshot goes out as a
bigImageUrl, and the outcome confirmation opens its dialog on tap.
-----
List notification providers alphabetically
The Provider Type list in the Add Notification Provider dialog is now
sorted by the name shown on screen, in the current UI language, so the
order holds in every locale.
A job kept the AMS mapping of the printer it was made for. Moved to a
location and picked by another printer, a tray of the same material in
another colour passed the fit check, so the job printed in that colour.
The scheduler now drops a stored mapping when it assigns a job by model
or location and matches the trays on the chosen printer, by type and
colour. Moving a job from a printer to a model or location clears its
mapping and the "Print Anyway" given for that printer.
A printer without an AMS whose external spool has no filament set gave
the matcher nothing to match, so such a job went out without a mapping
and the firmware rejected it with 0700_8012. Every filament now goes to
the external spool there.
The size selector greyed out on the Cam Wall, whose grid always put up to
four tiles in a row, so a two-printer setup got two small tiles side by
side. In Cam Wall mode the selector now sets the tile grid (S up to five
per row, M four as before, L two, XL one full-width tile), saved apart
from the card size. The standalone /camwall page follows the last pick
and takes ?size=s|m|l|xl for kiosk links.
A queue item keeps the AMS mapping it was made with. A job made for a
printer without an AMS ([254], external spool) that was moved to a
location could be picked by a printer with an AMS, and still went out
with use_ams false; the printer stopped with "External filament is
missing". The #2799 check skipped it because an external tray the
printer doesn't report as loaded counted as no evidence.
A printer that reports its external spool empty, while its AMS holds
the filament type the slot needs in a similar colour, now counts as a
conflict, so the mapping is recomputed for that printer. AMS-less
printers, including ones whose external spool has no filament set, keep
the stored mapping, and with only another colour in the AMS the printer
still asks for the spool.
Print costs covered filament and energy but not the printer. Each printer
can now carry an optional wear cost per printing hour. Every run's wear is
its logged duration at that rate, stored on the print log entry; the
archive keeps the first run's wear, like energy (#1378). Failed and
cancelled runs count, reconciled runs (unknown duration) don't, and a rate
applies to new prints only.
Wear is shown on the archive card, as a hidden sortable Print Log column,
as a Quick Stats tile, in the most expensive record, in project totals and
in batch order cost, and is kept by GitHub backup and restore. Billing
still charges filament only.
New nullable columns: printers.wear_cost_per_hour, print_log_entries.wear_cost
and print_archives.wear_cost.
The post-print cleanup picks what to delete from the finished archive.
When a print finished while Bambuddy was stopped and the file was then
reprinted from the printer's screen, startup reconciliation closed the
old archive and the cleanup deleted the file the printer was printing.
The cleanup now skips any candidate that matches the printer's current
gcode_file or job name while the printer is busy. Finished, failed and
idle states hold nothing back, so the ghost-print cleanup is unchanged;
a ghost replay's file is deleted by its own end-of-print cleanup.
The cleanup moves out of on_print_complete into its own function.
Four permission backfills in seed_default_groups ran on every start, so
removing MakerWorld, clear plate, forecasting or pipelines from a group
was undone by the next restart. Each now runs once behind a settings
flag. On the upgrade that adds the flag, a backfill whose permission the
Administrators group already held at the start of seeding is recorded as
done without running, so nothing an admin removed comes back one last
time. The Operators/Viewers block stays per-start: those system groups
can't be edited, so it only keeps them complete.
The slicer writes an external spool as -1 in ams_mapping, the same as an
unused filament, and names it only in ams_mapping2. Save AMS mapping read
the flat list alone, so dispatch sent the filament as unmapped and an H2C
stopped with 0700-8012 before the first layer. Resolve it through
ams_mapping2 to the global tray (254/255, by the target's nozzle count),
as the usage capture does since #3166.
Users with library:read_own saw every folder anyone had made, and the
folder counts and activity times included other users' files. Folders
now have an owner. A read_own user sees their own folders, shared ones,
folders holding their files and the parents leading there, and adds
files only to their own and shared folders. Admins can share a folder
with everyone. Owners can rename their folders and delete them when
everything inside is theirs.
On upgrade, a folder whose files all belong to one user becomes that
user's; every other folder is shared, so it stays visible as before.
Each hourly energy snapshot records the price, and the energy used until the
next one is costed at it. Prints and the Statistics energy cost follow the
price over time instead of applying one price after the fact. The price can
come from a Home Assistant sensor, read hourly and at print start and end.
Energy multipliers now accept any value above zero, for plugs that report
watt-seconds.
The person slicing is often away from the printer, and the useful filaments
are the ones already loaded. Two optional filters in the Slice dialog narrow
the printer profiles to the models online now and the filament profiles to
the spools loaded in them, and a Pick button fills a filament row and its
colour from a loaded spool.
A new route returns the connected printers and their slots in one call,
limited to the caller's printers. A spool is matched by the profile saved
for its slot, then that profile's copy for the selected printer, then its
brand text. Both filters are off by default, fall back to the full lists
when they would leave nothing, and never replace a profile the user chose.
Groups can be limited to printers and whole locations, managed on the new
Printer access page, and jobs can wait for staff review before they print.
Merging onto the current dev:
- The Printer Locations page keeps to the same access rules: a rename keeps
its groups' access, deleting a granted location or moving printers into or
out of one needs an admin and drops the stale grant, and a user limited to
some printers sees and changes only their own locations.
- The overlay logo checks its token without a printer, which the stricter
overlay check now needs and the logo route doesn't have.
The MakerWorld page becomes Model Sources, with a MakerWorld tab and a
Manyfold tab. Bambuddy signs in to a self-hosted Manyfold with an OAuth
application (public read scopes), lists and searches its models with their
previews, and imports 3MF, STL and STEP files into the library, from where
they are sliced and printed like any other file.
New permissions manyfold:view and manyfold:import are granted once to the
groups that hold the matching MakerWorld permissions. The client secret is
never returned and is left out of GitHub backups. The Manyfold URL and every
redirect pass the LAN-service URL check. Old /makerworld links open the
MakerWorld tab.
Several files import at once: tick files in a model, or Select all, then
Import selected or Import all; or tick models in the grid and import all
their printable files. Files import one after another, failures don't stop
the rest, and a summary reports the outcome.
Every choice in Settings → Camera → Streaming Overlay was lost on reload
or when leaving the page. They are now kept in local storage, checked
like an imported URL when read back; the token is never stored. A Reset
choices link restores the defaults.
A "Settings saved" toast confirms each change once the edits settle.
A printer kept dark between uses showed a black live view and sent black
notification photos (#1655). Settings → Camera can turn the light on for
all printers or for selected ones, for the live view, notification
photos, the finish photo and the snapshot API that Home Assistant uses,
and turns it off 15 seconds after the last use. It only turns off a
light it turned on, and switching the light by hand hands it back.
Snapshots wait an adjustable delay after the light comes on. Timelapse,
the Obico check and the in-print frame bank don't switch it, since they
would make it flash.
The camera card no longer lists every printer: external cameras are
added from a searchable printer picker and only those printers are
listed, so large farms get a short page.
External cameras (General) and camera tokens plus the Streaming Overlay
builder (API Keys) move to a new Camera tab. Old links to the tokens or
the builder, /camera-tokens included, open it. API Keys is hidden from a
user who may see nothing on it. The settings menu keeps General first and
sorts the other tabs by their label in the interface language.
Also lets the Connected Apps fields shrink so Add app stays inside its
card, and fixes the pt-BR camera button label.