New initial version
This commit is contained in:
@@ -0,0 +1,134 @@
|
||||
#!/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()
|
||||
|
||||
Reference in New Issue
Block a user