added migrated 2.x add-ons
Signed-off-by: Kai Kreuzer <kai@openhab.org>
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<features name="org.openhab.binding.yioremote-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.4.0">
|
||||
<repository>mvn:org.openhab.core.features.karaf/org.openhab.core.features.karaf.openhab-core/${ohc.version}/xml/features</repository>
|
||||
|
||||
<feature name="openhab-binding-yioremote" description="YIOremote Binding" version="${project.version}">
|
||||
<feature>openhab-runtime-base</feature>
|
||||
<bundle start-level="80">mvn:org.openhab.addons.bundles/org.openhab.binding.yioremote/${project.version}</bundle>
|
||||
</feature>
|
||||
</features>
|
||||
@@ -0,0 +1,61 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.yioremote.internal;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.core.thing.ThingTypeUID;
|
||||
|
||||
/**
|
||||
* The {@link YIOremoteBindingConstants} class defines common constants, which are
|
||||
* used across the whole binding.
|
||||
*
|
||||
* @author Michael Loercher - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class YIOremoteBindingConstants {
|
||||
|
||||
public static final String BINDING_ID = "yioremote";
|
||||
|
||||
// List of all used global variables
|
||||
public static enum YioRemoteDockHandleStatus {
|
||||
UNINITIALIZED_STATE,
|
||||
AUTHENTICATION_PROCESS,
|
||||
AUTHENTICATION_FAILED,
|
||||
AUTHENTICATION_COMPLETE,
|
||||
CONNECTION_FAILED,
|
||||
CONNECTION_ESTABLISHED;
|
||||
}
|
||||
|
||||
public static enum YioRemoteMessages {
|
||||
IR_SEND,
|
||||
AUTHENTICATE_MESSAGE,
|
||||
HEARTBEAT_MESSAGE,
|
||||
IR_RECEIVER_ON,
|
||||
IR_RECEIVER_OFF;
|
||||
}
|
||||
|
||||
// List of all Thing Type UIDs
|
||||
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";
|
||||
public static final String GROUP_OUTPUT = "output";
|
||||
|
||||
// List of all Channel ids
|
||||
public static final String RECEIVER_SWITCH_CHANNEL = "receiverswitch";
|
||||
public static final String STATUS_STRING_CHANNEL = "status";
|
||||
|
||||
// Configuration elements
|
||||
public static final String CONFIG_YIODOCKHOST = "host";
|
||||
public static final String CONFIG_YIODOCKACCESSTOKEN = "accesstoken";
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.yioremote.internal;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* The {@link YIOremoteConfiguration} class contains fields mapping thing configuration parameters.
|
||||
*
|
||||
* @author Michael Loercher - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class YIOremoteConfiguration {
|
||||
public @Nullable String host;
|
||||
public String accessToken = "0";
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.yioremote.internal;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.core.automation.annotation.ActionInput;
|
||||
import org.openhab.core.automation.annotation.RuleAction;
|
||||
import org.openhab.core.thing.binding.ThingActions;
|
||||
import org.openhab.core.thing.binding.ThingActionsScope;
|
||||
import org.openhab.core.thing.binding.ThingHandler;
|
||||
|
||||
/**
|
||||
* The {@link YIOremoteDockActions} is responsible for handling the action commands
|
||||
*
|
||||
*
|
||||
* @author Michael Loercher - Initial contribution
|
||||
*/
|
||||
@ThingActionsScope(name = "yioremote")
|
||||
@NonNullByDefault
|
||||
public class YIOremoteDockActions implements ThingActions {
|
||||
private @Nullable YIOremoteDockHandler dockHandler;
|
||||
|
||||
@Override
|
||||
public void setThingHandler(@Nullable ThingHandler yiremotedockhandler) {
|
||||
dockHandler = (YIOremoteDockHandler) yiremotedockhandler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable ThingHandler getThingHandler() {
|
||||
return dockHandler;
|
||||
}
|
||||
|
||||
@RuleAction(label = "@text/actionLabel", description = "@text/actionDesc")
|
||||
public void sendIRCode(
|
||||
@ActionInput(name = "IRCode", label = "@text/actionInputTopicLabel", description = "@text/actionInputTopicDesc") @Nullable String irCode) {
|
||||
YIOremoteDockHandler dockHandlerLocal = dockHandler;
|
||||
if (dockHandlerLocal != null) {
|
||||
dockHandlerLocal.sendIRCode(irCode);
|
||||
}
|
||||
}
|
||||
|
||||
public static void sendIRCode(@Nullable ThingActions actions, @Nullable String irCode) {
|
||||
if (actions instanceof YIOremoteDockActions) {
|
||||
((YIOremoteDockActions) actions).sendIRCode(irCode);
|
||||
} else {
|
||||
throw new IllegalArgumentException("Instance is not an YIOremoteDockActions class.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,381 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.yioremote.internal;
|
||||
|
||||
import static org.openhab.binding.yioremote.internal.YIOremoteBindingConstants.*;
|
||||
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.eclipse.jetty.websocket.client.ClientUpgradeRequest;
|
||||
import org.eclipse.jetty.websocket.client.WebSocketClient;
|
||||
import org.openhab.binding.yioremote.internal.YIOremoteBindingConstants.YioRemoteDockHandleStatus;
|
||||
import org.openhab.binding.yioremote.internal.YIOremoteBindingConstants.YioRemoteMessages;
|
||||
import org.openhab.binding.yioremote.internal.dto.AuthenticationMessage;
|
||||
import org.openhab.binding.yioremote.internal.dto.IRCode;
|
||||
import org.openhab.binding.yioremote.internal.dto.IRCodeSendMessage;
|
||||
import org.openhab.binding.yioremote.internal.dto.IRReceiverMessage;
|
||||
import org.openhab.binding.yioremote.internal.utils.Websocket;
|
||||
import org.openhab.binding.yioremote.internal.utils.WebsocketInterface;
|
||||
import org.openhab.core.library.types.OnOffType;
|
||||
import org.openhab.core.library.types.StringType;
|
||||
import org.openhab.core.thing.ChannelUID;
|
||||
import org.openhab.core.thing.Thing;
|
||||
import org.openhab.core.thing.ThingStatus;
|
||||
import org.openhab.core.thing.ThingStatusDetail;
|
||||
import org.openhab.core.thing.binding.BaseThingHandler;
|
||||
import org.openhab.core.thing.binding.ThingHandlerService;
|
||||
import org.openhab.core.types.Command;
|
||||
import org.openhab.core.types.State;
|
||||
import org.openhab.core.types.UnDefType;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
|
||||
/**
|
||||
* The {@link YIOremoteDockHandler} is responsible for handling commands, which are
|
||||
* sent to one of the channels.
|
||||
*
|
||||
* @author Michael Loercher - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class YIOremoteDockHandler extends BaseThingHandler {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(YIOremoteDockHandler.class);
|
||||
|
||||
YIOremoteConfiguration localConfig = getConfigAs(YIOremoteConfiguration.class);
|
||||
private WebSocketClient webSocketClient = new WebSocketClient();
|
||||
private Websocket yioremoteDockwebSocketClient = new Websocket();
|
||||
private ClientUpgradeRequest yioremoteDockwebSocketClientrequest = new ClientUpgradeRequest();
|
||||
private @Nullable URI websocketAddress;
|
||||
private YioRemoteDockHandleStatus yioRemoteDockActualStatus = YioRemoteDockHandleStatus.UNINITIALIZED_STATE;
|
||||
private @Nullable Future<?> webSocketPollingJob;
|
||||
public String receivedMessage = "";
|
||||
private JsonObject recievedJson = new JsonObject();
|
||||
private boolean heartBeat = false;
|
||||
private boolean authenticationOk = false;
|
||||
private String receivedStatus = "";
|
||||
private IRCode irCodeReceivedHandler = new IRCode();
|
||||
private IRCode irCodeSendHandler = new IRCode();
|
||||
private IRCodeSendMessage irCodeSendMessageHandler = new IRCodeSendMessage(irCodeSendHandler);
|
||||
private AuthenticationMessage authenticationMessageHandler = new AuthenticationMessage();
|
||||
private IRReceiverMessage irReceiverMessageHandler = new IRReceiverMessage();
|
||||
|
||||
public YIOremoteDockHandler(Thing thing) {
|
||||
super(thing);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
updateStatus(ThingStatus.UNKNOWN);
|
||||
scheduler.execute(() -> {
|
||||
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());
|
||||
}
|
||||
|
||||
yioremoteDockwebSocketClient.addMessageHandler(new WebsocketInterface() {
|
||||
|
||||
@Override
|
||||
public void onConnect(boolean connected) {
|
||||
if (connected) {
|
||||
yioRemoteDockActualStatus = YioRemoteDockHandleStatus.CONNECTION_ESTABLISHED;
|
||||
} else {
|
||||
yioRemoteDockActualStatus = YioRemoteDockHandleStatus.CONNECTION_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMessage(String message) {
|
||||
receivedMessage = message;
|
||||
logger.debug("Message recieved {}", message);
|
||||
recievedJson = convertStringToJsonObject(receivedMessage);
|
||||
if (recievedJson.size() > 0) {
|
||||
if (decodeReceivedMessage(recievedJson)) {
|
||||
triggerChannel(getChannelUuid(GROUP_OUTPUT, STATUS_STRING_CHANNEL));
|
||||
updateChannelString(GROUP_OUTPUT, STATUS_STRING_CHANNEL, receivedStatus);
|
||||
switch (yioRemoteDockActualStatus) {
|
||||
case CONNECTION_ESTABLISHED:
|
||||
case AUTHENTICATION_PROCESS:
|
||||
authenticate();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
logger.debug("Message {} decoded", receivedMessage);
|
||||
} else {
|
||||
logger.debug("Error during message {} decoding", receivedMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError() {
|
||||
if (webSocketPollingJob != null) {
|
||||
webSocketPollingJob.cancel(true);
|
||||
}
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
|
||||
"Connection lost no ping from YIO DOCK");
|
||||
updateState(GROUP_OUTPUT, STATUS_STRING_CHANNEL, UnDefType.UNDEF);
|
||||
}
|
||||
});
|
||||
|
||||
try {
|
||||
webSocketClient.start();
|
||||
|
||||
webSocketClient.connect(yioremoteDockwebSocketClient, websocketAddress,
|
||||
yioremoteDockwebSocketClientrequest);
|
||||
} catch (Exception e) {
|
||||
logger.debug("Connection error {}", e.getMessage());
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
private boolean decodeReceivedMessage(JsonObject message) {
|
||||
boolean success = false;
|
||||
|
||||
if (message.has("type")) {
|
||||
if (message.get("type").toString().equalsIgnoreCase("\"auth_required\"")) {
|
||||
heartBeat = true;
|
||||
success = true;
|
||||
receivedStatus = "Authentication required";
|
||||
} else if (message.get("type").toString().equalsIgnoreCase("\"auth_ok\"")) {
|
||||
authenticationOk = true;
|
||||
heartBeat = true;
|
||||
success = true;
|
||||
receivedStatus = "Authentication ok";
|
||||
} else if (message.get("type").toString().equalsIgnoreCase("\"dock\"") && message.has("message")) {
|
||||
if (message.get("message").toString().equalsIgnoreCase("\"ir_send\"")) {
|
||||
if (message.get("success").toString().equalsIgnoreCase("true")) {
|
||||
receivedStatus = "Send IR Code successfully";
|
||||
heartBeat = true;
|
||||
success = true;
|
||||
} else {
|
||||
if (irCodeSendHandler.getCode().equalsIgnoreCase("\"0;0x0;0;0\"")) {
|
||||
logger.debug("Send heartBeat Code success");
|
||||
} else {
|
||||
receivedStatus = "Send IR Code failure";
|
||||
}
|
||||
heartBeat = true;
|
||||
success = true;
|
||||
}
|
||||
} else {
|
||||
logger.warn("No known message {}", receivedMessage);
|
||||
heartBeat = false;
|
||||
success = false;
|
||||
}
|
||||
} else if (message.get("command").toString().equalsIgnoreCase("\"ir_receive\"")) {
|
||||
receivedStatus = message.get("code").toString().replace("\"", "");
|
||||
if (receivedStatus.matches("[0-9][;]0[xX][0-9a-fA-F]+[;][0-9]+[;][0-9]")) {
|
||||
irCodeReceivedHandler.setCode(message.get("code").toString().replace("\"", ""));
|
||||
} else {
|
||||
irCodeReceivedHandler.setCode("");
|
||||
}
|
||||
logger.debug("ir_receive message {}", irCodeReceivedHandler.getCode());
|
||||
heartBeat = true;
|
||||
success = true;
|
||||
} else {
|
||||
logger.warn("No known message {}", irCodeReceivedHandler.getCode());
|
||||
heartBeat = false;
|
||||
success = false;
|
||||
}
|
||||
} else {
|
||||
logger.warn("No known message {}", irCodeReceivedHandler.getCode());
|
||||
heartBeat = false;
|
||||
success = false;
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
private JsonObject convertStringToJsonObject(String jsonString) {
|
||||
try {
|
||||
JsonParser parser = new JsonParser();
|
||||
JsonElement jsonElement = parser.parse(jsonString);
|
||||
JsonObject result;
|
||||
|
||||
if (jsonElement instanceof JsonObject) {
|
||||
result = jsonElement.getAsJsonObject();
|
||||
} else {
|
||||
logger.debug("{} is not valid JSON stirng", jsonString);
|
||||
result = new JsonObject();
|
||||
throw new IllegalArgumentException(jsonString + "{} is not valid JSON stirng");
|
||||
}
|
||||
return result;
|
||||
} catch (IllegalArgumentException e) {
|
||||
JsonObject result = new JsonObject();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
public void updateState(String group, String channelId, State value) {
|
||||
ChannelUID id = new ChannelUID(getThing().getUID(), group, channelId);
|
||||
updateState(id, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Class<? extends ThingHandlerService>> getServices() {
|
||||
return Collections.singleton(YIOremoteDockActions.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
if (webSocketPollingJob != null) {
|
||||
webSocketPollingJob.cancel(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleCommand(ChannelUID channelUID, Command command) {
|
||||
if (RECEIVER_SWITCH_CHANNEL.equals(channelUID.getIdWithoutGroup())) {
|
||||
switch (yioRemoteDockActualStatus) {
|
||||
case AUTHENTICATION_COMPLETE:
|
||||
if (command == OnOffType.ON) {
|
||||
logger.debug("YIODOCKRECEIVERSWITCH ON procedure: Switching IR Receiver on");
|
||||
sendMessage(YioRemoteMessages.IR_RECEIVER_ON, "");
|
||||
} else if (command == OnOffType.OFF) {
|
||||
logger.debug("YIODOCKRECEIVERSWITCH OFF procedure: Switching IR Receiver off");
|
||||
sendMessage(YioRemoteMessages.IR_RECEIVER_OFF, "");
|
||||
} else {
|
||||
logger.debug("YIODOCKRECEIVERSWITCH no procedure");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void sendIRCode(@Nullable String irCode) {
|
||||
if (irCode != null && yioRemoteDockActualStatus.equals(YioRemoteDockHandleStatus.AUTHENTICATION_COMPLETE)) {
|
||||
if (irCode.matches("[0-9][;]0[xX][0-9a-fA-F]+[;][0-9]+[;][0-9]")) {
|
||||
sendMessage(YioRemoteMessages.IR_SEND, irCode);
|
||||
} else {
|
||||
logger.warn("Wrong ir code format {}", irCode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private ChannelUID getChannelUuid(String group, String typeId) {
|
||||
return new ChannelUID(getThing().getUID(), group, typeId);
|
||||
}
|
||||
|
||||
private void updateChannelString(String group, String channelId, String value) {
|
||||
ChannelUID id = new ChannelUID(getThing().getUID(), group, channelId);
|
||||
updateState(id, new StringType(value));
|
||||
}
|
||||
|
||||
private void authenticate() {
|
||||
switch (yioRemoteDockActualStatus) {
|
||||
case CONNECTION_ESTABLISHED:
|
||||
authenticationMessageHandler.setToken(localConfig.accessToken);
|
||||
sendMessage(YioRemoteMessages.AUTHENTICATE_MESSAGE, localConfig.accessToken);
|
||||
yioRemoteDockActualStatus = YioRemoteDockHandleStatus.AUTHENTICATION_PROCESS;
|
||||
break;
|
||||
case AUTHENTICATION_PROCESS:
|
||||
if (authenticationOk) {
|
||||
yioRemoteDockActualStatus = YioRemoteDockHandleStatus.AUTHENTICATION_COMPLETE;
|
||||
updateStatus(ThingStatus.ONLINE);
|
||||
webSocketPollingJob = scheduler.scheduleWithFixedDelay(this::pollingWebsocket, 0, 30,
|
||||
TimeUnit.SECONDS);
|
||||
} else {
|
||||
yioRemoteDockActualStatus = YioRemoteDockHandleStatus.AUTHENTICATION_FAILED;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
|
||||
"Connection lost no ping from YIO DOCK");
|
||||
updateState(GROUP_OUTPUT, STATUS_STRING_CHANNEL, UnDefType.UNDEF);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void pollingWebsocket() {
|
||||
switch (yioRemoteDockActualStatus) {
|
||||
case AUTHENTICATION_COMPLETE:
|
||||
if (getAndResetHeartbeat()) {
|
||||
updateChannelString(GROUP_OUTPUT, STATUS_STRING_CHANNEL,
|
||||
irCodeReceivedHandler.getCode() + irCodeReceivedHandler.getFormat());
|
||||
logger.debug("heartBeat ok");
|
||||
sendMessage(YioRemoteMessages.HEARTBEAT_MESSAGE, "");
|
||||
} else {
|
||||
yioRemoteDockActualStatus = YioRemoteDockHandleStatus.CONNECTION_FAILED;
|
||||
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);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (webSocketPollingJob != null) {
|
||||
webSocketPollingJob.cancel(true);
|
||||
}
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
|
||||
"Connection lost no ping from YIO DOCK");
|
||||
updateState(GROUP_OUTPUT, STATUS_STRING_CHANNEL, UnDefType.UNDEF);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean getAndResetHeartbeat() {
|
||||
boolean result = heartBeat;
|
||||
heartBeat = false;
|
||||
return result;
|
||||
}
|
||||
|
||||
public void sendMessage(YioRemoteMessages messageType, String messagePayload) {
|
||||
switch (messageType) {
|
||||
case AUTHENTICATE_MESSAGE:
|
||||
yioremoteDockwebSocketClient.sendMessage(authenticationMessageHandler.getAuthenticationMessageString());
|
||||
logger.debug("sending authenticating {}",
|
||||
authenticationMessageHandler.getAuthenticationMessageString());
|
||||
break;
|
||||
case HEARTBEAT_MESSAGE:
|
||||
irCodeSendHandler.setCode("0;0x0;0;0");
|
||||
yioremoteDockwebSocketClient.sendMessage(irCodeSendMessageHandler.getIRcodeSendMessageString());
|
||||
logger.debug("sending heartBeat message: {}", irCodeSendMessageHandler.getIRcodeSendMessageString());
|
||||
break;
|
||||
case IR_RECEIVER_ON:
|
||||
irReceiverMessageHandler.setOn();
|
||||
yioremoteDockwebSocketClient.sendMessage(irReceiverMessageHandler.getIRreceiverMessageString());
|
||||
logger.debug("sending IR receiver on message: {}",
|
||||
irReceiverMessageHandler.getIRreceiverMessageString());
|
||||
break;
|
||||
case IR_RECEIVER_OFF:
|
||||
irReceiverMessageHandler.setOff();
|
||||
yioremoteDockwebSocketClient.sendMessage(irReceiverMessageHandler.getIRreceiverMessageString());
|
||||
logger.debug("sending IR receiver on message: {}",
|
||||
irReceiverMessageHandler.getIRreceiverMessageString());
|
||||
break;
|
||||
case IR_SEND:
|
||||
irCodeSendHandler.setCode(messagePayload);
|
||||
yioremoteDockwebSocketClient.sendMessage(irCodeSendMessageHandler.getIRcodeSendMessageString());
|
||||
logger.debug("sending heartBeat message: {}", irCodeSendMessageHandler.getIRcodeSendMessageString());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.yioremote.internal;
|
||||
|
||||
import static org.openhab.binding.yioremote.internal.YIOremoteBindingConstants.THING_TYPE_YIOREMOTEDOCK;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.core.thing.Thing;
|
||||
import org.openhab.core.thing.ThingTypeUID;
|
||||
import org.openhab.core.thing.binding.BaseThingHandlerFactory;
|
||||
import org.openhab.core.thing.binding.ThingHandler;
|
||||
import org.openhab.core.thing.binding.ThingHandlerFactory;
|
||||
import org.osgi.service.component.annotations.Component;
|
||||
|
||||
/**
|
||||
* The {@link YIOremoteHandlerFactory} is responsible for creating things and thing
|
||||
* handlers.
|
||||
*
|
||||
* @author Michael Loercher - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
@Component(configurationPid = "binding.yioremote", service = ThingHandlerFactory.class)
|
||||
public class YIOremoteHandlerFactory extends BaseThingHandlerFactory {
|
||||
|
||||
private static final Set<ThingTypeUID> SUPPORTED_THING_TYPES_UIDS = Collections.singleton(THING_TYPE_YIOREMOTEDOCK);
|
||||
|
||||
@Override
|
||||
public boolean supportsThingType(ThingTypeUID thingTypeUID) {
|
||||
return SUPPORTED_THING_TYPES_UIDS.contains(thingTypeUID);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @Nullable ThingHandler createHandler(Thing thing) {
|
||||
ThingTypeUID thingTypeUID = thing.getThingTypeUID();
|
||||
|
||||
if (THING_TYPE_YIOREMOTEDOCK.equals(thingTypeUID)) {
|
||||
return new YIOremoteDockHandler(thing);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.yioremote.internal.dto;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
/**
|
||||
* The {@link AuthenticationMessage} the AuthenticationMessage DTO
|
||||
*
|
||||
*
|
||||
* @author Michael Loercher - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class AuthenticationMessage {
|
||||
private String type = "auth";
|
||||
private String token = "0";
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public String getToken() {
|
||||
return token;
|
||||
}
|
||||
|
||||
public void setToken(String token) {
|
||||
this.token = token;
|
||||
}
|
||||
|
||||
public JsonObject getAuthenticationMessageJsonObject() {
|
||||
JsonObject authenticationMessage = new JsonObject();
|
||||
authenticationMessage.addProperty("type", type);
|
||||
authenticationMessage.addProperty("token", token);
|
||||
return authenticationMessage;
|
||||
}
|
||||
|
||||
public String getAuthenticationMessageString() {
|
||||
JsonObject authenticationMessage = new JsonObject();
|
||||
authenticationMessage.addProperty("type", type);
|
||||
authenticationMessage.addProperty("token", token);
|
||||
return authenticationMessage.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.yioremote.internal.dto;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
|
||||
/**
|
||||
* The {@link IRCode} the IRCode DTO
|
||||
*
|
||||
*
|
||||
* @author Michael Loercher - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class IRCode {
|
||||
private String code = "0;0x0;0;0";
|
||||
private String format = "hex";
|
||||
|
||||
public String getFormat() {
|
||||
return format;
|
||||
}
|
||||
|
||||
public void setFormat(String format) {
|
||||
this.format = format;
|
||||
}
|
||||
|
||||
public String getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public void setCode(String code) {
|
||||
this.code = code;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.yioremote.internal.dto;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
/**
|
||||
* The {@link IRCodeSendMessage} the IRCodeSendMessage DTO
|
||||
*
|
||||
*
|
||||
* @author Michael Loercher - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class IRCodeSendMessage {
|
||||
private String type = "dock";
|
||||
private String command = "ir_send";
|
||||
|
||||
private IRCode ircode = new IRCode();
|
||||
|
||||
public IRCodeSendMessage(IRCode ircode) {
|
||||
this.ircode = ircode;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public String getCommand() {
|
||||
return command;
|
||||
}
|
||||
|
||||
public JsonObject getIRcodeSendMessageJsonObject() {
|
||||
JsonObject irCodeSendMessage = new JsonObject();
|
||||
irCodeSendMessage.addProperty("type", type);
|
||||
irCodeSendMessage.addProperty("command", command);
|
||||
irCodeSendMessage.addProperty("code", ircode.getCode());
|
||||
irCodeSendMessage.addProperty("format", ircode.getFormat());
|
||||
return irCodeSendMessage;
|
||||
}
|
||||
|
||||
public String getIRcodeSendMessageString() {
|
||||
JsonObject irCodeSendMessage = new JsonObject();
|
||||
irCodeSendMessage.addProperty("type", type);
|
||||
irCodeSendMessage.addProperty("command", command);
|
||||
irCodeSendMessage.addProperty("code", ircode.getCode());
|
||||
irCodeSendMessage.addProperty("format", ircode.getFormat());
|
||||
return irCodeSendMessage.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.yioremote.internal.dto;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
/**
|
||||
* The {@link IRReceiverMessage} the IRReceiverMessage DTO
|
||||
*
|
||||
*
|
||||
* @author Michael Loercher - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class IRReceiverMessage {
|
||||
private String type = "dock";
|
||||
private String command = "ir_receive_off";
|
||||
|
||||
public void setOn() {
|
||||
command = "ir_receive_on";
|
||||
}
|
||||
|
||||
public void setOff() {
|
||||
command = "ir_receive_off";
|
||||
}
|
||||
|
||||
public JsonObject getIRreceiverMessageJsonObject() {
|
||||
JsonObject irReceiverMessage = new JsonObject();
|
||||
irReceiverMessage.addProperty("type", type);
|
||||
irReceiverMessage.addProperty("command", command);
|
||||
return irReceiverMessage;
|
||||
}
|
||||
|
||||
public String getIRreceiverMessageString() {
|
||||
JsonObject irReceiverMessage = new JsonObject();
|
||||
irReceiverMessage.addProperty("type", type);
|
||||
irReceiverMessage.addProperty("command", command);
|
||||
return irReceiverMessage.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.yioremote.internal.utils;
|
||||
|
||||
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.annotations.OnWebSocketConnect;
|
||||
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketError;
|
||||
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage;
|
||||
import org.eclipse.jetty.websocket.api.annotations.WebSocket;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* The {@link Websocket} is responsible for the Websocket Connection
|
||||
*
|
||||
* @author Michael Loercher - Initial contribution
|
||||
*/
|
||||
|
||||
@NonNullByDefault
|
||||
@WebSocket
|
||||
public class Websocket {
|
||||
|
||||
private @Nullable Session session;
|
||||
private final Logger logger = LoggerFactory.getLogger(Websocket.class);
|
||||
private @Nullable WebsocketInterface websocketHandler;
|
||||
|
||||
public void addMessageHandler(WebsocketInterface yioremotedockwebsocketinterfacehandler) {
|
||||
this.websocketHandler = yioremotedockwebsocketinterfacehandler;
|
||||
}
|
||||
|
||||
@OnWebSocketMessage
|
||||
public void onText(Session session, String receivedMessage) {
|
||||
if (websocketHandler != null) {
|
||||
websocketHandler.onMessage(receivedMessage);
|
||||
}
|
||||
}
|
||||
|
||||
@OnWebSocketConnect
|
||||
public void onConnect(Session session) {
|
||||
this.session = session;
|
||||
if (websocketHandler != null) {
|
||||
websocketHandler.onConnect(true);
|
||||
}
|
||||
}
|
||||
|
||||
@OnWebSocketError
|
||||
public void onError(Throwable cause) {
|
||||
logger.warn("WebSocketError {}", cause.getMessage());
|
||||
if (websocketHandler != null) {
|
||||
websocketHandler.onError();
|
||||
}
|
||||
}
|
||||
|
||||
public void sendMessage(String str) {
|
||||
if (session != null) {
|
||||
try {
|
||||
session.getRemote().sendString(str);
|
||||
} catch (IOException e) {
|
||||
logger.warn("Error during sendMessage function {}", e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.yioremote.internal.utils;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
|
||||
/**
|
||||
* The {@link WebsocketInterface} is responsible for interfacing the Websocket.
|
||||
*
|
||||
* @author Michael Loercher - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public interface WebsocketInterface {
|
||||
|
||||
public void onConnect(boolean connected);
|
||||
|
||||
public void onMessage(String decodedmessage);
|
||||
|
||||
public void onError();
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<binding:binding id="yioremote" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:binding="https://openhab.org/schemas/binding/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/binding/v1.0.0 https://openhab.org/schemas/binding-1.0.0.xsd">
|
||||
|
||||
<name>YIOremote Binding</name>
|
||||
<description>This is the binding for YIOremote.</description>
|
||||
<author>Michael Loercher</author>
|
||||
|
||||
</binding:binding>
|
||||
@@ -0,0 +1,20 @@
|
||||
# binding
|
||||
binding.yioremote.name = YIO Remote Binding
|
||||
binding.yioremote.description = Dieses Addon steuert eine YIO Dock / Remote-Kombination
|
||||
|
||||
# thing types
|
||||
thing-type.yioremote.yioremotedock.label = YIO Remote Dock
|
||||
thing-type.yioremote.yioremotedock.description = Stellt das YIO Remote Dock Thing bereit
|
||||
|
||||
# thing type config description
|
||||
thing-type.config.yioremote.yioremotedock.host.label = IP-Adresse oder Hostname
|
||||
thing-type.config.yioremote.yioremotedock.host.description = IP-Adresse oder Hostname des YIO Docks
|
||||
thing-type.config.yioremote.yioremotedock.token.label = Das Authentifizierungstoken
|
||||
thing-type.config.yioremote.yioremotedock.token.description = Das Authentifizierungstoken fuer den Zugriff ist derzeit 0
|
||||
|
||||
# channel types
|
||||
channel-type.yioremotedock.receiverswitch.label = Schalter zum Aktivieren/Deaktivieren der IR-Empfängerdiode /-funktion
|
||||
channel-type.yioremotedock.receiverswitch.description = Der Schalter zum Aktivieren/Deaktivieren der IR-Empfängerdiode /-funktion
|
||||
channel-type.yioremotedock.sendircode.description = Der IR-Code Format(3; 0x20DF40BF; 32; 0), das vom YIO-Dock gesendet wird
|
||||
channel-type.yioremotedock.status.label = YIO Dock Status
|
||||
channel-type.yioremotedock.status.description = Der Status des YIO-Docks. Wenn der Empfänger eingeschaltet ist, wird der erkannte IR-Code angezeigt, andernfalls wird der IR-Sendestatus des letzten gesendeten IR-Codes angezeigt.
|
||||
@@ -0,0 +1,52 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<thing:thing-descriptions bindingId="yioremote"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
|
||||
|
||||
<thing-type id="yioRemoteDock">
|
||||
<label>YIO Remote Dock</label>
|
||||
<description>YIOremote Dock Binding Thing</description>
|
||||
<channel-groups>
|
||||
<channel-group id="input" typeId="input"/>
|
||||
<channel-group id="output" typeId="output"/>
|
||||
</channel-groups>
|
||||
<config-description>
|
||||
<parameter name="host" type="text" required="true">
|
||||
<label>Network Address</label>
|
||||
<description>Network address of the YIO Remote Dock</description>
|
||||
<context>network-address</context>
|
||||
</parameter>
|
||||
<parameter name="accessToken" type="text" required="true">
|
||||
<label>Access Token</label>
|
||||
<description>The authentication token for the access currently 0</description>
|
||||
<default>0</default>
|
||||
</parameter>
|
||||
</config-description>
|
||||
</thing-type>
|
||||
<channel-group-type id="input">
|
||||
<label>Inputs</label>
|
||||
<description>The channels used for Input</description>
|
||||
<channels>
|
||||
<channel id="receiverswitch" typeId="receiverswitch"/>
|
||||
</channels>
|
||||
</channel-group-type>
|
||||
<channel-group-type id="output">
|
||||
<label>Outputs</label>
|
||||
<description>The channels used for Output</description>
|
||||
<channels>
|
||||
<channel id="status" typeId="status"/>
|
||||
</channels>
|
||||
</channel-group-type>
|
||||
<channel-type id="receiverswitch">
|
||||
<item-type>Switch</item-type>
|
||||
<label>Receiver Switch</label>
|
||||
<description>The switch to enable disable the IR receiving diode/function</description>
|
||||
</channel-type>
|
||||
<channel-type id="status">
|
||||
<item-type>String</item-type>
|
||||
<label>Status</label>
|
||||
<description>The status of the YIO Dock. If the reciever is on than the recognized IR code will be displayed otherwise
|
||||
the IR send status is displayed of the last IR code send.</description>
|
||||
</channel-type>
|
||||
</thing:thing-descriptions>
|
||||
Reference in New Issue
Block a user