Загрузка данных


#!/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)