Autor Thema: Developer Guide  (Gelesen 3096 mal)

Offline Syrex-o

  • Moderator
  • Sr. Member
  • ***
  • Beiträge: 791
  • FhemNative
Developer Guide
« am: 23 April 2020, 13:19:07 »
FhemNative Developer Guide:

Hallo zusammen,
Falls jemand Interesse hat eine eigene Komponente für FhemNative zu schreiben, der kann diesen Guide verwenden.
Jedoch sollte etwas Grudwissen über Angular, Ionic und Typescript vorhanden sein.

Für den Start:
1. Repository von Github ziehen:
git pull2. nach Development/FhemNative navigieren und
npm installDann habt ihr alle notwendigen Pakete und könnt starten.

Live Development:
FhemNative kann über electron als Live Umgebung funktionieren. So könnt ihr code schreiben, speichern und das Fenster wird automatisch neu geladen.
Dafür einfach in Development/FhemNative
npm run electron:devDann könnt ihr über das Electron Fenster bei view die Developer Tools anzeigen.

Komponente erstellen:
Als Beispiel dient im folgenden die Button Komponente.

Um eine Komponente in FhemNative zu erstellen, benötigt es nur ein paar Bausteine.
Erstellt einen Ordner in fhem-components mit dem Namen: fhem-"Name der Komponente"Anschließend werden 3 files benötigt:
- fhem-button.component.ts
- fhem-button.component.html
- fhem-button.component.scss

...component.ts
In der Typescript Datei wird definiert, wie die Komponente funktionieren soll.
Als erstes werden ein paar Imports von Angular benötigt:
import { Component, Input, NgModule, OnInit, OnDestroy } from '@angular/core';

Anschließend werden die default Komponenten und Directives importiert:
import { ComponentsModule } from '../../components.module';
Nun können die nötigen Services importiert werden, die eure Komponente benötigt.

Wollt ihr eine Komponente erstellen, die mit FHEM spricht, braucht ihr:
import { FhemService } from '../../../services/fhem.service';
Wollt ihr eine Komponente erstellen, die Einstellungen von FhemNative benötigt, braucht ihr:
import { SettingsService } from '../../../services/settings.service';
Wollt ihr eine Komponente erstellen, die native Events ausführen kann, braucht ihr:
import { NativeFunctionsService } from '../../../services/native-functions.service';
Es gibt noch weitere Services, die je nach bedarf importiert werden können.

Must have Input() Werte
Jede Komponente benötigt ein paar "Pflicht-Inputs":
@Input() ID: string;

// position information
@Input() width: string;
@Input() height: string;
@Input() top: string;
@Input() left: string;
@Input() zIndex: string;
So wird die Komponente in einzelnen Räumen gefunden und bewegt. Die ID erstellt sich automatisch beim anlegen.

Um FhemNative nun zu helfen, was eure Komponente so an Einstellungen braucht, dient die getSettings() Funktion.
So könnt ihr bestimmte Attribute definieren, die dann beim Komponente erstellen/bearbeiten in (inputs/switches/selects) umgewandelt werden.
static getSettings() {
return {
name: 'Button',
type: 'fhem',
inputs: [
{variable: 'data_device', default: ''},
{variable: 'data_reading', default: 'state'},
{variable: 'data_setReading', default: ''},
{variable: 'data_getOn', default: 'on'},
{variable: 'data_getOff', default: 'off'},
{variable: 'data_setOn', default: 'on'},
{variable: 'data_setOff', default: 'off'},
{variable: 'data_label', default: ''},
{variable: 'data_sendCommand', default: ''},
{variable: 'data_borderRadius', default: '5'},
{variable: 'data_borderRadiusTopLeft', default: '5'},
{variable: 'data_borderRadiusTopRight', default: '5'},
{variable: 'data_borderRadiusBottomLeft', default: '5'},
{variable: 'data_borderRadiusBottomRight', default: '5'},
{variable: 'data_iconSize', default: '20'},
{variable: 'icon_iconOn', default: 'add-circle'},
{variable: 'icon_iconOff', default: 'add-circle'},
{variable: 'bool_data_iconOnly', default: false},
{variable: 'bool_data_customBorder', default: false},
{variable: 'style_iconColorOn', default: '#86d993'},
{variable: 'style_iconColorOff', default: '#86d993'},
{variable: 'style_buttonColor', default: '#86d993'},
{variable: 'style_labelColor', default: '#fff'},
{variable: 'arr_data_style', default: 'standard,NM-IN-standard,NM-OUT-standard'}
],
dependencies: {
data_iconSize: { dependOn: 'bool_data_iconOnly', value: false },
data_borderRadius: { dependOn: 'bool_data_customBorder', value: false },
data_borderRadiusTopLeft: { dependOn: 'bool_data_customBorder', value: true },
data_borderRadiusTopRight: { dependOn: 'bool_data_customBorder', value: true },
data_borderRadiusBottomLeft: { dependOn: 'bool_data_customBorder', value: true },
data_borderRadiusBottomRight: { dependOn: 'bool_data_customBorder', value: true },
// neumorph dependencies
style_buttonColor: { dependOn: 'arr_data_style', value: 'standard' }
},
dimensions: {minX: 30, minY: 30}
};
}

Benennung:
Damit FhemNative die Komponente finden kann, müsst ihr einen Namen vergeben.
Der gleiche Name muss anschließend in component-loader.service.ts unter fhemComponents mit dem Pfad eingetragen werden.

Type:
Damit FhemNative erkennt, was für eine Komponente gerade erstellt/bearbeitet wird, vergebt ihr einen type
Entweder fhem oder style
Komponenten mit type: 'fhem' werden beim Komponenten erstellen/bearbeiten auf der letzten Seite geprüft, um einen Hinweis zu geben, ob das device und reading existiert.

Inputs:
Für jede Input variable benötigt ihr eine Input() variable in der Komponente.
Für die Variablen gilt folgendes:
  • data_ --> erstellt ein Input Feld, dass der User füllen kann
  • arr_data_ --> erstellt eine Select box, bei der ein wert erlauft ist (als default müssen alle Möglichen Werte als string mitgegeben werden)
  • bool_data --> erstellt einen Switch für true/false Werte
  • icon_ --> erstellt einee Select box, die als Icon Auswahl dient (als default kann jedes Icon aus settings.service verwendet werden)
  • arr_icon_ --> erstellt eine Select box, die mehrer Icons als Eingabe erlaubt
  • style_ --> erstellt eine Select box, für die Farbauswahl
  • arr_style_ --> erstellt eine Select box, die mehrere Farben als Eingabe erlaubt

Dependencies:
Dependencies sind nicht notwendig, können jedoch dabei helfen, bestimmte Einstellungen nur anzuzeigen, wenn sie benötigt werden.
Bsp. Es wird nur ein Icon benötigt, wenn der User einen bestimmten Style der Komponente ausgewählt hat.
Dependencies funktionieren so:
data_borderRadius: { dependOn: 'bool_data_customBorder', value: false }
Als Object Attribut wird dabei angegeben, welche Einstellung verborgen werden soll, wenn eine Bedingung nicht erfüllt ist.
In diesem Beispiel, wird die Option data_borderRadius nur angezeigt, wenn die Option bool_data_customBorder auf false steht
Als value Parameter kann ebenfalls ein Array mit mehreren Werten angegeben werden.

Dimensions:
Hier teilt ihr FhemNative mit, mit welchen Dimensionen die Komponente erstellt werden soll.
dimensions: {minX: 30, minY: 30}
...component.html
In der HTML Datei könnt ihr eure Komponenten-Struktur definieren.
Damit FhemNative die Komponente richtig rendern kann und alle zusätzlichen Funktionen (move/resize/click) ermöglicht, benötigt ihr den:
<fhem-component-container></fhem-component-container>
Der Container dient als Begrenzung der Komponente und benötigt ein paar Attribute:
[specs]="{ID: ID, device: data_device, reading: data_reading, available: true, connected: true}"In den specs könnt ihr definieren, wie der Container mit der Komponente umgehen soll.
In diesem Beispiel wird der Gerätename und das Reading übergeben. In Kombination mit den nachfolgenden Attribute findet FhemNative heraus, ob die Komponente gerendert werden soll.
Im Beispiel wird available: true und connected: true festgelegt.
Das bedeutet, dass die Komponente gerendert wird, wenn das device und reading vorhanden ist, oder eine Verbindung zu FHEM hergestellt ist.

Folgende Attribute können verwendet werden:
Wenn die Bedingung zutrifft, wird die Komponente gerendert.
  • available --> wenn device und reading vorhanden sind
  • connected --> wenn eine Verbindung zu FHEM besteht
  • offline --> Komponente wird immer sofort gerendert

Wenn eure Komponente von FHEM Werten abhängt, macht es sinn dem Container das device mitzugeben, sobald es verfügbar ist:
[fhemDevice]="fhemDevice"
Alle Informationen über die Position der Komponente werden einfach an den Container weitergeleitet:
[position]="{width: width, height: height, top: top, left: left, zIndex: zIndex}"
Zuletzt müsst ihr die Minimalbreite und Minimalhöhe definieren. Diese sorgen dafür, dass eine Komponente beim "resizen" nicht kleiner als diese Werte werden kann.

Anschließend sollte die eigentliche Komponenten-Struktur in einen eigenen Container mit einerclass gepackt werden. Diese wird in der scss benötigt.
<button class="button"></button>

...component.scss
In der scss Datei wird der Style der Komponente definiert.
Als erstes benötigt ihr dafür die class die ihr definiert habt:
:host{
    .button{
        width: inherit;
        height: inherit;
    }
}
Die width und height Optionen sorgen dafür, dass die Komponente die Größe des übergeordneten Containers übernimmt.
Anschließend könnt ihr normalen "Style-code" schreiben.

Verbindung zu FHEM:
Damit eure Komponente Informationen von FHEM erhalten kann, benötigt ihr die getDevice() Funktion.
this.fhem.getDevice(this.ID, this.data_device, (device)=>{
this.getState(device);
}).then(device=>{
this.getState(device);
});
So wird das device, dass vom User vergeben wurde von FHEM abgefragt. Die ID wird benötigt, damit die Komponente Updates erhalten kann.
Der then teil der Funktion wird ausgeführt, sobald die Informationen von FHEM abgeholt worden sind. Diese könnt ihr dann weiter verarbeiten.
Im callback kommen die Informationen an, wenn sich Werte des definierten Geräts geändert haben.

Ich hoffe das reicht erst einmal als Einstieg. Alles weitere ergänze ich mit der Zeit.

Beste Grüße und viel Spaß beim erstellen eigener FhemNative Komponenten.

Offline Syrex-o

  • Moderator
  • Sr. Member
  • ***
  • Beiträge: 791
  • FhemNative
Antw:Developer Guide
« Antwort #1 am: 18 November 2020, 20:57:34 »
Schon jemand, der sich Mal an einer eigenen Komponte versucht hat ?

P.S. Da gibt ein keine doofe Fragen

 

decade-submarginal