Die ersten Schritte mit OpenHAB

OpenHAB war recht zügig installiert und startklar. Nachdem ich einige Zeit im OpenHAB-Wiki verbrachte und die Demo-Dateien studierte, fing ich mit einer leeren OpenHAB-Konfiguration an und begann, die ersten Items und Regeln zu erstellen.

Zunächst habe ich meine bereits vorhandene Messung (siehe vorheriger Artikel) meines Stromverbrauchs per nodejs an OpenHAB angebunden. Dafür habe ich das nodejs-Script, dass die Daten vom IR-Kopf liest so geändert, dass ich per OpenHAB über das HTTP-Binding den Zählerstand lesen kann. Alle 30 Sekunden lese ich den Zählerstand in Wh und kann somit den aktuellen Verbrauch ermitteln. Das ganze lässt sich dann auch schön als Graph darstellen.

Das nodejs-Script:

//*** Read EMH eHZ FW8xxx values and write them to syslog file to be read by Splunk

var syslog	= require('./syslog');

var serialport = require("serialport");
var SerialPort = serialport.SerialPort;
var util = require("util"), repl = require("repl");
var http = require("http");

var serial_port = new SerialPort("COM3", {baudrate: 9600, databits: 7, stopbits:1, parity:'none', buffersize:2048, parser: serialport.parsers.raw});
var regCompleteMsg = new RegExp('\\/[\\s\\S]+!');

var reg_0_0_0    = new RegExp('0\\.0\\.0\\*255\\((.*)\\)');
var reg_1_8_1    = new RegExp('1\\.8\\.1\\*255\\((.*)\\)');
var reg_96_5_5   = new RegExp('96\\.5\\.5\\*255\\((.*)\\)');
var reg_96_1_255 = new RegExp('96\\.1\\.255\\*255\\((.*)\\)');

var chunk = "";

var previousTotal = -1;

var lines = [];

var total = 0.0;

serial_port.on("data", function (data)
{
	chunk += data.toString();

	var partial = chunk.match(regCompleteMsg);

	if (partial != undefined) 
	{
		chunk = "";
		partial = partial.toString();

		var ownerUID  = partial.match(reg_0_0_0);
		    total     = partial.match(reg_1_8_1);
		var state     = partial.match(reg_96_5_5);
		var vendorUID = partial.match(reg_96_1_255);
		
		var delta = 0;
		if( previousTotal != -1 )
			delta = total[1] - previousTotal;
			
		previousTotal = total[1];

		syslog.log( "POWER", "total", total[1], "delta", delta, "state", state[1], "customerUID", ownerUID[1], "vendorUID", vendorUID[1] ); 
	}
})
serial_port.on("error", function (msg) {
  util.puts("error: "+msg);
})
repl.start("=>")

http.createServer(function (req, res)
{
	res.writeHead(200, {'Content-Type': 'text/plain'});
	res.end("" + total[1]);
}).listen(8765);

Am Ende des Scripts kann man sehen, wie der http-Server erstellt wird. Er gibt einfach den aktuellen Zählerstand aus.

Das entsprechende Item in OpenHAB sieht dann folgendermaßen aus:

Number PowerTotal "Zählerstand [%.3f KWh]" <energy> (gEnergy) { http="<[http://localhost:8765/:30000:REGEX((.*))]" }
Number PowerCurrent "Momentanverbrauch [%.1f W]" <energy>

Da mein Stromzähler nur den aktuellen Zählerstand ausgibt, nicht aber den Momentanverbrauch, bedarf es hier noch eines Scripts in OpenHAB, um den Momentanverbrauch auszurechnen. Das Script ist das folgende:

import org.openhab.core.library.types.*

var String TAG = "strom.rules"

var org.joda.time.DateTime g_lastTime
var Number g_lastValue = 0

rule "Power Current"
when
Item PowerTotal changed
then
var org.joda.time.DateTime currentTime = now
var Number currentValue = PowerTotal.state as DecimalType

if(g_lastTime != null && g_lastValue > 0)
{
var Number oldValue = g_lastValue
var Number deltaKWh = currentValue - oldValue
var long deltaMillis = currentTime.millis - g_lastTime.millis

if(deltaMillis > 0 && deltaMillis < 40000)
{
logInfo(TAG, "old=" + oldValue + " current=" + currentValue + " deltaKWh=" + deltaKWh + " deltaMS=" + deltaMillis )

var Number deltaWh = deltaKWh * 1000.0
var Number millisToHours = 60.0 * 60.0 * 1000.0;
var Number watts = deltaWh * millisToHours / deltaMillis

if(watts >= 0 && watts <= 10000)
postUpdate(PowerCurrent, watts)
}
}

g_lastTime = currentTime
g_lastValue = currentValue
end

 

Das Ergebnis ist ein schöner Graph über den aktuellen Stromverbrauch. Hier lassen sich dann wiederum zahlreiche Regeln erstellen, z.B. eine Warnung bei zu hohem Verbrauch etc.

chart

Bei der Durchsicht bereits vorhandener Bindings vielen mir insbesondere zwei auf, die für mich noch sehr nützlich sein würden: Das Onkyo-Binding für AV-Receiver des Herstellers Onkyo, sowie das Samsung-TV-Binding für Samsung-Fernseher.

Eigentich sind die beiden Geräte per HDMI verbunden und durch HDMI-CEC schaltet sich der Verstärker auch immer brav ein wenn ich den TV anschalte und dementsprechend auch wieder ab, wenn der TV ausgeschaltet wird. Das Problem daran war, dass auch beim Hören von Musik der TV angeschaltet wurde, obwohl ich diesen ja gar nicht benötigte.

Dieses Problem konnte ich nun per OpenHAB sehr elegant lösen und habe hierzu ein paar Regeln erstellt. Zunächst habe ich die HDMI-CEC Verbindung zwischen Onkyo-AV-Receiver und Samsung-TV deaktiviert, so dass ich beide Geräte wieder unabhängig ein- und abschalten konnte. Dann folgten in OpenHAB folgende Regeln:

  • Wenn TV eingeschaltet wird, schalte AV-Receiver ein.
  • Wenn AV-Receiver-Eingang auf „Netzwerk“ geändert wird, schalte TV ab
  • Wenn TV ausgeschaltet wird, schalte Onkyo ab wenn Eingang nicht „Netzwerk“ ist.

Mit Hilfe dieser Regeln konnte ich sicherstellen, dass der Verstärker immer noch mit dem TV an- und aus geht, aber gleichzeitig konnte ich nun auch den TV ausgehen lassen wenn über den Verstärker Musik gehört wird.

Ich war überrascht, wie viel man mit OpenHAB schon anstellen kann, damals habe ich mich wie ein kleines Kind gefreut. Aber wie das so ist, wenn man einmal anfängt hört man auch nicht mehr auf. Die ersten Sensoren und Aktoren erhielten schon bald Einzug, mehr dazu im nächsten Artikel!