Heating system improvements

Hi Chaps
Don’t know if this is something anyone here can help with but I’m looking to somehow aggregate the current weather conditions in my location i.e. wind speed, wind direction and external temperature. I then would like to combine this information in some kind of formula which would then result in a correction factor which I could apply to my house heating Node red flows.

The reason for this is that I’m trying to make my old central heating system a little more intelligent and efficient by taking into account external factors because at the moment, because of the positions of the temperature sensors in my home I’m regularly having to make manual adjustments to the set temperature to keep things comfortable but not excessive. I have already started the ball rolling by installing an additional sensor to the living room (in addition to the one in the hallway) and have them both controlling the heating. Now I know I could throw money at it by fitting smart TRV valves to every radiator but that is an expensive option and I don't want to be doing that at this time of year. So I thought I could improve the system for free by adding some data into the mix and making it respond in a more meaningful way.

Any thoughts?

If you want an efficient heating system, it all depends on the house. If it is draughty and poorly insulated it will not help to know the outside conditions. My advise is to insulate to the max and fix draughts, and only heat rooms that are in use, keep those rooms doors closed also.

Thank you for your suggestions regarding insulation E1cid. This has already been implemented i.e. the house has pretty good cavity wall insulation. The windows and doors are modern UPVC double glazed units and fit well in their frames (little to no draughts). The loft is also very well insulated.

I presume you already have a way to control the heating from Node-red?

You can certainly get estimated current weather conditions from various providers.
For example the Openweathermap node will return something like this:

"detail":"clear sky",
"location":"Port Elizabeth",
"description":"The weather in Port Elizabeth at coordinates: -33.918, 25.5701 is Clear (clear sky)."

I don't know how best to use msg.payload.tempc, msg.payload.windspeed etc to get a correction factor.
Rather than current weather, a forecast includes 3-hourly "feelslike" which presumably combines those factors in some way.


You could use the difference between temp and feels_like for the shortest term forecast to adjust your thermostat.

let insulationFactor = 10
thermostat += (msg.payload.temp - msg.payload.feels_like)/insulationFactor
1 Like

Hmm that looks interesting Mr Budd. I looks relatively straight forward to obtain the weather information using Openweathermap. Thanks for that info.

I did want the correction factor to include wind direction speed and temperature as this seems to affect the hallway temperature (and therefore the sensor) the most. This is because the hallway space is being affected by the weather more so than the other rooms in the house (probably because it's a large area with only one small radiator).

Using "winddirection" "temp" and "windspeed" from the Openweather node it should be possible to come up with a function. I know that if the wind is coming from the north and the wind is strongish, this has a big effect so I guess it will be a matter of taking northerly wind direction, say between <45° and greater than 315° (north east to north west), and wind speed say > 10mph and temperature < 8°C. Then some how write this into a function node. Unfortunately this is where I will struggle a bit, coding is a bit of a dark art for me I'm afraid.


I had a go at a function to calculate an adjustment factor based on wind.

It allows for any wind in the northern half of the compass, using the sin function to give increasing weight as the wind approaches North.

It's slightly less scientific and reliable than the back of an envelope...

function windfactor(bearing, speed) {
// Let's use the sin function to allow for how near to 360 the wind direction is. 
// sin wave is 0 at 0, max at 90, 0 at 180.
    let weighting = 0.01            // Arbitrary weighting to give wind
    bearing = (bearing + 90) % 360  // Add 90 degrees to map "northerly" directions (270 - 90) to (0 - 180) 
    let radians = bearing * Math.PI / 180;
    let sine = Math.sin(radians);
    if (sine < 0) { // ie wind East through South to West
        sine = 0
    return speed * sine * weighting

msg.payload.windFactor = windfactor(msg.payload.winddirection, msg.payload.windspeed)
return msg;

A test flow:

[{"id":"f3e02add17e4b873","type":"tab","label":"Flow 2","disabled":false,"info":"","env":[]},{"id":"27b992e4cc367d89","type":"function","z":"f3e02add17e4b873","name":"Simulated OWM data","func":"msg.payload = {\"id\": 800,\"weather\": \"Clear\",\"detail\": \"clear sky\",\"icon\": \"01d\",\"tempk\": 305.43,\"tempc\": 32.2,\"temp_maxc\": 32.2,\"temp_minc\": 32.2,\"humidity\": 43,\"pressure\": 1004,\"maxtemp\": 305.43,\"mintemp\": 305.43,\"windspeed\": 1.34,\"winddirection\": 342,\"location\": \"Port Elizabeth\",\"sunrise\": 1669172530,\"sunset\": 1669223179,\"clouds\": 5,\"description\": \"The weather in Port Elizabeth at coordinates: -33.918, 25.5701 is Clear (clear sky).\"}\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":280,"y":140,"wires":[["e01e7c442df56946"]]},{"id":"535799bb8f1cf187","type":"inject","z":"f3e02add17e4b873","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":100,"y":140,"wires":[["27b992e4cc367d89"]]},{"id":"16460505b7ec7dd0","type":"debug","z":"f3e02add17e4b873","name":"debug 63","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":740,"y":140,"wires":[]},{"id":"e01e7c442df56946","type":"function","z":"f3e02add17e4b873","name":"Calculate adjustment for wind","func":"function windfactor(bearing, speed) {\n// Let's use the sin function to allow for how near to 360 the wind direction is. \n// sin wave is 0 at 0, max at 90, 0 at 180.\n    let weighting = 0.01            // Arbitrary weighting to give wind\n    bearing = (bearing + 90) % 360  // Add 90 degrees to map \"northerly\" directions (270 - 90) to (0 - 180) \n    let radians = bearing * Math.PI / 180;\n    let sine = Math.sin(radians);\n    if (sine < 0) { // ie wind East through South to West\n        sine = 0\n    }\n    return speed * sine * weighting\n}\n\nmsg.payload.windFactor = windfactor(msg.payload.winddirection, msg.payload.windspeed)\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":530,"y":140,"wires":[["16460505b7ec7dd0"]]}]
1 Like

Wow Mr Budd, you really are very well versed in this area. I will play with that and see what happens.

Hi JBudd. Been having a look at your function and have been trying to figure it out (reverse engineer it if you will). Would you be able to modify it ever so slightly for a southerly wind direction i.e. heaviest weighting for south, decreasing when more easterly or westerly. Also could air temperature be included in the mix too as it does play a big part in the grand scheme of things.

Thank you for you assistance thus far, much appreciated.

Whatever direction I wanted to give most weight to, I would add a value to map that bearing to 90 (or 450). (Because sin(0) = 0, sin(90) = 1, sin(180) = 0.) For North it was 90, so South would be 270?)

bearing = (bearing + 270) % 360

NB I know that a North wind blows from North to South. I am not actually certain if it is reported as 0 degrees or as 180.

So the function above gives you an adjustment value for wind speed. You can have a similar function for temperature

function tempfactor(airtemp) {
    const highestrelevanttemp = 18 // Temperatures above this give negative adjustment factor
    const tempdiff = highestrelevanttemp - airtemp
    const weighting = 0.01         // How much weight do we give to temperature adjustment? 
    return tempdiff * weighting;

msg.payload.tempFactor = tempfactor(msg.payload.tempc)

To apply these adjustment factors, maybe just add each one to your thermostat setting?

thermostat = targetTemp + tempFactor + windFactor

I expect you will want to include some sanity checks so that hurricanes and ice storms don't set the thermostat ridiculously high.

jbudd, Just having a play with it now and it looks like it's gonna do what I needed. As for ice storms and hurricanes, not sure where you reside but the weather here in the UK is usually pretty placid.

Thanks once again for your speedy and expert response.


I found the details for this on t'internet ages ago so I don't know how accurate it is, also I wrote it when I was just starting with javascript so it could probably be polished up

Calculate Wind Chill Factor

const WCF01 = 13.12
const WCF02 = 0.6215
const WCF03 = 11.37
const WCF04 = 0.3965
const velocityPowerFactor = 0.16
const mpsTokph = 3.6
const velocityMultiplier = 1.5

let velocity = context.get('velocity') || undefined
let airTemperature = context.get('airTemperature') || undefined
let windChillFactor = airTemperature

// Note msg.device.measurement === 'temperature_C', msg.device.location === 'Outside' and msg.device.measurement === 'wind_avg_m_s' are the incoming message properties for MY device
// Edit for yours
if (msg.device.measurement === 'wind_avg_m_s') {
    velocity = msg.payload
    context.set('velocity', velocity)

} else if (msg.device.measurement === 'temperature_C' && msg.device.location === 'Outside') {
    airTemperature = msg.payload
    context.set('airTemperature', airTemperature)


if ((airTemperature != undefined && velocity != undefined) && ((msg.device.measurement === 'temperature_C' && msg.device.location === 'Outside') || msg.device.measurement === 'wind_avg_m_s')) {
    let windVelocity = velocity * velocityMultiplier * mpsTokph
    let v = windVelocity ** velocityPowerFactor

    windChillFactor = WCF01 + (WCF02 * airTemperature) - (WCF03 * v) + (WCF04 * airTemperature * v)

msg.topic = 'Wind Chill Factor'
msg.windChill = (airTemperature < 10 ? windChillFactor : airTemperature)
msg.airTemperature = airTemperature

return msg
1 Like

Wind Chill is not relevant if you are considering the effect of the wind on the interior of a building. It is a measure of the subjective effect of wind on a person.

Not sure about that Colin. I know for a fact that when it's windy my rooms feel colder. I suppose this is because the walls are not perfectly insulated so they "leak" heat to the outside. If the wind is blowing this will have an increased cooling affect so the heat is effectively "sucked out of the building ergo: wind chill.

I didn't mean that the wind is not significant, just that the Wind Chill Factor (Wind chill factor - Met Office) is not the correct formula. Certainly the higher the wind strength the more heat will be sucked out of the building. I think there are two factors, firstly a wind will increase draughts, and secondly it will cool the interior walls, which will make the room feel cooler than the actual air temperature would suggest. What formula one should use I don't know. I don't think the wind direction is relevant, just the strength (at the building) and the temperature of the air (the temperature of the air in the wind that is).

I seem to remember being taught that the wind chill factor is what it feels like if you stand outside naked.

Probably more relevant to a building is how quickly the air is exchanged, which may or may not vary with wind speed and direction.

Since @Surefire01's temperature sensor is in the hallway, I should think a massive influence is how often doors are opened and closed.

Yes Mr Budd I am mindful to keep doors closed as much as possible especially from the living room to the hallway. This is particularly important as I also have a temperature sensor in the living room which is also included in my heating control flow, but that's another story!

You might try searching the Forum for "heating." There have been a number of fairly in-depth discussions, including by members in the Midlands and North who are dealing with challenging sorts of home construction and variable local micro-climate.

[EDIT] Humidity is an important comfort factor you haven't considered.

"wind Chill" is effectively evaporative cooling. In order for there to be evaporative cooling there must be something to evaporate. Humans 'feel' wind chill because we have a lot of surface moisture on our skin, thus drafts will chill us more than static ambient temperature will. A room that cools when it's windy is mostly leaking air and thus thermal energy ⛮

I have to say that I think you’re approaching this from the wrong angle. Although you’ve marked the topic as solved, I suspect that all you’ve really solved is how to get the data you want, but not to actually make your house feel warmer.

Although external air temperature, wind speed and wind direction have a bearing on how cold it feels inside the house, the bottom line is that what matters is exactly that - how cold it feels inside the house.
I’f the house is draught-proofed and insulated as much as is practical, the only real thing you need to worry about is internal temperature (and possibly humidity).

If some parts of the house feel cold compared to others then TRVs are the only real way to address this, as they allow different temperature set-points for different zones of the house. Ultimately, a temperature sensor in each zone and TRV’s controlling the radiator(s) in that zone will be the only way to achieve the local control you seem to want.

Of course, the way things are going with energy prices we’ll all end-up wearing lots of layers and huddling around our Node-Red server for warmth


Without intending to sound ungrateful, the query I posed has been, for me, adequately addressed and with the kind responses from folks on this forum, I am happy with the suggested solutions. That is why I marked the posing as being solved. I have also increased my knowledge of how to manipulate data using a function node which is very welcomed. So from a purely “Node Red” point of view I am happy with the outcomes.

The bigger picture of whether my approach is correct, flawed or ill informed is probably a matter for a “home improvements” forum or at a stretch, a forum with subjects including “thermodynamics” centering on conduction, convection and radiation which are the principle ways in which solid objects (i.e. bricks and mortar) lose heat. So once again thank you for everyone’s input.

1 Like