2 * Copyright (c) 2010-2024 Contributors to the openHAB project
4 * See the NOTICE file(s) distributed with this work for additional
7 * This program and the accompanying materials are made available under the
8 * terms of the Eclipse Public License 2.0 which is available at
9 * http://www.eclipse.org/legal/epl-2.0
11 * SPDX-License-Identifier: EPL-2.0
13 package org.openhab.binding.siemenshvac.internal.network;
15 import java.io.EOFException;
16 import java.net.ConnectException;
17 import java.net.SocketException;
18 import java.net.SocketTimeoutException;
19 import java.util.concurrent.TimeoutException;
21 import org.eclipse.jdt.annotation.NonNullByDefault;
22 import org.eclipse.jdt.annotation.Nullable;
23 import org.eclipse.jetty.client.api.Request;
24 import org.eclipse.jetty.client.api.Request.BeginListener;
25 import org.eclipse.jetty.client.api.Request.QueuedListener;
26 import org.eclipse.jetty.client.api.Response;
27 import org.eclipse.jetty.client.api.Response.CompleteListener;
28 import org.eclipse.jetty.client.api.Response.ContentListener;
29 import org.eclipse.jetty.client.api.Response.FailureListener;
30 import org.eclipse.jetty.client.api.Response.SuccessListener;
31 import org.eclipse.jetty.client.api.Result;
32 import org.eclipse.jetty.client.util.BufferingResponseListener;
33 import org.openhab.binding.siemenshvac.internal.type.SiemensHvacException;
34 import org.slf4j.Logger;
35 import org.slf4j.LoggerFactory;
37 import com.google.gson.Gson;
38 import com.google.gson.JsonObject;
39 import com.google.gson.JsonSyntaxException;
42 * @author Laurent Arnal - Initial contribution
45 public class SiemensHvacRequestListener extends BufferingResponseListener
46 implements SuccessListener, FailureListener, ContentListener, CompleteListener, QueuedListener, BeginListener {
48 public enum ErrorSource {
53 private static int onSuccessCount = 0;
54 private static int onBeginCount = 0;
55 private static int onQueuedCount = 0;
56 private static int onCompleteCount = 0;
57 private static int onFailureCount = 0;
59 private final Logger logger = LoggerFactory.getLogger(SiemensHvacRequestListener.class);
61 private SiemensHvacRequestHandler requestHandler;
62 private SiemensHvacConnector hvacConnector;
65 * Callback to execute on complete response
67 private final SiemensHvacCallback callback;
69 public static int getQueuedCount() {
73 public static int getStartedCount() {
77 public static int getCompleteCount() {
78 return onCompleteCount;
81 public static int getFailureCount() {
82 return onFailureCount;
85 public static int getSuccessCount() {
86 return onSuccessCount;
92 * @param callback Callback which execute method has to be called.
94 public SiemensHvacRequestListener(SiemensHvacRequestHandler requestHandler) {
95 this.requestHandler = requestHandler;
96 this.hvacConnector = requestHandler.getHvacConnector();
97 this.callback = requestHandler.getCallback();
101 public void onSuccess(@Nullable Response response) {
103 requestHandler.setResponse(response);
105 if (response != null) {
106 logger.debug("{} response: {}", response.getRequest().getURI(), response.getStatus());
111 public void onFailure(@Nullable Response response, @Nullable Throwable failure) {
113 requestHandler.setResponse(response);
115 if (response != null && failure != null) {
116 Throwable cause = failure.getCause();
121 String msg = cause.getLocalizedMessage();
123 if (cause instanceof ConnectException e) {
124 logger.debug("ConnectException during request: {} {}", response.getRequest().getURI(), msg, e);
125 } else if (cause instanceof SocketException e) {
126 logger.debug("SocketException during request: {} {}", response.getRequest().getURI(), msg, e);
127 } else if (cause instanceof SocketTimeoutException e) {
128 logger.debug("SocketTimeoutException during request: {} {}", response.getRequest().getURI(), msg, e);
129 } else if (cause instanceof EOFException e) {
130 logger.debug("EOFException during request: {} {}", response.getRequest().getURI(), msg, e);
131 } else if (cause instanceof TimeoutException e) {
132 logger.debug("TimeoutException during request: {} {}", response.getRequest().getURI(), msg, e);
134 logger.debug("Response failed: {} {}", response.getRequest().getURI(), msg, failure);
140 public void onQueued(@Nullable Request request) {
142 requestHandler.setRequest(request);
146 public void onBegin(@Nullable Request request) {
148 requestHandler.setRequest(request);
152 public void onComplete(@Nullable Result result) {
154 requestHandler.setResult(result);
156 if (result == null) {
161 String content = getContentAsString();
162 logger.trace("response complete: {}", content);
163 boolean mayRetry = true;
165 if (result.getResponse().getStatus() != 200) {
166 logger.debug("Error requesting gateway, non success code: {}", result.getResponse().getStatus());
167 hvacConnector.onError(result.getRequest(), requestHandler, ErrorSource.ErrorBridge, mayRetry);
171 if (content != null) {
172 if (content.indexOf("<!DOCTYPE html>") >= 0) {
173 hvacConnector.onComplete(result.getRequest(), requestHandler);
174 callback.execute(result.getRequest().getURI(), result.getResponse().getStatus(), content);
176 JsonObject resultObj = null;
178 Gson gson = hvacConnector.getGson();
179 resultObj = gson.fromJson(content, JsonObject.class);
180 } catch (JsonSyntaxException ex) {
181 logger.debug("error(1): {}", ex.toString());
184 if (resultObj != null && resultObj.has("Result")) {
185 JsonObject subResultObj = resultObj.getAsJsonObject("Result");
187 if (subResultObj.has("Success")) {
188 boolean resultVal = subResultObj.get("Success").getAsBoolean();
189 JsonObject error = subResultObj.getAsJsonObject("Error");
190 String errorMsg = "";
192 errorMsg = error.get("Txt").getAsString();
195 if (errorMsg.indexOf("session") >= 0) {
196 String query = result.getRequest().getURI().getQuery();
197 String sessionId = SiemensHvacConnectorImpl.extractSessionId(query);
199 hvacConnector.resetSessionId(sessionId, false);
200 hvacConnector.resetSessionId(sessionId, true);
205 hvacConnector.onComplete(result.getRequest(), requestHandler);
206 callback.execute(result.getRequest().getURI(), result.getResponse().getStatus(),
210 } else if (("datatype not supported").equals(errorMsg)) {
211 hvacConnector.onComplete(result.getRequest(), requestHandler);
212 callback.execute(result.getRequest().getURI(), result.getResponse().getStatus(),
215 } else if (("read failed").equals(errorMsg)) {
216 logger.debug("error(2): {}", subResultObj);
217 hvacConnector.onError(result.getRequest(), requestHandler, ErrorSource.ErrorThings,
220 logger.debug("error(3): {}", subResultObj);
221 hvacConnector.onError(result.getRequest(), requestHandler, ErrorSource.ErrorBridge,
226 logger.debug("error(4): invalid response from gateway, missing subResultObj:Success entry");
227 hvacConnector.onError(result.getRequest(), requestHandler, ErrorSource.ErrorBridge,
233 logger.debug("error(5): invalid response from gateway, missing Result entry");
234 hvacConnector.onError(result.getRequest(), requestHandler, ErrorSource.ErrorBridge, mayRetry);
239 logger.debug("error: content == null");
240 hvacConnector.onError(result.getRequest(), requestHandler, ErrorSource.ErrorBridge, mayRetry);
243 } catch (SiemensHvacException ex) {
244 logger.debug("An error occurred", ex);