Below I attached my code for a subflow I call Heater Control. It has a deadman, variable setpoint and hysteresis capability.
If you input msg.setpoint it changes the setpoint, else it expects msg.payload to be a temperature.
When you double click the node you can manually set the setpoint/hysteresis/deadman wait.
It outputs a true or false if the heater should be on.
Here is a usage where I AND the output of the heater control with if I have been in the room in the last 30 minutes and an enable button I have at my desk.
Heater Node
[{“id”:“cd72f043d3c30165”,“type”:“subflow”,“name”:“Heater Control”,“info”:“”,“category”:“”,“in”:[{“x”:60,“y”:380,“wires”:[{“id”:“36ea054028726ff2”}]}],“out”:[{“x”:1100,“y”:480,“wires”:[{“id”:“aac0d08884b39eac”,“port”:0}]}],“env”:[{“name”:“Deadman”,“type”:“num”,“value”:“1800”,“ui”:{“type”:“input”,“opts”:{“types”:[“num”]}}},{“name”:“Setpoint”,“type”:“num”,“value”:“72”,“ui”:{“type”:“input”,“opts”:{“types”:[“num”]}}},{“name”:“Hysterisis”,“type”:“num”,“value”:“.25”,“ui”:{“type”:“input”,“opts”:{“types”:[“num”]}}}],“meta”:{},“color”:“#DDAA99”,“status”:{“x”:1240,“y”:700,“wires”:[{“id”:“ed0f6eed115d649f”,“port”:0},{“id”:“626ca8c4422166d3”,“port”:0},{“id”:“15f6134e5e2d061b”,“port”:0}]}},{“id”:“c38f605f469d288a”,“type”:“junction”,“z”:“cd72f043d3c30165”,“x”:640,“y”:420,“wires”:[[“128f2cc777c897e4”]]},{“id”:“aac0d08884b39eac”,“type”:“junction”,“z”:“cd72f043d3c30165”,“x”:1040,“y”:540,“wires”:[[“19f4a5df9510ac19”]]},{“id”:“281f57c8fa3f0f59”,“type”:“change”,“z”:“cd72f043d3c30165”,“name”:“set temperature vars”,“rules”:[{“t”:“set”,“p”:“temperature”,“pt”:“flow”,“to”:“payload”,“tot”:“msg”},{“t”:“set”,“p”:“deadman”,“pt”:“flow”,“to”:“true”,“tot”:“bool”}],“action”:“”,“property”:“”,“from”:“”,“to”:“”,“reg”:false,“x”:460,“y”:320,“wires”:[[“7d7467d8719355cd”,“c38f605f469d288a”]]},{“id”:“7d7467d8719355cd”,“type”:“stoptimer-varidelay”,“z”:“cd72f043d3c30165”,“duration”:“Deadman”,“durationType”:“env”,“units”:“Second”,“payloadtype”:“num”,“payloadval”:“0”,“name”:“”,“reporting”:“none”,“persist”:false,“ignoretimerpass”:false,“x”:790,“y”:380,“wires”:[[“c2a0cb4460ae7fc5”],[],[]]},{“id”:“c2a0cb4460ae7fc5”,“type”:“change”,“z”:“cd72f043d3c30165”,“name”:“set deadman”,“rules”:[{“t”:“set”,“p”:“deadman”,“pt”:“flow”,“to”:“false”,“tot”:“bool”}],“action”:“”,“property”:“”,“from”:“”,“to”:“”,“reg”:false,“x”:1030,“y”:360,“wires”:[[“9e33747691b16133”]]},{“id”:“f8cd1f1205490235”,“type”:“change”,“z”:“cd72f043d3c30165”,“name”:“Get Temp Diff”,“rules”:[{“t”:“delete”,“p”:“payload”,“pt”:“msg”},{“t”:“set”,“p”:“setpoint”,“pt”:“msg”,“to”:“Setpoint”,“tot”:“flow”},{“t”:“set”,“p”:“currentTemp”,“pt”:“msg”,“to”:“temperature”,“tot”:“flow”},{“t”:“set”,“p”:“payload”,“pt”:“msg”,“to”:“msg.currentTemp - msg.setpoint”,“tot”:“jsonata”}],“action”:“”,“property”:“”,“from”:“”,“to”:“”,“reg”:false,“x”:420,“y”:500,“wires”:[[“d137275b06425345”]]},{“id”:“128f2cc777c897e4”,“type”:“switch”,“z”:“cd72f043d3c30165”,“name”:“Heating”,“property”:“heating”,“propertyType”:“flow”,“rules”:[{“t”:“true”},{“t”:“false”}],“checkall”:“true”,“repair”:false,“outputs”:2,“x”:220,“y”:520,“wires”:[[“f8cd1f1205490235”],[“df3a3f28f4a0994f”]]},{“id”:“d137275b06425345”,“type”:“switch”,“z”:“cd72f043d3c30165”,“name”:“”,“property”:“payload”,“propertyType”:“msg”,“rules”:[{“t”:“gte”,“v”:“Hysterisis”,“vt”:“env”},{“t”:“lt”,“v”:“Hysterisis”,“vt”:“env”}],“checkall”:“true”,“repair”:false,“outputs”:2,“x”:590,“y”:500,“wires”:[[“9e33747691b16133”],[]]},{“id”:“9e33747691b16133”,“type”:“change”,“z”:“cd72f043d3c30165”,“name”:“Turn Off Heater”,“rules”:[{“t”:“delete”,“p”:“payload”,“pt”:“msg”},{“t”:“set”,“p”:“payload”,“pt”:“msg”,“to”:“false”,“tot”:“bool”},{“t”:“set”,“p”:“heating”,“pt”:“flow”,“to”:“false”,“tot”:“bool”},{“t”:“set”,“p”:“topic”,“pt”:“msg”,“to”:“HeaterControl”,“tot”:“str”}],“action”:“”,“property”:“”,“from”:“”,“to”:“”,“reg”:false,“x”:900,“y”:500,“wires”:[[“aac0d08884b39eac”]]},{“id”:“d1dacd6cdf736af6”,“type”:“switch”,“z”:“cd72f043d3c30165”,“name”:“”,“property”:“payload”,“propertyType”:“msg”,“rules”:[{“t”:“gte”,“v”:“Hysterisis”,“vt”:“env”},{“t”:“lt”,“v”:“Hysterisis”,“vt”:“env”}],“checkall”:“true”,“repair”:false,“outputs”:2,“x”:590,“y”:540,“wires”:[[“b079e1372bf6e02a”],[]]},{“id”:“b079e1372bf6e02a”,“type”:“change”,“z”:“cd72f043d3c30165”,“name”:“Turn On Heater”,“rules”:[{“t”:“delete”,“p”:“payload”,“pt”:“msg”},{“t”:“set”,“p”:“payload”,“pt”:“msg”,“to”:“true”,“tot”:“bool”},{“t”:“set”,“p”:“heating”,“pt”:“flow”,“to”:“true”,“tot”:“bool”},{“t”:“set”,“p”:“topic”,“pt”:“msg”,“to”:“HeaterControl”,“tot”:“str”}],“action”:“”,“property”:“”,“from”:“”,“to”:“”,“reg”:false,“x”:900,“y”:540,“wires”:[[“aac0d08884b39eac”]]},{“id”:“df3a3f28f4a0994f”,“type”:“change”,“z”:“cd72f043d3c30165”,“name”:“Get Temp Diff”,“rules”:[{“t”:“delete”,“p”:“payload”,“pt”:“msg”},{“t”:“set”,“p”:“setpoint”,“pt”:“msg”,“to”:“Setpoint”,“tot”:“flow”},{“t”:“set”,“p”:“currentTemp”,“pt”:“msg”,“to”:“temperature”,“tot”:“flow”},{“t”:“set”,“p”:“payload”,“pt”:“msg”,“to”:“msg.setpoint-msg.currentTemp”,“tot”:“jsonata”},{“t”:“set”,“p”:“tempDiff”,“pt”:“flow”,“to”:“payload”,“tot”:“msg”}],“action”:“”,“property”:“”,“from”:“”,“to”:“”,“reg”:false,“x”:420,“y”:540,“wires”:[[“d1dacd6cdf736af6”]]},{“id”:“19f4a5df9510ac19”,“type”:“switch”,“z”:“cd72f043d3c30165”,“name”:“not Deadman?”,“property”:“deadman”,“propertyType”:“flow”,“rules”:[{“t”:“false”},{“t”:“true”}],“checkall”:“true”,“repair”:false,“outputs”:2,“x”:700,“y”:660,“wires”:[[“ed0f6eed115d649f”],[“d5b0e732e3a2642b”]]},{“id”:“ed0f6eed115d649f”,“type”:“change”,“z”:“cd72f043d3c30165”,“name”:“”,“rules”:[{“t”:“set”,“p”:“payload”,“pt”:“msg”,“to”:“{"fill":"red","text":"Deadman"}”,“tot”:“json”}],“action”:“”,“property”:“”,“from”:“”,“to”:“”,“reg”:false,“x”:1080,“y”:660,“wires”:[[]]},{“id”:“d5b0e732e3a2642b”,“type”:“switch”,“z”:“cd72f043d3c30165”,“name”:“not heating?”,“property”:“heating”,“propertyType”:“flow”,“rules”:[{“t”:“false”},{“t”:“true”}],“checkall”:“true”,“repair”:false,“outputs”:2,“x”:870,“y”:700,“wires”:[[“626ca8c4422166d3”],[“15f6134e5e2d061b”]]},{“id”:“626ca8c4422166d3”,“type”:“change”,“z”:“cd72f043d3c30165”,“name”:“”,“rules”:[{“t”:“set”,“p”:“payload”,“pt”:“msg”,“to”:“{"fill":"red","text":"off"}”,“tot”:“json”}],“action”:“”,“property”:“”,“from”:“”,“to”:“”,“reg”:false,“x”:1080,“y”:700,“wires”:[[]]},{“id”:“15f6134e5e2d061b”,“type”:“change”,“z”:“cd72f043d3c30165”,“name”:“”,“rules”:[{“t”:“set”,“p”:“payload”,“pt”:“msg”,“to”:“{"fill":"green","text":"on"}”,“tot”:“json”}],“action”:“”,“property”:“”,“from”:“”,“to”:“”,“reg”:false,“x”:1080,“y”:740,“wires”:[[]]},{“id”:“e1e1861cf279e7b5”,“type”:“inject”,“z”:“cd72f043d3c30165”,“name”:“”,“props”:[{“p”:“payload”},{“p”:“topic”,“vt”:“str”}],“repeat”:“”,“crontab”:“”,“once”:true,“onceDelay”:0.1,“topic”:“”,“payload”:“”,“payloadType”:“date”,“x”:210,“y”:100,“wires”:[[“46acee4992eeaaf9”]]},{“id”:“46acee4992eeaaf9”,“type”:“change”,“z”:“cd72f043d3c30165”,“name”:“”,“rules”:[{“t”:“set”,“p”:“heating”,“pt”:“flow”,“to”:“false”,“tot”:“bool”},{“t”:“set”,“p”:“Setpoint”,“pt”:“flow”,“to”:“Setpoint”,“tot”:“env”}],“action”:“”,“property”:“”,“from”:“”,“to”:“”,“reg”:false,“x”:380,“y”:100,“wires”:[[]]},{“id”:“36ea054028726ff2”,“type”:“switch”,“z”:“cd72f043d3c30165”,“name”:“Setpoint message?”,“property”:“setpoint”,“propertyType”:“msg”,“rules”:[{“t”:“nnull”},{“t”:“else”}],“checkall”:“false”,“repair”:false,“outputs”:2,“x”:210,“y”:380,“wires”:[[“1b28cde477752fac”],[“281f57c8fa3f0f59”]]},{“id”:“1b28cde477752fac”,“type”:“change”,“z”:“cd72f043d3c30165”,“name”:“”,“rules”:[{“t”:“set”,“p”:“Setpoint”,“pt”:“flow”,“to”:“setpoint”,“tot”:“msg”}],“action”:“”,“property”:“”,“from”:“”,“to”:“”,“reg”:false,“x”:440,“y”:380,“wires”:[[“c38f605f469d288a”]]}]