Skip to content

Commit 348c978

Browse files
authored
Merge pull request SmartThingsCommunity#2407 from SmartThingsCommunity/staging
Rolling up staging to production
2 parents 0ddc546 + 0f99ed9 commit 348c978

File tree

12 files changed

+3174
-865
lines changed

12 files changed

+3174
-865
lines changed

devicetypes/smartthings/ecobee-thermostat.src/ecobee-thermostat.groovy

Lines changed: 287 additions & 535 deletions
Large diffs are not rendered by default.
Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
/**
2+
* Copyright 2017 SmartThings
3+
*
4+
* Simulates a dimmable light bulb. No color, no tunable white
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
7+
* in compliance with the License. You may obtain a copy of the License at:
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
12+
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License
13+
* for the specific language governing permissions and limitations under the License.
14+
*
15+
*/
16+
metadata {
17+
definition (name: "Simulated Dimmable Bulb", namespace: "smartthings/testing", author: "SmartThings") {
18+
capability "Health Check"
19+
capability "Actuator"
20+
capability "Sensor"
21+
capability "Light"
22+
23+
capability "Switch"
24+
capability "Switch Level"
25+
capability "Refresh"
26+
capability "Configuration"
27+
}
28+
29+
preferences {
30+
}
31+
32+
tiles(scale: 2) {
33+
multiAttributeTile(name:"switch", type: "lighting", width: 6, height: 4, canChangeIcon: true){
34+
tileAttribute ("device.switch", key: "PRIMARY_CONTROL") {
35+
attributeState "on", label:'${name}', action:"switch.off", icon:"st.switches.light.on", backgroundColor:"#00A0DC", nextState:"turningOff"
36+
attributeState "off", label:'${name}', action:"switch.on", icon:"st.switches.light.off", backgroundColor:"#FFFFFF", nextState:"turningOn"
37+
attributeState "turningOn", label:'Turning On', action:"switch.off", icon:"st.switches.light.on", backgroundColor:"#00A0DC", nextState:"on"
38+
attributeState "turningOff", label:'Turning Off', action:"switch.on", icon:"st.switches.light.off", backgroundColor:"#FFFFFF", nextState:"off"
39+
}
40+
tileAttribute ("device.level", key: "SLIDER_CONTROL") {
41+
attributeState "level", action: "setLevel"
42+
}
43+
tileAttribute ("brightnessLabel", key: "SECONDARY_CONTROL") {
44+
attributeState "Brightness", label: '${name}', defaultState: true
45+
}
46+
}
47+
48+
standardTile("refresh", "device.switch", width: 1, height: 1, inactiveLabel: false, decoration: "flat") {
49+
state "default", label: "", action:"refresh.refresh", icon:"st.secondary.refresh"
50+
}
51+
valueTile("reset", "device.switch", inactiveLabel: false, decoration: "flat", width: 1, height: 1) {
52+
state "default", label: "Reset", action: "configure"
53+
}
54+
55+
main(["switch"])
56+
details(["switch", "refresh", "reset"])
57+
58+
}
59+
}
60+
61+
// parse events into attributes
62+
def parse(String description) {
63+
log.trace "parse $description"
64+
def parsedEvents
65+
def pair = description?.split(":")
66+
if (!pair || pair.length < 2) {
67+
log.warn "parse() could not extract an event name and value from '$description'"
68+
} else {
69+
String name = pair[0]?.trim()
70+
if (name) {
71+
name = name.replaceAll(~/\W/, "_").replaceAll(~/_{2,}?/, "_")
72+
}
73+
parsedEvents = createEvent(name: name, value: pair[1]?.trim())
74+
}
75+
return parsedEvents
76+
}
77+
78+
def installed() {
79+
log.trace "Executing 'installed'"
80+
initialize()
81+
}
82+
83+
def updated() {
84+
log.trace "Executing 'updated'"
85+
initialize()
86+
}
87+
88+
//
89+
// command methods
90+
//
91+
def ping() {
92+
refresh()
93+
}
94+
95+
def refresh() {
96+
log.trace "Executing 'refresh'"
97+
sendEvent(name: "switch", value: getSwitch())
98+
sendEvent(buildSetLevelEvent(getLevel()))
99+
}
100+
101+
def configure() {
102+
log.trace "Executing 'configure'"
103+
initialize()
104+
}
105+
106+
def on() {
107+
log.trace "Executing 'on'"
108+
turnOn()
109+
}
110+
111+
def off() {
112+
log.trace "Executing 'off'"
113+
turnOff()
114+
}
115+
116+
def setLevel(value) {
117+
log.trace "Executing setLevel $value"
118+
Map levelEventMap = buildSetLevelEvent(value)
119+
if (levelEventMap.value == 0) {
120+
turnOff()
121+
// notice that we don't set the level to 0'
122+
} else {
123+
implicitOn()
124+
sendEvent(levelEventMap)
125+
}
126+
}
127+
128+
def setLevel(value, duration) {
129+
log.trace "Executing setLevel $value (ignoring duration)"
130+
setLevel(value)
131+
}
132+
133+
private String getSwitch() {
134+
def switchState = device.currentState("switch")
135+
return switchState ? switchState.getStringValue() : "off"
136+
}
137+
138+
private Integer getLevel() {
139+
def levelState = device.currentState("level")
140+
return levelState ? levelState.getIntegerValue() : 100
141+
}
142+
143+
private initialize() {
144+
log.trace "Executing 'initialize'"
145+
sendEvent(name: "switch", value: "off")
146+
sendEvent(name: "level", value: 100)
147+
}
148+
149+
private Map buildSetLevelEvent(value) {
150+
Integer intValue = value as Integer
151+
Integer newLevel = Math.max(Math.min(intValue, 99), 0)
152+
Map eventMap = [name: "level", value: newLevel, unit: "%"]
153+
return eventMap
154+
}
155+
156+
/**
157+
* Turns device on if it is not already on
158+
*/
159+
private implicitOn() {
160+
if (device.currentValue("switch") != "on") {
161+
turnOn()
162+
}
163+
}
164+
165+
/*
166+
* no-frills turn-on, no log, no simulation
167+
*/
168+
private turnOn() {
169+
sendEvent(name: "switch", value: "on")
170+
}
171+
172+
/**
173+
* no-frills turn-off, no log, no simulation
174+
*/
175+
private turnOff() {
176+
sendEvent(name: "switch", value: "off")
177+
}
Lines changed: 201 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,201 @@
1+
/**
2+
* Copyright 2017 SmartThings
3+
*
4+
* Simulates a dimmer switch, including physical operation
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
7+
* in compliance with the License. You may obtain a copy of the License at:
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
12+
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License
13+
* for the specific language governing permissions and limitations under the License.
14+
*
15+
*/
16+
metadata {
17+
definition (name: "Simulated Dimmer Switch", namespace: "smartthings/testing", author: "SmartThings") {
18+
capability "Actuator"
19+
capability "Sensor"
20+
21+
capability "Switch"
22+
capability "Switch Level"
23+
capability "Refresh"
24+
capability "Configuration"
25+
26+
command "onPhysical"
27+
command "offPhysical"
28+
command "setLevelPhysical"
29+
}
30+
31+
preferences {
32+
}
33+
34+
tiles(scale: 2) {
35+
multiAttributeTile(name:"switch", type: "lighting", width: 6, height: 4, canChangeIcon: true){
36+
tileAttribute ("device.switch", key: "PRIMARY_CONTROL") {
37+
attributeState "on", label:'${name}', action:"switch.off", icon:"st.Home.home30", backgroundColor:"#00A0DC", nextState:"turningOff"
38+
attributeState "off", label:'${name}', action:"switch.on", icon:"st.Home.home30", backgroundColor:"#FFFFFF", nextState:"turningOn", defaultState: true
39+
attributeState "turningOn", label:'Turning On', action:"switch.off", icon:"st.Home.home30", backgroundColor:"#00A0DC", nextState:"turningOn"
40+
attributeState "turningOff", label:'Turning Off', action:"switch.on", icon:"st.Home.home30", backgroundColor:"#FFFFFF", nextState:"turningOff"
41+
}
42+
tileAttribute ("device.level", key: "SLIDER_CONTROL") {
43+
attributeState "level", action: "setLevel"
44+
}
45+
tileAttribute ("brightnessLabel", key: "SECONDARY_CONTROL") {
46+
attributeState "Brightness", label: '${name}', defaultState: true
47+
}
48+
}
49+
50+
51+
valueTile("physicalLabel", "device.switch", width: 2, height: 2, decoration: "flat") {
52+
state "label", label: "Simulate\nPhysical\nOperations", defaultState: true
53+
}
54+
standardTile("physicalOn", "device.switch", width: 2, height: 2, decoration: "flat") {
55+
state "default", label: "Physical On", action: "onPhysical", icon: "st.Home.home30", backgroundColor: "#ffffff"
56+
}
57+
standardTile("physicalOff", "device.switch", width: 2, height: 2, decoration: "flat") {
58+
state "default", label: "Physical Off", action: "offPhysical", icon: "st.Home.home30", backgroundColor: "#ffffff"
59+
}
60+
61+
valueTile("physicalLevelLabel", "device.switch", width: 2, height: 1, decoration: "flat") {
62+
state "label", label: "Physical Level", defaultState: true
63+
}
64+
controlTile("physicalLevelSlider", "device.level", "slider", width: 4, height: 1, inactiveLabel: false, range: "(1..99)") {
65+
state "physicalLevel", action: "setLevelPhysical"
66+
}
67+
68+
standardTile("refresh", "device.switch", width: 1, height: 1, inactiveLabel: false, decoration: "flat") {
69+
state "default", label: "", action:"refresh.refresh", icon:"st.secondary.refresh"
70+
}
71+
valueTile("reset", "device.switch", inactiveLabel: false, decoration: "flat", width: 1, height: 1) {
72+
state "default", label: "Reset", action: "configure"
73+
}
74+
75+
main(["switch"])
76+
details(["switch", "physicalLabel", "physicalOn", "physicalOff", "physicalLevelLabel", "physicalLevelSlider", "refresh", "reset"])
77+
78+
}
79+
}
80+
81+
// parse events into attributes
82+
def parse(String description) {
83+
log.trace "parse $description"
84+
def parsedEvents
85+
def pair = description?.split(":")
86+
if (!pair || pair.length < 2) {
87+
log.warn "parse() could not extract an event name and value from '$description'"
88+
} else {
89+
String name = pair[0]?.trim()
90+
if (name) {
91+
name = name.replaceAll(~/\W/, "_").replaceAll(~/_{2,}?/, "_")
92+
}
93+
parsedEvents = createEvent(name: name, value: pair[1]?.trim())
94+
}
95+
return parsedEvents
96+
}
97+
98+
def installed() {
99+
log.trace "Executing 'installed'"
100+
initialize()
101+
}
102+
103+
def updated() {
104+
log.trace "Executing 'updated'"
105+
initialize()
106+
}
107+
108+
//
109+
// command methods
110+
//
111+
def refresh() {
112+
log.trace "Executing 'refresh'"
113+
// ummm.... not much to do here without a physical device
114+
}
115+
116+
def configure() {
117+
log.trace "Executing 'configure'"
118+
initialize()
119+
}
120+
121+
def on() {
122+
log.trace "Executing 'on'"
123+
turnOn()
124+
}
125+
126+
def off() {
127+
log.trace "Executing 'off'"
128+
turnOff()
129+
}
130+
131+
def setLevel(value) {
132+
log.trace "Executing setLevel $value"
133+
Map levelEventMap = buildSetLevelEvent(value)
134+
if (levelEventMap.value == 0) {
135+
turnOff()
136+
// notice that we don't set the level to 0'
137+
} else {
138+
implicitOn()
139+
sendEvent(levelEventMap)
140+
}
141+
}
142+
143+
def setLevel(value, duration) {
144+
log.trace "Executing setLevel $value (ignoring duration)"
145+
setLevel(value)
146+
}
147+
148+
private initialize() {
149+
log.trace "Executing 'initialize'"
150+
sendEvent(name: "switch", value: "off")
151+
sendEvent(name: "level", value: 100)
152+
}
153+
154+
private Map buildSetLevelEvent(value) {
155+
def intValue = value as Integer
156+
def newLevel = Math.max(Math.min(intValue, 99), 0)
157+
Map eventMap = [name: "level", value: newLevel, unit: "%"]
158+
return eventMap
159+
}
160+
161+
/**
162+
* Turns device on if it is not already on
163+
*/
164+
private implicitOn() {
165+
if (device.currentValue("switch") != "on") {
166+
turnOn()
167+
}
168+
}
169+
170+
/*
171+
* no-frills turn-on, no log, no simulation
172+
*/
173+
private turnOn() {
174+
sendEvent(name: "switch", value: "on")
175+
}
176+
177+
/**
178+
* no-frills turn-off, no log, no simulation
179+
*/
180+
private turnOff() {
181+
sendEvent(name: "switch", value: "off")
182+
}
183+
184+
// Generate pretend physical events
185+
private onPhysical() {
186+
log.trace "Executing 'onPhysical'"
187+
sendEvent(name: "switch", value: "on", type: "physical")
188+
}
189+
190+
private offPhysical() {
191+
log.trace "Executing 'offPhysical'"
192+
sendEvent(name: "switch", value: "off", type: "physical")
193+
}
194+
195+
private setLevelPhysical(value) {
196+
log.trace "Executing 'setLevelPhysical'"
197+
Map eventMap = buildSetLevelEvent(value)
198+
if (eventMap.value == 0) eventMap.value = 1 // can't turn it off by physically setting level
199+
eventMap.type = "physical"
200+
sendEvent(eventMap)
201+
}

0 commit comments

Comments
 (0)