mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-09-03 14:43:48 +08:00
dcd382ffb8
* refactor: enhance parameter handling and add new parameter retrieval method - Refactored `get_param_as_byte` for better modularity and added `_to_bytes` helper function. - Introduced `getParamsAllKeysV1` to retrieve all keys with enhanced metadata. * refactor: update parameter handling and response structure in sunnylink - Modified `_to_bytes` to accept `bytes` type for improved type consistency. - Adjusted response keys in `sunnylinkd` for clarity. * fix: update `get_param_as_byte` to use corrected method for default values - Replaced `get_default` with `get_default_value` for accurate param retrieval. - Ensures consistent handling of default parameter values. * refactor: remove redundant `None` check in `sunnylinkd.py` - Streamlined parameter iteration by eliminating unnecessary `None` validation. - Simplifies logic for constructing `params_dict`. * refactor: streamline `sunnylinkd` response by removing redundant `keys_v1` field - Simplified return structure by excluding unused `keys_v1` key. - Reduces response payload for improved efficiency. * refactor: split `getParamsAllKeys` into distinct functions for improved clarity - Added `getParamsAllKeysV1` to preserve original metadata-rich behavior. - Revised `getParamsAllKeys` to return a simplified list of parameter keys. * style: remove extraneous newline in `sunnylinkd.py` - Ensures consistent formatting and adheres to style guidelines. * Test
121 lines
4.4 KiB
Python
121 lines
4.4 KiB
Python
import base64
|
|
import gzip
|
|
import json
|
|
from sunnypilot.sunnylink.api import SunnylinkApi, UNREGISTERED_SUNNYLINK_DONGLE_ID
|
|
from openpilot.common.params import Params, ParamKeyType
|
|
from openpilot.system.version import is_prebuilt
|
|
|
|
|
|
def get_sunnylink_status(params=None) -> tuple[bool, bool]:
|
|
"""Get the status of Sunnylink on the device. Returns a tuple of (is_sunnylink_enabled, is_registered)."""
|
|
params = params or Params()
|
|
is_sunnylink_enabled = params.get_bool("SunnylinkEnabled")
|
|
is_registered = params.get("SunnylinkDongleId") not in (None, UNREGISTERED_SUNNYLINK_DONGLE_ID)
|
|
return is_sunnylink_enabled, is_registered
|
|
|
|
|
|
def sunnylink_ready(params=None) -> bool:
|
|
"""Check if the device is ready to communicate with Sunnylink. That means it is enabled and registered."""
|
|
params = params or Params()
|
|
is_sunnylink_enabled, is_registered = get_sunnylink_status(params)
|
|
return is_sunnylink_enabled and is_registered
|
|
|
|
|
|
def use_sunnylink_uploader(params) -> bool:
|
|
"""Check if the device is ready to use Sunnylink and the uploader is enabled."""
|
|
return sunnylink_ready(params) and params.get_bool("EnableSunnylinkUploader")
|
|
|
|
|
|
def sunnylink_need_register(params=None) -> bool:
|
|
"""Check if the device needs to be registered with Sunnylink."""
|
|
params = params or Params()
|
|
is_sunnylink_enabled, is_registered = get_sunnylink_status(params)
|
|
return is_sunnylink_enabled and not is_registered
|
|
|
|
|
|
def register_sunnylink():
|
|
"""Register the device with Sunnylink if it is enabled."""
|
|
extra_args = {}
|
|
|
|
if not Params().get_bool("SunnylinkEnabled"):
|
|
print("Sunnylink is not enabled. Exiting.")
|
|
exit(0)
|
|
|
|
if not is_prebuilt():
|
|
extra_args = {
|
|
"verbose": True,
|
|
"timeout": 60
|
|
}
|
|
|
|
sunnylink_id = SunnylinkApi(None).register_device(None, **extra_args)
|
|
print(f"SunnyLinkId: {sunnylink_id}")
|
|
|
|
|
|
def get_api_token():
|
|
"""Get the API token for the device."""
|
|
params = Params()
|
|
sunnylink_dongle_id = params.get("SunnylinkDongleId")
|
|
sunnylink_api = SunnylinkApi(sunnylink_dongle_id)
|
|
token = sunnylink_api.get_token()
|
|
print(f"API Token: {token}")
|
|
|
|
|
|
def _to_bytes(value: bytes | None, param_type: ParamKeyType) -> bytes | None:
|
|
"""Convert a parameter value to bytes based on its type."""
|
|
if value is None:
|
|
return None
|
|
|
|
if param_type == ParamKeyType.BYTES:
|
|
return bytes(value)
|
|
if param_type == ParamKeyType.JSON:
|
|
return json.dumps(value).encode("utf-8")
|
|
return str(value).encode("utf-8")
|
|
|
|
|
|
def get_param_as_byte(param_name: str, params=None, get_default=False) -> bytes | None:
|
|
"""Get a parameter as bytes. Returns None if the parameter does not exist."""
|
|
params = params or Params()
|
|
value = params.get(param_name) if not get_default else params.get_default_value(param_name)
|
|
param_type = params.get_type(param_name)
|
|
return _to_bytes(value, param_type)
|
|
|
|
def save_param_from_base64_encoded_string(param_name: str, base64_encoded_data: str, is_compressed=False) -> None:
|
|
"""Save a parameter from bytes. Overwrites the parameter if it already exists."""
|
|
params = Params()
|
|
# Find real param name (with correct casing)
|
|
param_type = params.get_type(param_name)
|
|
value = base64.b64decode(base64_encoded_data)
|
|
|
|
if is_compressed:
|
|
value = gzip.decompress(value)
|
|
|
|
# We convert to string anything that isn't bytes first. We later transform further.
|
|
param_value = _convert_param_to_type(value, param_type)
|
|
params.put(param_name, param_value)
|
|
|
|
|
|
def _convert_param_to_type(value: bytes, param_type: ParamKeyType) -> bytes | str | int | float | bool | dict | None:
|
|
"""
|
|
Convert a byte value to the specified param type. Used internally when getting a Param to convert it to the right type.
|
|
If this method looks familiar, it's because on SP we have a similar one in openpilot/sunnypilot/car/__init__.py.
|
|
"""
|
|
|
|
# We convert to string anything that isn't bytes first. We later transform further.
|
|
if param_type != ParamKeyType.BYTES:
|
|
value = value.decode('utf-8') # type: ignore
|
|
|
|
if param_type == ParamKeyType.STRING:
|
|
value = value
|
|
elif param_type == ParamKeyType.BOOL:
|
|
value = value.lower() in ('true', '1', 'yes') # type: ignore
|
|
elif param_type == ParamKeyType.INT:
|
|
value = int(value) # type: ignore
|
|
elif param_type == ParamKeyType.FLOAT:
|
|
value = float(value) # type: ignore
|
|
elif param_type == ParamKeyType.TIME:
|
|
value = str(value) # type: ignore
|
|
elif param_type == ParamKeyType.JSON:
|
|
value = json.loads(value)
|
|
|
|
return value
|