2024-12-12 23:05:19 +01:00
|
|
|
import json
|
2024-12-13 11:44:00 +01:00
|
|
|
import traceback
|
2024-12-12 23:05:19 +01:00
|
|
|
import uuid
|
|
|
|
|
2024-12-15 03:38:50 +01:00
|
|
|
from flask import Flask, request, render_template, redirect, url_for
|
2024-12-12 23:05:19 +01:00
|
|
|
|
2024-12-15 19:34:45 +01:00
|
|
|
from config import BASE_URL, AUTO_SPEND, SPOOLMAN_BASE_URL
|
2024-12-12 23:05:19 +01:00
|
|
|
from filament import generate_filament_brand_code, generate_filament_temperatures
|
2024-12-15 03:38:50 +01:00
|
|
|
from frontend_utils import color_is_dark
|
2024-12-12 23:05:19 +01:00
|
|
|
from messages import AMS_FILAMENT_SETTING
|
2024-12-13 11:01:41 +01:00
|
|
|
from mqtt_bambulab import fetchSpools, getLastAMSConfig, publish, getMqttClient, setActiveTray
|
|
|
|
from spoolman_client import patchExtraTags, getSpoolById
|
2024-12-15 03:38:50 +01:00
|
|
|
from spoolman_service import augmentTrayDataWithSpoolMan, trayUid
|
2024-12-12 23:05:19 +01:00
|
|
|
|
|
|
|
app = Flask(__name__)
|
|
|
|
|
2024-12-22 23:32:58 +01:00
|
|
|
EXTERNAL_SPOOL_AMS_ID = 255
|
|
|
|
|
2024-12-15 19:34:45 +01:00
|
|
|
@app.context_processor
|
|
|
|
def fronted_utilities():
|
2024-12-22 23:32:58 +01:00
|
|
|
return dict(SPOOLMAN_BASE_URL=SPOOLMAN_BASE_URL, AUTO_SPEND=AUTO_SPEND, color_is_dark=color_is_dark, BASE_URL=BASE_URL, EXTERNAL_SPOOL_AMS_ID=EXTERNAL_SPOOL_AMS_ID)
|
|
|
|
|
|
|
|
@app.route("/issue")
|
|
|
|
def issue():
|
|
|
|
return render_template('issue.html')
|
|
|
|
|
|
|
|
@app.route("/fill")
|
|
|
|
def fill():
|
|
|
|
ams_id = request.args.get("ams")
|
|
|
|
tray_id = request.args.get("tray")
|
|
|
|
if not all([ams_id, tray_id]):
|
|
|
|
return "Missing AMS ID, or Tray ID."
|
|
|
|
|
|
|
|
spool_id = request.args.get("spool_id")
|
|
|
|
if spool_id:
|
|
|
|
spool_data = getSpoolById(spool_id)
|
|
|
|
setActiveTray(spool_id, spool_data["extra"], ams_id, tray_id)
|
|
|
|
setActiveSpool(ams_id, tray_id, spool_data)
|
|
|
|
return redirect(url_for('home', success_message=f"Updated Spool ID {spool_id} to AMS {ams_id}, Tray {tray_id}."))
|
|
|
|
else:
|
|
|
|
spools = fetchSpools()
|
|
|
|
return render_template('fill.html', spools=spools, ams_id=ams_id, tray_id=tray_id)
|
2024-12-15 19:34:45 +01:00
|
|
|
|
2024-12-12 23:05:19 +01:00
|
|
|
@app.route("/spool_info")
|
|
|
|
def spool_info():
|
2024-12-15 03:38:50 +01:00
|
|
|
try:
|
|
|
|
tag_id = request.args.get("tag_id")
|
|
|
|
|
|
|
|
last_ams_config = getLastAMSConfig()
|
|
|
|
ams_data = last_ams_config.get("ams", [])
|
|
|
|
vt_tray_data = last_ams_config.get("vt_tray", {})
|
2024-12-12 23:05:19 +01:00
|
|
|
|
2024-12-15 03:38:50 +01:00
|
|
|
print(ams_data)
|
|
|
|
print(vt_tray_data)
|
|
|
|
|
|
|
|
if not tag_id:
|
|
|
|
return "TAG ID is required as a query parameter (e.g., ?tagid=RFID123)"
|
|
|
|
|
|
|
|
spools = fetchSpools()
|
|
|
|
current_spool = None
|
|
|
|
for spool in spools:
|
|
|
|
if not spool.get("extra", {}).get("tag"):
|
|
|
|
continue
|
|
|
|
tag = json.loads(spool["extra"]["tag"])
|
|
|
|
if tag != tag_id:
|
|
|
|
continue
|
|
|
|
current_spool = spool
|
|
|
|
|
|
|
|
# TODO: missing current_spool
|
2024-12-15 19:34:45 +01:00
|
|
|
return render_template('spool_info.html', tag_id=tag_id, current_spool=current_spool, ams_data=ams_data, vt_tray_data=vt_tray_data)
|
2024-12-15 03:38:50 +01:00
|
|
|
except Exception as e:
|
|
|
|
traceback.print_exc()
|
|
|
|
return render_template('error.html', exception=str(e))
|
2024-12-12 23:05:19 +01:00
|
|
|
|
2024-12-13 11:01:41 +01:00
|
|
|
|
2024-12-12 23:05:19 +01:00
|
|
|
@app.route("/tray_load")
|
|
|
|
def tray_load():
|
|
|
|
tag_id = request.args.get("tag_id")
|
|
|
|
ams_id = request.args.get("ams")
|
|
|
|
tray_id = request.args.get("tray")
|
|
|
|
spool_id = request.args.get("spool_id")
|
|
|
|
|
|
|
|
if not all([tag_id, ams_id, tray_id, spool_id]):
|
|
|
|
return "Missing RFID, AMS ID, or Tray ID or spool_id."
|
|
|
|
|
|
|
|
try:
|
|
|
|
# Update Spoolman with the selected tray
|
2024-12-13 11:01:41 +01:00
|
|
|
spool_data = getSpoolById(spool_id)
|
|
|
|
setActiveTray(spool_id, spool_data["extra"], ams_id, tray_id)
|
2024-12-22 23:32:58 +01:00
|
|
|
setActiveSpool(ams_id, tray_id, spool_data)
|
2024-12-12 23:05:19 +01:00
|
|
|
|
2024-12-15 03:38:50 +01:00
|
|
|
return redirect(url_for('home', success_message=f"Updated Spool ID {spool_id} with TAG id {tag_id} to AMS {ams_id}, Tray {tray_id}."))
|
2024-12-12 23:05:19 +01:00
|
|
|
except Exception as e:
|
2024-12-13 11:44:00 +01:00
|
|
|
traceback.print_exc()
|
2024-12-15 03:38:50 +01:00
|
|
|
return render_template('error.html', exception=str(e))
|
2024-12-12 23:05:19 +01:00
|
|
|
|
2024-12-22 23:32:58 +01:00
|
|
|
def setActiveSpool(ams_id, tray_id, spool_data):
|
|
|
|
ams_message = AMS_FILAMENT_SETTING
|
|
|
|
ams_message["print"]["sequence_id"] = 0
|
|
|
|
ams_message["print"]["ams_id"] = int(ams_id)
|
|
|
|
ams_message["print"]["tray_id"] = int(tray_id)
|
|
|
|
ams_message["print"]["tray_color"] = spool_data["filament"]["color_hex"].upper() + "FF"
|
|
|
|
|
|
|
|
if "nozzle_temperature" in spool_data["filament"]["extra"]:
|
|
|
|
nozzle_temperature_range = spool_data["filament"]["extra"]["nozzle_temperature"].strip("[]").split(",")
|
|
|
|
ams_message["print"]["nozzle_temp_min"] = int(nozzle_temperature_range[0])
|
|
|
|
ams_message["print"]["nozzle_temp_max"] = int(nozzle_temperature_range[1])
|
|
|
|
else:
|
|
|
|
nozzle_temperature_range_obj = generate_filament_temperatures(spool_data["filament"]["material"],
|
|
|
|
spool_data["filament"]["vendor"]["name"])
|
|
|
|
ams_message["print"]["nozzle_temp_min"] = int(nozzle_temperature_range_obj["filament_min_temp"])
|
|
|
|
ams_message["print"]["nozzle_temp_max"] = int(nozzle_temperature_range_obj["filament_max_temp"])
|
|
|
|
|
|
|
|
ams_message["print"]["tray_type"] = spool_data["filament"]["material"]
|
|
|
|
filament_brand_code = generate_filament_brand_code(spool_data["filament"]["material"],
|
|
|
|
spool_data["filament"]["vendor"]["name"],
|
|
|
|
spool_data["filament"]["extra"].get("type", ""))
|
|
|
|
ams_message["print"]["tray_info_idx"] = filament_brand_code["brand_code"]
|
|
|
|
|
|
|
|
# TODO: test sub_brand_code
|
|
|
|
# ams_message["print"]["tray_sub_brands"] = filament_brand_code["sub_brand_code"]
|
|
|
|
ams_message["print"]["tray_sub_brands"] = ""
|
|
|
|
|
|
|
|
print(ams_message)
|
|
|
|
publish(getMqttClient(), ams_message)
|
2024-12-13 11:01:41 +01:00
|
|
|
|
2024-12-12 23:05:19 +01:00
|
|
|
@app.route("/")
|
|
|
|
def home():
|
|
|
|
try:
|
|
|
|
last_ams_config = getLastAMSConfig()
|
|
|
|
ams_data = last_ams_config.get("ams", [])
|
|
|
|
vt_tray_data = last_ams_config.get("vt_tray", {})
|
2024-12-15 03:38:50 +01:00
|
|
|
spool_list = fetchSpools()
|
|
|
|
success_message = request.args.get("success_message")
|
2024-12-12 23:05:19 +01:00
|
|
|
|
2024-12-15 03:38:50 +01:00
|
|
|
issue = False
|
2024-12-22 23:32:58 +01:00
|
|
|
#TODO: Fix issue when external spool info is reset via bambulab interface
|
|
|
|
augmentTrayDataWithSpoolMan(spool_list, vt_tray_data, trayUid(EXTERNAL_SPOOL_AMS_ID, vt_tray_data["id"]))
|
2024-12-15 03:38:50 +01:00
|
|
|
issue |= vt_tray_data["issue"]
|
2024-12-12 23:05:19 +01:00
|
|
|
|
|
|
|
for ams in ams_data:
|
|
|
|
for tray in ams["tray"]:
|
2024-12-15 03:38:50 +01:00
|
|
|
augmentTrayDataWithSpoolMan(spool_list, tray, trayUid(ams["id"], tray["id"]))
|
|
|
|
issue |= tray["issue"]
|
|
|
|
|
2024-12-15 19:34:45 +01:00
|
|
|
return render_template('index.html', success_message=success_message, ams_data=ams_data, vt_tray_data=vt_tray_data, issue=issue)
|
2024-12-12 23:05:19 +01:00
|
|
|
except Exception as e:
|
2024-12-13 11:44:00 +01:00
|
|
|
traceback.print_exc()
|
2024-12-15 03:38:50 +01:00
|
|
|
return render_template('error.html', exception=str(e))
|
2024-12-13 11:01:41 +01:00
|
|
|
|
2024-12-22 23:32:58 +01:00
|
|
|
def sort_spools(spools):
|
|
|
|
def condition(item):
|
|
|
|
# Ensure the item has an "extra" key and is a dictionary
|
|
|
|
if not isinstance(item, dict) or "extra" not in item or not isinstance(item["extra"], dict):
|
|
|
|
return False
|
|
|
|
|
|
|
|
# Check the specified condition
|
|
|
|
return item["extra"].get("tag") or item["extra"].get("tag") == ""
|
|
|
|
|
|
|
|
# Sort with the custom condition: False values come first
|
|
|
|
return sorted(spools, key=lambda spool: bool(condition(spool)))
|
|
|
|
|
2024-12-12 23:05:19 +01:00
|
|
|
@app.route("/assign_tag")
|
|
|
|
def assign_tag():
|
2024-12-15 03:38:50 +01:00
|
|
|
try:
|
2024-12-22 23:32:58 +01:00
|
|
|
spools = sort_spools(fetchSpools())
|
2024-12-15 03:38:50 +01:00
|
|
|
|
|
|
|
return render_template('assign_tag.html', spools=spools)
|
|
|
|
except Exception as e:
|
|
|
|
traceback.print_exc()
|
|
|
|
return render_template('error.html', exception=str(e))
|
|
|
|
|
|
|
|
@app.route("/write_tag")
|
|
|
|
def write_tag():
|
|
|
|
try:
|
|
|
|
spool_id = request.args.get("spool_id")
|
2024-12-12 23:05:19 +01:00
|
|
|
|
2024-12-15 03:38:50 +01:00
|
|
|
if not spool_id:
|
|
|
|
return "spool ID is required as a query parameter (e.g., ?spool_id=1)"
|
2024-12-12 23:05:19 +01:00
|
|
|
|
2024-12-15 03:38:50 +01:00
|
|
|
myuuid = str(uuid.uuid4())
|
|
|
|
|
|
|
|
patchExtraTags(spool_id, {}, {
|
|
|
|
"tag": json.dumps(myuuid),
|
|
|
|
})
|
2024-12-15 19:34:45 +01:00
|
|
|
return render_template('write_tag.html', myuuid=myuuid)
|
2024-12-15 03:38:50 +01:00
|
|
|
except Exception as e:
|
|
|
|
traceback.print_exc()
|
|
|
|
return render_template('error.html', exception=str(e))
|
2024-12-13 11:01:41 +01:00
|
|
|
|
2024-12-12 23:05:19 +01:00
|
|
|
@app.route('/', methods=['GET'])
|
|
|
|
def health():
|
|
|
|
return "OK", 200
|