-
Notifications
You must be signed in to change notification settings - Fork 31
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
Cache and update the last Vehicle #369
base: main
Are you sure you want to change the base?
Conversation
a3835c1
to
95a0265
Compare
Thanks for working on this, i had encountered this issue as well and it stopped me from implementing the caching for all responses. Great work 🎉 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great stuff 🍻
This will allow us to be a lot more flexible in caching and thus use less API credits, yay!
Als a follow-up, we may need to revisit the code that does updates, so we force-update only whats needed, and cache the rest.
Also, i think this generally breaks homeassistant.update_entity
, we may need to fix that in a follow-up as well.
@@ -408,37 +412,39 @@ async def get_partial_vehicle(self, vin: str, capabilities: list[CapabilityId]) | |||
info = await self.get_info(vin) | |||
maintenance = await self.get_maintenance(vin) | |||
|
|||
vehicle = Vehicle(info, maintenance) | |||
if vin in self.vehicles: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It may be because im reviewing this on mobile or because of sleep deprivation, but i dont see where this dict gets filled with values?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the else
of this if
statement 😄
self.vehicles[vin] = Vehicle(info, maintenance)
Yeah there's definitely more we can do here. I'll create an issue to look further into this.
How so? The return values from |
95a0265
to
43ea0ae
Compare
It is related to the previous remark: |
Ah ok you mean that a forced refresh using the I'll poke around in the homeassistant-core code to see if we have a way (in the coordinator) to differentiate between a manually triggered update vs a scheduled one. |
- Use field.default_factory to automatically set the timestamp field when an instance is created - Create a common base model to deduplicate the timestamp field
When intentionally exluding specific capabilities (~endpoints) the problem is that the corresponding Vehicle fields will be None in the returned Vehicle. So either the client/caller must have the knowledge of the capability->endpoint->field mapping and stitch together the previous and new Vehicle, or the MySkoda class must store the last Vehicle(s) and update what can be updated. The second option seems much cleaner and keeps internal logic encapsulated in the myskoda lib.
43ea0ae
to
3d08e02
Compare
Yeah, kind of. Right now the behaviour of calling Since we are communicating calling I think i prefer As long as we only record the timestamps in the library and not do any active caching inside the library, we should be fine and this discussion can move to the integration. It would be preferred to not do any caching in the library to me, since we would then have to introduce more state. To me, any state belongs in the integration. |
So with the solution as I have it now in this PR, technically the library does caching, in the sense that it stores the last However, the library does not independently decide to skip fetching a specific capability/endpoint and return the 'cached' result (and I agree that it should never do that). If we want to completely avoid any form of state/caching in the library I think we need to do away with the concept of a I'm not set on any specific approach but what I didn't want to do is surgically rebuild the |
I hit a wall in skodaconnect/homeassistant-myskoda#632 trying to selectively exclude updates of the Vehicle.health based on the last timestamp:
When intentionally excluding specific capabilities (~endpoints) the
problem is that the corresponding Vehicle fields will be None in the
returned Vehicle.
So either the client/caller must have the knowledge of the
capability->endpoint->field mapping and stitch together the previous and
new Vehicle, or the MySkoda class must store the last Vehicle(s) and
update what can be updated. The second option seems much cleaner and
keeps internal logic encapsulated in the myskoda lib.
I've used the opportunity to refactor how the timestamp field is set. Rather than allowing it to be None and explicitly having to set it in the RestApi methods, we can use
field.default_factory
to automatically set the timestamp when an instance is created. Also create a common base model to deduplicate the timestamp field.