diff --git a/diagnostic/index.html b/diagnostic/index.html
index 58fdecc..7505ca2 100644
--- a/diagnostic/index.html
+++ b/diagnostic/index.html
@@ -4902,7 +4902,8 @@
(scanning ? ' disabled' : '') + '>Geraete scannen' +
'' +
'
kann: ' + escapeHtml(caps) + ' · ' + ctrl +
- (s.net && s.net.primary_ip ? ' · Netz: ' + escapeHtml(s.net.primary_ip) : '') + '
' +
+ (s.net && s.net.primary_ip ? ' · Netz: ' + escapeHtml(s.net.primary_ip) : '') +
+ (s.net && s.net.mac ? ' · MAC: ' + escapeHtml(s.net.mac) + '' : '') + '' +
(s.net && s.net.warning ? '⚠ ' + escapeHtml(s.net.warning) + '
' : '') +
devHtml +
'';
diff --git a/satellite/satellite.py b/satellite/satellite.py
index 80338d9..d81e448 100644
--- a/satellite/satellite.py
+++ b/satellite/satellite.py
@@ -333,7 +333,48 @@ def _net_context() -> dict:
"mDNS/SSDP erreichen die realen Geraete so nicht. Auf Docker Desktop "
"(Mac/Windows) geht LAN-Discovery nicht — den Satelliten NATIV (python "
"satellite.py) oder auf einem Linux-Host im Ziel-LAN betreiben.")
- return {"primary_ip": p, "ips": ips, "warning": warning}
+ return {"primary_ip": p, "ips": ips, "mac": _own_mac(p), "warning": warning}
+
+
+def _own_mac(ip: str) -> str:
+ """MAC der eigenen (primaeren) Netzwerkkarte — identifiziert die Kiste
+ eindeutig (DHCP-Reservierung, WOL). Liest /sys/class/net (Linux); faellt auf
+ uuid.getnode() zurueck, wenn das Interface nicht zuzuordnen ist."""
+ import subprocess
+ try:
+ base = "/sys/class/net"
+ if os.path.isdir(base):
+ # Interface zur primaeren IP finden (ueber die Adressen im /proc-Netz).
+ want = ""
+ if ip:
+ try:
+ out = subprocess.run(["ip", "-o", "-4", "addr", "show"],
+ capture_output=True, text=True, timeout=3).stdout
+ for line in out.splitlines():
+ parts = line.split()
+ if len(parts) >= 4 and parts[3].split("/")[0] == ip:
+ want = parts[1]
+ break
+ except Exception:
+ pass
+ names = [want] if want else []
+ names += [n for n in sorted(os.listdir(base)) if n != "lo" and n not in names]
+ for n in names:
+ try:
+ with open(os.path.join(base, n, "address"), "r") as f:
+ mac = f.read().strip()
+ if mac and mac != "00:00:00:00:00:00":
+ return mac.lower()
+ except Exception:
+ continue
+ except Exception:
+ pass
+ try:
+ import uuid
+ node = uuid.getnode()
+ return ":".join(f"{(node >> e) & 0xFF:02x}" for e in range(40, -8, -8))
+ except Exception:
+ return ""
NET = _net_context()
@@ -1686,7 +1727,8 @@ class Satellite:
def main() -> None:
logger.info("ARIA Satellit startet — id=%s location=%s control=%s",
SATELLITE_ID, SATELLITE_LOCATION, CONTROL_ENABLED)
- logger.info("Netz: primary_ip=%s alle=%s", NET.get("primary_ip"), NET.get("ips"))
+ logger.info("Netz: primary_ip=%s mac=%s alle=%s",
+ NET.get("primary_ip"), NET.get("mac") or "?", NET.get("ips"))
if NET.get("warning"):
logger.warning("⚠ %s", NET["warning"])
try: