[PYTHON] Have you tried using your student ID as a key? !!


Nice to meet you. This article is the third issue of the joint blog. What kind of joint blog is, I will write a joint blog as a "modest Kansai person" in the group work of the security camp, and it feels like the third person. The articles so far are here. https://modestkansaipeople.hatenablog.com/entry/tsudoinoba


I think that I will be assigned to the seminar room when I am in the third year of university, but it is highly reliable to use the key of the seminar room as a physical key, but it is very inconvenient ... If you are an information student, you can improve it yourself. You should do it! Therefore, we will improve convenience while ensuring reliability. To improve convenience, we decided to use the "student card" that students will always carry with them as a key. Since the analysis of the student ID card is done by our predecessors, we only need to build a hardware and software system.


Software implementation

If you only have the key, you only have to create the process of turning the key, but the professor casually

"It would be nice to know who is in the seminar room ♪ It's like an entry / exit management system."

This complicates the requirements a bit ... instead of just touching the student ID card when turning the lock, it is touched every time you enter or leave.


The above four are defined as the minimum requirements. As you can see from the articles and repositories so far, I have never made anything, so it is probably full of defects ...

Extract student information from your student ID card

Since the student ID card is NFC, it is accessed from the NFC reader. In python, the NFC library "nfcpy" is used. (Official: https://github.com/nfcpy/nfcpy.git) If you get angry that you are not authorized to use PaSoRi, please execute the following command. I have already aliased ... 2-2: 1.0 should be your own PaSoRi that came out with the usblib command.

sudo sh -c "echo -n '2-2:1.0' > /sys/bus/usb/drivers/port100/unbind"

When you clone, there is tagtool.py in example, so when you execute it, all the data that can be absorbed will be output. If there is a runtime error such as authority, the solution will be output, so it is recommended to execute this once. Since you can easily see some data in NFC, let's execute it to understand the structure.

Then I knew the area and size where the student number was stored, so I wrote the code to read it.


def read_idm_No(self, tag):
    # read IDm        
    self.idm = binascii.hexlify(tag.idm).upper().decode('utf-8')
    # defined service code & block
    sc = nfc.tag.tt3.ServiceCode(0x120B >> 6, 0x120B & 0x3f)
    bc = nfc.tag.tt3.BlockCode(0, service=0)
    # read blockdata
    block_data = tag.read_without_encryption([sc], [bc])
    self.No = block_data[0:8].decode("utf-8")
    return True

Since the area where the student number is saved is a writable area, the student number and IDm are acquired as key information.

The process of turning the lock

Operate the servo motor by PWM control. The output control was adjusted by experiment so that it would not run idle or be too strong, so I think this will change depending on the type of lock used.


import RPi.GPIO as GPIO
import time
servo_GPIO = 18 

def openSESAMI():
    GPIO.setup(servo_GPIO, GPIO.OUT)
    servo = GPIO.PWM(servo_GPIO, 50)

def lockSESAMI():
    GPIO.setup(servo_GPIO, GPIO.OUT)
    servo = GPIO.PWM(servo_GPIO, 50)

Entry / exit management process and lock opening / closing conditions

NFC touch log is used for entry/exit management. The log is in the format of following ** username/IDm/student number/H: M: S ** for each date, and entering and exiting is done by acquiring the username of each line of the log of the day and whether it is an odd number or an even number. judge.


def check_room_state(self, user):
    path = 'logs/' + str(self.year) + '/' + str(self.mon) + '/' + str(self.day) + '/access.log' #file path
    with open(path) as f:
        logs = f.readlines() #get logs

    # nobody's room
    if not logs:
        return 2

    cnt = 0
    for i in logs:
        log_user = i.split(sep='/') #get username form logs
        if user == log_user[0]:
            cnt += 1
        if cnt % 2 == 1: #when access time is even, enter the room
            return 0
        else: #when access time is odd, leave the room
            return 1
def main():
    sl = SmartLock()
    key_state = 2
    room_state = 0
    while True:
        print ("touch card:")
        sl.scan()#scan student card
        user = sl.authentication()#authentication
        sl.Log(user)#take log
        if user == 0:#no regist user
            flag = sl.check_room_state(user)
            print(user, key_state, flag, room_state)
            if key_state == 2 or key_state == 0 and flag == 0 and room_state == 0:
                key_state = 1
                room_state += 1
            elif key_state == 1 and flag == 1 and room_state == 1:
                key_state = 0
                room_state = 0
            elif key_state == 1 and flag == 0:
                room_state += 1
            elif key_state == 1 and flag == 1 and room_state > 1:
                room_state -= 1

The state of the key and the number of people in the room are stored as variables, and when the key is closed and the number of people in the room is 0, the key is opened when entering the room, and the key is open and the number of people in the room is 1. Close the key when you leave. Other than that, we will only change the number of people in the room by entering and leaving.

Hard implementation

Now that the system is complete, all that is left is the physical implementation that actually turns the lock.


In our laboratory, a similar one was used before, but it seems that there was a case where the key was broken at the time of taking over and the key could not be opened even with the physical key, and as a requirement, the physical key can be opened at worst. It was raised that it is desirable. Therefore, although it is related to software, taking advantage of the property that the shaft is not fixed unless it is energized, it is energized only when the key is opened and closed, so that it can be escaped even with a physical key. mortor.jpg SG-90 cannot be turned as it is, so I made a catch. The dice were 100% and had a nice size, so I could have made them with a 3D printer, but it was troublesome because I had never used CAD. .. ..

Insert SG-90 into your favorite GPIO control pin to control the 5V pin and GND pin.

Overall view of hardware



The rest is completed by how to fix the motor, Raspberry Pi, and leader to the door. There are many articles about reading the student number and IDm from the student ID card, so I was able to implement it immediately. And I didn't know how to implement authentication well, so I built a DB and implemented it in response to an inquiry. This is a call for improvement methods ... The conditional expression for opening and closing the lock is confusing, so I would like to improve this as well. But well, I think I was able to do it well for the first time I made something. The entire code is here https://github.com/raqqona/SmartLock_nfc

And finally, by a word from the professor ...

"Oh! Good, then I have a ThingWorx that I can't use, but can you make a guy that looks good with the data?"

Next time I tried to make it until I uploaded the data to ThingWorx and displayed it (I have never heard of ThingWorx ...)

Recommended Posts

Have you tried using your student ID as a key? !!
Day 67 [Introduction to Kaggle] Have you tried using Random Forest?
I tried playing a ○ ✕ game using TensorFlow
I tried drawing a line using turtle
I tried using Selective search as R-CNN
I tried using pipenv, so a memo