2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-04-20 07:16:03 +00:00

Added behaviour last

git-svn-id: https://svn.fhem.de/fhem/trunk@2563 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
rudolfkoenig 2013-01-25 16:56:00 +00:00
parent 49be31952b
commit d14032e055

View File

@ -40,7 +40,7 @@ structure_Initialize($)
$hash->{SetFn} = "structure_Set"; $hash->{SetFn} = "structure_Set";
$hash->{AttrFn} = "structure_Attr"; $hash->{AttrFn} = "structure_Attr";
$hash->{AttrList} = "clientstate_priority ". $hash->{AttrList} = "clientstate_priority ".
"clientstate_behavior:relative,absolute loglevel:0,5 ". "clientstate_behavior:relative,absolute,last loglevel:0,5 ".
$readingFnAttributes; $readingFnAttributes;
addToAttrList("structexclude"); addToAttrList("structexclude");
@ -117,16 +117,16 @@ sub structure_Notify($$)
my $me = $hash->{NAME}; my $me = $hash->{NAME};
my $devmap = $hash->{ATTR}."_map"; my $devmap = $hash->{ATTR}."_map";
# lade das Verhalten, Standard ist absolute return "" if(AttrVal($me,"disable", undef));
my $behavior = AttrVal($me,"clientstate_behavior", "absolute");
my @clientstate;
return "" if($attr{$me} && $attr{$me}{disable});
#pruefen ob Devices welches das notify ausgeloest hat Mitglied dieser #pruefen ob Devices welches das notify ausgeloest hat Mitglied dieser
# Struktur ist # Struktur ist
return "" if (!$hash->{CONTENT}->{$dev->{NAME}}); return "" if (!$hash->{CONTENT}->{$dev->{NAME}});
# lade das Verhalten, Standard ist absolute
my $behavior = AttrVal($me, "clientstate_behavior", "absolute");
my @clientstate;
# hier nur den Struktur-Status anpassen wenn # hier nur den Struktur-Status anpassen wenn
# a) behavior=absolute oder # a) behavior=absolute oder
# b) behavior=relative UND das Attr clientstate_priority gefaellt ist # b) behavior=relative UND das Attr clientstate_priority gefaellt ist
@ -134,6 +134,13 @@ sub structure_Notify($$)
if($attr{$me}{clientstate_priority}); if($attr{$me}{clientstate_priority});
return "" if (!@structPrio && $behavior eq "relative"); return "" if (!@structPrio && $behavior eq "relative");
if($hash->{INNTFY}) {
Log 1, "ERROR: endless loop detected in structure_Notify $me";
return "";
}
$hash->{INNTFY} = 1;
# assoziatives Array aus Prioritaetsliste aufbauen # assoziatives Array aus Prioritaetsliste aufbauen
# Bsp: Original: "On|An Off|Aus" # Bsp: Original: "On|An Off|Aus"
# wobei der erste Wert der "Oder"-Liste als Status der Struktur uebernommen # wobei der erste Wert der "Oder"-Liste als Status der Struktur uebernommen
@ -155,30 +162,24 @@ sub structure_Notify($$)
undef @structPrio; undef @structPrio;
#Log 1, Dumper(%priority) . "\n"; #Log 1, Dumper(%priority) . "\n";
$hash->{INSET} = 1;
my $minprio = 99999; my $minprio = 99999;
my $devstate; my $devstate;
#ueber jedes Device das zu dieser Struktur gehoert #ueber jedes Device das zu dieser Struktur gehoert
foreach my $d (sort keys %{ $hash->{CONTENT} }) { foreach my $d (sort keys %{ $hash->{CONTENT} }) {
next if(!$defs{$d}); next if(!$defs{$d});
if($defs{$d}{INSET}) {
Log 1, "ERROR: endless loop detected for $d in " . $hash->{NAME};
next;
}
# wenn zum Device das "structexclude" gesetzt ist, wird dieses nicht # wenn zum Device das "structexclude" gesetzt ist, wird dieses nicht
# beruecksichtigt # beruecksichtigt
if($attr{$d} && $attr{$d}{structexclude}) { if($attr{$d} && $attr{$d}{structexclude}) {
my $se = $attr{$d}{structexclude}; my $se = $attr{$d}{structexclude};
next if($hash->{NAME} =~ m/$se/); next if($me =~ m/$se/);
} }
# Status des Devices gemaess den Regeln des gesetztes StrukturAttr # Status des Devices gemaess den Regeln des gesetztes StrukturAttr
# umformatieren # umformatieren
if ($attr{$d}{$devmap}) { if($attr{$d} && $attr{$d}{$devmap}) {
my @gruppe = split(" ", $attr{$d}{$devmap}); my @gruppe = split(" ", $attr{$d}{$devmap});
my @value; my @value;
for (my $i=0; $i<@gruppe; $i++) { for (my $i=0; $i<@gruppe; $i++) {
@ -186,10 +187,11 @@ sub structure_Notify($$)
if(@value == 1) { if(@value == 1) {
# nur das zu lesende Reading ist angegeben, zb. bei 1wire Modul # nur das zu lesende Reading ist angegeben, zb. bei 1wire Modul
# OWSWITCH # OWSWITCH
#Bsp: A --> nur Reading A gehuert zur Struktur #Bsp: A --> nur Reading A gehoert zur Struktur
#Bsp: A B --> Reading A und B gehuert zur Struktur #Bsp: A B --> Reading A und B gehoert zur Struktur
$devstate = ReadingsVal($d, $value[0], undef); $devstate = ReadingsVal($d, $value[0], undef);
push(@clientstate, $devstate) if(defined($devstate)); push(@clientstate, $devstate) if(defined($devstate));
} elsif(@value == 2) { } elsif(@value == 2) {
# zustand wenn der Status auf dem in der Struktur definierten # zustand wenn der Status auf dem in der Struktur definierten
# umdefiniert werden muss # umdefiniert werden muss
@ -200,6 +202,7 @@ sub structure_Notify($$)
push(@clientstate, $devstate); push(@clientstate, $devstate);
$i=99999; $i=99999;
} }
} elsif(@value == 3) { } elsif(@value == 3) {
# Das zu lesende Reading wurde mit angegeben: # Das zu lesende Reading wurde mit angegeben:
# Reading:OriginalStatus:NeuerStatus wenn zb. ein Device mehrere # Reading:OriginalStatus:NeuerStatus wenn zb. ein Device mehrere
@ -236,27 +239,28 @@ sub structure_Notify($$)
@clientstate = uniq(@clientstate);# eleminiere alle Dubletten @clientstate = uniq(@clientstate);# eleminiere alle Dubletten
#ermittle Endstatus #ermittle Endstatus
my $newState = ""; my $newState = "undefined";
if($behavior eq "absolute"){ if($behavior eq "absolute"){
# wenn absolute, dann gebe undefinierten Status aus falls die Clients # wenn absolute, dann gebe undefinierten Status aus falls die Clients
# unterschiedliche Status' haben # unterschiedliche Stati haben
if(@clientstate > 1) { $newState = "undefined";} $newState = (@clientstate == 1 ? $clientstate[0] : "undefined");
elsif(@clientstate > 0) { $newState = $clientstate[0];}
} elsif($behavior eq "relative" && $minprio < 99999) { } elsif($behavior eq "relative" && $minprio < 99999) {
$newState = $priority[$minprio]; $newState = $priority[$minprio];
} else {
$newState = "undefined";
}
delete($hash->{INSET}); } elsif($behavior eq "last"){
$newState = ReadingsVal($dev->{NAME}, "state", undef);
}
#eigenen Status jetzt setzen, nur wenn abweichend #eigenen Status jetzt setzen, nur wenn abweichend
if(!defined($hash->{STATE}) || ($hash->{STATE} ne $newState)) { my $oldState = ReadingsVal($me, "state", "");
Log GetLogLevel($hash->{NAME},5), "Update structure '" .$me . "' to " . $newState . if($oldState ne $newState) {
" because device '" .$dev->{NAME}. "' has changed"; Log GetLogLevel($me,5), "Update structure '$me' to $newState" .
$hash->{STATE} = $newState; " because device $dev->{NAME} has changed";
readingsSingleUpdate($hash, "state", $newState, 1); readingsSingleUpdate($hash, "state", $newState, 1);
} }
delete($hash->{INNTFY});
undef; undef;
} }
@ -443,13 +447,17 @@ structure_Attr($@)
delemited by space. Each entry of one group are delimited by "pipe". delemited by space. Each entry of one group are delimited by "pipe".
The status represented by the structure is the first entry of each group The status represented by the structure is the first entry of each group
</ul> </ul>
<li>last</li>
<ul>
The structure state corresponds to the state of the device last changed.
</ul>
<br>Example:<br> <br>Example:<br>
<ul> <ul>
<li>attr kittchen clientstate_behavior relative</li> <li>attr kitchen clientstate_behavior relative</li>
<li>attr kittchen clientstate_priority An|On|on Aus|Off|off</li> <li>attr kitchen clientstate_priority An|On|on Aus|Off|off</li>
<li>attr house clientstate_priority Any_On|An All_Off|Aus</li> <li>attr house clientstate_priority Any_On|An All_Off|Aus</li>
</ul> </ul>
In this example the status of kittchen is either on or off. In this example the status of kitchen is either on or off.
The status of house is either Any_on or All_off. The status of house is either Any_on or All_off.
<br> <br>
To group more devices from different types of devices you can define To group more devices from different types of devices you can define
@ -465,7 +473,7 @@ structure_Attr($@)
<li>define lamp1 dummy</li> <li>define lamp1 dummy</li>
<li>attr lamp1 cmdlist on off</li> <li>attr lamp1 cmdlist on off</li>
<li>define kitchen structure struct_kitchen lamp1 door</li> <li>define kitchen structure struct_kitchen lamp1 door</li>
<li>attr kittchen clientstate_priority An|on OK|Aus|off</li> <li>attr kitchen clientstate_priority An|on OK|Aus|off</li>
<li>attr lamp1 struct_kitchen_map on:An off:Aus</li> <li>attr lamp1 struct_kitchen_map on:An off:Aus</li>
<li>attr door struct_kitchen_map A:open:on A:closed:off</li> <li>attr door struct_kitchen_map A:open:on A:closed:off</li>
<li>attr door2 struct_kitchen_map A</li> <li>attr door2 struct_kitchen_map A</li>
@ -476,7 +484,7 @@ structure_Attr($@)
<b>Set</b> <b>Set</b>
<ul> <ul>
Every set command is propagated to the attached devices. Exception: if an Every set command is propagated to the attached devices. Exception: if an
attached devices has an attribute structexclude, and the attribute value attached device has an attribute structexclude, and the attribute value
matches (as a regexp) the name of the current structure. matches (as a regexp) the name of the current structure.
</ul> </ul>
<br> <br>
@ -554,6 +562,10 @@ structure_Attr($@)
Leerzeichen, jeder Eintrag pro Gruppe durch Pipe getrennt. Der Status der Leerzeichen, jeder Eintrag pro Gruppe durch Pipe getrennt. Der Status der
Struktur ist der erste Eintrag in der entsprechenden Gruppe. Struktur ist der erste Eintrag in der entsprechenden Gruppe.
</ul> </ul>
<li>last</li>
<ul>
Die Struktur &uuml;bernimmt den Status des zuletzt ge&auml;nderten Ger&auml;tes.
</ul>
<br>Beispiel:<br> <br>Beispiel:<br>
<ul> <ul>
<li>attr kueche clientstate_behavior relative</li> <li>attr kueche clientstate_behavior relative</li>