-
Notifications
You must be signed in to change notification settings - Fork 91
/
shm-delay-modefix.groovy
303 lines (285 loc) · 8.89 KB
/
shm-delay-modefix.groovy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
/*
* SHM Delay ModeFix
* Functions: Fix the mode when it is invalid, generally cause when using Dashboard to switch modes
*
* Copyright 2017 Arn Burkhoff
*
* 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.
*
* Sep 23, 2017 v0.1.2 Ignore alarm changes caused by True Entry Delay in SHM Delay Child
* Sep 05, 2017 v0.1.1 minor code change to allow this module to run stand alone
* Sep 02, 2017 v0.1.0 add code to fix bad alarmstate set by unmodified Keypad module
* Sep 02, 2017 v0.1.0 Repackage logic that was in parent into this module for better reliability
* and control
* Aug 26/27, 2017 v0.0.0 Create
*
*/
definition(
name: "SHM Delay ModeFix",
namespace: "arnbme",
author: "Arn Burkhoff",
description: "Fix the ST Mode when using ST Dashboard to change AlarmState",
category: "My Apps",
iconUrl: "https://www.arnb.org/IMAGES/hourglass.png",
iconX2Url: "https://www.arnb.org/IMAGES/hourglass@2x.png",
iconX3Url: "https://www.arnb.org/IMAGES/hourglass@2x.png")
preferences {
page(name: "pageOne", nextPage: "pageOneVerify")
page(name: "pageOneVerify")
page(name: "pageTwo")
page(name: "aboutPage", nextPage: "pageOne")
}
def pageOne(error_msg)
{
dynamicPage(name: "pageOne", title: "For each alarm state, set valid modes and default modes.", install: false, uninstall: true)
{
section
{
if (error_msg instanceof String )
{
paragraph error_msg
}
else
paragraph "Caution! Wrong settings may create havoc. If you don't fully understand Alarm States and Modes, read the Introduction and use the defaults!"
href(name: "href",
title: "Introduction",
required: false,
page: "aboutPage")
}
section ("Alarm State: Disarmed / Off")
{
input "offModes", "mode", required: true, multiple: true, defaultValue: "Home",
title: "Valid Modes for: Disarmed"
input "offDefault", "mode", required: true, defaultValue: "Home",
title: "Default Mode for: Disarmed"
}
section ("Alarm State: Armed (Away)")
{
if (away_error_data instanceof String )
{
paragraph away_error_data
}
input "awayModes", "mode", required: true, multiple: true, defaultValue: "Away",
title: "Valid modes for: Armed Away"
input "awayDefault", "mode", required: true, defaultValue: "Away",
title: "Default Mode: Armed Away"
}
section ("Alarm State: Armed (Home) aka Stay or Night")
{
input "stayModes", "mode", required: true, multiple: true, defaultValue: "Night",
title: "Valid Modes for Armed Home"
input "stayDefault", "mode", required: true, defaultValue: "Night",
title: "Default Mode for Armed Home"
}
}
}
def pageOneVerify() //edit page One
{
// Verify disarm/off data
def off_error="Disarmed / Off Default Mode not defined in Valid Modes"
def children = offModes
children.each
{ child ->
if (offDefault == child)
{
off_error=null
}
}
// Verify Away data
def away_error="Armed (Away) Default Mode not defined in Valid Modes"
children = awayModes
children.each
{ child ->
if (awayDefault == child)
{
away_error=null
}
}
// Verify Stay data
def stay_error="Armed (Home) Default Mode not defined in Valid Modes"
children = stayModes
children.each
{ child ->
if (stayDefault == child)
{
stay_error=null
}
}
if (off_error == null && away_error == null && stay_error == null)
{
pageTwo()
}
else
{
def error_msg=""
def newline=""
if (off_error>"")
{
error_msg=off_error
newline="\n"
}
if (away_error >"")
{
error_msg+=newline + away_error
newline="\n"
}
if (stay_error >"")
{
error_msg+=newline + stay_error
newline="\n"
}
pageOne(error_msg)
}
}
def pageTwo()
{
dynamicPage(name: "pageTwo", title: "Mode settings verified, press 'Done' to install, press '<' to change, ", install: true, uninstall: true)
{
/* section
{
href(name: "href",
title: "Introduction",
required: false,
page: "aboutPage")
}
*/ section ("Alarm State: Disarmed / Off")
{
input "offModes", "mode", required: true, multiple: true, defaultValue: "Home",
title: "Valid Modes for: Disarmed"
input "offDefault", "mode", required: true, defaultValue: "Home",
title: "Default Mode for: Disarmed"
}
section ("Alarm State: Armed (Away)")
{
input "awayModes", "mode", required: true, multiple: true, defaultValue: "Away",
title: "Valid modes for: Armed Away"
input "awayDefault", "mode", required: true, defaultValue: "Away",
title: "Default Mode: Armed Away"
}
section ("Alarm State: Armed (Home) aka Stay or Night")
{
input "stayModes", "mode", required: true, multiple: true, defaultValue: "Night",
title: "Valid Modes for Armed Home"
input "stayDefault", "mode", required: true, defaultValue: "Night",
title: "Default Mode for Armed Home"
}
}
}
def aboutPage()
{
dynamicPage(name: "aboutPage", title: "Introduction")
{
section
{
paragraph "Have you ever wondered why Mode restricted Routines, SmartApps, and Pistons sometimes fail to execute, or execute when they should not?\n\n"+
"Perhaps you conflated AlarmState and Mode, however they are separate and independent SmartThings settings, "+
"and when Alarm State is changed using the SmartThings Dashboard Home Solutions---surprise, Mode does not change!\n\n" +
"SmartHome routines generally, but not always, have a defined SystemAlarm and Mode settings. "+
"Experienced SmartThings users seem to favor changing the AlarmState using SmartHome routines, avoiding use of the Dashboard's Home Solutions\n\n"+
"If like me, you can't keep track of all this, or utilize the Dashboard to change the AlarmState, this app may be helpful.\n\n"+
"For each AlarmState, set the Valid Mode states, and a Default Mode. This SmartApp attempts to correctly set the Mode by monitoring AlarmState for changes. When the current Mode is not defined as a Valid Mode for the AlarmState, the app sets Mode to the AlarmState's Default Mode\n\n"+
"Please Note: This app does not, directly or (knowingly) indirectly, execute a SmartHome Routine"
}
}
}
def installed() {
log.debug "Installed with settings: ${settings}"
initialize()
}
def updated() {
log.debug "Updated with settings: ${settings}"
unsubscribe()
initialize()
}
def initialize()
{
subscribe(location, "alarmSystemStatus", alarmStatusHandler)
}
def alarmStatusHandler(evt)
{
def theAlarm = evt.value
if (theAlarm == "night") //bad AlarmState set by unmodified Keypad module
{
def event = [
name:'alarmSystemStatus',
value: "stay",
displayed: true,
description: "SHM Delay Fix System Status from night to stay"]
sendLocationEvent(event) //change alarmstate to stay
setLocationMode("Night") //set the mode
// sendNotificationEvent("Change the Lock Manager Keypad module to version in github ARNBME lock-master SHMDelay")
log.warn "Change the Lock Manager Keypad module to version in github ARNBME lock-master SHMDelay ModeFix"
return "Night"
}
if (parent && !parent.globalFixMode)
{return false}
def theMode = location.currentMode
def oldMode = theMode
def delaydata=evt?.data
if (delaydata==null)
{}
else
if (delaydata.startsWith("shmtruedelay")) //ignore SHM Delay Child "true entry delay" alarm state changes
{
log.debug "Modefix ignoring True Entry Delay event, alarm state ${theAlarm}"
return false}
log.debug "ModeFix alarmStatusHandler entered alarm status change: ${theAlarm} Mode: ${theMode} "
// Fix the mode to match the Alarm State. When user sets alarm from dashboard
// the Mode is not set, resulting in Smarthings having Schizophrenia or cognitive dissonance.
def modeOK=false
if (theAlarm=="off")
{
offModes.each
{ child ->
if (theMode == child)
{modeOK=true}
}
if (!modeOK)
{
setLocationMode(offDefault)
theMode=offDefault
}
}
else
if (theAlarm=="stay")
{
stayModes.each
{ child ->
if (theMode == child)
{modeOK=true}
}
if (!modeOK)
{
setLocationMode(stayDefault)
theMode=stayDefault
}
}
else
if (theAlarm=="away")
{
awayModes.each
{ child ->
if (theMode == child)
{modeOK=true}
}
if (!modeOK)
{
setLocationMode(awayDefault)
theMode=awayDefault
}
}
else{
log.error "ModeFix alarmStatusHandler Unknown alarm mode: ${theAlarm} in "}
if (theMode != oldMode)
{
log.debug("ModeFix alarmStatusHandler Mode was changed From:$oldMode To:$theMode")
}
return theMode
}