Zum Hauptinhalt springen

Beispiel 12 - Nichtlineare Werteskalierung

Aufgabe

Ein Sensorwert muss innerhalb verschiedener Wertebereiche mit verschiedenen Skalierungen und Offsets verarbeitet werden. In Python lässt sie die Verarbeitung bspw. wie folgt realisieren:

if raw <= 51:
processed = raw * 0.5
elif raw <= 66:
processed = raw * 1 + 0.33
elif raw <= 101:
processed = raw * 3 + 2.5
else:
processed = 0.0

Lösung

1. Erstellen einer Tabelle

Die folgende Tabelle sei unter dem Ressourcen-Tag "Tabelle" angelegt:

raw	scale	offset
0 2 0
51 0.5 0
66 1 0.33
101 3 2.5
999 1 0

2. Implementierung im Formeltext

_sensor = $'Your.Channel';

// select first row, where input value _sensor is less or equal value in key 'raw'
_idx = selectRow(_sensor, {table:'Tabelle', colSep:'[ \\t]+', key:'<=raw'});
_scale = getField(_idx, {table:'Tabelle', field:'scale'});",
_offset = getField(_idx, {table:'Tabelle', field:'offset'});

processed = _raw * _scale + _offset1;

Verwendete Funktionen

Erläuterung

Die Tabelle wird zeilenweise gelesen. Leerzeilen oder solche, die mit 3 gleichen "Linien"-Zeichen (hier z.B. '---') beginnen, werden übersprungen. Die Zeilen werden an dem definierten Trennzeichen (siehe colSep) auseinander geschnitten, vorne und hinten von überflüssigen Leerzeichen befreit und als Variant interpretiert. Die erste Zeile liefert die Bezeichnungen für die Spalten (= Felder). Alle weiteren Zeilen die Datenelemente zum Vergleichen oder Auslesen.

Diese Vorbereitung passiert nur ein einziges Mal mit einer selectRow() Funktion im Formeltext, danach steht die Tabelle unter dem gegebenen Namen allen weiteren Funktionen zur Verfügung. Die Angabe für den Spaltentrenner colSep: ';' ist optional. Als Default werden als Regular-Expression ein einzelnes Komma, Semikolon, Tabulator oder '|' akzeptiert. Die Angabe von anyKey ist ebenso optional und bezeichnet einen Tabelleneintrag (Text), der mit jedem angebotenen Schlüsselwert übereinstimmt.

Mit selectRow() wird nun in der Tabelle eine passende Zeile gesucht und deren Index als Ergebniswert zurückgegeben. Dazu wird der Schlüsselwert (hier _sensor) in dem mittels key definierten Feld gesucht. Da die Suche bei Änderung der Schlüsselwerte Zeilenweise von oben nach unten erfolgt, müssen die Einträge aufsteigend einsortiert werden.

Mittels der getField() Funktion werden aus der gleichen Tabelle passende Einträge aus der bezeichneten Spalte (field) ausgelesen.