Compare commits

..

1 Commits

6 changed files with 189 additions and 158 deletions

View File

@@ -21,7 +21,6 @@ metadata {
attribute "tamper", "enum", ["detected", "clear"]
attribute "heatAlarm", "enum", ["overheat detected", "clear", "rapid temperature rise", "underheat detected"]
fingerprint deviceId: "0x0701", inClusters: "0x5E, 0x86, 0x72, 0x5A, 0x59, 0x85, 0x73, 0x84, 0x80, 0x71, 0x56, 0x70, 0x31, 0x8E, 0x22, 0x9C, 0x98, 0x7A", outClusters: "0x20, 0x8B"
fingerprint mfr:"010F", prod:"0C02", model:"1002"
}
simulator {
//battery

View File

@@ -1,2 +0,0 @@
.st-ignore
README.md

View File

@@ -1,30 +0,0 @@
# Smartsense Motion Sensor
Works with:
* [Samsung SmartThings Motion Sensor](https://shop.smartthings.com/#!/products/samsung-smartthings-motion-sensor)
## Table of contents
* [Capabilities](#capabilities)
* [Health]($health)
## Capabilities
* **Configuration** - _configure()_ command called when device is installed or device preferences updated
* **Motion Sensor** - can detect motion
* **Battery** - defines device uses a battery
* **Refresh** - _refresh()_ command for status updates
* **Health Check** - indicates ability to get device health notifications
## Device Health
A Category C2 motion sensor that has 120min check-in interval

View File

@@ -1,50 +0,0 @@
/**
* 이혜진
*
* Copyright 2016 Leehyejin
*
* 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: "이혜진",
namespace: "이혜진",
author: "Leehyejin",
description: "test",
category: "",
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")
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

@@ -0,0 +1,170 @@
/**
* Lights Flash on Door Knock
*
* Copyright 2016 Andrew Cornforth
*
* 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: "Lights Flash on Door Knock",
namespace: "com.stormwave.doorknock",
author: "Andrew Cornforth",
description: "Flashes lights when activity is noticed at the door.",
category: "Safety & Security",
iconUrl: "http://cdn.device-icons.smartthings.com/Lighting/light10-icn.png",
iconX2Url: "http://cdn.device-icons.smartthings.com/Lighting/light10-icn@2x.png",
iconX3Url: "http://cdn.device-icons.smartthings.com/Lighting/light10-icn@2x.png")
preferences {
section("Things")
{
input "doorsensor", "capability.accelerationSensor", title: "Door Sensor", required: true, multiple: true
input "lights", "capability.switch", title:"Lights", required:true, multiple:true
}
section("Settings")
{
input "numFlashes", "number", title:"Number of Flashes", required:true, defaultValue:"5"
input "onFor", "number", title:"Time On (ms)", required:true, defaultValue:"1000"
input "offFor", "number", title:"Time Off (ms)", required:true, defaultValue:"1000"
}
section("Only If")
{
input "switcheson", "capability.switch", title:"Switches Are On", required:false, multiple:true
input "switchesoff", "capability.switch", title:"Switches Are Off", required:false, multiple:true
input "sleepon", "capability.sleepSensor", title:"Thing Is Asleep", required:false, multiple:true
input "sleepoff", "capability.sleepSensor", title:"Thing Is Awake", required:false, multiple:true
}
section("Or If")
{
input "or_switcheson", "capability.switch", title:"Switches Are On", required:false, multiple:true
input "or_switchesoff", "capability.switch", title:"Switches Are Off", required:false, multiple:true
input "or_sleepon", "capability.sleepSensor", title:"Thing Is Asleep", required:false, multiple:true
input "or_sleepoff", "capability.sleepSensor", title:"Thing Is Awake", required:false, multiple:true
}
}
def flashLights()
{
lights.each
{
light ->
def delay = 0L
if (light.latestValue("switch")=="on")
{
numFlashes.times
{
light.off(delay: delay)
delay += offFor
light.on(delay: delay)
delay += onFor
}
}
else
{
numFlashes.times
{
light.on(delay: delay)
delay += onFor
light.off(delay: delay)
delay += offFor
}
}
}
}
def installed() {
log.debug "Installed with settings: ${settings}"
initialize()
}
def updated() {
log.debug "Updated with settings: ${settings}"
unsubscribe()
initialize()
}
def unsubcribe()
{
unsubscribe(doorsensor)
}
def initialize()
{
subscribe(doorsensor, "acceleration", activityHandler)
}
def activityHandler(evt)
{
if (evt.value=="active")
{
// Check conditions
def valid = true
switcheson.each
{
device ->
if (device.latestValue("switch")=="off") { valid = false; }
}
if (valid)
switchesoff.each
{
device ->
if (device.latestValue("switch")=="on") { valid = false; }
}
if (valid)
sleepon.each
{
device ->
if (device.latestValue("sleeping")=="not sleeping") { valid = false; }
}
if (valid)
sleepoff.each
{
device ->
if (device.latestValue("sleeping")=="sleeping") { valid = false; }
}
// Check for "or" values if failed first step
if (!valid)
{
valid = true
or_switcheson.each
{
device ->
if (device.latestValue("switch")=="off") { valid = false; }
}
if (valid)
or_switchesoff.each
{
device ->
if (device.latestValue("switch")=="on") { valid = false; }
}
if (valid)
or_sleepon.each
{
device ->
if (device.latestValue("sleeping")=="not sleeping") { valid = false; }
}
if (valid)
or_sleepoff.each
{
device ->
if (device.latestValue("sleeping")=="sleeping") { valid = false; }
}
}
if (valid)
{
flashLights()
}
}
}

View File

@@ -107,8 +107,8 @@ mappings {
path("/locks") {
action: [
GET: "listLocks",
PUT: "updateLocks",
POST: "updateLocks"
PUT: "updateLock",
POST: "updateLock"
]
}
path("/locks/:id") {
@@ -442,87 +442,31 @@ def executePhrase() {
}
private void updateAll(devices) {
def type = params.param1
def command = request.JSON?.command
if (!devices) {
httpError(404, "Devices not found")
}
if (command){
devices.each { device ->
executeCommand(device, type, command)
}
if (command)
{
command = command.toLowerCase()
devices."$command"()
}
}
private void update(devices) {
log.debug "update, request: ${request.JSON}, params: ${params}, devices: $devices.id"
def type = params.param1
def command = request.JSON?.command
def device = devices?.find { it.id == params.id }
if (!device) {
//def command = request.JSON?.command
def command = params.command
if (command)
{
command = command.toLowerCase()
def device = devices.find { it.id == params.id }
if (!device)
{
httpError(404, "Device not found")
}
else
{
device."$command"()
}
}
if (command) {
executeCommand(device, type, command)
}
}
/**
* Validating the command passed by the user based on capability.
* @return boolean
*/
def validateCommand(device, deviceType, command) {
def capabilityCommands = getDeviceCapabilityCommands(device.capabilities)
def currentDeviceCapability = getCapabilityName(deviceType)
if (capabilityCommands[currentDeviceCapability]) {
return command in capabilityCommands[currentDeviceCapability] ? true : false
} else {
// Handling other device types here, which don't accept commands
httpError(400, "Bad request.")
}
}
/**
* Need to get the attribute name to do the lookup. Only
* doing it for the device types which accept commands
* @return attribute name of the device type
*/
def getCapabilityName(type) {
switch(type) {
case "switches":
return "Switch"
case "locks":
return "Lock"
default:
return type
}
}
/**
* Constructing the map over here of
* supported commands by device capability
* @return a map of device capability -> supported commands
*/
def getDeviceCapabilityCommands(deviceCapabilities) {
def map = [:]
deviceCapabilities.collect {
map[it.name] = it.commands.collect{ it.name.toString() }
}
return map
}
/**
* Validates and executes the command
* on the device or devices
*/
def executeCommand(device, type, command) {
if (validateCommand(device, type, command)) {
device."$command"()
} else {
httpError(403, "Access denied. This command is not supported by current capability.")
}
}
private show(devices, type) {