Mehrere Messwerte auf einem Topic auseinanderhalten

Der go-eCharger schickt sechzehn Zahlen als JSON-Feld auf einem einzigen
Topic, die Wechselrichter und die WLAN-Felder machen es aehnlich. Welcher
Teil der Nutzlast gemeint ist, steht im value_template der
Home-Assistant-Discovery - das Modul las es bisher nur, um den Datentyp zu
raten, und warf es dann weg. Alle sechzehn Messwerte bekamen denselben
Rohtext.

actor_states hat jetzt eine Spalte value_path: ein Pfad in die Nutzlast, in
derselben Schreibweise, die WLED schon benutzt ("[4]", "ssid",
"seg[0].col[0]"). NULL heisst weiterhin: die ganze Nutzlast.

Gelesen wird aus dem Template nur der einfache Fall - ein Zugriff auf
value_json und was danach an Punkten und Klammern folgt. Von den 40
Vorlagen, die hier auf dem Broker liegen, sind 28 genau das. Die uebrigen
zwoelf sind entweder die ganze Nutzlast (dann ist NULL richtig) oder
Werttabellen wie ['Idle','Charging'][value_json|int] - das ist kein Pfad,
sondern eine Uebersetzung von Zahl nach Text, und dort bleibt es beim
bisherigen Verhalten. Kein einziger Fehltreffer: die Werttabellen liefern
sauber None statt eines erfundenen Pfades.

Die Pfad-Auswertung stand schon im WLED-Transport; sie ist jetzt eine
gemeinsame Funktion, die sich beide teilen. MQTT wertet die Nutzlast einmal
je Nachricht aus und verteilt sie danach an alle Messwerte des Topics.

Nachgemessen: die sechzehn nrg-Werte liefern jetzt sechzehn eigene Zahlen
statt sechzehnmal dasselbe, die Leseabdeckung bleibt bei 440 von 441, und
ein weiterer Discovery-Lauf aendert keine Zeile.

Die restlichen geteilten Topics sind kein Fehler: bei den Wechselrichtern
lesen "Limit Persistent" und "Limit NonPersistent" wirklich denselben Wert
und unterscheiden sich nur im Kommando-Topic, und beim Thermostat liest die
Klima-Entity dieselbe Temperatur wie der Sensor.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-31 15:23:08 +02:00
co-authored by Claude Opus 5
parent 631baa7333
commit 56b2ab1648
6 changed files with 140 additions and 45 deletions
@@ -6,6 +6,7 @@ Erweitert das Tahoma Script um MQTT-Geräte via Home Assistant Discovery
import paho.mqtt.client as mqtt
import json
import re
import time
from typing import Dict, List, Optional
import logging
@@ -506,6 +507,48 @@ class MQTTDeviceConverter:
return command_entry
@staticmethod
def _value_path(config: Dict) -> Optional[str]:
"""
Liest aus dem value_template heraus, welcher Teil der Nutzlast gemeint
ist.
Mehrere Messwerte teilen sich oft ein Topic: der go-eCharger schickt
sechzehn Zahlen als JSON-Feld auf "nrg", und erst das value_template
sagt, dass "Strom L1" das vierte Element ist. Ohne diese Angabe
bekaemen alle sechzehn denselben Rohtext.
Zurueck kommt ein Pfad in derselben Schreibweise, die auch WLED
benutzt: "[3]", "ssid", "foo[0].bar". None heisst: die ganze Nutzlast.
Home Assistant erlaubt in value_template beliebiges Jinja. Hier wird
nur der einfache Fall gelesen - ein Zugriff auf value_json und was
danach an Punkten und Klammern folgt. Bei allem anderen (Werttabellen
wie ['Idle','Charging'][value_json|int], Bedingungen) bleibt es beim
Rohtext, also beim bisherigen Verhalten.
"""
vorlage = config.get('value_template') or config.get('val_tpl')
if not vorlage:
return None
treffer = re.search(
r"value_json((?:\s*(?:\.\w+|\[\s*'[^']*'\s*\]|\[\s*\"[^\"]*\"\s*\]|\[\s*\d+\s*\]))*)",
vorlage)
if not treffer or not treffer.group(1).strip():
return None
teile = []
for stueck in re.finditer(
r"\.(\w+)|\[\s*'([^']*)'\s*\]|\[\s*\"([^\"]*)\"\s*\]|\[\s*(\d+)\s*\]",
treffer.group(1)):
name = stueck.group(1) or stueck.group(2) or stueck.group(3)
teile.append(name if name else "[%s]" % stueck.group(4))
if not teile:
return None
# "[3]" haengt sich ohne Punkt an, Namen mit Punkt.
pfad = ""
for teil in teile:
pfad += teil if teil.startswith("[") else (("." + teil) if pfad else teil)
return pfad[:120]
@staticmethod
def _entity_to_states(component: str, object_id: str, config: Dict) -> List[Dict]:
"""
@@ -539,7 +582,8 @@ class MQTTDeviceConverter:
state_entry = {
'name': object_id,
'type': 'string',
'url': state_topic
'url': state_topic,
'value_path': MQTTDeviceConverter._value_path(config)
}
# Unit hinzufügen - verschiedene mögliche Feldnamen