2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-03-10 09:16:53 +00:00

36_Shelly.pm: Bugfix

95_Babble.pm: Minimale Ergänzungen

git-svn-id: https://svn.fhem.de/fhem/trunk@19819 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
phenning 2019-07-12 06:54:38 +00:00
parent 05cb9b10ad
commit 6450c9c796
2 changed files with 66 additions and 37 deletions

View File

@ -31,14 +31,15 @@ package main;
use strict; use strict;
use warnings; use warnings;
use JSON; # imports encode_json, decode_json, to_json and from_json. use JSON;
use HttpUtils;
use vars qw{%attr %defs}; use vars qw{%attr %defs};
sub Log($$); sub Log($$);
#-- globals on start #-- globals on start
my $version = "2.03"; my $version = "2.04";
#-- these we may get on request #-- these we may get on request
my %gets = ( my %gets = (
@ -178,6 +179,9 @@ sub Shelly_Define($$) {
readingsBulkUpdate($hash,"network","not connected"); readingsBulkUpdate($hash,"network","not connected");
} }
readingsEndUpdate($hash,1); readingsEndUpdate($hash,1);
#-- perform status update in a minute or so
InternalTimer(time()+60, "Shelly_status", $hash,0);
$init_done = $oid; $init_done = $oid;
@ -993,7 +997,7 @@ sub Shelly_pwd($){
my $green = $jhash->{'lights'}[0]{'green'}; my $green = $jhash->{'lights'}[0]{'green'};
my $blue = $jhash->{'lights'}[0]{'blue'}; my $blue = $jhash->{'lights'}[0]{'blue'};
my $white = $jhash->{'lights'}[0]{'white'}; my $white = $jhash->{'lights'}[0]{'white'};
my $rgb = sprintf("%X%X%X", $red,$green,$blue); my $rgb = sprintf("%02X%02X%02X", $red,$green,$blue);
readingsBulkUpdateIfChanged($hash,"rgb",$rgb); readingsBulkUpdateIfChanged($hash,"rgb",$rgb);
readingsBulkUpdateIfChanged($hash,"L-red",$red); readingsBulkUpdateIfChanged($hash,"L-red",$red);
@ -1005,9 +1009,9 @@ sub Shelly_pwd($){
for( my $i=0;$i<$meters;$i++){ for( my $i=0;$i<$meters;$i++){
$subs = ($meters == 1) ? "" : "_".$i; $subs = ($meters == 1) ? "" : "_".$i;
$power = $jhash->{'meters'}[$i]{'power'}; $power = $jhash->{'meters'}[$i]{'power'};
$energy = int($jhash->{'meters'}[$i]{'total'}/6)/10; $energy = (defined($jhash->{'meters'}[$i]{'total'}))?int($jhash->{'meters'}[$i]{'total'}/6)/10:"undefined";
readingsBulkUpdateIfChanged($hash,"power".$subs,$power); readingsBulkUpdateIfChanged($hash,"power".$subs,$power);
#readingsBulkUpdateIfChanged($hash,"energy".$subs,$energy); readingsBulkUpdateIfChanged($hash,"energy".$subs,$energy);
} }
} }
#-- common to all Shelly models #-- common to all Shelly models

View File

@ -55,7 +55,7 @@ if (eval {require RiveScript;1;} ne 1) {
my $babblelinkname = "babbles"; # link text my $babblelinkname = "babbles"; # link text
my $babblehiddenroom = "babbleRoom"; # hidden room my $babblehiddenroom = "babbleRoom"; # hidden room
my $babblepublicroom = "babble"; # public room my $babblepublicroom = "babble"; # public room
my $babbleversion = "1.35"; my $babbleversion = "1.42";
my @babblerows; my @babblerows;
my %babble_transtable_EN = ( my %babble_transtable_EN = (
@ -188,7 +188,9 @@ sub Babble_Initialize ($) {
#$hash->{AttrFn} = "Babble_Attr"; #$hash->{AttrFn} = "Babble_Attr";
my $attst = "lockstate:locked,unlocked helpFunc confirmFunc noChatBot:0,1 dnuFile testParm0 testParm1 testParm2 testParm3 ". my $attst = "lockstate:locked,unlocked helpFunc confirmFunc noChatBot:0,1 dnuFile testParm0 testParm1 testParm2 testParm3 ".
"remoteFHEM0 remoteFHEM1 remoteFHEM2 remoteFHEM3 remoteFunc0 remoteFunc1 remoteFunc2 remoteFunc3 remoteToken0 remoteToken1 remoteToken2 remoteToken3 ". "remoteFHEM0 remoteFHEM1 remoteFHEM2 remoteFHEM3 remoteFunc0 remoteFunc1 remoteFunc2 remoteFunc3 remoteToken0 remoteToken1 remoteToken2 remoteToken3 ".
"babbleIds babblePreSubs babbleDevices babblePlaces babbleNotPlaces babbleVerbs babbleVerbParts babblePrepos babbleQuests babbleArticles babbleStatus babbleWrites babbleTimes"; "babbleIds babblePreSubs:textField-long babbleDevices:textField-long babblePlaces:textField-long babbleNotPlaces:textField-long babbleVerbs:textField-long ".
"babbleVerbParts:textField-long babblePrepos:textField-long babbleQuests:textField-long babbleArticles:textField-long babbleStatus:textField-long ".
"babbleWrites:textField-long babbleTimes:textField-long";
$hash->{AttrList} = $attst; $hash->{AttrList} = $attst;
if( !defined($babble_tt) ){ if( !defined($babble_tt) ){
@ -372,7 +374,12 @@ sub Babble_CreateEntry($) {
sub Babble_Set($@) { sub Babble_Set($@) {
my ( $hash, $name, $cmd, @args ) = @_; my ( $hash, $name, $cmd, @args ) = @_;
if ( $cmd =~ /^lock(ed)?$/ ) { if ( $cmd =~ /^((talk)|(doit))/ ) {
#-- put args together, then split again at comma boundaries
my ($str,@newargs) = split(',',join(' ',@args));
return Babble_DoIt($name,$str,@newargs);
#-----------------------------------------------------------
}elsif ( $cmd =~ /^lock(ed)?$/ ) {
readingsSingleUpdate( $hash, "lockstate", "locked", 0 ); readingsSingleUpdate( $hash, "lockstate", "locked", 0 );
return; return;
#----------------------------------------------------------- #-----------------------------------------------------------
@ -396,7 +403,7 @@ sub Babble_Set($@) {
return Babble_restore($hash,1); return Babble_restore($hash,1);
} else { } else {
my $str = "[babble] Unknown argument " . $cmd . ", choose one of locked:noArg unlocked:noArg save:noArg restore:noArg test:noArg "; my $str = "[babble] Unknown argument " . $cmd . ", choose one of talk doit locked:noArg unlocked:noArg save:noArg restore:noArg test:noArg ";
$str .= "rivereload:noArg" $str .= "rivereload:noArg"
if($rive == 1 && AttrVal($name,"noChatBot",0) != 1); if($rive == 1 && AttrVal($name,"noChatBot",0) != 1);
return $str; return $str;
@ -644,6 +651,9 @@ sub Babble_Normalize($$){
} }
my @word = split(' ',$sentmod,15); my @word = split(' ',$sentmod,15);
my $len = int(@word); my $len = int(@word);
#-- emergency: only one word given
return ($word[0],"none","none","none","none","none","none","X.X.X")
if( $len==1 );
############################# POS tagging ################### ############################# POS tagging ###################
@ -1096,6 +1106,7 @@ sub Babble_DoIt{
my $star = ""; my $star = "";
my $reply = ""; my $reply = "";
readingsSingleUpdate( $hash, "text", $sentence, 0 );
#-- semantic analysis #-- semantic analysis
my ($device,$verb,$reading,$value,$article,$reserve,$place,$cat) = Babble_Normalize($name,$sentence); my ($device,$verb,$reading,$value,$article,$reserve,$place,$cat) = Babble_Normalize($name,$sentence);
$verb = "none" $verb = "none"
@ -1120,6 +1131,7 @@ sub Babble_DoIt{
#-- find command directly #-- find command directly
my $cmd = $hash->{DATA}{"command"}{$device}{$place}{$verb}{$reading}; my $cmd = $hash->{DATA}{"command"}{$device}{$place}{$verb}{$reading};
#Log3 $name,5,"[Babble_DoIt] Result after first access of Cmd-Hash =".((defined $cmd)?$cmd:"none");
#-- not directly - but maybe we have an alias device ? #-- not directly - but maybe we have an alias device ?
if( !defined($cmd) || $cmd eq "" ){ if( !defined($cmd) || $cmd eq "" ){
@ -1138,6 +1150,7 @@ sub Babble_DoIt{
last; last;
} }
} }
#Log3 $name,5,"[Babble_DoIt] Result after second access of Cmd-Hash =".((defined $cmd)?$cmd:"none");
} }
#-- not directly - but maybe we have a device which is an extension of an alias device #-- not directly - but maybe we have a device which is an extension of an alias device
@ -1158,6 +1171,7 @@ sub Babble_DoIt{
} }
} }
} }
#Log3 $name,5,"[Babble_DoIt] Result after third access of Cmd-Hash =".((defined $cmd)?$cmd:"none");
} }
#-- command found after all #-- command found after all
@ -1174,18 +1188,21 @@ sub Babble_DoIt{
$cmd =~ s/\$PARM$i/$parms[$i]/g; $cmd =~ s/\$PARM$i/$parms[$i]/g;
} }
if( $testit==0 || ($testit==1 && $exflag==1 )){ if( $testit==0 || ($testit==1 && $exflag==1 )){
Log3 $name,1,"[Babble_DoIt] Executing from hash: $device.$place.$verb.$reading/$value "; Log3 $name,5,"[Babble_DoIt] Executing from hash: $device.$place.$verb.$reading/$value ";
my $contact = $hash->{DATA}{"devcontacts"}{$device}[2]; my $contact = $hash->{DATA}{"devcontacts"}{$device}[2];
my $fhemdev = $hash->{DATA}{"devcontacts"}{$device}[1]; my $fhemdev = $hash->{DATA}{"devcontacts"}{$device}[1];
if( $contact == 0 ){ if( $contact == 0 ){
$res = fhem($cmd); $res = fhem($cmd);
readingsSingleUpdate( $hash, "cmd", $cmd, 0 );
}else{ }else{
my $ip = AttrVal($name,"remoteFHEM".$contact,undef); my $ip = AttrVal($name,"remoteFHEM".$contact,undef);
my $token = AttrVal($name,"remoteToken".$contact,undef); my $token = AttrVal($name,"remoteToken".$contact,undef);
my $func = AttrVal($name,"remoteFunc".$contact,undef); my $func = AttrVal($name,"remoteFunc".$contact,undef);
if( $func && $func ne "" ){ if( $func && $func ne "" ){
$res = eval($func."(\"".$cmd."\")") $res = eval($func."(\"".$cmd."\")");
readingsSingleUpdate( $hash, "cmd", $res, 0 );
}else{ }else{
readingsSingleUpdate( $hash, "cmd", "remoteFHEM".$contact." ".$cmd, 0 );
$cmd =~ s/\s/\%20/g; $cmd =~ s/\s/\%20/g;
my $url = "http://".$ip."/fhem?XHR=1&amp;fwcsrf=".$token."&amp;cmd.$fhemdev=$cmd"; my $url = "http://".$ip."/fhem?XHR=1&amp;fwcsrf=".$token."&amp;cmd.$fhemdev=$cmd";
HttpUtils_NonblockingGet({ HttpUtils_NonblockingGet({
@ -1212,13 +1229,12 @@ sub Babble_DoIt{
} }
} }
#-- what to do in conclusion #-- what to do in conclusion
if( $testit==0 ){ if( $testit==1 ){
return undef;
}else{
$str .= "==> $cmd"; $str .= "==> $cmd";
return $str; return $str;
} }
return undef;
#-- no command found, acquire alternate text #-- no command found, acquire alternate text
}else{ }else{
#-- ChatBot available #-- ChatBot available
@ -1239,12 +1255,13 @@ sub Babble_DoIt{
close $fh; close $fh;
} }
} }
readingsSingleUpdate( $hash, "cmd", "none => ChatBot text = $reply", 0 );
#-- no chatbot, use help text directly #-- no chatbot, use help text directly
}else{ }else{
$reply = defined($hash->{DATA}{"help"}{$device}) ? $hash->{DATA}{"help"}{$device} : ""; $reply = defined($hash->{DATA}{"help"}{$device}) ? $hash->{DATA}{"help"}{$device} : "";
readingsSingleUpdate( $hash, "cmd", "none => Help text = $reply", 0 );
} }
#-- get help function #-- get help function - embed reply of chatbot here
my $func = AttrVal($name,"helpFunc",undef); my $func = AttrVal($name,"helpFunc",undef);
if( $func && $func ne "" ){ if( $func && $func ne "" ){
#-- substitution #-- substitution
@ -1254,23 +1271,25 @@ sub Babble_DoIt{
for(my $i=0;$i<int(@parms);$i++){ for(my $i=0;$i<int(@parms);$i++){
$func =~ s/\$PARM$i/$parms[$i]/g; $func =~ s/\$PARM$i/$parms[$i]/g;
} }
if( $testit==0 ){ #-- parameter is missing
if( $func =~ /.*PARM\d.*/){
return $str." ".$reply;
#-- test
}elsif( $testit==1 ){
$res = eval($func)
if( $exflag==1 );
return $str." ".$func;
}else{
$res = eval($func); $res = eval($func);
return ""; return "";
}elsif($testit==1 && $exflag==1 ){ }
$res = eval($func);
return $str." ".$reply;
}else{
return $str." ".$func;
}
#-- no command, testing, no execution #-- no command, testing, no execution
}elsif( $testit==1 ){ }elsif( $testit==1 ){
Log 1,"[Babble_DoIt] Command $device.$place.$verb.$reading/$value undefined, reply = $reply"; Log 1,"[Babble_DoIt] Command $device.$place.$verb.$reading/$value undefined, reply = $reply";
$str = $reply; return $reply;
}else{ }else{
$str = ""; return ""
} }
return $str;
} }
} }
@ -1470,14 +1489,14 @@ sub Babble_RemCmd($$$$$$){
if( $target eq ""); if( $target eq "");
#-- trying to delete from data obtained via web #-- trying to delete from data obtained via web
if( defined($hash->{DATA}{"command"}{$bdev}{$place}{$verb}{$target}) ){ if( defined($hash->{DATA}{"command"}{$bdev}{$place}{$verb}{$target}) ){
Log3 $name, 1,"[Babble_RemCmd] Deleting from hash: $bdev.$place.$verb.$target => ".$hash->{DATA}{"command"}{$bdev}{$place}{$verb}{$target}; Log3 $name, 5,"[Babble_RemCmd] Deleting from hash: $bdev.$place.$verb.$target => ".$hash->{DATA}{"command"}{$bdev}{$place}{$verb}{$target};
delete($hash->{DATA}{"command"}{$bdev}{$place}{$verb}{$target}); delete($hash->{DATA}{"command"}{$bdev}{$place}{$verb}{$target});
return return
#-- try to figure out data from index (fallback strategy) #-- try to figure out data from index (fallback strategy)
}else{ }else{
my $cmdstr = $babblerows[$fallback-1]; my $cmdstr = $babblerows[$fallback-1];
($bdev,$place,$verb,$target)=split('\+\|\+',$cmdstr); ($bdev,$place,$verb,$target)=split('\+\|\+',$cmdstr);
Log3 $name, 1,"[Babble_RemCmd] Deleting in fallback strategy from hash: $bdev.$place.$verb.$target => ".$hash->{DATA}{"command"}{$bdev}{$place}{$verb}{$target}; Log3 $name, 5,"[Babble_RemCmd] Deleting in fallback strategy from hash: $bdev.$place.$verb.$target => ".$hash->{DATA}{"command"}{$bdev}{$place}{$verb}{$target};
delete($hash->{DATA}{"command"}{$bdev}{$place}{$verb}{$target}); delete($hash->{DATA}{"command"}{$bdev}{$place}{$verb}{$target});
return return
} }
@ -2157,21 +2176,23 @@ sub Babble_Html($)
<br/> <br/>
<h4>Define</h4> <h4>Define</h4>
<p> <p>
<code>define &lt;name&gt; babble</code> <code>define &lt;name&gt; Babble</code>
<br />Defines the Babble device. </p> <br />Defines the Babble device. </p>
<a name="babbleset"></a> <a name="babbleset"></a>
Notes: <ul> Notes: <ul>
<li>This module uses the global attribute <code>language</code> to determine its output data<br/> <li>This module uses the global attribute <code>language</code> to determine its output data<br />
(default: EN=english). For German output set <code>attr global language DE</code>.</li> (default: EN=english). For German output set <code>attr global language DE</code>.</li>
<li>This module needs the JSON package.</li> <li>This module needs the JSON package.</li>
<li>Only when the chatbot functionality of RiveScript is required, the RiveScript module must be installed as well, see https://github.com/aichaos/rivescript-perl</li> <li>Only when the chatbot functionality of RiveScript is required, the RiveScript module must be installed as well, see https://github.com/aichaos/rivescript-perl</li>
</ul> </ul>
<h4>Usage</h4> <h4>Usage</h4>
To use this module, call the Perl function <code>Babble_DoIt("&lt;name&gt;","&lt;sentence&gt;"[,&lt;parm0&gt;,&lt;parm1&gt;,...])</code>. To use this module,
&lt;name&gt; is the name of the Babble device, &lt;parm0&gt; &lt;parm1&gt; are arbitrary parameters. <ol><li>call the Perl function <code>Babble_DoIt("&lt;name&gt;","&lt;sentence&gt;"[,&lt;parm0&gt;,&lt;parm1&gt;,...])</code>.</li>
<li>execute the FHEM command <code>set &lt;name&gt; talk|doit &lt;sentence&gt;[,&lt;parm0&gt;,&lt;parm1&gt;,...]</code>.</li>
</ol>
&lt;name&gt; is the name of the Babble device, &lt;parm0&gt; &lt;parm1&gt; are arbitrary parameters passed to the executed command.
The module will analyze the sentence passed an isolate a device to be addressed, a place identifier, The module will analyze the sentence passed an isolate a device to be addressed, a place identifier,
a verb, a target and its value from the sentence passed. a verb, a target and its value from the sentence passed. <b>Attention: in case the FHEM command is used, &lt;sentence&gt must not contain commas.</b>
If a proper command has been stored with device, place, verb and target, it will be subject to substitutions and then will be executed. If a proper command has been stored with device, place, verb and target, it will be subject to substitutions and then will be executed.
In these substitutions, a string $VALUE will be replaced by the value for the target reading, a string $DEV will be replaced by the device name identified by Babble, In these substitutions, a string $VALUE will be replaced by the value for the target reading, a string $DEV will be replaced by the device name identified by Babble,
@ -2185,7 +2206,11 @@ sub Babble_Html($)
</ul> </ul>
<h4>Set</h4> <h4>Set</h4>
<ul> <ul>
<li><a name="babble_lock"> <li><a name="babble_talk">
<code>set &lt;name&gt; talk|doit &lt;sentence&gt;[,&lt;parm0&gt;,&lt;parm1&gt;,...]</code><br />
</a>
<br />execute the command given in the sentence.</li>
<li><a name="babble_lock">
<code>set &lt;name&gt; locked</code><br /> <code>set &lt;name&gt; locked</code><br />
<code>set &lt;name&gt; unlocked</code> <code>set &lt;name&gt; unlocked</code>
</a> </a>
@ -2296,7 +2321,7 @@ sub Babble_Html($)
<a name="Babble"></a> <a name="Babble"></a>
<h3>Babble</h3> <h3>Babble</h3>
<ul> <ul>
<a href="https://wiki.fhem.de/wiki/Modul_Babble">Deutsche Dokumentation im Wiki</a> vorhanden, die englische Version gibt es hier: <a href="/fhem/docs/commandref.html#babble">babble</a> <a href="https://wiki.fhem.de/wiki/Modul_Babble">Deutsche Dokumentation im Wiki</a> vorhanden, die englische Version gibt es hier: <a href="commandref.html#Babble">Babble</a>
</ul> </ul>
=end html_DE =end html_DE
=cut =cut