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
- Wrt54gl
- interface 1-wire (Bus 1-wire sur Linksys Wrt54gl)
- Sondes 1-wire DS18B20
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
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