|
From: <pf...@us...> - 2012-05-05 19:33:25
|
Revision: 786
http://openautomation.svn.sourceforge.net/openautomation/?rev=786&view=rev
Author: pfry
Date: 2012-05-05 19:33:18 +0000 (Sat, 05 May 2012)
Log Message:
-----------
Modified Paths:
--------------
wiregate/plugin/generic/Szenencontroller.pl
wiregate/plugin/generic/conf.d/Szenencontroller.conf
Added Paths:
-----------
wiregate/plugin/generic/Logikprozessor.pl
wiregate/plugin/generic/conf.d/Logikprozessor.conf
Added: wiregate/plugin/generic/Logikprozessor.pl
===================================================================
--- wiregate/plugin/generic/Logikprozessor.pl (rev 0)
+++ wiregate/plugin/generic/Logikprozessor.pl 2012-05-05 19:33:18 UTC (rev 786)
@@ -0,0 +1,434 @@
+#!/usr/bin/perl -w
+##################
+# Logikprozessor #
+##################
+# Wiregate-Plugin
+# (c) 2012 Fry under the GNU Public License
+
+#$plugin_info{$plugname.'_cycle'}=0; return 'deaktiviert';
+
+my $use_short_names=1; # 1 fuer GA-Kuerzel (erstes Wort des GA-Namens), 0 fuer die "nackte" Gruppenadresse
+
+# eibgaconf fixen falls nicht komplett indiziert
+if($use_short_names && !exists $eibgaconf{ZV_Uhrzeit})
+{
+ for my $ga (grep /^[0-9\/]+$/, keys %eibgaconf)
+ {
+ $eibgaconf{$ga}{ga}=$ga;
+ my $name=$eibgaconf{$ga}{name};
+ next unless defined $name;
+ $eibgaconf{$name}=$eibgaconf{$ga};
+
+ next unless $name=~/^\s*(\S+)/;
+ my $short=$1;
+ $short='ZV_'.$1 if $eibgaconf{$ga}{name}=~/^Zeitversand.*(Uhrzeit|Datum)/;
+
+ $eibgaconf{$ga}{short}=$short;
+ $eibgaconf{$short}=$eibgaconf{$ga};
+ }
+}
+
+# Tools und vorbesetzte Variablen fue die Logiken
+sub limit { my ($lo,$x,$hi)=@_; return $x<$lo?$lo:($x>$hi?$hi:$x); }
+my $day_of_week=`/bin/date +"%a"`;
+my $weekend=($day_of_week=~/Sa|So/);
+my $time_of_day=`/bin/date +"%X"`;
+my $hour_of_day=substr($time_of_day,0,2);
+my $day=($hour_of_day>7 && $hour_of_day<23);
+my $night=!$day;
+
+# Konfigurationsfile einlesen
+my %devices=(0=>'Wiregate');
+my %logic=();
+my $conf="/etc/wiregate/plugin/generic/conf.d/$plugname"; $conf=~s/\.pl$/.conf/;
+open FILE, "<$conf" || return "no config found";
+my @lines = <FILE>;
+close FILE;
+eval("@lines");
+return "config error: $@" if $@;
+
+# Aufrufgrund ermitteln
+my $event=undef;
+if (!$plugin_initflag)
+{ $event='restart'; } # Restart des daemons / Reboot
+elsif ($plugin_info{$plugname.'_lastsaved'} > $plugin_info{$plugname.'_last'})
+{ $event='modified'; } # Plugin modifiziert
+elsif (%msg) { $event='bus'; } # Bustraffic
+elsif ($fh) { $event='socket'; } # Netzwerktraffic
+else { $event='cycle'; } # Zyklus
+
+# Konfigfile seit dem letzten Mal geaendert?
+my $config_modified = (24*60*60*(-M $conf)-time()) > $plugin_info{$plugname.'_configtime'};
+
+# Plugin-Code
+my $retval='';
+
+if($event=~/restart|modified/ || $config_modified)
+{
+ $plugin_info{$plugname.'_configtime'}=(24*60*60*(-M $conf)-time());
+
+ # alle Variablen loeschen und neu initialisieren, alle GAs abonnieren
+ for my $k (grep /^$plugname\_/, keys %plugin_info)
+ {
+ delete $plugin_info{$k};
+ }
+
+ my $count=0;
+ my $err=0;
+
+ for my $t (keys %logic)
+ {
+ # Eintrag pruefen
+ if(defined $logic{$t}{receive} && ref $logic{$t}{receive} && ref $logic{$t}{receive} ne 'ARRAY')
+ {
+ plugin_log($plugname, "Config err: \$logic{$t}{receive} ist weder Skalar noch ARRAY-Referenz ([...]).");
+ next;
+ }
+
+ if(defined $logic{$t}{translate} && ref $logic{$t}{translate} && ref $logic{$t}{translate} ne 'CODE')
+ {
+ plugin_log($plugname, "Config err: \$logic{$t}{translate} ist weder Skalar noch CODE-Referenz (sub {...}).");
+ next;
+ }
+
+ if(defined $logic{$t}{state} && ref $logic{$t}{state} && ref $logic{$t}{state} ne 'HASH')
+ {
+ plugin_log($plugname, "Config err: \$logic{$t}{state} ist weder Skalar noch HASH-Referenz ({...}).");
+ next;
+ }
+
+ # transmit-Adresse abonnieren
+ my $transmit=groupaddress($logic{$t}{transmit});
+ $plugin_subscribe{$transmit}{$plugname}=1;
+
+ $count++;
+
+ # alle receive-Adressen abonnieren (eine oder mehrere)
+ my $receive=groupaddress($logic{$t}{receive});
+
+ next unless $receive;
+
+ unless(ref $receive)
+ {
+ $plugin_subscribe{$receive}{$plugname}=1;
+ }
+ else
+ {
+ for my $rec (@{$receive})
+ {
+ $plugin_subscribe{$rec}{$plugname}=1;
+ }
+ }
+ }
+
+ $plugin_info{$plugname.'_cycle'}=0;
+ $retval.=$count." initialisiert";
+}
+
+if($event=~/bus/)
+{
+ # Bustraffic bedienen - nur Schreibzugriffe der iButtons interessieren
+ return unless $msg{apci}=~/A_GroupValue_(Write|Read)/;
+
+ my $ga=$msg{dst};
+ my $in=$msg{value};
+ my $keep_subscription=0; # falls am Ende immer noch Null, die GA stornieren
+
+ # welche translate-Logik ist aufgerufen?
+ for my $t (keys %logic)
+ {
+ my $transmit=groupaddress($logic{$t}{transmit});
+ my $transmit_ga = ($ga eq $transmit);
+
+ my $receive=groupaddress($logic{$t}{receive});
+ my $receive_ga=0;
+
+ if(defined $receive)
+ {
+ unless(ref $logic{$t}{receive})
+ {
+ $receive_ga=1 if $ga eq $receive;
+ }
+ else
+ {
+ $receive_ga=1 if grep /^$ga$/, @{$receive};
+ }
+ }
+
+ next unless $receive_ga || $transmit_ga; # diese Logik nicht anwendbar
+
+ $keep_subscription=1;
+
+ # Sonderfall: Read- und Write-Telegramme auf der Transmit-Adresse?
+ if($transmit_ga)
+ {
+ # Ein Read-Request auf einer Transmit-GA wird mit dem letzten Ergebnis beantwortet
+ # Read-Requests auf die receive-Adressen werden gar nicht beantwortet
+ if($msg{apci} eq "A_GroupValue_Read")
+ {
+ my $result=$plugin_info{$plugname.'_'.$t.'_result'};
+ if(defined $result)
+ {
+ knx_write($ga, $result);
+ }
+ next;
+ }
+ elsif(!$receive_ga) # Receive geht vor!
+ {
+ if(defined $in) # Write-Telegramm: das waren moeglicherweise wir selbst, also nicht antworten
+ {
+ $plugin_info{$plugname.'_'.$t.'_result'}=$in; # einfach Input ablegen
+ }
+ else
+ {
+ delete $plugin_info{$plugname.'_'.$t.'_result'};
+ }
+ next;
+ }
+ }
+
+ # Wir wissen ab hier: Es liegt ein Write-Telegramm auf einer der receive-Adressen vor
+
+ # Nebenbei berechnen wir noch zwei Flags, die Zirkelkommunikation verhindern sollen
+ # (Logik antwortet auf sich selbst in einer Endlosschleife)
+
+ # kommt transmit-GA unter den receive-GAs vor?
+ # Wenn transmit_ga gesetzt ist, ist das schon mal der Fall
+ my $possible_circle=$transmit_ga;
+
+ # war Wiregate der Sender des Telegramms?
+ my $sender_is_wiregate=int($msg{src})==0;
+
+ # Es folgt die eigentliche Logik-Engine - als erstes definiere das Input-Array fuer die Logik
+ my $input=$in; # Skalarer Fall (der haeufigste)
+
+ # Array-Fall: bereite Input-Array fuer Logik vor
+ if(ref $receive)
+ {
+ $input=();
+ for my $rec (@{$receive})
+ {
+ my $rec=groupaddress($rec);
+
+ $possible_circle=1 if $transmit eq $rec;
+
+ if($ga eq $rec)
+ {
+ push @{$input}, $in;
+ }
+ else
+ {
+ push @{$input}, knx_read($rec, 300);
+ }
+ }
+ }
+
+ # ab hier liegt $input komplett vor, und nun muss die Logik ausgewertet
+ # und das Resultat auf der Transmit-GA uebertragen
+ my $result=undef;
+
+ unless(ref $logic{$t}{translate})
+ {
+ # Trivialer Fall: translate enthaelt einen fixen Rueckgabewert
+ $plugin_info{$plugname.'_'.$t.'_result'}=$result=$logic{$t}{translate};
+ }
+ elsif(!ref $logic{$t}{state})
+ {
+ # Einfacher aber haeufiger Fall: skalarer $state
+ # $state mit Ergebnis des letzten Aufrufs vorbesetzen
+ my $state=$plugin_info{$plugname.'_'.$t.'_result'};
+
+ # Funktionsaufruf, das Ergebnis vom letzten Mal steht in $state
+ $result=$logic{$t}{translate}($state,$input);
+
+ # Ergebnis des letzten Aufrufs zurueckschreiben
+ if(defined $result)
+ {
+ $plugin_info{$plugname.'_'.$t.'_result'}=$result;
+ }
+ else
+ {
+ delete $plugin_info{$plugname.'_'.$t.'_result'};
+ }
+ }
+ else
+ {
+ # Komplexer Fall: $state-Hash aus %logic initialisieren
+ my $state=$logic{$t}{state};
+ my @vars=keys %{$state};
+ push @vars, 'result';
+
+ # Nun die dynamischen Variablen aus plugin_info hinzufuegen
+ for my $v (@vars)
+ {
+ $state->{$v}=$plugin_info{$plugname.'_'.$t.'_'.$v} if defined $plugin_info{$plugname.'_'.$t.'_'.$v};
+ }
+
+ # Funktionsaufruf, das Ergebnis vom letzten Mal steht in $state->{result}
+ $result=$state->{result}=$logic{$t}{translate}($state,$input);
+
+ # Alle dynamischen Variablen wieder nach plugin_info schreiben
+ # Damit plugin_info nicht durch Konfigurationsfehler vollgemuellt wird,
+ # erlauben wir nur Eintraege mit defined-Werten
+ for my $v (@vars)
+ {
+ if(defined $state->{$v})
+ {
+ $plugin_info{$plugname.'_'.$t.'_'.$v}=$state->{$v};
+ }
+ else
+ {
+ # wenn die Logik den Wert undef in eine state-Variable schreibt,
+ # wird beim naechsten Aufruf wieder der Startwert aus %logic genommen,
+ delete $plugin_info{$plugname.'_'.$t.'_'.$v};
+ }
+ }
+ }
+
+ # In bestimmten Sonderfaellen nichts schicken
+ next unless defined $result; # Resultat undef => nichts senden
+ next if $logic{$t}{transmit_only_on_request};
+ next if $possible_circle && $sender_is_wiregate && $in eq $result;
+
+ # Falls delay spezifiziert, wird ein "Wecker" gestellt, um in einem spaeteren Aufruf den Wert zu senden
+ if($logic{$t}{delay})
+ {
+ $plugin_info{$plugname.'__'.$t.'_timer'}=time()+$logic{$t}{delay};
+ set_timer();
+ }
+ else
+ {
+ knx_write($transmit, $result);
+ }
+ }
+
+ unless($keep_subscription)
+ {
+ delete $plugin_subscribe{$ga}{$plugname};
+ }
+}
+
+# Evtl. faellige Timer finden
+for my $timer (grep /$plugname\__.*_timer/, keys %plugin_info) # alle Timer
+{
+ next if time()<$plugin_info{$timer}; # weiter falls noch nicht faellig
+
+ # Timer loeschen
+ delete $plugin_info{$timer};
+
+ # Relevanten Eintrag von %logic ermitteln
+ $timer=~/$plugname\__(.*)_timer/;
+ my $t=$1;
+
+ # Transmit-GA
+ my $transmit=groupaddress($logic{$t}{transmit});
+
+ # zu sendendes Resultat
+ my $result=$plugin_info{$plugname.'_'.$t.'_result'};
+ next unless defined $result;
+
+ knx_write($transmit, $result);
+
+ # Timer fuer nachste Aktion setzen
+ set_timer();
+}
+
+return unless $retval;
+return $retval;
+
+
+# Zeit bis zum naechsten Aufruf dieses Plugins berechnen
+
+sub set_timer
+{
+ # optimalen Wert fuer Aufrufzyklus finden, um beim naechsten Aufruf was zu senden
+ my $nexttimer=undef;
+ for my $timer (grep /$plugname\__.*_timer/, keys %plugin_info) # alle Timer
+ {
+ $nexttimer=$plugin_info{$timer} if !defined $nexttimer || $plugin_info{$timer}<$nexttimer;
+ }
+
+ unless(defined $nexttimer)
+ {
+ $plugin_info{$plugname."_cycle"}=0;
+ }
+ else
+ {
+ my $cycle=$nexttimer-time();
+ $cycle=1 if $cycle<1;
+ $plugin_info{$plugname."_cycle"}=$cycle;
+ }
+}
+
+# Umgang mit GA-Kurznamen und -Adressen
+
+sub groupaddress
+{
+ my $short=shift;
+
+ return unless defined $short;
+
+ if(ref $short)
+ {
+ my $ga=[];
+ for my $sh (@{$short})
+ {
+ if($sh!~/^[0-9\/]+$/ && defined $eibgaconf{$sh}{ga})
+ {
+ push @{$ga}, $eibgaconf{$sh}{ga};
+ }
+ else
+ {
+ push @{$ga}, $sh;
+ }
+ }
+ return $ga;
+ }
+ else
+ {
+ my $ga=$short;
+
+ if($short!~/^[0-9\/]+$/ && defined $eibgaconf{$short}{ga})
+ {
+ $ga=$eibgaconf{$short}{ga};
+ }
+
+ return $ga;
+ }
+}
+
+sub shortname
+{
+ my $gas=shift;
+
+ return unless defined $gas;
+ return $gas unless $use_short_names;
+
+ if(ref $gas)
+ {
+ my $sh=[];
+ for my $ga (@{$gas})
+ {
+ if($ga=~/^[0-9\/]+$/ && defined $eibgaconf{$ga}{short})
+ {
+ push @{$sh}, $eibgaconf{$ga}{short};
+ }
+ else
+ {
+ push @{$sh}, $ga;
+ }
+ }
+ return $sh;
+ }
+ else
+ {
+ my $sh=$gas;
+
+ if($gas=~/^[0-9\/]+$/ && defined $eibgaconf{$gas}{short})
+ {
+ $sh=$eibgaconf{$gas}{short};
+ }
+
+ return $sh;
+ }
+}
Modified: wiregate/plugin/generic/Szenencontroller.pl
===================================================================
--- wiregate/plugin/generic/Szenencontroller.pl 2012-05-05 15:56:45 UTC (rev 785)
+++ wiregate/plugin/generic/Szenencontroller.pl 2012-05-05 19:33:18 UTC (rev 786)
@@ -5,9 +5,9 @@
# Wiregate-Plugin
# (c) 2012 Fry under the GNU Public License
-# $plugin_info{$plugname.'_cycle'}=0; return "deaktiviert";
+#$plugin_info{$plugname.'_cycle'}=0; return "deaktiviert";
-my $use_short_names=0; # 1 fuer GA-Kuerzel (erstes Wort des GA-Namens), 0 fuer die "nackte" Gruppenadresse
+my $use_short_names=1; # 1 fuer GA-Kuerzel (erstes Wort des GA-Namens), 0 fuer die "nackte" Gruppenadresse
# eibgaconf fixen falls nicht komplett indiziert
if($use_short_names && !exists $eibgaconf{ZV_Uhrzeit})
@@ -41,17 +41,24 @@
else { $event='cycle'; } # Zyklus
# Konfigurationsfile einlesen
-my $conf=$plugname; $conf=~s/\.pl$/.conf/;
-$conf="/etc/wiregate/plugin/generic/conf.d/$conf";
my %scene=();
+my $conf="/etc/wiregate/plugin/generic/conf.d/$plugname"; $conf=~s/\.pl$/.conf/;
my $err=read_from_config();
return $err if $err;
+# Konfigfile seit dem letzten Mal geaendert?
+my $config_modified = ($scene{storage} ne 'configfile' && (24*60*60*(-M $conf)-time()) > $plugin_info{$plugname.'_configtime'});
+
# Dynamisch definierte Szenen aus plugin_info einlesen
recall_from_plugin_info();
-if($event=~/restart|modified/)
+# Plugin-Code
+my $retval='';
+
+if($event=~/restart|modified/ || $config_modified)
{
+ $plugin_info{$plugname.'_configtime'}=(24*60*60*(-M $conf)-time());
+
# Cleanup aller Szenenvariablen in %plugin_info
for my $k (grep /^$plugname\_/, keys %plugin_info)
{
@@ -64,7 +71,7 @@
for my $sc (sort keys %scene)
{
- next if $sc eq 'storage';
+ next if $sc=~/^(storage|debug)$/;
my $store=$scene{$sc}{store};
my $recall=$scene{$sc}{recall};
@@ -85,12 +92,9 @@
$plugin_info{$plugname.'__SceneLookup'}=$scene_lookup;
$plugin_info{$plugname.'_cycle'}=0;
- return $count." initialisiert";
+ $retval.=$count." initialisiert";
}
-
-my $retval='';
-
-if($event=~/bus/)
+elsif($event=~/bus/)
{
# nur auf Write-Telegramme reagieren
return if $msg{apci} ne 'A_GroupValue_Write';
@@ -127,11 +131,15 @@
}
# Szenencode
- my $z="$sc\__$n";
+ my $z="$sc\#$n";
if($cmd eq 'S') # Szene speichern
{
- $retval.="Szene $z speichern: ";
+ $retval.="Szene $z speichern: " if $scene{debug};
+
+ my $confirm_store=$scene{$sc}{confirm_store};
+ $confirm_store=$eibgaconf{$confirm_store}{ga} if $confirm_store!~/^[0-9\/]+$/ && defined $eibgaconf{$confirm_store};
+ knx_write($confirm_store,1); # Translator feuert spaeter dann eine Null hinterher, um die LED auszuschalten
delete $scene{$z};
@@ -139,15 +147,18 @@
{
my $wga=$scene{$sc}{gas}{$ga}; # auf diese GA muss spaeter geschrieben werden
$wga=$eibgaconf{$wga}{short} if $wga=~/^[0-9\/]+$/ && $use_short_names && defined $eibgaconf{$wga}{short};
+
$ga=$eibgaconf{$ga}{ga} if $ga!~/^[0-9\/]+$/ && defined $eibgaconf{$ga};
- $scene{$z}{$wga}=knx_read($ga,300);
+ $scene{$z}{$wga}=knx_read($ga,300); # KOSTET ZEIT FALLS GERAETE NICHT ANTWORTEN!
+
if(defined $scene{$z}{$wga})
{
- $retval.=$wga.'->'.$scene{$z}{$wga}.' ';
+ $retval.=$wga.'->'.$scene{$z}{$wga}.' ' if $scene{debug};
}
else
{
+ $retval.=$wga.'? ' if $scene{debug};
delete $scene{$z}{$wga};
}
}
@@ -163,14 +174,12 @@
}
else # Szene abrufen
{
- $retval.="Szene $z abrufen: ";
+ $retval.="Szene $z abrufen: " if $scene{debug};
for my $v (keys %{$scene{$z}})
{
- my $ga=$v;
- $ga=$eibgaconf{$ga}{ga} if $ga!~/^[0-9\/]+$/ && defined $eibgaconf{$ga};
- knx_write($ga,$scene{$z}{$v});
- $retval.=$ga.'->'.$scene{$z}{$v}.' ';
+ knx_write(groupaddress($v),$scene{$z}{$v});
+ $retval.=$v.'->'.$scene{$z}{$v}.' ' if $scene{debug};
}
}
}
@@ -226,9 +235,81 @@
{
for my $k (grep /^$plugname\__/, keys %plugin_info)
{
- next unless($k=~/^$plugname\__([A-Z0-9 ]+__[0-9]+)__(.*)$/i);
+ next unless($k=~/^$plugname\__(.*\#.*)__(.*)$/);
my ($z,$v)=($1,$2);
$scene{$z}{$v}=$plugin_info{$k};
}
}
+# Umgang mit GA-Kurznamen und -Adressen
+sub groupaddress
+{
+ my $short=shift;
+
+ return unless defined $short;
+
+ if(ref $short)
+ {
+ my $ga=[];
+ for my $sh (@{$short})
+ {
+ if($sh!~/^[0-9\/]+$/ && defined $eibgaconf{$sh}{ga})
+ {
+ push @{$ga}, $eibgaconf{$sh}{ga};
+ }
+ else
+ {
+ push @{$ga}, $sh;
+ }
+ }
+ return $ga;
+ }
+ else
+ {
+ my $ga=$short;
+
+ if($short!~/^[0-9\/]+$/ && defined $eibgaconf{$short}{ga})
+ {
+ $ga=$eibgaconf{$short}{ga};
+ }
+
+ return $ga;
+ }
+}
+
+sub shortname
+{
+ my $gas=shift;
+
+ return unless defined $gas;
+ return $gas unless $use_short_names;
+
+ if(ref $gas)
+ {
+ my $sh=[];
+ for my $ga (@{$gas})
+ {
+ if($ga=~/^[0-9\/]+$/ && defined $eibgaconf{$ga}{short})
+ {
+ push @{$sh}, $eibgaconf{$ga}{short};
+ }
+ else
+ {
+ push @{$sh}, $ga;
+ }
+ }
+ return $sh;
+ }
+ else
+ {
+ my $sh=$gas;
+
+ if($gas=~/^[0-9\/]+$/ && defined $eibgaconf{$gas}{short})
+ {
+ $sh=$eibgaconf{$gas}{short};
+ }
+
+ return $sh;
+ }
+}
+
Added: wiregate/plugin/generic/conf.d/Logikprozessor.conf
===================================================================
--- wiregate/plugin/generic/conf.d/Logikprozessor.conf (rev 0)
+++ wiregate/plugin/generic/conf.d/Logikprozessor.conf 2012-05-05 19:33:18 UTC (rev 786)
@@ -0,0 +1,59 @@
+#!/usr/bin/perl
+#
+# Logikprozessor.pl - Konfiguration
+#
+
+%logic=(
+ # 1. Alle Werte, die auf einer GA gesendet werden, werden mit 2 multipliziert auf einer anderen GA weitergegeben
+ mal2 => { receive=>'9/5/201', transmit=>'9/5/202', translate => sub { my (undef,$input)=@_; 2*$input; }, },
+ # das "undef" steht da einfach, weil uns der letzte Ergebniswert nicht interessiert
+
+ # 2. Die Werte auf der ersten GA werden aufsummiert, das Ergebis auf der anderen GA gesendet.
+ # Damit kann man bspw aus einem relativen Dimmwert einen absoluten Dimmwert machen.
+ sum => { receive=>'9/5/207', transmit=>'9/5/208', translate => sub { my ($state,$input)=@_; $state+$input; }, },
+ # $state enthaelt das jeweils letzte Ergebnis.
+
+ # 3. Wie oben, aber das Ergebnis limitiert auf den Bereich 0-100
+ lsum => { receive=>'1/2/7', transmit=>'1/2/8', translate => sub { my ($state,$input)=@_; limit(0,$state+$input,100); }, },
+
+ # 4. Hier eine "Treppenlichtfunktion". Auf jeden Schreibzugriff auf die receive-Adresse wird 10min spaeter eine 0 an
+ # die transmit-Adresse (hier 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.
+ stair => { receive=>'1/2/9', transmit=>'1/2/9', delay=>600, translate => 0, },
+ # 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).
+
+ # 5. Memory-Funktion. Wenn ein Write-Telegramm auf die Transmit-Adresse kommt, speichert der Logikprozessor den Wert ab.
+ # Das Flag "transmit_on_request" bewirkt, dass nichts gesendet wird, jedoch wird eine Leseanfrage auf der transmit-GA immer
+ # mit dem letzten Wert (hier also dem gespeicherten) beantwortet. Damit laesst sich eine Speicherfunktion realisieren.
+ # Hier speichert Translator also den Input ab und sendet den errechneten (=gespeicherten) Wert NUR AUF ANFRAGE.
+ memory => { transmit=>'1/2/9', transmit_on_request=>1 },
+ # Eine receive-Adresse oder translate-Logik werden hier gar nicht gebraucht.
+
+ # 6. 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 angewendet und das Ergebnis auf der transmit-GA uebermittelt
+ und => { receive=>['1/2/12','1/2/13'], transmit=>'1/2/14', translate => sub { my (undef,$input)=@_; $input->[0] && $input->[1]; }, },
+
+ # 7. Ein komplexerer Fall nur zur Demonstration: hier besteht der Status des Translators aus mehreren Werten.
+ # Es wird immer die Summe aus letztem, vorletztem und aktuellem Wert gesendet, und zwar mit 30s Verzoegerung.
+ complex => { receive=>'9/5/205',
+ transmit=>'9/5/206',
+ delay=>30,
+ state => {val1=>0, val2=>0},
+ translate => sub { my ($state,$input)=@_;
+ $state->{val2}=$state->{val1}; $state->{val1}=$state->{result};
+ $state->{val2}+$state->{val1}+$input; },
+ },
+ # Wenn state ein Hash ist, wird der letzte gesendete Wert in $state->{result} gespeichert.
+
+ # 8. Schlussendlich wieder mal Werbung fuer die GA-Kurznamen. Setzt man im Skript Translator.pl $use_short_names=1
+ # und verwendet GA-Namen mit eindeutigem Kuerzel (=erstes Wort des Namens), so funktioniert auch das folgende:
+ D_SZ_Decke => { receive=>'LR_SZ_Decke_1', transmit=>'LK_SZ_Decke_1',
+ translate => sub { my ($state,$input)=@_; limit(0,$state+20*$input,100); }, },
+ # ist doch leserlicher, oder? Hier wird ein relativer Dimmwert durch Skalierung und Summierung
+ # in einen absoluten Wert umgewandelt
+ );
+
+
+
Modified: wiregate/plugin/generic/conf.d/Szenencontroller.conf
===================================================================
--- wiregate/plugin/generic/conf.d/Szenencontroller.conf 2012-05-05 15:56:45 UTC (rev 785)
+++ wiregate/plugin/generic/conf.d/Szenencontroller.conf 2012-05-05 19:33:18 UTC (rev 786)
@@ -5,6 +5,9 @@
%scene=(
+ # Debugflag fuer Kontrollmeldungen auf /var/log/wiregate_plugin.log auf 1 setzen
+ debug=>1,
+
# Storage auf 'configfile' setzen, wenn die Szenen hier im Konfigfile gespeichert werden sollen.
# Sie ueberleben in diesem Fall sogar das Loeschen des plugin_info und gelten somit als "fest verdrahtet".
# Ansonsten 'plugin_info' setzen, dann werden die Szenen im %plugin_info gespeichert.
@@ -48,10 +51,10 @@
#
# 4. Schlussendlich wieder mal Werbung fuer die GA-Kurznamen. Setzt man im Skript Translator.pl $use_short_names=1
# und verwendet GA-Namen mit eindeutigem Kuerzel (=erstes Wort des Namens), so funktioniert auch das folgende:
- Schlafzimmer2 => {store=>'ZS_SZ', recall=>'ZA_SZ', gas=>{'LI_SZ'=>'LI_SZ', 'JX_SZ'=>'JW_SZ', 'JQ_SZ'=>'JP_SZ'}},
+ Schlafzimmer2 => {store=>'ZS_SZ', recall=>'ZA_SZ', confirm_store=>'ZC_SZ', gas=>{'LI_SZ'=>'LI_SZ', 'JX_SZ'=>'JW_SZ', 'JQ_SZ'=>'JP_SZ'}},
# ist doch leserlicher, oder? SZ=Schlafzimmer, ZA=Szene abrufen, ZS=Szene speichern, LI=Licht,
# JX=Jalousiewinkel abfragen, JW=Jalousiewinkel einstellen, JQ=Jalousieposition abfragen, JP=Jalousie positionieren
-
+ # confirm_store ist uebrigens eine GA (Trigger), die gesendet wird, um ein Szenenabspeichern zu bestaetigen
);
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|