diff --git a/opendbc/safety/ignition.h b/opendbc/safety/ignition.h index 7ac8f008..ae00c729 100644 --- a/opendbc/safety/ignition.h +++ b/opendbc/safety/ignition.h @@ -53,6 +53,19 @@ void ignition_can_hook(const CANPacket_t *msg) { ignition_can = (msg->data[0] >> 5) == 0x6U; ignition_can_cnt = 0U; } + + // Volkswagen MEB exception + if ((msg->addr == 0x3C0U) && (len == 4)) { + int counter = msg->data[1] & 0xFU; + + static int prev_counter_vw_meb = -1; + if ((counter == ((prev_counter_vw_meb + 1) % 16)) && (prev_counter_vw_meb != -1)) { + // Klemmen_Status_01->ZAS_Kl_15 + ignition_can = ((msg->data[2] >> 1) & 1U) != 0U; + ignition_can_cnt = 0U; + } + prev_counter_vw_meb = counter; + } } // TODO: this is too loose, Teslas have 0x222 diff --git a/opendbc/safety/tests/test_volkswagen_meb.py b/opendbc/safety/tests/test_volkswagen_meb.py new file mode 100644 index 00000000..4fc349a2 --- /dev/null +++ b/opendbc/safety/tests/test_volkswagen_meb.py @@ -0,0 +1,40 @@ +#!/usr/bin/env python3 +import unittest + +from opendbc.safety.tests.libsafety import libsafety_py +from opendbc.safety.tests.common import CANPackerSafety + + +class TestVolkswagenMebIgnition(unittest.TestCase): + TX_MSGS: list = [] + + def setUp(self): + self.safety = libsafety_py.libsafety + self.safety.init_tests() + self.packer = CANPackerSafety("vw_meb") + + def _msg(self, counter, ign): + return self.packer.make_can_msg_safety("Klemmen_Status_01", 0, + {"Klemmen_Status_01_BZ": counter, + "ZAS_Kl_15": ign}) + + # ZAS_Kl_15=1 + def test_ignition_on(self): + for i in range(16): + self.safety.init_tests() + self.safety.ignition_can_hook(self._msg(i, 1)) + self.assertFalse(self.safety.get_ignition_can()) + self.safety.ignition_can_hook(self._msg((i + 1) % 16, 1)) + self.assertTrue(self.safety.get_ignition_can()) + + def test_ignition_off(self): + self.safety.ignition_can_hook(self._msg(0, 1)) + self.safety.ignition_can_hook(self._msg(1, 1)) + self.assertTrue(self.safety.get_ignition_can()) + self.safety.ignition_can_hook(self._msg(2, 0)) + self.safety.ignition_can_hook(self._msg(3, 0)) + self.assertFalse(self.safety.get_ignition_can()) + + +if __name__ == "__main__": + unittest.main()