
Partager:
Ancien développeur éducateur @Vonage. Issu d'une formation PHP, mais pas limité à un seul langage. Joueur passionné et adepte du Raspberry pi. On le trouve souvent en train de faire du bloc dans des salles d'escalade.
Système de surveillance domestique avec un nœud et un Raspberry Pi
Temps de lecture : 42 minutes
Vous êtes-vous déjà demandé comment construire un système de surveillance à domicile ? Peut-être pour surveiller vos enfants, surveiller les personnes vulnérables dans leur maison, ou pour être le système de sécurité de votre maison ? Ce tutoriel vous guidera dans le processus d'introduction à la construction d'un tel système.
Dans ce tutoriel, vous allez construire un petit système de surveillance domestique bon marché en utilisant un Raspberry Pi 4 avec un module Raspberry Pi Camera et un capteur de mouvement. La partie logicielle de ce système utilisera Video API de Vonage (anciennement TokBox OpenTok) pour publier le flux et l'API Vonage Messages API de Vonage pour notifier l'utilisateur de la détection d'un mouvement par SMS.
Voici quelques-unes des choses que vous apprendrez dans ce tutoriel :
Comment configurer un Raspberry Pi,
Installez une caméra Raspberry Pi et un capteur de mouvement,
Comment utiliser Messages API de Vonage (anciennement Nexmo) pour envoyer des SMS,
Comment utiliser Video API de Vonage (anciennement TokBox OpenTok) pour créer et visualiser un flux en direct.
Conditions préalables
Raspberry Pi 4
Module caméra Raspberry Pi
Capteur de mouvement (HC-SR501 PIR)
Node et NPM installés sur le Raspberry Pi
Vonage API Account
To complete this tutorial, you will need a Vonage API account. If you don’t have one already, you can sign up today and start building with free credit. Once you have an account, you can find your API Key and API Secret at the top of the Vonage API Dashboard.
This tutorial also uses a virtual phone number. To purchase one, go to Numbers > Buy Numbers and search for one that meets your needs.
Installation et configuration du Raspberry Pi
La Fondation Raspberry Pi est une organisation caritative basée au Royaume-Uni qui permet à des personnes du monde entier de résoudre des problèmes technologiques et de s'exprimer de manière créative en utilisant la puissance de l'informatique et des technologies numériques pour le travail.
Sur leur site, vous trouverez un excellent guide pas à pas sur la nature de chaque élément du Raspberry Pi, sur l'installation du système d'exploitation et sur la manière de commencer à utiliser un Raspberry Pi. Il existe également de nombreuses autres ressources pour vous aider à résoudre les problèmes que vous pourriez rencontrer, ainsi que de nombreux autres projets susceptibles de vous intéresser.
Installation de caméras et de détecteurs de mouvement
Installation du module de caméra Raspberry Pi
Ce tutoriel utilise un Raspberry Pi 4 et le module officiel Raspberry Pi Camera, bien qu'il n'y ait aucun problème à utiliser d'autres caméras.
La photo ci-dessous représente le Raspberry Pi et un module de caméra utilisés dans cet article :
A Raspberry Pi with the Camera module
Connectez le module de caméra via le câble ruban dans le port du module de caméra du Raspberry Pi. La photo ci-dessous montre l'endroit où vous devez installer le ruban du module de caméra :
Raspberry Pi with Camera Ribbon Installed
Activation de SSH et de la caméra
Secure Shell (SSH) est un logiciel qui permet une connexion sécurisée et le contrôle d'un système distant. Dans ce tutoriel, le Raspberry Pi fonctionnera en mode "headless", c'est-à-dire sans écran, clavier ou souris. Une fois SSH activé, vous pourrez vous connecter à l'appareil à distance sur votre ordinateur ou votre téléphone.
Pour activer SSH, dans le terminal du Raspberry Pi, exécutez :
Vous verrez apparaître un écran semblable à l'image ci-dessous :
Raspberry Pi Configuration
Choisir l'option 5 - Interfacing Options
Dans le menu suivant, choisissez l'option P1 pour
Camerapuis sélectionnezYes,Choisissez ensuite l'option P2 pour
SSHet sélectionnez à nouveauYes.
Vous avez maintenant activé le module Caméra et SSH sur votre Raspberry Pi.
Installation du détecteur de mouvement
L'étape suivante consiste à connecter le Raspberry Pi à un capteur de mouvement. Ce tutoriel utilise le capteur de mouvement PIR HC-SR501, mais d'autres modules de capteurs de mouvement devraient fonctionner correctement. Veuillez vous référer à leurs guides de câblage pour les connecter à votre Raspberry Pi.
Tout d'abord, prenez le capteur et connectez-y trois fils. J'ai utilisé le rouge pour la tension, le bleu pour le GPIO et le noir pour la masse. Pour le capteur de cet exemple, la première broche est la terre, la deuxième le GPIO et la troisième la tension, comme indiqué :
Example of Motion Sensor
Un excellent exemple de description de chacune des broches du Raspberry Pi se trouve sur le site suivant le site Web du Raspberry Pi. Le diagramme illustre la disposition des broches GPIO, comme indiqué ci-dessous :
Diagram of Raspberry Pi GPIO Pins
La dernière partie consiste à connecter les fils au Raspberry Pi. Le fil sous tension (rouge) doit être connecté à l'une des broches du Pi. 5V power Le fil de terre (noir) doit être connecté à l'une des broches du Pi, en me référant au diagramme ci-dessus, j'ai utilisé la broche 2. GND Le fil de terre (noir) doit être connecté à l'une des broches du Pi, en se référant à nouveau au diagramme, j'ai utilisé la broche 6. Le dernier fil à relier est le fil GPIO (bleu), qui doit être connecté à l'une des broches du Pi. GPIO broches. Dans cet exemple, j'ai utilisé la broche 12, étiquetée "GPIO 18".
La configuration finale du câblage est illustrée ci-dessous :
Sensor Writing Part 2
Test de la détection de mouvement
Maintenant que tout le matériel est installé et configuré, il est temps de construire le code du projet. Cependant, il faut d'abord créer un projet Node pour tester les mouvements et préparer le projet à venir. C'est dans ce projet que vous écrirez tout le code de détection de mouvement et de streaming vidéo. Pour créer un nouveau projet Node, créez un nouveau répertoire, allez dans ce répertoire et exécutez npm init. L'exécution des commandes ci-dessous permet de réaliser ces trois opérations :
Suivez les instructions demandées, donnez un nom au projet et laissez le reste des entrées par défaut.
Les commandes suivantes créent un nouveau index.jsqui contiendra la majorité de votre code, et installe un nouveau paquetage appelé onoff qui permet de contrôler les broches GPIO :
Dans votre nouveau fichier index.js copiez le code suivant qui lit la broche GPIO 18 pour alerter si un mouvement a été détecté, ou alerter lorsque le mouvement s'est arrêté.
const gpio = require('onoff').Gpio;
const pir = new gpio(18, 'in', 'both');
pir.watch(function(err, value) {
if (value == 1) {
console.log('Motion Detected!')
} else {
console.log('Motion Stopped');
}
});Il est temps de vérifier si le code ci-dessus et l'installation du détecteur de mouvement ont réussi. Exécuter :
Agitez votre main devant le capteur de mouvement, puis regardez le terminal pour voir "Motion Detected !". Quelques secondes plus tard, vous verrez apparaître le message "Mouvement arrêté".
Test de l'appareil photo
Dans la ligne de commande de votre Raspberry Pi, tapez la commande suivante pour prendre une photo de la vue de la caméra.
REMARQUE Si vous vous êtes connecté en tant qu'utilisateur autre que l'utilisateur par défaut piremplacez pi par votre nom d'utilisateur.
En regardant dans le répertoire /home/pi/ vous verrez maintenant cam.jpg. En l'ouvrant, vous verrez une photo de la vue actuelle de la caméra de votre Raspberry Pi.
Node et NPM
Node et NPM doivent être installés et à la bonne version. Allez sur nodejs.orgtéléchargez et installez la bonne version si vous ne l'avez pas.
Notre CLI
Configurez votre CLI Vonage en utilisant ce guide. Vous n'avez besoin que de l'outil Installation et Configuration de l'application de votre configuration.
Git (optionnel)
Vous pouvez utiliser git pour cloner l'application application de démonstration à partir de GitHub.
Pour ceux qui ne sont pas à l'aise avec les commandes git, ne vous inquiétez pas, je vous couvre.
Suivez ce pour installer git.
Installer un serveur Mysql
Sur le Raspberry Pi, exécutez la commande suivante pour installer le serveur de base de données MySQL :
Par défaut, le serveur MySQL est installé avec l'utilisateur root n'a pas de mot de passe. Vous devez corriger cela, pour vous assurer que la base de données n'est pas non sécurisée. Sur le Pi, exécutez la commande ci-dessous et suivez les instructions.
Maintenant que le mot de passe de l'utilisateur root est défini, il est temps de créer une base de données et un utilisateur pour accéder à cette base de données. Connectez-vous au serveur MySQL :
Exécutez maintenant les requêtes SQL suivantes pour créer un nouvel utilisateur et lui accorder certains privilèges sur une nouvelle base de données :
-- Creates the database with the name picam
CREATE DATABASE picam;
-- Creates a new database user "camuser" with a password "securemypass" and grants them access to picam
GRANT ALL PRIVILEGES ON picam.* TO `camuser`@localhost IDENTIFIED BY "securemypass";
-- Flushes these updates to the database
FLUSH PRIVILEGES;Votre Raspberry Pi est maintenant configuré et prêt pour la partie code de ce tutoriel.
Création de l'application
Installation d'un certificat SSL
Dans le terminal de votre Raspberry Pi, changez de répertoire jusqu'au chemin de votre projet et exécutez la commande suivante pour générer un certificat SSL auto-signé. L'accès à l'API Video de Vonage nécessite HTTPS, un certificat SSL est donc nécessaire, même s'il est auto-signé. Exécutez la commande ci-dessous pour générer vos certificats SSL.
Deux fichiers sont créés, key.pem et cert.pemdéplacez-les à un endroit auquel votre code peut accéder. Pour ce tutoriel, ils se trouvent dans le répertoire du projet.
Le serveur Web
Express est un framework d'application web Node.js minimal et flexible qui offre un ensemble robuste de fonctionnalités pour les applications web et mobiles.
Express est un framework Node.js très léger et flexible, c'est ce dont vous avez besoin dans ce projet. Fournir des points d'extrémité pour que vous puissiez accéder à votre flux vidéo.
Installez Express dans votre application à l'aide de la commande suivante :
En haut du fichier index.js vous devez importer les paquets https, fs et express. Effectuez les modifications suivantes :
+ const express = require('express');
+ const https = require('https');
+ const fs = require('fs');
const gpio = require('onoff').Gpio;
+ const app = express();
const pir = new gpio(18, 'in', 'both');
pir.watch(function(err, value) {
if (value == 1) {
console.log('Motion Detected!')
- } else {
- console.log('Motion Stopped');
}
});Vous n'avez pas besoin de la partie else de la détection de mouvement pour ce tutoriel. Supprimez donc également cette partie, comme indiqué ci-dessus.
Vous avez besoin d'un serveur web pour accéder à votre flux vidéo via le réseau ou Internet. Il est temps de créer une méthode pour initier un nouveau serveur avec un exemple de point de terminaison. Ci-dessus pir.watch(function(err, value) { ajouter
async function startServer() {
const port = 3000;
app.get('/', (req, res) => {
res.json({ message: 'Welcome to your webserver!' });
});
const httpServer = https.createServer({
// The key.pem and cert.pem files were created by you in the previous step, if the files are not stored in the project root directory
// make sure to update the two lines below with their correct paths.
key: fs.readFileSync('./key.pem'),
cert: fs.readFileSync('./cert.pem'),
// Update this passphrase with what ever passphrase you entered when generating your SSL certificate.
passphrase: 'testpass',
}, app);
httpServer.listen(port, (err) => {
if (err) {
return console.log(`Unable to start server: ${err}`);
}
return true;
});
}
Il faut maintenant trouver un moyen d'accéder à cette fonction. startServer() {} ajoutez un appel à la fonction comme indiqué :
startServer();Pour vérifier que cela fonctionne, dans votre terminal, exécutez :
Remarque : Si vous êtes connecté à votre Raspberry Pi via SSH ou clavier/tv, dans le Terminal tapez :
ifconfigpour connaître l'adresse IP locale de votre Raspberry Pi.
Accéder à l'adresse IP de votre Raspberry Pi dans votre navigateur : https://<ip address>:3000/ retournera
{"message":"Welcome to your webserver!"} Installation de Sequelize
Sequelize est une puissante bibliothèque pour Node qui facilite l'interrogation d'une base de données. Il s'agit d'un mappeur objet-relationnel (ORM), qui établit une correspondance entre les objets et les schémas de base de données. Sequelize couvre différents protocoles tels que Postgres, MySQL, MariaDB, SQLite et Microsoft SQL Server. Ce tutoriel utilisera le serveur MariaDB car c'est le serveur SQL disponible sur le Raspberry Pi.
Dans le répertoire de votre projet, créez un nouveau fichier .envet mettez à jour les valeurs ci-dessous avec les informations d'identification correctes pour votre base de données.
Dans le répertoire config créer un nouveau fichier appelé config.js. C'est dans ce fichier que sont stockés les paramètres de la base de données du projet, et comme il s'agit de javascript, il peut accéder au fichier .env fichier :
require('dotenv').config();
module.exports = {
development: {
database: process.env.DB_NAME,
username: process.env.DB_USERNAME,
password: process.env.DB_PASSWORD,
host: process.env.DB_HOST,
port: process.env.DB_PORT,
dialect: 'mysql',
operatorsAliases: false
},
}Maintenant dans models/index.js, trouver et remplacer :
- const config = require(__dirname + '/../config/config.json')[env];
+ const config = require(__dirname + '/../config/config.js')[env];De retour dans votre fichier principal index.js importez le fichier models/index.js pour que votre application puisse accéder aux modèles de votre base de données :
const db = require('./models/index'); Générer et exécuter une migration
Lorsqu'une session Vonage Video est créée, un identifiant de session est renvoyé. Cet identifiant de session doit être stocké quelque part pour que vous puissiez vous y connecter à distance. La meilleure façon de le faire est une table de base de données. En utilisant l'interface de commande Sequelize récemment installée, exécutez la commande ci-dessous. Elle crée une nouvelle table appelée Session, avec deux nouvelles colonnes :
sessionId (qui est une chaîne de caractères),
active (qui est un booléen).
Deux nouveaux fichiers sont créés après la réussite de cette commande :
models/session.jsmigrations/<timestamp>-Session.js
Le nouveau modèle, session.jsdéfinit les attentes de la base de données en termes de noms de colonnes, de types de données, etc.
Le nouveau fichier de migration définit ce qui doit être conservé dans la base de données lorsque la migration est réussie. Dans ce cas, il crée une nouvelle table de base de données appelée sessions avec cinq nouvelles colonnes :
id
sessionId
actif
Créé le
updatedAt
Exécutez cette migration à l'aide de la commande CLI Sequelize avec les paramètres suivants db:migrate:
Le résultat sera le même que dans l'exemple ci-dessous :
== 20200504091741-create-session: migrating =======
== 20200504091741-create-session: migrated (0.051s)Vous disposez à présent d'une nouvelle table de base de données que vous utiliserez ultérieurement pour stocker l'identifiant de session.
Vonage Video
Vous êtes sur le point d'installer deux bibliothèques dont le projet a besoin, Vonage Video (anciennement TokBox OpenTok) et Puppeteer.
Vonage Video (anciennement TokBox OpenTok) est un service qui fournit des sessions vidéo interactives en direct à des personnes du monde entier. L'API Video de Vonage (anciennement TokBox OpenTok) utilise la norme industrielle WebRTC. Elle permet aux gens de créer des expériences vidéo personnalisées sur des milliards d'appareils, qu'il s'agisse d'applications mobiles, web ou de bureau.
Puppeteer est une bibliothèque Node qui fournit une méthode pour contrôler Chrome ou Chromium de manière programmatique. Par défaut, Puppeteer s'exécute en mode headless, mais peut également s'exécuter dans un mode non headless de Chrome ou Chromium. Un navigateur headless est un navigateur sans interface utilisateur graphique (par exemple, sans écran visible par l'utilisateur).
Installez ces deux bibliothèques en exécutant la commande ci-dessous :
Copiez les ajouts au code dans votre index.js comme indiqué ci-dessous. Ce code importe trois bibliothèques dans votre projet.
OpenTok (pour publier/s'abonner à un flux vidéo avec Vonage Video)
Puppeteer (Pour que votre Raspberry Pi ouvre un navigateur en mode headless pour publier le flux)
DotEnv (pour accéder aux variables .env)
Un objet OpenTok est initialisé à l'aide de votre clé API Vonage et des variables .env secrètes que vous n'avez pas encore ajoutées.
const gpio = require('onoff').Gpio;
+ const OpenTok = require('opentok');
+ const puppeteer = require('puppeteer');
+ const dotenv = require('dotenv');
const app = express();
const pir = new gpio(23, 'in', 'both');
+ dotenv.config();
+ const opentok = new OpenTok(
+ process.env.VONAGE_VIDEO_API_KEY,
+ process.env.VONAGE_VIDEO_API_SECRET,
+ );Vous aurez besoin de la clé et du secret de l'API Video de Vonage. Vous pouvez les trouver en vous connectant à votre Video API Account de Vonage Video.
Ensuite, créez un nouveau projet. Une fois créé, vous verrez le tableau de bord de votre projet, qui contient la clé et le secret de l'API.
Dans votre fichier .env ajoutez les informations d'identification de Vonage Video comme ci-dessous (en mettant à jour les valeurs à l'intérieur de < et > avec vos informations d'identification) :
Création d'une session Video Vonage
Dans votre fichier index.js trouvez la partie du code qui initialise l'objet OpenTok, et ajoutez trois variables appelées :
canCreateSessiondétermine si votre projet peut créer une session ou non (si une session est déjà active)sessionest la variable qui contient l'objet de la session en coursurlest la variable qui conserve l'URL actuelle de la session (dans ce cas, une URL Ngrok)
const opentok = new OpenTok(
process.env.VONAGE_VIDEO_API_KEY,
process.env.VONAGE_VIDEO_API_SECRET,
);
+ let canCreateSession = true;
+ let session = null;
+ let url = null;Il est temps de créer une session et de stocker l'identifiant de session renvoyé dans la base de données afin de l'utiliser lorsque l'utilisateur clique sur le lien pour afficher le flux publié. Copiez le code ci-dessous pour ajouter les fonctions nécessaires à cet effet :
async function createSession() {
opentok.createSession({ mediaMode: 'routed' }, (error, session) => {
if (error) {
console.log(`Error creating session:${error}`);
return null;
}
createSessionEntry(session.sessionId);
return null;
});
}
function createSessionEntry(newSessionId) {
db.Session
.create({
sessionId: newSessionId,
active: true,
})
.then((sessionRow) => {
session = sessionRow;
return sessionRow.id;
});
}
La partie du projet consacrée à l'observation de la session doit être mise à jour pour déterminer si canCreateSession est vrai ; si c'est le cas, il faut lui donner la valeur false (pour qu'aucun autre flux ne soit créé tant que celui-ci est actif), puis créer la session en appelant la méthode précédemment ajoutée au projet createSession. Pour ce faire, il convient de mettre à jour le code suivant :
pir.watch(function(err, value) {
- if (value == 1) {
+ if (value === 1 && canCreateSession === true) {
+ canCreateSession = false;
console.log('Motion Detected!');
+ createSession();
}
});
Création d'un éditeur et d'un abonné
Un nouveau répertoire est nécessaire pour contenir les pages frontales permettant au Pi de publier son flux et au client (vous) de s'abonner à un flux. Créez un nouveau public avec ses pages d'accompagnement css, js, et config qui l'accompagnent, à l'aide des commandes ci-dessous :
Vous allez avoir besoin d'un certain style pour la page que le client verra, alors créez un nouveau fichier app.css à l'intérieur de public/css/ et copiez le code ci-dessous dans ce fichier. Le CSS ci-dessous garantit que la taille du contenu est de 100 % en hauteur, que la couleur d'arrière-plan est grise et que le flux vidéo est en plein écran pour une visibilité maximale.
body, html {
background-color: gray;
height: 100%;
}
#videos {
position: relative;
width: 100%;
height: 100%;
margin-left: auto;
margin-right: auto;
}
#subscriber {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
z-index: 10;
}
#publisher {
position: absolute;
width: 360px;
height: 240px;
bottom: 10px;
left: 10px;
z-index: 100;
border: 3px solid white;
border-radius: 3px;
}Ensuite, vous devrez créer un nouveau fichier javascript qui sera utilisé du côté du client (donc dans votre navigateur en tant qu'abonné). Ce fichier initialisera une session Vonage Video, obtiendra les détails de la session à partir du backend avec une requête GET et si la route est /serve il publiera le flux si le chemin URL est /client il s'abonne au flux vidéo actif. Dans public/js/ créez un nouveau fichier app.js et copiez-y le code suivant :
let apiKey;
let sessionId;
let token;
let isPublisher = false;
let isSubscriber = false;
let url = '';
// Handling all of our errors here by alerting them
function handleError(error) {
if (error) {
console.log(error.message);
}
}
function initializeSession() {
const session = OT.initSession(apiKey, sessionId);
// Subscribe to a newly created stream
if (isSubscriber === true) {
session.on('streamCreated', (event) => {
session.subscribe(event.stream, 'subscriber', {
insertMode: 'append',
width: '100%',
height: '100%',
}, handleError);
});
}
if (isPublisher === true) {
// Create a publisher
let publisher = OT.initPublisher('publisher', {
insertMode: 'append',
width: '100%',
height: '100%',
}, handleError);
}
// Connect to the session
session.connect(token, (error) => {
// If the connection is successful, publish to the session
if (error) {
handleError(error);
} else if (isPublisher === true) {
session.publish(publisher, handleError);
}
});
}
function setDetails(details) {
apiKey = details.apiKey;
sessionId = details.sessionId;
token = details.token;
initializeSession();
}
async function getDetails(publisher, subscriber, url) {
const request = await fetch(url);
const response = await request.json();
if (publisher === true) {
isPublisher = true;
}
if (subscriber === true) {
isSubscriber = true;
}
setDetails(response);
}
function fetchUrl() {
return fetch('/config/config.txt')
.then( r => r.text() )
.then( t => { url = t} );
}
Deux nouveaux fichiers HTML sont nécessaires pour ces deux nouveaux points d'extrémité /serve et /clientqui utilisent la bibliothèque javascript côté client de Vonage Video pour publier ou s'abonner aux sessions actives en cours.
Créer un nouveau server.html dans le répertoire public/ avec le contenu suivant :
<html>
<head>
<link type="text/css" rel="stylesheet" href="/css/app.css">
<script src="https://static.opentok.com/v2/js/opentok.min.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
</head>
<body>
<h1>Publisher view</h1>
<div id="videos">
<div id="publisher"></div>
</div>
<script type="text/javascript" src="/js/app.js"></script>
<script type="text/javascript">
getDetails(true, false, 'https://localhost:3000/get-details');
</script>
</body>
</html>
Pour le point de terminaison /client créer un nouveau fichier client.html dans le répertoire public/ et copiez le code suivant :
<html>
<head>
<link type="text/css" rel="stylesheet" href="/css/app.css">
<script src="https://static.opentok.com/v2/js/opentok.min.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
</head>
<body>
<h1>Subscriber view</h1>
<div>
<button onclick="getDetails(false, true, url + 'get-details')">Watch Video Stream</button>
</div>
<div id="videos">
<div id="subscriber"></div>
</div>
<script type="text/javascript" src="/js/app.js"></script>
</body>
</html>
Vous n'avez pas encore défini les points de terminaison dans votre code backend (index.js), il est donc temps de les construire ! Trouvez le point d'accès original que vous avez créé :
app.get('/', (req, res) => {
res.json({ message: 'Welcome to your webserver!' });
});
Remplacez-le par le code suivant :
// Adds the public directory to a publicly accessible directory within our new web server
app.use(express.static(path.join(`${__dirname}/public`)));
// Creates a new endpoint `/serve` as a GET request, which provides the contents of `/public/server.html` to the users browser
app.get('/serve', (req, res) => {
res.sendFile(path.join(`${__dirname}/public/server.html`));
});
// Creates a new endpoint `/client` as a GET request, which provides the contents of `/public/client.html` to the users browser
app.get('/client', (req, res) => {
res.sendFile(path.join(`${__dirname}/public/client.html`));
});
// Creates a new endpoint `/get-details` as a GET request, which returns a JSON response containing the active Vonage Video session, the API Key and a generated Token for the client to access the stream with.
app.get('/get-details', (req, res) => {
db.Session.findAll({
limit: 1,
where: {
active: true,
},
order: [['createdAt', 'DESC']],
}).then((entries) => res.json({
sessionId: entries[0].sessionId,
token: opentok.generateToken(entries[0].sessionId),
apiKey: process.env.VONAGE_VIDEO_API_KEY,
}));
});
Si vous regardez attentivement le code ci-dessus, vous utilisez une nouvelle bibliothèque appelée path. Ainsi, au début du fichier index.js inclure le chemin d'accès comme indiqué ci-dessous :
const path = require('path');Rien ne se passe tant que vous ne publiez pas l'affichage sur le Raspberry Pi.
A l'intérieur .env ajoutez une autre variable (60000 millisecondes est l'équivalent de 60 secondes) :
VIDEO_SESSION_DURATION=60000Retour à l'intérieur index.js ajouter une fonctionnalité qui fermera le flux lorsque la fonction closeSession() est appelée :
async function closeSession(currentPage, currentBrowser) {
console.log('Time limit expired. Closing stream');
await currentPage.close();
await currentBrowser.close();
if (session !== null) {
session.update({
active: false
});
}
}Il est maintenant temps de créer la publication du flux en mode "headless". La fonction ci-dessous effectue les opérations suivantes en mode "headless" :
Crée une nouvelle instance de navigateur,
Ouvre une nouvelle page / un nouvel onglet,
Remplace les autorisations pour la caméra et le microphone du navigateur,
Dirige la page vers le point de terminaison
/servepour publier le flux Video,Crée une nouvelle minuterie pour arrêter le flux vidéo après une certaine durée,
Création d'une autre minuterie pour créer un tampon entre la fin du flux et le moment où un autre flux est autorisé à démarrer.
Copiez le code ci-dessous dans votre fichier index.js fichier :
async function startPublish() {
// Create a new browser using puppeteer
const browser = await puppeteer.launch({
headless: true,
executablePath: 'chromium-browser',
ignoreHTTPSErrors: true,
args: [
'--ignore-certificate-errors',
'--use-fake-ui-for-media-stream',
'--no-user-gesture-required',
'--autoplay-policy=no-user-gesture-required',
'--allow-http-screen-capture',
'--enable-experimental-web-platform-features',
'--auto-select-desktop-capture-source=Entire screen',
],
});
// Creates a new page for the browser
const page = await browser.newPage();
const context = browser.defaultBrowserContext();
await context.overridePermissions('https://localhost:3000', ['camera', 'microphone']);
await page.goto('https://localhost:3000/serve');
let sessionDuration = parseInt(process.env.VIDEO_SESSION_DURATION);
let sessionExpiration = sessionDuration + 10000;
// Closes the video session / browser instance when the predetermined time has expired
setTimeout(closeSession, sessionDuration, page, browser);
// Provides a buffer between the previous stream closing and when the next can start if motion is detected
setTimeout(() => { canCreateSession = true; }, sessionExpiration);
}
Il est temps d'utiliser la fonction que vous venez de placer dans votre projet, trouvez et ajoutez startPublish() à votre code :
createSessionEntry(session.sessionId);
+ startPublish();Vous êtes presque arrivé au point où vous pouvez tester votre code ! Vous avez créé de nouveaux points de terminaison, accessibles en tant qu'éditeur ou abonné à la vidéo. Ensuite, vous souhaitez disposer d'une URL permettant d'accéder au flux si vous vous trouvez dans un endroit éloigné.
Ngrok
Si vous souhaitez vous connecter au flux de la caméra à distance, en dehors du réseau, le Raspberry Pi s'est connecté, et vous devrez exposer votre serveur web à l'Internet. Il est temps d'installer et d'utiliser Ngrok.
En exécutant la commande ci-dessous, Ngrok ne sera installé que localement pour le projet :
Vous devez maintenant implémenter l'utilisation de Ngrok dans votre projet. Ainsi, au début du fichier index.js incluez le paquetage ngrok package :
const ngrok = require('ngrok');Vous devez maintenant créer une fonction qui se connecte à Ngrok. En cas de succès, elle enregistrera l'URL renvoyée dans un fichier public/config/config.txt qui sera récupéré dans le fichier créé dans les étapes précédentes public/client.html. Dans votre fichier index.js ajoutez ce qui suit :
async function connectNgrok() {
let url = await ngrok.connect({
proto: 'http',
addr: 'https://localhost:3000',
region: 'eu',
// The below examples are if you have a paid subscription with Ngrok where you can specify which subdomain
//to use and add the location of your configPath. For me, it was gregdev which results in
//https://gregdev.eu.ngrok.io, a reserved subdomain
// subdomain: 'gregdev',
// configPath: '/home/pi/.ngrok2/ngrok.yml',
onStatusChange: (status) => { console.log(`Ngrok Status Update:${status}`); },
onLogEvent: (data) => { console.log(data); },
});
fs.writeFile('public/config/config.txt', url, (err) => {
if (err) throw err;
console.log('The file has been saved!');
});
}
Maintenant que tout cela est configuré, vous pouvez appeler Ngrok en appelant la fonction connectNgrok() comme indiqué ci-dessous :
httpServer.listen(port, (err) => {
if (err) {
return console.log(`Unable to start server: ${err}`);
}
+ connectNgrok();
return true;
});
Vous pouvez maintenant tester votre flux. Exécutez la commande suivante, dans le terminal du Raspberry Pi :
Après environ 10 secondes (le temps que le service s'initialise), agitez votre main devant le capteur de mouvement. En cas de succès, vous verrez un Motion Detected! dans votre fenêtre de terminal. Allez maintenant dans le fichier de votre Raspberry pi public/config/config.txtcopiez cette URL et collez-la dans votre navigateur. Ajoutez /client à la fin de l'URL. Pour moi, c'était https://gregdev.eu.ngrok.io/client. Votre navigateur affiche maintenant le flux publié par votre Raspberry pi, qui a ouvert une instance de navigateur Chromium sans tête et navigué jusqu'à son IP locale : https://localhost/serve.
Installation des messages Vonage
Pour utiliser la nouvelle API Messages de Vonage, qui envoie des SMS dès qu'un mouvement est détecté, vous devez installer la version bêta de notre SDK Node. Exécutez la commande suivante :
npm install @vonage/server-sdkL'API Messages nécessite la création d'une application sur le portail Vonage Developer, et d'un fichier d'accompagnement a private.key qui est généré lors de la création de l'application. L'exécution de la commande ci-dessous crée l'application, définit les webhooks (qui ne sont pas nécessaires pour l'instant, donc laissez-les tels quels), et enfin un fichier clé appelé private.key.
Maintenant que vous avez créé l'application, certaines variables d'environnement doivent être définies. Vous trouverez vos variables API key et API secret sur le tableau de bord du développeur Vonage.
Le VONAGE_APPLICATION_PRIVATE_KEY_PATH est l'emplacement du fichier que vous avez généré dans la commande précédente. Ce projet l'a stocké dans le répertoire du projet, donc par exemple : /home/pi/pi-cam/my_messages_app.key
Le VONAGE_BRAND_NAME n'est pas utilisée dans ce projet, mais vous devez en avoir une pour l'API Messages, je l'ai gardée simple HomeCam
Enfin, le TO_NUMBER est le destinataire qui reçoit la notification par SMS.
Au début de votre fichier index.js importez le paquet Vonage :
const Vonage = require('@vonage/server-sdk');Pour créer l'objet Vonage qui est utilisé pour effectuer les requêtes API, sous la définition de l'objet OpenTok, ajoutez ce qui suit :
const vonage = new Vonage({
apiKey: process.env.VONAGE_API_KEY,
apiSecret: process.env.VONAGE_API_SECRET,
applicationId: process.env.VONAGE_APPLICATION_ID,
privateKey: process.env.VONAGE_APPLICATION_PRIVATE_KEY_PATH,
});À l'intérieur et à la fin de votre fonction connectNgrok() ajoutez une fonctionnalité qui met à jour votre application Vonage avec des webhooks pour gérer les messages entrants et le message-status avec l'URL correcte (l'URL Ngrok) :
vonage.applications.update(process.env.VONAGE_APPLICATION_ID, {
name: process.env.VONAGE_BRAND_NAME,
capabilities: {
messages: {
webhooks: {
inbound_url: {
address: `${url}/webhooks/inbound-message`,
http_method: 'POST',
},
status_url: {
address: `${url}/webhooks/message-status`,
http_method: 'POST',
},
},
},
},
},
(error, result) => {
if (error) {
console.error(error);
} else {
console.log(result);
}
});
Envoi d'un SMS
La méthode de notification choisie pour ce tutoriel est le SMS, envoyé via l'API Messages. La bibliothèque Vonage a déjà été installée dans ce projet, il n'est donc pas nécessaire de la configurer. Dans le fichier index.js ajoutez une nouvelle fonction appelée sendSMS()Cette fonction prend en charge l'URL et le numéro sur lequel vous souhaitez recevoir le SMS. Puis, à l'aide de Messages API, elle envoie une notification par SMS indiquant que la caméra a détecté un mouvement.
function sendSMS() {
const message = {
content: {
type: 'text',
text: `Motion has been detected on your camera, please view the link here: ${url}/client`,
},
};
vonage.channel.send(
{ type: 'sms', number: process.env.TO_NUMBER },
{ type: 'sms', number: process.env.VONAGE_BRAND_NAME },
message,
(err, data) => { console.log(data.message_uuid); },
{ useBasicAuth: true },
);
}
Appelez maintenant la fonction sendSMS() en ajoutant :
createSessionEntry(session.sessionId);
+ sendSMS();Et voilà, c'est fait ! Il ne vous reste plus qu'à vous connecter en SSH à votre Raspberry Pi et à lancer le serveur dans votre répertoire de projet :
Votre serveur est maintenant en marche, et votre Raspberry Pi doit détecter les mouvements, ce qu'il fera ensuite comme suit :
Démarrer une session OpenTok,
Enregistrer l'identifiant de session dans la base de données,
Envoyez un SMS à votre numéro de téléphone prédéterminé avec un lien vers le flux,
Démarrer un flux de publication à partir du Raspberry pi.
Vous venez de vous doter en peu de temps d'un système de surveillance à domicile auquel vous pouvez accéder partout dans le monde !
Le code complet de ce tutoriel est disponible sur le dépôt dépôt GitHub.
Vous trouverez ci-dessous quelques autres tutoriels que nous avons rédigés et qui mettent en œuvre l'API Video de Vonage dans des projets :
Ajouter la fonction de texte à une conversation vidéo avec l'API Video de Vonage
Détection de visages en temps réel en .NET avec OpenTok et OpenCV
N'oubliez pas, si vous avez des questions, des conseils ou des idées à partager avec la communauté, n'hésitez pas à vous rendre sur notre espace de travail Slack de la communauté. Je serais ravi d'entendre les commentaires de tous ceux qui ont mis en œuvre ce tutoriel et de savoir comment leur projet fonctionne.
