lcpz / lain

Awesome WM complements
GNU General Public License v2.0
1.06k stars 212 forks source link

Notification function of weather widget is not general enough #186

Closed romildo closed 8 years ago

romildo commented 8 years ago

The notification function of the weather widget accepts only four arguments: day, description, minimum temperature, and maximum temperature. It should not be limited to those information. There are many other useful information that can be interesting to have in the notification, like humidity, pressure, wind speed, precipitation volume, etc. All of the those informations should be available in the function.

aajjbb commented 8 years ago

It depends on people, I think some of these information could be useful for some users, but the naughty notify for the widget would get bloated, and even, so large for some monitors.

The best approach would be to make the user decide what to insert into the notifications table.

aajjbb commented 8 years ago

If interest other users and maybe @copycat-killer himself. I could try to work on a way to make an user choose which information and in which order to be visible in the notification table.

lcpz commented 8 years ago

@romildo Now you can fetch any information from OWM API and display it your forecast notification.

The following example shows how to retrieve any data from forecast16 (default forecast API).

local read_pipe = require("lain.helpers").read_pipe

myweather = lain.widgets.weather({
    city_id = 3469058,  -- example city: Brasilia
    units = "imperial", -- example units: Fahrenheit
    notification_text_fun = function(wn)
        -- time of data forecasted
        local day = string.gsub(read_pipe(string.format("date -u -d @%d +'%%A %%d'", -- customize date cmd here
                                                        wn["dt"])), "\n", "")

        -- weather condition
        local desc = wn["weather"][1]["description"]

        -- temperatures, units are defined above
        local tmin = math.floor(wn["temp"]["min"])   -- min daily
        local tmax = math.floor(wn["temp"]["max"])   -- max daily
        local tmor = math.floor(wn["temp"]["morn"])  -- morning
        local tday = math.floor(wn["temp"]["day"])   -- day
        local teve = math.floor(wn["temp"]["eve"])   -- evening
        local tnig = math.floor(wn["temp"]["night"]) -- night

        -- pressure, hPa
        local pres = math.floor(wn["pressure"])

        -- humidity, %
        local humi = math.floor(wn["humidity"])

        -- wind speed, miles/hour if units are imperial, meter/sec otherwise 
        local wspe = math.floor(wn["speed"])

        -- wind degrees, meteorological degrees
        local wdeg = math.floor(wn["deg"])

        -- cloudliness, %
        local clou = math.floor(wn["clouds"])

        -- format infos as you like, HTML text markup is allowed
        return string.format("<br><b>%s</b>: %s<br>temperatures: min %d - max %d °F<br>pressure: %d hPa<br>humidity: %d%%<br>wind: %d miles/hour at %d°<br>cloudliness: %d%%<br>", day, desc, tmin, tmax, pres, humi, wspe, wdeg, clou)
    end,
    settings = function()
        units = math.floor(weather_now["main"]["temp"])
        widget:set_text(" " .. units .. " ")
    end
})

Screenshot (don't care about my Italian date, that it's just my machine localization).

This other example shows how to retrieve any data from forecast5 instead.

local read_pipe = require("lain.helpers").read_pipe

myweather = lain.widgets.weather({
    city_id = 3469058,  -- example city: Brasilia
    units = "imperial", -- example units: Fahrenheit
    forecast_call = "curl -s 'http://api.openweathermap.org/data/2.5/forecast?id=%s&units=%s&lang=%s&cnt=%s&APPID=%s'",
    notification_text_fun = function(wn)
        -- every data is supposed to be valid at the moment of calculation (see tcalc below)

        -- time of data forecasted
        local day = string.gsub(read_pipe(string.format("date -u -d @%d +'%%A %%d'", -- customize date cmd here
                                                        wn["dt"])), "\n", "")

        -- weather condition
        local desc = wn["weather"][1]["description"]

        -- temperatures, units are defined above
        local temp = math.floor(wn["main"]["temp"])     -- temp now
        local tmin = math.floor(wn["main"]["temp_min"]) -- current min
        local tmax = math.floor(wn["main"]["temp_max"]) -- current max

        -- pressure, hPa
        local pres = math.floor(wn["main"]["pressure"])   -- sea level by default
        local pres = math.floor(wn["main"]["sea_level"])  -- sea level
        local pres = math.floor(wn["main"]["grnd_level"]) -- ground level

        -- humidity, %
        local humi = math.floor(wn["main"]["humidity"])

        -- wind speed, miles/hour if units are imperial, meter/sec otherwise
        local wspe = math.floor(wn["wind"]["speed"])

        -- wind degrees, meteorological degrees
        local wdeg = math.floor(wn["wind"]["deg"])

        -- cloudliness, %
        local clou = math.floor(wn["clouds"]["all"])

        -- rain volume for last 3 hours, mm
        if wn["rain"] then
            local rain3h = math.floor(wn["rain"]["3h"])
        else
            local rain3h = 0
        end

        -- snow volume for last 3 hours, mm
        if wn["snow"] then
            local snow3h = math.floor(wn["snow"]["3h"])
        else
            local snow3h = 0
        end

        local tcalc = wn["dt_txt"]

        -- format infos as you like, html text markup is allowed
        return string.format("<br><b>%s</b>: %s<br>temperatures: min %d - max %d °F<br>pressure: %d hPa<br>humidity: %d%%<br>wind: %d miles/hour at %d°<br>cloudliness: %d%%<br>", day, desc, tmin, tmax, pres, humi, wspe, wdeg, clou)
    end,
    settings = function()
        units = math.floor(weather_now["main"]["temp"])
        widget:set_text(" " .. units .. " ")
    end
})
romildo commented 8 years ago

Thanks.