package com.fzzy.igds.iot.analysis; import com.fzzy.igds.constant.Constant; import com.fzzy.igds.constant.OrderRespEnum; import com.fzzy.igds.constant.RedisConst; import com.fzzy.igds.data.GrainData; import com.fzzy.igds.domain.*; import com.fzzy.igds.io.notify.NotifyGrainInvoker; import com.fzzy.igds.iot.analysis.builder.ReMessageBuilder; import com.fzzy.igds.iot.analysis.message.DeviceAttr; import com.fzzy.igds.iot.analysis.message.DeviceAttrInfo; import com.fzzy.igds.io.notify.NotifyWebInvoker; import com.fzzy.igds.service.*; import com.fzzy.igds.utils.ContextUtil; import com.ruoyi.common.core.redis.RedisCache; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import javax.annotation.Resource; import java.util.Date; import java.util.List; /** * @Description 解析入口 * @Author CZT * @Date 2025/11/11 18:20 */ @Slf4j @Component(AnalysisService.BEAN_ID) public class AnalysisService { public static final String BEAN_ID = "iot.analysisService"; @Resource private DeviceSerService deviceSerService; @Resource private DeviceIotService deviceIotService; @Autowired private DepotService depotService; @Autowired private NotifyWebInvoker notifyWebInvoker; @Autowired private DepotConfService depotConfService; @Autowired private NotifyGrainInvoker notifyGrainInvoker; @Resource private QuantityService quantityService; @Resource private RedisCache redisCache; /** * @param sessionKey ip:port * @param msg */ public void analysis(String sessionKey, String msg) throws Exception { String[] attr = sessionKey.split(":"); String ip = attr[0]; Integer port = Integer.valueOf(attr[1]); DeviceAttr reMessage = ReMessageBuilder.getInstance().buildMessage( ip, port, msg); if (null == reMessage || null == reMessage.getOrgId()) { log.error("IOT网关----->>>平台:返回信息没有获取组织编码信息,无法继续解析----{}", sessionKey); return; } DeviceSer ser = deviceSerService.getCacheSerBySn(reMessage.getOrgId(),reMessage.getSn()); if (null == ser) { String info = "IOT网关=" + reMessage.getDeviceId() + "返回信息没有匹配到分机,忽略消息。"; log.error("IOT网关----->>>平台:" + info); notifyWebInvoker.notifyWeb(reMessage.getOrgId(), OrderRespEnum.MSG_ERROR,"SYS", info); // 清除缓存并销毁链接 return; } //更新分机状态 ser.setIp(ip); ser.setPort(port); ser.setStatus(Constant.YN_Y); deviceSerService.updateByData(ser); log.debug("IOT网关----->>>平台:所属组织-{},分机-{} 返回的命令信息={}", ser.getCompanyId(), ser.getName(), reMessage.toString()); List deviceIots = deviceIotService.getCacheDeviceIotBySerId(ser.getCompanyId(),ser.getId()); if(deviceIots == null || deviceIots.size() <= 0){ log.error("IOT网关----->>>平台:" + "没有获取到分机下面有设备!"); return ; } DeviceIot deviceIot = deviceIots.stream().filter(item -> (item.getPassCode()+"").equals(reMessage.getDeviceId())).findAny().orElse(null); if(deviceIot == null ){ log.error("IOT网关----->>>平台:" + "没有获取到设备单个!"); return ; } log.info("IOT网关----->>>平台:"+ "开始解析数据" + reMessage.toString()); if(StringUtils.isEmpty(reMessage.getType())){ //液位解析 analysisHeight(reMessage, ser,deviceIot); } if("2".equals(reMessage.getType()) || "02".equals(reMessage.getType())){ //油温解析 analysisOilGrain(reMessage, ser,deviceIot); }else { //液位解析 analysisHeight(reMessage, ser,deviceIot); } } /** * 网管油情解析 * @param deviceAttr * @param ser */ public void analysisOilGrain(DeviceAttr deviceAttr, DeviceSer ser, DeviceIot deviceIot) { try { log.info("IOT网关----->>>平台:"+ "开始解析温度数据" + deviceAttr.toString()); List list = deviceAttr.getTerminalAttrInfoList(); if(null == list || list.isEmpty()){ log.error("IOT网关----->>>平台:" + "油情数据为空,不解析!"); return; } Integer ceng = 0; String points = ""; Double max = null, min = null, sumT = 0.0; Double temp = 0.0; for (DeviceAttrInfo iotInfo : list) { if("1".equals(iotInfo.getPasscode()) || "2".equals(iotInfo.getPasscode())){ //通道号为1或者2时,是通信状态和告警状态,不解析 continue; } points += iotInfo.getValue() + ","; ceng ++; temp = Double.valueOf(iotInfo.getValue()); if(null == max){ max = temp; } if(null == min){ min = temp; } if (temp > max) { max = temp; } if (temp < min) { min = temp; } sumT += temp; } DepotConf depotConf = depotConfService.getCacheDepotConfByDepotId(ser.getCompanyId(), deviceIot.getDepotId()); Depot depot = depotService.getCacheDepot(ser.getCompanyId(), deviceIot.getDepotId()); Grain grain = new Grain(); grain.setBatchId(ContextUtil.getBatchIdByFireq(depotConf.getGrainFreq())); grain.setReceiveDate(new Date()); grain.setCable("1"); grain.setCableCir(ceng + ""); grain.setPoints(points); grain.setCheckUser("系统"); grain.setDepotId(deviceIot.getDepotId()); grain.setCompanyId(depotConf.getCompanyId()); grain.setHumidityIn(-100.0); grain.setTempIn(-100.0); grain.setTempAve(sumT/ceng); grain.setTempMax(max); grain.setTempMin(min); grain.setDeptId(depot.getDeptId()); //油罐 液位高度,有就赋值 GrainData data = (GrainData) redisCache.getCacheObject(RedisConst.buildKey(ser.getCompanyId(),RedisConst.KEY_DEPOT_HEIGHT,grain.getDepotId())); if(data!= null && StringUtils.isNotEmpty(data.getOilHeight())){ grain.setOilHeight(data.getOilHeight()); } // 用户封装好数据即可 notifyGrainInvoker.analysisSuccess(grain, depot); log.info("IOT网关----->>>平台:油温解析完成:" + data); } catch (Exception e) { log.error(e.getMessage(), e); } } /** * 网管液位高度解析 * @param deviceAttr * @param ser */ public void analysisHeight(DeviceAttr deviceAttr, DeviceSer ser, DeviceIot deviceIot) { try { Depot depot = depotService.getCacheDepot(ser.getCompanyId(), deviceIot.getDepotId()); if(null == depot){ log.error("IOT网关----->>>平台:" + "未获取仓库信息,不解析!"); return; } List list = deviceAttr.getTerminalAttrInfoList(); if(null == list || list.isEmpty()){ log.error("IOT网关----->>>平台:" + "油情数据为空,不解析!"); return; } Double diameter = 0.0; //直径 Double volume = 0.0; //体积 Double bulkWeight = 0.0; //容重 Double realHeight = 0.0; //页面高度 Double maxHeight = 0.0; //最大高度 Double storage = 0.0; //计算储量 Double heightPer = 0.0; //高度百分比 if(null != depot.getHeight()){ maxHeight = depot.getHeight(); } if(null != depot.getLength()){ diameter = depot.getLength(); } if(null != depot.getBulkWeight()){ bulkWeight = depot.getBulkWeight(); } //解析真实高度 realHeight = Double.valueOf(list.get(2).getValue()); //计算体积 volume = 3.14159 * Math.pow(diameter / 2, 2) * realHeight; //判断体积是否为负,为负值则不计算,重置为0 if (volume < 0) { volume = 0.0; } //计算重量 storage = volume * bulkWeight; storage = Double.valueOf(String.format("%.2f", storage)); //高度百分比 if(maxHeight > 0){ heightPer = Double.valueOf(String.format("%.2f", realHeight/maxHeight * 100)); } Quantity data = new Quantity(); data.setBatchId(depot + ContextUtil.generateId()); data.setCompanyId(ser.getCompanyId()); data.setDeptId(depot.getDeptId()); data.setDepotId(deviceIot.getDepotId()); data.setDiameter(depot.getLength()); data.setHeightPer(heightPer); data.setHeight(realHeight); data.setBulk(volume); data.setWeight(storage); data.setReceiveDate(new Date()); data.setCheckUser("系统"); quantityService.saveData( data); log.info("高度解析完成:" + data); } catch (Exception e) { log.error(e.getMessage(), e); } } }