sige 2 years ago
parent
commit
7b6772186b
  1. 67
      src/src/main/java/com/my/graphiteDigesterBg/diframe/DiActuatorBase.java
  2. 1
      src/src/main/java/com/my/graphiteDigesterBg/diframe/DiCommand.java
  3. 16
      src/src/main/java/com/my/graphiteDigesterBg/diframe/DiCommandRequest.java
  4. 2
      src/src/main/java/com/my/graphiteDigesterBg/diframe/DiDeviceConnection.java
  5. 2
      src/src/main/java/com/my/graphiteDigesterBg/diframe/actuator/DiActPeristalticPump.java
  6. 97
      src/src/main/java/com/my/graphiteDigesterBg/diframe/connection/DiConSerialPort.java
  7. 1
      src/src/main/java/com/my/graphiteDigesterBg/task/TaskDigestion.java
  8. 4
      src/src/main/resources/application.yml

67
src/src/main/java/com/my/graphiteDigesterBg/diframe/DiActuatorBase.java

@ -1,9 +1,11 @@
package com.my.graphiteDigesterBg.diframe;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.List;
abstract public class DiActuatorBase implements DiActuator {
// message index
private static short messageIndex = 0;
// device
private DiDevice device;
// mid
@ -14,27 +16,76 @@ abstract public class DiActuatorBase implements DiActuator {
this.device = device;
}
// set enable
public void setEnable( Boolean enable ) {
this.call(DiCommand.MODULE_ENABLE, enable ? 1 : 0);
}
// execute device command
protected DiCommandResponse call( DiCommand cmd, Object... args ) {
ByteBuffer buffer = null;
String cmdMode = this.device.getEnv().getProperty("device.command.mode");
DiCommandRequest request = null;
String cmdMode = this.device.getEnv().getProperty("device.connection.mode");
if ("text".equals(cmdMode)) {
buffer = this.buildCommandBufferForTextMode(cmd, args);
request = this.buildCommandRequestForTextMode(cmd, args);
} else if ("binary".equals(cmdMode) ) {
request = this.buildCommandRequestForBinaryMode(cmd, args);
} else {
throw new RuntimeException("Unknown command mode: " + cmdMode);
}
ByteBuffer response = this.device.getConnection().call(buffer);
return new DiCommandResponse(response);
this.device.getConnection().call(request);
return new DiCommandResponse(request.response);
}
// build command buffer for text mode
private ByteBuffer buildCommandBufferForTextMode(DiCommand cmd, Object... args) {
private DiCommandRequest buildCommandRequestForTextMode(DiCommand cmd, Object... args) {
List<String> parts = new ArrayList<>();
parts.add(cmd.getName());
parts.add(this.mid.toString());
for ( Object arg : args ) {
parts.add(arg.toString());
}
String command = String.join(" ", parts);
return ByteBuffer.wrap(command.getBytes());
DiCommandRequest request = new DiCommandRequest();
request.parameter = ByteBuffer.wrap(command.getBytes());
return request;
}
// build command buffer for binary mode
private DiCommandRequest buildCommandRequestForBinaryMode(DiCommand cmd, Object... args) {
int length = 2/*PacketIndex*/ + 2/*MainCmdId*/ + 1/*SubCmdId*/ + 1/*CmdType*/ + 2/*ModuleId*/;
for ( Object param : args ) {
if ( param instanceof Integer ) {
length += 4;
} else {
throw new RuntimeException("param type error");
}
}
int cmdId = cmd.getCmdId();
int subCmdId = cmdId & 0xFF;
int mainCmdId = (cmdId >> 8) & 0xFFFF;
int moduleId = this.mid;
DiCommandRequest request = new DiCommandRequest();
request.id = DiActuatorBase.messageIndex;
request.parameter = ByteBuffer.allocate(length);
request.parameter.order(ByteOrder.LITTLE_ENDIAN);
request.parameter.putShort(DiActuatorBase.messageIndex);
request.parameter.putShort((short)mainCmdId); // main cmd id
request.parameter.put((byte)subCmdId); // sub cmd id
request.parameter.put((byte)0); // directive type
request.parameter.putShort((short)moduleId); // mid
for ( Object param : args ) {
if ( param instanceof Integer ) {
request.parameter.putInt((Integer)param);
}
}
DiActuatorBase.messageIndex ++;
if ( DiActuatorBase.messageIndex > 30000 ) {
DiActuatorBase.messageIndex = 0;
}
return request;
}
}

1
src/src/main/java/com/my/graphiteDigesterBg/diframe/DiCommand.java

@ -1,5 +1,6 @@
package com.my.graphiteDigesterBg.diframe;
public enum DiCommand {
MODULE_ENABLE("module_enable", 0x0114),
MOTOR_EASY_MOVE_BY("motor_easy_move_by", 0x0212);
// command name

16
src/src/main/java/com/my/graphiteDigesterBg/diframe/DiCommandRequest.java

@ -0,0 +1,16 @@
package com.my.graphiteDigesterBg.diframe;
import java.nio.ByteBuffer;
public class DiCommandRequest {
// message id
public short id;
// parameter
public ByteBuffer parameter;
// response
public ByteBuffer response;
// error code
public Integer errorCode = 0;
// is response received
public Boolean isResponseReceived = false;
// timeout count
public Integer timeoutCount = 0;
}

2
src/src/main/java/com/my/graphiteDigesterBg/diframe/DiDeviceConnection.java

@ -6,5 +6,5 @@ public interface DiDeviceConnection {
// connect to device
void connect();
// call device with parameter and return result
ByteBuffer call(ByteBuffer parameter);
void call(DiCommandRequest request);
}

2
src/src/main/java/com/my/graphiteDigesterBg/diframe/actuator/DiActPeristalticPump.java

@ -3,6 +3,6 @@ import com.my.graphiteDigesterBg.diframe.DiActuatorBase;
import com.my.graphiteDigesterBg.diframe.DiCommand;
public class DiActPeristalticPump extends DiActuatorBase {
public void rotate() {
this.call(DiCommand.MOTOR_EASY_MOVE_BY, 1);
this.call(DiCommand.MOTOR_EASY_MOVE_BY, 100 * 30);
}
}

97
src/src/main/java/com/my/graphiteDigesterBg/diframe/connection/DiConSerialPort.java

@ -2,12 +2,17 @@ package com.my.graphiteDigesterBg.diframe.connection;
import com.fazecast.jSerialComm.SerialPort;
import com.fazecast.jSerialComm.SerialPortDataListener;
import com.fazecast.jSerialComm.SerialPortEvent;
import com.my.graphiteDigesterBg.diframe.DiCommandRequest;
import com.my.graphiteDigesterBg.diframe.DiDevice;
import com.my.graphiteDigesterBg.diframe.DiDeviceConnection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.env.Environment;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
public class DiConSerialPort implements DiDeviceConnection {
// logger
public static final Logger LOG = LoggerFactory.getLogger(DiConSerialPort.class);
@ -15,6 +20,19 @@ public class DiConSerialPort implements DiDeviceConnection {
private DiDevice device;
// serial port connection
private SerialPort connection;
// requests
private final List<DiCommandRequest> requests;
// received data
private ByteBuffer receivedData;
// received data timer
private Timer receivedDataTimer;
// constructor
public DiConSerialPort() {
this.requests = new ArrayList<>();
this.receivedData = null;
this.receivedDataTimer = null;
}
@Override
public void setDevice(DiDevice device) {
@ -55,18 +73,83 @@ public class DiConSerialPort implements DiDeviceConnection {
// handle on data
private void handleOnData(SerialPortEvent serialPortEvent) {
if ( null != this.receivedDataTimer ) {
this.receivedDataTimer.cancel();
this.receivedDataTimer = null;
}
if ( null == this.receivedData ) {
this.receivedData = ByteBuffer.allocate(0);
}
byte[] data = serialPortEvent.getReceivedData();
System.out.println("Received data of size: " + data.length);
for (byte b : data) {
System.out.print((char)b);
ByteBuffer newBuffer = ByteBuffer.allocate(this.receivedData.capacity() + data.length);
newBuffer.put(this.receivedData).put(data);
this.receivedData = newBuffer;
TimerTask timerTask = new TimerTask() {
@Override
public void run() {
DiConSerialPort.this.handleOnDataTimeout();
}
};
this.receivedDataTimer = new Timer();
Integer frameTimeout = this.device.getEnv().getProperty("device.connection.frameTimeout", Integer.class, 1000);
this.receivedDataTimer.schedule(timerTask, frameTimeout);
}
// handle on data timeout
private void handleOnDataTimeout() {
String mode = this.device.getEnv().getProperty("device.connection.mode");
if ( "binary".equals(mode) ) {
this.handleOnDataTimeoutForBinaryMode();
} else {
throw new RuntimeException("Unknown command mode: " + mode);
}
}
// handle on data timeout for binary mode
private void handleOnDataTimeoutForBinaryMode() {
byte messageType = this.receivedData.get(5);
if ( 0x01 == messageType ) {
this.handleOnDataTimeoutForBinaryModeAckMessage();
} else {
throw new RuntimeException("unknown message type");
}
}
// handle on data timeout for binary mode ack message
private void handleOnDataTimeoutForBinaryModeAckMessage() {
short messageId = this.receivedData.getShort(0);
DiCommandRequest request = null;
for ( DiCommandRequest requestItem : this.requests ) {
if ( requestItem.id == messageId ) {
request = requestItem;
break;
}
}
if ( null == request ) {
throw new RuntimeException("unknown message id: " + messageId);
}
request.response = this.receivedData;
request.isResponseReceived = true;
this.receivedData = null;
synchronized ( request ) {
request.notify();
}
System.out.println("\n");
}
@Override
public ByteBuffer call(ByteBuffer parameter) {
byte[] data = parameter.array();
public void call(DiCommandRequest request) {
this.requests.add(request);
byte[] data = request.parameter.array();
this.connection.writeBytes(data, data.length);
return null;
synchronized ( request ) {
try {
request.wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
LOG.info("Command response received: {}", request.response);
}
}

1
src/src/main/java/com/my/graphiteDigesterBg/task/TaskDigestion.java

@ -9,6 +9,7 @@ public class TaskDigestion extends DiTaskBase {
@Override
public void run() {
DiActPeristalticPump peristalticPump = (DiActPeristalticPump)this.getDevice().getActuators().get(MyDevice.ACT_LIQUID_PERISTALTIC_PUMP);
peristalticPump.setEnable(true);
peristalticPump.rotate();
System.out.println("TaskDigestion.run()");

4
src/src/main/resources/application.yml

@ -3,5 +3,5 @@ device :
class : com.my.graphiteDigesterBg.diframe.connection.DiConSerialPort
path : COM1
baudRate : 9600
command :
mode : text # text | hex | binary
frameTimeout : 1000
mode : binary # text | hex | binary
Loading…
Cancel
Save