Integration of two devices into one?


#1

Newbie here.
I’ve got different device handlers that I’d like (if possible) to integrate into one…

  1. Custom device handler that “opens” or “closes” dog door
    This is via the “hook” rf device. The handler was written by BeckyR here:
    https://github.com/beckyricha/smartthings/tree/HookDevices/devicetypes/smartthings

  2. SmartThings Multipurpose Sensor which shows if the device is open/closed

The hook device sends the commands, but I have no way of knowing if it really worked. That’s why I added the multipurpose sensor which tells me open/closed

Is there anyway to integrate this into a single item that accurately reflects the true open/closed condition based off the sensor?
Thanks in advance


(George) #2

Depends. For what purpose? Sounds like the multi sensor reflects the correct state.

For automation, you don’t need to combine the two. While for visual aesthetics, yes, you could modify the door DTH to also show the status of the multi sensor in the same device. (The multi sensor device would still be around as a separate device.)

Would need a helper app to subscribe to multi sensor events and send the state (via custom command in the door DTH) to the door DTH.


#3

Sounds exactly like what I’m asking for. I’m very new to ST. I’m assuming DTH is an acronym for a device handler. Any pointers on where to go to learn the basics so I can hobble something together?
Thanks for the reply


(George) #4

Do you want the (current) tile in the hook device to reflect the state (open/closed) provided by the multi sensor?

If so, it’s actually very simple. I can post the code once I get to a PC.


#5

Yes, that’s what I was thinking. I’ve been digging into all the smartapp vs DTH lingo and am learning via firehose. If you could post the code, that would be great to see it work, use it, and learn from it. Thanks!


(George) #6

Let’s look at the “hook” DTH. It is a http-only (not zwave or zigbee) dth. Has a single tile with two states, “on” and “off”. Two commands, consistent with the switch capability, on() and off() The dth does not receive any messages from the physical device, and so it does not know the state of the physical door.

The dth also does not generate any “events”. Events, in ST, are notifications seen by the hub and smartapps. In a dth like this, events are traditionally created and sent by the command methods (as opposed to within the parse method). Events generated by a switch dth would be [name: “switch”, value: “on”] and [name: “switch”, value: “off”].

You’re using a contact sensor to determine if the door is open or closed. Need to have a helper app subscribe to “contact” events from the contact sensor and send the events to the door dth. The door dth will then create/send the state of the door (except it sees it as a “switch”) and its own UI will reflect the state.

Further suggested revision:

The dth should use a different capability, capability.doorControl
http://docs.smartthings.com/en/latest/capabilities-reference.html?highlight=capabilities#door-control

The commands would be open() and close(), the attribute name would be “door” and the states “unknown” “closed” “open” “closing” “opening”.

The dth would sendEvent of opening/closing while the helper app would notify the dth when the state should be changed to open/closed based on the contact sensor. Should also add a delay to correspond to how long the door takes to open (since contact sensor “open” event will fire at the beginning of the opening action, not once the door is fully opened).


I have not run these, so there might be errors – let me know.

Helper app:

/**
 *
 *  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.
 *
 *
 */
 
definition(
    name: "Hook helper",
    namespace: "gkl-sf",
    author: "gkl_sf",
    description: "Hook helper",
    category: "Convenience",
    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 {
		input "hookDevice", "capability.switch", title: "Select the hook device", required: true, multiple: false    
		input "doorSensor", "capability.contactSensor", title: "Select the contact sensor", required: true, multiple: false
	}
}

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

	initialize()
}

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

	unsubscribe()
	initialize()
}

def initialize() {
    subscribe(doorSensor, "contact", sensorHandler)
}

def sensorHandler(evt) {
    hookDevice.statusReceive(evt)
}

DTH:

/**
 *  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: "Hook", namespace: "smartthings", author: "BeckyR") {
		capability "Switch"
        
        command "statusReceive", ["string"]     //added a custom command for helper app to send door status to the dth   
	}


	// tile definitions -- changed labels to Open and Closed
	tiles {
		standardTile("switch", "device.switch", width: 2, height: 2, canChangeIcon: true) {
			state "on", label: "Open", action: "switch.off", icon: "st.switches.switch.on", backgroundColor: "#79b821"
			state "off", label: "Closed", action: "switch.on", icon: "st.switches.switch.off", backgroundColor: "#ffffff"
		}

		main "switch"
		details "switch"
	}
}

def parse(String description) {
	log.error "This device does not support incoming events"
	return null
}

def on() {
	put('On')
}

def off() {
	put('Off')
}

private put(toggle) {
	def params = [
    uri: "https://api.gethook.io/v1/device/trigger/${device.deviceNetworkId}/${toggle}/?token=yourhooktoken"
]
    httpGet(params) 
}

def statusReceive(evt) {
    if (evt == "open") switchValue = "on"
    else if (evt == "closed") switchValue = "off"
    sendEvent(name: "switch", value: switchValue, descriptionText: "Door is ${evt}")
}

#7

Fantastic! I had also recently come to the same conclusion that the Hook dth ought to be the door opener category, but haven’t got comfortable enough with the code to rewrite it yet… Thank you very much for your code. I hope once all the kids weekend soccer slows, I will try it out and let you know how it goes. Thanks again


(George) #8

To implement capability.doorControl, I recommend the following:
(you had indicated that on/off fails 10% of the time, activation takes about 1 sec, door open/close takes 21 sec)

Open:

  • DTH open() method should sendEvent “openning”
  • APP should subscribe to the event and then runIn 2-3 seconds to confirm that sensor indicates contact is “open”
  • if not, the APP should re-run the open() and repeat (1-2 times)
  • once the APP receives the “open” contact from sensor, it should runIn 22 sec and then relay door “open” to DTH

Close:

  • DTH close() method should sendEvent “closing”
  • APP should subscribe to the event and then runIn 23-24 seconds to confirm that sensor indicates contact is “closed”
  • if not, the APP should re-run the close() and repeat (again, 1-2 times)
  • once the APP receive the “closed” contact from sensor, it should relay “closed” to DTH

There’s a way for an app to spoof events, to look like they are coming from DTH:

But it’s controversial, so what I do is have the APP send it using:
yourDevice.eventCreator([name: attribName, value: attribValue]) //and any other params such as displayed or descriptionText

And in the DTH metadata command “eventCreator”

and method

def eventCreator(evt) {
    sendEvent(evt)
}