Explorar o código

增加两个报文类型

xiuwei %!s(int64=3) %!d(string=hai) anos
pai
achega
17986e673d

+ 3 - 1
protocol-core/src/main/java/wei/yigulu/netty/AbstractTcpMasterBuilder.java

@@ -71,7 +71,9 @@ public abstract class AbstractTcpMasterBuilder extends AbstractMasterBuilder {
 		synchronized (this) {
 			if (future != null) {
 				this.future.removeListener(getOrCreateConnectionListener());
-				this.future.addListener(ChannelFutureListener.CLOSE);
+				if (!future.channel().eventLoop().isShutdown()) {
+					this.future.addListener(ChannelFutureListener.CLOSE);
+				}
 				future = null;
 				try {
 					Thread.sleep(5000L);

+ 2 - 1
protocol-iec104/src/main/java/wei/yigulu/iec104/apdumodel/Apdu.java

@@ -247,7 +247,8 @@ public class Apdu {
 		if (this.apciType == ApciType.I_FORMAT) {
 			try {
 				if(this.asdu.getDataFrame()==null){
-					throw new Iec104Exception("I帧数据体为空");
+					log.error("I帧数据体为空");
+					return;
 				}
 				bb = this.asdu.getDataFrame().handleAndAnswer(this);
 			} catch (Exception e) {

+ 1 - 1
protocol-iec104/src/main/java/wei/yigulu/iec104/asdudataframe/BooleanType.java

@@ -126,7 +126,7 @@ public class BooleanType extends AbstractDataFrameType {
 	@Override
 	public Asdu generateBack() {
 		Asdu asdu = new Asdu();
-		asdu.setTypeId(1);
+		asdu.setTypeId(TYPEID);
 		asdu.setDataFrame(this);
 		asdu.getVsq().setSq(this.addresses.size() == 1 ? 1 : 0);
 		asdu.getVsq().setNum(this.datas.size());

+ 106 - 1
protocol-iec104/src/main/java/wei/yigulu/iec104/asdudataframe/BooleanWithTimeType.java

@@ -1,2 +1,107 @@
-package wei.yigulu.iec104.asdudataframe;public class BooleanWithTimeType {
+package wei.yigulu.iec104.asdudataframe;
+
+import io.netty.buffer.ByteBuf;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import wei.yigulu.iec104.apdumodel.Apdu;
+import wei.yigulu.iec104.apdumodel.Asdu;
+import wei.yigulu.iec104.apdumodel.Vsq;
+import wei.yigulu.iec104.asdudataframe.qualitydescription.IeMeasuredQuality;
+import wei.yigulu.iec104.asdudataframe.typemodel.IeBoolean;
+import wei.yigulu.iec104.asdudataframe.typemodel.IeProofreadTime;
+import wei.yigulu.iec104.asdudataframe.typemodel.InformationBodyAddress;
+import wei.yigulu.iec104.exception.Iec104Exception;
+import wei.yigulu.iec104.nettyconfig.TechnicalTerm;
+
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 单点长时标
+ *
+ * @author xiuwei
+ * @date 2022/03/17
+ */
+@EqualsAndHashCode(callSuper = true)
+@NoArgsConstructor
+@Data
+public class BooleanWithTimeType  extends  AbstractDataFrameType{
+
+    private List<InformationBodyAddress> addresses = new ArrayList<>();
+
+    private LinkedHashMap<IeBoolean, IeProofreadTime> datas = new LinkedHashMap<>();
+    /**
+     * TYPEID
+     */
+    public static final int TYPEID = TechnicalTerm.SINGEL_POINT_TIME_TYPE;
+
+
+    @Override
+    public void loadByteBuf(ByteBuf is, Vsq vsq) {
+        try {
+            if (vsq.getSq() == 0) {
+                for (int i = 0; i < vsq.getNum(); i++) {
+                    addresses.add(new InformationBodyAddress(is));
+                    datas.put(new IeBoolean(is),new IeProofreadTime(is));
+                }
+            } else {
+                addresses.add(new InformationBodyAddress(is));
+                for (int i = 0; i < vsq.getNum(); i++) {
+                    datas.put(new IeBoolean(is),new IeProofreadTime(is));
+                }
+            }
+        } catch (Iec104Exception e) {
+            if (e.getCode() == 3301) {
+                return;
+            }
+        }
+    }
+
+    @Override
+    public void encode(List<Byte> buffer) {
+
+    }
+
+    @Override
+    public Asdu generateBack() {
+        Asdu asdu = new Asdu();
+        asdu.setTypeId(TYPEID);
+        asdu.setDataFrame(this);
+        asdu.getVsq().setSq(this.addresses.size() == 1 ? 1 : 0);
+        asdu.getVsq().setNum(this.datas.size());
+        asdu.setOriginatorAddress(0);
+        asdu.setCommonAddress(1);
+        return asdu;
+    }
+
+    @Override
+    public byte[][] handleAndAnswer(Apdu apdu) throws Exception {
+        return new byte[0][];
+    }
+
+
+    @Override
+    public String toString() {
+        StringBuilder s = new StringBuilder("单点带时标\n");
+        if (addresses.size() == 1) {
+            s.append("连续寻址\n");
+            s.append(addresses.get(0).toString()).append("\n");
+            int d = 0;
+            for (Map.Entry<IeBoolean,IeProofreadTime> i : datas.entrySet()) {
+                s.append("点位:" + (addresses.get(0).getAddress() + (d++)) + ",");
+                s.append("时间:"+i.getValue()+"值,:"+i.getKey());
+
+            }
+        } else {
+            int f = 0;
+            for (Map.Entry<IeBoolean,IeProofreadTime> i : datas.entrySet()) {
+                s.append(addresses.get(f++).toString());
+                s.append("时间:"+i.getValue()+"值,:"+i.getKey());
+            }
+        }
+        return s.toString();
+    }
 }

+ 44 - 131
protocol-iec104/src/main/java/wei/yigulu/iec104/asdudataframe/NormalizedIntegerWithTimeType.java

@@ -2,12 +2,14 @@ package wei.yigulu.iec104.asdudataframe;
 
 
 import io.netty.buffer.ByteBuf;
+import lombok.AllArgsConstructor;
 import lombok.Data;
 import lombok.NoArgsConstructor;
 import wei.yigulu.iec104.apdumodel.Apdu;
 import wei.yigulu.iec104.apdumodel.Asdu;
 import wei.yigulu.iec104.apdumodel.Vsq;
 import wei.yigulu.iec104.asdudataframe.qualitydescription.IeMeasuredQuality;
+import wei.yigulu.iec104.asdudataframe.typemodel.IeProofreadTime;
 import wei.yigulu.iec104.asdudataframe.typemodel.IeShortInteger;
 import wei.yigulu.iec104.asdudataframe.typemodel.InformationBodyAddress;
 import wei.yigulu.iec104.exception.Iec104Exception;
@@ -26,48 +28,55 @@ import java.util.Map;
  */
 @NoArgsConstructor
 @Data
-public class NormalizedIntegerType extends AbstractDataFrameType {
+public class NormalizedIntegerWithTimeType extends AbstractDataFrameType {
 
     /**
      * TYPEID
      */
-    public static final int TYPEID = TechnicalTerm.NORMALIZED_INTEGER_TYPE;
+    public static final int TYPEID = TechnicalTerm.NORMALIZED_INTEGER_TIME_TYPE;
 
     private List<InformationBodyAddress> addresses = new ArrayList<>();
 
-    private Map<IeMeasuredQuality, Integer> datas = new LinkedHashMap<>();
+    private List<NormalizedIntegerAndQualityWithTime> datas = new ArrayList<>();
 
-    /**
-     * Normalized integer type
-     *
-     * @param addresses addresses
-     * @param datas     datas
-     * @throws Iec104Exception iec exception
-     */
-    public NormalizedIntegerType(List<InformationBodyAddress> addresses, Map<IeMeasuredQuality, Integer> datas) throws Iec104Exception {
-        if ((this.datas.size() * (IeMeasuredQuality.OCCUPYBYTES + IeShortInteger.OCCUPYBYTES) + this.addresses.size() * InformationBodyAddress.OCCUPYBYTES) > 240) {
-            throw new Iec104Exception("长度超长,创建对象失败,请切割数据。");
+
+
+    @Override
+    public String toString() {
+        StringBuilder s = new StringBuilder("带时长归一化值");
+        if (addresses.size() == 1) {
+            s.append("连续寻址\n");
+            s.append(addresses.get(0).toString() + "\n");
+            int i = 0;
+            for (NormalizedIntegerAndQualityWithTime e : datas) {
+                s.append("点位:" + (addresses.get(0).getAddress() + (i++)) + ",");
+                s.append("时间为:"+e.getTime());
+                s.append("值为 :" + e.getValue() + ";" + e.getQuality() + "\n");
+            }
+        } else {
+            s.append("单一寻址\n");
+            int f = 0;
+            for (NormalizedIntegerAndQualityWithTime e : datas) {
+                s.append(addresses.get(f++).toString());
+                s.append("时间为:"+e.getTime());
+                s.append("值为 :" + e.getValue() + ";" + e.getQuality() + "\n");
+            }
         }
-        this.addresses = addresses;
-        this.datas = datas;
+        return s.toString();
     }
 
-
     @Override
     public void loadByteBuf(ByteBuf is, Vsq vsq) {
-        Integer f;
         try {
             if (vsq.getSq() == 0) {
                 for (int i = 0; i < vsq.getNum(); i++) {
                     addresses.add(new InformationBodyAddress(is));
-                    f = new IeShortInteger(is).getValue();
-                    datas.put(new IeMeasuredQuality(is), f);
+                    datas.add(new NormalizedIntegerAndQualityWithTime(is));
                 }
             } else {
                 addresses.add(new InformationBodyAddress(is));
                 for (int i = 0; i < vsq.getNum(); i++) {
-                    f = new IeShortInteger(is).getValue();
-                    datas.put(new IeMeasuredQuality(is), f);
+                    datas.add(new NormalizedIntegerAndQualityWithTime(is));
                 }
             }
         } catch (Iec104Exception e) {
@@ -77,89 +86,15 @@ public class NormalizedIntegerType extends AbstractDataFrameType {
         }
     }
 
-    /**
-     * 向datas中添加数据,默认的质量描述
-     *
-     * @param f f
-     * @throws Iec104Exception iec exception
-     */
-    public void addData(int f) throws Iec104Exception {
-        addData(f, new IeMeasuredQuality());
-    }
-
-    /**
-     * 向datas中添加数据
-     *
-     * @param f       f
-     * @param quality quality
-     * @throws Iec104Exception iec exception
-     */
-    public void addData(int f, IeMeasuredQuality quality) throws Iec104Exception {
-        validateLen(IeShortInteger.OCCUPYBYTES + IeMeasuredQuality.OCCUPYBYTES);
-        this.datas.put(quality, f);
-    }
-
-
-    /**
-     * 向datas中添加数据和数据地址
-     *
-     * @param address address
-     * @param f       f
-     * @param quality quality
-     * @throws Iec104Exception iec exception
-     */
-    public void addDataAndAdd(InformationBodyAddress address, int f, IeMeasuredQuality quality) throws Iec104Exception {
-        addAddress(address);
-        addData(f, quality);
-    }
-
-    /**
-     * 向datas中添加数据和数据地址
-     *
-     * @param address address
-     * @param f       f
-     * @throws Iec104Exception iec exception
-     */
-    public void addDataAndAdd(InformationBodyAddress address, int f) throws Iec104Exception {
-        addAddress(address);
-        addData(f);
-    }
-
-
-    /**
-     * 向datas中添加数据和数据地址
-     *
-     * @param address address
-     * @throws Iec104Exception iec exception
-     */
-    public void addAddress(InformationBodyAddress address) throws Iec104Exception {
-        validateLen(InformationBodyAddress.OCCUPYBYTES);
-        this.addresses.add(address);
-    }
-
-
     @Override
     public void encode(List<Byte> buffer) {
-        if (addresses.size() == 1) {
-            addresses.get(0).encode(buffer);
-            for (Map.Entry<IeMeasuredQuality, Integer> i : datas.entrySet()) {
-                new IeShortInteger(i.getValue()).encode(buffer);
-                buffer.add((byte) i.getKey().encode());
-            }
-        } else {
-            int s = 0;
-            for (Map.Entry<IeMeasuredQuality, Integer> i : datas.entrySet()) {
-                addresses.get(s++).encode(buffer);
-                new IeShortInteger(i.getValue()).encode(buffer);
-                buffer.add((byte) i.getKey().encode());
-            }
-        }
+
     }
 
     @Override
     public Asdu generateBack() {
         Asdu asdu = new Asdu();
-        asdu.setTypeId(11);
+        asdu.setTypeId(TYPEID);
         asdu.setDataFrame(this);
         asdu.getVsq().setSq(this.addresses.size() == 1 ? 1 : 0);
         asdu.getVsq().setNum(this.datas.size());
@@ -168,45 +103,23 @@ public class NormalizedIntegerType extends AbstractDataFrameType {
         return asdu;
     }
 
-
-    /**
-     * Validate len *
-     *
-     * @param increase increase
-     * @throws Iec104Exception iec exception
-     */
-    protected void validateLen(int increase) throws Iec104Exception {
-        if (((this.datas.size() * (IeMeasuredQuality.OCCUPYBYTES + IeShortInteger.OCCUPYBYTES) + this.addresses.size() * InformationBodyAddress.OCCUPYBYTES) + increase) > 240) {
-            throw new Iec104Exception("长度超长,不能再向此对象中添加元素");
-        }
-    }
-
     @Override
     public byte[][] handleAndAnswer(Apdu apdu) throws Exception {
-        return null;
+        return new byte[0][];
     }
 
+    @AllArgsConstructor
+    @Data
+    class NormalizedIntegerAndQualityWithTime{
 
-    @Override
-    public String toString() {
-        StringBuilder s = new StringBuilder("归一化值");
-        if (addresses.size() == 1) {
-            s.append("连续寻址\n");
-            s.append(addresses.get(0).toString() + "\n");
-            int i = 0;
-            for (Map.Entry<IeMeasuredQuality, Integer> e : datas.entrySet()) {
-                s.append("点位:" + (addresses.get(0).getAddress() + (i++)) + ",");
-                s.append("值为 :" + e.getValue() + ";" + e.getKey().toString() + "\n");
-            }
-        } else {
-            s.append("单一寻址\n");
-            int f = 0;
-            for (Map.Entry<IeMeasuredQuality, Integer> i : datas.entrySet()) {
-                s.append(addresses.get(f++).toString());
-                s.append(i.getValue().toString());
-                s.append(i.getKey().toString() + "\n");
-            }
+        Integer value;
+        IeMeasuredQuality quality;
+        IeProofreadTime time;
+
+        public  NormalizedIntegerAndQualityWithTime(ByteBuf is) throws Iec104Exception {
+            this.value=new IeShortInteger(is).getValue();
+            this.quality=new IeMeasuredQuality(is);
+            this.time=new IeProofreadTime(is);
         }
-        return s.toString();
     }
 }

+ 9 - 0
protocol-iec104/src/main/java/wei/yigulu/iec104/nettyconfig/TechnicalTerm.java

@@ -77,6 +77,10 @@ public class TechnicalTerm {
 	 * 单点信息
 	 */
 	public static final Integer SINGEL_POINT_TYPE = 1;
+	/**
+	 * 单点带长时标信息
+	 */
+	public static final Integer SINGEL_POINT_TIME_TYPE = 30;
 
 
 	/**
@@ -91,6 +95,11 @@ public class TechnicalTerm {
 	public static final Integer NORMALIZED_INTEGER_TYPE = 9;
 
 	/**
+	 * 测量值,规一化值 带时间
+	 */
+	public static final Integer NORMALIZED_INTEGER_TIME_TYPE = 34;
+
+	/**
 	 * 测量值,标度化值
 	 */
 	public static final Integer SCALING_INTEGER_TYPE = 11;