# HG changeset patch # User Matti Hamalainen # Date 1443957682 -10800 # Node ID afb8c0e2d51304ad861ee80b8557cfb32c996c58 # Parent bff53f5bba5bcecc0e4e658e42f84aa45ebc6549 fetch_weather: Implement support for new Tiehallinto data API. diff -r bff53f5bba5b -r afb8c0e2d513 fetch_weather.pl --- 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"))