|  |  | @ -1,36 +1,12 @@ | 
			
		
	
		
		
			
				
					
					|  |  |  | #!/usr/bin/env python3 |  |  |  | #!/usr/bin/env python3 | 
			
		
	
		
		
			
				
					
					|  |  |  | import datetime |  |  |  | import datetime | 
			
		
	
		
		
			
				
					
					|  |  |  | import os |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | import subprocess |  |  |  | import subprocess | 
			
		
	
		
		
			
				
					
					|  |  |  | import time |  |  |  | import time | 
			
		
	
		
		
			
				
					
					|  |  |  | from typing import NoReturn |  |  |  | from typing import NoReturn | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | from timezonefinder import TimezoneFinder |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | import cereal.messaging as messaging |  |  |  | import cereal.messaging as messaging | 
			
		
	
		
		
			
				
					
					|  |  |  | from openpilot.common.time import system_time_valid |  |  |  | from openpilot.common.time import system_time_valid | 
			
		
	
		
		
			
				
					
					|  |  |  | from openpilot.common.params import Params |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | from openpilot.common.swaglog import cloudlog |  |  |  | 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): |  |  |  | def set_time(new_time): | 
			
		
	
	
		
		
			
				
					|  |  | @ -48,23 +24,13 @@ def set_time(new_time): | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | def main() -> NoReturn: |  |  |  | def main() -> NoReturn: | 
			
		
	
		
		
			
				
					
					|  |  |  |   """ |  |  |  |   """ | 
			
		
	
		
		
			
				
					
					|  |  |  |     timed has two responsibilities: |  |  |  |     timed has one responsibility: | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     - getting the current time |  |  |  |     - getting the current time | 
			
		
	
		
		
			
				
					
					|  |  |  |     - getting the current timezone |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     GPS directly gives time, and timezone is looked up from GPS position. |  |  |  |     GPS directly gives time. | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     AGNOS will also use NTP to update the time. |  |  |  |     AGNOS will also use NTP to update the time. | 
			
		
	
		
		
			
				
					
					|  |  |  |   """ |  |  |  |   """ | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |   params = Params() |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   # 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) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   pm = messaging.PubMaster(['clocks']) |  |  |  |   pm = messaging.PubMaster(['clocks']) | 
			
		
	
		
		
			
				
					
					|  |  |  |   sm = messaging.SubMaster(['liveLocationKalman']) |  |  |  |   sm = messaging.SubMaster(['liveLocationKalman']) | 
			
		
	
		
		
			
				
					
					|  |  |  |   while True: |  |  |  |   while True: | 
			
		
	
	
		
		
			
				
					|  |  | @ -84,16 +50,6 @@ def main() -> NoReturn: | 
			
		
	
		
		
			
				
					
					|  |  |  |     gps_time = datetime.datetime.fromtimestamp(llk.unixTimestampMillis / 1000.) |  |  |  |     gps_time = datetime.datetime.fromtimestamp(llk.unixTimestampMillis / 1000.) | 
			
		
	
		
		
			
				
					
					|  |  |  |     set_time(gps_time) |  |  |  |     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) |  |  |  |     time.sleep(10) | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | if __name__ == "__main__": |  |  |  | if __name__ == "__main__": | 
			
		
	
	
		
		
			
				
					|  |  | 
 |