Neues Plugin: SMA 2 Loxone
Einklappen
X
-
Die Ursache dürfte irgendwo in deinem Netzwerk liegen. Ist das immer die gleiche Uhrzeit?🇺🇦 Hilfe für die Menschen der Ukraine: https://www.loxforum.com/forum/proje...Cr-die-ukraine
LoxBerry - Beyond the Limits
-
Ich scheine ein ähnliches Problem zu haben wie SAWbri. Ich habe einen Sunny Tripower 8.0 als Speedwireinv angeschlossen.
Alles funktioniert gut, aber fast jeden Morgen muss ich den Dienst im Plugin manuell neu starten.
Gibt es eine Möglichkeit, einen Neustart-Befehl von loxone an das Plugin zu senden?Kommentar
-
Leider kommt es immer noch zu Ausfällen. Betrifft zwischendurch allerdings auch die anderen zwei Wechselrichter.
Was ich bisher gemacht habe
- Feste IPs vergeben
- Überprüfung Online-Status über Ping-Baustein (alle drei Wechselrichter sind dauerhaft online)
Ich wollte nun gerne auch den Inhalt des Logs posten, aber dort steht heute nur das hier und keine weiteren Einträge:
Die letzte Wertänderung vom Wechselrichter kam um 10:30 Uhr.
Hat noch wer einen Tipp für mich woran es liegen könnte?Grüße
SAWKommentar
-
Hier noch ein paar Erkentnisse. Bei dem Wechselrichter handelt es sich um einen SMA Sunny Boy 2.5. Wir haben das Gerät gerade bekommen und nun wird es von SMA nicht mehr hergestellt. Generell scheint es mir etwas in die Jahre gekommen zu sein. Wir haben drei SMA Wechselrichter der Sunny Boy 2.5 ist der einzige, der kein https unterstützt. Generell reagiert die Weboberfäche außerdem sehr langsam, bleibt aber immer erreichbar.
Ich habe in SMA2MQTT daher natürlich den Haken bei SSL weggelassen. Jetzt habe ich aber in der Fehlermeldung folgendes entdeckt:
Warum gibt es da den Doppelpunkt hinter der IP und keinen Port?
Außerdem habe ich in einem anderen Forum noch Leute gefunden, die ein ähnliches Problem hatten, dort schien IGMP Snooping das Problem zu sein. Der nächste Schritt wäre daher, das überall zu deaktivieren, aber vorher möchte ich natürlich alles andere ausschließen.
Dort wurde auch der Hinweis gegeben, die Logs der Fritzbox zu checken, um eventuelle IMGP Fehlermeldungen zu finden. Dort habe ich dann gesehen, dass der EWE DNS-Server regelmäßig nicht erreichbar ist. Habe den nun gegen 8.8.8.8 bzw. 1.1.1.1 getauscht. Hatte ich wohl beim Einrichten vergessen.
Weitere Berichte folgen, Tipps bleiben gerne gesehenZuletzt geändert von SAWbri; 16.04.2025, 20:00.Grüße
SAWKommentar
-
Nachdem das Plugin über mehrere Wochen stabil gelaufen ist habe ich nun seit ein paar Tagen ebenfalls das Problem, dass die Verbindung zu meinem Sunny Tripower 10.0 täglich über Nacht abbricht. Lt. SMA Webseite wurde am 12.2.2025 ein Firmwareupdate veröffentlicht, leider kann ich nicht herausfinden wann sich mein Wechselrichter aktualisiert hat und ob es da einen Zusammenhang geben könnte.
Den Loglevel auf INFO oder DEBUG zu stellen führt dazu, dass sämtliche Parameterwerte geloggt werden - gibt es eine einfache Möglichkeit nur relevante Informationen zu sammeln um das Problem besser einzugrenzen?
Gibt es einen Grund warum das Plugin nach einem erfolglosen Verbindungsversuch einfach aufgibt und nicht weiter periodisch versucht sich neu zu verbinden?
Code:Traceback (most recent call last): File "/opt/loxberry/bin/plugins/sma2loxone/pysma2mqtt.py", line 248, in asyncio.run(main()) File "/usr/lib/python3.11/asyncio/runners.py", line 190, in run return runner.run(main) ^^^^^^^^^^^^^^^^ File "/usr/lib/python3.11/asyncio/runners.py", line 118, in run return self._loop.run_until_complete(task) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3.11/asyncio/base_events.py", line 653, in run_until_complete return future.result() ^^^^^^^^^^^^^^^ File "/opt/loxberry/bin/plugins/sma2loxone/pysma2mqtt.py", line 244, in main await main_loop(args) File "/opt/loxberry/bin/plugins/sma2loxone/pysma2mqtt.py", line 196, in main_loop await VAR["sma"].close_session() File "/usr/local/lib/python3.11/dist-packages/pysmaplus/device_webconnect.py", line 311, in close_session await self._post_json(URL_LOGOUT) File "/usr/local/lib/python3.11/dist-packages/pysmaplus/device_webconnect.py", line 206, in _post_json return await self._request_json(hdrs.METH_POST, url, **params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/local/lib/python3.11/dist-packages/pysmaplus/device_webconnect.py", line 171, in _request_json raise SmaConnectionException( pysmaplus.exceptions.SmaConnectionException: Could not connect to SMA at https://192.168.55.11: Cannot connect to host 192.168.55.11:443 ssl:default [Connect call failed ('192.168.55.11', 443)]
Kommentar
-
Zwischenfazit: "Leider" konnte ich seit dem letzten Loxberry-Neustart keinen Verbindungsabbruch mehr beobachten, mal sehen was das Wochenende bringt. -
Heute früh gab es wieder einen Verbindungsabbruch um 3:44
Ich habe das script nun etwas umgebaut und beobachte weiter...
-
Zwischenfazit #2: Kein Verbindungsabbruch, konnte daher die Änderungen am Skript noch nicht verifizieren.
-
-
Auch ich habe leider seit Wochen das Problem, dass die Verbindung abbricht - mal zu meinen Wecheslrichtern, mal zu zum Home Manager. Sehr unregelmäßig, mal sind es nur 24 Stunden, mal dauert es 3 Tage, bis es wieder passiert. Ich habe noch keine Idee woran es liegen könnte ...Kommentar
-
Ganz allgemein gesprochen liegt es in der Natur der Dinge, dass es Mal zu Verbindungsfehlern kommen kann. Ich versuche daher vorrangig herauszufinden warum sich das pysma2mqtt Script in solchen Fällen nicht ordentlich neu verbindet. Ursachenforschung folgt im Anschluss - da ich aber nicht weiss wie sich der Fehler provozieren lässt kann ich auch nur warten und beobachten. Die Verbindungsabbrüche waren bei mir bisher immer Nachts nach Mitternacht (zw. 0:00 und 3:00), aber nie zur selben Uhrzeit.
-
-
Also nach eurem Auzug oben entsteht der Fehler in unserem Skript in Zeile 248, 244 und 196. Das sind Library Calls. 248 ist die Hauptschleife ich denke der Fehler kommt in 244 oder 196 hoch. Man könnte hier probieren mit try: except: zu arbeiten.
Oder man wendet sich mal an den Autor der Library: https://github.com/littleyoda/ha-pysmaplus/issues🇺🇦 Hilfe für die Menschen der Ukraine: https://www.loxforum.com/forum/proje...Cr-die-ukraine
LoxBerry - Beyond the Limits
Kommentar
-
Das habe ich bereits gemacht, siehe Kommentar in Beitrag HOWTO: Wunderground-Wetterdaten nutz...r Wetterserver
Meine Vermutung ist, dass der Webserver im Wechselrichter periodisch "alte" Sessions aufräumt ohne darauf Rücksicht zu nehmen ob diese noch in Verwendung sind. In dem Fall müsste dann der gesamte Login-Handshake nochmal stattfinden um eine neue Session zu initialisieren. https://github.com/littleyoda/pysma/...onnect.py#L156 lässt darauf schließen, dass der Author schon ähnliche Erfahrungen gemacht hat. -
Der "HOWTO"-Link ist natürlich falsch und das Forum lässt kein bearbeiten zu ...
https://www.loxforum.com/forum/proje...285#post460285 -
Prof.Mobilux ich habe dir einen Pull-Request gestellt:
-
-
haraldradi, danke für deinen Einsatz. Ich wollte den Fehler auch noch besser verstehen und habe mir jetzt mit deinen Hinweisen und ChatGPT eine neue pysma2mqtt.py gebaut mit der es problemlos zu laufen scheint.
Wenn ich die Änderungen richtig verstehe, wird der TCP-Socket nun nach jeder Abfrage geschlossen. Falls es trotzdem zu einem Fehler kommt, wird alle 5 Sekunden ein neuer Verbindungsversuch gestartet. Die ersten paar Minuten gab es noch etwas Schluckauf (vllt. wegen alter Sockets?) aber seitdem habe ich keine Fehlermeldungen mehr bekommen. Siehe Code unten und Datei im Anhang.
Code:#!/usr/bin/env python """Export SMA‑WebConnect Werte per MQTT. Änderungen 2025‑05‑04 --------------------- * **force_close=True** für den aiohttp‑Connector – jeder Zyklus hat einen frischen TCP‑Socket → keine Zombie‑Verbindungen mehr. * Fallback‑Re‑Login innerhalb des Poll‑Loops wenn `asyncio.TimeoutError` **oder** `pysmaplus.exceptions.SmaConnectionException` auftreten. * Äußere `reconnect_loop()` fängt alle übrigen Fehler ab und startet nach `RETRY_WAIT` Sekunden neu. * Kompatibel ab Python 3.7 durch `from __future__ import annotations` und sauberes `strip()` aller `os.popen`‑Rückgaben (keine störenden Newlines). """ from __future__ import annotations # Postponed eval of type hints → Py ≥ 3.7 import argparse import asyncio import logging import queue import signal import sys from typing import Any, Dict, List from urllib.parse import urlparse import json import os import aiohttp from aiomqtt import Client, ProtocolVersion import pysmaplus as pysma from pysmaplus.sensor import Sensors from pysmaplus import exceptions as sma_exc # --------------------------------------------------------------------------- # # Globale Variablen & Konstanten # --------------------------------------------------------------------------- # VAR: Dict[str, Any] = {} log_queue: queue.Queue = queue.Queue() deviceindex: int | str = "" pconfig: Dict[str, Any] = {} mqttconfig: Dict[str, str] = {} # Retry‑Wartezeit in Sekunden nach einem kompletten Verbindungsabbruch RETRY_WAIT = 5 # Pfade aus LoxBerry‑Umgebung (Newlines entfernen!) lbpconfigdir = os.popen("perl -e 'use LoxBerry::System; print $lbpconfigdir; exit;' ").read().strip() lbpdatadir = os.popen("perl -e 'use LoxBerry::System; print $lbpdatadir; exit;' ").read().strip() lbplogdir = os.popen("perl -e 'use LoxBerry::System; print $lbplogdir; exit;' ").read().strip() # --------------------------------------------------------------------------- # # Hilfsfunktionen # --------------------------------------------------------------------------- # def readconfig(device: str) -> None: """Konfiguration aus plugin.json + MQTT‑Datenbank lesen.""" global pconfig, deviceindex, mqttconfig try: with open(os.path.join(lbpconfigdir, "plugin.json")) as fp: pconfig = json.load(fp) for idx, itm in enumerate(pconfig.get("devices", [])): if str(device) == str(itm.get("name")): deviceindex = idx break else: raise KeyError(f"Device {device!r} nicht in plugin.json gefunden") # Delay prüfen (mind. 2 s) delay_val = float(pconfig.get("delay", 10)) if delay_val < 2: logging.warning("Delay < 2 s – setze auf 2 s.") pconfig["delay"] = 2 # Topic‑Name vorbelegen pconfig.setdefault("topic", "sma2mqtt") # MQTT‑Zugänge aus Perl‑Helper (alle .strip()) def _perl(cmd: str) -> str: return os.popen(cmd).read().strip() mqttconfig.update({ "hostname": _perl("perl -e 'use LoxBerry::IO; my $m=LoxBerry::IO::mqtt_connectiondetails(); print $m->{brokerhost};'"), "port": _perl("perl -e 'use LoxBerry::IO; my $m=LoxBerry::IO::mqtt_connectiondetails(); print $m->{brokerport};'"), "username": _perl("perl -e 'use LoxBerry::IO; my $m=LoxBerry::IO::mqtt_connectiondetails(); print $m->{brokeruser};'"), "password": _perl("perl -e 'use LoxBerry::IO; my $m=LoxBerry::IO::mqtt_connectiondetails(); print $m->{brokerpass};'"), }) if not mqttconfig["hostname"] or not mqttconfig["port"]: raise ValueError("Fehlende MQTT‑Broker‑Daten") except Exception: logging.exception("Konfigurationsfehler – Plugin stoppt") sys.exit(1) def getVersion() -> str: from importlib.metadata import PackageNotFoundError, version try: return version("pysma-plus") except PackageNotFoundError: return "unknown" def print_table(sensors: Sensors) -> None: for sen in sensors: name = sen.name or sen.key or "—" logging.debug(f"{name:<30} {str(sen.value):>12} {sen.unit or ''}") # --------------------------------------------------------------------------- # # Haupt‑Poll‑Loop (ein Device) # --------------------------------------------------------------------------- # async def poll_device(session: aiohttp.ClientSession, item: Dict[str, Any]) -> None: user = str(item.get("username", "")) password = str(item.get("password", "")) accessmethod = str(item.get("type", "")) url = str(item.get("address", "")) url = ("https://" if item.get("ssl") == "1" else "http://") + url delay = float(pconfig["delay"]) logging.debug("Starte Poll‑Loop für %s", url) sma_dev = pysma.getDevice(session, url, password, user, accessmethod) await sma_dev.new_session() devicelist = await sma_dev.device_list() sensors: Dict[str, Sensors] = { dev_id: await sma_dev.get_sensors(dev_id) for dev_id in devicelist } for senlist in sensors.values(): for s in senlist: s.enabled = True logging.info("Verbunden – exportiere Werte via MQTT") async with Client( mqttconfig["hostname"], port=int(mqttconfig["port"]), username=mqttconfig["username"], password=mqttconfig["password"], protocol=ProtocolVersion.V31, timeout=10, ) as mqtt: while VAR.get("running", True): for dev_id in devicelist: try: await sma_dev.read(sensors[dev_id], dev_id) topic_prefix = f"{pconfig['topic']}/{item['name']}" for sen in sensors[dev_id]: name = sen.name or sen.key if not name: continue await mqtt.publish(f"{topic_prefix}/{name}", payload=str(sen.value)) print_table(sensors[dev_id]) except (asyncio.TimeoutError, sma_exc.SmaConnectionException) as err: logging.warning("Sessionfehler %s – versuche Re‑Login", err) try: await sma_dev.close_session() await sma_dev.new_session() logging.info("Re‑Login erfolgreich") except Exception as relog_err: logging.error("Re‑Login fehlgeschlagen: %s", relog_err) raise # bricht ab → reconnect_loop await asyncio.sleep(delay) # --------------------------------------------------------------------------- # # Reconnect‑Hülle – fängt alle Fehler ab # --------------------------------------------------------------------------- # async def reconnect_loop() -> None: item = pconfig["devices"][deviceindex] dev_desc = item.get("name") while VAR.get("running", True): async with aiohttp.ClientSession( connector=aiohttp.TCPConnector(ssl=False, force_close=True) ) as session: try: await poll_device(session, item) except sma_exc.SmaAuthenticationException: logging.critical("Login‑Daten für %s falsch – Plugin stoppt", dev_desc) raise except Exception as ex: logging.error("Poll‑Loop für %s abgebrochen: %s – Neustart in %s s", dev_desc, ex, RETRY_WAIT) await asyncio.sleep(RETRY_WAIT) # --------------------------------------------------------------------------- # # CLI‑Einstieg # --------------------------------------------------------------------------- # async def main() -> None: parser = argparse.ArgumentParser(description="Exportiere SMA‑Daten als MQTT") parser.add_argument("--device", "-d", required=True, help="Gerätename in der plugin.json") parser.add_argument("--loglevel", "-l", default="INFO", help="Loglevel (DEBUG, INFO, …)") args = parser.parse_args() # Logging logging.basicConfig( level=getattr(logging, args.loglevel.upper(), logging.INFO), format="%(asctime)s <%(levelname)s> %(message)s", datefmt="%H:%M:%S", ) readconfig(args.device) VAR["running"] = True signal.signal(signal.SIGINT, lambda *_: VAR.update({"running": False})) logging.info("pysma‑plus Version %s", getVersion()) logging.info("Starte Poll‑Dienst für %s mit Delay %ss", args.device, pconfig["delay"]) await reconnect_loop() if __name__ == "__main__": asyncio.run(main())
Angehängte DateienGrüße
SAWKommentar
-
Im groben und ganzen sieht das ähnlich aus wie meine Änderung von letzter Woche (siehe Github-Link weiter oben). Deine ChatGPT-Variante umgeht aber die pysma-Library und baut sich eine eigene ClientSession - ich kann mir beim besten Willen nicht vorstellen, dass das zielführend ist.
Ich warte immernoch auf einen Verbindungsabbruch um zu verifizieren dass ein Reconnect nun klappt. Meine Verbindung steht nun aber seit einer Woche stabil - an sich gut, aber halt nicht wenn man den Fehlerfall testen will
-
-
Heute nacht gab es "endlich" wieder einen Verbindungsausfall und wie erhofft wurde die Verbindung neu aufgebaut:
Code:23:27:16.921 ERROR: Unknown error occured in MainLoop: Could not connect to SMA at https://tripower.***.**: Cannot connect to host tripower.***.**:443 ssl:default [Connect call failed ('192.168.55.11', 443)] 23:27:26.975 CRITICAL: Unable to connect to device at https://tripower.***.** 23:27:37.338 CRITICAL: Unable to connect to device at https://tripower.***.** 23:27:47.357 CRITICAL: Unable to connect to device at https://tripower.***.** 23:27:57.380 CRITICAL: Unable to connect to device at https://tripower.***.** 23:28:07.403 CRITICAL: Unable to connect to device at https://tripower.***.** 23:28:17.427 CRITICAL: Unable to connect to device at https://tripower.***.** 23:28:27.444 CRITICAL: Unable to connect to device at https://tripower.***.** 23:28:53.056 CRITICAL: Unable to connect to device at https://tripower.***.** 23:29:17.325 CRITICAL: Unable to connect to device at https://tripower.***.** 23:29:30.413 CRITICAL: Unable to connect to device at https://tripower.***.** 23:29:43.502 CRITICAL: Unable to connect to device at https://tripower.***.**
👍 1Kommentar
-
Hey Leute, ich habe mal zu dem SMA Setup eine Anfänger-Frage.
Ich habe einen Tripower 8kw und einen HomeManger2 sowie eine Wallbox und die Daten von den beiden kommen auch bei mir in MQTT an. (siehe Bild)
Ich hab jetzt Stromzähler für den PV Überschuss und die Wallbox erstellt, aber ich checke einfach nicht, wie ich den aktuellen Gesamt-Verbrauch vom Haus darstelle.
Könnt ihr mir mal mit der Zuordnung der Werte helfen?
metering_power_absorbed ist glaube der aktuelle (Netz-) Verbrauch, da ich gerade Strom Einspeise, ist der natürlich 0. metering_power_supplied ist denke ich die aktuelle PV Einspeisung. Was mir fehlt, ist der aktuelle Verbrauch oder der aktuelle Gesamt-Ertrag (nicht nur der Überschuss).
Bitte helft mir mal auf die Sprünge, vielen Dank!
Kommentar
-
Zähler-Zählpunkt (Baustein Zähler-Bidirektional):
Pf: metering_power_absorbed - metering_power_supplied
Mrc: metering_total_absorbed
Mrd: metering_total_yield
Zähler-Batterie (Baustein Zähler-für-Speicher):
Pf: battery_power_discharge_total - battery_power_charge_total
Mrc: battery_discharge_total
Mrd: battery_charge_total
Zähler-PV (Baustein Zähler):
Pf: pv_power
Mr: total_yield
Zähler-Haushalt/Verbrauch (Baustein Zähler):
Pf: grid_power + Pf_Zählpunkt (Eigenverbrauch setzt sich aus der Wechselrichterproduktion und dem momentanen Netzbezug, bei Einspeisung ein negativer Wert, zusammen)
Mr: Mrc_Zählpunkt + Mrd_Batterie + Mr_PV - Mrd_Zählpunkt - Mrc_Batterie -
Ggf. musst du Verbrauch und Zählerstand der Wallbox auch noch von Pf und Mr des Zähler-Haushalt abziehen, dann kannst du die Wallbox "daneben" statt "darunter" visualisieren -
Und beim Zähler-Haushalt empfielt es sich die Einstellung "Ungültigen Zählerstand melden" zu deaktivieren. Nachdem die Werte nicht gemessen, sondern nur berechnet sind, können sie nicht originär ungültig sein - allerdings liegen die Zählerstände mitunter nicht zeitgleich aktualisiert vor sodass es für 1-2 Miniserver-Zyklen zu unplausiblen Kombinationen kommen kann.
-
-
haraldradi Danke für Dein Feedback und den PullRequest. Er ist als Pre-Reöease jetzt verfügbar (von mir ungetestet): https://wiki.loxberry.de/plugins/sma2loxone/start🇺🇦 Hilfe für die Menschen der Ukraine: https://www.loxforum.com/forum/proje...Cr-die-ukraine
LoxBerry - Beyond the Limits
👍 1Kommentar
-
Hallo Prof.Mobilux,
beim SMA HomeManager ist mit dem Update 2.16.4.R ua die "Optimierung des Sunny Home Manager Modbus-Server: Verwendung ohne notwendigen Grid Guard Code (GGC) möglich".
Wenn ich aktuell den SMA Homemanger in SMA2Loxone ohne GGC einbinde (ich habe keinen GGC), bekomme ich keine Werte angezeigt.
Wäre bei einem Programm-Seitigen Verzicht des GGC ggf. auch hier ein Auslesen und ggf. auch Ansteuern des SMAHomemanger möglich?
Grüße und Danke für die super Arbeit!Kommentar
-
Sorry, späte Antwort. Du könntest es noch einmal probieren - die Funktion wurde schon vor längerer Zeit in der von mir verwendeten Library eingebaut: https://github.com/littleyoda/pysma/...c7f940c736a031
-
-
Ich konnte meinen Fehler inzwischen beheben. Es gab tatsächlich zwei Probleme im Netzwerk, die alles verursacht haben.
Nun bleibt aber noch ein Problem. Gelegentlich gehen alle metering Werte meines Wechselrichters offline. Er liefert weiterhin alle anderen Werte. Kennt jemand das Problem?
1 BildGrüße
SAWKommentar
-
Noch ein weiterer Punkt. Seit kurzem tritt beim Sunny Home Manager 2.0 (energymeter) folgendes auf:
Code:19:05:04.334 [COLOR=red][B]ERROR:[/B][/COLOR] Unknown Accessmethod: energymeter 19:05:04.335 [COLOR=red][B]ERROR:[/B][/COLOR] Unknown error occured in MainLoop:
Grüße
SAWKommentar
Kommentar