2 * Copyright (c) 2010-2020 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.deconz.internal.netutils;
17 import java.util.concurrent.ConcurrentHashMap;
19 import org.eclipse.jdt.annotation.NonNullByDefault;
20 import org.eclipse.jetty.websocket.api.Session;
21 import org.eclipse.jetty.websocket.api.annotations.OnWebSocketClose;
22 import org.eclipse.jetty.websocket.api.annotations.OnWebSocketConnect;
23 import org.eclipse.jetty.websocket.api.annotations.OnWebSocketError;
24 import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage;
25 import org.eclipse.jetty.websocket.api.annotations.WebSocket;
26 import org.eclipse.jetty.websocket.client.WebSocketClient;
27 import org.openhab.binding.deconz.internal.dto.DeconzBaseMessage;
28 import org.openhab.binding.deconz.internal.dto.LightMessage;
29 import org.openhab.binding.deconz.internal.dto.SensorMessage;
30 import org.slf4j.Logger;
31 import org.slf4j.LoggerFactory;
33 import com.google.gson.Gson;
36 * Establishes and keeps a websocket connection to the deCONZ software.
38 * The connection is closed by deCONZ now and then and needs to be re-established.
40 * @author David Graeff - Initial contribution
44 public class WebSocketConnection {
45 private final Logger logger = LoggerFactory.getLogger(WebSocketConnection.class);
47 private final WebSocketClient client;
48 private final WebSocketConnectionListener connectionListener;
49 private final Map<String, WebSocketMessageListener> sensorListener = new ConcurrentHashMap<>();
50 private final Map<String, WebSocketMessageListener> lightListener = new ConcurrentHashMap<>();
51 private final Gson gson;
52 private boolean connected = false;
54 public WebSocketConnection(WebSocketConnectionListener listener, WebSocketClient client, Gson gson) {
55 this.connectionListener = listener;
57 this.client.setMaxIdleTimeout(0);
61 public void start(String ip) {
66 URI destUri = URI.create("ws://" + ip);
70 logger.debug("Connecting to: {}", destUri);
71 client.connect(this, destUri).get();
72 } catch (Exception e) {
73 connectionListener.connectionError(e);
81 } catch (Exception e) {
82 logger.debug("Error while closing connection", e);
87 public void registerSensorListener(String sensorID, WebSocketMessageListener listener) {
88 sensorListener.put(sensorID, listener);
91 public void unregisterSensorListener(String sensorID) {
92 sensorListener.remove(sensorID);
95 public void registerLightListener(String lightID, WebSocketMessageListener listener) {
96 lightListener.put(lightID, listener);
99 public void unregisterLightListener(String lightID) {
100 sensorListener.remove(lightID);
104 public void onConnect(Session session) {
106 logger.debug("Connect: {}", session.getRemoteAddress().getAddress());
107 connectionListener.connectionEstablished();
110 @SuppressWarnings("null")
112 public void onMessage(String message) {
113 logger.trace("Raw data received by websocket: {}", message);
114 DeconzBaseMessage changedMessage = gson.fromJson(message, DeconzBaseMessage.class);
115 switch (changedMessage.r) {
117 WebSocketMessageListener listener = sensorListener.get(changedMessage.id);
118 if (listener != null) {
119 listener.messageReceived(changedMessage.id, gson.fromJson(message, SensorMessage.class));
121 logger.trace("Couldn't find sensor listener for id {}", changedMessage.id);
125 listener = lightListener.get(changedMessage.id);
126 if (listener != null) {
127 listener.messageReceived(changedMessage.id, gson.fromJson(message, LightMessage.class));
129 logger.trace("Couldn't find light listener for id {}", changedMessage.id);
133 logger.debug("Unknown message type: {}", changedMessage.r);
138 public void onError(Throwable cause) {
140 connectionListener.connectionError(cause);
144 public void onClose(int statusCode, String reason) {
146 connectionListener.connectionLost(reason);
149 public boolean isConnected() {