Auto-detect RTC device (/dev/rtc0,/dev/rtc1) for hwclock sync
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
import os
|
import os
|
||||||
import subprocess
|
import subprocess
|
||||||
from datetime import datetime, timezone
|
from datetime import datetime, timezone
|
||||||
from typing import Tuple
|
from typing import Optional, Tuple
|
||||||
|
|
||||||
import ntplib
|
import ntplib
|
||||||
|
|
||||||
@@ -13,21 +13,34 @@ class RTCAndNTPManager:
|
|||||||
self.state = state
|
self.state = state
|
||||||
self.rtc_device = rtc_device
|
self.rtc_device = rtc_device
|
||||||
self.ntp_server = ntp_server
|
self.ntp_server = ntp_server
|
||||||
|
self._resolved_rtc_device: Optional[str] = None
|
||||||
|
|
||||||
def _run(self, args, timeout: int = 12) -> subprocess.CompletedProcess:
|
def _run(self, args, timeout: int = 12) -> subprocess.CompletedProcess:
|
||||||
return subprocess.run(args, capture_output=True, text=True, timeout=timeout, check=False)
|
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:
|
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]:
|
def sync_from_rtc(self) -> Tuple[bool, str]:
|
||||||
if not self.rtc_available():
|
rtc_device = self._resolve_rtc_device()
|
||||||
return False, f"RTC not found at {self.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:
|
if proc.returncode == 0:
|
||||||
self.state.update_status("System time loaded from RTC", "")
|
self.state.update_status(f"System time loaded from {rtc_device}", "")
|
||||||
return True, "RTC -> system time ok"
|
return True, f"{rtc_device} -> system time ok"
|
||||||
return False, (proc.stderr or proc.stdout or "hwclock -s failed").strip()
|
return False, (proc.stderr or proc.stdout or "hwclock -s failed").strip()
|
||||||
|
|
||||||
def sync_ntp_to_system(self, timeout: int = 6) -> Tuple[bool, str]:
|
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}"
|
return False, f"NTP sync failed: {exc}"
|
||||||
|
|
||||||
def write_system_time_to_rtc(self) -> Tuple[bool, str]:
|
def write_system_time_to_rtc(self) -> Tuple[bool, str]:
|
||||||
if not self.rtc_available():
|
rtc_device = self._resolve_rtc_device()
|
||||||
return False, f"RTC not found at {self.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:
|
if proc.returncode == 0:
|
||||||
self.state.update_status("RTC updated from system time", "")
|
self.state.update_status(f"{rtc_device} updated from system time", "")
|
||||||
return True, "system -> RTC ok"
|
return True, f"system -> {rtc_device} ok"
|
||||||
return False, (proc.stderr or proc.stdout or "hwclock -w failed").strip()
|
return False, (proc.stderr or proc.stdout or "hwclock -w failed").strip()
|
||||||
|
|
||||||
def sync_ntp_and_rtc(self) -> Tuple[bool, str]:
|
def sync_ntp_and_rtc(self) -> Tuple[bool, str]:
|
||||||
|
|||||||
Reference in New Issue
Block a user