Grotti 3.7.0: Treiber für Kobra 4 und Marlin, smartere Dateien-Auswahl und einstellbare Etiketten.
Senden und Abbruch laufen über den Treiber, Orca-Doppelzeilen und tote Ideen-API fallen weg, Drucker folgen der Datei, Etikettenformat liegt in den Einstellungen.
This commit is contained in:
1 parent
5081212212
commit
db6a85a703
54 files changed
+3379
-384
No files matched your search
@@ -0,0 +1,128 @@
|
||||
"""Treiberwahl und die LAN-Karte. Kein echter Drucker."""
|
||||
|
||||
import sys
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
from unittest import mock
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
sys.path.insert(0, str(ROOT))
|
||||
|
||||
from grotti.drivers import for_printer
|
||||
from grotti.drivers.anycubic_lan import card_from_info, slots_from_report
|
||||
from grotti.moonraker import PrinterError
|
||||
from grotti.printers import family_from_name
|
||||
|
||||
|
||||
class FamilyTests(unittest.TestCase):
|
||||
def test_existing_names_stay_moonraker(self):
|
||||
for name, family in (
|
||||
("Kobra 3 A1", "kobra_3"),
|
||||
("Kobra S1", "kobra_s1"),
|
||||
):
|
||||
self.assertEqual(family_from_name(name), family)
|
||||
drv = for_printer({"name": name, "family": family, "host": "10.0.0.1"})
|
||||
self.assertEqual(drv.transport, "moonraker")
|
||||
self.assertTrue(drv.rinkhals)
|
||||
self.assertFalse(drv.firmware_restart)
|
||||
|
||||
def test_kobra_4_is_lan(self):
|
||||
self.assertEqual(family_from_name("Kobra 4"), "kobra_4")
|
||||
drv = for_printer({"family": "kobra_4", "host": "10.0.0.4"})
|
||||
self.assertEqual(drv.transport, "anycubic_lan")
|
||||
self.assertFalse(drv.rinkhals)
|
||||
|
||||
def test_i3_is_marlin(self):
|
||||
self.assertEqual(family_from_name("Anycubic i3 Mega"), "anycubic_i3")
|
||||
drv = for_printer({"family": "anycubic_i3", "host": "usb"})
|
||||
self.assertEqual(drv.transport, "marlin")
|
||||
|
||||
def test_tenlog_is_marlin_with_two_heads(self):
|
||||
self.assertEqual(family_from_name("Tenlog"), "tenlog")
|
||||
drv = for_printer({"family": "tenlog", "host": "COM5"})
|
||||
self.assertEqual(drv.transport, "marlin")
|
||||
self.assertFalse(drv.rinkhals)
|
||||
|
||||
|
||||
class LanCardTests(unittest.TestCase):
|
||||
def test_busy_with_file_is_printing(self):
|
||||
card = card_from_info({
|
||||
"state": "busy",
|
||||
"temp": {"curr_nozzle_temp": 210, "curr_hotbed_temp": 60},
|
||||
"project": {"filename": "teil.gcode", "progress": 40, "curr_layer": 3, "total_layers": 10},
|
||||
})
|
||||
self.assertEqual(card["state"], "printing")
|
||||
self.assertEqual(card["filename"], "teil.gcode")
|
||||
self.assertAlmostEqual(card["progress"], 0.4)
|
||||
self.assertEqual(card["nozzle"], 210)
|
||||
self.assertEqual(card["layer"], 3)
|
||||
self.assertFalse(card["has_camera"])
|
||||
self.assertIsNone(card["mesh"])
|
||||
|
||||
def test_free_is_standby(self):
|
||||
card = card_from_info({"state": "free", "project": None})
|
||||
self.assertEqual(card["state"], "standby")
|
||||
self.assertEqual(card["filename"], "")
|
||||
|
||||
def test_slots_from_boxes(self):
|
||||
slots = slots_from_report({
|
||||
"multi_color_box": [{
|
||||
"slots": [
|
||||
{"type": "PETG"},
|
||||
{"type": "PLA"},
|
||||
{"type": ""},
|
||||
{"type": "ABS"},
|
||||
],
|
||||
}],
|
||||
})
|
||||
self.assertEqual([item["type"] for item in slots], ["PETG", "PLA", "ABS"])
|
||||
self.assertEqual([item["index"] for item in slots], [0, 1, 3])
|
||||
|
||||
|
||||
class LanUploadTests(unittest.TestCase):
|
||||
def test_posts_filename_and_gcode(self):
|
||||
captured = {}
|
||||
|
||||
class Response:
|
||||
def __enter__(self):
|
||||
return self
|
||||
|
||||
def __exit__(self, *args):
|
||||
return False
|
||||
|
||||
def read(self):
|
||||
return b"{}"
|
||||
|
||||
def fake_urlopen(request, timeout=0):
|
||||
captured["url"] = request.full_url
|
||||
captured["body"] = request.data
|
||||
captured["length"] = request.headers["X-file-length"]
|
||||
return Response()
|
||||
|
||||
info = {"urls": {"fileUploadurl": "http://10.0.0.4:18910/gcode_upload?s=token"}}
|
||||
drv = for_printer({"family": "kobra_4", "host": "10.0.0.4"})
|
||||
with mock.patch("grotti.anycubic_lan.print_info", return_value=info), \
|
||||
mock.patch("urllib.request.urlopen", fake_urlopen):
|
||||
name = drv.upload("10.0.0.4", "teil.gcode", b"G1 X1")
|
||||
self.assertEqual(name, "teil.gcode")
|
||||
self.assertIn("/gcode_upload", captured["url"])
|
||||
self.assertIn(b'name="filename"', captured["body"])
|
||||
self.assertIn(b'name="gcode"', captured["body"])
|
||||
self.assertIn(b"G1 X1", captured["body"])
|
||||
self.assertEqual(captured["length"], "5")
|
||||
|
||||
def test_missing_url(self):
|
||||
drv = for_printer({"family": "kobra_4"})
|
||||
with mock.patch("grotti.anycubic_lan.print_info", return_value={"urls": {}}):
|
||||
with self.assertRaises(PrinterError):
|
||||
drv.upload("10.0.0.4", "teil.gcode", b"G1")
|
||||
|
||||
|
||||
class MarlinStubTests(unittest.TestCase):
|
||||
def test_start_says_service_missing(self):
|
||||
drv = for_printer({"family": "anycubic_i3", "name": "i3", "host": "COM3"})
|
||||
cards = drv.snapshot([{"name": "i3", "host": "COM3", "family": "anycubic_i3"}])
|
||||
self.assertEqual(cards[0]["state"], "offline")
|
||||
self.assertIn("läuft nicht", cards[0]["message"])
|
||||
with self.assertRaises(PrinterError):
|
||||
drv.start_print("COM3", "teil.gcode")
|
||||
Reference in new issue
Block a user