So hier nun der zweite Teil des Setups,
die Scripte für IPSymcon.
Für die verwendeten Skripte sind ein paar Variablen pro Device nötig
InSpeech wird der eingesprochene Text gespeichert
OutSpeech ist der Antwort Satz, also das was die App nach der Aktion sagen wird
Context ist für spätere Erweiterungen gedacht, hier denke ich an den Raum, wo sich das Device befindet. Dann kann "Licht aus" z.B. immer auf den aktuellen Raum beziehen
ServicePort ebenso, ist gedacht um den Proxy des Devices zu benutzen
IpAdresse analog
Bei mir stellt sich das ganze dann in etwa so dar
Natürlich lassen sich auch eigene Skripte verwenden,
aber für den Anfang sind die sicherlich gebrauchbar.
Skript 1 aivc.php
Das erste Skripte habe ich in meiner Installation ins Verzeichnis
..\IpSymcon\webfront\user kopiert.
Bei mir trägt es den Namen aivc.php
Damit kann ich dieses Script mit der Url http:/<IPvonIPSymcon>:<PORTWebFronted>/user/aivc.php aufrufen.
Dieses ist dann auch die Skript Url, wie sie in der App eingetragen werden muss.
Dieses Skript erhält drei Parameter von der App.
1. cmd Dieses hat immer den Wert 0, als Erkennung das eine Sprachnachricht übertragen wird
2. id Dieses ist die Geräte Id welche in den Settings eingetragen werden kann
3. par Dieser enthält den gesprochenen Text
Was tut es, es ruft ein weiteres Skript im IPS auf, dass der Sprachsteuerung dient, und gibt das Ergebnis zurück
Hier nun der Inhalt
<?
//der folgende Link wird per app aufgerufen und hier entsprechend ausgewertet
// http://ip:port/user/avic.php?cmd=0&id=AliceTest&par=text
//die Variable "cmd" 0 bedeutet SpeechSystem, weitere denkbar
//die Variable "id" enthält die Device-ID
//die Variable "par" gibt den gesprochenen Text an
$cmd = $_GET["cmd"];
$id = $_GET["id"];
$par = $_GET["par"];IPS_LogMessage('AIVC', $cmd.' '.$id.' '.$par);
switch ($id)
{
case "AliceTest":
$SpeechInputID = 57283; // Variable für das Device AliceTest Sprache rein
$SpeechOutputID = 15556; // Variable für das Device AliceTest Sprache raus
$contextId = 22278; // // Variable für das Device AliceTest interne Daten, in welchem Raum befindet sich das Tablet
break;case "TabWZ":
break;case "TabBüro":
break;
}switch($cmd)
{
case 0:// Nun das zweite Skript mit der ID (bitte anpassen) aufrufen (trigger.php)
IPS_RunScriptWaitEx (52716 , Array("DeviceID" => $id, "TextIn" => $par, "TextOutId" => $SpeechOutputID));
echo GetValueString($SpeechOutputID);break;
}
?>
Skript 2 trigger.php
Dieses Skript nimmt die Parameter und leitet sie ans nächste Skript weiter
<?
include "SpeechServer.inc.php";$DeviceID = $_IPS['DeviceID'];
$TextIn = $_IPS['TextIn'];
$TextOutId = $_IPS['TextoutId'];$result = Parse($TextIn, $SpeechOutputID, $contextId);
IPS_LogMessage("Sprachsteuerung", $result);
?>
Skript 3 SpeechServer.inc.php
Der Kern der Sprachauswertung, diese Skript liest die Grammatik und die Funktionen ein.
Ermittelt dann anhand ob die Spracheingabe eine Funktion ausführen soll,
und führt diese aus.
Das Skript entstammt im wesentlichen Forum von IPS
<?
include_once "Grammar.inc.php";
include_once "Commands.php";function Parse ($SpeechInput, $SpeechOutputID, $ContextId)
{
$grammar = GetGrammar();// $SpeechInput = GetValueString($SpeechInputID);
IPS_LogMessage("Sprachsteuerung", 'SpeechInput=" '.$SpeechInput.'" Ort: '.$ContextId);// Alle Nummern aus dem InputString ermitteln. Liefert ein Array $numbers
// mit allen gefundenen Zahlen als Float-Werte oder false.
$minusspeech = array(" Minus ", " minus ", "- ");
preg_match_all("/-?\d+(,|\.)?\d*/", str_replace($minusspeech, "-",$SpeechInput), $numbers);
if(isset($numbers[0][0]))
{
$numbers = $numbers[0];
for ($i = 0; $i < count($numbers); $i++)
{
$numbers[$i] = floatval(str_replace(',', '.' , $numbers[$i]));
IPS_LogMessage("Sprachsteuerung", ' $numbers['.$i.']='.$numbers[$i]);
}
}
else
{
$numbers = false;
IPS_LogMessage("Sprachsteuerung", ' $numbers=false');
}// Alle Einträge des $config Arrays werden auf Übereinstimmung mit dem Speech-Satz geprüft
$config_count = 0;
foreach ($grammar as $element)
{
$config_count++;
$check_command = true;
$answer = "";
IPS_LogMessage("Sprachsteuerung", 'CONFIG'.$config_count);
// Prüfe REGEX1 - REGEXxx auf Übereinstimmung
for ($i = 1; $i < 100; $i++)
{
@$RegEx = $element['REGEX'.$i];
if(empty($RegEx))
{
break; // Abbruch da REGEXx Eintrag nicht vorhanden ist
}
else
{
if(preg_match('/'.$RegEx.'/i', ' '.$SpeechInput.' '))
{
IPS_LogMessage("Sprachsteuerung", ' REGEX'.$i.'['.$RegEx.']=true');
}
else
{
IPS_LogMessage("Sprachsteuerung", ' REGEX'.$i.'['.$RegEx.']=false');
// Ein REGEXx Eintrag wurde nicht gefunden. Prüfung auf COMMAND wird nicht durchgeführt
$check_command = false;
}
}
} /*FOR*/if($check_command == true)
{
// Alle REGEX wurden gefunden, suche jetzt nach den COMMAND Ausdrücken
for ($i = 1; $i < 100; $i++)
{
@$RegEx = $element['COMMAND'.$i]['REGEX'];
if(empty($RegEx))
{
break; // Abbruch da COMMANDx Eintrag nicht vorhanden
}
else
{
if(preg_match('/'.$RegEx.'/i', ' '.$SpeechInput.' '))
{
IPS_LogMessage("Sprachsteuerung", ' COMMAND'.$i.' REGEX['.$RegEx.']=true');
$code = $element['COMMAND'.$i]['CODE'];
$say = $element['COMMAND'.$i]['SAY'];
IPS_LogMessage("Sprachsteuerung", ' Execute CODE :'.$code);
// Script in CODE ausführen...
IPS_LogMessage("CodeBefore",$code);
$code = str_replace ( "###CONTEXTID###", $ContextId , $code);
IPS_LogMessage("CodeReplaced",$code);
eval($code);
// Variablen in SAY auflösen...
eval("\$say = \"$say\";");
IPS_LogMessage("Sprachsteuerung", ' SAY : '.$say);
$answer = $say;
break;
}
else
{
IPS_LogMessage("Sprachsteuerung", ' COMMAND'.$i.' REGEX['.$RegEx.']=false');
}
}
} /* FOR */
}
if($answer != "") break; // Abbruch da passendes Element aus Config gefunden wurde
}/* FOR GRAMMAR */// Leerer Anwortstring bedeutet nichts passendes gefunden.
if($answer == "") $answer = 'Nein Dave, das kann ich nicht tun!';
IPS_LogMessage("Sprachsteuerung", 'SpeechOutput="'.$answer.'"');
SetValueString($SpeechOutputID, $answer);
return $answer;
}
?>
Skript 4 Grammar.inc.php
In diesem Skript sind die Sprachlichen Regeln und die Aktionen dazu verknüpft,
auch dieses entstammt dem Forum von IPS.
<?
function GetGrammar ()
{
$grammar = array(array('REGEX1' => 'wie spät ist es | wie viel Uhr | Zeit',
'COMMAND1' => array(
'REGEX' => ' ',
'CODE' => '$result = date("H")." Uhr ".date("i");',
'SAY' => 'Die aktuelle Uhrzeit ist $result'
)
),
/* Licht */
array(
'REGEX1' => ' (Licht|Lampe)',
'COMMAND1' => array(
'REGEX' => 'an|ein|einschalten',
'CODE' => 'Set_Light (###CONTEXTID###, true);',
'SAY' => 'Ich habe das Licht eingeschaltet'
),
'COMMAND2' => array(
'REGEX' => 'aus|ausschalten',
'CODE' => 'Set_Light (###CONTEXTID###, false);',
'SAY' => 'Ich habe das Licht ausgeschaltet'
)
),
/* Temperaturen */
array(
'REGEX1' => '(wie|welche|sag)?.+Temperatur',
'COMMAND1' => array(
'REGEX' => ' Kinderzimmern ',
'CODE' => '
$result = GetValue(34877);
$result = number_format($result, 1, ".", "");
$result1 = GetValue(24999);
$result1 = number_format($result, 1, ".", "");
',
'SAY' => 'In Aarons Zimmer beträgt die Temperatur $result Grad, in Dankens Zimmer beträgt die Temperatur $result1 Grad'
),
'COMMAND2' => array(
'REGEX' => ' Aarons Zimmer ',
'CODE' => '
$result = GetValue(34877);
$result = number_format($result, 1, ".", "");
',
'SAY' => 'In Aarons Zimmer beträgt die Temperatur $result Grad'
),
'COMMAND3' => array(
'REGEX' => ' Duncans Zimmer ',
'CODE' => '
$result = GetValue(24999);
$result = number_format($result, 1, ".", "");
',
'SAY' => 'In Dankens Zimmer beträgt die Temperatur $result Grad'
),
'COMMAND4' => array(
'REGEX' => ' Wohnzimmer ',
'CODE' => '
$result = GetValue(16576);
$result = number_format($result, 1, ".", "");
',
'SAY' => 'Im Wohnzimmer beträgt die Temperatur $result Grad'
),
'COMMAND5' => array(
'REGEX' => ' ',
'CODE' => '',
'SAY' => 'Bitte spezifizieren Sie Ihre Anfrage'
),
),
/* Globales */
array(
'REGEX1' => ' Alle ',
'REGEX2' => ' Lichter ',
'COMMAND1' => array(
'REGEX' => ' aus | ausschalten ',
'CODE' => '
$result = MyFunctionAllLightsOff();
',
'SAY' => '$result'
)
)
);return $grammar;
}
?>
Skript 5 Commands.php
Hier sind die Funtionen, welche in der Grammar benutzt werden enthalten.
Diese schalten dann die entsprechenden Versionen
<?
include_once "HardwareHelper.php";//Fügen Sie hier Ihren Skriptquellcode ein
function Set_Light($ContextId, $power)
{
// Wir wissen nun in welchem Raum wir sind
// Nun alle Lichter Mit Default Kennzeichen setzen
$children = IPS_GetChildrenIDs($ContextId);
foreach ($children as $child) // Child ist die Instanz
{
$defaultLight = IPS_GetVariableIDByName("SpeechServer_Light_Default", $child );
if ($defaultLight)
{
// Wenn DefaultLight nun true ist, dann dieses Licht schalten
if (GetValueBoolean($defaultLight))
{
// Nun diesse Licht schalten
// Dazu testen ob
// HM, FS20, MILIGHT
$typ = Get_InstanceType($child);
Set_Instance_Power($child, $power);
}}
}
}
?>
Skript 6 HardwareHelper.php
Dieses enthält ein paar für mich relevante Hilfsfunktionen
<?
IPSUtils_Include ("IPSLogger.inc.php", "IPSLibrary::app::core::IPSLogger");/* liefert z.B.:
Array
(
[InstanceID] => 18235
[InstanceStatus] => 102
[LastChange] => 0
[InstanceId] => Array
(
[ModuleID] => {48FCFDC1-11A5-4309-BB0B-A0DB8042A969}
[ModuleName] => FS20
[ModuleType] => 3
)
[ConnectionID] => 29416
)
*/function Get_InstanceType($InstanceId)
{
IPS_LogMessage("Get_InstanceType", $InstanceId);
$InstanceData = IPS_GetInstance($InstanceId);
$InstanceModuleData = $InstanceData["ModuleInfo"];
$typ = $InstanceModuleData["ModuleName"];
return $typ;
}
function Set_Instance_Power($child, $power)
{
IPS_LogMessage("HardWareHelper", "Id:".$child." Power:".$power);
$typ = Get_InstanceType($child);
IPS_LogMessage("HardWareHelper", "Id:".$child." Typ:".$typ);
switch ($typ)
{
case "FS20":
FS20_SwitchMode($child, $power);
break;
case "HomeMatic Device":
HM_WriteValueBoolean ( $child, "STATE",$power);
break;
}
}
?>
Aufbauend auf diesen, sich noch in der Entwicklung befindlichen Skripten lassen sich sicher eigene erstellen und diese benutzen.
Verschiedene Varianten dazu gibt es ja auch im IPS Forum