Dans ma maison, j’ai eu quelques problèmes avec des coupures de courant. Ces coupures proviennent d’orages qui font sauter le disjoncteur général. Quand je suis à la maison, je remets simplement ce disjoncteur, mais quand je suis en vacances, alors je ne me rends même pas compte. En Septembre dernier, l’intégralité de mon congélateur était à jeter après un défaut de disjoncteur qui est resté inapercu pendant 3 jours.

J’ai donc décidé de mettre en place un système de surveillance qui m’avertis que le courant est coupé. Je me sers de ma connexion d’internet pour surveiller. Le souci est que je ne veux pas ouvrir le firewall de mon routeur ADSL, car je ne veux pas me soucier des potentiels vulnérabilités.

L’astuce est simple : un Raspberry PI – qui se trouve dans ma maison – appelle une page internet toute les minutes. Cette page se trouve sur mon espace internet chez mon hébergeur. La page ne fait que enregistrer l’heure du dernier appel. Une autre page me permet de voir l’état à distance.raspberry_surveillance

Schéma de Fonctionnement

Schéma de Fonctionnement

Au cas où je me rends compte d’un problème, je peux appeler un ami pour aller voir et remettre le disjoncteur.

La Page pour le Protocole

La page ping.php ne fait rien d’autre que stocker la date et l’heure (timestamp) actuel lors de l’appel dans les fichiers last.txt et log.txt. Le fichier last.txt est écrasé à chaque écriture mais le fichier log.txt contient tous les enregistrements depuis le début de l’utilisation de cette page.

Le code PHP pour la page ping.php :

<html>
<body>
</body>
</html>
 
<?php
	$file = 'log.txt';
	$stamp = date('Y-m-d H:i:s', time()) . "\n";
	// Ecrit le contenu dans le fichier, en utilisant le drapeau
	// FILE_APPEND pour rajouter à la suite du fichier 
	file_put_contents($file, $stamp, FILE_APPEND);
 
	$file = 'last.txt';
	$stamp = date('Y-m-d H:i:s', time());
	// Ecrit le contenu dans le fichier, en utilisant le drapeau
	// FILE_APPEND pour rajouter à la suite du fichier 
	file_put_contents($file, $stamp);
?>

Appel de la Page par le Raspberry PI

Le Raspberry PI doit appeler la page ping.php qui se trouve à une adresse de mon serveur qui se trouve chez un grand hébergeur. L’appel peut se faire avec l’exécutable Linux wget. Pour l’exécution périodique, j’utilise l’outil cron qui fait parti de quasiment toutes les distributions Linux.

J’ai suivi les instructions de ce site : https://www.raspberrypi.org/documentation/linux/usage/cron.md

En bref :

  1. Ouvre la configuration de cron avec “sudo crontab -e”
  2. Ajoute la ligne “0 * * * * wget http://monserveur.com/ping.php”
  3. Enregistre le fichier.
  4. Redémarre le Raspberry PI.

La Page de Visualisation à Distance

La visualisation peu se faire simplement en affichant last.txt ou log.txt, mais j’ai préféré de mettre en place une petite page qui me rend la visualisation plus agréable :

Vue de la page status.php

Vue de la page status.php

Le fichier status.php doit se trouver dans le même dossier que ping.php et contenir le code suivant :

<html>
<head>
<style type="text/css">
 body {
	 font-family: "Arial";
	 color: white;
	 background-color: black;
 }
 span.green {
	 color: green;
 }
 span.orange {
	 color: orange;
 }
 span.red {
	 color: red;
 }
</style>
</head>
<body>
<h1>Surveillance &agrave; distance de coupure de courant/internet</h1>
 
<?php
	$file = 'log.txt';
	$stamp = date('Y-m-d H:i:s', time()) . "\n";
	// Ecrit le contenu dans le fichier, en utilisant le drapeau
	// FILE_APPEND pour rajouter à la suite du fichier 
	file_put_contents($file, $stamp, FILE_APPEND);
 
	$file = 'last.txt';
	// Ouvre un fichier pour lire un contenu existant
	$last = file_get_contents($file);
	$stamp = date('Y-m-d H:i:s', time());
	ereg("^([0-9]{4})-([0-9]{2})-([0-9]{2}) ([0-9]{2}):([0-9]{2}):([0-9]{2})$",$last,$regs);
 
	print("<p><b>Dernier ping : </b>".$regs[3]."/".$regs[2]."/".$regs[1]." &agrave; ".$regs[4]."h".$regs[5]." et ".$regs[6]."s</p>");
 
	$year = intval($regs[1]);
	$month = intval($regs[2]);
	$day = intval($regs[3]);
	$hours = intval($regs[4]);
	$minutes = intval($regs[5]);
	$seconds = intval($regs[6]);
 
	$last_time = mktime ($hours,$minutes,$seconds,$month,$day,$year);
	$interval =  time() - $last_time;
	print("<p>Dernier ping il y a ".$interval."s.");
 
	if ($interval <= 60)
	{
		print("<p>Etat : <span class=\"green\">fonctionnel</span></p>");
	}
	else
	{
		if ($interval <= 300)
		{
			print("<p>Etat : <span class=\"orange\">intermittent</span></p>");
		}
		else
		{
			print("<p>Etat : <span class=\"red\">interrompu</span></p>");
		}
	}
?>
 
</body>
</html>

La date et l’heure de la dernière connexion sont affichés en claire. Si le dernier ping a été fait il y a 60s ou moins, l’état “fonctionnel” est écrit. Jusqu’à 5 minutes de manquement l’état “intermittent” est écrit. Au-delà de 5 minutes l’état “interrompu” est écrit.