From df47982571ea512d4b45778a20b40ad375ccd9d1 Mon Sep 17 00:00:00 2001 From: losinshi Date: Fri, 11 Aug 2006 17:48:22 +0000 Subject: [PATCH] Initial project Import git-svn-id: file:///home/jan/tmp/wetterstation/trunk@2 dd492736-c11a-0410-ad51-8c26713eaf7f --- seriell/COPYING | 339 +++++++++++++++++++++++++++++++++++++++++ seriell/Makefile | 41 +++++ seriell/config.c | 179 ++++++++++++++++++++++ seriell/config.h | 40 +++++ seriell/definitions.h | 115 ++++++++++++++ seriell/input.c | 171 +++++++++++++++++++++ seriell/input.h | 28 ++++ seriell/main.c | 304 ++++++++++++++++++++++++++++++++++++ seriell/main.h | 90 +++++++++++ seriell/process.c | 347 ++++++++++++++++++++++++++++++++++++++++++ seriell/process.h | 29 ++++ seriell/weather.conf | 26 ++++ seriell/write.c | 157 +++++++++++++++++++ seriell/write.h | 110 +++++++++++++ 14 files changed, 1976 insertions(+) create mode 100644 seriell/COPYING create mode 100644 seriell/Makefile create mode 100644 seriell/config.c create mode 100644 seriell/config.h create mode 100644 seriell/definitions.h create mode 100644 seriell/input.c create mode 100644 seriell/input.h create mode 100644 seriell/main.c create mode 100644 seriell/main.h create mode 100644 seriell/process.c create mode 100644 seriell/process.h create mode 100644 seriell/weather.conf create mode 100644 seriell/write.c create mode 100644 seriell/write.h diff --git a/seriell/COPYING b/seriell/COPYING new file mode 100644 index 0000000..aca3fe3 --- /dev/null +++ b/seriell/COPYING @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 675 Mass Ave, Cambridge, MA 02139, USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + Appendix: How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) 19yy + + 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. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/seriell/Makefile b/seriell/Makefile new file mode 100644 index 0000000..4f27f38 --- /dev/null +++ b/seriell/Makefile @@ -0,0 +1,41 @@ +CC = gcc +LD = gcc +RM = rm +DEBUG = -DDEBUG +FLAGS = + +binary: + #make clean + # Compile + $(CC) $(FLAGS) -o main.o -c main.c + $(CC) $(FLAGS) -o input.o -c input.c + $(CC) $(FLAGS) -o process.o -c process.c + $(CC) $(FLAGS) -I/usr/include/postgresql -o write.o -c write.c + $(CC) $(FLAGS) -o config.o -c config.c + + # Link + $(LD) $(FLAGS) -L/usr/lib/pgsql -lpq -o weatherdeamon main.o input.o process.o write.o config.o + +debug: + #make clean + # Compile + $(CC) -DDEBUG -o main.o -c main.c + $(CC) -DDEBUG -o input.o -c input.c + $(CC) -DDEBUG -o process.o -c process.c + $(CC) -DDEBUG -I/usr/include/postgresql -o write.o -c write.c + $(CC) -DDEBUG -o config.o -c config.c + + # Link + $(LD) -DDEBUG -L/usr/lib/pgsql -lpq -o weatherdeamon main.o input.o process.o write.o config.o + + +partclean: + #remove *.o + $(RM) main.o input.o process.o + +clean: + #remove all output + $(RM) main.o input.o process.o write.o config.o weatherdeamon + + +# Die postgres-pfade bekommt man mit pg_config raus! diff --git a/seriell/config.c b/seriell/config.c new file mode 100644 index 0000000..723826d --- /dev/null +++ b/seriell/config.c @@ -0,0 +1,179 @@ +/* + + weatherdeamon -- Weather Data Capture Program for the + 'ELV-PC-Wettersensor-Empfänger' + config.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 "config.h" +#include "definitions.h" +#include "main.h" + + +static int read_str(const char *, void *); +static read_log_data_flag(const char *, void *); +static read_log_error_flag(const char *, void *); +static read_foreground_flag(const char *, void *); +static read_verbose_flag(const char *, void *); +static int flag_handler(int *, int , const char *); + + +/* Zuordnung zwischen Schlüsselwörtern in der Config, Der Funktion, die diese auswertet + * und dem eld in der Options-Struktur */ +static const struct config_keyword keywords[] = { + /* keyword handler variable address default */ + {"interface", read_str, &(global_opts.device), DEFAULT_SERIAL_PORT}, + {"log_data", read_log_data_flag, &(global_opts.flags), "no"}, + {"log_error", read_log_error_flag, &(global_opts.flags), "no"}, + {"data_file", read_str, &(global_opts.data_log), DEFAULT_DATA_FILE}, + {"error_file", read_str, &(global_opts.error_log), DEFAULT_ERROR_FILE}, + {"foreground", read_foreground_flag, &(global_opts.flags), "no"}, + {"verbose", read_verbose_flag, &(global_opts.flags), "no"}, + {"pg_host", read_str, &(global_opts.pg_host), DEFAULT_PG_HOST}, + {"pg_user", read_str, &(global_opts.pg_user), DEFAULT_PG_USER}, + {"pg_pass", read_str, &(global_opts.pg_pass), DEFAULT_PG_PASS}, + {"pg_database", read_str, &(global_opts.pg_database), DEFAULT_PG_DATABASE}, + {"", NULL, NULL, ""} +}; + +/* Liest eine Option (line) als String und speichert diese in + * dem entsprechendem Feld der Optionen-Struktur (arg) */ +static int read_str(const char *line, void *arg){ + char **dest = arg; + if (*dest) free(*dest); + *dest = strdup(line); + + return 1; +} + + +/* Die 4 Funktionen reichen jeweils nur die Daten an den + * flag_handler durch und teilen diesem noch das Flag + * mit, was er setzen soll (oder nicht) */ +static read_log_data_flag(const char *line, void *arg){ + return flag_handler(arg, LOG_DATA_FLAG, line); +} + +static read_log_error_flag(const char *line, void *arg){ + return flag_handler(arg, LOG_ERROR_FLAG, line); +} + +static read_foreground_flag(const char *line, void *arg){ + return flag_handler(arg, FOREGROUND_FLAG, line); +} + +static read_verbose_flag(const char *line, void *arg){ + return flag_handler(arg, VERBOSE_FLAG, line); +} + +/* Setzt Flags wenn der String gleich 'yes' ist */ +static int flag_handler(int *dest, int flag, const char *line){ + if (strcmp("yes", line) == 0){ + *dest |= flag; + } else { + *dest &= ~flag; + } + return 1; +} + + + +/* Liest und verarbeitet die Config-File + * der Integer reset gibt an, ob zu begin defaultwerte + * gesetzt werden sollen oder nicht */ +int read_config(const char *file, int reset){ + FILE *in; /* File-Handler */ + char buffer[CONFIG_BUFFERSIZE], *token, *line; /* Puffer zum lesen der config-file (imer 1 Zeile)*/ + char orig[CONFIG_BUFFERSIZE]; /* Originalpuffer zum lesen der config-file, um die Log und debug-ausgabe zu realisieren */ + int i; /* Laufvariable */ + int lm = 0; /* Zeilen-Nummer */ + + + /* Optionen mit default-werten füllen */ + if(reset){ + for (i = 0; keywords[i].keyword[0]; i++) + if (keywords[i].def[0]) + keywords[i].handler(keywords[i].def, keywords[i].var); + } + + /* config-file öffnen */ + if (!(in = fopen(file, "r"))) { + #ifndef NO_LOGING + if(get_flag(LOG_ERROR_FLAG)){ + sprintf(get_error_buffer(), "Kann Config-File: %s nicht öffnen!",file); + log_error(get_error_buffer()); + } + #endif + DEBUGOUT2("Kann Config-File: %s nicht öffnen!\n", file); + return 0; + } + + /* Datei Zeilenweise lesen */ + while (fgets(buffer, CONFIG_BUFFERSIZE, in)) { + lm++; + + /* Zeilenvorschübe gegen null-terminierungs-Zeichen ersetzen */ + if (strchr(buffer, '\n')) *(strchr(buffer, '\n')) = '\0'; + + /* Originlzeile für eventuelle log-, bzw. debug-meldungen */ + strcpy(orig, buffer); + + /* Kommentazeichen gegen null-terminierungs-Zeichen ersetzen und damit alles dahinter ignorieren */ + if (strchr(buffer, '#')) *(strchr(buffer, '#')) = '\0'; + + + if (!(token = strtok(buffer, " \t"))) continue; + if (!(line = strtok(NULL, ""))) continue; + + /* eat leading whitespace */ + line = line + strspn(line, " \t="); + /* eat trailing whitespace */ + for (i = strlen(line); i > 0 && isspace(line[i - 1]); i--); + line[i] = '\0'; + + for (i = 0; keywords[i].keyword[0]; i++){ + if (!strcasecmp(token, keywords[i].keyword)){ + if (!keywords[i].handler(line, keywords[i].var)) { + /* Fehler ins Logfile schreiben */ + #ifndef NO_LOGING + if(get_flag(LOG_ERROR_FLAG)){ + sprintf(get_error_buffer(), "Fehler beim Parsen des Parameters '%s' im file %s, Zeile %d",orig, file, lm); + log_error(get_error_buffer()); + } + #endif + DEBUGOUT4("Kann '%s' nicht Parsen (%s:%d)!\n", orig, file, lm); + /* reset back to the default value */ + keywords[i].handler(keywords[i].def, keywords[i].var); + } + } + } + } + fclose(in); + return 1; +} + + diff --git a/seriell/config.h b/seriell/config.h new file mode 100644 index 0000000..6c206ad --- /dev/null +++ b/seriell/config.h @@ -0,0 +1,40 @@ +/* + + weatherdeamon -- Weather Data Capture Program for the + 'ELV-PC-Wettersensor-Empfänger' + config.h -- 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 $ +*/ + + + + +/* Datenstruktur zum Auswerten des Config-Files */ +struct config_keyword { + const char *keyword; + int (* const handler)(const char *line, void *var); + void *var; + const char *def; +} ; + +/* Config lesen */ +int read_config(const char *, int); + + diff --git a/seriell/definitions.h b/seriell/definitions.h new file mode 100644 index 0000000..b0e55ee --- /dev/null +++ b/seriell/definitions.h @@ -0,0 +1,115 @@ +/* + + weatherdeamon -- Weather Data Capture Program for the + 'ELV-PC-Wettersensor-Empfänger' + definitions.h -- 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 $ +*/ + +/* Default-Werte ----------------------------------------------------- */ +#define DEFAULT_SERIAL_PORT "/dev/ttyS0" /* Serielle Schnittstelle */ +#define DEFAULT_DATA_FILE "./data.log" /* Daten-Logfile */ +#define DEFAULT_ERROR_FILE "./error.log" /* Error-Logfile */ +#define DEFAULT_PG_HOST "localhost" /* Postgres-host */ +#define DEFAULT_PG_USER "localuser" /* Postgres-Username */ +#define DEFAULT_PG_PASS "" /* Postgres-Passwort */ +#define DEFAULT_PG_DATABASE "localbase" /* Postgres-Datenbank */ +#define DEFAULT_CONFIG_FILE "./weather.conf" /* Standart-Configdatei */ + + + +/*Alle möglichen Definitionen, die in allen code-schnipseln benötigt werden*/ + +/* Sensor definitionen ------------------------------------------------- */ +#define FERNB 0x07 /* Funkfernbedienung */ +#define AUSS1 0x00 /* 'einfacher' Außensensor */ +#define AUSS2 0x01 /* 'besserer' Außensensor */ +#define REGEN 0x02 /* Regensensor */ +#define WINDS 0x03 /* Windsensor */ +#define INNEN 0x04 /* Innensensor */ +#define HELLI 0x05 /* Helligkeitssensor */ +#define PYANO 0x06 /* Pyanometer */ + + +/* Fehlermeldungen ------------------------------------------------------*/ +#define ERROR_OPEN "sensor-rs232interface: Fehler beim Oeffnen der RS232-Schnittstelle\n" +#define ERROR_OPTIONS "sensor-rs232interface: Fehler bei der Abfrage der Optionen\n" +#define ERROR_AKTIV "sensor-rs232interface: Fehler beim Aktivieren der Optionen\n" +#define ERROR_TIMEOUT "sensor-rs232interface: keine Daten - timeout-Fehler\n" +#define ERROR_POLLING "sensor-rs232interface: keine Daten - polling-Fehler\n" +#define ERROR_READ "sensor-rs232interface: Fehler beim Lesen\n" +#define ERROR_LOGFILE "Log-Error: Kann Logfile nicht öffnen\n" +#define ERROR_FORK "Fork-Fehler: Kann den Prozess nicht in den Hintergrund schieben\n" + + +/* Parameter-Flags ----------------------------------------------------- */ +#define LOG_ERROR_FLAG 0x01 +#define LOG_DATA_FLAG 0x02 +#define FOREGROUND_FLAG 0x04 +#define VERBOSE_FLAG 0x08 + + +/* Puffergrößen -------------------------------------------------------- */ +#define LOG_BUFFERSIZE 100 /* Größe für den Log-Puffer in process.c */ +#define ERR_BUFFERSIZE 512 /* Größe für den error-Puffer in main.c */ +#define INPUT_BUFFERSIZE 8 /* Größe für den Input-Puffer in input.c */ +#define CONFIG_BUFFERSIZE 512 /* Größe des Puffers zum Config-einlesen */ +#define QUERY_BUFFERSIZE 512 /* Größe des Zeichenpuffers für SQL-Anfragen */ + + +/* Timeout-Zeiten ------------------------------------------------------ */ +#define INPUT_TIMEOUT 10 + + +/* serial protocol definitions ----------------------------------------- */ +#define STX 0x02 /* Startbyte */ +#define ETX 0x03 /* Endbyte */ + + +/* Verschiedenes ------------------------------------------------------- */ +#define FALSE 0 +#define TRUE 1 + + +/* Debug --------------------------------------------------------------- */ +#ifdef DEBUG + #define DEBUGOUT1(x) fprintf(stderr,x) + #define DEBUGOUT2(x,y) fprintf(stderr,x,y) + #define DEBUGOUT3(x,y,z) fprintf(stderr,x,y,z) + #define DEBUGOUT4(x,y,z,a) fprintf(stderr,x,y,z,a) + #define DEBUGOUT5(x,y,z,a,b) fprintf(stderr,x,y,z,a,b) + #define FOR(x) for(x) +#else + #define DEBUGOUT1(x) + #define DEBUGOUT2(x,y) + #define DEBUGOUT3(x,y,z) + #define DEBUGOUT4(x,y,z,a) + #define DEBUGOUT5(x,y,z,a,b) + #define FOR(x) +#endif + +/* Dumping der Daten --------------------------------------------------- */ +#ifndef NO_LOGING + #define LOG_DATA(x,y) log_data(x.y) + #define LOG_ERROR(x) log_error(x) +#else + #define LOG_DATA(x,y) + #define LOG_ERROR(x) +#endif diff --git a/seriell/input.c b/seriell/input.c new file mode 100644 index 0000000..82b079a --- /dev/null +++ b/seriell/input.c @@ -0,0 +1,171 @@ +/* + + weatherdeamon -- Weather Data Capture Program for the + 'ELV-PC-Wettersensor-Empfänger' + input.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 /* File control definitions */ +#include /* POSIX terminal control definitions */ +#include +#include /* Polling */ + +#include "config.h" +#include "definitions.h" +#include "main.h" + + +static int fd; /* File-Deskriptor */ + +static void check_data(int, u_char*); +static int set_port(); +static void clean_port(void *); + +static int set_port() +{ + /** Diese Funktion stellt die Schnittstelle zum RS232 Port zur Verfuegung. * + * Gleichzeitig werden die Optionen so eingestellt, dass ein Abfragen der * + * Daten moeglich ist. * + * Zurueck gegeben wird der Filedeskriptor. */ + + struct termios options; /* Optionen Schnittstelle */ + int fd; /* File-Deskriptor */ + + /* oeffnen der Schnittstelle - nur lesen, nicht blockierend */ + if ((fd = open(global_opts.device,O_RDONLY | O_NONBLOCK | O_NOCTTY | O_NDELAY)) < 0) + exit_error(ERROR_OPEN); + + /* Erstmal alles zurücksetzen*/ + cfmakeraw(&options); + /* Uebertragungsgeschwindigkeit 19200 Baud */ + cfsetispeed(&options, B19200); + /* Control-Flags fertig codiert, funktioniert so! + * (so lange mit minicom rumgespielt bis es geklappt hat) + * wer lust hat kann das gern dekodieren und die Flags einzeln setzen.*/ + options.c_cflag = 0x80000BFE; + /* Output-Flags brauchmer net*/ + options.c_oflag = 0; + /* Break-conditions ignorieren wir einfach*/ + options.c_iflag = IGNBRK; + /* Local-Flags brauchmer auch keine*/ + options.c_lflag = 0; + + /* Zeug für die Flusskontrolle */ + //options.c_cc[VMIN] = 1; + //options.c_cc[VTIME] = 5; + + + tcflush(fd, TCIFLUSH); + if ( tcsetattr(fd, TCSANOW, &options) != 0 ) /* Optionen schreiben */ + exit_error(ERROR_AKTIV); + + DEBUGOUT2("\nInterface '%s' offen\n", global_opts.device); + + return fd; +} + +/* Diese Funktion liest einen Datensatz der seriellen Schnittstelle aus * + * und gibt diesen nach STDOUT. * + * Uebergeben wird der Filedeskriptor. */ +int read_port(){ + fd = set_port(); + int len=0; /* Anzahl gelesener Daten */ + int i, readlen =1; /* Laufvariable, Lesezähler */ + u_char buffer[INPUT_BUFFERSIZE], *temp = NULL; /* Lesepuffer, Temp-Zeiger */ + struct pollfd pfd = {fd, POLLIN, (short)NULL}; /* polling-Optionen */ + + temp = buffer; /* Temporärer Zeiger bekommt die Anfangsaddresse vom Puffer */ + + add_clean(clean_port, &fd); + + + DEBUGOUT1("\nWarte auf Daten\n\n"); + + do { + if((len = poll(&pfd, 1, INPUT_TIMEOUT)) > 0){ /* warten auf Eingabepuffer */ + len = read(fd, temp, 1); /* Zeichenweise lesen */ + if(readlen == 1){ /* Solange noch nix verwertbares gelesen wurde auf das Startbyte prüfen */ + if(*temp == STX){ + temp++; /* Wenn startbyte gefunden Zeiger auf das 2. Puffer-Element setzen */ + readlen++; /* Und Lese-Zähler erhöhen */ + } + } else { /* Wenn schon was relevantes gelesen wurde */ + if(readlen == 8 && *temp == ETX){ /* Wenn schon 8 Byte gelesen wurden und das letzte Byte das Stoppbyte ist */ + + FOR(i=0; i < readlen; i++) + DEBUGOUT2("%x ",buffer[i]); + DEBUGOUT1("\n"); + + check_data(readlen,buffer); /* Daten nochmals Prüfen und verarbeiten */ + + DEBUGOUT1("------------------------------------------\n"); + + readlen = 1; /* Lesezähler zurücksetzen */ + temp = buffer; /* Temp.-Zeiger wieder auf Pufferanfang setzen */ + } else { /* Wenn schon was relevantes da war, aber noch keine 8 byte incl. Stoppbyte */ + if(*temp == ETX || readlen >= 8){ /* Wenn das aktuelle byte das Stoppbyte oder das 8. Byte, dann sind die daten nicht ok */ + readlen = 1; /* Lesezähler zurücksetzen */ + temp = buffer; /* Temp-Zeiger auf Pufferanfang */ + } else { /* Sonst */ + readlen++; /* Lesezähler erhöhen */ + temp++; /* Temp.-Zeiger auf das nächste element setzen */ + } + } + } + //write(STDOUT_FILENO, buffer, n); /* Ausgabe Messung */ + } + } while (buffer[0] != '$'); /* Ende Datensatz */ + + close(fd); /* Schnittstelle schliessen */ + + return 1; +} + +/* Überprüfung, ob die Struktur der Daten stimmt + * es sollten 8 Byte ankommen: + * + * wobei = 02h + * und = 03h + * Bei ,... ist bit 7 (MSB) immer gesetzt, gehört also nicht zu den Daten! + * Im -Byte sind die unteren 4 bit die Addresse und die oberen 3 (weil 7. ist ja nicht benutzt) + * der Typ des Sensors. + * Die Typenzuordnung steht in der definitions.h. + * ... sind die Werte des Sensors. + * Eine genaue Beschreibung ist unter + * http://www.elv-downloads.de/service/manuals/PC-WS-Testempfaenger/39061-PCSensor_km.pdf + * zu finden. */ +static void check_data(int len, u_char *buffer){ + time_t timestamp = time(NULL); + if(len==8){ + if(buffer[0]==STX && check_msb_set(buffer[1]) && buffer[7]==ETX){ + process_data(timestamp, buffer); + } + } +} + +static void clean_port(void *data){ + close(*((int *)data)); + DEBUGOUT1("\nPort geschlossen\n"); +} diff --git a/seriell/input.h b/seriell/input.h new file mode 100644 index 0000000..56bd802 --- /dev/null +++ b/seriell/input.h @@ -0,0 +1,28 @@ +/* + + weatherdeamon -- Weather Data Capture Program for the + 'ELV-PC-Wettersensor-Empfänger' + input.h -- 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 $ +*/ + + +/*Funktionen*/ +int read_port(int); diff --git a/seriell/main.c b/seriell/main.c new file mode 100644 index 0000000..df834a1 --- /dev/null +++ b/seriell/main.c @@ -0,0 +1,304 @@ +/* + + weatherdeamon -- Weather Data Capture Program for the + 'ELV-PC-Wettersensor-Empfänger' + main.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 /* EXIT_SUCCESS */ +#include +#include /* STDOUT_FILENO */ +#include +#include /* O_WRONLY O_APPEND O_CREAT ... */ +#include +#include "definitions.h" +#include "config.h" +#include "main.h" + +/* Variablen ---------------------------------------------------------- */ +w_opts global_opts; +clean_struct_ptr clean_ptr = NULL; +#ifndef NO_LOGING + static char *error_buffer = NULL; /* Puffer für Fehler-ausgaben */ +#endif + +/* Funktionen ----------------------------------------------------------*/ +static void background(); +static void write_help(); +static void merge_options(w_opts *); +#ifndef NO_LOGING + static void log_message(char *, time_t, char *); + static int close_logfile(int); + static int open_logfile(char *); +#endif +static clean_struct_ptr get_last_clean(clean_struct_ptr); +static void clean(); + + +/* Jetzt gehts los.... --------------------------------------------------*/ + +/* Main-Funktion */ +int main(int argc, char *argv[]){ + char *extra_conf_file = NULL; + char c; + w_opts opts; /* temp. Optionen */ + + /* errno 0 setzen */ + errno = 0; + + /* temp. opts initialisieren (0 setzen) */ + opts.flags = 0; + opts.device = NULL; + #ifndef NO_LOGING + opts.data_log = NULL; + opts.error_log = NULL; + #endif + + DEBUGOUT1("Programm gestartet\n"); + + read_config(DEFAULT_CONFIG_FILE,1); + + /* Optionen auswerten */ + while ((c = getopt (argc, argv, "vfc:e:d:i:h")) != -1) + switch (c) { + #ifndef NO_LOGING + case 'e': + opts.flags |= LOG_ERROR_FLAG; + opts.error_log = optarg; + break; + case 'd': + opts.flags |= LOG_DATA_FLAG; + opts.data_log = optarg; + break; + #endif + case 'c': + extra_conf_file = optarg; + break; + case 'v': + opts.flags |= VERBOSE_FLAG; + break; + case 'f': + opts.flags |= FOREGROUND_FLAG; + break; + case 'i': + opts.device = optarg; + break; + case 'h': + write_help(); + return 0; + case '?': + write_help(); + return 1; + } + + /* eventuelle 2. config-file (mit -c angegeben) auswerten */ + if(extra_conf_file != NULL){ + read_config(extra_conf_file,0); + } + + /* Komandozeilen-Optionen zu denen aus der Config-File hinzufügen */ + merge_options(&opts); + + /* Debug-Ausgaben, um zu sehen, ob die Optionen richtig gesetzt werden */ + DEBUGOUT1("\nOptionen:\n"); + DEBUGOUT2(" Device = %s\n", global_opts.device); + DEBUGOUT2(" Foreground: %i\n", get_flag(FOREGROUND_FLAG)); + DEBUGOUT2(" Verbose: %i\n", get_flag(VERBOSE_FLAG)); + DEBUGOUT2(" LogData: %i\n", get_flag(LOG_DATA_FLAG)); + DEBUGOUT2(" DataFile = %s\n", global_opts.data_log); + DEBUGOUT2(" LogError: %i\n", get_flag(LOG_ERROR_FLAG)); + DEBUGOUT2(" ErrorFile = %s\n", global_opts.error_log); + + DEBUGOUT1("\nPostgres:\n"); + DEBUGOUT2(" Host: = %s\n",global_opts.pg_host); + DEBUGOUT2(" User: = %s\n",global_opts.pg_user); + DEBUGOUT2(" Pass: = %s\n",global_opts.pg_pass); + DEBUGOUT2(" Datenbank = %s\n",global_opts.pg_database); + + + /* Programm in den Hintergrund schicken ? */ + background(); + + DEBUGOUT1("\nBeginne Interface zu öffnen\n\n"); + + /* Port Pollen */ + read_port(); + + /* Theoretisch sollte das Programm hier _nie_ hinkommen */ + clean(); + return EXIT_SUCCESS; +} + +/* Diese Funktion ist dazu da, das Programm in den Hintergrund zu Forken */ +static void background(){ + if (!get_flag(FOREGROUND_FLAG)){ + DEBUGOUT1("Forke in den Hintergrund"); + if (daemon(0, get_flag(VERBOSE_FLAG)) == -1) { + exit_error(ERROR_FORK); + } + } +} + +/* Führt die Optionen aus der Komandozeile und die aus dem Conf-File zusammen */ +static void merge_options(w_opts *priv){ + if((*priv).device != NULL) + global_opts.device = (*priv).device; + if((*priv).data_log != NULL) + global_opts.data_log = (*priv).data_log; + if((*priv).error_log != NULL) + global_opts.error_log = (*priv).error_log; + global_opts.flags |= (*priv).flags; +} + +/* Bisschen Hilfe ausgeben */ +static void write_help(){ + printf("Usage:\n"); + #ifndef NO_LOGING + printf("weatherdeamon [-f] [-v] [-i ] [-c ] [-d ] [-e ]\n"); + #else + printf("weatherdeamon [-i ]\n"); + #endif + printf("\t-i \n\t\tThe interface where the reciver is connected \n\t\t(default:/dev/ttyS0)\n"); + printf("\t-f\n\t\tDon't Fork to background\n"); + printf("\t-v\n\t\tVerbose, log errors to stdout, even it's forked to background\n"); + printf("\t-c \n\t\t tells the Program to use an aditional config-file\n"); + #ifndef NO_LOGING + printf("\t-d \n\t\tLog all Data to the given Logfile\n\t\t(default: no logging!)\n"); + printf("\t-e \n\t\tLog all non-critical-Errors to the given Logfile\n\t\t(default: no logging!)\n"); + #endif +} + +/* ein Flag lesen */ +int get_flag(int mask){ + return (global_opts.flags & mask) != 0 ; +} + +/* Diese Funktion beendet das Programm mit einer Fehlermeldung. */ +void exit_error(char* err) +{ + clean(); + if(errno != 0){ + perror("Fehler"); + } + write(STDOUT_FILENO, err, strlen(err)); + exit(1); +} + + + +/* Funktionen für die Logfiles */ + +#ifndef NO_LOGING +/* Schreiben einer Fehlermeldung in das fehler-Logfile */ +void log_error(char *msg){ + if(get_flag(LOG_ERROR_FLAG)){ + log_message(global_opts.error_log, time(NULL), msg); + DEBUGOUT1(" -->Error Logged \n"); + } +} + +/* Schreiben eines Datensatzes in das Daten-Logfile */ +void log_data(time_t timestamp, char *msg){ + log_message(global_opts.data_log, time(NULL), msg); + DEBUGOUT1(" -->Data Logged \n"); +} + +/* Logfile öffnen */ +static int open_logfile(char *file){ + int log_fd; + + log_fd = open(file, O_WRONLY | O_APPEND | O_CREAT, 00600); + if (log_fd < 0) { + exit_error(ERROR_LOGFILE); + } + return log_fd; +} + +/* Logfile schließen */ +static int close_logfile(int log_fd){ + fsync(log_fd); + close(log_fd); +} + +/* Nachicht schreiben */ +static void log_message(char *file, time_t timestamp, char *msg){ + int log_fd; + char date[27]; + + log_fd=open_logfile(file); + snprintf(date, 27, (char *)asctime(localtime(×tamp))); + write(log_fd, date + 4, strlen(date) - 5); + write(log_fd, " - ", 3); + write(log_fd, msg, strlen(msg)); + write(log_fd, "\n", 1); + close_logfile(log_fd); +} + +char *get_error_buffer(){ + if(error_buffer == NULL){ + error_buffer = malloc(sizeof(char)*ERR_BUFFERSIZE); + } + return error_buffer; +} +#endif + +/* Pointer auf letztes 'Clean-Element' bekommen. + * Mir war grad nach rekrusiv und so viele Elemente sollten + * es ja nicht sein.*/ +static clean_struct_ptr get_last_clean(clean_struct_ptr ptr){ + if(ptr != NULL){ + if (ptr->next != NULL){ + return get_last_clean(ptr->next); + } else { + return ptr; + } + } + return NULL; +} + +/* Ein neues Clean-Element anfügen. Ein Clean-Element ist eine Datenstruktur, die + * einen Pointer auf eine Funktion vom Typ + * void func(void *data), + * einen Zeiger auf beliebige Daten und einen Zeiger auf das nächste Element hält. + * Die Funktionen werden beim regulären beenden des Programmes aufgerufen um zum bsp. + * datenbankverbindungen zu schließen, etc. */ +void add_clean(void (*func)(void *data), void *data){ + clean_struct_ptr p, temp = (clean_struct_ptr) malloc(sizeof(clean_data)); + temp->data = data; + temp->func = func; + temp->next = NULL; + if(clean_ptr == NULL){ + clean_ptr = temp; + } else { + p = get_last_clean(clean_ptr); + p->next = temp; + } +} + +/* 'Säuberung' ausführen */ +static void clean(){ + clean_struct_ptr p = clean_ptr; + while(p != NULL){ + p->func(p->data); + p = p->next; + } +} diff --git a/seriell/main.h b/seriell/main.h new file mode 100644 index 0000000..58fac18 --- /dev/null +++ b/seriell/main.h @@ -0,0 +1,90 @@ +/* + + weatherdeamon -- Weather Data Capture Program for the + 'ELV-PC-Wettersensor-Empfänger' + main.h -- 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 $ +*/ + + +/* Datenstrukturen --------------------------------------------------------*/ + +/* Optionen */ +typedef struct { + unsigned char flags; /* Flags */ + char *device; /* Das Serielle Device */ + char *pg_host; /* Postgres-Host */ + char *pg_user; /* Postgres-Username */ + char *pg_pass; /* Postgres-Password */ + char *pg_database; /* Postgres-Datenbank */ + #ifndef NO_LOGING + char *data_log; /* Das Daten-Logfile */ + char *error_log; /* Das Fehler-Logfile */ + #endif +} w_opts; + +/* Aufräumfunktionen */ +/* TODO: sollen Funktionen werden, mit denen die eintelnen Teile funktionen registrieren können, die aufräiumen + * (Verbindung schließen, file schließen, ...) */ +typedef struct clean_struct *clean_struct_ptr; +typedef struct clean_struct { + void *data; + void (*func)(void *data); + clean_struct_ptr next; +} clean_data; + + +/* Funktionen -------------------------------------------------------------*/ + +/* Programm mit einem Fatalem Fehler beenden. + * Argument: Fehlermeldung */ +void exit_error(char*); + +/* Ein Flag bekommen + * Argument: Maske für das Flag, siehe definitions.h */ +int get_flag(int); + +#ifndef NO_LOGING +/* Schreiben einer Fehlermeldung in ein Fehler-Log + * Das Argument ist die Fehermeldung */ +void log_error(char *); + +/* Schreiben eines Datensatzes in das Logfile + * 1. Argument: Timestamp + * 2. Argument: Log-Message */ +void log_data(time_t, char *); + +/* Gibt _EINEN_ Puffer für das Zusammensetzen + * der Fehler-Zeichenketten zurück. + * Es sollte wirklich bei jedem Aufruf der selbe + * Puffer sein */ +char *get_error_buffer(); +#endif + +/* Ein neues Clean-Element anfügen. Ein Clean-Element ist eine Datenstruktur, die + * einen Pointer auf eine Funktion vom Typ + * void func(void *data), + * einen Zeiger auf beliebige Daten und einen Zeiger auf das nächste Element hält. + * Die Funktionen werden beim regulären beenden des Programmes aufgerufen um zum bsp. + * datenbankverbindungen zu schließen, etc. */ +void add_clean(void (*func)(void *data), void *data); + +/* Variablen --------------------------------------------------------------*/ +extern w_opts global_opts; diff --git a/seriell/process.c b/seriell/process.c new file mode 100644 index 0000000..c740c00 --- /dev/null +++ b/seriell/process.c @@ -0,0 +1,347 @@ +/* + + weatherdeamon -- Weather Data Capture Program for the + 'ELV-PC-Wettersensor-Empfänger' + 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 "main.h" +#include "definitions.h" +#include "config.h" +#include "write.h" + +/* Funktionsdefinitionen */ +static u_char get_bit(u_char, 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 für die Log-Ausgabe */ +unsigned int last_rain_count = -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 für 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 für 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 für den Regensensor (ein Zählschritt = 370ml/m^2)*/ +static regen_data process_regen(time_t timestamp, u_char address, u_char *buffer){ + regen_data data; /* Datenstruktur */ + unsigned int new_rain_count = 0; /* Neuer Zählerstand */ + unsigned int now_rain_count = 0; /* Delta-Zählerstand */ + + data.timestamp = timestamp; /* Zeitstempel */ + data.address = address; /* Addresse */ + new_rain_count = ((buffer[2] & 0x1F) << 7) | remove_msb(buffer[3]); /* Niederschlagszähler */ + + if(last_rain_count == -1) /* Nach Programmstart Zähler initialisieren */ + last_rain_count = new_rain_count; + + now_rain_count = new_rain_count - last_rain_count; /* neuen Niederschlag berechnen */ + + if(now_rain_count < 0){ /* Wenn Integerüberlauf im Sensor */ + now_rain_count = (0x3FFF - last_rain_count) + new_rain_count; /* Dann letzten gemessenen Wert vom Max-Integer-Wert abziehen und neuen Zählwert dazurechnen */ + DEBUGOUT1("Integer-Überlauf\n"); + } + + data.counter = (now_rain_count * 370); /* Ein Zählschritt entspricht 370ml/m^2, also änderung mit 370 multiplizieren und zuweisen */ + + last_rain_count = new_rain_count; /* Zähler neu setzen */ + + DEBUGOUT2("Regensensor an Addresse %i\n", address); + DEBUGOUT3("Zähler: %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 für 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 für 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 für 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 für das Pyanometer */ +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("Pyanometer 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 Binärwert in einen Int umwandeln*/ +static int convert_signed_int(u_char hi_byte, u_char lo_byte){ + int val; + val = convert_unsigned_int(hi_byte,lo_byte); + if (get_bit(val,14)){ + val |= ~0x3FFF; + } + return val; +} + +/* einen 14-Bit Binärwert 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(u_char 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 + +/* Prüfen ob Puffer für 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 zurück, an der die Werte weitergeschrieben werden können */ +static char* prepend_type_address(u_char type, u_char address){ + return (log_buffer + sprintf(log_buffer, "Sens: %i:%i - ", type, address)); +} + +#endif diff --git a/seriell/process.h b/seriell/process.h new file mode 100644 index 0000000..b7dc50c --- /dev/null +++ b/seriell/process.h @@ -0,0 +1,29 @@ +/* + + weatherdeamon -- Weather Data Capture Program for the + 'ELV-PC-Wettersensor-Empfänger' + process.h -- 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 $ +*/ + + +/*Funktionen*/ +int check_msb_set(u_char); +void process_data(time_t, u_char*); diff --git a/seriell/weather.conf b/seriell/weather.conf new file mode 100644 index 0000000..f6b9216 --- /dev/null +++ b/seriell/weather.conf @@ -0,0 +1,26 @@ +# Die Serielle Schnittstelle +interface /dev/ttyS0 # default: /dev/ttyS0 + +# Sollen Daten in ein Logfile geschrieben werden? +log_data yes # default: no + +# Sollen Fehler in ein Logfile geschrieben werden? +log_error yes # default: no + +# Das File wo die daten reinkommen +data_file ../data.log # default: ./data.log + +# Das File wo die Fehler reinkommen +error_file ../error.log # default: ./error.log + +# Im Vordergrunf bleiben? +foreground yes # default: no + +# Fehlermeldungen nach stderr schicken? +verbose yes # default: no + +# Postgres-Einstellungen +pg_host 141.30.228.39 +pg_user losinshi +#pg_pass +pg_database wetter diff --git a/seriell/write.c b/seriell/write.c new file mode 100644 index 0000000..1ca8cec --- /dev/null +++ b/seriell/write.c @@ -0,0 +1,157 @@ +/* + + weatherdeamon -- Weather Data Capture Program for the + 'ELV-PC-Wettersensor-Empfänger' + write.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 $ +*/ + +/* + * Allgemeines zu dieser File: + * + * Sollte irgend jemand das Programm weiter verwenden, + * jedoch die Daten anders oder woandershin wegschreiben + * wollen, so müssen nur diese Funktionen neu implementiert + * werden. + */ + +#include +#include +#include +#include "definitions.h" +#include "main.h" +#include "write.h" + + +/* Globale Variablen -----------------------------------------*/ +static char *query_buffer = NULL; +static PGconn *connection = NULL; +static char *conn_string = NULL; + + +/* Funktionen ----------------------------------------------- */ +static void check_create_query_buffer(); +static int pg_connect(); +static void pg_insert(char *); +static void clean_write(void *); + +/* Funktionen zum wegschreiben -------------------------------*/ + +/* 'einfacher' Außensensor */ +void write_auss1(auss1_data data){ + check_create_query_buffer(); + snprintf(query_buffer, QUERY_BUFFERSIZE, "INSERT INTO auss1_data (sens_id, \"temp\") VALUES (get_sensor_id(%d,%d),%d)",AUSS1, data.address, data.temp); + pg_insert(query_buffer); +} + +/* 'besserer' Außensensor */ +void write_auss2(auss2_data data){ + check_create_query_buffer(); + snprintf(query_buffer, QUERY_BUFFERSIZE, "INSERT INTO auss2_data (sens_id, \"temp\", hum) VALUES (get_sensor_id(%d,%d),%d,%d)",AUSS2, data.address, data.temp, data.hum); + pg_insert(query_buffer); +} + +/* Regensensor */ +void write_regen(regen_data data){ + check_create_query_buffer(); + snprintf(query_buffer, QUERY_BUFFERSIZE, "INSERT INTO regen_data (sens_id, count) VALUES (get_sensor_id(%d,%d),%d)",REGEN, data.address, data.counter); + pg_insert(query_buffer); +} + +/* Windsensor */ +void write_winds(winds_data data){ + check_create_query_buffer(); + snprintf(query_buffer, QUERY_BUFFERSIZE, "INSERT INTO winds_data (sens_id, geschw, schwank, richt) VALUES (get_sensor_id(%d,%d),%d,%d,%d)",WINDS, data.address, data.geschw, data.schwank, data.richt); + pg_insert(query_buffer); +} + +/* Innensensor */ +void write_innen(innen_data data){ + check_create_query_buffer(); + snprintf(query_buffer, QUERY_BUFFERSIZE, "INSERT INTO innen_data (sens_id, \"temp\", hum, press) VALUES (get_sensor_id(%d,%d),%d,%d,%d)",INNEN, data.address, data.temp, data.hum, data.press); + pg_insert(query_buffer); +} + +/* Helligkeitssensor */ +void write_helli(helli_data data){ + check_create_query_buffer(); + snprintf(query_buffer, QUERY_BUFFERSIZE, "INSERT INTO helli_data (sens_id, bight) VALUES (get_sensor_id(%d,%d),%d)",HELLI, data.address, data.abslum); + pg_insert(query_buffer); +} + +/* Pyanometer */ +void write_pyano(pyano_data data){ + check_create_query_buffer(); + snprintf(query_buffer, QUERY_BUFFERSIZE, "INSERT INTO pyano_data (sens_id, intens) VALUES (get_sensor_id(%d,%d),%d)",PYANO, data.address, data.absrad); + pg_insert(query_buffer); +} + +/* Testen ob Puffer angelegt und bei bedarf anlegen */ +static void check_create_query_buffer(){ + if(query_buffer == NULL){ + query_buffer= malloc(sizeof(char)*QUERY_BUFFERSIZE); + } +} + +/* Guckt ob Verbindung da und versucht aufzubauen. + * gibt 1 zurück, wenn erfolgreich, sonst 0 */ +static int pg_connect(){ + if(PQstatus(connection) != CONNECTION_OK){ + if (connection == NULL){ + if(conn_string == NULL){ + conn_string = malloc(sizeof(char)*255); + snprintf(conn_string, 255, "host=%s dbname=%s user=%s password=%s", global_opts.pg_host, global_opts.pg_database, global_opts.pg_user, global_opts.pg_pass); + } + connection = PQconnectdb(conn_string); + add_clean(clean_write, connection); + } else { + PQreset(connection); + } + if(PQstatus(connection) != CONNECTION_OK){ + DEBUGOUT2("\nFehler beim Aufbau der Datenbankverbindung\n%s\n", PQerrorMessage(connection)); + snprintf(get_error_buffer(), ERR_BUFFERSIZE, "Fehler beim Aufbau der Datenbankverbindung: %s", PQerrorMessage(connection)); + log_error(get_error_buffer()); + return 0; + } + DEBUGOUT1("\nDatenbankverbindung erfolgreich hergestellt\n"); + } + return 1; +} + +static void pg_insert(char *query){ + PGresult *res; + if(pg_connect()){ + res = PQexec(connection, query); + if(!res || PQresultStatus(res) != PGRES_COMMAND_OK){ + DEBUGOUT2("Fehler beim INSERT: %s\n", query); + snprintf(get_error_buffer(), ERR_BUFFERSIZE, "Fehler beim INSERT: %s", query); + log_error(get_error_buffer()); + } else { + DEBUGOUT2("Query: '%s' ausgeführt\n", query); + } + PQclear(res); + } +} + +static void clean_write(void *data){ + PGconn *conn = data; + PQfinish(conn); + DEBUGOUT1("\nVerbindung Geschlossen \n"); +} diff --git a/seriell/write.h b/seriell/write.h new file mode 100644 index 0000000..58716f8 --- /dev/null +++ b/seriell/write.h @@ -0,0 +1,110 @@ +/* + + weatherdeamon -- Weather Data Capture Program for the + 'ELV-PC-Wettersensor-Empfänger' + write.h -- 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 + +/* Datenstrukturen für die einzelnen Sensoren ------------------------------- */ + +/* Datenstruktur für den 'einfachen' Außensensor */ +typedef struct { + time_t timestamp; /*Zeitstempel*/ + unsigned char address; /*Addresse*/ + int temp; /*Temparatur*/ +} auss1_data ; + +/* Datenstruktur für den 'besseren' Außensensor */ +typedef struct { + time_t timestamp; /*Zeitstempel*/ + unsigned char address; /*Addresse*/ + int temp; /*Temparatur*/ + unsigned int hum; /*Luftfeuchte*/ +} auss2_data; + +/* Datenstruktur für den Regensensor */ +typedef struct { + time_t timestamp; /*Zeitstempel*/ + unsigned char address; /*Addresse*/ + unsigned int counter; /*Zählerstand*/ +} regen_data; + +/* Datenstruktur für den Windsensor */ +typedef struct { + time_t timestamp; /*Zeitstempel*/ + unsigned char address; /*Addresse*/ + unsigned int geschw; /*Windgeschwindigkeit*/ + unsigned int schwank; /*Schwankungsbreite*/ + unsigned int richt; /*Windrichtung*/ +} winds_data; + +/* Datenstruktur für den Innensensor */ +typedef struct { + time_t timestamp; /*Zeitstempel*/ + unsigned char address; /*Addresse*/ + int temp; /*Temparatur*/ + unsigned int hum; /*Luftfeuchte*/ + unsigned int press; /*Luftdruck*/ +} innen_data; + +/* Datenstruktur für den Helligkeitssensor */ +typedef struct { + time_t timestamp; /*Zeitstempel*/ + unsigned char address; /*Addresse*/ + unsigned int rawlum; /*'Roh-Helligkeit' - Helligkeit ohne Multiplikator*/ + unsigned int mult; /*Multiplikator*/ + unsigned int abslum; /*Absolute Helligkeit*/ +} helli_data; + +/* Datenstruktur für das Pyanometer */ +typedef struct { + time_t timestamp; /*Zeitstempel*/ + unsigned char address; /*Addresse*/ + unsigned int rawrad; /*'Roh-Strahlung' - Strahlung ohne Multiplikator*/ + unsigned int mult; /*Multiplikator*/ + unsigned int absrad; /*Absolute Strahlung*/ +} pyano_data; + + +/* Funktionen zum wegschreiben der Daten ----------------------------------- */ + +/* 'einfacher' Außensensor */ +void write_auss1(auss1_data); + +/* 'besserer' Außensensor */ +void write_auss2(auss2_data); + +/* Regensensor */ +void write_regen(regen_data); + +/* Windsensor */ +void write_winds(winds_data); + +/* Innensensor */ +void write_innen(innen_data); + +/* Helligkeitssensor */ +void write_helli(helli_data); + +/* Pyanometer */ +void write_pyano(pyano_data);