root/driver/wwsr3.3.c

Revision 10, 22.8 KB (checked in by pzitny, 2 years ago)
Line 
1/*
2 * wwsr - Wireless Weather Station Reader
3 * 2007 dec 19, Michael Pendec (michael.pendec@gmail.com)
4 *  Version 0.5
5 * 2008 jan 24 Svend Skafte (svend@skafte.net)
6 * 2008 sep 28 Adam Pribyl (covex@lowlevel.cz)
7 *  Modifications for different firmware version(?)
8 * 2009 feb 1 Bradley Jarvis (bradley.jarvis@dcsi.net.au)
9 *  major code cleanup
10 *  update read to access device discretly
11 *  added user formatted output
12 *  added log function and fixed debug messaging
13 * 2009 mar 28 Lukas Zvonar (lukic@mag-net.sk)
14 *  added relative pressure formula (need to compile with -lm switch)
15 *  correct display of negative temperatures
16 * 2009 apr 16 Petr Zitny (petr@zitny.net)
17 *  added XML output (-x)
18 *  fixed new line in help
19 * 2009 apr 17 Lukas Zvonar (lukic@mag-net.sk)
20 *  some code cleanup @ style work with format string
21 *  added possibility of changing log position of weather station (-p switch)
22 *  added 1h and 24h rainfall computation in mm/h
23    (and also i'm expecting possible error in owerflow of
24     address in weatherstation log when meteostation resets
25     it's log possition to "zero". This takes max 24h to
26     cleanup itself. To correct this, I need to know exact
27     min and max possition of weatherstation log)
28 *  patch for xml - added new values
29 * 2009 apr 19 Lukas Zvonar (lukic@mag-net.sk)
30 *  corrected reading of -d (dump address and size) and -a (vendor and product
31    number) parameters ( from int to short int) - which lead to overwriting
32    variables.. This could be problem on gcc compilers interpreting
33    int as 2 byte and short as 1 byte. But now is int defined as 4 byte
34    and short as 2 byte.
35 * 2009 apr 21 Lukas Zvonar (lukic@mag-net.sk)
36 *  added errstr, which is printed out if station lost connection to outdoor unit
37    or somehow data from weather station are out of limits. Thanks to Petr Zitny.
38 * 2009 apr 23 Petr Zitny (petr@zitny.net)
39 *  repair some if for test lost connection to outdoor unit
40 */
41#include <stdio.h>
42#include <string.h>
43#include <stdlib.h>
44#include <string.h>
45#include <stdarg.h>
46#include <usb.h>
47#include <time.h>
48#include <math.h>
49
50#define PACKAGE "wwsr"
51#define DEFAULT_VENDOR    0x1941
52#define DEFAULT_PRODUCT   0x8021
53#define DEFAULT_FORMAT    (char *)"time:                  %N\nin humidity:           %h %%\nout humidity:          %H %%\nin temperature:        %t C\nout temperature:       %T C\nout dew temperature:   %C C\nwindchill temperature: %c C\nwind speed:            %W m/s\nwind gust:             %G m/s\nwind direction:        %D\npressure:              %P hPa\nrel. pressure:         %p hPa\nrain last hour:        %r mm\nrain last 24h:         %F mm\nrain total:            %R mm\n"
54
55#define WS_CURRENT_ENTRY  30
56#define WS_MIN_ENTRY_ADDR 0x0100
57#define WS_MAX_ENTRY_ADDR 0xFFF0
58
59int ws_open(usb_dev_handle **dev,uint16_t vendor,uint16_t product);
60int ws_close(usb_dev_handle *dev);
61
62int ws_read(usb_dev_handle *dev,uint16_t address,uint8_t *data,uint16_t size);
63int ws_reset(usb_dev_handle *dev);
64int ws_print(char *format,uint8_t *buffer,uint8_t *buffer2,uint8_t *buffer3);
65int ws_dump(uint16_t address,uint8_t *buffer,uint16_t size,uint8_t width);
66
67int altitude=0; //default altitude is sea level - change it if you need, or use -A parameter
68int position=0; //default position in log is "now". Altering this can lead to read some of stored values in weather station
69
70char* errorstring="NaN"; //what to write if value is out of range (e.g. outdoor unit is disconnected)
71
72typedef enum log_event
73{
74        LOG_DEBUG=1,
75        LOG_WARNING=2,
76        LOG_ERROR=4,
77        LOG_INFO=8
78} log_event;
79FILE *_log_debug=NULL,*_log_warning=NULL,*_log_error=NULL,*_log_info=NULL;
80
81void logger(log_event event,char *function,char *msg,...);
82
83
84
85int main(int argc, char **argv)
86{
87        usb_dev_handle *dev;
88  int rv,c;
89  uint16_t vendor,product;
90  uint8_t help;
91  char* format=NULL;
92 
93  rv=0;
94  dev=NULL;
95  vendor=DEFAULT_VENDOR;
96  product=DEFAULT_PRODUCT;
97  format=DEFAULT_FORMAT;
98  help=0;
99 
100  _log_error=stderr;
101  _log_info=stdout;
102 
103        while (rv==0 && (c=getopt(argc,argv,"h?vxf:d:a:A:p:e:"))!=-1)
104        {
105                switch (c)
106                {
107                        case 'a': // set device id
108                                sscanf(optarg,"%hX:%hX",&vendor,&product);
109                                logger(LOG_DEBUG,"main","USB device set to vendor=%04X product=%04X",vendor,product);
110                                break;
111
112                        case 'A': // set altitude
113                                sscanf(optarg,"%d",&altitude);
114                                logger(LOG_DEBUG,"main","altitude set to %d",altitude);
115                                break;
116
117                        case 'p': // set altitude
118                                sscanf(optarg,"%d",&position);
119                                logger(LOG_DEBUG,"main","weather station log position set to %d",position);
120                                break;
121                       
122                        case 'v': // Verbose messages
123                                _log_debug=_log_warning=stdout;
124                                logger(LOG_DEBUG,"main","Verbose messaging turned on");
125                                break;
126
127                        case 'x': // XML export
128                                optarg = "<data>\
129\n\t<timestamp>\n\t\t<data>%N</data>\n\t</timestamp>\
130\n\t<temp>\n\t\t<indoor>\n\t\t\t<data>%t</data>\n\t\t\t<unit>C</unit>\n\t\t</indoor>\n\t\t<outdoor>\n\t\t\t<data>%T</data>\n\t\t\t<unit>C</unit>\n\t\t</outdoor>\n\t\t<windchill>\n\t\t\t<data>%c</data>\n\t\t\t<unit>C</unit>\n\t\t</windchill>\n\t\t<dewpoint>\n\t\t\t<data>%C</data>\n\t\t\t<unit>C</unit>\n\t\t</dewpoint>\n\t</temp>\
131\n\t<wind>\n\t\t<speed>\n\t\t\t<data>%W</data>\n\t\t\t<unit>m/s</unit>\n\t\t</speed>\n\t\t<gust>\n\t\t\t<data>%G</data>\n\t\t\t<unit>m/s</unit>\n\t\t</gust>\n\t\t<direct>\n\t\t\t<data>%d</data>\n\t\t\t<unit>degrees</unit>\n\t\t</direct>\n\t\t<direct_str>\n\t\t\t<data>%D</data>\n\t\t\t<unit>Str</unit>\n\t\t</direct_str>\n\t</wind>\
132\n\t<pressure>\n\t\t<abs>\n\t\t\t<data>%P</data>\n\t\t\t<unit>hPa</unit>\n\t\t</abs>\n\t\t<rel>\n\t\t\t<data>%p</data>\n\t\t\t<unit>hPa</unit>\n\t\t</rel>\n\t</pressure>\
133\n\t<rain>\n\t\t<hour>\n\t\t\t<data>%r</data>\n\t\t\t<unit>mm</unit>\n\t\t</hour>\n\t\t<day>\n\t\t\t<data>%F</data>\n\t\t\t<unit>mm</unit>\n\t\t</day>\n\t\t<total>\n\t\t\t<data>%R</data>\n\t\t\t<unit>mm</unit>\n\t\t</total>\n\t</rain>\
134\n\t<humidity>\n\t\t<indoor>\n\t\t\t<data>%h</data>\n\t\t\t<unit>%%</unit>\n\t\t</indoor>\n\t\t<outdoor>\n\t\t\t<data>%H</data>\n\t\t\t<unit>%%</unit>\n\t\t</outdoor>\n\t</humidity>\
135\n</data>\n";
136                        case 'f': // Format output
137                                logger(LOG_DEBUG,"main","Format output using '%s'",optarg);
138                                format=optarg;
139                                break;
140
141                        case 'e': // Error string
142                                logger(LOG_DEBUG,"main","Error string set to: '%s'",optarg);
143                                errorstring=optarg;
144                                break;
145                       
146                        case 'd': // Dump raw data from weather station
147                        {
148                                uint16_t a,s,w;
149                               
150                                a=0;
151                                s=0x100;
152                                w=16;
153//                              sscanf(optarg,"0x%hX:0x%hX",&a,&s);
154                                if (sscanf(optarg,"0x%hX:0x%hX",&a,&s)<2)
155                                if (sscanf(optarg,"0x%hX:%hu",&a,&s)<2)
156                                if (sscanf(optarg,"%hu:0x%hX",&a,&s)<2)
157                                if (sscanf(optarg,"%hu:%hu",&a,&s)<2)
158                                if (sscanf(optarg,":0x%hX",&s)<1)
159                                        sscanf(optarg,":%hu",&s);
160                               
161                                logger(LOG_DEBUG,"main","Dump options address=%u size=%u",a,s);
162                               
163                                if (dev==NULL)
164                                {
165                                        rv=ws_open(&dev,vendor,product);
166                                }
167                               
168                                if (dev)
169                                {
170                                        uint8_t *b;
171                                       
172                                        logger(LOG_DEBUG,"main","Allocating %u bytes for read buffer",s);
173                                        b=malloc(s);
174                                        if (!b) logger(LOG_ERROR,"main","Could not allocate %u bytes for read buffer",s);
175                                       
176                                        if (b)
177                                        {
178                                                logger(LOG_DEBUG,"main","Allocated %u bytes for read buffer",s);
179                                               
180                                                ws_read(dev,a,b,s);
181                                                ws_dump(a,b,s,w);
182                                               
183                                                free(b);
184                                        }
185                                }
186                                break;
187                        }
188                       
189                        case '?':
190                        case 'h':
191                                help=1;
192                                printf("Wireless Weather Station Reader v0.1\n");
193                                printf("(C) 2007 Michael Pendec\n\n");
194                                printf("options\n");
195                                printf(" -? -h            Display this help\n");
196                                printf(" -a <v>:<p>       Change the vendor:product address of the usb device from the default\n");
197                                printf(" -A <alt in m>    Change altitude\n");
198                                printf(" -p <pos>         Alter position in weather station log from current position (can be +- value)\n");
199                                printf(" -v               Verbose output, enable debug and warning messages\n");
200                                printf(" -d [addr]:[len]  Dump length bytes from address\n");
201                                printf(" -x               XML output\n");
202                                printf(" -e <errstr>      Write this errstr if measured value is out of range (e.g. outdoor unit is disconnected)\n");
203                                printf(" -f <string>      Format output to user defined string\n");
204                                printf("    %%h - inside humidity\n");
205                                printf("    %%H - outside humidity\n");
206                                printf("    %%t - inside temperature\n");
207                                printf("    %%T - outside temperature\n");
208                                printf("    %%C - outside dew temperature\n");
209                                printf("    %%c - outside wind chill temperature\n");
210                                printf("    %%W - wind speed\n");
211                                printf("    %%G - wind gust\n");
212                                printf("    %%D - wind direction - named\n");
213                                printf("    %%S - wind direction - slovak names\n");
214                                printf("    %%d - wind direction - degrees\n");
215                                printf("    %%P - pressure\n");
216                                printf("    %%p - relative pressure\n");
217                                printf("    %%r - rain 1h in mm/h\n");
218                                printf("    %%f - rain 24h in mm/h\n");
219                                printf("    %%F - rain last 24h in mm\n");
220                                printf("    %%R - rain total from meteostation start in mm\n");
221                                printf("    %%N - now - date/time string\n");
222                }
223        }
224       
225        if (rv==0 && dev==NULL && help==0)
226        {
227                uint16_t address,newposition,newposition1,newposition24; // current address in log, new address and new address -1h and - 24h (for rainfall computation)
228                uint8_t buffer[0x10];
229                uint8_t buffer2[0x10]; //30-60 min ago for 1h rainfall computation
230                uint8_t buffer3[0x10]; //1410-1440 min ago for 24h rainfall computation
231               
232                rv=ws_open(&dev,vendor,product);
233               
234                if (rv==0) rv=ws_read(dev,WS_CURRENT_ENTRY,(unsigned char *)&address,sizeof(address));  //read current log address
235
236                newposition=address+(position*0x10);         //alter this address according to user parameter
237                newposition1=address+(position*0x10)-0x20;   //alter -1h address according to user parameter
238                newposition24=address+(position*0x10)-0x300; //alter -24h address according to user parameter
239
240                if ((newposition > WS_MAX_ENTRY_ADDR) || (newposition < WS_MIN_ENTRY_ADDR))     //check for buffer owerflow
241                          {newposition=(newposition && 0xFFFF) + WS_MIN_ENTRY_ADDR; }
242                if ((newposition1 > WS_MAX_ENTRY_ADDR) || (newposition1 < WS_MIN_ENTRY_ADDR))   //check for buffer owerflow
243                          {newposition1=(newposition1 && 0xFFFF) + WS_MIN_ENTRY_ADDR; }
244                if ((newposition24 > WS_MAX_ENTRY_ADDR) || (newposition24 < WS_MIN_ENTRY_ADDR)) //check for buffer owerflow
245                          {newposition24=(newposition24 && 0xFFFF) + WS_MIN_ENTRY_ADDR; }
246
247                if (rv==0) rv=ws_read(dev,newposition,buffer,sizeof(buffer));        //read current position
248                if (rv==0) rv=ws_read(dev,newposition1,buffer2,sizeof(buffer));      //read -1h buffer (in real 30-59 min ago)
249                if (rv==0) rv=ws_read(dev,newposition24,buffer3,sizeof(buffer));     //read -24h buffer (in real 23,5-24 h ago)
250                if (rv==0) rv=ws_print(format,buffer,buffer2,buffer3);
251        }
252       
253        if (dev)
254        {
255                ws_close(dev);
256        }
257       
258        return rv;
259}
260
261int ws_open(usb_dev_handle **dev,uint16_t vendor,uint16_t product)
262{
263        int rv;
264        struct usb_bus *bus;
265       
266        rv=0;
267        *dev=NULL;
268       
269        logger(LOG_DEBUG,"ws_open","Initialise usb");
270        usb_init();
271        usb_set_debug(0);
272        usb_find_busses();
273        usb_find_devices();
274       
275        logger(LOG_DEBUG,"ws_open","Scan for device %04X:%04X",vendor,product);
276        for (bus=usb_get_busses(); bus && *dev==NULL; bus=bus->next)
277        {
278                struct usb_device *device;
279               
280                for (device=bus->devices; device && *dev==NULL; device=device->next)
281                {
282                        if (device->descriptor.idVendor == vendor
283                                && device->descriptor.idProduct == product)
284                        {
285                                logger(LOG_DEBUG,"ws_open","Found device %04X:%04X",vendor,product);
286                                *dev=usb_open(device);
287                        }
288                }
289        }
290       
291        if (rv==0 && *dev)
292        {
293                char buf[100];
294               
295                switch (usb_get_driver_np(*dev,0,buf,sizeof(buf)))
296                {
297                        case 0:
298                                logger(LOG_WARNING,"ws_open","Interface 0 already claimed by driver \"%s\", attempting to detach it", buf);
299                                rv=usb_detach_kernel_driver_np(*dev,0);
300                }
301               
302                if (rv==0)
303                {
304                        logger(LOG_DEBUG,"ws_open","Claim device");
305                        rv=usb_claim_interface(*dev,0);
306                }
307               
308                if (rv==0)
309                {
310                        logger(LOG_DEBUG,"ws_open","Set alt interface");
311                        rv=usb_set_altinterface(*dev,0);
312                }
313        }
314        else
315        {
316                logger(LOG_ERROR,"ws_open","Device %04X:%04X not found",vendor,product);
317                rv=1;
318        }
319       
320        if (rv==0)
321        {
322                logger(LOG_DEBUG,"ws_open","Device %04X:%04X opened",vendor,product);
323        }
324        else
325        {
326                logger(LOG_ERROR,"ws_open","Device %04X:%04X: could not open, code:%d",vendor,product,rv);
327        }
328       
329        return rv;
330}
331
332int ws_close(usb_dev_handle *dev)
333{
334        int rv;
335
336        if (dev)
337        {
338                rv=usb_release_interface(dev, 0);
339                if (rv!=0) logger(LOG_ERROR,"ws_close","Could not release interface, code:%d", rv);
340               
341                rv=usb_close(dev);
342                if (rv!=0) logger(LOG_ERROR,"ws_close","Error closing interface, code:%d", rv);
343        }
344       
345        return rv;
346}
347
348int ws_read(usb_dev_handle *dev,uint16_t address,uint8_t *data,uint16_t size)
349{
350        uint16_t i,c;
351        int rv;
352        uint8_t s,tmp[0x20];
353       
354        memset(data,0,size);
355       
356        logger(LOG_DEBUG,"ws_read","Reading %d bytes from 0x%04X",size,address);
357       
358        i=0;
359        c=sizeof(tmp);
360        s=size-i<c?size-i:c;
361       
362        for (;i<size;i+=s, s=size-i<c?size-i:c)
363        {
364                uint16_t a;
365                char cmd[9];
366               
367                a=address+i;
368               
369                logger(LOG_DEBUG,"ws_read","Send read command: Addr=0x%04X Size=%u",a,s);
370                sprintf(cmd,"\xA1%c%c%c\xA1%c%c%c",a>>8,a,c,a>>8,a,c);
371                rv=usb_control_msg(dev,USB_TYPE_CLASS+USB_RECIP_INTERFACE,9,0x200,0,cmd,sizeof(cmd)-1,1000);
372                logger(LOG_DEBUG,"ws_read","Sent %d of %d bytes",rv,sizeof(cmd)-1); 
373                rv=usb_interrupt_read(dev,0x81,tmp,c,1000);
374                logger(LOG_DEBUG,"ws_read","Read %d of %d bytes",rv,c); 
375               
376                memcpy(data+i,tmp,s);
377        }
378       
379        return 0;
380}
381
382int ws_reset(usb_dev_handle *dev)
383{
384        printf("Resetting WetterStation history\n");
385       
386        usb_control_msg(dev,USB_TYPE_CLASS+USB_RECIP_INTERFACE,9,0x200,0,"\xA0\x00\x00\x20\xA0\x00\x00\x20",8,1000);
387        usb_control_msg(dev,USB_TYPE_CLASS+USB_RECIP_INTERFACE,9,0x200,0,"\x55\x55\xAA\xFF\xFF\xFF\xFF\xFF",8,1000);
388        //_send_usb_msg("\xa0","\x00","\x00","\x20","\xa0","\x00","\x00","\x20");
389        //_send_usb_msg("\x55","\x55","\xaa","\xff","\xff","\xff","\xff","\xff");
390        usleep(28*1000);
391       
392        usb_control_msg(dev,USB_TYPE_CLASS+USB_RECIP_INTERFACE,9,0x200,0,"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF",8,1000);
393        //_send_usb_msg("\xff","\xff","\xff","\xff","\xff","\xff","\xff","\xff");
394        usleep(28*1000);
395       
396        //_send_usb_msg("\x05","\x20","\x01","\x38","\x11","\x00","\x00","\x00");
397        usb_control_msg(dev,USB_TYPE_CLASS+USB_RECIP_INTERFACE,9,0x200,0,"\x05\x20\x01\x38\x11\x00\x00\x00",8,1000);
398        usleep(28*1000);
399       
400        //_send_usb_msg("\x00","\x00","\xaa","\x00","\x00","\x00","\x20","\x3e");
401        usb_control_msg(dev,USB_TYPE_CLASS+USB_RECIP_INTERFACE,9,0x200,0,"\x00\x00\xAA\x00\x00\x00\x20\x3E",8,1000);
402        usleep(28*1000);
403       
404        return 0;
405}
406
407int ws_print(char *format,uint8_t *buffer,uint8_t *buffer2,uint8_t *buffer3)
408{
409        char *dir[]=
410        {
411                "N","NNE","NE","ENE","E","ESE","SE","SSE",
412                "S","SSW","SW","WSW","W","WNW","NW","NNW"
413        };
414        char *dirdeg[]=
415        {
416                "0","23","45","68","90","113","135","158",
417                "180","203","225","248","270","293","315","338"
418        };
419        char *dirslovak[]=              {"S","SSV","SV","VSV","V","VJV","JV","JJV",
420                                         "J","JJZ","JZ","ZJZ","Z","ZSZ","SZ","SSZ"};   
421
422        time_t basictime;
423        char datestring[50]; 
424        float p,temp,m,windspeed,tw,hum,gama,rf,rf2;
425        short tempi,tempo;
426
427        if (buffer[0x06] >= 0x80) tempo=buffer[0x05]+(buffer[0x06]<<8) ^ 0x7FFF;   //weather station uses top bit for sign and not normal
428                          else    tempo=buffer[0x05]+(buffer[0x06]<<8) ^ 0x0000;   //signed short, so we need to correct this with xor
429        if (buffer[0x03] >= 0x80) tempi=buffer[0x02]+(buffer[0x03]<<8) ^ 0x7FFF;   //we need to do the same correction to indoor temp
430                          else    tempi=buffer[0x02]+(buffer[0x03]<<8) ^ 0x0000;   //
431        temp=(float)(tempo)/10;         //outdoor temp for computing Tdew, Windchill and Rel.pressure
432
433//        if (abs(temp) > 10000) {printf("err"); *format=(char)""; }    //if temp is over +-1000 °C, we lost connection to outdoor unit, so write error
434
435
436        for (;*format;format++)
437        {
438                if (*format=='%')
439                {
440                        switch (*++format)
441                        {
442                                case 'h': // inside humidity
443                                        if ((buffer[0x01] > 100) || (buffer[0x01] == 0)) printf("%s",errorstring); else
444                                        printf("%d",buffer[0x01]);
445                                        break;
446                               
447                                case 'H': // outside humidity
448                                        if ((buffer[0x04] > 100) || (buffer[0x04] == 0)) printf("%s",errorstring); else
449                                        printf("%d",buffer[0x04]);
450                                        break;
451                               
452                                case 't': // inside temperature
453                                        if ((tempi > 2000) || (tempi < -2000)) printf("%s",errorstring); else
454                                        printf("%0.1f",(float)(tempi)/10);
455                                        break;
456                               
457                                case 'T': // outside temperature
458                                        if ((temp > 200) || (temp < -200)) printf("%s",errorstring); else
459                                        printf("%0.1f",temp);
460                                        break;
461
462                                case 'C': // dew point based on outside temperature (formula from wikipedia)
463                                        if ((temp > 200) || (temp < -200) || (buffer[0x04] > 100)) printf("%s",errorstring); 
464                                        else
465                                        {
466                                            hum=(float)buffer[0x04]/100;                         //humidity / 100
467                                            if (hum == 0) hum=0.001;                             //in case of 0% humidity
468                                            gama=(17.271*temp)/(237.7+temp) + log (hum);         //gama=aT/(b+T) + ln (RH/100)
469                                            tw= (237.7 * gama) / (17.271 - gama);                //Tdew= (b * gama) / (a - gama)
470                                            printf("%0.1f",tw);
471                                        }
472                                        break;
473
474                                case 'c': // windchill temperature
475                                        if ((temp > 200) || (temp < -200) || (buffer[0x09] == 255)) printf("%s",errorstring); 
476                                        else
477                                        {
478                                            windspeed=(float)(buffer[0x09])/10 * 3.6;   //in km/h
479                                            //if (( windspeed > 4.8 ) && (temp < 10))   //formula from wikipedia only at condition
480                                            tw=13.12 + 0.6215 * temp - 11.37*pow(windspeed,0.16) + 0.3965*temp*pow(windspeed,0.16);
481                                            //else tw=temp;                             //else nothing..
482                                            if(temp<tw) tw=temp; //windchill can't be more than temp
483                                            printf("%0.1f",tw);
484                                        }
485                                        break;
486                               
487                                case 'W': // wind speed
488                                        if ((temp > 200) || (temp < -200) || (buffer[0x09] == 255)) printf("%s",errorstring); else
489                                        printf("%0.1f",(float)(buffer[0x09])/10);
490                                        break;
491                               
492                                case 'G': // wind gust
493                                        if ((temp > 200) || (temp < -200) || (buffer[0x0A] == 255)) printf("%s",errorstring); else
494                                        printf("%0.1f",(float)(buffer[0x0A])/10);
495                                        break;
496                               
497                                case 'D': // wind direction - named
498                                        printf(dir[buffer[0x0C]<sizeof(dir)/sizeof(dir[0])?buffer[0x0C]:0]);
499                                        break;
500
501                                case 'S': // wind direction - named Slovak
502                                        printf(dirslovak[buffer[0x0C]<sizeof(dir)/sizeof(dir[0])?buffer[0x0C]:0]);
503                                        break;
504
505                                case 'd': // wind direction - degrees
506                                        printf(dirdeg[buffer[0x0C]<sizeof(dir)/sizeof(dir[0])?buffer[0x0C]:0]);
507                                        break;
508                               
509                                case 'P': // pressure
510                                        if ((temp > 200) || (temp < -200)) printf("%s",errorstring); 
511                                        else
512                                        {
513                                            printf("%0.1f",(float)(buffer[0x07]+(buffer[0x08]<<8))/10);
514                                        }
515                                        break;
516                               
517                                case 'p': // rel. pressure
518                                        if ((temp > 200) || (temp < -200)) printf("%s",errorstring); 
519                                        else
520                                        {
521                                            p=(float)(buffer[0x07]+(buffer[0x08]<<8))/10; //abs. pressure
522                                            m=altitude / (18429.1 + 67.53 * temp + 0.003 * altitude); //power exponent to correction function
523                                            p=p * pow(10,m); //relative pressure * correction
524                                            printf("%0.1f",p);
525                                        }
526                                        break;
527                               
528                                case 'R': // rain total counter
529                                        printf("%0.1f",(float)(buffer[0x0D]+(buffer[0x0E]<<8))*0.3);
530                                        break;
531                                case 'r': // rain 1h in mm/h
532                                        rf=(float)(buffer[0x0D]+(buffer[0x0E]<<8));     //current rainfall total -
533                                        rf2=(float)(buffer2[0x0D]+(buffer2[0x0E]<<8));  //prev.last saved rainfall total
534                                        if ((rf-rf2) < 0) { rf=0; rf2=0;}               //if something is wrong..
535                                        if (rf2 >= 65000) { rf=0; rf2=0;}               //if something is wrong..
536                                        printf("%0.1f",(rf-rf2)*0.3*60/(30+buffer[0x00]));      //current-last/time (30-59 min)
537                                        break;
538
539                                case 'f': // rain 24h in mm/h
540                                        rf=(float)(buffer[0x0D]+(buffer[0x0E]<<8));     //current rainfall total -
541                                        rf2=(float)(buffer3[0x0D]+(buffer3[0x0E]<<8));  //-24h saved rainfall total
542                                        if ((rf-rf2) < 0) { rf=0; rf2=0;}               //if something is wrong..
543                                        if (rf2 >= 65000) { rf=0; rf2=0;}               //if something is wrong..
544                                        printf("%0.1f",(rf-rf2)*0.3*60/(30*47+buffer[0x00]));   //current-last/time
545                                        break;
546
547                                case 'F': // rain 24h in mm
548                                        rf=(float)(buffer[0x0D]+(buffer[0x0E]<<8));     //current rainfall total -
549                                        rf2=(float)(buffer3[0x0D]+(buffer3[0x0E]<<8));  //-24h saved rainfall total
550                                        if ((rf-rf2) < 0) { rf=0; rf2=0;}               //if something is wrong..
551                                        if (rf2 >= 65000) { rf=0; rf2=0;}               //if something is wrong..
552                                        printf("%0.1f",(rf-rf2)*0.3);           //current-last/time
553                                        break;
554
555                                case 'N': // date
556                                        time(&basictime);
557                                        basictime=basictime+position*30*60;
558                                        strftime(datestring,sizeof(datestring),"%Y-%m-%d %H:%M:%S",
559                                         localtime(&basictime));  //neeeeeeeeeeeeeeeeed to alter if -p param is applied
560                                        // Print out and leave
561                                        printf("%s",datestring);
562                                        break;
563                                case '%': // percents
564                                        printf("%%");
565                                        break;
566                        }
567                }
568                else if (*format=='\\')
569                {
570                        switch (*++format)
571                        {
572                                case 'n':
573                                        printf("\n");
574                                        break;
575                               
576                                case 'r':
577                                        printf("\r");
578                                        break;
579                               
580                                case 't':
581                                        printf("\t");
582                                        break;
583                               
584                        }
585                }
586                else
587                {
588                        printf("%c",*format);
589                }
590        }
591       
592        return 0;
593}
594
595int ws_dump(uint16_t address,uint8_t *data,uint16_t size,uint8_t w)
596{
597        uint16_t i,j,s;
598        char *buf;
599       
600        s=8+(w*5)+1;
601        logger(LOG_DEBUG,"ws_dump","Allocate %u bytes for temporary buffer",s);
602        buf=malloc(s);
603        if (!buf) logger(LOG_WARNING,"ws_dump","Could not allocate %u bytes for temporary buffer, verbose dump enabled",s);
604       
605        logger(LOG_INFO,"ws_dump","Dump %u bytes from address 0x%04X",size,address);
606        for (i=0;i<size && buf && data;)
607        {
608                if (buf) sprintf(buf,"0x%04X:",address+i);
609                for (j=0;j<w && i<size;i++,j++)
610                {
611                        if (buf)
612                        {
613                                sprintf(buf,"%s 0x%02X",buf,data[i]);
614                        } else
615                        {
616                                logger(LOG_INFO,"ws_dump","0x%04X: 0x%02X",address+i,data[i]);
617                        }
618                }
619                if (buf) logger(LOG_INFO,"ws_dump",buf);
620        }
621       
622        return 0;
623}
624
625void logger(log_event event,char *function,char *msg,...)
626{
627        va_list args;
628       
629        va_start(args,msg);
630        switch (event)
631        {
632                case LOG_DEBUG:
633                        if (_log_debug)
634                        {
635                                fprintf(_log_debug,"message: wwsr.%s - ",function);
636                                vfprintf(_log_debug,msg,args);
637                                fprintf(_log_debug,"\n");
638                        }
639                        break;
640               
641                case LOG_WARNING:
642                        if (_log_warning)
643                        {
644                                fprintf(_log_warning,"warning: wwsr.%s - ",function);
645                                vfprintf(_log_warning,msg,args);
646                                fprintf(_log_warning,"\n");
647                        }
648                        break;
649               
650                case LOG_ERROR:
651                        if (_log_error)
652                        {
653                                fprintf(_log_error,"error: wwsr.%s - ",function);
654                                vfprintf(_log_error,msg,args);
655                                fprintf(_log_error,"\n");
656                        }
657                        break;
658               
659                case LOG_INFO:
660                        if (_log_info)
661                        {
662                                fprintf(_log_info,"info: wwsr.%s - ",function);
663                                vfprintf(_log_info,msg,args);
664                                fprintf(_log_info,"\n");
665                        }
666                        break;
667        }
668        va_end(args);
669}
670
Note: See TracBrowser for help on using the browser.