1
2 local weather_timer = statusd.create_timer()
3
4 local defaults = {
5 update_interval = 15 * 60 * 1000,
6 unit = {
7 tempC = "°",
8 tempF = "F",
9 humidity = "%",
10 pressure = "hPa",
11 windspeed = "MPH",
12 },
13 important = {
14 tempC = 10,
15 tempF = 50,
16 windspeed = 5,
17 humidity = 30,
18 },
19 critical = {
20 tempC = 26,
21 tempF = 78,
22 windspeed = 20,
23 humidity = 90,
24 },
25 }
26
27 local url = "http://weather.noaa.gov/pub/data/observations/metar/decoded/"
28
29 local data = {
30 timezone = tonumber(os.date("%z")),
31 }
32
33 local raw_data
34
35 local settings = table.join(statusd.get_config("weather"), defaults)
36
37 local function get_weather()
38 local command = "/usr/bin/curl -s"..url..settings.station..".TXT"
39 f = io.popen(command)
40 raw_data = f:read("*all")
41 f:close()
42 end
43
44 local function process_data()
45 local s = raw_data
46 _, _, data.location, data.country = string.find(s, "^(.+)%,%s(.+)%(%u+%)" )
47 _, _, data.date, data.time = string.find(s, ".+%/%s([%d.]+)%s(%d+)%sUTC" )
48 _, _, data.wind, data.windspeed =
49 string.find(s, "Wind%:%s(.+%sat%s(%d+)%sMPH)" )
50 _, _, data.sky = string.find(s, "Sky%sconditions:%s(.-)%c" )
51 _, _, data.tempF, data.tempC =
52 string.find(s, "Temperature:%s([%d%.]+)%sF%s%(([%d%.]+)%sC%)%c" )
53 _, _, data.dewpointF, data.dewpointC =
54 string.find(s, "Dew%sPoint:%s([%d%.]+)%sF%s%(([%d%.]+)%sC%)" )
55 _, _, data.humidity = string.find(s, "Relative%sHumidity:%s(%d+)%%")
56 _, _, data.pressure = string.find(s, "Pressure%s.+%((.+)%shPa%)" )
57 _, _, data.weather = string.find(s, "Weather:%s(.-)%c" )
58 format_time()
59 end
60
61 function format_time()
62 local time
63 if data.time then
64 time = tonumber(data.time) + tonumber(data.timezone)
65 else return
66 end
67 if time > 2400 then
68 time = tostring(time - 2400)
69 end
70 if string.match(time, "^%d%d$") then
71 time = "00"..time
72 end
73 if string.match(time, "^%d%d%d$") then
74 time = "0"..time
75 end
76 data.time = tostring(time):gsub("(%d%d)(%d%d)","%1%:%2")
77 end
78
79 local function get_hint(meter, val)
80 local hint = "normal"
81 local crit = settings.critical[meter]
82 local imp = settings.important[meter]
83 if crit and tonumber(val) > crit then
84 hint = "critical"
85 elseif imp and tonumber(val) > imp then
86 hint = "important"
87 end
88 return hint
89 end
90
91 -- get the unit of each meter
92 local function get_unit(meter)
93 local unit = settings.unit[meter]
94 if unit then return unit end
95 return ""
96 end
97
98 -- update information for statusd
99 local function notify()
100 for i,v in pairs(data) do
101 statusd.inform("weather_"..i.."_"..settings.station.."_hint", get_hint(i, v))
102 statusd.inform("weather_"..i.."_hint", get_hint(i, v))
103 if not v then v = "N/A" end
104 statusd.inform("weather_"..i.."_"..settings.station, v..get_unit(i))
105 statusd.inform("weather_"..i, v..get_unit(i))
106 end
107 end
108
109
110 local function run()
111 get_weather()
112 process_data()
113 notify()
114 weather_timer:set(settings.update_interval, run)
115 end
116
117 run()
118
119 -- EOF
2 local weather_timer = statusd.create_timer()
3
4 local defaults = {
5 update_interval = 15 * 60 * 1000,
6 unit = {
7 tempC = "°",
8 tempF = "F",
9 humidity = "%",
10 pressure = "hPa",
11 windspeed = "MPH",
12 },
13 important = {
14 tempC = 10,
15 tempF = 50,
16 windspeed = 5,
17 humidity = 30,
18 },
19 critical = {
20 tempC = 26,
21 tempF = 78,
22 windspeed = 20,
23 humidity = 90,
24 },
25 }
26
27 local url = "http://weather.noaa.gov/pub/data/observations/metar/decoded/"
28
29 local data = {
30 timezone = tonumber(os.date("%z")),
31 }
32
33 local raw_data
34
35 local settings = table.join(statusd.get_config("weather"), defaults)
36
37 local function get_weather()
38 local command = "/usr/bin/curl -s"..url..settings.station..".TXT"
39 f = io.popen(command)
40 raw_data = f:read("*all")
41 f:close()
42 end
43
44 local function process_data()
45 local s = raw_data
46 _, _, data.location, data.country = string.find(s, "^(.+)%,%s(.+)%(%u+%)" )
47 _, _, data.date, data.time = string.find(s, ".+%/%s([%d.]+)%s(%d+)%sUTC" )
48 _, _, data.wind, data.windspeed =
49 string.find(s, "Wind%:%s(.+%sat%s(%d+)%sMPH)" )
50 _, _, data.sky = string.find(s, "Sky%sconditions:%s(.-)%c" )
51 _, _, data.tempF, data.tempC =
52 string.find(s, "Temperature:%s([%d%.]+)%sF%s%(([%d%.]+)%sC%)%c" )
53 _, _, data.dewpointF, data.dewpointC =
54 string.find(s, "Dew%sPoint:%s([%d%.]+)%sF%s%(([%d%.]+)%sC%)" )
55 _, _, data.humidity = string.find(s, "Relative%sHumidity:%s(%d+)%%")
56 _, _, data.pressure = string.find(s, "Pressure%s.+%((.+)%shPa%)" )
57 _, _, data.weather = string.find(s, "Weather:%s(.-)%c" )
58 format_time()
59 end
60
61 function format_time()
62 local time
63 if data.time then
64 time = tonumber(data.time) + tonumber(data.timezone)
65 else return
66 end
67 if time > 2400 then
68 time = tostring(time - 2400)
69 end
70 if string.match(time, "^%d%d$") then
71 time = "00"..time
72 end
73 if string.match(time, "^%d%d%d$") then
74 time = "0"..time
75 end
76 data.time = tostring(time):gsub("(%d%d)(%d%d)","%1%:%2")
77 end
78
79 local function get_hint(meter, val)
80 local hint = "normal"
81 local crit = settings.critical[meter]
82 local imp = settings.important[meter]
83 if crit and tonumber(val) > crit then
84 hint = "critical"
85 elseif imp and tonumber(val) > imp then
86 hint = "important"
87 end
88 return hint
89 end
90
91 -- get the unit of each meter
92 local function get_unit(meter)
93 local unit = settings.unit[meter]
94 if unit then return unit end
95 return ""
96 end
97
98 -- update information for statusd
99 local function notify()
100 for i,v in pairs(data) do
101 statusd.inform("weather_"..i.."_"..settings.station.."_hint", get_hint(i, v))
102 statusd.inform("weather_"..i.."_hint", get_hint(i, v))
103 if not v then v = "N/A" end
104 statusd.inform("weather_"..i.."_"..settings.station, v..get_unit(i))
105 statusd.inform("weather_"..i, v..get_unit(i))
106 end
107 end
108
109
110 local function run()
111 get_weather()
112 process_data()
113 notify()
114 weather_timer:set(settings.update_interval, run)
115 end
116
117 run()
118
119 -- EOF