(FHEM) FTUI 3

Aus TippvomTibb
Zur Navigation springen Zur Suche springen

Allgemeines

Seit 2000 (Beginn noch unbestaetigt) gibt es eine neue Variante 'FHEM Tablet User Interface Version 3', oder kurz FTUI3 genannt.

Der Entwickler hat seine bisherige Arbeit bei Github eingestellt. Es gibt keine offizelle Release, also alles noch 'Under Construction'

UI builder framework for FHEM — http://fhem.de/fhem.html with a clear intention: Keep it short and simple!
FTUI 3 uses Web Components technologies in pure ES2020 javascript.

Diese zwei Aussagen und mein Eindruck, dass die Version 2 doch recht sperrig ist, haben mich dazu bewogen es mit FTIU3 mal zu probieren.

FTUI V2 hat bei mir zwar funktioniert, war aber einfach auf einem Tablet zu langsam. Bei einer Seite mit mehr als 20 Widgets konnte man dem mühsamen Aufbau zuschauen. An einen schnellen Seitenwechsel ist nicht zu denken. Da war mein ASCII-Tablet (MT701) aus den 2000er deutlich schneller.  

Im FHEM-Forum gibt es 118 Beitraege (Stand082022) zum Thema FTUI3

Ueberblick

Das Projekt ist ein ES2020-Web-Components-Framework für FHEM/Home Assistant; FTUI v3 ist nicht kompatibel mit FTUI v1/v2 und unterstützt mehrere Backends. ([GitHub][1])

Hauptstruktur

www/ftui/
├── ftui.js                         Startdatei
├── modules/
│   ├── ftui/
│   │   ├── ftui.app.js             App-Initialisierung
│   │   ├── backend.service.js      Backend-Router FHEM/HA
│   │   ├── fhem.service.js         Kommunikation mit FHEM
│   │   ├── ha.service.js           Home-Assistant-Backend
│   │   ├── ftui.binding.js         Binding-System [ ], ( ), [( )]
│   │   └── ftui.helper.js          Hilfsfunktionen, Pipes, Observer
│   ├── chart.js                    Chart-Bibliothek
│   ├── iro.js                      Farbpicker-Bibliothek
│   ├── hocon/                      Parser für map/step-ähnliche Syntax
│   ├── rangeable/                  Slider-Hilfsbibliothek
│   └── vanilla-notify/             Toast/Notify
└── components/
    ├── element.components.js       Macht aus einer normalen Webcomponent eine FTUI-kompatible Komponente mit Attributbindung, Defaultwerten, Shadow DOM und Change-Events.
    ├── button/
    ├── label/
    ├── icon/
    ├── grid/
    ├── row/
    ├── column/
    ├── tab/
    ├── view/
    └── (insgesamt 37 siehe unten)

Die zentrale Komponenten-Ladung passiert dynamisch: `ftui.app.js` sucht unbekannte `ftui-*` Elemente und lädt daraus automatisch Dateien nach dem Muster `components/<gruppe>/<name>.component.js`. ([GitHub][2])

Kernprogramme

Tabelle TODO

| Datei | Aufgabe | Abhängigkeiten |

| -------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------- |

| `ftui.js` | Einstiegspunkt. Lädt `ftui.app.js`, setzt `window.ftuiApp`, startet `init()` und registriert Online/Offline/Visibility/Error-Handler. | `ftui.app.js` |

| `ftui.app.js` | Liest Meta-Tags, bestimmt `fhemDir`, lädt Komponenten, startet Binding und Backend. | `backend.service.js`, `ftui.binding.js`, `ftui.helper.js`, `vanilla-notify` |

| `backend.service.js` | Vermittler zwischen UI und Backend. Entscheidet: FHEM oder Home Assistant. Leitet Reads/Writes weiter. | `fhem.service.js`, `ha.service.js`, `ftui.helper.js` |

| `fhem.service.js` | FHEM-Kommunikation: `jsonlist2` Refresh, WebSocket/`inform`, `sendCommand`, CSRF-Handling, Reading-Cache. | `backend.service.js`, `ftui.helper.js` |

| `ftui.binding.js` | Parst `[attr]`, `(attr)`, `[(attr)]`, `@click`, Pipes wie `map`, `step`, `append`. Verknüpft Readings mit DOM-Properties. | `backend.service.js`, `ftui.helper.js`, `hocon` |

| `ftui.helper.js` | Utility-Funktionen: Regex-Matching, `map`, `step`, Datum, Zahlen, DOM-Helfer, `Subject` Observer. | keine zentrale Abhängigkeit |

| `ha.service.js` | Backend analog zu `fhem.service.js`, aber für Home Assistant.

| `ftui.helper.js` |

| `chart.js` | externe Chart-Bibliothek für FTUI-Chart-Komponenten.

| Chart-Komponenten |

| `iro.js` | externe Farbpicker-Bibliothek.

| Color-Komponenten |

| `rangeable/*` | externe Slider-Bibliothek.

| Slider/Range-Komponenten |

| `vanilla-notify/*` | Toast-Meldungen für Debug/Error.

| `ftui.app.js` |

Datenfluss

HTML:
<ftui-label [text]="RL_AZC:status2bit">

→ ftui.app.js erkennt ftui-label
→ lädt components/label/label.component.js
→ ftui.binding.js liest [text]
→ backend.service.js registriert Reading
→ fhem.service.js erzeugt Filter
→ fhem.service.js holt initial per jsonlist2
→ fhem.service.js öffnet WebSocket mit inform
→ Änderung in FHEM
→ WebSocket Event
→ Reading-Cache wird aktualisiert
→ Binding setzt label.text
→ DOM aktualisiert sich

FTUI verwendet für Eingaben/Ausgaben diese Richtungen:

[attr]     Backend → Widget
(attr)     Widget  → Backend
[(attr)]   Backend ↔ Widget
@click     JavaScript/Event → z.B. sendFhem(...)

FHEM-Kommunikation

`fhem.service.js` macht drei Dinge:

1. Initialwerte:
   sendCommand("jsonlist2 <filter>")

2. Live-Updates:
   WebSocket auf:
   /fhem?XHR=1&inform=type=status;filter=...;fmt=JSON

3. Schreibbefehle:
   /fhem?cmd=<befehl>&fwcsrf=<token>&XHR=1

Der aktuelle Code enthält `ensureCSrf()` und `fetchCSrf()`: Vor `sendCommand()` wird ein CSRF-Token geholt, falls noch keines gesetzt ist. ([GitHub][3])

Komponentenprogramme

Es gibt insgesamt 37 Komponenten:

badge
button
cell
chart
checkbox
circlemenu
clock
colorpicker
column
content
departure
dropdown
grid
icon
image
input
knob
label
main
map
medialist
menu
meter
nav
popup
rotor
row
segment
slider
solar
speak
swiper
switch
tab
timeset
view
weather

Die Komponenten liegen jeweils als Web Component in `components/<name>/...component.js`.

Beispiele:

components/button/button.component.js
components/button/button-nice.component.js
components/label/label.component.js
components/icon/icon.component.js
components/grid/grid.component.js

Der View ist die Basis fuer:

  • Toolbar
  • Stage
  • Sheet
  • Section
  • Item

Für `button` zeigt das Repository z.B. `button.component.js`, `button-nice.component.js` und CSS. ([GitHub][4]) Für `label` gibt es `label.component.js`. ([GitHub][5])

Kleiner Demo-View mit FHEM-Kommunikation

<!DOCTYPE html>
<html>
<head>
  <meta name="fhemweb_url" content="http://fhem.clx.local:8083/fhem">
  <meta name="debug" content="4">
 
  <script src="ftui.js"></script>
  <link href="ftui.css" rel="stylesheet">
  <link href="themes/ftui-theme.css" rel="stylesheet">
</head>
  
<body>
  
<ftui-grid base-width="100" base-height="100" margin="10">
  
  <ftui-grid-tile row="1" col="1" width="4" height="2">
 
    <ftui-row>
      <ftui-label text="Rollladen AZC"></ftui-label>
 
      <ftui-icon
        [name]="RL_AZC:status2bit | map('0:user_icons\/fts_shutter_0,1:user_icons\/fts_shutter_updown,2:user_icons\/fts_shutter_40,3:user_icons\/fts_shutter_100')"
        size="3">
      </ftui-icon>
 
      <ftui-label [text]="RL_AZC:status2bit"></ftui-label>
    </ftui-row>
 
    <ftui-row>
      <ftui-button @click="sendFhem('set RL_AZC up')">Auf</ftui-button>
      <ftui-button @click="sendFhem('set RL_AZC stop')">Stop</ftui-button>
      <ftui-button @click="sendFhem('set RL_AZC down')">Ab</ftui-button>
    </ftui-row>
 
  </ftui-grid-tile>
  
</ftui-grid>
  
</body>
</html>

Was dabei passiert:

[text]="RL_AZC:status2bit"
→ registriert Reading RL_AZC-status2bit
 
[name]="RL_AZC:status2bit | map(...)"
→ liest dasselbe Reading
→ setzt abhängig vom Wert das Icon

@click="sendFhem('set RL_AZC up')"
→ ruft backendService.sendUpdate()
→ fhem.service.js sendCommand()
→ FHEM bekommt set RL_AZC up

Wichtigster Zusammenhang

ftui.js
└── ftui.app.js
    ├── lädt Komponenten dynamisch
    ├── startet FtuiBinding
    └── backend.service.js
        ├── fhem.service.js
        │   ├── jsonlist2
        │   ├── WebSocket inform
        │   ├── CSRF
        │   └── sendCommand()
        └── ha.service.js

[1]: https://github.com/knowthelist/ftui "GitHub - knowthelist/ftui: FTUI version 3 · GitHub"

[2]: https://raw.githubusercontent.com/knowthelist/ftui/master/www/ftui/modules/ftui/ftui.app.js "raw.githubusercontent.com"

[3]: https://raw.githubusercontent.com/knowthelist/ftui/master/www/ftui/modules/ftui/fhem.service.js "raw.githubusercontent.com"

[4]: https://github.com/knowthelist/ftui/tree/master/www/ftui/components/button "ftui/www/ftui/components/button at master · knowthelist/ftui · GitHub"

[5]: https://github.com/knowthelist/ftui/tree/master/www/ftui/components/label "ftui/www/ftui/components/label at master · knowthelist/ftui · GitHub"

Custom HTML Tags

Einstieg

Das ganze Framework arbeitet mit eigenen HTML-Tags die alle mit <ftui-...> eingeleitet werden.

Mit meinem fing-Befehl

alias fing='function _fing(){ find "$1" -type f -exec grep -l "$2" {} \; ; }; _fing'

kann ich relativ schnell herausfinden wo das custom-tag ueberall drinsteckt. z. B.

fhem:/opt/fhem/www/ftui # fing /opt/fhem/www/ftui "<ftui-button"
/opt/fhem/www/ftui/index.html
/opt/fhem/www/ftui/examples/meter.html
/opt/fhem/www/ftui/examples/colors.html
/opt/fhem/www/ftui/examples/button.html
/opt/fhem/www/ftui/examples/circlemenu.html
/opt/fhem/www/ftui/examples/badge.html
/opt/fhem/www/ftui/examples/swiper.html
/opt/fhem/www/ftui/examples/binding.html
/opt/fhem/www/ftui/examples/button-nice.html
/opt/fhem/www/ftui/examples/tab.html
/opt/fhem/www/ftui/examples/speak.html
/opt/fhem/www/ftui/examples/icon.html
/opt/fhem/www/ftui/examples/popup.html
/opt/fhem/www/ftui/examples/themes.html
/opt/fhem/www/ftui/examples/grid.html
/opt/fhem/www/ftui/examples/contents/content-view2.html
/opt/fhem/www/ftui/examples/contents/mobile-shutter.html
/opt/fhem/www/ftui/examples/contents/mobile-view-sonos.html
/opt/fhem/www/ftui/examples/mobile_full.html
/opt/fhem/www/ftui/examples/label.html
/opt/fhem/www/ftui/components/button/button-nice.component.js

Neben den 3 Dateien

ftui.js
ftui.css

index.html

gibt es noch 5 Verzeichnisse

components
modules
themes
icons
examples

Das Verzeihnis components enthaelt die Definitionen der Custom-Tags. Modules weisz ich noch nicht.

Themes und icons enthalten das was man erwartet, bis auf die Datei demo.html. Mit deren Hilfe werden alle Icons angezeigt.

http://fhem.clx.local:8083/fhem/ftui/icons/demo.html

Inhalt

Neben den 3 Dateien

ftui.css
ftui.js
index.html

verteilt sich der Rest auf 5 Verzeichnisse

compnents
modules

icons
themes

examples


In components befinden sich alle Kompnenten die per Tag benutzt werden koennen. Die Bedeutung von modules ist mir noch unklar.

In themes und icons steckt genau das drin was man vermutet, auszer in icons gibt es noch eine demo.html

http://fhem.clx.local:8083/fhem/ftui/icons/demo.html


ftui.js

Mit 1326 Bytes ja richtig bescheiden.

TODO


Tag-List

Die eckigen [] und runden () Klammern um die Attribute sind die Kurzformen von get-value und set-value.

Aus <ftui-label get-color="dummy1:color">demo</ftui-label>   wird dann <ftui-label [color]="dummy1:color">demo</ftui-label> wenn die Farbe aus dem FHEM-Device dummy1 das Reading color uebernommen werden soll.
Aus <ftui-button set-value="dummy1"></ftui-button> wird dann <ftui-button (value)="dummy1"></ftui-button> wenn der (?) Wert des FHEM-Devices dummy1 gesetzt werden soll.

Es funktioniert auch Hin- und Rueckweg kombiniert.

Aus <ftui-button getset-value="dummy1"></ftui-button> wird dann <ftui-button [(value)]="dummy1"></ftui-button> In dem Beispiel aus der Doku kann ich aber nicht mehr die Funktion erkennen.


Local Bindung und Events

Die schiebe ich mal nach hinten.

Pipes

Pipes sind recht hilfreich wenn der Wert aus einem FHEM-Device-Reading und der Wert fuer das FTUI-Attribut nicht kompatibel sind. Dann kann man durch die Pipes eine Anpassung realisieren.


   part(number)
   toDate(string)
   toBool(string|number)
   toInt(number)
   format(string)
   round(number)
   add(number)
   multiply(number)
   divide(number)
   replace(find, replace)
   map('in1:out1,in2:out2,...')
   step('1:ok,6:warning,10:alert')
   scale(minIn, maxIn, minOut, maxOut)

Formatierung/Layout

Die Breite eines ftui-grid-tile wird im ftui-grid (Parent) berechnet
→ über base-width, width, margin
→ und dann als CSS (grid/flex/inline-style) umgesetzt

Die Breite der Grid-Tiles wird irgendwie falsch berechnet. Dadurch entsteht faelschlicherweise eine leere Flaeche an der rechten Seite. Siehe (FHEM) FTUI 3 Components.


Alignment and margins can be changed by the attributes

   align-item (top, bottom, left, right, center, around, stretch)
   margin
   padding


   Tab      <ftui-tab view="View1" title="Home" active>
            <ftui-tab fill="clear" direction="vertical" view="View1" title="Tab1" active>
            <ftui-tab-view id="View1" [hidden]="ftuitest | isNot('1')"> 
            <ftui-tab-title text-align="left"></ftui-tab-title> 
            <ftui-segment [(value)]="ftuitest">


   Grid     <ftui-grid base-width="150" base-height="120">
            <ftui-grid base-width="75" base-height="75" shape="round" margin="2">
            <ftui-grid-tile row="1" col="1" height="1" width="3">
            <ftui-grid-tile row="1" col="1" height="1" width="4" color="translucent">
            <ftui-grid-tile row="3" col="3" height="1000" width="1" color="red">
            <ftui-grid-header>ROUND</ftui-grid-header>


   Circlemenu <ftui-circlemenu circle-radius="4" keep-open>
               <ftui-circlemenu keep-open direction="horizontal-right" opacity="0.2">


   Row <ftui-row align-items="center" class="size-3"><ftui-row align-items="top" margin="1" width="80%" height="33%">
       <ftui-row color="ok-warning-alert">ok-warning-alert</ftui-row>
       <ftui-row slot="end" align-items="stretch"><ftui-row color="red">red</ftui-row>
   Column  <ftui-column width="10%" height="70%">RGB</ftui-column>
           <ftui-column shape="round" color="light">light</ftui-column>
           class="big"  align-items="top|left|right|stretch|around|dark"  class="size-3"
  Cell  <ftui-cell class="size-7" style="height: 1250px">Tab2</ftui-cell> <ftui-cell slot="end" width="70px"><ftui-cell align-items="left">


  View<ftui-view-toolbar slot="header">    <ftui-view id="view-1"> <ftui-view-sheet shape="round">
  ViewStage <ftui-view-stage>
  ViewSection <ftui-view-section>
  ViewItem  <ftui-view-item target="details-1">Item 2-1</ftui-view-item>   wird haeufig mit FHEM-Devices kombiniert: Decke, Wand, Desktop, Fenster, ...
  Swiper <ftui-swiper scrollbar auto-play interval="2"> <ftui-swiper id="swiper3" dots auto-play interval="3"> <ftui-swiper id="swiper2" [(value)]=local:swiper2 dots> <ftui-swiper id="swiper1" scrollbar>

Design

Die sogenannten 'fixed theme colors' die zur Verfuegung stehen, koennen hier betrachtet werden.

Komponenten/Elemente

   Labelx
   Icon(x)
   Buttonx 
   SegmentedButton
   Knob
   Slider
   Checkbox
   Weather
   Dropdown
   Colorpickerx
   Imagex
   Badgex
   Clock
   Chartx
   Medialist
<ftui-slider margin="-34px 0 0 0" class="size-0"
<ftui-button (value)="ftuitest" states="0,4,10,45,75,90,100">Try</ftui-button>
<ftui-icon margin="-10px 0 0 0" name="circle" class="size-0"
<ftui-dropdown nochevron class="size-3"
<ftui-meter value="50" min="1" max="200">
<ftui-input [(value)]="ftuitest" min="1" max="100" type="number" size="4"></ftui-input>
<ftui-departure [list]="depDummy:HBF" icon="bus"  getinterval="120" station="Default" alternate>
<ftui-segment-button value="1">
<ftui-chart title="demo-chart" y-label="Heizung" y1-label="Außen" y-unit="°C" y1-unit="°C">
<ftui-chart-data label="Außen" color="warning" log="FileLog_AgroWeather" spec="4:AgroWeather.temperature"
<ftui-chart-controls units="day, week"></ftui-chart-controls>

Miscellaneous

Speakx

Attribute

Alle Elemente verfuegen ueber diese Attribute:


   hidden
   disabled
   readonly
   margin
   padding


Objekthierarchie

Hier ist ein praktischer **Objektbaum für FTUI v3** mit den typischen erlaubten Eltern-Kind-Beziehungen.

FTUI stellt Layout-Komponenten wie **Grid**, **Row**, **Column** und **Tab/View-Strukturen** bereit; die offiziellen Beispiele zeigen `ftui-grid` mit `ftui-grid-tile`, darin `ftui-grid-header`, `ftui-row` und `ftui-column`. ([GitHub][1])

<body>
└── ftui-tab-view              optional: eine Seite / ein Tab-Inhalt
    └── ftui-grid              Hauptlayout einer Seite
        ├── ftui-grid-tile     Kachel im Grid
        │   ├── ftui-grid-header   Kopfzeile/Titel der Kachel
        │   ├── ftui-row           horizontale Anordnung
        │   │   ├── ftui-column    vertikale Untergruppe
        │   │   │   ├── ftui-label
        │   │   │   ├── ftui-icon
        │   │   │   └── ftui-button
        │   │   ├── ftui-icon
        │   │   └── ftui-label
        │   ├── ftui-column        vertikale Anordnung
        │   │   ├── ftui-row
        │   │   │   ├── ftui-label
        │   │   │   └── ftui-icon
        │   │   ├── ftui-label
        │   │   └── ftui-button
        │   ├── ftui-label
        │   ├── ftui-icon
        │   └── ftui-button
        └── ftui-grid-tile
            └── ...

Die wichtigsten Regeln:

ftui-tab-view
└── darf enthalten:
    ├── ftui-grid
    ├── ftui-row
    ├── ftui-column
    └── normale Widgets / HTML
ftui-grid
└── sollte hauptsächlich enthalten:
    └── ftui-grid-tile
ftui-grid-tile
└── darf enthalten:
    ├── ftui-grid-header
    ├── ftui-row
    ├── ftui-column
    ├── ftui-label
    ├── ftui-icon
    ├── ftui-button
    └── andere Widgets
ftui-grid-header
└── sollte innerhalb von ftui-grid-tile stehen
ftui-row
└── darf enthalten:
    ├── ftui-column
    ├── ftui-label
    ├── ftui-icon
    ├── ftui-button
    └── andere Widgets
ftui-column
└── darf enthalten:
    ├── ftui-row
    ├── ftui-label
    ├── ftui-icon
    ├── ftui-button
    └── andere Widgets

Ein sauberes Beispiel (html):

<ftui-tab-view id="rollladen">
 
  <ftui-grid base-width="100" base-height="100" margin="10">
 
    <ftui-grid-tile row="1" col="1" width="4" height="2">
      <ftui-grid-header>Arbeitszimmer</ftui-grid-header>
 
      <ftui-column>
 
        <ftui-row>
          <ftui-label text="Rollladen"></ftui-label>
          <ftui-icon name="user_icons/fts_shutter_100"></ftui-icon>
        </ftui-row>
 
        <ftui-row>
          <ftui-button @click="sendFhem('set RL_AZC up')">Auf</ftui-button>
          <ftui-button @click="sendFhem('set RL_AZC stop')">Stop</ftui-button>
          <ftui-button @click="sendFhem('set RL_AZC down')">Ab</ftui-button>
        </ftui-row>
 
      </ftui-column>
    </ftui-grid-tile>
 
  </ftui-grid>
 
</ftui-tab-view>

Kurz gesagt: **`ftui-grid` ordnet Kacheln an, `ftui-grid-tile` ist die Kachel, `ftui-row` und `ftui-column` strukturieren den Inhalt der Kachel.**

[1]: https://github.com/knowthelist/ftui?utm_source=chatgpt.com "knowthelist/ftui: FTUI version 3"


Beispiele

Fangen wir mal klein an. Zu Beginn erst einmal das Grundgeruest.

FTUI Grundgeruest
<!DOCTYPE html>
<html>

<head>
  <!--
    /* FHEM tablet ui - FTUI */
    /**
    * UI builder framework for FHEM
    *
    * Version: 3.0.0
    *
    * Copyright (c) 2015-2021 Mario Stephan <mstephan@shared-files.de>
    * Under MIT License (http://www.opensource.org/licenses/mit-license.php)
    * https://github.com/knowthelist/ftui
    */
    -->
  <script src="ftui.js"></script>

  <link href="ftui.css" rel="stylesheet">
  <link href="themes/ftui-theme.css" rel="stylesheet">
  <link href="favicon.ico" rel="icon" type="image/x-icon" />

  <!-- avoid 300ms delay on click-->
  <meta name="viewport" content="width=device-width">

  <meta name="mobile-web-app-capable" content="yes">
  <meta name="toast_position" content="topLeft">


  <!-- verbose level 0-4 -->
  <meta name="debug" content="0">


  <title>FTUI Example</title>
</head>

<body>

</body>

</html>


Zum Testen habe ich jetzt umeinander die Code-Bloecke im <body> einkopiert.

HINWEIS: Um die Toast-Meldungen ab-/anzuschalten folgendes einfuegen
 <meta name="toast" content="0">
<ftui-button (value)="set dummyFTUI off" direction="vertical" color="current" fill="none" margin="-1em">
    <ftui-icon name="angle-up" class="size-1" height="90%"></ftui-icon>
    <ftui-label>DummyFTUI</ftui-label>
</ftui-button>

Da passiert nix, auszer dass 'DummyFTUI' auf dem Bildschirm steht, aber kein Button nix. Mal einen View drumbauen.

<ftui-view id="View1">
<ftui-button (value)="set dummyFTUI off" direction="vertical" color="current" fill="none" margin="-1em">
    <ftui-icon name="angle-up" class="size-1" height="90%"></ftui-icon>
    <ftui-label>DummyFTUI</ftui-label>
</ftui-button>
</ftui-view>

Immer noch nix.

In den Beispielen war oft auszenherum eine Grid.

Immer noch nix.

Ganz anderer Fehler!

Ich habe mein Beispiel in Verzeichnis examples abgelegt und folgenden Eintrag vergessen.

  <base href="../" />

D.h. erst ma muss man den Pfad zum FTUI-root Verzeichnis richtig einstellen.

<body>

            <ftui-icon name="window-shutter" class="size-4"></ftui-icon>
          <ftui-button @click="sendFhem('{setJalousieNight()}')" direction="vertical" color="current" fill="none"
                       margin="-1em">
            <ftui-icon name="angle-down" class="size-1" height="90%"></ftui-icon>
            <ftui-label>Nacht</ftui-label>
          </ftui-button>

</body>

Jetzt sieht man einen Button ueber die gesamte Bildschirmbreite wobei man den Pfeil nach unten und das Label Nacht bedienen kann und auch eine Aktion ausloest. Das Rollladen-Ikon ist nicht zum clicken. Es liegt auch auszerhalb des Button-Tags.

HINWEIS: Bei der Vergabe von eigenen ID-Namen immer alles in/nur Kleinbuchstaben und maximal einen Unterstrich.

So jetzt geht's an Grid, um Einfluss auf Position und Groesze der Komponenten nehmen zu koennen.

https://www.ionos.de/digitalguide/websites/webseiten-erstellen/css-grid/

HINWEIS: cols und rows gibt es auch nicht mehr beim Grid, nur noch base-width und base-height - mit jeweils 140 als default. « Letzte Änderung: 07 Februar 2022, 19:47:25 von setstate »

Das konnte ich aber so nicht direkt finden. Im Code (grid.component.js) steht im Konstruktor:

 constructor() {
   const properties = {
     minX: 0,
     minY: 0,
     baseWidth: 0,
     baseHeight: 0,
     margin: 8,
     resize: false,
     responsive: false,
   }; 

Weiter unten folgt dann in Kombination mit dem Attribut 'responsive':

    :host([responsive]) {
       display: grid;
       grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
       grid-template-rows: repeat(auto-fill, minmax(140px, 1fr));
       grid-auto-flow: dense;
       grid-auto-columns: 25%;
       grid-auto-rows: 25%;
       gap: ${this.margin}px;
       margin: ${this.margin}px;
     }
HINWEIS: Die Attributnamen werden im Code von der 'Bindestrichschreibweise' in die 'CamelCase-Schreibweise' gewandelt. Bsp (s.o.): base-width -> baseWidth

An dieser Stelle gebe ich mal nur meinen Testcode an. Alle Kombinationen der Einstellungen von base-height, base-width, margin, row, col, height und width anzugeben ist natuerlich nicht moeglich. Jeder sollte mal selbst rumspielen.

 <ftui-grid base-width="100" base-height="100" margin="0" shape="round">
      <ftui-grid-tile row="1" col="1" height="1" width="1" shape="round"
                      [color]="dummy.state | map('on:warning, off:ok')">
    <ftui-button (value)="set dummy" direction="vertical" color="current" fill="none" margin="-1em">
    <ftui-icon name="lightbulb-o" class="size-1" height="100%"></ftui-icon>
    <ftui-label>Dummy1</ftui-label>
         </ftui-button>
      </ftui-grid-tile>
            <ftui-grid-tile row="2" col="2" height="2" width="2" shape="round"
                      [color]="dummy.state | map('on:warning, off:ok')">
    <ftui-button (value)="set dummy" direction="vertical" color="current" fill="none" margin="-1em">
    <ftui-icon name="lightbulb-o" class="size-3" height="100%"></ftui-icon>
    <ftui-label>Dummy2</ftui-label>
         </ftui-button>
      </ftui-grid-tile>

<ftui-grid>
 <ftui-grid base-width="10" base-height="10" margin="0" shape="round">
      <ftui-grid-tile row="31" col="1" height="10" width="10" shape="round"
                      [color]="dummy.state | map('on:warning, off:ok')">
    <ftui-button (value)="set dummy" direction="vertical" color="current" fill="none" margin="-1em">
    <ftui-icon name="lightbulb-o" class="size-1" height="100%"></ftui-icon>
    <ftui-label>Dummy1</ftui-label>
         </ftui-button>
      </ftui-grid-tile>
            <ftui-grid-tile row="41" col="5" height="20" width="20" shape="round"
                      [color]="dummy.state | map('on:warning, off:ok')">
    <ftui-button (value)="set dummy" direction="vertical" color="current" fill="none" margin="-1em">
    <ftui-icon name="lightbulb-o" class="size-5" height="100%"></ftui-icon>
    <ftui-label>Dummy2</ftui-label>
         </ftui-button>
      </ftui-grid-tile>

<ftui-grid>>
HINWEIS: Fuer row und col sind sogar 0 und negative Werte moeglich. Mit z.B. margin=0 rutscht der Button aus dem Fenster. Die kleinste sinnvolle Groesze ist 1.
HINWEIS: Mit base-height und base-width kann man gemeinsam mit height und width die Groesze des Button und damit das Verhaeltnis zum Icon /Label beeinflussen.

Mal zum Rechnen von row und col wird 1 abgezogen und dann mit base multipliziert. height und width werden direkt mit der base multipliziert und ergeben die Groesze des Buttons. Ein Button 100:1 hat die gleiche Groesze wie ein 10:10. Zwei Grids auf einer Seite sind keine gute Idee, dann muss man noch mehr rechnen (s.o.). Fuer den Einstieg reicht mir das beim Layout. Jetzt machen wir mal noch Funktion dazu.

 <ftui-grid base-width="100" base-height="100" margin="0" shape="round">
      <ftui-grid-tile row="1" col="1" height="1" width="1" shape="round"
                      [color]="test | map('on:red, off:orange')">
    <ftui-button (value)="set test" direction="vertical" color="current" fill="none" margin="-1em">
    <ftui-icon [name]="test | map('on:lightbulb-on, off:lightbulb')" class="size-1" height="100%" [color]="test | map('on:yellow, off:primary')"></ftui-icon>
    <ftui-label>Dummy1</ftui-label>
     <ftui-content [content]="test:state"></ftui-content>
         </ftui-button>
      </ftui-grid-tile>
HINWEIS: Das state-Reading darf nicht angegeben werden. Siehe Beispiel oben. Weder beim set () noch beim get [] ist ein test.state angegeben.

Das kommt mir trotzdem komisch vor. Ich werde weiter testen.

Das Beispiel waechst weiter und die Anpassung meiner FHEM-Instanz an meine Tablets funktioniert praechtig.

Jetzt besteht der Wunsch nach passenden Icons. Mit

fing /opt/fhem/www/ftui "icons/"

dass in den Beipielen Repositpries von 'bas' und 'kleinklima' genutzt werden.

Bas ist unter zu finden und mit

wget -r -A svg -nd  -nH -l 1 https://github.com/basmilius/weather-icons/tree/dev/production/fill/svg

habe ich mir mal die svg in das Verzeichnis ftui/icons/wether/basmilius geholt. Wer will kann noch einen Softlink im Verzeichnis ftui/icons/weather mit dem Namen bas darauf legen.

ln -s basmilius bas

Es ist nicht schwer einzelne passende Icons zu finden, aber ein Paket herunterzuladen spart halt doch Zeit. Fundstellen bitte gerne in die Kommentare.

Die Icons in den Unterordnern eine eine map einzubinden hat mich Nerven gekostet.

Einen Eintrag

<meta name="ftui_iconpath" content="path/to/your/icons/">

oder

 <meta name="iconPath" content="path/to/your/icons/">

scheint es in FTUI nicht (mehr) zu geben und die Pfadangabe in der map-Umgebung wird nicht (richtig) ausgewertet.

Das Escapen den Slashes hat nur bedingt funktioniert. Erst das Quoten mit z. B. ` hat dann geklappt.

<ftui-icon [name]="RL_AZC:status2bit | map('0:`user_icons/fts_shutter_0`,1:`user_icons/fts_shutter_updown`,2:`user_icons/fts_shutter_40`,3:`user_icons/fts_shutter_100`')" size="3"></ftui-icon>

Kleiner Ausflug in mein KNX

FHEM unterstuetzt nur fogende Datentypen

dpt1
dpt1.000
dpt1.001
dpt1.002
dpt1.003
dpt1.004
dpt1.005
dpt1.006
dpt1.007
dpt1.008
dpt1.009
dpt1.010
dpt1.011
dpt1.012
dpt1.013
dpt1.014
dpt1.015
dpt1.016
dpt1.017
dpt1.018
dpt1.019
dpt1.021
dpt1.022
dpt1.023
dpt2
dpt232     ???
dpt3
dpt3.007
dpt5
dpt5.001
dpt5.003
dpt5.004
dpt6
dpt6.001
dpt7
dpt7.001
dpt7.005
dpt7.006
dpt7.007
dpt7.012
dpt7.013
dpt8
dpt8.005
dpt8.010
dpt8.011
dpt9
dpt9.001
dpt9.004
dpt9.005
dpt9.006
dpt9.007
dpt9.008
dpt9.009
dpt9.010
dpt9.020
dpt9.021
dpt9.024
dpt9.025
dpt9.026
dpt9.028
dpt10
dpt11
dpt12
dpt13
dpt13.010
dpt13.013
dpt14
dpt14.019
dpt14.027
dpt14.033
dpt14.056
dpt14.057
dpt14.068
dpt14.076
dpt16
dpt16.000
dpt16.001
dpt17.001
dpt18.001
dpt19

Fehler nach Update

Im "sendcommand" ist auf einmal der wfcsrf Parameter leer.

Fehlermeldung

fhem command failed syntaxerror: json.parse: unexpected end of data at line 1 column 1 of the json data

Spurensuche:

curl -i "http://127.0.0.1:8083/fhem?cmd=jsonlist2&XHR=1"

Antwort:

HTTP/1.1 400 Bad Request
Content-Length: 0
Cache-Control: no-cache, no-store, must-revalidate
X-FHEM-csrfToken: csrf_19345435345346
Content-Type: text/html; charset=UTF-8
<meta name="fhemweb_url" content="http://fhem.clx.local:8083/fhem">

In fhem.service.js wurde durch das Versionupdate die Zeilen:

    // init FhemService
    fhemService.setConfig(this.config);
    fhemService.debugEvents.subscribe(text => this.toast(text));
    fhemService.errorEvents.subscribe(text => this.toast(text, 'error'));
    this.fhemService = fhemService;

    // init Page after CSFS Token has been retrieved
    await fhemService.fetchCSrf()
    this.initPage();

    // call health check periodically
    setInterval(() => {
      this.checkConnection();
    }, this.config.updateCheckInterval * 60 * 1000);

ersetzt durch

    // initialize backend service
    await this.initBackends();

In initBackends steht folgendes:

  // initialize backend services
  async initBackends() {
    try {
      // Initialize backend service
      backendService.setConfig(this.config);
      backendService.debugEvents.subscribe(text => this.toast(text));
      backendService.errorEvents.subscribe(text => this.toast(text, 'error'));

      await this.initPage();

      // call health check periodically
      setInterval(() => {
        this.checkConnection();
      }, this.config.updateCheckInterval * 60 * 1000);
    } catch (err) {
      ftui.error('[ftuiApp] initBackends error - ' + err);
    }
  }

Der BackendService wurde erzeugt um auch die Anbindung an HA in einem Aufwasch zu realisieren. Es haette aber gereicht fhemService.setConfig(this.config); zu ersetzen. Stattdessen wurde

   this.fhemService = fhemService;

    // init Page after CSFS Token has been retrieved
    await fhemService.fetchCSrf()

gleich mit geloescht aber nicht ersetzt.

Nach der Korrektur von initBackends() in der ftui.app.js hatten meine Seiten wieder Zugriff auf FHEM.

  // initialize backend services
  async initBackends() {
    try {
      // Initialize backend service
      backendService.setConfig(this.config);
      backendService.debugEvents.subscribe(text => this.toast(text));
      backendService.errorEvents.subscribe(text => this.toast(text, 'error'));

      this.fhemService = fhemService;
      await fhemService.fetchCSrf()

      await this.initPage();

      // call health check periodically
      setInterval(() => {
        this.checkConnection();
      }, this.config.updateCheckInterval * 60 * 1000);
    } catch (err) {
      ftui.error('[ftuiApp] initBackends error - ' + err);
    }
  }

Request for Comments

Loading comments...