-
Notifications
You must be signed in to change notification settings - Fork 1
/
cromecast-helper.groovy
243 lines (216 loc) · 9.69 KB
/
cromecast-helper.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
/** Chromecast Helper for hubitat
This app is no longer supported but I was still using it off and on so I have saved it.
It may no longer be needed as you needto have your google set to static IP in your router
And the hub wont lose track of it. Just in case someone still needs this app its archived here.
============================================================================================================
*
* Design Usage:
* Simple way to help keep your Google/Nest devices alive.
* Chromecast Integration (beta) is required for use of this app.
*
* Copyright 2019-2020 Bryan Turcotte (@bptworld)
*
* This App is free. If you like and use this app, please be sure to mention it on the Hubitat forums! Thanks.
*
* Remember...I am not a programmer, everything I do takes a lot of time and research!
* Donations are never necessary but always appreciated. Donations to support development efforts are accepted via:
*
* Paypal at: https://paypal.me/bptworld
*
* Unless noted in the code, ALL code contained within this app is mine. You are free to change, ripout, copy, modify or
* otherwise use the code in anyway you want. This is a hobby, I'm more than happy to share what I have learned and help
* the community grow. Have FUN with it!
*
*-------------------------------------------------------------------------------------------------------------------
* 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.
*
* ------------------------------------------------------------------------------------------------------------------------------
*
* If modifying this project, please keep the above header intact and add your comments/credits below - Thank you! - @BPTWorld
*
* App and Driver updates can be found at https://github.com/bptworld/Hubitat/
*
* ------------------------------------------------------------------------------------------------------------------------------
*
* Changes:
*
* 2.0.3 - 08/02/20 - Cosmetic changes
* 2.0.2 - 06/13/20 - Minor changes
* 2.0.1 - 04/27/20 - Cosmetic changes
* 2.0.0 - 08/18/19 - Now App Watchdog 2 compliant
* 1.0.0 - 07/21/19 - Initial release.
*
*/
import groovy.time.TimeCategory
import java.text.SimpleDateFormat
def setVersion(){
state.name = "Chromecast Helper"
state.version = "2.0.3"
}
definition(
name: "Chromecast Helper BU", namespace: "BPTWorld", author: "Bryan Turcotte", importUrl: "https://raw.githubusercontent.com/tmastersmart/hubitat-code/main/cromecast-helper.groovy"
)
preferences {
page(name: "pageConfig")
}
def pageConfig() {
dynamicPage(name: "", title: "", install: true, uninstall: true, refreshInterval:0) {
display()
section("Instructions:", hideable: true, hidden: true) {
paragraph "<b>Notes:</b>"
paragraph "Simple way to help keep your Google/Nest devices alive."
paragraph "* Chromecast Integration (beta) is required for use of this app."
}
section(getFormat("header-green", "${getImage("Blank")}"+" Options")) {
paragraph "This will send an 'initialize' every X minutes to help keep your Google/Nest speakers alive."
input "speaker", "capability.speechSynthesis", title: "Choose your Google/Nest speaker(s)", required: true, multiple: true
input "gInitRepeat", "number", title: "Initialize Google/Nest devices every X minutes? (recommended: 4)", required: true
}
section(getFormat("header-green", "${getImage("Blank")}"+" App Control")) {
input "pauseApp", "bool", title: "Pause App", defaultValue:false, submitOnChange:true
if(pauseApp) {
if(app.label) {
if(!app.label.contains(" (Paused)")) {
app.updateLabel(app.label + " (Paused)")
}
}
} else {
if(app.label) {
app.updateLabel(app.label - " (Paused)")
}
}
paragraph "This app can be enabled/disabled by using a switch. The switch can also be used to enable/disable several apps at the same time."
input "disableSwitch", "capability.switch", title: "Switch Device(s) to Enable / Disable this app", submitOnChange:true, required:false, multiple:true
}
section(getFormat("header-green", "${getImage("Blank")}"+" General")) {
label title: "Enter a name for this automation", required:false
input "logEnable", "bool", title: "Enable Debug Logging", description: "Enable logging for debugging.", defaultValue:false
}
display2()
}
}
def installed() {
log.debug "Installed with settings: ${settings}"
initialize()
}
def updated() {
if(logEnable) log.debug "Updated with settings: ${settings}"
unschedule()
if(logEnable) runIn(3600, logsOff)
initialize()
}
def initialize() {
checkEnableHandler()
if(pauseApp || state.eSwitch) {
log.info "${app.label} is Paused or Disabled"
} else {
setDefaults()
runIn(gInitRepeat,initializeSpeaker)
}
}
def initializeSpeaker() {
checkEnableHandler()
if(pauseApp || state.eSwitch) {
log.info "${app.label} is Paused or Disabled"
} else {
if(logEnable) log.debug "In initializeSpeaker - Initializing ${speaker}"
speaker.initialize()
repeat = gInitRepeat * 60
runIn(repeat,initializeSpeaker)
}
}
// ********** Normal Stuff **********
def logsOff() {
log.info "${app.label} - Debug logging auto disabled"
app?.updateSetting("logEnable",[value:"false",type:"bool"])
}
def checkEnableHandler() {
state.eSwitch = false
if(disableSwitch) {
if(logEnable) log.debug "In checkEnableHandler - disableSwitch: ${disableSwitch}"
disableSwitch.each { it ->
eSwitch = it.currentValue("switch")
if(eSwitch == "on") { state.eSwitch = true }
}
}
}
def setDefaults(){
if(logEnable == null){logEnable = false}
}
def getImage(type) { // Modified from @Stephack Code
def loc = "<img src=https://raw.githubusercontent.com/bptworld/Hubitat/master/resources/images/"
if(type == "Blank") return "${loc}blank.png height=40 width=5}>"
if(type == "checkMarkGreen") return "${loc}checkMarkGreen2.png height=30 width=30>"
if(type == "optionsGreen") return "${loc}options-green.png height=30 width=30>"
if(type == "optionsRed") return "${loc}options-red.png height=30 width=30>"
if(type == "instructions") return "${loc}instructions.png height=30 width=30>"
if(type == "logo") return "${loc}logo.png height=60>"
}
def getFormat(type, myText="") { // Modified from @Stephack Code
if(type == "header-green") return "<div style='color:#ffffff;font-weight: bold;background-color:#81BC00;border: 1px solid;box-shadow: 2px 3px #A9A9A9'>${myText}</div>"
if(type == "line") return "<hr style='background-color:#1A77C9; height: 1px; border: 0;'>"
if(type == "title") return "<h2 style='color:#1A77C9;font-weight: bold'>${myText}</h2>"
}
def display() {
setVersion()
getHeaderAndFooter()
theName = app.label
if(theName == null || theName == "") theName = "New Child App"
section (getFormat("title", "${getImage("logo")}" + " ${state.name} - ${theName}")) {
paragraph "${state.headerMessage}"
paragraph getFormat("line")
}
}
def display2() {
section() {
paragraph getFormat("line")
paragraph "<div style='color:#1A77C9;text-align:center;font-size:20px;font-weight:bold'>${state.name} - ${state.version}</div>"
paragraph "${state.footerMessage}"
}
}
def getHeaderAndFooter() {
timeSinceNewHeaders()
if(state.totalHours > 4) {
if(logEnable) log.debug "In getHeaderAndFooter (${state.version})"
def params = [
uri: "https://raw.githubusercontent.com/bptworld/Hubitat/master/info.json",
requestContentType: "application/json",
contentType: "application/json",
timeout: 30
]
try {
def result = null
httpGet(params) { resp ->
state.headerMessage = resp.data.headerMessage
state.footerMessage = resp.data.footerMessage
}
}
catch (e) { }
}
if(state.headerMessage == null) state.headerMessage = "<div style='color:#1A77C9'><a href='https://github.com/bptworld/Hubitat' target='_blank'>BPTWorld Apps and Drivers</a></div>"
if(state.footerMessage == null) state.footerMessage = "<div style='color:#1A77C9;text-align:center'>BPTWorld Apps and Drivers<br><a href='https://github.com/bptworld/Hubitat' target='_blank'>Donations are never necessary but always appreciated!</a><br><a href='https://paypal.me/bptworld' target='_blank'><b>Paypal</b></a></div>"
}
def timeSinceNewHeaders() {
if(state.previous == null) {
prev = new Date()
} else {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ")
prev = dateFormat.parse("${state.previous}".replace("+00:00","+0000"))
}
def now = new Date()
use(TimeCategory) {
state.dur = now - prev
state.days = state.dur.days
state.hours = state.dur.hours
state.totalHours = (state.days * 24) + state.hours
}
state.previous = now
//if(logEnable) log.warn "In checkHoursSince - totalHours: ${state.totalHours}"
}