params: unique default value (#35798)

* default

* None vs ""

* athena

* more

* more

* this

* better

* better

* now

* name

* better
pull/35802/head
Maxime Desroches 6 days ago committed by GitHub
parent c382245a41
commit abd657edfa
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 2
      common/params.cc
  2. 5
      common/params.h
  3. 2
      common/params_keys.h
  4. 57
      common/params_pyx.pyx
  5. 23
      common/tests/test_params.py
  6. 7
      selfdrive/selfdrived/selfdrived.py
  7. 4
      selfdrive/ui/layouts/settings/device.py
  8. 2
      selfdrive/ui/layouts/settings/toggles.py
  9. 2
      selfdrive/ui/widgets/pairing_dialog.py
  10. 4
      system/athena/athenad.py
  11. 2
      system/hardware/power_monitoring.py

@ -123,7 +123,7 @@ ParamKeyType Params::getKeyType(const std::string &key) {
return keys[key].type; return keys[key].type;
} }
std::string Params::getKeyDefaultValue(const std::string &key) { std::optional<std::string> Params::getKeyDefaultValue(const std::string &key) {
return keys[key].default_value; return keys[key].default_value;
} }

@ -2,6 +2,7 @@
#include <future> #include <future>
#include <map> #include <map>
#include <optional>
#include <string> #include <string>
#include <tuple> #include <tuple>
#include <utility> #include <utility>
@ -33,7 +34,7 @@ enum ParamKeyType {
struct ParamKeyAttributes { struct ParamKeyAttributes {
uint32_t flags; uint32_t flags;
ParamKeyType type; ParamKeyType type;
std::string default_value = ""; std::optional<std::string> default_value = std::nullopt;
}; };
class Params { class Params {
@ -48,7 +49,7 @@ public:
bool checkKey(const std::string &key); bool checkKey(const std::string &key);
ParamKeyFlag getKeyFlag(const std::string &key); ParamKeyFlag getKeyFlag(const std::string &key);
ParamKeyType getKeyType(const std::string &key); ParamKeyType getKeyType(const std::string &key);
std::string getKeyDefaultValue(const std::string &key); std::optional<std::string> getKeyDefaultValue(const std::string &key);
inline std::string getParamPath(const std::string &key = {}) { inline std::string getParamPath(const std::string &key = {}) {
return params_path + params_prefix + (key.empty() ? "" : "/" + key); return params_path + params_prefix + (key.empty() ? "" : "/" + key);
} }

@ -19,7 +19,7 @@ inline static std::unordered_map<std::string, ParamKeyAttributes> keys = {
{"CalibrationParams", {PERSISTENT, BYTES}}, {"CalibrationParams", {PERSISTENT, BYTES}},
{"CameraDebugExpGain", {CLEAR_ON_MANAGER_START, STRING}}, {"CameraDebugExpGain", {CLEAR_ON_MANAGER_START, STRING}},
{"CameraDebugExpTime", {CLEAR_ON_MANAGER_START, STRING}}, {"CameraDebugExpTime", {CLEAR_ON_MANAGER_START, STRING}},
{"CarBatteryCapacity", {PERSISTENT, INT}}, {"CarBatteryCapacity", {PERSISTENT, INT, "0"}},
{"CarParams", {CLEAR_ON_MANAGER_START | CLEAR_ON_ONROAD_TRANSITION, BYTES}}, {"CarParams", {CLEAR_ON_MANAGER_START | CLEAR_ON_ONROAD_TRANSITION, BYTES}},
{"CarParamsCache", {CLEAR_ON_MANAGER_START, BYTES}}, {"CarParamsCache", {CLEAR_ON_MANAGER_START, BYTES}},
{"CarParamsPersistent", {PERSISTENT, BYTES}}, {"CarParamsPersistent", {PERSISTENT, BYTES}},

@ -5,6 +5,7 @@ import json
from libcpp cimport bool from libcpp cimport bool
from libcpp.string cimport string from libcpp.string cimport string
from libcpp.vector cimport vector from libcpp.vector cimport vector
from libcpp.optional cimport optional
cdef extern from "common/params.h": cdef extern from "common/params.h":
cpdef enum ParamKeyFlag: cpdef enum ParamKeyFlag:
@ -36,7 +37,7 @@ cdef extern from "common/params.h":
int putBool(string, bool) nogil int putBool(string, bool) nogil
bool checkKey(string) nogil bool checkKey(string) nogil
ParamKeyType getKeyType(string) nogil ParamKeyType getKeyType(string) nogil
string getKeyDefaultValue(string) nogil optional[string] getKeyDefaultValue(string) nogil
string getParamPath(string) nogil string getParamPath(string) nogil
void clearAll(ParamKeyFlag) void clearAll(ParamKeyFlag)
vector[string] allKeys() vector[string] allKeys()
@ -73,40 +74,45 @@ cdef class Params:
raise UnknownKeyName(key) raise UnknownKeyName(key)
return key return key
def get(self, key, bool block=False, default=None): def cast(self, t, value, default):
if value is None:
return None
try:
if t == STRING:
return value.decode("utf-8")
elif t == BOOL:
return value == b"1"
elif t == INT:
return int(value)
elif t == FLOAT:
return float(value)
elif t == TIME:
return datetime.datetime.fromisoformat(value.decode("utf-8"))
elif t == JSON:
return json.loads(value)
elif t == BYTES:
return value
else:
raise TypeError()
except (TypeError, ValueError):
return self.cast(t, default, None)
def get(self, key, bool block=False):
cdef string k = self.check_key(key) cdef string k = self.check_key(key)
cdef ParamKeyType t = self.p.getKeyType(ensure_bytes(key)) cdef ParamKeyType t = self.p.getKeyType(k)
cdef string val cdef string val
with nogil: with nogil:
val = self.p.get(k, block) val = self.p.get(k, block)
default = self.get_default_value(k)
if val == b"": if val == b"":
if block: if block:
# If we got no value while running in blocked mode # If we got no value while running in blocked mode
# it means we got an interrupt while waiting # it means we got an interrupt while waiting
raise KeyboardInterrupt raise KeyboardInterrupt
else: else:
return default return self.cast(t, default, None)
return self.cast(t, val, default)
try:
if t == STRING:
return val.decode("utf-8")
elif t == BOOL:
return val == b"1"
elif t == INT:
return int(val)
elif t == FLOAT:
return float(val)
elif t == TIME:
return datetime.datetime.fromisoformat(val.decode("utf-8"))
elif t == JSON:
return json.loads(val)
elif t == BYTES:
return val
else:
return default
except (TypeError, ValueError):
return default
def get_bool(self, key, bool block=False): def get_bool(self, key, bool block=False):
cdef string k = self.check_key(key) cdef string k = self.check_key(key)
@ -156,4 +162,5 @@ cdef class Params:
return self.p.allKeys() return self.p.allKeys()
def get_default_value(self, key): def get_default_value(self, key):
return self.p.getKeyDefaultValue(self.check_key(key)) cdef optional[string] default = self.p.getKeyDefaultValue(self.check_key(key))
return default.value() if default.has_value() else None

@ -110,10 +110,14 @@ class TestParams:
assert len(keys) == len(set(keys)) assert len(keys) == len(set(keys))
assert b"CarParams" in keys assert b"CarParams" in keys
def test_params_default_init_value(self): def test_params_default_value(self):
assert self.params.get_default_value("LanguageSetting") self.params.remove("LanguageSetting")
assert self.params.get_default_value("LongitudinalPersonality") self.params.remove("LongitudinalPersonality")
assert not self.params.get_default_value("LiveParameters") self.params.remove("LiveParameters")
assert isinstance(self.params.get("LanguageSetting"), str)
assert isinstance(self.params.get("LongitudinalPersonality"), int)
assert self.params.get("LiveParameters") is None
def test_params_get_type(self): def test_params_get_type(self):
# json # json
@ -127,18 +131,9 @@ class TestParams:
# bool # bool
self.params.put("AdbEnabled", "1") self.params.put("AdbEnabled", "1")
assert self.params.get("AdbEnabled") assert self.params.get("AdbEnabled")
assert isinstance(self.params.get("AdbEnabled"), bool)
# time # time
now = datetime.datetime.now(datetime.UTC) now = datetime.datetime.now(datetime.UTC)
self.params.put("InstallDate", str(now)) self.params.put("InstallDate", str(now))
assert self.params.get("InstallDate") == now assert self.params.get("InstallDate") == now
def test_params_get_default(self):
now = datetime.datetime.now(datetime.UTC)
self.params.remove("InstallDate")
assert self.params.get("InstallDate") is None
assert self.params.get("InstallDate", default=now) == now
self.params.put("BootCount", "1xx1")
assert self.params.get("BootCount") is None
assert self.params.get("BootCount", default=1441) == 1441

@ -109,7 +109,7 @@ class SelfdriveD:
self.logged_comm_issue = None self.logged_comm_issue = None
self.not_running_prev = None self.not_running_prev = None
self.experimental_mode = False self.experimental_mode = False
self.personality = self.read_personality_param() self.personality = self.params.get('LongitudinalPersonality')
self.recalibrating_seen = False self.recalibrating_seen = False
self.state_machine = StateMachine() self.state_machine = StateMachine()
self.rk = Ratekeeper(100, print_delay_threshold=None) self.rk = Ratekeeper(100, print_delay_threshold=None)
@ -477,16 +477,13 @@ class SelfdriveD:
self.CS_prev = CS self.CS_prev = CS
def read_personality_param(self):
return self.params.get('LongitudinalPersonality', default=log.LongitudinalPersonality.standard)
def params_thread(self, evt): def params_thread(self, evt):
while not evt.is_set(): while not evt.is_set():
self.is_metric = self.params.get_bool("IsMetric") self.is_metric = self.params.get_bool("IsMetric")
self.is_ldw_enabled = self.params.get_bool("IsLdwEnabled") self.is_ldw_enabled = self.params.get_bool("IsLdwEnabled")
self.disengage_on_accelerator = self.params.get_bool("DisengageOnAccelerator") self.disengage_on_accelerator = self.params.get_bool("DisengageOnAccelerator")
self.experimental_mode = self.params.get_bool("ExperimentalMode") and self.CP.openpilotLongitudinalControl self.experimental_mode = self.params.get_bool("ExperimentalMode") and self.CP.openpilotLongitudinalControl
self.personality = self.read_personality_param() self.personality = self.params.get('LongitudinalPersonality')
time.sleep(0.1) time.sleep(0.1)
def run(self): def run(self):

@ -41,8 +41,8 @@ class DeviceLayout(Widget):
self._scroller = Scroller(items, line_separator=True, spacing=0) self._scroller = Scroller(items, line_separator=True, spacing=0)
def _initialize_items(self): def _initialize_items(self):
dongle_id = self._params.get("DongleId", default="N/A") dongle_id = self._params.get("DongleId") or "N/A"
serial = self._params.get("HardwareSerial", default="N/A") serial = self._params.get("HardwareSerial") or "N/A"
items = [ items = [
text_item("Dongle ID", dongle_id), text_item("Dongle ID", dongle_id),

@ -54,7 +54,7 @@ class TogglesLayout(Widget):
buttons=["Aggressive", "Standard", "Relaxed"], buttons=["Aggressive", "Standard", "Relaxed"],
button_width=255, button_width=255,
callback=self._set_longitudinal_personality, callback=self._set_longitudinal_personality,
selected_index=self._params.get("LongitudinalPersonality", default=0), selected_index=self._params.get("LongitudinalPersonality"),
icon="speed_limit.png" icon="speed_limit.png"
), ),
toggle_item( toggle_item(

@ -23,7 +23,7 @@ class PairingDialog:
def _get_pairing_url(self) -> str: def _get_pairing_url(self) -> str:
try: try:
dongle_id = self.params.get("DongleId", default="") dongle_id = self.params.get("DongleId") or ""
token = Api(dongle_id).get_token() token = Api(dongle_id).get_token()
except Exception as e: except Exception as e:
cloudlog.warning(f"Failed to get pairing token: {e}") cloudlog.warning(f"Failed to get pairing token: {e}")

@ -532,12 +532,12 @@ def getPublicKey() -> str | None:
@dispatcher.add_method @dispatcher.add_method
def getSshAuthorizedKeys() -> str: def getSshAuthorizedKeys() -> str:
return cast(str, Params().get("GithubSshKeys", default="")) return cast(str, Params().get("GithubSshKeys") or "")
@dispatcher.add_method @dispatcher.add_method
def getGithubUsername() -> str: def getGithubUsername() -> str:
return cast(str, Params().get("GithubUsername", default="")) return cast(str, Params().get("GithubUsername") or "")
@dispatcher.add_method @dispatcher.add_method
def getSimInfo(): def getSimInfo():

@ -29,7 +29,7 @@ class PowerMonitoring:
self.car_voltage_instant_mV = 12e3 # Last value of peripheralState voltage self.car_voltage_instant_mV = 12e3 # Last value of peripheralState voltage
self.integration_lock = threading.Lock() self.integration_lock = threading.Lock()
car_battery_capacity_uWh = self.params.get("CarBatteryCapacity", default=0) car_battery_capacity_uWh = self.params.get("CarBatteryCapacity")
# Reset capacity if it's low # Reset capacity if it's low
self.car_battery_capacity_uWh = max((CAR_BATTERY_CAPACITY_uWh / 10), car_battery_capacity_uWh) self.car_battery_capacity_uWh = max((CAR_BATTERY_CAPACITY_uWh / 10), car_battery_capacity_uWh)

Loading…
Cancel
Save