-
Notifications
You must be signed in to change notification settings - Fork 88.5k
[ICP-11264] Providing new DTH for Everspring Outdoor Floodlight #11383
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
9045de3
9c45b74
fbd6572
fc44ea0
9ea712b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since Same with Line 149. |
||
| } 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", | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I believe for this
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've only reverted my changes, so it went back as it was before I've started editing. |
||
| 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" | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,173 @@ | ||
| /** | ||
| * 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: "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" | ||
| 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") | ||
| } | ||
| } | ||
| 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") | ||
| } | ||
| 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() { | ||
| def cmds = [ | ||
| secure(zwave.notificationV3.notificationGet(notificationType: 0x07)), | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: Just two levels of indentation for this and all below. |
||
| secure(zwave.sensorMultilevelV5.sensorMultilevelGet(sensorType: 0x03)), | ||
| 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() { | ||
| response(secure(zwave.switchBinaryV1.switchBinaryGet())) | ||
| } | ||
|
|
||
| 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.contains("s")) { | ||
| zwave.securityV1.securityMessageEncapsulation().encapsulate(cmd).format() | ||
| } else { | ||
| cmd.format() | ||
| } | ||
| } | ||
|
|
||
| private isEverspringFloodlight() { | ||
| zwaveInfo.mfr == "0060" && zwaveInfo.prod == "0012" | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Generally, if you are removing a device from a DTH that has been published where there are customer devices already using it you would leave code for that device in the DTH and remove the fingerprint. This would be so that devices already paired continue to work. This seems a little less risky, but I'd probably leave it, and leave a note above the
ifblock indicating why it is staying around.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@tpmanley Thoughts?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since it's in the configure method I don't anticipate it being an issue, since anything already added would have already had this called.