Sync Object Method from async_turn_on

Hi All,

I have a custom component which I am currently trying to rewrite into async.
Within my old light entity I had the following method:

    def turn_on(self, **kwargs):
        """Turn the light on."""
        _LOGGER.debug("%s: turn_on: %s", self._board.friendlyname, self._name)
        self._board.SetLight(self._identifier,STATE_ON)

trying to rewrite this into async following this instruction my code looks like the following:

    async def async_turn_on(self, **kwargs) -> None:
        """Async: Turn the light on"""
        try:
            _LOGGER.debug("%s: async_turn_on: %s", self._board.friendlyname, self._name)
            self.hass.async_add_executor_job(self._board.SetLight(self._identifier,STATE_ON))
        except Exception as e:
            _LOGGER.error("async_turn_on: Failed to turn on %s: %s", self._name, str(e))

unfortunately with this I receive the error:

2021-08-25 08:46:13 DEBUG (MainThread) [custom_components.dscriptmodule.light_class] dS-technik: async_turn_on: dS-technik_Light2
2021-08-25 08:46:13 DEBUG (MainThread) [custom_components.dscriptmodule.light_class] dS-technik: async update dS-technik_Light2
2021-08-25 08:46:13 ERROR (MainThread) [homeassistant] Error doing job: Future exception was never retrieved
Traceback (most recent call last):
File “/usr/local/lib/python3.9/concurrent/futures/thread.py”, line 52, in run
result = self.fn(*self.args, **self.kwargs)
TypeError: ‘bool’ object is not callable

Due to this my current workaround is the following:

    async def async_turn_on(self, **kwargs) -> None:
        """Async: Turn the light on"""
        try:
            _LOGGER.debug("%s: async_turn_on: %s", self._board.friendlyname, self._name)
            self._board.SetLight(self._identifier,STATE_ON) 
            await asyncio.sleep(0)
        except Exception as e:
            _LOGGER.error("async_turn_on: Failed to turn on %s: %s", self._name, str(e))

never the less I doubt this is the intended way to go async here…
Any advice how this should be translated correctly as the underlying python class holding the “_board.SetLight()” method is not async at the moment.

Thanks for your help in advance

The simplest approach is to have the method not be async since the underlying communication is not asynchronous.

The approach you have taken, while it works, will block other asyncio tasks from executing while your method is blocked on whatever I/O is being done. Since I/O usually takes time (milliseconds), this is now time that is not available for other tasks,

Thanks Pete for your reply.
Well I have rewritten the underlying python module providing the “_board.SetLight()” function to provide a “_board.async_SetLight()” option which then really uses asyncio down to the client / server architecture.

The only challenge I have with this at the moment is that (while the communication itself is very fast) it causes a damn high CPU which I did not expect. Especially as python can work only with one core at the same time I might have to think about overclocking or replacing the underlaying device…

Just a short notice to others searching at this post due to high CPU usage.
This was caused due to a parallel async loop I created within the underlying python module.

Doing a try/except clause within the python module to first test if an async loop already exists and only creating a new one if I cannot receive an existing one massively dropped down the CPU usage again and provided me with much higher performance.