[atlona] Add support for the AT-PRO3HD66M (#9385)

* Add support for the AT-PRO3HD66M

Signed-off-by: Michael Lobstein <michael.lobstein@gmail.com>
This commit is contained in:
mlobstein 2020-12-25 07:36:58 -06:00 committed by GitHub
parent b2f6202b25
commit ce69f22ef3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 277 additions and 196 deletions

View File

@ -1,6 +1,7 @@
# Atlona Binding
This binding integrates Atlona AT-UHD-PRO3 HdBaseT matrix switches [Atlona AT-UHD-PRO3 HdBaseT matrix switches](https://www.atlona.com) into your openHAB installation.
The older HD model 6x6 matrix [AT-PRO3HD66M] (https://atlona.com/product/at-pro3hd66m/) is also supported.
## Supported Things
@ -12,6 +13,7 @@ This binding supports the following thing types:
| pro3-66m | Thing | The AT-UHD-PRO3-66M 6x6 HDBaseT matrix. |
| pro3-88m | Thing | The AT-UHD-PRO3-88M 8x8 HDBaseT matrix. |
| pro3-1616m | Thing | The AT-UHD-PRO3-1616M 16x16 HDBaseT matrix. |
| pro3-hd66m | Thing | The AT-PRO3HD66M 6x6 HDBaseT matrix. |
## Discovery
@ -145,6 +147,18 @@ If it is higher than the "IP Timeout" value, the switch will timeout our connect
| pro3-1616m | volume11#volumemute | Switch | RW | Mutes/Unmutes audio port #11 |
| pro3-1616m | volume12#volume | Number | RW | Sets the volume of audio port #12 to the specified decibel level (between -79db to +15db) |
| pro3-1616m | volume12#volumemute | Switch | RW | Mutes/Unmutes audio port #12 |
| | | | | |
| pro3-hd66m | primary#power | Switch | RW | Matrix Power Switch |
| pro3-hd66m | primary#panellock | Switch | RW | Sets the front panel locked or unlocked |
| pro3-hd66m | primary#irenable | Switch | RW | Enables/Disabled the front panel IR |
| pro3-hd66m | primary#presetcmd | Switch | W | Sends a preset command ('saveX', 'recallX', 'clearX') - see notes below |
| pro3-hd66m | primary#matrixcmd | Switch | W | Sends a matrix command ('resetmatrix', 'resetports', 'allportsX') - see notes below |
| pro3-hd66m | port1#portoutput | Number | RW | Sets output port #1 to the specified input port |
| pro3-hd66m | port2#portoutput | Number | RW | Sets output port #2 to the specified input port |
| pro3-hd66m | port3#portoutput | Number | RW | Sets output port #3 to the specified input port |
| pro3-hd66m | port4#portoutput | Number | RW | Sets output port #4 to the specified input port |
| pro3-hd66m | port5#portoutput | Number | RW | Sets output port #5 to the specified input port |
| pro3-hd66m | port5#portoutput | Number | RW | Sets output port #6 to the specified input port |
### presetcmd

View File

@ -19,6 +19,7 @@ import org.openhab.core.thing.ThingTypeUID;
* The {@link AtlonaBinding} class defines common constants, which are used across the whole binding.
*
* @author Tim Roberts - Initial contribution
* @author Michael Lobstein - Add support for AT-PRO3HD66M
*/
@NonNullByDefault
public class AtlonaBindingConstants {
@ -47,4 +48,9 @@ public class AtlonaBindingConstants {
* Thing ID for the AT-UHD-PRO3-1616m (16x16 hdbaset matrix)
*/
public static final ThingTypeUID THING_TYPE_PRO3_1616M = new ThingTypeUID(BINDING_ID, "pro3-1616m");
/**
* Thing ID for the AT-PRO3HD66M (HD 6x6 hdbaset matrix)
*/
public static final ThingTypeUID THING_TYPE_PRO3HD_66M = new ThingTypeUID(BINDING_ID, "pro3-hd66m");
}

View File

@ -16,8 +16,6 @@ import static org.openhab.binding.atlona.internal.AtlonaBindingConstants.*;
import java.util.Collections;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.openhab.binding.atlona.internal.pro3.AtlonaPro3Capabilities;
import org.openhab.binding.atlona.internal.pro3.AtlonaPro3Handler;
@ -35,6 +33,7 @@ import org.slf4j.LoggerFactory;
* handlers.
*
* @author Tim Roberts - Initial contribution
* @author Michael Lobstein - Add support for AT-PRO3HD66M
*/
@Component(service = ThingHandlerFactory.class, configurationPid = "binding.atlona")
public class AtlonaHandlerFactory extends BaseThingHandlerFactory {
@ -44,9 +43,8 @@ public class AtlonaHandlerFactory extends BaseThingHandlerFactory {
/**
* The set of supported Atlona products
*/
private static final Set<ThingTypeUID> SUPPORTED_THING_TYPES_UIDS = Collections.unmodifiableSet(
Stream.of(THING_TYPE_PRO3_44M, THING_TYPE_PRO3_66M, THING_TYPE_PRO3_88M, THING_TYPE_PRO3_1616M)
.collect(Collectors.toSet()));
private static final Set<ThingTypeUID> SUPPORTED_THING_TYPES_UIDS = Set.of(THING_TYPE_PRO3_44M, THING_TYPE_PRO3_66M,
THING_TYPE_PRO3_88M, THING_TYPE_PRO3_1616M, THING_TYPE_PRO3HD_66M);
/**
* {@inheritDoc}
@ -65,30 +63,26 @@ public class AtlonaHandlerFactory extends BaseThingHandlerFactory {
*/
@Override
protected ThingHandler createHandler(Thing thing) {
if (thing == null) {
logger.error("createHandler was given a null thing!");
return null;
}
ThingTypeUID thingTypeUID = thing.getThingTypeUID();
if (thingTypeUID.equals(THING_TYPE_PRO3_44M)) {
return new AtlonaPro3Handler(thing, new AtlonaPro3Capabilities(5, 3, Collections.singleton(5)));
return new AtlonaPro3Handler(thing, new AtlonaPro3Capabilities(5, 3, Collections.singleton(5), true));
}
if (thingTypeUID.equals(THING_TYPE_PRO3_66M)) {
return new AtlonaPro3Handler(thing, new AtlonaPro3Capabilities(8, 4,
Collections.unmodifiableSet(Stream.of(6, 8).collect(Collectors.toSet()))));
return new AtlonaPro3Handler(thing, new AtlonaPro3Capabilities(8, 4, Set.of(6, 8), true));
}
if (thingTypeUID.equals(THING_TYPE_PRO3_88M)) {
return new AtlonaPro3Handler(thing, new AtlonaPro3Capabilities(10, 6,
Collections.unmodifiableSet(Stream.of(8, 10).collect(Collectors.toSet()))));
return new AtlonaPro3Handler(thing, new AtlonaPro3Capabilities(10, 6, Set.of(8, 10), true));
}
if (thingTypeUID.equals(THING_TYPE_PRO3_1616M)) {
return new AtlonaPro3Handler(thing, new AtlonaPro3Capabilities(5, 3,
Collections.unmodifiableSet(Stream.of(17, 18, 19, 20).collect(Collectors.toSet()))));
return new AtlonaPro3Handler(thing, new AtlonaPro3Capabilities(5, 3, Set.of(17, 18, 19, 20), true));
}
if (thingTypeUID.equals(THING_TYPE_PRO3HD_66M)) {
return new AtlonaPro3Handler(thing, new AtlonaPro3Capabilities(0, 0, Set.of(1, 2, 3, 4, 5, 6), false));
}
logger.warn("Unknown binding: {}: {}", thingTypeUID.getId(), thingTypeUID.getBindingId());

View File

@ -140,7 +140,6 @@ public class StatefulHandlerCallback implements AtlonaHandlerCallback {
* @return the {@link State} for the propertyName or null if not found
*/
public State getState(String propertyName) {
// TODO Auto-generated method stub
return state.get(propertyName);
}
}

View File

@ -23,6 +23,7 @@ import org.openhab.binding.atlona.internal.handler.AtlonaCapabilities;
* powered, the number of audio ports there are and which (output) ports are HDMI ports.
*
* @author Tim Roberts - Initial contribution
* @author Michael Lobstein - Add support for AT-PRO3HD66M
*/
public class AtlonaPro3Capabilities extends AtlonaCapabilities {
@ -41,6 +42,11 @@ public class AtlonaPro3Capabilities extends AtlonaCapabilities {
*/
private final Set<Integer> hdmiPorts;
/**
* Indicates if the thing is a 4K/UHD model vs an older HD model
*/
private final boolean isUHDModel;
/**
* Constructs the capabilities from the parms
*
@ -48,17 +54,9 @@ public class AtlonaPro3Capabilities extends AtlonaCapabilities {
* @param nbrAudioPorts a greater than 0 number of audio ports
* @param hdmiPorts a non-null, non-empty set of hdmi ports
*/
public AtlonaPro3Capabilities(int nbrPowerPorts, int nbrAudioPorts, Set<Integer> hdmiPorts) {
public AtlonaPro3Capabilities(int nbrPowerPorts, int nbrAudioPorts, Set<Integer> hdmiPorts, boolean isUHDModel) {
super();
if (nbrPowerPorts < 1) {
throw new IllegalArgumentException("nbrPowerPorts must be greater than 0");
}
if (nbrAudioPorts < 1) {
throw new IllegalArgumentException("nbrAudioPorts must be greater than 0");
}
if (hdmiPorts == null) {
throw new IllegalArgumentException("hdmiPorts cannot be null");
}
@ -70,6 +68,7 @@ public class AtlonaPro3Capabilities extends AtlonaCapabilities {
this.nbrPowerPorts = nbrPowerPorts;
this.nbrAudioPorts = nbrAudioPorts;
this.hdmiPorts = Collections.unmodifiableSet(new HashSet<>(hdmiPorts));
this.isUHDModel = isUHDModel;
}
/**
@ -98,4 +97,13 @@ public class AtlonaPro3Capabilities extends AtlonaCapabilities {
Set<Integer> getHdmiPorts() {
return hdmiPorts;
}
/**
* Returns a flag indicating the model type
*
* @return boolean true if the thing is a 4K/UHD model
*/
boolean isUHDModel() {
return isUHDModel;
}
}

View File

@ -489,7 +489,12 @@ public class AtlonaPro3Handler extends AtlonaHandler<AtlonaPro3Capabilities> {
session.clearListeners();
session.connect();
response = atlonaHandler.login();
if (this.getCapabilities().isUHDModel()) {
response = atlonaHandler.loginUHD();
} else {
response = atlonaHandler.loginHD();
}
if (response == null) {
final AtlonaPro3Config config = getAtlonaConfig();
if (config != null) {

View File

@ -37,6 +37,7 @@ import org.slf4j.LoggerFactory;
* web GUI, front panel keystrokes, etc]).
*
* @author Tim Roberts - Initial contribution
* @author Michael Lobstein - Add support for AT-PRO3HD66M
*/
class AtlonaPro3PortocolHandler {
private final Logger logger = LoggerFactory.getLogger(AtlonaPro3PortocolHandler.class);
@ -134,6 +135,14 @@ class AtlonaPro3PortocolHandler {
private final Pattern broadCastPattern = Pattern.compile("Broadcast (\\w+)");
private static final String RSP_MATRIX_RESET = "Mreset";
// Constants added to support the HD models
private static final String RSP_WELCOME = "Welcome to TELNET";
private static final String RSP_LOGIN_PLEASE = "Login Please";
private static final String RSP_USERNAME = "Username";
private static final String RSP_TRY_AGAIN = "Please Try Again";
private final Pattern versionHdPattern = Pattern.compile("V(.*)");
private final Pattern typeHdPattern = Pattern.compile("AT-PRO3HD(\\d+)M");
// ------------------------------------------------------------------------------------------------
// The following isn't part of the atlona protocol and is generated by us
private static final String CMD_PING = "ping";
@ -178,7 +187,7 @@ class AtlonaPro3PortocolHandler {
* @return a null if logged in successfully (or if switch didn't require login). Non-null if an exception occurred.
* @throws IOException an IO exception occurred during login
*/
String login() throws Exception {
String loginUHD() throws Exception {
logger.debug("Logging into atlona switch");
// Void to make sure we retrieve them
modelType = null;
@ -192,7 +201,7 @@ class AtlonaPro3PortocolHandler {
try {
response = callback.getResponse();
if (!response.equals("")) {
logger.info("Altona protocol violation - didn't start with an inital empty response: '{}'", response);
logger.debug("Altona protocol violation - didn't start with an inital empty response: '{}'", response);
}
} catch (Exception e) {
// ignore - may not having given us an initial ""
@ -213,10 +222,10 @@ class AtlonaPro3PortocolHandler {
return null;
}
// We should have been presented wit a new "\r\nLogin: "
// We should have been presented with a new "\r\nLogin: "
response = callback.getResponse();
if (!response.equals("")) {
logger.info("Altona protocol violation - didn't start with an inital empty response: '{}'", response);
logger.debug("Altona protocol violation - didn't start with an inital empty response: '{}'", response);
}
// Get the new "Login: " prompt response
@ -263,7 +272,7 @@ class AtlonaPro3PortocolHandler {
// First make sure we had an empty response (the "\r\n" part)
if (!response.equals("")) {
logger.info("Altona protocol violation - not an empty response after password: '{}'", response);
logger.debug("Altona protocol violation - not an empty response after password: '{}'", response);
}
// Now send an invalid command
@ -280,6 +289,94 @@ class AtlonaPro3PortocolHandler {
return "Password was invalid - please check your atlona setup";
}
/**
* Attempts to log into the older HD model switches using a slightly different protocol
*
* @return a null if logged in successfully (or if switch didn't require login). Non-null if an exception occurred.
* @throws IOException an IO exception occurred during login
*/
String loginHD() throws Exception {
logger.debug("Logging into atlona switch");
// Void to make sure we retrieve them
modelType = null;
version = null;
NoDispatchingCallback callback = new NoDispatchingCallback();
session.addListener(callback);
// Burn the initial (empty) return
String response;
try {
response = callback.getResponse();
if (!response.equals("")) {
logger.debug("Altona protocol violation - didn't start with an inital empty response: '{}'", response);
}
} catch (Exception e) {
// ignore - may not having given us an initial ""
}
response = callback.getResponse();
if (response.startsWith(RSP_WELCOME)) {
logger.debug("Altona AT-PRO3HD66M didn't require a login");
postLogin();
return null;
} else {
if (!response.startsWith(RSP_LOGIN_PLEASE)) {
logger.debug("Altona protocol violation - didn't start with login prompt '{}'", response);
}
// Since we were not logged in automatically, a user name is required from the configuration
if (config.getUserName() == null || config.getUserName().trim().length() == 0) {
return "Atlona PRO3 has enabled Telnet/IP Login but no username was provided in the configuration.";
}
// Make sure we have a password too
if (config.getPassword() == null || config.getPassword().trim().length() == 0) {
return "Atlona PRO3 has enabled Telnet/IP Login but no password was provided in the configuration.";
}
// Check for an empty response after the login prompt (the "\r\n" part)
response = callback.getResponse();
if (!response.equals("")) {
logger.debug("Altona protocol violation - not an empty response after password: '{}'", response);
}
// Send the username and wait for a ": " response
session.sendCommand(config.getUserName());
// We should have gotten the username response
response = callback.getResponse();
if (!response.startsWith(RSP_USERNAME)) {
logger.debug("Altona protocol violation - invalid response to username: '{}'", response);
}
// Send the password
try {
session.sendCommand(config.getPassword());
response = callback.getResponse();
} catch (Exception e) {
return "Password was invalid - please check your atlona setup";
}
if (response.startsWith(RSP_TRY_AGAIN)) {
return "Username " + config.getUserName() + " is not a valid user on the atlona";
}
if (response.startsWith(RSP_PASSWORD)) {
// After the correct password is sent, several empty responses are sent before the welcome message
for (int i = 0; i < 8; i++) {
response = callback.getResponse();
// If we get a welcome message, login was successful
if (response.startsWith(RSP_WELCOME)) {
postLogin();
return null;
}
}
}
}
return "Authentication failed - please check your atlona setup";
}
/**
* Post successful login stuff - mark us online and refresh from the switch
*/
@ -289,9 +386,11 @@ class AtlonaPro3PortocolHandler {
session.addListener(new NormalResponseCallback());
callback.statusChanged(ThingStatus.ONLINE, ThingStatusDetail.NONE, null);
// Set broadcast to on to receive notifications when
// routing changes (via the webpage, or presets or IR, etc)
sendCommand(CMD_BROADCAST_ON);
if (capabilities.isUHDModel()) {
// Set broadcast to on to receive notifications when
// routing changes (via the webpage, or presets or IR, etc)
sendCommand(CMD_BROADCAST_ON);
}
// setup the most likely state of these switches (there is no protocol to get them)
refreshAll();
@ -310,7 +409,12 @@ class AtlonaPro3PortocolHandler {
* Pings the server with an (invalid) ping command to keep the connection alive
*/
void ping() {
sendCommand(CMD_PING);
if (capabilities.isUHDModel()) {
sendCommand(CMD_PING);
} else {
// the HD model does not reflect the invalid command string back in the response for us to match later
sendCommand(CMD_VERSION);
}
}
/**
@ -331,7 +435,9 @@ class AtlonaPro3PortocolHandler {
}
refreshPower();
refreshAllPortStatuses();
if (capabilities.isUHDModel()) {
refreshAllPortStatuses();
}
final int nbrPowerPorts = capabilities.getNbrPowerPorts();
for (int x = 1; x <= nbrPowerPorts; x++) {
@ -969,7 +1075,7 @@ class AtlonaPro3PortocolHandler {
* @param resp the possibly null, possibly empty actual response
*/
private void handleCommandFailure(String resp) {
logger.info("{}", resp);
logger.debug("{}", resp);
}
/**
@ -1012,12 +1118,24 @@ class AtlonaPro3PortocolHandler {
return;
}
m = versionHdPattern.matcher(response);
if (m.matches()) {
handleVersionResponse(m, response);
return;
}
m = typePattern.matcher(response);
if (m.matches()) {
handleTypeResponse(m, response);
return;
}
m = typeHdPattern.matcher(response);
if (m.matches()) {
handleTypeResponse(m, response);
return;
}
m = portPowerPattern.matcher(response);
if (m.matches()) {
handlePortPowerResponse(m, response);
@ -1103,7 +1221,7 @@ class AtlonaPro3PortocolHandler {
return;
}
logger.info("Unhandled response: {}", response);
logger.debug("Unhandled response: {}", response);
}
@Override

View File

@ -0,0 +1,46 @@
<?xml version="1.0" encoding="UTF-8"?>
<config-description:config-descriptions
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:config-description="https://openhab.org/schemas/config-description/v1.0.0"
xsi:schemaLocation="https://openhab.org/schemas/config-description/v1.0.0 https://openhab.org/schemas/config-description-1.0.0.xsd">
<config-description uri="thing-type:altona:hdmimatrix">
<parameter name="ipAddress" type="text">
<context>network-address</context>
<label>IP or Host Name</label>
<description>IP or Host name of Atlona Matrix Switch</description>
<required>true</required>
</parameter>
<parameter name="userName" type="text">
<label>User Name</label>
<description>User Name to login with if Telnet Login is on</description>
<required>false</required>
<advanced>true</advanced>
</parameter>
<parameter name="password" type="text">
<context>password</context>
<label>Password</label>
<description>Password to login with if Telnet Login is on</description>
<required>false</required>
<advanced>true</advanced>
</parameter>
<parameter name="polling" type="integer" min="10" max="9999" unit="s" required="false">
<label>Polling Interval</label>
<description>Interval (in seconds) to poll the actual state of the Matrix</description>
<default>600</default>
<advanced>true</advanced>
</parameter>
<parameter name="ping" type="integer" min="10" max="600" unit="s" required="false">
<label>Ping Interval</label>
<description>Ping Interval (in seconds) to keep the connection alive</description>
<default>30</default>
<advanced>true</advanced>
</parameter>
<parameter name="retryPolling" type="integer" min="10" max="60" unit="s" required="false">
<label>Polling Interval to Try to Reconnect</label>
<description>Interval (in seconds) to try to (re)connect to the Matrix</description>
<default>10</default>
<advanced>true</advanced>
</parameter>
</config-description>
</config-description:config-descriptions>

View File

@ -49,45 +49,7 @@
</channel-group>
</channel-groups>
<config-description>
<parameter name="ipAddress" type="text">
<context>network-address</context>
<label>IP or Host Name</label>
<description>IP or Host name of Atlona Pro3 44M Switch</description>
<required>true</required>
</parameter>
<parameter name="userName" type="text">
<label>UserName to Login With</label>
<description>User Name to login with if Telnet Login is on</description>
<required>false</required>
<advanced>true</advanced>
</parameter>
<parameter name="password" type="text">
<context>password</context>
<label>Password to Login With</label>
<description>Password to login with if Telnet Login is on</description>
<required>false</required>
<advanced>true</advanced>
</parameter>
<parameter name="polling" type="integer">
<label>Polling Interval</label>
<description>Interval (in seconds) to poll the actual state of the Matrix</description>
<default>600</default>
<advanced>true</advanced>
</parameter>
<parameter name="ping" type="integer">
<label>Pint Interval</label>
<description>Ping Interval (in seconds) to keep the connection alive</description>
<default>30</default>
<advanced>true</advanced>
</parameter>
<parameter name="retryPolling" type="integer">
<label>Polling Interval to Try to Reconnect</label>
<description>Interval (in seconds) to try to (re)connect to the matrix</description>
<default>10</default>
<advanced>true</advanced>
</parameter>
</config-description>
<config-description-ref uri="thing-type:altona:hdmimatrix"/>
</thing-type>
<!-- AT-UHD-PRO3-66M -->
@ -155,45 +117,7 @@
</channel-group>
</channel-groups>
<config-description>
<parameter name="ipAddress" type="text">
<context>network-address</context>
<label>IP or Host Name</label>
<description>IP or Host name of Atlona Pro3 66M Switch</description>
<required>true</required>
</parameter>
<parameter name="userName" type="text">
<label>UserName to Login With</label>
<description>User Name to login with if Telnet Login is on</description>
<required>false</required>
<advanced>true</advanced>
</parameter>
<parameter name="password" type="text">
<context>password</context>
<label>Password to Login With</label>
<description>Password to login with if Telnet Login is on</description>
<required>false</required>
<advanced>true</advanced>
</parameter>
<parameter name="polling" type="integer">
<label>Polling Interval</label>
<description>Interval (in seconds) to poll the actual state of the Matrix</description>
<default>600</default>
<advanced>true</advanced>
</parameter>
<parameter name="ping" type="integer">
<label>Pint Interval</label>
<description>Ping Interval (in seconds) to keep the connection alive</description>
<default>30</default>
<advanced>true</advanced>
</parameter>
<parameter name="retryPolling" type="integer">
<label>Polling Interval to Try to Reconnect</label>
<description>Interval (in seconds) to try to (re)connect to the matrix</description>
<default>10</default>
<advanced>true</advanced>
</parameter>
</config-description>
<config-description-ref uri="thing-type:altona:hdmimatrix"/>
</thing-type>
<!-- AT-UHD-PRO3-88M -->
@ -277,45 +201,7 @@
</channel-group>
</channel-groups>
<config-description>
<parameter name="ipAddress" type="text" required="true">
<context>network-address</context>
<label>IP or Host Name</label>
<description>IP or Host name of Atlona Switch</description>
<default></default>
</parameter>
<parameter name="userName" type="text">
<label>UserName</label>
<description>User Name to use (if Telnet Login is ON)</description>
<default></default>
<advanced>true</advanced>
</parameter>
<parameter name="password" type="text">
<context>password</context>
<label>Password to Login With</label>
<description>Password to use (if Telnet Login is ON)</description>
<default></default>
<advanced>true</advanced>
</parameter>
<parameter name="polling" type="integer">
<label>Polling Interval</label>
<description>Interval (in seconds) to poll the actual state</description>
<default>600</default>
<advanced>true</advanced>
</parameter>
<parameter name="ping" type="integer">
<label>Pint Interval</label>
<description>Ping Interval (in seconds) to keep the connection alive</description>
<default>30</default>
<advanced>true</advanced>
</parameter>
<parameter name="retryPolling" type="integer">
<label>Polling Interval to Try to Reconnect</label>
<description>Interval (in seconds) to try to (re)connect</description>
<default>10</default>
<advanced>true</advanced>
</parameter>
</config-description>
<config-description-ref uri="thing-type:altona:hdmimatrix"/>
</thing-type>
<!-- AT-UHD-PRO3-1616M -->
@ -471,45 +357,43 @@
</channel-group>
</channel-groups>
<config-description>
<parameter name="ipAddress" type="text">
<context>network-address</context>
<label>IP or Host Name</label>
<description>IP or Host name of Atlona Pro3 1616M Switch</description>
<required>true</required>
</parameter>
<parameter name="userName" type="text">
<label>UserName to Login With</label>
<description>User Name to login with if Telnet Login is on</description>
<required>false</required>
<advanced>true</advanced>
</parameter>
<parameter name="password" type="text">
<context>password</context>
<label>Password to Login With</label>
<description>Password to login with if Telnet Login is on</description>
<required>false</required>
<advanced>true</advanced>
</parameter>
<parameter name="polling" type="integer">
<label>Polling Interval</label>
<description>Interval (in seconds) to poll the actual state of the Matrix</description>
<default>600</default>
<advanced>true</advanced>
</parameter>
<parameter name="ping" type="integer">
<label>Pint Interval</label>
<description>Ping Interval (in seconds) to keep the connection alive</description>
<default>30</default>
<advanced>true</advanced>
</parameter>
<parameter name="retryPolling" type="integer">
<label>Polling Interval to Try to Reconnect</label>
<description>Interval (in seconds) to try to (re)connect to the matrix</description>
<default>10</default>
<advanced>true</advanced>
</parameter>
</config-description>
<config-description-ref uri="thing-type:altona:hdmimatrix"/>
</thing-type>
<!-- AT-PRO3HD66M -->
<thing-type id="pro3-hd66m">
<label>Atlona Pro3 HD 6x6 HDBaseT Matrix</label>
<description>Atlona Pro3 6x6 HDBaseT Matrix (Model AT-PRO3HD66M)</description>
<channel-groups>
<channel-group id="primary" typeId="primarygroup"/>
<channel-group id="port1" typeId="hd-portgroup">
<label>Port 1</label>
<description>Output Port 1 Channels</description>
</channel-group>
<channel-group id="port2" typeId="hd-portgroup">
<label>Port 2</label>
<description>Output Port 2 Channels</description>
</channel-group>
<channel-group id="port3" typeId="hd-portgroup">
<label>Port 3</label>
<description>Output Port 3 Channels</description>
</channel-group>
<channel-group id="port4" typeId="hd-portgroup">
<label>Port 4</label>
<description>Output Port 4 Channels</description>
</channel-group>
<channel-group id="port5" typeId="hd-portgroup">
<label>Port 5</label>
<description>Output Port 5 Channels</description>
</channel-group>
<channel-group id="port6" typeId="hd-portgroup">
<label>Port 6</label>
<description>Output Port 6 Channels</description>
</channel-group>
</channel-groups>
<config-description-ref uri="thing-type:altona:hdmimatrix"/>
</thing-type>
<channel-group-type id="primarygroup">
@ -534,6 +418,13 @@
</channels>
</channel-group-type>
<channel-group-type id="hd-portgroup">
<label>Port</label>
<description>Output Port Channels</description>
<channels>
<channel id="portoutput" typeId="portoutput"/>
</channels>
</channel-group-type>
<channel-group-type id="mirrorgroup">
<label>HDMI Port</label>