Files
rdm-card-reader/src/rdm_card_reader/demo.py
T
ske087 c720f4ca67 Remove dead code and use the event constants consistently
- drop unused BAR import, _VALID_MODES, _is_optional(),
  OPTIONAL_IMPORTS and is_loopback()
- replace hand-written event name strings with EVENT_INSERTED,
  EVENT_REMOVED and EVENT_INVALID, so a typo cannot silently
  disable an event path
- drop the now-moot pytest/coverage entries from .gitignore

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-10-05 21:24:45 +03:00

53 lines
1.5 KiB
Python

"""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