Files
xenia-pos-local/local_backend/print_codepage_probe.py
bonamin 34ae328b0d feat: bump client-services (accumulated feature work + deploy fixes)
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>
2026-07-19 10:00:14 +03:00

115 lines
4.1 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
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()