mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-04-07 19:04:20 +00:00
98_cloneDummy: Erweiterung addAtateFormat, Fehlerbeseitigun bei mehrfachreadings
git-svn-id: https://svn.fhem.de/fhem/trunk@5919 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
f4cb153bdc
commit
ea0c197c1b
@ -1,38 +1,55 @@
|
|||||||
# $Id$
|
# $Id$
|
||||||
##############################################
|
################################################################################
|
||||||
# 98_cloneDummy
|
# 98_cloneDummy
|
||||||
# Von Joachim Herold
|
# Von Joachim Herold
|
||||||
# FHEM Modul um aus Events von FHEM2FHEM clone-Devices zu erstellen
|
# FHEM Modul um aus Events von FHEM2FHEM clone-Devices zu erstellen
|
||||||
# cloneDummy ist "readonly"
|
# cloneDummy ist "readonly"
|
||||||
# Grundlage ist 98_dummy.pm von Rudolf Koenig
|
# Grundlage ist 98_dummy.pm von Rudolf Koenig
|
||||||
# von betateilchen gab es viel Hilfe (eigentlich wars betateilchen)
|
# von betateilchen gab es viel Hilfe (eigentlich wars betateilchen)
|
||||||
|
# mit Erweiterungenen von gandy
|
||||||
|
#
|
||||||
# Anleitung:
|
# Anleitung:
|
||||||
# Um die Änderung zu nutzen, einfach einen cloneDummy anlegen
|
# Um cloneDummy zu nutzen, einfach einen cloneDummy anlegen
|
||||||
#
|
#
|
||||||
# Eintrag in der fhem.cfg:
|
# Eintrag in der fhem.cfg:
|
||||||
# define <name> cloneDummy <quellDevice> [reading]
|
# define <name> cloneDummy <quellDevice> [reading]
|
||||||
# attr <name> cloneIgnore <reading1,reading2,...,readingX>
|
# attr <name> cloneIgnore <reading1,reading2,...,readingX>
|
||||||
|
# attr <name> addStateEvent 1 (0 ist Vorgabe)
|
||||||
#
|
#
|
||||||
#############################################
|
#
|
||||||
|
################################################################################
|
||||||
|
|
||||||
package main;
|
package main;
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
use warnings;
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
# Initialisierung des Moduls
|
||||||
|
################################################################################
|
||||||
sub cloneDummy_Initialize($) {
|
sub cloneDummy_Initialize($) {
|
||||||
my ($hash) = @_;
|
my ($hash) = @_;
|
||||||
|
|
||||||
$hash->{DefFn} = "cloneDummy_Define";
|
$hash->{DefFn} = "cloneDummy_Define";
|
||||||
$hash->{NotifyFn} = "cloneDummy_Notify";
|
$hash->{NotifyFn} = "cloneDummy_Notify";
|
||||||
$hash->{AttrList} = "cloneIgnore ".$readingFnAttributes;
|
$hash->{AttrList} = "cloneIgnore "
|
||||||
|
."addStateEvent:0,1 "
|
||||||
|
.$readingFnAttributes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
# Definition des Moduls
|
||||||
|
################################################################################
|
||||||
sub cloneDummy_Define($$) {
|
sub cloneDummy_Define($$) {
|
||||||
my ($hash, $def) = @_;
|
my ($hash, $def) = @_;
|
||||||
my @a = split("[ \t][ \t]*", $def);
|
my @a = split("[ \t][ \t]*", $def);
|
||||||
return "Wrong syntax: use define <name> cloneDummy <sourceDevice> [reading]" if((int(@a) < 3 || int(@a) > 4)) ;
|
|
||||||
return "Error: cloneDummy and sourceDevice must not have the same name!" if($a[0] eq $a[2]);
|
return "Wrong syntax: use define <name> cloneDummy <sourceDevice> [reading]"
|
||||||
|
if((int(@a) < 3 || int(@a) > 4)) ;
|
||||||
|
|
||||||
|
return "Error: cloneDummy and sourceDevice must not have the same name!"
|
||||||
|
if($a[0] eq $a[2]);
|
||||||
|
|
||||||
my $hn = $hash->{NAME};
|
my $hn = $hash->{NAME};
|
||||||
$hash->{NOTIFYDEV} = $a[2];
|
$hash->{NOTIFYDEV} = $a[2];
|
||||||
$hash->{NOTIFYSTATE} = $a[3] if(defined($a[3]));
|
$hash->{NOTIFYSTATE} = $a[3] if(defined($a[3]));
|
||||||
@ -42,47 +59,48 @@ sub cloneDummy_Define($$) {
|
|||||||
return undef;
|
return undef;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
# auslesen der Daten aus der globalen Schleife und aufbereiten der Daten
|
||||||
|
################################################################################
|
||||||
sub cloneDummy_Notify($$) {
|
sub cloneDummy_Notify($$) {
|
||||||
my ($hash, $dev) = @_;
|
my ($hash, $dev) = @_;
|
||||||
my $dn = $dev->{NAME};
|
my $dn = $dev->{NAME}; # Devicename
|
||||||
my $hn = $hash->{NAME};
|
my $hn = $hash->{NAME}; # Quellname
|
||||||
my $hs = "";
|
my $hs = ""; # optionales reading fuer STATE
|
||||||
|
my $events = deviceEvents($dev, AttrVal($hn, "addStateEvent", 0)); # Quellevents
|
||||||
|
my $max = int(@{$events}); # Anzahl Quellevents
|
||||||
if(defined($hash->{NOTIFYSTATE})) {
|
if(defined($hash->{NOTIFYSTATE})) {
|
||||||
$hs = $hash->{NOTIFYSTATE};
|
$hs = $hash->{NOTIFYSTATE};
|
||||||
}
|
}
|
||||||
my $reading = $dev->{CHANGED}[0];
|
|
||||||
|
readingsSingleUpdate($hash,"state", "active",1);
|
||||||
|
readingsBeginUpdate($hash);
|
||||||
|
|
||||||
|
for(my $i=0;$i<$max;$i++){
|
||||||
|
my $reading = $events->[$i]; # Quellevents in einzelne Readings ueberfuehren
|
||||||
$reading = "" if(!defined($reading));
|
$reading = "" if(!defined($reading));
|
||||||
Log3($hash,4, "cloneDummy: $hash D: $dn R: $reading");
|
Log3($hash,4, "cloneDummy: $hash D: $dn R: $reading");
|
||||||
my ($rname,$rval) = split(/ /,$reading,2);
|
my ($rname,$rval) = split(/ /,$reading,2); # zerlegen des Quellevents in Name und Wert
|
||||||
$rname = substr($rname,0,length($rname)-1);
|
$rname = substr($rname,0,length($rname)-1);
|
||||||
my %check = map { $_ => 1 } split(/,/,AttrVal($hn,'cloneIgnore',''));
|
my %check = map { $_ => 1 } split(/,/,AttrVal($hn,'cloneIgnore','')); # vorbereitung cloneIgnore
|
||||||
|
my ($isdup, $idx) = CheckDuplicate("", "$hn: $reading", undef); # vorbereitung doppelte Readings entfernen
|
||||||
|
|
||||||
# When more than one FHEM2FHEM instance is used to tap into RF traffic,
|
if ($isdup) { # doppelte Readings filtern
|
||||||
# we may get duplicate readings for the same sensor information.
|
|
||||||
# Use CheckDuplicate to prevent multiple events in this case.
|
|
||||||
#
|
|
||||||
# Currently, clonedummy accepts a device name rather than a REGEXP, so
|
|
||||||
# we can assume that all duplicates will have the same device name
|
|
||||||
# (rather than different IODEV names as is the case with other modules)
|
|
||||||
# - so we ned to leave empty the first parameter for CheckDuplicate()
|
|
||||||
#
|
|
||||||
# If cloneDummy should be changed to accepting more than one device, we
|
|
||||||
# will may want to adapt the call to CheckDuplicate.
|
|
||||||
my ($isdup, $idx) = CheckDuplicate("", "$hn: $reading", undef);
|
|
||||||
if ($isdup) {
|
|
||||||
Log3 $hash, 4, "cloneDummy: drop duplicate <$dn> <$hn> <$reading> ***";
|
Log3 $hash, 4, "cloneDummy: drop duplicate <$dn> <$hn> <$reading> ***";
|
||||||
} else {
|
} else {
|
||||||
Log3 $hash, 4, "cloneDummy: publish unique <$dn> <$hn> <$reading>";
|
Log3 $hash, 4, "cloneDummy: publish unique <$dn> <$hn> <$reading>";
|
||||||
readingsBeginUpdate($hash);
|
|
||||||
if (($hs ne "") && ($rname eq $hs) ){
|
if (($hs ne "") && ($rname eq $hs) ){ # Reading in _state einsetzen
|
||||||
readingsBulkUpdate($hash,"_state", $reading);
|
readingsBulkUpdate($hash,"_state", $reading);
|
||||||
}
|
}
|
||||||
readingsBulkUpdate($hash,"state", "active");
|
unless (exists ($check{$rname})) { # zu ignorierende Reading filtern
|
||||||
unless (exists ($check{$rname})) {
|
|
||||||
readingsBulkUpdate($hash, $rname, $rval);
|
readingsBulkUpdate($hash, $rname, $rval);
|
||||||
}
|
}
|
||||||
readingsEndUpdate($hash, 1);
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
readingsEndUpdate($hash, 1);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,51 +111,59 @@ sub cloneDummy_Notify($$) {
|
|||||||
|
|
||||||
<a name="cloneDummy"></a>
|
<a name="cloneDummy"></a>
|
||||||
<h3>cloneDummy</h3>
|
<h3>cloneDummy</h3>
|
||||||
<ul>
|
<ul>This module provides a cloneDummy which will receive readings from any other device sending data
|
||||||
This module provides a cloneDummy which will receive readings from any other device sending data to fhem.<br/>
|
to fhem.<br>
|
||||||
E.g. may be used in an FHEM2FHEM environment.
|
E.g. may be used in an FHEM2FHEM environment. Duplicate source events which may occur within the
|
||||||
Duplicate source events which may occur within the time given by the global attribute <a href="#dupTimeout">dupTimeout</a>,
|
time given by the global attribute <a href="#dupTimeout">dupTimeout</a>, will be suppressed in order
|
||||||
will be suppressed in order to avoid overhead. The value of this attribute is to be changed with great care, as it
|
to avoid overhead. The value of this attribute is to be changed with great care, as it affects other
|
||||||
affects other parts of FHEM, too.
|
parts of FHEM, too.<br>
|
||||||
<br/>
|
the order of precedence for STATE is following:
|
||||||
<br/>
|
<ul><li>if there is no parameter preset then state of cloneDummy (initialized,active)</li>
|
||||||
|
<li>if addStateEvent is set then the "state" of cloned Device is set
|
||||||
<a name="cloneDummydefine"></a>
|
(no "state" from cloneDummy)</li>
|
||||||
<b>Define</b>
|
<li>if the optional reading is set in define, then value of the optional reading.
|
||||||
<ul>
|
(this will overstrike the previous two lines)</li>
|
||||||
<code>define <cloneDevice> cloneDummy <sourceDevice> [reading]</code>
|
<li>if stateFormat set ass attr, it will dominate all previous lines</li>
|
||||||
<br/>
|
|
||||||
<br/>
|
|
||||||
Example:<br/>
|
|
||||||
<br/>
|
|
||||||
<ul><code>define clone_OWX_26_09FF26010000 cloneDummy OWX_26_09FF26010000</code></ul>
|
|
||||||
<br/>
|
|
||||||
Optional parameter [reading] will be written to STATE if provided.<br/>
|
|
||||||
<br/>
|
|
||||||
Example:<br/>
|
|
||||||
<br/>
|
|
||||||
<ul><code>define clone_OWX_26_09FF26010000 cloneDummy OWX_26_09FF26010000 temperature</code></ul>
|
|
||||||
</ul>
|
</ul>
|
||||||
<br/>
|
<br><a name="cloneDummydefine"></a>
|
||||||
|
<b>Define</b>
|
||||||
<a name="cloneDummyset"></a>
|
<ul><code>define <cloneDevice> cloneDummy <sourceDevice> [reading]</code><br>
|
||||||
<b>Set</b> <ul>N/A</ul>
|
<br>Example:<br>
|
||||||
<br/>
|
<br>
|
||||||
|
<ul><code>define clone_OWX_26_09FF26010000 cloneDummy OWX_26_09FF26010000</code>
|
||||||
|
</ul>
|
||||||
|
<br>Optional parameter [reading] will be written to STATE if provided.<br>
|
||||||
|
<br>Example:<br>
|
||||||
|
<br>
|
||||||
|
<ul><code>define clone_OWX_26_09FF26010000 cloneDummy OWX_26_09FF26010000 temperature</code>
|
||||||
|
</ul>
|
||||||
|
<br>
|
||||||
|
</ul>
|
||||||
|
<a name="cloneDummyset"></a>
|
||||||
|
<b>Set</b>
|
||||||
|
<ul>N/A
|
||||||
|
</ul>
|
||||||
|
<br>
|
||||||
<a name="cloneDummyget"></a>
|
<a name="cloneDummyget"></a>
|
||||||
<b>Get</b> <ul>N/A</ul>
|
<b>Get</b>
|
||||||
<br/>
|
<ul>N/A
|
||||||
|
</ul>
|
||||||
|
<br>
|
||||||
<a name="cloneDummyattr"></a>
|
<a name="cloneDummyattr"></a>
|
||||||
<b>Attributes</b>
|
<b>Attributes</b>
|
||||||
<ul>
|
<ul><li>addStateEvent
|
||||||
<li><a href="#readingFnAttributes"><b>readingFnAttributes</b></a></li>
|
<br>When paremeter in Modul is set to 1 the originalstate of the original Device will be STATE
|
||||||
<li><b>cloneIgnore</b> - comma separated list of readingnames that will NOT be generated.<br/>
|
(Momentarily not possible in Connection with FHEM2FHEM)</li>
|
||||||
|
<br>
|
||||||
|
<li>cloneIgnore
|
||||||
|
<br>- comma separated list of readingnames that will NOT be generated.<br>
|
||||||
Usefull to prevent truncated readingnames coming from state events.</li>
|
Usefull to prevent truncated readingnames coming from state events.</li>
|
||||||
|
<br>
|
||||||
|
<li><a href="#readingFnAttributes">readingFnAttributes</a></li>
|
||||||
|
</ul>
|
||||||
|
<br>
|
||||||
|
<b>Important: You MUST use different names for cloneDevice and sourceDevice!</b><br>
|
||||||
</ul>
|
</ul>
|
||||||
<br/>
|
|
||||||
<b>Important: You MUST use different names for cloneDevice and sourceDevice!</b><br/>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
=end html
|
=end html
|
||||||
|
|
||||||
@ -145,49 +171,68 @@ sub cloneDummy_Notify($$) {
|
|||||||
|
|
||||||
<a name="cloneDummy"></a>
|
<a name="cloneDummy"></a>
|
||||||
<h3>cloneDummy</h3>
|
<h3>cloneDummy</h3>
|
||||||
<ul>
|
<ul>Definiert einen Klon eines lokalen Devices oder von FHEM2FHEM im Logmodus uebergebenen Devices
|
||||||
Definiert einen Clon eines Devices oder von FHEM2FHEM im Logmodus uebergebenen Devices und uebernimmt dessen Readings.
|
und uebernimmt dessen Readings. Sinnvoll um entfernte FHEM-Installationen lesend einzubinden,
|
||||||
Sinnvoll um entfernte FHEM-Installationen lesend einzubinden, zum Testen oder Programmieren.
|
zum Testen oder Programmieren. Dabei werden die von FHEM2FHEM in Form von Events weitergereichten
|
||||||
Dabei werden die von FHEM2FHEM in Form von Events weitergereichten entfernten Device-Readings in eigene Readings übernommen.
|
entfernten Device-Readings in eigene Readings übernommen. Identische Events, die innerhalb der
|
||||||
Identische Events, die innerhalb der durch das globale Attribut <a href="#dupTimeout">dupTimeout</a> vorgegebenen Zeit auftreten,
|
durch das globale Attribut <a href="#dupTimeout">dupTimeout</a> vorgegebenen Zeit auftreten, werden
|
||||||
werden zusammengefasst, um überflüssige Events zu verhindern. Dieses Attribut ist mit bedacht zu ändern, da sich seine Auswirkungen
|
zusammengefasst, um überflüssige Events zu verhindern. Dieses Attribut ist mit bedacht zu ändern,
|
||||||
auch auf andere Bereiche von FHEM erstreckt.
|
da sich seine Auswirkungen auch auf andere Bereiche von FHEM erstreckt.<br>
|
||||||
<br><br>
|
Die Rangfolge für den STATE ist:
|
||||||
|
<ul><li>wenn keine Vorgabe gemacht wurde, dann die Meldung von cloneDummy (initialized, active)</li>
|
||||||
|
<li>wenn addStateEvent gesetzt ist, dann der "state" vom geklonten Device (dann kein "state" mehr
|
||||||
|
vom cloneDummy)</li>
|
||||||
|
<li>wenn das optionale reading im define gesetzt ist, dann der Wert davon (überstimmt die beiden
|
||||||
|
vorherigen Zeilen)</li>
|
||||||
|
<li>wenn stateFormat als attr gesetzt ist, toppt das alles</li>
|
||||||
|
</ul>
|
||||||
|
<br>
|
||||||
<a name="cloneDummydefine"></a>
|
<a name="cloneDummydefine"></a>
|
||||||
<b>Define</b>
|
<b>Define</b>
|
||||||
<ul>
|
<ul><code>define <name> cloneDummy <Quelldevice> [reading]</code><br>
|
||||||
<code>define <name> cloneDummy <Quelldevice> [reading]</code>
|
<br>
|
||||||
<br><br>
|
Aktiviert den cloneDummy, der dann an das Device <Quelldevice> gebunden ist.
|
||||||
Aktiviert den cloneDummy, der dann an das Device <Quelldevice> gebunden ist. Mit dem optionalen Parameter reading
|
Mit dem optionalen Parameter reading wird bestimmt, welches reading im STATE angezeigt wird,
|
||||||
wird bestimmt, welches reading im STATE angezeigt wird, stateFormat ist auch weiterhin möglich.
|
stateFormat ist auch weiterhin möglich.<br>
|
||||||
<ul>
|
<br>
|
||||||
Beispiel: Der cloneDummy wird lesend an den Sensor OWX_26_09FF26010000 gebunden und zeigt im State temperature an.
|
<ul>Beispiel:<br>
|
||||||
|
<br>
|
||||||
|
Der cloneDummy wird lesend an den Sensor OWX_26_09FF26010000 gebunden und zeigt im
|
||||||
|
State temperature an.<br>
|
||||||
|
<br>
|
||||||
|
<ul><code>define Feuchte cloneDummy OWX_26_09FF26010000 temperature</code><br>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<ul>
|
|
||||||
<code>define Feuchte cloneDummy OWX_26_09FF26010000 temperature</code><br>
|
|
||||||
</ul>
|
</ul>
|
||||||
</ul>
|
</ul>
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
<a name="cloneDummyset"></a>
|
<a name="cloneDummyset"></a>
|
||||||
<b>Set</b> <ul>N/A</ul><br>
|
<b>Set</b>
|
||||||
|
<ul>N/A
|
||||||
|
</ul>
|
||||||
|
<br>
|
||||||
<a name="cloneDummyget"></a>
|
<a name="cloneDummyget"></a>
|
||||||
<b>Get</b> <ul>N/A</ul><br>
|
<b>Get</b>
|
||||||
|
<ul>N/A
|
||||||
|
</ul>
|
||||||
|
<br>
|
||||||
<a name="cloneDummyattr"></a>
|
<a name="cloneDummyattr"></a>
|
||||||
<b>Attributes</b>
|
<b>Attributes</b>
|
||||||
<ul>
|
<ul>
|
||||||
|
<li>addStateEvent<br>
|
||||||
|
0 ist Vorgabe im Modul, bei 1 wird der Originalstate des original Devices als STATE verwendet
|
||||||
|
(geht z.Z. nicht in Verbindung mit FHEM2FHEM)</li>
|
||||||
|
<br>
|
||||||
<li>clonIgnore<br>
|
<li>clonIgnore<br>
|
||||||
Eine durch Kommata getrennte Liste der readings, die cloneDummy nicht in eigene readings umwandelt
|
Eine durch Kommata getrennte Liste der readings, die cloneDummy nicht in eigene readings
|
||||||
</li><br>
|
umwandelt</li>
|
||||||
|
<br>
|
||||||
<li><a href="#readingFnAttributes">readingFnAttributes</a></li>
|
<li><a href="#readingFnAttributes">readingFnAttributes</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
<br>
|
<br>
|
||||||
<b>Wichtig: Es müssen unterschiedliche Namen für <name> und <Quelldevice> verwendet werden!</b><br/>
|
<b>Wichtig: Es müssen unterschiedliche Namen für <name> und <Quelldevice> verwendet
|
||||||
</ul>
|
werden!</b><br/>
|
||||||
|
<br>
|
||||||
|
</ul>
|
||||||
|
|
||||||
=end html_DE
|
=end html_DE
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user