printer list ref
This commit is contained in:
parent
30a3458762
commit
8e2aaae7ec
1 changed files with 92 additions and 21 deletions
|
|
@ -14,8 +14,9 @@ from ....registry import register_class
|
||||||
from .base import ExecSliceNode, SliceNode, SliceNodeJoiner, SlicingCollection, SlicingGroup
|
from .base import ExecSliceNode, SliceNode, SliceNodeJoiner, SlicingCollection, SlicingGroup
|
||||||
|
|
||||||
@register_class
|
@register_class
|
||||||
class SLICENODE_PrinterList(SliceNode):
|
class SLICENODE_PrinterList(ExecSliceNode):
|
||||||
bl_label = "Printer List"
|
bl_label = "Printer List"
|
||||||
|
button_label = "Start Prints"
|
||||||
|
|
||||||
def _refresh(self):
|
def _refresh(self):
|
||||||
import json
|
import json
|
||||||
|
|
@ -38,22 +39,18 @@ class SLICENODE_PrinterList(SliceNode):
|
||||||
for p_data in printers:
|
for p_data in printers:
|
||||||
name = p_data.get("name", "Unknown")
|
name = p_data.get("name", "Unknown")
|
||||||
printer_names.add(name)
|
printer_names.add(name)
|
||||||
sock = self.outputs.get(name)
|
sock = self.inputs.get(name)
|
||||||
if not sock:
|
if not sock:
|
||||||
sock = self.add_output("SLICESOCK_Printer", name)
|
self.add_input("SLICESOCK_GcodeRo", name)
|
||||||
|
|
||||||
# Update properties
|
# Remove stale input sockets
|
||||||
sock.label = name
|
for sock in list(self.inputs):
|
||||||
sock.host = str(p_data.get("ip", "localhost"))
|
|
||||||
sock.port = int(p_data.get("port", 80))
|
|
||||||
sock.prefix = str(p_data.get("prefix", ""))
|
|
||||||
sock.username = str(p_data.get("username", ""))
|
|
||||||
sock.password = str(p_data.get("password", ""))
|
|
||||||
sock.host_type = str(p_data.get("host_type", "PRUSALINK")).upper()
|
|
||||||
|
|
||||||
# Remove stale sockets
|
|
||||||
for sock in list(self.outputs):
|
|
||||||
if sock.name not in printer_names:
|
if sock.name not in printer_names:
|
||||||
|
self.inputs.remove(sock)
|
||||||
|
|
||||||
|
# Remove stale output sockets (except Execution Link)
|
||||||
|
for sock in list(self.outputs):
|
||||||
|
if sock.name != "Execution Link":
|
||||||
self.outputs.remove(sock)
|
self.outputs.remove(sock)
|
||||||
|
|
||||||
def update_config(self, context):
|
def update_config(self, context):
|
||||||
|
|
@ -62,17 +59,91 @@ class SLICENODE_PrinterList(SliceNode):
|
||||||
printers_json_path: NfStringProperty(name="Config File", default="", subtype='FILE_PATH', update=update_config) # pyright: ignore[reportInvalidTypeForm]
|
printers_json_path: NfStringProperty(name="Config File", default="", subtype='FILE_PATH', update=update_config) # pyright: ignore[reportInvalidTypeForm]
|
||||||
|
|
||||||
def init(self, context):
|
def init(self, context):
|
||||||
pass
|
self._init_exec()
|
||||||
|
|
||||||
def draw_buttons(self, context, layout):
|
def draw_buttons(self, context, layout):
|
||||||
layout.prop(self, "printers_json_path") # pyright: ignore[reportOptionalMemberAccess]
|
super().draw_buttons(context, layout)
|
||||||
|
layout.prop(self, "printers_json_path")
|
||||||
|
|
||||||
def evaluate_output(self, socket_name: str, **_kwargs) -> Any:
|
def evaluate(self, operator=None):
|
||||||
|
import json
|
||||||
|
from ....infra.networking.printer_backends import (
|
||||||
|
PrusaLinkBackend,
|
||||||
|
CrealityBackend,
|
||||||
|
MoonrakerBackend
|
||||||
|
)
|
||||||
|
|
||||||
self._refresh()
|
self._refresh()
|
||||||
sock = self.outputs.get(socket_name)
|
|
||||||
if sock:
|
if not self.printers_json_path:
|
||||||
return sock.value
|
if operator: operator.report({'ERROR'}, "No Config File path provided")
|
||||||
return None
|
return 'error'
|
||||||
|
|
||||||
|
abs_path = bpy.path.abspath(self.printers_json_path)
|
||||||
|
if not os.path.exists(abs_path):
|
||||||
|
if operator: operator.report({'ERROR'}, f"Config file not found: {abs_path}")
|
||||||
|
return 'error'
|
||||||
|
|
||||||
|
try:
|
||||||
|
with open(abs_path, 'r', encoding='utf-8') as f:
|
||||||
|
data = json.load(f)
|
||||||
|
except Exception as e:
|
||||||
|
if operator: operator.report({'ERROR'}, f"Failed to read config file: {str(e)}")
|
||||||
|
return 'error'
|
||||||
|
|
||||||
|
printers = data.get("printers", [])
|
||||||
|
printer_configs = {p.get("name", "Unknown"): p for p in printers}
|
||||||
|
|
||||||
|
any_printed = False
|
||||||
|
for sock in self.inputs:
|
||||||
|
if sock.name not in printer_configs:
|
||||||
|
continue
|
||||||
|
|
||||||
|
gcode = self.resolve(sock.name)
|
||||||
|
if not gcode:
|
||||||
|
continue
|
||||||
|
|
||||||
|
p_data = printer_configs[sock.name]
|
||||||
|
host = str(p_data.get("ip", "localhost"))
|
||||||
|
port = int(p_data.get("port", 80))
|
||||||
|
prefix = str(p_data.get("prefix", ""))
|
||||||
|
password = str(p_data.get("password", ""))
|
||||||
|
host_type = str(p_data.get("host_type", "PRUSALINK")).upper()
|
||||||
|
|
||||||
|
# Instantiate backend
|
||||||
|
backend = None
|
||||||
|
if host_type == 'PRUSALINK':
|
||||||
|
backend = PrusaLinkBackend(host, port, prefix, api_key=password)
|
||||||
|
elif host_type == 'CREALITY':
|
||||||
|
backend = CrealityBackend(host, port, prefix)
|
||||||
|
elif host_type == 'MOONRAKER':
|
||||||
|
backend = MoonrakerBackend(host, port, prefix)
|
||||||
|
|
||||||
|
if not backend:
|
||||||
|
if operator: operator.report({'ERROR'}, f"Unsupported host type {host_type} for printer {sock.name}")
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Write to temp file to send
|
||||||
|
with tempfile.NamedTemporaryFile(mode='w', suffix='.gcode', delete=False) as tf:
|
||||||
|
tf.write(gcode)
|
||||||
|
temp_path = Path(tf.name)
|
||||||
|
|
||||||
|
try:
|
||||||
|
print_name = f"NodeSlicer_{sock.name}.gcode".replace(" ", "_")
|
||||||
|
backend.start_print(temp_path, print_name)
|
||||||
|
if operator: operator.report({'INFO'}, f"Print started on {sock.name}")
|
||||||
|
any_printed = True
|
||||||
|
except Exception as e:
|
||||||
|
if operator: operator.report({'ERROR'}, f"Failed to start print on {sock.name}: {str(e)}")
|
||||||
|
finally:
|
||||||
|
if temp_path.exists():
|
||||||
|
temp_path.unlink()
|
||||||
|
|
||||||
|
if not any_printed:
|
||||||
|
if operator: operator.report({'WARNING'}, "No Gcode was sent to any printer")
|
||||||
|
return 'no gcode'
|
||||||
|
|
||||||
|
return 'ok'
|
||||||
|
|
||||||
@register_class
|
@register_class
|
||||||
class SLICENODE_PrusaslicerSlice(SliceNode):
|
class SLICENODE_PrusaslicerSlice(SliceNode):
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue