Compare commits

..

1 Commits

Author SHA1 Message Date
임희진
42ca77e223 MSA-939: test1 2016-03-09 03:06:47 -06:00
4 changed files with 303 additions and 242 deletions

View File

@@ -1,97 +1,112 @@
/** /**
* Hue Lux Bulb * Hue Lux Bulb
* *
* Author: SmartThings * Author: SmartThings
*/ */
// for the UI // for the UI
metadata { metadata {
// Automatically generated. Make future change here. // Automatically generated. Make future change here.
definition (name: "Hue Lux Bulb", namespace: "smartthings", author: "SmartThings") { definition (name: "Hue Lux Bulb", namespace: "smartthings", author: "SmartThings") {
capability "Switch Level" capability "Switch Level"
capability "Actuator" capability "Actuator"
capability "Color Temperature" capability "Color Temperature"
capability "Switch" capability "Switch"
capability "Refresh" capability "Refresh"
capability "Sensor" capability "Sensor"
command "refresh" command "refresh"
} }
simulator { simulator {
// TODO: define status and reply messages here // TODO: define status and reply messages here
} }
tiles(scale: 2) { tiles(scale: 2) {
multiAttributeTile(name:"rich-control", type: "lighting", canChangeIcon: true){ multiAttributeTile(name:"rich-control", type: "lighting", canChangeIcon: true){
tileAttribute ("device.switch", key: "PRIMARY_CONTROL") { tileAttribute ("device.switch", key: "PRIMARY_CONTROL") {
attributeState "on", label:'${name}', action:"switch.off", icon:"st.lights.philips.hue-single", backgroundColor:"#79b821", nextState:"turningOff" attributeState "on", label:'${name}', action:"switch.off", icon:"st.lights.philips.hue-single", backgroundColor:"#79b821", nextState:"turningOff"
attributeState "off", label:'${name}', action:"switch.on", icon:"st.lights.philips.hue-single", backgroundColor:"#ffffff", nextState:"turningOn" attributeState "off", label:'${name}', action:"switch.on", icon:"st.lights.philips.hue-single", backgroundColor:"#ffffff", nextState:"turningOn"
attributeState "turningOn", label:'${name}', action:"switch.off", icon:"st.lights.philips.hue-single", backgroundColor:"#79b821", nextState:"turningOff" attributeState "turningOn", label:'${name}', action:"switch.off", icon:"st.lights.philips.hue-single", backgroundColor:"#79b821", nextState:"turningOff"
attributeState "turningOff", label:'${name}', action:"switch.on", icon:"st.lights.philips.hue-single", backgroundColor:"#ffffff", nextState:"turningOn" attributeState "turningOff", label:'${name}', action:"switch.on", icon:"st.lights.philips.hue-single", backgroundColor:"#ffffff", nextState:"turningOn"
} }
tileAttribute ("device.level", key: "SLIDER_CONTROL") { tileAttribute ("device.level", key: "SLIDER_CONTROL") {
attributeState "level", action:"switch level.setLevel", range:"(0..100)" attributeState "level", action:"switch level.setLevel", range:"(0..100)"
} }
tileAttribute ("device.level", key: "SECONDARY_CONTROL") { tileAttribute ("device.level", key: "SECONDARY_CONTROL") {
attributeState "level", label: 'Level ${currentValue}%' attributeState "level", label: 'Level ${currentValue}%'
} }
} }
standardTile("switch", "device.switch", width: 2, height: 2, canChangeIcon: true) { standardTile("switch", "device.switch", width: 2, height: 2, canChangeIcon: true) {
state "on", label:'${name}', action:"switch.off", icon:"st.lights.philips.hue-single", backgroundColor:"#79b821", nextState:"turningOff" state "on", label:'${name}', action:"switch.off", icon:"st.lights.philips.hue-single", backgroundColor:"#79b821", nextState:"turningOff"
state "off", label:'${name}', action:"switch.on", icon:"st.lights.philips.hue-single", backgroundColor:"#ffffff", nextState:"turningOn" state "off", label:'${name}', action:"switch.on", icon:"st.lights.philips.hue-single", backgroundColor:"#ffffff", nextState:"turningOn"
state "turningOn", label:'${name}', action:"switch.off", icon:"st.lights.philips.hue-single", backgroundColor:"#79b821", nextState:"turningOff" state "turningOn", label:'${name}', action:"switch.off", icon:"st.lights.philips.hue-single", backgroundColor:"#79b821", nextState:"turningOff"
state "turningOff", label:'${name}', action:"switch.on", icon:"st.lights.philips.hue-single", backgroundColor:"#ffffff", nextState:"turningOn" state "turningOff", label:'${name}', action:"switch.on", icon:"st.lights.philips.hue-single", backgroundColor:"#ffffff", nextState:"turningOn"
} }
controlTile("levelSliderControl", "device.level", "slider", height: 1, width: 2, inactiveLabel: false, range:"(0..100)") { controlTile("levelSliderControl", "device.level", "slider", height: 1, width: 2, inactiveLabel: false, range:"(0..100)") {
state "level", action:"switch level.setLevel" state "level", action:"switch level.setLevel"
} }
standardTile("refresh", "device.switch", inactiveLabel: false, decoration: "flat", width: 2, height: 2) { controlTile("colorTempSliderControl", "device.colorTemperature", "slider", width: 4, height: 2, inactiveLabel: false, range:"(2000..6500)") {
state "default", label:"", action:"refresh.refresh", icon:"st.secondary.refresh" state "colorTemperature", action:"color temperature.setColorTemperature"
} }
valueTile("colorTemp", "device.colorTemperature", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
main(["switch"]) state "colorTemperature", label: '${currentValue} K'
details(["rich-control", "colorTempSliderControl","refresh"]) }
}
} standardTile("refresh", "device.switch", inactiveLabel: false, decoration: "flat") {
state "default", label:"", action:"refresh.refresh", icon:"st.secondary.refresh"
// parse events into attributes }
def parse(description) {
log.debug "parse() - $description" main(["switch"])
def results = [] details(["rich-control", "colorTempSliderControl", "colorTemp", "refresh"])
}
def map = description }
if (description instanceof String) {
log.debug "Hue Bulb stringToMap - ${map}" // parse events into attributes
map = stringToMap(description) def parse(description) {
} log.debug "parse() - $description"
def results = []
if (map?.name && map?.value) {
results << createEvent(name: "${map?.name}", value: "${map?.value}") def map = description
} if (description instanceof String) {
results log.debug "Hue Bulb stringToMap - ${map}"
} map = stringToMap(description)
}
// handle commands
void on() { if (map?.name && map?.value) {
parent.on(this) results << createEvent(name: "${map?.name}", value: "${map?.value}")
sendEvent(name: "switch", value: "on") }
} results
}
void off() {
parent.off(this) // handle commands
sendEvent(name: "switch", value: "off") void on() {
} parent.on(this)
sendEvent(name: "switch", value: "on")
void setLevel(percent) { }
log.debug "Executing 'setLevel'"
parent.setLevel(this, percent) void off() {
sendEvent(name: "level", value: percent) parent.off(this)
} sendEvent(name: "switch", value: "off")
}
void refresh() {
log.debug "Executing 'refresh'" void setLevel(percent) {
parent.manualRefresh() log.debug "Executing 'setLevel'"
} parent.setLevel(this, percent)
sendEvent(name: "level", value: percent)
}
void setColorTemperature(value) {
if (value) {
log.trace "setColorTemperature: ${value}k"
parent.setColorTemperature(this, value)
sendEvent(name: "colorTemperature", value: value)
}
}
void refresh() {
log.debug "Executing 'refresh'"
parent.manualRefresh()
}

View File

@@ -32,15 +32,14 @@ metadata {
attributeState("default", label:'${currentValue}', unit:"dF") attributeState("default", label:'${currentValue}', unit:"dF")
} }
tileAttribute("device.temperature", key: "VALUE_CONTROL") { tileAttribute("device.temperature", key: "VALUE_CONTROL") {
attributeState("VALUE_UP", action: "tempUp") attributeState("default", action: "setTemperature")
attributeState("VALUE_DOWN", action: "tempDown")
} }
tileAttribute("device.humidity", key: "SECONDARY_CONTROL") { tileAttribute("device.humidity", key: "SECONDARY_CONTROL") {
attributeState("default", label:'${currentValue}%', unit:"%") attributeState("default", label:'${currentValue}%', unit:"%")
} }
tileAttribute("device.thermostatOperatingState", key: "OPERATING_STATE") { tileAttribute("device.thermostatOperatingState", key: "OPERATING_STATE") {
attributeState("idle", backgroundColor:"#44b621") attributeState("idle", backgroundColor:"#44b621")
attributeState("heating", backgroundColor:"#ea5462") attributeState("heating", backgroundColor:"#ffa81e")
attributeState("cooling", backgroundColor:"#269bd2") attributeState("cooling", backgroundColor:"#269bd2")
} }
tileAttribute("device.thermostatMode", key: "THERMOSTAT_MODE") { tileAttribute("device.thermostatMode", key: "THERMOSTAT_MODE") {

View File

@@ -0,0 +1,46 @@
/**
* test1
*
* Copyright 2016 임희진
*
* 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: "test1", namespace: "test11", author: "임희진") {
capability "Lock"
}
simulator {
// TODO: define status and reply messages here
}
tiles {
// TODO: define your main and details tiles here
}
}
// parse events into attributes
def parse(String description) {
log.debug "Parsing '${description}'"
// TODO: handle 'lock' attribute
}
// handle commands
def lock() {
log.debug "Executing 'lock'"
// TODO: handle 'lock' command
}
def unlock() {
log.debug "Executing 'unlock'"
// TODO: handle 'unlock' command
}

View File

@@ -1,142 +1,143 @@
/** /**
* Copyright 2015 SmartThings * Copyright 2015 SmartThings
* *
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except * 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: * in compliance with the License. You may obtain a copy of the License at:
* *
* http://www.apache.org/licenses/LICENSE-2.0 * 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 * 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 * 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. * for the specific language governing permissions and limitations under the License.
* *
* Virtual Thermostat * Virtual Thermostat
* *
* Author: SmartThings * Author: SmartThings
*/ */
definition( definition(
name: "Virtual Thermostat", name: "Virtual Thermostat",
namespace: "smartthings", namespace: "smartthings",
author: "SmartThings", author: "SmartThings",
description: "Control a space heater or window air conditioner in conjunction with any temperature sensor, like a SmartSense Multi.", description: "Control a space heater or window air conditioner in conjunction with any temperature sensor, like a SmartSense Multi.",
category: "Green Living", category: "Green Living",
iconUrl: "https://s3.amazonaws.com/smartapp-icons/Meta/temp_thermo-switch.png", iconUrl: "https://s3.amazonaws.com/smartapp-icons/Meta/temp_thermo-switch.png",
iconX2Url: "https://s3.amazonaws.com/smartapp-icons/Meta/temp_thermo-switch@2x.png" iconX2Url: "https://s3.amazonaws.com/smartapp-icons/Meta/temp_thermo-switch@2x.png"
) )
preferences { preferences {
section("Choose a temperature sensor... "){ section("Choose a temperature sensor... "){
input "sensor", "capability.temperatureMeasurement", title: "Sensor" input "sensor", "capability.temperatureMeasurement", title: "Sensor"
} }
section("Select the heater or air conditioner outlet(s)... "){ section("Select the heater or air conditioner outlet(s)... "){
input "outlets", "capability.switch", title: "Outlets", multiple: true input "outlets", "capability.switch", title: "Outlets", multiple: true
} }
section("Set the desired temperature..."){ section("Set the desired temperature..."){
input "setpoint", "decimal", title: "Set Temp" input "setpoint", "decimal", title: "Set Temp"
} }
section("When there's been movement from (optional, leave blank to not require motion)..."){ section("When there's been movement from (optional, leave blank to not require motion)..."){
input "motion", "capability.motionSensor", title: "Motion", required: false input "motion", "capability.motionSensor", title: "Motion", required: false
} }
section("Within this number of minutes..."){ section("Within this number of minutes..."){
input "minutes", "number", title: "Minutes", required: false input "minutes", "number", title: "Minutes", required: false
} }
section("But never go below (or above if A/C) this value with or without motion..."){ section("But never go below (or above if A/C) this value with or without motion..."){
input "emergencySetpoint", "decimal", title: "Emer Temp", required: false input "emergencySetpoint", "decimal", title: "Emer Temp", required: false
} }
section("Select 'heat' for a heater and 'cool' for an air conditioner..."){ section("Select 'heat' for a heater and 'cool' for an air conditioner..."){
input "mode", "enum", title: "Heating or cooling?", options: ["heat","cool"] input "mode", "enum", title: "Heating or cooling?", options: ["heat","cool"]
} }
} }
def installed() def installed()
{ {
subscribe(sensor, "temperature", temperatureHandler) subscribe(sensor, "temperature", temperatureHandler)
if (motion) { if (motion) {
subscribe(motion, "motion", motionHandler) subscribe(motion, "motion", motionHandler)
} }
} }
def updated() def updated()
{ {
unsubscribe() unsubscribe()
subscribe(sensor, "temperature", temperatureHandler) subscribe(sensor, "temperature", temperatureHandler)
if (motion) { if (motion) {
subscribe(motion, "motion", motionHandler) subscribe(motion, "motion", motionHandler)
} }
} }
def temperatureHandler(evt) def temperatureHandler(evt)
{ {
def isActive = hasBeenRecentMotion() def isActive = hasBeenRecentMotion()
if (isActive || emergencySetpoint) { if (isActive || emergencySetpoint) {
evaluate(evt.doubleValue, isActive ? setpoint : emergencySetpoint) evaluate(evt.doubleValue, isActive ? setpoint : emergencySetpoint)
} }
else { else {
outlets.off() outlets.off()
} }
} }
def motionHandler(evt) def motionHandler(evt)
{ {
if (evt.value == "active") { if (evt.value == "active") {
def lastTemp = sensor.currentTemperature def lastTemp = sensor.currentTemperature
if (lastTemp != null) { if (lastTemp != null) {
evaluate(lastTemp, setpoint) evaluate(lastTemp, setpoint)
} }
} else if (evt.value == "inactive") { } else if (evt.value == "inactive") {
def isActive = hasBeenRecentMotion() def isActive = hasBeenRecentMotion()
log.debug "INACTIVE($isActive)" log.debug "INACTIVE($isActive)"
if (isActive || emergencySetpoint) { if (isActive || emergencySetpoint) {
def lastTemp = sensor.currentTemperature def lastTemp = sensor.currentTemperature
if (lastTemp != null) { if (lastTemp != null) {
evaluate(lastTemp, isActive ? setpoint : emergencySetpoint) evaluate(lastTemp, isActive ? setpoint : emergencySetpoint)
} }
} }
else { else {
outlets.off() outlets.off()
} }
} }
} }
private evaluate(currentTemp, desiredTemp) private evaluate(currentTemp, desiredTemp)
{ {
log.debug "EVALUATE($currentTemp, $desiredTemp)" log.debug "EVALUATE($currentTemp, $desiredTemp)"
def threshold = 1.0 def threshold = 1.0
if (mode == "cool") { if (mode == "cool") {
// air conditioner // air conditioner
if (currentTemp - desiredTemp >= threshold) { if (currentTemp - desiredTemp >= threshold) {
outlets.on() outlets.on()
} }
else if (desiredTemp - currentTemp >= threshold) { else if (desiredTemp - currentTemp >= threshold) {
outlets.off() outlets.off()
} }
} }
else { else {
// heater // heater
if (desiredTemp - currentTemp >= threshold) { if (desiredTemp - currentTemp >= threshold) {
outlets.on() outlets.on()
} }
else if (currentTemp - desiredTemp >= threshold) { else if (currentTemp - desiredTemp >= threshold) {
outlets.off() outlets.off()
} }
} }
} }
private hasBeenRecentMotion() private hasBeenRecentMotion()
{ {
def isActive = false def isActive = false
if (motion && minutes) { if (motion && minutes) {
def deltaMinutes = minutes as Long def deltaMinutes = minutes as Long
if (deltaMinutes) { if (deltaMinutes) {
def motionEvents = motion.eventsSince(new Date(now() - (60000 * deltaMinutes))) def motionEvents = motion.eventsSince(new Date(now() - (60000 * deltaMinutes)))
log.trace "Found ${motionEvents?.size() ?: 0} events in the last $deltaMinutes minutes" log.trace "Found ${motionEvents?.size() ?: 0} events in the last $deltaMinutes minutes"
if (motionEvents.find { it.value == "active" }) { if (motionEvents.find { it.value == "active" }) {
isActive = true isActive = true
} }
} }
} }
else { else {
isActive = true isActive = true
} }
isActive isActive
} }