package com.ruoyi.task;
|
|
import com.alibaba.fastjson2.JSONArray;
|
import com.alibaba.fastjson2.JSONObject;
|
import com.mashape.unirest.http.HttpResponse;
|
import com.mashape.unirest.http.Unirest;
|
import com.mashape.unirest.http.exceptions.UnirestException;
|
import com.ruoyi.aibrain.domain.AiCamera;
|
import com.ruoyi.aibrain.service.IAiCameraService;
|
import com.ruoyi.camera.domain.CameraShipingsb;
|
import com.ruoyi.camera.service.ICameraShipingsbService;
|
import com.ruoyi.common.config.RuoYiConfig;
|
import com.ruoyi.common.constant.CacheConstants;
|
import com.ruoyi.common.core.domain.model.LoginUser;
|
import com.ruoyi.common.core.redis.RedisCache;
|
import com.ruoyi.common.utils.http.HttpUtils;
|
import com.ruoyi.common.utils.spring.SpringUtils;
|
import com.ruoyi.interchange.domain.TbDataSendRecords;
|
import com.ruoyi.interchange.service.ITbDataSendRecordsService;
|
import com.ruoyi.system.domain.SysUserOnline;
|
import okhttp3.*;
|
|
import javax.net.ssl.SSLContext;
|
import javax.net.ssl.TrustManager;
|
import javax.net.ssl.X509TrustManager;
|
import java.io.File;
|
import java.security.KeyManagementException;
|
import java.security.NoSuchAlgorithmException;
|
import java.text.ParseException;
|
import java.text.SimpleDateFormat;
|
import java.util.*;
|
import java.util.concurrent.TimeUnit;
|
|
public class CameraAssembleUtil {
|
private static IAiCameraService aiCameraService;
|
private static ICameraShipingsbService cameraShipingsbService;
|
private static ITbDataSendRecordsService tbDataSendRecordsService;
|
private static RedisCache redisCache;
|
|
private static String SJURL="https://192.168.100.89:4200/spjr000/api/open/v1"; //省级请求地址
|
private static String MKBM= RuoYiConfig.getMkbm(); //煤矿编码
|
private static String MKMC= RuoYiConfig.getMkmc(); //煤矿名称
|
private static String SCCJ="徐州珂尔玛科技有限公司"; //生产厂家名称
|
private static String XTXH="KEM2023SPJKXT"; //系统型号
|
private static String XTMC="AI智能视频监控系统"; //系统名称
|
|
//接口说明:https://192.168.100.89:4200/spjr000/swagger/index.html
|
//上传接口:https://192.168.100.89:4200/spjr000/api/open/v1/ai/channel/general/push
|
|
private static SimpleDateFormat YMDformat = new SimpleDateFormat("yyyy-MM-dd");
|
private static SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss");
|
private static SimpleDateFormat formatYMD = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
|
static {
|
aiCameraService = SpringUtils.getBean(IAiCameraService.class);
|
cameraShipingsbService = SpringUtils.getBean(ICameraShipingsbService.class);
|
tbDataSendRecordsService = SpringUtils.getBean(ITbDataSendRecordsService.class);
|
redisCache = SpringUtils.getBean(RedisCache.class);
|
}
|
|
|
//AI分析识别数据传输
|
//HTTPS://ip:port/api/open/v1/ai/channel/general/push/
|
//煤矿企业编码 company String(12)
|
//摄像头编码 biz String(5)
|
//分析类型编码 channel String(2)
|
//数据上报时间 pdt String(10) UTC 时间戳
|
//运输设备视频 (掘进工作面带式输送机机头、采煤工作面刮板机及带式输送机机头) file 上限10兆
|
//视频文件命名格式如下:煤矿企业编码+摄像头编码+分析类型编码+生产、运输设备运行状态编码+当前时间+.MP4,编码规范具体参考表 5-18 基础编码表。例如在 2021 年1月4日12点15分46秒识别到一煤矿企业掘进工作面带式输送机机头由停止变为运行,并且有煤,企业立即上传证据视频,视频文件名称为:1404210078660700200003000120210104121546.MP4
|
//扩展参数 data list String(255)
|
|
//1.运输设备运行状态识别信息
|
//2.工作面出口障碍物识别信息
|
//3.单体柱状态识别信息
|
//4.堆煤识别信息
|
//5.危险区域警戒线(电子围栏)内人员进入识别信息
|
//6.马头门罐笼摇台状态识别信息
|
//7.摄像头遮挡、挪动角度识别信息
|
public static void cameraAiError() throws ParseException {
|
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
|
//查询出所以未传输的报警
|
Collection<String> keys = redisCache.keys("video_*");
|
for (String key : keys) {
|
JSONObject errObj = redisCache.getCacheObject(key);
|
AiCamera aiCamera = redisCache.getCacheObject("AI::AiCameraObj"+errObj.getString("cameraCode"));
|
if(aiCamera!=null){
|
String shiBieLXMC=getShiBieLXMC(errObj.getString("analyse"));
|
if(shiBieLXMC.equals("未找到的类别")){
|
errObj.put("error","未找到的类别");
|
redisCache.setCacheObject("SC::error::"+key,errObj,10,TimeUnit.DAYS);
|
}else{
|
Date warningTime=sdf.parse(errObj.getString("warningTime"));
|
|
//需结合AI分析进行完善
|
CameraShipingsb cameraShipingsb=new CameraShipingsb();
|
cameraShipingsb.setSheXiangTID(aiCamera.getId());//摄像头ID
|
cameraShipingsb.setSheXiangTBM(errObj.getString("cameraCode"));//摄像头编码
|
cameraShipingsb.setShiBieLXBM(errObj.getString("analyseResult"));//识别类型编码
|
cameraShipingsb.setShiBieLXMC(shiBieLXMC);//识别类型名称
|
cameraShipingsb.setFenXiLXBM(errObj.getString("analyse"));//分析类型编码
|
cameraShipingsb.setFileUrl(errObj.getString("recordFileName"));//识别视频存储地址
|
cameraShipingsb.setShuJuSJ(warningTime);//数据时间
|
cameraShipingsbService.insertCameraShipingsb(cameraShipingsb);
|
|
JSONObject objCS=new JSONObject();
|
objCS.put("type","AI分析");
|
objCS.put("sendSum",0);
|
|
JSONObject obj=new JSONObject();
|
obj.put("company",MKBM);//煤矿企业编码
|
obj.put("biz",aiCamera.getCameraNum());//摄像头编码
|
obj.put("channel",cameraShipingsb.getFenXiLXBM() + cameraShipingsb.getShiBieLXBM());//分析类型编码
|
long currentTime=warningTime.getTime()/1000;
|
obj.put("pdt",currentTime);//数据上报时间
|
obj.put("file",cameraShipingsb.getFileUrl());//运输设备视频
|
obj.put("data","[]");//扩展参数
|
objCS.put("data",obj);
|
|
redisCache.rightPush("CameraAssemble",objCS);
|
redisCache.setCacheObject("SC::success::"+key,errObj,10,TimeUnit.DAYS);
|
}
|
}else{
|
errObj.put("error","未找到该摄像头");
|
redisCache.setCacheObject("SC::error::"+key,errObj,10,TimeUnit.DAYS);
|
}
|
|
redisCache.deleteObject(keys);
|
}
|
}
|
|
|
/**识别结果,按上级要求定制,都归属于以下识别类型(在IPCConfig.xml文件中配置)
|
* 运输设备运行状态 003
|
* 人员入井 004
|
* 货运车辆 005
|
* 人员睡岗 007
|
* 人员空岗 008
|
* 危险区域人员闯入 013
|
* 摄像头遮挡 020
|
* 摄像头挪动角度 021
|
* 罐笼摇台未到位 057
|
* 单体柱倾倒识别 059
|
* 障碍物堵塞识别 060
|
* 堆煤识别 062
|
* */
|
public static String getShiBieLXMC(String shiBieLXBM){
|
switch (shiBieLXBM){
|
case "003":
|
return "运输设备运行状态";
|
case "004":
|
return "人员入井";
|
case "005":
|
return "货运车辆";
|
case "007":
|
return "人员睡岗";
|
case "008":
|
return "人员空岗";
|
case "013":
|
return "危险区域人员闯入";
|
case "020":
|
return "摄像头遮挡";
|
case "021":
|
return "摄像头挪动角度";
|
case "057":
|
return "罐笼摇台未到位";
|
case "059":
|
return "单体柱倾倒识别";
|
case "060":
|
return "障碍物堵塞识别";
|
case "062":
|
return "堆煤识别";
|
default:
|
return "未找到的类别";
|
}
|
}
|
|
|
//8.带标记实时播放地址(需鉴权 实时视频地址变动时)
|
//HTTPS://ip:port/api/open/v1/ai/video/register/
|
//煤矿企业编码 company String(12)
|
//摄像头编码 biz String(5)
|
//识别视频流名称/简称 name String(32)
|
//视频接入协议 protocol String(12)
|
//接入视频编码 raw_codec String(5)
|
//实时视频地址 url String(128)
|
public static void cameraInfo(){
|
AiCamera aiCamera=new AiCamera();
|
aiCamera.setStatus("1");//启用的摄像头
|
List<AiCamera> list = aiCameraService.selectAiCameraList(aiCamera);
|
JSONObject objCS=new JSONObject();
|
objCS.put("type","摄像头信息");
|
objCS.put("sendSum",0);
|
|
for (int i = 0; i < list.size(); i++) {
|
AiCamera aiCameraObj=list.get(i);
|
JSONObject obj=new JSONObject();
|
obj.put("company",MKBM);//煤矿企业编码
|
obj.put("biz",aiCameraObj.getCameraNum());//摄像头编码
|
obj.put("name",aiCameraObj.getName());//识别视频流名称/简称
|
obj.put("protocol","RTMP");//视频接入协议
|
obj.put("raw_codec","H.264");//接入视频编码
|
obj.put("url",aiCameraObj.getToRtmp());//实时视频地址
|
objCS.put("data",obj);
|
redisCache.rightPush("CameraAssemble",objCS);
|
}
|
}
|
|
|
|
//9.摄像头在线、离线检测信息(每 5分钟一次)
|
//HTTPS://ip:port/api/open/v1/probe/status/push/
|
//煤矿企业编码 company String(12)
|
//摄像头编码 biz String(5)
|
//分析类型编码 biz_type String(2)
|
//子系统采集类型 link_type 固定为 AI String(2)
|
//采集传输频率 freq 固定为 0 String(1)
|
//采集类型 freq_channel 固定为空字符串 int(1)
|
//软件运行状态 status int(1) 摄像头离线时,推送值为 0,摄像头在线状态时,值为 1
|
public static void cameraSatus(){
|
AiCamera aiCamera=new AiCamera();
|
aiCamera.setStatus("1");//启用的摄像头
|
List<AiCamera> list = aiCameraService.selectAiCameraList(aiCamera);
|
JSONObject objCS=new JSONObject();
|
objCS.put("type","状态检测");
|
objCS.put("sendSum",0);
|
|
for (int i = 0; i < list.size(); i++) {
|
AiCamera aiCameraObj=list.get(i);
|
JSONObject obj=new JSONObject();
|
obj.put("company",MKBM);//煤矿企业编码
|
obj.put("biz",aiCameraObj.getCameraNum());//摄像头编码
|
obj.put("biz_type",aiCameraObj.getCameraModel());//摄像头分析类型编码
|
obj.put("link_type","AI");//子系统采集类型 固定为 AI
|
obj.put("freq","0");//采集传输频率 固定为 0
|
obj.put("freq_channel","");//采集类型 固定为空字符串
|
obj.put("status",aiCameraObj.getRunStatus());//软件运行状态
|
|
objCS.put("data",obj);
|
redisCache.rightPush("CameraAssemble",objCS);
|
}
|
}
|
|
|
|
|
public static void DataTransmission(JSONObject obj) throws UnirestException {
|
//通过https方式发送
|
//取出的数据
|
System.out.println("AI上传开始发送数据:"+obj.toString());
|
JSONObject paramJson=obj.getJSONObject("data");
|
|
TbDataSendRecords tbDataSendRecords=new TbDataSendRecords();
|
tbDataSendRecords.setFileName(paramJson.toJSONString());//文件名
|
tbDataSendRecords.setDataHeader("");//数据头
|
tbDataSendRecords.setDataNumber(1l);//数据数量
|
tbDataSendRecords.setCoalMineId(1l);//所属煤矿ID
|
tbDataSendRecords.setSystemId(1l);//所属系统ID
|
tbDataSendRecords.setRuleId(1l);//数据文件采集规则ID
|
tbDataSendRecords.setDetectionTime(new Date());//文件处理时间
|
tbDataSendRecords.setDetectionResult("0");//是否系统生成的 0是 1否
|
tbDataSendRecords.setCheckResult("1");//校验结果 0通过 1未通过
|
|
if(obj.getString("type").equals("AI分析")){
|
DataTransmissionAiFX(paramJson,tbDataSendRecords);
|
tbDataSendRecords.setSendFileUrl(paramJson.getString("file"));//文件发送FTP位置
|
}else if(obj.getString("type").equals("摄像头信息")){
|
DataTransmissionCameraInfo(paramJson,tbDataSendRecords);
|
}else if(obj.getString("type").equals("状态检测")){
|
DataTransmissionCameraStaus(paramJson,tbDataSendRecords);
|
}
|
tbDataSendRecordsService.insertTbDataSendRecords(tbDataSendRecords);
|
}
|
|
//AI分析识别数据传输
|
//HTTPS://ip:port/api/open/v1/ai/channel/general/push/
|
//煤矿企业编码 company String(12)
|
//摄像头编码 biz String(5)
|
//分析类型编码 channel String(2)
|
//数据上报时间 pdt String(10) UTC 时间戳
|
//运输设备视频 (掘进工作面带式输送机机头、采煤工作面刮板机及带式输送机机头) file 上限10兆
|
//视频文件命名格式如下:煤矿企业编码+摄像头编码+分析类型编码+生产、运输设备运行状态编码+当前时间+.MP4,编码规范具体参考表 5-18 基础编码表。例如在 2021 年1月4日12点15分46秒识别到一煤矿企业掘进工作面带式输送机机头由停止变为运行,并且有煤,企业立即上传证据视频,视频文件名称为:1404210078660700200003000120210104121546.MP4
|
//扩展参数 data list String(255)
|
|
//1.运输设备运行状态识别信息
|
//2.工作面出口障碍物识别信息
|
//3.单体柱状态识别信息
|
//4.堆煤识别信息
|
//5.危险区域警戒线(电子围栏)内人员进入识别信息
|
//6.马头门罐笼摇台状态识别信息
|
//7.摄像头遮挡、挪动角度识别信息
|
public static void DataTransmissionAiFX(JSONObject paramJson,TbDataSendRecords tbDataSendRecords) {
|
System.out.println("xxxxxxxxxxxxxxxx");
|
//String参数
|
Map<String, String> params = new HashMap<String, String>();
|
params.put("company",paramJson.getString("company"));//煤矿企业编码
|
params.put("biz",paramJson.getString("biz"));//摄像头编码
|
params.put("channel",paramJson.getString("channel"));//分析类型编码
|
params.put("pdt",paramJson.getString("pdt"));//数据上报时间
|
params.put("data",paramJson.getString("data"));//扩展参数
|
|
|
|
String boundary = "------WebKitFormBoundary7MA4YWxkTrZu0gW--"; // 设置boundary字符串,用于标识参数和附件的边界
|
|
final TrustManager[] trustAllCerts = new TrustManager[]{
|
new X509TrustManager() {
|
@Override
|
public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) {
|
}
|
|
@Override
|
public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) {
|
}
|
|
@Override
|
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
|
return new java.security.cert.X509Certificate[]{};
|
}
|
}
|
};
|
|
|
//请求地址
|
String url = SJURL+"/ai/channel/general/push/";
|
|
try{
|
final SSLContext sslContext = SSLContext.getInstance("SSL");
|
sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
|
final javax.net.ssl.SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
|
|
|
OkHttpClient client = new OkHttpClient.Builder()
|
.connectTimeout(30, TimeUnit.SECONDS)
|
.readTimeout(30, TimeUnit.SECONDS)
|
.sslSocketFactory(sslSocketFactory, (X509TrustManager) trustAllCerts[0])
|
.hostnameVerifier((hostname, session) -> true) // 信任所有主机名
|
.build();
|
String fileUrl=paramJson.getString("file");
|
File file = new File(fileUrl);
|
//fileUrl.split("\\");
|
String[] fileName=fileUrl.split("\\\\");
|
|
RequestBody body = new MultipartBody.Builder()
|
.setType(MultipartBody.FORM)
|
|
.addFormDataPart("company", params.get("company"))
|
.addFormDataPart("biz", params.get("biz"))
|
.addFormDataPart("channel", params.get("channel"))
|
.addFormDataPart("pdt", params.get("pdt"))
|
.addFormDataPart("data", params.get("data"))
|
|
.addFormDataPart("file", fileName[fileName.length-1],
|
RequestBody.create(MediaType.parse("application/octet-stream"),
|
file))
|
.build();
|
|
|
Request request = new Request.Builder()
|
.url(url)
|
.header("Content-Type", "multipart/form-data; boundary=" + boundary)
|
.post(body)
|
.build();
|
Response response = client.newCall(request).execute();
|
|
if (response.isSuccessful()) {
|
System.out.println("数据推送成功");
|
tbDataSendRecords.setSendResult("0");//发送结果 0成功 1失败
|
System.out.println("File uploaded successfully."+response.toString());
|
} else {
|
System.out.println("数据推送失败");
|
tbDataSendRecords.setSendResult("1");//发送结果 0成功 1失败
|
System.out.println("Failed to upload file. Response code: " + response.code());
|
}
|
}catch (Exception e){
|
System.out.println("数据推送失败"+e.getMessage());
|
tbDataSendRecords.setSendResult("1");//发送结果 0成功 1失败
|
}
|
|
}
|
|
//8.带标记实时播放地址(需鉴权 实时视频地址变动时)
|
//HTTPS://ip:port/api/open/v1/ai/video/register/
|
//煤矿企业编码 company String(12)
|
//摄像头编码 biz String(5)
|
//识别视频流名称/简称 name String(32)
|
//视频接入协议 protocol String(12)
|
//接入视频编码 raw_codec String(5)
|
//实时视频地址 url String(128)
|
public static void DataTransmissionCameraInfo(JSONObject paramJson,TbDataSendRecords tbDataSendRecords){
|
//Map<String, String> params= JSONObject.parseObject(paramJson.toString(),Map.class);;
|
//String respJson = HttpClientUtilHttps.doPost(SJURL+"/ai/video/register/",params, "UTF-8");
|
String respJson = HttpUtils.sendJsonToHttpsPost(SJURL+"/ai/video/register/",paramJson.toString());
|
|
JSONObject data = JSONObject.parseObject(respJson);
|
if (data == null) {
|
System.out.println("数据推送失败");
|
tbDataSendRecords.setSendResult("1");//发送结果 0成功 1失败
|
}else{
|
System.out.println("数据推送成功"+data.toString());
|
tbDataSendRecords.setSendResult("0");//发送结果 0成功 1失败
|
}
|
}
|
|
//9.摄像头在线、离线检测信息(每 30秒一次)
|
//HTTPS://ip:port/api/open/v1/probe/status/push/
|
//煤矿企业编码 company String(12)
|
//摄像头编码 biz_type String(5)
|
//分析类型编码 channel String(2)
|
//子系统采集类型 link_type 固定为 AI String(2)
|
//采集传输频率 freq 固定为 0 String(1)
|
//采集类型 freq_channel 固定为空字符串 int(1)
|
//软件运行状态 status int(1) 摄像头离线时,推送值为 0,摄像头在线状态时,值为 1
|
public static void DataTransmissionCameraStaus(JSONObject paramJson,TbDataSendRecords tbDataSendRecords){
|
//Map<String, String> params= JSONObject.parseObject(paramJson.toString(),Map.class);;
|
//String respJson = HttpClientUtilHttps.doPost(SJURL+"/ai/status/push/",params, "UTF-8");
|
String respJson = HttpUtils.sendJsonToHttpsPost(SJURL+"/ai/status/push/",paramJson.toString());
|
JSONObject data = JSONObject.parseObject(respJson);
|
if (data == null) {
|
System.out.println("数据推送失败");
|
tbDataSendRecords.setSendResult("1");//发送结果 0成功 1失败
|
}else{
|
System.out.println("数据推送成功"+data.toString());
|
tbDataSendRecords.setSendResult("0");//发送结果 0成功 1失败
|
}
|
}
|
|
}
|