sige 1 year ago
parent
commit
f759c5ca2a
  1. BIN
      app.db
  2. 2
      src/main/java/com/iflytop/digester/underframework/connection/UfModbusRTUOverTCP.java
  3. 105
      src/main/java/com/iflytop/digester/underframework/connection/UfZcancmderWebsocket.java
  4. 19
      src/main/java/com/iflytop/digester/underframework/dao/model/TsMdbActuator.java
  5. 2
      src/main/java/com/iflytop/digester/underframework/dao/model/UfMdbActuatorCmd.java
  6. 4
      src/main/java/com/iflytop/digester/underframework/util/UfClassHelper.java

BIN
app.db

2
src/main/java/com/iflytop/digester/underframework/connection/UfModbusRTUOverTCP.java

@ -36,7 +36,7 @@ public class UfModbusRTUOverTCP extends UfConnectionBase {
}
@Override
public String execute(UfMdbActuatorCmd command) {
synchronized public String execute(UfMdbActuatorCmd command) {
return "";
}

105
src/main/java/com/iflytop/digester/underframework/connection/UfZcancmderWebsocket.java

@ -1,6 +1,7 @@
package com.iflytop.digester.underframework.connection;
import com.iflytop.digester.underframework.dao.model.TsMdbActuator;
import com.iflytop.digester.underframework.dao.model.UfMdbActuatorCmd;
import com.iflytop.digester.underframework.dao.record.UfActiveRecord;
import com.iflytop.digester.underframework.util.TsByteBuffer;
import com.iflytop.digester.underframework.util.UfClassHelper;
import org.java_websocket.client.WebSocketClient;
@ -19,13 +20,17 @@ public class UfZcancmderWebsocket extends UfConnectionBase {
// client
private WebSocketClient client;
// packet index
private int packetIndex = 0;
private int packetIndexCounter = 0;
// current packet index
private int currentPacketIndex = 0;
// call lock
private final Object callLock = new Object();
// response
private ByteBuffer response;
// response error
private String responseError;
// timeout timer
private Timer timeoutTimer;
@Override
public void connect() {
@ -70,6 +75,8 @@ public class UfZcancmderWebsocket extends UfConnectionBase {
returnValue = (String) UfClassHelper.invokeMethod(this, methodName, List.of(command));
} catch (NoSuchMethodException e) {
returnValue = this.executeDeviceCommand(command);
} catch (Exception e) {
throw new RuntimeException(e);
}
if ( 1 == command.waitForFinish ) {
@ -80,18 +87,32 @@ public class UfZcancmderWebsocket extends UfConnectionBase {
// execute device command
private String executeDeviceCommand( UfMdbActuatorCmd actuatorCmd ) {
this.response = null;
this.responseError = null;
this.sendCommandRequest(actuatorCmd);
synchronized (this.callLock) {
try {
this.callLock.wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
// 超时重试3次
for ( int i=0; i<3; i++ ) {
this.response = null;
this.responseError = null;
// 启动超时定时器
this.startTimeoutTimer();
// 发送数据
this.sendCommandRequest(actuatorCmd);
// 等待数据响应或超时
synchronized (this.callLock) {
try {
this.callLock.wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
if ( null != this.response ) {
break ;
}
}
if ( null == this.response ) {
var actuator = UfActiveRecord.findOne(TsMdbActuator.class, actuatorCmd.actuatorId);
throw new RuntimeException(String.format("设备 [%s] 响应超时: %s", actuator.name, actuatorCmd.cmdKey));
}
if ( null != this.responseError ) {
throw new RuntimeException(this.responseError);
}
@ -112,6 +133,22 @@ public class UfZcancmderWebsocket extends UfConnectionBase {
}
}
// start timeout timer
private void startTimeoutTimer() {
var timerTask = new TimerTask() {
@Override
public void run() {
LOG.info("[Command-Executor] timeout");
UfZcancmderWebsocket.this.timeoutTimer = null;
synchronized (UfZcancmderWebsocket.this.callLock) {
UfZcancmderWebsocket.this.callLock.notifyAll();
}
}
};
this.timeoutTimer = new Timer();
this.timeoutTimer.schedule(timerTask, 3000);
}
// send command request
private void sendCommandRequest(UfMdbActuatorCmd actuatorCmd) {
String cmd = this.buildCommand(actuatorCmd);
@ -150,7 +187,7 @@ public class UfZcancmderWebsocket extends UfConnectionBase {
int bufferSize = 2 + 2 + 1 + 1 + 2 + 4 * paramList.size(); // PacketIndex - MainCmdId - SubCmdId - CmdType - ModuleId - Parameters
ByteBuffer buffer = ByteBuffer.allocate(bufferSize);
buffer.order(ByteOrder.LITTLE_ENDIAN);
buffer.putShort((short) this.packetIndex); // PacketIndex
buffer.putShort((short) this.packetIndexCounter); // PacketIndex
buffer.putShort((short) mainCmdId); // MainCmdId
buffer.put((byte) subCmdId); // SubCmdId
buffer.put((byte) 0); // CmdType
@ -160,9 +197,10 @@ public class UfZcancmderWebsocket extends UfConnectionBase {
buffer.putInt(Integer.parseInt(param));
}
this.packetIndex ++;
if ( this.packetIndex > 30000 ) {
this.packetIndex = 0;
this.currentPacketIndex = this.packetIndexCounter;
this.packetIndexCounter++;
if ( this.packetIndexCounter > 30000 ) {
this.packetIndexCounter = 0;
}
String cmd = TsByteBuffer.toHex(buffer);
@ -174,6 +212,16 @@ public class UfZcancmderWebsocket extends UfConnectionBase {
private void handleOnTextMessage( String text ) {
ByteBuffer message = TsByteBuffer.fromHex(text);
message.order(ByteOrder.LITTLE_ENDIAN);
short packetIndex = message.getShort(0);
if ( packetIndex != this.currentPacketIndex ) {
return ; // 可能超时了, 所以忽略掉 ~~~
}
if ( null != this.timeoutTimer ) {
this.timeoutTimer.cancel();
this.timeoutTimer = null;
}
byte messageType = message.get(5);
if ( 0x01 == messageType ) { // ack message
this.handleOnTextAckMessage(message);
@ -229,4 +277,33 @@ public class UfZcancmderWebsocket extends UfConnectionBase {
}
} while ( true );
}
// cmd motor easy move to
public void cmdMotorEasyMoveTo(UfMdbActuatorCmd command) {
this.executeDeviceCommand(command);
this.waitForActuatorFinish(command);
var actuator = UfActiveRecord.findOne(TsMdbActuator.class, command.actuatorId);
var encoderAvailable = actuator.getProperty("encoderAvailable");
if ( null == encoderAvailable || !encoderAvailable.asBoolean() ) {
return ;
}
var destValue = Integer.parseInt(command.parameters);
var encoderValue = this.getActuatorEncoderValue(command);
if ( Math.abs(encoderValue - destValue) > 10 ) {
throw new RuntimeException(String.format("电机 [%s] 移动失败,目标位置:%d,当前位置:%d", actuator.name, destValue, encoderValue));
}
}
// cmd motor read enc val
private Integer getActuatorEncoderValue(UfMdbActuatorCmd srcCmd) {
var command = new UfMdbActuatorCmd();
command.actuatorId = srcCmd.actuatorId;
command.cmdId = "0219";
command.cmdKey = "motor_read_enc_val";
command.cmdFlags = srcCmd.cmdFlags;
String value = this.executeDeviceCommand(command);
return Integer.parseInt(value);
}
}

19
src/main/java/com/iflytop/digester/underframework/dao/model/TsMdbActuator.java

@ -1,4 +1,8 @@
package com.iflytop.digester.underframework.dao.model;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.iflytop.digester.deviceinstance.HeatingTurntableSlotTube;
import com.iflytop.digester.underframework.dao.record.UfActiveRecord;
import com.iflytop.digester.underframework.dao.record.UfActiveRecordField;
/*
@ -14,8 +18,23 @@ public class TsMdbActuator extends UfActiveRecord {
@UfActiveRecordField
public String name;
@UfActiveRecordField
public String properties = "{}";
// get table name
public static String getTableName() {
return "app_actuators";
}
// get property
public JsonNode getProperty(String key) {
ObjectMapper jsonMapper = new ObjectMapper();
JsonNode properties = null;
try {
properties = jsonMapper.readTree(this.properties);
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
return properties.get(key);
}
}

2
src/main/java/com/iflytop/digester/underframework/dao/model/UfMdbActuatorCmd.java

@ -24,7 +24,7 @@ public class UfMdbActuatorCmd extends UfActiveRecord {
public String fixedParameters;
@UfActiveRecordField
public String parameters;
public String parameters = "";
@UfActiveRecordField
public Integer waitForFinish;

4
src/main/java/com/iflytop/digester/underframework/util/UfClassHelper.java

@ -54,8 +54,10 @@ public class UfClassHelper {
} else {
return method.invoke(obj, args.toArray());
}
} catch (IllegalAccessException | InvocationTargetException e) {
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
} catch ( InvocationTargetException e ) {
throw new RuntimeException(e.getCause().getMessage());
}
}

Loading…
Cancel
Save