浏览代码

104数据推送

songwenbin 2 年之前
父节点
当前提交
d0bec9058c

+ 4 - 4
gddlly/src/main/java/com/gyee/edge/gddlly/iec104/Iec104Message.java

@@ -140,13 +140,13 @@ public class Iec104Message {
 	}
 
 	public short getAcceptSeq() {
-		//todo: 从控制域3、4提取接受报文的序列号
-		return 0;
+		//从控制域3、4提取接受报文的序列号
+		return Iec104Util.getAccept(this.control);
 	}
 
 	public short getSendSeq() {
-		//todo: 从控制域1、2提取发送报文的序列号
-		return 0;
+		//从控制域1、2提取发送报文的序列号
+		return Iec104Util.getSend(this.control);
 	}
 	
 }

+ 41 - 32
gddlly/src/main/java/com/gyee/edge/gddlly/iec104/Iec104Session.java

@@ -19,19 +19,20 @@ import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 
 import java.net.InetSocketAddress;
+import java.util.ArrayList;
 import java.util.Date;
 import java.util.Map;
 
 @Slf4j
-public class Iec104Session implements Runnable {
+public class Iec104Session {
     private String clientIp;
     private int clientPort;
     private short asduAddress;
     private Date connectTime;
     private SessionState state;
     private Date lastSessionTime;
-    private short acceptSeq;    //接收序列号
-    private short sendSeq;      //发送序列号
+    private short acceptSeq = 0;    //接收序列号
+    private short sendSeq = 0;      //发送序列号
     private boolean isRunning = false;
 
     private ChannelHandlerContext channelHandlerContext;
@@ -39,8 +40,8 @@ public class Iec104Session implements Runnable {
     private PointService pointService = SpringContextUtil.getBean(PointService.class);
     private RedisDataService redisService = SpringContextUtil.getBean(RedisDataService.class);
 
-    Map<String, Point> aiMap;
-    Map<String, Point> diMap;
+    private Map<String, Point> aiMap;
+    private Map<String, Point> diMap;
 
     public Iec104Session(ChannelHandlerContext ctx) {
         channelHandlerContext = ctx;
@@ -85,7 +86,6 @@ public class Iec104Session implements Runnable {
                 }
             } else if (request.getTypeIdentifier() == TypeIdentifierEnum.generalCall) {
                 // 总召唤命令
-                //todo: 总召唤命令处理,全量传输
                 if (TransferReason.ACTIVATE == TransferReason.valueOf(request.getTransferReason())) {
                     state = SessionState.CALL_ALL;
                     asduAddress = request.getTerminalAddress();
@@ -93,19 +93,17 @@ public class Iec104Session implements Runnable {
                     diMap = pointService.getDiMap().get((int)asduAddress);
                     //todo: 启动全量传输
                     this.start();
-
-                    return BasicInstruction104.getYesGeneralCallRuleDetail104();
+                    acceptSeq = request.getAcceptSeq();
+                    sendSeq += 1;
+                    return BasicInstruction104.getYesGeneralCallRuleDetail104(acceptSeq, sendSeq);
 
                 } else if (TransferReason.STOP_ACTIVATION == TransferReason.valueOf(request.getTransferReason())) {
                     state = SessionState.CALL_ALL_END;
                     //todo: 启动变化传输
                     this.start();
-
                     return null;
                 }
 
-                //todo: 总召唤命令结束,变化传输
-
             } else {
                 //todo: 其它命令处理
             }
@@ -125,33 +123,44 @@ public class Iec104Session implements Runnable {
             return;
         }
 
-        this.run();
+        getPushThread().start();
     }
 
     public void stop() {
         isRunning = false;
     }
 
-
-    @Override
-    public void run() {
-        try {
-            isRunning = true;
-            while(isRunning) {
-                //todo: 从redis读取数据,发送到客户端
-                //1、从redis读取数据,填充aiMap、diMap中,point的value,consumed,lastUpdateTime;
-                aiMap = redisService.getData(aiMap);
-                diMap = redisService.getData(diMap);
-                //2、如果SessionState.CALL_ALL, 全量传输
-
-                //3、如果SessionState.CALL_ALL_END,变化传输
-
-                Thread.sleep(100);
+    private Thread getPushThread() {
+        return new Thread(new Runnable() {
+            public void run() {
+                log.info("开始启动数据轮询和转发线程...");
+                try {
+                    isRunning = true;
+                    while(isRunning) {
+                        //todo: 从redis读取数据,发送到客户端
+                        //1、从redis读取数据,填充aiMap、diMap中,point的value,consumed,lastUpdateTime;
+                        aiMap = redisService.getData(aiMap);
+                        diMap = redisService.getData(diMap);
+
+                        if (state == SessionState.CALL_ALL) {
+                            //2、如果SessionState.CALL_ALL, 全量传输
+
+                        } else if (state == SessionState.CALL_ALL_END) {
+                            //3、如果SessionState.CALL_ALL_END,变化传输
+
+                        } else {
+                            break;
+                        }
+
+                        Thread.sleep(3000);
+                    }
+                } catch (Exception e) {
+
+                } finally {
+                    isRunning = false;
+                }
             }
-        } catch (Exception e) {
-
-        } finally {
-            isRunning = false;
-        }
+        });
     }
+
 }

+ 24 - 24
gddlly/src/main/java/com/gyee/edge/gddlly/iec104/Iec104Util.java

@@ -138,48 +138,48 @@ public class Iec104Util {
 	
 	/**
 	 * 设置可以变限定词
-	 * @param ruleDetail104
+	 * @param msg104
 	 * @param byteItem
 	 */
-	public static void setChanged(Iec104Message ruleDetail104, byte byteItem) {
+	public static void setChanged(Iec104Message msg104, byte byteItem) {
 		// 第一位是 0 则是有序的
-		ruleDetail104.setContinuous((byteItem & 0x80) == 0 ? false : true);
+		msg104.setContinuous((byteItem & 0x80) == 0 ? false : true);
 		// 先将第一位数置零 然后转换成int
-		ruleDetail104.setMeasgLength(byteItem & (byte) 0x7F);
+		msg104.setMeasgLength(byteItem & (byte) 0x7F);
 	}
 	    
 	/**	
 	 * 返回可变限定词数组
-	 * @param ruleDetail104
+	 * @param msg104
 	 * @return
 	 */
-	public static byte getChangedQualifiers(Iec104Message ruleDetail104) {
+	public static byte getChangedQualifiers(Iec104Message msg104) {
 		// 将长度转换成 byte
-		byte changedQualifiers = (byte) ruleDetail104.getMeasgLength();
+		byte changedQualifiers = (byte) msg104.getMeasgLength();
 		// 判断SQ 置   isContinuous false SQ = 0;否则 SQ =1 ,  同时将SQ置 设置在 可变限定词的 D7位置
-		int sq = ruleDetail104.isContinuous() ?  0x80 : 0;
+		int sq = msg104.isContinuous() ?  0x80 : 0;
 		changedQualifiers = (byte) (sq | changedQualifiers);
 		return changedQualifiers;
 	} 
 	
 	
-	public static void setMeaageAttribute(Iec104Message ruleDetail104) {
-		boolean isMessage =  !(TypeIdentifierEnum.generalCall.equals(ruleDetail104.getTypeIdentifier())  //总召唤无此项
-				|| TypeIdentifierEnum.timeSynchronization.equals(ruleDetail104.getTypeIdentifier()) // 时钟同步
-				|| TypeIdentifierEnum.resetPprocess.equals(ruleDetail104.getTypeIdentifier()) // 复位进程
-				|| TypeIdentifierEnum.initEnd.equals(ruleDetail104.getTypeIdentifier()));
-		ruleDetail104.setMessage(isMessage);
+	public static void setMeaageAttribute(Iec104Message msg104) {
+		boolean isMessage =  !(TypeIdentifierEnum.generalCall.equals(msg104.getTypeIdentifier())  //总召唤无此项
+				|| TypeIdentifierEnum.timeSynchronization.equals(msg104.getTypeIdentifier()) // 时钟同步
+				|| TypeIdentifierEnum.resetPprocess.equals(msg104.getTypeIdentifier()) // 复位进程
+				|| TypeIdentifierEnum.initEnd.equals(msg104.getTypeIdentifier()));
+		msg104.setMessage(isMessage);
 		
-		boolean isQualifiers = !(TypeIdentifierEnum.timeSynchronization.equals(ruleDetail104.getTypeIdentifier())  // 时钟同步
-				|| TypeIdentifierEnum.onePointTeleindication.equals(ruleDetail104.getTypeIdentifier()) //单点摇信
-				|| TypeIdentifierEnum.twoPointTeleindication.equals(ruleDetail104.getTypeIdentifier()) // 双点摇信
-				|| TypeIdentifierEnum.onePointTelecontrol.equals(ruleDetail104.getTypeIdentifier()) // 单命令遥控
-				|| TypeIdentifierEnum.twoPointTelecontrol.equals(ruleDetail104.getTypeIdentifier())); // 双命令遥控
-		ruleDetail104.setQualifiers(isQualifiers);
-		boolean isTimeScale = TypeIdentifierEnum.timeSynchronization.equals(ruleDetail104.getTypeIdentifier())  // 时钟同步
-				|| TypeIdentifierEnum.onePointTimeTeleindication.equals(ruleDetail104.getTypeIdentifier()) // 摇信带时标 单点
-				|| TypeIdentifierEnum.twoPointTimeTeleindication.equals(ruleDetail104.getTypeIdentifier()); //摇信带时标 双点
-		ruleDetail104.setTimeScaleExit(isTimeScale);
+		boolean isQualifiers = !(TypeIdentifierEnum.timeSynchronization.equals(msg104.getTypeIdentifier())  // 时钟同步
+				|| TypeIdentifierEnum.onePointTeleindication.equals(msg104.getTypeIdentifier()) //单点摇信
+				|| TypeIdentifierEnum.twoPointTeleindication.equals(msg104.getTypeIdentifier()) // 双点摇信
+				|| TypeIdentifierEnum.onePointTelecontrol.equals(msg104.getTypeIdentifier()) // 单命令遥控
+				|| TypeIdentifierEnum.twoPointTelecontrol.equals(msg104.getTypeIdentifier())); // 双命令遥控
+		msg104.setQualifiers(isQualifiers);
+		boolean isTimeScale = TypeIdentifierEnum.timeSynchronization.equals(msg104.getTypeIdentifier())  // 时钟同步
+				|| TypeIdentifierEnum.onePointTimeTeleindication.equals(msg104.getTypeIdentifier()) // 摇信带时标 单点
+				|| TypeIdentifierEnum.twoPointTimeTeleindication.equals(msg104.getTypeIdentifier()); //摇信带时标 双点
+		msg104.setTimeScaleExit(isTimeScale);
 	}
 	
 	/**

+ 0 - 1
gddlly/src/main/java/com/gyee/edge/gddlly/iec104/builder/Encoder104.java

@@ -20,7 +20,6 @@ public class Encoder104 {
 		msg104.setApduLength(messageLen);
 		bytes.write((byte) messageLen);
 		bytes.write(apduBytes);
-		//todo: 控制域、公共地址(asdu)的序列化
 
 		return bytes.toByteArray();
 	}

+ 4 - 4
gddlly/src/main/java/com/gyee/edge/gddlly/iec104/protocol/BasicInstruction104.java

@@ -94,15 +94,15 @@ public class BasicInstruction104 {
 	* @return MessageDetail
 	* @throws
 	 */
-	public static Iec104Message getYesGeneralCallRuleDetail104() {
+	public static Iec104Message getYesGeneralCallRuleDetail104(short accept, short send) {
 		TypeIdentifierEnum typeIdentifierEnum = TypeIdentifierEnum.generalCall; 
 		 //SQ=0 length =1
 		int sq = 0;
 		boolean isContinuous = sq == 0 ? false : true;
 		// 接收序号
-		short accept = 0;
-		// 发送序号
-		short send = 0;
+//		short accept = 0;
+//		// 发送序号
+//		short send = 0;
 		byte[] control = Iec104Util.getIcontrol(accept, send);
 		// 传输原因
 		short transferReason = 7;

+ 6 - 2
gddlly/src/main/java/com/gyee/edge/gddlly/redis/RedisDataService.java

@@ -39,8 +39,12 @@ public class RedisDataService {
                 double value = Double.valueOf(vs.substring(1, vs.lastIndexOf("\"")));
 
                 point.setLastUpdateTime(new Date(time));
-                point.setConsumed(point.getValue() == value ? true : false);
-                point.setValue(value);
+                if (point.getValue() != value ) {
+                    point.setConsumed(false);
+                    point.setValue(value);
+                }
+               // point.setConsumed(point.getValue() == value ? true : false);
+
                 map.replace(points.get(i), point);
             }
         } catch (Exception e){