2 * Copyright (c) 2010-2021 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.lgwebos.internal.handler;
15 import java.io.IOException;
17 import java.util.Optional;
19 import org.eclipse.jdt.annotation.NonNullByDefault;
20 import org.eclipse.jdt.annotation.Nullable;
21 import org.eclipse.jetty.websocket.api.Session;
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.slf4j.Logger;
29 import org.slf4j.LoggerFactory;
32 * WebSocket implementation to connect to WebOSTV mouse api.
34 * @author Sebastian Prehn - Initial contribution
39 public class LGWebOSTVMouseSocket {
40 private final Logger logger = LoggerFactory.getLogger(LGWebOSTVMouseSocket.class);
49 public enum ButtonType {
58 private State state = State.DISCONNECTED;
59 private final WebSocketClient client;
60 private @Nullable Session session;
61 private @Nullable WebOSTVMouseSocketListener listener;
63 public LGWebOSTVMouseSocket(WebSocketClient client) {
67 public State getState() {
71 private void setState(State state) {
72 State oldState = this.state;
74 Optional.ofNullable(this.listener).ifPresent(l -> l.onStateChanged(oldState, this.state));
77 public interface WebOSTVMouseSocketListener {
79 public void onStateChanged(State oldState, State newState);
81 public void onError(String errorMessage);
84 public void setListener(@Nullable WebOSTVMouseSocketListener listener) {
85 this.listener = listener;
88 public void connect(URI destUri) {
90 if (state != State.DISCONNECTED) {
91 logger.debug("Already connecting; not trying to connect again: {}", state);
94 setState(State.CONNECTING);
98 this.client.connect(this, destUri);
99 logger.debug("Connecting to: {}", destUri);
100 } catch (IOException e) {
101 logger.warn("Unable to connect.", e);
102 setState(State.DISCONNECTED);
106 public void disconnect() {
107 setState(State.DISCONNECTING);
109 Optional.ofNullable(this.session).ifPresent(s -> s.close());
110 } catch (Exception e) {
111 logger.debug("Error connecting to device.", e);
113 setState(State.DISCONNECTED);
117 public void onClose(int statusCode, String reason) {
118 setState(State.DISCONNECTED);
119 logger.debug("WebSocket Closed - Code: {}, Reason: {}", statusCode, reason);
124 public void onConnect(Session session) {
125 logger.debug("WebSocket Connected to: {}", session.getRemoteAddress().getAddress());
126 this.session = session;
127 setState(State.CONNECTED);
131 public void onMessage(String message) {
132 logger.debug("Message [in]: {}", message);
136 public void onError(Throwable cause) {
137 String message = cause.getMessage();
138 Optional.ofNullable(this.listener).ifPresent(l -> l.onError(message != null ? message : ""));
139 logger.debug("Connection Error.", cause);
142 private void sendMessage(String msg) {
143 Session s = this.session;
146 logger.debug("Message [out]: {}", msg);
147 s.getRemote().sendString(msg);
149 logger.warn("No Connection to TV, skipping [out]: {}", msg);
152 } catch (IOException e) {
153 logger.error("Unable to send message.", e);
157 public void click() {
158 sendMessage("type:click\n" + "\n");
161 public void button(ButtonType type) {
191 public void button(String keyName) {
192 sendMessage("type:button\n" + "name:" + keyName + "\n" + "\n");
195 public void move(double dx, double dy) {
196 sendMessage("type:move\n" + "dx:" + dx + "\n" + "dy:" + dy + "\n" + "down:0\n" + "\n");
199 public void move(double dx, double dy, boolean drag) {
200 sendMessage("type:move\n" + "dx:" + dx + "\n" + "dy:" + dy + "\n" + "down:" + (drag ? 1 : 0) + "\n" + "\n");
203 public void scroll(double dx, double dy) {
204 sendMessage("type:scroll\n" + "dx:" + dx + "\n" + "dy:" + dy + "\n" + "\n");