From 77b1e43536f7487a770e4344565355da5270e9ca Mon Sep 17 00:00:00 2001 From: ZWozniakS <48519140+ZWozniakS@users.noreply.github.com> Date: Tue, 9 Jun 2020 19:54:52 +0200 Subject: [PATCH] [WWST-5069,ICP-12456] Added FP and integrated Everspring SP815 and fixed and added parameter for Evesrping SP817 (#32967) * Added FP and integrated Everspring SP815 and fixed and added parameter for Everspring SP817 Co-authored-by: Zuzanna Wozniak/Home IoT Development (IoT) /SRPOL/Engineer/Samsung Electronics --- .../zooz-4-in-1-sensor.groovy | 119 ++++++++++++- .../zwave-motion-sensor.groovy | 160 +++++++----------- 2 files changed, 176 insertions(+), 103 deletions(-) diff --git a/devicetypes/smartthings/zooz-4-in-1-sensor.src/zooz-4-in-1-sensor.groovy b/devicetypes/smartthings/zooz-4-in-1-sensor.src/zooz-4-in-1-sensor.groovy index efd89dd0754..9e79a63a7b0 100644 --- a/devicetypes/smartthings/zooz-4-in-1-sensor.src/zooz-4-in-1-sensor.groovy +++ b/devicetypes/smartthings/zooz-4-in-1-sensor.src/zooz-4-in-1-sensor.groovy @@ -23,8 +23,9 @@ metadata { capability "Health Check" capability "Tamper Alert" - fingerprint mfr: "027A", prod: "2021", model: "2101", deviceJoinName: "Zooz Multipurpose Sensor" //Zooz 4-in-1 sensor - fingerprint mfr: "0109", prod: "2021", model: "2101", deviceJoinName: "Vision Multipurpose Sensor" //ZP3111US 4-in-1 Motion + fingerprint mfr: "027A", prod: "2021", model: "2101", deviceJoinName: "Zooz Multipurpose Sensor" // Zooz 4-in-1 sensor + fingerprint mfr: "0109", prod: "2021", model: "2101", deviceJoinName: "Vision Multipurpose Sensor" // ZP3111US 4-in-1 Motion + fingerprint mfr: "0060", prod: "0001", model: "0004", deviceJoinName: "Everspring Motion Sensor", mnmn: "SmartThings", vid: "SmartThings-smartthings-Everspring_Multisensor" // Everspring Immune Pet PIR Sensor SP815 } tiles(scale: 2) { @@ -63,8 +64,36 @@ metadata { main(["motion", "temperature", "humidity", "illuminance"]) details(["motion", "temperature", "humidity", "illuminance", "battery", "tamper"]) } + + preferences { + section { + input( + title: "Settings Available For Everspring SP815 only", + description: "To apply updated device settings to the device press the learn key on the device three times or check the device manual.", + type: "paragraph", + element: "paragraph" + ) + input( + title: "Temperature and Humidity Auto Report (Everspring SP815 only):", + description: "This setting allows to adjusts report time (in seconds) of temperature and humidity report.", + name: "temperatureAndHumidityReport", + type: "number", + range: "600..1440", + defaultValue: 600 + ) + input( + title: "Re-trigger Interval Setting (Everspring SP815 only):", + description: "The setting adjusts the sleep period (in seconds) after the detector has been triggered. No response will be made during this interval if a movement is presented. Longer re-trigger interval will result in longer battery life.", + name: "retriggerIntervalSettings", + type: "number", + range: "10..3600", + defaultValue: 180 + ) + } + } } + def initialize() { sendEvent(name: "checkInterval", value: 2 * 60 * 60 + 2 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID]) clearTamper() @@ -76,6 +105,7 @@ def installed() { def updated() { initialize() + getConfigurationCommands() } def parse(String description) { @@ -95,6 +125,12 @@ def parse(String description) { def zwaveEvent(physicalgraph.zwave.commands.wakeupv2.WakeUpNotification cmd) { def results = [] results += createEvent(descriptionText: "$device.displayName woke up", isStateChange: false) + + log.debug "isConfigured: $state.configured" + if (isEverspringSP815() && !state.configured) { + results += lateConfigure() + } + results += response([ secure(zwave.batteryV1.batteryGet()), "delay 2000", @@ -182,6 +218,7 @@ def zwaveEvent(physicalgraph.zwave.commands.notificationv3.NotificationReport cm } else { result = createEvent(descriptionText: cmd.toString(), isStateChange: false) } + return result } @@ -194,12 +231,21 @@ def ping() { } def configure() { + if (isEverspringSP815()) { + state.configured = false + state.intervalConfigured = false + state.temperatureConfigured = false + } def request = [] request << zwave.batteryV1.batteryGet() request << zwave.notificationV3.notificationGet(notificationType: 0x07, event: 0x08) //motion request << zwave.sensorMultilevelV5.sensorMultilevelGet(sensorType: 0x01) //temperature - request << zwave.sensorMultilevelV5.sensorMultilevelGet(sensorType: 0x03) //illuminance request << zwave.sensorMultilevelV5.sensorMultilevelGet(sensorType: 0x05) //humidity + if (isEverspringSP815()) { + request += getConfigurationCommands() + } else { + request << zwave.sensorMultilevelV5.sensorMultilevelGet(sensorType: 0x03) //illuminance + } secureSequence(request) + ["delay 20000", zwave.wakeUpV2.wakeUpNoMoreInformation().format()] } @@ -236,3 +282,70 @@ private secure(physicalgraph.zwave.Command cmd) { private secureSequence(commands, delay = 200) { delayBetween(commands.collect{ secure(it) }, delay) } + +def getConfigurationCommands() { + log.debug "getConfigurationCommands" + def result = [] + + if (isEverspringSP815()) { + Integer temperatureAndHumidityReport = (settings.temperatureAndHumidityReport as Integer) ?: everspringDefaults[1] + Integer retriggerIntervalSettings = (settings.retriggerIntervalSettings as Integer) ?: everspringDefaults[2] + + if (!state.temperatureAndHumidityReport) { + state.temperatureAndHumidityReport = getEverspringDefaults[1] + } + if (!state.retriggerIntervalSettings) { + state.retriggerIntervalSettings = getEverspringDefaults[2] + } + + if (!state.configured || (temperatureAndHumidityReport != state.temperatureAndHumidityReport || retriggerIntervalSettings != state.retriggerIntervalSettings)) { + state.configured = false // this flag needs to be set to false when settings are changed (and the device was initially configured before) + + if (!state.temperatureConfigured || temperatureAndHumidityReport != state.temperatureAndHumidityReport) { + state.temperatureConfigured = false + result << zwave.configurationV2.configurationSet(parameterNumber: 1, size: 2, scaledConfigurationValue: temperatureAndHumidityReport) + result << zwave.configurationV2.configurationGet(parameterNumber: 1) + } + if (!state.intervalConfigured || retriggerIntervalSettings != state.retriggerIntervalSettings) { + state.intervalConfigured = false + result << zwave.configurationV2.configurationSet(parameterNumber: 2, size: 2, scaledConfigurationValue: retriggerIntervalSettings) + result << zwave.configurationV2.configurationGet(parameterNumber: 2) + } + } + } + + return result +} + +def getEverspringDefaults() { + [1: 600, + 2: 180] +} + +def lateConfigure() { + log.debug "lateConfigure" + sendHubCommand(getConfigurationCommands(), 200) +} + +def zwaveEvent(physicalgraph.zwave.commands.configurationv2.ConfigurationReport cmd) { + if (isEverspringSP815()) { + if (cmd.parameterNumber == 1) { + state.temperatureAndHumidityReport = scaledConfigurationValue + state.temperatureConfigured = true + } else if (cmd.parameterNumber == 2) { + state.retriggerIntervalSettings = scaledConfigurationValue + state.intervalConfigured = true + } + + if (state.intervalConfigured && state.temperatureConfigured) { + state.configured = true + } + log.debug "Everspring Configuration Report: ${cmd}" + } + + return [:] +} + +private isEverspringSP815() { + zwaveInfo?.mfr?.equals("0060") && zwaveInfo?.model?.equals("0004") +} diff --git a/devicetypes/smartthings/zwave-motion-sensor.src/zwave-motion-sensor.groovy b/devicetypes/smartthings/zwave-motion-sensor.src/zwave-motion-sensor.groovy index 70f82aa9824..272c762440b 100644 --- a/devicetypes/smartthings/zwave-motion-sensor.src/zwave-motion-sensor.groovy +++ b/devicetypes/smartthings/zwave-motion-sensor.src/zwave-motion-sensor.groovy @@ -17,7 +17,7 @@ */ metadata { - definition (name: "Z-Wave Motion Sensor", namespace: "smartthings", author: "SmartThings", ocfDeviceType: "x.com.st.d.sensor.motion", runLocally: true, minHubCoreVersion: '000.017.0012', executeCommandsLocally: false, genericHandler: "Z-Wave") { + definition(name: "Z-Wave Motion Sensor", namespace: "smartthings", author: "SmartThings", ocfDeviceType: "x.com.st.d.sensor.motion", runLocally: true, minHubCoreVersion: '000.017.0012', executeCommandsLocally: false, genericHandler: "Z-Wave") { capability "Motion Sensor" capability "Sensor" capability "Battery" @@ -25,17 +25,29 @@ metadata { capability "Tamper Alert" capability "Configuration" - fingerprint mfr: "011F", prod: "0001", model: "0001", deviceJoinName: "Schlage Motion Sensor" // Schlage motion //Schlage Motion Sensor - fingerprint mfr: "014A", prod: "0001", model: "0001", deviceJoinName: "Ecolink Motion Sensor" // Ecolink motion //Ecolink Motion Sensor - fingerprint mfr: "014A", prod: "0004", model: "0001", deviceJoinName: "Ecolink Motion Sensor" // Ecolink motion + //Ecolink Motion Sensor - fingerprint mfr: "0060", prod: "0001", model: "0002", deviceJoinName: "Everspring Motion Sensor" // Everspring SP814 //Everspring Motion Sensor - fingerprint mfr: "0060", prod: "0001", model: "0003", deviceJoinName: "Everspring Motion Sensor" // Everspring HSP02 //Everspring Motion Sensor - fingerprint mfr: "0060", prod: "0001", model: "0004", deviceJoinName: "Everspring Motion Sensor" //Everspring SP815 //Everspring Motion Detector - fingerprint mfr: "0060", prod: "0001", model: "0005", deviceJoinName: "Everspring Motion Sensor" //Everspring Motion Detector - fingerprint mfr: "0060", prod: "0001", model: "0006", deviceJoinName: "Everspring Motion Sensor" //Everspring SP817 //Everspring Motion Detector - fingerprint mfr: "011A", prod: "0601", model: "0901", deviceJoinName: "Enerwave Motion Sensor" // Enerwave ZWN-BPC //Enerwave Motion Sensor - fingerprint mfr: "0063", prod: "4953", model: "3133", deviceJoinName: "GE Motion Sensor" //GE Portable Smart Motion Sensor - fingerprint mfr: "0214", prod: "0003", model: "0002", deviceJoinName: "BeSense Motion Sensor" //BeSense Motion Detector + // BeSense + fingerprint mfr: "0214", prod: "0003", model: "0002", deviceJoinName: "BeSense Motion Sensor" // BeSense Motion Detector + + // Ecolink + fingerprint mfr: "014A", prod: "0001", model: "0001", deviceJoinName: "Ecolink Motion Sensor" // Ecolink motion //Ecolink Motion Sensor + fingerprint mfr: "014A", prod: "0004", model: "0001", deviceJoinName: "Ecolink Motion Sensor" // Ecolink motion + //Ecolink Motion Sensor + + // Enerwave + fingerprint mfr: "011A", prod: "0601", model: "0901", deviceJoinName: "Enerwave Motion Sensor" // Enerwave ZWN-BPC //Enerwave Motion Sensor + + // Everspring + fingerprint mfr: "0060", prod: "0001", model: "0002", deviceJoinName: "Everspring Motion Sensor" // Everspring SP814 //Everspring Motion Sensor + fingerprint mfr: "0060", prod: "0001", model: "0003", deviceJoinName: "Everspring Motion Sensor" // Everspring HSP02 //Everspring Motion Sensor + fingerprint mfr: "0060", prod: "0001", model: "0005", deviceJoinName: "Everspring Motion Sensor" // Everspring Motion Detector + fingerprint mfr: "0060", prod: "0001", model: "0006", deviceJoinName: "Everspring Motion Sensor" // Everspring SP817 //Everspring Motion Detector + + // GE + fingerprint mfr: "0063", prod: "4953", model: "3133", deviceJoinName: "GE Motion Sensor" // GE Portable Smart Motion Sensor + + // Shlage + fingerprint mfr: "011F", prod: "0001", model: "0001", deviceJoinName: "Schlage Motion Sensor" // Schlage motion //Schlage Motion Sensor + + // Zooz fingerprint mfr: "027A", prod: "0001", model: "0005", deviceJoinName: "Zooz Motion Sensor" //Zooz Outdoor Motion Sensor fingerprint mfr: "027A", prod: "0301", model: "0012", deviceJoinName: "Zooz Motion Sensor", mnmn: "SmartThings", vid: "generic-motion-2" //Zooz Motion Sensor } @@ -46,14 +58,14 @@ metadata { } tiles(scale: 2) { - multiAttributeTile(name:"motion", type: "generic", width: 6, height: 4){ + multiAttributeTile(name: "motion", type: "generic", width: 6, height: 4) { tileAttribute("device.motion", key: "PRIMARY_CONTROL") { - attributeState("active", label:'motion', icon:"st.motion.motion.active", backgroundColor:"#00A0DC") - attributeState("inactive", label:'no motion', icon:"st.motion.motion.inactive", backgroundColor:"#CCCCCC") + attributeState("active", label: 'motion', icon: "st.motion.motion.active", backgroundColor: "#00A0DC") + attributeState("inactive", label: 'no motion', icon: "st.motion.motion.inactive", backgroundColor: "#CCCCCC") } } valueTile("battery", "device.battery", inactiveLabel: false, decoration: "flat", width: 2, height: 2) { - state("battery", label:'${currentValue}% battery', unit:"") + state("battery", label: '${currentValue}% battery', unit: "") } valueTile("tamper", "device.tamper", height: 2, width: 2, decoration: "flat") { state "clear", label: 'tamper clear', backgroundColor: "#ffffff" @@ -64,33 +76,26 @@ metadata { details(["motion", "battery", "tamper"]) } - // Preferences for Everspring SP815 and Everspring SP817 - // preferences { + // Preferences for Everspring SP817 + preferences { section { input( - title: "Settings Available For Everspring SP815 and SP817 only", - description: "", + title: "Settings Available For Everspring SP817 only", + description: "To apply updated device settings to the device press the tamper switch on the device three times or check the device manual.", type: "paragraph", element: "paragraph" ) - input ( - title: "Temperature and Humidity Auto Report (Everspring SP815 only):", - description: "This setting allows to adjusts report time (in seconds) of temperature and humidity report.", - name: "temperatureAndHumidityReport", - type: "number", - range: "600..1440", - defaultValue: 600 - ) // defaultValue: 600 - input ( - title: "Re-trigger Interval Setting (Everspring SP815 and Everspring SP817 only):", + input( + title: "Re-trigger Interval Setting (Everspring SP817 only):", description: "The setting adjusts the sleep period (in seconds) after the detector has been triggered. No response will be made during this interval if a movement is presented. Longer re-trigger interval will result in longer battery life.", name: "retriggerIntervalSettings", type: "number", range: "10..3600", defaultValue: 180 - ) // defaultValue: 180 + ) } } +} def installed() { // Device wakes up every 4 hours, this interval allows us to miss one wakeup notification before marking offline @@ -102,16 +107,12 @@ def updated() { log.debug "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]) - response(getConfigurationCommands()) + getConfigurationCommands() } def configure() { - if (isEverspringSP815orSP817()) { + if (isEverspringSP817()) { state.configured = false - state.intervalConfigured = false - if(isEverspringSP815()){ - state.temperatureConfigured = false - } } response(initialPoll()) } @@ -123,7 +124,7 @@ private getCommandClassVersions() { def parse(String description) { def result = null if (description.startsWith("Err")) { - result = createEvent(descriptionText:description) + result = createEvent(descriptionText:description) } else { def cmd = zwave.parse(description, commandClassVersions) if (cmd) { @@ -195,10 +196,6 @@ def zwaveEvent(physicalgraph.zwave.commands.notificationv3.NotificationReport cm result << createEvent(name: "alarm $cmd.v1AlarmType", value: value, isStateChange: true, displayed: false) } - log.debug "isConfigured: ${isConfigured()}" - if (isEverspringSP815orSP817() && !isConfigured()) { - result += lateConfigure() - } result } @@ -210,8 +207,9 @@ def zwaveEvent(physicalgraph.zwave.commands.wakeupv1.WakeUpNotification cmd) { def result = [createEvent(descriptionText: "${device.displayName} woke up", isStateChange: false)] - if (isEverspringSP815orSP817() && !isConfigured()) { - result += lateConfigure(true) + log.debug "isConfigured: $state.configured" + if (isEverspringSP817() && !state.configured) { + result = lateConfigure() } if (isEnerwave() && device.currentState('motion') == null) { // Enerwave motion doesn't always get the associationSet that the hub sends on join @@ -329,7 +327,7 @@ def initialPoll() { if (isEnerwave()) { // Enerwave motion doesn't always get the associationSet that the hub sends on join request << zwave.associationV1.associationSet(groupingIdentifier:1, nodeId:zwaveHubNodeId) } - if (isEverspringSP815orSP817()) { + if (isEverspringSP817()) { request += getConfigurationCommands() } request << zwave.batteryV1.batteryGet() @@ -357,84 +355,46 @@ private command(physicalgraph.zwave.Command cmd) { def getConfigurationCommands() { log.debug "getConfigurationCommands" def result = [] - if (isEverspringSP815()) { - if (!state.temperatureAndHumidityReport) state.temperatureAndHumidityReport = getEverspringDefaults[1] - if (!state.retriggerIntervalSettings) state.retriggerIntervalSettings = getEverspringDefaults[2] - - Integer temperatureAndHumidityReport = (settings.temperatureAndHumidityReport as Integer) ?: everspringDefaults[1] - Integer retriggerIntervalSettings = (settings.retriggerIntervalSettings as Integer) ?: everspringDefaults[2] - - if (!isConfigured() || (temperatureAndHumidityReport != state.temperatureAndHumidityReport || retriggerIntervalSettings != state.retriggerIntervalSettings)) { - state.configured = false // this flag needs to be set to false when settings are changed (and the device was initially configured before) - if (!state.temperatureConfigured || temperatureAndHumidityReport != state.temperatureAndHumidityReport) { - state.temperatureConfigured = false - result << zwave.configurationV2.configurationSet(parameterNumber: 1, size: 2, scaledConfigurationValue: temperatureAndHumidityReport) - result << zwave.configurationV2.configurationGet(parameterNumber: 1) - } - if (!state.intervalConfigured || retriggerIntervalSettings != state.retriggerIntervalSettings) { - state.intervalConfigured = false - result << zwave.configurationV2.configurationSet(parameterNumber: 2, size: 2, scaledConfigurationValue: retriggerIntervalSettings) - result << zwave.configurationV2.configurationGet(parameterNumber: 2) - } + + if (isEverspringSP817()) { + Integer retriggerIntervalSettings = (settings.retriggerIntervalSettings as Integer) ?: 180 // default value (parameter 4) for Everspring SP817 + + if (!state.retriggerIntervalSettings) { + state.retriggerIntervalSettings = 180 // default value (parameter 4) for Everspring SP817 } - } else if (isEverspringSP817()) { - if (!state.retriggerIntervalSettings) state.retriggerIntervalSettings = everspringDefaults[2] - Integer retriggerIntervalSettings = (settings.retriggerIntervalSettings as Integer) ?: everspringDefaults[2] - if (!isConfigured() || (retriggerIntervalSettings != state.retriggerIntervalSettings)) { + + if (!state.configured || (retriggerIntervalSettings != state.retriggerIntervalSettings)) { + // when state.configured is true but if there were changes made through the preferences section this flag needs to be reset state.configured = false - if (!state.intervalConfigured || retriggerIntervalSettings != state.retriggerIntervalSettings) { - state.intervalConfigured = false - result << zwave.configurationV2.configurationSet(parameterNumber: 4, size: 2, scaledConfigurationValue: retriggerIntervalSettings) - result << zwave.configurationV2.configurationGet(parameterNumber: 4) + result << zwave.configurationV2.configurationSet(parameterNumber: 4, size: 2, scaledConfigurationValue: retriggerIntervalSettings) + result << zwave.configurationV2.configurationGet(parameterNumber: 4) } } - } - return result -} -def getEverspringDefaults() { - [1: 600, - 2: 180] + return result } def lateConfigure() { log.debug "lateConfigure" - sendHubCommand(commands(getConfigurationCommands(),200)) -} - -private isConfigured() { - return state.configured == true + sendHubCommand(getConfigurationCommands(), 200) } def zwaveEvent(physicalgraph.zwave.commands.configurationv2.ConfigurationReport cmd) { - if (isEverspringSP815orSP817()) { - if (cmd.parameterNumber == 1) { - state.temperatureAndHumidityReport = scaledConfigurationValue - state.temperatureConfigured = true - } else if ((isEverspringSP815() && cmd.parameterNumber == 2) || (isEverspringSP817() && cmd.parameterNumber == 4)) { + if (isEverspringSP817()) { + if (cmd.parameterNumber == 4) { state.retriggerIntervalSettings = scaledConfigurationValue - state.intervalConfigured = true - } - if (state.intervalConfigured == true && (isEverspringSP817() || (isEverspringSP815() && state.temperatureConfigured== true))) { state.configured = true } log.debug "Everspring Configuration Report: ${cmd}" - return [:] } + + return [:] } private isEnerwave() { zwaveInfo?.mfr?.equals("011A") && zwaveInfo?.prod?.equals("0601") && zwaveInfo?.model?.equals("0901") } -private isEverspringSP815() { - zwaveInfo?.mfr?.equals("0060") && zwaveInfo?.model?.equals("0004") -} - private isEverspringSP817() { zwaveInfo?.mfr?.equals("0060") && zwaveInfo?.model?.equals("0006") } - -private isEverspringSP815orSP817() { - zwaveInfo?.mfr?.equals("0060") && (zwaveInfo?.model?.equals("0004") || zwaveInfo?.model?.equals("0006")) -}