Phase 0: Repository-Initialisierung nach Bauplan v1.2
- Struktur gemäß §8 (Eigentumsgrenzen), PLAN.md als normative Basis - Pflichtdokumente: STATUS.md, ERRORS.md, TEST_REPORT.md, CHANGELOG.md, ADRs - ADR-0001 Python 3.13-Pin, ADR-0002 GStreamer 1.28.6-Pin (Windows), ADR-0003 IPC TCP+MessagePack v1 - Kernpakete: hms_protocol, hms_domain, hms_parameter, hms_artnet, hms_adaptive, hms_capabilities, hms_plugin_sdk - Renderer-Spike: D3D11-Primärpfad + Dev-GL-Pfad (§36 Nr. 4-5) - Control Core: FastAPI REST + WebSocket (§36 Nr. 9) - Beispielplugins: Passthrough + Gaussian Blur (3 Adaptive-Quality- Varianten, HLSL/GLSL/GLES) - Tools: Art-Net-Emulator, Fixture-Generator (Master32/Layer64-CSV), Capability-Probe - JSON-Schemas: IPC, Plugin, Projekt, Cluster - 121 Unit-/Integrationstests grün, Ruff grün Gate 0 bleibt offen: Hardwaremessungen nur auf echter Windows-Referenz- hardware gültig (§29.7, §33).
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