#!/usr/bin/env python3 import logging import subprocess from enocean.communicators.serialcommunicator import SerialCommunicator # ----------------------------- # Konfiguration # ----------------------------- # ----------------------------- # EnOcean # ----------------------------- ENOCEAN_PORT = "/dev/ttyS4" SENDER_ID = "FE:D0:A6:44" # ----------------------------- # KNXD # ----------------------------- KNXD_IP = "ip:172.20.21.168" GA_FRONT = "11/1/14" GA_REAR = "11/1/15" # ----------------------------- # Logging # ----------------------------- logging.basicConfig( level=logging.INFO, format="%(asctime)s %(levelname)s: %(message)s" ) log = logging.getLogger("enocean-knx") # ----------------------------- # KNX Senden über knxd # ----------------------------- def knx_write(ip: str, ga: str, state: bool): """ Sendet Boolean an KNX über knxd (groupswrite). """ value = "1" if state else "0" try: subprocess.run( ["/usr/lib/knxd/groupswrite", ip, ga, value], check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL ) log.info(f"KNX → {ga} = {value}") except Exception as e: log.error(f"KNX send failed: {e}") # ----------------------------- # EnOcean Verarbeitung # ----------------------------- last_button = None # "front" | "rear" def process_packet(packet): global last_button try: sender = packet.sender_hex if sender != SENDER_ID: return # Rohdaten data = packet.data if not data: return event = data[1] # ------------------------- # Fronttür (Button BO) # ------------------------- if event == 0x70: last_button = "front" knx_write(KNXD_IP, GA_FRONT, True) log.info("Front door OPEN") elif event == 0x00 and last_button == "front": knx_write(KNXD_IP, GA_FRONT, False) log.info("Front door CLOSED") # ------------------------- # Hecktür (Button BI) # ------------------------- elif event == 0x50: last_button = "rear" knx_write(KNXD_IP, GA_REAR, True) log.info("Rear door OPEN") elif event == 0x00 and last_button == "rear": knx_write(KNXD_IP, GA_REAR, False) log.info("Rear door CLOSED") except Exception as e: log.error(f"Packet error: {e}") # ----------------------------- # Main Loop # ----------------------------- def main(): log.info("Starting EnOcean → KNX gateway") communicator = SerialCommunicator(port=ENOCEAN_PORT) communicator.start() try: while True: packet = communicator.receive.get() process_packet(packet) except KeyboardInterrupt: log.info("Stopping gateway") finally: communicator.stop() if __name__ == "__main__": main()