編集履歴一覧に戻る
3mannennhosii2のアイコン画像

3mannennhosii2 が 2024年10月30日09時05分31秒 に編集

コメント無し

本文の変更

目次 -- 1. 概要 1. アイデアの詳細

-

1. 特徴・使い勝手

+

1. 特徴

1. 使用部品 1. ソースコード 1. 現状・今後 1. 参考文献 概要 --- ラズベリーパイ4と開閉スイッチを使用してドアの開閉の検知、ドアが開いた場合には録画の開始、一定期間ドアが開いていればブザーでの警告とスマホへの送信をすることによって注意を促すことができる。これにより遠隔監視、侵入検知が可能になります。 ![キャプションを入力できます](https://camo.elchika.com/99893ca68e51f1745466456df84311077399eac8/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f38383737316534312d373834652d343662372d393466652d3163333535323865643336342f30346233383562342d303030652d343730612d626137642d643766653139333366383733/) アイデアの詳細 --- ・監視機能:開閉スイッチを使用してドアの開閉の検知 ・アラート機能:45秒以上ドアが開いているのを検知するとブザーでの警告とLEDを点滅させる ・記録機能:監視機能が反応するとカメラを使って録画を開始、ドアが閉まるまで録画を続ける ・通知機能:ドアが開いた際にスマホに通知、一定以上開いていたら閉まっていないことの通知 ・削除機能:録画した動画が多すぎると重くなるので一定期間経過した動画を削除する ラズパイと接続した磁気センサーの入った開閉スイッチをドアと壁に設置します。ドアが開いた場合にスマホにLINE Notifyを使い開いたことの通知を行い、ラズパイで録画をはじめドアが閉まるまで撮影を続けます。 ++追記 LINE Notifyでは録画した動画の送信はできなかったため代案としてスマホアプリでVNCを入れWifi機能を利用することによって直接確認をするか、Google Driveに保存することによって確認をすることが可能++

-

特徴・使い勝手

+

特徴

---

-

このシステムはドアが開いたとき限定で反応するシステムなので常に監視できるわけではありませんが、反応した際にはスマホに通知を行い動画の確認もすることが可能です。そのため、何かあった場合にはすぐに確認や対応することを可能となっています。

+

このシステムはドアが開いたとき限定で反応するシステムなので常に監視できるわけではありませんが、反応した際にはスマホに通知を行い動画の確認もすることが可能です。そのため、何かあった場合にはすぐに確認や対応することを可能となます。

使用部品 --- ・ラズベリーパイ4 ・磁気センサー(ドア開閉スイッチ) ・ラズパイカメラ ・ブザー ・LED ソースコード --- Sentinel Watchのソースコードになります。今回は、GPIO18ピンとグランドに接続してドア開閉スイッチを使用しました。削除機能の時間は今回は一時間に設定しています。 ```arduino:Sentinel Wotchのソースコード import threading import RPi.GPIO as GPIO import sys import os import cv2 from picamera2 import MappedArray, Picamera2 import datetime import shutil import time from picamera2.encoders import H264Encoder import subprocess import requests # LINE Notify送信のために追加 from datetime import datetime, timedelta # ファイル削除用に追加 # GPIOの設定 GPIO.setmode(GPIO.BCM) # ピン番号の設定 LED1 = 27 # GPIO 27 DOOR_PIN = 18 # ドア開閉スイッチ BUZZER_PIN = 23 # ブザー # GPIOピンの設定

-

GPIO.setup(LED1, GPIO.OUT) # LED 出力設定

+

GPIO.setup(LED1, GPIO.OUT)

GPIO.setup(DOOR_PIN, GPIO.IN, pull_up_down=GPIO.PUD_UP) GPIO.setup(BUZZER_PIN, GPIO.OUT) # 録画回数(リビジョン)を管理

-

revision_counter = 0 # 初期リビジョンを0に設定

+

revision_counter = 0

# Line Notify設定

-

LINE_NOTIFY_TOKEN = "YOUR_LINE_NOTIFY_TOKEN" # ここにLINE Notifyのトークンを入力

+

LINE_NOTIFY_TOKEN = "YOUR_LINE_NOTIFY_TOKEN"

LINE_NOTIFY_API = 'https://notify-api.line.me/api/notify' # Line Notify送信関数 def send_line_notify(message): headers = { 'Authorization': f'Bearer {LINE_NOTIFY_TOKEN}' } payload = {'message': message} response = requests.post(LINE_NOTIFY_API, headers=headers, params=payload) print(f"LINE Notify Response: {response.status_code}, {response.text}") # 録画ファイルの削除関数 (1時間経過した .mp4 ファイルを削除) def delete_old_videos(directory, max_age_minutes=60): now = time.time() max_age_seconds = max_age_minutes * 60 for filename in os.listdir(directory): file_path = os.path.join(directory, filename) # 拡張子が .mp4 のファイルのみを対象とする if os.path.isfile(file_path) and file_path.endswith('.mp4'): file_age_seconds = now - os.path.getmtime(file_path) if file_age_seconds > max_age_seconds: print(f"削除対象: {file_path} (経過時間: {file_age_seconds}秒)") os.remove(file_path) # 録画ファイルの監視スレッド(1分おきに60分以上経過したファイルを削除) def video_cleanup_watcher(): while True: delete_old_videos("/home/pi/sentinel", max_age_minutes=15)

-

time.sleep(60) # 1分おきに監視

+

time.sleep(60)

# カメラ録画関数 def camera01():

-

global DOOR_PIN, revision_counter # グローバル変数宣言 print("CAMERA START") # カメラスタートをターミナルに表示

+

global DOOR_PIN, revision_counter print("CAMERA START")

try:

-

camera = Picamera2() # PiCamera2()をcameraで宣言

+

camera = Picamera2()

camera.configure(camera.create_video_configuration())

-

camera.configure(camera.create_preview_configuration(main={"format": 'XRGB8888', "size": (640, 480)})) # 解像度640×480で設定

+

camera.configure(camera.create_preview_configuration(main={"format": 'XRGB8888', "size": (640, 480)}))

# タイムスタンプを追加

-

colour = (0, 255, 0) # タイムスタンプの色を設定

+

colour = (0, 255, 0)

origin = (0, 30) font = cv2.FONT_HERSHEY_SIMPLEX scale = 1 thickness = 2 def apply_timestamp(request):

-

timestamp = time.strftime("%Y-%m-%d %X") # タイムスタンプのフォーマットを設定

+

timestamp = time.strftime("%Y-%m-%d %X")

with MappedArray(request, "main") as m: cv2.putText(m.array, timestamp, origin, font, scale, colour, thickness) camera.pre_callback = apply_timestamp

-

encoder = H264Encoder(10000000) # エンコーダの設定

+

encoder = H264Encoder(10000000)

# 保存先ディレクトリを確認・作成 os.makedirs("/home/pi/sentinel", exist_ok=True) # 録画ファイル名にタイムスタンプとリビジョンを追加 timestamp = time.strftime("%Y%m%d_%H%M%S") revision_counter += 1 # リビジョンをインクリメント h264_file_path = f"/home/pi/sentinel/DoorIsOpen_{timestamp}_rev{revision_counter}.h264" mp4_file_path = f"/home/pi/sentinel/DoorIsOpen_{timestamp}_rev{revision_counter}.mp4"

-

camera.start_recording(encoder, h264_file_path) # 録画開始

+

camera.start_recording(encoder, h264_file_path)

# ドアが開いている間録画を続ける while GPIO.input(DOOR_PIN) == 0: GPIO.output(LED1, True) # LED点灯

-

camera.stop_recording() # ドアが閉まったら録画停止 camera.close() # カメラをクローズしてリソース解放

+

camera.stop_recording() camera.close()

print("録画を終了しました") # H264をMP4に変換 (subprocess.runでエラーチェックを追加) result = subprocess.run(['/usr/bin/MP4Box', '-add', h264_file_path, mp4_file_path], capture_output=True, text=True) # MP4Boxのエラーを確認 if result.returncode != 0: print(f"MP4Boxエラー: {result.stderr}") raise RuntimeError(f"MP4Boxによる変換に失敗しました。") # MP4ファイルが存在するか確認 if not os.path.exists(mp4_file_path): raise FileNotFoundError(f"{mp4_file_path} が見つかりません。変換に失敗しました。") # 元の.h264ファイルを削除 os.remove(h264_file_path) GPIO.output(LED1, False) # LED消灯 print(f"録画ファイルが保存されました: {mp4_file_path}") return mp4_file_path except Exception as e: print(f"Error in camera recording: {e}") return None # LED点灯スレッド 録画時に点灯する def ledmain(): global stopstr1 stopstr1 = " "

-

last_buzzer_time = 0 # ブザーのタイマー door_open_start_time = None # ドアが開いた時間を初期化 door_was_open = False # ドアの状態を記録 notified_open = False # 「ドアが開いています」を送信したかどうか notified_open_long = False # 「ドアが開いたままです」を送信したかどうか

+

last_buzzer_time = 0 door_open_start_time = None door_was_open = False notified_open = False notified_open_long = False

while True: if stopstr1 != " ": GPIO.cleanup() print("ドア監視終了") sys.exit() current_time = time.time() # ドアが開いているかチェック door_open = GPIO.input(DOOR_PIN) == 0 if door_open: if door_open_start_time is None:

-

door_open_start_time = current_time # ドアが開いた時間を記録 if not door_was_open: # 状態が変わった場合のみ通知

+

door_open_start_time = current_time if not door_was_open:

print("ドアが開いています") door_was_open = True notified_open = False notified_open_long = False

-

GPIO.output(LED1, True) # LEDを点灯

+

GPIO.output(LED1, True)

# ドアが開いたことを通知(まだ通知していない場合) if not notified_open: send_line_notify("ドアが開いています") notified_open = True # 45秒以上開いている場合に「ドアが開いたままです」を通知(まだ通知していない場合) if current_time - door_open_start_time > 45 and not notified_open_long: send_line_notify("ドアが開いたままです") notified_open_long = True if current_time - last_buzzer_time > 45 and current_time - door_open_start_time > 10:

-

GPIO.output(BUZZER_PIN, GPIO.HIGH) # ブザーを鳴らす

+

GPIO.output(BUZZER_PIN, GPIO.HIGH)

time.sleep(0.5) GPIO.output(BUZZER_PIN, GPIO.LOW) last_buzzer_time = current_time # 録画処理 video_file = camera01() if video_file: print(f"録画ファイルが作成されました: {video_file}") else:

-

if door_was_open: # ドアが閉まったときだけ通知

+

if door_was_open:

print("ドアが閉まりました")

-

GPIO.output(LED1, False) # LEDを消灯 door_open_start_time = None # ドアが閉まったらリセット door_was_open = False # ドアが閉まったことを記録

+

GPIO.output(LED1, False) door_open_start_time = None door_was_open = False

notified_open = False notified_open_long = False

-

time.sleep(1) # 処理を1秒ごとに制御し、頻度を抑える

+

time.sleep(1)

# プログラム終了時の割り込み入力処理 def stopinput(): global stopstr1

-

stopstr1 = input() # キー入力待ち

+

stopstr1 = input()

# スレッドの開始 stop_thread = threading.Thread(target=stopinput) stop_thread.start() led_thread = threading.Thread(target=ledmain) led_thread.start() # 録画ファイルの監視スレッドの開始 cleanup_thread = threading.Thread(target=video_cleanup_watcher) cleanup_thread.start() # スレッドの終了を待つ stop_thread.join() led_thread.join() cleanup_thread.join() # GPIOのクリーンアップ GPIO.cleanup() ``` プログラムの動きとしては、ドアを開閉した際に磁気センサーが反応して信号を送ることによって開閉の検知、その際にLINE Notifyに「ドアが開きました」と送信。もし、45秒以上ドアが開いているなら続いて「ドアが開いたままです」と送信するのに加えてLEDの点滅やブザーでの警告も行っています。 録画の部分は動画の順番がわかりやすいように番号を付けています。削除は一分ごとにファイルの監視を行い一時間以上経過した動画は削除するようにしています。

-

==今回はLINE Notifyでメッセージの送信をできるようにして録画した動画はVNCアプリとWifi機能を使い確認しました。==

現状・今後 ---

-

現状ドアの開閉の検知や監視機能・録画機能・削除機能ともに動作できていますが、LINE Notifyでの録画した動画の送信についてはできないため、Google Driveを使用した動画の保存を試そうと考えています。そのため現状は代案の一つ目のVNCアプリとWifi機能をようしての動作の確認になります。

+

現状ドアの開閉の検知や監視機能・録画機能・削除機能ともに動作できていますが、LINE Notifyでの録画した動画の送信についてはできないため、Google Driveを使用した動画の保存を試そうと考えています。そのため現状は代案の一つ目のVNCアプリとWifi機能を使用ての動作の確認になります。

参考文献 --- > https://monomonotech.jp/kurage/raspberrypi/daiso_sensorlight.html [](url)