/* weatherdeamon -- Weather Data Capture Program for the 'ELV-PC-Wettersensor-Empfaenger' process.c -- Part of the weatherdeamon 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. $Id: process.c v 1.00 11 Aug 2006 losinski $ */ #include #include #include #include #include #include "process.h" #include "main.h" #include "definitions.h" #include "config.h" #include "write.h" /* Funktionsdefinitionen */ static u_char get_bit(unsigned int, u_char); static u_char get_2bits(u_char, u_char); static u_char get_hi_nibble(u_char); static u_char get_lo_nibble(u_char); static u_char remove_msb(u_char); static int convert_signed_int(u_char, u_char); static unsigned int convert_unsigned_int(u_char, u_char); static auss1_data process_auss1(time_t, u_char, u_char *); static auss2_data process_auss2(time_t, u_char, u_char *); static regen_data process_regen(time_t, u_char, u_char *); static winds_data process_winds(time_t, u_char, u_char *); static innen_data process_innen(time_t, u_char, u_char *); static helli_data process_helli(time_t, u_char, u_char *); static pyano_data process_pyano(time_t, u_char, u_char *); static void check_log_buffer(); static char* prepend_type_address(u_char, u_char); /* globale Variablen */ char *log_buffer = NULL; /* Puffer fuer die Log-Ausgabe */ int last_rain_count[16] = {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}; /* Letzter gemessener Wasserstand */ /* Bestimmung der Sensoren und Weiterreichung an die Funktionen zum auswerten der Werte * sowie zum wegschreiben */ void process_data(time_t timestamp, u_char *buffer){ u_char type; /* Sensortyp */ u_char address; /* Sensoraddresse */ type = get_hi_nibble(remove_msb(buffer[1])); address = get_lo_nibble(buffer[1]); DEBUGOUT1(asctime(localtime(×tamp))); switch (type){ case FERNB : DEBUGOUT2("Fernbedienung an Addresse %i\n", address); DEBUGOUT1("\nnoch nix zu implementiert!\n\n"); break; case AUSS1 : write_auss1(process_auss1(timestamp,address, buffer)); break; case AUSS2 : write_auss2(process_auss2(timestamp,address, buffer)); break; case REGEN : write_regen(process_regen(timestamp,address, buffer)); break; case WINDS : write_winds(process_winds(timestamp,address, buffer)); break; case INNEN : write_innen(process_innen(timestamp,address, buffer)); break; case HELLI : write_helli(process_helli(timestamp,address, buffer)); break; case PYANO : write_pyano(process_pyano(timestamp,address, buffer)); break; } } /* Wertkonvertierungen --------------------------------------------------- */ /* Wertkonvertierungen fuer den 'einfachen' Außensensor */ static auss1_data process_auss1(time_t timestamp, u_char address, u_char *buffer){ auss1_data data; /* Datenstruktur */ data.timestamp = timestamp; /* Zeitstempel */ data.address = address; /* Addresse */ data.temp = convert_signed_int(buffer[2],buffer[3]); /* Temparatur */ DEBUGOUT2("Aussensensor1 an Addresse %i\n", address); DEBUGOUT2("Temp.: %3.1f\n", (data.temp*0.1)); #ifndef NO_LOGING if(get_flag(LOG_DATA_FLAG)){ check_log_buffer(); sprintf(prepend_type_address(AUSS1,address), "Temp: %3.1f°C",(data.temp*0.1)); log_data(timestamp, log_buffer); } #endif return data; } /* Wertkonvertierungen fuer den 'besseren' Außensensor */ static auss2_data process_auss2(time_t timestamp, u_char address, u_char *buffer){ auss2_data data; /* Datenstruktur */ data.timestamp = timestamp; /* Zeitstempel */ data.address = address; /* Addresse */ data.temp = convert_signed_int(buffer[2],buffer[3]); /* Temparatur */ data.hum = remove_msb(buffer[4]); /* Luftfeuchte */ DEBUGOUT2("Aussensensor2 an Addresse %i\n", address); DEBUGOUT3("Temp.: %3.1f°C Feuchte: %d%%\n",(data.temp*0.1),data.hum); #ifndef NO_LOGING if(get_flag(LOG_DATA_FLAG)){ check_log_buffer(); sprintf(prepend_type_address(AUSS2,address), "Temp: %3.1f°C Hum: %d%%",(data.temp*0.1),data.hum); log_data(timestamp, log_buffer); } #endif return data; } /* Wertkonvertierungen fuer den Regensensor (ein Zaehlschritt = 370ml/m^2)*/ static regen_data process_regen(time_t timestamp, u_char address, u_char *buffer){ regen_data data; /* Datenstruktur */ int new_rain_count = 0; /* Neuer Zaehlerstand */ int now_rain_count = 0; /* Delta-Zaehlerstand */ data.timestamp = timestamp; /* Zeitstempel */ data.address = address; /* Addresse */ new_rain_count = ((buffer[2] & 0x1F) << 7) | remove_msb(buffer[3]); /* Niederschlagszaehler */ if(last_rain_count[address%16] == -1) /* Nach Programmstart Zaehler initialisieren */ last_rain_count[address%16] = new_rain_count; now_rain_count = new_rain_count - last_rain_count[address%16]; /* neuen Niederschlag berechnen */ if(now_rain_count < 0){ /* Wenn Integerueberlauf im Sensor */ now_rain_count = (0x3FFF - last_rain_count[address%16]) + new_rain_count; /* Dann letzten gemessenen Wert vom Max-Integer-Wert abziehen und neuen Zaehlwert dazurechnen */ DEBUGOUT1("Integer-Ueberlauf\n"); } data.counter = (now_rain_count * 370); /* Ein Zaehlschritt entspricht 370ml/m^2, also aenderung mit 370 multiplizieren und zuweisen */ last_rain_count[address%16] = new_rain_count; /* Zaehler neu setzen */ DEBUGOUT2("Regensensor an Addresse %i\n", address); DEBUGOUT3("Zaehler: %d Differenz: %d\n", new_rain_count,now_rain_count); DEBUGOUT2("Niederschlag: %dml/m^2\n", data.counter); #ifndef NO_LOGING if(get_flag(LOG_DATA_FLAG)){ check_log_buffer(); sprintf(prepend_type_address(REGEN,address), "Rain: %dml/m^2",data.counter); log_data(timestamp, log_buffer); } #endif return data; } /* Wertkonvertierungen fuer den Windsensor */ static winds_data process_winds(time_t timestamp, u_char address, u_char *buffer){ winds_data data; /* Datenstruktur */ data.timestamp = timestamp; /* Zeitstempel */ data.address = address; /* Addresse */ data.geschw = convert_unsigned_int(buffer[2],buffer[3]); /* Windgeschwindigkeit */ data.schwank = buffer[4] & 0x03; /* Schwankungsbreite */ data.richt = convert_unsigned_int(buffer[5],buffer[6]); /* Windrichtung */ DEBUGOUT2("Windsensor an Addresse %i\n", address); DEBUGOUT4("Geschw.: %3.1fKm/h Schwank: %d Richtung: %d°\n",(data.geschw*0.1),data.schwank,data.richt); #ifndef NO_LOGING if(get_flag(LOG_DATA_FLAG)){ check_log_buffer(); sprintf(prepend_type_address(WINDS,address), "Spd: %3.1fKm/h Fluct: %d%% Dir:%d°",(data.geschw*0.1),data.schwank,data.richt); log_data(timestamp, log_buffer); } #endif return data; } /* Wertkonvertierungen fuer den Innensensor */ static innen_data process_innen(time_t timestamp, u_char address, u_char *buffer){ innen_data data; /* Datenstruktur */ data.timestamp = timestamp; /* Zeitstempel */ data.address = address; /* Addresse */ data.temp = convert_signed_int(buffer[2],buffer[3]); /* Temparatur */ data.hum = remove_msb(buffer[4]); /* Luftfeuchte */ data.press = convert_unsigned_int(buffer[5],buffer[6]); /* Luftdruck */ DEBUGOUT2("Innensensor an Addresse %i\n",address); DEBUGOUT4("Temp.: %3.1f°C Feuchte: %d%% Druck: %dhPa\n",(data.temp*0.1),data.hum,data.press); #ifndef NO_LOGING if(get_flag(LOG_DATA_FLAG)){ check_log_buffer(); sprintf(prepend_type_address(INNEN,address), "Temp: %3.1f°C Hum: %d%% Press: %dhPa",(data.temp*0.1),data.hum,data.press); log_data(timestamp, log_buffer); } #endif return data; } /* Wertkonvertierungen fuer den Helligkeitssensor */ static helli_data process_helli(time_t timestamp, u_char address, u_char *buffer){ helli_data data; /* Datenstruktur */ data.timestamp = timestamp; /* Zeitstempel */ data.address = address; /* Addresse */ data.rawlum = convert_unsigned_int(buffer[2],buffer[3]); /* 'Roh-Helligkeit' - Helligkeit ohne Multiplikator */ data.mult = buffer[4] & 0x03; /* Multiplikator */ data.abslum = (0x01 << data.mult) * data.rawlum; /* Absolute Helligkeit */ DEBUGOUT2("Helligkeitssensor an Addresse %i\n", address); DEBUGOUT4("Rel. Hell.: %d Mult.: %d Abs. Hell.: %d\n",data.rawlum,data.mult,data.abslum); #ifndef NO_LOGING if(get_flag(LOG_DATA_FLAG)){ check_log_buffer(); sprintf(prepend_type_address(HELLI,address), "Bright: %d",data.abslum); log_data(timestamp, log_buffer); } #endif return data; } /* Wertkonvertierungen fuer das Pyranometer */ static pyano_data process_pyano(time_t timestamp, u_char address, u_char *buffer){ pyano_data data; /* Datenstruktur */ data.timestamp = timestamp; /* Zeitstempel */ data.rawrad = convert_unsigned_int(buffer[2],buffer[3]); /* 'Roh-Strahlung' - Strahlung ohne Multiplikator */ data.mult = buffer[4] & 0x03; /* Multiplikator */ data.absrad = (0x01 << data.mult) * data.rawrad; /* Absolute Strahlung */ DEBUGOUT2("Pyranometer an Addresse %i\n", address); DEBUGOUT4("Rel. Strahl.: %d Mult.: %d Abs. Strahl.: %d\n",data.rawrad,data.mult,data.absrad); #ifndef NO_LOGING if(get_flag(LOG_DATA_FLAG)){ check_log_buffer(); sprintf(prepend_type_address(PYANO,address), "Int: %d",data.absrad); log_data(timestamp, log_buffer); } #endif return data; } /* Verschiedenes ----------------------------------------------------------*/ /* einen vorzeichenbehafteten 14-Bit Binaerwert in einen Int umwandeln*/ static int convert_signed_int(u_char hi_byte, u_char lo_byte){ int val = 0; val = convert_unsigned_int(hi_byte,lo_byte); if (get_bit(val,13)){ val |= ~(0x3FFF); } return val; } /* einen 14-Bit Binaerwert in einen Int umwandeln*/ static unsigned int convert_unsigned_int(u_char hi_byte, u_char lo_byte){ return (remove_msb(hi_byte) << 7) | remove_msb(lo_byte); } /* Ein Bit vom Byte */ static u_char get_bit(unsigned int byte, u_char bit){ return (byte >> bit) & 0x01; } /* 2 Bit vom Byte */ static u_char get_2bits(u_char byte, u_char bit){ return byte >> bit & 0x03; } /* oberes halbbyte */ static u_char get_hi_nibble(u_char byte){ return byte >> 4 & 0x0f; } /* unteres halbbyte */ static u_char get_lo_nibble(u_char byte){ return byte & 0x0f; } /* Erstes Bit 0 setzen */ static u_char remove_msb(u_char byte){ return (byte & 0x7f); } /* Checkt, das das MSB gesetzt ist */ int check_msb_set(u_char byte){ return (byte & 0x80); } #ifndef NO_LOGING /* Pruefen ob Puffer fuer Logausgaben angelegt und renn nicht, dann anlegen */ static void check_log_buffer(){ if (log_buffer == NULL){ log_buffer = malloc(sizeof(char)*LOG_BUFFERSIZE); } } /* In der Log-Zeile die Addresse und den Typ des Sensors davorbauen * gibt die Addresse zurueck, an der die Werte weitergeschrieben werden koennen */ static char* prepend_type_address(u_char type, u_char address){ return (log_buffer + sprintf(log_buffer, "Sens: %i:%i - ", type, address)); } #endif