Refactor Sunnylink status checks and improve logic in multiple modules

This update streamlines how the system checks the status of Sunnylink. New methods were added to `sunnylink.py` to encapsify status checking logic, such as whether the device is connected to a network, if Sunnylink is enabled, if the device is registered and if registration is needed. This resulted in simplified code in `sunnylinkd.py` and `process_config.py` as these status checks are now standardized. Furthermore, removed repetitive code in `sunnylinkd.py` by replacing it with these new methods and modified the while loop conditions according to the new status methods.
This commit is contained in:
DevTekVE
2024-06-21 09:14:00 +02:00
parent 1bd2a2f007
commit 4c6fec9ddf
3 changed files with 51 additions and 21 deletions
+6 -6
View File
@@ -8,7 +8,6 @@ import os
import threading
import time
from openpilot.common.api.sunnylink import UNREGISTERED_SUNNYLINK_DONGLE_ID
from openpilot.system.athena.athenad import ws_send, jsonrpc_handler, \
recv_queue, UploadQueueCache, upload_queue, cur_upload_items, backoff, ws_manage, log_handler
from jsonrpc import dispatcher
@@ -19,6 +18,7 @@ from openpilot.common.api import SunnylinkApi
from openpilot.common.params import Params
from openpilot.common.realtime import set_core_affinity
from openpilot.common.swaglog import cloudlog
from openpilot.system.manager.sunnylink import sunnylink_need_register, sunnylink_ready
import cereal.messaging as messaging
SUNNYLINK_ATHENA_HOST = os.getenv('SUNNYLINK_ATHENA_HOST', 'wss://ws.stg.api.sunnypilot.ai')
@@ -53,7 +53,7 @@ def handle_long_poll(ws: WebSocket, exit_event: threading.Event | None) -> None:
thread.start()
try:
while not end_event.wait(0.1):
if not params.get_bool("SunnylinkEnabled"):
if not sunnylink_ready(params):
cloudlog.warning("Exiting sunnylinkd.handle_long_poll as SunnylinkEnabled is False")
break
@@ -190,7 +190,7 @@ def main(exit_event: threading.Event = None):
except Exception:
cloudlog.exception("failed to set core affinity")
while params.get_bool("SunnylinkEnabled") and not params.get("SunnylinkDongleId", encoding='utf-8') not in (None, UNREGISTERED_SUNNYLINK_DONGLE_ID):
while sunnylink_need_register(params):
cloudlog.info("Waiting for sunnylink registration to complete")
time.sleep(10)
@@ -199,7 +199,7 @@ def main(exit_event: threading.Event = None):
ws_uri = SUNNYLINK_ATHENA_HOST
conn_start = None
conn_retries = 0
while (exit_event is None or not exit_event.is_set()) and params.get_bool("SunnylinkEnabled"):
while (exit_event is None or not exit_event.is_set()) and sunnylink_ready(params):
try:
if conn_start is None:
conn_start = time.monotonic()
@@ -230,8 +230,8 @@ def main(exit_event: threading.Event = None):
time.sleep(backoff(conn_retries))
if not params.get_bool("SunnylinkEnabled"):
cloudlog.debug("Reached end of sunnylinkd.main while SunnylinkEnabled is False so will wait for 60 seconds before exiting")
if not sunnylink_ready(params):
cloudlog.debug("Reached end of sunnylinkd.main while sunnylink is not ready. Waiting 60s before retrying")
time.sleep(60)
+9 -12
View File
@@ -1,12 +1,12 @@
import os
from cereal import car
from openpilot.common.api.sunnylink import UNREGISTERED_SUNNYLINK_DONGLE_ID
from openpilot.common.params import Params
from openpilot.system.hardware import PC, TICI
from openpilot.selfdrive.sunnypilot import get_model_generation
from openpilot.system.manager.process import PythonProcess, NativeProcess, DaemonProcess
from openpilot.system.mapd_manager import MAPD_PATH, COMMON_DIR
from openpilot.system.manager.sunnylink import sunnylink_need_register, sunnylink_ready
WEBCAM = os.getenv("USE_WEBCAM") is not None
@@ -48,16 +48,13 @@ def model_use_nav(started, params, CP: car.CarParams) -> bool:
custom_model, model_gen = get_model_generation(params)
return started and custom_model and model_gen not in (0, 4)
def sunnylink_ready_shim(started, params, CP: car.CarParams) -> bool:
"""Shim for sunnylink_ready to match the process manager signature."""
return sunnylink_ready(params)
def use_sunnylink(started, params, CP: car.CarParams) -> bool:
is_sunnylink_enabled = params.get_bool("SunnylinkEnabled")
is_registered = params.get("SunnylinkDongleId", encoding='utf-8') not in (None, UNREGISTERED_SUNNYLINK_DONGLE_ID)
return is_sunnylink_enabled and is_registered
def sunnylink_need_register(started, params, CP: car.CarParams) -> bool:
is_sunnylink_enabled = params.get_bool("SunnylinkEnabled")
is_registered = params.get("SunnylinkDongleId", encoding='utf-8') not in (None, UNREGISTERED_SUNNYLINK_DONGLE_ID)
return is_sunnylink_enabled and not is_registered
def sunnylink_need_register_shim(started, params, CP: car.CarParams) -> bool:
"""Shim for sunnylink_need_register to match the process manager signature."""
return sunnylink_need_register(params)
procs = [
DaemonProcess("manage_athenad", "system.athena.manage_athenad", "AthenadPid"),
@@ -117,12 +114,12 @@ procs = [
# Sunnylink <3
DaemonProcess("manage_sunnylinkd", "system.athena.manage_sunnylinkd", "SunnylinkdPid"),
PythonProcess("sunnylink_registration", "system.manager.sunnylink", sunnylink_need_register),
PythonProcess("sunnylink_registration", "system.manager.sunnylink", sunnylink_need_register_shim),
]
if os.path.exists("../loggerd/sunnylink_uploader.py"):
procs += [
PythonProcess("sunnylink_uploader", "system.loggerd.sunnylink_uploader", use_sunnylink),
PythonProcess("sunnylink_uploader", "system.loggerd.sunnylink_uploader", sunnylink_ready_shim),
]
if os.path.exists("./gitlab_runner.sh") and not PC:
+36 -3
View File
@@ -1,12 +1,40 @@
#!/usr/bin/env python3
from openpilot.common.api.sunnylink import SunnylinkApi
from cereal import log
from openpilot.common.api.sunnylink import SunnylinkApi, UNREGISTERED_SUNNYLINK_DONGLE_ID
from openpilot.common.params import Params
from openpilot.system.hardware import HARDWARE
from openpilot.system.version import is_prebuilt
import time
NetworkType = log.DeviceState.NetworkType
def main():
def is_network_connected() -> bool:
"""Check if the device is connected to a network."""
return HARDWARE.get_network_type() != NetworkType.none
def get_sunnylink_status(params=Params()) -> tuple[bool, bool]:
"""Get the status of Sunnylink on the device. Returns a tuple of (is_sunnylink_enabled, is_registered)."""
is_sunnylink_enabled = params.get_bool("SunnylinkEnabled")
is_registered = params.get("SunnylinkDongleId", encoding='utf-8') not in (None, UNREGISTERED_SUNNYLINK_DONGLE_ID)
return is_sunnylink_enabled, is_registered
def sunnylink_ready(params=Params()) -> bool:
"""Check if the device is ready to communicate with Sunnylink. That means it is enabled and registered."""
is_sunnylink_enabled, is_registered = get_sunnylink_status(params)
return is_sunnylink_enabled and is_registered
def sunnylink_need_register(params=Params()) -> bool:
"""Check if the device needs to be registered with Sunnylink."""
is_sunnylink_enabled, is_registered = get_sunnylink_status(params)
return is_sunnylink_enabled and not is_registered and is_network_connected()
def register_sunnylink():
"""Register the device with Sunnylink if it is enabled."""
extra_args = {}
if not Params().get_bool("SunnylinkEnabled"):
@@ -27,5 +55,10 @@ def main():
Params().put("LastSunnylinkPingTime", str(last_ping))
def main():
"""The main method is expected to be called by the manager when the device boots up."""
register_sunnylink()
if __name__ == "__main__":
main()