This commit is contained in:
cheykrym 2026-04-01 05:05:21 +03:00
parent ac7fd5fd4b
commit ae558f1362

View File

@ -70,6 +70,12 @@ class IrRemoteService(QObject):
def _find_ir_device(self) -> str | None: def _find_ir_device(self) -> str | None:
"""Найти устройство ИК-пульта в /dev/input.""" """Найти устройство ИК-пульта в /dev/input."""
# Сначала пробуем lirc устройства
for path in Path("/dev").glob("lirc*"):
logger.info(f"Found lirc device: {path}")
return str(path)
# Затем ищем event устройства с ir/rc в имени
for path in Path("/dev/input").glob("event*"): for path in Path("/dev/input").glob("event*"):
try: try:
# Проверяем, поддерживает ли устройство MSC_SCAN # Проверяем, поддерживает ли устройство MSC_SCAN
@ -78,13 +84,19 @@ class IrRemoteService(QObject):
EVIOCGNAME = 0x80000000 | (16 << 8) | ord('E') << 24 | 6 EVIOCGNAME = 0x80000000 | (16 << 8) | ord('E') << 24 | 6
import fcntl import fcntl
name = fcntl.ioctl(f.fileno(), EVIOCGNAME, b'\x00' * 256) name = fcntl.ioctl(f.fileno(), EVIOCGNAME, b'\x00' * 256)
if b"ir" in name.lower() or b"rc" in name.lower(): name_str = name.decode('utf-8', errors='ignore').lower()
if "ir" in name_str or "rc" in name_str:
logger.info(f"Found IR device by name: {path} ({name_str})")
return str(path) return str(path)
except (OSError, IOError): except (OSError, IOError):
continue continue
# Если не нашли по имени, пробуем первое event
for path in Path("/dev/input").glob("event*"): # Если не нашли по имени, пробуем все event устройства
for path in sorted(Path("/dev/input").glob("event*")):
logger.info(f"Trying event device: {path}")
return str(path) return str(path)
logger.warning("No IR device found")
return None return None
def start(self) -> bool: def start(self) -> bool:
@ -111,34 +123,45 @@ class IrRemoteService(QObject):
def _event_loop(self) -> None: def _event_loop(self) -> None:
"""Цикл обработки событий.""" """Цикл обработки событий."""
logger.info(f"Event loop started for {self._device_path}")
while self._running: while self._running:
try: try:
with open(self._device_path, "rb") as f: with open(self._device_path, "rb") as f:
logger.info(f"Opened {self._device_path} successfully")
while self._running: while self._running:
# Используем select для неблокирующего чтения # Используем select для неблокирующего чтения
ready, _, _ = select.select([f], [], [], 0.1) ready, _, _ = select.select([f], [], [], 0.5)
if not ready: if not ready:
continue continue
# Читаем событие (24 байта: tv_sec, tv_usec, type, code, value) # Читаем событие (24 байта: tv_sec, tv_usec, type, code, value)
data = f.read(24) data = f.read(24)
if len(data) < 24: if len(data) < 24:
logger.warning(f"Read incomplete data: {len(data)} bytes")
continue continue
# Логируем сырые байты для отладки
logger.debug(f"Raw bytes: {data.hex()}")
tv_sec, tv_usec, ev_type, ev_code, ev_value = struct.unpack("llHHI", data) tv_sec, tv_usec, ev_type, ev_code, ev_value = struct.unpack("llHHI", data)
logger.debug(f"Raw event: type={ev_type} (0x{ev_type:02x}), code={ev_code} (0x{ev_code:02x}), value={ev_value} (0x{ev_value:02x})")
# Обрабатываем MSC_SCAN события (скан-код) # Обрабатываем MSC_SCAN события (скан-код)
if ev_type == EV_MSC and ev_code == MSC_SCAN: if ev_type == EV_MSC and ev_code == MSC_SCAN:
scancode = f"0x{ev_value:02x}" scancode = f"0x{ev_value:02x}"
logger.debug(f"MSC_SCAN event: scancode={scancode}")
self._handle_scancode(scancode) self._handle_scancode(scancode)
# Обрабатываем EV_KEY события (отпускание кнопки) # Обрабатываем EV_KEY события (отпускание кнопки)
elif ev_type == EV_KEY and ev_value == KEY_UP: elif ev_type == EV_KEY and ev_value == KEY_UP:
logger.debug(f"KEY_UP event: code={ev_code}")
# Кнопка отпущена - сбрасываем состояние # Кнопка отпущена - сбрасываем состояние
self.reset_button_state() self.reset_button_state()
except (OSError, IOError): except (OSError, IOError) as e:
# Устройство недоступно, ждём и пробуем снова # Устройство недоступно, ждём и пробуем снова
logger.warning(f"Device error: {e}, retrying...")
import time import time
time.sleep(1.0) time.sleep(1.0)