proceding with vzlogger...

This commit is contained in:
Steffen Vogel 2011-03-25 14:36:51 +01:00
parent 8b068bb44d
commit 08221f7d24
4 changed files with 179 additions and 35 deletions

View file

@ -1 +1,2 @@
*.o
vzlogger

View file

@ -1,5 +1,5 @@
CC=cc
CFLAGS=-c -Wall
CFLAGS=-c -Wall -g
LDFLAGS=
TARGET=vzlogger
@ -9,10 +9,10 @@ clean:
rm -rf *.o
vzlogger: main.c ehz.c
$(CC) $(LDFLAGS) main.o ehz.o -o $(TARGET)
$(CC) $(LDFLAGS) main.o ehz.o `curl-config --libs` -o $(TARGET)
main.c:
$(CC) $(CFLAGS) src/main.c -o main.o
$(CC) $(CFLAGS) src/main.c -o main.o `curl-config --cflags`
ehz.c:
$(CC) $(CFLAGS) src/ehz.c -o ehz.o

View file

@ -23,60 +23,146 @@
* along with volkszaehler.org. If not, see <http://www.gnu.org/licenses/>.
*/
#define VZ_VERSION "0.2"
#include <stdio.h>
#include <getopt.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <unistd.h>
#include <sys/time.h>
#include <curl/curl.h>
#include <curl/types.h>
#include <curl/easy.h>
#include "main.h"
#include "ehz.h"
static struct type types[] = {
// {"1wire", "Dallas 1-Wire Sensors", 1wire_get},
{"ehz", "German \"elektronische Heimzähler\"", ehz_get}
// {"ccost", "CurrentCost", ccost_get},
// {"fusb", "FluksoUSB prototype board", fusb_get}
struct options opt;
static struct device devices[] = {
// {"1wire", "Dallas 1-Wire Sensors", 1wire_get},
// {"ccost", "CurrentCost", ccost_get},
// {"fusb", "FluksoUSB prototype board", fusb_get}
{"ehz", "German \"elektronische Heimzähler\"", ehz_get},
{NULL} /* stop condition for iterator */
};
static struct option long_options[] = {
{"middleware", required_argument, 0, 'm'},
{"uuid", required_argument, 0, 'u'},
{"value", required_argument, 0, 'v'},
{"type", required_argument, 0, 't'},
{"device", required_argument, 0, 'd'},
{"config", required_argument, 0, 'c'},
//{"daemon", required_argument, 0, 'D'},
//{"interval", required_argument, 0, 'i'},
//{"local", no_argument, 0, 'l'},
//{"local-port",required_argument, 0, 'p'},
{"help", no_argument, 0, 'h'},
{"verbose", no_argument, 0, 'v'},
{0} /* stop condition for iterator */
{"middleware", required_argument, 0, 'm'},
{"uuid", required_argument, 0, 'u'},
{"value", required_argument, 0, 'v'},
{"device", required_argument, 0, 'd'},
{"port", required_argument, 0, 'p'},
// {"config", required_argument, 0, 'c'},
{"daemon", required_argument, 0, 'D'},
{"interval", required_argument, 0, 'i'},
// {"local", no_argument, 0, 'l'},
// {"local-port", required_argument, 0, 'p'},
{"help", no_argument, 0, 'h'},
{"verbose", no_argument, 0, 'v'},
{NULL} /* stop condition for iterator */
};
void usage(char ** argv) {
printf("usage: %s [options]\n\n", argv[0]);
printf("\n");
printf(" following options are available\n");
static char * long_options_descs[] = {
"url to middleware",
"channel uuid",
"sensor value or meter consumption to log",
"device type",
"port the device is connected to",
// "config file with channel -> uuid mapping",
"run as daemon",
"interval in seconds to log data",
// "activate local interface (tiny webserver)",
// "TCP port for local interface"
"show this help",
"enable verbose output",
NULL /* stop condition for iterator */
};
void usage(char * argv[]) {
char ** desc = long_options_descs;
struct option * op = long_options;
while (op->name) {
printf("\t--%s,\t-%c\n", op->name, op->val);
struct device * dev = devices;
printf("Usage: %s [options]\n\n", argv[0]);
printf(" following options are available:\n");
while (op->name && desc) {
printf("\t--%-12s\t-%c\t%s\n", op->name, op->val, *desc);
op++;
desc++;
}
printf("\n");
printf(" following device types are available:\n");
while (dev->name) {
printf("\t%-12s\t%s\n", dev->name, dev->desc);
dev++;
}
printf("\nvzlogger - volkszaehler.org logging utility VERSION\n");
printf("by Steffen Vogel <volkszaehler@steffenvogel.de>\n");
}
CURLcode backend_log(char * middleware, char * uuid, struct timeval tv, float value) {
CURL *curl;
CURLcode res;
char url[255], useragent[255], post[255];
sprintf(url, "%s/data/%s.json", middleware, uuid); /* build url */
sprintf(useragent, "vzlogger/%s (%s)", VZ_VERSION, curl_version());
sprintf(post, "?timestamp=%lu%lu&value=%f", tv.tv_sec, tv.tv_usec, value);
curl_global_init(CURL_GLOBAL_ALL);
curl_formadd(&formpost,
&lastptr,
CURLFORM_COPYNAME, "value",
CURLFORM_PTRCONTENTS , value_str,
CURLFORM_END);
curl_formadd(&formpost,
&lastptr,
CURLFORM_COPYNAME, "timestamp",
CURLFORM_PTRCONTENTS , &timestamp,
CURLFORM_END);
curl = curl_easy_init();
if (curl) {
/* what URL that receives this POST */
curl_easy_setopt(curl, CURLOPT_URL, url);
curl_easy_setopt(curl, CURLOPT_HTTPPOST, formpost);
curl_easy_setopt(curl, CURLOPT_USERAGENT, useragent);
curl_easy_setopt(curl, CURLOPT_VERBOSE, (int) opt.verbose);
res = curl_easy_perform(curl);
curl_easy_cleanup(curl); /* always cleanup */
curl_formfree(formpost); /* then cleanup the formpost chain */
return res;
}
return -1;
}
int main(int argc, char * argv[]) {
uint8_t verbose = 0;
/* setting default options */
opt.interval = 300; /* 5 minutes */
/* parse cli arguments */
while (1) {
/* getopt_long stores the option index here. */
int option_index = 0;
int c = getopt_long(argc, argv, "m:u:v:t:d:c:hv", long_options, &option_index);
int c = getopt_long(argc, argv, "i:m:u:v:t:p:c:hdv", long_options, &option_index);
/* detect the end of the options. */
if (c == -1)
@ -84,8 +170,35 @@ int main(int argc, char * argv[]) {
switch (c) {
case 'v':
verbose = 1;
opt.verbose = 1;
break;
case 'd':
opt.daemon = 1;
break;
case 'i':
opt.interval = atoi(optarg);
break;
case 'u':
opt.uuid = (char *) malloc(strlen(optarg)+1);
strcpy(opt.uuid, optarg);
break;
case 'm':
opt.middleware = (char *) malloc(strlen(optarg)+1);
strcpy(opt.middleware, optarg);
break;
case 'p':
opt.port = (char *) malloc(strlen(optarg)+1);
strcpy(opt.port, optarg);
break;
//case 'c': /* read config file */
// break;
case 'h':
case '?':
@ -93,6 +206,28 @@ int main(int argc, char * argv[]) {
exit((c == '?') ? -1 : 0);
}
}
/* setup devices */
struct timeval tv;
log: /* start logging */
gettimeofday(&tv, NULL);
CURLcode rc = backend_log(opt.middleware, opt.uuid, tv, 33.333);
if (rc != CURLE_OK) {
fprintf(stderr, "curl error: %s\n", curl_easy_strerror(rc));
} else if (opt.verbose) {
fprintf(stdout, "logging %s against %s with value %f", opt.uuid, opt.middleware, 33.333);
}
if (opt.daemon) {
sleep(opt.interval);
goto log;
}
return 0;
}

View file

@ -28,13 +28,21 @@
typedef float (*rfp)();
struct type {
char name[8];
char desc[50];
struct device {
char * name;
char * desc;
rfp read_fnct;
};
struct options {
char * uuid; /* universal unique channel identifier */
char * middleware; /* url to middleware server */
char * port; /* port your sensor is connected to */
unsigned interval; /* interval in seconds, the daemon send data */
unsigned verbose:1; /* boolean bitfield, at the end of struct */
unsigned daemon:1; /* boolean bitfield */
};
void usage(char ** argv);
void config_read(char * file);
#endif /* _MAIN_H_ */