Hauptmenü

FTUI version 3

Begonnen von Bunnu, 25 Oktober 2020, 09:25:41

Vorheriges Thema - Nächstes Thema

grossmaggul

Zitatreadonly und handle="none" konnte ich ganz easy per CSS realisieren und etwas dünner sieht er besser aus.
Na, die Erfüllung meiner Wünsche geht aber auch recht fix. ;)
FHEM auf Debian Buster Server, 2 x nanoCUL868, 1xnanoCUL465; Homematic, MAX, MiLight, HUE,  2 x Gosund SP1

Eisix

@Thyraz: hab gerade den Kalender reingepackt. Sieht wirklich klasse aus!

OdfFhem

@setstate

Leider hatte ich am gestrigen Tag keine Möglichkeit mehr zu Kommentaren/Hinweisen/...; heute sollten die Antwortzeiten wieder deutlich kürzer sein.

ZitatVielen Dank für die Zuarbeiten!
Äußerst gern geschehen, wenn auch bis jetzt noch kein endgültiges Ergebnis vorliegt ...

ZitatLustigerweise hatte ich gestern auch ago schon fertig, bei till fielen mir dann aber die Augen zu.
Nach dem kurzen Austausch weiter oben wollte ich nicht noch mal nachfragen, wer jetzt was macht und hab das beginnende Wochenende einfach für einen kleinen Beitrag zum Gesamtprojekt genutzt. Beim nächsten Mal wird es "teamorientierter" laufen ...

ZitatIch überlege immer noch, wo eine Trennung in ago und agoFormat Sinn macht. Würde man ago mit anderen Nachfolgern als agoFormat nutzen? Könnte agoFormat andere Vorfunktionen verarbeiten? Ich finde keine sinnvollen UseCases. Deshalb habe ich es bei mir in einer Funktion gelassen.
Hier kann ich schon mal meine neuen Erkenntnisse bzgl. Deiner ago-Pipe mitteilen: meine Umsetzung vom Anfang des Jahres sah - abgesehen von const/let bzw. ~~ - quasi identisch aus; mit einem solchen Stand hatte ich auch am Wochenende begonnen. Die Trennung von ago und format beruht bei mir auf einigen Tests, wo ich feststellen musste, dass - ein passendes Reading vorausgesetzt - nur noch die Formatierung benötigt wird; daraufhin habe ich mich an eine Aufteilung wie toDate und format angelehnt.

ZitatDie Angabe tillFormat('%SSSSSSSSs','upper') finde ich sehr unübersichtlich. Habe ich jetzt 8xS oder nur 7xS getippt? Wofür steht %? Warum muss ich 'upper' angeben, wenn SSSSSSSS ja schon UpperCase ist.
Die kleingeschriebenen Platzhalter 'ssssssss','mmmmmm','hhhh','dd' bzw. 'dd','hh','mm','ss','h','m','s' entstammen gesammelten Angaben bzgl. "Elapsed time formats".
Damit werden 2 Theorien umgesetzt:


  • Darstellung der ersten Gruppe beruht auf der gesamte Zeitspanne (Sekunden/Minuten/Stunden/Tage im Bereich 0..<beliebig>).
    Normalerweise wird hier nur ein Platzhalter angegeben.
    z.B. 439742 Sekunden liefern: 'ssssssss'=439742 ; 'mmmmmm'=7329 ; 'hhhh'=122 ; 'dd'=5

  • Darstellung der zweiten Gruppe beruht auf der übriggebliebenen Zeitspanne (Sekunden/Minuten im Bereich 00..59, Stunden im Bereich 00..23, Tage im Bereich 0..<beliebig>).
    Hier werden normalerweise mehrere, aber vielleicht auch nur ein Platzhalter angegeben.
    z.B. 439742 Sekunden liefern: 'dd'=5 ; 'hh'=02 ; 'mm'=09 ; 'ss'=02 ; 'h'=2 ; 'm'=9 ; 's'=2

Damit wäre man eigentlich schon fertig, wäre da nicht die gängige Praxis der Einstreuung von Texten ...


timeFormat('[ dd days + hh:mm:ss ]','s')   liefert   '[ 5 day2 + 02:09:02 ]'

Klingt nicht gut, daher Erweiterung der Routine um reguläre Ausdrücke:

timeFormat('[ dd days + hh:mm:ss ]','s')   liefert   '[ 5 days + 02:09:02 ]'

Prima, eigentlich erledigt. Eine kleine Änderung des gewünschten Textes führt aber zu:

timeFormat('[ dd day(s) + hh:mm:ss ]','s')   liefert   '[ 5 day(2) + 02:09:02 ]'

Um auch diese (bislang) letzte Hürde zu überwinden, habe ich zusätzlich besser erkennbare Platzhalter integriert:

timeFormat('[ %DD day(s) + %HH:%MM:%SS ]','s','upper')   liefert   '[ 5 day(s) + 02:09:02 ]'

Ich habe noch einige andere Beispiele durchgespielt und die gewünschten/erwarteten Ergebnisse bekommen, aber wer weiß ...
Übrigens sind die Problemlösungsvorschläge nicht auf englische Texte beschränkt; deutsche Formulierungen wie 'seit', 'wir treffen uns in' oder 'der Besuch kommt in' führen ebenfalls  zu ansonsten interessanten/unbrauchbaren Darstellungen.

Wichtig ist, dass man erst mal nur die kleingeschriebenen Platzhalter nutzen kann; im Zweifel greift man aber auf die eindeutigeren Platzhalter zurück.

ZitatIch denke noch ein bisschen darüber nach und schreibe ein paar Klugscheißerkommentare an den PR
Kommentare - egal welcher Art - sind ja in der Regel zielführend ...


Hier berichte ich kurz, was ich noch geändert habe:


  • var nach const bzw. let überführt

  • Math.floor in ~~ überführt (kommt übrigens unverändert noch in knob.component.js, circle-menu.js, iro.js und vor allem chart.js vor)

  • let ret = format habe ich um String erweitert

  • Die ursprünglich benamte Pipe 'agoTillFormat' heisst jetzt allgemeiner 'timeFormat'

  • Ich habe auch die bis jetzt aufgelaufenen Änderungen bei den zu übertragenden Modulen eingearbeitet (bei Deiner ago-Pipe ging das natürlich nicht).


Abschließend noch zwei Fragen:


  • Ich nutze optionale Parameter für zumindest eine Pipe und das klappt auch soweit. Gebe ich aber beispielsweise den zweiten, optionalen Parameter als Parameter mit, muss man alle davorliegenden, optionalen Parameter mitgeben. Funktioniert es auch irgendwie, dass ich nur den einen optionalen Parameter mitgeben kann?

  • Angenommen, ich darf meinen 2.ten Versuch noch einstellen, muss ich den alten Versuch löschen und einen neuen anfordern? Oder kann ich den alten irgendwie anpassen?

OdfFhem

@Thyraz

ZitatAber die Idee eigene Pipes anbieten zu können klingt an sich cool.
Das fände ich auch gut. Allgemein anwendbare Pipes sollten logischerweise im allgemeinen Bereich liegen; spezielle Pipes vielleicht eher beim "Verursacher".

Zitat
Ist aber für setstate sicher ein etwas größerer Umbau.
Daran wäre ich auch nicht interessiert. Mein Hintergedanke war, dass es vielleicht ausreicht, die gewünschte Pipe beim Starten eines Widgets anzumelden - Werte sollten zu dem Zeitpunkt ja noch keine Rolle spielen und die benötigte Funktion liegt tatsächlich einzig im speziellen Widget-Modul und kann von ausserhalb angesprochen werden.



Es ging mir aber auch gar nicht um eine zwingend notwendige Realisierung, sondern eher um die Machbarkeit. Bei leichter Umsetzung würde dies z.B. allein schon zu einem schmalen Basissystem beitragen.

OdfFhem

@Thyraz

Hallo,

ich hatte heute Gelegenheit, mich ein wenig näher mit der calendar-Komponente zu beschäftigen. Und mir fiel sofort auf, dass fullcalendar in Deiner genutzen Version v5.3.2 (nur zur Info: aktuell ist mittlerweile v5.4.0) eine deutlich schlankere Auslieferform hat. Ich habe bis etwa Mitte Februar diesen Jahres im Rahmen von ftui3-Tests und EPG-Darstellung die damals aktuelle Version v4.3.1 genutzt und musste eine ganze Reihe von notwendigen Modulen einbeziehen. Allein diese Erfahrung macht schon Laune. Auch die etwas andere Art von Vereinigung verschiedener Devices unter einem gemeinsamen Hut finde ich interessant. Bei mir war es zum damaligen Zeitpunkt noch nach dem bekannten Widget-Prinzip gestrickt, bei dem alle relevanten Devices über ein gemeinsames Array verwaltet wurden.

Die Darstellung mit Deiner Kalender-Variante klappte ohne jegliche Probleme - sehr gut.

Die Frage meinerseits wäre jetzt, hast Du schon Ausbaupläne für diese Komponente?

Thyraz

Zitat von: OdfFhem am 22 November 2020, 09:42:31
@Thyraz
Das fände ich auch gut. Allgemein anwendbare Pipes sollten logischerweise im allgemeinen Bereich liegen; spezielle Pipes vielleicht eher beim "Verursacher".

Hi OdFhem. :)

Ich glaub mein Problem ist, dass mir gerade kein Beispiel für Component-spezifische Pipes einfällt und ich deswegen nicht so recht eine Meinung dazu äußern kann...
Hast du da ein Beispiel dafür parat?
Fhem und MariaDB auf NUC6i5SYH in Proxmox Container (Ubuntu)
Zwave, Conbee II, Hue, Harmony, Solo4k, LaMetric, Echo, Sonos, Roborock S5, Nuki, Prusa Mini, Doorbird, ...

Thyraz

#96
Zitat von: OdfFhem am 22 November 2020, 11:03:30
ich hatte heute Gelegenheit, mich ein wenig näher mit der calendar-Komponente zu beschäftigen. Und mir fiel sofort auf, dass fullcalendar in Deiner genutzen Version v5.3.2 (nur zur Info: aktuell ist mittlerweile v5.4.0)
Stimmt hatte die Version schon vor einiger Zeit runtergeladen, als ich dachte damit könnte man mal eine nette FTUI Komponente basteln.
Update ich mal bei Gelegenheit.

Zitat von: OdfFhem am 22 November 2020, 11:03:30
Auch die etwas andere Art von Vereinigung verschiedener Devices unter einem gemeinsamen Hut finde ich interessant. Bei mir war es zum damaligen Zeitpunkt noch nach dem bekannten Widget-Prinzip gestrickt, bei dem alle relevanten Devices über ein gemeinsames Array verwaltet wurden.
Da haben setstate und ich irgendwann mal darüber sinniert, wie man diese fehleranfälligen (aus Enduser-HTML-Sicht) Konfig-Würmer innerhalb eines HTML-Attributs besser löst.
Bei der Chart Komponente kam uns dann dieser Idee.

Es wird auch besser deutlich, was zur einer Signalkonfiguration (früher Arraywert) und was zum Chart selbst gehört.

Bei der Kalender Komponente hat sich das dann ja auch angeboten.

Zitat von: OdfFhem am 22 November 2020, 11:03:30
Die Darstellung mit Deiner Kalender-Variante klappte ohne jegliche Probleme - sehr gut.
Die Frage meinerseits wäre jetzt, hast Du schon Ausbaupläne für diese Komponente?

Jein, Pläne es auszubauen auf alle Fälle.
Wie weit ich hier gehen will und was so rein soll ist noch ein wenig unklar.

Ich denke eine Listenversion mit fixer Anzahl nächster Termine macht definitiv noch Sinn, ebenso eine Grid-Ansicht z.B. für den aktuellen Monat.

Ob ich auch eine Detailansicht für die Termine dazubasteln soll / will weiß ich noch nicht so recht.
Evlt. in Verwendung mit einer Popup Komponente wenn es sowas mal gibt. :P
Fhem und MariaDB auf NUC6i5SYH in Proxmox Container (Ubuntu)
Zwave, Conbee II, Hue, Harmony, Solo4k, LaMetric, Echo, Sonos, Roborock S5, Nuki, Prusa Mini, Doorbird, ...

OdfFhem

@Thyraz

Ich hatte zunächst scale in Verdacht, aber das war wohl doch eher eine Fehleinschätzung. Einen direkten Kandidaten habe ich nicht auf der Liste ...

@all

Kann ich in einer Komponente ein Reading subscriben, das für alle Einsatzfälle gleich ist und nicht von außen mitgegeben werden muss?

Einsatzszenario wäre bei mir z.B. eine EPG-Komponente, deren Aktualisierung eigentlich immer von innen gesteuert wird. Der Initialwert einer Property kennt zwar den Namen des Readings, nicht aber den Namen des Gerätes ...

setstate

Zitat von: OdfFhem am 22 November 2020, 09:01:00

Angenommen, ich darf meinen 2.ten Versuch noch einstellen, muss ich den alten Versuch löschen und einen neuen anfordern? Oder kann ich den alten irgendwie anpassen?


Wenn der Branch geändert wird, müsste sich auch der Pull Request aktualisieren. Also, ein neuer PR ist nicht nötig.

Vielen Dank für die ausführlichen Erklärungen. Das mit den eingestreuten Texten hate ich garnicht auf dem Schirm.

setstate

#99
Zitat von: OdfFhem am 23 November 2020, 07:02:03

Kann ich in einer Komponente ein Reading subscriben, das für alle Einsatzfälle gleich ist und nicht von außen mitgegeben werden muss?

Einsatzszenario wäre bei mir z.B. eine EPG-Komponente, deren Aktualisierung eigentlich immer von innen gesteuert wird. Der Initialwert einer Property kennt zwar den Namen des Readings, nicht aber den Namen des Gerätes ...

Das hatte ich auch schon gedanklich angerissen. Eine Komponente kann eine andere auf der Seite mit const elem = document.querySelector('<selector>') finden und dann mit elem.setAttribute('device', 'neuesDevice') beeinflussen.

Ein Unsubscribe und neu Subscribe für die kontinuierlichen Updates habe ich aber noch nicht eingebaut. Eine AdHoc Abfrage an FHEM ist aber möglich, um aktuelle Werte zu bekommen.

Eine Anwendung wäre zum Beispiel: Eine Select für das Gerät (z.B. Sonos1, Sonos2, Sonos3) - nach Änderung dessen wird ein zweiter Select neu geladen und zeigt zum Beispiel die Playlisten des Geräts an. Bei diesem UseCase würde ein einmaliger Update der Playlisten reichen. Hier bräuchte man nicht unbedingt einen Update.

Thyraz

#100
Zitat von: OdfFhem am 23 November 2020, 07:02:03
Ich hatte zunächst scale in Verdacht, aber das war wohl doch eher eine Fehleinschätzung.
Ja, das war an sich gerade so eine Geschichte bei der ich gedacht hatte, dass man das nicht nur in Blind oder Icon-Multicolor benötigt, sondern ein Standardfall ist den man öfter braucht.
Damit man Attribute wie min, max, invert nicht in jeder zweiten Komponente umsetzen muss.

An sich dasselbe wie die min, max Parameter beim homebridgeMapping für Alexa oder Homekit.
Also wenn man einen Ausgangswert in Fhem hat, der vom Wertebereich nicht zum erwarteten Eingangswert einer Komponente passt.
Dann kann ich das eben beliebig umskalieren.

Und an sich ist das ja genau der Einsatzzweck von den Pipes: Der User hat etwas, dass er umwandeln muss damit die Komponente es versteht (Oder eben andersrum für den Weg Komponente -> Fhem).
Für etwas anderes würde ich Pipes glaube ich auch nicht verwenden.

Oder anders ausgedrückt: Die Pipes gehören dem User, nicht der Komponente.

Sprich, wirklich komponentenabhängiger Code der etwas mit den Readingswerten anstellt, gehört meinem aktuellen Gefühl nach eher in die Komponente und nicht als Pipe zur Verfügung gestellt.
Denn die Pipes muss der User ja händisch befüllen, was die Konfiguration komplexer macht.

Aber wer weiß, evtl. kommt ja doch noch eine Komponentenidee bei der man das anders sieht... ;)

Zitat von: OdfFhem am 23 November 2020, 07:02:03
Kann ich in einer Komponente ein Reading subscriben, das für alle Einsatzfälle gleich ist und nicht von außen mitgegeben werden muss?

Hab es noch nicht benötigt, würde es aber so aus setstates Quellcode rauslesen:


import { fhemService } from './fhem.service.js';

...

  fhemService.getReadingEvents('MyDevice:myReading).subscribe(data => {
    console.log('New Value: ' + data.value);
  });



edit: Nachdem setstate schon geantwortet hat während ich noch getippt habe, bin ich mir jetzt nicht mehr so sicher ob das wirklich funktioniert (zumindest so wie gewollt ohne Nebenenffekte). :P
Fhem und MariaDB auf NUC6i5SYH in Proxmox Container (Ubuntu)
Zwave, Conbee II, Hue, Harmony, Solo4k, LaMetric, Echo, Sonos, Roborock S5, Nuki, Prusa Mini, Doorbird, ...

setstate

#101
Zitat von: Thyraz am 22 November 2020, 20:17:17
Ich glaub mein Problem ist, dass mir gerade kein Beispiel für Component-spezifische Pipes einfällt und ich deswegen nicht so recht eine Meinung dazu äußern kann...
Hast du da ein Beispiel dafür parat?

Wenn nicht, wäre das auch gut. Ich habe nämlich ein Problem mit dem Scope/Context der zusätzlichen Funktion. Noch kann ich mit dem (evil) eval arbeiten und muss den Pipe-String nicht selber parsen. Damit muss aber die Funktion im aktuellen Scope liegen, damit man sie ohne Präfix angeben kann, sonst würde es so aussehen: this.scale(...) oder FtuiSlider.scale(...)

Update:

Obwohl, mit einer weiter ganz bösen Art und Weise könnte man das erreichen:


window.scale = (minIn, maxIn, minOut, maxOut) => input => ftui.scale(input, minIn, maxIn, minOut, maxOut);


Aus gutem Grund ist das Bad Practice - man kommt schnell in Namenskonflikte (map, toInt usw.) und muss dann wieder mit kruden Namen hantieren: ftuiMap, ftuiToInt

Thyraz

@setstate hast du das mit getReadingEvents oben von mir gesehen?
Wäre das so ok, oder ist das aus irgendeinem Grund pfui? ;)
Fhem und MariaDB auf NUC6i5SYH in Proxmox Container (Ubuntu)
Zwave, Conbee II, Hue, Harmony, Solo4k, LaMetric, Echo, Sonos, Roborock S5, Nuki, Prusa Mini, Doorbird, ...

setstate

Grundsätzlich ist das okay. So subscribe't man sich die Readings.

Aktuelle Probleme:
Wenn das zuvor (beim Init) keiner gemacht hat, bekommt man keine Events, da das Device:Reading dann nicht im Filter für jsonlist und inform mit drin ist.
Also müsste man nach einer Änderung createFilterParameter() rufen, damit das aufgenommen wird und dann die WebSocket Verbindung neu aufbauen.
Weiterhin müsste man vorher das alte Reading unsubsciben. Dafür muss ich erst noch ein unsubscribe() in die Subject Klasse bauen.

Alles nix wildes, aber viele Baustellen noch.

Thyraz

Ok, dan vermerke ich das mal als "richtigen Weg", versuche es aber in naher Zukunft noch zu vermeiden.  ;D
Fhem und MariaDB auf NUC6i5SYH in Proxmox Container (Ubuntu)
Zwave, Conbee II, Hue, Harmony, Solo4k, LaMetric, Echo, Sonos, Roborock S5, Nuki, Prusa Mini, Doorbird, ...