windowsでNFCのIdmを取得したいけど、どうします？

こんにちは、あるいは、こんばんは。

弊社は、スマートロックにNFCのタグを取得して開閉と記録をとっています。

このNFCのタグは[amazon](https://www.amazon.co.jp/NFC%E3%82%BF%E3%82%B0NTAG215%E3%83%A9%E3%83%99%E3%83%AB-NFC%E3%82%B9%E3%83%86%E3%83%83%E3%82%AB%E3%83%BC-%E6%9B%B8%E3%81%8D%E6%8F%9B%E3%81%88%E5%8F%AF%E8%83%BD-504%E3%83%90%E3%82%A4%E3%83%88%E3%83%A1%E3%83%A2%E3%83%AA-13-56MHz/dp/B07PBDHGDK/ref=sr_1_28?crid=1AUPGN44LOBXG&dib=eyJ2IjoiMSJ9.rz8oq6cqZNufRgBWpxrQ5rDNu7cXRSJk0tmegeKwzAcYa18JztNEfy_Qe0AUM1pui42C-iuzICgFc3J6phZfMEjJLbP85TmKEppiHYyfb65CoN-544zPX7YPA4fRNLmaDCnquPJtDN_sMXAzTSc_AM0JOgJTFXPjpbFql31nhHOFntWjPVHLBlYTYBF5fpwrh8byzE_1uvIOyLBXpubI39y6_62N1RNfv7lCfZgu8z4avIyCCcefIOl4pknagsNRVRULRqH3-1Ap19CTnvIyDbqzUMUgpOneE0010IHaOpk.jltIi34Gy2lth9IZYoP9IZLO91oFE61dyAz_hCaBS2g&dib_tag=se&keywords=nfc%E3%82%BF%E3%82%B0&qid=1710081398&sprefix=NFC%2Caps%2C174&sr=8-28&th=1)で売っているようなこんなタグです。（一例）

開錠にはNFCのタグごとのIdmが必要です。

このIdmはターミナル上でNFCのIdmを読み取ることは以下のコードで取得できる。

``` python:felica_read.py
import binascii
import nfc
import signal


class FelicaCardReader(object):

    def on_connect(self, tag):
        if tag.product != ['FeliCa Standard']:
            # felica
            self.idm = binascii.hexlify(tag.identifier)
        else:
            # nfc
            self.idm = binascii.hexlify(tag.idm)
        return True

    def read_idm(self):
        clf = nfc.ContactlessFrontend('usb')
        try:
            clf.connect(rdwr={'on-connect': self.on_connect})
        finally:
            clf.close()


if __name__ == '__main__':
    read_card = FelicaCardReader()
    while True:
        read_card.read_idm()
        idm = str(read_card.idm, encoding='utf-8', errors='replace')
        print(f'IDm: {idm}')
        signal.signal(signal.SIGINT, signal.SIG_DFL)
```

### だが、これだと人が増えたりした時に「Idmを取得してくだい」という仕事が私に降ってくる。
その度に、macにRC-S380を接続してターミナルでこのプログラムを走らせなければいけない。



#### ~~非常にめんどくさい~~ 
### とても改善できるポイントですね！

弊社には　Raspberry Pi3（以後ラズパイと略す） と　pasori RC-S380(以後パソリと略す)　が余っている。
ラズパイのOSはdebian系で対応しました。
ラズパイを常時起動するか、再起動した時にプログラムを起動するようにして、NFCの読み取り後Idmをslackのチャンネルに通知するようにすればいいんじゃないか？

とりあえず、slackのwebhookを準備するんだ。
あえてここでは説明しない。

その後、先ほどのコードに以下のコードを追加する。

```python
import requests

def _get_webhook_notification_url():
    return ('https://hooks.slack.com/services/省略')  # 各自webhookの設定をしてここに書く。


def send_slack(message):
    if isinstance(message, dict):
        post_data = message
    else:
        post_data = {
            "text": message,
        }

    post_data['username'] = 'ユーザーネームは各自で'
    post_data['channel'] = 'チャンネル名も各自で'
    post_data['icon_emoji'] = '絵文字も各自で'

    print(post_data)

    response = requests.post(
        _get_webhook_notification_url(),
        json=post_data,
    )

    return response

if __name__ == '__main__':
    read_card = FelicaCardReader()
    while True:
        read_card.read_idm()
        idm = str(read_card.idm, encoding='utf-8', errors='replace')
        send_slack(f'IDm: {idm}')
        signal.signal(signal.SIGINT, signal.SIG_DFL)
```

### ラズパイ側の設定

#### pipで必要なものインストールする
```bash
pip3 install requests  
pip3 install nfcpy
pip3 install requires
```

#### コード実行
```bash
sudo python3 felica_read.py >> felica_read.log 2>&1
```

これでslackに通知されちゃうよ!
![Slack_-_チャンネル___nfc-tracker_-_torico.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/516317/fda6c0ca-19ae-a514-7247-09ca671d9765.png)



#### では再起動する時どうしよう


crontabで入れるとして単純に以下の内容だと一瞬走るだけでタグを読み取らない。


```bash:crontab
# ${HOME}にpythonファイルを置いている前提
@reboot sudo python3 ${HOME}/read_felica.py' >> ${HOME}/cronlog/read_felica.log 2>&1
```

そんなこんなでtmuxしか思いつかなかったので、とりあえず、tmuxで対応しました。

```bash
sudo apt install tmux -y
```

```bash:crontab
@reboot (. ~/.profile; tmux new-session -d 'sudo python3 ${HOME}/read_felica.py') >> ${HOME}/cronlog/read_felica.log 2>&1
```

これで再起動しても大丈夫！

これで私がいなくてもIdmを読み取ってくれるぜ！

もっといい方法がありそうだけど、とりあえず目の前のあるものでなんとかしてみるという対応で終わりました。

みなさまご参考ください。