Загрузка данных
#!/usr/bin/env python3
"""
Авто-подборщик для мини-принтеров Jieli (Phomemo, Peripage и др.)
Сканирует USB, перебирает протоколы и пытается напечатать.
"""
import serial
import serial.tools.list_ports
import time
import sys
from typing import Optional, List, Tuple
# Твои VID/PID
TARGET_VID = 0x4C4A
TARGET_PID = 0x4155
# Популярные скорости для таких принтеров
BAUDRATES = [9600, 19200, 38400, 57600, 115200, 230400]
# Тестовые строки в разных кодировках
TEST_MESSAGES = [
b"Hello from Mac!\n\n",
b"\x1b\x40Hello ESC/POS\n\n", # ESC/POS инициализация
b"\x1d\x56\x00\n", # Попытка cut
]
def find_printer() -> Optional[serial.Serial]:
"""Находит принтер по VID/PID и пробует открыть порт"""
ports = serial.tools.list_ports.comports()
for port in ports:
# Проверяем VID/PID
if port.vid == TARGET_VID and port.pid == TARGET_PID:
print(f"[+] Найден принтер: {port.device} ({port.description})")
# Пробуем разные имена портов на Mac
for dev_name in [port.device, f"/dev/cu.{port.name}", f"/dev/tty.{port.name}"]:
for baud in BAUDRATES:
try:
ser = serial.Serial(
dev_name,
baudrate=baud,
bytesize=8,
parity='N',
stopbits=1,
timeout=2,
write_timeout=2
)
if ser.is_open:
print(f"[+] Открыт порт {dev_name} на {baud} бод")
return ser
except:
continue
return None
def test_commands(ser: serial.Serial) -> bool:
"""Перебирает команды для печати"""
# Команды для разных протоколов
cmd_sets = [
# Простой текст (работает на многих)
[b"Test Print\n\n\n"],
# ESC/POS init
[b"\x1b\x40", b"ESC/POS Test\n\n"],
# Jieli native (магия из документации)
[b"\x1b\x40", b"\x1d\x61\x01", b"Jieli native\n\n"],
# Печать как изображение (если поддерживает)
[b"\x1b\x40", b"\x1b\x33\x18", b"Image mode test\n\n"],
# Cut + feed
[b"\x1b\x40", b"Print test\n", b"\x1d\x56\x00"],
[b"\x1b\x40", b"Print test\n", b"\x1d\x56\x41"],
# Некоторые требуют начать с 0x1B 0x40
[b"\x1b\x40", b"Hello ", b"\x1b\x45\x01", b"BOLD", b"\x1b\x45\x00", b" text\n\n"],
]
for i, commands in enumerate(cmd_sets):
try:
print(f"[*] Попытка #{i+1}...", end=" ", flush=True)
# Очищаем буфер
ser.reset_input_buffer()
ser.reset_output_buffer()
# Отправляем команды
for cmd in commands:
ser.write(cmd)
time.sleep(0.1)
# Проверяем ответ (если есть)
response = ser.read(100)
if response:
print(f"получен ответ: {response[:20].hex()}")
else:
print("OK (без ответа)")
print("[!] Если что-то напечаталось - нажмите Ctrl+C для остановки")
time.sleep(3)
return True
except Exception as e:
print(f"ошибка: {e}")
continue
return False
def main():
print("=" * 60)
print("Авто-подборщик для мини-принтера Jieli")
print(f"VID: {TARGET_VID:04X}, PID: {TARGET_PID:04X}")
print("=" * 60)
# Ищем принтер
ser = find_printer()
if not ser:
print("[!] Принтер не найден.")
print("Проверьте:")
print(" 1. Подключён ли кабель")
print(" 2. Нажат ли 'Разрешить' в диалоге macOS")
print(" 3. Работает ли принтер (лампочка горит)")
sys.exit(1)
# Тестируем
print("\n[*] Начинаю перебор протоколов...\n")
success = test_commands(ser)
if success:
print("\n[✓] Тест завершён. Если принтер напечатал - всё работает!")
print(" Теперь можно использовать этот код как основу.")
else:
print("\n[✗] Не удалось напечатать. Возможно:")
print(" - Принтер требует специального протокола (не ESC/POS)")
print(" - Попробуйте библиотеки: peripage, phomemo_printer")
print(" - Напишите модель принтера - помогу точнее")
ser.close()
if __name__ == "__main__":
try:
main()
except KeyboardInterrupt:
print("\n[!] Прервано пользователем")
sys.exit(0)