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.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 {
60 private State state = State.DISCONNECTED;
61 private final WebSocketClient client;
62 private @Nullable Session session;
63 private @Nullable WebOSTVMouseSocketListener listener;
65 public LGWebOSTVMouseSocket(WebSocketClient client) {
69 public State getState() {
73 private void setState(State state) {
74 State oldState = this.state;
76 Optional.ofNullable(this.listener).ifPresent(l -> l.onStateChanged(oldState, this.state));
79 public interface WebOSTVMouseSocketListener {
81 public void onStateChanged(State oldState, State newState);
83 public void onError(String errorMessage);
86 public void setListener(@Nullable WebOSTVMouseSocketListener listener) {
87 this.listener = listener;
90 public void connect(URI destUri) {
92 if (state != State.DISCONNECTED) {
93 logger.debug("Already connecting; not trying to connect again: {}", state);
96 setState(State.CONNECTING);
100 this.client.connect(this, destUri);
101 logger.debug("Connecting to: {}", destUri);
102 } catch (IOException e) {
103 logger.warn("Unable to connect.", e);
104 setState(State.DISCONNECTED);
108 public void disconnect() {
109 setState(State.DISCONNECTING);
111 Optional.ofNullable(this.session).ifPresent(s -> s.close());
112 } catch (Exception e) {
113 logger.debug("Error connecting to device.", e);
115 setState(State.DISCONNECTED);
119 public void onClose(int statusCode, String reason) {
120 setState(State.DISCONNECTED);
121 logger.debug("WebSocket Closed - Code: {}, Reason: {}", statusCode, reason);
126 public void onConnect(Session session) {
127 logger.debug("WebSocket Connected to: {}", session.getRemoteAddress().getAddress());
128 this.session = session;
129 setState(State.CONNECTED);
133 public void onMessage(String message) {
134 logger.debug("Message [in]: {}", message);
138 public void onError(Throwable cause) {
139 String message = cause.getMessage();
140 Optional.ofNullable(this.listener).ifPresent(l -> l.onError(message != null ? message : ""));
141 logger.debug("Connection Error.", cause);
144 private void sendMessage(String msg) {
145 Session s = this.session;
148 logger.debug("Message [out]: {}", msg);
149 s.getRemote().sendString(msg);
151 logger.warn("No Connection to TV, skipping [out]: {}", msg);
154 } catch (IOException e) {
155 logger.error("Unable to send message.", e);
159 public void click() {
160 sendMessage("type:click\n" + "\n");
163 public void button(ButtonType type) {
199 public void button(String keyName) {
200 sendMessage("type:button\n" + "name:" + keyName + "\n" + "\n");
203 public void move(double dx, double dy) {
204 sendMessage("type:move\n" + "dx:" + dx + "\n" + "dy:" + dy + "\n" + "down:0\n" + "\n");
207 public void move(double dx, double dy, boolean drag) {
208 sendMessage("type:move\n" + "dx:" + dx + "\n" + "dy:" + dy + "\n" + "down:" + (drag ? 1 : 0) + "\n" + "\n");
211 public void scroll(double dx, double dy) {
212 sendMessage("type:scroll\n" + "dx:" + dx + "\n" + "dy:" + dy + "\n" + "\n");