mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-01-31 06:39:11 +00:00
Structure changes by Tobias
git-svn-id: https://svn.fhem.de/fhem/trunk@1869 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
934a3b57e4
commit
24e33dfc10
@ -4,6 +4,8 @@ package main;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
#use Data::Dumper;
|
||||
|
||||
|
||||
#####################################
|
||||
sub
|
||||
@ -13,9 +15,11 @@ structure_Initialize($)
|
||||
|
||||
$hash->{DefFn} = "structure_Define";
|
||||
$hash->{UndefFn} = "structure_Undef";
|
||||
|
||||
$hash->{NotifyFn} = "structure_Notify";
|
||||
$hash->{SetFn} = "structure_Set";
|
||||
$hash->{AttrFn} = "structure_Attr";
|
||||
$hash->{AttrList} = "clientstate_priority clientstate_behavior:relative,absolute";
|
||||
|
||||
addToAttrList("structexclude");
|
||||
|
||||
my %ahash = ( Fn=>"CommandAddStruct",
|
||||
@ -43,6 +47,7 @@ structure_Define($$)
|
||||
my $stype = shift(@a);
|
||||
|
||||
addToAttrList($stype);
|
||||
addToAttrList($stype . "_map");
|
||||
$hash->{ATTR} = $stype;
|
||||
|
||||
my %list;
|
||||
@ -70,6 +75,171 @@ structure_Undef($$)
|
||||
return undef;
|
||||
}
|
||||
|
||||
#############################
|
||||
# returns the unique keys of the given array
|
||||
# @my_array = ("one","two","three","two","three");
|
||||
# print join(" ", @my_array), "\n";
|
||||
# print join(" ", uniq(@my_array)), "\n";
|
||||
|
||||
sub uniq {
|
||||
return keys %{{ map { $_ => 1 } @_ }};
|
||||
}
|
||||
|
||||
|
||||
#############################
|
||||
sub structure_Notify($$)
|
||||
{
|
||||
my ($hash, $dev) = @_;
|
||||
#Log 1, Dumper($hash);
|
||||
my $me = $hash->{NAME};
|
||||
my $devmap = $hash->{ATTR}."_map";
|
||||
|
||||
# lade das Verhalten, Standard ist absolute
|
||||
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
|
||||
# Struktur ist
|
||||
return "" if (!$hash->{CONTENT}->{$dev->{NAME}});
|
||||
|
||||
# hier nur den Struktur-Status anpassen wenn
|
||||
# a) behavior=absolute oder
|
||||
# b) behavior=relative UND das Attr clientstate_priority gefaellt ist
|
||||
my @structPrio = split(" ", $attr{$me}{clientstate_priority})
|
||||
if($attr{$me}{clientstate_priority});
|
||||
return "" if (!@structPrio && $behavior eq "relative");
|
||||
|
||||
# assoziatives Array aus Prioritaetsliste aufbauen
|
||||
# Bsp: Original: "On|An Off|Aus"
|
||||
# wobei der erste Wert der "Oder"-Liste als Status der Struktur uebernommen
|
||||
# wird hier also On oder Off
|
||||
# priority[On]=0
|
||||
# priority[An]=0
|
||||
# priority[Off]=1
|
||||
# priority[Aus]=1
|
||||
my %priority;
|
||||
my (@priority, @foo);
|
||||
for (my $i=0; $i<@structPrio; $i++) {
|
||||
@foo = split(/\|/, $structPrio[$i]);
|
||||
for (my $j=0; $j<@foo;$j++) {
|
||||
$priority{$foo[$j]} = $i+1;
|
||||
$priority[$i+1]=$foo[0];
|
||||
}
|
||||
}
|
||||
undef @foo;
|
||||
undef @structPrio;
|
||||
#Log 1, Dumper(%priority) . "\n";
|
||||
|
||||
$hash->{INSET} = 1;
|
||||
|
||||
my $minprio = 99999;
|
||||
my $devstate;
|
||||
|
||||
#ueber jedes Device das zu dieser Struktur gehoert
|
||||
foreach my $d (sort keys %{ $hash->{CONTENT} }) {
|
||||
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
|
||||
# beruecksichtigt
|
||||
if($attr{$d} && $attr{$d}{structexclude}) {
|
||||
my $se = $attr{$d}{structexclude};
|
||||
next if($hash->{NAME} =~ m/$se/);
|
||||
}
|
||||
|
||||
|
||||
# Status des Devices gemaess den Regeln des gesetztes StrukturAttr
|
||||
# umformatieren
|
||||
if ($attr{$d}{$devmap}) {
|
||||
my @gruppe = split(" ", $attr{$d}{$devmap});
|
||||
my @value;
|
||||
for (my $i=0; $i<@gruppe; $i++) {
|
||||
@value = split(":", $gruppe[$i]);
|
||||
if(@value == 1) {
|
||||
# nur das zu lesende Reading ist angegeben, zb. bei 1wire Modul
|
||||
# OWSWITCH
|
||||
#Bsp: A --> nur Reading A gehuert zur Struktur
|
||||
#Bsp: A B --> Reading A und B gehuert zur Struktur
|
||||
$devstate = ReadingsVal($d, $value[0], undef);
|
||||
push(@clientstate, $devstate);
|
||||
} elsif(@value == 2) {
|
||||
# zustand wenn der Status auf dem in der Struktur definierten
|
||||
# umdefiniert werden muss
|
||||
# bsp: on:An
|
||||
if($devstate eq $value[0]){
|
||||
$devstate = $value[1];
|
||||
push(@clientstate, $devstate);
|
||||
$i=99999;
|
||||
}
|
||||
} elsif(@value == 3) {
|
||||
# Das zu lesende Reading wurde mit angegeben:
|
||||
# Reading:OriginalStatus:NeuerStatus wenn zb. ein Device mehrere
|
||||
# Readings abbildet, zb. 1wire DS2406, DS2450 Bsp: A:Zu.:Geschlossen
|
||||
$devstate = ReadingsVal($d, $value[0], undef);
|
||||
if($devstate eq $value[1]){
|
||||
$devstate = $value[2];
|
||||
push(@clientstate, $devstate);
|
||||
# $i=99999; entfernt, wenn Device mehrere Ports/Readings abbildet
|
||||
# wird beim ersten Auftreten sonst nicht weiter geprueft
|
||||
}
|
||||
}
|
||||
# Log 1, "Dev: ".$d." Anzahl: ".@value." Value:".$value[0]." devstate:
|
||||
# ".$devstate;
|
||||
$minprio = $priority{$devstate}
|
||||
if($devstate &&
|
||||
$priority{$devstate} &&
|
||||
$priority{$devstate} < $minprio);
|
||||
}
|
||||
} else {
|
||||
# falls kein mapping im Device angegeben wurde
|
||||
$devstate = ReadingsVal($d, "state", undef);
|
||||
$minprio = $priority{$devstate}
|
||||
if($devstate &&
|
||||
$priority{$devstate} &&
|
||||
$priority{$devstate} < $minprio);
|
||||
push(@clientstate, $devstate);
|
||||
}
|
||||
|
||||
#besser als 1 kann minprio nicht werden
|
||||
last if($minprio == 1);
|
||||
} #foreach
|
||||
|
||||
@clientstate = uniq(@clientstate);# eleminiere alle Dubletten
|
||||
|
||||
#ermittle Endstatus
|
||||
my $newState;
|
||||
if($behavior eq "absolute"){
|
||||
# wenn absolute, dann gebe undefinierten Status aus falls die Clients
|
||||
# unterschiedliche Status' haben
|
||||
if(@clientstate > 1) { $newState = "undefined";}
|
||||
else { $newState = $clientstate[0];}
|
||||
} elsif($behavior eq "relative" && $minprio < 99999) {
|
||||
$newState = $priority[$minprio];
|
||||
} else {
|
||||
$newState = "undefined";
|
||||
}
|
||||
|
||||
|
||||
#eigenen Status jetzt setzen, nur wenn abweichend
|
||||
if($hash->{STATE} ne $newState) {
|
||||
Log 3, "Update structure '" .$me . "' to " . $newState .
|
||||
" because device '" .$dev->{NAME}. "' has changed";
|
||||
$hash->{STATE} = $newState;
|
||||
readingsBeginUpdate($hash);
|
||||
readingsUpdate($hash, "state", $newState);
|
||||
readingsEndUpdate($hash, 1);
|
||||
}
|
||||
#Log 1, "devstate: ".$devstate." - minprio final: " . $minprio . "\n";
|
||||
#Log 1, Dumper(%priority);
|
||||
delete($hash->{INSET});
|
||||
|
||||
undef;
|
||||
}
|
||||
|
||||
#####################################
|
||||
sub
|
||||
|
@ -5385,6 +5385,7 @@ To send the data, both send or write could be used.<br>
|
||||
Notice: All links are relative to <code>http://hostname:8083/fhem</code>.
|
||||
</ul>
|
||||
<br><br>
|
||||
</ul>
|
||||
|
||||
<a name="USF1000"></a>
|
||||
<h3>USF1000</h3>
|
||||
@ -7921,6 +7922,7 @@ This module supports Samsung TV devices with few commands. It's developed and te
|
||||
|
||||
<b>Get</b><br>
|
||||
<ul>N/A</ul><br>
|
||||
</ul>
|
||||
|
||||
|
||||
<a name="NetIO230B"></a>
|
||||
@ -10498,29 +10500,27 @@ KlikAanKlikUit, NEXA, CHACON, HomeEasy UK. <br> You need to define an RFXtrx433
|
||||
|
||||
</ul>
|
||||
|
||||
|
||||
<a name="structure"></a>
|
||||
<h3>structure</h3>
|
||||
<ul>
|
||||
<br>
|
||||
|
||||
<a name="structuredefine"></a>
|
||||
<b>Define</b>
|
||||
<ul>
|
||||
<code>define <name> structure <struct_type> <dev1> <dev2> ...</code>
|
||||
<br><br>
|
||||
|
||||
The structure device is used to organize/structure a devices in order to
|
||||
The structure device is used to organize/structure devices in order to
|
||||
set groups of them at once (e.g. switching everything off in a house).<br>
|
||||
|
||||
The list of attached devices can be modified through the addstruct /
|
||||
delstruct commands. Each attached device will get the attribute
|
||||
<struct_type>=<name><br> when it is added to the list, and the
|
||||
attribute will be deleted if the device is deleted from the structure.
|
||||
Exception to this are the attributes room and alias. The structure devices
|
||||
can also be added to a structure, e.g. you can have a building consisting
|
||||
of levels which consists of rooms of devices.
|
||||
<br>
|
||||
The structure devices can also be added to a structure, e.g. you can have
|
||||
a building consisting of levels which consists of rooms of devices.
|
||||
<br>
|
||||
|
||||
Example:<br>
|
||||
<ul>
|
||||
<li>define kitchen structure room lamp1 lamp2</li>
|
||||
@ -10529,9 +10529,45 @@ KlikAanKlikUit, NEXA, CHACON, HomeEasy UK. <br> You need to define an RFXtrx433
|
||||
<li>define house structure building kitchen living</li>
|
||||
<li>set house off</li>
|
||||
</ul>
|
||||
</ul>
|
||||
<br>
|
||||
<br>
|
||||
|
||||
The backward propagated status change from the devices to this structure
|
||||
works in two different ways.
|
||||
<br>Attribute clientstate_behavior<br>
|
||||
<li>absolute</li>
|
||||
<ul>
|
||||
The structure status will changed to the common device status of all defined devices
|
||||
to this structure if all devices are identical. Otherwise the structure status is "undefined".
|
||||
</ul>
|
||||
<li>relative</li>
|
||||
<ul>
|
||||
You have to set the attribute "clientstate_priority" with all states of
|
||||
the defined devices to this structure in descending order. Each group are
|
||||
delemited by space. Each entry of one group are delimited by "pipe"
|
||||
</ul>
|
||||
<br>Example:<br>
|
||||
<ul>
|
||||
<li>attr kittchen clientstate_behavior relative</li>
|
||||
<li>attr kittchen clientstate_priority An|On|on Aus|Off|off</li>
|
||||
<li>attr house clientstate_priority Any_On|An All_Off|Aus</li>
|
||||
</ul>
|
||||
<br>
|
||||
To group more devices from different types of devices you can define
|
||||
a clientstate redefining on each device. For example the Reading "A" of device door
|
||||
is "open" or "closed" and the state of device lamp1 should redefine from
|
||||
"on" to "An" and "off" to "Aus"
|
||||
<br>Example:<br>
|
||||
<ul>
|
||||
<li>define door OWSWITCH <ROMID></li>
|
||||
<li>define lamp1 dummy</li>
|
||||
<li>attr lamp1 cmdlist on off</li>
|
||||
<li>define kitchen structure struct_kitchen lamp1 door</li>
|
||||
<li>attr kittchen clientstate_priority An|on OK|Aus|off</li>
|
||||
<li>attr lamp1 struct_kitchen on:An off:Aus</li>
|
||||
<li>attr door struct_kitchen A:open:on A:closed:off</li>
|
||||
</ul>
|
||||
|
||||
<br>
|
||||
<a name="structureset"></a>
|
||||
<b>Set</b>
|
||||
<ul>
|
||||
@ -10540,15 +10576,12 @@ KlikAanKlikUit, NEXA, CHACON, HomeEasy UK. <br> You need to define an RFXtrx433
|
||||
matches (as a regexp) the name of the current structure.
|
||||
</ul>
|
||||
<br>
|
||||
|
||||
<a name="structureget"></a>
|
||||
<b>Get</b>
|
||||
<ul>
|
||||
get is not supported through a structure device.
|
||||
</ul>
|
||||
<br>
|
||||
|
||||
|
||||
<a name="structureattr"></a>
|
||||
<b>Attributes</b>
|
||||
<ul>
|
||||
@ -10556,10 +10589,8 @@ KlikAanKlikUit, NEXA, CHACON, HomeEasy UK. <br> You need to define an RFXtrx433
|
||||
exclude the device from set operations, see the set command above.</li>
|
||||
</ul>
|
||||
<br>
|
||||
|
||||
</ul>
|
||||
|
||||
|
||||
<a name="watchdog"></a>
|
||||
<h3>watchdog</h3>
|
||||
<ul>
|
||||
|
Loading…
Reference in New Issue
Block a user