<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>Thema "Betreff: Shell-Script to publish data to MQTT" in Getting started programming with the Viessmann API</title>
    <link>https://community.viessmann.de/t5/Getting-started-programming-with/Shell-Script-to-publish-data-to-MQTT/m-p/243930#M206</link>
    <description>&lt;P&gt;Moin Flo,&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Ich vermute eher das User/Passwort ein paar lustige Zeichen enthält die vom Script fehlinterpretiert werden.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Typische problematische Zeichen wären " ! ( $ &amp;amp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Grüße&lt;/P&gt;&lt;P&gt;Andreas&amp;nbsp;&lt;/P&gt;</description>
    <pubDate>Tue, 05 Jul 2022 10:23:30 GMT</pubDate>
    <dc:creator>MrAnderson</dc:creator>
    <dc:date>2022-07-05T10:23:30Z</dc:date>
    <item>
      <title>Shell-Script to publish data to MQTT</title>
      <link>https://community.viessmann.de/t5/Getting-started-programming-with/Shell-Script-to-publish-data-to-MQTT/m-p/196096#M120</link>
      <description>&lt;P&gt;Hello,&lt;/P&gt;&lt;P&gt;I created a small script to publish the data of all endpoints to a MQTT server .&lt;/P&gt;&lt;P&gt;Inspired by&amp;nbsp;&lt;a href="https://community.viessmann.de/t5/user/viewprofilepage/user-id/40821"&gt;@SorinB&lt;/a&gt;&amp;nbsp;and the nice small PHP script and the help of&amp;nbsp;&lt;a href="https://community.viessmann.de/t5/user/viewprofilepage/user-id/29136"&gt;@CustomerCareMichael&lt;/a&gt;&amp;nbsp;to open my eyes &lt;span class="lia-unicode-emoji" title=":zwinkerndes_Gesicht:"&gt;😉&lt;/span&gt; I ended up in this setup.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;What you need:&lt;/P&gt;&lt;UL&gt;&lt;LI&gt;any kind of Linux server (I'm using a RaspberryPi)&lt;/LI&gt;&lt;LI&gt;json_pp, jq, curl, sed, grep, cat, sort, tr are the commands I'm using in the script&lt;/LI&gt;&lt;LI&gt;mosquitto_pub is not necessary when publishing the data to something different (used at the end of the script)&lt;/LI&gt;&lt;/UL&gt;&lt;P&gt;What you may need:&lt;/P&gt;&lt;UL&gt;&lt;LI&gt;mosquitto_pub&lt;/LI&gt;&lt;LI&gt;MQTT server (Mosquitto prefered)&lt;/LI&gt;&lt;LI&gt;Telegraf to feed a timeseries database&amp;nbsp;&lt;/LI&gt;&lt;LI&gt;InfluxDB as a timeseries database&lt;/LI&gt;&lt;LI&gt;Grafana to visualize the data&lt;/LI&gt;&lt;/UL&gt;&lt;P&gt;Prerequisites:&lt;/P&gt;&lt;OL&gt;&lt;LI&gt;Create a developer account and an API-Key at&amp;nbsp;&lt;A href="https://developer.viessmann.com/de/clients" target="_self"&gt;https://developer.viessmann.com/de/clients&lt;/A&gt;&amp;nbsp;&lt;/LI&gt;&lt;LI&gt;Create a challenge id with this small tool:&amp;nbsp;&lt;A href="https://tonyxu-io.github.io/pkce-generator/" target="_self"&gt;https://tonyxu-io.github.io/pkce-generator/&lt;/A&gt;&amp;nbsp;&lt;/LI&gt;&lt;LI&gt;User 1. and 2. and your user and password used in the ViCare app and put them into the small script in lines 8 (client id), 10 (challenge id), 11 (user) and 12 (password)&lt;/LI&gt;&lt;LI&gt;Line 13 can be modified to have a prefix like "viessmann-testing" to get started and when you are ready change it to "viessmann". This prefix is used for the topic to be published to MQTT&lt;/LI&gt;&lt;LI&gt;Line 14 is a directory where all the working files are stored, this can be /dev/shm or /tmp, it will be created when the scripts starts.&lt;/LI&gt;&lt;LI&gt;Line 15 to 18 are the credentials and host:port parameter for MQTT server&lt;/LI&gt;&lt;LI&gt;Line 19 is the number of the device queried in (getDeviceId). May be you have more than one device like I have but 1 is a good start. Check the file devices.json in the directory provided in line 14&lt;/LI&gt;&lt;/OL&gt;&lt;P&gt;Now you can run the script on the command line and when it works you can add it to the crontab and execute every 5 minutes. It is also possible to use Telegraf to transport the values into an InfluxDB and Grafana to query that database &lt;span class="lia-unicode-emoji" title=":leicht_lächelndes_Gesicht:"&gt;🙂&lt;/span&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="ruby"&gt;#!/bin/bash


#############################
# Constants to change
#############################

export client_id="client_id"
export redirect_uri="http://localhost:4200/oauth-callback"
export challenge_id="challenge_id"
export email="username from ViCare App"
export password="password"
export prefix="prefix if necessary"
export dirPrefix="/dev/shm/$prefix"
export mqttHost="127.0.0.1"
export mqttPort="1883"
export mqttUser="mqtt"
export mqttPassword="mqtt"
export number=1
mkdir -p $dirPrefix &amp;gt;/dev/null 2&amp;gt;&amp;amp;1

############################################################################
# Show a banner
############################################################################
banner() {
  echo "+------------------------------------------+"
  printf "| %-40s |\n" "`date`"
  echo "|                                          |"
  printf "|`tput bold` %-40s `tput sgr0`|\n" "$@"
  echo "+------------------------------------------+"
}

############################################################################
# Get access token or create new one when last login older than 1400 minutes
# otherwise refresh token when token older than 59 minutes
############################################################################
getAccessToken() {
	export auth_url="https://iam.viessmann.com/idp/v2/authorize"
	export scope="IoT%20User%20offline_access"
	export response_type="code"

	export token_url="https://iam.viessmann.com/idp/v2/token"
	export grant_type="authorization_code"

        export countLoginHtml=$(find $dirPrefix -cmin -59 -name login.html | wc -l)
	if [ $countLoginHtml -eq 0 ]; then # file older 1400 minutes, get new access token
		curl -c $dirPrefix/cookies.txt -H "Content-Type: application/x-www-form-urlencoded" \
        		-X POST "$auth_url?client_id=$client_id&amp;amp;redirect_uri=$redirect_uri&amp;amp;response_type=$response_type&amp;amp;code_challenge=$challenge_id&amp;amp;scope=$scope" \
        		-u "$email:$password" \
        		-o $dirPrefix/login.html &amp;gt;/dev/null 2&amp;gt;&amp;amp;1

		export code=$(grep $redirect_uri $dirPrefix/login.html | sed -E 's/(^.*code=)([^"]*)(.*)/\2/g')
		curl -b $dirPrefix/cookies.txt --basic -c $dirPrefix/cookies.txt -H "Content-Type: application/x-www-form-urlencoded" \
        		-X POST "$token_url" \
        		--data-urlencode "grant_type=$grant_type" \
        		--data-urlencode "code_verifier=$challenge_id" \
        		--data-urlencode "client_id=$client_id" \
        		--data-urlencode "redirect_uri=$redirect_uri" \
        		--data-urlencode "code=$code" \
        		-o $dirPrefix/access_token.json &amp;gt;/dev/null 2&amp;gt;&amp;amp;1
	fi

        export countAccessToken=$(find $dirPrefix -cmin -59 -name access_token.json | wc -l)
	if [ $countAccessToken -eq 0 ]; then # file older 59 minutes, get new access token with refresh token
		export refresh_token=$(sed -E 's/^.*"refresh_token":"([^"]).*/\1/g' $dirPrefix/access_token.json)
		curl -b $dirPrefix/cookies.txt --basic -c $dirPrefix/cookies.txt -H "Content-Type: application/x-www-form-urlencoded" \
		        -X POST "$token_url" \
		        --data-urlencode "grant_type=refresh_token" \
		        --data-urlencode "client_id=$client_id" \
		        --data-urlencode "refresh_token=$refresh_token" \
		        -o $dirPrefix/access_token.json &amp;gt;/dev/null 2&amp;gt;&amp;amp;1
	fi
	export access_token=$(sed -E 's/^\{"access_token":"([^"]*).*/\1/g' $dirPrefix/access_token.json)
	echo $access_token
}

############################################################################
# Just show the user profile in pretty print json format
############################################################################
showUserProfile() {
	banner "Show user profile"
	export profile_url="https://api.viessmann.com/users/v1/users/me?sections=identity"
	curl -b $dirPrefix/cookies.txt --basic -c $dirPrefix/cookies.txt -H "Authorization: Bearer $(getAccessToken)" \
        	-X GET "$profile_url" \
        	-o $dirPrefix/userprofile.json &amp;gt;/dev/null 2&amp;gt;&amp;amp;1

	cat $dirPrefix/userprofile.json | json_pp
}

############################################################################
# Get the installation id
############################################################################
getInstallationId() {
	if [ ! -f $dirPrefix/installation.json ]; then
		export installation_url="https://api.viessmann.com/iot/v1/equipment/installations"
        	curl -b $dirPrefix/cookies.txt --basic -c $dirPrefix/cookies.txt -H "Authorization: Bearer $(getAccessToken)" \
                	-X GET "$installation_url" \
                	-o $dirPrefix/installation.json &amp;gt;/dev/null 2&amp;gt;&amp;amp;1
	fi
	export installationId=$(sed -E 's/^.*"id":([^,]*).*/\1/g' $dirPrefix/installation.json)
	echo $installationId 
}

############################################################################
# Get the gateway serial
############################################################################
getGatewaySerial() {
        if [ ! -f $dirPrefix/gateway.json ]; then
		export gateway_url="https://api.viessmann.com/iot/v1/equipment/gateways"
                curl -b $dirPrefix/cookies.txt --basic -c $dirPrefix/cookies.txt -H "Authorization: Bearer $(getAccessToken)" \
                        -X GET "$gateway_url" \
                        -o $dirPrefix/gateway.json &amp;gt;/dev/null 2&amp;gt;&amp;amp;1
        fi
	export gatewaySerial=$(sed -E 's/^.*"serial":"([^"]*).*/\1/g' $dirPrefix/gateway.json)
        echo $gatewaySerial 
}

############################################################################
# Get the device id
############################################################################
getDeviceId() {
        if [ ! -f $dirPrefix/devices.json ]; then
		
		curl -b $dirPrefix/cookies.txt --basic -c $dirPrefix/cookies.txt -H "Authorization: Bearer $(getAccessToken)" \
			-X GET "https://api.viessmann.com/iot/v1/equipment/installations/$(getInstallationId)/gateways/$(getGatewaySerial)/devices" \
			-o $dirPrefix/devices.json &amp;gt;/dev/null 2&amp;gt;&amp;amp;1

        fi
	export deviceNumber=$1
	export deviceId=$(cat $dirPrefix/devices.json | json_pp | grep '"id"' | sed -n "${deviceNumber}p" | sed -E 's/^.*"id" : "([^"]*).*/\1/g')
        echo $deviceId 
}


############################################################################
# Get features
############################################################################
getFeatures() {
	export deviceNumber=$1
	curl -b $dirPrefix/cookies.txt --basic -c $dirPrefix/cookies.txt -H "Authorization: Bearer $(getAccessToken)" \
		-X GET "https://api.viessmann.com/iot/v1/equipment/installations/$(getInstallationId)/gateways/$(getGatewaySerial)/devices/$(getDeviceId $deviceNumber)/features" \
		-o $dirPrefix/features-$deviceNumber.json &amp;gt;/dev/null 2&amp;gt;&amp;amp;1
}

getFeatures $number 

############################################################################
# publish the data to MQTT
############################################################################
cat $dirPrefix/features-$number.json | jq '.data[].feature' | tr -d '"' | sort -u &amp;gt; $dirPrefix/feature.dat
cat $dirPrefix/feature.dat | while read feature
do
        cat $dirPrefix/features-$number.json | jq '.data[] | select(.feature == "'$feature'") | .properties | keys[]' | tr -d '"' | sort -u &amp;gt; $dirPrefix/topic.dat
        cat $dirPrefix/topic.dat | while read topic
        do
                export TOPIC=$(echo $feature.$topic | sed 's/\./\//g')
                cat $dirPrefix/features-$number.json | jq '.data[] | select(.feature == "'$feature'") | .properties.'$topic'.value' &amp;gt; $dirPrefix/$feature.$topic.dat
                #curl -d @$dirPrefix/$feature.$topic.dat $mqttUrl/$TOPIC
		mosquitto_pub -h $mqttHost -p $mqttPort -u $mqttUser -P $mqttPassword -t $prefix/$TOPIC -f $dirPrefix/$feature.$topic.dat
        done
done&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;You can see an example how it may looks like. I'm not finished yet, still some endpoints missing in the Grafana and the API seems to be incomplete. I couldn't find all the data the ViCare is showing..&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;// Andreas&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Wed, 10 Nov 2021 20:54:47 GMT</pubDate>
      <guid>https://community.viessmann.de/t5/Getting-started-programming-with/Shell-Script-to-publish-data-to-MQTT/m-p/196096#M120</guid>
      <dc:creator>MrAnderson</dc:creator>
      <dc:date>2021-11-10T20:54:47Z</dc:date>
    </item>
    <item>
      <title>Betreff: Shell-Script to publish data to MQTT</title>
      <link>https://community.viessmann.de/t5/Getting-started-programming-with/Shell-Script-to-publish-data-to-MQTT/m-p/243928#M205</link>
      <description>&lt;P&gt;Hallo Andreas,&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;ich habe versucht, dein Skript auf meinem Raspberry Pi zu nutzen und bin gemäß deiner wirklich tollen und ausführlichen Anleitung vorgegangen.&lt;/P&gt;&lt;P&gt;Das Problem ist, dass offenbar die Authentifizierung nicht klappt. Im vom Skript erzeugten File access_token.json steht lediglich "{"error:"internal server error"}".&amp;nbsp;&lt;/P&gt;&lt;P&gt;Im File devices.json steht unter anderem "statusCode":401,"errorType":"UNAUTHORIZED","message":"Token provided in request is expired or invalid."&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Ich habe die "manuelle" Authentifizierung nach der Viessmann-Doku hinbekommen und konnte über den RPi auch schon manuell curl-Request senden und habe entsprechende Response erhalten. Demnach sollten die Daten für clientID, challengeID, User und Passwort korrekt sein.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Hast du hier vielleicht noch einen Tip für mich?&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Danke und viele Grüße&lt;/P&gt;&lt;P&gt;Flo&lt;/P&gt;</description>
      <pubDate>Tue, 05 Jul 2022 10:18:30 GMT</pubDate>
      <guid>https://community.viessmann.de/t5/Getting-started-programming-with/Shell-Script-to-publish-data-to-MQTT/m-p/243928#M205</guid>
      <dc:creator>FloE</dc:creator>
      <dc:date>2022-07-05T10:18:30Z</dc:date>
    </item>
    <item>
      <title>Betreff: Shell-Script to publish data to MQTT</title>
      <link>https://community.viessmann.de/t5/Getting-started-programming-with/Shell-Script-to-publish-data-to-MQTT/m-p/243930#M206</link>
      <description>&lt;P&gt;Moin Flo,&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Ich vermute eher das User/Passwort ein paar lustige Zeichen enthält die vom Script fehlinterpretiert werden.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Typische problematische Zeichen wären " ! ( $ &amp;amp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Grüße&lt;/P&gt;&lt;P&gt;Andreas&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Tue, 05 Jul 2022 10:23:30 GMT</pubDate>
      <guid>https://community.viessmann.de/t5/Getting-started-programming-with/Shell-Script-to-publish-data-to-MQTT/m-p/243930#M206</guid>
      <dc:creator>MrAnderson</dc:creator>
      <dc:date>2022-07-05T10:23:30Z</dc:date>
    </item>
    <item>
      <title>Betreff: Shell-Script to publish data to MQTT</title>
      <link>https://community.viessmann.de/t5/Getting-started-programming-with/Shell-Script-to-publish-data-to-MQTT/m-p/243934#M207</link>
      <description>&lt;P&gt;Hi Andreas,&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;du bist mein persönlicher Held des Tages!&amp;nbsp;&lt;span class="lia-unicode-emoji" title=":grinsendes_Gesicht:"&gt;😀&lt;/span&gt;&lt;/P&gt;&lt;P&gt;Es war tatsächlich eines der Zeichen im Passwort. Passwort geändert und nun funktioniert es tadellos.&lt;/P&gt;&lt;P&gt;Tausend Dank dir.&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Viele Grüße&lt;/P&gt;&lt;P&gt;Flo&lt;/P&gt;</description>
      <pubDate>Tue, 05 Jul 2022 10:40:15 GMT</pubDate>
      <guid>https://community.viessmann.de/t5/Getting-started-programming-with/Shell-Script-to-publish-data-to-MQTT/m-p/243934#M207</guid>
      <dc:creator>FloE</dc:creator>
      <dc:date>2022-07-05T10:40:15Z</dc:date>
    </item>
    <item>
      <title>Betreff: Shell-Script to publish data to MQTT</title>
      <link>https://community.viessmann.de/t5/Getting-started-programming-with/Shell-Script-to-publish-data-to-MQTT/m-p/336366#M408</link>
      <description>&lt;P&gt;Hallo Andreas,&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;ist das Script noch aktuell ?&lt;/P&gt;&lt;P&gt;In der Datei access_token.json steht {"error":"invalid-token-request"}&lt;/P&gt;&lt;P&gt;und es gibt im Passwort kein Sonderzeichen.&lt;/P&gt;&lt;P&gt;Ich versuche mit der API meine VX3 Solaranlage auszulesen.&lt;/P&gt;</description>
      <pubDate>Fri, 19 May 2023 15:37:00 GMT</pubDate>
      <guid>https://community.viessmann.de/t5/Getting-started-programming-with/Shell-Script-to-publish-data-to-MQTT/m-p/336366#M408</guid>
      <dc:creator>petkow</dc:creator>
      <dc:date>2023-05-19T15:37:00Z</dc:date>
    </item>
  </channel>
</rss>

