]> git.basschouten.com Git - openhab-addons.git/blob
770eb43ada1b57a2d002ee6b74e21aeca65d8038
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2024 Contributors to the openHAB project
3  *
4  * See the NOTICE file(s) distributed with this work for additional
5  * information.
6  *
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
10  *
11  * SPDX-License-Identifier: EPL-2.0
12  */
13 package org.openhab.binding.siemenshvac.internal.network;
14
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;
20
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;
36
37 import com.google.gson.Gson;
38 import com.google.gson.JsonObject;
39 import com.google.gson.JsonSyntaxException;
40
41 /**
42  * @author Laurent Arnal - Initial contribution
43  */
44 @NonNullByDefault
45 public class SiemensHvacRequestListener extends BufferingResponseListener
46         implements SuccessListener, FailureListener, ContentListener, CompleteListener, QueuedListener, BeginListener {
47
48     public enum ErrorSource {
49         ErrorBridge,
50         ErrorThings
51     }
52
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;
58
59     private final Logger logger = LoggerFactory.getLogger(SiemensHvacRequestListener.class);
60
61     private SiemensHvacRequestHandler requestHandler;
62     private SiemensHvacConnector hvacConnector;
63
64     /**
65      * Callback to execute on complete response
66      */
67     private final SiemensHvacCallback callback;
68
69     public static int getQueuedCount() {
70         return onQueuedCount;
71     }
72
73     public static int getStartedCount() {
74         return onBeginCount;
75     }
76
77     public static int getCompleteCount() {
78         return onCompleteCount;
79     }
80
81     public static int getFailureCount() {
82         return onFailureCount;
83     }
84
85     public static int getSuccessCount() {
86         return onSuccessCount;
87     }
88
89     /**
90      * Constructor
91      *
92      * @param callback Callback which execute method has to be called.
93      */
94     public SiemensHvacRequestListener(SiemensHvacRequestHandler requestHandler) {
95         this.requestHandler = requestHandler;
96         this.hvacConnector = requestHandler.getHvacConnector();
97         this.callback = requestHandler.getCallback();
98     }
99
100     @Override
101     public void onSuccess(@Nullable Response response) {
102         onSuccessCount++;
103         requestHandler.setResponse(response);
104
105         if (response != null) {
106             logger.debug("{} response: {}", response.getRequest().getURI(), response.getStatus());
107         }
108     }
109
110     @Override
111     public void onFailure(@Nullable Response response, @Nullable Throwable failure) {
112         onFailureCount++;
113         requestHandler.setResponse(response);
114
115         if (response != null && failure != null) {
116             Throwable cause = failure.getCause();
117             if (cause == null) {
118                 cause = failure;
119             }
120
121             String msg = cause.getLocalizedMessage();
122
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);
133             } else {
134                 logger.debug("Response failed: {}  {}", response.getRequest().getURI(), msg, failure);
135             }
136         }
137     }
138
139     @Override
140     public void onQueued(@Nullable Request request) {
141         onQueuedCount++;
142         requestHandler.setRequest(request);
143     }
144
145     @Override
146     public void onBegin(@Nullable Request request) {
147         onBeginCount++;
148         requestHandler.setRequest(request);
149     }
150
151     @Override
152     public void onComplete(@Nullable Result result) {
153         onCompleteCount++;
154         requestHandler.setResult(result);
155
156         if (result == null) {
157             return;
158         }
159
160         try {
161             String content = getContentAsString();
162             logger.trace("response complete: {}", content);
163             boolean mayRetry = true;
164
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);
168                 return;
169             }
170
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);
175                 } else {
176                     JsonObject resultObj = null;
177                     try {
178                         Gson gson = hvacConnector.getGson();
179                         resultObj = gson.fromJson(content, JsonObject.class);
180                     } catch (JsonSyntaxException ex) {
181                         logger.debug("error(1): {}", ex.toString());
182                     }
183
184                     if (resultObj != null && resultObj.has("Result")) {
185                         JsonObject subResultObj = resultObj.getAsJsonObject("Result");
186
187                         if (subResultObj.has("Success")) {
188                             boolean resultVal = subResultObj.get("Success").getAsBoolean();
189                             JsonObject error = subResultObj.getAsJsonObject("Error");
190                             String errorMsg = "";
191                             if (error != null) {
192                                 errorMsg = error.get("Txt").getAsString();
193                             }
194
195                             if (errorMsg.indexOf("session") >= 0) {
196                                 String query = result.getRequest().getURI().getQuery();
197                                 String sessionId = SiemensHvacConnectorImpl.extractSessionId(query);
198
199                                 hvacConnector.resetSessionId(sessionId, false);
200                                 hvacConnector.resetSessionId(sessionId, true);
201                                 mayRetry = false;
202                             }
203
204                             if (resultVal) {
205                                 hvacConnector.onComplete(result.getRequest(), requestHandler);
206                                 callback.execute(result.getRequest().getURI(), result.getResponse().getStatus(),
207                                         resultObj);
208
209                                 return;
210                             } else if (("datatype not supported").equals(errorMsg)) {
211                                 hvacConnector.onComplete(result.getRequest(), requestHandler);
212                                 callback.execute(result.getRequest().getURI(), result.getResponse().getStatus(),
213                                         resultObj);
214                                 return;
215                             } else if (("read failed").equals(errorMsg)) {
216                                 logger.debug("error(2): {}", subResultObj);
217                                 hvacConnector.onError(result.getRequest(), requestHandler, ErrorSource.ErrorThings,
218                                         mayRetry);
219                             } else {
220                                 logger.debug("error(3): {}", subResultObj);
221                                 hvacConnector.onError(result.getRequest(), requestHandler, ErrorSource.ErrorBridge,
222                                         mayRetry);
223                                 return;
224                             }
225                         } else {
226                             logger.debug("error(4): invalid response from gateway, missing subResultObj:Success entry");
227                             hvacConnector.onError(result.getRequest(), requestHandler, ErrorSource.ErrorBridge,
228                                     mayRetry);
229                             return;
230                         }
231
232                     } else {
233                         logger.debug("error(5): invalid response from gateway, missing Result entry");
234                         hvacConnector.onError(result.getRequest(), requestHandler, ErrorSource.ErrorBridge, mayRetry);
235                         return;
236                     }
237                 }
238             } else {
239                 logger.debug("error: content == null");
240                 hvacConnector.onError(result.getRequest(), requestHandler, ErrorSource.ErrorBridge, mayRetry);
241                 return;
242             }
243         } catch (SiemensHvacException ex) {
244             logger.debug("An error occurred", ex);
245         }
246     }
247 }