Alexa Custom Skill Modul

Das ist ja nur auf die schnelle reinkopiert damit das vielleicht verständlich ist. Redundanten Code kann Du ja einfach in eine Funktion packen und diese aufrufen. Und Du musst ja nix verschachten Du kannst auch einfach mit einer if Anweisung arbeiten. Der Übersichtlichkeit ist das halt geschachtelt du kannst aber auch so was machen wie


if(($roomname == "flur" || $roomname == "diele") && ($device == "licht" || $device == "lampe" || $device == "beleuchtung" || $device == "led") && ($action == "an"))
{
// Einschaltbefehl
}

Erstmal auch von mir ein dickes Dankeschön an patami für die Module. Hab es damit hinbekommen dass Alexa mir eine Lampe an und aus schaltet. Fühl mich grad wie ein Fünfjähriger mit nem neuen Spielzeug.:smiley:

Ja, aber, mit der Verfeinerung hab ich noch so meine Sorgen.

Config sieht so aus:
Es gibt einen intent „MakeTest“ mit den slots: action und rooms

Custom Slots sind wie folgt definiert:
action: an | aus | einschalten | ausschalten
rooms: schlafzimmer | bad | wohnzimmer | flur

Utterances:
MakeTest licht {action} im {rooms}
MakeTest das licht {action} im {rooms}

in IPS gibt es die passende Instanz die auch fleissig Daten empfängt, aber es kommt nicht das an was soll:
Auf den Satz: „Alexa, frag … licht ausschalten im bad“ bekomme ich die slots wie folgt ins IPS:

  • Slots: {„action“:„licht ausschalten“,„rooms“:„bad“}

Tja, warum auch immer, landet das „licht“ mit im slot action. Klingt erstmal nicht schlimm, aber das führt natürlich dazu, das weitere Intents nicht erkannt werden und die Auswertung in IPS etwas schwieriger wird.

Für mein Verständnis sollte doch nur das übergeben werden, was als custom slot definiert ist, aber das "licht " gehört da nicht dazu.

Weiß hier jemand Rat?

Danke schonmal.

Grüße
user

Was steht denn im Service Simulator was Amazon an Intents sendet?

Eigentlich genau das, was im intent ankommt:

...
    "intent": {
      "name": "MakeTest",
      "slots": {
        "rooms": {
          "name": "rooms",
          "value": "bad"
        },
        "action": {
          "name": "action",
          "value": "licht ausschalten"
        }
      }
    }
  },
  "version": "1.0"
}

Es wird also schon von Amazon so an IPS gesendet.
Weiß auch nicht wieso amazon das nicht richtig auswertet nach Vorgabe der utterance.

Grüße
user

Sehr kurios, hab jetzt den custom slot type komplett gelöscht und neu angelegt, jetzt wird das richtig übergeben. Man könnte kurz denken jetzt funktioniert es, ABER: :mad:

amazon ist es augenscheinlich egal was im custom slot definiert ist denn:

„licht blabla im ofen“ ergibt:

    "slots": {
        "rooms": {
          "name": "rooms",
          "value": "ofen"
        },
        "action": {
          "name": "action",
          "value": "blabla"

obwohl die slots so definert sind:

rooms: schlafzimmer | bad | wohnzimmer | flur
action: einschalten | ausschalten

Ist das normal? Wozu definiere ich denn den custom slot, wenn dann doch wieder irgendwas in IPS landet was das Skript dort natürlich wieder nicht kennt.

Ist das bei Euch auch so?

Grüße
user

Du hast bei rooms nach deinen Angaben gar kein Ofen als Slot definiert da kann das Amazon auch nicht erkennen.

Schau Dir mal z.B. den How-To Skill näher an und dessen zugehörige Utterances, da siehst Du wie genau Utterances aufgebaut sein sollten, diese müssen sehr genau formuliert werden.

ja, das kommt schon vor. es passiert auch, dass man „lampen“ definiert und „lampe“ ankommt. das ist schon doof. aber dafür kann man die sätze in den sample utterances auch leicht abwandeln (es ist normalerweise egal ab man „die lampe“ oder „eine lampe“ sagt z.B.). nachteil ist, dass man das im intent abfangen muss.

aber etwas in der art

switch (strtolower(@slots['action'])) {
    case 'lampe':
    case 'lampen':
    case 'eine lampe':
    case 'die lampen':

löst das problem teilweise. man muss dann halt den switch case bei bedarf erweitern.

aber ja, es kommt auch mal „blabla“ an. aber dafür gibt es im switch case ja den fall default, wo man dann „diese lampe kenne ich nicht“ zurückgeben kann :slight_smile:

meine erfahrung ist, dass amazon es umso besser erkennt, umso mehr utterances angegeben sind. insgesamt ist das schon kurios, aber man bekommt das durch testen und optimierungen ganz gut in den griff. ist halt ein bisschen arbeit.

man könnte als utterances auch das definieren:

schalte die lampe im {room} {action}
schalte die lampen im {room} {action}
schalte eine lampe im {room} {action}
schalte das licht im {room} {action}
schalte die beleuchtung im {room} {action}

sowas funktioniert dann bei mir ganz gut.

sobald ich hier mal (am wochenende hoffentlich) mehr zeit habe, erweitere ich die beispiele.

Hallo Leute,

Ich habe soeben Version 3.1 des Custom Skill Moduls im master Branch released.

Die wesentlichen Änderungen sind:

  • Unterstützung für AMAZON.RepeatIntent, um vorherige Antworten erneut vorzulesen.
  • Erweiterung der Demo um AMAZON.StopIntent und AMAZON.RepeatIntent.
  • Komplette Umstrukturierung der Dokumentation.
  • Kleinere Verbesserungen. Bugfixes waren glücklicherweise nicht nötig :slight_smile:

Hier findet ihr mehr Infos:

Zukünftig findet ihr eine Übersicht der Änderungen immer in den Release Notes.

Feedback ist gerne willkommen :slight_smile:

Wahnsinn - Klasse Arbeit - Danke !!!

Und jetzt eine weitere Demo, wie versprochen.
Hat nur indirekt was mit Home Automation zu tun, zeigt aber das Session Handling ganz gut.

Hier geht’s zur Anleitung für das Labyrinth-Spiel.

Hallo Leute, danke für die Antworten. Hab schon befürchtet dass das normales Verhalten ist. Aber dass muss dann halt im Ips abgefangen werden.

Danke nochmal an patami, saubere Arbeit!

Grüße
user

Gesendet von meinem HUAWEI VNS-L31 mit Tapatalk

Hi patami, noch ein sehr großes Danke an dich.
Meine Alexa Datenbank ist mittlerweile ganz schön groß angewachsen.
Ich benutze momentan den Standard Skill von IPS und dazu deinen. Dein Skill kann mir über verschieden Fragen ganz andere Rückmeldungen und Ausführungen durchführen.
Da ich kein PHP Spezi bin vielleicht kann mir kurz einer weiterhelfen.
Eine Antwort gebe ich mit Alex in dem Stiel aus.

return AlexaCustomSkillPlainTextResponse::create(sprintf('Es sind % Grad im Wohnzimmer',getvalue(11919)));

Leider Spricht Alexa immer Punkt und nicht Komma aus. Hat jemand einen Tipp für mich. Ich habe schon andere Formatierungen versucht die es leider nicht besser gemacht haben.

Viele Grüße Daniel

Leider Spricht Alexa immer Punkt und nicht Komma aus. Hat jemand einen Tipp für mich.

Ja :wink:


return AlexaCustomSkillPlainTextResponse::create(sprintf('Es sind %s Grad im Wohnzimmer',number_format(getvalue(11919),1, ",", "")));

Danke Uwe jetzt läuft es optimal - war fast an der Lösung dran aber nur fast …:smiley:

<?
function ExecuteAction($name, $id, array $slots, $locale)

{
	$roomname = strtolower(@$slots['rooms']);
    //$action = strtolower(@$slots['action']);
   	if($roomname == "wohnzimmer")
   {      
			$status = "aus";
			$grad = number_format(getvalue(11919),1, ",", "");
			$luft = getvalue(29769);
			$format = 'Es sind %1s Grad im Wohnzimmer bei einer Luftfeuchtigkeit von %2s Prozent';
			return AlexaCustomSkillPlainTextResponse::create(sprintf($format, $grad, $luft));  
   }
   return $status;
} 

Hat jemand schon eine Möglichkeit z.B. die Temperatur im Wohnzimmer anzupassen ???

„Alexa sage James er soll die Temperatur im Wohnzimmer auf 23 Grad stellen“
„Alexa, James stelle Wohnzimmer auf 23 Grad“

KlimaTemp stelle {rooms} auf {zahl} Grad

muss man ein Custom Slot für die Zahl erstellen die dann 20 21 22 23 erhält ?? oder muss es zwanzig, einundzwanzig … heißen. Wie geht man mit Nachkommastellen um ? Hat jemand so was schon umgesetzt.

Schönen Sonntag

Nein wo immer möglich sollte man zuerst definierte Slots von Amazon nutzten und erst dann eigene Slots. Für so was wie Zahlen, Uhrzeit oder ähliches gibt es vordefinierte Slots.

Der für Zahlen heisst
AMAZON.NUMBER

Siehe auch Amazon slot type reference

Dann noch für alle…

        {
      "intent": "KlimaTemp",
      "slots": [
        {
          "name": "rooms",
          "type": "rooms"
        },
        {
          "name": "action",
          "type": "action"
        },
        {
          "name": "zahl",
          "type": "AMAZON.NUMBER"
        }
      ]
    }


Sample Utterances
KlimaTemp stelle {rooms} auf {zahl} Grad



function ExecuteAction($name, $id, array $slots, $locale)

{
	$roomname = strtolower(@$slots['rooms']);
    $zahl = strtolower(@$slots['zahl']);
	
	if($roomname == "wohnzimmer" and is_numeric($zahl))
   {      
			$status = "aus";
			HM_writeValueFloat(25905 /*[Hardware\Heizung\Wohnzimmer\Heizungsfühler Wohnzimmer]*/, 'SET_TEMPERATURE', $zahl);
			$format = 'Temperatur wurde auf %s Grad im Wohnzimmer gestellt';
			return AlexaCustomSkillPlainTextResponse::create(sprintf($format, $zahl));  
   }

Im Service Simulator von Amazon müsst ihr allerdings „fünfundzwanzig“ schreiben sonst wird nur ein ? übertragen.

@patami: danke für die wunderbare Arbeit und die hervorragende Anleitung, toll gemacht, geht erste Sahne :slight_smile:

Eine Frage habe ich aber: entweder habe ich es noch nicht richtig durchschaut, oder es ist nicht möglich :confused:

Ist es eigentlich möglich, dass ich dem _question-subject konkret „mit auf den Weg“ gebe, welchen Slot ich mit der Rückantwort meine oder muss ich das symcon-seitig lösen?

als Beispiel:
„Möchtest Du wirklich das gesamte Licht ausschalten?“ Antwort ja/nein
„Möchtest Du in die Einstellungen wechseln?“ Antwort ja/nein

Es kommt bei beiden als subject eben ja oder nein zurück.
Wenn ich nun zwei Slot-Typen mit den Antwortmöglichkeiten ja/nein anlege, weiß ja das Skill nicht, welcher das nun sein soll, oder?

Danke
Marc

Deswegen stellst Du bei der Antwort auch „An den Session Controller“ weiterleiten als Aktion ein.
Im ersten Intent stellst Du die Frage und rufst ContinueSession auf, gibst dabei als Session Controller die ID des ersten Intents an.
Dies wird dann in der Session gespeichert und der YesNo Intent leitet an den in der Session gespeicherten Intent weiter.

In der Demo ruft der GetInformation Intent ContinueSession auf und speichert in der Session Variable _session_controller_id die ID von GetInformation. Der InformationSubjectResponse nimmt die Antwort auf und ruft dann erneut GetInformation auf und tut so, als wäre GetInformation direkt mit dem Slot Value aufgerufen worden.

Das würde auch dann funktionieren, wenn außer GetInformation noch ein weiterer Intent eine Frage mit derselben Antwort stellen würde.