164 lines
4.5 KiB
Python
164 lines
4.5 KiB
Python
import platform
|
|
import shutil
|
|
import socket
|
|
from pathlib import Path
|
|
|
|
|
|
APP_NAME = "Car UI"
|
|
VERSION = "0.1.0-dev"
|
|
BUILD_DATE = "dev"
|
|
GIT_HASH = "dev"
|
|
DEVICE_MODEL = "Raspberry Pi"
|
|
DEFAULT_SOUND_VOLUME = 100
|
|
DEFAULT_PREMUTE_VOLUME = 10
|
|
DEFAULT_DUCKING_VOLUME = 35
|
|
DEV_MODE_ENABLE = (Path(__file__).resolve().parent / "dev_mode_enable").exists()
|
|
|
|
|
|
def get_device_model() -> str:
|
|
for path in ("/proc/device-tree/model", "/sys/firmware/devicetree/base/model"):
|
|
try:
|
|
with open(path, "rb") as f:
|
|
raw = f.read().strip(b"\x00").strip()
|
|
if raw:
|
|
return raw.decode("utf-8", errors="replace")
|
|
except OSError:
|
|
continue
|
|
return DEVICE_MODEL
|
|
|
|
|
|
def get_os_pretty_name() -> str:
|
|
for path in ("/etc/os-release", "/usr/lib/os-release"):
|
|
try:
|
|
with open(path, "r", encoding="utf-8") as f:
|
|
for line in f:
|
|
if line.startswith("PRETTY_NAME="):
|
|
value = line.split("=", 1)[1].strip().strip('"')
|
|
return value or "—"
|
|
except OSError:
|
|
continue
|
|
return platform.system() or "—"
|
|
|
|
|
|
def get_kernel_version() -> str:
|
|
return platform.release() or "—"
|
|
|
|
|
|
def _read_meminfo() -> dict[str, int]:
|
|
info: dict[str, int] = {}
|
|
try:
|
|
with open("/proc/meminfo", "r", encoding="utf-8") as f:
|
|
for line in f:
|
|
if ":" not in line:
|
|
continue
|
|
key, rest = line.split(":", 1)
|
|
parts = rest.strip().split()
|
|
if not parts:
|
|
continue
|
|
try:
|
|
value_kb = int(parts[0])
|
|
except ValueError:
|
|
continue
|
|
info[key] = value_kb * 1024
|
|
except OSError:
|
|
return {}
|
|
return info
|
|
|
|
|
|
def _format_bytes(num_bytes: int) -> str:
|
|
if num_bytes <= 0:
|
|
return "—"
|
|
gib = num_bytes / (1024 ** 3)
|
|
if gib >= 1:
|
|
return f"{gib:.1f} GB"
|
|
mib = num_bytes / (1024 ** 2)
|
|
return f"{mib:.0f} MB"
|
|
|
|
|
|
def get_ram_info() -> str:
|
|
info = _read_meminfo()
|
|
total = info.get("MemTotal", 0)
|
|
free = info.get("MemFree", 0)
|
|
if total <= 0:
|
|
return "—"
|
|
return f"{_format_bytes(free)} / {_format_bytes(total)}"
|
|
|
|
|
|
def get_disk_info() -> str:
|
|
try:
|
|
usage = shutil.disk_usage("/")
|
|
except OSError:
|
|
return "—"
|
|
return f"{_format_bytes(usage.used)} / {_format_bytes(usage.total)}"
|
|
|
|
|
|
def get_serial_number() -> str:
|
|
for path in ("/proc/device-tree/serial-number",):
|
|
try:
|
|
with open(path, "rb") as f:
|
|
raw = f.read().strip(b"\x00").strip()
|
|
if raw:
|
|
return raw.decode("utf-8", errors="replace")
|
|
except OSError:
|
|
continue
|
|
try:
|
|
with open("/proc/cpuinfo", "r", encoding="utf-8") as f:
|
|
for line in f:
|
|
if line.lower().startswith("serial"):
|
|
return line.split(":", 1)[1].strip() or "—"
|
|
except OSError:
|
|
pass
|
|
return "—"
|
|
|
|
|
|
def get_ip_address() -> str:
|
|
try:
|
|
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
|
try:
|
|
sock.connect(("8.8.8.8", 80))
|
|
ip = sock.getsockname()[0]
|
|
finally:
|
|
sock.close()
|
|
if ip and not ip.startswith("127."):
|
|
return ip
|
|
except OSError:
|
|
pass
|
|
try:
|
|
ip = socket.gethostbyname(socket.gethostname())
|
|
if ip and not ip.startswith("127."):
|
|
return ip
|
|
except OSError:
|
|
pass
|
|
return "—"
|
|
|
|
|
|
def get_cpu_temp() -> str:
|
|
for path in ("/sys/class/thermal/thermal_zone0/temp",):
|
|
try:
|
|
with open(path, "r", encoding="utf-8") as f:
|
|
raw = f.read().strip()
|
|
if raw:
|
|
temp_c = float(raw) / 1000.0
|
|
return f"{temp_c:.1f} C"
|
|
except (OSError, ValueError):
|
|
continue
|
|
return "—"
|
|
|
|
|
|
def get_display_resolution() -> str:
|
|
for path in ("/sys/class/graphics/fb0/virtual_size", "/sys/class/graphics/fb0/modes"):
|
|
try:
|
|
with open(path, "r", encoding="utf-8") as f:
|
|
raw = f.read().strip()
|
|
if not raw:
|
|
continue
|
|
if "x" in raw:
|
|
first_line = raw.splitlines()[0]
|
|
return first_line.split(" ", 1)[0]
|
|
if "," in raw:
|
|
width, height = raw.split(",", 1)
|
|
return f"{width.strip()}x{height.strip()}"
|
|
except OSError:
|
|
continue
|
|
return "—"
|