ultrabug / py3status

py3status is an extensible i3status wrapper written in python

Home Page:https://ultrabug.github.io/py3status/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

3.41 update broke weather_owm module

mlmatlock opened this issue · comments

Describe the bug

Upgrade to v3.41 broke weather_owm for me

Your py3status version

py3status version 3.41 (python 3.10.2) on sway

To Reproduce
Steps to reproduce the behavior along with your py3status configuration (filter out any private values):

  1. Add module 'weather_owm'
  2. Configure module like this my weather_owm config snippet
  3. Run py3status 'Normal statusbar start from sway config.'
  4. See error

Expected behavior

Proper module output/display as from previous versions

Screenshots
Screenshot from v3.40:
3 40_no_error

Screenshot from v3.41:
3 41_error

Additional context

Bisect accomplished. Results:

`86f465972bc298c38925dc9fb00c84639b4bc3be is the first bad commit
commit 86f4659
Author: Ultrabug ultrabug@users.noreply.github.com
Date: Tue Feb 1 11:01:44 2022 +0100

weather_owm module: fix forecast by using new onecall api endpoint (#2097)

thx to @cjquines

closes #2096

py3status/modules/weather_owm.py | 47 +++++++++++++++++++++++++++-------------
1 file changed, 32 insertions(+), 15 deletions(-)`

Sorry for breaking your module @mlmatlock 😇 Nice setup!

So we get a HTTP 400 error... pfff :( I'll check it out

Found & fixed, thanks for providing everything I needed to help

Thanks, @ultrabug! I miss my weather. :)

Now, I am noticing (still related, I would think):

The call to the onecall API seems to be for a DAILY request; so while my forecast_icons now match with the onecall output, I've lost my CURRENT conditions (right now, the remainder of my display is based on the daily JSON output key).

Playing with direct requests to the API, I've found that you can get the current conditions and daily forecast by excluding the minutely and hourly keys.

@mlmatlock can you elaborate please with details?

@ultrabug:

Note: py3status was refreshed immediately prior to the API call.

3 41_git_update

Raw JSON output

Filtered thru a viewer (thru day 3)

As you can see, the current conditions do not match the output, but the forecast icons are correct.

Ok, so I figured out how to put my api key and location directly into a stand-alone copy of weather_owm.py, and ran it. Below status bar output is from the 3.40 version, running as a custom module, and updated immediately prior to running the self test.

20220301_10h19m23s_grim

This is the terminal output of the test (no need to let it run forever).

Well @mlmatlock indeed, the "current" one is derived from the daily forecast, day 0 (= current) which might be less accurate than the real current one

Thing is, the onecall API does not expose a consistent view on each of the forecast versions it returns...

It will be inaccurate, because it is still a forecast of conditions.

Like I've said before, I'm not a coder, but I see:

OWM_CURR_ENDPOINT = "https://api.openweathermap.org/data/2.5/weather?"
OWM_FUTURE_ENDPOINT = "https://api.openweathermap.org/data/2.5/forecast?"
OWM_ONECALL_ENDPOINT = "https://api.openweathermap.org/data/2.5/onecall?"

and

    def _get_weather(self, extras):
        # Get and process the current weather
        params = {"appid": self.api_key, "lang": self.lang}
        extras.update(params)
        `i

    def _get_forecast(self, extras):
        # Get the next few days
        if self.forecast_days == 0:
            return []
        # Get raw data
        params = {
            "appid": self.api_key,
            "lang": self.lang,
            "cnt": self.forecast_days + 1,
        }
        extras.update(params)
        data = self._make_req(OWM_FUTURE_ENDPOINT, extras)
        # Extract forecast
        weathers = data["list"]
        return weathers[:-1] if self.forecast_include_today else weathers[1:]

    def _get_onecall(self, extras):
        # Get and process the current weather
        params = {"appid": self.api_key, "lang": self.lang}
        extras.update(params)
        return self._make_req(OWM_ONECALL_ENDPOINT, extras)

Where is the output from return self._make_req(OWM_CURR_ENDPOINT, extras)?

Then down here is where I think the problem is:

            onecall = self._get_onecall({"lat": lat, "lon": lon})
            onecall_daily = onecall["daily"]
            fcsts_days = self.forecast_days + 1
            text = self._format(
                onecall_daily[0], onecall_daily[1:fcsts_days], city, country,

A call (with no "exclude" key), via https://api.openweathermap.org/data/2.5/onecall?lat=32.61645&lon=-83.63354&units=imperial&appid=redacted

resulted in this collapsed JSON:


lat : 32.6165
lon : -83.6335
timezone : "America/New_York"
timezone_offset : -18000
current
minutely
hourly
daily

The info under "current" matches the info from the old API call.