Sure thing. Here you go. Hope it makes sense. There are comments. It’s too big to screen shot
[{"id":"e1990edd.19d3f8","type":"tab","label":"Climate","disabled":false,"info":""},{"id":"ba3b1dc9.70d1d","type":"server-state-changed","z":"e1990edd.19d3f8","name":"Increase temp","server":"3f1b73d1.299cbc","version":3,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"input_boolean.living_room_temperature_up","entityidfiltertype":"exact","outputinitially":true,"state_type":"str","haltifstate":"on","halt_if_type":"str","halt_if_compare":"is","outputs":2,"output_only_on_state_change":true,"for":"100","forType":"num","forUnits":"milliseconds","ignorePrevStateNull":false,"ignorePrevStateUnknown":false,"ignorePrevStateUnavailable":false,"ignoreCurrentStateUnknown":false,"ignoreCurrentStateUnavailable":false,"x":110,"y":160,"wires":[["30d2da05.d31976","74ffef80.494e4","2e2cad33.fe8b8a"],[]]},{"id":"30d2da05.d31976","type":"delay","z":"e1990edd.19d3f8","name":"Wait 100ms","pauseType":"delay","timeout":"100","timeoutUnits":"milliseconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":350,"y":140,"wires":[["2b983094.26baa"]]},{"id":"2b983094.26baa","type":"api-call-service","z":"e1990edd.19d3f8","name":"Turn off button","server":"3f1b73d1.299cbc","version":3,"debugenabled":false,"service_domain":"input_boolean","service":"turn_off","entityId":"input_boolean.living_room_temperature_up, input_boolean.living_room_temperature_down","data":"","dataType":"json","mergecontext":"","mustacheAltTags":false,"output_location":"payload","output_location_type":"msg","x":540,"y":140,"wires":[[]]},{"id":"8f2ab4c5.d14bc8","type":"api-call-service","z":"e1990edd.19d3f8","name":"Set new targets","server":"3f1b73d1.299cbc","version":3,"debugenabled":false,"service_domain":"climate","service":"set_temperature","entityId":"climate.livingroom_thermostat","data":"","dataType":"json","mergecontext":"","mustacheAltTags":false,"x":580,"y":300,"wires":[[]]},{"id":"9e722cbd.8266a","type":"api-current-state","z":"e1990edd.19d3f8","name":"Get current target","server":"3f1b73d1.299cbc","version":2,"outputs":1,"halt_if":"","halt_if_type":"str","halt_if_compare":"is","entity_id":"climate.livingroom_thermostat","state_type":"str","blockInputOverrides":false,"x":570,"y":220,"wires":[["344a613f.68ecae"]]},{"id":"57e8ccf8.35ebbc","type":"server-state-changed","z":"e1990edd.19d3f8","name":"Decrease temp","server":"3f1b73d1.299cbc","version":3,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"input_boolean.living_room_temperature_down","entityidfiltertype":"exact","outputinitially":false,"state_type":"str","haltifstate":"on","halt_if_type":"str","halt_if_compare":"is","outputs":2,"output_only_on_state_change":true,"for":"100","forType":"num","forUnits":"milliseconds","ignorePrevStateNull":false,"ignorePrevStateUnknown":false,"ignorePrevStateUnavailable":false,"ignoreCurrentStateUnknown":false,"ignoreCurrentStateUnavailable":false,"x":100,"y":220,"wires":[["30d2da05.d31976","ce219d1.894ac6","2e2cad33.fe8b8a"],[]]},{"id":"344a613f.68ecae","type":"function","z":"e1990edd.19d3f8","name":"Calc new target","func":"var temp_change = flow.get('temp_change') || 0\nvar current_temp = msg.data.attributes.temperature\n\nvar new_temp = current_temp + temp_change\nmsg.payload = {\n data: {\n temperature: new_temp\n },\n current_temp: current_temp,\n temp_change: temp_change\n}\n\nflow.set('temp_change', 0)\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":400,"y":300,"wires":[["8f2ab4c5.d14bc8"]]},{"id":"74ffef80.494e4","type":"function","z":"e1990edd.19d3f8","name":"Increment counter","func":"var temp_change = flow.get('temp_change') || 0\n\nflow.set('temp_change', temp_change + 1)\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":310,"y":100,"wires":[[]]},{"id":"eb5852cb.afb968","type":"function","z":"e1990edd.19d3f8","name":"initialisation","func":"\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":90,"y":100,"wires":[[]]},{"id":"ce219d1.894ac6","type":"function","z":"e1990edd.19d3f8","name":"Decrement counter","func":"var temp_change = flow.get('temp_change') || 0\n\nflow.set('temp_change', temp_change - 1)\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":310,"y":260,"wires":[[]]},{"id":"2e2cad33.fe8b8a","type":"trigger","z":"e1990edd.19d3f8","name":"5 second timer","op1":"","op2":"","op1type":"nul","op2type":"payl","duration":"5","extend":true,"units":"s","reset":"","bytopic":"all","topic":"topic","outputs":1,"x":360,"y":220,"wires":[["9e722cbd.8266a"]]},{"id":"f2301f3e.4a805","type":"comment","z":"e1990edd.19d3f8","name":"Adjust the thermostat target temperatures","info":"Increment or decrement the target temperatures of the Living room thermostat.\n\nEach the up or down buttons are pressed, a counter is incremented/decremented. Once 5 seconds has elapsed from the time of the last button-press, the current target will be retrieved and the new target calculated. The new target is then sent to the thermostat.","x":180,"y":60,"wires":[]},{"id":"f254f430.d4d838","type":"inject","z":"e1990edd.19d3f8","name":"trigger at 00:01","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"01 00 * * *","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":110,"y":400,"wires":[["cb5911db.6c3bf","18617dd5.0f436a"]]},{"id":"cb5911db.6c3bf","type":"api-call-service","z":"e1990edd.19d3f8","name":"Turn off manual overide","server":"3f1b73d1.299cbc","version":3,"debugenabled":false,"service_domain":"input_boolean","service":"turn_off","entityId":"input_boolean.central_heating_manual","data":"","dataType":"json","mergecontext":"","mustacheAltTags":false,"x":350,"y":400,"wires":[[]]},{"id":"792aca1f.f54f0c","type":"comment","z":"e1990edd.19d3f8","name":"Reset the central_heating_manual switch","info":"There is a manual overide switch to prevent Schedy switching to nighttime mode. This switch needs to be reset at midnight.","x":180,"y":360,"wires":[]},{"id":"d7754504.1ad5d8","type":"comment","z":"e1990edd.19d3f8","name":"Control CH Boiler","info":"Use the state of the \"we need heat\" virtual switch to control the Sheely switch that causes the boiler to fire.","x":100,"y":568,"wires":[]},{"id":"83331097.6a4d98","type":"api-call-service","z":"e1990edd.19d3f8","name":"Boiler Off","server":"3f1b73d1.299cbc","version":3,"debugenabled":false,"service_domain":"switch","service":"turn_off","entityId":"switch.central_heating_boiler_ch","data":"","dataType":"json","mergecontext":"","mustacheAltTags":false,"x":540,"y":648,"wires":[[]]},{"id":"8ae45f67.0b0278","type":"api-call-service","z":"e1990edd.19d3f8","name":"Boiler On","server":"3f1b73d1.299cbc","version":3,"debugenabled":false,"service_domain":"switch","service":"turn_on","entityId":"switch.central_heating_boiler_ch","data":"","dataType":"json","mergecontext":"","mustacheAltTags":false,"x":540,"y":568,"wires":[[]]},{"id":"16d9f61.9f28c8a","type":"api-call-service","z":"e1990edd.19d3f8","name":"Set Dining Rad","server":"3f1b73d1.299cbc","version":3,"debugenabled":false,"service_domain":"climate","service":"set_temperature","entityId":"climate.diningroom_radiator_thermostat","data":"","dataType":"json","mergecontext":"","mustacheAltTags":false,"x":600,"y":900,"wires":[[]]},{"id":"f62a45ba.70aa08","type":"trigger-state","z":"e1990edd.19d3f8","name":"Livingroom Thermostat","server":"3f1b73d1.299cbc","exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityid":"climate.livingroom_thermostat","entityidfiltertype":"exact","debugenabled":false,"constraints":[],"outputs":2,"customoutputs":[],"outputinitially":false,"state_type":"str","x":130,"y":800,"wires":[["8d475e87.2e9fe8","f0087f7a.b18908"],[]]},{"id":"8d475e87.2e9fe8","type":"function","z":"e1990edd.19d3f8","name":"","func":"var newTemp;\n\nnewTemp = msg.data.event.new_state.attributes.temperature + 0.5;\n\nmsg.payload = {\n domain: 'climate',\n service: 'set_temperature',\n data: {\n temperature: newTemp\n }\n}\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":400,"y":800,"wires":[["9bd29009.94aca","ce82251c.a54b38"]]},{"id":"9bd29009.94aca","type":"debug","z":"e1990edd.19d3f8","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":710,"y":800,"wires":[]},{"id":"ce82251c.a54b38","type":"api-call-service","z":"e1990edd.19d3f8","name":"Set Living Rad","server":"3f1b73d1.299cbc","version":3,"debugenabled":false,"service_domain":"climate","service":"set_temperature","entityId":"climate.livingroom_radiator_thermostat","data":"","dataType":"json","mergecontext":"","mustacheAltTags":false,"x":600,"y":840,"wires":[[]]},{"id":"f712e71d.311498","type":"trigger-state","z":"e1990edd.19d3f8","name":"Bedroom 1 Thermostat","server":"3f1b73d1.299cbc","exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityid":"climate.bedroom_1_thermostat","entityidfiltertype":"exact","debugenabled":false,"constraints":[],"outputs":2,"customoutputs":[],"outputinitially":false,"state_type":"str","x":130,"y":960,"wires":[["c0e41ebe.a00d78"],[]]},{"id":"c0e41ebe.a00d78","type":"function","z":"e1990edd.19d3f8","name":"","func":"var newTemp;\n\nnewTemp = msg.data.event.new_state.attributes.temperature + 0.5\nmsg.payload = {\n domain: 'climate',\n service: 'set_temperature',\n data: {\n temperature: newTemp\n }\n}\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":380,"y":960,"wires":[["3dc170e1.308168","1e46bad6.134e7d"]]},{"id":"3dc170e1.308168","type":"debug","z":"e1990edd.19d3f8","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":590,"y":960,"wires":[]},{"id":"1e46bad6.134e7d","type":"api-call-service","z":"e1990edd.19d3f8","name":"Set Bedroom 1 Rad","server":"3f1b73d1.299cbc","version":3,"debugenabled":false,"service_domain":"climate","service":"set_temperature","entityId":"climate.bedroom_1_radiator_thermostat","data":"","dataType":"json","mergecontext":"","mustacheAltTags":false,"x":620,"y":1000,"wires":[[]]},{"id":"c1ceb612.36728","type":"trigger-state","z":"e1990edd.19d3f8","name":"Bedroom 2 Thermostat","server":"3f1b73d1.299cbc","exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityid":"climate.bedroom_2_thermostat","entityidfiltertype":"exact","debugenabled":false,"constraints":[],"outputs":2,"customoutputs":[],"outputinitially":false,"state_type":"str","x":130,"y":1060,"wires":[["588c8f80.166088"],[]]},{"id":"588c8f80.166088","type":"function","z":"e1990edd.19d3f8","name":"","func":"var newTemp;\n\nnewTemp = msg.data.event.new_state.attributes.temperature + 2.5;\n\nmsg.payload = {\n domain: 'climate',\n service: 'set_temperature',\n data: {\n temperature: newTemp\n }\n}\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":380,"y":1060,"wires":[["9004e06d.b7e97","74370f6c.66f92"]]},{"id":"9004e06d.b7e97","type":"debug","z":"e1990edd.19d3f8","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":590,"y":1060,"wires":[]},{"id":"74370f6c.66f92","type":"api-call-service","z":"e1990edd.19d3f8","name":"Set Bedroom 2 Rad","server":"3f1b73d1.299cbc","version":3,"debugenabled":false,"service_domain":"climate","service":"set_temperature","entityId":"climate.bedroom_2_radiator_thermostat","data":"","dataType":"json","mergecontext":"","mustacheAltTags":false,"x":620,"y":1100,"wires":[[]]},{"id":"6804d077.05d9c8","type":"poll-state","z":"e1990edd.19d3f8","name":"Poll \"We need heat\"","server":"3f1b73d1.299cbc","version":1,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"updateinterval":"1","updateIntervalUnits":"minutes","outputinitially":false,"outputonchanged":false,"entity_id":"binary_sensor.we_need_heat","state_type":"str","halt_if":"","halt_if_type":"str","halt_if_compare":"is","outputs":1,"x":110,"y":600,"wires":[["32ef889e.3865d"]]},{"id":"32ef889e.3865d","type":"switch","z":"e1990edd.19d3f8","name":"On/Off","property":"payload","propertyType":"msg","rules":[{"t":"cont","v":"on","vt":"str"},{"t":"cont","v":"off","vt":"str"}],"checkall":"false","repair":false,"outputs":2,"x":330,"y":608,"wires":[["8ae45f67.0b0278"],["83331097.6a4d98"]]},{"id":"f0087f7a.b18908","type":"function","z":"e1990edd.19d3f8","name":"","func":"var newTemp;\n\nnewTemp = msg.data.event.new_state.attributes.temperature + 1.0;\n\nmsg.payload = {\n domain: 'climate',\n service: 'set_temperature',\n data: {\n temperature: newTemp\n }\n}\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":400,"y":860,"wires":[["16d9f61.9f28c8a"]]},{"id":"18617dd5.0f436a","type":"api-call-service","z":"e1990edd.19d3f8","name":"Reset simulate_bedtime","server":"3f1b73d1.299cbc","version":3,"debugenabled":false,"service_domain":"input_boolean","service":"turn_off","entityId":"input_boolean.simulate_bedtime","data":"","dataType":"jsonata","mergecontext":"","mustacheAltTags":false,"x":360,"y":500,"wires":[[]]},{"id":"ecd70450ccacd0ab","type":"comment","z":"e1990edd.19d3f8","name":"Adjust the room TRVs","info":"","x":130,"y":760,"wires":[]},{"id":"615c6742e66aee2b","type":"comment","z":"e1990edd.19d3f8","name":"Overview","info":"# Entities\n- Each room has at least one radiator with a Danfoss TRV. Unfortunately, you cannot read the actual room temperature from the TRV, so\n- Each room also has a temperature sensor\n- Each room has a generic thermostat in HA which controls the state of:\n- an input_boolean if the room needs heat\n- Some rooms have up/down buttons in HA to increment/decrement the target temp\n\n# Control loops\n- Schedy is running in an Appdaemon addon to provide top level control of room set-points.\n- A couple of rooms have a Node-Red flow that is triggered by the up/down buttons and adjust the room's 'thermostat'\n- Each room then has a node-red flow to ensure the room's TRV mirrors the thermostat's set-point (with the option of adding an offset based on how closely the TRV's set-point matches that of the thermostat)\n- An automation monitors the state of each room's \"I need heat\" input_boolean to decide if the House needs heat. (this allows the flexibility to add additional \"rooms\" or other reasons to switch the heating on)\n- The last node-red flow then uses the state of the \"we need heat\" inut_boolean to control the boiler","x":80,"y":20,"wires":[]},{"id":"3f1b73d1.299cbc","type":"server","name":"Home Assistant","legacy":false,"addon":true,"rejectUnauthorizedCerts":true,"ha_boolean":"y|yes|true|on|home|open","connectionDelay":true,"cacheJson":true}]