diff --git a/web/src/main/java/com/zhehekeji/web/controller/OrderController.java b/web/src/main/java/com/zhehekeji/web/controller/OrderController.java index 59800f3..cb04dcb 100644 --- a/web/src/main/java/com/zhehekeji/web/controller/OrderController.java +++ b/web/src/main/java/com/zhehekeji/web/controller/OrderController.java @@ -7,7 +7,9 @@ import com.zhehekeji.web.entity.Order; import com.zhehekeji.web.pojo.OrderSaveReq; import com.zhehekeji.web.pojo.OrderSearch; import com.zhehekeji.web.service.OrderService; +import com.zhehekeji.web.service.PlcService; import io.swagger.annotations.Api; +import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; import org.springframework.beans.factory.annotation.Value; @@ -24,6 +26,8 @@ public class OrderController { @Resource private OrderService orderService; @Resource + private PlcService plcService; + @Resource private ValidatorUtil validatorUtil; @Value("${zhehe.filter.postToken}") @@ -46,22 +50,22 @@ public class OrderController { @ApiOperation("工单开始信号") @GetMapping("/start") - public Result orderStart(@ApiParam("工单号") @RequestParam String orderNum){ - orderService.orderStart(orderNum); + public Result orderStart(@ApiParam("工单号") @RequestParam String orderNum, @ApiParam("plc")String plcId){ + plcService.orderStart(orderNum,plcId); return Result.success(); } @ApiOperation("工单结束信号") @GetMapping("/stop") - public Result orderStop(@ApiParam("工单号") @RequestParam String orderNum){ - orderService.orderStop(orderNum,null); + public Result orderStop(@ApiParam("工单号") @RequestParam String orderNum,@ApiParam("plc")String plcId){ + plcService.orderStop(orderNum,null,plcId); return Result.success(); } @ApiOperation("工单被告警打断") @GetMapping("/error") - public Result orderError(@ApiParam("工单号") @RequestParam String plcId){ - orderService.error(plcId); + public Result orderError(@ApiParam("plc") @RequestParam String plcId,@RequestParam String warnNum){ + plcService.warnStart(plcId,warnNum); return Result.success(); } diff --git a/web/src/main/java/com/zhehekeji/web/controller/PLCController.java b/web/src/main/java/com/zhehekeji/web/controller/PLCController.java index 85c5226..8a9ecb0 100644 --- a/web/src/main/java/com/zhehekeji/web/controller/PLCController.java +++ b/web/src/main/java/com/zhehekeji/web/controller/PLCController.java @@ -24,6 +24,8 @@ public class PLCController { private StreetService streetService; @Resource private StreetMapper streetMapper; + @Resource + private ClientMap clientMap; @GetMapping("/heart") @@ -31,7 +33,7 @@ public class PLCController { public Result heart(@RequestParam Integer id) throws InterruptedException { Street street = streetMapper.selectById(id); Assert.isTrue(street!= null && street.getPlcIp() != null && street.getPlcPort() != null,"未配置IP"); - ClientMap.createClient(street); + clientMap.createClient(street); return Result.success(); } diff --git a/web/src/main/java/com/zhehekeji/web/entity/Warn.java b/web/src/main/java/com/zhehekeji/web/entity/Warn.java new file mode 100644 index 0000000..9c988a1 --- /dev/null +++ b/web/src/main/java/com/zhehekeji/web/entity/Warn.java @@ -0,0 +1,38 @@ +package com.zhehekeji.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 +public class Warn { + + @TableId(type = IdType.AUTO) + private Long id; + + private Integer streetId; + + @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss") + private LocalDateTime createTime; + + @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss") + private LocalDateTime startTime; + + @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss") + private LocalDateTime endTime; + + @ApiModelProperty("视频图片地址") + @TableField("`video_path_1`") + private String videoPath1; + + @ApiModelProperty("视频图片地址") + @TableField("`video_path_2`") + private String videoPath2; +} diff --git a/web/src/main/java/com/zhehekeji/web/lib/OrderRealtime.java b/web/src/main/java/com/zhehekeji/web/lib/OrderRealtime.java index ec624f5..fadb3ff 100644 --- a/web/src/main/java/com/zhehekeji/web/lib/OrderRealtime.java +++ b/web/src/main/java/com/zhehekeji/web/lib/OrderRealtime.java @@ -1,6 +1,9 @@ package com.zhehekeji.web.lib; +import org.springframework.util.CollectionUtils; + import java.util.Map; +import java.util.Set; import java.util.concurrent.ConcurrentHashMap; /** @@ -15,6 +18,9 @@ public class OrderRealtime { */ private static Map orderMap = new ConcurrentHashMap<>(); + private static Map> warnMap = new ConcurrentHashMap<>(); + private static Map warnIdMap = new ConcurrentHashMap<>(); + /** * 下载句柄与订单号的关联 * key: 下载句柄 @@ -23,9 +29,7 @@ public class OrderRealtime { private static Map playOrderMap = new ConcurrentHashMap<>(); public static void startOrder(Integer streetId,String orderNum){ - synchronized (streetId.toString().intern()){ orderMap.put(streetId,orderNum); - } } /** @@ -37,17 +41,47 @@ public class OrderRealtime { return orderMap.get(streetId); } + public static void startWarn(Integer streetId,String orderNum,Long warnId){ + Set set = warnMap.get(streetId); + set.add(orderNum); + warnMap.put(streetId,set); + if(warnId != null){ + warnIdMap.put(streetId,warnId); + } + } + + /** + * 结束告警,返回是否还存在告警 + * true:存在告警 + * @param streetId + * @return + */ + public static Boolean stopWarn(Integer streetId,String orderNum){ + Set set = warnMap.get(streetId); + set.remove(orderNum); + warnMap.put(streetId,set); + return !set.isEmpty(); + } + + public static Long getWarnId(Integer streetId){ + return warnIdMap.get(streetId); + } + + public static void cleanWarn(Integer streetId){ + warnIdMap.remove(streetId); + } + /** * 结束订单,返回订单号 * @param streetId * @return */ public static String stopOrder(Integer streetId){ - synchronized (streetId.toString().intern()){ + String orderNum = orderMap.get(streetId); orderMap.remove(streetId); return orderNum; - } + } public static void startDownload(NetSDKLib.LLong play,String orderNum){ diff --git a/web/src/main/java/com/zhehekeji/web/mapper/WarnMapper.java b/web/src/main/java/com/zhehekeji/web/mapper/WarnMapper.java new file mode 100644 index 0000000..a027232 --- /dev/null +++ b/web/src/main/java/com/zhehekeji/web/mapper/WarnMapper.java @@ -0,0 +1,9 @@ +package com.zhehekeji.web.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.zhehekeji.web.entity.Warn; + + +public interface WarnMapper extends BaseMapper { + +} diff --git a/web/src/main/java/com/zhehekeji/web/service/ClientMap.java b/web/src/main/java/com/zhehekeji/web/service/ClientMap.java index fde68ee..18120f2 100644 --- a/web/src/main/java/com/zhehekeji/web/service/ClientMap.java +++ b/web/src/main/java/com/zhehekeji/web/service/ClientMap.java @@ -1,32 +1,33 @@ package com.zhehekeji.web.service; -import com.zhehekeji.core.util.Assert; import com.zhehekeji.web.entity.Street; import io.netty.bootstrap.Bootstrap; import io.netty.channel.*; import io.netty.channel.nio.NioEventLoopGroup; -import io.netty.channel.socket.SocketChannel; import io.netty.channel.socket.nio.NioSocketChannel; import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; -import java.util.HashMap; -import java.util.Map; +import javax.annotation.Resource; @Slf4j +@Component public class ClientMap { - private static Map channelFutureMap = new HashMap<>(); - private static EventLoopGroup group = new NioEventLoopGroup(); - public static void createClient(Street street) throws InterruptedException { + @Resource + private PlcService plcService; + + public void createClient(Street street) throws InterruptedException { Bootstrap client = new Bootstrap(); // 第1步 定义线程组,处理读写和链接事件,没有了accept事件 client.group(group); // 第2步 绑定客户端通道 client.channel(NioSocketChannel.class); // 第3步 给NIoSocketChannel初始化handler, 处理读写事件 - client.handler(new HeartNettyClientFilter(street.getId())); + SendHeart sendHeart = new SendHeart(street.getPlcId(),"0A"); + client.handler(new HeartNettyClientFilter(street.getId(),sendHeart,plcService)); // 连接服务端 client.connect(street.getPlcIp(), street.getPlcPort()).sync().channel(); } diff --git a/web/src/main/java/com/zhehekeji/web/service/HeartNettyClientFilter.java b/web/src/main/java/com/zhehekeji/web/service/HeartNettyClientFilter.java index 8b116df..88c5f9c 100644 --- a/web/src/main/java/com/zhehekeji/web/service/HeartNettyClientFilter.java +++ b/web/src/main/java/com/zhehekeji/web/service/HeartNettyClientFilter.java @@ -3,8 +3,6 @@ package com.zhehekeji.web.service; import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelPipeline; import io.netty.channel.socket.SocketChannel; -import io.netty.handler.codec.string.StringDecoder; -import io.netty.handler.codec.string.StringEncoder; import io.netty.handler.timeout.IdleStateHandler; import java.util.concurrent.TimeUnit; @@ -19,8 +17,14 @@ public class HeartNettyClientFilter extends ChannelInitializer { private Integer streetId; - public HeartNettyClientFilter(Integer streetId){ + private SendHeart sendHeart; + + private PlcService plcService; + + public HeartNettyClientFilter(Integer streetId,SendHeart sendHeart,PlcService plcService){ this.streetId = streetId; + this.sendHeart = sendHeart; + this.plcService = plcService; } @Override @@ -28,7 +32,9 @@ public class HeartNettyClientFilter extends ChannelInitializer { ChannelPipeline ph = ch.pipeline(); //因为服务端设置的超时时间是5秒,所以客户端设置4秒 ph.addLast(new IdleStateHandler(0, 4, 0, TimeUnit.SECONDS)); + ph.addLast(new MyProtocolDecoder(1000*10000,6,4,0,0,false,null,plcService)); + ph.addLast(new MyProtocolEncoder()); //处理客户端的业务逻辑 - ph.addLast(new HeartNettyClientHandler(streetId)); + ph.addLast(new HeartNettyClientHandler(streetId,sendHeart)); } } diff --git a/web/src/main/java/com/zhehekeji/web/service/HeartNettyClientHandler.java b/web/src/main/java/com/zhehekeji/web/service/HeartNettyClientHandler.java index 59840e5..d339e40 100644 --- a/web/src/main/java/com/zhehekeji/web/service/HeartNettyClientHandler.java +++ b/web/src/main/java/com/zhehekeji/web/service/HeartNettyClientHandler.java @@ -1,7 +1,6 @@ package com.zhehekeji.web.service; import io.netty.buffer.ByteBuf; -import io.netty.buffer.Unpooled; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundHandlerAdapter; import io.netty.handler.timeout.IdleState; @@ -9,8 +8,7 @@ import io.netty.handler.timeout.IdleStateEvent; import io.netty.util.CharsetUtil; import lombok.extern.slf4j.Slf4j; -import java.text.SimpleDateFormat; -import java.util.Date; +import java.nio.charset.Charset; /** * 处理客户端业务逻辑:心跳超时处理、服务端返回的数据处理 @@ -21,12 +19,13 @@ import java.util.Date; @Slf4j public class HeartNettyClientHandler extends ChannelInboundHandlerAdapter { /** 客户端请求的心跳命令 */ - private static final SendHeart s = new SendHeart(); + private SendHeart heart; private Integer streetId; - public HeartNettyClientHandler(Integer streetId){ + public HeartNettyClientHandler(Integer streetId,SendHeart heart){ this.streetId = streetId; + this.heart = heart; } /** @@ -51,23 +50,15 @@ public class HeartNettyClientHandler extends ChannelInboundHandlerAdapter { */ @Override public void userEventTriggered(ChannelHandlerContext ctx, Object obj) throws Exception { - log.debug("streetId:{}心跳",streetId); - if (obj instanceof IdleStateEvent) { IdleStateEvent event = (IdleStateEvent) obj; if (IdleState.WRITER_IDLE.equals(event.state())) { // 如果写通道处于空闲状态就发送心跳命令 - ctx.channel().writeAndFlush(s); + log.debug("streetId:{}heart",streetId); + ctx.channel().writeAndFlush(heart); } } } - /** - * 业务逻辑处理 - */ - @Override - public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { - log.debug("streetId:{},client receive msg:{}",streetId,msg.toString()); - } } diff --git a/web/src/main/java/com/zhehekeji/web/service/InitService.java b/web/src/main/java/com/zhehekeji/web/service/InitService.java index 535ef52..d52c50e 100644 --- a/web/src/main/java/com/zhehekeji/web/service/InitService.java +++ b/web/src/main/java/com/zhehekeji/web/service/InitService.java @@ -23,8 +23,6 @@ public class InitService implements ApplicationRunner { @Resource private CameraMapper cameraMapper; @Resource - private TcpListener tcpListener; - @Resource private StreetMapper streetMapper; @Override @@ -32,7 +30,6 @@ public class InitService implements ApplicationRunner { List cameras = cameraMapper.selectByMap(new HashMap<>(0)); loginThread loginThread = new loginThread(cameras); loginThread.start(); - tcpListener.run(); } diff --git a/web/src/main/java/com/zhehekeji/web/service/MyProtocolDecoder.java b/web/src/main/java/com/zhehekeji/web/service/MyProtocolDecoder.java index cd44ac7..9fd8b43 100644 --- a/web/src/main/java/com/zhehekeji/web/service/MyProtocolDecoder.java +++ b/web/src/main/java/com/zhehekeji/web/service/MyProtocolDecoder.java @@ -3,6 +3,7 @@ package com.zhehekeji.web.service; import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelHandlerContext; import io.netty.handler.codec.LengthFieldBasedFrameDecoder; +import io.netty.util.CharsetUtil; import lombok.extern.slf4j.Slf4j; import java.nio.charset.Charset; @@ -13,7 +14,7 @@ public class MyProtocolDecoder extends LengthFieldBasedFrameDecoder { private ThreadPoolExecutor threadPoolExecutor; - private OrderService orderService; + private PlcService plcService; /** * * @param maxFrameLength 帧的最大长度 @@ -24,91 +25,73 @@ public class MyProtocolDecoder extends LengthFieldBasedFrameDecoder { * @param failFast 为true,当frame长度超过maxFrameLength时立即报TooLongFrameException异常,为false,读取完整个帧再报异 */ - public MyProtocolDecoder(int maxFrameLength, int lengthFieldOffset, int lengthFieldLength, int lengthAdjustment, int initialBytesToStrip, boolean failFast, ThreadPoolExecutor threadPoolExecutor, OrderService orderService) { + public MyProtocolDecoder(int maxFrameLength, int lengthFieldOffset, int lengthFieldLength, int lengthAdjustment, int initialBytesToStrip, boolean failFast, ThreadPoolExecutor threadPoolExecutor, PlcService plcService) { super(maxFrameLength, lengthFieldOffset, lengthFieldLength, lengthAdjustment, initialBytesToStrip, failFast); this.threadPoolExecutor = threadPoolExecutor; - this.orderService = orderService; + this.plcService = plcService; } @Override protected Object decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception { - in = (ByteBuf) super.decode(ctx,in); + //in = (ByteBuf) super.decode(ctx,in); - if(in == null){ - return null; - } - //包头 `L` `P` - char l = in.readChar(); - char p = in.readChar(); + byte l = in.readByte(); + byte p = in.readByte(); if(l != 76 && p != 80){ //不是包头 丢 - return null; + log.error("??"); + }else { + log.info("baotou come"); } - short length = in.readShort(); - log.debug("length:{}",length); - CharSequence charSequence = in.readCharSequence(6, Charset.defaultCharset()); - String plcId = charSequence.toString(); - log.debug("plcId:{}",plcId); + byte len1 = in.readByte(); + byte len2 = in.readByte(); + + log.info("len1:{},len2:{}",len1,len2); + CharSequence plc = in.readCharSequence(6,Charset.defaultCharset()); + String plcId = plc.toString(); + log.info("plcId:{}",plcId); // OA=心跳 OB=工单 OC=任务 OD=告警 - CharSequence charSequence1 = in.readCharSequence(2,Charset.defaultCharset()); - String type = charSequence1.toString(); - log.debug("type:{}",type); - CharSequence charSequence2 = in.readCharSequence(20,Charset.defaultCharset()); - String orderNum = charSequence2.toString(); - log.debug("订单号:{}",orderNum); - char maohao = in.readChar(); - log.debug("冒号:{}",maohao); - char leixing = in.readChar(); - log.debug("---{}",leixing); - in.readBytes(8); + CharSequence typeChar = in.readCharSequence(2,Charset.defaultCharset()); + String type = typeChar.toString(); + int q =in.readInt(); + + log.info("type:{}",type); -// //读取type字段 -// byte header1 = in.readByte(); -// byte header2 = in.readByte(); -// byte header3 = in.readByte(); -// byte header4 = in.readByte(); -// byte header5 = in.readByte(); -// byte header6 = in.readByte(); -// if(header1 != 20 && header2 != 20 && header3 != 9 && header4 != 7 && header5 != 11 && header6 != 30){ -// //不是包头 直接丢弃 -// return null; -// } -// long length = in.readUnsignedInt(); -// if(in.readableBytes()!=length){ -// throw new Exception("标记的长度不符合实际长度"); -// } -// //读取body -// byte []bytes = new byte[in.readableBytes()]; -// in.readBytes(bytes); -// String string = new String(bytes,"UTF-8"); -// String substring = string.substring(string.indexOf("{"), string.lastIndexOf("}") + 1); -// JSONObject jsonObject = JSONObject.parseObject(substring); -// String deviceId = jsonObject.getString("device_id"); -// log.debug("tcp deviceId:{}",deviceId); -// String dataLength = jsonObject.getString("data_length"); -// Integer flawType = jsonObject.getInteger("msg"); -// String detectStatus = ""; -// if(flawType > 0){ -// detectStatus = "NG"; -// }else { -// detectStatus = "OK"; -// } -// String result = jsonObject.getString("result"); -// if(!StringUtils.isEmpty(result) && !"{}".equals(result)){ -// log.debug(result); -// AdaptData adaptData = JSONObject.parseObject(result,AdaptData.class); -// if(adaptData != null){ -// FlawRunnable flawRunnable = new FlawRunnable(jdbcTemplate,deviceId,"flaw",adaptData); -// threadPoolExecutor.execute(flawRunnable); -// } -// }else { -// log.warn("result为空:{}",result); -// } -// String s2 = string.substring(string.lastIndexOf("}") + 1, string.length()); -// WebSocketMapUtil.send(deviceId,s2,detectStatus); - in.release(); + short short1 = in.readShort(); + short short2 = in.readShort(); + short short3 = in.readShort(); + short short4 = in.readShort(); + short short5 = in.readShort(); + short short6 = in.readShort(); + short short7 = in.readShort(); + short short8 = in.readShort(); + log.info("int:{},1:{},2:{},3:{},4:{},5:{},6:{},7:{},8:{}",q,short1,short2,short3,short4,short5,short6,short7,short8); + if(type.equals("0A")){ + //心跳 + log.info("recieve plc heart"); + }else if(type.equals("0B")){ + String orderNum = ""+q+short1+short2+short3+short4+short5+short6+short7+short8; + log.info("order:{}",orderNum); + if(q ==1){ + log.info("order start"); + plcService.orderStart(orderNum,plcId); + }else if(q == 2){ + log.info("order end"); + plcService.orderStop(orderNum,null,plcId); + } + }else if(type.equals("0C")){ + }else { + + } + byte maohao = in.readByte(); + log.info(":{}",maohao); + byte leixing = in.readByte(); + log.info("---leixing{}",leixing); + byte w = in.readByte(); + log.info("---w{}",w); + in.readBytes(8); return null; } diff --git a/web/src/main/java/com/zhehekeji/web/service/MyProtocolEncoder.java b/web/src/main/java/com/zhehekeji/web/service/MyProtocolEncoder.java index f6c3c04..d7cd4b5 100644 --- a/web/src/main/java/com/zhehekeji/web/service/MyProtocolEncoder.java +++ b/web/src/main/java/com/zhehekeji/web/service/MyProtocolEncoder.java @@ -13,14 +13,20 @@ public class MyProtocolEncoder extends MessageToByteEncoder { if(msg == null){ throw new Exception("msg is null"); } - out.writeChar(msg.getL()); - out.writeChar(msg.getP()); - out.writeShort(msg.getLength()); - out.writeCharSequence(msg.getPlcId(), Charset.defaultCharset()); - out.writeCharSequence(msg.getType(), Charset.defaultCharset()); - out.writeCharSequence(msg.getId(),Charset.defaultCharset()); - out.writeChar(msg.getMaohao()); - out.writeChar(msg.getH()); + out.writeByte(msg.getL()); + out.writeByte(msg.getP()); + out.writeByte(msg.getLength01()); + out.writeByte(msg.getLength02()); + out.writeBytes(msg.getPlcId()); + out.writeBytes(msg.getType()); + out.writeInt(msg.getId()); + for(short s: msg.getIds()){ + out.writeShort(s); + } + out.writeByte(msg.getMaohao()); + out.writeByte(msg.getH()); + out.writeByte(msg.getQ()); out.writeBytes(msg.getEmp()); + } } diff --git a/web/src/main/java/com/zhehekeji/web/service/OrderService.java b/web/src/main/java/com/zhehekeji/web/service/OrderService.java index 4a972c0..a063059 100644 --- a/web/src/main/java/com/zhehekeji/web/service/OrderService.java +++ b/web/src/main/java/com/zhehekeji/web/service/OrderService.java @@ -75,75 +75,6 @@ public class OrderService { return order.getId(); } - public void orderStart(String orderNum) { - Order order = new Order(); - order.setOrderNum(orderNum); - order.setStartTime(LocalDateTime.now()); - //todo 根据订单号,找到plcId,找到巷道 - String plcId = "123"; - Street street = streetMapper.getStreetByPlcId(plcId); - if(street == null){ - log.error("订单开始信号,巷道不存在,orderNum:{},plcId:{}", orderNum,plcId); - return; - } - OrderRealtime.startOrder(street.getId(), orderNum); - orderMapper.update(order, new UpdateWrapper().eq("order_num", orderNum)); - } - - /** - * 结束订单,下载该段时间的视频 - * @param orderNum - * @param type 是否告警 1:是 - */ - public void orderStop(String orderNum,Integer type) { - Order order = orderMapper.getOneByOrderNum(orderNum); - if (order == null) { - log.error("订单结束信号,订单不存在,orderNum:{}", orderNum); - return; - } - if (order.getStartTime() == null) { - log.error("订单结束信号,订单未开始,orderNum:{}", orderNum); - return; - } - if(type != null && type == 1){ - order.setStatus(type); - } - order.setOrderNum(orderNum); - order.setEndTime(LocalDateTime.now()); - //todo 根据订单号,找到plcId,找到巷道 - String plcId = "123"; - Street street = streetMapper.getStreetByPlcId(plcId); - if(street == null){ - log.error("订单结束信号,巷道不存在,orderNum:{},plcId:{}", orderNum,plcId); - return; - } - if (street.getCamera1Id() != null) { - String path = PathUtil.createFileName("mp4"); - PtzControlModule.downloadMp4(street.getCamera1Id(), mp4Path + path, orderNum, order.getStartTime(), order.getEndTime()); - order.setVideoPath1(path); - } - if (street.getCamera2Id() != null) { - String path = PathUtil.createFileName("mp4"); - PtzControlModule.downloadMp4(street.getCamera2Id(), mp4Path + path, orderNum, order.getStartTime(), order.getEndTime()); - order.setVideoPath2(path); - } - orderMapper.update(order, new UpdateWrapper().eq("order_num", orderNum)); - OrderRealtime.stopOrder(street.getId()); - } - - /** - * 发生告警,如果仍有运行的订单,需要将该订单标记为告警,并下载录像 - * @param plcId - */ - public void error(String plcId){ - Street street = streetMapper.getStreetByPlcId(plcId); - if(street == null){ - return; - } - String orderNum = OrderRealtime.stopOrder(street.getId()); - //停止订单 - orderStop(orderNum,1); - } } diff --git a/web/src/main/java/com/zhehekeji/web/service/PlcService.java b/web/src/main/java/com/zhehekeji/web/service/PlcService.java new file mode 100644 index 0000000..78f7eb5 --- /dev/null +++ b/web/src/main/java/com/zhehekeji/web/service/PlcService.java @@ -0,0 +1,168 @@ +package com.zhehekeji.web.service; + +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.zhehekeji.common.util.PathUtil; +import com.zhehekeji.web.entity.Order; +import com.zhehekeji.web.entity.Street; +import com.zhehekeji.web.entity.Warn; +import com.zhehekeji.web.lib.OrderRealtime; +import com.zhehekeji.web.lib.PtzControlModule; +import com.zhehekeji.web.mapper.OrderMapper; +import com.zhehekeji.web.mapper.StreetMapper; +import com.zhehekeji.web.mapper.StreetShelveMapper; +import com.zhehekeji.web.mapper.WarnMapper; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; +import org.springframework.util.StringUtils; + +import javax.annotation.Resource; +import java.time.LocalDateTime; + +@Service +@Slf4j +public class PlcService { + + @Resource + private OrderMapper orderMapper; + @Resource + private StreetShelveMapper streetShelveMapper; + @Resource + private StreetMapper streetMapper; + @Resource + private WarnMapper warnMapper; + + @Value("${picPort}") + private String picPort; + + @Value("${mp4Path}") + private String mp4Path; + + private Street getStreetByPlcId(String plcId){ + Street street = streetMapper.getStreetByPlcId(plcId); + if(street == null){ + log.error("巷道不存在plcId:{}",plcId); + } + return street; + } + + /** + * 开始工单 + * @param orderNum + * @param plcId + */ + public void orderStart(String orderNum,String plcId) { + Order order = new Order(); + String orderNumber = plcId+orderNum; + order.setOrderNum(orderNumber); + order.setStartTime(LocalDateTime.now()); + Street street = getStreetByPlcId(plcId); + if(street != null){ + OrderRealtime.startOrder(street.getId(), orderNumber); + orderMapper.update(order, new UpdateWrapper().eq("order_num", orderNumber)); + } + } + + /** + * 结束订单,下载该段时间的视频 + * @param orderNum + * @param warn 是否告警 1:是 + */ + public void orderStop(String orderNum,Integer warn,String plcId) { + Street street = getStreetByPlcId(plcId); + if(street == null){ + return; + } + String orderNumber = plcId+orderNum; + Order order = orderMapper.getOneByOrderNum(orderNumber); + if (order == null) { + log.error("订单结束信号,订单不存在,orderNum:{}", orderNumber); + return; + } + if (order.getStartTime() == null) { + log.error("订单结束信号,订单未开始,orderNum:{}", orderNumber); + return; + } + if(warn != null && warn == 1){ + order.setStatus(warn); + } + order.setOrderNum(orderNumber); + order.setEndTime(LocalDateTime.now()); + + if (street.getCamera1Id() != null) { + String path = PathUtil.createFileName("mp4"); + PtzControlModule.downloadMp4(street.getCamera1Id(), mp4Path + path, orderNumber, order.getStartTime(), order.getEndTime()); + order.setVideoPath1(path); + } + if (street.getCamera2Id() != null) { + String path = PathUtil.createFileName("mp4"); + PtzControlModule.downloadMp4(street.getCamera2Id(), mp4Path + path, orderNumber, order.getStartTime(), order.getEndTime()); + order.setVideoPath2(path); + } + orderMapper.update(order, new UpdateWrapper().eq("order_num", orderNumber)); + OrderRealtime.stopOrder(street.getId()); + } + + /** + * 收到告警异常开始信号 + * @param plcId + */ + public void warnStart(String plcId,String warnNum){ + synchronized (plcId.intern()){ + Street street = getStreetByPlcId(plcId); + if(street == null){ + return; + } + String orderNum = OrderRealtime.getOrderByStreetId(street.getId()); + Long warnId = null; + if(StringUtils.isEmpty(orderNum)){ + //空的 说明没有正在执行的订单 + //新增 告警 + Warn warn = new Warn(); + warn.setStartTime(LocalDateTime.now()); + warn.setStreetId(street.getId()); + warnMapper.insert(warn); + warnId = warn.getId(); + } + OrderRealtime.startWarn(street.getId(),warnNum,warnId); + } + } + + /** + * 发生告警,如果仍有运行的订单,需要将该订单标记为告警,并下载录像 + * @param plcId + */ + public void wearnStop(String plcId,String warnNum){ + synchronized (plcId.intern()){ + Street street = streetMapper.getStreetByPlcId(plcId); + if(street == null){ + return; + } + Boolean hasWarn = OrderRealtime.stopWarn(street.getId(),warnNum); + if(!hasWarn){ + //不存在告警了 + //是否存在未结束的订单 + String orderNum = OrderRealtime.getOrderByStreetId(street.getId()); + if(!StringUtils.isEmpty(orderNum)){ + //存在未结束的订单 + orderStop(orderNum,1,plcId); + }else { + //是否有告警 + Long warnId = OrderRealtime.getWarnId(street.getId()); + if(warnId != null){ + Warn warn = warnMapper.selectById(warnId); + if(warn != null){ + + warn.setEndTime(LocalDateTime.now()); + } + + OrderRealtime.cleanWarn(street.getId()); + } + } + } + + } + + + } +} diff --git a/web/src/main/java/com/zhehekeji/web/service/SendHeart.java b/web/src/main/java/com/zhehekeji/web/service/SendHeart.java index 4d84355..0181127 100644 --- a/web/src/main/java/com/zhehekeji/web/service/SendHeart.java +++ b/web/src/main/java/com/zhehekeji/web/service/SendHeart.java @@ -5,22 +5,38 @@ import lombok.Data; @Data public class SendHeart { - private char l = 'L'; + private byte l = 'L'; - private char p = 'P'; + private byte p = 'P'; - private short length = 43; + private byte length01 = (byte) 4; + private byte length02 = (byte) 3; - private String plcId = "ABC000"; + private byte[] plcId; - private String type = "0A"; + private byte[] type; - private String id = "0101010101"; + private int id ; - private char maohao = ':'; + private short[]ids =new short[8]; - private char h = 'H'; + private byte maohao = ':'; - private byte[]emp = new byte[]{10}; + private byte h = 'H'; + private byte q = 1; + + private byte[] emp = new byte[8]; + + public SendHeart(String plcIdStr, String typeStr) { + plcId = plcIdStr.getBytes(); + type = typeStr.getBytes(); + for (int i = 0; i < 8; i++) { + ids[i] = (short) 1; + } + id = 1; + for (int j = 0; j < 8; j++) { + emp[j] = (byte) 1; + } + } } diff --git a/web/src/main/java/com/zhehekeji/web/service/TcpListener.java b/web/src/main/java/com/zhehekeji/web/service/TcpListener.java index 71cc16b..0e6c0ad 100644 --- a/web/src/main/java/com/zhehekeji/web/service/TcpListener.java +++ b/web/src/main/java/com/zhehekeji/web/service/TcpListener.java @@ -22,36 +22,36 @@ import java.util.concurrent.TimeUnit; @Slf4j public class TcpListener { - @Value("${tcpPort}") - private Integer tcpPort; - - private static ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(2, 100, 200, - TimeUnit.MILLISECONDS, new ArrayBlockingQueue<>(10000000)); - - @Resource - private OrderService orderService; - - public void run(){ - EventLoopGroup boss = new NioEventLoopGroup(); - EventLoopGroup work = new NioEventLoopGroup(); - try { - ServerBootstrap bootstrap = new ServerBootstrap(); - bootstrap.group(boss,work).channel(NioServerSocketChannel.class).localAddress(tcpPort).childHandler(new ChannelInitializer() { - @Override - public void initChannel(SocketChannel ch) { - ch.pipeline().addLast("handler", new MyProtocolDecoder(1000*10000,6,4,0,0,false,threadPoolExecutor,orderService)); // 自定义业务逻辑处理器 - } - }).childOption(ChannelOption.SO_KEEPALIVE, true); - ChannelFuture future = bootstrap.bind().sync(); - log.info("netty server started, Listening on " + tcpPort); - future.channel().closeFuture().sync(); - }catch (Exception e){ - log.error("netty出错:{}"+e); - e.printStackTrace(); - }finally { - work.shutdownGracefully(); - boss.shutdownGracefully(); - } - } +// @Value("${tcpPort}") +// private Integer tcpPort; +// +// private static ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(2, 100, 200, +// TimeUnit.MILLISECONDS, new ArrayBlockingQueue<>(10000000)); +// +// @Resource +// private OrderService orderService; +// +// public void run(){ +// EventLoopGroup boss = new NioEventLoopGroup(); +// EventLoopGroup work = new NioEventLoopGroup(); +// try { +// ServerBootstrap bootstrap = new ServerBootstrap(); +// bootstrap.group(boss,work).channel(NioServerSocketChannel.class).localAddress(tcpPort).childHandler(new ChannelInitializer() { +// @Override +// public void initChannel(SocketChannel ch) { +// ch.pipeline().addLast("handler", new MyProtocolDecoder(1000*10000,6,4,0,0,false,threadPoolExecutor,orderService)); // 自定义业务逻辑处理器 +// } +// }).childOption(ChannelOption.SO_KEEPALIVE, true); +// ChannelFuture future = bootstrap.bind().sync(); +// log.info("netty server started, Listening on " + tcpPort); +// future.channel().closeFuture().sync(); +// }catch (Exception e){ +// log.error("netty出错:{}"+e); +// e.printStackTrace(); +// }finally { +// work.shutdownGracefully(); +// boss.shutdownGracefully(); +// } +// } }