diff --git a/selfdrive/hardware/eon/hardware.py b/selfdrive/hardware/eon/hardware.py index dcc29d5919..ae5ae53f78 100644 --- a/selfdrive/hardware/eon/hardware.py +++ b/selfdrive/hardware/eon/hardware.py @@ -373,8 +373,13 @@ class Android(HardwareBase): return self.read_param_file("/sys/class/power_supply/usb/present", lambda x: bool(int(x)), False) def get_current_power_draw(self): - # We don't have a good direct way to measure this on android - return None + if self.get_battery_status() == 'Discharging': + # If the battery is discharging, we can use this measurement + # On C2: this is low by about 10-15%, probably mostly due to UNO draw not being factored in + return ((self.get_battery_voltage() / 1000000) * (self.get_battery_current() / 1000000)) + else: + # We don't have a good direct way to measure this if it's not "discharging" + return None def shutdown(self): os.system('LD_LIBRARY_PATH="" svc power shutdown') diff --git a/selfdrive/thermald/power_monitoring.py b/selfdrive/thermald/power_monitoring.py index 0dc4c5a1d3..25b1bad04d 100644 --- a/selfdrive/thermald/power_monitoring.py +++ b/selfdrive/thermald/power_monitoring.py @@ -88,10 +88,6 @@ class PowerMonitoring: current_power = HARDWARE.get_current_power_draw() # pylint: disable=assignment-from-none if current_power is not None: pass - elif HARDWARE.get_battery_status() == 'Discharging': - # If the battery is discharging, we can use this measurement - # On C2: this is low by about 10-15%, probably mostly due to UNO draw not being factored in - current_power = ((HARDWARE.get_battery_voltage() / 1000000) * (HARDWARE.get_battery_current() / 1000000)) elif (self.next_pulsed_measurement_time is not None) and (self.next_pulsed_measurement_time <= now): # TODO: Figure out why this is off by a factor of 3/4??? FUDGE_FACTOR = 1.33 diff --git a/selfdrive/thermald/tests/test_power_monitoring.py b/selfdrive/thermald/tests/test_power_monitoring.py index 0086715fc6..9eeb5f0c6d 100755 --- a/selfdrive/thermald/tests/test_power_monitoring.py +++ b/selfdrive/thermald/tests/test_power_monitoring.py @@ -62,23 +62,19 @@ class TestPowerMonitoring(unittest.TestCase): # Test to see that it integrates with discharging battery @parameterized.expand(ALL_PANDA_TYPES) def test_offroad_integration_discharging(self, hw_type): - BATT_VOLTAGE = 4 - BATT_CURRENT = 1 - 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): + POWER_DRAW = 4 + with pm_patch("HARDWARE.get_current_power_draw", POWER_DRAW): pm = PowerMonitoring() for _ in range(TEST_DURATION_S + 1): pm.calculate(self.mock_peripheralState(hw_type), False) - expected_power_usage = ((TEST_DURATION_S/3600) * (BATT_VOLTAGE * BATT_CURRENT) * 1e6) + expected_power_usage = ((TEST_DURATION_S/3600) * POWER_DRAW * 1e6) self.assertLess(abs(pm.get_power_used() - expected_power_usage), 10) # Test to check positive integration of car_battery_capacity @parameterized.expand(ALL_PANDA_TYPES) def test_car_battery_integration_onroad(self, hw_type): - BATT_VOLTAGE = 4 - BATT_CURRENT = 1 - 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): + POWER_DRAW = 4 + with pm_patch("HARDWARE.get_current_power_draw", POWER_DRAW): pm = PowerMonitoring() pm.car_battery_capacity_uWh = 0 for _ in range(TEST_DURATION_S + 1): @@ -89,10 +85,8 @@ class TestPowerMonitoring(unittest.TestCase): # Test to check positive integration upper limit @parameterized.expand(ALL_PANDA_TYPES) def test_car_battery_integration_upper_limit(self, hw_type): - BATT_VOLTAGE = 4 - BATT_CURRENT = 1 - 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): + POWER_DRAW = 4 + with pm_patch("HARDWARE.get_current_power_draw", POWER_DRAW): pm = PowerMonitoring() pm.car_battery_capacity_uWh = CAR_BATTERY_CAPACITY_uWh - 1000 for _ in range(TEST_DURATION_S + 1): @@ -103,29 +97,25 @@ class TestPowerMonitoring(unittest.TestCase): # Test to check negative integration of car_battery_capacity @parameterized.expand(ALL_PANDA_TYPES) def test_car_battery_integration_offroad(self, hw_type): - BATT_VOLTAGE = 4 - BATT_CURRENT = 1 - 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): + POWER_DRAW = 4 + with pm_patch("HARDWARE.get_current_power_draw", POWER_DRAW): pm = PowerMonitoring() pm.car_battery_capacity_uWh = CAR_BATTERY_CAPACITY_uWh for _ in range(TEST_DURATION_S + 1): pm.calculate(self.mock_peripheralState(hw_type), False) - expected_capacity = CAR_BATTERY_CAPACITY_uWh - ((TEST_DURATION_S/3600) * (BATT_VOLTAGE * BATT_CURRENT) * 1e6) + expected_capacity = CAR_BATTERY_CAPACITY_uWh - ((TEST_DURATION_S/3600) * POWER_DRAW * 1e6) self.assertLess(abs(pm.get_car_battery_capacity() - expected_capacity), 10) # Test to check negative integration lower limit @parameterized.expand(ALL_PANDA_TYPES) def test_car_battery_integration_lower_limit(self, hw_type): - BATT_VOLTAGE = 4 - BATT_CURRENT = 1 - 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): + POWER_DRAW = 4 + with pm_patch("HARDWARE.get_current_power_draw", POWER_DRAW): pm = PowerMonitoring() pm.car_battery_capacity_uWh = 1000 for _ in range(TEST_DURATION_S + 1): pm.calculate(self.mock_peripheralState(hw_type), False) - estimated_capacity = 0 - ((1/3600) * (BATT_VOLTAGE * BATT_CURRENT) * 1e6) + estimated_capacity = 0 - ((1/3600) * POWER_DRAW * 1e6) self.assertLess(abs(pm.get_car_battery_capacity() - estimated_capacity), 10) # Test to check policy of stopping charging after MAX_TIME_OFFROAD_S @@ -151,11 +141,9 @@ class TestPowerMonitoring(unittest.TestCase): # Test to check policy of stopping charging when the car voltage is too low @parameterized.expand(ALL_PANDA_TYPES) def test_car_voltage(self, hw_type): - BATT_VOLTAGE = 4 - BATT_CURRENT = 0 # To stop shutting down for other reasons + POWER_DRAW = 0 # To stop shutting down for other reasons TEST_TIME = 100 - 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): + with pm_patch("HARDWARE.get_current_power_draw", POWER_DRAW): pm = PowerMonitoring() pm.car_battery_capacity_uWh = CAR_BATTERY_CAPACITY_uWh ignition = False @@ -168,12 +156,10 @@ class TestPowerMonitoring(unittest.TestCase): # Test to check policy of not stopping charging when DisablePowerDown is set def test_disable_power_down(self): - BATT_VOLTAGE = 4 - BATT_CURRENT = 0 # To stop shutting down for other reasons + POWER_DRAW = 0 # To stop shutting down for other reasons TEST_TIME = 100 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): + with pm_patch("HARDWARE.get_current_power_draw", POWER_DRAW): pm = PowerMonitoring() pm.car_battery_capacity_uWh = CAR_BATTERY_CAPACITY_uWh ignition = False @@ -186,11 +172,9 @@ class TestPowerMonitoring(unittest.TestCase): # Test to check policy of not stopping charging when ignition def test_ignition(self): - BATT_VOLTAGE = 4 - BATT_CURRENT = 0 # To stop shutting down for other reasons + POWER_DRAW = 0 # To stop shutting down for other reasons TEST_TIME = 100 - 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): + with pm_patch("HARDWARE.get_current_power_draw", POWER_DRAW): pm = PowerMonitoring() pm.car_battery_capacity_uWh = CAR_BATTERY_CAPACITY_uWh ignition = True @@ -203,11 +187,9 @@ class TestPowerMonitoring(unittest.TestCase): # Test to check policy of not stopping charging when harness is not connected def test_harness_connection(self): - BATT_VOLTAGE = 4 - BATT_CURRENT = 0 # To stop shutting down for other reasons + POWER_DRAW = 0 # To stop shutting down for other reasons TEST_TIME = 100 - 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): + with pm_patch("HARDWARE.get_current_power_draw", POWER_DRAW): pm = PowerMonitoring() pm.car_battery_capacity_uWh = CAR_BATTERY_CAPACITY_uWh diff --git a/selfdrive/thermald/thermald.py b/selfdrive/thermald/thermald.py index ffcefa8610..7c64eaf31e 100755 --- a/selfdrive/thermald/thermald.py +++ b/selfdrive/thermald/thermald.py @@ -337,7 +337,11 @@ def thermald_thread(end_event, hw_queue): msg.deviceState.offroadPowerUsageUwh = power_monitor.get_power_used() msg.deviceState.carBatteryCapacityUwh = max(0, power_monitor.get_car_battery_capacity()) current_power_draw = HARDWARE.get_current_power_draw() # pylint: disable=assignment-from-none - msg.deviceState.powerDrawW = current_power_draw if current_power_draw is not None else 0 + if current_power_draw is not None: + statlog.sample("power_draw", current_power_draw) + msg.deviceState.powerDrawW = current_power_draw + else: + msg.deviceState.powerDrawW = 0 # Check if we need to disable charging (handled by boardd) msg.deviceState.chargingDisabled = power_monitor.should_disable_charging(onroad_conditions["ignition"], in_car, off_ts)