Compare commits

..

1 Commits

Author SHA1 Message Date
Andres
11501f4c31 MSA-1792: Hi smartthings team,
We  made the handler with tamper and motion alarm and we update the fingerprint for our hardware Besense.
Regards,
Andres.
2017-02-17 21:11:06 -08:00
13 changed files with 264 additions and 180 deletions

View File

@@ -0,0 +1,145 @@
/**
*
*
* BeSense Z-Wave Motion Sensor
*
*
*/
metadata {
definition (name: "BeSense Motion Sensor", namespace: "BeSense Sensors", author: "BeSense") {
capability "Motion Sensor"
capability "Sensor"
capability "Battery"
capability "Tamper Alert"
fingerprint mfr: "0214", prod: "0002", model: "0002", deviceJoinName: "Besense Motion Sensor" // Besense motion sensor
}
simulator {
status "inactive": "command: 3003, payload: 00"
status "active": "command: 3003, payload: FF"
}
tiles(scale: 1) {
standardTile("motion", "device.motion", width: 3, height: 3, canChangeIcon: true) {
state("active", label:'motion', icon:"st.motion.motion.active", backgroundColor:"#ea0f46", nextState:"inactive")
state("inactive", label:'no motion', icon:"st.motion.motion.inactive", backgroundColor:"#27CC73", nextState:"active")
}
valueTile("battery", "device.battery", inactiveLabel: false, decoration: "flat") {
state("battery", label:'${currentValue}% battery', unit:"")
}
main "motion"
details(["motion", "battery", "tamper"])
}
}
def parse(String description) {
def result = null
if (description.startsWith("Err")) {
result = createEvent(descriptionText:description)
} else {
def cmd = zwave.parse(description, [0x20: 1, 0x30:1, 0x80: 1, 0x84: 1, 0x71: 6, 0x9C: 1])
if (cmd) {
result = zwaveEvent(cmd)
} else {
result = createEvent(value: description, descriptionText: description, isStateChange: false)
}
}
return result
}
def zwaveEvent(physicalgraph.zwave.commands.alarmv2.AlarmReport cmd)
{
def map = [:]
map.name = "tamper"
map.value = cmd.alarmLevel == 255 ? "tampered" : "secured"
if (map.value == "tampered") {
map.value = "tampered"
map.descriptionText = "$device.displayName has been tampered with"
map.isStateChange = "true"
map.display = "true"
log.debug "tampered: $map"
}
else {
map.value = "secured"
map.descriptionText = "$device.displayName is secured"
map.isStateChange = "true"
map.display = "true"
log.debug "secure: $map"
}
createEvent(map)
}
def sensorValueEvent(value) {
if (value) {
createEvent(name: "motion", value: "active", descriptionText: "$device.displayName detected motion")
} else {
createEvent(name: "motion", value: "inactive", descriptionText: "$device.displayName motion has stopped")
}
}
def zwaveEvent(physicalgraph.zwave.commands.basicv1.BasicReport cmd)
{
sensorValueEvent(cmd.value)
}
def zwaveEvent(physicalgraph.zwave.commands.basicv1.BasicSet cmd)
{
sensorValueEvent(cmd.value)
}
def zwaveEvent(physicalgraph.zwave.commands.switchbinaryv1.SwitchBinaryReport cmd)
{
sensorValueEvent(cmd.value)
}
def zwaveEvent(physicalgraph.zwave.commands.sensorbinaryv1.SensorBinaryReport cmd)
{
sensorValueEvent(cmd.sensorValue)
}
def zwaveEvent(physicalgraph.zwave.commands.sensoralarmv1.SensorAlarmReport cmd)
{
sensorValueEvent(cmd.sensorState)
}
def zwaveEvent(physicalgraph.zwave.commands.wakeupv1.WakeUpNotification cmd)
{
def result = [createEvent(descriptionText: "${device.displayName} woke up", isStateChange: false)]
if (!state.lastbat || (new Date().time) - state.lastbat > 53*60*60*1000) {
result << response(zwave.batteryV1.batteryGet())
} else {
result << response(zwave.wakeUpV1.wakeUpNoMoreInformation())
}
result
}
def zwaveEvent(physicalgraph.zwave.commands.batteryv1.BatteryReport cmd) {
def map = [ name: "battery", unit: "%" ]
if (cmd.batteryLevel == 0xFF) {
map.value = 1
map.descriptionText = "${device.displayName} has a low battery"
map.isStateChange = true
} else {
map.value = cmd.batteryLevel
}
state.lastbat = new Date().time
[createEvent(map), response(zwave.wakeUpV1.wakeUpNoMoreInformation())]
}

View File

@@ -58,7 +58,7 @@ metadata {
}
void installed() {
sendEvent(name: "DeviceWatch-Enroll", value: "{\"protocol\": \"LAN\", \"scheme\":\"untracked\", \"hubHardwareId\": \"${device.hub.hardwareID}\"}", displayed: false)
sendEvent(name: "DeviceWatch-Enroll", value: "{\"protocol\": \"LAN\", \"scheme\":\"untracked\", \"hubHardwareId\": \"${device.hub.hardwareID}\"}")
}
// parse events into attributes

View File

@@ -7,7 +7,6 @@
metadata {
// Automatically generated. Make future change here.
definition (name: "Hue Bridge", namespace: "smartthings", author: "SmartThings") {
capability "Bridge"
capability "Health Check"
attribute "networkAddress", "string"
@@ -46,7 +45,7 @@ metadata {
}
void installed() {
sendEvent(name: "DeviceWatch-Enroll", value: "{\"protocol\": \"LAN\", \"scheme\":\"untracked\", \"hubHardwareId\": \"${device.hub.hardwareID}\"}", displayed: false)
sendEvent(name: "DeviceWatch-Enroll", value: "{\"protocol\": \"LAN\", \"scheme\":\"untracked\", \"hubHardwareId\": \"${device.hub.hardwareID}\"}")
}
// parse events into attributes

View File

@@ -67,7 +67,7 @@ metadata {
}
void installed() {
sendEvent(name: "DeviceWatch-Enroll", value: "{\"protocol\": \"LAN\", \"scheme\":\"untracked\", \"hubHardwareId\": \"${device.hub.hardwareID}\"}", displayed: false)
sendEvent(name: "DeviceWatch-Enroll", value: "{\"protocol\": \"LAN\", \"scheme\":\"untracked\", \"hubHardwareId\": \"${device.hub.hardwareID}\"}")
}
// parse events into attributes

View File

@@ -51,7 +51,7 @@ metadata {
}
void installed() {
sendEvent(name: "DeviceWatch-Enroll", value: "{\"protocol\": \"LAN\", \"scheme\":\"untracked\", \"hubHardwareId\": \"${device.hub.hardwareID}\"}", displayed: false)
sendEvent(name: "DeviceWatch-Enroll", value: "{\"protocol\": \"LAN\", \"scheme\":\"untracked\", \"hubHardwareId\": \"${device.hub.hardwareID}\"}")
}
// parse events into attributes

View File

@@ -56,7 +56,7 @@ metadata {
}
void installed() {
sendEvent(name: "DeviceWatch-Enroll", value: "{\"protocol\": \"LAN\", \"scheme\":\"untracked\", \"hubHardwareId\": \"${device.hub.hardwareID}\"}", displayed: false)
sendEvent(name: "DeviceWatch-Enroll", value: "{\"protocol\": \"LAN\", \"scheme\":\"untracked\", \"hubHardwareId\": \"${device.hub.hardwareID}\"}")
}
// parse events into attributes

View File

@@ -24,7 +24,6 @@ metadata {
capability "Refresh"
capability "Actuator"
capability "Sensor"
capability "Outlet"
fingerprint profileId: "0104", inClusters: "0000,0003,0004,0005,0006,0008,0B04,0B05", outClusters: "0019", manufacturer: "CentraLite", model: "4257050-ZHAC"
@@ -80,8 +79,7 @@ def parse(String description) {
*/
event.value = event.value / 10
}
return event ? createEvent(event) : event
return event
}
def setLevel(value) {

View File

@@ -4,7 +4,6 @@ metadata {
capability "Actuator"
capability "Switch"
capability "Sensor"
capability "Outlet"
fingerprint profileId: "0104", inClusters: "0006, 0004, 0003, 0000, 0005", outClusters: "0019", manufacturer: "Compacta International, Ltd", model: "ZBMPlug15", deviceJoinName: "SmartPower Outlet V1"
}

View File

@@ -83,8 +83,9 @@ def parse(String description) {
if (event) {
if (event.name == "power") {
def value = (event.value as Integer) / 10
event = createEvent(name: event.name, value: value, descriptionText: '{{ device.displayName }} power is {{ value }} Watts', translatable: true)
event.value = event.value / 10
event.descriptionText = '{{ device.displayName }} power is {{ value }} Watts'
event.translatable = true
} else if (event.name == "switch") {
def descriptionText = event.value == "on" ? '{{ device.displayName }} is On' : '{{ device.displayName }} is Off'
event = createEvent(name: event.name, value: event.value, descriptionText: descriptionText, translatable: true)
@@ -105,7 +106,7 @@ def parse(String description) {
log.debug "${cluster}"
}
}
return event ? createEvent(event) : event
return event
}
def off() {

View File

@@ -1,71 +1,71 @@
/**
* Simulated Alarm
*
* Copyright 2014 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: "Simulated Alarm", namespace: "smartthings/testing", author: "SmartThings") {
capability "Alarm"
capability "Sensor"
capability "Actuator"
}
simulator {
// reply messages
["strobe","siren","both","off"].each {
reply "$it": "alarm:$it"
}
}
tiles {
standardTile("alarm", "device.alarm", width: 2, height: 2) {
state "off", label:'off', action:'alarm.both', icon:"st.alarm.alarm.alarm", backgroundColor:"#ffffff"
state "strobe", label:'strobe!', action:'alarm.off', icon:"st.alarm.alarm.alarm", backgroundColor:"#e86d13"
state "siren", label:'siren!', action:'alarm.off', icon:"st.alarm.alarm.alarm", backgroundColor:"#e86d13"
state "both", label:'alarm!', action:'alarm.off', icon:"st.alarm.alarm.alarm", backgroundColor:"#e86d13"
}
standardTile("strobe", "device.alarm", inactiveLabel: false, decoration: "flat") {
state "default", label:'', action:"alarm.strobe", icon:"st.secondary.strobe", backgroundColor:"#cccccc"
}
standardTile("siren", "device.alarm", inactiveLabel: false, decoration: "flat") {
state "default", label:'', action:"alarm.siren", icon:"st.secondary.siren", backgroundColor:"#cccccc"
}
standardTile("off", "device.alarm", inactiveLabel: false, decoration: "flat") {
state "default", label:'', action:"alarm.off", icon:"st.secondary.off"
}
main "alarm"
details(["alarm","strobe","siren","test","off"])
}
}
def strobe() {
sendEvent(name: "alarm", value: "strobe")
}
def siren() {
sendEvent(name: "alarm", value: "siren")
}
def both() {
sendEvent(name: "alarm", value: "both")
}
def off() {
sendEvent(name: "alarm", value: "off")
}
// Parse incoming device messages to generate events
def parse(String description) {
def pair = description.split(":")
createEvent(name: pair[0].trim(), value: pair[1].trim())
}
/**
* Simulated Alarm
*
* Copyright 2014 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: "Simulated Alarm", namespace: "smartthings/testing", author: "SmartThings") {
capability "Alarm"
capability "Sensor"
capability "Actuator"
}
simulator {
// reply messages
["strobe","siren","both","off"].each {
reply "$it": "alarm:$it"
}
}
tiles {
standardTile("alarm", "device.alarm", width: 2, height: 2) {
state "off", label:'off', action:'alarm.both', icon:"st.alarm.alarm.alarm", backgroundColor:"#ffffff"
state "strobe", label:'strobe!', action:'alarm.off', icon:"st.alarm.alarm.alarm", backgroundColor:"#e86d13"
state "siren", label:'siren!', action:'alarm.off', icon:"st.alarm.alarm.alarm", backgroundColor:"#e86d13"
state "both", label:'alarm!', action:'alarm.off', icon:"st.alarm.alarm.alarm", backgroundColor:"#e86d13"
}
standardTile("strobe", "device.alarm", inactiveLabel: false, decoration: "flat") {
state "default", label:'', action:"alarm.strobe", icon:"st.secondary.strobe", backgroundColor:"#cccccc"
}
standardTile("siren", "device.alarm", inactiveLabel: false, decoration: "flat") {
state "default", label:'', action:"alarm.siren", icon:"st.secondary.siren", backgroundColor:"#cccccc"
}
standardTile("off", "device.alarm", inactiveLabel: false, decoration: "flat") {
state "default", label:'', action:"alarm.off", icon:"st.secondary.off"
}
main "alarm"
details(["alarm","strobe","siren","test","off"])
}
}
def strobe() {
sendEvent(name: "alarm", value: "strobe")
}
def siren() {
sendEvent(name: "alarm", value: "siren")
}
def both() {
sendEvent(name: "alarm", value: "both")
}
def off() {
sendEvent(name: "alarm", value: "off")
}
// Parse incoming device messages to generate events
def parse(String description) {
def pair = description.split(":")
createEvent(name: pair[0].trim(), value: pair[1].trim())
}

View File

@@ -1,51 +0,0 @@
/**
* jefferson
*
* Copyright 2017 Jaeguk Yun
*
* 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.
*
*/
definition(
name: "jefferson",
namespace: "jefferson",
author: "Jaeguk Yun",
description: "Jaeguk Yun",
category: "Green Living",
iconUrl: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience.png",
iconX2Url: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience@2x.png",
iconX3Url: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience@2x.png",
oauth: true)
preferences {
section("Title") {
// TODO: put inputs here
}
}
def installed() {
log.debug "Installed with settings: ${settings}"
initialize()
}
def updated() {
log.debug "Updated with settings: ${settings}"
unsubscribe()
initialize()
}
def initialize() {
// TODO: subscribe to attributes, devices, locations, etc.
}
// TODO: implement event handlers

View File

@@ -17,14 +17,14 @@
*/
definition(
name: "Hue (Connect)",
namespace: "smartthings",
author: "SmartThings",
description: "Allows you to connect your Philips Hue lights with SmartThings and control them from your Things area or Dashboard in the SmartThings Mobile app. Adjust colors by going to the Thing detail screen for your Hue lights (tap the gear on Hue tiles).\n\nPlease update your Hue Bridge first, outside of the SmartThings app, using the Philips Hue app.",
category: "SmartThings Labs",
iconUrl: "https://s3.amazonaws.com/smartapp-icons/Partner/hue.png",
iconX2Url: "https://s3.amazonaws.com/smartapp-icons/Partner/hue@2x.png",
singleInstance: true
name: "Hue (Connect)",
namespace: "smartthings",
author: "SmartThings",
description: "Allows you to connect your Philips Hue lights with SmartThings and control them from your Things area or Dashboard in the SmartThings Mobile app. Adjust colors by going to the Thing detail screen for your Hue lights (tap the gear on Hue tiles).\n\nPlease update your Hue Bridge first, outside of the SmartThings app, using the Philips Hue app.",
category: "SmartThings Labs",
iconUrl: "https://s3.amazonaws.com/smartapp-icons/Partner/hue.png",
iconX2Url: "https://s3.amazonaws.com/smartapp-icons/Partner/hue@2x.png",
singleInstance: true
)
preferences {
@@ -85,8 +85,7 @@ def bridgeDiscovery(params=[:])
}
return dynamicPage(name:"bridgeDiscovery", title:"Discovery Started!", nextPage:"bridgeBtnPush", refreshInterval:refreshInterval, uninstall: true) {
section("Please wait while we discover your Hue Bridge. Kindly note that you must first configure your Hue Bridge and Lights using the Philips Hue application. " +
"Discovery can take five minutes or more, so sit back and relax! Select your device below once discovered.") {
section("Please wait while we discover your Hue Bridge. Discovery can take five minutes or more, so sit back and relax! Select your device below once discovered.") {
input "selectedHue", "enum", required:false, title:"Select Hue Bridge (${numFound} found)", multiple:false, options:options, submitOnChange: true
}
}
@@ -179,7 +178,7 @@ def bulbDiscovery() {
}
if (bulbRefreshCount > 200 && numFound == 0) {
// Time out after 10 minutes
// Time out to avoid endless discovery
state.inBulbDiscovery = false
bulbRefreshCount = 0
return dynamicPage(name:"bulbDiscovery", title:"Light Discovery Failed!", nextPage:"", refreshInterval:0, install:true, uninstall: true) {
@@ -217,32 +216,32 @@ private sendDeveloperReq() {
def token = app.id
def host = getBridgeIP()
sendHubCommand(new physicalgraph.device.HubAction([
method: "POST",
path: "/api",
headers: [
HOST: host
],
body: [devicetype: "$token-0"]], "${selectedHue}", [callback: "usernameHandler"]))
method: "POST",
path: "/api",
headers: [
HOST: host
],
body: [devicetype: "$token-0"]], "${selectedHue}", [callback: "usernameHandler"]))
}
private discoverHueBulbs() {
def host = getBridgeIP()
sendHubCommand(new physicalgraph.device.HubAction([
method: "GET",
path: "/api/${state.username}/lights",
headers: [
HOST: host
]], "${selectedHue}", [callback: "lightsHandler"]))
method: "GET",
path: "/api/${state.username}/lights",
headers: [
HOST: host
]], "${selectedHue}", [callback: "lightsHandler"]))
}
private verifyHueBridge(String deviceNetworkId, String host) {
log.trace "Verify Hue Bridge $deviceNetworkId"
sendHubCommand(new physicalgraph.device.HubAction([
method: "GET",
path: "/description.xml",
headers: [
HOST: host
]], deviceNetworkId, [callback: "bridgeDescriptionHandler"]))
method: "GET",
path: "/description.xml",
headers: [
HOST: host
]], deviceNetworkId, [callback: "bridgeDescriptionHandler"]))
}
private verifyHueBridges() {
@@ -400,7 +399,7 @@ def addBulbs() {
log.debug "$dni in not longer paired to the Hue Bridge or ID changed"
}
} else {
//backwards compatable
//backwards compatable
newHueBulb = bulbs.find { (app.id + "/" + it.id) == dni }
d = addChildBulb(dni, "Extended Color Light", newHueBulb?.value?.name, newHueBulb?.value?.hub)
d?.completedSetup = true
@@ -1152,7 +1151,7 @@ def setColorTemperature(childDevice, huesettings) {
def ct = hueSettings == 6500 ? 153 : Math.round(1000000/huesettings)
createSwitchEvent(childDevice, "on")
put("lights/$id/state", [ct: ct, on: true])
return "Setting color temperature to $ct"
return "Setting color temperature to $percent"
}
def setColor(childDevice, huesettings) {
@@ -1227,7 +1226,7 @@ private poll() {
def uri = "/api/${state.username}/lights/"
log.debug "GET: $host$uri"
sendHubCommand(new physicalgraph.device.HubAction("GET ${uri} HTTP/1.1\r\n" +
"HOST: ${host}\r\n\r\n", physicalgraph.device.Protocol.LAN, selectedHue))
"HOST: ${host}\r\n\r\n", physicalgraph.device.Protocol.LAN, selectedHue))
}
private isOnline(id) {
@@ -1244,10 +1243,10 @@ private put(path, body) {
log.debug "BODY: ${bodyJSON}"
sendHubCommand(new physicalgraph.device.HubAction("PUT $uri HTTP/1.1\r\n" +
"HOST: ${host}\r\n" +
"Content-Length: ${length}\r\n" +
"\r\n" +
"${bodyJSON}", physicalgraph.device.Protocol.LAN, "${selectedHue}"))
"HOST: ${host}\r\n" +
"Content-Length: ${length}\r\n" +
"\r\n" +
"${bodyJSON}", physicalgraph.device.Protocol.LAN, "${selectedHue}"))
}
/*

View File

@@ -346,7 +346,7 @@ def devicesList(selector = '') {
if (resp.status == 200) {
return resp.data
} else {
log.debug("No response from device list call. ${resp.status} ${resp.data}")
log.error("Non-200 from device list call. ${resp.status} ${resp.data}")
return []
}
}
@@ -418,15 +418,9 @@ def updateDevices() {
}
getChildDevices().findAll { !selectors.contains("${it.deviceNetworkId}") }.each {
log.info("Deleting ${it.deviceNetworkId}")
if (state.devices[it.deviceNetworkId])
state.devices[it.deviceNetworkId] = null
// The reason the implementation is trying to delete this bulb is because it is not longer connected to the LIFX location.
// Adding "try" will prevent this exception from happening.
// Ideally device health would show to the user that the device is not longer accessible so that the user can either force delete it or remove it from the SmartApp.
try {
deleteChildDevice(it.deviceNetworkId)
} catch (Exception e) {
log.debug("Can't remove this device because it's being used by an SmartApp")
}
state.devices[it.deviceNetworkId] = null
deleteChildDevice(it.deviceNetworkId)
}
}