How To Integrate an Async Third Party Library (XKNX)

Hi,

I have been getting to grips with the Django platform to serve data etc and now want to try and incorporate a third party library - XKNX. This allows communication with building control devices, so what I want is to be able to present the user with an button that will trigger an action in XKNX (e.g. switch a light on and off).

The library is asynchronous and I would want it running whilst the Django app is running. This is a Hello World example of the library in use:

import asyncio
from xknx import XKNX
from xknx.devices import Light

async def main():
    xknx = XKNX()
    await xknx.start()
    light = Light(xknx,
                  name='HelloWorldLight',
                  group_address_switch='1/0/9')
    await light.set_on()
    await asyncio.sleep(2)
    await light.set_off()
    await asyncio.sleep(2)
    await xknx.stop()


loop = asyncio.get_event_loop()
loop.run_until_complete(main())
loop.close()

In my use case I would likely do the start() when Django starts up and then have the stop() happen when Django stops with an option to reset via an admin function perhaps. I would then have callback functions that execute when a command is sent or feedback data is received from the building control system

The main questions are:
1 - where I would hook this code in?
2 - how do I pass around the xknx object so I can see it in Django?
3 - what async considerations do I need to make?

Many thanks in advance!

J

While you probably can do this, I would have to ask whether or not you should.

When I have had to interface Django-based controls with continuously-running tasks, I have always done it through external communication channels communicating to external processes.

If you look at the rest of the Django world, that seems to be the common pattern. Both Celery (task queues) and Channels (“Worker tasks”) establish external processes for long-running tasks.

I have used, at various times and circumstances:

  • Celery
  • Redis
  • TCP sockets
  • Unix sockets

to communicate with external processes. I then define a “lightweight API” to manage the communications between Django and that process. While it is a bit more work to set it up initially, I find these types of architectures to be easier to manage, test, and debug. (It becomes very easy to use the Django shell to poke around with the API. And there are plenty of tools to watch and examine the traffic through the communications channels to see what’s getting passed in each direction.)

Ken

Yes - researching this suggests that perhaps ASGI could be an option which in principle would give the channel between the two processes.