Alexa Custom Skill Modul

Kannst Du kurz etwas zu deinen custom slots:

[ul]
[li]climate
[/li][li]position
[/li][li]device
[/li][/ul]

sagen - versuche das ganze in einen Kontext zu bringen, wie Du diese verwendest. Bei Device würde ich mal raten, wenn sich in einem Raum mehrere schaltbare Geräte (bzw. hier Lampen) befinden. Aber zu climate und Position wäre mal interessant zu erfahren, was Du dort als Beispiel an Einträgen in den Slots verwendest.

Mein du den Intent GetClimate oder ToggleLight?

Kann man wie gesagt halten wie ein Dachdecker ist jedem selbst überlassen wie er das gerne hat.

Beispiel GetClimate sieht so aus:


{
      "intent": "GetClimate",
      "slots": [
        {
          "name": "rooms",
          "type": "rooms"
        },
        {
          "name": "climate",
          "type": "climate"
        }
      ]
    },

Custom Slot Types:
Type:
rooms


wohnzimmer
wohnen
flur
büro
arbeitszimmer
schlafzimmer
schlafen
küche
garten
kinderzimmer
gästezimmer
terasse

Type
climate


Luftfeuchtigkeit
Feuchte
Temperatur
warm
kalt
feucht
Grad

Sample Utterances


GetClimate nach der {climate} vom {rooms}
GetClimate nach der {climate} des {rooms} s
GetClimate wie ist die {climate} im {rooms}
GetClimate wieviel {climate} hat es im {rooms}
GetClimate wie {climate} ist es im {rooms}
GetClimate welche {climate} hat es im {rooms}
GetClimate wie {climate} ist es im {rooms}

Actionscript (passend zu eigenen Bedürfnissen ergänzen)


<?
function ExecuteAction($name, $id, array $slots, $locale, $sessionControllerId)
{
    $roomname = strtolower(@$slots['rooms']);
	$climate = strtolower(@$slots['climate']);
	switch ($roomname) {
        case 'arbeitszimmer':
            if($climate == "grad" || $climate == "kalt" || $climate == "warm" || $climate == "temperatur")  
	        {
				return AlexaCustomSkillPlainTextResponse::create('Es hat momentan '.getRoomTemperature($roomname, $climate).' Grad im '.$roomname);
			}
			elseif($climate == "luftfeuchtigkeit" ||  $climate == "feuchte")
			{
				return AlexaCustomSkillPlainTextResponse::create('Es hat momentan im  '.$roomname.' eine Luftfeuchtigkeit von '.getRoomTemperature($roomname, $climate).' Prozent');
			}
			return AlexaCustomSkillPlainTextResponse::create('Es hat momentan '.getRoomTemperature($roomname).' Grad im '.$roomname);
        case 'bad':
			if($climate == "grad" || $climate == "kalt" || $climate == "warm" || $climate == "temperatur")  
	        {
				return AlexaCustomSkillPlainTextResponse::create('Es hat momentan '.getRoomTemperature($roomname, $climate).' Grad im '.$roomname);
			}
			elseif($climate == "luftfeuchtigkeit" ||  $climate == "feuchte")
			{
				return AlexaCustomSkillPlainTextResponse::create('Es hat momentan im  '.$roomname.' eine Luftfeuchtigkeit von '.getRoomTemperature($roomname, $climate).' Prozent');
			}
            return AlexaCustomSkillPlainTextResponse::create('Es hat momentan '.getRoomTemperature($roomname).' Grad im '.$roomname);
        /*
		case '':
            $slots['_question'] = 'subject';
            return AlexaCustomSkillPlainTextResponse::create(
                'Ich kann Dir die Luffeuchte oder die temperatur eines Raums ansagen. Welche Art von Information interessiert Dich?'
            )->ContinueSession($id, $slots);
		*/	
        default:
            return AlexaCustomSkillPlainTextResponse::create(
                'Ich kenne diesen Raum nicht. Du kannst zum Beispiel nach Wohnzimmer, Arbeitszimmer, Gästezimmer, Kinderzimmer fragen.'
            )->ContinueSession($id, $slots);
    }
}

function getRoomTemperature($roomname, $climate)
{
   if($roomname == "arbeitszimmer")
   {
   		if($climate == "grad" || $climate == "kalt" || $climate == "warm" || $climate == "temperatur") 
		{
			$climate = GetValue(10586 /*[Geräte\Homematic\Räume\Büro\Büro Thermostat Temperatursensor\Temperatur]*/);
		}
		elseif($climate == "luftfeuchtigkeit" ||  $climate == "feuchte")
		{
			$climate = GetValue(25055 /*[Geräte\Homematic\Räume\Büro\Büro Thermostat Temperatursensor\Luftfeuchte]*/);
		}
   }
   elseif($roomname == "bad")
   {
   		if($climate == "grad" || $climate == "kalt" || $climate == "warm" || $climate == "temperatur") 
		{
			$climate = GetValue(45476 /*[Geräte\Homematic\Räume\Bad\Thermostat Bad Temperatursensor\Temperatur]*/);
		}
		elseif($climate == "luftfeuchtigkeit" ||  $climate == "feuchte")
		{
			$climate = GetValue(44621 /*[Geräte\Homematic\Räume\Bad\Thermostat Bad Temperatursensor\Luftfeuchte]*/);
		}
   }
   return $climate;
}

Wird dann z.B. so ausgesprochen

Alexa frage <INVOCATIONNAME> wie warm ist es im Arbeitszimmer

Hallo,

ich hatte zwar schon selber mit eigenen Custom Skills experimentiert, aber mit diesem Modul geht das alles viel besser. Erst mal ein großes Lob an den Entwickler, super Sache!

Ich habe gestern die Demo nachgebaut und mit einem eigenen Intent „SwitchDevice“ erweitert.

Utterances ist sowas wie:


SwitchDevice {device} im {room} {action}
...

und die Custom Slots für {device} {room} {action} sind auch entsprechend definiert.

Auf IPS Seite habe ich ein neues „Alexa Custom Skill Intent“ für „SwitchDevice“ eingerichtet.
In dem zugehörigen Action-Script werte ich die übergebenen Paramter für {device} {room} {action} aus und schalte die entsprechenden Geräte.

Alles super!

Wenn ich bei dem Sprachbefehl z.B. keinen Raum angegeben habe, soll Alexa das sagen und nach dem fehlenden Parameter fragen. Also schicke ich in Falle eines fehlenden Raums:


return AlexaCustomSkillPlainTextResponse::create('In welchem Raum soll ich die Aktion durchführen?')->ContinueSession($id, $slots);

Bis hierhin funktioniert alles. Alexa gibt die Frage wieder und nimmt meine Antwort entgegen.
Die Antwort besteht üblicherweise nur aus einem Wort, in diesem Fall den Namen des Raumes.

Dieses eine Wort wird auf das Intent „InformationSubjectResponse“ aus der Demo gemappt.
Hierfür gilt „An den Session Controller weiterleiten“.

Ich weis nicht, was jetzt im Hintergrund geschieht, aber die Rückantwort landet beim Action-Script von „GetInformation“.
Ich bekomme dann die Antwort aus der Case Schleife:


case '':
            $slots['_question'] = 'subject';
            return AlexaCustomSkillPlainTextResponse::create(
                'Ich kann Dir die Anzahl von Objekten nennen. Welche Art von Objekt interessiert Dich?'
            )->ContinueSession($id, $slots);

Die Anwort auf die Rückfrage sollte aber bei dem Action Script von meinem „SwitchDevice“ landen.

Was mache ich falsch?

Wie sieht denn der Utterance aus?
Diese muss dann auf Deinen Intent verweisen und Du musst eine Instanz in IP-Symcon dafür erstellen.

Morgen!

Ich möchte einfach nur ein Licht schalten!

Intent Schema:

„intent“: „ToggleLight“,
„slots“:
{
„name“: „action“,
„type“: „action“
}

Custom Slot Types angelegt mit:

action

Leselampe

Sample Utterances

ToggleLight {action} an

Leider komme ich nicht weiter was mache ich falsch?

Alexa sage „Demo“ Leselampe an

mfg
maxx

Wie ist die Antwort in der Amazon Deloper Console im Service Simulator
auf

Alexa sage Demo Leselampe an

Wie sieht Dein Aktionskript der Instanz mit dem Intent ToggleLight aus?

Alexa sagt sie kann keinen Intent mit diesem namen finden! ( so in die richtung)
habe jetzt mal alles gelöscht und fange nochmal neu an.

könnte jemand ein skript posten?

mfg

Zur Zeit geht sowieso gerade nix über IP-Symcon Connect das ist gerade tot
Status Symcon

Hier findest Du doch schon eine Idee wie so was aussehen könnte.

genau so habe ich es gemacht!

{
„intent“: „ToggleLight“,
„slots“: [
{
„name“: „rooms“,
„type“: „rooms“
}
,
{
„name“: „position“,
„type“: „position“
},
{
„name“: „device“,
„type“: „device“
},
{
„name“: „action“,
„type“: „action“
}
]

rooms, position, device habe ich gelöscht denn ich will ja nur action leselampe

Warte mal bis IP Symcon Connect wieder läuft dann kann man sich den Response genauer anschauen und den Fehler eingrenzen sonst ist das Stochern im Dunkeln.

Meine Utterances sehen so aus: Die Demo und meine zusätzlicher SwitchDevice Intent.


{
  "intents": [
    {
      "intent": "SwitchDevice",
      "slots": [
        {
          "name": "room",
          "type": "House_Rooms"
        },
   		{
          "name": "device",
          "type": "Switch_Devices" 
        },
   		{
          "name": "action",
          "type": "Switch_Action" 
        }        
      ]
    },
    {
      "intent": "GetInformation",
      "slots": [
        {
          "name": "subject",
          "type": "Information_Subjects"
        }
      ]
    },
    {
      "intent": "InformationSubjectResponse",
      "slots": [
        {
          "name": "subject",
          "type": "Information_Subjects"
        }
      ]
    },
    {
      "intent": "AMAZON.HelpIntent"
    },
    {
      "intent": "AMAZON.CancelIntent"
    }
  ]
}

 
GetInformation {subject} informationen
GetInformation informationen über {subject}
GetInformation informationen

InformationSubjectResponse {subject}

SwitchDevice {device} im {room} {action}

Die möglichen Worte für „House_Rooms“ „Switch_Devices“ und „Switch_Action“ sind natürlich als Custom Slot Type definiert.
Ich habe auch eine „SwitchDevice“ Instanz in IPS erstellt. Funktioniert alles soweit.

Lampe im Wohnzimmer einschalten

wird mit gefüllten slots-Array für {device} {room} {action} an das Action Script meiner „SwitchDevice“ Instanz in IPS übermittelt.

Jetzt soll das Action-Script von „SwitchDevice“ über Alexa eine Rückfrage mit ->ContinueSession($id, $slots)
stellen, weil z.B. ein Parameter fehlt oder die Anfrage nicht eindeutig ausführbar ist.

Die Antwort auf die Rückfrage besteht ja aus einem Wort. In meinem „SwitchDevice“ Intent kann es z.B. ein Gerät, Raum oder eine Aktion sein. Diese Anwort soll jetzt wieder an das „SwitchDevice“ Action-Script gehen.

Bei der Demo Funktioniert das ja auch so. „GetInformation“ antwortet z.B. mit einer Rückfrage.


return AlexaCustomSkillPlainTextResponse::create(
                'Hierzu habe ich keine Informationen. Du kannst Bibliotheken, Module, Instanzen, Skripte oder Variablen sagen.'
            )->ContinueSession($id, $slots);

Die Antwort auf die Rückfrage landet über „InformationSubjectResponse“ wieder bei „GetInformation“.

Ich verstehe momentan aber nicht wie „InformationSubjectResponse“ und „GetInformation“ zusammenhängen.
Wieso landent der Intent „InformationSubjectResponse“ aus der Demo:


   {
      "intent": "InformationSubjectResponse",
      "slots": [
        {
          "name": "subject",
          "type": "Information_Subjects"
        }
      ]
    },

am Ende bei dem Action Script von „GetInformation“

???

Zur allgemeinen Belustigung stelle ich mal den Custom-Command Teil meiner Variante des Skripts auf Seite 1 ein.
Ich will damit zeigen, was alles in einem einzigen Skript ohne weitere Links/Variablen möglich ist.

Ich finde den generellen Ansatz an sich eigentlich gut, da man einfache Kommandos direkt im Skript auswerten und ausführen kann. Leider ist die Erkennung schlecht, seit der LITERAL-Slot abgeschafft wurde. Bei hier vorgeschlagenen Hack kommen die die Kommandos auch in einem Sting, müssen aber in der richtigen Reihenfolge gesprochen werden.

Ich würde gerne mit verschiedenen Slots arbeiten und dort die Keywörter, wie weiter vorne beschrieben, verwenden. Also ein Slot für den Raum, einen für das Gerät, einen für die Aktion, usw.). Das erhöht die Erkennung dramatisch, wie ich schon getestet habe.

Man braucht hier auch nur ein Intent und dann beliebig viele verschiedene Slots. Dann ist die Reihenfolge der Worte egal, man kann Füllwörter benutzen und die Erkennung wird besser.

Soweit ich verstehe ist die andere Lösung hier komplizierter und würde bei der Menge an Geräten die ich steuern möchte einen großen Aufwand bedeuten, oder?

Besteht die Möglichkeit, dass der Author diese Skript noch weiterentwickelt?
Meine beschiedenen php Kenntnisse reichen leider für die Anpassung der Parser Routine nicht aus.

# Lichter ---
if(WordProbe("schlafzimmer schrank|licht|lampe ein|an")){HM_WriteValueBoolean(57357 /*[Hardware\OG\Schlafzimmer\Schrankbeleuchtung]*/, "STATE", True);$resp.="ja meister";}
if(WordProbe("schlafzimmer schrank|licht|lampe aus")){HM_WriteValueBoolean(57357 /*[Hardware\OG\Schlafzimmer\Schrankbeleuchtung]*/, "STATE", False);$resp.="mach ich doch gerne, stefan. viel spass!";}

if(WordProbe("flur licht|lampe|beleuchtung|LED ein|an")){HM_WriteValueBoolean(54211 /*[Hardware\EG\Flur\LichtVorne]*/, "STATE", True);$resp.="dein wunsch ist mir befehl";}
if(WordProbe("flur licht|lampe|beleuchtung|LED aus")){HM_WriteValueBoolean(54211 /*[Hardware\EG\Flur\LichtVorne]*/, "STATE", False);$resp.="geht klar alter";}

if(WordProbe("wohnzimmer|wohnen couch|fluter licht|lampe ein|an")){ZW_SwitchMode(49960 /*[Hardware\EG\Wohnzimmer\LampeCouch]*/, true);$resp.="sehr wohl der herr";}
if(WordProbe("couch|fluter licht|lampe ein|an")){ZW_SwitchMode(49960 /*[Hardware\EG\Wohnzimmer\LampeCouch]*/, true);$resp.="sehr wohl der herr";}
if(WordProbe("wohnzimmer|wohnen couch|fluter licht|lampe aus")){ZW_SwitchMode(49960 /*[Hardware\EG\Wohnzimmer\LampeCouch]*/, false);$resp.="aber nur weil dus bist";}
if(WordProbe("couch|fluter licht|lampe aus")){ZW_SwitchMode(49960 /*[Hardware\EG\Wohnzimmer\LampeCouch]*/, false);$resp.="aber nur weil dus bist";}

if(WordProbe("wohnzimmer|wohnen fenster licht|lampe ein|an")){ZW_SwitchMode(48737 /*[Hardware\EG\Wohnzimmer\LampeFenster]*/, true);$resp.="na logo";}
if(WordProbe("fenster licht|lampe ein|an")){ZW_SwitchMode(48737 /*[Hardware\EG\Wohnzimmer\LampeFenster]*/, true);$resp.="na logo";}
if(WordProbe("wohnzimmer|wohnen fenster licht|lampe aus")){ZW_SwitchMode(48737 /*[Hardware\EG\Wohnzimmer\LampeFenster]*/, false);$resp.="erledigt";}
if(WordProbe("fenster licht|lampe aus")){ZW_SwitchMode(48737 /*[Hardware\EG\Wohnzimmer\LampeFenster]*/, false);$resp.="erledigt";}

if(WordProbe("wohnzimmer|wohnen schrankwand|schrank|regal licht|lampe ein|an")){ZW_SwitchMode(46682 /*[Hardware\EG\Wohnzimmer\LampeSchrankwand]*/, true);$resp.="oki doki";}
if(WordProbe("schrankwand|schrank|regal licht|lampe ein|an")){ZW_SwitchMode(46682 /*[Hardware\EG\Wohnzimmer\LampeSchrankwand]*/, true);$resp.="oki doki";}
if(WordProbe("wohnzimmer|wohnen schrankwand|schrank|regal licht|lampe aus")){ZW_SwitchMode(46682 /*[Hardware\EG\Wohnzimmer\LampeSchrankwand]*/, false);$resp.="joh";}
if(WordProbe("schrankwand|schrank|regal licht|lampe aus")){ZW_SwitchMode(46682 /*[Hardware\EG\Wohnzimmer\LampeSchrankwand]*/, false);$resp.="joh";}

if(WordProbe("wohnzimmer|wohnen tisch|eingang licht|lampe ein|an")){ZW_SwitchMode(22027 /*[Hardware\EG\Wohnzimmer\LampeTisch]*/, true);$resp.="geht klar";}
if(WordProbe("tisch|eingang licht|lampe ein|an")){ZW_SwitchMode(22027 /*[Hardware\EG\Wohnzimmer\LampeTisch]*/, true);$resp.="geht klar";}
if(WordProbe("wohnzimmer|wohnen tisch|eingang licht|lampe aus")){ZW_SwitchMode(22027 /*[Hardware\EG\Wohnzimmer\LampeTisch]*/, false);$resp.="jawohl der herr";}
if(WordProbe("tisch|eingang licht|lampe aus")){ZW_SwitchMode(22027 /*[Hardware\EG\Wohnzimmer\LampeTisch]*/, false);$resp.="jawohl der herr";}

#LED Vorhang:
if(WordProbe("wohnzimmer vorhang licht aus")){ZW_SwitchMode(43810 /*[Hardware\EG\Wohnzimmer\RGB-Fenster\Z-Wave Dimmer (NodeID 007)]*/, false);$resp.="joh L.E.D. aus";}
if(WordProbe("vorhang licht aus")){ZW_SwitchMode(43810 /*[Hardware\EG\Wohnzimmer\RGB-Fenster\Z-Wave Dimmer (NodeID 007)]*/, false);$resp.="joh L.E.D. aus";}
if(WordProbe("vorhang licht weiss|weiß")){ZW_SwitchMode(43810 /*[Hardware\EG\Wohnzimmer\RGB-Fenster\Z-Wave Dimmer (NodeID 007)]*/, false);sleep(3);
		ZW_DimSet(52194 /*[Hardware\EG\Wohnzimmer\RGB-Fenster\Z-Wave Dimmer (NodeID 007)\Z-Wave Dimmer WHITE (NodeID 007) (SubID 5)]*/, 100);$resp.="joh L.E.D. auf weisses licht";}
if(WordProbe("wohnzimmer vorhang licht weiss|weiß")){ZW_SwitchMode(43810 /*[Hardware\EG\Wohnzimmer\RGB-Fenster\Z-Wave Dimmer (NodeID 007)]*/, false);sleep(3);
		ZW_DimSet(52194 /*[Hardware\EG\Wohnzimmer\RGB-Fenster\Z-Wave Dimmer (NodeID 007)\Z-Wave Dimmer WHITE (NodeID 007) (SubID 5)]*/, 100);$resp.="joh L.E.D. auf weisses licht";}
if(WordProbe("vorhang licht kamin")){ZW_ConfigurationSetValue(43810 /*[Hardware\EG\Wohnzimmer\RGB-Fenster\Z-Wave Dimmer (NodeID 007)]*/, 72, 6);$resp.="ohhlahlah Kaminfeuer";}
if(WordProbe("wohnzimmer vorhang licht kamin")){ZW_ConfigurationSetValue(43810 /*[Hardware\EG\Wohnzimmer\RGB-Fenster\Z-Wave Dimmer (NodeID 007)]*/, 72, 6);$resp.="ohhlahlah Kaminfeuer";}
if(WordProbe("vorhang licht sturm|gewitter")){ZW_ConfigurationSetValue(43810 /*[Hardware\EG\Wohnzimmer\RGB-Fenster\Z-Wave Dimmer (NodeID 007)]*/, 72, 7);$resp.="Gewitter Simulation an";}
if(WordProbe("wohnzimmer vorhang licht sturm|gewitter")){ZW_ConfigurationSetValue(43810 /*[Hardware\EG\Wohnzimmer\RGB-Fenster\Z-Wave Dimmer (NodeID 007)]*/, 72, 7);$resp.="Gewitter Simulation an";}
if(WordProbe("vorhang licht regenbogen")){ZW_ConfigurationSetValue(43810 /*[Hardware\EG\Wohnzimmer\RGB-Fenster\Z-Wave Dimmer (NodeID 007)]*/, 72, 8);$resp.="regenbogen Simulation an";}
if(WordProbe("wohnzimmer vorhang licht regenbogen")){ZW_ConfigurationSetValue(43810 /*[Hardware\EG\Wohnzimmer\RGB-Fenster\Z-Wave Dimmer (NodeID 007)]*/, 72, 8);$resp.="regenbogen Simulation an";}
if(WordProbe("vorhang licht aurora")){ZW_ConfigurationSetValue(43810 /*[Hardware\EG\Wohnzimmer\RGB-Fenster\Z-Wave Dimmer (NodeID 007)]*/, 72, 9);$resp.="aurora Simulation an";}
if(WordProbe("wohnzimmer vorhang licht aurora")){ZW_ConfigurationSetValue(43810 /*[Hardware\EG\Wohnzimmer\RGB-Fenster\Z-Wave Dimmer (NodeID 007)]*/, 72, 9);$resp.="aurora Simulation an";}


# Belueftung ----
if(WordProbe("belüftung|lüftung ein|an")){HM_WriteValueBoolean(57946 /*[Hardware\EG\Flur\Lüftung]*/, "STATE", True);$resp.="frischluft kommt";}
if(WordProbe("belüftung|lüftung aus")){HM_WriteValueBoolean(57946 /*[Hardware\EG\Flur\Lüftung]*/, "STATE", False);$resp.="verrückt";}


# Jalousien ----
# Buero:
if(WordProbe("büro|arbeitszimmer rollladen|jalousie zu|schliessen|runter")){HM_WriteValueFloat(26064 /*[Hardware\OG\Büro\Jalousie]*/, "LEVEL", 0.2);$resp.="mach ich doch";}
if(WordProbe("büro|arbeitszimmer rollladen|jalousie auf|öffnen|hoch")){HM_WriteValueFloat(26064 /*[Hardware\OG\Büro\Jalousie]*/, "LEVEL", 1.0);$resp.="jo alter";}
if(WordProbe("büro|arbeitszimmer rollladen|jalousie abschatten|schatten")){HM_WriteValueFloat(26064 /*[Hardware\OG\Büro\Jalousie]*/, "LEVEL", 0.70);$resp.="abschatten, aber nur weil du's bist";}
if(WordProbe("büro|arbeitszimmer rollladen|jalousie stopp|anhalten|halt")){HM_WriteValueBoolean(26064 /*[Hardware\OG\Büro\Jalousie]*/, "STOP", true);$resp.="vollbremsung";}


#Wohnzimmer:
if(WordProbe("wohnzimmer|wohnen rollladen|jalousie links|tür zu|schliessen|runter")){HM_WriteValueFloat(41277 /*[Hardware\EG\Wohnzimmer\JalousieTür]*/, "LEVEL", 0.2);$resp.="mach ich doch";}
if(WordProbe("rollladen|jalousie links|tür zu|schliessen|runter")){HM_WriteValueFloat(41277 /*[Hardware\EG\Wohnzimmer\JalousieTür]*/, "LEVEL", 0.2);$resp.="mach ich doch";}
if(WordProbe("wohnzimmer|wohnen rollladen|jalousie links|tür auf|öffnen|hoch")){HM_WriteValueFloat(41277 /*[Hardware\EG\Wohnzimmer\JalousieTür]*/, "LEVEL", 1.0);$resp.="jo alter";}
if(WordProbe("rollladen|jalousie links|tür auf|öffnen|hoch")){HM_WriteValueFloat(41277 /*[Hardware\EG\Wohnzimmer\JalousieTür]*/, "LEVEL", 1.0);$resp.="jo alter";}
if(WordProbe("wohnzimmer|wohnen rollladen|jalousie links|tür abschatten|schatten")){HM_WriteValueFloat(41277 /*[Hardware\EG\Wohnzimmer\JalousieTür]*/, "LEVEL", 0.80);$resp.="ja ooh meine gebieterin";}
if(WordProbe("rollladen|jalousie links|tür abschatten|schatten")){HM_WriteValueFloat(41277 /*[Hardware\EG\Wohnzimmer\JalousieTür]*/, "LEVEL", 0.80);$resp.="aber nur weil du's bist";}
if(WordProbe("wohnzimmer|wohnen rollladen|jalousie links|tür stop|anhalten|halt")){HM_WriteValueBoolean(41277 /*[Hardware\EG\Wohnzimmer\JalousieTür]*/, "STOP", true);$resp.="das war knapp";}
if(WordProbe("rollladen|jalousie links|tür stopp|anhalten|halt")){HM_WriteValueBoolean(41277 /*[Hardware\EG\Wohnzimmer\JalousieTür]*/, "STOP", true);$resp.="mann war das knapp";}

if(WordProbe("wohnzimmer|wohnen rollladen|jalousie mitte zu|schliessen|runter")){HM_WriteValueFloat(30501 /*[Hardware\EG\Wohnzimmer\JalousieMitte]*/, "LEVEL", 0.2);$resp.="mach ich doch";}
if(WordProbe("rollladen|jalousie mitte zu|schliessen|runter")){HM_WriteValueFloat(30501 /*[Hardware\EG\Wohnzimmer\JalousieMitte]*/, "LEVEL", 0.2);$resp.="mach ich doch";}
if(WordProbe("wohnzimmer|wohnen rollladen|jalousie mitte auf|öffnen|hoch")){HM_WriteValueFloat(30501 /*[Hardware\EG\Wohnzimmer\JalousieMitte]*/, "LEVEL", 1.0);$resp.="jo alter";}
if(WordProbe("rollladen|jalousie mitte auf|öffnen|hoch")){HM_WriteValueFloat(30501 /*[Hardware\EG\Wohnzimmer\JalousieMitte]*/, "LEVEL", 1.0);$resp.="jo alter";}
if(WordProbe("wohnzimmer|wohnen rollladen|jalousie mitte abschatten|schatten")){HM_WriteValueFloat(30501 /*[Hardware\EG\Wohnzimmer\JalousieMitte]*/, "LEVEL", 0.80);$resp.="aber nur weil du's bist";}
if(WordProbe("rollladen|jalousie mitte abschatten|schatten")){HM_WriteValueFloat(30501 /*[Hardware\EG\Wohnzimmer\JalousieMitte]*/, "LEVEL", 0.80);$resp.="aber nur weil du's bist";}
if(WordProbe("wohnzimmer|wohnen rollladen|jalousie mitte stop|anhalten|halt")){HM_WriteValueBoolean(30501 /*[Hardware\EG\Wohnzimmer\JalousieMitte]*/, "STOP", true);$resp.="das war knapp";}
if(WordProbe("rollladen|jalousie mitte stopp|anhalten|halt")){HM_WriteValueBoolean(30501 /*[Hardware\EG\Wohnzimmer\JalousieMitte]*/, "STOP", true);$resp.="mann war das knapp";}

if(WordProbe("wohnzimmer|wohnen rollladen|jalousie rechts zu|schliessen|runter")){HM_WriteValueFloat(54273 /*[Hardware\EG\Wohnzimmer\JalousieRechts]*/, "LEVEL", 0.2);$resp.="mach ich doch";}
if(WordProbe("rollladen|jalousie rechts zu|schliessen|runter")){HM_WriteValueFloat(54273 /*[Hardware\EG\Wohnzimmer\JalousieRechts]*/, "LEVEL", 0.2);$resp.="mach ich doch";}
if(WordProbe("wohnzimmer|wohnen rollladen|jalousie rechts auf|öffnen|hoch")){HM_WriteValueFloat(54273 /*[Hardware\EG\Wohnzimmer\JalousieRechts]*/, "LEVEL", 1.0);$resp.="jo alter";}
if(WordProbe("rollladen|jalousie rechts auf|öffnen|hoch")){HM_WriteValueFloat(54273 /*[Hardware\EG\Wohnzimmer\JalousieRechts]*/, "LEVEL", 1.0);$resp.="jo alter";}
if(WordProbe("wohnzimmer|wohnen rollladen|jalousie rechts abschatten|schatten")){HM_WriteValueFloat(54273 /*[Hardware\EG\Wohnzimmer\JalousieRechts]*/, "LEVEL", 0.80);$resp.="aber nur weil du's bist";}
if(WordProbe("rollladen|jalousie rechts abschatten|schatten")){HM_WriteValueFloat(54273 /*[Hardware\EG\Wohnzimmer\JalousieRechts]*/, "LEVEL", 0.80);$resp.="aber nur weil du's bist";}
if(WordProbe("wohnzimmer|wohnen rollladen|jalousie rechts stop|anhalten|halt")){HM_WriteValueBoolean(54273 /*[Hardware\EG\Wohnzimmer\JalousieRechts]*/, "STOP", true);$resp.="das war knapp";}
if(WordProbe("rollladen|jalousie rechts stopp|anhalten|halt")){HM_WriteValueBoolean(54273 /*[Hardware\EG\Wohnzimmer\JalousieRechts]*/, "STOP", true);$resp.="mann war das knapp";}

if(WordProbe("wohnzimmer|wohnen rollladen|jalousien alle zu|schliessen|runter")){HM_WriteValueFloat(54273 /*[Hardware\EG\Wohnzimmer\JalousieRechts]*/, "LEVEL", 0.2);
																				HM_WriteValueFloat(41277 /*[Hardware\EG\Wohnzimmer\JalousieTür]*/, "LEVEL", 0.2);
																				HM_WriteValueFloat(30501 /*[Hardware\EG\Wohnzimmer\JalousieMitte]*/, "LEVEL", 0.2);
																				$resp.="sehr wohl eure durchlaucht";}
if(WordProbe("rollladen|jalousien alle zu|schliessen|runter"))					{HM_WriteValueFloat(54273 /*[Hardware\EG\Wohnzimmer\JalousieRechts]*/, "LEVEL", 0.2);
																				HM_WriteValueFloat(41277 /*[Hardware\EG\Wohnzimmer\JalousieTür]*/, "LEVEL", 0.2);
																				HM_WriteValueFloat(30501 /*[Hardware\EG\Wohnzimmer\JalousieMitte]*/, "LEVEL", 0.2);
																				$resp.="das ist ja schwerst arbeit";}
if(WordProbe("wohnzimmer|wohnen rollladen|jalousien alle auf|öffnen|hoch"))		{HM_WriteValueFloat(54273 /*[Hardware\EG\Wohnzimmer\JalousieRechts]*/, "LEVEL", 1.0);
																				HM_WriteValueFloat(41277 /*[Hardware\EG\Wohnzimmer\JalousieTür]*/, "LEVEL", 1.0);
																				HM_WriteValueFloat(30501 /*[Hardware\EG\Wohnzimmer\JalousieMitte]*/, "LEVEL", 1.0);
																				$resp.="Alexa sagt: es werde licht";}
if(WordProbe("rollladen|jalousien alle auf|öffnen|hoch"))						{HM_WriteValueFloat(54273 /*[Hardware\EG\Wohnzimmer\JalousieRechts]*/, "LEVEL", 1.0);
																				HM_WriteValueFloat(41277 /*[Hardware\EG\Wohnzimmer\JalousieTür]*/, "LEVEL", 1.0);
																				HM_WriteValueFloat(30501 /*[Hardware\EG\Wohnzimmer\JalousieMitte]*/, "LEVEL", 1.0);
																				$resp.="Alexa sagt: es werde licht";}
if(WordProbe("wohnzimmer|wohnen rollladen|jalousien alle abschatten|schatten")){HM_WriteValueFloat(54273 /*[Hardware\EG\Wohnzimmer\JalousieRechts]*/, "LEVEL", 0.8);
																				HM_WriteValueFloat(41277 /*[Hardware\EG\Wohnzimmer\JalousieTür]*/, "LEVEL", 0.8);
																				HM_WriteValueFloat(30501 /*[Hardware\EG\Wohnzimmer\JalousieMitte]*/, "LEVEL", 0.8);
																				$resp.="besser so?";}
if(WordProbe("rollladen|jalousien alle abschatten|schatten"))					{HM_WriteValueFloat(54273 /*[Hardware\EG\Wohnzimmer\JalousieRechts]*/, "LEVEL", 0.8);
																				HM_WriteValueFloat(41277 /*[Hardware\EG\Wohnzimmer\JalousieTür]*/, "LEVEL", 0.8);
																				HM_WriteValueFloat(30501 /*[Hardware\EG\Wohnzimmer\JalousieMitte]*/, "LEVEL", 0.8);
																				$resp.="besser so?";}
if(WordProbe("wohnzimmer|wohnen rollladen|jalousien alle stop|anhalten|halt"))	{HM_WriteValueBoolean(54273 /*[Hardware\EG\Wohnzimmer\JalousieRechts]*/, "STOP", true);
																				HM_WriteValueBoolean(41277 /*[Hardware\EG\Wohnzimmer\JalousieTür]*/, "STOP", true);
																				HM_WriteValueBoolean(30501 /*[Hardware\EG\Wohnzimmer\JalousieMitte]*/, "STOP", true);
																				$resp.="puuh das war knapp";}
if(WordProbe("rollladen|jalousien alle stopp|anhalten|halt"))					{HM_WriteValueBoolean(54273 /*[Hardware\EG\Wohnzimmer\JalousieRechts]*/, "STOP", true);
																				HM_WriteValueBoolean(41277 /*[Hardware\EG\Wohnzimmer\JalousieTür]*/, "STOP", true);
																				HM_WriteValueBoolean(30501 /*[Hardware\EG\Wohnzimmer\JalousieMitte]*/, "STOP", true);
																				$resp.="puuh das war knapp";}

# Schlafzimmer:
if(WordProbe("schlafzimmer rollladen|jalousie rechts zu|schliessen|runter")){HM_WriteValueFloat(31137 /*[Hardware\OG\Schlafzimmer\JalousieRechts]*/, "LEVEL", 0.2);$resp.="mach ich doch";}
if(WordProbe("schlafzimmer rollladen|jalousie rechts auf|öffnen|hoch")){HM_WriteValueFloat(31137 /*[Hardware\OG\Schlafzimmer\JalousieRechts]*/, "LEVEL", 1.0);$resp.="jo alter";}
if(WordProbe("schlafzimmer rollladen|jalousie rechts abschatten|schatten")){HM_WriteValueFloat(31137 /*[Hardware\OG\Schlafzimmer\JalousieRechts]*/, "LEVEL", 0.75);$resp.="aber nur weil du's bist";}
if(WordProbe("schlafzimmer rollladen|jalousie rechts stop|anhalten|halt")){HM_WriteValueBoolean(31137 /*[Hardware\OG\Schlafzimmer\JalousieRechts]*/, "STOP", true);$resp.="das war knapp";}

if(WordProbe("schlafzimmer rollladen|jalousie links zu|schliessen|runter")){HM_WriteValueFloat(22866 /*[Hardware\OG\Schlafzimmer\JalousieLinks]*/, "LEVEL", 0.2);$resp.="mach ich doch";}
if(WordProbe("schlafzimmer rollladen|jalousie links auf|öffnen|hoch")){HM_WriteValueFloat(22866 /*[Hardware\OG\Schlafzimmer\JalousieLinks]*/, "LEVEL", 1.0);$resp.="jo alter";}
if(WordProbe("schlafzimmer rollladen|jalousie links abschatten|schatten")){HM_WriteValueFloat(22866 /*[Hardware\OG\Schlafzimmer\JalousieLinks]*/, "LEVEL", 0.75);$resp.="aber nur weil du's bist";}
if(WordProbe("schlafzimmer rollladen|jalousie links stop|anhalten|halt")){HM_WriteValueBoolean(22866 /*[Hardware\OG\Schlafzimmer\JalousieLinks]*/, "STOP", true);$resp.="das war knapp";}

if(WordProbe("schlafzimmer rollladen|jalousien alle|beide zu|schliessen|runter")){HM_WriteValueFloat(22866 /*[Hardware\OG\Schlafzimmer\JalousieLinks]*/, "LEVEL", 0.2);
																				HM_WriteValueFloat(31137 /*[Hardware\OG\Schlafzimmer\JalousieRechts]*/, "LEVEL", 0.2);
																				$resp.="sehr wohl eure durchlaucht";}
if(WordProbe("schlafzimmer rollladen|jalousien alle|beide auf|öffnen|hoch"))	{HM_WriteValueFloat(22866 /*[Hardware\OG\Schlafzimmer\JalousieLinks]*/, "LEVEL", 1.0);
																				HM_WriteValueFloat(31137 /*[Hardware\OG\Schlafzimmer\JalousieRechts]*/, "LEVEL", 1.0);
																				$resp.="Alexa sagt: ok beide auf";}
if(WordProbe("schlafzimmer rollladen|jalousien alle|beide abschatten|schatten")){HM_WriteValueFloat(22866 /*[Hardware\OG\Schlafzimmer\JalousieLinks]*/, "LEVEL", 0.75);
																				HM_WriteValueFloat(31137 /*[Hardware\OG\Schlafzimmer\JalousieRechts]*/, "LEVEL", 0.75);
																				$resp.="besser so?";}
if(WordProbe("schlafzimmer rollladen|jalousien alle|beide stop|anhalten|halt"))	{HM_WriteValueBoolean(22866 /*[Hardware\OG\Schlafzimmer\JalousieLinks]*/, "STOP", true);
																				HM_WriteValueBoolean(31137 /*[Hardware\OG\Schlafzimmer\JalousieRechts]*/, "STOP", true);
																				$resp.="puuh das war knapp";}


# Wetter ----
if(WordProbe("temperatur draußen|garten|außen")){$resp.= "Die Aussentemperatur beträgt ".GetValueFormatted(38564 /*[EigeneProgramme\Netatmo_Community\70:ee:50:20:dc:c6\Garten\Temperature]*/);}
if(WordProbe("luftfeuchtigkeit|feuchte|luftfeuchte draußen|garten|außen")){$resp.= "Die luftfeuchte aussen beträgt ".GetValueFormatted(21619 /*[EigeneProgramme\Netatmo_Community\70:ee:50:20:dc:c6\Garten\Humidity]*/);}
if(WordProbe("temperatur innen|drinnen|wohnzimmer")){$resp.= "Die innentemperatur lautet kuschelige ".GetValueFormatted(30618 /*[EigeneProgramme\Netatmo_Community\70:ee:50:20:dc:c6\Temperature]*/);}
if(WordProbe("luftfeuchtigkeit|feuchte|luftfeuchte innen|drinnen|wohnzimmer")){$resp.= "Die luftfeuchte im wohnzimmer beträgt ".GetValueFormatted(34683 /*[EigeneProgramme\Netatmo_Community\70:ee:50:20:dc:c6\Humidity]*/);}
if(WordProbe("luftdruck")){$resp.= "der luftdruck beträgt ".GetValueFormatted(44088 /*[EigeneProgramme\Netatmo_Community\70:ee:50:20:dc:c6\Pressure]*/).". Trend ".GetValueString(41216 /*[EigeneProgramme\Netatmo_Community\70:ee:50:20:dc:c6\pressure_trend]*/);}

# WLAN ----
if(WordProbe("gäste wehlan an|ein")){IPS_RunScriptEx(40105 /*[FritzBox Project\Scripte\Aktions & Auslese-Script WLAN]*/,array('SENDER'=>'RequestAction','IDENT'=>'FB_WLAN_G','VALUE'=>true));$resp.="jetzt können die schnorrer auf unsere kosten surfen";}
if(WordProbe("gäste wehlan aus")){IPS_RunScriptEx(40105 /*[FritzBox Project\Scripte\Aktions & Auslese-Script WLAN]*/,array('SENDER'=>'RequestAction','IDENT'=>'FB_WLAN_G','VALUE'=>false));$resp.="das darfst du nicht tun, Dave";}

# Other ----
if(WordProbe("mülltermine vorlesen")){$resp.= "Hier die nächsten Mülltermine: ".GetValueString(37187 /*[EigeneProgramme\Muellkalender\MuelltermineText]*/);}

if(WordProbe("diskstation aufwecken|wecken|starten")){IPS_RunScript(58117 /*[EigeneProgramme\WakeOnLan]*/);$resp.="gibt mir eine minute";}

if(WordProbe("momentane|momentanen stromerzeugung")){$resp.= "Die Solaranlage erzeugt zur Zeit eine Leistung von ".GetValueFormatted(33254 /*[EigeneProgramme\Solar\SymoPowerNow]*/);}
if(WordProbe("momentaner|momentane|momentanen stromverbrauch")){$resp.= "Der momentane Stromverbrauch beträgt ".GetValueFormatted(58516 /*[EigeneProgramme\Solar\SymoMeterPowerNow]*/);}

if(WordProbe("verschluss status")){$resp.= "Dachfenster vorne: ".GetValueFormatted(31142 /*[Hardware\DG\Studio\DachfensterVorne\STATE]*/).". ".
									"Dachfenster hinten: ".GetValueFormatted(51933 /*[Hardware\DG\Studio\DachfensterHinten\STATE]*/).". ".
									"Terassentür: ".GetValueFormatted(54782 /*[Hardware\EG\Wohnzimmer\Terassentür\STATE]*/).". ";}

if(WordProbe("gewicht stefan")){$resp.= "Stefan wiegt zur zeit ".GetValueFormatted(11560 /*[Program\IPSLibrary\data\modules\Informationen\WithingsInfo\STE\WAAGE\Gewicht]*/).". der fette sack!";}


Sorry MOD das gehört nicht hier her. Habe Fieber und bin verwirrt.
Bitte in den anderen Thread umhängen!

Fonzo schrieb:

Kann man wie gesagt halten wie ein Dachdecker ist jedem selbst überlassen wie er das gerne hat.

Actionscript (passend zu eigenen Bedürfnissen ergänzen)


<?
function ExecuteAction($name, $id, array $slots, $locale, $sessionControllerId)
{
    $roomname = strtolower(@$slots['rooms']);
	$climate = strtolower(@$slots['climate']);
	switch ($roomname) {
        case 'arbeitszimmer':
            if($climate == "grad" || $climate == "kalt" || $climate == "warm" || $climate == "temperatur")  
	        {
				return AlexaCustomSkillPlainTextResponse::create('Es hat momentan '.getRoomTemperature($roomname, $climate).' Grad im '.$roomname);
			}
			elseif($climate == "luftfeuchtigkeit" ||  $climate == "feuchte")
			{
				return AlexaCustomSkillPlainTextResponse::create('Es hat momentan im  '.$roomname.' eine 

Das Aktionskript ist ja cool, aber es wäre doch zumindest für die Standardsachen einfacher eine Liste mit Schlüsselworten zu übergeben und wenn die in irgendeiner Reihenfolge in den Slots alle vorkommen, dann einen Befehl aufzuführen.

Etwa so, wie das momentan die Wordprobe aus den ersten Skript mach Routine macht?

Man müsste dann an einer Stelle die Slotnamen und Anzahl definieren (zB raum, device, subdevice, action) und dann die if Anweisung wie folgt umstricken:


if(WordProbeV2("flur|diele", "licht|lampe|beleuchtung|LED", "", "aus")){HM_WriteValueBoolean(54211 /*[Hardware\EG\Flur\LichtVorne]*/, "STATE", False);$resp.="geht klar alter";}

Der Befehl soll in diesem Fall ausgeführt werden, wenn alles matched, bis auf subdevice was in diesem Beispiel leer bleiben kann.

Ich habe noch nicht ganz was Du genau willst? Du kannst dir doch die Schlüsselwörter die du haben willst selber in Slots frei definierten. In welcher Reihenfolge die Slots übergeben werden spielt ja überhaupt keine Rolle. Du must nur genügend Utterances vorgeben. Vielleicht kannst Du ja mal ein Beispiel geben was Dir konkret fehlt?

Der Ansatz ist zwar simpel, entspricht aber nicht dem wie sich Amazon die Spracherkennung vorstellt und funktioniert. Das einzige was Dir das erspart ist es passende Utteraces zu definieren, weil Du sagst was Du willst. Die Spracherkennung wird aber mit zunehmender Länge schlechter da der Spracherkennung der Vergleichsblock fehlt. Außerdem kannst Du so keine richtige AUI aufbauen mit unterschiedlichen Antworten weil immer nur ein Intent aufgerufen wird.

Amazon empfiehlt grundsätzlich wo möglich Built in Intents zu nutzen da diese was die Spracherkennung anbelangt weiterentwickelt werden. Als zweites dann Custom Slots. Bei dem Ansatz mit Wordprobe wird die Spracherkennung niemals besser weil Du Dir irgendwas übergeben lässt und für Amazon noch nicht mal zu vergleichen ist ob das was erkannt wurde tatsächlich einem Mustersatz entspricht.

Das machst Du z.B. so

Intent
ToggleLight

Custom Slot

rooms


flur
diele

device


licht
lampe
beleuchtung
led

action


ein
aus

Utterances


ToggleLight schalte im {rooms} das {device} {action}
ToggleLight schalte {device} im {rooms} {action}
ToggleLight das {device} im {rooms} {action} schalten
ToggleLight  im {rooms} das {device} {action} schalten

usw.

Das hat mehrere Gründe:

  1. Der WebHook füllt die von Alexa übergebenen Slots mit ggf. in der Session gemerkten Slots auf.
  2. Wenn Du die Session mit ContinueSession fortführst, werden die Slots in der Session gespeichert, außerdem die ID des Intents, der die Session öffnet (der Session Controller, in Deinem Fall GetInformation).
  3. Somit bekommen Folge-Intents in der Session immer die eigenen Slots sowie die Slots der vorherigen Intents in der Session (sofern sie vom aktuellen Slots nicht überschrieben werden).
  4. Der InformationSubjectResponse Intent ist mit der Aktion „An den Session Controller weiterleiten“ konfiguriert. Er macht somit nichts anderes, als einfach nur den Session Controller (also GetInformation) anstatt sich selbst ausführen.
  5. Über die Session bekommt dann GetInformation den Slot Subject und er kann was tun.

Das geht auch mit mehreren Slots.
Du müsstest in GetInformation nur prüfen, ob der erste Slot fehlt. Frage zurückgeben, Session öffnen.
Über einen anderen Intent das Antwort-Wort einsammeln, es landet in der Session und wird über den Forward an den Session Controller an GetInformation übergeben.
Der erste Slot ist nun da. Jetzt prüfen, ob der zweite Slot fehlt. Frage zurückgeben. Session bleibt offen.
Über einend ritten Intent die Antwort einsammeln, diese landet mit dem ersten Slot zusammen in der Session und geht wieder an GetInformation.
Nun sind beide Slots da.

@alle, ich find’s toll, dass ihr so rege testet.
Leider bin ich noch bis zum Wochenende arbeitsmäßig sehr eingebunden.
Ich versuche, alle eure Fragen am Wochenende zu beantworten, außerdem die erweiterte Version 3.1 zu releasen und noch mehr Beispiele hinzuzufügen.
Stay tuned :slight_smile:

@patami

Und ich finde es toll gleich mit so einem Projekt hier einzusteigen und sich auch im Support so reinzuhängen.

Hi Fonzo,

Ich meine übriges dieses Skript hier:
https://www.symcon.de/forum/threads/32448-Info-Alexa-Amazon-Echo-Integration?highlight=wordprobe

Das Problem ist das der Parser hier nicht mit verschiedenen Slots klar kommt. Das Auswerteskript ist hier so schönen einfach, kann aber nur einen einzigen Slot umgehen.

Ich finde die verschachtelten Case-Anweisungen, wie sie hier vorgeschlagen werden, ja generell OK, aber man erzeugt damit aber ziemlich mehr redundanten Code.

Ich dachte an ein Skript in dem man die Slots (und deren Anzahl) selbst definiert und dann die Befehlswörter auf die getriggert wird in einer Art Matrix übergibt die noch zusätzlich ein Feld für Aktion(en) und Response hat.

Die if(WordProbe… Anweisung des Skripts aus dem anderen Thread ist schon fast so einfach wie eine Matrix. Man übergibt die Wörter in einem String, dann folgt eine (oder eine Kette) von Aktionen, dann noch ein Antwortsatz für Alex. Fertig.

Eigentlich kann man dazu wahrscheinlich sogar dieses Modul hier verwenden, man müsste nur ein einfacheres Auswerte-Skript dazu schreiben.

Ich finde die Anleitung des Themenerstellers sehr gut, leider geht er auf den Auswertepart nur bedingt ein.