Kaynağa Gözat

摄像头拍照火焰识别代码提交
预案触发远程调用,日志打印

hanzhiwei 2 yıl önce
ebeveyn
işleme
4aef6c32ae

+ 9 - 4
zd-api/zd-laboratory-api/src/main/java/com/zd/laboratory/api/feign/RemoteLaboratoryService.java

@@ -3,12 +3,10 @@ package com.zd.laboratory.api.feign;
 import com.zd.laboratory.api.dto.CheckSubjectDto;
 import com.zd.laboratory.api.dto.WarningConfigDto;
 import com.zd.laboratory.api.dto.WarningNoticeLogDto;
-import com.zd.laboratory.api.entity.LabGradeManageRecord;
-import com.zd.laboratory.api.entity.LabMessageContent;
-import com.zd.laboratory.api.entity.LabSubjectEntityVO;
-import com.zd.laboratory.api.entity.OneClickFireDTO;
+import com.zd.laboratory.api.entity.*;
 import com.zd.laboratory.api.feign.fallback.RemoteLaboratoryFallbackFactory;
 import com.zd.laboratory.api.vo.LabGradeManageWorkVO;
+import com.zd.laboratory.api.vo.SubFunction;
 import com.zd.model.constant.ApplicationConstants;
 import com.zd.model.domain.AjaxResult;
 import com.zd.model.domain.DTO.UserPhoneInfo;
@@ -584,4 +582,11 @@ public interface RemoteLaboratoryService {
     @GetMapping("/subject/selectAdminAndSafeAdmin")
     @ApiOperation("根据实验室查询实验室负责人,安全员 身份信息和电话号码")
     ResultData<List<UserPhoneInfo>> selectAdminAndSafeAdminById(@RequestParam("subId") Long subId);
+
+    /**
+     * 预案触发
+     */
+    @PostMapping("/plan/triggerRiskPlan")
+    ResultData triggerRiskPlan(@RequestBody SubFunction<SensorFunctionStatus> subFunction);
+
 }

+ 7 - 4
zd-api/zd-laboratory-api/src/main/java/com/zd/laboratory/api/feign/fallback/RemoteLaboratoryFallbackFactory.java

@@ -3,12 +3,10 @@ package com.zd.laboratory.api.feign.fallback;
 import com.zd.laboratory.api.dto.CheckSubjectDto;
 import com.zd.laboratory.api.dto.WarningConfigDto;
 import com.zd.laboratory.api.dto.WarningNoticeLogDto;
-import com.zd.laboratory.api.entity.LabGradeManageRecord;
-import com.zd.laboratory.api.entity.LabMessageContent;
-import com.zd.laboratory.api.entity.LabSubjectEntityVO;
-import com.zd.laboratory.api.entity.OneClickFireDTO;
+import com.zd.laboratory.api.entity.*;
 import com.zd.laboratory.api.feign.RemoteLaboratoryService;
 import com.zd.laboratory.api.vo.LabGradeManageWorkVO;
+import com.zd.laboratory.api.vo.SubFunction;
 import com.zd.model.domain.AjaxResult;
 import com.zd.model.domain.DTO.UserPhoneInfo;
 import com.zd.model.domain.R;
@@ -562,6 +560,11 @@ public class RemoteLaboratoryFallbackFactory implements FallbackFactory<RemoteLa
             public ResultData<List<UserPhoneInfo>> selectAdminAndSafeAdminById(Long subId) {
                 return ResultData.fail("查询实验室管理员和安全员失败!!"+ cause.getMessage());
             }
+
+            @Override
+            public ResultData triggerRiskPlan(SubFunction<SensorFunctionStatus> subFunction) {
+                return ResultData.fail("预案报警失败!!"+ cause.getMessage());
+            }
         };
     }
 }

+ 1 - 0
zd-modules/zd-algorithm/src/main/java/com/zd/alg/forward/domain/DataPostAnalysisRespDto.java

@@ -8,6 +8,7 @@ import java.util.List;
 public class DataPostAnalysisRespDto {
 
     private Integer aid;
+    private Integer cid;
     private String did;
     private String extension;
     private List<AnalysisData> analysisDatas;

+ 5 - 0
zd-modules/zd-algorithm/src/main/java/com/zd/alg/forward/properties/FireProperties.java

@@ -25,6 +25,11 @@ public class FireProperties {
     private String did;
 
     /**
+     * cid
+     */
+    private String cid;
+
+    /**
      * 实验室ID,和设备编号二选一即可
      */
     private Integer labId;

+ 55 - 28
zd-modules/zd-algorithm/src/main/java/com/zd/alg/forward/serivce/FireImageService.java

@@ -1,17 +1,32 @@
 package com.zd.alg.forward.serivce;
 
+import cn.hutool.core.date.DateTime;
+import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.io.FileUtil;
+import cn.hutool.http.HttpUtil;
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
 import com.zd.alg.forward.config.AlgorithmYml;
 import com.zd.alg.forward.domain.AnalysisData;
+import com.zd.alg.forward.domain.AnalysisReturnData;
 import com.zd.alg.forward.domain.DataPostAnalysisRespDto;
 import com.zd.alg.forward.domain.ImgPostResponse;
 import com.zd.alg.forward.properties.FireProperties;
 import com.zd.alg.forward.utils.HttpUtils;
 import com.zd.alg.forward.utils.VideoUtils;
 import com.zd.common.core.exception.ServiceException;
+import com.zd.common.core.redis.RedisService;
+import com.zd.laboratory.api.entity.SensorFunctionStatus;
+import com.zd.laboratory.api.feign.RemoteLaboratoryService;
+import com.zd.laboratory.api.vo.SubFunction;
+import com.zd.model.domain.ResultData;
 import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
 import org.bytedeco.javacv.FFmpegFrameGrabber;
 import org.bytedeco.javacv.Frame;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.http.HttpEntity;
+import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.stereotype.Service;
 import org.springframework.util.MultiValueMap;
 import org.springframework.web.client.RestTemplate;
@@ -22,14 +37,15 @@ import javax.imageio.ImageIO;
 import java.awt.image.BufferedImage;
 import java.io.File;
 import java.io.IOException;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
+import java.time.LocalDateTime;
+import java.time.ZoneOffset;
+import java.util.*;
+import java.util.concurrent.TimeUnit;
 
 import static com.zd.alg.face.utils.FileUtil.multipartFileToFile;
 import static com.zd.alg.forward.utils.HttpUtils.getHttpEntityMap;
 import static com.zd.alg.forward.utils.VideoUtils.frameToBufferedImage;
+import static com.zd.model.constant.BaseConstants.MAP_INIT_SIZE;
 
 /**
  * 火焰图片抓拍处理
@@ -45,6 +61,12 @@ public class FireImageService {
     @Resource
     private AlgorithmYml algorithmYml;
 
+    @Autowired
+    RedisService redisService;
+
+    @Autowired
+    private RemoteLaboratoryService remoteLaboratoryService;
+
     @Resource
     private RestTemplate restTemplate;
     @Resource
@@ -60,9 +82,10 @@ public class FireImageService {
      */
     private static final String IMAGE_FORMAT = "jpg";
 
-//    @Scheduled(cron = "0/5 * * * * ?")
+    @Scheduled(cron = "0/5 * * * * ?")
     public void camera(){
         try {
+            log.info("开始执行定时火焰检测!");
             String streamUrl = fireProperties.getStreamUrl();
             if (streamUrl != null && !"".equals(streamUrl)) {
                 catchImage(streamUrl);
@@ -75,11 +98,16 @@ public class FireImageService {
     }
 
     public void catchImage(String streamUrl) throws IOException {
+        log.info("获取视频流开始=================");
         try (FFmpegFrameGrabber grabber = VideoUtils.createGrabber(streamUrl)) {
             grabber.start();
-            String fileName = "test";
+            String fileName = "huoyan-"+ DateUtil.format(new DateTime(), "yyyyMMddHHmmssSSS");;
             //文件储存对象
-            File file=new File(fileName+"." + IMAGE_FORMAT);
+            File file=new File("/img/"+fileName+"." + IMAGE_FORMAT);
+            if (!file.exists()) {
+                file.mkdirs();
+            }
+            log.info("获取第一帧");
             //获取第一帧
             Frame frame = grabber.grabFrame();
             if (frame != null) {
@@ -110,29 +138,28 @@ public class FireImageService {
         if (fireProperties.getAlgoId() == null) {
             throw new ServiceException("未配置火焰算法ID");
         }
-        MultiValueMap<String, Object> params = HttpUtils.getMultiValueMap(fireProperties, null);
-        HttpEntity<MultiValueMap<String, Object>> files = getHttpEntityMap(file, params);
-        ImgPostResponse<DataPostAnalysisRespDto> send = HttpUtils.send(restTemplate, files, algorithmYml);
-        if (send == null || send.getStatus_code() != SUCCESS_CODE) {
-            assert send != null;
-            //log.error(send.getMessage());
+        HashMap<String, Object> paramMap = new HashMap<>();
+        paramMap.put("image", FileUtil.file(file.getAbsoluteFile()));
+        paramMap.put("aid",fireProperties.getAlgoId());
+        paramMap.put("cid",fireProperties.getCid());
+        paramMap.put("sync",1);
+        paramMap.put("timestamp", LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli() / 1000);
+        log.info("火焰算法请求参数={}", JSON.toJSONString(paramMap));
+        String resultStr= HttpUtil.post(algorithmYml.getImgPostUrl(), paramMap);
+        log.info("火焰算法响应参数status_code={}", JSON.parseObject(resultStr).get("status_code"));
+        log.info("火焰算法响应参数message={}", JSON.parseObject(resultStr).get("message"));
+        if (StringUtils.isBlank(resultStr) || SUCCESS_CODE != JSON.parseObject(resultStr).getIntValue("status_code")) {
+            log.info("火焰算法请求失败!响应参数={}",resultStr);
             return;
         }
-        DataPostAnalysisRespDto data = send.getData();
-        List<AnalysisData> analysisDatas = data.getAnalysisDatas();
-        AnalysisData analysisData = analysisDatas.get(0);
-        int code = analysisData.getCode();
-        if (code==-1){
-            log.error("==============请求失败:{}=================",analysisData.getMsg());
-        }else {
-            log.info("===============向算法服务发送数据完成====================");
-            Map<String, Object> result = (Map<String, Object>) Optional.ofNullable(analysisData.getResult()).orElse(Collections.emptyMap());
-            Map<String, Object> algorithmData = (Map<String, Object>) Optional.ofNullable(result.get("algorithm_data")).orElse(Collections.emptyMap());
-            boolean alert = "false".equals(algorithmData.getOrDefault("is_alert", "").toString());
-            if (!alert) {
-                log.info("===============返回告警信息====================");
-                sendSginAccessLogService.saveAlarm(fireProperties);
-            }
+        AnalysisReturnData data = JSON.parseObject(resultStr).getObject("data", AnalysisReturnData.class);
+        JSONObject resultJSON = JSON.parseObject(JSON.toJSONString(data.getResult()));
+        JSONObject algorithm_data = resultJSON.getJSONObject("algorithm_data");
+        Boolean is_alert = algorithm_data.getBoolean("is_alert");
+        log.info("火焰算法识别结果is_alert={}",is_alert);
+        if (is_alert) {
+            log.info("======火焰预案报警!!!======");
+            sendSginAccessLogService.saveAlarm(fireProperties);
         }
     }
 }

+ 22 - 1
zd-modules/zd-algorithm/src/main/java/com/zd/alg/forward/serivce/SendSginAccessLogService.java

@@ -1,5 +1,6 @@
 package com.zd.alg.forward.serivce;
 
+import cn.hutool.http.HttpUtil;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONObject;
 import com.zd.alg.forward.config.AlgorithmYml;
@@ -9,12 +10,15 @@ import com.zd.algorithm.api.speaker.entity.PlayVo;
 import com.zd.algorithm.api.speaker.feign.RemoteSpeakService;
 import com.zd.common.core.exception.PreAuthorizeException;
 import com.zd.common.core.utils.StringUtils;
+import com.zd.laboratory.api.entity.SensorFunctionStatus;
 import com.zd.laboratory.api.feign.RemoteLaboratoryService;
+import com.zd.laboratory.api.vo.SubFunction;
 import com.zd.model.constant.CacheDevice;
 import com.zd.model.constant.HttpStatus;
 import com.zd.model.constant.SecurityConstants;
 import com.zd.model.domain.AjaxResult;
 import com.zd.model.domain.R;
+import com.zd.model.domain.ResultData;
 import com.zd.model.entity.Algorithm;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -121,8 +125,21 @@ public class SendSginAccessLogService {
             if (currentTimeMillis > expiryTime) {
                 expiryMap.remove(hardwareNum);
                 alarmMap.remove(hardwareNum);
+                logger.info("===============时间大于30s,不执行!!!");
             }else {
-                send(properties, hardwareNum);
+                logger.info("+++++++++++++++报警!!!!");
+                SubFunction<SensorFunctionStatus> subFunction = new SubFunction<>();
+                List<SensorFunctionStatus> subFunctions = new ArrayList<>();
+                SensorFunctionStatus sensorFunctionStatus = new SensorFunctionStatus();
+                sensorFunctionStatus.setVal("1");
+                sensorFunctionStatus.setHardwareNum(properties.getHardwareNum());
+                sensorFunctionStatus.setFunNum("huoyan");
+                sensorFunctionStatus.setDescribe("火焰");
+                subFunctions.add(sensorFunctionStatus);
+                subFunction.setFunctionStatuses(subFunctions);
+                logger.info("subFunction={}",JSON.toJSONString(subFunction));
+                ResultData resultData = remoteLaboratoryService.triggerRiskPlan(subFunction);
+//                send(properties, hardwareNum);
             }
             int count = alarmMap.get(hardwareNum) == null ? 0 : alarmMap.get(hardwareNum);
             ++count;
@@ -229,6 +246,10 @@ public class SendSginAccessLogService {
 
     private <T> R<T> send(Map<String, Object> params, String url, HttpMethod method, ParameterizedTypeReference<R<T>> reference) {
         HttpEntity<Map<String, Object>> requestEntity = getMapHttpEntity(params);
+        logger.info("调用url={}",url);
+        logger.info("调用method={}",JSON.toJSONString(method));
+        logger.info("调用requestEntity={}", JSON.toJSONString(requestEntity));
+        logger.info("reference={}", JSON.toJSONString(reference));
         ResponseEntity<R<T>> exchange = restTemplateLocal.exchange(url, method, requestEntity, reference);
         R<T> body = exchange.getBody();
         if (body != null && body.getCode() == HttpStatus.UNAUTHORIZED) {

+ 3 - 2
zd-modules/zd-algorithm/src/main/java/com/zd/alg/forward/utils/HttpUtils.java

@@ -107,8 +107,9 @@ public class HttpUtils {
      */
     public static MultiValueMap<String, Object> getMultiValueMap(FireProperties properties, String extension) {
         MultiValueMap<String, Object> form = getStringObjectMultiValueMap(extension);
-        form.add("algoId", properties.getAlgoId());
-        form.add("did", properties.getDid());
+        form.add("aid", properties.getAlgoId());
+//        form.add("did", properties.getDid());
+        form.add("cid", properties.getCid());
         return form;
     }
 

+ 101 - 0
zd-modules/zd-algorithm/src/main/java/com/zd/alg/forward/utils/ImageBioChangeUtil.java

@@ -0,0 +1,101 @@
+package com.zd.alg.forward.utils;
+ 
+import java.awt.image.BufferedImage;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+ 
+import javax.imageio.ImageIO;
+
+import com.github.pagehelper.util.StringUtil;
+import sun.misc.BASE64Decoder;
+import sun.misc.BASE64Encoder;
+ 
+public class ImageBioChangeUtil {
+	
+	static BASE64Encoder encoder = new sun.misc.BASE64Encoder();   
+    static BASE64Decoder decoder = new sun.misc.BASE64Decoder();
+    
+    //从文件路径中获取图片转为二进制
+	public static String getImageBinary(String filePath){
+		if(StringUtil.isEmpty(filePath)) {
+			return null;
+		}
+        File f = new File(filePath);	//这里gif动态图不可以,虽然在后面也能输出gif格式,但是却不是动图
+        BufferedImage bi;   
+        try {   
+            bi = ImageIO.read(f);   
+            ByteArrayOutputStream baos = new ByteArrayOutputStream();   
+            ImageIO.write(bi, "jpg", baos);   
+            byte[] bytes = baos.toByteArray();   
+               
+            return encoder.encodeBuffer(bytes).trim();   
+        } catch (IOException e) {   
+            e.printStackTrace();   
+        }   
+        return null;   
+    }
+	//从URl中获取图片转为二进制
+	public static String getImageBinaryFromUrl(String urlPath) throws Exception{
+		if(StringUtil.isEmpty(urlPath)) {
+			return "";
+		}
+		URL url=new URL(urlPath);
+        HttpURLConnection conn= (HttpURLConnection) url.openConnection();
+        conn.setRequestMethod("GET");
+        conn.setConnectTimeout(3000);//超时提示1秒=1000毫秒
+        InputStream inStream=conn.getInputStream();//获取输出流
+        byte[] data=readInputStream(inStream);
+		return encoder.encodeBuffer(data).trim();   
+		
+	}   
+	 //readInputStream方法
+    private static byte[] readInputStream(InputStream inStream) throws Exception{
+        ByteArrayOutputStream outStream=new ByteArrayOutputStream();
+        byte[] buffer=new byte[1024];//转换为二进制
+        int len=0;
+        while((len =inStream.read(buffer))!=-1){
+            outStream.write(buffer,0,len);
+        }
+        return  outStream.toByteArray();
+    }
+    //将二进制转为图片
+    public static void base64StringToImage(String base64String,String outFilePath){
+    	if(StringUtil.isNotEmpty(base64String)&&StringUtil.isNotEmpty(outFilePath)) {
+    		try {   
+                byte[] bytes1 = decoder.decodeBuffer(base64String);   
+                   
+                ByteArrayInputStream bais = new ByteArrayInputStream(bytes1);   
+                BufferedImage bi1 =ImageIO.read(bais);   
+                File w2 = new File(outFilePath);//可以是jpg,png格式   
+                if (!w2.exists()) {   //文件不存在则创建文件,先创建目录
+                    File dir = new File(w2.getParent());
+                    dir.mkdirs();
+                    w2.createNewFile(); // 创建新文件
+                }
+                ImageIO.write(bi1, "jpg", w2);//不管输出什么格式图片,此处不需改动   
+            } catch (IOException e) {   
+                e.printStackTrace();   
+            }   
+		}
+    }
+    
+    public static void main(String[] args) {
+//    	String imageBinary=null;
+//		try {
+//			imageBinary = getImageBinaryFromUrl("");
+//		} catch (Exception e) {
+//			// TODO Auto-generated catch block
+//			e.printStackTrace();
+//		}
+//        System.out.println(imageBinary);
+        String outFilePath= "E://huoyan.jpg";
+//        base64StringToImage(imageBinary,outFilePath);
+        String imageBinary1 = getImageBinary(outFilePath);
+        System.out.println(imageBinary1);
+    }
+}

+ 1 - 0
zd-modules/zd-modules-laboratory/src/main/java/com/zd/laboratory/controller/LabRiskPlanController.java

@@ -313,6 +313,7 @@ public class LabRiskPlanController extends BaseController {
     @PostMapping("/triggerRiskPlan")
     public ResultData triggerRiskPlan(@RequestBody SubFunction <SensorFunctionStatus> subFunction) {
         try {
+            logger.error("调用火焰触发预案={}",JSON.toJSONString(subFunction));
             int flag=1;
             //如果实验室ID为空 通过设备ID查询绑定实验室ID
             if(StringUtils.isNull(subFunction.getSubId())){