Unifi binding 2.4.0

hi all

I’m new in the use of openhab, and I wanted to get a home/away status whenever a member off my household enters og goes away, and read about the unifi binding.
I’m not sure what to do, to get this working, and need some step guides how to set it up!
All I have done now is I have installed the unifi binding.
hope someone can help.

I found this:

and

and

To get you started
I just searched “unifi presence” in the forum
There are many more

1 Like

Hi Christian,

If you get stuck - I should be able to help you. I’m running OH 2.4 and I’m using the Unifi Binding 2.4 for exactly what your looking to do. Mine controls everything from Lights, Ecobee Temps, Playing Sonos and Alexa Announcements all tied to presence of cell phones coming and going.

Best, Jay

Dear Jay,

I just discover This thread recently… and wondering if you kindly share some details about how to get start with home/away?
I’m running OH 2.5 on a Rapi 4/8 and my UNIFI devices are managed by CLOUDKEY 2.
I just need some code to start :slight_smile:

Best regards

Joerg

Hey Joerg,

Here’s some code and logic around how I do things with the Unifi. I don’t use CloudKey at all, my Unifi controller is local along with my three Access Points.

Unifi phones/devices defined in Things:

Bridge unifi:controller:home "UniFi Home Controller" [ host="192.168.0.20", port=8443, username="ubnt", password="password", refresh=10 ] {
    Thing site default									"Home Default Site" 		[ sid="default" ]
	Thing wirelessClient TriciaiPhoneUnifi 				"Tricias iPhone XR"			[ cid="e4:b2:fb:d6:xx:xx", site="default", considerHome=180 ]
	Thing wirelessClient JayAndriodUnifi 				"Jays Note9"				[ cid="44:91:60:c1:xx:xx", site="default", considerHome=180 ]
 ]
}

Items tied to things and some virtual items and groups:

Switch	Home_Away						"Home Away OH [MAP(home_away.map):%s]"							(HomeState, Group_HabPanel_Dashboard)		[ "Switchable" ]

Group:Switch:OR(ON,OFF)	UnifiAdults	"Adults with Cell Phones Home [MAP(On_Off.map):%s]"			(Groups, Group_HabPanel_Dashboard)
Group:Switch:OR(ON,OFF)	UnifiPhones	"Family with Cell Phones Home [MAP(On_Off.map):%s]"			(Groups, Group_HabPanel_Dashboard)

Switch   TsiPhoneUnifi      		"Tricias iPhone: [MAP(unifi.map):%s]"           			(UnifiTricia, Unifi, UnifiAdults, UnifiPhones)					{ channel="unifi:wirelessClient:home:TriciaiPhoneUnifi:online" }
Switch   JsAndriodUnifi      		"Jays Andriod: [MAP(unifi.map):%s]"             			(Unifi, UnifiAdults, UnifiPhones, Group_HabPanel_Dashboard)		{ channel="unifi:wirelessClient:home:JayAndriodUnifi:online" }

Rules tied to groups, I do a lot of changes in the house when a cell phone triggers a group ON/OFF.

rule "Automation AWAY"
     when
    	Item UnifiPhones changed to OFF
     then

		if (systemStarted.state != ON && gInternet.state == ON && gPort25.state == ON && Home_Away.state == ON) {

			logInfo("Unifi", "-----------------------------------------------------------------------------")
			logInfo("Unifi", "UnifiPhones changed to OFF.")

			Echo_BackYard_Volume.sendCommand('0')
				Thread::sleep(1500) 
			Echo_BackYard_textToSpeechVolume.sendCommand('0')

			logInfo("ECHO", "-----------------------------------------------------------------------------")
			logInfo("ECHO" , 'Echo BackYard volume set to 0 because UnifiPhones are OFF.')
			logInfo("HVAC", "-----------------------------------------------------------------------------")
			logInfo("HVAC", "HVAC System Fans Turned OFF.")

			// Turn OFF HVAC FAN Main Floor
			MF_settings_fanMinOnTime.sendCommand(0)
				Thread::sleep(3000)
			MF_settings_fanMinOnTime.sendCommand(0)
				Thread::sleep(1500)

			// Turn OFF HVAC FAN Upstairs
			UpS_settings_fanMinOnTime.sendCommand(0)
				Thread::sleep(3000)
			UpS_settings_fanMinOnTime.sendCommand(0)

			logInfo("ecobee", "-----------------------------------------------------------------------------")
			logInfo("ecobee", "Ecobee Automation AWAY prior to executing with MF_runningEvent_climate is " + MF_runningEvent_climate.state + " and UpS_runningEvent_climate is " + UpS_runningEvent_climate.state)

			// If UnifiPhones state changed  - waiting 1 hr period before setting AWAY, timer will be canceled otherwise.
			if (systemStarted.state != ON && ecobeeAutoAway_tAlive === null) {
			
				logInfo("ecobee", "Ecobee Automation Away setting ecobeeAutoAway_tAlive with delay of 1 hours")
				logInfo("ecobee", "-----------------------------------------------------------------------------")
				logInfo("tAlive" , "ecobeeAutoAway_tAlive is null <--> CREATING Timer!")
				ecobeeAutoAway_tAlive = createTimer(now.plusHours(1), [ |

					logInfo("ecobee", "-----------------------------------------------------------------------------")
					logInfo("ecobee", "Setting both Thermostats schedule to AWAY mode after 1 hour wait.")

					if (MF_runningEvent_climate.state != "away") {
					
						logInfo("ecobee", "Ecobee " + MF_name.state + " being set to AWAY after 1 hour wait.")
						MF_runningEvent_climate.sendCommand("away")
							Thread::sleep(1500)
					}

					if (UpS_runningEvent_climate.state != "away") {
					
						logInfo("ecobee", "Ecobee " + UpS_name.state + " being set to AWAY after 1 hour wait.")
						UpS_runningEvent_climate.sendCommand("away")
							Thread::sleep(1500)
					}

					logInfo("ecobee", "Ecobee Automation AWAY has executed with MF_runningEvent_climate is " + MF_runningEvent_climate.state + " and UpS_runningEvent_climate is " + UpS_runningEvent_climate.state)
	
					Wallplug_xMas_Tree.sendCommand(OFF)
						Thread::sleep(200)  
					Wallplug_xMas_Tree.sendCommand(OFF)
						Thread::sleep(1500)  
				
					Switch_Hallway_Light.sendCommand(OFF)
						Thread::sleep(200)  
					Switch_Hallway_Light.sendCommand(OFF)
						Thread::sleep(1500)  
				
					Switch_LaundryRoom_Light.sendCommand(OFF)
						Thread::sleep(200)  
					Switch_LaundryRoom_Light.sendCommand(OFF)
						Thread::sleep(1500)  
		
					Wallplug_Jays_Office_Light.sendCommand(OFF)
						Thread::sleep(200)  
					Wallplug_Jays_Office_Light.sendCommand(OFF)
						Thread::sleep(1500)  
		
					Switch_Bathroom_Light.sendCommand(OFF)
						Thread::sleep(200)  
					Switch_Bathroom_Light.sendCommand(OFF)
						Thread::sleep(1500) 
		
					Wallplug_MyLamp.sendCommand(OFF)
						Thread::sleep(200)  
					Wallplug_MyLamp.sendCommand(OFF)
						Thread::sleep(1500)  
		
					Switch_MyOffice_Light.sendCommand(OFF)
						Thread::sleep(200)  
					Switch_MyOffice_Light.sendCommand(OFF)
						Thread::sleep(1500)  

					Wallplug_MyStringLights.sendCommand(OFF)
						Thread::sleep(200)  
					Wallplug_MyStringLights.sendCommand(OFF)
						Thread::sleep(1500) 

					Switch_BasementHallway_Light.sendCommand(OFF)
						Thread::sleep(200)  
					Switch_BasementHallway_Light.sendCommand(OFF)
						Thread::sleep(1500)  

					logInfo("WeMo", "-----------------------------------------------------------------------------")
					logInfo("WeMo", "Room Air Cleaners Turned OFF.")
					logInfo("WeMo", "-----------------------------------------------------------------------------")

					Wallplug_Guest_Air_Cleaner.sendCommand(OFF)
						Thread::sleep(200)  
					Wallplug_Guest_Air_Cleaner.sendCommand(OFF)
						Thread::sleep(1500)  

					Wallplug_Bedroom_Air_Cleaner.sendCommand(OFF)
						Thread::sleep(200)  
					Wallplug_Bedroom_Air_Cleaner.sendCommand(OFF)
						Thread::sleep(1500)  

					Wallplug_Loft_Air_Cleaner.sendCommand(OFF)
						Thread::sleep(200)  
					Wallplug_Loft_Air_Cleaner.sendCommand(OFF)
						Thread::sleep(1500)  

					Wallplug_Cubby_Light.sendCommand(OFF)
						Thread::sleep(1500)  
					Wallplug_Cubby_Light.sendCommand(OFF) 

					var SimpleDateFormat df = new SimpleDateFormat( "M/d/YY h:mm a" )
					var String timestamp 	= df.format( new Date() )
					
					var String subjectemailecobee 	= "openHAB - Ecobee"
					var String bodyemailecobee		= "openHAB - Both Thermostats automatically set to AWAY mode at " + timestamp + "\n"
					sendMail(JaygMail, subjectemailecobee, bodyemailecobee)

					ecobeeAutoAway_tAlive .cancel()
						Thread::sleep(1500)  
					ecobeeAutoAway_tAlive  = null
				])
			}
		}

		if (systemStarted.state != ON && HouseGuestHere.state == OFF && gInternet.state == ON && gPort25.state == ON && (Part1Zone1Fault.state == ON || Part1Zone2Fault.state == ON || Part1Zone2FaultCopy.state == ON )) {
		
			val String subjectemailDoorsAlarm	= "openHAB - Doors Left Open"	
			val String bodyemailDoorsAlarm 		= "openHAB - Doors Left Open with Nobody Home."
			sendMail(JaygMail, subjectemailDoorsAlarm, bodyemailDoorsAlarm)
				Thread::sleep(200) 
			var String subjectemailDoorsAlarm2	= "Doors"	
			var String bodyemailDoorsAlarm2		= "Doors Left Open with Nobody Home."
			sendMail(JaySMS, subjectemailDoorsAlarm2, bodyemailDoorsAlarm2)
				Thread::sleep(200)  
			sendMail(TriciaSMS, subjectemailDoorsAlarm2, bodyemailDoorsAlarm2) 			
		}

		if (systemStarted.state != ON && gInternet.state == ON) {
	
			Wallplug_xMas_Tree.sendCommand(OFF)
				Thread::sleep(200)  
			Wallplug_xMas_Tree.sendCommand(OFF)
				Thread::sleep(1500)  

			Happy_Holidays_Switch.postUpdate(OFF)		
		
			Switch_Hallway_Light.sendCommand(OFF)
				Thread::sleep(200)  
			Switch_Hallway_Light.sendCommand(OFF)
				Thread::sleep(1500)  
		
			Switch_LaundryRoom_Light.sendCommand(OFF)
				Thread::sleep(200)  
			Switch_LaundryRoom_Light.sendCommand(OFF)
				Thread::sleep(1500)  

			Wallplug_Jays_Office_Light.sendCommand(OFF)
				Thread::sleep(200)  
			Wallplug_Jays_Office_Light.sendCommand(OFF)
				Thread::sleep(1500)  

			Switch_Bathroom_Light.sendCommand(OFF)
				Thread::sleep(200)  
			Switch_Bathroom_Light.sendCommand(OFF)
				Thread::sleep(1500) 

			Wallplug_MyLamp.sendCommand(OFF)
				Thread::sleep(200)  
			Wallplug_MyLamp.sendCommand(OFF)
				Thread::sleep(1500)  

			Wallplug_MyStringLights.sendCommand(OFF)
				Thread::sleep(200)  
			Wallplug_MyStringLights.sendCommand(OFF)
				Thread::sleep(1500) 

			Switch_MyOffice_Light.sendCommand(OFF)
				Thread::sleep(200)  
			Switch_MyOffice_Light.sendCommand(OFF)
				Thread::sleep(1500)  

			Switch_BasementHallway_Light.sendCommand(OFF)
				Thread::sleep(200)  
			Switch_BasementHallway_Light.sendCommand(OFF)
				Thread::sleep(1500)  

			Switch_PowderRoom_Light.sendCommand(OFF)
				Thread::sleep(200)  
			Switch_PowderRoom_Light.sendCommand(OFF)
				Thread::sleep(1500)  

			Switch_Closet_Light.sendCommand(OFF)
				Thread::sleep(200)  
			Switch_Closet_Light.sendCommand(OFF)
				Thread::sleep(1500)

			Switch_BasementSteps_Light.sendCommand(OFF)
				Thread::sleep(200)  
			Switch_BasementSteps_Light.sendCommand(OFF)
				Thread::sleep(1500)
				
			Switch_KidsBathroom_Light.sendCommand(OFF)
				Thread::sleep(200)  
			Switch_KidsBathroom_Light.sendCommand(OFF)
				Thread::sleep(1500)

			Switch_GarageLight_Light.sendCommand(OFF)
				Thread::sleep(200)  
			Switch_GarageLight_Light.sendCommand(OFF)
				Thread::sleep(1500)	

			Wallplug_Guest_Air_Cleaner.sendCommand(OFF)
				Thread::sleep(200)  
			Wallplug_Guest_Air_Cleaner.sendCommand(OFF)
				Thread::sleep(1500)  

			Wallplug_Bedroom_Air_Cleaner.sendCommand(OFF)
				Thread::sleep(200)  
			Wallplug_Bedroom_Air_Cleaner.sendCommand(OFF)
				Thread::sleep(1500)  

			Wallplug_Loft_Air_Cleaner.sendCommand(OFF)
				Thread::sleep(200)  
			Wallplug_Loft_Air_Cleaner.sendCommand(OFF)
				Thread::sleep(1500)  

			Wallplug_Cubby_Light.sendCommand(OFF)
				Thread::sleep(1500)  
			Wallplug_Cubby_Light.sendCommand(OFF) 
		}

		if (systemStarted.state != ON && Home_Away.state == ON && Alexa_Status.state == 'ONLINE' && gInternet.state == ON && Wallplug_xMas_Tree.state == ON) {

			currMonth = now.getMonthOfYear 	

			if (systemStarted.state != ON && Home_Away.state == ON && currMonth == 12 && Wallplug_xMas_Tree.state == ON) {

				logInfo("ECHO", "-----------------------------------------------------------------------------")
	    		logInfo("ECHO", "Echo Speaking on Living Room, Tricia, Basement and Jays - I do not detect the adults")  
	    		Alexa_TTS_Doors.sendCommand('<speak><prosody rate="fast">Excuse me Cinnamon, I do not detect the adults in the house, so I am turning OFF the Christmas Tree, to insure your safety.</prosody></speak>')

			} else if (systemStarted.state != ON) {
			
		    	logInfo("ECHO", "Echo Speaking on Living Room, Tricia, Basement and Jays - I do not detect the adults")  
		    	Alexa_TTS_Doors.sendCommand('<speak><prosody rate="fast">Excuse me Cinnamon, I do not detect the adults in the house, so I am turning OFF the Zen Lamp, to insure your safety.</prosody></speak>') 	 
			}
		}

		if (systemStarted.state != ON && (Sonos_BackYard_State.state == 'PLAY' || Sonos_BackYard_State.state == 'PLAYING' || Sonos_BackYard_State.state == 'TRANSITIONING')) { 

			Sonos_BackYard_StandAlone.sendCommand(ON)
				Thread::sleep(1500)   
			Sonos_BackYard_Stop.sendCommand(ON)								// Stop Player Completely
				Thread::sleep(1500) 
			Sonos_BackYard_ClearQueue.sendCommand(ON)						// Clear Queue ON
				Thread::sleep(200)  
			Sonos_BackYard_ClearQueue.sendCommand(OFF)						// Clear Queue OFF
				Thread::sleep(1500)  
			Sonos_BackYard_Controller.postUpdate('PAUSE')				
			Sonos_BackYard_Stop.sendCommand(OFF)							// Reset Flag
		}
			
		if (systemStarted.state != ON && (Sonos_OnWallOutside_State.state == 'PLAY' || Sonos_OnWallOutside_State.state == 'PLAYING' || Sonos_OnWallOutside_State.state == 'TRANSITIONING')) { 

			Sonos_OnWallOutside_StandAlone.sendCommand(ON)
				Thread::sleep(1500)   
			Sonos_OnWallOutside_Stop.sendCommand(ON)						// Stop Player Completely
				Thread::sleep(1500) 
			Sonos_OnWallOutside_ClearQueue.sendCommand(ON)					// Clear Queue ON
				Thread::sleep(200)  
			Sonos_OnWallOutside_ClearQueue.sendCommand(OFF)					// Clear Queue OFF
				Thread::sleep(1500)  
			Sonos_OnWallOutside_Controller.postUpdate('PAUSE')				
			Sonos_OnWallOutside_Stop.sendCommand(OFF)						// Reset Flag
		}	

		if (systemStarted.state != ON && Partition1Status.state != 5 && HouseGuestHere.state == OFF && Wallplug_String_Lights.state == OFF && Part1Zone1Fault.state != ON && Part1Zone2Fault.state != ON && Part1Zone2FaultCopy.state != ON && Part1Zone3Fault.state != ON) {
	
			var String HouseAlarmMsgON = '<speak><prosody rate="fast">Excuse me, I am activiating the house alarm system, since no cell phones are detected.</prosody></speak>'
		
			Partition1ArmMode.sendCommand(2)
				Thread::sleep(1500)
				
			logInfo("ECHO", "Echo Speaking on Living Room, Tricia, Basement and Jays - Activating the Alarm System - NO cell phones are detected.")
			Alexa_TTS_Doors.sendCommand(HouseAlarmMsgON)	

			Switch_GarageLight_Light.sendCommand(OFF)
				Thread::sleep(1500)	
			Switch_GarageLight_Light.sendCommand(OFF)

			if (systemStarted.state != ON && gInternet.state == ON && gPort25.state == ON) { 

				val String subjectemailAlarm	= "openHAB - House Alarm"	
				val String bodyemailAlarm 		= "openHAB - Turned ON House Alarm - NO cell phones are detected."
				sendMail(JaygMail, subjectemailAlarm, bodyemailAlarm)
			}
  				
		} else if (systemStarted.state != ON && Partition1Status.state != 5 && (Wallplug_String_Lights.state == ON || PatioDoor_Status.state == OPEN || FrontDoor_Status.state == OPEN || Door2Garage_Status.state == OPEN || Part1Zone1Fault.state == ON || Part1Zone2Fault.state == ON || Part1Zone2FaultCopy.state == ON || Part1Zone3Fault.state == ON )){
		
			var String HouseAlarmMsgOFF = '<speak><prosody rate="fast">Excuse me, I was unable to activiate the house alarm system, since no cell phones are detected. A door is ajar or the string lights are on outside.</prosody></speak>'
				
			logInfo("ECHO", "Echo Speaking on Living Room, Tricia, Basement and Jays - NOT Activating the Alarm System - NO cell phones are detected.")
			Alexa_TTS_Doors.sendCommand(HouseAlarmMsgOFF)	

			if (systemStarted.state != ON && gInternet.state == ON && gPort25.state == ON) { 

				val String subjectemailAlarm	= "openHAB - House Alarm"	
				val String bodyemailAlarm 		= "openHAB - There are conflicts so I could NOT turn on the House Alarm with NO cell phones detected."
				sendMail(JaygMail, subjectemailAlarm, bodyemailAlarm)
			}
		}
end


rule "Automation Present"
	when
    	Item UnifiPhones changed to ON
	then

		if (systemStarted.state != ON) {

			logInfo("Unifi", "-----------------------------------------------------------------------------")
			logInfo("Unifi", "UnifiPhones changed to ON.")

			currHourVariable = now.getHourOfDay
			currHour.postUpdate(currHourVariable)
			currMonth = now.getMonthOfYear 

			if (systemStarted.state != ON && Partition1Status.state != 1 && Home_Away.state == ON && currHour.state >= 6 && currHour.state <= 21) {
	
				Partition1ArmMode.sendCommand(1)
					Thread::sleep(1500)
				Partition1ArmMode.sendCommand(1)
			}

			if (systemStarted.state != ON && Home_Away.state == ON && currHour.state >= 6 && currHour.state <= 21  && gInternet.state == ON) {
		
				var String HouseAlarmMsgON = '<speak><prosody rate="fast">Excuse me, I deactiviated the house alarm system, since cell phones are detected.</prosody></speak>'
								
				logInfo("ECHO", "Echo Speaking on Living Room, Tricia, Basement and Jays - deactiviated the Alarm System - Cell phones are detected.")
				Alexa_TTS_Doors.sendCommand(HouseAlarmMsgON)	
	
				if (systemStarted.state != ON && gInternet.state == ON && gPort25.state == ON) { 
	
					val String subjectemailAlarm	= "openHAB - House Alarm"	
					val String bodyemailAlarm 		= "openHAB - Turned OFF House Alarm - Cell phones are detected."
					sendMail(JaygMail, subjectemailAlarm, bodyemailAlarm)
				}
	  				
			} else if (systemStarted.state != ON && Partition1Status.state != 1 && Home_Away.state == ON && currHour.state >= 6 && currHour.state <= 21 && gInternet.state == ON) {
			
				var String HouseAlarmMsgOFF = '<speak><prosody rate="fast">Excuse me, I am unable to deactiviate the house alarm system, since cell phones are detected.</prosody></speak>'
					
				logInfo("ECHO", "Echo Speaking on Living Room, Tricia, Basement and Jays - NOT Deactivating the Alarm System - Cell phones are detected.")
				Alexa_TTS_Doors.sendCommand(HouseAlarmMsgOFF)

				if (systemStarted.state != ON && gInternet.state == ON && gPort25.state == ON) { 
	
					val String subjectemailAlarm	= "openHAB - House Alarm"	
					val String bodyemailAlarm 		= "openHAB - There are conflicts so I could NOT turn OFF the House Alarm with cell phones detected."
					sendMail(JaygMail, subjectemailAlarm, bodyemailAlarm)
				}
			}

			if (systemStarted.state != ON && gInternet.state == ON) { 

				Echo_BackYard_Volume.sendCommand('90')
					Thread::sleep(1500) 
				Echo_BackYard_textToSpeechVolume.sendCommand('90')
				logInfo("ECHO", "-----------------------------------------------------------------------------")
				logInfo("ECHO" , 'Echo BackYard volume set to 90.')
			}

			if (systemStarted.state != ON && gExtDoors.state == CLOSED && gInternet.state == ON) {

				logInfo("HVAC", "-----------------------------------------------------------------------------")
				logInfo("HVAC", "HVAC System Fans Turned ON.")

				// Turn ON HVAC FAN Main Floor
				MF_settings_fanMinOnTime.sendCommand(60)
					Thread::sleep(3000)
				MF_settings_fanMinOnTime.sendCommand(60)
					Thread::sleep(1500)
	
				// Turn OFF HVAC FAN Upstairs
				UpS_settings_fanMinOnTime.sendCommand(60)
					Thread::sleep(3000)
				UpS_settings_fanMinOnTime.sendCommand(60)
			}

			logInfo("ecobee", "-----------------------------------------------------------------------------")
			logInfo("ecobee", "Ecobee Automation Present executing with MF_runningEvent_climate is " + MF_runningEvent_climate.state + " and UpS_runningEvent_climate is " + UpS_runningEvent_climate.state)

			if (ecobeeAutoAway_tAlive !== null) {
			
				logInfo("tAlive", "Canceling ecobeeAutoAway_tAlive")
				ecobeeAutoAway_tAlive.cancel()
					Thread::sleep(1500)
				ecobeeAutoAway_tAlive = null
			}

			if (MF_runningEvent_climate.state != "resume" && gInternet.state == ON) {
			
				logInfo("ecobee", "Ecobee " + MF_name.state + " schedule being resumed.")
				ecobeeResumeProgram(MFecobeeID, true)
					Thread::sleep(1500)
			}

			if (UpS_runningEvent_climate.state != "resume" && gInternet.state == ON) {
			
				logInfo("ecobee", "Ecobee " + UpS_name.state + " schedule being resumed.")
				logInfo("ecobee", "-----------------------------------------------------------------------------")
				ecobeeResumeProgram(UpSecobeeID, true)
					Thread::sleep(1500)
			}

			if (systemStarted.state != ON && gInternet.state == ON && gPort25.state == ON) {

				var SimpleDateFormat df 		= new SimpleDateFormat( "M/d/YY h:mm a" )
				var String timestamp 			= df.format( new Date() )
			    var String subjectemailecobee 	= "openHAB - Ecobee"
			    var String bodyemailecobee		= "openHAB - Thermostats automatically resumed at " + timestamp + "\n"
			    sendMail(JaygMail, subjectemailecobee, bodyemailecobee)
			}

			logInfo("WeMo", "-----------------------------------------------------------------------------")
			logInfo("WeMo", "Room Air Cleaners Turned ON.")
			logInfo("WeMo", "-----------------------------------------------------------------------------")

			Wallplug_Guest_Air_Cleaner.sendCommand(ON)		
				Thread::sleep(200)  
			Wallplug_Guest_Air_Cleaner.sendCommand(ON)		
				Thread::sleep(1500)  

			Wallplug_Bedroom_Air_Cleaner.sendCommand(ON)	
				Thread::sleep(200)  
			Wallplug_Bedroom_Air_Cleaner.sendCommand(ON)	
				Thread::sleep(1500) 

			Wallplug_Loft_Air_Cleaner.sendCommand(ON)		
				Thread::sleep(1500)  
			Wallplug_Loft_Air_Cleaner.sendCommand(ON)		
		}		

		if (systemStarted.state != ON && Home_Away.state == OFF) {

			// In case they were on from AWAY mode

			Wallplug_Loft_Light.sendCommand(OFF)
				Thread::sleep(200)  
			Wallplug_Loft_Light.sendCommand(OFF)
				Thread::sleep(1500)
	
			Wallplug_Living_Room_Light.sendCommand(OFF)
				Thread::sleep(200)  
			Wallplug_Living_Room_Light.sendCommand(OFF)
				Thread::sleep(1500) 

			Wallplug_Cubby_Light.sendCommand(OFF)
				Thread::sleep(1500)  
			Wallplug_Cubby_Light.sendCommand(OFF)

			var String MovementInHouse		= null
			var String locationmap			= null
			var String previouslocationmap	= null
			locationmap    					= transform("MAP", "lastmotionlocation.map", LastMotion_Location.state.toString())
			previouslocationmap    			= transform("MAP", "lastmotionlocation.map", PreviousMotion_Location.state.toString())
			
			if (systemStarted.state != ON && locationmap != 'Motionless for Past 30 Min' && locationmap != 'Garage' && locationmap != 'Front Door') {
			
				MovementInHouse = ", The last movement in the house was in the " + locationmap
			
			} else if (systemStarted.state != ON) {
			
				if (systemStarted.state != ON && previouslocationmap != 'Motionless for Past 30 Min' && previouslocationmap != 'Garage' && previouslocationmap != 'Front Door') {
			
					MovementInHouse = ", The last movement in the house was in the " + previouslocationmap
					
				} else if (systemStarted.state != ON) {

					MovementInHouse = ", There is no movement in the house, for the last half hour."
				}		
			}

			Wallplug_SecurityTV.sendCommand(ON)
				Thread::sleep(1500) 
			Wallplug_SecurityTV.sendCommand(ON)

			if (systemStarted.state != ON && gInternet.state == ON) {

				var String WelcomeTempMessage = '<speak><prosody rate="fast">Welcome Home Family, The temperature in the house is ' + KitchenSensor_Temp_Rounded.state + ' degrees.' + MovementInHouse + '. </prosody></speak>'
	
					try { Thread::sleep(6000) } catch(InterruptedException e) { logError("UnifiPhones changed to ON", "Thread Sleep died improperly - please investigate.") }
	
				logInfo("ECHO", "-----------------------------------------------------------------------------")
	    		logInfo("ECHO", "Echo Speaking on Garage - Welcome Home Family.")  
				Echo_Garage_TTS.sendCommand(WelcomeTempMessage)
	    		logInfo("ECHO", "Echo Speaking on Living Room, Tricia, Basement and Jays - Welcome Home Family.")  
				Alexa_TTS_Doors.sendCommand(WelcomeTempMessage)  
				logInfo("ECHO", "-----------------------------------------------------------------------------") 
			}
		}

		// Start Living Room Sonos Playing from 7 am to 6 pm
        if (systemStarted.state != ON && Home_Away.state == ON && gInternet.state == ON && currHour.state >= 7 && currHour.state <= 18 && UnifiPhones.state == ON && Sonos_LivingRoom_State.state != 'PLAY' && Sonos_LivingRoom_State.state != 'PLAYING' && Sonos_LivingRoom_State.state != 'TRANSITIONING' && OnkyoLRPower.state != ON && Living_TV_Power.state != ON && Discover_Living_TV_Power.state != ON) {

			var SonosThingLR1			= getThingStatusInfo("sonos:PLAY1:RINCON_7828CAA1342C01400").getStatus()	 
			var SonosThingLR2		 	= getThingStatusInfo("sonos:PLAY1:RINCON_7828CAA1392A01400").getStatus()	 

			if (systemStarted.state != ON && Home_Away.state == ON && SonosThingLR1.toString() == 'ONLINE' && SonosThingLR2.toString() == 'ONLINE') {

				Sonos_LivingRoom_StandAlone.sendCommand(ON)
					Thread::sleep(1500)  
				Sonos_LivingRoom2_StandAlone.sendCommand(ON)
					Thread::sleep(1500)  

				Sonos_LivingRoom_Controller.sendCommand('PAUSE')	
					Thread::sleep(1500)  
				Sonos_LivingRoom2_Controller.sendCommand('PAUSE')	
					Thread::sleep(1500) 

				Sonos_LivingRoom_State.postUpdate('STOPPED')
				Sonos_LivingRoom2_State.postUpdate('STOPPED')
			
				Sonos_LivingRoom_ClearQueue.sendCommand(ON)					// Clear Queue ON
					Thread::sleep(1500)  
				Sonos_LivingRoom2_ClearQueue.sendCommand(ON)				// Clear Queue ON
					Thread::sleep(1500)  
			
				Sonos_LivingRoom_ClearQueue.sendCommand(OFF)				// Clear Queue OFF
					Thread::sleep(1500)  
				Sonos_LivingRoom2_ClearQueue.sendCommand(OFF)				// Clear Queue OFF
					Thread::sleep(1500)   
			
				Sonos_LivingRoom_Controller.sendCommand('PAUSE')	
					Thread::sleep(1500)  
				Sonos_LivingRoom2_Controller.sendCommand('PAUSE')	
					Thread::sleep(1500)

				Sonos_LivingRoom_State.postUpdate('STOPPED')
				Sonos_LivingRoom2_State.postUpdate('STOPPED')
	
			    Sonos_LivingRoom_Volume.sendCommand('10')
		            Thread::sleep(1500)
			    Sonos_LivingRoom2_Volume.sendCommand('10')
			        Thread::sleep(1500)
			
			    Sonos_LivingRoom_Favorite.sendCommand(Sonos_Today_Favorite)
			        Thread::sleep(1500)
			    Sonos_LivingRoom2_Favorite.sendCommand(Sonos_Today_Favorite)
			        Thread::sleep(1500)

				Sonos_LivingRoom_Stop.sendCommand(OFF)						// Reset Flag
					Thread::sleep(1500)  
				Sonos_LivingRoom2_Stop.sendCommand(OFF)						// Reset Flag
					Thread::sleep(1500)  
			
			    Sonos_LivingRoom_PlayQueue.sendCommand(ON)
			        Thread::sleep(200)
			    Sonos_LivingRoom2_PlayQueue.sendCommand(ON)
			        Thread::sleep(1500)
	
				Sonos_LivingRoom_Volume.sendCommand('10')
				    Thread::sleep(1500)
				Sonos_LivingRoom2_Volume.sendCommand('10')
				    Thread::sleep(1500)

	    		logInfo("SONOS", "Sonos Volume set to 10 for Living Room and Start Playing.")

			    Sonos_Kitchen_Volume.sendCommand('10')
				    Thread::sleep(1500)
				Sonos_LivingRoom_Add.sendCommand('RINCON_B8E937B684EE01400')		// Add Kitchen

	    		logInfo("SONOS", "Sonos Volume set to 10 for Kitchen and Joined to Living Room.")
			}
		}

		if (systemStarted.state != ON && Home_Away.state == OFF && currHour.state >= 17 && currHour.state <= 22) {			// 5 pm - 10 pm
		
			if (systemStarted.state != ON && Home_Away.state == ON && currMonth !== null && currMonth != 12) {

				logInfo("HUE", "Turning ON Bookshelf, KitchenShelf and KitchenIsland in WHITE.")

				KitchenShelf_Dimmer.sendCommand(new PercentType(100))
					Thread::sleep(200)  
				KitchenShelf_Color.sendCommand(Whitelight)
					Thread::sleep(200)
				KitchenShelf_Switch.sendCommand(ON) 
					Thread::sleep(200)

				KitchenIsland_Dimmer.sendCommand(new PercentType(50))
					Thread::sleep(200)  
    			KitchenIsland_Color.sendCommand(Whitelight50)
					Thread::sleep(200)
				KitchenIsland_Switch.sendCommand(ON) 
					Thread::sleep(200)
					
				BookShelf_Dimmer.sendCommand(new PercentType(100))
					Thread::sleep(200)  
				BookShelf_Color.sendCommand(Whitelight)
					Thread::sleep(200)
				BookShelf_Switch.sendCommand(ON)

			} else if (systemStarted.state != ON && Home_Away.state == ON && currMonth == 12) {

				if (systemStarted.state != ON && currDay == 9) {

					logInfo("HUE", "Turning ON Bookshelf, KitchenShelf and KitchenIsland in PURPLE.")
	
					KitchenShelf_Dimmer.sendCommand(new PercentType(100))
						Thread::sleep(200)  
					KitchenShelf_Color.sendCommand(Purplelight) 
						Thread::sleep(200)
					KitchenShelf_Switch.sendCommand(ON)
						Thread::sleep(200)
	
					KitchenIsland_Dimmer.sendCommand(new PercentType(50))
						Thread::sleep(200)  
	    			KitchenIsland_Color.sendCommand(Purplelight) 
						Thread::sleep(200)
					KitchenIsland_Switch.sendCommand(ON) 
						Thread::sleep(200)
						
					BookShelf_Dimmer.sendCommand(new PercentType(100))
						Thread::sleep(200)  
					BookShelf_Color.sendCommand(Purplelight)
						Thread::sleep(200)
					BookShelf_Switch.sendCommand(ON) 

				} else if (systemStarted.state != ON) {

					logInfo("HUE", "Turning ON Bookshelf, KitchenShelf and KitchenIsland in SCARLET RED.")
	
					KitchenShelf_Dimmer.sendCommand(new PercentType(100))
						Thread::sleep(200)  
					KitchenShelf_Color.sendCommand(Redlight) 
						Thread::sleep(200)
					KitchenShelf_Switch.sendCommand(ON)
						Thread::sleep(200)
	
					KitchenIsland_Dimmer.sendCommand(new PercentType(50))
						Thread::sleep(200)  
	    			KitchenIsland_Color.sendCommand(Redlight50) 
						Thread::sleep(200)
					KitchenIsland_Switch.sendCommand(ON) 
						Thread::sleep(200)
						
					BookShelf_Dimmer.sendCommand(new PercentType(100))
						Thread::sleep(200)  
					BookShelf_Color.sendCommand(Redlight)
						Thread::sleep(200)
					BookShelf_Switch.sendCommand(ON) 
				}
			}
		}	

		// Set Virtual Switch Home/Away to ON
		if (systemStarted.state != ON && Home_Away.state != ON) {	

			logInfo("HomeAway", "Back from Vacation OR Restart of OH with Nobody at Home.")
			Home_Away.postUpdate(ON)  
		}
end

I use the home/away virtual switch NOT for coming and going day to day but for vacations (long times away from home). It’s a virtual switch that basically does what group UnifiPhones logic does but much more. I manually turn this ON/OFF vs. it being automated in anyway.

I hope this helps, I have a ton of code examples if you need anything else.

Best, Jay