Files
SmartThingsPublic/smartapps/smartsolutionsv2/sleeping/smart-sleep-automation.src/smart-sleep-automation.groovy

1487 lines
55 KiB
Groovy

/**
* Sleep Rules
*
* 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.
*
*/
import java.text.DecimalFormat
definition(
name: "Smart Sleep Automation",
namespace: "smartsolutionsv2/sleeping",
parent: "smartsolutionsv2/sleeping:Smart Sleep",
author: "SmartThings",
description: "Sleeping automation rule.",
category: "My Apps",
iconUrl: "https://s3.amazonaws.com/smartapp-icons/ModeMagic/Cat-ModeMagic.png",
iconX2Url: "https://s3.amazonaws.com/smartapp-icons/ModeMagic/Cat-ModeMagic@2x.png",
iconX3Url: "https://s3.amazonaws.com/smartapp-icons/ModeMagic/Cat-ModeMagic@3x.png"
)
preferences {
page(name: "mainPage", title: getLabel("str_MainPageTitle"), install: false, uninstall: true, nextPage: "namePage");
page(name: "namePage", title: getLabel("str_NamePageTitle"), install: true, uninstall: true);
page(name: "timeIntervalInput", title: getLabel("str_TimeSet"));
}
def mainPage() {
dynamicPage(name: "mainPage") {
section {
sleepSensorInput();
triggerInput();
}
controlType();
controlledInput();
otherInputs();
}
}
//Sleep sensor input
def sleepSensorInput() {
input(name: "sleepSensor", type: "capability.sleepSensor", title: getLabel("str_SelectSense"), multiple: false, submitOnChange: true);
}
//Sleep sensor action to trigger event
private actionMap() {
state.sleepActionMap = ["sleeping": getLabel("str_sleep"), "not sleeping": getLabel("str_wake")];
if(sleepSensor.find{it.hasAttribute("bedstate")} != null) {
state.sleepActionMap.put("in bed", getLabel("str_inbed"));
state.sleepActionMap.put("out of bed", getLabel("str_outofbed"));
}
return state.sleepActionMap;
}
private actionOptions() {
actionMap().collect{[(it.key): it.value]}
}
def triggerInput() {
def requiredInput = androidClient() || iosClient("1.7.0.RC1");
if(sleepSensor) {
input(name: "trigger", type: "enum", title: getLabel("str_SelectSleepTrigger"), options: actionOptions(), required: true, submitOnChange: true);
}
}
// What type should be controlled
private controlType() {
def requiredInput = androidClient() || iosClient("1.7.0.RC1");
def mapControlTypes
if(clientLocale?.language == "ko")
{
mapControlTypes = [device: "${location.name}${getLabel("str_HubofDevice")}", homeWatch: getLabel("str_HubofHomeWatch"), mode: "${location.name}${getLabel("str_HubofMode")}", routine: "${location.name}${getLabel("str_HubofRoutines")}"];
}
else
{
mapControlTypes = [device: "${getLabel("str_HubofDevice")}${location.name}", homeWatch: getLabel("str_HubofHomeWatch"), mode: "${getLabel("str_HubofMode")}${location.name}", routine: "${getLabel("str_HubofRoutines")}${location.name}"];
}
if(settings.trigger) {
section() {
input(name: "controlType", type: "enum", title: getLabel("str_SelectLocation"), options: mapControlTypes, required: requiredInput, submitOnChange: true);
}
}
}
//Device to control with sleep sensor input
private lightMap() {
def lightActionMap = [on: getLabel("str_DeviceTurnOn"), off: getLabel("str_DeviceTurnOff")];
if (controlledDevice.find{it.hasCapability("Switch Level")} != null) {
lightActionMap.level = getLabel("str_DeviceLevel")
}
if (controlledDevice.find{it.hasCapability("Color Control")} != null) {
lightActionMap.color = getLabel("str_DeviceColor")
}
return lightActionMap;
}
private lightOptions() {
lightMap().collect{[(it.key): it.value]}
}
def controlledInput() {
def requiredInput = androidClient() || iosClient("1.7.0.RC1");
def mapControlledDeivces = [switch: getLabel("str_DeviceSwitch"), imageCapture: getLabel("str_DeviceCameras"), lock: getLabel("str_DeviceLocks"), thermostat: getLabel("str_DeviceThermostats"), alarm: getLabel("str_DeviceAlarms"), musicPlayer: getLabel("str_DeviceSpeaker")];
log.debug "control type ${settings.controlType}";
if(settings.controlType && settings.controlType == "device") {
section(getLabel("str_DeviceTitle")) {
input(name: "controlledDeviceType", type: "enum", title: getLabel("str_DeviceSelect"), options: mapControlledDeivces, required: requiredInput, submitOnChange: true);
}
if(controlledDeviceType) {
def deviceType;
section() {
input(name: "controlledDevice", type: "capability.${controlledDeviceType}", required: true, multiple: true, submitOnChange: true);
}
if(controlledDevice) {
def label = controlledDevice.size() == 1? "${controlledDevice[0].label !=null ? controlledDevice[0].label : controlledDevice[0]} Control" : "${controlledDevice[0].label != null ? controlledDevice[0].label : controlledDevice[0]}, etc Control";
section("${label}") {
switch(controlledDeviceType) {
case "switch":
input(name: "actionsLights", type: "enum", title: getLabel("str_DeviceLightsTitle"), options: lightOptions(), multiple: false, required: requiredInput, submitOnChange: true);
if(actionsLights == "color") {
input(name: "color", type: "enum", title: "Color", required: true, multiple: false, options: [
["Soft White":"Soft White - Default"],
["White":"White - Concentrate"],
["Daylight":"Daylight - Energize"],
["Warm White":"Warm White - Relax"],
"Red","Green","Blue","Yellow","Orange","Purple","Pink"]);
}
if(actionsLights == "level") {
input(name: "level", type: "number", title: "Dimmer Level", defaultValue: 50, required: true, submitOnChange: true);
}
def nonDimmableLights = "";
def nonColorControlLights = "";
def isareLevel = "";
def hasSwitchLevel = false;
def hasColorControl = false;
controlledDevice.eachWithIndex { item, index ->
if(item.hasCapability("Switch Level") == null) {
if(nonDimmableLights == "") {
nonDimmableLights += "${item.label != null ? item.label : item}" ;
isareLevel = "is";
} else {
nonDimmableLights += ", ${item.label != null ? item.label : item}";
if(isareLevel == "is") {
isareLevel = "are";
}
}
} else {
hasSwitchLevel = true;
}
if(item.hasCapability("Color Control") == null) {
if(nonColorControlLights == "") {
nonColorControlLights += "${item.label != null ? item.label : item}";
} else {
nonColorControlLights += ", ${item.label != null ? item.label : item}";
}
} else {
hasColorControl = true;
}
}
if(hasSwitchLevel && nonDimmableLights != "") {
paragraph "${nonDimmableLights} ${isareLevel} not dimmable. These will be turned on to 100%.";
}
if(hasColorControl && nonColorControlLights != "") {
paragraph "${nonColorControlLights} cannot set color.";
}
break;
case "imageCapture":
input(name: "imageCaptureAction", type: "enum", title: getLabel("str_CameraTitle"), options: [take: getLabel("str_CameraTake")], multiple: false, required:true, submitOnChange: true);
break;
case "lock":
input(name: "lockAction", type: "enum", title: getLabel("str_LocksTitle"), options: [lock: getLabel("str_LocksLock"), unlock: getLabel("str_LocksUnLock")], multiple: false, required: true, submitOnChange: true);
break;
case "thermostat":
input(name: "thermostatMode", type: "enum", title: getLabel("str_DeviceThermostatTitle"), options: [modeCool: getLabel("str_DeviceThermostatCool"), modeHeat: getLabel("str_DeviceThermostatHeat"), off: getLabel("str_DeviceTurnOff")], required: requiredInput, multiple: false, submitOnChange: true);
switch(thermostatMode) {
case "modeCool":
input(name: "thermostatCoolTemp", type: "number", title: getLabel("str_DeviceThermostatCoolSet"), defaultValue: 76, required: true, submitOnChange: true);
break;
case "modeHeat":
input(name: "thermostatHeatTemp", type: "number", title: getLabel("str_DeviceThermostatHeatSet"), defaultValue: 86, required: true, submitOnChange: true);
break;
}
break;
case "alarm":
input(name: "alarmAction", type: "enum", title: getLabel("str_AlarmWill"), options: [strobe: "Strobe the lights", siren: "Sound the siren", both: "Strobe the lights & sound the alarm", off: "turn Off"], multiple: false, required: true, submitOnChange: true);
break;
case "musicPlayer":
input(name: "musicPlayerAction", type: "enum", title: getLabel("str_DeviceSpeakerTitle"), options: [play: getLabel("str_DeviceSpeakerPlae"), pause: getLabel("str_DeviceSpeakerPause"), stop: getLabel("str_DeviceSpeakerStop")], required: true, multiple: false, submitOnChange: true);
break;
}
}
}
}
}
if(settings.controlType && settings.controlType == "homeWatch") {
section(getLabel("str_HomeWatchTitle")) {
input(name: "homeWatchAction", type: "enum", title: getLabel("str_HomeWatchSectionSelect"), required: true, multiple: false, options: [off: "Off", stay: "Stay", arm: "Arm"], submitOnChange: true);
}
}
if(settings.controlType && settings.controlType == "mode") {
section(getLabel("strr_ModeTitle")) {
input(name: "modeAction", type: "mode", title: getLabel("str_ModeSelect"), required: true, multiple: false, submitOnChange: true);
}
}
if(settings.controlType && settings.controlType == "routine") {
def routines = location.helloHome?.getPhrases()*.label;
if(routines) {
section(getLabel("str_RoutineTitle")) {
input(name: "routineAction", type: "enum", title: getLabel("str_RoutineSelect"), options: routines, required: true, multiple: false, submitOnChange: true);
}
}
}
}
def otherInputs() {
if (settings.trigger) {
def timeLabel = timeIntervalLabel()
section(title: getLabel("str_Moreoption"), hidden: hideOptionsSection(), hideable: true) {
def timeBasedTrigger = trigger in ["At Sunrise", "At Sunset", "At a Specific Time"]
log.trace "timeBasedTrigger: $timeBasedTrigger"
if (!timeBasedTrigger) {
href "timeIntervalInput", title: getLabel("str_TimeSet"), description: timeLabel ?: getLabel("str_Taptoset"), state: timeLabel ? "complete" : "incomplete"
}
input "days", "enum", title: getLabel("str_WeekSet"), multiple: true, required: false,
options: [getLabel("str_Monday"), getLabel("str_Tuesday"), getLabel("str_Wednesday"), getLabel("str_Thursday"), getLabel("str_Friday"), getLabel("str_Saturday"), getLabel("str_Sunday")]
//input "modes", "mode", title: "Only when mode is", multiple: true, required: false
}
}
}
def timeIntervalInput() {
dynamicPage(name: "timeIntervalInput") {
section {
input "startTimeType", "enum", title: getLabel("str_TimeStartingCondition"), options: [["time": getLabel("str_TimeSpecificTime")], ["sunrise": getLabel("str_TimeSunrise")], ["sunset": getLabel("str_TimeSunset")]], defaultValue: "time", submitOnChange: true
if (startTimeType in ["sunrise","sunset"]) {
input "startTimeOffset", "number", title: getLabel("str_TimeOffset"), range: "*..*", required: false
}
else {
input "starting", "time", title: getLabel("str_TimeStart"), required: false
}
}
section {
input "endTimeType", "enum", title: getLabel("str_TimeEngingCondition"), options: [["time": getLabel("str_TimeSpecificTime")], ["sunrise": getLabel("str_TimeSunrise")], ["sunset": getLabel("str_TimeSunset")]], defaultValue: "time", submitOnChange: true
if (endTimeType in ["sunrise","sunset"]) {
input "endTimeOffset", "number", title: getLabel("str_TimeOffset"), range: "*..*", required: false
}
else {
input "ending", "time", title: getLabel("str_TimeEnd"), required: false
}
}
}
}
private hideOptionsSection() {
(starting || startTimeType in ["sunrise","sunset"] || ending || endTimeType in ["sunrise","sunset"] || days || modes) ? false : true
}
private String generateDefaultLabel() {
def sleepSensor = sleepSensor.label;
def trigger = state.sleepActionMap[trigger];
def device = "";
if(controlledDevice) {
device = controlledDevice.size() == 1 ? "${controlledDevice[0].label != null ? controlledDevice[0].label : controlledDevice[0]}": "${controlledDevice[0].label != null ? controlledDevice[0].label : controlledDevice[0]}, etc";
} else if(modeAction) {
device = "${modeAction}";
} else if(homeWatchAction) {
device = "Home Watch";
}
def defaultLabel = "${trigger}";
if(controlType == "device") {
switch(controlledDeviceType) {
case "switch":
switch(actionsLights) {
case "on":
return "${defaultLabel} turn on ${device}";
break;
case "off":
return "${defaultLabel} turn off ${device}";
break;
case "color":
return "${defaultLabel} turn on ${device} and set color to ${color}";
break;
case "level":
return "${defaultLabel} turn on ${device} and set level to ${level}";
break;
}
break;
case "imageCapture":
return "${defaultLabel} have ${device} capture Image"
break;
case "lock":
return "${defaultLabel} ${lockAction[0].toLowerCase() + lockAction.substring(1)} ${device}";
break;
case "thermostat":
switch(thermostatMode) {
case "modeCool":
return "${defaultLabel} turn ${device} on, change cooling setpoint to ${thermostatCoolTemp}, and set mode to cool."
break;
case "modeHeat":
return "${defaultLabel} turn ${device} on, change cooling setpoint to ${thermostatHeatTemp}, and set mode to heat."
break;
case "off":
return "${defaultLabel} turn ${device} off."
break;
}
break;
case "alarm":
return "${defaultLabel} ${alarmAction[0].toLowerCase() + alarmAction.substring(1)} ${device}";
break;
case "musicPlayer":
return "$defaultLabel} ${musicPlayerAction[0].toLowerCase() + musicPlayerAction.substring(1)} ${device}"
break;
}
} else if(controlType == "homeWatch") {
return "${defaultLabel} ${homeWatchAction} Home Watch";
} else if(controlType == "mode") {
return "${defaultLabel} change mode to ${modeAction}";
} else if(controlType == "routine") {
return "${defaultLabel} run routine ${routineAction}";
}
}
def namePage() {
if(!overrideLabel) {
app.updateLabel(generateDefaultLabel());
}
dynamicPage(name: "namePage") {
if(overrideLabel) {
section(title: getLabel("str_NameAutomation")) {
label(title: getLabel("str_NameUser"), defaultValue: generateDefaultLabel(), required: false);
}
} else {
section(title: getLabel("str_NameAutomation")) {
paragraph app.label;
}
}
section {
input(name: "overrideLabel", type: "bool", title: getLabel("str_NameChange"), required: false, submitOnChange: true);
}
}
}
def installed() {
log.debug "Installed with settings: ${settings}"
initialize()
}
def updated() {
log.debug "Updated with settings: ${settings}"
unsubscribe()
unschedule()
initialize()
}
def initialize() {
if(!overrideLabel) {
app.updateLabel(generateDefaultLabel());
}
subscribe(sleepSensor, "bedstate", eventHandler);
subscribe(sleepSensor, "sleeping", eventHandler);
}
def eventHandler(evt) {
if(evt.value == trigger) {
if(getAllOk()) {
log.debug "all ok";
switch(controlType) {
case "device":
if(controlledDevice) {
switch(controlledDeviceType) {
case "switch":
if(actionsLights == "on") {
controlledDevice.on();
sendMessage();
}
if(actionsLights == "off") {
controlledDevice.off();
sendMessage();
}
if(actionsLights == "color" || actionsLights == "level") {
setColor();
}
break;
case "imageCapture":
controlledDevice."${imageCaptureAction}"();
sendMessage();
break;
case "lock":
controlledDevice."${lockAction}"();
sendMessage();
break;
case "thermostat":
if(thermostatMode == "modeCool") {
controlledDevice.setCoolingSetpoint(thermostatCoolTemp);
controlledDevice.cool();
sendMessage();
}
if(thermostatMode == "modeHeat") {
controlledDevice.setHeatingSetpoints(thermostatHeatTemp);
controlledDevice.heat();
sendMessage();
}
break;
case "alarm":
controlledDevice."${alarmAction}"();
sendMessage();
break;
case "musicPlayer":
controlledDevice."${musicPlayerAction}"();
sendMessage();
break;
}
}
break;
case "homeWatch":
log.debug "homeWatch";
sendLocationEvent(name: "alarmSystemStatus", value: "${homeWatchAction}");
sendMessage();
break;
case "mode":
log.debug "mode";
location.setMode("${modeAction}");
sendMessage();
break;
case "routine":
log.debug "routine";
location.helloHome?.execute("${routineAction}");
sendMessage();
break;
}
}
}
}
private setColor() {
def hueColor = 0
def saturation = 100
switch(color) {
case "White":
hueColor = 52
saturation = 19
break;
case "Daylight":
hueColor = 53
saturation = 91
break;
case "Soft White":
hueColor = 23
saturation = 56
break;
case "Warm White":
hueColor = 20
saturation = 80
break;
case "Blue":
hueColor = 70
break;
case "Green":
hueColor = 39
break;
case "Yellow":
hueColor = 25
break;
case "Orange":
hueColor = 10
break;
case "Purple":
hueColor = 75
break;
case "Pink":
hueColor = 83
break;
case "Red":
hueColor = 100
break;
}
def value = [switch: "on", hue: hueColor, saturation: saturation, level: 100]
controlledDevice.each {
it.on()
if (actionsLights.contains("color")) {
if(it.hasCapability("Color Control"))
it.setColor(value);
sendMessage();
}
if (actionsLights.contains("level")) {
if(it.hasCapability("Switch Level"))
it.setLevel(level as Integer ?: 100);
sendMessage();
}
}
}
private sendMessage(evt = [:]) {
def color = "#79b821";
def icon = "st.switches.light.on";
def actionLabel = "";
log.debug "control type: ${controlType}"
def controlledDeviceLabel = controlledDevice.size() == 1 ? "${controlledDevice[0].label != null ? controlledDevice[0].label : controlledDevice[0]}" : "${controlledDevice[0].label != null ? controlledDevice[0].label : controlledDevice[0]}, ect"
if(controlType == "device") {
switch(controlledDeviceType) {
case "switch":
switch(actionLights) {
case "on":
icon = "st.switches.light.on";
actionLabel = "Turned on ${controlledDevice.label}";
break;
case "off":
color = "#878787";
icon = "st.switches.light.off";
actionLabel = "Turned off ${controlledDevice.label}";
break;
case "color":
icon = "st.switches.light.on";
actionLabel = "Turned on ${controlledDevice.label} and set color to ${color}";
break;
case "level":
icon = "st.switches.light.on";
actionLabel = "Turned on ${controlledDevice.label} and set level to ${level}";
break;
}
if (app.currentState("status")?.value != actionLights || app.currentState("status") == null) {
def text = "$app.label $actionLabel"
sendEvent(name: "status", value: actionLights, linkText: app.label,
descriptionText: text, eventType:"SOLUTION_EVENT", data: [icon: icon, backgroundColor: color])
}
break;
case "imageCapture":
icon = "st.camera.take-photo";
actionLabel = "${controlledDevice.label} captured image";
sendEvent(name: "status", value: imageCaptureAction, linkText: app.label,
descriptionText: text, eventType: "SOLUTION_EVENT", data: [icon: icon, backgroundColor: color])
break;
case "lock":
if(lockAction == "lock") {
icon = "st.locks.lock.locked";
actionLabel = "${controlledDevice.label} has been locked";
sendEvent(name: "status", value: lockAction, linkText: app.label,
descriptionText: text, eventType: "SOLUTION_EVENT", data: [icon: icon, backgroundColor: color])
} else if(lockAction == "unlock") {
icon = "st.locks.lock.unlocked";
actionLabel = "${controlledDevice.label} has been unlocked";
sendEvent(name: "status", value: lockAction, linkText: app.label,
descriptionText: text, eventType: "SOLUTION_EVENT", data: [icon: icon, backgroundColor: color])
}
break;
case "thermostat":
if(thermostatMode == "modeCool") {
icon = "st.thermostat.cool";
actionLabel = "${controlledDevice.label} has cooling setpoint of ${thermostatCoolTemp} and is in cooling mode."
}
if(thermostatMode == "modeHeat") {
icon = "st.thermostat.heat";
actionLabel = "${controlledDevice.label} has heating setpoint of ${thermostatCoolTemp} and is in heating mode."
}
if (app.currentState("status")?.value != thermostatMode || app.currentState("status") == null) {
def text = "$app.label $actionLabel"
sendEvent(name: "status", value: thermostatMode, linkText: app.label,
descriptionText: text, eventType:"SOLUTION_EVENT", data: [icon: icon, backgroundColor: color])
}
break;
case "alarm":
switch(alarmAction) {
case "strobe":
icon = "st.security.alarm.alarm";
actionLabel = "Strobe the lights on ${controlledDevice.label}";
sendEvent(name: "status", value: alarmAction, linkText: app.label,
descriptionText: text, eventType: "SOLUTION_EVENT", data: [icon: icon, backgroundColor: color])
break;
case "siren":
icon = "st.security.alarm.alarm";
actionLabel = "Sound siren on ${controlledDevice.label}";
sendEvent(name: "status", value: alarmAction, linkText: app.label,
descriptionText: text, eventType: "SOLUTION_EVENT", data: [icon: icon, backgroundColor: color])
break;
case "both":
icon = "st.security.alarm.alarm";
actionLabel = "Strobe the lights and sound the siren on ${controlledDevice.label}";
sendEvent(name: "status", value: alarmAction, linkText: app.label,
descriptionText: text, eventType: "SOLUTION_EVENT", data: [icon: icon, backgroundColor: color])
break;
case "off":
icon = "st.security.alarm.clear";
color = "#878787";
actionLabel = "Turn ${controlledDevice.label} off";
sendEvent(name: "status", value: alarmAction, linkText: app.label,
descriptionText: text, eventType: "SOLUTION_EVENT", data: [icon: icon, backgroundColor: color])
break;
}
break;
case "musicPlayer":
switch(musicPlayerAction) {
case "play":
icon = "st.sonos.play-btn";
actionLabel = "Play music on ${controlledDevice.label}";
sendEvent(name: "status", value: musicPlayerAction, linkText: app.label,
descriptionText: text, eventType: "SOLUTION_EVENT", data: [icon: icon, backgroundColor: color])
break;
case "pause":
icon = "st.sonos.pause-btn";
color = "#878787";
actionLabel = "Pause music on ${controlledDevice.label}";
sendEvent(name: "status", value: musicPlayerAction, linkText: app.label,
descriptionText: text, eventType: "SOLUTION_EVENT", data: [icon: icon, backgroundColor: color])
break;
case "stop":
icon = "st.sonos.stop-btn";
color = "#878787";
actionLabel = "Stop music on ${controlledDevice.label}";
sendEvent(name: "status", value: musicPlayerAction, linkText: app.label,
descriptionText: text, eventType: "SOLUTION_EVENT", data: [icon: icon, backgroundColor: color])
break;
}
break;
}
} else if(controlType == "homeWatch") {
switch(homeWatchAction) {
case "off":
icon = "st.security.alarm.off";
color = "#878787";
actionLabel = "Smart Home Monitoring is off";
sendEvent(name: "status", value: homeWatchAction, linkText: app.label,
descriptionText: text, eventType: "SOLUTION_EVENT", data: [icon: icon, backgroundColor: color])
break;
case "stay":
icon = "st.security.alarm.partial";
color = "#F0F015";
actionLabel = "Smart Home Monitoring is in stay";
sendEvent(name: "status", value: homeWatchAction, linkText: app.label,
descriptionText: text, eventType: "SOLUTION_EVENT", data: [icon: icon, backgroundColor: color])
break;
case "arm":
icon = "st.security.alarm.on";
actionLabel = "Smart Home Monitoring is armed";
sendEvent(name: "status", value: homeWatchAction, linkText: app.label,
descriptionText: text, eventType: "SOLUTION_EVENT", data: [icon: icon, backgroundColor: color])
break;
}
} else if(controlType == "mode") {
icon = "st.Home.home2";
actionLabel = "${location.name} changed modes to ${modeAction}";
sendEvent(name: "status", value: modeAction, linkText: app.label,
descriptionText: text, eventType: "SOLUTION_EVENT", data: [icon: icon, backgroundColor: color])
} else if(controlType == "routine") {
icon = "st.Home.home2";
actionLabel = "Execute ${routineAction} at ${location.name}";
sendEvent(name: "status", value: routineAction, linkText: app.label,
descriptionText: text, eventType: "SOLUTION_EVENT", data: [icon: icon, backgroundColor: color])
}
}
// TODO - centralize somehow
private getAllOk() {
modeOk && daysOk && timeOk
}
private getModeOk() {
def result = !modes || modes.contains(location.mode)
log.trace "modeOk = $result"
result
}
private getDaysOk() {
def result = true
if (days) {
def df = new java.text.SimpleDateFormat("EEEE")
if (location.timeZone) {
df.setTimeZone(location.timeZone)
}
else {
df.setTimeZone(TimeZone.getTimeZone("America/Los_Angeles"))
}
def day = df.format(new Date())
result = days.contains(day)
}
log.trace "daysOk = $result"
result
}
private getTimeOk() {
def result = true
def start = timeWindowStart()
def stop = timeWindowStop()
if (start && stop) {
result = timeOfDayIsBetween(start, stop, new Date(), location.timeZone)
}
log.trace "timeOk = $result"
result
}
private timeWindowStart() {
def result = null
if (startTimeType == "sunrise") {
result = location.currentState("sunriseTime")?.dateValue
if (result && startTimeOffset) {
result = new Date(result.time + Math.round(startTimeOffset * 60000))
}
}
else if (startTimeType == "sunset") {
result = location.currentState("sunsetTime")?.dateValue
if (result && startTimeOffset) {
result = new Date(result.time + Math.round(startTimeOffset * 60000))
}
}
else if (starting) {
result = timeToday(starting, location.timeZone)
}
log.trace "timeWindowStart = ${result}"
result
}
private timeWindowStop() {
def result = null
if (endTimeType == "sunrise") {
result = location.currentState("sunriseTime")?.dateValue
if (result && endTimeOffset) {
result = new Date(result.time + Math.round(endTimeOffset * 60000))
}
}
else if (endTimeType == "sunset") {
result = location.currentState("sunsetTime")?.dateValue
if (result && endTimeOffset) {
result = new Date(result.time + Math.round(endTimeOffset * 60000))
}
}
else if (ending) {
result = timeToday(ending, location.timeZone)
}
log.trace "timeWindowStop = ${result}"
result
}
private hhmm(time, fmt = "h:mm a")
{
def t = timeToday(time, location.timeZone)
def f = new java.text.SimpleDateFormat(fmt)
f.setTimeZone(location.timeZone ?: timeZone(time))
f.format(t)
}
private timeIntervalLabel() {
def start = ""
switch (startTimeType) {
case "time":
if (ending) {
start += hhmm(starting)
}
break
case "sunrise":
case "sunset":
start += startTimeType[0].toUpperCase() + startTimeType[1..-1]
if (startTimeOffset) {
start += startTimeOffset > 0 ? "+${startTimeOffset} min" : "${startTimeOffset} min"
}
break
}
def finish = ""
switch (endTimeType) {
case "time":
if (ending) {
finish += hhmm(ending)
}
break
case "sunrise":
case "sunset":
finish += endTimeType[0].toUpperCase() + endTimeType[1..-1]
if (endTimeOffset) {
finish += endTimeOffset > 0 ? "+${endTimeOffset} min" : "${endTimeOffset} min"
}
break
}
start && finish ? "${start} to ${finish}" : ""
}
def getLabel(value)
{
//Name Page
def str_NameChange=[
"kr": "이름을 변경 설정.",
"us": "Do you want to allow custom automation name?"
]
def str_NameAutomation=[
"kr": "이름을 변경 설정.",
"us": "Automation name"
]
def str_NameUser=[
"kr": "사용자 이름.",
"us": "Enter custom name"
]
def str_NamePageTitle=[
"kr": "자동화 룰 이름 설정",
"us": "Configure rule based on sleep sensor state"
]
///////////////////////////////////////////////////////////////////////////
//Main Page
def str_MainPageTitle=[
"kr": "슬립센서를 이용하여 자동화 룰을 만드세요.",
"us": "Configure rule based on sleep sensor state"
]
def str_SelectSense=[
"kr": "슬립센서를 선택하세요.",
"us": "Which sleep sensor?"
]
def str_SelectSleepTrigger=[
"kr": "트리거를 선택하세요.",
"us": "Select trigger."
]
def str_SelectLocation=[
"kr": "제어 방식을 선택하세요.",
"us": "What would you like to control?"
]
def str_HubofHomeWatch=[
"kr": "홈지키미의 상태",
"us": "The state of Smart Home Monitoring"
]
def str_HubofDevice=[
"kr": "의 디바이스",
"us": "The mode at "
]
def str_HubofMode=[
"kr": "의 모드",
"us": "A mode at "
]
def str_HubofRoutines=[
"kr": "의 루틴",
"us": "A routine at "
]
///////////////////////////////////////////////////////////////////////////
def str_RoutineTitle=[
"kr": "자동화 설정",
"us": "Routine Control"
]
def str_RoutineSelect=[
"kr": "자동화 룰을 선택하세요",
"us": "Run the routine..."
]
///////////////////////////////////////////////////////////////////////////
def strr_ModeTitle=[
"kr": "모드",
"us": "mode"
]
def str_ModeSelect=[
"kr": "모드 선택",
"us": "Change Mode to..."
]
///////////////////////////////////////////////////////////////////////////
def str_HomeWatchTitle=[
"kr": "홈지키미 모드 설정",
"us": "Home Watch Control"
]
def str_HomeWatchSectionSelect=[
"kr": "홈지키미 모드 상태 선택",
"us": "Set HomeWatch status to..."
]
///////////////////////////////////////////////////////////////////////////
def str_DeviceTitle=[
"kr": "기기 제어",
"us": "Device Control"
]
def str_DeviceSelect=[
"kr": "기기 선택",
"us": "Select device to control"
]
def str_DeviceSwitch=[
"kr": "스위치 및 디머",
"us": "Switches & Dimmers"
]
def str_DeviceCameras=[
"kr": "카메라",
"us": "Cameras"
]
def str_DeviceLocks=[
"kr": "자동 잠금 기기",
"us": "Locks"
]
def str_DeviceThermostats=[
"kr": "에어컨 및 온도 설정기",
"us": "Thermostats"
]
def str_DeviceAlarms=[
"kr": "알림 센서",
"us": "Alarms & Sirens"
]
def str_DeviceSpeaker=[
"kr": "스피커",
"us": "Speakers"
]
def str_DeviceLightsTitle=[
"kr": "동작 선택",
"us": "Lights will..."
]
def str_DeviceTurnOn=[
"kr": "켜기",
"us": "Turn On"
]
def str_DeviceTurnOff=[
"kr": "끄기",
"us": "Turn Off"
]
def str_DeviceLevel=[
"kr": "켜고 밝기 조정하기",
"us": "Turn On & Set Level"
]
def str_DeviceColor=[
"kr": "켜고 색상 조정하기",
"us": "Turn On & Set Color"
]
def str_DeviceSpeakerTitle=[
"kr": "동작 선택",
"us": "Speaker will..."
]
def str_AlarmWill=[
"kr": "알람이 발생했을때...",
"us": "Alarm will..."
]
def str_DeviceSpeakerPlae=[
"kr": "동작",
"us": "Play"
]
def str_DeviceSpeakerPause=[
"kr": "일시 정지",
"us": "Pause"
]
def str_DeviceSpeakerStop=[
"kr": "중지",
"us": "Stop"
]
def str_DeviceThermostatTitle=[
"kr": "동작 선택",
"us": "Thermostat will..."
]
def str_DeviceThermostatCool=[
"kr": "냉방 모드 설정",
"us": "Set cooling point & set mode to cool"
]
def str_DeviceThermostatHeat=[
"kr": "난방 모드 설정",
"us": "Set heating point & set mode to heat"
]
def str_DeviceThermostatCoolSet=[
"kr": "냉방 모드 온도 설정",
"us": "Set cooling point to..."
]
def str_DeviceThermostatHeatSet=[
"kr": "난방 모드 온도 설정",
"us": "Set heating point to..."
]
def str_CameraTitle=[
"kr": "동작 설정",
"us": "Camera will..."
]
def str_CameraTake=[
"kr": "사진 가져 오기",
"us": "Take a photo"
]
def str_LocksTitle=[
"kr": "동작 설정",
"us": "Lock will..."
]
def str_LocksLock=[
"kr": "잠그기",
"us": "Lock the door"
]
def str_LocksUnLock=[
"kr": "잠금 풀기",
"us": "Unlock the door"
]
///////////////////////////////////////////////////////////////////////////
def str_MoreOption=[
"kr": "추가 설정",
"us": "More options"
]
def str_TimeSet=[
"kr": "동작 시간 설정",
"us": "Only during a certain time"
]
def str_TimeStartingCondition=[
"kr": "시작 조건",
"us": "Starting at"
]
def str_TimeEngingCondition=[
"kr": "종료 조건",
"us": "Ending at"
]
def str_TimeSunrise=[
"kr": "해 질때",
"us": "At Sunrise"
]
def str_TimeSunset=[
"kr": "해 뜰때",
"us": "At Sunset"
]
def str_TimeSpecificTime=[
"kr": "사용자 설정",
"us": "At a Specific Time"
]
def str_TimeOffset=[
"kr": "오차 범위를 설정하세요.",
"us": "Offset in minutes (+/-)"
]
def str_TimeStart=[
"kr": "시작 시간",
"us": "Start time"
]
def str_TimeEnd=[
"kr": "종료 시간",
"us": "End time"
]
def str_WeekSet=[
"kr": "동작 요일을 선택하세요.",
"us": "Only on certain days of the week"
]
///////////////////////////////////////////////////////////////////////////
def str_Moreoption=[
"kr": "추가 설정",
"us": "More options"
]
def str_Monday=[
"kr": "월요일",
"us": "Monday"
]
def str_Tuesday=[
"kr": "화요일",
"us": "Tuesday"
]
def str_Wednesday=[
"kr": "수요일",
"us": "Wednesday"
]
def str_Thursday=[
"kr": "목요일",
"us": "Thursday"
]
def str_Friday=[
"kr": "금요일",
"us": "Friday"
]
def str_Saturday=[
"kr": "토요일",
"us": "Saturday"
]
def str_Sunday=[
"kr": "일요일",
"us": "Sunday"
]
///////////////////////////////////////////////////////////////////////////
def str_sleep=[
"kr": "잠 들었을때",
"us": "When I fall asleep"
]
def str_wake=[
"kr": "일어 났을때",
"us": "When I wake"
]
def str_inbed=[
"kr": "잠자리에 들었을때",
"us": "When I get in bed"
]
def str_outofbed=[
"kr": "잠자리에서 나왔을때",
"us": "When I get out of bed"
]
def str_Taptoset=[
"kr": "설정",
"us": "Tap to set"
]
if(clientLocale?.language == "ko")
{
switch(value)
{
case "str_MainPageTitle":
return str_MainPageTitle["kr"]
case "str_SelectSense":
return str_SelectSense["kr"]
case "str_SelectSleepTrigger":
return str_SelectSleepTrigger["kr"]
case "str_SelectLocation":
return str_SelectLocation["kr"]
case "str_HubofHomeWatch":
return str_HubofHomeWatch["kr"]
case "str_HubofMode":
return str_HubofMode["kr"]
case "str_HubofRoutines":
return str_HubofRoutines["kr"]
case "str_HubofDevice":
return str_HubofDevice["kr"]
case "str_RoutineTitle":
return str_RoutineTitle["kr"]
case "str_RoutineSelect":
return str_RoutineSelect["kr"]
case "str_TimeSet":
return str_TimeSet["kr"]
case "str_TimeStartingCondition":
return str_TimeStartingCondition["kr"]
case "str_TimeEngingCondition":
return str_TimeEngingCondition["kr"]
case "str_TimeSunrise":
return str_TimeSunrise["kr"]
case "str_TimeSunset":
return str_TimeSunset["kr"]
case "str_TimeSpecificTime":
return str_TimeSpecificTime["kr"]
case "str_TimeOffset":
return str_TimeOffset["kr"]
case "str_TimeStart":
return str_TimeStart["kr"]
case "str_TimeEnd":
return str_TimeEnd["kr"]
case "str_WeekSet":
return str_WeekSet["kr"]
case "str_NameChange":
return str_NameChange["kr"]
case "str_NameAutomation":
return str_NameAutomation["kr"]
case "str_NameUser":
return str_NameUser["kr"]
case "str_NamePageTitle":
return str_NamePageTitle["kr"]
case "str_DeviceTitle":
return str_DeviceTitle["kr"]
case "str_DeviceSelect":
return str_DeviceSelect["kr"]
case "str_DeviceLightsTitle":
return str_DeviceLightsTitle["kr"]
case "str_DeviceTurnOn":
return str_DeviceTurnOn["kr"]
case "str_DeviceTurnOff":
return str_DeviceTurnOff["kr"]
case "str_DeviceLevel":
return str_DeviceLevel["kr"]
case "str_DeviceColor":
return str_DeviceColor["kr"]
case "str_DeviceSpeakerTitle":
return str_DeviceSpeakerTitle["kr"]
case "str_AlarmWill":
return str_AlarmWill["kr"]
case "str_DeviceSpeakerPlae":
return str_DeviceSpeakerPlae["kr"]
case "str_DeviceSpeakerPause":
return str_DeviceSpeakerPause["kr"]
case "str_DeviceSpeakerStop":
return str_DeviceSpeakerStop["kr"]
case "str_DeviceSwitch":
return str_DeviceSwitch["kr"]
case "str_DeviceCameras":
return str_DeviceCameras["kr"]
case "str_DeviceLocks":
return str_DeviceLocks["kr"]
case "str_DeviceThermostats":
return str_DeviceThermostats["kr"]
case "str_DeviceAlarms":
return str_DeviceAlarms["kr"]
case "str_DeviceSpeaker":
return str_DeviceSpeaker["kr"]
case "str_DeviceThermostatTitle":
return str_DeviceThermostatTitle["kr"]
case "str_DeviceThermostatCool":
return str_DeviceThermostatCool["kr"]
case "str_DeviceThermostatHeat":
return str_DeviceThermostatHeat["kr"]
case "str_DeviceThermostatCoolSet":
return str_DeviceThermostatCoolSet["kr"]
case "str_DeviceThermostatHeatSet":
return str_DeviceThermostatHeatSet["kr"]
case "strr_ModeTitle":
return strr_ModeTitle["kr"]
case "str_ModeSelect":
return str_ModeSelect["kr"]
case "str_HomeWatchTitle":
return str_HomeWatchTitle["kr"]
case "str_HomeWatchSectionSelect":
return str_HomeWatchSectionSelect["kr"]
case "str_CameraTitle":
return str_CameraTitle["kr"]
case "str_CameraTake":
return str_CameraTake["kr"]
case "str_Moreoption":
return str_Moreoption["kr"]
case "str_Monday":
return str_Monday["kr"]
case "str_Tuesday":
return str_Tuesday["kr"]
case "str_Wednesday":
return str_Wednesday["kr"]
case "str_Thursday":
return str_Thursday["kr"]
case "str_Friday":
return str_Friday["kr"]
case "str_Saturday":
return str_Saturday["kr"]
case "str_Sunday":
return str_Sunday["kr"]
case "str_sleep":
return str_sleep["kr"]
case "str_wake":
return str_wake["kr"]
case "str_inbed":
return str_inbed["kr"]
case "str_outofbed":
return str_outofbed["kr"]
case "str_Taptoset":
return str_Taptoset["kr"]
}
}
else
{
switch(value)
{
case "str_MainPageTitle":
return str_MainPageTitle["us"]
case "str_SelectSense":
return str_SelectSense["us"]
case "str_SelectSleepTrigger":
return str_SelectSleepTrigger["us"]
case "str_SelectLocation":
return str_SelectLocation["us"]
case "str_HubofHomeWatch":
return str_HubofHomeWatch["us"]
case "str_HubofMode":
return str_HubofMode["us"]
case "str_HubofRoutines":
return str_HubofRoutines["us"]
case "str_HubofDevice":
return str_HubofDevice["us"]
case "str_RoutineTitle":
return str_RoutineTitle["us"]
case "str_RoutineSelect":
return str_RoutineSelect["us"]
case "str_TimeSet":
return str_TimeSet["us"]
case "str_TimeStartingCondition":
return str_TimeStartingCondition["us"]
case "str_TimeEngingCondition":
return str_TimeEngingCondition["us"]
case "str_TimeSunrise":
return str_TimeSunrise["us"]
case "str_TimeSunset":
return str_TimeSunset["us"]
case "str_TimeSpecificTime":
return str_TimeSpecificTime["us"]
case "str_TimeOffset":
return str_TimeOffset["us"]
case "str_TimeStart":
return str_TimeStart["us"]
case "str_TimeEnd":
return str_TimeEnd["us"]
case "str_WeekSet":
return str_WeekSet["us"]
case "str_NameChange":
return str_NameChange["us"]
case "str_NameAutomation":
return str_NameAutomation["us"]
case "str_NameUser":
return str_NameUser["us"]
case "str_NamePageTitle":
return str_NamePageTitle["us"]
case "str_DeviceTitle":
return str_DeviceTitle["us"]
case "str_DeviceSelect":
return str_DeviceSelect["us"]
case "str_DeviceLightsTitle":
return str_DeviceLightsTitle["us"]
case "str_DeviceTurnOn":
return str_DeviceTurnOn["us"]
case "str_DeviceTurnOff":
return str_DeviceTurnOff["us"]
case "str_DeviceLevel":
return str_DeviceLevel["us"]
case "str_DeviceColor":
return str_DeviceColor["us"]
case "str_DeviceSpeakerTitle":
return str_DeviceSpeakerTitle["us"]
case "str_AlarmWill":
return str_AlarmWill["us"]
case "str_DeviceSpeakerPlae":
return str_DeviceSpeakerPlae["us"]
case "str_DeviceSpeakerPause":
return str_DeviceSpeakerPause["us"]
case "str_DeviceSpeakerStop":
return str_DeviceSpeakerStop["us"]
case "str_DeviceSwitch":
return str_DeviceSwitch["us"]
case "str_DeviceCameras":
return str_DeviceCameras["us"]
case "str_DeviceLocks":
return str_DeviceLocks["us"]
case "str_DeviceThermostats":
return str_DeviceThermostats["us"]
case "str_DeviceAlarms":
return str_DeviceAlarms["us"]
case "str_DeviceSpeaker":
return str_DeviceSpeaker["us"]
case "str_DeviceThermostatTitle":
return str_DeviceThermostatTitle["us"]
case "str_DeviceThermostatCool":
return str_DeviceThermostatCool["us"]
case "str_DeviceThermostatHeat":
return str_DeviceThermostatHeat["us"]
case "str_DeviceThermostatCoolSet":
return str_DeviceThermostatCoolSet["us"]
case "str_DeviceThermostatHeatSet":
return str_DeviceThermostatHeatSet["us"]
case "strr_ModeTitle":
return strr_ModeTitle["us"]
case "str_ModeSelect":
return str_ModeSelect["us"]
case "str_HomeWatchTitle":
return str_HomeWatchTitle["us"]
case "str_HomeWatchSectionSelect":
return str_HomeWatchSectionSelect["us"]
case "str_CameraTitle":
return str_CameraTitle["us"]
case "str_CameraTake":
return str_CameraTake["us"]
case "str_Moreoption":
return str_Moreoption["us"]
case "str_Monday":
return str_Monday["us"]
case "str_Tuesday":
return str_Tuesday["us"]
case "str_Wednesday":
return str_Wednesday["us"]
case "str_Thursday":
return str_Thursday["us"]
case "str_Friday":
return str_Friday["us"]
case "str_Saturday":
return str_Saturday["us"]
case "str_Sunday":
return str_Sunday["us"]
case "str_sleep":
return str_sleep["us"]
case "str_wake":
return str_wake["us"]
case "str_inbed":
return str_inbed["us"]
case "str_outofbed":
return str_outofbed["us"]
case "str_Taptoset":
return str_Taptoset["us"]
}
}
return "Unknown"
}