修改为灵闪延时,

视频路径修改
增加预备代码
hubei-jinshennong
LAPTOP-S9HJSOEB\昊天 3 weeks ago
parent 21df529d49
commit d983a1939e

@ -57,11 +57,13 @@ public class EmptyCheckService {
key+="C2";
}
Street street = getStreet(transmission);
plcConnectionExample.writePlcDataTaskId(key + "-out");
log.info("transmission,{}",transmission.toString());
plcConnectionExample. writePlcDataTaskId(key + "-out");
if(street!= null){
Order order = orderMapper.getOneByStreetId(street.getId());
transmission.setUrl(transmission.getUrl().replace("E:","").replace("D:",""));
transmission.setUrl("http://"+street.getPlcIp()+":9007/api/pic"+transmission.getUrl());
order.setEndTime(LocalDateTime.now());
order.setPicPaths(order.getPicPaths()!=null ? order.getPicPaths() + "," +transmission.getUrl(): transmission.getUrl());
if (transmission.getNgBoolean()){
order.setStatus(1);

@ -904,33 +904,37 @@ public class PlcService {
try {
//执行动作
// if(times==1) {
if(times==1) {
// 暂时关掉延时使用灵闪
// Thread.sleep(configProperties.getCameraConfig().getC1DelayCaptureTime());
//
// ClientChanel.sendMessage(plcId, "C1:1");
// } else
ClientChanel.sendMessage(plcId, "C1:1");
} else
if (times==2) {
Thread.sleep(configProperties.getCameraConfig().getC2DelayCaptureTime());
// 暂时关掉延时使用灵闪延时
// Thread.sleep(configProperties.getCameraConfig().getC2DelayCaptureTime());
//C1底部拍照
log.info(plcId+" C1");
ClientChanel.sendMessage(plcId, "C1:1");
log.info(plcId+" C1 "+ taskId);
Thread.sleep(configProperties.getCameraConfig().getC3DelayCaptureTime());
Order order = orderMapper.getOneByOrderNum(plcId+"_"+taskId);
ClientChanel.sendMessage(plcId, "C3:1");
Street street = streetService.getStreetByPlcId(plcId);
String path = zlmService.stopRecord(cameraService.getById(street.getCamera1Id()));
order.setVideoPath1(path);
orderMapper.updateById(order);
}else if(times == 4){
Thread.sleep(configProperties.getCameraConfig().getC4DelayCaptureTime());
// 暂时关掉延时使用灵闪延时
// Thread.sleep(configProperties.getCameraConfig().getC4DelayCaptureTime());
ClientChanel.sendMessage(plcId, "C4:1");
}
} catch (InterruptedException e) {
throw new RuntimeException(e);
log.error("拍照报错:{}",e);
}
}
public void upStreet(KsecDataInfo dataInfo) {

@ -107,17 +107,18 @@ public class Decoder extends DelimiterBasedFrameDecoder {
//断连
ClientChanel.disConnect(transmission.getSRMNumber());
//ClientChanel.sendMessage(transmission.getSRMNumber(),transmission.getBody());
}else if("ED".equals(transmission.getHeader())){
//底部报警
emptyCheckService.visualJudgmentStatus(transmission,0);
//ClientChanel.sendMessage(transmission.getSRMNumber(),transmission.getBody());
}else if("ET".equals(transmission.getHeader())){
//顶部报警
emptyCheckService.visualJudgmentStatus(transmission,1);
//ClientChanel.sendMessage(transmission.getSRMNumber(),transmission.getBody());
}
// else if("ED".equals(transmission.getHeader())){
// //底部报警
//
// emptyCheckService.visualJudgmentStatus(transmission,0);
// //ClientChanel.sendMessage(transmission.getSRMNumber(),transmission.getBody());
// }else if("ET".equals(transmission.getHeader())){
// //顶部报警
//
// emptyCheckService.visualJudgmentStatus(transmission,1);
// //ClientChanel.sendMessage(transmission.getSRMNumber(),transmission.getBody());
// }
}
}

@ -237,6 +237,7 @@ public class PLCConnectionExample {
// 将原来的循环体逻辑提取到单独的方法中
private void processKey(Integer i, String plcId,String key) {
writePlcDataTaskId(key+"-out");
if (key.contains("C1")) {
// 推烟录像触发任务号
plcService.orderStart(i, plcId);
@ -247,13 +248,12 @@ public class PLCConnectionExample {
// 顶部拍照触发任务号
plcService.action(plcId, 4, i);
}
try {
Thread.sleep(1000);
writePlcDataTaskId(key+"-out");
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
// try {
// Thread.sleep(1000);
//
// } catch (InterruptedException e) {
// throw new RuntimeException(e);
// }
}
@ -263,6 +263,7 @@ public class PLCConnectionExample {
void server(){
// 批量读取所有C1/C2/C3地址
Map<String, Integer> dataMap = readPlcDataTaskIds();
log.info("dataMap: {} time:{}", dataMap, System.currentTimeMillis());
for (String key : dataMap.keySet()){
int i = dataMap.get(key);
@ -275,9 +276,7 @@ public class PLCConnectionExample {
String plcId = key.split("-")[0];
executorService.submit(() -> processKey(i, plcId, key));
if(key.contains("C1")){
writePlcDataTaskId(key+"-out", i);
}
}
}
}

@ -0,0 +1,372 @@
package com.zhehekeji.web.service.cron;
import com.sourceforge.snap7.moka7.S7;
import com.sourceforge.snap7.moka7.S7Client;
import io.swagger.models.auth.In;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.*;
@Slf4j
@Component
public class PLCMonitorService {
// 定义数据块和偏移量
int dbNumber = 121; // DB121
String plcIp = "10.69.105.122";
int plcRack = 0;
int plcSlot = 1;
int sizeToRead = 4; // 读取4个字节
// 地址映射
public static final Map<String, Integer> addressMap = new ConcurrentHashMap<>();
// 当前命令的上一个任务号
public static final Map<String, Integer> taskMap = new ConcurrentHashMap<>();
private final int POOL_SIZE = 5; // 连接池大小
private BlockingQueue<S7Client> connectionPool;
// 监控线程
private volatile boolean running = true;
private Thread monitorThread;
// 重启计数器
private volatile int restartCount = 0;
private static final int MAX_RESTART_COUNT = 10; // 最大重启次数
// 线程池
int corePoolSize = 15;
int maximumPoolSize = 40;
long keepAliveTime = 60;
TimeUnit unit = TimeUnit.SECONDS;
BlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<>();
ExecutorService executorService = new ThreadPoolExecutor(
corePoolSize,
maximumPoolSize,
keepAliveTime,
unit,
workQueue
);
// @PostConstruct
public void init() {
// 初始化连接池
connectionPool = new ArrayBlockingQueue<>(POOL_SIZE);
log.info("建立PLC监控连接池");
readDbConf();
// 创建连接池中的连接
for (int i = 0; i < POOL_SIZE; i++) {
S7Client client = new S7Client();
client.ConnectTo(plcIp, plcRack, plcSlot);
connectionPool.offer(client);
}
// 启动监控线程
startMonitorThread();
}
/**
* 线
*/
private void startMonitorThread() {
monitorThread = new Thread(() -> {
log.info("PLC监控线程启动");
while (running) {
try {
// 批量读取所有C1/C2/C3地址
Map<String, Integer> dataMap = readPlcDataTaskIds();
for (String key : dataMap.keySet()) {
int i = dataMap.get(key);
if (i == 0) continue;
if (taskMap.get(key) == null || taskMap.get(key) != i) {
log.info("任务号变化" + key + ":" + i);
taskMap.put(key, i);
taskMap.put(key + "-out", i);
}
}
Thread.sleep(300); // 查询间隔
} catch (InterruptedException e) {
log.info("PLC监控线程被中断");
Thread.currentThread().interrupt();
// 跳出循环后会检查是否需要重启
break;
} catch (Exception e) {
log.error("PLC监控线程异常", e);
try {
Thread.sleep(1000);
} catch (InterruptedException ie) {
Thread.currentThread().interrupt();
break;
}
}
}
log.info("PLC监控线程结束");
// 线程异常退出时,检查是否需要重启
if (running && restartCount < MAX_RESTART_COUNT) {
restartCount++;
log.warn("PLC监控线程异常退出{}秒后尝试第{}次重启", restartCount * 2, restartCount);
try {
Thread.sleep(restartCount * 2000L); // 递增延迟2s, 4s, 6s...
// 重新初始化连接池
reinitializeConnectionPool();
startMonitorThread();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
log.info("重启PLC监控线程被中断");
}
} else if (restartCount >= MAX_RESTART_COUNT) {
log.error("PLC监控线程重启次数超过上限({}),停止自动重启", MAX_RESTART_COUNT);
}
}, "PLC-Monitor-Thread");
monitorThread.setDaemon(true);
monitorThread.start();
}
/**
*
*/
private void reinitializeConnectionPool() {
log.info("重新初始化PLC连接池...");
// 清理旧连接
connectionPool.clear();
// 重建连接池
for (int i = 0; i < POOL_SIZE; i++) {
S7Client client = new S7Client();
client.ConnectTo(plcIp, plcRack, plcSlot);
connectionPool.offer(client);
}
log.info("PLC连接池重新初始化完成");
}
/**
* 线
*/
public void stopMonitor() {
running = false;
restartCount = MAX_RESTART_COUNT; // 停止自动重启
if (monitorThread != null) {
monitorThread.interrupt();
}
executorService.shutdown();
log.info("PLC监控服务已停止");
}
/**
*
*/
public S7Client getConnection() {
try {
return connectionPool.take();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new RuntimeException("获取 PLC 连接失败", e);
}
}
/**
*
*/
public void updateConnection(S7Client client) {
try {
if (client != null) {
client.Disconnect();
}
connectionPool.remove(client);
S7Client newClient = new S7Client();
int result = newClient.ConnectTo(plcIp, plcRack, plcSlot);
if (result == 0) {
connectionPool.offer(newClient);
log.info("成功创建并添加新PLC连接到连接池");
} else {
log.error("创建新PLC连接失败错误码: {}", result);
}
} catch (Exception e) {
log.error("更新PLC连接失败", e);
throw new RuntimeException("归还 PLC 连接失败", e);
}
}
/**
*
*/
public void returnConnection(S7Client client) {
try {
if (client != null && client.Connected) {
connectionPool.offer(client);
} else {
updateConnection(client);
}
} catch (Exception e) {
log.error("归还PLC连接时发生错误", e);
throw new RuntimeException("归还 PLC 连接失败", e);
}
}
/**
* s7
*/
void readDbConf() {
try (BufferedReader reader = new BufferedReader(new FileReader("./s7DB.txt"))) {
String line;
while ((line = reader.readLine()) != null) {
if (line.startsWith("#")) continue;
String[] parts = line.split(":", 2);
if (parts.length == 2) {
addressMap.put(parts[0].trim(), Integer.valueOf(parts[1].trim()));
}
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
/**
*
*/
public int readPlcDataTaskId(int startOffset) {
S7Client client = getConnection();
try {
byte[] buffer = new byte[sizeToRead];
int result = client.ReadArea(S7.S7AreaDB, dbNumber, startOffset, sizeToRead, buffer);
int i = 0;
if (result == 0) {
i = ((buffer[0] & 0xFF) << 24) |
((buffer[1] & 0xFF) << 16) |
((buffer[2] & 0xFF) << 8) |
(buffer[3] & 0xFF);
} else {
updateConnection(client);
log.info("读取失败,错误码: " + result + " 位置: " + startOffset);
}
return i;
} catch (Exception e) {
log.error("连接池报错", e);
} finally {
returnConnection(client);
}
return 0;
}
/**
*
*/
public synchronized boolean writePlcDataTaskId(String key) {
log.info("写入任务号:" + key);
int value = taskMap.get(key);
if (value == 0) {
return false;
} else {
writePlcDataTaskId(key, value);
taskMap.put(key, 0);
}
return true;
}
/**
*
*/
public boolean writePlcDataTaskId(String key, int value) {
S7Client client = getConnection();
try {
byte[] buffer = new byte[sizeToRead];
S7.SetDIntAt(buffer, 0, value);
int result = client.WriteArea(S7.S7AreaDB, dbNumber, addressMap.get(key), sizeToRead, buffer);
if (result == 0) {
log.info("写入成功" + key + ":" + value);
return true;
} else {
updateConnection(client);
log.info("写入失败,错误码: " + result);
return false;
}
} catch (Exception e) {
log.error("连接池报错", e);
} finally {
returnConnection(client);
}
return false;
}
/**
* C1/C2/C3
*/
public Map<String, Integer> readPlcDataTaskIds() {
S7Client client = getConnection();
try {
byte[] buffer = new byte[48];
int result = client.ReadArea(S7.S7AreaDB, dbNumber, 0, 48, buffer);
if (result != 0) {
updateConnection(client);
log.info("批量读取失败,错误码: " + result);
return new HashMap<>();
}
Map<String, Integer> resultMap = new HashMap<>();
for (String key : addressMap.keySet()) {
if (key.contains("out") || !key.contains("C")) {
continue;
}
int offset = addressMap.get(key);
int value = S7.GetDIntAt(buffer, offset);
resultMap.put(key, value);
}
return resultMap;
} catch (Exception e) {
log.error("批量读取异常", e);
return new HashMap<>();
} finally {
returnConnection(client);
}
}
/**
* PLC
*/
public boolean writePlcDataStatusErr(String plcId, int digit) {
if (digit == 1) {
return writePlcDataStatus((plcId + "-ET-out"), digit, true);
} else {
return writePlcDataStatus((plcId + "-ED-out"), digit, true);
}
}
/**
* PLC
*/
public boolean writePlcDataStatus(String startOffset, int digit, boolean value) {
S7Client client = getConnection();
try {
int sizeToRead = 1;
byte[] buffer = new byte[sizeToRead];
S7.SetBitAt(buffer, 0, digit, value);
int result = client.WriteArea(S7.S7AreaDB, dbNumber, addressMap.get(startOffset), sizeToRead, buffer);
if (result == 0) {
log.info("写入成功位置:" + startOffset + ":" + digit);
return true;
} else {
updateConnection(client);
log.info("写入失败,错误码: " + result);
return false;
}
} catch (Exception e) {
log.error("连接池报错", e);
} finally {
returnConnection(client);
}
return false;
}
}

@ -157,14 +157,14 @@ public class ZlmService {
String url = buildUrl(zlmApiUrl + "getMp4RecordFile", params);
String response = get(url);
log.info("getMp4RecordFiles camera:{} period:{} response:{}", camera.getId(), period, response);
// log.info("getMp4RecordFiles camera:{} period:{} response:{}", camera.getId(), period, response);
try {
Map<String, Object> result = JsonUtils.parseObject(response, Map.class);
if (result != null && Integer.parseInt(result.get("code").toString()) == 0) {
Map<String, Object> data = (Map<String, Object>) result.get("data");
String rootPath = data.get("rootPath").toString();
rootPath = rootPath.replace("E:\\\\data", "http://127.0.0.1:9007/api");
rootPath = rootPath.replace("E:\\data", "http://127.0.0.1:9007/api");
List<String> paths = (List<String>) data.get("paths");
// 构建完整路径
@ -217,14 +217,11 @@ public class ZlmService {
if (!recordFiles.isEmpty()) {
// 返回最新(最后)的录像文件
String latestFile = recordFiles.get(recordFiles.size() - 1);
log.info("获取到最新录像文件: camera:{}, file:{}", camera.getId(), latestFile);
// log.info("获取到最新录像文件: camera:{}, file:{}", camera.getId(), latestFile);
// 转换为相对路径(如果需要)
// 假设保存路径配置中的 mp4Path 是录像根目录
String basePath = configProperties.getSavePath().getMp4Path();
if (latestFile.startsWith(basePath)) {
return latestFile.substring(basePath.length());
}
return latestFile;
}
@ -240,7 +237,7 @@ public class ZlmService {
public void startRecord(Camera camera, int recordSeconds) {
// 检查是否已经在录制中
if (isRecording(camera)) {
log.warn("camera:{} 已经在录制中,", camera.getId());
log.error("camera:{} 已经在录制中,", camera.getId());
}
@ -273,7 +270,7 @@ public class ZlmService {
* @param camera
*/
public void startRecord(Camera camera) {
startRecord(camera, 15);
startRecord(camera, 10);
}
}

Loading…
Cancel
Save