diff --git a/mfrc522/SimpleMFRC522.py b/mfrc522/SimpleMFRC522.py index 91eca06..b8480ec 100644 --- a/mfrc522/SimpleMFRC522.py +++ b/mfrc522/SimpleMFRC522.py @@ -2,89 +2,118 @@ from . import MFRC522 import RPi.GPIO as GPIO - +import datetime + class SimpleMFRC522: - READER = None - - KEY = [0xFF,0xFF,0xFF,0xFF,0xFF,0xFF] - BLOCK_ADDRS = [8, 9, 10] - - def __init__(self): - self.READER = MFRC522() - - def read(self): - id, text = self.read_no_block() - while not id: - id, text = self.read_no_block() - return id, text + READER = None + + KEY = [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF] + BLOCK_ADDRS = [8, 9, 10] + + def __init__(self): + self.READER = MFRC522() + + def read(self, **kwargs): + ''' + read method accepting a timeout expressed as integer in seconds. For example + read(timeout = 5) will enter the read mode for 5 sec. + ''' + idnum, text = self.read_no_block() + + #Log the current date and time and add timeout to the current time stamp in case entering the while loop + if not kwargs: #If timeout keyword hasn't been provided read for infinity + while idnum is None: + idnum, text = self.read_no_block() + else: + timeout = datetime.datetime.now() + datetime.timedelta(seconds = kwargs['timeout']) + while idnum is None: + idnum, text = self.read_no_block() + if (datetime.datetime.now() > timeout): + break + return idnum, text + + def read_id(self): + idnum = self.read_id_no_block() + while not idnum: + idnum = self.read_id_no_block() + return idnum + + def read_id_no_block(self): + (status, TagType) = self.READER.MFRC522_Request(self.READER.PICC_REQIDL) + if status != self.READER.MI_OK: + return None + (status, uid) = self.READER.MFRC522_Anticoll() + if status != self.READER.MI_OK: + return None + return self.uid_to_num(uid) + + def read_no_block(self): + (status, TagType) = self.READER.MFRC522_Request(self.READER.PICC_REQIDL) + if status != self.READER.MI_OK: + return None, None + (status, uid) = self.READER.MFRC522_Anticoll() + if status != self.READER.MI_OK: + return None, None + idnum = self.uid_to_num(uid) + self.READER.MFRC522_SelectTag(uid) + status = self.READER.MFRC522_Auth( + self.READER.PICC_AUTHENT1A, 11, self.KEY, uid) + data = [] + text_read = '' + if status == self.READER.MI_OK: + for block_num in self.BLOCK_ADDRS: + block = self.READER.MFRC522_Read(block_num) + if block: + data += block + if data: + text_read = ''.join(chr(i) for i in data) + self.READER.MFRC522_StopCrypto1() + return idnum, text_read - def read_id(self): - id = self.read_id_no_block() - while not id: - id = self.read_id_no_block() - return id + def write(self, text, **kwargs): + ''' + kwargs can accept timeout as integer expressed in number of + seconds. If the card is not introduced to the reader within the timeout, the write will be terminated. + ''' + idnum, text_in = self.write_no_block(text) + if not kwargs: #If no kwargs is introduced, the write goes into an infinite + while not idnum: + idnum, text_in = self.write_no_block(text) + return idnum, text_in + else: + timeout = datetime.datetime.now() + datetime.timedelta(seconds = kwargs['timeout']) + if idnum is None: + while (datetime.datetime.now() < timeout): + idnum, text_in = self.write_no_block(text) + if idnum: + break - def read_id_no_block(self): - (status, TagType) = self.READER.MFRC522_Request(self.READER.PICC_REQIDL) - if status != self.READER.MI_OK: - return None - (status, uid) = self.READER.MFRC522_Anticoll() - if status != self.READER.MI_OK: - return None - return self.uid_to_num(uid) - - def read_no_block(self): - (status, TagType) = self.READER.MFRC522_Request(self.READER.PICC_REQIDL) - if status != self.READER.MI_OK: - return None, None - (status, uid) = self.READER.MFRC522_Anticoll() - if status != self.READER.MI_OK: - return None, None - id = self.uid_to_num(uid) - self.READER.MFRC522_SelectTag(uid) - status = self.READER.MFRC522_Auth(self.READER.PICC_AUTHENT1A, 11, self.KEY, uid) - data = [] - text_read = '' - if status == self.READER.MI_OK: - for block_num in self.BLOCK_ADDRS: - block = self.READER.MFRC522_Read(block_num) - if block: - data += block - if data: - text_read = ''.join(chr(i) for i in data) - self.READER.MFRC522_StopCrypto1() - return id, text_read - - def write(self, text): - id, text_in = self.write_no_block(text) - while not id: - id, text_in = self.write_no_block(text) - return id, text_in + def write_no_block(self, text): + (status, TagType) = self.READER.MFRC522_Request(self.READER.PICC_REQIDL) + if status != self.READER.MI_OK: + return None, None + (status, uid) = self.READER.MFRC522_Anticoll() + if status != self.READER.MI_OK: + return None, None + idnum = self.uid_to_num(uid) + self.READER.MFRC522_SelectTag(uid) + status = self.READER.MFRC522_Auth( + self.READER.PICC_AUTHENT1A, 11, self.KEY, uid) + self.READER.MFRC522_Read(11) + if status == self.READER.MI_OK: + data = bytearray() + data.extend(bytearray(text.ljust( + len(self.BLOCK_ADDRS) * 16).encode('ascii'))) + i = 0 + for block_num in self.BLOCK_ADDRS: + self.READER.MFRC522_Write(block_num, data[(i*16):(i+1)*16]) + i += 1 + self.READER.MFRC522_StopCrypto1() + return idnum, text[0:(len(self.BLOCK_ADDRS) * 16)] - def write_no_block(self, text): - (status, TagType) = self.READER.MFRC522_Request(self.READER.PICC_REQIDL) - if status != self.READER.MI_OK: - return None, None - (status, uid) = self.READER.MFRC522_Anticoll() - if status != self.READER.MI_OK: - return None, None - id = self.uid_to_num(uid) - self.READER.MFRC522_SelectTag(uid) - status = self.READER.MFRC522_Auth(self.READER.PICC_AUTHENT1A, 11, self.KEY, uid) - self.READER.MFRC522_Read(11) - if status == self.READER.MI_OK: - data = bytearray() - data.extend(bytearray(text.ljust(len(self.BLOCK_ADDRS) * 16).encode('ascii'))) - i = 0 - for block_num in self.BLOCK_ADDRS: - self.READER.MFRC522_Write(block_num, data[(i*16):(i+1)*16]) - i += 1 - self.READER.MFRC522_StopCrypto1() - return id, text[0:(len(self.BLOCK_ADDRS) * 16)] - - def uid_to_num(self, uid): - n = 0 - for i in range(0, 5): - n = n * 256 + uid[i] - return n + def uid_to_num(self, uid): + n = 0 + for i in range(0, 5): + n = n * 256 + uid[i] + return n