昆船协议

camera_merge
qiushui 4 years ago
parent b4a63d2090
commit bc09910c91

@ -0,0 +1,24 @@
package com.zhehekeji.web.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.time.LocalDateTime;
/**
*
*/
@Data
@TableName("ksec_up_pc_info")
public class KsecUpPcInfo {
private Integer id;
private String ip;
private Integer port;
private String name;
private LocalDateTime createTime;
}

@ -0,0 +1,7 @@
package com.zhehekeji.web.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.zhehekeji.web.entity.KsecUpPcInfo;
public interface KsecUpPcMapper extends BaseMapper<KsecUpPcInfo> {
}

@ -0,0 +1,13 @@
package com.zhehekeji.web.pojo;
import lombok.Data;
@Data
public class IpInfo {
private Integer id;
private String ip;
private Integer port;
}

@ -1,10 +1,13 @@
package com.zhehekeji.web.service;
import com.zhehekeji.web.entity.Camera;
import com.zhehekeji.web.entity.KsecUpPcInfo;
import com.zhehekeji.web.entity.Street;
import com.zhehekeji.web.lib.*;
import com.zhehekeji.web.mapper.CameraMapper;
import com.zhehekeji.web.mapper.KsecUpPcMapper;
import com.zhehekeji.web.mapper.StreetMapper;
import com.zhehekeji.web.service.ksec.KsecNettyClient;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.ApplicationArguments;
@ -26,34 +29,58 @@ public class InitService implements ApplicationRunner {
private StreetMapper streetMapper;
@Resource
private NettyClient nettyClient;
@Resource
private KsecNettyClient ksecNettyClient;
public static Integer cameraNum;
@Value("${cameraType}")
private Integer cameraType;
@Value("${serverMode}")
private Integer serverMode;
@Resource
private KsecUpPcMapper upPcMapper;
@Override
public void run(ApplicationArguments args) throws Exception {
//球机登录
List<Camera> cameras = cameraMapper.selectByMap(new HashMap<>(0));
loginThread loginThread = new loginThread(cameras, cameraType);
loginThread.start();
//plc 连接状态初始化
List<Street> streets = streetMapper.selectByMap(new HashMap<>(0));
if(serverMode == 0){
log.info("PLC TCP MODE");
//plc 连接状态初始化
List<Street> streets = streetMapper.selectByMap(new HashMap<>(0));
streets.forEach(street -> {
//随便找一个巷道,只要配置了一个球机,就是单个球机的项目
if((street.getCamera1Id() != null && street.getCamera2Id() == null)||(street.getCamera2Id() != null && street.getCamera1Id() == null)){
cameraNum = 1;
}
StreetConn.init(street.getId(),street.getPlcId());
try {
nettyClient.createClient(street);
}catch (Exception e){
log.error("streetId:{}初始plc连接失败,url:{},port:{}",street.getId(),street.getPlcIp(),street.getPlcPort());
}
streets.forEach(street -> {
//随便找一个巷道,只要配置了一个球机,就是单个球机的项目
if((street.getCamera1Id() != null && street.getCamera2Id() == null)||(street.getCamera2Id() != null && street.getCamera1Id() == null)){
cameraNum = 1;
}
StreetConn.init(street.getId(),street.getPlcId());
try {
nettyClient.createClient(street);
}catch (Exception e){
log.error("streetId:{}初始plc连接失败,url:{},port:{}",street.getId(),street.getPlcIp(),street.getPlcPort());
});
}else if(serverMode == 1){
log.info("KESC JSON MODE");
// 昆船协议
KsecUpPcInfo ksec = upPcMapper.selectById(1);
if(ksec != null){
StreetConn.init(1,"ksec");
try {
ksecNettyClient.createClient(ksec);
}catch (Exception e){
log.error("kesc connect error,url:{},port:{}",ksec.getIp(),ksec.getPort());
}
}else {
log.error("ksec no config");
}
});
}
}

@ -59,7 +59,7 @@ public class MyProtocolDecoder extends FixedLengthFrameDecoder {
short short6 = in.readShort();
short short7 = in.readShort();
short short8 = in.readShort();
PlcOrderInfo plcOrderInfo = new PlcOrderInfo(plcId, taskId, (int) short1, (int) short2, (int) short3, (int) short4, (int) short5, (int) short6, (int) short7, (int) short8);
PlcOrderInfo plcOrderInfo = new PlcOrderInfo(plcId, String.valueOf(taskId), (int) short1, (int) short2, (int) short3, (int) short4, (int) short5, (int) short6, (int) short7, (int) short8);
byte maohao = in.readByte();
byte leixing = in.readByte();

@ -12,7 +12,7 @@ public class PlcOrderInfo {
/**
* Id
*/
private Integer taskId;
private String taskId;
/**
* 1 2
@ -56,7 +56,7 @@ public class PlcOrderInfo {
private String orderNum;
public PlcOrderInfo(String plcId,Integer taskId, Integer inOut1, Integer leftRight1, Integer column1, Integer row1, Integer inOut2, Integer leftRight2, Integer column2, Integer row2) {
public PlcOrderInfo(String plcId,String taskId, Integer inOut1, Integer leftRight1, Integer column1, Integer row1, Integer inOut2, Integer leftRight2, Integer column2, Integer row2) {
this.taskId = taskId;
this.inOut1 = inOut1;
this.leftRight1 = leftRight1;

@ -366,7 +366,7 @@ public class PlcService {
String prevFile = mediaPath+stock.getPreoperationPic();
String overFile = mediaPath+stock.getOveroperationPic();
String code = BarCodeScan.detectBestBarCode(overFile);
if(boxNumSys == boxNumAlgo) {
if(boxNumSys == boxNumAlgo && code.equals(barCodeSys)) {
stock.setStatus(StockStatus.SUCCESS.getStatus());
log.info("核对正确");
stockMapper.updateById(stock);

@ -0,0 +1,22 @@
package com.zhehekeji.web.service.ksec;
import com.alibaba.fastjson.JSONObject;
import com.zhehekeji.web.service.SendHeart;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToByteEncoder;
import java.nio.charset.StandardCharsets;
/**
* JSON < >
*/
public class KescEncoder extends MessageToByteEncoder<KsecInfo> {
@Override
protected void encode(ChannelHandlerContext channelHandlerContext, KsecInfo ksecInfo, ByteBuf byteBuf) throws Exception {
String body = "<" + JSONObject.toJSONString(ksecInfo) + ">";
byteBuf.writeBytes(body.getBytes(StandardCharsets.UTF_8));
}
}

@ -0,0 +1,44 @@
package com.zhehekeji.web.service.ksec;
import com.zhehekeji.web.service.*;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.timeout.IdleStateHandler;
import java.util.concurrent.TimeUnit;
/**
*
*
* @author Administrator
*
*/
public class KescFilter extends ChannelInitializer<SocketChannel> {
private KsecInfo ksecInfo;
private PlcService plcService;
private KsecNettyClient nettyClient;
public KescFilter(KsecInfo ksecInfo, PlcService plcService, KsecNettyClient nettyClient){
this.ksecInfo = ksecInfo;
this.plcService = plcService;
this.nettyClient = nettyClient;
}
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline ph = ch.pipeline();
//4秒发一次心跳
ph.addLast(new IdleStateHandler(0, 4, 0, TimeUnit.SECONDS));
ByteBuf byteBuf = Unpooled.copiedBuffer(">".getBytes());
ph.addLast(new KsecDecoder(1000,byteBuf,plcService));
ph.addLast(new KescEncoder());
ph.addLast(new KescNettyHandler(ksecInfo,nettyClient));
}
}

@ -0,0 +1,69 @@
package com.zhehekeji.web.service.ksec;
import com.zhehekeji.web.service.StreetConn;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.timeout.IdleStateEvent;
import lombok.extern.slf4j.Slf4j;
/**
* PLC
*
* @author Administrator
*
*/
@Slf4j
public class KescNettyHandler extends ChannelInboundHandlerAdapter {
/** 客户端请求的心跳命令 */
private KsecInfo heart;
private KsecNettyClient nettyClient;
public KescNettyHandler(KsecInfo ksecInfo,KsecNettyClient nettyClient){
this.heart = ksecInfo;
this.nettyClient = nettyClient;
}
/**
*
*/
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
log.info("upPc connected ");
StreetConn.conn(1);
ctx.fireChannelActive();
}
/**
*
*/
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
log.info("upPc closed");
StreetConn.disConn(1);
log.info(" streetId reconnect......");
nettyClient.reconnect(1);
}
/**
* 4;
*
*/
@Override
public void userEventTriggered(ChannelHandlerContext ctx, Object obj) throws Exception {
if (obj instanceof IdleStateEvent) {
log.debug("upPc send heart");
ctx.channel().writeAndFlush(heart);
IdleStateEvent event = (IdleStateEvent) obj;
// if (IdleState.WRITER_IDLE.equals(event.state())) { // 如果写通道处于空闲状态就发送心跳命令
//
// }
}
}
}

@ -0,0 +1,35 @@
package com.zhehekeji.web.service.ksec;
import lombok.Data;
@Data
public class KsecDataInfo {
private String SRMNumber;
private String CmdName;
private String TaskId;
private Integer FromAddrType;
private Integer FromRow;
private Integer FromBay;
private Integer FromLevel;
private Integer ToAddrType;
private Integer ToRow;
private Integer ToBay;
private Integer ToLevel;
private String code;
private String WarnCode;
private Integer AckStatus;
}

@ -0,0 +1,82 @@
package com.zhehekeji.web.service.ksec;
import com.alibaba.fastjson.JSONObject;
import com.zhehekeji.web.service.OrderAction;
import com.zhehekeji.web.service.PlcOrderInfo;
import com.zhehekeji.web.service.PlcService;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.DelimiterBasedFrameDecoder;
import lombok.extern.slf4j.Slf4j;
import java.nio.charset.Charset;
/**
* TCP JSON
*/
@Slf4j
public class KsecDecoder extends DelimiterBasedFrameDecoder {
private PlcService plcService;
public KsecDecoder(int maxFrameLength, ByteBuf delimiter, PlcService plcService) {
super(maxFrameLength, delimiter);
this.plcService = plcService;
}
@Override
protected Object decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception {
in = (ByteBuf) super.decode(ctx, in);
String body = in.toString(Charset.forName("UTF-8"));
if (body.startsWith("<")){
// 去掉首尾标识符
body = body.substring(1, body.length());
KsecInfo ksecInfo = JSONObject.parseObject(body, KsecInfo.class);
log.info("receieve info:{}", ksecInfo);
KsecDataInfo dataInfo = ksecInfo.getData();
PlcOrderInfo plcOrderInfo = null;
String srmNumber = null;
String cmdName = null;
if(dataInfo != null){
plcOrderInfo = new PlcOrderInfo(dataInfo.getSRMNumber(), dataInfo.getTaskId(), dataInfo.getFromAddrType(), dataInfo.getFromRow(), dataInfo.getFromBay(), dataInfo.getFromLevel(), dataInfo.getToAddrType(), dataInfo.getToRow(), dataInfo.getToBay(), dataInfo.getToLevel());
srmNumber = dataInfo.getSRMNumber();
cmdName = dataInfo.getCmdName();
}
if ("A".equals(ksecInfo.getType())) {
//心跳
} else if ("B".equals(ksecInfo.getType())) {
//任务
if ("B1".equals(cmdName)) {
plcService.orderStart(plcOrderInfo, srmNumber);
} else if ("B2".equals(cmdName)) {
plcService.orderStop(srmNumber, plcOrderInfo.getOrderNum());
}
} else if ("C".equals(ksecInfo.getType())) {
//动作
String code = dataInfo.getCmdName();
log.info("action code,{} plcId:{},orderInfo:{}", code, srmNumber, plcOrderInfo.toString());
if (code.equals("C1") || code.equals("C2") || code.equals("C3") || code.equals("C4") || code.equals("C5")) {
// C1-5 是执行动作,需要保存执行到第几步了
Integer times = OrderAction.put(plcOrderInfo.getOrderNum());
//执行动作
plcService.action(plcOrderInfo, srmNumber, times, code);
} else if (code.equals("C7")) {
//旋转360 然后发送C8命令
plcService.turn360AndC8(srmNumber);
} else {
// 其他命令执行动作
plcService.action(plcOrderInfo, srmNumber, 1, code);
}
} else if ("D".equals(ksecInfo.getType())) {
//todo 告警
} else if ("E".equals(ksecInfo.getType())) {
//盘点
plcService.recordStock(plcOrderInfo, srmNumber, dataInfo.getCode(), 0, 0);
}
}
in.release();
return null;
}
}

@ -0,0 +1,23 @@
package com.zhehekeji.web.service.ksec;
import lombok.AllArgsConstructor;
import lombok.Data;
@Data
@AllArgsConstructor
public class KsecInfo {
private String header;
private String Type;
private KsecDataInfo data;
/**
*
* @return
*/
public static KsecInfo heart(){
return new KsecInfo("LP","A",null);
}
}

@ -0,0 +1,93 @@
package com.zhehekeji.web.service.ksec;
import com.zhehekeji.web.entity.KsecUpPcInfo;
import com.zhehekeji.web.mapper.KsecUpPcMapper;
import com.zhehekeji.web.service.PlcService;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import javax.annotation.Resource;
@Slf4j
@Component
public class KsecNettyClient {
private static EventLoopGroup group = new NioEventLoopGroup();
@Resource
private PlcService plcService;
@Resource
private KsecUpPcMapper ksecUpPcMapper;
/**
*
*/
private static int RECONNECT_NUM = 5;
private static Channel channel;
public void createClient(KsecUpPcInfo ksec){
if (StringUtils.isEmpty(ksec.getIp()) || ksec.getPort() == null) {
return;
}
Bootstrap client = new Bootstrap();
client.group(group);
client.channel(NioSocketChannel.class);
KsecInfo heart = KsecInfo.heart();
client.handler(new KescFilter(heart, plcService,this));
// 连接服务端
try {
channel = client.connect(ksec.getIp(), ksec.getPort()).sync().channel();
} catch (InterruptedException e) {
channel = null;
e.printStackTrace();
throw new RuntimeException("");
}
}
/**
* 线 RECONNECT_NUM
*
* @param upId
*/
public void reconnect(Integer upId) {
Boolean isConnected = false;
int num = 0;
KsecUpPcInfo ksec = ksecUpPcMapper.selectById(upId);
if (ksec == null) {
log.error("reconnect ,upPc is null ,id:{}", upId);
return;
}
while (num < RECONNECT_NUM && !isConnected) {
try {
createClient(ksec);
} catch (Exception e) {
//没连上 继续
log.error("reconnect error num:{}", num);
num++;
continue;
}
isConnected = true;
}
if (isConnected) {
log.info("plc reconnect success");
} else {
log.error("plc reconnect error .upPcId:{},reconnect num:{},name:{},ip:{},port:{}", upId, num, ksec.getName(), ksec.getIp(), ksec.getPort());
}
}
public static void write(KsecInfo ksecInfo){
if(channel != null){
channel.writeAndFlush(ksecInfo);
}else {
log.error(" no connected upPc");
}
}
}
Loading…
Cancel
Save