import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
+import java.time.Instant;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
// Cloud fallback
private boolean cloudFallback = false;
+ // Communication errors counter
+ private int errorsCounter = 0;
+
+ // Last login timestamp
+ private Instant lastLoginTimestamp = Instant.MIN;
+
/**
* Our configuration
*/
return;
}
- if (tooManyRequests) {
- logger.debug("Skipping login due to too many requests");
+ if (tooManyRequests || Instant.now().minusSeconds(LOGIN_LIMIT_TIME).isBefore(lastLoginTimestamp)) {
+ logger.debug("Postponing login to avoid throttling");
return;
}
SomfyTahomaLoginResponse data = gson.fromJson(response.getContentAsString(),
SomfyTahomaLoginResponse.class);
+ lastLoginTimestamp = Instant.now();
+
if (data == null) {
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
"Received invalid data (login)");
private Request sendRequestBuilderLocal(String subUrl, HttpMethod method) {
return httpClient.newRequest(getApiFullUrl(subUrl)).method(method).accept("application/json")
- .header(HttpHeader.AUTHORIZATION, "Bearer " + localToken);
+ .timeout(TAHOMA_TIMEOUT, TimeUnit.SECONDS).header(HttpHeader.AUTHORIZATION, "Bearer " + localToken);
}
/**
response = sendDeleteToTahomaWithCookie(url);
default:
}
+ errorsCounter = 0;
return classOfT != null ? gson.fromJson(response, classOfT) : null;
} catch (JsonSyntaxException e) {
logger.debug("Received data: {} is not JSON", response, e);
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, "Temporarily banned");
setTooManyRequests();
} else if (isEventListenerTimeout(e)) {
+ logger.debug("Event listener timeout occurred", e);
reLogin();
+ } else if (isDevModeReady()) {
+ // the local gateway is unreachable
+ errorsCounter++;
+ logger.debug("Local gateway communication error", e);
+ discoverGateway();
+ if (errorsCounter > MAX_ERRORS) {
+ updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
+ "Too many communication errors");
+ }
} else {
logger.debug("Cannot call url: {} with params: {}!", getApiFullUrl(url), urlParameters, e);
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR);
}
} catch (TimeoutException e) {
+ errorsCounter++;
logger.debug("Timeout when calling url: {} with params: {}!", getApiFullUrl(url), urlParameters, e);
- updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR);
+ if (errorsCounter > MAX_ERRORS) {
+ updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, "Too many timeouts");
+ }
} catch (InterruptedException e) {
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR);
Thread.currentThread().interrupt();