diff --git a/NfcReaderService.py b/NfcReaderService.py index 95740fd..721e4fb 100644 --- a/NfcReaderService.py +++ b/NfcReaderService.py @@ -10,98 +10,69 @@ from pynput.keyboard import Controller from card_reader import read_card -GET_UID = [0xFF, 0xCA, 0x00, 0x00, 0x00] class NfcReaderService: def __init__(self) -> None: self._is_running = True self._last_uid = None self._keyboard = Controller() - self._last_write = datetime.min + self._last_write = datetime(1900, 1, 1) def run(self) -> None: print("Reader ready.") while self._is_running: try: - self._poll_card() + time.sleep(0.1) + card_request = CardRequest(timeout=None) + print("Waiting for card...") + card_service = card_request.waitforcard() + connection = card_service.connection + print("Connected to card!") + + try: + connection.connect(CardConnection.T1_protocol) + + GET_UID = [0xFF, 0xCA, 0x00, 0x00, 0x00] + uid, sw1, sw2 = connection.transmit(GET_UID) + + if sw1 != 0x90: + raise CardConnectionException("UID read failed") + + uid_hex = toHexString(uid) + + if uid_hex == self._last_uid: + connection.disconnect() + time.sleep(0.5) + self._last_uid = None + continue + + self._last_uid = uid_hex + + user_id = read_card(connection) + if user_id is not None: + now = datetime.now() + if now - self._last_write > timedelta(seconds=2): + self._keyboard.type(str(user_id)) + self._last_write = now + + except (CardConnectionException, NoCardException): + pass + + finally: + try: + connection.disconnect() + except: + pass + + time.sleep(0.5) except (KeyboardInterrupt, SystemExit): self.stop() - except Exception as e: - print(f"[ERROR] Unexpected failure: {e}") - time.sleep(1) - - def _poll_card(self) -> None: - card_request = CardRequest(timeout=1) - - try: - card_service = card_request.waitforcard() - except NoCardException: - self._last_uid = None - return - - connection = card_service.connection - - try: - connection.connect(CardConnection.T1_protocol) - - uid_hex = self._read_uid(connection) - if uid_hex is None: - return - - # Card still present and unchanged -> ignore - if uid_hex == self._last_uid: - return - - self._last_uid = uid_hex - - self._handle_card(connection) - - except (CardConnectionException, NoCardException) as e: - print(f"[CARD ERROR] {e}") - - finally: - try: - connection.disconnect() - except Exception: - pass - - def _read_uid(self, connection) -> Optional[str]: - uid, sw1, sw2 = connection.transmit(GET_UID) - - if sw1 != 0x90: - raise CardConnectionException("UID read failed") - - return toHexString(uid) - - def _handle_card(self, connection) -> None: - user_id = read_card(connection) - - if user_id is None: - return - - now = datetime.now() - - # debounce keyboard output - if now - self._last_write < timedelta(seconds=2): - return - - self._send_to_keyboard(user_id) - self._last_write = now - - def _send_to_keyboard(self, user_id: str) -> None: - try: - self._keyboard.type(f"{user_id}\n") - except Exception as e: - print(f"[KEYBOARD ERROR] {e}") - def stop(self) -> None: - print("Stopping NFC service.") self._is_running = False - if __name__ == "__main__": service = NfcReaderService() - service.run() \ No newline at end of file + service.run()