2 * Copyright (c) 2010-2023 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.innogysmarthome.internal;
17 import org.eclipse.jdt.annotation.NonNullByDefault;
18 import org.eclipse.jdt.annotation.Nullable;
19 import org.eclipse.jetty.util.ssl.SslContextFactory;
20 import org.eclipse.jetty.websocket.api.Session;
21 import org.eclipse.jetty.websocket.api.StatusCode;
22 import org.eclipse.jetty.websocket.api.annotations.OnWebSocketClose;
23 import org.eclipse.jetty.websocket.api.annotations.OnWebSocketConnect;
24 import org.eclipse.jetty.websocket.api.annotations.OnWebSocketError;
25 import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage;
26 import org.eclipse.jetty.websocket.api.annotations.WebSocket;
27 import org.eclipse.jetty.websocket.client.WebSocketClient;
28 import org.openhab.binding.innogysmarthome.internal.handler.InnogyBridgeHandler;
29 import org.openhab.binding.innogysmarthome.internal.listener.EventListener;
30 import org.slf4j.Logger;
31 import org.slf4j.LoggerFactory;
34 * The {@link InnogyWebSocket} implements the websocket for receiving constant updates
35 * from the innogy SmartHome web service.
37 * @author Oliver Kuhl - Initial contribution
41 public class InnogyWebSocket {
43 private final Logger logger = LoggerFactory.getLogger(InnogyWebSocket.class);
44 private final EventListener eventListener;
45 private final URI webSocketURI;
46 private final int maxIdleTimeout;
48 private @Nullable Session session;
49 private @Nullable WebSocketClient client;
50 private boolean closing;
53 * Constructs the {@link InnogyWebSocket}.
55 * @param eventListener the responsible {@link InnogyBridgeHandler}
56 * @param webSocketURI the {@link URI} of the websocket endpoint
57 * @param maxIdleTimeout
59 public InnogyWebSocket(EventListener eventListener, URI webSocketURI, int maxIdleTimeout) {
60 this.eventListener = eventListener;
61 this.webSocketURI = webSocketURI;
62 this.maxIdleTimeout = maxIdleTimeout;
66 * Starts the {@link InnogyWebSocket}.
70 public synchronized void start() throws Exception {
71 if (client == null || client.isStopped()) {
72 client = startWebSocketClient();
75 if (session != null) {
79 logger.debug("Connecting to innogy WebSocket...");
80 session = client.connect(this, webSocketURI).get();
84 * Stops the {@link InnogyWebSocket}.
86 public synchronized void stop() {
89 logger.debug("Closing session...");
94 logger.trace("Stopping websocket ignored - was not running.");
100 } catch (Exception e) {
101 logger.debug("Stopping websocket failed", e);
108 * Return true, if the websocket is running.
112 public synchronized boolean isRunning() {
113 return session != null && session.isOpen();
117 public void onConnect(Session session) {
118 this.closing = false;
119 logger.info("Connected to innogy Webservice.");
120 logger.trace("innogy Websocket session: {}", session);
124 public void onClose(int statusCode, String reason) {
125 if (statusCode == StatusCode.NORMAL) {
126 logger.info("Connection to innogy Webservice was closed normally.");
127 } else if (!closing) {
128 // An additional reconnect attempt is only required when the close/stop wasn't executed by the binding.
129 logger.info("Connection to innogy Webservice was closed abnormally (code: {}). Reason: {}", statusCode,
131 eventListener.connectionClosed();
136 public void onError(Throwable cause) {
137 logger.debug("innogy WebSocket onError() - {}", cause.getMessage());
138 eventListener.onError(cause);
142 public void onMessage(String msg) {
143 logger.debug("innogy WebSocket onMessage() - {}", msg);
145 logger.debug("innogy WebSocket onMessage() - ignored, WebSocket is closing...");
147 eventListener.onEvent(msg);
151 WebSocketClient startWebSocketClient() throws Exception {
152 WebSocketClient client = new WebSocketClient(new SslContextFactory.Client());
153 client.setMaxIdleTimeout(this.maxIdleTimeout);