Meta

Aus FHEMWiki
Wechseln zu: Navigation, Suche

Development Module and Package Meta Data

Einleitung

Neben den für ein FHEM Modul notwendigen obligatorischen Metadaten (CommandRef, Kurzbeschreibung, Typ), gibt es in FHEM das Perl Package FHEM::Meta (oder kurz Meta.pm). Die Einbindung in ein FHEM Modul (= stellt Devices zur Verfügung) oder ein FHEM Package (= stellt Subroutinen für ein oder mehrere FHEM Module bereit) ermöglicht es, Informationen über das Modul in Form eines JSON Pod (auch META.json genannt) direkt in die Datei mit einzubetten. Darüber wird es möglich, diese Zusatzinformationen auch bereits auszuwerten und anzuzeigen, ohne dass ein Modul geladen oder verwendet wird. Beispielsweise kann ermittelt werden, welche Perl Module für die Nutzung des Moduls notwendig sind und ob eine bestimmte Version vorausgesetzt wird. Außerdem können Informationen über die Version des Moduls, die Historie, den Autor, für Supportanfragen und vieles weiteres hinterlegt werden.

Das Grundschema für die JSON Struktur basiert dabei auf der offiziellen CPAN::Meta::Spec Spezifikation, welche auch bei regulär veröffentlichten Perl Modulen verwendet wird. Das FHEM::Meta Package hilft dabei, diese JSON Informationen aus der Datei auszulesen und stellt diese im globalen %modules Hash des jeweiligen Moduls zur weiteren Verarbeitung bereit. Meta wertet dabei die in der Moduldatei (bei Modulen, die im SVN veröffentlicht sind, auch weitere Informationsquellen/-dateien des SVN) hinterlegten Maintenance und Supportdaten aus, so dass diese Informationen für sämtliche FHEM Module grundsätzlich bereitgestellt werden können. Meta erweitert die Standard Spezifikation dafür mit eigenen JSON Attributen, die spezifikationskonform im Namen mit x_ beginnen. Diese Art, zusätzliche Informationen über die Funktionalität eines Modules bereitzustellen, ohne dass ein Modul dafür tatsächlich geladen werden muss, steht jedem Modul als Erweiterung zur Verfügung. Es ist also denkbar, dass Module darüber bekanntmachen, welche Netzwerk-Protokolle sie beherrschen, wie bestimmte Geräte im Netzwerk gefunden werden können und mit welchen define-Parametern ein Gerät in FHEM angelegt werden kann. Hierzu gibt es erste Ansätze, die sich in Planung befinden.

Der FHEM Installer

Der FHEM Installer ist ein FHEM Modul, welches ein graphisches Interface für die Metadaten bereitstellt. Mit Hilfe des FHEM Installers werden die Metadaten auch für Module in den Speicher geladen, welche keine explizite Unterstützung eingebaut haben. Sobald man die Informationen für ein bestimmtes Modul oder Package abfragt, wird der Meta-Hash über die Funktion FHEM::Meta::Load() geladen. Für FHEM Module, die beim Start von FHEM bereits in Verwendung sind, werden die Metadaten automatisch im Voraus geladen, so dass sie zur Laufzeit zur Verfügung stehen. Es ist geplant, dass dies auch zur Laufzeit für Module, für die der Benutzer ein neues Device anlegt, geschieht.

Die Grundfunktion des FHEM Installer ist jedoch nicht die Bereitstellung der Metadaten, sondern die Auswertung derselben. In seiner weiteren Entwicklung soll er dabei unterstützen fehlende Systemkomponenten, die für die Nutzung eines FHEM Moduls notwendig sind, zu installieren und aktuell zu halten. Die Installation und Aktualisierung von Perl Modulen ist bereits jetzt in einer ersten Ausbaustufe möglich.

Stellt man am FHEM Installer Device das Attribut installerMode auf developer, dann werden einige weitere Get Befehle sichtbar, über die sich auch der Inhalt des kummulierten META.json Hashes anzeigen lässt. Dies ist oft hilfreich für ein initiales Verständnis, welche Informationen FHEM::Meta bereits über ein Modul gesammelt hat, bevor man diese über einen eigenen META.json Pod in der Moduldatei ergänzen oder verändern möchte.

Hinweis: Die Weiterentwicklung von FHEM::Meta ist stark an die weitere Entwicklung des FHEM Installer geknüpft. Dort geht es dann insbesondere darum, dass FHEM Module aus anderen Installationsquellen neben dem SVN die gleiche Metadaten einliefern können, insbesondere was Versionierung und Historie angehen. Dieses und mehr ist jedoch ein ganz eigenes Kapitel und soll deshalb für das Thema FHEM::Meta nur kurz erwähnt sein.


Der search-Befehl

Der FHEM Befehl search ist ein Wrapper, um den Get-Befehl search beim FHEM Installer Device im Schnellzugriff über die FHEM Befehlszeile aufzurufen. Hierüber lassen sich die Metadaten aller FHEM Module durchsuchen und ermöglicht so das Auffinden von FHEM Modulen für eine bestimmte Funktion oder ein Gebiet. FHEM Module, die einen META.json Pod bereitstellen, können dort Schlagworte hinterlegen, über die das Modul in der Suche gefunden werden können soll. FHEM::Meta generiert für Module, die über das SVN bereitgestellt werden, bereits einige Schlagworte basierend auf dem hinterlegten Support Forum in MAINTAINER.txt. Auch Der Modul Typ (helper|device|command) findet sich als eigenes Schlagwort wieder. Man erhält also Out-of-the-Box bereits eine ziemlich gute Kategorisierung über den Anwendungsbereich eines bestimmten Moduls und welche anderen Module noch in diesen Bereich fallen. Ein Modulname alleine hingegen lässt oftmals nicht auf die Funktionalität dahinter schließen, insbesondere wenn Hersteller- oder Produktnamen eine Rolle spielen, die man selbst bisher nicht kennt.


Erweiterung eines FHEM Moduls mit META.json Pod

Möchte ein Modulautor aktiven Support für FHEM::Meta einbauen, dann ist der erste Schritt die Bereitstellung eines META.json Abschnitts am Ende der Modul- oder Paketdatei. Dieser Abschnitt beinhaltet ein reguläres JSON Objekt. Deshalb empfiehlt es sich den Abschnitt vor dem hinzufügen über einen JSON Validator auf seine Syntax zu überprüfen. Ansonsten wird von FHEM::Meta beim laden eine entsprechende Meldung im FHEM Log ausgegeben und es werden keinerlei Metadaten mehr über das Modul bereitgestellt. Sobald ein META.json Abschnitt vorhanden ist, geht FHEM::Meta davon aus, dass dieses maßgeblich ist und wird deshalb nur noch Daten ergänzen, die dort nicht enthalten sind. Fehlt also ein valides META.json Objekt als Basis, so werden auch diese Ergänzungen nicht erfolgen und der Modulautor muss zunächst zwingend das JSON Gerüst korrigieren.

Für das Hinzufügen des META.json Abschnitts kann man mit der Beispieldatei contrib/META.json.txt als Ausgangsbasis starten. Die oben erwähnte Spezifikation sollte man einmal gelesen haben um zu verstehen, welches Format für ein Datenfeld gilt und welche Angaben die Spezifikation als zwingend vorschreibt. Es ist empfehlenswert alle dort als mandatory erwähnten Angaben in META.json anzugeben, auch wenn diese Informationen vielleicht teilweise in anderen Dateien in FHEM bereits vorhanden sind (gilt natürlich nur für Module, die auch über das SVN verteilt werden). Beispielsweise sollte eine (Kurz-)Beschreibung trotzdem enthalten sein. Der Grund ist, dass zumindest theoretisch dann auch andere 3rd-party Tools, die mit Perl Modulen hantieren, diese Informationen in vereinfachter Art ebenfalls auslesen und auswerten können. Diese Tools könnten darauf bestehen, dass sie eben diese als zwingend spezifizierten Attribute dort auch vorfinden. FHEM::Meta fügt fehlende Informationen zwar zur Laufzeit selbst hinzu, dies hilft jedoch anderen Tools, die das JSON Objekt direkt auswerten, eben nicht. Wie genau ein Modulautor dieser Empfehlung folgen möchte, ist ihm überlassen.

Die Inhalte aus der Beispieldatei oben sollten als Mindestvoraussetzung angesehen werden. Insbesondere der Abschnitt prereqs für verwendete Perl Module ist hier wichtig, da das Vorhandensein eines selben eine wesentlich schnellere Ladezeit der Metainformationen zur Folge hat, da die Abhängigkeiten nicht durch eine Analyse erfolgen muss. Das bedeutet jedoch auch, dass diese Informationen vollständig sein müssen und der Autor dafür verantwortlich ist, das diese stimmig sind. Als Hilfestellung, was man hier für sein Modul eintragen sollte, kann man sich über den FHEM Installer im oben erwähnten Developer-Modus das über das Analyseverfahren erzeugte META.json ansehen und dort den entsprechenden prereqs Abschnitt kopieren. Im Grunde werden dort alle "use" und "require" Aufrufe, die ein Modul macht, aufgeführt. Das schließt auch den Aufruf von Perl Builtin Funktionen wie "use strict;" oder ähnliches ein. Es ist empfehlenswert diese hier ebenfalls mit aufzuführen. Über die Metadaten kann man dann auch als FHEM Entwickler entsprechende Statistiken über die Code/Modul Qualität (so man die Nutzung von "use strict;" denn beispielhaft als positiv wirkend interpretieren möchte) fahren.

Hat man das JSON Objekt für sein Modul nun also fertig, dann kopiert man es in seine Moduldatei hinter den letzten commandRef Abschnitt und vor der Schlussformel =cut. Dabei wird das META.json Objekt von folgender Markierung umschlossen:

META.json Abschnitt

=for :application/json;q=META.json 00_myModule.pm
{ ... }
=end :application/json;q=META.json

Dabei ist 00_myModule.pm durch den Dateinamen der jeweiligen Moduldatei zu ersetzen. Auf diese Weise wird sichergestellt, dass eine Metainformation auch wirklich zu genau dieser Moduldatei dazugehört. Alle Informationen innerhalb des META.json sind im UTF-8 Format. Dies machen wir deshalb zusätzlich nochmals zum Beginn des =pod Abschnitts vor dem ersten CommandRef Eintrag deutlich:

Encoding

=pod

=encoding utf8


...


=cut

Ein komplettes Beispiel, wie sich der META.json Abschnitt in eine Moduldatei einfügt, zeigt die Datei contrib/META.json.full.txt. Für Fortgeschrittene sind dort außerdem weitere Beispieleinträge für Metadaten, die der FHEM Installer auswerten und verarbeiten kann.

Hat man nun also den META.json Abschnitt ordnungsgemäß hinzugefügt, kann man mit Hilfe des FHEM Installer überprüfen, ob die Daten richtig hinterlegt worden sind und geladen werden können.

Eigenständiges Laden der Metadaten aus einem FHEM Modul heraus

Ein FHEM Modul kann selbstständig die Unterstützung für das Laden der Metadaten in den %modules Hash einbauen, um diese unabhängig vom FHEM Installer zur Verfügung zu haben. Hierfür muss am Beginn der Moduldatei zunächst use FHEM::Meta; hinzugefügt werden und die X_Initialize(); Funktion am Ende um einen Initialisierungsaufruf erweitert werden:

X_Initialize

use FHEM::Meta;

sub X_Initialize($)
{
	my ($hash) = @_;
	...

	return FHEM::Meta::InitMod( __FILE__, $hash );
}

Die Metadaten werden dann beim Initialisieren des Moduls nach $modules{<TYPE>}{META} geladen und stehen dort bereit.

Anzeigen der Modulversion über FHEM::Meta

Im META.json Objekt kann eine Version des Moduls explizit in semantischer Form (beispielsweise v1.2.3) angegeben werden. Ist dies nicht der Fall, dann generiert FHEM::Meta eine eigene Versionsnummer auf Basis der Revisionsnummer aus dem Subversion Repository im $Id$ Abschnitt der Moduldatei. Dies gilt jedoch nur für Module, die auch tatsächlich über das SVN verteilt werden, ansonsten wird dieser Abschnitt ignoriert. Durch die Angabe der Versionsnummer im META.json Objekt wird es somit erstmals möglich, dass auch Module außerhalb des SVN mit einer einheitlichen Art der Versionierung auftreten können. Eine semantische Versionsnummer wird von FHEM::Meta automatisch über die Perl Builtin Module version in einen Float Wert umgewandelt, um nummerische Vergleiche zu ermöglichen.

FHEM::Meta bietet eine Funktion, um die essentiellen Metadaten zum Versionsstand eines Moduls als Internal mit dem Namen FVERSION anzuzeigen. Dafür kann man an den Beginn der X_Define() Funktion folgenden Aufruf setzen:

X_Define

sub X_Define($$)
{
	my ( $hash, $def ) = @_;
	return $@ unless ( FHEM::Meta::SetInternals($hash) );
	...
 
	return $error;
}

Zum aktuellen Zeitpunkt wird hierdurch lediglich das Internal FVERSION gesetzt. Dieses sieht dann beispielsweise so aus:

00_myModule.pm:v0.5.6-s19500/2019-05-30

Als Informationen sind hier verpackt:

  • Dateiname des Moduls inkl. Präfix
  • semantische Version (= version-Attribut in META.json vorhanden)
  • Subversion Revision (-s steht für "Subversion", danach folgt die Revisionsnummer des jeweiligen Commits)
  • das Release Datum (hier konkret das Check-in Datum in das SVN)

Für Module außerhalb des SVN werden diese Informationen entsprechend anders zusammengetragen oder müssen/können über das META.json Objekt bereitgestellt werden. Hierbei ist zu erwähnen, dass ein FHEM Modul erst dann als dem SVN zugehörig angesehen wird, wenn es einen Eintrag in MAINTAINER.txt hat. Fehlt dieser Eintrag, dann wird das Modul nicht als FHEM Core Modul behandelt, sondern als externes 3rd-party Modul.