Hallo zusammen,
der "Translator", den ich neulich gepostet habe, ist mittlerweile so verbessert, dass er eigentlich eine einfache Logikmaschine geworden ist. Viele einfache Dinge lassen sich damit per Wiregate-Plugin lösen.
Man spezifiziert eine beliebige Zahl von Logiken im Konfigurationsfile, und der Logikprozessor (=Wiregate-Plugin) abonniert die passenden GAs und führt bei eingehenden Telegrammen die entsprechenden Logiken aus. Auch mehrere Logiken für die gleiche GA sind kein Problem.
Hier ein Eindruck der Möglichkeiten:
1. Alle Werte, die auf einer GA gesendet werden, mit 2 multiplizieren und auf einer anderen GA weitergeben. Das kostet nur eine Zeile im Konfigurationsfile:
2. Aus einem relativen Dimmwert einen absoluten Dimmwert machen. Die Werte auf der ersten GA werden aufsummiert, das Ergebnis auf der anderen GA gesendet. Wieder nur eine Zeile im Konfigurationsfile:
$state enthaelt dabei das jeweils letzte Ergebnis, und das Minuszeichen... ist ein KNX-Geheimnis :-) .
3. Wie oben, aber das Ergebnis auf den Bereich 0-100 limitieren
4. Hier eine "Treppenlichtfunktion". Auf jeden Schreibzugriff auf die receive-Adresse wird 10min spaeter eine 0 an die transmit-Adresse (hier sind beide gleich) geschickt.
Verzoegert wird uebrigens nur das Senden, nicht das Ausfuehren der translate-Routine. Neu ist hier der "delay"-Parameter, ausserdem der Spezialfall, dass translate einfach eine Konstante als Rueckgabewert spezifiziert.
Bemerkungen:
* translate darf nur entweder eine Konstante oder ausführbarer Code (sub {...}) sein.
* Damit im Fall transmit==receive der Translator nicht auf sein eigenes Schreibtelegramm immer wieder antwortet, wird nur dann gesendet,
wenn Ergebnis!=Input oder Sender des empfangenen Telegramms!=0 (Wiregate).
Hier noch ein Feature, für das mir momentan kein Beispiel einfällt: analog der Klausel "delay=>600" oben gibt es auch die Spezifikation "transmit_only_on_request=>1". Diese bewirkt, dass das Ergebnis von translate GAR NICHT gesendet wird, sondern dass auf eine spätere Leseanforderung auf der transmit-Adresse mit dem berechneten Ergebnis geantwortet wird.
5. Eine Logik, die einem Lichtanschalten gleich einen Dimmwert hinterherfeuert, und zwar tags und nachts einen verschiedenen:
Die Variablen $day_of_week (Mo...So), $weekend (0 oder 1), $time_of_day ("08:34:02"), $hour_of_day ("08"), $day (1 falls zwischen 7 und 23 Uhr, 0 sonst) und $night (entsprechend umgekehrt) sind für diese Logiken vorbesetzt
6. Memory-Funktion. Für KNX-Geräte, die kein Auslesen ihres Statuswerts zulassen (z.B. MDT DaliControl bei Einzel-EVG-Ansteuerung). Sehr einfach:
Hier wird folgende Eigenschaft der Logik ausgenutzt: Wenn ein Write-Telegramm auf die Transmit-Adresse kommt, speichert der Logikprozessor den Wert immer automatisch ab. Eine Leseanfrage auf der transmit-GA hingegen wird immer mit dem letzten Wert (hier also dem gespeicherten) beantwortet. Eine receive-Adresse oder translate-Logik werden hier gar nicht gebraucht.
7. Eine einfache UND-Logik mit zwei Eingaengen. Falls ein Telegramm auf einer der beiden receive-GAs empfangen wird, wird die andere Adresse noch ausgelesen, die Logik ausgeführt und das Ergebnis auf der transmit-GA uebermittelt:
Neu ist hier die Verwendung eines Arrays für receive. Wenn das geschieht, ist auch $input ein Array, und die Werte sind so angeordnet wie die Gruppenadressen in receive. Arrays für transmit werden übrigens NICHT unterstützt.
8. Ein komplexerer Fall als Demonstration: hier sind receive und transmit wieder einfache GAs, dafür besteht der Status des Logikprozessors aus mehreren Werten. Es wird immer die Summe aus letztem, vorletztem und aktuellem Wert gesendet, und zwar mit 30s Verzoegerung.
Wenn state ein Hash ist, wird der letzte gesendete Wert - also das was sonst im skalaren $state stehen würde - in $state->{result} übergeben.
(Für $state sind nur Hashes und Skalare erlaubt, keine Arrays).
9. Schlussendlich wieder mal Werbung fuer meine GA-Kurznamen. Setzt man im Skript Logikprozessor.pl "$use_short_names=1" (ganz oben im Skript) und verwendet GA-Namen mit eindeutigem Kuerzel (Kuerzel=erstes Wort des Namens), so funktioniert auch das folgende:
Das ist doch leserlicher als Beispiel 3, oder? Hier wird ein relativer Dimmwert (LR) im Schlafzimmer (SZ) durch Skalierung und Summierung in einen absoluten Wert für die Konstantlichtregelung (LK) umgewandelt.
Zum Schluss: Have fun!
Der Logikprozessor ist gerade "frisch aus dem Ofen", macht bei mir im Testbrett (mittlerweile ist das ein Schaltschrank) so einiges, aber "nothing is perfect". Ich freue mich über Verbesserungsvorschläge und Bug reports.
NACHTRÄGLICHES EDIT: Der Logikprozessor ist inzwischen erheblich erweitert, u.a. um eine Verzögerungsfunktion für die Logik (delay), eine Karenzzeit, um zu häufiges Senden oder Zirkellogiken auszuschließen (cool), und eine komplette Timerfunktion mit umfangreichen Möglichkeiten (z.B. Weckfunktion nur an Arbeitstagen um 7:30). Für mehr Infos bitte diesem Thread folgen und unbedingt den Code aus dem SVN verwenden, nicht den hier geposteten (veraltet). Wiregate PL32 ist mittlerweile ebenfalls "Pflicht", zumindest wenn man alle Features nutzen will.
VG,
Fry
der "Translator", den ich neulich gepostet habe, ist mittlerweile so verbessert, dass er eigentlich eine einfache Logikmaschine geworden ist. Viele einfache Dinge lassen sich damit per Wiregate-Plugin lösen.
Man spezifiziert eine beliebige Zahl von Logiken im Konfigurationsfile, und der Logikprozessor (=Wiregate-Plugin) abonniert die passenden GAs und führt bei eingehenden Telegrammen die entsprechenden Logiken aus. Auch mehrere Logiken für die gleiche GA sind kein Problem.
Hier ein Eindruck der Möglichkeiten:
1. Alle Werte, die auf einer GA gesendet werden, mit 2 multiplizieren und auf einer anderen GA weitergeben. Das kostet nur eine Zeile im Konfigurationsfile:
Code:
mal2 => { receive=>'9/5/201', transmit=>'9/5/202', translate => sub { 2*$input; }, },
Code:
sum => { receive=>'9/5/207', transmit=>'9/5/208', translate => sub { $state-2*$input; }, },
3. Wie oben, aber das Ergebnis auf den Bereich 0-100 limitieren
Code:
lsum => { receive=>'1/2/7', transmit=>'1/2/8', translate => sub { limit(0,$state-2*$input,100); }, },
Code:
stair => { receive=>'1/2/9', transmit=>'1/2/9', delay=>600, translate => 0, },
Bemerkungen:
* translate darf nur entweder eine Konstante oder ausführbarer Code (sub {...}) sein.
* Damit im Fall transmit==receive der Translator nicht auf sein eigenes Schreibtelegramm immer wieder antwortet, wird nur dann gesendet,
wenn Ergebnis!=Input oder Sender des empfangenen Telegramms!=0 (Wiregate).
Hier noch ein Feature, für das mir momentan kein Beispiel einfällt: analog der Klausel "delay=>600" oben gibt es auch die Spezifikation "transmit_only_on_request=>1". Diese bewirkt, dass das Ergebnis von translate GAR NICHT gesendet wird, sondern dass auf eine spätere Leseanforderung auf der transmit-Adresse mit dem berechneten Ergebnis geantwortet wird.
5. Eine Logik, die einem Lichtanschalten gleich einen Dimmwert hinterherfeuert, und zwar tags und nachts einen verschiedenen:
Code:
dim => { receive=>'2/2/9', transmit=>'2/3/9', translate => sub { return unless $input; $day ? 80 : 5; }, },
6. Memory-Funktion. Für KNX-Geräte, die kein Auslesen ihres Statuswerts zulassen (z.B. MDT DaliControl bei Einzel-EVG-Ansteuerung). Sehr einfach:
Code:
memory => { transmit=>'1/2/9' },
7. Eine einfache UND-Logik mit zwei Eingaengen. Falls ein Telegramm auf einer der beiden receive-GAs empfangen wird, wird die andere Adresse noch ausgelesen, die Logik ausgeführt und das Ergebnis auf der transmit-GA uebermittelt:
Code:
und => { receive=>['1/2/12','1/2/13'], transmit=>'1/2/14', translate => sub { $input->[0] && $input->[1]; }, },
8. Ein komplexerer Fall als Demonstration: hier sind receive und transmit wieder einfache GAs, dafür besteht der Status des Logikprozessors aus mehreren Werten. Es wird immer die Summe aus letztem, vorletztem und aktuellem Wert gesendet, und zwar mit 30s Verzoegerung.
Code:
complex => { receive=>'9/5/205', transmit=>'9/5/206', delay=>30, state => {val1=>0, val2=>0}, translate => sub { $state->{val2}=$state->{val1}; $state->{val1}=$state->{result}; $state->{val2}+$state->{val1}+$input; }, },
(Für $state sind nur Hashes und Skalare erlaubt, keine Arrays).
9. Schlussendlich wieder mal Werbung fuer meine GA-Kurznamen. Setzt man im Skript Logikprozessor.pl "$use_short_names=1" (ganz oben im Skript) und verwendet GA-Namen mit eindeutigem Kuerzel (Kuerzel=erstes Wort des Namens), so funktioniert auch das folgende:
Code:
D_SZ_Decke => { receive=>'LR_SZ_Decke_1', transmit=>'LK_SZ_Decke_1', translate => sub { limit(0,$state-2*$input,100); }, },
Zum Schluss: Have fun!
Der Logikprozessor ist gerade "frisch aus dem Ofen", macht bei mir im Testbrett (mittlerweile ist das ein Schaltschrank) so einiges, aber "nothing is perfect". Ich freue mich über Verbesserungsvorschläge und Bug reports.
NACHTRÄGLICHES EDIT: Der Logikprozessor ist inzwischen erheblich erweitert, u.a. um eine Verzögerungsfunktion für die Logik (delay), eine Karenzzeit, um zu häufiges Senden oder Zirkellogiken auszuschließen (cool), und eine komplette Timerfunktion mit umfangreichen Möglichkeiten (z.B. Weckfunktion nur an Arbeitstagen um 7:30). Für mehr Infos bitte diesem Thread folgen und unbedingt den Code aus dem SVN verwenden, nicht den hier geposteten (veraltet). Wiregate PL32 ist mittlerweile ebenfalls "Pflicht", zumindest wenn man alle Features nutzen will.
VG,
Fry
Kommentar