From 6f06a5e031d398deff8c3ecaa79b00c02a2e8a7d Mon Sep 17 00:00:00 2001
From: Beta-User <>
Date: Wed, 2 Mar 2022 17:33:38 +0000
Subject: [PATCH] mqtt2.template: add some OMG templates
git-svn-id: https://svn.fhem.de/fhem/trunk@25763 2b470e98-0d58-463d-a4d8-8e2adae1ed80
---
fhem/FHEM/lib/AttrTemplate/mqtt2.template | 46 ++++++++-
fhem/contrib/RHASSPY/10_RHASSPY.pm | 108 ++++++++++------------
2 files changed, 95 insertions(+), 59 deletions(-)
diff --git a/fhem/FHEM/lib/AttrTemplate/mqtt2.template b/fhem/FHEM/lib/AttrTemplate/mqtt2.template
index 20048d483..57df5bff9 100644
--- a/fhem/FHEM/lib/AttrTemplate/mqtt2.template
+++ b/fhem/FHEM/lib/AttrTemplate/mqtt2.template
@@ -4479,7 +4479,6 @@ desc:use this with an OpenMQTTGateway for temp/hum sensors like LYWSD03MMC and L
order:X_02d
par:BT_ID;Pls. enter your bluetooth device ID; {undef}
par:BASE_ID;BASE_ID typically is home;{ AttrVal("DEVICE","readingList","") =~ m,([^:]+)[/]O[^/]*M[^/]*G[^/]*[/].*:, ? $1 : undef }
-#par:READINGLISTOLD;copy readingList to new device for later resolving parameters;{ AttrVal("DEVICE","readingList","")}
par:NEWDEVROOM;Room of the calling device; {AttrVal("DEVICE","room","MQTT2_\DEVICE" )}
defmod OMG_BT_ID MQTT2_\DEVICE BT_ID
deletereading -q OMG_BT_ID (?!associatedWith|IODev).*
@@ -4497,6 +4496,51 @@ attr OMG_BT_ID model OpenMQTTGateway_BT_temp_hum_sensor
set DEVICE attrTemplate set_IODev_in_channels SUBCHANNELS=OMG_BT_ID
setreading OMG_BT_ID attrTemplateVersion 20220220
+name:OpenMQTTGateway_BT_scale
+prereq:{my @devices=devspec2array("model=OpenMQTTGateway_MCU");return 1 if $devices[0];return 0}
+filter:TYPE=MQTT2_DEVICE:FILTER=readingList=.*/O[^/]*M[^/]*G[^/]*/.*
+desc:use this with an OpenMQTTGateway for scales like Xiaomi Mi Scale. For further details visit https://github.com/1technophile/OpenMQTTGateway/wiki
Recommended structure of the topic pattern home/OpenMQTTGateway/.*.
NOTE: You'll be asked to provide the HEX address of your scale. Best start with looking at what "OpenMQTTGateway_BT_scanner" povides, e.g. if you have a reading name like "6C697244245E_id", "6C697244245E" (without quotes) is what you want to enter...
NOTE: this will create a new device!
+order:X_02e
+par:BT_ID;Pls. enter your bluetooth device ID; {undef}
+par:BASE_ID;BASE_ID typically is home;{ AttrVal('DEVICE','readingList','') =~ m,([^:]+)[/]O[^/]*M[^/]*G[^/]*[/].*:, ? $1 : undef }
+par:NEWDEVROOM;Room of the calling device; {AttrVal('DEVICE','room','MQTT2_\DEVICE')}
+defmod OMG_BT_ID MQTT2_\DEVICE BT_ID
+deletereading -q OMG_BT_ID (?!associatedWith|IODev).*
+attr OMG_BT_ID autocreate 0
+attr OMG_BT_ID readingList\
+ BASE_ID/O[^/]*M[^/]*G[^/]*/BTtoMQTT/BT_ID:.* { json2nameValue($EVENT,'',$JSONMAP) }
+attr OMG_BT_ID event-min-interval batteryPercent:7200,weight:1800
+attr OMG_BT_ID event-on-change-reading batteryPercent,weight:0.1,distance:5,impedance
+attr OMG_BT_ID icon message_medicine
+attr OMG_BT_ID jsonMap batt:batteryPercent tempc:temperature tem:0 tempf:0 hum:humidity servicedatauuid:0 servicedata:0
+attr OMG_BT_ID stateFormat weight kg
+attr OMG_BT_ID room NEWDEVROOM
+{ fhem "trigger $FW_wname JS:location.href='$FW_ME?detail=OMG_BT_ID'" if($cl && $cl->{TYPE} eq "FHEMWEB") }
+attr OMG_BT_ID model OpenMQTTGateway_BT_temp_hum_sensor
+set DEVICE attrTemplate set_IODev_in_channels SUBCHANNELS=OMG_BT_ID
+setreading OMG_BT_ID attrTemplateVersion 20220302
+
+name:OpenMQTTGateway_BT_unknown_gadget
+prereq:{my @devices=devspec2array("model=OpenMQTTGateway_MCU");return 1 if $devices[0];return 0}
+filter:TYPE=MQTT2_DEVICE:FILTER=readingList=.*/O[^/]*M[^/]*G[^/]*/.*
+desc:use this with an OpenMQTTGateway to get an "empty" device for further adoptions to your needs. For further details visit https://github.com/1technophile/OpenMQTTGateway/wiki
NOTE: You'll be asked to provide the HEX address of your gadget. Best start with looking at what "OpenMQTTGateway_BT_scanner" povides, e.g. if you have a reading name like "6C697244245E_id", "6C697244245E" (without quotes) is what you want to enter...
NOTE: this will create a new device!
+order:X_02x
+par:BT_ID;Pls. enter your bluetooth device ID; {undef}
+par:BASE_ID;BASE_ID typically is home;{ AttrVal('DEVICE','readingList','') =~ m,([^:]+)[/]O[^/]*M[^/]*G[^/]*[/].*:, ? $1 : undef }
+par:NEWDEVROOM;Room of the calling device; {AttrVal('DEVICE','room','MQTT2_\DEVICE')}
+defmod OMG_BT_ID MQTT2_\DEVICE BT_ID
+deletereading -q OMG_BT_ID (?!associatedWith|IODev).*
+attr OMG_BT_ID autocreate 0
+attr OMG_BT_ID readingList\
+ BASE_ID/O[^/]*M[^/]*G[^/]*/BTtoMQTT/BT_ID:.* { json2nameValue($EVENT,'',$JSONMAP) }
+attr OMG_BT_ID icon bluetooth
+attr OMG_BT_ID jsonMap batt:batteryPercent tempc:temperature tem:0 tempf:0 hum:humidity servicedatauuid:0 servicedata:0
+attr OMG_BT_ID room NEWDEVROOM
+{ fhem "trigger $FW_wname JS:location.href='$FW_ME?detail=OMG_BT_ID'" if($cl && $cl->{TYPE} eq "FHEMWEB") }
+attr OMG_BT_ID model OpenMQTTGateway_BT_temp_hum_sensor
+set DEVICE attrTemplate set_IODev_in_channels SUBCHANNELS=OMG_BT_ID
+setreading OMG_BT_ID attrTemplateVersion 20220302
+
###############
#OwnTracks
diff --git a/fhem/contrib/RHASSPY/10_RHASSPY.pm b/fhem/contrib/RHASSPY/10_RHASSPY.pm
index 95e4df262..13b66e564 100644
--- a/fhem/contrib/RHASSPY/10_RHASSPY.pm
+++ b/fhem/contrib/RHASSPY/10_RHASSPY.pm
@@ -320,7 +320,7 @@ sub Define {
$hash->{defaultRoom} = $defaultRoom;
my $language = $h->{language} // shift @{$anon} // lc AttrVal('global','language','en');
- $hash->{MODULE_VERSION} = '0.5.16';
+ $hash->{MODULE_VERSION} = '0.5.18';
$hash->{baseUrl} = $Rhasspy;
initialize_Language($hash, $language) if !defined $hash->{LANGUAGE} || $hash->{LANGUAGE} ne $language;
$hash->{LANGUAGE} = $language;
@@ -473,39 +473,10 @@ sub Undefine {
sub Delete {
my $hash = shift // return;
- #my $prefix = $hash->{prefix} // return;
deleteAllRegIntTimer($hash);
RemoveInternalTimer($hash);
-# DELETE POD AFTER TESTS ARE COMPLETED
-#Beta-User: Most likely removing attributes isn't a good idea; additionally: if, then attributes should be removed from global
-=begin comment
-
- #Beta-User: globale Attribute löschen
- for (devspec2array("${prefix}Mapping=.+")) {
- delFromDevAttrList($_,"${prefix}Mapping:textField-long");
- }
- for (devspec2array("${prefix}Name=.+")) {
- delFromDevAttrList($_,"${prefix}Name");
- }
- for (devspec2array("${prefix}Room=.+")) {
- delFromDevAttrList($_,"${prefix}Room");
- }
- for (devspec2array("${prefix}Channels=.+")) {
- delFromDevAttrList($_,"${prefix}Channels");
- }
- for (devspec2array("${prefix}Colors=.+")) {
- delFromDevAttrList($_,"${prefix}Colors");
- }
- for (devspec2array("${prefix}Specials=.+")) {
- delFromDevAttrList($_,"${prefix}Specials");
- }
- for (devspec2array("${prefix}Group=.+")) {
- delFromDevAttrList($_,"${prefix}Group");
- }
-=end comment
-=cut
return;
}
@@ -846,8 +817,6 @@ hermes/dialogueManager/configure (JSON)
https://rhasspy-hermes-app.readthedocs.io/en/latest/usage.html#continuing-a-session
=cut
- my $sId = $siteId eq 'null' ? 'null' : qq("$siteId");
-
my @disabled;
my $matches = join q{|}, @{$toDisable};
for (@intents) {
@@ -905,7 +874,6 @@ sub init_custom_intents {
my $err = perlSyntaxCheck( $perlcommand );
return "$err in $line" if $err && $init_done;
- #$hash->{helper}{custom}{$+{intent}}{perl} = $perlcommand; #Beta-User: delete after testing!
$hash->{helper}{custom}{$intent}{function} = $function;
my $args = trim($+{arg});
@@ -916,7 +884,7 @@ sub init_custom_intents {
push @params, $ar;
}
- $hash->{helper}{custom}{$+{intent}}{args} = \@params;
+ $hash->{helper}{custom}{$intent}{args} = \@params;
}
return;
}
@@ -1519,9 +1487,9 @@ sub initialize_msgDialog {
sub disable_msgDialog {
my $hash = shift // return;
my $enable = shift // 0;
- my $fromSST = shift;
- readingsSingleUpdate($hash,'enableMsgDialog',$enable,1) if !$fromSST;
- return initialize_msgDialog($hash) if $enable && !$fromSST;
+ my $fromSTT = shift;
+ readingsSingleUpdate($hash,'enableMsgDialog',$enable,1) if !$fromSTT;
+ return initialize_msgDialog($hash) if $enable && !$fromSTT;
my $devsp;
if ( defined $hash->{helper}->{STT}
@@ -2555,7 +2523,7 @@ sub notifySTT {
return AnalyzePerlCommand( undef, Babble_DoIt($hash->{Babble},$msgtext) ) if $msgtext !~ m{\A[\b]*$tocheck[\b]*\z}i;
$msgtext =~ s{\A[\b]*$tocheck}{}i;
}
- return msgDialog_open($hash, $client, $msgtext);
+ return ttsDialog_open($hash, $client, $msgtext);
}
return;
@@ -2678,7 +2646,7 @@ sub msgDialog_progress {
#This is the place to add additional logics and decission making...
#my $data = $hash->{helper}->{msgDialog}->{$device}->{data}; # // msgDialog_close($hash, $device);
Log3($hash, 5, "msgDialog_progress called with $device and text $msgtext");
- Log3($hash, 5, 'msgDialog_progress called without DATA') if !defined $data;
+ #Log3($hash, 5, 'msgDialog_progress called without DATA') if !defined $data;
return if !defined $data;
@@ -2740,7 +2708,7 @@ sub handleTtsMsgDialog {
&& defined $hash->{helper}->{msgDialog}->{$recipient} ) {
msgDialog_respond($hash,$recipient,$message);
sayFinished($hash, $data->{id}, $hash->{siteId});
- } elsif (defined $hash->{helper}->{STT}
+ } elsif ( defined $hash->{helper}->{STT}
&& defined $hash->{helper}->{STT}->{config}->{$recipient} ) {
ttsDialog_respond($hash,$recipient,$message,0);
sayFinished($hash, $data->{id}, $hash->{siteId}); #Beta-User: may be moved to response logic later with timeout...?
@@ -2777,6 +2745,7 @@ sub ttsDialog_close {
Log3($hash, 5, "ttsDialog_close called with $device");
deleteSingleRegIntTimer($device, $hash);
+ readingsSingleUpdate($defs{$device}, 'rhasspy_dialogue', 'closed', 1);
delete $hash->{helper}{ttsDialog}->{$device};
return;
@@ -2797,7 +2766,8 @@ sub ttsDialog_open {
customData => $device
};
- setTtsDialogTimeout($hash, $sendData, $hash->{helper}->{TTS}->{config}->{$device}->{sessionTimeout});
+ my $tout = $hash->{helper}->{TTS}->{config}->{$device}->{sessionTimeout} // $hash->{sessionTimeout};
+ setTtsDialogTimeout($hash, $sendData, $tout);
return ttsDialog_progress($hash, $device, $msgtext, $sendData);
}
@@ -2832,20 +2802,32 @@ sub ttsDialog_progress {
sub ttsDialog_respond {
my $hash = shift // return;
- my $DEVICE = shift // return;
+ my $device = shift // return;
my $message = shift // return;
my $keepopen = shift // 1;
- Log3($hash, 5, "ttsDialog_respond called with $DEVICE and text $message");
+ Log3($hash, 5, "ttsDialog_respond called with $device and text $message");
trim($message);
return if !$message; # empty?
- my $msgCommand = $hash->{helper}->{TTS}->{config}->{$DEVICE}->{ttsCommand} // return;
- $msgCommand =~ s{\\[\@]}{@}x;
- $msgCommand =~ s{(\$\w+)}{$1}eegx;
- AnalyzeCommand($hash, $msgCommand);
- resetRegIntTimer( $DEVICE, time + $hash->{helper}->{TTS}->{config}->{$DEVICE}->{sessionTimeout}, \&RHASSPY_msgDialogTimeout, $hash, 0) if $keepopen;
- return $DEVICE;
+ my $msgCommand = $hash->{helper}->{TTS}->{config}->{$device}->{ttsCommand} // return;
+ my %specials = (
+ '$DEVICE' => $device,
+ '$message' => $message,
+ '$NAME' => $hash->{NAME}
+ );
+ $msgCommand = EvalSpecials($msgCommand, %specials);
+ AnalyzeCommandChain($hash, $msgCommand);
+ if ( $keepopen ) {
+ my $tout = $hash->{helper}->{TTS}->{config}->{$device}->{sessionTimeout} // $hash->{sessionTimeout};
+ resetRegIntTimer( $device, time + $tout, \&RHASSPY_ttsDialogTimeout, $hash, 0);
+ readingsSingleUpdate($defs{$device}, 'rhasspy_dialogue', 'open', 1);
+ } else {
+ deleteSingleRegIntTimer($device, $hash);
+ delete $hash->{helper}->{ttsDialog}->{$device};
+ readingsSingleUpdate($defs{$device}, 'rhasspy_dialogue', 'closed', 1);
+ }
+ return $device;
}
# Update the readings lastIntentPayload and lastIntentTopic
@@ -3083,12 +3065,23 @@ sub respond {
readingsEndUpdate($hash,1);
Log3($hash->{NAME}, 5, "Response is: $response");
- #check for msgDialog session
- my $identity = (split m{_$hash->{siteId}_}, $data->{sessionId},3)[0];
+ #check for msgDialog or ttsDialog sessions
+ my $identity = (split m{_$hash->{siteId}_}xms, $data->{sessionId},3)[0];
if ( defined $hash->{helper}->{msgDialog}
&& defined $hash->{helper}->{msgDialog}->{$identity} ){
Log3($hash, 5, "respond deviated to msgDialog_respond for $identity.");
return msgDialog_respond($hash, $identity, $response);
+ } elsif (defined $hash->{helper}->{TTS}
+ && defined $hash->{helper}->{TTS}->{config}->{$identity} ) {
+ Log3($hash, 5, "respond deviated to ttsDialog_respond for $identity.");
+ $hash->{helper}->{ttsDialog}->{$identity}->{data} = $data if $topic eq 'continueSession';
+ return ttsDialog_respond($hash,$identity,$response,$topic eq 'continueSession');
+ } elsif (defined $hash->{helper}->{TTS}
+ && defined $hash->{helper}->{TTS}->{$identity} ) {
+ $identity = $hash->{helper}->{TTS}->{$identity};
+ Log3($hash, 5, "respond deviated to ttsDialog_respond for $identity by siteId.");
+ $hash->{helper}->{ttsDialog}->{$identity}->{data} = $data if $topic eq 'continueSession';
+ return ttsDialog_respond($hash,$identity,$response,$topic eq 'continueSession');
}
IOWrite($hash, 'publish', qq{hermes/dialogueManager/$topic $json});
@@ -3096,13 +3089,12 @@ sub respond {
#setDialogTimeout( $hash, $data, $delay, getResponse( $hash, 'SilentCancelConfirmation' ) ) if $delay;
#no audio output in msgDialog session
- return if defined $hash->{helper}->{msgDialog}
- && defined $hash->{helper}->{msgDialog}->{(split m{_$hash->{siteId}_}, $data->{sessionId},3)[0]};
- my $secondAudio = ReadingsVal($hash->{NAME}, "siteId2doubleSpeak_$data->{siteId}",0);
+ #return if defined $hash->{helper}->{msgDialog}
+ # && defined $hash->{helper}->{msgDialog}->{(split m{_$hash->{siteId}_}, $data->{sessionId},3)[0]};
+ my $secondAudio = ReadingsVal($hash->{NAME}, "siteId2doubleSpeak_$data->{siteId}",undef) // return;
sendSpeakCommand( $hash, {
siteId => $secondAudio,
- text => $response} )
- if $secondAudio;
+ text => $response} );
return;
}
@@ -5614,7 +5606,7 @@ i="i am hungry" f="set Stove on" d="Stove" c="would you like roast pork"<
Define custom reactions as soon as a specific hotword is detected (or with "global": a toggle command is detected). This does not require any specific configuration on any other FHEM device.
- One hotword per line, syntax is either a simple and an extended version. The "hotword" global will be treated specially and can be used to also execute custom commands when a
bumblebee_linux = set amplifier2 mute on
<
porcupine_linux = livingroom="set amplifier mute on" default={Log3($DEVICE,3,"device $DEVICE - room $ROOM - value $VALUE")}
@@ -5662,7 +5654,7 @@ i="i am hungry" f="set Stove on" d="Stove" c="would you like roast pork"
In addition to rhasspySTT, this attributes adds some options to manipulate the text-to-speech processing. Any AMADDevice to be adressed for own TTS processing has to be listed here with it's link to it's siteId. If RHASSPY detects a link between a siteId and an AMADDevice type FHEM device, it will not forward any text to be spoken to Rhasspy but use other synthetisation methods instead (defaulting to set <AMADDevice> ttsMsg $message
).
+
In addition to rhasspySTT, this attributes adds some options to manipulate the text-to-speech processing. Any AMADDevice to be adressed for own TTS processing has to be listed here with it's link to it's siteId (development remark: this is missleading atm!). If RHASSPY detects a link between a siteId and an AMADDevice type FHEM device, it will not forward any text to be spoken to Rhasspy but use other synthetisation methods instead (defaulting to set <AMADDevice> ttsMsg $message
).
Example:
AMADDev_A=siteId=android_livingroom ttsCommand={fhem("set $DEVICE ttsMsg $message")}
Notes: