abbrechen
Suchergebnisse werden angezeigt für 
Anzeigen  nur  | Stattdessen suchen nach 
Meintest du: 
Beantwortet! Gehe zur Lösung.

Some code to receive info from the Viessmann boiler

Here is some code I have put together in order to receive basic info from the Viessmann boiler. I have used HTML and PHP.

 

<html> 
 <title>Viessmann boiler info</title>
 <body>

 <h1>Viessmann boiler info</h1>

<?php

$installationId = "Replace with your installation id";
$gatewaySerial = "Replace with your gateway serial";
$deviceId = "Replace with your device Id";


$getURL='https://api.viessmann.com/iot/v1/equipment/installations/'.$installationId.'/gateways/'.$gatewaySerial.'/devices/'.$deviceId.'/features';

$headerRequest = array(
		"Content-Type: application/x-www-form-urlencoded",
		"Authorization: Bearer $autorizationTOKEN"
);

  
$cURLConnection = curl_init();
curl_setopt($cURLConnection, CURLOPT_USERAGENT, "Mozilla/5.0 (compatible; MSIE 7.01; Windows NT 5.0)");
curl_setopt($cURLConnection, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($cURLConnection, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($cURLConnection, CURLOPT_FOLLOWLOCATION, 0);
curl_setopt($cURLConnection, CURLOPT_RETURNTRANSFER,true);
curl_setopt($cURLConnection, CURLOPT_HTTPHEADER, $headerRequest); 
curl_setopt($cURLConnection, CURLOPT_CONNECTTIMEOUT, 130);
curl_setopt($cURLConnection, CURLOPT_TIMEOUT, 130);
curl_setopt($cURLConnection, CURLOPT_URL,$getURL);

$apiResponse = curl_exec($cURLConnection);
$apiErr = curl_error($cURLConnection);

curl_close($cURLConnection);

$jsonResponse = json_decode($apiResponse, true);

echo "<br><br><br>";
print_r($jsonResponse);
print_r($apiErr);
echo "<br><br><br>";


$BurnerHours = $jsonResponse['data']['29']['properties']['hours']['value'];
echo "BurnerHours: ".$BurnerHours."<br>";

$BurnerStarts = $jsonResponse['data']['29']['properties']['starts']['value'];
echo "BurnerStarts: ".$BurnerStarts."<br>";

$MeasureUnit = $jsonResponse['data']['15']['properties']['value']['unit'];
if ($MeasureUnit == "celsius") {
		$MU = " &deg;C ";
	} else {
		$MU = " &deg;F ";
	}

$TemperatureCommon = $jsonResponse['data']['15']['properties']['value']['value'];
echo "TemperaturaTur: ".$TemperatureCommon." ".$MU."<br>";

$HotWaterSet = $jsonResponse['data']['4']['properties']['value']['value'];
$HotWater = $jsonResponse['data']['20']['properties']['value']['value'];
echo "HotWater: ".$HotWaterSet." / ".$HotWater." ".$MU."<br>";

$RadiatorsSet = $jsonResponse['data']['1']['properties']['temperature']['value'];
$Radiators = $jsonResponse['data']['31']['properties']['value']['value'];
echo "Radiators: ".$RadiatorsSet ." / ".$Radiators." ".$MU."<br>";


?>

<div style="position:relative; ">
			<img src="sistem_termic.png" alt="cetrala" style="display:block; margin-left:auto; margin-right:auto; "> 
	<div style="position:absolute; top: 12%; left:52%; font-size:150%; ">
		<?php echo "Boiler<br>".
			"TemperatureCommon: ".number_format($RadiatorsSet,0).$MU."<br>".
			"BurnerHours: ".$BurnerHours."<br>".
			"BurnerStarts: ".$BurnerStarts."<br>";?>
	</div>
	<div style="position:absolute; top: 53%; left:27%; font-size:150%; text-align:right; ">
		<?php echo "Water heating<br>".
			"Set: ".number_format($HotWaterSet,0).$MU."<br>".
			"Current: ".number_format($HotWater,0).$MU."<br>";?>
	</div>
	<div style="position:absolute; top: 53%; left:50%; font-size:150%; ">
		<?php echo "Radiators<br>".
			"Set: ".number_format($RadiatorsSet,0).$MU."<br>".
			"Current: ".number_format($Radiators,0).$MU."<br>";?>
	</div>
</div>

<br><br><br><br><br><br>

</body>
 </html>

 

And the result is presented in the attached screenshot. 

2021-09-27 19_18_43-Viessmann - Brave.png
1 AKZEPTIERTE LÖSUNG

Akzeptierte Lösungen

Thank you for all questions and contributions. As a result I have updated the code and posted a new version here:

https://www.viessmann-community.com/t5/Getting-started-programming-with/Some-code-to-receive-info-fr...

Regards,

Lösung in ursprünglichem Beitrag anzeigen

19 ANTWORTEN 19

@SorinB Thank you very much for sharing your code! This will definitely help others in start developing with the API.
Much appreciated!

@MichaelHanna, did you test the code?
@SorinB, your code is not functional as it is.
Where is the "$ autorizationTOKEN" variable?
Can you provide "sistem_termic.png"?
Best regards

The code is functional only after you get the following variables

$autorizationTOKEN
$installationId
$gatewaySerial
$deviceId

 

For this preliminary steps, documentation is available here:

https://developer.viessmann.com/en/doc/getting-started

and with more details, after you login, here

https://developer.viessmann.com/en/doc/authentication

 

Also you can take a lock at this post:

https://www.viessmann-community.com/t5/Getting-started-programming-with/To-help-get-started/td-p/181...

 

I have attached the background .PNG. Strongly encourage to design your own and share. Mine is not much.

 

All best,

S

sistem_termic.png

Note that the returned JSON array order is not assured! Initially I used the array indices  as well and had to change my code afterwards!

True, 

it looks like from time to time the order of the data points is changing. I do not know yet what in causing this change. It can be a boiler restart, a restart of the boiler communication gateway or something else.

Regards

@JueBag Thank you for pointing that out.

 

There is no defined order for the returned JSON array. I recommend analysing the using names to sort the values.

 

CC: @SorinB

HI,

If we go data point to data point we will have about 7 queries to the server. If we query the entire list of features will have only one query. Is there any solution to simplify the process?

Regards,

You can call for one datapoint, several points or all!

See this example from my javascript rule which is requesting several datapoints:

url ="https://api.viessmann.com/iot/v1/equipment/installations/"+ installationID +"/gateways/" +gatewaySerial + "/devices/0/features?regex=heating.(sensors.temperature.outside%7Cdhw.(oneTimeCharge%7Csensors.temperature.hotWaterStorage%7Cpumps.circulation)%7Cburners.0.statistics%7Ccircuits.0.operating.modes.active)";

 

The "%7" is used instead of the "|" character.

Very good suggestion. I will publish an update of the code accordingly.

So the $getURL variable would be updated as follows. It will be registered as a single transaction, however it is not clear if the JSON order will preserve. For the moment the reply for each data point is not provided in the order stated in the URL. I will return in couple of days after I can test the code in the boiler premises,

 

$getURL='https://api.viessmann.com/iot/v1/equipment/installations/'.$installationId.'/gateways/'.$gatewaySeri...'
.'heating.burners'.'%7C'
.'heating.burners.0.statistics'.'%7C'
.'heating.boiler.sensors.temperature.commonSupply'.'%7C'
.'heating.dhw.temperature.main'.'%7C'
.'hotWaterStorage'.'%7C'
.'heating.circuits.0.operating.programs.normal'.'%7C'
.'heating.circuits.0.sensors.temperatue.room';

Quote: "however it is not clear if the JSON order will preserve."

 

That is assured, the order does change so you can't use the array index for parsing the results!

So, at the end of the day we remint with 7 queries to the server instead of one ...

Maybe would be good for the syntax to be reviewed and place al data points as elements in an array ([]) rather than displaying them as "objects" ({}). Just a thought ...

What makes you think so?

 

Try something like that:

 


var returnvalue = HTTP.sendHttpGetRequest(url, headers, 10*1000);
logger.info("returnvalue: {}", returnvalue);
//var arr=returnvalue;
returnvalue = JSON.parse(returnvalue);
var count = returnvalue.data.length;
logger.info("count: {}", count);
try {
for (var i = 0; i < count; i++) {
switch (returnvalue.data[i].feature) {
case "heating.sensors.temperature.outside":
var temp = returnvalue.data[i].properties.value.value;
events.postUpdate('OutsideTemperature', temp);
logger.info("DataIndex: {}, ExtTemp: {}", i,temp);
break;
case "heating.dhw.sensors.temperature.hotWaterStorage":
var temp = returnvalue.data[i].properties.value.value;
events.postUpdate('BoilerTemperature', temp);
logger.info("DataIndex: {}, HotWaterStorageTemp: {}", i, temp);
break;
case "heating.dhw.oneTimeCharge":
var temp = returnvalue.data[i].properties.active.value;
temp = (temp === true) ? 'on' : 'off';
events.postUpdate('IsOneTimeCharge', temp);
logger.info("DataIndex: {}, OneTimeCharge: {}",i, temp);
break;
case "heating.dhw.pumps.circulation":
temp = returnvalue.data[i].properties.status.value;
events.postUpdate('DhwPumpsCirculation', temp);
logger.info("DataIndex: {}, DhwPumpsCirculation: {}",i, temp);
break;
case "heating.burners.0.statistics":
temp = returnvalue.data[i].properties.hours.value;
events.postUpdate("HeatingBurnerStatistics_Hours",temp);
logger.info("DataIndex {}, Hours: {}", i, temp);
temp = returnvalue.data[i].properties.starts.value;
events.postUpdate("HeatingBurnerStatistics_Starts",temp)
logger.info("DataIndex: {}, Starts: {}", i, temp);
break;
case "heating.circuits.0.operating.modes.active":
temp= returnvalue.data[i].properties.value.value;
events.postUpdate("ActiveMode", temp);
logger.info("DataIndex: {}, ActiveMode: {}", i, temp);
break;
default:
logger.info("DataIndex: {}, Data not used: {}",i, returnvalue.data[i].feature);
}

 

I'm using those lines after the request posted above.

Sorry for no code tags, can't find them using my smartphone😎.

Thank you,

Solved. In PHP I have used ”usorit”.  Just 3 lines after 

 

$jsonResponse = json_decode($apiResponse, true);

 

 

include:

 

usort($jsonResponse['data'], function($a,$b){
return $a["feature"]>$b["feature"];
});

 

 

Thank you for all questions and contributions. As a result I have updated the code and posted a new version here:

https://www.viessmann-community.com/t5/Getting-started-programming-with/Some-code-to-receive-info-fr...

Regards,

The usort will help, but this is also not the best solution. Since 13.12.2021 i have new values in the $jsonResponse and so the indexes of the array are misleading. The Code should be corrected to extract the values by the name of the feature and not by a hardcoded index of an (sorted) array.

 

Regards,

Bernhard

 

Hi @BernhardW1 ,

 

Thank you for comments. Indeed I have faced this problems and as result on 26.10.2021 I have published an updated version of the code. Check this link:

https://www.viessmann-community.com/t5/Getting-started-programming-with/Some-code-to-receive-info-fr...

 

Regards,

Sorin

I have adopted the example  to make it more robust if the number of items or the order of the items will change in the array:

$jsonResponse = json_decode($response, true);

function getEntryByFeatureName($resp, $feature)
{
    for($i = 0; $i < sizeof($resp["data"]); $i++)
    if ($resp["data"][$i]["feature"] == $feature)
    return $resp["data"][$i];
}

echo getEntryByFeatureName($jsonResponse, "heating.sensors.temperature.outside")['properties']['value']['value'];

The reason for ( a lot of ) more datapoints being returned started on Dec 2nd for me. Actually the used Regex statement was not used and ALL datapoints were returned.

This misbehaviour was corrected today. 

 

However the order of the returned datapoints is NOT fixed, for that reason the USORT function will not help!