1 -- Authors: Andrea Rossato <arossato@istitutocolli.org>, Sergey Kozhemyakin <luc@server.by>
2 -- License: GPL, version 2 or later
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:
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)
21 -- %weather_pressure (hPa)
23 -- %weather_windspeed (MPH)
24 -- %weather_windchillF (Fahrenheit)
25 -- %weather_windchillC (Celsius)
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 :)
50 update_interval
= 30 * 60 * 1000, -- every 30 minutes
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()
63 local function calculate_gmt_offset()
64 -- offset (+|-)(\d\d)(\d\d)
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
71 local function reformat_time(date, time
)
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
)
79 local function parse_weather(s
)
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
)
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")
104 os
.execute("rm ".."/tmp/".. settings
.station
..".dat")
105 return parse_weather(s
)
108 local function update_weather()
109 local w
= load_weather()
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
)
123 weather_timer
:set(settings
.update_interval
, get_weather
)
126 local s
= f
:read("*all")
128 if not string.match(s
, "100%%") then
129 -- wget still downloading. resetting timer
130 wget_timer
:set(2000, check_wget
)
132 -- wget finished. so we need parse file and update info
133 os
.execute("rm "..filename
)
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"
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()