From 57ed1a64be1e9d930efe1113e105b09410498355 Mon Sep 17 00:00:00 2001 From: Siraaj Khandkar Date: Thu, 7 Feb 2019 17:00:21 -0500 Subject: [PATCH] Replace `metar` with custom parser of NOAA XML API --- TODO.md | 6 ++- x2/Makefile | 10 ++-- x2/src/awk/exe/parse_noaa_api.awk | 3 ++ x2/src/awk/lib/parse_hxpipe.awk | 62 ++++++++++++++++++++++++ x2/src/bash/exe/khatus_sensor_weather.sh | 7 ++- 5 files changed, 83 insertions(+), 5 deletions(-) create mode 100644 x2/src/awk/exe/parse_noaa_api.awk create mode 100644 x2/src/awk/lib/parse_hxpipe.awk diff --git a/TODO.md b/TODO.md index 90d1ad1..e9cf34f 100644 --- a/TODO.md +++ b/TODO.md @@ -7,7 +7,6 @@ TODO - show how many Debian package security-updates are available - monitor disk usage rate of change and alert if suspiciously fast - bring back CPU usage monitor -- actual METAR parser, to replace the flaky `metar` program - status bar templating language - retry/cache for sensors fetching flaky remote resources (such as weather) - throttling of broken sensors (constantly returns errors) @@ -42,3 +41,8 @@ TODO - monitor battery time remaining - monitor accuracy (is percentage change rate on track to meet estimate?) - adjust estimate based on observed inaccuracies in past estimates (Kalman?) + +DONE +---- +- [x] actual METAR parser, to replace the flaky `metar` program + - Replaced it with a parser of NOAA's XML API (piping `curl | hxpipe | awk`) diff --git a/x2/Makefile b/x2/Makefile index c2d3f52..e97b61f 100644 --- a/x2/Makefile +++ b/x2/Makefile @@ -18,7 +18,7 @@ AWK_EXECUTABLES := \ bin/khatus_parse_ip_addr \ bin/khatus_parse_iwconfig \ bin/khatus_parse_loadavg_file \ - bin/khatus_parse_metar_d_output \ + bin/khatus_parse_noaa_api \ bin/khatus_parse_mpd_status_currentsong \ bin/khatus_parse_pactl_list_sinks \ bin/khatus_parse_ps \ @@ -174,8 +174,12 @@ bin/khatus_parse_loadavg_file: \ src/awk/lib/msg.awk $(BUILD_AWK_EXE) -bin/khatus_parse_metar_d_output: \ - src/awk/exe/parse_metar_d_output.awk \ +# Order of dependencies is important for khatus_parse_noaa_api! +# parse_hxpipe MUST appear before parse_noaa_api, because the order in +# which they match lines matters! +bin/khatus_parse_noaa_api: \ + src/awk/lib/parse_hxpipe.awk \ + src/awk/exe/parse_noaa_api.awk \ src/awk/lib/msg.awk \ src/awk/lib/str.awk $(BUILD_AWK_EXE) diff --git a/x2/src/awk/exe/parse_noaa_api.awk b/x2/src/awk/exe/parse_noaa_api.awk new file mode 100644 index 0000000..6c34091 --- /dev/null +++ b/x2/src/awk/exe/parse_noaa_api.awk @@ -0,0 +1,3 @@ +XmlPath == "/current_observation/temp_f" { + print("temperature_f", XmlPayload) # °F +} diff --git a/x2/src/awk/lib/parse_hxpipe.awk b/x2/src/awk/lib/parse_hxpipe.awk new file mode 100644 index 0000000..ab07779 --- /dev/null +++ b/x2/src/awk/lib/parse_hxpipe.awk @@ -0,0 +1,62 @@ +# API: +# XmlPath : string +# XmlAttr : dict : [XmlPath, string] -> string +# XmlPayload : string + +/^[\(\)]/ { + update_node() + next +} + +/^A/ && $2 == "CDATA" { + update_node_attributes() + next +} + +/^-/ { + XmlPayload = substr($0, 2, length($0)) +} + +function path_to_string(path, depth, p, i) { + p = "" + for (i = 1; i <= depth; i++) { + p = p "/" path[i] + } + return p +} + +function update_node( paren, name, key, val, path, attr) { + paren = substr($1, 1, 1) + name = substr($1, 2, length($1) - 1) + if (paren == "(") { + _depth++ + _path[_depth] = name + XmlPath = path_to_string(_path, _depth) + for (key in _hxpipe_curr_attrs) { + val = _hxpipe_curr_attrs[key] + XmlAttr[XmlPath, key] = val + } + } else if (paren == ")") { + delete _hxpipe_curr_attrs + XmlPayload = "" + for (key in XmlAttr) { + split(key, k, SUBSEP) + path = k[1] + attr = k[2] + if (path == XmlPath) delete XmlAttr[key] + } + _depth-- + XmlPath = path_to_string(_path, _depth) + } else { + printf("ERROR in input line %d - not a parenthesis: \"%s\"\n", NR, paren) > "/dev/stderr" + exit 1 + } +} + +function update_node_attributes( key, val, s) { + key = substr($1, 2, length($1)) + val = $0 + s = " +" + sub("^" $1 s $2 s, "", val) + _hxpipe_curr_attrs[key] = val +} diff --git a/x2/src/bash/exe/khatus_sensor_weather.sh b/x2/src/bash/exe/khatus_sensor_weather.sh index 371010f..a41f14a 100644 --- a/x2/src/bash/exe/khatus_sensor_weather.sh +++ b/x2/src/bash/exe/khatus_sensor_weather.sh @@ -5,4 +5,9 @@ set -e dir_bin="$1" weather_station_id="$2" -metar -d "$weather_station_id" 2>&1 | "$dir_bin"/khatus_parse_metar_d_output +curl \ + -X GET \ + -H "accept: application/vnd.noaa.obs+xml" \ + "https://api.weather.gov/stations/${weather_station_id}/observations/latest?require_qc=false" \ +| hxpipe \ +| "$dir_bin"/khatus_parse_noaa_api -- 2.20.1