package com.casic.missiles.netty; import cn.hutool.core.date.DateUtil; import cn.hutool.core.util.ObjectUtil; import com.casic.missiles.modular.neutron.model.Psd; import com.casic.missiles.modular.neutron.model.Vol; import lombok.extern.slf4j.Slf4j; import net.jodah.expiringmap.ExpirationPolicy; import net.jodah.expiringmap.ExpiringMap; import org.springframework.stereotype.Component; import java.util.*; import java.util.concurrent.TimeUnit; @Slf4j @Component public class CacheUtils { //电压数据分包计数 private volatile static int VOL_I = 0; private volatile static boolean VOL_FLAG = false; //PSD数据分包计数 private volatile static int PSD_I = 0; private volatile static boolean PSD_FLAG = false; /** * 缓存电压信息 */ public static final ExpiringMap<Integer, String> VOL_MAP = ExpiringMap.builder() .maxSize(3000) .expiration(5, TimeUnit.MINUTES) .variableExpiration() .expirationPolicy(ExpirationPolicy.ACCESSED) .build(); /** * 缓存PSD流信息 */ public static final ExpiringMap<Integer, String> PSD_MAP = ExpiringMap.builder() .maxSize(3000) .expiration(5, TimeUnit.MINUTES) .variableExpiration() // .expirationListener((key,value) -> { // System.out.println("key:" + key + "已过期……"); // }) .expirationPolicy(ExpirationPolicy.ACCESSED) .build(); /** * 缓存PSD解析后的数据 */ public static final ExpiringMap<String, String> PSD_DATA_MAP = ExpiringMap.builder() .maxSize(5000) .expiration(1, TimeUnit.MINUTES) .variableExpiration() .expirationPolicy(ExpirationPolicy.ACCESSED) .build(); public synchronized static String startVolMapCache() { String msgs = ""; if (CacheUtils.VOL_MAP.size() > 1) { Set<Integer> keys = CacheUtils.VOL_MAP.keySet(); if(null!=keys) { List<Integer> keyInts = new ArrayList<>(keys); Collections.sort(keyInts); for (Integer i : keyInts) { msgs += CacheUtils.VOL_MAP.get(i); } if (ObjectUtil.isNotEmpty(msgs)) { CacheUtils.VOL_MAP.clear(); } } } return msgs; } public synchronized static String startPsdMapCache() { String msgs = ""; if (CacheUtils.PSD_MAP.size() > 1) { Set<Integer> keys = CacheUtils.PSD_MAP.keySet(); List<Integer> keyInts = new ArrayList<>(keys); Collections.sort(keyInts); for (Integer i : keyInts) { msgs += CacheUtils.PSD_MAP.get(i); } if (ObjectUtil.isNotEmpty(msgs)) { CacheUtils.PSD_MAP.clear(); } } return msgs; } public static void main(String[] args) { String msg = "f0f0a5a50300001102000c081b0070000000000059f372000d81030058d50000f0f0a5a50300001102000b081b0070000000000012c7a900bd7e03006ed3000055aa55aa4dfccf1a2c000000f0f0a5a50300001102000b081b00700000000000aa0b2e001080030084d40000"; String[] arr = msg.split(InstructCode.PSD1_HEAD); Double psdRate=(1234L-867L)*1.000/1234L; System.out.println(arr); } //解析PSD数据 public static List<Psd> processPSD(String msgT) { List<Psd> psdList = new ArrayList<>(); String[] msgArr = msgT.split(InstructCode.PSD1_HEAD); for (int j = 0; j < msgArr.length; j++) { String msg = msgArr[j]; if (msgArr.length > 1 && ObjectUtil.isNotEmpty(msgArr[j]) && j > 0) { msg = InstructCode.PSD1_HEAD + msg; } if (ObjectUtil.isNotEmpty(msg)) { // 1、处理 PSD数据 if (msg.indexOf(InstructCode.PSD1_HEAD) != -1) { if (msg.length() >= 24) { // log.info("原始msg--->"+msg); int totalLength = Integer.parseInt(ByteUtil.reverseHex(msg.substring(msg.indexOf(InstructCode.PSD1_HEAD) + 16, msg.indexOf(InstructCode.PSD1_HEAD) + 24)), 16); if (msg.length() >= totalLength * 2) { PSD_FLAG = false; for (int i = 0; i < (msg.length() - (msg.indexOf(InstructCode.PSD1_HEAD) + 24)) / 64; i++) { String msgi = msg.substring((msg.indexOf(InstructCode.PSD1_HEAD) + 24) + i * 64, (msg.indexOf(InstructCode.PSD1_HEAD) + 24) + (i + 1) * 64); if (msgi.indexOf(InstructCode.PSD2_HEAD) == 0) { String gateOff = ByteUtil.reverseHex(msgi.substring(16, 20)); String baseline = ByteUtil.reverseHex(msgi.substring(20, 24)); String shortGate = ByteUtil.reverseHex(msgi.substring(24, 28)); String longGate = ByteUtil.reverseHex(msgi.substring(28, 32)); String qlong = ByteUtil.reverseHex(msgi.substring(48, 56)); String qshort = ByteUtil.reverseHex(msgi.substring(56, 64)); log.info("gateOff--->" + gateOff + "baseline--->" + baseline + "shortGate--->" + shortGate + "longGate--->" + longGate + "qlong--->" + qlong + "qshort--->" + qshort); psdList.add(new Psd(gateOff, baseline, shortGate, longGate, qlong, qshort, DateUtil.formatDateTime(new Date()))); } } } else { //2.缺psd数据存入缓存处理 PSD_FLAG = true; PSD_I++; CacheUtils.PSD_MAP.put(PSD_I, msg); // log.info("psd加入数据:" + PSD_I + "------->" + msg); } } } else if (PSD_FLAG) { PSD_I++; CacheUtils.PSD_MAP.put(PSD_I, msg); String str = startPsdMapCache(); // log.info("分包psd加入数据:" + PSD_I + "------->" + msg); if (ObjectUtil.isNotEmpty(str) && str.length() >= 24) { // log.info("**************strpsd---->" + str); if (str.indexOf(InstructCode.PSD1_HEAD) != -1 && str.substring(str.indexOf(InstructCode.PSD1_HEAD) + 16).length() >= 8) { int totalLength = Integer.parseInt(ByteUtil.reverseHex(str.substring(str.indexOf(InstructCode.PSD1_HEAD) + 16, str.indexOf(InstructCode.PSD1_HEAD) + 24)), 16); if (str.length() >= totalLength * 2) { PSD_FLAG = false; for (int i = 0; i < (str.length() - (str.indexOf(InstructCode.PSD1_HEAD) + 24)) / 64; i++) { String msgi = str.substring((str.indexOf(InstructCode.PSD1_HEAD) + 24) + i * 64, (str.indexOf(InstructCode.PSD1_HEAD) + 24) + (i + 1) * 64); if (msgi.indexOf(InstructCode.PSD2_HEAD) == 0) { String gateOff = ByteUtil.reverseHex(msgi.substring(16, 20)); String baseline = ByteUtil.reverseHex(msgi.substring(20, 24)); String shortGate = ByteUtil.reverseHex(msgi.substring(24, 28)); String longGate = ByteUtil.reverseHex(msgi.substring(28, 32)); String qlong = ByteUtil.reverseHex(msgi.substring(48, 56)); String qshort = ByteUtil.reverseHex(msgi.substring(56, 64)); log.info("分包:gateOff--->" + gateOff + "baseline--->" + baseline + "shortGate--->" + shortGate + "longGate--->" + longGate + "qlong--->" + qlong + "qshort--->" + qshort); psdList.add(new Psd(gateOff, baseline, shortGate, longGate, qlong, qshort, DateUtil.formatDateTime(new Date()))); } } } } } } } } return psdList; } //解析电压数据 public static List<Vol> processVOL(String msg) { List<Vol> volList = new ArrayList<>(); //2、处理 电压数据 if (msg.indexOf(InstructCode.DAC_HEAD + InstructCode.DAC_HEAD_LENGTH) != -1) { //完整包处理 if (msg.length() >= (msg.indexOf(InstructCode.DAC_HEAD + InstructCode.DAC_HEAD_LENGTH) + 24 + InstructCode.DAC_DATA_LENGTH)) { VOL_FLAG = false; msg = msg.substring(msg.indexOf(InstructCode.DAC_HEAD + InstructCode.DAC_HEAD_LENGTH) + 24); String[] volArr = InstructCode.getVolArr(msg); //本设备只用到第6通道 String vol6 = volArr[5]; log.info("第6通道电压值-------->" + vol6); volList.add(new Vol(Long.parseLong(vol6,16)+"", DateUtil.formatDateTime(new Date()))); } else { //分包处理,先放到缓存 VOL_FLAG = true; VOL_I++; CacheUtils.VOL_MAP.put(VOL_I, msg); } } else if (VOL_FLAG) { VOL_I++; CacheUtils.VOL_MAP.put(VOL_I, msg); String str = startVolMapCache(); VOL_FLAG = false; if (ObjectUtil.isNotEmpty(str) &&str.indexOf(InstructCode.DAC_HEAD + InstructCode.DAC_HEAD_LENGTH) != -1&& str.length() >= (str.indexOf(InstructCode.DAC_HEAD + InstructCode.DAC_HEAD_LENGTH) + 24 + InstructCode.DAC_DATA_LENGTH)) { str = str.substring(str.indexOf(InstructCode.DAC_HEAD + InstructCode.DAC_HEAD_LENGTH) + 24); String[] volArr = InstructCode.getVolArr(str); //本设备只用到第6通道 String vol6 = volArr[5]; log.info("分包第6通道电压值-------->" + vol6); volList.add(new Vol(Long.parseLong(vol6,16)+"", DateUtil.formatDateTime(new Date()))); } } return volList; } public static Map<String, Object> processData(String msg) { Map<String, Object> resultMap = new HashMap<>(); //解析PSD数据 List<Psd> psdList = processPSD(msg); //解析电压数据 List<Vol> volList = processVOL(msg); resultMap.put("psd", psdList); resultMap.put("vol", volList); return resultMap; } }