Bridging synchronous logic with an asynchronous hardware library
The MELCloud client library is asynchronous, while the scheduler and decision engine were intentionally designed around a predictable synchronous flow.
Rather than converting the entire application to async, I isolated the difference inside the MELCloud service.
A dedicated background thread owns its own asyncio event loop. Synchronous callers submit coroutines through run_coroutine_threadsafe() and receive normal return values.
Result
The async complexity remains contained inside one integration module while the rest of the system keeps a simple synchronous interface.