sige 1 year ago
parent
commit
8db8c95ddc
  1. BIN
      app.db
  2. 116
      src/main/java/com/iflytop/digester/DigestionTaskThread.java
  3. BIN
      src/main/java/com/iflytop/digester/camera/.vs/baslerCamera/FileContentIndex/003a4049-43a8-4685-b725-0ef981a63d09.vsidx
  4. BIN
      src/main/java/com/iflytop/digester/camera/.vs/baslerCamera/FileContentIndex/32a71717-b8c7-4106-8f15-99bbd922817c.vsidx
  5. BIN
      src/main/java/com/iflytop/digester/camera/.vs/baslerCamera/FileContentIndex/3ffb981f-6afa-4d2f-a956-f6e71b0a3ff7.vsidx
  6. BIN
      src/main/java/com/iflytop/digester/camera/.vs/baslerCamera/v17/.suo
  7. BIN
      src/main/java/com/iflytop/digester/camera/.vs/baslerCamera/v17/Browse.VC.db
  8. 2
      src/main/java/com/iflytop/digester/camera/DiComBaslerCamera.cpp
  9. 29
      src/main/java/com/iflytop/digester/controller/CameraController.java
  10. 25
      src/main/java/com/iflytop/digester/controller/TestController.java
  11. 12
      src/main/java/com/iflytop/digester/deviceinstance/LiquidAdditionInstance.java
  12. 6
      src/main/java/com/iflytop/digester/deviceinstance/TransferRobotArmInstance.java
  13. 6
      src/main/java/com/iflytop/digester/model/MdbDigestionSolution.java
  14. 9
      src/main/java/com/iflytop/digester/model/MdbDigestionTaskLog.java
  15. 38
      src/main/java/com/iflytop/digester/underframework/connection/UfZcancmderWebsocket.java
  16. 2
      src/main/resources/application-dev.yml
  17. 2
      web

BIN
app.db

116
src/main/java/com/iflytop/digester/DigestionTaskThread.java

@ -4,6 +4,7 @@ import com.iflytop.digester.model.MdbDigestionTask;
import com.iflytop.digester.model.MdbDigestionSolution; import com.iflytop.digester.model.MdbDigestionSolution;
import com.iflytop.digester.model.MdbDigestionTaskLog; import com.iflytop.digester.model.MdbDigestionTaskLog;
import com.iflytop.digester.underframework.dao.model.UfMdbNotification; import com.iflytop.digester.underframework.dao.model.UfMdbNotification;
import com.iflytop.digester.underframework.dao.model.UfMdbOption;
import com.iflytop.digester.underframework.dao.record.UfActiveRecord; import com.iflytop.digester.underframework.dao.record.UfActiveRecord;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -107,14 +108,15 @@ public class DigestionTaskThread extends Thread {
lastRound = rounds.remove(rounds.size() - 1); lastRound = rounds.remove(rounds.size() - 1);
} }
// 执行第一轮
if ( null != firstRound ) {
this.executeRound(firstRound);
}
// 执行中间轮
for (var round : rounds) {
this.executeRound(round);
}
// // 执行第一轮
// if ( null != firstRound ) {
// this.updateTaskStatus("FirstRound", "执行第一轮配置");
// this.executeRound(firstRound);
// }
// // 执行中间轮
// for (var round : rounds) {
// this.executeRound(round);
// }
// 执行最后一轮 // 执行最后一轮
if ( null != lastRound ) { if ( null != lastRound ) {
this.executeLastRound(lastRound); this.executeLastRound(lastRound);
@ -224,6 +226,7 @@ public class DigestionTaskThread extends Thread {
// 执行消解每轮配置 // 执行消解每轮配置
private void executeRound( MdbDigestionSolution.DigestionSolutionRound digestionRound ) throws InterruptedException { private void executeRound( MdbDigestionSolution.DigestionSolutionRound digestionRound ) throws InterruptedException {
this.updateTaskStatus("RoundStart", "配置轮次开始执行");
var device = Device.getInstance(); var device = Device.getInstance();
// 加液 // 加液
@ -232,6 +235,7 @@ public class DigestionTaskThread extends Thread {
for ( var liquid : digestionRound.liquids ) { for ( var liquid : digestionRound.liquids ) {
this.updateTaskStatus("Liquid", String.format("加液 %s %d", liquid.type, liquid.volume)); this.updateTaskStatus("Liquid", String.format("加液 %s %d", liquid.type, liquid.volume));
liquidAddition.addLiquidToTubes(tubes, liquid.type, liquid.volume); liquidAddition.addLiquidToTubes(tubes, liquid.type, liquid.volume);
liquidAddition.shake(digestionRound.shakingCount);
} }
// 搬运到加热转盘 // 搬运到加热转盘
@ -245,10 +249,12 @@ public class DigestionTaskThread extends Thread {
// 移至加液区 以便执行下一轮 // 移至加液区 以便执行下一轮
device.transferArm.moveTubeRackToLiquidPlate(this.heatingSlot.index); device.transferArm.moveTubeRackToLiquidPlate(this.heatingSlot.index);
this.updateTaskStatus("RoundFinish", "配置轮次执行结束");
} }
// 执行消解最后一轮配置 // 执行消解最后一轮配置
private void executeLastRound( MdbDigestionSolution.DigestionSolutionRound digestionRound ) throws InterruptedException { private void executeLastRound( MdbDigestionSolution.DigestionSolutionRound digestionRound ) throws InterruptedException {
this.updateTaskStatus("LastRound", "执行最后一轮配置开始");
this.isPrecheckFinished = false; this.isPrecheckFinished = false;
var device = Device.getInstance(); var device = Device.getInstance();
@ -257,13 +263,15 @@ public class DigestionTaskThread extends Thread {
for ( var heating : digestionRound.heatings ) { for ( var heating : digestionRound.heatings ) {
totalDurationCount += heating.duration; totalDurationCount += heating.duration;
} }
long preCheckDuration = totalDurationCount - 10;
if ( 0 >= preCheckDuration ) {
preCheckDuration = 0;
Integer preCheckTimeOption = UfMdbOption.getInteger("DigestionLastRoundPreCheckTime", 10);
long preCheckTime = totalDurationCount - preCheckTimeOption;
if ( 0 >= preCheckTime ) {
preCheckTime = 0;
} }
var preCheckTimerTask = new TimerTask() { var preCheckTimerTask = new TimerTask() {
@Override @Override
public void run() { public void run() {
DigestionTaskThread.this.updateTaskStatus("LastRoundPreCheck", "末轮预检查开始");
try { try {
// 检查试管 // 检查试管
DigestionTaskThread.this.tubeCheckAndMove(); DigestionTaskThread.this.tubeCheckAndMove();
@ -275,17 +283,22 @@ public class DigestionTaskThread extends Thread {
DigestionTaskThread.this.precheckLock.notifyAll(); DigestionTaskThread.this.precheckLock.notifyAll();
} }
} catch (Exception e) { } catch (Exception e) {
DigestionTaskThread.this.updateTaskStatus("LastRoundPreCheck", String.format("末轮预检查异常: %s", e.getMessage()));
throw new RuntimeException(e); throw new RuntimeException(e);
} finally {
DigestionTaskThread.this.updateTaskStatus("LastRoundPreCheck", "末轮预检查结束");
} }
} }
}; };
var preCheckTimer = new Timer(); var preCheckTimer = new Timer();
preCheckTimer.schedule(preCheckTimerTask, preCheckDuration * 60 * 1000);
this.updateTaskStatus("LastRound",String.format("预检将于%d秒后执行", preCheckTime * 60));
preCheckTimer.schedule(preCheckTimerTask, preCheckTime * 60 * 1000);
// 加热 // 加热
for ( var heating : digestionRound.heatings ) { for ( var heating : digestionRound.heatings ) {
this.updateTaskStatus("heating", String.format("加热 %d℃ %d分钟", heating.temperature, heating.duration));
this.updateTaskStatus("Heating", String.format("加热 %d℃ %d分钟", heating.temperature, heating.duration));
this.heatingSlot.heating(heating.temperature, heating.duration); this.heatingSlot.heating(heating.temperature, heating.duration);
this.updateTaskStatus("Heating", "加热完成");
} }
// 等待预检查完成 // 等待预检查完成
@ -298,6 +311,7 @@ public class DigestionTaskThread extends Thread {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
} }
this.updateTaskStatus("PreCheckWait", "预检完成");
} }
// 加水定容 // 加水定容
@ -318,45 +332,73 @@ public class DigestionTaskThread extends Thread {
// 释放加热位 // 释放加热位
this.heatingSlot.setTubeRackNo(null); this.heatingSlot.setTubeRackNo(null);
} }
this.updateTaskStatus("LastRound", "执行最后一轮配置结束");
} }
// 执行消解异常处理配置
/**
* 执行消解异常处理配置
* @param errorRound - 异常处理配置
* @throws InterruptedException -
*/
private void executeErrorRound( MdbDigestionSolution.DigestionSolutionErrorRound errorRound ) throws InterruptedException { private void executeErrorRound( MdbDigestionSolution.DigestionSolutionErrorRound errorRound ) throws InterruptedException {
String errorTubeIndexListStr = String.join(",", this.errorTubeIndexes.stream().map(Object::toString).toArray(String[]::new));
this.updateTaskStatus("ErrorRound", String.format("异常轮次开始 : [%s]", errorTubeIndexListStr));
var device = Device.getInstance(); var device = Device.getInstance();
var errorSlot = device.heatingTurntable.getErrorSlot();
// 移至加液区
device.transferArm.moveTubeRackToLiquidPlate(this.heatingSlot.index);
// this.updateTaskStatus("ErrorRound", "移动异常试管架至加液区");
// device.transferArm.moveTubeRackToLiquidPlate(errorSlot.index);
//
// var liquidAddition = device.liquidAddition;
// for ( var liquid : errorRound.liquids ) {
// this.updateTaskStatus("ErrorRoundLiquidAdd", String.format("异常加液 %s %d", liquid.type, liquid.volume));
// liquidAddition.addLiquidToTubes(this.errorTubeIndexes, liquid.type, liquid.volume);
// }
// this.updateTaskStatus("ErrorRoundLiquidAdd", "异常摇匀");
// liquidAddition.shake(errorRound.shakingCount);
//
// this.updateTaskStatus("ErrorRound", "移动异常试管架至加热区");
// device.transferArm.moveTubeRackToHeatingTurntable(errorSlot.index);
//
// for ( var heating : errorRound.heatings ) {
// this.updateTaskStatus("ErrorRoundHeating", String.format("异常加热 %d℃ %d分钟", heating.temperature, heating.duration));
// this.heatingSlot.heating(heating.temperature, heating.duration);
// }
//
// this.updateTaskStatus("ErrorRound", "移动异常试管架至加液区");
// device.transferArm.moveTubeRackToLiquidPlate(errorSlot.index);
// 加液
var liquidAddition = device.liquidAddition;
for ( var liquid : errorRound.liquids ) {
this.updateTaskStatus("liquid", String.format("异常加液 %s %d", liquid.type, liquid.volume));
liquidAddition.addLiquidToTubes(this.errorTubeIndexes, liquid.type, liquid.volume);
}
// 搬运到加热转盘
device.transferArm.moveTubeRackToHeatingTurntable(this.heatingSlot.index);
// 拍照检查是否存在消解完成的试管
this.takeShotAndCheckFinishedTubes();
// 加热
for ( var heating : errorRound.heatings ) {
this.updateTaskStatus("heating", String.format("异常加热 %d℃ %d分钟", heating.temperature, heating.duration));
this.heatingSlot.heating(heating.temperature, heating.duration);
// 如果不存在消解完成的试管则本轮次结束
if (this.finishedErrorTubeIndexes.isEmpty()) {
return ;
} }
// 移至加液区
device.transferArm.moveTubeRackToLiquidPlate(this.heatingSlot.index);
// 拍照检查是否存在消解完成的试管
this.takeShotAndCheckFinishedTubes();
// 将试管架放入异常处理区域
device.transferArm.moveTubeRackToHeatingTurntable(this.heatingSlot.index);
// this.updateTaskStatus("ErrorRound", "移动异常试管架至加热区");
// device.transferArm.moveTubeRackToHeatingTurntable(errorSlot.index);
// 等待放入空试管架 // 等待放入空试管架
device.door.open();
this.waitForEmptyTubeRackPutIn(); this.waitForEmptyTubeRackPutIn();
// 取出消解完成的试管
device.door.close();
String finishedTubeIndexListStr = String.join(",", this.finishedErrorTubeIndexes.stream().map(Object::toString).toArray(String[]::new));
this.updateTaskStatus("ErrorRound", String.format("取出消解完成的试管 : %s", finishedTubeIndexListStr));
device.transferArm.takeOutTubesFromErrorSlot(this.finishedErrorTubeIndexes); device.transferArm.takeOutTubesFromErrorSlot(this.finishedErrorTubeIndexes);
// 等待取出试管架 // 等待取出试管架
device.door.open();
this.waitForTubeRackTakeOut(); this.waitForTubeRackTakeOut();
device.door.close();
// 更新异常试管索引列表 // 更新异常试管索引列表
this.errorTubeIndexes.removeAll(this.finishedErrorTubeIndexes); this.errorTubeIndexes.removeAll(this.finishedErrorTubeIndexes);
String remainTubeIndexListStr = String.join(",", this.errorTubeIndexes.stream().map(Object::toString).toArray(String[]::new));
this.updateTaskStatus("ErrorRound", String.format("异常轮次执行结束, 异常试管剩余 : [%s]", remainTubeIndexListStr));
} }
// 等待放入试管架 // 等待放入试管架
@ -435,7 +477,7 @@ public class DigestionTaskThread extends Thread {
} catch (InterruptedException e) { } catch (InterruptedException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
}
} // @TODO : 这里记录下试管索引
this.updateTaskStatus("TubeCheck", "异常试管已确认"); this.updateTaskStatus("TubeCheck", "异常试管已确认");
} }

BIN
src/main/java/com/iflytop/digester/camera/.vs/baslerCamera/FileContentIndex/003a4049-43a8-4685-b725-0ef981a63d09.vsidx

BIN
src/main/java/com/iflytop/digester/camera/.vs/baslerCamera/FileContentIndex/32a71717-b8c7-4106-8f15-99bbd922817c.vsidx

BIN
src/main/java/com/iflytop/digester/camera/.vs/baslerCamera/FileContentIndex/0c5d8c00-190b-4149-adea-d196cfb732c1.vsidx → src/main/java/com/iflytop/digester/camera/.vs/baslerCamera/FileContentIndex/3ffb981f-6afa-4d2f-a956-f6e71b0a3ff7.vsidx

BIN
src/main/java/com/iflytop/digester/camera/.vs/baslerCamera/v17/.suo

BIN
src/main/java/com/iflytop/digester/camera/.vs/baslerCamera/v17/Browse.VC.db

2
src/main/java/com/iflytop/digester/camera/DiComBaslerCamera.cpp

@ -246,7 +246,7 @@ JNIEXPORT jobject JNICALL CAMERA(deviceGrabSingleFrame)(JNIEnv* env, jobject, jl
return nullptr; return nullptr;
} }
jclass javaGrabResultClass = env->FindClass("com/my/graphiteDigesterBg/diframe/component/baslerCamera/DiComBaslerCamera$GrabResult");
jclass javaGrabResultClass = env->FindClass("com/iflytop/digester/camera/DiComBaslerCamera$GrabResult");
if (javaGrabResultClass == NULL) { if (javaGrabResultClass == NULL) {
throwException(env, "unable to find java grab result class"); throwException(env, "unable to find java grab result class");
return NULL; return NULL;

29
src/main/java/com/iflytop/digester/controller/CameraController.java

@ -1,15 +1,42 @@
package com.iflytop.digester.controller; package com.iflytop.digester.controller;
import com.iflytop.digester.deviceinstance.Device;
import com.iflytop.digester.underframework.controller.UfApiControllerBase; import com.iflytop.digester.underframework.controller.UfApiControllerBase;
import com.iflytop.digester.underframework.controller.UfApiResponse; import com.iflytop.digester.underframework.controller.UfApiResponse;
import jakarta.annotation.Resource;
import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.MatOfByte;
import org.opencv.core.Rect;
import org.opencv.imgcodecs.Imgcodecs;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseBody;
import java.util.Base64;
import java.util.Map; import java.util.Map;
@Controller @Controller
public class CameraController extends UfApiControllerBase { public class CameraController extends UfApiControllerBase {
@Resource
private Device device;
@ResponseBody @ResponseBody
@PostMapping("/api/camera/take-shot") @PostMapping("/api/camera/take-shot")
public UfApiResponse takeShot() { public UfApiResponse takeShot() {
return this.success(Map.of("data", "https://avatars.githubusercontent.com/u/53512912?v=4"));
var srcImageMat = this.device.camera.grabToMat();
// 翻转图像
Mat flippedImgMat = new Mat();
Core.flip(srcImageMat, flippedImgMat, 1);
// 裁剪图像
Rect croppedRoi = new Rect(240, 120, 800, 800);
Mat croppedImgMat = new Mat(flippedImgMat, croppedRoi);
MatOfByte imageMob = new MatOfByte();
Imgcodecs.imencode(".png", croppedImgMat, imageMob);
byte[] imageBytes = imageMob.toArray();
String base64Image = Base64.getEncoder().encodeToString(imageBytes);
String base64Data = "data:image/image/png;base64," + base64Image;
return this.success(Map.of("data",base64Data));
} }
} }

25
src/main/java/com/iflytop/digester/controller/TestController.java

@ -0,0 +1,25 @@
package com.iflytop.digester.controller;
import com.iflytop.digester.deviceinstance.Device;
import com.iflytop.digester.underframework.controller.UfApiControllerBase;
import com.iflytop.digester.underframework.controller.UfApiResponse;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.List;
import java.util.Map;
@Controller
public class TestController extends UfApiControllerBase {
@Resource
private Device device;
@ResponseBody
@PostMapping("/api/test/move-tube-from-error-slot-to-liquid-plate")
public UfApiResponse moveTubeFromErrorSlotToLiquidPlate(@RequestBody Map<String,Object> params) {
List<Integer> indexes = (List<Integer>)params.get("indexes");
this.device.transferArm.takeOutTubesFromErrorSlot(indexes);
return this.success();
}
}

12
src/main/java/com/iflytop/digester/deviceinstance/LiquidAdditionInstance.java

@ -117,4 +117,16 @@ public class LiquidAdditionInstance {
} }
throw new RuntimeException("未找到对应的液体类型"); throw new RuntimeException("未找到对应的液体类型");
} }
// 摇匀
public void shake( Integer count ) {
if ( 0 == count ) {
return ;
}
UfCmdSnippetExecutor.execute("LiquidAddShakeSetup");
for ( int i=0; i<count; i++ ) {
UfCmdSnippetExecutor.execute("LiquidAddShake");
}
UfCmdSnippetExecutor.execute("LiquidAddShakeStop");
}
} }

6
src/main/java/com/iflytop/digester/deviceinstance/TransferRobotArmInstance.java

@ -22,9 +22,9 @@ public class TransferRobotArmInstance {
var snippetKey = "TubeTakeOutFromErrorSlot"; var snippetKey = "TubeTakeOutFromErrorSlot";
var snippetParams = new HashMap<String, Object>(); var snippetParams = new HashMap<String, Object>();
snippetParams.put("LiquidPlatePos", UfMdbOption.getInteger("LiquidPlateTube." + tubeIndex, 0)); snippetParams.put("LiquidPlatePos", UfMdbOption.getInteger("LiquidPlateTube." + tubeIndex, 0));
snippetParams.put("TransLrSrcPos", UfMdbOption.getInteger("HeatPlateErrorSlotTube." + tubeIndex, 0));
snippetParams.put("HeatingPlatePos", UfMdbOption.getInteger("TransLrMotorLiquidPlateTube." + tubeIndex, 0));
snippetParams.put("TransLrDestPos", UfMdbOption.getInteger("TransLrMotorHeatingPlateTube." + tubeIndex, 0));
snippetParams.put("HeatingPlatePos", UfMdbOption.getInteger("HeatPlateErrorSlotTube." + tubeIndex, 0));
snippetParams.put("TransLrSrcPos", UfMdbOption.getInteger("TransLrMotorHeatingPlateTube." + tubeIndex, 0));
snippetParams.put("TransLrDestPos", UfMdbOption.getInteger("TransLrMotorLiquidPlateTube." + tubeIndex, 0));
UfCmdSnippetExecutor.execute(snippetKey, snippetParams); UfCmdSnippetExecutor.execute(snippetKey, snippetParams);
} }
this.unlockArm(lock); this.unlockArm(lock);

6
src/main/java/com/iflytop/digester/model/MdbDigestionSolution.java

@ -42,6 +42,7 @@ public class MdbDigestionSolution extends UfActiveRecord {
liquid.volume = liquidNode.get("volume").asInt(); liquid.volume = liquidNode.get("volume").asInt();
round.liquids.add(liquid); round.liquids.add(liquid);
}); });
round.shakingCount = roundNode.get("shaking").asInt();
// 加热配置 // 加热配置
round.heatings = new ArrayList<>(); round.heatings = new ArrayList<>();
roundNode.get("heating").forEach(heatingNode -> { roundNode.get("heating").forEach(heatingNode -> {
@ -74,6 +75,7 @@ public class MdbDigestionSolution extends UfActiveRecord {
liquid.volume = liquidNode.get("volume").asInt(); liquid.volume = liquidNode.get("volume").asInt();
errorRound.liquids.add(liquid); errorRound.liquids.add(liquid);
}); });
errorRound.shakingCount = errorRoundsJsonTree.get("shaking").asInt();
// 加热配置 // 加热配置
errorRound.heatings = new ArrayList<>(); errorRound.heatings = new ArrayList<>();
errorRoundsJsonTree.get("heating").forEach(heatingNode -> { errorRoundsJsonTree.get("heating").forEach(heatingNode -> {
@ -104,6 +106,8 @@ public class MdbDigestionSolution extends UfActiveRecord {
// 加液配置 // 加液配置
public List<DigestionSolutionRoundLiquid> liquids; public List<DigestionSolutionRoundLiquid> liquids;
// 摇匀次数
public Integer shakingCount;
// 加热配置 // 加热配置
public List<DigestionSolutionRoundHeating> heatings; public List<DigestionSolutionRoundHeating> heatings;
// 加水定容 // 加水定容
@ -122,6 +126,8 @@ public class MdbDigestionSolution extends UfActiveRecord {
// 加液配置 // 加液配置
public List<DigestionSolutionErrorLiquid> liquids; public List<DigestionSolutionErrorLiquid> liquids;
// 摇匀次数
public Integer shakingCount;
// 加热配置 // 加热配置
public List<DigestionSolutionErrorHeating> heatings; public List<DigestionSolutionErrorHeating> heatings;
// 最大轮数 // 最大轮数

9
src/main/java/com/iflytop/digester/model/MdbDigestionTaskLog.java

@ -1,6 +1,10 @@
package com.iflytop.digester.model; package com.iflytop.digester.model;
import com.iflytop.digester.underframework.dao.record.UfActiveRecord; import com.iflytop.digester.underframework.dao.record.UfActiveRecord;
import com.iflytop.digester.underframework.dao.record.UfActiveRecordField; import com.iflytop.digester.underframework.dao.record.UfActiveRecordField;
import java.text.SimpleDateFormat;
import java.util.Date;
public class MdbDigestionTaskLog extends UfActiveRecord { public class MdbDigestionTaskLog extends UfActiveRecord {
@UfActiveRecordField @UfActiveRecordField
public String taskId; public String taskId;
@ -14,6 +18,9 @@ public class MdbDigestionTaskLog extends UfActiveRecord {
@UfActiveRecordField @UfActiveRecordField
public Long timestamp; public Long timestamp;
@UfActiveRecordField
public String time;
// get table name // get table name
public static String getTableName() { public static String getTableName() {
return "app_digestion_task_logs"; return "app_digestion_task_logs";
@ -26,6 +33,8 @@ public class MdbDigestionTaskLog extends UfActiveRecord {
log.action = action; log.action = action;
log.content = content; log.content = content;
log.timestamp = System.currentTimeMillis(); log.timestamp = System.currentTimeMillis();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
log.time = simpleDateFormat.format(new Date());
log.save(); log.save();
} }
} }

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

@ -158,13 +158,7 @@ public class UfZcancmderWebsocket extends UfConnectionBase {
UfMdbActuator actuator = UfMdbActuator.findOne(UfMdbActuator.class, actuatorCmd.actuatorId); UfMdbActuator actuator = UfMdbActuator.findOne(UfMdbActuator.class, actuatorCmd.actuatorId);
LOG.info(" [Command-Executor:{}] {}({}) => {}", actuator.name, actuatorCmd.cmdKey, actuatorCmd.parameters, cmd); LOG.info(" [Command-Executor:{}] {}({}) => {}", actuator.name, actuatorCmd.cmdKey, actuatorCmd.parameters, cmd);
if ( !this.client.isOpen() ) {
try {
this.client.connectBlocking();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
this.reconnectIfClosed();
TimerTask task = new TimerTask() { TimerTask task = new TimerTask() {
@Override @Override
@ -176,6 +170,36 @@ public class UfZcancmderWebsocket extends UfConnectionBase {
timer.schedule(task, 10); timer.schedule(task, 10);
} }
// reconnect if closed
private void reconnectIfClosed() {
if ( this.client.isOpen() ) {
return ;
}
var connectThread = new Thread(() -> {
do {
LOG.info("[Connection#{}] reconnecting ...", this.name);
try {
this.client.reconnectBlocking();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
} while ( true );
});
connectThread.start();
try {
connectThread.join();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
// build command // build command
private String buildCommand(UfMdbActuatorCmd actuatorCmd) { private String buildCommand(UfMdbActuatorCmd actuatorCmd) {
String params = actuatorCmd.parameters.trim(); String params = actuatorCmd.parameters.trim();

2
src/main/resources/application-dev.yml

@ -34,7 +34,7 @@ mqtt-broker:
app : app :
errorSlotIndex : 4 errorSlotIndex : 4
liquidPeristalticPumpPipeSetupEnable : true
liquidPeristalticPumpPipeSetupEnable : false
liquidPipeVolumn : 1 liquidPipeVolumn : 1
opencv-library-path: D:/ProgramFiles/OpenCV/opencv/build/java/x64/opencv_java490.dll opencv-library-path: D:/ProgramFiles/OpenCV/opencv/build/java/x64/opencv_java490.dll
pylon-library-path: D:/ProgramFiles/Pylon5/Runtime/x64/PylonC_v5_2.dll pylon-library-path: D:/ProgramFiles/Pylon5/Runtime/x64/PylonC_v5_2.dll

2
web

@ -1 +1 @@
Subproject commit 464111807ce66ce1d0f0652455cc17689d12ab7e
Subproject commit dee18622264b9391dedae06957d92d1c834b5c80
Loading…
Cancel
Save