changeset 448:ac3b79eca0ca

fetch_weather: Change to use the new REST/JSON API for fetching Tiehallinto digitraffic weather data. Sidenote: How can JSON format data be designed so idiotically?
author Matti Hamalainen <ccr@tnsp.org>
date Thu, 28 Sep 2017 15:22:03 +0300
parents 11124f9bf994
children d4f4a9dfb34f
files fetch_weather.pl
diffstat 1 files changed, 44 insertions(+), 41 deletions(-) [+]
line wrap: on
line diff
--- a/fetch_weather.pl	Thu Sep 28 15:19:09 2017 +0300
+++ b/fetch_weather.pl	Thu Sep 28 15:22:03 2017 +0300
@@ -43,9 +43,9 @@
   "fmi_api_key" => "",
   "outfile" => "",
   "http_user_agent" => "Mozilla/4.0 (compatible; MSIE 6.0; MSIE 5.5; Windows NT 6.0) Opera 10.63  [en]",
-  "tiehallinto_rw_url" => "http://tie.digitraffic.fi/sujuvuus/ws/roadWeather",
   "tiehallinto_meta" => "tiehallinto.meta",
   "tiehallinto_meta_period" => 7,
+  "tiehallinto_rw_url" => "http://tie.digitraffic.fi/api/v1/data/weather-data",
   "tiehallinto_meta_url" => "http://tie.digitraffic.fi/api/v1/metadata/weather-stations",
 );
 
@@ -360,18 +360,16 @@
   my $res = fetch_http($uri);
   if ($res->code >= 200 && $res->code <= 201)
   {
-    my $xml = XMLin($res->decoded_content);
+    my $json_str = $res->decoded_content;
+    my $data = JSON->new->decode($json_str);
 
-    if (!defined($xml->{"soap:Body"}) || !defined($xml->{"soap:Body"}{"RoadWeatherResponse"}))
+    if (!defined($data->{"dataUpdatedTime"}) || !defined($data->{"weatherStations"}))
     {
-      print STDERR "ERROR: SOAP call result did not contain required data.\n";
-      print STDERR $res->decoded_content."\n\n";
+      print STDERR "ERROR: REST/JSON call result did not contain required data.\n";
+      print STDERR $json_str."\n\n";
     }
     else
     {
-      # Parse the XML
-      my $data = $xml->{"soap:Body"}{"RoadWeatherResponse"};
-
       # Check if we need to update the static meta data
       my $meta_file = opt_get("tiehallinto_meta");
       my $meta_stamp = (-e $meta_file) ? (stat($meta_file))[9] : -1;
@@ -426,44 +424,47 @@
         }
       }
 
-      # Parse XML and combine with the station meta data
-      if (defined($data->{"roadweatherdata"}))
+      my $nrecords = 0;
+      foreach my $wdata (@{$data->{"weatherStations"}})
       {
-        my $nrecords = 0;
-        foreach my $wdata (@{$data->{"roadweatherdata"}{"roadweather"}})
+        my $wid = $wdata->{"id"};
+        if (defined($meta_data->{$wid}) && defined($wdata->{"sensorValues"}))
         {
-          my $wid = $wdata->{"stationid"};
-          if (defined($meta_data->{$wid}))
+          $wdata->{"sensors"} = {};
+          foreach my $sensor (@{$wdata->{"sensorValues"}})
           {
-            $nrecords++;
-            $weatherdata->{$meta_data->{$wid}{"properties"}{"names"}{"fi"}} =
-            [
-              1,
+            $wdata->{"sensors"}->{$sensor->{"oldName"}} = $sensor;
+          }
 
-              $meta_data->{$wid}{"geometry"}{"coordinates"}[1],
-              $meta_data->{$wid}{"geometry"}{"coordinates"}[0],
-              $meta_data->{$wid}{"geometry"}{"coordinates"}[2],
+          $nrecords++;
+          $weatherdata->{$meta_data->{$wid}{"properties"}{"names"}{"fi"}} =
+          [
+            # Measurement source type
+            1,
 
-              str2time(plonk_data($wdata->{"measurementtime"}{"utc"})),
-              plonk_data($wdata->{"airtemperature1"}),
+            # Basic data
+            $meta_data->{$wid}{"geometry"}{"coordinates"}[1],
+            $meta_data->{$wid}{"geometry"}{"coordinates"}[0],
+            $meta_data->{$wid}{"geometry"}{"coordinates"}[2],
+            str2time(plonk_data($wdata->{"measuredTime"})),
+            plonk_data($wdata->{"sensors"}->{"airtemperature1"}->{"sensorValue"}),
+            plonk_data($wdata->{"sensors"}->{"humidity"}->{"sensorValue"}),
+            plonk_data($wdata->{"sensors"}->{"averagewindspeed"}->{"sensorValue"}),
 
-              plonk_data($wdata->{"humidity"}),
-              plonk_data($wdata->{"averagewindspeed"}),
-            ];
-          }
-          else
-          {
-            print STDERR "Station ID #".$wid." not defined?\n" if (opt_get_int("debug") > 0);
-            #.Dumper($meta_data->{$wid});
-          }
+            # Station type dependant data
+            "",
+            plonk_data($wdata->{"sensors"}->{"roadsurfacetemperature1"}->{"sensorValue"}),
+            plonk_data($wdata->{"sensors"}->{"precipitation"}->{"sensorValueDescriptionFi"}),
+            plonk_data($wdata->{"sensors"}->{"visibility"}->{"sensorValue"}),
+          ];
         }
-        print STDERR $nrecords." records from Tiehallinto.\n" if (opt_get_int("debug") > 0);
+        else
+        {
+          print STDERR "Station ID #".$wid." not defined?\n" if (opt_get_int("debug") > 0);
+          #.Dumper($meta_data->{$wid});
+        }
       }
-      else
-      {
-        print STDERR "ERROR: Invalid (or unsupported) road weather data blob.\n";
-        print STDERR $res->decoded_content."\n\n";
-      }
+      print STDERR $nrecords." records from Tiehallinto.\n" if (opt_get_int("debug") > 0);
     }
   }
 }
@@ -560,17 +561,19 @@
               $nrecords++;
               $weatherdata->{$floc->{"gml:name"}} =
               [
-                1,
+                # Measurement source type
+                2,
 
+                # Basic data
                 $frec->{"lat"},
                 $frec->{"long"},
                 0,
-
                 plonk_data($frec->{"time"}),
                 plonk_data($frec->{"temperature"}),
-
                 plonk_data($frec->{"humidity"}),
                 plonk_data($frec->{"windspeedms"}),
+
+                # Station type dependant data
                 translate_clouds(plonk_data($frec->{"totalcloudcover"})),
               ];
             }