Meine Alexa Custom Skill Config

Begonnen von AbeamStart, 17 September 2018, 19:04:36

Vorheriges Thema - Nächstes Thema

AbeamStart

Hallo,
da ich auch lange gebraucht habe mit dem zusammenbasteln poste ich mal meine Config als Inspiration.
Wem etwas zur Optimierung auffällt, bitte gerne schreiben.

1. Abfrage Raumtemperatur
2. Abfrage Benzinkosten
3. Aktuelles Wetter
4. Haustüröffner
5. Müllkalender
6. Status Heizöltank
7. Aktuelle Fernsehsendung (Neutrino Receiver)
8. Radiosendung (Squeezebox)
9. Besuchermodus
10. Heizperiode an/aus
11. Fensterstatus
12. Lichtstatus
13. Batteriestatus

Hier meine 99_myUtilsAlexa.pm

package main;

use strict;
use warnings;
use POSIX;

sub
myUtilsAlexa_Initialize($$)
{
  my ($hash) = @_;
}

######################################################
# Alexa"
######################################################

sub alexaRoomTemperature($$) {
my($preposition,$room) = @_;
my $device = "";

$room = lc($room);

if ($room eq "wohnzimmer") {
$device = "Wohnzimmer_Heizung";
} elsif ($room eq "fernsehzimmer") {
$device = "Fernsehzimmer_Heizung";
} elsif ($room eq "esszimmer") {
$device = "Esszimmer_Heizung";
} elsif ($room eq "küche") {
$device = "Kueche_Heizung";
} elsif ($room eq "WC") {
$device = "GaesteWC_Heizung";
} elsif ($room eq "gästezimmer") {
$device = "Gaestezimmer_Heizung";
} elsif ($room eq "schlafzimmer") {
$device = "Schlafzimmer_Heizung";
} elsif ($room eq "kinderzimmer") {
$device = "Kinderzimmer_Heizung";
} elsif ($room eq "arbeitszimmer") {
$device = "Arbeitszimmer_Heizung";
} elsif ($room eq "bad") {
$device = "BAD_Heizung";
} else {
return "Kein passendes Thermometer gefunden";
}

my $temperature = ReadingsVal($device, "measured-temp", 0);
$temperature =~ s/\./\,/g;
my $humidity = ReadingsVal($device, "humidity", 0);

return "Die aktuelle Temperatur beträgt $temperature Grad bei $humidity Prozent Luftfeuchtigkeit";
}


sub alexaCustom($) {
    my ($type) = @_;
    if ($type eq "benzin") {
    return 'Bei Aral in Obertshausen kostet der Super ' . ReadingsVal('Aral_Obertshausen', 'SuperE5', '0') . ' € und der Diesel ' . ReadingsVal('Aral_Obertshausen', 'Diesel', '0') . ' €, bei der Esso in Obertshausen kostet der Super ' . ReadingsVal('Esso_Obertshausen', 'SuperE5', '0') . ' € und der Diesel ' . ReadingsVal('Esso_Obertshausen', 'Diesel', '0') . ' €, bei der Jet in Offenbach kostet der Super ' . ReadingsVal('JET_Offenbach', 'SuperE5', '0') . ' € und der Diesel ' . ReadingsVal('JET_Offenbach', 'Diesel', '0') . ' €';
} elsif ($type eq "wetter") {
return 'Aktuell ist es ' . ReadingsVal('wetter_WU', 'condition', '0') . 'bei ' . ReadingsVal('wetter_WU', 'temperatureround', '0') . ' Grad morgen wird es ' . ReadingsVal('wetter_WU', 'fc1_condition', '0') . 'bei mindestens' . ReadingsVal('wetter_WU', 'fc1_low_c', '0') . ' Grad und maximal' . ReadingsVal('wetter_WU', 'fc1_high_c', '0') . 'Grad. Die Sonne geht um ' . ReadingsVal('wetter_WU', 'sunrise', '0') . ' Uhr auf und um ' . ReadingsVal('wetter_WU', 'sunset', '0') . ' Uhr unter.';
} elsif ($type eq "öl") {
return 'Im Heizöltank sind noch ' . ReadingsVal('heizoelrestliter', 'RemainingUsableLevel', '0') . ' Liter, das sind ' . ReadingsVal('heizoelprozent', 'RemainingUsablePercent', '0') . ' Prozent';
} elsif ($type eq "fernsehen") {
return 'Aktuell läuft ' . ReadingsVal('TankReceiver', 'currentTitle', '0') . ' Die Sendung hat um ' . ReadingsVal('TankReceiver', 'egp_current_start_t', '0') . ' Uhr angefangen und läuft noch bis ' . ReadingsVal('TankReceiver', 'egp_current_stop_t', '0') . ' Uhr';

    }

    return 'wie bitte?';
}

sub alexaMuell($) {
    my ($type) = @_;

    Log3('alexa', 4, 'Müll: ' . $type);

    my $days;
    my $what;

    if ($type eq "müll") {
        $days = ReadingsNum('abfallkalendermodul', 'next_days', -1);
        $what = join(
            ' und ',
            split(
                / \/ /,
                ReadingsVal('abfallkalendermodul', 'next_text', 'irgendetwas')
            )
        );

    } elsif ($type =~ /bio/) {
        $days = ReadingsNum('abfallkalendermodul', 'abfallkalender_Biotonne_days', -1);
        $what = 'der Biomüll';
    } elsif ($type =~ /papier/) {
        $days = ReadingsNum('abfallkalendermodul', 'abfallkalender_Papier_days', -1);
        $what = 'der Papiermüll';
    } elsif ($type =~ /haus/) {
        $days = ReadingsNum('abfallkalendermodul', 'abfallkalender_Hausmuell_days', -1);
        $what = 'der Restmüll';
    } elsif ($type =~ /sack/) {
        $days = ReadingsNum('abfallkalendermodul', 'abfallkalender_GelberSack_days', -1);
        $what = 'der gelbe Sack';
    }

    if ($days && $what) {
        if ($days == -1) {
            return 'Irgendetwas stimmt mit dem Abfallkalender nicht.';
        } elsif ($days == 0) {
            return 'Heute wird ' . $what . ' abgeholt';
        } elsif ($days == 1) {
            return 'Morgen wird ' . $what . ' abgeholt';
        }

        return 'In ' . $days . ' Tagen wird ' . $what . ' abgeholt';
    }

    return 'Ich habe leider nur Müll verstanden.';
}

sub alexaRoomRadio($$) {
my($preposition,$room) = @_;
my $device = "";

$room = lc($room);

if ($room eq "wohnzimmer") {
$device = "WohnzimmerPlayer";
} elsif ($room eq "esszimmer") {
$device = "EsszimmerPlayer";
} elsif ($room eq "küche") {
$device = "KuechePlayer";
} elsif ($room eq "WC") {
$device = "WCPlayer";
} elsif ($room eq "bad") {
$device = "BadPlayer";
} else {
return "Das weiss ich aktuell leider nicht";
}

my $artist = ReadingsVal($device, "currentArtist", 0);
my $playlist = ReadingsVal($device, "currentPlaylistName", 0);
my $title = ReadingsVal($device, "currentTitle", 0);
my $album = ReadingsVal($device, "currentAlbum", 0);

return "Aktuell läuft $preposition $room $artist und $title $playlist $album";
}

sub alexastatusFensterOffen() {

#my @monitored=devspec2array("comment=/*Fenster/*:FILTER=STATE!=closed");
my @monitored=devspec2array("subType=threeStateSensor:FILTER=STATE!=closed");
my $cnt_devs=@monitored;
my $i = 0;
my $msgtext = "";
foreach(@monitored) {
$msgtext .= AttrVal($_,"alias",$_);
if ($i < $cnt_devs - 2) {
  $msgtext .= ", ";
}
if ($i == $cnt_devs - 2) {
  $msgtext .= " und ";
}
$i++;
}

if ($cnt_devs > 1) {
return "$msgtext sind noch auf";
}
elsif ($cnt_devs < 1){
return "Alle Fenster sind zu";
}
elsif ($cnt_devs = 1){
return "$msgtext ist noch auf";
}
}

sub alexastatusLichtan() {

my @monitored=devspec2array("comment=/*Licht/*:FILTER=STATE!=off");
my $cnt_devs=@monitored;
my $i = 0;
my $msgtext = "";
foreach(@monitored) {
$msgtext .= AttrVal($_,"alias",$_);
if ($i < $cnt_devs - 2) {
  $msgtext .= ", ";
}
if ($i == $cnt_devs - 2) {
  $msgtext .= " und ";
}
$i++;
}

if ($cnt_devs > 1) {
return "$msgtext sind noch an";
}
elsif ($cnt_devs < 1){
return "Alle Lichter sind aus";
}
elsif ($cnt_devs = 1){
return "$msgtext ist noch an";
}
}

sub alexastatusBatterie() {

my @monitored=devspec2array("battery=(0|low)");
my $cnt_devs=@monitored;
my $i = 0;
my $msgtext = "";
foreach(@monitored) {
$msgtext .= AttrVal($_,"alias",$_);
if ($i < $cnt_devs - 2) {
  $msgtext .= ", ";
}
if ($i == $cnt_devs - 2) {
  $msgtext .= " und ";
}
$i++;
}

if ($cnt_devs > 1) {
return "Die Batterien von $msgtext sind leer";
}
elsif ($cnt_devs < 1){
return "Keine Batterien sind leer";
}
elsif ($cnt_devs = 1){
return "Die Batterie von $msgtext ist leer";
}
}

# End Alexa
# behind your last function, we need the following
1;


Und hier mein Auszug aus der .cfg

attr alexa fhemIntents #IntentName=<sample utterance>\
gutenMorgen=guten morgen\
guteNacht=gute nacht\
{alexaRoomTemperature($preposition,$Room)}=wie warm ist es {preposition} {Room}\
{alexaCustom("benzin")}=was kostet der Sprit|wieviel kostet der Sprit|was kostet das Benzin|wieviel kostet das Benzin\
{alexaCustom("wetter")}=wie ist das wetter|wie sieht es draussen aus|wie warm ist es draussen|wie ist es draussen\
{ fhem("set keymatic open");;;;return "Haustür geöffnet"}:öffne haustür|mach die haustür auf|sesam öffne dich|tür auf\
{alexaMuell($type)}=wann wird der {type:Müll;;Biomüll;;Papiermüll;;Hausmüll;;gelbe Sack} abgeholt\
{alexaCustom("öl")}=wie viel Heizöl ist noch da|wie viel Heizöl ist noch im Tank|ist noch Heizöl da\
{alexaCustom("fernsehen")}=was läuft gerade im fernsehen|was ist gerade im Fernsehen\
{alexaRoomRadio($preposition,$Room)}=was läuft gerade {preposition} {Room}\
{ fhem("set Besuch BesuchAnwesend");;;;return "Ich habe den Besuchermodus aktiviert, sage mir bitte Bescheid wenn der Besuch abreist"}:Besuch ist da|aktiviere Besuchermodus|wir haben Gäste\
{ fhem("set Besuch BesuchAbwesend");;;;return "Ich habe den Besuchermodus deaktiviert, sage mir bitte Bescheid wenn Besuch da ist"}:Besuch ist nicht mehr da|deaktiviere Besuchermodus|Besuch ist abgereist\
{ fhem("set Jahreszeit Sommer");;;;return "Ich habe den Sommermodus aktiviert, sage mir bitte Bescheid wenn ich auf Wintermodus schalten soll"}:Es ist Sommer|aktiviere den Sommermodus|Stelle auf Sommermodus\
{ fhem("set Jahreszeit Winter");;;;return "Ich habe den Wintermodus aktiviert, sage mir bitte Bescheid wenn ich auf Sommermodus schalten soll"}:Es ist Winter|aktiviere den Wintermodus|Stelle auf Wintermodus\
{alexastatusFensterOffen()}=ob noch fenster auf sind|welche fenster auf sind|welche fenster noch auf sind|sind noch fenster offen\
{alexastatusLichtan()}=ob noch licht an ist|welche lichter an sind|welche lichter noch an sind|sind noch lichter an\
{alexastatusBatterie()}=ob batterien leer sind|welche batterien leer sind|sind batterien leer


Die Intents und Slot Types sollten sich ja dann ergeben, kann ich aber auch auf Nachfrage nachliefern, genau wie Gerätespezifische Fragen.
FHEM auf Debian (VM)

cnkru

Hallo AbeamStart,

schön, dass Du deine Skill-Beispiele hier als Ideensammlung dem Forum mitteilst.
Ich möchte auch einige Ideen hinzufügen.
Am Anfang hatte ich meine Alexa's über die Ha-bridge eingebunden, um in meiner FHEM-Installation entsprechen Aktionen auslösen zu können.
Ziel war es mittels der Sprachsteuerung den WAF deutlich zu verbessern. Alle früheren Versuche mit FTUI und Floorplan
führten nicht zu der gewünschten Akzeptanz.
Die Gründe hierfür waren immer die selbigen, wie – ich muss erst den Computer starten, dann die Webseite aufrufen und irgendwo im Menü herumklicken ...
Selbst nach Einführung der ha-bridge, gab es kurioser Weise neue Probleme.
Stichwort Syntax, und damit die Notwendigkeit eines Spickzettels.

Wer kann sich das auch merken: ,,Alexa dimme die Heizung im Wohnzimmer auf 25 Prozent"

Nun gibt es den Custom-Skill – und ich muss sagen der liefert neue Freiheitsgrade...
Vielen Dank auch an Matthias Kleine von haus-automatisierung.com,
der mit seinen FHEM-Tutorial Parts zu ,,mit  Alexa FHEM steuern"  mich neu motiviert hat.

Ja was wollen meine Mädels denn wirklich? Hier ein paar Sprüche.
Alexa sag Schatzi:
-   Mir ist kalt/warm im Wohnzimmer? - Stellt den Thermostat auf Boost-Modus und zurück auf Automatic
-   Was kommt jetzt/abends im Fernsehen? - Liest Fernsehprogram mit Titel und Uhrzeit vor
-   Wie warm/kalt ist es draußen? - Gibt Temperatur/Feuchtigkeit/... von Sensor-1/2 plus Yahoo-Wetterdaten aus
-   Wann kommt der Bus? - Liefert Abfahrtzeiten ... (Beispiel aus FTUI)
-   Welche Neuigkeiten gibt es über Blitzer/Pollenflug
(Beispiel Blitzer nutzt Readings aus https://forum.fhem.de/index.php/topic,85941.15.html)

Hier ein Auszug aus dem fhemIndents

{alexaCustom("benzin","")}=was kostet der Sprit
{alexaCustom("temperature","")}=wie ist das  Wetter
{alexaCustom("muell","")}=wann sind die nächsten Termine
{alexaCustom("battery","")}=wie ist der Batteriestatus
{alexaCustom($preTemperature,$Room)}=mir ist {preTemperature:warm;kalt} {preposition} {Room}
{alexaCustom($InfoDevice,"")}=welche Neuigkeiten gibt es {preposition} {InfoDevice:temperatur;blitzer;pollen}
{alexaCustom($InfoDevice,"")}=wann kommt {article} {InfoDevice:müll;bus;bahn}
{alexaCustom($InfoDevice,$temporal)}=was kommt {temporal:jetzt;heute;abends} {preposition} {InfoDevice:fernsehen;heimkino;nachrichten}


Im Skill-Editor müssen die Slots InfoDevice , temporal, preTemperature, etc. entsprechend angelegt oder ergänzt werden.

Nun einige Beispiele aus meiner myUtils.pm


#############################
# ALEXA Custom Skill
##############################
sub alexaCustom($$) {
    my ($typ,$zeit) = @_;
    my $geraet="";
my $type = lc $typ;
.......
elsif ($type eq "temperature" || $type eq "temperatur") {
        return 'Die Temperatur bei uns an der Haustür ist ' . ReadingsVal('MultiSensor1', 'temperature', '0') . '
        Grad, und die Temperatur im Garten beträgt ' .  ReadingsVal('MultiSensor2', 'temperature', '0') . ' Grad.
        Draußen ist es ' .  ReadingsVal('m_Wetter', 'condition', '0') .' die Temperatur beträgt ' . ReadingsVal('m_Wetter', 'temp_c', '0') . ' Grad, der Wind weht mit ' . ReadingsVal('m_Wetter', 'wind', '0') . ' Kilometer pro Stunde.';

    }
.......
elsif ($type eq "fernsehen"|| $type eq "heimkino") {
     my $wert = Fernsehprogramm($zeit);
return $wert;
}
.......
elsif ($type eq "nachrichten"|| $type eq "neuigkeiten") {
     my $wert = Nachrichten();
return $wert;
}
.....

################################
# Fernsehprogramm für Alexa
sub Fernsehprogramm($)
{
my ($wann) = @_;
use strict;
use WWW::Mechanize ();
use HTML::TokeParser;

my $content;
my $Text = "";
my $t = "";
my $schar = '|';
my $in =0;
my $l = 0;
my $zeit="";
my $sender="";
my $prog="";
my $url = "";
my $mech = WWW::Mechanize->new();
if ($wann eq "jetzt" || $wann eq "gerade" || $wann eq "heute") {
$url ="https://www.tvspielfilm.de/tv-programm/rss/jetzt.xml";
}
if ($wann eq "heute abend" || $wann eq "abends") {
$url = "https://www.tvspielfilm.de/tv-programm/rss/heute2015.xml";
}
$mech->get( $url );

$content = HTML::TokeParser->new(\$mech->{content});
# suche alle title

while ( my $token = $content->get_tag("title")) {
    $t = $content->get_trimmed_text("/title");
   if (index($t, $schar) != -1) {
    $in = index($t, $schar);
    $l = length($t);
    $zeit=substr($t,0,$in);
    $t = substr($t,$in+1,($l-$in-1));
    $in = index($t, $schar);
    $sender=substr($t,0,$in);
    $l = length($t);
    $prog = substr($t,$in+1,($l-$in-1));

    $Text = $Text . "Um " . $zeit . "Uhr auf " . $sender. "kommt" . $prog . ". ";

}

  fhem("setreading TV Alexa_Text $Text");
return $Text
}
################################
# Nachrichten
################################

# Tagesschau Kurznachrichten für Alexa
sub Nachrichten()
{

use strict;
use WWW::Mechanize ();
use HTML::TokeParser;
use Encode qw(encode decode);
#my $fuer = decode_utf8 $cell->value;
my $content;
my $Text = "";

my $t = "";
my $t1 ="";
my $url = "";
my $mech = WWW::Mechanize->new();
my $enc = 'utf-8';

$url ="http://www.tagesschau.de/xml/rss2";

$mech->get( $url );

$content = HTML::TokeParser->new(\$mech->{content});
# Suche alle title

while ( my $token = $content->get_tag("title")) {
    $t = $content->get_trimmed_text("/title");
    $t1 = encode($enc, $t);
    $Text = $Text . $t1. ". ";
   }
  fhem("setreading News Alexa_Text $Text");

return $Text
}
################


Ich hoffe, ich habe einige Anregungen geben können.
Viel Spaß dabei.
Gruß
Carsten
RPi4, Razberry, ZWAVE (Thermostate, Dimmer, Schalter, Multisensor), Milight-LED, Wifi (IPCAM, Fritz!DECT, Sonoff), alexa, Hombridge, Velux-Rollos, Viessman-API, iobroker, SENEC

AbeamStart

#2
.
FHEM auf Debian (VM)

MadMax-FHEM

Ihr könnt euch auch dort anhängen, dann gibt es nicht mehrere Stellen... ;)

https://forum.fhem.de/index.php/topic,65890.0.html

Gruß und weiterhin viel Spaß, Joachim
FHEM PI3B+ Bullseye: HM-CFG-USB, 40x HM, ZWave-USB, 13x ZWave, EnOcean-PI, 15x EnOcean, HUE/deCONZ, CO2, ESP-Multisensor, Shelly, alexa-fhem, ...
FHEM PI2 Buster: HM-CFG-USB, 25x HM, ZWave-USB, 4x ZWave, EnOcean-PI, 3x EnOcean, Shelly, ha-bridge, ...
FHEM PI3 Buster (Test)

AbeamStart

Zitat von: MadMax-FHEM am 19 September 2018, 20:37:41
Ihr könnt euch auch dort anhängen, dann gibt es nicht mehrere Stellen... ;)

https://forum.fhem.de/index.php/topic,65890.0.html

Gruß und weiterhin viel Spaß, Joachim

Finde es hier fast treffender, da im anderen Forum wieder Diskussionen sind hier geht es ja um Codeschnipsel. Bin da aber Leidenschaftslos.
Zur Not @Admins verschieben...
FHEM auf Debian (VM)