Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix nws forecast coordinators and remove legacy forecast handling #115857

Merged
merged 13 commits into from
May 3, 2024

Conversation

MatthewFlamm
Copy link
Contributor

@MatthewFlamm MatthewFlamm commented Apr 19, 2024

Proposed change

This PR adds listeners to the forecast coordinators to fix issue with the forecast updating. In doing so, the NWS handling of retries was discovered to be brittle to changes in core. It was suggested on discord to put the retry behavior upstream into pynws.

This enables further removal of custom code in the integration. Multiple years tests have been pared down now that we do not need to test custom things in the integration.

Release notes for pynws: https://github.com/MatthewFlamm/pynws/releases/tag/v1.7.0

Type of change

  • Dependency upgrade
  • Bugfix (non-breaking change which fixes an issue)
  • New integration (thank you!)
  • New feature (which adds functionality to an existing integration)
  • Deprecation (breaking change to happen in the future)
  • Breaking change (fix/feature causing existing functionality to break)
  • Code quality improvements to existing code or addition of tests

Additional information

Checklist

  • The code change is tested and works locally.
  • Local tests pass. Your PR cannot be merged unless tests pass
  • There is no commented out code in this PR.
  • I have followed the development checklist
  • I have followed the perfect PR recommendations
  • The code has been formatted using Ruff (ruff format homeassistant tests)
  • Tests have been added to verify that the new code works.

If user exposed functionality or configuration variables are added/changed:

If the code communicates with devices, web services, or third-party tools:

  • The manifest file has all fields filled out correctly.
    Updated and included derived files by running: python3 -m script.hassfest.
  • New or updated dependencies have been added to requirements_all.txt.
    Updated by running python3 -m script.gen_requirements_all.
  • For the updated dependencies - a link to the changelog, or at minimum a diff between library versions is added to the PR description.
  • Untested files have been added to .coveragerc.

To help with the load of incoming pull requests:

@home-assistant
Copy link

Hey there @kamiyo, mind taking a look at this pull request as it has been labeled with an integration (nws) you are listed as a code owner for? Thanks!

Code owner commands

Code owners of nws can trigger bot actions by commenting:

  • @home-assistant close Closes the pull request.
  • @home-assistant rename Awesome new title Renames the pull request.
  • @home-assistant reopen Reopen the pull request.
  • @home-assistant unassign nws Removes the current integration label and assignees on the pull request, add the integration domain after the command.
  • @home-assistant add-label needs-more-information Add a label (needs-more-information, problem in dependency, problem in custom component) to the pull request.
  • @home-assistant remove-label needs-more-information Remove a label (needs-more-information, problem in dependency, problem in custom component) on the pull request.

@MatthewFlamm
Copy link
Contributor Author

This is still WIP, but opening early, so that it can be contrasted with #115836.

@MatthewFlamm MatthewFlamm mentioned this pull request Apr 19, 2024
20 tasks
@@ -355,7 +322,7 @@ async def test_forecast_service(

assert instance.update_observation.call_count == 2
assert instance.update_forecast.call_count == 2
assert instance.update_forecast_hourly.call_count == 1
assert instance.update_forecast_hourly.call_count == 2
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Failure in this test on line above shows that CoordinatorWeatherEntity.forecast_coordinators["twice_daily"] is not called on a time basis, at least in this integration implementation. This PR tries to use the CoordinatorWeatherEntity methods as much as possible here however.

Copy link
Contributor Author

@MatthewFlamm MatthewFlamm Apr 19, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CoordinatorWeatherEntity does not have a coordinator.async_add_listener call in async_added_to_hass.

async def async_added_to_hass(self) -> None:
"""When entity is added to hass."""
await super().async_added_to_hass()
self.async_on_remove(partial(self._remove_forecast_listener, "daily"))
self.async_on_remove(partial(self._remove_forecast_listener, "hourly"))
self.async_on_remove(partial(self._remove_forecast_listener, "twice_daily"))
def _remove_forecast_listener(
self, forecast_type: Literal["daily", "hourly", "twice_daily"]
) -> None:
"""Remove weather forecast listener."""
if unsub_fn := self.unsub_forecast[forecast_type]:
unsub_fn()
self.unsub_forecast[forecast_type] = None

It only occurs if a subscription is performed first:

https://github.com/home-assistant/core/blob/a8025a8606fa63be570fb43f0f0643068bef8844/homeassistant/components/weather/__init__.py#L1132C5-L1141C10

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

coordinator.async_add_listener is now called in async_added_to_hass to fix this.


async def async_update(self) -> None:
"""Update the entity.

Only used by the generic entity update service.
"""
await self.coordinator.async_request_refresh()
await self.coordinator_forecast_legacy.async_request_refresh()
if self.forecast_coordinators["twice_daily"] is not None:
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This sort of behavior would be better in CoordinatorWeatherEntity in my opinion.

@MatthewFlamm
Copy link
Contributor Author

@kamiyo this PR goes further than yours by removing unneeded methods, legacy_forecast related, and we don't need the _handle_update_* methods as the upstream library already does the caching. Also the available code no longer should depend on the forecasts as the entity's state no longer has the forecast.

But now the one test for available when the observation coordinator has an error is failing. I cannot figure this out. Did I make some logic error here?

Another thought is that our custom coordinator override of _schedule_refresh could be causing problems.

@MatthewFlamm
Copy link
Contributor Author

These lines are the cause

if not self.last_update_success and not previous_update_success:
return

Previously, the forecast update would notify the entity to update it's availability. Now it will never update it's availability if it has consecutive failures in a row. Will remove here for feedback.

@kamiyo
Copy link
Contributor

kamiyo commented Apr 24, 2024

@MatthewFlamm Is this change to update_coordinator.py causing the test with the mock update function to fail? Should we update that test?

What was the original issue you were having with available failing? Was it

assert state.state == STATE_UNAVAILABLE

@MatthewFlamm
Copy link
Contributor Author

MatthewFlamm commented Apr 24, 2024

@kamiyo, (edited) I had a chat with some core devs on discord on this topic. They did not seem keen to change the core code, but suggested moving the multiple retry behavior inside pynws so that it looks like 1 API call to HA. This will take some time unfortunately. Maybe your PR should move forward in the meantime to fix the behavior, then this one can clean everything up?

@kamiyo
Copy link
Contributor

kamiyo commented May 1, 2024

I'll test this locally

@MatthewFlamm
Copy link
Contributor Author

Thanks for testing. This should be mostly done so it is ready for codeowner review.
I want to go over this once more and do more live testing before I officially mark it as "ready" for wider review.

@MatthewFlamm MatthewFlamm marked this pull request as ready for review May 2, 2024 01:10
@MatthewFlamm
Copy link
Contributor Author

I have tested locally and it is working well, so I'm opening for full review.

@kamiyo
Copy link
Contributor

kamiyo commented May 2, 2024

My local testing is also stable and working.

Copy link
Member

@bdraco bdraco left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

homeassistant/components/nws/weather.py Outdated Show resolved Hide resolved
homeassistant/components/nws/weather.py Outdated Show resolved Hide resolved
homeassistant/components/nws/weather.py Outdated Show resolved Hide resolved
@bdraco
Copy link
Member

bdraco commented May 2, 2024

Screenshot 2024-05-02 at 9 45 07 AM

seems to work just fine for me

@MatthewFlamm
Copy link
Contributor Author

There are unrelated files in this PR

tests/components/geocaching/pycache/init.cpython-312.pyc.139816749228096

Was having problems with dependencies and pre-commit mypy and was forced to use git commit -n a few times. This crept in, good catch.

@MatthewFlamm MatthewFlamm marked this pull request as ready for review May 2, 2024 19:14
@home-assistant home-assistant bot requested review from bdraco and kamiyo May 2, 2024 19:14
@bdraco
Copy link
Member

bdraco commented May 2, 2024

Looks like forecast data is working but everything has an unknown state

Screenshot 2024-05-02 at 2 15 55 PM Screenshot 2024-05-02 at 2 15 58 PM

@MatthewFlamm
Copy link
Contributor Author

MatthewFlamm commented May 2, 2024

I cannot test live now, but can later. In the meantime, this could be the infamous NWS server temporarily returning junk data problem.

I plan on adding in a retry also when the data is blank, and returning an error if the data continues to be blank after the specified total retry time. [Edit: currently we only retry if there is a server error like 502]. This is for upstream. Captured this thought in MatthewFlamm/pynws#194

@MatthewFlamm
Copy link
Contributor Author

Working locally for me for KHOU

Screenshot_20240502-180017

Screenshot_20240502-180136

@bdraco
Copy link
Member

bdraco commented May 2, 2024

It recovered on its own

Screenshot 2024-05-02 at 5 44 47 PM

@bdraco
Copy link
Member

bdraco commented May 2, 2024

PHOG still seems to be flakey but it seems like its the incoming data

Screenshot 2024-05-02 at 5 45 43 PM

@bdraco
Copy link
Member

bdraco commented May 2, 2024

I think we can tag this for 2024.5.1 since the removal of the legacy forecast handling shouldn't be considering a breaking change since that was already removed.

Let me know if that sounds right or we should wait for 2024.6.x

@MatthewFlamm
Copy link
Contributor Author

I was under the impression that the legacy forecast handling was totally removed in core, if that is true, then I agree with you that this would be good to land 2024.5.x. There are subtle changes in behavior (availability of the entity, for example), but they are intended to support a bug fix.

@bdraco bdraco added this to the 2024.5.1 milestone May 2, 2024
@MatthewFlamm
Copy link
Contributor Author

A final live check is that the hourly forecast has been updating nicely, which indicates the problem is indeed fixed. From the same example as I posted above running continuously for a few hours, the hourly forecast is current (as of 9 PM EDT, not CDT). So I'm good with this. Thanks for the help and review!

Screenshot_20240502-212330

@frenck frenck merged commit 6413376 into home-assistant:dev May 3, 2024
38 checks passed
@MatthewFlamm MatthewFlamm deleted the nws-forecast-coord branch May 3, 2024 11:10
frenck pushed a commit that referenced this pull request May 3, 2024
@frenck frenck mentioned this pull request May 3, 2024
@github-actions github-actions bot locked and limited conversation to collaborators May 4, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

NWS Get_Forcasts returning old data
4 participants