Who took The Car?

My wife and I both have a car each, but we also have a third car (4x4) that we share.
This is used when one of us takes the dogs out, or because the weather is bad and one of us has to go somewhere and doesn’t want to chance taking a 2 wheel drive.

I was recently reading this thread:
https://community.smartthings.com/t/3-or-more-state-virtual-button/78073/7?u=cobra

and it got me thinking…

… Car at home… Wife took the car… I took the car… we both took the car…

4 ‘states’ for a virtual indication switch
So after ‘tweaking’ the DTH to show: Driver1, Driver2, On Drive & Both I created a little smartapp to try and indicate ‘who took the car’

I’m adding both the modified DTH and the smartapp here in case someone else might find it useful or as a building block for something else.

I have only been testing for a few days but everything seems to work quite well.
Always welcome feedback (good or bad :slight_smile: )

I’m afraid I’ve been rather sexist with the icons for the DTH
Driver 1 shows a man and Driver 2 shows a woman… easily changeable :slight_smile:

DTH:

/**
 *  Copyright 2015 SmartThings V1.2.0
 *
 *  Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
 *  in compliance with the License. You may obtain a copy of the License at:
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
 *  on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License
 *  for the specific language governing permissions and limitations under the License.
 *
 *  This DTH was originally developed by SmartThings for a garage door. 
 *  Then modified by Robin Winbourne for use with a dog feeder to give access to four 'states'
 *  Then modified by me (@cobra) to change the text/colours/icons to be able to use it to show who took a shared car :)
 *
 */


metadata {
	definition (name: "Custom Car Indicator - Generic", namespace: "Cobra", author: "SmartThings") {
		capability "Actuator"
		capability "Door Control"
    capability "Garage Door Control"
		capability "Refresh"
		capability "Sensor"
        
        command "driver1"
        command "driver2"
        command "on_drive"
		command "both"
       
	}

	simulator {
		
	}

	tiles {
		standardTile("toggle", "device.door", inactiveLabel: true, width: 3, height: 3) {
			state("closed", label:"Driver 1", action:"door control.open", icon:"st.People.people8", backgroundColor:"#0808F9")
			state("open", label:"Driver 2", action:"door control.close", icon:"st.People.people2", backgroundColor:"#F908F1")
			state("opening", label:"On Drive", icon:"st.Transportation.transportation12", backgroundColor:"#29BA29")
			state("closing", label:"Both", icon:"st.Transportation.transportation8", backgroundColor:"#FEC003")
			
		}
		standardTile("open", "device.door", inactiveLabel: false, decoration: "flat") {
			state "default", label:"On Drive", action:"door control.open", icon:"st.Transportation.transportation12"
		}
		
	
        standardTile("driver2", "device.door", inactiveLabel: false, decoration: "flat") {
			state "default", label:"Driver 2", action:"woman", icon:"st.People.people2"
		}
        standardTile("driver1", "device.door", inactiveLabel: false, decoration: "flat") {
			state "default", label:"Driver 1", action:"man", icon:"st.People.people8"
		}
	standardTile("close", "device.door", inactiveLabel: false, decoration: "flat") {
			state "default", label:"Both", action:"door control.close", icon:"st.Transportation.transportation8"
		}


		main "toggle"
		details(["toggle", "open", "close", "driver1", "driver2"])
	}
}

def parse(String description) {
	log.trace "parse($description)"
}

def open() {
	sendEvent(name: "door", value: "opening")
}

def close() {
    sendEvent(name: "door", value: "closing")
}

def driver1() {
    sendEvent(name: "door", value: "closed")
}

def driver2() {
    sendEvent(name: "door", value: "open")
}

def on_drive() {
    sendEvent(name: "door", value: "opening")
}

def both() {
    sendEvent(name: "door", value: "closing")
}

And the app to play with…

/**
 *  ****************  Who Took The Car  ****************
 *
 *  Design Usage:
 *  This was designed to indicate who took the shared car..... 
 *  It was created as a response to the creation of a special DTH:
 *  This DTH was originally developed by SmartThings for a garage door, 
 *  then modified by Robin Winbourne for use with a dog feeder to give access to four 'states'.
 *  Then modified by me (@cobra) to change the text/colours/icons to be able to use it to show who took a shared car :)
 *
 *  Copyright 2017 Andrew Parker
 *  
 *  This SmartApp is free!
 *  Donations to support development efforts are accepted via: 
 *
 *  Paypal at: https://www.paypal.me/smartcobra
 *  
 *
 *  I'm very happy for you to use this app without a donation, but if you find it useful then it would be nice to get a 'shout out' on the forum! -  @Cobra
 *  Have an idea to make this app better?  - Please let me know :)
 *
 *  Website: http://securendpoint.com/smartthings
 *
 *-------------------------------------------------------------------------------------------------------------------
 *  Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
 *  in compliance with the License. You may obtain a copy of the License at:
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
 *  on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License
 *  for the specific language governing permissions and limitations under the License.
 *-------------------------------------------------------------------------------------------------------------------
 *
 *  If modifying this project, please keep the above header intact and add your comments/credits below - Thank you! -  @Cobra
 *
 *-------------------------------------------------------------------------------------------------------------------
 *
 *  Last Update:
 *
 *  Changes:
 *
 *  V1.1.1 - Debug & Typos
 *  V1.1.0 - Added Enable/Disable switch - Added paragraph & header
 *  V1.0.0 - POC
 */
 
 
 
 
 
 
definition(
    name: "Who took the car?",
    namespace: "Cobra",
    author: "Andrew Parker",
    description: "Sets a switch when a car leaves, and tries to work out who took it",
    category: "Family",
    iconUrl: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience.png",
    iconX2Url: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience@2x.png",
    iconX3Url: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience@2x.png")


preferences {


section("") {
        paragraph "V1.1.1"
        paragraph image: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience.png",
                  title: "Who Took The Car?",
                  required: false,
                  "This app is designed to use a special 'Virtual Switch' to indicate who left with a shared vehicle"
    }

 section(){
            input "enableApp", "bool", title: "Enable App", required: true, defaultValue: true
        }




	section("Select Car Presence Sensor ") {
		input "presenceSensor1", "capability.presenceSensor", title: "Car Presence Sensor", multiple: false, required: true
       
	}
    section("Select Driver 1 "){
     input "presenceSensor2", "capability.presenceSensor", title: "Presence Sensor", multiple: false, required: true
     }
     section("Select Driver 2"){
     input "presenceSensor3", "capability.presenceSensor", title: "Presence Sensor", multiple: false, required: true
     }
    section("Select Virtual Car Status Switch"){
     input "switch1", "capability.doorControl", title: "Virtual Presence Sensor", multiple: true, required: true
     }
}

def installed() {
	log.debug "Installed with settings: ${settings}"
	initialize()
}

def updated() {
	log.debug "Updated with settings: ${settings}"
	unsubscribe()
	initialize()
}

def initialize() {
// Check if app is enabled
appEnable()

	subscribe(presenceSensor1, "presence", "presenceHandler1")
    subscribe(presenceSensor2, "presence", "presenceHandler2")
    subscribe(presenceSensor3, "presence", "presenceHandler3")
}



def presenceHandler2(evt) {
   state.currS2 = evt.value 
 log.debug "$presenceSensor2 = $state.currS2"
 if (state.currS2  == "not present") { process() }
 
}
def presenceHandler3(evt) {
   state.currS3 = evt.value  
   log.debug "$presenceSensor3 = $state.currS3"
    if (state.currS3  == "not present") { process() }
}


def presenceHandler1(evt) {
if (state.appGo == true){ 

state.currS1 = evt.value
 log.debug "$presenceSensor1 (Car) = $evt.value"
 if (state.currS1 == "not present"){
 def delay = 60
  log.info "Car left so checking who took it"
 log.info "Waiting for $delay seconds before checking"
 runIn(delay, process)
 }
 if (state.currS1 == "present"){process()}
 }
 }
 
 def process(){
 
 if (state.appGo == true){
 if (state.currS1  == "not present") {
 carAway()
 }
 else {
 log.info " Car is present"
 switch1.on_drive()
 }
 }
 }
 
 def carAway(){
 if (state.appGo == true){
 log.info "Checking now..."
    if (state.currS2  == "present" && state.currS3 == "not present") {
 log.info " $presenceSensor3 took the car"
  switch1.driver2()
 }

 else if (state.currS3  == "present" && state.currS2 == "not present"){
  log.info " $presenceSensor2 took the car"
 switch1.driver1()
 
 }
 
 else if (state.currS3  == "not present" && state.currS2 == "not present"){
  log.info " $presenceSensor2 & $presenceSensor3 both left, so maybe they both took the car !"
 switch1.both()
 
 }
  }
  }
 
 
 // Enable/Disable App
def appEnable (){
	if (enableApp == true){ 
    state.appGo = true
    log.debug "App is Enabled" }
    else if (enableApp == false){ 
    state.appGo = false
    log.debug "App is Disabled" }
    
 } 

There is currently one scenario that I have discovered that causes problems…
If the wife is out in the shared car and I take my car out… the app decides that we both have the car…
I’m working on adding our other two cars into the mix so the app can track if we took our own cars or the shared car…

5 Likes

Ok… this should work ok now - testing today :slight_smile:

I have added an optional ‘Drivers Own Car’ section to deal with the problem of leaving in my own car when the wife has the shared car.
Basically… if her car is at home she must be in the shared car.
If my car is at home as well, then we must both be in the shared car

So…
If the shared car leaves… and the driver’s own car is still at home then they must be in the shared car even if the second driver leaves in his/her own car… I think! :slight_smile:

Code…

/**
 *  ****************  Who Took The Car  ****************
 *
 *  Design Usage:
 *  This was designed to indicate who took the shared car..... 
 *  It was created as a response to the creation of a special DTH:
 *  This DTH was originally developed by SmartThings for a garage door, 
 *  then modified by Robin Winbourne for use with a dog feeder to give access to four 'states'.
 *  Then modified by me (@cobra) to change the text/colours/icons to be able to use it to show who took a shared car :)
 *
 *  Copyright 2017 Andrew Parker
 *  
 *  This SmartApp is free!
 *  Donations to support development efforts are accepted via: 
 *
 *  Paypal at: https://www.paypal.me/smartcobra
 *  
 *
 *  I'm very happy for you to use this app without a donation, but if you find it useful then it would be nice to get a 'shout out' on the forum! -  @Cobra
 *  Have an idea to make this app better?  - Please let me know :)
 *
 *  Website: http://securendpoint.com/smartthings
 *
 *-------------------------------------------------------------------------------------------------------------------
 *  Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
 *  in compliance with the License. You may obtain a copy of the License at:
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
 *  on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License
 *  for the specific language governing permissions and limitations under the License.
 *-------------------------------------------------------------------------------------------------------------------
 *
 *  If modifying this project, please keep the above header intact and add your comments/credits below - Thank you! -  @Cobra
 *
 *-------------------------------------------------------------------------------------------------------------------
 *
 *  Last Update: 10/08/2017
 *
 *  Changes:
 *
 *  V1.2.0 - Added driver's own car 
 *  V1.1.1 - Debug & Typos
 *  V1.1.0 - Added Enable/Disable switch - Added paragraph & header
 *  V1.0.0 - POC
 */
 
 
 
 
 
 
definition(
    name: "Who took the car?",
    namespace: "Cobra",
    author: "Andrew Parker",
    description: "Sets a switch when a car leaves, and tries to work out who took it",
    category: "Family",
    iconUrl: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience.png",
    iconX2Url: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience@2x.png",
    iconX3Url: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience@2x.png")


preferences {


section("") {
        paragraph "V1.2.0"
        paragraph image: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience.png",
                  title: "Who Took The Car?",
                  required: false,
                  "This app is designed to use a special 'Virtual Switch' to indicate who left with a shared vehicle"
    }

 section(){
            input "enableApp", "bool", title: "Enable App", required: true, defaultValue: true
        }




	section("Select Shared Car Presence Sensor ") {
		input "sharedCar", "capability.presenceSensor", title: "Car Presence Sensor", multiple: false, required: true
   	}
    
     section("Select Driver 1 "){
     input "carDriver1", "capability.presenceSensor", title: "Presence Sensor", multiple: false, required: true
    }
     section("Select Driver 2"){
     input "carDriver2", "capability.presenceSensor", title: "Presence Sensor", multiple: false, required: true
    }
    
    section("Select Driver 1's Car Presence Sensor") {
		input "driver1Car", "capability.presenceSensor", title: "Car Presence Sensor", multiple: false, required: false
     }
    section("Select Driver 2's Car Presence Sensor ") {
    	input "driver2Car", "capability.presenceSensor", title: "Car Presence Sensor", multiple: false, required: false
    }
   
    section("Select Virtual Car Status Switch"){
     input "switch1", "capability.doorControl", title: "Virtual Presence Sensor", multiple: true, required: true
    }
}

def installed() {
	log.debug "Installed with settings: ${settings}"
	initialize()
}

def updated() {
	log.debug "Updated with settings: ${settings}"
	unsubscribe()
	initialize()
}

def initialize() {
// Check if app is enabled
appEnable()

	subscribe(sharedCar, "presence", "sharedCarHandler")
    subscribe(carDriver1, "presence", "driver1Handler")
    subscribe(carDriver2, "presence", "driver2Handler")
    subscribe(driver1Car, "presence", "driver1OwnCarHandler")
    subscribe(driver2Car, "presence", "driver2OwnCarHandler")
    
}

def driver1OwnCarHandler(evt){
state.d1car = evt.value
log.debug "$driver1Car = $state.d1car"
}

def driver2OwnCarHandler(evt){
state.d2car = evt.value
log.debug "$driver2Car = $state.d2car"
}


def driver1Handler(evt) {
   state.currS2 = evt.value 
 log.debug "$carDriver1 = $state.currS2"
 if (state.currS2  == "not present") { process() }
 
}
def driver2Handler(evt) {
   state.currS3 = evt.value  
   log.debug "$presenceSensor3 = $state.currS3"
    if (state.currS3  == "not present") { process() }
}



def sharedCarHandler(evt) {
if (state.appGo == true){ 

state.currS1 = evt.value
 log.debug "$sharedCar (Car) = $evt.value"
 if (state.currS1 == "not present"){
 def delay = 60
  log.info "Car left so checking who took it"
 log.info "Waiting for $delay seconds before checking"
 runIn(delay, process)
 }
 if (state.currS1 == "present"){process()}
 }
 }
 
 def process(){
 
 if (state.appGo == true){
 if (state.currS1  == "not present") {
 carAway()
 }
 else {
 log.info " Car is present"
 switch1.on_drive()
 }
 }
 }
 
 def carAway(){
 if (state.appGo == true){
 log.info "Checking now..."
 carTest()
    if (state.currS2  == "present" && state.currS3 == "not present" && state.d2CarHome == true) {
 log.info " $carDriver2 took the car"
  switch1.driver2()
 }

 else if (state.currS3  == "present" && state.currS2 == "not present" && state.d1CarHome == true) {
  log.info " $carDriver1 took the car"
 switch1.driver1()
 
 }
 
 else if (state.currS3  == "not present" && state.currS2 == "not present"){
  log.info " $carDriver1 & $carDriver2 both left, so maybe they both took the car !"
 switch1.both()
 
 }
  }
  }
 
 
 // Own car presence
 
 def carTest(){
 if (state.d1car != 'null' && state.d1car == 'present'){
 state.d1CarHome = true
 }
  else if (state.d1car == 'null'){
   state.d1CarHome = true
 }
  else if (state.d1car == 'null' && state.d1car == 'not present'){
 state.d1CarHome = false
 }
 
  if (state.d2car != 'null'&& state.d2car != 'present'){
 state.d2CarHome = true
 
 }
  else if (state.d2car == 'null'){
   state.d1CarHome = true
 }
 else if (state.d2car != 'null' && state.d2car == 'not present'){
 state.d2CarHome = false
 }
 }
 
 
 
 
 
 
 
 // Enable/Disable App
def appEnable (){
	if (enableApp == true){ 
    state.appGo = true
    log.debug "App is Enabled" }
    else if (enableApp == false){ 
    state.appGo = false
    log.debug "App is Disabled" }
    
 }
1 Like

well if you didn’t take the car, and the wife didn’t take the car, then the dog took the car.

4 Likes

Damn… I didn’t think about that one… need to fit the dogs with presence sensors! :):rofl:

2 Likes