HowTo: Node Red – Control the FritzBox radiator thermostat from Node Red

I recently ordered one of the DECT radiator thermostats for the FritzBox out of curiosity.

As usual with Fritz products, installation and commissioning was super easy. It takes less than ten minutes to install and set up.

All kinds of options can then be set in the app and the FritzBox interface. These include fixed times at which the radiator should be switched on. Unfortunately, this option is not so practical for me. What I have always done very well in the past, however, is to switch on the heating when it is cold outside (for example, cooler than 15°C) and the TV in the living room is switched on (as a kind of presence detection).

I wanted to have this "dynamic" switching behavior again. In the past, I did this with a few nodes in NodeRed. Thank goodness there is also a suitable node for controlling the Fritz heating thermostats. You just have to configure it accordingly.

You can find an example flow for controlling a Fritz DECT radiator thermostat in this article.

Safety instructions

I know the following notes are always kind of annoying and seem unnecessary. Unfortunately, many people who knew "better" have lost eyes, fingers or other things due to carelessness or injured themselves. Data loss is almost negligible in comparison, but even these can be really annoying. Therefore, please take five minutes to read the safety instructions. Because even the coolest project is not worth injury or other trouble.

Affiliate links/advertising links

The links to online shops listed here are so-called affiliate links. If you click on such an affiliate link and make a purchase via this link, will receive a commission from the relevant online shop or provider. The price does not change for you. If you make your purchases via these links, you support in being able to offer other useful projects in the future. 🙂 


Helpful articles:
So that you can install new nodes, NodeRed should of course already be installed.
How to prepare a RaspberryPi and then install NodeRed on it is described in the following articles.

The following three articles describe what needs to be done to prepare the RaspberryPi:
RaspberryPi – setup for nerdiys!
RaspberryPi – The first configuration!
RaspberryPi – Control the RaspberryPi via SSH

NodeRed – Installing NodeRed on the RaspberryPi
NodeRed - import and export node code

Required tool:

Required material:

In the following list you will find all the parts you need to implement this article.

Log into the NodeRed configuration interface

Before you can edit your NodeRed configuration, you must - if activated - first log into the NodeRed configuration interface.

View of the login dialog. Here you have to enter the login data that you specified during the configuration of the login. You can find information about this in the article NodeRed - set up user login.

Install the appropriate FritzBox node

In order for NodeRed to communicate with the connected radiator thermostats, you must install the node "node-red-contrib-fritzapi". How to install nodes is described in the article NodeRed – Install new nodes described.

NodeCode for controlling a Fritz DECT radiator thermostat

The current status of the NodeCode is my first draft of a control system. I will certainly continue to work on it. So please ask for updates if this post has not been updated for a long time.

In the current version, you can display the temperature measured at the radiator and the setpoint or target temperature. Of course, you can also set the desired temperature.

Last but not least, the charge status of the batteries is also displayed in the radiator thermostat. I assume that this is displayed as a percentage. However, as the charge level is currently at 100 and is falling very slowly, I still need to observe how this value develops as it falls.

What I have already installed but have not yet been able to trigger is the boost function. This function can be triggered on the thermostat itself by pressing the menu button for two seconds. This heats up the radiator fully for a short period of time. Of course, it would be practical if this could also be triggered from NodeRed to heat up a room quickly and automatically.

Below are a few views of the configuration and the actual NodeCode.

View of the flow in the NodeRed configuration view.

View of the controls in the dashboard view.

How you can import the NodeCode below is described in the article NodeRed - import and export node code described.

As always, you can find the NodeCode in the Nerdiy Git repository under the following link:

Have fun with the project

I hope everything worked as described for you. If not or you have questions or suggestions please let me know in the comments. I will then add this to the article if necessary.
Ideas for new projects are always welcome. 🙂

PS Many of these projects - especially the hardware projects - cost a lot of time and money. Of course I do this because I enjoy it, but if you think it's cool that I share the information with you, I would be happy about a small donation to the coffee fund. 🙂

Buy Me a Coffee at       


  1. Hi, you can address the boost function like this.

    [{“id”:”1faf9813.1db958″,”type”:”fritzbox-in”,”z”:”c47fd6d2.77c058″,”device”:”fae20a49.af3108″, "name":"", "service": "urn:dslforum-org:service:DeviceConfig:1″, "action": "X_AVM-DE_CreateUrlSID", "arguments":"{}", "x":490, "y":2440, "wires":[["b31af515.e51bd8"]]},{"id": "f8af624a.17eda", "type": "inject", "z": "c47fd6d2.77c058″, "name": "boost", "props":[{"p": "payload"},{"p": "topic", "vt": "str"}], "repeat":"", "crontab":"", "once":false, "onceDelay": "3″, "topic": "boost", "payload":"", "payloadType": "date", "x":130, "y":2480, "wires":[["64d9a853.09dca8”]]},{“id”:”864f66c3.198ed8″,”type”:”debug”,”z”:”c47fd6d2.77c058″, "name":"", "active":true, "tosidebar":true, "console":false, "tostatus":false, "complete": "false", "statusVal":"", "statusType": "auto", "x":1250, "y":2660, "wires":[]},{"id": "e82c0e1.b773af", "type": "template", "z": "c47fd6d2.77c058″, "name": "gettemp", "field": "payload", "fieldType": "msg", "format": "handlebars", "syntax": "mustache", "template":"/webservices/homeautoswitch.lua?ain={{ain}}&switchcmd=gettemperature&sid={{payload.NewX_AVM-DE_UrlSID}}", "output": "str", "x":800, "y":2580, "wires":[["4abfff85.997b8"]]},{"id": "4abfff85.997b8″, "type": "http request", "z": "c47fd6d2.77c058″, "name":"", "method": "GET", "ret": "txt", "paytoqs": "ignore", "url": "{{payload}}}", "tls": "402169f3.8da818″,”persist”:false,”proxy”:””,”authType”:””,”x”:1050,”y”:2660,”wires”:[[“864f66c3.198ed8”]]},{“id”:”75765e63.210fb", "type": "change", "z": "c47fd6d2.77c058″, "name": "set ain", "rules":[{"t": "set", "p": "ain", "pt": "msg", "to": "099950642052″, "tot": "str"}], "action":"", "property":"", "from":"", "to":"", "reg":false, "x":850, "y":2440, "wires":[["4ca0ace7.858544"]]},{"id": "4ca0ace7.858544″, "type": "function", "z": "c47fd6d2.77c058″, "name": "now() + 5min", "func":"//node.warn(;\nmsg.endtime = rounding( / 1000 + 60 * 5, 0)\nreturn msg;\n\nfunction rounding(num, decimalPlaces = 0) {\n num = Math.round(num + \"e\" + decimalPlaces);\n return Number(num + \"e\" + -decimalPlaces);\n}", "outputs":1, "noerr":0, "initialize":"", "finalize":"", "x":450, "y":2680, "wires":[["2e6db71e.28fe78"]]},{"id": "b31af515.e51bd8″, "type": "change", "z": "c47fd6d2.77c058″, "name": "clean SID", "rules":[{"t": "change", "p": "payload.NewX_AVM-DE_UrlSID", "pt": "msg", "from": "sid=", "fromt": "str", "to":"", "tot": "str"}], "action":"", "property":"", "from":"", "to":"", "reg":false, "x":700, "y":2440, "wires":[["75765e63.210fb"]]},{"id": "34097198.32a5ae", "type": "template", "z": "c47fd6d2.77c058″, "name": "Boost an", "field": "payload", "fieldType": "msg", "format": "handlebars", "syntax": "mustache", "template":"/webservices/homeautoswitch.lua?ain={{ain}}&switchcmd=sethkrboost&sid={{payload.NewX_AVM-DE_UrlSID}}&endtimestamp={{endtime}}", "output": "str", "x":800, "y":2620, "wires":[["4abfff85.997b8”]]},{“id”:”a0bfa44f.b806e8″,”type”:”template”,”z”:”c47fd6d2.77c058″, "name": "Boost off", "field": "payload", "fieldType": "msg", "format": "handlebars", "syntax": "mustache", "template":"/webservices/homeautoswitch.lua?ain={{ain}}&switchcmd=sethkrboost&sid={{payload.NewX_AVM-DE_UrlSID}}&endtimestamp=0″, "output": "str", "x":800, "y":2660, "wires":[["4abfff85.997b8"]]},{"id": "2e6db71e.28fe78″, "type": "switch", "z": "c47fd6d2.77c058″, "name":"", "property": "topic", "propertyType": "msg", "rules":[{"t": "eq", "v": "temp", "vt": "str"},{"t": "eq", "v": "boost", "vt": "str"},{"t": "eq", "v": "noboost", "vt":"str"},{"t": "eq", "v": "window", "vt": "str"},{"t": "eq", "v": "nowindow", "vt": "str"}], "checkall": "true", "repair":false, "outputs":5, "x":610, "y":2680, "wires":[["e82c0e1.b773af”],[“34097198.32a5ae”],[“a0bfa44f.b806e8”],[“7d4888cf.55f988”],[“4c9b3c7b.984124”]]},{“id”:”27537213.66face”,”type”:”inject”,”z”:”c47fd6d2.77c058″, "name": "noboost", "props":[{"p": "payload"},{"p": "topic", "vt": "str"}], "repeat":"", "crontab":"", "once":false, "onceDelay": "3″, "topic": "noboost", "payload":"", "payloadType": "date", "x":140, "y":2520, "wires":[["e0f67d6.2def88”]]},{“id”:”56ba18bf.b2f828″, "type": "inject", "z": "c47fd6d2.77c058″, "name": "get temp", "props":[{"p": "payload"},{"p": "topic", "vt": "str"}], "repeat":"", "crontab":"", "once":false, "onceDelay": "3″, "topic": "temp", "payload":"", "payloadType": "date", "x":140, "y":2440, "wires":[["7e0e1632.c31dd8”]]},{“id”:”4c9b3c7b.984124″, "type": "template", "z": "c47fd6d2.77c058″, "name": "Window closed", "field": "payload", "fieldType": "msg", "format": "handlebars", "syntax": "mustache", "template":"/webservices/homeautoswitch.lua?ain={{ain}}&switchcmd=sethkrwindowopen&sid={{payload.NewX_AVM-DE_UrlSID}}&endtimestamp=0″, "output": "str", "x":810, "y":2740, "wires":[["4abfff85.997b8"]]},{"id": "7d4888cf.55f988″, "type": "template", "z": "c47fd6d2.77c058″, "name": "Window open", "field": "payload", "fieldType": "msg", "format": "handlebars", "syntax": "mustache", "template":"/webservices/homeautoswitch.lua?ain={{ain}}&switchcmd=sethkrwindowopen&sid={{payload.NewX_AVM-DE_UrlSID}}&endtimestamp={{endtime}}", "output": "str", "x":810, "y":2700, "wires":[["4abfff85.997b8"]]},{"id": "5560a2ca.10bc6c", "type": "inject", "z": "c47fd6d2.77c058″, "name": "window", "props":[{"p": "payload"},{"p": "topic", "vt": "str"}], "repeat":"", "crontab":"", "once":false, "onceDelay": "3″, "topic": "window", "payload":"", "payloadType": "date", "x":130, "y":2560, "wires":[["cda59701.f28878”]]},{“id”:”18250461.024fbc", "type": "inject", "z": "c47fd6d2.77c058″, "name": "window closed", "props":[{"p": "payload"},{"p": "topic", "vt": "str"}], "repeat":"", "crontab":"", "once":false, "onceDelay": "3″, "topic": "nowindow", "payload":"", "payloadType": "date", "x":140, "y":2600, "wires":[["804b42ac.172b3”]]},{“id”:”cda59701.f28878″,”type”:”ui_button”,”z”:”c47fd6d2.77c058″,”name”:””,”group”:”5a2c927c.ba1edc", "order":5, "width":0, "height":0, "passthru":true, "label": "window open", "tooltip":"", "color":"", "bgcolor":"", "icon":"", "payload":"", "payloadType": "date", "topic": "window", "topicType": "str", "x":320, "y":2560, "wires":[["1faf9813.1db958”]]},{“id”:”804b42ac.172b3″, "type": "ui_button", "z": "c47fd6d2.77c058″, "name":"", "group": "5a2c927c.ba1edc", "order":6, "width":0, "height":0, "passthru":true, "label": "window closed", "tooltip":"", "color":"", "bgcolor":"", "icon":"", "payload":"", "payloadType": "date", "topic": "nowindow", "topicType": "str", "x":320, "y":2600, "wires":[["1faf9813.1db958”]]},{“id”:”64d9a853.09dca8″,”type”:”ui_button”,”z”:”c47fd6d2.77c058″,”name”:””,”group”:”5a2c927c.ba1edc", "order":2, "width":0, "height":0, "passthru":true, "label": "boost 5m", "tooltip":"", "color":"", "bgcolor":"", "icon":"", "payload":"", "payloadType": "date", "topic": "boost", "topicType": "str", "x":300, "y":2480, "wires":[["1faf9813.1db958”]]},{“id”:”e0f67d6.2def88″,”type”:”ui_button”,”z”:”c47fd6d2.77c058″, "name":"", "group": "5a2c927c.ba1edc", "order":3, "width":0, "height":0, "passthru":true, "label": "boost off", "tooltip":"", "color":"", "bgcolor":"", "icon":"", "payload":"", "payloadType": "date", "topic": "noboost", "topicType": "str", "x":300, "y":2520, "wires":[["1faf9813.1db958”]]},{“id”:”7e0e1632.c31dd8″,”type”:”ui_button”,”z”:”c47fd6d2.77c058″,”name”:””,”group”:”5a2c927c.ba1edc", "order":2, "width":0, "height":0, "passthru":true, "label": "get temp", "tooltip":"", "color":"", "bgcolor":"", "icon":"", "payload":"", "payloadType": "date", "topic": "temp", "topicType": "str", "x":300, "y":2440, "wires":[["1faf9813.1db958"]]},{"id": "fae20a49.af3108″, "type": "fritzbox-config", "name": "fritz", "host": "", "port": "49443″, "ssl":true, "user": "user"},{"id": "402169f3.8da818″, "type": "tls-config", "name":"", "cert":"", "key":"", "ca":"", "certname":"", "keyname":"", "caname":"", "servername":"", "verifyservercert":false},{"id": "5a2c927c.ba1edc", "type": "ui_group", "name": "test", "tab": "42b914b0.66a0ac", "order":null, "disp":true, "width": "6″, "collapse":false},{"id": "42b914b0.66a0ac", "type": "ui_tab", "name": "Main", "icon": "dashboard", "order":1, "disabled":false, "hidden":false}]

  2. Hello, great example! I have already been able to implement a lot with my Fritz devices. But I can't get the Fritz Dect 500 lamp to work. I can read out the status, but neither switch nor change color. I have already searched everything but have not found any examples for the Fritz Dect 500. Do you have an example flow, e.g. how the "Simple on/off" node is used?

    Greetings, Mathias

    1. Hi Mathias,
      unfortunately I haven't tested the DECT500 yet. But I just ordered it and I'll take a look. Actually, that should also be possible. 🙂
      Best regards

  3. Hello Fab,
    Thank you for your great examples.
    I tried your example for the Fritz radiator valve with me. It works so far that I can see the actual and target temperatures on the dashboard. Only when I select a new target temperature in the dashboard does the display switch back very quickly to the original temperature set in the Fritzbox. Writing the setpoint temperature does not seem to work.
    Do you have a tip for me? Unfortunately I'm still a beginner with Nodered..
    Thanks and best regards

    1. Hi Joachim,
      hmm, to be honest, I can't explain it. I've just tried it on mine and it seems to work there.
      Can you roughly estimate after how long the setpoint value will be reset? Could that equate to about 5 seconds?
      Best regards

  4. Hello Fabian
    I am very enthusiastic about your projects and explanations.....
    Unfortunately, I'm an absolute beginner in this field and I'm looking for a way to elicit the humidity and the 4 button signals in Node Red from the Fritz Dect 440.

    Mfg Cord

    1. Hi cord,
      unfortunately I don't have the DECT 440 available, so I haven't been able to try to create the code for it yet. As soon as I get my hands on it, I'll post it here as well. 🙂
      Best regards

  5. Hi,

    I'm also having problems using the "Fritz nodes" and may be able to get a tip here. The help for the "thermostat" node, for example, is quite poor. For example, it does not go into what feels like 20 selection options in the action drop-down field. It is therefore completely unclear how, for example, window open detection is controlled. What does this node expect at the input? In this particular case of window detection, a "true"/"false", "TRUE"/"FALSE", "on"/"off", "ON"/"OFF" or even simply "1"/"0"? In the case of window detection, the documentation makes it sound as if you can even specify the timeout as a second parameter. If that is the case. How does that work?
    I would have even more questions about the temperature setting itself, but since this setting via FritzBox and DECT is obviously extremely sluggish, I tend to only automate the window detection for my existing Fritz thermostats (via external Zigbee window contact).
    I don't necessarily need a long novel here about how something works. A link to a current, working documentation would be helpful. I'm either too stupid to find it or it simply doesn't exist.

    Regards, Frank

  6. Ok, it gave me no peace.
    If you select the action 'Set "Window open" mode for the given number of minutes', you must enter a number for the thermostat timeout as the payload. For example, "5" for 5 minutes.
    May it help those who do not understand the description of the node right away and then find what they are looking for here. 🙂

    Regards, Frank

    1. Hey Frank,
      thanks for the hint. I know the feeling (that there is no rest). 😀
      And I also find the transfer of the settings using the FritzBox a bit sluggish. One of the reasons why I switched to Zigbee. But I can also well imagine going back to the FritzBox. I'm curious about their Matter implementation. 🙂
      Thanks again and best regards

  7. Hello,

    A quick question about "Window open": is the new temperature then transferred to the thermostat immediately or is there a time delay? So far, the values have only ever been transferred to the thermostat with a delay.

    Best regards

    the little one

    1. Hi Matthias,
      Unfortunately, I think there is a slight delay for technical reasons. As far as I know, the FritzBox can only send data over the DECT system for a certain amount of time per time slot. Depending on how much data traffic is currently taking place, the messages can then arrive with a slight delay.
      (But that's also a bit of dangerous half-knowledge. :/) I'd have to read in there again.
      These delays (and the prices for the Fritz actuators) were also one of the reasons why I switched to the Zigbee system for the other thermostats. 🙂
      Best regards

      1. Good morning Fabian,

        Which thermostats with Zigbee did you switch to?
        You then also control them via NodeRed?
        The prices I found for it are currently not affordable 🙁

        I would be very interested in that and would gradually convert it if the price was right!

        Best regards


        1. Hi Mathias,
          Yes, that's true, I noticed that recently too. I had already switched to these thermostats at the beginning of last year:
          At that time they cost about 20 euros per thermostat. Thanks to Zigbee2mqtt, the thermostats can then be configured and controlled via MQTT. The new values are then adopted directly. I really like the whole Zigbee system now because it just works. I also have no range problems, because permanently supplied Zigbee participants automatically act as repeaters.
          Best regards

  8. The control works so far. Temperatures are only accepted with a delay due to Fritz, but this was known and is also the case with control via the Fitzz interface.
    Unfortunately, the boost function runs with an error. Any idea why this could be?

    Output at Boost:
    {"error":null, "response":{"statusCode":500, "body":"", "headers":{"cache-control": "no-cache", "connection": "close", "content-length": "0″, "content-type": "text/plain; charset=utf-8″, "expires":"-1″, "pragma":"no-cache", "x-frame-options": "SAMEORIGIN", "x-xss-protection": "1; mode=block", "x-content-type-options": "nosniff", "content-security-policy": "default-src 'none'; connect-src 'self'; font-src 'self'; frame-src 'self'; img-src 'self' data:; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; frame-ancestors 'self'; media-src 'self'"}, "request":{"uri":{"protocol": "http:", "slashes":true, "auth":null, "host": "″,”port”:80,”hostname”:”″,”hash”:null,”search”:”?0=0&si…

  9. Hello,
    Does anyone here know why node-red-contrib-fritzapi cannot address the dect 302 thermostat?
    An error message always appears: unknown device: xxxxxxxxxxxxxxx
    {"Valid devices":{"Thermostat kitchen": "xxxxxxxxxxxxxxx"}}
    Greetings Friedrich

Kommentar hinterlassen

Your email address will not be published. Erforderliche Felder sind mit * markiert

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