Category Archives: 1-wire

Le One Wire est une technologie conçue par Dallas, très utile en domotique car les informations ne circulent que sur une paire de câble.

Suvi de la consommation d’eau avec des compteurs à impulsions sur un bus 1-wire

Contexte

Si vous avez suivi les posts précédents, vous savez peut-être que j’ai aménagé dans une maison neuve, et la construction a ses avantages, comme le fait de penser à installer des compteurs à impulsion par le sanitaire, puis une prise réseau à proximité par l’electricien, ainsi je me retrouve avec ça :

Compteur à impulsion en attente

Compteur à impulsion en attente

Le but étant de suivre la consomation d’eau chaude et d’eau froide.
Le compteur pour l’eau froide est placé avant la nourrice et après l’alimentation du CESI.
Le compteur pour l’eau chaude est placé à la sortie du CESI.
CQFD : inutile dans mon cas de déduire l’eau froide sur l’eau chaude.

Principe

Je vais utiliser un Raspberry Pi et utilise le bus 1-wire pour le comptage des impulsions.
En 1-wire, j’utilise l’interface DS1490 (USB/1-wire) que j’ai acqueri lors des mes découvertes du 1-wire ; car sauf erreur ma part, l’utilisation du 1-wire par les pins du Raspberry Pi ne permettent pas d’exploitrer un DS2423.
Un DS2423 est un double compteur avec mémoire.
Plus tard, je profiterai d’avoir un bus 1-wire pour mettre des sondes de températures DS18B20 à coller aux tuyaux du chauffage qui passent à coté.

Le raspberry est alimenté par le réseau, de plus, ayant besoin d’une alimentation 5 volts pour les composants 1-wire, je ne la prends pas du USB, mais du PoE passif grâce à un simple splitter.

Un schéma de principe :

compteur-impulsion-raspberry-principe

Schéma de principe

 

Dans l’ordre :

  • Les compteurs d’eau génère une impulsion à chaque littre qui passe.
  • Le DS2423 compte chaque impulsion de chaque compteur.
  • Le raspberry consulte le compteur du DS2423.
  • Le raspberry envoi le chiffre obtenu dans une table MySQL sur un serveur.
  • Une page web traire ces chiffres de la table pour générer des graphiques.
  • Je peux me faire la morale parce que mes douches sont trop longues.

Go ?!

Montage du DS2423 pour compter des impulsions

Pour commencer, le DS2423 n’est plus produit, il est en fin de vie.
On peut encore s’en procurer chez hobby-boards.com à 10.50 $ / pièce, auquel on rajoute 10,55 $ de frais de port ! Ce n’est pas rien !

Voici comment j’utilise le DS2423 :

ds2423 schéma

ds2423 : schéma

Il faut donc fournir un bus 1-wire composé d’un « DATA » et d’une masse. Il faut également fournir une alimentation 5V qui a une masse commune avec le bus 1-wire.
Pour l’alimentation, je vais m’inspirer de mon injecteur 5 Volts → 1Wire, sauf que je vais l’inclure dans un seul et même boitier.

 

Schéma injecteur 1-wire

Schéma injecteur 1-wire

+

ds2423 schéma

ds2423 schéma

=

ds2423 avec alimentation

ds2423 avec alimentation

Je me laisse la possibilité de repiquer le bus 1-wire et une alimentation (à droite du schéma) pour ajouter un autre DS2423 dans le but de compter un 3ième compteur à impulsion, voir un 4ième ou un pluviomètre qui se comporte de la même façon qu’un compteur d’eau à impulsion.

Réalisation et mise en place

Est-ce que la théorie rejoint la pratique ?
Je suis parti sur une « prototype board », des borniers, le tout placé dans une prise RJ45 en saillie.
L’avantage d’une prise RJ45 en saillie, c’est quelle permet de planquer le PCB, le tout se  fixe proprement au mur. De plus, j’y connecte à travers le RJ45, un câble RJ11 du DS9490R.
Place aux photos.

Comme on peut le voir, il y a deux DS2423 sur ce montage, c’est en prévision d’un 3ième compteur à impulsion pour un pluviomètre.
Pour ne pas compliquer la chose, on va faire comme si ce deuxième DS2423 n’existe pas.
Sur la dernière photo, on voit clairement les deux compteurs à impulsion raccordés au montage.
La LED permet de vérifier que le circuit est bien alimenté.
Le 5 Volts, provient de l’USB du Raspberry Pi, mais il est préférable de le sortir d’une alimentation sans rapport aux Raspberry Pi, ce qui a été fait entre temps, j’ai utilisé un splitter DC 3,5mm pour alimenter le montage ; le 5V provient du PoE passif.

Récupération des valeurs des compteurs

C’est partie pour une installation de Raspbian sur le Raspberry Pi.
Mes quelques commandes de bases sur le Raspberry :

# sudo passwd
# su
# apt-get update
# apt-get dist-upgrade
# apt-get install htop vim screen usbutils

Puis les choses sérieuses commecent, on branche le dongle DS1490 :

# lsusb
Bus 001 Device 002: ID 0424:9514 Standard Microsystems Corp.
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 003: ID 0424:ec00 Standard Microsystems Corp.
Bus 001 Device 004: ID 04fa:2490 Dallas Semiconductor DS1490F 2-in-1 Fob, 1-Wire adapter

On installe owserver, owfs-fuse et surtout owhttps qui permettra de visualiser facilement l’état des compteurs le temps de scripter tout ça.

# apt-get install owserver owfs owhttpd

Puis on modifie le fichier /etc/owfs.conf :
On commente la ligne 16 et décommente la ligne 19.

# vi /etc/owfs.conf
# ...and owserver uses the real hardware, by default fake devices
# This part must be changed on real installation
#server: FAKE = DS18S20,DS2405
#
# USB device: DS9490
server: usb = all
#
# Serial port: DS9097
#server: device = /dev/ttyS1
#
# owserver tcp address
#server: server = 192.168.10.1:3131

Puis on redemarre owserver

# /etc/init.d/owserver restart
[ ok ] Restarting 1-Wire TCP Server: owserver.

Direction le navigateur pour consulter owhttp : http://adresseipduraspberry:2121
Owhttp devrait lister une sonde DS2423 commençant par 1D. 

DS2423 sur OWHTTPD

DS2423 sur OWHTTPD

Ohhhh ! counters.A correspond à mon compteur d’eau froide ; counters.B à mon compteur d’eau chaude.
Après un petit test au verre mesureur, 1 litre d’eau = 1 impulsion. Autrement, la valeur d’une impulsion est généralement marquée sur le compteur, ce n’est pas le cas pour ma part.

Bon, c’est en bonne voie, il reste maintenant à scripter tout ça afin d’alimenter une base de données MySQL sur un serveur distant.
A noter qu’on peut également ecrire les relevé des compteurs sur une base MySQL en local sur le Raspberry ; dans mon cas j’utilise un serveur distant pour d’autres applications lié à la domotique et donc je centralise toutes les données sur une même machine.

Pour insérer les valeurs des compteurs, je m’inspire d’un des mes tuto : Insérer les valeurs 1-wire dans une base MySQL.

Coté serveur MySQL (local/distant, à adapter selon votre convenance)

Nécéssite apache2, php5 et mysql-server  : apt-get install apache2 mysql-server php5
Je crée une base et les deux tables, comme dans mon article, à l’exception de la table 1wire_sensor qui est modifiée pour prendre en compteur les compteurs.
Ce qui donne :

# mysql -p
create database 1wire;
use 1wire;
CREATE TABLE IF NOT EXISTS `1wire_sensor` (
`1wire_sensor_id` int(3) NOT NULL AUTO_INCREMENT,
`1wire_sensor_enable` enum('true','false') NOT NULL,
`1wire_sensor_type` enum('temperature','presence','sensed.A','counters.A','counters.B') NOT NULL,
`1wire_sensor_family` tinytext NOT NULL,
`1wire_sensor_idaddress` tinytext NOT NULL,
`1wire_sensor_comment` text NOT NULL,
PRIMARY KEY (`1wire_sensor_id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
CREATE TABLE IF NOT EXISTS `1wire_data` (
`1wire_data_id` int(11) NOT NULL AUTO_INCREMENT,
`1wire_data_sensor_id` int(3) NOT NULL,
`1wire_data_timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`1wire_data_value` text NOT NULL,
PRIMARY KEY (`1wire_data_id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
GRANT ALL PRIVILEGES ON 1wire.* TO '1wire'@'%' IDENTIFIED BY '1wire';

En détail, j’ai ajouté counters.A et counters.B dans le champs 1wire_sensor_type.
Ceci afin de m’adapter aux DS2423 ; counters.A et counters.B sont les noms exact des champs a récupérer.
Faut penser à permettre à notre serveur MySQL d’autoriser les connexions distantes et commenter la ligne bind-address.

# vi /etc/mysql/my.cnf
#
# Instead of skip-networking the default is now to listen only on
# localhost which is more compatible and is not less secure.
# bind-address = 127.0.0.1
#
# /etc/init.d/mysql restart

Et voila, la partie serveur se termine là pour l’instant, nous y reviendrons pour créer un graphique avec la consomation d’eau.

Pour résumer :
Host : 192.168.1.100
Database MySQL : 1wire
User MySQL : 1wire
Password MySQL : 1wire

Coté RaspberryPi

Là encore, je m’inspire de mon article de l’époque, cependant mon fichier PHP ne traite que les sondes de témpérature et de présence, quelques adaptations sont nécessaires pour explorer un DS2423 :

# cd /root/
# wget https://www.domolio.fr/wp-content/uploads/2012/05/1-wire-mysql.tgz
# tar zxvf 1-wire-mysql.tgz
# cd 1-wire/

J’apporte de suite les informations nécessaires pour la connexion au serveur :

# vi require/main.inc.php

A noter que je travail dans /root/1-wire .

<?php

// -- BASE --

$DEBUG = true;
$DEBUG_TXCOLOR = "#fff";
$DEBUG_BGCOLOR = "#000";
$PATH = "/root/1-wire";

// --

define("DEBUG", $DEBUG);
define("DEBUG_TXCOLOR", $DEBUG_TXCOLOR);
define("DEBUG_BGCOLOR", $DEBUG_BGCOLOR);
define("PATH", $PATH);

// ----
// -- MYSQL --

// Préfixe de toutes les tables du site
$MYSQLHOST = "192.168.1.100";
$MYSQLLOGIN = "1wire";
$MYSQLPWD = "1wire";
$MYSQLBASE = "1wire";

//--

Ah oui, il faut php et php5-mysql

# apt-get install php5-cli php5-mysql mysql-client

Et je créer mon script qui récupère les valeurs des sondes :

# vi /usr/local/bin/1wire-fetch.php

Puis je copie/colle le script de mon article précédent, modifié pour permettre l’intérogation de sondes DS2423 :

#!/usr/bin/php
<?php
$pathconfig = "/root/1-wire";
require_once($pathconfig."/require/main.inc.php");
require_once(PATH."/require/database.inc.php");
require_once(PATH."/require/function-1wire.inc.php");

// Recup des données des sondes depuis la BDD
$req_sensor = "SELECT * FROM 1wire_sensor WHERE 1wire_sensor_enable IS TRUE";
$qur_sensor = mysql_query($req_sensor);
while($dat_sensor = mysql_fetch_array($qur_sensor)) {
 // Pour chaque sonde on constitue son adresse :
 $onewire_address = $dat_sensor['1wire_sensor_family'].".".$dat_sensor['1wire_sensor_idaddress'];
 // On teste sa présence sur le bus
 if(onewire_presence($onewire_address)) {
 debug("OUI ! ".$onewire_address." est présent sur le bus","cli");
 if ($dat_sensor['1wire_sensor_type'] == "presence") {
 debug("Seul sa presence sur le bus est nécessaire","cli");
 // on ecris dans la BDD qu'il est présent et on s'arrete là
 $value = 1;
 }
 elseif ($dat_sensor['1wire_sensor_type'] == "temperature" || $dat_sensor['1wire_sensor_type'] == "sensed.A" || $dat_sensor['1wire_sensor_type'] == "counters.A" || $dat_sensor['1wire_sensor_type'] == "counters.B" ) {
 // on récupère sa valeur, que ca soit la température ou l'état du PIO (DS2406) ou le compteur (DS2423).
 $value = onewire_read($onewire_address,$dat_sensor['1wire_sensor_type']);
 }
 }
 else {
 // Composant absent du bus
 debug ("NON ! ".$onewire_address." n'est pas présent sur le bus","cli");
 $value = 0;
 }

 // on écris le resultat dans la BDD
 $req_insdata = "INSERT INTO 1wire_data SET
 1wire_data_sensor_id = ".$dat_sensor['1wire_sensor_id'].",
 1wire_data_value = '".$value."'";
 mysql_query($req_insdata) or die ("Erreur à l'insertion des données 1-wire : ".mysql_error());
}
mysql_close();
?>
# chmod +x /usr/local/bin/1wire-fetch.php

Puis on fait un break ! Une petite explication s’impose !
Le script 1wire-fetch.php sera appelé par le cron pour remplir une base de donnée sur un serveur distant.
Ce script fait appel à des fichiers stockés dans /root/1-wire/require/ ; ces fichiers sont des « functions » que j’ai pondu il y a quelque temps en utilisant une libraire fournis par l’équipe qui développe 1wire sur linux (owfs.org).
La libraire maitresse, qui permet d’intéroger des sondes par PHP, s’appel libownet-php et fournis un fichier miraculeux qui se nomme ownet.php.

Pour aller plus loin, consulter mon article : Interroger les sondes 1-wire par un script PHP.

Le fichier ownet.php fourni par le paquet libownet-php est buggé, dans l’état, il ne permet pas d’exploiter les DS2423, de plus, c’est ce même paquet que j’ai intégré dans l’archive que vous avez décompressé tout à l’heure.
Mais c’est pas grave, on va débugger ça ensemble.

Pour commencer, adios le fichier ownet.php de mon archive, on va reprendre la version packagé par Debian.

# apt-get install libownet-php
# cd /root/1-wire/require/
# cp /usr/share/php/OWNet/ownet.php .

Puis deux corrections sont nécessaire :

# vi ownet.php

Ligne 516 :

if (bccmp($ret['data_php'],0,0)==-1){

Devient,

if (bccomp($ret['data_php'],0,0)==-1){

Ligne 484 :

$ret['data']    =substr($data,0,$data_len);     // data_php length is the same as $ret[2]

Devient,

$ret['data']    =trim(substr($data,0,$data_len));     // data_php length is the same as $ret[2]

Le premier bug bccmp/bccomp est assez connu, traine depuis très longtemps.
Le second bug est propre au DS2423, j’ai trouvé un seul appel à l’aide sur internet, datant de mars 2010 :
Cannot acces counters DS2423 with ownet.php
C’est donc bien lié aux espaces qui trainent devant la valeur du compteur, chose corrigé avec la fonction php trim().

Ou plus simplement, télécharger directement ma version du fichier ownet.php corrigée :

# cd /root/1-wire/require/
# wget "https://domolio.fr/wp-content/uploads/2015/01/ownet.php.txt" -O ownet.php

Voila, notre break/débug est terminé, pour résumer step by step :

  1. Le cron lance le script /usr/local/bin/1wire-fetch.php
  2. Ce script utilise les fichiers stocké dans /root/1-wire pour se connecter au serveur MySQL distant et au bus 1-wire
  3. Le script consulte la table MySQL 1wire_sensor pour lister les sondes à intéroger sur le bus
  4. Ce même script consulte chaque sonde en verifiant sa présence sur le bus 1-wire et récupère la valeur souhaitée.
  5. Toujours ce script, ajoute les valeurs récupérées dans la table MySQL 1wire_data du serveur distant.
  6. Le script est terminé, il recommencera dans une heure.
  7. Une page web sur notre serveur distant, intéroge les valeurs dans les différentes tables MySQL pour afficher de beaux graphiques.

Ainsi nous allons maintenant alimenter la table 1wire_sensor avec les sondes à intéroger.
Et comme je suis sûr de moi, je le fais depuis mon client, selon les informations MySQL que je me suis mis de coté :

# mysql -h192.168.1.100 -u1wire -p1wire 1wire
INSERT INTO 1wire_sensor SET 1wire_sensor_enable='true', 1wire_sensor_type='counters.A', 1wire_sensor_family='1D', 1wire_sensor_idaddress='641710000000', 1wire_sensor_comment='eau froide';
INSERT INTO 1wire_sensor SET 1wire_sensor_enable='true', 1wire_sensor_type='counters.B', 1wire_sensor_family='1D', 1wire_sensor_idaddress='641710000000', 1wire_sensor_comment='eau chaude';

Pour rappel :
1wire_sensor_family=’1D’ : 1D correspond à la famille des DS2423.
1wire_sensor_idaddress=’641710000000′ : 641710000000 correspond à l’ID de ce DS2423 tel que owhttp me l’a indiqué tout à l’heure.

Il ne reste plus qu’à tester :

# php /usr/local/bin/1wire-fetch.php
[function] onewire_presence pour : 1D.641710000000
OUI ! 1D.641710000000 est présent sur le bus
[function] onewire_read pour : 1D.641710000000 et le type counters.A
La variable value est vide pour le mode counters.A, on recommence (1 fois est normal)
Valeur brute trouvée :972
[result] Donnée trouvée pour /1D.641710000000/counters.A : 972
[function] onewire_presence pour : 1D.641710000000
OUI ! 1D.641710000000 est présent sur le bus
[function] onewire_read pour : 1D.641710000000 et le type counters.B
La variable value est vide pour le mode counters.B, on recommence (1 fois est normal)
Valeur brute trouvée :638
[result] Donnée trouvée pour /1D.641710000000/counters.B : 638

Oh 🙂
Grâce à la première ligne du script ( #!/usr/bin/php ) on peut même directement lancer 1wire-fetch.php :

# 1wire-fetch.php
[function] onewire_presence pour : 1D.641710000000
OUI ! 1D.641710000000 est présent sur le bus
[function] onewire_read pour : 1D.641710000000 et le type counters.A
La variable value est vide pour le mode counters.A, on recommence (1 fois est normal)
Valeur brute trouvée :975
[result] Donnée trouvée pour /1D.641710000000/counters.A : 975
[function] onewire_presence pour : 1D.641710000000
OUI ! 1D.641710000000 est présent sur le bus
[function] onewire_read pour : 1D.641710000000 et le type counters.B
La variable value est vide pour le mode counters.B, on recommence (1 fois est normal)
Valeur brute trouvée :638
[result] Donnée trouvée pour /1D.641710000000/counters.B : 638

Au passage, une petite chasse d’eau + lavage de main aura utilisé 3 litres.
Coté mysql, je devrais avoir toutes les données :

select * from 1wire_data;
+---------------+----------------------+----------------------+------------------+
| 1wire_data_id | 1wire_data_sensor_id | 1wire_data_timestamp | 1wire_data_value |
+---------------+----------------------+----------------------+------------------+
|             1 |                    1 | 2015-01-13 00:37:06  | 975              |
|             2 |                    2 | 2015-01-13 00:37:06  | 638              |
+---------------+----------------------+----------------------+------------------+
2 rows in set (0.00 sec)

C’est le cas !

Je mets en place le cron pour une execution toutes les heures :

# vi /etc/cron.d/crononewire
# Récup des valuers 1-wire tout les 1h et 5 minutes
5 * * * * root /usr/local/bin/1wire-fetch.php

Donc le script se lancera à 13h05, 14h05, 15h05, etc…

Visualisation des données

Le temps passe, la table MySQL se remplit, place aux graphiques !
J’utilise Highcharts et plus précisement sur Highstock qui a l’avantage d’avoir une échelle du temps.
On part du principe que sur la machine qui herberge la partie web pour les graphiques dispose des outils nécessaire : apache2, php-mysql, php5, etc..
Bien entendu, cette partie peut également se situer sur le raspberry, tout comme les données MySQL.

# cd /var/www
# wget https://www.domolio.fr/wp-content/uploads/2015/10/graph-eau.tar.gz
# tar zxvf graph-eau.tar.gz
# cd eau

Le graphique se scinde en deux parties :
– data.php qui récupère les valeurs dans la base de donnéess et qui met en forme au format json.
– index.php et son répertoire « js » qui traite les données et crée les graphiques.

# vi data.php
<php 
header('Cache-Control: no-cache, must-revalidate');
header('Content-type: text/javascript');

$mysql_host = "127.0.0.1";
$mysql_db = "1wire";
$mysql_user = "1wire";
$mysql_pwd = "1wire";

$id_eau_froide = 1;
$id_eau_chaude = 2;

Mon eau froide correspond à l’id « 1wire_data_sensor_id » n°1 dans la table 1wire_data qui correspond à COUNTERS.A de mon DS2423.
L’eau chaude à l’id n°2 -> COUNTERS.B.

Dans le fichier index.php, une seule modification est importante :

$pointStart = "Date.UTC(2015, 0, 13, 0, 0, 0)"
...
$pointStart =  "Date.UTC(2015, 0, 13)";
...
$pointStart =  "Date.UTC(2015, 0)";

« 2015, 0, 13, 0, 0, 0 » correspond à mon tout premier relevé de compteurs :
Le 13 janvier 2015 à 01h soit 00h GMT.

Ici, HighStock travail en intervalle avec les données json reçues par le fichier data.php
On récupère la valeur des compteurs toutes les heures, donc l’intervalle entre deux points pointInterval pour le format :
– Journalier : 3600000 millisecondes (3600 x 1000).
– Hebdomadaire : 3600 x 1000 x 24 x 7.
– Mensuel : 3600 x 1000 x 24 x 31.

Là est le petit faux dans ce script, tous les mois ne font pas 31 jours…
Ça implique un petit décalage visuel de mois en mois.
A corriger à l’occasion…

Voila le résultat :

consomation eau hebdomadaire

consomation eau hebdomadaire

consomation d'eau heure par heure

consomation d’eau heure par heure

consomation d'eau par mois

consomation d’eau par mois

Demo

Une demo figée au 11/10/2015 ici :

http://www.chocolio.com/demo-eau/

Et voila ! Très content de mes compteurs et de mon suivi !
La prochaine étape pour moi, sera d’ajouter un pluviomètre sur le dernier compteur du DS2423, et cela afin d’actionner ou pas un arrosage automatique.

Posté dans 1-wire, Debian, graphs, php, Raspberry Pi, Web | 6 Commentaires

Monitorer la temperature avec un Raspberry Pi, vite fait bien fait

L’hiver arrive, dans la nouvelle maison je souhaite surveiller la température temporairement pièce par pièce pour mesurer l’impact du chauffage.
Pour cela, je m’aide d’un Raspberry Pi en WIFI et d’une sonde 1-wire DS18B20.

Je ne vais pas réinventer le fil à couper le beurre, le schéma de câblage d’un DS18B20 est le même sur tous les blogs :

DS18B20 sur raspberry pi

DS18B20 sur raspberry pi

 

Ce qui donne une fois soudé :

Magnifique tapis de souris

Magnifique tapis de souris

Vite fait bien fait on a dit

Vite fait bien fait on a dit

Avec des pins !

Avec des pins ! Luxe !

J’utilise une résistance de 4.2kΩ qui fait très bien l’affaire.

Coté Raspberry Pi, après la configuration du WIFI, place à la configuration du 1-wire.

# vi /etc/modules
w1-therm
w1-gpio pullup=1
snd-bcm2835

Pour une action immédiate :

# modprobe w1-therm
# modprobe w1-gpio pullup=1

Puis allons voir ce qu’il se passe  du coté du bus 1-wire :

# cd /sys/bus/w1/devices
# ls -l
total 0
lrwxrwxrwx 1 root root 0 nov. 18 00:05 28-000003977b0a -&gt; ../../../devices/w1_bus_master1/28-000003977b0a
lrwxrwxrwx 1 root root 0 nov. 17 22:45 w1_bus_master1 -&gt; ../../../devices/w1_bus_master1

Ah ! 28 machins, ça me rappelle des souvenirs.

# cd 28-000003977b0a
# cat w1_slave
63 01 4b 46 7f ff 0d 10 15 : crc=15 YES
63 01 4b 46 7f ff 0d 10 15 t=22187

Bon, on devine que 22187 correspond à 22,187°C.
Autrement on peut utiliser cette commande :

# find /sys/bus/w1/devices/ -name "28-*" -exec cat {}/w1_slave \; | grep "t=" | awk -F "t=" '{print $2/1000}'
22.187

Voila voila…

Reste à grapher périodiquement cette valeur.
Vite fait, bien fait, j’aime grapher avec munin et j’ai vite trouvé un script simple et efficace :
https://gist.github.com/kminiatures/4f3…

Ah bah !?! Go !

# apt-get install -y munin-node bc
# cd /etc/munin/plugins/

Personnellement, je souhaite juste ma temperature, donc je supprime tous les plugins et crée le nouveau plugin :

# rm *
# vi 1w-temp

Pour y insérer ceci (selon https://gist.github.com/kminiatures/4f3… )

#!/bin/sh

case $1 in
   config)
        cat <<'EOM'
graph_title Temperature
graph_vlabel Temperature
temperature.label temperature
EOM
        exit 0;;
esac

printf "temperature.value "
TEMP=`cat /sys/bus/w1/devices/*/w1_slave | grep t= | sed s/.*t=//`
echo "scale=2; $TEMP / 1000" | bc

Puis on teste tout de suite notre plugin :

# chmod +x 1w-temp
# munin-run 1w-temp
temperature.value 22.25

Bientôt la fin… J’ajoute un « allow * » au fichier /etc/munin/munin-node.conf
Puis /etc/init.d/munin-node restart

Mettons un serveur munin/apache2 en place :

# apt-get install munin apache2
# vi /etc/apache2/conf.d/munin

Puis remplaçer toutes les occurences de Allow from localhost 127.0.0.0/8 ::1 par Allow from all .
On redémarre apache2 :

# /etc/init.d/apache2 restart

Vous pouvez également modifier le fichier /etc/munin/munin.conf pour modifier le nom de votre serveur.

Evidemment, si vous avez un autre serveur munin (mon cas), inutile d’installer un serveur munin sur votre Raspberry, il vaut mieux décharger cette tâche à une autre machine plus apte à ce genre de service.
Au bout de quelques heures ou quelques jours, vous devriez voir ce genre de graphique :

DS18b20 dans munin

DS18b20 dans munin

DS18b20 zoomé dans munin

DS18b20 zoomé dans munin

Bon, vite fait, maintenant qu’on a un apache2 sur le raspberry, une petite page PHP pour connaitre la température actuelle de la sonde.
On peut aussi lire la valeur « Cur: » sur les graphs munin, mais mes petits yeux veulent quelque chose de plus grand, surtout depuis le téléphone.

# apt-get install php5
# cd /var/www/
# vi index.php
<meta name="viewport" content="width=device-width, user-scalable=no">
<center><span style="font-size:65px;">
<?php
// Fichier à lire
$file = "/sys/bus/w1/devices/28-000003977b0a/w1_slave";

// Lecture ligne par ligne
$lines = file($file);

// Recupere la 2nd ligne
$temp = explode('=', $lines[1]);

// Formatage de la temperature
$temp = number_format($temp[1]/1000,2, '.', '');

// On affiche la temperature
echo $temp;
?>
</center></span>

28-000003977b0a correspond à l’ID de ma sonde DS18B20.

Ce qui donne sur smartphone :

page web DS18b20

page web DS18b20

Voila, un article vite fait bien fait, pour surveiller une température.
Cela va me permettre dans un premier temps de calibrer mon Z41.
Puis ça me permettra d’analyser les variations de température de la maison entre le chauffage au sol, le poêle à pellet, et l’ensoleillement à travers les ouvertures.

Posté dans 1-wire, graphs, php, Raspberry Pi, Web | Tagged , , , , | 19 Commentaires

Graphique de températures 1-wire avec pChart2

Il y’a quelques temps, j’ai abordé le sujet de la réalisation de graphiques de températures pour munin.
La base étant  l’exploitation des sondes 1-Wire sur une machine Debian et l’utilisation en PHP.
J’ai également parlé de la mise en base de données MySQL des valeurs du bus OneWire.

Un des buts de la mise en place des valeurs dans une base, est de pouvoir générer des graphiques personnalisés sur une durée et/ou une sonde spécifique.

Jusqu’à présent, j’avais une préférence pour les librairies Artichow, mais le projet a été arrêté.
Je me suis tourné vers pChart v2 : http://www.pchart.net

Ce que j’apprécie particulièrement, c’est la sandbox, sa documentation complète,ainsi que ses nombreuses possibilités !

Sandbox pChart

Sandbox pChart

En partant de mes derniers articles, j’ai repris un code généré en sandbox et adapté pour 24h de données 1-wire :
Script encore une fois, à adapter, je n’ai pas fait appel à mes includes pour mieux comprendre le principe du script.

<?php
ini_set('display_errors','Off');

// Préfixe de toutes les tables du site
$MYSQLHOST = "localhost";
$MYSQLLOGIN = "root";
$MYSQLPWD = "toto";
$MYSQLBASE = "1wire";
// Conection avec la base de données mysql
$db = mysql_connect($MYSQLHOST, $MYSQLLOGIN, $MYSQLPWD);
$mysql=mysql_select_db($MYSQLBASE,$db);

function OWSensorList($type=null) {
 $OWSensorList = array();
 $cpt = 0;
 if ($type == 'temperature') $req_owlist = "SELECT * FROM 1wire_sensor WHERE 1wire_sensor_type='temperature' ORDER BY 1wire_sensor_id ASC";
 else $req_owlist = "SELECT * FROM 1wire_sensor WHERE 1 ORDER BY 1wire_sensor_id ASC";
 $qur_owlist = mysql_query($req_owlist) or die(mysql_error());
 while($dat_owlist = mysql_fetch_array($qur_owlist)) {
 $OWSensorList[$cpt]['sensor_id'] = $dat_owlist['1wire_sensor_id'];
 $OWSensorList[$cpt]['sensor_enable'] = $dat_owlist['1wire_sensor_enable'];
 $OWSensorList[$cpt]['sensor_type'] = $dat_owlist['1wire_sensor_type'];
 $OWSensorList[$cpt]['sensor_family'] = $dat_owlist['1wire_sensor_family'];
 $OWSensorList[$cpt]['sensor_idaddress'] = $dat_owlist['1wire_sensor_idaddress'];
 $OWSensorList[$cpt]['sensor_comment'] = $dat_owlist['1wire_sensor_comment'];
 $cpt++;
 }
 return $OWSensorList;
}

// Retourne juste l'heure ou les minutes de YYYY-MM-DD H:i:s
function SplitTime($datemysql,$type) {
 list($date, $time) = explode(" ", $datemysql);
 list($year, $month, $day) = explode("-", $date);
 list($hour, $min, $sec) = explode(":", $time);
 if($type == 'min') return $min;
 if($type == 'hour') return $hour;
}

function OWFetch24HData($sensor_id) {
 $OWFetch24HData = array();
 $cpt = 0;
 $req_owlist = "SELECT * FROM 1wire_data WHERE 1wire_data_sensor_id = ".$sensor_id." AND 1wire_data_timestamp BETWEEN DATE_ADD( NOW( ) , INTERVAL -1 DAY ) AND NOW( ) ORDER BY 1wire_data_id ASC";
 $qur_owlist = mysql_query($req_owlist) or die(mysql_error());
 while($dat_owlist = mysql_fetch_array($qur_owlist)) {
 $fetch_timestamp = $dat_owlist['1wire_data_timestamp'];
 $fetch_minute = SplitTime($fetch_timestamp,'min');
 if($fetch_minute != '00') $OWFetch24HData['data_timestamp'][$cpt] = '';
 elseif($fetch_minute == '00') $OWFetch24HData['data_timestamp'][$cpt] = SplitTime($fetch_timestamp,'hour')."h";
 $OWFetch24HData['data_value'][$cpt] = $dat_owlist['1wire_data_value'];
 $cpt++;
 }
 return $OWFetch24HData;
}

include("lib/pChart2.1.3/class/pData.class.php");
include("lib/pChart2.1.3/class/pDraw.class.php");
include("lib/pChart2.1.3/class/pImage.class.php");

$myData = new pData();

$OWSensorList = OWSensorList('temperature');
for ($i = 0; $i < sizeof($OWSensorList); $i++) {
 if($OWSensorList[$i]['sensor_enable']) {
 $OWFetch24HData = OWFetch24HData($OWSensorList[$i]['sensor_id']);
 $myData->addPoints($OWFetch24HData['data_value'],$OWSensorList[$i]['sensor_id']);
 $myData->setSerieDescription($OWSensorList[$i]['sensor_id'],$OWSensorList[$i]['sensor_comment']);
 $myData->setSerieOnAxis($OWSensorList[$i]['sensor_id'],0);
 }
}

$myData->addPoints($OWFetch24HData['data_timestamp'],"Absissa");
$myData->setAbscissa("Absissa");

$myData->setAxisPosition(0,AXIS_POSITION_LEFT);
$myData->setAxisName(0,"Temp&eacute;ratures");
$myData->setAxisUnit(0,"°C");

$myPicture = new pImage(1000,400,$myData);
$myPicture->setShadow(TRUE,array("X"=>1,"Y"=>1,"R"=>50,"G"=>50,"B"=>50,"Alpha"=>20));

$myPicture->setFontProperties(array("FontName"=>"fonts/Forgotte.ttf","FontSize"=>18));
$TextSettings = array("Align"=>TEXT_ALIGN_MIDDLEMIDDLE
, "R"=>0, "G"=>0, "B"=>0);
$myPicture->drawText(500,25,"Températures",$TextSettings);

$myPicture->setShadow(FALSE);
$myPicture->setGraphArea(75,50,975,360);
$myPicture->setFontProperties(array("R"=>0,"G"=>0,"B"=>0,"FontName"=>"fonts/Bedizen.ttf","FontSize"=>10));

$Settings = array("Pos"=>SCALE_POS_LEFTRIGHT
, "Mode"=>SCALE_MODE_FLOATING
, "LabelingMethod"=>LABELING_ALL
, "GridR"=>255, "GridG"=>255, "GridB"=>255, "GridAlpha"=>50, "TickR"=>0, "TickG"=>0, "TickB"=>0, "TickAlpha"=>50, "LabelRotation"=>0, "CycleBackground"=>1, "DrawXLines"=>1, "DrawSubTicks"=>1, "SubTickR"=>255, "SubTickG"=>0, "SubTickB"=>0, "SubTickAlpha"=>50, "DrawYLines"=>ALL);
$myPicture->drawScale($Settings);

$myPicture->setShadow(TRUE,array("X"=>1,"Y"=>1,"R"=>50,"G"=>50,"B"=>50,"Alpha"=>10));

$Config = "";
$myPicture->drawSplineChart($Config);

$Config = array("FontR"=>0, "FontG"=>0, "FontB"=>0, "FontName"=>"fonts/Forgotte.ttf", "FontSize"=>12, "Margin"=>6, "Alpha"=>30, "BoxSize"=>5, "Style"=>LEGEND_NOBORDER
, "Mode"=>LEGEND_HORIZONTAL
, "Family"=>LEGEND_FAMILY_LINE
);
$myPicture->drawLegend(837,16,$Config);

$myPicture->stroke();
?>

Il faut au moins 1h de données, résultat :

Graphique 1-wire avec librairie pChart

Graphique 1-wire avec librairie pChart

Comme d’habitude, il est nécessaire d’adapter, inclure, configurer, à chacun comme bon lui semble. Ça reste un exemple, ou une base de travail.

En tout cas, parmi les différentes libraries PHP pour génerer des graphiques, pChart2 est mon coup de coeur, même si le projet n’a pas bougé depuis septembre 2011, il est suffisament abouti.

Posté dans 1-wire, php, Web | 4 Commentaires

Barrière infra-rouge, DS2401 et bus 1-wire

Après une longue pause de plusieurs mois, je me suis enfin attaqué à mon idée de barrière infra-rouge reliée au bus 1-wire.

Mon idée de base est d’être averti lors du passage du facteur : une boîte aux lettres domotisée.
Des solutions DIY existent déjà, regroupant des technologies d’ILS + IPX800RFXCOM, Zwave, etc…

Je n’ai pour l’instant pas lu d’articles utilisant le protocole 1-wire pour avertir de la venue du facteur, j’ai donc pensé à une solution pour y arriver.

Les solutions existantes pour l’instant se basent toutes sur la détection de l’ouverture de la porte ou du clapet de la boîte, il est clair que c’est le plus logique et évident ; sauf qu’en 1-Wire, surveiller l’omniprésence de la porte ou du clapet n’est pas envisageable car sur-occuperait l’ensemble du bus.
Le clapet de la boîte ne s’ouvre que pendant une demi-seconde et y placer une détection de la même façon qu’une fenêtre, n’est donc pas envisageable.

Le seul moyen, à mes yeux, est de surveiller le contenu de la boîte aux lettres.

Le petit matériel

Je me suis équipé de trois barrières infra-rouges ainsi que d’un relais 1 channel :

Barrière infra-rouge à 2,63 €

Barrière infra-rouge à 2,63 €

Cette barrière infrarouge dispose d’un récepteur / émetteur perpendiculaire au PCB.
A 2,63 € frais de ports compris, c’est le plus « cheap ».
3 pin :
– VCC (5V)
– Output
– Ground


Barrière infra-rouge à 7,41 €

Barrière infra-rouge à 7,41 €

Cette barrière infrarouge dispose d’un récepteur / émetteur parallèle au PCB.
A 2,63 € frais de ports compris, c’est le plus « cheap ».
4 pin :
– VCC (5V)
– Output
– Ground
– EN (???)


Barrière infra-rouge à 7,41 €

Barrière infra-rouge à 4,45 €

Cette barrière se trouve aux alentours de 4,45 €.
Elle est vendue en tant que barrière IR pour Arduino.
Contrairement à sa taille, son boîtier est un avantage.


Channel relais 5V

Channel relais 5V à 4,14 €

Un relais 5Volt monté sur un PCB, permettant de relier le DS2401 au bus 1-wire.


Schéma d'utilisation du DS2401

Schéma d’utilisation du DS2401

Un DS2401 déjà étudié pour la detection d’ouverture de portes et fenêtres.

Le principe

Le faisceau infra-rouge reflète sur une bande réfléchissante autocollante, le faisceau est renvoyé à la barrière infrarouge = il n’y a pas de courrier.

Boite aux lettres sans courrier

Boite aux lettres sans courrier

Le faisceau infra-rouge ne reflète pas, il est obstrué par une lettre ou un colis = il y’a du courrier.

Boite aux lettres avec courrier

Boite aux lettres avec courrier

Bon, alors … quelques points à préciser :

  • Je suis vraiment loin d’être un pro sous paint.
  • Je ne suis vraiment pas sûr que ça fonctionne, tout va dépendre de la sensibilité de la barrière IR (réglable avec un tournevis), mais faut bien essayer …
  • Ce n’est pas infaillible, si la lettre ne tombe pas devant le faisceau, c’est cuit, l’avantage c’est que le marabout du coin qui me laisse sa carte de visite ne me déclenchera pas d’alerte facteur.
  • Ce fonctionnement est applicable à d’autres cas : le chien est dans sa niche ? Les hirondelles dans leur nid ? Suffit d’une meilleure imagination.
  • Pas de boîtier adapté.
  • Un pétard dans la boîte aux lettres me rendrait fou de rage !
  • Faut être sûr d’avoir du 5 Volts qui tiennent jusqu’à la boîte aux lettres, malgré la paire torsadée.

Schéma électronique

Je pars avec mon existant, c’est à dire un injecteur 5V et un bus 1-wire.

Principe de fonctionnement barrière IR

Principe de fonctionnement barrière IR

J’alimente ma barrière infra-rouge, qui me sort du 5V sur la pin Output, cette même pin qui est reliée au Input du relais sur PCB.
En sortie du relais, je retrouve mon bus 1-wire avec mon DS2401.
La barrière infra-rouge va faire basculer mon relais, donc connecter ou déconnecter le DS2401.
Ainsi, logiciellement, j’aurais toute les 5 minutes par exemple, à tester la présence de ce DS2401 sur le bus pour y conclure l’état de la boîte aux lettres.

Pourquoi pas ?

Alors essayons ! Fil à l’air pour voir …
Humm…
Je rappelle que ce blog est alimenté par mes découvertes en domotique, j’ai des idées, je teste, je mets en ligne ; si il y a mieux, tant mieux … Ca fonctionne, c’est cool…
A ce stade je ne suis pas sûr que ça fonctionne dans un cas concret.

Les essais

Réglage du potentiomètre

Réglage du potentiomètre

Déjà les trois barrières infra-rouge, la puissance d’émission de la LED se régle par un potentiomètre.
C’est bien, mais les modèles sans boîtier ne sont pas faciles à régler, pas assez de sensibilité, c’est vite du tout ou rien.
Petite astuce : s’aider d’un appareil photo pour voir la lumière infrarouge s’atténuer selon la rotation du potentiomètre.

Photo produit

Photo produit

Ensuite le modèle à deux « potars » est encore moins facile d’utilisation.
C’est peut-être parce que je n’ai pas compris le chinois qui est écrit sur sa « photo de vente ».
J’ai l’impression que l’un sert à régler la puissance d’émission de la LED, et l’autre la sensibilité du phototransistor.
Le cavalier et la sortie « EN » je sèche…

Alors, fil en l’air, vite fait bien fait, ca donne ceci :

Montage fil à l'air n°1

Montage fil à l’air n°1

Rouge : 5V
Noir : masse
Blanc : Input/output entre la barrière et le switch, c’est ma commande.
Bleu et brun : Data 1-wire

C’est bien, mais le switch IR est instable, problème de sensibilité lié, mauvais positionnement de potentioètre?
Ca clignote ! grrr

En fait, ce qui ne va pas sur ce modèle de barrière, au delà de la sensibilité, c’est la tension de sortie en 3,3 Volts.

Le switch infra-rouge avec le boîtier jaune à 4,45 € a une commande à 5 Volts, bien plus pratique dans notre cas, et bien plus performant.
De plus, ce modèle fait l’objet d’une sensibilité de l’emetteur/recepteur beaucoup plus fine.

Pas besoin de plus de vidéo, ça fonctionne pour l’instant.

Coté OWHTTP également, le DS2401 est présent sur le bus lorsque le faisceau IR est obstrué ; à l’inverse, il est absent du bus lorsque le faisceau n’est pas obstrué.
La sensibilité d’obstruction est à régler selon la boîte aux lettres, selon le positionnement du switch, le type de réflecteur, l’utilisation d’un catadioptre ou non.

En pratique

En pratique ? Gros suspens !
Il y a une part de physique optique avec l’orientation et la sensibilité du faisceau IR.
Une part électronique avec l’arrivée du 1-WIRE et de son 5Volt injecté jusqu’à l’extérieur, dans une boîte aux lettres soumise aux intempéries. A voir …
L’article s’arrête malheureusement là, sans mise en oeuvre pratique pour l’instant, faute de cas concret : pas de boîte aux lettres, pas de boîtier pour planquer l’électronique.
J’essaie de récupérer une boîte aux lettres aux normes de La Poste pour y fixer de façon intelligente cette barrière IR, les réglages optiques fonctionnels et une programmation adéquate.

A suivre.

Posté dans 1-wire | 12 Commentaires

Alimentation / injecteur 5 Volts 1-wire (version beta)

Il était temps de changer la version alpha !

Même principe, même schéma électrique, sans pistolet à colle et le luxe d’un fusible :

Injecteur 5Volt pour 1-wire DIY

Injecteur 5Volt pour 1-wire DIY

Injecteur 1wire avec fusible

Injecteur 1wire avec fusible

Le boitier est vendu sur ebay.com (Cat5e Ethernet Keystone RJ-45 Jack & Surface Mount Box).

Ouf ! Il était vraiment temps de changer !

Posté dans 1-wire | 7 Commentaires

Insérer les valeurs 1-wire dans une base MySQL

J’ai déjà abordé la récupération des températures dans un graphique munin.
J’ai également abordé la récupération de ces mêmes valeurs en PHP.

Et maintenant, place à la récupération des valeurs pour l’insertion dans une base de données MySQL.
Le but étant de passer par le cron, d’avoir une table avec les sondes, une table avec les valeurs.

J’ai réalisé ce premier ensemble de scripts regroupant pas mal de require, c’est plus difficile à partager pour la compréhension et les explications mais j’espère que ce script restera sous cette forme pour mon usine à gaz définitive.

Structure de la base

Une première table avec les sondes, voici son squelette :

CREATE TABLE IF NOT EXISTS `1wire_sensor` (
  `1wire_sensor_id` int(3) NOT NULL AUTO_INCREMENT,
  `1wire_sensor_enable` enum('true','false') NOT NULL,
  `1wire_sensor_type` enum('temperature','presence','sensed.A') NOT NULL,
  `1wire_sensor_family` tinytext NOT NULL,
  `1wire_sensor_idaddress` tinytext NOT NULL,
  `1wire_sensor_comment` text NOT NULL,
  PRIMARY KEY (`1wire_sensor_id`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;

Une seconde table avec les valeurs, son squelette :

CREATE TABLE IF NOT EXISTS `1wire_data` (
  `1wire_data_id` int(11) NOT NULL AUTO_INCREMENT,
  `1wire_data_sensor_id` int(3) NOT NULL,
  `1wire_data_timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `1wire_data_value` text NOT NULL,
  PRIMARY KEY (`1wire_data_id`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;

Le script automatique

Comme expliqué plus haut, difficile de partager un script complexe pour un besoin simple.
Je fais un « require » pour appeler un fichier de config, un autre pour la connexion MySQL, un dernier pour mes fonctions 1-wire.

Ce qui donne cet ensemble :

<?php
$pathconfig = "/var/www/domy";
require_once($pathconfig."/require/main.inc.php");
require_once(PATH."/require/database.inc.php");
require_once(PATH."/require/function-1wire.inc.php");

// Recup des données des sondes depuis la BDD
$req_sensor = "SELECT * FROM 1wire_sensor WHERE 1wire_sensor_enable IS TRUE";
$qur_sensor = mysql_query($req_sensor);
while($dat_sensor = mysql_fetch_array($qur_sensor)) {
 // Pour chaque sonde on constitue son adresse :
 $onewire_address = $dat_sensor['1wire_sensor_family'].".".$dat_sensor['1wire_sensor_idaddress'];
 // On teste sa présence sur le bus
 if(onewire_presence($onewire_address)) {
 debug("OUI ! ".$onewire_address." est présent sur le bus","cli");
 if ($dat_sensor['1wire_sensor_type'] == "presence") {
 debug("Seul sa presence sur le bus est nécessaire","cli");
 // on ecris dans la BDD qu'il est présent et on s'arrete là
 $value = 1;
 }
 elseif ($dat_sensor['1wire_sensor_type'] == "temperature" || $dat_sensor['1wire_sensor_type'] == "sensed.A") {
 // on récupère sa valeur, que ca soit la température ou l'état du PIO (DS2406)
 $value = onewire_read($onewire_address,$dat_sensor['1wire_sensor_type']);
 }
 }
 else {
 // Composant absent du bus
 debug ("NON ! ".$onewire_address." n'est pas présent sur le bus","cli");
 $value = 0;
 }

 // on écris le resultat dans la BDD
 $req_insdata = "INSERT INTO 1wire_data SET
 1wire_data_sensor_id = ".$dat_sensor['1wire_sensor_id'].",
 1wire_data_value = '".$value."'";
 mysql_query($req_insdata) or die ("Erreur à l'insertion des données 1-wire : ".mysql_error());
}

?>

J’espère que le principe de ce script php reste compréhensible avec les commentaires.

L’ensemble des fichiers sont disponible à la fin de l’article.

Le contenu de la base

Une fois la structure de la base établie ainsi que le script chargé de consulter les élements 1-wire, il reste à saisir les informations liés aux éléments 1-wire.
Pour cela, en plus d’avoir identifiant chaque sonde au moment de son câblage, je me sert de owhttpd pour récupérer l’ID  des sondes. ( http://ipduserveur:2121/ )

Fenêtre fermée, DS2401 présent dans owhttp

Fenêtre fermée, DS2401 présent dans owhttp

J’ai descidé de spliter en deux l’ID des sondes 1-wire.
Par exemple, pour 28.7B2DB5030000 :
– Famille : 28.
– ID : 7B2DB5030000.

Et j’utilise phpmyadmin pour inserer la 1re sonde de température ( 28.7B2DB5030000 ) afin d’obtenir ceci :

Sonde 1-wire dans la base MySQL via phpmyadmin

Sonde 1-wire dans la base MySQL via phpmyadmin

Ainsi de suite pour chaque sonde désirée, 1wire_sensor_id étant la clée primaire en AUTO_INCREMENT.

A terme, le but étant de créer une interface pour gérer l’ajout, l’édition et la supression de sonde plus facilement via une page développée dans ce sens.
Idem pour chaque famille de sonde : température / présence / PIO.

Execution

On peut faire un simple test :

# cd /var/www/1-wire/cron
# php fetch-1wire.php

Vous devriez obtenir les valeurs de température.
Si vous obtenez le message :

PHP Notice: Can’t create socket [ow://127.0.0.1:4304], errno: 111, error: Connection refused in /var/www/1-wire/require/ownet.php on line 205
PHP Notice: Can’t connect get#1 in /var/www/1-wire/require/ownet.php on line 388

Modifiez le /etc/owfs.conf pour remplacer :
server: port = localhost:4304
Par :
server: port = 4304

Redemarrez owserver et refaite le test.

Si tout est ok, l’execution se fait via le cron, tout simplement :

# vi /etc/cron.d/cron1wire
*/5 *   * * *   root    /usr/bin/php -q /var/www/1-wire/cron/fetch-1wire.php

Au bout de quelques heures :

Résultat  de l'insertion des températures 1-wire dans une base MySQL

Résultat de l’insertion des températures 1-wire dans une base MySQL

Télécharger

Télécharger l’archive

A adapter, bidouiller, comprendre, améliorer, etc…

Et bientôt la génération de beaux graphs à partir de ces valeurs.

Posté dans 1-wire, Debian, graphs, php | 5 Commentaires

Interroger les sondes 1-wire par un script PHP

Un point que je n’avais pour l’instant pas abordé dans mes différents articles sur le 1-wire :

Je n’ai pas abordé le contrôle du 1-wire en PHP.

Pour faire quoi ?

Une grosse usine à gaz !
Utiliser PHP pour interroger les sondes 1-wire, c’est tout simplement ce qu’il y’a de plus logique dans mon projet, vue que je souhaite une interface à la knxweb2 mais home made.
L’affichage d’une température sur un plan et toute autre utilisation des mesures se fera par PHP.

Quels paquets php à installer ?

Comme vu dans la phase de découverte, owserver est désormais disponible en package compilé pour Debian Wheezy.
Pour les librairies PHP, il existe deux paquets aux noms semblables : libow-php5 et libownet-php.

Quelle différence ? La question a été posée au contributeur du package, voici sa réponse :
libownet-php ne peut que communiquer avec owserver, qui, lui-même pourra communiquer avec d’autres owserver et/ou matériel 1-wire.
libow-php5 est un wrapper autour de la bibliothèque C qui permet de communiquer directement avec le matériel 1-wire.

Alors on installe libownet-php.

# apt-get install libownet-php

Ce qui a pour effet d’installer un fichier php de class au chemin suivant :
/usr/share/php/OWNet/ownet.php

Une page d’exemple est disponible au chemin suivant :
/usr/share/doc/libownet-php/examples/ownet_example.php

Cet exemple fait référence à un fichier bcadd.php, il s’agit d’un hack car certaines versions distribuées de php ne permettent pas l’utilisation de cette fonction, fournir cette fonction par un include permet de contourner le problème. Evidemment, sous Debian Wheezy hébergement maison, ce qu’il y’a de plus classique, pas de problème avec bcadd, donc le « require » ne sera pas utilisé.

Récupérer des valeurs en PHP

Pour ce test, j’ai placé sur mon bus 1-wire :

  • 1x DS18B20 : sonde de température à l’extérieur.
  • 1x DS18B20+PAR : sonde de température à l’intérieur.
  • 1x DS2406 : capteur d’ouverture de fenêtre.
  • 1x DS2401 : capteur d’ouverture de fenêtre.

L’ensemble des fonctions ownet php sont visibles sur la page du projet :
http://owfs.org/index.php?page=ownet-php

Je récupère le fichier ownet.php, sans quoi on obtient forcément l’erreur suivante :

PHP Fatal error:  Class 'OWNet' not found
# cp /usr/share/php/OWNet/ownet.php /var/www/1-wire/

Et mon index.php

<?php
require "ownet.php";

$ow=new OWNet("tcp://127.0.0.1:4304");

?>
Temp&eacute;rature ext&eacute;rieure :
<?
$temp_ext = $ow->read("/28.EA54B5030000/temperature");
// Décommenter la ligne suivante pour avoir les détails du composant
//var_dump($ow->dir("/28.EA54B5030000",OWNET_MSG_READ,true));
echo $temp_ext;
// ------------------
?>

<br />
Temp&eacute;rature int&eacute;rieure :
<?php
$temp_int = $ow->get("/28.919277030000/temperature",OWNET_MSG_READ,false);
// Décommenter la ligne suivante pour avoir toutes les infos sur la température
//var_dump($ow->get("/28.919277030000/temperature",OWNET_MSG_READ,true));
echo $temp_int;
// ------------------
?>

<br />
Fen&ecirc;tre DS2406 :
<?php
$fenetre_ds2406 = $ow->read("/12.D0457D000000/sensed.A");
// Décommenter la ligne suivant pour avoir toutes les infos sur le PIO A
//var_dump($ow->get("/12.D0457D000000/sensed.A",OWNET_MSG_READ,true));
echo ($fenetre_ds2406)?"ouverte":"ferm&eacute;e";
// ------------------
?>

<br />
Fen&ecirc;tre DS2401 :
<?php
$fenetre_ds2406 = $ow->presence("/01.DC4343140000");
// Décommencer la ligne suivante pour avoir les détails, minimaliste car c'est une présence
//var_dump($ow->dir("/01.DC4343140000",OWNET_MSG_READ,true));
echo ($fenetre_ds2406)?"ferm&eacute;e":"ouverte";
// ------------------
?>

<br />
Page PHP de requêtes 1-wire

Page PHP de requêtes 1-wire

J’ai laissé les lignes var_dump commentées, elles peuvent servir de débogage.
Le port 4304 à adapter selon votre serveur owserver ( /etc/owfs.conf ).

A noter, comme vue dans mon article sur le DS2406, sensed.A retourne un 1 lorsque l’ILS est ouvert, 0 lorsque qu’un aimant est à proximité, ce qui pourrait porter à confusion.

Read et Get sont sur un bateau

Les read et le get, syntaxé comme ceci, apportent le même résultat.

$ow->get("/28.919277030000/temperature",OWNET_MSG_READ,false);
$ow->read("/28.919277030000/temperature");

D’après la doc de owfs.org le get parcourt chaque valeur de l’élément désiré et y applique une fonction/constante.
Tandis que le read, récupère la valeur demandée, point final.

Dans mes tests, et pour une requête de température il s’avère que le get ne retourne pas toujours de valeurs.
Il semble fonctionner à un niveau plus « bas » que le read.
Donc la fonction read est à privilégier.

Et maintenant ?

L’insertion des données dans une base MySQL, pour un prochain article.

Posté dans 1-wire, Debian, php, Web | 6 Commentaires

Capteur d’ouverture de fenêtres avec un DS2401

Datasheet du DS2401

Datasheet du DS2401

Après la découverte du DS2406 en tant que capteur d’ouverture / fermeture de fenêtre, je découvre le DS2401.
Il s’agit toujours d’un boîtier TO-92 dont la pin 3 n’est pas connectée.

Le principe est plus simple : le DS2401 est présent sur le bus ?

  • Oui, la fenêtre est fermée.
  • Non, la fenêtre est ouverte.

Pas de mode alimenté, l’alim du DATA suffit à alimenter le composant.
Donc il suffit de placer un switch magnétique sur la pin DATA.
Aucune utilisation du 5 Volts.

Schéma d'utilisation du DS2401

Schéma d'utilisation du DS2401

Ce qui donne ceci :

DS2401 soudé à un switch

DS2401 soudé à un switch

Place aux tests.
Je garde les autres paires pour maintenir la solidité de l’installation.

Fenêtre ouverte le DS2401 est absent

Fenêtre ouverte le DS2401 est absent

Fenêtre fermée le DS2401 est présent

Fenêtre fermée le DS2401 est présent

Évidemment, le jour venu de mettre ces capteurs en place dans les fenêtres, j’utiliserai de vrais switch magnétiques en accord avec l’entreprise en charge des menuiseries.

Vue dans owhttp :

Fenêtre ouverte, DS2401 absent dans owhttp

Fenêtre ouverte, DS2401 absent dans owhttp

Mon composant a l’ID DC4343140000

Fenêtre fermée, DS2401 présent dans owhttp

Fenêtre fermée, DS2401 présent dans owhttp

Ou tout simplement en utilisant le uncaches via owfs :

# ls uncached/ -lha
total 0
drwxr-xr-x 1 root root 8 avril 11 15:08 .
drwxr-xr-x 1 root root 8 avril 11 15:08 ..
drwxrwxrwx 1 root root 8 avril 11 15:53 01.DC4343140000
drwxrwxrwx 1 root root 8 avril 11 15:53 28.7B2DB5030000
drwxrwxrwx 1 root root 8 avril 11 15:53 81.BD2223000000
drwxr-xr-x 1 root root 8 avril 11 15:08 alarm
drwxr-xr-x 1 root root 8 avril 11 15:08 bus.0
drwxr-xr-x 1 root root 8 avril 11 15:08 bus.1
drwxr-xr-x 1 root root 8 avril 11 15:08 settings
drwxrwxrwx 1 root root 8 avril 11 15:53 simultaneous
drwxr-xr-x 1 root root 8 avril 11 15:08 statistics
drwxr-xr-x 1 root root 32 avril 11 15:08 structure
drwxr-xr-x 1 root root 8 avril 11 15:08 system

Voila, c’est encore plus simple à mettre en place que le DS2406.

J’ai hâte de faire les premiers tests en php pour utiliser pleinement ces composants.

Avantage du DS2401 par rappot au DS2406 ?
Le coût ! On peut facilement trouver des DS2401 par 10 à moins de 10 €, frais de port compris, ça fait moins d’un euro le capteur d’ouverture.

Posté dans 1-wire, Debian | 12 Commentaires

Capteur d’ouverture de fenêtres avec un DS2406

Datasheet DS2406

Datasheet DS2406

Dans mon projet domotique, je souhaite surveiller l’ouverture des fenêtres, et peut-être même les portes intérieures.
Et pour ça, je pars à la découverte du DS2406+, il s’agit d’un boîtier en TO-92 permentant soit de :

  • Lire l’état d’une sortie
  • Commander une sortie

Je ferai également le test avec un DS2401 quand j’en aurai.
Son utilisation est différente, on ne lit pas une sortie du composant mais on teste la présence de celui-ci sur le bus.
Je garde mon dernier DS2406 pour commander une sortie.

Donc je souhaite câbler mon DS2406 pour lire l’état de ma patte 3, nommée PIO.
Là encore, comme j’aime bien pomper, je re-utilise le schéma de queret, mais sans la LED.

Schéma du DS2406 en capteur

Schéma du DS2406 en capteur

R1 = 100 kΩ
5Volts provenant de mon injecteur.

Voilà pour la théorie, en pratique, je m’accorde un premier essai à l’air.
L’interrupteur est un ILS Interrupteur à Lame Souple (0.40 € pièce), je pensais naïvement pouvoir les encastrer dans les moulures de mes futures fenêtres, chose qu’on m’a déconseillé car, étant en verre, ils sont trop fragiles. Je m’en servirai pour mes tests.

Soudure en l'air d'un DS2406

Soudure en l'air d'un DS2406

Voila pour un premier test en l’air.
Une fois branché à mon serveur Debian Wheezy Domy OWFS powered, owhttp me donne ceci :

Vue d'OWHTTP pour le DS2406

Vue d'OWHTTP pour le DS2406

Le champs m’indiquant l’état de l’ILS est sensed.A.
La valeur est en cache pour 10 secondes.

Pour ne pas patienter 10 secondes entre chaque état, il est possible d’utiliser les valeurs « uncached », cf le lien en haut de la page d’owhttp.

Je préfère malgré tout utiliser owfs par simplicité.

# cd /mnt/1wire/uncached/12.D0457D000000/
# cat sensed.A
1

Direction le frigo pour piquer une bière un aimant.

DS2406+ avec un aimant et un ILS

DS2406+ avec un aimant et un ILS

# cat sensed.A
0

C’est finalement très simple ! Et je me rend compte que mon désir de pouvoir intervenir sur l’élément en cas de panne sera possible.

Je m’oriente vers un switch magnétique prévu pour être encastré dans une fenêtre, ceci :

Un switch à encastrer dans une porte

Un switch à encastrer dans une porte

D’après un constructeur de fenêtres, l’incrustation de ce type d’interrupteur ne pose pas de problème de pont thermique, il est même possible de fournir les composants de façon à ce qu’ils adaptent les trous et le passage des câbles.
D’autre part, comme soulevé sur le forum bricozone.be (mon pseudo : Aior) : « Pour les contacts encastrables, il faut savoir que les installateurs sont assez peu motivés pour ce genre d’installation car le prix de revient (surtout main d’oeuvre) est très élévé alors que sur 1 détecteur, la marge est cash. ».
Humm ! A voir avec le menuisier le jour venu.
L’avantage de ce type de switch magnétique et, au vu de la simplicité de câblage du DS2406, en cas de soucis, il me suffirait de déboiter le switch, de tirer délicatement sur celui-ci pour faire venir le DS2406 et sa résistance.
Donc la maintenance est possible !

Bon, revenons à notre DS2406, j’essaye de faire quelque chose de propre en « intégrant » les résistances dans la longueur du câble et enrober l’ensemble de gaine thermo :

Mise en place de la gaine thermo difficile avec les jonctions

Mise en place de la gaine thermo difficile avec les jonctions

Je fais sortir mon ILS  au-dessus du DS2406, ce qui donne un résultat *bien mais pas top*. 8 ans sans souder, 8 ans !

DS2406 planqué avec ILS

DS2406 planqué avec ILS

Le DS2406 a résisté au briquet.

Place aux tests soft.
Toujours depuis owfs uncached.

# watch -n1 'cat sensed.A'

Et là, essai avec l’aimant pour constater qu’il y’a parfois des loupés.
Bon, pour une fenêtre, ça marche bien, détecter une fenêtre ouverte dans le but de couper le chauffage, on est pas à 10 secondes près.
Mais j’aurais bien voulu porter ce fonctionnement à la boîte aux lettres… Vu comme c’est simple, autant ne pas se priver !

Sauf qu’avec ces ratés de détection, ça ne sera pas possible.
Le temps d’ouverture de la trappe de la boîte aux lettres pour le passage d’une lettre, c’est quoi ? 1 seconde, même pas ?
Bah si je présente mon aimant devant ILS juste 1 seconde, sensed.A passe seulement quelques fois à 0.
Ce n’est pas fiable pour détecter le passage du facteur, dommage !
D’autant plus qu’interroger le composant toutes les secondes dans le uncache, n’est pas une solution viable.

Fenêtre fermée sensed.A est à 0.
Fenêtre ouverte sensed.A est à 1.
Ça ne serait pas plus logique l’inverse ?

La solution pour obtenir l’inverse serait de câbler le DS2406 comme ceci :

DS2406 ILS sur PIO. Non testé.

DS2406 ILS sur PIO. Non testé.

R1 toujours à 100kΩ.

Mais je n’ai pas testé ce montage, donc sans garantie.

Conclusion

Détecter des ouvertures de portes/fenêtre est un jeu d’enfant avec le DS2406, son câblage est facile, il est solide, réactif.
Points négatifs : sa rareté, à part en échantillons, je ne sais pas où en acheter.
Je pense qu’il y’a moyen de faire plus simple avec le DS2401 qui fonctionne en mode parasite, et qui coûte moins d’1€ pièce, mais je reste perplexe sur le mode de fonctionnement de celui-ci.

Posté dans 1-wire, Debian | 9 Commentaires

Découvertes des sondes DS18B20 et DS18B20PAR

L’astuce de demande d’échantillons chez MAXIM ne date pas d’hier, ça marche bien, très bien même. Il faut tout de même veiller à respecter un certain délai entre les demandes, paraît-il entre 2 et 3 mois.
Un DS18B20 coûte 3€ pièce, mais si on cherche bien, on en trouve à moins d’un euro pièce.

Mes derniers expériences en soudure date d’il y’a 10 ans, c’est comme le vélo, ça ne s’oublie pas, sauf que je fais de gros pâtés dégueulasses.

J’utilise mon injecteur 5Volts pour interconnecter mon bus ; j’ai toujours mes 3 câbles :
Brun : 5 Volts
Blanc bleu : GND
Bleu : DATA

Le but étant de souder une sonde de température ou bout d’un RJ45 rigide et de lui enfiler une gaine thermorétractable.
J’ai deux DS18B20+ et deux DS18B20+PAR.
En effet, il existe deux modèles de DS18B20, le « normal » et son jumeau qui fonctionne d’office en mode parasite.
Le mode parasite consiste à alimenter le composant par le brin DATA du bus 1-wire.
Il est donc possible d’utiliser un DS18B20 « normal » pour l’utiliser en mode parasite, ce qui revient à utiliser directement un DS18B20+.

DS18B20+PAR la sonde de température en mode parasite par Dallas

Schéma DS18B20+PAR

Schéma DS18B20+PAR

Une installation très simple !
Contrairement au DS18B20 câblé en mode parasite (cf ci-dessous), sur le DS18B20+PAR il n’est pas nécessaire de relier la patte 3 à la patte 2.

C’est fou de se dire qu’un petit truc comme ça, peut nous apporter les informations de température, avec un identifiant unique, un protocole embarqué…

Le mode parasite contraint à avoir un nombre restreint de composants sur le bus.

La patte 3 du DS18B20+PAR ne sert à rien

La patte 3 du DS18B20+PAR ne sert à rien

Je sais que je ne les mettrais pas dans mon projet de maison, mais comme j’en ai, autant s’en servir pour effectuer des tests.

Un petit test avant d’enfiler la gaine thermo.

Test d'un DS18B20 avant mise en place de la gaine themo

Test d'un DS18B20 avant mise en place de la gaine thermo

Je laisse toujours les câbles non-connectés pour maintenir la solidité, puis j’y met le feu !!§§

Les DS18B20 résistent bien à la chaleur

Les DS18B20 résistent bien à la chaleur

Pas de craintes, les DS18B20 semblent bien résister au fer à souder et à la flamme.

DS18B20+PAR identifié avec gaine thermo

DS18B20+PAR identifié avec gaine thermo

Vue d'ensemble d'un DS18B20 sur RJ15 rigide

Vue d'ensemble d'un DS18B20 sur RJ15 rigide

DS18B20 avec alimentation 5 Volts

Schéma de câblage du DS18B20 en mode parasite

Schéma de câblage du DS18B20 en mode parasite

Schéma de câblage du DS18B20 en mode normal

Schéma de câblage du DS18B20 en mode normal

Deux branchements possibles, en mode parasite, ce qui revient à utiliser un DS18B20+PAR.

Plus logiquement, l’utilisation du composant en l’alimentant de 5 Volts dans sa patte 3.

Même procédé pour les soudures.

DS18B20 avec connexion 5V DATA et masse

DS18B20 avec connexion 5V DATA et masse

Que celui qui n’a jamais soudé et oublié d’enfiler la gaine thermo me jette la première pierre…
Et encore, je pourrais dire que c’est fait exprès mais il ne faut pas se leurrer, c’est déjà arrivé à tout le monde ! Sauf qu’après une certaine heure, je ne dessoude pas ! Na !

Voila pour la découverte des DS18B20, rien de bien compliqué mais souhaitant parler sur ce blog de la découverte domotique, jusqu’à  l’installation finale, il fallait faire une présentation de ces composants.

Posté dans 1-wire | 3 Commentaires