From 0d580a2b6e4ac2013ba5cbab046bdabf956b301b Mon Sep 17 00:00:00 2001 From: whycq <913841844@qq.com> Date: 星期三, 14 八月 2024 15:18:17 +0800 Subject: [PATCH] # --- app/src/main/java/com/example/agvcontroller/protocol/AGV_02_DOWN.java | 31 +++ app/src/main/java/com/example/agvcontroller/protocol/ForceSwitchAction.java | 28 +++ app/src/main/java/com/example/agvcontroller/protocol/IActionBody.java | 12 + app/src/main/java/com/example/agvcontroller/protocol/AgvActionItem.java | 63 +++++++ app/src/main/java/com/example/agvcontroller/protocol/HandleCmdType.java | 29 +++ app/src/main/java/com/example/agvcontroller/socket/RadixTools.java | 163 ++++++++++++++++++ app/src/main/java/com/example/agvcontroller/MainActivity.java | 16 + app/src/main/java/com/example/agvcontroller/StartActivity.java | 2 app/src/main/java/com/example/agvcontroller/socket/NettyServerHandler.java | 14 + .idea/.name | 1 app/src/main/java/com/example/agvcontroller/protocol/DataSupport.java | 7 app/src/main/java/com/example/agvcontroller/protocol/ProtocolEncoder.java | 35 +++ app/src/main/java/com/example/agvcontroller/socket/NettyServer.java | 11 + app/src/main/java/com/example/agvcontroller/protocol/AgvAction.java | 124 +++++++++++++ 14 files changed, 532 insertions(+), 4 deletions(-) diff --git a/.idea/.name b/.idea/.name new file mode 100644 index 0000000..944eaac --- /dev/null +++ b/.idea/.name @@ -0,0 +1 @@ +AGVController \ No newline at end of file diff --git a/app/src/main/java/com/example/agvcontroller/MainActivity.java b/app/src/main/java/com/example/agvcontroller/MainActivity.java index 69d593f..13761d8 100644 --- a/app/src/main/java/com/example/agvcontroller/MainActivity.java +++ b/app/src/main/java/com/example/agvcontroller/MainActivity.java @@ -15,6 +15,8 @@ import android.view.View; import android.widget.Button; +import com.example.agvcontroller.protocol.AgvAction; +import com.example.agvcontroller.protocol.ForceSwitchAction; import com.example.agvcontroller.protocol2.AgvPackage; import com.example.agvcontroller.protocol2.PackagePart; import com.example.agvcontroller.socket.NettyServerHandler; @@ -43,11 +45,21 @@ private Handler handler = new Handler(new Handler.Callback() { @Override public boolean handleMessage(Message msg) { + + + AgvAction agvAction = new AgvAction<>(ForceSwitchAction.class) + .setAgvNo("1") + .setSerialNo("asdsadsadsad") + .setVal(1) + .bodySync((action) -> action.setPwd((short) 21)); + + // 鍦ㄨ繖閲岃繘琛屾墦鍗拌緭鍑� System.out.println("鎵撳嵃杈撳嚭"); if (isDowm) { - byte[] message2 = new byte[]{0x01, 0x02, 0x03, 0x06}; // 绀轰緥娑堟伅 - nettyServerHandler.sendMessageToClient(clientId, message2); // 鍙戦�佹秷鎭埌瀹㈡埛绔� + System.out.println(agvAction); +// byte[] message2 = new byte[]{0x01, 0x02, 0x03, 0x06}; // 绀轰緥娑堟伅 + nettyServerHandler.sendMessageToClient(clientId, agvAction); // 鍙戦�佹秷鎭埌瀹㈡埛绔� handler.sendEmptyMessageDelayed(0, 100); } return false; diff --git a/app/src/main/java/com/example/agvcontroller/StartActivity.java b/app/src/main/java/com/example/agvcontroller/StartActivity.java index ebc0cdf..adb74d2 100644 --- a/app/src/main/java/com/example/agvcontroller/StartActivity.java +++ b/app/src/main/java/com/example/agvcontroller/StartActivity.java @@ -52,7 +52,7 @@ } }); socketManager = new SocketManager(); - socketManager.startServer(8024); + socketManager.startServer(8022); } @Subscribe(threadMode = ThreadMode.MAIN) diff --git a/app/src/main/java/com/example/agvcontroller/protocol/AGV_02_DOWN.java b/app/src/main/java/com/example/agvcontroller/protocol/AGV_02_DOWN.java index 9578d44..a9a1292 100644 --- a/app/src/main/java/com/example/agvcontroller/protocol/AGV_02_DOWN.java +++ b/app/src/main/java/com/example/agvcontroller/protocol/AGV_02_DOWN.java @@ -42,4 +42,35 @@ // 鍔ㄤ綔鍙傛暟 private ICommandBody commandBody; + public String getSerialNo() { + return serialNo; + } + + public void setSerialNo(String serialNo) { + this.serialNo = serialNo; + } + + public int getCmdCode() { + return cmdCode; + } + + public void setCmdCode(int cmdCode) { + this.cmdCode = cmdCode; + } + + public int getVal() { + return val; + } + + public void setVal(int val) { + this.val = val; + } + + public ICommandBody getCommandBody() { + return commandBody; + } + + public void setCommandBody(ICommandBody commandBody) { + this.commandBody = commandBody; + } } diff --git a/app/src/main/java/com/example/agvcontroller/protocol/AgvAction.java b/app/src/main/java/com/example/agvcontroller/protocol/AgvAction.java new file mode 100644 index 0000000..2ac3817 --- /dev/null +++ b/app/src/main/java/com/example/agvcontroller/protocol/AgvAction.java @@ -0,0 +1,124 @@ +package com.example.agvcontroller.protocol; + + + +import com.example.agvcontroller.socket.NettyServerHandler; +import com.example.agvcontroller.socket.RadixTools; + +import org.json.JSONObject; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + + +/** + * Created by vincent on 2023/3/14 + */ +@SuppressWarnings("all") +public class AgvAction<T extends IActionBody> implements Serializable { + + private static final long serialVersionUID = -1701520567284510548L; + + private String agvNo; + + private String serialNo; + + private int val; + + private T actionBody; + + private HandleCmdType handleCmdType; + + public byte[] writeToBytes() { + +// byte[] bytes = new + String serialNo = Utils.zeroFill(this.serialNo, 16); + byte[] serialNoBytes = Utils.reverse(serialNo.getBytes()); // 娴佹按鍙� + + byte cmdCode = (byte) handleCmdType.cmdCode; // 鍛戒护鐮� + + byte valByte = (byte) val; // 灞炴�у�� + + byte[] bytes = actionBody.writeToBytes(); // 鍛戒护鍙傛暟 + + return new byte[12]; + } + + void readFromBytes(byte[] messageBodyBytes) { + + } + + + public AgvAction(Class<T> clazz) { + try { + actionBody = clazz.newInstance(); + } catch (Exception e) { + e.printStackTrace(); + } + this.handleCmdType = HandleCmdType.find(actionBody.getClass()); + if (null == handleCmdType) { + throw new RuntimeException(clazz.getName() + "妫�绱� HandleCmdType 鏋氫妇澶辫触"); + } + } + + public AgvAction<T> setAgvNo(String agvNo) { + this.agvNo = agvNo; + return this; + } + + public AgvAction<T> setSerialNo(String serialNo) { + this.serialNo = serialNo; + return this; + } + + public AgvAction<T> bodySync(DataSupport<T> dataSupport) { + dataSupport.sync(this.actionBody); + return this; + } + + public static void main(String[] args) { + + AgvAction agvAction = new AgvAction<>(ForceSwitchAction.class) + .setAgvNo("1") + .setSerialNo("asdsadsadsad") + .setVal(1) + .bodySync((action) -> action.setPwd((short) 21)); + + NettyServerHandler.sendMessageToClient("123213", agvAction); + + } + + public String getAgvNo() { + return agvNo; + } + + public String getSerialNo() { + return serialNo; + } + + public T getActionBody() { + return actionBody; + } + + public void setActionBody(T actionBody) { + this.actionBody = actionBody; + } + + public HandleCmdType getHandleCmdType() { + return handleCmdType; + } + + public void setHandleCmdType(HandleCmdType handleCmdType) { + this.handleCmdType = handleCmdType; + } + + public int getVal() { + return val; + } + + public AgvAction<T> setVal(int val) { + this.val = val; + return this; + } +} diff --git a/app/src/main/java/com/example/agvcontroller/protocol/AgvActionItem.java b/app/src/main/java/com/example/agvcontroller/protocol/AgvActionItem.java new file mode 100644 index 0000000..2174a3e --- /dev/null +++ b/app/src/main/java/com/example/agvcontroller/protocol/AgvActionItem.java @@ -0,0 +1,63 @@ +package com.example.agvcontroller.protocol; + + + +import java.io.Serializable; + +/** + * 璺緞鍖� - 璺緞鐐� + * Created by vincent on 2023/3/14 + */ +//@Data +public class AgvActionItem<T extends IActionBody> implements Serializable { + + private static final long serialVersionUID = -6988765550778795176L; + + // 鍦伴潰鐮� + private String qrCode; + + // 鍔ㄤ綔鐮� +// private AgvActionCmdType actionCmdType; + + // 灞炴�у�� + private int val; + + // 鍔ㄤ綔鍙傛暟 + private T actionBody; + + public AgvActionItem() { + } + +// public AgvActionItem(Class<T> clazz) { +// try { +// actionBody = clazz.newInstance(); +// } catch (Exception e) { +// e.printStackTrace(); +// } +// this.actionCmdType = AgvActionCmdType.find(actionBody.getClass()); +// if (null == actionCmdType) { +// throw new CoolException(clazz.getName() + "妫�绱� AgvActionCmdType 鏋氫妇澶辫触"); +// } +// } + + public AgvActionItem<T> setQrCode(String qrCode) { + this.qrCode = qrCode; + return this; + } + +// public AgvActionItem<T> setActionCmdType(AgvActionCmdType actionCmdType) { +// this.actionCmdType = actionCmdType; +// return this; +// } + + public AgvActionItem<T> setVal(int val) { + this.val = val; + return this; + } + + public AgvActionItem<T> bodySync(DataSupport<T> dataSupport) { + dataSupport.sync(this.actionBody); + return this; + } + +} diff --git a/app/src/main/java/com/example/agvcontroller/protocol/DataSupport.java b/app/src/main/java/com/example/agvcontroller/protocol/DataSupport.java new file mode 100644 index 0000000..e6ac0a8 --- /dev/null +++ b/app/src/main/java/com/example/agvcontroller/protocol/DataSupport.java @@ -0,0 +1,7 @@ +package com.example.agvcontroller.protocol; + +public interface DataSupport<T> { + + void sync(T t); + +} diff --git a/app/src/main/java/com/example/agvcontroller/protocol/ForceSwitchAction.java b/app/src/main/java/com/example/agvcontroller/protocol/ForceSwitchAction.java new file mode 100644 index 0000000..d7e2c7a --- /dev/null +++ b/app/src/main/java/com/example/agvcontroller/protocol/ForceSwitchAction.java @@ -0,0 +1,28 @@ +package com.example.agvcontroller.protocol; + +import java.io.Serializable; + +public class ForceSwitchAction implements IActionBody, Serializable { + + private static final long serialVersionUID = -3250235107705010316L; + + private Short pwd; + + @Override + public byte[] writeToBytes() { + return new byte[0]; + } + + @Override + public void readFromBytes(byte[] messageBodyBytes) { + + } + + public Short getPwd() { + return pwd; + } + + public void setPwd(Short pwd) { + this.pwd = pwd; + } +} diff --git a/app/src/main/java/com/example/agvcontroller/protocol/HandleCmdType.java b/app/src/main/java/com/example/agvcontroller/protocol/HandleCmdType.java new file mode 100644 index 0000000..ea73339 --- /dev/null +++ b/app/src/main/java/com/example/agvcontroller/protocol/HandleCmdType.java @@ -0,0 +1,29 @@ +package com.example.agvcontroller.protocol; + +public enum HandleCmdType { + + FORCE_SWITCH(0x80, "寮�鍚�/鍏抽棴寮哄埗", ForceSwitchAction.class), + ; + + public int cmdCode; + + public String desc; + + public Class<? extends IActionBody> cls; + + HandleCmdType(int cmdCode, String desc, Class<? extends IActionBody> cls) { + this.cmdCode = cmdCode; + this.desc = desc; + this.cls = cls; + } + + public static HandleCmdType find(Class<? extends IActionBody> cls) { + for (HandleCmdType value : HandleCmdType.values()) { + if (value.cls.equals(cls)) { + return value; + } + } + return null; + } + +} diff --git a/app/src/main/java/com/example/agvcontroller/protocol/IActionBody.java b/app/src/main/java/com/example/agvcontroller/protocol/IActionBody.java new file mode 100644 index 0000000..5020172 --- /dev/null +++ b/app/src/main/java/com/example/agvcontroller/protocol/IActionBody.java @@ -0,0 +1,12 @@ +package com.example.agvcontroller.protocol; + +/** + * 鍔ㄤ綔鍙傛暟 + */ +public interface IActionBody { + + byte[] writeToBytes(); + + void readFromBytes(byte[] messageBodyBytes); + +} diff --git a/app/src/main/java/com/example/agvcontroller/protocol/ProtocolEncoder.java b/app/src/main/java/com/example/agvcontroller/protocol/ProtocolEncoder.java index 30b8695..9cb2cd5 100644 --- a/app/src/main/java/com/example/agvcontroller/protocol/ProtocolEncoder.java +++ b/app/src/main/java/com/example/agvcontroller/protocol/ProtocolEncoder.java @@ -1,5 +1,7 @@ package com.example.agvcontroller.protocol; +import com.example.agvcontroller.socket.RadixTools; + import java.util.logging.Logger; import io.netty.buffer.ByteBuf; @@ -32,6 +34,39 @@ } else if (obj instanceof byte[]){ out.writeBytes((byte[]) obj); + + } else if (obj instanceof AgvAction<?>){ + + + AgvAction action = (AgvAction)obj; + + String uniqueNo = action.getAgvNo(); + + byte[] uniqueNoBytes = RadixTools.intToBytes(Integer.parseInt(uniqueNo)); // uniqueno + + byte[] bodyBytes = action.writeToBytes(); + + + int len = PackagePart.UNIQUENO.getLen() // len + + PackagePart.TIMESTAMP.getLen() + + PackagePart.COMMAND_MARK.getLen() + + bodyBytes.length; + + out.writeByte((byte)0xEE) // symbol + .writeShortLE(len) + .writeBytes(Utils.reverse(uniqueNoBytes)) // uniqueno + .writeIntLE((int) (System.currentTimeMillis() / 1000)) // timestamp + .writeByte(ProtocolPojoType.ACTION_COMMAND.protocolType.getCode()) // type + .writeBytes(bodyBytes) // body + .writeShort((short)0) // valid + ; + + int validCode = ValidUtil.calculateValidByteFromBuff(out); + out.resetReaderIndex(); + + out.writerIndex(out.readableBytes() - 2); + out.writeShortLE(validCode); + } else if (obj instanceof AgvPackage){ AgvPackage pac = (AgvPackage)obj; diff --git a/app/src/main/java/com/example/agvcontroller/socket/NettyServer.java b/app/src/main/java/com/example/agvcontroller/socket/NettyServer.java index be8a729..06bd508 100644 --- a/app/src/main/java/com/example/agvcontroller/socket/NettyServer.java +++ b/app/src/main/java/com/example/agvcontroller/socket/NettyServer.java @@ -1,5 +1,7 @@ package com.example.agvcontroller.socket; +import com.example.agvcontroller.protocol.ProtocolEncoder; + import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.Channel; import io.netty.channel.ChannelFuture; @@ -32,9 +34,16 @@ .childHandler(new ChannelInitializer<SocketChannel>() { @Override public void initChannel(SocketChannel ch) throws Exception { - ch.pipeline().addLast(new NettyServerHandler()); + ch.pipeline().addLast(new NettyServerHandler()).addLast(new ProtocolEncoder()); } }) +// .childHandler(new ChannelInitializer<Channel>(){ +// +// @Override +// protected void initChannel(Channel ch) throws Exception { +// ch.pipeline().addLast(new ProtocolEncoder()); +// } +// }) .option(ChannelOption.SO_BACKLOG, 128) .childOption(ChannelOption.SO_KEEPALIVE, true); diff --git a/app/src/main/java/com/example/agvcontroller/socket/NettyServerHandler.java b/app/src/main/java/com/example/agvcontroller/socket/NettyServerHandler.java index 73271c0..1bcb965 100644 --- a/app/src/main/java/com/example/agvcontroller/socket/NettyServerHandler.java +++ b/app/src/main/java/com/example/agvcontroller/socket/NettyServerHandler.java @@ -11,6 +11,7 @@ import android.util.Log; import com.example.agvcontroller.Item; +import com.example.agvcontroller.protocol.AgvAction; import org.greenrobot.eventbus.EventBus; @@ -89,6 +90,19 @@ } } + public static void sendMessageToClient(String clientId, AgvAction<?> action) { + + + + Channel channel = channelMap.get(clientId); + if (channel != null && channel.isActive()) { + + channel.writeAndFlush(action); + } else { + Log.d(TAG, "Client " + clientId + " is not connected"); + } + } + @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { cause.printStackTrace(); diff --git a/app/src/main/java/com/example/agvcontroller/socket/RadixTools.java b/app/src/main/java/com/example/agvcontroller/socket/RadixTools.java new file mode 100644 index 0000000..4e1089d --- /dev/null +++ b/app/src/main/java/com/example/agvcontroller/socket/RadixTools.java @@ -0,0 +1,163 @@ +package com.example.agvcontroller.socket; + +import java.io.UnsupportedEncodingException; +import java.nio.charset.Charset; + +/** + * radix tools + * Created by vincent on 2018/10/6 + */ +public class RadixTools { + + public static void main(String[] args) { + String s = RadixTools.toBinaryString((byte) 1); + System.out.println(s); + for(int i=s.length()-1;i>=0;i--){ + char c=s.charAt(i); + if (i == 7 && c =='1'){ + System.out.println("==="); + } + } + } + + /************************************** BinaryString **********************************************/ + + public static String toBinaryString(byte b){ + return Long.toBinaryString((b & 0xFF) + 0x100).substring(1); + } + + public static String toBinaryString(byte[] bytes){ + StringBuilder sb = new StringBuilder(); + for (byte aByte : bytes) { + sb.append(Long.toBinaryString((aByte & 0xFF) + 0x100).substring(1)); + } + return sb.toString(); + } + + /************************************** HexString **********************************************/ + + public static byte[] hexStringToBytes(String hexString) { + if (hexString == null || hexString.equals("")) { + return null; + } + hexString = hexString.toUpperCase(); + int length = hexString.length() / 2; + char[] hexChars = hexString.toCharArray(); + byte[] d = new byte[length]; + for (int i = 0; i < length; i++) { + int pos = i * 2; + d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1])); + } + return d; + } + + public static String bytesToHexStr(byte[] bytes){ + StringBuilder buf = new StringBuilder(bytes.length * 2); + for(byte b : bytes) { + buf.append(String.format("%02x", b & 0xff)); + } + + return buf.toString(); + } + + private static byte charToByte(char c) { + return (byte) "0123456789ABCDEF".indexOf(c); + } + + + /************************************** String **********************************************/ + + public static String bytesToStr(byte[] bytes){ + return bytesToStr(bytes, Charset.forName("gbk")); + } + + public static String bytesToStr(byte[] bytes, Charset charset){ + return new String(bytes, charset).trim().toUpperCase(); + } + + public static byte[] strToBytes(String str) throws UnsupportedEncodingException { + return str.getBytes("gbk"); + } + + /************************************** long **********************************************/ + + public static byte[] longToBytes(long number) { + long temp = number; + byte[] b = new byte[8]; + for (int i = 0; i < b.length; i++) { + b[i] = new Long(temp & 0xff).byteValue();// 灏嗘渶浣庝綅淇濆瓨鍦ㄦ渶浣庝綅 + temp = temp >> 8; // 鍚戝彸绉�8浣� + } + return b; + } + + public static long bytesToLong(byte[] bytes) { + long s = 0; + long s0 = bytes[0] & 0xff;// 鏈�浣庝綅 + long s1 = bytes[1] & 0xff; + long s2 = bytes[2] & 0xff; + long s3 = bytes[3] & 0xff; + long s4 = bytes[4] & 0xff;// 鏈�浣庝綅 + long s5 = bytes[5] & 0xff; + long s6 = bytes[6] & 0xff; + long s7 = bytes[7] & 0xff; + + // s0涓嶅彉 + s1 <<= 8; + s2 <<= 16; + s3 <<= 24; + s4 <<= 8 * 4; + s5 <<= 8 * 5; + s6 <<= 8 * 6; + s7 <<= 8 * 7; + s = s0 | s1 | s2 | s3 | s4 | s5 | s6 | s7; + return s; + } + + + /************************************** int **********************************************/ + + public static byte[] intToBytes(int n) { + byte[] b = new byte[4]; + b[3] = (byte) (n & 0xff); + b[2] = (byte) (n >> 8 & 0xff); + b[1] = (byte) (n >> 16 & 0xff); + b[0] = (byte) (n >> 24 & 0xff); + return b; + } + + + public static int bytesToInt(byte[] b) { + int s = 0; + int s0 = b[0] & 0xff;// 鏈�浣庝綅 + int s1 = b[1] & 0xff; + int s2 = b[2] & 0xff; + int s3 = b[3] & 0xff; + s0 <<= 24; + s1 <<= 16; + s2 <<= 8; + s = s0 | s1 | s2 | s3; + return s; + } + + /************************************** short **********************************************/ + + public static short byteToShort(byte[] b) { + short s = 0; + short s0 = (short) (b[1] & 0xff);// 鏈�浣庝綅 + short s1 = (short) (b[0] & 0xff); + s1 <<= 8; + s = (short) (s0 | s1); + return s; + } + + public static byte[] shortToByte(short s){ + byte[] b = new byte[2]; + for(int i = 0; i < 2; i++){ + int offset = 16 - (i+1)*8; //鍥犱负byte鍗�4涓瓧鑺傦紝鎵�浠ヨ璁$畻鍋忕Щ閲� + b[i] = (byte)((s >> offset)&0xff); //鎶�16浣嶅垎涓�2涓�8浣嶈繘琛屽垎鍒瓨鍌� + } + return b; + } + +} -- Gitblit v1.9.1