Forráskód Böngészése

Fix H2D Pro L/R nozzle hover card swap and hide left-only fields (#300)

Nozzle rack id 0 = extruder 0 = right nozzle, id 1 = extruder 1 = left.
The dual-nozzle hover card had them backwards, showing serial number and
max temp on the left column instead of the right. Serial and max temp
are now restricted to the right (removable) nozzle only. Single-nozzle
fallback (H2D, H2C) updated to use the primary nozzle (id 0).
maziggy 6 hónapja
szülő
commit
0282fbd442

+ 1 - 0
CHANGELOG.md

@@ -48,6 +48,7 @@ All notable changes to Bambuddy will be documented in this file.
 - **Support Bundle Shows 0 AMS Units** — The support info always reported `ams_unit_count: 0` because it expected `raw_data["ams"]` to be a nested dict (`{"ams": [...]}`) but the MQTT handler stores it as a flat list. Now handles both formats.
 - **Firmware Badge Shown for Models Without API Data** ([#311](https://github.com/maziggy/bambuddy/issues/311)) — Printers whose model has no firmware data in Bambu Lab's API (e.g. H2C on public beta firmware) showed a misleading green "up to date" badge. The badge is now hidden when the API returns no `latest_version`, since there is nothing to compare against.
 - **AMS-HT Mapping Fails for Left Nozzle on H2D Pro** ([#318](https://github.com/maziggy/bambuddy/issues/318)) — Printing with the left nozzle on dual-nozzle printers (H2D/H2D Pro) using AMS-HT failed with "Failed to get AMS mapping table." The global tray ID for AMS-HT units (ams_id >= 128) was calculated as `ams_id * 4 + tray_id` (= 512), but AMS-HT uses the raw `ams_id` (128) since it has a single tray. The backend then misidentified 512 as an external spool. Fixed in frontend tray ID calculation, backend `ams_mapping2` builder, print scheduler, and Spoolman tracking.
+- **H2D Pro L/R Nozzle Hover Card Swapped** ([#300](https://github.com/maziggy/bambuddy/issues/300)) — The dual-nozzle hover card had left and right nozzles swapped: nozzle_rack id 0 (extruder 0 = right) was shown as left and vice versa. Serial number and max temp now correctly appear only on the right (removable) nozzle column.
 - **H2C Printer Card Shows H2D Image** ([#300](https://github.com/maziggy/bambuddy/issues/300)) — The H2C printer card displayed the H2D printer image because no dedicated H2C image existed in the frontend. Added H2C image and updated `getPrinterImage()` to return it for H2C models.
 - **H2C Nozzle Rack Shows Wrong Empty Slot and Missing Filament Colors** ([#300](https://github.com/maziggy/bambuddy/issues/300)) — Empty rack slots always appeared at position 6 instead of their actual position because nozzles were mapped by array index instead of by ID. Fixed by mapping each nozzle to its correct rack position (`id - 16`). Filament colors and materials were missing because the H2C uses different MQTT field names (`color_m`, `fila_id`, `sn`, `tm`) than the H2D (`filament_colour`, `filament_id`, `serial_number`, `max_temp`). Added fallback field name resolution. Also fixed nozzle rack layout breaking on medium card size by allowing the temperature row to wrap.
 

+ 10 - 7
frontend/src/pages/PrintersPage.tsx

@@ -675,7 +675,6 @@ function DualNozzleHoverCard({ leftSlot, rightSlot, activeNozzle, children }: {
     const isActive = activeNozzle === side;
     const typeFull = nozzleTypeName(slot.nozzle_type, t);
     const flowFull = nozzleFlowName(slot.nozzle_type, t);
-
     return (
       <div className="flex-1 space-y-1.5">
         <div className={`text-[10px] font-bold pb-1 border-b border-bambu-dark-tertiary/50 ${isActive ? 'text-amber-400' : 'text-bambu-gray'}`}>
@@ -715,13 +714,14 @@ function DualNozzleHoverCard({ leftSlot, rightSlot, activeNozzle, children }: {
             <span className="text-xs text-white font-semibold">{slot.wear}%</span>
           </div>
         )}
-        {slot.max_temp > 0 && (
+        {/* Serial and max temp only available on the right (removable) nozzle */}
+        {side === 'R' && slot.max_temp > 0 && (
           <div className="flex items-center justify-between">
             <span className="text-[10px] text-bambu-gray">{t('printers.nozzleMaxTemp')}</span>
             <span className="text-xs text-white font-semibold">{slot.max_temp}°C</span>
           </div>
         )}
-        {slot.serial_number && (
+        {side === 'R' && slot.serial_number && (
           <div className="flex items-center justify-between">
             <span className="text-[10px] text-bambu-gray">{t('printers.nozzleSerial')}</span>
             <span className="text-[10px] text-white font-mono">{slot.serial_number}</span>
@@ -2393,8 +2393,11 @@ function PrinterCard({
               // active_extruder: 0=right, 1=left
               const activeNozzle = status.active_extruder === 1 ? 'L' : 'R';
               // Extended nozzle data from nozzle_rack (H2 series: wear, serial, max_temp, etc.)
-              const leftNozzleSlot = status.nozzle_rack?.find(s => s.id === 0);
-              const rightNozzleSlot = status.nozzle_rack?.find(s => s.id === 1);
+              // nozzle_rack id 0 = extruder 0 = RIGHT, id 1 = extruder 1 = LEFT
+              const leftNozzleSlot = status.nozzle_rack?.find(s => s.id === 1);
+              const rightNozzleSlot = status.nozzle_rack?.find(s => s.id === 0);
+              // Single-nozzle models (H2D, H2C): use the primary nozzle (id 0)
+              const singleNozzleSlot = rightNozzleSlot || leftNozzleSlot;
 
               return (
                 <div className="flex items-stretch gap-1.5 flex-wrap">
@@ -2408,8 +2411,8 @@ function PrinterCard({
                           {Math.round(status.temperatures.nozzle || 0)}° / {Math.round(status.temperatures.nozzle_2 || 0)}°
                         </p>
                       </>
-                    ) : leftNozzleSlot ? (
-                      <NozzleSlotHoverCard slot={leftNozzleSlot} index={0} activeStatus filamentName={leftNozzleSlot.filament_id ? filamentInfo?.[leftNozzleSlot.filament_id]?.name : undefined}>
+                    ) : singleNozzleSlot ? (
+                      <NozzleSlotHoverCard slot={singleNozzleSlot} index={0} activeStatus filamentName={singleNozzleSlot.filament_id ? filamentInfo?.[singleNozzleSlot.filament_id]?.name : undefined}>
                         <div className="cursor-default">
                           <p className="text-[9px] text-bambu-gray">{t('printers.temperatures.nozzle')}</p>
                           <p className="text-[11px] text-white">

A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 0 - 0
static/assets/index-B1hpQ91Q.css


A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 0 - 0
static/assets/index-BnphTAH8.js


A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 0 - 0
static/assets/index-DCzsNoVv.css


BIN
static/img/printers/h2c.png


+ 2 - 2
static/index.html

@@ -23,8 +23,8 @@
 
     <!-- Splash screens for iOS -->
     <link rel="apple-touch-startup-image" href="/img/android-chrome-512x512.png" />
-    <script type="module" crossorigin src="/assets/index-tNOV_9of.js"></script>
-    <link rel="stylesheet" crossorigin href="/assets/index-DCzsNoVv.css">
+    <script type="module" crossorigin src="/assets/index-BnphTAH8.js"></script>
+    <link rel="stylesheet" crossorigin href="/assets/index-B1hpQ91Q.css">
   </head>
   <body>
     <div id="root"></div>

Nem az összes módosított fájl került megjelenítésre, mert túl sok fájl változott