Загрузка данных
#!/usr/bin/env python3
"""
Супер-сканер для любого USB-принтера на Mac
Пробует все порты, все скорости, все команды
"""
import serial
import serial.tools.list_ports
import time
import sys
import os
import glob
from typing import Optional, List
# Все возможные скорости
BAUDRATES = [9600, 19200, 38400, 57600, 115200, 230400, 4800, 2400, 1200]
# Все возможные варианты портов на Mac
PORT_PATTERNS = [
"/dev/cu.usbmodem*",
"/dev/cu.usbserial*",
"/dev/cu.wchusbserial*",
"/dev/cu.SLAB_USBtoUART*",
"/dev/tty.usbmodem*",
"/dev/tty.usbserial*",
"/dev/tty.wchusbserial*",
"/dev/cu.*",
"/dev/tty.*",
]
# Команды для теста (разные протоколы)
COMMAND_SETS = [
# Простой текст
[b"Test\n\n"],
# ESC/POS
[b"\x1b\x40", b"ESC/POS\n\n"],
# ESC/POS с жирным
[b"\x1b\x40", b"\x1b\x45\x01", b"BOLD", b"\x1b\x45\x00", b"\n\n"],
# ESC/POS с выравниванием
[b"\x1b\x40", b"\x1b\x61\x01", b"CENTER\n", b"\x1b\x61\x00", b"\n"],
# Jieli native
[b"\x1b\x40", b"\x1d\x61\x01", b"Jieli\n\n"],
# Просто символы
[b"Hello World!\n\n\n"],
# С обрезкой
[b"\x1b\x40", b"Test\n", b"\x1d\x56\x00"],
# С инициализацией
[b"\x1b\x40", b"\x1b\x33\x18", b"Init test\n\n"],
]
def get_all_ports() -> List[str]:
"""Возвращает все возможные порты"""
ports = []
# 1. Через pyserial
for port in serial.tools.list_ports.comports():
ports.append(port.device)
if hasattr(port, 'name') and port.name:
ports.append(f"/dev/cu.{port.name}")
ports.append(f"/dev/tty.{port.name}")
# 2. Через glob паттерны
for pattern in PORT_PATTERNS:
for port in glob.glob(pattern):
if port not in ports:
ports.append(port)
# 3. Самые популярные имена
common_names = [
"/dev/cu.usbmodem",
"/dev/cu.usbserial",
"/dev/cu.wchusbserial",
"/dev/tty.usbmodem",
"/dev/tty.usbserial",
]
for base in common_names:
for i in range(10):
port = f"{base}{i}"
if os.path.exists(port) and port not in ports:
ports.append(port)
# 4. Ищем любые tty/cu порты
for port in glob.glob("/dev/cu.*"):
if port not in ports:
ports.append(port)
for port in glob.glob("/dev/tty.*"):
if port not in ports:
ports.append(port)
# Фильтруем системные порты
blacklist = ["cu.bluetooth", "cu.Bluetooth", "cu.wlan", "cu.debug", "tty.Bluetooth"]
ports = [p for p in ports if not any(x in p.lower() for x in blacklist)]
return list(dict.fromkeys(ports)) # Убираем дубликаты
def test_port(port: str, baud: int) -> bool:
"""Пробует открыть порт и отправить тестовые команды"""
try:
ser = serial.Serial(
port,
baudrate=baud,
bytesize=8,
parity='N',
stopbits=1,
timeout=1,
write_timeout=1
)
if not ser.is_open:
return False
# Пробуем все команды
for cmd_set in COMMAND_SETS:
try:
ser.reset_input_buffer()
ser.reset_output_buffer()
for cmd in cmd_set:
ser.write(cmd)
time.sleep(0.05)
# Проверяем, есть ли ответ
response = ser.read(10)
if response:
return True
except:
continue
ser.close()
return False
except:
return False
def find_printer() -> Optional[tuple]:
"""Агрессивный поиск принтера"""
ports = get_all_ports()
print(f"[*] Найдено {len(ports)} портов для проверки")
# Показываем порты
for i, port in enumerate(ports[:10]):
print(f" {i+1}. {port}")
if len(ports) > 10:
print(f" ... и еще {len(ports)-10} портов")
print("\n[*] Начинаю сканирование...")
print(" (может занять несколько минут)\n")
tested = 0
for port in ports:
# Проверяем, существует ли порт
if not os.path.exists(port):
continue
for baud in BAUDRATES:
tested += 1
if tested % 20 == 0:
print(f"[*] Проверено {tested} комбинаций...")
try:
if test_port(port, baud):
print(f"\n[+] НАЙДЕНО! Порт: {port}, Скорость: {baud}")
return (port, baud)
except:
continue
print(f"\n[*] Всего проверено {tested} комбинаций")
return None
def interactive_test(port: str, baud: int):
"""Интерактивный тест найденного принтера"""
print("\n" + "="*60)
print(f"[✓] Принтер найден на {port} ({baud} бод)")
print("="*60)
print("\nПробую разные команды печати...")
try:
ser = serial.Serial(port, baudrate=baud, timeout=2, write_timeout=2)
# Пробуем все наборы команд по очереди
for i, cmd_set in enumerate(COMMAND_SETS):
try:
print(f"\n[*] Команда #{i+1}...", end=" ", flush=True)
ser.reset_input_buffer()
ser.reset_output_buffer()
for cmd in cmd_set:
ser.write(cmd)
time.sleep(0.1)
print("ОТПРАВЛЕНО")
print(" (если что-то напечаталось - нажмите Ctrl+C)")
time.sleep(2)
except Exception as e:
print(f"ошибка: {e}")
print("\n" + "="*60)
print("Если ничего не напечаталось, попробуй:")
print("1. Перезагрузи принтер")
print("2. Подключи через другой USB-порт")
print("3. Нажми на принтере кнопку питания дважды")
print("4. Напиши мне модель принтера")
print("="*60)
ser.close()
except Exception as e:
print(f"[!] Ошибка: {e}")
def main():
print("="*70)
print("СУПЕР-СКАНЕР ДЛЯ USB-ПРИНТЕРОВ НА MAC")
print("="*70)
# Проверяем доступ к портам
try:
import serial
except ImportError:
print("[!] Установи pyserial: pip install pyserial")
sys.exit(1)
# Ищем принтер
result = find_printer()
if result:
port, baud = result
interactive_test(port, baud)
else:
print("\n[!] Принтер не найден!")
print("\nПроверь:")
print(" 1. Подключен ли USB-кабель")
print(" 2. Нажат ли 'Разрешить' в диалоге macOS")
print(" 3. Включен ли принтер (горит индикатор)")
print(" 4. Попробуй другой USB-порт на Mac")
print(" 5. Перезагрузи принтер (выключи/включи)")
print("\nЕсли принтер работает на другом компьютере,")
print("напиши его модель - поищу драйвер специально.")
if __name__ == "__main__":
try:
main()
except KeyboardInterrupt:
print("\n\n[!] Остановлено пользователем")
sys.exit(0)