Files
sunnypilot/selfdrive/mapd/lib/helpers.py
T
Jason Wen c726a82eaf mapd: offline/local OpenStreetMap database, Feature Speed Limits (#55)
* mapd: offline/local database

* link overpy before manager

* add path to deps

* down here

* this too

* don't force redownload/reinstall unless db not current

* make things neater in json

* small fix

* Revert "small fix"

This reverts commit dbc70ee6d40b51e4d7c4a4af4523d23737350905.

* Revert "make things neater in json"

This reverts commit 1b244c552c1bf877e8b6bf879ca73ebf72617025.

* neater attempt 2 (no reboot for now)

* neater attempt 2 (no reboot for now)

* "selected" not working

* make it stick

* already QString

* check when menu is up

* check when menu is up

* interactive buttons

* add label to inform users about car off

* update texts

* set all params properly

* clean up ui logic

* test

* revert

* ui logic again

* interactive button

* after confirmation updates

* only check when selected

* stop signs?

* bruh

* missed

* small cleanup

* query for real from local db

* Revert "query for real from local db"

This reverts commit d7eb664da2949b073c7d7eb00e0098aa01c83ad3.

* don't hold in same object

* remote server as fallback if local server fails

* use different waypoint

* use function

* declare missing vars

* skip SSL/TLS verification

* fallback to online query if local query fails

* don't prompt to reboot if none is selected

* update ui on press

* Revert "skip SSL/TLS verification"

This reverts commit 2eb5c0972a08227edbfc4f50c38d22d2ced62423.

* simplier

* handle ConnectionError

* point to sunnypilot-osm S3 bucket

* revert freq of road name

* small cleanup

* small cleanup

* revert

* cleanup

* TEMP: test online/offline switchover

* Revert "TEMP: test online/offline switchover"

This reverts commit 4641b8e6f26f4015559a9aff2271f1850708ab09.

* set user-agent

* more databases!

* new urls

* TEST: remove check here

* parse timestamp from file content instead of HEAD Last Modified

* not correct

* wrong var

* don't need this

* have list in cpp

* don't read from json

* provide expectation

* add var to gate feature speed limits

* remove unused
2023-03-24 14:46:14 -04:00

103 lines
2.9 KiB
Python

import overpy
import subprocess
import email.utils as eut
import time
from common.params import Params
from system.version import get_version
from urllib.request import Request, urlopen
OSM_LOCAL_PATH = "/data/media/0/osm"
OSM_DB_STAMP_FILE = OSM_LOCAL_PATH + "/db_stamp"
OSM_QUERY = [f"{OSM_LOCAL_PATH}/v0.7.57/bin/osm3s_query", f"--db-dir={OSM_LOCAL_PATH}/db"]
OSM_DB_STAMP_REMOTE = "https://sunnypilot-osm.s3.us-east-2.amazonaws.com/osm-db/timestamps"
def get_current_s3_osm_db_timestamp():
try:
local_osm_db_name = Params().get("OsmLocationName", encoding="utf8")
req = Request(url=f"{OSM_DB_STAMP_REMOTE}/{local_osm_db_name}.txt", headers={"User-Agent": f"sunnypilot-{get_version()}"})
r = urlopen(req)
if r.status != 200:
print(f'Failed to fetch timestamp for S3 OSM db.\n\n{r.status}')
return None
timestamp_string = r.read().decode("utf-8").strip()
if timestamp_string is None:
print('Timestamp file for S3 OSM db contained no value.')
return None
parsed_date = eut.parsedate(timestamp_string)
return time.mktime(parsed_date)
except Exception as e:
print(f'Could not parse timestamp for S3 local osm db.\n\n{e}')
return None
def persist_s3_osm_db_timestamp(timestamp):
try:
with open(OSM_DB_STAMP_FILE, 'w') as file:
file.write(f'{timestamp}')
except Exception as e:
print(f'Failed to timestamp local OSM db.\n\n{e}')
def get_local_osm_timestamp():
try:
with open(OSM_DB_STAMP_FILE, 'r') as file:
return float(file.readline())
except Exception as e:
print(f'Failed to read timestamp for local OSM db.\n\n{e}')
return None
def is_osm_db_up_to_date():
current_osm_ts = get_local_osm_timestamp()
if current_osm_ts is None:
return False
current_s3_osm_ts = get_current_s3_osm_db_timestamp()
if current_s3_osm_ts is None:
return True
return current_osm_ts == current_s3_osm_ts
def timestamp_local_osm_db():
current_s3_osm_ts = get_current_s3_osm_db_timestamp()
if current_s3_osm_ts is not None:
persist_s3_osm_db_timestamp(current_s3_osm_ts)
def is_local_osm_installed(params=Params()):
api = overpy.Overpass()
waypoint = params.get("OsmWayTest", encoding="utf8")
if waypoint is None:
return False
q = f"""
way({waypoint});
(._;>;);
out;
"""
try:
completion = subprocess.run(OSM_QUERY + [f"--request={q}"], check=True, capture_output=True)
print(f'OSM local query returned with exit code: {completion.returncode}')
if completion.returncode != 0:
return False
print(f'OSM Local query returned:\n\n{completion.stdout}')
ways = api.parse_xml(completion.stdout).ways
success = len(ways) == 1
print(f"Test osm script returned {len(ways)} ways")
print(f'OSM local server query {"succeeded" if success else "failed"}')
return success
except Exception as e:
print(e)
return False