Short Cycle - temps close

I have a whole house fan that takes a look at temperature and if the inside temp is warmer than outside the whole house fan turns on. Its quite a bit more complex than that - I'll share my code, but when the outside temp and inside temp is close the fan turns on and off rapidly, when there is a bigger swing it runs as it should. I'm trying to find a way to prevent the rapid on/off and looking for guidance. Here's my code:

context.data = context.data || {};
switch (msg.topic) {
    case "stat": 
        context.data.stat = msg.payload;
        break;
    case "outside": 
        context.data.outside = msg.payload;
        break;
    case "inside": 
        context.data.inside = msg.payload;
        break;
    case "comfort": 
        context.data.comfort = msg.payload;
        break;
    case "low": 
        context.data.low = msg.payload;
        break;        
    case "mintocomfort": 
        context.data.mintocomfort = msg.payload;
        break;
}
var stat = context.data.stat;
var outside = context.data.outside;
var inside = context.data.inside;
var comfort = context.data.comfort;
var low = context.data.low;
var mintocomfort = context.data.mintocomfort;
var fanspeed = fanspeed;
var stage = stage;
var msg1 = {};
var msg2 = {};
var msg3 = {};
msg1.topic = 'fan';
msg2.topic = 'mintocomfort';
msg3.topic = 'temp';
if (stat == 'on')
{
    if (inside - 1 >= outside)
    {
        if (inside >= low)
        {
            if (inside >= comfort)
            {
                if (inside >= comfort)
                {
                    mintocomfort = 1;
                }
                if (outside <= inside-8)
                {
                    if (comfort + 3 > inside)
                    {
                        fanspeed = 'min';
                        stage = '1 min';
                    }
                    else
                    {
                        fanspeed = 'max';
                        stage = '2 max';
                    }
                }
                else if ((outside > inside-8) && (outside <= inside-5))
                {
                    if (comfort + 3 > inside)
                    {
                        fanspeed = 'min';
                        stage = '3 min';
                    }
                    else
                    {
                        fanspeed = 'midmax';
                        stage = '4 midmax';
                    }
                }
                else if ((outside > inside-5) && (outside <= inside-3))
                {
                    if (comfort > inside)
                    {
                        fanspeed = 'min';
                        stage = '5 min';
                    }
                    else
                    {
                        fanspeed = 'mid';
                        stage = '6 mid';
                    }
                }
                else if ((outside > inside-3) && (outside <= inside-1))
                {
                    fanspeed = 'midmin';
                    stage = '7 midmin';
                }
                else
                {
                    fanspeed = 'min';
                    stage = '17 midmin';
                }
            }
            else if (inside < comfort)
            {
                if (mintocomfort == 1)
                {
                    fanspeed = 'min';
                    stage = '8 min';
                }
                else 
                {
                    fanspeed = 'off';
                    stage = '9 off';
                    mintocomfort = 0;
                }
            }
            else
            {
                fanspeed = 'off';
                stage = '19 off';
                mintocomfort = 0;
            }
        }
        else if (inside < low)
        {
            fanspeed = 'off';
            stage = '10 off';
            mintocomfort = 0;
        }
        else
        {
            fanspeed = 'off';
            stage = '100 off';
            mintocomfort = 0;
            }
    }
    else if (inside >= outside)
    {
        if (inside >= low)
        {
            if (inside >= comfort)
            {
                if (inside + 2 >= outside)
                {
                    mintocomfort = 1;
                }
                if (outside <= inside-8)
                {
                    if (comfort + 3 > inside)
                    {
                        fanspeed = 'min';
                        stage = '01 min';
                    }
                    else
                    {
                        fanspeed = 'max';
                        stage = '02 max';
                    }
                }
                else if ((outside > inside-8) && (outside <= inside-5))
                {
                    if (comfort + 3 > inside)
                    {
                        fanspeed = 'min';
                        stage = '03 min';
                    }
                    else
                    {
                        fanspeed = 'midmax';
                        stage = '04 midmax';
                    }
                }
                else if ((outside > inside-5) && (outside <= inside-3))
                {
                    if (comfort > inside)
                    {
                        fanspeed = 'min';
                        stage = '05 min';
                    }
                    else
                    {
                        fanspeed = 'mid';
                        stage = '06 mid';
                    }
                }
                else if ((outside > inside-3) && (outside <= inside-1))
                {
                    fanspeed = 'midmin';
                    stage = '07 midmin';
                }
                else
                {
                    fanspeed = 'min';
                    stage = '017 midmin';
                }
            }
            else if (inside < comfort)
            {
                if (mintocomfort == 1)
                {
                    fanspeed = 'min';
                    stage = '08 min';
                }
                else 
                {
                    fanspeed = 'off';
                    stage = '09 off';
                    mintocomfort = 0;
                }
            }
            else
            {
                fanspeed = 'off';
                stage = '019 off';
                mintocomfort = 0;
            }
        }
        else if (inside < low)
        {
            fanspeed = 'off';
            stage = '010 off';
            mintocomfort = 0;
        }
        else
        {
            fanspeed = 'off';
            stage = '0100 off';
            mintocomfort = 0;
            }
    }
//    else if (inside < outside)
    else if ((inside < outside) && (mintocomfort == 1))
    {
        fanspeed = 'off';
        stage = '011 off';
        mintocomfort = 0;
    }
    else
    {
        fanspeed = 'off';
        stage = '0111 off';
        mintocomfort = 0;
    }

}
//else if (stat == 'off')
else
{
    fanspeed = 'off';
    stage = '12 off';
    mintocomfort = 1;
}
msg1.payload = fanspeed;
msg2.payload = mintocomfort;
msg3.payload = stage;
node.status({fill:"green",shape:"dot",text:`Stage: ${stage}, Speed: ${msg1.payload}, Inside: ${inside}, Outside: ${outside}, Status: ${stat}, Stage: ${msg2.payload}`})
return [msg1, msg2, msg3];

YOu need to smooth out the hysteresis - the simplest method is to use the smooth node and average the readings over an appropriate period of time, you could also look at using trigger nodes and/or RBE to accomplish some dampening (so fan switches on because of temperature differential and will not switch off for x period of time/number of measurements)

If your fans are variable speed you could also look at the PID nodes (Colin has written an excellent one)

Craig

1 Like