changeset 338:afb8c0e2d513

fetch_weather: Implement support for new Tiehallinto data API.
author Matti Hamalainen <ccr@tnsp.org>
date Sun, 04 Oct 2015 14:21:22 +0300
parents bff53f5bba5b
children 6ea410acbe74
files fetch_weather.pl
diffstat 1 files changed, 96 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/fetch_weather.pl	Sat Sep 19 16:19:50 2015 +0300
+++ b/fetch_weather.pl	Sun Oct 04 14:21:22 2015 +0300
@@ -23,7 +23,8 @@
 use Date::Format;
 use Date::Parse;
 use Data::Dumper;
-
+use File::Slurp;
+use Text::CSV;
 
 ###
 ### Configuration settings
@@ -34,6 +35,7 @@
   "opt_tiehallinto" => 0,
   "fmi_api_key" => "",
   "outfile" => "",
+  "tiehallinto_static_meta" => "tiehallinto.meta",
   "http_user_agent" => "Mozilla/4.0 (compatible; MSIE 6.0; MSIE 5.5; Windows NT 6.0) Opera 10.63  [en]",
 );
 
@@ -264,6 +266,99 @@
 
 
 ###
+### Fetch Tiehallinto data
+###
+if (opt_chk_bool("opt_tiehallinto"))
+{
+  my $uri = "http://tie.digitraffic.fi/sujuvuus/ws/roadWeather";
+  my $res = fetch_http($uri);
+  if ($res->code >= 200 && $res->code <= 201)
+  {
+    my $xml = XMLin($res->decoded_content);
+
+    if (!defined($xml->{"soap:Body"}) || !defined($xml->{"soap:Body"}{"RoadWeatherResponse"}))
+    {
+      print STDERR "ERROR: SOAP call result did not contain required data.\n";
+      print STDERR $res->decoded_content."\n\n";
+    }
+    else
+    {
+      my $data = $xml->{"soap:Body"}{"RoadWeatherResponse"};
+
+      # Check if we need to update the static meta data
+      my $meta_file = opt_get("tiehallinto_static_meta");
+      my $fetch_meta = (-e $meta_file) ? 0 : 1;
+
+      if (defined($data->{"laststaticdataupdate"}))
+      {
+        # Compare metadata cache file modification timestamp to info in XML
+        my $tmp1 = str2time($data->{"laststaticdataupdate"});
+        my $tmp2 = (-e $meta_file) ? (stat($meta_file))[9] : -1;
+        $fetch_meta = 1 unless ($tmp1 < $tmp2);
+      }
+
+      # Fetch or read the cache
+      my $meta_str;
+      if ($fetch_meta)
+      {
+        print STDERR "Fetching Tiehallinto static meta data.\n" if (opt_get_int("debug") > 0);
+        my $uri = "https://raw.githubusercontent.com/finnishtransportagency/metadata/master/csv/meta_traffic_stations.csv";
+        my $res = fetch_http($uri);
+        die("Failed to fetch $uri data.\n") unless ($res->code <= 200 && $res->code <= 201);
+        
+        print STDERR "Storing to cache '$meta_file'.\n" if (opt_get_int("debug") > 0);
+        $meta_str = $res->decoded_content;
+        write_file($meta_file, {binmode => ':utf8'}, $meta_str);
+      }
+      else
+      {
+        print STDERR "Using CACHED Tiehallinto static meta data from '$meta_file'.\n" if (opt_get_int("debug") > 0);
+        $meta_str = read_file($meta_file, binmode => ':utf8');
+      }
+
+      # Parse the data ..
+      my $meta_data = {};
+      my $csv = Text::CSV->new({blank_is_undef => 1, decode_utf8 => 1});
+      foreach my $line (split(/\s*\n\s*/, $meta_str))
+      {
+        if ($csv->parse($line))
+        {
+          my @fields = $csv->fields();
+          $$meta_data{$fields[1]} = \@fields;
+        }
+      }
+
+      # Parse XML and combine with the station meta data
+      if (defined($data->{"roadweatherdata"}))
+      {
+        foreach my $wdata (@{$data->{"roadweatherdata"}{"roadweather"}})
+        {
+          my $wid = $wdata->{"stationid"};
+          if (defined($meta_data->{$wid}))
+          {
+            $weatherdata->{$meta_data->{$wid}[3]} =
+            [
+              0,
+              str2time(plonk_data($wdata->{"measurementtime"}{"utc"})),
+              plonk_data($wdata->{"airtemperature1"}),
+
+              plonk_data($wdata->{"humidity"}),
+              plonk_data($wdata->{"averagewindspeed"}),
+            ];
+          }
+        }
+      }
+      else
+      {
+        print STDERR "ERROR: Invalid (or unsupported) road weather data blob.\n";
+        print STDERR $res->decoded_content."\n\n";
+      }
+    }
+  }
+}
+
+
+###
 ### Fetch FMI data
 ###
 if (opt_chk_bool("opt_fmi"))