HVAC Fan Circulation

Never found a good app that worked properly for what I needed. So I made one and have it on my GitHub for anyone looking. If anything turns on the HVAC fan the delay timer stops and then restarts after the fan is off again. That way when the furnace/ac runs or if another app or you turn on the fan from the thermostat this app won’t try to turn on/off the fan.

How do I get to your github I’m pretty new to this and I’m looking for a circulate fan app.

Go to GitHub.com and do an advance search under user for mebaddog2002. Give me a day to make sure everything is updated. Looks like it’s not.

Okay everything cleaned up on github.

Hi Eric,

Here’s one too:

https://raw.githubusercontent.com/jsconstantelos/SmartThings/master/smartapps/jsconstantelos/simple-thermostat-fan-cycler.src/simple-thermostat-fan-cycler.groovy

It’s pretty simple, just tell it how many minutes you want the fan to run and how many minutes to stay off, and what mode you want it to run.

I’m using 2 instances of the app, one instance for Home mode and one instance for Away mode. You just need to install the app in the IDE once, but you can add as many instances of this smartapp as you want via the mobile app, just give each one a unique name.

How new are you to ST? Do you know how to create your own custom smartapps in the IDE?

In case you’ve not done that before, here’s a little how-to:
http://thingsthataresmart.wiki/index.php?title=Using_Custom_Code

If you’d like more help, just reply back!

1 Like

Thanks John. I got this to work, but ran into an issue this morning. The fan was cycling normally, until 5am this morning and it “stuck” with fan on. Any thoughts?

Did you location change Modes at that time, like from Night to Home? That’s one thing I can think of.

Live logging the smartapp in the IDE will show messages during all that activity, but you’d have to up at 5am watching it, or leave your PC on and logged into the the IDE with Live Logging up. You’ll be able to find the smartapp in the list of activities and single out those events.

Here’s everything from the events going from the previous Auto to the On and then nothing [2020-03-2020-03-23 6:48:32.269 AM CDT
3 hours ago DEVICE level 38 Media Dimmer level is 38
2020-03-23 6:48:31.043 AM CDT
3 hours ago DEVICE switch on Media Dimmer switch is on
2020-03-23 6:48:31.042 AM CDT
3 hours ago DEVICE level 11 Media Dimmer level is 11
2020-03-23 6:07:44.209 AM CDT
3 hours ago DEVICE switch off Samsung 6 Series (55) was off
2020-03-23 5:41:04.937 AM CDT
4 hours ago DEVICE thermostatOperatingState fan only Upstairs Thermostat thermostat operating state is fan only
2020-03-23 5:40:36.047 AM CDT
4 hours ago DEVICE thermostatFanMode on Upstairs Thermostat thermostat fan mode is on
2020-03-23 5:40:32.113 AM CDT
4 hours ago DEVICE thermostatOperatingState fan only Downstairs Thermostat thermostat operating state is fan only
2020-03-23 5:40:32.033 AM CDT
4 hours ago DEVICE thermostatFanMode on Downstairs Thermostat thermostat fan mode is on
2020-03-23 5:40:30.545 AM CDT
4 hours ago APP_COMMAND fanOn Fan Recirculation sent fanOn command to Upstairs Thermostat
2020-03-23 5:40:29.799 AM CDT
4 hours ago APP_COMMAND fanOn Fan Recirculation sent fanOn command to Downstairs Thermostat
2020-03-23 5:31:04.682 AM CDT
4 hours ago DEVICE thermostatOperatingState idle Upstairs Thermostat thermostat operating state is idle
2020-03-23 5:31:04.205 AM CDT
4 hours ago DEVICE thermostatOperatingState idle Downstairs Thermostat thermostat operating state is idle
2020-03-23 5:30:39.545 AM CDT
4 hours ago DEVICE thermostatFanMode auto Upstairs Thermostat thermostat fan mode is auto
2020-03-23 5:30:36.738 AM CDT
4 hours ago DEVICE thermostatFanMode auto Downstairs Thermostat thermostat fan mode is auto
2020-03-23 5:30:35.641 AM CDT
4 hours ago APP_COMMAND fanAuto Fan Recirculation sent fanAuto command to Upstairs Thermostat
2020-03-23 5:30:29.546 AM CDT
4 hours ago APP_COMMAND fanAuto Fan Recirculation sent fanAuto command to Downstairs Ther

It did it again. I was running the live log at the time and I can see that it pushed the Setting Off Timer at 11:43:28 AM then the fan came on around 11:53 without seeing the push, but has not turned off 20 minutes later. ( I currently have the timer set for 5 minutes run time.

98fc86a9-ca7b-4691-8d49-e54211f0b3b5 11:46:29 AM: debug Description read attr - raw: 0BA70100010E3E001B00000000, dni: 0BA7, endpoint: 01, cluster: 0001, size: 14, attrId: 003e, result: success, encoding: 1b, value: 00000000 parsed to [[name:powerSource, value:mains, descriptionText:Upstairs Thermostat is connected to mains, linkText:Upstairs Thermostat, isStateChange:false, displayed:false]]
98fc86a9-ca7b-4691-8d49-e54211f0b3b5 11:46:29 AM: debug Desc Map: [raw:0BA70100010E3E001B00000000, dni:0BA7, endpoint:01, cluster:0001, size:14, attrId:003e, result:success, encoding:1b, value:00000000, isValidForDataType:true, clusterInt:1, attrInt:62]
98fc86a9-ca7b-4691-8d49-e54211f0b3b5 11:46:21 AM: debug Description read attr - raw: 0BA70102010A1200293F08, dni: 0BA7, endpoint: 01, cluster: 0201, size: 10, attrId: 0012, result: success, encoding: 29, value: 083f parsed to [[name:heatingSetpoint, value:70, unit:F, linkText:Upstairs Thermostat, descriptionText:Upstairs Thermostat heating setpoint is 70°F, isStateChange:false, displayed:false]]
98fc86a9-ca7b-4691-8d49-e54211f0b3b5 11:46:21 AM: debug HEATING SETPOINT
98fc86a9-ca7b-4691-8d49-e54211f0b3b5 11:46:21 AM: debug Desc Map: [raw:0BA70102010A1200293F08, dni:0BA7, endpoint:01, cluster:0201, size:10, attrId:0012, result:success, encoding:29, value:083f, isValidForDataType:true, clusterInt:513, attrInt:18]
861e281c-ec2b-414d-a758-d1f5ba544636 11:44:04 AM: debug Description read attr - raw: ADD90102010A2900190000, dni: ADD9, endpoint: 01, cluster: 0201, size: 10, attrId: 0029, result: success, encoding: 19, value: 0000 parsed to [[name:thermostatOperatingState, value:idle, linkText:Downstairs Thermostat, descriptionText:Downstairs Thermostat thermostat operating state is idle, isStateChange:true, displayed:true]]
861e281c-ec2b-414d-a758-d1f5ba544636 11:44:04 AM: debug RUNNING STATE
861e281c-ec2b-414d-a758-d1f5ba544636 11:44:04 AM: debug Desc Map: [raw:ADD90102010A2900190000, dni:ADD9, endpoint:01, cluster:0201, size:10, attrId:0029, result:success, encoding:19, value:0000, isValidForDataType:true, clusterInt:513, attrInt:41]
861e281c-ec2b-414d-a758-d1f5ba544636 11:44:00 AM: debug Description read attr - raw: ADD90100010E3E001B00000000, dni: ADD9, endpoint: 01, cluster: 0001, size: 14, attrId: 003e, result: success, encoding: 1b, value: 00000000 parsed to [[name:powerSource, value:mains, descriptionText:Downstairs Thermostat is connected to mains, linkText:Downstairs Thermostat, isStateChange:false, displayed:false]]
861e281c-ec2b-414d-a758-d1f5ba544636 11:44:00 AM: debug Desc Map: [raw:ADD90100010E3E001B00000000, dni:ADD9, endpoint:01, cluster:0001, size:14, attrId:003e, result:success, encoding:1b, value:00000000, isValidForDataType:true, clusterInt:1, attrInt:62]
98fc86a9-ca7b-4691-8d49-e54211f0b3b5 11:43:33 AM: debug Description read attr - raw: 0BA70102010A2900190000, dni: 0BA7, endpoint: 01, cluster: 0201, size: 10, attrId: 0029, result: success, encoding: 19, value: 0000 parsed to [[name:thermostatOperatingState, value:idle, linkText:Upstairs Thermostat, descriptionText:Upstairs Thermostat thermostat operating state is idle, isStateChange:true, displayed:true]]
98fc86a9-ca7b-4691-8d49-e54211f0b3b5 11:43:33 AM: debug RUNNING STATE
98fc86a9-ca7b-4691-8d49-e54211f0b3b5 11:43:33 AM: debug Desc Map: [raw:0BA70102010A2900190000, dni:0BA7, endpoint:01, cluster:0201, size:10, attrId:0029, result:success, encoding:19, value:0000, isValidForDataType:true, clusterInt:513, attrInt:41]
861e281c-ec2b-414d-a758-d1f5ba544636 11:43:33 AM: debug Description read attr - raw: ADD90102020A0000003005, dni: ADD9, endpoint: 01, cluster: 0202, size: 10, attrId: 0000, result: success, encoding: 30, value: 05 parsed to [[name:thermostatFanMode, value:auto, data:[supportedThermostatFanModes:[on, auto]], linkText:Downstairs Thermostat, descriptionText:Downstairs Thermostat thermostat fan mode is auto, isStateChange:false, displayed:false]]
861e281c-ec2b-414d-a758-d1f5ba544636 11:43:33 AM: debug FAN MODE
861e281c-ec2b-414d-a758-d1f5ba544636 11:43:33 AM: debug Desc Map: [raw:ADD90102020A0000003005, dni:ADD9, endpoint:01, cluster:0202, size:10, attrId:0000, result:success, encoding:30, value:05, isValidForDataType:true, clusterInt:514, attrInt:0]
861e281c-ec2b-414d-a758-d1f5ba544636 11:43:33 AM: debug Description read attr - raw: ADD90102020800003005, dni: ADD9, endpoint: 01, cluster: 0202, size: 8, attrId: 0000, result: success, encoding: 30, value: 05 parsed to [[name:thermostatFanMode, value:auto, data:[supportedThermostatFanModes:[on, auto]], linkText:Downstairs Thermostat, descriptionText:Downstairs Thermostat thermostat fan mode is auto, isStateChange:true, displayed:true]]
861e281c-ec2b-414d-a758-d1f5ba544636 11:43:33 AM: debug FAN MODE
861e281c-ec2b-414d-a758-d1f5ba544636 11:43:33 AM: debug Desc Map: [raw:ADD90102020800003005, dni:ADD9, endpoint:01, cluster:0202, size:8, attrId:0000, result:success, encoding:30, value:05, isValidForDataType:true, clusterInt:514, attrInt:0]
861e281c-ec2b-414d-a758-d1f5ba544636 11:43:32 AM: debug Description catchall: 0104 0202 01 01 0000 00 ADD9 00 00 0000 04 01 00 parsed to
861e281c-ec2b-414d-a758-d1f5ba544636 11:43:32 AM: debug Desc Map: [raw:0104 0202 01 01 0000 00 ADD9 00 00 0000 04 01 00, profileId:0104, clusterId:0202, sourceEndpoint:01, destinationEndpoint:01, options:0000, messageType:00, dni:ADD9, isClusterSpecific:false, isManufacturerSpecific:false, manufacturerId:0000, command:04, direction:01, data:[00], clusterInt:514, commandInt:4]
98fc86a9-ca7b-4691-8d49-e54211f0b3b5 11:43:30 AM: debug Description read attr - raw: 0BA70102020A0000003005, dni: 0BA7, endpoint: 01, cluster: 0202, size: 10, attrId: 0000, result: success, encoding: 30, value: 05 parsed to [[name:thermostatFanMode, value:auto, data:[supportedThermostatFanModes:[on, auto]], linkText:Upstairs Thermostat, descriptionText:Upstairs Thermostat thermostat fan mode is auto, isStateChange:false, displayed:false]]
98fc86a9-ca7b-4691-8d49-e54211f0b3b5 11:43:30 AM: debug FAN MODE
98fc86a9-ca7b-4691-8d49-e54211f0b3b5 11:43:30 AM: debug Desc Map: [raw:0BA70102020A0000003005, dni:0BA7, endpoint:01, cluster:0202, size:10, attrId:0000, result:success, encoding:30, value:05, isValidForDataType:true, clusterInt:514, attrInt:0]
98fc86a9-ca7b-4691-8d49-e54211f0b3b5 11:43:29 AM: debug Description read attr - raw: 0BA70102020800003005, dni: 0BA7, endpoint: 01, cluster: 0202, size: 8, attrId: 0000, result: success, encoding: 30, value: 05 parsed to [[name:thermostatFanMode, value:auto, data:[supportedThermostatFanModes:[on, auto]], linkText:Upstairs Thermostat, descriptionText:Upstairs Thermostat thermostat fan mode is auto, isStateChange:true, displayed:true]]
98fc86a9-ca7b-4691-8d49-e54211f0b3b5 11:43:29 AM: debug FAN MODE
98fc86a9-ca7b-4691-8d49-e54211f0b3b5 11:43:29 AM: debug Desc Map: [raw:0BA70102020800003005, dni:0BA7, endpoint:01, cluster:0202, size:8, attrId:0000, result:success, encoding:30, value:05, isValidForDataType:true, clusterInt:514, attrInt:0]
98fc86a9-ca7b-4691-8d49-e54211f0b3b5 11:43:29 AM: debug Description catchall: 0104 0202 01 01 0000 00 0BA7 00 00 0000 04 01 00 parsed to
98fc86a9-ca7b-4691-8d49-e54211f0b3b5 11:43:29 AM: debug Desc Map: [raw:0104 0202 01 01 0000 00 0BA7 00 00 0000 04 01 00, profileId:0104, clusterId:0202, sourceEndpoint:01, destinationEndpoint:01, options:0000, messageType:00, dni:0BA7, isClusterSpecific:false, isManufacturerSpecific:false, manufacturerId:0000, command:04, direction:01, data:[00], clusterInt:514, commandInt:4]
5af95821-d5bb-440d-a516-d611ad2cccb7 11:43:28 AM: debug Setting OFF timer…
98fc86a9-ca7b-4691-8d49-e54211f0b3b5 11:42:04 AM: debug Description read attr - raw: 0BA7010201101C0030031E003003, dni: 0BA7, endpoint: 01, cluster: 0201, size: 16, attrId: 001c, result: success, encoding: 30, value: 0330001e03 parsed to [[name:thermostatMode, value:cool, data:[supportedThermostatModes:[off, cool, heat]], linkText:Upstairs Thermostat, descriptionText:Upstairs Thermostat thermostat mode is cool, isStateChange:false, displayed:false], [name:thermostatMode, value:cool, data:[supportedThermostatModes:[off, cool, heat]], linkText:Upstairs Thermostat, descriptionText:Upstairs Thermostat thermostat mode is cool, isStateChange:false, displayed:false]]
98fc86a9-ca7b-4691-8d49-e54211f0b3b5 11:42:04 AM: debug MODE
98fc86a9-ca7b-4691-8d49-e54211f0b3b5 11:42:04 AM: debug MODE
98fc86a9-ca7b-4691-8d49-e54211f0b3b5 11:42:04 AM: debug Desc Map: [raw:0BA7010201101C0030031E003003, dni:0BA7, endpoint:01, cluster:0201, size:16, attrId:001c, result:success, encoding:30, value:03, additionalAttrs:[[attrId:001e, attrInt:30, encoding:30, value:03, isValidForDataType:true, consumedBytes:8]], isValidForDataType:true, clusterInt:513, attrInt:28]
861e281c-ec2b-414d-a758-d1f5ba544636 11:41:46 AM: debug Description read attr - raw: ADD9010201101C0030031E003003, dni: ADD9, endpoint: 01, cluster: 0201, size: 16, attrId: 001c, result: success, encoding: 30, value: 0330001e03 parsed to [[name:thermostatMode, value:cool, data:[supportedThermostatModes:[off, cool, heat]], linkText:Downstairs Thermostat, descriptionText:Downstairs Thermostat thermostat mode is cool, isStateChange:false, displayed:false], [name:thermostatMode, value:cool, data:[supportedThermostatModes:[off, cool, heat]], linkText:Downstairs Thermostat, descriptionText:Downstairs Thermostat thermostat mode is cool, isStateChange:false, displayed:false]]
861e281c-ec2b-414d-a758-d1f5ba544636 11:41:46 AM: debug MODE
861e281c-ec2b-414d-a758-d1f5ba544636 11:41:46 AM: debug MODE
861e281c-ec2b-414d-a758-d1f5ba544636 11:41:46 AM: debug Desc Map: [raw:ADD9010201101C0030031E003003, dni:ADD9, endpoint:01, cluster:0201, size:16, attrId:001c, result:success, encoding:30, value:03, additionalAttrs:[[attrId:001e, attrInt:30, encoding:30, value:03, isValidForDataType:true, consumedBytes:8]], isValidForDataType:true, clusterInt:513, attrInt:28]
861e281c-ec2b-414d-a758-d1f5ba544636 11:41:34 AM: debug Description read attr - raw: ADD901020124100028001200293F08230030002400210000, dni: ADD9, endpoint: 01, cluster: 0201, size: 36, attrId: 0010, result: success, encoding: 28, value: 000021002400300023083f29001200 parsed to [[name:heatingSetpoint, value:70, unit:F, linkText:Downstairs Thermostat, descriptionText:Downstairs Thermostat heating setpoint is 70°F, isStateChange:false, displayed:false]]
861e281c-ec2b-414d-a758-d1f5ba544636 11:41:34 AM: debug HEATING SETPOINT
861e281c-ec2b-414d-a758-d1f5ba544636 11:41:34 AM: debug Desc Map: [raw:ADD901020124100028001200293F08230030002400210000, dni:ADD9, endpoint:01, cluster:0201, size:36, attrId:0010, result:success, encoding:28, value:00, additionalAttrs:[[attrId:0012, attrInt:18, encoding:29, value:083f, isValidForDataType:true, consumedBytes:10], [attrId:0023, attrInt:35, encoding:30, value:00, isValidForDataType:true, consumedBytes:8], [attrId:0024, attrInt:36, encoding:21, value:0000, isValidForDataType:true, consumedBytes:10]], isValidForDataType:true, clusterInt:513, attrInt:16]
861e281c-ec2b-414d-a758-d1f5ba544636 11:39:04 AM: debug Description read attr - raw: ADD90102010A2900190400, dni: ADD9, endpoint: 01, cluster: 0201, size: 10, attrId: 0029, result: success, encoding: 19, value: 0004 parsed to [[name:thermostatOperatingState, value:fan only, linkText:Downstairs Thermostat, descriptionText:Downstairs Thermostat thermostat operating state is fan only, isStateChange:true, displayed:true]]
861e281c-ec2b-414d-a758-d1f5ba544636 11:39:04 AM: debug RUNNING STATE
861e281c-ec2b-414d-a758-d1f5ba544636 11:39:04 AM: debug Desc Map: [raw:ADD90102010A2900190400, dni:ADD9, endpoint:01, cluster:0201, size:10, attrId:0029, result:success, encoding:19, value:0004, isValidForDataType:true, clusterInt:513, attrInt:41]
98fc86a9-ca7b-4691-8d49-e54211f0b3b5 11:39:04 AM: debug Description read attr - raw: 0BA70102010A2900190400, dni: 0BA7, endpoint: 01, cluster: 0201, size: 10, attrId: 0029, result: success, encoding: 19, value: 0004 parsed to [[name:thermostatOperatingState, value:fan only, linkText:Upstairs Thermostat, descriptionText:Upstairs Thermostat thermostat operating state is fan only, isStateChange:true, displayed:true]]
98fc86a9-ca7b-4691-8d49-e54211f0b3b5 11:39:04 AM: debug RUNNING STATE
98fc86a9-ca7b-4691-8d49-e54211f0b3b5 11:39:04 AM: debug Desc Map: [raw:0BA70102010A2900190400, dni:0BA7, endpoint:01, cluster:0201, size:10, attrId:0029, result:success, encoding:19, value:0004, isValidForDataType:true, clusterInt:513, attrInt:41]
98fc86a9-ca7b-4691-8d49-e54211f0b3b5 11:38:37 AM: debug Description read attr - raw: 0BA70102020A0000003004, dni: 0BA7, endpoint: 01, cluster: 0202, size: 10, attrId: 0000, result: success, encoding: 30, value: 04 parsed to [[name:thermostatFanMode, value:on, data:[supportedThermostatFanModes:[on, auto]], linkText:Upstairs Thermostat, descriptionText:Upstairs Thermostat thermostat fan mode is on, isStateChange:false, displayed:false]]
98fc86a9-ca7b-4691-8d49-e54211f0b3b5 11:38:37 AM: debug FAN MODE

Cool, live logging is what I really wanted to see. Is there any way you can do that again and just click on the SmartApp name in the list of devices and apps live logging events? That way we only see events related to the app vs everything going on. Here’s an example of mine:

Here’s another new schedule:

In the IDE, you can see when the next schedule is set: (via Locations -> Installed SmartApps)

Also, what Zigbee thermostat are you using and who’s device handler are you using? It’s dumping a lot of debug messages.

It’s a Lux Konoz thermostat, and I’m using whatever the default is I’m sure.

Cool, thanks for letting me know. I’ll look at the dth code to make sure there’s nothing odd with the code.

Looks like ST default handler should work just fine, which is almost exactly the same code I’m using for my thermostat. Nice thermostat btw, where did you get it? I can’t seem to find it available for purchase anywhere.

Anyway, I’m definitely not seeing an issue like you had, so the only 2 things I can think of would be that your location had a mode change or ST had a problem, which wouldn’t surprise me. If fact, I have an Automation saying I have power running on a device longer than 30 minutes, but I can physically see that it’s off and that it’s using 0 watts in the mobile app and IDE. So yeah, it could be something funky on ST’s back end.

I’ll keep an eye on my apps over the next day to see if I experience anything like you.

I work for the manufacturer so I got it through the company store. I’m sharing feedback to the product team. I think I’m seeing a trend. If it cycles on AND off while the system is actively cooling or heating, it does not queue the next command. ie off timer (10 minutes) started at 2:38. System started cooling at 2:40. No command was sent at 2:48 because system was running. On time would be 5 minutes. No command was sent at 2:53 because system still running. No additional commands added until i pushed update through ST

The problem you are seeing is one reason why I wrote this program. It shouldn’t be doing that. It sometimes bugs out on me and leaves the fan ON but that has always been because of bad internet connection and only rarely does it. I have satellite internet. Maybe once a month if that. But sense this virus thing and the internet being overloaded it has done it a few times. Does your thermostat connect directly to ST or through a third party? If a third party the commands could be to fast for it to see it. As soon as cooling or heating starts it sends the command to turn the fan to AUTO and cancels the ON timer. Once heating or cooling stops then the delay timer starts again. That way if your heat or cooling is cycling faster then the delay timer then fan will never be turned to ON.

Oh just thought of something. Still haven’t made this app to were you can use it for a specific MODE (not very good at groovy and couldn’t figure out how to cancel it and turn the fan OFF if the mode changed). So if your trying to run it for only a specific MODE then that maybe why it keeps leaving it ON.

But I’m betting ST is bugging. My garage keeps opening because it thinks my car keeps leaving and coming home for the last few days. And I have a 30 min delay that it has to be gone before opening the door so this won’t happen.

This is all great info. Thanks so much.

I made a simple program that does nothing except cycle fan between on and auto. No Mode considerations etc. I’m running it now to see if it will work. What I don’t understand is even if the stat doesn’t receive the command, why would’t ST schedule the next command?

They probably do depending on your program. I don’t know. But with my program it wouldn’t try to turn to AUTO again. I have a whole house humidifier and dehumidifier that also controls the fan. So if the circ program sees the fan ON and it didn’t turn it ON it thinks something else turned it ON so it will not turn it to AUTO. Also this helps for in spring and fall for when you want to manually turn the fan ON just to circ for a few hours.