Есть считыватель RFID-карт и программа его использующая для авторизации пользователей.
В общем, пока зарегистрированная в системе RFID-карта лежит на считывателе, пользователь авторизован и может работать на машине. Как только карта убирается -- машина должна блокироваться.
Для работы со считывателем используется библиотека Pyscard.
Исходный код CardObserver`а:
from smartcard.CardConnectionObserver import ConsoleCardConnectionObserver
from smartcard.CardMonitoring import CardObserver
from smartcard.util import toHexString
from smartcard.Exceptions import NoCardException
class CardObserver(CardObserver):
def __init__(self, app):
self.app = app
self.connection_observer = ConsoleCardConnectionObserver()
self.has_card = False
self.rfid_tag = None
def update(self, observable, actions):
connected_cards, disconnected_cards = actions
for card in connected_cards:
try:
card.connection = card.createConnection()
card.connection.connect()
card.connection.addObserver(self.connection_observer)
data, sw1, sw2 = card.connection.transmit([255, 202, 0, 0, 0])
data.reverse()
self.rfid_tag = toHexString(data, format=1)
self.has_card = True
except NoCardException:
print('Ошибка. Карта обнаружена, но убрана до прочтения.')
if disconnected_cards:
self.rfid_tag = None
self.has_card = False
Всё работает неплохо, но есть одна проблема.
Пользователь может быстро подменить свою RFID-карту на другую (даже незарегистрированную в системе), тогда CardMonitor может не заметить подмены и не оповестить CardObserver, а значит не будет вызван метод update и новая RFID-метка не будет проверена на предмет регистрации в системе.
Заказчика такое поведение не устраивает.
Кто-нибудь знает самый оптимальный и стабильный способ это исправить?
Я склоняюсь к мысли отказаться от готового классов CardMonitor и CardObserver из Pyscard, а написать свой, что будет в отдельном потоке ежесекундно опрашивать считыватель карт и ежесекундно читать RFID-метку с положенной карты.
Ещё думал приделать отдельный поток к текущей реализации сбоку, в котором RFID-метка только для положенной карты будет перезапрашиваться каждые несколько секунд. Так что внутри метода update, если карта лежит -- поток ежесекундного чтения RFID-метки запускается, если карта убрана -- поток останавливается. На текущий момент, до корректно работающего решения не дошёл.