mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-05-04 22:19:38 +00:00
10_RHASSPY:Initial Commit
git-svn-id: https://svn.fhem.de/fhem/trunk@24343 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
7b91ed778e
commit
7b1f0ca1f2
4051
fhem/contrib/RHASSPY/10_RHASSPY.pm
Normal file
4051
fhem/contrib/RHASSPY/10_RHASSPY.pm
Normal file
File diff suppressed because it is too large
Load Diff
133
fhem/contrib/RHASSPY/99_RHASSPY_Utils_Demo.pm
Normal file
133
fhem/contrib/RHASSPY/99_RHASSPY_Utils_Demo.pm
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
##############################################
|
||||||
|
# $Id$
|
||||||
|
#
|
||||||
|
|
||||||
|
package RHASSPY::Demo; ## no critic 'Package declaration'
|
||||||
|
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
use JSON;
|
||||||
|
use Encode;
|
||||||
|
use List::Util qw(max min);
|
||||||
|
|
||||||
|
use GPUtils qw(GP_Import);
|
||||||
|
|
||||||
|
## Import der FHEM Funktionen
|
||||||
|
#-- Run before package compilation
|
||||||
|
BEGIN {
|
||||||
|
|
||||||
|
# Import from main context
|
||||||
|
GP_Import(
|
||||||
|
qw(
|
||||||
|
AttrVal
|
||||||
|
InternalVal
|
||||||
|
ReadingsVal
|
||||||
|
ReadingsNum
|
||||||
|
ReadingsAge
|
||||||
|
fhem
|
||||||
|
Log3
|
||||||
|
decode
|
||||||
|
defs
|
||||||
|
round
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
sub ::RHASSPY_Utils_Demo_Initialize { goto &Initialize }
|
||||||
|
|
||||||
|
# initialize ##################################################################
|
||||||
|
sub Initialize {
|
||||||
|
my $hash = shift;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Enter you functions below _this_ line.
|
||||||
|
|
||||||
|
sub BasicTest {
|
||||||
|
my $site = shift;
|
||||||
|
my $type = shift;
|
||||||
|
Log3('rhasspy',3 , "RHASSPY: Site $site, Type $type");
|
||||||
|
return "RHASSPY: Site $site, Type $type";
|
||||||
|
}
|
||||||
|
|
||||||
|
sub DataTest {
|
||||||
|
my $name = shift;
|
||||||
|
my $rawd = shift;
|
||||||
|
|
||||||
|
my $hash = $defs{$name} // return;
|
||||||
|
my $data;
|
||||||
|
if ( !eval { $data = decode_json($rawd) ; 1 } ) {
|
||||||
|
Log3($hash->{NAME}, 1, "JSON decoding error, $rawd seems not to be valid JSON data: $@");
|
||||||
|
return "Error! $rawd seems not to be valid JSON data!";
|
||||||
|
}
|
||||||
|
my $site = $data->{siteId};
|
||||||
|
my $type = $data->{Type};
|
||||||
|
Log3('rhasspy',3 , "RHASSPY: Site $site, Type $type");
|
||||||
|
my @devices = sort keys %{$hash->{helper}{devicemap}->{devices}};
|
||||||
|
while (@devices > 2) {
|
||||||
|
shift @devices; # limit triggered devices two to minimize unwanted side effects
|
||||||
|
}
|
||||||
|
my @rets;
|
||||||
|
|
||||||
|
$rets[0] = "RHASSPY: Site $site, Type $type";
|
||||||
|
$rets[1] = join q{,}, @devices;
|
||||||
|
return \@rets;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub DialogueTest{
|
||||||
|
my $name = shift;
|
||||||
|
my $rawd = shift;
|
||||||
|
|
||||||
|
my $hash = $defs{$name} // return;
|
||||||
|
my $data;
|
||||||
|
if ( !eval { $data = decode_json($rawd) ; 1 } ) {
|
||||||
|
Log3($hash->{NAME}, 1, "JSON decoding error, $rawd seems not to be valid JSON data: $@");
|
||||||
|
return "Error! $rawd seems not to be valid JSON data!";
|
||||||
|
}
|
||||||
|
my $site = $data->{siteId};
|
||||||
|
my $type = $data->{Type};
|
||||||
|
Log3('rhasspy',3 , "RHASSPY: Site $site, Type $type");
|
||||||
|
my @devices = sort keys %{$hash->{helper}{devicemap}->{devices}};
|
||||||
|
while (@devices > 2) {
|
||||||
|
shift @devices; # limit triggered devices two to minimize unwanted side effects
|
||||||
|
}
|
||||||
|
my @rets;
|
||||||
|
|
||||||
|
#interactive dialogue as described in https://rhasspy.readthedocs.io/en/latest/reference/#dialoguemanager_continuesession and https://docs.snips.ai/articles/platform/dialog/multi-turn-dialog
|
||||||
|
|
||||||
|
#This example here just lets you confirm the action, as intent filter is limited to ConfirmAction
|
||||||
|
|
||||||
|
my $response = "RHASSPY asking for OK or cancellation: Site $site, Type $type";
|
||||||
|
my $ca_string = qq{$hash->{LANGUAGE}.$hash->{fhemId}:ConfirmAction};
|
||||||
|
my $reaction = { text => $response,
|
||||||
|
intentFilter => ["$ca_string"] };
|
||||||
|
|
||||||
|
$rets[0] = $reaction;
|
||||||
|
$rets[2] = 30; #timeout to replace default timeout
|
||||||
|
|
||||||
|
return \@rets;
|
||||||
|
}
|
||||||
|
|
||||||
|
1;
|
||||||
|
|
||||||
|
__END__
|
||||||
|
|
||||||
|
=pod
|
||||||
|
=begin html
|
||||||
|
|
||||||
|
<a name="RHASSPY_Demo_Utils"></a>
|
||||||
|
<h3>RHASSPY_Demo_Utils</h3>
|
||||||
|
<ul>
|
||||||
|
<b>Routines to demonstrate how to handle function calls from within Custom intents in RHASSPY context</b><br>
|
||||||
|
<li>BasicTest</li>
|
||||||
|
This is to demonstrate how to get single elements from the message hash just by their name.</p>
|
||||||
|
Example: <code>attr <rhasspyDevice> rhasspyIntents SetCustomIntentsBasicTest=RHASSPY::Demo::BasicTest(siteId,Type)</code></p>
|
||||||
|
<li>DataTest</li>
|
||||||
|
This is to demonstrate how to get NAME and entire message hash and return a list of devices that may have been triggered. This is just a showcase to extended options and might be a good starting point for developing own complex Custom Intent functions.</p>
|
||||||
|
Example: <code>attr <rhasspyDevice> rhasspyIntents SetCustomIntentsDataTest=RHASSPY::Demo::DataTest(NAME,DATA)</code></p>
|
||||||
|
<li>DialogueTest</li>
|
||||||
|
This is to demonstrate how to keep dialogue open for some time and dynamically fill a slot for possible answer values to the dialoge. This is not fully tested jet and might somewhen in time be a good starting point for developing own complex Custom Intent functions including dialogues.</p>
|
||||||
|
Example: <code>attr <rhasspyDevice> rhasspyIntents SetCustomIntentsDialogueTest=RHASSPY::Demo::DialogueTest(NAME,DATA)</code></p>
|
||||||
|
</ul>
|
||||||
|
=end html
|
||||||
|
=cut
|
83
fhem/contrib/RHASSPY/99_RHASSPY_Utils_siteId2room.pm
Normal file
83
fhem/contrib/RHASSPY/99_RHASSPY_Utils_siteId2room.pm
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
##############################################
|
||||||
|
# $Id$
|
||||||
|
#
|
||||||
|
|
||||||
|
package RHASSPY::siteId2room; ## no critic 'Package declaration'
|
||||||
|
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
use JSON;
|
||||||
|
use Encode;
|
||||||
|
use List::Util qw(max min);
|
||||||
|
|
||||||
|
use GPUtils qw(GP_Import);
|
||||||
|
|
||||||
|
## Import der FHEM Funktionen
|
||||||
|
#-- Run before package compilation
|
||||||
|
BEGIN {
|
||||||
|
|
||||||
|
# Import from main context
|
||||||
|
GP_Import(
|
||||||
|
qw(
|
||||||
|
ReadingsVal
|
||||||
|
readingsSingleUpdate
|
||||||
|
Log3
|
||||||
|
decode
|
||||||
|
defs
|
||||||
|
makeReadingName
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
sub ::RHASSPY_Utils_siteId2room_Initialize { goto &Initialize }
|
||||||
|
|
||||||
|
# initialize ##################################################################
|
||||||
|
sub Initialize {
|
||||||
|
my $hash = shift;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Enter you functions below _this_ line.
|
||||||
|
|
||||||
|
sub siteId2room {
|
||||||
|
my $name = shift;
|
||||||
|
my $rawd = shift;
|
||||||
|
|
||||||
|
my $hash = $defs{$name} // return;
|
||||||
|
my $data;
|
||||||
|
if ( !eval { $data = decode_json($rawd) ; 1 } ) {
|
||||||
|
Log3($hash->{NAME}, 1, "JSON decoding error, $rawd seems not to be valid JSON data: $@");
|
||||||
|
return "Error! $rawd seems not to be valid JSON data!";
|
||||||
|
}
|
||||||
|
my $site = encode('UTF-8',$data->{siteId});
|
||||||
|
my $room = encode('UTF-8',$data->{Room});
|
||||||
|
my $rreading = makeReadingName("siteId2room_$site");
|
||||||
|
|
||||||
|
readingsSingleUpdate($hash, $rreading, $room, 1);
|
||||||
|
|
||||||
|
Log3($name, 5, "RHASSPY: Site $site now is in room $room");
|
||||||
|
|
||||||
|
my @rets;
|
||||||
|
|
||||||
|
$rets[0] = "Habe den Raum von $site auf $room geändert";
|
||||||
|
$rets[1] = $name;
|
||||||
|
return \@rets;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
1;
|
||||||
|
|
||||||
|
__END__
|
||||||
|
|
||||||
|
=pod
|
||||||
|
=begin html
|
||||||
|
|
||||||
|
<a name="RHASSPY_Utils_siteId2room"></a>
|
||||||
|
<h3>RHASSPY_Utils_siteId2room</h3>
|
||||||
|
<ul>
|
||||||
|
<li>siteId2room</li>
|
||||||
|
Routine to change the default room a siteId is assigned to. Might be usefull if you use e.g. your mobile phone as satellite.<br>
|
||||||
|
Example: <code>attr <rhasspyDevice> rhasspyIntents siteId2room=RHASSPY::siteId2room::siteId2room(NAME,DATA)</code></p>
|
||||||
|
</ul>
|
||||||
|
=end html
|
||||||
|
=cut
|
144
fhem/contrib/RHASSPY/rhasspy-de.cfg
Normal file
144
fhem/contrib/RHASSPY/rhasspy-de.cfg
Normal file
@ -0,0 +1,144 @@
|
|||||||
|
#$Id$
|
||||||
|
# Diese Datei an einem Ort ablegen, den der user fhem lesen kann
|
||||||
|
# und dann diesen Ort im Attribut configFile hinterlegen. Beispiel:
|
||||||
|
# attr <rhasspy> configFile ./log/rhasspy-de.cfg
|
||||||
|
#
|
||||||
|
# "commaconversion", "units" und "mutated_vowels" sind optional, wenn nicht
|
||||||
|
# angegeben, werden die englischen Werte/Gepflogenheiten verwendet bzw. keine
|
||||||
|
# Ersetzungen vorgenommen.
|
||||||
|
|
||||||
|
{"default":
|
||||||
|
{
|
||||||
|
"commaconversion": "1",
|
||||||
|
"mutated_vowels": {
|
||||||
|
"Ä": "Ae",
|
||||||
|
"Ö": "Oe",
|
||||||
|
"Ü": "Ue",
|
||||||
|
"ß": "ss",
|
||||||
|
"ä": "ae",
|
||||||
|
"ö": "oe",
|
||||||
|
"ü": "ue"
|
||||||
|
},
|
||||||
|
"units": {
|
||||||
|
"unitHours" : {
|
||||||
|
"0": "stunden",
|
||||||
|
"1": "eine stunde"
|
||||||
|
},
|
||||||
|
"unitMinutes": {
|
||||||
|
"0": "minuten",
|
||||||
|
"1": "eine minute"
|
||||||
|
},
|
||||||
|
"unitSeconds": {
|
||||||
|
"0": "sekunden",
|
||||||
|
"1": "eine sekunde"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"responses": {
|
||||||
|
"DefaultConfirmation": "OK",
|
||||||
|
"DefaultConfirmationTimeout": "Tut mir leid, da hat etwas zu lange gedauert",
|
||||||
|
"DefaultConfirmationNoOutstanding": "warte grade nicht auf eine bestätigung",
|
||||||
|
"DefaultCancelConfirmation": "Habe abgebrochen",
|
||||||
|
"DefaultConfirmationReceived": "Ok, werde ich machen",
|
||||||
|
"DefaultError": "Da ist leider etwas schief gegangen",
|
||||||
|
"NoValidData": "Tut mir leid, aber ich habe zu wenig Daten um den Vorgang auszuführen",
|
||||||
|
"NoDeviceFound": "Tut mir leid, ich konnte kein passendes Gerät finden",
|
||||||
|
"NoMappingFound": "Tut mir leid, aber ich konnte kein passendes Mäpping finden",
|
||||||
|
"NoNewValDerived": "Tut mir leid, aber ich konnte den Zielwert nicht ausrechnen",
|
||||||
|
"NoActiveMediaDevice": "Tut mir leid, es ist kein Wiedergabegerät aktiv",
|
||||||
|
"NoMediaChannelFound": "Tut mir leid, der angefragte Kanal scheint nicht zu existieren.",
|
||||||
|
"duration_not_understood": "Tut mir leid, ich habe die Dauer nicht verstanden",
|
||||||
|
"timerEnd": {
|
||||||
|
"0": "$label abgelaufen",
|
||||||
|
"1": "$label im raum $room abgelaufen"
|
||||||
|
},
|
||||||
|
"timerSet": {
|
||||||
|
"0": "$label im Raum $room ist gestellt auf $seconds sekunden",
|
||||||
|
"1": "$label im Raum $room ist gestellt auf $minutetext $seconds",
|
||||||
|
"2": "$label im Raum $room ist gestellt auf $minutetext",
|
||||||
|
"3": "$label im Raum $room ist gestellt auf $hours stunden $minutetext",
|
||||||
|
"4": "$label im Raum $room ist gestellt auf $hours uhr $minutes",
|
||||||
|
"5": "$label im Raum $room ist gestellt auf morgen, $hours uhr $minutes"
|
||||||
|
},
|
||||||
|
"timerCancellation": "$label im $room gelöscht",
|
||||||
|
"timeRequest": "Es ist $hour Uhr $min",
|
||||||
|
"weekdayRequest": "Heute ist $weekDay",
|
||||||
|
"reSpeak_failed": "Tut mir leid, ich kann mich nicht erinnern",
|
||||||
|
"Change": {
|
||||||
|
"volume": "$deviceName ist auf $value gestellt",
|
||||||
|
"brightness": "$deviceName ist auf $value gestellt",
|
||||||
|
"temperature": {
|
||||||
|
"0": "Die Temperatur von $location ist $value",
|
||||||
|
"1": "Die Temperatur von $location beträgt $value Grad"
|
||||||
|
},
|
||||||
|
"desired-temp": "Die Solltemperatur von $location beträgt $value Grad",
|
||||||
|
"battery": {
|
||||||
|
"0": "Der Batteriestand von $location ist $value",
|
||||||
|
"1": "Der Batteriestand von $location beträgt $value Prozent"
|
||||||
|
},
|
||||||
|
"waterLevel": "Der Wasserstand von $location beträgt $value Prozent",
|
||||||
|
"airHumidity": "Die Luftfeuchtigkeit von $location beträgt $value Prozent",
|
||||||
|
"soilMoisture": "Die Bodenfeuchte von $location beträgt $value Prozent",
|
||||||
|
"setTarget": "$device ist auf $value gesetzt",
|
||||||
|
"knownType": "$mappingType von $location beträgt $value Prozent",
|
||||||
|
"unknownType": "Der Wert von $location beträgt $value Prozent"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"stateResponses": {
|
||||||
|
"onOff": {
|
||||||
|
"0": "$deviceName ist ausgeschaltet",
|
||||||
|
"1": "$deviceName ist eingeschaltet"
|
||||||
|
},
|
||||||
|
"openClose": {
|
||||||
|
"0": "$deviceName ist geöffnet",
|
||||||
|
"1": "$deviceName ist geschlossen"
|
||||||
|
},
|
||||||
|
"inOut": {
|
||||||
|
"0": "$deviceName ist ausgefahren",
|
||||||
|
"1": "$deviceName ist eingefahren"
|
||||||
|
},
|
||||||
|
"inOperation": {
|
||||||
|
"0": "$deviceName ist fertig",
|
||||||
|
"1": "$deviceName läuft noch"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"user":
|
||||||
|
{
|
||||||
|
"units": {
|
||||||
|
"unitSeconds": {
|
||||||
|
"0": "Test einige Sekunden",
|
||||||
|
"1": "Test genau eine Sekunde"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
"slots":
|
||||||
|
{
|
||||||
|
"Colors": "braun:20,
|
||||||
|
grüngelb:90,
|
||||||
|
blaurot:330,
|
||||||
|
leichtes grüngelb:75,
|
||||||
|
grünblau:210,
|
||||||
|
rot:0,
|
||||||
|
grün:120,
|
||||||
|
magenta:300,
|
||||||
|
indigo:255,
|
||||||
|
dunkelgrün:120,
|
||||||
|
leichtes blaurot:345,
|
||||||
|
zinnober:15,
|
||||||
|
cyan:180,
|
||||||
|
leichtes grünblau:225,
|
||||||
|
leichtes blaugrün:135,
|
||||||
|
limett:105,
|
||||||
|
orange:30,
|
||||||
|
blaugrün:150,
|
||||||
|
gelb:60,
|
||||||
|
blau:240,
|
||||||
|
blaumagenta:315,
|
||||||
|
grüncyan:165,
|
||||||
|
violett:270,
|
||||||
|
blaucyan:195,
|
||||||
|
rotmagenta:315,
|
||||||
|
safran:45"
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user