Nest Thermostat Rule Change Between Heat & Cool

Has anyone written a rule to switch between Heat and Cool on the Nest thermostat? I have been trying to get the Heat-Cool (auto) mode to work, but it allows way too much temperature swing. First, the built in minimum tolerance is 3 degrees. You can set the low temp (for heat) to 68 and high temp (for A/C) to 71. The problem is that the A/C won’t cut on unless the ambient temperature gets to 73 and the Heat won’t cut on unless the ambient temperature gets to 66… That is a 7 degree range of nothing happening…

I will be starting to write my first rule to do this but with smaller tolerances via a rule in openHAB, but figured I’d check if someone else had done something similar already.

This is what I use and it works pretty well. Keeps the temperature between ±1.0 then shuts off when within 0.5. I set up a target temperature variable that I set via the UI. I also set up some timers so the HVAC runs a little longer once the temperature is reached. Let me know if you have any questions. I was never able to to get the Auto to work correctly.

rule "Temperature Control"
when
Time cron “0 0/2 * 1/1 * ? *” or
Item HVAC_AUTO changed or
Item TargetTemperature changed
then
target = TargetTemperature.state as DecimalType
indoortemp = IndoorTemps.state as DecimalType

if(HVAC_AUTO.state == ON){
	if(indoortemp > (target + 1.0)){CoolSetpoint = 65}
	if(indoortemp < (target - 1.0)){HeatSetpoint = 72}
	if(NestTStat_hvac_mode.state.toString == "cool" && indoortemp < (target + 1.0)){hvacruntimer = 5}
	if(NestTStat_hvac_mode.state.toString == "heat" && indoortemp > (target - 1.0)){hvacruntimer = 2}

if((indoortemp >= (target - 0.5)) && (indoortemp <= (target + 0.5))){
		if (NestTStat_hvac_mode.state.toString != "eco"){postUpdate(HVACString, "Turning Off HVAC System")}
		hvactimeroff = createTimer(now.plusMinutes(hvacruntimer))[|
			if (NestTStat_hvac_mode.state.toString != "eco"){
				NestTStat_hvac_mode.sendCommand("eco")}
		postUpdate(HVACString, "HVAC System task is complete")]
		if(hvactimeroff != null){
			if(hvactimer != null){hvactimer.cancel}
			hvactimer = null}}
if((indoortemp < (target - 1.0)) || (indoortemp > (target + 1.0))){
		if (NestTStat_hvac_mode.state.toString == "eco"){postUpdate(HVACString, "Starting HVAC System")}
		hvactimer = createTimer(now.plusMinutes(5))[|
			if (NestTStat_hvac_mode.state.toString != "cool" && indoortemp > (target + 1.0)){
				NestTStat_hvac_mode.sendCommand("cool")}
			if (NestTStat_hvac_mode.state.toString != "heat" && indoortemp < (target - 1.0)){
				NestTStat_hvac_mode.sendCommand("heat")}
			Thread::sleep(5000)
					if (NestTStat_target_temperature_f.state != CoolSetpoint && indoortemp > (target + 1.0)){
						NestTStat_target_temperature_f.sendCommand(CoolSetpoint)}
					if (NestTStat_target_temperature_f.state != HeatSetpoint && indoortemp < (target - 1.0)){
						NestTStat_target_temperature_f.sendCommand(HeatSetpoint)}
						HVACString.postUpdate("HVAC System is running")]
				if(hvactimer != null){
					if(hvactimeroff != null){hvactimeroff.cancel}
					hvactimeroff = null}	
	}
}

if(HVAC_AUTO.state == OFF){
	if (NestTStat_hvac_mode.state.toString != "eco"){NestTStat_hvac_mode.sendCommand("eco")}
	if(hvactimeroff != null){hvactimeroff.cancel}
	postUpdate(HVACString, "Automatic HVAC mode is off.")
	hvacmode = 0
	hvactimeroff = null
	if(hvactimer != null){hvactimer.cancel}
	hvactimer = null}

end