]> git.basschouten.com Git - openhab-addons.git/blob
ec7b49eaa1a033a2e421770ecde743656c41b677
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2021 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.lgwebos.internal.handler;
14
15 import java.io.IOException;
16 import java.net.URI;
17 import java.util.Optional;
18
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;
30
31 /**
32  * WebSocket implementation to connect to WebOSTV mouse api.
33  *
34  * @author Sebastian Prehn - Initial contribution
35  *
36  */
37 @WebSocket()
38 @NonNullByDefault
39 public class LGWebOSTVMouseSocket {
40     private final Logger logger = LoggerFactory.getLogger(LGWebOSTVMouseSocket.class);
41
42     public enum State {
43         DISCONNECTED,
44         CONNECTING,
45         CONNECTED,
46         DISCONNECTING
47     }
48
49     public enum ButtonType {
50         HOME,
51         BACK,
52         UP,
53         DOWN,
54         LEFT,
55         RIGHT,
56     }
57
58     private State state = State.DISCONNECTED;
59     private final WebSocketClient client;
60     private @Nullable Session session;
61     private @Nullable WebOSTVMouseSocketListener listener;
62
63     public LGWebOSTVMouseSocket(WebSocketClient client) {
64         this.client = client;
65     }
66
67     public State getState() {
68         return state;
69     }
70
71     private void setState(State state) {
72         State oldState = this.state;
73         this.state = state;
74         Optional.ofNullable(this.listener).ifPresent(l -> l.onStateChanged(oldState, this.state));
75     }
76
77     public interface WebOSTVMouseSocketListener {
78
79         public void onStateChanged(State oldState, State newState);
80
81         public void onError(String errorMessage);
82     }
83
84     public void setListener(@Nullable WebOSTVMouseSocketListener listener) {
85         this.listener = listener;
86     }
87
88     public void connect(URI destUri) {
89         synchronized (this) {
90             if (state != State.DISCONNECTED) {
91                 logger.debug("Already connecting; not trying to connect again: {}", state);
92                 return;
93             }
94             setState(State.CONNECTING);
95         }
96
97         try {
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);
103         }
104     }
105
106     public void disconnect() {
107         setState(State.DISCONNECTING);
108         try {
109             Optional.ofNullable(this.session).ifPresent(s -> s.close());
110         } catch (Exception e) {
111             logger.debug("Error connecting to device.", e);
112         }
113         setState(State.DISCONNECTED);
114     }
115
116     @OnWebSocketClose
117     public void onClose(int statusCode, String reason) {
118         setState(State.DISCONNECTED);
119         logger.debug("WebSocket Closed - Code: {}, Reason: {}", statusCode, reason);
120         this.session = null;
121     }
122
123     @OnWebSocketConnect
124     public void onConnect(Session session) {
125         logger.debug("WebSocket Connected to: {}", session.getRemoteAddress().getAddress());
126         this.session = session;
127         setState(State.CONNECTED);
128     }
129
130     @OnWebSocketMessage
131     public void onMessage(String message) {
132         logger.debug("Message [in]: {}", message);
133     }
134
135     @OnWebSocketError
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);
140     }
141
142     private void sendMessage(String msg) {
143         Session s = this.session;
144         try {
145             if (s != null) {
146                 logger.debug("Message [out]: {}", msg);
147                 s.getRemote().sendString(msg);
148             } else {
149                 logger.warn("No Connection to TV, skipping [out]: {}", msg);
150             }
151
152         } catch (IOException e) {
153             logger.error("Unable to send message.", e);
154         }
155     }
156
157     public void click() {
158         sendMessage("type:click\n" + "\n");
159     }
160
161     public void button(ButtonType type) {
162         String keyName;
163         switch (type) {
164             case HOME:
165                 keyName = "HOME";
166                 break;
167             case BACK:
168                 keyName = "BACK";
169                 break;
170             case UP:
171                 keyName = "UP";
172                 break;
173             case DOWN:
174                 keyName = "DOWN";
175                 break;
176             case LEFT:
177                 keyName = "LEFT";
178                 break;
179             case RIGHT:
180                 keyName = "RIGHT";
181                 break;
182
183             default:
184                 keyName = "NONE";
185                 break;
186         }
187
188         button(keyName);
189     }
190
191     public void button(String keyName) {
192         sendMessage("type:button\n" + "name:" + keyName + "\n" + "\n");
193     }
194
195     public void move(double dx, double dy) {
196         sendMessage("type:move\n" + "dx:" + dx + "\n" + "dy:" + dy + "\n" + "down:0\n" + "\n");
197     }
198
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");
201     }
202
203     public void scroll(double dx, double dy) {
204         sendMessage("type:scroll\n" + "dx:" + dx + "\n" + "dy:" + dy + "\n" + "\n");
205     }
206 }