Wyze Contact Sensor, transform into Smartthings Virtual Sensor

I’ve looked 10 times and still cant find Alexa Switch. Any ideas??

1 Like

Just sent you a reply, if you didn’t get it, here is the link to try:

https://github.com/SmartThingsCommunity/SmartThingsPublic/blob/production/devicetypes/smartthings/testing/simulated-switch.src/simulated-switch.groovy

1 Like

These are the steps to do AFTER you publish the Device type for the Alexa Switch from Github:

In the list of steps below Select a “Type” from the dropdown, this should be “Alexa Switch” is the critical step to change the DTH (or Type) of a virtual device.

  • Login to the IDE @ https://account.smartthings.com/
  • Click “My Devices”
  • Click the “New Device” Button
  • Enter a “Name” for the device, this can be whatever you want.
  • Enter a “Label” for the device, this is optional and can be whatever you want.
  • Enter a “Device Network Id” This can be
    anything you want. I recommend short and sweet but it cannot duplicate other device ID’s. Lets say it was a virtual switch for your living room
    lights, maybe call it LRVD01
  • “Zigbee” Id should be left blank
  • Select a “Type” from the dropdown, this should be “Alexa Switch” (don’t expect the dropdown list to be in alphabetical order, the Alexa switch option might be at the bottom of the list)
  • “Version” should be published
  • “Location” should be your hub location, probably “Home”
  • “Hub” should be your hub name.
  • “Group” you won’t be able to select when creating, but these are Groups you’ve created in the Things page in
    the SmartThings app.
  • Click Create
1 Like

I think you want to use the DTH I listed in this earlier post, assuming you want the device to have the Contact Sensor Capability, as well as the Switch Capability.

1 Like

Thanks again! Did your info. get to TY_byrd_89? Looks like you did a forward or reply to him, but I just wanted to make sure. I have used the Alexa Switch for several tiles for my Actiontiles, many thanks

1 Like

No clue as @Ty_byrd_89 has not responded to either of us yet. Hopefully he has it figured out.

Here are my basic edits. I renamed the switch to “Wyze Motion Switch” I also changed the tiles to show motion instead of a switch. Again, I take no credit for the original work(s) - just made it work for me. Hope this helps.

/**
 *  Copyright 2015 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.
 *
 */
metadata {

    definition (name: "Wyze Motion Switch", namespace: "joek", author: "joek", runLocally: false, mnmn: "SmartThings", vid: "generic-switch") {
        capability "Switch"
        capability "Relay Switch"
        capability "Sensor"
        capability "Actuator"
        capability "Health Check"
        
        capability "Motion Sensor"

        command    "markDeviceOnline"
        command    "markDeviceOffline"
    }
    
    simulator {
		status "active": "motion:active"
		status "inactive": "motion:inactive"
	}

    tiles {
        standardTile("switch", "device.switch", width: 2, height: 2, canChangeIcon: true) {
            state "off", label: '${currentValue}', action: "switch.on", icon: "st.switches.switch.off", backgroundColor: "#ffffff"
            state "on", label: '${currentValue}', action: "switch.off", icon: "st.switches.switch.on", backgroundColor: "#00A0DC"
        }
        standardTile("motion", "device.motion", width: 2, height: 2) {
			state("inactive", label:'no motion', icon:"st.motion.motion.inactive", backgroundColor:"#cccccc", action: "active")
			state("active", label:'motion', icon:"st.motion.motion.active", backgroundColor:"#00A0DC", action: "inactive")
		}
        standardTile("deviceHealthControl", "device.healthStatus", decoration: "flat", width: 1, height: 1, inactiveLabel: false) {
            state "online",  label: "ONLINE", backgroundColor: "#00A0DC", action: "markDeviceOffline", icon: "st.Health & Wellness.health9", nextState: "goingOffline", defaultState: true
            state "offline", label: "OFFLINE", backgroundColor: "#E86D13", action: "markDeviceOnline", icon: "st.Health & Wellness.health9", nextState: "goingOnline"
            state "goingOnline", label: "Going ONLINE", backgroundColor: "#FFFFFF", icon: "st.Health & Wellness.health9"
            state "goingOffline", label: "Going OFFLINE", backgroundColor: "#FFFFFF", icon: "st.Health & Wellness.health9"
        }
        main "motion"
        details "motion"
    }
}

def installed() {
    log.trace "Executing 'installed'"
    markDeviceOnline()
    off()
    initialize()
}

def updated() {
    log.trace "Executing 'updated'"
    initialize()
}

def markDeviceOnline() {
    setDeviceHealth("online")
}

def markDeviceOffline() {
    setDeviceHealth("offline")
}

private setDeviceHealth(String healthState) {
    log.debug("healthStatus: ${device.currentValue('healthStatus')}; DeviceWatch-DeviceStatus: ${device.currentValue('DeviceWatch-DeviceStatus')}")
    // ensure healthState is valid
    List validHealthStates = ["online", "offline"]
    healthState = validHealthStates.contains(healthState) ? healthState : device.currentValue("healthStatus")
    // set the healthState
    sendEvent(name: "DeviceWatch-DeviceStatus", value: healthState)
    sendEvent(name: "healthStatus", value: healthState)
}

private initialize() {
    log.trace "Executing 'initialize'"
    sendEvent(name: "DeviceWatch-Enroll", value: [protocol: "cloud", scheme:"untracked"].encodeAsJson(), displayed: false)
}

def parse(description) {
}

def on() {
    log.debug "$version on()"
    sendEvent(name: "switch", value: "on")
    sendEvent(name: "motion", value: "active")
}

def off() {
    log.debug "$version off()"
    sendEvent(name: "switch", value: "off")
    sendEvent(name: "motion", value: "inactive")
}



private getVersion() {
    "PUBLISHED"
}
1 Like

@breezer260 Thanks for the update to the Wyze motion it works good.

1 Like

Works Great! What a nice addition! Makes the actiontiles look the same as if it was based on an actual smart physical device. Thanks ever so much!

2 Likes

Thanks to breezer260,
I just modify the device handler to be use like contact sensor.

“Wyze Contact Switch”

/**
 *  Copyright 2015 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.
 *
 */
metadata {

    definition (name: "Wyze Contact Switch", namespace: "JP", author: "JP", runLocally: false, mnmn: "SmartThings", vid: "generic-switch") {
        capability "Switch"
        capability "Relay Switch"
        capability "Sensor"
        capability "Actuator"
        capability "Health Check"
        
        capability "Contact Sensor"

        command    "markDeviceOnline"
        command    "markDeviceOffline"
    }
    	
	simulator {
		status "open": "contact:open"
		status "closed": "contact:closed"
	}

    tiles {
        standardTile("switch", "device.switch", width: 2, height: 2, canChangeIcon: true) {
            state "off", label: '${currentValue}', action: "switch.on", icon: "st.switches.switch.off", backgroundColor: "#ffffff"
            state "on", label: '${currentValue}', action: "switch.off", icon: "st.switches.switch.on", backgroundColor: "#00A0DC"
        }		
		standardTile("contact", "device.contact", width: 2, height: 2) {
			state("open", label:'Open', icon:"st.contact.contact.open", backgroundColor:"#cccccc", action: "open")
			state("closed", label:'Close', icon:"st.contact.contact.closed", backgroundColor:"#00A0DC", action: "closed")
		}
		
        standardTile("deviceHealthControl", "device.healthStatus", decoration: "flat", width: 1, height: 1, inactiveLabel: false) {
            state "online",  label: "ONLINE", backgroundColor: "#00A0DC", action: "markDeviceOffline", icon: "st.Health & Wellness.health9", nextState: "goingOffline", defaultState: true
            state "offline", label: "OFFLINE", backgroundColor: "#E86D13", action: "markDeviceOnline", icon: "st.Health & Wellness.health9", nextState: "goingOnline"
            state "goingOnline", label: "Going ONLINE", backgroundColor: "#FFFFFF", icon: "st.Health & Wellness.health9"
            state "goingOffline", label: "Going OFFLINE", backgroundColor: "#FFFFFF", icon: "st.Health & Wellness.health9"
        }
        main "contact"
        details "contact"
    }
}

def installed() {
    log.trace "Executing 'installed'"
    markDeviceOnline()
    off()
    initialize()
}

def updated() {
    log.trace "Executing 'updated'"
    initialize()
}

def markDeviceOnline() {
    setDeviceHealth("online")
}

def markDeviceOffline() {
    setDeviceHealth("offline")
}

private setDeviceHealth(String healthState) {
    log.debug("healthStatus: ${device.currentValue('healthStatus')}; DeviceWatch-DeviceStatus: ${device.currentValue('DeviceWatch-DeviceStatus')}")
    // ensure healthState is valid
    List validHealthStates = ["online", "offline"]
    healthState = validHealthStates.contains(healthState) ? healthState : device.currentValue("healthStatus")
    // set the healthState
    sendEvent(name: "DeviceWatch-DeviceStatus", value: healthState)
    sendEvent(name: "healthStatus", value: healthState)
}

private initialize() {
    log.trace "Executing 'initialize'"
    sendEvent(name: "DeviceWatch-Enroll", value: [protocol: "cloud", scheme:"untracked"].encodeAsJson(), displayed: false)
}

def parse(description) {
}

def on() {
    log.debug "$version on()"
    sendEvent(name: "switch", value: "on")
    sendEvent(name: "contact", value: "open")
}

def off() {
    log.debug "$version off()"
    sendEvent(name: "switch", value: "off")
    sendEvent(name: "contact", value: "closed")
}



private getVersion() {
    "PUBLISHED"
}

I’m confused…

How is this different from a general purpose Virtual Contact Sensor?

I believe it is different because it also implements the Switch Capability, thereby allowing IFTTT to change the state of the ‘Contact Sensor’.

1 Like

Every Virtual SENSOR (of any type!) needs to have a “Switch” Capability so that its State can be changed. Anything that is just a Sensor, has zero Commands. That’s why Virtual Sensors have added Commands to simulate (or replicate) a physical change. The most obvious Capability / Command to be used is “Switch”.

Does SmartThings still not acknowledge Virtual Devices as an essential part of the Platform? If they do, aren’t there “official” Virtual Devices (which follow a consistent pattern, including which Capability(s) should be claimed in order to change their State)?

Regardless, if this code above really is the first time Switch has been exposed for Virtual Contact Sensor, then really this code is applicable to any Virtual Contact Sensor, not just Wyze, and should be published as such (i.e., no need to mention Wyze… this will work for … anything; including Virtual Contact Sensors used to trigger Alexa Routines, and so on…).

1 Like

Looking through the SmartThings “official” virtual devices I’m not able to find anything with both switch and contact sensor capabilities.

But no, the code you’re referencing is certainly not the first time switch capability has been combined with contact sensor capability for a virtual device. The “Alexa Switch” referenced several times earlier in this thread is one example. And yes, either the virtual “Alexa Switch” or the “Wyze Contact Switch” can be used for all sorts of virtual sensor applications, and don’t really need the “Alexa” or “Wyze” names mentioned. At the same time, the name can sometimes help people understand use cases for the virtual devices.

The chief benefit to utilizing the combination sensor / switch is that Alexa will view it as an actual sensor and will trigger routines

1 Like

Correct. But that’s exactly why all “virtual sensors” need a triggering Command, the most obvious and practical of which is Capability “Switch” (which, of course, offers the switch(on,off) command.

In other words - this is all painfully obvious and I don’t understand why this Topic exists at all - except for the fact, as I mentioned earlier, that SmartThings has not officially acknowledged “virtual sensors” of any type, let alone document them for power-users.

can i switch line 95

endEvent(name: “switch”, value: “on”)

to

endEvent(name: “switch”, value: “open”)

and line 101
sendEvent(name: “switch”, value: “off”)
to
sendEvent(name: “switch”, value: “closed”)

so my app shows that the sensor is open or closed vs on and off?

I am trying to integrate the wyze sensor into the sensors on my SmartTHings hub and take advantage of the Smart Home Monitoring…

2nd day with SmartTHings hub, 1st day with Wyze

didn’t work… trying to get the middle garage door on this screenshot to say closed instead of off…


…should clarify, the code that bigjuanpa posted worked for me to get the wyze contact sensor to be read by SmartThings hub and app,… just want the nomenclature for it to say open or closed in my app…

Agree some of this is obvious, to make the virtual sensor useful of course it needs some commands (on, off, etc). My only question is, can you enable these on/off commands (to be triggered by IFTT) but disable any physical presses in the smartthings app (don’t want my dad to accidentally turn on or off one of these virtual sensors/switches i’m building for him)…

There’s no way to do it in the smartthings app, but what many people do is hide these type of switches in a “room“ which is only used for devices that you don’t want people to activate through the app. That will work for many people, but not all.

The other alternative is to use one of the third-party dashboards like action tiles or sharp tools. With these, you can build a custom dashboard for each person so they only see the devices you want them to see. This is popular, for example, for people with school-age children where they don’t want one child turning off the lights in the other child’s room.

For more about these options, see the following discussion thread. (Although the topic title mentions wall panels, these dashboards will all run in a web browser, so they will also work on a phone.)

FAQ: Sharptools , actiontiles or native ST app for your wall panel? (2020)

Note that one of the contributors to that thread, @tgauchat , Who was one of the action tiles developers, sadly passed away a few months ago. If you have any questions about one of his posts, just tag @625alex and he should be able to answer you there.

1 Like