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.
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.
The 3MF pass skipped a tray once it had charged it, so a second slicer
filament mapped to the same tray was never deducted, and a single-filament
print that switched trays and came back lost its last segment. Deduplicate
by slicer slot instead. Trays covered before the pass, and trays only
guessed by position that were already charged, are still skipped; charged
trays are still reported to the remain% fallback.
Track a last-seen time per fault instead of one set per printer, with a
10-minute window. Faults seen before the print resumes, starts or
finishes are forgotten as soon as they are gone, so a fixed runout that
recurs is still reported.
The daemon took tray_uuid from tag blocks 4-5, which hold the filament
type, so every spool of one type sent the same value and the kiosk never
saved it. Read block 9, which both tags of a spool share and the AMS
reports as tray_uuid. Save it on kiosk quick-add and link in local and
Spoolman mode, and give spools added before the fix their tray_uuid when
their exact tag UID is scanned again. Drop any tray_uuid that is not a v4
UUID, so daemons that are not updated yet keep matching by tag UID.
Block 9 read based on #1200 by @Keybored02.
Co-Authored-By: Keybored02 <Keybored02@users.noreply.github.com>
After an RTSP session dropped, ffmpeg could keep writing the same JPEG
indefinitely with no connection to the printer left (two hours at ~29 fps
on a P2S), and every check that counts frames saw a healthy stream. The
stream now restarts ffmpeg after 20 s without a changed frame, on the
existing reconnect path, while viewers stay attached. If the first frame
after the restart is the same picture again, the camera really shows a
still scene (a dark, idle chamber): it is then only re-checked every
5 minutes until the picture changes.
OrcaSlicer's Sync filaments finds a slot's preset by the slot's filament
ID alone. The Configure dialog looked up an Orca profile's ID in the
browser and quietly sent the generic for the material when that came back
empty, so Orca custom filaments reached the slicer as Generic and the log
showed nothing. configure now resolves the ID on the server from
orca_profile_id, follows inherits to the parent profile or the Bambu
filament it was copied from, logs the outcome and reports a fallback,
which the dialog shows as a warning.
Slot presets also store the filament ID they were written with, so the
slot card and the Configure dialog stop showing a preset once the slot is
changed from OrcaSlicer's Device tab or the printer.
Re-configuring a slot for another filament no longer carries over the old
filament's active K-profile, which switched the slot back to the old
filament.
A group can now be given locations as well as single printers: it then
reaches every printer in them, including printers added there later.
Printer access moves out of the group editor to Settings ->
Authentication -> Printer access, built for large fleets: groups and
printers searchable and filtered by location, model and access, edited
by group or by printer, saved together. "Who has access" in the printer
card menu opens it on that printer.
- group_locations table; the scope is picked printers plus printers
whose location matches.
- Moving a printer into or out of a location a limited group has is
admin-only, and open connections are rescoped. The edit dialog names
the groups a move affects. Locations are trimmed on save.
- Clearing a printer's location in the edit dialog now clears it.
A group can now be limited to a set of printers. Its members see and
control only those printers. Every other printer answers 404, as if it
didn't exist.
- Groups gain restrict_printers and a group_printers table (migration
for SQLite and Postgres). A user's printers are the union of their
limited groups. Groups without the flag don't limit anything, a user
in no limited group keeps every printer, and admins see all of them.
- core/printer_scope.py holds the scope. RequestPrinterScope and
RequirePrinterPermissionIfAuthEnabled apply it to routes: printer
routes, camera, queue and batches, archives, projects, stats, print
log, pipeline runs, inventory and Spoolman assignments, maintenance,
smart plugs, scheduled drying, firmware and Obico status.
- API keys, camera stream, Cam Wall, overlay and WebSocket tokens carry
the printers of whoever created them. WebSocket broadcasts are
filtered per connection, and the filtering fails closed.
- Scheduler: "Any <model>" jobs stay on their owner's printers. A job
pinned to a printer its owner lost waits with a reason. Callers with
no user identity and limited printers must queue to a specific printer.
- Group editor: new Printer access section, translated into all 15
locales. Saving a system group no longer resends unchanged
permissions, which the backend refused.
- Expired messages stay readable under a collapsed "Earlier" section, as
long as the feed keeps them (12 months, at most 50). They never count as
unread or raise a banner; withdrawn ones are gone everywhere.
- Each message is one row (level, date, title) that opens in place.
Unread ones carry a dot and a New chip, and opening one is what marks
it read; the banner's Read more opens the panel on its message.
- A fetch that brings a newer feed broadcasts an empty
announcements_changed event, so open pages show the new dot and banner
without a reload.
- The sidebar entry is a megaphone icon with an unread badge, in the
footer row left of System. Footer icons are 32px with no gap so seven
fit an expanded sidebar; with authentication on, logout used to wrap
onto a line of its own.
Fetch a signed feed.json from the public bambuddy-notifications repo on
GitHub at startup and every 6 hours. Nothing about the install is sent;
targeting (version, beta channel, install type) is decided locally.
- Ed25519 against a key built into the app; an older serial is refused so a
withdrawn message can't come back. The feed replaces the stored list, and
a failed or rejected fetch keeps the last good one.
- Sidebar entry above System with an unread count, a slide-over list, and a
banner for unread important/critical messages. Read state per user.
- Admins by default; Settings > General > Updates can show them to all
users or switch them off, which also stops the fetch.
- Plain text only; links to github.com and bambuddy.cool only.
ams_get_rfid was published and reported as success without reading the
printer's answer. X1Plus on base 01.08.02.00 answers FAIL / ERROR STATE,
so the user saw "Refreshing" and the K profile was re-applied to a slot
that was never read.
- Wait for the ams_get_rfid answer (matched by sequence_id).
- On a refusal from an idle X1/P1/A1, send the legacy M620 R<ams*4+slot>
gcode Bambu Studio uses for those models, AMS units 0-3 only. Never
during a job, never on newer-protocol models; printers that accept
ams_get_rfid never see it.
- Refused: the route returns 400 with the printer's reason and no PA
re-apply is scheduled. No answer still counts as accepted.
- Log the answers at INFO so refusals reach support bundles.
With authentication on, {finish_photo_url} pointed at the archive photo
route, which needs a media token. A link tapped in Telegram, CallMeBot
or a Home Assistant notification has none, so it only ever answered 401.
_finish_photo_for_notification() now builds the link and the attachment
bytes. With authentication off the link is the archive URL, unchanged.
With it on, the photo is also saved through the notification photo
store from #3199, and the link points there. That is an unguessable
name that opens this one photo, for 3 days. If the auth check fails,
it is treated as on. With auth on and the photo missing, no link is
set rather than one that 401s. Photos over 2.5 MB are still linked but
not attached, as before.
lldap and OpenLDAP's memberof overlay omit memberOf from "*", so every
lldap login fell through to the default group. Request memberOf by name
when the schema defines it, and on non-AD directories also search the
directory root for groupOfNames/groupOfUniqueNames entries listing the
user, since groups often sit outside the user search base and the
overlay tracks only one group class.
Also: skip ldap3's anonymous schema read after StartTLS, which AD and
Samba AD reject, so StartTLS works there; reword a server's StartTLS
refusal with an LDAPS hint; stop the bundle sanitizer masking part of
an OID as an IP; skip the sync right after auto-provisioning so the
default-group warning logs once.
Spoolman keeps a full spool's net weight on the spool (initial_weight)
and falls back to the filament's weight, but Bambuddy read only the
filament, so a 250 g spool of a 1000 g filament showed and synced as
1000 g. The list, weigh, AMS sync, SpoolBuddy scale, remain-% tracking,
fill bar and cost now share one lookup. Create writes initial_weight,
and a label-weight edit writes it instead of patching or duplicating the
filament. The spool form's cost per kg is converted at the spool's size
to and from Spoolman's per-spool price.
Spoolman resolves a spool's tare from the spool, then the filament, then
the vendor's empty_spool_weight. Bambuddy skipped the vendor and fell
back to 250 g, so weighing a spool whose tare was set only on its vendor
gave the wrong remaining weight. The inventory weigh action, the
SpoolBuddy scale and the displayed core weight now share one lookup, and
"keep old weight" on a filament change stamps a vendor-inherited tare.
C11 is the P1P, C12 the P1S, C13 the X1E and N7 the P2S, as the virtual
printer and a real P1P 3MF already say. The frontend map had them shifted,
so discovery pre-filled a P1S as a P1P and an X1E as a P2S. The backend
map read C11/C12 as X1C/X1 and lacked N7, the firmware check sent C13 to
the P2S line, and the capability lists never matched BL-P001 because
their lookup strips the dash.
-----
Post work PR #3134