diff 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
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/db/insertBoM.c	Tue Feb 09 13:44:25 2010 +1030
@@ -0,0 +1,229 @@
+/*
+ * Read in Australian Bureau of Meteorology comma-delimited files and convert
+ * them into INSERT commands for MySQL.
+ *
+ * $Id: insertBoM.c,v 1.4 2010/01/03 05:05:28 grog Exp $
+ */
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/file.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#define BUFSIZE 1024
+char buf [BUFSIZE];
+char sql_command [BUFSIZE];
+
+/* We split up the input line into these fields, not all of which we use. */
+char *field [50];                               /* pointers to beginnings of fields */
+
+/*
+ * We alias these structs to the input field above.  Unfortunately, the data
+ * returned from Sheoaks is different from Ballarat and Melbourne airports:
+ * Sheoaks doesn't report a QNH pressure.  I should really parse the input files
+ * to check the fields, but it's pretty messy.
+ */
+
+struct ballarat_row
+{
+  char *order;                                  /* sort order (backwards!) */
+  char *station_id;                             /* station ID, apparently always numeric */
+  char *name;                                   /* name of town, it would seem */
+  char *history;                                /* this looks like another station ID */
+  char *funnydate;                              /* date in useless form 0D/0H:0m[ap]m */
+  char *date;                                   /* date as YYYYMMDDHHmmSS */
+  char *temp;                                   /* temperature, °C */
+  char *apparent_temp;                          /* apparent temperature */
+  char *delta_t;                                /* wet bulb depression */
+  char *dewpoint;                               /* dew point */
+  char *wind_gust;                              /* wind gust speed */
+  char *gust_knots;                             /* same again in knots */
+  char *pressure_msl;                           /* pressure at mean sea level */
+  char *pressure_qnh;                           /* QNH pressure, whatever that may be */
+  char *rain;                                   /* rain as text (can be "Tce") */
+  char *humidity;                               /* relative humdity */
+  char *wind_direction_text;                    /* text of direction */
+  char *wind_speed;                             /* speed in km/h */
+  char *wind_speed_knots;                       /* and in knots */
+} *ballarat_readings = (struct ballarat_row *) field;
+
+struct sheoaks_row
+{
+  char *order;                                  /* sort order (backwards!) */
+  char *station_id;                             /* station ID, apparently always numeric */
+  char *name;                                   /* name of town, it would seem */
+  char *history;                                /* this looks like another station ID */
+  char *funnydate;                              /* date in useless form 0D/0H:0m[ap]m */
+  char *date;                                   /* date as YYYYMMDDHHmmSS */
+  char *temp;                                   /* temperature, °C */
+  char *apparent_temp;                          /* apparent temperature */
+  char *delta_t;                                /* wet bulb depression */
+  char *dewpoint;                               /* dew point */
+  char *wind_gust;                              /* wind gust speed */
+  char *gust_knots;                             /* same again in knots */
+  char *pressure_msl;                           /* pressure at mean sea level */
+  char *rain;                                   /* rain as text (can be "Tce") */
+  char *humidity;                               /* relative humdity */
+  char *wind_direction_text;                    /* text of direction */
+  char *wind_speed;                             /* speed in km/h */
+  char *wind_speed_knots;                       /* and in knots */
+} *sheoaks_readings = (struct sheoaks_row *) field;
+
+void skipblanks (char **cp)
+{
+  while (**cp == ' ')
+    (*cp)++;
+}
+
+/*
+ * Wind directions as text.  BoM encloses them in "", so we do the same
+ */
+struct wind_directions
+{
+  char *text;                                   /* name of direction */
+  float direction;                              /* and the direction it represents */
+} wind_directions [] = {
+  {"\"N\"", 0},
+  {"\"North\"", 0},
+  {"\"NNE\"", 22.5},
+  {"\"NE\"", 45},
+  {"\"ENE\"", 67.5},
+  {"\"E\"", 90},
+  {"\"East\"", 90},
+  {"\"ESE\"", 112.5},
+  {"\"SE\"", 135},
+  {"\"SSE\"", 157.5},
+  {"\"S\"", 180},
+  {"\"South\"", 180},
+  {"\"SSW\"", 202.5},
+  {"\"SW\"", 225},
+  {"\"WSW\"", 247.5},
+  {"\"W\"", 270},
+  {"\"West\"", 270},
+  {"\"WNW\"", 292.5},
+  {"\"NW\"", 315},
+  {"\"NNW\"", 337.5}};
+
+int wind_direction_count = sizeof (wind_directions) / sizeof (struct wind_directions);
+float previous_wind;
+float wind_direction (char *text)
+{
+  int i;
+  if (! strcmp (text, "\"CALM\""))
+    return previous_wind;
+  for (i = 0; i < wind_direction_count; i++)
+    if (! strcmp (wind_directions [i].text, text))
+      return previous_wind = wind_directions [i].direction;
+  fprintf (stderr, "Unknown wind direction: %s\n", text);
+  return previous_wind;                         /* Sam Ting */
+}
+
+int main (int argc, char *argv [])
+{
+  char *cp;                                     /* pointers in buffers */
+  int fields;                                   /* becomes number of fields in row */
+  char date_text [11];                          /* YYYY-MM-DD */
+  char time_text [9];                           /* HH-MM-SS */
+
+  if (argc > 1)
+  {
+    fprintf (stderr, "Usage: $0 < file\n");
+    exit (1);
+  }
+
+  while (1)
+  {
+    memset ((void *) buf, '\0', sizeof (buf));  /* don't trip over old stuff */
+    if (! fgets (buf, BUFSIZE - 1, stdin))
+      exit (0);                                 /* empty file, just ignore  */
+    if (isdigit (buf [0]))                      /* valid row  */
+    {
+      fields = 0;
+      cp = buf;
+      while (1)
+      {
+        skipblanks (&cp);                       /* though there don't seem to be any */
+        field [fields++] = cp;
+        while (*cp && (*cp != ',') && (*cp != '\n') && (*cp != ','))
+          cp++;
+        if (! *cp)
+          break;
+        *cp++ = '\0';                           /* delimit the string */
+      }
+      /*
+       * buf now contains "fields" strings, and field (and thus "ballarat_row"
+       * and "sheoaks_row") contain pointers to them.
+       *
+       * Fix a few fields.
+       */
+      strcpy (date_text, "YYYY-MM-DD");
+      strcpy (time_text, "HH:MM:SS");
+      /* The date info is surrounded with " */
+      memcpy (date_text, &ballarat_readings->date [1], 4); /* YYYY */
+      memcpy (&date_text [5], &ballarat_readings->date [5], 2); /* MM */
+      memcpy (&date_text [8], &ballarat_readings->date [7], 2); /* MM */
+      memcpy (time_text, &ballarat_readings->date [9], 2); /* HH */
+      memcpy (&time_text [3], &ballarat_readings->date [11], 2); /* MM */
+      memcpy (&time_text [6], &ballarat_readings->date [13], 2); /* MM */
+
+      if (strcmp (ballarat_readings->station_id, "94863")) /* Not Sheoaks */
+      {
+        if (! strcmp (ballarat_readings->pressure_qnh, "-9999.0")) /* this seems to be a null value */
+          ballarat_readings->pressure_qnh = "NULL";
+        sprintf (sql_command,
+                 "REPLACE INTO remote_observations (station_id, date, time, outside_temp, apparent_temp,"
+                 "delta_t, outside_dewpoint, wind_gust, pressure_msl, pressure_qnh, rain, outside_humidity, "
+                 "wind_direction, wind_direction_text, wind_speed) "
+                 "VALUES (\"%s\", \"%s\", \"%s\", \"%s\", \"%s\", \"%s\", \"%s\", \"%s\", %s, %s, "
+                 "%s, \"%s\", %4.1f, %s, \"%s\");",
+                 ballarat_readings->station_id,
+                 date_text,
+                 time_text,
+                 ballarat_readings->temp,
+                 ballarat_readings->apparent_temp,
+                 ballarat_readings->delta_t,
+                 ballarat_readings->dewpoint,
+                 ballarat_readings->wind_gust,
+                 ballarat_readings->pressure_msl,
+                 ballarat_readings->pressure_qnh,
+                 ballarat_readings->rain,
+                 ballarat_readings->humidity,
+                 wind_direction (ballarat_readings->wind_direction_text),
+                 ballarat_readings->wind_direction_text,
+                 ballarat_readings->wind_speed );
+      }
+      else                                      /* currently only sheoaks */
+      {
+      if (! strcmp (sheoaks_readings->pressure_msl, "-9999.0")) /* this seems to be a null value */
+        sheoaks_readings->pressure_msl = NULL;
+
+        sprintf (sql_command,
+                 "REPLACE INTO remote_observations (station_id, date, time, outside_temp, apparent_temp,"
+                 "delta_t, outside_dewpoint, wind_gust, pressure_msl, rain, outside_humidity, "
+                 "wind_direction, wind_direction_text, wind_speed) "
+                 "VALUES (\"%s\", \"%s\", \"%s\", \"%s\", \"%s\", \"%s\", \"%s\", \"%s\", %s, "
+                 "%s, \"%s\", %4.1f, %s, \"%s\");",
+                 sheoaks_readings->station_id,
+                 date_text,
+                 time_text,
+                 sheoaks_readings->temp,
+                 sheoaks_readings->apparent_temp,
+                 sheoaks_readings->delta_t,
+                 sheoaks_readings->dewpoint,
+                 sheoaks_readings->wind_gust,
+                 sheoaks_readings->pressure_msl,
+                 sheoaks_readings->rain,
+                 sheoaks_readings->humidity,
+                 wind_direction (sheoaks_readings->wind_direction_text),
+                 sheoaks_readings->wind_direction_text,
+                 sheoaks_readings->wind_speed );
+      }
+      puts (sql_command);
+    }
+  }
+  return 0;
+}
+