[yioremote] Fixed reconnection and thing creation issues (#8596)
Signed-off-by: Michael Loercher <MichaelLoercher@web.de>
This commit is contained in:
parent
4e72980c6c
commit
4b91bfcfa0
|
@ -8,7 +8,7 @@ Since this binding allows actual you to trigger IR send/receive actions on YIO D
|
|||
|
||||
## Supported Things
|
||||
|
||||
* Thing Type ID: `yioremotedock`
|
||||
* Thing Type ID: `yioRemoteDock`
|
||||
|
||||
The following are the configurations available to each of the bridges/things:
|
||||
|
||||
|
@ -41,7 +41,7 @@ rule "yioremote Action Example"
|
|||
when
|
||||
...
|
||||
then
|
||||
val actions = getActions("yioremote", "yioremote:yioremotedock:livingroom")
|
||||
val actions = getActions("yioremote", "yioremote:yioRemoteDock:livingroom")
|
||||
if (actions === null)
|
||||
{
|
||||
......
|
||||
|
@ -58,22 +58,20 @@ end
|
|||
.things
|
||||
|
||||
```
|
||||
yioremote:yioremotedock:livingroom [ host="192.168.178.21", accesstoken="0" ]
|
||||
yioremote:yioRemoteDock:livingroom [ host="xxx.xxx.xxx.xxx", accesstoken="0" ]
|
||||
```
|
||||
|
||||
.items
|
||||
|
||||
```
|
||||
String sendircode "IR CODE [%s]" {channel="yioremote:yioremotedock:livingroom:input# sendircode"}
|
||||
Switch receiverswitch "IR recieving switch" {channel="yioremote:yioremotedock:livingroom:input# receiverswitch"}
|
||||
String status "YIO Dock status[%s]" {channel="yioremote:yioremotedock:livingroom:output# status"}
|
||||
Switch receiverswitch "IR recieving switch" {channel="yioremote:yioRemoteDock:livingroom:input# receiverswitch"}
|
||||
String status "YIO Dock status[%s]" {channel="yioremote:yioRemoteDock:livingroom:output# status"}
|
||||
```
|
||||
|
||||
.sitemap
|
||||
|
||||
```
|
||||
sitemap Basic label="YIO Dock" {
|
||||
Text item= sendircode
|
||||
Switch item= receiverswitch
|
||||
Text item= status
|
||||
}
|
||||
|
|
|
@ -33,7 +33,9 @@ public class YIOremoteBindingConstants {
|
|||
AUTHENTICATION_FAILED,
|
||||
AUTHENTICATION_COMPLETE,
|
||||
CONNECTION_FAILED,
|
||||
CONNECTION_ESTABLISHED;
|
||||
CONNECTION_ESTABLISHED,
|
||||
COMMUNICATION_ERROR,
|
||||
RECONNECTION_PROCESS;
|
||||
}
|
||||
|
||||
public static enum YioRemoteMessages {
|
||||
|
@ -45,7 +47,7 @@ public class YIOremoteBindingConstants {
|
|||
}
|
||||
|
||||
// List of all Thing Type UIDs
|
||||
public static final ThingTypeUID THING_TYPE_YIOREMOTEDOCK = new ThingTypeUID(BINDING_ID, "yioremotedock");
|
||||
public static final ThingTypeUID THING_TYPE_YIOREMOTEDOCK = new ThingTypeUID(BINDING_ID, "yioRemoteDock");
|
||||
|
||||
// List of all Channel Groups Group Channel ids
|
||||
public static final String GROUP_INPUT = "input";
|
||||
|
|
|
@ -69,6 +69,7 @@ public class YIOremoteDockHandler extends BaseThingHandler {
|
|||
private @Nullable URI websocketAddress;
|
||||
private YioRemoteDockHandleStatus yioRemoteDockActualStatus = YioRemoteDockHandleStatus.UNINITIALIZED_STATE;
|
||||
private @Nullable Future<?> webSocketPollingJob;
|
||||
private @Nullable Future<?> webSocketReconnectionPollingJob;
|
||||
public String receivedMessage = "";
|
||||
private JsonObject recievedJson = new JsonObject();
|
||||
private boolean heartBeat = false;
|
||||
|
@ -119,7 +120,10 @@ public class YIOremoteDockHandler extends BaseThingHandler {
|
|||
switch (yioRemoteDockActualStatus) {
|
||||
case CONNECTION_ESTABLISHED:
|
||||
case AUTHENTICATION_PROCESS:
|
||||
authenticate();
|
||||
authenticateWebsocket();
|
||||
break;
|
||||
case COMMUNICATION_ERROR:
|
||||
reconnectWebsocket();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -132,13 +136,15 @@ public class YIOremoteDockHandler extends BaseThingHandler {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onError() {
|
||||
if (webSocketPollingJob != null) {
|
||||
webSocketPollingJob.cancel(true);
|
||||
}
|
||||
public void onClose() {
|
||||
reconnectWebsocket();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(Throwable cause) {
|
||||
yioRemoteDockActualStatus = YioRemoteDockHandleStatus.COMMUNICATION_ERROR;
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
|
||||
"Connection lost no ping from YIO DOCK");
|
||||
updateState(GROUP_OUTPUT, STATUS_STRING_CHANNEL, UnDefType.UNDEF);
|
||||
"Communication lost no ping from YIO DOCK");
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -174,8 +180,9 @@ public class YIOremoteDockHandler extends BaseThingHandler {
|
|||
heartBeat = true;
|
||||
success = true;
|
||||
} else {
|
||||
if (irCodeSendHandler.getCode().equalsIgnoreCase("\"0;0x0;0;0\"")) {
|
||||
if (irCodeSendHandler.getCode().equalsIgnoreCase("0;0x0;0;0")) {
|
||||
logger.debug("Send heartBeat Code success");
|
||||
receivedStatus = "Send heartBeat Code success";
|
||||
} else {
|
||||
receivedStatus = "Send IR Code failure";
|
||||
}
|
||||
|
@ -242,8 +249,12 @@ public class YIOremoteDockHandler extends BaseThingHandler {
|
|||
|
||||
@Override
|
||||
public void dispose() {
|
||||
if (webSocketPollingJob != null) {
|
||||
webSocketPollingJob.cancel(true);
|
||||
disposeWebsocketPollingJob();
|
||||
if (webSocketReconnectionPollingJob != null) {
|
||||
if (!webSocketReconnectionPollingJob.isCancelled() && webSocketReconnectionPollingJob != null) {
|
||||
webSocketReconnectionPollingJob.cancel(true);
|
||||
}
|
||||
webSocketReconnectionPollingJob = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -287,7 +298,7 @@ public class YIOremoteDockHandler extends BaseThingHandler {
|
|||
updateState(id, new StringType(value));
|
||||
}
|
||||
|
||||
private void authenticate() {
|
||||
private void authenticateWebsocket() {
|
||||
switch (yioRemoteDockActualStatus) {
|
||||
case CONNECTION_ESTABLISHED:
|
||||
authenticationMessageHandler.setToken(localConfig.accessToken);
|
||||
|
@ -298,13 +309,15 @@ public class YIOremoteDockHandler extends BaseThingHandler {
|
|||
if (authenticationOk) {
|
||||
yioRemoteDockActualStatus = YioRemoteDockHandleStatus.AUTHENTICATION_COMPLETE;
|
||||
updateStatus(ThingStatus.ONLINE);
|
||||
webSocketPollingJob = scheduler.scheduleWithFixedDelay(this::pollingWebsocket, 0, 30,
|
||||
webSocketPollingJob = scheduler.scheduleWithFixedDelay(this::pollingWebsocketJob, 0, 150,
|
||||
TimeUnit.SECONDS);
|
||||
} else {
|
||||
yioRemoteDockActualStatus = YioRemoteDockHandleStatus.AUTHENTICATION_FAILED;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
disposeWebsocketPollingJob();
|
||||
yioRemoteDockActualStatus = YioRemoteDockHandleStatus.COMMUNICATION_ERROR;
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
|
||||
"Connection lost no ping from YIO DOCK");
|
||||
updateState(GROUP_OUTPUT, STATUS_STRING_CHANNEL, UnDefType.UNDEF);
|
||||
|
@ -312,7 +325,16 @@ public class YIOremoteDockHandler extends BaseThingHandler {
|
|||
}
|
||||
}
|
||||
|
||||
private void pollingWebsocket() {
|
||||
private void disposeWebsocketPollingJob() {
|
||||
if (webSocketPollingJob != null) {
|
||||
if (!webSocketPollingJob.isCancelled() && webSocketPollingJob != null) {
|
||||
webSocketPollingJob.cancel(true);
|
||||
}
|
||||
webSocketPollingJob = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void pollingWebsocketJob() {
|
||||
switch (yioRemoteDockActualStatus) {
|
||||
case AUTHENTICATION_COMPLETE:
|
||||
if (getAndResetHeartbeat()) {
|
||||
|
@ -321,19 +343,16 @@ public class YIOremoteDockHandler extends BaseThingHandler {
|
|||
logger.debug("heartBeat ok");
|
||||
sendMessage(YioRemoteMessages.HEARTBEAT_MESSAGE, "");
|
||||
} else {
|
||||
yioRemoteDockActualStatus = YioRemoteDockHandleStatus.CONNECTION_FAILED;
|
||||
yioRemoteDockActualStatus = YioRemoteDockHandleStatus.COMMUNICATION_ERROR;
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
|
||||
"Connection lost no ping from YIO DOCK");
|
||||
updateState(GROUP_OUTPUT, STATUS_STRING_CHANNEL, UnDefType.UNDEF);
|
||||
if (webSocketPollingJob != null) {
|
||||
webSocketPollingJob.cancel(true);
|
||||
}
|
||||
disposeWebsocketPollingJob();
|
||||
reconnectWebsocket();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (webSocketPollingJob != null) {
|
||||
webSocketPollingJob.cancel(true);
|
||||
}
|
||||
disposeWebsocketPollingJob();
|
||||
yioRemoteDockActualStatus = YioRemoteDockHandleStatus.COMMUNICATION_ERROR;
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
|
||||
"Connection lost no ping from YIO DOCK");
|
||||
updateState(GROUP_OUTPUT, STATUS_STRING_CHANNEL, UnDefType.UNDEF);
|
||||
|
@ -347,6 +366,55 @@ public class YIOremoteDockHandler extends BaseThingHandler {
|
|||
return result;
|
||||
}
|
||||
|
||||
public void reconnectWebsocket() {
|
||||
if (webSocketReconnectionPollingJob == null) {
|
||||
webSocketReconnectionPollingJob = scheduler.scheduleWithFixedDelay(this::reconnectWebsocketJob, 0, 30,
|
||||
TimeUnit.SECONDS);
|
||||
}
|
||||
}
|
||||
|
||||
public void reconnectWebsocketJob() {
|
||||
switch (yioRemoteDockActualStatus) {
|
||||
case COMMUNICATION_ERROR:
|
||||
logger.debug("Reconnecting YIORemoteHandler");
|
||||
try {
|
||||
disposeWebsocketPollingJob();
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
|
||||
"Connection lost no ping from YIO DOCK");
|
||||
yioremoteDockwebSocketClient.closeWebsocketSession();
|
||||
webSocketClient.stop();
|
||||
yioRemoteDockActualStatus = YioRemoteDockHandleStatus.RECONNECTION_PROCESS;
|
||||
} catch (Exception e) {
|
||||
logger.debug("Connection error {}", e.getMessage());
|
||||
}
|
||||
try {
|
||||
websocketAddress = new URI("ws://" + localConfig.host + ":946");
|
||||
yioRemoteDockActualStatus = YioRemoteDockHandleStatus.AUTHENTICATION_PROCESS;
|
||||
} catch (URISyntaxException e) {
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.OFFLINE.CONFIGURATION_ERROR,
|
||||
"Initialize web socket failed: " + e.getMessage());
|
||||
}
|
||||
try {
|
||||
webSocketClient.start();
|
||||
webSocketClient.connect(yioremoteDockwebSocketClient, websocketAddress,
|
||||
yioremoteDockwebSocketClientrequest);
|
||||
} catch (Exception e) {
|
||||
logger.debug("Connection error {}", e.getMessage());
|
||||
}
|
||||
break;
|
||||
case AUTHENTICATION_COMPLETE:
|
||||
if (webSocketReconnectionPollingJob != null) {
|
||||
if (!webSocketReconnectionPollingJob.isCancelled() && webSocketReconnectionPollingJob != null) {
|
||||
webSocketReconnectionPollingJob.cancel(true);
|
||||
}
|
||||
webSocketReconnectionPollingJob = null;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void sendMessage(YioRemoteMessages messageType, String messagePayload) {
|
||||
switch (messageType) {
|
||||
case AUTHENTICATE_MESSAGE:
|
||||
|
|
|
@ -17,6 +17,8 @@ import java.io.IOException;
|
|||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.eclipse.jetty.websocket.api.Session;
|
||||
import org.eclipse.jetty.websocket.api.StatusCode;
|
||||
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketClose;
|
||||
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketConnect;
|
||||
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketError;
|
||||
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage;
|
||||
|
@ -61,7 +63,25 @@ public class Websocket {
|
|||
public void onError(Throwable cause) {
|
||||
logger.warn("WebSocketError {}", cause.getMessage());
|
||||
if (websocketHandler != null) {
|
||||
websocketHandler.onError();
|
||||
websocketHandler.onError(cause);
|
||||
}
|
||||
}
|
||||
|
||||
@OnWebSocketClose
|
||||
public void onClose(int statusCode, String reason) {
|
||||
if (statusCode != StatusCode.NORMAL) {
|
||||
logger.debug("WebSocket Connection closed: {} - {}", statusCode, reason);
|
||||
}
|
||||
if (session != null) {
|
||||
if (!session.isOpen()) {
|
||||
if (session != null) {
|
||||
session.close();
|
||||
}
|
||||
}
|
||||
session = null;
|
||||
}
|
||||
if (websocketHandler != null) {
|
||||
websocketHandler.onClose();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -74,4 +94,10 @@ public class Websocket {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void closeWebsocketSession() {
|
||||
if (session != null) {
|
||||
session.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,7 +24,9 @@ public interface WebsocketInterface {
|
|||
|
||||
public void onConnect(boolean connected);
|
||||
|
||||
public void onClose();
|
||||
|
||||
public void onMessage(String decodedmessage);
|
||||
|
||||
public void onError();
|
||||
public void onError(Throwable cause);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue