Как в JAVA библиотеке jSSC получать данные сразу с нескольких COM портов?

Получается удачно создать подключения к com портам, но данные всегда получаю только с последнего созданного подключения. Пробовал использовать потоки, но в итоге то же самое.

класс Main

public class RDetectApplication {
    private static SerialPort serialPort;

    static EventRepo eventRepo;

    public EventRepo getEventRepo() {
        return eventRepo;
    }

    public static void main(String[] args) throws IOException {

        ConfigurableApplicationContext context = SpringApplication.run(RDetectApplication.class);
        eventRepo = context.getBean(EventRepo.class);

        try {
            Thread t1 = new Thread(new Runnable() {
                @Override
                public void run() {
                    new ComListener("100+75", "COM60").comConnect();
                }
            });

            t1.start();

            Thread t2 = new Thread(new Runnable() {
                @Override
                public void run() {
                    new ComListener("159+96", "COM82").comConnect();
                }
            });
            t2.start();
       } catch (InterruptedException e) {
           throw new RuntimeException(e);
       }

класс для чтения com порта

public class ComListener {

    //Объект типа SerialPort
    private static SerialPort serialPort;

    //пикет
    String picket;

    //имя порта в рагедкоме
    String ruggedComPortName;

    //конструктор
    public ComListener(String km, String ruggedComPortName) {
        this.ruggedComPortName = ruggedComPortName;
        this.picket = km;
    }

    public void comConnect() {
        //в конструктор передается номер порта из конструктора класса ComListener
        serialPort = new SerialPort(ruggedComPortName);
        try {
            serialPort.openPort(); // открытие порта
            serialPort.setParams(
                SerialPort.BAUDRATE_9600,
                SerialPort.DATABITS_8,
                SerialPort.STOPBITS_1,
                SerialPort.PARITY_NONE); // основные параметры протокола UART
            serialPort.setEventsMask(SerialPort.MASK_RXCHAR); //Установка  маски или списка события на которые будет происходить реакция. В данном случае это приход данных в буфер порта
            serialPort.addEventListener(new EventListener());//Передача экземпляра класса EventListener порту, где будет обрабатываться события
            System.out.println("имя созданного порта  "+serialPort.getPortName());
            if (serialPort.isOpened()) {
                System.out.println("порт " + serialPort.getPortName() + " открыт");
            }
        } catch (SerialPortException ex) {
            System.out.println(ex);
        }
    }

    //Слушатель срабатывающий по появлению данных на COM-порту
    public class EventListener implements SerialPortEventListener {

        public void serialEvent (SerialPortEvent event) {
            //Если происходит событие установленной маски и количество байтов в буфере более 0
            if (event.isRXCHAR () && event.getEventValue () > 0) {

                //Создание строковой переменной data, в которую записываются данные с COM порта
                String data;
                try {
                    //получение данных с ком порта
                    data = serialPort.readHexString(event.getEventValue());
                    //создание экземпляра парсера
                    Parser parser = new Parser(data,picket);
                    parser.parserStart();
                } catch (SerialPortException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }
}

класс парсер, который распознает данные с порта и пишет в sql

public class Parser {

    //получение переменной репозитория для возможности сохранения в бд
    EventRepo er = new RDetectApplication().getEventRepo();

    // данные с COM порта
    String data;

    //пикет
    String km;

    //полоса
    String  roadLine = null;

    //класс транспортного средства
    String carClass = null;

    //скорость
    int speed = 0;

    public Parser(String data, String km) {
        this.data = data;
        this.km = km;
    }

    //метод для парсинга данных с com порта
    public void parserStart() {
        //форматирование
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm");
        LocalDateTime localDateTime =LocalDateTime.now() ;
        String formattedDateTime = localDateTime.format(formatter);
        LocalDateTime dateTime = LocalDateTime.parse(formattedDateTime, formatter);

        //если строка начинается с 68 и длинна пакета больше 50 символов(возможно позже более точная корректировка)
        if (data.startsWith("68") & data.length() >= 50) {
            System.out.println(data);

            //дата
            //"EEE, d MMM yyyy, HH:mm:ss z"
            DateFormat dateFormat = new SimpleDateFormat("d MMM yyyy");
            String date = dateFormat.format(new Date());

            //время
            DateFormat timeFormat = new SimpleDateFormat("HH:mm");
            String time = timeFormat.format(new Date());

            System.out.print("дата: " + date + "   ");
            System.out.print("время: " + time + "   ");

            //километр
            System.out.print("пикет: " + km + "   ");

            //Парсинг
            //получение интов для проверки формата пакета
            int beginOne = Integer.parseInt(data.substring(0, 2));
            int beginTwo = Integer.parseInt(data.substring(9, 11));

            //если beginOne == 68 и beginTwo == 68  то продолжаем парcить (это проверка формата пакета)
            if (beginOne == 68 & beginTwo == 68) {

                //получение номера полосы движения над которой расположен детектор
                roadLine = data.substring(16, 17);
                //System.out.print("полоса: " + roadLine + "   ");

                //получение скорости транспортного средства
                speed = Integer.parseInt(data.substring(33, 35), 16);
                System.out.print("скорость: " + speed + "   ");

                //получение инта класса транспортного средства
                int carClassInt = Integer.parseInt(data.substring(36, 38), 16);

                switch (carClassInt) {
                    case 1:
                    case 32:
                        carClass = "легковой автомобиль";
                        break;
                    case 3:
                    case 33:
                        carClass = "грузовой автомобиль";
                        break;
                    case 2:
                        carClass = "легковой автомобиль с прицепом";
                         break;
                    case 4:
                        carClass = "грузовой автомобиль с прицепом";
                        break;
                     case 5:
                        carClass = "автобус";
                        break;
                     default:
                        carClass = "не определен";
                        break;
                }

                System.out.println("класс: " + carClass + "   ");
                System.out.println("_________________________");

                //добавление в базу
                er.save(new DetectorEvent(dateTime,km,roadLine,carClass,Integer.toString(speed)));
            }
        }
    }
}

Ответы (1 шт):

Автор решения: Oleg A

Когда создаете SerialPort, него можно указать лисенер, укажите другой, как-то так

serialPort1.addEventListener(new SerialPortReader1(), SerialPort.MASK_RXCHAR);
serialPort2.addEventListener(new SerialPortReader2(), SerialPort.MASK_RXCHAR);

где SerialPortReader1 и SerialPortReader2 реализуют SerialPortEventListener

→ Ссылка