2021-02-06 18:07:37 +08:00
|
|
|
#!/usr/bin/env python3
|
|
|
|
import json
|
2021-02-19 10:14:34 +08:00
|
|
|
import os
|
|
|
|
import time
|
2021-02-06 18:07:37 +08:00
|
|
|
import subprocess
|
2021-12-29 01:07:00 +08:00
|
|
|
from typing import NoReturn
|
2021-02-06 18:07:37 +08:00
|
|
|
|
|
|
|
import requests
|
|
|
|
from timezonefinder import TimezoneFinder
|
|
|
|
|
|
|
|
from common.params import Params
|
2022-06-12 07:38:24 +08:00
|
|
|
from system.hardware import AGNOS
|
2022-06-12 14:19:27 +08:00
|
|
|
from system.swaglog import cloudlog
|
2021-02-06 18:07:37 +08:00
|
|
|
|
|
|
|
|
|
|
|
def set_timezone(valid_timezones, timezone):
|
|
|
|
if timezone not in valid_timezones:
|
|
|
|
cloudlog.error(f"Timezone not supported {timezone}")
|
|
|
|
return
|
|
|
|
|
2021-05-31 18:17:52 +08:00
|
|
|
cloudlog.debug(f"Setting timezone to {timezone}")
|
2021-02-06 18:07:37 +08:00
|
|
|
try:
|
2022-06-02 21:20:51 +08:00
|
|
|
if AGNOS:
|
2021-02-19 10:14:34 +08:00
|
|
|
tzpath = os.path.join("/usr/share/zoneinfo/", timezone)
|
2021-02-20 12:49:06 +08:00
|
|
|
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)
|
2021-02-19 10:14:34 +08:00
|
|
|
else:
|
|
|
|
subprocess.check_call(f'sudo timedatectl set-timezone {timezone}', shell=True)
|
2021-02-06 18:07:37 +08:00
|
|
|
except subprocess.CalledProcessError:
|
|
|
|
cloudlog.exception(f"Error setting timezone to {timezone}")
|
|
|
|
|
|
|
|
|
2021-12-29 01:07:00 +08:00
|
|
|
def main() -> NoReturn:
|
2021-02-06 18:07:37 +08:00
|
|
|
params = Params()
|
|
|
|
tf = TimezoneFinder()
|
|
|
|
|
|
|
|
# Get allowed timezones
|
|
|
|
valid_timezones = subprocess.check_output('timedatectl list-timezones', shell=True, encoding='utf8').strip().split('\n')
|
|
|
|
|
|
|
|
while True:
|
|
|
|
time.sleep(60)
|
|
|
|
|
2021-04-07 21:36:37 +08:00
|
|
|
is_onroad = not params.get_bool("IsOffroad")
|
2021-02-06 18:07:37 +08:00
|
|
|
if is_onroad:
|
|
|
|
continue
|
|
|
|
|
|
|
|
# Set based on param
|
|
|
|
timezone = params.get("Timezone", encoding='utf8')
|
|
|
|
if timezone is not None:
|
2021-05-31 18:17:52 +08:00
|
|
|
cloudlog.debug("Setting timezone based on param")
|
2021-02-06 18:07:37 +08:00
|
|
|
set_timezone(valid_timezones, timezone)
|
|
|
|
continue
|
|
|
|
|
|
|
|
location = params.get("LastGPSPosition", encoding='utf8')
|
|
|
|
|
|
|
|
# Find timezone based on IP geolocation if no gps location is available
|
|
|
|
if location is None:
|
2021-05-31 18:17:52 +08:00
|
|
|
cloudlog.debug("Setting timezone based on IP lookup")
|
2021-02-06 18:07:37 +08:00
|
|
|
try:
|
|
|
|
r = requests.get("https://ipapi.co/timezone", timeout=10)
|
|
|
|
if r.status_code == 200:
|
|
|
|
set_timezone(valid_timezones, r.text)
|
|
|
|
else:
|
|
|
|
cloudlog.error(f"Unexpected status code from api {r.status_code}")
|
2021-02-15 23:19:01 +08:00
|
|
|
|
|
|
|
time.sleep(3600) # Don't make too many API requests
|
2021-02-06 18:07:37 +08:00
|
|
|
except requests.exceptions.RequestException:
|
|
|
|
cloudlog.exception("Error getting timezone based on IP")
|
|
|
|
continue
|
|
|
|
|
|
|
|
# Find timezone by reverse geocoding the last known gps location
|
|
|
|
else:
|
2021-05-31 18:17:52 +08:00
|
|
|
cloudlog.debug("Setting timezone based on GPS location")
|
2021-02-06 18:07:37 +08:00
|
|
|
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()
|