timed: always pull time and timezone from GPS (#31112)
* timed * rm timezoned * just gps * ok * little more * fix * datetime * sleep a little --------- Co-authored-by: Comma Device <device@comma.ai> old-commit-hash: 827aa2e4fad3334e594f8a259444f9461579fa2d
This commit is contained in:
@@ -153,6 +153,7 @@ selfdrive/controls/lib/lateral_mpc_lib/*
|
||||
selfdrive/controls/lib/longitudinal_mpc_lib/*
|
||||
|
||||
system/__init__.py
|
||||
system/*.py
|
||||
|
||||
system/hardware/__init__.py
|
||||
system/hardware/base.h
|
||||
|
||||
@@ -4,8 +4,6 @@ third_party/snpe/aarch64-ubuntu-gcc7.5/*
|
||||
third_party/mapbox-gl-native-qt/include/*
|
||||
third_party/acados/larch64/**
|
||||
|
||||
system/timezoned.py
|
||||
|
||||
system/camerad/cameras/camera_qcom2.cc
|
||||
system/camerad/cameras/camera_qcom2.h
|
||||
system/camerad/cameras/camera_util.cc
|
||||
|
||||
@@ -49,7 +49,7 @@ procs = [
|
||||
NativeProcess("proclogd", "system/proclogd", ["./proclogd"], only_onroad),
|
||||
PythonProcess("logmessaged", "system.logmessaged", always_run),
|
||||
PythonProcess("micd", "system.micd", iscar),
|
||||
PythonProcess("timezoned", "system.timezoned", always_run, enabled=not PC),
|
||||
PythonProcess("timed", "system.timed", always_run, enabled=not PC),
|
||||
|
||||
PythonProcess("dmonitoringmodeld", "selfdrive.modeld.dmonitoringmodeld", driverview, enabled=(not PC or WEBCAM)),
|
||||
NativeProcess("encoderd", "system/loggerd", ["./encoderd"], only_onroad),
|
||||
|
||||
@@ -53,7 +53,7 @@ PROCS = {
|
||||
"selfdrive.tombstoned": 0,
|
||||
"./logcatd": 0,
|
||||
"system.micd": 6.0,
|
||||
"system.timezoned": 0,
|
||||
"system.timed": 0,
|
||||
"selfdrive.boardd.pandad": 0,
|
||||
"selfdrive.statsd": 0.4,
|
||||
"selfdrive.navd.navd": 0.4,
|
||||
|
||||
94
system/timed.py
Executable file
94
system/timed.py
Executable file
@@ -0,0 +1,94 @@
|
||||
#!/usr/bin/env python3
|
||||
import datetime
|
||||
import os
|
||||
import subprocess
|
||||
import time
|
||||
from typing import NoReturn
|
||||
|
||||
from timezonefinder import TimezoneFinder
|
||||
|
||||
import cereal.messaging as messaging
|
||||
from openpilot.common.params import Params
|
||||
from openpilot.common.swaglog import cloudlog
|
||||
from openpilot.system.hardware import AGNOS
|
||||
|
||||
|
||||
def set_timezone(timezone):
|
||||
valid_timezones = subprocess.check_output('timedatectl list-timezones', shell=True, encoding='utf8').strip().split('\n')
|
||||
if timezone not in valid_timezones:
|
||||
cloudlog.error(f"Timezone not supported {timezone}")
|
||||
return
|
||||
|
||||
cloudlog.debug(f"Setting timezone to {timezone}")
|
||||
try:
|
||||
if AGNOS:
|
||||
tzpath = os.path.join("/usr/share/zoneinfo/", timezone)
|
||||
subprocess.check_call(f'sudo su -c "ln -snf {tzpath} /data/etc/tmptime && \
|
||||
mv /data/etc/tmptime /data/etc/localtime"', shell=True)
|
||||
subprocess.check_call(f'sudo su -c "echo \"{timezone}\" > /data/etc/timezone"', shell=True)
|
||||
else:
|
||||
subprocess.check_call(f'sudo timedatectl set-timezone {timezone}', shell=True)
|
||||
except subprocess.CalledProcessError:
|
||||
cloudlog.exception(f"Error setting timezone to {timezone}")
|
||||
|
||||
|
||||
def set_time(new_time):
|
||||
diff = datetime.datetime.now() - new_time
|
||||
if diff < datetime.timedelta(seconds=10):
|
||||
cloudlog.debug(f"Time diff too small: {diff}")
|
||||
return
|
||||
|
||||
cloudlog.debug(f"Setting time to {new_time}")
|
||||
try:
|
||||
subprocess.run(f"TZ=UTC date -s '{new_time}'", shell=True, check=True)
|
||||
except subprocess.CalledProcessError:
|
||||
cloudlog.exception("timed.failed_setting_time")
|
||||
|
||||
|
||||
def main() -> NoReturn:
|
||||
"""
|
||||
timed has two responsibilities:
|
||||
- getting the current time
|
||||
- getting the current timezone
|
||||
|
||||
GPS directly gives time, and timezone is looked up from GPS position.
|
||||
AGNOS will also use NTP to update the time.
|
||||
"""
|
||||
|
||||
params = Params()
|
||||
tf = TimezoneFinder()
|
||||
|
||||
# Restore timezone from param
|
||||
tz = params.get("Timezone", encoding='utf8')
|
||||
tf = TimezoneFinder()
|
||||
if tz is not None:
|
||||
cloudlog.debug("Restoring timezone from param")
|
||||
set_timezone(tz)
|
||||
|
||||
sm = messaging.SubMaster(['liveLocationKalman'])
|
||||
while True:
|
||||
sm.update(1000)
|
||||
|
||||
llk = sm['liveLocationKalman']
|
||||
if not llk.gpsOK or (time.monotonic() - sm.logMonoTime['liveLocationKalman']/1e9) > 0.2:
|
||||
continue
|
||||
|
||||
# set time
|
||||
# TODO: account for unixTimesatmpMillis being a (usually short) time in the past
|
||||
gps_time = datetime.datetime.fromtimestamp(llk.unixTimestampMillis / 1000.)
|
||||
set_time(gps_time)
|
||||
|
||||
# set timezone
|
||||
pos = llk.positionGeodetic.value
|
||||
if len(pos) == 3:
|
||||
gps_timezone = tf.timezone_at(lat=pos[0], lng=pos[1])
|
||||
if gps_timezone is None:
|
||||
cloudlog.critical(f"No timezone found based on {pos=}")
|
||||
else:
|
||||
set_timezone(gps_timezone)
|
||||
params.put_nonblocking("Timezone", gps_timezone)
|
||||
|
||||
time.sleep(10)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -1,70 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
import json
|
||||
import os
|
||||
import time
|
||||
import subprocess
|
||||
from typing import NoReturn
|
||||
|
||||
from timezonefinder import TimezoneFinder
|
||||
|
||||
from openpilot.common.params import Params
|
||||
from openpilot.system.hardware import AGNOS
|
||||
from openpilot.common.swaglog import cloudlog
|
||||
from openpilot.system.version import get_version
|
||||
|
||||
REQUEST_HEADERS = {'User-Agent': "openpilot-" + get_version()}
|
||||
|
||||
|
||||
def set_timezone(valid_timezones, timezone):
|
||||
if timezone not in valid_timezones:
|
||||
cloudlog.error(f"Timezone not supported {timezone}")
|
||||
return
|
||||
|
||||
cloudlog.info(f"Setting timezone to {timezone}")
|
||||
try:
|
||||
if AGNOS:
|
||||
tzpath = os.path.join("/usr/share/zoneinfo/", timezone)
|
||||
subprocess.check_call(f'sudo su -c "ln -snf {tzpath} /data/etc/tmptime && \
|
||||
mv /data/etc/tmptime /data/etc/localtime"', shell=True)
|
||||
subprocess.check_call(f'sudo su -c "echo \"{timezone}\" > /data/etc/timezone"', shell=True)
|
||||
else:
|
||||
subprocess.check_call(f'sudo timedatectl set-timezone {timezone}', shell=True)
|
||||
except subprocess.CalledProcessError:
|
||||
cloudlog.exception(f"Error setting timezone to {timezone}")
|
||||
|
||||
|
||||
def main() -> NoReturn:
|
||||
params = Params()
|
||||
tf = TimezoneFinder()
|
||||
|
||||
# Get allowed timezones
|
||||
valid_timezones = subprocess.check_output('timedatectl list-timezones', shell=True, encoding='utf8').strip().split('\n')
|
||||
|
||||
timezone = params.get("Timezone", encoding='utf8')
|
||||
if timezone is not None:
|
||||
cloudlog.debug("Setting timezone based on param")
|
||||
set_timezone(valid_timezones, timezone)
|
||||
|
||||
while True:
|
||||
time.sleep(60)
|
||||
|
||||
location = params.get("LastGPSPosition", encoding='utf8')
|
||||
|
||||
# Find timezone by reverse geocoding the last known gps location
|
||||
if location is not None:
|
||||
cloudlog.debug("Setting timezone based on GPS location")
|
||||
try:
|
||||
location = json.loads(location)
|
||||
except Exception:
|
||||
cloudlog.exception("Error parsing location")
|
||||
continue
|
||||
|
||||
timezone = tf.timezone_at(lng=location['longitude'], lat=location['latitude'])
|
||||
if timezone is None:
|
||||
cloudlog.error(f"No timezone found based on location, {location}")
|
||||
continue
|
||||
set_timezone(valid_timezones, timezone)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user