diff --git a/README.md b/README.md index 5a597dc7..18521578 100644 --- a/README.md +++ b/README.md @@ -174,7 +174,9 @@ SpoolMan can print QR-code stickers for every spool; follow the SpoolMan label g - set `PRINTER_ID` — find it in the printer settings under Setting → Device → Printer SN. - set `PRINTER_ACCESS_CODE` — find it in Setting → LAN Only Mode → Access Code (the LAN Only Mode toggle may stay off). - set `PRINTER_IP` — found in Setting → LAN Only Mode → IP Address. - - set `SPOOLMAN_BASE_URL` — the URL of your SpoolMan installation without trailing slash. + - set `SPOOLMAN_BASE_URL` — the URL of your SpoolMan installation without trailing slash. Used for UI links (menu, spool detail pages) and as the default for API calls when `SPOOLMAN_API_URL` is not set. + - set `SPOOLMAN_UI_URL` *(optional)* — semantic alias for `SPOOLMAN_BASE_URL`; either variable satisfies the requirement. If both are set, `SPOOLMAN_BASE_URL` takes precedence. + - set `SPOOLMAN_API_URL` *(optional)* — the URL OpenSpoolMan uses for backend API calls to SpoolMan (without trailing slash). Defaults to `SPOOLMAN_BASE_URL`. Useful for reverse-proxy / split-horizon setups where the container reaches SpoolMan via internal DNS (e.g. `http://spoolman:8000`) while the browser needs a public hostname (e.g. `https://spoolman.example.com`). - set `AUTO_SPEND` to `True` to enable legacy slicer-estimate tracking (no live layer tracking). - set `TRACK_LAYER_USAGE` to `True` to switch to per-layer tracking/consumption **while `AUTO_SPEND` is also `True`**. If `AUTO_SPEND` is `False`, all filament tracking remains disabled regardless of `TRACK_LAYER_USAGE`. - set `AUTO_SPEND` to `True` if you want automatic filament usage tracking (see the AUTO SPEND notes below). diff --git a/config.env.template b/config.env.template index ba26bfa2..c8060783 100644 --- a/config.env.template +++ b/config.env.template @@ -6,7 +6,11 @@ PRINTER_IP= PRINTER_NAME= SPOOLMAN_BASE_URL= AUTO_SPEND=False -TRACK_LAYER_USAGE=False -SPOOL_SORTING=filament.material:asc,filament.vendor.name:asc,filament.name:asc -CLEAR_ASSIGNMENT_WHEN_EMPTY=False -COLOR_DISTANCE_TOLERANCE=40 +TRACK_LAYER_USAGE=False +SPOOL_SORTING=filament.material:asc,filament.vendor.name:asc,filament.name:asc +CLEAR_ASSIGNMENT_WHEN_EMPTY=False +COLOR_DISTANCE_TOLERANCE=40 + +# Allow API and UI URLs to differ (reverse-proxy friendly) +# SPOOLMAN_UI_URL= # Semantic alias for SPOOLMAN_BASE_URL +# SPOOLMAN_API_URL=http://spoolman:8000 # The Backend reaches Spoolman via internal Docker DNS diff --git a/config.py b/config.py index ca30dadd..3eff41c0 100644 --- a/config.py +++ b/config.py @@ -35,8 +35,9 @@ def _env_to_int(name: str, default: int) -> int: PRINTER_CODE = os.getenv("PRINTER_ACCESS_CODE") # Printer access code - Run init_bambulab.py PRINTER_IP = os.getenv("PRINTER_IP") # Printer local IP address - Check wireless on printer PRINTER_NAME = os.getenv("PRINTER_NAME") # Printer name - Check wireless on printer -SPOOLMAN_BASE_URL = os.getenv("SPOOLMAN_BASE_URL") -SPOOLMAN_API_URL = f"{SPOOLMAN_BASE_URL}/api/v1" +SPOOLMAN_BASE_URL = os.getenv("SPOOLMAN_BASE_URL") or os.getenv("SPOOLMAN_UI_URL") +SPOOLMAN_API_URL = os.getenv("SPOOLMAN_API_URL") or SPOOLMAN_BASE_URL +SPOOLMAN_API_V1 = f"{SPOOLMAN_API_URL}/api/v1" AUTO_SPEND = _env_to_bool("AUTO_SPEND", False) TRACK_LAYER_USAGE = _env_to_bool("TRACK_LAYER_USAGE", False) SPOOL_SORTING = os.getenv( diff --git a/spoolman_client.py b/spoolman_client.py index 7c8b51a0..acd47ac6 100644 --- a/spoolman_client.py +++ b/spoolman_client.py @@ -1,5 +1,5 @@ import requests -from config import SPOOLMAN_API_URL, SPOOL_SORTING +from config import SPOOLMAN_API_V1, SPOOL_SORTING import json from logger import append_to_rotating_file, log @@ -31,7 +31,7 @@ def patchExtraTags(spool_id, old_extras, new_extras): for key, value in new_extras.items(): old_extras[key] = value - resp = requests.patch(f"{SPOOLMAN_API_URL}/spool/{spool_id}", json={ + resp = requests.patch(f"{SPOOLMAN_API_V1}/spool/{spool_id}", json={ "extra": old_extras }) _log_spoolman_change( @@ -45,27 +45,27 @@ def patchExtraTags(spool_id, old_extras, new_extras): def getSpoolById(spool_id): - response = requests.get(f"{SPOOLMAN_API_URL}/spool/{spool_id}") - #print(response.status_code) - #print(response.text) - return response.json() - - -def fetchSpoolList(): - if SPOOL_SORTING: - response = requests.get(f"{SPOOLMAN_API_URL}/spool?sort={SPOOL_SORTING}") - else: - response = requests.get(f"{SPOOLMAN_API_URL}/spool") - - #print(response.status_code) - #print(response.text) - return response.json() - -def consumeSpool(spool_id, use_weight=None, use_length=None): - if use_weight is None and use_length is None: - raise ValueError("use_weight or use_length is required") - - payload = {} + response = requests.get(f"{SPOOLMAN_API_V1}/spool/{spool_id}") + #print(response.status_code) + #print(response.text) + return response.json() + + +def fetchSpoolList(): + if SPOOL_SORTING: + response = requests.get(f"{SPOOLMAN_API_V1}/spool?sort={SPOOL_SORTING}") + else: + response = requests.get(f"{SPOOLMAN_API_V1}/spool") + + #print(response.status_code) + #print(response.text) + return response.json() + +def consumeSpool(spool_id, use_weight=None, use_length=None): + if use_weight is None and use_length is None: + raise ValueError("use_weight or use_length is required") + + payload = {} if use_weight is not None: payload["use_weight"] = use_weight if use_length is not None: @@ -73,7 +73,7 @@ def consumeSpool(spool_id, use_weight=None, use_length=None): log(f'Consuming {payload} from spool {spool_id}') - response = requests.put(f"{SPOOLMAN_API_URL}/spool/{spool_id}/use", json=payload) + response = requests.put(f"{SPOOLMAN_API_V1}/spool/{spool_id}/use", json=payload) _log_spoolman_change( "consume_spool", spool_id=spool_id, @@ -82,25 +82,25 @@ def consumeSpool(spool_id, use_weight=None, use_length=None): ) #print(response.status_code) #print(response.text) - -def fetchSettings(): - response = requests.get(f"{SPOOLMAN_API_URL}/setting/") - #print(response.status_code) - #print(response.text) - - # JSON in ein Python-Dictionary laden - data = response.json() - - # Extrahiere die Werte aus den relevanten Feldern - extra_fields_spool = json.loads(data["extra_fields_spool"]["value"]) - extra_fields_filament = json.loads(data["extra_fields_filament"]["value"]) - base_url = data["base_url"]["value"] - currency = data["currency"]["value"] - - settings = {} - settings["extra_fields_spool"] = extra_fields_spool - settings["extra_fields_filament"] = extra_fields_filament - settings["base_url"] = base_url.replace('"', '') - settings["currency"] = currency.replace('"', '') - + +def fetchSettings(): + response = requests.get(f"{SPOOLMAN_API_V1}/setting/") + #print(response.status_code) + #print(response.text) + + # JSON in ein Python-Dictionary laden + data = response.json() + + # Extrahiere die Werte aus den relevanten Feldern + extra_fields_spool = json.loads(data["extra_fields_spool"]["value"]) + extra_fields_filament = json.loads(data["extra_fields_filament"]["value"]) + base_url = data["base_url"]["value"] + currency = data["currency"]["value"] + + settings = {} + settings["extra_fields_spool"] = extra_fields_spool + settings["extra_fields_filament"] = extra_fields_filament + settings["base_url"] = base_url.replace('"', '') + settings["currency"] = currency.replace('"', '') + return settings