diff --git a/fhem/CHANGED b/fhem/CHANGED
index 3a33e84b4..c648a2f87 100644
--- a/fhem/CHANGED
+++ b/fhem/CHANGED
@@ -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.
+ - change: 50_Signalbot: new favorite feature and bug fixes
- change: 93_DbRep: usage of placeholder §device§, §reading§ in sqlCmd
changed (refer to commandRef)
- bugfix: 71_COE_Node: fix for negative temparatures by thor3
diff --git a/fhem/FHEM/50_Signalbot.pm b/fhem/FHEM/50_Signalbot.pm
index ff72f9427..e5a828e36 100755
--- a/fhem/FHEM/50_Signalbot.pm
+++ b/fhem/FHEM/50_Signalbot.pm
@@ -1,6 +1,6 @@
##############################################
#$Id$
-my $Signalbot_VERSION="3.2";
+my $Signalbot_VERSION="3.3";
# Simple Interface to Signal CLI running as Dbus service
# Author: Adimarantis
# License: GPL
@@ -50,6 +50,7 @@ my %sets = (
"contacts" => "all,nonblocked", #V0.8.1+
"groups" => "all,active,nonblocked", #V0.8.1+
"accounts" => "noArg", #V0.9.0+
+ "favorites" => "noArg",
# "introspective" => "noArg"
);
@@ -111,6 +112,7 @@ sub Signalbot_Initialize($) {
$hash->{GetFn} = "Signalbot_Get";
$hash->{UndefFn} = "Signalbot_Undef";
$hash->{MessageReceived} = "Signalbot_MessageReceived";
+ $hash->{MessageReceivedV2} = "Signalbot_MessageReceivedV2";
$hash->{ReceiptReceived} = "Signalbot_ReceiptReceived";
$hash->{version} = "Signalbot_Version_cb";
$hash->{updateGroup} = "Signalbot_UpdateGroup_cb";
@@ -125,6 +127,8 @@ sub Signalbot_Initialize($) {
"authTimeout ".
"authDev ".
"cmdKeyword ".
+ "cmdFavorite ".
+ "favorites ".
"autoJoin:yes,no ".
"registerMethod:SMS,Voice ".
"$readingFnAttributes";
@@ -366,11 +370,11 @@ sub Signalbot_Set($@) { #
#Check for embedded fhem/perl commands
my $err;
- ($err, @recipients) = SignalBot_replaceCommands($hash,@recipients);
+ ($err, @recipients) = Signalbot_replaceCommands($hash,@recipients);
if ($err) { return $err; }
- ($err, @groups) = SignalBot_replaceCommands($hash,@groups);
+ ($err, @groups) = Signalbot_replaceCommands($hash,@groups);
if ($err) { return $err; }
- ($err, @attachments) = SignalBot_replaceCommands($hash,@attachments);
+ ($err, @attachments) = Signalbot_replaceCommands($hash,@attachments);
if ($err) { return $err; }
#Am Schluss eine Schleife über die Attachments und alle die mit /tmp/signalbot anfangen löschen (unlink)
@@ -474,6 +478,27 @@ sub Signalbot_Get($@) {
$ret.=$account."\n";
}
return $ret;
+ } elsif ($cmd eq "favorites") {
+ my @fav=split(";",AttrVal($name,"favorites",""));
+ return "No favorites defined" if @fav==0;
+ my $ret="Defined favorites:\n\n";
+ my $format="%2i (%s) %-15s %-50s\n";
+ $ret.="ID (A) Alias Command\n";
+ my $cnt=1;
+ foreach (@fav) {
+ my $ff=$_;
+ $ff =~ /(\[(.*)\])?([\-]?)(.*)/;
+ my $aa="y";
+ if ($3 eq "-") {
+ $aa="n";
+ }
+ my $alias=$2;
+ $alias="" if !defined $2;
+ $ret.=sprintf($format,$cnt,$aa,$alias,$4);
+ $cnt++;
+ }
+ $ret.="\n(A)=GoogleAuth required to execute command";
+ return $ret;
}
if ($gets{$cmd} =~ /$arg/) {
@@ -563,7 +588,7 @@ sub Signalbot_command($@){
$hash->{helper}{auth}{$sender}=1;
#Remove potential old timer so countdown start from scratch
RemoveInternalTimer("$hash->{NAME} $sender");
- InternalTimer(gettimeofday() + $timeout, 'SignalBot_authTimeout', "$hash->{NAME} $sender", 0);
+ InternalTimer(gettimeofday() + $timeout, 'Signalbot_authTimeout', "$hash->{NAME} $sender", 0);
Signalbot_sendMessage($hash,$sender,"","You have control for ".$timeout."s");
$cmd=$restcmd;
} else {
@@ -573,8 +598,65 @@ sub Signalbot_command($@){
return $cmd;
}
}
+ my $auth=0;
+ if (defined $hash->{helper}{auth}{$sender} && $hash->{helper}{auth}{$sender}==1) {
+ $auth=1;
+ }
+ my $fav=AttrVal($hash->{NAME},"cmdFavorite",undef);
+ if (defined $fav && defined $cc[0] && $cc[0] eq $fav) {
+ shift @cc;
+ my @favorites=split(";",AttrVal($hash->{NAME},"favorites",""));
+ if (@cc>0) {
+ Log3 $hash->{NAME}, 4, $hash->{NAME}.": $sender executes favorite command $cc[0]";
+ if ($cc[0] =~/\d+$/) {
+ #Favorite by index
+ my $fid=$cc[0]-1;
+ if ($fid<@favorites) {
+ $cmd=$favorites[$fid];
+ $cmd =~ /(\[.*\])?([\-]?)(.*)/;
+ $cmd=$3 if defined $3;
+ #"-" defined favorite commands that do not require authentification
+ $auth=1 if (defined $2 && $2 eq "-");
+ Log3 $hash->{NAME}, 4, $hash->{NAME}.": $sender requests favorite command:$cmd";
+ } else {
+ $cmd="";
+ Signalbot_sendMessage($hash,$sender,"","favorite #$cc[0] not defined");
+ Log3 $hash->{NAME}, 4, $hash->{NAME}.": favorite #$cc[0] not defined";
+ }
+ } else {
+ my $alias=join(" ",@cc);
+ $cmd="";
+ foreach my $ff (@favorites) {
+ $ff =~ /(\[(.*)\])?([\-]?)(.*)/;
+ if (defined $2 && $2 eq $alias) {
+ $cmd=$4 if defined $4;
+ #"-" defined favorite commands that do not require authentification
+ $auth=1 if (defined $3 && $3 eq "-");
+ }
+ }
+ if ($cmd eq "") {
+ Signalbot_sendMessage($hash,$sender,"","favorite '$alias' not defined");
+ Log3 $hash->{NAME}, 4, $hash->{NAME}.": favorite '$alias' not defined";
+ }
+ }
+ } else {
+ return "No favorites defined" if @favorites==0;
+ my $ret="Defined favorites:\n\n";
+ my $format="%2i %-30s\n";
+ $ret.="ID Command\n";
+ my $cnt=1;
+ foreach (@favorites) {
+ my $ff=$_;
+ $ff =~ /(\[(.*)\])?([\-]?)(.*)/;
+ $ret.=sprintf($format,$cnt,$4);
+ $cnt++;
+ }
+ Signalbot_sendMessage($hash,$sender,"",$ret) if $auth;
+ $cmd="";
+ }
+ }
return $cmd if $cmd eq "";
- if ($hash->{helper}{auth}{$sender}==1) {
+ if ($auth) {
Log3 $hash->{NAME}, 4, $hash->{NAME}.": $sender executes command $cmd";
my $error = AnalyzeCommand($hash, $cmd);
if (defined $error) {
@@ -591,13 +673,29 @@ sub Signalbot_command($@){
}
#Reset auth after timeout
-sub SignalBot_authTimeout($@) {
+sub Signalbot_authTimeout($@) {
my ($val)=@_;
my ($name,$sender)=split(" ",$val);
my $hash = $defs{$name};
$hash->{helper}{auth}{$sender}=0;
}
+#Wrapper around the new MessageReceived callback - currently ignored since V0.10.0 sends both callbacks
+sub Signalbot_MessageReceivedV2 ($@) {
+ my ($hash,$timestamp,$source,$groupID,$message,$extras) = @_;
+ Log3 $hash->{NAME}, 5, $hash->{NAME}.": Message CallbackV2 - ignored";
+ return;
+ my $att = $extras->{attachments};
+ my @attachments;
+ if (defined $att) {
+ my @arr=@$att;
+ foreach (@arr) {
+ push @attachments, $_->{file};
+ }
+ }
+ Signalbot_MessageReceived($hash,$timestamp,$source,$groupID,$message,\@attachments);
+}
+
sub Signalbot_MessageReceived ($@) {
my ($hash,$timestamp,$source,$groupID,$message,$attachments) = @_;
@@ -657,7 +755,7 @@ sub Signalbot_MessageReceived ($@) {
readingsEndUpdate($hash, 0);
my $cmd=AttrVal($hash->{NAME},"cmdKeyword",undef);
- if ($message =~ /^$cmd(.*)/) {
+ if (defined $cmd && $message =~ /^$cmd(.*)/) {
$babble=0; #Skip Babble execution in command mode
$message=Signalbot_command($hash,$source,$message);
}
@@ -802,6 +900,7 @@ sub Signalbot_setup($@){
return undef;
}
+my $Signalbot_Retry=0;
# After Dbus init successfully came back
sub Signalbot_setup2($@) {
my ($hash) = @_;
@@ -826,14 +925,19 @@ sub Signalbot_setup2($@) {
my $account=ReadingsVal($name,"account","none");
if (!defined $version) {
$hash->{helper}{version}=0; #prevent uninitalized value in case of service not present
+ if ($Signalbot_Retry<3) {
+ $Signalbot_Retry++;
+ InternalTimer(gettimeofday() + 10, 'Signalbot_setup', $hash, 0);
+ Log3 $name, 3, $hash->{NAME}.": Could not init signal-cli - retry $Signalbot_Retry in 10 seconds";
+ }
return "Error calling version";
}
my @ver=split('\.',$version);
- #to be on the safe side allow 2 digits for lowest version number, so 0.8.0 results to 800
- $hash->{helper}{version}=$ver[0]*1000+$ver[1]*100+$ver[2];
+ #to be on the safe side allow 2 digits for version number, so 0.8.0 results to 800, 1.10.11 would result in 11011
+ $hash->{helper}{version}=$ver[0]*10000+$ver[1]*100+$ver[2];
$hash->{VERSION}="Signalbot:".$Signalbot_VERSION." signal-cli:".$version." Protocol::DBus:".$Protocol::DBus::VERSION;
- $hash->{model}=SignalBot_OSRel();
+ $hash->{model}=Signalbot_OSRel();
if($hash->{helper}{version}>800) {
my $state=Signalbot_CallS($hash,"isRegistered");
#Signal-cli 0.9.0 : isRegistered not existing and will return undef when in multi-mode (or false with my PR)
@@ -1079,7 +1183,7 @@ sub Signalbot_Read($@){
if (defined $callback) {
my $b=$msg->get_body();
my @body=@$b;
- if ($callback eq "MessageReceived" || $callback eq "ReceiptReceived" || $callback eq "SyncMessageReceived") {
+ if ($callback eq "MessageReceived" || $callback eq "ReceiptReceived" || $callback eq "SyncMessageReceived" || $callback eq "MessageReceivedV2") {
my $func="Signalbot_$callback";
Log3 $hash->{NAME}, 5, $hash->{NAME}.": Sync Callback: $callback Args:".join(",",@body);
CallFn($hash->{NAME},$callback,$hash,@body);
@@ -1415,10 +1519,13 @@ sub Signalbot_Attr(@) { #
} elsif($attr eq "authDev") {
return undef unless (defined $val && $val ne "" && $init_done);
my $bhash = $defs{$val};
+ return "Unknown device $val" if !defined $bhash;
return "Not a GoogleAuth device $val" unless $bhash->{TYPE} eq "GoogleAuth";
return undef;
} elsif($attr eq "cmdKeyword") {
return undef;
+ } elsif($attr eq "cmdFavorite") {
+ return undef;
} elsif($attr eq "babbleDev") {
return undef unless (defined $val && $val ne "" && $init_done);
my $bhash = $defs{$val};
@@ -1640,22 +1747,22 @@ sub Signalbot_Detail {
return "Perl module Protocol:DBus not found, please install with
sudo cpan install Protocol::DBus
and restart FHEM
";
}
my $multi=$hash->{helper}{multi};
+ my $version=$hash->{helper}{version};
+ $version=0 if !defined $version;
$multi=0 if !defined $multi;
- if($hash->{helper}{version}<900) {
+ if($version<900) {
$ret .= "signal-cli v0.9.0+ required.
Please use installer to install or update
";
- $ret .= "Note: The installer only supports Debian based Linux distributions like Ubuntu and Raspberry OS
";
+ $ret .= "Note: The installer only supports Debian based Linux distributions like Ubuntu and Raspberry OS
";
$ret .= " and X86 or armv7l CPUs
";
}
- if($hash->{helper}{version}==901) {
+ if($version==901) {
$ret .= "Warning: signal-cli v0.9.1 has issues affecting Signalbot.
Please use installer to downgrade to 0.9.0
";
}
- if ($multi==0) {
+ if ($multi==0 && $version>0) {
$ret .= "Signal-cli is running in single-mode, please consider starting it without -u parameter (e.g. by re-running the installer)
";
}
- if($hash->{helper}{version}<900 || $multi==0) {
- $ret .= 'You can download the installer here or your www/signal directory and run it with
sudo ./signal_install.sh
';
- $ret .= "Alternatively go to FHEM SVN thirdparty and download the matching Debian package
";
- $ret .= "Install with e.g. sudo apt install ./signal-cli-dbus_0.9.0-1_buster_armhf.deb (./ is important to tell apt this is a file)
";
+ if($version<900 || $multi==0) {
+ $ret .= '
You can download the installer here or your www/signal directory and run it with
sudo ./signal_install.sh
';
}
return $ret if ($hash->{helper}{version}<900);
@@ -1758,7 +1865,7 @@ sub Signalbot_Undef($$) { #
#If its a media stream, a file is being created and the temporary filename (delete later!) is returned
#Question: more complex commands could contain spaces but that will require more complex parsing
-sub SignalBot_replaceCommands(@) {
+sub Signalbot_replaceCommands(@) {
my ($hash, @data) = @_;
my @processed=();
@@ -1788,7 +1895,7 @@ sub SignalBot_replaceCommands(@) {
return ($msg, @processed);
}
- my ( $isMediaStream, $type ) = SignalBot_IdentifyStream( $hash, $msg );
+ my ( $isMediaStream, $type ) = Signalbot_IdentifyStream( $hash, $msg );
if ($isMediaStream<0) {
Log3 $hash->{NAME}, 5, $hash->{NAME}.": Media stream found $isMediaStream $type";
my $tmpfilename="/tmp/signalbot".gettimeofday().".".$type;
@@ -1822,7 +1929,7 @@ sub SignalBot_replaceCommands(@) {
}
#Get OSRelease Version
-sub SignalBot_OSRel() {
+sub Signalbot_OSRel() {
my $fh;
if (!open($fh, "<", "/etc/os-release")) {
@@ -1849,7 +1956,7 @@ sub SignalBot_OSRel() {
# -3 for other media
# and extension without dot as 2nd list element
-sub SignalBot_IdentifyStream($$) {
+sub Signalbot_IdentifyStream($$) {
my ($hash, $msg) = @_;
# signatures for media files are documented here --> https://en.wikipedia.org/wiki/List_of_file_signatures
@@ -2026,6 +2133,10 @@ For German documentation see Wiki<
Lists all accounts (phone numbers) registered on this computer. Only available when not attached to an account (account=none).
Use register or link to create new accounts.
+
+
+ Lists the defined favorites in the attribute "favorites" in a readable format
+
@@ -2072,13 +2183,31 @@ For German documentation see Wiki<
RegExp pattern that, when matched, will exclude messages to be processed by the Babble connection
-