[PYTHON] WeWork office keys can now be unlocked / locked with an IC card using the smart lock "SESAME mini" and Raspberry Pi Zero WH.

We live in a private office at WeWork. Common spaces such as the lounge area in the building can be unlocked with an IC card for WeWork members, but I was a little dissatisfied with the fact that the key to the office room was a physical key. It would be convenient if the room could be opened with an IC card.

When I contacted WeWork support for a way to do it, I heard that there are companies that use commercially available smart locks, so we decided to follow suit.

Introduced Sesame mini

So-called smart locks, which can be attached to the door without any construction work and can be unlocked with a smartphone app, are available from various manufacturers.

However, WeWork's private office keys have a slightly special shape (the width of the mounting area is narrow, the thumb turn knob is thin), so not all smart locks can be mounted. After a lot of research, I decided that Sesame mini would be okay, so I bought it from the online shop.

The points decided are as follows.

  1. Compact width of 57mm allows it to be attached to private office doors
  2. A 3D printer will make an adapter for any shape of key.
  3. You can continue to use the physical key (necessary for cleaning at night)
  4. The price is relatively low and there is no running cost.

In particular, the second point was a decisive factor different from the others. Actually, when I emailed the photo of the key, there was an immediate reply and the adapter was sent to me.

Thanks to that, I was able to unlock / lock with the smartphone app safely. sesame01.gif

It was good that there was matte black in the color variation. It feels good to match the color of the door.

Introducing additional Sesame WiFi access points

Sesame alone can only connect to a smartphone app via Bluetooth, but a dedicated [WiFi access point](https://jp.candyhouse.co/blogs/how-to/wifi%E3%82%A2%E3%82%AF% E3% 82% BB% E3% 82% B9% E3% 83% 9D% E3% 82% A4% E3% 83% B3% E3% 83% 88% E3% 81% A7% E9% 81% A0% E9% 9A% 94% E6% 93% 8D% E4% BD% 9C% E3% 82% 92% E5% 8F% AF% E8% 83% BD% E3% 81% AB% E3% 81% 99% E3% 82% With the addition of 8B), you will be able to access the sesame installed in your office from anywhere in the world with an internet connection.

In addition, Sesame is API is open, so you can customize it yourself.

It's much more convenient than before just to be able to operate it with a smartphone app instead of a physical key, but the ideal is to be able to open and close it with the touch of an IC card. A WiFi access point is indispensable for that, so I purchased it additionally.

Raspberry Pi and IC card reader setup

Raspberry Pi is used for the process of reading the IC card and operating the API. There was already a helpful article, so I generally followed that procedure.

First, prepare the necessary equipment. I bought them all on Amazon.

Then, I proceeded with the setup according to the contents of the above article, but since I did not have a USB hub, mouse, and keyboard, I decided to operate it via WiFi by referring to the following article.

The above steps don't give much consideration to security, so let's do it properly. It's a shared office where various people are mixed.

Read WeWork IC card to operate Sesame API

Well, if you follow the article on operating Sesame with Raspberry Pi earlier, it's generally OK, but there are some parts that do not go well as it is. ** WeWork's card is not Suica **, and ** the API version used in the article is old **.

So, I fixed the part that didn't work and completed the following code. The current version of API requires an API key. How to get the API key is described in here.

SesameNFC.py


# -*- coding: utf-8 -*-
import requests
import json
import binascii
import nfc
import time
import traceback
from threading import Thread, Timer

#1 cycle second of IC card standby
TIME_cycle = 1.0
#IC card standby reaction interval seconds
TIME_interval = 0.2
#Disable seconds from touch to start next
TIME_wait = 3

#SESAME API KEY
API_key = "Sesame API key"

#Preparation for NFC connection request
# 106A(NFC type A)Set with
target_req_nfc = nfc.clf.RemoteTarget("106A")

print 'Please touch the IC card...'
while True:
    try:
        #Instantiate a USB-connected card reader
        clf = nfc.ContactlessFrontend('usb')
        #IC card standby start
        # clf.sense( [Remote target], [Number of searches], [Search interval] )
        target_res = clf.sense(target_req_nfc, iterations=int(TIME_cycle//TIME_interval)+1 , interval=TIME_interval)

        if target_res != None:

            tag = nfc.tag.activate(clf, target_res)

            #Extract ID
            idm = binascii.hexlify(tag.identifier).upper()
            print 'NFC detected. ID = ' + idm

            #IC card check
            if (idm == "tagtool.ID retrieved by py"):
                url_control = "https://api.candyhouse.co/public/sesame/Sesame terminal ID"
                head_control = {"Authorization": API_key, "Content-type": "application/json"}
                # get status
                response_control = requests.get(url_control, headers=head_control)
                #Will an error occur if the interval is short until the next request? So wait a few seconds
                time.sleep(1)
                res = json.loads(response_control.text)
                stats = res["locked"]

                if (stats == True):
                    # unlock
                    payload_control = {"command":"unlock"}
                    response_control = requests.post(url_control, headers=head_control, data=json.dumps(payload_control))

                else:
                    # lock
                    payload_control = {"command":"lock"}
                    response_control = requests.post(url_control, headers=head_control, data=json.dumps(payload_control))

                print(response_control.text)
                print 'sleep ' + str(TIME_wait) + ' seconds'
                time.sleep(TIME_wait)

            #end if
        #end if

        clf.close()
    #end try

    except KeyboardInterrupt:
        print("Ctrl+Stopped at C")
        clf.close()
        break

    except:
        clf.close()
        traceback.print_exc()
        pass

#end while

You can now unlock / lock the sesame with your WeWork IC card! sesame02.gif

The mark on the IC card reader has been turned upside down due to the cable insertion slot, so I put a WeWork sticker on it to cheat. As a result, it looks like an official item, and I think it's wonderful.

Flashes LED when touching IC card, unlocking / locking, or error

It works for the time being, but in fact this code often fails to unlock / lock with an error. Apparently, there are times when the response of the API or WiFi access point is delayed, so if you do it seriously, you should incorporate retry processing etc., but if you touch it again, it will work, so it's okay ... I am.

Instead, the LED flashes at each event. You can tell which process was done by the blinking pattern, and above all, L Chika is the royal road if you do Raspberry Pi!

I referred to the following article for how to blink the LED. How to make Python3 L Chika (LED blinking) with Raspberry Pi Zero WH

And the code that incorporates L Chika is as follows.

SesameNFC_LED.py


# -*- coding: utf-8 -*-
import requests
import json
import binascii
import nfc
import time
import traceback
import RPi.GPIO as GPIO
from threading import Thread, Timer

#1 cycle second of IC card standby
TIME_cycle = 1.0
#IC card standby reaction interval seconds
TIME_interval = 0.2
#Disable seconds from touch to start next
TIME_wait = 3

#SESAME API KEY
API_key = "Sesame API key"

#Preparation for NFC connection request
# 106A(NFC type A)Set with
target_req_nfc = nfc.clf.RemoteTarget("106A")

print 'Please touch the IC card...'
while True:
    try:
        #Instantiate a USB-connected card reader
        clf = nfc.ContactlessFrontend('usb')
        #IC card standby start
        # clf.sense( [Remote target], [Number of searches], [Search interval] )
        target_res = clf.sense(target_req_nfc, iterations=int(TIME_cycle//TIME_interval)+1 , interval=TIME_interval)

        if target_res != None:

            tag = nfc.tag.activate(clf, target_res)

            #Extract ID
            idm = binascii.hexlify(tag.identifier).upper()
            print 'NFC detected. ID = ' + idm

            #IC card check
            if (idm == "tagtool.ID read by py"):

                #Set GPIO number specification mode(BCM:Role pin number, BOARD:PIN number)
                GPIO.setmode(GPIO.BCM)
                #Set to use pin 23 (green LED) as output
                GPIO.setup(23, GPIO.OUT)
                #Blinking
                for i in range(3):
                    GPIO.output(23, GPIO.HIGH)
                    time.sleep(0.5)
                    GPIO.output(23, GPIO.LOW)
                    time.sleep(0.5)
                #Reset GPIO settings
                GPIO.cleanup()

                url_control = "https://api.candyhouse.co/public/sesame/Sesame terminal ID"
                head_control = {"Authorization": API_key, "Content-type": "application/json"}
                # get status
                response_control = requests.get(url_control, headers=head_control)
                #Will an error occur if the interval is short until the next request? So wait a few seconds
                time.sleep(1)
                res = json.loads(response_control.text)
                stats = res["locked"]

                if (stats == True):
                    # unlock
                    payload_control = {"command":"unlock"}
                    response_control = requests.post(url_control, headers=head_control, data=json.dumps(payload_control))
                    #Green LED lights when unlocked
                    GPIO.setmode(GPIO.BCM)
                    GPIO.setup(23, GPIO.OUT)
                    GPIO.output(23, GPIO.HIGH)
                    time.sleep(3)
                    GPIO.output(23, GPIO.LOW)
                    GPIO.cleanup()

                else:
                    # lock
                    payload_control = {"command":"lock"}
                    response_control = requests.post(url_control, headers=head_control, data=json.dumps(payload_control))
                    #Green LED flashes quickly when locked
                    GPIO.setmode(GPIO.BCM)
                    GPIO.setup(23, GPIO.OUT)
                    for i in range(6):
                        GPIO.output(23, GPIO.HIGH)
                        time.sleep(0.25)
                        GPIO.output(23, GPIO.LOW)
                        time.sleep(0.25)
                    GPIO.cleanup()

                print(response_control.text)

                print 'sleep ' + str(TIME_wait) + ' seconds'
                time.sleep(TIME_wait)

            #end if
        #end if

        clf.close()
    #end try

    except KeyboardInterrupt:
        print("Ctrl+Stopped at C")
        clf.close()
        #Flashes red LED (pin 22) violently when an error occurs
        GPIO.setmode(GPIO.BCM)
        GPIO.setup(22, GPIO.OUT)
        for i in range(10):
            GPIO.output(22, GPIO.HIGH)
            time.sleep(0.1)
            GPIO.output(22, GPIO.LOW)
            time.sleep(0.1)
        GPIO.cleanup()
        break

    except:
        clf.close()
        GPIO.cleanup()
        traceback.print_exc()
        #Flashes red LED violently on error
        GPIO.setmode(GPIO.BCM)
        GPIO.setup(22, GPIO.OUT)
        for i in range(20):
            GPIO.output(22, GPIO.HIGH)
            time.sleep(0.1)
            GPIO.output(22, GPIO.LOW)
            time.sleep(0.1)
        GPIO.cleanup()
        pass

#end while

...... It's a clumsy code that I just made it work for the time being, but it doesn't hinder my work, so I'm leaving it untouched.

Can you see the LED blinking on the desk? Only at this time, I was grateful for the glass wall of WeWork. It would have been more troublesome to install an IC card reader and LED on an ordinary wall. sesame03.gif

in conclusion

In this way, we were able to fulfill the desire to unlock and lock the room with WeWork's IC card.

Due to the poor code and the slow response of the API and WiFi access point, the problem of ** often failing to unlock / lock ** or ** taking seconds from touch to unlocking / locking ** Although there are, it is okay because the number of people and frequency of use are not so high. Bumpy, that's fine if I'm comfortable.

So, I am very happy that I am freed from physical keys and smartphone operations, and can freely move from the common area to the private office with an IC card. I'm happy.

Recommended Posts

WeWork office keys can now be unlocked / locked with an IC card using the smart lock "SESAME mini" and Raspberry Pi Zero WH.
I made an npm package to get the ID of the IC card with Raspberry Pi and PaSoRi