Ankündigung

Einklappen
Keine Ankündigung bisher.

Lesen der Uhrzeit DPT 10.001

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

  • Sonnengruesser
    antwortet
    Ich hatte vor einigen Tagen das gleiche Problem und hier dokumentiert wie's zu lösen ist:
    knx/issues/233

    Edit: Lösung war ja schon weiter oben...

    Einen Kommentar schreiben:


  • willisurf
    antwortet
    Eigentlich nicht und da Du den Thread erstellt hast, sollte das gehen. Aber egal, kannst Du auch einfach so lassen, ging früher vor dem Update der Forensoftware (das diese Funktion einführte) ja auch.

    Also alles gut.

    Einen Kommentar schreiben:


  • mobil750
    antwortet
    Hallo Bernhard,

    bei keinem der Beiträge gibt es die Möglichkeit den Haken zu setzen ....
    Bildschirmfoto 2023-04-01 um 18.46.47.png
    Muss man das irgendwo konfigurieren?

    Gruß
    Helmut

    Einen Kommentar schreiben:


  • willisurf
    antwortet
    Setze einfach bei dem passenden Beitrag den Haken rechts unten
    IMG_8321.jpg

    Einen Kommentar schreiben:


  • mobil750
    antwortet
    Hallo Waldemar,

    danke für die Erläuterungen.

    Ich habe deine Vorschläge ausprobiert. Nur​ wenn man die dpt.h entsprechend deiner Beschreibung ergänzt, funktioniert der DPT 10.001 korrekt.

    Da mir dann noch der Wochentag fehlt, habe ich die entsprechende Erweiterung in der dptconvert.cpp durchgeführt. Mein Problem ist damit gelöst.

    Die beiden Änderungen habe ich dann auch, wie von dir vorgeschlagen, als Pull-Request eingestellt.

    Das war heute sehr lehrreich! Bleibt nur noch die Frage, wie ich dieses Topic als gelöst markieren kann ...

    Gruß
    Helmut

    Einen Kommentar schreiben:


  • mumpf
    antwortet
    Hi Helmut,

    ich gebe gerne Hilfe zur Selbsthilfe, in der annahme, dass man sich in das Thema eindenkt und motiviert ist, eigene Probleme zu lösen und daraus zu lernen.

    Zitat von mobil750 Beitrag anzeigen
    Hier meine Code-Schnipsel für Date (funktioniert) und Time (funktioniert nicht).
    Mit der Aussage weißt Du, dass Time nicht geht.

    Zitat von mumpf Beitrag anzeigen
    Da sieht man dann, dass man ein Time-value mit Dpt(10,1,1) abholen muss. Du hast wahrscheinlich Dpt(10,1,0) genommen.
    Oben sage ich, dass Du wahrscheinlich auf Time mit dem falschen Dpt zugreifst.

    Zitat von mobil750 Beitrag anzeigen
    grpObjTime.dataPointType(DPT_TimeOfDay);
    Dein Codeschnipsel sagt, dass Du mit DPT_TimeOfDay zugreifst.

    Nachschauen im Header-File:
    Code:
    #define DPT_TimeOfDay Dpt(10, 1)
    Ok, ist weder Dpt(10,1,0) noch Dpt(10,1,1).

    Im Kostruktor nachgeschaut:
    Code:
    Dpt::Dpt(short mainGroup, short subGroup, short index /* = 0 */)
    Aha, Dpt(10,1) entspricht Dpt(10,1,0).

    Ausprobieren:
    Du änderst Dein Coding in
    Code:
    grpObjTime.dataPointType(Dpt(10,1,1));
    Ok, funktioniert. Jetzt kann man aufhören. Oder den Community-Gedanken weiterverfolgen und das Headerfile ändern:
    Code:
    #define DPT_TimeOfDay Dpt(10, 1, 1)
    ​Danach einen Pull-Request erstellen mit dem Hinweis, dass man einen Fehler im Stack gefunden hat und TimeOfDay für den Gelegenheitsuser eher so definiert sein sollte.

    Zitat von mobil750 Beitrag anzeigen
    Allerdings geht das schon extrem tief in den Stack, wobei mir unklar ist wie da der Aufruf erfolgt.
    Ich weiß auch nicht, wie der Aufruf erfolgt. Das ist auch nicht wichtig. Irgendwann muss eine payload im Telegramm in Abhängigkeit vom DPT in einen Wert gewandelt werden und da passiert es. Zum nachschauen reicht das.

    Zitat von mobil750 Beitrag anzeigen
    Im Prinzip müssten doch diese Details für die Anwendung transparent sein, so wie es auch bei allen anderen DPTs ist.
    Das ist eine Erwartungshaltung, die man (vielleicht) an einen professionellen Stack stellen kann (und selbst da dürfte es nicht immer so sein). Auch stimmt es nicht, dass das Verhalten bei zusammengesetzten DPT immer nach oben transparent sein kann, es hängt davon ab, was man bezweckt.

    Ich will hier nicht kritisieren, sondern die Erwartungshaltung zurechtrücken. Es ist vieles nicht perfekt und Verbesserungen sind willkommen. Allerdings können diese nicht von uns vorgenommen werden sondern müssen auch von der Community kommen. Schon bei ganz wenig nutzern ist es unmöglich zu realisieren, wenn jeder sagt "mach es besser" und nur einer es machen soll.

    Ich hoffe, Du bekommst Deine Lösung jetzt hin, wenn nicht, helfe ich gerne weiter.
    Gruß, Waldemar

    Einen Kommentar schreiben:


  • Ing-Dom
    antwortet
    Zitat von mobil750 Beitrag anzeigen
    Entweder habe ich da noch einen Fehler in meinem Code, den ich nicht erkenne, oder da stimmt im Stack was nicht. Liege ich da richtig?
    Der stack ist nicht ideal bei der conversion der Datentypen. Da könnte man verbessern, da haben wir auch schon diskutiert. Hat halt aktuell nicht die oberste Prio.
    Speziell mit Uhrzeit hatte sich aber auch schon Cornelius intensiver beschäftigt, Status kenne ich aber nicht...

    Grundsätzlich gilt: wenn du was am stack verbessert haben willst, mache es. PRs welcome.

    Einen Kommentar schreiben:


  • mobil750
    antwortet
    Hallo Waldemar,

    danke für die ausführliche Antwort. Allerdings geht das schon extrem tief in den Stack, wobei mir unklar ist wie da der Aufruf erfolgt.

    Im Prinzip müssten doch diese Details für die Anwendung transparent sein, so wie es auch bei allen anderen DPTs ist.

    Hier meine Code-Schnipsel für Date (funktioniert) und Time (funktioniert nicht).

    Code:
    #define grpObjDate knx.getGroupObject(COMOBJ_Datum)
    #define grpObjTime knx.getGroupObject(COMOBJ_Zeit)
    
      grpObjDate.callback(callbackDate);
      grpObjDate.dataPointType(DPT_Date);
    
      grpObjTime.callback(callbackTime);
      grpObjTime.dataPointType(DPT_TimeOfDay);
    
    
    ​//--------------------------------------------------------------
    void callbackDate(GroupObject& go) {
      struct tm myTime;
      bool success = false;
    
      myTime = go.value();
      tmp_mday = myTime.tm_mday;
      tmp_month = myTime.tm_mon;
      tmp_year = myTime.tm_year;
      short unsigned int subYear = tmp_year - 2000;
    
      DEBUG_VERBOSE("callbackDate(%d-0): >>>>>>>>>> new KNX Date event received - tmp_mday = %d; tmp_month = %d; subYear = %d", loopCntr, tmp_mday, tmp_month, subYear);
    .....
    
    
    ​//--------------------------------------------------------------
    void callbackTime(GroupObject& go) {
      struct tm rxdTime;
      bool success = false;
    
      rxdTime = go.value();
    ​//  rxdTime = go.value(DPT_TimeOfDay);     -> bringt auch nichts
    
      tmp_min = rxdTime.tm_min;
      tmp_hour = rxdTime.tm_hour;
      tmp_wday = (rxdTime.tm_hour & dayMask) >> 5;
    
      DEBUG_VERBOSE("callbackTime(%d-0): >>>>>>>>>> new KNX TIME event received - tmp_wday = %d; tmp_hour = %d; tmp_min = %d", loopCntr, tmp_wday, tmp_hour, tmp_min);
    .....
    ​
    ​
    ​
    Wie man aus deinem zitierten Code-Auszug auch sieht fehlt da ein für mich relevanter Wert, der dayOfWeek, den ich gerne anzeigen möchte.
    Klar den kann ich mir den in den Sourcen selbst nachbauen, oder eben das Maskieren von tm_hour entfernen.

    Entweder habe ich da noch einen Fehler in meinem Code, den ich nicht erkenne, oder da stimmt im Stack was nicht. Liege ich da richtig?

    Für mich wäre es in diesem Fall auch völlig ausreichend die 3 Byte direkt auszulesen, nur dazu fehlen mir allerdings die Coding Skills. Es hapert da am Verständnis der notwendigen Typ-Definitionen / Umwandlung ...
    Ein Beispiel für das Abholen der 3 Bytes wäre super.

    Danke und Gruß
    Helmut

    Einen Kommentar schreiben:


  • mumpf
    antwortet

    Zitat von Ing-Dom Beitrag anzeigen
    als bytearray lesen und selber parsen...
    Nö, besser nachgucken, was genau beim Empfang vom Telegramm am KO passiert.

    Zitat von mobil750 Beitrag anzeigen
    KNX liefert aber nur 3 Byte und ich kann mir nicht vorstellen, dass der KNX Stack das dann richtig im Struct tm ablegt.
    Du hast doch die Sourcen, schau doch einfach nach:
    Code:
    int busValueToTime(const uint8_t* payload, size_t payload_length, const Dpt& datatype, KNXValue& value)
    {
        ASSERT_PAYLOAD(3);
        switch (datatype.index)
        {
            case 0:
                value = (uint8_t)((unsigned8FromPayload(payload, 0) >> 5) & 0x07);
                return true;
            case 1:
            {
                unsigned char hours = unsigned8FromPayload(payload, 0) & 0x1F;
                unsigned char minutes = unsigned8FromPayload(payload, 1) & 0x3F;
                unsigned char seconds = unsigned8FromPayload(payload, 2) & 0x3F;
                if (hours > 23 || minutes > 59 || seconds > 59)
                    return false;
                struct tm tmp = {0};
                tmp.tm_hour = hours;
                tmp.tm_min = minutes;
                tmp.tm_sec = seconds;
                value = tmp;
                return true;
            }
        }
        return false;
    }
    ​
    Da sieht man dann, dass man ein Time-value mit Dpt(10,1,1) abholen muss. Du hast wahrscheinlich Dpt(10,1,0) genommen.

    Gruß, Waldemar

    P.S.: Bitte Coding in Zukunft mit dem   [CODE] -Tag einbetten, nicht über quote, das kann man nicht lesen.

    Einen Kommentar schreiben:


  • mobil750
    antwortet
    Parsen ist kein Problem, aber wie bekomme ich die 3 Byte Payload in ein Byte Array? Hier setzen meine C-Kenntnisse aus.
    Könntest du mir da ein Code-Beispiel geben?

    Danke und Gruß
    Helmut

    Einen Kommentar schreiben:


  • Ing-Dom
    antwortet
    Workaround:
    als bytearray lesen und selber parsen...

    Einen Kommentar schreiben:


  • mobil750
    antwortet
    Hallo Waldemar,

    ja ich habe 2 unterschiedliche Callbacks. Ich sehe das Problem in der Struct tm. Die enthält alles Time und Date. KNX liefert aber nur 3 Byte und ich kann mir nicht vorstellen, dass der KNX Stack das dann richtig im Struct tm ablegt.

    Ich habe auch schon versucht 2 eigene Struct aufzumachen, die aus meiner Sicht die 3 KNX Bytes abdecken, das lässt sich dann aber nicht kompilieren.
    // DPT 10.001
    structknxTime {
    uint8_t seconds;
    uint8_t minutes;
    uint8_t hours;
    };

    // DPT 11.001 masks
    constuint8_t dayOfMonthMask = 0x1F;
    constuint8_t monthMask = 0x0F;
    constuint8_t yearMask = 0x7F;
    String dayString = "";
    // DPT 11.001
    structknxDate {
    uint8_t year;
    uint8_t month;
    uint8_t day;
    };



    //--------------------------------------------------------------
    voidcallbackDate(GroupObject&go) {
    structknxDatemyTime;
    bool success = false;
    int objectSize = 0;
    objectSize = go.valueSize();
    DEBUG_VERBOSE("callbackDate(%d): >>>>>>>>>> new KNX Date event received - objectSize = %d", loopCntr, objectSize);
    myTime = go.value();
    tmp_mday = myTime.tm_mday;
    tmp_month = myTime.tm_mon;
    tmp_year = myTime.tm_year;
    shortunsignedint subYear = tmp_year - 2000;
    DEBUG_VERBOSE("callbackDate(%d-0): >>>>>>>>>> new KNX Date event received - tmp_mday = %d; tmp_month = %d; subYear = %d", loopCntr, tmp_mday, tmp_month, subYear);
    currentDate = dayString + String(tmp_mday) + "." + String(tmp_month) + "." + String(subYear);
    DEBUG_VERBOSE("callbackDate(%d-1) new KNX DATE event received - %s", loopCntr, String(currentDate).c_str());
    #ifdef LCD
    writeLcdDate(currentDate);
    #endif
    // set job to update display
    success = jobQueue.enchain(TRIGGER_DISPLAY);
    DEBUG_VERBOSE("callbackDate(%d-2) - jobQueue - TRIGGER_DISPLAY: Job = %d\n", loopCntr, TRIGGER_DISPLAY);
    if (!success) {
    DEBUG_ERROR("callbackDate(%d-3) - jobQueue - TRIGGER_DISPLAY: ##### writing jobQueue failed!!! #####\n", loopCntr);
    }
    }

    //--------------------------------------------------------------
    voidcallbackTime(GroupObject&go) {
    structknxTimerxdTime;
    bool success = false;

    int objectSize = 0;
    objectSize = go.valueSize();
    DEBUG_VERBOSE("callbackTime(%d): >>>>>>>>>> new KNX TIME event received - objectSize = %d", loopCntr, objectSize);

    rxdTime = go.value();
    tmp_sec = rxdTime.tm_sec;
    tmp_min = rxdTime.tm_min;
    tmp_hour = rxdTime.tm_hour;
    tmp_wday = (rxdTime.tm_hour & dayMask) >> 5;
    DEBUG_VERBOSE("callbackTime(%d-0): >>>>>>>>>> new KNX TIME event received - tmp_wday = %d; tmp_min = %d; tmp_hour = %d; ", loopCntr, tmp_wday, tmp_min, tmp_hour);
    buildDayStr(tmp_wday);
    currentTime = String(tmp_hour) + ":" + String(tmp_min);
    DEBUG_VERBOSE("callbackTime(%d-1): new KNX TIME event received - %s", loopCntr, String(currentTime).c_str());
    #ifdef LCD
    writeLcdTime(currentTime);
    #endif
    ...


    Das endet dann immer in
    In file included from /Users/helric/Projekte/openKNX/openknx_taster_monochromes_display_sensoren/openknx_taster_monochromes_display_sensoren.ino:26 2:
    /Users/helric/Projekte/openKNX/openknx_taster_monochromes_display_sensoren/knx_events.h: In function 'void callbackDate(GroupObject&)':
    /Users/helric/Projekte/openKNX/openknx_taster_monochromes_display_sensoren/knx_events.h:32:21: error: no match for 'operator=' (operand types are 'knxDate' and 'KNXValue')
    32 | myTime = go.value();
    | ^
    In file included from /Users/helric/Projekte/openKNX/openknx_taster_monochromes_display_sensoren/openknx_taster_monochromes_display_sensoren.ino:18 9:
    /Users/helric/Projekte/openKNX/openknx_taster_monochromes_display_sensoren/config.h:270:8: note: candidate: 'knxDate& knxDate:perator=(const knxDate&)'
    270 | struct knxDate {
    | ^~~~~~~
    /Users/helric/Projekte/openKNX/openknx_taster_monochromes_display_sensoren/config.h:270:8: note: no known conversion for argument 1 from 'KNXValue' to 'const knxDate&'
    /Users/helric/Projekte/openKNX/openknx_taster_monochromes_display_sensoren/config.h:270:8: note: candidate: 'knxDate& knxDate:perator=(knxDate&&)'
    /Users/helric/Projekte/openKNX/openknx_taster_monochromes_display_sensoren/config.h:270:8: note: no known conversion for argument 1 from 'KNXValue' to 'knxDate&&'
    In file included from /Users/helric/Projekte/openKNX/openknx_taster_monochromes_display_sensoren/openknx_taster_monochromes_display_sensoren.ino:26 2:
    /Users/helric/Projekte/openKNX/openknx_taster_monochromes_display_sensoren/knx_events.h:33:21: error: 'struct knxDate' has no member named 'tm_mday'
    33 | tmp_mday = myTime.tm_mday;
    | ^~~~~~~
    /Users/helric/Projekte/openKNX/openknx_taster_monochromes_display_sensoren/knx_events.h:34:22: error: 'struct knxDate' has no member named 'tm_mon'
    34 | tmp_month = myTime.tm_mon;
    | ^~~~~~
    /Users/helric/Projekte/openKNX/openknx_taster_monochromes_display_sensoren/knx_events.h:35:21: error: 'struct knxDate' has no member named 'tm_year'; did you mean 'year'?
    35 | tmp_year = myTime.tm_year;
    | ^~~~~~~
    | year
    In file included from /Users/helric/Projekte/openKNX/openknx_taster_monochromes_display_sensoren/openknx_taster_monochromes_display_sensoren.ino:26 2:
    /Users/helric/Projekte/openKNX/openknx_taster_monochromes_display_sensoren/knx_events.h: In function 'void callbackTime(GroupObject&)':
    /Users/helric/Projekte/openKNX/openknx_taster_monochromes_display_sensoren/knx_events.h:67:22: error: no match for 'operator=' (operand types are 'knxTime' and 'KNXValue')
    67 | rxdTime = go.value();
    | ^
    In file included from /Users/helric/Projekte/openKNX/openknx_taster_monochromes_display_sensoren/openknx_taster_monochromes_display_sensoren.ino:18 9:
    /Users/helric/Projekte/openKNX/openknx_taster_monochromes_display_sensoren/config.h:255:8: note: candidate: 'knxTime& knxTimeperator=(const knxTime&)'
    255 | struct knxTime {
    ...
    Ich bin im C-Bereich nur Anfänger und steh hier vor einem Scheunentor ...

    Gruß
    Helmut

    Einen Kommentar schreiben:


  • mumpf
    antwortet
    Hi Helmut,

    das ist prinzipiell schon richtig so. Dir ist aber klar, dass es 2 verschiedene KO sind (und damit auch 2 verschiedene callbacks), die das angesprochen werden?

    Gruß, Waldemar

    Einen Kommentar schreiben:


  • mobil750
    hat ein Thema erstellt Lesen der Uhrzeit DPT 10.001.

    Lesen der Uhrzeit DPT 10.001

    Hallo zusammen,

    ich habe ein Problem mit dem Einlesen der über den KNX Bus bereitgestellten Uhrzeit.

    Ich hatte ein Beispiel gefunden, in dem das Struct tm (https://cplusplus.com/reference/ctime/tm/) verwendet wird.

    voidcallbackTime(GroupObject&go) {
    structtmrxdTime;
    bool success = false;

    rxdTime = go.value();
    tmp_sec = rxdTime.tm_sec;
    tmp_min = rxdTime.tm_min;
    tmp_hour = rxdTime.tm_hour;
    tmp_wday = (rxdTime.tm_hour & dayMask) >> 5;
    ....

    Das Ergebnis ist allerdings immer 0 für sec, min, hour.

    Ich verwende das "gleiche" für das Datum und das funktioniert.

    oidcallbackDate(GroupObject&go) {
    structtmmyTime;
    bool success = false;
    myTime = go.value();
    tmp_mday = myTime.tm_mday;
    tmp_month = myTime.tm_mon;
    tmp_year = myTime.tm_year;


    Ich verstehe allerdings auch nicht, wie das Struct tm zu DPT 10.001 und DPT11.001 passt.

    Kann mir hier jemand ein Beispiel für DPT 10.001 geben?

    Danke und Gruß
    Helmut
Lädt...
X