自作ドアシステムのコード
Pythonを用いたドアシステムの開発。NFCカードを用いて認証を行う。認証に失敗したときは失敗した人物の写真を撮影し、Discordに送信する。認証できた場合は、サーボモーターを回転させて鍵の解錠・施錠をする。
開発環境
Raspberry Pi4
Genny
サーボモーター(MG996R)
Webカメラ(EMEET C960)
NFCカードリーダー(RC-S380)
ラズパイに接続するスクリーン、キーボード、マウス
importしたもの(pip install xxxのような)
使い方は、調べてください。
datetime
pigpiod
binascii
nfc
discord
siohttp
cv2
main.py
import datetime
import os
import pigpio
import DoorTest
start = datetime.time(6,0,0)
end = datetime.time(14,23,0)
dt_now = datetime.datetime.now()
nowtime = dt_now.time()
cr = DoorTest.MyCardReader()
Print_I = False
while True:
#最初に表示
print(str(nowtime))
#タッチ待ち
cr.read_id()
if Print_I == True and nowtime >= start and nowtime <end:
#sys.stdout = open("DoorSystem.log", "a")
print(str(nowtime) + "システム名:レーニン起動します")
#sys.stdout = sys.__stdout__
Print_I = False
else:
print("システムは停止いたしました")
Print_I = True
後述のプログラムを動かすためのプログラム
DoorTest.pyを取得してファイル内の関数を実行している。
DoorTest.py
import pigpio
import sys
import binascii
import datetime
import json
import time
import nfc
SERVO_PIN = 18
pi = pigpio.pi()
def set_angle(angle):
assert 0 <= angle <= 180.
pulse_width = (angle / 180) * (2500 - 500) + 500
pi.set_servo_pulsewidth(SERVO_PIN, pulse_width)
class MyCardReader(object):
def __init__(self):
self.is_door_open = False
def on_connect(self, tag):
sys.stdout = open("DoorSystem.log", "a")
idm = binascii.hexlify(tag._nfcid)
print("Get IDm")
dt_now = datetime.datetime.now()
print(dt_now)
start = datetime.time(6,0,0)
end = datetime.time(14,23,0)
now = dt_now.time()
if now >= start and now <end:
json_open = open('Pass_ID.json', 'r')
else:
json_open = open('Master.json', 'r')
Pass_data = json.load(json_open)
id_list = [obj["id"] for obj in Pass_data["user"]]
PassData_list = Pass_data["user"]
if str(idm) in id_list:
if self.is_door_open:
set_angle(95)
time.sleep(1)
message_door="施錠"
else:
set_angle (0)
message_door="解錠"
Name = [UserData["name"] for UserData in PassData_list if str(idm)==UserData["id"]]
print ("同志" + Name[0] + "は認証されたユーザーです。ドアを" + message_door + "します。\n")
self.is_door_open= not self.is_door_open
else:
print ("認証されていないユーザーです。" + str(idm) + "\n")
for a in range(1):
import Camera
sys.stdout = sys.__stdout__
return True
def read_id(self):
clf = nfc.ContactlessFrontend('usb')
try:
clf.connect(rdwr={'on-connect': self.on_connect})
finally:
clf.close()
Pass_ID.jsonとMaster.jsonに入っている情報を元にNFCカード、Suicaの認証を行う。時間によって参照するファイルを変えることによってマスターキーを作成している。認証開始の時間はstartとendの()内の数字を変更することで変更できる。左から時、分、秒となっている。
例)(15 , 0 ,0 )→15時0分0秒
※Pass_ID.jsonには登録者全員を登録する。Master.jsonにはマスターキーとして使うカードを登録する。
IDmなどを登録する方法は後日アップする。
複数のusbケーブルを接続している場合は、usbのIDを入力する必要がある。clfの定義のところに入力する。
例)clf = nfc.ContactlessFrontend('usb: 000:000')
ログをファイルに出力しているため、ターミナルには表示されない。
サーボモーターの角度は個体差があるのでそれぞれの環境で調整してください。
set_angle( )の()内の数字を変更することで調整できる。
Camera.py
from discord import Webhook
import discord
import aiohttp
import asyncio
import cv2
import time
import datetime
import cv2 as cv
webhook_url = "discord_webhook_url"
#カメラで撮影用
camera = cv2.VideoCapture(0)
#タイトルの管理
id=0
count_number = 0
while count_number == 0:
ret,frame =camera.read()
motion_detected = False
if not ret:
break
dt_now = datetime.datetime.now() #データを取得した時刻
#ファイル名と、画像中に埋め込む日付時刻
dt_format_string = dt_now.strftime('%Y-%m-%d %H:%M:%S')
# 動き検出していれば画像を保存する
if 1+1 == 2:
title="image"+str(id)+".jpeg"
cv2.imwrite(title, frame)
print(title)
dt_now = datetime.datetime.now()
#メッセージの詳細
username = "守護天使"
title = (dt_now.strftime('%Y年%m月%d日 %H:%M:%S'))
description = "ID認証に失敗しました"
color_hex = "ff0000"
image_path = "image"+str(id)+".jpeg"
pathid = "image"+str(id)+".jpeg"
#discordに画像を送信する
file = discord.File(image_path, filename="image"+str(id)+".jpeg")
embed = discord.Embed(
title=title, description=description, color=int(color_hex, 16)
).set_image(url="attachment://"+pathid)
async def foo():
async with aiohttp.ClientSession() as session:
webhookdata = Webhook.from_url(webhook_url, session=session)
await webhookdata.send(username=username, embed=embed, file=file)
asyncio.run(foo())
#タイトルの変更
id +=1
count_number +=1
key = cv2.waitKey(1)
if key == 27:
break
count_number -=1
print(count_number)
camera.release()
cv2.destroyAllWindows()
このコードはDiscordに画像を送信するためのもの。Door.pyの中で使用するコード。現状では一度しか作動しないため後日修正する。
discord_webhook_urlはDiscordのWebhook URL(そのまんま)を取得して入力する。これがないと画像を送信することができない。
この記事が気に入ったらサポートをしてみませんか?