NIBE Heat Pump Monitoring using Python instead of Perl

One of the most popular topics on this Blog is using the NIBE Uplink API to retrieve operational data reported by the Internet-connected NIBE heat pumps. That API is protected by OAuth2 authentication, which is a robust solution but which is rather more complicated than other APIs which simply expect an API Key or a non-expiring Token for authentication purposes.

There’s a Technical Articles page dating from 2016 which explains how to use the Perl scripting language on Linux to call the NIBE Uplink API, navigating the multiple steps of the OAuth2 handshake – see NIBE Heat Pump Monitoring via NIBE Uplink API (Perl Version). I originally chose Perl because that’s the language I was familiar with – and there was a Perl Module which handled many of the OAuth2 complexities.

Recently I’ve been learning Python for work and that’s proven to be a bit more friendly for this sort of thing. It’s also a language that more people are familiar with – and it’s rather more commonly used on different platforms, notably Microsoft Windows.

I’ve therefore adapted the original Technical Article to use Python rather than Perl and published that as NIBE Heat Pump Monitoring via NIBE Uplink API (Python Version). The Perl version is still relevant so will remain available too (especially since it has some valuable comments and responses) but my advice is for new users to follow the Python version instead.

I’ve also included some more general updates (such as the new NIBE S-Series heat pumps using an alternative API connected to myUplink.com) and some new screenshots. The script code is also now in a GitHub Repository rather than being embedded in the Blog page – and I intend to add some more comprehensive script examples once I migrate my other scripts from Perl to Python.

CC BY-SA 4.0 NIBE Heat Pump Monitoring using Python instead of Perl by Marsh Flatts Farm Self Build Diary is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.

25 thoughts on “NIBE Heat Pump Monitoring using Python instead of Perl

  1. Hello,
    I also have a NIBE heat pump, many months ago I tried the old article of you to get the API working. But this was on linux, and to difficult for me.
    so now I saw you made a new one for windows and tried this:
    And i’m following your instructions for API:
    https://www.marshflattsfarm.org.uk/wordpress/?page_id=4988
    But I have troubles with this:
    “2. The second requirement is the Requests-OAuthlib library
    On Windows, use a Command Prompt to run: pip3 install requests-oauthlib”
    If i open CMD en type “pip3 ……” I get a fault message:
    ‘pip3’ is not recognized as an internal or external command, operable program or batch file.
    I also tried this sollution that i found on google, but still fault message:
    https://blog.finxter.com/how-to-install-requests-oauthlib-in-python/

    Is it possible to give me more info?
    thank you very much.

    Gr Sven from Belgium.

    • Hi Sven,

      That error message (‘pip3’ is not recognized…) means that no Python installation is being found in the Command Prompt window – or the Python version is too old to have the ‘pip3’ command included.

      The first step is to ensure you have Python 3.4 or newer installed. Get it from https://www.python.org/downloads/windows/ – most people will want the “Windows installer (64-bit)” option.

      With the Python environment installed, when you open a Command Prompt and run “python3 –version” you should get confirmation of the Python version. Running “pip3 –version” should also return version details.

      If Python is installed but those commands are not working, there is probably an issue with the PATH setting that is preventing Windows from locating the Python programs.

      Until those ‘–version’ commands are working, the problem is with the installation of the Python environment, not the addition of requests-oauthlib.

      There is more detail about pip3 here: https://www.activestate.com/resources/quick-reads/how-to-install-and-use-pip3/

      David

  2. David,

    Eureka!!!
    Together with your explaination. I got my system ID and System name as respond on the “py simple_call_to_protected_api.py” in CMD.
    This site was very helpfull for me, like you suggested:https://www.activestate.com/resources/quick-reads/how-to-install-and-use-pip3/

    The next step for me is to get the info from Nibe.uplink to my domotica server.
    I have KNX installation, controlled by Jigsaw (https://www.comfortclick.com/Products/Servers/Jigsaw)
    I found here the information:
    https://www.comfortclick.com/BOS/KnowledgeBase/Http
    But I don’t understand quit good what to do. 🙁

    David, perhaps you have a idea? or do you know someone who connected his Nibe heatpump to a server from comfortlick.
    I don’t find anything in google 🙁

    Thank you!!!!

    • Hi Sven,

      That’s excellent news. It’s great that your persistence paid off.

      I’m not familiar with the ComfortClick systems but from a quick look at the links you posted their bOS seems similar to openHAB or HomeAssistant.

      I don’t think the bOS HTTP driver will be able to call NIBE Uplink since there doesn’t seem to be an option to do OAuth authentication (only ‘Basic’ Authentication).

      Most home automation systems provide some way to call a script on a regular cycle (e.g. every 5 minutes) and interpret the output. Is there some way to do that with the ComfortClick bOS? I see there is a Basic / Command option but I’m not sure what that does.

      If you can get bOS to call a Python script which prints out a number (that might be a Temperature from the heat pump) then you “simply” have to adapt the simple_call_to_protected_api.py script to grab the real readings and print those, perhaps using JSON format.

      If there’s no option to call a script from bOS then you might be able to use the RCP driver to talk to a Python HTTP server which then talks to NIBE Uplink – but that would be more complicated.

      David

      • David,
        For me your last 3 alineas are not clear 🙁
        But perhaps I’m running to fast.

        Maybe I first should get the API working on my windows desktop and next step is bOS.
        So I’m at the point to get a system ID and name in CMD!
        After that i’m lost.
        – I searched some info on youtube about JSON/API….
        – I checked the “functions” tab on nibe.uplink.api….
        – and your examples below the title:
        “JSON Response Formats”
        But i can’t make a connection?
        If I open this link in a browser: https://api.nibeuplink.com/api/v1/systems –> i get: {“message”:””}
        If I a open this link in a browser:
        https://api.nibeuplink.com/api/v1/systems/$system/serviceinfo/categories (and fill in my ID on the place of $system)
        –> i get {“message”:””}
        If i press both times on F12 then is see “failed to load resource: the server responded with a status of 400 (Bad request)

        Can you light me up? 🙂
        thanks again.
        PS: amasing that you cleared it op by yourself.
        I don’t get any help from Nibe for the API, even not in sweden. Quit strange for me.

  3. David,

    After some evenings this week on Youtube I succeeded to get some extra info about my heat pump!
    Perhaps this is helpfull for someone else, beceause i knew nothing of JSON or API ;-( :
    This youtube video was very usefull:
    https://www.youtube.com/watch?v=qbLc5a9jdXo
    I downloaded “Postman”
    after the GET command i filled in: https://api.nibeuplink.com/api/v1/systems/……
    below that there is a tab called: “authorization”:
    – type: OAuth 2.0
    there i placed for:
    – Name: Nibe
    – Grant Type: Authorization Code
    – Callback URL: https://www.marshflattsfarm.org.uk/nibeuplink/oauth2callback/index.php
    – Auth URL: https://api.nibeuplink.com/oauth/authorize
    – Access Token URL: https://api.nibeuplink.com/oauth/token
    – Client ID: “my private client ID”
    – Client Secret: “my private client secret”
    – Scope: READSYSTEM
    – State: STATESTRING
    – Client Authentication: send client credentials in body
    after pressing GET NEW ACCES TOKEN i need to fill in my email adres and password in a web browser. after clicking on some buses and fire hydrants i get a message from postman: Authentication complete
    –> press “use token”
    –> press “send”
    And at the bottem i get respond!!!
    now i need to investigate some more the “functions” and automatic refresh of the token.
    Gr Sven.

  4. Hello,
    David, to complete my API story:
    I got contact with the third party API specialist of Comfortclick in Slovenia.
    He was able to extract 1 Array, and 1 signal.
    then i did the rest of the signals with copy paste. 🙂
    Also thanks for your “expanded version” you placed on GitHub, this was helpful!

    If somebody needs the info to connect the api to Comfortclick.
    Follow the excellent steps of David on this blog.
    Then do this in comfortclick:
    add a HTTP driver in bOS:
    With this url: https://api.nibeuplink.com/
    make a POST command to “oauth/token”
    With the following:
    – Content Type: “application/x-www-form-urlencoded;charset=UTF-8″
    – Post Data: grant_type=refresh_token&client_id=”YOUR PERSONAL CLIENT ID”&client_secret=”YOUR PEROSNAL CLIENT SECRET”&refresh_token=”YOUR PERSONAL CLIENT”
    And send it cyclical for example 1700 sec.
    The tricky part of this is, that my secret was coded,
    so perhaps you need to encode it:
    https://www.urlencoder.org/
    As response you get your “acces token”

    Then insert a new HTTP driver with this URL:
    https://api.nibeuplink.com/api/v1/systems/
    and a new command:
    With for example this request:
    “YOUR SYSTEM ID”/serviceinfo/categories/STATUS
    Header: Authorization: Bearer “YOUR PERSONAL ACCES TOKEN”
    Method type: GET
    as response data you get the array in JSON of that request.
    if you copy/past the response data to https://jsoneditoronline.org/
    then you can see where the data is and parse it out.

    with this done, i made a visualisation page were a placed all imported values for me, and also made some loggings.
    With this I hope to optimize the heatpump even more.

    Gr. Sven.

  5. Hi,
    thanks so much for excellent guidance, I was trying perl version in past, but the python3 is much more “user” friendly.
    My goal is to read current amperage from my F2120 unit so I’m trying modification in your code to get this details. My system is having a master (smo20) and slave1 (f2120):
    [{‘systemUnitId’: 0, ‘name’: ‘SMO 20’, ‘shortName’: ‘m’, ‘product’: ‘SMO 20’, ‘softwareVersion’: ‘9303R8’}, {‘systemUnitId’: 1, ‘name’: ‘slave 1’, ‘shortName’: ‘s1’, ‘product’: ‘F2120’, ‘softwareVersion’: ‘10677’}]
    When getting details for slave 1 using …/v1/systems/XXXXX/status/systemUnit/1/units the output is not “complete” – some important parameters are missing:
    This is the output:
    {‘image’: {‘name’: ‘Supply’, ‘sizes’: [{‘width’: 35, ‘height’: 35, ‘url’: ‘/Content/Icons/Emmy/Supply_Tiny.png’}, {‘width’: 50, ‘height’: 50, ‘url’: ‘/Content/Icons/Emmy/Supply_Small.png’}, {‘width’: 100, ‘height’: 100, ‘url’: ‘/Content/Icons/Emmy/Supply_Medium.png’}, {‘width’: 150, ‘height’: 150, ‘url’: ‘/Content/Icons/Emmy/Supply_Large.png’}, {‘width’: 256, ‘height’: 256, ‘url’: ‘/Content/Icons/Emmy/Supply_256x256.png’}]}, ‘inlineText’: ‘GP12’, ‘title’: ‘Charge Pump’, ‘parameters’: [{‘parameterId’: 44058, ‘name’: ‘44058’, ‘title’: ‘supply temp.’, ‘designation’: ‘EB101-BT12’, ‘unit’: ‘°C’, ‘displayValue’: ‘36.3°C’, ‘rawValue’: 363}, {‘parameterId’: 44055, ‘name’: ‘44055’, ‘title’: ‘return temp.’, ‘designation’: ‘EB101-BT3’, ‘unit’: ‘°C’, ‘displayValue’: ‘36.5°C’, ‘rawValue’: 365}, {‘parameterId’: 44396, ‘name’: ‘44396’, ‘title’: ‘charge pump speed’, ‘designation’: ‘EB101’, ‘unit’: ‘%’, ‘displayValue’: ‘30%’, ‘rawValue’: 30}]}
    Of corse, these parameters are from slave1 but I’m missing current EB101, defrosting flag, current compr. frequency EB101, fan speed EB101 and some other.
    Any idea how to get more details?
    Many thanks for your excellent job,
    regards
    jan

    • Hi Jan,

      Thanks for the feedback – I agree that for most people the Python script version is much easier to use than the Perl version.

      I found that a lot of the detailed parameters are only included in the ‘serviceinfo’ API call (that one returns more comprehensive info than ‘status’).

      Do you see the information you need when connecting to https://www.nibeuplink.com/ with a web browser and is it listed under “Service Info”?

      Do you get the parameter you’re after when using:
      https://github.com/MarshFlattsFarm/NIBE-Uplink-API/blob/main/get_parameters_for_categories_for_systems.py

      David

      • Hi David,
        I can see requested informations under Service Info in http://www.nibeuplink.com. All I need to do is click Overview, Service Info, Slave 1 and the web page shows me all I want.
        Get_parameters_for_categories…py is not showing these details 🙁
        I’m trying to compose right url to get service info details – any idea how it should look?
        nibeuplink.get(‘https://api.nibeuplink.com/api/v1/systems/’ + str(system_id) + ‘/serviceinfo/systemUnit/1/’) is returning errors

        • Hi Jan,

          From the docs, it looks like the Unit ID needs to be passed as an HTTP Parameter, not as part of the Base URL.

          I’ve amended https://github.com/MarshFlattsFarm/NIBE-Uplink-API/blob/main/get_parameters_for_categories_for_systems.py so that it now reports on every Unit connected to every System. I only have one Unit so difficult to test but it works OK for that simple case (no errors) so please try the modified script for your installation.

          Even if it doesn’t work quite right, see the code I’ve added for ‘params’, which I think is how the systemUnitId needs to be specified.

          David

          • Hi David,
            amended script is working perfectly – it is showing all details I need!!! Finally I can read category Id: CPR_INFO_EP14 and current amperage:
            Parameter Id: 44866
            Parameter Name: 44866
            Parameter Title: current
            Parameter Designation: EB101
            Parameter Unit:
            Parameter Display Value: 1.0
            Parameter Raw Value: 10

            Thanks so much for excellent support and for your good scripting work!
            With respect,
            Jan

          • Hi Jan,

            Thanks for the feedback and I’m pleased to hear you’re now getting the data you need. Including ‘slave’ units is a worthwhile enhancement to the sample script which doesn’t break it for single-unit installations and provides a good example of how to send HTTP Parameters to other API calls.

            NIBE did a good job with their API, although their docs seem to be aimed at IT Professionals and can be a little difficult to follow. I am grateful to you and others who ask questions here and provide feedback on how you solve problems.

            David

  6. Hi, I am using a NIBE S155-06PC heat pump and wanted to use your guide to implement the data of my heat pump on my raspberry pi4. There are small differences between myuplink and NIBEuplink. For NIBEuplink you receive an authorization code with a length of 99 digits with myuplink the authorization code has only 64 digits. To not get an error I put a hashtag in front of the following section:

    # Check we did actually get a plausibly long code entered
    # if len(authorization_code) < 99:
    # raise SystemExit('Invalid Authorization Code entered; exiting')

    Once I enter the authorization code the source code continues with the reception of the token. But at this point I get the message – Invalid token received; exiting

    Do you have any clue why this happens? I got a client id, client_secret from myuplink. token_url, authorize_url are changed to myuplink

    Thank you in advance

  7. Hi, thank you for the post.

    Do you know if the code in the GitHub repository is still compatible with the API ? I have tried the code but I am unable to request the token. The Nibe API always responds invalid_request. I am fairly experienced with API coding but I seem to have tried everything.

    • Hi Olavur,

      I believe the code is still compatible with the NIBE API, yes.

      Other people have used it quite recently, with good success.

      I am running the API code myself (but I allocated my token some time ago).

      David

  8. I’ve just come across your article and found it inspiring!
    I have a house full of Rpis controlling all sorts of things like my water filtration system to high level hi-fi.
    I’ve just replaced my old Danfoss GSHP with a Nibe S1255 and been impressed by its performance but unimpressed by myuplink.
    Your article should fix the limitations of myuplink. I’d like to get to the point where I can generate realtime CoP data.

    • Thanks for the feedback.
      I’ve recently learned that the ‘S’ series of NIBE Heat Pumps offer the option of a local Modbus-over-TCP protocol interaction. This means it’s not necessary to let the data go ‘to the cloud’ then grab it back via the API; the operational parameters can be read (and modified?) locally, via the LAN connection.
      I wonder if that approach might suit you better than using the myuplink API? You’ll find info from people who have integrated with HomeAssistant and other similar tools – you should be able to use the same approach to integrate your own code.
      David

Leave a Reply to Marc Cancel reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.