From 5736eb5a6a9bb2d6ce29cd533f9dea3b0c4dd62a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?LAPTOP-S9HJSOEB=5C=E6=98=8A=E5=A4=A9?= Date: Mon, 17 Jul 2023 15:09:38 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8D=8E=E4=B8=BA=E4=BA=91=E6=8E=A5=E5=85=A5?= =?UTF-8?q?=20=E5=9B=BE=E7=89=87=E5=88=A0=E9=99=A4=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E9=80=BB=E8=BE=91=EF=BC=88=E9=87=87=E7=94=A8=E5=85=88=E5=AD=98?= =?UTF-8?q?=E6=9C=AC=E5=9C=B0=EF=BC=89=20cron=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- web/pom.xml | 19 +- .../leaper/web/config/ConfigProperties.java | 6 + .../com/leaper/web/config/SftpConfig.java | 37 ++++ .../controller/CameraControlController.java | 9 +- .../java/com/leaper/web/entity/OrderLive.java | 68 +++++++ .../java/com/leaper/web/entity/PicData.java | 23 +++ .../main/java/com/leaper/web/entity/RFID.java | 2 +- .../java/com/leaper/web/entity/Street.java | 2 +- .../leaper/web/lib/CameraControlModule.java | 6 +- .../com/leaper/web/lib/CameraDelayTask.java | 3 + .../com/leaper/web/lib/TaskDelayExecutor.java | 13 +- .../lib/hik/HikCameraControlModuleImpl.java | 21 +- .../JoywareCameraControlModuleImpl.java | 11 +- .../leaper/web/mapper/OrderLiveMapper.java | 8 + .../com/leaper/web/mapper/PicDataMapper.java | 8 + .../java/com/leaper/web/service/CronTab.java | 49 ++++- .../java/com/leaper/web/service/Demo01.java | 61 ++++++ .../com/leaper/web/service/FtpsUtils.java | 189 +++++++++++++++++ .../com/leaper/web/service/InitService.java | 8 + .../com/leaper/web/service/PlcService.java | 113 ++++++++++- .../leaper/web/service/RealTimeService.java | 2 +- .../leaper/web/service/ksec/KescFilter.java | 8 +- .../leaper/web/service/ksec/KsecDecoder.java | 186 ++++++++++++++++- .../web/service/ksec/KsecNettyClient.java | 2 +- .../leaper/web/service/sftp/SftpFactory.java | 100 +++++++++ .../leaper/web/service/sftp/SftpHelper.java | 190 ++++++++++++++++++ .../com/leaper/web/service/sftp/SftpPool.java | 45 +++++ web/src/main/resources/application-test.yml | 42 +++- .../main/resources/mapper/StreetMapper.xml | 2 +- 29 files changed, 1185 insertions(+), 48 deletions(-) create mode 100644 web/src/main/java/com/leaper/web/config/SftpConfig.java create mode 100644 web/src/main/java/com/leaper/web/entity/OrderLive.java create mode 100644 web/src/main/java/com/leaper/web/entity/PicData.java create mode 100644 web/src/main/java/com/leaper/web/mapper/OrderLiveMapper.java create mode 100644 web/src/main/java/com/leaper/web/mapper/PicDataMapper.java create mode 100644 web/src/main/java/com/leaper/web/service/Demo01.java create mode 100644 web/src/main/java/com/leaper/web/service/FtpsUtils.java create mode 100644 web/src/main/java/com/leaper/web/service/sftp/SftpFactory.java create mode 100644 web/src/main/java/com/leaper/web/service/sftp/SftpHelper.java create mode 100644 web/src/main/java/com/leaper/web/service/sftp/SftpPool.java diff --git a/web/pom.xml b/web/pom.xml index 3a6a975..02c40e6 100644 --- a/web/pom.xml +++ b/web/pom.xml @@ -18,6 +18,18 @@ + + + com.jcraft + jsch + 0.1.55 + + + + org.apache.commons + commons-pool2 + 2.6.1 + @@ -53,7 +65,12 @@ netty-all 4.1.50.Final - + + + com.hierynomus + sshj + 0.35.0 + com.alibaba diff --git a/web/src/main/java/com/leaper/web/config/ConfigProperties.java b/web/src/main/java/com/leaper/web/config/ConfigProperties.java index 7a64eb3..ba9ce6d 100644 --- a/web/src/main/java/com/leaper/web/config/ConfigProperties.java +++ b/web/src/main/java/com/leaper/web/config/ConfigProperties.java @@ -74,8 +74,14 @@ public class ConfigProperties { @Data public static class SavePath{ + private Integer saveDays = 30; private String mediaPath; private String mp4Path; + private String cloudIp; + private String cloudUser; + private String cloudPassword; + private String mp4PathCache; + private String mediaPathCache; } @Data diff --git a/web/src/main/java/com/leaper/web/config/SftpConfig.java b/web/src/main/java/com/leaper/web/config/SftpConfig.java new file mode 100644 index 0000000..5daa9ed --- /dev/null +++ b/web/src/main/java/com/leaper/web/config/SftpConfig.java @@ -0,0 +1,37 @@ +package com.leaper.web.config; + + +import com.leaper.web.service.sftp.SftpFactory; +import com.leaper.web.service.sftp.SftpHelper; +import com.leaper.web.service.sftp.SftpPool; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import javax.annotation.Resource; + +// ftp配置 +@Configuration +public class SftpConfig { + @Resource + ConfigProperties properties; + + // 工厂 + @Bean + public SftpFactory sftpFactory(ConfigProperties properties) { + return new SftpFactory(properties); + } + + // 连接池 + @Bean + public SftpPool sftpPool(SftpFactory sftpFactory) { + return new SftpPool(sftpFactory); + } + + // 辅助类 + @Bean + public SftpHelper sftpHelper(SftpPool sftpPool) { + return new SftpHelper(sftpPool); + } + +} \ No newline at end of file diff --git a/web/src/main/java/com/leaper/web/controller/CameraControlController.java b/web/src/main/java/com/leaper/web/controller/CameraControlController.java index 00f58b1..8c2e5e0 100644 --- a/web/src/main/java/com/leaper/web/controller/CameraControlController.java +++ b/web/src/main/java/com/leaper/web/controller/CameraControlController.java @@ -37,6 +37,8 @@ public class CameraControlController { @Resource private CameraControlLoginModule loginControlModule; + @Resource + ConfigProperties configProperties; @PostMapping("/{id}") @ApiOperation(value = "球机登录") public Result login(@PathVariable Integer id) { @@ -327,13 +329,12 @@ public class CameraControlController { @ApiOperation(value = "立即拍照") public Result pic(@PathVariable Integer id) { checkLogin(id); + ConfigProperties.SavePath savePath = configProperties.getSavePath(); String path = "D:\\work\\"+LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))+".jpeg"; - TaskDelayExecutor.addPicDelayTask(id,path,2000L); + TaskDelayExecutor.addPicDelayTask(id,path,2000L,savePath); return Result.success(); } - @Resource - private ConfigProperties configProperties; @Resource private PlcService plcService; @@ -355,7 +356,7 @@ public class CameraControlController { public Result MP4(@PathVariable Integer id) { checkLogin(id); LocalDateTime localDateTime = LocalDateTime.of(2022,7,21,8,20); - cameraControlModule.downloadMp4(id,"E:\\work\\"+localDateTime.format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))+".mp4", localDateTime,localDateTime.plusMinutes(3)); + cameraControlModule.downloadMp4(id,"E:\\work\\"+localDateTime.format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))+".mp4", localDateTime,localDateTime.plusMinutes(3),configProperties.getSavePath()); return Result.success(); } diff --git a/web/src/main/java/com/leaper/web/entity/OrderLive.java b/web/src/main/java/com/leaper/web/entity/OrderLive.java new file mode 100644 index 0000000..72411d4 --- /dev/null +++ b/web/src/main/java/com/leaper/web/entity/OrderLive.java @@ -0,0 +1,68 @@ +package com.leaper.web.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.time.LocalDateTime; + +@Data +@TableName("`order_live`") +public class OrderLive { + + + @TableId(type = IdType.AUTO) + private Integer id; + private Integer streetId; + + @ApiModelProperty("订单号") + private String orderNum; + + @ApiModelProperty("0:正常 1:告警") + private Integer status; + + /** + * 前两个命令 库内?库口? 1:库内 2:库口 + */ + private Integer inOut; + + /** + * 前两个命令 左?右? 1:左 2:右 + */ + private Integer leftRight; + + /** + * 前两个 列号 + */ + @TableField("`column`") + private Integer column; + + /** + * 前两个 行号 + */ + @TableField("`row`") + private Integer row; + @ApiModelProperty("图片地址,分隔") + private String picPaths; + +// @ApiModelProperty("入库照片") +// private String putPath; +// +// @ApiModelProperty("出库照片") +// private String outputPath; +// +// @ApiModelProperty("货位照片") +// private String goodsPath; + + @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss") + private LocalDateTime startTime; + + @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss") + private LocalDateTime endTime; + @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss") + private LocalDateTime updateTime; +} diff --git a/web/src/main/java/com/leaper/web/entity/PicData.java b/web/src/main/java/com/leaper/web/entity/PicData.java new file mode 100644 index 0000000..07339b2 --- /dev/null +++ b/web/src/main/java/com/leaper/web/entity/PicData.java @@ -0,0 +1,23 @@ +package com.leaper.web.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; + +import java.time.LocalDateTime; + +@Data +public class PicData { + + @TableId(type = IdType.AUTO) + private Integer id; + + private String url; + + private String type; + + @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss") + private LocalDateTime createTime; + +} diff --git a/web/src/main/java/com/leaper/web/entity/RFID.java b/web/src/main/java/com/leaper/web/entity/RFID.java index 994cfe1..017951f 100644 --- a/web/src/main/java/com/leaper/web/entity/RFID.java +++ b/web/src/main/java/com/leaper/web/entity/RFID.java @@ -6,7 +6,7 @@ import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; @Data -@TableName("RFID") +@TableName("rfid") public class RFID { @TableId(type = IdType.AUTO) diff --git a/web/src/main/java/com/leaper/web/entity/Street.java b/web/src/main/java/com/leaper/web/entity/Street.java index 3fa1534..44881d6 100644 --- a/web/src/main/java/com/leaper/web/entity/Street.java +++ b/web/src/main/java/com/leaper/web/entity/Street.java @@ -61,5 +61,5 @@ public class Street { /** * 库区 */ - private String area; + //private String area; } diff --git a/web/src/main/java/com/leaper/web/lib/CameraControlModule.java b/web/src/main/java/com/leaper/web/lib/CameraControlModule.java index e10d205..a81b2fd 100644 --- a/web/src/main/java/com/leaper/web/lib/CameraControlModule.java +++ b/web/src/main/java/com/leaper/web/lib/CameraControlModule.java @@ -1,5 +1,7 @@ package com.leaper.web.lib; +import com.leaper.web.config.ConfigProperties; + import java.time.LocalDateTime; public interface CameraControlModule { @@ -104,9 +106,9 @@ public interface CameraControlModule { boolean ptzControlIrisDecEnd(Integer cameraId, int nChannelID); - boolean pic(Integer cameraId, int channel, String realPath); + boolean pic(Integer cameraId, int channel, String realPath, ConfigProperties.SavePath savePath); - void downloadMp4(Integer cameraId, String path, LocalDateTime start, LocalDateTime end); + void downloadMp4(Integer cameraId, String path, LocalDateTime start, LocalDateTime end, ConfigProperties.SavePath savePath); /** * 设置预置点 diff --git a/web/src/main/java/com/leaper/web/lib/CameraDelayTask.java b/web/src/main/java/com/leaper/web/lib/CameraDelayTask.java index fd7f470..cd6580a 100644 --- a/web/src/main/java/com/leaper/web/lib/CameraDelayTask.java +++ b/web/src/main/java/com/leaper/web/lib/CameraDelayTask.java @@ -1,5 +1,6 @@ package com.leaper.web.lib; +import com.leaper.web.config.ConfigProperties; import lombok.AllArgsConstructor; import lombok.Data; @@ -17,6 +18,8 @@ public class CameraDelayTask implements Delayed { private LocalDateTime endTime; + private ConfigProperties configProperties; + private String path; /** diff --git a/web/src/main/java/com/leaper/web/lib/TaskDelayExecutor.java b/web/src/main/java/com/leaper/web/lib/TaskDelayExecutor.java index 691f256..bfacfaa 100644 --- a/web/src/main/java/com/leaper/web/lib/TaskDelayExecutor.java +++ b/web/src/main/java/com/leaper/web/lib/TaskDelayExecutor.java @@ -1,6 +1,7 @@ package com.leaper.web.lib; import com.leaper.common.util.SpringContextUtil; +import com.leaper.web.config.ConfigProperties; import java.time.LocalDateTime; import java.util.concurrent.DelayQueue; @@ -13,13 +14,17 @@ public class TaskDelayExecutor { private static DelayQueue queue = new DelayQueue<>(); - public static void addMp4DelayTask(Integer cameraId, String path, LocalDateTime startTime, LocalDateTime endTime, Long delayTime) { + public static void addMp4DelayTask(Integer cameraId, String path, LocalDateTime startTime, LocalDateTime endTime, Long delayTime, ConfigProperties.SavePath savePath) { CameraDelayTask cameraDelayTask = new CameraDelayTask(cameraId, startTime, endTime,path, 0,delayTime); + cameraDelayTask.setConfigProperties(new ConfigProperties()); + cameraDelayTask.getConfigProperties().setSavePath(savePath); queue.add(cameraDelayTask); } - public static void addPicDelayTask(Integer cameraId, String path, Long delayTime) { + public static void addPicDelayTask(Integer cameraId, String path, Long delayTime, ConfigProperties.SavePath savePath) { CameraDelayTask cameraDelayTask = new CameraDelayTask(cameraId, null, null,path, 1,delayTime); + cameraDelayTask.setConfigProperties(new ConfigProperties()); + cameraDelayTask.getConfigProperties().setSavePath(savePath); queue.add(cameraDelayTask); } @@ -45,9 +50,9 @@ public class TaskDelayExecutor { if(cameraDelayTask.getType() == 0){ - cameraControlModule.downloadMp4(cameraDelayTask.getCameraId(), cameraDelayTask.getPath(), cameraDelayTask.getStartTime(), cameraDelayTask.getEndTime()); + cameraControlModule.downloadMp4(cameraDelayTask.getCameraId(), cameraDelayTask.getPath(), cameraDelayTask.getStartTime(), cameraDelayTask.getEndTime(),cameraDelayTask.getConfigProperties().getSavePath()); }else if(cameraDelayTask.getType() == 1){ - cameraControlModule.pic(cameraDelayTask.getCameraId(),0, cameraDelayTask.getPath()); + cameraControlModule.pic(cameraDelayTask.getCameraId(),0, cameraDelayTask.getPath(),cameraDelayTask.getConfigProperties().getSavePath()); }else if(cameraDelayTask.getType() == 2){ cameraControlModule.toPtz(cameraDelayTask.getPtzId(),cameraDelayTask.getCameraId()); } diff --git a/web/src/main/java/com/leaper/web/lib/hik/HikCameraControlModuleImpl.java b/web/src/main/java/com/leaper/web/lib/hik/HikCameraControlModuleImpl.java index f877174..1f75f28 100644 --- a/web/src/main/java/com/leaper/web/lib/hik/HikCameraControlModuleImpl.java +++ b/web/src/main/java/com/leaper/web/lib/hik/HikCameraControlModuleImpl.java @@ -1,7 +1,10 @@ package com.leaper.web.lib.hik; +import com.leaper.common.util.SpringContextUtil; +import com.leaper.web.config.ConfigProperties; import com.leaper.web.lib.CameraConnMap; import com.leaper.web.lib.joyware.NetSDKLib; +import com.leaper.web.service.FtpsUtils; import com.sun.jna.ptr.IntByReference; import com.leaper.common.util.PathUtil; import com.zhehekeji.core.util.Assert; @@ -237,7 +240,7 @@ public class HikCameraControlModuleImpl implements CameraControlModule { return ok; } - public boolean pic(Integer cameraId, int nChannelID, String path) + public boolean pic(Integer cameraId, int nChannelID, String path, ConfigProperties.SavePath savePath) { PathUtil.checkDirc(path); int lUserId = CameraConnMap.getConnId(cameraId).intValue(); @@ -248,11 +251,14 @@ public class HikCameraControlModuleImpl implements CameraControlModule { if (!picResult) { log.error("pic error:{},cameraId:{}", HikLoginModuleImpl.hcNetsdk.NET_DVR_GetLastError(),cameraId); } + //上传到云服务器 + FtpsUtils ftpsUtils = SpringContextUtil.getBean(FtpsUtils.class); + ftpsUtils.moveFile(true,10, path,savePath.getMediaPath() + path.replace(savePath.getMediaPathCache(),"")); return picResult; } - public void downloadMp4(Integer cameraId, String path, LocalDateTime start, LocalDateTime end) { + public void downloadMp4(Integer cameraId, String path, LocalDateTime start, LocalDateTime end, ConfigProperties.SavePath savePath) { PathUtil.checkDirc(path); HCNetSDK.NET_DVR_TIME startTime = new HCNetSDK.NET_DVR_TIME(); @@ -269,8 +275,9 @@ public class HikCameraControlModuleImpl implements CameraControlModule { } else { HikLoginModuleImpl.hcNetsdk.NET_DVR_PlayBackControl(result, HikLoginModuleImpl.hcNetsdk.NET_DVR_PLAYSTART,0,null); Timer downloadtimer = new Timer(); - downloadtimer.schedule(new DownloadTask(result,downloadtimer,path,cameraId), 0, 5000); + downloadtimer.schedule(new DownloadTask(result,downloadtimer,path,cameraId,savePath), 0, 5000); } + } class DownloadTask extends java.util.TimerTask { @@ -279,11 +286,13 @@ public class HikCameraControlModuleImpl implements CameraControlModule { private Integer cameraId; private String path; - public DownloadTask(Integer handler,Timer downloadtimer,String path,int cameraId){ + private ConfigProperties.SavePath savePath; + public DownloadTask(Integer handler,Timer downloadtimer,String path,int cameraId,ConfigProperties.SavePath savePath){ this.handler = handler; this.cameraId = cameraId; this.downloadtimer = downloadtimer; this.path = path; + this.savePath = savePath; } //定时器函数 @Override @@ -308,6 +317,10 @@ public class HikCameraControlModuleImpl implements CameraControlModule { PathUtil.deleteFile(path); File file = new File(ffmpegFile); file.renameTo(new File(path)); + + //上传到云服务器 + FtpsUtils ftpsUtils = SpringContextUtil.getBean(FtpsUtils.class); + ftpsUtils.moveFile(true,10, path,savePath.getMp4Path() + path.replace(savePath.getMp4PathCache(),"")); }else { log.debug("cameraId:{},progress:{}",cameraId,nPos.getValue()); } diff --git a/web/src/main/java/com/leaper/web/lib/joyware/JoywareCameraControlModuleImpl.java b/web/src/main/java/com/leaper/web/lib/joyware/JoywareCameraControlModuleImpl.java index 2a8e5d7..7650626 100644 --- a/web/src/main/java/com/leaper/web/lib/joyware/JoywareCameraControlModuleImpl.java +++ b/web/src/main/java/com/leaper/web/lib/joyware/JoywareCameraControlModuleImpl.java @@ -1,6 +1,9 @@ package com.leaper.web.lib.joyware; +import com.leaper.common.util.SpringContextUtil; +import com.leaper.web.config.ConfigProperties; import com.leaper.web.lib.CameraConnMap; +import com.leaper.web.service.FtpsUtils; import com.sun.jna.ptr.IntByReference; import com.leaper.common.util.PathUtil; import com.zhehekeji.core.util.Assert; @@ -255,7 +258,7 @@ public class JoywareCameraControlModuleImpl implements CameraControlModule { 0, 0, 0, 1); } - public boolean pic(Integer cameraId,int channel, String realPath) { + public boolean pic(Integer cameraId,int channel, String realPath, ConfigProperties.SavePath savePath) { NetSDKLib.SNAP_PARAMS stuSnapParams = new NetSDKLib.SNAP_PARAMS(); stuSnapParams.Channel = 0; // channel stuSnapParams.mode = 0; // capture picture mode @@ -267,10 +270,14 @@ public class JoywareCameraControlModuleImpl implements CameraControlModule { if (!ok) { log.error("pic error :{},cameraId:{}", ToolKits.getErrorCodePrint(),cameraId); } + //上传到云服务器 + + FtpsUtils ftpsUtils = SpringContextUtil.getBean(FtpsUtils.class); + ftpsUtils.moveFile(true,10,savePath.getMp4PathCache() + realPath,savePath.getMp4Path() + realPath); return ok; } - public void downloadMp4(Integer cameraId, String path, LocalDateTime start, LocalDateTime end) { + public void downloadMp4(Integer cameraId, String path, LocalDateTime start, LocalDateTime end, ConfigProperties.SavePath savePath) { PathUtil.checkDirc(path); NetSDKLib.NET_TIME startTime = new NetSDKLib.NET_TIME(); diff --git a/web/src/main/java/com/leaper/web/mapper/OrderLiveMapper.java b/web/src/main/java/com/leaper/web/mapper/OrderLiveMapper.java new file mode 100644 index 0000000..2f10238 --- /dev/null +++ b/web/src/main/java/com/leaper/web/mapper/OrderLiveMapper.java @@ -0,0 +1,8 @@ +package com.leaper.web.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.leaper.web.entity.LightSource; +import com.leaper.web.entity.OrderLive; + +public interface OrderLiveMapper extends BaseMapper { +} diff --git a/web/src/main/java/com/leaper/web/mapper/PicDataMapper.java b/web/src/main/java/com/leaper/web/mapper/PicDataMapper.java new file mode 100644 index 0000000..2c20706 --- /dev/null +++ b/web/src/main/java/com/leaper/web/mapper/PicDataMapper.java @@ -0,0 +1,8 @@ +package com.leaper.web.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.leaper.web.entity.PicData; + + +public interface PicDataMapper extends BaseMapper { +} diff --git a/web/src/main/java/com/leaper/web/service/CronTab.java b/web/src/main/java/com/leaper/web/service/CronTab.java index 3c6c4ae..11eba80 100644 --- a/web/src/main/java/com/leaper/web/service/CronTab.java +++ b/web/src/main/java/com/leaper/web/service/CronTab.java @@ -1,13 +1,20 @@ package com.leaper.web.service; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.jcraft.jsch.ChannelSftp; +import com.jcraft.jsch.SftpATTRS; import com.leaper.web.config.ConfigProperties; import com.leaper.web.entity.LightSource; +import com.leaper.web.entity.OrderLive; +import com.leaper.web.entity.PicData; import com.leaper.web.mapper.LightSourceMapper; +import com.leaper.web.mapper.OrderLiveMapper; +import com.leaper.web.mapper.PicDataMapper; import com.leaper.web.service.damLightSource.JYDAMEquip; import com.leaper.web.service.damLightSource.JYDamHelper; import com.leaper.web.service.hikLightSource.HikControlSocket; import lombok.extern.slf4j.Slf4j; +import net.schmizz.sshj.sftp.SFTPClient; import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; @@ -34,6 +41,13 @@ public class CronTab { private ConfigProperties configProperties; @Resource private LightSourceMapper lightSourceMapper; + @Resource + FtpsUtils ftpsUtils; + @Resource + PicDataMapper picDataMapper; + @Resource + OrderLiveMapper orderLiveMapper; + private static LocalDateTime now; @@ -44,20 +58,35 @@ public class CronTab { private static int gByte = 1024* 1024 * 1024; - @Scheduled(cron = "0 0 0 * * ?") + @Scheduled(cron = "${savePath.deleteSaveCron}") //@Scheduled(cron = "0 0/1 * * * *") public void file() { log.info(" corn delete file"); - now = LocalDateTime.now(); - File dir = new File(configProperties.getSavePath().getMediaPath()); - long space = dir.getFreeSpace() / gByte; - log.info(" free space :{}",space); - if(space > 150){ - return; + //照片删除 + LocalDateTime localDateTime = LocalDateTime.now(); + localDateTime = localDateTime.minusDays(configProperties.getSavePath().getSaveDays()); + List picDataList = picDataMapper.selectList(new QueryWrapper() + //.eq("type","2") + .lt("create_time",localDateTime)); + List orderLives = orderLiveMapper.selectList(new QueryWrapper<>()); + for (PicData picData : picDataList) { + if ("2".equals(picData.getType())) { + boolean isLast = false; + for (OrderLive orderLive : orderLives) { + if (orderLive.getPicPaths().contains(picData.getUrl().substring(picData.getUrl().lastIndexOf("/")))) { + isLast = true; + break; + } + } + if (!isLast) { + picDataMapper.deleteById(picData.getId()); + ftpsUtils.deleteFile(picData.getUrl()); + } + } else { + picDataMapper.deleteById(picData.getId()); + ftpsUtils.deleteFile(picData.getUrl()); + } } - checkFileTime(dir,configProperties.getDeleteFileDays()); - File dir2 = new File(configProperties.getSavePath().getMp4Path()); - checkFileTime(dir2,configProperties.getDeleteFileDays()); } public static void putTime(Integer streetId){ diff --git a/web/src/main/java/com/leaper/web/service/Demo01.java b/web/src/main/java/com/leaper/web/service/Demo01.java new file mode 100644 index 0000000..591bf0a --- /dev/null +++ b/web/src/main/java/com/leaper/web/service/Demo01.java @@ -0,0 +1,61 @@ +package com.leaper.web.service; + +import com.sun.management.OperatingSystemMXBean; + +import java.io.File; +import java.io.IOException; +import java.lang.management.ManagementFactory; +import java.text.DecimalFormat; + +/** + * @author layman + */ +public class Demo01 { + public static void main(String[] args) throws IOException { + getDiskInfo(); + getMemoryInfo(); + } + /** + * 获取系统各个硬盘的总容量、已经使用的容量、剩余容量和使用率 + * @throws IOException + */ + public static void getDiskInfo() throws IOException { + DecimalFormat df = new DecimalFormat("#0.00"); + File[] disks = File.listRoots(); + for (File file : disks) { + // 获取盘符 + System.out.print(file.getCanonicalPath() + " "); + // 获取总容量 + long totalSpace = file.getTotalSpace(); + // 获取剩余容量 + long usableSpace = file.getUsableSpace(); + // 获取已经使用的容量 + long freeSpace = totalSpace - usableSpace; + // 获取使用率 + float useRate = (float)((freeSpace * 1.0 / totalSpace) * 100); + System.out.print("总容量: " + transformation(totalSpace)); + System.out.print("已经使用: " + transformation(freeSpace)); + System.out.print("剩余容量: " + transformation(usableSpace)); + System.out.println("使用率: " + Double.parseDouble(df.format(useRate)) + "% "); + } + } + /** + * 获取内存使用情况 + */ + public static void getMemoryInfo() { + OperatingSystemMXBean mem = (OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean(); + // 获取内存总容量 + long totalMemorySize = mem.getTotalPhysicalMemorySize(); + // 获取可用内存容量 + long freeMemorySize = mem.getFreePhysicalMemorySize(); + System.out.println("内存总容量:" + transformation(totalMemorySize) ); + System.out.println("可用容量:" + transformation(freeMemorySize)); + } + /** + * 将字节容量转化为GB + */ + public static String transformation(long size){ + return size / 1024 / 1024 / 1024 + "GB"+" "; + } +} + diff --git a/web/src/main/java/com/leaper/web/service/FtpsUtils.java b/web/src/main/java/com/leaper/web/service/FtpsUtils.java new file mode 100644 index 0000000..7e43af0 --- /dev/null +++ b/web/src/main/java/com/leaper/web/service/FtpsUtils.java @@ -0,0 +1,189 @@ +package com.leaper.web.service; + +import com.jcraft.jsch.ChannelSftp; +import com.leaper.web.config.ConfigProperties; +import com.leaper.web.entity.PicData; +import com.leaper.web.mapper.PicDataMapper; +import com.leaper.web.service.sftp.SftpHelper; +import lombok.extern.slf4j.Slf4j; +import net.schmizz.sshj.SSHClient; +import net.schmizz.sshj.common.SSHException; +import net.schmizz.sshj.connection.ConnectionException; +import net.schmizz.sshj.sftp.FileAttributes; +import net.schmizz.sshj.sftp.SFTPClient; +import net.schmizz.sshj.transport.verification.PromiscuousVerifier; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; +import java.io.File; +import java.io.IOException; +import java.net.ConnectException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.attribute.BasicFileAttributes; +import java.time.Duration; +import java.time.Instant; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.util.List; + +/** + * https://github.com/hierynomus/sshj + * + * @author qing-feng.zhao + * @Sees https://stackoverflow.com/questions/14617/how-to-retrieve-a-file-from-a-server-via-sftp + */ +@Slf4j +@Component +public class FtpsUtils { + + @Resource + ConfigProperties configProperties; + @Resource + PicDataMapper picDataMapper; + @Resource + SftpHelper sftpHelper; + + + public static void main(String[] args) { + SSHClient ssh = new SSHClient(); + SFTPClient sftpClient = null; + try { + //ssh.loadKnownHosts(); to skip host verification + ssh.addHostKeyVerifier(new PromiscuousVerifier()); + ssh.connect("121.37.95.190"); + ssh.authPassword("root", "Leaper@123"); + sftpClient = ssh.newSFTPClient(); + + FileAttributes f = sftpClient.stat("/mnt/media/1/1-47/20230717/20230717165726-11-47.jpg"); + System.out.println("1111"); + //create a folder + //sftpClient.mkdir("/data"); + //sftpClient.rmdir("");重命名文件夹 + //List s = sftpClient.ls("/"); //列出当前目录 + //System.out.println(s); + } catch (Exception e) { + log.error(e.getMessage(), e); + } finally { + + } + } + + public boolean isExistSftp(String targetFilePath) { + return sftpHelper.isExist(targetFilePath); + } + + + public void moveFile(boolean flag ,int count, + String srcFilePath, + String targetFilePath) { + try { + //ssh.loadKnownHosts(); to skip host verification + if(isExistSftp(targetFilePath)){ + flag = false; + return; + } + sftpHelper.mkdirs(targetFilePath.substring(0,targetFilePath.lastIndexOf("/")));//创建多级文件夹 + sftpHelper.put(srcFilePath, targetFilePath); + log.info("sftp新建文件:"+targetFilePath); + File file = new File(srcFilePath); + PicData picData = new PicData(); + if(srcFilePath.contains("mp4")){ + picData.setType("1"); + }else { + picData.setType("2"); + } + picData.setUrl(targetFilePath); + picData.setCreateTime(LocalDateTime.now()); + picDataMapper.insert(picData); + //deleteFileSrc(file); + //create a folder + //sftpClient.mkdir("/data"); + //sftpClient.rmdir("");重命名文件夹 + //List s = sftpClient.ls("/"); //列出当前目录 + //System.out.println(s); + } catch (Exception e) { + log.error(e.getMessage(), e); + try { + if(flag && count!=0){ + Thread.sleep(10000); + + count = --count ; + + moveFile(true,count,srcFilePath, targetFilePath); + } + } catch (InterruptedException ee) { + throw new RuntimeException(ee); + } + } + } + + /** + * 删除文件,如果文件夹没有文件同步删除文件夹 + * @param dir + */ + public void deleteFile(String dir) { + sftpHelper.delete(dir); + String path = dir.substring(0,dir.lastIndexOf("/")); + List list = sftpHelper.ls(path); + if(list.size() == 2){ + sftpHelper.rmdir(path); + } + } + + + public void deleteFileSrc(File dir) { + if (!dir.exists()) { + return; + } + if (dir.isDirectory()) { + String[] children = dir.list(); + if (children.length == 0) { + log.info("delete path:{}", dir.getPath()); + dir.delete(); + } + } else { + //判斷時間 + dir.delete(); + } + } +// } +// public void deleteFile(){ +// SSHClient ssh = new SSHClient(); +// SFTPClient sftpClient = null; +// try { +// //ssh.loadKnownHosts(); to skip host verification +// ssh.addHostKeyVerifier(new PromiscuousVerifier()); +// ssh.connect(this.hostName); +// ssh.authPassword(username, password); +// sftpClient = ssh.newSFTPClient(); +// +// sftpClient.mkdirs(targetFilePath.substring(0,targetFilePath.lastIndexOf("/")));//创建多级文件夹 +// sftpClient.rm( targetFilePath); +// //create a folder +// //sftpClient.mkdir("/data"); +// //sftpClient.rmdir("");重命名文件夹 +// //List s = sftpClient.ls("/"); //列出当前目录 +// //System.out.println(s); +// } catch (IOException e) { +// log.error(e.getMessage(), e); +// } finally { +// if (null != sftpClient) { +// try { +// sftpClient.close(); +// } catch (IOException e) { +// log.error(e.getMessage(), e); +// } +// } +// try { +// ssh.disconnect(); +// } catch (IOException e) { +// log.error(e.getMessage(), e); +// } +// } +// } + + +} diff --git a/web/src/main/java/com/leaper/web/service/InitService.java b/web/src/main/java/com/leaper/web/service/InitService.java index f82add1..f9b6742 100644 --- a/web/src/main/java/com/leaper/web/service/InitService.java +++ b/web/src/main/java/com/leaper/web/service/InitService.java @@ -1,5 +1,6 @@ package com.leaper.web.service; +import com.leaper.common.util.SpringContextUtil; import com.leaper.filter.aspect.LPLicense; import com.leaper.web.lib.CameraControlLoginModule; import com.leaper.web.lib.CameraControlModule; @@ -17,12 +18,17 @@ import com.leaper.web.mapper.StreetMapper; import com.leaper.web.service.ksec.KsecNettyClient; import com.leaper.web.service.robotic.NettyClient; import lombok.extern.slf4j.Slf4j; +import net.schmizz.sshj.SSHClient; +import net.schmizz.sshj.sftp.SFTPClient; +import net.schmizz.sshj.transport.verification.PromiscuousVerifier; +import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.ApplicationArguments; import org.springframework.boot.ApplicationRunner; import org.springframework.context.annotation.Bean; import org.springframework.stereotype.Component; import javax.annotation.Resource; +import java.io.IOException; import java.util.HashMap; import java.util.List; @@ -64,6 +70,8 @@ public class InitService implements ApplicationRunner { return cameraControlLoginModule; } + + @Bean public CameraControlModule cameraControlModule(ConfigProperties configProperties){ CameraControlModule cameraControlModule = null; diff --git a/web/src/main/java/com/leaper/web/service/PlcService.java b/web/src/main/java/com/leaper/web/service/PlcService.java index 351ec94..9674cd5 100644 --- a/web/src/main/java/com/leaper/web/service/PlcService.java +++ b/web/src/main/java/com/leaper/web/service/PlcService.java @@ -17,6 +17,7 @@ import com.leaper.web.pojo.OrderVO; import com.leaper.web.service.RFID.RFIDMap; import com.leaper.web.service.hikLightSource.HikControlSocket; import lombok.extern.slf4j.Slf4j; +import org.aspectj.weaver.ast.Or; import org.springframework.beans.BeanUtils; import org.springframework.stereotype.Service; import org.springframework.util.StringUtils; @@ -24,6 +25,8 @@ import org.springframework.util.StringUtils; import javax.annotation.Resource; import java.time.Duration; import java.time.LocalDateTime; +import java.util.Arrays; +import java.util.LinkedList; import java.util.List; import java.util.Set; import java.util.concurrent.ArrayBlockingQueue; @@ -43,6 +46,8 @@ public class PlcService { @Resource private OrderMapper orderMapper; @Resource + private OrderLiveMapper orderLiveMapper; + @Resource private StockMapper stockMapper; @Resource private StreetMapper streetMapper; @@ -69,6 +74,8 @@ public class PlcService { @Resource private SensorService sensorService; @Resource + private FtpsUtils ftpsUtils; + @Resource private RFIDService rfidService; @Resource private CheckLogMapper checkLogMapper; @@ -172,6 +179,64 @@ public class PlcService { update.setVideoPath2(path); } orderMapper.updateById(update); + orderLiveInsert(orderMapper.selectById(order.getId())); + } + + void orderLiveInsert(Order oldOrder ){ + LinkedList picPaths = new LinkedList<>(Arrays.asList(oldOrder.getPicPaths().split(","))); + //旧库 + OrderLive orderInLiveOld = orderLiveMapper.selectOne(new QueryWrapper() + .eq("street_id",oldOrder.getStreetId()) + .eq("`row`",oldOrder.getRow1()) + .eq("`column`",oldOrder.getColumn1()) + .eq("in_out",oldOrder.getInOut1()) + .eq("left_right",oldOrder.getLeftRight1())); + OrderLive orderInLive = new OrderLive(); + orderInLive.setOrderNum(oldOrder.getOrderNum()); + orderInLive.setColumn(oldOrder.getColumn1()); + orderInLive.setRow(oldOrder.getRow1()); + orderInLive.setStatus(oldOrder.getStatus()); + orderInLive.setInOut(oldOrder.getInOut1()); + orderInLive.setLeftRight(oldOrder.getLeftRight1()); + orderInLive.setStreetId(oldOrder.getStreetId()); + orderInLive.setEndTime(oldOrder.getEndTime()); + orderInLive.setStartTime(oldOrder.getStartTime()); + if(picPaths.size()>=2){ + orderInLive.setPicPaths(picPaths.poll()+","+picPaths.poll()); + } + if(orderInLiveOld != null){ + orderInLive.setId(orderInLiveOld.getId()); + orderLiveMapper.updateById(orderInLive); + }else { + orderLiveMapper.insert(orderInLive); + } + + //新库 + OrderLive orderOutLiveOld = orderLiveMapper.selectOne(new QueryWrapper() + .eq("street_id",oldOrder.getStreetId()) + .eq("`row`",oldOrder.getRow2()) + .eq("`column`",oldOrder.getColumn2()) + .eq("in_out",oldOrder.getInOut2()) + .eq("left_right",oldOrder.getLeftRight2())); + OrderLive orderOutLive = new OrderLive(); + orderOutLive.setOrderNum(oldOrder.getOrderNum()); + orderOutLive.setColumn(oldOrder.getColumn2()); + orderOutLive.setRow(oldOrder.getRow2()); + orderOutLive.setStatus(oldOrder.getStatus()); + orderOutLive.setInOut(oldOrder.getInOut2()); + orderOutLive.setLeftRight(oldOrder.getLeftRight2()); + orderOutLive.setStreetId(oldOrder.getStreetId()); + orderOutLive.setEndTime(oldOrder.getEndTime()); + orderOutLive.setStartTime(oldOrder.getStartTime()); + if(picPaths.size()>=2){ + orderOutLive.setPicPaths(picPaths.poll()+","+picPaths.poll()); + } + if(orderOutLiveOld != null){ + orderOutLive.setId(orderOutLiveOld.getId()); + orderLiveMapper.updateById(orderOutLive); + }else { + orderLiveMapper.insert(orderOutLive); + } } @@ -194,8 +259,8 @@ public class PlcService { Thread thread = new Thread(new Runnable() { @Override public void run() { - String realPath = configProperties.getSavePath().getMp4Path() + path; - TaskDelayExecutor.addMp4DelayTask(cameraId,realPath,startTime,endTime,configProperties.getCameraConfig().getDelayDownloadMp4()); + String realPath = configProperties.getSavePath().getMp4PathCache() + path; + TaskDelayExecutor.addMp4DelayTask(cameraId,realPath,startTime,endTime,configProperties.getCameraConfig().getDelayDownloadMp4(),configProperties.getSavePath()); } }); thread.start(); @@ -273,6 +338,8 @@ public class PlcService { //update order info after capture if (path != null && needCapture) { captureUpdateOrderAndStock(orderInfo, path); + captureUpdateOrderLive(orderInfo, path,code); + } //转向原点位 if(times == 2){ @@ -286,6 +353,40 @@ public class PlcService { } } + private void captureUpdateOrderLive(OrderInfo orderInfo, String path, String code) { + synchronized (orderInfo.getOrderNum().intern()) { + Order order = orderMapper.getOneByOrderNum(orderInfo.getOrderNum()); + if (order != null) { + //update picPath in stock if code is C2/C4 + if(orderInfo.getCode().startsWith("C2") || orderInfo.getCode().startsWith("C4")){ + StockLog stockLog = new StockLog(); + stockLog.setStreetId(orderInfo.getStreetId()); + stockLog.setDirection(orderInfo.getLeftRight()); + stockLog.setSide(orderInfo.getSeparation()); + stockLog.setRow(orderInfo.getRow()); + stockLog.setColumn(orderInfo.getColumn()); + stockLog.setPic(path); + String type = orderInfo.getCode().substring(1,2); + stockLog.setType(Integer.valueOf(type)); + stockLog.setOrderNum(orderInfo.getOrderNum()); + stockLog.setCreateTime(LocalDateTime.now()); + stockLogMapper.insert(stockLog); + } + String pics = order.getPicPaths(); + if (StringUtils.isEmpty(pics)) { + order.setPicPaths(path); + } else { + order.setPicPaths(pics + "," + path); + } + Order update = new Order(); + update.setId(order.getId()); + update.setPicPaths(order.getPicPaths()); + log.debug(" update order set pics:{},orderNum:{}", update.getPicPaths(), orderInfo.getOrderNum()); + orderMapper.updateById(update); + } + } + } + public void gyrateCamera(PlcCmdInfo plcCmdInfo,String code){ Street street = streetService.getStreetByPlcId(plcCmdInfo.getPlcId()); if(street == null){ @@ -330,11 +431,13 @@ public class PlcService { */ public String cameraCapture(Integer cameraId,Boolean delay,Long delayTime,String path) { //String path = PathUtil.createFileName("jpg",cameraId); - String realPath = configProperties.getSavePath().getMediaPath() + path; + String realPath = configProperties.getSavePath().getMediaPathCache() + path; + ConfigProperties.SavePath savePath = configProperties.getSavePath(); if(delay){ - TaskDelayExecutor.addPicDelayTask(cameraId,realPath,delayTime); + TaskDelayExecutor.addPicDelayTask(cameraId,realPath,delayTime,savePath); }else { - cameraControlModule.pic(cameraId,0,realPath); + cameraControlModule.pic(cameraId,0,realPath,configProperties.getSavePath()); + } return path; } diff --git a/web/src/main/java/com/leaper/web/service/RealTimeService.java b/web/src/main/java/com/leaper/web/service/RealTimeService.java index 7a4e9a8..5c38ba2 100644 --- a/web/src/main/java/com/leaper/web/service/RealTimeService.java +++ b/web/src/main/java/com/leaper/web/service/RealTimeService.java @@ -66,7 +66,7 @@ public class RealTimeService { public Set allAreas(){ List streets = streetMapper.selectByMap(new HashMap<>()); - return streets.stream().collect(Collectors.groupingBy(Street::getArea)).keySet(); + return new HashSet<>(); } public List getAllCamerasByArea(String area){ diff --git a/web/src/main/java/com/leaper/web/service/ksec/KescFilter.java b/web/src/main/java/com/leaper/web/service/ksec/KescFilter.java index e8550ff..7b2aedd 100644 --- a/web/src/main/java/com/leaper/web/service/ksec/KescFilter.java +++ b/web/src/main/java/com/leaper/web/service/ksec/KescFilter.java @@ -17,14 +17,18 @@ import java.util.concurrent.TimeUnit; * @author Administrator * */ + public class KescFilter extends ChannelInitializer { private KsecInfo ksecInfo; + private PlcService plcService; + private KsecNettyClient nettyClient; - public KescFilter(KsecInfo ksecInfo, KsecNettyClient nettyClient){ + public KescFilter(KsecInfo ksecInfo, PlcService plcService, KsecNettyClient nettyClient){ this.ksecInfo = ksecInfo; + this.plcService = plcService; this.nettyClient = nettyClient; } @@ -35,7 +39,7 @@ public class KescFilter extends ChannelInitializer { //4秒发一次心跳 ph.addLast(new IdleStateHandler(0, 4, 0, TimeUnit.SECONDS)); ByteBuf byteBuf = Unpooled.copiedBuffer(">".getBytes()); - ph.addLast(new KsecDecoder(10000,byteBuf)); + ph.addLast(new KsecDecoder(10000,byteBuf,plcService)); ph.addLast(new KescEncoder()); ph.addLast(new KescNettyHandler(ksecInfo,nettyClient)); } diff --git a/web/src/main/java/com/leaper/web/service/ksec/KsecDecoder.java b/web/src/main/java/com/leaper/web/service/ksec/KsecDecoder.java index 26c3da8..9ab4778 100644 --- a/web/src/main/java/com/leaper/web/service/ksec/KsecDecoder.java +++ b/web/src/main/java/com/leaper/web/service/ksec/KsecDecoder.java @@ -1,12 +1,11 @@ package com.leaper.web.service.ksec; import com.alibaba.fastjson.JSONObject; -import com.leaper.web.pojo.Cmd; -import com.leaper.web.service.CommandHandler; -import com.leaper.web.service.PlcService; import com.leaper.common.util.FileUtil; +import com.leaper.web.pojo.Cmd; import com.leaper.web.service.GoodsActionTimes; import com.leaper.web.service.PlcCmdInfo; +import com.leaper.web.service.PlcService; import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelHandlerContext; import io.netty.handler.codec.DelimiterBasedFrameDecoder; @@ -26,8 +25,23 @@ import java.util.concurrent.TimeUnit; @Slf4j public class KsecDecoder extends DelimiterBasedFrameDecoder { - public KsecDecoder(int maxFrameLength, ByteBuf delimiter) { + private static final Logger tcpLogger = LoggerFactory.getLogger("tcp"); + + public static void setLastLotnum(String lotnum){ + lastLotnum = lotnum; + } + + private static String lastLotnum; + private static ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(7,21,30, TimeUnit.MILLISECONDS,new ArrayBlockingQueue<>(20000)); + + + //private static ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(7,21,30, TimeUnit.MILLISECONDS,new ArrayBlockingQueue<>(20000)); + + private PlcService plcService; + + public KsecDecoder(int maxFrameLength, ByteBuf delimiter, PlcService plcService) { super(maxFrameLength, delimiter); + this.plcService = plcService; } @Override @@ -37,7 +51,169 @@ public class KsecDecoder extends DelimiterBasedFrameDecoder { log.debug("no data"); return null; } - CommandHandler.exec(ctx, in); + KescRunnable kescRunnable = new KescRunnable(in,ctx,plcService); + threadPoolExecutor.execute(kescRunnable); return null; } + + public static class KescRunnable implements Runnable{ + + private ByteBuf in; + + private ChannelHandlerContext ctx; + + private PlcService plcService; + + public KescRunnable(ByteBuf body,ChannelHandlerContext ctx,PlcService plcService){ + this.in = body; + this.ctx = ctx; + this.plcService = plcService; + } + + @Override + public void run() { + String body = in.toString(Charset.forName("UTF-8")); + tcpLogger.info(body); + if (body.startsWith("<")){ + // 去掉首尾标识符 + body = body.substring(1, body.length()); + KsecInfo ksecInfo = JSONObject.parseObject(body, KsecInfo.class); + if (Cmd.A.name().equals(ksecInfo.getType())) { + in.release(); + return ; + } + KsecDataInfo dataInfo = ksecInfo.getData(); + String lotnum = dataInfo.getLotnum(); + PlcCmdInfo plcCmdInfo = null; + String srmNumber = null; + String cmdName = null; + if(dataInfo != null){ + //左右换过来 + if(dataInfo.getFromDirection() == 1){ + dataInfo.setFromDirection(2); + }else { + dataInfo.setFromDirection(1); + } + if(dataInfo.getToDirection() != null && dataInfo.getToDirection() == 1){ + dataInfo.setToDirection(2); + }else { + dataInfo.setToDirection(1); + } + plcCmdInfo = new PlcCmdInfo(dataInfo.getSRMNumber(), dataInfo.getTaskId(), dataInfo.getFromSide(), dataInfo.getFromDirection(), dataInfo.getFromColumn(), dataInfo.getFromRow(), dataInfo.getFromSeparation(),dataInfo.getToSide(), dataInfo.getToDirection(), dataInfo.getToColumn(), dataInfo.getToRow(),dataInfo.getToSeparation(),lotnum); + + srmNumber = dataInfo.getSRMNumber(); + cmdName = dataInfo.getCmdName(); + } + if (Cmd.A.name().equals(ksecInfo.getType())) { + //心跳 + log.debug("receieve heart "); + } else if (Cmd.B.name().equals(ksecInfo.getType())) { + + //任务 + if (Cmd.B1.name().equals(cmdName)) { + //昆船盘点模式下也会发B1 ,但是不会发送B2 + //这里判断下,是否存在盘点批次号 若存在,既是盘点的B1,无需处理;若不存在lotnum,则是随行的B1 + if(StringUtils.isEmpty(dataInfo.getLotnum())){ + //任务开始 旋转到原点位 + plcService.gyrateCamera(plcCmdInfo,Cmd.C5.name()); + plcService.orderStart(plcCmdInfo); + }else { + log.info("check move"); + } + + } else if (Cmd.B2.name().equals(cmdName)) { + //B2 C4 一起发的,需要停止等B2 + + //这里判断是不是双伸 + if(plcCmdInfo.getSeparation2() == 2){ + //深测货架延迟 + try { + Thread.sleep(plcService.getConfigProperties().getCameraConfig().getB2OutDelayTime()); + } catch (InterruptedException e) { + e.printStackTrace(); + } + }else { + //浅侧延迟 + try { + Thread.sleep(plcService.getConfigProperties().getCameraConfig().getB2DelayTime()); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + plcService.gyrateCamera(plcCmdInfo,Cmd.C5.name()); + plcService.orderStop(plcCmdInfo); + } + } else if (Cmd.C.name().equals(ksecInfo.getType())) { + + //动作 + String code = dataInfo.getCmdName(); + log.info("action code,{},orderInfo:{}", code, plcCmdInfo.toString()); + if (Cmd.isBaseAction(code)) { + //执行动作,需要保存执行到第几步了 + Integer times = GoodsActionTimes.put(plcCmdInfo.getOrderNum()); + plcCmdInfo.setTimes(times); + code = code + "-" + plcCmdInfo.getLeftRightStr(times) + plcCmdInfo.getInOutStr(times); + //执行动作 + try { + plcService.action(plcCmdInfo, times, code); + } catch (InterruptedException e) { + e.printStackTrace(); + } + }else { + log.info("other C code :{}",code); + } + } else if (Cmd.D.name().equals(ksecInfo.getType())) { + + //柳州去掉告警 +// String code = dataInfo.getCmdName(); +// if(code.equals(Cmd.D1.name())){ +// log.info("plcId:{},warn start",plcCmdInfo.getPlcId()); +// //根据告警code转动camera +// String warnCode = dataInfo.getWarnCode(); +// if(!StringUtils.isEmpty(warnCode)){ +// String warnCode0 = Cmd.D1.name()+"-"+warnCode.split(",")[0]; +// plcService.warnAction(plcCmdInfo,warnCode0); +// } +// plcService.warnStart(plcCmdInfo.getPlcId(),dataInfo.getWarnCode()); +// }else if(code.equals(Cmd.D2.name())){ +// log.info("plcId:{},warn stop",plcCmdInfo.getPlcId()); +// plcService.warnStop(plcCmdInfo.getPlcId()); +// }else { +// log.info("other D code :{}",code); +// } + } else if (Cmd.E.name().equals(ksecInfo.getType())) { + + //盘点 + //转球机到盘点位 然后拍照 + +// if(!StringUtils.isEmpty(lotnum) && !lotnum.equals(lastLotnum)){ +// //需要把stock表truncate +// FileUtil.save(lotnum,"lastLotnum"); +// tcpLogger.info("truncate table ,last lotnum:{},new lotnum:{}",lastLotnum,lotnum); +// plcService.truncateStock(); +// lastLotnum = lotnum; +// } +// plcCmdInfo.setTimes(1); +// Boolean ok = plcService.check(plcCmdInfo,ksecInfo.getData().getCmdName(), dataInfo.getCode(), dataInfo.getTrayCode()); +// if(ok){ +// ksecInfo.getData().setAckStatus(1); +// }else { +// ksecInfo.getData().setAckStatus(0); +// } +// ctx.channel().writeAndFlush(ksecInfo); + //rfid的逻辑 + String code = dataInfo.getCmdName(); + if("E1".equals(code)){ + plcService.RFIDCheck(plcCmdInfo); + }else { + plcService.RFIDStop(plcCmdInfo); + } + + } + //找到该货位的最后一张照片与现在的照片比照 + //plcService.recordStock(plcCmdInfo, dataInfo.getCode(), 0, 0); + } + in.release(); + } + } } diff --git a/web/src/main/java/com/leaper/web/service/ksec/KsecNettyClient.java b/web/src/main/java/com/leaper/web/service/ksec/KsecNettyClient.java index 57cb5a2..fa5740d 100644 --- a/web/src/main/java/com/leaper/web/service/ksec/KsecNettyClient.java +++ b/web/src/main/java/com/leaper/web/service/ksec/KsecNettyClient.java @@ -41,7 +41,7 @@ public class KsecNettyClient { client.group(group); client.channel(NioSocketChannel.class); KsecInfo heart = KsecInfo.heart(); - client.handler(new KescFilter(heart,this)); + client.handler(new KescFilter(heart, plcService,this)); // 连接服务端 channel = client.connect(ksec.getIp(), ksec.getPort()).sync().channel(); } diff --git a/web/src/main/java/com/leaper/web/service/sftp/SftpFactory.java b/web/src/main/java/com/leaper/web/service/sftp/SftpFactory.java new file mode 100644 index 0000000..45f158b --- /dev/null +++ b/web/src/main/java/com/leaper/web/service/sftp/SftpFactory.java @@ -0,0 +1,100 @@ +package com.leaper.web.service.sftp; + + +import com.jcraft.jsch.ChannelSftp; +import com.jcraft.jsch.JSch; +import com.jcraft.jsch.JSchException; +import com.jcraft.jsch.Session; +import com.leaper.web.config.ConfigProperties; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.pool2.BasePooledObjectFactory; +import org.apache.commons.pool2.PooledObject; +import org.apache.commons.pool2.impl.DefaultPooledObject; +import org.apache.commons.pool2.impl.GenericObjectPoolConfig; + +import javax.annotation.Resource; +import java.util.Properties; + +@Data +@Slf4j +public class SftpFactory extends BasePooledObjectFactory { + + private Pool pool = new Pool(); + + public static class Pool extends GenericObjectPoolConfig { + + private int maxTotal = DEFAULT_MAX_TOTAL; + private int maxIdle = DEFAULT_MAX_IDLE; + private int minIdle = DEFAULT_MIN_IDLE; + + public Pool() { + super(); + } + @Override + public int getMaxTotal() { + return maxTotal; + } + @Override + public void setMaxTotal(int maxTotal) { + this.maxTotal = maxTotal; + } + @Override + public int getMaxIdle() { + return maxIdle; + } + @Override + public void setMaxIdle(int maxIdle) { + this.maxIdle = maxIdle; + } + @Override + public int getMinIdle() { + return minIdle; + } + @Override + public void setMinIdle(int minIdle) { + this.minIdle = minIdle; + } + + } + + ConfigProperties configProperties; + + public SftpFactory(ConfigProperties properties) { + this.configProperties = properties; + } + + @Override + public ChannelSftp create() { + try { + JSch jsch = new JSch(); + Session sshSession = jsch.getSession(configProperties.getSavePath().getCloudUser(),configProperties.getSavePath().getCloudIp(), 22); + sshSession.setPassword(configProperties.getSavePath().getCloudPassword()); + Properties sshConfig = new Properties(); + sshConfig.put("StrictHostKeyChecking", "no"); + sshSession.setConfig(sshConfig); + sshSession.connect(); + ChannelSftp channel = (ChannelSftp) sshSession.openChannel("sftp"); + channel.connect(); + return channel; + } catch (JSchException e) { + log.info("连接sfpt失败"); + e.printStackTrace(); + + } + return null; + } + + @Override + public PooledObject wrap(ChannelSftp channelSftp) { + return new DefaultPooledObject<>(channelSftp); + } + + // 销毁对象 + @Override + public void destroyObject(PooledObject p) { + ChannelSftp channelSftp = p.getObject(); + channelSftp.disconnect(); + } + +} \ No newline at end of file diff --git a/web/src/main/java/com/leaper/web/service/sftp/SftpHelper.java b/web/src/main/java/com/leaper/web/service/sftp/SftpHelper.java new file mode 100644 index 0000000..422b16f --- /dev/null +++ b/web/src/main/java/com/leaper/web/service/sftp/SftpHelper.java @@ -0,0 +1,190 @@ +package com.leaper.web.service.sftp; + + +import com.jcraft.jsch.ChannelSftp; +import com.jcraft.jsch.SftpATTRS; +import com.jcraft.jsch.SftpException; +import io.swagger.models.auth.In; +import lombok.extern.slf4j.Slf4j; + +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.IntStream; + +// sftp辅助类 +@Slf4j +public class SftpHelper { + + private SftpPool pool; + + public SftpHelper(SftpPool pool) { + this.pool = pool; + } + + /** + * 下载文件 + * @param dir 远程目录 + * @param name 远程文件名 + * @return 文件字节数组 + */ + public byte[] download(String dir, String name) { + ChannelSftp sftp = pool.borrowObject(); + try { + sftp.cd(dir); + InputStream in = sftp.get(name); + + return new byte[in.available()]; + } catch (SftpException e) { + log.info("sftp下载文件出错"); + e.printStackTrace(); + return null; + } catch (IOException e) { + throw new RuntimeException(e); + } finally { + pool.returnObject(sftp); + } + } + + /** + * 上传文件 + * @param dir 远程目录 + * @param name 远程文件名 + * @param in 输入流 + */ + public void upload(String dir, String name, InputStream in) { + ChannelSftp sftp = pool.borrowObject(); + try { + mkdirs(dir); + sftp.cd(dir); + sftp.put(in, name); + } catch (SftpException e) { + + log.info("sftp上传文件出错"); + e.printStackTrace(); + } finally { + pool.returnObject(sftp); + } + } + + public void put(String srcFilePath, String targetFilePath) { + ChannelSftp sftp = pool.borrowObject(); + try { + sftp.put(srcFilePath, targetFilePath); + } catch (SftpException e) { + + log.info("sftp上传文件出错"); + e.printStackTrace(); + } finally { + pool.returnObject(sftp); + } + } + + /** + * 删除文件 + * @param dir 远程目录 + * @param name 远程文件名 + */ + public void delete(String dir, String name) { + ChannelSftp sftp = pool.borrowObject(); + try { + sftp.cd(dir); + sftp.rm(name); + } catch (SftpException e) { + log.info("sftp删除文件出错"); + e.printStackTrace(); + } finally { + pool.returnObject(sftp); + } + } + /** + * 删除文件 + * @param dirPath 远程目录文件名 + */ + public void delete(String dirPath) { + ChannelSftp sftp = pool.borrowObject(); + try { + sftp.rm(dirPath); + } catch (SftpException e) { + log.info("sftp删除文件出错"); + e.printStackTrace(); + } finally { + pool.returnObject(sftp); + } + } + + /** + * 查看文件夹 + * @param dirPath 远程目录文件名 + */ + public List ls(String dirPath) { + ChannelSftp sftp = pool.borrowObject(); + List list = new ArrayList<>(); + try { + list = sftp.ls(dirPath); + } catch (SftpException e) { + log.info("sftp查看文件夹失败"); + e.printStackTrace(); + } finally { + pool.returnObject(sftp); + } + return list; + } + + /** + * 文件是否存在 + * @param dir 远程文件名 + */ + public boolean isExist(String dir) { + ChannelSftp sftp = pool.borrowObject(); + try { + sftp.stat(dir); + return true; + } catch (SftpException e) { + log.info("sftp文件不存在"); + return false; + } finally { + pool.returnObject(sftp); + } + } + + /** + * 递归创建多级目录 + * + * @param dir 多级目录 + */ + public void mkdirs(String dir) { + String[] folders = dir.split("/"); + ChannelSftp sftp = pool.borrowObject(); + try { + sftp.cd("/"); + for (String folder: folders) { + if (folder.length()>0) { + try { + sftp.cd(folder); + } catch (Exception e) { + sftp.mkdir(folder); + sftp.cd(folder); + } + } + } + } catch (SftpException e) { + log.info("sftp创建目录出错"); + e.printStackTrace(); + } + } + + public void rmdir(String dirPath) { + ChannelSftp sftp = pool.borrowObject(); + try { + sftp.rmdir(dirPath); + } catch (SftpException e) { + log.info("sftp删除文件夹出错"); + e.printStackTrace(); + } finally { + pool.returnObject(sftp); + } + } +} + diff --git a/web/src/main/java/com/leaper/web/service/sftp/SftpPool.java b/web/src/main/java/com/leaper/web/service/sftp/SftpPool.java new file mode 100644 index 0000000..e3ff7e9 --- /dev/null +++ b/web/src/main/java/com/leaper/web/service/sftp/SftpPool.java @@ -0,0 +1,45 @@ +package com.leaper.web.service.sftp; + +import com.jcraft.jsch.ChannelSftp; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.pool2.impl.GenericObjectPool; +import org.apache.commons.pool2.impl.GenericObjectPoolConfig; +import org.springframework.boot.context.properties.ConfigurationProperties; + +@Slf4j +@Data +public class SftpPool { + + private GenericObjectPool pool; + + public SftpPool(SftpFactory factory) { + this.pool = new GenericObjectPool<>(factory, factory.getPool()); + } + + /** + * 获取一个sftp连接对象 + * @return sftp连接对象 + */ + public ChannelSftp borrowObject() { + try { + return pool.borrowObject(); + } catch (Exception e) { + log.info("获取ftp连接失败"); + e.printStackTrace(); + + } + return null; + } + + /** + * 归还一个sftp连接对象 + * @param channelSftp sftp连接对象 + */ + public void returnObject(ChannelSftp channelSftp) { + if (channelSftp!=null) { + pool.returnObject(channelSftp); + } + } + +} diff --git a/web/src/main/resources/application-test.yml b/web/src/main/resources/application-test.yml index cf2e001..3238321 100644 --- a/web/src/main/resources/application-test.yml +++ b/web/src/main/resources/application-test.yml @@ -14,7 +14,7 @@ spring: testWhileIdle: false timeBetweenEvictionRunsMillis: 60000 type: com.alibaba.druid.pool.DruidDataSource - url: jdbc:mysql://127.0.0.1:3306/lia_duoji?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B8 + url: jdbc:mysql://121.37.95.190:3306/lia_duoji?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B8 username: root validationQuery: SELECT 1 FROM DUAL #-------------- @@ -22,13 +22,28 @@ spring: # ----默认摄像头的连接信息 cameraConfig: # ------------球機選擇--- 0:利珀 1:海康 - cameraType: 0 + cameraType: 1 cameraPassword: a1234567 cameraUser: admin cameraPort: 8000 videoServer: 127.0.0.1:8083 #相机抓图延迟 毫秒,这个延迟是等待球机球机转动到位,然后拍照的 delayCaptureTime: 3500 + #随行模式下的相机抓图延迟 毫秒,这个延迟是等待球机球机转动到位,然后拍照的 + # 发了C1之后多久拍照 + C1DelayCaptureTime: 1500 + # 内侧货架 发了C2 之后多久拍照 + C2DelayCaptureTime: 1500 + # 外侧货架 发了C2 之后多久拍照 + C2OutDelayCaptureTime: 2500 + # 发了C3之后多久拍照 + C3DelayCaptureTime: 1500 + C4DelayCaptureTime: 1500 + C4OutDelayCaptureTime: 1500 + # 发了B2之后多久转原点位 + B2DelayTime: 2000 + # 外侧货架发了B2多久转原点位 + B2OutDelayTime: 2000 # 下载mp4延迟 海康的下载mp4需要2分钟 # 利珀延迟10s就可 # 单位毫秒 @@ -36,13 +51,32 @@ cameraConfig: # ------------ # -----图片 mp4下载地址 savePath: - mediaPath: d:\\data\media\ - mp4Path: d://data/mp4/ + saveDays: 1 +# 定期删除文件cron解析 + deleteSaveCron: 0 0 0 2 * ? + cloudIp: 121.37.95.190 + cloudUser: root + cloudPassword: Leaper@123 + mediaPathCache: d:\\data\media\ + mp4PathCache: d://data/mp4/ + mediaPath: /mnt/media/ + mp4Path: /mnt/mp4/ # ------------服务端类型 0:TCP(罗伯泰克) 1:KSEC(JSON)(昆船) serverMode: 1 ksec: ip: 127.0.0.1 port: 3000 +sftp: + host: server02 # 服务器ip + port: 22 # ssh端口 + username: demofile # 用户名 + password: demo # 密码 + # 连接池参数 + pool: + max-total: 10 + max-idle: 10 + min-idle: 5 + # ------------ 实时视频流 全部页面的格式 行列数量 videoStyleConfig: videoStyleRow: 2 diff --git a/web/src/main/resources/mapper/StreetMapper.xml b/web/src/main/resources/mapper/StreetMapper.xml index ed0d208..85870e6 100644 --- a/web/src/main/resources/mapper/StreetMapper.xml +++ b/web/src/main/resources/mapper/StreetMapper.xml @@ -13,7 +13,7 @@ left join camera c2 on t.camera2_id = c2.id left join sensor_gun s1 on s1.street_id = t.id and s1.direction = 1 left join sensor_gun s2 on s2.street_id = t.id and s2.direction = 2 - left join RFID rf on rf.street_id = t.id + left join rfid rf on rf.street_id = t.id order by t.id desc