RWE Smarthome API

RWE Smarthome überzeugt mit gut gestalteten Komponenten, die einfach zusammen funktionieren. Leider ist RWE aber alles andere als offen, sodass sich das System nicht erweitern oder mit anderen Systemen kombinieren lässt. Einige findige Entwickler haben die Schnittstelle zwischen der RWE Smarthome Silverlight-App und der Zentrale entschlüsselt und auf dieser Basis eigene Libraries entwickelt, die einige interessante Erweiterungen erlauben.

An dieser Stelle versuche ich die XML-Kommunikation von RWE Smarthome zu dokumentieren. Da ich nur einen Teil der verfügbaren Komponenten im Einsatz habe, kann ich leider nicht alle Varianten in der Kommunikation mitlesen und freue mich über weitere Mithilfe!

Achtung: Diese Seite ist noch im Anfangsstadium und deshalb äußerst unvollständig….

LoginRequest

Wird zum Login verwendet. Hier werden Benutzername/Passwort übergeben, die man auch zum Anmelden in der RWE Smarthome Silverlight App verwendet. Beim Passwort ist zu beachten, dass es verschlüsselt eingetragen werden muss. Dazu wird aus dem Passwort ein SHA-256-Hash gebildet und dieser Base64-enkodiert. In Java sieht das so aus:

String plainPassword = "password";
MessageDigest md = MessageDigest.getInstance("SHA-256");
md.update(plainPassword.getBytes());
byte byteData[] = md.digest();
String encodedPassword = new String(Base64.encodeBase64(byteData));

Request (https://smarthome02.local/cmd):

POST /cmd HTTP/1.1
Host: smarthome02.local
Referer: https://smarthome.blob.core.windows.net/silverlight/latest/application/RWE.SmartHome.UI.Shell.xap?ignore=1.70.365.0
Proxy-Connection: keep-alive
Accept-Encoding: identity
Content-Type: text/xml
Content-Length: 229
Connection: keep-alive
Accept: */*
Accept-Language: de-de
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/600.1.25 (KHTML, like Gecko)

<BaseRequest xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="LoginRequest" Version="1.70" RequestId="59d4ef67-a496-bd21-67db-ff5fecadf064" UserName="username" Password="verschuesseltes_passwort"/>

Response:

Hieran ist besonders interessant die SessionId, die für nachfolgende Abfragen verwendet werden muss. Außerdem interessant ist die CurrentConfigurationVersion, die sich mit jeder Konfigurationsänderung erhöht. Darüber hat man bspw. die Möglichkeit, nur dann die Konfiguration neu zu laden, wenn sich die Versionsnummer geändert hat. Das ist je nachdem auch ratsam, da das Laden der gesamten Konfiguration mehrere Sekunden dauert.

HTTP/1.1 200 OK
ClientId: 26dc14d3-3f94-4b67-a9ad-779898336c1d
Content-Length: 444
Connection: Keep-Alive

<BaseResponse xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="LoginResponse" Version="1.70" CorrespondingRequestId="59d4ef67-a496-bd21-67db-ff5fecadf064" SessionId="e75718e7-999f-4b19-b186-a34c891c938c" CurrentConfigurationVersion="105" ShcOperatingMode="Normal" TokenHash="f4f4071ca49da0bad2622711e0b8d0bf"><UserRoles><ShcRole><Id>f3ebfaea-e293-47c3-835c-0e429fed8fdf</Id><Name>Owner</Name></ShcRole></UserRoles></BaseResponse>

Notification System

Damit man über Änderungen der Devices informiert wird, kann man über einen NotificationRequest abfragen, ob Änderungsbenachrichtigungen (sog. Notifications) vorliegen. Damit dies funktioniert, muss man sich für Notifications erstmal anmelden.

NotificationRequest – Subscribe

Fragt man die Zentrale nach Notifications, ohne sich vorher für diese zu registrieren, liefert die Zentrale schlicht keine Notifications zurück. Nun kann man unterschiedliche Notifications abonnieren (diese sind mir zumindest bekannt):

  • ConfigurationChanges
  • Calibration
  • CustomApplication
  • DeviceStateChanges
  • DeploymentChanges
  • MessageUpdate

Ich habe mir derzeit nur DeviceStateChanges angesehen und nehme dies hier auch als Beispiel (die anderen Varianten werden genauso abonniert).

Request (https://smarthome02.local/cmd):

POST /cmd HTTP/1.1
Host: smarthome02.local
Referer: https://smarthome.blob.core.windows.net/silverlight/latest/application/RWE.SmartHome.UI.Shell.xap?ignore=1.70.365.0
ClientId: 26dc14d3-3f94-4b67-a9ad-779898336c1d
Proxy-Connection: keep-alive
Accept-Encoding: identity
Content-Type: text/xml
Content-Length: 301
Connection: keep-alive
Accept: */*
Accept-Language: de-de
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/600.1.25 (KHTML, like Gecko)

<BaseRequest xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="NotificationRequest" Version="1.70" RequestId="a7b419e0-54da-2120-abae-bf4f892c5ffd" SessionId="e75718e7-999f-4b19-b186-a34c891c938c">
  <Action>Subscribe</Action>
  <NotificationType>DeviceStateChanges</NotificationType>
</BaseRequest>

Zurück kommt dann eine AcknowledgeResponse, die das Abonnieren bestätigt.

Response:

HTTP/1.1 200 OK
ClientId: 26dc14d3-3f94-4b67-a9ad-779898336c1d
Content-Length: 178
Connection: Keep-Alive

<BaseResponse xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="AcknowledgeResponse" Version="1.70" CorrespondingRequestId="a7b419e0-54da-2120-abae-bf4f892c5ffd" />

 

Notifications abfragen

Hat man sich für Notifications registriert, so kann man diese abfragen. Gibt es neue Notifications, so werden diese als Ergebnis angezeigt. In dem folgenden Beispiel werden die Notifications abgefragt, nachdem zuvor ein Unterputzlichtschalter und ein Wandtaster, der eine Variable schaltet betätigt wurden.

Notifications werden über das Kommando /upd abgerufen.

Request (https://smarthome02.local/upd):

POST /upd HTTP/1.1
Host: smarthome02.local
Referer: https://smarthome.blob.core.windows.net/silverlight/latest/application/RWE.SmartHome.UI.Shell.xap?ignore=1.70.365.0
ClientId: 26dc14d3-3f94-4b67-a9ad-779898336c1d
Proxy-Connection: keep-alive
Accept-Encoding: identity
Content-Type: text/xml
Content-Length: 3
Connection: keep-alive
Accept: */*
Accept-Language: de-de
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/600.1.25 (KHTML, like Gecko)

upd

Response:

HTTP/1.1 200 OK
ClientId: 26dc14d3-3f94-4b67-a9ad-779898336c1d
Content-Length: 940
Connection: Keep-Alive

<?xml version="1.0"?>
<NotificationList xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" NotificationListId="f900fc4d-06e7-4c77-99ce-3151238a671a">
  <Notifications>
    <LogicalDeviceStatesChangedNotification Version="1.70" NotificationId="e993be36-67a8-4c95-bedf-6329b082783d">
      <LogicalDeviceStates>
        <LogicalDeviceState xsi:type="GenericDeviceState" LID="97865ef1-eaea-5bbd-4f45-xxxxxxxxxxxx">
          <Ppts>
            <Ppt xsi:type="BooleanProperty" Name="Value" Value="False" />
          </Ppts>
        </LogicalDeviceState>
      </LogicalDeviceStates>
    </LogicalDeviceStatesChangedNotification>
    <LogicalDeviceStatesChangedNotification Version="1.70" NotificationId="8c471fc4-38cc-4d20-97d8-b439d7cf01d4">
      <LogicalDeviceStates>
        <LogicalDeviceState xsi:type="SwitchActuatorState" LID="09ea1f0d-4142-136d-03d7-xxxxxxxxxxxx" IsOn="True" />
      </LogicalDeviceStates>
    </LogicalDeviceStatesChangedNotification>
  </Notifications>
</NotificationList>

Mit diesen Notifications kann man dann weiter arbeiten und sieht im Beispiel, dass die Variable mit der logischen ID 97865ef1-eaea-5bbd-4f45-xxxxxxxxxxxx auf False geschaltet wurde und der Lichtschalter mit der LID 09ea1f0d-4142-136d-03d7-xxxxxxxxxxxx eingeschaltet wurde.

LogoutNotification

Nach einigen Stunden kann es sein, dass man keine Notifications mehr erhält. Zuvor liefert die oben beschriebene Notificationsabfrage aber eine LogoutNotification als Ergebnis. In dem Falle sieht es also so aus:

<?xml version="1.0"?>
<NotificationList xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" NotificationListId="b3f938e4-51e9-4a47-9c6f-28f9a1b79d4c">
  <Notifications>
    <LogoutNotification Version="1.70" NotificationId="44da7ca0-7a16-4841-a0e7-3fa5f72fddb4" Reason="SessionExpired" />
  </Notifications>
</NotificationList>

LogicalDeviceStatesChangedNotification „Rauchmelder“

Diese Mitteilung kommt, wenn ein Rauchmelder Rauch erkannt hat. Da automatisch der Alarm eingeschaltet wird, kommt in einem die Notification für den Alarm mit. Aktiviert man nur den Alarm, bspw. als Alarmanlagenfunktion, wird auch nur der Alarm ohne Raucherkennung geliefert:

<?xml version="1.0"?>
<NotificationList xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" NotificationListId="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx">
  <Notifications>
    <LogicalDeviceStatesChangedNotification Version="1.70" NotificationId="408f7202-f336-4ba2-b120-11d9122785d7">
      <LogicalDeviceStates>
        <LogicalDeviceState xsi:type="SmokeDetectionSensorState" LID="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx">
          <IsSmokeAlarm>true</IsSmokeAlarm>
        </LogicalDeviceState>
      </LogicalDeviceStates>
    </LogicalDeviceStatesChangedNotification>
    <LogicalDeviceStatesChangedNotification Version="1.70" NotificationId="a9c45271-edeb-4752-a1e2-ae2d3a94118f">
      <LogicalDeviceStates>
        <LogicalDeviceState xsi:type="AlarmActuatorState" LID="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx">
          <IsOn>true</IsOn>
        </LogicalDeviceState>
      </LogicalDeviceStates>
    </LogicalDeviceStatesChangedNotification>
  </Notifications>
</NotificationList>

BatteryLowNotification – oder so ähnlich…

Eine „BatteryLowNotification“ würde man eigentlich erwarten – aber die gibt es nicht. Statt dessen liegt eine Nachricht im RWE Smarthome Posteingang. Diese kann man auswerten und somit herausfinden, wenn ein Gerät unter leeren Batterien leidet. Doch wie kommt man an die Nachricht? Zunächst lassen sich alle Messages mit einem „GetMessageListRequest“ abrufen. Allerdings bekommt man darüber keine Änderungen mit. Deshalb muss man sich über einen NotificationRequest in den Typ „MessageUpdate“ einschreiben und bekommt dann über die Notifications mit, wenn es neue Nachrichten gibt. Eine „MessageStateChangedNotification“ sieht dann etwa so aus:

?xml version="1.0"?>
<NotificationList xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" NotificationListId="c3cd81b1-b75c-4c88-a3b0-4b4f3fe7955b">
  <Notifications>
    <MessageStateChangedNotification Version="1.70" NotificationId="5edf6ac3-44b5-4b50-ad54-d606dccc4191" State="Read" MessageId="8c291bdb-7820-4877-ad8e-xxxxxxxxxxxx" />
  </Notifications>
</NotificationList>

Die eigentliche Message sieht man dann bei einem „GetMessageListRequest“:

POST https://smarthome02/cmd HTTP/1.1
Accept: */*
Accept-Language: de-DE
Referer: https://smarthome.blob.core.windows.net/silverlight/latest/application/RWE.SmartHome.UI.Shell.xap?ignore=1.70.556.0
Content-Length: 215
Accept-Encoding: identity
Content-Type: text/xml
ClientId: 78366bc8-8c7c-49ba-b8ea-xxxxxxxxxxxx
User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; OfficeLiveConnector.1.5; OfficeLivePatch.1.3)
Host: smarthome02
Connection: Keep-Alive
Cache-Control: no-cache

<BaseRequest xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="GetMessageListRequest" Version="1.70" RequestId="f98d4f48-af0d-4be1-aa27-0d41df6ce5e2" SessionId="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" />

Response:

HTTP/1.1 200 OK
ClientId: 78366bc8-8c7c-49ba-b8ea-56a99b74bf75
Content-Length: 3912
Connection: Keep-Alive

<BaseResponse CorrespondingRequestId="f98d4f48-af0d-4be1-aa27-0d41df6ce5e2" Version="1.70" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="MessageListResponse">
	<MessageList>
		<MessageContainer State="Read">
			<Message Class="Alert" Id="d05bb88a-21c0-4662-8396-68e5b97b3961" TimeStamp="2015-03-22T07:33:53.61" Type="DeviceLowBattery">
				<Parameters>
					<MessageParameter Key="DeviceId" Value="887cfdb3-b2ba-4311-ae61-xxxxxxxxxxxx"/>
				</Parameters>
			</Message>
		</MessageContainer>
	</MessageList>
</BaseResponse>

Hier erkennt man nun, dass eine Nachricht der Klasse „Alert“ mit dem Typ „DeviceLowBattery“ für das Device mit der DeviceId „887cfdb3-b2ba-4311-ae61-xxxxxxxxxxxx“ vorhanden ist. Wechselt man dann die Batterien, wird diese Message von der Zentrale einfach wieder gelöscht. Dazu gibt es dann wieder eine MessageStateChangedNotification, sodass man das auch mitbekommt.

8 Antworten auf „RWE Smarthome API“

  1. Hi Ollie,
    super Arbeit.
    Kannst du mir evtl. helfen, wie eine Notification für einen Rolladen (RollerShutter) aussehen würde?
    Ich habe da meine Probleme mit dem xlm.
    Für eine Hilfe wäre ich sehr, sehr dankbar.
    Cheers
    Björn

    1. Hallo Björn,
      würde ich gerne, allerdings besitze ich keine Rolladenaktoren. Was ich sonst immer mache ist mit Fiddler unter Windows mitsniffen. Fiddler starten, die RWE Silverlight Software starten und einfach an einem Rolladenaktor die Taste drücken. Daraus wird dann eine Notification, die die Silverlight Software auswertet.
      Gruß
      Ollie

  2. Hi Olli,

    Herzlichen Dank das Du Dir Zeit genommen hast eineDoku zu erstellen. Jetzt verstehe ich endlich wie Notifications funktionieren und kann meine PHP Programme erweitern.

    Viele Grüße

      1. hi,
        Auch da ist wie in der neuen API der Verweis auf

        Start SmartHome authorization page und der zeigt auf
        https://api.services-smarthome.de/AUTH/authorize?response_type=code&client_id=xxxxxxxxx&redirect_uri=https://www.ollie.in/start-smarthome-token/&scope&lang=de-DE
        und start-smarthome-token existiert ncht, dies hat den Effekt, das zwar die login Seite von innogy angezeigt wird, abe dann nicht der Autorisierungscode, sonden wieder der login.

        d.h. start-smarthome-token müsste eine Kopie von rwe-smarthome-token auf http://www.ollie.in werden

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.