Homematic Wired (W)LAN Gateway

Begonnen von maxx3105, 19 Juni 2026, 18:32:30

Vorheriges Thema - Nächstes Thema

maxx3105

Hallo Miteinander,

Da das originale HMW-LGW-O-DR-GS-EU nicht mehr produziert wird habe ich mich Hilfe einer KI dann gemacht einen Ersatz zu bauen. Welche Anforderungen soll das für FHEM erfüllen? Die Hardware läuft aktuell auf einem ESP32 somit kann es per LAN als auch WLAN angebunden werden. Serial und Passphrase. WebServer zur Konfiguration habe ich bereits eingeplant. AES AN/AUS hätte ich auch eingeplant. Habt ihr noch anregungen?

LG Markus 

maxx3105

Das Gateway läuft soweit. Bitte ausführlich testen.
https://github.com/maxx3105/HMW-Gateway-Pro

Ralf9

Hallo Markus,

die Idee hatte ich auch schon, aber ich habe den Code von der HM485_Protocol.pm nicht komplett verstanden.

Ich habe über Deinen Code mal drüber geschaut.
In der HM485_Protocol.pm wird nach dem Senden auf eine Antwort oder ack gewartet und dann ggf die die Nachricht bis zu zwei mal wiederholt, ich konnte dazu in Deinem Code nichts finden.
https://github.com/kc-GitHub/FHEM-HM485/blob/master/FHEM/lib/HM485/HM485d/HM485_Protocol.pm

In der Protokollbeschreibung steht dazu folgendes:
Zitat1.1.1. Vermeidung von Kollisionen auf dem RS485 Bus
Das Protokoll auf dem Bus muss Multimaster-Eigenschaften unterstützen. Es existiert mit der CCU zwar eine Zentrale
die auch die Kommunikation steuert, einzelne Module müssen aber auch ohne Aufforderung durch diese Senden
können. Z.B. bei anliegenden Events (Tastendrücke, geänderte Sensordaten usw.)

Die Informationen zur Kollisionsvermeidung sind derzeit Vermutungen von mir. Ggf. bedarf es noch einer weiteren
Überprüfung Vermutlich werden CSMA/CA Techniken eingesetzt.

- Die Module "überwachen" permanent den Bus (Carrier Sense)

- Ist der Bus für eine bestimmte Zeit (DIFS*) frei (welche muss noch rausgefunden werden) wartet das Modul
noch eine zufällige Zeit (Backoff) (ggf. auch abhängig der Geräteadresse).
Ist der Bus weiterhin frei, kann das Modul senden.

- Nach vollständigem Empfang einer Nachricht wartet das Modul noch eine gewisse Zeit (SIFS**) und sendet
dann die ACK Nachricht oder die Antwort.

- Bleibt die Antwort aus (missing ACK) wird nach einer Wartezeit (EIFS***) die Nachricht bis zu zwei mal wie-
derholt.

Gruß Ralf
FHEM auf Cubietruck mit Igor-Image, SSD und  hmland + HM-CFG-USB-2,  HMUARTLGW Lan,   HM-LC-Bl1PBU-FM, HM-CC-RT-DN, HM-SEC-SC-2, HM-MOD-Re-8, HM-MOD-Em-8
HM-Wired:  HMW_IO_12_FM, HMW_Sen_SC_12_DR, Selbstbau IO-Module HBW_IO_SW
Maple-SIGNALduino, WH3080,  Hideki, Id 7

maxx3105

Ich habe deine Frage an Claude (KI) weitergeleitet weil die ganze Programmierung meine Kenntnis etwas übersteigt.

Hallo Ralf,

guter Punkt — und du suchst genau richtig, nur an der falschen Stelle. Die Wiederhol-Logik fehlt im Gateway mit Absicht, weil sie dort nicht hingehört. Verräterisch ist der Pfad deiner eigenen Datei: HM485/HM485d/HM485_Protocol.pm liegt im HM485d, also im Daemon — nicht im LGW. Bei einer echten CCU steckt dieselbe Logik im hs485d.

Man muss drei Dinge trennen, die in der Protokollbeschreibung zusammen stehen:

1. ,,Bleibt die Antwort aus → bis zu 2× wiederholen" (EIFS).
Das ist End-zu-End-Retransmission und die macht der Master, nicht das Gateway. Das LGW ist nur ein Modem/Transceiver: Es nimmt ein S-Kommando von der CCU an, legt das eingebettete Busframe einmal auf den Bus und gibt die Geräteantwort als r zurück. Kommt keine Antwort, gibt es kein r — und der Master (bei dir FHEM/HM485_Protocol.pm, bei mir die CCU/hs485d) schickt das S erneut. Würde das Gateway zusätzlich selbst wiederholen, hättest du Doppel-Sends. Das deckt sich mit meinen Bus-Mitschnitten des Original-LGW: Auf der LAN-Seite gibt es ein S-Kommando mit Mode-Byte (0xC8 = Unicast+ACK / 0x00 = Broadcast), die CCU schickt genau ein S und erwartet genau ein r; wiederholt wird oben.

2. ,,Nach Empfang SIFS abwarten, dann ACK senden".
Das macht mein Gateway — es ist die einzige ACK-Ebene, die tatsächlich ins LGW gehört. In busAck() schicke ich nach jeder adressierten Geräteantwort ein len02-Null-Frame (Control-Basis 0x19 + txSeqNum) zurück, damit das Gerät aufhört, seine Antwort zu wiederholen. Das hatte ich anfangs vergessen — Folge: Geräte sendeten ihre Antwort 3× und gaben auf. Seit busAck drin ist, läuft die Interrogation sauber durch.

3. ,,Bus überwachen (Carrier Sense), DIFS-Idle, Backoff" (CSMA/CA).
Hier bin ich ehrlich: Mein ESP32-LGW macht vor dem Senden aktuell keinen expliziten Carrier-Sense — es sendet direkt. In meinem Python-Prototyp ist es drin (_wait_idle() = DIFS, plus send_acked() mit 3 Retries, Werte aus HBWired: DIFS ~210–310 ms, ACKWAITTIME 200 ms), aber das ist der Standalone-Master-Modus, wo Python die CCU komplett ersetzt. Im LGW-Betrieb trage ich das (noch) nicht nach, weil der Verkehr fast durchweg Frage→Antwort ist (strikt halb-duplex, das Gerät hat gerade keinen Sendegrund, wenn ich sende) und weil kollidierende spontane Events doppelt abgesichert sind: Das sendende Gerät macht selbst Carrier-Sense + 3 Retries, und der Master retryt Ende-zu-Ende. Eine einzelne verlorene Kollision wird also so oder so wiederholt. Das Original-LGW macht Carrier-Sense vermutlich in seiner Firmware; wenn du in deiner Umgebung (viele Sensoren/Taster = viel spontaner Verkehr) tatsächlich Kollisionen siehst, baue ich den _wait_idle()-Ansatz gern auch ins Gateway ein — es ist im Grunde: vor busSend() warten, bis der Bus X ms still war, plus kleiner Zufalls-Backoff.

Kurz: Ebene 1 (dein Fund) ist Absicht und liegt im Daemon, Ebene 2 ist drin (busAck), Ebene 3 ist eine bewusste Vereinfachung, die man bei Bedarf nachrüsten kann.

Ralf9

ZitatDas LGW ist nur ein Modem/Transceiver
Das ist dann aber kein Gateway sondern nur ein Netzwerk-RS485-Adapter ähnlich dem WIZ108SR.
Da passt es dann, es muss nicht auf eine Antwort gewartet und dann ggf die die Nachricht bis zu zwei mal wiederholt werden, das macht ja der HM485d.
Die FHEM Definition müsste ungefähr so aussehen:
define hm485 HM485_LAN localhost:2000
attr hm485 HM485d_device 192.168.0.x:1000

Bei einem richtigen Gateway wird der HM485d Daemon nicht benötigt.

 
FHEM auf Cubietruck mit Igor-Image, SSD und  hmland + HM-CFG-USB-2,  HMUARTLGW Lan,   HM-LC-Bl1PBU-FM, HM-CC-RT-DN, HM-SEC-SC-2, HM-MOD-Re-8, HM-MOD-Em-8
HM-Wired:  HMW_IO_12_FM, HMW_Sen_SC_12_DR, Selbstbau IO-Module HBW_IO_SW
Maple-SIGNALduino, WH3080,  Hideki, Id 7

maxx3105

Hallo Ralf,

Terminologisch hast du recht: Es ist ein LGW im Sinne von ,,LAN-Adapter für den RS485-Bus", kein autarker Controller. Die Ende-zu-Ende-Retransmission und die Geräte-/Session-Logik macht der Daemon — bei dir HM485d, bei einer CCU der hs485d. Deine FHEM-Definition ist auch der richtige Weg:

define hm485 HM485_LAN localhost:2000
attr hm485 HM485d_device <gateway-ip>:1000
Der Port 1000 passt: mein Gateway lauscht genau da, wie das Original-LGW. Das localhost:2000 ist ja die Strecke FHEM↔HM485d, die :1000 die Strecke HM485d↔Gateway — stimmt so.

Ein WIZ108SR ist es aber nicht ganz. Ein reiner Serial-über-TCP-Adapter reicht nur rohe Bytes durch. Mein Gateway (wie das eQ-3-Original) macht auf der Leitung selbst:

das HMW-Framing — Startbyte 0xFD, CRC16, 0xFC-Escaping (das eingebettete Busframe im LAN-Kommando kommt ohne 0xFD und ohne CRC an, die ergänzt das Gateway erst auf dem Bus),
das len02-Bus-ACK an die Geräte (damit die nicht selbst retransmittieren),
die Discovery-Binärsuche über den 32-Bit-Adressraum — auf ein einziges D-Kommando hin fährt das Gateway den kompletten Sweep autonom ab und meldet gefundene Geräte zurück; das mit seinem 12-ms-Antwortfenster könnte ein WIZ108SR nie leisten,
dazu die LAN-Session: Handshake, AES-128-CFB, Keepalive-Beantwortung (K→a).
Es deckt also Bitübertragung + Sicherung + die LAN-Session ab — nur die Anwendungsschicht (Retransmit-Policy, Geräteverwaltung, Config-Ablauf) liegt im Daemon. Ein ,,richtiges Gateway ohne HM485d" gäbe es erst, wenn man den hs485d/HM485d mit an Bord holt — dann wäre es faktisch eine Mini-CCU. Das ist bewusst nicht das Ziel; ich baue den LGW-Ersatz, damit CCU oder FHEM unverändert davorpassen. Übrigens meldet sich mein Gateway im Handshake als eQ3-HMW-LGW, 1.0.5 — für HM485d/hs485d ist es von einem echten LGW nicht zu unterscheiden.

AES: Mein Gateway hat AES per Default an (Key = MD5 deines Sicherheitsschlüssels). Wenn dein HM485d im Klartext spricht, im Gateway-Portal unter ,,AES" den Haken raus.
Ehrlich: Live verifiziert habe ich bisher nur gegen eine echte CCU (hs485d, AES an). Die Kombi FHEM/HM485d — und speziell der Klartext-Pfad — ist bei mir noch ungetestet.

Gruß Markus

Ralf9

Zitatdas HMW-Framing — Startbyte 0xFD, CRC16, 0xFC-Escaping (das eingebettete Busframe im LAN-Kommando kommt ohne 0xFD und ohne CRC an, die ergänzt das Gateway erst auf dem Bus),
das len02-Bus-ACK an die Geräte (damit die nicht selbst retransmittieren),
Keepalive-Beantwortung (K→a).
Dann muß es in FHEM ohne den HM485d definiert werden und es wird in FHEM ohne die Ende-zu-Ende-Retransmission nur mit Einschränkungen funktionieren.
define hm485 HM485_LAN <IP Adresse>:1000
https://wiki.fhem.de/wiki/HomeMatic_Wired_RS485_LAN_Gateway

Gruß Ralf
FHEM auf Cubietruck mit Igor-Image, SSD und  hmland + HM-CFG-USB-2,  HMUARTLGW Lan,   HM-LC-Bl1PBU-FM, HM-CC-RT-DN, HM-SEC-SC-2, HM-MOD-Re-8, HM-MOD-Em-8
HM-Wired:  HMW_IO_12_FM, HMW_Sen_SC_12_DR, Selbstbau IO-Module HBW_IO_SW
Maple-SIGNALduino, WH3080,  Hideki, Id 7

maxx3105

danke — Für das LAN-Gateway ist die direkte Anbindung define hm485 HM485_LAN <IP>:1000 der vorgesehene Weg, ohne hm485d.pl. Meine hm485d-Zwischenschaltung aus der letzten Mail war also falsch — der Daemon ist laut Wiki nur für die ,,dummen" Serial/USB-Adapter da, ,,da diese Adapter keine eigene 'Intelligenz' besitzen". Mein Gateway hat diese Intelligenz (Framing, Keepalive, AES, Discovery) an Bord, also direkt dran.

Bei einem Punkt sehe ich es anders. Die Ende-zu-Ende-Retransmission geht dabei nicht verloren. Im selben Artikel steht, dass das HM485_LAN-Modul die Protokoll-Logik selbst implementiert. Der Retransmit sitzt also im FHEM-Modul (im FHEM-Prozess), nicht im hm485d.pl. Der hm485d.pl ist nur der LGW-Emulator für dumme Adapter — er bildet Framing/Keepalive/AES nach, damit ein nackter USB-RS485-Adapter wie ein LGW aussieht. Die Wiederhol-Logik war da nie drin; die macht immer das Modul obendrauf.

Anders gesagt, die Rollenverteilung ist in beiden Welten identisch:

CCU: LGW (Transport) ↔ hs485d (Master + Retransmit)
FHEM + LAN-Gateway: mein Gateway (Transport) ↔ HM485_LAN-Modul (Master + Retransmit)
FHEM + USB-Adapter: Adapter (Bytes) ↔ hm485d.pl (LGW-Emulation) ↔ HM485_LAN-Modul (Master + Retransmit)
In allen drei Fällen macht die Ende-zu-Ende-Wiederholung dieselbe Stelle — der Master (hs485d bzw. das HM485_LAN-Modul). Mein Gateway ersetzt nur die Transport-Rolle ,,LGW". Es läuft also voll, nicht ,,mit Einschränkungen": FHEM direkt auf :1000, und das Modul retryt bei fehlender Antwort ganz normal.

Es wäre spannend zu sehen, ob mein Gateway die alten LGW-Probleme in FHEM umgeht. Wenn du magst, teste das gern — den kompletten Mitschnitt kannst du über die Weboberfläche mitlaufen lassen.
LG Markus

Ralf9

Ich hab mir mal den Code vom 00_HM485_LAN.pm angeschaut, ich konnte da nichts finden wo auf ein ack oder auf eine Antwort gewartet und dann ggf die Nachricht bis zu zwei mal wiederholt wird.

Der Retransmit ist in der HM485_Protocol.pm:
if ($self->{sendQueue}{$currentQueueId}{STATE} == STATE_WAIT_ACK ||
$self->{sendQueue}{$currentQueueId}{STATE} == STATE_WAIT_RESPONSE) {

# check if the item must resend after 100ms resend this queue item after 100 ms
$checkResendQueueItemsTimeout = main::setTimeout(
SEND_RETRY_TIMEOUT, 'checkResendQueueItems'
);
} else {
$queueRunning = 0;
$self->deleteCurrentItemFromQueue();
}

FHEM auf Cubietruck mit Igor-Image, SSD und  hmland + HM-CFG-USB-2,  HMUARTLGW Lan,   HM-LC-Bl1PBU-FM, HM-CC-RT-DN, HM-SEC-SC-2, HM-MOD-Re-8, HM-MOD-Em-8
HM-Wired:  HMW_IO_12_FM, HMW_Sen_SC_12_DR, Selbstbau IO-Module HBW_IO_SW
Maple-SIGNALduino, WH3080,  Hideki, Id 7