Ankündigung

Einklappen
Keine Ankündigung bisher.

Wie Datums-/Uhrzeitwerte formatieren?

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

    Wie Datums-/Uhrzeitwerte formatieren?

    Hallo miteinander,

    nachdem ich Datumswerte in der Form 2015-12-01T07:55:00 vorliegen habe, möchte ich diese für die Darstellung in der CV brauchbar formatieren.

    Meine erste Idee war, das via strftime-Widget zu machen. Nur ist dieses wohl ausschliesslich dazu gedacht, die aktuelle Zeit darzustellen. Auf der Wikipage dazu finden sich auch keine anderen Hinweise. Supercool wäre es ja, wenn man im strftime-Tag einfach ein address-Tag einfügen könnte.

    Das normale CV-Format ist an printf(...) angelehnt und kann damit auch nichts anfangen, siehe hier. Hat jemand eine Idee, wie man Timestamps formatieren kann? Also wenn aus obigem Beispiel nur den Teil Stunden:Minuten oder nur den Monat haben möchte?
    Kind regards,
    Yves

    #2
    Wo liegen diese Strings vor, bzw. wie kommen die zur CV? Als KNX 14-Byte Objekt? Per OpenHAB?

    Woran ich spontan denken musste, war ein Mapping mit Formel zu nutzen. Da kann man ja alles machen was JavaScript so kann...
    TS2, B.IQ, DALI, WireGate für 1wire so wie Server für Logik und als KNX Visu die CometVisu auf HomeCockpit Minor. - Bitte keine PNs, Fragen gehören in das Forum, damit jeder was von den Antworten hat!

    Kommentar


      #3
      Hi,

      die Strings kommen vom openHAB Astro-Binding.
      Kind regards,
      Yves

      Kommentar


        #4
        Gut, OH kenne ich nicht wirklich. Ich glaube aber verstanden zu haben, dass dort die Infos als String ankommen.

        Wenn das nun ein neuer Datentyp ist, dann kann natürlich in der transform_oh.js hierfür ein Datentyp angelegt werden der diesen String in eine native JavaScript Zeit überträgt und das dann wie eine andere Zeit auch nutzen.

        Wenn es nur um die Darstellung geht, z.B. in einem Info-Widget, dann wäre das Mapping mit Formel eine Idee
        TS2, B.IQ, DALI, WireGate für 1wire so wie Server für Logik und als KNX Visu die CometVisu auf HomeCockpit Minor. - Bitte keine PNs, Fragen gehören in das Forum, damit jeder was von den Antworten hat!

        Kommentar


          #5
          Hallo Chris

          Zitat von Chris M. Beitrag anzeigen
          Gut, OH kenne ich nicht wirklich. Ich glaube aber verstanden zu haben, dass dort die Infos als String ankommen.
          Naja, das ist nicht wirklich eine OH-Besonderheit. Es handelt sich einfach um einen Datums- resp. Zeitangabe im ISO-8601 Format, siehe Wikipedia.


          Zitat von Chris M. Beitrag anzeigen
          Wenn das nun ein neuer Datentyp ist, dann kann natürlich in der transform_oh.js hierfür ein Datentyp angelegt werden der diesen String in eine native JavaScript Zeit überträgt und das dann wie eine andere Zeit auch nutzen.
          Ah, wieder was gelernt. Jetzt weiss ich, wie das Mapping der Datentypen zwischen OH und CV gemacht wird. So wie es aussieht, braucht es dann keinen neuen Datentyp, denn OH_DateTime gibt es schon. Als DateTime kann ich die Infos auch direkt von OH bekommen, von daher ist das schonmal kein Problem.

          Nur Frage ich mich gerade, wie ich die JavaScript-Zeit dann in der Ausgabe formatieren kann!? Wie müsste der entsprechende Block aussehen? Ideal wäre es natürlich, wenn die Formatierung nach üblichem Schema möglich wäre. Dann könnte man sowas schreiben, um lediglich die Uhrzeit im Format H:MM zu erhalten:

          Code:
          <info format="+%H:%M Uhr" class="value_right">
              <layout colspan="1"/>
              <address transform="OH:DateTime">Sunrise_Time</address>
          </info>

          Zitat von Chris M. Beitrag anzeigen
          Wenn es nur um die Darstellung geht, z.B. in einem Info-Widget, dann wäre das Mapping mit Formel eine Idee
          Das wird dann wohl eher entfallen, wenn es nach obigem Vorschlag machbar ist.
          Kind regards,
          Yves

          Kommentar


            #6
            Zitat von starwarsfan Beitrag anzeigen
            Naja, das ist nicht wirklich eine OH-Besonderheit. Es handelt sich einfach um einen Datums- resp. Zeitangabe im ISO-8601 Format
            Das der Inhalt einem Standard folgt ist mir schon klar (JavaScript kann den per Date.parse('2015-12-01T07:55:00') übrigens nativ versetehen).
            Aber die Übertragung ist OH spezifisch.

            Gundsätzlich läuft hier die Datenverarbeitung in mehreren Schichten:
            1. Das Backend überträgt den Wert "irgendwie"
            2. Die CV übersetzt diesen Wert in einen JavaScript nativen Wert/Datentyp basierend auf der per "transform" festgelegten Regel (die ist (normalerweise) Backend spezifisch und kann daher mit dem "irgendwie" etwas anfangen)
            3. Die CV wandelt den JavaScript Wert per mapping in einen anderen Wert (und ggf. Datentyp)
            4. Die CV stellt diesen Wert dar, ggf. mit "format"
            Zitat von starwarsfan Beitrag anzeigen
            Ah, wieder was gelernt. Jetzt weiss ich, wie das Mapping der Datentypen zwischen OH und CV gemacht wird. So wie es aussieht, braucht es dann keinen neuen Datentyp, denn OH_DateTime gibt es schon. Als DateTime kann ich die Infos auch direkt von OH bekommen, von daher ist das schonmal kein Problem.

            Nur Frage ich mich gerade, wie ich die JavaScript-Zeit dann in der Ausgabe formatieren kann!? Wie müsste der entsprechende Block aussehen? Ideal wäre es natürlich, wenn die Formatierung nach üblichem Schema möglich wäre. Dann könnte man sowas schreiben, um lediglich die Uhrzeit im Format H:MM zu erhalten:

            Code:
            <info format="+%H:%M Uhr" class="value_right">
            <layout colspan="1"/>
            <address transform="OH:DateTime">Sunrise_Time</address>
            </info>
            Das Format kann aber nur die normalen printf Formatierungen.

            Leider kann die CV zur Zeit nur relativ einfaches Handling von Datum und Uhrzeit. D.h. ein DPT 10.001 und 11.001 werden (zumindest bei dem knxd Backend) werden als normales Datum und Uhrzeit dargestellt. Eine extra Formatierung oder Interaktion (z.B. um eine Zeit für eine Schaltuhr zu setzen) hat bisher niemand implementiert.

            Von daher kann weiterhin ein Mapping interssant sein - da kann man nämlich selber das Date-Objekt in den persönlich passenden String übersetzen lassen (Schritt 3.). Voraussetzung ist natürlich, dass ein Date-Objekt vorliegt (also 2. funktioniert hat)
            TS2, B.IQ, DALI, WireGate für 1wire so wie Server für Logik und als KNX Visu die CometVisu auf HomeCockpit Minor. - Bitte keine PNs, Fragen gehören in das Forum, damit jeder was von den Antworten hat!

            Kommentar


              #7
              Hi Chris

              Zitat von Chris M. Beitrag anzeigen
              Das der Inhalt einem Standard folgt ist mir schon klar (JavaScript kann den per Date.parse('2015-12-01T07:55:00') übrigens nativ versetehen).
              Aber die Übertragung ist OH spezifisch.
              Na das ist doch schonmal was!


              Zitat von Chris M. Beitrag anzeigen
              Gundsätzlich läuft hier die Datenverarbeitung in mehreren Schichten:
              1. Das Backend überträgt den Wert "irgendwie"
              2. Die CV übersetzt diesen Wert in einen JavaScript nativen Wert/Datentyp basierend auf der per "transform" festgelegten Regel (die ist (normalerweise) Backend spezifisch und kann daher mit dem "irgendwie" etwas anfangen)
              An dieser Stelle kommt ein "richtiges" JavaScript-Date-Objekt an, denn in transform_oh.js steht an der entsprechenden Stelle das hier (gekürzt):

              Code:
                'datetime' : {
                  name : "OH_DateTime",
              ...
                  decode : function(str) {
                    if (str=="NaN" || str=='Uninitialized') return '-';
                    var date = new Date(str);
                    return date;
                  },
                },

              Zitat von Chris M. Beitrag anzeigen
              3. Die CV wandelt den JavaScript Wert per mapping in einen anderen Wert (und ggf. Datentyp)
              4. Die CV stellt diesen Wert dar, ggf. mit "format"

              Das Format kann aber nur die normalen printf Formatierungen.

              Leider kann die CV zur Zeit nur relativ einfaches Handling von Datum und Uhrzeit. D.h. ein DPT 10.001 und 11.001 werden (zumindest bei dem knxd Backend) werden als normales Datum und Uhrzeit dargestellt. Eine extra Formatierung oder Interaktion (z.B. um eine Zeit für eine Schaltuhr zu setzen) hat bisher niemand implementiert.

              Von daher kann weiterhin ein Mapping interssant sein - da kann man nämlich selber das Date-Objekt in den persönlich passenden String übersetzen lassen (Schritt 3.). Voraussetzung ist natürlich, dass ein Date-Objekt vorliegt (also 2. funktioniert hat)
              Da diese Voraussetzung gegeben ist, stellt sich die Frage, wie genau man so ein generisches Mapping definieren muss/kann!? Aus der Mapping-Doku werde ich dahingehend nicht schlau, dort ist nur das Mapping für fixe Werte bzw. Ranges beschrieben und eine Umrechnung via Formel ist ja auch nicht das, was ich erreichen möchte.
              Kind regards,
              Yves

              Kommentar


                #8
                Ich hab wohl immer noch nicht verstanden, was Du konkret brauchst.
                Hast Du jetzt bereits ein natives Date() Objekt?

                Wo ist dann das konkrete Problem?

                Meine täglich genutzte Config enthält:
                <info>
                <label>Uhrzeit</label>
                <address transform="DPT:10.001" mode="read">0/3/1</address>
                </info>
                <info>
                <label>Datum</label>
                <address transform="DPT:11.001" mode="read">0/3/0</address>
                </info>

                Damit bekomme ich Uhrzeit und Datum richtig angezeigt.

                Beim Mapping kannst Du als Formel normalen JavaScript Code verwenden, vgl. http://cometvisu.org/wiki/CometVisu/...ing/de#Formeln

                TS2, B.IQ, DALI, WireGate für 1wire so wie Server für Logik und als KNX Visu die CometVisu auf HomeCockpit Minor. - Bitte keine PNs, Fragen gehören in das Forum, damit jeder was von den Antworten hat!

                Kommentar


                  #9
                  Hallo Chris,

                  ok, dann hole ich nochmals etwas weiter aus.

                  Ich verwende OH als Backend und habe dort das Astro-Binding eingerichtet. Dieses stellt mir diverse Werte zur Verfügung, welche in der OH-Items-Konfig bspw. so abgebildet werden:

                  Code:
                  DateTime   Sunrise_Time        "Sunrise Time [%1$tH:%1$tM]"                          (Astro)   {astro="planet=sun, type=rise, property=start"}
                  ​DateTime   Sun_Eclipse_Total   "Sun total eclipse [%1$td.%1$tm.%1$tY %1$tH:%1$tM]"   (Astro)   {astro="planet=sun, type=eclipse, property=total"}
                  Das sind also DateTime-Items, welche im nativen OH-Gui so dargestellt werden, wie es in der dritten Spalte angegeben wurde. In der CV-Konfig habe ich sie dementsprechend so eingebunden:

                  Code:
                      <info format="%s Uhr" class="value_right">
                          <layout colspan="1"/>
                          <address transform="OH:DateTime">Sunrise_Time</address>
                      </info>
                      <info format="%s Uhr" class="value_right">
                          <layout colspan="2"/>
                          <address transform="OH:DateTime">Sun_Eclipse_Total_HR</address>
                      </info>
                  Laut dem bereits geposteten Code in transform_oh.js, werden aus den OH-Items native JavaScript-Date-Objekte gemacht. Soweit, so gut. Nur habe ich dann im GUI den vollen Output 2015-12-01T07:55:00 stehen und genau diesen möchte ich formatieren. Also bspw. nur das Datum als 1.12.2015 oder die Uhrzeit als 7:55 Uhr anzeigen. Das muss nun als Formel im Mapping in seine Bestandteile zerhackt und je nach gewünschtem Output wieder zusammengesetzt werden?
                  Kind regards,
                  Yves

                  Kommentar


                    #10
                    Ok, jetzt wird's bisschen klarer

                    Schau mal nach structure/pure/_common.js in die Zeilen 179ff. Dort wird als Special Case die Ausgabe von JavaScript Date-Objekten geregelt, so dass dort je nach transform eine Uhrzeit oder ein Datum raus kommt.

                    Solltest Du nun etwas anderes wollen (aber schon über die normalen Mechanismen wie transform="OHateTime" ein Date-Objekt haben), dann sollte ein Mapping, dass dieses Date-Objekt in einen String überführt, das gewünschte Ergebnis bringen.

                    Versuche mal ein Mapping wie (ungetestet!):

                    <mapping name="DateTime">
                    <formula>y = x.toLocaleDateString() + ' ' + x.toLocaleTimeString();</formula>
                    </mapping>
                    TS2, B.IQ, DALI, WireGate für 1wire so wie Server für Logik und als KNX Visu die CometVisu auf HomeCockpit Minor. - Bitte keine PNs, Fragen gehören in das Forum, damit jeder was von den Antworten hat!

                    Kommentar


                      #11
                      Hallo Chris

                      Zitat von Chris M. Beitrag anzeigen
                      Schau mal nach structure/pure/_common.js in die Zeilen 179ff. Dort wird als Special Case die Ausgabe von JavaScript Date-Objekten geregelt, so dass dort je nach transform eine Uhrzeit oder ein Datum raus kommt.
                      Schau ich mir an...


                      Zitat von Chris M. Beitrag anzeigen
                      Versuche mal ein Mapping wie (ungetestet!):

                      <mapping name="DateTime">
                      <formula>y = x.toLocaleDateString() + ' ' + x.toLocaleTimeString();</formula>
                      </mapping>
                      Damit kommt die CV nicht über den schwarzen Start-Screen hinaus und in der Konsole gibt es diese Fehlermeldung:

                      Code:
                      Uncaught TypeError: Cannot read property 'toLocaleDateString' of undefined
                      Kann es sein, dass da nicht korrekt erkannt wird, dass x ein Date-Object ist? Wie kann ich das explizit prüfen?
                      Kind regards,
                      Yves

                      Kommentar


                        #12
                        Ja, dass kann sein. V.a. das direkt nach dem Initialisieren da noch kein Date liegt. Versuch daher mal:
                        x.constructor === Date ? x.toLocaleDateString() + ' ' + x.toLocaleTimeString() : x
                        TS2, B.IQ, DALI, WireGate für 1wire so wie Server für Logik und als KNX Visu die CometVisu auf HomeCockpit Minor. - Bitte keine PNs, Fragen gehören in das Forum, damit jeder was von den Antworten hat!

                        Kommentar


                          #13
                          Hi

                          Zitat von Chris M. Beitrag anzeigen
                          Ja, dass kann sein. V.a. das direkt nach dem Initialisieren da noch kein Date liegt. Versuch daher mal:
                          x.constructor === Date ? x.toLocaleDateString() + ' ' + x.toLocaleTimeString() : x
                          Hm, klappt leider genausowenig. Habe auch noch etwas experimentiert, bspw. (nach Google-Suche) so:

                          Code:
                          [COLOR=#E8BF6A][FONT=Courier New]<formula>[/FONT][/COLOR][COLOR=#A9B7C6][FONT=Courier New]y = Object.prototype.toString.call(x) === "[object Date]" ? x.toLocaleDateString() + ' ' + x.toLocaleTimeString() : x ;[/FONT][/COLOR][COLOR=#E8BF6A][FONT=Courier New]</formula>[/FONT][/COLOR]
                          Das gibt keinen Fehler aber es wird wieder der volle String dargestellt. Von daher ist er in den Else-Zweig gelaufen. Werde das mal so laufen lassen und schauen, ob sich da etwas ändert, wenn das Item aktualisiert wird...
                          Kind regards,
                          Yves

                          Kommentar


                            #14
                            Mein Ansatz war schon fast richtig - hatte nur übersehen, dass wenn "x" undefiniert ist es auch kein x.constructor gibt...

                            => Bei mir funktioniert nun (man beachte das Escapen des "&" im XML):
                            Code:
                                  <mapping name="DateTime">
                                    <formula>y = x &amp;&amp; x.constructor === Date ? x.toLocaleDateString() + ' ' + x.toLocaleTimeString() : x;</formula>
                                  </mapping>
                            ...
                                <info mapping="DateTime">
                                  <label>Uhrzeit</label>
                                  <address transform="DPT:10.001" mode="read">0/3/1</address>
                                </info>
                                <info mapping="DateTime">
                                  <label>Datum</label>
                                  <address transform="DPT:11.001" mode="read">0/3/0</address>
                                </info>
                            TS2, B.IQ, DALI, WireGate für 1wire so wie Server für Logik und als KNX Visu die CometVisu auf HomeCockpit Minor. - Bitte keine PNs, Fragen gehören in das Forum, damit jeder was von den Antworten hat!

                            Kommentar


                              #15
                              Hi Chris,

                              cool, freut mich zu hören. Ich hab's bei mir nun auch so eingetragen, sehe aber noch immer den vollen String. Werde mal ein wenig abwarten, um eine echte Änderung der Werte zu haben.
                              Kind regards,
                              Yves

                              Kommentar

                              Lädt...
                              X