[transport.serial] usb-stick is not initialized correctly

Hi,
I am in the process of developing my own binding and use a USB stick which is accessed via the serial port with the standard libraries (org.eclipse.smarthome.io.transport.serial).

Unfortunately, the connection or initialization of this USB stick does not work properly with [transport.serial] . By this I mean that no data is sent or received until an additional trigger is given by another lib (e.g. jssc.jar).
This can be triggered externally (a separate java script) or by a function call within the binding. And this trigger only needs to be done once.

Here is my actual class:

package org.openhab.binding.openwms.connector;

import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.util.TooManyListenersException;

import org.apache.commons.io.IOUtils;
import org.eclipse.smarthome.core.util.HexUtils;
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.openwms.config.OpenWMSBindingConstants;
import org.openhab.binding.openwms.config.OpenWMSBridgeConfiguration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class OpenWMSSerialConnector extends OpenWMSBaseConnector implements SerialPortEventListener {

    private final Logger logger = LoggerFactory.getLogger(OpenWMSSerialConnector.class);

    private OutputStream out;
    private SerialPort serialPort;

    private Thread readerThread;

    private SerialPortManager serialPortManager;

    public OpenWMSSerialConnector(SerialPortManager serialPortManager) {
        super();
        this.serialPortManager = serialPortManager;
    }


    @Override
    public void connect(OpenWMSBridgeConfiguration device)
            throws PortInUseException, UnsupportedCommOperationException, IOException {

        SerialPortIdentifier portIdentifier = serialPortManager.getIdentifier(device.serialPort.toString());
        if (portIdentifier == null) {
            logger.debug("No serial port {}", device.serialPort);
            throw new IOException("Could not find a gateway on given path '" + device.serialPort + "', "
                    + serialPortManager.getIdentifiers().count() + " ports available.");
        }
        serialPort = portIdentifier.open(OpenWMSBindingConstants.BINDING_ID, 2000);
        serialPort.setSerialPortParams(230400, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
       
        serialPort.enableReceiveThreshold(1);
        serialPort.enableReceiveTimeout(100); 
        in = serialPort.getInputStream();
        out = serialPort.getOutputStream();
        out.flush();
        if (in.markSupported()) {
            in.reset();
        }
        try {
            serialPort.addEventListener(this);
            serialPort.notifyOnDataAvailable(true);
            logger.debug("Serial port event listener started");
        } catch (TooManyListenersException e) {
        }

        readerThread = new OpenWMSStreamReader(this);
        readerThread.start();
    }

    @Override
    public void disconnect() {
        logger.debug("Disconnecting");

        if (serialPort != null) {
            serialPort.removeEventListener();
            logger.debug("Serial port event listener stopped");
        }

        if (readerThread != null) {
            logger.debug("Interrupt serial listener");
            readerThread.interrupt();
            try {
                readerThread.join();
            } catch (InterruptedException e) {
            }
        }

        if (out != null) {
            logger.debug("Close serial out stream");
            IOUtils.closeQuietly(out);
        }
        if (in != null) {
            logger.debug("Close serial in stream");
            IOUtils.closeQuietly(in);
        }

        if (serialPort != null) {
            logger.debug("Close serial port");
            serialPort.close();
        }

        readerThread = null;
        serialPort = null;
        out = null;
        in = null;

        logger.debug("Closed");
    }

    @Override
    public void sendMessage(byte[] data) throws IOException {
        String str = new String(data, StandardCharsets.UTF_8);
        if (out == null) {
            throw new IOException("Not connected sending messages is not possible");
        }
        }

        out.write(data);
        out.flush();
    }

    @Override
    public void serialEvent(SerialPortEvent arg0) {
        try {
            Thread.sleep(Long.MAX_VALUE);
        } catch (InterruptedException ignore) {
        }

    }

}

Running this function once initializes the stick and establishes a permanent connection:

package org.openhab.binding.openwms.connector;

import jssc.SerialPort;
import jssc.SerialPortException;

public class OpenWMSSerialWorkaround {
    private static SerialPort serialPort = null;

    public static void TestSerial(String port) throws SerialPortException {

        serialPort = new SerialPort(port);
        final int MAX_CONNECTION = 2;
        int reconnections = 0;

        boolean scanning = true;
        while (scanning && reconnections < MAX_CONNECTION) {
            {
                reconnections++;
                try {
                    serialPort.openPort();
                    serialPort.setParams(SerialPort.BAUDRATE_128000, SerialPort.DATABITS_8, SerialPort.STOPBITS_1,
                            SerialPort.PARITY_NONE);
                    scanning = false;
                } catch (Exception e) {
                    e.printStackTrace();
                    try {
                        Thread.sleep(2000);// 2 seconds
                    } catch (InterruptedException ie) {
                        ie.printStackTrace();
                    }
                }
            }

        }
        serialPort = null;

    }

}

Does anyone have an idea how I can achieve the same result with the [transport.serial] ?
Any help or hint where I can look for a solution is welcome - thanks in advance.

1 Like

This topic was automatically closed 41 days after the last reply. New replies are no longer allowed.