"""Simulated card reads, so the output can be checked without hardware.""" from __future__ import annotations import random import time from .card import ( DEFAULT_HEARTBEAT_INTERVAL, EVENT_INVALID, EVENT_INSERTED, EVENT_REMOVED, CardData, CardEvent, format_event, ) # Card ids with the checksum the real protocol would produce # (XOR of the type byte and the four id bytes), so the output looks genuine. DEMO_CARDS = ( CardData(value=0x00C4A0B5, checksum=0xDE, type=0x0F, is_valid=True), CardData(value=0x1A2B3C4D, checksum=0x4F, type=0x0F, is_valid=True), CardData(value=0xDEADBEEF, checksum=0x00, type=0x0F, is_valid=False), ) def _emit(event: CardEvent, as_json: bool) -> None: print(event.to_json() if as_json else format_event(event), flush=True) def run_demo( count: int = 3, heartbeat: float = DEFAULT_HEARTBEAT_INTERVAL, as_json: bool = False, seed: int = 1234, ) -> int: """Print *count* simulated card read cycles. Returns a process exit code.""" rng = random.Random(seed) print("Demo mode - no hardware is used, values are simulated.\n", flush=True) for _ in range(max(1, count)): card = rng.choice(DEMO_CARDS) event_name = EVENT_INSERTED if card.is_valid else EVENT_INVALID _emit(CardEvent.from_card(event_name, card, "demo"), as_json) time.sleep(max(0.1, heartbeat)) if card.is_valid: _emit(CardEvent.from_card(EVENT_REMOVED, card, "demo"), as_json) time.sleep(0.3) print("\nDemo finished.", flush=True) return 0