mirror of
https://github.com/mtan93/SmartThingsPublic.git
synced 2026-03-08 05:31:56 +00:00
Merge pull request #2064 from SmartThingsCommunity/staging
Rolling down staging to master
This commit is contained in:
@@ -0,0 +1,266 @@
|
||||
/**
|
||||
*
|
||||
* Inovelli 2-Channel Smart Plug
|
||||
*
|
||||
* github: Eric Maycock (erocm123)
|
||||
* Date: 2017-04-27
|
||||
* Copyright Eric Maycock
|
||||
*
|
||||
* Includes all configuration parameters and ease of advanced configuration.
|
||||
*
|
||||
* 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: "Inovelli 2-Channel Smart Plug", namespace: "erocm123", author: "Eric Maycock") {
|
||||
capability "Actuator"
|
||||
capability "Sensor"
|
||||
capability "Switch"
|
||||
capability "Polling"
|
||||
capability "Refresh"
|
||||
capability "Health Check"
|
||||
fingerprint manufacturer: "015D", prod: "0221", model: "251C"
|
||||
}
|
||||
simulator {}
|
||||
preferences {}
|
||||
tiles {
|
||||
multiAttributeTile(name: "switch", type: "lighting", width: 6, height: 4, canChangeIcon: true) {
|
||||
tileAttribute("device.switch", key: "PRIMARY_CONTROL") {
|
||||
attributeState "off", label: '${name}', action: "switch.on", icon: "st.switches.switch.off", backgroundColor: "#ffffff", nextState: "turningOn"
|
||||
attributeState "on", label: '${name}', action: "switch.off", icon: "st.switches.switch.on", backgroundColor: "#00a0dc", nextState: "turningOff"
|
||||
attributeState "turningOff", label: '${name}', action: "switch.on", icon: "st.switches.switch.off", backgroundColor: "#ffffff", nextState: "turningOn"
|
||||
attributeState "turningOn", label: '${name}', action: "switch.off", icon: "st.switches.switch.on", backgroundColor: "#00a0dc", nextState: "turningOff"
|
||||
}
|
||||
}
|
||||
standardTile("refresh", "device.switch", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
|
||||
state "default", label: "", action: "refresh.refresh", icon: "st.secondary.refresh"
|
||||
}
|
||||
main(["switch"])
|
||||
details(["switch",
|
||||
childDeviceTiles("all"), "refresh"
|
||||
])
|
||||
}
|
||||
}
|
||||
def parse(String description) {
|
||||
def result = []
|
||||
def cmd = zwave.parse(description)
|
||||
if (cmd) {
|
||||
result += zwaveEvent(cmd)
|
||||
logging("Parsed ${cmd} to ${result.inspect()}", 1)
|
||||
} else {
|
||||
logging("Non-parsed event: ${description}", 2)
|
||||
}
|
||||
return result
|
||||
}
|
||||
def zwaveEvent(physicalgraph.zwave.commands.basicv1.BasicReport cmd, ep = null) {
|
||||
logging("BasicReport ${cmd} - ep ${ep}", 2)
|
||||
if (ep) {
|
||||
def event
|
||||
childDevices.each {
|
||||
childDevice ->
|
||||
if (childDevice.deviceNetworkId == "$device.deviceNetworkId-ep$ep") {
|
||||
childDevice.sendEvent(name: "switch", value: cmd.value ? "on" : "off")
|
||||
}
|
||||
}
|
||||
if (cmd.value) {
|
||||
event = [createEvent([name: "switch", value: "on"])]
|
||||
} else {
|
||||
def allOff = true
|
||||
childDevices.each {
|
||||
n ->
|
||||
if (n.currentState("switch").value != "off") allOff = false
|
||||
}
|
||||
if (allOff) {
|
||||
event = [createEvent([name: "switch", value: "off"])]
|
||||
} else {
|
||||
event = [createEvent([name: "switch", value: "on"])]
|
||||
}
|
||||
}
|
||||
return event
|
||||
}
|
||||
}
|
||||
def zwaveEvent(physicalgraph.zwave.commands.basicv1.BasicSet cmd) {
|
||||
logging("BasicSet ${cmd}", 2)
|
||||
def result = createEvent(name: "switch", value: cmd.value ? "on" : "off", type: "digital")
|
||||
def cmds = []
|
||||
cmds << encap(zwave.switchBinaryV1.switchBinaryGet(), 1)
|
||||
cmds << encap(zwave.switchBinaryV1.switchBinaryGet(), 2)
|
||||
return [result, response(commands(cmds))] // returns the result of reponse()
|
||||
}
|
||||
def zwaveEvent(physicalgraph.zwave.commands.switchbinaryv1.SwitchBinaryReport cmd, ep = null) {
|
||||
logging("SwitchBinaryReport ${cmd} - ep ${ep}", 2)
|
||||
if (ep) {
|
||||
def event
|
||||
def childDevice = childDevices.find {
|
||||
it.deviceNetworkId == "$device.deviceNetworkId-ep$ep"
|
||||
}
|
||||
if (childDevice) childDevice.sendEvent(name: "switch", value: cmd.value ? "on" : "off")
|
||||
if (cmd.value) {
|
||||
event = [createEvent([name: "switch", value: "on"])]
|
||||
} else {
|
||||
def allOff = true
|
||||
childDevices.each {
|
||||
n->
|
||||
if (n.currentState("switch").value != "off") allOff = false
|
||||
}
|
||||
if (allOff) {
|
||||
event = [createEvent([name: "switch", value: "off"])]
|
||||
} else {
|
||||
event = [createEvent([name: "switch", value: "on"])]
|
||||
}
|
||||
}
|
||||
return event
|
||||
} else {
|
||||
def result = createEvent(name: "switch", value: cmd.value ? "on" : "off", type: "digital")
|
||||
def cmds = []
|
||||
cmds << encap(zwave.switchBinaryV1.switchBinaryGet(), 1)
|
||||
cmds << encap(zwave.switchBinaryV1.switchBinaryGet(), 2)
|
||||
return [result, response(commands(cmds))] // returns the result of reponse()
|
||||
}
|
||||
}
|
||||
def zwaveEvent(physicalgraph.zwave.commands.multichannelv3.MultiChannelCmdEncap cmd) {
|
||||
logging("MultiChannelCmdEncap ${cmd}", 2)
|
||||
def encapsulatedCommand = cmd.encapsulatedCommand([0x32: 3, 0x25: 1, 0x20: 1])
|
||||
if (encapsulatedCommand) {
|
||||
zwaveEvent(encapsulatedCommand, cmd.sourceEndPoint as Integer)
|
||||
}
|
||||
}
|
||||
def zwaveEvent(physicalgraph.zwave.commands.manufacturerspecificv2.ManufacturerSpecificReport cmd) {
|
||||
logging("ManufacturerSpecificReport ${cmd}", 2)
|
||||
def msr = String.format("%04X-%04X-%04X", cmd.manufacturerId, cmd.productTypeId, cmd.productId)
|
||||
logging("msr: $msr", 2)
|
||||
updateDataValue("MSR", msr)
|
||||
}
|
||||
def zwaveEvent(physicalgraph.zwave.Command cmd) {
|
||||
// This will capture any commands not handled by other instances of zwaveEvent
|
||||
// and is recommended for development so you can see every command the device sends
|
||||
logging("Unhandled Event: ${cmd}", 2)
|
||||
}
|
||||
def on() {
|
||||
logging("on()", 1)
|
||||
commands([
|
||||
zwave.switchAllV1.switchAllOn(),
|
||||
encap(zwave.switchBinaryV1.switchBinaryGet(), 1),
|
||||
encap(zwave.switchBinaryV1.switchBinaryGet(), 2)
|
||||
])
|
||||
}
|
||||
def off() {
|
||||
logging("off()", 1)
|
||||
commands([
|
||||
zwave.switchAllV1.switchAllOff(),
|
||||
encap(zwave.switchBinaryV1.switchBinaryGet(), 1),
|
||||
encap(zwave.switchBinaryV1.switchBinaryGet(), 2)
|
||||
])
|
||||
}
|
||||
void childOn(String dni) {
|
||||
logging("childOn($dni)", 1)
|
||||
def cmds = []
|
||||
cmds << new physicalgraph.device.HubAction(command(encap(zwave.basicV1.basicSet(value: 0xFF), channelNumber(dni))))
|
||||
cmds << new physicalgraph.device.HubAction(command(encap(zwave.switchBinaryV1.switchBinaryGet(), channelNumber(dni))))
|
||||
sendHubCommand(cmds, 1000)
|
||||
}
|
||||
void childOff(String dni) {
|
||||
logging("childOff($dni)", 1)
|
||||
def cmds = []
|
||||
cmds << new physicalgraph.device.HubAction(command(encap(zwave.basicV1.basicSet(value: 0x00), channelNumber(dni))))
|
||||
cmds << new physicalgraph.device.HubAction(command(encap(zwave.switchBinaryV1.switchBinaryGet(), channelNumber(dni))))
|
||||
sendHubCommand(cmds, 1000)
|
||||
}
|
||||
void childRefresh(String dni) {
|
||||
logging("childRefresh($dni)", 1)
|
||||
def cmds = []
|
||||
cmds << new physicalgraph.device.HubAction(command(encap(zwave.switchBinaryV1.switchBinaryGet(), channelNumber(dni))))
|
||||
sendHubCommand(cmds, 1000)
|
||||
}
|
||||
def poll() {
|
||||
logging("poll()", 1)
|
||||
commands([
|
||||
encap(zwave.switchBinaryV1.switchBinaryGet(), 1),
|
||||
encap(zwave.switchBinaryV1.switchBinaryGet(), 2),
|
||||
])
|
||||
}
|
||||
def refresh() {
|
||||
logging("refresh()", 1)
|
||||
commands([
|
||||
encap(zwave.switchBinaryV1.switchBinaryGet(), 1),
|
||||
encap(zwave.switchBinaryV1.switchBinaryGet(), 2),
|
||||
])
|
||||
}
|
||||
def ping() {
|
||||
logging("ping()", 1)
|
||||
refresh()
|
||||
}
|
||||
def installed() {
|
||||
logging("installed()", 1)
|
||||
command(zwave.manufacturerSpecificV1.manufacturerSpecificGet())
|
||||
createChildDevices()
|
||||
}
|
||||
def updated() {
|
||||
logging("updated()", 1)
|
||||
if (!childDevices) {
|
||||
createChildDevices()
|
||||
} else if (device.label != state.oldLabel) {
|
||||
childDevices.each {
|
||||
if (it.label == "${state.oldLabel} (CH${channelNumber(it.deviceNetworkId)})") {
|
||||
def newLabel = "${device.displayName} (CH${channelNumber(it.deviceNetworkId)})"
|
||||
it.setLabel(newLabel)
|
||||
}
|
||||
}
|
||||
state.oldLabel = device.label
|
||||
}
|
||||
sendEvent(name: "checkInterval", value: 2 * 15 * 60 + 2 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID])
|
||||
sendEvent(name: "needUpdate", value: device.currentValue("needUpdate"), displayed: false, isStateChange: true)
|
||||
}
|
||||
def zwaveEvent(physicalgraph.zwave.commands.configurationv2.ConfigurationReport cmd) {
|
||||
logging("${device.displayName} parameter '${cmd.parameterNumber}' with a byte size of '${cmd.size}' is set to '${cmd2Integer(cmd.configurationValue)}'", 2)
|
||||
}
|
||||
private encap(cmd, endpoint) {
|
||||
if (endpoint) {
|
||||
zwave.multiChannelV3.multiChannelCmdEncap(destinationEndPoint: endpoint).encapsulate(cmd)
|
||||
} else {
|
||||
cmd
|
||||
}
|
||||
}
|
||||
private command(physicalgraph.zwave.Command cmd) {
|
||||
if (state.sec) {
|
||||
zwave.securityV1.securityMessageEncapsulation().encapsulate(cmd).format()
|
||||
} else {
|
||||
cmd.format()
|
||||
}
|
||||
}
|
||||
private commands(commands, delay = 1000) {
|
||||
delayBetween(commands.collect {
|
||||
command(it)
|
||||
}, delay)
|
||||
}
|
||||
private channelNumber(String dni) {
|
||||
dni.split("-ep")[-1] as Integer
|
||||
}
|
||||
private void createChildDevices() {
|
||||
state.oldLabel = device.label
|
||||
for (i in 1..2) {
|
||||
addChildDevice("Switch Child Device", "${device.deviceNetworkId}-ep${i}", null, [completedSetup: true, label: "${device.displayName} (CH${i})",
|
||||
isComponent: true, componentName: "ep$i", componentLabel: "Channel $i"
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
private def logging(message, level) {
|
||||
if (logLevel != "0") {
|
||||
switch (logLevel) {
|
||||
case "1":
|
||||
if (level > 1) log.debug "$message"
|
||||
break
|
||||
case "99":
|
||||
log.debug "$message"
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/**
|
||||
* Switch Child Device
|
||||
*
|
||||
* Copyright 2017 Eric Maycock
|
||||
*
|
||||
* 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: "Switch Child Device", namespace: "erocm123", author: "Eric Maycock") {
|
||||
capability "Switch"
|
||||
capability "Actuator"
|
||||
capability "Sensor"
|
||||
capability "Refresh"
|
||||
}
|
||||
|
||||
tiles {
|
||||
multiAttributeTile(name:"switch", type: "lighting", width: 3, height: 4, canChangeIcon: true){
|
||||
tileAttribute ("device.switch", key: "PRIMARY_CONTROL") {
|
||||
attributeState "off", label: '${name}', action: "switch.on", icon: "st.switches.switch.off", backgroundColor: "#ffffff", nextState:"turningOn"
|
||||
attributeState "on", label: '${name}', action: "switch.off", icon: "st.switches.switch.on", backgroundColor: "#00A0DC", nextState:"turningOff"
|
||||
attributeState "turningOn", label:'${name}', action:"switch.off", icon:"st.switches.switch.on", backgroundColor:"#00A0DC", nextState:"turningOff"
|
||||
attributeState "turningOff", label:'${name}', action:"switch.on", icon:"st.switches.switch.off", backgroundColor:"#ffffff", nextState:"turningOn"
|
||||
}
|
||||
}
|
||||
standardTile("refresh", "device.switch", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
|
||||
state "default", label:"", action:"refresh.refresh", icon:"st.secondary.refresh"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void on() {
|
||||
parent.childOn(device.deviceNetworkId)
|
||||
}
|
||||
|
||||
void off() {
|
||||
parent.childOff(device.deviceNetworkId)
|
||||
}
|
||||
|
||||
void refresh() {
|
||||
parent.childRefresh(device.deviceNetworkId)
|
||||
}
|
||||
@@ -61,6 +61,8 @@ metadata {
|
||||
def installed() {
|
||||
// Device-Watch simply pings if no device events received for 32min(checkInterval)
|
||||
sendEvent(name: "checkInterval", value: 2 * 15 * 60 + 2 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID])
|
||||
|
||||
response(secure(zwave.basicV1.basicGet()))
|
||||
}
|
||||
|
||||
def updated() {
|
||||
@@ -163,4 +165,4 @@ private secure(physicalgraph.zwave.Command cmd) {
|
||||
* */
|
||||
def ping() {
|
||||
secure(zwave.basicV1.basicGet())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
* Date: 2013-03-05
|
||||
*/
|
||||
metadata {
|
||||
definition (name: "SmartAlert Siren", namespace: "smartthings", author: "SmartThings", ocfDeviceType: "x.com.st.smokedetector") {
|
||||
definition (name: "SmartAlert Siren", namespace: "smartthings", author: "SmartThings", ocfDeviceType: "x.com.st.d.sensor.smoke") {
|
||||
capability "Actuator"
|
||||
capability "Switch"
|
||||
capability "Sensor"
|
||||
|
||||
@@ -113,9 +113,9 @@ def updated() {
|
||||
|
||||
def configure() {
|
||||
commands([
|
||||
zwave.manufacturerSpecificV2.manufacturerSpecificGet(),
|
||||
zwave.batteryV1.batteryGet()
|
||||
], 6000)
|
||||
zwave.sensorBinaryV2.sensorBinaryGet(sensorType: zwave.sensorBinaryV2.SENSOR_TYPE_DOOR_WINDOW),
|
||||
zwave.manufacturerSpecificV2.manufacturerSpecificGet()
|
||||
], 1000)
|
||||
}
|
||||
|
||||
def sensorValueEvent(value) {
|
||||
@@ -190,11 +190,17 @@ def zwaveEvent(physicalgraph.zwave.commands.wakeupv1.WakeUpNotification cmd)
|
||||
cmds << command(zwave.manufacturerSpecificV2.manufacturerSpecificGet())
|
||||
cmds << "delay 1200"
|
||||
}
|
||||
|
||||
if (device.currentValue("contact") == null) { // Incase our initial request didn't make it
|
||||
cmds << command(zwave.sensorBinaryV2.sensorBinaryGet(sensorType: zwave.sensorBinaryV2.SENSOR_TYPE_DOOR_WINDOW))
|
||||
}
|
||||
|
||||
if (!state.lastbat || now() - state.lastbat > 53*60*60*1000) {
|
||||
cmds << command(zwave.batteryV1.batteryGet())
|
||||
} else {
|
||||
} else { // If we check the battery state we will send NoMoreInfo in the handler for BatteryReport so that we definitely get the report
|
||||
cmds << zwave.wakeUpV1.wakeUpNoMoreInformation().format()
|
||||
}
|
||||
|
||||
[event, response(cmds)]
|
||||
}
|
||||
|
||||
|
||||
@@ -86,13 +86,13 @@ import physicalgraph.zwave.commands.doorlockv1.*
|
||||
import physicalgraph.zwave.commands.usercodev1.*
|
||||
|
||||
def installed() {
|
||||
// Device-Watch simply pings if no device events received for 32min(checkInterval)
|
||||
sendEvent(name: "checkInterval", value: 2 * 15 * 60 + 2 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID])
|
||||
// Device-Watch pings if no device events received for 1 hour (checkInterval)
|
||||
sendEvent(name: "checkInterval", value: 1 * 60 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID])
|
||||
}
|
||||
|
||||
def updated() {
|
||||
// Device-Watch simply pings if no device events received for 32min(checkInterval)
|
||||
sendEvent(name: "checkInterval", value: 2 * 15 * 60 + 2 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID])
|
||||
// Device-Watch pings if no device events received for 1 hour (checkInterval)
|
||||
sendEvent(name: "checkInterval", value: 1 * 60 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID])
|
||||
try {
|
||||
if (!state.init) {
|
||||
state.init = true
|
||||
@@ -152,6 +152,10 @@ def zwaveEvent(physicalgraph.zwave.commands.securityv1.SecurityCommandsSupported
|
||||
|
||||
def zwaveEvent(DoorLockOperationReport cmd) {
|
||||
def result = []
|
||||
|
||||
unschedule("followupStateCheck")
|
||||
unschedule("stateCheck")
|
||||
|
||||
def map = [ name: "lock" ]
|
||||
if (cmd.doorLockMode == 0xFF) {
|
||||
map.value = "locked"
|
||||
@@ -365,7 +369,7 @@ def zwaveEvent(UserCodeReport cmd) {
|
||||
code = state["set$name"] ?: decrypt(state[name]) ?: "****"
|
||||
state.remove("set$name".toString())
|
||||
} else {
|
||||
map = [ name: "codeReport", value: cmd.userIdentifier, data: [ code: code ] ]
|
||||
map = [ name: "codeReport", value: cmd.userIdentifier, data: [ code: code ], isStateChange: true ]
|
||||
map.descriptionText = "$device.displayName code $cmd.userIdentifier is set"
|
||||
map.displayed = (cmd.userIdentifier != state.requestCode && cmd.userIdentifier != state.pollCode)
|
||||
map.isStateChange = true
|
||||
@@ -456,11 +460,12 @@ def zwaveEvent(physicalgraph.zwave.commands.timev1.TimeGet cmd) {
|
||||
def zwaveEvent(physicalgraph.zwave.commands.basicv1.BasicSet cmd) {
|
||||
// The old Schlage locks use group 1 for basic control - we don't want that, so unsubscribe from group 1
|
||||
def result = [ createEvent(name: "lock", value: cmd.value ? "unlocked" : "locked") ]
|
||||
result << response(zwave.associationV1.associationRemove(groupingIdentifier:1, nodeId:zwaveHubNodeId))
|
||||
if (state.assoc != zwaveHubNodeId) {
|
||||
result << response(zwave.associationV1.associationGet(groupingIdentifier:2))
|
||||
}
|
||||
result
|
||||
def cmds = [
|
||||
zwave.associationV1.associationRemove(groupingIdentifier:1, nodeId:zwaveHubNodeId).format(),
|
||||
"delay 1200",
|
||||
zwave.associationV1.associationGet(groupingIdentifier:2).format()
|
||||
]
|
||||
[result, response(cmds)]
|
||||
}
|
||||
|
||||
def zwaveEvent(physicalgraph.zwave.commands.batteryv1.BatteryReport cmd) {
|
||||
@@ -530,11 +535,18 @@ def unlockwtimeout() {
|
||||
lockAndCheck(DoorLockOperationSet.DOOR_LOCK_MODE_DOOR_UNSECURED_WITH_TIMEOUT)
|
||||
}
|
||||
|
||||
/**
|
||||
* PING is used by Device-Watch in attempt to reach the Device
|
||||
* */
|
||||
def ping() {
|
||||
refresh()
|
||||
runIn(30, followupStateCheck)
|
||||
secure(zwave.doorLockV1.doorLockOperationGet())
|
||||
}
|
||||
|
||||
def followupStateCheck() {
|
||||
runEvery1Hour(stateCheck)
|
||||
stateCheck()
|
||||
}
|
||||
|
||||
def stateCheck() {
|
||||
sendHubCommand(new physicalgraph.device.HubAction(secure(zwave.doorLockV1.doorLockOperationGet())))
|
||||
}
|
||||
|
||||
def refresh() {
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
* Date: 2014-07-15
|
||||
*/
|
||||
metadata {
|
||||
definition (name: "Z-Wave Siren", namespace: "smartthings", author: "SmartThings") {
|
||||
definition (name: "Z-Wave Siren", namespace: "smartthings", author: "SmartThings", ocfDeviceType: "x.com.st.d.sensor.smoke") {
|
||||
capability "Actuator"
|
||||
capability "Alarm"
|
||||
capability "Battery"
|
||||
|
||||
Reference in New Issue
Block a user