[OBSOLETE] Universal Virtual Device Type and Translator

Could someone give me the link to the documentation? I have two Aeon Open/Close sensors that are for garage doors but the device type doesn’t use garage door icons they are from Aeon. I want to have garage door open and close icons in Smarttiles. I was told that this will give me what I want.

1 Like

@SBDOBRESCU

You set on the path of life360, which a wonderful app. But, as usual, the ST integration could always be better.

About twice a week now I’m having to send a text to sunshine asking them to send a check in do ST will update. That our I have to open the life360 connect app and click done.

I read through the thread and saw you talking about using this device as a virtual presence device.

So, this is what I’m thinking, and what I think you said you did.

  • Create a virtual device using udth for each person on life360.
  • setup an IFTTT for each person.
  • create a recipe that uses life360 and ST. Life360 reports arrival/departure then IFTTT turns on the udth
  • use the nite on ufth switch input to show presence arrival.

Is this basically what you did?
How reliable has it been?
Is it worth the trouble?

Possibly use this along with the lif life360 integration as a presence failsafe?

Thoughts? Opinions? Everything is welcome from everyone.

It’s not ST is your phone. I have not had 360 issues in months. There was a thread on this subject where people were saying that 360 was rock solid while I was having exactly the same issues as you now. I took several measures. Killed the Samsung app optimization, never turn off wifi, open l360 app on each phone after each l360 update.

With that bwing said, I did exactly what you were thinking in IFTTT and it sucked with capital S. I used it exclusively at first and it misfired badly. Then as fail safe but ST turned out more reliable. I don’t use IFTTT 360 with ST. but i still use it to disarm my alarm, so is not all that useless.

Thanks! Funny thing is, it is only two of the phones I have the problem with.

Well one use case is that it seems that SHM can not send notifications for lights left on, in a similar way that SHM can send notification if a door is left open for some amount of time.

So I can use this universal to wire up the light to send notification if left on for more than 1 hour.

But I still have some use cases that I think are still not handled.

I have the aeon leak sensor, which detects water and no water. I would like to both send notification when there is NOT water and turn on and off another switch.

Yeah, check the app optimization for sure.

What do you mean???

Very cool, @Mike_Maxwell, thanks. Can you add Smoke, CO, and Flood sensor attributes to this with similar functionality.

Reason being is I have a detached garage that is far from the house. I’d like to add door sensors, motion sensors, and smoke/CO alarm and be able to integrate them with my ST hub in my house. Becuase it’s so far. it’s not possible for me to have the garage on the same ST hub that is in the house. :frowning: I have to add a second hub in the garage and use IFTTT to set and get the values of the actual devicecs in the garage by setting and getting virtual devices in ST in the house using your uDTH ie if Smoke/CO alarm goes off in garage, turn on the Virtual Smoke uDTH in the ST hub in the house in order to trigger SHM. Or use ST to turn on a Virtual Light Switch uDTH in the house and have IFTTT trigger turn on the actual light switch in the garage.

Thanks!

1 Like

Also if you add smoke/CO capabilities, that would allow ST users to use a LEEO Smart Alert and IFTTT to easily integrate their non Z-Wave smoke/CO/flood alarms into ST.

I just did that with this device handler. Granted it doesn’t show up as a smoke alarm, but I can set SHM to send me an alert, which is good enough.

I modified the code to add smoke and flood and sound sensor capabilities. Works great. Shows up as a smoke detector and flood detector. IFTTT was able to trigger it. SHM also worked with it.
Let me know if anyone wants the code.

Scott

I’d suggest just opening a pull request to Mike’s repo.

2 Likes
   /* 
	Universal virtual DTH
  	Copyright 2016 Mike Maxwell

        Modded by Scott Barton to add Smoke, Water, Sound
        Lines between the //SB and //END SB are the lines I added/modified
    
    1.0.5.  2016-08-29  added sensor and actuator capabilities per Alex
    1.0.4	2016-05-21	added LUX capability
    1.0.3	2016-05-18	added optional auto off
    1.0.2	2016-05-15	ignore duplicate input requests
    					added version info

	This software if free for Private Use. You may use and modify the software without distributing it.
 
	This software and derivatives may not be used for commercial purposes.
	You may not distribute or sublicense this software.
	You may not grant a sublicense to modify and distribute this software to third parties not included in the license.

	Software is provided without warranty and the software author/license owner cannot be held liable for damages.        

*/


metadata {
	definition (name: "UVDT", namespace: "Scott_Barton", author: "scott barton") {
		
	    capability "Sensor"
	    capability "Actuator"
		//inputs
	    capability "Switch"					//on, off
        capability "Lock"					//lock, unlock
        
        //outputs
        capability "Contact Sensor"			//"open","closed"
        capability "Motion Sensor"			//"active", "inactive"
        capability "Presence Sensor"		//"present", "not present"
        capability "Acceleration Sensor"	//"active", "inactive"
        capability "Illuminance Measurement"

    //SB
        capability "Smoke Detector"    //"detected", "clear", "tested"
        capability "Water Sensor"      //"dry", "wet"
        capability "Sound Sensor"      //"detected", "not detected"
    //END SB
        
        //both
        capability "Door Control"			//listen for "open", "close" respond with "open" "closed"
        capability "Garage Door Control"	//listen for "open", "close" respond with "open" "closed"
        
        command "localOff"
        command "localOn"
        
        attribute "version", "string"
	}
    
    preferences {
    	def s1
        def s2
        def d
        //paragraph input
        input(
            title			: "UVDT version: ${getVersion()}"
            ,description	: null
            ,type			: "paragraph"
        )
    	input(
        	title			: "Device inputs\nRespond to these events/commands." 
            ,description	: null
            ,type			: "icon"
            ,required		: false
            ,defaultValue	: "st.illuminance.illuminance.dark"
        )
        input(
        	name			: "inSwitchOn"
            ,title			: "Switch (on, off)"
           	,type			: "bool"
            ,defaultValue	: true
        )
        input(
        	name			: "inDoorOn"
            ,title			: "Door Control (open, close)"
           	,type			: "bool"
            ,defaultValue	: false
        )
        input(
        	name			: "inGDoorOn"
            ,title			: "Garge Door Control (open, close)"
           	,type			: "bool"
            ,defaultValue	: false
        )
        input(
        	name			: "inLockOn"
            ,title			: "Lock (lock, unlock)"
           	,type			: "bool"
            ,defaultValue	: false
        )
        input(
        	name			: "autoOff"
            ,title			: "Delayed device turn off (optional)"
            ,type			: "enum"
            ,required		: false
            ,options		: [["5":"5 seconds"],["30":"30 seconds"],["60":"1 Minute"],["300":"5 Minutes"]]
        )
        input( 
           	title			: "Device outputs\nSend the events listed below."
            ,description	: null
           	,type			: "icon"
            ,required		: false
            ,defaultValue	: "st.illuminance.illuminance.dark"
        )
        
        d = "Contact"
        s1 = "open"
        s2 = "closed"
        input( 
        	name			: "contactOn"
           	,title			: buildTitle(d,s1,s2)
           	,type			: "enum"
           	,options		: buildOptions(d,s1,s2)
           	,description	: contactOn ?: "Not Used, Tap to enable..."
        )        

	d = "Motion"
        s1 = "active"
        s2 = "inactive"
		input( 
        	name			: "motionOn"
            ,title			: buildTitle(d,s1,s2)
            ,type			: "enum"
            ,options		: buildOptions(d,s1,s2)
            ,description	: motionOn ?: "Not Used, Tap to enable..."            
        )
        

    //SB
        d = "Smoke"
        s1 = "detected"
        s2 = "clear"
		input( 
        	name			: "smokeOn"
            ,title			: buildTitle(d,s1,s2)
            ,type			: "enum"
            ,options		: buildOptions(d,s1,s2)
            ,description	: smokeOn ?: "Not Used, Tap to enable..."            
        )
        
        d = "Water"
        s1 = "wet"
        s2 = "dry"
		input( 
        	name			: "waterOn"
            ,title			: buildTitle(d,s1,s2)
            ,type			: "enum"
            ,options		: buildOptions(d,s1,s2)
            ,description	: waterOn ?: "Not Used, Tap to enable..."            
        )
        
        d = "Sound"
        s1 = "detected"
        s2 = "not detected"
		input( 
        	name			: "soundOn"
            ,title			: buildTitle(d,s1,s2)
            ,type			: "enum"
            ,options		: buildOptions(d,s1,s2)
            ,description	: soundOn ?: "Not Used, Tap to enable..."            
        )
    //END SB


        d = "Presence"
        s1 = "present"
        s2 = "not present"
		input( 
        	name			: "presenceOn"
            ,title			: buildTitle(d,s1,s2)
            ,type			: "enum"
          	,options		: buildOptions(d,s1,s2)
            ,description	: presenceOn ?: "Not Used, Tap to enable..." 
        )
        
        d = "Door"
        s1 = "open"
        s2 = "closed"
        input( 
        	name			: "doorOn"
            ,title			: buildTitle(d,s1,s2)
            ,type			: "enum"
            ,options		: buildOptions(d,s1,s2)
            ,description	: doorOn ?: "Not Used, Tap to enable..." 
        )
        d = "Acceleration"
        s1 = "active"
        s2 = "inactive"
		input( 
        	name			: "accelOn"
            ,title			: buildTitle(d,s1,s2)
            ,type			: "enum"
          	,options		: buildOptions(d,s1,s2)
            ,description	: accelOn ?: "Not Used, Tap to enable..."  
        )
        d = "Illuminance"
        s1 = "0 Lux"
        s2 = "50 Lux"
		input( 
        	name			: "luxOn"
            ,title			: buildTitle(d,s1,s2)
            ,type			: "enum"
          	,options		: buildOptions(d,s1,s2)
            ,description	: accelOn ?: "Not Used, Tap to enable..."  
        )        
    }
  
  	simulator {
	}

	// tile definitions
	tiles (scale:1) {
    	multiAttributeTile(name:"switch", type: "generic", width: 6, height: 2, canChangeIcon: true){
			tileAttribute ("device.UVDT", key: "PRIMARY_CONTROL") {
				attributeState "on", label: '${name}', action: "localOff", icon: "st.switches.switch.on", backgroundColor: "#53a7c0"
				attributeState "off", label: '${name}', action: "localOn", icon: "st.switches.switch.off", backgroundColor: "#ffffff"
			}
        }
		standardTile("contact", "device.contact", inactiveLabel: false, height:2, width:2, canChangeIcon: false) {
        	state "default", label:"contact\nnot used" //, backgroundColor: "#ffffff" 
            state "closed", label:'${name}', backgroundColor: "#ffffff", icon:"st.contact.contact.closed" 
            state "open", label:'${name}', backgroundColor: "#53a7c0", icon:"st.contact.contact.open" 
		}
        standardTile("motion", "device.motion", inactiveLabel: false, height:2, width:2, canChangeIcon: false) {
            state "default", label: "motion\nnot used" //, icon:"st.motion.motion.inactive"
            state "inactive", label:'${name}', backgroundColor: "#ffffff", icon:"st.motion.motion.inactive" 
            state "active", label:'${name}', backgroundColor: "#53a7c0", icon:"st.motion.motion.active" 
        }

    //SB
        standardTile("smoke", "device.smoke", inactiveLabel: false, height:2, width:2, canChangeIcon: false) {
            state "default", label: "smoke\nnot used" //, icon:"st.alarm.smoke.clear"
            state "clear", label:'${name}', backgroundColor: "#ffffff", icon:"st.alarm.smoke.clear" 
            state "detected", label:'${name}', backgroundColor: "#e86d13", icon:"st.alarm.smoke.smoke" 
        }
        
        standardTile("water", "device.water", inactiveLabel: false, height:2, width:2, canChangeIcon: false) {
            state "default", label: "water\nnot used" //, icon:"st.alarm.water.dry"
            state "dry", label:'${name}', backgroundColor: "#ffffff", icon:"st.alarm.water.dry" 
            state "wet", label:'${name}', backgroundColor: "#53a7c0", icon:"st.alarm.water.wet" 
        }
        
        standardTile("sound", "device.sound", inactiveLabel: false, height:2, width:2, canChangeIcon: false) {
            state "default", label: "sound\nnot used" //, icon:"st.quirky.spotter.quirky-spotter-sound-off"
            state "not detected", label:'${name}', backgroundColor: "#ffffff", icon:"st.quirky.spotter.quirky-spotter-sound-off" 
            state "detected", label:'${name}', backgroundColor: "#53a7c0", icon:"st.quirky.spotter.quirky-spotter-sound-on" 
        }
    //END SB


           standardTile("present", "device.presence", inactiveLabel: false, height:2, width:2, canChangeIcon: false) {
            state "default", label: "presence\nnot used"
            state "not present", label:'${name}', backgroundColor: "#ffffff", icon:"st.presence.tile.presence-default" 
            state "present", label:'${name}', backgroundColor: "#53a7c0", icon:"st.presence.tile.presence-default" 
        }
        standardTile("door", "device.door", inactiveLabel: false, height:2, width:2, canChangeIcon: false) {
            state "default", label: "door\nnot used" 
            state "closed", label:'${name}', backgroundColor: "#ffffff", icon:"st.doors.garage.garage-closed" 
            state "open", label:'${name}', backgroundColor: "#53a7c0", icon:"st.doors.garage.garage-open" 
        }
        standardTile("accel", "device.acceleration", inactiveLabel: false, height:2, width:2, canChangeIcon: false) {
            state "default", label: "acceleration\nnot used"
            state "inactive", label:'${name}', backgroundColor: "#ffffff", icon:"st.motion.acceleration.inactive" 
            state "active", label:'${name}', backgroundColor: "#53a7c0", icon:"st.motion.acceleration.active" 
        }
        standardTile("lux", "device.lux", inactiveLabel: false, height:2, width:2, canChangeIcon: false) {
            state "default", label: "illuminance\nnot used"
            state "dark", label:'${name}', backgroundColor: "#ffffff", icon:"st.illuminance.illuminance.dark" 
            state "bright", label:'${name}', backgroundColor: "#ecf23a", icon:"st.illuminance.illuminance.bright" 
        }
        main(["switch"])
      //SB - Added "smoke","water","sound",
        details(["switch","contact","motion","smoke","water","sound","present","door","accel","lux"])
 	}
}

def open(){
	if (inDoorOn || inGDoorOn) localOn()
}

def close(){
	if (inDoorOn || inGDoorOn) localOff()
}

def lock(){
	if (inLockOn) localOn()
}

def unlock(){
	if (inLockOn) localOff()
}

def on(){
	if (inSwitchOn) localOn()
}

def off(){
	if (inSwitchOn) localOff()
}

def buildTitle(d,s1,s2){
	return "${d} (${s1}, ${s2})"
}

def buildOptions(d,s1,s2){
	def sOn = "on"
    def sOff = "off"
	def options = []
    options.add(["1":"when ${sOn} set ${d} to '${s1}'\nwhen ${sOff} set ${d} to '${s2}'"])
    options.add(["0":"when ${sOn} set ${d} to '${s2}'\nwhen ${sOff} set ${d} to '${s1}'"])
	return options
}

def syncDevices(cmd){
	if (cmd == null) cmd = device.currentValue("UVDT") == "on" ? "1" : "0"
    //log.debug "cmd: ${cmd}"
	if (contactOn != null){
		if (contactOn == cmd) sendEvent(name: "contact", value: "open")			//"when on send 'open'\nwhen off send 'closed'"
        else sendEvent(name: "contact", value: "closed")						//"when on send 'closed'\nwhen off send 'open'"
    } else sendEvent(name: "contact", value: null, displayed	: false)
	if (motionOn != null){
		if (motionOn == cmd) sendEvent(name: "motion", value: "active")			//"when on send 'active'\nwhen off send 'inactive'"
        else sendEvent(name: "motion", value: "inactive")						//"when on send 'inactive'\nwhen off send 'active'"
    } else sendEvent(name: "motion", value: null, displayed	: false)

     //SB
       if (smokeOn != null){
		if (smokeOn == cmd) sendEvent(name: "smoke", value: "detected")			//"when on send 'detected'\nwhen off send 'clear'"
        else sendEvent(name: "smoke", value: "clear")						//"when on send 'clear'\nwhen off send 'detected'"
    } else sendEvent(name: "smoke", value: null, displayed	: false)
    
    if (waterOn != null){
		if (waterOn == cmd) sendEvent(name: "water", value: "wet")			//"when on send 'wet'\nwhen off send 'dry'"
        else sendEvent(name: "water", value: "dry")						//"when on send 'dry'\nwhen off send 'wet'"
    } else sendEvent(name: "water", value: null, displayed	: false)
     
     if (soundOn != null){
		if (soundOn == cmd) sendEvent(name: "sound", value: "detected")			//"when on send 'detected'\nwhen off send 'not detected'"
        else sendEvent(name: "sound", value: "not detected")						//"when on send 'not detected'\nwhen off send 'detected'"
    } else sendEvent(name: "sound", value: null, displayed	: false) 
     //END SB

	if (presenceOn != null){
		if (presenceOn == cmd) sendEvent(name: "presence", value: "present")		//"when on send 'present'\nwhen off send 'not present'"
        else sendEvent(name: "presence", value: "not present")					//"when on send 'not present'\nwhen off send 'present'"
    } else sendEvent(name: "presence", value: null, displayed	: false)
	if (doorOn != null){
		if (doorOn == cmd) sendEvent(name: "door", value: "open")			//"when on send 'active'\nwhen off send 'inactive'"
        else sendEvent(name: "door", value: "closed")						//"when on send 'inactive'\nwhen off send 'active'"
    } else sendEvent(name: "door", value: null, displayed	: false)
	if (accelOn != null){
		if (accelOn == cmd) sendEvent(name: "acceleration", value: "active")
        else sendEvent(name: "acceleration", value: "inactive")				
    } else sendEvent(name: "acceleration", value: null, displayed	: false)
    if (luxOn != null){
    	if (luxOn == cmd){
        	sendEvent(name: "illuminance", value: 50)
        	sendEvent(name: "lux", value: "bright", displayed	: false)
        } else {
        	sendEvent(name: "illuminance", value: 0)
            sendEvent(name: "lux", value: "dark", displayed	: false)
        }
    } else {
    	sendEvent(name: "illuminance", value: null, displayed	: false)
        sendEvent(name: "lux", value: null, displayed	: false)
    }
}

def localOn() {
	if (device.currentValue("UVDT") != "on"){
    	log.info "on request: OK"
		sendEvent(name: "UVDT", value: "on" ,displayed: false)
    	syncDevices("1")
        if (autoOff) runIn(autoOff.toInteger(),localOff)
    } else {
    	log.info "on request: duplicate, ignored"
    }
}

def localOff() {
	if (device.currentValue("UVDT") != "off"){
    	log.info "off request: OK"
		sendEvent(name: "UVDT", value: "off" ,displayed: false)
    	syncDevices("0")
    } else {
    	log.info "off request: duplicate, ignored"
    }
}

def getVersion(){
	return "1.0.69"
}

//capture preference changes
def updated() {
	sendEvent( name: "version", value: getVersion(), displayed: false)
    //log.debug "syncDevices"
    syncDevices(null)
}

def configure() {

}
1 Like

I should be able to get these added to the production disto in the next few days.

4 Likes

Can you also add the ability to disable a device output that was previously enabled?
If I enable Contact accidently and save it, there is no way to disable it other than deleting the device and starting over. It would be nice to add a 3rd option ‘Not Used’ for each device output:

Contact (open, closed)
*when on set Contact to ‘open’, when off set contact to ‘closed’
*when on set contact to ‘closed’, when off set Contact to ‘open’
*Not Used

1.0.7 out, added in scotts changes, and ability to disable “not use” a formally used output capability.

5 Likes

Hi. Fairly new to ST, but excited about its expand-ability and the active Dev community. I recently implemented Mike’s Virtual Device to interface with the Roost Smart 9V. Just a couple questions:

  1. With a virtual switch like this, would there be any way to suppress the switch toggle in the mobile app, but keep the status? My goal here would be to avoid accidentally tipping the virtual switch, which in my use case reports as a smoke detector. I’d still want Roost (via IFTTT) to be able to ‘flip’ the switch, but just avoid unintended manual activation in the mobile app. Thoughts?

  2. I’m no sure yet (waiting to receive my Roost battery) whether Roost can (or will) turn the switch off when the Roost alert is cleared. If for some reason Roost doesn’t turn the switch off when cleared, is there any way to work around this in the DTH itself?

Thanks.

I’m using this dth in a similar way to get smoke alerfs in ST with Leeo via ifttt.

Why are you concerned about this? I haven’t personally found that accidentally turning switches on/off in the mobile app is an issue.

The DTH will allow you to set the switch to turn off after a few seconds (you can configure how long up to several minutes).

1 Like

NOTE: The issue that I needed help with initially has been resolved. It was just a glitch in the Device Handler code that needed to be tweaked, and I don’t need this for that anymore. Still curious though, as to whether or not I understand this SmartApp.

Is it possible to get new options added to this?

If so, I’m interested in using some old rules and custom commands that I have in Rule Machine that I created for my Rheem water heater. However, the Rheem API has changed, and they don’t work anymore.

Somebody has picked up the ball on the Rheem water heater Device Handler and Smart App to make them work with the new Rheem API, but now we need some help with the custom commands so that we can use it in rules.

If I understand it correctly (WARNING: I probably don’t lol ), the command being used in the old custom commands (and the old API) is setHeatingSetpoint whereas the new API uses setSetPoint.

Is there any way of getting this thing to translate from one command to the other? Am I even understanding what this is for? …and if so, is this even what I actually need here?

So first off major kudos to @Mike_Maxwell for this DTH. It’s super useful and is saving my bacon in getting my CoRE stuff built to overcome Presence issues.

Questions I had is there a possible way to set the device image vs icons similar to say mobile devices as presence sensors?

Also, on the My Home, Family TAB in the ST iOS app, the presence outputs show up but have no labels. Anyway to get text in there?

Thanks!