Sfoglia il codice sorgente

Printers: a nozzle's hover card says whether it is on the toolhead (#3442)

- the hover card took stat 1 as "Mounted", but stat says whether the
  nozzle's details are reliable and normal (Bambu Studio's DevNozzle),
  not where it is
- on an H3C a hotend without RFID in the rack (stat 1) showed as
  Mounted and the one on the toolhead (stat 176) as Docked
- Mounted is now an id below 0x10, as Studio tells them apart: the
  nozzles on the toolhead; rack ids start at 0x10
- test with the rack from a real H3C frame after a tool swap
maziggy 7 ore fa
parent
commit
0ca2a9b545

+ 1 - 0
CHANGELOG.md

@@ -21,6 +21,7 @@ All notable changes to Bambuddy will be documented in this file.
 - **The external spool keeps its filament after Configure Slot on an A1 or A1 mini (#3513, reported by @SaadShaya7)** — These printers report a change to the external spool with only what changed, often just the colour. Bambuddy stored that as the whole slot, so after a colour or preset change the spool showed as empty, with no filament type, until the printer's next full update. The check that the printer took the new preset also could not find the slot and reported it as not confirmed. A partial update now changes only what it carries, and the check confirms the new preset as soon as the printer reports it.
 - **A print that fails before its first layer no longer charges a whole spool (#3511)** — When a print failed or was cancelled before its first layer, Bambuddy worked out from the sliced file that no filament was used, but still let the AMS remaining % decide for that slot. The AMS can read 0% for a moment as the filament unloads, so a new spool at 100% was charged in full: 1000 g and its cost for a print stopped after five minutes, which then topped the Stats page as the heaviest and most expensive print. A slot whose spool the sliced file already accounts for is now left to that figure, so such a print charges nothing. Prints without a sliced file still use the AMS remaining %.
 - **The H3C's printer card shows the temperature of the hotend on the toolhead (#3442, reported by @hurr1k4ne, cause found by @daltonclift)** — After a tool swap the H3C keeps reporting the temperature of the hotend that just went back to the rack, so the card could show one cooling down there instead of the one printing. The card now takes the temperature, target and heating state of the hotend on the toolhead, as Bambu Studio does, and names it by its rack position (**Nozzle 5**), the number its chip has in the nozzle rack beside it.
+- **A nozzle's hover card says whether it is on the toolhead (#3442, frame from @daltonclift)** — The hover card of a nozzle took a status flag the printer uses for whether the nozzle's details can be trusted as "Mounted". On an H3C, a hotend without RFID in the rack showed as **Mounted**, and the one on the toolhead as **Docked**. The card now says **Mounted** for the nozzles on the toolhead and **Docked** for those in the rack, as Bambu Studio tells them apart.
 - **The SpoolBuddy kiosk works with its own device when several are registered (#3504, reported by @pleasantone)** — The kiosk's **Write** page always sent the write to the first registered device, which could be another kiosk or an old reader that had long been offline. The online state and display settings also came from that device, and every kiosk showed the weight and tags of every reader. The kiosk now works with one device: the one picked on its **Write** page, or else the device that is online. **Write** shows a choice of device when more than one is online, and the kiosk remembers it. Weight, tags and online state from other devices no longer show on it.
 - **A tag written with SpoolBuddy moves to the new spool (#3505, reported by @pleasantone)** — With Bambuddy's own inventory, writing a tag that already belonged to another spool linked it to the new spool but left it on the old one too, so scanning it could open the old spool. The tag now moves: the spool that had it gives it up, as it already did with Spoolman.
 - **SpoolBuddy checks a tag write instead of always reporting success (#3076, reported by @jinjiangz, gaps found by @pleasantone)** — The PN5180 can't see a tag's answer to a write, so **Write Tag** reported success for every page it sent. SpoolBuddy now reads the written data back and fails the write if the tag holds something else, naming the page. If the tag doesn't answer the read-back, the write still counts, reported as not verified. A tag too small for the data is refused before anything is written, and so is a tag that isn't NDEF-formatted, such as a blank MIFARE Ultralight, which looks like an NTAG to the reader. Before, a write past its end was reported as successful. When the write's result couldn't reach Bambuddy straight away, the next heartbeat brought the same write back and SpoolBuddy ran it a second time, on whatever tag was then on the reader. It now waits until the result is through.

+ 35 - 0
frontend/src/__tests__/pages/PrintersPageAms3h.test.tsx

@@ -219,6 +219,41 @@ describe('PrintersPage - H3C mounted hotend temperature (#3442)', () => {
     });
   });
 
+  it('says Mounted for the hotend on the toolhead and Docked in the rack, whatever its stat', async () => {
+    // device.nozzle.info of a real H3C frame after a swap to PrintTool 2: the
+    // toolhead's hotend is id 0 at addr_id 1 with stat 176; the hotend without
+    // RFID in rack position 8 (id 23) reports stat 1.
+    const entry = (id: number, addr_id: number, stat: number, type = 'HS01', color = 'CA2525FF') => ({
+      id, addr_id, nozzle_type: type, nozzle_diameter: '0.4', wear: 0, stat, max_temp: 350,
+      serial_number: '', filament_color: color, filament_id: type === 'HS01' ? 'GFL99' : '', filament_type: '',
+    });
+    const realRack = [
+      entry(0, 1, 176, 'HS01', 'FFFFFFFF'), entry(16, 0, 160), entry(18, 2, 160), entry(19, 3, 160),
+      entry(20, 4, 160), entry(21, 5, 160), entry(22, 6, 160), entry(23, 7, 1, 'HT01', '00000000'), entry(24, 8, 160),
+    ];
+    server.use(
+      http.get('/api/v1/printers/:id/status', () => HttpResponse.json({ ...h3cStatus, nozzle_rack: realRack })),
+    );
+    const user = userEvent.setup();
+
+    const { container } = render(<PrintersPage />);
+
+    await waitFor(() => {
+      expect(container.querySelectorAll('[data-rack-diameter]')).toHaveLength(9);
+    });
+    const chips = container.querySelectorAll('[data-rack-diameter]');
+
+    await user.hover(chips[7]);
+    expect(await screen.findByText('Docked')).toBeInTheDocument();
+    expect(screen.queryByText('Mounted')).not.toBeInTheDocument();
+    await user.unhover(chips[7]);
+    await waitFor(() => expect(screen.queryByText('Docked')).not.toBeInTheDocument());
+
+    await user.hover(chips[1]);
+    expect(await screen.findByText('Mounted')).toBeInTheDocument();
+    expect(screen.queryByText('Docked')).not.toBeInTheDocument();
+  });
+
   it('keeps Nozzle on a printer without a rack', async () => {
     server.use(
       http.get('/api/v1/printers/', () => HttpResponse.json([{ ...mockPrinter, model: 'P2S' }])),

+ 5 - 1
frontend/src/pages/PrintersPage.tsx

@@ -407,7 +407,11 @@ function NozzleSlotHoverCard({ slot, index, activeStatus, filamentName, children
   const timeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);
 
   const isEmpty = !slot.nozzle_diameter && !slot.nozzle_type;
-  const isMounted = slot.stat === 1;
+  // Mounted = on an extruder: ids below 0x10, rack ids from 0x10 up, as Bambu
+  // Studio tells them apart (DevNozzleSystem). `stat` says whether the nozzle's
+  // info is reliable and normal, not where it is (#3442: an H3C hotend without
+  // RFID reports stat 1 in the rack). Empty rack placeholders have negative ids.
+  const isMounted = slot.id >= 0 && slot.id < 16;
 
   useEffect(() => {
     if (isVisible && triggerRef.current && cardRef.current) {