- 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)
- 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`)
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 \
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)
--- /dev/null
+XmlPath == "/current_observation/temp_f" {
+ print("temperature_f", XmlPayload) # °F
+}
--- /dev/null
+# 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
+}
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