[VitoConnect] Getting readings from Viessmann Heating system via VitoConnect

Note: As of July15th 2021 Viessmann will close down this soultion! A (temporary solution is available: https://community.openhab.org/t/vitoconnect-getting-values-sending-commands-via-the-new-api-by-using-rules/123900).

Solution for getting and setting readings from your Viessmann heating system via a connected VitoConnect 100 unit. The later connects to a Viessmann server only via your local Wifi, however the needed data can be requested from that server.

Note: YES, this is not the “normal” way for a openHAB solution, i.e. using only data from own sources. Look at the Vitotronic Binding with all its requirements if you are not comfortable with this cloudbased approach.

The solution is based on code written by the french Github-user “thetrueavatar”, who made it real easy to use the Viessmann API. A big MERCI BEAUCOUP goes to “thetrueavatar”.
The code can be found here.

Prerequisites:

  1. PHP7 and Curl installed on the System ( use “sudo apt-get instal php” AND “sudo apt-get install php-curl” for installation)
  2. User credential for ViCare App
  3. Exec Binding installed on openHAB

On the above posted Github-Link, navigate to the Code page page and select the Example folder. From the displayed files download the files “Viessmann-Api-x.y-SNAPSHOT.phar” (the x.y Version number might change and the "SNAPSHOT might be dropped in the future), “bootstrap.php”, and “credentials.properties” and paste them into the “scripts” folder of your openHAB system.
Edit the “credential.properties” and fill in your username and password, each in a seperate line. Save the file.
[Updated]
For getting values use a one single php file for all requests (that way the needed token is requested only once) and call the script via a rule.

Create a new .php file with following entries (for example to get the Outside Temperature and HotWater Temperature, the values are seperated by a “@” sign!):

<?php include __DIR__.'/bootstrap.php';
echo $viessmannApi->getOutsideTemperature();
echo "@";
echo $viessmannApi->getHotWaterStorageTemperature();

and save it, for example GetValues.php.
Make the file executable for owner and group.
You can test it from the commandline with.

php GetValues.php

For other readings refer to the Example folder.

Item Definitions:

String OutsideTemperature "OutsideTemperature [%s °C]" String BoilerTemperature "BoilerTemperature [%s °C]`

Use a rule like:

rule "GetValues"
  when
     Time cron "10 0/5 * * * ?" //called every five minutes
  then
    var result=executeCommandLine("php@@/etc/openhab2/scripts/GetValues.php",5000)
    OutsideTemperature.postUpdate( result.split("@").get(0)) 
    BoilerTemperature.postUpdate( result.split("@").get(1))
  end

For setting values create a new .php file with following entries (for example for setting the heating curve).

SetCurve.php

<?php
include __DIR__.'/bootstrap.php';
$slope=$viessmannApi->getSlope();
$shift=$viessmannApi->getShift();
if (count($argv)>1) {
        if (count($argv)==2 ) {
                //One argument given, has to be Shift!!
                echo $viessmannApi->setCurve($argv[1], $slope);
                echo "Shift set!"."\n";
        }
        if (count($argv)==3 ) {
                //Two arguments given, has to be Shift followed by Slope!!
                echo $viessmannApi->setCurve($argv[1], $argv[2]);
                echo "Slope and Shift set!"."\n";
        }
         
} else {
        echo "Nothing set!"."\n";   
}     

This script takes shift and slope as commandline arguments.

Make the file executable for owner and group.
You can test it from the commandline with:

php SetCurve.php

It can run with one or two commands or with none!

In openHAB you can start it through a rule like:

rule "Test"
  when
     Item Test changed
  then
    var String slope="0.8"
    var String shift="4"
    logInfo("Test", "Start")
    var result=executeCommandLine("php@@/etc/openhab2/scripts/MyScript.php@@" + slope + "@@" + shift,6000)
    logInfo ("Test", "Result: {}", result)
end

The hardcoded values for slope and shift could easily be connected to setpoint items!

NOTE: The decimal point in the rule HAS TO BE set according the language setting of your system when started via the openHAB rule! In my case (german) I have to set it to “0,8”!

5 Likes

@GeorgJ interested?

Setting the slope and shift of the heating-curve is working also.

php-Files

GetSlope.php

&lt;?php include __DIR__.'/bootstrap.php';
echo $viessmannApi->getSlope();

SetSlope.php

&lt;?php include __DIR__.'/bootstrap.php';
echo $viessmannApi->setCurve("8", "0.8");

Yes, shift and slope are hardcoded ATM!

Thing Definitions:

Thing exec:command:getSlope [command="php  /etc/openhab2/scripts/GetSlope.php", intervall= 60, autorun=false]
Thing exec:command:setslope [command="php  /etc/openhab2/scripts/SetSlope.php", intervall= 60, autorun=false]

Item Definitions:

String GetSlope "Slope [%s °]" {channel="exec:command:getSlope:output"}
Switch YourTrigger {channel="exec:command:setCurve:run"}

The setCurve code is run when switching to ON!

[This has been incooperated into the initial post!]

Thanks Juergen,
yes am interested and will work on it - but it may take 2 to 3 weeks until I can finish it.
Georg

Hi Jürgen,
had alreday some time to test.
I installed php on my openhab2 Server and tried to run the php scripts.
php Shows following Version:

PHP 7.0.30-0+deb9u1 (cli) (built: Jun 14 2018 13:50:25) ( NTS )
Copyright (c) 1997-2017 The PHP Group
Zend Engine v3.0.0, Copyright (c) 1998-2017 Zend Technologies
with Zend OPcache v7.0.30-0+deb9u1, Copyright (c) 1999-2017, by Zend Technologies

I receive following errors:

  • → php GetOutsideTemperature.php
    PHP Notice: Use of undefined constant CURLOPT_URL - assumed ‘CURLOPT_URL’ in phar:///tmp/viessmann/Viessmann-Api-0.4-SNAPSHOT.phar/src/Oauth/ViessmannOauthClientImpl.php on line 81
    PHP Notice: Use of undefined constant CURLOPT_HTTPHEADER - assumed ‘CURLOPT_HTTPHEADER’ in phar:///tmp/viessmann/Viessmann-Api-0.4-SNAPSHOT.phar/src/Oauth/ViessmannOauthClientImpl.php on line 82
    PHP Notice: Use of undefined constant CURLOPT_SSL_VERIFYPEER - assumed ‘CURLOPT_SSL_VERIFYPEER’ in phar:///tmp/viessmann/Viessmann-Api-0.4-SNAPSHOT.phar/src/Oauth/ViessmannOauthClientImpl.php on line 83
    PHP Notice: Use of undefined constant CURLOPT_RETURNTRANSFER - assumed ‘CURLOPT_RETURNTRANSFER’ in phar:///tmp/viessmann/Viessmann-Api-0.4-SNAPSHOT.phar/src/Oauth/ViessmannOauthClientImpl.php on line 84
    PHP Notice: Use of undefined constant CURLOPT_USERPWD - assumed ‘CURLOPT_USERPWD’ in phar:///tmp/viessmann/Viessmann-Api-0.4-SNAPSHOT.phar/src/Oauth/ViessmannOauthClientImpl.php on line 85
    PHP Notice: Use of undefined constant CURLOPT_HTTPAUTH - assumed ‘CURLOPT_HTTPAUTH’ in phar:///tmp/viessmann/Viessmann-Api-0.4-SNAPSHOT.phar/src/Oauth/ViessmannOauthClientImpl.php on line 86
    PHP Notice: Use of undefined constant CURLAUTH_BASIC - assumed ‘CURLAUTH_BASIC’ in phar:///tmp/viessmann/Viessmann-Api-0.4-SNAPSHOT.phar/src/Oauth/ViessmannOauthClientImpl.php on line 86
    PHP Notice: Use of undefined constant CURLOPT_POST - assumed ‘CURLOPT_POST’ in phar:///tmp/viessmann/Viessmann-Api-0.4-SNAPSHOT.phar/src/Oauth/ViessmannOauthClientImpl.php on line 87
    PHP Fatal error: Uncaught Error: Call to undefined function Viessmann\Oauth\curl_init() in phar:///tmp/viessmann/Viessmann-Api-0.4-SNAPSHOT.phar/src/Oauth/ViessmannOauthClientImpl.php:89
    Stack trace:
    #0 phar:///tmp/viessmann/Viessmann-Api-0.4-SNAPSHOT.phar/src/Oauth/ViessmannOauthClientImpl.php(56): Viessmann\Oauth\ViessmannOauthClientImpl->getCode()
    #1 phar:///tmp/viessmann/Viessmann-Api-0.4-SNAPSHOT.phar/src/API/ViessmannAPI.php(43): Viessmann\Oauth\ViessmannOauthClientImpl->__construct(Array)
    #2 /tmp/viessmann/bootstrap.php(13): Viessmann\API\ViessmannAPI->__construct(Array)
    #3 /tmp/viessmann/GetOutsideTemperature.php(2): include(‘/tmp/viessmann/…’)
    #4 {main}
    thrown in phar:///tmp/viessmann/Viessmann-Api-0.4-SNAPSHOT.phar/src/Oauth/ViessmannOauthClientImpl.php on line 89

Unfortunate I can’t reed the php protocol - don’t know what to correct.

I have tested the whole staff on a “fresh” Raspberry System - this works for mentioned method without problems, the corrrect temperature was send

Any suggestion - what is going wrong?
Thanks Georg

Not really.
The php I installed is the same as yours!
It sounds as if cURL is the problem.
My testing system was build with openhabian, additionally installed only php.
What is the difference between your systems, the one with the error and the fresh install without?

What do you get on this command: “apt-cache search curl” ?
Installing cURL might be the solution.

Hello, I’m the developper of the api. My api requires php-curl to be installed so php is able to call curl through code. To install it on a debian-like system(such as raspbian) just do

sudo apt-get install php-curl

should fix the problem. I have added the information on the wiki.
For information, I highly recommand to combine all the api call into one php file. It wil be more efficient cause authentication will only be done once and the Oauth2 token will be reused through every call.
I have done one file per method in example because it was the easier way for me to integrate it with jeedom command.
Please note I have provided a sample of Error Handling into example/GetActiveModeErrorHandling.php
This is quite usefull since some method might not be available on some viessmann device(gas consumption for instance). Most of the time Viessmann return a “FEATURE_NOT_FOUND” as message when the function is not available or not yet exposed through the service.
Best Regards,

1 Like

Welcome @thetrueavatar and thanks again for the code provided.

I changed the posted requirements in the OP.

Thanks thetrueavatar and Jürgen.
This solved my Problems.
Georg

That is understood, however that would need to code to be moved to a rule or a binding. My knowledge of cURL is rather limited, but I’m m already considering it. As I understand it, the API is still worked on, so for a binding it migth be a bit early.
Also one has to bear in mind that users probably want to use only a limited number of features via OH.

Well, I’m still working on it for some improvement but I would say that 90% of the work is done. I still have to work on a more elegant way to set schedule. Viessmann service only provide a full write of the schedule without possibility to add period one by one. I should take some time to watch how Vicare does but I suspect it also push the whole schedule every time. Gas consumption data provided by the service are currently buggy. You have to multiply data by 8 to get value corresponding to what’s displayed on the heating. Moreover data seems completely bugged when consumption >256kwh

I saw those problems concerning the consumption data.
IMHO the change of schedules is overdoing it. Unless you have an UI with restricted access (which openHAB does not) I would limit the access to reading some data (temperatures consumption, actual modes) and setting one-time-heating of water and Comfort-mode for the heating.All other settings are handled better by a limited number of persons/UIs, But that is my opinion.
So I would go a for a single request for all getters and for each set a own request.

Checking the logs I see intermittently errors like:

PHP Fatal error:  Uncaught Viessmann\API\ViessmannApiException: Unable to get data for feature heating.sensors.temperature.outside    Reason: DEVICE_COMMUNICATION_ERROR in phar:///etc/openhab2/scripts/Viessmann-Api-0.4-SNAPSHOT.phar/src/API/ViessmannAPI.php                                          :280

Since this error comes and goes without changing the files I suspect that the Viessmann server somehow does react on to many calls in a short timeframe.

I got this same here two days ago and it just ust I came back without any intervention. I thought it was my vitocoonect which wasn’t able to connect but no this was the viessmann services which was in error

@thetrueavatar have you looked deeper into the Token in order to find the time the token is valid? Follwing request could use the old token if it is still valid. That way the load on the server could be decreased and the observed error might not happen (that often).

Well it’s already managed. I’ve used an outh2 library which store token so that once the token is created it will always use the same token as long as he is still valid. If you reuse the same viessmannApi instance then token will be reused

OK.
That way I think can only be done via a OH binding, when using a rule or script would restart the at every iteration and by that create a new instance. At least that is my humble understanding.

Indeed Token is currently store in current call session. I’m rather new to PHP so doesn’t know if there is a kind of global session or static scope such in java. If not token could be serialised in text file anyway.

No kidding. Your code was the first PHP I was working with.
We did some tries with “Postman” today but didn’t succeed😡. Have you been able to get the responses with “Postman”?

In order to reduce the load on the server I suggest to use a single php file for all GET-requests. That is only a initial solution! The intial post has been updated for that.

1 Like