Edimax SP-2101W V3 Schaltsteckdose

Da der SMA Sunny Home Manager nur AVM und Edimax Steckdosen unterstützt, habe ich mir mal jeweils eine bestellt.
Die AVM Fritz!DECT Steckdose lässt sich auch in IPS integrieren. Nur mit der Edimax geht das wohl nicht mehr so einfach wie hier Schaltsteckdose EDIMAX SP-1101W mit IPS. Diese und auch ältere mit neuster Firmware nutzt nun wohl Digest Authentifizierung zur Anmeldung und Kommunikation.
Hat hier schon jemand die SP-2101W V3 im Einsatz und in IPS auch eingebunden?
Auf dem Datenblatt steht zwar ein Hinweis auf eine API, aber diese wird lt. Edimax Support wohl nur „Firmen“ zugänglich gemacht, wofür dann erst einmal eine Geheimhaltungserklärung unterschrieben werden muss.
Ob und wie sich das dann in IPS integrieren lässt, kann @paresy vielleicht was zu sagen. Zumal php-code ja nicht gerade „geheim“ ist.
Da es hier sehr wenig Einträge zum Thema Edimax Steckdosen gibt, nehme ich mal an, dass die nicht groß im Einsatz sind.

Gruß
Rainer

Wir unterstützen über PHP/cURL seit langem Digest Authentication und seit der 6.0 auch über die Sys_GetURLContent Befehle. Daran sollte es also nicht liegen. Frag bei Edimax doch trotzdem mal an. Mittlerweile gehören Protokollen zum guten Produkt. Die Zeiten in der Protokolle wie Staatsgeheimnisse gehütet wurden sind zum Glück eher vorbei :slight_smile:

paresy

Hallo @paresy, die Antwort vom Edimax Support Deutschland habe ich ja schon:

„die API ist eigentlich nur für Firmen nach einsenden des angehängten NDA verfügbar.“

ich kann dir die Email und das vierseitige Formular gerne weiterleiten - das ist eh komplett in englisch. Da bräuchte ich erstmal einen Anwalt, der mir erklärt, was ich da unterschreibe :frowning: :wink:

Ich habe ja auch schon mit cURL angefangen und bekomme da auch schon die erste Antwort. Aber wie sich dann die Antwort darauf zusammen setzt, ist mir nicht klar. Daher dachte ich, die API könnte da helfen.

Rainer

Hi Rainer,

frag doch mal bei denen ohne das Formular an. Vielleicht geht ja was.

Ich werde leider nicht dazu kommen mich um solch ein Formular zu kümmern, da das Gerät für uns leider nicht auf der Roadmap ist. (Und wenn ich das Protokoll bekomme, dürfte ich es dir ja nicht weitergeben :wink: )

paresy

Hi paresy,

ich kann es ja mal versuchen, vielleicht geschehen ja noch Wunder und die API ist kein Staatsgeheimnis :wink:
Verstehe auch, da so ein „unbedeutendes Gerät“ nicht auf eurer Roadmap steht - scheint im IPS Umfeld wohl auch nicht groß im Einsatz zu sein. Daher auch meine Eingangsfrage, wer das sonst noch verwendet. Aber vielleicht kommt da ja noch was.

Ich bin jetzt auch nicht darauf angewiesen. Habe es ja nur zum Testen mit SMA gekauft, was schon etwas „hakelig“ in der Einbindung war.

ohne Hilfe von Edimax - aber mit Google - bin ja schon mal so weit gekommen, dass ich eine Antwort vom Gerät bekomme:

<?php

$url = "http://192.168.10.132:10000/smartplug.cgi";

$xml = '<?xml version="1.0" encoding="UTF8"?><SMARTPLUG id="edimax"><CMD id="get"><Device.System.Power.State></Device.System.Power.State></CMD></SMARTPLUG>';

$ch = curl_init();
curl_setopt($ch,CURLOPT_URL, $url);
curl_setopt($ch,CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch,CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch,CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch,CURLOPT_FOLLOWLOCATION, false);
curl_setopt($ch,CURLOPT_TIMEOUT, 30);
curl_setopt($ch,CURLOPT_CONNECTTIMEOUT, 30);
curl_setopt($ch,CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_HEADER, 1);
$first_response = curl_exec($ch);
$info = curl_getinfo($ch);
var_dump($first_response);

die 1. Antwort darauf ist dann:

"HTTP/1.0 401 Unauthorized
WWW-Authenticate: Digest realm="myPLUG_XX",nonce="xxxxxxxxxxxxxxxxxxxxxxxxxxxx",qop="auth"
Content-Length: 0

"

wenn ich darauf antworte

<?php
preg_match('/WWW-Authenticate: Digest (.*)/', $first_response, $matches);

$username = 'admin';
$password = 'xxxxxxxxxxxx';

$xml = '<?xml version="1.0" encoding="UTF8"?><SMARTPLUG id="edimax"><CMD id="get"><Device.System.Power.State></Device.System.Power.State></CMD></SMARTPLUG>';

if(!empty($matches))
{
  $auth_header = $matches[1];
  $auth_header_array = explode(',', $auth_header);
  $parsed = array();

  foreach ($auth_header_array as $pair)
  {
    $vals = explode('=', $pair);
    $parsed[trim($vals[0])] = trim($vals[1], '" ');
  }

  $response_realm     = (isset($parsed['realm'])) ? $parsed['realm'] : "";
  $response_nonce     = (isset($parsed['nonce'])) ? $parsed['nonce'] : "";
  $response_qop       = (isset($parsed['qop'])) ? $parsed['qop'] : "";

  $authenticate1 = md5($username.":".$response_realm.":".$password);
  $authenticate2 = md5("POST:".$url);

  $authenticate_response = md5($authenticate1.":".$response_nonce.":".$authenticate2);

  $request = sprintf('Authorization: Digest username="%s", realm="%s", nonce="%s", uri="%s", response="%s"',
  $username, $response_realm, $response_nonce, $url, $authenticate_response);

  $request_header = array($request);
  $request_header[] = 'Content-Type:application/xml';

  $ch = curl_init();
  curl_setopt($ch,CURLOPT_URL, $url);
  curl_setopt($ch,CURLOPT_SSL_VERIFYPEER, false);
  curl_setopt($ch,CURLOPT_SSL_VERIFYHOST, false);
  curl_setopt($ch,CURLOPT_RETURNTRANSFER, 1);
  curl_setopt($ch,CURLOPT_FOLLOWLOCATION, false);
  curl_setopt($ch,CURLOPT_TIMEOUT, 30);
  curl_setopt($ch,CURLOPT_CONNECTTIMEOUT, 30);
  curl_setopt($ch,CURLOPT_CUSTOMREQUEST, "POST");
  curl_setopt($ch, CURLOPT_POSTFIELDS, "xmlRequest=".$xml);
  curl_setopt($ch, CURLOPT_HTTPHEADER, $request_header);

  $result['response']         = curl_exec($ch);
  $result['info']             = curl_getinfo ($ch);
  $result['info']['errno']    = curl_errno($ch);
  $result['info']['errmsg']   = curl_error($ch); 

  var_dump($result);
}

bekomme ich das:

array(2) {
  ["response"]=>
  string(0) ""
  ["info"]=>
  array(39) {
    ["url"]=>
    string(41) "http://192.168.10.132:10000/smartplug.cgi"
    ["content_type"]=>
    NULL
    ["http_code"]=>
    int(401)
    ["header_size"]=>
    int(144)
    ["request_size"]=>
    int(496)
    ["filetime"]=>
    int(-1)
    ["ssl_verify_result"]=>
    int(0)
    ["redirect_count"]=>
    int(0)
    ["total_time"]=>
    float(0,128037)
    ["namelookup_time"]=>
    float(9,5E-5)
    ["connect_time"]=>
    float(0,002819)
    ["pretransfer_time"]=>
    float(0,00303)
    ["size_upload"]=>
    float(158)
    ["size_download"]=>
    float(0)
    ["speed_download"]=>
    float(0)
    ["speed_upload"]=>
    float(1234)
    ["download_content_length"]=>
    float(0)
    ["upload_content_length"]=>
    float(158)
    ["starttransfer_time"]=>
    float(0,127969)
    ["redirect_time"]=>
    float(0)
    ["redirect_url"]=>
    string(0) ""
    ["primary_ip"]=>
    string(14) "192.168.10.132"
    ["certinfo"]=>
    array(0) {
    }
    ["primary_port"]=>
    int(10000)
    ["local_ip"]=>
    string(13) "192.168.10.27"
    ["local_port"]=>
    int(63161)
    ["http_version"]=>
    int(1)
    ["protocol"]=>
    int(1)
    ["ssl_verifyresult"]=>
    int(0)
    ["scheme"]=>
    string(4) "HTTP"
    ["appconnect_time_us"]=>
    int(0)
    ["connect_time_us"]=>
    int(2819)
    ["namelookup_time_us"]=>
    int(95)
    ["pretransfer_time_us"]=>
    int(3030)
    ["redirect_time_us"]=>
    int(0)
    ["starttransfer_time_us"]=>
    int(127969)
    ["total_time_us"]=>
    int(128037)
    ["errno"]=>
    int(0)
    ["errmsg"]=>
    string(0) ""
  }
}

hier scheint wohl in der cURL Konfiguration noch was nicht zu passen. Da fehlen mir aber die Kenntnisse (oder auch die API)
Vielleicht kann mir da jemand weiterhelfen.
Danke

und wie schon geschrieben, die Zeile sind auch nur Ergebnis meiner Suche im Internet.

Gruß
Rainer

Nur ein Tipp:
Curl kann Digest von sich aus.
Da musst du nix per Hand am Header machen.
Michael

Danke Michael,

da fehlen mir aber leider die tieferen Curl- und php-Kenntnisse.
Das was ich da bisher habe, habe ich mit Hilfe von Google zusammengetragen.
Und Edimax selbst ist da leider auch keine Hilfe. Thema API.

zu Curl, Digest und php von der Client-Seite findet man nicht ganz so viel, ist das meiste dann für die Server-Seite.
Wie das mit Curl und Digest standardmäßig aussehen soll, habe ich noch nicht gefunden.
Und ob sich Edimax da auch dran hält, weiß ich dann auch noch nicht :frowning:
Daher die Frage nach Beispielen, wie Curl mit Digest zu machen ist. Oder auch Tipps, was ich ggf. an dem Code anpassen/ändern muss.

Rainer

Ich habe dir hier mal etwas zusammenkopiert aus dem Original-Thema, nur jetzt mit HTTP-Digest.
Vielleicht hilft das ja :slight_smile:

$username = 'admin';
$password = 'xxxxxxxxxxxx';
$url = "http://192.168.10.132:10000/smartplug.cgi";
$xml = '<?xml version="1.0" encoding="UTF8"?><SMARTPLUG id="edimax"><CMD id="get"><Device.System.Power.State></Device.System.Power.State></CMD></SMARTPLUG>';

        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST);
        curl_setopt($ch, CURLOPT_USERPWD, $username. ':' . $password);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, "xmlRequest=" . $xml);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
        curl_setopt($ch,CURLOPT_TIMEOUT, 10);
        $data = curl_exec($ch);
        curl_close($ch);
        $r = json_decode(json_encode(simplexml_load_string($data)), true);

var_dump($r);

Michael

mit dem Skript aus dem Original-Thema hatte ich ja angefangen. Da kam immer „nichts“ zurück.
Mit deinen Änderungen bekomme ich auch nur „false“ für $r, $data = „“.
Deshalb war ich so überrascht, dass auf meine erste Digest Anfrage dann die Antwort mit Digest kam.
Da scheint Curl doch noch was zu fehlen?

Rainer

Kannst ja erstmal direkt ein
var_dump($data); nach dem curl_exec einbauen.
Und sonst noch damit ergänzen, dann kommt aber auch die Antworten inkl. Header im $data an.

curl_setopt($ch, CURLOPT_HEADER, true);

Michael

habe das mal ergänzt und bekomme in $data 2x

beim Erstellen von $r gibt’s dann natürlich Fehler, da kein xml zurück kommt.

Die gleiche Antwort (aber nur einmal) bekomme ich auch im 2. Teil von meinem Skript, wenn ich da den Header noch ergänze.
Da kommt noch nicht das, was Edimax erwartet.
Username und Password habe ich auch schon die aus der App ohne Erfolg probiert.

Bei Edimax habe ich noch mal angefragt, ob die API wirklich nur gegen eine 4seitige englische-sprachige Geheimhaltungserklärung erhältlich ist (in Zeiten von Smart Home Integration). Bin auf die Antwort gespannt.

Es muss jetzt nicht unbedingt Edimax sein, hatte mich halt nur im Zusammenhang mit der Solaranlage von SMA interessiert.

Vielleicht finden sich ja noch ein paar Ideen.

Rainer