Going to individual polling to global polling

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.

2 Likes

See https://developers.home-assistant.io/docs/integration_fetching_data#coordinated-single-api-poll-for-data-for-all-entities

3 Likes

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.

1 Like

Hi !
I use DataUpdateCoordinator and it works well :slight_smile: 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 :frowning:

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.

1 Like

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 :frowning: