Ankündigung

Einklappen
Keine Ankündigung bisher.

Umfrage: Amazon Echo

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

    #31
    Hi Hendrik,

    nein kannte ich noch nicht. Ich bin mal drüber geflogen kann aber nicht auf die schnelle beurteilen, ob das für die Sache von Nutzen ist. Ich kann auch nichts über FHEM sagen, weil ich mich damit noch gar nie befasst habe. Vielleicht kann ich mal versuchen mit dem Entwickler Kontakt aufzunehmen. Der könnte wertvolle Tipps haben, wie ich das eventuell portieren kann. Fest steht, er benutzt die Smart Home Skill API die momentan seitens Amazon noch stark beschränkt ist. Soll heißen, damit bekämen wir ohne hin eh nur hin Lichter zu schalten und zu Dimmen und Thermostate zu regel. Das wars dann aber auch schon wieder. Keine Beschattung oder andere Sonderlocken.

    Aber Danke auf jeden Fall für die Nennung des Beitrages.

    Grüße,
    Patrick

    Kommentar


      #32
      Hey du! Kannst du mir irgendwie die "alexa-fhem-0.0.0.tgz" aus deinem verlinkten Beitrag zukommen lassen? Wichtig! Denn das FHEM-Forum hat die Registrierung geschlossen und ich komme nicht an die Datei! Sehr ärgelich! PN!

      Kommentar


        #33
        Hab ich selbst nicht.
        warum haben die geschlossen?

        Kommentar


          #34
          Mal ein kleiner Zwischenstand für die, die nicht im Edomi Forum noch mitlesen. Ich habe dort jemanden gefunden, der das für Edomi aufbereitet hat. Ich bin aktuell dabei den Mechanismus zu SmartHomeNG zu portieren. Von der Funktion her nutzt der Entwickler die Amazon Cloud und eine Lambda Funktion, die die Anfrage an einen eigenen Webserver weitergibt. Hierbei wird die Kommunikation mit einem Clientzertifikat abgesichert. Nicht so leicht zu konfigurieren, allerdings halt mega sicher. Somit muss man sich auch keinerlei Sorgen machen, dass man irgendwie von außen gehackt wird. Der eigene Webserver leitet dann die Anfrage an das Network Socket weiter und schaltet das ganze. Als Confirmation gibt er dann den Status zurück an die Lambda Funktion in der Cloud und Alexa quittiert das dann mit einer Wortmeldung.

          Die Items, die über Alexa geschaltet werden können, werden in einem separaten Config File verstaut. Dieses File lässt sich mit einem kleinen Script auch aus der items.conf erzeugen.

          So ist mal die Idee. Sobald es was beta mäßiges gibt, melde ich mich wieder oder mache einen Plugin release Thread auf.

          Grüße,
          Patrick

          Kommentar


            #35
            hey patrick, habe mich gerade mal durch den thread gewühlt, da hast du dich schon genau damit beschäftigt, warum ich unbedingt einen echo haben will
            magts du mal den entsprechenden edomi thread hier querverlinken?

            so stelle ich mir mein setup vor:
            - nginx reverse proxy mit 0815 config (kann man copy&paste mässig in einer readme.md aufbereiten)
            - lets encrypt ssl-zertifikat
            - auth ganz normal http basic auth (über ssl/tls) - siehst du hier echte vorteile eines client zertifikats?

            in smarthome-ng:
            - in den items direkt die alexa_keywords definieren, aber versuchen vererbung in der item-hierarchie zu nutzen
            - aus der items.conf per plugin ein entsprechend aufbereitetes alexa skillset generieren
            - plugin für endpunkt (per nginx exponiert), der das alexa json verarbeiten kann

            ich schau mal in die edomi entwicklung...

            schön, dass du das thema hier anleierst!

            Kommentar


              #36
              Voll coole Sache, Patrick!
              Ich hab bei mir mal das Speech Plugin laufen gehabt, das hat eigentlich gut funktioniert und ist von der Idee her auch sehr flexibel.
              Mit Alexa natürlich noch mehr sexy - einfach nur in den Raum rufen zu brauchen.

              Wenn ich dich richtig verstehe, ist man dann mit der Lambda-Funktion genauso flexibel?
              Muss aber dann sowas sagen wie "Alexa, sag mal dem Haus, dass es im Wohnzimmer Licht machen soll"?

              LG Stefan

              Kommentar


                #37
                Noch eine Frage, wie stehst grundätzlich zu der offiziellen Home Skill API?
                Hört sich ja erstmal an wie Home Skill API = Apple Homekit vs. Custom / Proprietär / Keinerlei Referenz

                Von der Funktionalität her, sind das "nur' vorgefertigte Utterances, die ich komplett deckungsgeich mit den Custom Skills nachbilden kann? Oder stecken in den Home Skills auch Dinge, die man nicht einfach custom nachbilden kann?

                Will man vielleicht grundsätzlich auf die Home Skills API setzen, weil diese offiziell ist und die Amazon-Referenz für Smarthome-Steuerung ist? In der Hoffnung, dass diese kontinuierlich ausgebaut wird.

                Kommentar


                  #38
                  Hier der Link ins Edomi Forum zur Referenz: https://knx-user-forum.de/forum/proj...pracherkennung


                  Zitat von SvStefan Beitrag anzeigen
                  Voll coole Sache, Patrick!
                  Ich hab bei mir mal das Speech Plugin laufen gehabt, das hat eigentlich gut funktioniert und ist von der Idee her auch sehr flexibel.
                  Mit Alexa natürlich noch mehr sexy - einfach nur in den Raum rufen zu brauchen.

                  Wenn ich dich richtig verstehe, ist man dann mit der Lambda-Funktion genauso flexibel?
                  Muss aber dann sowas sagen wie "Alexa, sag mal dem Haus, dass es im Wohnzimmer Licht machen soll"?

                  LG Stefan
                  Das ist korrekt. Wenn du gut programmieren kannst bist du genauso felxibel. Das Problem ist, dass du natürlich ein Schlüsselwort mehr hast, wie du schon richtig erkannt hast. Das macht natürlich die Spracheingabe relativ "sperrig". Was mich dann hierzu führt:

                  Zitat von hotzen Beitrag anzeigen
                  Noch eine Frage, wie stehst grundätzlich zu der offiziellen Home Skill API?
                  Hört sich ja erstmal an wie Home Skill API = Apple Homekit vs. Custom / Proprietär / Keinerlei Referenz

                  Von der Funktionalität her, sind das "nur' vorgefertigte Utterances, die ich komplett deckungsgeich mit den Custom Skills nachbilden kann? Oder stecken in den Home Skills auch Dinge, die man nicht einfach custom nachbilden kann?

                  Will man vielleicht grundsätzlich auf die Home Skills API setzen, weil diese offiziell ist und die Amazon-Referenz für Smarthome-Steuerung ist? In der Hoffnung, dass diese kontinuierlich ausgebaut wird.
                  Ja die Smart Home API ist besser, weil man sich nicht um das Gesagte kümmern muss. Es gibt dann von Amazon vorgefertige Szenarien (im Moment Licht schalten/dimmen und Thermostat regel).

                  Ich werde so wie der Entwickler auf Edomi Seite auch auf diese API setzen in der Hoffnung, dass Amazon hier kräftig weiterentwickelt. Ich denke es wird so kommen.

                  - auth ganz normal http basic auth (über ssl/tls) - siehst du hier echte vorteile eines client zertifikats?
                  Ja sehe ich. Sicherheit. Außerdem muss ich dann kein Passwort an eine Amazon Web Cloud geben, sondern nur ein Zertifikat. Okay zugegebener Maßen haben die dann auch den entschlüsselten Private Key des Zertifikates. Aber einen Tod muss man wohl sterben. Die Chance dass ein Zertifikat kompromittiert wird ist allerdings geringer, als bei einem Passwort.


                  in smarthome-ng:
                  - in den items direkt die alexa_keywords definieren, aber versuchen vererbung in der item-hierarchie zu nutzen
                  - aus der items.conf per plugin ein entsprechend aufbereitetes alexa skillset generieren
                  - plugin für endpunkt (per nginx exponiert), der das alexa json verarbeiten kann
                  Das wäre ebenfalls meine Wunschvorstellung. Aber für sowas programmiere ich noch nicht gut genug. Ich werde erst einmal mit einer losgelösten config.txt starten, die aus der items erstellt werden kann. Solltest du das besser programmieren können bin ich offen für Vorschläge

                  Grüße,
                  Patrick

                  Kommentar


                    #39
                    Moin,

                    bedeutet das, dass man um das zukünftige Plugin zu nutzen einen eigenen Webserver braucht?

                    Wie realisiert man "Licht in Kevins Zimmer anschalten" mit der Smart Home api, wo man keine eigenen Begriffe definieren kann?

                    Gruß,
                    Hendrik

                    Kommentar


                      #40
                      Hallo Patrick,
                      Zitat von patrickgoll Beitrag anzeigen
                      Die Chance dass ein Zertifikat kompromittiert wird ist allerdings geringer, als bei einem Passwort.
                      wieso ist ein Zertifikat bei Amazon, wenn kein Passwort für das Cert gesetzt ist, sicherer als ein Passwort im Script? Wenn ich Zugriff auf das Script haben, dann habe ich doch auch Zugriff auf das Zertifikat. Oder haben die einen secure Storage, wo man als Kunde Zertifikate ablegen kann?

                      Meiner Meinung nach besteht kein Unterschied, ob ich Amazon nun ein Passwort gebe oder ein Zertifikat das nicht noch anderweitig geschützt ist.

                      Bis bald

                      Marcus

                      Kommentar


                        #41
                        Hi,

                        So wie man die Lampen benennt, so nimmt Alexa das auch an. Sprich Lampe in Kevins Zimmer sollte meiner Meinung nach funktionieren. Wenn du die smartvisu nutzt hast du schon einen eigenen Webserver. Den kann man erweitern.

                        Zum Thema Zertifikat sieht es so aus, dass ich nur verhindern möchte dass der Kommunikationsweg überwacht wird. Macht also einer ein Man-in-the-Middle Angriff ist das Zertifikat sicherer als das Passwort.

                        Hat allerdings jemand Zugriff auf dein aws developer Profil ist die Sache eh gelaufen. Auch wenn ich nach dem zip upload der Zertifikate keinen Weg gesehen habe die wieder runterzuladen.

                        Grüße,
                        Patrick

                        ​​

                        Kommentar


                          #42
                          Das Backend-Plugin spannt sowieso auch schon einen Webserver auf.. Ansich stünde sowieso noch an, auf der Basis eine REST API zu programmieren. Dann könnte ich endlich meine alte linknx/php Layer ablösen..

                          Kommentar


                            #43
                            Könnte die REST API dann auch von nutzen für mich sein? Das Thema mit den REST APIs dieser Welt habe ich so oder so noch nicht richtig verstanden.

                            Kommentar


                              #44
                              Lese hier und im Edomi Forum mit. Auch Gira HS Baustein wäre für mich interessant. Kann selber nicht gut programmieren aber Pi aufsetzen oder Scripte editieren schaffe ich noch. Hatte schon Google mit Tasker und dann über udp an Gira HS. Fand die Einrichtung und Google super nervig und war damit nicht zufrieden.

                              Kommentar


                                #45
                                So Zwischenstatus! Ich habe es hinbekommen mithilfe des Network Plugin als Schnittstelle zu SmartHomeNG und mit der angepassten php App aus dem Edomi Forum meine Lampen zu schalten. Was nicht geht ist dimmen. Ich habe auch rausgefunden warum. Die Kumpels von Edomi können via deren API abfragen welchen Wert eine Lampe/Heizung gerade hat. Dann verrechnen die im Falle eines "IncreasePercentage" Events (also hochdimmen) den alten Wert und fügen einfach sagen wir mal 10 hinzu.

                                Da das Network Plugin aber offenbar nur schalten kann und nicht abfragen wird es wohl vorerst nur bei Lampen an und aus bleiben. Mehr werden wir wohl nicht hinbekommen, bis wir sämtliche Komponenten (Network Plugin, Alexa PHP App, ...) angepasst haben.

                                Wer mal die "Alpha" testen will kann folgendes tun. Webserver mit Zertifikatsauth einrichten und durch den Router schleifen (setze ich jetzt für die Alpha mal voraus, ein Developer bekommt das schon hin).

                                AWS und developer Account machen bei Amazon (Ist auch alles beschrieben im verlinkten EDOMI Thread).

                                Dann folgenden Code in einem Texteditor speichern als index.js:

                                Code:
                                const PORT=xxxx;
                                const HOST='domain.de';
                                
                                
                                // namespaces
                                const NAMESPACE_CONTROL = "Alexa.ConnectedHome.Control";
                                const NAMESPACE_DISCOVERY = "Alexa.ConnectedHome.Discovery";
                                
                                // errors
                                const ERROR_TARGET_OFFLINE = "TargetOfflineError";
                                const ERROR_UNSUPPORTED_OPERATION = "UnsupportedOperationError";
                                const ERROR_UNEXPECTED_INFO = "UnexpectedInformationReceivedError";
                                
                                
                                // entry
                                exports.handler = function (event, context, callback) {
                                
                                    log("Received Directive", JSON.stringify(event));
                                
                                    var postData = JSON.stringify(event);
                                    fs =    require('fs');
                                    var options = {
                                        hostname: HOST,
                                        port: PORT,
                                        //family: 6,
                                        rejectUnauthorized: false,
                                        path: '/alexa.php',
                                        method: 'POST',
                                        //ca: fs.readFileSync('client.crt'),
                                
                                        key:   fs.readFileSync('client.key'),  // Secret client key
                                        cert:  fs.readFileSync('client.crt'),  // Public client key
                                
                                        headers: {
                                            'Content-Type': 'application/json',
                                            'Content-Length': Buffer.byteLength(postData)
                                        }
                                    };
                                
                                    var http = require('https');
                                    var req = http.request(options, (res) => {
                                        console.log(`STATUS: ${res.statusCode}`);
                                        console.log(`HEADERS: ${JSON.stringify(res.headers)}`);
                                        res.setEncoding('utf8');
                                        var rawData = '';
                                        res.on('data', (chunk) => rawData += chunk);
                                        res.on('end', () => {
                                            console.log('No more data in response.');
                                            if (rawData.length>0) {
                                                log('Response: ', rawData);
                                                Data = JSON.parse(rawData);
                                                log('json output', JSON.stringify(Data));
                                //                callback(null, Data);
                                                callback(null, Data);
                                            } else {
                                                callback(null, createError(ERROR_TARGET_OFFLINE) );
                                            }
                                            return;
                                        });
                                    });
                                
                                    req.on('error', (e) => {
                                        console.log(`problem with request: ${e.message}`);
                                        callback(null, createError(ERROR_TARGET_OFFLINE) );
                                        return;
                                    });
                                
                                    // write data to request body
                                    req.write(postData);
                                    req.end();
                                    return;
                                
                                }// exports.handler
                                
                                
                                var handleUnsupportedOperation = function() {
                                    var header = createHeader(NAMESPACE_CONTROL,ERROR_UNSUPPORTED_OPERATION);
                                    var payload = {};
                                    return createDirective(header,payload);
                                }// handleUnsupportedOperation
                                
                                
                                var handleUnexpectedInfo = function(fault) {
                                    var header = createHeader(NAMESPACE_CONTROL,ERROR_UNEXPECTED_INFO);
                                    var payload = {
                                        "faultingParameter" : fault
                                    };
                                    return createDirective(header,payload);
                                }// handleUnexpectedInfo
                                
                                
                                // support functions
                                var createMessageId = function() {
                                    var d = new Date().getTime();
                                    var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
                                        var r = (d + Math.random()*16)%16 | 0;
                                        d = Math.floor(d/16);
                                        return (c=='x' ? r : (r&0x3|0x8)).toString(16);
                                    });
                                    return uuid;
                                }// createMessageId
                                
                                
                                var createHeader = function(namespace, name) {
                                    return {
                                        "messageId": createMessageId(),
                                        "namespace": namespace,
                                        "name": name,
                                        "payloadVersion": "2"
                                    };
                                }// createHeader
                                
                                function log(title, msg) {
                                    console.log(title + ': ' + msg);
                                }
                                Angepasst werden muss in dieser Datei ganz oben Port und Domain unter dem euer PHP Server hört.
                                Ihr zippt das dann als function.zip zusammen mit dem Zertifikat und dem Private Key die client.key und client.crt heißen müssen.
                                Der Key muss unverschlüsselt sein.

                                Für die PHP Funktion in eurem Server im Rootverzeichnis legt ihr eine Datei an, die alexa.php heißt mit folgendem Inhalt:

                                Code:
                                <?php
                                
                                $host = 'ip.von.smart.home';
                                $url = '/';
                                $configFile = 'config.txt';
                                
                                function cleanString($string) {
                                    $string = str_replace(' ', '-', $string); // Replaces all spaces with hyphens.
                                    return preg_replace('/[^A-Za-z0-9\-]/', '', $string); // Removes special chars.
                                }
                                
                                function readConfig()
                                {
                                    global $koConfig, $configFile;
                                    $configLines = file($configFile);
                                    $koConfig=array();
                                    foreach ($configLines as $line) {
                                        $line = trim($line);
                                        if (($line!="") && (substr($line,0,1)!='#') && (substr($line,0,1)!='/') && (substr($line,0,1)!=';')) {
                                            $subStrings = explode(';', $line);
                                            if (count($subStrings)>=2) {
                                                $name=trim($subStrings[0]);
                                                $deviceName=cleanString($name);
                                                $koConfig[$deviceName]=array();
                                                $koConfig[$deviceName]['name']=$name;
                                                for ($i=1; $i<count($subStrings); $i++) {
                                                    $subStr=trim($subStrings[$i]);
                                                    if ($subStr=="") continue;
                                                    if ((is_numeric($subStr)) && (is_int($subStr*1))) {
                                                        $typ = 'S';
                                                        $ko = $subStr*1;
                                                        $koConfig[$deviceName][$typ]=$ko;
                                                    } else {
                                                        $subStrings2 = explode(':', $subStr);
                                                        if (count($subStrings2)==2) {
                                                            $typ = trim($subStrings2[0]);
                                                            $ko = trim($subStrings2[1]);
                                                            $koConfig[$deviceName][$typ]=$ko;
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                                
                                function setValue($koId, $koValue)
                                {
                                    global $url, $host;
                                    $fp = fsockopen("ip.von.smart.home", port.von.nw.plugin, $errno, $errstr, 30);
                                    $params=array(
                                    urlencode('item'),
                                    urlencode($koId),
                                    urlencode($koValue)
                                    );
                                    if (!$fp) {
                                        echo "$errstr ($errno)<br />\n";
                                    } else {
                                        $out = "GET $url".implode($params, '|')." HTTP/1.1\r\n";
                                        $out .= "Host: ".$host."\r\n";
                                        $out .= "Connection: Close\r\n\r\n";
                                        fwrite($fp, $out);
                                        $rcv='';
                                        while (!feof($fp)) { $rcv.=fgets($fp, 128);    }
                                        fclose($fp);
                                    }
                                }
                                
                                function getValue($koId)
                                {
                                    global $url, $host;
                                    $fp = fsockopen("ip.von.smart.home", port.von.nw.plugin, $errno, $errstr, 30);
                                    $params=array(
                                    urlencode('login')."=".urlencode('remote'),
                                    urlencode('pass')."=".urlencode('remote'),
                                    urlencode('koid')."=".urlencode($koId)
                                    );
                                    if (!$fp) {
                                        echo "$errstr ($errno)<br />\n";
                                    } else {
                                        $out = "GET $url?".implode($params, '&')." HTTP/1.1\r\n";
                                        $out .= "Host: ".$host."\r\n";
                                        $out .= "Connection: Close\r\n\r\n";
                                        fwrite($fp, $out);
                                        $rcv='';
                                        while (!feof($fp)) { $rcv.=fgets($fp, 128);    }
                                        fclose($fp);
                                
                                        $pos = strpos($rcv, "\r\n\r\n");
                                        if ($pos>0) {
                                            $rcv=substr($rcv,$pos+4);
                                        } else {
                                            $pos = strpos($rcv, "\n\n");
                                            if ($pos>0) $rcv=substr($rcv,$pos+2);
                                        }
                                        return $rcv;
                                    }
                                }
                                
                                function discovery()
                                {
                                    global $koConfig;
                                
                                    $response = array();
                                    $response['header'] = array();
                                    $response['header']['namespace']='Alexa.ConnectedHome.Discovery';
                                    $response['header']['name']='DiscoverAppliancesResponse';
                                    $response['header']['payloadVersion']="2";
                                
                                    $response['payload'] = array();
                                    $response['payload']['discoveredAppliances'] = array();
                                
                                    foreach ($koConfig as $koDeviceName => $koData) {
                                        $type=array();
                                        $functions=array();
                                        if (array_key_exists('S', $koData)) { $type[]='Licht'; $functions[]='turnOn'; $functions[]='turnOff'; }
                                        if (array_key_exists('D', $koData)) { $type[]='Dimmer'; $functions[]='setPercentage'; $functions[]='incrementPercentage'; $functions[]='decrementPercentage'; }
                                        if (array_key_exists('H', $koData)) { $type[]='Heizung'; $functions[]='setTargetTemperature'; $functions[]='incrementTargetTemperature'; $functions[]='decrementTargetTemperature'; }
                                
                                        $dev = array();
                                        $dev['applianceId'] = $koDeviceName;
                                        $dev['manufacturerName'] = 'Patrick';
                                        $dev['modelName'] = 'Model '.cleanString(implode('', $type));
                                        $dev['version'] = 'VER01';
                                        $dev['friendlyName'] = $koData['name'];
                                        $dev['isReachable'] = true;
                                        $dev['friendlyDescription'] = implode('/', $type).' im '.$koData['name'].' ('.$koDeviceName.')';
                                        $dev['actions'] = $functions;
                                        // 'setTargetTemperature', 'incrementTargetTemperature', 'decrementTargetTemperature', 'setPercentage', 'incrementPercentage', 'decrementPercentage', 'turnOn', 'turnOff'
                                        $response['payload']['discoveredAppliances'][]=$dev;
                                    }
                                    return $response;
                                }
                                
                                
                                function control($request)
                                {
                                    global $koConfig, $debugStr;
                                
                                    $device_id = $request['payload']['appliance']['applianceId'];
                                    $message_id = $request['header']['messageId'];
                                    $reuqestType = $request['header']['name'];
                                
                                    $response = array();
                                    $response['header'] = array();
                                    $response['header']['namespace'] = 'Alexa.ConnectedHome.Control';
                                    $response['header']['payloadVersion'] = "2";
                                    $response['header']['messageId'] = $message_id;
                                
                                    $configEntry = $koConfig[$device_id];
                                
                                    // Für Schalter 'S': TurnOnRequest, TurnOffRequest
                                    if (array_key_exists('S', $configEntry)) {
                                        if ($reuqestType=='TurnOnRequest') {
                                            $response['header']['name']='TurnOnConfirmation';
                                            setValue($configEntry['S'], 1);
                                        }
                                        if ($reuqestType=='TurnOffRequest')  {
                                            $response['header']['name']='TurnOffConfirmation';
                                            setValue($configEntry['S'], 0);
                                        }
                                    }
                                
                                    // Für Dimmer 'D': SetPercentageRequest, IncrementPercentageRequest, DecrementPercentageRequest
                                    if (array_key_exists('D', $configEntry)) {
                                        if ($reuqestType=='SetPercentageRequest') {
                                            $value = $request['payload']['percentageState']['value'];
                                            $response['header']['name']='SetPercentageConfirmation';
                                            setValue($configEntry['D'], $value);
                                        }
                                        if ($reuqestType=='IncrementPercentageRequest')  {
                                            $delta = $request['payload']['deltaPercentage']['value'];
                                            $response['header']['name']='IncrementPercentageConfirmation';
                                            $oldValue=getValue($configEntry['D']);
                                            setValue($configEntry['D'], min(100, $oldValue+$delta));
                                        }
                                        if ($reuqestType=='DecrementPercentageRequest')  {
                                            $delta = $request['payload']['deltaPercentage']['value'];
                                            $response['header']['name']='DecrementPercentageConfirmation';
                                            $oldValue=getValue($configEntry['D']);
                                            setValue($configEntry['D'], max(0, $oldValue-$delta) );
                                        }
                                    }
                                
                                    // Für Heitung 'H': SetTargetTemperatureRequest / SetTargetTemperatureConfirmation , IncrementTargetTemperatureRequest / IncrementTargetTemperatureConfirmation, DecrementTargetTemperatureRequest / DecrementTargetTemperatureConfirmation 
                                    if ((array_key_exists('H', $configEntry)) && (($reuqestType=='SetTargetTemperatureRequest') || ($reuqestType=='IncrementTargetTemperatureRequest') || ($reuqestType=='DecrementTargetTemperatureRequest'))) {
                                        $oldValue=getValue($configEntry['H']);
                                        $debugStr .= "Oldvalue=$oldValue ";
                                        $response['payload']=array();
                                        $response['payload']['temperatureMode']=array('value'=>'AUTO');
                                        $response['payload']['previousState']=array(
                                            'mode' => array('value'=>'AUTO'),
                                            'targetTemperature' => array('value'=>$oldValue),
                                        );
                                
                                
                                        if ($reuqestType=='SetTargetTemperatureRequest') {
                                            $value = $request['payload']['targetTemperature']['value'];
                                            $debugStr .= "Setvalue=$value ";
                                            setValue($configEntry['H'], $value);
                                            $response['header']['name']='SetTargetTemperatureConfirmation';
                                        }
                                        if ($reuqestType=='IncrementTargetTemperatureRequest')  {
                                            $delta = $request['payload']['deltaTemperature']['value'];
                                            $response['header']['name']='IncrementTargetTemperatureConfirmation';
                                            setValue($configEntry['H'], min(100, $oldValue+$delta));
                                        }
                                        if ($reuqestType=='DecrementTargetTemperatureRequest')  {
                                            $delta = $request['payload']['deltaTemperature']['value'];
                                            $response['header']['name']='DecrementTargetTemperatureConfirmation';
                                            setValue($configEntry['H'], max(0, $oldValue-$delta) );
                                        }
                                        usleep(100*1000);
                                        $newValue=getValue($configEntry['H']);
                                        $debugStr .= "newValue=$newValue";
                                        $response['payload']['targetTemperature']=array('value'=>$newValue);
                                    }
                                
                                    return $response;
                                }
                                
                                function alexaSystem($request)
                                {
                                    $response = array();
                                    if ($request['header']['name']=='HealthCheckRequest') {        
                                        $response['header'] = array();
                                        $response['header']['messageId']=$request['header']['messageId'];
                                        $response['header']['name']='HealthCheckResponse';
                                        $response['header']['namespace']='Alexa.ConnectedHome.System';
                                        $response['header']['payloadVersion']="2";
                                        $response['payload'] = array();
                                        $response['payload']['description'] = 'The system is currently healthy';
                                        $response['payload']['isHealthy'] = true;
                                    }
                                    return $response;
                                }
                                
                                function main()
                                {
                                    global $configFile, $koConfig, $debugStr;
                                    $fnLog = getcwd() . "/alexa-log.txt";
                                    date_default_timezone_set('Europe/Berlin');
                                    $debugStr='';
                                
                                    readConfig();
                                
                                
                                    $postdata = file_get_contents("php://input");
                                
                                
                                // For testing....
                                    if ($postdata=='')
                                            $postdata = '{"header":{"namespace":"Alexa.ConnectedHome.Discovery","name":"DiscoverAppliancesRequest","payloadVersion":"2","messageId":"2bac165a-e532-4177-86b8-37210f247538"},"payload":{"accessToken":"Atza|IwEBIC096nvP_y5mIaW0H30USLZ3CLDqn6MluMkEU4glt9rLH3E8ufthjUdQtRC1G1FAK6ZNYTJdr3rZw45vLRmy5ETQw-JIaRNFxcylBOVh50a4sohvatpJeLy_SF_Bj-8QKNIwchm6otnbWa_kgQIsS-o9SOt5_l1cxF9TbMHvscw5eSJ0pnulvC145Equx17ldAlGQ9M7tIj8lQO7qHkTZp06jieLbnYvwMHT96kQ6clweB2HVyFqlXPhWjiXlY83GbQdqsNX1WXQm4UfCy3CZ5I8nEKmk0Ju2YVK1UmtgOlx1gNjsvnvA40lqgzXd46s-L3ocZqMB1zfAgO2GUmgFN7R1B3A9wjCgnDJhYRzsxXat_3CsHZ2w0zkeo-g1HJ7vtx2VUqh1W8fM9w93pCEnmLa1Hv1IZCCNqm89xgowqWI-os2QgNjC50QTMYldrFGZo8hzUiRwKvbHRQFVAKiDQ8BtoFHgOG8vizJ_bpbPGLG_JH8ZxSpDpORWuKkKhqoMrplH7mNyrXLCIdK6-LZo9VB"}}';
                                
                                
                                    $fp = fopen($fnLog, 'a');
                                    fwrite($fp, date('r')." =======================================================================================================\n");
                                    fwrite($fp, date('r')." Request: ".$postdata."\n");
                                    fwrite($fp, date('r')." -------------------------------------------------------------------------------------------------------\n");
                                    fclose($fp);
                                
                                    $request = json_decode($postdata, true);
                                    $response = array();
                                    if ($request['header']['namespace'] == 'Alexa.ConnectedHome.Discovery') {
                                        $response = discovery();
                                    }
                                    if ($request['header']['namespace'] == 'Alexa.ConnectedHome.Control') {
                                        $response = control($request);
                                    }
                                    if ($request['header']['namespace'] == 'Alexa.ConnectedHome.System') {
                                        $response = alexaSystem($request);
                                    }
                                
                                
                                    $jsonText = json_encode($response);
                                //    include 'prettyprint.php'; $jsonText = prettyPrint($jsonText);
                                    print $jsonText;  // Eigentliche Rückgabe
                                
                                    $fp = fopen($fnLog, 'a');
                                    fwrite($fp, date('r')." Response: ".json_encode($response)."\n");
                                    if ($debugStr!='') {
                                        fwrite($fp, date('r')." -------------------------------------------------------------------------------------------------------\n");
                                        fwrite($fp, date('r')." DebugStr: $debugStr\n");
                                    }
                                    fwrite($fp, date('r')." =======================================================================================================\n\n");
                                    fclose($fp);
                                }
                                
                                
                                main();
                                
                                ?>
                                Angepasst werden müssen die Stellen ip.von.smart.home und port.von.nw.plugin. Sucht einfach am besten in nem Texteditor danach, bevor ihr den Code als alexa.php abspeichert und passt das auf eure Umgebung an.

                                Ebenfalls im Root Verzeichnis des Servers zur alexa.php legt ihr eine config.txt an. meine sieht so aus und sollte selbsterklärend sein:

                                Code:
                                # Kommentare beginnen mit # oder ; oder // 
                                # Format: Name;[Liste von Typen:Item]
                                # Typen: S (Lichtschalter), D (Dimmer) oder H (Heizung)
                                #
                                # Beispiel:     Schlafzimmer Spots; S:EG.Schlafzimmer.Spots.Schalten; D:EG.Schlafzimmer.Spots.Dimmen
                                #        Schlafzimmer Heizung; H:EG.Schlafzimmer.Heizung.Wert
                                
                                Wohnzimmer Deckenlampe; S:EG.Wohnzimmer.Deckenlampe.Schalten; D:EG.Wohnzimmer.Deckenlampe.Dimmen
                                Wohnzimmer Ofen; S:EG.Wohnzimmer.SpotsOfen.Schalten; D:EG.Wohnzimmer.SpotsOfen.Dimmen
                                Büro Deckenlampe; S:OG.Buero.Deckenlampe.Schalten; D:OG.Buero.Deckenlampe.Dimmen
                                Ich habe vorerst mal nur 3 Items drin.
                                Ihr müsst in eurer Items.conf dafür natürlich auch das network Plugin freischalten (nw = yes).

                                Nun könnt ihr in der AWS Konsole über den Teststring ein Discovery und ein und Ausschaltbefehle senden.

                                Code:
                                {
                                  "header": {
                                    "namespace": "Alexa.ConnectedHome.Discovery",
                                    "name": "DiscoverAppliancesRequest",
                                    "payloadVersion": "2",
                                    "messageId": "06c4efaf-da9b-4deb-8561-54412400382c"
                                  },
                                  "payload": {
                                    "accessToken": "BLA BLA aber brauchen wir nicht(?)"
                                  }
                                }
                                Code:
                                {
                                   "header":{
                                      "namespace":"Alexa.ConnectedHome.Control",
                                      "name":"TurnOnRequest",
                                      "payloadVersion":"2",
                                      "messageId":"81c27978-cc0c-4ae8-b1bc-09510c597a60"
                                   },
                                   "payload":{
                                      "accessToken":"BLA BLA BLA",
                                      "appliance":{
                                         "applianceId":"Bro-Deckenlampe",
                                         "additionalApplianceDetails":{
                                         }
                                      }
                                   }
                                }
                                Code:
                                {
                                   "header":{
                                      "namespace":"Alexa.ConnectedHome.Control",
                                      "name":"TurnOffRequest",
                                      "payloadVersion":"2",
                                      "messageId":"81c27978-cc0c-4ae8-b1bc-09510c597a60"
                                   },
                                   "payload":{
                                      "accessToken":"BLA BLA BLA",
                                      "appliance":{
                                         "applianceId":"Bro-Deckenlampe",
                                         "additionalApplianceDetails":{
                                         }
                                      }
                                   }
                                }
                                Wichtig ist, dass ihr unter "applianceID" die richtige ID einsetzt. Diese erfahrt ihr aus dem Ergebnis der Discovery Abfrage.

                                Ich hoffe der ein oder andere kann eventuell nachstellen, was ich hier beschreibe. Dadurch haben wir vielleicht ein bisschen schneller den Source Code verbessert.

                                Viel Erfolg beim Testen an alle,

                                Grüße Patrick

                                Kommentar

                                Lädt...
                                X