Acquisition senseurs 1-wire Wrt54gl par messages xPL

De MicElectroLinGenMet.

Sommaire

Description

Programme C tournant sur le Wrt54gl pour envoyer les données de capteurs 1-wire par Xpl. Compilé avec le SDK de OpenWrt Kamikaze 8.09

Reprise du programme sur Fonera: Acquisition senseurs I2C Fonera par messages xPL


Partie matériel


Partie logiciel

  • OpenWrt Kamikaze 8.09 (doit pouvoir fonctionner aussi sur WhiteRussian)
  • Pakages owfs (disponible avec OpenWrt Kamikaze)
owserver - 2.7p13-1 - 
owshell - 2.7p13-1 - 
owfs - 2.7p13-1 - 

Le binaire owread du package owshell est utilisé par le programme pour lire les sondes DS18B20.


Programme

Ci-dessous source C du programme à compiler avec le SDK OpenWrt
Une fois compiler le programme est simplement lancé en crontab du Wrt54gl toutes les minutes.


Si mode debug activé, le programme affiche les valeurs lus sur les capteurs et les messages xPL envoyés.

root@wrt54gl:/tmp# ./xpl-owfs 
cmd: /usr/bin/owread -s localhost:4304 28.FC1D80010000/temperature
Temp:        -19.5
xpl-stat
{
hop=1
source=domos-wrt54gl.owfs
target=*
}
sensor.basic
{
device=28.FC1D80010000
type=temp
current=-19.5
}

cmd: /usr/bin/owread -s localhost:4304 28.281080010000/temperature
Temp:      18.5625
xpl-stat
{
hop=1 
source=domos-wrt54gl.owfs
target=*
}
sensor.basic
{
device=28.281080010000
type=temp
current=18.6
}


Messages xPL reçus avec un xPL_Logger

09/09/03 23:30:37 xpl-trig {bnz-rfxcomrx.vesta *} sensor.basic { device='thn132n.20' type='temp' current='18.8' }
09/09/03 23:30:37 xpl-trig {bnz-rfxcomrx.vesta *} sensor.basic { device='thn132n.20' type='battery' current='90' units='%' }
09/09/03 23:31:03 xpl-stat {domos-wrt54gl.owfs *} sensor.basic { device='28.FC1D80010000' type='temp' current='-18.8' }
09/09/03 23:31:03 xpl-stat {domos-wrt54gl.owfs *} sensor.basic { device='28.281080010000' type='temp' current='18.5' }
09/09/03 23:31:13 xpl-trig {bnz-rfxcomrx.vesta *} sensor.basic { device='thgr228n.6f' type='temp' current='13.9' }
09/09/03 23:31:13 xpl-trig {bnz-rfxcomrx.vesta *} sensor.basic { device='thgr228n.6f' type='humidity' current='70' string='normal' }
09/09/03 23:31:13 xpl-trig {bnz-rfxcomrx.vesta *} sensor.basic { device='thgr228n.6f' type='battery' current='90' units='%' }


Exemples de graphes générés par xpl-rrd


Sonde température congélateur
Sonde température garage


Source

Voir version améliorée utilisant la libowapi de owfs: Dockstar xpl-owfs.c

/*------------------------------------------------------------------------------*/
/* xpl-owfs */
/*------------------------------------------------------------------------------*/
 
/* 
3/9/2009
Lecture sondes 1-wire DS18B20 sur Wrt54gl et envoie données par message xPL.
Compiler sous SDK OpenWrt Kamikaze 8.09.
 
09/09/03 23:30:34 xpl-trig {bnz-rfxcomrx.vesta *} sensor.basic { device='thgr228n.6f' type='battery' current='90' units='%' }
09/09/03 23:30:37 xpl-trig {bnz-rfxcomrx.vesta *} sensor.basic { device='thn132n.20' type='temp' current='18.8' }
09/09/03 23:30:37 xpl-trig {bnz-rfxcomrx.vesta *} sensor.basic { device='thn132n.20' type='battery' current='90' units='%' }
09/09/03 23:31:03 xpl-stat {domos-wrt54gl.owfs *} sensor.basic { device='28.FC1D80010000' type='temp' current='-18.8' }
09/09/03 23:31:03 xpl-stat {domos-wrt54gl.owfs *} sensor.basic { device='28.281080010000' type='temp' current='18.5' }
09/09/03 23:31:13 xpl-trig {bnz-rfxcomrx.vesta *} sensor.basic { device='thgr228n.6f' type='temp' current='13.9' }
09/09/03 23:31:13 xpl-trig {bnz-rfxcomrx.vesta *} sensor.basic { device='thgr228n.6f' type='humidity' current='70' string='normal' }
09/09/03 23:31:13 xpl-trig {bnz-rfxcomrx.vesta *} sensor.basic { device='thgr228n.6f' type='battery' current='90' units='%' }
09/09/03 23:31:16 xpl-trig {bnz-rfxcomrx.vesta *} sensor.basic { device='thn132n.20' type='temp' current='18.8' }
09/09/03 23:31:16 xpl-trig {bnz-rfxcomrx.vesta *} sensor.basic { device='thn132n.20' type='battery' current='90' units='%' }
*/
 
 
/*------------------------------------------------------------------------------*/
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <time.h>
#include <syslog.h>
#include <errno.h>
#include <sys/fcntl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
 
#define BROADCASTIP "192.168.0.255"	// Adr. de broadcast sur réseau local.
#define HUBPORT	3865			// Port HUB xPL
 
#define XPLMSGSOURCE "domos-wrt54gl.owfs"
#define XPLMSGTARGET "*"
 
#define OWFSHOST "localhost"
#define SENSEUR1 "28.FC1D80010000"
#define SENSEUR2 "28.281080010000"
 
 
// Variables socket
int sockxpl ;
struct sockaddr_in address ;
int enabled = 1 ;
 
// Déclaration commande exécutée.
char    cmdresult[32768];
 
// Flags
int debug = 0 ;
 
/*------------------------------------------------------------------------------*/
/* Fonctions execute commande							*/
/*------------------------------------------------------------------------------*/
int ExecCommand(char cmd[], char *buf)
{
	FILE    *processpipe_fp;        //Utilisation d'un pipe entre processus pour executer des commandes externes.
	int     lecture_pipe ;
 
        if (debug) printf("cmd: %s\n", cmd) ;
        errno = 0 ;
        if ( (processpipe_fp = popen(cmd, "r") ) == NULL )
        {
                syslog(LOG_ERR, "Erreur ouverture pipe sur commande '%s', %s !", cmd, strerror(errno)) ;
                return 0 ;
        }
        else
        {
                // Execute cmd.
                lecture_pipe = fread(buf, sizeof(char), BUFSIZ, processpipe_fp);
		pclose(processpipe_fp) ;
		return lecture_pipe ;   // Return 0 (erreur) si lecture vide.
        }
}
 
//-----------------------------------------------------------------------------
int ExecCommandOwread(char senseur[], char fichier[], char *reponse)
{
        char command[256]  ;
 	char *psautdeligne ;
 
//	sprintf(command, "/usr/local/bin/owread -s %s:4304 %s/%s", OWFSHOST, senseur, fichier) ; 
	sprintf(command, "/usr/bin/owread -s %s:4304 %s/%s", OWFSHOST, senseur, fichier) ; 
        memset(reponse, '\0', sizeof(reponse));
        if ( ExecCommand(command, reponse) )
        {
                if ( (psautdeligne=strchr(reponse,'\n')) )
                        psautdeligne[0] = '\0' ;     		//Remplace \n par '\0', une seule ligne lue.
                return 1 ;
        }
        else return 0 ;
}
 
/*------------------------------------------------------------------------------*/
/* Fonctions socket 								*/
/*------------------------------------------------------------------------------*/
int sockxpl_init()
{
	/* Create the UDP socket */
	int socketudp ;
	if ((socketudp = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
	{
		syslog(LOG_ERR, "Erreur ouverture socket: %s (%d)\n", strerror(errno), errno) ;
		exit(EXIT_FAILURE) ;
	}
 
	setsockopt(socketudp, SOL_SOCKET, SO_BROADCAST, &enabled, sizeof enabled) ; //Droit broadcast.
 
	/* Construct the server sockaddr_in structure */
	memset(&address, 0, sizeof(address));       		/* Clear struct */
	address.sin_family = AF_INET;                  		/* Internet/IP */
	address.sin_addr.s_addr = inet_addr(BROADCASTIP);	/* IP address */
	address.sin_port = htons(HUBPORT);       		/* Hub port */
 
	return socketudp ;
}
 
 
// Broadcast message xpl
int sendxplmsg(char msg[])
{
	/* Send the msg to the server */
	int msglen ;
	msglen = strlen(msg);
	if (debug) printf("%s\n", msg) ;
	if (sendto(sockxpl, msg, msglen, 0, (struct sockaddr *) &address, sizeof(address) ) != msglen)
	{
		syslog(LOG_ERR, "Erreur envoie message xPL: %s (%d)\n", strerror(errno), errno) ;
		return 0 ;
	}
	return 1 ;
}
 
// Broadcast message sensor.basic xpl
int sendxplsensorbasicmsg(char msgtype[],char device[], char type[], char current[])
{
	char msg[1024] ;
	char msgheader[512] ;
 
	// Entête du message
	sprintf( msgheader, "%s\n{\nhop=1\nsource=%s\ntarget=%s\n}\nsensor.basic\n{\n", msgtype, XPLMSGSOURCE, XPLMSGTARGET) ;
 
	sprintf( msg, "%sdevice=%s\ntype=%s\ncurrent=%s\n}\n", msgheader, device, type, current) ;
	if ( sendxplmsg(msg) ) return 1 ;
		else return 0 ;
}
 
/*------------------------------------------------------------------------------*/
/* Main                                                                         */
/*------------------------------------------------------------------------------*/
int main(int argc, char *argv[])
{
 char tempsenseur[32] ;
 
 openlog("xpl-owfs", LOG_PID, LOG_USER) ;
 
 // Init socket.
 sockxpl = sockxpl_init() ;
 
 // lecture sondes 1-wire et envoie message xPL.
 if ( ExecCommandOwread(SENSEUR1, "temperature", cmdresult) )
 {
        if (debug) printf("Temp: %s\n", cmdresult) ;
	sprintf(tempsenseur, "%2.1f", atof(cmdresult) ); 
	sendxplsensorbasicmsg("xpl-stat", SENSEUR1, "temp", tempsenseur) ;
 }
 else syslog(LOG_ERR, "Erreur lecture owfs %s\n", SENSEUR1) ;
 
 if ( ExecCommandOwread(SENSEUR2, "temperature", cmdresult) )
 {
        if (debug) printf("Temp: %s\n", cmdresult) ;
	sprintf(tempsenseur, "%2.1f", atof(cmdresult) ); 
	sendxplsensorbasicmsg("xpl-stat", SENSEUR2, "temp", tempsenseur) ;
 }
 else syslog(LOG_ERR, "Erreur lecture owfs %s\n", SENSEUR2) ;
 
 close(sockxpl) ;
 
 return 0 ;
}



3/9/2009