# Dynamic Duty Cycle

**URL:** https://discourse.nodered.org/t/dynamic-duty-cycle/56232
**Category:** General
**Created:** [7 January 2022 00:28 UTC](https://discourse.nodered.org/t/dynamic-duty-cycle/56232 "2022-01-07T00:28:32Z")
**Posts on this page:** 9
**Page:** 1

<div class="post-metadata">

### Author: ![crbn60](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/crbn60/32/53688_2.png) [@crbn60](https://discourse.nodered.org/u/crbn60)
#### Post date: [7 January 2022 00:28 UTC](https://discourse.nodered.org/t/dynamic-duty-cycle/56232/1 "2022-01-07T00:28:33Z")

</div>

I have an existing thermostat that calculates and outputs a "Heating Demand" value which is a percentage. I would like to slave an auxiliary heater from this value, by having it match the heating demand with its duty cycle.

For example, if I have a value of 50%, then turn ON the controlled device 50% of the time, resulting in a 50% duty cycle. How exactly to achieve this, I'm not really sure.

I think equal periods will result in a smoother temperature maintenance.

I could round down to the nearest factor of 20, then use 12 minute periods.

Then, how would I actually implement the logic? Any good Nodes for that purpose?

Thanks,

A.

---

<div class="post-metadata">

### Author: ![craigcurtin](https://avatars.discourse-cdn.com/v4/letter/c/94ad74/32.png) [@craigcurtin](https://discourse.nodered.org/u/craigcurtin)
#### Post date: [7 January 2022 01:37 UTC](https://discourse.nodered.org/t/dynamic-duty-cycle/56232/2 "2022-01-07T01:37:15Z")

</div>

If you are talking duty cycle in minutes - then you could use Neil Cherry's MyTimeout node.

Basically you can programatically send it the number of seconds to run in timeout mode and once it gets to the end of its cycle it will output additional info on another output.

Craig

---

<div class="post-metadata">

### Author: ![crbn60](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/crbn60/32/53688_2.png) [@crbn60](https://discourse.nodered.org/u/crbn60)
#### Post date: [7 January 2022 02:53 UTC](https://discourse.nodered.org/t/dynamic-duty-cycle/56232/3 "2022-01-07T02:53:43Z")

</div>

> [@craigcurtin](#):
>
> If you are talking duty cycle in minutes - then you could use Neil Cherry's MyTimeout node.

Looked up the [MyTimeout](https://flows.nodered.org/node/node-red-contrib-mytimeout) node. So that would let me fire a timer for the "on" portion of the duty cycle, then I would need to loop back around, check the current duty cycle target, and fire it again. I'm slowly seeing the plan…

Thanks, any other suggestions?

How would you trigger the MyTimeout node?

---

<div class="post-metadata">

### Author: ![craigcurtin](https://avatars.discourse-cdn.com/v4/letter/c/94ad74/32.png) [@craigcurtin](https://discourse.nodered.org/u/craigcurtin)
#### Post date: [7 January 2022 03:02 UTC](https://discourse.nodered.org/t/dynamic-duty-cycle/56232/4 "2022-01-07T03:02:22Z")

</div>

How is the Value for the heating requirement getting into Node Red i..e how are you capturing the value that the thermostat is outputting ?

Once you have that value coming in as a number into NR then you could perform the magic in a number of ways depending on your abilities and how much programming you want to do.

The easiest way to start is to string together a series of change and switch nodes - which will look daunting to start with but requires no programming - later you can simplify it if you wish by putting in function nodes

Functionally you are going to look like

1. Capture incoming value from Thermostat
2. Put the output to a switch node - the switch node has (say) 10 switches/checks in it

If value = 100 then output 1  
If value \>90 then output 2  
if value \> 80 then output 3 etc etc

Each of these outputs goes to a change node where you take the value that is passed in and send that on to the mytimeout node in the format it needs

Give that a go to start with and come back and paste your basic flow then we can refine it further

Craig

---

<div class="post-metadata">

### Author: ![Colin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/colin/32/17040_2.png) [@Colin](https://discourse.nodered.org/u/Colin)
#### Post date: [7 January 2022 06:45 UTC](https://discourse.nodered.org/t/dynamic-duty-cycle/56232/5 "2022-01-07T06:45:11Z")

</div>

> [@crbn60](#):
>
> if I have a value of 50%, then turn ON the controlled device 50% of the time, resulting in a 50% duty cycle

Have a look at node-red-contrib-timeprop, it is intended for exactly this application. You might like to look at node-red-contrib-pid too.

---

<div class="post-metadata">

### Author: ![crbn60](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/crbn60/32/53688_2.png) [@crbn60](https://discourse.nodered.org/u/crbn60)
#### Post date: [7 January 2022 15:11 UTC](https://discourse.nodered.org/t/dynamic-duty-cycle/56232/6 "2022-01-07T15:11:06Z")

</div>

> [@Colin](#):
>
> Have a look at node-red-contrib-timeprop, it is intended for exactly this application. You might like to look at node-red-contrib-pid too.

timeprop is not working for me, unsure why. My understanding of pid is that it is for controlling a temperature directly, whereas I'm using an actual thermostat.

Here is my test sketch with timeprop:

```json
[
    {
        "id": "1dcd707332701bf2",
        "type": "debug",
        "z": "1b4dc69d8cd3f4af",
        "name": "output",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 1460,
        "y": 920,
        "wires": []
    },
    {
        "id": "99afa2ae7f661cbe",
        "type": "inject",
        "z": "1b4dc69d8cd3f4af",
        "name": "",
        "props": [
            {
                "p": "payload"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "0.5",
        "payloadType": "num",
        "x": 1110,
        "y": 960,
        "wires": [
            [
                "70ee8ef879c76a39"
            ]
        ]
    },
    {
        "id": "70ee8ef879c76a39",
        "type": "timeprop",
        "z": "1b4dc69d8cd3f4af",
        "name": "",
        "cycleTime": "600",
        "deadTime": 0,
        "triggerPeriod": "6",
        "invert": false,
        "x": 1320,
        "y": 940,
        "wires": [
            [
                "1dcd707332701bf2"
            ]
        ]
    },
    {
        "id": "d601a366669cee57",
        "type": "inject",
        "z": "1b4dc69d8cd3f4af",
        "name": "",
        "props": [
            {
                "p": "payload"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "0.2",
        "payloadType": "num",
        "x": 1110,
        "y": 920,
        "wires": [
            [
                "70ee8ef879c76a39"
            ]
        ]
    },
    {
        "id": "656222e32a2f6622",
        "type": "inject",
        "z": "1b4dc69d8cd3f4af",
        "name": "",
        "props": [
            {
                "p": "payload"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "1",
        "payloadType": "num",
        "x": 1110,
        "y": 1000,
        "wires": [
            [
                "70ee8ef879c76a39"
            ]
        ]
    }
]

```

To clarify a little bit:

- Two heaters: primary and auxiliary.
- Primary is directly controlled by a thermostat.
- Auxiliary heater is connected to a Zigbee-controlled plug.
- Primary thermostat outputs (via Zigbee) and heating demand percentage.
- When the thermostat calls for a heating demand percentage higher than N, I want to start cycling the auxiliary heater to match.

Examples of what I expect with demand percentages:

1. 50%: cycle the auxiliary for 5 minutes ON, 5 minutes OFF
2. 75%: cycle the auxiliary for 7.5 minutes ON, 2.5 minutes OFF
3. Etc.

I will likely have to tweak that to get a smooth temperature without an annoying start/stop in the background.

I'm actually more comfortable coding than using Node-RED, at this point, so I'll take your ideas and see about writing a function @craigcurtin .

---

<div class="post-metadata">

### Author: ![Colin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/colin/32/17040_2.png) [@Colin](https://discourse.nodered.org/u/Colin)
#### Post date: [7 January 2022 19:33 UTC](https://discourse.nodered.org/t/dynamic-duty-cycle/56232/7 "2022-01-07T19:33:55Z")

</div>

> [@crbn60](#):
>
> timeprop is not working for me, unsure why.

Neither am I. Your flow works for me. I sent the output to a chart and see this with 50%

![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/7/1/71585a55f1a32a6125a64e9231cfd8cec5a5f1f1.png)

It sounds as the PID node is not what you want. But the timeprop node should do what you are asking for.

---

<div class="post-metadata">

### Author: ![crbn60](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/crbn60/32/53688_2.png) [@crbn60](https://discourse.nodered.org/u/crbn60)
#### Post date: [7 January 2022 19:50 UTC](https://discourse.nodered.org/t/dynamic-duty-cycle/56232/8 "2022-01-07T19:50:31Z")

</div>

> [@Colin](#):
>
> Neither am I. Your flow works for me. I sent the output to a chart and see this with 50%

I restarted Node-RED and now it's working for me. 🙂

Also, sending it to a chart is a great idea for testing, thank you.

---

<div class="post-metadata">

### Author: ![system](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/1X/d073cd938eafa2e558d7c2cd59003b3ef4963033.png) [@system](https://discourse.nodered.org/u/system)
#### Post date: [21 January 2022 19:50 UTC](https://discourse.nodered.org/t/dynamic-duty-cycle/56232/9 "2022-01-21T19:50:37Z")

</div>

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.
