Wetterfühlig mit Eclipse SmartHome

Seite 3: Probelauf

Inhaltsverzeichnis

Nun können Entwickler das Binding das erste Mal ausprobieren. Dazu öffnen sie in Eclipse das Run-Menü, klicken auf Run Configurations und wählen die Konfiguration SmartHome Runtime aus. Unter dem Reiter Plug-ins muss für das Netatmo-Binding das Start Level auf 0 und Auto-Start auf true stehen. Nun lässt sich Eclipse SmartHome mit dem Binding über die Schaltfläche Run starten. Die Web-Benutzeroberfläche ist anschließend unter http://localhost:8080/ui/index.html erreichbar. Dort können Anwender im Bereich Inbox eine Discovery starten und die Netatmo-Wetterstationen finden. Um dessen Daten anzuzeigen, ist das Anlegen eines Thing und seiner Channels erforderlich.

Ein Thing besteht aus den folgenden drei Dateien:

  • der Definition des Thing mit seinen Channels,
  • einem Handler,
  • einer Factory, die das Thing erstellt.

Das Skript hat diese Dateien bereits angelegt. Entwickler definieren zu Beginn die Channels in der Datei ESH-INF/thing/thing-types.xml. Die Definition steht im Element <channels>. Jeder Channel hat einen Typ (<thing-type>-Element).

Die folgende XML-Datei zeigt die angepasste Definition des Thing. Sie verwendet nur die drei Channels temperature, humidity und co2. Die Definition des jeweiligen Channeltyps erfolgt darunter. Im Beispiel hat temperature den Typ Number und die Kategorie Temperature. Die Formatierung erfolgt mit einer Nachkommastelle und in Grad Celsius. Die Definition der anderen beiden Channeltypen erfolgt auf die gleiche Weise.

<thing-type id="weatherstation">
<label>Netatmo Weather Station</label>
<description>The Netatmo Weatherstation.</description>
  <channels>
<channel id="temperature" typeId="temperature"/>
<channel id="humidity" typeId="humidity"/>
<channel id="co2" typeId="co2"/>
</channels>
</thing-type>
<channel-type id="temperature">
<item-type>Number</item-type>
<label>Temperature</label>
<description>The current temperature.</description>
<category>Temperature</category>
<state readOnly="true" pattern="%.1f C" />
</channel-type>
<channel-type id="humidity">
<item-type>Number</item-type>
<label>Humidity</label>
<description>The current humidity.</description>
<category>Humidity</category>
<state readOnly="true" pattern="%.1f %%" />
</channel-type>
<channel-type id="co2">
<item-type>Number</item-type>
<label>CO2</label>
<description>The current CO2 saturation.</description>
<category>CarbonDioxide</category>
<state readOnly="true" pattern="%d ppm" />
</channel-type>

Die Datei NetatmoBindingConstants verlangt noch nach einer Anpassung: Die Verknüpfung von XML und Java erfolgt über Strings, die den gleichen Wert haben müssen und die in der Klasse NetamoBindingConstants definiert sind:

public class NetatmoBindingConstants {
public final static String CHANNEL_TEMPERATURE
= "temperature";
public final static String CHANNEL_HUMIDITY
= "humidity";
public final static String CHANNEL_CO2
= "co2";
}

Wenn der Anwender in der Inbox bei einer Wetterstation auf den Approve-Button klickt, wird in der Klasse NetatmoHandlerFactory die Methode supportsThingType mit dem Wetterstationtypen aufgerufen. Wenn die Methode true zurückgibt, erstellt die Methode createHandler den Thing-Handler. Das Tool hat den Code bereits generiert. Für die Wetterstation wird eine Instanz der Klasse NetatmoHandler erstellt.

Diese erbt von BaseThingHandler und enthält zwei Methoden: initialize() wird von Eclipse SmartHome nach dem Erstellen des Handlers aufgerufen. Der Aufruf von handleCommand() erfolgt, wenn der Benutzer den Wert eines Channels ändert. Das Wetterstation-Thing verwendet Letzteres nicht, da es nur lesbare Channels enthält. Nur Things, die schreibbare Channels enthalten, müssen die Methode implementieren.

@Override
public void initialize() {
scheduler.scheduleWithFixedDelay(new Runnable() {
@Override
public void run() {
refresh();
}
}, 0, 10, TimeUnit.MINUTES);
}

Der Eclipse SmartHome Scheduler führt den Code alle zehn Minuten aus

Die initialize()-Methode erstellt über den ESH-Scheduler einen Task, dessen Ausführung alle zehn Minuten erfolgt und der die folgende refresh()-Methode aufruft:

private void refresh() {
String id = getThing().getProperties().get("id");
  StationData data = NetatmoWebservice.INSTANCE
.fetchStationData();
for (Device device : data.getBody().getDevices()) {
if (device.getId().equals(id)) {
DashboardData dashboard = device.getDashboardData();
      updateState(NetatmoBindingConstants.
CHANNEL_TEMPERATURE,
new DecimalType(dashboard
.getTemperature()));
updateState(NetatmoBindingConstants.CHANNEL_HUMIDITY,
new DecimalType(dashboard.getHumidity()));
updateState(NetatmoBindingConstants.CHANNEL_CO2,
new DecimalType(dashboard.getCo2()));
return;
}
}
}

In der refresh-Methode erfolgt die Abfrage der aktuellen Daten der Wetterstation über den Netatmo-Webservice. Da er die Daten aller Wetterstationen liefert, muss das Programm die richtige Wetterstation herausfiltern. Im Discovery Service wurde die ID der Wetterstation, die zum Thing gehört, in der Eigenschaft id gespeichert. Diese lässt sich im ThingHandler mit der Methode getThing().getProperties().get("id") auslesen.

Nach dem Filtern der Webservice-Daten auf die richtige Wetterstation lassen sich mit der von der Basisklasse geerbten Methode updateState die neuen Werte der Channels setzen.