Snapshot of in-progress work across local_backend, manager_dashboard, and waiter_pwa (pricing, chat, fiscal, prep zones, recovery codes, CRM, inventory, permissions), plus the nginx/docker-compose deploy fixes for the Unraid + NPM reverse-proxy setup. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
115 lines
4.1 KiB
Python
115 lines
4.1 KiB
Python
"""
|
||
Greek code page probe — NETUM NT8330L (or any unknown printer)
|
||
Usage: python print_codepage_probe.py <IP> [PORT]
|
||
Example: python print_codepage_probe.py 192.168.1.50 9100
|
||
|
||
Prints one long receipt that tries every candidate (n, encoding) combination.
|
||
Circle the block where you can read "ΚΑΛΗΜΕΡΑ ΕΛΛΑΔΑ" correctly.
|
||
That block tells you the codepage_n value to use in the printer profile.
|
||
"""
|
||
import sys
|
||
from escpos.printer import Network
|
||
|
||
IP = sys.argv[1] if len(sys.argv) > 1 else "192.168.1.50"
|
||
PORT = int(sys.argv[2]) if len(sys.argv) > 2 else 9100
|
||
|
||
# (n_value, python_encoding, label)
|
||
# Each will be tested independently with a fresh ESC @ reset.
|
||
CANDIDATES = [
|
||
# Standard Epson table assignments for Greek
|
||
(14, "cp737", "n=14 CP737 (Epson standard slot)"),
|
||
(38, "cp737", "n=38 CP737 (alt slot / CP869 area)"),
|
||
(11, "cp737", "n=11 CP737 (CP851 slot)"),
|
||
(47, "cp737", "n=47 CP737 (CP1253 slot, cp737 bytes)"),
|
||
# Same slots but with cp869 encoding (different byte layout)
|
||
(14, "cp869", "n=14 CP869 (Greek DOS #2)"),
|
||
(38, "cp869", "n=38 CP869 (alt slot)"),
|
||
# Windows / ISO encodings
|
||
(47, "cp1253", "n=47 CP1253 (Windows Greek)"),
|
||
(15, "iso8859_7", "n=15 ISO-8859-7"),
|
||
(14, "iso8859_7", "n=14 ISO-8859-7"),
|
||
# The Jolimark value, for reference
|
||
(29, "cp737", "n=29 CP737 (Jolimark confirmed)"),
|
||
# A few more obscure slots some Chinese-made printers use
|
||
(16, "cp737", "n=16 CP737 (rare slot)"),
|
||
(18, "cp737", "n=18 CP737 (rare slot)"),
|
||
(21, "cp737", "n=21 CP737 (rare slot)"),
|
||
]
|
||
|
||
GREEK_SAMPLE = "ΚΑΛΗΜΕΡΑ ΕΛΛΑΔΑ"
|
||
GREEK_LOWER = "καλημέρα ελλάδα"
|
||
GREEK_DIGITS = "ΤΙΜΗ: 12.50 ευρώ"
|
||
|
||
def probe(n: int, encoding: str, label: str):
|
||
try:
|
||
p = Network(IP, PORT, timeout=8)
|
||
p._raw(b'\x1b\x40') # ESC @ full reset
|
||
p._raw(bytes([0x1b, 0x74, n])) # ESC t n — select code page
|
||
|
||
# Label in plain ASCII (always safe)
|
||
p._raw(b'\x1b\x21\x00') # normal size
|
||
p._raw(f"[{label}]\n".encode('ascii', errors='replace'))
|
||
|
||
# Greek sample in the candidate encoding
|
||
try:
|
||
greek_bytes = GREEK_SAMPLE.encode(encoding, errors='replace')
|
||
lower_bytes = GREEK_LOWER.encode(encoding, errors='replace')
|
||
digit_bytes = GREEK_DIGITS.encode(encoding, errors='replace')
|
||
except LookupError:
|
||
p._raw(b' (encoding not available)\n')
|
||
p._raw(b'\n')
|
||
p.close()
|
||
return
|
||
|
||
p._raw(b'\x1b\x21\x08') # bold
|
||
p._raw(greek_bytes + b'\n')
|
||
p._raw(b'\x1b\x21\x00') # normal
|
||
p._raw(lower_bytes + b'\n')
|
||
p._raw(digit_bytes + b'\n')
|
||
p._raw(b'\n') # spacer
|
||
p.close()
|
||
print(f" OK {label}")
|
||
except Exception as e:
|
||
print(f" ERR {label}: {e}")
|
||
|
||
def main():
|
||
print(f"Probing {IP}:{PORT}")
|
||
print(f"Testing {len(CANDIDATES)} combinations...\n")
|
||
|
||
# Print header block
|
||
try:
|
||
p = Network(IP, PORT, timeout=8)
|
||
p._raw(b'\x1b\x40')
|
||
p._raw(b'\x1b\x61\x01') # center
|
||
p._raw(b'\x1b\x21\x30') # double width+height
|
||
p._raw(b'GREEK PROBE\n')
|
||
p._raw(b'\x1b\x21\x00')
|
||
p._raw(b'\x1b\x61\x00') # left
|
||
p._raw(b'Circle the block with readable Greek.\n')
|
||
p._raw(b'Looking for: KALIMERA ELLADA\n')
|
||
p._raw(b'================================================\n')
|
||
p._raw(b'\n')
|
||
p.close()
|
||
except Exception as e:
|
||
print(f"Header failed: {e}")
|
||
return
|
||
|
||
for (n, enc, label) in CANDIDATES:
|
||
probe(n, enc, label)
|
||
|
||
# Footer + cut
|
||
try:
|
||
p = Network(IP, PORT, timeout=8)
|
||
p._raw(b'\x1b\x40')
|
||
p._raw(b'================================================\n')
|
||
p._raw(b'END OF PROBE\n')
|
||
p._raw(b'\n\n\n')
|
||
p.cut()
|
||
p.close()
|
||
print("\nDone. Read the printout and note which block shows readable Greek.")
|
||
except Exception as e:
|
||
print(f"Footer failed: {e}")
|
||
|
||
if __name__ == "__main__":
|
||
main()
|