mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-10-28 00:53:45 +08:00
a82935f326
Integrate onroad views, configurable widgets, local settings, steering-profile contracts, Bluetooth and Android Auto with their device and runtime services. Co-authored-by: Adeeb Shihadeh <adeebshihadeh@gmail.com> Co-authored-by: Daniel Koepping <elkoled@gmail.com> Co-authored-by: Danny <dannyirwin31@yahoo.com> Co-authored-by: DimitriChrysafis <Dimitri.chrysafis@gmail.com> Co-authored-by: Dom <168790843+firestar5683@users.noreply.github.com> Co-authored-by: Harald Schäfer <harald.the.engineer@gmail.com> Co-authored-by: Prabhaav Pillai <prabhaav@msu.edu> Co-authored-by: Shane Smiskol <shane@smiskol.com> Co-authored-by: dirwin31 <83434411+dirwin31@users.noreply.github.com> Co-authored-by: firestarsdog <229254897+firestarsdog@users.noreply.github.com> Co-authored-by: stef <19478336+stefpi@users.noreply.github.com> Co-authored-by: whoisdomi <dcantu83@gmail.com> Co-authored-by: Intelli <contact@intelli.software> Co-authored-by: pharmacomaniac <blittle65@gmail.com> Co-authored-by: prabhaavp <prabhaav@msu.edu>
107 lines
3.8 KiB
Python
107 lines
3.8 KiB
Python
from dataclasses import dataclass
|
|
from pathlib import Path
|
|
|
|
from openpilot.starpilot.saved_source import read_saved
|
|
from openpilot.starpilot.vehicle_selection import read_selection
|
|
|
|
|
|
KEYS = ('RemoteStartBootsComma', 'HKGRemoteStartBootsComma', 'IgnoreIgnitionLine', 'TeslaWakeOnCAN')
|
|
|
|
|
|
def supported_keys(cp):
|
|
from opendbc.car.gm.values import CAR as GM
|
|
from opendbc.car.hyundai.values import CAR as HKG, HyundaiFlags
|
|
from opendbc.car.tesla.values import CAR as TESLA
|
|
try:
|
|
if cp is None or cp.notCar:
|
|
return ()
|
|
if cp.brand == 'gm' and cp.carFingerprint in tuple(GM) and cp.openpilotLongitudinalControl:
|
|
return ('RemoteStartBootsComma', 'IgnoreIgnitionLine')
|
|
if (cp.brand == 'hyundai' and cp.carFingerprint in tuple(HKG) and cp.flags & HyundaiFlags.CANFD and
|
|
cp.openpilotLongitudinalControl):
|
|
return ('HKGRemoteStartBootsComma',)
|
|
if cp.brand == 'tesla' and cp.carFingerprint in (TESLA.TESLA_MODEL_3, TESLA.TESLA_MODEL_Y, TESLA.TESLA_MODEL_X):
|
|
return ('TeslaWakeOnCAN',)
|
|
except (AttributeError, TypeError, ValueError):
|
|
pass
|
|
return ()
|
|
|
|
|
|
def snapshot(params):
|
|
return tuple((key, *read_saved(params, key, 8)) for key in KEYS)
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class FirmwareChoice:
|
|
gm: bool = False
|
|
hkg: bool = False
|
|
can_only: bool = False
|
|
tesla: bool = False
|
|
|
|
@property
|
|
def alternate(self):
|
|
return self.gm or self.hkg or self.can_only or self.tesla
|
|
|
|
def filename(self, app_fn):
|
|
if not self.alternate:
|
|
return app_fn
|
|
if app_fn not in ('panda.bin.signed', 'panda_h7.bin.signed'):
|
|
raise ValueError('Unsupported Panda for vehicle wake firmware')
|
|
parts = ['panda_h7' if app_fn == 'panda_h7.bin.signed' else 'panda']
|
|
if self.tesla:
|
|
parts.extend(('tesla', 'wake'))
|
|
elif self.hkg:
|
|
parts.extend(('hkg', 'remote'))
|
|
elif self.gm:
|
|
parts.append('remote')
|
|
if self.can_only:
|
|
parts.append('can_ignition_only')
|
|
return '_'.join(parts) + '.bin.signed'
|
|
|
|
|
|
def resolve(cp, sources):
|
|
supported = supported_keys(cp)
|
|
enabled = {key for key, raw, readable in sources if readable and raw == b'1' and key in supported}
|
|
return FirmwareChoice('RemoteStartBootsComma' in enabled, 'HKGRemoteStartBootsComma' in enabled,
|
|
'IgnoreIgnitionLine' in enabled, 'TeslaWakeOnCAN' in enabled)
|
|
|
|
|
|
def startup_choice(params):
|
|
from openpilot.starpilot.schema_cache import inspect_cache
|
|
from openpilot.cereal import messaging
|
|
from opendbc.car.structs import car
|
|
selection = read_selection(params)
|
|
sources = snapshot(params)
|
|
raw, readable = read_saved(params, 'CarParamsPersistent', 1_048_576)
|
|
if not selection.readable or not selection.valid or selection.platform is None or not readable or raw is None:
|
|
return FirmwareChoice()
|
|
try:
|
|
inspected = inspect_cache('CarParamsPersistent', raw)
|
|
if inspected.status != 'valid' or inspected.payload is None:
|
|
return FirmwareChoice()
|
|
cp = messaging.log_from_bytes(inspected.payload, car.CarParams)
|
|
if selection.platform is not None and selection.platform != cp.carFingerprint:
|
|
return FirmwareChoice()
|
|
if (read_selection(params) != selection or snapshot(params) != sources or
|
|
read_saved(params, 'CarParamsPersistent', 1_048_576) != (raw, True)):
|
|
return FirmwareChoice()
|
|
return resolve(cp, sources)
|
|
except (AttributeError, OSError, RuntimeError, TypeError, ValueError, OverflowError):
|
|
return FirmwareChoice()
|
|
|
|
|
|
def firmware_path(directory, app_fn, choice):
|
|
path = Path(directory) / choice.filename(app_fn)
|
|
if not path.is_file() or path.stat().st_size == 0:
|
|
raise FileNotFoundError(f'Required Panda firmware missing or empty: {path.name}')
|
|
return str(path)
|
|
|
|
|
|
def firmware_ready(directory, choice):
|
|
try:
|
|
for app_fn in ('panda.bin.signed', 'panda_h7.bin.signed'):
|
|
firmware_path(directory, app_fn, choice)
|
|
return True
|
|
except (OSError, ValueError):
|
|
return False
|