Miele@Home XKM 3100W Protokollanalyse

@miele Team: Das finde ich toll, dass ihr euch hier einklinkt.
Ich habe auch mehrere Geräte mit dem XKM 3100 W und würde diese gern direkt (ohne das XGW 3000) ansprechen.

Wäre es evtl. denkbar eine Art Schnittstellen-Doku zu veröffentlichen? Das spart etwas Arbeit derer, die das hier reverse engineeren. Ideal wäre natürlich eine selbstdokumentierte Webschnittselle wie sie z.B. Swagger anbietet (das wäre auch was für’s XGW3000).

@miele-Team: gibt es schon was neues? Könnt ihr mal einen kurzen Status abgeben? Vielen Dank!

Hallo!

(Disclaimer: Mein Deutsch ist sehr slecht. Ich will doch versuchen, Deutsch zu schreiben, aus respect für sie allen in dieser forum.)

@phenx: Ich habe gesehen, dass Sie Eclipse benutzen hat. Sie wissen ganz sicher, dass Eclipse auch der Platform für OpenHAB ist? Es wäre sehr gut ob es möglich war, eine bindung für OpenHAB zu schreiben. Wäre es OK für Sie wenn jemand ihr kode anwendet, um eine bindung zu schreiben?

Gibt’s jemand hier im forum der schon weiss wie man OpenHAB bindungen schreiben kann? Ich kann gern versuchen, aber ich kenne kaum Java, Eclipse, OSGi und so weiter. Darum wird es monaten dauern, wenn ich es schreiben versucht. (Ich tue es doch gern, und wenn ich kein respons auf dies krieg, werde ich es versuchen. )

Ich habe auch drei Maschinen von Miele mit W-Lan und hätte auch großes Interesse an eine Integration in Openhab2.
Gibt es da schon Neuigkeiten?

Viele Grüße

Hallo Zusammen

Seit dieser Woche gibt es die Open Beta von der 3rd Party Miele API. Das heisst, alle Geräte, welche ihr in der Miele@home app habt, könnt ihr über die API abfragen.
Die Informationen dazu findet ihr auf: Miele 3rd party API

Ich arbeite derzeit an einer Home Assistant Komponente, welche das umsetzt. Der Thread dazu ist hier, falls jemand gedenkt mitzumachen: Miele@home, miele@mobile component - Development - Home Assistant Community

Viele Grüsse
Roman

Na super. Da hat uns Mile ja schön veräppelt! :mad:
Als sie gesehen haben dass mischo22 ihre App reverse engineered hat, haben sie schnell geschrieben dass wir bloß warten sollen, weil sie ja selbst eine API schreiben.

Dann über ein Jahr später veröffentlichen sie endliche eine API und sie funktioniert nur in Verbindung mit der Cloud! :banghead:

Ich habe schon viel Geld für das WLAN-Modul ausgegeben und jetzt soll ich auch noch mit meinen Daten zahlen?!
Nein danke!

Ich möchte einfach nicht, dass Mile genau weiß wann wie viel und wie lange ich wasche. Alu Hut auf Geschweige denn die NSA das BKA und jeder Hacker der da beim Mile ein und aus geht.

Ich werde in meinem Urlaub versuchen auf die Arbeit von mischo22 aufzubauen und eine Offline API schreiben. Aber so link wie Mile zu seien scheint, traue ich ihnen zu, dass sie mittlerweile die Verschlüsselung geändert haben um uns auszusperren. Mal sehen.

Eins ist klar. Das war meine letzte Mile Maschine!

1 „Gefällt mir“

Für die meisten Nutzer bzw. Entwickler dürfte es von Vorteil sein, unkompliziert auf die Daten von außerhalb des LAN zugreifen zu können. IPS ist da eher untypisch.

Okay … dann ist schon mal klar, welcher Hersteller mir NICHT ins Haus kommt. Meinen Kunden werde ich dann wohl auch etwas anderes empfehlen müssen.

Schade Miele, das klang anfangs alles richtig gut.

1 „Gefällt mir“

Hey Leute,

das ganze hat mir doch keine Ruhe gelassen. :o
Ich habe mal schnell eine Art Gateway in node.js zusammengebastelt: GitHub - Ich-Eben/MieleXKM3100WGateway

Damit bekommt man Zugriff auf seine Miele Geräte ohne sich mit der Verschlüsselung rumschlagen zu müssen.
Danke an mischo22 und phenx! Ihr habt da echt tolle reverse engineering Arbeit geleistet!

Ich verstehen nicht warum Miele - die ja schon vorhandene - API nicht einfach dokumentiert. Eigentlich scheint mir das Ganze nämlich ziemlich solide.

Na ja, ich geh jetzt besser schlafen. Bei Fragen melde ich mich morgen noch mal.

Ich nochmal.

Habe noch ein wenig rum probiert und festgestellt, dass das XKM3100W wohl nur einen Verbindungspartner gleichzeitig akzeptiert. Das bedeutet, wenn ihr die groupId / den groupKey der app nicht kennt, müsst ihr das XKM3100W auf Werkseinstellungen zurück setzen. Das geht einfach über das Menü eures Miele Geräts. (Siehe Bedienungsanleitung)

Nachdem ihr euer Miele Gerät wieder in euer WLAN eingebunden habt, (entweder über die miele@home app oder per WPS) gibt es nun zwei Möglichkeiten:

1. Ihr installiert euch die App Packet Capture und schneidet die Kommunikation zwischen Miele App und Gerät mit. Im ersten Paket welches die App an das Gerät schickt findet ihr die benötigte ID und den Key. Diese könnt ihr nun in der datei mielgeGateway.js in Zeile 19 und 20 eintragen und danach die API nutzen.

oder

2. Ihr nutzt die init Funktion des Gateways um ihn direkt bei dem Miele gerät zu registrieren. Dann könnt ihr euch aber nicht mehr mit der miele@home app mit dem Gerät verbinden, bis ihr das XKM3100W wieder auf Werkseinstellungen setzt.

Installation Gateway:
Um das Gateway ausführen zu können benötigt ihr node.js (google: node.js installieren).
Laded euch die Dateien mieleGateway.js und package.json von Github herunter und kopiert sie in einen Ordner.
Danach mit gedrückter Shift Taste einen Rechtsklick auf den Hintergrund von diesem Ordner.
Eingabeaufforderung hier öffnen
Nun tippt ihr „npm install“ ein.
Danach könnt ihr das Gateway mit „node mieleGateway.js“ starten.
Wenn ihr nun im Webbrowser „http://127.0.0.1:3000/explore/<IP-ADRESSE-MIELE_GERÄT>/“ eingebt, (die IP-Adresse eures Miele Gerätes findet ihr z.B. in eurem Router heraus) könnt ihr euch die Daten des Gerätes anzeigen lassen.
Wenn ein Fehler angezeigt wird, stimmt die groupId / der Key nicht und ihr müsst erst doch ein init ausführen (Erklärung siehe oben).
Um ein init auszuführen einfach das Gateway starten und „http://127.0.0.1:3000/init/<IP-ADRESSE-MIELE_GERÄT>/“ im Browser eingeben. Dort sollte dann so etwas zurück kommen:

[{"Success":{"GroupID":"0000000000000000"}},{"Success":{"GroupKey":"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"}}]

Außerdem habe ich noch herausgefunden wie man das Miele Gerät ohne die Miele@home App in sein WLAN einbinden kann:

GET /WLAN/Scan/ HTTP/1.1 
Accept: application/vnd.miele.v1 + json 
Connection: keep-alive 
Host: 192.168.1.1

HTTP/1.1 200 OK 
Content-Type: application/vnd.miele.v1+json; charset=utf-8 
access-control-allow-origin:* 
access-control-allow-headers:Authorization 
Date: Tue, 01 Jan 2013 00:04:00 GMT 
Content-Length:164

{
 "Result":
 [
  {"SSID":"FreeCookies", "Sec":"WPA", "RSSI":-86},
  {"SSID":"BlaBla", "Sec":"WPA", "RSSI":-67},
  {"SSID":"ItHurtsWhenIP", "Sec":"WPA", "RSSI":-83}
 ]
}

PUT /WLAN/ HTTP/1.1 
Accept: application/vnd.miele.v1 + json 
Content-Type: application / vnd.miele.v1 + json; charset = utf - 8 
Content-Length: 55 
Host: 192.168.1.1

{"SSID":"BlaBla","Sec":2,"Key":"PASSWORD"}

[
 {"Success":{"SSID":"meinz"}},
 {"Success":{"Sec":"WPA"}},
 {"Success":{"Key":"***"}}
]

Mal schauen, wenn ich ganz viel Langeweile habe, schreibe ich dafür vielleicht noch eine App.

Hattest du hier noch Einstellungen in Handy vornehmen müssen? Sobalt ich „Packet Capture“ lauschen lassen geht nichts mehr (Daten kommen eventuell nicht durch den VPN) Certificate-status ist aber ok. (Samsung S8 mit aktuellem Android)

Du meinst damit das erste Paket aus der Prozedur „Gerät hinzufügen“ in der Miele-App?

Hat das mal jemand mit Packet Capture gemacht und kann mir ein paar Tips geben?

Wenn jemand interessiert ist, habe ich schon ein script publiziert, dass sprichst mit der Miele cloud service, und publiziert die dateien durch MQTT. Das script wendet das offizielle API an, und ist hier verfügbar: GitHub - oklona/Miele-MQTT: A very simple script to read data from Miele@home cloud services, and publish using Mosquitto MQTT

Habe dein Skript ausprobiert, nachdem ich die ClientID und ClientKey von Miele bekommen habe. Läuft Prima! Ich versuche jetzt mal nach und nach die einzelnen Statuscodes für eine Waschmaschine zu bekommen. In deinem Skript ist ja ein Geschirrspüler enthalten.

Ja,das ist recht. Ich habe nur ein Geschirrspüler. Du hast die „-d“ Switch probiert? Es ist ein bisschen Arbeit, aber du kannst
im Mobil-app volgen, und sehen, welche beschreibungen gibt. Dann, jedenmahls als der status im App ist verändert, kannst du nochmal der „-d“ Switch versuchen. Danach sollte es ganz einfach sein, die Koden zu „übersetzen“.

Moin,

hat schon mal jemand versucht das Gateway auf einen Linux Rechner zum laufen zu bekommen?

Ich bekomme folgende Meldung:

/home/miele/mieleGateway.js:45
    let match = resourcePath.match(regex);
    ^^^

SyntaxError: Block-scoped declarations (let, const, function, class) not yet supported outside strict mode
    at exports.runInThisContext (vm.js:53:16)
    at Module._compile (module.js:374:25)
    at Object.Module._extensions..js (module.js:417:10)
    at Module.load (module.js:344:32)
    at Function.Module._load (module.js:301:12)
    at Function.Module.runMain (module.js:442:10)
    at startup (node.js:136:18)
    at node.js:966:3

Jemand einen Idee?

Hm nu bin ich schon etwas weiter die Notes Version war wohl zu alt…


->http://192.168.2.40:3000/init/192.168.2.244

{
  "error": 403
}

 ok: false,
     redirect: false,
     clientError: true,
     serverError: false,
     error:
      { Error: cannot PUT /Security/Commissioning/ (403)
          at Response.toError (/home/miele/node_modules/superagent/lib/node/response.js:94:15)
          at ResponseBase._setStatusProperties (/home/miele/node_modules/superagent/lib/response-base.js:123:16)
          at new Response (/home/miele/node_modules/superagent/lib/node/response.js:41:8)
          at Request._emitResponse (/home/miele/node_modules/superagent/lib/node/index.js:752:20)
          at parser (/home/miele/node_modules/superagent/lib/node/index.js:916:38)
          at IncomingMessage.res.on (/home/miele/node_modules/superagent/lib/node/parsers/json.js:19:7)
          at IncomingMessage.emit (events.js:187:15)
          at endReadableNT (_stream_readable.js:1094:12)
          at process._tickCallback (internal/process/next_tick.js:63:19)
        status: 403,
        text: '',
        method: 'PUT',
        path: '/Security/Commissioning/' },
     created: false,


Hallo zusammen

Ich versuche gerade das PHP Skript von oklona auf meinem Raspi zum laufen zu bringen.
Kann mir jemand sagen was mit „Type the full path to your mosquitto_pub binary:“ gemeint ist?:confused:

Besten Dank und Gruss

Hallo zusammen

Dank dem Skript von oklona https://github.com/oklona/Miele-MQTThabe ich mit kleinen Anpassungen die Offizielle API in IPS zum laufen gebracht.:loveips:
Was Ihr damit mach ist euch überlassen, für mich funktioniert es erstmals :slight_smile: sicher nicht perfekt, aber besser als nichts
Einfach euren Benutzernamen (email) und euer Passwort eingeben, zudem benötigt Ihr die „personal Client_Id“ und den „Client_Secret“ den ihr euch unter „developer@miele.com“ beschaffen könnt.

<?
$content="application/x-www-form-urlencoded";
$userid="euere email";
$password="euer pwd";
$country='ch-ch'; // eure Region z.b. DE-DE usw
$client_id="client ID";
$client_secret="client_secret";
$authorization='';
$url="https://api.mcs3.miele.com/thirdparty/auth";
$postdata='email=' . urlencode($userid) . '&password=' . urlencode($password) . '&redirect_uri=%2Fv1%2Fdevices&state=login&response_type=code&client_id=' . $client_id . '&vgInformationSelector=' . $country;
	
$method="POST";
		
$data=getRESTData($url,$postdata,$method,$content);

//var_dump ($data);


if (is_array($data) == FALSE){
	$params=(explode('?',$data))[1];
	foreach (explode('&', $params) as $part) {
		$param=explode("=",$part);	
			if(strstr($param[0],'code') <> FALSE ) {
			$code=$param[1];
			}
	}
}

//echo ($code);



if (strlen($code) >> 0 ) {
	$url='https://api.mcs3.miele.com/thirdparty/token?client_id=' . urlencode($client_id) . '&client_secret=' . $client_secret . '&code=' . $code . '&redirect_uri=%2Fv1%2Fdevices&grant_type=authorization_code&state=token';
	$postdata="";
	$method='POST';
	$data=getRESTData($url,$postdata,$method,$content);
	$access_token = $data["access_token"];
	$refresh_token = $data["refresh_token"];
	$tokenscreated = true;
}

//echo ($tokenscreated);


if (strlen($access_token) >> 0 ) {
	$url='https://api.mcs3.miele.com/v1/devices/';
	$authorization='Bearer ' . $access_token;
	$method='GET';
	$data=getRESTData($url,'',$method,'',$authorization);
	if (array_search("Unauthorized",$data) != "" ) {
		$authorization='Bearer ' . $config['access_token'];
		$method='GET';
		$data=getRESTData($url,'',$method,'',$authorization);
	}
	var_dump($data);
}


foreach ($data as $appliance) {
		$appliance_id=$appliance['ident']['deviceIdentLabel']['fabNumber'];
		echo "Data for appliance: " . $appliance_id . PHP_EOL;
		$appliance_type=$appliance['ident']['type']['value_localized'];
		switch ($appliance_type) {
			case "Clothes Dryer":
				$programStatus=$appliance['state']['status']['value_localized'];
				$programType= $appliance['state']['programType']['value_raw'];
				$programPhaseRaw=$appliance['state']['programPhase']['value_raw'];
				$dryingStep=$appliance['state']['dryingStep']['value_localized'];
				$techType=$appliance['ident']['deviceIdentLabel']['techType'];
				switch ($programPhaseRaw) {
					case "512":
						// Purpose unknown, observed when programmed (without phase) and off.
						$programPhase="Not running";
						break;
					case "513":
						$programPhase="Programm läuft";
						break;
					case "514":
						$programPhase="Trocknen";
						break;
					case "515":
						$programPhase="Machine Iron";
						break;
					case "516":
						$programPhase="Bügelfeucht";
						break;
					case "517":
						$programPhase="Normal";
						break;
					case "518":
						$programPhase="Normal Plus";
						break;
					case "519":
						$programPhase="Abkühlen";
						break;
					case "520":
						$programPhase="Bügelfeucht";
						break;
					case "521":
						$programPhase="Anti-crease";
						break;
					case "522":
						$programPhase="Fertig";
						break;
					case "523":
						$programPhase="Extra Trocken";
						break;
					case "524":
						$programPhase="Bügelfeucht";
						break;
					case "526":
						$programPhase="Befeuchten";
						break;
					case "528":
						$programPhase="Zeitgesteuertes Trocknen";
						break;
					case "529":
						$programPhase="Warmluft";
						break;
					case "530":
						$programPhase="Dampfglätten";
						break;
					case "531":
						$programPhase="Comfort Cooling";
						break;
					case "532":
						$programPhase="Rinse out lint";
						break;
					case "533":
						$programPhase="Rinses";
						break;
					case "534":
						$programPhase="Smoothing";
						break;
					case "538":
						$programPhase="Slightly Dry";
						break;						
					case "539":
						$programPhase="Safety Cooling";
						break;
					default:
						$programPhase="Unknown: " . $programPhaseRaw;
					break;
				}
				$timeleft=sprintf("%'.02d:%'.02d",$appliance['state']['remainingTime'][0],$appliance['state']['remainingTime'][1]);
				$timerunning=sprintf("%'.02d:%'.02d",$appliance['state']['elapsedTime'][0],$appliance['state']['elapsedTime'][1]);
				echo "Appliance type: " . $appliance_type . PHP_EOL;
				echo "Program status: " . $programStatus . PHP_EOL;
				echo "Program type: " . $programType . PHP_EOL;
				echo "Program phase: " . $programPhase . PHP_EOL;
				echo "Time left: " . $timeleft . PHP_EOL;
				echo "Time elapsed: " . $timerunning . PHP_EOL;
				echo "techType: " . $techType . PHP_EOL;
				echo "Prog: " .$dryingStep . PHP_EOL . PHP_EOL;
				break;
			default:
				echo "Appliance type " . $appliance_type . " is not defined. Please define it, or send information to have it added." . PHP_EOL;
				break;
		}
	}










function getRESTData($url,$postdata,$method,$content,$authorization='')
{
	$ch = curl_init($url);                                                                      
	curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);                                                                     
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
	$headers=array();
	if(strlen($authorization)>> 0 ) {
		array_push($headers, 'Authorization: ' . $authorization);
	}
	
	if(strlen($content) >> 0 ) {
		array_push($headers, 'Content-Type: ' . $content);
	}
	
	
	curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
	if ( strcmp($method,"POST" ) == 0 ) {
		curl_setopt($ch,CURLOPT_POSTFIELDS, $postdata);
	}
	$result = curl_exec($ch);
	//echo($result);
	
	if (curl_getinfo($ch,CURLINFO_RESPONSE_CODE) == 302 ) {
		$returndata=curl_getinfo($ch,CURLINFO_REDIRECT_URL);
		//var_dump ($returndata);
	}
	else {
		$returndata=json_decode($result,true);
		//var_dump ($returndata);
	}
	
 return $returndata;
}
?>

271 Beiträge wurden in ein existierendes Thema verschoben: [Modul] Miele@Home