"""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 ~750 idle v = 750 * 4 return [(v >> 8) & 0xFF, v & 0xFF] if pid == "05": # ECT 82C return [122] if pid == "0D": # speed 48 km/h return [48] if pid == "10": # MAF 12.0 g/s v = 1200 return [(v >> 8) & 0xFF, v & 0xFF] if pid == "01": # readiness: MIL off, 0 DTCs, mixed monitors return [0x00, 0x07, 0x61, 0x20] 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 read_vehicle_info(self, timeout=2.0): return {"vin": "1FMZU73E12ZA12345", "calibration": "JR3A-12A650-BCD", "ecu_name": "ECM-EngineControl"} def read_readiness(self, timeout=1.0): from . import obdservices as svc return svc.decode_readiness([0x00, 0x07, 0x61, 0x20]) def read_freeze_frame(self, timeout=0.6): return {"dtc": "P0148", "values": [("Engine RPM", 240, "rpm"), ("Coolant Temp", 33, "C"), ("Engine Load", 18, "%"), ("Vehicle Speed", 0, "km/h")]} def close(self): pass