Compare commits

..

42 Commits

Author SHA1 Message Date
Vinay Rao
95c383a2ea Merge pull request #1915 from SmartThingsCommunity/staging
Rolling up staging to production
2017-04-18 13:06:43 -07:00
Vinay Rao
7f61feaebc Merge pull request #1909 from larsfinander/DVCSMP-2572_OpenT2T_Update_4_14_submission_staging
DVCSMP-2572 OpenT2T: Update to 4/14 submission
2017-04-18 11:23:07 -07:00
Lars Finander
7a467df659 DVCSMP-2572 OpenT2T: Update to 4/14 submission 2017-04-18 12:01:56 -06:00
Vinay Rao
538eb057ce Merge pull request #1913 from SmartThingsCommunity/production
Rolling down production to staging
2017-04-17 12:59:57 -07:00
Vinay Rao
2ff9486790 Merge pull request #1912 from varzac/sengled-level-fix
[ICP-691] Set level on sengled bulbs configure
2017-04-17 12:59:20 -07:00
Zach Varberg
5429986e81 Set level on sengled bulbs configure
This works around the sengled bulbs not following the ZCL spec and using
the value 0xFF as a valid level (the spec says it should be invalid).
It does this by manually setting the level of the bulb to
0xFE (SmartThings 100%) when it is configured, or if it previously had a
level set, manually setting it to that value.  This avoids the issue of
the bulb reporting 0xFF and having the library ignore it because it is
an invalid value.

This resolves: https://smartthings.atlassian.net/browse/ICP-691
2017-04-17 12:36:13 -05:00
Vinay Rao
6514087a1a Merge pull request #1905 from workingmonk/log/hue_logs
CELL-139 Hue logging to detect hue pairing
2017-04-13 16:31:45 -07:00
Vinay Rao
0f2b8c18d2 CELL-139 Hue logging to detect hue pairing 2017-04-13 16:06:49 -07:00
Vinay Rao
ce0363fa43 Merge pull request #1889 from SmartThingsCommunity/MSA-1883-3
MSA-1883: EZMultipli 3:1 MultiSensor wall powered
2017-04-13 15:56:30 -07:00
Vinay Rao
fd620977bb Merge pull request #1902 from workingmonk/bug/arrival_battery
DVCSMP-2568 Arrival-sensor-ha Read battery level on join
2017-04-12 12:20:41 -07:00
Tom Manley
a308bff574 arrival-sensor-ha: Read battery level on join
In configure we were setting up the battery level to be reported every
20 seconds but we weren't reading the attribute so it would take 20
seconds before the battery level was reported. Now we read it during
configure so it is updated right away after join.

https://smartthings.atlassian.net/browse/DVCSMP-2568
2017-04-12 12:19:36 -07:00
Vinay Rao
068cfaeaad Merge pull request #1901 from workingmonk/bug/zwave_enerwave
[ICP-598] Adding Enerwave Door/Window Sensor
2017-04-11 21:53:14 -07:00
jackchi
fb55349db0 [ICP-598] Adding Enerwave Door/Window Sensor 2017-04-11 21:49:51 -07:00
Vinay Rao
476d3caa38 Merge pull request #1900 from tpmanley/feature/arrival-sensor-reporting
DVCSMP-2568 arrival-sensor-ha: Read battery level on join
2017-04-11 21:39:19 -07:00
Tom Manley
9b621c9a7b arrival-sensor-ha: Read battery level on join
In configure we were setting up the battery level to be reported every
20 seconds but we weren't reading the attribute so it would take 20
seconds before the battery level was reported. Now we read it during
configure so it is updated right away after join.

https://smartthings.atlassian.net/browse/DVCSMP-2568
2017-04-11 23:35:49 -05:00
Vinay Rao
619b3499c8 Merge pull request #1899 from workingmonk/bug/zwave_fingerprint
[ICP-598] Adding Z-Wave device manufacturer
2017-04-11 20:14:11 -07:00
jackchi
3ec8be708a [ICP-598] Adding Z-Wave device manufacturer 2017-04-11 17:39:17 -07:00
Vinay Rao
34b2210134 Merge pull request #1898 from jackchi/zwave-manufacturer-update
[ICP-598] Adding Enerwave Door/Window Sensor
2017-04-11 17:06:13 -07:00
jackchi
8abb82ecae [ICP-598] Adding Enerwave Door/Window Sensor 2017-04-11 17:00:48 -07:00
Vinay Rao
55da70cd7c Merge pull request #1897 from jackchi/zwave-manufacturer-update
[ICP-598] Adding Z-Wave device manufacturer
2017-04-11 16:46:00 -07:00
jackchi
80a5a41f7e [ICP-598] Adding Z-Wave device manufacturer 2017-04-11 16:21:28 -07:00
Vinay Rao
b4276c05e0 Merge pull request #1896 from SmartThingsCommunity/master
Rolling up master to staging
2017-04-11 14:07:20 -07:00
Vinay Rao
1db3765a9c Merge pull request #1895 from SmartThingsCommunity/staging
Rolling down staging to master
2017-04-11 14:06:52 -07:00
Vinay Rao
264e822c9f Merge pull request #1894 from SmartThingsCommunity/staging
Rolling up staging to production
2017-04-11 13:40:00 -07:00
Vinay Rao
e4642e300f Merge pull request #1893 from SmartThingsCommunity/production
Rolling down production hotfix to staging
2017-04-11 13:34:30 -07:00
Vinay Rao
b4eed54ddd Merge pull request #1892 from jackchi/enrollment-fix-updated
[CHF-595] Device Health enrollment needs to be in both updated() & installed()
2017-04-11 12:27:56 -07:00
jackchi
b2b03604a7 [CHF-595] Device Health enrollment needs to be in both updated() & installed() 2017-04-11 12:16:05 -07:00
Vinay Rao
2b05817843 Merge pull request #1891 from juano2310/OCF_light
ICP-554 - ocfDeviceType: "oic.d.light"
2017-04-11 11:18:02 -07:00
juano2310
1f6a27f381 ICP-554 - ocfDeviceType: "oic.d.light"
more
2017-04-11 14:17:31 -04:00
Vinay Rao
157bc3ef56 Merge pull request #1890 from jackchi/enrollment-fix-harmony
[CHF-596] Device Health Enrollment Fix
2017-04-11 09:01:03 -07:00
jackchi
096f4f767f [CHF-596] Device Health Enrollment Fix 2017-04-11 08:52:45 -07:00
Vinay Rao
c15a21b8bf Merge pull request #1888 from parijatdas/zwave_healthcheck
[CHF-595] Z-Wave checkInterval event needs to be in installed() DTH method
2017-04-11 08:32:21 -07:00
Eric Ryherd
c65c9cc185 MSA-1883: Features:
Motion Sensor
-  Passive Infrared Sensor (PIR)
-  12’ range - 90 coverage
-  Programmable timeout
-  Control four associated devices
Temperature Sensor
-  -10 - 80C range
-  0.1C resolution
Light Level Sensor
-  Relative light level 0-100%
Color Indicator Night Light
-  Eight colors
Wall Powered
-  110VAC 60Hz
-  No wires - just plug it in
-  Never needs batteries
Wireless Z-Wave ® RF Technology
-  Fifth generation chipset
-  Z-Wave range extender
-  100,000 bits/sec data rate
-  300’ RF range
-  Over-the-air firmware update
-  Push button to join network
-  Z-Wave Plus certified
Designed and assembled in USA
2017-04-11 05:25:16 -07:00
Parijat Das
daefec9d1f Added checkInterval sendEvent in installed() section for all zwave DTHs 2017-04-11 09:37:09 +05:30
Vinay Rao
a28c90e492 Merge pull request #1887 from workingmonk/bug/name_fix
ICP-554 ocf resource type update
2017-04-10 14:22:00 -07:00
Vinay Rao
664b300b37 ICP-554 ocf resource type update 2017-04-10 14:10:32 -07:00
Vinay Rao
2b6d978d13 Merge pull request #1883 from jackchi/revert-zwavesiren
Revert "Added health-check for FortrezZ Siren Strobe Alarm"
2017-04-06 14:33:09 -07:00
jackchi
8197097e1d Revert "Added health-check for FortrezZ Siren Strobe Alarm"
This reverts commit 7a7a08ea6e.
2017-04-06 14:15:08 -07:00
Vinay Rao
4644362465 Merge pull request #1882 from juano2310/production
ICP-554 - OCF device types Public Repo HOTFIX
2017-04-05 17:39:42 -07:00
juano2310
2c25e293c0 ICP-554 - OCF device types Public Repo 2017-04-05 20:34:14 -04:00
Vinay Rao
36fe6428ab Merge pull request #1878 from SmartThingsCommunity/master
Rolling up master to staging
2017-04-04 14:42:18 -07:00
Vinay Rao
7f3a99d889 Merge pull request #1874 from SmartThingsCommunity/staging
Rolling up staging to production
2017-04-04 13:58:28 -07:00
55 changed files with 984 additions and 769 deletions

View File

@@ -1,438 +0,0 @@
/**
* Strips by Sensative
* Device Handler by Don Caruana
*
* Date: 2017-2-19
* Supported Command Classes per device specs
*
* Association v2
* Association Group Information
* Battery
* Binary Sensor
* Configuration
* Device Reset Local
* Manufacturer Specific
* Notification v4
* Powerlevel
* Version v2
* Wake Up v2
* ZWavePlus Info v2
*
* Parm Size Description Value
* 1 1 Type of report to send 1 (Default)-Notification Report, 0-Binary Sensor report, 2-Basic report
* 2 1 LED Indication 1 (Default)-On for event (ex. door opened), 0-Off
*
* This device handler will just override the smartthings default wakeup interval of 4 hours and set to 24 hours (manufacturer default)
* and check the battery once a day (no sooner than every 23 hours)
*/
metadata {
definition (name: "Strips by Sensative", namespace: "doncaruana/Sensative", author: "Don Caruana, Sensative") {
capability "Contact Sensor"
capability "Configuration"
capability "Battery"
capability "Sensor"
capability "Refresh"
attribute "needUpdate", "string"
attribute "tamper" , "string"
fingerprint mfr:"019A", prod:"0003", model:"0003", deviceJoinName:"Strips by Sensative"
fingerprint deviceId:"0x0701", inClusters: "0x5E,0x86,0x72,0x30,0x70,0x71,0x5A,0x85,0x59,0x80,0x84,0x73"
fingerprint cc: "0x5E,0x86,0x72,0x30,0x70,0x71,0x5A,0x85,0x59,0x80,0x84,0x73", mfr:"019A", prod:"0003", model:"0003", deviceJoinName:"Strips by Sensative"
}
preferences {
section ("configuration settings") {
input(
title : "Changes in Settings marked with * will not take effect until the next device Wake Up."
,description : null
,type : "paragraph")
input "sendType", "enum",
title: "* Reporting Type",
description: "Notification Report",
options:["binary": "Sensor Binary Report", "notification": "Notification Report", "basic": "Basic Report"],
defaultValue: "notification",
displayDuringSetup: false
input "wakeupInterval","enum",
title: "* Device Wake Up Interval",
description: "24 hours",
defaultValue: "86400",
required: false,
displayDuringSetup: false,
options: buildInterval()
input "led", "bool",
title: "* LED On",
defaultValue: true,
displayDuringSetup: false
input "ignoreWakeup", "bool",
title: "Ignore Manual Wake Up",
defaultValue: false,
displayDuringSetup: false
input "invertOutput", "bool",
title: "Invert Open/Close Reporting",
defaultValue: false,
displayDuringSetup: false
}
}
tiles(scale: 2) {
multiAttributeTile(name:"contact", width: 6, height: 4, canChangeIcon: true){
tileAttribute ("device.contact", key: "PRIMARY_CONTROL") {
attributeState "open", label:'${name}', icon:"st.contact.contact.open", backgroundColor:"#ffa81e"
attributeState "closed", label:'${name}', icon:"st.contact.contact.closed", backgroundColor:"#79b821"
}
}
standardTile("tamper", "device.tamper", inactiveLabel: false, width: 4, height: 3) {
state "tamper", label:'${currentValue}', action:"refresh.refresh", backgroundColor:"#FFCC7B"
}
standardTile("configure", "device.needUpdate", inactiveLabel: false, width: 2, height: 2) {
state "NO" , label:'Synced', backgroundColor:"#B1D57D"
state "YES", label:'Pending changes', backgroundColor:"#FFCC7B"
}
standardTile("battery", "device.battery", inactiveLabel: false, width: 2, height: 1) {
state "battery", label:'Battery: ${currentValue}%'
}
main (["contact"])
details(["contact","battery","tamper","configure"])
}
simulator {
// messages the device returns in response to commands it receives
status "open (basic)" : "command: 9881, payload: 00 20 01 FF"
status "closed (basic)" : "command: 9881 payload: 00 20 01 00"
status "open (notification)" : "command: 9881, payload: 00 71 05 06 FF 00 FF 06 16 00 00"
status "closed (notification)" : "command: 9881, payload: 00 71 05 06 00 00 FF 06 17 00 00"
status "wake up" : "command: 9881, payload: 00 84 07"
status "battery (100%)" : "command: 9881, payload: 00 80 03 64"
status "battery low" : "command: 9881, payload: 00 80 03 FF"
}
}
def configure() {
def commands = []
state.lastupdate = now()
sendEvent(name: "tamper", value: "No Tamper", displayed: false)
log.debug "Listing all device parameters and defaults since this is a new inclusion"
commands << zwave.manufacturerSpecificV1.manufacturerSpecificGet().format()
commands << zwave.versionV1.versionGet().format()
commands << zwave.batteryV1.batteryGet().format()
commands << zwave.configurationV1.configurationGet(parameterNumber: 1).format()
commands << zwave.configurationV1.configurationGet(parameterNumber: 2).format()
commands << zwave.wakeUpV2.wakeUpIntervalSet(seconds: 86400, nodeid:zwaveHubNodeId).format()
commands << zwave.wakeUpV2.wakeUpIntervalGet().format()
commands << zwave.wakeUpV2.wakeUpNoMoreInformation().format()
delayBetween(commands, 1500)
}
private getCommandClassVersions() {
[
0x71: 3, // Notification
0x5E: 2, // ZwaveplusInfo
0x59: 1, // AssociationGrpInfo
0x85: 2, // Association
0x80: 1, // Battery
0x70: 1, // Configuration
0x5A: 1, // DeviceResetLocally
0x72: 1, // ManufacturerSpecific
0x73: 1, // Powerlevel
0x84: 2, // WakeUp
0x86: 1, // Version
0x30: 1, // Binary Sensor
]
}
// Parse incoming device messages to generate events
def parse(String description) {
def result = []
def cmd
if (description.startsWith("Err 106")) {
state.sec = 0
result = createEvent( name: "secureInclusion", value: "failed", eventType: "ALERT",
descriptionText: "This sensor failed to complete the network security key exchange. If you are unable to control it via SmartThings, you must remove it from your network and add it again.")
} else if (description.startsWith("Err")) {
result = createEvent(descriptionText: "$device.displayName $description", isStateChange: true)
} else {
cmd = zwave.parse(description, commandClassVersions)
if (cmd) {
result = zwaveEvent(cmd)
}
}
if (result instanceof List) {
result = result.flatten()
}
log.debug "Parsed '$description' to $result"
return result
}
/**
* Triggered when Done button is pushed on Preference Pane
*/
def updated()
{
if(now() - state.lastupdate > 3000){
def isUpdateNeeded = "NO"
if(wakeupInterval != null && state.wakeupInterval != wakeupInterval) {isUpdateNeeded = "YES"}
if (sendType != null && sendType != state.sendType) {isUpdateNeeded = "YES"}
if (led != null && led != state.led) {isUpdateNeeded = "YES"}
state.lastupdate = now()
sendEvent(name:"needUpdate", value: isUpdateNeeded, displayed:false, isStateChange: true)
}
}
/**
* Only device parameter changes require a state change
*/
def update_settings()
{
def cmds = []
def isUpdateNeeded = "NO"
if (state.wakeupInterval != wakeupInterval){
cmds << zwave.wakeUpV2.wakeUpIntervalSet(seconds: wakeupInterval.toInteger(), nodeid:zwaveHubNodeId).format()
cmds << "delay 1000"
cmds << zwave.wakeUpV2.wakeUpIntervalGet().format()
}
if (sendType != state.sendType){
cmds << zwave.configurationV1.configurationSet(parameterNumber: 1, size: 1, configurationValue: [sendType == "binary" ? 0 : sendType == "basic" ? 2 : 1]).format()
cmds << "delay 1000"
cmds << zwave.configurationV1.configurationGet(parameterNumber: 1).format()
}
if (led != state.led){
cmds << zwave.configurationV1.configurationSet(parameterNumber: 2, size: 1, configurationValue: [led == true ? 1 : 0]).format()
cmds << "delay 1000"
cmds << zwave.configurationV1.configurationGet(parameterNumber: 2).format()
}
cmds << "delay 1000"
sendEvent(name:"needUpdate", value: isUpdateNeeded, displayed:false, isStateChange: true)
return cmds
}
def zwaveEvent(physicalgraph.zwave.commands.configurationv1.ConfigurationReport cmd) {
def name = ""
def value = ""
def tmpParm = cmd.parameterNumber
def reportValue = cmd.configurationValue[0]
switch (cmd.parameterNumber) {
case 1:
name = "sendType"
switch (reportValue) {
case 0:
value = "binary"
break
case 1:
value = "notification"
break
case 2:
value = "basic"
break
default:
break
}
state.sendType = value
log.debug "sendType = $value"
break
case 2:
name = "led"
value = reportValue
log.debug "led = $value"
state.led = reportValue == 1 ? true : false
break
default:
break
}
sendEvent(name: name, value: value, displayed: true)
}
def zwaveEvent(physicalgraph.zwave.commands.securityv1.SecurityMessageEncapsulation cmd) {
def encapsulatedCommand = cmd.encapsulatedCommand(commandClassVersions)
log.debug "encapsulated: $encapsulatedCommand"
if (encapsulatedCommand) {
state.sec = 1
return zwaveEvent(encapsulatedCommand)
} else {
log.warn "Unable to extract encapsulated cmd from $cmd"
return [createEvent(descriptionText: cmd.toString())]
}
}
def sensorValueEvent(value) {
//If the invertOutput parameter is set, logically invert the output value
def flip = 0
if (state.sendType == "notification"){
flip = value ^ 0x1}
else{
flip = value ^ 0xFF}
if (invertOutput) {value = flip}
if (value) {
createEvent(name: "contact", value: "open", descriptionText: "$device.displayName is open")
} else {
createEvent(name: "contact", value: "closed", descriptionText: "$device.displayName is closed")
}
}
def zwaveEvent(physicalgraph.zwave.commands.basicv1.BasicReport cmd) {
return sensorValueEvent(cmd.value)
}
def zwaveEvent(physicalgraph.zwave.commands.basicv1.BasicSet cmd) {
return sensorValueEvent(cmd.value)
}
def zwaveEvent(physicalgraph.zwave.commands.sensorbinaryv1.SensorBinaryReport cmd) {
return sensorValueEvent(cmd.sensorValue)
}
def zwaveEvent(physicalgraph.zwave.commands.sensoralarmv1.SensorAlarmReport cmd) {
return sensorValueEvent(cmd.sensorState)
}
def zwaveEvent(physicalgraph.zwave.commands.notificationv3.NotificationReport cmd) {
def result = []
if (cmd.notificationType == 0x06 && cmd.event == 0x16) {
result << sensorValueEvent(1)
} else if (cmd.notificationType == 0x06 && cmd.event == 0x17) {
result << sensorValueEvent(0)
} else if (cmd.notificationType == 0x07) {
if (cmd.event == 0x00) {
if (cmd.eventParametersLength == 0 || cmd.eventParameter[0] != 3) {
result << createEvent(descriptionText: "$device.displayName covering replaced", isStateChange: true, displayed: false)
} else {
result << sensorValueEvent(0)
}
} else if (cmd.event == 0x01 || cmd.event == 0x02) {
result << sensorValueEvent(1)
} else if (cmd.event == 0x03) {
result << createEvent(descriptionText: "$device.displayName covering was removed", isStateChange: true)
if (!device.currentState("ManufacturerCode")) {
result << response(secure(zwave.manufacturerSpecificV1.manufacturerSpecificGet()))
}
} else if (cmd.event == 0x04) {
def timeString1 = new Date().format("MMM d", location.timeZone)
def timeString2 = new Date().format("hh:mm:ss", location.timeZone)
result << createEvent(name: "tamper", value: "Tampered\n${timeString1}\n${timeString2}", descriptionText: "$device.displayName was tampered with at ${timeString1} ${timeString2}", isStateChange: true)
if (!ignoreWakeup) {
sendEvent(name:"WakeUp", value: "Manual Wakeup", descriptionText: "${device.displayName} woke up", isStateChange: true, displayed: true)
result << doWakeup()
}
} else if (cmd.event == 0x05 || cmd.event == 0x06) {
result << createEvent(descriptionText: "$device.displayName detected glass breakage", isStateChange: true)
} else {
result << createEvent(descriptionText: "$device.displayName event $cmd.event ${cmd.eventParameter.inspect()}", isStateChange: true, displayed: false)
}
} else if (cmd.notificationType) {
result << createEvent(descriptionText: "$device.displayName notification $cmd.notificationType event $cmd.event ${cmd.eventParameter.inspect()}", isStateChange: true, displayed: false)
} else {
def value = cmd.v1AlarmLevel == 255 ? "active" : cmd.v1AlarmLevel ?: "inactive"
result << createEvent(name: "alarm $cmd.v1AlarmType", value: value, isStateChange: true, displayed: false)
}
return result
}
def zwaveEvent(physicalgraph.zwave.commands.wakeupv2.WakeUpNotification cmd) {
def event = createEvent(name: "WakeUp", value: "Auto Wakeup", descriptionText: "${device.displayName} woke up", isStateChange: true, displayed: true)
def cmds = []
if (!device.currentState("ManufacturerCode")) {
cmds << zwave.manufacturerSpecificV1.manufacturerSpecificGet().format()
cmds << "delay 2000"
}
if (!state.lastbat || now() - state.lastbat > 23*60*60*1000) { //check no sooner than once every 23 hours (once a day)
log.debug "checking battery"
event.descriptionText += ", requesting battery"
cmds << zwave.batteryV1.batteryGet().format()
cmds << "delay 2000"
} else {
log.debug "not checking battery, was updated ${(now() - state.lastbat)/60000 as int} min ago"
}
if (device.currentValue("needUpdate") == "YES") { cmds += update_settings() }
cmds << zwave.wakeUpV2.wakeUpNoMoreInformation().format()
return [event, response(cmds)]
}
def zwaveEvent(physicalgraph.zwave.commands.batteryv1.BatteryReport cmd) {
def map = [ name: "battery", unit: "%" ]
if (cmd.batteryLevel == 0xFF) {
map.value = 1
map.descriptionText = "${device.displayName} has a low battery"
map.isStateChange = true
} else {
map.value = cmd.batteryLevel
}
def event = createEvent(map)
map.isStateChange = true
state.lastbat = now()
return [event]
}
def zwaveEvent(physicalgraph.zwave.commands.manufacturerspecificv1.ManufacturerSpecificReport cmd) {
def result = []
def manufacturerCode = String.format("%04X", cmd.manufacturerId)
def productTypeCode = String.format("%04X", cmd.productTypeId)
def productCode = String.format("%04X", cmd.productId)
def wirelessConfig = "ZWP"
updateDataValue("Manufacturer", cmd.manufacturerName)
updateDataValue("Manufacturer ID", manufacturerCode)
updateDataValue("Product Type", productTypeCode)
updateDataValue("Product Code", productCode)
return result
}
def zwaveEvent(physicalgraph.zwave.Command cmd) {
return [createEvent(descriptionText: "$device.displayName: $cmd", displayed: false)]
}
private secure(physicalgraph.zwave.Command cmd) {
if (state.sec == 0) { // default to secure
cmd.format()
} else {
zwave.securityV1.securityMessageEncapsulation().encapsulate(cmd).format()
}
}
private secureSequence(commands, delay=200) {
delayBetween(commands.collect{ secure(it) }, delay)
}
def buildInterval() {
def intervalList = []
intervalList << [ "0" : "Disabled" ]
intervalList << [ "1800" : "30 minutes" ]
intervalList << [ "3600" : "1 hour" ]
intervalList << [ "7200" : "2 hours" ]
intervalList << [ "10800" : "3 hours" ]
intervalList << [ "14400" : "4 hours" ]
intervalList << [ "18000" : "5 hours" ]
intervalList << [ "21600" : "6 hours" ]
intervalList << [ "36000" : "10 hours" ]
intervalList << [ "43200" : "12 hours" ]
intervalList << [ "86400" : "24 hours" ]
}
def doWakeup() {
def cmds = []
cmds << "delay 2000"
if (device.currentValue("needUpdate") == "YES") { cmds += update_settings() }
cmds << zwave.wakeUpV2.wakeUpNoMoreInformation().format()
return response(cmds)
}
def refresh() {
sendEvent(name: "tamper", value: "No Tamper", displayed: false)
}
def zwaveEvent(physicalgraph.zwave.commands.versionv1.VersionReport cmd) {
def appversion = String.format("%02d.%02d", cmd.applicationVersion, cmd.applicationSubVersion)
def zprotoversion = String.format("%d.%02d", cmd.zWaveProtocolVersion, cmd.zWaveProtocolSubVersion)
updateDataValue("zWave Library", cmd.zWaveLibraryType.toString())
updateDataValue("Firmware", appversion)
updateDataValue("zWave Version", zprotoversion)
sendEvent(name: "Firmware", value: appversion, displayed: true)
}
def zwaveEvent(physicalgraph.zwave.commands.wakeupv2.WakeUpIntervalReport cmd) {
state.wakeupInterval = cmd.seconds.toString()
sendEvent(name: "wakeupInterval", value: state.wakeupInterval, displayed: true)
}

View File

@@ -0,0 +1,426 @@
// Express Controls EZMultiPli Multi-sensor
// Motion Sensor - Temperature - Light level - 8 Color Indicator LED - Z-Wave Range Extender - Wall Powered
// driver for SmartThings
// The EZMultiPli is also known as the HSM200 from HomeSeer.com
//
// 2017-04-10 - DrZwave (with help from Don Kirker) - changed fingerprint to the new format, lowered the OnTime
// and other parameters to be "more in line with ST user expectations", get the luminance in LUX so it reports in lux all the time.
// 2016-10-06 - erocm1231 - Added "updated" method to run when configuration options are changed. Depending on model of unit, luminance is being
// reported as a relative percentace or as a lux value. Added the option to configure this in the handler.
// 2016-01-28 - erocm1231 - Changed the configuration method to use scaledConfiguration so that it properly formatted negative numbers.
// Also, added configurationGet and a configurationReport method so that config values can be verified.
// 2015-12-04 - erocm1231 - added range value to preferences as suggested by @Dela-Rick.
// 2015-11-26 - erocm1231 - Fixed null condition error when adding as a new device.
// 2015-11-24 - erocm1231 - Added refresh command. Made a few changes to how the handler maps colors to the LEDs. Fixed
// the device not having its on/off status updated when colors are changed.
// 2015-11-23 - erocm1231 - Changed the look to match SmartThings v2 devices.
// 2015-11-21 - erocm1231 - Made code much more efficient. Also made it compatible when setColor is passed a hex value.
// Mapping of special colors: Soft White - Default - Yellow, White - Concentrate - White,
// Daylight - Energize - Teal, Warm White - Relax - Yellow
// 2015-11-19 - erocm1231 - Fixed a couple incorrect colors, changed setColor to be more compatible with other apps
// 2015-11-18 - erocm1231 - Added to setColor for compatibility with Smart Lighting
// v0.1.0 - DrZWave - chose better icons, Got color LED to work - first fully functional version
// v0.0.9 - jrs - got the temp and luminance to work. Motion works. Debugging the color wheel.
// v0.0.8 - DrZWave 2/25/2015 - change the color control to be tiles since there are only 8 colors.
// v0.0.7 - jrs - 02/23/2015 - Jim Sulin
metadata {
definition (name: "EZmultiPli", namespace: "DrZWave", author: "Eric Ryherd", oauth: true) {
capability "Actuator"
capability "Sensor"
capability "Motion Sensor"
capability "Temperature Measurement"
capability "Illuminance Measurement"
capability "Switch"
capability "Color Control"
capability "Configuration"
capability "Refresh"
fingerprint mfr: "001E", prod: "0004", model: "0001" // new format for Fingerprint which is unique for every certified Z-Wave product
} // end definition
simulator {
// messages the device returns in response to commands it receives
status "motion" : "command: 7105000000FF07, payload: 07"
status "no motion" : "command: 7105000000FF07, payload: 00"
for (int i = 0; i <= 100; i += 20) {
status "temperature ${i}F": new physicalgraph.zwave.Zwave().sensorMultilevelV5.sensorMultilevelReport(
scaledSensorValue: i, precision: 1, sensorType: 1, scale: 1).incomingMessage()
}
for (int i = 0; i <= 100; i += 20) {
status "luminance ${i} %": new physicalgraph.zwave.Zwave().sensorMultilevelV5.sensorMultilevelReport(
scaledSensorValue: i, precision: 0, sensorType: 3).incomingMessage()
}
} //end simulator
tiles (scale: 2){
multiAttributeTile(name:"switch", type: "lighting", width: 6, height: 4, canChangeIcon: true){
tileAttribute ("device.switch", key: "PRIMARY_CONTROL", icon: "st.Lighting.light18") {
attributeState "on", label:'${name}', action:"switch.off", icon:"st.switches.light.on", backgroundColor:"#79b821", nextState:"turningOff"
attributeState "off", label:'${name}', action:"switch.on", icon:"st.switches.light.off", backgroundColor:"#ffffff", nextState:"turningOn"
attributeState "turningOn", label:'${name}', icon:"st.switches.light.on", backgroundColor:"#79b821"
attributeState "turningOff", label:'${name}', icon:"st.switches.light.off", backgroundColor:"#ffffff"
}
tileAttribute ("device.color", key: "COLOR_CONTROL") {
attributeState "color", action:"setColor"
}
tileAttribute ("statusText", key: "SECONDARY_CONTROL") {
attributeState "statusText", label:'${currentValue}'
}
}
standardTile("motion", "device.motion", width: 2, height: 2, canChangeIcon: true, canChangeBackground: true) {
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", width: 2, height: 2) {
state "temperature", label:'${currentValue}°', unit:"F", icon:"", // would be better if the units would switch to the desired units of the system (imperial or metric)
backgroundColors:[
[value: 0, color: "#1010ff"], // blue=cold
[value: 65, color: "#a0a0f0"],
[value: 70, color: "#e0e050"],
[value: 75, color: "#f0d030"], // yellow
[value: 80, color: "#fbf020"],
[value: 85, color: "#fbdc01"],
[value: 90, color: "#fb3a01"],
[value: 95, color: "#fb0801"] // red=hot
]
}
// icons to use would be st.Weather.weather2 or st.alarm.temperature.normal - see http://scripts.3dgo.net/smartthings/icons/ for a list of icons
valueTile("illuminance", "device.illuminance", width: 2, height: 2, inactiveLabel: false) {
// jrs 4/7/2015 - Null on display
//state "luminosity", label:'${currentValue} ${unit}'
state "luminosity", label:'${currentValue}', unit:'${currentValue}', icon:"",
backgroundColors:[
[value: 25, color: "#404040"],
[value: 50, color: "#808080"],
[value: 75, color: "#a0a0a0"],
[value: 90, color: "#e0e0e0"],
//lux measurement values
[value: 150, color: "#404040"],
[value: 300, color: "#808080"],
[value: 600, color: "#a0a0a0"],
[value: 900, color: "#e0e0e0"]
]
}
standardTile("refresh", "device.switch", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
state "default", label:"", action:"refresh.refresh", icon:"st.secondary.refresh"
}
standardTile("configure", "device.configure", inactiveLabel: false, width: 2, height: 2, decoration: "flat") {
state "configure", label:'', action:"configuration.configure", icon:"st.secondary.configure"
}
main (["temperature","motion", "switch"])
details(["switch", "motion", "temperature", "illuminance", "refresh", "configure"])
} // end tiles
preferences {
input "OnTime", "number", title: "No Motion Interval", description: "N minutes lights stay on after no motion detected [0, 1-127]", range: "0..127", defaultValue: 2, displayDuringSetup: true, required: false
input "OnLevel", "number", title: "Dimmer Onlevel", description: "Dimmer OnLevel for associated node 2 lights [-1, 0, 1-99]", range: "-1..99", defaultValue: -1, displayDuringSetup: true, required: false
input "LiteMin", "number", title: "Luminance Report Frequency", description: "Luminance report sent every N minutes [0-127]", range: "0..127", defaultValue: 6, displayDuringSetup: true, required: false
input "TempMin", "number", title: "Temperature Report Frequency", description: "Temperature report sent every N minutes [0-127]", range: "0..127", defaultValue: 6, displayDuringSetup: true, required: false
input "TempAdj", "number", title: "Temperature Calibration", description: "Adjust temperature up/down N tenths of a degree F [(-127)-(+128)]", range: "-127..128", defaultValue: 0, displayDuringSetup: true, required: false
input("lum", "enum", title:"Illuminance Measurement", description: "Percent or Lux", defaultValue: 2 ,required: false, displayDuringSetup: true, options:
[1:"Percent",
2:"Lux"])
}
} // end metadata
// Parse incoming device messages from device to generate events
def parse(String description){
//log.debug "==> New Zwave Event: ${description}"
def result = []
def cmd = zwave.parse(description, [0x31: 5]) // 0x31=SensorMultilevel which we force to be version 5
if (cmd) {
def cmdData = zwaveEvent(cmd)
if (cmdData != [:])
result << createEvent(cmdData)
}
def statusTextmsg = ""
if (device.currentState('temperature') != null && device.currentState('illuminance') != null) {
statusTextmsg = "${device.currentState('temperature').value} ° - ${device.currentState('illuminance').value} ${(lum == "" || lum == null || lum == 1) ? "%" : "LUX"}"
sendEvent("name":"statusText", "value":statusTextmsg, displayed:false)
}
if (result != [null] && result != []) log.debug "Parse returned ${result}"
return result
}
// Event Generation
def zwaveEvent(physicalgraph.zwave.commands.sensormultilevelv5.SensorMultilevelReport cmd){
def map = [:]
switch (cmd.sensorType) {
case 0x01: // SENSOR_TYPE_TEMPERATURE_VERSION_1
def cmdScale = cmd.scale == 1 ? "F" : "C"
map.value = convertTemperatureIfNeeded(cmd.scaledSensorValue, cmdScale, cmd.precision)
map.unit = getTemperatureScale()
map.name = "temperature"
log.debug "Temperature report"
break;
case 0x03 : // SENSOR_TYPE_LUMINANCE_VERSION_1
map.value = cmd.scaledSensorValue.toInteger().toString()
if(lum == "" || lum == null || lum == 1) map.unit = "%"
else map.unit = "lux"
map.name = "illuminance"
log.debug "Luminance report"
break;
}
return map
}
def zwaveEvent(physicalgraph.zwave.commands.configurationv2.ConfigurationReport cmd) {
log.debug "${device.displayName} parameter '${cmd.parameterNumber}' with a byte size of '${cmd.size}' is set to '${cmd.configurationValue}'"
}
def zwaveEvent(physicalgraph.zwave.commands.notificationv3.NotificationReport cmd) {
def map = [:]
if (cmd.notificationType==0x07) { // NOTIFICATION_TYPE_BURGLAR
if (cmd.event==0x07 || cmd.event==0x08) {
map.name = "motion"
map.value = "active"
map.descriptionText = "$device.displayName motion detected"
log.debug "motion recognized"
} else if (cmd.event==0) {
map.name = "motion"
map.value = "inactive"
map.descriptionText = "$device.displayName no motion detected"
log.debug "No motion recognized"
}
}
if (map.name != "motion") {
log.debug "unmatched parameters for cmd: ${cmd.toString()}}"
}
return map
}
def zwaveEvent(physicalgraph.zwave.commands.basicv1.BasicReport cmd) {
if (cmd.value == 0 && device.latestState("color").value != "#ffffff") {
sendEvent(name: "color", value: "#ffffff", displayed: true)
}
[name: "switch", value: cmd.value ? "on" : "off", type: "digital"]
}
def updated()
{
log.debug "updated() is being called"
def cmds = configure()
if (cmds != []) response(cmds)
}
def on() {
log.debug "Turning Light 'on'"
delayBetween([
zwave.basicV1.basicSet(value: 0xFF).format(),
zwave.basicV1.basicGet().format()
], 500)
}
def off() {
log.debug "Turning Light 'off'"
delayBetween([
zwave.basicV1.basicSet(value: 0x00).format(),
zwave.basicV1.basicGet().format()
], 500)
}
def setColor(value) {
log.debug "setColor() : ${value}"
def myred
def mygreen
def myblue
def hexValue
def cmds = []
if ( value.level == 1 && value.saturation > 20) {
def rgb = huesatToRGB(value.hue as Integer, 100)
myred = rgb[0] >=128 ? 255 : 0
mygreen = rgb[1] >=128 ? 255 : 0
myblue = rgb[2] >=128 ? 255 : 0
}
else if ( value.level > 1 ) {
def rgb = huesatToRGB(value.hue as Integer, value.saturation as Integer)
myred = rgb[0] >=128 ? 255 : 0
mygreen = rgb[1] >=128 ? 255 : 0
myblue = rgb[2] >=128 ? 255 : 0
}
else if (value.hex) {
def rgb = value.hex.findAll(/[0-9a-fA-F]{2}/).collect { Integer.parseInt(it, 16) }
myred = rgb[0] >=128 ? 255 : 0
mygreen = rgb[1] >=128 ? 255 : 0
myblue = rgb[2] >=128 ? 255 : 0
}
else {
myred=value.red >=128 ? 255 : 0 // the EZMultiPli has just on/off for each of the 3 channels RGB so convert the 0-255 value into 0 or 255.
mygreen=value.green >=128 ? 255 : 0
myblue=value.blue>=128 ? 255 : 0
}
//log.debug "Red: ${myred} Green: ${mygreen} Blue: ${myblue}"
//cmds << zwave.colorControlV1.stateSet(stateDataLength: 3, VariantGroup1: [0x02, myred], VariantGroup2:[ 0x03, mygreen], VariantGroup3:[0x04,myblue]).format() // ST support for this command as of 2015/02/23 does not support the color IDs so this command cannot be used.
// So instead we'll use these commands to hack around the lack of support of the above command
cmds << zwave.basicV1.basicSet(value: 0x00).format() // As of 2015/02/23 ST is not supporting stateSet properly but found this hack that works.
if (myred!=0) {
cmds << zwave.colorControlV1.startCapabilityLevelChange(capabilityId: 0x02, startState: myred, ignoreStartState: True, updown: True).format()
cmds << zwave.colorControlV1.stopStateChange(capabilityId: 0x02).format()
}
if (mygreen!=0) {
cmds << zwave.colorControlV1.startCapabilityLevelChange(capabilityId: 0x03, startState: mygreen, ignoreStartState: True, updown: True).format()
cmds << zwave.colorControlV1.stopStateChange(capabilityId: 0x03).format()
}
if (myblue!=0) {
cmds << zwave.colorControlV1.startCapabilityLevelChange(capabilityId: 0x04, startState: myblue, ignoreStartState: True, updown: True).format()
cmds << zwave.colorControlV1.stopStateChange(capabilityId: 0x04).format()
}
cmds << zwave.basicV1.basicGet().format()
hexValue = rgbToHex([r:myred, g:mygreen, b:myblue])
if(hexValue) sendEvent(name: "color", value: hexValue, displayed: true)
delayBetween(cmds, 100)
}
def zwaveEvent(physicalgraph.zwave.Command cmd) {
// Handles all Z-Wave commands we aren't interested in
[:]
}
// ensure we are passing acceptable param values for LiteMin & TempMin configs
def checkLiteTempInput(value) {
if (value == null) {
value=60
}
def liteTempVal = value.toInteger()
switch (liteTempVal) {
case { it < 0 }:
return 60 // bad value, set to default
break
case { it > 127 }:
return 127 // bad value, greater then MAX, set to MAX
break
default:
return liteTempVal // acceptable value
}
}
// ensure we are passing acceptable param value for OnTime config
def checkOnTimeInput(value) {
if (value == null) {
value=10
}
def onTimeVal = value.toInteger()
switch (onTimeVal) {
case { it < 0 }:
return 10 // bad value set to default
break
case { it > 127 }:
return 127 // bad value, greater then MAX, set to MAX
break
default:
return onTimeVal // acceptable value
}
}
// ensure we are passing acceptable param value for OnLevel config
def checkOnLevelInput(value) {
if (value == null) {
value=99
}
def onLevelVal = value.toInteger()
switch (onLevelVal) {
case { it < -1 }:
return -1 // bad value set to default
break
case { it > 99 }:
return 99 // bad value, greater then MAX, set to MAX
break
default:
return onLevelVal // acceptable value
}
}
// ensure we are passing an acceptable param value for TempAdj configs
def checkTempAdjInput(value) {
if (value == null) {
value=0
}
def tempAdjVal = value.toInteger()
switch (tempAdjVal) {
case { it < -127 }:
return 0 // bad value, set to default
break
case { it > 128 }:
return 128 // bad value, greater then MAX, set to MAX
break
default:
return tempAdjVal // acceptable value
}
}
def refresh() {
def cmd = []
cmd << zwave.switchColorV3.switchColorGet().format()
cmd << zwave.sensorMultilevelV5.sensorMultilevelGet(sensorType:1, scale:1).format()
cmd << zwave.sensorMultilevelV5.sensorMultilevelGet(sensorType:3, scale:1).format()
cmd << zwave.basicV1.basicGet().format()
delayBetween(cmd, 1000)
}
def configure() {
log.debug "OnTime=${settings.OnTime} OnLevel=${settings.OnLevel} TempAdj=${settings.TempAdj}"
def cmd = delayBetween([
zwave.configurationV1.configurationSet(parameterNumber: 1, size: 1, scaledConfigurationValue: checkOnTimeInput(settings.OnTime)).format(),
zwave.configurationV1.configurationSet(parameterNumber: 2, size: 1, scaledConfigurationValue: checkOnLevelInput(settings.OnLevel)).format(),
zwave.configurationV1.configurationSet(parameterNumber: 3, size: 1, scaledConfigurationValue: checkLiteTempInput(settings.LiteMin)).format(),
zwave.configurationV1.configurationSet(parameterNumber: 4, size: 1, scaledConfigurationValue: checkLiteTempInput(settings.TempMin)).format(),
zwave.configurationV1.configurationSet(parameterNumber: 5, size: 1, scaledConfigurationValue: checkTempAdjInput(settings.TempAdj)).format(),
zwave.configurationV1.configurationGet(parameterNumber: 1).format(),
zwave.configurationV1.configurationGet(parameterNumber: 2).format(),
zwave.configurationV1.configurationGet(parameterNumber: 3).format(),
zwave.configurationV1.configurationGet(parameterNumber: 4).format(),
zwave.configurationV1.configurationGet(parameterNumber: 5).format()
], 100)
//log.debug cmd
cmd + refresh()
}
def huesatToRGB(float hue, float sat) {
while(hue >= 100) hue -= 100
int h = (int)(hue / 100 * 6)
float f = hue / 100 * 6 - h
int p = Math.round(255 * (1 - (sat / 100)))
int q = Math.round(255 * (1 - (sat / 100) * f))
int t = Math.round(255 * (1 - (sat / 100) * (1 - f)))
switch (h) {
case 0: return [255, t, p]
case 1: return [q, 255, p]
case 2: return [p, 255, t]
case 3: return [p, q, 255]
case 4: return [t, p, 255]
case 5: return [255, p, q]
}
}
def rgbToHex(rgb) {
def r = hex(rgb.r)
def g = hex(rgb.g)
def b = hex(rgb.b)
def hexColor = "#${r}${g}${b}"
hexColor
}
private hex(value, width=2) {
def s = new BigInteger(Math.round(value).toString()).toString(16)
while (s.size() < width) {
s = "0" + s
}
s
}

View File

@@ -14,13 +14,13 @@
*
*/
metadata {
definition (name: "Fibaro Door/Window Sensor ZW5 with Temperature", namespace: "fibargroup", author: "Fibar Group S.A.") {
definition (name: "Fibaro Door/Window Sensor ZW5 with Temperature", namespace: "fibargroup", author: "Fibar Group S.A.", ocfDeviceType: "x.com.st.d.sensor.contact") {
capability "Battery"
capability "Contact Sensor"
capability "Sensor"
capability "Configuration"
capability "Tamper Alert"
capability "Temperature Measurement"
fingerprint deviceId: "0x0701", inClusters: "0x5E, 0x85, 0x59, 0x22, 0x20, 0x80, 0x70, 0x56, 0x5A, 0x7A, 0x72, 0x8E, 0x71, 0x73, 0x98, 0x2B, 0x9C, 0x30, 0x31, 0x86", outClusters: ""
@@ -28,26 +28,26 @@ metadata {
}
simulator {
}
tiles(scale: 2) {
multiAttributeTile(name:"FGK", type:"lighting", width:6, height:4) {//with generic type secondary control text is not displayed in Android app
tileAttribute("device.contact", key:"PRIMARY_CONTROL") {
attributeState("open", icon:"st.contact.contact.open", backgroundColor:"#e86d13")
attributeState("closed", icon:"st.contact.contact.closed", backgroundColor:"#00a0dc")
}
tileAttribute("device.tamper", key:"SECONDARY_CONTROL") {
attributeState("active", label:'tamper active', backgroundColor:"#53a7c0")
attributeState("inactive", label:'tamper inactive', backgroundColor:"#ffffff")
}
}
}
valueTile("battery", "device.battery", inactiveLabel: false, width: 2, height: 2, decoration: "flat") {
state "battery", label:'${currentValue}% battery', unit:""
}
valueTile("temperature", "device.temperature", inactiveLabel: false, width: 2, height: 2) {
state "temperature", label:'${currentValue}°',
backgroundColors:[
@@ -60,7 +60,7 @@ metadata {
[value: 96, color: "#bc2323"]
]
}
main "FGK"
details(["FGK","battery", "temperature"])
}
@@ -68,9 +68,9 @@ metadata {
// parse events into attributes
def parse(String description) {
log.debug "Parsing '${description}'"
log.debug "Parsing '${description}'"
def result = []
if (description.startsWith("Err 106")) {
if (state.sec) {
result = createEvent(descriptionText:description, displayed:false)
@@ -87,7 +87,7 @@ def parse(String description) {
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])
if (cmd) {
log.debug "Parsed '${cmd}'"
zwaveEvent(cmd)
@@ -125,13 +125,13 @@ def zwaveEvent(physicalgraph.zwave.commands.notificationv3.NotificationReport cm
//(parameter 20 was not changed before device's re-inclusion)
def map = [:]
if (cmd.notificationType == 6) {
switch (cmd.event) {
switch (cmd.event) {
case 22:
map.name = "contact"
map.value = "open"
map.descriptionText = "${device.displayName}: is open"
break
case 23:
map.name = "contact"
map.value = "closed"
@@ -145,7 +145,7 @@ def zwaveEvent(physicalgraph.zwave.commands.notificationv3.NotificationReport cm
map.value = "inactive"
map.descriptionText = "${device.displayName}: tamper alarm has been deactivated"
break
case 3:
map.name = "tamper"
map.value = "active"
@@ -153,7 +153,7 @@ def zwaveEvent(physicalgraph.zwave.commands.notificationv3.NotificationReport cm
break
}
}
createEvent(map)
}
@@ -166,7 +166,7 @@ def zwaveEvent(physicalgraph.zwave.commands.batteryv1.BatteryReport cmd) {
createEvent(map)
}
def zwaveEvent(physicalgraph.zwave.commands.wakeupv2.WakeUpNotification cmd) {
def zwaveEvent(physicalgraph.zwave.commands.wakeupv2.WakeUpNotification cmd) {
def event = createEvent(descriptionText: "${device.displayName} woke up", displayed: false)
def cmds = []
cmds << encap(zwave.batteryV1.batteryGet())
@@ -177,32 +177,32 @@ def zwaveEvent(physicalgraph.zwave.commands.wakeupv2.WakeUpNotification cmd) {
[event, response(cmds)]
}
def zwaveEvent(physicalgraph.zwave.commands.manufacturerspecificv2.ManufacturerSpecificReport cmd) {
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}"
}
def zwaveEvent(physicalgraph.zwave.commands.manufacturerspecificv2.DeviceSpecificReport cmd) {
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
String serialNumber = "h'"
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) {
def zwaveEvent(physicalgraph.zwave.commands.versionv1.VersionReport cmd) {
updateDataValue("version", "${cmd.applicationVersion}.${cmd.applicationSubVersion}")
log.debug "applicationVersion: ${cmd.applicationVersion}"
log.debug "applicationSubVersion: ${cmd.applicationSubVersion}"
@@ -221,7 +221,7 @@ def zwaveEvent(physicalgraph.zwave.commands.sensormultilevelv5.SensorMultilevelR
map.name = "temperature"
map.displayed = true
}
createEvent(map)
}
@@ -231,9 +231,9 @@ def zwaveEvent(physicalgraph.zwave.commands.deviceresetlocallyv1.DeviceResetLoca
def configure() {
log.debug "Executing 'configure'"
def cmds = []
cmds += zwave.wakeUpV2.wakeUpIntervalSet(seconds:21600, nodeid: zwaveHubNodeId)//FGK's default wake up interval
cmds += zwave.manufacturerSpecificV2.manufacturerSpecificGet()
cmds += zwave.manufacturerSpecificV2.deviceSpecificGet()
@@ -242,7 +242,7 @@ def configure() {
cmds += zwave.sensorMultilevelV5.sensorMultilevelGet(sensorType: 1, scale: 0)
cmds += zwave.associationV2.associationSet(groupingIdentifier:1, nodeId: [zwaveHubNodeId])
cmds += zwave.wakeUpV2.wakeUpNoMoreInformation()
encapSequence(cmds, 500)
}
@@ -261,7 +261,7 @@ private encapSequence(commands, delay=200) {
private encap(physicalgraph.zwave.Command cmd) {
def secureClasses = [0x20, 0x2B, 0x30, 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 }) {
@@ -269,4 +269,4 @@ private encap(physicalgraph.zwave.Command cmd) {
} else {
crc16(cmd)
}
}
}

View File

@@ -14,7 +14,7 @@
*
*/
metadata {
definition (name: "Fibaro Door/Window Sensor ZW5", namespace: "fibargroup", author: "Fibar Group S.A.") {
definition (name: "Fibaro Door/Window Sensor ZW5", namespace: "fibargroup", author: "Fibar Group S.A.", ocfDeviceType: "x.com.st.d.sensor.contact") {
capability "Battery"
capability "Contact Sensor"
capability "Sensor"
@@ -26,26 +26,26 @@ metadata {
}
simulator {
}
tiles(scale: 2) {
multiAttributeTile(name:"FGK", type:"lighting", width:6, height:4) {//with generic type secondary control text is not displayed in Android app
tileAttribute("device.contact", key:"PRIMARY_CONTROL") {
attributeState("open", icon:"st.contact.contact.open", backgroundColor:"#e86d13")
attributeState("closed", icon:"st.contact.contact.closed", backgroundColor:"#00a0dc")
}
tileAttribute("device.tamper", key:"SECONDARY_CONTROL") {
attributeState("active", label:'tamper active', backgroundColor:"#53a7c0")
attributeState("inactive", label:'tamper inactive', backgroundColor:"#ffffff")
}
}
}
valueTile("battery", "device.battery", inactiveLabel: false, width: 2, height: 2, decoration: "flat") {
state "battery", label:'${currentValue}% battery', unit:""
}
main "FGK"
details(["FGK","battery"])
}
@@ -53,9 +53,9 @@ metadata {
// parse events into attributes
def parse(String description) {
log.debug "Parsing '${description}'"
log.debug "Parsing '${description}'"
def result = []
if (description.startsWith("Err 106")) {
if (state.sec) {
result = createEvent(descriptionText:description, displayed:false)
@@ -72,7 +72,7 @@ def parse(String description) {
return null
} else {
def cmd = zwave.parse(description, [0x56: 1, 0x71: 3, 0x72: 2, 0x80: 1, 0x84: 2, 0x85: 2, 0x86: 1, 0x98: 1])
if (cmd) {
log.debug "Parsed '${cmd}'"
zwaveEvent(cmd)
@@ -110,13 +110,13 @@ def zwaveEvent(physicalgraph.zwave.commands.notificationv3.NotificationReport cm
//(parameter 20 was not changed before device's re-inclusion)
def map = [:]
if (cmd.notificationType == 6) {
switch (cmd.event) {
switch (cmd.event) {
case 22:
map.name = "contact"
map.value = "open"
map.descriptionText = "${device.displayName}: is open"
break
case 23:
map.name = "contact"
map.value = "closed"
@@ -130,7 +130,7 @@ def zwaveEvent(physicalgraph.zwave.commands.notificationv3.NotificationReport cm
map.value = "inactive"
map.descriptionText = "${device.displayName}: tamper alarm has been deactivated"
break
case 3:
map.name = "tamper"
map.value = "active"
@@ -138,7 +138,7 @@ def zwaveEvent(physicalgraph.zwave.commands.notificationv3.NotificationReport cm
break
}
}
createEvent(map)
}
@@ -151,7 +151,7 @@ def zwaveEvent(physicalgraph.zwave.commands.batteryv1.BatteryReport cmd) {
createEvent(map)
}
def zwaveEvent(physicalgraph.zwave.commands.wakeupv2.WakeUpNotification cmd) {
def zwaveEvent(physicalgraph.zwave.commands.wakeupv2.WakeUpNotification cmd) {
def event = createEvent(descriptionText: "${device.displayName} woke up", displayed: false)
def cmds = []
cmds << encap(zwave.batteryV1.batteryGet())
@@ -160,32 +160,32 @@ def zwaveEvent(physicalgraph.zwave.commands.wakeupv2.WakeUpNotification cmd) {
[event, response(cmds)]
}
def zwaveEvent(physicalgraph.zwave.commands.manufacturerspecificv2.ManufacturerSpecificReport cmd) {
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}"
}
def zwaveEvent(physicalgraph.zwave.commands.manufacturerspecificv2.DeviceSpecificReport cmd) {
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
String serialNumber = "h'"
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) {
def zwaveEvent(physicalgraph.zwave.commands.versionv1.VersionReport cmd) {
updateDataValue("version", "${cmd.applicationVersion}.${cmd.applicationSubVersion}")
log.debug "applicationVersion: ${cmd.applicationVersion}"
log.debug "applicationSubVersion: ${cmd.applicationSubVersion}"
@@ -204,7 +204,7 @@ def configure() {
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)//FGK's default wake up interval
cmds += zwave.manufacturerSpecificV2.manufacturerSpecificGet()
cmds += zwave.manufacturerSpecificV2.deviceSpecificGet()
@@ -212,7 +212,7 @@ def configure() {
cmds += zwave.batteryV1.batteryGet()
cmds += zwave.associationV2.associationSet(groupingIdentifier:1, nodeId: [zwaveHubNodeId])
cmds += zwave.wakeUpV2.wakeUpNoMoreInformation()
encapSequence(cmds, 500)
}
@@ -231,7 +231,7 @@ private encapSequence(commands, delay=200) {
private encap(physicalgraph.zwave.Command cmd) {
def secureClasses = [0x20, 0x2B, 0x30, 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 }) {
@@ -239,4 +239,4 @@ private encap(physicalgraph.zwave.Command cmd) {
} else {
crc16(cmd)
}
}
}

View File

@@ -14,7 +14,7 @@
*
*/
metadata {
definition (name: "Fibaro Flood Sensor ZW5", namespace: "fibargroup", author: "Fibar Group S.A.") {
definition (name: "Fibaro Flood Sensor ZW5", namespace: "fibargroup", author: "Fibar Group S.A.", ocfDeviceType: "x.com.st.d.sensor.moisture") {
capability "Battery"
capability "Configuration"
capability "Sensor"
@@ -37,13 +37,13 @@ metadata {
attributeState("dry", icon:"st.alarm.water.dry", backgroundColor:"#ffffff")
attributeState("wet", icon:"st.alarm.water.wet", backgroundColor:"#00a0dc")
}
tileAttribute("device.tamper", key:"SECONDARY_CONTROL") {
attributeState("active", label:'tamper active', backgroundColor:"#cccccc")
attributeState("inactive", label:'tamper inactive', backgroundColor:"#00A0DC")
}
}
valueTile("temperature", "device.temperature", inactiveLabel: false, width: 2, height: 2) {
state "temperature", label:'${currentValue}°',
backgroundColors:[
@@ -130,14 +130,14 @@ def zwaveEvent(physicalgraph.zwave.commands.wakeupv2.WakeUpNotification cmd)
[event, response(cmds)]
}
def zwaveEvent(physicalgraph.zwave.commands.manufacturerspecificv2.ManufacturerSpecificReport cmd) {
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}"
}
def zwaveEvent(physicalgraph.zwave.commands.manufacturerspecificv2.DeviceSpecificReport cmd) {
def zwaveEvent(physicalgraph.zwave.commands.manufacturerspecificv2.DeviceSpecificReport cmd) {
log.debug "deviceIdData: ${cmd.deviceIdData}"
log.debug "deviceIdDataFormat: ${cmd.deviceIdDataFormat}"
log.debug "deviceIdDataLengthIndicator: ${cmd.deviceIdDataLengthIndicator}"

View File

@@ -14,7 +14,7 @@
*
*/
metadata {
definition (name: "Fibaro Motion Sensor ZW5", namespace: "fibargroup", author: "Fibar Group S.A.") {
definition (name: "Fibaro Motion Sensor ZW5", namespace: "fibargroup", author: "Fibar Group S.A.", ocfDeviceType: "x.com.st.d.sensor.motion") {
capability "Battery"
capability "Configuration"
capability "Illuminance Measurement"
@@ -23,27 +23,27 @@ metadata {
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: ""
}
simulator {
}
tiles(scale: 2) {
multiAttributeTile(name:"FGMS", type:"lighting", width:6, height:4) {//with generic type secondary control text is not displayed in Android app
tileAttribute("device.motion", key:"PRIMARY_CONTROL") {
attributeState("inactive", label:"no motion", icon:"st.motion.motion.inactive", backgroundColor:"#79b821")
attributeState("active", label:"motion", icon:"st.motion.motion.active", backgroundColor:"#ffa81e")
attributeState("active", label:"motion", icon:"st.motion.motion.active", backgroundColor:"#ffa81e")
}
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) {
state "temperature", label:'${currentValue}°',
backgroundColors:[
@@ -56,15 +56,15 @@ metadata {
[value: 96, color: "#bc2323"]
]
}
valueTile("illuminance", "device.illuminance", inactiveLabel: false, width: 2, height: 2) {
state "luminosity", label:'${currentValue} ${unit}', unit:"lux"
}
valueTile("battery", "device.battery", inactiveLabel: false, width: 2, height: 2, decoration: "flat") {
state "battery", label:'${currentValue}% battery', unit:""
}
main "FGMS"
details(["FGMS","battery","temperature","illuminance"])
}
@@ -72,9 +72,9 @@ metadata {
// parse events into attributes
def parse(String description) {
log.debug "Parsing '${description}'"
log.debug "Parsing '${description}'"
def result = []
if (description.startsWith("Err 106")) {
if (state.sec) {
result = createEvent(descriptionText:description, displayed:false)
@@ -91,7 +91,7 @@ def parse(String description) {
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])
if (cmd) {
log.debug "Parsed '${cmd}'"
zwaveEvent(cmd)
@@ -159,13 +159,13 @@ def zwaveEvent(physicalgraph.zwave.commands.notificationv3.NotificationReport cm
map.descriptionText = "${device.displayName}: motion has stopped"
}
break
case 3:
map.name = "tamper"
map.value = "active"
map.descriptionText = "${device.displayName}: tamper alarm activated"
break
case 8:
map.name = "motion"
map.value = "active"
@@ -173,7 +173,7 @@ def zwaveEvent(physicalgraph.zwave.commands.notificationv3.NotificationReport cm
break
}
}
createEvent(map)
}
@@ -194,39 +194,39 @@ def zwaveEvent(physicalgraph.zwave.commands.wakeupv2.WakeUpNotification cmd)
cmds << "delay 500"
cmds << encap(zwave.sensorMultilevelV5.sensorMultilevelGet(sensorType: 1, scale: 0))
cmds << "delay 500"
cmds << encap(zwave.sensorMultilevelV5.sensorMultilevelGet(sensorType: 3, scale: 1))
cmds << encap(zwave.sensorMultilevelV5.sensorMultilevelGet(sensorType: 3, scale: 1))
cmds << "delay 1200"
cmds << encap(zwave.wakeUpV1.wakeUpNoMoreInformation())
[event, response(cmds)]
}
def zwaveEvent(physicalgraph.zwave.commands.manufacturerspecificv2.ManufacturerSpecificReport cmd) {
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}"
}
def zwaveEvent(physicalgraph.zwave.commands.manufacturerspecificv2.DeviceSpecificReport cmd) {
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
String serialNumber = "h'"
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) {
def zwaveEvent(physicalgraph.zwave.commands.versionv1.VersionReport cmd) {
updateDataValue("version", "${cmd.applicationVersion}.${cmd.applicationSubVersion}")
log.debug "applicationVersion: ${cmd.applicationVersion}"
log.debug "applicationSubVersion: ${cmd.applicationSubVersion}"
@@ -245,7 +245,7 @@ def configure() {
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
cmds += zwave.manufacturerSpecificV2.manufacturerSpecificGet()
cmds += zwave.manufacturerSpecificV2.deviceSpecificGet()
@@ -255,7 +255,7 @@ def configure() {
cmds += zwave.sensorMultilevelV5.sensorMultilevelGet(sensorType: 1, scale: 0)
cmds += zwave.sensorMultilevelV5.sensorMultilevelGet(sensorType: 3, scale: 1)
cmds += zwave.wakeUpV2.wakeUpNoMoreInformation()
encapSequence(cmds, 500)
}

View File

@@ -100,6 +100,11 @@ metadata {
}
}
def installed(){
// Device-Watch simply pings if no device events received for 32min(checkInterval)
sendEvent(name: "checkInterval", value: 2 * 15 * 60 + 2 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID])
}
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])

View File

@@ -58,6 +58,11 @@ metadata {
}
}
def installed() {
// Device-Watch simply pings if no device events received for 32min(checkInterval)
sendEvent(name: "checkInterval", value: 2 * 15 * 60 + 2 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID])
}
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])

View File

@@ -1,5 +1,5 @@
/**
* Copyright 2016 SmartThings
* Copyright 2017 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:
@@ -59,7 +59,7 @@ def updated() {
}
def configure() {
def cmds = zigbee.batteryConfig(20, 20, 0x01)
def cmds = zigbee.readAttribute(zigbee.POWER_CONFIGURATION_CLUSTER, 0x0020) + zigbee.batteryConfig(20, 20, 0x01)
log.debug "configure -- cmds: ${cmds}"
return cmds
}
@@ -166,4 +166,4 @@ def checkPresenceCallback() {
if (timeSinceLastCheckin >= theCheckInterval) {
handlePresenceEvent(false)
}
}
}

View File

@@ -15,7 +15,7 @@
*/
metadata {
definition (name: "Cree Bulb", namespace: "smartthings", author: "SmartThings") {
definition (name: "Cree Bulb", namespace: "smartthings", author: "SmartThings", ocfDeviceType: "oic.d.light") {
capability "Actuator"
capability "Configuration"

View File

@@ -23,9 +23,9 @@ metadata {
capability "Health Check"
capability "Light"
fingerprint mfr:"0063", prod:"4457", deviceJoinName: "GE In-Wall Smart Dimmer "
fingerprint mfr:"0063", prod:"4944", deviceJoinName: "GE In-Wall Smart Dimmer "
fingerprint mfr:"0063", prod:"5044", deviceJoinName: "GE Plug-In Smart Dimmer "
fingerprint mfr:"0063", prod:"4457", deviceJoinName: "GE In-Wall Smart Dimmer"
fingerprint mfr:"0063", prod:"4944", deviceJoinName: "GE In-Wall Smart Dimmer"
fingerprint mfr:"0063", prod:"5044", deviceJoinName: "GE Plug-In Smart Dimmer"
fingerprint mfr:"0063", prod:"4944", model:"3034", deviceJoinName: "GE In-Wall Smart Fan Control"
}
@@ -84,6 +84,11 @@ metadata {
}
}
def installed() {
// Device-Watch simply pings if no device events received for 32min(checkInterval)
sendEvent(name: "checkInterval", value: 2 * 15 * 60 + 2 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID])
}
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])

View File

@@ -85,6 +85,11 @@ def parse(String description) {
result
}
def installed() {
// Device-Watch simply pings if no device events received for 32min(checkInterval)
sendEvent(name: "checkInterval", value: 2 * 15 * 60 + 2 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID])
}
//send the command to stop polling
def updated() {
// Device-Watch simply pings if no device events received for 32min(checkInterval)

View File

@@ -12,7 +12,7 @@
*
*/
metadata {
definition (name: "Everspring Flood Sensor", namespace: "smartthings", author: "SmartThings") {
definition (name: "Everspring Flood Sensor", namespace: "smartthings", author: "SmartThings", ocfDeviceType: "x.com.st.d.sensor.moisture") {
capability "Water Sensor"
capability "Configuration"
capability "Sensor"
@@ -29,7 +29,7 @@ metadata {
status "battery ${i}%": new physicalgraph.zwave.Zwave().batteryV1.batteryReport(batteryLevel: i).incomingMessage()
}
}
tiles(scale: 2) {
multiAttributeTile(name:"water", type: "generic", width: 6, height: 4){
tileAttribute ("device.water", key: "PRIMARY_CONTROL") {

View File

@@ -29,7 +29,7 @@
* 2. 20150125 Todd Wackford
* Leaned out parse and moved most device info getting into configuration method.
*/
/**
* Sets up metadata, simulator info and tile definition.
*
@@ -38,7 +38,7 @@
* @return none
*/
metadata {
definition (name: "Fibaro Motion Sensor", namespace: "smartthings", author: "SmartThings") {
definition (name: "Fibaro Motion Sensor", namespace: "smartthings", author: "SmartThings", ocfDeviceType: "x.com.st.d.sensor.motion") {
capability "Motion Sensor"
capability "Temperature Measurement"
capability "Acceleration Sensor"
@@ -47,7 +47,7 @@
capability "Sensor"
capability "Battery"
capability "Health Check"
command "resetParams2StDefaults"
command "listCurrentParams"
command "updateZwaveParam"
@@ -110,7 +110,7 @@
state("active", label:'vibration', icon:"st.motion.acceleration.active", backgroundColor:"#53a7c0")
state("inactive", label:'still', icon:"st.motion.acceleration.inactive", backgroundColor:"#ffffff")
}
main(["motion", "temperature", "acceleration", "illuminance"])
details(["motion", "temperature", "acceleration", "battery", "illuminance", "configure"])
@@ -130,18 +130,18 @@ def configure() {
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
cmds << zwave.associationV2.associationSet(groupingIdentifier:3, nodeId:[zwaveHubNodeId]).format()
// turn on tamper sensor with active/inactive reports (use it as an acceleration sensor) default is 0, or off
cmds << zwave.configurationV1.configurationSet(configurationValue: [4], parameterNumber: 24, size: 1).format()
cmds << zwave.configurationV1.configurationGet(parameterNumber: 24).format()
// temperature change report threshold (0-255 = 0.1 to 25.5C) default is 1.0 Celcius, setting to .5 Celcius
cmds << zwave.configurationV1.configurationSet(configurationValue: [5], parameterNumber: 60, size: 1).format()
cmds << zwave.configurationV1.configurationGet(parameterNumber: 60).format()
cmds << zwave.configurationV1.configurationGet(parameterNumber: 60).format()
cmds << response(zwave.batteryV1.batteryGet())
cmds << response(zwave.versionV1.versionGet().format())
cmds << response(zwave.manufacturerSpecificV2.manufacturerSpecificGet().format())
@@ -155,20 +155,20 @@ def parse(String description)
{
def result = []
def cmd = zwave.parse(description, [0x72: 2, 0x31: 2, 0x30: 1, 0x84: 1, 0x9C: 1, 0x70: 2, 0x80: 1, 0x86: 1, 0x7A: 1, 0x56: 1])
if (description == "updated") {
result << response(zwave.wakeUpV1.wakeUpIntervalSet(seconds: 7200, nodeid:zwaveHubNodeId))
result << response(zwave.manufacturerSpecificV2.manufacturerSpecificGet())
result << response(zwave.manufacturerSpecificV2.manufacturerSpecificGet())
}
if (cmd) {
if( cmd.CMD == "8407" ) {
if( cmd.CMD == "8407" ) {
result << response(zwave.batteryV1.batteryGet().format())
result << new physicalgraph.device.HubAction(zwave.wakeUpV1.wakeUpNoMoreInformation().format())
result << new physicalgraph.device.HubAction(zwave.wakeUpV1.wakeUpNoMoreInformation().format())
}
result << createEvent(zwaveEvent(cmd))
}
if ( result[0] != null ) {
log.debug "Parse returned ${result}"
result
@@ -189,14 +189,14 @@ def zwaveEvent(physicalgraph.zwave.commands.crc16encapv1.Crc16Encap cmd)
}
}
def createEvent(physicalgraph.zwave.commands.manufacturerspecificv2.ManufacturerSpecificReport cmd, Map item1) {
def createEvent(physicalgraph.zwave.commands.manufacturerspecificv2.ManufacturerSpecificReport cmd, Map item1) {
log.debug "manufacturerId: ${cmd.manufacturerId}"
log.debug "manufacturerName: ${cmd.manufacturerName}"
log.debug "productId: ${cmd.productId}"
log.debug "productTypeId: ${cmd.productTypeId}"
}
def createEvent(physicalgraph.zwave.commands.versionv1.VersionReport cmd, Map item1) {
def createEvent(physicalgraph.zwave.commands.versionv1.VersionReport cmd, Map item1) {
updateDataValue("applicationVersion", "${cmd.applicationVersion}")
log.debug "applicationVersion: ${cmd.applicationVersion}"
log.debug "applicationSubVersion: ${cmd.applicationSubVersion}"
@@ -205,7 +205,7 @@ def createEvent(physicalgraph.zwave.commands.versionv1.VersionReport cmd, Map it
log.debug "zWaveProtocolSubVersion: ${cmd.zWaveProtocolSubVersion}"
}
def createEvent(physicalgraph.zwave.commands.firmwareupdatemdv1.FirmwareMdReport cmd, Map item1) {
def createEvent(physicalgraph.zwave.commands.firmwareupdatemdv1.FirmwareMdReport cmd, Map item1) {
log.debug "checksum: ${cmd.checksum}"
log.debug "firmwareId: ${cmd.firmwareId}"
log.debug "manufacturerId: ${cmd.manufacturerId}"
@@ -304,7 +304,7 @@ def zwaveEvent(physicalgraph.zwave.commands.manufacturerspecificv2.ManufacturerS
def msr = String.format("%04X-%04X-%04X", cmd.manufacturerId, cmd.productTypeId, cmd.productId)
log.debug "msr: $msr"
updateDataValue("MSR", msr)
if ( msr == "010F-0800-2001" ) { //this is the msr and device type for the fibaro motion sensor
configure()
}
@@ -334,7 +334,7 @@ def test() {
* @return none
*/
def updateZwaveParam(params) {
if ( params ) {
if ( params ) {
def pNumber = params.paramNumber
def pSize = params.size
def pValue = [params.value]
@@ -344,7 +344,7 @@ def updateZwaveParam(params) {
def cmds = []
cmds << zwave.configurationV1.configurationSet(configurationValue: pValue, parameterNumber: pNumber, size: pSize).format()
cmds << zwave.configurationV1.configurationGet(parameterNumber: pNumber).format()
delayBetween(cmds, 1000)
delayBetween(cmds, 1000)
}
}
@@ -388,13 +388,13 @@ def resetParams2StDefaults() {
cmds << zwave.configurationV1.configurationSet(configurationValue: [18], parameterNumber: 86, size: 1).format()
cmds << zwave.configurationV1.configurationSet(configurationValue: [28], parameterNumber: 87, size: 1).format()
cmds << zwave.configurationV1.configurationSet(configurationValue: [1], parameterNumber: 89, size: 1).format()
delayBetween(cmds, 500)
}
/**
* Lists all of available Fibaro parameters and thier current settings out to the
* logging window in the IDE This will be called from the "Fibaro Tweaker" or
* Lists all of available Fibaro parameters and thier current settings out to the
* logging window in the IDE This will be called from the "Fibaro Tweaker" or
* user's own app.
*
* <p>THIS IS AN ADVANCED OPERATION. USE AT YOUR OWN RISK! READ OEM DOCUMENTATION!
@@ -433,7 +433,6 @@ def listCurrentParams() {
cmds << zwave.configurationV1.configurationGet(parameterNumber: 86).format()
cmds << zwave.configurationV1.configurationGet(parameterNumber: 87).format()
cmds << zwave.configurationV1.configurationGet(parameterNumber: 89).format()
delayBetween(cmds, 500)
}

View File

@@ -50,6 +50,11 @@ metadata {
}
}
def installed(){
// Device-Watch simply pings if no device events received for 32min(checkInterval)
sendEvent(name: "checkInterval", value: 2 * 15 * 60 + 2 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID])
}
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])

View File

@@ -42,7 +42,7 @@
*/
metadata {
definition (name: "GE Link Bulb", namespace: "smartthings", author: "SmartThings") {
definition (name: "GE Link Bulb", namespace: "smartthings", author: "SmartThings", ocfDeviceType: "oic.d.light") {
capability "Actuator"
capability "Configuration"

View File

@@ -57,10 +57,20 @@ metadata {
}
}
void installed() {
def initialize() {
sendEvent(name: "DeviceWatch-Enroll", value: "{\"protocol\": \"LAN\", \"scheme\":\"untracked\", \"hubHardwareId\": \"${device.hub.hardwareID}\"}", displayed: false)
}
void installed() {
log.debug "installed()"
initialize()
}
def updated() {
log.debug "updated()"
initialize()
}
// parse events into attributes
def parse(description) {
log.debug "parse() - $description"

View File

@@ -45,10 +45,20 @@ metadata {
}
}
void installed() {
def initialize() {
sendEvent(name: "DeviceWatch-Enroll", value: "{\"protocol\": \"LAN\", \"scheme\":\"untracked\", \"hubHardwareId\": \"${device.hub.hardwareID}\"}", displayed: false)
}
void installed() {
log.debug "installed()"
initialize()
}
def updated() {
log.debug "updated()"
initialize()
}
// parse events into attributes
def parse(description) {
log.debug "Parsing '${description}'"

View File

@@ -66,10 +66,20 @@ metadata {
}
}
void installed() {
def initialize() {
sendEvent(name: "DeviceWatch-Enroll", value: "{\"protocol\": \"LAN\", \"scheme\":\"untracked\", \"hubHardwareId\": \"${device.hub.hardwareID}\"}", displayed: false)
}
void installed() {
log.debug "installed()"
initialize()
}
def updated() {
log.debug "updated()"
initialize()
}
// parse events into attributes
def parse(description) {
log.debug "parse() - $description"

View File

@@ -50,10 +50,19 @@ metadata {
}
}
void installed() {
def initialize() {
sendEvent(name: "DeviceWatch-Enroll", value: "{\"protocol\": \"LAN\", \"scheme\":\"untracked\", \"hubHardwareId\": \"${device.hub.hardwareID}\"}", displayed: false)
}
void installed() {
log.debug "installed()"
initialize()
}
def updated() {
initialize()
}
// parse events into attributes
def parse(description) {
log.debug "parse() - $description"

View File

@@ -55,10 +55,20 @@ metadata {
}
}
void installed() {
def initialize() {
sendEvent(name: "DeviceWatch-Enroll", value: "{\"protocol\": \"LAN\", \"scheme\":\"untracked\", \"hubHardwareId\": \"${device.hub.hardwareID}\"}", displayed: false)
}
void installed() {
log.debug "installed()"
initialize()
}
def updated() {
log.debug "updated()"
initialize()
}
// parse events into attributes
def parse(description) {
log.debug "parse() - $description"

View File

@@ -5,7 +5,7 @@
*
*/
metadata {
definition (name: "LIFX Color Bulb", namespace: "smartthings", author: "LIFX") {
definition (name: "LIFX Color Bulb", namespace: "smartthings", author: "LIFX", ocfDeviceType: "oic.d.light") {
capability "Actuator"
capability "Color Control"
capability "Color Temperature"
@@ -64,8 +64,18 @@ metadata {
}
}
def initialize() {
sendEvent(name: "DeviceWatch-Enroll", value: "{\"protocol\": \"cloud\", \"scheme\":\"untracked\", \"hubHardwareId\": \"${device?.hub?.hardwareID}\"}", displayed: false)
}
void installed() {
sendEvent(name: "DeviceWatch-Enroll", value: "{\"protocol\": \"cloud\", \"scheme\":\"untracked\", \"hubHardwareId\": \"${device?.hub?.hardwareID}\"}")
log.debug "installed()"
initialize()
}
def updated() {
log.debug "updated()"
initialize()
}
// handle commands
@@ -190,7 +200,7 @@ def off() {
def refresh() {
log.debug "Executing 'refresh'"
def resp = parent.apiGET("/lights/${selector()}")
if (resp.status == 404) {
state.online = false

View File

@@ -5,7 +5,7 @@
*
*/
metadata {
definition (name: "LIFX White Bulb", namespace: "smartthings", author: "LIFX") {
definition (name: "LIFX White Bulb", namespace: "smartthings", author: "LIFX", ocfDeviceType: "oic.d.light") {
capability "Actuator"
capability "Color Temperature"
capability "Switch"
@@ -55,8 +55,18 @@ metadata {
}
}
def initialize() {
sendEvent(name: "DeviceWatch-Enroll", value: "{\"protocol\": \"cloud\", \"scheme\":\"untracked\", \"hubHardwareId\": \"${device?.hub?.hardwareID}\"}", displayed: false)
}
void installed() {
sendEvent(name: "DeviceWatch-Enroll", value: "{\"protocol\": \"cloud\", \"scheme\":\"untracked\", \"hubHardwareId\": \"${device?.hub?.hardwareID}\"}")
log.debug "installed()"
initialize()
}
def updated() {
log.debug "updated()"
initialize()
}
// handle commands
@@ -119,7 +129,7 @@ def off() {
def refresh() {
log.debug "Executing 'refresh'"
def resp = parent.apiGET("/lights/${selector()}")
if (resp.status == 404) {
state.online = false

View File

@@ -1,3 +1,4 @@
import groovy.json.JsonOutput
/**
* Logitech Harmony Hub
*
@@ -39,14 +40,18 @@ metadata {
}
}
def initialize() {
sendEvent(name: "DeviceWatch-Enroll", value: JsonOutput.toJson([protocol: "cloud", scheme:"untracked"]), displayed: false)
}
def installed() {
log.debug "installed()"
sendEvent(name: "DeviceWatch-Enroll", value: JsonOutput.toJson([protocol: "cloud", scheme:"untracked"]), displayed: false)
initialize()
}
def updated() {
log.debug "updated()"
sendEvent(name: "DeviceWatch-Enroll", value: JsonOutput.toJson([protocol: "cloud", scheme:"untracked"]), displayed: false)
initialize()
}
def startActivity(String activityId) {

View File

@@ -12,7 +12,7 @@
*
*/
metadata {
definition (name: "Open/Closed Sensor", namespace: "smartthings", author: "SmartThings") {
definition (name: "Open/Closed Sensor", namespace: "smartthings", author: "SmartThings", ocfDeviceType: "x.com.st.d.sensor.contact") {
capability "Contact Sensor"
capability "Sensor"
@@ -44,7 +44,7 @@ def parse(String description) {
if (description.startsWith("zone")) {
resMap = createEvent(name: "contact", value: zigbee.parseZoneStatus(description).isAlarm1Set() ? "open" : "closed")
}
log.debug "Parse returned $resMap"
return resMap
}

View File

@@ -17,7 +17,7 @@
*/
metadata {
definition (name: "RGBW Light", namespace: "smartthings", author: "SmartThings") {
definition (name: "RGBW Light", namespace: "smartthings", author: "SmartThings", ocfDeviceType: "oic.d.light") {
capability "Switch Level"
capability "Color Control"
capability "Color Temperature"

View File

@@ -91,6 +91,11 @@ def parse(String description) {
return result
}
def installed() {
// Device-Watch simply pings if no device events received for 482min(checkInterval)
sendEvent(name: "checkInterval", value: 2 * 4 * 60 * 60 + 2 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID])
}
def updated() {
// Device-Watch simply pings if no device events received for 482min(checkInterval)
sendEvent(name: "checkInterval", value: 2 * 4 * 60 * 60 + 2 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID])

View File

@@ -15,7 +15,7 @@
//DEPRECATED - Using the generic DTH for this device. Users need to be moved before deleting this DTH
metadata {
definition (name: "Sylvania Ultra iQ", namespace:"smartthings", author: "SmartThings") {
definition (name: "Sylvania Ultra iQ", namespace:"smartthings", author: "SmartThings", ocfDeviceType: "oic.d.light") {
capability "Switch Level"
capability "Configuration"
capability "Switch"

View File

@@ -18,8 +18,8 @@
//DEPRECATED - Using the generic DTH for this device. Users need to be moved before deleting this DTH
metadata {
definition (name: "WeMo Bulb", namespace: "smartthings", author: "SmartThings") {
definition (name: "WeMo Bulb", namespace: "smartthings", author: "SmartThings", ocfDeviceType: "oic.d.light") {
capability "Actuator"
capability "Configuration"
capability "Refresh"
@@ -57,7 +57,7 @@ metadata {
valueTile("level", "device.level", inactiveLabel: false, decoration: "flat") {
state "level", label: 'Level ${currentValue}%'
}
main(["switch"])
details(["switch", "level", "levelSliderControl", "refresh"])
@@ -87,11 +87,11 @@ def parse(String description) {
if (description?.startsWith("read attr")) {
log.debug description[-2..-1]
def i = Math.round(convertHexToInt(description[-2..-1]) / 256 * 100 )
sendEvent( name: "level", value: i )
}
}
def on() {
@@ -136,16 +136,16 @@ def setLevel(value) {
def configure() {
log.debug "Configuring Reporting and Bindings."
def configCmds = [
def configCmds = [
//Switch Reporting
"zcl global send-me-a-report 6 0 0x10 0 3600 {01}", "delay 500",
"send 0x${device.deviceNetworkId} 1 1", "delay 1000",
//Level Control Reporting
"zcl global send-me-a-report 8 0 0x20 5 3600 {0010}", "delay 200",
"send 0x${device.deviceNetworkId} 1 1", "delay 1500",
"zdo bind 0x${device.deviceNetworkId} 1 1 6 {${device.zigbeeId}} {}", "delay 1000",
"zdo bind 0x${device.deviceNetworkId} 1 1 8 {${device.zigbeeId}} {}", "delay 500",
]

View File

@@ -13,7 +13,7 @@
*/
metadata {
definition (name: "ZigBee Dimmer Power", namespace: "smartthings", author: "SmartThings", ocfDeviceType: "oic.d.switch") {
definition (name: "ZigBee Dimmer Power", namespace: "smartthings", author: "SmartThings", ocfDeviceType: "oic.d.light") {
capability "Actuator"
capability "Configuration"
capability "Refresh"
@@ -114,9 +114,17 @@ def refresh() {
def configure() {
log.debug "Configuring Reporting and Bindings."
def cmds = []
if (device.getDataValue("manufacturer") == "sengled") {
def startLevel = 0xFE
if ((device.currentState("level")?.value != null)) {
startLevel = Math.round(Integer.parseInt(device.currentState("level").value) * 0xFE / 100)
}
// Level Control Cluster, command Move to Level, level start level, transition time 0
cmds << zigbee.command(zigbee.LEVEL_CONTROL_CLUSTER, 0x00, sprintf("%02X0000", startLevel))
}
// Device-Watch allows 2 check-in misses from device + ping (plus 1 min lag time)
// enrolls with default periodic reporting until newer 5 min interval is confirmed
sendEvent(name: "checkInterval", value: 2 * 60 * 60 + 1 * 60, displayed: false, data: [protocol: "zigbee", hubHardwareId: device.hub.hardwareID])
refresh()
cmds + refresh()
}

View File

@@ -13,7 +13,7 @@
*/
metadata {
definition (name: "ZigBee Dimmer", namespace: "smartthings", author: "SmartThings", ocfDeviceType: "oic.d.switch") {
definition (name: "ZigBee Dimmer", namespace: "smartthings", author: "SmartThings", ocfDeviceType: "oic.d.light") {
capability "Actuator"
capability "Configuration"
capability "Refresh"

View File

@@ -16,7 +16,7 @@ import groovy.transform.Field
@Field Boolean hasConfiguredHealthCheck = false
metadata {
definition (name: "ZLL Dimmer Bulb", namespace: "smartthings", author: "SmartThings") {
definition (name: "ZLL Dimmer Bulb", namespace: "smartthings", author: "SmartThings", ocfDeviceType: "oic.d.light") {
capability "Actuator"
capability "Configuration"

View File

@@ -14,7 +14,7 @@
import physicalgraph.zigbee.zcl.DataType
metadata {
definition (name: "ZLL RGB Bulb", namespace: "smartthings", author: "SmartThings") {
definition (name: "ZLL RGB Bulb", namespace: "smartthings", author: "SmartThings", ocfDeviceType: "oic.d.light") {
capability "Actuator"
capability "Color Control"

View File

@@ -14,7 +14,7 @@
import physicalgraph.zigbee.zcl.DataType
metadata {
definition (name: "ZLL RGBW Bulb", namespace: "smartthings", author: "SmartThings") {
definition (name: "ZLL RGBW Bulb", namespace: "smartthings", author: "SmartThings", ocfDeviceType: "oic.d.light") {
capability "Actuator"
capability "Color Control"

View File

@@ -16,7 +16,7 @@ import groovy.transform.Field
@Field Boolean hasConfiguredHealthCheck = false
metadata {
definition (name: "ZLL White Color Temperature Bulb 5000K", namespace: "smartthings", author: "SmartThings") {
definition (name: "ZLL White Color Temperature Bulb 5000K", namespace: "smartthings", author: "SmartThings", ocfDeviceType: "oic.d.light") {
capability "Actuator"
capability "Color Temperature"
@@ -101,7 +101,7 @@ def refresh() {
if (!((device.getDataValue("manufacturer") == "Eaton") && (device.getDataValue("model") == "Halo_LT01"))) {
cmds = cmds + zigbee.onOffConfig() + zigbee.levelConfig() + zigbee.colorTemperatureConfig()
}
cmds
}

View File

@@ -16,7 +16,7 @@ import groovy.transform.Field
@Field Boolean hasConfiguredHealthCheck = false
metadata {
definition (name: "ZLL White Color Temperature Bulb", namespace: "smartthings", author: "SmartThings") {
definition (name: "ZLL White Color Temperature Bulb", namespace: "smartthings", author: "SmartThings", ocfDeviceType: "oic.d.light") {
capability "Actuator"
capability "Color Temperature"

View File

@@ -12,7 +12,7 @@
*
*/
metadata {
definition (name: "Z-Wave Dimmer Switch Generic", namespace: "smartthings", author: "SmartThings", ocfDeviceType: "oic.d.switch") {
definition (name: "Z-Wave Dimmer Switch Generic", namespace: "smartthings", author: "SmartThings", ocfDeviceType: "oic.d.light") {
capability "Switch Level"
capability "Actuator"
capability "Health Check"
@@ -78,6 +78,11 @@ metadata {
}
}
def installed(){
// Device-Watch simply pings if no device events received for 32min(checkInterval)
sendEvent(name: "checkInterval", value: 2 * 15 * 60 + 2 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID])
}
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])

View File

@@ -17,7 +17,7 @@
*/
metadata {
definition (name: "Z-Wave Door/Window Sensor", namespace: "smartthings", author: "SmartThings") {
definition (name: "Z-Wave Door/Window Sensor", namespace: "smartthings", author: "SmartThings", ocfDeviceType: "x.com.st.d.sensor.contact") {
capability "Contact Sensor"
capability "Sensor"
capability "Battery"
@@ -30,6 +30,9 @@ metadata {
fingerprint deviceId: "0x0701", inClusters: "0x5E,0x86,0x72,0x98", outClusters: "0x5A,0x82"
fingerprint deviceId: "0x0701", inClusters: "0x5E,0x80,0x71,0x85,0x70,0x72,0x86,0x30,0x31,0x84,0x59,0x73,0x5A,0x8F,0x98,0x7A", outClusters:"0x20" // Philio multi+
fingerprint mfr:"0086", prod:"0002", model:"001D", deviceJoinName: "Aeon Labs Door/Window Sensor (Gen 5)"
fingerprint mfr:"014A", prod:"0001", model:"0002", deviceJoinName: "Ecolink Door/Window Sensor"
fingerprint mfr:"0086", prod:"0102", model:"0070", deviceJoinName: "Aeon Labs Door/Window Sensor 6"
fingerprint mfr:"011A", prod:"0601", model:"0903", deviceJoinName: "Enerwave Magnetic Door/Window Sensor"
}
// simulator metadata
@@ -79,6 +82,11 @@ def parse(String description) {
return result
}
def installed() {
// Device-Watch simply pings if no device events received for 482min(checkInterval)
sendEvent(name: "checkInterval", value: 2 * 4 * 60 * 60 + 2 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID])
}
def updated() {
// Device-Watch simply pings if no device events received for 482min(checkInterval)
sendEvent(name: "checkInterval", value: 2 * 4 * 60 * 60 + 2 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID])

View File

@@ -65,6 +65,11 @@ metadata {
import physicalgraph.zwave.commands.barrieroperatorv1.*
def installed(){
// Device-Watch simply pings if no device events received for 32min(checkInterval)
sendEvent(name: "checkInterval", value: 2 * 15 * 60 + 2 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID])
}
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])

View File

@@ -68,6 +68,11 @@ metadata {
import physicalgraph.zwave.commands.doorlockv1.*
import physicalgraph.zwave.commands.usercodev1.*
def installed() {
// Device-Watch simply pings if no device events received for 32min(checkInterval)
sendEvent(name: "checkInterval", value: 2 * 15 * 60 + 2 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID])
}
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])

View File

@@ -100,6 +100,11 @@ def parse(String description) {
result
}
def installed() {
// Device-Watch simply pings if no device events received for 32min(checkInterval)
sendEvent(name: "checkInterval", value: 2 * 15 * 60 + 2 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID])
}
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])

View File

@@ -74,6 +74,11 @@ metadata {
}
}
def installed() {
// Device-Watch simply pings if no device events received for 32min(checkInterval)
sendEvent(name: "checkInterval", value: 2 * 15 * 60 + 2 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID])
}
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])

View File

@@ -17,7 +17,7 @@
*/
metadata {
definition (name: "Z-Wave Motion Sensor", namespace: "smartthings", author: "SmartThings") {
definition (name: "Z-Wave Motion Sensor", namespace: "smartthings", author: "SmartThings", ocfDeviceType: "x.com.st.d.sensor.motion") {
capability "Motion Sensor"
capability "Sensor"
capability "Battery"
@@ -36,7 +36,7 @@ metadata {
status "inactive": "command: 3003, payload: 00"
status "active": "command: 3003, payload: FF"
}
tiles {
standardTile("motion", "device.motion", width: 2, height: 2) {
state("active", label:'motion', icon:"st.motion.motion.active", backgroundColor:"#00A0DC")
@@ -51,7 +51,12 @@ metadata {
}
}
def updated(){
def installed() {
// 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])
}
def updated() {
// 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])
}
@@ -197,4 +202,4 @@ def zwaveEvent(physicalgraph.zwave.commands.manufacturerspecificv2.ManufacturerS
result << createEvent(descriptionText: "$device.displayName MSR: $msr", isStateChange: false)
result
}
}

View File

@@ -16,7 +16,7 @@
*/
metadata {
definition (name: "Z-Wave Plus Door/Window Sensor", namespace: "smartthings", author: "SmartThings") {
definition (name: "Z-Wave Plus Door/Window Sensor", namespace: "smartthings", author: "SmartThings", ocfDeviceType: "x.com.st.d.sensor.contact") {
capability "Contact Sensor"
capability "Configuration"
capability "Battery"

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

@@ -53,7 +53,12 @@ metadata {
}
}
def updated(){
def installed() {
// 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 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])
}

View File

@@ -61,6 +61,11 @@ metadata {
}
}
def installed(){
// Device-Watch simply pings if no device events received for checkInterval duration of 32min = 2 * 15min + 2min lag time
sendEvent(name: "checkInterval", value: 2 * 15 * 60 + 2 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID])
}
def updated(){
// Device-Watch simply pings if no device events received for checkInterval duration of 32min = 2 * 15min + 2min lag time
sendEvent(name: "checkInterval", value: 2 * 15 * 60 + 2 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID])

View File

@@ -22,9 +22,9 @@ metadata {
capability "Health Check"
capability "Light"
fingerprint mfr:"0063", prod:"4952", deviceJoinName: "Z-Wave Wall Switch"
fingerprint mfr:"0063", prod:"5257", deviceJoinName: "Z-Wave Wall Switch"
fingerprint mfr:"0063", prod:"5052", deviceJoinName: "Z-Wave Plug-In Switch"
fingerprint mfr:"0063", prod:"4952", deviceJoinName: "GE Wall Switch"
fingerprint mfr:"0063", prod:"5257", deviceJoinName: "GE Wall Switch"
fingerprint mfr:"0063", prod:"5052", deviceJoinName: "GE Plug-In Switch"
fingerprint mfr:"0113", prod:"5257", deviceJoinName: "Z-Wave Wall Switch"
}
@@ -65,6 +65,11 @@ metadata {
}
}
def installed() {
// Device-Watch simply pings if no device events received for 32min(checkInterval)
sendEvent(name: "checkInterval", value: 2 * 15 * 60 + 2 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID])
}
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])

View File

@@ -124,6 +124,11 @@ metadata {
}
}
def installed(){
// Device-Watch simply pings if no device events received for 32min(checkInterval)
sendEvent(name: "checkInterval", value: 2 * 15 * 60 + 2 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID])
}
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])

View File

@@ -16,7 +16,7 @@
* Date: 2013-03-07
*/
metadata {
definition (name: "Z-Wave Virtual Momentary Contact Switch", namespace: "smartthings", author: "SmartThings") {
definition (name: "Z-Wave Virtual Momentary Contact Switch", namespace: "smartthings", author: "SmartThings", ocfDeviceType: "x.com.st.d.sensor.contact") {
capability "Actuator"
capability "Switch"
capability "Refresh"

View File

@@ -17,7 +17,7 @@
*/
metadata {
definition (name: "Z-Wave Water Sensor", namespace: "smartthings", author: "SmartThings") {
definition (name: "Z-Wave Water Sensor", namespace: "smartthings", author: "SmartThings", ocfDeviceType: "x.com.st.d.sensor.moisture") {
capability "Water Sensor"
capability "Sensor"
capability "Battery"
@@ -29,7 +29,7 @@ metadata {
status "dry": "command: 3003, payload: 00"
status "wet": "command: 3003, payload: FF"
}
tiles {
standardTile("water", "device.water", width: 2, height: 2) {
state "dry", icon:"st.alarm.water.dry", backgroundColor:"#ffffff"

View File

@@ -52,15 +52,15 @@ definition(
//Device Inputs
preferences {
section("Allow OpenT2T to control these things...") {
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 "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
input "thermostats", "capability.thermostat", title: "Which Thermostat?", multiple: true, required: false
input "waterSensors", "capability.waterSensor", title: "Which Water Leak Sensors?", multiple: true, required: false
input "contactSensors", "capability.contactSensor", title: "Which Contact Sensors", multiple: true, required: false, hideWhenEmpty: true
input "garageDoors", "capability.garageDoorControl", title: "Which Garage Doors?", multiple: true, required: false, hideWhenEmpty: true
input "locks", "capability.lock", title: "Which Locks?", multiple: true, required: false, hideWhenEmpty: true
input "cameras", "capability.videoCapture", title: "Which Cameras?", multiple: true, required: false, hideWhenEmpty: true
input "motionSensors", "capability.motionSensor", title: "Which Motion Sensors?", multiple: true, required: false, hideWhenEmpty: true
input "presenceSensors", "capability.presenceSensor", title: "Which Presence Sensors", multiple: true, required: false, hideWhenEmpty: true
input "switches", "capability.switch", title: "Which Switches and Lights?", multiple: true, required: false, hideWhenEmpty: true
input "thermostats", "capability.thermostat", title: "Which Thermostat?", multiple: true, required: false, hideWhenEmpty: true
input "waterSensors", "capability.waterSensor", title: "Which Water Leak Sensors?", multiple: true, required: false, hideWhenEmpty: true
}
}
@@ -80,16 +80,6 @@ def getInputs() {
//API external Endpoints
mappings {
path("/subscriptionURL/:url") {
action: [
PUT: "updateEndpointURL"
]
}
path("/connectionId/:connId") {
action: [
PUT: "updateConnectionId"
]
}
path("/devices") {
action: [
GET: "getDevices"
@@ -105,33 +95,52 @@ mappings {
PUT: "updateDevice"
]
}
path("/subscription/:id") {
path("/deviceSubscription") {
action: [
POST: "registerDeviceChange",
DELETE: "unregisterDeviceChange"
]
}
path("/locationSubscription") {
action: [
POST: "registerDeviceGraph",
DELETE: "unregisterDeviceGraph"
]
}
}
def installed() {
log.debug "Installed with settings: ${settings}"
log.debug "Installing with settings: ${settings}"
initialize()
}
def updated() {
log.debug "Updated with settings: ${settings}"
log.debug "Updating with settings: ${settings}"
if(state.deviceSubscriptionMap == null){
state.deviceSubscriptionMap = [:]
log.debug "deviceSubscriptionMap created."
}
if( state.locationSubscriptionMap == null){
state.locationSubscriptionMap = [:]
log.debug "locationSubscriptionMap created."
}
unsubscribe()
registerSubscriptions()
registerAllDeviceSubscriptions()
}
def initialize() {
state.connectionId = ""
state.endpointURL = "https://ifs.windows-int.com/v1/cb/81C7E77B-EABC-488A-B2BF-FEC42F0DABD2/notify"
registerSubscriptions()
log.debug "Initializing with settings: ${settings}"
state.deviceSubscriptionMap = [:]
log.debug "deviceSubscriptionMap created."
registerAllDeviceSubscriptions()
state.locationSubscriptionMap = [:]
log.debug "locationSubscriptionMap created."
}
/*** Subscription Functions ***/
//Subscribe events for all devices
def registerSubscriptions() {
def registerAllDeviceSubscriptions() {
registerChangeHandler(inputs)
}
@@ -140,101 +149,195 @@ def registerChangeHandler(myList) {
myList.each { myDevice ->
def theAtts = myDevice.supportedAttributes
theAtts.each {att ->
subscribe(myDevice, att.name, eventHandler)
log.info "Registering ${myDevice.displayName}.${att.name}"
subscribe(myDevice, att.name, deviceEventHandler)
log.info "Registering for ${myDevice.displayName}.${att.name}"
}
}
}
//Endpoints function: Subscribe to events from a specific device
def registerDeviceChange() {
def myDevice = findDevice(params.id)
def subscriptionEndpt = params.subscriptionURL
def deviceId = params.deviceId
def myDevice = findDevice(deviceId)
if( myDevice == null ){
httpError(404, "Cannot find device with device ID ${deviceId}.")
}
def theAtts = myDevice.supportedAttributes
try {
theAtts.each {att ->
subscribe(myDevice, att.name, eventHandler)
log.info "Registering ${myDevice.displayName}.${att.name}"
subscribe(myDevice, att.name, deviceEventHandler)
}
log.info "Subscribing for ${myDevice.displayName}"
if(subscriptionEndpt != null){
if(state.deviceSubscriptionMap[deviceId] == null){
state.deviceSubscriptionMap.put(deviceId, [subscriptionEndpt])
log.info "Added subscription URL: ${subscriptionEndpt} for ${myDevice.displayName}"
} else if (!state.deviceSubscriptionMap[deviceId].contains(subscriptionEndpt)){
state.deviceSubscriptionMap[deviceId] << subscriptionEndpt
log.info "Added subscription URL: ${subscriptionEndpt} for ${myDevice.displayName}"
}
}
return ["succeed"]
} catch (e) {
httpError(500, "something went wrong: $e")
}
log.info "Current subscription map is ${state.deviceSubscriptionMap}"
return ["succeed"]
}
//Endpoints function: Unsubscribe to events from a specific device
def unregisterDeviceChange() {
def myDevice = findDevice(params.id)
def subscriptionEndpt = params.subscriptionURL
def deviceId = params.deviceId
def myDevice = findDevice(deviceId)
if( myDevice == null ){
httpError(404, "Cannot find device with device ID ${deviceId}.")
}
try {
unsubscribe(myDevice)
log.info "Unregistering ${myDevice.displayName}"
return ["succeed"]
if(subscriptionEndpt != null && subscriptionEndpt != "undefined"){
if (state.deviceSubscriptionMap[deviceId]?.contains(subscriptionEndpt)){
if(state.deviceSubscriptionMap[deviceId].size() == 1){
state.deviceSubscriptionMap.remove(deviceId)
} else {
state.deviceSubscriptionMap[deviceId].remove(subscriptionEndpt)
}
log.info "Removed subscription URL: ${subscriptionEndpt} for ${myDevice.displayName}"
}
} else {
state.deviceSubscriptionMap.remove(deviceId)
log.info "Unsubscriping for ${myDevice.displayName}"
}
} catch (e) {
httpError(500, "something went wrong: $e")
}
log.info "Current subscription map is ${state.deviceSubscriptionMap}"
}
//Endpoints function: Subscribe to device additiona/removal updated in a location
def registerDeviceGraph() {
def subscriptionEndpt = params.subscriptionURL
if (subscriptionEndpt != null && subscriptionEndpt != "undefined"){
subscribe(location, "DeviceCreated", locationEventHandler, [filterEvents: false])
subscribe(location, "DeviceUpdated", locationEventHandler, [filterEvents: false])
subscribe(location, "DeviceDeleted", locationEventHandler, [filterEvents: false])
if(state.locationSubscriptionMap[location.id] == null){
state.locationSubscriptionMap.put(location.id, [subscriptionEndpt])
log.info "Added subscription URL: ${subscriptionEndpt} for Location ${location.name}"
} else if (!state.locationSubscriptionMap[location.id].contains(subscriptionEndpt)){
state.locationSubscriptionMap[location.id] << subscriptionEndpt
log.info "Added subscription URL: ${subscriptionEndpt} for Location ${location.name}"
}
log.info "Current location subscription map is ${state.locationSubscriptionMap}"
return ["succeed"]
} else {
httpError(400, "missing input parameter: subscriptionURL")
}
}
//Endpoints function: Unsubscribe to events from a specific device
def unregisterDeviceGraph() {
def subscriptionEndpt = params.subscriptionURL
try {
if(subscriptionEndpt != null && subscriptionEndpt != "undefined"){
if (state.locationSubscriptionMap[location.id]?.contains(subscriptionEndpt)){
if(state.locationSubscriptionMap[location.id].size() == 1){
state.locationSubscriptionMap.remove(location.id)
} else {
state.locationSubscriptionMap[location.id].remove(subscriptionEndpt)
}
log.info "Removed subscription URL: ${subscriptionEndpt} for Location ${location.name}"
}
}else{
httpError(400, "missing input parameter: subscriptionURL")
}
} catch (e) {
httpError(500, "something went wrong: $e")
}
log.info "Current location subscription map is ${state.locationSubscriptionMap}"
}
//When events are triggered, send HTTP post to web socket servers
def eventHandler(evt) {
def evt_device_id = evt.deviceId
def evt_device_value = evt.value
def evt_name = evt.name
def deviceEventHandler(evt) {
def evt_device = evt.device
def evt_deviceType = getDeviceType(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 = [ body: [deviceName: evt_device.displayName, deviceId: evt_device.id, locationId: location.id] ]
if(evt.data != null){
def evtData = parseJson(evt.data)
log.info "Received event for ${evt_device.displayName}, data: ${evtData}, description: ${evt.descriptionText}"
}
def params = [
uri: "${state.endpointURL}/${state.connectionId}",
body: [ deviceInfo ]
]
try {
//send event to all subscriptions urls
log.debug "Current subscription urls for ${evt_device.displayName} is ${state.deviceSubscriptionMap[evt_device.id]}"
state.deviceSubscriptionMap[evt_device.id].each {
params.uri = "${it}"
log.trace "POST URI: ${params.uri}"
log.trace "Payload: ${params.body}"
httpPostJson(params) { resp ->
resp.headers.each {
log.debug "${it.name} : ${it.value}"
try{
httpPostJson(params) { resp ->
log.trace "response status code: ${resp.status}"
log.trace "response data: ${resp.data}"
}
log.trace "response status code: ${resp.status}"
log.trace "response data: ${resp.data}"
} catch (e) {
log.error "something went wrong: $e"
}
} catch (e) {
log.debug "something went wrong: $e"
}
}
//Endpoints function: update subcription endpoint url [state.endpoint]
void updateEndpointURL() {
state.endpointURL = params.url
log.info "Updated EndpointURL to ${state.endpointURL}"
def locationEventHandler(evt) {
log.info "Received event for location ${location.name}/${location.id}, Event: ${evt.name}, description: ${evt.descriptionText}, apiServerUrl: ${apiServerUrl("")}"
switch(evt.name){
case "DeviceCreated":
case "DeviceDeleted":
def evt_device = evt.device
def evt_deviceType = getDeviceType(evt_device)
log.info "DeviceName: ${evt_device.displayName}, DeviceID: ${evt_device.id}, deviceType: ${evt_deviceType}"
def params = [ body: [ eventType:evt.name, deviceId: evt_device.id, locationId: location.id ] ]
state.locationSubscriptionMap[location.id].each {
params.uri = "${it}"
log.trace "POST URI: ${params.uri}"
log.trace "Payload: ${params.body}"
try{
httpPostJson(params) { resp ->
log.trace "response status code: ${resp.status}"
log.trace "response data: ${resp.data}"
}
} catch (e) {
log.error "something went wrong: $e"
}
}
case "DeviceUpdated":
default:
break
}
}
//Endpoints function: update global variable [state.connectionId]
void updateConnectionId() {
def connId = params.connId
state.connectionId = connId
log.info "Updated ConnectionID to ${state.connectionId}"
}
/*** Device Query/Update Functions ***/
//Endpoints function: return all device data in json format
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, status:it.status, deviceType:deviceType, manufacturer:it.manufacturerName, model:it.modelName, attributes: deviceAttributeList(it, deviceType), locationMode: getLocationModeInfo()]
} else {
deviceData << [name: it.displayName, id: it.id, status:it.status, deviceType:deviceType, manufacturer:it.manufacturerName, model:it.modelName, attributes: deviceAttributeList(it, deviceType)]
}
}
@@ -247,14 +350,12 @@ 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, status:it.status, deviceType:deviceType, manufacturer:it.manufacturerName, model:it.modelName, attributes: deviceAttributeList(it,deviceType), locationMode: getLocationModeInfo()]
} else {
device = [name: it.displayName, id: it.id, status:it.status, deviceType:deviceType, manufacturer:it.manufacturerName, model:it.modelName, attributes: deviceAttributeList(it, deviceType)]
}
log.debug "getDevice, return: ${device}"
return device
}
@@ -350,9 +451,6 @@ private getDeviceType(device) {
}
}
break
case "contact sensor":
deviceType = "contactSensor"
return deviceType
case "garageDoorControl":
deviceType = "garageDoor"
return deviceType
@@ -362,17 +460,15 @@ private getDeviceType(device) {
case "video camera":
deviceType = "camera"
return deviceType
case "motion sensor":
deviceType = "motionSensor"
return deviceType
case "presence sensor":
deviceType = "presenceSensor"
return deviceType
case "thermostat":
deviceType = "thermostat"
return deviceType
case "acceleration sensor":
case "contact sensor":
case "motion sensor":
case "presence sensor":
case "water sensor":
deviceType = "waterSensor"
deviceType = "genericSensor"
return deviceType
default:
break
@@ -387,14 +483,33 @@ private findDevice(deviceId) {
}
//Return a list of device attributes
private deviceAttributeList(device) {
device.supportedAttributes.collectEntries { attribute->
private deviceAttributeList(device, deviceType) {
def attributeList = [:]
def allAttributes = device.supportedAttributes
allAttributes.each { attribute ->
try {
[ (attribute.name): device.currentValue(attribute.name) ]
def currentState = device.currentState(attribute.name)
if(currentState != null ){
switch(attribute.name){
case 'temperature':
attributeList.putAll([ (attribute.name): currentState.value, 'temperatureScale':location.temperatureScale ])
break;
default:
attributeList.putAll([(attribute.name): currentState.value ])
break;
}
if( deviceType == "genericSensor" ){
def key = attribute.name + "_lastUpdated"
attributeList.putAll([ (key): currentState.isoDate ])
}
} else {
attributeList.putAll([ (attribute.name): null ]);
}
} catch(e) {
[ (attribute.name): null ]
attributeList.putAll([ (attribute.name): null ]);
}
}
return attributeList
}
//Map device command and value.

View File

@@ -73,7 +73,7 @@ def bridgeDiscovery(params = [:]) {
}
ssdpSubscribe()
log.trace "bridgeRefreshCount: $bridgeRefreshCount"
//bridge discovery request every 15 //25 seconds
if ((bridgeRefreshCount % 5) == 0) {
discoverBridges()
@@ -207,6 +207,7 @@ def bulbDiscovery() {
}
private discoverBridges() {
log.trace "Sending Hue Discovery message to the hub"
sendHubCommand(new physicalgraph.device.HubAction("lan discovery urn:schemas-upnp-org:device:basic:1", physicalgraph.device.Protocol.LAN))
}