mirror of
https://github.com/maziggy/bambuddy.git
synced 2026-10-09 07:25:44 +02:00
Auto-create Spoolman 'tag' extra field on connect (Issue #123)
The 'tag' extra field is required in Spoolman for storing RFID/UUID identifiers that link Bambu Lab spools to Spoolman entries. Previously, users had to manually create this field in Spoolman, causing sync failures for fresh installations. Added ensure_tag_extra_field() method to SpoolmanClient that: - Checks if the 'tag' field exists via GET /api/v1/field/spool/tag - Creates it via POST if missing The method is called automatically: - On app startup when auto-connecting to Spoolman - When user clicks "Connect" in Spoolman settings
This commit is contained in:
@@ -15,6 +15,7 @@ All notable changes to Bambuddy will be documented in this file.
|
||||
|
||||
### Fixed
|
||||
- **Filament cost using wrong default** - Statistics now correctly uses the "Default filament cost (per kg)" setting instead of hardcoded €25 value (Issue #120)
|
||||
- **Spoolman tag field not auto-created** - The required "tag" extra field is now automatically created in Spoolman on first connect, fixing sync failures for fresh Spoolman installs (Issue #123)
|
||||
|
||||
## [0.1.6b10] - 2026-01-21
|
||||
|
||||
|
||||
@@ -109,6 +109,9 @@ async def connect_spoolman(db: AsyncSession = Depends(get_db)):
|
||||
detail=f"Could not connect to Spoolman at {url}",
|
||||
)
|
||||
|
||||
# Ensure the 'tag' extra field exists for RFID/UUID storage
|
||||
await client.ensure_tag_extra_field()
|
||||
|
||||
return {"success": True, "message": f"Connected to Spoolman at {url}"}
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to connect to Spoolman: {e}")
|
||||
|
||||
@@ -1903,6 +1903,8 @@ async def lifespan(app: FastAPI):
|
||||
client = await init_spoolman_client(spoolman_url)
|
||||
if await client.health_check():
|
||||
logging.info(f"Auto-connected to Spoolman at {spoolman_url}")
|
||||
# Ensure the 'tag' extra field exists for RFID/UUID storage
|
||||
await client.ensure_tag_extra_field()
|
||||
else:
|
||||
logging.warning(f"Spoolman at {spoolman_url} is not reachable")
|
||||
except Exception as e:
|
||||
|
||||
@@ -488,6 +488,42 @@ class SpoolmanClient:
|
||||
vendor = await self.create_vendor("Bambu Lab")
|
||||
return vendor["id"] if vendor else None
|
||||
|
||||
async def ensure_tag_extra_field(self) -> bool:
|
||||
"""Ensure the 'tag' extra field exists for spools.
|
||||
|
||||
Spoolman requires extra fields to be registered before use.
|
||||
This creates the 'tag' field used to store RFID/UUID identifiers.
|
||||
|
||||
Returns:
|
||||
True if field exists or was created, False on failure.
|
||||
"""
|
||||
try:
|
||||
client = await self._get_client()
|
||||
|
||||
# Check if field already exists
|
||||
response = await client.get(f"{self.api_url}/field/spool/tag")
|
||||
if response.status_code == 200:
|
||||
logger.debug("Spoolman 'tag' extra field already exists")
|
||||
return True
|
||||
|
||||
# Field doesn't exist - create it
|
||||
field_data = {
|
||||
"name": "tag",
|
||||
"field_type": "text",
|
||||
"default_value": None,
|
||||
}
|
||||
response = await client.post(f"{self.api_url}/field/spool/tag", json=field_data)
|
||||
if response.status_code in (200, 201):
|
||||
logger.info("Created 'tag' extra field in Spoolman")
|
||||
return True
|
||||
|
||||
logger.warning(f"Failed to create 'tag' extra field: {response.status_code} - {response.text}")
|
||||
return False
|
||||
|
||||
except Exception as e:
|
||||
logger.warning(f"Failed to ensure 'tag' extra field exists: {e}")
|
||||
return False
|
||||
|
||||
def parse_ams_tray(self, ams_id: int, tray_data: dict) -> AMSTray | None:
|
||||
"""Parse AMS tray data into AMSTray object.
|
||||
|
||||
|
||||
@@ -39,6 +39,7 @@ class TestSpoolmanAPI:
|
||||
mock_client.is_connected = True
|
||||
mock_client.base_url = "http://localhost:7912"
|
||||
mock_client.health_check = AsyncMock(return_value=True)
|
||||
mock_client.ensure_tag_extra_field = AsyncMock(return_value=True)
|
||||
mock_client.get_spools = AsyncMock(return_value=[])
|
||||
mock_client.get_filaments = AsyncMock(return_value=[])
|
||||
mock_client.create_spool = AsyncMock(return_value={"id": 1})
|
||||
|
||||
Reference in New Issue
Block a user