Die Leichtigkeit des Seins
Bindings für Eclipse SmartHome entwickeln
Köln, 12.05.2016
Moritz Kammerer
Über den Autor
2
■ Entwickelt seit 2014 Bindings für Eclipse SmartHome
■Arbeitet bei QAware GmbH, www.qaware.de
■ GitHub: @phxql / Twitter: @phxql
■ Blog: https://www.mkammerer.de/blog
■ Anmerkung: Die nachfolgenden Slides dienen als Handout für die Besucher. Im Vortrag wird
hands-on ein Binding in Eclipse entwickelt und die Konzepte daran erklärt.
■ Sourcecode des Vortrags: https://github.com/phxql/building-iot
Was ist Eclipse SmartHome?
3
■ Ein Projekt der Eclipse Foundation
■ Open-Source
■ Framework, um Geräte herstellerübergreifend zu vernetzen (sogenannte Bindings)
■ Dient als Basis für diverse SmartHome-Systeme, z.B. OpenHAB oder QIVICON der Telekom
Der Softwarestack
4
JVM
OSGi-Runtime (Equinox, Felix, …)
Eclipse SmartHome
Unser Binding
Bind
Building Blocks: Bindings, Bridges, Things und Channels
5
Bridge
Thing Thing Thing
Channel Channel Channel
Binding
Building Blocks: Bindings, Bridges, Things und Channels
6
■ Binding: Plugin, das Geräte in Eclipse SmartHome integriert. z.B. Hue-Binding, das die Hue-
Lampen von Phillips in Eclipse SmartHome integriert oder das Nest-Binding
■ Bridge: Netzwerkbrücken, ermöglichen Zugang zu weiteren Things. Beispiel: Bridge der
Phillips Hue
■ Thing: Ein physikalisches Gerät. Kann zu einer Bridge gehören, muss aber nicht. Beispiel:
Phillips Hue Lampe oder das Nest Thermostat
■ Channel: Ein- und Ausgabekanal eines Things. Kann les- und schreibbar oder nur lesbar sein.
Beispiel: Zieltemperatur des Nest-Thermostats, Farbe der Hue-Lampe. Hat einen bestimmten
Typen, z.B. Number oder Color.
Getting started
7
■ Eclipse SmartHome Dokumentation: https://eclipse.org/smarthome/documentation/index.html
■ IDE Setup: https://eclipse.org/smarthome/documentation/development/ide.html
■Source von Eclipse SmartHome unter $INSTALL_DIR/smarthome-master/git
■Eclipse Workspace unter $INSTALL_DIR/ws
■ Projekt einmal mit „mvn clean install“ komplett durchbauen
■Nur dann funktioniert die UI!
Unser erstes Binding
8
■ Skelett des Bindings anlegen: extensions/binding/create_binding_skeleton.cmd [Name]
[Author]
■ ESH-INF – Metadaten für Eclipse SmartHome
■binding – Metadaten über das Binding
■i18n – Internationalisierung
■thing – Definition der Bridges, Things und Channels
■ META-INF – Manifest für OSGi, etc.
■ OSGI-INF – Registrierung von OSGi-Services, etc.
■ src – Quelltext
■ target – Kompilate von Maven
9
Nest Webservice
in der Cloud
Thing:
Thermostat
Channel: Target
Temperature
Eclipse SmartHome
Kommunikation Nest Thermostat / Eclipse SmartHome
10
■ Thermostat kommuniziert mit dem Nest Cloudservice
■ Dieser bietet eine Firebase-API an, um die Werte des Thermostats zu lesen und zu schreiben
■Firebase arbeitet push-basiert, d.h. wir werden bei Änderungen benachrichtigt
■ Damit wir den Nest Cloudservice verwenden können, benötigen wir ein OAuth2 Access Token
■ Dieses ist für einen Client ausgestellt, den wir auf https://developer.nest.com erstellen müssen
■ Mittels der Authorization URL bekommen wir einen Pincode, den wir mit der Access Token URL
verwenden können, um an ein Access Token zu kommen
■Leider bietet Eclipse SmartHome noch keine eingebaute Unterstützung von OAuth2
■ Dieses Access Token kodieren wir in der Klasse NestBindingConstants
Anlegen der Channels
11
■ In der Datei ESH-INF/thing/thing-types.xml beschreiben wir unseren Channel:
<channel-type id="target_temperature">
<item-type>Number</item-type>
<label>Target temperature</label>
<description>The target temperature.</description>
<category>Temperature</category>
<state readOnly="false" pattern="%.1f C" />
</channel-type>
Finden des Thermostats
12
■ Eclipse SmartHome verwendet Discovery Services, um Things zu finden
■ In unserem Fall muss der Discovery Service den Nest Cloud Webservice kontaktieren, um die
Thermostate aufzulisten
■ Dazu erstellen wir eine neue Klasse NestDiscoveryService und leiten diese von
AbstractDiscoveryService ab
■Im Constructor wird angegeben, welche Things der DiscoveryService finden kann
■Die Methode startScan() wird aufgerufen, wenn der Benutzer nach neuen Things suchen möchte
Nest Cloud Webservice anprogrammieren
13
■ Wir verwenden Firebase zur Kommunikation mit dem Cloud Webservice
■ Die Firebase-Clientbibliothek muss in den Ordner lib kopiert und im OSGi-Manifest inkludiert
werden
■Wir verwenden ein Fat-JAR, das alle Abhängigkeiten von Firebase enthält
■Dieses JAR kann unter https://www.firebase.com/docs/android/quickstart.html heruntergeladen werden
■Direkt-Link: https://cdn.firebase.com/java/firebase-client-jvm-2.5.2.jar
■ Nun kann der Firebase-Client im NestDiscoveryService verwendet werden, um die verfügbaren
Thermostate aufzulisten
■Im Code ist der Nest Webservice Client in der Klasse NestWebservice zu finden
Entdecke neue Things
14
■ An die URL /devices/thermostats kann nun im DiscoveryService ein Listener gehängt werden
■Dieser wird aufgerufen, wenn ein Thermostat entdeckt wurde
■Firebase stellt sicher, dass der Listener auch schon für bereits vorhandene Thermostate aufgerufen
wird
■ Der Listener wird mit Daten des Thermostats aufgerufen. Die Eigenschaft device_id enthält die
ID des Thermostats
■ Über die geerbte Methode thingDiscovered() und der Klasse DiscoveryResult wird der neu
gefundene Thermostat Eclipse SmartHome bekannt gemacht. Dieser landet in der Inbox.
■ Der Discovery Service muss noch durch eine XML-Datei im OSGi-Framework registriert
werden.
■Diese Datei befindet sich im Ordner OSGI-INF (NestDiscovery.xml)
Inbox, Things und ThingHandler
15
■ Wenn ein DiscoveryResult in der Inbox vom Benutzer „approved“ wird, wird die Methode
supportsThingType der Klasse NestHandlerFactory aufgerufen
■ Liefert diese true, wird die Methode createHandler aufgerufen
■ Diese gibt den ThingHandler für ein bestimmtes Thing zurück
■Normalerweise gibt es für jeden ThingType (thermostat, …) einen eigenen Handler
■Der Handler für Thermostate befindet sich in der Klasse NestHandler
■ Eclipse SmartHome instanziiert nun diese Klasse und ruft die Methode initialize() auf
■ Ein ThingHandler erbt im Normalfall von BaseThingHandler
■Die Methode handleCommand() des Interfaces wird aufgerufen, wenn der Benutzer über die UI von
Eclipse SmartHome Werte des Geräts ändern möchte
Ändern der Zieltemperatur: vom Binding zum Thermostat
16
■ handleCommand() erhält als Argument den Eingangschannel und dessen neuen Wert
■ Diesen Wert können wir nun verwenden, um die Zieltemperatur des Thermostats einzustellen:
■Wir schreiben durch Firebase auf die URL /devices/thermostats/{id}/target_temperature_c mittels
setValue() den Wert der neuen Zieltemperatur
■Die ID des Thermostats können wir über die Methode getThing().getProperties() auslesen. Diese Map
enthält die Werte, die beim DiscoveryResult angegeben wurden
■ Der Nest Cloudwebservice kümmert sich nun darum, dass die Temperatur auf dem Thermostat
eingestellt wird
17
Reagieren auf Änderungen der Zieltemperatur: Vom Thermostat
zum Binding
18
■ Die Methode initialize() des ThingHandlers wird durch Eclipse SmartHome aufgerufen, wenn
das DiscoveryResult „approved“ wurde
■ In dieser Methode verwenden wir Firebase und die URL
/devices/thermostats/{id}/target_temperature_c, um sich über Änderungen der Zieltemperatur
benachrichtigen zu lassen
■Die ID des Thermostats lesen wir, wie beim Ändern der Temperatur, aus den Properties des Things
■ Der Firebase-Listener wird aufgerufen, wenn sich die Zieltemperatur ändert
■Über die Methode getValue() kann die Zieltemperatur ausgelesen werden
■ Über die Methode updateState() kann ein Channel aktualisiert werden
■Der Temperaturwert muss von double noch in DecimalType umgewandelt werden
19
Ausführen des Bindings in Eclipse
20
■ Run / Run Configurations
■ SmartHome Runtime / Plugins
■ Binding „org.eclipse.smarthome.binding.nest“ suchen
■Start Level: 0, Auto-Start: True
■ Run
■ UI unter http://localhost:8080/ui/index.html erreichbar
Ausführen des Bindings in OpenHAB
21
■ OpenHAB ist eine Distribution von EclipseSmartHome (http://www.openhab.org/)
■Achtung: Erst Version 2 basiert auf EclipseSmartHome
■ Bauen des Bindings mit „mvn clean install“
■Im Ordner „target“ befindet sich nun org.eclipse.smarthome.binding.nest-0.8.0-SNAPSHOT.jar
■ OpenHAB 2 Offline Version herunterladen und entpacken:
https://openhab.ci.cloudbees.com/job/openHAB-Distribution/
■ JAR des Bindings in OpenHAB2/addons kopieren und OpenHAB starten
■ UI unter http://localhost:8080/ui/index.html erreichbar
22
https://github.com/phxql/building-iot
Code des Vortrags:

Die Leichtigkeit des Seins: Bindings für Eclipse SmartHome entwickeln

  • 1.
    Die Leichtigkeit desSeins Bindings für Eclipse SmartHome entwickeln Köln, 12.05.2016 Moritz Kammerer
  • 2.
    Über den Autor 2 ■Entwickelt seit 2014 Bindings für Eclipse SmartHome ■Arbeitet bei QAware GmbH, www.qaware.de ■ GitHub: @phxql / Twitter: @phxql ■ Blog: https://www.mkammerer.de/blog ■ Anmerkung: Die nachfolgenden Slides dienen als Handout für die Besucher. Im Vortrag wird hands-on ein Binding in Eclipse entwickelt und die Konzepte daran erklärt. ■ Sourcecode des Vortrags: https://github.com/phxql/building-iot
  • 3.
    Was ist EclipseSmartHome? 3 ■ Ein Projekt der Eclipse Foundation ■ Open-Source ■ Framework, um Geräte herstellerübergreifend zu vernetzen (sogenannte Bindings) ■ Dient als Basis für diverse SmartHome-Systeme, z.B. OpenHAB oder QIVICON der Telekom
  • 4.
    Der Softwarestack 4 JVM OSGi-Runtime (Equinox,Felix, …) Eclipse SmartHome Unser Binding
  • 5.
    Bind Building Blocks: Bindings,Bridges, Things und Channels 5 Bridge Thing Thing Thing Channel Channel Channel Binding
  • 6.
    Building Blocks: Bindings,Bridges, Things und Channels 6 ■ Binding: Plugin, das Geräte in Eclipse SmartHome integriert. z.B. Hue-Binding, das die Hue- Lampen von Phillips in Eclipse SmartHome integriert oder das Nest-Binding ■ Bridge: Netzwerkbrücken, ermöglichen Zugang zu weiteren Things. Beispiel: Bridge der Phillips Hue ■ Thing: Ein physikalisches Gerät. Kann zu einer Bridge gehören, muss aber nicht. Beispiel: Phillips Hue Lampe oder das Nest Thermostat ■ Channel: Ein- und Ausgabekanal eines Things. Kann les- und schreibbar oder nur lesbar sein. Beispiel: Zieltemperatur des Nest-Thermostats, Farbe der Hue-Lampe. Hat einen bestimmten Typen, z.B. Number oder Color.
  • 7.
    Getting started 7 ■ EclipseSmartHome Dokumentation: https://eclipse.org/smarthome/documentation/index.html ■ IDE Setup: https://eclipse.org/smarthome/documentation/development/ide.html ■Source von Eclipse SmartHome unter $INSTALL_DIR/smarthome-master/git ■Eclipse Workspace unter $INSTALL_DIR/ws ■ Projekt einmal mit „mvn clean install“ komplett durchbauen ■Nur dann funktioniert die UI!
  • 8.
    Unser erstes Binding 8 ■Skelett des Bindings anlegen: extensions/binding/create_binding_skeleton.cmd [Name] [Author] ■ ESH-INF – Metadaten für Eclipse SmartHome ■binding – Metadaten über das Binding ■i18n – Internationalisierung ■thing – Definition der Bridges, Things und Channels ■ META-INF – Manifest für OSGi, etc. ■ OSGI-INF – Registrierung von OSGi-Services, etc. ■ src – Quelltext ■ target – Kompilate von Maven
  • 9.
    9 Nest Webservice in derCloud Thing: Thermostat Channel: Target Temperature Eclipse SmartHome
  • 10.
    Kommunikation Nest Thermostat/ Eclipse SmartHome 10 ■ Thermostat kommuniziert mit dem Nest Cloudservice ■ Dieser bietet eine Firebase-API an, um die Werte des Thermostats zu lesen und zu schreiben ■Firebase arbeitet push-basiert, d.h. wir werden bei Änderungen benachrichtigt ■ Damit wir den Nest Cloudservice verwenden können, benötigen wir ein OAuth2 Access Token ■ Dieses ist für einen Client ausgestellt, den wir auf https://developer.nest.com erstellen müssen ■ Mittels der Authorization URL bekommen wir einen Pincode, den wir mit der Access Token URL verwenden können, um an ein Access Token zu kommen ■Leider bietet Eclipse SmartHome noch keine eingebaute Unterstützung von OAuth2 ■ Dieses Access Token kodieren wir in der Klasse NestBindingConstants
  • 11.
    Anlegen der Channels 11 ■In der Datei ESH-INF/thing/thing-types.xml beschreiben wir unseren Channel: <channel-type id="target_temperature"> <item-type>Number</item-type> <label>Target temperature</label> <description>The target temperature.</description> <category>Temperature</category> <state readOnly="false" pattern="%.1f C" /> </channel-type>
  • 12.
    Finden des Thermostats 12 ■Eclipse SmartHome verwendet Discovery Services, um Things zu finden ■ In unserem Fall muss der Discovery Service den Nest Cloud Webservice kontaktieren, um die Thermostate aufzulisten ■ Dazu erstellen wir eine neue Klasse NestDiscoveryService und leiten diese von AbstractDiscoveryService ab ■Im Constructor wird angegeben, welche Things der DiscoveryService finden kann ■Die Methode startScan() wird aufgerufen, wenn der Benutzer nach neuen Things suchen möchte
  • 13.
    Nest Cloud Webserviceanprogrammieren 13 ■ Wir verwenden Firebase zur Kommunikation mit dem Cloud Webservice ■ Die Firebase-Clientbibliothek muss in den Ordner lib kopiert und im OSGi-Manifest inkludiert werden ■Wir verwenden ein Fat-JAR, das alle Abhängigkeiten von Firebase enthält ■Dieses JAR kann unter https://www.firebase.com/docs/android/quickstart.html heruntergeladen werden ■Direkt-Link: https://cdn.firebase.com/java/firebase-client-jvm-2.5.2.jar ■ Nun kann der Firebase-Client im NestDiscoveryService verwendet werden, um die verfügbaren Thermostate aufzulisten ■Im Code ist der Nest Webservice Client in der Klasse NestWebservice zu finden
  • 14.
    Entdecke neue Things 14 ■An die URL /devices/thermostats kann nun im DiscoveryService ein Listener gehängt werden ■Dieser wird aufgerufen, wenn ein Thermostat entdeckt wurde ■Firebase stellt sicher, dass der Listener auch schon für bereits vorhandene Thermostate aufgerufen wird ■ Der Listener wird mit Daten des Thermostats aufgerufen. Die Eigenschaft device_id enthält die ID des Thermostats ■ Über die geerbte Methode thingDiscovered() und der Klasse DiscoveryResult wird der neu gefundene Thermostat Eclipse SmartHome bekannt gemacht. Dieser landet in der Inbox. ■ Der Discovery Service muss noch durch eine XML-Datei im OSGi-Framework registriert werden. ■Diese Datei befindet sich im Ordner OSGI-INF (NestDiscovery.xml)
  • 15.
    Inbox, Things undThingHandler 15 ■ Wenn ein DiscoveryResult in der Inbox vom Benutzer „approved“ wird, wird die Methode supportsThingType der Klasse NestHandlerFactory aufgerufen ■ Liefert diese true, wird die Methode createHandler aufgerufen ■ Diese gibt den ThingHandler für ein bestimmtes Thing zurück ■Normalerweise gibt es für jeden ThingType (thermostat, …) einen eigenen Handler ■Der Handler für Thermostate befindet sich in der Klasse NestHandler ■ Eclipse SmartHome instanziiert nun diese Klasse und ruft die Methode initialize() auf ■ Ein ThingHandler erbt im Normalfall von BaseThingHandler ■Die Methode handleCommand() des Interfaces wird aufgerufen, wenn der Benutzer über die UI von Eclipse SmartHome Werte des Geräts ändern möchte
  • 16.
    Ändern der Zieltemperatur:vom Binding zum Thermostat 16 ■ handleCommand() erhält als Argument den Eingangschannel und dessen neuen Wert ■ Diesen Wert können wir nun verwenden, um die Zieltemperatur des Thermostats einzustellen: ■Wir schreiben durch Firebase auf die URL /devices/thermostats/{id}/target_temperature_c mittels setValue() den Wert der neuen Zieltemperatur ■Die ID des Thermostats können wir über die Methode getThing().getProperties() auslesen. Diese Map enthält die Werte, die beim DiscoveryResult angegeben wurden ■ Der Nest Cloudwebservice kümmert sich nun darum, dass die Temperatur auf dem Thermostat eingestellt wird
  • 17.
  • 18.
    Reagieren auf Änderungender Zieltemperatur: Vom Thermostat zum Binding 18 ■ Die Methode initialize() des ThingHandlers wird durch Eclipse SmartHome aufgerufen, wenn das DiscoveryResult „approved“ wurde ■ In dieser Methode verwenden wir Firebase und die URL /devices/thermostats/{id}/target_temperature_c, um sich über Änderungen der Zieltemperatur benachrichtigen zu lassen ■Die ID des Thermostats lesen wir, wie beim Ändern der Temperatur, aus den Properties des Things ■ Der Firebase-Listener wird aufgerufen, wenn sich die Zieltemperatur ändert ■Über die Methode getValue() kann die Zieltemperatur ausgelesen werden ■ Über die Methode updateState() kann ein Channel aktualisiert werden ■Der Temperaturwert muss von double noch in DecimalType umgewandelt werden
  • 19.
  • 20.
    Ausführen des Bindingsin Eclipse 20 ■ Run / Run Configurations ■ SmartHome Runtime / Plugins ■ Binding „org.eclipse.smarthome.binding.nest“ suchen ■Start Level: 0, Auto-Start: True ■ Run ■ UI unter http://localhost:8080/ui/index.html erreichbar
  • 21.
    Ausführen des Bindingsin OpenHAB 21 ■ OpenHAB ist eine Distribution von EclipseSmartHome (http://www.openhab.org/) ■Achtung: Erst Version 2 basiert auf EclipseSmartHome ■ Bauen des Bindings mit „mvn clean install“ ■Im Ordner „target“ befindet sich nun org.eclipse.smarthome.binding.nest-0.8.0-SNAPSHOT.jar ■ OpenHAB 2 Offline Version herunterladen und entpacken: https://openhab.ci.cloudbees.com/job/openHAB-Distribution/ ■ JAR des Bindings in OpenHAB2/addons kopieren und OpenHAB starten ■ UI unter http://localhost:8080/ui/index.html erreichbar
  • 22.