Как в 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