AUFGERAUMT: Root auf 10 sichtbare Elemente reduziert
Der Nutzer hat recht: Der Ordner war voller Entwicklungs-Muell. Jetzt ist sauber getrennt: ROOT (was der Nutzer sieht und braucht): - run.py = das Programm - hms_app/ = der Anwendungscode - HMS MediaEngine.app = macOS Doppelklick-Starter - HMS-Start.vbs = Windows Doppelklick-Starter - HMS-Install.vbs = Windows Erst-Installation - HMS-Mac-Install.command = macOS Homebrew-Installation - HMS-Portable-Install.command = macOS Portable-Installation (16GB-Fix) - installer_gui.py = grafischer Installer - launcher.pyw + launcher_core.py = interne Start-Logik - LIESMICH.txt = 10-Zeilen-Kurzanleitung - .gitignore _entwicklung/ (alles andere, NICHT benoetigt): - packages/ apps/ native/ plugins/ tools/ schemas/ tests/ docs/ build/ fixture_profiles/ - PLAN.md STATUS.md ERRORS.md TEST_REPORT.md CHANGELOG.md README.md - pyproject.toml uv.lock setup_*.sh/ps1 make_mac_app.py Diese Trennung gilt ab sofort fuer alle Commits. Der Nutzer kann _entwicklung/ loeschen wenn er Platz braucht - die App laeuft ohne. Verifiziert: App startet nach Aufraeumen unveraendert (Health 200).
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
"""hms_capabilities – Hardware-Erkennung und Capability-Tiers (PLAN.md §5)."""
|
||||
|
||||
from hms_capabilities.probe import CapabilityReport, CapabilityTier, detect_cpu_ram
|
||||
|
||||
__all__ = ["CapabilityTier", "CapabilityReport", "detect_cpu_ram"]
|
||||
@@ -0,0 +1,99 @@
|
||||
"""Capability-Probe (PLAN.md §5, §5.2).
|
||||
|
||||
Phase 0: plattformneutrale Basis-Erkennung (CPU/RAM/OS) und Tier-Vergabe
|
||||
nach gemessenen Fakten. GPU-/Decoder-/Display-Erkennung läuft auf dem
|
||||
Zielsystem (D3D11/GL/GLES); hier kein Fake-Ergebnis (§33: keine nicht
|
||||
getestete Dekodierung als Hardwarebeschleunigung ausgeben).
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import enum
|
||||
|
||||
|
||||
class CapabilityTier(enum.StrEnum):
|
||||
DESKTOP_FULL = "DESKTOP_FULL"
|
||||
DESKTOP_LITE = "DESKTOP_LITE"
|
||||
PI_LITE = "PI_LITE"
|
||||
HEADLESS_CONTROL = "HEADLESS_CONTROL"
|
||||
|
||||
|
||||
# Mindest-VRAM für DESKTOP_FULL (§5)
|
||||
_DESKTOP_FULL_MIN_VRAM_GB = 8.0
|
||||
|
||||
|
||||
def detect_cpu_ram() -> dict[str, object]:
|
||||
"""Basis-Hardwareinformationen (plattformneutral, ohne Fake)."""
|
||||
import os
|
||||
import platform
|
||||
|
||||
info: dict[str, object] = {
|
||||
"os": platform.system(),
|
||||
"os_release": platform.release(),
|
||||
"machine": platform.machine(),
|
||||
"cpu_count": os.cpu_count() or 1,
|
||||
"ram_total_gb": _ram_gb(),
|
||||
}
|
||||
return info
|
||||
|
||||
|
||||
def _ram_gb() -> float:
|
||||
"""RAM in GB; Linux via /proc/meminfo, sonst -1 (unbekannt, nicht geraten)."""
|
||||
try:
|
||||
with open("/proc/meminfo", encoding="ascii") as fh:
|
||||
for line in fh:
|
||||
if line.startswith("MemTotal:"):
|
||||
kib = int(line.split()[1])
|
||||
return round(kib / (1024 * 1024), 2)
|
||||
except (OSError, ValueError):
|
||||
pass
|
||||
return -1.0
|
||||
|
||||
|
||||
class CapabilityReport:
|
||||
"""Ergebnis des Capability-Selbsttests (Phase 0: Skelett).
|
||||
|
||||
GPU/Decoder/Displays werden auf dem Zielsystem gemessen und hier
|
||||
ergänzt; ein Report ohne GPU-Messung kann kein DESKTOP-Tier vergeben.
|
||||
"""
|
||||
|
||||
def __init__(self) -> None:
|
||||
self.cpu_ram = detect_cpu_ram()
|
||||
self.gpu: dict[str, object] | None = None
|
||||
self.decoders: dict[str, object] | None = None
|
||||
self.displays: dict[str, object] | None = None
|
||||
self.tier: CapabilityTier | None = None
|
||||
self.fingerprint: str = "" # an Messwerte gebunden (§5.2)
|
||||
|
||||
def conclude_tier(
|
||||
self,
|
||||
has_gpu: bool,
|
||||
vram_gb: float | None,
|
||||
decode_ok: bool,
|
||||
has_display: bool,
|
||||
) -> CapabilityTier | None:
|
||||
"""Vergibt das Tier nach gemessenen Fakten; None wenn unklar.
|
||||
|
||||
Unklar bedeutet: Gate 0 darf nicht grün melden, solange keine
|
||||
Messwerte vorliegen (§33).
|
||||
"""
|
||||
if not has_display:
|
||||
self.tier = CapabilityTier.HEADLESS_CONTROL
|
||||
return self.tier
|
||||
if not has_gpu or not decode_ok:
|
||||
return None
|
||||
if vram_gb is not None and vram_gb >= _DESKTOP_FULL_MIN_VRAM_GB:
|
||||
self.tier = CapabilityTier.DESKTOP_FULL
|
||||
else:
|
||||
self.tier = CapabilityTier.DESKTOP_LITE
|
||||
return self.tier
|
||||
|
||||
def as_dict(self) -> dict[str, object]:
|
||||
return {
|
||||
"cpu_ram": self.cpu_ram,
|
||||
"gpu": self.gpu,
|
||||
"decoders": self.decoders,
|
||||
"displays": self.displays,
|
||||
"tier": self.tier.value if self.tier else None,
|
||||
"fingerprint": self.fingerprint,
|
||||
}
|
||||
Reference in New Issue
Block a user