mirror of
https://github.com/sunnypilot/sunnypilot.git
synced 2026-06-21 21:12:08 +08:00
updated: move update alerts out of thermald (#23028)
* updated: move update alerts out of thermald
* cleanup last update time
* set on startup
old-commit-hash: b79eaca18d
This commit is contained in:
@@ -22,15 +22,13 @@ from selfdrive.hardware import EON, TICI, PC, HARDWARE
|
||||
from selfdrive.loggerd.config import get_available_percent
|
||||
from selfdrive.swaglog import cloudlog
|
||||
from selfdrive.thermald.power_monitoring import PowerMonitoring
|
||||
from selfdrive.version import get_tested_branch, terms_version, training_version
|
||||
from selfdrive.version import terms_version, training_version
|
||||
|
||||
ThermalStatus = log.DeviceState.ThermalStatus
|
||||
NetworkType = log.DeviceState.NetworkType
|
||||
NetworkStrength = log.DeviceState.NetworkStrength
|
||||
CURRENT_TAU = 15. # 15s time constant
|
||||
TEMP_TAU = 5. # 5s time constant
|
||||
DAYS_NO_CONNECTIVITY_MAX = 14 # do not allow to engage after this many days
|
||||
DAYS_NO_CONNECTIVITY_PROMPT = 10 # send an offroad prompt after this many days
|
||||
DISCONNECT_TIMEOUT = 5. # wait 5 seconds before going offroad after disconnect so you get an alert
|
||||
|
||||
ThermalBand = namedtuple("ThermalBand", ['min_temp', 'max_temp'])
|
||||
@@ -324,47 +322,11 @@ def thermald_thread():
|
||||
|
||||
# **** starting logic ****
|
||||
|
||||
# Check for last update time and display alerts if needed
|
||||
# Ensure date/time are valid
|
||||
now = datetime.datetime.utcnow()
|
||||
|
||||
# show invalid date/time alert
|
||||
startup_conditions["time_valid"] = (now.year > 2020) or (now.year == 2020 and now.month >= 10)
|
||||
set_offroad_alert_if_changed("Offroad_InvalidTime", (not startup_conditions["time_valid"]))
|
||||
|
||||
# Show update prompt
|
||||
try:
|
||||
last_update = datetime.datetime.fromisoformat(params.get("LastUpdateTime", encoding='utf8'))
|
||||
except (TypeError, ValueError):
|
||||
last_update = now
|
||||
dt = now - last_update
|
||||
|
||||
update_failed_count = params.get("UpdateFailedCount")
|
||||
update_failed_count = 0 if update_failed_count is None else int(update_failed_count)
|
||||
last_update_exception = params.get("LastUpdateException", encoding='utf8')
|
||||
|
||||
if update_failed_count > 15 and last_update_exception is not None:
|
||||
if get_tested_branch():
|
||||
extra_text = "Ensure the software is correctly installed"
|
||||
else:
|
||||
extra_text = last_update_exception
|
||||
|
||||
set_offroad_alert_if_changed("Offroad_ConnectivityNeeded", False)
|
||||
set_offroad_alert_if_changed("Offroad_ConnectivityNeededPrompt", False)
|
||||
set_offroad_alert_if_changed("Offroad_UpdateFailed", True, extra_text=extra_text)
|
||||
elif dt.days > DAYS_NO_CONNECTIVITY_MAX and update_failed_count > 1:
|
||||
set_offroad_alert_if_changed("Offroad_UpdateFailed", False)
|
||||
set_offroad_alert_if_changed("Offroad_ConnectivityNeededPrompt", False)
|
||||
set_offroad_alert_if_changed("Offroad_ConnectivityNeeded", True)
|
||||
elif dt.days > DAYS_NO_CONNECTIVITY_PROMPT:
|
||||
remaining = max(DAYS_NO_CONNECTIVITY_MAX - dt.days, 1)
|
||||
set_offroad_alert_if_changed("Offroad_UpdateFailed", False)
|
||||
set_offroad_alert_if_changed("Offroad_ConnectivityNeeded", False)
|
||||
set_offroad_alert_if_changed("Offroad_ConnectivityNeededPrompt", True, extra_text=f"{remaining} day{'' if remaining == 1 else 's'}.")
|
||||
else:
|
||||
set_offroad_alert_if_changed("Offroad_UpdateFailed", False)
|
||||
set_offroad_alert_if_changed("Offroad_ConnectivityNeeded", False)
|
||||
set_offroad_alert_if_changed("Offroad_ConnectivityNeededPrompt", False)
|
||||
|
||||
startup_conditions["up_to_date"] = params.get("Offroad_ConnectivityNeeded") is None or params.get_bool("DisableUpdates") or params.get_bool("SnoozeUpdate")
|
||||
startup_conditions["not_uninstalling"] = not params.get_bool("DoUninstall")
|
||||
startup_conditions["accepted_terms"] = params.get("HasAcceptedTerms") == terms_version
|
||||
|
||||
+41
-10
@@ -40,6 +40,7 @@ from common.params import Params
|
||||
from selfdrive.hardware import EON, TICI, HARDWARE
|
||||
from selfdrive.swaglog import cloudlog
|
||||
from selfdrive.controls.lib.alertmanager import set_offroad_alert
|
||||
from selfdrive.version import get_tested_branch
|
||||
|
||||
LOCK_FILE = os.getenv("UPDATER_LOCK_FILE", "/tmp/safe_staging_overlay.lock")
|
||||
STAGING_ROOT = os.getenv("UPDATER_STAGING_ROOT", "/data/safe_staging")
|
||||
@@ -51,6 +52,8 @@ OVERLAY_METADATA = os.path.join(STAGING_ROOT, "metadata")
|
||||
OVERLAY_MERGED = os.path.join(STAGING_ROOT, "merged")
|
||||
FINALIZED = os.path.join(STAGING_ROOT, "finalized")
|
||||
|
||||
DAYS_NO_CONNECTIVITY_MAX = 14 # do not allow to engage after this many days
|
||||
DAYS_NO_CONNECTIVITY_PROMPT = 10 # send an offroad prompt after this many days
|
||||
|
||||
class WaitTimeHelper:
|
||||
def __init__(self, proc):
|
||||
@@ -102,15 +105,24 @@ def set_params(new_version: bool, failed_count: int, exception: Optional[str]) -
|
||||
params = Params()
|
||||
|
||||
params.put("UpdateFailedCount", str(failed_count))
|
||||
|
||||
last_update = datetime.datetime.utcnow()
|
||||
if failed_count == 0:
|
||||
t = datetime.datetime.utcnow().isoformat()
|
||||
t = last_update.isoformat()
|
||||
params.put("LastUpdateTime", t.encode('utf8'))
|
||||
else:
|
||||
try:
|
||||
t = params.get("LastUpdateTime", encoding='utf8')
|
||||
last_update = datetime.datetime.fromisoformat(t)
|
||||
except (TypeError, ValueError):
|
||||
pass
|
||||
|
||||
if exception is None:
|
||||
params.delete("LastUpdateException")
|
||||
else:
|
||||
params.put("LastUpdateException", exception)
|
||||
|
||||
# Write out release notes for new versions
|
||||
if new_version:
|
||||
try:
|
||||
with open(os.path.join(FINALIZED, "RELEASES.md"), "rb") as f:
|
||||
@@ -123,6 +135,24 @@ def set_params(new_version: bool, failed_count: int, exception: Optional[str]) -
|
||||
params.put("ReleaseNotes", "")
|
||||
params.put_bool("UpdateAvailable", True)
|
||||
|
||||
# Handle user prompt
|
||||
for alert in ("Offroad_UpdateFailed", "Offroad_ConnectivityNeeded", "Offroad_ConnectivityNeededPrompt"):
|
||||
set_offroad_alert(alert, False)
|
||||
|
||||
now = datetime.datetime.utcnow()
|
||||
dt = now - last_update
|
||||
if failed_count > 15 and exception is not None:
|
||||
if get_tested_branch():
|
||||
extra_text = "Ensure the software is correctly installed"
|
||||
else:
|
||||
extra_text = exception
|
||||
set_offroad_alert("Offroad_UpdateFailed", True, extra_text=extra_text)
|
||||
elif dt.days > DAYS_NO_CONNECTIVITY_MAX and failed_count > 1:
|
||||
set_offroad_alert("Offroad_ConnectivityNeeded", True)
|
||||
elif dt.days > DAYS_NO_CONNECTIVITY_PROMPT:
|
||||
remaining = max(DAYS_NO_CONNECTIVITY_MAX - dt.days, 1)
|
||||
set_offroad_alert("Offroad_ConnectivityNeededPrompt", True, extra_text=f"{remaining} day{'' if remaining == 1 else 's'}.")
|
||||
|
||||
|
||||
def setup_git_options(cwd: str) -> None:
|
||||
# We sync FS object atimes (which NEOS doesn't use) and mtimes, but ctimes
|
||||
@@ -344,16 +374,14 @@ def main():
|
||||
params = Params()
|
||||
|
||||
if params.get_bool("DisableUpdates"):
|
||||
raise RuntimeError("updates are disabled by the DisableUpdates param")
|
||||
|
||||
if EON and os.geteuid() != 0:
|
||||
raise RuntimeError("updated must be launched as root!")
|
||||
cloudlog.warning("updates are disabled by the DisableUpdates param")
|
||||
exit(0)
|
||||
|
||||
ov_lock_fd = open(LOCK_FILE, 'w')
|
||||
try:
|
||||
fcntl.flock(ov_lock_fd, fcntl.LOCK_EX | fcntl.LOCK_NB)
|
||||
except IOError as e:
|
||||
raise RuntimeError("couldn't get overlay lock; is another updated running?") from e
|
||||
raise RuntimeError("couldn't get overlay lock; is another instance running?") from e
|
||||
|
||||
# Set low io priority
|
||||
proc = psutil.Process()
|
||||
@@ -368,10 +396,6 @@ def main():
|
||||
t = datetime.datetime.utcnow().isoformat()
|
||||
params.put("InstallDate", t.encode('utf8'))
|
||||
|
||||
# Wait for IsOffroad to be set before our first update attempt
|
||||
wait_helper = WaitTimeHelper(proc)
|
||||
wait_helper.sleep(30)
|
||||
|
||||
overlay_init = Path(os.path.join(BASEDIR, ".overlay_init"))
|
||||
overlay_init.unlink(missing_ok=True)
|
||||
|
||||
@@ -379,6 +403,13 @@ def main():
|
||||
last_fetch_time = 0
|
||||
update_failed_count = 0
|
||||
|
||||
# Set initial params for offroad alerts
|
||||
set_params(False, 0, None)
|
||||
|
||||
# Wait for IsOffroad to be set before our first update attempt
|
||||
wait_helper = WaitTimeHelper(proc)
|
||||
wait_helper.sleep(30)
|
||||
|
||||
# Run the update loop
|
||||
# * every 1m, do a lightweight internet/update check
|
||||
# * every 10m, do a full git fetch
|
||||
|
||||
Reference in New Issue
Block a user