package com.fzzy.protocol.youxian0.analysis; import com.alibaba.fastjson.JSONObject; import com.fzzy.api.data.GatewayDeviceType; import com.fzzy.api.utils.BytesUtil; import com.fzzy.api.utils.NumberUtil; import com.fzzy.gateway.GatewayUtils; import com.fzzy.gateway.api.GatewayDeviceReportService; import com.fzzy.gateway.api.GatewayRemoteManager; import com.fzzy.gateway.data.BaseReqData; import com.fzzy.gateway.data.WeatherWebDto; import com.fzzy.gateway.entity.GatewayDevice; import com.fzzy.gateway.hx2023.ScConstant; import com.fzzy.gateway.hx2023.data.*; import com.fzzy.protocol.ProtocolUtils; import com.fzzy.protocol.bhzn.cmd.ReMessageBuilder; import com.fzzy.protocol.data.THDto; import com.fzzy.protocol.youxian0.ServiceUtils; import com.fzzy.protocol.youxian0.data.GrainRoot; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import javax.annotation.Resource; import java.net.InetAddress; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** * 游仙主库,返回报文解析 */ @Slf4j @Component(AnalysisService.BEAN_ID) public class AnalysisService { public static final String BEAN_ID = "youxian0.analysisService"; @Resource private GatewayRemoteManager gatewayRemoteManager; private static Map contextGrainRoot = new HashMap<>(); /** * 用于存放返回的仓温仓湿信息 */ public static Map contextMapTH = new HashMap<>(); /** * 协议解析 *

* 7E 00 02 02 00 77 00 00 A0 FF FF 66 FF 04 BE 01 64 6A 6B 6A 68 CE 02 A4 BB BA BA B4 CE 03 E4 32 3D 32 3D CE 04 44 BC B3 BC B3 20 47 7E * * @param address * @param port * @param strMsg */ public void analysis(InetAddress address, int port, String strMsg) { //分机ID int start = 2 * 2; String deviceSn = strMsg.substring(start, start + 2); deviceSn = BytesUtil.hexToInt(deviceSn) + ""; //命令ID start = 5 * 2; String msgIdHex = strMsg.substring(start, start + 2); int msgId = BytesUtil.hexToInt(msgIdHex); //命令类型 start = 11 * 2; String funId = strMsg.substring(start, start + 2); GatewayDevice device = GatewayUtils.getCacheByDeviceSn(deviceSn); //粮情返回 if (ServiceUtils.FUNCTION_66.equalsIgnoreCase(funId)) { log.info("---------开始解析粮情信息---------"); try{ this.analysisGrainStep1(device, msgId, strMsg); }catch (Exception e){ log.error(e.getMessage(),e); } log.info("---------解析粮情信息结束---------"); } //温湿度返回 if (ServiceUtils.FUNCTION_68.equalsIgnoreCase(funId)) { log.info("---------开始解析仓温湿度信息---------"); try{ this.analysisGrainTh(device, strMsg); }catch (Exception e){ log.error(e.getMessage(),e); } } } private void analysisGrainTh(GatewayDevice device, String strMsg) { try{ THDto th = new THDto(); //TODO----->>> 待解析调整,先用外部气象信息 //7E 00 01 01 00 06 00 00 A0 FF FF 68 1A 05 CC 16 3A 62 36 7E //系统气象站信息 // WeatherWebDto weather = WeatherWebDto.contextMap.get("default"); // th.setTempIn(Double.valueOf(weather.getTem()) - 2); // th.setHumidityIn(Double.valueOf(weather.getHumidity()) - 10); double t,h; String temp = strMsg.substring(30,32); t = BytesUtil.hexToInt(temp)/2; log.info("温度:{}",t); temp = strMsg.substring(32,34); h = BytesUtil.hexToInt(temp); log.info("湿度:{}",h); th.setTempIn(t); th.setHumidityIn(h); this.add2ThMap(device.getDepotIdSys(), th); }catch (Exception e){ log.error(e.getMessage(),e); } } /** * 粮情解析 *

* 7E 00 02 02 00 77 00 00 A0 FF FF 66 FF 04 BE 01 64 6A 6B 6A 68 CE * 02 A4 BB BA BA B4 CE 03 E4 32 3D 32 3D CE 04 44 BC B3 BC B3 20 47 7E * * @param device * @param msgId 命令ID */ private void analysisGrainStep1(GatewayDevice device, int msgId, String strMsg) { String[] attCable = device.getCableRule().split("-"); int cableZ = Integer.valueOf(attCable[0]); int cableY = Integer.valueOf(attCable[1]); int cableX = Integer.valueOf(attCable[2]); log.info("z={},x={},y={}",cableZ,cableX,cableY); //获取请求信息 BaseReqData reqData = ProtocolUtils.getSyncReq(device.getDepotIdSys()); if (null == reqData) { log.error("---------没有获取到请求信息,不执行解析------{}", device.getDeviceName()); return; } //只保留粮情信息 int start = 15 * 2; strMsg = strMsg.substring(start); GrainRoot grainRoot = new GrainRoot(); grainRoot.setKey(buildGrainRootKey(device.getDeviceSn(), msgId)); grainRoot.setNum(msgId); String tempStr = ""; for (int j = 0;j points = new ArrayList<>(); GrainRoot root; List t = null; for (int i = 1; i <= cableX; i++) { root = this.getGrainRoot(buildGrainRootKey(reqData.getDevice().getDeviceSn(), i)); if (null == root || null == root.getPoints()) { log.error("-----------解析获取所有粮情检测点失败,取消执行---------{}---{}", reqData.getDevice().getDeviceName(),i); ; t = new ArrayList<>(); for (int x = 0;x points) { GatewayDevice device = reqData.getDevice(); //数据封装 GrainData grain = new GrainData(); grain.setMessageId(ScConstant.getMessageId()); grain.setDeviceId(device.getDeviceId()); grain.setTimestamp(System.currentTimeMillis() + ""); ClientHeaders headers = new ClientHeaders(); headers.setDeviceName(device.getDeviceName()); headers.setProductId(device.getProductId()); headers.setOrgId(device.getOrgId()); headers.setMsgId(reqData.getMessageId()); grain.setHeaders(headers); GrainOutPut outPut = new GrainOutPut(); double max = ReMessageBuilder.MAX_TEMP, min = ReMessageBuilder.MIN_TEMP, sumT = 0.0; List temperature = new ArrayList<>(); //根号 int cableNum = 1, position = 0,sumNum = 0; double curTemp; int x = 0, y = 0, z = 0; for (int i = 0; i < points.size(); i++) { curTemp = points.get(i); position = i; z = i % cableZ + 1; x = i / (cableZ * cableY); y = x * (cableZ * cableY); y = (i - y) / cableZ; //根号 cableNum = (i / cableZ) + 1; temperature.add(new GrainTemp(cableNum + "", z + "", curTemp + "", position + "")); sumT += curTemp; if (curTemp > max) { max = curTemp; } if (curTemp < min && new Double(curTemp).intValue()!= -100) { min = curTemp; } if(new Double(curTemp).intValue()!= -100){ sumNum++; } } if (sumNum == 0) { sumNum = 1; log.warn("---当前粮情采集异常--"); } //过滤比较用的最大最小值 if (max == ReMessageBuilder.MAX_TEMP) { max = 0.0; } if (min == ReMessageBuilder.MIN_TEMP) { min = 0.0; } outPut.setTemperature(temperature); outPut.setAvgTemperature(NumberUtil.keepPrecision((sumT / sumNum), 1) + ""); outPut.setMinTemperature(min + ""); outPut.setMaxTemperature(max + ""); List ths = new ArrayList<>(); //获取温湿度 THDto thDto = this.getGrainTh(device.getDepotIdSys()); ths.add(new GrainTH(thDto.getTempIn() != null ? thDto.getTempIn() + "" : "", thDto.getHumidityIn() != null ? thDto.getHumidityIn() + "" : "", "1")); outPut.setTemperatureAndhumidity(ths); grain.setOutput(JSONObject.toJSONString(outPut)); GatewayDevice gatewayDeviceWeather = GatewayUtils.getCacheByDeviceTypeOne(GatewayDeviceType.TYPE_09.getCode()); //系统气象站信息 WeatherWebDto weather = WeatherWebDto.contextMap.get("default"); //气象信息 GrainWeather weatherStation = new GrainWeather(); weatherStation.setMessageId(ScConstant.getMessageId()); weatherStation.setMessgeId(weatherStation.getMessageId()); if (null != gatewayDeviceWeather) { weatherStation.setId(gatewayDeviceWeather.getDeviceId()); } else { weatherStation.setId(device.getDeviceId()); } weatherStation.setAirPressure(weather.getPressure()); weatherStation.setHumidity(weather.getHumidity().replaceAll("%","")); weatherStation.setPm(weather.getAir_pm25()); weatherStation.setRadiation("0"); weatherStation.setRainfallAmount(weather.getWea()); weatherStation.setTemperature(weather.getTem()); weatherStation.setWindDirection(weather.getWin()); weatherStation.setWindPower(weather.getWin_meter()); weatherStation.setWindSpeed(weather.getWin_speed()); grain.setWeatherStation(JSONObject.toJSONString(weatherStation)); //封装好的数据 log.info("---粮情信息封装完成-开始执行推送"); reqData.setData(JSONObject.toJSONString(grain)); doPushGrain(reqData,grain); } private void doPushGrain(BaseReqData reqData,GrainData grainData) { GatewayDeviceReportService reportService = gatewayRemoteManager.getDeviceReportService(reqData.getDevice().getPushProtocol()); if (null == reportService) { log.error("------------粮情推送失败,系统不存在当前协议执行类----{}", reqData.getDevice().getDeviceName()); return; } reportService.reportGrainData(reqData); reqData.setData(reportService.grainData2GatewayApiInfoKafka(grainData,reqData.getDevice()).getData()); reportService.reportGrainDataByKafka(reqData); } private synchronized void add2GrainMap(GrainRoot grainRoot) { contextGrainRoot.put(grainRoot.getKey(), grainRoot); } private GrainRoot getGrainRoot(String key) { return contextGrainRoot.get(key); } private String buildGrainRootKey(String deviceSn, int num) { return deviceSn + "_" + num; } /** * 计算粮情温度 * 实际温度=密钥*密钥*37(溢出为无符号字节)再异或加密后的温度/2。 * 举例说明:第三个字节BB实际温度是5*5*37=039D取9D^(0xBB)=38/2=19; * * @param keyValue * @param tempHex * @return */ private double getGrainTemp(int keyValue, String tempHex) { int value = keyValue * keyValue * 37; String valueHex = BytesUtil.intToHexStr(value); valueHex = valueHex.substring(2); int num1 = BytesUtil.hexToInt(valueHex); int num2 = BytesUtil.hexToInt(tempHex); if((num1 ^ num2) / 2.0 > 35){ return -100.00; }else { return (num1 ^ num2) / 2.0; } } private void add2ThMap(String depotIdSys, THDto th) { String key = "TH_" + depotIdSys; contextMapTH.put(key, th); } private THDto getGrainTh(String depotIdSys) { String key = "TH_" + depotIdSys; return contextMapTH.get(key); } }