mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-04-21 01:46:08 +00:00
bugfix: publish with wildcards, subscribe multiple target
git-svn-id: https://svn.fhem.de/fhem/trunk@17676 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
6f7a4b0c4f
commit
f865ab0821
@ -30,6 +30,12 @@
|
|||||||
#
|
#
|
||||||
# CHANGE LOG
|
# CHANGE LOG
|
||||||
#
|
#
|
||||||
|
# 04.11.2018 0.9.9
|
||||||
|
# bugfix : Bei Mehrfachdefinitionen wie 'a|b|c:topic=some/$reading/thing'
|
||||||
|
# wurden beim Treffer alle genannten Readings aktualisiert
|
||||||
|
# anstatt nur der einer passenden.
|
||||||
|
# change : forward blockieren nur fuer Readings (mode 'R').
|
||||||
|
#
|
||||||
# 18.10.2018 0.9.9
|
# 18.10.2018 0.9.9
|
||||||
# bugfix : qos/retain/expression aus 'mqttDefaults' in Device wurden nicht
|
# bugfix : qos/retain/expression aus 'mqttDefaults' in Device wurden nicht
|
||||||
# verwendet (Fehler bei der Suche (Namen))
|
# verwendet (Fehler bei der Suche (Namen))
|
||||||
@ -888,37 +894,38 @@ sub getDevicePublishRecIntern($$$$$) {
|
|||||||
|
|
||||||
# reading map
|
# reading map
|
||||||
my $readingMap = $publishMap->{$reading} if defined $publishMap;
|
my $readingMap = $publishMap->{$reading} if defined $publishMap;
|
||||||
#my $defaultReadingMap = $publishMap->{'*'} if defined $publishMap;
|
my $wildcardReadingMap = $publishMap->{'*'} if defined $publishMap;
|
||||||
my $defaultReadingMap = $devMap->{':defaults'} if defined $publishMap;
|
#my $defaultReadingMap = $devMap->{':defaults'} if defined $devMap;
|
||||||
|
|
||||||
# global reading map
|
# global reading map
|
||||||
my $globalReadingMap = $globalPublishMap->{$reading} if defined $globalPublishMap;
|
my $globalReadingMap = $globalPublishMap->{$reading} if defined $globalPublishMap;
|
||||||
my $globalDefaultReadingMap = $globalPublishMap->{'*'} if defined $globalPublishMap;
|
my $globalWildcardReadingsMap = $globalPublishMap->{'*'} if defined $globalPublishMap;
|
||||||
|
|
||||||
#Log3('xxx',1,"MQTT_GENERIC_BRIDGE:DEBUG:> getDevicePublishRec> readingMap ".Dumper($readingMap));
|
#Log3('xxx',1,"MQTT_GENERIC_BRIDGE:DEBUG:> getDevicePublishRec> readingMap ".Dumper($readingMap));
|
||||||
#Log3('xxx',1,"MQTT_GENERIC_BRIDGE:DEBUG:> getDevicePublishRec> defaultReadingMap ".Dumper($defaultReadingMap));
|
#Log3('xxx',1,"MQTT_GENERIC_BRIDGE:DEBUG:> getDevicePublishRec> wildcardReadingMap ".Dumper($wildcardReadingMap));
|
||||||
#Log3('xxx',1,"MQTT_GENERIC_BRIDGE:DEBUG:> getDevicePublishRec> readingMap ".Dumper($globalReadingMap));
|
#Log3('xxx',1,"MQTT_GENERIC_BRIDGE:DEBUG:> getDevicePublishRec> readingMap ".Dumper($globalReadingMap));
|
||||||
#Log3('xxx',1,"MQTT_GENERIC_BRIDGE:DEBUG:> getDevicePublishRec> defaultReadingMap ".Dumper($globalDefaultReadingMap));
|
#Log3('xxx',1,"MQTT_GENERIC_BRIDGE:DEBUG:> getDevicePublishRec> wildcardReadingMap ".Dumper($globalWildcardReadingsMap));
|
||||||
# topic
|
# topic
|
||||||
my $topic = undef;
|
my $topic = undef;
|
||||||
$topic = $readingMap->{'topic'} if defined $readingMap;
|
$topic = $readingMap->{'topic'} if defined $readingMap;
|
||||||
$topic = $defaultReadingMap->{'topic'} if (defined($defaultReadingMap) and !defined($topic));
|
$topic = $wildcardReadingMap->{'topic'} if (defined($wildcardReadingMap) and !defined($topic));
|
||||||
|
|
||||||
# global topic
|
# global topic
|
||||||
$topic = $globalReadingMap->{'topic'} if (defined($globalReadingMap) and !defined($topic));
|
$topic = $globalReadingMap->{'topic'} if (defined($globalReadingMap) and !defined($topic));
|
||||||
$topic = $globalDefaultReadingMap->{'topic'} if (defined($globalDefaultReadingMap) and !defined($topic));
|
$topic = $globalWildcardReadingsMap->{'topic'} if (defined($globalWildcardReadingsMap) and !defined($topic));
|
||||||
|
|
||||||
# attr-topic
|
# attr-topic
|
||||||
my $atopic = undef;
|
my $atopic = undef;
|
||||||
$atopic = $readingMap->{'atopic'} if defined $readingMap;
|
$atopic = $readingMap->{'atopic'} if defined $readingMap;
|
||||||
$atopic = $defaultReadingMap->{'atopic'} if (defined($defaultReadingMap) and !defined($atopic));
|
$atopic = $wildcardReadingMap->{'atopic'} if (defined($wildcardReadingMap) and !defined($atopic));
|
||||||
|
|
||||||
# global attr-topic
|
# global attr-topic
|
||||||
$atopic = $globalReadingMap->{'atopic'} if (defined($globalReadingMap) and !defined($atopic));
|
$atopic = $globalReadingMap->{'atopic'} if (defined($globalReadingMap) and !defined($atopic));
|
||||||
$atopic = $globalDefaultReadingMap->{'atopic'} if (defined($globalDefaultReadingMap) and !defined($atopic));
|
$atopic = $globalWildcardReadingsMap->{'atopic'} if (defined($globalWildcardReadingsMap) and !defined($atopic));
|
||||||
|
|
||||||
# qos & retain & expression
|
# qos & retain & expression
|
||||||
my($qos, $retain, $expression) = retrieveQosRetainExpression($globalDefaultReadingMap, $globalReadingMap, $defaultReadingMap, $readingMap);
|
#my($qos, $retain, $expression) = retrieveQosRetainExpression($globalWildcardReadingsMap, $globalReadingMap, $wildcardReadingMap, $readingMap);
|
||||||
|
my($qos, $retain, $expression) = retrieveQosRetainExpression($globalMap->{':defaults'}, $globalReadingMap, $devMap->{':defaults'}, $readingMap);
|
||||||
|
|
||||||
# wenn kein topic und keine expression definiert sind, kann auch nicht gesendet werden, es muss nichts mehr ausgewertet werden
|
# wenn kein topic und keine expression definiert sind, kann auch nicht gesendet werden, es muss nichts mehr ausgewertet werden
|
||||||
return unless (defined($topic) or defined($atopic) or defined( $expression));
|
return unless (defined($topic) or defined($atopic) or defined( $expression));
|
||||||
@ -926,10 +933,10 @@ sub getDevicePublishRecIntern($$$$$) {
|
|||||||
# resendOnConnect Option
|
# resendOnConnect Option
|
||||||
my $resendOnConnect = undef;
|
my $resendOnConnect = undef;
|
||||||
$resendOnConnect = $readingMap->{'resendOnConnect'} if defined $readingMap;
|
$resendOnConnect = $readingMap->{'resendOnConnect'} if defined $readingMap;
|
||||||
$resendOnConnect = $defaultReadingMap->{'resendOnConnect'} if (defined($defaultReadingMap) and !defined($resendOnConnect));
|
$resendOnConnect = $wildcardReadingMap->{'resendOnConnect'} if (defined($wildcardReadingMap) and !defined($resendOnConnect));
|
||||||
# global
|
# global
|
||||||
$resendOnConnect = $globalReadingMap->{'resendOnConnect'} if (defined($globalReadingMap) and !defined($resendOnConnect));
|
$resendOnConnect = $globalReadingMap->{'resendOnConnect'} if (defined($globalReadingMap) and !defined($resendOnConnect));
|
||||||
$resendOnConnect = $globalDefaultReadingMap->{'resendOnConnect'} if (defined($globalDefaultReadingMap) and !defined($resendOnConnect));
|
$resendOnConnect = $globalWildcardReadingsMap->{'resendOnConnect'} if (defined($globalWildcardReadingsMap) and !defined($resendOnConnect));
|
||||||
|
|
||||||
# map name
|
# map name
|
||||||
my $name = undef;
|
my $name = undef;
|
||||||
@ -1135,12 +1142,21 @@ sub searchDeviceForTopic($$) {
|
|||||||
#Log3($hash->{NAME},1,"MQTT_GENERIC_BRIDGE:DEBUG:> searchDeviceForTopic: >>>: \$+{name}: ".$+{name}.", \$+{reading}: ".$+{reading});
|
#Log3($hash->{NAME},1,"MQTT_GENERIC_BRIDGE:DEBUG:> searchDeviceForTopic: >>>: \$+{name}: ".$+{name}.", \$+{reading}: ".$+{reading});
|
||||||
# Check named groups: $+{reading},..
|
# Check named groups: $+{reading},..
|
||||||
my $reading = undef;
|
my $reading = undef;
|
||||||
if($rmap->{'wildcardTarget'}) {
|
my $oReading = $rmap->{'reading'};
|
||||||
$reading = $+{name} unless defined $reading;
|
my $nReading = $+{name};
|
||||||
# Remap name
|
$nReading = $+{reading} unless defined $nReading;
|
||||||
$reading = $+{reading} unless defined $reading;
|
if((!defined($nReading)) or ($oReading eq $nReading)) {
|
||||||
|
$reading = $oReading;
|
||||||
}
|
}
|
||||||
$reading = $rmap->{'reading'} unless defined $reading;
|
if($rmap->{'wildcardTarget'}) {
|
||||||
|
# $reading = $+{name} unless defined $reading;
|
||||||
|
# # Remap name
|
||||||
|
# $reading = $+{reading} unless defined $reading;
|
||||||
|
$reading = $nReading;
|
||||||
|
}
|
||||||
|
#$reading = $rmap->{'reading'} unless defined $reading;
|
||||||
|
next unless defined $reading;
|
||||||
|
#Log3($hash->{NAME},1,"MQTT_GENERIC_BRIDGE:DEBUG:> searchDeviceForTopic: match topic: $topic, reading: $reading, nREading: $nReading, oReading: $oReading");
|
||||||
my $tn = $dname.':'.$reading;
|
my $tn = $dname.':'.$reading;
|
||||||
$ret->{$tn}->{'mode'}=$rmap->{'mode'};
|
$ret->{$tn}->{'mode'}=$rmap->{'mode'};
|
||||||
$ret->{$tn}->{'reading'}=$reading;
|
$ret->{$tn}->{'reading'}=$reading;
|
||||||
@ -2293,9 +2309,9 @@ sub doSetUpdate($$$$$) {
|
|||||||
# R - Normale Topic (beim Empfang nicht weiter publishen)
|
# R - Normale Topic (beim Empfang nicht weiter publishen)
|
||||||
# T - Selt-Trigger-Topic (Sonderfall, auch wenn gerade empfangen, kann weiter getriggert/gepublisht werden. Vorsicht! Gefahr von 'Loops'!)
|
# T - Selt-Trigger-Topic (Sonderfall, auch wenn gerade empfangen, kann weiter getriggert/gepublisht werden. Vorsicht! Gefahr von 'Loops'!)
|
||||||
readingsBeginUpdate($dhash);
|
readingsBeginUpdate($dhash);
|
||||||
#if ($mode eq 'R') {
|
if ($mode eq 'R') {
|
||||||
$dhash->{'.mqttGenericBridge_triggeredReading'}=$reading unless $doForward;
|
$dhash->{'.mqttGenericBridge_triggeredReading'}=$reading unless $doForward;
|
||||||
#}
|
}
|
||||||
readingsBulkUpdate($dhash,$reading,$message);
|
readingsBulkUpdate($dhash,$reading,$message);
|
||||||
readingsEndUpdate($dhash,1);
|
readingsEndUpdate($dhash,1);
|
||||||
# wird in 'notify' entfernt # delete $dhash->{'.mqttGenericBridge_triggeredReading'};
|
# wird in 'notify' entfernt # delete $dhash->{'.mqttGenericBridge_triggeredReading'};
|
||||||
@ -2639,9 +2655,11 @@ sub onmessage($$$) {
|
|||||||
Furthermore the attribute 'qos' can be specified ('retain' does not make sense here).<br/>
|
Furthermore the attribute 'qos' can be specified ('retain' does not make sense here).<br/>
|
||||||
Topic definition can include MQTT wildcards (+ and #).<br/>
|
Topic definition can include MQTT wildcards (+ and #).<br/>
|
||||||
If the reading name is defined with a '*' at the beginning, it will act as a wildcard.
|
If the reading name is defined with a '*' at the beginning, it will act as a wildcard.
|
||||||
|
Several definitions with '*' should also be used as: *1:topic = ... *2:topic = ...
|
||||||
The actual name of the reading (and possibly of the device) is defined by variables from the topic
|
The actual name of the reading (and possibly of the device) is defined by variables from the topic
|
||||||
($device (only for global definition in the bridge), $reading, $name).
|
($device (only for global definition in the bridge), $reading, $name).
|
||||||
In the topic these variables act as wildcards, of course only makes sense, if reading-name is not defined (so start with '*').<br/>
|
In the topic these variables act as wildcards, of course only makes sense, if reading-name is not defined
|
||||||
|
(so start with '*', or multiple names separated with '|').<br/>
|
||||||
The variable $name, unlike $reading, may be affected by the aliases defined in 'mqttAlias'. Also use of $base is allowed.<br/>
|
The variable $name, unlike $reading, may be affected by the aliases defined in 'mqttAlias'. Also use of $base is allowed.<br/>
|
||||||
When using 'stopic', the 'set' command is executed as 'set <dev> <reading> <value>'.
|
When using 'stopic', the 'set' command is executed as 'set <dev> <reading> <value>'.
|
||||||
For something like 'set <dev> <value>' 'state' should be used as reading-name.</p>
|
For something like 'set <dev> <value>' 'state' should be used as reading-name.</p>
|
||||||
@ -3027,9 +3045,11 @@ sub onmessage($$$) {
|
|||||||
Weiterhin kann das Attribut 'qos' angegeben werden ('retain' macht dagegen keinen Sinn).<br/>
|
Weiterhin kann das Attribut 'qos' angegeben werden ('retain' macht dagegen keinen Sinn).<br/>
|
||||||
In der Topic-Definition koennen MQTT-Wildcards (+ und #) verwendet werden. <br/>
|
In der Topic-Definition koennen MQTT-Wildcards (+ und #) verwendet werden. <br/>
|
||||||
Falls der Reading-Name mit einem '*'-Zeichen am Anfang definiert wird, gilt dieser als 'Platzhalter'.
|
Falls der Reading-Name mit einem '*'-Zeichen am Anfang definiert wird, gilt dieser als 'Platzhalter'.
|
||||||
|
Mehrere Definitionen mit '*' sollten somit z.B. in folgender Form verwendet werden: *1:topic=... *2:topic=...
|
||||||
Der tatsaechliche Name der Reading (und ggf. des Geraetes) wird dabei durch Variablen aus dem Topic
|
Der tatsaechliche Name der Reading (und ggf. des Geraetes) wird dabei durch Variablen aus dem Topic
|
||||||
definiert ($device (nur fuer globale Definition in der Bridge), $reading, $name).
|
definiert ($device (nur fuer globale Definition in der Bridge), $reading, $name).
|
||||||
Im Topic wirken diese Variablen als Wildcards, macht natuerlich nur Sinn, wenn Reading-Name auch nicht fest definiert ist (also faengt mit '*' an). <br/>
|
Im Topic wirken diese Variablen als Wildcards, macht natuerlich nur Sinn, wenn Reading-Name auch nicht fest definiert ist
|
||||||
|
(also faengt mit '*' an, oder mehrere Namen durch '|' getrennt definiert werden). <br/>
|
||||||
Die Variable $name wird im Unterschied zu $reading ggf. ueber die in 'mqttAlias' definierten Aliases beeinflusst.
|
Die Variable $name wird im Unterschied zu $reading ggf. ueber die in 'mqttAlias' definierten Aliases beeinflusst.
|
||||||
Auch Verwendung von $base ist erlaubt.<br/>
|
Auch Verwendung von $base ist erlaubt.<br/>
|
||||||
Bei Verwendung von 'stopic' wird das 'set'-Befehl als 'set <dev> <reading> <value>' ausgefuert.
|
Bei Verwendung von 'stopic' wird das 'set'-Befehl als 'set <dev> <reading> <value>' ausgefuert.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user