Add udev stuff
This commit is contained in:
parent
a8ac092277
commit
934c4183aa
@ -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"),
|
||||||
)
|
)
|
||||||
|
@ -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)
|
||||||
|
|
||||||
|
if config.watch_connector:
|
||||||
|
logger.info("Will be watching display if it's gone")
|
||||||
|
|
||||||
|
exit_code = 0
|
||||||
|
while True:
|
||||||
exit_code = app.exec()
|
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
27
microkodi/udev.py
Normal 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
|
@ -4,7 +4,8 @@ version = "0.1.0"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"pyside6",
|
"pyside6",
|
||||||
"requests",
|
"requests",
|
||||||
"yt-dlp"
|
"yt-dlp",
|
||||||
|
"pyudev"
|
||||||
]
|
]
|
||||||
|
|
||||||
[tools.build]
|
[tools.build]
|
||||||
|
Loading…
Reference in New Issue
Block a user