/** * Copyright 2015 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: "Aeon Multisensor Gen5 Battery Settings - fixed settings", namespace: "Aeotec", author: "Chris Cheng") { capability "Motion Sensor" capability "Temperature Measurement" capability "Relative Humidity Measurement" capability "Illuminance Measurement" capability "Sensor" capability "Battery" capability "Configuration" command "configureAfterSecure" fingerprint deviceId: "0x0701", inClusters: "0x5E,0x86,0x72,0x59,0x85,0x73,0x71,0x84,0x80,0x30,0x31,0x70,0x98,0x7A", outClusters:"0x5A" } simulator { status "no motion" : "command: 9881, payload: 00300300" status "motion" : "command: 9881, payload: 003003FF" for (int i = 0; i <= 100; i += 20) { status "temperature ${i}F": new physicalgraph.zwave.Zwave().securityV1.securityMessageEncapsulation().encapsulate( new physicalgraph.zwave.Zwave().sensorMultilevelV2.sensorMultilevelReport( scaledSensorValue: i, precision: 1, sensorType: 1, scale: 1) ).incomingMessage() } for (int i = 0; i <= 100; i += 20) { status "humidity ${i}%": new physicalgraph.zwave.Zwave().securityV1.securityMessageEncapsulation().encapsulate( new physicalgraph.zwave.Zwave().sensorMultilevelV2.sensorMultilevelReport(scaledSensorValue: i, sensorType: 5) ).incomingMessage() } for (int i in [0, 20, 89, 100, 200, 500, 1000]) { status "illuminance ${i} lux": new physicalgraph.zwave.Zwave().securityV1.securityMessageEncapsulation().encapsulate( new physicalgraph.zwave.Zwave().sensorMultilevelV2.sensorMultilevelReport(scaledSensorValue: i, sensorType: 3) ).incomingMessage() } for (int i in [0, 5, 10, 15, 50, 99, 100]) { status "battery ${i}%": new physicalgraph.zwave.Zwave().securityV1.securityMessageEncapsulation().encapsulate( new physicalgraph.zwave.Zwave().batteryV1.batteryReport(batteryLevel: i) ).incomingMessage() } status "low battery alert": new physicalgraph.zwave.Zwave().securityV1.securityMessageEncapsulation().encapsulate( new physicalgraph.zwave.Zwave().batteryV1.batteryReport(batteryLevel: 255) ).incomingMessage() status "wake up" : "command: 8407, payload: " } tiles(scale: 2) { multiAttributeTile(name:"motion", type: "generic", width: 6, height: 4){ tileAttribute ("device.motion", key: "PRIMARY_CONTROL") { attributeState "active", label:'motion', icon:"st.motion.motion.active", backgroundColor:"#53a7c0" attributeState "inactive", label:'no motion', icon:"st.motion.motion.inactive", backgroundColor:"#ffffff" } } valueTile("temperature", "device.temperature", inactiveLabel: false, width: 2, height: 2) { state "temperature", label:'${currentValue}°', backgroundColors:[ [value: 32, color: "#153591"], [value: 44, color: "#1e9cbb"], [value: 59, color: "#90d2a7"], [value: 74, color: "#44b621"], [value: 84, color: "#f1d801"], [value: 92, color: "#d04e00"], [value: 98, color: "#bc2323"] ] } valueTile("humidity", "device.humidity", inactiveLabel: false, width: 2, height: 2) { state "humidity", label:'${currentValue}% humidity', unit:"" } valueTile("illuminance", "device.illuminance", inactiveLabel: false, width: 2, height: 2) { state "luminosity", label:'${currentValue} ${unit}', unit:"lux" } valueTile("battery", "device.battery", inactiveLabel: false, decoration: "flat", width: 2, height: 2) { state "battery", label:'${currentValue}% battery', unit:"" } standardTile("configureAfterSecure", "configureAfterSecure", inactiveLabel: false, decoration: "flat", width: 2, height: 2) { state "configureAfterSecure", label:"", action:"configureAfterSecure", icon:"st.secondary.configure" } main(["motion", "temperature", "humidity", "illuminance"]) details(["motion", "temperature", "humidity", "illuminance", "battery", "configureAfterSecure"]) } } def parse(String description) { def result = null if (description == "updated") { result = null } else { def cmd = zwave.parse(description, [0x31: 5, 0x30: 2, 0x84: 1]) if (cmd) { result = zwaveEvent(cmd) } } log.debug "Parsed '${description}' to ${result.inspect()}" return result } def zwaveEvent(physicalgraph.zwave.commands.wakeupv1.WakeUpNotification cmd) { def result = [createEvent(descriptionText: "${device.displayName} woke up", isStateChange: false)] if (!isConfigured()) { // we're still in the process of configuring a newly joined device log.debug("not sending wakeUpNoMoreInformation yet") result += response(configureAfterSecure()) } else { result += response(zwave.wakeUpV1.wakeUpNoMoreInformation()) } result } def zwaveEvent(physicalgraph.zwave.commands.securityv1.SecurityMessageEncapsulation cmd) { def encapsulatedCommand = cmd.encapsulatedCommand([0x31: 5, 0x30: 2, 0x84: 1]) // log.debug "encapsulated: ${encapsulatedCommand}" if (encapsulatedCommand) { zwaveEvent(encapsulatedCommand) } else { log.warn "Unable to extract encapsulated cmd from $cmd" createEvent(descriptionText: cmd.toString()) } } def zwaveEvent(physicalgraph.zwave.commands.securityv1.SecurityCommandsSupportedReport cmd) { // log.debug "Received SecurityCommandsSupportedReport" response(configureAfterSecure()) } def zwaveEvent(physicalgraph.zwave.commands.batteryv1.BatteryReport cmd) { def map = [ name: "battery", unit: "%" ] if (cmd.batteryLevel == 0xFF) { map.value = 1 map.descriptionText = "${device.displayName} battery is low" map.isStateChange = true } else { map.value = cmd.batteryLevel } state.lastbatt = new Date().time createEvent(map) } def zwaveEvent(physicalgraph.zwave.commands.sensormultilevelv5.SensorMultilevelReport cmd) { def map = [:] switch (cmd.sensorType) { case 1: map.name = "temperature" def cmdScale = cmd.scale == 1 ? "F" : "C" map.value = convertTemperatureIfNeeded(cmd.scaledSensorValue, cmdScale, cmd.precision) map.unit = getTemperatureScale() break; case 3: map.name = "illuminance" map.value = cmd.scaledSensorValue.toInteger() map.unit = "lux" break; case 5: map.name = "humidity" map.value = cmd.scaledSensorValue.toInteger() map.unit = "%" break; default: map.descriptionText = cmd.toString() } createEvent(map) } def motionEvent(value) { def map = [name: "motion"] if (value) { map.value = "active" map.descriptionText = "$device.displayName detected motion" } else { map.value = "inactive" map.descriptionText = "$device.displayName motion has stopped" } createEvent(map) } def zwaveEvent(physicalgraph.zwave.commands.sensorbinaryv2.SensorBinaryReport cmd) { motionEvent(cmd.sensorValue) } def zwaveEvent(physicalgraph.zwave.commands.basicv1.BasicSet cmd) { motionEvent(cmd.value) } def zwaveEvent(physicalgraph.zwave.commands.notificationv3.NotificationReport cmd) { if (cmd.notificationType == 7 && cmd.event == 7) { motionEvent(cmd.notificationStatus) } else { createEvent(descriptionText: cmd.toString(), isStateChange: false) } } def zwaveEvent(physicalgraph.zwave.Command cmd) { createEvent(descriptionText: cmd.toString(), isStateChange: false) } def configureAfterSecure() { //log.debug "Commands sent" def cmds = [] // send battery, temperature, humidity, and illuminance every 30 minutes cmds << zwave.configurationV1.configurationSet(scaledConfigurationValue: 225, parameterNumber: 101, size: 4) cmds << zwave.configurationV1.configurationSet(parameterNumber: 111, size: 4, scaledConfigurationValue: 30*60) // send no-motion report 60 seconds after motion stops cmds << zwave.configurationV1.configurationSet(parameterNumber: 3, size: 2, scaledConfigurationValue: 10) // send binary sensor report instead of basic set for motion cmds << zwave.configurationV1.configurationSet(parameterNumber: 5, size: 1, scaledConfigurationValue: 2) // Ensure that the Multisensor Gen5 PIR sensor is active cmds << zwave.configurationV1.configurationSet(parameterNumber: 4, size: 1, scaledConfigurationValue: 1) // disable notification-style motion events cmds << zwave.notificationV3.notificationSet(notificationType: 7, notificationStatus: 0) cmds << zwave.batteryV1.batteryGet() cmds << zwave.sensorBinaryV2.sensorBinaryGet(sensorType:0x0C) //commands(cmds) setConfigured() secureSequence(cmds) + ["delay 20000", zwave.wakeUpV1.wakeUpNoMoreInformation().format()] } private setConfigured() { device.updateDataValue("configured", "true") } private isConfigured() { device.getDataValue(["configured"]).toString() == "true" } private secure(physicalgraph.zwave.Command cmd) { zwave.securityV1.securityMessageEncapsulation().encapsulate(cmd).format() } private secureSequence(commands, delay=200) { delayBetween(commands.collect{ secure(it) }, delay) }