Files
bambuddy/static/index.html
T
maziggy d5c7047765 Name an AMS slot after the spool assigned to it
The print dialog described every slot from the printer's own telemetry, and
a printer cannot describe a spool it did not sell: a tray record carries no
brand field, tray_sub_brands is left empty for anything that is not a Bambu
spool, and the colour arrives as a bare hex the client resolves against
Bambu's own colour catalogue. A Devil Design PLA Basic Orange assigned in
Bambuddy therefore read as "PLA (Sunflower Yellow)" -- Bambu sell a
Sunflower Yellow at the same FEC600 -- while the printer card, which reads
the assignment, named it correctly. Two views of one slot, disagreeing.

GET /printers/{id}/inventory-remain now carries each bound slot's brand,
material, subtype, colour name and hex alongside the pooling key it already
sent, and the dialog prefers that over telemetry. The fallback is per field,
not all or nothing, so a spool with no stored colour name still gets the
catalogue lookup it had before while its brand and subtype come from the
binding. Resolved server-side because the identity rule differs per
inventory mode -- brand is a column in internal mode and a nested vendor in
Spoolman's, where the subtype is the filament name with its material prefix
stripped and the colour name has a three-step read order Spoolman has no
field for. Spoolman's synthesised colour name, which falls back to the
subtype, is withheld rather than rendered as "PLA Basic (Basic)".

Matching is deliberately untouched and still runs on the printer's
telemetry. The auto-assignment, the colour-mismatch test and the mapping
that actually gets dispatched all read type, colour hex and tray_info_idx,
so renaming a slot cannot make the panel and the dispatcher draw different
conclusions from it. The payload is re-read on every open of the dialog: it
names the slots now, and a spool assigned moments earlier would otherwise
keep its old name for the rest of the thirty-second stale window. Done at
the two readers rather than by invalidating the key from each of the
eighteen places a binding or a spool can change, half of which are internal
paths and half Spoolman ones -- covering some would make freshness depend on
which mode you run.

Two hardening fixes fall out of putting a mapper on this path.
build_slot_materials runs before every queue start through
compute_deficit_for_queue_item, and _map_spoolman_spool walks a dozen nested
fields off the wire, any of which arriving as the wrong type raises
AttributeError rather than ValueError. Naming a slot must never cost a
dispatch, so that call fails soft to no name. The same inputs also reached
_material_identity_spoolman and _normalize_color_for_id, which have always
been on this path and would fail a queue start on a Spoolman record whose
filament is not a dict or whose color_hex is a number; both now read those
as "nothing to pool with". Behaviour for well-formed input is unchanged --
the guards only intercept types that previously raised -- so no pooling key
moves and AMS Filament Backup is untouched.
2026-08-27 16:04:41 +02:00

41 lines
1.8 KiB
HTML

<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<!-- L-4: Restrict Referer header to origin-only on cross-origin navigation so
sensitive tokens in query parameters are not leaked to third-party servers. -->
<meta name="referrer" content="strict-origin-when-cross-origin" />
<title>Bambuddy</title>
<!-- PWA Meta Tags -->
<meta name="description" content="Monitor and manage your Bambu Lab 3D printers" />
<meta name="theme-color" content="#00ae42" />
<meta name="mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
<meta name="apple-mobile-web-app-title" content="Bambuddy" />
<!-- Manifest -->
<link rel="manifest" href="/manifest.json" />
<!-- Favicons -->
<link rel="icon" type="image/png" sizes="32x32" href="/img/favicon-32x32.png" />
<link rel="icon" type="image/png" sizes="16x16" href="/img/favicon-16x16.png" />
<link rel="apple-touch-icon" sizes="180x180" href="/img/apple-touch-icon.png" />
<!-- Splash screens for iOS -->
<link rel="apple-touch-startup-image" href="/img/android-chrome-512x512.png" />
<script type="module" crossorigin src="/assets/index-DkJ3AJ3x.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-q2IPtdZB.css">
</head>
<body>
<div id="root"></div>
<!-- Service Worker Registration (skip on SpoolBuddy kiosk).
Kept as an external file so the CSP `script-src 'self'` covers it
without needing 'unsafe-inline' or per-build hashes. -->
<script src="/sw-register.js"></script>
</body>
</html>