Eigene valueTextConverter erstellen

Ein valueTextConverter wird für die Umwandlung  von Werten („value“ eines Geräte-Attributs, also eine Zahl) in menschenlesbaren Text („valueText“) und umgekehrt genutzt. Aktuell unterstützt LogoControl 2 Typen von ValueTextConvertern: „textMapping“ und „calculation“. In der Standard config.xml von LogoControl sind bereits folgende Beispiele der beiden Konvertertypen enthalten, welche die meisten Anwendungsszenarien abdecken sollten:

<valueTextConverter>
	<!-- Verschiedene Konverter zur Überführung von Value (ganzzahliger Rohwert aus der Logo) in ValueText (Anzeigewert für den Benutzer) -->
	<textMapping id="an_aus"><!-- Einfaches Text-Mapping für aus (0) und an (1) -->
		<valueText value="0" text="aus" />
		<valueText value="1" text="an" />
	</textMapping>
	<textMapping id="auf_zu">
		<valueText value="0" text="zu" />
		<valueText value="1" text="auf" />
	</textMapping>
	<textMapping id="rollo">
		<valueText value="0" text="geschlossen" />
		<valueText value="1" text="mittel" />
		<valueText value="2" text="offen" />
	</textMapping>
	<calculation id="minsec">
		<!-- Analogwert zu/von Zeitwert (Bsp: 4873 zu 81:13) -->
		<valueToText calculation="{Floor([value]/60)}:{if([value]%60>9,'','0')}{[value]%60}"/>
		<textToValue valueParseRegex="(\d+):(\d+)" calculation="{[value1]*60+[value2]}"/>
	</calculation>
	<calculation id="time">
		<!-- Analogwert zu/von Uhrzeit (4873 zu 13:09) -->
		<valueToText calculation="{Floor(LogoDec2Hex([value])/100)}:{if(LogoDec2Hex([value])%100>9,'','0')}{LogoDec2Hex([value])%100}" />
		<textToValue valueParseRegex="(\d+):(\d+)" calculation="{LogoHex2Dec([value1]*100+[value2])}" />
	</calculation>
</valueTextConverter>

Darüber hinaus besteht die Möglichkeit selbst eigene Konverter im Settings-Block der config.xml zu definieren und entsprechenden Geräte-Attributen zuzuweisen. Dies soll in diesem Artikel näher erläutert werden.

<textMapping>

Der textMapping Konverter funktioniert recht einfach: er definiert eine Liste von möglichen (Zahl-)Werten mit ihrer entsprechenden Text-Repräsentation (daher „mapping“). Aus 0 wird so z.B. „aus“ und aus 1 wird „ein“. Um einen textMapping Konverter anzulegen wird dafür im <valueTextConverter> Block einfach neues Element <textMapping> hinzugefügt. Die „id“ muss für alle Konverter eindeutig sein (egal ob <textMapping> oder <calculation> Konverter) und wird später für die Referenzierung des Konverters aus Attributen heraus verwendet.

<textMapping id="rollo">
	<valueText value="0" text="geschlossen" />
	<valueText value="1" text="mittel" />
	<valueText value="2" text="offen" />
</textMapping>

Anschließend können beliebig viele Wertepaare hinzugefügt werden. Dies geschieht durch Definition von <valueText> Elementen. Die Eigenschaft „value“ ist dabei der Wert und „text“ die entsprechende Text-Repräsentation.

<calculation>

Über den calculation Konverter kann der Rohwert („value“) eines Geräte-Attributs über beliebige mathematische Operationen in repräsentativen Text („valueText“) konvertiert werden oder im umgekehrten Fall, beim Schreiben des „valueText“ entsprechend Rückwärts in den Rohwert („value“) konvertiert werden. Für die Auswertung der mathematischen Formeln verwende ich die freie Lib NCalc. Neben mathematischen Operationen kann die Ausgabe auch noch in Grenzen formatiert werden, z.B. ein „°C“ hinter die Gleitkommazahl gehängt werden.

Folgendes Beispiel zeigt die Konvertierung für einen Temperatur-Wert, bei dem zusätzlich zum angehängten „°C“ auch noch ein Division durch 10 vorgenommen wird um die mathematischen Operationen zu demonstrieren:

<calculation id="temp">
	<!-- Analogwert zu/von Temperatur in °C -->
	<valueToText calculation="{[value]/10}°C"/>
	<textToValue valueParseRegex="([\d.,]+)\w*" calculation="{[value1]*10}"/>
</calculation>

Wichtig auch hier wieder: die „id“ der <calculation> muss für alle Konverter (egal ob <textMapping> oder <calculation> Konverter) eindeutig sein und wird später für die Referenzierung des Konverters aus Attributen heraus verwendet. Das <calculation> Element verfügt über zwei Kind-Elemente: <valueToText> und <textToValue>. Da für die Konvertierung von Rohwert in Text i.d.R. andere Operationen nötig sind als für die Umwandlung von Text in Rohwert müssen immer beide Operationen definiert werden.

<valueToText>

Hier erfolgt im Parameter „calculation“ der Ausdruck welcher von LogoControl bei der Umwandlung des Rohwerts in Text berücksichtigt wird. Der calculation Konverter unterscheidet hierbei zwischen Formatierungen (ergänzender Text) und mathematischen Ausdrücken. Letztere werden in geschweiften Klammern eingefasst, erstere als einfacher Text hinzugefügt. Die Variable [value] dient in der Formel als Platzhalter für den späteren Rohwert.

Für die Auswertung der mathematischen Ausdrücke verwendet LogoControl die Bibliothek NCalc  weshalb ich hier nur auf die dortige Referenz zur Syntax verweise. Es werden alle dort gelisteten Operationen und Funktionen unterstützt.

Zusätzlich sind 2 LOGO-Sonderfunktionen verfügbar, welche für die Umrechnung von Zeitangaben aus dem LOGO-eigenen Hex-Format benötigt werden: LogoDec2Hex und LogoHex2Dec (Details siehe Kasten „LOGO-Hex-Format“)

LOGO-Hex-Format
Die Logo speichert Uhrzeiten (z.B. der Wochenschaltuhr) relativ seltsam ab. Eine Zeit von 18:30 Uhr wird als Hex-Wert 0x1830 im VM-Speicher abgelegt, dies entspricht der Dezimalzahl 6192. Für die Visualisierung muss diese Dezimalzahl also wieder in Hex umgerechnet werden. Die Funktion LogoDec2Hex entspricht also einer einfachen Dec->Hex-Konvertierung mit einem Sonderfall: die Umrechnung wird nur durchgeführt, wenn der sich ergebende Hex-Wert ausschließlich aus Ziffern bestünde (kein A-F erlaubt!).  Ist dies nicht der Fall, liefert die Funktion -1 zurück. Dieser Kunstgriff ist nötig, da NCalc nicht mit Hex-Werten umgehen kann. Die Funktion LogoHex2Dec erledigt die Konvertierung in die entgegengesetzte Richtung.
<textToValue>

Dieses Element beschreibt die Umwandlung von Text zurück in einen Rohwert, welcher in der LOGO gespeichert werden kann. Dazu bedarf es zweier Parameter: „valueParseRegex“ und „calculation“.

„valueParseRegex“ ist für das „Herauspicken“ der relevanten Werte (neben z.B. überflüssigen Formatierungszeichen) aus einem Text zuständig, letzterer für die anschließende Umrechnung. Bei „valueParseRegex“ handelt es sich um einen Regulären Ausdruck, welcher Capture Groups zur Extraktion der relevanten Werte verwendet. Reguläre Ausdrücke hier genauer zu erklären wurde jetzt den Rahmen sprengen, fragt bei Interesse einfach Google 😉 Kurz gesagt: alles was zwischen zwei Klammern steht wird als Capture Group erfasst und bekommt eine Nummer (von 1 bis X). Diese Capture Groups stehen euch im „calculation“-Parameter als Variablen (value1 bis valueX) zur Verfügung.

„calculation“ ist wiederum der Ausdruck, welcher von LogoControl für die Umrechnung der in „valueParseRegex“ extrahierten Werte in einen gesamten Rohwert berücksichtigt wird. Es gilt hier die gleiche NCalc-Syntax wie schon im „calculation“ Parameter des <valueToText> Elements. Lediglich Text- und Formatierungszeichen sind hier natürlich nicht mehr erlaubt, da wir ja am Ende ein Zahl errechnen wollen.

 

Beispiel: <calculation> für Uhrzeiten der LOGO-Wochenschaltuhr
<calculation id="time">
	<!-- Analogwert zu/von Uhrzeit (4873 zu 13:09) -->
	<valueToText calculation="{Floor(LogoDec2Hex([value])/100)}:{if(LogoDec2Hex([value])%100>9,'','0')}{LogoDec2Hex([value])%100}"/>
	<textToValue valueParseRegex="(\d+):(\d+)" calculation="{LogoHex2Dec([value1]*100+[value2])}"/>
</calculation>