#!/usr/bin/env python3
import argparse
from openpilot . common . basedir import BASEDIR
from openpilot . tools . lib . logreader import MultiLogIterator
from openpilot . tools . lib . route import Route
from openpilot . selfdrive . car . fw_versions import match_fw_to_car
from openpilot . selfdrive . car . interfaces import get_interface_attr
ALL_FW_VERSIONS = get_interface_attr ( " FW_VERSIONS " )
ALL_CARS = get_interface_attr ( " CAR " )
PLATFORM_TO_PYTHON_CAR_NAME = { brand : { car . value : car . name for car in ALL_CARS [ brand ] } for brand in ALL_CARS }
BRAND_TO_PLATFORMS = { brand : [ car . value for car in ALL_CARS [ brand ] ] for brand in ALL_CARS }
PLATFORM_TO_BRAND = dict ( sum ( [ [ ( platform , brand ) for platform in BRAND_TO_PLATFORMS [ brand ] ] for brand in BRAND_TO_PLATFORMS ] , [ ] ) )
def add_fw_versions ( brand , platform , new_fw_versions ) :
filename = f " { BASEDIR } /selfdrive/car/ { brand } /values.py "
with open ( filename , " r " ) as f :
values_py = f . read ( )
for key in new_fw_versions . keys ( ) :
ecu , addr , subAddr = key
fw_version = new_fw_versions [ key ]
platform_start = values_py . index ( f " CAR. { PLATFORM_TO_PYTHON_CAR_NAME [ brand ] [ platform ] } : {{ " )
start = values_py . index ( f " (Ecu. { ecu } , { hex ( addr ) } , { subAddr } ): [ " , platform_start )
try :
end_str = " ], \n "
end = values_py . index ( end_str , start )
except ValueError :
end_str = " ] \n "
end = values_py . index ( end_str , start )
values_py = values_py [ : end ] + f " { fw_version } , \n " + values_py [ end : ]
with open ( filename , " w " ) as f :
f . write ( values_py )
if __name__ == " __main__ " :
parser = argparse . ArgumentParser ( description = " Auto fingerprint from a route " )
parser . add_argument ( " route " , help = " The route name to use " )
parser . add_argument ( " platform " , help = " The platform, or leave empty to auto-determine using fuzzy " , default = None , nargs = ' ? ' )
args = parser . parse_args ( )
route = Route ( args . route )
lr = MultiLogIterator ( route . qlog_paths ( ) )
carFw = None
carVin = None
carPlatform = None
for msg in lr :
if msg . which ( ) == " carParams " :
carFw = msg . carParams . carFw
carVin = msg . carParams . carVin
carPlatform = msg . carParams . carFingerprint
break
if carFw is None :
raise Exception ( " No fw versions in the provided route... " )
if args . platform is None : # attempt to auto-determine platform with other fuzzy fingerprints
_ , possible_platforms = match_fw_to_car ( carFw , log = False )
if len ( possible_platforms ) != 1 :
print ( f " Unable to auto-determine platform, possible platforms: { possible_platforms } " )
if carPlatform != " mock " :
print ( " Using platform from route " )
platform = carPlatform
else :
raise Exception ( " unable to determine platform, try manually specifying the fingerprint. " )
else :
platform = list ( possible_platforms ) [ 0 ]
else :
platform = args . platform
print ( " Attempting to add fw version for: " , platform )
brand = PLATFORM_TO_BRAND [ platform ]
new_fw_versions = { }
for fw in carFw :
if fw . brand == brand :
addr = fw . address
subAddr = None if fw . subAddress == 0 else fw . subAddress
key = ( fw . ecu . raw , addr , subAddr )
if key in ALL_FW_VERSIONS [ brand ] [ platform ] :
fw_versions = set ( ALL_FW_VERSIONS [ brand ] [ platform ] [ key ] )
if fw . fwVersion not in fw_versions :
new_fw_versions [ ( fw . ecu , addr , subAddr ) ] = fw . fwVersion
if not new_fw_versions :
print ( " No new fw versions found... " )
add_fw_versions ( brand , platform , new_fw_versions )