Browse Source

开始添加遥控 遥调命令 1

xiuwei 4 years ago
parent
commit
3fc1addac0
17 changed files with 517 additions and 153 deletions
  1. 0 139
      protocol-iec104/README.en.md
  2. 95 0
      protocol-iec104/src/test/java/ReadFile.java
  3. 8 1
      protocol-modbus/src/main/java/wei/yigulu/modbus/domain/FunctionCode.java
  4. 33 0
      protocol-modbus/src/main/java/wei/yigulu/modbus/domain/ModbusPacketInterface.java
  5. 131 0
      protocol-modbus/src/main/java/wei/yigulu/modbus/domain/command/AbstractModbusCommand.java
  6. 51 0
      protocol-modbus/src/main/java/wei/yigulu/modbus/domain/command/RtuModbusCommand.java
  7. 63 0
      protocol-modbus/src/main/java/wei/yigulu/modbus/domain/command/TcpModbusCommand.java
  8. 44 1
      protocol-modbus/src/main/java/wei/yigulu/modbus/domain/datatype/BooleanModbusDataInCoil.java
  9. 7 0
      protocol-modbus/src/main/java/wei/yigulu/modbus/domain/datatype/BooleanModbusDataInRegister.java
  10. 9 0
      protocol-modbus/src/main/java/wei/yigulu/modbus/domain/datatype/IModbusDataType.java
  11. 1 6
      protocol-modbus/src/main/java/wei/yigulu/modbus/domain/datatype/NumericModbusData.java
  12. 57 0
      protocol-modbus/src/main/java/wei/yigulu/modbus/domain/datatype/numeric/SingleCommandCoilValue.java
  13. 7 2
      protocol-modbus/src/main/java/wei/yigulu/modbus/domain/request/AbstractModbusRequest.java
  14. 4 1
      protocol-modbus/src/main/java/wei/yigulu/modbus/domain/request/RtuModbusRequest.java
  15. 3 1
      protocol-modbus/src/main/java/wei/yigulu/modbus/domain/request/TcpModbusRequest.java
  16. 4 1
      protocol-modbus/src/main/java/wei/yigulu/modbus/domain/response/AbstractModbusResponse.java
  17. 0 1
      protocol-modbus/src/main/java/wei/yigulu/modbus/domain/synchronouswaitingroom/RtuSynchronousWaitingRoom.java

+ 0 - 139
protocol-iec104/README.en.md

@@ -1,139 +0,0 @@
-###### 本工具是本人基于工作所需开发的针对于IEC104通讯的辅助工具
-
-该工具针对U帧和S帧已经做好了收发逻辑,但是I帧的具体处理逻辑需要使用者自己实现
-
-本工具基于netty框架。建议有netty使用经验和对104通讯规约的人使用。如果不了解104通讯规约,理解本工具的工作流程可能会有些麻烦。
-
-# 使用方式 
-
-## Matser的创建 以及数据的接收处理:
-
-### Matser的创建 
-
-```java
-SimpleMasterBuilder simpleMasterBuilder=new SimpleMasterBuilder("127.0.0.1",2404);
-        simpleMasterBuilder.create();
-```
-
- 上面 这种master仅支持一个ip和端口号,与之相对的是HSMasterBuilder 支持主备链接 ,主动切换。
-
-```java
- HSMasterBuilder masterBuilder=new HSMasterBuilder("127.0.0.1",2404).setSpareIp("127.0.0.2");
-        masterBuilder.create();
-```
-
-create() 方法会阻塞线程,如果不希望阻塞线程可以使用createByUnBlock(),以工具内的单线程池执行。
-
-### 数据的接收
-
-首先向slave端发送总召唤
-
-```java
-        //创建总召唤类型I帧
-        TotalSummonType totalSummonType=new TotalSummonType();
-        //反向生成asdu
-        Asdu asdu = totalSummonType.generateBack();
-        //配置总召唤发送原因
-        asdu.setNot(6);
-        //配置公共地址位
-        asdu.setCommonAddress(1);
-        Apdu apdu=new Apdu().setAsdu(asdu);
-        masterBuilder.sendFrame(apdu);
-```
-
-实现对应数据类型的数据接收后的处理,以数据类型为13的浮点数为例
-
-```java
-@Slf4j
-@AsduType(typeId=13)
-public class HandleShortFloat extends ShortFloatType {
-
-
-    /**
-     * 处理短浮点数据
-     *
-     * @param apdu
-     * @return
-     */
-    @Override
-    public byte[][] handleAndAnswer(Apdu apdu) {
-        log.info("----------处理短浮点数据---------");
-        Map<Integer, Float> map = new HashMap<>();
-        HandleShortFloat handleShortFloat = (HandleShortFloat) apdu.getAsdu().getDataFrame();
-        List<InformationBodyAddress> address = handleShortFloat.getAddresses();
-        Map<IeMeasuredQuality, Float> datas = handleShortFloat.getDatas();
-        int i = 0;
-        //存入共享服务端
-        if (apdu.getAsdu().getVsq().getSq() == 0) {
-            log.warn("------处理短浮点单一寻址-----");
-            for (Map.Entry<IeMeasuredQuality, Float> e : datas.entrySet()) {
-                map.put(address.get(i++).getAddress(), e.getValue());
-            }
-        } else if (apdu.getAsdu().getVsq().getSq() == 1) {
-            log.warn("------处理短浮点连续寻址-----");
-            i = address.get(0).getAddress();
-            for (Map.Entry<IeMeasuredQuality, Float> e : datas.entrySet()) {
-                map.put(i++, e.getValue());
-            }
-        }
-        //将map 储起来
-       //TODO
-        
-        //如果有需要返回数据帧可以创建byte数据  向内置入要返回的数据帧encode()后的数组
-        return null;
-    }
-}
-```
-
-## Slave端的创建及数据的发送
-
-### Slave端的创建
-
-```java
-SlaverBuilder slaverBuilder=new SlaverBuilder();
-slaverBuilder.create();
-```
-
-数据响应 响应总召唤
-
-```java
-@AsduType(typeId = 100)
-@Slf4j
-public class HandleTotalSummonType extends TotalSummonType {
-
-
-	@Override
-	public byte[][] handleAndAnswer(Apdu apdu) throws Exception {
-		TotalSummonType dataFrameType = (TotalSummonType) (apdu.getAsdu().getDataFrame());
-		Channel channel = apdu.getChannel();
-		int commonAddress = apdu.getAsdu().getCommonAddress();
-		if (dataFrameType.getValue() == 20 && apdu.getAsdu().getCot().getNot() == 6) {
-			//1.回应激活确认总召唤
-			SendDataFrameHelper.sendTotalSummonFrame(channel, commonAddress, 7);
-			//2.回应连续寻址短浮点i帧
-			SendDataFrameHelper.sendYcDataFrame(channel, //TODO 传入<Integer,Number>类型的数据map
-                                                , commonAddress, 20);
-			//3.回应激活终止总召唤总召唤
-			SendDataFrameHelper.sendTotalSummonFrame(channel, commonAddress, 8);
-		}
-		return null;
-	}
-
-
-```
-
-突发上送数据 向所有接入的master突发上送map中的数据
-
-```java
-for (Channel channel : slaverBuilder.getChannels()) {
-				try {
-					SendDataFrameHelper.sendYcDataFrameDiscontinuity(channel, //TODO 传入<Integer,Number>类型的数据map
-                                                                     , 1, 3);
-				} catch (Exception e) {
-					e.printStackTrace();
-				}
-			}
-```
-
-##### 更加深入的应用请研究代码  apdu asdu 和各个类型的报文帧  都支持重写,包括拆包工具也支持重写,如果有疑问可以向 weiyigulu524710549@gmail.com  邮箱留言
-

+ 95 - 0
protocol-iec104/src/test/java/ReadFile.java

@@ -0,0 +1,95 @@
+import ch.qos.logback.core.Appender;
+import io.netty.buffer.Unpooled;
+import wei.yigulu.iec104.apdumodel.Apdu;
+import wei.yigulu.iec104.apdumodel.Asdu;
+import wei.yigulu.iec104.asdudataframe.ShortFloatType;
+import wei.yigulu.iec104.asdudataframe.qualitydescription.IeMeasuredQuality;
+
+import java.io.*;
+import java.time.LocalTime;
+import java.util.Map;
+
+/**
+ * @author: xiuwei
+ * @version:
+ */
+public class ReadFile {
+
+
+	public static void main(String[] args) throws Exception {
+		BufferedWriter out = new BufferedWriter(new FileWriter("C:\\Users\\Administrator\\Desktop\\星能3-4.15解析.txt"));
+
+
+		File file = new File("C:\\Users\\Administrator\\Desktop\\104m_04_20210415.log");//定义一个file对象,用来初始化FileReader
+		FileReader reader = new FileReader(file);//定义一个fileReader对象,用来初始化BufferedReader
+		BufferedReader bReader = new BufferedReader(reader);//new一个BufferedReader对象,将文件内容读取到缓存
+		StringBuilder sb = new StringBuilder();//定义一个字符串缓存,将字符串存放缓存中
+		String s = "";
+		while ((s =bReader.readLine()) != null) {//逐行读取文件内容,不读取换行符和末尾的空格
+			if(s.contains("recv :")&&!s.contains("-")){
+				String f="";
+				f+=s.substring(0,15)+"\r";
+				Apdu a=new Apdu().loadByteBuf(Unpooled.copiedBuffer(Hex2Bytes(s.substring(23).replaceAll(" ",""))));
+				Asdu asdu=a.getAsdu();
+				if(asdu!=null && asdu.getDataFrame() instanceof ShortFloatType){
+					ShortFloatType ss=(ShortFloatType)asdu.getDataFrame();
+					if (ss.getAddresses().size() == 1) {
+						int j=0;
+						for (Map.Entry<IeMeasuredQuality, Float> e : ss.getDatas().entrySet()) {
+							f+=dayin(ss.getAddresses().get(0).getAddress()+j,e.getValue());
+							j++;
+						}
+					} else {
+						int f1 = 0;
+						for (Map.Entry<IeMeasuredQuality, Float> i : ss.getDatas().entrySet()) {
+							f+=dayin( ss.getAddresses().get(f1++).getAddress(),i.getValue());
+						}
+					}
+				}
+				if(f.length()>16){
+					System.out.println(f);
+					out.write(f);
+				}
+			}
+		}
+		bReader.close();
+		out.close();
+		String str = sb.toString();
+		System.out.println(str );
+
+
+
+	}
+
+
+	public static byte[] Hex2Bytes(String hexString){
+		byte[] arrB = hexString.getBytes();
+		int iLen = arrB.length;
+		byte[] arrOut = new byte[iLen / 2];
+		String strTmp = null;
+		for (int i = 0; i < iLen; i += 2)
+		{
+			strTmp = new String(arrB, i, 2);
+			arrOut[(i / 2)] = ((byte)Integer.parseInt(strTmp, 16));
+		}
+		return arrOut;
+	}
+
+
+
+	public static String dayin(int key, Float value){
+		String s="";
+		int i;
+		if(key==16385){
+			s+="                  实际功率 : "+value+"\r";
+		}
+		if(key>16421&&key<16921 && (key-16422)%6==0){
+			i=(key-16422)/6+1;
+			if(i==9||i==16||i==31||i==44||i==48||i==59){
+				s+="                  样"+i+" : "+value+"\r";
+			}else{s+="                  "+i+" : "+value+"\r";}
+
+		}
+		return s;
+	}
+}

+ 8 - 1
protocol-modbus/src/main/java/wei/yigulu/modbus/domain/FunctionCode.java

@@ -58,7 +58,12 @@ public enum FunctionCode {
 	/**
 	 * Constant <code>WRITE_MASK_REGISTER 22</code>
 	 */
-	WRITE_MASK_REGISTER(22);
+	WRITE_MASK_REGISTER(22),
+
+	/**
+	 * Constant <code>READ_WRITE_REGISTERS 23</code>
+	 */
+	READ_WRITE_REGISTERS(23);
 
 
 	@Getter
@@ -97,6 +102,8 @@ public enum FunctionCode {
 				return REPORT_SLAVE_ID;
 			case 22:
 				return WRITE_MASK_REGISTER;
+			case 23:
+				return READ_WRITE_REGISTERS;
 			default:
 				throw new IllegalArgumentException();
 		}

+ 33 - 0
protocol-modbus/src/main/java/wei/yigulu/modbus/domain/ModbusPacketInterface.java

@@ -0,0 +1,33 @@
+package wei.yigulu.modbus.domain;
+
+import wei.yigulu.modbus.domain.response.AbstractModbusResponse;
+import wei.yigulu.modbus.exceptiom.ModbusException;
+
+import java.nio.ByteBuffer;
+import java.util.List;
+
+/**
+ * @program: protocol
+ * @description: Modbus 报文接口
+ * @author: xiuwei
+ * @create: 2021-04-27 11:27
+ */
+public interface ModbusPacketInterface {
+
+
+	/**
+	 * 解码
+	 *
+	 * @param byteBuf 字节缓冲区
+	 * @return {@link AbstractModbusResponse}* @throws ModbusException modbus例外
+	 */
+	ModbusPacketInterface decode(ByteBuffer byteBuf) throws ModbusException;
+
+
+	/**
+	 * 编码
+	 *
+	 * @param bytes 字节
+	 */
+	ModbusPacketInterface encode(List<Byte> bytes) throws ModbusException;
+}

+ 131 - 0
protocol-modbus/src/main/java/wei/yigulu/modbus/domain/command/AbstractModbusCommand.java

@@ -0,0 +1,131 @@
+package wei.yigulu.modbus.domain.command;
+
+import com.google.common.primitives.Bytes;
+import lombok.Setter;
+import lombok.experimental.Accessors;
+import wei.yigulu.modbus.domain.FunctionCode;
+import wei.yigulu.modbus.domain.ModbusPacketInterface;
+import wei.yigulu.modbus.domain.datatype.BooleanModbusDataInCoil;
+import wei.yigulu.modbus.domain.datatype.Register;
+import wei.yigulu.modbus.domain.datatype.RegisterValue;
+import wei.yigulu.modbus.domain.datatype.numeric.P_AB;
+import wei.yigulu.modbus.domain.datatype.numeric.SingleCommandCoilValue;
+import wei.yigulu.modbus.exceptiom.ModbusException;
+
+import javax.annotation.Nonnull;
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @program: protocol
+ * @description: modbus的控制命令
+ * @author: xiuwei
+ * @create: 2021-04-26 16:14
+ */
+public abstract class AbstractModbusCommand implements ModbusPacketInterface {
+
+
+	/**
+	 * 客户端地址 一字节
+	 */
+	@Setter
+	@Accessors(chain = true)
+	protected Integer slaveId = 01;
+
+	/**
+	 * 功能码  一字节
+	 */
+	protected FunctionCode functionCode;
+
+	/**
+	 * 下达数据的起始地址位  两字节
+	 */
+	protected Integer startAddress;
+
+	/**
+	 * 输出数据的数量  两字节  (线圈或者寄存器的数量) 两字节  15 16 有    5 6 没有
+	 */
+	protected Integer quantity;
+
+	/**
+	 * 输出数据的字节数  一字节(线圈数量*1或寄存器数量*2) 15 16 有    5 6 没有
+	 */
+	protected Integer numOfByte;
+
+	/**
+	 * 具体输出值的内容
+	 */
+	protected byte[] dataBytes;
+
+
+	public AbstractModbusCommand setRegisters(@Nonnull Integer startAddress, @Nonnull List<RegisterValue> values) {
+		if (values.size() == 0) {
+			throw new RuntimeException("未传入具体的控制值");
+		}
+		this.startAddress = startAddress;
+		List<Register> registers = new ArrayList<>();
+		for (RegisterValue rv : values) {
+			registers.addAll(rv.getRegisters());
+		}
+		if (registers.size() == 1) {
+			functionCode = FunctionCode.WRITE_REGISTERS;
+			this.quantity = registers.size();
+			this.numOfByte = registers.size() * 2;
+			dataBytes = new byte[numOfByte];
+			for (int i = 0; i < registers.size(); i++) {
+				this.dataBytes[i * 2] = registers.get(i).getB1();
+				this.dataBytes[i * 2 + 1] = registers.get(i).getB2();
+			}
+		} else {
+			functionCode = FunctionCode.WRITE_REGISTER;
+			this.quantity = null;
+			this.numOfByte = null;
+			dataBytes = new byte[2];
+			this.dataBytes[0] = registers.get(0).getB1();
+			this.dataBytes[1] = registers.get(0).getB2();
+		}
+		return this;
+	}
+
+
+	public AbstractModbusCommand setCoils(Integer startAddress, List<Boolean> values) {
+		if (values.size() == 0) {
+			throw new RuntimeException("未传入具体的控制值");
+		}
+		this.startAddress = startAddress;
+		if (values.size() == 1) {
+			functionCode = FunctionCode.WRITE_COIL;
+			this.quantity = null;
+			this.numOfByte = null;
+			dataBytes = new SingleCommandCoilValue(values.get(0)).encode();
+		} else {
+			functionCode = FunctionCode.WRITE_COILS;
+			this.quantity = values.size();
+			List<BooleanModbusDataInCoil> booleanModbusDataInCoils = BooleanModbusDataInCoil.getFormBooleanList(values);
+			this.numOfByte = booleanModbusDataInCoils.size();
+			List<Byte> byteList = new ArrayList<>();
+			booleanModbusDataInCoils.forEach(o -> o.encode(byteList));
+			this.dataBytes = Bytes.toArray(byteList);
+		}
+		return this;
+	}
+
+
+	@Override
+	public AbstractModbusCommand encode(List<Byte> bytes) throws ModbusException {
+		bytes.add((byte) (slaveId & 0xff));
+		bytes.add((byte) (functionCode.getCode() & 0xff));
+		new P_AB(BigDecimal.valueOf(startAddress)).encode(bytes);
+		if (quantity != null) {
+			new P_AB(BigDecimal.valueOf(quantity)).encode(bytes);
+		}
+		if (numOfByte != null) {
+			bytes.add((byte) (numOfByte & 0xff));
+		}
+		bytes.addAll(Bytes.asList(dataBytes));
+		return this;
+	}
+
+
+}

+ 51 - 0
protocol-modbus/src/main/java/wei/yigulu/modbus/domain/command/RtuModbusCommand.java

@@ -0,0 +1,51 @@
+package wei.yigulu.modbus.domain.command;
+
+import com.google.common.primitives.Bytes;
+import wei.yigulu.modbus.domain.ModbusPacketInterface;
+import wei.yigulu.modbus.domain.datatype.numeric.P_BA;
+import wei.yigulu.modbus.domain.request.RtuModbusRequest;
+import wei.yigulu.modbus.exceptiom.ModbusException;
+import wei.yigulu.utils.CrcUtils;
+
+import java.math.BigDecimal;
+import java.nio.ByteBuffer;
+import java.util.List;
+
+/**
+ * RTU的控制命令
+ *
+ * @author: xiuwei
+ * @version:
+ */
+public class RtuModbusCommand extends AbstractModbusCommand{
+
+	/**
+	 * crc 校验  两位 除去本两位 其余所有字节的校验位
+	 */
+	protected Integer crc16;
+
+	/**
+	 * 编码
+	 *
+	 * @param bytes 字节
+	 * @return
+	 */
+	@Override
+	public RtuModbusCommand encode(List<Byte> bytes) throws ModbusException {
+		super.encode(bytes);
+		this.crc16 = CrcUtils.generateCRC16(Bytes.toArray(bytes));
+		new P_BA(BigDecimal.valueOf(this.crc16)).encode(bytes);
+		return this;
+	}
+
+	/**
+	 * 解码
+	 *
+	 * @param byteBuf 字节缓冲
+	 */
+	@Override
+	public RtuModbusCommand decode(ByteBuffer byteBuf) throws ModbusException {
+		//super.decode(byteBuf);
+		return this;
+	}
+}

+ 63 - 0
protocol-modbus/src/main/java/wei/yigulu/modbus/domain/command/TcpModbusCommand.java

@@ -0,0 +1,63 @@
+package wei.yigulu.modbus.domain.command;
+
+import lombok.Setter;
+import wei.yigulu.modbus.domain.datatype.numeric.P_AB;
+import wei.yigulu.modbus.domain.tcpextracode.TcpExtraCode;
+import wei.yigulu.modbus.domain.tcpextracode.TransactionIdentifier;
+import wei.yigulu.modbus.exceptiom.ModbusException;
+
+import java.math.BigDecimal;
+import java.nio.ByteBuffer;
+import java.util.List;
+
+/**
+ * tcp写的modbus 控制命令
+ *
+ * @author: xiuwei
+ * @version:
+ */
+
+public class TcpModbusCommand extends AbstractModbusCommand {
+	/**
+	 * tcp通讯时的前端附加码
+	 */
+	@Setter
+	protected TcpExtraCode tcpExtraCode = new TcpExtraCode();
+	/**
+	 * 除去四个附加码 和两个长度字节 剩余的报文的字节个数
+	 */
+	@Setter
+	protected Integer length = 6;
+
+	/**
+	 * 设置事务标识符
+	 *
+	 * @param transactionIdentifier
+	 * @return
+	 */
+	public TcpModbusCommand setTransactionIdentifier(TransactionIdentifier transactionIdentifier) {
+		this.tcpExtraCode.setTransactionIdentifier(transactionIdentifier);
+		return this;
+	}
+
+	@Override
+	public TcpModbusCommand encode(List<Byte> bytes) throws ModbusException {
+		tcpExtraCode.encode(bytes);
+		new P_AB(BigDecimal.valueOf(length)).encode(bytes);
+		super.encode(bytes);
+		return this;
+	}
+
+
+	@Override
+	public TcpModbusCommand decode(ByteBuffer byteBuf) throws ModbusException {
+		if (byteBuf.remaining() != 12) {
+			throw new ModbusException("该帧非数据请求帧");
+		}
+		this.tcpExtraCode.decode(byteBuf);
+		this.setLength(new P_AB().decode(byteBuf).getValue().intValue());
+		//super.decode(byteBuf);
+		return this;
+	}
+
+}

+ 44 - 1
protocol-modbus/src/main/java/wei/yigulu/modbus/domain/datatype/BooleanModbusDataInCoil.java

@@ -1,6 +1,8 @@
 package wei.yigulu.modbus.domain.datatype;
 
 import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.List;
 
 /**
  * 8个布尔值组成的数据类型
@@ -11,10 +13,12 @@ import java.nio.ByteBuffer;
  */
 public class BooleanModbusDataInCoil extends CoilValue {
 
+	public static final int BIT_NUM =8;
+
 	/**
 	 * 八个布尔 对应一字节 八比特
 	 */
-	boolean[] values = new boolean[8];
+	boolean[] values = new boolean[BIT_NUM];
 
 
 	@Override
@@ -28,6 +32,18 @@ public class BooleanModbusDataInCoil extends CoilValue {
 
 	}
 
+	@Override
+	public BooleanModbusDataInCoil encode(List<Byte> bytes) {
+		byte b=0;
+		for (int i = 0; i <values.length ; i++) {
+			if(this.values[i]){
+				b=(byte)(b|0x01>>i);
+			}
+		}
+		bytes.add(b);
+		return this;
+	}
+
 	private IModbusDataType getValFormByte(byte b) {
 		for (int i = 0; i < values.length; i++) {
 			this.values[i] = (byte) ((b >> i) & 0x01) == 0x01;
@@ -52,5 +68,32 @@ public class BooleanModbusDataInCoil extends CoilValue {
 		}
 	}
 
+	/**
+	 * 通过布尔list 生成 List<BooleanModbusDataInCoil>
+	 *
+	 * @param booleanValues 布尔值
+	 * @return {@link List<BooleanModbusDataInCoil>}
+	 */
+	public static List<BooleanModbusDataInCoil> getFormBooleanList(List<Boolean> booleanValues){
+		int size= Double.valueOf(Math.ceil(booleanValues.size()/BIT_NUM)).intValue();
+		List<BooleanModbusDataInCoil> booleanModbusDataInCoils=new ArrayList<>();
+		BooleanModbusDataInCoil booleanModbusDataInCoil;
+		int index;
+		for (int i = 0; i < size; i++) {
+			booleanModbusDataInCoil=new BooleanModbusDataInCoil();
+			for (int j = 0; j <BIT_NUM; j++) {
+				index=BIT_NUM*i+j;
+				if (booleanValues.size()>index){
+					booleanModbusDataInCoil.setValue(j,booleanValues.get(index));
+				}else{
+					booleanModbusDataInCoils.add(booleanModbusDataInCoil);
+					break;
+				}
+				booleanModbusDataInCoils.add(booleanModbusDataInCoil);
+			}
+		}
+		return booleanModbusDataInCoils;
+	}
+
 
 }

+ 7 - 0
protocol-modbus/src/main/java/wei/yigulu/modbus/domain/datatype/BooleanModbusDataInRegister.java

@@ -38,6 +38,13 @@ public class BooleanModbusDataInRegister extends RegisterValue {
 
 	}
 
+	@Override
+	public IModbusDataType encode(List<Byte> bytes) {
+		bytes.add(getByteFormValue(0));
+		bytes.add(getByteFormValue(1));
+		return this;
+	}
+
 	private BooleanModbusDataInRegister getValFormByte(byte b1, byte b2) {
 		for (int i = 0; i < ONEBYTEBOOL; i++) {
 			this.values[i] = (byte) ((b1 >> i) & 0x01) == 0x01;

+ 9 - 0
protocol-modbus/src/main/java/wei/yigulu/modbus/domain/datatype/IModbusDataType.java

@@ -1,6 +1,7 @@
 package wei.yigulu.modbus.domain.datatype;
 
 import java.nio.ByteBuffer;
+import java.util.List;
 
 /**
  * modbus的数据类型的抽象类
@@ -28,4 +29,12 @@ public interface IModbusDataType {
 	IModbusDataType decode(ByteBuffer byteBuf);
 
 
+	/**
+	 * 编码
+	 *
+	 * @param bytes 字节
+	 */
+	public abstract IModbusDataType encode(List<Byte> bytes);
+
+
 }

+ 1 - 6
protocol-modbus/src/main/java/wei/yigulu/modbus/domain/datatype/NumericModbusData.java

@@ -26,11 +26,6 @@ public abstract class NumericModbusData extends RegisterValue {
 	@Accessors(chain = true)
 	protected BigDecimal value;
 
-	/**
-	 * 编码
-	 *
-	 * @param bytes 字节
-	 */
-	public abstract IModbusDataType encode(List<Byte> bytes);
+
 
 }

+ 57 - 0
protocol-modbus/src/main/java/wei/yigulu/modbus/domain/datatype/numeric/SingleCommandCoilValue.java

@@ -0,0 +1,57 @@
+package wei.yigulu.modbus.domain.datatype.numeric;
+
+import lombok.AllArgsConstructor;
+import lombok.NoArgsConstructor;
+import org.checkerframework.checker.units.qual.C;
+import wei.yigulu.modbus.domain.datatype.CoilValue;
+import wei.yigulu.modbus.domain.datatype.IModbusDataType;
+
+import java.nio.ByteBuffer;
+import java.util.List;
+
+/**
+ * 命令报文中的coil设定值
+ *
+ * @author: xiuwei
+ * @vesion:
+ */
+@AllArgsConstructor
+@NoArgsConstructor
+public class SingleCommandCoilValue extends CoilValue {
+
+	boolean bValue;
+
+
+	@Override
+	public IModbusDataType decode(byte[] bytes, int offset) {
+		return null;
+	}
+
+	@Override
+	public IModbusDataType decode(ByteBuffer byteBuf) {
+		return null;
+	}
+
+	@Override
+	public IModbusDataType encode(List<Byte> bytes) {
+		if(bValue) {
+			bytes.add ((byte) 0xff);
+		}else{
+			bytes.add ((byte) 0x00);
+		}
+		bytes.add ((byte) 0x00);
+		return this;
+	}
+
+
+	public byte[] encode() {
+		byte[] bs=new byte[2];
+		if(bValue) {
+			bs[0] = (byte) 0xff;
+		}else{
+			bs[0] = (byte) 0x00;
+		}
+		bs[1] = (byte)0x00;
+		return bs;
+	}
+}

+ 7 - 2
protocol-modbus/src/main/java/wei/yigulu/modbus/domain/request/AbstractModbusRequest.java

@@ -4,6 +4,7 @@ package wei.yigulu.modbus.domain.request;
 import lombok.Data;
 import lombok.experimental.Accessors;
 import wei.yigulu.modbus.domain.FunctionCode;
+import wei.yigulu.modbus.domain.ModbusPacketInterface;
 import wei.yigulu.modbus.domain.datatype.numeric.P_AB;
 import wei.yigulu.modbus.exceptiom.ModbusException;
 
@@ -19,7 +20,7 @@ import java.util.List;
  */
 @Data
 @Accessors(chain = true)
-public class AbstractModbusRequest {
+public class AbstractModbusRequest  implements ModbusPacketInterface {
 
 
 	/**
@@ -46,12 +47,15 @@ public class AbstractModbusRequest {
 	 * 编码
 	 *
 	 * @param bytes 字节
+	 * @return
 	 */
-	public void encode(List<Byte> bytes) {
+	@Override
+	public AbstractModbusRequest encode(List<Byte> bytes) {
 		bytes.add((byte) (slaveId & 0xff));
 		bytes.add((byte) (functionCode.getCode() & 0xff));
 		new P_AB(BigDecimal.valueOf(startAddress)).encode(bytes);
 		new P_AB(BigDecimal.valueOf(quantity)).encode(bytes);
+		return this;
 	}
 
 	/**
@@ -59,6 +63,7 @@ public class AbstractModbusRequest {
 	 *
 	 * @param byteBuf 字节缓冲
 	 */
+	@Override
 	public AbstractModbusRequest decode(ByteBuffer byteBuf) throws ModbusException {
 		this.setSlaveId((byteBuf.get() & 0xff));
 		this.setFunctionCode(FunctionCode.valueOf(byteBuf.get() & 0xff));

+ 4 - 1
protocol-modbus/src/main/java/wei/yigulu/modbus/domain/request/RtuModbusRequest.java

@@ -1,6 +1,7 @@
 package wei.yigulu.modbus.domain.request;
 
 import com.google.common.primitives.Bytes;
+import wei.yigulu.modbus.domain.ModbusPacketInterface;
 import wei.yigulu.modbus.domain.datatype.numeric.P_BA;
 import wei.yigulu.modbus.exceptiom.ModbusException;
 import wei.yigulu.utils.CrcUtils;
@@ -26,12 +27,14 @@ public class RtuModbusRequest extends AbstractModbusRequest {
 	 * 编码
 	 *
 	 * @param bytes 字节
+	 * @return
 	 */
 	@Override
-	public void encode(List<Byte> bytes) {
+	public RtuModbusRequest encode(List<Byte> bytes) {
 		super.encode(bytes);
 		this.crc16 = CrcUtils.generateCRC16(Bytes.toArray(bytes));
 		new P_BA(BigDecimal.valueOf(this.crc16)).encode(bytes);
+		return this;
 	}
 
 	/**

+ 3 - 1
protocol-modbus/src/main/java/wei/yigulu/modbus/domain/request/TcpModbusRequest.java

@@ -4,6 +4,7 @@ package wei.yigulu.modbus.domain.request;
 import lombok.Data;
 import lombok.Setter;
 import lombok.experimental.Accessors;
+import wei.yigulu.modbus.domain.ModbusPacketInterface;
 import wei.yigulu.modbus.domain.datatype.numeric.P_AB;
 import wei.yigulu.modbus.domain.tcpextracode.TcpExtraCode;
 import wei.yigulu.modbus.domain.tcpextracode.TransactionIdentifier;
@@ -49,10 +50,11 @@ public class TcpModbusRequest extends AbstractModbusRequest {
 
 
 	@Override
-	public void encode(List<Byte> bytes) {
+	public TcpModbusRequest encode(List<Byte> bytes) {
 		tcpExtraCode.encode(bytes);
 		new P_AB(BigDecimal.valueOf(length)).encode(bytes);
 		super.encode(bytes);
+		return this;
 	}
 
 

+ 4 - 1
protocol-modbus/src/main/java/wei/yigulu/modbus/domain/response/AbstractModbusResponse.java

@@ -4,6 +4,7 @@ import com.google.common.primitives.Bytes;
 import lombok.Getter;
 import lombok.Setter;
 import wei.yigulu.modbus.domain.FunctionCode;
+import wei.yigulu.modbus.domain.ModbusPacketInterface;
 import wei.yigulu.modbus.exceptiom.ModbusException;
 
 import java.nio.ByteBuffer;
@@ -17,7 +18,7 @@ import java.util.List;
  */
 @Setter
 @Getter
-public class AbstractModbusResponse {
+public class AbstractModbusResponse implements ModbusPacketInterface {
 
 
 	/**
@@ -41,6 +42,7 @@ public class AbstractModbusResponse {
 	protected byte[] dataBytes;
 
 
+	@Override
 	public AbstractModbusResponse decode(ByteBuffer byteBuf) throws ModbusException {
 		this.slaveId = (int) byteBuf.get() & 0xff;
 		this.functionCode = FunctionCode.valueOf((int) byteBuf.get() & 0xff);
@@ -50,6 +52,7 @@ public class AbstractModbusResponse {
 		return this;
 	}
 
+	@Override
 	public AbstractModbusResponse encode(List<Byte> bytes) throws ModbusException {
 		bytes.add((byte) (slaveId & 0xff));
 		bytes.add((byte) (functionCode.getCode() & 0xff));

+ 0 - 1
protocol-modbus/src/main/java/wei/yigulu/modbus/domain/synchronouswaitingroom/RtuSynchronousWaitingRoom.java

@@ -19,7 +19,6 @@ public class RtuSynchronousWaitingRoom implements SynchronousWaitingRoom {
 
 	protected ByteBuffer bytes = null;
 
-
 	protected boolean hasGuest;