Ankündigung

Einklappen
Keine Ankündigung bisher.

Einbindung von Modbus TCP

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge
    Tom Bombadil
    KNX Anwender

  • Tom Bombadil
    antwortet
    Zitat von tsb2001 Beitrag anzeigen
    Universell ist es doch genau dann, wenn es doch alle Anforderungen abdeckt?!
    Das tut es doch, aber nicht dadurch, dass man für jedes neue Gerät jedesmal den Plugin-Code gerätespezifisch ändert (jemand muss die Spezialanpassungen implementieren, Pull-Request, jemand muss die Anpassungen validieren, ggf testen und mergen, dann knallt es nach dem nächsten Pull bei 20 Anwendern, wo es vorher sauber lief (weil die Spezialanpassungen für eine KWL sich plötzlich auch auf die Routinen für Wechselrichter auswirken) - Fehlerbehebung, neuer pull request, neues testen/mergen, die User müssen wieder pullen, etc pp).

    Übernimmst Du das alles?

    Lieber auslagern in yaml's, da kann jeder die Beispiele nach brauchbarem durchsuchen und ggf. für neue Geräte verändern - fertig ...

    /tom
    Tom Bombadil
    KNX Anwender
    Zuletzt geändert von Tom Bombadil; 17.01.2022, 00:27.

    Einen Kommentar schreiben:


  • tsb2001
    antwortet
    Zitat von Tom Bombadil Beitrag anzeigen
    Wenn ich es richtig verstanden habe, war es das Ziel, ein universelles Modbus-Plugin zu schreiben, das auch wartbar ist und pflegeleicht bleibt (das Ding heisst ja auch Modbus-Plugin und nicht Wechselrichter-Plugin).
    Hmm, aber wird es nicht genau dadurch zu einem universellen Modbus-TCP-Plugin?
    Universell ist es doch genau dann, wenn es doch alle Anforderungen abdeckt?!

    Einen Kommentar schreiben:

  • Tom Bombadil
    KNX Anwender

  • Tom Bombadil
    antwortet
    Zitat von tsb2001 Beitrag anzeigen
    Daher nochmal: der "sunssf" als zusätzliches Attribut tut keinem weh; hilft aber extrem dem Verständnis, wie man mit einfacher Multiplikation von Daten, die im Item-Baum schon aufgelöst als Dezimalzahl beispielsweise mit 0.001 erscheinen, sauber und simpel mit einer Multiplikation auf den passenden Wert kommt.
    Wenn ich es richtig verstanden habe, war es das Ziel, ein universelles Modbus-Plugin zu schreiben, das auch wartbar ist und pflegeleicht bleibt (das Ding heisst ja auch Modbus-Plugin und nicht Wechselrichter-Plugin).

    Ich sehe momentan nicht, wie mir ein Parameter "sunssf" helfen sollte, meine KWL oder meinen Heizungsregler anzuflanschen, die hier beide per Modbus ausgelesen werden.

    Statt dessen sehe ich sehr viel Sinn darin, eine oder mehrere Muster-yaml's mitzuliefern, die Spezifika für Geräte an Beispielen oder fertigen Implementierungen aufzeigen. So habe ich es in der Vergangenheit mit meinen eigenen Plugins gehalten, und das hat gut funktioniert. Sowas gehört einfach nicht in den Code (sagt jemand, der derartige Dinge beruflich jeden Tag für eine Vielzahl von Kunden mit unterschiedlichen Anforderungen 'in großem Stil' verwalten muss).

    Just my 2 cents ...

    /tom

    Einen Kommentar schreiben:


  • tsb2001
    antwortet
    Das Problem sehe ich woanders:
    Es gibt Anwender, versierte Anwender und Entwickler; folglich solche und solche.
    Aber auch der einfache "Anwender" soll ja auch hiermit etwas anfangen können.

    Mit "math.pow" als Funktion von Python und auch der "**" für die Auflösung des Exponenten ist jemand, der SmarthomeNG einfach nur nutzen möchte, schlichtweg überfordert.

    Mach mal einen Perspektivwechsel und versetze dich in die Situation:
    Du bist jemandem, der sich zum ersten Mal SmarthomeNG installiert, die Konfigurationsanleitung vom SmarthomeNG und deren Plugins durchliest, Items zusammenbaut und daraus versucht, sich sein Haus etwas "smarter" zu machen.

    "Python" hält er grundsätzlich erst mal für eine Schlange und hat gar keine Ahnung, was da im Hintergrund überhaupt passiert.

    Grundrechenarten mit plus, minus mal und geteilt beherrscht dieser in seinem grundlegenden Mathematikwissen und kann das auch in Items definieren. Das leuchtet ein und wird auch an sehr vielen Stellen erklärt.

    Nun findet derjenige auch dein Plugin und möchte seinen Wechselrichter über Modbus TCP anbinden. Das alleine gestaltet sich schon schwierig, die Register passend zu lesen und dann steht da tatsächlich in den Unterlagen des Wechselrichters, dass es einen Datentyp namens "sunssf" gibt.

    Genau dann steht dieser Anwender da, wo ich stand: Wie der Ochse vor dem Berg!
    Und nun muss er sich eine Lösung überlegen, wie er eine Zahl von -5 bis + 5 (oder auch höher) dahingehend umwandeln kann, dass es einen Faktor mit 0.irgendwas ergibt.

    Das mag aus Sicht eines Entwicklers simple Mathematik und Anwendung von einfachen Python-Befehlen sein, die er selbst hat und darüber lächelt, wenn es einer nicht umsetzen kann, weil die Grundkenntnisse fehlen und das Verständnis einfach nicht da ist.

    Der normal sterbliche Anwender scheitert aber an solchen einfachen Dingen.

    Der möchte beispielsweise "5682 * 0.0001" aus dem Item "Strom" multipliziert mit dem "Skalierungsfaktor" rechnen; das kennt der und kann das auch nachvollziehen.
    5682 als Strom und -4 als verschobener Dezimalpunkt bringt der aber einfach nicht zusammen.

    Guck dir doch mal den Verlauf dieses Postings an, wie Schusselig ich mich angestellt habe. Das betrifft aber die meisten Anwender die als "Otto-Normalverbraucher" versuchen, hier etwas schönes zu generieren. Und wenn das nicht klappt, schmeißen viele auch schnell die Flinte ins Korn und stöpseln alles wieder ab. Erst recht, wenn nicht die Möglichkeit besteht, jemanden direkt zu fragen. Dann entsteht schnell ein Frustlevel.

    Um das zu umgehen, muss man halt alles berücksichtigen; und nicht nur das, was einem selbst einfach erscheint.

    Daher nochmal: der "sunssf" als zusätzliches Attribut tut keinem weh; hilft aber extrem dem Verständnis, wie man mit einfacher Multiplikation von Daten, die im Item-Baum schon aufgelöst als Dezimalzahl beispielsweise mit 0.001 erscheinen, sauber und simpel mit einer Multiplikation auf den passenden Wert kommt.
    Das versteht jeder einfach gestrickte Anwender wie z.B. ich.

    Einen Kommentar schreiben:


  • ivande
    antwortet
    damit die Berechnung mittels sunssf Skalierungsfaktor (über eval) vielleicht weniger verwirrend erscheint, dürfte auch dies zum Ergebnis führen:

    Code:
    eval: value*math.pow(10, sh.PV_GEN_24.DCA_SF())
    Code:
    PV_GEN_24;
        DCA_SF:
           type: num
            modBusAddress: 40265
            modBusUnit: 1
            modBusDataType: int16
        A_DC_Bat:
            type: num
            enforce_updates: True
            eval: value*math.pow(10, sh.PV_GEN_24.DCA_SF())
            modBusAddress: 40322
            modBusUnit: 1
    Zuletzt geändert von ivande; 10.01.2022, 14:25.

    Einen Kommentar schreiben:


  • ivande
    antwortet
    Zitat von tsb2001 Beitrag anzeigen
    Nee, es gibt doch gar kein Hilfsitem.
    doch das DCA_SF - Item (eigentlich interessiert dieses doch niemandem) es wir ja nur zur Berechnung des eigentlichen Wertes A_DC_Bat benötig.

    ich sehe die SF alle als Hilfsitem (auch bei mir) weil mir diese Werte ja eigentlich nicht interessieren.
    Zuletzt geändert von ivande; 09.01.2022, 16:29.

    Einen Kommentar schreiben:


  • tsb2001
    antwortet
    Zitat von ivande Beitrag anzeigen
    und mit eingebautem sunsff muss ja immer noch mit Item und Hilfitem gerechnet werden..
    Nee, es gibt doch gar kein Hilfsitem.

    Beide Items braucht es doch sowieso. Du musst die generell den Skalierungsfaktor und den eigentlichen Wert abholen.
    Erst das zusammen ergibt die wirkliche Nutzdaten.
    Die Rechenfunktion erfolgt daher direkt in dem Wert-Item (grundsätzlich genau so wie bei dir):
    Code:
    ...
        DCA_SF:
            type: num
            value: '0'
            modBusAddress: 40265
            modBusUnit: '1'
            modBusDataType: 'sunssf'
    ...
        A_DC_Bat:
            type: num
            enforce_updates: True
            eval: value*sh.PV_GEN_24.DCA_SF()
            modBusAddress: 40322
            modBusUnit: '1'
            modBusDataType: 'uint16'
    Benötigt also auch kein Hilfsitem, sondern wird genau so verarbeitet wie in deinem Fall.
    Zuletzt geändert von tsb2001; 09.01.2022, 16:21.

    Einen Kommentar schreiben:


  • ivande
    antwortet
    Zitat von tsb2001 Beitrag anzeigen
    Aber jeder einfache Nutzer, der das Plugin "out of the Box" versucht einzusetzen, scheitert halt kläglich daran.
    dann sollte ich dies evtl. in die Plugin-Doku einbauen/erklären..
    Zumindest schon mal gut dass das wenige Tage alte Plugin schon ein paar Anwendungen gefunden hat.
    Gruß

    Einen Kommentar schreiben:


  • ivande
    antwortet
    Zitat von tsb2001 Beitrag anzeigen
    Was spricht denn dagegen
    prinzipiell nichts - da das modbus-Plugin universell bleiben sollte, sollten nur eingebaut werden, was es zur Funktion auch braucht.

    und mit eingebautem sunsff muss ja immer noch mit Item und Hilfitem gerechnet werden..

    Wichtig dass es nun läuft,.. Ich brauch auch manchmal mehrere Stunden/Tage bis ich eine (meist Kleinigkeit) peile oder sehe,..

    Einen Kommentar schreiben:


  • tsb2001
    antwortet
    Ja, du weißt das.

    Aber jeder einfache Nutzer, der das Plugin "out of the Box" versucht einzusetzen, scheitert halt kläglich daran.
    Und ohne deine und die Erklärung von Tom wäre ich auch nie darauf gekommen, weil ich mich grundsätzlich als "Einfacher Nutzer" bezeichne.

    Daher bekommst du hierbei nur Werte heraus, wenn du das Hintergrundwissen hast, wie Dezimalzahlen mit -5 bis +5 als Exponentialfunktion in Items zur Umrechnung in Zehnerpotenzen verwendet werden können. Das kann man aber bei keinem Normalsterblichen voraussetzen.

    Einen Kommentar schreiben:


  • ivande
    antwortet
    Modbus_TCP1.png

    Einen Kommentar schreiben:


  • tsb2001
    antwortet
    Zitat von ivande Beitrag anzeigen
    Wenn die Plugin's ein Update bekommen, musst du dann ständig Deine Änderungen in Plugin einbauen/korrigieren.
    Was spricht denn dagegen, den "sunsff" nicht mit in das Plugin zu schreiben; sprich meinen Testblock schlichtweg in deinen Code einzuarbeiten?
    Ist nur eine Variable im Item mehr zur Verwendung möglich, um sich damit das Leben einfacher zu machen. Wer das nicht benötigt, lässt es einfach weg.

    Wäre für alle klassischen "Anwender" (die sich wie ich zum Beispiel stundenlang den Kopf darüber zerbrochen hat, wie dieser blöde sunssf-Faktor mathematisch in einen Dezimalpunkt verwandeln lässt) doch viel simpler umzusetzen.

    Der integriert nur die Variable und macht im Item folgenden Schritt:
    Code:
        DCA_SF:
            type: num
            value: '0'
            modBusAddress: 40265
            modBusUnit: '1'
            modBusDataType: 'sunssf'
    
        A_DC_Bat:
            type: num
            enforce_updates: True
            eval: value*sh.PV_GEN_24.DCA_SF()
            modBusAddress: 40322 
            modBusUnit: '1'
            modBusDataType: 'uint16'
    Nichts mit Konvertierung von irgendwelcher Hochzahlen innerhalb eines Items (da wäre ich übrigens nie drauf gekommen, dass das über zwei * (**) hintereinander ausgelöst wird), sondern schlichtweg pure Multiplikation mit Werten, die das Plugin zurückliefert.

    Erklärt sich von selbst, lässt sich als Variable im Item-Baum und auch in dem Webinterface für jeden darstellbar nachvollziehen und kostet nix extra.

    Um darauf zu kommen, habe ich zwei Tage benötigt...

    Einen Kommentar schreiben:


  • ivande
    antwortet
    Zitat von tsb2001 Beitrag anzeigen
    Was ich jetzt nicht weiß: Beeinflusst die Anordnung der Items die Abfrage?
    ja so ist es, desswegen zuerst die SF's anlegen und darunter die Werte:

    die Berechnung würde ich nur in dem Items machen, ohne am Plugin Änderungen zu machen. Wenn die Plugin's ein Update bekommen, musst du dann ständig Deine Änderungen in Plugin einbauen/korrigieren.


    Du bräuchtest damit nur deine Items richtig anlegen: (die 10Potenz rechne ich ja im eval !)

    das doppelte Multiplikationszeichen im Eval bildet ja bereits die 10er Potenz,... Basis 10 und Hochzahl hole ich aus dem Item z.B. sh.PV_GEN24.DCV_SF
    eval: value*10**sh.PV_GEN24.DCV_SF()

    dies wird dann überflüssig:
    Zitat von tsb2001 Beitrag anzeigen
    float(math.pow(10, value.decode_16bit_int()))

    Code:
       PV_GEN24:    
        DCV_SF:
            type: num
            modBusAddress: 40266
            enforce_updates: True
            modBusUnit: 1
            modBusDataType: int16
        V_DC_1:
            type: num
            enforce_updates: True
            eval: value*10**sh.PV_GEN24.DCV_SF()    # Basis 10 und Hochzahl aus dem Item sh.PV_GEN24.DCV_SF
            modBusAddress: 40283
            modBusUnit: 1


    Einen Kommentar schreiben:

  • Tom Bombadil
    KNX Anwender

  • Tom Bombadil
    antwortet
    Zitat von ivande Beitrag anzeigen
    oder so im Scale-Factor-Item: (je nach dem wie die Daten ankommen)
    Code:
    eval: value - 32768 if value < 0 else value
    Ist natürlich richtig, wenn das Ding bereits signed Int ist. Das von mir oben verlinkte eval wertet den 'Rohwert' (=Buswert) aus - der kennt noch keine negativen Zahlen, sonden nur unsigned 16 Bit Int (siehe Link zur __init__.py des Trovis Plugins). Zu diesem Zeitpunkt kann man '<0' noch nicht auswerten ...

    /tom

    Einen Kommentar schreiben:


  • tsb2001
    antwortet
    Hallo Ivan,
    da ich das ganze Problem nun verstanden habe (vor allem habe ich mich mit dem blöden Zweierkomplement ablenken lassen (dabei ist das im int16 ja ohnehin verwurzelt) ), habe ich heute morgen herumexperimentiert.

    Die hohen Zahlen waren offensichtlich ein Eingabefehler bei den Registernummern. Das hat vermutlich zu den falschen Werten geführt.
    Hole ich das passende Register mit dem sunssf-Wert als int16 ab, kommt da tatsächlich ein Wertebereich von -10 bis +10 direkt heraus.

    Da das aber nur der Stellenwert der Verschiebung des Kommas ist und man damit nicht rechnen kann, habe ich etwas herumexperimentiert und versucht, dass in dein Programm einzubauen.
    Was habe ich gemacht:
    Ich habe eine neue Variable in den Items mit der Bezeichnung "sunssf" definiert

    Im __init__.py mache ich jetzt folgendes:
    ich importiere "math" in Zeile 27
    Code:
    import math
    Ab Zeile 267 habe ich folgendes eingefügt:
    Code:
    #Testblock
            elif dataType.lower() == 'sunssf':
                if bits == 16:
                     return float(math.pow(10, value.decode_16bit_int()))
                else:
                     self.logger.error("Number of bits or datatype not supportet : {0}".format(typeStr))
    #Ende Testblock
    Ich werte folglich aus, ob das Item die Variabel "sunssf" enthält und forme dann einen float-Wert mit dem Exponenten (definiert durch die dezimale Variable mit -10 bis +10) zur Basis 10 und gebe die zurück.

    Das Ergebnis ist ein Skalierungsfaktor zwischen 1000000000 und 0.0000000001, je nach übertragener Dezimalzahl. Damit kann man dann direkt in den Items rechnen und somit skalieren.

    Was ich jetzt nicht weiß: Beeinflusst die Anordnung der Items die Abfrage?
    Sprich, wenn der Skalierungsfaktor oberhalb der zu skalierenden Werte in den Items angeordnet ist, wird sich der auf das nachgeordnete Item sofort auswirken?

    Gruß Torsten

    Edit:
    Hier die Testitems dazu (die Skalierungswerte für Spannung, Strom und Leistung im gesamten DC-Bereich des Wechselrichters):
    Code:
        DCA_SF:
            type: num
            value: '0'
            modBusAddress: 40265
            modBusUnit: '1'
            modBusDataType: 'sunssf'
        DCV_SF:
            type: num
            value: '0'
            modBusAddress: 40266
            modBusUnit: '1'
            modBusDataType: 'sunssf'
        DCW_SF:
            type: num
            value: '0'
            modBusAddress: 40267
            modBusUnit: '1'
            modBusDataType: 'sunssf'
    Hier noch das Bild aus dem WebIF:
    Unbenannt.png
    Zuletzt geändert von tsb2001; 09.01.2022, 12:13.

    Einen Kommentar schreiben:

Lädt...
X