From 9045de3ee0f72992aa5b5c13ad5fe6805745ac33 Mon Sep 17 00:00:00 2001
From: Przemyslaw Kacprowicz
Date: Wed, 9 Oct 2019 14:08:00 +0200
Subject: [PATCH 1/5] Reverting all changes in Z-Wave Motion Light Sensor and
creating new DTH for Everspring Outdoor Floodlight.
---
.../everspring-outdoor-floodlight.groovy | 162 ++++++++++++++++++
.../zwave-motion-light-sensor.groovy | 31 ++--
2 files changed, 173 insertions(+), 20 deletions(-)
create mode 100644 devicetypes/smartthings/everspring-outdoor-floodlight.src/everspring-outdoor-floodlight.groovy
diff --git a/devicetypes/smartthings/everspring-outdoor-floodlight.src/everspring-outdoor-floodlight.groovy b/devicetypes/smartthings/everspring-outdoor-floodlight.src/everspring-outdoor-floodlight.groovy
new file mode 100644
index 00000000000..6e7d8271843
--- /dev/null
+++ b/devicetypes/smartthings/everspring-outdoor-floodlight.src/everspring-outdoor-floodlight.groovy
@@ -0,0 +1,162 @@
+/**
+ * Copyright 2018 SmartThings
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License
+ * for the specific language governing permissions and limitations under the License.
+ *
+ */
+
+metadata {
+ definition(name: "Everpsring Outdoor Floodlight", namespace: "smartthings", author: "SmartThings", ocfDeviceType: "oic.d.light", mmnm: "SmartThings", vid: "generic-motion-light-sensor") {
+ capability "Switch"
+ capability "Motion Sensor"
+ capability "Illuminance Measurement"
+ capability "Sensor"
+ capability "Health Check"
+ capability "Configuration"
+
+ fingerprint mfr: "0060", prod: "0012", model: "0001", deviceJoinName: "Everspring Outdoor Floodlight"
+ }
+
+ tiles(scale: 2) {
+ multiAttributeTile(name:"switch", type: "lighting", width: 1, height: 1, canChangeIcon: true) {
+ tileAttribute("device.switch", key: "PRIMARY_CONTROL") {
+ attributeState("on", label:'${name}', action:"switch.off", icon:"st.lights.philips.hue-single", backgroundColor:"#00a0dc", nextState:"turningOff")
+ attributeState("off", label:'${name}', action:"switch.on", icon:"st.lights.philips.hue-single", backgroundColor:"#ffffff", nextState:"turningOn")
+ attributeState("turningOn", label:'${name}', action:"switch.off", icon:"st.lights.philips.hue-single", backgroundColor:"#00a0dc", nextState:"turningOff")
+ attributeState("turningOff", label:'${name}', action:"switch.on", icon:"st.lights.philips.hue-single", backgroundColor:"#ffffff", nextState:"turningOn")
+ }
+ }
+ tileAttribute("motion", "device.motion", decoration: "flat", width: 2, height: 2) {
+ attributeState("active", label: 'motion', icon: "st.motion.motion.active", backgroundColor: "#00A0DC")
+ attributeState("inactive", label: 'no motion', icon: "st.motion.motion.inactive", backgroundColor: "#CCCCCC")
+ }
+ valueTile("illuminance", "device.illuminance", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
+ state "illuminance", label: '${currentValue} lux', backgroundColors: [
+ [value: 40, color: "#999900"],
+ [value: 100, color: "#CCCC00"],
+ [value: 300, color: "#FFFF00"],
+ [value: 500, color: "#FFFF33"],
+ [value: 1000, color: "#FFFF66"],
+ [value: 2000, color: "#FFFF99"],
+ [value: 10000, color: "#FFFFCC"]
+ ]
+ }
+
+ main "switch"
+ details(["switch", "motion", "illuminance"])
+ }
+}
+
+def initialize() {
+ sendEvent(name: "checkInterval", value: 2 * 4 * 60 * 60 + 24 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID])
+ sendEvent(name: "motion", value: "inactive", displayed: false)
+}
+
+def installed() {
+ initialize()
+}
+
+def updated() {
+ initialize()
+}
+
+def configure() {
+ [
+ secure(zwave.notificationV3.notificationGet(notificationType: 0x07)),
+ secure(zwave.sensorMultilevelV5.sensorMultilevelGet(sensorType: 0x03)),
+ secure(zwave.switchBinaryV1.switchBinaryGet()),
+ secure(zwave.configurationV1.configurationSet(parameterNumber: 3, size: 2, scaledConfigurationValue: 600)) //enables illuminance report every 10 minutes
+ ]
+}
+
+def parse(String description) {
+ def result = []
+ if (description.startsWith("Err")) {
+ result = createEvent(descriptionText:description, isStateChange:true)
+ } else {
+ def cmd = zwave.parse(description)
+ if (cmd) {
+ result += zwaveEvent(cmd)
+ }
+ }
+ log.debug "Parse returned: ${result}"
+ result
+}
+
+def on() {
+ [
+ secure(zwave.switchBinaryV1.switchBinarySet(switchValue: 0xFF)),
+ "delay 500",
+ secure(zwave.switchBinaryV1.switchBinaryGet())
+ ]
+}
+
+def off() {
+ [
+ secure(zwave.switchBinaryV1.switchBinarySet(switchValue: 0x00)),
+ "delay 500",
+ secure(zwave.switchBinaryV1.switchBinaryGet())
+ ]
+}
+
+def zwaveEvent(physicalgraph.zwave.commands.securityv1.SecurityMessageEncapsulation cmd) {
+ def encapsulatedCommand = cmd.encapsulatedCommand()
+ if (encapsulatedCommand) {
+ zwaveEvent(encapsulatedCommand)
+ } else {
+ log.warn "Unable to extract encapsulated cmd from $cmd"
+ createEvent(descriptionText: cmd.toString())
+ }
+}
+
+def zwaveEvent(physicalgraph.zwave.commands.switchbinaryv1.SwitchBinaryReport cmd) {
+ def map = [name: "switch"]
+ map.value = cmd.value ? "on" : "off"
+ map.descriptionText = "${device.displayName} light has been turned ${map.value}"
+ createEvent(map)
+}
+
+def zwaveEvent(physicalgraph.zwave.commands.notificationv3.NotificationReport cmd) {
+ if (cmd.notificationType == 0x07) {
+ if (cmd.event == 0x08) { // detected
+ createEvent(name: "motion", value: "active", descriptionText: "$device.displayName detected motion")
+ } else if (cmd.event == 0x00) { // inactive
+ createEvent(name: "motion", value: "inactive", descriptionText: "$device.displayName motion has stopped")
+ }
+ }
+}
+
+def zwaveEvent(physicalgraph.zwave.commands.sensormultilevelv5.SensorMultilevelReport cmd) {
+ def map = [:]
+ switch (cmd.sensorType) {
+ case 3:
+ map.name = "illuminance"
+ map.value = cmd.scaledSensorValue.toInteger().toString()
+ map.unit = "lux"
+ map.isStateChange = true
+ break
+ default:
+ map.descriptionText = cmd.toString()
+ }
+ createEvent(map)
+}
+
+def zwaveEvent(physicalgraph.zwave.Command cmd) {
+ log.debug "Unhandled command: ${cmd}"
+ [:]
+}
+
+private secure(cmd) {
+ if(zwaveInfo.zw.endsWith("s")) {
+ zwave.securityV1.securityMessageEncapsulation().encapsulate(cmd).format()
+ } else {
+ cmd.format()
+ }
+}
\ No newline at end of file
diff --git a/devicetypes/smartthings/zwave-motion-light-sensor.src/zwave-motion-light-sensor.groovy b/devicetypes/smartthings/zwave-motion-light-sensor.src/zwave-motion-light-sensor.groovy
index d13faa016c1..26ed7d77b2a 100644
--- a/devicetypes/smartthings/zwave-motion-light-sensor.src/zwave-motion-light-sensor.groovy
+++ b/devicetypes/smartthings/zwave-motion-light-sensor.src/zwave-motion-light-sensor.groovy
@@ -31,7 +31,6 @@ metadata {
fingerprint mfr: "0258", prod: "0003", model: "008D", deviceJoinName: "NEO Coolcam Motion/Light Sensor"
//zw:S type:0701 mfr:0258 prod:0003 model:108D ver:3.80 zwv:4.38 lib:06 cc:5E,86,72,5A,73,80,31,71,30,70,85,59,84 role:06 ff:8C07 ui:8C07 EU version
fingerprint mfr: "0258", prod: "0003", model: "108D", deviceJoinName: "NEO Coolcam Motion/Light Sensor"
- fingerprint mfr: "0060", prod: "0012", model: "0001", deviceJoinName: "Everspring Outdoor Floodlight", mmnm: "SmartThings", vid: "generic-motion-light-sensor"
}
simulator {
@@ -90,10 +89,6 @@ def updated() {
def configure() {
// Device wakes up every deviceCheckInterval hours, this interval allows us to miss one wakeup notification before marking offline
sendEvent(name: "checkInterval", value: 2 * deviceWakeUpInterval * 60 * 60 + 2 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID])
-
- if (isEverspringFloodlight()) {
- response(zwave.configurationV1.configurationSet(parameterNumber: 3, size: 2, scaledConfigurationValue: 600)) //enables illuminance report every 10 minutes
- }
}
def getDeviceWakeUpInterval() {
@@ -126,7 +121,7 @@ private getCommandClassVersions() {
def parse(String description) {
def results = []
if (description.startsWith("Err")) {
- results += createEvent(descriptionText: description, displayed: true)
+ results << createEvent(descriptionText: description, displayed: true)
} else {
def cmd = zwave.parse(description, commandClassVersions)
if (cmd) {
@@ -149,9 +144,9 @@ def zwaveEvent(physicalgraph.zwave.commands.notificationv3.NotificationReport cm
def results = []
if (cmd.notificationType == 0x07) { // Burglar
if (cmd.event == 0x08) { // detected
- results += sensorMotionEvent(1)
+ results << sensorMotionEvent(1)
} else if (cmd.event == 0x00) { // inactive
- results += sensorMotionEvent(0)
+ results << sensorMotionEvent(0)
}
}
return results
@@ -167,7 +162,7 @@ def zwaveEvent(physicalgraph.zwave.commands.batteryv1.BatteryReport cmd) {
} else {
map.value = cmd.batteryLevel
}
- results += createEvent(map)
+ results << createEvent(map)
return results
}
@@ -184,21 +179,21 @@ def zwaveEvent(physicalgraph.zwave.commands.sensormultilevelv5.SensorMultilevelR
default:
map.descriptionText = cmd.toString()
}
- results += createEvent(map)
+ results << createEvent(map)
return results
}
def zwaveEvent(physicalgraph.zwave.commands.wakeupv2.WakeUpNotification cmd) {
def results = []
- results += createEvent(descriptionText: "$device.displayName woke up", isStateChange: false)
- results += response(zwave.sensorMultilevelV5.sensorMultilevelGet(sensorType: 3, scale: 1).format())
+ results << createEvent(descriptionText: "$device.displayName woke up", isStateChange: false)
+ results << response(zwave.sensorMultilevelV5.sensorMultilevelGet(sensorType: 3, scale: 1).format())
if (!state.lastbatt || (now() - state.lastbatt) >= 10 * 60 * 60 * 1000) {
- results += response(["delay 1000",
+ results << response(["delay 1000",
zwave.batteryV1.batteryGet().format(),
"delay 2000"
])
}
- results += response(zwave.wakeUpV2.wakeUpNoMoreInformation().format())
+ results << response(zwave.wakeUpV2.wakeUpNoMoreInformation().format())
return results
}
@@ -211,13 +206,9 @@ def zwaveEvent(physicalgraph.zwave.Command cmd) {
def sensorMotionEvent(value) {
def result = []
if (value) {
- result += createEvent(name: "motion", value: "active", descriptionText: "$device.displayName detected motion")
+ result << createEvent(name: "motion", value: "active", descriptionText: "$device.displayName detected motion")
} else {
- result += createEvent(name: "motion", value: "inactive", descriptionText: "$device.displayName motion has stopped")
+ result << createEvent(name: "motion", value: "inactive", descriptionText: "$device.displayName motion has stopped")
}
return result
}
-
-private isEverspringFloodlight() {
- zwaveInfo.mfr == "0060" && zwaveInfo.model == "0001"
-}
From 9c45b74e39ad8662b1a902aea59beb361ef6e940 Mon Sep 17 00:00:00 2001
From: Przemyslaw Kacprowicz
Date: Mon, 21 Oct 2019 11:47:26 +0200
Subject: [PATCH 2/5] Changed name of DTH to be more generic.
---
.../zwave-motion-light.groovy} | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
rename devicetypes/smartthings/{everspring-outdoor-floodlight.src/everspring-outdoor-floodlight.groovy => zwave-motion-light.src/zwave-motion-light.groovy} (92%)
diff --git a/devicetypes/smartthings/everspring-outdoor-floodlight.src/everspring-outdoor-floodlight.groovy b/devicetypes/smartthings/zwave-motion-light.src/zwave-motion-light.groovy
similarity index 92%
rename from devicetypes/smartthings/everspring-outdoor-floodlight.src/everspring-outdoor-floodlight.groovy
rename to devicetypes/smartthings/zwave-motion-light.src/zwave-motion-light.groovy
index 6e7d8271843..a8bd2cc7226 100644
--- a/devicetypes/smartthings/everspring-outdoor-floodlight.src/everspring-outdoor-floodlight.groovy
+++ b/devicetypes/smartthings/zwave-motion-light.src/zwave-motion-light.groovy
@@ -13,7 +13,7 @@
*/
metadata {
- definition(name: "Everpsring Outdoor Floodlight", namespace: "smartthings", author: "SmartThings", ocfDeviceType: "oic.d.light", mmnm: "SmartThings", vid: "generic-motion-light-sensor") {
+ definition(name: "Z-Wave Motion Light", namespace: "smartthings", author: "SmartThings", ocfDeviceType: "oic.d.light", mmnm: "SmartThings", vid: "generic-motion-light") {
capability "Switch"
capability "Motion Sensor"
capability "Illuminance Measurement"
@@ -34,8 +34,8 @@ metadata {
}
}
tileAttribute("motion", "device.motion", decoration: "flat", width: 2, height: 2) {
- attributeState("active", label: 'motion', icon: "st.motion.motion.active", backgroundColor: "#00A0DC")
- attributeState("inactive", label: 'no motion', icon: "st.motion.motion.inactive", backgroundColor: "#CCCCCC")
+ state("active", label: 'motion', icon: "st.motion.motion.active", backgroundColor: "#00A0DC")
+ state("inactive", label: 'no motion', icon: "st.motion.motion.inactive", backgroundColor: "#CCCCCC")
}
valueTile("illuminance", "device.illuminance", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
state "illuminance", label: '${currentValue} lux', backgroundColors: [
From fbd65722d94e8691edd839ed93f83114252d21dc Mon Sep 17 00:00:00 2001
From: Przemyslaw Kacprowicz
Date: Mon, 21 Oct 2019 14:19:00 +0200
Subject: [PATCH 3/5] Fixed another wrong definition in tiles.
---
.../zwave-motion-light.src/zwave-motion-light.groovy | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/devicetypes/smartthings/zwave-motion-light.src/zwave-motion-light.groovy b/devicetypes/smartthings/zwave-motion-light.src/zwave-motion-light.groovy
index a8bd2cc7226..6399ad5e577 100644
--- a/devicetypes/smartthings/zwave-motion-light.src/zwave-motion-light.groovy
+++ b/devicetypes/smartthings/zwave-motion-light.src/zwave-motion-light.groovy
@@ -33,7 +33,7 @@ metadata {
attributeState("turningOff", label:'${name}', action:"switch.on", icon:"st.lights.philips.hue-single", backgroundColor:"#ffffff", nextState:"turningOn")
}
}
- tileAttribute("motion", "device.motion", decoration: "flat", width: 2, height: 2) {
+ valueTile("motion", "device.motion", decoration: "flat", width: 2, height: 2) {
state("active", label: 'motion', icon: "st.motion.motion.active", backgroundColor: "#00A0DC")
state("inactive", label: 'no motion', icon: "st.motion.motion.inactive", backgroundColor: "#CCCCCC")
}
From fc44ea06c7dcfc8c87b25ca44868b8969d9ed573 Mon Sep 17 00:00:00 2001
From: Przemyslaw Kacprowicz
Date: Fri, 25 Oct 2019 10:37:54 +0200
Subject: [PATCH 4/5] Couple of fixes
---
.../zwave-motion-light.src/zwave-motion-light.groovy | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/devicetypes/smartthings/zwave-motion-light.src/zwave-motion-light.groovy b/devicetypes/smartthings/zwave-motion-light.src/zwave-motion-light.groovy
index 6399ad5e577..06e68555163 100644
--- a/devicetypes/smartthings/zwave-motion-light.src/zwave-motion-light.groovy
+++ b/devicetypes/smartthings/zwave-motion-light.src/zwave-motion-light.groovy
@@ -72,10 +72,14 @@ def configure() {
secure(zwave.notificationV3.notificationGet(notificationType: 0x07)),
secure(zwave.sensorMultilevelV5.sensorMultilevelGet(sensorType: 0x03)),
secure(zwave.switchBinaryV1.switchBinaryGet()),
- secure(zwave.configurationV1.configurationSet(parameterNumber: 3, size: 2, scaledConfigurationValue: 600)) //enables illuminance report every 10 minutes
+ secure(zwave.configurationV1.configurationSet(parameterNumber: 3, size: 2, scaledConfigurationValue: 10)) //enables illuminance report every 10 minutes
]
}
+def ping() {
+ response(secure(zwave.switchBinaryV1.switchBinaryGet()))
+}
+
def parse(String description) {
def result = []
if (description.startsWith("Err")) {
@@ -154,7 +158,7 @@ def zwaveEvent(physicalgraph.zwave.Command cmd) {
}
private secure(cmd) {
- if(zwaveInfo.zw.endsWith("s")) {
+ if(zwaveInfo.zw.contains("s")) {
zwave.securityV1.securityMessageEncapsulation().encapsulate(cmd).format()
} else {
cmd.format()
From 9ea712bc44626e1281a5151dbde9f3e9deafaf41 Mon Sep 17 00:00:00 2001
From: Przemyslaw Kacprowicz
Date: Fri, 25 Oct 2019 10:42:24 +0200
Subject: [PATCH 5/5] Added device check for configuration change.
---
.../zwave-motion-light.groovy | 13 ++++++++++---
1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/devicetypes/smartthings/zwave-motion-light.src/zwave-motion-light.groovy b/devicetypes/smartthings/zwave-motion-light.src/zwave-motion-light.groovy
index 06e68555163..a493d983363 100644
--- a/devicetypes/smartthings/zwave-motion-light.src/zwave-motion-light.groovy
+++ b/devicetypes/smartthings/zwave-motion-light.src/zwave-motion-light.groovy
@@ -68,12 +68,15 @@ def updated() {
}
def configure() {
- [
+ def cmds = [
secure(zwave.notificationV3.notificationGet(notificationType: 0x07)),
secure(zwave.sensorMultilevelV5.sensorMultilevelGet(sensorType: 0x03)),
- secure(zwave.switchBinaryV1.switchBinaryGet()),
- secure(zwave.configurationV1.configurationSet(parameterNumber: 3, size: 2, scaledConfigurationValue: 10)) //enables illuminance report every 10 minutes
+ secure(zwave.switchBinaryV1.switchBinaryGet())
]
+ if (isEverspringFloodlight()) {
+ cmds += secure(zwave.configurationV1.configurationSet(parameterNumber: 3, size: 2, scaledConfigurationValue: 10)) //enables illuminance report every 10 minutes
+ }
+ cmds
}
def ping() {
@@ -163,4 +166,8 @@ private secure(cmd) {
} else {
cmd.format()
}
+}
+
+private isEverspringFloodlight() {
+ zwaveInfo.mfr == "0060" && zwaveInfo.prod == "0012"
}
\ No newline at end of file