Add udev stuff

This commit is contained in:
PapaTutuWawa 2025-01-12 00:21:59 +01:00
parent a8ac092277
commit 934c4183aa
4 changed files with 64 additions and 3 deletions

View File

@ -34,6 +34,13 @@ class Config:
# URL scheme -> netloc (or '*' for fallback) -> fully-qualified player class # URL scheme -> netloc (or '*' for fallback) -> fully-qualified player class
players: dict[str, dict[str, str]] players: dict[str, dict[str, str]]
card: str | None
connector: str | None
@property
def watch_connector(self) -> bool:
return self.card is not None and self.connector is not None
def load_config(config_path: Path | None) -> Config: def load_config(config_path: Path | None) -> Config:
if config_path is None: if config_path is None:
config_data = {} config_data = {}
@ -59,4 +66,6 @@ def load_config(config_path: Path | None) -> Config:
}, },
config_data.get("players", {}), config_data.get("players", {}),
), ),
card=config_data.get("card"),
connector=config_data.get("connector"),
) )

View File

@ -5,6 +5,7 @@ import threading
import argparse import argparse
from pathlib import Path from pathlib import Path
import importlib.util import importlib.util
import time
from PySide6.QtGui import QGuiApplication from PySide6.QtGui import QGuiApplication
from PySide6.QtQml import QQmlApplicationEngine from PySide6.QtQml import QQmlApplicationEngine
@ -13,12 +14,12 @@ from microkodi.jsonrpc import JsonRpcHandler, GlobalMethodHandler
from microkodi.ui.bridge import DataBridge from microkodi.ui.bridge import DataBridge
from microkodi.config import Config, load_config from microkodi.config import Config, load_config
from microkodi.repository import I from microkodi.repository import I
from microkodi.udev import is_display_connected, block_until_display_connected
def run_kodi_server(): def run_kodi_server():
config: Config = I.get("Config") config: Config = I.get("Config")
logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger("JsonRPCServer") logger = logging.getLogger("JsonRPCServer")
method_handler = GlobalMethodHandler() method_handler = GlobalMethodHandler()
I.register("GlobalMethodHandler", method_handler) I.register("GlobalMethodHandler", method_handler)
@ -58,8 +59,12 @@ def run_kodi_server():
if __name__ == "__main__": if __name__ == "__main__":
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
parser.add_argument("--config", "-c", type=Path, help="Location of the config file") parser.add_argument("--config", "-c", type=Path, help="Location of the config file")
parser.add_argument("--debug", action="store_true", default=False)
options = parser.parse_args() options = parser.parse_args()
logging.basicConfig(level=logging.DEBUG if options.debug else logging.INFO)
logger = logging.getLogger("ui")
# Load the config # Load the config
config = load_config(options.config) config = load_config(options.config)
I.register("Config", config) I.register("Config", config)
@ -87,6 +92,25 @@ if __name__ == "__main__":
sys.exit(-1) sys.exit(-1)
engine.rootObjects()[0].setProperty("bridge", bridge) engine.rootObjects()[0].setProperty("bridge", bridge)
exit_code = app.exec()
if config.watch_connector:
logger.info("Will be watching display if it's gone")
exit_code = 0
while True:
exit_code = app.exec()
if not config.watch_connector:
break
# Exit if the display is still connected
if is_display_connected(config.card, config.connector):
break
logger.info("Display is gone. Waiting until it's back")
block_until_display_connected(config.card, config.connector)
logger.info("Display is back. Waiting 500ms...")
time.sleep(0.5)
del engine del engine
sys.exit(exit_code) sys.exit(exit_code)

27
microkodi/udev.py Normal file
View File

@ -0,0 +1,27 @@
import logging
import pyudev
def is_display_connected(card: str, connector: str) -> bool:
logger = logging.getLogger("udev")
status_file = f"/sys/class/drm/{card}-{connector}/status"
logger.debug("Reading file %s", status_file)
with open(status_file, "r") as f:
result = f.read().strip()
logger.debug("Result: '%s'", result)
return result == "connected"
def block_until_display_connected(card: str, connector: str):
ctx = pyudev.Context()
monitor = pyudev.Monitor.from_netlink(ctx)
monitor.filter_by("drm")
for device in iter(monitor.poll, None):
if not "DEVNAME" in device:
continue
if device.get("DEVNAME") != f"/dev/dri/{card}":
continue
if not is_display_connected(card, connector):
continue
break

View File

@ -4,7 +4,8 @@ version = "0.1.0"
dependencies = [ dependencies = [
"pyside6", "pyside6",
"requests", "requests",
"yt-dlp" "yt-dlp",
"pyudev"
] ]
[tools.build] [tools.build]