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

Add DataUpdateCoordinator to bmw_connected_drive #67003

Merged
merged 12 commits into from
Apr 21, 2022

Conversation

rikroe
Copy link
Contributor

@rikroe rikroe commented Feb 21, 2022

Breaking change

The button.<your_vehicle_refresh entity is deprecated and will be removed in a future version. Please use the homeassistant.update_entity service with any BMW entity to force-refresh all platforms from the BMW API.

Proposed change

Adds a DataUpdateCoordinator to bmw_connected_drive .

This leads to drastically reduced API calls, as before each platform would call the API twice every 5 minutes. Now, only the coordinator does the required two requests.

Main changes:

  • Move setup_account() (i.e. all library-related code) from __init__.py to coordinator.py
  • Replace BMWConnectedDriveAccount with BMWDataUpdateCoordinator in all platforms
  • Remove all update() methods in platforms and switch to properties
  • Replace all update() methods in platforms with __handle_coordinator_update()

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)
  • 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
  • The code has been formatted using Black (black --fast 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.

The integration reached or maintains the following Integration Quality Scale:

  • No score or internal
  • 🥈 Silver
  • 🥇 Gold
  • 🏆 Platinum

To help with the load of incoming pull requests:

@probot-home-assistant
Copy link

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

rikroe added a commit to bimmerconnected/ha_custom_component that referenced this pull request Mar 27, 2022
@rikroe rikroe force-pushed the bmw-updatecoordinator branch 2 times, most recently from 5020047 to a445592 Compare April 13, 2022 22:03
@rikroe
Copy link
Contributor Author

rikroe commented Apr 18, 2022

Just to be clear: The desired way of refreshing DataUpdateCoordinator entities is using _handle_coordinator_update(self) instead of using @property for the separate values?

I find it adds quite some verbosity, but I'll happily adhere if thats the desired path!

Didn't change device_tracker though - it requires the latitude and longitude properties anyway (will raise NotImplementedError otherwise), so would have bloated it up totally.

EDIT: Based on your input, I revisited and refactored the binary sensors - here it does make it much clearer imo.

Comment on lines +94 to +95
"door_lock_state": vehicle_state.door_lock_state.value,
"last_update_reason": vehicle_state.last_update_reason,
Copy link
Member

@bdraco bdraco Apr 18, 2022

Choose a reason for hiding this comment

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

For a future PR since this is existing:

It looks like these should be sensor entities
https://developers.home-assistant.io/docs/core/entity/?_highlight=extra_state_attributes

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I know, sorry. It regularly comes up but haven't had the chance to go give them a good clean up.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks for the reminder, thats on my todo list once the bigger backend changes are done!

@rikroe
Copy link
Contributor Author

rikroe commented Apr 20, 2022

Added the breaking change paragraph + now logging a warning. Also created a docs PR.

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.

Thanks @rikroe

@bdraco bdraco merged commit 8065346 into home-assistant:dev Apr 21, 2022
@github-actions github-actions bot locked and limited conversation to collaborators Apr 22, 2022


class BMWConnectedDriveBaseEntity(Entity):
class BMWConnectedDriveBaseEntity(CoordinatorEntity, Entity):
Copy link
Member

Choose a reason for hiding this comment

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

We don't need to inherit from Entity. The CoordinatorEntity already does that.

"""Fetch data from BMW."""
try:
async with async_timeout.timeout(15):
if isinstance(self.account, ConnectedDriveAccount):
Copy link
Member

Choose a reason for hiding this comment

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

It's faster to check for None than using isinstance. Please invert the check.

@property
def extra_state_attributes(self) -> dict:
"""Return entity specific state attributes."""
return dict(self._attrs, **{ATTR_DIRECTION: self.vehicle.status.gps_heading})
Copy link
Member

Choose a reason for hiding this comment

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

return {**self._attrs, ATTR_DIRECTION: self.vehicle.status.gps_heading}

Or now in Python 3.9 we can do:

return self._attrs | {ATTR_DIRECTION: self.vehicle.status.gps_heading}

state = getattr(self._vehicle.status, self.entity_description.key)
return cast(StateType, self.entity_description.value(state, self.hass))
@callback
def _handle_coordinator_update(self) -> None:
Copy link
Member

Choose a reason for hiding this comment

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

As we can see it's often more succinct to implement the entity state property than overriding _handle_coordinator_update in coordinator entities.

@rikroe rikroe deleted the bmw-updatecoordinator branch June 3, 2022 10:17
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.

4 participants