Ankündigung

Einklappen
Keine Ankündigung bisher.

OpenKNX und DPT 7.007

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

    OpenKNX und DPT 7.007

    Hallo zusammen,

    ich lese hier schon eine Zeit lang mit und habe auch schon verschiedene OpenKnx Geräte im Einsatz. An dieser Stelle einmal vielen Dank an alle die OpenKnx zu dem gemacht haben und machen was es heute ist. Es ist überaus beeindruckend was ihr hier geschaffen habt und wie viel Zeit ihr hier investiert! 👍

    Aktuell bin ich dabei eine eigene Applikation / Firmware auf Basis von OpenKNX zu entwickeln, um unsere Hoval Lüftungsanlage an den KNX-Bus zu bekommen. Das Hoval CAN Protocol habe ich mittlerweile weitgehend verstanden und auch schon den Grundstock implementiert, um das ganze auf den Bus zu bekommen. Die ersten Werte werden bereits erfolgreich übertragen. Wenn das ganze einmal weiter gediehen ist und die initialen Bugs weg sind, werde ich das ganze auch veröffentlichen und hier im Forum mal vorstellen.

    Nun zu meinem Anliegen / Problem. Ich verwende unter anderem einen DPT vom Typ 7.007 (Zeit in Stunden) um die aktuelle Restzeit des Wartungszählers auf den Bus zu bekommen. Dabei stoße ich auf ein paar Hürden und frage mich, ob die Knx Implementierung an der Stelle fehlerhaft ist, oder ich zu Blöd dafür bin 😉. Ich komme aus der Java Welt und mein C++ Wissen ist teilweise begrenzt.
    Mein Problem, ist das, "egal" wie ich den Wert übergebe auf dem Bus immer eine 0 ankommt.

    Im ersten Schritt hatte ich es naiv so versucht:
    Code:
    GroupObject &groupObject = knx.getGroupObject(comObject);
    
    KNXValue value = KNXValue((uint16_t)5);
    groupObject.value(value, DPT_TimePeriodHrs);
    Dann hatte ich mir valueToBusValueTimePeriod in dptconvert.cpp angeschaut und gesehn das hier ein tm struct verwendet wird. Also verschieden Varianten damit versucht:
    Code:
    tm time = {0};
    time.tm_hour = 5;
    KNXValue value = KNXValue(time)
    groupObject.value(value, DPT_TimePeriodHrs);​
    ...
    gmtime_r(0, &time);
    time.tm_hour = 5;​
    ...
    localtime_r(0, &time);
    time.tm_hour = 5;
    ...
    time_t hrs = 5;
    gmtime_r(&hrs, &time);
    ...
    localtime_r(&hrs, &time);
    ...
    Diverse weitere Varianten...
    Ich habe dann in valueToBusValueTimePeriod​ Log Ausgaben hinzugefügt und festgestellt das timeSinceEpoch (hier https://github.com/OpenKNX/knx/blob/...nvert.cpp#L997) in allen Fällen negativ ist - in den meisten von mir getesten Fällen um 3600 gegenüber meinem Wert.
    Ich habe es jetzt aktuell so am laufen und bekomme korrekte Werte auf den Bus
    Code:
    time_t hrs = 5 + 3600; // Offset von 3600s / 1h
    tm time;
    gmtime_r(&hrs, &time);
    KNXValue value = KNXValue(time);
    groupObject.value(value, DPT_TimePeriodHrs);​
    Sinnvoll erscheint mir das allerdings nicht.

    Die Frage ist für mich erstmal, ist die Implementierung von valueToBusValueTimePeriod​ überhaupt korrekt / sinnvoll. Für mich erscheint es wenig sinnhaft hier ein tm struct zu verwenden. Am Ende des Tages soll ja kein Zeitpunkt übertragen werden sondern nur ein Zeitraum. Ich würde hier also ein einfaches uint16_t erwarten. Aber möglicherweise liegt das auch an meinem fehlenden Verständnis
    Falls das wirklich so beabsichtigt ist stellt sich mir die Frage was ist der Sinn dahinter und wie kann das ganze korrekt verwendet werden.

    Beste Grüße

    #2
    Zitat von alanz Beitrag anzeigen
    und festgestellt das timeSinceEpoch (hier https://github.com/OpenKNX/knx/blob/...nvert.cpp#L997) in allen Fällen negativ ist
    Darstellungsproblem?
    große uint als int interpretiert werden negativ.. ?

    Zitat von alanz Beitrag anzeigen
    in den meisten von mir getesten Fällen um 3600 gegenüber meinem Wert.
    negativ gegenüber verstehe ich nicht.
    Bei 3600 = 1h fällt mir spontan Zeitzone ein...

    Zitat von alanz Beitrag anzeigen
    Die Frage ist für mich erstmal, ist die Implementierung von valueToBusValueTimePeriod​ überhaupt korrekt / sinnvoll.
    auf den ersten Blick verstehe ich nicht was der ursprüngliche Autor sich dabei gedacht hat...
    evtl die fehlannahme dass die daten als sekunden übertragen werden.. aber selbst da macht es wenig Sinn über time_t zu gehen.

    evtl schaut unser Zeitexperte mgeramb mal drauf
    OpenKNX www.openknx.de

    Kommentar


      #3
      Empfehlung: Nutze beim Senden/Schreiben ins KO den DPT 7.001 (DPT_Value_2_Ucount) auf dem Bus macht das keinen Unterschied. Da kannst Du direkt uint16_t eingeben.

      Nach History wurde die DPT-Konvertierung vor 7 Jahren (noch vor Beginn von OpenKNX) aus knxd-Implementierung umgesetzt und es ist durchaus möglich, dass das ganze schlicht und einfache eine Implementierung ist die ursprünglich mal erstellt wurde mit dem Ziel alle definierten DPTs mit abzudecken. Ich häte hier zumindest auch eine Fallunterscheidung nach Subtyp erwartet.

      Zitat von alanz Beitrag anzeigen
      festgestellt das timeSinceEpoch (hier https://github.com/OpenKNX/knx/blob/...nvert.cpp#L997) in allen Fällen negativ ist - in den meisten von mir getesten Fällen um 3600 gegenüber meinem Wert.
      Ohne das weiter geprüft/analysiert zu haben, vermute ich das dies auf die gesetzte deutsche Zeitzone (Standardeinstellung in Common) zurückzuführen ist.
      OpenKNX www.openknx.de | StateEngine: Universelle Zustandsautomaten in KNX | OpenKNX Konfigurationstransfer

      Kommentar


        #4
        Ich weiß auch nicht, ob und wie der DPT7.007 implementiert wurde, fand das aber schon immer überflüssig (außer 5.001, damit da einheitlich gerechnet wird).
        Der DPT7.007 sagt ja nur, wie Du die Zahl, die da ankommt, zu interpretieren hast. Es sagt nur, dass die 17, die über den Bus gesendet wird, 17 Stunden meint. Gesendet wird trotzdem nur eine 17. Und wenn Du in der ETS den DPT auf 7.006 stellst (Zeit in min), bleibt die Zahl 17 und es wird daraus nicht irgendwie magisch 17*60=1020.
        Mach es also so, wie von coco vorgeschlagen und sende mit DPT7.*. In der knxprod gibst Du (für die ETS) normal 7.007 an und alle sind glücklich.

        Gruß, Waldemar
        OpenKNX www.openknx.de

        Kommentar


          #5
          Ich bin mal wieder beeindruck wie schnell einem hier geholfen wird - und auch zu welchen Tageszeiten ...

          Auf die Idee einfach ein DPT 7.001 zu verwenden bin ich noch gar nicht gekommen - aber macht Sinn. Damit sollte es funktionieren. Werde ich gleich mal testen. --> Funktioniert Prima.

          Zitat von Ing-Dom Beitrag anzeigen
          negativ gegenüber verstehe ich nicht.
          Bei 3600 = 1h fällt mir spontan Zeitzone ein...​
          Da war ich wohl zu ungenau. Ich hatte in timeSinceEpoch​ nach Zeile 997 ein Serial.println((int64_t)timeSinceEpoch); eingefügt und habe da, wenn ich 5 gesendet habe, einen Wert von -3595 ausgegeben bekommen.

          Zitat von coko Beitrag anzeigen
          Ohne das weiter geprüft/analysiert zu haben, vermute ich das dies auf die gesetzte deutsche Zeitzone (Standardeinstellung in Common) zurückzuführen ist.
          Das war auch meine Vermutung​. Deswegen hatte ich sowohl mit localtime_r als auch mit gmtime_r herumgespielt. Hatte aber beides mal das selbe Ergebnis.

          Um das ganze zu fixen müsste man eigentlich nur bei dptconvert.cpp in Zeile 162 die DPT 7.002 - 7.007 mit aufnehmen und die Sonderbehandlung für diese Typen entfernen. Oder wie beim decode einfach valueToBusValueTimePeriod analog valueToBusValueUnsigned16 implementieren. Wäre hier ein PR willkommen? Oder fürchtet ihr da einen breaking change? Wenn ja, gibt es präferenzen für die eine oder andere Variante?

          Kommentar


            #6
            Zitat von alanz Beitrag anzeigen
            Wäre hier ein PR willkommen?
            klar

            Zitat von alanz Beitrag anzeigen
            Oder fürchtet ihr da einen breaking change?
            Wir verwenden den nicht, insofern wird er auch nichts brechen.

            OpenKNX www.openknx.de

            Kommentar


              #7
              Zitat von alanz Beitrag anzeigen
              Da war ich wohl zu ungenau. Ich hatte in timeSinceEpoch​ nach Zeile 997 ein Serial.println((int64_t)timeSinceEpoch); eingefügt und habe da, wenn ich 5 gesendet habe, einen Wert von -3595 ausgegeben bekommen.
              mktime "Converts local calendar time to a time since epoch". Wenn Du eine Zeit mit UTC+1:00 eingibst ist das Verhalten somit nachvollziehbar.

              Zitat von alanz Beitrag anzeigen
              Um das ganze zu fixen müsste man eigentlich nur bei dptconvert.cpp in Zeile 162 die DPT 7.002 - 7.007 mit aufnehmen und die Sonderbehandlung für diese Typen entfernen. Oder wie beim decode einfach valueToBusValueTimePeriod analog valueToBusValueUnsigned16 implementieren. Wäre hier ein PR willkommen? Oder fürchtet ihr da einen breaking change? Wenn ja, gibt es präferenzen für die eine oder andere Variante?
              Also ein Breaking-Change wäre es natürlich schon. Und ich stelle gerade mit leichter überraschung fest, dass traxanos den Typ DPT_TimePeriodHrs tatsächlich schon im Meter-Modul verwendet hat. Allerdings uint32_t Input. Kann nicht ausschließen, dass das das in diesem Fall sogar zufällig durch Konvertierung mit KnxValue funktioniert hat. Das sollte vorab geklärt werden. Auch würde ich eine entsprechende Anpassung Upstream bereitstellen wollen, wo eine Nutzung praktisch nicht überprüfbar ist.
              OpenKNX www.openknx.de | StateEngine: Universelle Zustandsautomaten in KNX | OpenKNX Konfigurationstransfer

              Kommentar


                #8
                Zitat von coko Beitrag anzeigen
                Und ich stelle gerade mit leichter überraschung fest, dass traxanos den Typ DPT_TimePeriodHrs tatsächlich schon im Meter-Modul verwendet hat. Allerdings uint32_t Input. Kann nicht ausschließen, dass das das in diesem Fall sogar zufällig durch Konvertierung mit KnxValue funktioniert hat. Das sollte vorab geklärt werden. Auch würde ich eine entsprechende Anpassung Upstream bereitstellen wollen, wo eine Nutzung praktisch nicht überprüfbar ist.
                Ich hatte es mit uint16_t versucht. uint32_t macht da keinen Unterschied. Beides wird von KnxValue auf uint64_t gemapped, dann auf time_t gecastet und per gmtime_r in ein tm struct umgewandelt. Das Problem müsste also beim Meter-Modul auch auftreten. Ggf. ist es dort kein Problem weil die Zeitzone UTC ist - wobei das durch Common auf CET/CEST gesetzt werden müsste wenn ich dich richtig verstanden habe. Vielleicht ist es aus irgendeinem Grund beim Meter Modul bisher nur noch nicht aufgefallen. Dort kann man ja zwischen zwei DPTs wählen und man merkt es da erst nach einer Stunde.

                Kommentar

                Lädt...
                X