Compare commits

..

1 Commits

Author SHA1 Message Date
Will Cole
801944e689 MSA-1733: This application allows a user to set up from 1 to 5 lighting scenes, controlled by momentary switches. The switches could be physical momentary wall switches, or virtual switches created in the IDE.
The lighting scene options include setting color hue and saturation for color-changing bulbs, & lighting level and color temperature for color temperature bulbs (which includes color-changing bulbs as well). A 'scene' can change any or all of the parameters. As an example, 'Movie Scene' could set the lighting level on all lights to 25%, the color temperature for color temp bulbs to 2700k, and leave the colors alone; while 'Full Bright' could set the color temperature to 5500k and brightness to 100% for all bulbs. 'Green' mode could set the hue/saturation of color bulbs to full green, while leaving brightness levels as is, or could set the brightness to a different level at the same time.
2017-01-23 14:41:25 -08:00
16 changed files with 651 additions and 191 deletions

View File

@@ -1,46 +0,0 @@
/**
* Stateless On/Off Button Tile
*
* Author: Ronald Gouldner
*
* Date: 2015-05-14
*/
metadata {
// Automatically generated. Make future change here.
definition (name: "Stateless On-Off Button Tile", namespace: "gouldner", author: "Ronald Gouldner") {
capability "Actuator"
capability "Switch"
capability "Sensor"
}
// simulator metadata
simulator {
}
// UI tile definitions
tiles {
standardTile("button", "device.switch", width: 2, height: 2, canChangeIcon: true) {
state "offReady", label: 'Off', action: "switch.on", icon: "st.switches.switch.off", backgroundColor: "#ffffff", nextState: "onReady"
state "onReady", label: 'On', action: "switch.off", icon: "st.switches.switch.on", backgroundColor: "#79b821", nextState: "offReady"
state "off", label: 'Off', action: "switch.on", icon: "st.switches.switch.off", backgroundColor: "#ffffff"
state "on", label: 'On', action: "switch.off", icon: "st.switches.switch.on", backgroundColor: "#79b821"
}
main "button"
details "button"
}
}
def parse(String description) {
}
def on() {
log.debug "Stateless On/Off Button Tile Virtual Switch ${device.name} turned on"
sendEvent(name: "switch", value: "on")
sendEvent(name: "switch", value: "onReady")
}
def off() {
log.debug "Stateless On/Off Button Tile Virtual Switch ${device.name} turned off"
sendEvent(name: "switch", value: "off")
sendEvent(name: "switch", value: "offReady")
}

View File

@@ -82,7 +82,7 @@ def on() {
}
def setLevel(value) {
zigbee.setLevel(value) + zigbee.onOffRefresh() + zigbee.levelRefresh() //adding refresh because of ZLL bulb not conforming to send-me-a-report
zigbee.setLevel(value) + ["delay 500"] + zigbee.levelRefresh() //adding refresh because of ZLL bulb not conforming to send-me-a-report
}
/**

View File

@@ -17,7 +17,6 @@ metadata {
capability "Refresh"
capability "Sensor"
capability "Health Check"
capability "Light"
command "setAdjustedColor"
command "reset"

View File

@@ -18,7 +18,6 @@ metadata {
capability "Refresh"
capability "Sensor"
capability "Health Check"
capability "Light"
command "setAdjustedColor"
command "reset"

View File

@@ -14,8 +14,7 @@ metadata {
capability "Switch"
capability "Refresh"
capability "Sensor"
capability "Health Check"
capability "Light"
capability "Health Check"
command "refresh"
}

View File

@@ -16,7 +16,6 @@ metadata {
capability "Switch"
capability "Refresh"
capability "Health Check"
capability "Light"
command "refresh"
}

View File

@@ -12,7 +12,7 @@
*
*/
metadata {
definition (name: "Simulated Switch", namespace: "smartthings/testing", author: "bob") {
capability "Switch"
capability "Relay Switch"
@@ -39,7 +39,9 @@ metadata {
}
}
def parse(description) {
def parse(String description) {
def pair = description.split(":")
createEvent(name: pair[0].trim(), value: pair[1].trim())
}
def on() {

View File

@@ -28,10 +28,6 @@ metadata {
fingerprint profileId: "0104", inClusters: "0000, 0003, 0004, 0005, 0006, 0008, 0B05", outClusters: "0019", manufacturer: "OSRAM SYLVANIA", model: "iQBR30", deviceJoinName: "Sylvania Ultra iQ"
fingerprint profileId: "0104", inClusters: "0000, 0003, 0004, 0005, 0006, 0008, FC0F", outClusters: "0019", manufacturer: "OSRAM", model: "LIGHTIFY PAR38 ON/OFF/DIM", deviceJoinName: "SYLVANIA Smart PAR38 Soft White"
fingerprint profileId: "0104", inClusters: "0000, 0003, 0004, 0005, 0006, 0008, 0B04, FC0F", outClusters: "0019", manufacturer: "OSRAM", model: "LIGHTIFY BR ON/OFF/DIM", deviceJoinName: "SYLVANIA Smart BR30 Soft White"
fingerprint profileId: "0104", inClusters: "0000, 0003, 0004, 0005, 0006, 0008, 0702, 0B05", outClusters: "0019", manufacturer: "sengled", model: "E11-G13", deviceJoinName: "Sengled Element Classic"
fingerprint profileId: "0104", inClusters: "0000, 0003, 0004, 0005, 0006, 0008", outClusters: "0003, 0006, 0008, 0019, 0406", manufacturer: "Leviton", model: "DL6HD", deviceJoinName: "Leviton Dimmer Switch"
fingerprint profileId: "0104", inClusters: "0000, 0003, 0004, 0005, 0006, 0008", outClusters: "0003, 0006, 0008, 0019, 0406", manufacturer: "Leviton", model: "DL3HL", deviceJoinName: "Leviton Lumina RF Plug-In Dimmer"
fingerprint profileId: "0104", inClusters: "0000, 0003, 0004, 0005, 0006, 0008", outClusters: "0003, 0006, 0008, 0019, 0406", manufacturer: "Leviton", model: "DL1KD", deviceJoinName: "Leviton Lumina RF Dimmer Switch"
}
tiles(scale: 2) {

View File

@@ -22,7 +22,6 @@ metadata {
fingerprint profileId: "0104", inClusters: "0000, 0003, 0004, 0005, 0006"
fingerprint profileId: "0104", inClusters: "0000, 0003, 0006", outClusters: "0003, 0006, 0019, 0406", manufacturer: "Leviton", model: "ZSS-10", deviceJoinName: "Leviton Switch"
fingerprint profileId: "0104", inClusters: "0000, 0003, 0006", outClusters: "000A", manufacturer: "HAI", model: "65A21-1", deviceJoinName: "Leviton Wireless Load Control Module-30amp"
fingerprint profileId: "0104", inClusters: "0000, 0003, 0004, 0005, 0006", outClusters: "0003, 0006, 0008, 0019, 0406", manufacturer: "Leviton", model: "DL15A", deviceJoinName: "Leviton Lumina RF Plug-In Appliance Module"
}
// simulator metadata

View File

@@ -89,7 +89,7 @@ def on() {
}
def setLevel(value) {
zigbee.setLevel(value) + zigbee.onOffRefresh() + zigbee.levelRefresh() //adding refresh because of ZLL bulb not conforming to send-me-a-report
zigbee.setLevel(value) + ["delay 1500"] + zigbee.levelRefresh() //adding refresh because of ZLL bulb not conforming to send-me-a-report
}
def refresh() {

View File

@@ -115,7 +115,7 @@ def refreshAttributes() {
}
def setLevel(value) {
zigbee.setLevel(value) + zigbee.onOffRefresh() + zigbee.levelRefresh() //adding refresh because of ZLL bulb not conforming to send-me-a-report
zigbee.setLevel(value) + ["delay 1500"] + zigbee.levelRefresh() //adding refresh because of ZLL bulb not conforming to send-me-a-report
}
def setColor(value){

View File

@@ -135,7 +135,7 @@ def setColorTemperature(value) {
}
def setLevel(value) {
zigbee.setLevel(value) + zigbee.onOffRefresh() + zigbee.levelRefresh() //adding refresh because of ZLL bulb not conforming to send-me-a-report
zigbee.setLevel(value) + ["delay 1500"] + zigbee.levelRefresh() //adding refresh because of ZLL bulb not conforming to send-me-a-report
}
def setColor(value){

View File

@@ -90,7 +90,7 @@ def on() {
}
def setLevel(value) {
zigbee.setLevel(value) + zigbee.onOffRefresh() + zigbee.levelRefresh()
zigbee.setLevel(value) + ["delay 1500"] + zigbee.levelRefresh()
}
def refresh() {

View File

@@ -73,7 +73,7 @@ def authPage() {
return dynamicPage(name: "Credentials", title: "Authorize Connection", nextPage:"listDevices", uninstall: uninstallAllowed, install:false) {
section() {
paragraph "Tap below to log in to the netatmo and authorize SmartThings access."
href url:redirectUrl, style:"embedded", required:false, title:"Connect to ${getVendorName()}", description:description
href url:redirectUrl, style:"embedded", required:false, title:"Connect to ${getVendorName()}:", description:description
}
}
} else {
@@ -146,24 +146,19 @@ def callback() {
// log.debug "PARAMS: ${params}"
try {
httpPost(params) { resp ->
httpPost(params) { resp ->
def slurper = new JsonSlurper()
def slurper = new JsonSlurper()
resp.data.each { key, value ->
def data = slurper.parseText(key)
log.debug "Data: $data"
state.refreshToken = data.refresh_token
state.authToken = data.access_token
//state.accessToken = data.access_token
state.tokenExpires = now() + (data.expires_in * 1000)
// log.debug "swapped token: $resp.data"
}
}
} catch (Exception e) {
log.debug "callback: Call failed $e"
}
resp.data.each { key, value ->
def data = slurper.parseText(key)
state.refreshToken = data.refresh_token
state.authToken = data.access_token
state.tokenExpires = now() + (data.expires_in * 1000)
// log.debug "swapped token: $resp.data"
}
}
// Handle success and failure here, and render stuff accordingly
if (state.authToken) {
@@ -392,18 +387,18 @@ def getDeviceList() {
state.deviceDetail = [:]
state.deviceState = [:]
apiGet("/api/getstationsdata") { response ->
apiGet("/api/devicelist") { response ->
response.data.body.devices.each { value ->
def key = value._id
deviceList[key] = "${value.station_name}: ${value.module_name}"
state.deviceDetail[key] = value
state.deviceState[key] = value.dashboard_data
value.modules.each { value2 ->
def key2 = value2._id
deviceList[key2] = "${value.station_name}: ${value2.module_name}"
state.deviceDetail[key2] = value2
state.deviceState[key2] = value2.dashboard_data
}
}
response.data.body.modules.each { value ->
def key = value._id
deviceList[key] = "${state.deviceDetail[value.main_device].station_name}: ${value.module_name}"
state.deviceDetail[key] = value
state.deviceState[key] = value.dashboard_data
}
}
@@ -453,7 +448,6 @@ def listDevices() {
}
def apiGet(String path, Map query, Closure callback) {
if(now() >= state.tokenExpires) {
refreshToken();
}
@@ -473,16 +467,12 @@ def apiGet(String path, Map query, Closure callback) {
} catch (Exception e) {
// This is most likely due to an invalid token. Try to refresh it and try again.
log.debug "apiGet: Call failed $e"
if(refreshToken()) {
log.debug "apiGet: Trying again after refreshing token"
try {
httpGet(params) { response ->
callback.call(response)
}
} catch (Exception f) {
log.debug "apiGet: Call failed $f"
}
}
if(refreshToken()) {
log.debug "apiGet: Trying again after refreshing token"
httpGet(params) { response ->
callback.call(response)
}
}
}
}
@@ -571,4 +561,4 @@ private Boolean hasAllHubsOver(String desiredFirmware) {
private List getRealHubFirmwareVersions() {
return location.hubs*.firmwareVersionString.findAll { it }
}
}

View File

@@ -57,7 +57,7 @@ def authPage(){
atomicState.accessToken = state.accessToken
}
def redirectUrl = oauthInitUrl()
def redirectUrl = oauthInitUrl()
def uninstallAllowed = false
def oauthTokenProvided = false
if(atomicState.authToken){
@@ -78,9 +78,9 @@ def authPage(){
}
}else{
return dynamicPage(name: "auth", title: "Step 1 of 2 - Completed", nextPage:"deviceList", uninstall:uninstallAllowed) {
section(){
section(){
paragraph "You are logged in to myplantlink.com, tap next to continue", image: iconUrl
href(url:redirectUrl, title:"Or", description:"tap to switch accounts")
href(url:redirectUrl, title:"Or", description:"tap to switch accounts")
}
}
}
@@ -137,44 +137,36 @@ def dock_sensor(device_serial, expected_plant_name) {
contentType: "application/json",
]
log.debug "Creating new plant on myplantlink.com - ${expected_plant_name}"
try {
httpPost(docking_params) { docking_response ->
if (parse_api_response(docking_response, "Docking a link")) {
if (docking_response.data.plants.size() == 0) {
log.debug "creating plant for - ${expected_plant_name}"
plant_post_body_map["name"] = expected_plant_name
plant_post_body_map['links_key'] = [docking_response.data.key]
def plant_post_body_json_builder = new JsonBuilder(plant_post_body_map)
plant_post_params["body"] = plant_post_body_json_builder.toString()
try {
httpPost(plant_post_params) { plant_post_response ->
if(parse_api_response(plant_post_response, 'creating plant')){
def attached_map = atomicState.attached_sensors
attached_map[device_serial] = plant_post_response.data
atomicState.attached_sensors = attached_map
}
}
} catch (Exception f) {
log.debug "call failed $f"
httpPost(docking_params) { docking_response ->
if (parse_api_response(docking_response, "Docking a link")) {
if (docking_response.data.plants.size() == 0) {
log.debug "creating plant for - ${expected_plant_name}"
plant_post_body_map["name"] = expected_plant_name
plant_post_body_map['links_key'] = [docking_response.data.key]
def plant_post_body_json_builder = new JsonBuilder(plant_post_body_map)
plant_post_params["body"] = plant_post_body_json_builder.toString()
httpPost(plant_post_params) { plant_post_response ->
if(parse_api_response(plant_post_response, 'creating plant')){
def attached_map = atomicState.attached_sensors
attached_map[device_serial] = plant_post_response.data
atomicState.attached_sensors = attached_map
}
} else {
def plant = docking_response.data.plants[0]
def attached_map = atomicState.attached_sensors
attached_map[device_serial] = plant
atomicState.attached_sensors = attached_map
checkAndUpdatePlantIfNeeded(plant, expected_plant_name)
}
} else {
def plant = docking_response.data.plants[0]
def attached_map = atomicState.attached_sensors
attached_map[device_serial] = plant
atomicState.attached_sensors = attached_map
checkAndUpdatePlantIfNeeded(plant, expected_plant_name)
}
}
} catch (Exception e) {
log.debug "call failed $e"
}
return true
}
def checkAndUpdatePlantIfNeeded(plant, expected_plant_name){
def plant_put_params = [
uri : appSettings.https_plantLinkServer,
uri : appSettings.https_plantLinkServer,
headers : ["Content-Type": "application/json", "Authorization": "Bearer ${atomicState.authToken}"],
contentType : "application/json"
]
@@ -182,16 +174,12 @@ def checkAndUpdatePlantIfNeeded(plant, expected_plant_name){
log.debug "updating plant for - ${expected_plant_name}"
plant_put_params["path"] = "/api/v1/plants/${plant.key}"
def plant_put_body_map = [
name: expected_plant_name
name: expected_plant_name
]
def plant_put_body_json_builder = new JsonBuilder(plant_put_body_map)
plant_put_params["body"] = plant_put_body_json_builder.toString()
try {
httpPut(plant_put_params) { plant_put_response ->
parse_api_response(plant_put_response, 'updating plant name')
}
} catch (Exception e) {
log.debug "call failed $e"
httpPut(plant_put_params) { plant_put_response ->
parse_api_response(plant_put_response, 'updating plant name')
}
}
}
@@ -210,29 +198,25 @@ def moistureHandler(event){
contentType: "application/json",
body: event.value
]
try {
httpPost(measurement_post_params) { measurement_post_response ->
if (parse_api_response(measurement_post_response, 'creating moisture measurement') &&
measurement_post_response.data.size() >0){
def measurement = measurement_post_response.data[0]
def plant = measurement.plant
log.debug plant
checkAndUpdatePlantIfNeeded(plant, expected_plant_name)
plantlinksensors.each{ sensor_device ->
if (sensor_device.id == event.deviceId){
sensor_device.setStatusIcon(plant.status)
if (plant.last_measurements && plant.last_measurements[0].moisture){
sensor_device.setPlantFuelLevel(plant.last_measurements[0].moisture * 100 as int)
}
if (plant.last_measurements && plant.last_measurements[0].battery){
sensor_device.setBatteryLevel(plant.last_measurements[0].battery * 100 as int)
}
httpPost(measurement_post_params) { measurement_post_response ->
if (parse_api_response(measurement_post_response, 'creating moisture measurement') &&
measurement_post_response.data.size() >0){
def measurement = measurement_post_response.data[0]
def plant = measurement.plant
log.debug plant
checkAndUpdatePlantIfNeeded(plant, expected_plant_name)
plantlinksensors.each{ sensor_device ->
if (sensor_device.id == event.deviceId){
sensor_device.setStatusIcon(plant.status)
if (plant.last_measurements && plant.last_measurements[0].moisture){
sensor_device.setPlantFuelLevel(plant.last_measurements[0].moisture * 100 as int)
}
if (plant.last_measurements && plant.last_measurements[0].battery){
sensor_device.setBatteryLevel(plant.last_measurements[0].battery * 100 as int)
}
}
}
}
} catch (Exception e) {
log.debug "call failed $e"
}
}
}
@@ -251,12 +235,8 @@ def batteryHandler(event){
contentType: "application/json",
body: event.value
]
try {
httpPost(measurement_post_params) { measurement_post_response ->
parse_api_response(measurement_post_response, 'creating battery measurement')
}
} catch (Exception e) {
log.debug "call failed $e"
httpPost(measurement_post_params) { measurement_post_response ->
parse_api_response(measurement_post_response, 'creating battery measurement')
}
}
}
@@ -268,7 +248,7 @@ def getDeviceSerialFromEvent(event){
}
def oauthInitUrl(){
atomicState.oauthInitState = UUID.randomUUID().toString()
atomicState.oauthInitState = UUID.randomUUID().toString()
def oauthParams = [
response_type: "code",
client_id: appSettings.client_id,
@@ -295,12 +275,8 @@ def swapToken(){
]
def jsonMap
try {
httpPost(postParams) { resp ->
jsonMap = resp.data
}
} catch (Exception e) {
log.debug "call failed $e"
httpPost(postParams) { resp ->
jsonMap = resp.data
}
atomicState.refreshToken = jsonMap.refresh_token
@@ -311,33 +287,33 @@ def swapToken(){
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
.container {
padding:25px;
}
.flex1 {
width:33%;
float:left;
text-align: center;
}
p {
font-size: 2em;
font-family: Verdana, Geneva, sans-serif;
text-align: center;
color: #777;
}
.container {
padding:25px;
}
.flex1 {
width:33%;
float:left;
text-align: center;
}
p {
font-size: 2em;
font-family: Verdana, Geneva, sans-serif;
text-align: center;
color: #777;
}
</style>
</head>
<body>
<div class="container">
<div class="flex1"><img src="https://dashboard.myplantlink.com/images/PLlogo.png" alt="PlantLink" height="75"/></div>
<div class="flex1"><img src="https://s3.amazonaws.com/smartapp-icons/Partner/support/connected-device-icn%402x.png" alt="connected to" height="25" style="padding-top:25px;" /></div>
<div class="flex1"><img src="https://s3.amazonaws.com/smartapp-icons/Partner/support/st-logo%402x.png" alt="SmartThings" height="75"/></div>
<br clear="all">
<div class="container">
<div class="flex1"><img src="https://dashboard.myplantlink.com/images/PLlogo.png" alt="PlantLink" height="75"/></div>
<div class="flex1"><img src="https://s3.amazonaws.com/smartapp-icons/Partner/support/connected-device-icn%402x.png" alt="connected to" height="25" style="padding-top:25px;" /></div>
<div class="flex1"><img src="https://s3.amazonaws.com/smartapp-icons/Partner/support/st-logo%402x.png" alt="SmartThings" height="75"/></div>
<br clear="all">
</div>
<div class="container">
<p>Your PlantLink Account is now connected to SmartThings!</p>
<p style="color:green;">Click <strong>Done</strong> at the top right to finish setup.</p>
</div>
<p>Your PlantLink Account is now connected to SmartThings!</p>
<p style="color:green;">Click <strong>Done</strong> at the top right to finish setup.</p>
</div>
</body>
</html>
"""

View File

@@ -0,0 +1,547 @@
/**
* Switches Control Light Scenes
*
* Copyright 2017 Will Cole
*
* 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: "Control Light Scenes",
namespace: "triosniolin",
author: "Will Cole",
description: "Using switches, control scenes for light(s).",
category: "Convenience",
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 {
page(name: "page1")
page(name: "page2")
page(name: "page3")
page(name: "page4")
page(name: "page5")
page(name: "page6")
}
def page1() {
dynamicPage(name: "page1", title: "Select devices:", nextPage: "page2", uninstall:true) {
section("Number of Scenes (such as on, off, movie, party)") {
input "scenes", "number",
title: "Number of Scenes (1-5)",
range: "1..5",
defaultValue: "3",
required: true,
submitOnChange: true
}
section("Device(s) to control") {
input "colors", "capability.colorControl",
multiple: true,
title: "Slave Color bulb(s)...",
required: false,
hideWhenEmpty: true
input "slaves", "capability.colorTemperature",
multiple: true,
title: "Slave Temp bulb(s)...",
required: true
}
}
}
def page2() {
def i = 1
if (scenes > i) {
dynamicPage(name: "page2", title: "Select Scene $i", nextPage: "page3") {
section("Scene $i") {
input "switch$i", "capability.switch",
multiple: false,
title: "Switch To Enable Scene $i",
required: true
}
section("Scene $i Color Temp") {
input "Temp$i", "number",
title: "Scene $i Color Temp (Kelvin) (2700-6500)",
range: "2700..6500",
defaultValue: "",
required: false
}
section("Scene $i Level") {
input "Dim$i", "number",
title: "Scene $i Dim Level (0-100%)",
range: "0..100",
defaultValue: "",
required: false
}
if (colors) {
section("Scene $i Hue") {
input "Hue$i", "number",
title: "Scene $i Hue (0-100)",
range: "0..100",
defaultValue: "",
required: false
}
section("Scene $i Saturation") {
input "Sat$i", "number",
title: "Scene $i Saturation (0-100)",
range: "0..100",
defaultValue: "",
required: false
}
}
}
} else {
dynamicPage(name: "page2", title: "Select Scene $i", install:true) {
section("Scene $i") {
input "switch$i", "capability.switch",
multiple: false,
title: "Switch To Enable Scene $i",
required: true
}
section("Scene $i Color Temp") {
input "Temp$i", "number",
title: "Scene $i Color Temp (Kelvin) (2700-6500)",
range: "2700..6500",
defaultValue: "",
required: false
}
section("Scene $i Level") {
input "Dim$i", "number",
title: "Scene $i Dim Level (0-100%)",
range: "0..100",
defaultValue: "",
required: false
}
if (colors) {
section("Scene $i Hue") {
input "Hue$i", "number",
title: "Scene $i Hue (0-100)",
range: "0..100",
defaultValue: "",
required: false
}
section("Scene $i Saturation") {
input "Sat$i", "number",
title: "Scene $i Saturation (0-100)",
range: "0..100",
defaultValue: "",
required: false
}
}
}
}
}
def page3() {
def i = 2
if (scenes > i) {
dynamicPage(name: "page3", title: "Select Scene $i", nextPage: "page4") {
section("Scene $i") {
input "switch$i", "capability.switch",
multiple: false,
title: "Switch To Enable Scene $i",
required: true
}
section("Scene $i Color Temp") {
input "Temp$i", "number",
title: "Scene $i Color Temp (Kelvin) (2700-6500)",
range: "2700..6500",
defaultValue: "",
required: false
}
section("Scene $i Level") {
input "Dim$i", "number",
title: "Scene $i Dim Level (0-100%)",
range: "0..100",
defaultValue: "",
required: false
}
if (colors) {
section("Scene $i Hue") {
input "Hue$i", "number",
title: "Scene $i Hue (0-100)",
range: "0..100",
defaultValue: "",
required: false
}
section("Scene $i Saturation") {
input "Sat$i", "number",
title: "Scene $i Saturation (0-100)",
range: "0..100",
defaultValue: "",
required: false
}
}
}
} else {
dynamicPage(name: "page3", title: "Select Scene $i", install:true) {
section("Scene $i") {
input "switch$i", "capability.switch",
multiple: false,
title: "Switch To Enable Scene $i",
required: true
}
section("Scene $i Color Temp") {
input "Temp$i", "number",
title: "Scene $i Color Temp (Kelvin) (2700-6500)",
range: "2700..6500",
defaultValue: "",
required: false
}
section("Scene $i Level") {
input "Dim$i", "number",
title: "Scene $i Dim Level (0-100%)",
range: "0..100",
defaultValue: "",
required: false
}
if (colors) {
section("Scene $i Hue") {
input "Hue$i", "number",
title: "Scene $i Hue (0-100)",
range: "0..100",
defaultValue: "",
required: false
}
section("Scene $i Saturation") {
input "Sat$i", "number",
title: "Scene $i Saturation (0-100)",
range: "0..100",
defaultValue: "",
required: false
}
}
}
}
}
def page4() {
def i = 3
if (scenes > i) {
dynamicPage(name: "page4", title: "Select Scene $i", nextPage: "page5") {
section("Scene $i") {
input "switch$i", "capability.switch",
multiple: false,
title: "Switch To Enable Scene $i",
required: true
}
section("Scene $i Color Temp") {
input "Temp$i", "number",
title: "Scene $i Color Temp (Kelvin) (2700-6500)",
range: "2700..6500",
defaultValue: "",
required: false
}
section("Scene $i Level") {
input "Dim$i", "number",
title: "Scene $i Dim Level (0-100%)",
range: "0..100",
defaultValue: "",
required: false
}
if (colors) {
section("Scene $i Hue") {
input "Hue$i", "number",
title: "Scene $i Hue (0-100)",
range: "0..100",
defaultValue: "",
required: false
}
section("Scene $i Saturation") {
input "Sat$i", "number",
title: "Scene $i Saturation (0-100)",
range: "0..100",
defaultValue: "",
required: false
}
}
}
} else {
dynamicPage(name: "page4", title: "Select Scene $i", install:true) {
section("Scene $i") {
input "switch$i", "capability.switch",
multiple: false,
title: "Switch To Enable Scene $i",
required: true
}
section("Scene $i Color Temp") {
input "Temp$i", "number",
title: "Scene $i Color Temp (Kelvin) (2700-6500)",
range: "2700..6500",
defaultValue: "",
required: false
}
section("Scene $i Level") {
input "Dim$i", "number",
title: "Scene $i Dim Level (0-100%)",
range: "0..100",
defaultValue: "",
required: false
}
if (colors) {
section("Scene $i Hue") {
input "Hue$i", "number",
title: "Scene $i Hue (0-100)",
range: "0..100",
defaultValue: "",
required: false
}
section("Scene $i Saturation") {
input "Sat$i", "number",
title: "Scene $i Saturation (0-100)",
range: "0..100",
defaultValue: "",
required: false
}
}
}
}
}
def page5() {
def i = 4
if (scenes > i) {
dynamicPage(name: "page5", title: "Select Scene $i", nextPage: "page6") {
section("Scene $i") {
input "switch$i", "capability.switch",
multiple: false,
title: "Switch To Enable Scene $i",
required: true
}
section("Scene $i Color Temp") {
input "Temp$i", "number",
title: "Scene $i Color Temp (Kelvin) (2700-6500)",
range: "2700..6500",
defaultValue: "",
required: false
}
section("Scene $i Level") {
input "Dim$i", "number",
title: "Scene $i Dim Level (0-100%)",
range: "0..100",
defaultValue: "",
required: false
}
if (colors) {
section("Scene $i Hue") {
input "Hue$i", "number",
title: "Scene $i Hue (0-100)",
range: "0..100",
defaultValue: "",
required: false
}
section("Scene $i Saturation") {
input "Sat$i", "number",
title: "Scene $i Saturation (0-100)",
range: "0..100",
defaultValue: "",
required: false
}
}
}
} else {
dynamicPage(name: "page5", title: "Select Scene $i", install:true) {
section("Scene $i") {
input "switch$i", "capability.switch",
multiple: false,
title: "Switch To Enable Scene $i",
required: true
}
section("Scene $i Color Temp") {
input "Temp$i", "number",
title: "Scene $i Color Temp (Kelvin) (2700-6500)",
range: "2700..6500",
defaultValue: "",
required: false
}
section("Scene $i Level") {
input "Dim$i", "number",
title: "Scene $i Dim Level (0-100%)",
range: "0..100",
defaultValue: "",
required: false
}
if (colors) {
section("Scene $i Hue") {
input "Hue$i", "number",
title: "Scene $i Hue (0-100)",
range: "0..100",
defaultValue: "",
required: false
}
section("Scene $i Saturation") {
input "Sat$i", "number",
title: "Scene $i Saturation (0-100)",
range: "0..100",
defaultValue: "",
required: false
}
}
}
}
}
def page6() {
def i = 5
dynamicPage(name: "page6", title: "Select Scene $i", install:true) {
section("Scene $i") {
input "switch$i", "capability.switch",
multiple: false,
title: "Switch To Enable Scene $i",
required: true
}
section("Scene $i Color Temp") {
input "Temp$i", "number",
title: "Scene $i Color Temp (Kelvin) (2700-6500)",
range: "2700..6500",
defaultValue: "",
required: false
}
section("Scene $i Level") {
input "Dim$i", "number",
title: "Scene $i Dim Level (0-100%)",
range: "0..100",
defaultValue: "",
required: false
}
if (colors) {
section("Scene $i Hue") {
input "Hue$i", "number",
title: "Scene $i Hue (0-100)",
range: "0..100",
defaultValue: "",
required: false
}
section("Scene $i Saturation") {
input "Sat$i", "number",
title: "Scene $i Saturation (0-100)",
range: "0..100",
defaultValue: "",
required: false
}
}
}
}
def installed()
{
if (switch1) {
subscribe (switch1, "switch.on", switch1Handler)
}
if (switch2) {
subscribe (switch2, "switch.on", switch2Handler)
}
if (switch3) {
subscribe (switch3, "switch.on", switch3Handler)
}
if (switch4) {
subscribe (switch4, "switch.on", switch4Handler)
}
if (switch5) {
subscribe (switch5, "switch.on", switch5Handler)
}
}
def updated()
{
unsubscribe()
if (switch1) {
subscribe (switch1, "switch.on", switch1Handler)
}
if (switch2) {
subscribe (switch2, "switch.on", switch2Handler)
}
if (switch3) {
subscribe (switch3, "switch.on", switch3Handler)
}
if (switch4) {
subscribe (switch4, "switch.on", switch4Handler)
}
if (switch5) {
subscribe (switch5, "switch.on", switch5Handler)
}
log.info "subscribed to all of switches events"
}
def switch1Handler(evt){
log.info "switch1Handler Event: ${evt.value}"
if (colors) {
if (Temp1) { slaves?.setColorTemperature(Temp1)
colors?.setColorTemperature(Temp1) }
if (Dim1) { slaves?.setLevel(Dim1)
colors?.setLevel(Dim1) }
if (Hue1) { colors?.setHue(Hue1) }
if (Sat1) { colors?.setSaturation(Sat1) }
} else {
if (Temp1) { slaves?.setColorTemperature(Temp1) }
if (Dim1) { slaves?.setLevel(Dim1) }
}
}
def switch2Handler(evt){
log.info "switch2Handler Event: ${evt.value}"
if (colors) {
if (Temp2) { slaves?.setColorTemperature(Temp2)
colors?.setColorTemperature(Temp2) }
if (Dim2) { slaves?.setLevel(Dim2)
colors?.setLevel(Dim2) }
if (Hue2) { colors?.setHue(Hue2) }
if (Sat2) { colors?.setSaturation(Sat2) }
} else {
if (Temp2) { slaves?.setColorTemperature(Temp2) }
if (Dim2) { slaves?.setLevel(Dim2) }
}
}
def switch3Handler(evt){
log.info "switch3Handler Event: ${evt.value}"
if (colors) {
if (Temp3) { slaves?.setColorTemperature(Temp3)
colors?.setColorTemperature(Temp3) }
if (Dim3) { slaves?.setLevel(Dim3)
colors?.setLevel(Dim3) }
if (Hue3) { colors?.setHue(Hue3) }
if (Sat3) { colors?.setSaturation(Sat3) }
} else {
if (Temp3) { slaves?.setColorTemperature(Temp3) }
if (Dim3) { slaves?.setLevel(Dim3) }
}
}
def switch4Handler(evt){
log.info "switch4Handler Event: ${evt.value}"
if (colors) {
if (Temp4) { slaves?.setColorTemperature(Temp4)
colors?.setColorTemperature(Temp4) }
if (Dim4) { slaves?.setLevel(Dim4)
colors?.setLevel(Dim4) }
if (Hue4) { colors?.setHue(Hue4) }
if (Sat4) { colors?.setSaturation(Sat4) }
} else {
if (Temp4) { slaves?.setColorTemperature(Temp4) }
if (Dim4) { slaves?.setLevel(Dim4) }
}
}
def switch5Handler(evt){
log.info "switch5Handler Event: ${evt.value}"
if (colors) {
if (Temp5) { slaves?.setColorTemperature(Temp5)
colors?.setColorTemperature(Temp5) }
if (Dim5) { slaves?.setLevel(Dim5)
colors?.setLevel(Dim5) }
if (Hue5) { colors?.setHue(Hue5) }
if (Sat5) { colors?.setSaturation(Sat5) }
} else {
if (Temp5) { slaves?.setColorTemperature(Temp5) }
if (Dim5) { slaves?.setLevel(Dim5) }
}
}