mirror of
https://github.com/maziggy/bambuddy.git
synced 2026-10-21 10:15:04 +02:00
fix(spool-assign): defer MQTT for empty AMS slot, replay on physical insert
The SpoolBuddy "weigh-then-assign" workflow tried to configure an empty AMS slot at assign time, but Bambu firmware silently drops ams_filament_setting and extrusion_cali_sel for unloaded slots — the MQTT calls completed and the modal closed, yet BambuStudio kept showing the slot as default-PLA forever. assign_spool now detects an empty target slot (fingerprint_type empty) and persists the SpoolAssignment without publishing MQTT, returning a new pending_config flag so the frontend can swap "Assigned!" for "Slot will configure when you insert the spool." on_ams_change watches for the slot to load (state == 11, which fires for 3rd-party tags too even when tray_type stays empty) and replays the deferred ams_filament_setting + extrusion_cali_sel — including the printer-kp realignment that converts PFUS-prefix cloud user presets to the P-prefix local-preset filament_id the slicer actually accepts. The full assign-time MQTT block was extracted into apply_spool_to_slot_via_mqtt so both the assign endpoint and the on_ams_change replay path use the same resolution logic; the helper takes ~270 lines of duplication out of assign_spool.
This commit is contained in:
@@ -167,27 +167,37 @@ export function AssignToAmsModal({ isOpen, onClose, spool, printerId }: AssignTo
|
||||
}, [isDualNozzle, amsExtruderMap]);
|
||||
|
||||
// Assign spool to AMS slot — single API call, backend handles both
|
||||
// DB record AND MQTT auto-configuration (same as SpoolStation).
|
||||
// DB record AND MQTT auto-configuration (same as SpoolStation). When the
|
||||
// target slot is currently empty, the backend persists the assignment and
|
||||
// skips the MQTT publish (firmware drops it anyway); on_ams_change re-fires
|
||||
// the full configuration when filament is later inserted. The response's
|
||||
// `pending_config` flag distinguishes that from the immediate-apply path
|
||||
// so we can adjust the success toast.
|
||||
const configureMutation = useMutation({
|
||||
mutationFn: async ({ amsId, trayId }: { amsId: number; trayId: number }) => {
|
||||
if (!printerId) throw new Error('No printer selected');
|
||||
|
||||
await api.assignSpool({
|
||||
return await api.assignSpool({
|
||||
spool_id: spool.id,
|
||||
printer_id: printerId,
|
||||
ams_id: amsId,
|
||||
tray_id: trayId,
|
||||
});
|
||||
|
||||
// Slot preset mapping is now saved by the backend in assign_spool()
|
||||
// after successful MQTT configuration, using the authoritative
|
||||
// slicer_filament_name from the spool record.
|
||||
},
|
||||
onSuccess: () => {
|
||||
onSuccess: (assignment) => {
|
||||
setStatusType('success');
|
||||
setStatusMessage(t('spoolbuddy.modal.assignSuccess', 'Assigned!'));
|
||||
if (assignment?.pending_config) {
|
||||
setStatusMessage(
|
||||
t(
|
||||
'spoolbuddy.modal.assignPendingInsert',
|
||||
'Assigned. Slot will configure when you insert the spool.',
|
||||
),
|
||||
);
|
||||
} else {
|
||||
setStatusMessage(t('spoolbuddy.modal.assignSuccess', 'Assigned!'));
|
||||
}
|
||||
queryClient.invalidateQueries({ queryKey: ['slotPresets'] });
|
||||
setTimeout(() => onClose(), 1500);
|
||||
setTimeout(() => onClose(), assignment?.pending_config ? 2500 : 1500);
|
||||
},
|
||||
onError: (err) => {
|
||||
setStatusType('error');
|
||||
|
||||
Reference in New Issue
Block a user