Compare commits

..

1 Commits

65 changed files with 503 additions and 1865 deletions

View File

@@ -9,7 +9,7 @@ apply plugin: 'smartthings-slack'
buildscript {
dependencies {
classpath "com.smartthings.deployment:executable-deployment-scripts:1.0.11"
classpath "com.smartthings.deployment:executable-deployment-scripts:1.0.8"
}
repositories {
mavenLocal()

View File

@@ -21,30 +21,28 @@ metadata {
capability "Tamper Alert"
capability "Temperature Measurement"
capability "Water Sensor"
capability "Health Check"
fingerprint deviceId: "0x0701", inClusters: "0x5E, 0x22, 0x85, 0x59, 0x20, 0x80, 0x70, 0x56, 0x5A, 0x7A, 0x72, 0x8E, 0x71, 0x73, 0x98, 0x9C, 0x31, 0x86", outClusters: ""
fingerprint mfr:"010F", prod:"0B01", model:"2002"
fingerprint mfr:"010F", prod:"0B01", model:"1002"
fingerprint deviceId: "0x0701", inClusters: "0x5E, 0x22, 0x85, 0x59, 0x20, 0x80, 0x70, 0x56, 0x5A, 0x7A, 0x72, 0x8E, 0x71, 0x73, 0x98, 0x9C, 0x31, 0x86", outClusters: ""
}
simulator {
}
tiles(scale: 2) {
multiAttributeTile(name:"FGFS", type:"lighting", width:6, height:4) {//with generic type secondary control text is not displayed in Android app
tileAttribute("device.water", key:"PRIMARY_CONTROL") {
attributeState("dry", icon:"st.alarm.water.dry", backgroundColor:"#00a0dc")
attributeState("wet", icon:"st.alarm.water.wet", backgroundColor:"#e86d13")
}
tileAttribute("device.tamper", key:"SECONDARY_CONTROL") {
tiles(scale: 2) {
multiAttributeTile(name:"FGFS", type:"lighting", width:6, height:4) {//with generic type secondary control text is not displayed in Android app
tileAttribute("device.water", key:"PRIMARY_CONTROL") {
attributeState("dry", icon:"st.alarm.water.dry", backgroundColor:"#00a0dc")
attributeState("wet", icon:"st.alarm.water.wet", backgroundColor:"#e86d13")
}
tileAttribute("device.tamper", key:"SECONDARY_CONTROL") {
attributeState("active", label:'tamper active', backgroundColor:"#00a0dc")
attributeState("inactive", label:'tamper inactive', backgroundColor:"#cccccc")
}
}
valueTile("temperature", "device.temperature", inactiveLabel: false, width: 2, height: 2) {
}
}
valueTile("temperature", "device.temperature", inactiveLabel: false, width: 2, height: 2) {
state "temperature", label:'${currentValue}°',
backgroundColors:[
[value: 31, color: "#153591"],
@@ -56,22 +54,22 @@ metadata {
[value: 96, color: "#bc2323"]
]
}
valueTile("battery", "device.battery", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
state "battery", label:'${currentValue}% battery', unit:""
}
main "FGFS"
details(["FGFS","battery", "temperature"])
}
valueTile("battery", "device.battery", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
state "battery", label:'${currentValue}% battery', unit:""
}
main "FGFS"
details(["FGFS","battery", "temperature"])
}
}
// parse events into attributes
def parse(String description) {
log.debug "Parsing '${description}'"
def result = []
if (description.startsWith("Err 106")) {
if (description.startsWith("Err 106")) {
if (state.sec) {
result = createEvent(descriptionText:description, displayed:false)
} else {
@@ -86,13 +84,13 @@ def parse(String description) {
} else if (description == "updated") {
return null
} else {
def cmd = zwave.parse(description, [0x31: 5, 0x56: 1, 0x71: 3, 0x72:2, 0x80: 1, 0x84: 2, 0x85: 2, 0x86: 1, 0x98: 1])
def cmd = zwave.parse(description, [0x31: 5, 0x56: 1, 0x71: 3, 0x72:2, 0x80: 1, 0x84: 2, 0x85: 2, 0x86: 1, 0x98: 1])
if (cmd) {
log.debug "Parsed '${cmd}'"
zwaveEvent(cmd)
}
}
if (cmd) {
log.debug "Parsed '${cmd}'"
zwaveEvent(cmd)
}
}
}
//security
@@ -109,7 +107,7 @@ def zwaveEvent(physicalgraph.zwave.commands.securityv1.SecurityMessageEncapsulat
//crc16
def zwaveEvent(physicalgraph.zwave.commands.crc16encapv1.Crc16Encap cmd)
{
def versions = [0x31: 5, 0x72: 2, 0x80: 1]
def versions = [0x31: 5, 0x72: 2, 0x80: 1]
def version = versions[cmd.commandClass as Integer]
def ccObj = version ? zwave.commandClass(cmd.commandClass, version) : zwave.commandClass(cmd.commandClass)
def encapsulatedCommand = ccObj?.command(cmd.command)?.parse(cmd.data)
@@ -123,124 +121,105 @@ def zwaveEvent(physicalgraph.zwave.commands.crc16encapv1.Crc16Encap cmd)
def zwaveEvent(physicalgraph.zwave.commands.wakeupv2.WakeUpNotification cmd)
{
def event = createEvent(descriptionText: "${device.displayName} woke up", displayed: false)
def cmds = []
// cmds << encap(zwave.sensorMultilevelV5.sensorMultilevelGet(sensorType: 1, scale: 0))
// cmds << "delay 500"
cmds << encap(zwave.batteryV1.batteryGet())
[event, response(cmds)]
def cmds = []
cmds << encap(zwave.batteryV1.batteryGet())
cmds << "delay 500"
cmds << encap(zwave.sensorMultilevelV5.sensorMultilevelGet(sensorType: 1, scale: 0))
cmds << "delay 1200"
cmds << encap(zwave.wakeUpV1.wakeUpNoMoreInformation())
[event, response(cmds)]
}
def zwaveEvent(physicalgraph.zwave.commands.manufacturerspecificv2.ManufacturerSpecificReport cmd) {
log.debug "manufacturerId: ${cmd.manufacturerId}"
log.debug "manufacturerName: ${cmd.manufacturerName}"
log.debug "productId: ${cmd.productId}"
log.debug "productTypeId: ${cmd.productTypeId}"
log.debug "manufacturerName: ${cmd.manufacturerName}"
log.debug "productId: ${cmd.productId}"
log.debug "productTypeId: ${cmd.productTypeId}"
}
def zwaveEvent(physicalgraph.zwave.commands.manufacturerspecificv2.DeviceSpecificReport cmd) {
log.debug "deviceIdData: ${cmd.deviceIdData}"
log.debug "deviceIdDataFormat: ${cmd.deviceIdDataFormat}"
log.debug "deviceIdDataLengthIndicator: ${cmd.deviceIdDataLengthIndicator}"
log.debug "deviceIdType: ${cmd.deviceIdType}"
if (cmd.deviceIdType == 1 && cmd.deviceIdDataFormat == 1) { //serial number in binary format
log.debug "deviceIdDataFormat: ${cmd.deviceIdDataFormat}"
log.debug "deviceIdDataLengthIndicator: ${cmd.deviceIdDataLengthIndicator}"
log.debug "deviceIdType: ${cmd.deviceIdType}"
if (cmd.deviceIdType == 1 && cmd.deviceIdDataFormat == 1) {//serial number in binary format
String serialNumber = "h'"
cmd.deviceIdData.each{ data ->
serialNumber += "${String.format("%02X", data)}"
}
updateDataValue("serialNumber", serialNumber)
log.debug "${device.displayName} - serial number: ${serialNumber}"
}
def response_cmds = []
if (!device.currentState("temperature")) {
response_cmds << encap(zwave.sensorMultilevelV5.sensorMultilevelGet(sensorType: 1, scale: 0))
}
if (!getDataValue("version") && !zwaveInfo.ver) {
log.debug "Requesting Version Report"
response_cmds << "delay 500"
response_cmds << encap(zwave.versionV1.versionGet())
}
response_cmds << "delay 1000"
response_cmds << encap(zwave.wakeUpV2.wakeUpNoMoreInformation())
[[:], response(response_cmds)]
cmd.deviceIdData.each{ data ->
serialNumber += "${String.format("%02X", data)}"
}
updateDataValue("serialNumber", serialNumber)
log.debug "${device.displayName} - serial number: ${serialNumber}"
}
}
def zwaveEvent(physicalgraph.zwave.commands.versionv1.VersionReport cmd) {
updateDataValue("version", "${cmd.applicationVersion}.${cmd.applicationSubVersion}")
log.debug "applicationVersion: ${cmd.applicationVersion}"
log.debug "applicationSubVersion: ${cmd.applicationSubVersion}"
log.debug "zWaveLibraryType: ${cmd.zWaveLibraryType}"
log.debug "zWaveProtocolVersion: ${cmd.zWaveProtocolVersion}"
log.debug "zWaveProtocolSubVersion: ${cmd.zWaveProtocolSubVersion}"
def zwaveEvent(physicalgraph.zwave.commands.versionv1.VersionReport cmd) {
updateDataValue("version", "${cmd.applicationVersion}.${cmd.applicationSubVersion}")
log.debug "applicationVersion: ${cmd.applicationVersion}"
log.debug "applicationSubVersion: ${cmd.applicationSubVersion}"
log.debug "zWaveLibraryType: ${cmd.zWaveLibraryType}"
log.debug "zWaveProtocolVersion: ${cmd.zWaveProtocolVersion}"
log.debug "zWaveProtocolSubVersion: ${cmd.zWaveProtocolSubVersion}"
}
def zwaveEvent(physicalgraph.zwave.commands.batteryv1.BatteryReport cmd) {
def result = []
def map = [:]
map.name = "battery"
map.value = cmd.batteryLevel == 255 ? 1 : cmd.batteryLevel.toString()
map.unit = "%"
result << createEvent(map)
if (!getDataValue("serialNumber")) {
result << response(encap(zwave.manufacturerSpecificV2.deviceSpecificGet()))
} else {
result << response(encap(zwave.wakeUpV2.wakeUpNoMoreInformation()))
}
result
map.displayed = true
createEvent(map)
}
def zwaveEvent(physicalgraph.zwave.commands.notificationv3.NotificationReport cmd) {
def map = [:]
if (cmd.notificationType == 5) {
switch (cmd.event) {
case 2:
map.name = "water"
map.value = "wet"
map.descriptionText = "${device.displayName} is ${map.value}"
if (cmd.notificationType == 5) {
switch (cmd.event) {
case 2:
map.name = "water"
map.value = "wet"
map.descriptionText = "${device.displayName} is ${map.value}"
break
case 0:
map.name = "water"
map.value = "dry"
map.descriptionText = "${device.displayName} is ${map.value}"
break
}
} else if (cmd.notificationType == 7) {
switch (cmd.event) {
case 0:
map.name = "tamper"
map.value = "inactive"
map.descriptionText = "${device.displayName}: tamper alarm has been deactivated"
break
case 0:
map.name = "water"
map.value = "dry"
map.descriptionText = "${device.displayName} is ${map.value}"
break
}
} else if (cmd.notificationType == 7) {
switch (cmd.event) {
case 0:
map.name = "tamper"
map.value = "inactive"
map.descriptionText = "${device.displayName}: tamper alarm has been deactivated"
break
case 3:
map.name = "tamper"
map.value = "active"
map.descriptionText = "${device.displayName}: tamper alarm activated"
break
}
}
createEvent(map)
case 3:
map.name = "tamper"
map.value = "active"
map.descriptionText = "${device.displayName}: tamper alarm activated"
break
}
}
createEvent(map)
}
def zwaveEvent(physicalgraph.zwave.commands.sensormultilevelv5.SensorMultilevelReport cmd) {
def map = [:]
if (cmd.sensorType == 1) {
// temperature
def cmdScale = cmd.scale == 1 ? "F" : "C"
map.value = convertTemperatureIfNeeded(cmd.scaledSensorValue, cmdScale, cmd.precision)
map.unit = getTemperatureScale()
map.name = "temperature"
map.displayed = true
// temperature
def cmdScale = cmd.scale == 1 ? "F" : "C"
map.value = convertTemperatureIfNeeded(cmd.scaledSensorValue, cmdScale, cmd.precision)
map.unit = getTemperatureScale()
map.name = "temperature"
map.displayed = true
}
createEvent(map)
createEvent(map)
}
def zwaveEvent(physicalgraph.zwave.commands.deviceresetlocallyv1.DeviceResetLocallyNotification cmd) {
@@ -249,18 +228,19 @@ def zwaveEvent(physicalgraph.zwave.commands.deviceresetlocallyv1.DeviceResetLoca
def configure() {
log.debug "Executing 'configure'"
// Device wakes up every 4 hours, this interval of 8h 2m allows us to miss one wakeup notification before marking offline
sendEvent(name: "checkInterval", value: 8 * 60 * 60 + 2 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID])
def cmds = []
cmds += zwave.wakeUpV2.wakeUpIntervalSet(seconds:21600, nodeid: zwaveHubNodeId)//FGFS' default wake up interval
cmds += zwave.manufacturerSpecificV2.manufacturerSpecificGet()
cmds += zwave.manufacturerSpecificV2.deviceSpecificGet()
cmds += zwave.versionV1.versionGet()
cmds += zwave.batteryV1.batteryGet()
cmds += zwave.sensorMultilevelV5.sensorMultilevelGet(sensorType: 1, scale: 0)
cmds += zwave.associationV2.associationSet(groupingIdentifier:1, nodeId: [zwaveHubNodeId])
cmds += zwave.wakeUpV2.wakeUpNoMoreInformation()
// default initial state
sendEvent(name: "water", value: "dry")
def cmds = []
cmds << zwave.associationV2.associationSet(groupingIdentifier:1, nodeId: [zwaveHubNodeId])
cmds << zwave.batteryV1.batteryGet() // other queries sent as response to BatteryReport
encapSequence(cmds, 200)
encapSequence(cmds, 500)
}
private secure(physicalgraph.zwave.Command cmd) {
@@ -269,7 +249,7 @@ private secure(physicalgraph.zwave.Command cmd) {
private crc16(physicalgraph.zwave.Command cmd) {
//zwave.crc16EncapV1.crc16Encap().encapsulate(cmd).format()
"5601${cmd.format()}0000"
"5601${cmd.format()}0000"
}
private encapSequence(commands, delay=200) {
@@ -277,10 +257,13 @@ private encapSequence(commands, delay=200) {
}
private encap(physicalgraph.zwave.Command cmd) {
if (zwaveInfo.zw && !zwaveInfo.zw.contains("s")) {
// Secure inclusion failed
crc16(cmd)
} else {
secure(cmd)
}
}
def secureClasses = [0x20, 0x5A, 0x70, 0x71, 0x84, 0x85, 0x8E, 0x9C]
//todo: check if secure inclusion was successful
//if not do not send security-encapsulated command
if (secureClasses.find{ it == cmd.commandClassId }) {
secure(cmd)
} else {
crc16(cmd)
}
}

View File

@@ -22,7 +22,6 @@ metadata {
capability "Sensor"
capability "Tamper Alert"
capability "Temperature Measurement"
capability "Health Check"
fingerprint deviceId: "0x0701", inClusters: "0x5E, 0x20, 0x86, 0x72, 0x5A, 0x59, 0x85, 0x73, 0x84, 0x80, 0x71, 0x56, 0x70, 0x31, 0x8E, 0x22, 0x30, 0x9C, 0x98, 0x7A", outClusters: ""
}
@@ -241,9 +240,7 @@ def zwaveEvent(physicalgraph.zwave.commands.deviceresetlocallyv1.DeviceResetLoca
def configure() {
log.debug "Executing 'configure'"
// Device-Watch simply pings if no device events received for 8 hrs & 2 minutes
sendEvent(name: "checkInterval", value: 8 * 60 * 60 + 2 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID])
def cmds = []
cmds += zwave.wakeUpV2.wakeUpIntervalSet(seconds: 7200, nodeid: zwaveHubNodeId)//FGMS' default wake up interval

View File

@@ -40,10 +40,10 @@ metadata {
// UI tile definitions
tiles {
standardTile("switch", "device.switch", width: 2, height: 2, canChangeIcon: true) {
state "on", action: "switch.off", icon: "st.vents.vent-open-text", backgroundColor: "#00a0dc"
state "on", action: "switch.off", icon: "st.vents.vent-open-text", backgroundColor: "#53a7c0"
state "off", action: "switch.on", icon: "st.vents.vent-closed", backgroundColor: "#ffffff"
state "obstructed", action: "clearObstruction", icon: "st.vents.vent-closed", backgroundColor: "#e86d13"
state "clearing", action: "", icon: "st.vents.vent-closed", backgroundColor: "#ffffff"
state "obstructed", action: "clearObstruction", icon: "st.vents.vent-closed", backgroundColor: "#ff0000"
state "clearing", action: "", icon: "st.vents.vent-closed", backgroundColor: "#ffff33"
}
controlTile("levelSliderControl", "device.level", "slider", height: 1, width: 2, inactiveLabel: false) {
state "level", action:"switch level.setLevel"

View File

@@ -22,7 +22,7 @@ metadata
{
standardTile("mainTile", "device.status", width: 1, height: 1, icon: "st.Entertainment.entertainment11")
{
state "default", label: "Simple Sync", icon: "st.Home.home2", backgroundColor: "#00a0dc"
state "default", label: "Simple Sync", icon: "st.Home.home2", backgroundColor: "#55A7FF"
}
def detailTiles = ["mainTile"]

View File

@@ -82,8 +82,8 @@ metadata {
tiles(scale: 2) {
multiAttributeTile(name:"motion", type: "generic", width: 6, height: 4){
tileAttribute ("device.motion", key: "PRIMARY_CONTROL") {
attributeState "active", label:'motion', icon:"st.motion.motion.active", backgroundColor:"#00A0DC"
attributeState "inactive", label:'no motion', icon:"st.motion.motion.inactive", backgroundColor:"#cccccc"
attributeState "active", label:'motion', icon:"st.motion.motion.active", backgroundColor:"#53a7c0"
attributeState "inactive", label:'no motion', icon:"st.motion.motion.inactive", backgroundColor:"#ffffff"
}
}
valueTile("temperature", "device.temperature", inactiveLabel: false, width: 2, height: 2) {

View File

@@ -1,2 +0,0 @@
.st-ignore
README.md

View File

@@ -1,43 +0,0 @@
# Aeon Multisensor Gen5
Cloud Execution
Works with:
* [Aeon Labs MultiSensor (Gen 5)](https://www.smartthings.com/works-with-smartthings/sensors/aeon-labs-multisensor-gen-5)
## Table of contents
* [Capabilities](#capabilities)
* [Health](#device-health)
* [Troubleshooting](#troubleshooting)
## Capabilities
* **Motion Sensor** - can detect motion
* **Temperature Measurement** - defines device measures current temperature
* **Relative Humidity Measurement** - allow reading the relative humidity from devices that support it
* **Illuminance Measurement** - gives the illuminance reading from devices that support it
* **Configuration** - _configure()_ command called when device is installed or device preferences updated
* **Sensor** - detects sensor events
* **Battery** - defines device uses a battery
* **Health Check** - indicates ability to get device health notifications
## Device Health
Aeon Labs MultiSensor (Gen 5) is polled by the hub.
As of hubCore version 0.14.38 the hub sends up reports every 15 minutes regardless of whether the state changed.
Device-Watch allows 2 check-in misses from device plus some lag time. So Check-in interval = (2*15 + 2)mins = 32 mins.
Not to mention after going OFFLINE when the device is plugged back in, it might take a considerable amount of time for
the device to appear as ONLINE again. This is because if this listening device does not respond to two poll requests in a row,
it is not polled for 5 minutes by the hub. This can delay up the process of being marked ONLINE by quite some time.
* __32min__ checkInterval
## Troubleshooting
If the device doesn't pair when trying from the SmartThings mobile app, it is possible that the device is out of range.
Pairing needs to be tried again by placing the device closer to the hub.
Instructions related to pairing, resetting and removing the device from SmartThings can be found in the following link:
* [Aeon Labs MultiSensor (Gen 5) Troubleshooting Tips](https://support.smartthings.com/hc/en-us/articles/206157226-Aeon-Labs-MultiSensor-Gen-5-)

View File

@@ -20,12 +20,10 @@ metadata {
capability "Configuration"
capability "Sensor"
capability "Battery"
capability "Health Check"
command "configureAfterSecure"
fingerprint deviceId: "0x0701", inClusters: "0x5E,0x86,0x72,0x59,0x85,0x73,0x71,0x84,0x80,0x30,0x31,0x70,0x98,0x7A", outClusters:"0x5A"
fingerprint mfr:"0086", prod:"0102", model:"004A", deviceJoinName: "Aeon Labs MultiSensor (Gen 5)"
}
simulator {
@@ -66,8 +64,8 @@ metadata {
tiles(scale: 2) {
multiAttributeTile(name:"motion", type: "generic", width: 6, height: 4){
tileAttribute ("device.motion", key: "PRIMARY_CONTROL") {
attributeState "active", label:'motion', icon:"st.motion.motion.active", backgroundColor:"#00a0dc"
attributeState "inactive", label:'no motion', icon:"st.motion.motion.inactive", backgroundColor:"#cccccc"
attributeState "active", label:'motion', icon:"st.motion.motion.active", backgroundColor:"#53a7c0"
attributeState "inactive", label:'no motion', icon:"st.motion.motion.inactive", backgroundColor:"#ffffff"
}
}
valueTile("temperature", "device.temperature", inactiveLabel: false, width: 2, height: 2) {
@@ -100,11 +98,6 @@ metadata {
}
}
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])
}
def parse(String description)
{
def result = null
@@ -251,13 +244,6 @@ def configureAfterSecure() {
secureSequence(request) + ["delay 20000", zwave.wakeUpV1.wakeUpNoMoreInformation().format()]
}
/**
* PING is used by Device-Watch in attempt to reach the Device
* */
def ping() {
secure(zwave.batteryV1.batteryGet())
}
def configure() {
// log.debug "configure()"
//["delay 30000"] + secure(zwave.securityV1.securityCommandsSupportedGet())

View File

@@ -59,8 +59,8 @@ metadata {
tiles(scale: 2) {
multiAttributeTile(name:"motion", type: "generic", width: 6, height: 4){
tileAttribute ("device.motion", key: "PRIMARY_CONTROL") {
attributeState "active", label:'motion', icon:"st.motion.motion.active", backgroundColor:"#00a0dc"
attributeState "inactive", label:'no motion', icon:"st.motion.motion.inactive", backgroundColor:"#cccccc"
attributeState "active", label:'motion', icon:"st.motion.motion.active", backgroundColor:"#53a7c0"
attributeState "inactive", label:'no motion', icon:"st.motion.motion.inactive", backgroundColor:"#ffffff"
}
}
valueTile("temperature", "device.temperature", inactiveLabel: false, width: 2, height: 2) {

View File

@@ -53,7 +53,7 @@ metadata {
// tile definitions
tiles {
standardTile("switch", "device.switch", width: 2, height: 2, canChangeIcon: true) {
state "on", label: '${name}', action: "switch.off", icon: "st.switches.switch.on", backgroundColor: "#00A0DC"
state "on", label: '${name}', action: "switch.off", icon: "st.switches.switch.on", backgroundColor: "#79b821"
state "off", label: '${name}', action: "switch.on", icon: "st.switches.switch.off", backgroundColor: "#ffffff"
}
valueTile("power", "device.power", decoration: "flat") {

View File

@@ -1,2 +0,0 @@
.st-ignore
README.md

View File

@@ -1,37 +0,0 @@
# Aeon Siren
Cloud Execution
Works with:
* [Aeon Labs Siren (Gen 5)](https://www.smartthings.com/works-with-smartthings/aeon-labs/aeon-labs-siren-gen-5)
## Table of contents
* [Capabilities](#capabilities)
* [Health](#device-health)
## Capabilities
* **Actuator** - represents that a Device has commands
* **Alarm** - allows for interacting with devices that serve as alarms
* **Switch** - can detect state (possible values: on/off)
* **Health Check** - indicates ability to get device health notifications
## Device Health
Aeon Labs Siren (Gen 5) is polled by the hub.
As of hubCore version 0.14.38 the hub sends up reports every 15 minutes regardless of whether the state changed.
Device-Watch allows 2 check-in misses from device plus some lag time. So Check-in interval = (2*15 + 2)mins = 32 mins.
Not to mention after going OFFLINE when the device is plugged back in, it might take a considerable amount of time for
the device to appear as ONLINE again. This is because if this listening device does not respond to two poll requests in a row,
it is not polled for 5 minutes by the hub. This can delay up the process of being marked ONLINE by quite some time.
* __32min__ checkInterval
## Troubleshooting
If the device doesn't pair when trying from the SmartThings mobile app, it is possible that the device is out of range.
Pairing needs to be tried again by placing the device closer to the hub.
Instructions related to pairing, resetting and removing the device from SmartThings can be found in the following link:
* [Aeon Labs Siren (Gen 5) Troubleshooting Tips](https://support.smartthings.com/hc/en-us/articles/204555240-Aeon-Labs-Siren-Gen-5-)

View File

@@ -20,11 +20,10 @@ metadata {
capability "Actuator"
capability "Alarm"
capability "Switch"
capability "Health Check"
command "test"
fingerprint deviceId: "0x1005", inClusters: "0x5E,0x98", deviceJoinName: "Aeon Labs Siren (Gen 5)"
fingerprint deviceId: "0x1005", inClusters: "0x5E,0x98"
}
simulator {
@@ -59,9 +58,6 @@ metadata {
}
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])
if(!state.sound) state.sound = 1
if(!state.volume) state.volume = 3
@@ -152,10 +148,3 @@ def test() {
private secure(physicalgraph.zwave.Command cmd) {
zwave.securityV1.securityMessageEncapsulation().encapsulate(cmd).format()
}
/**
* PING is used by Device-Watch in attempt to reach the Device
* */
def ping() {
secure(zwave.basicV1.basicGet())
}

View File

@@ -42,8 +42,8 @@ metadata {
tiles {
standardTile("presence", "device.presence", width: 2, height: 2, canChangeBackground: true) {
state "present", labelIcon:"st.presence.tile.present", backgroundColor:"#00a0dc"
state "not present", labelIcon:"st.presence.tile.not-present", backgroundColor:"#ffffff"
state "present", labelIcon:"st.presence.tile.present", backgroundColor:"#53a7c0"
state "not present", labelIcon:"st.presence.tile.not-present", backgroundColor:"#ebeef2"
}
standardTile("beep", "device.beep", decoration: "flat") {
state "beep", label:'', action:"tone.beep", icon:"st.secondary.beep", backgroundColor:"#ffffff"

View File

@@ -67,10 +67,10 @@ metadata {
}
standardTile("switch", "device.switch", width: 1, height: 1, canChangeIcon: true) {
state "on", label: '${name}', action: "forceOff", icon: "st.Electronics.electronics16", backgroundColor: "#00a0dc", nextState:"turningOff"
state "on", label: '${name}', action: "forceOff", icon: "st.Electronics.electronics16", backgroundColor: "#79b821", nextState:"turningOff"
state "turningOff", label:'TURNING OFF', icon:"st.Electronics.electronics16", backgroundColor:"#ffffff"
state "off", label: '${name}', action: "forceOn", icon: "st.Electronics.electronics16", backgroundColor: "#ffffff", nextState:"turningOn"
state "turningOn", label:'TURNING ON', icon:"st.Electronics.electronics16", backgroundColor:"#00a0dc"
state "turningOn", label:'TURNING ON', icon:"st.Electronics.electronics16", backgroundColor:"#79b821"
}
valueTile("1", "device.station1", decoration: "flat", canChangeIcon: false) {
state "station1", label:'${currentValue}', action:"preset1"

View File

@@ -81,13 +81,13 @@ metadata {
state "fanCirculate", label:'${name}', action:"switchFanMode"
}
controlTile("heatSliderControl", "device.heatingSetpoint", "slider", height: 1, width: 2, inactiveLabel: false) {
state "setHeatingSetpoint", action:"quickSetHeat", backgroundColor:"#e86d13"
state "setHeatingSetpoint", action:"quickSetHeat", backgroundColor:"#d04e00"
}
valueTile("heatingSetpoint", "device.heatingSetpoint", inactiveLabel: false, decoration: "flat") {
state "heat", label:'${currentValue}° heat', backgroundColor:"#ffffff"
}
controlTile("coolSliderControl", "device.coolingSetpoint", "slider", height: 1, width: 2, inactiveLabel: false) {
state "setCoolingSetpoint", action:"quickSetCool", backgroundColor: "#00a0dc"
state "setCoolingSetpoint", action:"quickSetCool", backgroundColor: "#1e9cbb"
}
valueTile("coolingSetpoint", "device.coolingSetpoint", inactiveLabel: false, decoration: "flat") {
state "cool", label:'${currentValue}° cool', backgroundColor:"#ffffff"

View File

@@ -53,7 +53,7 @@ metadata {
tiles {
standardTile("switch", "device.switch", width: 2, height: 2, canChangeIcon: true) {
state "on", action:"switch.off", icon:"st.vents.vent-open-text", backgroundColor:"#00a0dc"
state "on", action:"switch.off", icon:"st.vents.vent-open-text", backgroundColor:"#53a7c0"
state "off", action:"switch.on", icon:"st.vents.vent-closed", backgroundColor:"#ffffff"
}
valueTile("battery", "device.battery", inactiveLabel: false, decoration: "flat") {

View File

@@ -56,9 +56,9 @@ metadata {
tiles {
standardTile("switch", "device.switch", width: 2, height: 2, canChangeIcon: true) {
state "on", label:'${name}', action:"switch.off", icon:"st.switches.switch.on", backgroundColor:"#00a0dc", nextState:"turningOff"
state "on", label:'${name}', action:"switch.off", icon:"st.switches.switch.on", backgroundColor:"#79b821", nextState:"turningOff"
state "off", label:'${name}', action:"switch.on", icon:"st.switches.switch.off", backgroundColor:"#ffffff", nextState:"turningOn"
state "turningOn", label:'${name}', action:"switch.off", icon:"st.switches.switch.on", backgroundColor:"#00a0dc", nextState:"turningOff"
state "turningOn", label:'${name}', action:"switch.off", icon:"st.switches.switch.on", backgroundColor:"#79b821", nextState:"turningOff"
state "turningOff", label:'${name}', action:"switch.on", icon:"st.switches.switch.off", backgroundColor:"#ffffff", nextState:"turningOn"
}
standardTile("refresh", "device.switch", inactiveLabel: false, decoration: "flat") {

View File

@@ -1,12 +1,12 @@
/**
* Device Type Definition File
*
* Device Type: Fibaro Flood Sensor
* File Name: fibaro-flood-sensor.groovy
* Initial Release: 2014-12-10
* @author: Todd Wackford
* Email: todd@wackford.net
* @version: 1.0
* Device Type: Fibaro Flood Sensor
* File Name: fibaro-flood-sensor.groovy
* Initial Release: 2014-12-10
* @author: Todd Wackford
* Email: todd@wackford.net
* @version: 1.0
*
* Copyright 2014 SmartThings
*
@@ -26,8 +26,8 @@
* not displayed to the user. We do this so we can receive events and display on device
* activity. If the user wants to display the tamper tile, adjust the tile display lines
* with the following:
* main(["water", "temperature", "tamper"])
* details(["water", "temperature", "battery", "tamper"])
* main(["water", "temperature", "tamper"])
* details(["water", "temperature", "battery", "tamper"])
*
* @param none
*
@@ -39,18 +39,13 @@ metadata {
capability "Temperature Measurement"
capability "Configuration"
capability "Battery"
capability "Health Check"
capability "Sensor"
command "resetParams2StDefaults"
command "listCurrentParams"
command "updateZwaveParam"
command "test"
command "resetParams2StDefaults"
command "listCurrentParams"
command "updateZwaveParam"
command "test"
fingerprint deviceId: "0xA102", inClusters: "0x30,0x9C,0x60,0x85,0x8E,0x72,0x70,0x86,0x80,0x84"
fingerprint mfr:"010F", prod:"0000", model:"2002"
fingerprint mfr:"010F", prod:"0000", model:"1002"
fingerprint mfr:"010F", prod:"0B00", model:"1001"
}
simulator {
@@ -77,7 +72,7 @@ metadata {
tiles {
standardTile("water", "device.water", width: 2, height: 2) {
state "dry", icon:"st.alarm.water.dry", backgroundColor:"#ffffff"
state "wet", icon:"st.alarm.water.wet", backgroundColor:"#00a0dc"
state "wet", icon:"st.alarm.water.wet", backgroundColor:"#53a7c0"
}
valueTile("temperature", "device.temperature", inactiveLabel: false) {
state "temperature", label:'${currentValue}°',
@@ -91,9 +86,9 @@ metadata {
[value: 96, color: "#bc2323"]
]
}
standardTile("tamper", "device.tamper") {
state("secure", label:"secure", icon:"st.locks.lock.locked", backgroundColor:"#ffffff")
state("tampered", label:"tampered", icon:"st.locks.lock.unlocked", backgroundColor:"#00a0dc")
standardTile("tamper", "device.tamper") {
state("secure", label:"secure", icon:"st.locks.lock.locked", backgroundColor:"#ffffff")
state("tampered", label:"tampered", icon:"st.locks.lock.unlocked", backgroundColor:"#53a7c0")
}
valueTile("battery", "device.battery", inactiveLabel: false, decoration: "flat") {
state "battery", label:'${currentValue}% battery', unit:""
@@ -111,17 +106,26 @@ metadata {
def parse(String description)
{
def result = []
def cmd = zwave.parse(description, [0x31: 2, 0x30: 1, 0x70: 2, 0x71: 1, 0x84: 1, 0x80: 1, 0x9C: 1, 0x72: 2, 0x56: 2, 0x60: 3])
if (cmd) {
result += zwaveEvent(cmd) //createEvent(zwaveEvent(cmd))
}
if ( result[0] != null ) {
if (description == "updated") {
if (!state.MSR) {
result << response(zwave.wakeUpV1.wakeUpIntervalSet(seconds: 60*60, nodeid:zwaveHubNodeId))
result << response(zwave.manufacturerSpecificV2.manufacturerSpecificGet())
}
} else {
def cmd = zwave.parse(description, [0x31: 2, 0x30: 1, 0x70: 2, 0x71: 1, 0x84: 1, 0x80: 1, 0x9C: 1, 0x72: 2, 0x56: 2, 0x60: 3])
if (cmd) {
result += zwaveEvent(cmd) //createEvent(zwaveEvent(cmd))
}
}
result << response(zwave.batteryV1.batteryGet().format())
if ( result[0] != null ) {
log.debug "Parse returned ${result}"
result
}
}
}
@@ -138,9 +142,10 @@ def zwaveEvent(physicalgraph.zwave.commands.wakeupv1.WakeUpNotification cmd) {
def result = [createEvent(descriptionText: "${device.displayName} woke up", isStateChange: false)]
if (!isConfigured()) {
// we're still in the process of configuring a newly joined device
result << lateConfigure(true)
result += lateConfigure(true)
} else {
result << response(zwave.wakeUpV1.wakeUpNoMoreInformation())
result += response(zwave.wakeUpV1.wakeUpNoMoreInformation())
log.debug "We're done with WakeUp!"
}
result
}
@@ -148,7 +153,7 @@ def zwaveEvent(physicalgraph.zwave.commands.wakeupv1.WakeUpNotification cmd) {
def zwaveEvent(physicalgraph.zwave.commands.sensormultilevelv2.SensorMultilevelReport cmd)
{
def map = [:]
switch (cmd.sensorType) {
case 1:
// temperature
@@ -179,7 +184,7 @@ def zwaveEvent(physicalgraph.zwave.commands.sensorbinaryv1.SensorBinaryReport cm
def map = [:]
map.value = cmd.sensorValue ? "active" : "inactive"
map.name = "acceleration"
if (map.value == "active") {
map.descriptionText = "$device.displayName detected vibration"
}
@@ -194,49 +199,49 @@ def zwaveEvent(physicalgraph.zwave.commands.configurationv2.ConfigurationReport
}
def zwaveEvent(physicalgraph.zwave.commands.basicv1.BasicSet cmd) {
log.debug "BasicSet with CMD = ${cmd}"
if (!isConfigured()) {
def result = []
def map = [:]
map.name = "water"
log.debug "BasicSet with CMD = ${cmd}"
if (!isConfigured()) {
def result = []
def map = [:]
map.name = "water"
map.value = cmd.value ? "wet" : "dry"
map.descriptionText = "${device.displayName} is ${map.value}"
// If we are getting a BasicSet, and isConfigured == false, then we are likely NOT properly configured.
result += lateConfigure(true)
result << createEvent(map)
result
}
// If we are getting a BasicSet, and isConfigured == false, then we are likely NOT properly configured.
result += lateConfigure(true)
result << createEvent(map)
result
}
}
def zwaveEvent(physicalgraph.zwave.commands.sensoralarmv1.SensorAlarmReport cmd)
{
def map = [:]
if (cmd.sensorType == 0x05) {
map.name = "water"
map.value = cmd.sensorState ? "wet" : "dry"
map.descriptionText = "${device.displayName} is ${map.value}"
log.debug "CMD = SensorAlarmReport: ${cmd}"
setConfigured()
} else if ( cmd.sensorType == 0) {
map.name = "tamper"
map.isStateChange = true
map.value = cmd.sensorState ? "tampered" : "secure"
map.descriptionText = "${device.displayName} has been tampered with"
runIn(30, "resetTamper") //device does not send alarm cancelation
} else if ( cmd.sensorType == 1) {
map.name = "tamper"
map.value = cmd.sensorState ? "tampered" : "secure"
map.descriptionText = "${device.displayName} has been tampered with"
runIn(30, "resetTamper") //device does not send alarm cancelation
log.debug "CMD = SensorAlarmReport: ${cmd}"
setConfigured()
} else if ( cmd.sensorType == 0) {
map.name = "tamper"
map.isStateChange = true
map.value = cmd.sensorState ? "tampered" : "secure"
map.descriptionText = "${device.displayName} has been tampered with"
runIn(30, "resetTamper") //device does not send alarm cancelation
} else if ( cmd.sensorType == 1) {
map.name = "tamper"
map.value = cmd.sensorState ? "tampered" : "secure"
map.descriptionText = "${device.displayName} has been tampered with"
runIn(30, "resetTamper") //device does not send alarm cancelation
} else {
map.descriptionText = "${device.displayName}: ${cmd}"
}
@@ -245,10 +250,10 @@ def zwaveEvent(physicalgraph.zwave.commands.sensoralarmv1.SensorAlarmReport cmd)
def resetTamper() {
def map = [:]
map.name = "tamper"
map.value = "secure"
map.descriptionText = "$device.displayName is secure"
sendEvent(map)
map.name = "tamper"
map.value = "secure"
map.descriptionText = "$device.displayName is secure"
sendEvent(map)
}
def zwaveEvent(physicalgraph.zwave.Command cmd) {
@@ -262,10 +267,10 @@ def zwaveEvent(physicalgraph.zwave.commands.manufacturerspecificv2.ManufacturerS
def msr = String.format("%04X-%04X-%04X", cmd.manufacturerId, cmd.productTypeId, cmd.productId)
log.debug "msr: $msr"
device.updateDataValue(["MSR", msr])
if ( msr == "010F-0B00-2001" ) { //this is the msr and device type for the fibaro flood sensor
result += lateConfigure(true)
}
if ( msr == "010F-0B00-2001" ) { //this is the msr and device type for the fibaro flood sensor
result += lateConfigure(true)
}
result << createEvent(descriptionText: "$device.displayName MSR: $msr", isStateChange: false)
result
@@ -277,17 +282,17 @@ def setConfigured() {
def isConfigured() {
Boolean configured = device.getDataValue(["configured"]) as Boolean
return configured
return configured
}
def lateConfigure(setConf = False) {
def res = response(configure())
if (setConf)
setConfigured()
return res
if (setConf)
setConfigured()
return res
}
/**
@@ -299,34 +304,26 @@ def lateConfigure(setConf = False) {
*/
def configure() {
log.debug "Configuring Device..."
// Device wakes up every 4 hours, this interval allows us to miss one wakeup notification before marking offline
sendEvent(name: "checkInterval", value: 8 * 60 * 60 + 2 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID])
// default initial state
sendEvent(name: "water", value: "dry")
def cmds = []
// send associate to group 2 to get alarm data
cmds << zwave.associationV2.associationSet(groupingIdentifier:2, nodeId:[zwaveHubNodeId]).format()
cmds << zwave.configurationV1.configurationSet(configurationValue: [255], parameterNumber: 5, size: 1).format()
// send associate to group 3 to get sensor data reported only to hub
cmds << zwave.associationV2.associationSet(groupingIdentifier:3, nodeId:[zwaveHubNodeId]).format()
// reporting frequency of temps and battery set to one hour
cmds << zwave.configurationV1.configurationSet(configurationValue: [0,60*60], parameterNumber: 10, size: 2).format()
// cmds << zwave.configurationV1.configurationGet(parameterNumber: 10).format()
def cmds = []
// send associate to group 2 to get alarm data
cmds << zwave.associationV2.associationSet(groupingIdentifier:2, nodeId:[zwaveHubNodeId]).format()
cmds << zwave.configurationV1.configurationSet(configurationValue: [255], parameterNumber: 5, size: 1).format()
// send associate to group 3 to get sensor data reported only to hub
cmds << zwave.associationV2.associationSet(groupingIdentifier:3, nodeId:[zwaveHubNodeId]).format()
// temp hysteresis set to .5 degrees celcius
cmds << zwave.configurationV1.configurationSet(configurationValue: [0,50], parameterNumber: 12, size: 2).format()
// cmds << zwave.configurationV1.configurationGet(parameterNumber: 12).format()
cmds << zwave.batteryV1.batteryGet().format()
cmds << zwave.wakeUpV1.wakeUpNoMoreInformation().format()
cmds << zwave.configurationV1.configurationGet(parameterNumber: 12).format()
// reporting frequency of temps and battery set to one hour
cmds << zwave.configurationV1.configurationSet(configurationValue: [0,60*60], parameterNumber: 10, size: 2).format()
cmds << zwave.configurationV1.configurationGet(parameterNumber: 10).format()
cmds << zwave.wakeUpV1.wakeUpNoMoreInformation().format()
delayBetween(cmds, 100)
}
@@ -352,18 +349,18 @@ def test() {
* @return none
*/
def updateZwaveParam(params) {
if ( params ) {
def pNumber = params.paramNumber
def pSize = params.size
def pValue = [params.value]
log.debug "Make sure device is awake and in recieve mode (triple-click?)"
log.debug "Updating ${device.displayName} parameter number '${pNumber}' with value '${pValue}' with size of '${pSize}'"
if ( params ) {
def pNumber = params.paramNumber
def pSize = params.size
def pValue = [params.value]
log.debug "Make sure device is awake and in recieve mode (triple-click?)"
log.debug "Updating ${device.displayName} parameter number '${pNumber}' with value '${pValue}' with size of '${pSize}'"
def cmds = []
cmds << zwave.configurationV1.configurationSet(configurationValue: pValue, parameterNumber: pNumber, size: pSize).format()
cmds << zwave.configurationV1.configurationGet(parameterNumber: pNumber).format()
delayBetween(cmds, 1000)
}
cmds << zwave.configurationV1.configurationSet(configurationValue: pValue, parameterNumber: pNumber, size: pSize).format()
cmds << zwave.configurationV1.configurationGet(parameterNumber: pNumber).format()
delayBetween(cmds, 1000)
}
}
/**
@@ -380,26 +377,26 @@ def updateZwaveParam(params) {
def resetParams2StDefaults() {
log.debug "Resetting ${device.displayName} parameters to SmartThings compatible defaults"
def cmds = []
cmds << zwave.configurationV1.configurationSet(configurationValue: [0,0], parameterNumber: 1, size: 2).format()
cmds << zwave.configurationV1.configurationSet(configurationValue: [3], parameterNumber: 2, size: 1).format()
cmds << zwave.configurationV1.configurationSet(configurationValue: [255], parameterNumber: 5, size: 1).format()
cmds << zwave.configurationV1.configurationSet(configurationValue: [255], parameterNumber: 7, size: 1).format()
cmds << zwave.configurationV1.configurationSet(configurationValue: [1], parameterNumber: 9, size: 1).format()
cmds << zwave.configurationV1.configurationSet(configurationValue: [0,60*60], parameterNumber: 10, size: 2).format()
cmds << zwave.configurationV1.configurationSet(configurationValue: [0,50], parameterNumber: 12, size: 2).format()
cmds << zwave.configurationV1.configurationSet(configurationValue: [0], parameterNumber: 13, size: 1).format()
cmds << zwave.configurationV1.configurationSet(configurationValue: [5,220], parameterNumber: 50, size: 2).format()
cmds << zwave.configurationV1.configurationSet(configurationValue: [13,172], parameterNumber: 51, size: 2).format()
cmds << zwave.configurationV1.configurationSet(configurationValue: [0,0,0,225], parameterNumber: 61, size: 4).format()
cmds << zwave.configurationV1.configurationSet(configurationValue: [0,255,0,0], parameterNumber: 62, size: 4).format()
cmds << zwave.configurationV1.configurationSet(configurationValue: [2], parameterNumber: 63, size: 1).format()
cmds << zwave.configurationV1.configurationSet(configurationValue: [0,0], parameterNumber: 73, size: 2).format()
cmds << zwave.configurationV1.configurationSet(configurationValue: [2], parameterNumber: 74, size: 1).format()
cmds << zwave.configurationV1.configurationSet(configurationValue: [0,0], parameterNumber: 75, size: 2).format()
cmds << zwave.configurationV1.configurationSet(configurationValue: [0,0], parameterNumber: 76, size: 2).format()
cmds << zwave.configurationV1.configurationSet(configurationValue: [0], parameterNumber: 77, size: 1).format()
delayBetween(cmds, 1200)
cmds << zwave.configurationV1.configurationSet(configurationValue: [0,0], parameterNumber: 1, size: 2).format()
cmds << zwave.configurationV1.configurationSet(configurationValue: [3], parameterNumber: 2, size: 1).format()
cmds << zwave.configurationV1.configurationSet(configurationValue: [255], parameterNumber: 5, size: 1).format()
cmds << zwave.configurationV1.configurationSet(configurationValue: [255], parameterNumber: 7, size: 1).format()
cmds << zwave.configurationV1.configurationSet(configurationValue: [1], parameterNumber: 9, size: 1).format()
cmds << zwave.configurationV1.configurationSet(configurationValue: [0,60*60], parameterNumber: 10, size: 2).format()
cmds << zwave.configurationV1.configurationSet(configurationValue: [0,50], parameterNumber: 12, size: 2).format()
cmds << zwave.configurationV1.configurationSet(configurationValue: [0], parameterNumber: 13, size: 1).format()
cmds << zwave.configurationV1.configurationSet(configurationValue: [5,220], parameterNumber: 50, size: 2).format()
cmds << zwave.configurationV1.configurationSet(configurationValue: [13,172], parameterNumber: 51, size: 2).format()
cmds << zwave.configurationV1.configurationSet(configurationValue: [0,0,0,225], parameterNumber: 61, size: 4).format()
cmds << zwave.configurationV1.configurationSet(configurationValue: [0,255,0,0], parameterNumber: 62, size: 4).format()
cmds << zwave.configurationV1.configurationSet(configurationValue: [2], parameterNumber: 63, size: 1).format()
cmds << zwave.configurationV1.configurationSet(configurationValue: [0,0], parameterNumber: 73, size: 2).format()
cmds << zwave.configurationV1.configurationSet(configurationValue: [2], parameterNumber: 74, size: 1).format()
cmds << zwave.configurationV1.configurationSet(configurationValue: [0,0], parameterNumber: 75, size: 2).format()
cmds << zwave.configurationV1.configurationSet(configurationValue: [0,0], parameterNumber: 76, size: 2).format()
cmds << zwave.configurationV1.configurationSet(configurationValue: [0], parameterNumber: 77, size: 1).format()
delayBetween(cmds, 1200)
}
/**
@@ -416,25 +413,25 @@ def resetParams2StDefaults() {
def listCurrentParams() {
log.debug "Listing of current parameter settings of ${device.displayName}"
def cmds = []
cmds << zwave.configurationV1.configurationGet(parameterNumber: 1).format()
cmds << zwave.configurationV1.configurationGet(parameterNumber: 2).format()
cmds << zwave.configurationV1.configurationGet(parameterNumber: 5).format()
cmds << zwave.configurationV1.configurationGet(parameterNumber: 7).format()
cmds << zwave.configurationV1.configurationGet(parameterNumber: 9).format()
cmds << zwave.configurationV1.configurationGet(parameterNumber: 10).format()
cmds << zwave.configurationV1.configurationGet(parameterNumber: 12).format()
cmds << zwave.configurationV1.configurationGet(parameterNumber: 13).format()
cmds << zwave.configurationV1.configurationGet(parameterNumber: 50).format()
cmds << zwave.configurationV1.configurationGet(parameterNumber: 51).format()
cmds << zwave.configurationV1.configurationGet(parameterNumber: 61).format()
cmds << zwave.configurationV1.configurationGet(parameterNumber: 62).format()
cmds << zwave.configurationV1.configurationGet(parameterNumber: 63).format()
cmds << zwave.configurationV1.configurationGet(parameterNumber: 73).format()
cmds << zwave.configurationV1.configurationGet(parameterNumber: 74).format()
cmds << zwave.configurationV1.configurationGet(parameterNumber: 75).format()
cmds << zwave.configurationV1.configurationGet(parameterNumber: 76).format()
cmds << zwave.configurationV1.configurationGet(parameterNumber: 77).format()
cmds << zwave.configurationV1.configurationGet(parameterNumber: 1).format()
cmds << zwave.configurationV1.configurationGet(parameterNumber: 2).format()
cmds << zwave.configurationV1.configurationGet(parameterNumber: 5).format()
cmds << zwave.configurationV1.configurationGet(parameterNumber: 7).format()
cmds << zwave.configurationV1.configurationGet(parameterNumber: 9).format()
cmds << zwave.configurationV1.configurationGet(parameterNumber: 10).format()
cmds << zwave.configurationV1.configurationGet(parameterNumber: 12).format()
cmds << zwave.configurationV1.configurationGet(parameterNumber: 13).format()
cmds << zwave.configurationV1.configurationGet(parameterNumber: 50).format()
cmds << zwave.configurationV1.configurationGet(parameterNumber: 51).format()
cmds << zwave.configurationV1.configurationGet(parameterNumber: 61).format()
cmds << zwave.configurationV1.configurationGet(parameterNumber: 62).format()
cmds << zwave.configurationV1.configurationGet(parameterNumber: 63).format()
cmds << zwave.configurationV1.configurationGet(parameterNumber: 73).format()
cmds << zwave.configurationV1.configurationGet(parameterNumber: 74).format()
cmds << zwave.configurationV1.configurationGet(parameterNumber: 75).format()
cmds << zwave.configurationV1.configurationGet(parameterNumber: 76).format()
cmds << zwave.configurationV1.configurationGet(parameterNumber: 77).format()
delayBetween(cmds, 1200)
}

View File

@@ -46,7 +46,6 @@
capability "Illuminance Measurement"
capability "Sensor"
capability "Battery"
capability "Health Check"
command "resetParams2StDefaults"
command "listCurrentParams"
@@ -82,8 +81,8 @@
tiles {
standardTile("motion", "device.motion", width: 2, height: 2) {
state "active", label:'motion', icon:"st.motion.motion.active", backgroundColor:"#00a0dc"
state "inactive", label:'no motion', icon:"st.motion.motion.inactive", backgroundColor:"#cccccc"
state "active", label:'motion', icon:"st.motion.motion.active", backgroundColor:"#53a7c0"
state "inactive", label:'no motion', icon:"st.motion.motion.inactive", backgroundColor:"#ffffff"
}
valueTile("temperature", "device.temperature", inactiveLabel: false) {
state "temperature", label:'${currentValue}°',
@@ -126,9 +125,6 @@
*/
def configure() {
log.debug "Configuring Device For SmartThings Use"
// Device-Watch simply pings if no device events received for 8 hrs & 2 minutes
sendEvent(name: "checkInterval", value: 8 * 60 * 60 + 2 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID])
def cmds = []
// send associate to group 3 to get sensor data reported only to hub

View File

@@ -1,2 +0,0 @@
.st-ignore
README.md

View File

@@ -1,39 +0,0 @@
# FortrezZ Water Valve
Cloud Execution
Works with:
* [FortrezZ Water Valve](https://www.smartthings.com/works-with-smartthings/other/fortrezz-water-valve)
## Table of contents
* [Capabilities](#capabilities)
* [Health](#device-health)
* [Troubleshooting](#troubleshooting)
## Capabilities
* **Actuator** - represents that a Device has commands
* **Health Check** - indicates ability to get device health notifications
* **Valve** - allows for the control of a valve device
* **Refresh** - _refresh()_ command for status updates
* **Sensor** - detects sensor events
## Device Health
FortrezZ Water Valve is polled by the hub.
As of hubCore version 0.14.38 the hub sends up reports every 15 minutes regardless of whether the state changed.
Device-Watch allows 2 check-in misses from device plus some lag time. So Check-in interval = (2*15 + 2)mins = 32 mins.
Not to mention after going OFFLINE when the device is plugged back in, it might take a considerable amount of time for
the device to appear as ONLINE again. This is because if this listening device does not respond to two poll requests in a row,
it is not polled for 5 minutes by the hub. This can delay up the process of being marked ONLINE by quite some time.
* __32min__ checkInterval
## Troubleshooting
If the device doesn't pair when trying from the SmartThings mobile app, it is possible that the device is out of range.
Pairing needs to be tried again by placing the device closer to the hub.
Instructions related to pairing, resetting and removing the device from SmartThings can be found in the following link:
* [FortrezZ Water Valve Troubleshooting Tips](https://support.smartthings.com/hc/en-us/articles/202088434-FortrezZ-Water-Valve-Shutoff)

View File

@@ -14,13 +14,11 @@
metadata {
definition (name: "Fortrezz Water Valve", namespace: "smartthings", author: "SmartThings") {
capability "Actuator"
capability "Health Check"
capability "Valve"
capability "Refresh"
capability "Sensor"
fingerprint deviceId: "0x1000", inClusters: "0x25,0x72,0x86,0x71,0x22,0x70"
fingerprint mfr:"0084", prod:"0213", model:"0215", deviceJoinName: "FortrezZ Water Valve"
}
// simulator metadata
@@ -50,11 +48,6 @@ metadata {
}
}
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])
}
def parse(String description) {
log.trace description
def result = null
@@ -83,13 +76,6 @@ def close() {
zwave.switchBinaryV1.switchBinarySet(switchValue: 0xFF).format()
}
/**
* PING is used by Device-Watch in attempt to reach the Device
* */
def ping() {
refresh()
}
def refresh() {
zwave.switchBinaryV1.switchBinaryGet().format()
}

View File

@@ -39,8 +39,8 @@ metadata {
tiles {
standardTile("motion", "device.motion", width: 2, height: 2) {
state "active", label:'motion', icon:"st.motion.motion.active", backgroundColor:"#00A0DC"
state "inactive", label:'no motion', icon:"st.motion.motion.inactive", backgroundColor:"#cccccc"
state "active", label:'motion', icon:"st.motion.motion.active", backgroundColor:"#53a7c0"
state "inactive", label:'no motion', icon:"st.motion.motion.inactive", backgroundColor:"#ffffff"
}
valueTile("temperature", "device.temperature", inactiveLabel: false) {
state "temperature", label:'${currentValue}°',

View File

@@ -21,7 +21,6 @@ metadata {
capability "Configuration"
capability "Battery"
capability "Refresh"
capability "Sensor"
command "enrollResponse"
@@ -32,8 +31,8 @@ metadata {
tiles {
standardTile("motion", "device.motion", width: 2, height: 2) {
state("active", label:'motion', icon:"st.motion.motion.active", backgroundColor:"#00A0DC")
state("inactive", label:'no motion', icon:"st.motion.motion.inactive", backgroundColor:"#cccccc")
state("active", label:'motion', icon:"st.motion.motion.active", backgroundColor:"#53a7c0")
state("inactive", label:'no motion', icon:"st.motion.motion.inactive", backgroundColor:"#ffffff")
}
valueTile("battery", "device.battery", decoration: "flat", inactiveLabel: false) {

View File

@@ -24,7 +24,6 @@ metadata {
capability "Contact Sensor"
capability "Refresh"
capability "Health Check"
capability "Sensor"
command "enrollResponse"
@@ -42,8 +41,8 @@ metadata {
tiles {
standardTile("contact", "device.contact", width: 2, height: 2) {
state("open", label:'${name}', icon:"st.contact.contact.open", backgroundColor:"#e86d13")
state("closed", label:'${name}', icon:"st.contact.contact.closed", backgroundColor:"#00a0dc")
state("open", label:'${name}', icon:"st.contact.contact.open", backgroundColor:"#ffa81e")
state("closed", label:'${name}', icon:"st.contact.contact.closed", backgroundColor:"#79b821")
}
valueTile("battery", "device.battery", decoration: "flat", inactiveLabel: false) {

View File

@@ -33,7 +33,6 @@ metadata {
fingerprint inClusters: "0000,0001,0003,0402,0500,0020,0B05", outClusters: "0019", manufacturer: "CentraLite", model: "3315"
fingerprint inClusters: "0000,0001,0003,0402,0500,0020,0B05", outClusters: "0019", manufacturer: "CentraLite", model: "3315-Seu", deviceJoinName: "Water Leak Sensor"
fingerprint inClusters: "0000,0001,0003,0020,0402,0500,0B05", outClusters: "0019", manufacturer: "CentraLite", model: "3315-L", deviceJoinName: "Iris Smart Water Sensor"
fingerprint inClusters: "0000,0001,0003,0020,0402,0500,0B05", outClusters: "0019", manufacturer: "CentraLite", model: "3315-G", deviceJoinName: "Centralite Water Sensor"
fingerprint inClusters: "0000,0001,0003,000F,0020,0402,0500", outClusters: "0019", manufacturer: "SmartThings", model: "moisturev4", deviceJoinName: "Water Leak Sensor"
}
@@ -59,7 +58,7 @@ metadata {
multiAttributeTile(name: "water", type: "generic", width: 6, height: 4) {
tileAttribute("device.water", key: "PRIMARY_CONTROL") {
attributeState "dry", label: "Dry", icon: "st.alarm.water.dry", backgroundColor: "#ffffff"
attributeState "wet", label: "Wet", icon: "st.alarm.water.wet", backgroundColor: "#00A0DC"
attributeState "wet", label: "Wet", icon: "st.alarm.water.wet", backgroundColor: "#53a7c0"
}
}
valueTile("temperature", "device.temperature", inactiveLabel: false, width: 2, height: 2) {
@@ -107,12 +106,6 @@ def parse(String description) {
}
}
}
} else if (map.name == "temperature") {
if (tempOffset) {
map.value = (int) map.value + (int) tempOffset
}
map.descriptionText = temperatureScale == 'C' ? '{{ device.displayName }} was {{ value }}°C' : '{{ device.displayName }} was {{ value }}°F'
map.translatable = true
}
log.debug "Parse returned $map"

View File

@@ -34,7 +34,6 @@ metadata {
fingerprint inClusters: "0000,0001,0003,0402,0500,0020,0B05", outClusters: "0019", manufacturer: "CentraLite", model: "3325"
fingerprint inClusters: "0000,0001,0003,0402,0500,0020,0B05", outClusters: "0019", manufacturer: "CentraLite", model: "3326"
fingerprint inClusters: "0000,0001,0003,0402,0500,0020,0B05", outClusters: "0019", manufacturer: "CentraLite", model: "3326-L", deviceJoinName: "Iris Motion Sensor"
fingerprint inClusters: "0000,0001,0003,0020,0402,0500,0B05", outClusters: "0019", manufacturer: "CentraLite", model: "3328-G", deviceJoinName: "Centralite Micro Motion Sensor"
fingerprint inClusters: "0000,0001,0003,000F,0020,0402,0500", outClusters: "0019", manufacturer: "SmartThings", model: "motionv4", deviceJoinName: "Motion Sensor"
fingerprint inClusters: "0000,0001,0003,000F,0020,0402,0500", outClusters: "0019", manufacturer: "SmartThings", model: "motionv5", deviceJoinName: "Motion Sensor"
}
@@ -113,12 +112,6 @@ def parse(String description) {
map = getMotionResult(value)
}
}
} else if (map.name == "temperature") {
if (tempOffset) {
map.value = (int) map.value + (int) tempOffset
}
map.descriptionText = temperatureScale == 'C' ? '{{ device.displayName }} was {{ value }}°C' : '{{ device.displayName }} was {{ value }}°F'
map.translatable = true
}
log.debug "Parse returned $map"

View File

@@ -30,8 +30,8 @@ metadata {
tiles(scale: 2) {
multiAttributeTile(name:"motion", type: "generic", width: 6, height: 4){
tileAttribute ("device.motion", key: "PRIMARY_CONTROL") {
attributeState "active", label:'motion', icon:"st.motion.motion.active", backgroundColor:"#00A0DC"
attributeState "inactive", label:'no motion', icon:"st.motion.motion.inactive", backgroundColor:"#cccccc"
attributeState "active", label:'motion', icon:"st.motion.motion.active", backgroundColor:"#53a7c0"
attributeState "inactive", label:'no motion', icon:"st.motion.motion.inactive", backgroundColor:"#ffffff"
}
}
valueTile("battery", "device.battery", decoration: "flat", inactiveLabel: false, width: 2, height: 2) {

View File

@@ -33,7 +33,6 @@ metadata {
fingerprint inClusters: "0000,0001,0003,0402,0500,0020,0B05,FC02", outClusters: "0019", manufacturer: "CentraLite", model: "3320"
fingerprint inClusters: "0000,0001,0003,0402,0500,0020,0B05,FC02", outClusters: "0019", manufacturer: "CentraLite", model: "3321"
fingerprint inClusters: "0000,0001,0003,0402,0500,0020,0B05,FC02", outClusters: "0019", manufacturer: "CentraLite", model: "3321-S", deviceJoinName: "Multipurpose Sensor"
fingerprint inClusters: "0000,0001,0003,0020,0402,0500,0B05", outClusters: "0019", manufacturer: "CentraLite", model: "3323-G", deviceJoinName: "Centralite Micro Door Sensor"
fingerprint inClusters: "0000,0001,0003,000F,0020,0402,0500,FC02", outClusters: "0019", manufacturer: "SmartThings", model: "multiv4", deviceJoinName: "Multipurpose Sensor"
attribute "status", "string"

View File

@@ -52,14 +52,14 @@ metadata {
tiles(scale: 2) {
multiAttributeTile(name:"contact", type: "generic", width: 6, height: 4){
tileAttribute ("device.contact", key: "PRIMARY_CONTROL") {
attributeState "open", label:'${name}', icon:"st.contact.contact.open", backgroundColor:"#e86d13"
attributeState "closed", label:'${name}', icon:"st.contact.contact.closed", backgroundColor:"#00a0dc"
attributeState "open", label:'${name}', icon:"st.contact.contact.open", backgroundColor:"#ffa81e"
attributeState "closed", label:'${name}', icon:"st.contact.contact.closed", backgroundColor:"#79b821"
}
}
standardTile("acceleration", "device.acceleration", width: 2, height: 2) {
state("active", label:'${name}', icon:"st.motion.acceleration.active", backgroundColor:"#00a0dc")
state("inactive", label:'${name}', icon:"st.motion.acceleration.inactive", backgroundColor:"#cccccc")
state("active", label:'${name}', icon:"st.motion.acceleration.active", backgroundColor:"#53a7c0")
state("inactive", label:'${name}', icon:"st.motion.acceleration.inactive", backgroundColor:"#ffffff")
}
valueTile("temperature", "device.temperature", width: 2, height: 2) {
state("temperature", label:'${currentValue}°',

View File

@@ -45,8 +45,8 @@ metadata {
tiles(scale: 2) {
multiAttributeTile(name: "contact", type: "generic", width: 6, height: 4) {
tileAttribute("device.contact", key: "PRIMARY_CONTROL") {
attributeState "open", label: '${name}', icon: "st.contact.contact.open", backgroundColor: "#e86d13"
attributeState "closed", label: '${name}', icon: "st.contact.contact.closed", backgroundColor: "#00A0DC"
attributeState "open", label: '${name}', icon: "st.contact.contact.open", backgroundColor: "#ffa81e"
attributeState "closed", label: '${name}', icon: "st.contact.contact.closed", backgroundColor: "#79b821"
}
}
@@ -95,12 +95,6 @@ def parse(String description) {
}
}
}
} else if (map.name == "temperature") {
if (tempOffset) {
map.value = (int) map.value + (int) tempOffset
}
map.descriptionText = temperatureScale == 'C' ? '{{ device.displayName }} was {{ value }}°C' : '{{ device.displayName }} was {{ value }}°F'
map.translatable = true
}
log.debug "Parse returned $map"

View File

@@ -88,12 +88,6 @@ def parse(String description) {
log.warn "TEMP REPORTING CONFIG FAILED- error code: ${descMap.data[0]}"
}
}
} else if (map.name == "temperature") {
if (tempOffset) {
map.value = (int) map.value + (int) tempOffset
}
map.descriptionText = temperatureScale == 'C' ? '{{ device.displayName }} was {{ value }}°C' : '{{ device.displayName }} was {{ value }}°F'
map.translatable = true
}
log.debug "Parse returned $map"

View File

@@ -41,8 +41,8 @@ metadata {
tiles {
standardTile("contact", "device.contact", width: 2, height: 2) {
state("open", label:'${name}', icon:"st.contact.contact.open", backgroundColor:"#e86d13")
state("closed", label:'${name}', icon:"st.contact.contact.closed", backgroundColor:"#00A0DC")
state("open", label:'${name}', icon:"st.contact.contact.open", backgroundColor:"#ffa81e")
state("closed", label:'${name}', icon:"st.contact.contact.closed", backgroundColor:"#79b821")
}
valueTile("temperature", "device.temperature", inactiveLabel: false) {

View File

@@ -44,7 +44,7 @@ metadata {
tiles {
standardTile("button", "device.button", width: 2, height: 2) {
state "default", label: "", icon: "st.unknown.zwave.remote-controller", backgroundColor: "#ffffff"
state "button 1 pushed", label: "pushed #1", icon: "st.unknown.zwave.remote-controller", backgroundColor: "#00A0DC"
state "button 1 pushed", label: "pushed #1", icon: "st.unknown.zwave.remote-controller", backgroundColor: "#79b821"
}
valueTile("battery", "device.battery", decoration: "flat", inactiveLabel: false) {

View File

@@ -1,169 +0,0 @@
/**
* Copyright 2016 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.
*
*/
import groovy.transform.Field
@Field Boolean hasConfiguredHealthCheck = false
metadata {
definition (name: "ZLL White Color Temperature Bulb 5000K", namespace: "smartthings", author: "SmartThings") {
capability "Actuator"
capability "Color Temperature"
capability "Configuration"
capability "Polling"
capability "Refresh"
capability "Switch"
capability "Switch Level"
capability "Health Check"
attribute "colorName", "string"
command "setGenericName"
fingerprint profileId: "C05E", deviceId: "0220", inClusters: "0000, 0004, 0003, 0006, 0008, 0005, 0300", outClusters: "0019", manufacturer: "Eaton", model: "Halo_LT01", deviceJoinName: "Halo RL56 Wireless"
}
// UI tile definitions
tiles(scale: 2) {
multiAttributeTile(name:"switch", type: "lighting", width: 6, height: 4, canChangeIcon: true){
tileAttribute ("device.switch", key: "PRIMARY_CONTROL") {
attributeState "on", label:'${name}', action:"switch.off", icon:"st.switches.light.on", backgroundColor:"#00A0DC", nextState:"turningOff"
attributeState "off", label:'${name}', action:"switch.on", icon:"st.switches.light.off", backgroundColor:"#ffffff", nextState:"turningOn"
attributeState "turningOn", label:'${name}', action:"switch.off", icon:"st.switches.light.on", backgroundColor:"#00A0DC", nextState:"turningOff"
attributeState "turningOff", label:'${name}', action:"switch.on", icon:"st.switches.light.off", backgroundColor:"#ffffff", nextState:"turningOn"
}
tileAttribute ("device.level", key: "SLIDER_CONTROL") {
attributeState "level", action:"switch level.setLevel"
}
tileAttribute ("colorName", key: "SECONDARY_CONTROL") {
attributeState "colorName", label:'${currentValue}'
}
}
standardTile("refresh", "device.refresh", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
state "default", label:"", action:"refresh.refresh", icon:"st.secondary.refresh"
}
controlTile("colorTempSliderControl", "device.colorTemperature", "slider", width: 4, height: 2, inactiveLabel: false, range:"(2700..5000)") {
state "colorTemperature", action:"color temperature.setColorTemperature"
}
valueTile("colorTemp", "device.colorTemperature", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
state "colorTemperature", label: '${currentValue} K'
}
main(["switch"])
details(["switch", "colorTempSliderControl", "colorTemp", "refresh"])
}
}
// Parse incoming device messages to generate events
def parse(String description) {
log.debug "description is $description"
def event = zigbee.getEvent(description)
if (event) {
if (event.name == "colorTemperature") {
event.unit = "K"
}
sendEvent(event)
}
else {
log.warn "DID NOT PARSE MESSAGE for description : $description"
log.debug zigbee.parseDescriptionAsMap(description)
}
}
def off() {
zigbee.off() + ["delay 1500"] + zigbee.onOffRefresh()
}
def on() {
zigbee.on() + ["delay 1500"] + zigbee.onOffRefresh()
}
def setLevel(value) {
zigbee.setLevel(value) + zigbee.onOffRefresh() + zigbee.levelRefresh()
}
def refresh() {
def cmds = zigbee.onOffRefresh() + zigbee.levelRefresh() + zigbee.colorTemperatureRefresh()
// Do NOT config if the device is the Eaton Halo_LT01, it responds with "switch:off" to onOffConfig, and maybe other weird things with the others
if (!((device.getDataValue("manufacturer") == "Eaton") && (device.getDataValue("model") == "Halo_LT01"))) {
cmds = cmds + zigbee.onOffConfig() + zigbee.levelConfig() + zigbee.colorTemperatureConfig()
}
cmds
}
def poll() {
zigbee.onOffRefresh() + zigbee.levelRefresh() + zigbee.colorTemperatureRefresh()
}
/**
* PING is used by Device-Watch in attempt to reach the Device
* */
def ping() {
return zigbee.levelRefresh()
}
def healthPoll() {
log.debug "healthPoll()"
def cmds = zigbee.onOffRefresh() + zigbee.levelRefresh()
cmds.each{ sendHubCommand(new physicalgraph.device.HubAction(it))}
}
def configureHealthCheck() {
Integer hcIntervalMinutes = 12
if (!hasConfiguredHealthCheck) {
log.debug "Configuring Health Check, Reporting"
unschedule("healthPoll")
runEvery5Minutes("healthPoll")
// Device-Watch allows 2 check-in misses from device
sendEvent(name: "checkInterval", value: hcIntervalMinutes * 60, displayed: false, data: [protocol: "zigbee", hubHardwareId: device.hub.hardwareID])
hasConfiguredHealthCheck = true
}
}
def configure() {
log.debug "configure()"
configureHealthCheck()
// Implementation note: for the Eaton Halo_LT01, it responds with "switch:off" to onOffConfig, so be sure this is before the call to onOffRefresh
zigbee.onOffConfig() + zigbee.levelConfig() + zigbee.colorTemperatureConfig() + zigbee.onOffRefresh() + zigbee.levelRefresh() + zigbee.colorTemperatureRefresh()
}
def updated() {
log.debug "updated()"
configureHealthCheck()
}
def setColorTemperature(value) {
setGenericName(value)
zigbee.setColorTemperature(value) + ["delay 1500"] + zigbee.colorTemperatureRefresh()
}
//Naming based on the wiki article here: http://en.wikipedia.org/wiki/Color_temperature
def setGenericName(value){
if (value != null) {
def genericName = ""
if (value < 3300) {
genericName = "Soft White"
} else if (value < 4150) {
genericName = "Moonlight"
} else if (value <= 5000) {
genericName = "Cool White"
} else {
genericName = "Daylight"
}
sendEvent(name: "colorName", value: genericName, displayed: false)
}
}

View File

@@ -40,7 +40,7 @@ metadata {
tiles {
standardTile("switch", "device.switch", width: 2, height: 2, canChangeIcon: true) {
state "on", label: '${name}', action: "switch.off", icon: "st.unknown.zwave.device", backgroundColor: "#00A0DC"
state "on", label: '${name}', action: "switch.off", icon: "st.unknown.zwave.device", backgroundColor: "#79b821"
state "off", label: '${name}', action: "switch.on", icon: "st.unknown.zwave.device", backgroundColor: "#ffffff"
}
standardTile("switchOn", "device.switch", inactiveLabel: false, decoration: "flat") {

View File

@@ -33,7 +33,7 @@ metadata {
tiles {
standardTile("switch", "device.switch", width: 2, height: 2, canChangeIcon: true) {
state "on", label: '${name}', action: "switch.off", icon: "st.unknown.zwave.device", backgroundColor: "#00A0DC"
state "on", label: '${name}', action: "switch.off", icon: "st.unknown.zwave.device", backgroundColor: "#79b821"
state "off", label: '${name}', action: "switch.on", icon: "st.unknown.zwave.device", backgroundColor: "#ffffff"
}
standardTile("switchOn", "device.switch", inactiveLabel: false, decoration: "flat") {

View File

@@ -41,8 +41,8 @@ metadata {
// UI tile definitions
tiles {
standardTile("contact", "device.contact", width: 2, height: 2) {
state "open", label: '${name}', icon: "st.contact.contact.open", backgroundColor: "#e86d13"
state "closed", label: '${name}', icon: "st.contact.contact.closed", backgroundColor: "#00A0DC"
state "open", label: '${name}', icon: "st.contact.contact.open", backgroundColor: "#ffa81e"
state "closed", label: '${name}', icon: "st.contact.contact.closed", backgroundColor: "#79b821"
}
valueTile("battery", "device.battery", inactiveLabel: false, decoration: "flat") {
state "battery", label:'${currentValue}% battery', unit:""

View File

@@ -1,2 +0,0 @@
.st-ignore
README.md

View File

@@ -1,41 +0,0 @@
# Z-wave Garage Door Opener
Cloud Execution
Works with:
* [Linear GoControl Garage Door Opener](https://www.smartthings.com/works-with-smartthings/other/linear-gocontrol-garage-door-opener)
## Table of contents
* [Capabilities](#capabilities)
* [Health](#device-health)
* [Troubleshooting](#troubleshooting)
## Capabilities
* **Actuator** - represents that a Device has commands
* **Door Control** - allow for the control of a door
* **Garage Door Control** - allow for the control of a garage door
* **Health Check** - indicates ability to get device health notifications
* **Contact Sensor** - can detect contact (with possible values - open/closed)
* **Refresh** - _refresh()_ command for status updates
* **Sensor** - detects sensor events
## Device Health
Linear GoControl Garage Door Opener is polled by the hub.
As of hubCore version 0.14.38 the hub sends up reports every 15 minutes regardless of whether the state changed.
Device-Watch allows 2 check-in misses from device plus some lag time. So Check-in interval = (2*15 + 2)mins = 32 mins.
Not to mention after going OFFLINE when the device is plugged back in, it might take a considerable amount of time for
the device to appear as ONLINE again. This is because if this listening device does not respond to two poll requests in a row,
it is not polled for 5 minutes by the hub. This can delay up the process of being marked ONLINE by quite some time.
* __32min__ checkInterval
## Troubleshooting
If the device doesn't pair when trying from the SmartThings mobile app, it is possible that the device is out of range.
Pairing needs to be tried again by placing the device closer to the hub.
Instructions related to pairing, resetting and removing the device from SmartThings can be found in the following link:
* [Linear GoControl Garage Door Opener Troubleshooting Tips](https://support.smartthings.com/hc/en-us/articles/204831116-GoControl-Linear-Garage-Door-Opener-GD00Z-4-)

View File

@@ -18,14 +18,12 @@ metadata {
capability "Actuator"
capability "Door Control"
capability "Garage Door Control"
capability "Health Check"
capability "Contact Sensor"
capability "Refresh"
capability "Sensor"
fingerprint deviceId: "0x4007", inClusters: "0x98"
fingerprint deviceId: "0x4006", inClusters: "0x98"
fingerprint mfr:"014F", prod:"4744", model:"3030", deviceJoinName: "Linear GoControl Garage Door Opener"
}
simulator {
@@ -41,11 +39,11 @@ metadata {
tiles {
standardTile("toggle", "device.door", width: 2, height: 2) {
state("unknown", label:'${name}', action:"refresh.refresh", icon:"st.doors.garage.garage-open", backgroundColor:"#ffffff")
state("closed", label:'${name}', action:"door control.open", icon:"st.doors.garage.garage-closed", backgroundColor:"#00a0dc", nextState:"opening")
state("open", label:'${name}', action:"door control.close", icon:"st.doors.garage.garage-open", backgroundColor:"#e86d13", nextState:"closing")
state("opening", label:'${name}', icon:"st.doors.garage.garage-opening", backgroundColor:"#e86d13")
state("closing", label:'${name}', icon:"st.doors.garage.garage-closing", backgroundColor:"#00a0dc")
state("unknown", label:'${name}', action:"refresh.refresh", icon:"st.doors.garage.garage-open", backgroundColor:"#ffa81e")
state("closed", label:'${name}', action:"door control.open", icon:"st.doors.garage.garage-closed", backgroundColor:"#79b821", nextState:"opening")
state("open", label:'${name}', action:"door control.close", icon:"st.doors.garage.garage-open", backgroundColor:"#ffa81e", nextState:"closing")
state("opening", label:'${name}', icon:"st.doors.garage.garage-opening", backgroundColor:"#ffe71e")
state("closing", label:'${name}', icon:"st.doors.garage.garage-closing", backgroundColor:"#ffe71e")
}
standardTile("open", "device.door", inactiveLabel: false, decoration: "flat") {
@@ -65,11 +63,6 @@ metadata {
import physicalgraph.zwave.commands.barrieroperatorv1.*
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])
}
def parse(String description) {
def result = null
if (description.startsWith("Err")) {
@@ -294,13 +287,6 @@ def close() {
secure(zwave.barrierOperatorV1.barrierOperatorSet(requestedBarrierState: BarrierOperatorSet.REQUESTED_BARRIER_STATE_CLOSE))
}
/**
* PING is used by Device-Watch in attempt to reach the Device
* */
def ping() {
refresh()
}
def refresh() {
secure(zwave.barrierOperatorV1.barrierOperatorGet())
}

View File

@@ -1,2 +0,0 @@
.st-ignore
README.md

View File

@@ -1,45 +0,0 @@
# Z-Wave Switch
Cloud Execution
Works with:
* [Yale Key Free Touchscreen Deadbolt (YRD240)](https://www.smartthings.com/works-with-smartthings/yale/yale-key-free-touchscreen-deadbolt-yrd240)
## Table of contents
* [Capabilities](#capabilities)
* [Health](#device-health)
* [Troubleshooting](#Troubleshooting)
## Capabilities
* **Actuator** - represents that a Device has commands
* **Battery** - defines device uses a battery
* **Lock** - allows for the control of a lock device
* **Lock Codes** - allows for the lock code control of a lock device
* **Polling** - represents that poll() can be implemented for the device
* **Refresh** - _refresh()_ command for status updates
* **Sensor** - detects sensor events
* **Health Check** - indicates ability to get device health notifications
## Device Health
Z-Wave Locks are polled by the hub.
As of hubCore version 0.14.38 the hub sends up reports every 15 minutes regardless of whether the state changed.
Device-Watch allows 2 check-in misses from device plus some lag time. So Check-in interval = (2*15 + 2)mins = 32 mins.
Not to mention after going OFFLINE when the device is plugged back in, it might take a considerable amount of time for
the device to appear as ONLINE again. This is because if this listening device does not respond to two poll requests in a row,
it is not polled for 5 minutes by the hub. This can delay up the process of being marked ONLINE by quite some time.
* __32min__ checkInterval
## Troubleshooting
If the device doesn't pair when trying from the SmartThings mobile app, it is possible that the device is out of range.
Pairing needs to be tried again by placing the device closer to the hub.
Instructions related to pairing, resetting and removing the device from SmartThings can be found in the following link:
* [General Z-Wave/ZigBee Yale Lock Troubleshooting](https://support.smartthings.com/hc/en-us/articles/205138400-How-to-connect-Yale-locks)

View File

@@ -20,13 +20,11 @@ metadata {
capability "Sensor"
capability "Lock Codes"
capability "Battery"
capability "Health Check"
command "unlockwtimeout"
fingerprint deviceId: "0x4003", inClusters: "0x98"
fingerprint deviceId: "0x4004", inClusters: "0x98"
fingerprint mfr:"0129", prod:"0002", model:"0000", deviceJoinName: "Yale Key Free Touchscreen Deadbolt"
}
simulator {
@@ -40,10 +38,10 @@ metadata {
tiles(scale: 2) {
multiAttributeTile(name:"toggle", type: "generic", width: 6, height: 4){
tileAttribute ("device.lock", key: "PRIMARY_CONTROL") {
attributeState "locked", label:'locked', action:"lock.unlock", icon:"st.locks.lock.locked", backgroundColor:"#00A0DC", nextState:"unlocking"
attributeState "locked", label:'locked', action:"lock.unlock", icon:"st.locks.lock.locked", backgroundColor:"#79b821", nextState:"unlocking"
attributeState "unlocked", label:'unlocked', action:"lock.lock", icon:"st.locks.lock.unlocked", backgroundColor:"#ffffff", nextState:"locking"
attributeState "unknown", label:"unknown", action:"lock.lock", icon:"st.locks.lock.unknown", backgroundColor:"#ffffff", nextState:"locking"
attributeState "locking", label:'locking', icon:"st.locks.lock.locked", backgroundColor:"#00A0DC"
attributeState "locking", label:'locking', icon:"st.locks.lock.locked", backgroundColor:"#79b821"
attributeState "unlocking", label:'unlocking', icon:"st.locks.lock.unlocked", backgroundColor:"#ffffff"
}
}
@@ -69,8 +67,6 @@ import physicalgraph.zwave.commands.doorlockv1.*
import physicalgraph.zwave.commands.usercodev1.*
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])
try {
if (!state.init) {
state.init = true
@@ -508,13 +504,6 @@ 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()
}
def refresh() {
def cmds = [secure(zwave.doorLockV1.doorLockOperationGet())]
if (state.assoc == zwaveHubNodeId) {

View File

@@ -22,12 +22,10 @@ metadata {
capability "Configuration"
capability "Sensor"
capability "Light"
capability "Health Check"
command "reset"
fingerprint inClusters: "0x25,0x32"
fingerprint mfr:"0086", prod:"0003", model:"0012", deviceJoinName: "Aeon Labs Micro Smart Switch 2E"
}
// simulator metadata
@@ -53,7 +51,7 @@ metadata {
// tile definitions
tiles {
standardTile("switch", "device.switch", width: 2, height: 2, canChangeIcon: true) {
state "on", label: '${name}', action: "switch.off", icon: "st.switches.switch.on", backgroundColor: "#00A0DC"
state "on", label: '${name}', action: "switch.off", icon: "st.switches.switch.on", backgroundColor: "#79b821"
state "off", label: '${name}', action: "switch.on", icon: "st.switches.switch.off", backgroundColor: "#ffffff"
}
valueTile("power", "device.power") {
@@ -75,8 +73,6 @@ metadata {
}
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])
try {
if (!state.MSR) {
response(zwave.manufacturerSpecificV2.manufacturerSpecificGet().format())
@@ -183,14 +179,6 @@ def poll() {
])
}
/**
* PING is used by Device-Watch in attempt to reach the Device
* */
def ping() {
log.debug "ping() called"
refresh()
}
def refresh() {
delayBetween([
zwave.switchBinaryV1.switchBinaryGet().format(),

View File

@@ -38,8 +38,8 @@ metadata {
tiles {
standardTile("motion", "device.motion", width: 2, height: 2) {
state("active", label:'motion', icon:"st.motion.motion.active", backgroundColor:"#00A0DC")
state("inactive", label:'no motion', icon:"st.motion.motion.inactive", backgroundColor:"#cccccc")
state("active", label:'motion', icon:"st.motion.motion.active", backgroundColor:"#53a7c0")
state("inactive", label:'no motion', icon:"st.motion.motion.inactive", backgroundColor:"#ffffff")
}
valueTile("battery", "device.battery", inactiveLabel: false, decoration: "flat") {
state("battery", label:'${currentValue}% battery', unit:"")

View File

@@ -37,8 +37,8 @@ metadata {
tiles(scale: 2) {
multiAttributeTile(name:"contact", type: "generic", width: 6, height: 4){
tileAttribute ("device.contact", key: "PRIMARY_CONTROL") {
attributeState "open", label:'${name}', icon:"st.contact.contact.open", backgroundColor:"#e86d13"
attributeState "closed", label:'${name}', icon:"st.contact.contact.closed", backgroundColor:"#00a0dc"
attributeState "open", label:'${name}', icon:"st.contact.contact.open", backgroundColor:"#ffa81e"
attributeState "closed", label:'${name}', icon:"st.contact.contact.closed", backgroundColor:"#79b821"
}
}
valueTile("battery", "device.battery", decoration: "flat", inactiveLabel: false, width: 2, height: 2) {

View File

@@ -32,8 +32,8 @@ metadata {
tiles {
standardTile("sensor", "device.sensor", width: 2, height: 2) {
state("inactive", label:'inactive', icon:"st.unknown.zwave.sensor", backgroundColor:"#cccccc")
state("active", label:'active', icon:"st.unknown.zwave.sensor", backgroundColor:"#00A0DC")
state("inactive", label:'inactive', icon:"st.unknown.zwave.sensor", backgroundColor:"#ffffff")
state("active", label:'active', icon:"st.unknown.zwave.sensor", backgroundColor:"#53a7c0")
}
valueTile("battery", "device.battery", inactiveLabel: false, decoration: "flat") {
state "battery", label:'${currentValue}% battery', unit:""

View File

@@ -1,2 +0,0 @@
.st-ignore
README.md

View File

@@ -1,42 +0,0 @@
# Z-wave Siren
Cloud Execution
Works with:
* [FortrezZ Siren Strobe Alarm](https://www.smartthings.com/works-with-smartthings/other/fortrezz-water-valve)
## Table of contents
* [Capabilities](#capabilities)
* [Health](#device-health)
* [Troubleshooting](#troubleshooting)
## Capabilities
* **Actuator** - represents that a Device has commands
* **Alarm** - allows for interacting with devices that serve as alarms
* **Battery** - defines device uses a battery
* **Health Check** - indicates ability to get device health notifications
* **Polling** - represents that poll() can be implemented for the device
* **Refresh** - _refresh()_ command for status updates
* **Sensor** - detects sensor events
* **Switch** - can detect state (possible values: on/off)
## Device Health
FortrezZ Siren Strobe Alarm is polled by the hub.
As of hubCore version 0.14.38 the hub sends up reports every 15 minutes regardless of whether the state changed.
Device-Watch allows 2 check-in misses from device plus some lag time. So Check-in interval = (2*15 + 2)mins = 32 mins.
Not to mention after going OFFLINE when the device is plugged back in, it might take a considerable amount of time for
the device to appear as ONLINE again. This is because if this listening device does not respond to two poll requests in a row,
it is not polled for 5 minutes by the hub. This can delay up the process of being marked ONLINE by quite some time.
* __32min__ checkInterval
## Troubleshooting
If the device doesn't pair when trying from the SmartThings mobile app, it is possible that the device is out of range.
Pairing needs to be tried again by placing the device closer to the hub.
Instructions related to pairing, resetting and removing the device from SmartThings can be found in the following link:
* [FortrezZ Siren Strobe Alarm Troubleshooting Tips](https://support.smartthings.com/hc/en-us/articles/202294760-FortrezZ-Siren-Strobe-Alarm)

View File

@@ -20,7 +20,6 @@ metadata {
capability "Actuator"
capability "Alarm"
capability "Battery"
capability "Health Check"
capability "Polling"
capability "Refresh"
capability "Sensor"
@@ -28,7 +27,6 @@ metadata {
fingerprint inClusters: "0x20,0x25,0x86,0x80,0x85,0x72,0x71"
fingerprint mfr:"0084", prod:"0313", model:"010B", deviceJoinName: "FortrezZ Siren Strobe Alarm"
}
simulator {
@@ -60,11 +58,6 @@ metadata {
}
}
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])
}
def createEvents(physicalgraph.zwave.commands.batteryv1.BatteryReport cmd) {
def map = [ name: "battery", unit: "%" ]
if (cmd.batteryLevel == 0xFF) {
@@ -126,13 +119,6 @@ def both() {
on()
}
/**
* PING is used by Device-Watch in attempt to reach the Device
* */
def ping() {
refresh()
}
def refresh() {
log.debug "sending battery refresh command"
zwave.batteryV1.batteryGet().format()

View File

@@ -1,2 +0,0 @@
.st-ignore
README.md

View File

@@ -1,40 +0,0 @@
# Z-wave Smoke Alarm
Cloud Execution
Works with:
* [First Alert Smoke Detector and Carbon Monoxide Alarm (ZCOMBO)](https://www.smartthings.com/works-with-smartthings/sensors/first-alert-smoke-detector-and-carbon-monoxide-alarm-zcombo)
## Table of contents
* [Capabilities](#capabilities)
* [Health](#device-health)
* [Battery](#battery-specification)
* [Troubleshooting](#troubleshooting)
## Capabilities
* **Smoke Detector** - measure smoke and optionally carbon monoxide levels
* **Carbon Monoxide Detector** - measure carbon monoxide levels
* **Sensor** - detects sensor events
* **Battery** - defines device uses a battery
* **Health Check** - indicates ability to get device health notifications
## Device Health
First Alert Smoke Detector and Carbon Monoxide Alarm (ZCOMBO) is a Z-wave sleepy device and checks in every 1 hour.
Device-Watch allows 2 check-in misses from device plus some lag time. So Check-in interval = (2*60 + 2)mins = 122 mins.
* __122min__ checkInterval
## Battery Specification
Two AA 1.5V batteries are required.
## Troubleshooting
If the device doesn't pair when trying from the SmartThings mobile app, it is possible that the device is out of range.
Pairing needs to be tried again by placing the device closer to the hub.
Instructions related to pairing, resetting and removing the device from SmartThings can be found in the following link:
* [First Alert Smoke Detector and Carbon Monoxide Alarm (ZCOMBO) Troubleshooting Tips](https://support.smartthings.com/hc/en-us/articles/201581984-First-Alert-Smoke-Detector-and-Carbon-Monoxide-Alarm-ZCOMBO-)

View File

@@ -17,12 +17,10 @@ metadata {
capability "Carbon Monoxide Detector"
capability "Sensor"
capability "Battery"
capability "Health Check"
attribute "alarmState", "string"
fingerprint deviceId: "0xA100", inClusters: "0x20,0x80,0x70,0x85,0x71,0x72,0x86"
fingerprint mfr:"0138", prod:"0001", model:"0002", deviceJoinName: "First Alert Smoke Detector and Carbon Monoxide Alarm (ZCOMBO)"
}
simulator {
@@ -53,11 +51,6 @@ metadata {
}
}
def updated(){
// Device checks in every hour, this interval allows us to miss one check-in notification before marking offline
sendEvent(name: "checkInterval", value: 2 * 60 * 60 + 2 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID])
}
def parse(String description) {
def results = []
if (description.startsWith("Err")) {
@@ -72,6 +65,7 @@ def parse(String description) {
return results
}
def createSmokeOrCOEvents(name, results) {
def text = null
switch (name) {

View File

@@ -47,7 +47,7 @@ metadata {
tiles(scale: 2) {
multiAttributeTile(name:"switch", type: "lighting", width: 6, height: 4, canChangeIcon: true){
tileAttribute ("device.switch", key: "PRIMARY_CONTROL") {
attributeState "on", label: '${name}', action: "switch.off", icon: "st.switches.switch.on", backgroundColor: "#00A0DC"
attributeState "on", label: '${name}', action: "switch.off", icon: "st.switches.switch.on", backgroundColor: "#79b821"
attributeState "off", label: '${name}', action: "switch.on", icon: "st.switches.switch.off", backgroundColor: "#ffffff"
}
}

View File

@@ -46,7 +46,7 @@ metadata {
tiles(scale: 2) {
multiAttributeTile(name:"switch", type: "lighting", width: 6, height: 4, canChangeIcon: true){
tileAttribute ("device.switch", key: "PRIMARY_CONTROL") {
attributeState "on", label: '${name}', action: "switch.off", icon: "st.switches.switch.on", backgroundColor: "#00A0DC"
attributeState "on", label: '${name}', action: "switch.off", icon: "st.switches.switch.on", backgroundColor: "#79b821"
attributeState "off", label: '${name}', action: "switch.on", icon: "st.switches.switch.off", backgroundColor: "#ffffff"
}
}

View File

@@ -20,7 +20,6 @@ metadata {
capability "Configuration"
capability "Polling"
capability "Sensor"
capability "Health Check"
attribute "thermostatFanState", "string"
@@ -31,7 +30,6 @@ metadata {
fingerprint deviceId: "0x08"
fingerprint inClusters: "0x43,0x40,0x44,0x31"
fingerprint mfr:"0039", prod:"0011", model:"0001", deviceJoinName: "Honeywell Z-Wave Thermostat"
}
// simulator metadata
@@ -125,11 +123,6 @@ metadata {
}
}
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])
}
def parse(String description)
{
def map = createEvent(zwaveEvent(zwave.parse(description, [0x42:1, 0x43:2, 0x31: 3])))
@@ -400,14 +393,6 @@ def setCoolingSetpoint(Double degrees, Integer delay = 30000) {
], delay)
}
/**
* PING is used by Device-Watch in attempt to reach the Device
* */
def ping() {
log.debug "ping() called"
poll()
}
def configure() {
delayBetween([
zwave.thermostatModeV2.thermostatModeSupportedGet().format(),

View File

@@ -33,7 +33,7 @@ metadata {
tiles {
standardTile("water", "device.water", width: 2, height: 2) {
state "dry", icon:"st.alarm.water.dry", backgroundColor:"#ffffff"
state "wet", icon:"st.alarm.water.wet", backgroundColor:"#00A0DC"
state "wet", icon:"st.alarm.water.wet", backgroundColor:"#53a7c0"
}
valueTile("battery", "device.battery", inactiveLabel: false, decoration: "flat") {
state "battery", label:'${currentValue}% battery', unit:""

View File

@@ -1,794 +0,0 @@
/**
* Gideon
*
* Copyright 2016 Nicola Russo
*
* 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: "Gideon Smart Home",
namespace: "gideon.api",
author: "Braindrain Solutions ltd",
description: "Gideon Smart Home SmartApp allows you to connect and control all of your SmartThings devices through the Gideon app, making your SmartThings devices even smarter.",
category: "Family",
iconUrl: "http://s33.postimg.org/t77u7y7v3/logo.png",
iconX2Url: "http://s33.postimg.org/t77u7y7v3/logo.png",
iconX3Url: "http://s33.postimg.org/t77u7y7v3/logo.png",
oauth: [displayName: "Gideon Smart Home API app", displayLink: "gideon.ai"])
preferences {
section("Control these contact sensors...") {
input "contact", "capability.contactSensor", multiple:true, required:false
}
section("Control these switch levels...") {
input "switchlevels", "capability.switchLevel", multiple:true, required:false
}
/* section("Control these thermostats...") {
input "thermostats", "capability.thermostat", multiple:true, required:false
}*/
section("Control the color for these devices...") {
input "colors", "capability.colorControl", multiple:true, required:false
}
section("Control the color temperature for these devices...") {
input "kelvin", "capability.colorTemperature", multiple:true, required:false
}
section("Control these switches...") {
input "switches", "capability.switch", multiple:true, required:false
}
section("Control these smoke alarms...") {
input "smoke_alarms", "capability.smokeDetector", multiple:true, required:false
}
section("Control these window shades...") {
input "shades", "capability.windowShade", multiple:true, required:false
}
section("Control these garage doors...") {
input "garage", "capability.garageDoorControl", multiple:true, required:false
}
section("Control these water sensors...") {
input "water_sensors", "capability.waterSensor", multiple:true, required:false
}
section("Control these motion sensors...") {
input "motions", "capability.motionSensor", multiple:true, required:false
}
section("Control these presence sensors...") {
input "presence_sensors", "capability.presenceSensor", multiple:true, required:false
}
section("Control these outlets...") {
input "outlets", "capability.outlet", multiple:true, required:false
}
section("Control these power meters...") {
input "meters", "capability.powerMeter", multiple:true, required:false
}
section("Control these locks...") {
input "locks", "capability.lock", multiple:true, required:false
}
section("Control these temperature sensors...") {
input "temperature_sensors", "capability.temperatureMeasurement", multiple:true, required:false
}
section("Control these batteries...") {
input "batteries", "capability.battery", multiple:true, required:false
}
}
def installed() {
log.debug "Installed with settings: ${settings}"
initialize()
}
def updated() {
log.debug "Updated with settings: ${settings}"
unsubscribe()
initialize()
}
def initialize() {
}
private device(it, type) {
it ? [id: it.id, label: it.label, type: type] : null
}
//API Mapping
mappings {
path("/getalldevices") {
action: [
GET: "getAllDevices"
]
}
/*
path("/thermostat/setcool/:id/:temp") {
action: [
GET: "setCoolTemp"
]
}
path("/thermostat/setheat/:id/:temp") {
action: [
GET: "setHeatTemp"
]
}
path("/thermostat/setfanmode/:id/:mode") {
action: [
GET: "setFanMode"
]
}
path("/thermostat/setmode/:id/:mode") {
action: [
GET: "setThermostatMode"
]
}
path("/thermostat/:id") {
action: [
GET: "getThermostatStatus"
]
}
*/
path("/light/dim/:id/:dim") {
action: [
GET: "setLevelStatus"
]
}
path("/light/kelvin/:id/:kelvin") {
action: [
GET: "setKelvin"
]
}
path("/colorlight/:id/:hue/:sat") {
action: [
GET: "setColor"
]
}
path("/light/status/:id") {
action: [
GET: "getLightStatus"
]
}
path("/light/on/:id") {
action: [
GET: "turnOnLight"
]
}
path("/light/off/:id") {
action: [
GET: "turnOffLight"
]
}
path("/doorlocks/lock/:id") {
action: [
GET: "lockDoorLock"
]
}
path("/doorlocks/unlock/:id") {
action: [
GET: "unlockDoorLock"
]
}
path("/doorlocks/:id") {
action: [
GET: "getDoorLockStatus"
]
}
path("/contacts/:id") {
action: [
GET: "getContactStatus"
]
}
path("/smoke/:id") {
action: [
GET: "getSmokeStatus"
]
}
path("/shades/open/:id") {
action: [
GET: "openShade"
]
}
path("/shades/preset/:id") {
action: [
GET: "presetShade"
]
}
path("/shades/close/:id") {
action: [
GET: "closeShade"
]
}
path("/shades/:id") {
action: [
GET: "getShadeStatus"
]
}
path("/garage/open/:id") {
action: [
GET: "openGarage"
]
}
path("/garage/close/:id") {
action: [
GET: "closeGarage"
]
}
path("/garage/:id") {
action: [
GET: "getGarageStatus"
]
}
path("/watersensors/:id") {
action: [
GET: "getWaterSensorStatus"
]
}
path("/tempsensors/:id") {
action: [
GET: "getTempSensorsStatus"
]
}
path("/meters/:id") {
action: [
GET: "getMeterStatus"
]
}
path("/batteries/:id") {
action: [
GET: "getBatteryStatus"
]
}
path("/presences/:id") {
action: [
GET: "getPresenceStatus"
]
}
path("/motions/:id") {
action: [
GET: "getMotionStatus"
]
}
path("/outlets/:id") {
action: [
GET: "getOutletStatus"
]
}
path("/outlets/turnon/:id") {
action: [
GET: "turnOnOutlet"
]
}
path("/outlets/turnoff/:id") {
action: [
GET: "turnOffOutlet"
]
}
path("/switches/turnon/:id") {
action: [
GET: "turnOnSwitch"
]
}
path("/switches/turnoff/:id") {
action: [
GET: "turnOffSwitch"
]
}
path("/switches/:id") {
action: [
GET: "getSwitchStatus"
]
}
}
//API Methods
def getAllDevices() {
def locks_list = locks.collect{device(it,"Lock")}
/*def thermo_list = thermostats.collect{device(it,"Thermostat")}*/
def colors_list = colors.collect{device(it,"Color")}
def kelvin_list = kelvin.collect{device(it,"Kelvin")}
def contact_list = contact.collect{device(it,"Contact Sensor")}
def smokes_list = smoke_alarms.collect{device(it,"Smoke Alarm")}
def shades_list = shades.collect{device(it,"Window Shade")}
def garage_list = garage.collect{device(it,"Garage Door")}
def water_sensors_list = water_sensors.collect{device(it,"Water Sensor")}
def presences_list = presence_sensors.collect{device(it,"Presence")}
def motions_list = motions.collect{device(it,"Motion")}
def outlets_list = outlets.collect{device(it,"Outlet")}
def switches_list = switches.collect{device(it,"Switch")}
def switchlevels_list = switchlevels.collect{device(it,"Switch Level")}
def temp_list = temperature_sensors.collect{device(it,"Temperature")}
def meters_list = meters.collect{device(it,"Power Meters")}
def battery_list = batteries.collect{device(it,"Batteries")}
return outlets_list + kelvin_list + colors_list + switchlevels_list + smokes_list + contact_list + water_sensors_list + shades_list + garage_list + locks_list + presences_list + motions_list + switches_list + temp_list + meters_list + battery_list
}
//thermostat
/*
def setCoolTemp() {
def device = thermostats.find { it.id == params.id }
if (!device) {
httpError(404, "Device not found")
} else {
if(device.hasCommand("setCoolingSetpoint")) {
device.setCoolingSetpoint(params.temp.toInteger());
return [result_action: "200"]
}
else {
httpError(510, "Not supported!")
}
}
}
def setHeatTemp() {
def device = thermostats.find { it.id == params.id }
if (!device) {
httpError(404, "Device not found")
} else {
if(device.hasCommand("setHeatingSetpoint")) {
device.setHeatingSetpoint(params.temp.toInteger());
return [result_action: "200"]
}
else {
httpError(510, "Not supported!")
}
}
}
def setFanMode() {
def device = thermostats.find { it.id == params.id }
if (!device) {
httpError(404, "Device not found")
} else {
if(device.hasCommand("setThermostatFanMode")) {
device.setThermostatFanMode(params.mode);
return [result_action: "200"]
}
else {
httpError(510, "Not supported!")
}
}
}
def setThermostatMode() {
def device = thermostats.find { it.id == params.id }
if (!device) {
httpError(404, "Device not found")
} else {
if(device.hasCommand("setThermostatMode")) {
device.setThermostatMode(params.mode);
return [result_action: "200"]
}
else {
httpError(510, "Not supported!")
}
}
}
def getThermostatStatus() {
def device = thermostats.find{ it.id == params.id }
if (!device) {
httpError(404, "Device not found")
} else {
return [ThermostatOperatingState: device.currentValue('thermostatOperatingState'), ThermostatSetpoint: device.currentValue('thermostatSetpoint'),
ThermostatFanMode: device.currentValue('thermostatFanMode'), ThermostatMode: device.currentValue('thermostatMode')]
}
}
*/
//light
def turnOnLight() {
def device = switches.find { it.id == params.id }
if (!device) {
httpError(404, "Device not found")
} else {
device.on();
return [Device_id: params.id, result_action: "200"]
}
}
def turnOffLight() {
def device = switches.find { it.id == params.id }
if (!device) {
httpError(404, "Device not found")
} else {
device.off();
return [Device_id: params.id, result_action: "200"]
}
}
def getLightStatus() {
def device = switches.find{ it.id == params.id }
if (!device) {
httpError(404, "Device not found")
} else {
return [Status: device.currentValue('switch'), Dim: getLevelStatus(params.id), Color: getColorStatus(params.id), Kelvin: getKelvinStatus(params.id)]
}
}
//color control
def setColor() {
def device = colors.find { it.id == params.id }
if (!device) {
httpError(404, "Device not found")
} else {
def map = [hue:params.hue.toInteger(), saturation:params.sat.toInteger()]
device.setColor(map);
return [Device_id: params.id, result_action: "200"]
}
}
def getColorStatus(id) {
def device = colors.find { it.id == id }
if (!device) {
return [Color: "none"]
} else {
return [hue: device.currentValue('hue'), saturation: device.currentValue('saturation')]
}
}
//kelvin control
def setKelvin() {
def device = kelvin.find { it.id == params.id }
if (!device) {
httpError(404, "Device not found")
} else {
device.setColorTemperature(params.kelvin.toInteger());
return [Device_id: params.id, result_action: "200"]
}
}
def getKelvinStatus(id) {
def device = kelvin.find { it.id == id }
if (!device) {
return [kelvin: "none"]
} else {
return [kelvin: device.currentValue('colorTemperature')]
}
}
//switch level
def getLevelStatus() {
def device = switchlevels.find { it.id == params.id }
if (!device) {
[Level: "No dimmer"]
} else {
return [Level: device.currentValue('level')]
}
}
def getLevelStatus(id) {
def device = switchlevels.find { it.id == id }
if (!device) {
[Level: "No dimmer"]
} else {
return [Level: device.currentValue('level')]
}
}
def setLevelStatus() {
def device = switchlevels.find { it.id == params.id }
def level = params.dim
if (!device) {
httpError(404, "Device not found")
} else {
device.setLevel(level.toInteger())
return [result_action: "200", Level: device.currentValue('level')]
}
}
//contact sensors
def getContactStatus() {
def device = contact.find { it.id == params.id }
if (!device) {
httpError(404, "Device not found")
} else {
def args = getTempSensorsStatus(device.id)
return [Device_state: device.currentValue('contact')] + args
}
}
//smoke detectors
def getSmokeStatus() {
def device = smoke_alarms.find { it.id == params.id }
if (!device) {
httpError(404, "Device not found")
} else {
def bat = getBatteryStatus(device.id)
return [Device_state: device.currentValue('smoke')] + bat
}
}
//garage
def getGarageStatus() {
def device = garage.find { it.id == params.id }
if (!device) {
httpError(404, "Device not found")
} else {
return [Device_state: device.currentValue('door')]
}
}
def openGarage() {
def device = garage.find { it.id == params.id }
if (!device) {
httpError(404, "Device not found")
} else {
device.open();
return [Device_id: params.id, result_action: "200"]
}
}
def closeGarage() {
def device = garage.find { it.id == params.id }
if (!device) {
httpError(404, "Device not found")
} else {
device.close();
return [Device_id: params.id, result_action: "200"]
}
}
//shades
def getShadeStatus() {
def device = shades.find { it.id == params.id }
if (!device) {
httpError(404, "Device not found")
} else {
return [Device_state: device.currentValue('windowShade')]
}
}
def openShade() {
def device = shades.find { it.id == params.id }
if (!device) {
httpError(404, "Device not found")
} else {
device.open();
return [Device_id: params.id, result_action: "200"]
}
}
def presetShade() {
def device = shades.find { it.id == params.id }
if (!device) {
httpError(404, "Device not found")
} else {
device.presetPosition();
return [Device_id: params.id, result_action: "200"]
}
}
def closeShade() {
def device = shades.find { it.id == params.id }
if (!device) {
httpError(404, "Device not found")
} else {
device.close();
return [Device_id: params.id, result_action: "200"]
}
}
//water sensor
def getWaterSensorStatus() {
def device = water_sensors.find { it.id == params.id }
if (!device) {
httpError(404, "Device not found")
} else {
def bat = getBatteryStatus(device.id)
return [Device_state: device.currentValue('water')] + bat
}
}
//batteries
def getBatteryStatus() {
def device = batteries.find { it.id == params.id }
if (!device) {
httpError(404, "Device not found")
} else {
return [Device_state: device.latestValue("battery")]
}
}
def getBatteryStatus(id) {
def device = batteries.find { it.id == id }
if (!device) {
return []
} else {
return [battery_state: device.latestValue("battery")]
}
}
//LOCKS
def getDoorLockStatus() {
def device = locks.find { it.id == params.id }
if (!device) {
httpError(404, "Device not found")
} else {
def bat = getBatteryStatus(device.id)
return [Device_state: device.currentValue('lock')] + bat
}
}
def lockDoorLock() {
def device = locks.find { it.id == params.id }
if (!device) {
httpError(404, "Device not found")
} else {
device.lock();
return [Device_id: params.id, result_action: "200"]
}
}
def unlockDoorLock() {
def device = locks.find { it.id == params.id }
if (!device) {
httpError(404, "Device not found")
} else {
device.unlock();
return [Device_id: params.id, result_action: "200"]
}
}
//PRESENCE
def getPresenceStatus() {
def device = presence_sensors.find { it.id == params.id }
if (!device) {
httpError(404, "Device not found")
} else {
def bat = getBatteryStatus(device.id)
return [Device_state: device.currentValue('presence')] + bat
}
}
//MOTION
def getMotionStatus() {
def device = motions.find { it.id == params.id }
if (!device) {
httpError(404, "Device not found")
} else {
def args = getTempSensorsStatus(device.id)
return [Device_state: device.currentValue('motion')] + args
}
}
//OUTLET
def getOutletStatus() {
def device = outlets.find { it.id == params.id }
if (!device) {
device = switches.find { it.id == params.id }
if(!device) {
httpError(404, "Device not found")
}
}
def watt = getMeterStatus(device.id)
return [Device_state: device.currentValue('switch')] + watt
}
def getMeterStatus() {
def device = meters.find { it.id == params.id }
if (!device) {
httpError(404, "Device not found")
} else {
return [Device_id: device.id, Device_type: device.type, Current_watt: device.currentValue("power")]
}
}
def getMeterStatus(id) {
def device = meters.find { it.id == id }
if (!device) {
return []
} else {
return [Current_watt: device.currentValue("power")]
}
}
def turnOnOutlet() {
def device = outlets.find { it.id == params.id }
if (!device) {
device = switches.find { it.id == params.id }
if(!device) {
httpError(404, "Device not found")
}
}
device.on();
return [Device_id: params.id, result_action: "200"]
}
def turnOffOutlet() {
def device = outlets.find { it.id == params.id }
if (!device) {
device = switches.find { it.id == params.id }
if(!device) {
httpError(404, "Device not found")
}
}
device.off();
return [Device_id: params.id, result_action: "200"]
}
//SWITCH
def getSwitchStatus() {
def device = switches.find { it.id == params.id }
if (!device) {
httpError(404, "Device not found")
} else {
return [Device_state: device.currentValue('switch'), Dim: getLevelStatus(params.id)]
}
}
def turnOnSwitch() {
def device = switches.find { it.id == params.id }
if (!device) {
httpError(404, "Device not found")
} else {
device.on();
return [Device_id: params.id, result_action: "200"]
}
}
def turnOffSwitch() {
def device = switches.find { it.id == params.id }
if (!device) {
httpError(404, "Device not found")
} else {
device.off();
return [Device_id: params.id, result_action: "200"]
}
}
//TEMPERATURE
def getTempSensorsStatus() {
def device = temperature_sensors.find { it.id == params.id }
if (!device) {
httpError(404, "Device not found")
} else {
def bat = getBatteryStatus(device.id)
def scale = [Scale: location.temperatureScale]
return [Device_state: device.currentValue('temperature')] + scale + bat
}
}
def getTempSensorsStatus(id) {
def device = temperature_sensors.find { it.id == id }
if (!device) {
return []
} else {
def bat = getBatteryStatus(device.id)
return [temperature: device.currentValue('temperature')] + bat
}
}

View File

@@ -39,7 +39,7 @@ definition(
* garageDoors | door | open, close | unknown, closed, open, closing, opening
* cameras | image | take | <String>
* thermostats | thermostat | setHeatingSetpoint, | temperature, heatingSetpoint, coolingSetpoint,
* | | setCoolingSetpoint, | thermostatSetpoint, thermostatMode,
* | | setCoolingSetpoint, | thermostatSetpoint, thermostatMode,
* | | off, heat, cool, auto,| thermostatFanMode, thermostatOperatingState
* | | emergencyHeat, |
* | | setThermostatMode, |
@@ -55,7 +55,7 @@ preferences {
input "contactSensors", "capability.contactSensor", title: "Which Contact Sensors", multiple: true, required: false
input "garageDoors", "capability.garageDoorControl", title: "Which Garage Doors?", multiple: true, required: false
input "locks", "capability.lock", title: "Which Locks?", multiple: true, required: false
input "cameras", "capability.videoCapture", title: "Which Cameras?", multiple: true, required: false
input "cameras", "capability.videoCapture", title: "Which Cameras?", multiple: true, required: false
input "motionSensors", "capability.motionSensor", title: "Which Motion Sensors?", multiple: true, required: false
input "presenceSensors", "capability.presenceSensor", title: "Which Presence Sensors", multiple: true, required: false
input "switches", "capability.switch", title: "Which Switches and Lights?", multiple: true, required: false
@@ -66,48 +66,54 @@ preferences {
def getInputs() {
def inputList = []
inputList += contactSensors?: []
inputList += garageDoors?: []
inputList += locks?: []
inputList += cameras?: []
inputList += motionSensors?: []
inputList += presenceSensors?: []
inputList += switches?: []
inputList += thermostats?: []
inputList += waterSensors?: []
inputList += contactSensors ?: []
inputList += garageDoors ?: []
inputList += locks ?: []
inputList += cameras ?: []
inputList += motionSensors ?: []
inputList += presenceSensors ?: []
inputList += switches ?: []
inputList += thermostats ?: []
inputList += waterSensors ?: []
return inputList
}
//API external Endpoints
mappings {
path("/subscriptionURL/:url") {
action: [
action:
[
PUT: "updateEndpointURL"
]
}
path("/connectionId/:connId") {
action: [
action:
[
PUT: "updateConnectionId"
]
}
path("/devices") {
action: [
action:
[
GET: "getDevices"
]
}
path("/devices/:id") {
action: [
action:
[
GET: "getDevice"
]
}
path("/update/:id") {
action: [
action:
[
PUT: "updateDevice"
]
}
path("/subscription/:id") {
action: [
POST: "registerDeviceChange",
action:
[
POST : "registerDeviceChange",
DELETE: "unregisterDeviceChange"
]
}
@@ -139,7 +145,7 @@ def registerSubscriptions() {
def registerChangeHandler(myList) {
myList.each { myDevice ->
def theAtts = myDevice.supportedAttributes
theAtts.each {att ->
theAtts.each { att ->
subscribe(myDevice, att.name, eventHandler)
log.info "Registering ${myDevice.displayName}.${att.name}"
}
@@ -151,7 +157,7 @@ def registerDeviceChange() {
def myDevice = findDevice(params.id)
def theAtts = myDevice.supportedAttributes
try {
theAtts.each {att ->
theAtts.each { att ->
subscribe(myDevice, att.name, eventHandler)
log.info "Registering ${myDevice.displayName}.${att.name}"
}
@@ -180,20 +186,16 @@ def eventHandler(evt) {
def evt_name = evt.name
def evt_device = evt.device
def evt_deviceType = getDeviceType(evt_device);
def deviceInfo
if(evt_deviceType == "thermostat")
{
deviceInfo = [name: evt_device.displayName, id: evt_device.id, status:evt_device.getStatus(), deviceType:evt_deviceType, manufacturer:evt_device.getManufacturerName(), model:evt_device.getModelName(), attributes: deviceAttributeList(evt_device), locationMode: getLocationModeInfo()]
}
else
{
deviceInfo = [name: evt_device.displayName, id: evt_device.id, status:evt_device.getStatus(), deviceType:evt_deviceType, manufacturer:evt_device.getManufacturerName(), model:evt_device.getModelName(), attributes: deviceAttributeList(evt_device)]
}
def params = [
uri: "${state.endpointURL}/${state.connectionId}",
body: [ deviceInfo ]
uri : "${state.endpointURL}/${state.connectionId}",
body: [
name : evt_device.displayName,
id : evt_device.id,
deviceType : evt_deviceType,
manufacturer: evt_device.getManufacturerName(),
model : evt_device.getModelName(),
attributes : deviceAttributeList(evt_device)
]
]
try {
log.trace "POST URI: ${params.uri}"
@@ -228,13 +230,10 @@ def getDevices() {
def deviceData = []
inputs?.each {
def deviceType = getDeviceType(it)
if(deviceType == "thermostat")
{
deviceData << [name: it.displayName, id: it.id, status:it.getStatus(), deviceType:deviceType, manufacturer:it.getManufacturerName(), model:it.getModelName(), attributes: deviceAttributeList(it), locationMode: getLocationModeInfo()]
}
else
{
deviceData << [name: it.displayName, id: it.id, status:it.getStatus(), deviceType:deviceType, manufacturer:it.getManufacturerName(), model:it.getModelName(), attributes: deviceAttributeList(it)]
if (deviceType == "thermostat") {
deviceData << [name: it.displayName, id: it.id, deviceType: deviceType, manufacturer: it.getManufacturerName(), model: it.getModelName(), attributes: deviceAttributeList(it), locationMode: getLocationModeInfo()]
} else {
deviceData << [name: it.displayName, id: it.id, deviceType: deviceType, manufacturer: it.getManufacturerName(), model: it.getModelName(), attributes: deviceAttributeList(it)]
}
}
@@ -247,13 +246,10 @@ def getDevice() {
def it = findDevice(params.id)
def deviceType = getDeviceType(it)
def device
if(deviceType == "thermostat")
{
device = [name: it.displayName, id: it.id, status:it.getStatus(), deviceType:deviceType, manufacturer:it.getManufacturerName(), model:it.getModelName(), attributes: deviceAttributeList(it), locationMode: getLocationModeInfo()]
}
else
{
device = [name: it.displayName, id: it.id, status:it.getStatus(), deviceType:deviceType, manufacturer:it.getManufacturerName(), model:it.getModelName(), attributes: deviceAttributeList(it)]
if (deviceType == "thermostat") {
device = [name: it.displayName, id: it.id, deviceType: deviceType, manufacturer: it.getManufacturerName(), model: it.getModelName(), attributes: deviceAttributeList(it), locationMode: getLocationModeInfo()]
} else {
device = [name: it.displayName, id: it.id, deviceType: deviceType, manufacturer: it.getManufacturerName(), model: it.getModelName(), attributes: deviceAttributeList(it)]
}
log.debug "getDevice, return: ${device}"
return device
@@ -265,18 +261,18 @@ void updateDevice() {
request.JSON.each {
def command = it.key
def value = it.value
if (command){
if (command) {
def commandList = mapDeviceCommands(command, value)
command = commandList[0]
value = commandList[1]
if (command == "setAwayMode") {
log.info "Setting away mode to ${value}"
if (location.modes?.find {it.name == value}) {
if (location.modes?.find { it.name == value }) {
location.setMode(value)
}
}else if (command == "thermostatSetpoint"){
switch(device.currentThermostatMode){
} else if (command == "thermostatSetpoint") {
switch (device.currentThermostatMode) {
case "cool":
log.info "Update: ${device.displayName}, [${command}, ${value}]"
device.setCoolingSetpoint(value)
@@ -290,7 +286,7 @@ void updateDevice() {
httpError(501, "this mode: ${device.currentThermostatMode} does not allow changing thermostat setpoint.")
break
}
}else if (!device) {
} else if (!device) {
log.error "updateDevice, Device not found"
httpError(404, "Device not found")
} else if (!device.hasCommand(command)) {
@@ -300,11 +296,11 @@ void updateDevice() {
if (command == "setColor") {
log.info "Update: ${device.displayName}, [${command}, ${value}]"
device."$command"(hex: value)
} else if(value.isNumber()) {
} else if (value.isNumber()) {
def intValue = value as Integer
log.info "Update: ${device.displayName}, [${command}, ${intValue}(int)]"
device."$command"(intValue)
} else if (value){
} else if (value) {
log.info "Update: ${device.displayName}, [${command}, ${value}]"
device."$command"(value)
} else {
@@ -326,28 +322,19 @@ private getLocationModeInfo() {
//Map each device to a type given it's capabilities
private getDeviceType(device) {
def deviceType
def capabilities = device.capabilities
log.debug "capabilities: [${device}, ${capabilities}]"
def caps = device.capabilities
log.debug "capabilities: [${device}, ${caps}]"
log.debug "supported commands: [${device}, ${device.supportedCommands}]"
//Loop through the device capability list to determine the device type.
capabilities.each {capability ->
switch(capability.name.toLowerCase())
{
caps.each {
switch (it.name.toLowerCase()) {
case "switch":
deviceType = "switch"
//If the device also contains "Switch Level" capability, identify it as a "light" device.
if (capabilities.any{it.name.toLowerCase() == "switch level"}){
//If the device also contains "Power Meter" capability, identify it as a "dimmerSwitch" device.
if (capabilities.any{it.name.toLowerCase() == "power meter"}){
deviceType = "dimmerSwitch"
return deviceType
} else {
deviceType = "light"
return deviceType
}
if (caps.any { it.name.toLowerCase() == "power meter" }) {
return deviceType
}
if (caps.any { it.name.toLowerCase() == "switch level" }) {
deviceType = "light"
return deviceType
}
break
case "contact sensor":
@@ -388,16 +375,16 @@ private findDevice(deviceId) {
//Return a list of device attributes
private deviceAttributeList(device) {
device.supportedAttributes.collectEntries { attribute->
device.supportedAttributes.collectEntries { attribute ->
try {
[ (attribute.name): device.currentValue(attribute.name) ]
} catch(e) {
[ (attribute.name): null ]
[(attribute.name): device.currentValue(attribute.name)]
} catch (e) {
[(attribute.name): null]
}
}
}
//Map device command and value.
//Map device command and value.
//input command and value are from UWP,
//returns resultCommand and resultValue that corresponds with function and value in SmartApps
private mapDeviceCommands(command, value) {
@@ -427,7 +414,7 @@ private mapDeviceCommands(command, value) {
resultCommand = "setSaturation"
resultValue = value
break
case "colorTemperature":
case "ct":
resultCommand = "setColorTemperature"
resultValue = value
break
@@ -464,8 +451,7 @@ private mapDeviceCommands(command, value) {
if (value == 1 || value == "1" || value == "lock") {
resultCommand = "lock"
resultValue = ""
}
else if (value == 0 || value == "0" || value == "unlock") {
} else if (value == 0 || value == "0" || value == "unlock") {
resultCommand = "unlock"
resultValue = ""
}
@@ -474,5 +460,6 @@ private mapDeviceCommands(command, value) {
break
}
return [resultCommand,resultValue]
return [resultCommand, resultValue]
}

View File

@@ -30,7 +30,7 @@ preferences {
input "havdalahOffset", "number", title: "Minutes After Sundown", required:true
}
section("Your ZipCode") {
input "zipcode", "text", title: "ZipCode", required:true
input "zipcode", "number", title: "ZipCode", required:true
}
section( "Notifications" ) {
input "sendPushMessage", "enum", title: "Send a push notification?", metadata:[values:["Yes","No"]], required:false
@@ -205,4 +205,4 @@ if ( sendPushMessage != "No" ) {
log.debug( "sending text message" )
sendSms( phone, msg )
}
}//END def sendMessage(msg)
}//END def sendMessage(msg)

View File

@@ -472,6 +472,8 @@ def addBridge() {
log.error "Failed to create Hue Bridge device"
}
}
} else {
log.debug "found ${d.displayName} with id $selectedHue already exists"
}
}
}
@@ -713,9 +715,6 @@ def doDeviceSync(){
log.warn "state.updating failed to clear"
}
if (selectedHue) {
addBridge()
}
convertBulbListToMap()
poll()
ssdpSubscribe()
@@ -1359,7 +1358,7 @@ private void createSwitchEvent(childDevice, setSwitch, setLevel = null) {
private colorPointsForModel(model = null) {
def result = null
switch (model) {
// Gamut A
// Gamut A
case "LLC001": /* Monet, Renoir, Mondriaan (gen II) */
case "LLC005": /* Bloom (gen II) */
case "LLC006": /* Iris (gen III) */
@@ -1371,12 +1370,12 @@ private colorPointsForModel(model = null) {
case "LLC010": /* Hue Living Colors Iris + */
result = [r:[x: 0.704f, y: 0.296f], g:[x: 0.2151f, y: 0.7106f], b:[x: 0.138f, y: 0.08f]];
break
// Gamut C
// Gamut C
case "LLC020": /* Hue Go */
case "LST002": /* Hue LightStrips Plus */
result = [r:[x: 0.692f, y: 0.308f], g:[x: 0.17f, y: 0.7f], b:[x: 0.153f, y: 0.048f]];
break
// Gamut B
// Gamut B
case "LCT001": /* Hue A19 */
case "LCT002": /* Hue BR30 */
case "LCT003": /* Hue GU10 */
@@ -1804,3 +1803,4 @@ def hsvToHex(hue, sat, value = 100){
return "#$r1$g1$b1"
}

View File

@@ -0,0 +1,82 @@
/**
* Turn Off
*
* Copyright 2017 Trevor
*
* 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: "Turn Off",
namespace: "TEAPPS",
author: "Trevor",
description: "Turn off a light after its been turned on.",
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("Lights") {
input "lights", "capability.switch", required: true, title: "Which lights to turn off after being turned on?", multiple: true
input "offsetHours", "number", title: "How long until the light is turned off (hours)?"
input "offsetMinutes", "number", title: "How long until the light is turned off (minutes)?"
input "offsetSeconds", "number", title: "How long until the light is turned off (seconds)?"
}
}
def installed() {
log.debug "Installed with settings: ${settings}"
initialize()
}
def updated() {
log.debug "Updated with settings: ${settings}"
unsubscribe()
initialize()
}
def initialize() {
// TODO: subscribe to attributes, devices, locations, etc.
//Subscribe to the light device being turned on
subscribe(lights, "switch.on", lightHandler)
}
// TODO: implement event handlers
def lightHandler(evt) {
if("on" == evt.value)
//Light was turned on
log.debug "Light is in ${evt.value} state"
//Get the date and time
def currentTime = new Date()
//Calculate the offset
def timeToTurnOff = new Date(currentTime.time + (offsetHours * 60 * 60 * 1000) + (offsetMinutes * 60 * 1000) + (offsetSeconds * 1000))
log.debug "Scheduling for: $timeToTurnOff"
//Schedule this to run one time
runOnce(timeToTurnOff, turnOff)
}
def turnOff() {
log.debug "turning off lights"
lights.off()
}