Virtual contact sensor. add auto close capability

Please consider adding an auto close capability with a selectable time to the built in virtual contact sensor.

I did this one a zillion years ago. Not sure if it would be useful to you or not. It is a switch, not contact, but seems like it would be pretty easy to make a contact version.

I use this to trigger an Alexa routine. She doesn't like switches to trigger routines but contact sensors work. The uDTH driver, Universal Virtual Device Switch uDTH, has worked great for years but for some reason is no longer triggering. My guess is a very recent beta update has created an issue. The built-in virtual contact works and a rule machine rule can create the auto off required.

I'll look at this, but if this is the only reason you have for doing this, the Virtual Motion Sensor driver will also work. It already has a similar feature built in. Just something to look at if you haven't already!

I have this sitting in my code. I think I was using it for triggering Alexa at one point.


/*
	Virtual Contact Sensor

	2023 -> chrisb

*/

metadata {
	definition (
			name: "Virtual Contact  Sensor",
			namespace: "Hubitat",
			author: "chrisb"
	) {

        capability "ContactSensor"
        attribute "contact", "enum"

        command "open"
        command "close"		

}

	preferences {
		input(name: "logEnable", type:"bool", title: "Enable debug logging",defaultValue: false)
		input(name: "txtEnable", type:"bool", title: "Enable descriptionText logging", defaultValue: true)
        input(name: "autoOff", type: "enum", description: "Automatically sets contact closed after selected time.", title: "Enable Auto-close", options: [[0:"Disabled"],[1:"1s"],[2:"2s"],[5:"5s"],[10:"10s"],[20:"20s"],[30:"30s"],[60:"1m"],[120:"2m"],[300:"5m"],[600:"10m"],[1800:"30m"],[3200:"60m"]], defaultValue: 0)
	}
}


def installed() {
	log.warn "installed..." 
    device.updateSetting("txtEnable",[type:"bool",value:true])
	sendEvent(name: "contact", value: "closed", descriptionText: getDescriptionText("contact set to closed"))
	updated()
}

def updated() {
	log.info "updated..."
	log.warn "debug logging is: ${logEnable == true}"
	log.warn "description logging is: ${txtEnable == true}"
	if (logEnable) runIn(1800,logsOff)
	initialize()
}

def initialize() {
	if (state?.lastRunningMode == null) {    

    }	
}

def parse(String description) { noCommands("parse") }

Integer limitIntegerRange(value,min,max) {
    Integer limit = value.toInteger()
    return (limit < min) ? min : (limit > max) ? max : limit
}

def logsOff(){
	log.warn "debug logging disabled..."
	device.updateSetting("logEnable",[value:"false",type:"bool"])
}

def open() {
	logDebug "setOpen was called"
    sendEvent(name: "contact", value: "open", descriptionText: getDescriptionText("contact set to open"))
    if (autoOff.toInteger()>0){
        runIn(autoOff.toInteger(),close)
    }
}

def close() {
	logDebug "setClosed was called"
    sendEvent(name: "contact", value: "closed", descriptionText: getDescriptionText("contact set to closed"))
}

private logDebug(msg) {
	if (settings?.logEnable) log.debug "${msg}"
}

private getDescriptionText(msg) {
	def descriptionText = "${device.displayName} ${msg}"
	if (settings?.txtEnable) log.info "${descriptionText}"
	return descriptionText
}

That does in fact work. Thanks.

One less rule.