Skip to content

Commit db27080

Browse files
marstorpbflorian
authored andcommitted
WWST-207 HOTFIX Ecobee JWT auth errors (SmartThingsCommunity#2981)
WWST-207 HOTFIX Ecobee JWT auth errors sendCommandToEcobee() is calling poll and if poll causes child to call sendCommandToEcobee this may lead to recursive calls. Refactor sendCommandToEcobee, removing poll and instead try to send the command one more time after refresh of authToken.
1 parent c42a6ab commit db27080

File tree

1 file changed

+41
-26
lines changed

1 file changed

+41
-26
lines changed

smartapps/smartthings/ecobee-connect.src/ecobee-connect.groovy

Lines changed: 41 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1064,41 +1064,56 @@ def setSensorName(name, deviceId) {
10641064
* @return true if the command was accepted by Ecobee without error, false otherwise.
10651065
*/
10661066
private boolean sendCommandToEcobee(Map bodyParams) {
1067+
// no need to try sending a command if authToken is null
1068+
if (!state.authToken) {
1069+
log.warn "sendCommandToEcobee failed due to authToken=null"
1070+
return false
1071+
}
10671072
def isSuccess = false
10681073
def cmdParams = [
10691074
uri: apiEndpoint,
10701075
path: "/1/thermostat",
10711076
headers: ["Content-Type": "application/json", "Authorization": "Bearer ${state.authToken}"],
10721077
body: toJson(bodyParams)
10731078
]
1079+
def keepTrying = true
1080+
def cmdAttempt = 1
10741081

1075-
try{
1076-
httpPost(cmdParams) { resp ->
1077-
if(resp.status == 200) {
1078-
log.debug "updated ${resp.data}"
1079-
def returnStatus = resp.data.status.code
1080-
if (returnStatus == 0) {
1081-
log.debug "Successful call to ecobee API."
1082-
isSuccess = true
1083-
} else {
1084-
log.debug "Error return code = ${returnStatus}"
1085-
}
1086-
}
1087-
}
1088-
} catch (groovyx.net.http.HttpResponseException e) {
1089-
log.trace "Exception Sending Json: $e, ${e?.response?.data}"
1090-
if (e.response.data.status.code == 14) {
1091-
// TODO - figure out why we're setting the next action to be poll
1092-
// after refreshing auth token. Is it to keep UI in sync, or just copy/paste error?
1093-
state.action = "poll"
1094-
log.debug "Refreshing your auth_token!"
1095-
refreshAuthToken()
1096-
} else {
1097-
log.error "Authentication error, invalid authentication method, lack of credentials, etc."
1098-
}
1099-
}
1082+
while (keepTrying) {
1083+
try{
1084+
httpPost(cmdParams) { resp ->
1085+
keepTrying = false
1086+
if(resp.status == 200) {
1087+
log.debug "updated ${resp.data}"
1088+
def returnStatus = resp.data.status.code
1089+
if (returnStatus == 0) {
1090+
log.debug "Successful call to ecobee API."
1091+
isSuccess = true
1092+
} else {
1093+
log.debug "Error return code = ${returnStatus}"
1094+
}
1095+
}
1096+
}
1097+
} catch (groovyx.net.http.HttpResponseException e) {
1098+
log.trace "Exception Sending Json: $e, status:${e.getStatusCode()}, ${e?.response?.data}"
1099+
if (e.response.data.status.code == 14) {
1100+
if (cmdAttempt < 2) {
1101+
cmdAttempt = cmdAttempt + 1
1102+
log.debug "Refreshing your auth_token!"
1103+
refreshAuthToken()
1104+
cmdParams.headers.Authorization = "Bearer ${state.authToken}"
1105+
} else {
1106+
log.info "sendJson failed ${cmdAttempt} times, e:$e, status:${e.getStatusCode()}"
1107+
keepTrying = false
1108+
}
1109+
} else {
1110+
log.error "Authentication error, invalid authentication method, lack of credentials, etc."
1111+
keepTrying = false
1112+
}
1113+
}
1114+
}
11001115

1101-
return isSuccess
1116+
return isSuccess
11021117
}
11031118

11041119
def getChildName() { return "Ecobee Thermostat" }

0 commit comments

Comments
 (0)