Auto-detect RTC device (/dev/rtc0,/dev/rtc1) for hwclock sync

This commit is contained in:
2026-02-13 02:11:46 +01:00
parent f0eaf3dc5f
commit 5f5087c3d6

View File

@@ -1,7 +1,7 @@
import os
import subprocess
from datetime import datetime, timezone
from typing import Tuple
from typing import Optional, Tuple
import ntplib
@@ -13,21 +13,34 @@ class RTCAndNTPManager:
self.state = state
self.rtc_device = rtc_device
self.ntp_server = ntp_server
self._resolved_rtc_device: Optional[str] = None
def _run(self, args, timeout: int = 12) -> subprocess.CompletedProcess:
return subprocess.run(args, capture_output=True, text=True, timeout=timeout, check=False)
def _resolve_rtc_device(self) -> Optional[str]:
if self._resolved_rtc_device and os.path.exists(self._resolved_rtc_device):
return self._resolved_rtc_device
candidates = [self.rtc_device, "/dev/rtc", "/dev/rtc0", "/dev/rtc1"]
for candidate in candidates:
if os.path.exists(candidate):
self._resolved_rtc_device = candidate
return candidate
return None
def rtc_available(self) -> bool:
return os.path.exists(self.rtc_device)
return self._resolve_rtc_device() is not None
def sync_from_rtc(self) -> Tuple[bool, str]:
if not self.rtc_available():
return False, f"RTC not found at {self.rtc_device}"
rtc_device = self._resolve_rtc_device()
if rtc_device is None:
return False, f"RTC not found (checked: {self.rtc_device}, /dev/rtc, /dev/rtc0, /dev/rtc1)"
proc = self._run(["hwclock", "-s", "--utc"], timeout=10)
proc = self._run(["hwclock", "-s", "--utc", "--rtc", rtc_device], timeout=10)
if proc.returncode == 0:
self.state.update_status("System time loaded from RTC", "")
return True, "RTC -> system time ok"
self.state.update_status(f"System time loaded from {rtc_device}", "")
return True, f"{rtc_device} -> system time ok"
return False, (proc.stderr or proc.stdout or "hwclock -s failed").strip()
def sync_ntp_to_system(self, timeout: int = 6) -> Tuple[bool, str]:
@@ -48,13 +61,14 @@ class RTCAndNTPManager:
return False, f"NTP sync failed: {exc}"
def write_system_time_to_rtc(self) -> Tuple[bool, str]:
if not self.rtc_available():
return False, f"RTC not found at {self.rtc_device}"
rtc_device = self._resolve_rtc_device()
if rtc_device is None:
return False, f"RTC not found (checked: {self.rtc_device}, /dev/rtc, /dev/rtc0, /dev/rtc1)"
proc = self._run(["hwclock", "-w", "--utc"], timeout=10)
proc = self._run(["hwclock", "-w", "--utc", "--rtc", rtc_device], timeout=10)
if proc.returncode == 0:
self.state.update_status("RTC updated from system time", "")
return True, "system -> RTC ok"
self.state.update_status(f"{rtc_device} updated from system time", "")
return True, f"system -> {rtc_device} ok"
return False, (proc.stderr or proc.stdout or "hwclock -w failed").strip()
def sync_ntp_and_rtc(self) -> Tuple[bool, str]: