Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion devicetypes/smartthings/aeon-key-fob.src/aeon-key-fob.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,7 @@ def updated() {
def initialize() {

def results = []
def buttons = 1

if (zwaveInfo && zwaveInfo.mfr == "0086" && zwaveInfo.prod == "0001" && zwaveInfo.model == "0026") {
sendEvent(name: "checkInterval", value: 8 * 60 * 60 + 2 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID])
Expand All @@ -191,7 +192,7 @@ def initialize() {
} else {
// Device only goes OFFLINE when Hub is off
sendEvent(name: "DeviceWatch-Enroll", value: JsonOutput.toJson([protocol: "zwave", scheme:"untracked"]), displayed: false)
def buttons = 4 // Default for Key Fob
buttons = 4 // Default for Key Fob
}

sendEvent(name: "numberOfButtons", value: buttons)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ metadata {
}

def installed() {
if (zwaveInfo.zw && zwaveInfo.zw.cc?.contains("84")) {
if (zwaveInfo.cc?.contains("84")) {
response(zwave.wakeUpV1.wakeUpNoMoreInformation())
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ metadata {
fingerprint profileId: "0104", inClusters: "0000, 0004, 0003, 0006, 0008, 0005, FFFF, 1000", outClusters: "0019", manufacturer: "LDS", model: "ZBT-DIMLight-GLS0000", deviceJoinName: "A60 Dim Bulb"
fingerprint profileId: "0104", inClusters: "0000, 0003, 0004, 0005, 0006, 0008", outClusters: "0019", manufacturer: "LDS", model: "ZHA-DIMLight-GLS0000", deviceJoinName: "A60 Dim Bulb"
fingerprint profileId: "0104", inClusters: "0000, 0003, 0004, 0005, 0006, 0008, 1000", outClusters: "0019", manufacturer: "LDS", model: "ZBT-DIMLight-GLS", deviceJoinName: "A60 Dim Bulb"
fingerprint profileId: "0104", inClusters: "0000, 0003, 0004, 0005, 0006, 0008, 1000", outClusters: "0019", manufacturer: "LDS", model: "ZBT-DIMLight-GLS0044", deviceJoinName: "智能球泡灯(可调光版)"
fingerprint profileId: "0104", inClusters: "0000, 0003, 0004, 0005, 0006, 0008, 1000", outClusters: "0019", manufacturer: "LDS", model: "ZBT-DIMLight-GLS0044", deviceJoinName: "A60 Dim Bulb"
fingerprint profileId: "0104", inClusters: "0000, 0003, 0004, 0005, 0006, 0008, 0009", outClusters: "0019", manufacturer: "Aurora", model: "FWMPROZXBulb50AU", deviceJoinName: "Aurora MPro"
fingerprint profileId: "0104", inClusters: "0000, 0004, 0003, 0006, 0008, 0005, FFFF, 1000", outClusters: "0019", manufacturer: "Aurora", model: "FWBulb51AU", deviceJoinName: "Aurora Smart Dimmable"
fingerprint profileId: "0104", inClusters: "0000, 0003, 0004, 0005, 0006, 0008", outClusters: "0019", manufacturer: "Aurora", model: "FWStrip50AU", deviceJoinName: "Aurora Dimmable Strip Controller"
Expand All @@ -61,6 +61,7 @@ metadata {
fingerprint profileId: "0104", inClusters: "0000, 0003, 0004, 0005, 0006, 0008, 0702, 0B05", outClusters: "0019", manufacturer: "sengled", model: "E11-N13", deviceJoinName: "Sengled Element Classic"
fingerprint profileId: "0104", inClusters: "0000, 0003, 0004, 0005, 0006, 0008, 0702, 0B05", outClusters: "0019", manufacturer: "sengled", model: "E11-N14", deviceJoinName: "Sengled Element Classic"
fingerprint profileId: "0104", inClusters: "0000, 0003, 0004, 0005, 0006, 0008, 0B05, 1000, FEDC", outClusters: "000A, 0019", manufacturer: "LDS", model: "ZBT-DIMLight-GLS0006", deviceJoinName: "Smart Bulb"
fingerprint profileId: "0104", inClusters: "0000, 0003, 0004, 0005, 0006, 0008", outClusters: "0019", manufacturer: "Aurora", model: "WallDimmerMaster", deviceJoinName: "Aurora Smart Rotary Dimmer"
}

tiles(scale: 2) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
*
*/
metadata {
definition (name: "Zigbee Power Meter", namespace: "smartthings", author: "SmartThings") {
definition (name: "Zigbee Power Meter", namespace: "smartthings", author: "SmartThings", mnmn: "SmartThings", vid: "SmartThings-smartthings-Aeon_Home_Energy_Meter") {
capability "Energy Meter"
capability "Power Meter"
capability "Refresh"
Expand Down Expand Up @@ -105,5 +105,3 @@ def configure() {
zigbee.simpleMeteringPowerConfig() +
zigbee.electricMeasurementPowerConfig()
}


Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ metadata {
fingerprint profileId: "0104", inClusters: "0000, 0003, 0004, 0005, 0006, 0008, 0300, 0B05, FC01", outClusters: "0019", manufacturer: "LEDVANCE", model: "RT TW", deviceJoinName: "SYLVANIA Smart+ Adustable White RT5/6"

// Aurora/AOne
fingerprint profileId: "0104", inClusters: "0000, 0004, 0003, 0006, 0008, 0005, 0300, FFFF, FFFF, 1000", outClusters: "0019", manufacturer: "Aurora", model: "TWBulb51AU", deviceJoinName: "Aurora Smart Tunable White", mnmn: "SmartThings", vid: "generic-color-temperature-bulb-2200K-5000K"
fingerprint profileId: "0104", inClusters: "0000, 0004, 0003, 0006, 0008, 0005, 0300, FFFF, FFFF, 1000", outClusters: "0019", manufacturer: "Aurora", model: "TWBulb51AU", deviceJoinName: "Aurora Smart Tuneable White", mnmn: "SmartThings", vid: "generic-color-temperature-bulb-2200K-5000K"
fingerprint profileId: "0104", inClusters: "0000, 0003, 0004, 0005, 0006, 0008, 0300", outClusters: "0019", manufacturer: "Aurora", model: "TWMPROZXBulb50AU", deviceJoinName: "Aurora MPro Smart Tuneable LED", mnmn: "SmartThings", vid: "generic-color-temperature-bulb-2200K-5000K"
fingerprint profileId: "0104", inClusters: "0000, 0003, 0004, 0005, 0006, 0008, 0300", outClusters: "0019", manufacturer: "Aurora", model: "TWStrip50AU", deviceJoinName: "Aurora Tunable Strip Controller", mnmn: "SmartThings", vid: "generic-color-temperature-bulb-2200K-5000K"
fingerprint profileId: "0104", inClusters: "0000, 0003, 0004, 0005, 0006, 0008, 0300, 0B05, 1000, FEDC", outClusters: "0019, 000A", manufacturer: "Aurora", model: "TWGU10Bulb50AU", deviceJoinName: "Aurora GU10 Tuneable Smart Lamp", mnmn: "SmartThings", vid: "generic-color-temperature-bulb-2200K-5000K"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ metadata {
fingerprint mfr: "0063", prod: "4953", model: "3133", deviceJoinName: "GE Portable Smart Motion Sensor"
fingerprint mfr: "0214", prod: "0003", model: "0002", deviceJoinName: "BeSense Motion Detector"
fingerprint mfr: "027A", prod: "0001", model: "0005", deviceJoinName: "Zooz Outdoor Motion Sensor"
fingerprint mfr: "027A", prod: "0301", model: "0012", deviceJoinName: "Zooz Motion Sensor"
fingerprint mfr: "027A", prod: "0301", model: "0012", deviceJoinName: "Zooz Motion Sensor", mnmn: "SmartThings", vid: "generic-motion-2"
}

simulator {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
/**
* Z-Wave Multi Button
*
* Copyright 2019 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 Multi Button", namespace: "smartthings", author: "SmartThings", mnmn: "SmartThings", vid: "generic-6-button") {
capability "Button"
capability "Battery"
capability "Sensor"
capability "Health Check"
capability "Configuration"

/*
fingerprint mfr: "010F", prod: "1001", model: "1000", deviceJoinName: "Fibaro KeyFob" //EU
fingerprint mfr: "010F", prod: "1001", model: "2000", deviceJoinName: "Fibaro KeyFob" //US
*/
}

tiles(scale: 2) {
multiAttributeTile(name: "button", type: "generic", width: 6, height: 4, canChangeIcon: true) {
tileAttribute("device.button", key: "PRIMARY_CONTROL") {
attributeState "default", label: ' ', icon: "st.unknown.zwave.remote-controller", backgroundColor: "#ffffff"
}
}
valueTile("battery", "device.battery", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
state "battery", label:'${currentValue}% battery', unit:""
}

main "button"
details(["button", "battery"])
}
}

def installed() {
runIn(2, "initialize", [overwrite: true])
sendEvent(name: "button", value: "pushed", isStateChange: true)
}

def updated() {
runIn(2, "initialize", [overwrite: true])
}


def initialize() {
def numberOfButtons = prodNumberOfButtons[zwaveInfo.prod]
sendEvent(name: "numberOfButtons", value: numberOfButtons, displayed: false)
sendEvent(name: "checkInterval", value: 8 * 60 * 60 + 2 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID])
if(!childDevices) {
addChildButtons(numberOfButtons)
}
if(childDevices) {
def event
for(def endpoint : 2..prodNumberOfButtons[zwaveInfo.prod]) {
event = createEvent(name: "button", value: "pushed", isStateChange: true)
sendEventToChild(endpoint, event)
}
}
response([
secure(zwave.batteryV1.batteryGet()),
"delay 2000",
secure(zwave.wakeUpV1.wakeUpNoMoreInformation())
])
}

def configure() {
def cmds = []
for(def parameter : 21..26) {
cmds += secure(zwave.configurationV1.configurationSet(parameterNumber: parameter, scaledConfigurationValue: 15)) //Makes Fibaro KeyFob buttons send all kind of supported events
}
cmds
}

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 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.centralscenev1.CentralSceneNotification cmd) {
def value = eventsMap[(int) cmd.keyAttributes]
def description = "Button no. ${cmd.sceneNumber} was ${value}"
def event = createEvent(name: "button", value: value, descriptionText: description, data: [buttonNumber: cmd.sceneNumber], isStateChange: true)
if(cmd.sceneNumber == 1) {
return event
} else {
sendEventToChild(cmd.sceneNumber, event)
return createEvent(descriptionText: description)
}
}

def sendEventToChild(buttonNumber, event) {
String childDni = "${device.deviceNetworkId}:$buttonNumber"
def child = childDevices.find { it.deviceNetworkId == childDni }
child?.sendEvent(event)
}

def zwaveEvent(physicalgraph.zwave.commands.wakeupv1.WakeUpNotification cmd) {
def results = []
results += createEvent(descriptionText: "$device.displayName woke up", isStateChange: false)
results += response([
secure(zwave.batteryV1.batteryGet()),
"delay 2000",
secure(zwave.wakeUpV1.wakeUpNoMoreInformation())
])
results
}

def zwaveEvent(physicalgraph.zwave.commands.batteryv1.BatteryReport cmd) {
def map = [ name: "battery", unit: "%", isStateChange: true ]
state.lastbatt = now()
if (cmd.batteryLevel == 0xFF) {
map.value = 1
map.descriptionText = "$device.displayName battery is low!"
} else {
map.value = cmd.batteryLevel
}
createEvent(map)
}

def zwaveEvent(physicalgraph.zwave.Command cmd) {
log.warn "Unhandled command: ${cmd}"
}

private secure(cmd) {
if(zwaveInfo.zw.endsWith("s")) {
zwave.securityV1.securityMessageEncapsulation().encapsulate(cmd).format()
} else {
cmd.format()
}
}

private addChildButtons(numberOfButtons) {
for(def endpoint : 2..numberOfButtons) {
try {
String childDni = "${device.deviceNetworkId}:$endpoint"
def componentLabel = (device.displayName.endsWith(' 1') ? device.displayName[0..-2] : (device.displayName + " ")) + "${endpoint}"
addChildDevice("Child Button", childDni, device.getHub().getId(), [
completedSetup: true,
label : componentLabel,
isComponent : true,
componentName : "button$endpoint",
componentLabel: "Button $endpoint"
])
} catch(Exception e) {
log.debug "Exception: ${e}"
}
}
}

private getEventsMap() {[
0: "pushed",
1: "held",
//2: "down_hold",
3: "double",
//4: "pushed_3x"
]}

private getProdNumberOfButtons() {[
"1001" : 6
]}
14 changes: 12 additions & 2 deletions devicetypes/smartthings/zwave-siren.src/zwave-siren.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -363,7 +363,13 @@ def handleSwitchValue(value) {

def zwaveEvent(physicalgraph.zwave.commands.batteryv1.BatteryReport cmd) {
def map = [name: "battery", unit: "%"]
if (cmd.batteryLevel == 0xFF) {

// The Utilitech siren always sends low battery events (0xFF) below 20%,
// so we will ignore 0% events that sometimes seem to come before valid events.
if (cmd.batteryLevel == 0 && isUtilitech()) {
log.debug "Ignoring battery 0%"
return [:]
} else if (cmd.batteryLevel == 0xFF) {
map.value = 1
map.descriptionText = "$device.displayName has a low battery"
} else {
Expand Down Expand Up @@ -414,4 +420,8 @@ def isYale() {

def isZipato() {
(zwaveInfo?.mfr == "0131" && zwaveInfo?.prod == "0003" && zwaveInfo?.model == "1083")
}
}

def isUtilitech() {
(zwaveInfo?.mfr == "0060" && zwaveInfo?.prod == "000C" && zwaveInfo?.model == "0001")
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ metadata {
fingerprint deviceId: "0x1006", inClusters: "0x25"
fingerprint mfr: "0173", prod: "0003", model: "0002", deviceJoinName: "Leak Intelligence Leak Gopher Water Shutoff Valve"
fingerprint mfr: "021F", prod: "0003", model: "0002", deviceJoinName: "Dome Water Main Shut-off"
fingerprint mfr: "0157", prod: "0003", model: "0002", deviceJoinName: "EcoNet Bulldog Valve Robot"
}

// simulator metadata
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,13 @@ metadata {
simulator { }

preferences {
input("heatdetails", "enum", title: "Do you want a detailed operating state notification?", options: ["No", "Yes"], defaultValue: "No", required: true, displayDuringSetup: true)
input("zipcode", "text", title: "ZipCode (Outdoor Temperature)", description: "[Do not use space](Blank = No Forecast)")
section {
input("heatdetails", "enum", title: "Do you want a detailed operating state notification?", options: ["No", "Yes"], defaultValue: "No", required: true, displayDuringSetup: true)
}
section {
input title: "Outdoor Temperature", description: "To get the current outdoor temperature to display on your thermostat enter your zip code or postal code below and make sure that your SmartThings location has a Geolocation configured (typically used for geofencing).", displayDuringSetup: false, type: "paragraph", element: "paragraph"
input("zipcode", "text", title: "ZipCode (Outdoor Temperature)", description: "[Do not use space](Blank = No Forecast)")
}
}

tiles(scale : 2) {
Expand Down Expand Up @@ -161,6 +166,7 @@ def updated() {

unschedule(scheduledUpdateWeather)
if (settings.zipcode) {
state.invalidZip = false // Reset and validate the zip-code later
runEvery1Hour(scheduledUpdateWeather)
scheduledUpdateWeather()
}
Expand Down Expand Up @@ -208,21 +214,42 @@ def updateWeather() {
// If there is a zipcode defined, weather forecast will be sent. Otherwise, no weather forecast.
if (settings.zipcode) {
log.debug "ZipCode: ${settings.zipcode}"
weather = getTwcConditions(settings.zipcode)
try {
// If we do not have a zip-code setting we've determined as invalid, try to use the zip-code defined.
if (!state.invalidZip) {
weather = getTwcConditions(settings.zipcode)
}
} catch (e) {
log.debug "getTwcConditions exception: $e"
// There was a problem obtaining the weather with this zip-code, so fall back to the hub's location and note this for future runs.
state.invalidZip = true
}

// Check if the variable is populated, otherwise return.
if (!weather) {
log.debug("Something went wrong, no data found.")
return false
try {
// It is possible that a non-U.S. zip-code was used, so try with the location's lat/lon.
if (location?.latitude && location?.longitude) {
// Restrict to two decimal places for the API
weather = getTwcConditions(sprintf("%.2f,%.2f", location.latitude, location.longitude))
}
} catch (e2) {
log.debug "getTwcConditions exception: $e2"
weather = null
}
}

def locationScale = getTemperatureScale()
def tempToSend = weather.temperature
log.debug("Outdoor Temperature: ${tempToSend} ${locationScale}")
// Right now this can disrupt device health if the device is
// currently offline -- it would be erroneously marked online.
//sendEvent(name: 'outsideTemp', value: tempToSend)
setOutdoorTemperature(tempToSend)
// Either the location lat,lon was invalid or one was not defined for the location, on top of an error with the given zip-code
if (!weather) {
log.debug("Something went wrong, no data found.")
} else {
def locationScale = getTemperatureScale()
def tempToSend = weather.temperature
log.debug("Outdoor Temperature: ${tempToSend} ${locationScale}")
// Right now this can disrupt device health if the device is
// currently offline -- it would be erroneously marked online.
//sendEvent( name: 'outsideTemp', value: tempToSend )
setOutdoorTemperature(tempToSend)
}
}
}

Expand Down Expand Up @@ -387,6 +414,7 @@ def refresh() {
def configure() {
unschedule(scheduledUpdateWeather)
if (settings.zipcode) {
state.invalidZip = false // Reset and validate the zip-code later
runEvery1Hour(scheduledUpdateWeather)
}
poll()
Expand Down
Loading