Shelly TRV & Boiler Control

Hi all,

Is there anyone using node red to control their heating using shelly TRVs? I have a sheely relay controlling the boiler. I have it working kind of but I need to refine my flow as it's not working well and would love some help.

[{"id":"199927621f74dae7","type":"shelly-gen1","z":"621e13c065c90b68","hostname":"192.168.1.13","description":"Upstairs TRV","pollinginterval":"20000","pollstatus":false,"getstatusoncommand":true,"devicetype":"Thermostat","outputs":1,"rgbwmode":"color","x":1070,"y":600,"wires":[["732aad396e2a7494","bb66b1491f9717a9","2e9dc0aafae6db31"]]},{"id":"3cde6b496e57a52d","type":"inject","z":"621e13c065c90b68","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":620,"y":460,"wires":[["b7eff84fe58778f4"]]},{"id":"e5a025a3cb4ac8dc","type":"debug","z":"621e13c065c90b68","name":"debug 29","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":2280,"y":480,"wires":[]},{"id":"732aad396e2a7494","type":"change","z":"621e13c065c90b68","name":"MY TRV Temp","rules":[{"t":"set","p":"payload","pt":"msg","to":"payload.thermostats[0].tmp.value","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":1320,"y":620,"wires":[["77c696e9e1c904ef"]]},{"id":"2e9dc0aafae6db31","type":"switch","z":"621e13c065c90b68","name":"Above or Below Setpoint?","property":"payload.thermostats[0].tmp.value","propertyType":"jsonata","rules":[{"t":"lt","v":"payload.thermostats[0].target_t.value","vt":"jsonata"},{"t":"gte","v":"payload.thermostats[0].target_t.value","vt":"jsonata"}],"checkall":"true","repair":false,"outputs":2,"x":1350,"y":520,"wires":[["bc1b15b9303cbe96","84d9c421fa5ad887"],["71a371970da5ab47","c5a9c8ee733f7937"]]},{"id":"bb66b1491f9717a9","type":"change","z":"621e13c065c90b68","name":"Set point Temp?","rules":[{"t":"set","p":"payload","pt":"msg","to":"payload.thermostats[0].target_t.value","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":1320,"y":720,"wires":[["80ca104e29336005"]]},{"id":"69639a8497ad18f9","type":"shelly-gen1","z":"621e13c065c90b68","hostname":"192.168.1.28","description":"Boiler ","pollinginterval":"5000","pollstatus":false,"getstatusoncommand":true,"devicetype":"Relay","outputs":1,"rgbwmode":"color","x":2070,"y":280,"wires":[["f0ecf23892a193f6","d9d51e43bc742c4e"]],"outputLabels":["Heating ON"]},{"id":"1efbc40ebce3bbef","type":"shelly-gen1","z":"621e13c065c90b68","hostname":"192.168.1.28","description":"Boiler ","pollinginterval":"5000","pollstatus":false,"getstatusoncommand":true,"devicetype":"Relay","outputs":1,"rgbwmode":"color","x":2070,"y":380,"wires":[["e5a025a3cb4ac8dc","d9d51e43bc742c4e"]]},{"id":"bc1b15b9303cbe96","type":"function","z":"621e13c065c90b68","name":"If Temp Below Set Point - Boiler On","func":"msg.payload = {\n    relay:0,\n    on:true\n};\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1680,"y":300,"wires":[["9585d6ed3ca183eb"]]},{"id":"c5a9c8ee733f7937","type":"function","z":"621e13c065c90b68","name":"If Temp Above Set Point - Boiler Off","func":"msg.payload = {\n    relay:0, \n    on:false\n};\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1680,"y":500,"wires":[["bbd97d47e44755ad"]]},{"id":"77c696e9e1c904ef","type":"debug","z":"621e13c065c90b68","name":"debug 30","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1620,"y":680,"wires":[]},{"id":"80ca104e29336005","type":"debug","z":"621e13c065c90b68","name":"debug 31","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":1620,"y":760,"wires":[]},{"id":"84d9c421fa5ad887","type":"debug","z":"621e13c065c90b68","name":"debug 32","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1620,"y":400,"wires":[]},{"id":"71a371970da5ab47","type":"debug","z":"621e13c065c90b68","name":"debug 33","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":1620,"y":600,"wires":[]},{"id":"d9d51e43bc742c4e","type":"link out","z":"621e13c065c90b68","name":"link out 2","mode":"link","links":[],"x":2385,"y":340,"wires":[]},{"id":"62af04d43ea81058","type":"link in","z":"621e13c065c90b68","name":"link in 2","links":[],"x":675,"y":580,"wires":[["b7eff84fe58778f4"]]},{"id":"b7eff84fe58778f4","type":"function","z":"621e13c065c90b68","name":"schedule profile 4","func":"// see https://shelly-api-docs.shelly.cloud/gen1/#shelly-trv-thermostats-0\nmsg.payload = {\n  scheduleProfile : 4\n};\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":810,"y":520,"wires":[["199927621f74dae7","16b821ed5473ee9f","9d19952ccac5f813"]]},{"id":"16b821ed5473ee9f","type":"shelly-gen1","z":"621e13c065c90b68","hostname":"192.168.1.14","description":"Bedroom 1 TRV","pollinginterval":"20000","pollstatus":false,"getstatusoncommand":true,"devicetype":"Thermostat","outputs":1,"rgbwmode":"color","x":1060,"y":520,"wires":[["2e9dc0aafae6db31"]]},{"id":"9d19952ccac5f813","type":"shelly-gen1","z":"621e13c065c90b68","hostname":"192.168.1.15","description":"Bedroom 2 TRV","pollinginterval":"20000","pollstatus":false,"getstatusoncommand":true,"devicetype":"Thermostat","outputs":1,"rgbwmode":"color","x":1060,"y":440,"wires":[["2e9dc0aafae6db31"]]},{"id":"f0ecf23892a193f6","type":"debug","z":"621e13c065c90b68","name":"debug 34","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":2300,"y":220,"wires":[]},{"id":"bbd97d47e44755ad","type":"delay","z":"621e13c065c90b68","name":"","pauseType":"delay","timeout":"10","timeoutUnits":"minutes","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":1910,"y":440,"wires":[["1efbc40ebce3bbef"]]},{"id":"9585d6ed3ca183eb","type":"delay","z":"621e13c065c90b68","name":"","pauseType":"delay","timeout":"10","timeoutUnits":"minutes","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":1910,"y":280,"wires":[["69639a8497ad18f9"]]}]

This is where I am at, but it drives the relay mad with multiple outputs to the relay. I'm relatively new to node red and still very much learning as I go so please be kind.

Thanks in advance.

In order to make code readable and usable it is necessary to surround your code with three backticks (also known as a left quote or backquote ```)

``` 
   code goes here 
```

You can edit and correct your post by clicking the pencil :pencil2: icon.

See this post for more details - How to share code or flow json

ok thanks Paul

That's still not correct Brendan, the 3 backticks at the top & bottom of your code need to be on their own lines, just like the example I showed you above.

Is there contention between the TRV's switching the boiler on/off as each temperature is above/below target temperature?

A Debug node after 'Above or Below Setpoint' would help identify this.

I've included the debug nodes.

Yes I think you're right, there is conflicting msgs going to the boiler to turn on and off and also multiple msgs hitting the relay at the same time. I had hoped the delay node might help with this and also to prevent the boiler cycling on and off too much but i will have to find a better solution.

[{"id":"01cdaeaa523a6e51","type":"shelly-gen1","z":"8b0bb1a391938429","hostname":"192.168.1.13","description":"Upstairs TRV","pollinginterval":"20000","pollstatus":false,"getstatusoncommand":true,"devicetype":"Thermostat","outputs":1,"rgbwmode":"color","x":550,"y":520,"wires":[["4e93b8090121ae90","1965df3edab1a701","69587ac2002b58a9"]]},{"id":"eed0a26c7be05f31","type":"inject","z":"8b0bb1a391938429","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":100,"y":380,"wires":[["0ecc87277b9a71fc"]]},{"id":"fd7c4e94a40d59fa","type":"debug","z":"8b0bb1a391938429","name":"debug 2","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1760,"y":400,"wires":[]},{"id":"4e93b8090121ae90","type":"change","z":"8b0bb1a391938429","name":"MY TRV Temp","rules":[{"t":"set","p":"payload","pt":"msg","to":"payload.thermostats[0].tmp.value","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":800,"y":540,"wires":[["9d93e0e5952b07c1"]]},{"id":"69587ac2002b58a9","type":"switch","z":"8b0bb1a391938429","name":"Above or Below Setpoint?","property":"payload.thermostats[0].tmp.value","propertyType":"jsonata","rules":[{"t":"lt","v":"payload.thermostats[0].target_t.value","vt":"jsonata"},{"t":"gte","v":"payload.thermostats[0].target_t.value","vt":"jsonata"}],"checkall":"true","repair":false,"outputs":2,"x":830,"y":440,"wires":[["63f70d52ef8d6b49","83b5cb0f77b486df"],["fa555c9d9f12768e","db7b64f2963a2256"]]},{"id":"1965df3edab1a701","type":"change","z":"8b0bb1a391938429","name":"Set point Temp?","rules":[{"t":"set","p":"payload","pt":"msg","to":"payload.thermostats[0].target_t.value","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":800,"y":640,"wires":[["91ccfb62cbdb9198"]]},{"id":"8a064f656ebf8061","type":"shelly-gen1","z":"8b0bb1a391938429","hostname":"192.168.1.28","description":"Boiler ","pollinginterval":"5000","pollstatus":false,"getstatusoncommand":true,"devicetype":"Relay","outputs":1,"rgbwmode":"color","x":1550,"y":200,"wires":[["8643394d0fa81396","994002b342b5fe5d"]],"outputLabels":["Heating ON"]},{"id":"2c5b923354495d4c","type":"shelly-gen1","z":"8b0bb1a391938429","hostname":"192.168.1.28","description":"Boiler ","pollinginterval":"5000","pollstatus":false,"getstatusoncommand":true,"devicetype":"Relay","outputs":1,"rgbwmode":"color","x":1550,"y":300,"wires":[["fd7c4e94a40d59fa","994002b342b5fe5d"]]},{"id":"63f70d52ef8d6b49","type":"function","z":"8b0bb1a391938429","name":"If Temp Below Set Point - Boiler On","func":"msg.payload = {\n    relay:0,\n    on:true\n};\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1160,"y":220,"wires":[["33c81bfeb951ce74","b67e3557d93eebda"]]},{"id":"db7b64f2963a2256","type":"function","z":"8b0bb1a391938429","name":"If Temp Above Set Point - Boiler Off","func":"msg.payload = {\n    relay:0, \n    on:false\n};\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1160,"y":420,"wires":[["8ee63792398db22a","bf71c95eec6321cf"]]},{"id":"9d93e0e5952b07c1","type":"debug","z":"8b0bb1a391938429","name":"debug 8","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1100,"y":600,"wires":[]},{"id":"91ccfb62cbdb9198","type":"debug","z":"8b0bb1a391938429","name":"debug 9","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":1100,"y":680,"wires":[]},{"id":"83b5cb0f77b486df","type":"debug","z":"8b0bb1a391938429","name":"debug 10","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1100,"y":320,"wires":[]},{"id":"fa555c9d9f12768e","type":"debug","z":"8b0bb1a391938429","name":"debug 11","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":1100,"y":520,"wires":[]},{"id":"994002b342b5fe5d","type":"link out","z":"8b0bb1a391938429","name":"link out 1","mode":"link","links":[],"x":1865,"y":260,"wires":[]},{"id":"ec74e1e8aac05283","type":"link in","z":"8b0bb1a391938429","name":"link in 1","links":[],"x":155,"y":500,"wires":[["0ecc87277b9a71fc"]]},{"id":"0ecc87277b9a71fc","type":"function","z":"8b0bb1a391938429","name":"schedule profile 4","func":"// see https://shelly-api-docs.shelly.cloud/gen1/#shelly-trv-thermostats-0\nmsg.payload = {\n  scheduleProfile : 4\n};\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":290,"y":440,"wires":[["01cdaeaa523a6e51","bb3c07022160fdbf","cd5883d62d61979c"]]},{"id":"bb3c07022160fdbf","type":"shelly-gen1","z":"8b0bb1a391938429","hostname":"192.168.1.14","description":"Bedroom 1 TRV","pollinginterval":"20000","pollstatus":false,"getstatusoncommand":true,"devicetype":"Thermostat","outputs":1,"rgbwmode":"color","x":540,"y":440,"wires":[["69587ac2002b58a9"]]},{"id":"cd5883d62d61979c","type":"shelly-gen1","z":"8b0bb1a391938429","hostname":"192.168.1.15","description":"Bedroom 2 TRV","pollinginterval":"20000","pollstatus":false,"getstatusoncommand":true,"devicetype":"Thermostat","outputs":1,"rgbwmode":"color","x":540,"y":360,"wires":[["69587ac2002b58a9"]]},{"id":"8ee63792398db22a","type":"delay","z":"8b0bb1a391938429","name":"","pauseType":"delay","timeout":"10","timeoutUnits":"minutes","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":1390,"y":360,"wires":[["2c5b923354495d4c"]]},{"id":"33c81bfeb951ce74","type":"delay","z":"8b0bb1a391938429","name":"","pauseType":"delay","timeout":"10","timeoutUnits":"minutes","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":1390,"y":200,"wires":[["8a064f656ebf8061"]]},{"id":"bf71c95eec6321cf","type":"debug","z":"8b0bb1a391938429","name":"debug 29","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":1440,"y":440,"wires":[]},{"id":"b67e3557d93eebda","type":"debug","z":"8b0bb1a391938429","name":"debug 30","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":1400,"y":280,"wires":[]}]

If you switch the boiler on and off when the measured temperature hovers around the target temperature you can expect this behaviour.
You don't need a time delay, you need hysteresis (plus perhaps a time delay).

I feel that you need to think about what is required.

Hysteresis is something to be considered, But first you need to get some kind of priority going so that IF a TRV requires heat the boiler will stay on UNTIL no TRV requires heat. Once you have this, you can add a timing schedule to control WHEN you want this to happen if desired.

Thanks I appreciate your input. I realise that this is what I need to achive I am just unssure how to get there, which is why I am posting. For example I am not sure whether this can/should be done with a function node to check if any of the TRV require heat or maybe a logic node such as an or node? I prbable need a rate limiter also to allow only 1 msg hit the boiler relay ever x minuest also.
The bottom line is I need some guidance with this so if anyone can help row in :slight_smile:

If it was me, I would use a function node and then use an OR|OR, so basically

if (TRV1 demand  || TRV2 demand || TRV3 demand){
     Boiler ON
} 
else
{
Boiler OFF
}

Javascript (JS) is what you need to use and Google will be your friend.

I could do it for you, but then you need to understand what you are doing! Seriously, Node RED is great for this sort of thing and once you get to know it, you will benefit from it's flexibility.

Now the usual advice...

I recommend watching this playlist: Node-RED Essentials. The videos are done by the developers of node-red. They're nice & short and to the point. You will understand a whole lot more in about 1 hour. A small investment for a lot of gain.

Actually, i think this would be better than relying on temperature measurements. It's also less complicated.
If the valve is opened, there is demand. No need to check the actual / target temperature.

1 Like

Hey mudwalker, thanks for the input it's much appreciated. I have taken jw_te_r's advice below and looked for the valve position if it's zero turn off the boiler if any are any other position leave the boiler on.

I've set up variables in the change nodes and now it's just the function node comparing these that is catching me. I watched all the videos and have done some googling but maybe you could let me know if I'm on the right tack here? I'm trying to use the or or function you suggested.

P.S. I did all my homework and watched the videos you suggested, thank you :slight_smile:

[{"id":"01cdaeaa523a6e51","type":"shelly-gen1","z":"8b0bb1a391938429","hostname":"192.168.1.13","description":"Upstairs TRV","pollinginterval":"20000","pollstatus":false,"getstatusoncommand":true,"devicetype":"Thermostat","outputs":1,"rgbwmode":"color","x":530,"y":520,"wires":[["8341ee0febeca782"]]},{"id":"eed0a26c7be05f31","type":"inject","z":"8b0bb1a391938429","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":100,"y":380,"wires":[["0ecc87277b9a71fc"]]},{"id":"8a064f656ebf8061","type":"shelly-gen1","z":"8b0bb1a391938429","hostname":"192.168.1.28","description":"Boiler ","pollinginterval":"5000","pollstatus":false,"getstatusoncommand":true,"devicetype":"Relay","outputs":1,"rgbwmode":"color","x":1510,"y":440,"wires":[["994002b342b5fe5d"]],"outputLabels":["Heating ON"]},{"id":"994002b342b5fe5d","type":"link out","z":"8b0bb1a391938429","name":"link out 1","mode":"link","links":[],"x":1605,"y":500,"wires":[]},{"id":"ec74e1e8aac05283","type":"link in","z":"8b0bb1a391938429","name":"link in 1","links":[],"x":155,"y":500,"wires":[["0ecc87277b9a71fc"]]},{"id":"0ecc87277b9a71fc","type":"function","z":"8b0bb1a391938429","name":"schedule profile 4","func":"// see https://shelly-api-docs.shelly.cloud/gen1/#shelly-trv-thermostats-0\nmsg.payload = {\n  scheduleProfile : 4\n};\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":290,"y":440,"wires":[["01cdaeaa523a6e51","bb3c07022160fdbf","cd5883d62d61979c"]]},{"id":"bb3c07022160fdbf","type":"shelly-gen1","z":"8b0bb1a391938429","hostname":"192.168.1.14","description":"Bedroom 1 TRV","pollinginterval":"20000","pollstatus":false,"getstatusoncommand":true,"devicetype":"Thermostat","outputs":1,"rgbwmode":"color","x":540,"y":440,"wires":[["8341ee0febeca782"]]},{"id":"cd5883d62d61979c","type":"shelly-gen1","z":"8b0bb1a391938429","hostname":"192.168.1.15","description":"Bedroom 2 TRV","pollinginterval":"20000","pollstatus":false,"getstatusoncommand":true,"devicetype":"Thermostat","outputs":1,"rgbwmode":"color","x":540,"y":360,"wires":[["8341ee0febeca782"]]},{"id":"8341ee0febeca782","type":"change","z":"8b0bb1a391938429","name":"","rules":[{"t":"set","p":"trv_2","pt":"flow","to":"payload.thermostats[0].pos","tot":"msg"},{"t":"set","p":"trv_1","pt":"flow","to":"payload.thermostats[0].pos","tot":"msg"},{"t":"set","p":"upstairs_trv","pt":"flow","to":"payload.thermostats[0].pos","tot":"msg"},{"t":"set","p":"payload","pt":"msg","to":"output set","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":820,"y":440,"wires":[["6eb2cb299ffcf505"]]},{"id":"6eb2cb299ffcf505","type":"function","z":"8b0bb1a391938429","name":"function 1","func":"if (trv_1 = 0 || trv_2 = 0 || upstairs_trv = 0) {\n     msg.payload = {\n          relay: 0,\n          on: true\n     };\n\n} \nelse\n{\n     msg.payload = {\n          relay: 0,\n          on: false\n     };\n}\nreturn msg;","outputs":1,"noerr":7,"initialize":"","finalize":"","libs":[],"x":1080,"y":440,"wires":[["192723fccffbc8d7"]]},{"id":"192723fccffbc8d7","type":"delay","z":"8b0bb1a391938429","name":"","pauseType":"rate","timeout":"10","timeoutUnits":"minutes","rate":"1","nbRateUnits":"10","rateUnits":"minute","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":true,"allowrate":false,"outputs":1,"x":1300,"y":440,"wires":[["8a064f656ebf8061"]]}]

in your function you have

if (trv_1 = 0 || trv_2 = 0 || upstairs_trv = 0) {
     msg.payload = {
          relay: 0,
          on: true
     };

} 
else
{
     msg.payload = {
          relay: 0,
          on: false
     };
}
return msg;

first off you have if (trv_1 = 0 || trv_2 = 0 || upstairs_trv = 0) {
error 1: try_1 is not defined neither is trv_2 or upstairs_trv
try adding 'let try_1 = flow.get("try_1");` and the same for the other variables.

error 2: trv_1 = 0 would set try_1 to the value 0 you want trv_1 == 0` You might find this link helpful JavaScript Comparison and Logical Operators

1 Like

Thanks I'll try that.. I had thought that they (trv_1) etc were defined in the change node but obviously not.

Each node is separate from each other. The only thing that will be constant is what is in the msg.

You need to use
let trv_1 = flow.get(“trv_1”) || 0;
to get the value

You might want to search for a couple of threads in here regarding Shelly TRV and MQTT. You could find some pointers in tere. The internet is a good thing just use JS before you ask the search question e.g. , you will be surprised what comes up.

You can use the position, but as you advance, you might set the Minimum Valve Position Setting, then you might not close to '0' but, you could request that setting from each TRV via MQTT. Good planning at this stage will help later as you develop a flow.

Get a basic flow working first and go from there. It is how we all started. As @zenofmud has pointed out, you hadn't defined some variables, the Editor will put a red block in the Scroll Bar of there is a Syntax error, or if the node is not displayed, but the flow is, a red triangle will appear on it (as per your flow).

Keep going and there are many helpful people on here that can help with specific problems you may come across!

Just a quick thank you to all those that contributed here @mudwalker @zenofmud @jw_te_r I really appreciate it. It's tough starting out, but your input has really helped and I feel I've learnt a lot from your advice.

I have a basic flow going now which is controlling the heat nicely now and as I learn I will add further control. For example when it is warm during the summer and the trvs don't call for heat I would like to turn off the motorised valve letting heat to all rads and just heat the cylinder for an hour or so which will allow for hot water. For this I might need to check local temp and count the amout of time boiler relay has been on in 24hrs but that is the next step.

Anyway thanks again.
I'll post my flow here for critique or it may help someone else who stumbles upon this thread down the line.

[{"id":"eed0a26c7be05f31","type":"inject","z":"8b0bb1a391938429","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":100,"y":380,"wires":[["0ecc87277b9a71fc"]]},{"id":"0ecc87277b9a71fc","type":"function","z":"8b0bb1a391938429","name":"schedule profile 4","func":"// see https://shelly-api-docs.shelly.cloud/gen1/#shelly-trv-thermostats-0\nmsg.payload = {\n  scheduleProfile : 4\n};\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":290,"y":440,"wires":[["bb3c07022160fdbf","cd5883d62d61979c","94b2ac641b3043fb"]]},{"id":"bb3c07022160fdbf","type":"shelly-gen1","z":"8b0bb1a391938429","hostname":"192.168.1.14","description":"Bedroom 1 TRV","pollinginterval":"20000","pollstatus":false,"getstatusoncommand":true,"devicetype":"Thermostat","outputs":1,"rgbwmode":"color","x":540,"y":440,"wires":[["f674dc1440f9b10e","61330c256c910598"]]},{"id":"cd5883d62d61979c","type":"shelly-gen1","z":"8b0bb1a391938429","hostname":"192.168.1.15","description":"Bedroom 2 TRV","pollinginterval":"20000","pollstatus":false,"getstatusoncommand":true,"devicetype":"Thermostat","outputs":1,"rgbwmode":"color","x":540,"y":360,"wires":[["4c76b3bb46faba6e","6774eb197e4982e7"]]},{"id":"1c82d4c8f9f224a9","type":"debug","z":"8b0bb1a391938429","name":"debug 46","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":1540,"y":400,"wires":[]},{"id":"f05c49f240df9390","type":"shelly-gen1","z":"8b0bb1a391938429","hostname":"192.168.1.28","description":"Boiler ","pollinginterval":"5000","pollstatus":false,"getstatusoncommand":true,"devicetype":"Relay","outputs":1,"rgbwmode":"color","x":1410,"y":460,"wires":[["1c82d4c8f9f224a9","089d3eea0216087a"]],"outputLabels":["Heating ON"]},{"id":"dc1e35f86eb3a4db","type":"delay","z":"8b0bb1a391938429","name":"","pauseType":"rate","timeout":"10","timeoutUnits":"minutes","rate":"1","nbRateUnits":"1","rateUnits":"minute","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":true,"allowrate":false,"outputs":1,"x":1230,"y":440,"wires":[["f05c49f240df9390"]]},{"id":"7c5c7756fbcf9191","type":"debug","z":"8b0bb1a391938429","name":"debug 48","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":1260,"y":540,"wires":[]},{"id":"f674dc1440f9b10e","type":"debug","z":"8b0bb1a391938429","name":"debug 49","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":760,"y":320,"wires":[]},{"id":"4c76b3bb46faba6e","type":"debug","z":"8b0bb1a391938429","name":"debug 50","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":760,"y":280,"wires":[]},{"id":"61330c256c910598","type":"change","z":"8b0bb1a391938429","name":"Change TRV 1","rules":[{"t":"set","p":"trv_1","pt":"flow","to":"payload.thermostats[0].pos","tot":"jsonata"},{"t":"set","p":"payload","pt":"msg","to":"payload.thermostats[0].pos","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":820,"y":440,"wires":[["c7efc07ecd3ae3bc"]]},{"id":"c7efc07ecd3ae3bc","type":"function","z":"8b0bb1a391938429","name":"function 4","func":"var trv_1 = flow.get(\"trv_1\")\nvar trv_2 = flow.get(\"trv_2\")\nvar upstairs_trv = flow.get(\"upstairs_trv\")\n\nif (trv_1 > 5 || trv_2 > 5 || upstairs_trv >5) {\n     msg.payload = {\n          relay: 0,\n          on: true\n     }   \n} else {\n     msg.payload = {\n          relay: 0,\n          on: false\n     }\n}\nreturn msg;\n","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1020,"y":500,"wires":[["7c5c7756fbcf9191","dc1e35f86eb3a4db"]]},{"id":"6774eb197e4982e7","type":"change","z":"8b0bb1a391938429","name":"Change TRV 2","rules":[{"t":"set","p":"trv_2","pt":"flow","to":"payload.thermostats[0].pos","tot":"jsonata"},{"t":"set","p":"payload","pt":"msg","to":"payload.thermostats[0].pos","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":820,"y":400,"wires":[["c7efc07ecd3ae3bc"]]},{"id":"089d3eea0216087a","type":"delay","z":"8b0bb1a391938429","name":"","pauseType":"delay","timeout":"10","timeoutUnits":"minutes","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":1410,"y":620,"wires":[["0ecc87277b9a71fc"]]},{"id":"485b0a5c2d567446","type":"change","z":"8b0bb1a391938429","name":"Change Upstairs TRV","rules":[{"t":"set","p":"upstairs_trv","pt":"flow","to":"payload.thermostats[0].pos","tot":"jsonata"},{"t":"set","p":"payload","pt":"msg","to":"payload.thermostats[0].pos","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":800,"y":480,"wires":[["c7efc07ecd3ae3bc"]]},{"id":"94b2ac641b3043fb","type":"shelly-gen1","z":"8b0bb1a391938429","hostname":"192.168.1.13","description":"","pollinginterval":"20000","pollstatus":false,"getstatusoncommand":true,"devicetype":"Thermostat","outputs":1,"rgbwmode":"color","x":550,"y":540,"wires":[["485b0a5c2d567446"]]}] ```
1 Like

Looks good!

You use JSON (in a good way!), which I have never really got the hang of. As you progress, so your flow will increase in size until you get one that does everything you want from the heating system (including controlling the water side??.

There is a flow discussed around here that programmes the profiles into the Shelly and enables selection of one to run. (Should you be interested) and yes, I did use JSON, but only after being shown how to do it!! :rofl:

1 Like