mirror of
https://github.com/maziggy/bambuddy.git
synced 2026-10-18 11:56:01 +02:00
feat: dual external spool support, AMS slot model filtering & pre-population
Backend: - Add dual external spool support for H2D (vt_tray as list: Ext-L/Ext-R) - Add cloud filament ID map endpoint (/cloud/filament-id-map) - Fix RFID spool data erased by periodic AMS updates (skip tag matcher for RFID-tagged trays) - Fix AMS slot config overwrites RFID spool state - Fix K-profile selection corrupts existing profiles on X1C/P1S - Resolve K-profiles filament name via cloud filament ID map - Update print scheduler and usage tracker for dual external spools Frontend: - Add printer model filtering to ConfigureAmsSlotModal (cloud/local/builtin presets filtered by @BBL model suffix and compatible_printers) - Add pre-population for configured slots (preset, color, K-profile) - Add K-Profiles view with accurate filament name resolution - Internationalize all ConfigureAmsSlotModal strings (en/de/fr/it/ja — 21 keys) - Add 5 new ConfigureAmsSlotModal tests (model filtering, pre-selection, color pre-population, i18n) - Update PrintersPage for dual external spool rendering Docs: - Update CHANGELOG, README, website features, and wiki AMS docs
This commit is contained in:
@@ -734,23 +734,26 @@ class TestPrinterStateToDict:
|
||||
assert result["ams"][0]["tray"][0]["tag_uid"] is None
|
||||
|
||||
def test_vt_tray_parsing(self, mock_state):
|
||||
"""Verify virtual tray is parsed correctly."""
|
||||
"""Verify virtual tray is parsed correctly as a list."""
|
||||
mock_state.raw_data = {
|
||||
"vt_tray": {
|
||||
"tray_color": "00FF00",
|
||||
"tray_type": "PETG",
|
||||
"tray_sub_brands": "Generic",
|
||||
"remain": 60,
|
||||
"tag_uid": "VT123",
|
||||
}
|
||||
"vt_tray": [
|
||||
{
|
||||
"tray_color": "00FF00",
|
||||
"tray_type": "PETG",
|
||||
"tray_sub_brands": "Generic",
|
||||
"remain": 60,
|
||||
"tag_uid": "VT123",
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
result = printer_state_to_dict(mock_state)
|
||||
|
||||
assert result["vt_tray"] is not None
|
||||
assert result["vt_tray"]["id"] == 254
|
||||
assert result["vt_tray"]["tray_color"] == "00FF00"
|
||||
assert result["vt_tray"]["tray_type"] == "PETG"
|
||||
assert isinstance(result["vt_tray"], list)
|
||||
assert len(result["vt_tray"]) == 1
|
||||
assert result["vt_tray"][0]["id"] == 254
|
||||
assert result["vt_tray"][0]["tray_color"] == "00FF00"
|
||||
assert result["vt_tray"][0]["tray_type"] == "PETG"
|
||||
|
||||
def test_hms_errors_conversion(self, mock_state):
|
||||
"""Verify HMS errors are converted correctly."""
|
||||
|
||||
@@ -99,14 +99,14 @@ class TestBuildAmsTrayLookup:
|
||||
def test_external_spool(self):
|
||||
raw = {
|
||||
"ams": [],
|
||||
"vt_tray": {"tray_uuid": "EXT", "tag_uid": "X", "tray_type": "TPU"},
|
||||
"vt_tray": [{"tray_uuid": "EXT", "tag_uid": "X", "tray_type": "TPU"}],
|
||||
}
|
||||
lookup = build_ams_tray_lookup(raw)
|
||||
assert 254 in lookup
|
||||
assert lookup[254]["tray_type"] == "TPU"
|
||||
|
||||
def test_empty_external_spool_skipped(self):
|
||||
raw = {"ams": [], "vt_tray": {"tray_type": ""}}
|
||||
raw = {"ams": [], "vt_tray": [{"tray_type": ""}]}
|
||||
lookup = build_ams_tray_lookup(raw)
|
||||
assert 254 not in lookup
|
||||
|
||||
|
||||
@@ -140,7 +140,7 @@ class TestBuildLoadedFilaments:
|
||||
"""Should include external spool."""
|
||||
|
||||
class MockStatus:
|
||||
raw_data = {"vt_tray": {"tray_type": "TPU", "tray_color": "0000FF"}}
|
||||
raw_data = {"vt_tray": [{"tray_type": "TPU", "tray_color": "0000FF"}]}
|
||||
|
||||
result = scheduler._build_loaded_filaments(MockStatus())
|
||||
assert len(result) == 1
|
||||
@@ -466,7 +466,7 @@ class TestBuildLoadedFilamentsTrayInfoIdx:
|
||||
"""Should extract tray_info_idx from external spool."""
|
||||
|
||||
class MockStatus:
|
||||
raw_data = {"vt_tray": {"tray_type": "TPU", "tray_color": "0000FF", "tray_info_idx": "P4d64437"}}
|
||||
raw_data = {"vt_tray": [{"tray_type": "TPU", "tray_color": "0000FF", "tray_info_idx": "P4d64437"}]}
|
||||
|
||||
result = scheduler._build_loaded_filaments(MockStatus())
|
||||
assert len(result) == 1
|
||||
@@ -624,7 +624,7 @@ class TestNozzleAwareMapping:
|
||||
|
||||
class MockStatus:
|
||||
raw_data = {
|
||||
"vt_tray": {"tray_type": "TPU", "tray_color": "0000FF"},
|
||||
"vt_tray": [{"tray_type": "TPU", "tray_color": "0000FF"}],
|
||||
"ams_extruder_map": {"0": 0},
|
||||
}
|
||||
|
||||
@@ -637,7 +637,7 @@ class TestNozzleAwareMapping:
|
||||
"""External spool extruder_id should be None without ams_extruder_map."""
|
||||
|
||||
class MockStatus:
|
||||
raw_data = {"vt_tray": {"tray_type": "TPU", "tray_color": "0000FF"}}
|
||||
raw_data = {"vt_tray": [{"tray_type": "TPU", "tray_color": "0000FF"}]}
|
||||
|
||||
result = scheduler._build_loaded_filaments(MockStatus())
|
||||
assert len(result) == 1
|
||||
|
||||
Reference in New Issue
Block a user