{"id":4988,"date":"2021-09-28T16:00:00","date_gmt":"2021-09-28T15:00:00","guid":{"rendered":"https:\/\/www.marshflattsfarm.org.uk\/wordpress\/?page_id=4988"},"modified":"2025-05-26T14:01:44","modified_gmt":"2025-05-26T13:01:44","slug":"nibe-heat-pump-monitoring-via-nibe-uplink-api-python-version","status":"publish","type":"page","link":"https:\/\/www.marshflattsfarm.org.uk\/wordpress\/?page_id=4988","title":{"rendered":"NIBE Heat Pump Monitoring via NIBE Uplink API (Python Version)"},"content":{"rendered":"\n<h1 class=\"wp-block-heading\">Introduction<\/h1>\n\n\n\n<p>Back in 2016 I wrote <a rel=\"noreferrer noopener\" href=\"https:\/\/www.marshflattsfarm.org.uk\/wordpress\/?page_id=3480\" data-type=\"page\" data-id=\"3480\" target=\"_blank\">this earlier page<\/a> on querying the <a rel=\"noreferrer noopener\" href=\"https:\/\/www.nibeuplink.com\/\" target=\"_blank\">NIBE Uplink<\/a> <a rel=\"noreferrer noopener\" href=\"https:\/\/api.nibeuplink.com\/\" target=\"_blank\">API<\/a> using Perl scripts running on a particular flavour of Linux system. Based on the comments and questions received, this clearly proved useful for a number of readers but I&#8217;ve been aware for some time that Perl is not (any longer) a popular scripting language and making sense of JSON responses within a Perl script is much more difficult than in some other scripting languages &#8211; notably Python. I&#8217;ve recently been learning Python for other reasons and found it to be better when handling JSON responses. I&#8217;ve therefore re-written the earlier guidance notes to use Python instead. The Python-specific page you are reading now is an updated replacement for <a rel=\"noreferrer noopener\" href=\"https:\/\/www.marshflattsfarm.org.uk\/wordpress\/?page_id=3480\" data-type=\"page\" data-id=\"3480\" target=\"_blank\">the earlier Perl-specific page<\/a> but contains the same background information. The older page is still there for reference but most people will want to follow this newer page instead.<\/p>\n\n\n\n<p>For readers familiar with the previous notes, be aware I&#8217;ve made some minor changes to the instructions:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>The script that requests the tokens now prompts you with the Authorization URL to connect to, so you don&#8217;t have to compose that manually from the documented template<\/li><li>The code examples are now stored in <a href=\"https:\/\/github.com\/MarshFlattsFarm\/NIBE-Uplink-API\" target=\"_blank\" rel=\"noreferrer noopener\">a repository on GitHub<\/a> rather than being pasted into this page<\/li><\/ul>\n\n\n\n<p>Since Python is quite tolerant of running on other platforms than Linux I&#8217;ve included guidance for running on either Microsoft Windows or a Linux variant such as Raspberry Pi OS. Code examples are written to be as tolerant as possible of different platform requirements. Note that this page assumes the use of a recent release of Python version 3.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Disclaimer<\/h2>\n\n\n\n<p>This procedure works for me and I&#8217;m publishing it here as a Proof of Concept in case it helps other people trying to accomplish the same objective. It may not work for you. It may not get updated in line with changes to the NIBE Uplink API service. You are responsible for complying with the terms of the NIBE Uplink API Services Agreement and for keeping the application Identifier, Secret and any generated user Tokens confidential.<\/p>\n\n\n\n<p>As with all other material on this Blog this article is published under the terms of the <a href=\"https:\/\/creativecommons.org\/licenses\/by-sa\/4.0\/\" target=\"_blank\" rel=\"noreferrer noopener\">Creative Commons Attribution-ShareAlike 4.0 International License<\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">NIBE Uplink versus myUplink<\/h2>\n\n\n\n<p>My NIBE <strong>F<\/strong>-Series heat pump, made in 2016, uses the <a rel=\"noreferrer noopener\" href=\"https:\/\/api.nibeuplink.com\/\" target=\"_blank\">NIBE Uplink API.<\/a> The new NIBE <strong>S<\/strong>-Series heat pumps released in 2020 appear to use the alternative <a rel=\"noreferrer noopener\" href=\"https:\/\/dev.myuplink.com\/login\" target=\"_blank\">myUplink API<\/a> (in parallel with the <a href=\"https:\/\/myuplink.com\/\" target=\"_blank\" rel=\"noreferrer noopener\">myUplink<\/a> website). As a result, these instructions are only directly relevant if you have an F-Series heat pump.<\/p>\n\n\n\n<p>Having said that, from a quick look at the myUplink documentation, it appears to be based on almost identical technologies; in particular, it appears to use OAuth2 for Authentication.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">My Use Case<\/h2>\n\n\n\n<p>I have an 8kW NIBE F1145 Ground Source Heat Pump which is configured to send data to the NIBE Uplink service over the Internet. The uploaded data is accessible via the NIBE Uplink website and via the NIBE Uplink smartphone apps, but those apps use the API &#8216;under the covers&#8217; and it&#8217;s possible to call the API directly from a custom program or script to access all the same data &#8211; and then do more interesting things with it.<\/p>\n\n\n\n<p>I have written a script which invokes the NIBE Uplink API on a timed schedule (every 5 minutes) to download the parameters I&#8217;m interested in which I then re-publish using <a rel=\"noreferrer noopener\" href=\"https:\/\/en.wikipedia.org\/wiki\/MQTT\" target=\"_blank\">MQTT<\/a> (my personal preference; in no sense essential) to integrate them with temperature data from other sources (Dallas Semiconductor One-Wire sensors and Oregon Scientific temperature \/ humidity sensors &#8211; see other pages on this Blog for more details of those if you&#8217;re interested). Everything then gets loaded into an <a rel=\"noreferrer noopener\" href=\"https:\/\/en.wikipedia.org\/wiki\/InfluxDB\" target=\"_blank\">InfluxDB<\/a> time-series database from which it can be extracted and graphed with <a rel=\"noreferrer noopener\" href=\"http:\/\/grafana.org\/\" target=\"_blank\">Grafana<\/a> (again my personal preferences but they work well for me).<\/p>\n\n\n\n<p>An example of the sort of dashboard generated by Grafana is shown below but to be honest a static screenshot doesn&#8217;t do it justice since hovering over any of the graphs displays the numeric data values and clicking on one or more of the labels in a legend shows just those lines (and auto-scales to suit). Scrolling left and right across different time periods and zooming in and out is also easy and slick.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"alignright\"><a href=\"http:\/\/www.marshflattsfarm.org.uk\/wordpress\/?attachment_id=3537\" rel=\"attachment wp-att-3537\"><img loading=\"lazy\" decoding=\"async\" width=\"1236\" height=\"910\" src=\"http:\/\/www.marshflattsfarm.org.uk\/wordpress\/wp-content\/uploads\/2016\/11\/NIBEUplinkGrafana.png\" alt=\"NIBE Heat Pump Dashboard using data extracted via the NIBE Uplink API\" class=\"wp-image-3537\" srcset=\"https:\/\/www.marshflattsfarm.org.uk\/wordpress\/wp-content\/uploads\/2016\/11\/NIBEUplinkGrafana.png 1236w, https:\/\/www.marshflattsfarm.org.uk\/wordpress\/wp-content\/uploads\/2016\/11\/NIBEUplinkGrafana-300x221.png 300w, https:\/\/www.marshflattsfarm.org.uk\/wordpress\/wp-content\/uploads\/2016\/11\/NIBEUplinkGrafana-768x565.png 768w, https:\/\/www.marshflattsfarm.org.uk\/wordpress\/wp-content\/uploads\/2016\/11\/NIBEUplinkGrafana-1024x754.png 1024w, https:\/\/www.marshflattsfarm.org.uk\/wordpress\/wp-content\/uploads\/2016\/11\/NIBEUplinkGrafana-407x300.png 407w\" sizes=\"auto, (max-width: 1236px) 100vw, 1236px\" \/><\/a><figcaption>NIBE Heat Pump Dashboard using data extracted via the NIBE Uplink API<\/figcaption><\/figure><\/div>\n\n\n\n<h1 class=\"wp-block-heading\">Pre-Requisites<\/h1>\n\n\n\n<p>At a bare minimum you will need the following to use this procedure:<\/p>\n\n\n\n<ol class=\"wp-block-list\"><li>A <a rel=\"noreferrer noopener\" href=\"https:\/\/www.nibeuplink.com\/\" target=\"_blank\">NIBE Uplink<\/a> account with at least one (F-Series) heat pump registered to it and reporting data which is viewable via the website or one of the smartphone apps.<ul><li>Anyone can use the &#8220;Register an account&#8221; button on the main NIBE Uplink page to create an account if you don&#8217;t have one, but unless you have a heat pump linked to the account the API won&#8217;t return any data.<\/li><\/ul><\/li><li>A computer which is able to access the Internet and which will run the Python script to download data via the API.<ul><li>It doesn&#8217;t need to be particularly powerful &#8211; a <a rel=\"noreferrer noopener\" href=\"https:\/\/en.wikipedia.org\/wiki\/Raspberry_Pi\" target=\"_blank\">Raspberry Pi<\/a> or similar single-board-computer is perfectly adequate. It could also be a virtual server hosted in the Cloud, or a Windows desktop or laptop.<\/li><\/ul><ul><li>It doesn&#8217;t need to run a web browser or have a graphical display attached &#8211; remote access via a terminal window using a tool like PuTTY or &#8216;ssh&#8217; is sufficient.<\/li><\/ul><\/li><li>An Internet-connected computer with a standard graphical web browser (Firefox, Internet Explorer, Safari etc.) which can be used to complete Steps 1 and 2 in the procedure described below. This can be any platform you like &#8211; potentially even a Smartphone &#8211; and certainly could be the same computer described at Item 2 above if that meets the requirements, though typically it will be a different machine.<ul><li>If the computer running the browser is not the same as the one running the script, then ensure you can connect to the computer running the script, since you will need to copy-and-paste a long text string between the two, accurately and quickly.<\/li><\/ul><\/li><li>A basic knowledge of the <a rel=\"noreferrer noopener\" href=\"https:\/\/en.wikipedia.org\/wiki\/Python_(programming_language)\" target=\"_blank\">Python<\/a> scripting language, editing files and installing software packages on your chosen platform.<\/li><\/ol>\n\n\n\n<h2 class=\"wp-block-heading\">NIBE Uplink API &#8211; Documentation and Underpinning Technologies<\/h2>\n\n\n\n<p>The official documentation for the NIBE Uplink API is at <a href=\"https:\/\/api.nibeuplink.com\/docs\/v1\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/api.nibeuplink.com\/docs\/v1<\/a> (note you need to login to access that page). The detail is described on those pages but in summary:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>It&#8217;s a <a href=\"https:\/\/en.wikipedia.org\/wiki\/Representational_state_transfer\" target=\"_blank\" rel=\"noreferrer noopener\">RESTful<\/a> API accessed over HTTPS<\/li><li>Data is encoded using <a href=\"https:\/\/en.wikipedia.org\/wiki\/JSON\" target=\"_blank\" rel=\"noreferrer noopener\">JSON<\/a><\/li><li>All requests are authenticated using <a href=\"https:\/\/en.wikipedia.org\/wiki\/OAuth#OAuth_2.0\" target=\"_blank\" rel=\"noreferrer noopener\">OAuth2<\/a><ul><li>This presents the single biggest challenge because you need to obtain a valid Token and then Refresh that whenever it Expires<\/li><\/ul><\/li><\/ul>\n\n\n\n<p>Personally I found the biggest barrier to getting the API working was understanding what the OAuth2 <strong>Callback URL<\/strong> was all about and what would be an acceptable value to use for that (there are several constraints). Actually it&#8217;s not all <em>that<\/em> complicated and it only needs to be used once, in order to initially get an Access Token. Importantly, it&#8217;s possible to run some steps in the procedure on different machines (as long as they&#8217;re done in quick succession). Here&#8217;s a summary of how it works:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>When one of your application&#8217;s users (most likely yourself in this scenario) enters their NIBE Uplink credentials in a browser window and agrees to grant your application access to their data, the NIBE Uplink website redirects them to the <strong>Callback URL<\/strong>, attaching an Authorization Code which is only valid for a limited time and can only be presented once<\/li><li>Before the code expires, it&#8217;s necessary to present it to the NIBE Uplink <strong>Token URL<\/strong> together with other application-specific parameters in order to be allocated an Access Token and an accompanying Refresh Token<\/li><li>As long as you can get the Authentication Code presented to the Token URL before it expires, you can do that from anywhere &#8211; it doesn&#8217;t need to be from the same machine as is hosting the <strong>Callback URL<\/strong> though that is typically the scenario described in other OAuth2 documentation<\/li><\/ul>\n\n\n\n<p>I believe it&#8217;s necessary for the <strong>Callback URL<\/strong> to use HTTP<strong>S<\/strong> and since that can be problematic to configure I&#8217;m hosting a simple script on the same server as this Blog which anyone should be able to specify as their <strong>Callback URL<\/strong> &#8211; it will simply print out the generated Authorization Code (or any error message). That URL is: <a rel=\"noreferrer noopener\" href=\"https:\/\/www.marshflattsfarm.org.uk\/nibeuplink\/oauth2callback\/index.php\" target=\"_blank\">https:\/\/www.marshflattsfarm.org.uk\/nibeuplink\/oauth2callback\/index.php<\/a> (which will complain unless you call it with the right parameters &#8211; see later).<\/p>\n\n\n\n<p>(I&#8217;m going to assume the nice people at NIBE Uplink will permit multiple applications to be registered which have the same Callback URL &#8211; which does indeed appear to be the case.)<\/p>\n\n\n\n<p>If you want to host your own installation of the <strong>Callback URL<\/strong> the PHP script code I&#8217;m using can be download from GitHub <a href=\"https:\/\/github.com\/MarshFlattsFarm\/NIBE-Uplink-API\/blob\/main\/oauth2callback\/index.php\" data-type=\"URL\" data-id=\"https:\/\/github.com\/MarshFlattsFarm\/NIBE-Uplink-API\/blob\/main\/oauth2callback\/index.php\" target=\"_blank\" rel=\"noreferrer noopener\">here<\/a>.<\/p>\n\n\n\n<p>The Python library <a rel=\"noreferrer noopener\" href=\"https:\/\/requests-oauthlib.readthedocs.io\/en\/latest\/index.html\" target=\"_blank\">Requests-<\/a><a rel=\"noreferrer noopener\" href=\"https:\/\/requests-oauthlib.readthedocs.io\/en\/latest\/oauth2_workflow.html\" target=\"_blank\">OAuthlib<\/a> is used to hide much of the complexity of OAuth2 processing. The documentation at that link explains how to use that though in principle if you exactly follow the procedure outlined below you don&#8217;t need to understand in detail how it works.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Step-By-Step Procedure<\/h1>\n\n\n\n<h2 class=\"wp-block-heading\">Step 0 &#8211; Prepare the Python Computer<\/h2>\n\n\n\n<p>The computer which will run the script that calls the NIBE Uplink API needs some preparation to ensure the Python environment and the necessary supporting Python libraries are available.<\/p>\n\n\n\n<ol class=\"wp-block-list\"><li>The first requirement is a working Python3 environment<ul><li>On Windows, follow the instructions at <a rel=\"noreferrer noopener\" href=\"https:\/\/www.python.org\/downloads\/windows\/\" target=\"_blank\">Python Releases for Windows<\/a><\/li><li>On Raspberry Pi OS, run:  <code>sudo apt-get install python3<\/code><\/li><\/ul><\/li><li>The second requirement is the Requests-OAuthlib library<ul><li>On Windows, use a Command Prompt to run:  <code>pip3 install requests-oauthlib<\/code><\/li><li>On Raspberry Pi OS, can install this with:  <code>sudo pip3 install requests-oauthlib<\/code><ul><li>If that doesn&#8217;t work, you might need to first run:  <code>sudo apt-get install python3-pip<\/code><\/li><\/ul><\/li><\/ul><\/li><\/ol>\n\n\n\n<h2 class=\"wp-block-heading\">Step 1 &#8211; Register your &#8216;Application&#8217;<\/h2>\n\n\n\n<p>The Python script you are about to create that will call the NIBE Uplink API is what the API calls an &#8216;Application&#8217; so start by Registering the new Application at the NIBE Uplink website so that you get allocated your various unique ID strings which will be required later.<\/p>\n\n\n\n<ol class=\"wp-block-list\"><li>Connect to <a rel=\"noreferrer noopener\" href=\"https:\/\/api.nibeuplink.com\/\" target=\"_blank\">https:\/\/api.nibeuplink.com\/<\/a>&nbsp;using your favourite web browser on any machine you like (it does not need to be the machine which will later run the Python script)<\/li><li>Login with your NIBE Uplink username and password<\/li><li>Click on the <strong>MY APPLICATIONS<\/strong> tab<\/li><li>Press the red <strong>Create application <\/strong>button<\/li><li>Populate the <strong>Name<\/strong>, <strong>Description<\/strong> and <strong>Callback URL<\/strong> fields &#8211; choose your own values for <strong>Name<\/strong> (maybe &#8220;Python API Script&#8221; as shown) and <strong>Description<\/strong> and either specify your own <strong>Callback URL<\/strong> (if you&#8217;ve set one up hosting the PHP code mentioned above) or use <a rel=\"noreferrer noopener\" href=\"https:\/\/www.marshflattsfarm.org.uk\/nibeuplink\/oauth2callback\/index.php\" target=\"_blank\">https:\/\/www.marshflattsfarm.org.uk\/nibeuplink\/oauth2callback\/index.php<\/a><\/li><li>Read the <strong>Services Agreement<\/strong>, click to confirm your acceptance of that &#8211; at this point the screen should look like the image below:<br><img loading=\"lazy\" decoding=\"async\" width=\"640\" height=\"425\" class=\"wp-image-5009\" style=\"width: 640px;\" src=\"https:\/\/www.marshflattsfarm.org.uk\/wordpress\/wp-content\/uploads\/2021\/09\/NIBE_Uplink-Create_application.png\" alt=\"\" srcset=\"https:\/\/www.marshflattsfarm.org.uk\/wordpress\/wp-content\/uploads\/2021\/09\/NIBE_Uplink-Create_application.png 1170w, https:\/\/www.marshflattsfarm.org.uk\/wordpress\/wp-content\/uploads\/2021\/09\/NIBE_Uplink-Create_application-300x199.png 300w, https:\/\/www.marshflattsfarm.org.uk\/wordpress\/wp-content\/uploads\/2021\/09\/NIBE_Uplink-Create_application-1024x680.png 1024w, https:\/\/www.marshflattsfarm.org.uk\/wordpress\/wp-content\/uploads\/2021\/09\/NIBE_Uplink-Create_application-768x510.png 768w, https:\/\/www.marshflattsfarm.org.uk\/wordpress\/wp-content\/uploads\/2021\/09\/NIBE_Uplink-Create_application-452x300.png 452w\" sizes=\"auto, (max-width: 640px) 100vw, 640px\" \/><\/li><li>Press the <strong>Create application<\/strong> button<\/li><li>Record the allocated <strong>Identifier<\/strong> and <strong>Secret<\/strong> strings and <strong>keep them secret!<\/strong> (you can view them later under <strong>MY APPLICATIONS<\/strong> if required).<\/li><\/ol>\n\n\n\n<h2 class=\"wp-block-heading\">Step 2 &#8211; Create an Access Token using an Authorization Code<br><a href=\"http:\/\/www.marshflattsfarm.org.uk\/wordpress\/?attachment_id=3542\"><\/a><\/h2>\n\n\n\n<ol class=\"wp-block-list\"><li>Download the first sample Python script from the GitHub repository<ul><li>If you&#8217;re familiar with GitHub and you have the &#8216;Git&#8217; client software installed, you might wish to &#8216;clone&#8217; the repository (don&#8217;t worry if those words don&#8217;t make sense &#8211; do one of the following instead)<\/li><li>Alternatively, browse to the <a rel=\"noreferrer noopener\" href=\"https:\/\/github.com\/MarshFlattsFarm\/NIBE-Uplink-API\" target=\"_blank\">GitHub repository page<\/a> and download the <code>request_token.py<\/code> file<\/li><li>Alternatively, run this command in a terminal window: <code>wget https:\/\/github.com\/MarshFlattsFarm\/NIBE-Uplink-API\/raw\/main\/request_token.py<\/code><\/li><\/ul><\/li><li>Edit the downloaded Python script with whichever editor you prefer and replace the definitions of <code>client_id<\/code> and <code>client_secret<\/code> with the <strong>Identifier<\/strong> and <strong>Secret<\/strong> strings from Step 1<\/li><li>In a terminal window, run the command: <code>python3 request_token.py<\/code><\/li><li>The script will display a long URL which you should copy and paste into a Web Browser window<\/li><li>Assuming you&#8217;re already logged in to the NIBE Uplink API website (e.g. having just created your Application) in the same Browser you won&#8217;t be prompted for your credentials, otherwise expect to have to enter your Username and Password<\/li><li>Expect to see a page like the screenshot below (you&#8217;ll see the <strong>Name<\/strong> you specified rather than &#8220;Python API Script&#8221; if you changed it). This is NIBE Uplink asking you to grant permission for your script to act on behalf of your user account.<br><img loading=\"lazy\" decoding=\"async\" width=\"640\" height=\"199\" class=\"wp-image-5010\" style=\"width: 640px;\" src=\"https:\/\/www.marshflattsfarm.org.uk\/wordpress\/wp-content\/uploads\/2021\/09\/NIBE_Uplink-Read_Data.png\" alt=\"\" srcset=\"https:\/\/www.marshflattsfarm.org.uk\/wordpress\/wp-content\/uploads\/2021\/09\/NIBE_Uplink-Read_Data.png 1649w, https:\/\/www.marshflattsfarm.org.uk\/wordpress\/wp-content\/uploads\/2021\/09\/NIBE_Uplink-Read_Data-300x93.png 300w, https:\/\/www.marshflattsfarm.org.uk\/wordpress\/wp-content\/uploads\/2021\/09\/NIBE_Uplink-Read_Data-1024x319.png 1024w, https:\/\/www.marshflattsfarm.org.uk\/wordpress\/wp-content\/uploads\/2021\/09\/NIBE_Uplink-Read_Data-768x239.png 768w, https:\/\/www.marshflattsfarm.org.uk\/wordpress\/wp-content\/uploads\/2021\/09\/NIBE_Uplink-Read_Data-1536x478.png 1536w, https:\/\/www.marshflattsfarm.org.uk\/wordpress\/wp-content\/uploads\/2021\/09\/NIBE_Uplink-Read_Data-500x156.png 500w\" sizes=\"auto, (max-width: 640px) 100vw, 640px\" \/><\/li><li>Convince reCAPTCHA that you&#8217;re not a robot, at which point the screen should look like this:<br><img loading=\"lazy\" decoding=\"async\" width=\"640\" height=\"217\" class=\"wp-image-5011\" style=\"width: 640px;\" src=\"https:\/\/www.marshflattsfarm.org.uk\/wordpress\/wp-content\/uploads\/2021\/09\/NIBE_Uplink-Not_A_Robot.png\" alt=\"\" srcset=\"https:\/\/www.marshflattsfarm.org.uk\/wordpress\/wp-content\/uploads\/2021\/09\/NIBE_Uplink-Not_A_Robot.png 1646w, https:\/\/www.marshflattsfarm.org.uk\/wordpress\/wp-content\/uploads\/2021\/09\/NIBE_Uplink-Not_A_Robot-300x102.png 300w, https:\/\/www.marshflattsfarm.org.uk\/wordpress\/wp-content\/uploads\/2021\/09\/NIBE_Uplink-Not_A_Robot-1024x348.png 1024w, https:\/\/www.marshflattsfarm.org.uk\/wordpress\/wp-content\/uploads\/2021\/09\/NIBE_Uplink-Not_A_Robot-768x261.png 768w, https:\/\/www.marshflattsfarm.org.uk\/wordpress\/wp-content\/uploads\/2021\/09\/NIBE_Uplink-Not_A_Robot-1536x522.png 1536w, https:\/\/www.marshflattsfarm.org.uk\/wordpress\/wp-content\/uploads\/2021\/09\/NIBE_Uplink-Not_A_Robot-500x170.png 500w\" sizes=\"auto, (max-width: 640px) 100vw, 640px\" \/><\/li><li>Press the <strong>Accept<\/strong> button<\/li><li>If everything works you&#8217;ll see a very simple web page which looks like the following (which is generated by the <strong>Callback URL<\/strong>):<br><img loading=\"lazy\" decoding=\"async\" width=\"640\" height=\"62\" class=\"wp-image-3542\" style=\"width: 640px;\" src=\"https:\/\/www.marshflattsfarm.org.uk\/wordpress\/wp-content\/uploads\/2016\/11\/AuthorizationCode.png\" alt=\"\" srcset=\"https:\/\/www.marshflattsfarm.org.uk\/wordpress\/wp-content\/uploads\/2016\/11\/AuthorizationCode.png 1076w, https:\/\/www.marshflattsfarm.org.uk\/wordpress\/wp-content\/uploads\/2016\/11\/AuthorizationCode-300x29.png 300w, https:\/\/www.marshflattsfarm.org.uk\/wordpress\/wp-content\/uploads\/2016\/11\/AuthorizationCode-768x75.png 768w, https:\/\/www.marshflattsfarm.org.uk\/wordpress\/wp-content\/uploads\/2016\/11\/AuthorizationCode-1024x100.png 1024w, https:\/\/www.marshflattsfarm.org.uk\/wordpress\/wp-content\/uploads\/2016\/11\/AuthorizationCode-500x49.png 500w\" sizes=\"auto, (max-width: 640px) 100vw, 640px\" \/><\/li><li>That value for <strong>Parameter &#8216;code&#8217;<\/strong> (pixelized in the screenshot) is your <strong>Authorization Code<\/strong> which you&#8217;ll need to copy-and-paste into the terminal window where the Python script will still be waiting &#8211; before it expires<\/li><li>The script should confirm where it has written the Token obtained using the <strong>Code<\/strong> &#8211; if you see an error message instead the code might have expired, so try the procedure again but paste the code as soon as you see it in the browser<\/li><li>Note that anyone who can read the file containing the Token will be able to access NIBE Uplink; if it&#8217;s on a shared computer you might want to change the permissions to ensure nobody else can read it<\/li><\/ol>\n\n\n\n<h2 class=\"wp-block-heading\">Step 3 &#8211; Call the NIBE Uplink API<\/h2>\n\n\n\n<p>Now we have an Access Token we can <em>actually<\/em> call the API &#8211; and now things are less time-critical because the Token will be automatically renewed as required.<\/p>\n\n\n\n<ol class=\"wp-block-list\"><li>Download the second sample Python script from the GitHub repository &#8211; this one is called: <code>simple_call_to_protected_api.py<\/code><\/li><li>Edit this sample script to set <code>client_id<\/code> and <code>client_secret<\/code> as before<\/li><li>Run the script with: <code>python3 simple_call_to_protected_api.py<\/code><\/li><li> If it works as expected it will list out the systemId number(s) and model name(s) of the heat pump(s) assigned to your NIBE Uplink account<\/li><\/ol>\n\n\n\n<p>If that worked OK then you can also try the third sample Python script in the GitHub repository, called: <code>get_parameters_for_categories_for_systems.py<\/code><\/p>\n\n\n\n<p>You will have to edi<span style=\"font-size: revert;\">t <\/span><code style=\"background-color: rgb(255, 255, 255);\">client_id<\/code><span style=\"font-size: revert;\"> and <\/span><code style=\"background-color: rgb(255, 255, 255);\">client_secret<\/code><span style=\"font-size: revert;\"> as before<\/span> (the first part of this script is identical to the previous script). This third script:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Retrieves the list of Systems defined for the authorized User<\/li><li>For each of those Systems, retrieves a list of defined parameter &#8216;Categories&#8217;<\/li><li>For each of those Categories, retrieves a list of defined Parameters, together with their Names, Units and current Values<\/li><\/ul>\n\n\n\n<p>These details are simply printed out but the script could be adapted to publish them as MQTT messages or re-formatted as XML or JSON or similar and sent to a Home Automation system.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">JSON Response Formats<\/h1>\n\n\n\n<p>Some people have asked for examples of the JSON strings that are returned in response to the NIBE Uplink API calls. I&#8217;ve replaced strings like the serial number of my heat pump and my postal address details with XXXXXX&#8217;s but otherwise the responses are exactly as returned.<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>In response to API call <a href=\"https:\/\/api.nibeuplink.com\/api\/v1\/systems\">https:\/\/api.nibeuplink.com\/api\/v1\/systems<\/a><\/li><\/ul>\n\n\n\n<pre class=\"wp-block-preformatted\">{\"page\":1,\"itemsPerPage\":30,\"numItems\":1,\"objects\":[{\"systemId\":XXXXX,\"name\":\"F1145-8, 1x230\",\"productName\":\"NIBE F1145\",\"productImage\":{\"name\":\"NIBE_F1145\",\"sizes\":[{\"width\":75,\"height\":100,\"url\":\"\/Content\/Products\/F1145_75x100.png\"}]},\"securityLevel\":\"ADMIN\",\"serialNumber\":\"XXXXXXXXXXXXXX\",\"lastActivityDate\":\"2017-04-17T14:12:41Z\",\"connectionStatus\":\"ONLINE\",\"address\":{\"addressLine1\":\"XXXXXXXXXXXXXXXXX\",\"addressLine2\":\"XXXXXXXXXX\",\"postalCode\":\"XXXXXXXX\",\"city\":\"XXXXX\",\"region\":\"XXXXXXXXXX\",\"country\":\"UNITED_KINGDOM\"},\"hasAlarmed\":false}]}<\/pre>\n\n\n\n<ul class=\"wp-block-list\"><li>In response to API call <a href=\"https:\/\/api.nibeuplink.com\/api\/v1\/systems\/$system\/serviceinfo\/categories\">https:\/\/api.nibeuplink.com\/api\/v1\/systems\/$system\/serviceinfo\/categories<\/a> (with $system replaced with the value returned for systemId previously)<\/li><\/ul>\n\n\n\n<pre class=\"wp-block-preformatted\">[{\"categoryId\":\"STATUS\",\"name\":\"status\",\"parameters\":null},{\"categoryId\":\"CPR_INFO_EP15\",\"name\":\"compressor module \",\"parameters\":null},{\"categoryId\":\"SYSTEM_1\",\"name\":\"climate system 1\",\"parameters\":null},{\"categoryId\":\"ADDITION\",\"name\":\"addition\",\"parameters\":null},{\"categoryId\":\"AUX_IN_OUT\",\"name\":\"soft in\/outputs\",\"parameters\":null},{\"categoryId\":\"SYSTEM_INFO\",\"name\":\"info\",\"parameters\":null}]<\/pre>\n\n\n\n<ul class=\"wp-block-list\"><li>In response to API call <a href=\"https:\/\/api.nibeuplink.com\/api\/v1\/systems\/$system\/serviceinfo\/categories\/status?categoryId=STATUS\">https:\/\/api.nibeuplink.com\/api\/v1\/systems\/$system\/serviceinfo\/categories\/status?categoryId=STATUS<\/a> (with $system replaced with the value returned for systemId previously)<\/li><\/ul>\n\n\n\n<pre class=\"wp-block-preformatted\">[{\"parameterId\":40004,\"name\":\"40004\",\"title\":\"outdoor temp.\",\"designation\":\"BT1\",\"unit\":\"\u00b0C\",\"displayValue\":\"9.8\u00b0C\",\"rawValue\":98},{\"parameterId\":40067,\"name\":\"40067\",\"title\":\"avg. outdoor temp\",\"designation\":\"BT1\",\"unit\":\"\u00b0C\",\"displayValue\":\"8.3\u00b0C\",\"rawValue\":83},{\"parameterId\":40013,\"name\":\"40013\",\"title\":\"hot water top\",\"designation\":\"BT7\",\"unit\":\"\u00b0C\",\"displayValue\":\"41.4\u00b0C\",\"rawValue\":414},{\"parameterId\":40014,\"name\":\"40014\",\"title\":\"hot water charging\",\"designation\":\"BT6\",\"unit\":\"\u00b0C\",\"displayValue\":\"37.9\u00b0C\",\"rawValue\":379},{\"parameterId\":43005,\"name\":\"43005\",\"title\":\"degree minutes\",\"designation\":\"\",\"unit\":\"DM\",\"displayValue\":\"-57DM\",\"rawValue\":-578}]<\/pre>\n\n\n\n<h1 class=\"wp-block-heading\">Next Steps<\/h1>\n\n\n\n<p>If this procedure works for you, great! Please leave a Comment to let me know. If it doesn&#8217;t work or doesn&#8217;t makes sense please also leave a Comment and I&#8217;ll try to help.<\/p>\n\n\n\n<p>Clearly just printing out the systemIds isn&#8217;t very interesting but the <a rel=\"noreferrer noopener\" href=\"https:\/\/api.nibeuplink.com\/docs\/v1\" target=\"_blank\">NIBE Uplink API Documentation<\/a> describes the other API calls in some detail.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Further Reading<\/h1>\n\n\n\n<p>I found the following resources useful for understanding how to get OAuth2 working:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><a href=\"https:\/\/oauth.net\/2\/\" target=\"_blank\" rel=\"noreferrer noopener\">The main OAuth2 website<\/a><\/li><li><a href=\"https:\/\/aaronparecki.com\/2012\/07\/29\/2\/oauth2-simplified\" target=\"_blank\" rel=\"noreferrer noopener\">Aaron Parecki&#8217;s OAuth2 Simplified web page<\/a><\/li><li><a href=\"http:\/\/20missionglass.tumblr.com\/post\/60787835108\/programming-an-oauth2-client-app-in-php\">Programming an OAuth2 Client App in PHP<\/a><\/li><\/ul>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Introduction Back in 2016 I wrote this earlier page on querying the NIBE Uplink API using Perl scripts running on a particular flavour of Linux system. Based on the comments and questions received, this clearly proved useful for a number &hellip; <a href=\"https:\/\/www.marshflattsfarm.org.uk\/wordpress\/?page_id=4988\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"parent":5866,"menu_order":10,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-4988","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/www.marshflattsfarm.org.uk\/wordpress\/index.php?rest_route=\/wp\/v2\/pages\/4988","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.marshflattsfarm.org.uk\/wordpress\/index.php?rest_route=\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.marshflattsfarm.org.uk\/wordpress\/index.php?rest_route=\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.marshflattsfarm.org.uk\/wordpress\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.marshflattsfarm.org.uk\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=4988"}],"version-history":[{"count":14,"href":"https:\/\/www.marshflattsfarm.org.uk\/wordpress\/index.php?rest_route=\/wp\/v2\/pages\/4988\/revisions"}],"predecessor-version":[{"id":5059,"href":"https:\/\/www.marshflattsfarm.org.uk\/wordpress\/index.php?rest_route=\/wp\/v2\/pages\/4988\/revisions\/5059"}],"up":[{"embeddable":true,"href":"https:\/\/www.marshflattsfarm.org.uk\/wordpress\/index.php?rest_route=\/wp\/v2\/pages\/5866"}],"wp:attachment":[{"href":"https:\/\/www.marshflattsfarm.org.uk\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=4988"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}