Amazon Echo an Symcon anbinden inklusive Proxy

Ja,… Danke es macht wirklich Spaß!
Funktioniert soweit auch recht stabil und sogar meine Frau nutzt inzwischen die Echos nicht nur für Musik und Info!

Du hast sicher prinzipiell recht, dass muss auch jeder für sich entscheiden!
Aber wenn Du Dich technisch nicht komplett abschotten möchtest, wirst Du um Cloud basiernde Systeme immer weniger drum herum kommen. Habe ich mit Onstar inzwischen sogar im Auto…
Und mal ehrlich und dies nur als Gedankenspiel da ich als Firmwarentwickler (Hardware Steuerungstechnik) auch über die eine oder andere Sache „nachdenke“,… muss Dir dein Handy in jedem Fall Visualisieren was es gerade macht?

Aber nun zurück zum Thema, dass andere gern in einem neuen Thread.

Gruß André

Hallo 1007,

bei der Anfrage „Alexa sag demhaus schalte drucker ein“ (gestellt über die Testumgebung von Amazon (also per Texteingabe)) bekomme ich folgende Meldung:

In IPS kommen aber Daten an!

Mache ich die gleiche Anfrage per Sprache über Alexa antwortet sie: „Bei der Kommunikation mit dem angeforderten Skill ist ein Problem aufgetreten“. Gleichzeitig kann ich im AmazonEcho.log erkennen das die USER ID falsch ist. Hier wird auch tatsächlich eine andere USER ID genutzt wie über die Testkonsole von Amazon.

Axel

Ich habe jetzt die USER ID aus dem AmazonEcho.log genommen.
Jetzt kommt der gesprochene Text in IP Symcon an. Leider immer noch mit der gesprochen Fehlermeldung.

In der Variable „Response“ gibt es folgende Meldung: „Ich habe : schalte den drucker an nicht verstanden“

Axel

Hi,

habe gerade meinen Echo bekommen aber habe Fragen bei der Einrichtung.

  1. Bei Einrichten des Developer Accounts kann ich bei der Verwendung von Deutsch als Sprache „type“: „LITERAL“ beim Intent nicht verwenden … es kommt ein Fehler das es nicht erlaubt ist. Bei Englisch geht es … was muss man bei Deutsch wählen?

  2. Jetzt habe ich die eine Kategorie in der Management Console angelegt (Echo) und dort soll man die Script reinkopieren und dann umkopieren. Das ist mir neu … wenn ich sie auf OS Ebene kopiere, dann heissen sie auch „index.php“ etc. aber wenn ich sie via Console anlege, dann heissen sie so wie scripte eben heissen (Objekt ID.ips.php). Wie kann kann ich via Console umbenennen - habe ich noch nie gemacht, oder muss ich dann alles ausserhalb der Console bearbeiten?

Hallo,

in der Console kannst Du im Script oben einen Button verwenden zum umbenennen.
Es ist der Button mit dem Stift drauf

Zur ersten Frage kann ich nichts sagen, bei mir hat es so geklappt, wie es im ersten Thread beschrieben ist.
Wichtig ist noch, dass die Scripte und die Variablen in verschiedenen Kategorien sind, wenn Du 1007s Sichte nimmst.

Gruß
Christian

Dave … was verwendest du denn für Intends und Utterances? Ich kann genau wegen dem oben in Deutsch nichts nutzen :confused: - kann jemand mal die aktuell im deutschen funktionierenden posten.

Danke

Enno

Ich habe jetzt mal die Script von 1007 verwendet und irgendwie kann ich sie untereinander nicht aufrufen.

Wenn ich das richtig sehe wird als erstes AmazonEcho.ips.php aufgerufen

Das sollte dann die anderen Scripte via include callen, also AmazonEchoConfig.ips.php

Bei mir klappt das aber nicht :confused: - Fatal error: Call to undefined function IPSUtils_Include() in /var/lib/symcon/scripts/AmazonEcho.ips.php on line 2

EDIT … Problem ist nicht das die Scripte nicht aufgerufen werden, sondern

$parentDataID = IPSUtil_ObjectIDByPath(„Program.IPSLibrary.data.privat.AmazonEcho“); in AmazonEchoConfig.ips.php

EDIT 2 … wieder einen Schritt weiter - die IPSLibrary hat gefehlt. Die braucht man zwingen, wobei mir jetzt unklar ist, wie es jetzt weiter geht … Die Meldung unten sagt ja das er privat.AmazonEcho nicht finden kann, aber wo muss die hin und welche der Files von 1007 ist es?!?

Fatal error: Uncaught exception ‚IPSUtilException‘ with message ‚„privat“ could NOT be found while searching for Path Program.IPSLibrary.data.privat.AmazonEcho‘ in /var/lib/symcon/scripts/IPSLibrary/app/core/IPSUtils/IPSUtils.inc.php:70
Stack trace:
#0 /var/lib/symcon/scripts/AmazonEchoConfig.ips.php(21): IPSUtil_ObjectIDByPath(‚Program.IPSLibr…‘)
#1 {main}
thrown in /var/lib/symcon/scripts/IPSLibrary/app/core/IPSUtils/IPSUtils.inc.php on line 70
Abort Processing during Fatal-Error: Uncaught exception ‚IPSUtilException‘ with message ‚„privat“ could NOT be found while searching for Path Program.IPSLibrary.data.privat.AmazonEcho‘ in /var/lib/symcon/scripts/IPSLibrary/app/core/IPSUtils/IPSUtils.inc.php:70
Stack trace:
#0 /var/lib/symcon/scripts/AmazonEchoConfig.ips.php(21): IPSUtil_ObjectIDByPath(‚Program.IPSLibr…‘)
#1 {main}
thrown
Error in Script /var/lib/symcon/scripts/IPSLibrary/app/core/IPSUtils/IPSUtils.inc.php on Line 70

Edit 3: Man musste in der IPS Library 2 Kategorien anlagen … da steht zwar nichts drin, aber der Fehler ist weg?!?

3.PNG

Sorry für all den Spam und die Updates, aber diese Installation ist nicht so ganz einfach, auch wenn ich mich durch alles Posts suche.

Sollte ich das mal zu laufen bekommen, fassen ich gerne einmal alles Schritte in einer Anleitung zusammen, aber ich stehe auf dem Schlauch.

Du musst auf jeden Fall die IPSLibrary von Brownson installiert haben.

Die habe ich drauf … Problem ist, dass er die Amazon.Echo Komponente nicht findet. Muss man die noch referenzieren?

OK … Fehler ist wie in #227 durch hinzufügen von 2 Kategorien behoben. #227

Mal sehen wie es jetzt weiter geht. Also einfach ist das nicht so wirklich oder ich stelle mich doof an (beides möglich :banghead:)

Hi an alle, die ein Problem mit dem LITERAL-Type bei der Deutschen Version haben.

Intent Schema:
{ „intents“: [
{ „intent“: „DoCommand“,
„slots“: [ {
„name“: „command“,
„type“: „symcon“ } ] } ] }

Utterance:
DoCommand {command}

Ihr müsst einen Custom Slot Type erstellen. Ich habe ihn symcon genannt ( „type“: „symcon“) und als Werte
schalte | schalte ein | schalte aus | status
eingetragen. Jedes Wort auf eine einzelne Zeile. Scheint nicht wirklich von Bedeutung zu sein was in der Liste drin steht.

Zumindest ist dann aber der Fehler weg.

Gruss
Michael

Hi,

ich habe mir ein neues Custom Skill gebaut, die Mustersätze sind auf „unseren“ wortgebrauch zurecht geschnitten, ich denke das das Skill nicht wirklich für die allgemeinheit nutzbar ist… in richtung IPS habe ich ein Modul was die Intents/Slots auswertet und dementsprechend handelt…
gerade arbeite ich an einem SmartHome Skill über das Symcon OAuth, lampen schalten geht schon :smiley: weiter bin ich noch nicht, da ich mich gerade mit einem nervigen HomeMatic problem beschäftige

Grüsse
Dave

Hi Dave,

an sowas wäre ich interessiert … ich kämpfe auch gerade mit Alexa und ja es geht, aber zuverlässig und flexibel ist noch anders (was auch an mir liegen kann).

Aktuell verwende ich die Standard Scripte (also nicht die von 1007, da ich die IPS Lib. eigentlich nicht nutzen möchte). Grundproblem ist, dass selbst einfach Sätze wie: Alex sage haus

  • schalte lampe
  • fahre rollo

Schon nicht super zuverlässig erkannt werden. „Schalte lampe“ geht besser als „fahre rollo“, bei Rollladen kamen gar keine Treffer.

Ich vermute das man hier wirklich mit einer gewissen Fuzzyness arbeiten muss, da Alexa vor allem mit ihr nicht bekannten Worten Probleme hat (und ich spreche SEHR deutlich bei den Tests). Vermutlich ist es genau das andem Amazon gerade auch arbeitet. Generell nutzbar ist es noch nicht so richtig oder nur mit Abstrichen - das Potential ist aber sehr groß, aber von „Alex fahre den Rollo vorne rechts hoch“ sind wir noch eine ganze Ecke entfernt (oder hat jemand das schon am laufen?!?).

Enno

Hallo an alle

Ich habe das Skript von 1007 umgeschrieben, um das Verständnis zu erleichtern und alle IPSLibrary-Elemente entfernt.
Das Skript läuft also so wie es ist ohne Abhängigkeiten.

Erstellt einen Ordner und erstellt ein Skript (Inhalt weiter unten). Es braucht noch 3 Variabeln: Alle String:
-CurrentTask (Zum Beispiel: GetPassword, damit das Skript weiss, wo es weitergeht,)
-Response (Beinhaltet die Antwort)
-SessionEnd (Session beenden oder nicht)

Ich habe einige request-Typen unterschieden:
-Spezielle Tasks,d ie vordefiniert sind, wie etwa die Abfrage eines Passwortes
-Fixe Befehle: Definierte Befehle, die nicht geparst werden müssen, wie „Abbrechen“ oder einfache Befehle, wie „schalte Fernseher“
-Geparste Befehle mit Wortsuche

Das Parsing ist lausig und würde mehr intelligenz ertragen, aber mein PHP ist nicht der Hammer.
Nehmt es als Einstiegshilfe. Feedback ist willkommen.

Dank an alle, deren Arbeit direkt oder indirekt Eingeflossen ist

<?

GLOBAL $applicationIdValidation;
GLOBAL $userIdValidation;           
GLOBAL $echoServiceDomain;         
GLOBAL $debug;
GLOBAL $logging;
GLOBAL $responseOID;
GLOBAL $sessionEndOID;
GLOBAL $currentTaskOID;

$debug   = true;
$logging = true;

$responseOID = 43612 /*[Kommunikation\Amazon Echo\Response]*/;
$sessionEndOID = 56359 /*[Kommunikation\Amazon Echo\SessionEnd]*/;
$currentTaskOID = 31995 /*[Kommunikation\Amazon Echo\CurrentTask]*/;

 // Debugging anschalten? --> Log wird mit Script ID im Log Ordner geschrieben.
 $applicationIdValidation    = 'amzn1.ask.skill.XXXXXXXX'; // aus dem log herausfinden
 $userIdValidation           = 'amzn1.ask.account.XXXXXXXX; //aus dem log herausfinden
 $echoServiceDomain          = 'echo-api.amazon.com';


// Capture Amazon's POST JSON request:
$jsonRequest    = file_get_contents('php://input');
$data           = json_decode($jsonRequest, true);

$sessionId          = @$data['session']['sessionId'];
$applicationId      = @$data['session']['application']['applicationId'];
$userId             = @$data['session']['user']['userId'];
$newSession         = @$data['session']['new'];
$requestTimestamp   = @$data['request']['timestamp'];
$command            = @$data['request']['intent']['slots']['command']['value'];
$requestType        = @$data['request']['type'];

$command            = strtolower($command); // For the GUI

Ips_LogMessage('ECHO',$command);

if( ($applicationId != $applicationIdValidation) || ($userId != $userIdValidation) ){
	IPS_LogMessage('ECHO','Anwendungs- oder UserID-Fehler');
    AnswerAmazon('Fehler bei der Anwendungs- oder User ID',1);
    return;
}

//Alexas Anfrage ist ein HTTP POST
if ( $_SERVER['REQUEST_METHOD'] == 'GET' )
	{
	AnswerAmazon('Ein Fehler ist aufgetreten',true);
	IPS_LogMessage('ECHO','GET-Request-Fehler');
	}

// Fehler wenn Anfrage aelter als 60 Sekunden
$localTime = time();
$alexaTime = strtotime($requestTimestamp);
if ($localTime - $alexaTime > 60){
    IPS_LogMessage('ECHO','Zeitstempelfehler : Local - ' . date("d.m.Y H:i",$localTime) . ' Alexa - ' . date("d.m.Y H:i",$alexaTime));
	}

// Neue Session ?
if ( $newSession == 'true' ){
	IPS_LogMessage('ECHO','New session');
	SetValueString($sessionEndOID,0);
	SetValueString($responseOID,'Ich habe Deine Anfrage nicht verstanden.');
	SetValueString($currentTaskOID,'');
}
	

#@list($script,$args) = explode(" ", $command);
$spokenwords = explode(" ", $command);

//Handle special tasks
if (GetValueString($currentTaskOID)=='PasswordVerification'){
if ((in_array("sieben", $spokenwords )==true) && (in_array("neun", $spokenwords )==true)){
	 SetValueString($responseOID,'Die Alarmanlage wird ausgeschaltet.');
	 SetValueString($sessionEndOID,1);
	 SetValueString($currentTaskOID,'');
	 IPS_RunScriptWait(29053 /*[Sicherheit\Steuerung\Alarm - Aus]*/);
	 
	 } else {
	 SetValueString($responseOID,'Das Passwort ist ungültig.');
	 SetValueString($sessionEndOID,0);
	 
	 }
}

//Handle fix commands
  if ($command =="abbrechen") {
	 SetValueString($responseOID,'Abgebrochen.');
	 SetValueString($sessionEndOID,1);  
	 unset($spokenword);
	 SetValueString($currentTaskOID,'');
  }
  if ($command=='zeige überwachungskamera'){
     SetValueString($responseOID,'Zeige Überwachungskamera.'); 
	 SetValueString($sessionEndOID,1);  
	 unset($spokenword);
	 IPS_RunScriptWait(12927 /*[Server\Fernseher\Show Surveillance]*/);
	 }
  if ($command=='zeige live t. v.'){ 
     SetValueString($responseOID,'Zeige Live T.V.'); 
	 SetValueString($sessionEndOID,1);  
	 unset($spokenword);
	 IPS_RunScriptWait(52732 /*[Server\Fernseher\Show LiveTV]*/);		 
	 }


//Handle everything else
if ((in_array("alarm", $spokenwords )==true) || (in_array("alarmanlage", $spokenwords ))==true){
  if (in_array("status", $spokenwords )==true) {
     if (GetValueBoolean(40578 /*[Sicherheit\Steuerung\Status]*/)==true) {
	 SetValueString($responseOID,'Die Alarmanlage ist eingeschaltet.');
	 }else{
	 SetValueString($responseOID,'Die Alarmanlage ist ausgeschaltet.');
	 }
	 SetValueString($sessionEndOID,1);
	 
  }
  if ((in_array("schalte", $spokenwords )==true)  && (in_array("aus", $spokenwords )==true)) {
	 SetValueString($responseOID,'Bitte nenne mir das Passwort');
	 SetValueString($sessionEndOID,0);
	 SetValueString($currentTaskOID,'PasswordVerification');
  }
  if ((in_array("schalte", $spokenwords )==true) && (in_array("ein", $spokenwords )==true)) {
	 SetValueString($responseOID,'Die Alarmanlage ist eingeschaltet');
	 SetValueString($sessionEndOID,1);
	 IPS_RunScriptWait(38129 /*[Sicherheit\Steuerung\Alarm - An]*/);
  }  
}

AnswerAmazon(GetValueString($responseOID),GetValueString($sessionEndOID));

function AnswerAmazon($Response, $EndSession = false) {
 // Provide JSON response to echo.
 header('Content-Type: application/json;charset=UTF-8');
 $shouldEndSession = $EndSession ? 'true' : 'false';
 $text = '{
                "version" : "1.0",
                "response" : {
                    "outputSpeech" : {
                                        "type" : "PlainText",
                                        "text" : "'.$Response.'"
                                        },
                    "shouldEndSession" : '.$shouldEndSession.'
                }
            }';

 // Response do Amazon Web Service (or GUI)
 header('Content-Length: ' . strlen($text));
 echo $text;
 IPS_LogMessage('ECHO','JSON posted: '.$response);
}
	

?>

Ich habe wahrscheinlich Tomaten auf den Augen und hoffe das mir einer von Euch helfen kann

Wenn ich Alexa einen Sprachbefehl sende wird der sauber in IPS verstanden und ausgeführt, Seit heute morgen allerdings meint Alexa das meine Antwort nicht in Ordnung ist.

Im Log sieht das wie folgt aus

{
„version“ : „1.0“,
„response“ : {
„outputSpeech“ : {
„type“ : „PlainText“,
„text“ : „roger radio switched on“
},
„shouldEndSession“ : true
}
}

Der PHP Code ist hier :

$shouldEndSession = 'true';
 $text = '{
                "version" : "1.0",
                "response" : {
                    "outputSpeech" : {
                                        "type" : "PlainText",
                                        "text" : "'.$resp.'"
                                        },
                    "shouldEndSession" : '.$shouldEndSession.'
                }
            }';

@BestEx

Nur eine Vermutung: Das Problem liegt meist nicht bei der JSON-Antwort. Wenn in Deinem Skript irgendwo ein Fehler ist, dann quitiert das Amazon mit einer Fehlermeldung in der Art: Endpoint could not be reached or answer is invalid.

Also schau mal, wo Du kürzlich was im Code geänderst hast oder ob eine Funktion aufgerufen wird, die bisher nicht aktiv war.

Michael

@MikeLima

Danke für den Tip, das wars in der Tat. In IPS wird das Script trotz Fehler nicht fehlerhaft markiert und Alexa kommt dann mit dieser blöden Meldung

Hallo MikeLima,

Dein Skript läuft super!!! Vielen Dank!

Die Temperaturen im Haus kann ich bereits abfragen.
Nun würde ich diese natürlich auch gerne setzen.
Hast Du hierzu eine Idee?

Axel

Hallo Axel

Schau Dir mal das Script von 1007 an. Dort gibts ne Funktion zum wandeln von Text-Zahlen in echte Zahlen: Also EIns zu 1. Danach solltest Du eigentlich ganz einfach den Wert setzen können.

function ZahlWort($zahlwort)
	{
	
	$result = false;
	
	// Eins
	$array0 = array ('eins','eine','einen');
	// Zehner
	$array1 = array ('null','zehn','zwanzig','dreißig','vierzig','fünfzig','sechzig','siebzig','achtzig','neunzig','hundert');
	// 1 bis 19
	$array2 = array ('null','eins','zwei','drei','vier','fünf','sechs','sieben','acht','neun','zehn',
						'elf','zwölf','dreizehn','vierzehn','fünfzehn','sechzehn','siebzehn','achtzehn','neunzehn');
	
	$key = array_search($zahlwort,$array0);
		
	if ( $key !== false )
		{
		$result = 1;
		}
	
	if ( $result != 1 )
		{
		$key = array_search($zahlwort,$array1);
	
		if ( $key !== false )
			{
			$result = ($key) * 10;
			}
		else
			{
			$key = array_search($zahlwort,$array2);
		
			if ( $key !== false )
				{
				$result = ($key);
				}
			else
				{
				$s = explode('und',$zahlwort);
			
			
				$key = array_search($s[1],$array1);
				$result = ($key) * 10;
				$key = array_search($s[0],$array2);
				$result = $result + $key;
			
				}	
			}
		}
	
	
	return $result;
	
	}

Hallo MikeLima ,

könntest Du mir bitte sagen, wie ich die Funktion von 1007 in Dein Skript einbinden kann.

Vielen Dank!

Axel

Ich habe noch keinen Echo oder Dot und mich daher noch nicht näher mit auseinander gesetzt, aber liefert denn Amazon kein sauberes JSON das man automatisch weis um welchen Variablentyp es sich handelt oder wir da wirklich alles als Text geliefert?