Mercurial > ~darius > hgwebdir.cgi > wh1080
comparison db/insertBoM.c @ 0:9dab44dcb331
Initial commit of Greg's code from http://www.lemis.com/grog/tmp/wh1080.tar.gz
author | Daniel O'Connor <darius@dons.net.au> |
---|---|
date | Tue, 09 Feb 2010 13:44:25 +1030 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:9dab44dcb331 |
---|---|
1 /* | |
2 * Read in Australian Bureau of Meteorology comma-delimited files and convert | |
3 * them into INSERT commands for MySQL. | |
4 * | |
5 * $Id: insertBoM.c,v 1.4 2010/01/03 05:05:28 grog Exp $ | |
6 */ | |
7 #include <ctype.h> | |
8 #include <stdio.h> | |
9 #include <stdlib.h> | |
10 #include <string.h> | |
11 #include <sys/file.h> | |
12 #include <sys/stat.h> | |
13 #include <sys/types.h> | |
14 #include <unistd.h> | |
15 | |
16 #define BUFSIZE 1024 | |
17 char buf [BUFSIZE]; | |
18 char sql_command [BUFSIZE]; | |
19 | |
20 /* We split up the input line into these fields, not all of which we use. */ | |
21 char *field [50]; /* pointers to beginnings of fields */ | |
22 | |
23 /* | |
24 * We alias these structs to the input field above. Unfortunately, the data | |
25 * returned from Sheoaks is different from Ballarat and Melbourne airports: | |
26 * Sheoaks doesn't report a QNH pressure. I should really parse the input files | |
27 * to check the fields, but it's pretty messy. | |
28 */ | |
29 | |
30 struct ballarat_row | |
31 { | |
32 char *order; /* sort order (backwards!) */ | |
33 char *station_id; /* station ID, apparently always numeric */ | |
34 char *name; /* name of town, it would seem */ | |
35 char *history; /* this looks like another station ID */ | |
36 char *funnydate; /* date in useless form 0D/0H:0m[ap]m */ | |
37 char *date; /* date as YYYYMMDDHHmmSS */ | |
38 char *temp; /* temperature, °C */ | |
39 char *apparent_temp; /* apparent temperature */ | |
40 char *delta_t; /* wet bulb depression */ | |
41 char *dewpoint; /* dew point */ | |
42 char *wind_gust; /* wind gust speed */ | |
43 char *gust_knots; /* same again in knots */ | |
44 char *pressure_msl; /* pressure at mean sea level */ | |
45 char *pressure_qnh; /* QNH pressure, whatever that may be */ | |
46 char *rain; /* rain as text (can be "Tce") */ | |
47 char *humidity; /* relative humdity */ | |
48 char *wind_direction_text; /* text of direction */ | |
49 char *wind_speed; /* speed in km/h */ | |
50 char *wind_speed_knots; /* and in knots */ | |
51 } *ballarat_readings = (struct ballarat_row *) field; | |
52 | |
53 struct sheoaks_row | |
54 { | |
55 char *order; /* sort order (backwards!) */ | |
56 char *station_id; /* station ID, apparently always numeric */ | |
57 char *name; /* name of town, it would seem */ | |
58 char *history; /* this looks like another station ID */ | |
59 char *funnydate; /* date in useless form 0D/0H:0m[ap]m */ | |
60 char *date; /* date as YYYYMMDDHHmmSS */ | |
61 char *temp; /* temperature, °C */ | |
62 char *apparent_temp; /* apparent temperature */ | |
63 char *delta_t; /* wet bulb depression */ | |
64 char *dewpoint; /* dew point */ | |
65 char *wind_gust; /* wind gust speed */ | |
66 char *gust_knots; /* same again in knots */ | |
67 char *pressure_msl; /* pressure at mean sea level */ | |
68 char *rain; /* rain as text (can be "Tce") */ | |
69 char *humidity; /* relative humdity */ | |
70 char *wind_direction_text; /* text of direction */ | |
71 char *wind_speed; /* speed in km/h */ | |
72 char *wind_speed_knots; /* and in knots */ | |
73 } *sheoaks_readings = (struct sheoaks_row *) field; | |
74 | |
75 void skipblanks (char **cp) | |
76 { | |
77 while (**cp == ' ') | |
78 (*cp)++; | |
79 } | |
80 | |
81 /* | |
82 * Wind directions as text. BoM encloses them in "", so we do the same | |
83 */ | |
84 struct wind_directions | |
85 { | |
86 char *text; /* name of direction */ | |
87 float direction; /* and the direction it represents */ | |
88 } wind_directions [] = { | |
89 {"\"N\"", 0}, | |
90 {"\"North\"", 0}, | |
91 {"\"NNE\"", 22.5}, | |
92 {"\"NE\"", 45}, | |
93 {"\"ENE\"", 67.5}, | |
94 {"\"E\"", 90}, | |
95 {"\"East\"", 90}, | |
96 {"\"ESE\"", 112.5}, | |
97 {"\"SE\"", 135}, | |
98 {"\"SSE\"", 157.5}, | |
99 {"\"S\"", 180}, | |
100 {"\"South\"", 180}, | |
101 {"\"SSW\"", 202.5}, | |
102 {"\"SW\"", 225}, | |
103 {"\"WSW\"", 247.5}, | |
104 {"\"W\"", 270}, | |
105 {"\"West\"", 270}, | |
106 {"\"WNW\"", 292.5}, | |
107 {"\"NW\"", 315}, | |
108 {"\"NNW\"", 337.5}}; | |
109 | |
110 int wind_direction_count = sizeof (wind_directions) / sizeof (struct wind_directions); | |
111 float previous_wind; | |
112 float wind_direction (char *text) | |
113 { | |
114 int i; | |
115 if (! strcmp (text, "\"CALM\"")) | |
116 return previous_wind; | |
117 for (i = 0; i < wind_direction_count; i++) | |
118 if (! strcmp (wind_directions [i].text, text)) | |
119 return previous_wind = wind_directions [i].direction; | |
120 fprintf (stderr, "Unknown wind direction: %s\n", text); | |
121 return previous_wind; /* Sam Ting */ | |
122 } | |
123 | |
124 int main (int argc, char *argv []) | |
125 { | |
126 char *cp; /* pointers in buffers */ | |
127 int fields; /* becomes number of fields in row */ | |
128 char date_text [11]; /* YYYY-MM-DD */ | |
129 char time_text [9]; /* HH-MM-SS */ | |
130 | |
131 if (argc > 1) | |
132 { | |
133 fprintf (stderr, "Usage: $0 < file\n"); | |
134 exit (1); | |
135 } | |
136 | |
137 while (1) | |
138 { | |
139 memset ((void *) buf, '\0', sizeof (buf)); /* don't trip over old stuff */ | |
140 if (! fgets (buf, BUFSIZE - 1, stdin)) | |
141 exit (0); /* empty file, just ignore */ | |
142 if (isdigit (buf [0])) /* valid row */ | |
143 { | |
144 fields = 0; | |
145 cp = buf; | |
146 while (1) | |
147 { | |
148 skipblanks (&cp); /* though there don't seem to be any */ | |
149 field [fields++] = cp; | |
150 while (*cp && (*cp != ',') && (*cp != '\n') && (*cp != ',')) | |
151 cp++; | |
152 if (! *cp) | |
153 break; | |
154 *cp++ = '\0'; /* delimit the string */ | |
155 } | |
156 /* | |
157 * buf now contains "fields" strings, and field (and thus "ballarat_row" | |
158 * and "sheoaks_row") contain pointers to them. | |
159 * | |
160 * Fix a few fields. | |
161 */ | |
162 strcpy (date_text, "YYYY-MM-DD"); | |
163 strcpy (time_text, "HH:MM:SS"); | |
164 /* The date info is surrounded with " */ | |
165 memcpy (date_text, &ballarat_readings->date [1], 4); /* YYYY */ | |
166 memcpy (&date_text [5], &ballarat_readings->date [5], 2); /* MM */ | |
167 memcpy (&date_text [8], &ballarat_readings->date [7], 2); /* MM */ | |
168 memcpy (time_text, &ballarat_readings->date [9], 2); /* HH */ | |
169 memcpy (&time_text [3], &ballarat_readings->date [11], 2); /* MM */ | |
170 memcpy (&time_text [6], &ballarat_readings->date [13], 2); /* MM */ | |
171 | |
172 if (strcmp (ballarat_readings->station_id, "94863")) /* Not Sheoaks */ | |
173 { | |
174 if (! strcmp (ballarat_readings->pressure_qnh, "-9999.0")) /* this seems to be a null value */ | |
175 ballarat_readings->pressure_qnh = "NULL"; | |
176 sprintf (sql_command, | |
177 "REPLACE INTO remote_observations (station_id, date, time, outside_temp, apparent_temp," | |
178 "delta_t, outside_dewpoint, wind_gust, pressure_msl, pressure_qnh, rain, outside_humidity, " | |
179 "wind_direction, wind_direction_text, wind_speed) " | |
180 "VALUES (\"%s\", \"%s\", \"%s\", \"%s\", \"%s\", \"%s\", \"%s\", \"%s\", %s, %s, " | |
181 "%s, \"%s\", %4.1f, %s, \"%s\");", | |
182 ballarat_readings->station_id, | |
183 date_text, | |
184 time_text, | |
185 ballarat_readings->temp, | |
186 ballarat_readings->apparent_temp, | |
187 ballarat_readings->delta_t, | |
188 ballarat_readings->dewpoint, | |
189 ballarat_readings->wind_gust, | |
190 ballarat_readings->pressure_msl, | |
191 ballarat_readings->pressure_qnh, | |
192 ballarat_readings->rain, | |
193 ballarat_readings->humidity, | |
194 wind_direction (ballarat_readings->wind_direction_text), | |
195 ballarat_readings->wind_direction_text, | |
196 ballarat_readings->wind_speed ); | |
197 } | |
198 else /* currently only sheoaks */ | |
199 { | |
200 if (! strcmp (sheoaks_readings->pressure_msl, "-9999.0")) /* this seems to be a null value */ | |
201 sheoaks_readings->pressure_msl = NULL; | |
202 | |
203 sprintf (sql_command, | |
204 "REPLACE INTO remote_observations (station_id, date, time, outside_temp, apparent_temp," | |
205 "delta_t, outside_dewpoint, wind_gust, pressure_msl, rain, outside_humidity, " | |
206 "wind_direction, wind_direction_text, wind_speed) " | |
207 "VALUES (\"%s\", \"%s\", \"%s\", \"%s\", \"%s\", \"%s\", \"%s\", \"%s\", %s, " | |
208 "%s, \"%s\", %4.1f, %s, \"%s\");", | |
209 sheoaks_readings->station_id, | |
210 date_text, | |
211 time_text, | |
212 sheoaks_readings->temp, | |
213 sheoaks_readings->apparent_temp, | |
214 sheoaks_readings->delta_t, | |
215 sheoaks_readings->dewpoint, | |
216 sheoaks_readings->wind_gust, | |
217 sheoaks_readings->pressure_msl, | |
218 sheoaks_readings->rain, | |
219 sheoaks_readings->humidity, | |
220 wind_direction (sheoaks_readings->wind_direction_text), | |
221 sheoaks_readings->wind_direction_text, | |
222 sheoaks_readings->wind_speed ); | |
223 } | |
224 puts (sql_command); | |
225 } | |
226 } | |
227 return 0; | |
228 } | |
229 |