[SOLVED] SOLVIS Heating

Dear all,

I am new to openHAB. I even have not installed it yet on my Raspberry. So far I was playing arounfd with FHEM but from what I’ve read s far about OpenHAB, I want to have a lokk at it for sure, for various reasons.
One thing I would like to understand is weather I could use OpenHAB to readout/control my central heating. The heating is a SOLVIS Max and I have a webinterface (SolvisRemote) to communicate with it.
IN FHEM there seems t be a rather simple method to communicate but I haven’t tried it out, since I’m recently found OpenHAB and now I do not know which platform I want to use in the future.
Certainly the Heating control would be one of the things for making this decision. Apart from taht I want to control my Harmony remote control, several homematic actors (wia a USB CUL) and other low frequency (FS) devices. I also have a sheepwalk one-wire board connected to my PI3 to do temperature measurements in my house.

Thanks for any help or comments
Manfred

There isn’t a SOLVIS binding but if it has a REST API you can use the HTTP Binding to send commands to it and poll for changes.

There is a Harmony Binding and Homematic Binding which should work.

I don’t know anything about FS devices.

There is a OneWire binding.

It is possible to get the values from the SolvisRemote by using executeCommandLine that calls a cURL-command:

var results = executeCommandLine("/usr/bin/curl -u user:password --digest -s ip_of_solvisRemote/sc2_val.xml", 500)

You get a large string in the variable results. With the following rule you translate the string to the values of interest from the solvis.

rule "Solvis"
when
	Item solvisswitch received update
then
	if(solvisswitch.state == ON) {
        var results = executeCommandLine("/usr/bin/curl -u user:password --digest -s ip_of_solvisRemote/sc2_val.xml", 500)
		solvis_aktuell.sendCommand(results)
		solvis_anlagenummer.postUpdate(results.substring(35,37)+results.substring(33,35))
		var String temp = ""
		if (Integer.parseInt(results.substring(27,29),16)>9) {
			temp = Integer.parseInt(results.substring(27,29),16).toString
			}
			else {
				temp = "0" + Integer.parseInt(results.substring(27,29),16).toString
			}
		if (Integer.parseInt(results.substring(25,27),16)>9) {
			temp = Integer.parseInt(results.substring(25,27),16).toString + ":" + temp
			}
			else {
				temp = "0" + Integer.parseInt(results.substring(25,27),16).toString + ":" + temp
			}
		if (Integer.parseInt(results.substring(23,25),16)>9) {
			temp = Integer.parseInt(results.substring(23,25),16).toString + ":" + temp
			}
			else {
				temp = "0" + Integer.parseInt(results.substring(23,25),16).toString + ":" + temp
			}
		solvis_zeit.postUpdate(temp)
		solvis_S1v.postUpdate(Integer.parseInt(results.substring(39,41)+results.substring(37,39),16)/10.floatValue())
		solvis_S2v.postUpdate(Integer.parseInt(results.substring(43,45)+results.substring(41,43),16)/10.floatValue())
		solvis_S3v.postUpdate(Integer.parseInt(results.substring(47,49)+results.substring(45,47),16)/10.floatValue())
		solvis_S4v.postUpdate(Integer.parseInt(results.substring(51,53)+results.substring(49,51),16)/10.floatValue())
		solvis_S5v.postUpdate(Integer.parseInt(results.substring(55,57)+results.substring(53,55),16)/10.floatValue())
		solvis_S6v.postUpdate(Integer.parseInt(results.substring(59,61)+results.substring(57,59),16)/10.floatValue())
		solvis_S7v.postUpdate(Integer.parseInt(results.substring(63,65)+results.substring(61,63),16)/10.floatValue())
		solvis_S8v.postUpdate(Integer.parseInt(results.substring(67,69)+results.substring(65,67),16)/10.floatValue())
		solvis_S9v.postUpdate(Integer.parseInt(results.substring(71,73)+results.substring(69,71),16)/10.floatValue())
		solvis_S10v.postUpdate(Integer.parseInt(results.substring(75,77)+results.substring(73,75),16)/10.floatValue())
		solvis_S11v.postUpdate(Integer.parseInt(results.substring(79,81)+results.substring(77,79),16)/10.floatValue())
		solvis_S12v.postUpdate(Integer.parseInt(results.substring(83,85)+results.substring(81,83),16)/10.floatValue())
		solvis_S18v.postUpdate(Integer.parseInt(results.substring(103,105)+results.substring(101,103),16)/10.floatValue())
		solvis_S17v.postUpdate(Integer.parseInt(results.substring(107,109)+results.substring(105,107),16)/10.floatValue())
		if (Integer.parseInt(results.substring(141,143),16)==0) {solvis_A1v.sendCommand(OFF)}
		else solvis_A1v.sendCommand(ON)
		if (Integer.parseInt(results.substring(143,145),16)==0) {solvis_A2v.sendCommand(OFF)}
		else solvis_A2v.sendCommand(ON)
		if (Integer.parseInt(results.substring(145,147),16)==0) {solvis_A3v.sendCommand(OFF)}
		else solvis_A3v.sendCommand(ON)
		if (Integer.parseInt(results.substring(149,151),16)==0) {solvis_A5v.sendCommand(OFF)}
		else solvis_A5v.sendCommand(ON)
		if (Integer.parseInt(results.substring(155,157),16)==0) {solvis_A8v.sendCommand(OFF)}
		else solvis_A8v.sendCommand(ON)
		if (Integer.parseInt(results.substring(157,159),16)==0) {solvis_A9v.sendCommand(OFF)}
		else solvis_A9v.sendCommand(ON)
		if (Integer.parseInt(results.substring(163,165),16)==0) {solvis_A12v.sendCommand(OFF)}
		else solvis_A12v.sendCommand(ON)
		if (Integer.parseInt(results.substring(167,169),16)==0) {solvis_A14v.sendCommand(OFF)}
		else solvis_A14v.sendCommand(ON)
		solvis_SEv.postUpdate(Integer.parseInt(results.substring(187,189)+results.substring(185,187),16))
		solvis_SLv.postUpdate(Integer.parseInt(results.substring(222,224)+results.substring(220,222),16)/10.floatValue())
		solvisswitch.sendCommand(OFF)
	}
	if(solvisswitch.state == OFF) {
	// Führe die Anweisung erst aus, wenn die letzte Ausführung vollständig erledigt ist.
			
	}
end

To control the solvis, you had the possibility to call the solvisRemote-URL and simulate the mouse-clicks (as you do it, when you are at keyboard and mouse).
This is a work for the http-binding.
But I don’t know how it ist possible to make a request with the needed authentification “digest”.
Does anyone knows this ?
You can find this solution in the fhem-community-board Ansteuerung SolvisMax/Solvis-Remote

Greetings
Wolfgang

Those of us who run openHAB in regions of harsh environmental conditions (ie. temperatures in winter actually drop below 0°C… :wink:) will eventually notice that Wolfgang’s code can be improved to account for the fact that java-method parseInt could also be referred to as parseUInt:

All temperature values sent by SOLVIS’s Remote-Interface are 16bit-values represented in two’s complement notation! As long as the readings are greater than zero, the code above works fine.
But if sensors located outside of the building (eg. flow temperature of solar panels (S8v) or outdoor sensor (S10v)) report values less than 0, one will have to transform the 16bit-data words in order to not end up with garbled temperature readings!

For myself, I found following solution:

// Add two temporary variables for S8v and S10v
var Integer S8v = Integer.parseInt(rawdata.substring(67,69)+rawdata.substring(65,67),16)
var Integer S10v = Integer.parseInt(rawdata.substring(75,77)+rawdata.substring(73,75),16)
// take care of two's complement representation, if applicable
if (S8v > 32767) { S8v = S8v - 65536 }
if (S10v > 32767) { S10v =  S10v - 65536 }

Then, in the postUpdate -Block of Wolfgang’s snippet, replace the update lines for the both sensors by

GF_Heating_Solvis_S8v.postUpdate(S8v/10.floatValue())
GF_Heating_Solvis_S10v.postUpdate(S10v/10.floatValue())

I’m sure there are more elegant ways to code that (I tried to implement a function, doing the math) but honestly - Xtend and me have a hard time becoming friends…

Greetings,
-bernie

1 Like

Thank you, Bernie, for your nice addition.
In fact, temperature values <0 degrees are shown in Solvis as described by you.
Your supplement correctly displays the values in openHab.

Greetings

Wolfgang

This solution made day - 2 small comments from my side:

1.) In FoxWhiskeys Code: Shouldn’t it be “results.substring…” instead of “rawdata.substring…” to match Wolfgangs code?

2,) Instead of running CURL to retrieve the XML string from Solvis, I am using a HTTP URL Thing which can easily be configured in the GUI, but CURL of course works . In case you want to go this way, this the code for the HTTP GET thing on openhab 4:

ID: http:url:899f563c80
label: SolvisXMLFile
thingTypeUID: http:url
configuration:
ignoreSSLErrors: true
stateMethod: GET
refresh: 300
commandMethod: GET
encoding: text/xml
timeout: 3000
authMode: DIGEST
baseURL: http://192.168.x.y
password: CHANGEME
delay: 0
contentType: application/xml
bufferSize: 4096
username: CHANGEME
location: Heizungskeller
channels:

  • id: SolvisXMLString
    channelTypeUID: http:string
    label: SolvisXMLString
    description: “”
    configuration:
    stateExtension: sc2_val.xml
  1. Yes, that’s correct. Apparently I copy&pasted parts of my own implementation. :smirk:
  2. Another neat way to kill a cat :wink:
1 Like