added migrated 2.x add-ons
Signed-off-by: Kai Kreuzer <kai@openhab.org>
This commit is contained in:
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<features name="org.openhab.binding.globalcache-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.4.0">
|
||||
<repository>file:${basedirRoot}/bundles/org.openhab.transform.map/target/feature/feature.xml</repository>
|
||||
|
||||
<feature name="openhab-binding-globalcache" description="GlobalCache Binding" version="${project.version}">
|
||||
<feature>openhab-runtime-base</feature>
|
||||
<feature>openhab-transformation-map</feature>
|
||||
<bundle start-level="80">mvn:org.openhab.addons.bundles/org.openhab.binding.globalcache/${project.version}</bundle>
|
||||
</feature>
|
||||
</features>
|
||||
@@ -0,0 +1,120 @@
|
||||
/**
|
||||
* 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.globalcache.internal;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.core.thing.ThingTypeUID;
|
||||
|
||||
/**
|
||||
* The {@link GlobalCacheBindingConstants} class defines common constants that are
|
||||
* used by the globalcache binding.
|
||||
*
|
||||
* @author Mark Hilbush - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class GlobalCacheBindingConstants {
|
||||
|
||||
public static final String BINDING_ID = "globalcache";
|
||||
|
||||
/*
|
||||
* GlobalCache thing definitions
|
||||
*/
|
||||
// GlobalCache Thing Type UIDs -- IR = Infrared, CC = Contact Closure, SL = Serial
|
||||
public static final ThingTypeUID THING_TYPE_ITACH_IR = new ThingTypeUID(BINDING_ID, "itachIR");
|
||||
public static final ThingTypeUID THING_TYPE_ITACH_CC = new ThingTypeUID(BINDING_ID, "itachCC");
|
||||
public static final ThingTypeUID THING_TYPE_ITACH_SL = new ThingTypeUID(BINDING_ID, "itachSL");
|
||||
public static final ThingTypeUID THING_TYPE_ITACH_FLEX = new ThingTypeUID(BINDING_ID, "itachFlex");
|
||||
public static final ThingTypeUID THING_TYPE_GC_100_06 = new ThingTypeUID(BINDING_ID, "gc100_06");
|
||||
public static final ThingTypeUID THING_TYPE_GC_100_12 = new ThingTypeUID(BINDING_ID, "gc100_12");
|
||||
public static final ThingTypeUID THING_TYPE_ZMOTE = new ThingTypeUID(BINDING_ID, "zmote");
|
||||
|
||||
public static final Set<ThingTypeUID> SUPPORTED_THING_TYPES_UIDS = Collections.unmodifiableSet(
|
||||
Stream.of(THING_TYPE_ITACH_IR, THING_TYPE_ITACH_CC, THING_TYPE_ITACH_SL, THING_TYPE_ITACH_FLEX,
|
||||
THING_TYPE_GC_100_06, THING_TYPE_GC_100_12, THING_TYPE_ZMOTE).collect(Collectors.toSet()));
|
||||
|
||||
// GlobalCache-specific thing properties
|
||||
public static final String THING_PROPERTY_UID = "uid";
|
||||
public static final String THING_PROPERTY_MAC = "macAddress";
|
||||
|
||||
/*
|
||||
* GlobalCache thing configuration items
|
||||
*/
|
||||
// Network address of the device
|
||||
public static final String THING_PROPERTY_IP = "ipAddress";
|
||||
|
||||
// MAP file containing mappings from command to IR and SL string
|
||||
public static final String THING_CONFIG_MAP_FILENAME = "mapFilename";
|
||||
|
||||
// Flex "Current Active Cable"
|
||||
public static final String THING_CONFIG_ACTIVECABLE = "activeCable";
|
||||
|
||||
public static final String ACTIVE_CABLE_INFRARED = "FLEX_INFRARED";
|
||||
public static final String ACTIVE_CABLE_SERIAL = "FLEX_SERIAL";
|
||||
public static final String ACTIVE_CABLE_RELAY = "FLEX_RELAY";
|
||||
|
||||
// Serial readers
|
||||
public static final String CONFIG_ENABLE_TWO_WAY_PORT_1 = "enableTwoWay1";
|
||||
public static final String CONFIG_END_OF_MESSAGE_DELIMITER_PORT_1 = "eomDelimiter1";
|
||||
public static final String CONFIG_ENABLE_TWO_WAY_PORT_2 = "enableTwoWay2";
|
||||
public static final String CONFIG_END_OF_MESSAGE_DELIMITER_PORT_2 = "eomDelimiter2";
|
||||
|
||||
// Indicates TCP connection over which the command will be sent
|
||||
public enum CommandType {
|
||||
COMMAND,
|
||||
SERIAL1,
|
||||
SERIAL2
|
||||
}
|
||||
|
||||
/*
|
||||
* Channel constants
|
||||
*/
|
||||
// GlobalCache Channel Types
|
||||
public static final String CHANNEL_TYPE_IR = "channel-type-ir";
|
||||
public static final String CHANNEL_TYPE_CC = "channel-type-cc";
|
||||
public static final String CHANNEL_TYPE_SL = "channel-type-sl";
|
||||
public static final String CHANNEL_TYPE_SL_DIRECT = "channel-type-sl-direct";
|
||||
public static final String CHANNEL_TYPE_SL_FEEDBACK = "channel-type-sl-receive";
|
||||
|
||||
// Channels for handing feedback from serial devices
|
||||
public static final String CHANNEL_SL_M1_RECEIVE = "sl-m1#c1-receive";
|
||||
public static final String CHANNEL_SL_M2_RECEIVE = "sl-m2#c1-receive";
|
||||
|
||||
// Channel properties that are used to specify module number and connector number
|
||||
public static final String CHANNEL_PROPERTY_MODULE = "module";
|
||||
public static final String CHANNEL_PROPERTY_CONNECTOR = "connector";
|
||||
|
||||
// List of iTach model strings returned in the device discovery beacon
|
||||
public static final String GC_MODEL_ITACH = "iTach";
|
||||
public static final String GC_MODEL_ITACHIP2IR = "iTachIP2IR";
|
||||
public static final String GC_MODEL_ITACHWF2IR = "iTachWF2IR";
|
||||
public static final String GC_MODEL_ITACHIP2CC = "iTachIP2CC";
|
||||
public static final String GC_MODEL_ITACHWF2CC = "iTachWF2CC";
|
||||
public static final String GC_MODEL_ITACHIP2SL = "iTachIP2SL";
|
||||
public static final String GC_MODEL_ITACHWF2SL = "iTachWF2SL";
|
||||
public static final String GC_MODEL_ITACHFLEXETH = "iTachFlexEthernet";
|
||||
public static final String GC_MODEL_ITACHFLEXETHPOE = "iTachFlexEthernetPoE";
|
||||
public static final String GC_MODEL_ITACHFLEXWIFI = "iTachFlexWiFi";
|
||||
|
||||
// List of GC-100 model strings returned in the device discovery beacon
|
||||
public static final String GC_MODEL_GC_100 = "GC-100";
|
||||
public static final String GC_MODEL_GC_100_06 = "GC-100-06";
|
||||
public static final String GC_MODEL_GC_100_12 = "GC-100-12";
|
||||
|
||||
// List of Zmote strings returned in the device discovery beacon
|
||||
public static final String GC_MODEL_ZMOTE = "ZV-2";
|
||||
}
|
||||
@@ -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.globalcache.internal;
|
||||
|
||||
import static org.openhab.binding.globalcache.internal.GlobalCacheBindingConstants.SUPPORTED_THING_TYPES_UIDS;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.binding.globalcache.internal.handler.GlobalCacheHandler;
|
||||
import org.openhab.core.net.NetworkAddressService;
|
||||
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.Activate;
|
||||
import org.osgi.service.component.annotations.Component;
|
||||
import org.osgi.service.component.annotations.Reference;
|
||||
|
||||
/**
|
||||
* The {@link GlobalCacheHandlerFactory} is responsible for creating thing handlers.
|
||||
*
|
||||
* @author Mark Hilbush - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
@Component(service = ThingHandlerFactory.class, configurationPid = "binding.globalcache")
|
||||
public class GlobalCacheHandlerFactory extends BaseThingHandlerFactory {
|
||||
|
||||
private final NetworkAddressService networkAddressService;
|
||||
|
||||
@Activate
|
||||
public GlobalCacheHandlerFactory(@Reference NetworkAddressService networkAddressService) {
|
||||
this.networkAddressService = networkAddressService;
|
||||
}
|
||||
|
||||
@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 (SUPPORTED_THING_TYPES_UIDS.contains(thingTypeUID)) {
|
||||
return new GlobalCacheHandler(thing, networkAddressService.getPrimaryIpv4HostAddress());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,517 @@
|
||||
/**
|
||||
* 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.globalcache.internal.command;
|
||||
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.openhab.binding.globalcache.internal.GlobalCacheBindingConstants;
|
||||
import org.openhab.binding.globalcache.internal.GlobalCacheBindingConstants.CommandType;
|
||||
import org.openhab.binding.globalcache.internal.handler.GlobalCacheHandler;
|
||||
import org.openhab.core.thing.Thing;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* The {@link AbstractCommand} class implements the basic functionality needed for all GlobalCache commands.
|
||||
*
|
||||
* @author Mark Hilbush - Initial contribution
|
||||
*/
|
||||
public abstract class AbstractCommand implements CommandInterface {
|
||||
private final Logger logger = LoggerFactory.getLogger(AbstractCommand.class);
|
||||
|
||||
private LinkedBlockingQueue<RequestMessage> requestQueue;
|
||||
|
||||
private final int RESPONSE_QUEUE_MAX_DEPTH = 1;
|
||||
private final int RESPONSE_QUEUE_TIMEOUT = 3000;
|
||||
|
||||
protected Thing thing;
|
||||
|
||||
protected String ipAddress;
|
||||
|
||||
// Actual command strings sent to/received from the device (without CR)
|
||||
protected String deviceCommand;
|
||||
protected String deviceReply;
|
||||
|
||||
// Short human-readable name of the command
|
||||
protected String commandName;
|
||||
|
||||
// Determines which TCP port will be used for the command
|
||||
private CommandType commandType;
|
||||
|
||||
protected String module;
|
||||
protected String connector;
|
||||
|
||||
protected String errorModule;
|
||||
protected String errorConnector;
|
||||
protected String errorCode;
|
||||
protected String errorMessage;
|
||||
|
||||
private boolean isQuiet;
|
||||
|
||||
/*
|
||||
* The {@link AbstractCommand} abstract class is the basis for all GlobalCache device command classes.
|
||||
*
|
||||
* @author Mark Hilbush - Initial contribution
|
||||
*/
|
||||
public AbstractCommand(Thing t, LinkedBlockingQueue<RequestMessage> q, String n, CommandType c) {
|
||||
thing = t;
|
||||
requestQueue = q;
|
||||
commandName = n;
|
||||
commandType = c;
|
||||
setQuiet(false);
|
||||
|
||||
module = null;
|
||||
connector = null;
|
||||
deviceCommand = null;
|
||||
deviceReply = null;
|
||||
errorCode = null;
|
||||
errorMessage = null;
|
||||
|
||||
ipAddress = ((GlobalCacheHandler) thing.getHandler()).getIP();
|
||||
}
|
||||
|
||||
public String getCommandName() {
|
||||
return commandName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getModule() {
|
||||
return module;
|
||||
}
|
||||
|
||||
public void setModule(String m) {
|
||||
module = m;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getConnector() {
|
||||
return connector;
|
||||
}
|
||||
|
||||
public void setConnector(String c) {
|
||||
connector = c;
|
||||
}
|
||||
|
||||
public void setCommandType(CommandType commandType) {
|
||||
this.commandType = commandType;
|
||||
}
|
||||
|
||||
public boolean isGC100Model12() {
|
||||
return thing.getThingTypeUID().equals(GlobalCacheBindingConstants.THING_TYPE_GC_100_12);
|
||||
}
|
||||
|
||||
@Override
|
||||
public abstract void parseSuccessfulReply();
|
||||
|
||||
public boolean isSuccessful() {
|
||||
return errorCode == null ? true : false;
|
||||
}
|
||||
|
||||
public String successAsString() {
|
||||
return errorCode == null ? "succeeded" : "failed";
|
||||
}
|
||||
|
||||
public String getErrorCode() {
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
public String getErrorMessage() {
|
||||
return errorMessage;
|
||||
}
|
||||
|
||||
public String getErrorModule() {
|
||||
return errorModule;
|
||||
}
|
||||
|
||||
public String getErrorConnector() {
|
||||
return errorConnector;
|
||||
}
|
||||
|
||||
protected boolean isQuiet() {
|
||||
return isQuiet;
|
||||
}
|
||||
|
||||
private void setQuiet(boolean quiet) {
|
||||
isQuiet = quiet;
|
||||
}
|
||||
|
||||
/*
|
||||
* Execute a GlobalCache device command
|
||||
*/
|
||||
public void executeQuiet() {
|
||||
setQuiet(true);
|
||||
execute();
|
||||
}
|
||||
|
||||
public void execute() {
|
||||
if (requestQueue == null) {
|
||||
createGenericError("Execute method was called with a null requestQueue");
|
||||
return;
|
||||
}
|
||||
|
||||
if (deviceCommand == null) {
|
||||
createGenericError("Execute method was called with a null deviceCommand");
|
||||
return;
|
||||
}
|
||||
|
||||
if (thing == null) {
|
||||
createGenericError("Execute method was called with a null thing");
|
||||
return;
|
||||
}
|
||||
|
||||
// Send command & get response
|
||||
if (sendCommand()) {
|
||||
parseSuccessfulReply();
|
||||
if (!isQuiet()) {
|
||||
logSuccess();
|
||||
}
|
||||
} else {
|
||||
if (!isQuiet()) {
|
||||
logFailure();
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Place a request message onto the request queue, then wait on the response queue for the
|
||||
* response message. The CommandHandler private class in GlobalCacheHandler.java
|
||||
* is responsible for the actual device interaction.
|
||||
*/
|
||||
private boolean sendCommand() {
|
||||
// Create a response queue. The command processor will use this queue to return the device's reply.
|
||||
LinkedBlockingQueue<ResponseMessage> responseQueue = new LinkedBlockingQueue<>(RESPONSE_QUEUE_MAX_DEPTH);
|
||||
|
||||
// Create the request message
|
||||
RequestMessage requestMsg = new RequestMessage(commandName, commandType, deviceCommand, responseQueue);
|
||||
|
||||
try {
|
||||
// Put the request message on the request queue
|
||||
requestQueue.put(requestMsg);
|
||||
logger.trace("Put request on queue (depth={}), sent command '{}'", requestQueue.size(), deviceCommand);
|
||||
|
||||
// Wait on the response queue for the response message
|
||||
ResponseMessage responseMsg = responseQueue.poll(RESPONSE_QUEUE_TIMEOUT, TimeUnit.MILLISECONDS);
|
||||
|
||||
if (responseMsg == null) {
|
||||
createGenericError("Timed out waiting on response queue for message");
|
||||
return false;
|
||||
}
|
||||
|
||||
deviceReply = responseMsg.getDeviceReply();
|
||||
logger.trace("Got response message off response queue, received reply '{}'", deviceReply);
|
||||
|
||||
if (isErrorReply(deviceReply)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
} catch (InterruptedException e) {
|
||||
createGenericError("Poll of response queue was interrupted");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse the reply and set error values if an error occurred.
|
||||
*/
|
||||
private boolean isErrorReply(String reply) {
|
||||
logger.trace("Checking device reply for error condition: {}", reply);
|
||||
|
||||
Pattern pattern;
|
||||
Matcher matcher;
|
||||
|
||||
// Generic (generated by binding) errors are of the form
|
||||
// ERROR: message
|
||||
if (reply.startsWith("ERROR:")) {
|
||||
createGenericError(reply);
|
||||
return true;
|
||||
}
|
||||
|
||||
// iTach response for unknown command are of the form
|
||||
// unknowncommand,eee, where eee is the error number
|
||||
if (reply.startsWith("unknowncommand,") && reply.length() >= 16) {
|
||||
String eCode = reply.substring(15);
|
||||
createGenericError("Device does not understand command, error code is " + eCode);
|
||||
errorCode = eCode;
|
||||
return true;
|
||||
}
|
||||
|
||||
// GC-100 response for unknown command are of the form
|
||||
// unknowncommand ee, where ee is the error number
|
||||
if (reply.startsWith("unknowncommand ") && reply.length() >= 16) {
|
||||
errorModule = "";
|
||||
errorConnector = "";
|
||||
errorCode = reply.substring(15);
|
||||
errorMessage = lookupErrorMessage(errorCode, GC100_ERROR_MESSAGES);
|
||||
logger.debug("Device reply indicates GC-100 error condition");
|
||||
return true;
|
||||
}
|
||||
|
||||
// iTach error replies are of the form ERR_m:c,eee, where m is the module number,
|
||||
// c is the connector number, and eee is the error number
|
||||
pattern = Pattern.compile("ERR_[0-9]:[0-3],\\d\\d\\d");
|
||||
matcher = pattern.matcher(reply);
|
||||
if (matcher.find()) {
|
||||
errorModule = reply.substring(4, 5);
|
||||
errorConnector = reply.substring(6, 7);
|
||||
errorCode = reply.substring(8, 11);
|
||||
errorMessage = lookupErrorMessage(errorCode, ITACH_ERROR_MESSAGES);
|
||||
logger.debug("Device reply indicates iTach error condition");
|
||||
return true;
|
||||
}
|
||||
|
||||
// Flex general error replies are of the form ERR eee, where eee is the error number
|
||||
pattern = Pattern.compile("ERR \\d\\d\\d");
|
||||
matcher = pattern.matcher(reply);
|
||||
if (matcher.find()) {
|
||||
errorModule = "";
|
||||
errorConnector = "";
|
||||
errorCode = reply.substring(4);
|
||||
errorMessage = lookupErrorMessage(errorCode, FLEX_ERROR_MESSAGES);
|
||||
logger.debug("Device reply indicates Flex general error condition");
|
||||
return true;
|
||||
}
|
||||
|
||||
// Flex infrared error replies are of the form ERR IReee, where eee is the error number
|
||||
pattern = Pattern.compile("ERR IR\\d\\d\\d");
|
||||
matcher = pattern.matcher(reply);
|
||||
if (matcher.find()) {
|
||||
errorModule = "";
|
||||
errorConnector = "";
|
||||
errorCode = reply.substring(6);
|
||||
errorMessage = lookupErrorMessage(errorCode, FLEX_IR_ERROR_MESSAGES);
|
||||
logger.debug("Device reply indicates Flex IR error condition");
|
||||
return true;
|
||||
}
|
||||
|
||||
// Flex serial error replies are of the form ERR SLeee, where eee is the error number
|
||||
pattern = Pattern.compile("ERR SL\\d\\d\\d");
|
||||
matcher = pattern.matcher(reply);
|
||||
if (matcher.find()) {
|
||||
errorModule = "";
|
||||
errorConnector = "";
|
||||
errorCode = reply.substring(6);
|
||||
errorMessage = lookupErrorMessage(errorCode, FLEX_SL_ERROR_MESSAGES);
|
||||
logger.debug("Device reply indicates Flex SL error condition");
|
||||
return true;
|
||||
}
|
||||
|
||||
errorCode = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
private void createGenericError(String s) {
|
||||
errorModule = "N/A";
|
||||
errorConnector = "N/A";
|
||||
errorCode = "N/A";
|
||||
errorMessage = s;
|
||||
}
|
||||
|
||||
private String lookupErrorMessage(String errorCode, String[] errorMessageArray) {
|
||||
int eCode;
|
||||
try {
|
||||
eCode = Integer.parseInt(errorCode);
|
||||
|
||||
} catch (NumberFormatException e) {
|
||||
eCode = 0;
|
||||
logger.debug("Badly formatted error code '{}' received from device: {}", errorCode, e.getMessage());
|
||||
}
|
||||
|
||||
if (eCode < 1 || eCode > errorMessageArray.length) {
|
||||
eCode = 0;
|
||||
}
|
||||
return errorMessageArray[eCode];
|
||||
}
|
||||
|
||||
/*
|
||||
* Errors returned by GlobalCache iTach devices
|
||||
*/
|
||||
private static final String[] ITACH_ERROR_MESSAGES = {
|
||||
// 0
|
||||
"Unknown error",
|
||||
// 1
|
||||
"Invalid command. Command not found.",
|
||||
// 2
|
||||
"Invalid module address (does not exist).",
|
||||
// 3
|
||||
"Invalid connector address (does not exist).",
|
||||
// 4
|
||||
"Invalid ID value.",
|
||||
// 5
|
||||
"Invalid frequency value",
|
||||
// 6
|
||||
"Invalid repeat value.",
|
||||
// 7
|
||||
"Invalid offset value.",
|
||||
// 8
|
||||
"Invalid pulse count.",
|
||||
// 9
|
||||
"Invalid pulse data.",
|
||||
// 10
|
||||
"Uneven amount of <on|off> statements.",
|
||||
// 11
|
||||
"No carriage return found.",
|
||||
// 12
|
||||
"Repeat count exceeded.",
|
||||
// 13
|
||||
"IR command sent to input connector.",
|
||||
// 14
|
||||
"Blaster command sent to non-blaster connector.",
|
||||
// 15
|
||||
"No carriage return before buffer full.",
|
||||
// 16
|
||||
"No carriage return.",
|
||||
// 17
|
||||
"Bad command syntax.",
|
||||
// 18
|
||||
"Sensor command sent to non-input connector.",
|
||||
// 19
|
||||
"Repeated IR transmission failure.",
|
||||
// 20
|
||||
"Above designated IR <on|off> pair limit.",
|
||||
// 21
|
||||
"Symbol odd boundary.",
|
||||
// 22
|
||||
"Undefined symbol.",
|
||||
// 23
|
||||
"Unknown option.",
|
||||
// 24
|
||||
"Invalid baud rate setting.",
|
||||
// 25
|
||||
"Invalid flow control setting.",
|
||||
// 26
|
||||
"Invalid parity setting.",
|
||||
// 27
|
||||
"Settings are locked."
|
||||
//
|
||||
};
|
||||
|
||||
/*
|
||||
* Errors returned by GlobalCache GC-100 devices
|
||||
*/
|
||||
private static final String[] GC100_ERROR_MESSAGES = {
|
||||
// 0
|
||||
"Unknown error.",
|
||||
// 1
|
||||
"Time out occurred because <CR> not received. Request not processed",
|
||||
// 2
|
||||
"Invalid module address (module does not exist) received with getversion.",
|
||||
// 3
|
||||
"Invalid module address (module does not exist).",
|
||||
// 4
|
||||
"Invalid connector address.",
|
||||
// 5
|
||||
"Connector address 1 is set up as “sensor in” when attempting IR command.",
|
||||
// 6
|
||||
"Connector address 2 is set up as “sensor in” when attempting IR command.",
|
||||
// 7
|
||||
"Connector address 3 is set up as “sensor in” when attempting IR command.",
|
||||
// 8
|
||||
"Offset is set to an even transition number, but should be odd.",
|
||||
// 9
|
||||
"Maximum number of transitions exceeded (256 total allowed).",
|
||||
// 10
|
||||
"Number of transitions in the IR command is not even.",
|
||||
// 11
|
||||
"Contact closure command sent to a module that is not a relay.",
|
||||
// 12
|
||||
"Missing carriage return. All commands must end with a carriage return.",
|
||||
// 13
|
||||
"State was requested of an invalid connector address.",
|
||||
// 14
|
||||
"Command sent to the unit is not supported by the GC-100.",
|
||||
// 15
|
||||
"Maximum number of IR transitions exceeded. (SM_IR_INPROCESS)",
|
||||
// 16
|
||||
"Invalid number of IR transitions (must be an even number).",
|
||||
// 17
|
||||
"Unknown error.",
|
||||
// 18
|
||||
"Unknown error.",
|
||||
// 19
|
||||
"Unknown error.",
|
||||
// 20
|
||||
"Unknown error.",
|
||||
// 21
|
||||
"Attempted to send an IR command to a non-IR module.",
|
||||
// 22
|
||||
"Unknown error.",
|
||||
// 23
|
||||
"Command sent is not supported by this type of module."
|
||||
//
|
||||
};
|
||||
|
||||
/*
|
||||
* General errors returned by Flex devices
|
||||
*/
|
||||
private static final String[] FLEX_ERROR_MESSAGES = {
|
||||
// 0
|
||||
"Unknown error.",
|
||||
// 1
|
||||
"Invalid command. Command not found.",
|
||||
// 2
|
||||
"Bad command syntax used with a known command.",
|
||||
// 3
|
||||
"Invalid connector address (does not exist).",
|
||||
// 4
|
||||
"No carriage return found.",
|
||||
// 5
|
||||
"Command not supported by current Flex Link Port setting.",
|
||||
// 6
|
||||
"Settings are locked.",
|
||||
//
|
||||
};
|
||||
|
||||
/*
|
||||
* Infrared errors returned by Flex devices
|
||||
*/
|
||||
private static final String[] FLEX_IR_ERROR_MESSAGES = {
|
||||
// 0
|
||||
"Unknown error.",
|
||||
// 1
|
||||
"Invalid ID value.",
|
||||
// 2
|
||||
"Invalid frequency.",
|
||||
// 3
|
||||
"Invalid repeat.",
|
||||
// 4
|
||||
"Invalid offset.",
|
||||
// 5
|
||||
"Invalid IR pulse value.",
|
||||
// 6
|
||||
"Odd amount of IR pulse values (must be even).",
|
||||
// 7
|
||||
"Maximum pulse pair limit exceeded.",
|
||||
//
|
||||
};
|
||||
|
||||
/*
|
||||
* Serial errors returned by Flex devices
|
||||
*/
|
||||
private static final String[] FLEX_SL_ERROR_MESSAGES = {
|
||||
// 0
|
||||
"Unknown error.",
|
||||
// 1
|
||||
"Invalid baud rate.",
|
||||
// 2
|
||||
"Invalid flow control setting.",
|
||||
// 3
|
||||
"Invalid parity setting.",
|
||||
//
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/**
|
||||
* 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.globalcache.internal.command;
|
||||
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
|
||||
import org.openhab.binding.globalcache.internal.GlobalCacheBindingConstants.CommandType;
|
||||
import org.openhab.core.thing.Thing;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* The {@link CommandGetdevices} class implements the GlobalCache getdevices command.
|
||||
*
|
||||
* @author Mark Hilbush - Initial contribution
|
||||
*/
|
||||
public class CommandGetdevices extends AbstractCommand {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(CommandGetdevices.class);
|
||||
|
||||
public CommandGetdevices(Thing thing, LinkedBlockingQueue<RequestMessage> requestQueue) {
|
||||
super(thing, requestQueue, "getdevices", CommandType.COMMAND);
|
||||
deviceCommand = "getdevices";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parseSuccessfulReply() {
|
||||
if (deviceReply == null) {
|
||||
return;
|
||||
}
|
||||
// decode response
|
||||
}
|
||||
|
||||
@Override
|
||||
public void logSuccess() {
|
||||
logger.debug("Execute '{}' succeeded on thing {} at {}", commandName, thing.getUID().getId(), ipAddress);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void logFailure() {
|
||||
logger.error("Execute '{}' failed for thing {} at {}, errorCode={}, errorMessage={}", commandName,
|
||||
thing.getUID().getId(), ipAddress, errorCode, errorMessage);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
/**
|
||||
* 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.globalcache.internal.command;
|
||||
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.openhab.binding.globalcache.internal.GlobalCacheBindingConstants.CommandType;
|
||||
import org.openhab.core.thing.Thing;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* The {@link CommandGetserial} class implements the GlobalCache get_SERIAL command, which retrieves the serial
|
||||
* port parameters (baud, flow control, and parity) from the device.
|
||||
*
|
||||
* @author Mark Hilbush - Initial contribution
|
||||
*/
|
||||
public class CommandGetserial extends AbstractCommand {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(CommandGetserial.class);
|
||||
|
||||
private String baud;
|
||||
private String flow;
|
||||
private String parity;
|
||||
|
||||
public CommandGetserial(Thing thing, LinkedBlockingQueue<RequestMessage> requestQueue, String mod, String con) {
|
||||
super(thing, requestQueue, "get_SERIAL", CommandType.COMMAND);
|
||||
|
||||
deviceCommand = "get_SERIAL," + mod + ":" + con;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parseSuccessfulReply() {
|
||||
if (deviceReply == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// decode response of form SERIAL,1:1,<baudrate>,<flowcontrol>,<parity
|
||||
Pattern p = Pattern.compile("SERIAL,\\d:\\d,\\S+,\\S+,\\S+");
|
||||
Matcher m = p.matcher(deviceReply);
|
||||
if (!m.matches()) {
|
||||
return;
|
||||
}
|
||||
|
||||
String fields[] = deviceReply.split(",");
|
||||
if (fields.length != 5) {
|
||||
return;
|
||||
}
|
||||
|
||||
setModule(fields[1].substring(0, 1));
|
||||
setConnector(fields[1].substring(2));
|
||||
baud = fields[2];
|
||||
flow = fields[3];
|
||||
parity = fields[4];
|
||||
}
|
||||
|
||||
public String getBaud() {
|
||||
return baud;
|
||||
}
|
||||
|
||||
public String getFlowcontrol() {
|
||||
return flow;
|
||||
}
|
||||
|
||||
public String getParity() {
|
||||
return parity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void logSuccess() {
|
||||
logger.debug("Execute '{}' succeeded on thing {} at {}", commandName, thing.getUID().getId(), ipAddress);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void logFailure() {
|
||||
logger.error("Execute '{}' failed on thing {} at {}: errorCode={}, errorMessage={}", commandName,
|
||||
thing.getUID().getId(), ipAddress, errorCode, errorMessage);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
/**
|
||||
* 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.globalcache.internal.command;
|
||||
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.openhab.binding.globalcache.internal.GlobalCacheBindingConstants.CommandType;
|
||||
import org.openhab.core.library.types.OnOffType;
|
||||
import org.openhab.core.thing.Thing;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* The {@link CommandGetstate} class implements the GlobalCache getstate command, which retrieves the
|
||||
* current state of the contact closure on the device.
|
||||
*
|
||||
* @author Mark Hilbush - Initial contribution
|
||||
*/
|
||||
public class CommandGetstate extends AbstractCommand {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(CommandGetstate.class);
|
||||
|
||||
private OnOffType state;
|
||||
|
||||
public CommandGetstate(Thing thing, LinkedBlockingQueue<RequestMessage> requestQueue, String mod, String con) {
|
||||
super(thing, requestQueue, "getstate", CommandType.COMMAND);
|
||||
deviceCommand = "getstate," + mod + ":" + con;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parseSuccessfulReply() {
|
||||
if (deviceReply == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// decode response of form state,1:3,0
|
||||
Pattern p = Pattern.compile("state,\\d:\\d,[01]");
|
||||
Matcher m = p.matcher(deviceReply);
|
||||
if (!m.matches()) {
|
||||
logger.warn("Successful reply from device can't be matched: {}", deviceReply);
|
||||
state = OnOffType.OFF;
|
||||
return;
|
||||
}
|
||||
|
||||
setModule(deviceReply.substring(6, 7));
|
||||
setConnector(deviceReply.substring(8, 9));
|
||||
setState((deviceReply.charAt(10) == '0' ? OnOffType.OFF : OnOffType.ON));
|
||||
}
|
||||
|
||||
private void setState(OnOffType s) {
|
||||
state = s;
|
||||
}
|
||||
|
||||
public OnOffType state() {
|
||||
return state;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void logSuccess() {
|
||||
logger.debug("Execute '{}' succeeded on thing {} at {}, state={}", commandName, thing.getUID().getId(),
|
||||
ipAddress, state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void logFailure() {
|
||||
logger.error("Execute '{}' failed on thing {} at {}: errorCode={}, errorMessage={}", commandName,
|
||||
thing.getUID().getId(), ipAddress, errorCode, errorMessage);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/**
|
||||
* 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.globalcache.internal.command;
|
||||
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
|
||||
import org.openhab.binding.globalcache.internal.GlobalCacheBindingConstants.CommandType;
|
||||
import org.openhab.core.thing.Thing;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* The {@link CommandGetversion} class implements the GlobalCache getversion command, which retrieves software
|
||||
* version of the device.
|
||||
*
|
||||
* @author Mark Hilbush - Initial contribution
|
||||
*/
|
||||
public class CommandGetversion extends AbstractCommand {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(CommandGetversion.class);
|
||||
|
||||
private String version;
|
||||
|
||||
public CommandGetversion(Thing thing, LinkedBlockingQueue<RequestMessage> requestQueue) {
|
||||
super(thing, requestQueue, "getversion", CommandType.COMMAND);
|
||||
deviceCommand = "getversion";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parseSuccessfulReply() {
|
||||
if (deviceReply == null) {
|
||||
return;
|
||||
}
|
||||
// decode response of form <textversionstring>
|
||||
version = deviceReply;
|
||||
}
|
||||
|
||||
public String getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void logSuccess() {
|
||||
logger.debug("Execute '{}' succeeded on thing {} at {}, version={}", commandName, thing.getUID().getId(),
|
||||
ipAddress, version);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void logFailure() {
|
||||
logger.error("Execute '{}' failed for thing {} at {}, errorCode={}, errorMessage={}", commandName,
|
||||
thing.getUID().getId(), ipAddress, errorCode, errorMessage);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/**
|
||||
* 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.globalcache.internal.command;
|
||||
|
||||
/**
|
||||
* The {@link CommandInterface} interface class defines the methods that all command classes must implement.
|
||||
*
|
||||
* @author Mark Hilbush - Initial contribution
|
||||
*/
|
||||
public interface CommandInterface {
|
||||
|
||||
/**
|
||||
* Get the module number to which the command will be sent
|
||||
*
|
||||
* @return module number as String
|
||||
*/
|
||||
public String getModule();
|
||||
|
||||
/**
|
||||
* Get the connector number to which the command will be sent
|
||||
*
|
||||
* @return connector number as String
|
||||
*/
|
||||
public String getConnector();
|
||||
|
||||
/**
|
||||
* Used by command implementations to parse the device's response
|
||||
*/
|
||||
abstract void parseSuccessfulReply();
|
||||
|
||||
/*
|
||||
* Used by command implementations to report a successful command execution
|
||||
*/
|
||||
abstract void logSuccess();
|
||||
|
||||
/*
|
||||
* Used by command implementations to report a failed command execution
|
||||
*/
|
||||
abstract void logFailure();
|
||||
}
|
||||
@@ -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.globalcache.internal.command;
|
||||
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
|
||||
import org.openhab.binding.globalcache.internal.GlobalCacheBindingConstants.CommandType;
|
||||
import org.openhab.core.thing.Thing;
|
||||
import org.openhab.core.types.Command;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* The {@link CommandSendir} class implements the GlobalCache sendir command, which sends
|
||||
* an infrared command to the device.
|
||||
*
|
||||
* @author Mark Hilbush - Initial contribution
|
||||
*/
|
||||
public class CommandSendir extends AbstractCommand {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(CommandSendir.class);
|
||||
|
||||
private String rcvCounter;
|
||||
Command command;
|
||||
|
||||
public CommandSendir(Thing thing, Command command, LinkedBlockingQueue<RequestMessage> queue, String mod,
|
||||
String con, String code, int sendCounter) {
|
||||
super(thing, queue, "sendir", CommandType.COMMAND);
|
||||
|
||||
this.command = command;
|
||||
deviceCommand = "sendir," + mod + ":" + con + "," + String.valueOf(sendCounter) + "," + code;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parseSuccessfulReply() {
|
||||
if (deviceReply == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// decode response of form completeir,1:1,<ID>
|
||||
if (deviceReply.startsWith("completeir")) {
|
||||
setModule(deviceReply.substring(11, 12));
|
||||
setConnector(deviceReply.substring(13, 14));
|
||||
setRcvCounter(deviceReply.substring(15));
|
||||
}
|
||||
}
|
||||
|
||||
private void setRcvCounter(String c) {
|
||||
rcvCounter = c;
|
||||
}
|
||||
|
||||
public String getRcvCounter() {
|
||||
return rcvCounter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void logSuccess() {
|
||||
logger.debug("Execute '{}' succeeded for command {} on thing {} at {}", commandName, command.toString(),
|
||||
thing.getUID().getId(), ipAddress);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void logFailure() {
|
||||
logger.error("Execute '{}' failed on thing {} at {}: errorCode={}, errorMessage={}", commandName,
|
||||
thing.getUID().getId(), ipAddress, errorCode, errorMessage);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/**
|
||||
* 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.globalcache.internal.command;
|
||||
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
|
||||
import org.openhab.binding.globalcache.internal.GlobalCacheBindingConstants.CommandType;
|
||||
import org.openhab.core.thing.Thing;
|
||||
import org.openhab.core.types.Command;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* The {@link CommandSendserial} class sends a serial command string to the device.
|
||||
*
|
||||
* @author Mark Hilbush - Initial contribution
|
||||
*/
|
||||
public class CommandSendserial extends AbstractCommand {
|
||||
private final Logger logger = LoggerFactory.getLogger(CommandSendserial.class);
|
||||
|
||||
private Command command;
|
||||
|
||||
public CommandSendserial(Thing thing, Command command, LinkedBlockingQueue<RequestMessage> queue, String mod,
|
||||
String con, String code) {
|
||||
super(thing, queue, "sendserial", CommandType.SERIAL1);
|
||||
// Check to see if this is for the second serial port on a GC-100-12
|
||||
if (isGC100Model12() && mod.equals("2")) {
|
||||
setCommandType(CommandType.SERIAL2);
|
||||
}
|
||||
this.command = command;
|
||||
this.deviceCommand = code;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parseSuccessfulReply() {
|
||||
if (deviceReply == null) {
|
||||
return;
|
||||
}
|
||||
// decode response
|
||||
}
|
||||
|
||||
@Override
|
||||
public void logSuccess() {
|
||||
logger.debug("Execute '{}' succeeded for command {} on thing {} at {}", commandName, command.toString(),
|
||||
thing.getUID().getId(), ipAddress);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void logFailure() {
|
||||
logger.error("Execute '{}' failed on thing {} at {}: errorCode={}, errorMessage={}", commandName,
|
||||
thing.getUID().getId(), ipAddress, errorCode, errorMessage);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
/**
|
||||
* 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.globalcache.internal.command;
|
||||
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.openhab.binding.globalcache.internal.GlobalCacheBindingConstants.CommandType;
|
||||
import org.openhab.core.thing.Thing;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* The {@link CommandSetserial} class implements the GlobalCache set_SERIAL command, which sets the serial
|
||||
* port parameters (baud, flow control, and parity) on the device.
|
||||
*
|
||||
* @author Mark Hilbush - Initial contribution
|
||||
*/
|
||||
public class CommandSetserial extends AbstractCommand {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(CommandSetserial.class);
|
||||
|
||||
private String baud;
|
||||
private String flow;
|
||||
private String parity;
|
||||
|
||||
public CommandSetserial(Thing thing, LinkedBlockingQueue<RequestMessage> requestQueue, String mod, String con,
|
||||
String baud, String flowcontrol, String parity) {
|
||||
super(thing, requestQueue, "set_SERIAL", CommandType.COMMAND);
|
||||
|
||||
deviceCommand = "set_SERIAL," + mod + ":" + con + "," + baud + "," + flowcontrol + "," + parity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parseSuccessfulReply() {
|
||||
if (deviceReply == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// decode response of form SERIAL,1:1,<baudrate>,<flowcontrol>,<parity
|
||||
Pattern p = Pattern.compile("SERIAL,\\d:\\d,\\S+,\\S+,\\S+");
|
||||
Matcher m = p.matcher(deviceReply);
|
||||
if (!m.matches()) {
|
||||
return;
|
||||
}
|
||||
|
||||
String fields[] = deviceReply.split(",");
|
||||
if (fields.length != 5) {
|
||||
return;
|
||||
}
|
||||
|
||||
setModule(fields[1].substring(0, 1));
|
||||
setConnector(fields[1].substring(2));
|
||||
baud = fields[2];
|
||||
flow = fields[3];
|
||||
parity = fields[4];
|
||||
}
|
||||
|
||||
public String getBaud() {
|
||||
return baud;
|
||||
}
|
||||
|
||||
public String getFlowcontrol() {
|
||||
return flow;
|
||||
}
|
||||
|
||||
public String getParity() {
|
||||
return parity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void logSuccess() {
|
||||
logger.debug("Execute '{}' succeeded on thing {} at {}", commandName, thing.getUID().getId(), ipAddress);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void logFailure() {
|
||||
logger.error("Execute '{}' failed on thing {} at: ipAdress={}, errorCode={}, errorMessage={}", commandName,
|
||||
thing.getUID().getId(), ipAddress, errorCode, errorMessage);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
/**
|
||||
* 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.globalcache.internal.command;
|
||||
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.openhab.binding.globalcache.internal.GlobalCacheBindingConstants.CommandType;
|
||||
import org.openhab.core.library.types.OnOffType;
|
||||
import org.openhab.core.thing.Thing;
|
||||
import org.openhab.core.types.Command;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* The {@link CommandSetstate} class implements the GlobalCache setstate command for devices that support contact
|
||||
* closure.
|
||||
*
|
||||
* @author Mark Hilbush - Initial contribution
|
||||
*/
|
||||
public class CommandSetstate extends AbstractCommand {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(CommandSetstate.class);
|
||||
|
||||
private Command command;
|
||||
private OnOffType state;
|
||||
|
||||
public CommandSetstate(Thing thing, Command command, LinkedBlockingQueue<RequestMessage> queue, String mod,
|
||||
String con) {
|
||||
super(thing, queue, "setstate", CommandType.COMMAND);
|
||||
|
||||
this.command = command;
|
||||
if (command instanceof OnOffType) {
|
||||
deviceCommand = "setstate," + mod + ":" + con + "," + (command.equals(OnOffType.ON) ? "1" : "0");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parseSuccessfulReply() {
|
||||
if (deviceReply == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Match on response of form setstate,1:3,0 or state,1:3,0
|
||||
if (!matchSetstate()) {
|
||||
logger.warn("Successful reply from device can't be matched: {}", deviceReply);
|
||||
setState(OnOffType.OFF);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean matchSetstate() {
|
||||
// Matches both iTach and GC-100 responses
|
||||
Pattern p = Pattern.compile("(setstate|state),(\\d):(\\d),([01])");
|
||||
Matcher m = p.matcher(deviceReply);
|
||||
if (m.matches()) {
|
||||
logger.trace("Matched setstate response: g2={}, g3={}, g4={}", m.group(2), m.group(3), m.group(4));
|
||||
if (m.groupCount() == 4) {
|
||||
setModule(m.group(2));
|
||||
setConnector(m.group(3));
|
||||
setState(m.group(4).equals("0") ? OnOffType.OFF : OnOffType.ON);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void setState(OnOffType s) {
|
||||
state = s;
|
||||
}
|
||||
|
||||
public OnOffType state() {
|
||||
return state;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void logSuccess() {
|
||||
logger.debug("Execute '{}' succeeded for command {} on thing {} at {}", commandName, command,
|
||||
thing.getUID().getId(), ipAddress);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void logFailure() {
|
||||
logger.error("Execute '{}' failed on thing {} at {}: errorCode={}, errorMessage={}", commandName,
|
||||
thing.getUID().getId(), ipAddress, errorCode, errorMessage);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
/**
|
||||
* 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.globalcache.internal.command;
|
||||
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
|
||||
import org.openhab.binding.globalcache.internal.GlobalCacheBindingConstants.CommandType;
|
||||
|
||||
/**
|
||||
* The {@link RequestMessage} class is responsible for storing the command to be sent to the GlobalCache
|
||||
* device and for storing whether the command is serial or not.
|
||||
*
|
||||
* @author Mark Hilbush - Initial contribution
|
||||
*/
|
||||
public class RequestMessage {
|
||||
private LinkedBlockingQueue<ResponseMessage> rcvQueue;
|
||||
private String deviceCommand;
|
||||
private CommandType commandType;
|
||||
private String commandName;
|
||||
|
||||
public RequestMessage(String commandName, CommandType commandType, String deviceCommand,
|
||||
LinkedBlockingQueue<ResponseMessage> rcvQueue) {
|
||||
this.commandName = commandName;
|
||||
this.commandType = commandType;
|
||||
this.deviceCommand = deviceCommand;
|
||||
this.rcvQueue = rcvQueue;
|
||||
}
|
||||
|
||||
public String getDeviceCommand() {
|
||||
return deviceCommand;
|
||||
}
|
||||
|
||||
public String getCommandName() {
|
||||
return commandName;
|
||||
}
|
||||
|
||||
public CommandType getCommandType() {
|
||||
return commandType;
|
||||
}
|
||||
|
||||
public boolean isCommand() {
|
||||
return commandType == CommandType.COMMAND;
|
||||
}
|
||||
|
||||
public boolean isSerial() {
|
||||
return commandType == CommandType.SERIAL1 || commandType == CommandType.SERIAL2;
|
||||
}
|
||||
|
||||
public boolean isSerial1() {
|
||||
return commandType == CommandType.SERIAL1;
|
||||
}
|
||||
|
||||
public boolean isSerial2() {
|
||||
return commandType == CommandType.SERIAL2;
|
||||
}
|
||||
|
||||
public LinkedBlockingQueue<ResponseMessage> getReceiveQueue() {
|
||||
return rcvQueue;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/**
|
||||
* 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.globalcache.internal.command;
|
||||
|
||||
/**
|
||||
* The {@link ResponseMessage} class is responsible for storing the raw and parsed response from the
|
||||
* GlobalCache device.
|
||||
*
|
||||
* @author Mark Hilbush - Initial contribution
|
||||
*/
|
||||
public class ResponseMessage {
|
||||
|
||||
private String deviceReply;
|
||||
|
||||
public ResponseMessage(String deviceReply) {
|
||||
this.deviceReply = deviceReply;
|
||||
}
|
||||
|
||||
public String getDeviceReply() {
|
||||
return deviceReply;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,182 @@
|
||||
/**
|
||||
* 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.globalcache.internal.discovery;
|
||||
|
||||
import static org.openhab.binding.globalcache.internal.GlobalCacheBindingConstants.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.SocketException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.openhab.core.config.discovery.AbstractDiscoveryService;
|
||||
import org.openhab.core.config.discovery.DiscoveryResultBuilder;
|
||||
import org.openhab.core.config.discovery.DiscoveryService;
|
||||
import org.openhab.core.net.NetworkAddressService;
|
||||
import org.openhab.core.thing.Thing;
|
||||
import org.openhab.core.thing.ThingTypeUID;
|
||||
import org.openhab.core.thing.ThingUID;
|
||||
import org.osgi.service.component.annotations.Component;
|
||||
import org.osgi.service.component.annotations.Modified;
|
||||
import org.osgi.service.component.annotations.Reference;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* The {@link GlobalCacheDiscoveryService} class implements a service
|
||||
* for discovering the GlobalCache devices.
|
||||
*
|
||||
* @author Mark Hilbush - Initial contribution
|
||||
*/
|
||||
@Component(service = DiscoveryService.class, immediate = true, configurationPid = "discovery.globalcache")
|
||||
public class GlobalCacheDiscoveryService extends AbstractDiscoveryService {
|
||||
private final Logger logger = LoggerFactory.getLogger(GlobalCacheDiscoveryService.class);
|
||||
|
||||
private ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(1);
|
||||
private ScheduledFuture<?> gcDiscoveryJob;
|
||||
|
||||
// Discovery parameters
|
||||
public static final boolean BACKGROUND_DISCOVERY_ENABLED = true;
|
||||
public static final int BACKGROUND_DISCOVERY_DELAY = 10;
|
||||
|
||||
private NetworkAddressService networkAddressService;
|
||||
|
||||
private boolean terminate;
|
||||
|
||||
public GlobalCacheDiscoveryService() {
|
||||
super(SUPPORTED_THING_TYPES_UIDS, 0, BACKGROUND_DISCOVERY_ENABLED);
|
||||
gcDiscoveryJob = null;
|
||||
terminate = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<ThingTypeUID> getSupportedThingTypes() {
|
||||
return SUPPORTED_THING_TYPES_UIDS;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void activate(Map<String, Object> configProperties) {
|
||||
logger.debug("Globalcache discovery service activated");
|
||||
super.activate(configProperties);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void deactivate() {
|
||||
logger.debug("Globalcache discovery service deactivated");
|
||||
stopBackgroundDiscovery();
|
||||
super.deactivate();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Modified
|
||||
protected void modified(Map<String, Object> configProperties) {
|
||||
super.modified(configProperties);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void startBackgroundDiscovery() {
|
||||
if (gcDiscoveryJob == null) {
|
||||
terminate = false;
|
||||
logger.debug("Starting background discovery job in {} seconds", BACKGROUND_DISCOVERY_DELAY);
|
||||
gcDiscoveryJob = scheduledExecutorService.schedule(this::discover, BACKGROUND_DISCOVERY_DELAY,
|
||||
TimeUnit.SECONDS);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void stopBackgroundDiscovery() {
|
||||
if (gcDiscoveryJob != null) {
|
||||
logger.debug("Canceling background discovery job");
|
||||
terminate = true;
|
||||
gcDiscoveryJob.cancel(false);
|
||||
gcDiscoveryJob = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startScan() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stopScan() {
|
||||
}
|
||||
|
||||
private synchronized void discover() {
|
||||
logger.debug("Discovery job is running");
|
||||
|
||||
MulticastListener gcMulticastListener;
|
||||
|
||||
try {
|
||||
gcMulticastListener = new MulticastListener(networkAddressService.getPrimaryIpv4HostAddress());
|
||||
} catch (SocketException se) {
|
||||
logger.error("Discovery job got Socket exception creating multicast socket: {}", se.getMessage());
|
||||
return;
|
||||
} catch (IOException ioe) {
|
||||
logger.error("Discovery job got IO exception creating multicast socket: {}", ioe.getMessage());
|
||||
return;
|
||||
}
|
||||
|
||||
while (!terminate) {
|
||||
boolean beaconReceived;
|
||||
try {
|
||||
// Wait for a discovery beacon.
|
||||
beaconReceived = gcMulticastListener.waitForBeacon();
|
||||
} catch (IOException ioe) {
|
||||
logger.debug("Discovery job got exception waiting for beacon: {}", ioe.getMessage());
|
||||
beaconReceived = false;
|
||||
}
|
||||
|
||||
if (beaconReceived) {
|
||||
// We got a discovery beacon. Process it as a potential new thing
|
||||
Map<String, Object> properties = new HashMap<>();
|
||||
|
||||
properties.put(THING_PROPERTY_IP, gcMulticastListener.getIPAddress());
|
||||
properties.put(THING_PROPERTY_MAC, gcMulticastListener.getMACAddress());
|
||||
properties.put(THING_PROPERTY_UID, gcMulticastListener.getUID());
|
||||
properties.put(Thing.PROPERTY_VENDOR, gcMulticastListener.getVendor());
|
||||
properties.put(Thing.PROPERTY_MODEL_ID, gcMulticastListener.getModel());
|
||||
properties.put(Thing.PROPERTY_FIRMWARE_VERSION, gcMulticastListener.getSoftwareRevision());
|
||||
properties.put(Thing.PROPERTY_HARDWARE_VERSION, gcMulticastListener.getHardwareRevision());
|
||||
properties.put(Thing.PROPERTY_SERIAL_NUMBER, gcMulticastListener.getSerialNumber());
|
||||
|
||||
logger.trace("Device of type {} discovered with MAC {} and IP {}", gcMulticastListener.getModel(),
|
||||
gcMulticastListener.getMACAddress(), gcMulticastListener.getIPAddress());
|
||||
|
||||
ThingTypeUID typeUID = gcMulticastListener.getThingTypeUID();
|
||||
if (typeUID != null) {
|
||||
ThingUID uid = new ThingUID(typeUID, gcMulticastListener.getSerialNumber());
|
||||
logger.trace("Creating discovery result for: {}, type={}, IP={}", uid,
|
||||
gcMulticastListener.getModel(), gcMulticastListener.getIPAddress());
|
||||
thingDiscovered(DiscoveryResultBuilder.create(uid).withProperties(properties)
|
||||
.withLabel(gcMulticastListener.getVendor() + " " + gcMulticastListener.getModel()).build());
|
||||
}
|
||||
}
|
||||
}
|
||||
gcMulticastListener.shutdown();
|
||||
logger.debug("Discovery job is exiting");
|
||||
}
|
||||
|
||||
@Reference
|
||||
protected void setNetworkAddressService(NetworkAddressService networkAddressService) {
|
||||
this.networkAddressService = networkAddressService;
|
||||
}
|
||||
|
||||
protected void unsetNetworkAddressService(NetworkAddressService networkAddressService) {
|
||||
this.networkAddressService = null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,323 @@
|
||||
/**
|
||||
* 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.globalcache.internal.discovery;
|
||||
|
||||
import static org.openhab.binding.globalcache.internal.GlobalCacheBindingConstants.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.DatagramPacket;
|
||||
import java.net.InetAddress;
|
||||
import java.net.MulticastSocket;
|
||||
import java.net.NetworkInterface;
|
||||
import java.net.SocketException;
|
||||
import java.net.SocketTimeoutException;
|
||||
import java.util.Date;
|
||||
|
||||
import org.openhab.core.thing.ThingTypeUID;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* The {@link MulticastListener} class is responsible for listening for the GlobalCache device announcement
|
||||
* beacons on the multicast address, and then extracting the data fields out of the received datagram.
|
||||
*
|
||||
* @author Mark Hilbush - Initial contribution
|
||||
*/
|
||||
public class MulticastListener {
|
||||
private final Logger logger = LoggerFactory.getLogger(MulticastListener.class);
|
||||
|
||||
private MulticastSocket socket;
|
||||
|
||||
private String serialNumber = "";
|
||||
private String vendor = "";
|
||||
private String model = "";
|
||||
private String softwareRevision = "";
|
||||
private String hardwareRevision = "";
|
||||
|
||||
// GlobalCache-specific properties defined in this binding
|
||||
private String uid = "";
|
||||
private String ipAddress = "";
|
||||
private String macAddress = "";
|
||||
|
||||
private Date lastUpdate;
|
||||
|
||||
// GC devices announce themselves on a multicast port
|
||||
private static final String GC_MULTICAST_GROUP = "239.255.250.250";
|
||||
private static final int GC_MULTICAST_PORT = 9131;
|
||||
|
||||
// How long to wait in milliseconds for a discovery beacon
|
||||
public static final int DEFAULT_SOCKET_TIMEOUT = 3000;
|
||||
|
||||
/*
|
||||
* Constructor joins the multicast group, throws IOException on failure.
|
||||
*/
|
||||
public MulticastListener(String ipv4Address) throws IOException, SocketException {
|
||||
InetAddress ifAddress = InetAddress.getByName(ipv4Address);
|
||||
logger.debug("Discovery job using address {} on network interface {}", ifAddress.getHostAddress(),
|
||||
NetworkInterface.getByInetAddress(ifAddress).getName());
|
||||
socket = new MulticastSocket(GC_MULTICAST_PORT);
|
||||
socket.setInterface(ifAddress);
|
||||
socket.setSoTimeout(DEFAULT_SOCKET_TIMEOUT);
|
||||
InetAddress mcastAddress = InetAddress.getByName(GC_MULTICAST_GROUP);
|
||||
socket.joinGroup(mcastAddress);
|
||||
logger.debug("Multicast listener joined multicast group {}:{}", GC_MULTICAST_GROUP, GC_MULTICAST_PORT);
|
||||
}
|
||||
|
||||
public void shutdown() {
|
||||
logger.debug("Multicast listener closing down multicast socket");
|
||||
socket.close();
|
||||
}
|
||||
|
||||
/*
|
||||
* Wait on the multicast socket for an announcement beacon. Return false on socket timeout or error.
|
||||
* Otherwise, parse the beacon for information about the device.
|
||||
*/
|
||||
public boolean waitForBeacon() throws IOException {
|
||||
byte[] bytes = new byte[600];
|
||||
boolean beaconFound;
|
||||
|
||||
// Wait for a device to announce itself
|
||||
logger.trace("Multicast listener waiting for datagram on multicast port");
|
||||
DatagramPacket msgPacket = new DatagramPacket(bytes, bytes.length);
|
||||
try {
|
||||
socket.receive(msgPacket);
|
||||
beaconFound = true;
|
||||
logger.trace("Multicast listener got datagram of length {} from multicast port: {}", msgPacket.getLength(),
|
||||
msgPacket.toString());
|
||||
|
||||
} catch (SocketTimeoutException e) {
|
||||
beaconFound = false;
|
||||
}
|
||||
|
||||
if (beaconFound) {
|
||||
// Get the device properties from the announcement beacon
|
||||
parseAnnouncementBeacon(msgPacket);
|
||||
}
|
||||
|
||||
return beaconFound;
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse the announcement beacon into the elements needed to create the thing.
|
||||
*
|
||||
* Example iTach beacon:
|
||||
*
|
||||
* AMXB<-UUID=GlobalCache_000C1E021777><-SDKClass=Utility><-Make=GlobalCache><-Model=iTachWF2IR>
|
||||
* <-Revision=710-1001-05><-Pkg_Level=GCPK002><-Config-URL=http://192.168.1.90><-PCB_PN=025-0026-06>
|
||||
* <-Status=Ready>CR
|
||||
*
|
||||
* Example GC-100 beacon:
|
||||
*
|
||||
* AMXB<-UUID=GC100_000C1E00F0E9_GlobalCache><-SDKClass=Utility><-Make=GlobalCache><-Model=GC-100-06>
|
||||
* <-Revision=1.0.0><Config-Name=GC-100><Config-URL=http://192.168.1.70>CR
|
||||
*
|
||||
*/
|
||||
private void parseAnnouncementBeacon(DatagramPacket packet) {
|
||||
String beacon = (new String(packet.getData())).trim();
|
||||
|
||||
logger.trace("Multicast listener parsing announcement packet: {}", beacon);
|
||||
|
||||
clearProperties();
|
||||
|
||||
if (beacon.contains(GC_MODEL_ITACH)) {
|
||||
parseItachAnnouncementBeacon(beacon);
|
||||
} else if (beacon.contains(GC_MODEL_GC_100)) {
|
||||
parseGC100AnnouncementBeacon(beacon);
|
||||
} else if (beacon.contains(GC_MODEL_ZMOTE)) {
|
||||
parseZmoteAnnouncementBeacon(beacon);
|
||||
} else {
|
||||
logger.debug("Multicast listener doesn't know how to parse beacon: {}", beacon);
|
||||
}
|
||||
}
|
||||
|
||||
private void parseItachAnnouncementBeacon(String beacon) {
|
||||
String[] parameterList = beacon.split("<-");
|
||||
|
||||
for (String parameter : parameterList) {
|
||||
String[] keyValue = parameter.split("=");
|
||||
|
||||
if (keyValue.length != 2) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (keyValue[0].contains("UUID")) {
|
||||
uid = keyValue[1].substring(0, keyValue[1].length() - 1);
|
||||
macAddress = uid.substring(uid.indexOf("_") + 1);
|
||||
serialNumber = macAddress;
|
||||
} else if (keyValue[0].contains("Make")) {
|
||||
vendor = keyValue[1].substring(0, keyValue[1].length() - 1);
|
||||
} else if (keyValue[0].contains("Model")) {
|
||||
model = keyValue[1].substring(0, keyValue[1].length() - 1);
|
||||
} else if (keyValue[0].contains("Revision")) {
|
||||
softwareRevision = keyValue[1].substring(0, keyValue[1].length() - 1);
|
||||
} else if (keyValue[0].contains("Config-URL")) {
|
||||
ipAddress = keyValue[1].substring(keyValue[1].indexOf("://") + 3, keyValue[1].length() - 1);
|
||||
} else if (keyValue[0].contains("PCB_PN")) {
|
||||
hardwareRevision = keyValue[1].substring(0, keyValue[1].length() - 1);
|
||||
}
|
||||
}
|
||||
lastUpdate = new Date();
|
||||
}
|
||||
|
||||
/*
|
||||
* AMXB<-UUID=GC100_000C1E00F0E9_GlobalCache><-SDKClass=Utility><-Make=GlobalCache><-Model=GC-100-06>
|
||||
* <-Revision=1.0.0><Config-Name=GC-100><Config-URL=http://192.168.1.70>CR
|
||||
*/
|
||||
private void parseGC100AnnouncementBeacon(String beacon) {
|
||||
String[] parameterList = beacon.split("<");
|
||||
|
||||
for (String parameter : parameterList) {
|
||||
String[] keyValue = parameter.split("=");
|
||||
|
||||
if (keyValue.length != 2) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (keyValue[0].contains("UUID")) {
|
||||
uid = keyValue[1].substring(0, keyValue[1].length() - 1);
|
||||
macAddress = uid.subSequence(6, 18).toString();
|
||||
serialNumber = macAddress;
|
||||
} else if (keyValue[0].contains("Make")) {
|
||||
vendor = keyValue[1].substring(0, keyValue[1].length() - 1);
|
||||
} else if (keyValue[0].contains("Model")) {
|
||||
model = keyValue[1].substring(0, keyValue[1].length() - 1);
|
||||
} else if (keyValue[0].contains("Revision")) {
|
||||
softwareRevision = keyValue[1].substring(0, keyValue[1].length() - 1);
|
||||
} else if (keyValue[0].contains("Config-URL")) {
|
||||
ipAddress = keyValue[1].substring(keyValue[1].indexOf("://") + 3, keyValue[1].length() - 1);
|
||||
}
|
||||
}
|
||||
hardwareRevision = "N/A";
|
||||
lastUpdate = new Date(System.currentTimeMillis());
|
||||
}
|
||||
|
||||
/*
|
||||
* AMXB<-UUID=CI00a1b2c3><-Type=ZMT2><-Make=zmote.io><-Model=ZV-2><-Revision=2.1.4><-Config-URL=http://192.168.1.12>
|
||||
*/
|
||||
private void parseZmoteAnnouncementBeacon(String beacon) {
|
||||
String[] parameterList = beacon.split("<-");
|
||||
|
||||
for (String parameter : parameterList) {
|
||||
String[] keyValue = parameter.split("=");
|
||||
if (keyValue.length != 2) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (keyValue[0].contains("UUID")) {
|
||||
uid = keyValue[1].substring(0, keyValue[1].length() - 1);
|
||||
serialNumber = uid;
|
||||
} else if (keyValue[0].contains("Make")) {
|
||||
vendor = keyValue[1].substring(0, keyValue[1].length() - 1);
|
||||
} else if (keyValue[0].contains("Model")) {
|
||||
model = keyValue[1].substring(0, keyValue[1].length() - 1);
|
||||
} else if (keyValue[0].contains("Revision")) {
|
||||
softwareRevision = keyValue[1].substring(0, keyValue[1].length() - 1);
|
||||
} else if (keyValue[0].contains("Config-URL")) {
|
||||
ipAddress = keyValue[1].substring(keyValue[1].indexOf("://") + 3, keyValue[1].length() - 1);
|
||||
}
|
||||
}
|
||||
|
||||
hardwareRevision = "N/A";
|
||||
lastUpdate = new Date(System.currentTimeMillis());
|
||||
}
|
||||
|
||||
private void clearProperties() {
|
||||
serialNumber = "";
|
||||
vendor = "";
|
||||
model = "";
|
||||
softwareRevision = "";
|
||||
hardwareRevision = "";
|
||||
uid = "";
|
||||
ipAddress = "";
|
||||
macAddress = "";
|
||||
}
|
||||
|
||||
public String getSerialNumber() {
|
||||
return serialNumber;
|
||||
}
|
||||
|
||||
public String getVendor() {
|
||||
return vendor;
|
||||
}
|
||||
|
||||
public String getModel() {
|
||||
return model;
|
||||
}
|
||||
|
||||
public String getSoftwareRevision() {
|
||||
return softwareRevision;
|
||||
}
|
||||
|
||||
public String getHardwareRevision() {
|
||||
return hardwareRevision;
|
||||
}
|
||||
|
||||
public String getUID() {
|
||||
return uid;
|
||||
}
|
||||
|
||||
public String getIPAddress() {
|
||||
return ipAddress;
|
||||
}
|
||||
|
||||
public String getMACAddress() {
|
||||
return macAddress;
|
||||
}
|
||||
|
||||
public Date getLastUpdate() {
|
||||
return lastUpdate;
|
||||
}
|
||||
|
||||
public boolean isITach() {
|
||||
return model.contains(GC_MODEL_ITACH);
|
||||
}
|
||||
|
||||
public boolean isGC100() {
|
||||
return model.contains(GC_MODEL_GC_100);
|
||||
}
|
||||
|
||||
public ThingTypeUID getThingTypeUID() {
|
||||
logger.trace("Multicast listener looking up thing type for model {} at IP {}", model, ipAddress);
|
||||
|
||||
switch (model) {
|
||||
case GC_MODEL_ITACHIP2IR:
|
||||
case GC_MODEL_ITACHWF2IR:
|
||||
return THING_TYPE_ITACH_IR;
|
||||
|
||||
case GC_MODEL_ITACHIP2CC:
|
||||
case GC_MODEL_ITACHWF2CC:
|
||||
return THING_TYPE_ITACH_CC;
|
||||
|
||||
case GC_MODEL_ITACHIP2SL:
|
||||
case GC_MODEL_ITACHWF2SL:
|
||||
return THING_TYPE_ITACH_SL;
|
||||
|
||||
case GC_MODEL_ITACHFLEXETH:
|
||||
case GC_MODEL_ITACHFLEXETHPOE:
|
||||
case GC_MODEL_ITACHFLEXWIFI:
|
||||
return THING_TYPE_ITACH_FLEX;
|
||||
|
||||
case GC_MODEL_GC_100_06:
|
||||
return THING_TYPE_GC_100_06;
|
||||
|
||||
case GC_MODEL_GC_100_12:
|
||||
return THING_TYPE_GC_100_12;
|
||||
|
||||
case GC_MODEL_ZMOTE:
|
||||
return THING_TYPE_ZMOTE;
|
||||
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<binding:binding id="globalcache" 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>GlobalCache Binding</name>
|
||||
<description>Binding for GlobalCache iTach and GC-100 devices supporting infrared, serial, and contact closure
|
||||
interfaces.</description>
|
||||
<author>Mark Hilbush</author>
|
||||
|
||||
</binding:binding>
|
||||
@@ -0,0 +1,40 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<thing:thing-descriptions bindingId="globalcache"
|
||||
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">
|
||||
|
||||
<!-- GlobalCache Channel Types -->
|
||||
|
||||
<channel-type id="channel-type-ir">
|
||||
<item-type>String</item-type>
|
||||
<label>Infrared</label>
|
||||
<description>Transmits infrared command on module:connector</description>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="channel-type-cc">
|
||||
<item-type>Switch</item-type>
|
||||
<label>Contact Closure</label>
|
||||
<description>Transmits contact closure command on module:connector</description>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="channel-type-sl">
|
||||
<item-type>String</item-type>
|
||||
<label>Serial</label>
|
||||
<description>Transmits serial command on module:connector</description>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="channel-type-sl-direct" advanced="false">
|
||||
<item-type>String</item-type>
|
||||
<label>Serial</label>
|
||||
<description>Transmits serial command on module:connector bypassing MAP transform</description>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="channel-type-sl-receive" advanced="true">
|
||||
<item-type>String</item-type>
|
||||
<label>Serial Receive</label>
|
||||
<description>Data received on the serial port from the device</description>
|
||||
<state readOnly="true"></state>
|
||||
</channel-type>
|
||||
|
||||
</thing:thing-descriptions>
|
||||
@@ -0,0 +1,287 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<thing:thing-descriptions bindingId="globalcache"
|
||||
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">
|
||||
|
||||
<!-- GlobalCache Channel Groups -->
|
||||
|
||||
<channel-group-type id="sl-m1">
|
||||
<label>Module 1</label>
|
||||
<description>Serial Module</description>
|
||||
<channels>
|
||||
<channel id="c1" typeId="channel-type-sl">
|
||||
<label>Connector 1 (mapped)</label>
|
||||
<description>Mapped commands to serial port</description>
|
||||
<properties>
|
||||
<property name="module">1</property>
|
||||
<property name="connector">1</property>
|
||||
</properties>
|
||||
</channel>
|
||||
|
||||
<channel id="c1-direct" typeId="channel-type-sl-direct">
|
||||
<label>Connector 1 (direct)</label>
|
||||
<description>Direct commands to serial port</description>
|
||||
<properties>
|
||||
<property name="module">1</property>
|
||||
<property name="connector">1</property>
|
||||
</properties>
|
||||
</channel>
|
||||
|
||||
<channel id="c1-receive" typeId="channel-type-sl-receive">
|
||||
<label>Connector 1 (receive)</label>
|
||||
<description>Data received on serial port</description>
|
||||
<properties>
|
||||
<property name="module">1</property>
|
||||
<property name="connector">1</property>
|
||||
</properties>
|
||||
</channel>
|
||||
</channels>
|
||||
</channel-group-type>
|
||||
|
||||
<channel-group-type id="sl-m2">
|
||||
<label>Module 2</label>
|
||||
<description>Serial Module</description>
|
||||
<channels>
|
||||
<channel id="c1" typeId="channel-type-sl">
|
||||
<label>Connector 1 (mapped)</label>
|
||||
<description>Mapped commands to serial port</description>
|
||||
<properties>
|
||||
<property name="module">2</property>
|
||||
<property name="connector">1</property>
|
||||
</properties>
|
||||
</channel>
|
||||
|
||||
<channel id="c1-direct" typeId="channel-type-sl-direct">
|
||||
<label>Connector 1 (direct)</label>
|
||||
<description>Direct commands to serial port</description>
|
||||
<properties>
|
||||
<property name="module">2</property>
|
||||
<property name="connector">1</property>
|
||||
</properties>
|
||||
</channel>
|
||||
|
||||
<channel id="c1-receive" typeId="channel-type-sl-receive">
|
||||
<label>Connector 1 (receive)</label>
|
||||
<description>Data received on serial port</description>
|
||||
<properties>
|
||||
<property name="module">2</property>
|
||||
<property name="connector">1</property>
|
||||
</properties>
|
||||
</channel>
|
||||
</channels>
|
||||
</channel-group-type>
|
||||
|
||||
<channel-group-type id="ir-m1">
|
||||
<label>Module 1</label>
|
||||
<description>Infrared Module</description>
|
||||
<channels>
|
||||
<channel id="c1" typeId="channel-type-ir">
|
||||
<label>Connector 1</label>
|
||||
<description>Infrared emitter on connector 1. Connector 1 is the connector closest to the power plug.</description>
|
||||
<properties>
|
||||
<property name="module">1</property>
|
||||
<property name="connector">1</property>
|
||||
</properties>
|
||||
</channel>
|
||||
|
||||
<channel id="c2" typeId="channel-type-ir">
|
||||
<label>Connector 2</label>
|
||||
<description>Infrared emitter on connector 2.</description>
|
||||
<properties>
|
||||
<property name="module">1</property>
|
||||
<property name="connector">2</property>
|
||||
</properties>
|
||||
</channel>
|
||||
|
||||
<channel id="c3" typeId="channel-type-ir">
|
||||
<label>Connector 3</label>
|
||||
<description>Infrared emitter/blaster on connector 3.</description>
|
||||
<properties>
|
||||
<property name="module">1</property>
|
||||
<property name="connector">3</property>
|
||||
</properties>
|
||||
</channel>
|
||||
</channels>
|
||||
</channel-group-type>
|
||||
|
||||
<channel-group-type id="ir-m1-c1">
|
||||
<label>Module 1</label>
|
||||
<description>Infrared Module</description>
|
||||
<channels>
|
||||
<channel id="c1" typeId="channel-type-ir">
|
||||
<label>Connector 1</label>
|
||||
<description>ZMote infrared emitter.</description>
|
||||
<properties>
|
||||
<property name="module">1</property>
|
||||
<property name="connector">1</property>
|
||||
</properties>
|
||||
</channel>
|
||||
</channels>
|
||||
</channel-group-type>
|
||||
|
||||
<channel-group-type id="ir-m2">
|
||||
<label>Module 2</label>
|
||||
<description>Infrared Module</description>
|
||||
<channels>
|
||||
<channel id="c1" typeId="channel-type-ir">
|
||||
<label>Connector 1</label>
|
||||
<description>Infrared emitter on connector 1. Connector 1 is the connector closest to the power plug.</description>
|
||||
<properties>
|
||||
<property name="module">2</property>
|
||||
<property name="connector">1</property>
|
||||
</properties>
|
||||
</channel>
|
||||
|
||||
<channel id="c2" typeId="channel-type-ir">
|
||||
<label>Connector 2</label>
|
||||
<description>Infrared emitter on connector 2.</description>
|
||||
<properties>
|
||||
<property name="module">2</property>
|
||||
<property name="connector">2</property>
|
||||
</properties>
|
||||
</channel>
|
||||
|
||||
<channel id="c3" typeId="channel-type-ir">
|
||||
<label>Connector 3</label>
|
||||
<description>Infrared emitter/blaster on connector 3.</description>
|
||||
<properties>
|
||||
<property name="module">2</property>
|
||||
<property name="connector">3</property>
|
||||
</properties>
|
||||
</channel>
|
||||
</channels>
|
||||
</channel-group-type>
|
||||
|
||||
<channel-group-type id="ir-m4">
|
||||
<label>Module 4</label>
|
||||
<description>Infrared Module</description>
|
||||
<channels>
|
||||
<channel id="c1" typeId="channel-type-ir">
|
||||
<label>Connector 1</label>
|
||||
<description>Infrared emitter on connector 1. Connector 1 is the connector closest to the power plug.</description>
|
||||
<properties>
|
||||
<property name="module">4</property>
|
||||
<property name="connector">1</property>
|
||||
</properties>
|
||||
</channel>
|
||||
|
||||
<channel id="c2" typeId="channel-type-ir">
|
||||
<label>Connector 2</label>
|
||||
<description>Infrared emitter on connector 2.</description>
|
||||
<properties>
|
||||
<property name="module">4</property>
|
||||
<property name="connector">2</property>
|
||||
</properties>
|
||||
</channel>
|
||||
|
||||
<channel id="c3" typeId="channel-type-ir">
|
||||
<label>Connector 3</label>
|
||||
<description>Infrared emitter/blaster on connector 3.</description>
|
||||
<properties>
|
||||
<property name="module">4</property>
|
||||
<property name="connector">3</property>
|
||||
</properties>
|
||||
</channel>
|
||||
</channels>
|
||||
</channel-group-type>
|
||||
|
||||
<channel-group-type id="ir-m5">
|
||||
<label>Module 5</label>
|
||||
<description>Infrared Module</description>
|
||||
<channels>
|
||||
<channel id="c1" typeId="channel-type-ir">
|
||||
<label>Connector 1</label>
|
||||
<description>Infrared emitter on connector 1. Connector 1 is the connector closest to the power plug.</description>
|
||||
<properties>
|
||||
<property name="module">5</property>
|
||||
<property name="connector">1</property>
|
||||
</properties>
|
||||
</channel>
|
||||
|
||||
<channel id="c2" typeId="channel-type-ir">
|
||||
<label>Connector 2</label>
|
||||
<description>Infrared emitter on connector 2.</description>
|
||||
<properties>
|
||||
<property name="module">5</property>
|
||||
<property name="connector">2</property>
|
||||
</properties>
|
||||
</channel>
|
||||
|
||||
<channel id="c3" typeId="channel-type-ir">
|
||||
<label>Connector 3</label>
|
||||
<description>Infrared emitter/blaster on connector 3.</description>
|
||||
<properties>
|
||||
<property name="module">5</property>
|
||||
<property name="connector">3</property>
|
||||
</properties>
|
||||
</channel>
|
||||
</channels>
|
||||
</channel-group-type>
|
||||
|
||||
<channel-group-type id="cc-m1">
|
||||
<label>Module 1</label>
|
||||
<description>Contact Closure Module</description>
|
||||
<channels>
|
||||
<channel id="c1" typeId="channel-type-cc">
|
||||
<label>Connector 1</label>
|
||||
<description>Contact closure on connector 1.</description>
|
||||
<properties>
|
||||
<property name="module">1</property>
|
||||
<property name="connector">1</property>
|
||||
</properties>
|
||||
</channel>
|
||||
|
||||
<channel id="c2" typeId="channel-type-cc">
|
||||
<label>Connector 2</label>
|
||||
<description>Contact closure on connector 2.</description>
|
||||
<properties>
|
||||
<property name="module">1</property>
|
||||
<property name="connector">2</property>
|
||||
</properties>
|
||||
</channel>
|
||||
|
||||
<channel id="c3" typeId="channel-type-cc">
|
||||
<label>Connector 3</label>
|
||||
<description>Contact closure on connector 3.</description>
|
||||
<properties>
|
||||
<property name="module">1</property>
|
||||
<property name="connector">3</property>
|
||||
</properties>
|
||||
</channel>
|
||||
</channels>
|
||||
</channel-group-type>
|
||||
|
||||
<channel-group-type id="cc-m3">
|
||||
<label>Module 3</label>
|
||||
<description>Contact Closure Module</description>
|
||||
<channels>
|
||||
<channel id="c1" typeId="channel-type-cc">
|
||||
<label>Connector 1</label>
|
||||
<description>Contact closure on connector 1.</description>
|
||||
<properties>
|
||||
<property name="module">3</property>
|
||||
<property name="connector">1</property>
|
||||
</properties>
|
||||
</channel>
|
||||
|
||||
<channel id="c2" typeId="channel-type-cc">
|
||||
<label>Connector 2</label>
|
||||
<description>Contact closure on connector 2.</description>
|
||||
<properties>
|
||||
<property name="module">3</property>
|
||||
<property name="connector">2</property>
|
||||
</properties>
|
||||
</channel>
|
||||
|
||||
<channel id="c3" typeId="channel-type-cc">
|
||||
<label>Connector 3</label>
|
||||
<description>Contact closure on connector 3.</description>
|
||||
<properties>
|
||||
<property name="module">3</property>
|
||||
<property name="connector">3</property>
|
||||
</properties>
|
||||
</channel>
|
||||
</channels>
|
||||
</channel-group-type>
|
||||
</thing:thing-descriptions>
|
||||
@@ -0,0 +1,44 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<thing:thing-descriptions bindingId="globalcache"
|
||||
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">
|
||||
|
||||
<!-- GlobalCache GC-100-06 device contains one SL module, one IR module -->
|
||||
<thing-type id="gc100_06">
|
||||
|
||||
<label>GlobalCache GC-100-06</label>
|
||||
<description>GC-100-06 Infrared and Serial Device</description>
|
||||
|
||||
<channel-groups>
|
||||
<channel-group id="sl-m1" typeId="sl-m1"/>
|
||||
<channel-group id="ir-m2" typeId="ir-m2"/>
|
||||
</channel-groups>
|
||||
|
||||
<config-description>
|
||||
<parameter name="ipAddress" type="text" required="true">
|
||||
<label>Network Address</label>
|
||||
<description>Enter the IP address of the iTach CC device</description>
|
||||
<context>network-address</context>
|
||||
</parameter>
|
||||
|
||||
<parameter name="mapFilename" type="text">
|
||||
<label>Map File</label>
|
||||
<description>Enter name of file containing mapping of commands to IR and Serial codes</description>
|
||||
</parameter>
|
||||
|
||||
<parameter name="enableTwoWay1" type="boolean">
|
||||
<label>Enable Two Way</label>
|
||||
<description>Enable two-way serial communication</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
|
||||
<parameter name="eomDelimiter1" type="text">
|
||||
<label>End-of-message Delimiter</label>
|
||||
<description>URL encoded end-of-message delimiter string for receiving messages</description>
|
||||
<default>%0A</default>
|
||||
</parameter>
|
||||
</config-description>
|
||||
|
||||
</thing-type>
|
||||
</thing:thing-descriptions>
|
||||
@@ -0,0 +1,59 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<thing:thing-descriptions bindingId="globalcache"
|
||||
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">
|
||||
|
||||
<!-- GlobalCache GC-100-12 device contains two IR modules, two SL modules, one CC module -->
|
||||
<thing-type id="gc100_12">
|
||||
|
||||
<label>GlobalCache GC-100-12</label>
|
||||
<description>GC-100-12 Infrared, Serial, and Contact Closure Device</description>
|
||||
|
||||
<channel-groups>
|
||||
<channel-group id="sl-m1" typeId="sl-m1"/>
|
||||
<channel-group id="sl-m2" typeId="sl-m2"/>
|
||||
<channel-group id="cc-m3" typeId="cc-m3"/>
|
||||
<channel-group id="ir-m4" typeId="ir-m4"/>
|
||||
<channel-group id="ir-m5" typeId="ir-m5"/>
|
||||
</channel-groups>
|
||||
|
||||
<config-description>
|
||||
<parameter name="ipAddress" type="text" required="true">
|
||||
<label>Network Address</label>
|
||||
<description>Enter the IP address of the iTach CC device</description>
|
||||
<context>network-address</context>
|
||||
</parameter>
|
||||
|
||||
<parameter name="mapFilename" type="text">
|
||||
<label>Map File</label>
|
||||
<description>Enter name of file containing mapping of commands to IR and Serial codes</description>
|
||||
</parameter>
|
||||
|
||||
<parameter name="enableTwoWay1" type="boolean">
|
||||
<label>Enable Two Way Port 1</label>
|
||||
<description>Enable two-way serial communication on serial port 1</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
|
||||
<parameter name="eomDelimiter1" type="text">
|
||||
<label>End-of-message Delimiter Port 1</label>
|
||||
<description>URL encoded end-of-message delimiter string for receiving messages on serial port 1</description>
|
||||
<default>%0A</default>
|
||||
</parameter>
|
||||
|
||||
<parameter name="enableTwoWay2" type="boolean">
|
||||
<label>Enable Two Way Port 2</label>
|
||||
<description>Enable two-way serial communication on serial port 2</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
|
||||
<parameter name="eomDelimiter2" type="text">
|
||||
<label>End-of-message Delimiter Port 2</label>
|
||||
<description>URL encoded end-of-message delimiter string for receiving messages on serial port 2</description>
|
||||
<default>%0A</default>
|
||||
</parameter>
|
||||
</config-description>
|
||||
|
||||
</thing-type>
|
||||
</thing:thing-descriptions>
|
||||
@@ -0,0 +1,27 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<thing:thing-descriptions bindingId="globalcache"
|
||||
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">
|
||||
|
||||
<!-- GlobalCache iTach CC (relay) device contains one CC module -->
|
||||
<thing-type id="itachCC">
|
||||
|
||||
<label>GlobalCache iTach CC</label>
|
||||
<description>iTach Contact Closure Device (WF2CC or IP2CC)</description>
|
||||
|
||||
<channel-groups>
|
||||
<channel-group id="cc-m1" typeId="cc-m1"/>
|
||||
</channel-groups>
|
||||
|
||||
<config-description>
|
||||
<parameter name="ipAddress" type="text" required="true">
|
||||
<label>Network Address</label>
|
||||
<description>Enter the IP address of the iTach CC device</description>
|
||||
<context>network-address</context>
|
||||
</parameter>
|
||||
</config-description>
|
||||
|
||||
</thing-type>
|
||||
|
||||
</thing:thing-descriptions>
|
||||
@@ -0,0 +1,57 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<thing:thing-descriptions bindingId="globalcache"
|
||||
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">
|
||||
|
||||
<!-- GlobalCache iTach Flex device -->
|
||||
<thing-type id="itachFlex">
|
||||
|
||||
<label>GlobalCache iTach Flex</label>
|
||||
<description>iTach Flex Device</description>
|
||||
|
||||
<channel-groups>
|
||||
<channel-group id="sl-m1" typeId="sl-m1"/>
|
||||
<channel-group id="ir-m1" typeId="ir-m1"/>
|
||||
<channel-group id="cc-m1" typeId="cc-m1"/>
|
||||
</channel-groups>
|
||||
|
||||
<config-description>
|
||||
<parameter name="ipAddress" type="text" required="true">
|
||||
<label>Network Address</label>
|
||||
<description>Enter the IP address of the iTach Flex device</description>
|
||||
<context>network-address</context>
|
||||
</parameter>
|
||||
|
||||
<parameter name="mapFilename" type="text">
|
||||
<label>Map File</label>
|
||||
<description>Enter name of file containing mapping of commands to IR and Serial codes</description>
|
||||
</parameter>
|
||||
|
||||
<parameter name="activeCable" type="text" required="true">
|
||||
<label>Active Cable</label>
|
||||
<description>This setting should match the Current Active Cable in the Flex configuration</description>
|
||||
<options>
|
||||
<option value="FLEX_INFRARED">Infrared</option>
|
||||
<option value="FLEX_SERIAL">Serial</option>
|
||||
<option value="FLEX_RELAY">Relay/Sensor</option>
|
||||
</options>
|
||||
<default>FLEX_INFRARED</default>
|
||||
</parameter>
|
||||
|
||||
<parameter name="enableTwoWay1" type="boolean">
|
||||
<label>Enable Two Way</label>
|
||||
<description>Enable two-way serial communication</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
|
||||
<parameter name="eomDelimiter1" type="text">
|
||||
<label>End-of-message Delimiter</label>
|
||||
<description>URL encoded end-of-message delimiter string for receiving messages</description>
|
||||
<default>%0A</default>
|
||||
</parameter>
|
||||
</config-description>
|
||||
|
||||
</thing-type>
|
||||
|
||||
</thing:thing-descriptions>
|
||||
@@ -0,0 +1,32 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<thing:thing-descriptions bindingId="globalcache"
|
||||
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">
|
||||
|
||||
<!-- GlobalCache iTach IR (infrared) device contains one IR module -->
|
||||
<thing-type id="itachIR">
|
||||
|
||||
<label>GlobalCache iTach IR</label>
|
||||
<description>iTach Infrared Device (WF2IR or IP2IR)</description>
|
||||
|
||||
<channel-groups>
|
||||
<channel-group id="ir-m1" typeId="ir-m1"/>
|
||||
</channel-groups>
|
||||
|
||||
<config-description>
|
||||
<parameter name="ipAddress" type="text" required="true">
|
||||
<label>Network Address</label>
|
||||
<description>Enter the IP address of the iTach IR device</description>
|
||||
<context>network-address</context>
|
||||
</parameter>
|
||||
|
||||
<parameter name="mapFilename" type="text">
|
||||
<label>Map File</label>
|
||||
<description>Enter name of file containing mapping of commands to IR and Serial codes</description>
|
||||
</parameter>
|
||||
</config-description>
|
||||
|
||||
</thing-type>
|
||||
|
||||
</thing:thing-descriptions>
|
||||
@@ -0,0 +1,43 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<thing:thing-descriptions bindingId="globalcache"
|
||||
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">
|
||||
|
||||
<!-- GlobalCache iTach SL (serial) device contains one SL module -->
|
||||
<thing-type id="itachSL">
|
||||
|
||||
<label>GlobalCache iTach SL</label>
|
||||
<description>iTach Serial Device (WF2SL or IP2SL)</description>
|
||||
|
||||
<channel-groups>
|
||||
<channel-group id="sl-m1" typeId="sl-m1"/>
|
||||
</channel-groups>
|
||||
|
||||
<config-description>
|
||||
<parameter name="ipAddress" type="text" required="true">
|
||||
<label>Network Address</label>
|
||||
<description>Enter the IP address of the iTach SL device</description>
|
||||
<context>network-address</context>
|
||||
</parameter>
|
||||
|
||||
<parameter name="mapFilename" type="text">
|
||||
<label>Map File</label>
|
||||
<description>Enter namer of file containing mapping of commands to IR and Serial codes</description>
|
||||
</parameter>
|
||||
|
||||
<parameter name="enableTwoWay1" type="boolean">
|
||||
<label>Enable Two Way</label>
|
||||
<description>Enable two-way serial communication</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
|
||||
<parameter name="eomDelimiter1" type="text">
|
||||
<label>End-of-message Delimiter</label>
|
||||
<description>URL encoded end-of-message delimiter string for receiving messages</description>
|
||||
<default>%0A</default>
|
||||
</parameter>
|
||||
</config-description>
|
||||
|
||||
</thing-type>
|
||||
</thing:thing-descriptions>
|
||||
@@ -0,0 +1,32 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<thing:thing-descriptions bindingId="globalcache"
|
||||
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">
|
||||
|
||||
<!-- Zmote IR (infrared) device contains one IR module -->
|
||||
<thing-type id="zmote">
|
||||
|
||||
<label>Zmote IR</label>
|
||||
<description>Zmote Infrared Device</description>
|
||||
|
||||
<channel-groups>
|
||||
<channel-group id="ir-m1-c1" typeId="ir-m1-c1"/>
|
||||
</channel-groups>
|
||||
|
||||
<config-description>
|
||||
<parameter name="ipAddress" type="text" required="true">
|
||||
<label>Network Address</label>
|
||||
<description>Enter the IP address of the Zmote device</description>
|
||||
<context>network-address</context>
|
||||
</parameter>
|
||||
|
||||
<parameter name="mapFilename" type="text">
|
||||
<label>Map File</label>
|
||||
<description>Enter name of file containing mapping of commands to IR codes</description>
|
||||
</parameter>
|
||||
</config-description>
|
||||
|
||||
</thing-type>
|
||||
|
||||
</thing:thing-descriptions>
|
||||
Reference in New Issue
Block a user