Package: knxdclient
KNXDclientA pure Python async client for KNXD's (EIBD's) native Layer 4 KNX protocol.EIBD is a *NIX daemon for routing EIB/KNX telegrams through various interfaces and programmatically accessing the EIB/KNX bus.
It's part of the no-longer maintainedBCUSDK.
However, there's a fork calledKNXD, which is still actively maintained.This package reimplements small parts of the EIBD client (seeBCUSDK documentation, section 7.7)
in pure Python 3, based on asynchronous coroutines (asyncio).
Currently, it allows to open a Group Socket for sending and receiving KNX telegrams to/for any group address via KNXD.
Additionally, this package includes helper methodsencode_value()anddecode_value()to convert the send/received data from/to native Python types according to a known KNX Datapoint Type (DPT).Usage exampleimportasyncioimportknxdclientdefhandler(packet:knxdclient.ReceivedGroupAPDU)->None:print("Received group telegram:{}".format(packet))asyncdefmain()->None:# Raises a TimeoutError after 30 seconds of not receiving any traffic. This argument is optionalconnection=knxdclient.KNXDConnection(timeout=30.0)connection.set_group_apdu_handler(handler)awaitconnection.connect()# Connection was successful. Start receive loop:run_task=asyncio.create_task(connection.run())# Now that the receive loop is running, we can open the KNXd Group Socket:awaitconnection.open_group_socket()# Startup completed. Now our `handler()` will receive incoming telegrams and we can send some:awaitconnection.group_write(knxdclient.GroupAddress(1,3,2),knxdclient.KNXDAPDUType.WRITE,knxdclient.encode_value(True,knxdclient.KNXDPT.BOOLEAN))awaitasyncio.sleep(5)# Let's stop the connection and wait for graceful termination of the receive loop:awaitconnection.stop()awaitrun_taskasyncio.run(main())Alternatively, an async iterator can be used for receiving group telegrams:importasyncioimportknxdclient# KNX Datapoint Types of some known group addresses, used for decoding incoming values and encoding group RESPONSEDPTs={knxdclient.GroupAddress(1,2,3):knxdclient.KNXDPT.BOOLEAN,knxdclient.GroupAddress(4,5,6):knxdclient.KNXDPT.FLOAT16,}# Some values for responding to group READ telegramsCURRENT_VALUE={knxdclient.GroupAddress(1,2,3):True}asyncdefmain()->None:connection=knxdclient.KNXDConnection()awaitconnection.connect()try:# Start run task and open group socketrun_task=asyncio.create_task(connection.run())awaitconnection.open_group_socket()# Iterate asynchronously over incoming group telegramspacket:knxdclient.ReceivedGroupAPDUasyncforpacketinconnection.iterate_group_telegrams():# Respond to GROUP READ telegrams with known values from CURRENT_VALUE dictifpacket.payload.type==knxdclient.KNXDAPDUType.READ:address=packet.dstifaddressinCURRENT_VALUE:awaitconnection.group_write(address,knxdclient.KNXDAPDUType.RESPONSE,knxdclient.encode_value(CURRENT_VALUE[address],DPTs[address]))# Decode and log incoming group WRITE and RESPONSE telegramselse:ifpacket.dstnotinDPTs:# Skip telegrams with unknown datatypecontinuevalue=knxdclient.decode_value(packet.payload.value,DPTs[packet.dst])print(f"Telegram from{packet.src}to GAD{packet.dst}:{value}")finally:# Let's stop the connection and wait for graceful termination of the receive loop:awaitconnection.stop()awaitrun_taskasyncio.run(main())LicenseThis package is published under the terms of the Apache License 2.0.