Hello
I developped a custom component https://github.com/Aohzan/ipx800, through I have more than 40 entities that being pulled everytime.
I want to use the global state pull to make just one api call from hass but I don’t know how from my code. Can someone give me a little help ?
Thank you
Typically this is done using the dispatcher helper. See dispatcher.py. You can find many examples of integrations that use this.
I will try this, thanks
Yes I saw this, I think I have to change the way my component works to use it
The DataUpdateCoordinator class is very nice and it provides a lot of functionality if you are making an API call and then each entity retrieves it’s own information. If you need more control the dispatcher method is more flexible.
Hi !
I use DataUpdateCoordinator and it works well except I have an error from async:
2020-07-29 08:00:01 WARNING (MainThread) [homeassistant.util.async_] Detected I/O inside the event loop. This is causing stability issues. Please report issue to the custom component author for ipx800 doing I/O at custom_components/ipx800/__init__.py, line 262: data = self.ipx.global_get()
This is my code:
class IpxDataUpdateCoordinator(DataUpdateCoordinator):
"""Define an object to hold ipx data."""
def __init__(self, hass, ipx, update_interval):
"""Initialize."""
self.ipx = ipx
super().__init__(hass, _LOGGER, name=DOMAIN, update_interval=update_interval)
async def _async_update_data(self):
"""Get all states from API."""
data = {}
try:
data = self.ipx.global_get()
return data
except:
_LOGGER.warning("IPX800 global get failed, data received: %s", data)
Like a call the sync method global_get()
, I tried to use async_add_executor_job
(see here https://developers.home-assistant.io/docs/asyncio_working_with_async/#calling-sync-functions-from-async):
data = await hass.async_add_executor_job(self.ipx.global_get())
but data is always empty
Do you have an idea how I can fix this ?
Thanks
Did you get valid data with the sync blocking version?
I suspect that you haven’t refreshed the data and/or there is no listener. Put in a debug log statement to make sure it is actually getting refreshed?
Yes it works well, all my entities get their states, I only have the warning message:
2020-07-29 13:25:44 WARNING (MainThread) [homeassistant.util.async_] Detected I/O inside the event loop. This is causing stability issues. Please report issue to the custom component author for ipx800 doing I/O at custom_components/ipx800/__init__.py, line 262: data = self.ipx.global_get()
2020-07-29 13:25:44 WARNING (MainThread) [homeassistant.util.async_] Detected I/O inside the event loop. This is causing stability issues. Please report issue to the custom component author for ipx800 doing I/O at custom_components/ipx800/__init__.py, line 262: data = self.ipx.global_get()
2020-07-29 13:25:44 DEBUG (MainThread) [custom_components.ipx800] Finished fetching ipx800 data in 0.114 seconds
Try:
data = await hass.async_add_executor_job(self.ipx.global_get)
Note lack of calling sync function, you just pass the callable object.
I removed the try/catch and see that I didn’t have hass object defined since the beginning… now it works with your command:
class IpxDataUpdateCoordinator(DataUpdateCoordinator):
"""Define an object to hold ipx data."""
def __init__(self, hass, ipx, update_interval):
"""Initialize."""
self.ipx = ipx
super().__init__(hass, _LOGGER, name=DOMAIN, update_interval=update_interval)
async def _async_update_data(self):
"""Get all states from API."""
return await self.hass.async_add_executor_job(self.ipx.global_get)
thanks a lot
The danger of using an overly broad exception.
indeed