New to Home Assistant - How do you listen to events

Hi,

I’m very new to the HomeAssistant world and wanted to play with custom integration to get some understanding.

I have built a light integration with python tinytuya (I know there is localtuya but that would defeat the point of learning) and it works.
My next step is to create a function that listens to the device’s state on the network and updates it dynamically.

tinytuya provides a receive() definition and heartbeat definition that works well on my local machine

while(True):
    data = device.receive()
    print(data)
    if not data:
        print(" > Send Heartbeat Ping < ")
        device.heartbeat()

But I don’t know

  1. what to use to implement this “listener” (Separate threads of HA libraries)
    or
  2. How to implement it - I guess this should be in the light.py given that it has access to hass

Any guidance would be appreciated or example?

Not to discourage you, but I have a technical background and have been using Home Assistant for 7 years, and have never felt the need to write a custom integration. HA will keep you fully occupied configuring integrations, automations, dashboards etc., and will help deplete your bank account by tempting you to automate everything within reach. I would be concerned that jumping in the deep end would be discouraging and end your HA journey prematurely.

1 Like

Well I understand your point on this and I am also curious how it’s done because I am also lacking this knowledge.
While MichaelBlight has also a point but I hope you are not becoming discouraged in the end.

The best way to go about writing your own integration is to follow the developer docs on how to set up a scaffold empty integration, and look at what others do. One thing though. What you show, a while true loop, is not a listener and would never be accepted in an integration. The integration should be event driven, maybe polling based on timer events, but never idle looping.

You’d make a long running coroutine that fires events from the event bus or dispatches events to your integration. Your mileage may vary here because there’s a lot of ways to screw this up. HA usually will tell you when you do something wrong in logs.

e.g.

async def xyz(...):
    while True:
       ...
       hass.bus.async_fire(... some event ...)
       # or 
       dispatcher_send(....)

then make a callback

@callback
def _start(_: Event) -> None:
    xyz(...)

then when registering

hass.bus.async_listen_once(
    EVENT_STARTED, # You can use any event here, import the event when HA starts
    _start
)

That would only be ok if data = device.receive() yields control and waits for responses for a reasonable amount of time. If it returns straight away when there’s no data it would be a cpu hog?

There’s alot of gotcha’s here. It really depends if the lib he’s using is async or not. If it’s not async, OP will need to create a thread for it. But yes, yield, or other fine tuning is likely needed.

Thanks, I do try to follow the documentation and also learn from other integrations.

  1. I find it a bit hard to follow the documentation - it jumps quite a bit and when I compare it to actual integration - things are missing in the document or only make sense after re/re/re-reading other integration

  2. Yes I’m not a find of the while true and don’t want to use it by any means - I’m just trying to understand some best practices.