Add filament spool tracking sync

This commit is contained in:
2026-04-15 15:16:47 +03:00
parent 791c2235c5
commit ec0a0bf9af
8 changed files with 1157 additions and 2 deletions

164
README.md
View File

@@ -1,6 +1,6 @@
# Bambuddy InvenTree Sync
Sidecar service for syncing successful Bambuddy print archives into InvenTree stock.
Sidecar service for syncing successful Bambuddy print archives into InvenTree stock and tracking filament spools between InvenTree and Bambuddy.
The service runs as a separate Docker container. It does not modify Bambuddy or InvenTree source code. Bambuddy is used as the print-history source, while InvenTree remains the stock-control system of record.
@@ -17,6 +17,14 @@ For each successful Bambuddy archive, the service:
Failed, stopped, running, or still-printing archives are skipped when `SYNC_SUCCESS_ONLY=true`.
For filament, the service can:
- use InvenTree `StockItem.batch` as the spool identity;
- create/update Bambuddy spool records from InvenTree filament stock;
- move InvenTree spool stock between storage and printer locations from Bambuddy assignments;
- subtract Bambuddy filament usage from the matching InvenTree stock item;
- store usage sync state in SQLite to prevent duplicate subtraction.
## Data Flow
```text
@@ -35,6 +43,24 @@ Part + StockItem + Parameters + Image
Archive external_url -> InvenTree Part page
```
Filament flow:
```text
InvenTree filament StockItem.batch
|
| creates or updates Bambuddy spool tag_uid
v
Bambuddy spool + printer assignment
|
| stock transfer
v
InvenTree storage location <-> printer location
|
| successful Bambuddy usage history
v
InvenTree stock/remove subtracts filament grams
```
## InvenTree Mapping
| Bambuddy data | InvenTree target |
@@ -49,6 +75,36 @@ Archive external_url -> InvenTree Part page
| archive thumbnail | `Part.image` |
| InvenTree part page | Bambuddy `external_url` |
## Filament Tracking
InvenTree remains the source of truth for spool identity and remaining stock.
The key rule is:
```text
InvenTree StockItem.batch == Bambuddy Spool.tag_uid
```
Recommended InvenTree structure for the current setup:
| Purpose | InvenTree ID |
| --- | --- |
| filament part category | `19` |
| filament storage root | `85` |
| loaded-in-printers root | `72` |
| B1 printer stock location | `93` |
| B2 printer stock location | `94` |
| B3 printer stock location | `95` |
| B4 printer stock location | `96` |
The service deliberately starts with `FILAMENT_DRY_RUN=true`. In dry-run mode it reads both systems and reports what it would create, move, or subtract, but it does not write filament changes. Switch to `FILAMENT_DRY_RUN=false` only after `/filament/status` and `/sync/filament?dry_run=true` show the expected mapping.
Filament sync has three independent parts:
- spool catalog sync: InvenTree stock items create/update Bambuddy spools;
- location sync: Bambuddy assignments move InvenTree stock to printer locations; returning unassigned loaded spools to storage is optional;
- usage sync: Bambuddy usage history subtracts grams from the matching InvenTree stock item.
## Duplicate Protection
The service is idempotent:
@@ -57,6 +113,7 @@ The service is idempotent:
- each `StockItem` gets batch `bambuddy-<archive_id>`;
- rerunning backfill does not create duplicate stock items;
- repeat prints of the same file/model reuse the same `Part` and create new `StockItem` rows.
- each Bambuddy filament usage ID is stored before it can subtract stock twice.
The `Part` identity key is controlled by:
@@ -84,6 +141,7 @@ This is intentional. InvenTree is the inventory record, and deleting print histo
- InvenTree API token.
- Existing InvenTree part category ID.
- Existing InvenTree stock location ID.
- Optional InvenTree filament category and stock location IDs.
- Optional InvenTree parameter templates: `Weight` and `PrintTime`.
On Windows Server 2022, verify Docker with:
@@ -166,6 +224,24 @@ BACKFILL_PAGE_SIZE=50
POLL_INTERVAL_SECONDS=300
SYNC_ON_STARTUP=false
HTTP_TIMEOUT_SECONDS=30
FILAMENT_TRACKING_ENABLED=false
FILAMENT_DRY_RUN=true
FILAMENT_PART_CATEGORY_ID=19
FILAMENT_STORAGE_LOCATION_ID=85
FILAMENT_LOADED_LOCATION_ID=72
FILAMENT_PRINTER_LOCATION_MAP=B1:93,B2:94,B3:95,B4:96
FILAMENT_BATCH_SOURCE=tag_uid
FILAMENT_SYNC_SPOOLS=true
FILAMENT_SYNC_LOCATIONS=true
FILAMENT_SYNC_USAGE=true
FILAMENT_RETURN_UNASSIGNED_TO_STORAGE=false
FILAMENT_USAGE_LIMIT=200
FILAMENT_USAGE_SUCCESS_STATUSES=success,completed,complete,done
FILAMENT_DEFAULT_MATERIAL=PLA
FILAMENT_DEFAULT_LABEL_WEIGHT=1000
FILAMENT_DEFAULT_CORE_WEIGHT=250
DATA_DIR=/data
```
@@ -206,6 +282,39 @@ Do not commit `.env`. It contains API tokens and is ignored by git.
`OVERWRITE_ARCHIVE_EXTERNAL_LINK`
: When `false`, existing non-InvenTree external links in Bambuddy are preserved.
`FILAMENT_TRACKING_ENABLED`
: Enables scheduled and manual filament sync actions.
`FILAMENT_DRY_RUN`
: When `true`, filament endpoints report planned writes but do not create spools, move stock, or subtract stock.
`FILAMENT_PART_CATEGORY_ID`
: InvenTree category containing filament parts.
`FILAMENT_STORAGE_LOCATION_ID`
: InvenTree root location where spare filament spools are stored.
`FILAMENT_LOADED_LOCATION_ID`
: InvenTree root location for spools loaded in printers.
`FILAMENT_PRINTER_LOCATION_MAP`
: Printer prefix to InvenTree location map. Example `B1:93` matches Bambuddy printer names like `B1-X1-CARBON`.
`FILAMENT_BATCH_SOURCE`
: Bambuddy spool field that contains the InvenTree batch code. Default is `tag_uid`.
`FILAMENT_SYNC_SPOOLS`
: Creates/updates Bambuddy spool records from InvenTree stock.
`FILAMENT_SYNC_LOCATIONS`
: Moves InvenTree stock items between storage and printer locations from Bambuddy assignments.
`FILAMENT_SYNC_USAGE`
: Subtracts successful Bambuddy usage history from InvenTree stock.
`FILAMENT_RETURN_UNASSIGNED_TO_STORAGE`
: When `true`, known Bambuddy spools that are no longer assigned are moved from printer locations back to storage. Keep this `false` until Bambuddy assignments are reliable.
## InvenTree IDs
Use numeric IDs for target category and stock location. You can find them from the InvenTree UI URL or API.
@@ -231,12 +340,14 @@ After the container starts:
```powershell
curl.exe http://localhost:8088/health
curl.exe -H "X-Service-Token: change-me" http://localhost:8088/validate
curl.exe -H "X-Service-Token: change-me" http://localhost:8088/filament/status
```
Expected result:
- `/health` returns `status: ok`;
- `/validate` confirms Bambuddy, InvenTree category, and InvenTree location are reachable.
- `/filament/status` shows how many InvenTree filament batches match Bambuddy spools.
## Initial Backfill
@@ -272,6 +383,35 @@ SYNC_ON_STARTUP=false
This makes the service check Bambuddy every 5 minutes and import all newly completed prints.
To also run filament tracking automatically:
```env
FILAMENT_TRACKING_ENABLED=true
FILAMENT_DRY_RUN=true
FILAMENT_SYNC_SPOOLS=true
FILAMENT_SYNC_LOCATIONS=true
FILAMENT_SYNC_USAGE=true
FILAMENT_RETURN_UNASSIGNED_TO_STORAGE=false
```
First run in dry-run:
```powershell
curl.exe -X POST -H "X-Service-Token: change-me" "http://localhost:8088/sync/filament?dry_run=true"
```
When the reported actions are correct, change:
```env
FILAMENT_DRY_RUN=false
```
Then rebuild/restart:
```powershell
docker compose up -d --build
```
For near-real-time syncing, also configure a Bambuddy webhook:
```text
@@ -302,14 +442,33 @@ curl.exe -X POST -H "X-Service-Token: change-me" "http://localhost:8088/sync/arc
Force sync is useful after changing image, parameter, or external link behavior.
Run all filament sync steps manually:
```powershell
curl.exe -X POST -H "X-Service-Token: change-me" http://localhost:8088/sync/filament
```
Run individual filament steps:
```powershell
curl.exe -X POST -H "X-Service-Token: change-me" http://localhost:8088/sync/filament/spools
curl.exe -X POST -H "X-Service-Token: change-me" http://localhost:8088/sync/filament/locations
curl.exe -X POST -H "X-Service-Token: change-me" http://localhost:8088/sync/filament/usage
```
## API Endpoints
```text
GET /health
GET /validate
GET /sync/status
GET /filament/status
POST /sync/archive/{archive_id}
POST /sync/backfill
POST /sync/filament
POST /sync/filament/spools
POST /sync/filament/locations
POST /sync/filament/usage
POST /webhooks/bambuddy
```
@@ -338,6 +497,9 @@ Common issues:
- InvenTree `description` length errors: update to the latest service version; descriptions are capped at 250 characters.
- No items imported: check if Bambuddy archives are still `printing` or `failed`.
- Duplicate protection prevents repeated imports: use `force=true` only when you want to refresh parameters/images/links for an existing archive.
- Filament sync reports `missing_in_bambuddy`: run `/sync/filament/spools?dry_run=true`, then disable dry-run when the generated spool data is correct.
- Filament usage stays `pending`: the Bambuddy spool is not linked to an InvenTree batch code in `tag_uid`, or the matching InvenTree stock item is missing.
- Location moves do not happen: check `FILAMENT_PRINTER_LOCATION_MAP` and Bambuddy spool assignments.
## Backups