commenting

git-svn-id: file:///home/jan/tmp/wetterstation/trunk@103 dd492736-c11a-0410-ad51-8c26713eaf7f
This commit is contained in:
losinshi 2006-09-17 23:39:09 +00:00
parent 0b1912639b
commit 738cf5ff26
16 changed files with 422 additions and 158 deletions

View File

@ -26,46 +26,51 @@
#include <sys/wait.h> #include <sys/wait.h>
#include <unistd.h> #include <unistd.h>
#include <signal.h> #include <signal.h>
#include "definitions.h" #include "definitions.h"
#include "config.h" #include "config.h"
#include "chart.h" #include "chart.h"
#include "common.h" #include "common.h"
#include "image_file/image_file.h" #include "image_file/image_file.h"
static int walk_image_cfg_list(); static int walk_image_cfg_list(); /* Definition fuer walk_image_cfg_list */
static void wait_for_childs(); static void wait_for_childs(); /* Definition fuer wait_for_childs */
config global_opts;
config global_opts; /* Globale Optionen */
/* Geht die Bilder-Configs durch und startet das
* Generieren der Bilder
* Rueckgabe: Anzahl der Childs die Geforkt wurden */
static int walk_image_cfg_list(){ static int walk_image_cfg_list(){
int has_forked = 0; int has_forked = 0; /* Zaehler der Childs */
pid_t pid = 0; pid_t pid = 0; /* Temporaer abgespeicherte Pid */
image_cfg_list_ptr tmp_ptr = global_opts.image_cfg; image_cfg_list_ptr tmp_ptr = global_opts.image_cfg; /* Hilfszeiger auf das aktuelle element der Config-Liste */
for(; tmp_ptr; tmp_ptr = tmp_ptr->next){ for(; tmp_ptr; tmp_ptr = tmp_ptr->next){ /* Configliste durchgehen */
if(global_opts.fork){ if(global_opts.fork){ /* Wenn geforkt werden soll */
if((pid = fork()) == 0){ if((pid = fork()) == 0){ /* Unterscheidung ob im Child oder im Parent */
clear_clean(); clear_clean(); /* Wenn im Child, dann die Clean-Liste leeren */
process_image_cfg(tmp_ptr->image_cfg_file); process_image_cfg(tmp_ptr->image_cfg_file); /* Bild generieren */
exit(EXIT_SUCCESS); exit(EXIT_SUCCESS); /* und Child beenden */
} }
else if (pid == -1){ else if (pid == -1){ /* Probleme beim Fork */
exit_error(ERROR_FORK); exit_error(ERROR_FORK);
} }
if(!has_forked){ if(!has_forked){ /* beim ersten durchlauf die warte-funktion an die Clean-Liste anhaengen */
add_clean(wait_for_childs, NULL); add_clean(wait_for_childs, NULL);
} }
has_forked++; has_forked++; /* Den fork-zaehler erhoehen */
DEBUGOUT2("Prozess %d angelegt\n",pid); DEBUGOUT2("Prozess %d angelegt\n",pid);
} else { } else { /* Wenn nicht geforkt werden soll */
process_image_cfg(tmp_ptr->image_cfg_file); process_image_cfg(tmp_ptr->image_cfg_file); /* dann so das Bild generieren */
} }
} }
return has_forked; return has_forked;
} }
/* Wartet auf gestartete Child-Prozesse */
static void wait_for_childs(void *dummy){ static void wait_for_childs(void *dummy){
int ret_val; int ret_val;
pid_t pid; pid_t pid;
@ -74,7 +79,10 @@ static void wait_for_childs(void *dummy){
} }
} }
/* Main - Funktion */
int main(int argc, char *argv[]){ int main(int argc, char *argv[]){
DEBUGOUT1("Programm gestartet\n"); DEBUGOUT1("Programm gestartet\n");
if(signal(SIGABRT, exit_sig_handler) == SIG_ERR) if(signal(SIGABRT, exit_sig_handler) == SIG_ERR)
@ -90,6 +98,7 @@ int main(int argc, char *argv[]){
exit_error(ERROR_SEIINST); exit_error(ERROR_SEIINST);
DEBUGOUT1("Signalhandler zum beenden per SIGTERM installiert\n"); DEBUGOUT1("Signalhandler zum beenden per SIGTERM installiert\n");
/* Haupt-Config einlesen */
read_config(DEFAULT_CONFIG_FILE, 1, NULL); read_config(DEFAULT_CONFIG_FILE, 1, NULL);
/* Debug-Ausgaben, um zu sehen, ob die Optionen richtig gesetzt werden */ /* Debug-Ausgaben, um zu sehen, ob die Optionen richtig gesetzt werden */
@ -104,6 +113,7 @@ int main(int argc, char *argv[]){
DEBUGOUT2(" Datenbank = %s\n",global_opts.pg_database); DEBUGOUT2(" Datenbank = %s\n",global_opts.pg_database);
DEBUGOUT2(" Timeout = %s\n",global_opts.pg_database); DEBUGOUT2(" Timeout = %s\n",global_opts.pg_database);
/* Bilder - Configs durchgehen */
if(walk_image_cfg_list()) if(walk_image_cfg_list())
wait_for_childs(NULL); wait_for_childs(NULL);

View File

@ -56,6 +56,7 @@ void add_clean(clean_func_t func, void *data){
} }
} }
/* Zuletzt angefuegtes Clean - Element entfernen */
void remove_clean(){ void remove_clean(){
clean_struct_ptr temp = clean_ptr; clean_struct_ptr temp = clean_ptr;
if (temp != NULL){ if (temp != NULL){
@ -64,6 +65,7 @@ void remove_clean(){
} }
} }
/* Clean - Liste leeren */
void clear_clean(){ void clear_clean(){
while(clean_ptr != NULL){ while(clean_ptr != NULL){
remove_clean(); remove_clean();

View File

@ -22,12 +22,14 @@
#include "definitions.h" #include "definitions.h"
/* Liste der Bilder - Configs */
typedef struct image_cfg_list_t *image_cfg_list_ptr; typedef struct image_cfg_list_t *image_cfg_list_ptr;
typedef struct image_cfg_list_t { typedef struct image_cfg_list_t {
char *image_cfg_file; char *image_cfg_file;
image_cfg_list_ptr next; image_cfg_list_ptr next;
} image_cfg_list; } image_cfg_list;
/* Globale Config */
typedef struct config_t { typedef struct config_t {
char *pg_host; char *pg_host;
char *pg_database; char *pg_database;
@ -40,8 +42,11 @@ typedef struct config_t {
int fork; int fork;
} config; } config;
/* Prototyp einer Finktion, die addclean() uebergeben
* wird. */
typedef void (*clean_func_t)(void *data); typedef void (*clean_func_t)(void *data);
/* Clean - Liste */
typedef struct clean_struct *clean_struct_ptr; typedef struct clean_struct *clean_struct_ptr;
typedef struct clean_struct { typedef struct clean_struct {
void *data; void *data;
@ -50,7 +55,7 @@ typedef struct clean_struct {
} clean_data; } clean_data;
/* Globale Optionen */
extern config global_opts; extern config global_opts;
/* Funktionen -------------------------------------------------------------*/ /* Funktionen -------------------------------------------------------------*/
@ -65,7 +70,7 @@ void exit_sig_handler(int);
/* Eine (neuste) Clean-Funktion entfernen */ /* Eine (neuste) Clean-Funktion entfernen */
void remove_clean(); void remove_clean();
/* Eine Clean-Funktion hinzufügen */ /* Eine Clean-Funktion hinzufuegen */
void add_clean(clean_func_t , void *); void add_clean(clean_func_t , void *);
/* Alle clean-Funktionen entfernen */ /* Alle clean-Funktionen entfernen */

View File

@ -38,7 +38,7 @@
static int add_image_cfg(const char *, void *); static int add_image_cfg(const char *, void *);
/* Zuordnung zwischen Schlüsselwörtern in der Config, Der Funktion, die diese auswertet /* Zuordnung zwischen Schluesselwoertern in der Config, Der Funktion, die diese auswertet
* und dem eld in der Options-Struktur */ * und dem eld in der Options-Struktur */
static const config_keyword dflt_keywords[] = { static const config_keyword dflt_keywords[] = {
/* keyword handler variable address default */ /* keyword handler variable address default */
@ -126,7 +126,7 @@ int read_config(char *file, int reset, const config_keyword *keywords){
if(keywords == NULL) if(keywords == NULL)
keywords = (config_keyword *)dflt_keywords; keywords = (config_keyword *)dflt_keywords;
/* Optionen mit default-werten füllen */ /* Optionen mit default-werten fuellen */
if(reset){ if(reset){
for (i = 0; keywords[i].keyword[0]; i++) for (i = 0; keywords[i].keyword[0]; i++)
//printf("keyword: %s \n",keywords[i].keyword); //printf("keyword: %s \n",keywords[i].keyword);
@ -134,9 +134,9 @@ int read_config(char *file, int reset, const config_keyword *keywords){
keywords[i].handler(keywords[i].def, keywords[i].var); keywords[i].handler(keywords[i].def, keywords[i].var);
} }
/* config-file öffnen */ /* config-file oeffnen */
if (!(in = fopen(file, "r"))) { if (!(in = fopen(file, "r"))) {
DEBUGOUT2("Kann Config-File: '%s' nicht öffnen!\n", file); DEBUGOUT2("Kann Config-File: '%s' nicht oeffnen!\n", file);
return 0; return 0;
} }
@ -144,10 +144,10 @@ int read_config(char *file, int reset, const config_keyword *keywords){
while (fgets(buffer, CONFIG_BUFFERSIZE, in)) { while (fgets(buffer, CONFIG_BUFFERSIZE, in)) {
lm++; lm++;
/* Zeilenvorschübe gegen null-terminierungs-Zeichen ersetzen */ /* Zeilenvorschuebe gegen null-terminierungs-Zeichen ersetzen */
if (strchr(buffer, '\n')) *(strchr(buffer, '\n')) = '\0'; if (strchr(buffer, '\n')) *(strchr(buffer, '\n')) = '\0';
/* Originlzeile für eventuelle log-, bzw. debug-meldungen */ /* Originlzeile fuer eventuelle log-, bzw. debug-meldungen */
strcpy(orig, buffer); strcpy(orig, buffer);
/* Kommentazeichen gegen null-terminierungs-Zeichen ersetzen und damit alles dahinter ignorieren */ /* Kommentazeichen gegen null-terminierungs-Zeichen ersetzen und damit alles dahinter ignorieren */

View File

@ -35,6 +35,6 @@ typedef struct config_keyword_t {
int read_config(char *, int , const config_keyword *); int read_config(char *, int , const config_keyword *);
/* Config-Zeilen auswerten */ /* Config-Zeilen auswerten */
int read_str(const char *, void *); int read_str(const char *, void *); /* Einen String lesen */
int read_int(const char *, void *); int read_int(const char *, void *); /* Einen int lesen */
int read_yn(const char *, void *); int read_yn(const char *, void *); /* Ein yes/no in 1/0 umwandeln */

View File

@ -49,6 +49,7 @@
#define DEFAULT_X_FORMAT "%H:%M" #define DEFAULT_X_FORMAT "%H:%M"
#define DEFAULT_X_FORMAT_EXTRA "%d.%m.%y| %H:%M" #define DEFAULT_X_FORMAT_EXTRA "%d.%m.%y| %H:%M"
/* Image-Default-Farben ---------------------------------------------- */
#define DEFAULT_BG_COLOR "DF:DF:EF:00" #define DEFAULT_BG_COLOR "DF:DF:EF:00"
#define DEFAULT_DIA_BG_COLOR "F0:A0:D0:D0" #define DEFAULT_DIA_BG_COLOR "F0:A0:D0:D0"
#define DEFAULT_ZERO_LINE_COLOR "BF:80:80:40" #define DEFAULT_ZERO_LINE_COLOR "BF:80:80:40"
@ -65,20 +66,20 @@
/*Alle möglichen Definitionen, die in allen code-schnipseln benötigt werden*/ /*Alle moeglichen Definitionen, die in allen code-schnipseln benoetigt werden*/
/* Fehlermeldungen ------------------------------------------------------*/ /* Fehlermeldungen ------------------------------------------------------*/
#define ERROR_SEIINST "Signal-Fehler: Kann Signalhandler zum beenden nicht installieren\n" #define ERROR_SEIINST "Signal-Fehler: Kann Signalhandler zum beenden nicht installieren\n"
#define ERROR_FORK "Fork-Fehler: Kann keinen neuen Prozess anlegen\n" #define ERROR_FORK "Fork-Fehler: Kann keinen neuen Prozess anlegen\n"
#define ERROR_STAT "Kann Stat nicht ausführen\n" #define ERROR_STAT "Kann Stat nicht ausfuehren\n"
#define ERROR_MAKECONN "PgSQL-Fehler: Kann Datenbankverbindung nicht herstellen\n" #define ERROR_MAKECONN "PgSQL-Fehler: Kann Datenbankverbindung nicht herstellen\n"
#define ERROR_QUERY "PgSQL-Fehler: Kann query nicht sudführen \n" #define ERROR_QUERY "PgSQL-Fehler: Kann query nicht ausfuehren \n"
/* Puffergrößen -------------------------------------------------------- */ /* Puffergroeßen -------------------------------------------------------- */
#define CONFIG_BUFFERSIZE 512 /* Größe des Puffers zum Config-einlesen */ #define CONFIG_BUFFERSIZE 512 /* Groeße des Puffers zum Config-einlesen */
#define QUERY_BUFFERSIZE 512 /* Größe des Zeichenpuffers für SQL-Anfragen */ #define QUERY_BUFFERSIZE 512 /* Groeße des Zeichenpuffers fuer SQL-Anfragen */
/* Verschiedenes ------------------------------------------------------- */ /* Verschiedenes ------------------------------------------------------- */

View File

@ -1,2 +1,23 @@
/*
chart.c -- Part of Chart-generator for the weatherstation
Copyright (C) 2006 Jan Losinski
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "image_common.h" #include "image_common.h"

View File

@ -1,34 +1,60 @@
/*
image_common.h -- Part of Chart-generator for the weatherstation
Copyright (C) 2006 Jan Losinski
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* Repraesentiert eine Farbe */
typedef struct img_color *img_color_ptr; typedef struct img_color *img_color_ptr;
typedef struct img_color { typedef struct img_color {
int r; int r; /* Rotanteil */
int g; int g; /* Gruenanteil */
int b; int b; /* Blauanteil */
int alpha; int alpha; /* Alphawert */
} img_color_t; } img_color_t;
typedef struct image_cfg {
char *file_name;
char *headline;
char *table_field;
int manual_table;
char *table_name;
long gen_interval;
long show_interval;
long label_interval;
int label_sum;
int width;
int height;
char *unit;
char *x_desc;
char *y_desc;
int sens_id;
double val_koeff;
char *x_fmt_extra;
char *x_fmt;
int zero_min;
int bars;
int dflt_dir;
/* Config eines Bildes */
typedef struct image_cfg {
char *file_name; /* Filename des Bildes */
char *headline; /* Ueberschrift */
char *table_field; /* Feldname in der Tabelle */
int manual_table; /* Tabelle manuell angeben */
char *table_name; /* manueller Tabellenname */
long gen_interval; /* Generierungsinterval */
long show_interval; /* Anzeigeinterval */
long label_interval; /* Label - Interval */
int label_sum; /* Sollen Werte aufsummiert statt gemittelt werden */
int width; /* Breite */
int height; /* Hoehe */
char *unit; /* Einheit, die an die Skala angehangen werden soll */
char *x_desc; /* Beschreibung der X - Achse */
char *y_desc; /* Beschreibung der Y - Achse */
int sens_id; /* Id des Sensors */
double val_koeff; /* Faktir mit dem die Werte multipliziert werden sollen */
char *x_fmt_extra; /* Formatstring fuer die erste und letzte Zeit */
char *x_fmt; /* Formatstring fuer die restlichen Labels */
int zero_min; /* Nullinie auf jeden Fall anzeigen */
int bars; /* Balken malen statt einer Linie */
int dflt_dir; /* Standart - Verzeichnis fuer die Bilder */
/* Farben */
img_color_ptr bg_color; img_color_ptr bg_color;
img_color_ptr dia_bg_color; img_color_ptr dia_bg_color;
img_color_ptr dia_line_color; img_color_ptr dia_line_color;
@ -42,8 +68,7 @@ typedef struct image_cfg {
img_color_ptr label_y_color; img_color_ptr label_y_color;
img_color_ptr desc_x_color; img_color_ptr desc_x_color;
img_color_ptr desc_y_color; img_color_ptr desc_y_color;
} image_cfg_t; } image_cfg_t;
/* Entfaelt die aktuelle Bild - Config */
extern image_cfg_t img_cfg; extern image_cfg_t img_cfg;

View File

@ -1,6 +1,6 @@
/* /*
chart.c -- Part of Chart-generator for the weatherstation image_config.c -- Part of Chart-generator for the weatherstation
Copyright (C) 2006 Jan Losinski Copyright (C) 2006 Jan Losinski
@ -29,6 +29,8 @@
#define BUFFSIZE 512 #define BUFFSIZE 512
/* Funktionsdefinitionen */
static int read_time(const char *, void *); static int read_time(const char *, void *);
static int read_color(const char *, void *); static int read_color(const char *, void *);
static int read_double(const char *, void *); static int read_double(const char *, void *);
@ -36,7 +38,7 @@ static int read_fmt_str(const char *, void *);
/* Zuordnung zwischen Schlüsselwörtern in der Config, Der Funktion, die diese auswertet /* Zuordnung zwischen Schluesselwoertern in der Config, Der Funktion, die diese auswertet
* und dem eld in der Options-Struktur */ * und dem eld in der Options-Struktur */
static const config_keyword keywords[] = { static const config_keyword keywords[] = {
/* keyword handler variable address default */ /* keyword handler variable address default */
@ -54,8 +56,8 @@ static const config_keyword keywords[] = {
{"height", read_int, &(img_cfg.height), DEFAULT_HEIGHT}, {"height", read_int, &(img_cfg.height), DEFAULT_HEIGHT},
{"unit", read_str, &(img_cfg.unit), DEFAULT_UNIT}, {"unit", read_str, &(img_cfg.unit), DEFAULT_UNIT},
{"sensor_id", read_int, &(img_cfg.sens_id), DEFAULT_SENS_ID}, {"sensor_id", read_int, &(img_cfg.sens_id), DEFAULT_SENS_ID},
{"zero_min", read_yn, &(img_cfg.zero_min), DEFAULT_ZERO_MIN}, {"zero_min", read_yn, &(img_cfg.zero_min), DEFAULT_ZERO_MIN},
{"as_bars", read_yn, &(img_cfg.bars), DEFAULT_AS_BARS}, {"as_bars", read_yn, &(img_cfg.bars), DEFAULT_AS_BARS},
{"x_axis_desc", read_str, &(img_cfg.x_desc), DEFAULT_X_AX_DESC}, {"x_axis_desc", read_str, &(img_cfg.x_desc), DEFAULT_X_AX_DESC},
{"y_axis_desc", read_str, &(img_cfg.y_desc), DEFAULT_Y_AX_DESC}, {"y_axis_desc", read_str, &(img_cfg.y_desc), DEFAULT_Y_AX_DESC},
{"x_format", read_fmt_str, &(img_cfg.x_fmt), DEFAULT_X_FORMAT}, {"x_format", read_fmt_str, &(img_cfg.x_fmt), DEFAULT_X_FORMAT},
@ -80,6 +82,8 @@ static const config_keyword keywords[] = {
{"", NULL, NULL, ""} {"", NULL, NULL, ""}
}; };
/* Einen Zeit - Format - String lesen */
static int read_fmt_str(const char *line, void *arg){ static int read_fmt_str(const char *line, void *arg){
char **dest = arg; char **dest = arg;
char *new_line = NULL; char *new_line = NULL;
@ -90,13 +94,13 @@ static int read_fmt_str(const char *line, void *arg){
if(new_line != NULL){ if(new_line != NULL){
p = strchr(new_line, '|'); p = strchr(new_line, '|');
if(p != NULL){ if(p != NULL){ /* Wenn ein | gefunden wurde */
strcpy(p, "\0"); strcpy(p, "\0"); /* dann diesen durch ein Stringende ersetzen */
strcpy(temp, new_line); strcpy(temp, new_line); /* Das Srueck vor dem | in einen Puffer schreiben */
strcat(temp, "\r\n"); strcat(temp, "\r\n"); /* ein zeilenumbruch mit Wagenruecklauf einfuegen */
strcat(temp, p+1); strcat(temp, p+1); /* das stueck hinter dem | anfuegen */
} else { } else {
strcpy(temp, new_line); strcpy(temp, new_line); /* Wenn kein | gefunden, dann den ganzen String in den Puffer */
} }
if (*dest) free(*dest); if (*dest) free(*dest);
@ -110,24 +114,28 @@ static int read_fmt_str(const char *line, void *arg){
} }
/* Liest ein double ein */
static int read_double(const char *line, void *arg){ static int read_double(const char *line, void *arg){
double *dest = arg; double *dest = arg;
*dest = atof(line); *dest = atof(line);
return 1; return 1;
} }
/* Liest eine Farbe ein
* Format: rr:gg:bb:aa */
static int read_color(const char *line, void *arg){ static int read_color(const char *line, void *arg){
img_color_ptr *col = arg; img_color_ptr *col = arg;
img_color_ptr tmp = NULL; img_color_ptr tmp = NULL;
char *buff = malloc(sizeof(char)*3); char *buff = malloc(sizeof(char)*3);
if(strlen(line) == 11){ if(strlen(line) == 11){ /* Wenn String auch wirkle 11 Zeichen lang */
if (strchr(line, ':') != NULL){ if (strchr(line, ':') != NULL){ /* und min. 1 : vorkommt */
tmp = malloc(sizeof(img_color_t)); tmp = malloc(sizeof(img_color_t)); /* Neues Farbelement allocieren */
tmp->r = strtol(strncpy(buff, line, 2), NULL, 16); tmp->r = strtol(strncpy(buff, line, 2), NULL, 16); /* r */
tmp->b = strtol(strncpy(buff, line+3, 2), NULL, 16); tmp->b = strtol(strncpy(buff, line+3, 2), NULL, 16); /* b */
tmp->g = strtol(strncpy(buff, line+6, 2), NULL, 16); tmp->g = strtol(strncpy(buff, line+6, 2), NULL, 16); /* g */
tmp->alpha = strtol(strncpy(buff, line+9, 2), NULL, 16); tmp->alpha = strtol(strncpy(buff, line+9, 2), NULL, 16); /* alpha */
DEBUGOUT5(" Farbe gelesen: rot:%2x gelb:%2x gruen:%2x mit alpha:%2x\n", tmp->r, tmp->b, tmp->g, tmp->alpha) ; DEBUGOUT5(" Farbe gelesen: rot:%2x gelb:%2x gruen:%2x mit alpha:%2x\n", tmp->r, tmp->b, tmp->g, tmp->alpha) ;
} }
@ -150,22 +158,22 @@ static int read_time(const char *line, void *arg){
char *p = NULL; char *p = NULL;
char *tmp = strdup(line); char *tmp = strdup(line);
p = strchr(tmp, '\0'); p = strchr(tmp, '\0'); /* P auf das ende des Strings setzen */
if(p != NULL){ if(p != NULL){
switch( *(p - 1) ){ switch( *(p - 1) ){ /* Letztes Zeichen pruefen */
case 's': case 's': /* Sekunden */
mult = 1; mult = 1;
break; break;
case 'm': case 'm': /* Minuten */
mult = 60; mult = 60;
break; break;
case 'h': case 'h': /* Stunden */
mult = 3600; mult = 3600;
break; break;
case 'd': case 'd': /* Tage */
mult = 86400; mult = 86400;
break; break;
case 'y': case 'y': /* Jahre */
mult = 31536000; mult = 31536000;
break; break;
default: default:
@ -189,12 +197,15 @@ int get_image_cfg(char *file){
int ret_var; int ret_var;
char *buff; char *buff;
/* Config - URL zusammenbauen */
buff = malloc(sizeof(char)*(strlen(file)+strlen(global_opts.image_cfg_location)+1)); buff = malloc(sizeof(char)*(strlen(file)+strlen(global_opts.image_cfg_location)+1));
buff = strcpy(buff, global_opts.image_cfg_location); buff = strcpy(buff, global_opts.image_cfg_location);
buff = strcat(buff, file); buff = strcat(buff, file);
DEBUGOUT2("\nLese Config-File: '%s' \n", buff); DEBUGOUT2("\nLese Config-File: '%s' \n", buff);
/* File einlesen */
ret_var = read_config(buff, 1, keywords); ret_var = read_config(buff, 1, keywords);
return ret_var; return ret_var;
} }

View File

@ -1,6 +1,6 @@
/* /*
chart.c -- Part of Chart-generator for the weatherstation image_config.h -- Part of Chart-generator for the weatherstation
Copyright (C) 2006 Jan Losinski Copyright (C) 2006 Jan Losinski
@ -20,4 +20,7 @@
*/ */
/* Bild - Config holen.
* Argument: Dateiname des Config - Files
* Rueckgabe: 1 bei Erfolg */
int get_image_cfg(char *); int get_image_cfg(char *);

View File

@ -1,3 +1,25 @@
/*
image_data.c -- Part of Chart-generator for the weatherstation
Copyright (C) 2006 Jan Losinski
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <time.h> #include <time.h>
@ -12,14 +34,15 @@
#define BUFFSIZE 512 #define BUFFSIZE 512
/* Variablen */
static pix_list_ptr min = NULL; static pix_list_ptr min = NULL; /* Pointer auf min - Element */
static pix_list_ptr max = NULL; static pix_list_ptr max = NULL; /* Pointer auf Max - Element */
double real_min = 0; double real_min = 0; /* Realer Max - Wert */
double real_max = 0; double real_max = 0; /* Realer Min - Wert */
static long base_time; /* Zeit an der 0-Koordinate (lt. Datenbank!) */ static long base_time; /* Zeit an der 0-Koordinate (lt. Datenbank!) */
/* Funktionsdefinitionen */
static pix_list_ptr add_pix_value(pix_list_ptr , long, int , int ); static pix_list_ptr add_pix_value(pix_list_ptr , long, int , int );
static char *get_conn_string(); static char *get_conn_string();
static PGconn *pg_check_connect(char *); static PGconn *pg_check_connect(char *);
@ -29,11 +52,11 @@ static char *get_type_table_by_id(PGconn *, int );
/* Bibt die Liste mit den y-Labels zurueck */ /* Bibt die Liste mit den y-Labels zurueck */
label_list_ptr get_y_label_list(int c_hight, int padding){ label_list_ptr get_y_label_list(int c_hight, int padding){
int max_val = 0; int max_val = 0; /* Maximaler Wert */
int min_val = 0; int min_val = 0; /* Minimaler Wert */
double factor = 0; double factor = 0; /* Pixel / Werte */
int diff = 0; int diff = 0; /* Wertebereich */
double real_diff = 0; double real_diff = 0; /* Realer Wertebereich */
double padd_val = 0; double padd_val = 0;
int temp = 0; int temp = 0;
double koeff = 1; double koeff = 1;
@ -52,6 +75,7 @@ label_list_ptr get_y_label_list(int c_hight, int padding){
DEBUGOUT1("\nBaue y-Labels...\n"); DEBUGOUT1("\nBaue y-Labels...\n");
DEBUGOUT4(" Max. Wert: %d, Min. Wert: %d (inkl. Koeffizient: %3.3f)\n", max_val, min_val, img_cfg.val_koeff); DEBUGOUT4(" Max. Wert: %d, Min. Wert: %d (inkl. Koeffizient: %3.3f)\n", max_val, min_val, img_cfg.val_koeff);
/* Max und min festlegen */
if (!img_cfg.label_sum){ if (!img_cfg.label_sum){
max_val = ceil( ( ((double)max->value_sum) / ((double)max->value_count) ) * img_cfg.val_koeff); max_val = ceil( ( ((double)max->value_sum) / ((double)max->value_count) ) * img_cfg.val_koeff);
min_val = floor( ( ((double)min->value_sum) / ((double)min->value_count) ) * img_cfg.val_koeff); min_val = floor( ( ((double)min->value_sum) / ((double)min->value_count) ) * img_cfg.val_koeff);
@ -59,10 +83,12 @@ label_list_ptr get_y_label_list(int c_hight, int padding){
max_val = ceil( ( ((double)max->value_sum) ) * img_cfg.val_koeff); max_val = ceil( ( ((double)max->value_sum) ) * img_cfg.val_koeff);
min_val = floor( ( ((double)min->value_sum) ) * img_cfg.val_koeff); min_val = floor( ( ((double)min->value_sum) ) * img_cfg.val_koeff);
} }
/* Min 0 setzen wenn zero_min gesetzt */
if (img_cfg.zero_min){ if (img_cfg.zero_min){
min_val = 0; min_val = 0;
} }
/* Rechnen ... */
diff = max_val - min_val; diff = max_val - min_val;
factor = ( ((double)c_hight - (2 * padding)) / ((double)diff) ); factor = ( ((double)c_hight - (2 * padding)) / ((double)diff) );
padd_val = (1 / factor) * ((double)padding); padd_val = (1 / factor) * ((double)padding);
@ -90,22 +116,30 @@ label_list_ptr get_y_label_list(int c_hight, int padding){
temp++; temp++;
} }
/* Puffer fuer die Labels */
buff = malloc(sizeof(char)*BUFFSIZE); buff = malloc(sizeof(char)*BUFFSIZE);
/* Labels generieren */
for (i = 0; i < num; i++){ for (i = 0; i < num; i++){
/* Momentaner wert */
new_val = temp + (i * interval); new_val = temp + (i * interval);
/* Labels zusammenbauen */
if(img_cfg.unit != NULL){ if(img_cfg.unit != NULL){
snprintf(buff, BUFFSIZE, "%d%s", new_val, img_cfg.unit); snprintf(buff, BUFFSIZE, "%d%s", new_val, img_cfg.unit);
} else { } else {
snprintf(buff, BUFFSIZE, "%d", new_val); snprintf(buff, BUFFSIZE, "%d", new_val);
} }
/* Neues Label - Element */
new_ptr = malloc(sizeof(label_list_t)); new_ptr = malloc(sizeof(label_list_t));
new_ptr->pos = floor( (real_max - ((double)new_val) ) * factor); new_ptr->pos = floor( (real_max - ((double)new_val) ) * factor);
new_ptr->value = new_val; new_ptr->value = new_val;
new_ptr->text = strdup(buff); new_ptr->text = strdup(buff);
new_ptr->next = NULL; new_ptr->next = NULL;
/* Rueckgabe- und Temp-pointer zuweisen */
if (ptr != NULL){ if (ptr != NULL){
temp_ptr->next = new_ptr; temp_ptr->next = new_ptr;
temp_ptr = temp_ptr->next; temp_ptr = temp_ptr->next;
@ -138,16 +172,23 @@ label_list_ptr get_x_label_list(int c_width){
DEBUGOUT1("\nBaue x-Labels...\n"); DEBUGOUT1("\nBaue x-Labels...\n");
/* Labels generieren */
for ( i = 1; i < num; i++ ) { for ( i = 1; i < num; i++ ) {
/* aktueller Timestamp */
timestamp = base_time + (i * img_cfg.label_interval); timestamp = base_time + (i * img_cfg.label_interval);
/* Text fuer das Label bauen */
strftime(buff, BUFFSIZE, img_cfg.x_fmt, localtime(&timestamp) ); strftime(buff, BUFFSIZE, img_cfg.x_fmt, localtime(&timestamp) );
/* Neues Label - Element */
new_ptr = malloc(sizeof(label_list_t)); new_ptr = malloc(sizeof(label_list_t));
new_ptr->pos = floor( ((double)i) * factor); new_ptr->pos = floor( ((double)i) * factor);
new_ptr->value = base_time + (i * img_cfg.label_interval); new_ptr->value = base_time + (i * img_cfg.label_interval);
new_ptr->text = strdup(buff); new_ptr->text = strdup(buff);
new_ptr->next = NULL; new_ptr->next = NULL;
/* Rueckgabe- und Temp-pointer zuweisen */
if (ptr != NULL){ if (ptr != NULL){
temp_ptr->next = new_ptr; temp_ptr->next = new_ptr;
temp_ptr = temp_ptr->next; temp_ptr = temp_ptr->next;
@ -168,26 +209,31 @@ label_list_ptr get_x_label_list(int c_width){
/* Skaliert die X-Koordinaten der Punkte im angegebenem Bereich /* Skaliert die X-Koordinaten der Punkte im angegebenem Bereich
* ausführliche Beschreibung im header-file */ * ausfuehrliche Beschreibung im header-file */
int scale_y_coords(pix_list_ptr ptr, int c_height){ int scale_y_coords(pix_list_ptr ptr, int c_height){
double range = (((real_max - real_min) / img_cfg.val_koeff ) + 1) ; /* Anzahl von 0,1-Schritten */ double range = (((real_max - real_min) / img_cfg.val_koeff ) + 1) ; /* Anzahl von 0,1-Schritten */
double pix_per_scale = ((double)c_height) / ((double)range); /* Pixel pro 0,1 */ double pix_per_scale = ((double)c_height) / ((double)range); /* Pixel pro 0,1 */
pix_list_ptr temp = ptr; int zero_line = floor( ((double)((real_max / img_cfg.val_koeff) + 1)) * pix_per_scale); /* Nullinie */
int zero_line = floor( ((double)((real_max / img_cfg.val_koeff) + 1)) * pix_per_scale); /* Nullinie */ pix_list_ptr temp = ptr; /* Temporaerer Pointer zum durchgehen der Liste */
DEBUGOUT1("\nBerechne y-Koordinaten:\n"); DEBUGOUT1("\nBerechne y-Koordinaten:\n");
/* Liste duchgehen */
for (; temp; temp = temp->next){ for (; temp; temp = temp->next){
/* unterscheidung ob summiert oder gemittelt werden soll */
if(!img_cfg.label_sum){ if(!img_cfg.label_sum){
temp->y_pix_coord = (-1 * floor( ( ((double)temp->value_sum) / ((double)temp->value_count) ) * pix_per_scale)) + zero_line; temp->y_pix_coord = (-1 * floor( ( ((double)temp->value_sum) / ((double)temp->value_count) ) * pix_per_scale)) + zero_line;
} else { } else {
temp->y_pix_coord = (-1 * floor( ((double)temp->value_sum) * pix_per_scale)) + zero_line; temp->y_pix_coord = (-1 * floor( ((double)temp->value_sum) * pix_per_scale)) + zero_line;
} }
DEBUGOUT3(" neue y-Koordinate: %d bei x: %d\n",temp->y_pix_coord, temp->x_pix_coord); DEBUGOUT3(" neue y-Koordinate: %d bei x: %d\n",temp->y_pix_coord, temp->x_pix_coord);
} }
DEBUGOUT2(" Nullinie bei: %d\n", zero_line); DEBUGOUT2(" Nullinie bei: %d\n", zero_line);
/* Wenn Nullinie zu sehen, dann die Position zurueckgeben */
if ((real_max - real_min + 1) >= real_max){ if ((real_max - real_min + 1) >= real_max){
return zero_line; return zero_line;
} else { } else {
@ -195,16 +241,20 @@ int scale_y_coords(pix_list_ptr ptr, int c_height){
} }
} }
/* Maximaler wert */ /* Maximaler wert */
pix_list_ptr get_max_val(){ pix_list_ptr get_max_val(){
return min; return min;
} }
/* Minimaler Wert */ /* Minimaler Wert */
pix_list_ptr get_min_val(){ pix_list_ptr get_min_val(){
return max; return max;
} }
/* Maximale Zeit */
char *get_max_time(){ char *get_max_time(){
char *buff = malloc(sizeof(char)*BUFFSIZE); char *buff = malloc(sizeof(char)*BUFFSIZE);
time_t timestamp = base_time + img_cfg.show_interval; time_t timestamp = base_time + img_cfg.show_interval;
@ -214,6 +264,8 @@ char *get_max_time(){
return buff; return buff;
} }
/* Minimale Zeit */
char *get_min_time(){ char *get_min_time(){
char *buff = malloc(sizeof(char)*BUFFSIZE); char *buff = malloc(sizeof(char)*BUFFSIZE);
time_t timestamp = base_time ; time_t timestamp = base_time ;
@ -223,6 +275,7 @@ char *get_min_time(){
return buff; return buff;
} }
/* Holt eine Liste mit den Werten und den jeweiligen x-koordinaten */ /* Holt eine Liste mit den Werten und den jeweiligen x-koordinaten */
pix_list_ptr get_pix_list(int c_width){ pix_list_ptr get_pix_list(int c_width){
double seconds_per_pix = ((double)c_width)/((double)img_cfg.show_interval); /* Pixel pro Sekunde */ double seconds_per_pix = ((double)c_width)/((double)img_cfg.show_interval); /* Pixel pro Sekunde */
@ -234,7 +287,7 @@ pix_list_ptr get_pix_list(int c_width){
int time_field; /* Id ses Timestamp-Feldes */ int time_field; /* Id ses Timestamp-Feldes */
int val_field; /* Id des Wert - Feldes */ int val_field; /* Id des Wert - Feldes */
long time_temp; /* Hilfsvariable */ long time_temp; /* Hilfsvariable */
int pix_coord; /* x - Koordinate, an die der Wert gehört */ int pix_coord; /* x - Koordinate, an die der Wert gehoert */
int i, s, t, u; /* Laufvariable zum durchlaufen des Datenbank-resuls */ int i, s, t, u; /* Laufvariable zum durchlaufen des Datenbank-resuls */
long timestamp; long timestamp;
pix_list_ptr list_ptr = NULL; /* Zeiger auf den Anfang der Wertliste */ pix_list_ptr list_ptr = NULL; /* Zeiger auf den Anfang der Wertliste */
@ -243,46 +296,78 @@ pix_list_ptr get_pix_list(int c_width){
DEBUGOUT1("\nHole Daten...\n"); DEBUGOUT1("\nHole Daten...\n");
DEBUGOUT2(" Ein Pixel entspricht %f sekunden\n", seconds_per_pix); DEBUGOUT2(" Ein Pixel entspricht %f sekunden\n", seconds_per_pix);
/* Tabellenname holen */
if (img_cfg.manual_table) { if (img_cfg.manual_table) {
table = strdup(img_cfg.table_name); table = strdup(img_cfg.table_name);
} else { } else {
table = get_type_table_by_id(conn, img_cfg.sens_id); table = get_type_table_by_id(conn, img_cfg.sens_id);
} }
/* Anfrage zusammenbauen */
snprintf(query, BUFFSIZE, "SELECT round(date_part('epoch', current_timestamp)) AS now, round(date_part('epoch', timestamp)) AS times, %s AS val FROM %s WHERE sens_id=%d AND timestamp > (current_timestamp - INTERVAL '%d seconds') ORDER BY times ASC", img_cfg.table_field, table, img_cfg.sens_id, img_cfg.show_interval ); snprintf(query, BUFFSIZE, "SELECT round(date_part('epoch', current_timestamp)) AS now, round(date_part('epoch', timestamp)) AS times, %s AS val FROM %s WHERE sens_id=%d AND timestamp > (current_timestamp - INTERVAL '%d seconds') ORDER BY times ASC", img_cfg.table_field, table, img_cfg.sens_id, img_cfg.show_interval );
/* Anfrage stellen */
res = pg_check_exec(conn, query); res = pg_check_exec(conn, query);
/* ID's der Felder ermitteln */
time_field = PQfnumber(res, "times"); time_field = PQfnumber(res, "times");
val_field = PQfnumber(res, "val"); val_field = PQfnumber(res, "val");
base_time = atol(PQgetvalue(res, 0, PQfnumber(res, "now"))) - img_cfg.show_interval; /* Momentane Zeit */
if(PQntuples(res) > 0){
base_time = atol(PQgetvalue(res, 0, PQfnumber(res, "now"))) - img_cfg.show_interval;
} else {
base_time = time(NULL);
}
/* Ergebnisse durchlaufen */
for (i = 0; i < PQntuples(res); i++){ for (i = 0; i < PQntuples(res); i++){
timestamp = atol(PQgetvalue(res, i, time_field)); timestamp = atol(PQgetvalue(res, i, time_field));
time_temp = timestamp - base_time; time_temp = timestamp - base_time;
/* Wenn Balken gezeichnet werden sollen */
if(img_cfg.bars){ if(img_cfg.bars){
time_temp --; time_temp --;
if(time_temp < 1) if(time_temp < 1)
time_temp++; time_temp++;
time_temp = floor( ((double)time_temp) / ((double)img_cfg.label_interval) ) * img_cfg.label_interval; time_temp = floor( ((double)time_temp) / ((double)img_cfg.label_interval) ) * img_cfg.label_interval;
} }
/* Koordinate berechnen */
pix_coord = floor( ((double)time_temp) * seconds_per_pix) ; pix_coord = floor( ((double)time_temp) * seconds_per_pix) ;
/* Listenelement generieren */
temp_ptr = add_pix_value(temp_ptr, timestamp, pix_coord, atoi( PQgetvalue(res, i, val_field) ) ); temp_ptr = add_pix_value(temp_ptr, timestamp, pix_coord, atoi( PQgetvalue(res, i, val_field) ) );
/* Rueckgabe- und Max/Min-pointer zuweisen */
if (list_ptr == NULL){ if (list_ptr == NULL){
list_ptr = temp_ptr; list_ptr = temp_ptr;
/* Globale Variablen neu initialisieren um /* Globale Variablen neu initialisieren um
* mehtete Bilder in einem Thread bauen zu * mehtete Bilder in einem Thread bauen zu
* können */ * koennen */
min = temp_ptr; min = temp_ptr;
max = temp_ptr; max = temp_ptr;
} }
} }
/* Wenn keine Daten vorhanden, dann Fake - Element generieren */
if(i == 0){
timestamp = timestamp - base_time +1;
if(img_cfg.bars){
time_temp = floor( ((double)timestamp) / ((double)img_cfg.label_interval) ) * img_cfg.label_interval;
} else {
time_temp = timestamp;
}
pix_coord = floor( ((double)time_temp) * seconds_per_pix) ;
temp_ptr = add_pix_value(temp_ptr, timestamp, pix_coord, 0 );
list_ptr = temp_ptr;
min = temp_ptr;
max = temp_ptr;
}
/* Min / Max ermitteln */ /* Min / Max ermitteln */
temp_ptr = list_ptr; temp_ptr = list_ptr;
u = 1; u = 1;
@ -313,6 +398,8 @@ pix_list_ptr get_pix_list(int c_width){
DEBUGOUT2(" %d Werte geholt \n", i); DEBUGOUT2(" %d Werte geholt \n", i);
DEBUGOUT3(" Min: x-pos.: %d, Wert: %d\n", min->x_pix_coord, (min->value_sum / min->value_count) ); DEBUGOUT3(" Min: x-pos.: %d, Wert: %d\n", min->x_pix_coord, (min->value_sum / min->value_count) );
DEBUGOUT3(" Max: x-pos.: %d, Wert: %d\n", max->x_pix_coord, (max->value_sum / max->value_count) ); DEBUGOUT3(" Max: x-pos.: %d, Wert: %d\n", max->x_pix_coord, (max->value_sum / max->value_count) );
/* Aufraemen */
PQclear(res); PQclear(res);
PQfinish(conn); PQfinish(conn);
free(query); free(query);
@ -325,6 +412,7 @@ pix_list_ptr get_pix_list(int c_width){
/* Speichert einen geholten Wert ab */ /* Speichert einen geholten Wert ab */
static pix_list_ptr add_pix_value(pix_list_ptr ptr, long timestamp, int coord, int value){ static pix_list_ptr add_pix_value(pix_list_ptr ptr, long timestamp, int coord, int value){
/* Erstes Element */
if(ptr == NULL){ if(ptr == NULL){
DEBUGOUT1("\nLese Daten ein:\n"); DEBUGOUT1("\nLese Daten ein:\n");
ptr = malloc(sizeof(pix_list_t)); ptr = malloc(sizeof(pix_list_t));
@ -336,11 +424,13 @@ static pix_list_ptr add_pix_value(pix_list_ptr ptr, long timestamp, int coord, i
DEBUGOUT3(" Erstes Element generiert...x-pos.: %d Wert: %d\n",ptr->x_pix_coord, ptr->value_sum); DEBUGOUT3(" Erstes Element generiert...x-pos.: %d Wert: %d\n",ptr->x_pix_coord, ptr->value_sum);
} else { } else {
/* Wenn schon ein Wert fuer X - Koordinate vorhanden,
* dann aufsummieren, sonst neues Element anfuegen */
if(coord == ptr->x_pix_coord){ if(coord == ptr->x_pix_coord){
ptr->value_sum += value; ptr->value_sum += value;
ptr->value_count++; ptr->value_count++;
DEBUGOUT5(" Zu x-pos. %d %d. Wert (%d) hinzugefügt. Durchschn.: %d\n", ptr->x_pix_coord, ptr->value_count, value, (ptr->value_sum/ptr->value_count) ); DEBUGOUT5(" Zu x-pos. %d %d. Wert (%d) hinzugefuegt. Durchschn.: %d\n", ptr->x_pix_coord, ptr->value_count, value, (ptr->value_sum/ptr->value_count) );
} else { } else {
ptr->next = malloc(sizeof(pix_list_t)); ptr->next = malloc(sizeof(pix_list_t));
ptr = ptr->next; ptr = ptr->next;
@ -385,7 +475,7 @@ static PGresult *pg_check_exec(PGconn *conn, char *query){
DEBUGOUT2("Fehler beim exec: %s\n", query); DEBUGOUT2("Fehler beim exec: %s\n", query);
exit_error(ERROR_QUERY); exit_error(ERROR_QUERY);
} else { } else {
DEBUGOUT2("Query: '%s' ausgeführt\n", query); DEBUGOUT2("Query: '%s' ausgefuehrt\n", query);
} }
return res; return res;
} }

View File

@ -1,21 +1,44 @@
/*
image_data.h -- Part of Chart-generator for the weatherstation
Copyright (C) 2006 Jan Losinski
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* Liste mit den Werten fuer das Diagram */
typedef struct pix_list *pix_list_ptr; typedef struct pix_list *pix_list_ptr;
typedef struct pix_list { typedef struct pix_list {
pix_list_ptr next; pix_list_ptr next; /* naechstes Element */
int x_pix_coord; int x_pix_coord; /* X - Koordinate */
int y_pix_coord; int y_pix_coord; /* Y - Koordinate */
int value_count; int value_count; /* Anzahl der Werte */
int value_sum; int value_sum; /* Summe der Werte */
} pix_list_t; } pix_list_t;
/* Liste mit Labels */
typedef struct label_list *label_list_ptr; typedef struct label_list *label_list_ptr;
typedef struct label_list { typedef struct label_list {
int pos; int pos; /* Position (X oder Y) */
long value; long value; /* Wert */
char *text; char *text; /* Anzuzeigender Text */
label_list_ptr next; label_list_ptr next; /* naechstes Element */
} label_list_t; } label_list_t;
@ -35,7 +58,11 @@ pix_list_ptr get_min_val();
pix_list_ptr get_max_val(); pix_list_ptr get_max_val();
/* Max. Zeit */
char *get_max_time(); char *get_max_time();
/* Min. Zeit */
char *get_min_time(); char *get_min_time();
@ -53,4 +80,10 @@ int scale_y_coords(pix_list_ptr , int );
*/ */
label_list_ptr get_x_label_list(int ); label_list_ptr get_x_label_list(int );
/* Baut die Liste mit den Labels an der Y-Achse
* 1. Argument: Hoehe des Bildes
* 2. Argument: Einrueckung oben und unten
* Rueckgabe: List mit den Labels
* */
label_list_ptr get_y_label_list(int, int); label_list_ptr get_y_label_list(int, int);

View File

@ -1,3 +1,25 @@
/*
image_draw.c -- Part of Chart-generator for the weatherstation
Copyright (C) 2006 Jan Losinski
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <time.h> #include <time.h>
@ -10,22 +32,27 @@
#define SHORTBUFFSIZE 64 #define SHORTBUFFSIZE 64
/* der besseren Lesbarkeit wegen einen Farbtyp definiert */
typedef int color; typedef int color;
/* Datenstruktur, welche die Dimensionen eines Textes enthaelt */
typedef struct dimension { typedef struct dimension {
int width; int width; /* Breite */
int height; int height; /* Hoehe */
int l_t_x; int l_t_x; /* Links - oben - x */
int l_t_y; int l_t_y; /* Links - oben - y */
int l_b_x; int l_b_x; /* Links - unten - x */
int l_b_y; int l_b_y; /* Links - unten - y */
int r_b_x; int r_b_x; /* Rechts - unten - x */
int r_b_y; int r_b_y; /* Rechts - unten - y */
int r_t_x; int r_t_x; /* Rechts - oben - x */
int r_t_y; int r_t_y; /* Rechts - oben - y */
int to_base; int to_base; /* Abstand von oben zur Grundlinie */
} dimension_t; } dimension_t;
/* Funktionsdefinitionen */
static gdImagePtr create_image(); static gdImagePtr create_image();
static gdImagePtr draw_image(gdImagePtr); static gdImagePtr draw_image(gdImagePtr);
static dimension_t calc_text_dim(char *, double , double ); static dimension_t calc_text_dim(char *, double , double );
@ -33,11 +60,11 @@ static color alloc_alpha_color(gdImagePtr , img_color_ptr );
static void write_image_png(gdImagePtr, FILE *); static void write_image_png(gdImagePtr, FILE *);
/* Baut ein Bild und schreibt es in die Datei */ /* Baut ein Bild und schreibt es in die Datei */
int draw_to_file(FILE *fd){ void draw_to_file(FILE *fd){
gdImagePtr img = create_image(); gdImagePtr img = create_image(); /* Bild 'erschaffen' */
draw_image(img); draw_image(img); /* Bild zeichnen */
write_image_png(img, fd); write_image_png(img, fd); /* Bild schreiben */
gdImageDestroy(img); gdImageDestroy(img); /* Bild 'zerstoeren */
} }
/* Erstellt ein Bild mit Hintergrundfarbe */ /* Erstellt ein Bild mit Hintergrundfarbe */
@ -81,7 +108,7 @@ static gdImagePtr draw_image(gdImagePtr img){
char *buff; char *buff;
time_t ts; time_t ts;
/* Größenangaben fuer die einzelnen Texte */ /* Groeßenangaben fuer die einzelnen Texte */
dimension_t head_d; dimension_t head_d;
dimension_t y_label_d; dimension_t y_label_d;
dimension_t x_label_d; dimension_t x_label_d;
@ -123,7 +150,7 @@ static gdImagePtr draw_image(gdImagePtr img){
/* Diagramhöhe */ /* Diagramhoehe */
buff = malloc(sizeof(char)*SHORTBUFFSIZE); buff = malloc(sizeof(char)*SHORTBUFFSIZE);
ts = time(NULL); ts = time(NULL);
strftime(buff, SHORTBUFFSIZE, "%d.%m.%y\r\n%H:%M", localtime(&ts) ) ; strftime(buff, SHORTBUFFSIZE, "%d.%m.%y\r\n%H:%M", localtime(&ts) ) ;
@ -196,11 +223,10 @@ static gdImagePtr draw_image(gdImagePtr img){
/* Rahmen */ /* Rahmen */
gdImageRectangle(img, offset_x_left, offset_y_top, img_cfg.width - offset_x_right, img_cfg.height - offset_y_bottom, dia_border_c); gdImageRectangle(img, offset_x_left, offset_y_top, img_cfg.width - offset_x_right, img_cfg.height - offset_y_bottom, dia_border_c);
} }
/* Berechnet die Dimensionen eines Textes */
static dimension_t calc_text_dim(char *text, double size, double angle){ static dimension_t calc_text_dim(char *text, double size, double angle){
int brect[8]; int brect[8];
dimension_t dim; dimension_t dim;
@ -209,8 +235,10 @@ static dimension_t calc_text_dim(char *text, double size, double angle){
int y_rt_lb = 0; int y_rt_lb = 0;
int y_rb_lt = 0; int y_rb_lt = 0;
/* Dimmensionen holen */
gdImageStringFT(NULL, &brect[0], 0, IMG_FONT, size, angle, 0,0, text); gdImageStringFT(NULL, &brect[0], 0, IMG_FONT, size, angle, 0,0, text);
/* Zuweisen */
dim.l_t_x = brect[6]; dim.l_t_x = brect[6];
dim.l_t_y = brect[7]; dim.l_t_y = brect[7];
dim.l_b_x = brect[0]; dim.l_b_x = brect[0];
@ -220,8 +248,10 @@ static dimension_t calc_text_dim(char *text, double size, double angle){
dim.r_t_x = brect[4]; dim.r_t_x = brect[4];
dim.r_t_y = brect[5]; dim.r_t_y = brect[5];
/* Abstand zur Grundlinie */
dim.to_base = 0 - dim.r_t_y; dim.to_base = 0 - dim.r_t_y;
/* Abstaende berechnen */
x_rt_lb = dim.r_t_x - dim.l_b_x; x_rt_lb = dim.r_t_x - dim.l_b_x;
x_rb_lt = dim.r_b_x - dim.l_t_x; x_rb_lt = dim.r_b_x - dim.l_t_x;
y_rt_lb = dim.l_b_y - dim.r_t_y; y_rt_lb = dim.l_b_y - dim.r_t_y;
@ -235,13 +265,10 @@ static dimension_t calc_text_dim(char *text, double size, double angle){
if(y_rt_lb < y_rb_lt){ if(y_rt_lb < y_rb_lt){
dim.height = y_rb_lt; dim.height = y_rb_lt;
//printf("y_rb_lt");
} else { } else {
dim.height = y_rt_lb; dim.height = y_rt_lb;
//printf("y_rt_lb");
} }
//printf("%d -- %s\n", dim.height, text);
return dim; return dim;
} }

View File

@ -1,2 +1,25 @@
/*
int draw_to_file(FILE *); image_config.c -- Part of Chart-generator for the weatherstation
Copyright (C) 2006 Jan Losinski
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* Bild generieren und in eine Datei schreiben
* Argument: Datei */
void draw_to_file(FILE *);

View File

@ -1,6 +1,6 @@
/* /*
process_image.c -- Part of Chart-generator for the weatherstation image_file.c -- Part of Chart-generator for the weatherstation
Copyright (C) 2006 Jan Losinski Copyright (C) 2006 Jan Losinski
@ -39,6 +39,7 @@
image_cfg_t img_cfg; image_cfg_t img_cfg;
/* Funktionsdefinitionen */
static void regenerate_image(); static void regenerate_image();
static int check_file_interval(); static int check_file_interval();
@ -52,6 +53,8 @@ void process_image_cfg(char *image_cfg_file){
get_image_cfg(image_cfg_file); get_image_cfg(image_cfg_file);
if (img_cfg.file_name != NULL){ if (img_cfg.file_name != NULL){
/* Debugausgabe einiger Config - Optionen */
DEBUGOUT2("File-Name = %s\n", img_cfg.file_name); DEBUGOUT2("File-Name = %s\n", img_cfg.file_name);
DEBUGOUT2("Ueberschr. = %s\n", img_cfg.headline); DEBUGOUT2("Ueberschr. = %s\n", img_cfg.headline);
DEBUGOUT2("Gen.Interval = %d\n", img_cfg.gen_interval); DEBUGOUT2("Gen.Interval = %d\n", img_cfg.gen_interval);
@ -66,6 +69,7 @@ void process_image_cfg(char *image_cfg_file){
DEBUGOUT2("TabellenName = %s\n", img_cfg.table_name); DEBUGOUT2("TabellenName = %s\n", img_cfg.table_name);
DEBUGOUT1("\n"); DEBUGOUT1("\n");
/* Bild - Namen zusammenbauen */
if(img_cfg.dflt_dir){ if(img_cfg.dflt_dir){
buff = malloc(sizeof(char)*BUFFSIZE); buff = malloc(sizeof(char)*BUFFSIZE);
buff = strncpy(buff, global_opts.dflt_image_location, BUFFSIZE - 1); buff = strncpy(buff, global_opts.dflt_image_location, BUFFSIZE - 1);
@ -77,11 +81,12 @@ void process_image_cfg(char *image_cfg_file){
} else { } else {
return; return;
} }
/* Pruefen ob Generierung noetig */
if(check_file_interval()){ if(check_file_interval()){
regenerate_image(); regenerate_image(); /* generieren */
} }
//sleep(30);
} }
@ -93,11 +98,14 @@ static int check_file_interval(){
time_t now; time_t now;
long diff_sek; long diff_sek;
/* Pruefen ob Bild vorhanden */
if(access(img_cfg.file_name, F_OK) == -1){ if(access(img_cfg.file_name, F_OK) == -1){
DEBUGOUT2("Datei '%s' existiert nicht\n", img_cfg.file_name); DEBUGOUT2("Datei '%s' existiert nicht\n", img_cfg.file_name);
DEBUGOUT1("Sie muss neu generiert werden!\n"); DEBUGOUT1("Sie muss neu generiert werden!\n");
return 1; return 1;
} }
/* Pruefen ob Bild zu alt */
if ((stat(img_cfg.file_name, &stat_buff)) != -1){ if ((stat(img_cfg.file_name, &stat_buff)) != -1){
now = time(NULL); now = time(NULL);
@ -118,7 +126,9 @@ static int check_file_interval(){
return 0; return 0;
} }
/* Bild (neu-) generieren */
static void regenerate_image(){ static void regenerate_image(){
FILE *fd = fopen(img_cfg.file_name, "wb"); FILE *fd = fopen(img_cfg.file_name, "wb"); /* Datei oeffnen */
draw_to_file(fd); draw_to_file(fd); /* Bild bauen und in Datei schreiben */
fclose(fd); /* Datei schließen */
} }

View File

@ -1,6 +1,6 @@
/* /*
process_image.h -- Part of Chart-generator for the weatherstation image_file.h -- Part of Chart-generator for the weatherstation
Copyright (C) 2006 Jan Losinski Copyright (C) 2006 Jan Losinski
@ -20,4 +20,7 @@
*/ */
/* Image bei Bedarf
* generieren und in Datei schreiben.
* Argument: Filename des Config - Files*/
void process_image_cfg(char *); void process_image_cfg(char *);