Implemented differential poll intervals which significantly reduces polling#208
Conversation
* Poll intervals adhere to the API guidelines * Implemented multiple coordinators to handle the various poll intervals * Top which polls for firmware updates, once every day * Info which polls for device info updates, once every hour * One per device for handling run-time state data update. Every minute during charging, 10 minute otherwise * Fixed trigger poll sequencer to use the coordinator and make sure only one run per device * API: Added Charger.is_charging() method * Removed user configurable scan interval
custom_components/zaptec/__init__.py
Outdated
| ZAPTEC_POLL_BUILD_INTERVAL, | ||
| ZAPTEC_POLL_CHARGER_TRIGGER_DELAYS, | ||
| ZAPTEC_POLL_CHARGING_INTERVAL, | ||
| ZAPTEC_POLL_INFO_INTERVAL, | ||
| ZAPTEC_POLL_INSTALLATION_TRIGGER_DELAYS, | ||
| ZAPTEC_POLL_IDLE_INTERVAL, |
There was a problem hiding this comment.
Wouldn't it be nicer to keep interval in front of the different states, so that the intervals stick together when alfabetized?
| ZAPTEC_POLL_BUILD_INTERVAL, | |
| ZAPTEC_POLL_CHARGER_TRIGGER_DELAYS, | |
| ZAPTEC_POLL_CHARGING_INTERVAL, | |
| ZAPTEC_POLL_INFO_INTERVAL, | |
| ZAPTEC_POLL_INSTALLATION_TRIGGER_DELAYS, | |
| ZAPTEC_POLL_IDLE_INTERVAL, | |
| ZAPTEC_POLL_CHARGER_TRIGGER_DELAYS, | |
| ZAPTEC_POLL_INSTALLATION_TRIGGER_DELAYS, | |
| ZAPTEC_POLL_INTERVAL_BUILD, | |
| ZAPTEC_POLL_INTERVAL_CHARGING, | |
| ZAPTEC_POLL_INTERVAL_INFO, | |
| ZAPTEC_POLL_INTERVAL_IDLE, |
There was a problem hiding this comment.
Very good idea. Fixed.
custom_components/zaptec/__init__.py
Outdated
| kw = {"state": True, "info": True} | ||
| else: | ||
| delays = ZAPTEC_POLL_CHARGER_TRIGGER_DELAYS | ||
| kw = {"state": True} |
There was a problem hiding this comment.
kw is no longer needed since it's now handled by self.options.poll_args
There was a problem hiding this comment.
Yes, that kw does nothing. Removed.
custom_components/zaptec/__init__.py
Outdated
| @@ -507,22 +612,35 @@ async def _trigger_poll(self, obj: ZaptecBase) -> None: | |||
| delta, | |||
| kw, | |||
There was a problem hiding this comment.
| kw, | |
| self.options.poll_args, |
There was a problem hiding this comment.
No. kw, removed altogether. So fixed.
custom_components/zaptec/__init__.py
Outdated
|
|
||
| This function is called on data updates from the coordinator. | ||
| """ | ||
| zaptec_obj = self.options.zaptec_object |
There was a problem hiding this comment.
since zaptec_obj.is_charging() only exists if zaptec_obj is a Charger, I think we can make it explicit:
| zaptec_obj = self.options.zaptec_object | |
| zaptec_obj: Charger = self.options.zaptec_object |
There was a problem hiding this comment.
Added. I also made the code even more defensive and raise an error if zaptec_object is anything else than a Charger. Its good to be explicit.
custom_components/zaptec/__init__.py
Outdated
| zaptec_obj = zaptec[deviceid] | ||
|
|
||
| if isinstance(zaptec_obj, Installation): | ||
| poll_args = {"state": True, "info": True, "firmware": False} |
There was a problem hiding this comment.
Does polling installation state do anything?
There was a problem hiding this comment.
And since installation info is already handled by info_coordinator, do we even want a timed polling of this here, or do we just want the ones triggered by HA-actions?
There was a problem hiding this comment.
Technically inthe info_coordinator and the device_coordinator overlaps on info polling for installations. My thinking is that the device coordinator is a replacement of not having state, and that we poll it every 10 minutes. The info coordinator is run every 60 minutes, so it doesn't overload the server having them both.
The great thing about having the device coordinator for the installation is that it automatically provides the mechanism for sequenced polls if the "max current" number dial is changed. Which I've seen many times is needed.
What this doesn't have thou, is your comment that triggers of changes in the installation device, should also trigger its chargers. That we'll have to look at later.
There was a problem hiding this comment.
What this doesn't have thou, is your comment that triggers of changes in the installation device, should also trigger its chargers. That we'll have to look at later.
As long as this is covered before we fully close #202, I think we're good here.
custom_components/zaptec/__init__.py
Outdated
| options=ZaptecUpdateOptions( | ||
| name=deviceid, | ||
| update_interval=ZAPTEC_POLL_IDLE_INTERVAL, | ||
| charging_update_interval=ZAPTEC_POLL_CHARGING_INTERVAL, |
There was a problem hiding this comment.
From here it looks like installation also changes polling frequency during charging, and it's not until you check in the ZaptecUpdateCoordinator constructor it becomes apparent that that is not the case.
There was a problem hiding this comment.
Yes, I changed the code to make it more explicit. Please take a look and see if it is easier to follow now. Thanks.
* Fixed naming of `ZAPTEC_POLL_INTERVAL_` to make them order nicely * Added more documentation around device entity creation * Make code more explicit * Removed left-overs
|
LGTM The only question I have is what happens if a periodic poll fails at some point, especially the long period ones? I occasionally get some |
Thank you.
The flippant answer is: The same way all other poll requests from HA are handled :D The more serious response is that I believe the coordinator have a mechanism for handling that, but I'm not 100% sure. It's a valid question.
This is interesting, because say that there is some mechanism in coordinators that handles connection issues, that would not affect the other coordinators. They will keep on trying and eventually time out. This is something we definitely need to test more when the beta is out. |
This PR implements the full system for differential poll intervals which significantly reduces the amount of polling. This fixes #205, #202, #199, #189 and is implementing as discussed in #188. Aims to address #165
Charger.is_charging()method