mirror of
https://github.com/openhab/openhab-addons.git
synced 2025-01-10 07:02:02 +01:00
[meater] Fix broken cloud communication (#16994)
* Improve error handling Signed-off-by: Jacob Laursen <jacob-github@vindvejr.dk>
This commit is contained in:
parent
4b7220c552
commit
ac2ff96f25
@ -35,6 +35,7 @@ import org.openhab.binding.meater.internal.dto.MeaterProbeDTO.Device;
|
|||||||
import org.openhab.binding.meater.internal.exceptions.MeaterAuthenticationException;
|
import org.openhab.binding.meater.internal.exceptions.MeaterAuthenticationException;
|
||||||
import org.openhab.binding.meater.internal.exceptions.MeaterException;
|
import org.openhab.binding.meater.internal.exceptions.MeaterException;
|
||||||
import org.openhab.core.i18n.LocaleProvider;
|
import org.openhab.core.i18n.LocaleProvider;
|
||||||
|
import org.osgi.framework.FrameworkUtil;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
@ -63,6 +64,7 @@ public class MeaterRestAPI {
|
|||||||
private final Gson gson;
|
private final Gson gson;
|
||||||
private final HttpClient httpClient;
|
private final HttpClient httpClient;
|
||||||
private final MeaterBridgeConfiguration configuration;
|
private final MeaterBridgeConfiguration configuration;
|
||||||
|
private final String userAgent;
|
||||||
private String authToken = "";
|
private String authToken = "";
|
||||||
private LocaleProvider localeProvider;
|
private LocaleProvider localeProvider;
|
||||||
|
|
||||||
@ -72,42 +74,42 @@ public class MeaterRestAPI {
|
|||||||
this.configuration = configuration;
|
this.configuration = configuration;
|
||||||
this.httpClient = httpClient;
|
this.httpClient = httpClient;
|
||||||
this.localeProvider = localeProvider;
|
this.localeProvider = localeProvider;
|
||||||
|
userAgent = "openHAB/" + FrameworkUtil.getBundle(this.getClass()).getVersion().toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean refresh(Map<String, MeaterProbeDTO.Device> meaterProbeThings) {
|
public void refresh(Map<String, MeaterProbeDTO.Device> meaterProbeThings) throws MeaterException {
|
||||||
try {
|
MeaterProbeDTO dto = getDevices(MeaterProbeDTO.class);
|
||||||
MeaterProbeDTO dto = getDevices(MeaterProbeDTO.class);
|
if (dto != null) {
|
||||||
if (dto != null) {
|
List<Device> devices = dto.getData().getDevices();
|
||||||
List<Device> devices = dto.getData().getDevices();
|
if (devices != null) {
|
||||||
if (devices != null) {
|
if (!devices.isEmpty()) {
|
||||||
if (!devices.isEmpty()) {
|
for (Device meaterProbe : devices) {
|
||||||
for (Device meaterProbe : devices) {
|
meaterProbeThings.put(meaterProbe.id, meaterProbe);
|
||||||
meaterProbeThings.put(meaterProbe.id, meaterProbe);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
meaterProbeThings.clear();
|
|
||||||
}
|
}
|
||||||
return true;
|
} else {
|
||||||
|
meaterProbeThings.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (MeaterException e) {
|
|
||||||
logger.warn("Failed to refresh! {}", e.getMessage());
|
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void login() throws MeaterException {
|
private void login() throws MeaterException {
|
||||||
try {
|
try {
|
||||||
// Login
|
// Login
|
||||||
String json = "{ \"email\": \"" + configuration.email + "\", \"password\": \"" + configuration.password
|
String json = """
|
||||||
+ "\" }";
|
{
|
||||||
Request request = httpClient.newRequest(API_ENDPOINT + LOGIN).method(HttpMethod.POST)
|
"email": "%s",
|
||||||
.timeout(REQUEST_TIMEOUT_MS, TimeUnit.MILLISECONDS);
|
"password": "%s"
|
||||||
request.header(HttpHeader.ACCEPT, JSON_CONTENT_TYPE);
|
}
|
||||||
request.header(HttpHeader.CONTENT_TYPE, JSON_CONTENT_TYPE);
|
""".formatted(configuration.email, configuration.password);
|
||||||
request.content(new StringContentProvider(json), JSON_CONTENT_TYPE);
|
Request request = httpClient.newRequest(API_ENDPOINT + LOGIN) //
|
||||||
|
.method(HttpMethod.POST) //
|
||||||
|
.timeout(REQUEST_TIMEOUT_MS, TimeUnit.MILLISECONDS) //
|
||||||
|
.header(HttpHeader.ACCEPT, JSON_CONTENT_TYPE) //
|
||||||
|
.agent(userAgent) //
|
||||||
|
.content(new StringContentProvider(json), JSON_CONTENT_TYPE);
|
||||||
|
|
||||||
logger.trace("{}.", request.toString());
|
logger.trace("{}", request.toString());
|
||||||
|
|
||||||
ContentResponse httpResponse = request.send();
|
ContentResponse httpResponse = request.send();
|
||||||
if (!HttpStatus.isSuccess(httpResponse.getStatus())) {
|
if (!HttpStatus.isSuccess(httpResponse.getStatus())) {
|
||||||
@ -135,24 +137,25 @@ public class MeaterRestAPI {
|
|||||||
try {
|
try {
|
||||||
for (int i = 0; i < MAX_RETRIES; i++) {
|
for (int i = 0; i < MAX_RETRIES; i++) {
|
||||||
try {
|
try {
|
||||||
Request request = httpClient.newRequest(API_ENDPOINT + uri).method(HttpMethod.GET)
|
Request request = httpClient.newRequest(API_ENDPOINT + uri) //
|
||||||
.timeout(REQUEST_TIMEOUT_MS, TimeUnit.MILLISECONDS);
|
.method(HttpMethod.GET) //
|
||||||
request.header(HttpHeader.AUTHORIZATION, "Bearer " + authToken);
|
.timeout(REQUEST_TIMEOUT_MS, TimeUnit.MILLISECONDS)
|
||||||
request.header(HttpHeader.ACCEPT, JSON_CONTENT_TYPE);
|
.header(HttpHeader.AUTHORIZATION, "Bearer " + authToken)
|
||||||
request.header(HttpHeader.CONTENT_TYPE, JSON_CONTENT_TYPE);
|
.header(HttpHeader.ACCEPT, JSON_CONTENT_TYPE)
|
||||||
request.header(HttpHeader.ACCEPT_LANGUAGE, localeProvider.getLocale().getLanguage());
|
.header(HttpHeader.ACCEPT_LANGUAGE, localeProvider.getLocale().getLanguage())
|
||||||
|
.agent(userAgent);
|
||||||
|
|
||||||
ContentResponse response = request.send();
|
ContentResponse response = request.send();
|
||||||
String content = response.getContentAsString();
|
String content = response.getContentAsString();
|
||||||
logger.trace("API response: {}", content);
|
logger.trace("API response: {}", content);
|
||||||
|
|
||||||
if (response.getStatus() == HttpStatus.UNAUTHORIZED_401) {
|
int status = response.getStatus();
|
||||||
|
if (status == HttpStatus.UNAUTHORIZED_401) {
|
||||||
// This will currently not happen because "WWW-Authenticate" header is missing; see below.
|
// This will currently not happen because "WWW-Authenticate" header is missing; see below.
|
||||||
logger.debug("getFromApi failed, authentication failed, HTTP status: 401");
|
logger.debug("getFromApi failed, authentication failed, HTTP status: 401");
|
||||||
throw new MeaterAuthenticationException("Authentication failed");
|
throw new MeaterAuthenticationException("Authentication failed");
|
||||||
} else if (!HttpStatus.isSuccess(response.getStatus())) {
|
} else if (!HttpStatus.isSuccess(status)) {
|
||||||
logger.debug("getFromApi failed, HTTP status: {}", response.getStatus());
|
throw new MeaterException(HttpStatus.getCode(status).getMessage());
|
||||||
throw new MeaterException("Failed to fetch from API!");
|
|
||||||
} else {
|
} else {
|
||||||
return content;
|
return content;
|
||||||
}
|
}
|
||||||
@ -160,7 +163,7 @@ public class MeaterRestAPI {
|
|||||||
logger.debug("TimeoutException error in get: {}", e.getMessage());
|
logger.debug("TimeoutException error in get: {}", e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
throw new MeaterException("Failed to fetch from API!");
|
throw new MeaterException("Failed to fetch from API");
|
||||||
} catch (ExecutionException e) {
|
} catch (ExecutionException e) {
|
||||||
Throwable cause = e.getCause();
|
Throwable cause = e.getCause();
|
||||||
if (cause instanceof HttpResponseException httpResponseException) {
|
if (cause instanceof HttpResponseException httpResponseException) {
|
||||||
@ -201,7 +204,7 @@ public class MeaterRestAPI {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (json.isEmpty()) {
|
if (json.isEmpty()) {
|
||||||
throw new MeaterException("JSON from API is empty!");
|
throw new MeaterException("JSON from API is empty");
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
return gson.fromJson(json, dto);
|
return gson.fromJson(json, dto);
|
||||||
|
@ -28,6 +28,7 @@ import org.openhab.binding.meater.internal.MeaterBridgeConfiguration;
|
|||||||
import org.openhab.binding.meater.internal.api.MeaterRestAPI;
|
import org.openhab.binding.meater.internal.api.MeaterRestAPI;
|
||||||
import org.openhab.binding.meater.internal.discovery.MeaterDiscoveryService;
|
import org.openhab.binding.meater.internal.discovery.MeaterDiscoveryService;
|
||||||
import org.openhab.binding.meater.internal.dto.MeaterProbeDTO;
|
import org.openhab.binding.meater.internal.dto.MeaterProbeDTO;
|
||||||
|
import org.openhab.binding.meater.internal.exceptions.MeaterException;
|
||||||
import org.openhab.core.i18n.LocaleProvider;
|
import org.openhab.core.i18n.LocaleProvider;
|
||||||
import org.openhab.core.i18n.TranslationProvider;
|
import org.openhab.core.i18n.TranslationProvider;
|
||||||
import org.openhab.core.thing.Bridge;
|
import org.openhab.core.thing.Bridge;
|
||||||
@ -109,23 +110,24 @@ public class MeaterBridgeHandler extends BaseBridgeHandler {
|
|||||||
meaterProbeThings.clear();
|
meaterProbeThings.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean refreshAndUpdateStatus() {
|
private void refreshAndUpdateStatus() {
|
||||||
MeaterRestAPI localAPI = api;
|
MeaterRestAPI localAPI = api;
|
||||||
if (localAPI != null) {
|
if (localAPI == null) {
|
||||||
if (localAPI.refresh(meaterProbeThings)) {
|
return;
|
||||||
updateStatus(ThingStatus.ONLINE);
|
}
|
||||||
getThing().getThings().stream().forEach(thing -> {
|
|
||||||
MeaterHandler handler = (MeaterHandler) thing.getHandler();
|
try {
|
||||||
if (handler != null) {
|
localAPI.refresh(meaterProbeThings);
|
||||||
handler.update();
|
updateStatus(ThingStatus.ONLINE);
|
||||||
}
|
getThing().getThings().stream().forEach(thing -> {
|
||||||
});
|
MeaterHandler handler = (MeaterHandler) thing.getHandler();
|
||||||
return true;
|
if (handler != null) {
|
||||||
} else {
|
handler.update();
|
||||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR);
|
}
|
||||||
}
|
});
|
||||||
|
} catch (MeaterException e) {
|
||||||
|
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, e.getMessage());
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void startAutomaticRefresh() {
|
private void startAutomaticRefresh() {
|
||||||
|
Loading…
Reference in New Issue
Block a user