[VitoConnect] Getting values/sending commands via the "new" API by using rules@

The Viessmann-Api of @thetrueavatar is not really working reliable any more. Sometimes it works, but most time it doesn’t. It’s really strange.

Did anybody implement the Authentication Process into a rule to create a new RefreshToken once it is getting invalid after half a year?

@STSC

I am the developer of the SmartHome/J Viessmann Binding and have previously contributed to the Viessmann-API by @thetrueavatar. Since I wanted a direct implementation in OpenHAB as a binding, I focused on it. I am constantly developing the binding.
You can find the documentation here:
https://docs.smarthomej.org/3.2.14/org.smarthomej.binding.viessmann.html

Just add this https://download.smarthomej.org/addons.json JSON third party addons in settings area

I’m not sure if I can use the binding.
Can I trigger the binding in a rule to start a OneTimeDhwCharge and afterwards read back the status of the OneTimeDhwCharge, if it was really started:

var startOneTimeCharge=executeCommandLine(Duration.ofSeconds(12), "php","/etc/openhab/scripts/StartOneTimeCharge.php").toString.replace('\n', '')
Thread::sleep(1000)
var newStatusOneTimeCharge=executeCommandLine(Duration.ofSeconds(12), "php","/etc/openhab/scripts/StatusOneTimeCharge.php").toString.replace('\n', '')

Yes, there is a channel for OneTimeCharge. If the OneTimeCharge is not successfully started, the channel state will be updated at the next polling

If I set OneTimeCharge will it be executed immediately or at the next poll? Is it possible to request a poll in a rule, the next poll is just too late?

The switch is working immidiatly, so it will be working as rule as well.

1 Like

Why do you need this response immediately?

When a command is sent to the API, you get a response as to whether the command was executed correctly. If not, then a poll is carried out. This way you can be sure that the command was executed correctly

I need the status immediately to send the OneTimeChargeStatus back to KNX. Once OneTimeCharge has started I call another rule which checks every minute if OneTimeCharging is still ongoing.

Would it be possible to get a separate item/switch, which I can set in a rule to request an additional poll and maybe a busy status item to check it the poll is currently ongoing? Then I think I have everything to use the binding. Thanks!

Hello, I want to share with the community a php script to initially get or to renew access and refresh token (after 180 days).

<?php

/*
php script to get refresh access token from viessmann API
version: 2022-11-12
*/

// initalizes global parameters
$authorizeURL = "https://iam.viessmann.com/idp/v2/authorize";
$tokenURL = "https://iam.viessmann.com/idp/v2/token";
$callbackUri = "http://localhost:4200/";
//$scope = "IoT User offline_access"; // hard coded
$responseType = "code";
$grantType = "authorization_code";


// initalizes user specific parameters
$clientId = "xxxxx"; // the cliend id, get if rom Viessmann online
$codeChallenge = "yyyyyyyy"; // recommended to use: https://developer.pingidentity.com/en/tools/pkce-code-generator.html
//$codeVerifier = "yyyyyyyyxxxxxx"; // the use of code verifier will lead to error; this is in contratiction to Viessmann access guideline documentation
$user = "the-user-name-as-used-for-Vicare-app"; // the user name as used for Vicare, e.g., "userAB"
$pwd = "the-PW-as-used-for-Vicare"; // the PW as used for Vicare, e.g., "xYz4trPw"
$installationId = "xyz"; // the specific id of the device, get it from Viessmann online
$gatewaySerial = "xyzqwertz"; // the specific serial of communication interface device, look at your VitoConnect device
$device_id = "0"; // the device id, is "0" if only a single device exists


// Step 1, authorization request
echo("############\n");
echo("# <step 1> #\n");
echo("############\n");

$url = "$authorizeURL?client_id=$clientId&code_challenge=$codeChallenge&scope=IoT%20User%20offline_access&redirect_uri=$callbackUri&response_type=$responseType";
$header = array("Content-Type: application/x-www-form-urlencoded");

$curloptions = array(
    CURLOPT_URL => $url,
    CURLOPT_HTTPHEADER => $header,
    CURLOPT_SSL_VERIFYPEER => false,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_USERPWD => "$user:$pwd",
    CURLOPT_HTTPAUTH => CURLAUTH_BASIC,
    CURLOPT_POST => true,
);

// calls curl 

$curl = curl_init();
curl_setopt_array($curl, $curloptions);
$response = curl_exec($curl);
curl_close($curl);

// outputs response
echo($response);
echo("\n==============================================\n");

// extracts code from response 

$matches = array();
$pattern = '/code=(.*)"/';
if (preg_match_all($pattern, $response, $matches)) {
    $code = $matches[1][0];
} else {
    exit("Failed to get authorization code"."\n");
}
echo("\n======================================================\n");
echo("\nthis is the returned code in step 1, use it in step 2:\n\n");
echo($code);
echo("\n\n======================================================\n");

// Token Settings, Step 2
//
echo("############\n");
echo("# <step 2> #\n");
echo("############\n");

$url = "$tokenURL?grant_type=$grantType&code_verifier=$codeChallenge&client_id=$clientId&redirect_uri=$callbackUri&code=$code";
$header = array("Content-Type: application/x-www-form-urlencoded");

$curloptions = array(
    CURLOPT_URL => $url,
    CURLOPT_HTTPHEADER => $header,
    CURLOPT_SSL_VERIFYPEER => false,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPAUTH => CURLAUTH_BASIC,
    CURLOPT_POST => true,
);

// calls curl 

$curl = curl_init();
curl_setopt_array($curl, $curloptions);
$response = curl_exec($curl);
curl_close($curl);

// extracts token

$json = json_decode($response, true);
$token = $json['access_token'];




// beautifies output of response

$json = json_decode($response, true);
$accessToken = $json['access_token'];
$refreshToken = $json['refresh_token'];
$tokenType = $json['token_type'];
$expiresIn = $json['expires_in'];
echo("\n");
echo("#############################################\n");
echo("# copy following and save it in a txt file  #");
echo("#############################################\n");
echo("\n======================================================================\n\n");
echo("{\n");
echo("access_token : ");
echo($accessToken);
echo("\n\n");
echo("refresh_token : ");
echo($refreshToken);
echo("\n\n");
echo("token_type : ");
echo($tokenType);
echo("\n\n");
echo("expires_in : ");
echo($expiresIn);
echo("\n}\n");




// verifies success with reading user data 

echo("\n=====================================================================\n\n");
echo("verifies success with reading user data\n");

$url = "https://api.viessmann.com/users/v1/users/me?sections=identity";
$header = array("Authorization: Bearer $token");

$curloptions = array(
    CURLOPT_URL => $url,
    CURLOPT_HTTPHEADER => $header,
    CURLOPT_SSL_VERIFYPEER => false,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPAUTH => CURLAUTH_BASIC,
);


// calls curl

$curl = curl_init();
curl_setopt_array($curl, $curloptions);
$response = curl_exec($curl);
curl_close($curl);

echo($response);
echo("\n==============================================\n");
1 Like

The above mentioned Smarthome/j Viessman Binding is having this functionality as well.

Tried to install and setup the binding.
I configured Client ID, e-mail and password and I get connection errors:
[viessmann.internal.api.ViessmannAuth] - ViessmannAuth: Login failed. Wrong code response.

It actually works with the other API binding ( Viessmann API binding - Add-on Marketplace / Bundles - openHAB Community but that one does not yet support (still a bit strange that two bidnings are developped in parallel).

Anyway, I’d like to try out your binding but I can’t see what’s going wrong here. I’m on Openhab 3.4 M4.
Any help would be highly appreciated!

Did you add the RedirectURI “http://localhost:8080/viessmann/authcode/” in the Developer Portal for your ClientId?

Yes, that throws an error message too: invalid-code-request.
How can I increase log levels?

log:set TRACE org.smarthomej.binding.viessmann

Thanks a lot, it was a faulty callback uri. Works now :slight_smile:

1 Like

Hey guys from Czech Republic :slight_smile:
I just got a brand new old model :confused: Vitocal 200-S and Vitoconnect opto2.
I already started googling as to how I could connect to modbus etc. and only from this very thread I realized that with Vitoconnect I am connected to Viessmann directly and can send request to the api :slight_smile:

Thanks for all the examples and the work that you’ve did.
My goal is to connect to my neighbor’s app which I am running on my barebone synology nas, in docker - in Java.
It’s able to work with spot prices, graphs etc and some smart wall plugs
We have some work to do, but thanks for the kick start :slight_smile:

I already tried calling the installations with my new token from viess dev. portal, thanks for that.

Now, next step is to figure out what’s wrong with the call to one time charge, thanks for the example, I guess the v1 is wrong ?

{
    "viErrorId": "req-0be117a7d3f94e81aa9ee4cf2dea53f1",
    "statusCode": 422,
    "errorType": "VALIDATION_ERROR",
    "message": "VALIDATION_ERROR",
    "validationErrors": [
        {
            "path": [
                "commandBody"
            ],
            "type": "any.invalid",
            "message": "invalid value, most likely wrong format"
        }
    ],
    "extendedPayload": {
        "commandBody": "EMPTY_MODEL"
    }
}

Thanks !