Le 1-Wire est une technologie qui permet de connecter des composants de type sonde sur un réseau BUS à l’aide de deux fils. Une interface Serie ou USB permet à un PC de communiquer avec ces sondes et de récupérer les données.

J’ai choisi de créer un réseau de sonde de température avec les composants DS18S20B (entre 2 et 3€). Pour plus d’informations sur les composants ou l’interface Serie/1-Wire, vous pouvez consulter ce site très bien documenté : http://martybugs.net/electronics/tempsensor/.

L’avantage est de pouvoir par la suite créer des graphiques pour chaque sonde. Le résultat final est le suivant :

Tout le système est basé sur un environnement Debian Linux.

Dans un premier temps, testez la communication avec vos sondes à l’aide de l’outil Digitemp.

/usr/bin/digitemp_DS9097U -s/dev/ttyS0 -a %C

Le résultat doit ressembler à ça :

DigiTemp v3.5.0 Copyright 1996-2007 by Brian C. Lane
GNU Public License v2.0 - http://www.digitemp.com
Jul 16 15:44:35 Sensor 0 C: 29.38 F: 84.88
Jul 16 15:44:36 Sensor 1 C: 24.44 F: 75.99

Si tout est bon, alors on peut passer au script qui va automatiser l’enregistrement des données dans une base RDD et va générer nos graphiques.

Le script a été écrit en Perl par Martin Pot en 2006, je l’ai légèrement modifié pour enregistrer les valeurs actuelles de chaque sonde dans un fichier texte afin de récupérer la température sur l’interface de contrôle iPhone.

#!/usr/bin/perl
#
# copyright Martin Pot 2006
# http://martybugs.net/electronics/tempsensor/
# thanks to Petr for suggestions relating to better handling of failed data reads
# rrd_tempsensor.pl
 
#use lib qw(/usr/local/rrdtool-1.2.12/lib/perl);
use RRDs;
 
# define location of rrdtool databases
my $rrd = '/usr/local/rrdtool';
# define destination of images
my $img = '/var/www/maison/script/temperature/';
 
# process data for each interface (add/delete as required)
&ProcessSensor(0, "server room");
&ProcessSensor(1, "temp sensor 1");
#&ProcessSensor(2, "temp sensor 2");
 
sub ProcessSensor
{
# process sensor
# inputs: $_[0]: sensor number (ie, 0/1/2/etc)
#	  $_[1]: sensor description
 
	# get temperature from sensor
	my $temp = `/usr/bin/digitemp_DS9097U -s/dev/ttyS0 -t $_[0] -q -o"%.2C"`;
 
	# remove eol chars
	chomp($temp);
 
	# ecriture du dernier resultat dans un fichier txt
	open (FH, ">/var/www/maison/script/temperature/temp$_[0].txt");
	print FH $temp;
	close (FH);
 
	print "sensor $_[0]: $temp degrees C\n";
 
	# if rrdtool database doesn't exist, create it
	if (! -e "$rrd/temp$_[0].rrd")
	{
		print "creating rrd database for temp sensor $_[0]...\n";
		RRDs::create "$rrd/temp$_[0].rrd",
			"-s 300",
			"DS:temp:GAUGE:600:U:U",
			"RRA:AVERAGE:0.5:1:2016",
			"RRA:MIN:0.5:1:2016",
			"RRA:MAX:0.5:1:2016",
			"RRA:AVERAGE:0.5:6:1344",
			"RRA:MIN:0.5:6:1344",
			"RRA:MAX:0.5:6:1344",
			"RRA:AVERAGE:0.5:24:2190",
			"RRA:MIN:0.5:24:2190",
			"RRA:MAX:0.5:24:2190",
			"RRA:AVERAGE:0.5:144:3650",
			"RRA:MIN:0.5:144:3650",
			"RRA:MAX:0.5:144:3650";
	}
	if ($ERROR = RRDs::error) { print "$0: failed to create $_[0] database file: $ERROR\n"; }
 
	# check for error code from temp sensor
	if (int $temp eq 85)
	{
		print "failed to read value from sensor $_[0]\n";
		$temp = "U";
	}
 
	# insert values into rrd
	RRDs::update "$rrd/temp$_[0].rrd",
		"-t", "temp",
		"N:$temp";
	if ($ERROR = RRDs::error) { print "$0: failed to insert $_[0] data into rrd: $ERROR\n"; }
 
	# create graphs for current sensor
	&CreateGraph($_[0], "day", $_[1]);
	&CreateGraph($_[0], "week", $_[1]);
	&CreateGraph($_[0], "month", $_[1]);
	&CreateGraph($_[0], "year", $_[1]);
}
 
sub CreateGraph
{
# creates graph
# inputs: $_[0]: sensor number (ie, 0/1/2/etc)
#	  $_[1]: interval (ie, day, week, month, year)
#	  $_[2]: sensor description
 
	RRDs::graph "$img/temp$_[0]-$_[1].png",
		"-s -1$_[1]",
		"-t $_[2] (Sonde n° $_[0]) :: last $_[1]",
		"--lazy",
		"-h", "120", "-w", "600",
		"-a", "PNG",
		"-v degrees C",
		"--slope-mode",
		"DEF:temp=$rrd/temp$_[0].rrd:temp:AVERAGE",
		"DEF:min=$rrd/temp$_[0].rrd:temp:MIN",
		"DEF:max=$rrd/temp$_[0].rrd:temp:MAX",
		"LINE1:min#FF3333",
		"LINE1:max#66FF33",
		"LINE2:temp#0000FF:temp sonde $_[0]\\:",
		"GPRINT:temp:MAX:    Max\\: %6.1lf",
		"GPRINT:temp:AVERAGE: Moy\\: %6.1lf",
		"GPRINT:temp:LAST: Actuelle\\: %6.1lf degrees C\\n";
	if ($ERROR = RRDs::error) { print "$0: unable to generate sensor $_[0] $_[1] graph: $ERROR\n"; }
}

Sur votre serveur Linux, copiez ce script dans un fichier « .pl ». N’oubliez pas d’adapter les Paths à votre configuration. Pour la suite, définissez ce script comme exécutable (chmod).

La deuxième étape est de créer un Cron qui va exécuter ce script toutes les 5 minutes.

Dans un shell, taper la commande « crontab e » et copier cette ligne en adaptant l’emplacement de votre script perl.
*/5 * * * * /usr/local/rrdtool/rrd_tempsensor.pl > /dev/null 2>&1
Redémarrez le service cron et vérifiez que les graphiques sont bien générés dans le répertoire que vous avez indiqué (dans mon cas /var/www/maison/script/temperature/).

Si tout est bon, alors voici un petit script PHP qui affiche les graphiques de chaque sonde pour la journée, la semaine, le mois ou l’année.

$time=$_GET['time'];
if($time=='')
        $time="day";
 
echo "";
echo "Affichage :  <a href="?page=time=day">Jour</a>  /  <a href="?page=time=week">Semaine</a>  / <a href="?page=time=month">Mois</a>  /  <a href="?time=year">AnneAnnee</a>";
echo "
";
 
switch ($time) {
    case day:
        echo "Temperature de la journee";
        break;
    case week:
        echo "Temperature de la semaine";
        break;
    case month:
        echo "Temperature du mois";
        break;
    case year:
        echo "Temperature de l'annee";
        break;
}
 
echo "Sonde 0 :";
echo "<img src="script/temperature/temp0-&quot;.$time.&quot;.png" alt="" />";
 
echo "Sonde 1 :";
echo "<img src="script/temperature/temp1-&quot;.$time.&quot;.png" alt="" />";

Conclusion

Je ne m’attarde pas trop sur cette méthode puisque j’ai récemment découvert le protocole XPL qui permet d’envoyer des messages types, indépendants de la source d’acquisition. L’objectif pour moi est de générer des graphiques de température provenant de sonde en 1-Wire et en RFXCOM.

Sur demande, je peux détailler davantage ce sujet.

Les Scripts peuvent être téléchargés ici