"""MockLink -- a synthetic ElmLink for tests and GUI development without a truck. Simulates a cranking 6.0: ICP ramps toward ~540 psi, FICM holds ~48V, battery sags, MAP/BARO sit at atmospheric. Same read interface as ElmLink. """ class MockLink: def __init__(self, clock): self.clock = clock # callable -> float seconds self.t0 = clock() self.protocol = "A6" def init(self): pass def fast_timing(self, on=True): pass def connect(self): return True def is_can(self): return True def _u16le(self, raw16): return [(raw16 >> 8) & 0xFF, raw16 & 0xFF] def read_m22(self, pid, timeout=0.5): el = self.clock() - self.t0 if pid == "1446": # ICP: ramps 0 -> 540 over ~2.7s return self._u16le(int(min(540, el * 200) / 0.57)) if pid == "09D0": # FICM main ~48V (0x3000) return self._u16le(0x3000) if pid == "1440": # MAP atmospheric return [0x01, 0x89] if pid == "1442": # BARO atmospheric return [0x01, 0x88] if pid == "1445": # EBP atmospheric return [0x01, 0x8F] if pid == "1310": # EOT ~33C return [0x1C, 0x92] return None # everything else: no response def read_m01(self, pid, nbytes, timeout=0.6): if pid == "0C": # RPM 0 at rest return [0x00, 0x00] if pid == "05": # ECT 82C return [122] return None def read_atrv(self, timeout=0.8): el = self.clock() - self.t0 return 10.6 if el < 2.5 else 12.5 # crank sag then recover def read_dtcs(self, mode, svc, timeout=5.0): return ["P0148"] if mode == "03" else [] def clear_dtcs(self): return True def close(self): pass