Include notionflux in the main repo instead of its own submodule
[notion/jeffpc.git] / contrib / statusd / statusd_weather.lua
blob5d5ddd089fd01111601664f500db6b0208a70a48
1 -- Authors: Andrea Rossato <arossato@istitutocolli.org>, Sergey Kozhemyakin <luc@server.by>
2 -- License: GPL, version 2 or later
3 -- Last Changed: 2008
4 --
5 -- statusd_weather.lua
7 -- statusd_weather.lua: an Ion3 statusd applet for displaying weather information
8 -- based on weather.lua by Andrea Rossato arossato AT istitutocolli DOT org
10 -- Here's the list of all available data:
11 -- %weather_location
12 -- %weather_country
13 -- %weather_date
14 -- %weather_time (UTC)
15 -- %weather_timestamp (timestamp of the latest report: your local time.)
16 -- %weather_tempF (Fahrenheit)
17 -- %weather_tempC (Celsius)
18 -- %weather_dewpointF (Fahrenheit)
19 -- %weather_dewpointC (Celsius)
20 -- %weather_humidity
21 -- %weather_pressure (hPa)
22 -- %weather_wind
23 -- %weather_windspeed (MPH)
24 -- %weather_windchillF (Fahrenheit)
25 -- %weather_windchillC (Celsius)
26 -- %weather_sky
27 -- %weather_weather
29 -- LEGAL
30 -- Copyright (C) 2006 Andrea Rossato arossato AT istitutocolli DOT org
31 -- Copyright (C) 2008 Sergey Kozhemyakin luc AT server DOT by
33 -- This program is free software; you can redistribute it and/or
34 -- modify it under the terms of the GNU General Public License
35 -- as published by the Free Software Foundation; either version 2
36 -- of the License, or (at your option) any later version.
38 -- This software is distributed in the hope that it will be useful,
39 -- but WITHOUT ANY WARRANTY; without even the implied warranty of
40 -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
41 -- GNU General Public License for more details.
43 -- You should have received a copy of the GNU General Public License
44 -- along with this program; if not, write to the Free Software
45 -- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
47 -- Have a nice weather :)
49 local defaults = {
50 update_interval = 30 * 60 * 1000, -- every 30 minutes
51 station = "UMGG",
52 timestamp_format = "%F %H:%M", -- strftime format
53 gmt_offset = nil, -- offset from gmt in seconds. should be calculated automaticaly but may be specified manualy
56 local settings = table.join(statusd.get_config("weather"), defaults)
58 local weather_timer = statusd.create_timer()
59 local wget_timer = statusd.create_timer()
61 local get_weather
63 local function calculate_gmt_offset()
64 -- offset (+|-)(\d\d)(\d\d)
65 local off = {}
66 _, _, off.sign, off.hour, off.min = string.find(os.date("%z", os.time()), "([-+])(%d%d)(%d%d)")
67 settings.gmt_offset = (off.hour * 60 + off.min) * 60
68 if off.sign == '-' then settings.gmt_offset = -settings.gmt_offset end
69 end
71 local function reformat_time(date, time)
72 local dt = {}
73 _, _, dt.year, dt.month, dt.day = string.find(date, "(%d+)%.(%d+)%.(%d+)")
74 _, _, dt.hour, dt.min = string.find(time, "(%d%d)(%d%d)")
75 os.setlocale(os.getenv("LANG"), "time")
76 return os.date(settings.timestamp_format, os.time(dt) + settings.gmt_offset)
77 end
79 local function parse_weather(s)
80 local w = {}
81 _, _, w.location, w.country = string.find(s, "^(.+)%,%s(.+)%(%u+%)" )
82 _, _, w.date, w.time = string.find(s, ".+%/%s([%d.]+)%s(%d+)%sUTC" )
83 _, _, w.wind, w.windspeed = string.find(s, "Wind%:%s(.+%sat%s(%d+)%sMPH)" )
84 _, _, w.sky = string.find(s, "Sky%sconditions:%s(.-)%c" )
85 _, _, w.tempF, w.tempC = string.find(s, "Temperature:%s(-?%d*%.?%d+)%sF%s%((-?%d*%.?%d+)%sC%)%c" )
86 _, _, w.dewpointF, w.dewpointC = string.find(s, "Dew%sPoint:%s(-?%d*%.?%d+)%sF%s%((-?%d*%.?%d+)%sC%)" )
87 _, _, w.windchillF, w.windchillC = string.find(s, "Windchill:%s(-?%d*%.?%d+)%sF%s%((-?%d*%.?%d+)%sC%)" )
88 _, _, w.humidity = string.find(s, "Relative%sHumidity:%s(%d+)%%")
89 _, _, w.pressure = string.find(s, "Pressure%s%b():.-%((%d+)%shPa%)" )
90 _, _, w.weather = string.find(s, "Weather:%s(.-)%c" )
91 if w.date and w.time then
92 w.timestamp = reformat_time(w.date, w.time)
93 else
94 w.timestamp = "undef"
95 end
96 return w
97 end
99 local function load_weather()
100 local f = io.open ("/tmp/".. settings.station..".dat")
101 if not f then return nil end
102 local s = f:read("*all")
103 f:close()
104 os.execute("rm ".."/tmp/".. settings.station..".dat")
105 return parse_weather(s)
108 local function update_weather()
109 local w = load_weather()
110 if w then
111 for i,v in pairs(w) do
112 if not v then v = "N/A" end
113 statusd.inform("weather_"..i, v);
116 weather_timer:set(settings.update_interval, get_weather)
119 local function check_wget()
120 local filename = "/tmp/wget_"..settings.station.."_status.txt"
121 local f = io.open (filename)
122 if not f then
123 weather_timer:set(settings.update_interval, get_weather)
124 return nil
126 local s = f:read("*all")
127 f:close()
128 if not string.match(s, "100%%") then
129 -- wget still downloading. resetting timer
130 wget_timer:set(2000, check_wget)
131 else
132 -- wget finished. so we need parse file and update info
133 os.execute("rm "..filename)
134 update_weather()
138 get_weather = function ()
139 local url = "http://weather.noaa.gov/pub/data/observations/metar/decoded/"
140 local command = "wget -b -o /tmp/wget_"..settings.station.."_status.txt -O /tmp/"..settings.station..".dat "..url..settings.station..".TXT"
141 os.execute(command)
142 -- start watching timer -- when wget will exit -- update weather
143 wget_timer:set(2000, check_wget)
146 if not settings.gmt_offset then
147 calculate_gmt_offset()
149 get_weather()