Sitemap / Advertise

Introduction

Via Telegram, get apprised of every attempt to lock or unlock the door w/ surveillance footage by night vision camera or USB Webcam.


Tags

Share

IoT | Telegram Fingerprint Door Lock and Surveillance Camera w/ Night Vision

Advertisement:


read_later

Read Later



read_later

Read Later

Introduction

Via Telegram, get apprised of every attempt to lock or unlock the door w/ surveillance footage by night vision camera or USB Webcam.

Tags

Share





Advertisement

Advertisement




    Components :
  • [1]Raspberry Pi 3B+ or 4
  • [1]DFRobot Fingerprint Sensor
  • [1]USB-to-Serial Converter (CP2102)
  • [1]5MP Night Vision Camera for Raspberry Pi
  • [1]USB Webcam
  • [1]Electromagnetic Lock (12V)
  • [1]2 Channel Relay Module
  • [1]12V Battery

Description

For a long time, I had been contemplating installing a security system for my balcony garden door with ample features to grant permission to lock or unlock the door to anyone but me. Thus, I decided to create this project that suffices my balcony garden seclusion with a fingerprint sensor and lets me check its status by sending me surveillance footage by a night vision camera or a USB webcam.

Since Telegram is a cross-platform cloud-based messaging service compatible with iOS and Android, I decided to create a Telegram bot to manage my security system on disparate devices easily. In Telegram, it is effortless to create bots with a command list unalike any other messaging application, which are special accounts that do not require an additional phone number to set up. IoT Surveillance System, the Telegram bot I created for this project, allows me to change the camera type option, request surveillance footage, and display the entry log with these commands:

To fetch and transfer data via the Telegram bot, I developed a PHP web application (outgoing) that gets updated from the Telegram Bot API, sends surveillance footage to the bot, and saves information to the database.

When the fingerprint sensor detects a fingerprint (enrolled or unmatched), I programmed my Raspberry Pi to capture an image and record a video with the selected camera type (night vision camera or USB webcam) to send them to the bot as surveillance footage via the web application. Also, it sends surveillance footage when directly requested by the bot:

Finally, I added an electromagnetic lock to lock or unlock the door if the fingerprint sensor detects an enrolled fingerprint.

Huge thanks to DFRobot for sponsoring this project.

Sponsored products by DFRobot:

⭐ DFRobot Fingerprint Sensor | Inspect

⭐ 5MP Night Vision Camera for Raspberry Pi | Inspect

project-image
Figure - 60.1


project-image
Figure - 60.2


project-image
Figure - 60.3

Step 1: Building a bot for Telegram with BotFather

BotFather is a Telegram bot that lets us create and manage bots on Telegram without any coding required.

⭐ First of all, open BotFather on Telegram and enter /start to view the available command list and manuals.

project-image
Figure - 60.4

⭐ Use the /newbot command to create a new bot. Enter the name of your bot when BotFather asks you for a name. It is displayed in contact details and elsewhere.

IoT Surveillance System

⭐ Then, enter the username of your bot. Usernames are 5-32 characters long and are case insensitive, but may only include Latin characters, numbers, and underscores. They must end in 'bot', e.g. 'tetris_bot' or 'TetrisBot'.

surveillance_system_bot

⭐ After these steps, BotFather generates an authorization token for your new bot. The authorization token is a string along the lines of 123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11 that is required to authorize the bot and send requests to the Telegram Bot API. Keep your token secure and store it safely.

project-image
Figure - 60.5

⭐ Also, you can change your bot's profile picture by using the /setuserpic command.

project-image
Figure - 60.6

⭐ Finally, enter the /setcommands command to create the list of commands supported by the bot. Users will see these commands as suggestions when they type / in the chat with the bot.

⭐ The command list I created for my Telegram bot (IoT Surveillance System):

project-image
Figure - 60.7

Step 2: Developing a web application in PHP to communicate with the bot via the Telegram Bot API

I developed this web application in PHP, named telegram_surveillance_bot, in order to:

⭐ First of all, I created a class named telegram_surveillance to define database settings and functions to communicate with the bot, fetch surveillance footage (files), send (print) commands, and save information to the database.

⭐ In the __init__ function, the class requires four parameters to execute functions:

⭐ In the send_message function, the application sends the given text to the bot via the Telegram Bot API by using its authorization token.

Syntax: https://api.telegram.org/bot<token>/sendMessage?chat_id=<chat_id>&text=<string>

⭐ In the send_photo function, the application sends the given picture to the bot via the Telegram Bot API by using its authorization token.

Syntax: https://api.telegram.org/bot<token>/sendPhoto?chat_id=<chat_id>&photo=<link>&caption=<string>

⭐ In the send_video function, the application sends the given video to the bot via the Telegram Bot API by using its authorization token.

Syntax: https://api.telegram.org/bot<token>/sendVideo?chat_id=<chat_id>&video=<link>&caption=<string>


// Define the telegram_surveillance class and its functions:
class telegram_surveillance {
	public $token, $web_path, $conn, $table;
	
	public function __init__($token, $server, $conn, $table){
		$this->token = $token;
		$this->web_path = $server.$token;
		$this->conn = $conn;
		$this->table = $table;
	}
	// Telegram:
	public function send_message($id, $string){
		$new_message = $this->web_path."/sendMessage?chat_id=".$id."&text=".urlencode($string);
		file_get_contents($new_message);
	}
	
	public function send_photo($id, $photo, $caption){
	    $new_photo = $this->web_path."/sendPhoto?chat_id=".$id."&photo=".$photo."&caption=".$caption;
	    file_get_contents($new_photo);
	}

	public function send_video($id, $video, $caption){
	    $new_video = $this->web_path."/sendVideo?chat_id=".$id."&video=".$video."&caption=".$caption;
	    file_get_contents($new_video);
	}
	
	...
	

⭐ In update_id, update_access, update_camera, and update_surveillance functions, the application saves information transferred from the bot and Raspberry Pi to the database:

⭐ In get_last_access and get_chat_id functions, the application returns access and id variables saved in the database.

⭐ In the get_entry_log function, the application returns the entry log of the security system chronologically by decoding the saved surveillance footage file names with glob and explode functions.



...

	// Fetch:
	public function get_last_access(){
		$sql = "SELECT * FROM `$this->table` LIMIT 1";
		$result = mysqli_query($this->conn, $sql);
		if($row = mysqli_fetch_assoc($result)){
			return $row["access"];
		}
	}
	
	public function get_entry_log(){
		$entries = "";
		foreach(glob("*captured/*.jpg*") as $entry){
			$entries .= explode(".", explode("/", $entry)[1])[0]."\n";
		}
		return $entries;
	}
	
	public function get_chat_id(){
		$sql = "SELECT * FROM `$this->table` LIMIT 1";
		$result = mysqli_query($this->conn, $sql);
		if($row = mysqli_fetch_assoc($result)){
			return $row["id"];
		}
	}

...


⭐ Define the required database settings and create the surveillance object.


// Define database and server settings:
$server = array(
	"name" => "localhost",
	"username" => "<_username_>",
	"password" => "<_password_>",
	"database" => "telegramsurveillance",
	"table" => "entries"

);

$conn = mysqli_connect($server["name"], $server["username"], $server["password"], $server["database"]);

// Define the new 'surveillance' object:
$surveillance = new telegram_surveillance();
$surveillance->__init__("<_bot_token_>", "https://api.telegram.org/bot", $conn, $server["table"]); // e.g., 123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11

⭐ Get updates from the Telegram Bot API.


// Get updates from the Telegram Bot API.
$updates = json_decode(file_get_contents('php://input'), TRUE); 

⭐ If the application receives data from the Telegram Bot API, get the chat ID and message.

⭐ Depending on the type of the incoming message - photo, video, document, or text - reply to the chat with the given chat ID.

⭐ The web application is compatible with these commands from the bot:

⭐ If the /start command is received, the application registers the chat ID to the database to send messages without an update by the bot.

⭐ If /enable_night_vision or /disable_night_vision command is received, the application changes camera and status variables in the database.

⭐ If the /status_check command is received, the application changes surveillance and status variables in the database.

⭐ If the /last_access command is received, the application sends the last entry (access) saved in the database to the bot.

⭐ If the /entry_log command is received, the application sends the entry log (access, failed, and requested) to the bot.


if($updates['update_id']){
	$chat_id =   $updates['message']['chat']['id'];
	$message = $updates['message']['text'];
    
	if($updates["message"]["photo"]){
		$surveillance->send_message($chat_id, "Thank you for sending me a photo but I cannot process it yet 🎞");
	}else if($updates["message"]["video"]){
		$surveillance->send_message($chat_id, "Thank you for sending me a video but I cannot process it yet  📹");
	}else if($updates["message"]["document"]){
		$surveillance->send_message($chat_id, "Thank you for sending me a file but I cannot process it yet  📜");
	}else{
		// Commands:
		switch($message){
		  case '/start':
		  $surveillance->update_id($chat_id); // Register the chat ID to send messages without an update by the bot. 
		  $surveillance->send_message($chat_id, "Chat ID has been successfully registered to the database. Now, you can receive surveillance footage directly from Raspberry Pi if the fingerprint sensor is triggered. Or, you can request surveillance footage without triggering the fingerprint sensor.\n\nEnter /help to view all available commands.");
		  break;	
		  case '/enable_night_vision':
		  $surveillance->update_camera("night", "changed");
		  $surveillance->send_message($chat_id, "📌 Night Vision Camera => Activated!");
		  break;	
		  case '/disable_night_vision':
		  $surveillance->update_camera("USB", "changed");
		  $surveillance->send_message($chat_id, "📌 USB Webcam => Activated!");
		  break;
		  case '/status_check':
		  $surveillance->update_surveillance("footage", "changed");
		  $surveillance->send_message($chat_id, "📌 Footage => Requested!");
		  break;		  
		  case '/last_access':
		  $access = $surveillance->get_last_access();
		  $surveillance->send_message($chat_id, "🕑 Last Access: \n\n$access");
		  break;
		  case '/entry_log':
		  $entries = $surveillance->get_entry_log();
		  $surveillance->send_message($chat_id, "📓 Entry Log: \n\n$entries");
	      break;
		  case '/help':
		  $surveillance->send_message($chat_id, "/enable_night_vision - activate the 5MP Night Vision Camera\n/disable_night_vision - activate the USB Webcam (default)\n/status_check - run the surveillance system without triggered by the fingerprint sensor\n/last_access - display the preceding entry to the fingerprint sensor\n/entry_log - list all attempts to open the fingerprint smart lock");
		  break;	  
	    }
	}
}

project-image
Figure - 60.8


project-image
Figure - 60.9


project-image
Figure - 60.10

⭐ With the web application, to collate and register data transferred by the Telegram bot and Raspberry Pi, create a database table and insert default variables.

telegramsurveillance > entries > variables:


CREATE TABLE `entries`(
   id varchar(255) PRIMARY KEY NOT NULL,
   access varchar(255) NOT NULL,
   camera varchar(255) NOT NULL,
   surveillance varchar(255) NOT NULL,
   `status` varchar(255) NOT NULL
);

INSERT INTO `entries`(`id`, `access`, `camera`, `surveillance`, `status`) VALUES ('default', 'default' , 'USB', 'default', 'default')

project-image
Figure - 60.11


project-image
Figure - 60.12

Getting updates by making requests to https://api.telegram.org/ requires an SSL connection, so I used my web server to host the web application.

theamplituhedron.com

However, the Bot API server source code is available at telegram-bot-api. You can run it locally and send the requests to your server instead of https://api.telegram.org.

project-image
Figure - 60.13

Step 2.1: Setting up the web application to fetch and send data

After developing the web application, I specified the URL of the application for my Telegram bot (IoT Surveillance System) by using the setWebhook method to receive incoming updates from the Telegram Bot API.

https://api.telegram.org/bot<token>/setWebhook/?url=https://www.theamplituhedron.com/telegram_surveillance_bot/

project-image
Figure - 60.14

⭐ After specifying the URL of the application, the Telegram Bot API throws this message: Webhook was set.

⭐ Then, to check the bot functions and register the chat ID to the database, open the bot and enter /start.

project-image
Figure - 60.15


project-image
Figure - 60.16

⭐ Enter /help to view descriptions.

project-image
Figure - 60.17

Step 2.2: Saving surveillance footage from Raspberry Pi and sending it to the bot

When the web application receives surveillance footage (video and image) from Raspberry Pi, it registers the access (last entry) variable to the database and saves the fetched files to the captured folder after checking file extensions and sizes.

After saving files successfully, the application sends the recently uploaded files to the Telegram bot by getting the registered chat ID in the database.


// Save the captured photo and video transferred by Raspberry Pi. And, send them via Telegram Bot API.
if(!empty($_FILES["rasp_video"]["name"]) && !empty($_FILES["rasp_capture"]["name"])){
	// Update the last access (entry).
	$access = (isset($_POST['access'])) ? $_POST['access'] : "Not Detected!";
	$surveillance->update_access($access);
	// Get properties of the uploaded files.
	$video_properties = array(
	    "name" => $_FILES["rasp_video"]["name"],
	    "tmp_name" => $_FILES["rasp_video"]["tmp_name"],
		"size" => $_FILES["rasp_video"]["size"],
		"extension" => pathinfo($_FILES["rasp_video"]["name"], PATHINFO_EXTENSION)
	);
	$capture_properties = array(
	    "name" => $_FILES["rasp_capture"]["name"],
	    "tmp_name" => $_FILES["rasp_capture"]["tmp_name"],
		"size" => $_FILES["rasp_capture"]["size"],
		"extension" => pathinfo($_FILES["rasp_capture"]["name"], PATHINFO_EXTENSION)
	);
	// Check whether the uploaded file extensions are in allowed formats.
	$allowed_formats = array('jpg', 'png', 'mp4');
	if(!in_array($video_properties["extension"], $allowed_formats) || !in_array($capture_properties["extension"], $allowed_formats)){
		echo 'SERVER RESPONSE => File Format Not Allowed!\r\n';
	}else{
		// Check whether the uploaded file sizes exceed the data limit - 5MB.
		if($video_properties["size"] > 5000000 || $capture_properties["size"] > 5000000){
			echo 'SERVER RESPONSE => File size cannot exceed 5MB!\r\n';
		}else{
			$URL = "<_save_files_to_>"; // e.g., https://www.theamplituhedron.com/telegram_surveillance_bot/captured/
			$capture_path = $URL.$capture_properties["name"];
			$video_path = $URL.$video_properties["name"];
			
			// Upload files:
		    move_uploaded_file($video_properties["tmp_name"], "./captured/".$video_properties["name"]);
		    move_uploaded_file($capture_properties["tmp_name"], "./captured/".$capture_properties["name"]);
		    echo "SERVER RESPONSE => Files Uploaded Successfully!\r\n";
			
			// Send the recently uploaded files to the Telegram Bot with the registered chat ID:
			$chat_id = $surveillance->get_chat_id();
			$surveillance->send_photo($chat_id, $capture_path, $capture_properties["name"]);
			$surveillance->send_video($chat_id, $video_path, $video_properties["name"]);
		}
	}
}

project-image
Figure - 60.18

Step 2.3: Transferring (printing) information sent by the bot to Raspberry Pi

If the data variable is received, the web application sends information registered in the database to Raspberry Pi:

https://www.theamplituhedron.com/telegram_surveillance_bot/?data=ok


// If requested, print information to update Raspberry Pi.
if(isset($_GET["data"])){
	$surveillance->print_and_manage_data();
}

⭐ If the status variable is set as "changed", the web application prints camera and surveillance variables registered in the database in JSON:

{"camera":"night","surveillance":"default"}

{"camera":"USB","surveillance":"footage"}

project-image
Figure - 60.19


project-image
Figure - 60.20

⭐ The application changes the status variable from "changed" to "default" after printing information to prevent sending commands repetitively to Raspberry Pi.

project-image
Figure - 60.21



...

	// Print:
	public function print_and_manage_data(){
		$sql = "SELECT * FROM `$this->table` LIMIT 1";
		$result = mysqli_query($this->conn, $sql);
		if($row = mysqli_fetch_assoc($result)){
			if($row["status"] == "default"){
				echo "Waiting new commands...";
			}else if($row["status"] == "changed"){
				$data = array(
					"camera" => $row["camera"],
					"surveillance" => $row["surveillance"]
				);
				// Set variables to default.
				$this->update_surveillance("default", "default");
				echo json_encode($data);
			}
		}
	}

...


Step 3: Creating the Telegram Surveillance System application in Python on Raspberry Pi

In this section, I will discuss how I developed an application, named Telegram Surveillance System, in Python on Raspberry Pi to control the fingerprint sensor, the electromagnetic lock, the night vision camera, and the USB webcam in order to create this project.

The application consists of two code files:

The fingerprint_sensor_settings.py file includes functions to enroll, search, and delete fingerprint images by utilizing the Adafruit Fingerprint Library for Python. In the following steps, I will give more information on this code file and the fingerprint sensor.

The surveillance_system.py file includes the main code of the security system under the Surveillance_System class. Subsequently, I will scrutinize each function under this class to provide more information.

project-image
Figure - 60.22

⭐ In the surveillance_system.py, after importing the required modules, define the GPIO settings and set up the relay pin.


from picamera import PiCamera
import json
from time import sleep
import datetime
from subprocess import call 
import requests
import RPi.GPIO as GPIO
import adafruit_fingerprint
import serial

# Set up BCM GPIO numbering
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
# Set up Relay pins:
lock = 4
GPIO.setup(lock, GPIO.OUT)
GPIO.output(lock, GPIO.HIGH)

⭐ In the __init__ function, the Surveillance_System class defines the fingerprint sensor settings (USB/serial converter) and the server settings (the Telegram bot). Then, it specifies the night vision camera settings and the default camera type option (USB) for the security system.


# Create the Surveillance System class with the required settings:
class Surveillance_System:
    def __init__(self, server, file_location):
        # Define the fingerprint sensor settings (USB/serial converter).
        uart = serial.Serial("/dev/ttyUSB0", baudrate=57600, timeout=1)
        self.finger = adafruit_fingerprint.Adafruit_Fingerprint(uart)
        # Define the server (Telegram Bot) and the file location (captured).
        self.server = server
        self.file_location = file_location
        # Define the Night Vision Camera Settings.
        self.night_cam = PiCamera()
        self.night_cam.resolution = (640, 480)
        self.night_cam.framerate = 15
        # Define the default camera type setting (USB Webcam).
        self.camera_type = "USB"
        self.surveillance_request = "default"
		
...


⭐ In the get_updates_from_web_app function, the class gets data in JSON (camera and surveillance) from the Telegram Bot via the PHP web application.



...

    # Get updates from the Telegram Bot via the PHP web application (telegram_surveillance_bot).
    def get_updates_from_web_app(self):
        data = requests.get(self.server+"?data=ok");
        # If incoming data:
        if(data.text == "Waiting new commands..."):
            pass
        else:
            self.commands = json.loads(data.text)
            self.camera_type = self.commands["camera"]
            self.surveillance_request = self.commands["surveillance"]
			
...


I will explain the remaining class functions in the following steps.

⭐ Define a new class object named surveillance.

⭐ After obtaining updates via the web application, send surveillance footage (requested) to the Telegram bot if requested without triggering the fingerprint sensor.

⭐ If an enrolled fingerprint is detected by the fingerprint sensor, activate the relay to lock or unlock the door and send surveillance footage (access) to the Telegram bot via the web application.

⭐ Otherwise, send surveillance footage (failed) to the Telegram bot via the web application.


surveillance = Surveillance_System("https://www.theamplituhedron.com/telegram_surveillance_bot/", "/home/pi/Telegram_Surveillance_System_w_Fingerprint/captured/") # Change with your settings.

while True:
    # Get updates from the Telegram Bot via the PHP web app.
    surveillance.get_updates_from_web_app()
    sleep(5)
    # If surveillance footage requested without triggering the fingerprint sensor:
    if(surveillance.surveillance_request == "footage"):
        surveillance.surveillance_request = "default"
        print("Bot => Footage Requested!\r\n")
        date = datetime.datetime.now().strftime("%m-%d-%y_%H-%M-%S")
        surveillance.capture_last_attempt(date, "requested_"+date, surveillance.camera_type)
        surveillance.send_last_attempt("requested_"+date)
    # Detect whether the fingerprint is found or not.
    fingerprint_sta = surveillance.detect_fingerprint()
    if(fingerprint_sta == "Waiting"):
        print("Waiting for image...")
    elif(fingerprint_sta == "Found"):
        # Lock or unlock:
        if(GPIO.input(lock)):
            GPIO.output(lock, GPIO.LOW)
        else:
            GPIO.output(lock, GPIO.HIGH)
        print("Fingerprint => Detected!")
        date = datetime.datetime.now().strftime("%m-%d-%y_%H-%M-%S")
        surveillance.capture_last_attempt(date, "access_"+date, surveillance.camera_type)
        surveillance.send_last_attempt("access_"+date)
    elif(fingerprint_sta == "Not Found"):
        print("Fingerprint => Not Found!")
        date = datetime.datetime.now().strftime("%m-%d-%y_%H-%M-%S")
        surveillance.capture_last_attempt(date, "failed_"+date, surveillance.camera_type)
        surveillance.send_last_attempt("failed_"+date)

You can inspect and download the code files separately or within the application folder - Telegram_Surveillance_System.zip.

project-image
Figure - 60.23


project-image
Figure - 60.24


project-image
Figure - 60.25

Step 4: Enrolling and searching fingerprints with the fingerprint sensor on Raspberry Pi

In this project, I used this optical fingerprint sensor which detects and verifies fingerprints. It includes a high-powered DSP chip that does the image rendering, calculation, feature-finding, and searching. Although these sensors were incipiently developed for Arduino, they can be connected to any microcontroller or system with TTL serial to enroll and detect fingerprints.

I utilized a USB-to-Serial Converter (CP2102) to connect the fingerprint sensor (5V) to Raspberry Pi since the built-in UART on the Pi's TX/RX pins (pin 8 / GPIO 14 and pin 10 / GPIO 15) works with 3.3V.

project-image
Figure - 60.26

⭐ After connecting the sensor to Pi, download the Adafruit Fingerprint Library by entering this command to the terminal:

sudo pip3 install adafruit-circuitpython-fingerprint

project-image
Figure - 60.27

⭐ If you want to use the built-in UART, disable the serial console and enable the serial port hardware in raspi-config.

project-image
Figure - 60.28

After installing the library, to test the sensor and enroll fingerprints, I modified the example code provided by Adafruit (fingerprint_sensor_settings.py).

project-image
Figure - 60.29

⭐ First, run the fingerprint_sensor_settings.py that gives three options:

project-image
Figure - 60.30

⭐ Enter e to template a new fingerprint and store it in the given location (from 1 to 127) - that means assigning an ID number to the print.

project-image
Figure - 60.31

⭐ Enter f to test the fingerprint sensor by searching enrolled fingerprints and identifying which ID (if any) is currently being photographed.

⭐ Enter d to remove an enrolled fingerprint model from the sensor.

project-image
Figure - 60.32

After enrolling fingerprints to the sensor by running the fingerprint_sensor_settings.py, I added the detect_fingerprint function to the Surveillance_System class in the main code file (surveillance_system.py).

⭐ In the detect_fingerprint function, the Surveillance_System class gets a fingerprint image, templates it, and checks if it matches the enrolled fingerprints.

⭐ After being executed, depending on the sensor's response, the function returns these variables:



...

    # Get a fingerprint image, template it, and see if it matches.
    def detect_fingerprint(self):
        if self.finger.get_image() != adafruit_fingerprint.OK:
            sleep(1)
            return "Waiting"
        print("Templating...")
        if self.finger.image_2_tz(1) != adafruit_fingerprint.OK:
            return "Not Reading"
        print("Searching...")
        if self.finger.finger_search() != adafruit_fingerprint.OK:
            return "Not Found"
        print("Detected #", self.finger.finger_id, "with confidence", self.finger.confidence)
        return "Found"

...


Step 5.1: Capturing pictures and recording videos with the USB Webcam and sending them to the web application

As explained in the previous steps, this project supports two camera type options - a USB webcam and a 5MP night vision camera - to capture surveillance footage. When the PHP web application receives /enable_night_vision or /disable_night_vision command from the Telegram bot, it changes the camera variable in the database:

Then, as shown in the previous steps, the web application sends the camera variable to Raspberry Pi to change the selected camera type.

Before changing the camera type option, the USB webcam (USB) is the default option. If the fingerprint sensor detects a fingerprint or surveillance footage is directly requested by the Telegram bot: Raspberry Pi captures surveillance footage (image and video) and sends it to the bot via the web application.

Raspberry Pi requires two Python modules to capture images and record videos with a USB webcam:

⭐ Open the terminal and install the fswebcam module with the command below.

sudo apt install fswebcam

project-image
Figure - 60.33

⭐ In the capture_last_attempt function under the Surveillance_System class, Raspberry Pi captures an image and records a video with the USB webcam by adding the date as the timestamp to the file names by these categories:

⭐ After installing the fswebcam module, capture an image by using the subprocess module.

fswebcam -D 2 -S 20 -r widthxheight file_name

⭐ By using the subprocess module, record a 5 seconds video with the ffmpeg module (built-in).

ffmpeg -f video4linux2 -r 20 -t 5 -s widthxheight -i /dev/video0 file_name

⭐ Install the MP4Box module:

sudo apt install -y gpac

⭐ Then, with the MP4Box module, convert the AVI format to the MP4 format since the Telegram video player does not support the AVI format.

MP4Box -add file_name.avi file_name.mp4



...

    # According to the selected camera type (Night Vision or USB Webcam), capture the recent attempt to lock or unlock the door.
    def capture_last_attempt(self, _date, file_name, camera_type):
        file_name = self.file_location + file_name
		
		...
		
        # USB Webcam:
        elif (camera_type == "USB"):
            # Capture an image with Fswebcam module.
            width = "640"
            height = "480"
            command_capture = "fswebcam -D 2 -S 20 -r " + width + "x" + height + " " + file_name + ".jpg"
            call([command_capture], shell=True)
            print("\r\nRasp_Pi => Image Captured!\r\n")
            # Record a 5 seconds video with FFmpeg.
            command_record = "ffmpeg -f video4linux2 -r 20 -t 5 -s " + width + "x" + height + " -i /dev/video0 " + file_name + ".avi"
            call([command_record], shell=True)
            print("Rasp_Pi => Video Recorded! \r\n")
            # Convert the AVI format to the MP4 format.
            command = "MP4Box -add " + file_name + ".avi" + " " + file_name + ".mp4"
            call([command], shell=True)
            print("\r\nRasp_Pi => Video Converted! \r\n")
            sleep(3)

...


project-image
Figure - 60.34


project-image
Figure - 60.35


project-image
Figure - 60.36

⭐ In the send_last_attempt function under the Surveillance_System class, Raspberry Pi transfers surveillance footage (captured image and recorded video) to the web application by using the requests module. Also, it sends the recently captured file's name as the access (last entry) variable.



...

    # Send the recently captured files to the server (web app).
    def send_last_attempt(self, _file_name):
        file_name = self.file_location + _file_name
        # Files:
        files = {'rasp_video': open(file_name+".mp4", 'rb'), 'rasp_capture': open(file_name+".jpg", 'rb')}
        # Last Entry:
        data = {'access': _file_name}
        # Make an HTTP Post Request to the server to send the files.
        request = requests.post(self.server, files=files, data=data)
        # Print the response from the server.
        print("Rasp_Pi => Files Transferred!\r\n")
        print(request.text+"\r\n")

...


project-image
Figure - 60.37

Step 5.2: Capturing pictures and recording videos with the Night Vision Camera and sending them to the web application

The 5MP night vision camera can be connected to the camera module port via the camera module ribbon cable. Thus, it works with the built-in picamera library.

⭐ First of all, select the Interfaces tab and ensure that the Camera is enabled.

⭐ In the capture_last_attempt function under the Surveillance_System class, Raspberry Pi captures an image and records a video with the night vision camera by adding the date as the timestamp to the file names by these categories:

⭐ Annotate the date on the generated files.

⭐ Capture an image and record a 5 seconds video by using the picamera library.

⭐ Then, with the MP4Box module, convert the H264 format to the MP4 format since the Telegram video player does not support the H264 format.

MP4Box -add file_name.h264 file_name.mp4



...

    # According to the selected camera type (Night Vision or USB Webcam), capture the recent attempt to lock or unlock the door.
    def capture_last_attempt(self, _date, file_name, camera_type):
        file_name = self.file_location + file_name
        # Night Vision Camera:
        if(camera_type == "night"):
            # Add date as timestamp on the generated files.
            self.night_cam.annotate_text = _date
            # Capture an image as the thumbnail.
            sleep(2)
            self.night_cam.capture(file_name+".jpg")
            print("\r\nRasp_Pi => Image Captured!\r\n")
            # Record a 5 seconds video.
            self.night_cam.start_recording(file_name+".h264")
            sleep(10)
            self.night_cam.stop_recording()
            print("Rasp_Pi => Video Recorded! \r\n")
            # Convert the H264 format to the MP4 format.
            command = "MP4Box -add " + file_name + ".h264" + " " + file_name + ".mp4"
            call([command], shell=True)
            print("\r\nRasp_Pi => Video Converted! \r\n")
			
...


project-image
Figure - 60.38


project-image
Figure - 60.39


project-image
Figure - 60.40

⭐ As shown in the previous step, in the send_last_attempt function, Raspberry Pi sends surveillance footage (captured image and recorded video) to the web application after saving (/captured) and converting files.

project-image
Figure - 60.41

Connections and Adjustments

First of all, I had to cut, strip, and solder thicker jumper wires to the current wires of the fingerprint sensor to connect the sensor to the USB-to-Serial Converter (CP2102).

project-image
Figure - 60.42


project-image
Figure - 60.43

Then, I attached the USB-to-Serial Converter (CP2102) to Raspberry Pi via a USB Cable.

project-image
Figure - 60.44

I connected the 5MP night vision camera to Raspberry Pi via the camera module port and ribbon cable.

project-image
Figure - 60.45

After that, I connected the USB webcam to Raspberry Pi.

project-image
Figure - 60.46

Finally, I attached the electromagnetic lock and the 12V battery to the 2 Channel relay. And, I connected the 2 Channel relay to Raspberry Pi:

project-image
Figure - 60.47

Modes and Features

📸🔒 The security system scans fingerprints and waits for commands from the Telegram bot (IoT Surveillance System).

project-image
Figure - 60.48

📸🔒 If the Telegram bot sends the /enable_night_vision command, the security system uses the 5MP night vision camera to capture surveillance footage (image and video).

📌 Night Vision Camera => Activated!

project-image
Figure - 60.49

📸🔒 If the Telegram bot sends the /disable_night_vision command, the security system uses the USB webcam to capture surveillance footage (image and video).

📌 USB Webcam => Activated!

project-image
Figure - 60.50

📸🔒 If the fingerprint sensor detects an enrolled (matched) fingerprint, the security system captures and sends surveillance footage depending on the selected camera type. Then, it locks or unlocks the electromagnetic lock.

access_date

access_04-07-21_14-31-10

project-image
Figure - 60.51


project-image
Figure - 60.52


project-image
Figure - 60.53


project-image
Figure - 60.54

📸🔒 Otherwise, if the fingerprint sensor detects an unmatched fingerprint, the security system captures and sends surveillance footage depending on the selected camera type.

failed_date

failed_04-07-21_14-48-30

project-image
Figure - 60.55

📸🔒 If the Telegram bot sends the /status_check command, the security system captures and directly sends surveillance footage depending on the selected camera type without triggered by the fingerprint sensor.

📌 Footage => Requested!

requested_date

requested_04-07-21_14-53-09

project-image
Figure - 60.56


project-image
Figure - 60.57

📸🔒 If the Telegram bot sends the /last_access command, the security system sends the last entry (access) as the reply.

🕑 Last Access:

failed_04-07-21_14-48-30

project-image
Figure - 60.58

📸🔒 If the Telegram bot sends the /entry_log command, the security system sends all registered entries to the system chronologically under these categories:

📓 Entry Log:

project-image
Figure - 60.59

Videos and Conclusion







After completing all steps above, I installed the security system on my balcony garden door, and it works stupendously with the Telegram bot :)

project-image
Figure - 60.60

Code

surveillance_system.py

Download



# IoT | Telegram Fingerprint Door Lock and Surveillance Camera w/ Night Vision
#
# Raspberry Pi 3 Model B+ or 4
#
# By Kutluhan Aktar
#
# Via Telegram, get apprised of every attempt to lock or unlock the door w/ surveillance footage
# by night vision camera or USB Webcam.
#
# For more information:
# https://www.theamplituhedron.com/projects/IoT-Telegram-Fingerprint-Door-Lock-and-Surveillance-Camera-w-Night-Vision/

from picamera import PiCamera
import json
from time import sleep
import datetime
from subprocess import call 
import requests
import RPi.GPIO as GPIO
import adafruit_fingerprint
import serial

# Set up BCM GPIO numbering
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
# Set up Relay pins:
lock = 4
GPIO.setup(lock, GPIO.OUT)
GPIO.output(lock, GPIO.HIGH)

# Create the Surveillance System class with the required settings:
class Surveillance_System:
    def __init__(self, server, file_location):
        # Define the fingerprint sensor settings (USB/serial converter).
        uart = serial.Serial("/dev/ttyUSB0", baudrate=57600, timeout=1)
        self.finger = adafruit_fingerprint.Adafruit_Fingerprint(uart)
        # Define the server (Telegram Bot) and the file location (captured).
        self.server = server
        self.file_location = file_location
        # Define the Night Vision Camera Settings.
        self.night_cam = PiCamera()
        self.night_cam.resolution = (640, 480)
        self.night_cam.framerate = 15
        # Define the default camera type setting (USB Webcam).
        self.camera_type = "USB"
        self.surveillance_request = "default"
    # Get a fingerprint image, template it, and see if it matches.
    def detect_fingerprint(self):
        if self.finger.get_image() != adafruit_fingerprint.OK:
            sleep(1)
            return "Waiting"
        print("Templating...")
        if self.finger.image_2_tz(1) != adafruit_fingerprint.OK:
            return "Not Reading"
        print("Searching...")
        if self.finger.finger_search() != adafruit_fingerprint.OK:
            return "Not Found"
        print("Detected #", self.finger.finger_id, "with confidence", self.finger.confidence)
        return "Found"
    # Get updates from the Telegram Bot via the PHP web application (telegram_surveillance_bot).
    def get_updates_from_web_app(self):
        data = requests.get(self.server+"?data=ok");
        # If incoming data:
        if(data.text == "Waiting new commands..."):
            pass
        else:
            self.commands = json.loads(data.text)
            self.camera_type = self.commands["camera"]
            self.surveillance_request = self.commands["surveillance"]
    # According to the selected camera type (Night Vision or USB Webcam), capture the recent attempt to lock or unlock the door.
    def capture_last_attempt(self, _date, file_name, camera_type):
        file_name = self.file_location + file_name
        # Night Vision Camera:
        if(camera_type == "night"):
            # Add date as timestamp on the generated files.
            self.night_cam.annotate_text = _date
            # Capture an image as the thumbnail.
            sleep(2)
            self.night_cam.capture(file_name+".jpg")
            print("\r\nRasp_Pi => Image Captured!\r\n")
            # Record a 5 seconds video.
            self.night_cam.start_recording(file_name+".h264")
            sleep(10)
            self.night_cam.stop_recording()
            print("Rasp_Pi => Video Recorded! \r\n")
            # Convert the H264 format to the MP4 format.
            command = "MP4Box -add " + file_name + ".h264" + " " + file_name + ".mp4"
            call([command], shell=True)
            print("\r\nRasp_Pi => Video Converted! \r\n")
        # USB Webcam:
        elif (camera_type == "USB"):
            # Capture an image with Fswebcam module.
            width = "640"
            height = "480"
            command_capture = "fswebcam -D 2 -S 20 -r " + width + "x" + height + " " + file_name + ".jpg"
            call([command_capture], shell=True)
            print("\r\nRasp_Pi => Image Captured!\r\n")
            # Record a 5 seconds video with FFmpeg.
            command_record = "ffmpeg -f video4linux2 -r 20 -t 5 -s " + width + "x" + height + " -i /dev/video0 " + file_name + ".avi"
            call([command_record], shell=True)
            print("Rasp_Pi => Video Recorded! \r\n")
            # Convert the AVI format to the MP4 format.
            command = "MP4Box -add " + file_name + ".avi" + " " + file_name + ".mp4"
            call([command], shell=True)
            print("\r\nRasp_Pi => Video Converted! \r\n")
            sleep(3)
    # Send the recently captured files to the server (web app).
    def send_last_attempt(self, _file_name):
        file_name = self.file_location + _file_name
        # Files:
        files = {'rasp_video': open(file_name+".mp4", 'rb'), 'rasp_capture': open(file_name+".jpg", 'rb')}
        # Last Entry:
        data = {'access': _file_name}
        # Make an HTTP Post Request to the server to send the files.
        request = requests.post(self.server, files=files, data=data)
        # Print the response from the server.
        print("Rasp_Pi => Files Transferred!\r\n")
        print(request.text+"\r\n")

# Define a new class object named 'surveillance':
surveillance = Surveillance_System("https://www.theamplituhedron.com/telegram_surveillance_bot/", "/home/pi/Telegram_Surveillance_System_w_Fingerprint/captured/") # Change with your settings.

while True:
    # Get updates from the Telegram Bot via the PHP web app.
    surveillance.get_updates_from_web_app()
    sleep(5)
    # If surveillance footage requested without triggering the fingerprint sensor:
    if(surveillance.surveillance_request == "footage"):
        surveillance.surveillance_request = "default"
        print("Bot => Footage Requested!\r\n")
        date = datetime.datetime.now().strftime("%m-%d-%y_%H-%M-%S")
        surveillance.capture_last_attempt(date, "requested_"+date, surveillance.camera_type)
        surveillance.send_last_attempt("requested_"+date)
    # Detect whether the fingerprint is found or not.
    fingerprint_sta = surveillance.detect_fingerprint()
    if(fingerprint_sta == "Waiting"):
        print("Waiting for image...")
    elif(fingerprint_sta == "Found"):
        # Lock or unlock:
        if(GPIO.input(lock)):
            GPIO.output(lock, GPIO.LOW)
        else:
            GPIO.output(lock, GPIO.HIGH)
        print("Fingerprint => Detected!")
        date = datetime.datetime.now().strftime("%m-%d-%y_%H-%M-%S")
        surveillance.capture_last_attempt(date, "access_"+date, surveillance.camera_type)
        surveillance.send_last_attempt("access_"+date)
    elif(fingerprint_sta == "Not Found"):
        print("Fingerprint => Not Found!")
        date = datetime.datetime.now().strftime("%m-%d-%y_%H-%M-%S")
        surveillance.capture_last_attempt(date, "failed_"+date, surveillance.camera_type)
        surveillance.send_last_attempt("failed_"+date)


fingerprint_sensor_settings.py

Download



# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries
# SPDX-License-Identifier: MIT

import time
import adafruit_fingerprint
import serial

# If using with Linux/Raspberry Pi and hardware UART:
#uart = serial.Serial("/dev/ttyS0", baudrate=57600, timeout=1)

# If using with a computer such as Linux/RaspberryPi, Mac, Windows with USB/serial converter:
uart = serial.Serial("/dev/ttyUSB0", baudrate=57600, timeout=1)

finger = adafruit_fingerprint.Adafruit_Fingerprint(uart)

##################################################


def get_fingerprint():
    """Get a finger print image, template it, and see if it matches!"""
    print("Waiting for image...")
    while finger.get_image() != adafruit_fingerprint.OK:
        pass
    print("Templating...")
    if finger.image_2_tz(1) != adafruit_fingerprint.OK:
        return False
    print("Searching...")
    if finger.finger_search() != adafruit_fingerprint.OK:
        return False
    return True


# pylint: disable=too-many-branches
def get_fingerprint_detail():
    """Get a finger print image, template it, and see if it matches!
    This time, print out each error instead of just returning on failure"""
    print("Getting image...", end="", flush=True)
    i = finger.get_image()
    if i == adafruit_fingerprint.OK:
        print("Image taken")
    else:
        if i == adafruit_fingerprint.NOFINGER:
            print("No finger detected")
        elif i == adafruit_fingerprint.IMAGEFAIL:
            print("Imaging error")
        else:
            print("Other error")
        return False

    print("Templating...", end="", flush=True)
    i = finger.image_2_tz(1)
    if i == adafruit_fingerprint.OK:
        print("Templated")
    else:
        if i == adafruit_fingerprint.IMAGEMESS:
            print("Image too messy")
        elif i == adafruit_fingerprint.FEATUREFAIL:
            print("Could not identify features")
        elif i == adafruit_fingerprint.INVALIDIMAGE:
            print("Image invalid")
        else:
            print("Other error")
        return False

    print("Searching...", end="", flush=True)
    i = finger.finger_fast_search()
    # pylint: disable=no-else-return
    # This block needs to be refactored when it can be tested.
    if i == adafruit_fingerprint.OK:
        print("Found fingerprint!")
        return True
    else:
        if i == adafruit_fingerprint.NOTFOUND:
            print("No match found")
        else:
            print("Other error")
        return False


# pylint: disable=too-many-statements
def enroll_finger(location):
    """Take a 2 finger images and template it, then store in 'location'"""
    for fingerimg in range(1, 3):
        if fingerimg == 1:
            print("Place finger on sensor...", end="", flush=True)
        else:
            print("Place same finger again...", end="", flush=True)

        while True:
            i = finger.get_image()
            if i == adafruit_fingerprint.OK:
                print("Image taken")
                break
            if i == adafruit_fingerprint.NOFINGER:
                print(".", end="", flush=True)
            elif i == adafruit_fingerprint.IMAGEFAIL:
                print("Imaging error")
                return False
            else:
                print("Other error")
                return False

        print("Templating...", end="", flush=True)
        i = finger.image_2_tz(fingerimg)
        if i == adafruit_fingerprint.OK:
            print("Templated")
        else:
            if i == adafruit_fingerprint.IMAGEMESS:
                print("Image too messy")
            elif i == adafruit_fingerprint.FEATUREFAIL:
                print("Could not identify features")
            elif i == adafruit_fingerprint.INVALIDIMAGE:
                print("Image invalid")
            else:
                print("Other error")
            return False

        if fingerimg == 1:
            print("Remove finger")
            time.sleep(1)
            while i != adafruit_fingerprint.NOFINGER:
                i = finger.get_image()

    print("Creating model...", end="", flush=True)
    i = finger.create_model()
    if i == adafruit_fingerprint.OK:
        print("Created")
    else:
        if i == adafruit_fingerprint.ENROLLMISMATCH:
            print("Prints did not match")
        else:
            print("Other error")
        return False

    print("Storing model #%d..." % location, end="", flush=True)
    i = finger.store_model(location)
    if i == adafruit_fingerprint.OK:
        print("Stored")
    else:
        if i == adafruit_fingerprint.BADLOCATION:
            print("Bad storage location")
        elif i == adafruit_fingerprint.FLASHERR:
            print("Flash storage error")
        else:
            print("Other error")
        return False

    return True


##################################################


def get_num():
    """Use input() to get a valid number from 1 to 127. Retry till success!"""
    i = 0
    while (i > 127) or (i < 1):
        try:
            i = int(input("Enter ID # from 1-127: "))
        except ValueError:
            pass
    return i


while True:
    print("----------------")
    if finger.read_templates() != adafruit_fingerprint.OK:
        raise RuntimeError("Failed to read templates")
    print("Fingerprint templates:", finger.templates)
    print("e) enroll print")
    print("f) find print")
    print("d) delete print")
    print("----------------")
    c = input("> ")

    if c == "e":
        enroll_finger(get_num())
    if c == "f":
        if get_fingerprint():
            print("Detected #", finger.finger_id, "with confidence", finger.confidence)
        else:
            print("Finger not found")
    if c == "d":
        if finger.delete_model(get_num()) == adafruit_fingerprint.OK:
            print("Deleted!")
        else:
            print("Failed to delete")


index.php (web app)

Download



<?php

// Define the telegram_surveillance class and its functions:
class telegram_surveillance {
	public $token, $web_path, $conn, $table;
	
	public function __init__($token, $server, $conn, $table){
		$this->token = $token;
		$this->web_path = $server.$token;
		$this->conn = $conn;
		$this->table = $table;
	}
	// Telegram:
	public function send_message($id, $string){
		$new_message = $this->web_path."/sendMessage?chat_id=".$id."&text=".urlencode($string);
		file_get_contents($new_message);
	}
	
	public function send_photo($id, $photo, $caption){
	    $new_photo = $this->web_path."/sendPhoto?chat_id=".$id."&photo=".$photo."&caption=".$caption;
	    file_get_contents($new_photo);
	}

	public function send_video($id, $video, $caption){
	    $new_video = $this->web_path."/sendVideo?chat_id=".$id."&video=".$video."&caption=".$caption;
	    file_get_contents($new_video);
	}
	
	// Database:
	public function update_id($chat_id){
		$sql = "UPDATE `$this->table` SET `id`='$chat_id' LIMIT 1";
		mysqli_query($this->conn, $sql);
	}

	public function update_access($access){
		$sql = "UPDATE `$this->table` SET `access`='$access' LIMIT 1";
		mysqli_query($this->conn, $sql);
	}

	public function update_camera($camera, $status){
		$sql = "UPDATE `$this->table` SET `camera`='$camera', `status`='$status' LIMIT 1";
		mysqli_query($this->conn, $sql);
	}

	public function update_surveillance($surveillance, $status){
		$sql = "UPDATE `$this->table` SET `surveillance`='$surveillance', `status`='$status' LIMIT 1";
		mysqli_query($this->conn, $sql);
	}
	
	// Fetch:
	public function get_last_access(){
		$sql = "SELECT * FROM `$this->table` LIMIT 1";
		$result = mysqli_query($this->conn, $sql);
		if($row = mysqli_fetch_assoc($result)){
			return $row["access"];
		}
	}
	
	public function get_entry_log(){
		$entries = "";
		foreach(glob("*captured/*.jpg*") as $entry){
			$entries .= explode(".", explode("/", $entry)[1])[0]."\n";
		}
		return $entries;
	}
	
	public function get_chat_id(){
		$sql = "SELECT * FROM `$this->table` LIMIT 1";
		$result = mysqli_query($this->conn, $sql);
		if($row = mysqli_fetch_assoc($result)){
			return $row["id"];
		}
	}
	
	// Print:
	public function print_and_manage_data(){
		$sql = "SELECT * FROM `$this->table` LIMIT 1";
		$result = mysqli_query($this->conn, $sql);
		if($row = mysqli_fetch_assoc($result)){
			if($row["status"] == "default"){
				echo "Waiting new commands...";
			}else if($row["status"] == "changed"){
				$data = array(
					"camera" => $row["camera"],
					"surveillance" => $row["surveillance"]
				);
				// Set variables to default.
				$this->update_surveillance("default", "default");
				echo json_encode($data);
			}
		}
	}
}

// Define database and server settings:
$server = array(
	"name" => "localhost",
	"username" => "<_username_>",
	"password" => "<_password_>",
	"database" => "telegramsurveillance",
	"table" => "entries"

);

$conn = mysqli_connect($server["name"], $server["username"], $server["password"], $server["database"]);

// Define the new 'surveillance' object:
$surveillance = new telegram_surveillance();
$surveillance->__init__("<_bot_token_>", "https://api.telegram.org/bot", $conn, $server["table"]); // e.g., 123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11

// Get updates from the Telegram Bot API.
$updates = json_decode(file_get_contents('php://input'), TRUE); 
if($updates['update_id']){
	$chat_id =   $updates['message']['chat']['id'];
	$message = $updates['message']['text'];
    
	if($updates["message"]["photo"]){
		$surveillance->send_message($chat_id, "Thank you for sending me a photo but I cannot process it yet 🎞");
	}else if($updates["message"]["video"]){
		$surveillance->send_message($chat_id, "Thank you for sending me a video but I cannot process it yet  📹");
	}else if($updates["message"]["document"]){
		$surveillance->send_message($chat_id, "Thank you for sending me a file but I cannot process it yet  📜");
	}else{
		// Commands:
		switch($message){
		  case '/start':
		  $surveillance->update_id($chat_id); // Register the chat ID to send messages without an update by the bot. 
		  $surveillance->send_message($chat_id, "Chat ID has been successfully registered to the database. Now, you can receive surveillance footage directly from Raspberry Pi if the fingerprint sensor is triggered. Or, you can request surveillance footage without triggering the fingerprint sensor.\n\nEnter /help to view all available commands.");
		  break;	
		  case '/enable_night_vision':
		  $surveillance->update_camera("night", "changed");
		  $surveillance->send_message($chat_id, "📌 Night Vision Camera => Activated!");
		  break;	
		  case '/disable_night_vision':
		  $surveillance->update_camera("USB", "changed");
		  $surveillance->send_message($chat_id, "📌 USB Webcam => Activated!");
		  break;
		  case '/status_check':
		  $surveillance->update_surveillance("footage", "changed");
		  $surveillance->send_message($chat_id, "📌 Footage => Requested!");
		  break;		  
		  case '/last_access':
		  $access = $surveillance->get_last_access();
		  $surveillance->send_message($chat_id, "🕑 Last Access: \n\n$access");
		  break;
		  case '/entry_log':
		  $entries = $surveillance->get_entry_log();
		  $surveillance->send_message($chat_id, "📓 Entry Log: \n\n$entries");
	      break;
		  case '/help':
		  $surveillance->send_message($chat_id, "/enable_night_vision - activate the 5MP Night Vision Camera\n/disable_night_vision - activate the USB Webcam (default)\n/status_check - run the surveillance system without triggered by the fingerprint sensor\n/last_access - display the preceding entry to the fingerprint sensor\n/entry_log - list all attempts to open the fingerprint smart lock");
		  break;	  
	    }
	}
}

// If requested, print information to update Raspberry Pi.
if(isset($_GET["data"])){
	$surveillance->print_and_manage_data();
}

// Save the captured photo and video transferred by Raspberry Pi. And, send them via Telegram Bot API.
if(!empty($_FILES["rasp_video"]["name"]) && !empty($_FILES["rasp_capture"]["name"])){
	// Update the last access (entry).
	$access = (isset($_POST['access'])) ? $_POST['access'] : "Not Detected!";
	$surveillance->update_access($access);
	// Get properties of the uploaded files.
	$video_properties = array(
	    "name" => $_FILES["rasp_video"]["name"],
	    "tmp_name" => $_FILES["rasp_video"]["tmp_name"],
		"size" => $_FILES["rasp_video"]["size"],
		"extension" => pathinfo($_FILES["rasp_video"]["name"], PATHINFO_EXTENSION)
	);
	$capture_properties = array(
	    "name" => $_FILES["rasp_capture"]["name"],
	    "tmp_name" => $_FILES["rasp_capture"]["tmp_name"],
		"size" => $_FILES["rasp_capture"]["size"],
		"extension" => pathinfo($_FILES["rasp_capture"]["name"], PATHINFO_EXTENSION)
	);
	// Check whether the uploaded file extensions are in allowed formats.
	$allowed_formats = array('jpg', 'png', 'mp4');
	if(!in_array($video_properties["extension"], $allowed_formats) || !in_array($capture_properties["extension"], $allowed_formats)){
		echo 'SERVER RESPONSE => File Format Not Allowed!\r\n';
	}else{
		// Check whether the uploaded file sizes exceed the data limit - 5MB.
		if($video_properties["size"] > 5000000 || $capture_properties["size"] > 5000000){
			echo 'SERVER RESPONSE => File size cannot exceed 5MB!\r\n';
		}else{
			$URL = "<_save_files_to_>"; // e.g., https://www.theamplituhedron.com/telegram_surveillance_bot/captured/
			$capture_path = $URL.$capture_properties["name"];
			$video_path = $URL.$video_properties["name"];
			
			// Upload files:
		    move_uploaded_file($video_properties["tmp_name"], "./captured/".$video_properties["name"]);
		    move_uploaded_file($capture_properties["tmp_name"], "./captured/".$capture_properties["name"]);
		    echo "SERVER RESPONSE => Files Uploaded Successfully!\r\n";
			
			// Send the recently uploaded files to the Telegram Bot with the registered chat ID:
			$chat_id = $surveillance->get_chat_id();
			$surveillance->send_photo($chat_id, $capture_path, $capture_properties["name"]);
			$surveillance->send_video($chat_id, $video_path, $video_properties["name"]);
		}
	}
}

?>


Schematics

project-image
Schematic - 60.1


project-image
Schematic - 60.2

Downloads

Telegram_Surveillance_System.zip

Download