]> git.basschouten.com Git - openhab-addons.git/blob
e360b6cae39e996f2b458a81c782c11e0eaf1fba
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2020 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         Optional.ofNullable(this.listener).ifPresent(l -> l.onError(cause.getMessage()));
138         logger.debug("Connection Error.", cause);
139     }
140
141     private void sendMessage(String msg) {
142         Session s = this.session;
143         try {
144             if (s != null) {
145                 logger.debug("Message [out]: {}", msg);
146                 s.getRemote().sendString(msg);
147             } else {
148                 logger.warn("No Connection to TV, skipping [out]: {}", msg);
149             }
150
151         } catch (IOException e) {
152             logger.error("Unable to send message.", e);
153         }
154     }
155
156     public void click() {
157         sendMessage("type:click\n" + "\n");
158     }
159
160     public void button(ButtonType type) {
161         String keyName;
162         switch (type) {
163             case HOME:
164                 keyName = "HOME";
165                 break;
166             case BACK:
167                 keyName = "BACK";
168                 break;
169             case UP:
170                 keyName = "UP";
171                 break;
172             case DOWN:
173                 keyName = "DOWN";
174                 break;
175             case LEFT:
176                 keyName = "LEFT";
177                 break;
178             case RIGHT:
179                 keyName = "RIGHT";
180                 break;
181
182             default:
183                 keyName = "NONE";
184                 break;
185         }
186
187         button(keyName);
188     }
189
190     public void button(String keyName) {
191         sendMessage("type:button\n" + "name:" + keyName + "\n" + "\n");
192     }
193
194     public void move(double dx, double dy) {
195         sendMessage("type:move\n" + "dx:" + dx + "\n" + "dy:" + dy + "\n" + "down:0\n" + "\n");
196     }
197
198     public void move(double dx, double dy, boolean drag) {
199         sendMessage("type:move\n" + "dx:" + dx + "\n" + "dy:" + dy + "\n" + "down:" + (drag ? 1 : 0) + "\n" + "\n");
200     }
201
202     public void scroll(double dx, double dy) {
203         sendMessage("type:scroll\n" + "dx:" + dx + "\n" + "dy:" + dy + "\n" + "\n");
204     }
205 }