Browse Source

#15 前台获取设备温度时,时常会出现接口错误导致无法获取设备温度

master
sige 2 years ago
parent
commit
5b4d1f414a
  1. 37
      src/main/java/com/dreamworks/boditech/driver/Device.java
  2. 121
      src/main/java/com/dreamworks/boditech/driver/connection/ComSerialPort.java

37
src/main/java/com/dreamworks/boditech/driver/Device.java

@ -152,41 +152,10 @@ public class Device {
}
if ("SerialPort".equals(this.connectionType)) {
return this.serialPortCall(request.parameter);
return this.serialPort.call(request);
} else {
return this.websocket.call(request);
}
return this.websocket.call(request);
}
// call device command in debug mode
private ByteBuffer serialPortCall(ByteBuffer request) {
this.logMessage(DeviceLogEntry.DIR_SEND, request);
this.serialPort.write(request);
if ( !this.serialPort.waitForResponse(3000) ) {
return null;
}
ByteBuffer response = this.serialPort.read();
this.logMessage(DeviceLogEntry.DIR_RECEIVE, response);
return response;
}
// log device message
public void logMessage( Integer direction, ByteBuffer message ) {
String messageHex = MyByteBuffer.toHex(message);
// if ( direction.equals(DeviceLogEntry.DIR_SEND) ) {
// LOG.info("Device => {}", messageHex);
// } else {
// LOG.info("Device <= {}", messageHex);
// }
DeviceLogEntry entry = new DeviceLogEntry();
entry.message = messageHex;
entry.direction = direction;
entry.timestamp = System.currentTimeMillis();
LocalDateTime now = LocalDateTime.now();
entry.createdAt = now.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
this.deviceLogMapper.insert(entry);
}
// get connection status

121
src/main/java/com/dreamworks/boditech/driver/connection/ComSerialPort.java

@ -1,13 +1,21 @@
package com.dreamworks.boditech.driver.connection;
import com.dreamworks.boditech.utils.MyByteBuffer;
import com.fazecast.jSerialComm.SerialPort;
import com.fazecast.jSerialComm.SerialPortDataListener;
import com.fazecast.jSerialComm.SerialPortEvent;
import jakarta.annotation.PostConstruct;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.*;
@Component
public class ComSerialPort {
// message type : ack
private static final byte MESSAGE_TYPE_ACK = 0x01;
private static final Logger LOG = LoggerFactory.getLogger(ComSerialPort.class);
@Value("${app.device.connectionType}")
private String connectionType;
@ -17,6 +25,8 @@ public class ComSerialPort {
private int baudRate;
// serial port connection
private SerialPort port;
// request list
private final List<ClientRequest> requestList = new ArrayList<>();
@PostConstruct
public void init() {
@ -40,35 +50,108 @@ public class ComSerialPort {
}
this.port.setBaudRate(this.baudRate);
this.port.addDataListener(new SerialPortDataListener() {
@Override
public int getListeningEvents() {
return SerialPort.LISTENING_EVENT_DATA_AVAILABLE;
}
@Override
public void serialEvent(SerialPortEvent event) {
if (event.getEventType() != SerialPort.LISTENING_EVENT_DATA_AVAILABLE) {
return ;
}
handleOnData();
}
});
}
// write bytes to serial port
public void write( ByteBuffer content ) {
byte[] bytes = content.array();
this.port.writeBytes(bytes, bytes.length);
// handle on data
public void handleOnData() {
ByteBuffer message = this.readAll();
message.order(ByteOrder.LITTLE_ENDIAN);
LOG.info("device <= {}", MyByteBuffer.toHex(message));
byte messageType = message.get(5);
if ( ComSerialPort.MESSAGE_TYPE_ACK == messageType ) {
this.onMessageHandleAck(message);
} else {
throw new RuntimeException("unknown message type");
}
}
// read text from serial port
public ByteBuffer read() {
int readableLength = this.port.bytesAvailable();
byte[] buffer = new byte[readableLength];
int numRead = this.port.readBytes(buffer, buffer.length);
return ByteBuffer.wrap(buffer, 0, numRead);
// handle ack message
private void onMessageHandleAck(ByteBuffer message) {
ClientRequest request = this.getRequestMessage(message);
if ( null == request ) {
return ;
}
synchronized (Objects.requireNonNull(request)) {
request.isResponseReceived = true;
request.response = message;
request.notify();
}
}
// get request message
private ClientRequest getRequestMessage( ByteBuffer message ) {
short messageId = message.getShort(0);
for ( ClientRequest requestItem : this.requestList ) {
if ( requestItem.id == messageId ) {
return requestItem;
}
}
return null;
}
// wait for response
public boolean waitForResponse( Integer timeout ) {
int count = timeout / 200;
for (int i=0; i<count; i++) {
if ( this.port.bytesAvailable() > 0 ) {
return true;
// call device method and wait for response
public ByteBuffer call(ClientRequest request ) {
this.requestList.add(request);
int index = this.requestList.indexOf(request);
ClientRequest requestItem = this.requestList.get(index);
// timeout check
TimerTask timerTask = new TimerTask() {
@Override
public void run() {
synchronized (requestItem) {
if ( requestItem.isResponseReceived ) {
return ;
}
LOG.info("device -- timeout");
requestItem.response = null;
requestItem.errorCode = ClientRequest.ERROR_CODE_TIMEOUT;
requestItem.notify();
}
}
};
Timer timer = new Timer();
timer.schedule(timerTask, 10000);
synchronized (requestItem) {
String cmd = MyByteBuffer.toHex(request.parameter);
LOG.info("device => {}", cmd);
byte[] bytes = request.parameter.array();
this.port.writeBytes(bytes, bytes.length);
try {
Thread.sleep(200);
requestItem.wait();
} catch (InterruptedException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
return false;
if ( 0 != request.errorCode ) {
throw new RuntimeException("device error : " + request.errorCode);
}
return request.response;
}
// read all data from serial port
public ByteBuffer readAll() {
int readableLength = this.port.bytesAvailable();
byte[] buffer = new byte[readableLength];
int numRead = this.port.readBytes(buffer, buffer.length);
return ByteBuffer.wrap(buffer, 0, numRead);
}
}
Loading…
Cancel
Save