Outils pour utilisateurs

Outils du site


informatique:arduino:collectd_packet

CollectdPacket

CollectdPacket est une librairie pour Arduino permettant de créer des paquets UDP pour collectd.

Beaucoup de tutoriels Arduino montrent des fonctionnement où des données sont captées puis inscrites dans des fichiers ou bien envoyées vers des serveurs en PHP pour les afficher… L'idée de cette librairie est de pouvoir exploiter des données sur un système de métrologie centralisé.

Dès lors que votre carte Arduino possède une interface réseau (filaire ou wifi), il vous sera possible d'envoyer vos données vers un serveur collectd 8-)

Tout le fonctionnement de cette classe est basé sur la documentation du protocole binaire de collectd.

Documentation

Voici quelques explications sur les différentes méthodes publiques de la classe.

Les notions de 'plugin', 'instances', 'types' etc… sont directement reprises du format utilisé par le protocole binaire de collectd.

Ne pas hésitez à s'y référer pour plus d'explications sur leur signification.

Les explications/exemples donnés ici sont uniquement destinées à faciliter la compréhension de la classe CollectPacket mais ne sont en aucun cas une référence sur le fonctionnement de Collectd.

Syntaxe de la classe et ses méthodes publiques
class CollectdPacket
{
    public:
        CollectdPacket( const char *hostname, unsigned long interval );
        void addPlugin( const char *plugin );
        void addPluginInstance( const char *instance );
        void addType( const char *type );
        void addTypeInstance( const char *instance );
        void addTimestamp( unsigned long timestamp );
        void addTimestampHR( unsigned long timestamp );
        void addValue( byte type, float value );
 
        word getPacketSize( void );
        byte *getPacketBuffer( void );
        void resetPacket( void );
}

addPlugin

Nom du plugin auquel seront affectées les données.

Syntaxe
void addPlugin( const char *plugin );
Exemple
addPlugin( "temperature" );

addPluginInstance

Nom de l'instance du plugin auquel seront affectées les données dans le cas ou il y a plusieurs mesures pour un même plugin (plusieurs capteurs différents).

Syntaxe
void addPluginInstance( const char *instance );
Exemple
addPlugin( "temperature" );
addPluginInstance( "sensor1" );
// code to get data from sensor 1
addPluginInstance( "sensor2" );
// code to get data from sensor 2

addType

Type de données de la mesure. Cette méthode peu être utilisée quand une sonde permet de renvoyer plusieurs type différents de données.

Syntaxe
void addType( const char *type );
Exemple
addPlugin( "THN132N" );         // Oregon scientifics humidity and temp sensor
addType( "temperature" );
// code to get the temperature from sensor
addType( "humidity" );
// Code to get humidity from sensor

addTypeInstance

Instance utilisée par le 'type' de données de la mesure. Cette méthode peu être utilisée quand une sonde permet de renvoyer plusieurs sous types de données.

Syntaxe
void addTypeInstance( const char *instance );
Exemple
addPlugin( "Sensor" );
addType( "power" );      // Example sensor that mesures electrical power
addTypeInstance( "watts" );
// code that get the power in watts from sensor
addTypeInstance( "amperes" );
// code that get the power in amperes from sensor

addTimestamp

Permet d'horodater le paquet. La date est exprimée en secondes depuis le 1er janvier 1900.

Syntaxe
void addTimestamp( unsigned long timestamp );

Depuis les versions récentes de Collectd (version 5) cette fonction n'est plus utilisée et est remplacée par la version 'HR' (high resolution).

→ Voir la fonction addTimestampHR

addTimestampHR

Permet d'horodater le paquet. La date est exprimée en secondes depuis le 1er janvier 1900. Cette date peu être récupérée via un serveur NTP par exemple.

Syntaxe
void addTimestampHR( unsigned long timestamp );

addValue

Cette méthode permet d'ajouter les valeurs collectées au paquet. Elle prend deux arguments, le type de donnée et la donnée elle même.

Les types sont des constantes définies comme suit :

  • VALUE_TYPE_COUNTER
  • VALUE_TYPE_GAUGE
  • VALUE_TYPE_DERIVE
  • VALUE_TYPE_ABSOLUTE

Ces types sont directement issus des types de données supportées par RRDTool (format de stockage de Collectd).

Syntaxe
void addValue( byte type, float value );
Exemple
addPlugin( "temperature" );
addPluginInstance( "sensor1" );
// code to get data from sensor 1
addValue( VALUE_TYPE_GAUGE, sensor1_temp );
addPluginInstance( "sensor2" );
// code to get data from sensor 2
addValue( VALUE_TYPE_GAUGE, sensor2_temp );

getPacketSize

Renvoie la taille du paquet Collectd généré (exprimé en octets).

Syntaxe
word getPacketSize( void );

getPacketBuffer

Renvoi le contenu du paquet Collectd. C'est ce contenu qui doit être envoyé au serveur.

Syntaxe
byte *getPacketBuffer( void );

resetPacket

ré-initialise le paquet Collectd afin de recommencer un cycle. Cette méthode est utile lorsque vous utilisez la même instance d'un paquet dans une boucle. Cette méthode vide le contenu du paquet en conservant les paramètres utilisés lors de sa création (client name et interval).

Syntaxe
void resetPacket( void );

Exemple d'utilisation

L'exemple ci-dessous met en oeuvre un capteur de température Dallas 1-wire DS18S20 pour effectuer des relevés et les envoyer vers un serveur Collectd. Le capteur de température est relié à la broche 8 de l'Arduino qui est équipé d'un ethernet shield pour la communication réseau.

arduino_collectd_example.ino
#include <Ethernet.h>
#include <EthernetUdp.h>
#include <OneWire.h>
#include <SPI.h>
 
#include <CollectdPacket.h>
#include "ntp_client.h"      # Another personal library ;-)
 
// The device id of a DS18S20 is 0x10
#define DS18S20 0x10
 
CollectdPacket packet( "Arduino", 30 );   // Init 'CollectdPacket' class with :
                                          //   client name = Arduino
                                          //   interval    = 30s
 
OneWire        ds18s20( 8 );              // Init the OneWire on pin 8
 
static byte mac[]         = { 0x00, 0x04, 0x25 , 0x15, 0x48, 0x12 };
static byte ip[]          = { 10, 1, 1, 40 };
static byte collectd_ip[] = { 10, 1, 1, 100 };
static byte ntp_ip[]      = { 10, 1, 1, 254 };
 
// Init the UDP instance
EthernetUDP udp_handler;
 
void setup()
{
    Serial.begin( 9600 );
    Serial.println( "Initialized a packet for 'Arduino' with interval 30" );
 
    Ethernet.begin( mac, ip );
    udp_handler.begin( 8888 );     // Start an UDP instance listening on port 8888
}
 
void loop()
{
    float temperature;
    byte ds_addr[8];
    byte ds_buffer[12];
    char ds_idstr[17];   // 16 chars + \0
 
    // Search for the Dallas sensor until found
    while ( ! ds18s20.search( ds_addr ) )
    {
        ds18s20.reset_search();
        delay( 250 );
    }
 
    // Not so beautiful but just for DEBUGING purpose... 8-)
    sprintf( ds_idstr, "%02x%02x%02x%02x%02x%02x%02x%02x", ds_addr[0], ds_addr[1], ds_addr[2], ds_addr[3], ds_addr[4], ds_addr[5], ds_addr[6], ds_addr[7] );
    Serial.print( "Found sensor id : " );
    Serial.println( ds_idstr );
 
    if ( ds_addr[0] != DS18S20 )
    {
        Serial.println( "Found sensor is not a DS18S20, skipping" );
        return;
    }
 
    if ( OneWire::crc8( ds_addr, 7 ) != ds_addr[7] )
    {
        Serial.println("CRC is not valid, skipping...");
        return;
    }
 
    // Send a mesure command to the sensor
    ds18s20.reset();
    ds18s20.select( ds_addr );
    ds18s20.write( 0x44, 1 );
 
    // Wait for conversion to finish (~750ms)
    // There is no reason to wait it, but as this program is an example
    // we can proceed that way.
 
    delay( 800 );
 
    // Retrieve mesured data
    ds18s20.reset();
    ds18s20.select( ds_addr );    
    ds18s20.write( 0xBE );      // Read the scratchpad
    ds18s20.read_bytes( ds_buffer, 9 );
 
    unsigned int raw = ( ds_buffer[1] << 8 ) | ds_buffer[0];
 
    raw = raw << 3;             // 9 bit resolution default
    if ( ds_buffer[7] == 0x10 )
    {
        // count remain gives full 12 bit resolution
        raw = ( raw & 0xFFF0 ) + 12 - ds_buffer[6];
    }
 
    temperature = (float) raw / 16.0;
    Serial.print( "Sensor temperature : " );
    Serial.println( temperature );
 
    Serial.println( "Resetting packet..." );
    packet.resetPacket();
    packet.addTimestampHR( GetTimeFromNTPServer( ntp_ip, 5 ) );
 
    packet.addPlugin( "sensors" );
    packet.addPluginInstance( "ds18s20" );  // Could be 'ds_idstr' if you want...
    packet.addType( "temperature" );
    packet.addValue( VALUE_TYPE_GAUGE, temperature );
 
    Serial.print( "Generated a packet of " );
    Serial.print( packet.getPacketSize() );
    Serial.println( " bytes" );
 
    Serial.print( "Sending packet to 10.1.1." );
    Serial.println( collectd_ip[3] );
    udp_handler.beginPacket( collectd_ip, 25826 );
    udp_handler.write( packet.getPacketBuffer(), packet.getPacketSize() );
    udp_handler.endPacket();
 
    delay( 29 * 1000 ); // Sleep 29 seconds  (30s - 800ms... ;)) 
}

Cet exemple, permet de faire de jolis graphiques tels que celui-ci : :-)

Téléchargement

informatique/arduino/collectd_packet.txt · Dernière modification : 2022/11/27 17:21 de lestat

Outils de la page