Ankündigung

Einklappen
Keine Ankündigung bisher.

Open-Source Mitstreiter vor allem mit KNX-Wissen gesucht ...

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

    Open-Source Mitstreiter vor allem mit KNX-Wissen gesucht ...

    Hallo allerseits,

    ich habe hier gelegentlich mal fragen gestellt, weil ich aktiv am KNX Treiber für das Apache PLC4X (https://plc4x.apache.org) Projekt arbeite. Generell läuft der normale KNX support bei uns schon ziemlich gut (in Java und in Go). Momentan arbeite ich mit dem Rest der Community an dem Thema Auto-Discovery (Welche Geräte habe ich?) und Browsing (Welche Datenpunkte hat ein Gerät?). Hier bin ich vor allem beim Go Treiber bei KNX sehr gut voran gekommen.

    Der Java-Treiber benötigt momentan noch ein knxproj-File, beim Go Treiber sind wir aber dabei alles so zu machen, dass es komplett ohne auskommen soll. Sowie das dann in Go geht, soll auch der Java (und alle anderen Treiber) davon profitieren.

    Hier finden wir jetzt schon KNX Gateways automatisch und können uns verbinden. Auch kann ich automatisch KNX Geräte auf meinem Bus finden, die konfigurierten Gruppenadressen und deren Attribute auslesen (Lesen, Schreiben, Übertragen, Com-Objekt Basis-Typen). Hier eine kleine Demo: https://www.youtube.com/watch?v=Q5LGdAD_6Es

    Leider gibt es immer wieder Edge-Cases, bei denen etwas nicht so 100% funktioniert. Daher wären wir sehr dankbar für Freiwillige, die hier ein wenig mit helfen könnten. Das muss auch nicht Hilfe in form von Programmierung sein, sondern vor allem Hilfe im Verständnis des KNX Protokolls. Ich denke es würden indirekt viele andere (Open-Source) Projekte davon profitieren, wenn wir das wirklich solide hin bekommen.

    Momentan arbeite ich daran die genauen Datentypen der Com-Objects zu berechnen. Hierzu muss ich allerdings die Konfiguration des Geräts kennen. Da die Parameter ja ihre daten aus den Code Blocks bekommen, war meine Idee: Die benötigten Speicherbereiche auszulesen und dann auf Basis dessen zu rekonstruieren, wie das Gerät genau konfiguriert ist und welche genauen Datentypen die Com-Objects haben.

    Würde mich sehr freuen,
    Chris

    #2
    Hi 👋! Das is ja ne coole Sache!
    Darf ich fragen wie du die Com-Objekt Basis-Typen extrahierst? Das wäre für unser Projekt xknx vielleicht auch ganz intetessant.

    Kommentar


      #3
      Hi meti,

      Ich glaube ihr und wir sollten mal etwas mehr zusammen arbeiten ... unsere Community arbeitet gerade auch an PLC4Py, was unsere Treiber in Python verfügbar machen wird. Allerdings hat PLC4X ja nicht den Anspruch ein vollwertiger Treiber für das jeweilige Protokoll zu sein, sondern die wichtigsten Operationen über alle Protokolle so einfach wie möglich verfügbar zu machen. Zumindest könntet ihr mit plc4py schon mal alle Messages und Typen, Parser, Serializer generiert bekommen und wir haben auch eine automatisierte Testsuite, die unsere Treiber cross-language testet. Aber das interessiert euch vermutlich nur, wenn ihr noch nicht alle implementiert habt.

      Zu deiner Frage:
      https://github.com/apache/plc4x/blob...Browser.go#L45
      Also ich hole mir zuerst die Adresse der GroupAddressTable, dann die Anzahl der Tabellen-Einträgen dann lese ich die Einträge der GroupAddressTable.

      Danach mache ich das gleiche mit der GroupAssociationTable. Darin steht dann glaube ich welche GroupAddress an welches ComObject gekoppelt ist.

      Als letzten Schritt lese ich die ComObjectTable. Hier musste ich auch glaube ich einen kleinen Trick anwenden. Ich konnte aus System 7 Geräten die ComObjectTable Start-Adresse nicht auslesen. Daher habe ich mir eine Anwendung geschrieben, die den KNX Webservice die XML Deskriptoren herunter-lädt, via XSL radikal eindampft und am ende eine Liste von Start-Adressen enthält. Mit Vendor-Id, Applitcation-Id und Application-Version, kann ich dann diese Start-Adresse nehmen und weiter machen. (https://github.com/apache/plc4x/blob...ice-info.mspec)

      Bin mir sicher, dass das nicht 100% korrekt ist alles, aber ich bin schon mal sehr viel weiter gekommen. Natürlich denke ich, wenn wir uns alle zusammen tun, dann können wir das sicher perfektionieren.

      Hoffe das erklärt, was ich bisher gemacht habe.

      Gruß,
      Chris

      Kommentar


        #4
        Hi Chris,

        ich verstehe noch nicht, was Du damit erreichen willst. Den Zustand, den Du in Deiner Demo ausliest, ist ja nur eine Momentaufnahme.
        Ich interpretiere den Satz
        Zitat von cdutz Beitrag anzeigen
        Zumindest könntet ihr mit plc4py schon mal alle Messages und Typen, Parser, Serializer generiert bekommen
        so, dass ihr wirklich Coding daraus generiert.

        Dummerweise gibt es in KNX-Produktdatenbanken so was:
        Code:
          <ComObjectTable>
            <ComObject Id="M-00FA_A-0001-01-0000_O-2045001" Name="KOs%C%" Number="345" Text="Dynamic" ObjectSize="1 Bit" FunctionText="Gerät %C%, Ausgang" ReadFlag="Enabled" WriteFlag="Disabled" CommunicationFlag="Enabled" TransmitFlag="Enabled" UpdateFlag="Disabled" ReadOnInitFlag="Disabled" />
          </ComObjectTable>
          <ComObjectRefs>
            <ComObjectRef Id="M-00FA_A-0001-01-0000_O-2045001_R-204500101" RefId="M-00FA_A-0001-01-0000_O-2045001" Text="{{0:Ausgang}}" TextParameterRefId="M-00FA_A-0001-01-0000_P-2045042_R-204504201" DatapointType="DPST-1-1" />
            <ComObjectRef Id="M-00FA_A-0001-01-0000_O-2045001_R-204500102" RefId="M-00FA_A-0001-01-0000_O-2045001" Text="{{0:Ausgang}}" TextParameterRefId="M-00FA_A-0001-01-0000_P-2045042_R-204504201" ObjectSize="2 Bytes" DatapointType="DPST-9-1" />
            <ComObjectRef Id="M-00FA_A-0001-01-0000_O-2045001_R-204500103" RefId="M-00FA_A-0001-01-0000_O-2045001" Text="{{0:Ausgang}}" TextParameterRefId="M-00FA_A-0001-01-0000_P-2045042_R-204504201" ObjectSize="2 Bytes" DatapointType="DPST-9-4" />
            <ComObjectRef Id="M-00FA_A-0001-01-0000_O-2045001_R-204500104" RefId="M-00FA_A-0001-01-0000_O-2045001" Text="{{0:Ausgang}}" TextParameterRefId="M-00FA_A-0001-01-0000_P-2045042_R-204504201" ObjectSize="2 Bytes" DatapointType="DPST-9-7" />
            <ComObjectRef Id="M-00FA_A-0001-01-0000_O-2045001_R-204500105" RefId="M-00FA_A-0001-01-0000_O-2045001" Text="{{0:Ausgang}}" TextParameterRefId="M-00FA_A-0001-01-0000_P-2045042_R-204504201" ObjectSize="2 Bytes" DatapointType="DPT-9" />
            <ComObjectRef Id="M-00FA_A-0001-01-0000_O-2045001_R-204500106" RefId="M-00FA_A-0001-01-0000_O-2045001" Text="{{0:Eingang/Status}}" TextParameterRefId="M-00FA_A-0001-01-0000_P-2045042_R-204504201" FunctionText="Gerät %C%, Eingang/Status" WriteFlag="Enabled" DatapointType="DPST-1-1" />
            <ComObjectRef Id="M-00FA_A-0001-01-0000_O-2045001_R-204500107" RefId="M-00FA_A-0001-01-0000_O-2045001" Text="{{0:Ein-/Ausgang/Status}}" TextParameterRefId="M-00FA_A-0001-01-0000_P-2045042_R-204504201" ObjectSize="1 Byte" FunctionText="Gerät %C%, Eingang/Ausgang/Status" WriteFlag="Enabled" DatapointType="DPST-5-5" />
            <ComObjectRef Id="M-00FA_A-0001-01-0000_O-2045001_R-204500108" RefId="M-00FA_A-0001-01-0000_O-2045001" Text="{{0:Ausgang}}" TextParameterRefId="M-00FA_A-0001-01-0000_P-2045042_R-204504201" ObjectSize="2 Bytes" DatapointType="DPST-9-20" />
          </ComObjectRefs>
        Das sagt mehr oder minder, das KO 345, je nach Parametrierung, in 8 verschiedenen Ausprägungen existieren kann,
        • mit unterschiedlichen DPT (im Beispiel 1.001, 9.001, 9.004, 9.007, 9.*, 5.005, 9.020)
        • damit unterschiedlichen Längen (im Beispiel 1 Bit, 1 Byte, 2 Bytes)
        • und unterschiedlichen Flags (im Beispiel KLÜ und KLSÜ)
        Damit hängt das also von einer konkreten Parametrisierung des Gerätes ab. Einmal mit der ETS neu programmiert und eure Codegenerierung ist invalidiert. Man müsste also nach jeder ETS-Programmierung die Code-Generierung anstoßen, oder? Zumindest müsste man verifizieren, ob das noch passt.

        Ich will Deine Leistung nicht kritisieren, ich will nur besser verstehen, wofür das gedacht ist. Und Dich vielleicht auf "Stolperfallen" in KNX hinweisen, die Du vielleicht noch nicht weißt oder noch nicht rausgefunden hast. Wobei dieser Satz
        Zitat von cdutz Beitrag anzeigen
        Momentan arbeite ich daran die genauen Datentypen der Com-Objects zu berechnen. Hierzu muss ich allerdings die Konfiguration des Geräts kennen.
        eigentlich zeigt, dass Du das schon weißt .

        Gruß, Waldemar
        OpenKNX www.openknx.de

        Kommentar


          #5
          Hi Waldemar,

          In dem anderen thread gehe ich gezeilt auf dieses thema ein.
          Also ich habe ein knx device profil in XML-form. Das enthält im dynamic Teil all das wissen darüber in welchem zustand das KNX bei gegebener Konfiguration sein sollte.

          Soweit ich das recherchieren konnte, sind die Parameter, die dafür zuständig sind, zu entscheiden welcher typ ein com-object hat immer an Memory gebunden. Nun war es meine Idee diesen Speicher auszulesen. Somit kenne ich den aktuellen Zustand des KNX gerätes und kann anhand der Information im dynamic teil berechnen, welchen datentyp ein com object haben sollte.

          Ja: es hat einen verbindungs-overhead. Ich muss generell beim verbindungs-aufbau den config speicher auslesen ... aber danach sollte ich in der lage sein, während der session die Daten interpretieren zu können.

          Hier mal ein beispiel, was ich gerade mache:

          Ich nehme den "dynamic" teil und mach' den erstmal für mich lesbarer:

          Code:
          <enableParameter>delay after bus voltage recovery</enableParameter>
          <enableParameter>monitor interval time</enableParameter>
          <enableComObject>General In operation</enableComObject>
          <enableParameter>enable safety priority</enableParameter>
          <switch on="enable safety priority">
            <case value="1">
              <enableParameter>set safety priority 1</enableParameter>
              <switch on="set safety priority 1">
                <case value="1">
                  <enableParameter>control period safety 1</enableParameter>
                  <enableComObject>General safety priority 1</enableComObject>
                </case>
                <case value="2">
                  <enableParameter>control period safety 1</enableParameter>
                  <enableComObject>General safety priority 1</enableComObject>
                </case>
              </switch>
              <enableParameter>set safety priority 2</enableParameter>
              <switch on="set safety priority 2">
                <case value="1">
                  <enableParameter>control period safety 2</enableParameter>
                  <enableComObject>General safety priority 2</enableComObject>
                </case>
                <case value="2">
                  <enableParameter>control period safety 2</enableParameter>
                  <enableComObject>General safety priority 2</enableComObject>
                </case>
              </switch>
            </case>
          </switch>
          ...
          Aber ich denke das kann ich generell so eindampfen, dass ich am ende nur noch die Switches mit speicher-adressen habe und als Ergebnisse aktivierte com-object Konfigurationen.

          Macht das soweit Sinn?

          Gruß,
          Chirs

          Kommentar


            #6
            Ja, hört sich gut an. Noch ein paar Tipps zur Auswertung (weil das für Programmierer nicht unbedingt erwartungskonform ist):
            1. Die "value"-Attribute ("test" in KNX) sind komplex, es können so Sachen stehen wie
              • value="!=0" (ungleich 0)
              • value="1 3 5" (1 oder 3 oder 5)
              • value="&lt;5" (kleiner 5)
              • wahrscheinlich noch weitere Varianten, die ich noch nicht kenne...
            2. Die "case"-Äste ("when" in KNX) sind nicht alternativ, ich kann also so was haben (beides wird durchlaufen, wenn der Wert 1 ist):
              • case value="1"
              • case value="!=0"
            3. Es gibt noch Assign... aber das dürfte für Dich, der ja "rückwärts" vom im Memory gespeicherten Wert ausgeht, nicht interessant sein.
            Aber das würde ja trotzdem bedeuten, dass Du nach jeder ETS-Programmierung entweder Dein komplettes Coding neu generieren musst, oder? Und das dann darauf basierendes Coding invalidiert wird, oder? Zumindest bei "strong typed" Sprachen?

            Jemand, der schon ähnliches versucht hat, ist thewhobox (Mike), hast Du mit dem schon gesprochen?

            Gruß, Waldemar
            OpenKNX www.openknx.de

            Kommentar


              #7
              Hallo Waldemar,

              uiii ... das mit den switches, bei denen mehrere cases aktiv sein können, hätte mich sicher übelst irritiert ... danke für den Hinweis :-)

              Naja ... die Device XML Files sind doch statisch, oder?
              Meine Erwartung momentan wäre gewesen:
              - Ich verbinde mich mit dem KNX gerät, lese den speicher aus, weiß dann automatisch wie die datenpunkte zu interpretieren sind
              - Nun ändert der User etwas an der Konfiguration ... dies verändert dann die Konfiguration in dem data block.
              - Wenn ich mich nach der Änderung wieder mit dem Gerät verbinde, bekomme ich den geänderten data block und die auswertung sollte mir die geänderten datentypen liefern.

              Oder sehe ich da was falsch und die vom KNX webserivce geladenen profile-xml files ändern sich?

              Viele Grüße,
              Chris

              Kommentar


                #8
                Aber noch eine frage zu den Switches ... es gibt auch die "case default=true" fälle ... ist das evtl. ein sonderfall? Auch wenn ich eben dieses Konstrukt nur in fällen sehen konnte, wo das ganze "when" nicht wirklich sinn gemacht hat ...
                Gibt's irgendwo eine Dokumentation für die Auswertungslogik der XML files und vor allem des dynamic teils?

                Kommentar


                  #9
                  Hi,

                  ich antworte mal - nach bestem Wissen - muss aber nicht korrekt sein:

                  Zitat von cdutz Beitrag anzeigen
                  Naja ... die Device XML Files sind doch statisch, oder?
                  Bis auf verschiedene Applikationsversionen für das gleiche Gerät. Also "alte" Versionen, bei den das Speicherlayout anders sein kann als bei der aktuellen Version. Aber ja, sie sind statisch. Falls Du Dich aber immer auf die neuste Version verlässt, kann vom Webservice jederzeit (wenn auch sehr selten) bei einem Aufruf was "neueres" kommen.

                  Zitat von cdutz Beitrag anzeigen
                  es gibt auch die "case default=true" fälle
                  Tja, das weiß ich leider auch nicht. Ich habe es bisher erfolgreich vermieden, die zu nutzen und kam auch immer drumrum. Weil ich nicht weiß, wie die genau funktionieren. Da kann aber vielleicht thewhobox noch was zu sagen...

                  Zitat von cdutz Beitrag anzeigen
                  Gibt's irgendwo eine Dokumentation für die Auswertungslogik der XML files und vor allem des dynamic teils?
                  Ich hab alles durch Try&Error rausgefunden, keine Doku da. Wäre schön, so was zu haben .

                  Gruß, Waldemar


                  OpenKNX www.openknx.de

                  Kommentar


                    #10
                    Guten Abend,

                    wie stellt ihr denn sicher, dass ihr immer die passende Produktdatenbank habt zum Gerät?
                    Die müsstet ihr ja auch vorher importieren oder eine Fehlermeldung ausgeben.

                    Zitat von cdutz Beitrag anzeigen
                    es gibt auch die "when default=true" fälle
                    Der Zweig wird angezeigt, wenn kein anderer when zweig angezeigt wird.

                    Zitat von cdutz Beitrag anzeigen
                    Konstrukt nur in fällen sehen konnte, wo das ganze "when" nicht wirklich sinn gemacht hat ...
                    Wenn du sowas meinst:
                    <Dynamic>
                    <IndipendentChannel>
                    <ParameterBlock Id="_R-12" TextParameterId="_R-13">
                    <choose ParameterId="_R-13">
                    <when default="true">
                    Das kommt durch das Konvertieren von alten Produktdatenbanken.
                    Es kommt noch dazu, dass ein choose nur geprüft wird, wenn der Parameter "aktiv" ist. Aktiv ist ein Parameter, wenn er sichtbar ist, bzw der ParameterBlock sichtbar, dem er zugewiesen wurde.

                    Gruß Mike
                    OpenKNX www.openknx.de | Kaenx-Creator | Dali-GW

                    Kommentar


                      #11
                      Vielen Dank für diese ganzen Infos :-)

                      Echt sehr hilfreich :-)

                      Sollte mal anfangen die zusammen getragenen Infos zu dokumentieren ... ich glaube die eine oder andere Antwort kam mir tatsächlich bekannt vor. Tut mir leid, wenn ich zu viele dumme Fragen stelle ... das letzte mal war ich vor über einem Jahr an dem Thema dran.

                      Naja .. im PLC4X Projekt sammeln wir diese Descriptoren. Zwar haben wir sicher 5000 über den Webserivce bekommen und wir checken regelmäßig ob's neue gibt ... aber gibt ja immer noch welche die fehlen. Da wollen wir so eine Art Extraktor bauen, dem man dann seine knxproj Files vorwerfen kann und der dann fehlende Deskriptoren ergänzt.

                      Gruß,
                      Chris

                      Kommentar


                        #12
                        @thewhobox verstehe ich das richtig, dass ein "when default='true'" enthalten ist, dieser block nur ausgewertet wird, wenn kein anderer `when` block sonst aktiviert ist?

                        Ich kann also durchaus mehrere blöcke aktivieren ... aber erst wenn keiner aktiviert ist, wird der default verarbeitet?

                        Und sehe ich das auch richtig, dass diese aus nur einem default=true bestehenden konstukte zu lesen sind wie "if-Anweisungen"? Also ist Parameter X aktiviert (Egal welcher Wert)? Dann werte den default=true block aus?

                        Dann hätte ich allgemein noch eine Frage zu den "test" ausdrücken:
                        - Geht auch ein "<=4" und ">= 4"? (Also alles kleiner-gleich 4 oder größer-gleich 4)
                        - Gibt es ein "3-5" (alle werte 3, 4 und 5)

                        Ich dokumentiere gerade alles, was ich gelernt habe damit ich nicht nochmal fragen muss und damit auch andere davon profitieren. Werde dann hier auch den link posten sowie ich mit dem ersten Entwurf fertig bin.

                        Gurß,
                        Chris

                        Kommentar


                          #13
                          Ja genau. Der default wird nur angezeigt, wenn kein anderen when block aktiv ist.
                          So gesehen, können auch mehrere when Blöcke eines choose gleichzeitig aktiv sein.

                          Zitat von cdutz Beitrag anzeigen
                          Also ist Parameter X aktiviert (Egal welcher Wert)? Dann werte den default=true block aus?
                          Das mit den aktiven Parametern hat nix mit dem default zu tun.
                          Nur wenn der Parameter vom choose sichtbar ist, wird dieser auch ausgewertet.
                          Das Beispiel mit dem unnötigen choose und default kommt nur durch das Konvertieren alter Produktdatenbanken vor.

                          Zitat von cdutz Beitrag anzeigen
                          Geht auch ein "<=4" und ">= 4"?
                          Ja das gibt es.

                          Zitat von cdutz Beitrag anzeigen
                          Gibt es ein "3-5"
                          Nein das gibt es nicht. (Bzw habe ich es noch nicht gesehen)

                          Gruß Mike
                          OpenKNX www.openknx.de | Kaenx-Creator | Dali-GW

                          Kommentar


                            #14
                            So ... hier der Link: https://github.com/apache/plc4x/blob...-profiles.adoc

                            Kommentar


                              #15
                              Ich hab mir die Doku mal kurz angeschaut.
                              Da ist vieles nur sehr "schwammig" beschrieben.
                              Du solltest da ganz klar immer von Paramter, ParameterRef und ParameterRefRef unterscheiden.
                              Ein ParameterRefRef verweist nur auf ParameterRef, der wiederrum auf Parameter verweist.
                              Anmerkung zur Note: Es kann auch mehrere ParameterRefRef geben, die auf den gleichen ParameterRef verweisen. Diese sollten dann aber natürlich nicht gleichzeitig sichtbar sein.

                              Anmerkung zu ComObjectRefRef: Auch hier können mehrere RefRefs auf den gleichen Ref zeigen. Diese dürfen aber niemals gleichzeitig sichtbar sein.

                              Zu den Channesl siehe hier im anderen Post.
                              "CH-1" ist dabei ein Channel und "Konfig CH-1" ein ParameterBlock. Die Parameter rechts davon sind dann eben in diesem enthalten:
                              Code:
                              <Channel Text="CH-1">
                              <ParameterBlock Text="Konfig CH-1">
                              <ParameterRefRef ParameterRefId="_P-1_R-1" />
                              <ParameterRefRef ParameterRefId="_P-2_R-2" />

                              Weitere Anmerkung:
                              Es gibt auch IndependentChannels. Der wird viel bei kleineren Produktdatenbanken verwendet und stellt einen unsichtbaren Channel da.
                              Es werden also nur die ParameterBlöcke direkt angezeigt.

                              Ganz außer acht gelassen hast du bisher ModuleDefines^^
                              Die werden auch immer öfters verwendet.

                              Gruß Mike
                              OpenKNX www.openknx.de | Kaenx-Creator | Dali-GW

                              Kommentar

                              Lädt...
                              X