diff --git a/cereal b/cereal index d87e7e56d9..1681cdbaf0 160000 --- a/cereal +++ b/cereal @@ -1 +1 @@ -Subproject commit d87e7e56d931413d0625fb765c3142ed6106c47b +Subproject commit 1681cdbaf0e3f78f0e2643187809cefb693483ac diff --git a/selfdrive/boardd/boardd.cc b/selfdrive/boardd/boardd.cc index 7d3547e7aa..4aacc1e9dd 100644 --- a/selfdrive/boardd/boardd.cc +++ b/selfdrive/boardd/boardd.cc @@ -377,6 +377,7 @@ void panda_state_thread(bool spoofing_started) { ps.setFanSpeedRpm(fan_speed_rpm); ps.setFaultStatus(cereal::PandaState::FaultStatus(pandaState.fault_status)); ps.setPowerSaveEnabled((bool)(pandaState.power_save_enabled)); + ps.setHarnessStatus(cereal::PandaState::HarnessStatus(pandaState.car_harness_status)); // Convert faults bitset to capnp list std::bitset fault_bits(pandaState.faults); diff --git a/selfdrive/thermald/power_monitoring.py b/selfdrive/thermald/power_monitoring.py index b10c599b1e..70ee9fc0af 100644 --- a/selfdrive/thermald/power_monitoring.py +++ b/selfdrive/thermald/power_monitoring.py @@ -169,6 +169,7 @@ class PowerMonitoring: disable_charging |= (self.car_battery_capacity_uWh <= 0) disable_charging &= (not pandaState.pandaState.ignitionLine and not pandaState.pandaState.ignitionCan) disable_charging &= (not self.params.get_bool("DisablePowerDown")) + disable_charging &= (pandaState.pandaState.harnessStatus != log.PandaState.HarnessStatus.notConnected) disable_charging |= self.params.get_bool("ForcePowerDown") return disable_charging diff --git a/selfdrive/thermald/tests/test_power_monitoring.py b/selfdrive/thermald/tests/test_power_monitoring.py index d669e0922b..77a77eb281 100755 --- a/selfdrive/thermald/tests/test_power_monitoring.py +++ b/selfdrive/thermald/tests/test_power_monitoring.py @@ -37,12 +37,13 @@ class TestPowerMonitoring(unittest.TestCase): params.delete("CarBatteryCapacity") params.delete("DisablePowerDown") - def mock_pandaState(self, ignition, hw_type, car_voltage=12): + def mock_pandaState(self, ignition, hw_type, car_voltage=12, harness_status=log.PandaState.HarnessStatus.normal): pandaState = messaging.new_message('pandaState') pandaState.pandaState.pandaType = hw_type pandaState.pandaState.voltage = car_voltage * 1e3 pandaState.pandaState.ignitionLine = ignition pandaState.pandaState.ignitionCan = False + pandaState.pandaState.harnessStatus = harness_status return pandaState # Test to see that it doesn't do anything when pandaState is None @@ -203,5 +204,23 @@ class TestPowerMonitoring(unittest.TestCase): self.assertFalse(pm.should_disable_charging(pandaState, ssb)) self.assertFalse(pm.should_disable_charging(pandaState, ssb)) + # Test to check policy of not stopping charging when harness is not connected + def test_harness_connection(self): + global ssb + BATT_VOLTAGE = 4 + BATT_CURRENT = 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): + pm = PowerMonitoring() + pm.car_battery_capacity_uWh = CAR_BATTERY_CAPACITY_uWh + pandaState = self.mock_pandaState(False, log.PandaState.PandaType.uno, car_voltage=(VBATT_PAUSE_CHARGING - 1), + harness_status=log.PandaState.HarnessStatus.notConnected) + for i in range(TEST_TIME): + pm.calculate(pandaState) + if i % 10 == 0: + self.assertFalse(pm.should_disable_charging(pandaState, ssb)) + self.assertFalse(pm.should_disable_charging(pandaState, ssb)) + if __name__ == "__main__": unittest.main()