-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgen_model_db.py
More file actions
115 lines (97 loc) · 4.35 KB
/
Copy pathgen_model_db.py
File metadata and controls
115 lines (97 loc) · 4.35 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
"""Build-time generator for the embedded model database (model_db.py).
Source data: epson_print_conf's PRINTER_CONFIG (EUPL-1.2, (c) Ircama) -- converted
to this project's schema -- PLUS the L3250 family values verified on real hardware.
The output model_db.py is compiled into the .exe, so distribution is a single file.
Run: python gen_model_db.py
"""
import os
import re
import sys
import pprint
HERE = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, os.path.join(HERE, "epson_print_conf"))
import epson_print_conf # noqa: E402
PAD_NAMES = ["Main waste ink pad", "Platen / borderless pad", "Flushing / cleaning pad"]
def norm(name):
n = name.lower().strip()
n = re.sub(r"\bseries\b", "", n)
return re.sub(r"[^a-z0-9]", "", n)
def caesar(write_key):
return [0 if b == 0 else (b + 1) & 0xFF for b in write_key]
def convert(name, cfg):
rk, wk, reset = cfg.get("read_key"), cfg.get("write_key"), cfg.get("raw_waste_reset")
if not rk or not isinstance(wk, (bytes, bytearray)) or not reset:
return None
counters = []
for i, key in enumerate(("main_waste", "borderless_waste", "third_waste")):
w = cfg.get(key)
if w and w.get("oids"):
counters.append({"addresses": list(w["oids"]),
"max": round(w.get("divider", 1) * 100),
"name": PAD_NAMES[i] if i < len(PAD_NAMES) else f"Waste pad {i+1}"})
if not counters:
return None
usage = []
for sname, addrs in (cfg.get("stats") or {}).items():
lst = list(addrs) if isinstance(addrs, (list, tuple, range)) else None
if lst:
# usage value = sum over register-groups; epson_print_conf has one group
usage.append([sname, [[int(a) for a in lst]]])
names = [name] + list(cfg.get("alias", []))
return {
"factory": list(rk),
"keyword": caesar(wk),
"counters": counters,
"reset": [[int(a), int(v)] for a, v in reset.items()],
"usage": usage,
"names": sorted({norm(n) for n in names}),
}
# L3250/L3251/L3253/L3255 — verified on hardware (factory 0x4A36, keyword from
# write-key "Maribaya"; three pads; reset map confirmed to zero the counters).
L3250 = {
"factory": [0x4A, 0x36],
"keyword": caesar(b"Maribaya"),
"counters": [
{"addresses": [0x30, 0x31], "max": 6346, "name": PAD_NAMES[0]},
{"addresses": [0x32, 0x33], "max": 3416, "name": PAD_NAMES[1]},
{"addresses": [0xFC, 0xFD], "max": 1300, "name": PAD_NAMES[2]},
],
"reset": [[0x30, 0], [0x31, 0], [0x2F, 0], [0x34, 0], [0x35, 0], [0x36, 0x5E],
[0x32, 0], [0x33, 0], [0x37, 0x5E], [0x1C, 0],
[0xFC, 0], [0xFD, 0], [0xFE, 0], [0xFF, 0x5E]],
"usage": [
["Manual cleaning counter", [[0x5A]]],
["Timer cleaning counter", [[0x59]]],
["Power cleaning counter", [[0x5B]]],
["Total print pass counter", [[0x85, 0x84, 0x83, 0x82]]],
["Total print page counter", [[0x314, 0x313, 0x312, 0x311],
[0x318, 0x317, 0x316, 0x315],
[0x308, 0x307, 0x306, 0x305]]],
["Total scan counter", [[0x733, 0x732, 0x731, 0x730]]],
],
"names": sorted({norm(n) for n in ["L3250", "L3251", "L3253", "L3255"]}),
}
def main():
printer = epson_print_conf.EpsonPrinter()
config = printer.PRINTER_CONFIG
models = {"L3250": L3250}
for name, cfg in sorted(config.items()):
if not isinstance(cfg, dict) or name == "L3250":
continue
entry = convert(name, cfg)
if entry:
models[name] = entry
out = os.path.join(HERE, "model_db.py")
with open(out, "w", encoding="utf-8") as f:
f.write('"""Embedded Epson model database (generated by gen_model_db.py).\n\n')
f.write("Converted from epson_print_conf (EUPL-1.2, (c) Ircama) plus the L3250\n")
f.write('family verified on hardware. See NOTICE for attribution/licensing.\n"""\n\n')
f.write("MODELS = ")
f.write(pprint.pformat(models, width=100, sort_dicts=True))
f.write("\n")
print(f"Wrote {out} with {len(models)} models.")
# quick sanity for a few important ones
for probe in ("L3250", "L3150", "L3160", "ET-2800", "ET-4700"):
print(f" {probe:10} -> {'present' if probe in models else 'absent'}")
if __name__ == "__main__":
main()