added migrated 2.x add-ons
Signed-off-by: Kai Kreuzer <kai@openhab.org>
This commit is contained in:
32
bundles/org.openhab.binding.hdanywhere/.classpath
Normal file
32
bundles/org.openhab.binding.hdanywhere/.classpath
Normal file
@@ -0,0 +1,32 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" output="target/classes" path="src/main/java">
|
||||
<attributes>
|
||||
<attribute name="optional" value="true"/>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="src" output="target/test-classes" path="src/test/java">
|
||||
<attributes>
|
||||
<attribute name="optional" value="true"/>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
<attribute name="test" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="output" path="target/classes"/>
|
||||
</classpath>
|
||||
23
bundles/org.openhab.binding.hdanywhere/.project
Normal file
23
bundles/org.openhab.binding.hdanywhere/.project
Normal file
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>org.openhab.binding.hdanywhere</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.m2e.core.maven2Builder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
<nature>org.eclipse.m2e.core.maven2Nature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
13
bundles/org.openhab.binding.hdanywhere/NOTICE
Normal file
13
bundles/org.openhab.binding.hdanywhere/NOTICE
Normal file
@@ -0,0 +1,13 @@
|
||||
This content is produced and maintained by the openHAB project.
|
||||
|
||||
* Project home: https://www.openhab.org
|
||||
|
||||
== Declared Project Licenses
|
||||
|
||||
This program and the accompanying materials are made available under the terms
|
||||
of the Eclipse Public License 2.0 which is available at
|
||||
https://www.eclipse.org/legal/epl-2.0/.
|
||||
|
||||
== Source Code
|
||||
|
||||
https://github.com/openhab/openhab-addons
|
||||
65
bundles/org.openhab.binding.hdanywhere/README.md
Normal file
65
bundles/org.openhab.binding.hdanywhere/README.md
Normal file
@@ -0,0 +1,65 @@
|
||||
# HDanywhere Binding
|
||||
|
||||
This binding integrates with [HDanywhere](https://www.hdanywhere.co.uk) HDMI matrices.
|
||||
|
||||
HDanywhere is a manufacturer of multiroom/distributed audio/video equipment.
|
||||
This binding supports their V3 of the Multiroom+ HDMI matrix running firmware V1.2(20131222), as well as the newer MHUB series of matrices.
|
||||
These matrices support the highest HD resolutions, including 1080p 3D & 4K, use a single Cat5e/6/7 wiring structure with reliable performance up to 100m,
|
||||
have IR passback to allow you to select and control what you watch from every room and are fully compatible with universal remote controls
|
||||
|
||||
The matrices can be controlled by either UDP/IP and/or Serial connections,
|
||||
but due to the lack of feedback on the actual state of the HDMI matrix when using those methods, this binding operates by controlling the built-in webserver of the matrix.
|
||||
|
||||
## Supported Things
|
||||
|
||||
This binding currently supports the following thing types:
|
||||
|
||||
- *multiroomplus* : Multiroom+ V3 (**Note:** This product is no longer sold by HDanywhere)
|
||||
- *mhub4k431* : MHUB 4K (4X3+1)
|
||||
|
||||
## Discovery
|
||||
|
||||
The binding does not support a discovery feature.
|
||||
|
||||
## Binding Configuration
|
||||
|
||||
This binding does not require any special configuration.
|
||||
|
||||
## Thing Configuration
|
||||
|
||||
Each thing requires the IP address of the matrix, and the interval in between status updates that are fetched from the matrix.
|
||||
Additionally, the *multiroomplus* has an additional required parameter 'ports' to specify the number of physical ports (e.g. 4x4, 8x8,...) of the matrix.
|
||||
|
||||
```java
|
||||
Thing hdanywhere:mhub4k431:m1 [ipAddress="192.168.0.89",interval=15]
|
||||
Thing hdanywhere:multiroomplus:m2 [ipAddress="192.168.0.88", ports=4, interval=15]
|
||||
```
|
||||
|
||||
## Channels
|
||||
|
||||
The following channels are supported (actual number of channels is a function of the number of physical ports on the matrix):
|
||||
|
||||
| Thing Type | Item Type | Description |
|
||||
|------------|-----------|---------------------------------------------------------------------|
|
||||
| port1 | Number | The number of the input port that is connected to the output port 1 |
|
||||
| port2 | Number | The number of the input port that is connected to the output port 2 |
|
||||
| port3 | Number | The number of the input port that is connected to the output port 3 |
|
||||
| ... | Number | ... |
|
||||
| port8 | Number | The number of the input port that is connected to the output port 8 |
|
||||
|
||||
## Example
|
||||
|
||||
demo.Things:
|
||||
|
||||
```java
|
||||
hdanywhere:mhub4k431:m1 [ipAddress="192.168.0.89",interval=15]
|
||||
```
|
||||
|
||||
demo.items:
|
||||
|
||||
```java
|
||||
Number OutputPort1 "Output port 1 is currently connected to Source port [%d]" { channel="hdanywhere:mhub4k431:m1:port1" }
|
||||
Number OutputPort2 "Output port 2 is currently connected to Source port [%d]" { channel="hdanywhere:mhub4k431:m1:port2" }
|
||||
Number OutputPort3 "Output port 3 is currently connected to Source port [%d]" { channel="hdanywhere:mhub4k431:m1:port3" }
|
||||
Number OutputPort4 "Output port 4 is currently connected to Source port [%d]" { channel="hdanywhere:mhub4k431:m1:port4" }
|
||||
```
|
||||
17
bundles/org.openhab.binding.hdanywhere/pom.xml
Normal file
17
bundles/org.openhab.binding.hdanywhere/pom.xml
Normal file
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>org.openhab.addons.bundles</groupId>
|
||||
<artifactId>org.openhab.addons.reactor.bundles</artifactId>
|
||||
<version>3.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>org.openhab.binding.hdanywhere</artifactId>
|
||||
|
||||
<name>openHAB Add-ons :: Bundles :: HDanywhere Binding</name>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<features name="org.openhab.binding.hdanywhere-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.4.0">
|
||||
<repository>mvn:org.openhab.core.features.karaf/org.openhab.core.features.karaf.openhab-core/${ohc.version}/xml/features</repository>
|
||||
|
||||
<feature name="openhab-binding-hdanywhere" description="HDAnywhere Binding" version="${project.version}">
|
||||
<feature>openhab-runtime-base</feature>
|
||||
<bundle start-level="80">mvn:org.openhab.addons.bundles/org.openhab.binding.hdanywhere/${project.version}</bundle>
|
||||
</feature>
|
||||
</features>
|
||||
@@ -0,0 +1,85 @@
|
||||
/**
|
||||
* 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.hdanywhere.internal;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.core.thing.ThingTypeUID;
|
||||
|
||||
/**
|
||||
* The {@link HDanywhereBinding} class defines common constants, which are used
|
||||
* across the whole binding.
|
||||
*
|
||||
* @author Karel Goderis - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class HDanywhereBindingConstants {
|
||||
|
||||
public static final String BINDING_ID = "hdanywhere";
|
||||
|
||||
// List of all Thing Type UIDs
|
||||
public static final ThingTypeUID THING_TYPE_MULTIROOMPLUS = new ThingTypeUID(BINDING_ID, "multiroomplus");
|
||||
public static final ThingTypeUID THING_TYPE_MHUB4K431 = new ThingTypeUID(BINDING_ID, "mhub4k431");
|
||||
|
||||
// List of all Channel ids
|
||||
public enum Port {
|
||||
ONE(1, "port1"),
|
||||
TWO(2, "port2"),
|
||||
THREE(3, "port3"),
|
||||
FOUR(4, "port4"),
|
||||
FIVE(5, "port5"),
|
||||
SIX(6, "port6"),
|
||||
SEVEN(7, "port7"),
|
||||
EIGHT(8, "port8");
|
||||
|
||||
private final int number;
|
||||
private final String id;
|
||||
|
||||
private Port(final int number, final String id) {
|
||||
this.number = number;
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.valueOf(number);
|
||||
}
|
||||
|
||||
public int toNumber() {
|
||||
return number;
|
||||
}
|
||||
|
||||
public static Port get(int valueSelectorNumber) throws IllegalArgumentException {
|
||||
for (Port c : Port.values()) {
|
||||
if (c.number == valueSelectorNumber) {
|
||||
return c;
|
||||
}
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("Not valid value selector");
|
||||
}
|
||||
|
||||
public static Port get(String valueSelectorText) throws IllegalArgumentException {
|
||||
for (Port c : Port.values()) {
|
||||
if (c.id.equals(valueSelectorText)) {
|
||||
return c;
|
||||
}
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("Not valid value selector");
|
||||
}
|
||||
|
||||
public String channelID() {
|
||||
return this.id;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
/**
|
||||
* 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.hdanywhere.internal;
|
||||
|
||||
import static org.openhab.binding.hdanywhere.internal.HDanywhereBindingConstants.*;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.openhab.binding.hdanywhere.internal.handler.Mhub4K431Handler;
|
||||
import org.openhab.binding.hdanywhere.internal.handler.MultiroomPlusHandler;
|
||||
import org.openhab.core.config.core.Configuration;
|
||||
import org.openhab.core.thing.Thing;
|
||||
import org.openhab.core.thing.ThingTypeUID;
|
||||
import org.openhab.core.thing.ThingUID;
|
||||
import org.openhab.core.thing.binding.BaseThingHandlerFactory;
|
||||
import org.openhab.core.thing.binding.ThingHandler;
|
||||
import org.openhab.core.thing.binding.ThingHandlerFactory;
|
||||
import org.osgi.service.component.annotations.Component;
|
||||
|
||||
/**
|
||||
* The {@link HDanywhereHandlerFactory} is responsible for creating things and
|
||||
* thing handlers.
|
||||
*
|
||||
* @author Karel Goderis - Initial contribution
|
||||
*/
|
||||
@Component(service = ThingHandlerFactory.class, configurationPid = "binding.hdanywhere")
|
||||
public class HDanywhereHandlerFactory extends BaseThingHandlerFactory {
|
||||
|
||||
private static final Set<ThingTypeUID> SUPPORTED_THING_TYPES_UIDS = Collections
|
||||
.unmodifiableSet(Stream.of(THING_TYPE_MULTIROOMPLUS, THING_TYPE_MHUB4K431).collect(Collectors.toSet()));
|
||||
|
||||
@Override
|
||||
public boolean supportsThingType(ThingTypeUID thingTypeUID) {
|
||||
return SUPPORTED_THING_TYPES_UIDS.contains(thingTypeUID);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ThingHandler createHandler(Thing thing) {
|
||||
ThingTypeUID thingTypeUID = thing.getThingTypeUID();
|
||||
|
||||
if (thingTypeUID.equals(THING_TYPE_MULTIROOMPLUS)) {
|
||||
return new MultiroomPlusHandler(thing);
|
||||
}
|
||||
|
||||
if (thingTypeUID.equals(THING_TYPE_MHUB4K431)) {
|
||||
return new Mhub4K431Handler(thing);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Thing createThing(ThingTypeUID thingTypeUID, Configuration configuration, ThingUID thingUID,
|
||||
ThingUID bridgeUID) {
|
||||
if (HDanywhereBindingConstants.THING_TYPE_MULTIROOMPLUS.equals(thingTypeUID)) {
|
||||
ThingUID matrixUID = getMultiroomPlusUID(thingTypeUID, thingUID, configuration);
|
||||
return super.createThing(thingTypeUID, configuration, matrixUID, null);
|
||||
}
|
||||
if (HDanywhereBindingConstants.THING_TYPE_MHUB4K431.equals(thingTypeUID)) {
|
||||
ThingUID matrixUID = getMhub4K431UID(thingTypeUID, thingUID, configuration);
|
||||
return super.createThing(thingTypeUID, configuration, matrixUID, null);
|
||||
}
|
||||
throw new IllegalArgumentException(
|
||||
"The thing type " + thingTypeUID + " is not supported by the HDanywhere binding.");
|
||||
}
|
||||
|
||||
private ThingUID getMultiroomPlusUID(ThingTypeUID thingTypeUID, ThingUID thingUID, Configuration configuration) {
|
||||
String ipAddress = (String) configuration.get(MultiroomPlusHandler.IP_ADDRESS);
|
||||
|
||||
if (thingUID == null) {
|
||||
thingUID = new ThingUID(thingTypeUID, ipAddress.replaceAll("[^A-Za-z0-9_]", "_"));
|
||||
}
|
||||
return thingUID;
|
||||
}
|
||||
|
||||
private ThingUID getMhub4K431UID(ThingTypeUID thingTypeUID, ThingUID thingUID, Configuration configuration) {
|
||||
String ipAddress = (String) configuration.get(Mhub4K431Handler.IP_ADDRESS);
|
||||
|
||||
if (thingUID == null) {
|
||||
thingUID = new ThingUID(thingTypeUID, ipAddress.replaceAll("[^A-Za-z0-9_]", "_"));
|
||||
}
|
||||
return thingUID;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,167 @@
|
||||
/**
|
||||
* 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.hdanywhere.internal.handler;
|
||||
|
||||
import static org.apache.commons.lang.StringUtils.isNotBlank;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.math.BigDecimal;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.openhab.binding.hdanywhere.internal.HDanywhereBindingConstants.Port;
|
||||
import org.openhab.core.io.net.http.HttpUtil;
|
||||
import org.openhab.core.library.types.DecimalType;
|
||||
import org.openhab.core.thing.ChannelUID;
|
||||
import org.openhab.core.thing.Thing;
|
||||
import org.openhab.core.thing.ThingStatus;
|
||||
import org.openhab.core.thing.binding.BaseThingHandler;
|
||||
import org.openhab.core.types.Command;
|
||||
import org.openhab.core.types.RefreshType;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
|
||||
/**
|
||||
* The {@link Mhub4K431Handler} is responsible for handling commands, which are
|
||||
* sent to one of the channels. It supports the MHUB 4K (4×3+1) matrix
|
||||
*
|
||||
* @author Karel Goderis - Initial contribution
|
||||
*/
|
||||
public class Mhub4K431Handler extends BaseThingHandler {
|
||||
|
||||
// List of Configurations constants
|
||||
public static final String IP_ADDRESS = "ipAddress";
|
||||
// public static final String PORTS = "ports";
|
||||
public static final String POLLING_INTERVAL = "interval";
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(Mhub4K431Handler.class);
|
||||
|
||||
private ScheduledFuture<?> pollingJob;
|
||||
protected final Gson gson = new Gson();
|
||||
|
||||
private final int timeout = 5000;
|
||||
private final int numberOfPorts = 4;
|
||||
|
||||
public Mhub4K431Handler(Thing thing) {
|
||||
super(thing);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
logger.debug("Initializing HDanywhere MHUB 4K (4×3+1) matrix handler.");
|
||||
|
||||
if (pollingJob == null || pollingJob.isCancelled()) {
|
||||
int pollingInterval = ((BigDecimal) getConfig().get(POLLING_INTERVAL)).intValue();
|
||||
pollingJob = scheduler.scheduleWithFixedDelay(pollingRunnable, 1, pollingInterval, TimeUnit.SECONDS);
|
||||
}
|
||||
updateStatus(ThingStatus.UNKNOWN);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
logger.debug("Disposing HDanywhere matrix handler.");
|
||||
if (pollingJob != null && !pollingJob.isCancelled()) {
|
||||
pollingJob.cancel(true);
|
||||
pollingJob = null;
|
||||
}
|
||||
}
|
||||
|
||||
private Runnable pollingRunnable = () -> {
|
||||
try {
|
||||
String host = (String) getConfig().get(IP_ADDRESS);
|
||||
|
||||
String httpMethod = "POST";
|
||||
String url = "http://" + host + "/cgi-bin/MUH44TP_getsetparams.cgi";
|
||||
String content = "{tag:ptn}";
|
||||
InputStream stream = new ByteArrayInputStream(content.getBytes(StandardCharsets.UTF_8));
|
||||
|
||||
if (isNotBlank(httpMethod) && isNotBlank(url)) {
|
||||
String response = HttpUtil.executeUrl(httpMethod, url, null, stream, null, timeout);
|
||||
response = response.trim();
|
||||
response = response.substring(1, response.length() - 1);
|
||||
|
||||
if (response != null) {
|
||||
updateStatus(ThingStatus.ONLINE);
|
||||
|
||||
java.lang.reflect.Type type = new TypeToken<Map<String, String>>() {
|
||||
}.getType();
|
||||
Map<String, String> map = gson.fromJson(response, type);
|
||||
|
||||
String inputChannel = map.get("Inputchannel");
|
||||
|
||||
for (int i = 0; i < numberOfPorts; i++) {
|
||||
DecimalType decimalType = new DecimalType(String.valueOf(inputChannel.charAt(i)));
|
||||
updateState(new ChannelUID(getThing().getUID(), Port.get(i + 1).channelID()), decimalType);
|
||||
}
|
||||
} else {
|
||||
updateStatus(ThingStatus.OFFLINE);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.debug("An exception occurred while polling the HDanwywhere matrix: '{}'", e.getMessage());
|
||||
updateStatus(ThingStatus.OFFLINE);
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public void handleCommand(ChannelUID channelUID, Command command) {
|
||||
if (command instanceof RefreshType) {
|
||||
// Simply schedule a single run of the polling runnable to refresh all channels
|
||||
scheduler.schedule(pollingRunnable, 0, TimeUnit.SECONDS);
|
||||
} else {
|
||||
String channelID = channelUID.getId();
|
||||
|
||||
String host = (String) getConfig().get(IP_ADDRESS);
|
||||
int sourcePort = Integer.valueOf(command.toString());
|
||||
int outputPort = Port.get(channelID).toNumber();
|
||||
|
||||
if (sourcePort > numberOfPorts) {
|
||||
// nice try - we can switch to a port that does not physically exist
|
||||
logger.warn("Source port {} goes beyond the physical number of {} ports available on the matrix {}",
|
||||
new Object[] { sourcePort, numberOfPorts, host });
|
||||
} else if (outputPort > numberOfPorts) {
|
||||
// nice try - we can switch to a port that does not physically exist
|
||||
logger.warn("Output port {} goes beyond the physical number of {} ports available on the matrix {}",
|
||||
new Object[] { outputPort, numberOfPorts, host });
|
||||
} else {
|
||||
String httpMethod = "POST";
|
||||
String url = "http://" + host + "/cgi-bin/MMX32_Keyvalue.cgi";
|
||||
|
||||
String content = "{CMD=";
|
||||
content = content + command.toString() + "B";
|
||||
content = content + String.valueOf(outputPort) + ".";
|
||||
|
||||
InputStream stream = new ByteArrayInputStream(content.getBytes(StandardCharsets.UTF_8));
|
||||
|
||||
Properties httpHeaders = new Properties();
|
||||
httpHeaders.setProperty("Cookie", "logintype-88=01");
|
||||
|
||||
try {
|
||||
String response = HttpUtil.executeUrl(httpMethod, url, httpHeaders, stream,
|
||||
"application/x-www-form-urlencoded; charset=UTF-8", timeout);
|
||||
} catch (IOException e) {
|
||||
logger.debug("Communication with device failed", e);
|
||||
updateStatus(ThingStatus.OFFLINE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,159 @@
|
||||
/**
|
||||
* 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.hdanywhere.internal.handler;
|
||||
|
||||
import static org.apache.commons.lang.StringUtils.isNotBlank;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.openhab.binding.hdanywhere.internal.HDanywhereBindingConstants.Port;
|
||||
import org.openhab.core.io.net.http.HttpUtil;
|
||||
import org.openhab.core.library.types.DecimalType;
|
||||
import org.openhab.core.thing.ChannelUID;
|
||||
import org.openhab.core.thing.Thing;
|
||||
import org.openhab.core.thing.ThingStatus;
|
||||
import org.openhab.core.thing.binding.BaseThingHandler;
|
||||
import org.openhab.core.types.Command;
|
||||
import org.openhab.core.types.RefreshType;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* The {@link MultiroomPlusHandler} is responsible for handling commands, which are
|
||||
* sent to one of the channels. It supports the Multiroom+ V1/2/3 matrix (Note: this matrix is not longer supported by
|
||||
* HDanywhere)
|
||||
*
|
||||
* @author Karel Goderis - Initial contribution
|
||||
*/
|
||||
public class MultiroomPlusHandler extends BaseThingHandler {
|
||||
|
||||
// List of Configurations constants
|
||||
public static final String IP_ADDRESS = "ipAddress";
|
||||
public static final String PORTS = "ports";
|
||||
public static final String POLLING_INTERVAL = "interval";
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(MultiroomPlusHandler.class);
|
||||
|
||||
private ScheduledFuture<?> pollingJob;
|
||||
|
||||
/**
|
||||
* the timeout to use for connecting to a given host (defaults to 5000
|
||||
* milliseconds)
|
||||
*/
|
||||
private static int timeout = 5000;
|
||||
|
||||
public MultiroomPlusHandler(Thing thing) {
|
||||
super(thing);
|
||||
}
|
||||
|
||||
private Runnable pollingRunnable = () -> {
|
||||
try {
|
||||
String host = (String) getConfig().get(IP_ADDRESS);
|
||||
int numberOfPorts = ((BigDecimal) getConfig().get(PORTS)).intValue();
|
||||
|
||||
String httpMethod = "GET";
|
||||
String url = "http://" + host + "/status_show.shtml";
|
||||
|
||||
if (isNotBlank(httpMethod) && isNotBlank(url)) {
|
||||
String response = HttpUtil.executeUrl(httpMethod, url, null, null, null, timeout);
|
||||
|
||||
if (response != null) {
|
||||
updateStatus(ThingStatus.ONLINE);
|
||||
|
||||
for (int i = 1; i <= numberOfPorts; i++) {
|
||||
Pattern p = Pattern.compile("var out" + i + "var = (.*);");
|
||||
Matcher m = p.matcher(response);
|
||||
|
||||
while (m.find()) {
|
||||
DecimalType decimalType = new DecimalType(m.group(1));
|
||||
updateState(new ChannelUID(getThing().getUID(), Port.get(i).channelID()), decimalType);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
updateStatus(ThingStatus.OFFLINE);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.warn("An exception occurred while polling the HDanwywhere matrix: '{}'", e.getMessage());
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public void handleCommand(ChannelUID channelUID, Command command) {
|
||||
if (command instanceof RefreshType) {
|
||||
// Simply schedule a single run of the polling runnable to refresh all channels
|
||||
scheduler.schedule(pollingRunnable, 0, TimeUnit.SECONDS);
|
||||
} else {
|
||||
String channelID = channelUID.getId();
|
||||
|
||||
String host = (String) getConfig().get(IP_ADDRESS);
|
||||
int numberOfPorts = ((BigDecimal) getConfig().get(PORTS)).intValue();
|
||||
int sourcePort = Integer.valueOf(command.toString());
|
||||
int outputPort = Port.get(channelID).toNumber();
|
||||
|
||||
if (sourcePort > numberOfPorts) {
|
||||
// nice try - we can switch to a port that does not physically exist
|
||||
logger.warn("Source port {} goes beyond the physical number of {} ports available on the matrix {}",
|
||||
new Object[] { sourcePort, numberOfPorts, host });
|
||||
} else if (outputPort > numberOfPorts) {
|
||||
// nice try - we can switch to a port that does not physically exist
|
||||
logger.warn("Output port {} goes beyond the physical number of {} ports available on the matrix {}",
|
||||
new Object[] { outputPort, numberOfPorts, host });
|
||||
} else {
|
||||
String httpMethod = "GET";
|
||||
String url = "http://" + host + "/switch.cgi?command=3&data0=";
|
||||
|
||||
url = url + String.valueOf(outputPort) + "&data1=";
|
||||
url = url + command.toString() + "&checksum=";
|
||||
|
||||
int checksum = 3 + outputPort + sourcePort;
|
||||
url = url + String.valueOf(checksum);
|
||||
|
||||
try {
|
||||
HttpUtil.executeUrl(httpMethod, url, null, null, null, timeout);
|
||||
} catch (IOException e) {
|
||||
logger.error("Communication with device failed", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
logger.debug("Disposing HDanywhere matrix handler.");
|
||||
if (pollingJob != null && !pollingJob.isCancelled()) {
|
||||
pollingJob.cancel(true);
|
||||
pollingJob = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
logger.debug("Initializing HDanywhere Multiroom+ matrix handler.");
|
||||
onUpdate();
|
||||
|
||||
updateStatus(ThingStatus.UNKNOWN);
|
||||
}
|
||||
|
||||
private synchronized void onUpdate() {
|
||||
if (pollingJob == null || pollingJob.isCancelled()) {
|
||||
int pollingInterval = ((BigDecimal) getConfig().get(POLLING_INTERVAL)).intValue();
|
||||
pollingJob = scheduler.scheduleWithFixedDelay(pollingRunnable, 1, pollingInterval, TimeUnit.SECONDS);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<binding:binding id="hdanywhere" 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>openHAB HDanywhere Binding</name>
|
||||
<description>This is the binding for HDanywhere HDMI Matrices</description>
|
||||
<author>Karel Goderis</author>
|
||||
|
||||
</binding:binding>
|
||||
@@ -0,0 +1,41 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<thing:thing-descriptions bindingId="hdanywhere"
|
||||
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">
|
||||
|
||||
<!-- HDanywhere Thing Type -->
|
||||
<thing-type id="mhub4k431">
|
||||
<label>HDanywhere MHUB4K431 HDMI Matrix</label>
|
||||
<description>Thing for the HDanywhere MHUB4K431 HDMI Matrix</description>
|
||||
|
||||
<channels>
|
||||
<channel id="port1" typeId="port"/>
|
||||
<channel id="port2" typeId="port"/>
|
||||
<channel id="port3" typeId="port"/>
|
||||
<channel id="port4" typeId="port"/>
|
||||
</channels>
|
||||
|
||||
<config-description>
|
||||
<parameter name="ipAddress" type="text">
|
||||
<label>Network Address</label>
|
||||
<description>Network address of the Matrix</description>
|
||||
<required>true</required>
|
||||
</parameter>
|
||||
<parameter name="interval" type="integer" required="true">
|
||||
<label>Polling Interval</label>
|
||||
<description>Interval in seconds to poll the actual state of the Matrix</description>
|
||||
<default>3</default>
|
||||
</parameter>
|
||||
</config-description>
|
||||
</thing-type>
|
||||
|
||||
<!-- Port Channel Type -->
|
||||
<channel-type id="port">
|
||||
<item-type>Number</item-type>
|
||||
<label>Output Port</label>
|
||||
<description>The port channel allows to set or read the number of the input port that is connected to the output port.
|
||||
Valid values are 1 to 4</description>
|
||||
</channel-type>
|
||||
|
||||
</thing:thing-descriptions>
|
||||
@@ -0,0 +1,51 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<thing:thing-descriptions bindingId="hdanywhere"
|
||||
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">
|
||||
|
||||
<!-- HDanywhere Thing Type -->
|
||||
<thing-type id="multiroomplus">
|
||||
<label>HDanywhere Multiroom+ HDMI Matrix</label>
|
||||
<description>Thing for the HDanywhere Multiroom+ HDMI Matrix</description>
|
||||
|
||||
<channels>
|
||||
<channel id="port1" typeId="port"/>
|
||||
<channel id="port2" typeId="port"/>
|
||||
<channel id="port3" typeId="port"/>
|
||||
<channel id="port4" typeId="port"/>
|
||||
<channel id="port5" typeId="port"/>
|
||||
<channel id="port6" typeId="port"/>
|
||||
<channel id="port7" typeId="port"/>
|
||||
<channel id="port8" typeId="port"/>
|
||||
</channels>
|
||||
|
||||
<config-description>
|
||||
<parameter name="ipAddress" type="text">
|
||||
<label>Network Address</label>
|
||||
<description>Network address of the Matrix</description>
|
||||
<required>true</required>
|
||||
</parameter>
|
||||
<parameter name="ports" type="integer" required="true" min="1" max="8">
|
||||
<label>Number of Ports</label>
|
||||
<description>Specifies the number of input/output ports on the Matrix, e.g. 4 or 8 if 4x4 or 8x8 version of the
|
||||
Matrix</description>
|
||||
<default>4</default>
|
||||
</parameter>
|
||||
<parameter name="interval" type="integer" required="true">
|
||||
<label>Polling Interval</label>
|
||||
<description>Interval in seconds to poll the actual state of the Matrix</description>
|
||||
<default>10</default>
|
||||
</parameter>
|
||||
</config-description>
|
||||
</thing-type>
|
||||
|
||||
<!-- Port Channel Type -->
|
||||
<channel-type id="port">
|
||||
<item-type>Number</item-type>
|
||||
<label>Output Port</label>
|
||||
<description>The port channel allows to set or read the number of the input port that is connected to the output port.
|
||||
Valid values are 1 to 8 depending on the nature of the Matrix, e.g 4x4 8x8 etc</description>
|
||||
</channel-type>
|
||||
|
||||
</thing:thing-descriptions>
|
||||
Reference in New Issue
Block a user