| 
					
				 | 
			
			
				@@ -0,0 +1,161 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+package com.huashe.park.application.engine.impl; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import com.alibaba.fastjson2.JSON; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import com.alibaba.fastjson2.JSONObject; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import com.huashe.park.application.engine.EvtFusionEngine; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import com.huashe.park.application.engine.LocationInfo; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import com.huashe.park.application.socket.server.FenceVioEvtSocketServer; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import com.huashe.park.application.web.core.config.MqttCfg; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import com.huashe.park.common.DateTimeUtil; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import com.huashe.park.common.consts.BDConst; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import com.huashe.park.common.consts.enums.EvtStatus; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import com.huashe.park.common.consts.enums.EvtType; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import com.huashe.park.common.consts.enums.FenceType; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import com.huashe.park.common.geo.GeoUtils; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import com.huashe.park.core.service.IBdFenceInfoService; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import com.huashe.park.core.service.IBdFenceVioEvtService; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import com.huashe.park.domain.entity.BdFenceInfo; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import com.huashe.park.domain.entity.BdFenceVioEvt; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import com.ruoyi.common.core.redis.RedisCache; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import net.dreamlu.iot.mqtt.spring.client.MqttClientTemplate; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import org.apache.commons.lang3.ObjectUtils; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import org.locationtech.jts.geom.Polygon; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import org.slf4j.Logger; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import org.slf4j.LoggerFactory; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import org.springframework.beans.factory.annotation.Autowired; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import org.springframework.beans.factory.annotation.Value; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import org.springframework.stereotype.Service; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import org.springframework.util.CollectionUtils; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import javax.annotation.PostConstruct; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import javax.annotation.Resource; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import java.util.ArrayList; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import java.util.List; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import java.util.concurrent.LinkedBlockingQueue; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * The type Room break in engine. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+@Service 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+@ConditionalOnBean(MqttCfg.class) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+public class RoomBreakInEngine extends EvtFusionEngine { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private static final Logger logger = LoggerFactory.getLogger(RoomBreakInEngine.class); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    @Autowired 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private IBdFenceInfoService fenceInfoService; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    @Autowired 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private IBdFenceVioEvtService vioEvtService; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    @Resource 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private RedisCache redisCache; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    @Autowired 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private MqttClientTemplate client; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    @Value("${evt-fusion.fusion-time.room-location:300}") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private int MAX_EVT_TIME_GAP; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    @Autowired 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private FenceVioEvtSocketServer fenceVioEvtSocketServer; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private final List<LinkedBlockingQueue<JSONObject>> messageQueueList = new ArrayList<>(5); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    @PostConstruct 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    public void init() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        super.init(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this.setEngineName("室内围栏闯禁事件融合"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (!redisCache.hasKey(BDConst.REDIS_KEY.FENCE_ROOM)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            List<BdFenceInfo> bdFenceInfos = fenceInfoService.selectBdFenceInfoList(new BdFenceInfo() {{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                setFenceType(FenceType.INSIDE_FENCE_IN.getCode()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            }}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (CollectionUtils.isEmpty(bdFenceInfos)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            bdFenceInfos.removeIf(item -> ObjectUtils.isEmpty(item.getPoly()) || ObjectUtils.isEmpty(GeoUtils.getPolygon(item.getPoly()))); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            redisCache.setCacheList(BDConst.REDIS_KEY.FENCE_ROOM, bdFenceInfos); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    @Override 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    public Boolean check(LocationInfo older, LocationInfo newer) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        long gap = newer.getSrcTimestamp() - older.getSrcTimestamp(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 将gap 转换为秒 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        gap = gap / 1000; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        String oldFenceId = older.getMsg().getString("fenceId"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        String newerFenceId = newer.getMsg().getString("fenceId"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return gap <= MAX_EVT_TIME_GAP && oldFenceId.equals(newerFenceId); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    @Override 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    public List<LinkedBlockingQueue<JSONObject>> getQueue() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return messageQueueList; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * Gets key. 获取融合对象在redis中的key 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * @param msg the msg 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * @return the key 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * @author chen.cheng 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    @Override 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    public String getKey(LocationInfo msg) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return BDConst.REDIS_KEY.FENCE_ROOM_BREAK_IN_KEY + msg.getMsg().getString("deviceId"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    @Override 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    public void getBizId(LocationInfo msg) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        BdFenceVioEvt bdFenceVioEvt = new BdFenceVioEvt(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        bdFenceVioEvt.setFenceId(msg.getMsg().getLong("fenceId")); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        bdFenceVioEvt.setLat(msg.getLatitude()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        bdFenceVioEvt.setLng(msg.getLongitude()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        bdFenceVioEvt.setLocationId(msg.getMsg().getLong("roomId")); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        bdFenceVioEvt.setEvtStatus(EvtStatus.NEW.getCode()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        bdFenceVioEvt.setEvtType(EvtType.FENCE_ROOM_IN.getCode()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        bdFenceVioEvt.setEvtTime(DateTimeUtil.getDateFromMills(msg.getSrcTimestamp())); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        bdFenceVioEvt.setEvtDesc(String.format("室内围栏闯禁: %s", msg.getMsg().getString("fenceName"))); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        vioEvtService.insertBdFenceVioEvt(bdFenceVioEvt); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        msg.setBizId(bdFenceVioEvt.getId().toString()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    @Override 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    public void processOlderData(LocationInfo msg) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        vioEvtService.updateBdFenceVioEvt(new BdFenceVioEvt() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                setFenceId(msg.getMsg().getLong("fenceId")); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                setEvtStatus(EvtStatus.DISAPPEAR.getCode()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    @Override 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    public void newEvtCallback(LocationInfo msg) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        fenceVioEvtSocketServer.broadcast(msg); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    public void generateEvt(JSONObject msg, byte[] payload) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        List<BdFenceInfo> cacheList = redisCache.getCacheList(BDConst.REDIS_KEY.FENCE_ROOM); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (CollectionUtils.isEmpty(cacheList)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Polygon polygon; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        logger.info("fence info size: {}", msg); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        for (BdFenceInfo fenceInfo : cacheList) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            polygon = GeoUtils.getPolygon(fenceInfo.getPoly()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (GeoUtils.isPointInGeoFence(polygon, msg.getString("longitude"), msg.getString("latitude"))) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                logger.info("?>>>>>fence info size: {}", msg); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                msg.put("fenceId", fenceInfo.getId()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                msg.put("fenceName", fenceInfo.getDefenceName()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                msg.put("roomId", fenceInfo.getLocationId()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                client.publish(BDConst.MQTT_TOPIC.EVT_ROOM_LOCATION_TOPIC, JSON.toJSONBytes(msg)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 |