From dc8fa86bf19b202b91fa3825a2a8bff32de92aca Mon Sep 17 00:00:00 2001 From: mlobstein Date: Fri, 25 Dec 2020 07:36:58 -0600 Subject: [PATCH] [atlona] Add support for the AT-PRO3HD66M (#9385) * Add support for the AT-PRO3HD66M --- bundles/org.openhab.binding.atlona/README.md | 14 ++ .../internal/AtlonaBindingConstants.java | 6 + .../atlona/internal/AtlonaHandlerFactory.java | 28 +-- .../internal/StatefulHandlerCallback.java | 1 - .../internal/pro3/AtlonaPro3Capabilities.java | 26 ++- .../internal/pro3/AtlonaPro3Handler.java | 7 +- .../pro3/AtlonaPro3PortocolHandler.java | 142 ++++++++++-- .../main/resources/OH-INF/config/config.xml | 46 ++++ .../resources/OH-INF/thing/thing-types.xml | 203 ++++-------------- 9 files changed, 277 insertions(+), 196 deletions(-) create mode 100644 bundles/org.openhab.binding.atlona/src/main/resources/OH-INF/config/config.xml diff --git a/bundles/org.openhab.binding.atlona/README.md b/bundles/org.openhab.binding.atlona/README.md index 668e4e0dd523d..e8390239e85a7 100644 --- a/bundles/org.openhab.binding.atlona/README.md +++ b/bundles/org.openhab.binding.atlona/README.md @@ -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 diff --git a/bundles/org.openhab.binding.atlona/src/main/java/org/openhab/binding/atlona/internal/AtlonaBindingConstants.java b/bundles/org.openhab.binding.atlona/src/main/java/org/openhab/binding/atlona/internal/AtlonaBindingConstants.java index 0415cc5056520..af7bbfe7e9ca4 100644 --- a/bundles/org.openhab.binding.atlona/src/main/java/org/openhab/binding/atlona/internal/AtlonaBindingConstants.java +++ b/bundles/org.openhab.binding.atlona/src/main/java/org/openhab/binding/atlona/internal/AtlonaBindingConstants.java @@ -19,6 +19,7 @@ * 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"); } diff --git a/bundles/org.openhab.binding.atlona/src/main/java/org/openhab/binding/atlona/internal/AtlonaHandlerFactory.java b/bundles/org.openhab.binding.atlona/src/main/java/org/openhab/binding/atlona/internal/AtlonaHandlerFactory.java index 2572bd7ed2b7c..c9aadb6196b33 100644 --- a/bundles/org.openhab.binding.atlona/src/main/java/org/openhab/binding/atlona/internal/AtlonaHandlerFactory.java +++ b/bundles/org.openhab.binding.atlona/src/main/java/org/openhab/binding/atlona/internal/AtlonaHandlerFactory.java @@ -16,8 +16,6 @@ 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 @@ * 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 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 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 boolean supportsThingType(ThingTypeUID thingTypeUID) { */ @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()); diff --git a/bundles/org.openhab.binding.atlona/src/main/java/org/openhab/binding/atlona/internal/StatefulHandlerCallback.java b/bundles/org.openhab.binding.atlona/src/main/java/org/openhab/binding/atlona/internal/StatefulHandlerCallback.java index a1031ab0e6578..79a78d03ae2c8 100644 --- a/bundles/org.openhab.binding.atlona/src/main/java/org/openhab/binding/atlona/internal/StatefulHandlerCallback.java +++ b/bundles/org.openhab.binding.atlona/src/main/java/org/openhab/binding/atlona/internal/StatefulHandlerCallback.java @@ -140,7 +140,6 @@ public void setProperty(String propertyName, String propertyValue) { * @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); } } diff --git a/bundles/org.openhab.binding.atlona/src/main/java/org/openhab/binding/atlona/internal/pro3/AtlonaPro3Capabilities.java b/bundles/org.openhab.binding.atlona/src/main/java/org/openhab/binding/atlona/internal/pro3/AtlonaPro3Capabilities.java index d2951f7001b56..cd4c4a9943479 100644 --- a/bundles/org.openhab.binding.atlona/src/main/java/org/openhab/binding/atlona/internal/pro3/AtlonaPro3Capabilities.java +++ b/bundles/org.openhab.binding.atlona/src/main/java/org/openhab/binding/atlona/internal/pro3/AtlonaPro3Capabilities.java @@ -23,6 +23,7 @@ * 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 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 hdmiPorts) { + public AtlonaPro3Capabilities(int nbrPowerPorts, int nbrAudioPorts, Set 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 AtlonaPro3Capabilities(int nbrPowerPorts, int nbrAudioPorts, Set this.nbrPowerPorts = nbrPowerPorts; this.nbrAudioPorts = nbrAudioPorts; this.hdmiPorts = Collections.unmodifiableSet(new HashSet<>(hdmiPorts)); + this.isUHDModel = isUHDModel; } /** @@ -98,4 +97,13 @@ int getNbrAudioPorts() { Set 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; + } } diff --git a/bundles/org.openhab.binding.atlona/src/main/java/org/openhab/binding/atlona/internal/pro3/AtlonaPro3Handler.java b/bundles/org.openhab.binding.atlona/src/main/java/org/openhab/binding/atlona/internal/pro3/AtlonaPro3Handler.java index a666dd5cbd656..a5172b87d68a0 100644 --- a/bundles/org.openhab.binding.atlona/src/main/java/org/openhab/binding/atlona/internal/pro3/AtlonaPro3Handler.java +++ b/bundles/org.openhab.binding.atlona/src/main/java/org/openhab/binding/atlona/internal/pro3/AtlonaPro3Handler.java @@ -489,7 +489,12 @@ private void connect() { 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) { diff --git a/bundles/org.openhab.binding.atlona/src/main/java/org/openhab/binding/atlona/internal/pro3/AtlonaPro3PortocolHandler.java b/bundles/org.openhab.binding.atlona/src/main/java/org/openhab/binding/atlona/internal/pro3/AtlonaPro3PortocolHandler.java index efd3f42573589..0f65e9fc18543 100644 --- a/bundles/org.openhab.binding.atlona/src/main/java/org/openhab/binding/atlona/internal/pro3/AtlonaPro3PortocolHandler.java +++ b/bundles/org.openhab.binding.atlona/src/main/java/org/openhab/binding/atlona/internal/pro3/AtlonaPro3PortocolHandler.java @@ -37,6 +37,7 @@ * 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 @@ String login() throws Exception { 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 @@ String login() throws Exception { 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 @@ String login() throws Exception { // 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 @@ String login() throws Exception { 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 @@ private void postLogin() { 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 @@ AtlonaHandlerCallback getCallback() { * 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 @@ void refreshAll() { } refreshPower(); - refreshAllPortStatuses(); + if (capabilities.isUHDModel()) { + refreshAllPortStatuses(); + } final int nbrPowerPorts = capabilities.getNbrPowerPorts(); for (int x = 1; x <= nbrPowerPorts; x++) { @@ -969,7 +1075,7 @@ private void handleMatrixResetResponse(String resp) { * @param resp the possibly null, possibly empty actual response */ private void handleCommandFailure(String resp) { - logger.info("{}", resp); + logger.debug("{}", resp); } /** @@ -1012,12 +1118,24 @@ public void responseReceived(String response) { 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 @@ public void responseReceived(String response) { return; } - logger.info("Unhandled response: {}", response); + logger.debug("Unhandled response: {}", response); } @Override diff --git a/bundles/org.openhab.binding.atlona/src/main/resources/OH-INF/config/config.xml b/bundles/org.openhab.binding.atlona/src/main/resources/OH-INF/config/config.xml new file mode 100644 index 0000000000000..ce4acc3aa69b3 --- /dev/null +++ b/bundles/org.openhab.binding.atlona/src/main/resources/OH-INF/config/config.xml @@ -0,0 +1,46 @@ + + + + + + network-address + + IP or Host name of Atlona Matrix Switch + true + + + + User Name to login with if Telnet Login is on + false + true + + + password + + Password to login with if Telnet Login is on + false + true + + + + Interval (in seconds) to poll the actual state of the Matrix + 600 + true + + + + Ping Interval (in seconds) to keep the connection alive + 30 + true + + + + Interval (in seconds) to try to (re)connect to the Matrix + 10 + true + + + diff --git a/bundles/org.openhab.binding.atlona/src/main/resources/OH-INF/thing/thing-types.xml b/bundles/org.openhab.binding.atlona/src/main/resources/OH-INF/thing/thing-types.xml index 40a4ed2f7bcfe..afb6e1f9f70dc 100644 --- a/bundles/org.openhab.binding.atlona/src/main/resources/OH-INF/thing/thing-types.xml +++ b/bundles/org.openhab.binding.atlona/src/main/resources/OH-INF/thing/thing-types.xml @@ -49,45 +49,7 @@ - - - network-address - - IP or Host name of Atlona Pro3 44M Switch - true - - - - User Name to login with if Telnet Login is on - false - true - - - password - - Password to login with if Telnet Login is on - false - true - - - - Interval (in seconds) to poll the actual state of the Matrix - 600 - true - - - - Ping Interval (in seconds) to keep the connection alive - 30 - true - - - - Interval (in seconds) to try to (re)connect to the matrix - 10 - true - - + @@ -155,45 +117,7 @@ - - - network-address - - IP or Host name of Atlona Pro3 66M Switch - true - - - - User Name to login with if Telnet Login is on - false - true - - - password - - Password to login with if Telnet Login is on - false - true - - - - Interval (in seconds) to poll the actual state of the Matrix - 600 - true - - - - Ping Interval (in seconds) to keep the connection alive - 30 - true - - - - Interval (in seconds) to try to (re)connect to the matrix - 10 - true - - + @@ -277,45 +201,7 @@ - - - network-address - - IP or Host name of Atlona Switch - - - - - User Name to use (if Telnet Login is ON) - - true - - - password - - Password to use (if Telnet Login is ON) - - true - - - - Interval (in seconds) to poll the actual state - 600 - true - - - - Ping Interval (in seconds) to keep the connection alive - 30 - true - - - - Interval (in seconds) to try to (re)connect - 10 - true - - + @@ -471,45 +357,43 @@ - - - network-address - - IP or Host name of Atlona Pro3 1616M Switch - true - - - - User Name to login with if Telnet Login is on - false - true - - - password - - Password to login with if Telnet Login is on - false - true - - - - Interval (in seconds) to poll the actual state of the Matrix - 600 - true - - - - Ping Interval (in seconds) to keep the connection alive - 30 - true - - - - Interval (in seconds) to try to (re)connect to the matrix - 10 - true - - + + + + + + + Atlona Pro3 6x6 HDBaseT Matrix (Model AT-PRO3HD66M) + + + + + + Output Port 1 Channels + + + + Output Port 2 Channels + + + + Output Port 3 Channels + + + + Output Port 4 Channels + + + + Output Port 5 Channels + + + + Output Port 6 Channels + + + + @@ -534,6 +418,13 @@ + + + Output Port Channels + + + +