Dynamic Duty Cycle

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.

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

Looked up the 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?

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

1 Like

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:

[
    {
        "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 .

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

image

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

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

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

1 Like