From affe53074b4dea10695f53eb58b2090c3d371919 Mon Sep 17 00:00:00 2001 From: Wouter Born Date: Tue, 12 May 2020 23:39:28 +0200 Subject: [PATCH] [digiplex] Use serial transport Related to #7573 Also removes the IT100BridgeDiscovery which sends messages to all available serial ports. Sending messages to other serial devices may cause issues such as message corruption, locking issues and unwanted operations. There's also a SerialConfigOptionProvider nowadays which simplifies selecting the serial ports in UIs from all available serial devices. Signed-off-by: Wouter Born --- .../org.openhab.binding.dscalarm/README.md | 3 +- bundles/org.openhab.binding.dscalarm/pom.xml | 4 - .../discovery/DSCAlarmBridgeDiscovery.java | 46 ------ .../discovery/IT100BridgeDiscovery.java | 133 ------------------ .../factory/DSCAlarmHandlerFactory.java | 12 +- .../internal/handler/IT100BridgeHandler.java | 51 ++++--- 6 files changed, 36 insertions(+), 213 deletions(-) delete mode 100644 bundles/org.openhab.binding.dscalarm/src/main/java/org/openhab/binding/dscalarm/internal/discovery/IT100BridgeDiscovery.java diff --git a/bundles/org.openhab.binding.dscalarm/README.md b/bundles/org.openhab.binding.dscalarm/README.md index 45200886870ff..b6f43d2326df0 100644 --- a/bundles/org.openhab.binding.dscalarm/README.md +++ b/bundles/org.openhab.binding.dscalarm/README.md @@ -29,9 +29,8 @@ Most settings are through thing configuration parameters. The DSC Alarm binding incorporates several discovery modes in order to find DSC Alarm systems. First, there is the Envisalink bridge discovery mode which performs a network query for any Envisalink adapters and adds them to the discovery inbox. -Second, there is The IT-100 bridge discovery mode which will search serial ports for any IT-100 adapters and add them to the discovery inbox. The bridge discovery modes are started manually through Paper UI. -Third, after a bridge is discovered and available to openHAB, the binding will attempt to discover DSC Alarm things and add them to the discovery inbox. +After a bridge is discovered and available to openHAB, the binding will attempt to discover DSC Alarm things and add them to the discovery inbox. The TCP Server bridge does not implement bridge discovery but will utilize thing discovery once it is online. Note: diff --git a/bundles/org.openhab.binding.dscalarm/pom.xml b/bundles/org.openhab.binding.dscalarm/pom.xml index 1c8367143703c..96a03ca900923 100644 --- a/bundles/org.openhab.binding.dscalarm/pom.xml +++ b/bundles/org.openhab.binding.dscalarm/pom.xml @@ -14,8 +14,4 @@ openHAB Add-ons :: Bundles :: DSCAlarm Binding - - gnu.io;version="[3.12,6)" - - diff --git a/bundles/org.openhab.binding.dscalarm/src/main/java/org/openhab/binding/dscalarm/internal/discovery/DSCAlarmBridgeDiscovery.java b/bundles/org.openhab.binding.dscalarm/src/main/java/org/openhab/binding/dscalarm/internal/discovery/DSCAlarmBridgeDiscovery.java index d0923b7d6feaf..24b2911cfa6db 100644 --- a/bundles/org.openhab.binding.dscalarm/src/main/java/org/openhab/binding/dscalarm/internal/discovery/DSCAlarmBridgeDiscovery.java +++ b/bundles/org.openhab.binding.dscalarm/src/main/java/org/openhab/binding/dscalarm/internal/discovery/DSCAlarmBridgeDiscovery.java @@ -21,7 +21,6 @@ import org.eclipse.smarthome.core.thing.ThingUID; import org.openhab.binding.dscalarm.internal.DSCAlarmBindingConstants; import org.openhab.binding.dscalarm.internal.config.EnvisalinkBridgeConfiguration; -import org.openhab.binding.dscalarm.internal.config.IT100BridgeConfiguration; import org.osgi.service.component.annotations.Component; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -37,11 +36,7 @@ public class DSCAlarmBridgeDiscovery extends AbstractDiscoveryService { private final Logger logger = LoggerFactory.getLogger(DSCAlarmBridgeDiscovery.class); private EnvisalinkBridgeDiscovery envisalinkBridgeDiscovery = new EnvisalinkBridgeDiscovery(this); - private IT100BridgeDiscovery it100BridgeDiscovery = new IT100BridgeDiscovery(this); - /** - * Constructor. - */ public DSCAlarmBridgeDiscovery() { super(DSCAlarmBindingConstants.SUPPORTED_BRIDGE_THING_TYPES_UIDS, 15, true); } @@ -50,17 +45,12 @@ public DSCAlarmBridgeDiscovery() { protected void startScan() { logger.trace("Start DSC Alarm Bridge discovery."); scheduler.execute(envisalinkBridgeDiscoveryRunnable); - scheduler.execute(it100BridgeDiscoveryRunnable); } private Runnable envisalinkBridgeDiscoveryRunnable = () -> { envisalinkBridgeDiscovery.discoverBridge(); }; - private Runnable it100BridgeDiscoveryRunnable = () -> { - it100BridgeDiscovery.discoverBridge(); - }; - /** * Method to add an Envisalink Bridge to the Smarthome Inbox. * @@ -84,40 +74,4 @@ public void addEnvisalinkBridge(String ipAddress) { logger.error("addBridge(): Error", e); } } - - /** - * Method to add an IT-100 Bridge to the Smarthome Inbox. - * - * @param port - */ - public void addIT100Bridge(String port) { - logger.trace("addBridge(): Adding new IT-100 Bridge on {} to Smarthome inbox", port); - - String bridgeID = ""; - boolean containsChar = port.contains("/"); - - if (containsChar) { - String[] parts = port.split("/"); - String id = parts[parts.length - 1].toUpperCase(); - bridgeID = id.replaceAll("\\W", "_"); - - } else { - String id = port.toUpperCase(); - bridgeID = id.replaceAll("\\W", "_"); - } - - Map properties = new HashMap<>(0); - properties.put(IT100BridgeConfiguration.SERIAL_PORT, port); - - try { - ThingUID thingUID = new ThingUID(DSCAlarmBindingConstants.IT100BRIDGE_THING_TYPE, bridgeID); - - thingDiscovered(DiscoveryResultBuilder.create(thingUID).withProperties(properties) - .withLabel("DSC IT-100 Bridge - " + port).build()); - - logger.trace("addBridge(): '{}' was added to Smarthome inbox.", thingUID); - } catch (Exception e) { - logger.error("addBridge(): Error", e); - } - } } diff --git a/bundles/org.openhab.binding.dscalarm/src/main/java/org/openhab/binding/dscalarm/internal/discovery/IT100BridgeDiscovery.java b/bundles/org.openhab.binding.dscalarm/src/main/java/org/openhab/binding/dscalarm/internal/discovery/IT100BridgeDiscovery.java deleted file mode 100644 index 93aea7aa3d360..0000000000000 --- a/bundles/org.openhab.binding.dscalarm/src/main/java/org/openhab/binding/dscalarm/internal/discovery/IT100BridgeDiscovery.java +++ /dev/null @@ -1,133 +0,0 @@ -/** - * 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.dscalarm.internal.discovery; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.OutputStreamWriter; -import java.io.UnsupportedEncodingException; -import java.util.Enumeration; - -import org.apache.commons.io.IOUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import gnu.io.CommPort; -import gnu.io.CommPortIdentifier; -import gnu.io.PortInUseException; -import gnu.io.SerialPort; -import gnu.io.UnsupportedCommOperationException; - -/** - * This class is responsible for discovering the DSC IT100 RS232 Serial interface. - * - * @author Russell Stephens - Initial Contribution - * - */ -public class IT100BridgeDiscovery { - private final Logger logger = LoggerFactory.getLogger(IT100BridgeDiscovery.class); - - static final int BAUD_RATE = 9600; - static final int RECEIVE_TIMEOUT = 15000; - static final String IT100_SEND_STRING = "00090\r\n"; - static final String IT100_DISCOVERY_RESPONSE = "500"; - - private DSCAlarmBridgeDiscovery dscAlarmBridgeDiscovery = null; - - /** - * Constructor. - */ - public IT100BridgeDiscovery(DSCAlarmBridgeDiscovery dscAlarmBridgeDiscovery) { - this.dscAlarmBridgeDiscovery = dscAlarmBridgeDiscovery; - } - - /** - * Method for Bridge Discovery. - */ - public synchronized void discoverBridge() { - logger.debug("Starting IT-100 Bridge Discovery."); - - Enumeration ports = CommPortIdentifier.getPortIdentifiers(); - - while (ports.hasMoreElements()) { - CommPortIdentifier portIdentifier = (CommPortIdentifier) ports.nextElement(); - - if (portIdentifier.getPortType() == CommPortIdentifier.PORT_SERIAL) { - SerialPort serialPort = null; - OutputStreamWriter serialOutput = null; - BufferedReader serialInput = null; - - try { - CommPort commPort = portIdentifier.open(this.getClass().getName(), 2000); - serialPort = (SerialPort) commPort; - serialPort.setSerialPortParams(BAUD_RATE, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, - SerialPort.PARITY_NONE); - serialPort.enableReceiveThreshold(1); - - serialOutput = new OutputStreamWriter(serialPort.getOutputStream(), "US-ASCII"); - serialInput = new BufferedReader(new InputStreamReader(serialPort.getInputStream())); - - serialPort.enableReceiveTimeout(RECEIVE_TIMEOUT); - String message = ""; - - serialOutput.write(IT100_SEND_STRING); - serialOutput.flush(); - - try { - message = serialInput.readLine(); - } catch (IOException e) { - logger.debug("discoverBridge(): No Message Read from Serial Port '{}'", - portIdentifier.getName()); - continue; - } - - if (message.substring(0, 3).equals(IT100_DISCOVERY_RESPONSE)) { - logger.debug("discoverBridge(): Serial Port '{}' Found!", portIdentifier.getName()); - dscAlarmBridgeDiscovery.addIT100Bridge(portIdentifier.getName()); - } else { - logger.debug("discoverBridge(): Incorrect Response from Serial Port! '{}' - {}", - portIdentifier.getName(), message); - } - - } catch (UnsupportedCommOperationException e) { - logger.debug("discoverBridge(): Unsupported Comm Operation Exception - '{}': {}", - portIdentifier.getName(), e.getMessage()); - } catch (PortInUseException e) { - logger.debug("discoverBridge(): Port in Use Exception - '{}': {}", portIdentifier.getName(), - e.getMessage()); - } catch (UnsupportedEncodingException e) { - logger.debug("discoverBridge(): Unsupported Encoding Exception - '{}': {}", - portIdentifier.getName(), e.getMessage()); - } catch (IOException e) { - logger.debug("discoverBridge(): IO Exception - '{}': {}", portIdentifier.getName(), e.getMessage()); - } finally { - if (serialInput != null) { - IOUtils.closeQuietly(serialInput); - serialInput = null; - } - - if (serialOutput != null) { - IOUtils.closeQuietly(serialOutput); - serialOutput = null; - } - - if (serialPort != null) { - serialPort.close(); - serialPort = null; - } - } - } - } - } -} diff --git a/bundles/org.openhab.binding.dscalarm/src/main/java/org/openhab/binding/dscalarm/internal/factory/DSCAlarmHandlerFactory.java b/bundles/org.openhab.binding.dscalarm/src/main/java/org/openhab/binding/dscalarm/internal/factory/DSCAlarmHandlerFactory.java index 1babc4ef7f3c9..48a0caa84d623 100644 --- a/bundles/org.openhab.binding.dscalarm/src/main/java/org/openhab/binding/dscalarm/internal/factory/DSCAlarmHandlerFactory.java +++ b/bundles/org.openhab.binding.dscalarm/src/main/java/org/openhab/binding/dscalarm/internal/factory/DSCAlarmHandlerFactory.java @@ -27,6 +27,7 @@ import org.eclipse.smarthome.core.thing.binding.BaseThingHandlerFactory; import org.eclipse.smarthome.core.thing.binding.ThingHandler; import org.eclipse.smarthome.core.thing.binding.ThingHandlerFactory; +import org.eclipse.smarthome.io.transport.serial.SerialPortManager; import org.openhab.binding.dscalarm.internal.DSCAlarmBindingConstants; import org.openhab.binding.dscalarm.internal.config.DSCAlarmPartitionConfiguration; import org.openhab.binding.dscalarm.internal.config.DSCAlarmZoneConfiguration; @@ -43,7 +44,9 @@ import org.openhab.binding.dscalarm.internal.handler.TCPServerBridgeHandler; import org.openhab.binding.dscalarm.internal.handler.ZoneThingHandler; import org.osgi.framework.ServiceRegistration; +import org.osgi.service.component.annotations.Activate; import org.osgi.service.component.annotations.Component; +import org.osgi.service.component.annotations.Reference; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -58,6 +61,13 @@ public class DSCAlarmHandlerFactory extends BaseThingHandlerFactory { private final Logger logger = LoggerFactory.getLogger(DSCAlarmHandlerFactory.class); private final Map> discoveryServiceRegistrations = new HashMap<>(); + private final SerialPortManager serialPortManager; + + @Activate + public DSCAlarmHandlerFactory(final @Reference SerialPortManager serialPortManager) { + this.serialPortManager = serialPortManager; + } + @Override public Thing createThing(ThingTypeUID thingTypeUID, Configuration configuration, ThingUID thingUID, ThingUID bridgeUID) { @@ -261,7 +271,7 @@ protected ThingHandler createHandler(Thing thing) { logger.debug("createHandler(): ENVISALINKBRIDGE_THING: ThingHandler created for {}", thingTypeUID); return handler; } else if (thingTypeUID.equals(DSCAlarmBindingConstants.IT100BRIDGE_THING_TYPE)) { - IT100BridgeHandler handler = new IT100BridgeHandler((Bridge) thing); + IT100BridgeHandler handler = new IT100BridgeHandler((Bridge) thing, serialPortManager); registerDSCAlarmDiscoveryService(handler); logger.debug("createHandler(): IT100BRIDGE_THING: ThingHandler created for {}", thingTypeUID); return handler; diff --git a/bundles/org.openhab.binding.dscalarm/src/main/java/org/openhab/binding/dscalarm/internal/handler/IT100BridgeHandler.java b/bundles/org.openhab.binding.dscalarm/src/main/java/org/openhab/binding/dscalarm/internal/handler/IT100BridgeHandler.java index 47ddbf19e2eba..8428baa8d33e2 100644 --- a/bundles/org.openhab.binding.dscalarm/src/main/java/org/openhab/binding/dscalarm/internal/handler/IT100BridgeHandler.java +++ b/bundles/org.openhab.binding.dscalarm/src/main/java/org/openhab/binding/dscalarm/internal/handler/IT100BridgeHandler.java @@ -22,19 +22,17 @@ import org.apache.commons.io.IOUtils; import org.eclipse.smarthome.core.thing.Bridge; import org.eclipse.smarthome.core.thing.ThingStatus; +import org.eclipse.smarthome.io.transport.serial.PortInUseException; +import org.eclipse.smarthome.io.transport.serial.SerialPort; +import org.eclipse.smarthome.io.transport.serial.SerialPortEvent; +import org.eclipse.smarthome.io.transport.serial.SerialPortEventListener; +import org.eclipse.smarthome.io.transport.serial.SerialPortIdentifier; +import org.eclipse.smarthome.io.transport.serial.SerialPortManager; +import org.eclipse.smarthome.io.transport.serial.UnsupportedCommOperationException; import org.openhab.binding.dscalarm.internal.config.IT100BridgeConfiguration; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import gnu.io.CommPort; -import gnu.io.CommPortIdentifier; -import gnu.io.NoSuchPortException; -import gnu.io.PortInUseException; -import gnu.io.SerialPort; -import gnu.io.SerialPortEvent; -import gnu.io.SerialPortEventListener; -import gnu.io.UnsupportedCommOperationException; - /** * The bridge handler for the DSC IT100 RS232 Serial interface. * @@ -44,15 +42,7 @@ public class IT100BridgeHandler extends DSCAlarmBaseBridgeHandler implements SerialPortEventListener { private final Logger logger = LoggerFactory.getLogger(IT100BridgeHandler.class); - - /** - * Constructor. - * - * @param bridge - */ - public IT100BridgeHandler(Bridge bridge) { - super(bridge, DSCAlarmBridgeType.IT100, DSCAlarmProtocol.IT100_API); - } + private final SerialPortManager serialPortManager; private String serialPortName = ""; private int baudRate; @@ -60,6 +50,11 @@ public IT100BridgeHandler(Bridge bridge) { private OutputStreamWriter serialOutput = null; private BufferedReader serialInput = null; + public IT100BridgeHandler(Bridge bridge, SerialPortManager serialPortManager) { + super(bridge, DSCAlarmBridgeType.IT100, DSCAlarmProtocol.IT100_API); + this.serialPortManager = serialPortManager; + } + @Override public void initialize() { logger.debug("Initializing the DSC IT100 Bridge handler."); @@ -98,13 +93,19 @@ public void dispose() { @Override public void openConnection() { - try { - logger.debug("openConnection(): Connecting to IT-100 "); + logger.debug("openConnection(): Connecting to IT-100"); - CommPortIdentifier portIdentifier = CommPortIdentifier.getPortIdentifier(serialPortName); - CommPort commPort = portIdentifier.open(this.getClass().getName(), 2000); + SerialPortIdentifier portIdentifier = serialPortManager.getIdentifier(serialPortName); + if (portIdentifier == null) { + logger.error("openConnection(): No Such Port: {}", serialPort); + setConnected(false); + return; + } - serialPort = (SerialPort) commPort; + try { + SerialPort commPort = portIdentifier.open(this.getClass().getName(), 2000); + + serialPort = commPort; serialPort.setSerialPortParams(baudRate, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE); serialPort.enableReceiveThreshold(1); @@ -116,10 +117,6 @@ public void openConnection() { setSerialEventHandler(this); setConnected(true); - - } catch (NoSuchPortException noSuchPortException) { - logger.error("openConnection(): No Such Port Exception: {}", noSuchPortException.getMessage()); - setConnected(false); } catch (PortInUseException portInUseException) { logger.error("openConnection(): Port in Use Exception: {}", portInUseException.getMessage()); setConnected(false);