SMA-Multicast aus anderem VLAN zu openHAB umleiten

openHAB läuft im Host-Netz (z. B. 192.168.50.0/24, Interface eth0). Der SMA Home Manager sendet via Speedwire (Multicast 239.12.255.254:9522) im zugeordneten VLAN 70. Wir pinnen die Multicast-Route so, dass der IGMP-Join für 239.12.255.254 über eth0.70 erfolgt – openHAB muss sein Default-Interface nicht ändern.
Voraussetzungen
- Switch/UniFi: Der Port des RasPi ist als Trunk konfiguriert (Native/Default VLAN = euer „Default“-Netz, VLAN 70 als „Allowed/Tagged“).
- Raspberry Pi OS Bookworm (Standard: NetworkManager).
- openHAB läuft im host-Netzwerk (Docker `--network host` oder nativ).
- Optional, aber empfohlen: Java/OpenJDK nutzt IPv4-Stack.
Schritt 1: VLAN 70 auf dem RasPi mit fester IP (ohne Gateway)
# VLAN-Interface anlegen (ID 70 auf eth0), statische IP, kein GW
nmcli connection add type vlan con-name vlan70 dev eth0 id 70 ip4 192.168.70.100/24
# Verbindung aktivieren
nmcli connection up eth0.70
# Kontrolle
ip -d link show eth0.70
ip a show dev eth0.70
Schritt 2: Multicast-Route auf eth0.70 pinnen
Variante A (empfohlen): persistent im NetworkManager-Profil
# Route zur Gruppe im VLAN-70-Profil hinterlegen und aktivieren
nmcli con modify vlan70 +ipv4.routes "239.12.255.254/32"
nmcli con up vlan70
Variante B: systemd One-Shot (falls NM-Route nicht greift)
tee /etc/systemd/system/mcast-route-239.service >/dev/null <<'SERVICE'
[Unit]
Description=Pin multicast route 239.12.255.254 to eth0.70
Wants=network-online.target
After=network-online.target
[Service]
Type=oneshot
ExecStart=/sbin/ip route replace 239.12.255.254/32 dev eth0.70
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
SERVICE
sudo systemctl daemon-reload
sudo systemctl enable --now mcast-route-239.service
Ad-hoc (sofort, nicht persistent)
ip route replace 239.12.255.254/32 dev eth0.70
Schritt 3: openHAB (Docker) auf IPv4 trimmen & neu starten
# optional: in docker-compose für den openHAB-Service environment: - EXTRA_JAVA_OPTS=-Djava.net.preferIPv4Stack=true network_mode: host # neu starten cd /opt/openhab docker compose restart openhab
Verifikation
# Route muss auf eth0.70 zeigen
ip route get 239.12.255.254
# IGMP-Join: Gruppe soll auf eth0.70 erscheinen (und NICHT mehr auf eth0)
ip maddr show dev eth0.70 | grep 239.12.255.254 || echo "kein Join auf eth0.70"
ip maddr show dev eth0 | grep 239.12.255.254 || echo "kein Join auf eth0"
# Pakete sichtbar?
tcpdump -ni eth0.70 src 192.168.70.10 and dst 239.12.255.254 and port 9522 -c 5
# openHAB lauscht per IPv4?
ss -ulnp -4 | grep ':9522'
Troubleshooting
- Route zeigt falsch:
ip route get 239.12.255.254muss deveth0.70ausgeben. - Join auf falschem Interface: openHAB neu starten, danach prüfen:
ip maddr show dev eth0.70 | grep 239.12.255.254
- Pakete kommen an, aber openHAB parst nicht: Binding „SMA Energy Meter“ installiert, Thing mit richtiger Seriennummer anlegen; Java auf IPv4 (siehe Schritt 3).
- Multicast-Forwarder aktiv: igmpproxy/smcroute werden für diese Lösung nicht benötigt – ggf. deaktivieren:
systemctl disable --now igmpproxy smcroute
Zusammenfassung
- VLAN 70 per NetworkManager anlegen (statisch, ohne Gateway).
- Multicast-Route 239.12.255.254/32 → eth0.70 persistent setzen.
- openHAB neu starten → der IGMP-Join passiert jetzt auf eth0.70 und die Pakete landen zuverlässig am openHAB-Socket auf eth0 (Host-Netz bleibt unverändert).
Optional: LLDP für korrekte UniFi-Topologie
Da der Raspberry Pi dieselbe MAC-Adresse in zwei VLANs (Default/Native + VLAN 70) nutzt, verwirrt das den UniFi-Controller: der Pi erscheint dann häufig am Gateway statt am tatsächlichen Switch-Port. Mit LLDP meldet sich der Pi aktiv beim Switch als Nachbar an und wird in der UniFi-Topologie korrekt am richtigen Port dargestellt.
Installation
sudo apt install lldpd
sudo systemctl enable --now lldpd
Konfiguration
Standardmäßig verwendet lldpd das erste Interface (alphabetisch, also eth0) als Chassis-ID und wirbt auf allen UP-Interfaces. Damit der Pi mit der MAC des tatsächlich genutzten Interfaces erscheint, wird lldpd gezielt auf dieses Interface beschränkt und die Chassis-ID explizit gesetzt (hier eth1 – bei Onboard-NIC entsprechend eth0 verwenden):
# MAC-Adresse von eth1 ermitteln
cat /sys/class/net/eth1/address
Die ausgegebene MAC wird in der folgenden Konfiguration als Chassis-ID eingetragen:
tee /etc/lldpd.d/eth1-only.conf >/dev/null <<'EOF'
configure system interface pattern eth1
configure system chassisid d8:3a:dd:e2:b4:ee
configure lldp portidsubtype ifname
EOF
sudo systemctl restart lldpd
- configure system interface pattern eth1 – lldpd sendet/empfängt ausschließlich auf eth1.
- configure system chassisid <MAC> – erzwingt die MAC von eth1 als Chassis-ID (ohne diese Zeile wird weiterhin die MAC von eth0 beworben, auch wenn lldpd nur auf eth1 läuft).
- configure lldp portidsubtype ifname – Port wird als Interface-Name (z. B. eth1) statt als MAC beworben.
Verifikation
# Chassis-ID und aktive Interfaces prüfen
lldpcli show chassis
lldpcli show interfaces
# Nachbarn (Switch) anzeigen
lldpcli show neighbors
Die Ausgabe von lldpcli show chassis muss die MAC-Adresse von eth1 als ChassisID zeigen.
Anschließend im UniFi-Controller unter Client Devices den RasPi einmal „Forget Client" und neu verbinden – er sollte nun mit der MAC von eth1 am korrekten Switch-Port in der Topologie erscheinen.