mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-01-31 06:39:11 +00:00
00_MQTT: topics and payload patch (Forum: #86270)
git-svn-id: https://svn.fhem.de/fhem/trunk@16674 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
f416081f1f
commit
bee096a00c
@ -1,5 +1,6 @@
|
||||
# Add changes at the top of the list. Keep it in ASCII, and 80-char wide.
|
||||
# Do not insert empty lines here, update check depends on it.
|
||||
- bugfix: 00_MQTT: topics and payload patch
|
||||
- bugfix: 73_GardenaSmartBridge: fix fetch token after rereadcfg
|
||||
- feature: 60_allergy: alternative data source for extended 5 day forecast
|
||||
- new: 74_HusqvarnaAutomower.pm: New module to control your
|
||||
|
@ -242,11 +242,12 @@ sub Set($@) {
|
||||
};
|
||||
}
|
||||
|
||||
sub parseParams($;$$) {
|
||||
sub parseParams($;$$$$) {
|
||||
|
||||
my ( $cmd, $separator, $joiner ) = @_;
|
||||
my ( $cmd, $separator, $joiner, $keyvalueseparator, $acceptedkeys ) = @_;
|
||||
$separator = ' ' if ( !$separator );
|
||||
$joiner = $separator if ( !$joiner ); # needed if separator is a regexp
|
||||
$keyvalueseparator = ':' if(!$keyvalueseparator);
|
||||
my ( @a, %h );
|
||||
|
||||
my @params;
|
||||
@ -260,7 +261,7 @@ sub parseParams($;$$) {
|
||||
while (@params) {
|
||||
my $param = shift(@params);
|
||||
next if ( $param eq "" );
|
||||
my ( $key, $value ) = split( ':', $param, 2 );
|
||||
my ( $key, $value ) = split( $keyvalueseparator, $param, 2 );
|
||||
|
||||
if ( !defined($value) ) {
|
||||
$value = $key;
|
||||
@ -272,6 +273,16 @@ sub parseParams($;$$) {
|
||||
$value = $param;
|
||||
$key = undef;
|
||||
}
|
||||
# the key can not start with a ' or "
|
||||
elsif ( $key =~ m/^\s*('|")/ ) {
|
||||
$value = $param;
|
||||
$key = undef;
|
||||
}
|
||||
# accept known keys only (if defined $acceptedkeys)
|
||||
elsif (defined($acceptedkeys) and !defined($acceptedkeys->{$key})) {
|
||||
$value = $param;
|
||||
$key = undef;
|
||||
}
|
||||
|
||||
#collect all parts until the closing ' or "
|
||||
while ( $param && $value =~ m/^('|")/ && $value !~ m/$1$/ ) {
|
||||
@ -321,21 +332,15 @@ sub parseParams($;$$) {
|
||||
sub parsePublishCmdStr($) {
|
||||
my ($str) = @_;
|
||||
|
||||
if(defined($str) && $str=~m/\s*(?:({.*})\s+)?(.*)/) {
|
||||
my $exp = $1;
|
||||
my $rest = $2;
|
||||
if ($rest){
|
||||
my @lwa = split("[ \t]+",$rest);
|
||||
unshift (@lwa,$exp) if($exp);
|
||||
return undef unless defined($str);
|
||||
|
||||
my @lwa = split("[ \t]+",$str);
|
||||
return parsePublishCmd(@lwa);
|
||||
}
|
||||
}
|
||||
return undef;
|
||||
}
|
||||
|
||||
sub parsePublishCmd(@) {
|
||||
my @a = @_;
|
||||
my ( $aa, $bb ) = parseParams(\@a);
|
||||
my ( $aa, $bb ) = parseParams(\@a,undef,undef,undef,{qos=>1,retain=>1});
|
||||
|
||||
my $qos = 0;
|
||||
my $retain = 0;
|
||||
@ -356,7 +361,7 @@ sub parsePublishCmd(@) {
|
||||
|
||||
while ( scalar(@xaa) > 0 ) {
|
||||
my $av = shift @xaa;
|
||||
if ( $av =~ /\{.*\}/ ) {
|
||||
if (!defined($expression) and $av =~ /^\{.*\}$/ and scalar(@xaa)>0) {
|
||||
$expression = $av;
|
||||
next;
|
||||
}
|
||||
@ -695,6 +700,7 @@ sub send_message($$$@) {
|
||||
sub topic_to_regexp($) {
|
||||
my $t = shift;
|
||||
$t =~ s|#$|.\*|;
|
||||
$t =~ s|\$|\\\$|g;
|
||||
$t =~ s|\/\.\*$|.\*|;
|
||||
$t =~ s|\/|\\\/|g;
|
||||
$t =~ s|(\+)([^+]*$)|(+)$2|;
|
||||
@ -705,6 +711,7 @@ sub topic_to_regexp($) {
|
||||
sub client_subscribe_topic($$;$$) {
|
||||
my ($client,$topic,$qos,$retain) = @_;
|
||||
push @{$client->{subscribe}},$topic unless grep {$_ eq $topic} @{$client->{subscribe}};
|
||||
$client->{subscribeQos}->{$topic}=$qos;
|
||||
my $expr = topic_to_regexp($topic);
|
||||
push @{$client->{subscribeExpr}},$expr unless grep {$_ eq $expr} @{$client->{subscribeExpr}};
|
||||
if ($main::init_done) {
|
||||
@ -723,6 +730,7 @@ sub client_subscribe_topic($$;$$) {
|
||||
sub client_unsubscribe_topic($$) {
|
||||
my ($client,$topic) = @_;
|
||||
$client->{subscribe} = [grep { $_ ne $topic } @{$client->{subscribe}}];
|
||||
delete $client->{subscribeQos}->{$topic};
|
||||
my $expr = topic_to_regexp($topic);
|
||||
$client->{subscribeExpr} = [grep { $_ ne $expr} @{$client->{subscribeExpr}}];
|
||||
if ($main::init_done) {
|
||||
@ -744,6 +752,7 @@ sub Client_Define($$) {
|
||||
$client->{".qos"}->{'*'} = 0;
|
||||
$client->{".retain"}->{'*'} = "0";
|
||||
$client->{subscribe} = [];
|
||||
$client->{subscribeQos} = {};
|
||||
$client->{subscribeExpr} = [];
|
||||
AssignIoPort($client);
|
||||
|
||||
@ -875,13 +884,15 @@ sub client_attr($$$$$) {
|
||||
|
||||
sub client_start($) {
|
||||
my $client = shift;
|
||||
my $name = $client->{NAME};
|
||||
if (! (defined AttrVal($name,"stateFormat",undef))) {
|
||||
$main::attr{$name}{stateFormat} = "transmission-state";
|
||||
}
|
||||
CallFn($client->{NAME},"OnClientStartFn",($client));
|
||||
|
||||
#my $name = $client->{NAME};
|
||||
#if (! (defined AttrVal($name,"stateFormat",undef))) {
|
||||
# $main::attr{$name}{stateFormat} = "transmission-state";
|
||||
#}
|
||||
if (@{$client->{subscribe}}) {
|
||||
my $msgid = send_subscribe($client->{IODev},
|
||||
topics => [map { [$_ => $client->{".qos"}->{$_} || MQTT_QOS_AT_MOST_ONCE] } @{$client->{subscribe}}],
|
||||
topics => [map { [$_ => $client->{subscribeQos}->{$_} || MQTT_QOS_AT_MOST_ONCE] } @{$client->{subscribe}}],
|
||||
);
|
||||
$client->{message_ids}->{$msgid}++;
|
||||
readingsSingleUpdate($client,"transmission-state","subscribe sent",1);
|
||||
@ -892,6 +903,7 @@ sub client_start($) {
|
||||
|
||||
sub client_stop($) {
|
||||
my $client = shift;
|
||||
|
||||
if (@{$client->{subscribe}}) {
|
||||
my $msgid = send_unsubscribe($client->{IODev},
|
||||
topics => [@{$client->{subscribe}}],
|
||||
@ -899,6 +911,8 @@ sub client_stop($) {
|
||||
$client->{message_ids}->{$msgid}++;
|
||||
readingsSingleUpdate($client,"transmission-state","unsubscribe sent",1);
|
||||
}
|
||||
|
||||
CallFn($client->{NAME},"OnClientStopFn",($client));
|
||||
};
|
||||
|
||||
1;
|
||||
|
@ -39,6 +39,8 @@ sub MQTT_BRIDGE_Initialize($) {
|
||||
|
||||
my $hash = shift @_;
|
||||
|
||||
require "$main::attr{global}{modpath}/FHEM/00_MQTT.pm";
|
||||
|
||||
# Consumer
|
||||
$hash->{DefFn} = "MQTT::Client_Define";
|
||||
$hash->{UndefFn} = "MQTT::Client_Undefine";
|
||||
|
@ -35,6 +35,8 @@ sub MQTT_DEVICE_Initialize($) {
|
||||
|
||||
my $hash = shift @_;
|
||||
|
||||
require "$main::attr{global}{modpath}/FHEM/00_MQTT.pm";
|
||||
|
||||
# Consumer
|
||||
$hash->{DefFn} = "MQTT::DEVICE::Define";
|
||||
$hash->{UndefFn} = "MQTT::Client_Undefine";
|
||||
@ -188,7 +190,7 @@ sub Attr($$$$) {
|
||||
};
|
||||
$attribute =~ /^publishSet(_?)(.*)/ and do {
|
||||
if ($command eq "set") {
|
||||
my ( $aa, $bb ) = parseParams($value);
|
||||
my ( $aa, $bb ) = parseParams($value,undef,undef,undef,{});
|
||||
my @values = @{$aa};
|
||||
my $topic = pop @values;
|
||||
$hash->{publishSets}->{$2} = {
|
||||
@ -306,7 +308,8 @@ sub onmessage($$$) {
|
||||
<li>
|
||||
<p><code>attr <name> autoSubscribeReadings <topic></code><br/>
|
||||
specify a mqtt-topic pattern with wildcard (e.c. 'myhouse/kitchen/+') and MQTT_DEVICE automagically creates readings based on the wildcard-match<br/>
|
||||
e.g a message received with topic 'myhouse/kitchen/temperature' would create and update a reading 'temperature'</p>
|
||||
e.g a message received with topic 'myhouse/kitchen/temperature' would create and update a reading 'temperature'.<br/>
|
||||
Please note that topics with spaces will not work here!</p>
|
||||
</li>
|
||||
<li>
|
||||
<p><code>attr <name> subscribeReading_<reading> [{Perl-expression}] [qos:?] [retain:?] <topic></code><br/>
|
||||
|
Loading…
Reference in New Issue
Block a user