mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-04-09 13:45:33 +00:00
MQTT: refactor to get rid of 'constant subroutine redifined'-messages caused by import of Net::MQTT
git-svn-id: https://svn.fhem.de/fhem/trunk@6653 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
99b96cce4f
commit
f01a844bf5
@ -23,15 +23,6 @@
|
||||
#
|
||||
##############################################
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use GPUtils qw(:all);
|
||||
|
||||
use Net::MQTT::Constants;
|
||||
use Net::MQTT::Message;
|
||||
|
||||
require "10_MQTT_DEVICE.pm";
|
||||
|
||||
my %sets = (
|
||||
"connect" => "",
|
||||
"disconnect" => "",
|
||||
@ -53,36 +44,67 @@ sub MQTT_Initialize($) {
|
||||
|
||||
# Provider
|
||||
$hash->{Clients} = join (':',@clients);
|
||||
$hash->{ReadyFn} = "MQTT_Ready";
|
||||
$hash->{ReadFn} = "MQTT_Read";
|
||||
$hash->{ReadyFn} = "MQTT::Ready";
|
||||
$hash->{ReadFn} = "MQTT::Read";
|
||||
|
||||
# Consumer
|
||||
$hash->{DefFn} = "MQTT_Define";
|
||||
$hash->{UndefFn} = "MQTT_Undef";
|
||||
$hash->{SetFn} = "MQTT_Set";
|
||||
$hash->{NotifyFn} = "MQTT_Notify";
|
||||
$hash->{DefFn} = "MQTT::Define";
|
||||
$hash->{UndefFn} = "MQTT::Undef";
|
||||
$hash->{SetFn} = "MQTT::Set";
|
||||
$hash->{NotifyFn} = "MQTT::Notify";
|
||||
|
||||
$hash->{AttrList} = "keep-alive";
|
||||
}
|
||||
|
||||
sub MQTT_Define($$) {
|
||||
package MQTT;
|
||||
|
||||
use Exporter ('import');
|
||||
@EXPORT = ();
|
||||
@EXPORT_OK = qw(send_publish send_subscribe send_unsubscribe client_attr);
|
||||
%EXPORT_TAGS = (all => [@EXPORT_OK]);
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use GPUtils qw(:all);
|
||||
|
||||
use Net::MQTT::Constants;
|
||||
use Net::MQTT::Message;
|
||||
|
||||
our %qos = map {qos_string($_) => $_} (MQTT_QOS_AT_MOST_ONCE,MQTT_QOS_AT_LEAST_ONCE,MQTT_QOS_EXACTLY_ONCE);
|
||||
|
||||
BEGIN {GP_Import(qw(
|
||||
gettimeofday
|
||||
readingsSingleUpdate
|
||||
DevIo_OpenDev
|
||||
DevIo_SimpleWrite
|
||||
DevIo_SimpleRead
|
||||
DevIo_CloseDev
|
||||
RemoveInternalTimer
|
||||
InternalTimer
|
||||
AttrVal
|
||||
Log3
|
||||
AssignIoPort
|
||||
))};
|
||||
|
||||
sub Define($$) {
|
||||
my ( $hash, $def ) = @_;
|
||||
|
||||
$hash->{NOTIFYDEV} = "global";
|
||||
$hash->{msgid} = 1;
|
||||
|
||||
if ($main::init_done) {
|
||||
return MQTT_Start($hash);
|
||||
return Start($hash);
|
||||
} else {
|
||||
return undef;
|
||||
}
|
||||
}
|
||||
|
||||
sub MQTT_Undef($) {
|
||||
MQTT_Stop(shift);
|
||||
sub Undef($) {
|
||||
Stop(shift);
|
||||
}
|
||||
|
||||
sub MQTT_Set($@) {
|
||||
sub Set($@) {
|
||||
my ($hash, @a) = @_;
|
||||
return "Need at least one parameters" if(@a < 2);
|
||||
return "Unknown argument $a[1], choose one of " . join(" ", sort keys %sets)
|
||||
@ -92,64 +114,64 @@ sub MQTT_Set($@) {
|
||||
|
||||
COMMAND_HANDLER: {
|
||||
$command eq "connect" and do {
|
||||
MQTT_Start($hash);
|
||||
Start($hash);
|
||||
last;
|
||||
};
|
||||
$command eq "disconnect" and do {
|
||||
MQTT_Stop($hash);
|
||||
Stop($hash);
|
||||
last;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
sub MQTT_Notify($$) {
|
||||
sub Notify($$) {
|
||||
my ($hash,$dev) = @_;
|
||||
if( grep(m/^(INITIALIZED|REREADCFG)$/, @{$dev->{CHANGED}}) ) {
|
||||
MQTT_Start($hash);
|
||||
Start($hash);
|
||||
} elsif( grep(m/^SAVE$/, @{$dev->{CHANGED}}) ) {
|
||||
}
|
||||
}
|
||||
|
||||
sub MQTT_Start($) {
|
||||
sub Start($) {
|
||||
my $hash = shift;
|
||||
my ($dev) = split("[ \t]+", $hash->{DEF});
|
||||
$hash->{DeviceName} = $dev;
|
||||
DevIo_CloseDev($hash);
|
||||
return DevIo_OpenDev($hash, 0, "MQTT_Init");
|
||||
return DevIo_OpenDev($hash, 0, "MQTT::Init");
|
||||
}
|
||||
|
||||
sub MQTT_Stop($) {
|
||||
sub Stop($) {
|
||||
my $hash = shift;
|
||||
MQTT_send_disconnect($hash);
|
||||
send_disconnect($hash);
|
||||
DevIo_CloseDev($hash);
|
||||
main::RemoveInternalTimer($hash);
|
||||
main::readingsSingleUpdate($hash,"connection","disconnected",1);
|
||||
RemoveInternalTimer($hash);
|
||||
readingsSingleUpdate($hash,"connection","disconnected",1);
|
||||
}
|
||||
|
||||
sub MQTT_Ready($) {
|
||||
sub Ready($) {
|
||||
my $hash = shift;
|
||||
return DevIo_OpenDev($hash, 1, "MQTT_Init") if($hash->{STATE} eq "disconnected");
|
||||
return DevIo_OpenDev($hash, 1, "MQTT::Init") if($hash->{STATE} eq "disconnected");
|
||||
}
|
||||
|
||||
sub MQTT_Init($) {
|
||||
sub Init($) {
|
||||
my $hash = shift;
|
||||
MQTT_send_connect($hash);
|
||||
main::readingsSingleUpdate($hash,"connection","connecting",1);
|
||||
send_connect($hash);
|
||||
readingsSingleUpdate($hash,"connection","connecting",1);
|
||||
$hash->{ping_received}=1;
|
||||
MQTT_Timer($hash);
|
||||
Timer($hash);
|
||||
return undef;
|
||||
}
|
||||
|
||||
sub MQTT_Timer($) {
|
||||
sub Timer($) {
|
||||
my $hash = shift;
|
||||
main::RemoveInternalTimer($hash);
|
||||
main::readingsSingleUpdate($hash,"connection","timed-out",1) unless $hash->{ping_received};
|
||||
RemoveInternalTimer($hash);
|
||||
readingsSingleUpdate($hash,"connection","timed-out",1) unless $hash->{ping_received};
|
||||
$hash->{ping_received} = 0;
|
||||
main::InternalTimer(gettimeofday()+main::AttrVal($hash-> {NAME},"keep-alive",60), "MQTT_Timer", $hash, 0);
|
||||
MQTT_send_ping($hash);
|
||||
InternalTimer(gettimeofday()+AttrVal($hash-> {NAME},"keep-alive",60), "MQTT::Timer", $hash, 0);
|
||||
send_ping($hash);
|
||||
}
|
||||
|
||||
sub MQTT_Read {
|
||||
sub Read {
|
||||
my ($hash) = @_;
|
||||
my $name = $hash->{NAME};
|
||||
my $buf = DevIo_SimpleRead($hash);
|
||||
@ -158,12 +180,12 @@ sub MQTT_Read {
|
||||
while (my $mqtt = Net::MQTT::Message->new_from_bytes($hash->{buf},1)) {
|
||||
my $message_type = $mqtt->message_type();
|
||||
|
||||
main::Log3($name,5,"MQTT $name message received: ".$mqtt->string());
|
||||
Log3($name,5,"MQTT $name message received: ".$mqtt->string());
|
||||
|
||||
MESSAGE_TYPE: {
|
||||
$message_type == MQTT_CONNACK and do {
|
||||
readingsSingleUpdate($hash,"connection","connected",1);
|
||||
GP_ForallClients($hash,\&MQTT_client_start);
|
||||
GP_ForallClients($hash,\&client_start);
|
||||
last;
|
||||
};
|
||||
|
||||
@ -171,13 +193,13 @@ sub MQTT_Read {
|
||||
my $topic = $mqtt->topic();
|
||||
GP_ForallClients($hash,sub {
|
||||
my $client = shift;
|
||||
main::Log3($client->{NAME},5,"publish received for $topic, ".$mqtt->message());
|
||||
Log3($client->{NAME},5,"publish received for $topic, ".$mqtt->message());
|
||||
if (grep { $_ eq $topic } @{$client->{subscribe}}) {
|
||||
readingsSingleUpdate($client,"transmission-state","publish received",1);
|
||||
if ($client->{TYPE} eq "MQTT_DEVICE") {
|
||||
MQTT_DEVICE_onmessage($client,$topic,$mqtt->message());
|
||||
MQTT::DEVICE::onmessage($client,$topic,$mqtt->message());
|
||||
} else {
|
||||
MQTT_BRIDGE_onmessage($client,$topic,$mqtt->message());
|
||||
MQTT::BRIDGE::onmessage($client,$topic,$mqtt->message());
|
||||
}
|
||||
};
|
||||
},undef);
|
||||
@ -258,95 +280,123 @@ sub MQTT_Read {
|
||||
|
||||
$message_type == MQTT_PINGRESP and do {
|
||||
$hash->{ping_received} = 1;
|
||||
main::readingsSingleUpdate($hash,"connection","active",1);
|
||||
readingsSingleUpdate($hash,"connection","active",1);
|
||||
last;
|
||||
};
|
||||
|
||||
main::Log3($hash->{NAME},4,"MQTT_Read '$hash->{NAME}' unexpected message type '".message_type_string($message_type)."'");
|
||||
Log3($hash->{NAME},4,"MQTT::Read '$hash->{NAME}' unexpected message type '".message_type_string($message_type)."'");
|
||||
}
|
||||
}
|
||||
return undef;
|
||||
};
|
||||
|
||||
sub MQTT_send_connect($) {
|
||||
sub send_connect($) {
|
||||
my $hash = shift;
|
||||
return MQTT_send_message($hash, message_type => MQTT_CONNECT, keep_alive_timer => main::AttrVal($hash->{NAME},"keep-alive",60));
|
||||
return send_message($hash, message_type => MQTT_CONNECT, keep_alive_timer => AttrVal($hash->{NAME},"keep-alive",60));
|
||||
};
|
||||
|
||||
sub MQTT_send_publish($@) {
|
||||
return MQTT_send_message(shift, message_type => MQTT_PUBLISH, @_);
|
||||
sub send_publish($@) {
|
||||
return send_message(shift, message_type => MQTT_PUBLISH, @_);
|
||||
};
|
||||
|
||||
sub MQTT_send_subscribe($@) {
|
||||
sub send_subscribe($@) {
|
||||
my $hash = shift;
|
||||
return MQTT_send_message($hash, message_type => MQTT_SUBSCRIBE, @_);
|
||||
return send_message($hash, message_type => MQTT_SUBSCRIBE, @_);
|
||||
};
|
||||
|
||||
sub MQTT_send_unsubscribe($@) {
|
||||
return MQTT_send_message(shift, message_type => MQTT_UNSUBSCRIBE, @_);
|
||||
sub send_unsubscribe($@) {
|
||||
return send_message(shift, message_type => MQTT_UNSUBSCRIBE, @_);
|
||||
};
|
||||
|
||||
sub MQTT_send_ping($) {
|
||||
return MQTT_send_message(shift, message_type => MQTT_PINGREQ);
|
||||
sub send_ping($) {
|
||||
return send_message(shift, message_type => MQTT_PINGREQ);
|
||||
};
|
||||
|
||||
sub MQTT_send_disconnect($) {
|
||||
return MQTT_send_message(shift, message_type => MQTT_DISCONNECT);
|
||||
sub send_disconnect($) {
|
||||
return send_message(shift, message_type => MQTT_DISCONNECT);
|
||||
};
|
||||
|
||||
sub MQTT_send_message($$$@) {
|
||||
sub send_message($$$@) {
|
||||
my $hash = shift;
|
||||
my $name = $hash->{NAME};
|
||||
my $msgid = $hash->{msgid}++;
|
||||
my $msg = Net::MQTT::Message->new(message_id => $msgid,@_);
|
||||
main::Log3($name,5,"MQTT $name message sent: ".$msg->string());
|
||||
Log3($name,5,"MQTT $name message sent: ".$msg->string());
|
||||
DevIo_SimpleWrite($hash,$msg->bytes,undef);
|
||||
return $msgid;
|
||||
};
|
||||
|
||||
sub MQTT_client_define($$) {
|
||||
sub Client_Define($$) {
|
||||
my ( $client, $def ) = @_;
|
||||
|
||||
$client->{NOTIFYDEV} = $client->{DEF} if $client->{DEF};
|
||||
$client->{qos} = MQTT_QOS_AT_MOST_ONCE;
|
||||
$client->{subscribe} = [];
|
||||
|
||||
if ($main::init_done) {
|
||||
return MQTT_client_start($client);
|
||||
return client_start($client);
|
||||
} else {
|
||||
return undef;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
sub MQTT_client_undefine($) {
|
||||
MQTT_client_stop(shift);
|
||||
}
|
||||
sub Client_Undefine($) {
|
||||
client_stop(shift);
|
||||
};
|
||||
|
||||
sub client_attr($$$$$) {
|
||||
my ($client,$command,$name,$attribute,$value) = @_;
|
||||
|
||||
sub MQTT_client_start($) {
|
||||
ATTRIBUTE_HANDLER: {
|
||||
$attribute eq "qos" and do {
|
||||
if ($command eq "set") {
|
||||
$client->{qos} = $MQTT::qos{$value};
|
||||
} else {
|
||||
$client->{qos} = MQTT_QOS_AT_MOST_ONCE;
|
||||
}
|
||||
last;
|
||||
};
|
||||
$attribute eq "IODev" and do {
|
||||
if ($main::init_done) {
|
||||
if ($command eq "set") {
|
||||
client_stop($client);
|
||||
$main::attr{$name}{IODev} = $value;
|
||||
client_start($client);
|
||||
} else {
|
||||
client_stop($client);
|
||||
}
|
||||
}
|
||||
last;
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
sub client_start($) {
|
||||
my $client = shift;
|
||||
AssignIoPort($client);
|
||||
my $name = $client->{NAME};
|
||||
if (! (defined AttrVal($name,"stateFormat",undef))) {
|
||||
$main::attr{$name}{stateFormat} = "transmission-state";
|
||||
}
|
||||
if (@{$client->{subscribe}}) {
|
||||
my $msgid = MQTT_send_subscribe($client->{IODev},
|
||||
my $msgid = send_subscribe($client->{IODev},
|
||||
topics => [map { [$_ => $client->{qos} || MQTT_QOS_AT_MOST_ONCE] } @{$client->{subscribe}}],
|
||||
);
|
||||
$client->{message_ids}->{$msgid}++;
|
||||
readingsSingleUpdate($client,"transmission-state","subscribe sent",1)
|
||||
readingsSingleUpdate($client,"transmission-state","subscribe sent",1);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
sub MQTT_client_stop($) {
|
||||
sub client_stop($) {
|
||||
my $client = shift;
|
||||
if (@{$client->{subscribe}}) {
|
||||
my $msgid = MQTT_send_unsubscribe($client->{IODev},
|
||||
my $msgid = send_unsubscribe($client->{IODev},
|
||||
topics => [@{$client->{subscribe}}],
|
||||
);
|
||||
$client->{message_ids}->{$msgid}++;
|
||||
readingsSingleUpdate($client,"transmission-state","unsubscribe sent",1)
|
||||
readingsSingleUpdate($client,"transmission-state","unsubscribe sent",1);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
1;
|
||||
|
||||
|
@ -25,10 +25,6 @@
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use GPUtils qw(:all);
|
||||
|
||||
use Net::MQTT::Constants;
|
||||
use Net::MQTT::Message;
|
||||
|
||||
my %sets = (
|
||||
);
|
||||
@ -38,31 +34,51 @@ my %gets = (
|
||||
"readings" => ""
|
||||
);
|
||||
|
||||
my %qos = map {qos_string($_) => $_} (MQTT_QOS_AT_MOST_ONCE,MQTT_QOS_AT_LEAST_ONCE,MQTT_QOS_EXACTLY_ONCE);
|
||||
|
||||
sub MQTT_BRIDGE_Initialize($) {
|
||||
|
||||
my $hash = shift @_;
|
||||
|
||||
# Consumer
|
||||
$hash->{DefFn} = "MQTT_client_define";
|
||||
$hash->{UndefFn} = "MQTT_client_undefine";
|
||||
$hash->{GetFn} = "MQTT_BRIDGE_Get";
|
||||
$hash->{NotifyFn} = "MQTT_BRIDGE_Notify";
|
||||
$hash->{AttrFn} = "MQTT_BRIDGE_Attr";
|
||||
$hash->{DefFn} = "MQTT::Client_Define";
|
||||
$hash->{UndefFn} = "MQTT::Client_Undefine";
|
||||
$hash->{GetFn} = "MQTT::BRIDGE::Get";
|
||||
$hash->{NotifyFn} = "MQTT::BRIDGE::Notify";
|
||||
$hash->{AttrFn} = "MQTT::BRIDGE::Attr";
|
||||
|
||||
$hash->{AttrList} =
|
||||
"IODev ".
|
||||
"qos:".join(",",keys %qos)." ".
|
||||
"qos:".join(",",keys %MQTT::qos)." ".
|
||||
"publish-topic-base ".
|
||||
"publishState ".
|
||||
"publishReading_.* ".
|
||||
"subscribeSet ".
|
||||
"subscribeSet_.* ".
|
||||
$main::readingFnAttributes;
|
||||
|
||||
main::LoadModule("MQTT");
|
||||
}
|
||||
|
||||
sub MQTT_BRIDGE_Get($$@) {
|
||||
package MQTT::BRIDGE;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use GPUtils qw(:all);
|
||||
|
||||
use Net::MQTT::Constants;
|
||||
|
||||
BEGIN {
|
||||
MQTT->import(qw(:all));
|
||||
|
||||
GP_Import(qw(
|
||||
AttrVal
|
||||
CommandAttr
|
||||
readingsSingleUpdate
|
||||
Log3
|
||||
DoSet
|
||||
))
|
||||
};
|
||||
|
||||
sub Get($$@) {
|
||||
my ($hash, $name, $command) = @_;
|
||||
return "Need at least one parameters" unless (defined $command);
|
||||
return "Unknown argument $command, choose one of " . join(" ", sort keys %gets)
|
||||
@ -73,8 +89,8 @@ sub MQTT_BRIDGE_Get($$@) {
|
||||
$command eq "readings" and do {
|
||||
my $base = AttrVal($name,"publish-topic-base","/$hash->{DEF}/");
|
||||
foreach my $reading (keys %{$main::defs{$hash->{DEF}}{READINGS}}) {
|
||||
unless (defined main::AttrVal($name,"publishReading_$reading",undef)) {
|
||||
main::CommandAttr($hash,"$name publishReading_$reading $base$reading");
|
||||
unless (defined AttrVal($name,"publishReading_$reading",undef)) {
|
||||
CommandAttr($hash,"$name publishReading_$reading $base$reading");
|
||||
}
|
||||
};
|
||||
last;
|
||||
@ -82,28 +98,28 @@ sub MQTT_BRIDGE_Get($$@) {
|
||||
};
|
||||
}
|
||||
|
||||
sub MQTT_BRIDGE_Notify() {
|
||||
sub Notify() {
|
||||
my ($hash,$dev) = @_;
|
||||
|
||||
main::Log3($hash->{NAME},5,"Notify for $dev->{NAME}");
|
||||
Log3($hash->{NAME},5,"Notify for $dev->{NAME}");
|
||||
foreach my $event (@{$dev->{CHANGED}}) {
|
||||
$event =~ /^([^:]+)(: )?(.*)$/;
|
||||
main::Log3($hash->{NAME},5,"$event, '".((defined $1) ? $1 : "-undef-")."', '".((defined $3) ? $3 : "-undef-")."'");
|
||||
Log3($hash->{NAME},5,"$event, '".((defined $1) ? $1 : "-undef-")."', '".((defined $3) ? $3 : "-undef-")."'");
|
||||
if (defined $3 and $3 ne "") {
|
||||
if (defined $hash->{publishReadings}->{$1}) {
|
||||
MQTT_send_publish($hash->{IODev}, topic => $hash->{publishReadings}->{$1}, message => $3, qos => $hash->{qos});
|
||||
send_publish($hash->{IODev}, topic => $hash->{publishReadings}->{$1}, message => $3, qos => $hash->{qos});
|
||||
readingsSingleUpdate($hash,"transmission-state","publish sent",1);
|
||||
}
|
||||
} else {
|
||||
if (defined $hash->{publishState}) {
|
||||
MQTT_send_publish($hash->{IODev}, topic => $hash->{publishState}, message => $1, qos => $hash->{qos});
|
||||
send_publish($hash->{IODev}, topic => $hash->{publishState}, message => $1, qos => $hash->{qos});
|
||||
readingsSingleUpdate($hash,"transmission-state","publish sent",1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub MQTT_BRIDGE_Attr($$$$) {
|
||||
sub Attr($$$$) {
|
||||
my ($command,$name,$attribute,$value) = @_;
|
||||
|
||||
my $hash = $main::defs{$name};
|
||||
@ -114,7 +130,7 @@ sub MQTT_BRIDGE_Attr($$$$) {
|
||||
push @{$hash->{subscribe}},$value unless grep {$_ eq $value} @{$hash->{subscribe}};
|
||||
if ($main::init_done) {
|
||||
if (my $mqtt = $hash->{IODev}) {;
|
||||
my $msgid = MQTT_send_subscribe($mqtt,
|
||||
my $msgid = send_subscribe($mqtt,
|
||||
topics => [[$value => $hash->{qos} || MQTT_QOS_AT_MOST_ONCE]],
|
||||
);
|
||||
$hash->{message_ids}->{$msgid}++;
|
||||
@ -128,7 +144,7 @@ sub MQTT_BRIDGE_Attr($$$$) {
|
||||
$hash->{subscribe} = [grep { $_ != $topic } @{$hash->{subscribe}}];
|
||||
if ($main::init_done) {
|
||||
if (my $mqtt = $hash->{IODev}) {;
|
||||
my $msgid = MQTT_send_unsubscribe($mqtt,
|
||||
my $msgid = send_unsubscribe($mqtt,
|
||||
topics => [$topic],
|
||||
);
|
||||
$hash->{message_ids}->{$msgid}++;
|
||||
@ -156,33 +172,20 @@ sub MQTT_BRIDGE_Attr($$$$) {
|
||||
}
|
||||
last;
|
||||
};
|
||||
$attribute eq "qos" and do {
|
||||
if ($command eq "set") {
|
||||
$hash->{qos} = $qos{$value};
|
||||
} else {
|
||||
$hash->{qos} = MQTT_QOS_AT_MOST_ONCE;
|
||||
}
|
||||
last;
|
||||
};
|
||||
$attribute eq "IODev" and do {
|
||||
if ($command eq "set") {
|
||||
} else {
|
||||
}
|
||||
last;
|
||||
};
|
||||
client_attr($hash,$command,$name,$attribute,$value);
|
||||
}
|
||||
}
|
||||
|
||||
sub MQTT_BRIDGE_onmessage($$$) {
|
||||
sub onmessage($$$) {
|
||||
my ($hash,$topic,$message) = @_;
|
||||
if (defined (my $command = $hash->{subscribeSets}->{$topic})) {
|
||||
my @args = split ("[ \t]+",$message);
|
||||
if ($command eq "") {
|
||||
main::Log3($hash->{NAME},5,"calling DoSet($hash->{DEF}".(@args ? ",".join(",",@args) : ""));
|
||||
main::DoSet($hash->{DEF},@args);
|
||||
Log3($hash->{NAME},5,"calling DoSet($hash->{DEF}".(@args ? ",".join(",",@args) : ""));
|
||||
DoSet($hash->{DEF},@args);
|
||||
} else {
|
||||
main::Log3($hash->{NAME},5,"calling DoSet($hash->{DEF},$command".(@args ? ",".join(",",@args) : ""));
|
||||
main::DoSet($hash->{DEF},$command,@args);
|
||||
Log3($hash->{NAME},5,"calling DoSet($hash->{DEF},$command".(@args ? ",".join(",",@args) : ""));
|
||||
DoSet($hash->{DEF},$command,@args);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -25,10 +25,6 @@
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use GPUtils qw(:all);
|
||||
|
||||
use Net::MQTT::Constants;
|
||||
use Net::MQTT::Message;
|
||||
|
||||
my %sets = (
|
||||
);
|
||||
@ -37,28 +33,45 @@ my %gets = (
|
||||
"version" => "",
|
||||
);
|
||||
|
||||
my %qos = map {qos_string($_) => $_} (MQTT_QOS_AT_MOST_ONCE,MQTT_QOS_AT_LEAST_ONCE,MQTT_QOS_EXACTLY_ONCE);
|
||||
|
||||
sub MQTT_DEVICE_Initialize($) {
|
||||
|
||||
my $hash = shift @_;
|
||||
|
||||
# Consumer
|
||||
$hash->{DefFn} = "MQTT_client_define";
|
||||
$hash->{UndefFn} = "MQTT_client_undefine";
|
||||
$hash->{SetFn} = "MQTT_DEVICE_Set";
|
||||
$hash->{AttrFn} = "MQTT_DEVICE_Attr";
|
||||
$hash->{DefFn} = "MQTT::Client_Define";
|
||||
$hash->{UndefFn} = "MQTT::Client_Undefine";
|
||||
$hash->{SetFn} = "MQTT::DEVICE::Set";
|
||||
$hash->{AttrFn} = "MQTT::DEVICE::Attr";
|
||||
|
||||
$hash->{AttrList} =
|
||||
"IODev ".
|
||||
"qos:".join(",",keys %qos)." ".
|
||||
"qos:".join(",",keys %MQTT::qos)." ".
|
||||
"publishSet ".
|
||||
"publishSet_.* ".
|
||||
"subscribeReading_.* ".
|
||||
$main::readingFnAttributes;
|
||||
|
||||
main::LoadModule("MQTT");
|
||||
}
|
||||
|
||||
sub MQTT_DEVICE_Set($@) {
|
||||
package MQTT::DEVICE;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use GPUtils qw(:all);
|
||||
|
||||
use Net::MQTT::Constants;
|
||||
|
||||
BEGIN {
|
||||
MQTT->import(qw(:all));
|
||||
|
||||
GP_Import(qw(
|
||||
readingsSingleUpdate
|
||||
Log3
|
||||
))
|
||||
};
|
||||
|
||||
sub Set($@) {
|
||||
my ($hash, @a) = @_;
|
||||
return "Need at least one parameters" if(@a < 2);
|
||||
return "Unknown argument $a[1], choose one of " . join(" ", map {$sets{$_} eq "" ? $_ : "$_:$sets{$_}"} sort keys %sets)
|
||||
@ -66,16 +79,16 @@ sub MQTT_DEVICE_Set($@) {
|
||||
my $command = $a[1];
|
||||
my $value = $a[2];
|
||||
if (defined $value) {
|
||||
MQTT_send_publish($hash->{IODev}, topic => $hash->{publishSets}->{$command}->{topic}, message => $value, qos => $hash->{qos});
|
||||
send_publish($hash->{IODev}, topic => $hash->{publishSets}->{$command}->{topic}, message => $value, qos => $hash->{qos});
|
||||
readingsSingleUpdate($hash,$command,$value,1);
|
||||
} else {
|
||||
MQTT_send_publish($hash->{IODev}, topic => $hash->{publishSets}->{""}->{topic}, message => $command, qos => $hash->{qos});
|
||||
send_publish($hash->{IODev}, topic => $hash->{publishSets}->{""}->{topic}, message => $command, qos => $hash->{qos});
|
||||
readingsSingleUpdate($hash,"state",$command,1);
|
||||
}
|
||||
return undef;
|
||||
}
|
||||
|
||||
sub MQTT_DEVICE_Attr($$$$) {
|
||||
sub Attr($$$$) {
|
||||
my ($command,$name,$attribute,$value) = @_;
|
||||
|
||||
my $hash = $main::defs{$name};
|
||||
@ -86,7 +99,7 @@ sub MQTT_DEVICE_Attr($$$$) {
|
||||
push @{$hash->{subscribe}},$value unless grep {$_ eq $value} @{$hash->{subscribe}};
|
||||
if ($main::init_done) {
|
||||
if (my $mqtt = $hash->{IODev}) {;
|
||||
my $msgid = MQTT_send_subscribe($mqtt,
|
||||
my $msgid = send_subscribe($mqtt,
|
||||
topics => [[$value => $hash->{qos} || MQTT_QOS_AT_MOST_ONCE]],
|
||||
);
|
||||
$hash->{message_ids}->{$msgid}++;
|
||||
@ -100,7 +113,7 @@ sub MQTT_DEVICE_Attr($$$$) {
|
||||
delete $hash->{subscribeReadings}->{$topic};
|
||||
if ($main::init_done) {
|
||||
if (my $mqtt = $hash->{IODev}) {;
|
||||
my $msgid = MQTT_send_unsubscribe($mqtt,
|
||||
my $msgid = send_unsubscribe($mqtt,
|
||||
topics => [$topic],
|
||||
);
|
||||
$hash->{message_ids}->{$msgid}++;
|
||||
@ -139,28 +152,15 @@ sub MQTT_DEVICE_Attr($$$$) {
|
||||
}
|
||||
last;
|
||||
};
|
||||
$attribute eq "qos" and do {
|
||||
if ($command eq "set") {
|
||||
$hash->{qos} = $qos{$value};
|
||||
} else {
|
||||
$hash->{qos} = MQTT_QOS_AT_MOST_ONCE;
|
||||
}
|
||||
last;
|
||||
};
|
||||
$attribute eq "IODev" and do {
|
||||
if ($command eq "set") {
|
||||
} else {
|
||||
}
|
||||
last;
|
||||
};
|
||||
client_attr($hash,$command,$name,$attribute,$value);
|
||||
}
|
||||
}
|
||||
|
||||
sub MQTT_DEVICE_onmessage($$$) {
|
||||
sub onmessage($$$) {
|
||||
my ($hash,$topic,$message) = @_;
|
||||
if (defined (my $reading = $hash->{subscribeReadings}->{$topic})) {
|
||||
main::Log3($hash->{NAME},5,"calling readingsSingleUpdate($hash->{NAME},$reading,$message,1");
|
||||
main::readingsSingleUpdate($hash,$reading,$message,1);
|
||||
Log3($hash->{NAME},5,"calling readingsSingleUpdate($hash->{NAME},$reading,$message,1");
|
||||
readingsSingleUpdate($hash,$reading,$message,1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -7,7 +7,7 @@ use Exporter qw( import );
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
our %EXPORT_TAGS = (all => [qw(GP_Define GP_Catch GP_ForallClients)]);
|
||||
our %EXPORT_TAGS = (all => [qw(GP_Define GP_Catch GP_ForallClients GP_Import)]);
|
||||
Exporter::export_ok_tags('all');
|
||||
|
||||
#add FHEM/lib to @INC if it's not allready included. Should rather be in fhem.pl than here though...
|
||||
@ -54,5 +54,14 @@ sub GP_ForallClients($$@)
|
||||
return undef;
|
||||
}
|
||||
|
||||
sub GP_Import(@)
|
||||
{
|
||||
no strict qw/refs/; ## no critic
|
||||
my $pkg = caller(0);
|
||||
foreach (@_) {
|
||||
*{$pkg.'::'.$_} = *{'main::'.$_};
|
||||
}
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user