add putBool/getBool wrappers to cython params class (#20611)

* add putBool/getBool wrappers to cython class

* use new API

* some more puts

* fix mockparams arguments

* add get_bool to MockParams

* typo
albatross
Willem Melching 2021-04-07 15:36:37 +02:00 committed by GitHub
parent 1c824ba2c5
commit ae094042ad
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 110 additions and 69 deletions

View File

@ -12,5 +12,7 @@ cdef extern from "selfdrive/common/params.h":
Params(bool)
Params(string)
string get(string, bool) nogil
bool getBool(string)
int remove(string)
int put(string, string)
int putBool(string, bool)

View File

@ -39,7 +39,6 @@ keys = {
b"GithubUsername": [TxType.PERSISTENT],
b"HardwareSerial": [TxType.PERSISTENT],
b"HasAcceptedTerms": [TxType.PERSISTENT],
b"HasCompletedSetup": [TxType.PERSISTENT],
b"IsDriverViewEnabled": [TxType.CLEAR_ON_MANAGER_START],
b"IMEI": [TxType.PERSISTENT],
b"IsLdwEnabled": [TxType.PERSISTENT],
@ -118,13 +117,16 @@ cdef class Params:
def panda_disconnect(self):
self.clear_all(TxType.CLEAR_ON_PANDA_DISCONNECT)
def get(self, key, block=False, encoding=None):
def check_key(self, key):
key = ensure_bytes(key)
if key not in keys:
raise UnknownKeyName(key)
cdef string k = key
return key
def get(self, key, block=False, encoding=None):
cdef string k = self.check_key(key)
cdef bool b = block
cdef string val
@ -144,6 +146,10 @@ cdef class Params:
else:
return val
def get_bool(self, key):
cdef string k = self.check_key(key)
return self.p.getBool(k)
def put(self, key, dat):
"""
Warning: This function blocks until the param is written to disk!
@ -151,17 +157,18 @@ cdef class Params:
Use the put_nonblocking helper function in time sensitive code, but
in general try to avoid writing params as much as possible.
"""
key = ensure_bytes(key)
dat = ensure_bytes(dat)
if key not in keys:
raise UnknownKeyName(key)
cdef string k = self.check_key(key)
self.p.put(k, dat)
self.p.put(key, dat)
def put_bool(self, key, val):
cdef string k = self.check_key(key)
self.p.putBool(k, val)
def delete(self, key):
key = ensure_bytes(key)
self.p.remove(key)
cdef string k = self.check_key(key)
self.p.remove(k)
def put_nonblocking(key, val, d=None):

View File

@ -65,6 +65,15 @@ class TestParams(unittest.TestCase):
with self.assertRaises(UnknownKeyName):
self.params.get("swag")
with self.assertRaises(UnknownKeyName):
self.params.get_bool("swag")
with self.assertRaises(UnknownKeyName):
self.params.put("swag", "abc")
with self.assertRaises(UnknownKeyName):
self.params.put_bool("swag", True)
def test_params_permissions(self):
permissions = stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP | stat.S_IWGRP | stat.S_IROTH | stat.S_IWOTH
@ -77,6 +86,22 @@ class TestParams(unittest.TestCase):
self.params.delete("CarParams")
assert self.params.get("CarParams") is None
def test_get_bool(self):
self.params.delete("IsMetric")
self.assertFalse(self.params.get_bool("IsMetric"))
self.params.put_bool("IsMetric", True)
self.assertTrue(self.params.get_bool("IsMetric"))
self.params.put_bool("IsMetric", False)
self.assertFalse(self.params.get_bool("IsMetric"))
self.params.put("IsMetric", "1")
self.assertTrue(self.params.get_bool("IsMetric"))
self.params.put("IsMetric", "0")
self.assertFalse(self.params.get_bool("IsMetric"))
def test_put_non_blocking_with_get_block(self):
q = Params(self.tmpdir)
def _delayed_writer():

View File

@ -50,13 +50,13 @@ def get_snapshots(frame="roadCameraState", front_frame="driverCameraState"):
def snapshot():
params = Params()
front_camera_allowed = int(params.get("RecordFront"))
front_camera_allowed = params.get_bool("RecordFront")
if params.get("IsOffroad") != b"1" or params.get("IsTakingSnapshot") == b"1":
if (not params.get_bool("IsOffroad")) or params.get_bool("IsTakingSnapshot"):
print("Already taking snapshot")
return None, None
params.put("IsTakingSnapshot", "1")
params.put_bool("IsTakingSnapshot", True)
set_offroad_alert("Offroad_IsTakingSnapshot", True)
time.sleep(2.0) # Give thermald time to read the param, or if just started give camerad time to start
@ -65,7 +65,7 @@ def snapshot():
subprocess.check_call(["pgrep", "camerad"])
print("Camerad already running")
params.put("IsTakingSnapshot", "0")
params.put_bool("IsTakingSnapshot", False)
params.delete("Offroad_IsTakingSnapshot")
return None, None
except subprocess.CalledProcessError:
@ -89,7 +89,7 @@ def snapshot():
proc.send_signal(signal.SIGINT)
proc.communicate()
params.put("IsTakingSnapshot", "0")
params.put_bool("IsTakingSnapshot", False)
set_offroad_alert("Offroad_IsTakingSnapshot", False)
if not front_camera_allowed:

View File

@ -39,6 +39,10 @@ public:
return iss.fail() ? std::nullopt : std::optional(value);
}
inline bool getBool(const std::string &key) {
return getBool(key.c_str());
}
inline bool getBool(const char *key) {
return get(key) == "1";
}
@ -53,4 +57,8 @@ public:
inline int putBool(const char *key, bool val) {
return put(key, val ? "1" : "0", 1);
}
inline int putBool(const std::string &key, bool val) {
return putBool(key.c_str(), val);
}
};

View File

@ -73,11 +73,11 @@ class Controls:
# read params
params = Params()
self.is_metric = params.get("IsMetric", encoding='utf8') == "1"
self.is_ldw_enabled = params.get("IsLdwEnabled", encoding='utf8') == "1"
community_feature_toggle = params.get("CommunityFeaturesToggle", encoding='utf8') == "1"
openpilot_enabled_toggle = params.get("OpenpilotEnabledToggle", encoding='utf8') == "1"
passive = params.get("Passive", encoding='utf8') == "1" or not openpilot_enabled_toggle
self.is_metric = params.get_bool("IsMetric")
self.is_ldw_enabled = params.get_bool("IsLdwEnabled")
community_feature_toggle = params.get_bool("CommunityFeaturesToggle")
openpilot_enabled_toggle = params.get_bool("OpenpilotEnabledToggle")
passive = params.get_bool("Passive") or not openpilot_enabled_toggle
# detect sound card presence and ensure successful init
sounds_available = HARDWARE.get_sound_card_online()

View File

@ -54,7 +54,7 @@ class LateralPlanner():
self.setup_mpc()
self.solution_invalid_cnt = 0
self.use_lanelines = Params().get('EndToEndToggle') != b'1'
self.use_lanelines = not Params().get_bool('EndToEndToggle')
self.lane_change_state = LaneChangeState.off
self.lane_change_direction = LaneChangeDirection.none
self.lane_change_timer = 0.0

View File

@ -45,9 +45,9 @@ class TestStartup(unittest.TestCase):
params = Params()
params.clear_all()
params.put("Passive", b"0")
params.put("OpenpilotEnabledToggle", b"1")
params.put("CommunityFeaturesToggle", b"1" if toggle_enabled else b"0")
params.put_bool("Passive", False)
params.put_bool("OpenpilotEnabledToggle", True)
params.put_bool("CommunityFeaturesToggle", toggle_enabled)
time.sleep(2) # wait for controlsd to be ready

View File

@ -60,8 +60,17 @@ class MockParams():
"IsOffroad": b"1",
}
def get(self, k):
return self.params[k]
def get(self, k, block=False, encoding=None):
val = self.params[k]
if encoding is not None:
return val.decode(encoding)
else:
return val
def get_bool(self, k):
val = self.params[k]
return (val == b'1')
class UploaderTestCase(unittest.TestCase):
f_type = "UNKNOWN"

View File

@ -192,7 +192,7 @@ class Uploader():
def uploader_fn(exit_event):
params = Params()
dongle_id = params.get("DongleId").decode('utf8')
dongle_id = params.get("DongleId", encoding='utf8')
if dongle_id is None:
cloudlog.info("uploader missing dongle_id")
@ -207,7 +207,7 @@ def uploader_fn(exit_event):
backoff = 0.1
while not exit_event.is_set():
sm.update(0)
offroad = params.get("IsOffroad") == b'1'
offroad = params.get_bool("IsOffroad")
network_type = sm['deviceState'].networkType if not force_wifi else NetworkType.wifi
if network_type == NetworkType.none:
if allow_sleep:
@ -215,7 +215,7 @@ def uploader_fn(exit_event):
continue
on_wifi = network_type == NetworkType.wifi
allow_raw_upload = params.get("IsUploadRawEnabled") != b"0"
allow_raw_upload = params.get_bool("IsUploadRawEnabled")
d = uploader.next_file_to_upload(with_raw=allow_raw_upload and on_wifi and offroad)
if d is None: # Nothing to upload

View File

@ -25,24 +25,15 @@ def manager_init():
params.manager_start()
default_params = [
("CommunityFeaturesToggle", "0"),
("EndToEndToggle", "0"),
("CompletedTrainingVersion", "0"),
("IsRHD", "0"),
("IsMetric", "0"),
("RecordFront", "0"),
("HasAcceptedTerms", "0"),
("HasCompletedSetup", "0"),
("IsUploadRawEnabled", "1"),
("IsLdwEnabled", "0"),
("LastUpdateTime", datetime.datetime.utcnow().isoformat().encode('utf8')),
("OpenpilotEnabledToggle", "1"),
("VisionRadarToggle", "0"),
("IsDriverViewEnabled", "0"),
]
if params.get("RecordFrontLock", encoding='utf-8') == "1":
params.put("RecordFront", "1")
if params.get_bool("RecordFrontLock"):
params.put_bool("RecordFront", True)
# set unset params
for k, v in default_params:
@ -123,7 +114,7 @@ def manager_thread():
not_run.append("loggerd")
started = sm['deviceState'].started
driverview = params.get("IsDriverViewEnabled") == b"1"
driverview = params.get_bool("IsDriverViewEnabled")
ensure_running(managed_processes.values(), started, driverview, not_run)
# trigger an update after going offroad
@ -143,7 +134,7 @@ def manager_thread():
pm.send('managerState', msg)
# Exit main loop when uninstall is needed
if params.get("DoUninstall", encoding='utf8') == "1":
if params.get_bool("DoUninstall"):
break
@ -172,7 +163,7 @@ def main():
finally:
manager_cleanup()
if Params().get("DoUninstall", encoding='utf8') == "1":
if Params().get_bool("DoUninstall"):
cloudlog.warning("uninstalling")
HARDWARE.uninstall()

View File

@ -14,7 +14,7 @@ def dmonitoringd_thread(sm=None, pm=None):
if sm is None:
sm = messaging.SubMaster(['driverState', 'liveCalibration', 'carState', 'controlsState', 'modelV2'], poll=['driverState'])
driver_status = DriverStatus(rhd=Params().get("IsRHD") == b"1")
driver_status = DriverStatus(rhd=Params().get_bool("IsRHD"))
sm['liveCalibration'].calStatus = Calibration.INVALID
sm['liveCalibration'].rpyCalib = [0, 0, 0]

View File

@ -11,11 +11,10 @@ def set_params_enabled():
from common.params import Params
params = Params()
params.put("HasAcceptedTerms", terms_version)
params.put("HasCompletedSetup", "1")
params.put("OpenpilotEnabledToggle", "1")
params.put("CommunityFeaturesToggle", "1")
params.put("Passive", "0")
params.put("CompletedTrainingVersion", training_version)
params.put_bool("OpenpilotEnabledToggle", True)
params.put_bool("CommunityFeaturesToggle", True)
params.put_bool("Passive", False)
def phone_only(x):

View File

@ -326,9 +326,9 @@ class LongitudinalControl(unittest.TestCase):
params = Params()
params.clear_all()
params.put("Passive", "1" if os.getenv("PASSIVE") else "0")
params.put("OpenpilotEnabledToggle", "1")
params.put("CommunityFeaturesToggle", "1")
params.put_bool("Passive", bool(os.getenv("PASSIVE")))
params.put_bool("OpenpilotEnabledToggle", True)
params.put_bool("CommunityFeaturesToggle", True)
# hack
def test_longitudinal_setup(self):

View File

@ -338,9 +338,9 @@ def python_replay_process(cfg, lr):
params = Params()
params.clear_all()
params.manager_start()
params.put("OpenpilotEnabledToggle", "1")
params.put("Passive", "0")
params.put("CommunityFeaturesToggle", "1")
params.put_bool("OpenpilotEnabledToggle", True)
params.put_bool("Passive", False)
params.put_bool("CommunityFeaturesToggle", True)
os.environ['NO_RADAR_SLEEP'] = "1"
os.environ['SKIP_FW_QUERY'] = "1"

View File

@ -92,7 +92,7 @@ class TestUpdated(unittest.TestCase):
return subprocess.Popen(updated_path, env=os.environ)
def _start_updater(self, offroad=True, nosleep=False):
self.params.put("IsOffroad", "1" if offroad else "0")
self.params.put_bool("IsOffroad", offroad)
self.updated_proc = self._get_updated_proc()
if not nosleep:
time.sleep(1)

View File

@ -164,8 +164,8 @@ class PowerMonitoring:
disable_charging |= (self.car_voltage_mV < (VBATT_PAUSE_CHARGING * 1e3))
disable_charging |= (self.car_battery_capacity_uWh <= 0)
disable_charging &= (not pandaState.pandaState.ignitionLine and not pandaState.pandaState.ignitionCan)
disable_charging &= (self.params.get("DisablePowerDown") != b"1")
disable_charging |= (self.params.get("ForcePowerDown") == b"1")
disable_charging &= (not self.params.get_bool("DisablePowerDown"))
disable_charging |= self.params.get_bool("ForcePowerDown")
return disable_charging
# See if we need to shutdown

View File

@ -174,7 +174,7 @@ class TestPowerMonitoring(unittest.TestCase):
BATT_VOLTAGE = 4
BATT_CURRENT = 0 # To stop shutting down for other reasons
TEST_TIME = 100
params.put("DisablePowerDown", b"1")
params.put_bool("DisablePowerDown", True)
with pm_patch("HARDWARE.get_battery_voltage", BATT_VOLTAGE * 1e6), pm_patch("HARDWARE.get_battery_current", BATT_CURRENT * 1e6), \
pm_patch("HARDWARE.get_battery_status", "Discharging"), pm_patch("HARDWARE.get_current_power_draw", None):
pm = PowerMonitoring()

View File

@ -327,8 +327,8 @@ def thermald_thread():
set_offroad_alert_if_changed("Offroad_ConnectivityNeeded", False)
set_offroad_alert_if_changed("Offroad_ConnectivityNeededPrompt", False)
startup_conditions["up_to_date"] = params.get("Offroad_ConnectivityNeeded") is None or params.get("DisableUpdates") == b"1"
startup_conditions["not_uninstalling"] = not params.get("DoUninstall") == b"1"
startup_conditions["up_to_date"] = params.get("Offroad_ConnectivityNeeded") is None or params.get_bool("DisableUpdates")
startup_conditions["not_uninstalling"] = not params.get_bool("DoUninstall")
startup_conditions["accepted_terms"] = params.get("HasAcceptedTerms") == terms_version
panda_signature = params.get("PandaFirmware")
@ -339,8 +339,8 @@ def thermald_thread():
startup_conditions["free_space"] = msg.deviceState.freeSpacePercent > 2
startup_conditions["completed_training"] = params.get("CompletedTrainingVersion") == training_version or \
(current_branch in ['dashcam', 'dashcam-staging'])
startup_conditions["not_driver_view"] = not params.get("IsDriverViewEnabled") == b"1"
startup_conditions["not_taking_snapshot"] = not params.get("IsTakingSnapshot") == b"1"
startup_conditions["not_driver_view"] = not params.get_bool("IsDriverViewEnabled")
startup_conditions["not_taking_snapshot"] = not params.get_bool("IsTakingSnapshot")
# if any CPU gets above 107 or the battery gets above 63, kill all processes
# controls will warn with CPU above 95 or battery above 60
startup_conditions["device_temp_good"] = thermal_status < ThermalStatus.danger
@ -363,7 +363,7 @@ def thermald_thread():
cloudlog.event("Startup blocked", startup_conditions=startup_conditions)
if should_start_prev or (count == 0):
params.put("IsOffroad", "1")
params.put_bool("IsOffroad", True)
if TICI and DISABLE_LTE_ONROAD:
os.system("sudo systemctl start --no-block lte")

View File

@ -40,7 +40,7 @@ def main():
while True:
time.sleep(60)
is_onroad = params.get("IsOffroad") != b"1"
is_onroad = not params.get_bool("IsOffroad")
if is_onroad:
continue

View File

@ -17,13 +17,13 @@ if __name__ == "__main__":
t = 10 if len(sys.argv) < 2 else int(sys.argv[1])
while True:
print("setting alert update")
params.put("UpdateAvailable", "1")
params.put_bool("UpdateAvailable", True)
r = open(os.path.join(BASEDIR, "RELEASES.md"), "r").read()
r = r[:r.find('\n\n')] # Slice latest release notes
params.put("ReleaseNotes", r + "\n")
time.sleep(t)
params.put("UpdateAvailable", "0")
params.put_bool("UpdateAvailable", False)
# cycle through normal alerts
for a in offroad_alerts:

View File

@ -119,7 +119,7 @@ def set_params(new_version: bool, failed_count: int, exception: Optional[str]) -
params.put("ReleaseNotes", r + b"\n")
except Exception:
params.put("ReleaseNotes", "")
params.put("UpdateAvailable", "1")
params.put_bool("UpdateAvailable", True)
def setup_git_options(cwd: str) -> None:
@ -165,7 +165,7 @@ def init_overlay() -> None:
cloudlog.info("preparing new safe staging area")
params = Params()
params.put("UpdateAvailable", "0")
params.put_bool("UpdateAvailable", False)
set_consistent_flag(False)
dismount_overlay()
if os.path.isdir(STAGING_ROOT):
@ -332,7 +332,7 @@ def fetch_update(wait_helper: WaitTimeHelper) -> bool:
def main():
params = Params()
if params.get("DisableUpdates") == b"1":
if params.get_bool("DisableUpdates"):
raise RuntimeError("updates are disabled by the DisableUpdates param")
if EON and os.geteuid() != 0:
@ -370,7 +370,7 @@ def main():
# Don't run updater while onroad or if the time's wrong
time_wrong = datetime.datetime.utcnow().year < 2019
is_onroad = params.get("IsOffroad") != b"1"
is_onroad = not params.get_bool("IsOffroad")
if is_onroad or time_wrong:
wait_helper.sleep(30)
cloudlog.info("not running updater, not offroad")