- Chart: linear average improved (performance)

- Chart: gaussian average implemented


git-svn-id: file:///home/jan/tmp/wetterstation/trunk@225 dd492736-c11a-0410-ad51-8c26713eaf7f
This commit is contained in:
losinshi 2007-04-18 15:19:34 +00:00
parent 022071a473
commit 85fd3d1859
12 changed files with 140 additions and 53 deletions

View File

@ -3,7 +3,7 @@ LD = gcc
RM = rm
CFLAGS = $(PackageFlags) -c
LDFLAS = $(PackageFlags) -o
LD_LIBS = -lm -lpq -lgd -lpng -lz -lfreetype
LD_LIBS = -lm -lpq -lgd -lpng -lz -lfreetype -lefence
#INCL = -I$$(pg_config --includedir)
BIN_NAME = weather_chart

View File

@ -30,31 +30,34 @@
/* Image-Default-Werte ----------------------------------------------- */
#define DEFAULT_HEADLINE "Wetter - Diagram"
#define DEFAULT_MANUAL_TABLE "no"
#define DEFAULT_TABLE_FIELD "temp"
#define DEFAULT_GEN_INTERVAL "15m"
#define DEFAULT_SHOW_INTERVAL "2d"
#define DEFAULT_LABEL_INTERVAL "2h"
#define DEFAULT_FIX_TIMEPOINT "no"
#define DEFAULT_TIMEPOINT "2006-01-01-12-00"
#define DEFAULT_LABEL_SUM "no"
#define DEFAULT_ZERO_MIN "no"
#define DEFAULT_AS_BARS "no"
#define DEFAULT_SHOW_AVERAGE "yes"
#define DEFAULT_SHOW_MIN "no"
#define DEFAULT_SHOW_MAX "no"
#define DEFAULT_INVERT_MIN "yes"
#define DEFAULT_INVERT_MAX "yes"
#define DEFAULT_WIDTH "800"
#define DEFAULT_HEIGHT "300"
#define DEFAULT_SENS_ID "1"
#define DEFAULT_VAL_KOEFF "0.1"
#define DEFAULT_UNIT "°C"
#define DEFAULT_X_AX_DESC "X-Axis"
#define DEFAULT_Y_AX_DESC "Y-Axis"
#define DEFAULT_X_FORMAT "%H:%M"
#define DEFAULT_X_FORMAT_EXTRA "%d.%m.%y| %H:%M"
#define DEFAULT_HEADLINE "Wetter - Diagram"
#define DEFAULT_MANUAL_TABLE "no"
#define DEFAULT_TABLE_FIELD "temp"
#define DEFAULT_GEN_INTERVAL "15m"
#define DEFAULT_SHOW_INTERVAL "2d"
#define DEFAULT_LABEL_INTERVAL "2h"
#define DEFAULT_FIX_TIMEPOINT "no"
#define DEFAULT_TIMEPOINT "2006-01-01-12-00"
#define DEFAULT_LABEL_SUM "no"
#define DEFAULT_ZERO_MIN "no"
#define DEFAULT_AS_BARS "no"
#define DEFAULT_SHOW_AVERAGE "yes"
#define DEFAULT_SHOW_MIN "no"
#define DEFAULT_SHOW_MAX "no"
#define DEFAULT_INVERT_MIN "yes"
#define DEFAULT_INVERT_MAX "yes"
#define DEFAULT_WIDTH "800"
#define DEFAULT_HEIGHT "300"
#define DEFAULT_SENS_ID "1"
#define DEFAULT_VAL_KOEFF "0.1"
#define DEFAULT_UNIT "°C"
#define DEFAULT_X_AX_DESC "X-Axis"
#define DEFAULT_Y_AX_DESC "Y-Axis"
#define DEFAULT_X_FORMAT "%H:%M"
#define DEFAULT_X_FORMAT_EXTRA "%d.%m.%y| %H:%M"
#define DEFAULT_USE_GAUSS_AVERAGE "no"
#define DEFAULT_AVERAGE_LOOK_WIDTH "30"
#define DEFAULT_GAUSS_WIDTH "12"
/* Image-Default-Farben ---------------------------------------------- */
#define DEFAULT_BG_COLOR "DF:DF:EF:00"
@ -97,7 +100,7 @@
#define TRUE 1
#define IMG_FONT "/usr/share/fonts/truetype/freefont/FreeSans.ttf"
#define CRON_INTERVAL 15 //Minuten
#define PI 3.14159265358979323846264
/* Debug --------------------------------------------------------------- */
#ifdef DEBUG

View File

@ -65,6 +65,13 @@ x_format_extra %d.%m.%y| %H:%M # Das ersre und das letzte Label
# Gibt an, ob eine Linie mit den Durchschnittswerten gezeichnet werden soll
# Funktioniert NICHT in Verbindung mit Balkendiagrammen
show_average yes
# Wieviele Pixel Links und rechts für den durchschnitt genommen werden sollen
average_look_width 30
# Anstatt eines Linear gewichtetem Durchschnittes die werte mit einer Gausschen
# Glockenkurve falten
use_gauss_average no
# Breite der Glockenkurve
gauss_width 13
# Zeigt in der rechten oberen Ecke die Minimal- bzw. Maximal-Werte an
show_min yes

View File

@ -65,6 +65,13 @@ x_format_extra %d.%m.%y| %H:%M # Das ersre und das letzte Label
# Gibt an, ob eine Linie mit den Durchschnittswerten gezeichnet werden soll
# Funktioniert NICHT in Verbindung mit Balkendiagrammen
show_average yes
# Wieviele Pixel Links und rechts für den durchschnitt genommen werden sollen
average_look_width 30
# Anstatt eines Linear gewichtetem Durchschnittes die werte mit einer Gausschen
# Glockenkurve falten
use_gauss_average no
# Breite der Glockenkurve
gauss_width 13
# Zeigt in der rechten oberen Ecke die Minimal- bzw. Maximal-Werte an
show_min yes

View File

@ -65,6 +65,13 @@ x_format_extra %d.%m.%y| %H:%M # Das ersre und das letzte Label
# Gibt an, ob eine Linie mit den Durchschnittswerten gezeichnet werden soll
# Funktioniert NICHT in Verbindung mit Balkendiagrammen
show_average yes
# Wieviele Pixel Links und rechts für den durchschnitt genommen werden sollen
average_look_width 30
# Anstatt eines Linear gewichtetem Durchschnittes die werte mit einer Gausschen
# Glockenkurve falten
use_gauss_average no
# Breite der Glockenkurve
gauss_width 13
# Zeigt in der rechten oberen Ecke die Minimal- bzw. Maximal-Werte an
show_min yes

View File

@ -65,6 +65,13 @@ x_format_extra %d.%m.%y| %H:%M # Das ersre und das letzte Label
# Gibt an, ob eine Linie mit den Durchschnittswerten gezeichnet werden soll
# Funktioniert NICHT in Verbindung mit Balkendiagrammen
show_average no
# Wieviele Pixel Links und rechts für den durchschnitt genommen werden sollen
average_look_width 30
# Anstatt eines Linear gewichtetem Durchschnittes die werte mit einer Gausschen
# Glockenkurve falten
use_gauss_average no
# Breite der Glockenkurve
gauss_width 13
# Zeigt in der rechten oberen Ecke die Minimal- bzw. Maximal-Werte an
show_min no

View File

@ -65,6 +65,13 @@ x_format_extra %d.%m.%y| %H:%M # Das ersre und das letzte Label
# Gibt an, ob eine Linie mit den Durchschnittswerten gezeichnet werden soll
# Funktioniert NICHT in Verbindung mit Balkendiagrammen
show_average yes
# Wieviele Pixel Links und rechts für den durchschnitt genommen werden sollen
average_look_width 30
# Anstatt eines Linear gewichtetem Durchschnittes die werte mit einer Gausschen
# Glockenkurve falten
use_gauss_average no
# Breite der Glockenkurve
gauss_width 13
# Zeigt in der rechten oberen Ecke die Minimal- bzw. Maximal-Werte an
show_min yes

View File

@ -3,16 +3,17 @@ use_dflt_img_dir yes
headline Temparatur - Innensensor
manual_table no
manual_table_name auss2_data
table_field temp
table_field geschw
#table_field temp
#table_field press
gen_interval 1
show_interval 200d
label_interval 20d
show_interval 20d
label_interval 2d
fixed_timepoint no
timepoint 2006-12-17-13-00
width 800
height 300
sensor_id 4
sensor_id 2
value_koeffizient 0.1
#value_koeffizient 1.0
unit °C
@ -28,7 +29,10 @@ show_min yes
show_max yes
invert_min yes
invert_max yes
#use_gauss_average no
use_gauss_average yes
average_look_width 20
gauss_width 7
#bg_color DF:DF:EF:00

View File

@ -65,6 +65,13 @@ x_format_extra %d.%m.%y| %H:%M # Das ersre und das letzte Label
# Gibt an, ob eine Linie mit den Durchschnittswerten gezeichnet werden soll
# Funktioniert NICHT in Verbindung mit Balkendiagrammen
show_average yes
# Wieviele Pixel Links und rechts für den durchschnitt genommen werden sollen
average_look_width 30
# Anstatt eines Linear gewichtetem Durchschnittes die werte mit einer Gausschen
# Glockenkurve falten
use_gauss_average no
# Breite der Glockenkurve
gauss_width 13
# Zeigt in der rechten oberen Ecke die Minimal- bzw. Maximal-Werte an
show_min no

View File

@ -55,10 +55,13 @@ typedef struct image_cfg {
int zero_min; /* Nullinie auf jeden Fall anzeigen */
int bars; /* Balken malen statt einer Linie */
int show_average; /* Durchschnittslinie zeichnen */
int show_min;
int show_max;
int invert_min;
int invert_max;
int gauss_width; /* 'Breite' der Gauss-Glocke */
int average_look_width; /* wieviele Pixel sollen 'links und rechts' angeschaut werden */
int use_gauss_average; /* Gaussche Glockenkurve statt einer linearen Wichtung fuer den Durchschnitt bebutzen */
int show_min; /* Minimum in der oberen ecke einblenden */
int show_max; /* maximum in der oberen ecke einblenden */
int invert_min; /* minimum invertiert anzeigen */
int invert_max; /* maximum invertiert anzeigen */
int dflt_dir; /* Standart - Verzeichnis fuer die Bilder */
/* Farben */

View File

@ -62,6 +62,9 @@ static const config_keyword keywords[] = {
{"zero_min", read_yn, &(img_cfg.zero_min), DEFAULT_ZERO_MIN},
{"as_bars", read_yn, &(img_cfg.bars), DEFAULT_AS_BARS},
{"show_average", read_yn, &(img_cfg.show_average), DEFAULT_SHOW_AVERAGE},
{"use_gauss_average", read_yn, &(img_cfg.use_gauss_average), DEFAULT_USE_GAUSS_AVERAGE},
{"average_look_width", read_int, &(img_cfg.average_look_width), DEFAULT_AVERAGE_LOOK_WIDTH},
{"gauss_width", read_int, &(img_cfg.gauss_width), DEFAULT_GAUSS_WIDTH},
{"show_min", read_yn, &(img_cfg.show_min), DEFAULT_SHOW_MIN},
{"show_max", read_yn, &(img_cfg.show_max), DEFAULT_SHOW_MAX},
{"invert_min", read_yn, &(img_cfg.invert_min), DEFAULT_INVERT_MIN},

View File

@ -54,6 +54,7 @@ static char *get_conn_string();
static PGconn *pg_check_connect(char *);
static PGresult *pg_check_exec(PGconn *, char *, int);
static char *get_type_table_by_id(PGconn *, int );
static inline double * build_koeff_array(int, int , int);
/* Gibt die Liste mit den y-Labels zurueck */
@ -496,7 +497,7 @@ pix_list_ptr build_average_line(pix_list_ptr real_list, int c_width){
int field_size = c_width + 10; /* Array-Groeße (sollte nicht groeßer sein als die Breite in Pixel) */
int i,j,m; /* Zaehlvariablen */
double sum = 0; /* Summe der berechneten Werte */
double koeff = 0; /* Momentan zu bearbeitener Koeffizient */
double *koeff = 0; /* Momentan zu bearbeitener Koeffizient */
double count = 0; /* Summe der Koeffizienten */
pix_list_ptr old_temp = real_list; /* Liste mit den 'echten' Werten */
@ -534,6 +535,9 @@ pix_list_ptr build_average_line(pix_list_ptr real_list, int c_width){
list_count++;
}
/* Koeffizienten bauen */
koeff = build_koeff_array(img_cfg.use_gauss_average, img_cfg.average_look_width, img_cfg.gauss_width);
/* Array durchgehen und neue Werte berechnen.
* Es werden immer 30 Werte Link und 30 Werte rechts mit
* sich jeweils um 0.03 veringernden koeffizienten
@ -543,18 +547,15 @@ pix_list_ptr build_average_line(pix_list_ptr real_list, int c_width){
if(old_ptr_field[i] != NULL){
/* Aktueller Wert aus der 'realen' Liste */
sum = ((double)old_ptr_field[i]->value_sum) / ((double)old_ptr_field[i]->value_count);
sum = ((double)old_ptr_field[i]->value_sum) / ((double)old_ptr_field[i]->value_count) * koeff[0];
/* Summe der Koeffizienten.
* Aktueller Wert hat die Wichtung 1,
* daher mit 1 initialisiert */
count = 1;
count = koeff[0];
/* 30 (29) Links ind rechts durchgehen */
for(j = 1; j < 30; j++){
/* aktueller Koeffizient */
koeff = 0.9 - (0.01 * (3*j));
for(j = 1; j < img_cfg.average_look_width; j++){
/* Anzahl, wie viele Werte mit dem Aktuellem
* Koeffizienten zur Summe addiert wurden */
@ -563,7 +564,7 @@ pix_list_ptr build_average_line(pix_list_ptr real_list, int c_width){
/* j Werte 'links' vom aktuellem Wert */
if( (i - j) >= 0){
if(old_ptr_field[i-j] != NULL){
sum += (((double)old_ptr_field[i-j]->value_sum) / ((double)old_ptr_field[i-j]->value_count)) * koeff;
sum += (((double)old_ptr_field[i-j]->value_sum) / ((double)old_ptr_field[i-j]->value_count)) * koeff[j];
m++;
}
}
@ -571,18 +572,19 @@ pix_list_ptr build_average_line(pix_list_ptr real_list, int c_width){
/* j Werte rechts vom aktuellem Wert */
if( (i + j) < list_count){
if(old_ptr_field[i+j] != NULL){
sum += (((double)old_ptr_field[i+j]->value_sum) / ((double)old_ptr_field[i+j]->value_count)) * koeff;
sum += (((double)old_ptr_field[i+j]->value_sum) / ((double)old_ptr_field[i+j]->value_count)) * koeff[j];
m++;
}
}
/* Hier wir die anzahl der Werte,
* die zur Summe hinzuaddiert wurden
* multipliziert mit dem aktuellem
* koeffizienten und das ganze auf
* den gesammtkoeffizienten addiert */
count += m * koeff;
/* Hier wir die anzahl der Werte,
* die zur Summe hinzuaddiert wurden
* multipliziert mit dem aktuellem
* koeffizienten und das ganze auf
* den gesammtkoeffizienten addiert */
count += m * koeff[j];
}
/* Neues Element an die Durchschnittsliste anfuegen */
@ -596,6 +598,9 @@ pix_list_ptr build_average_line(pix_list_ptr real_list, int c_width){
}
}
/* Koeffizienten freigeben */
free(koeff);
/* Array freigeben */
free(old_ptr_field);
@ -604,6 +609,33 @@ pix_list_ptr build_average_line(pix_list_ptr real_list, int c_width){
}
/* Array mit koeffizienten bauen
* gibt als rueckgabewert die koeffizienten
* Typ: 0=linear, 1=gauss*/
static inline double* build_koeff_array(int type, int look_width, int gauss_width){
int j; /* Laufvariable */
double div;
int o = gauss_width;
double * koeff_array = malloc((sizeof(double) * (look_width+1)));
for(j = 0; j < look_width; j++){
if(type){
/* GAUSS!!!*/
koeff_array[j] = (1/ (sqrt(2*PI) * o))*exp(-(j*j)/(o*o));
} else {
/* LINEAR*/
if (j == 0){
koeff_array[0] = 1;
} else {
div = 0.9 / ((double)look_width);
koeff_array[j] = 0.9 - (div * j);
}
}
}
return koeff_array;
}
/* baut den String fuer die Postgres-Verbindung zusammen */
static char *get_conn_string(){
char *conn_string = malloc(sizeof(char)*BUFFSIZE);