dengzedong
2024-12-24 76743b009ca5ea67557fcab597b332f8d1947813
提交 | 用户 | 时间
a6de49 1 package com.iailab.module.data.point.collection.handler;
H 2
781e72 3 import com.iailab.module.data.common.enums.CommonConstant;
a6de49 4 import com.iailab.module.data.common.enums.DataTypeEnum;
H 5 import com.iailab.module.data.common.enums.JsErrorCode;
6 import com.iailab.module.data.common.utils.JavaScriptHandler;
781e72 7 import com.iailab.module.data.point.collection.PointCollector;
a6de49 8 import com.iailab.module.data.point.collection.utils.GenInfluxPointValueUtils;
H 9 import com.iailab.module.data.point.dto.DaPointDTO;
10 import com.iailab.module.data.point.service.DaPointService;
11 import com.iailab.module.data.influxdb.pojo.InfluxPointValuePOJO;
12 import lombok.extern.slf4j.Slf4j;
13 import org.apache.commons.lang3.StringUtils;
14 import javax.annotation.Resource;
781e72 15
16 import org.springframework.beans.factory.annotation.Autowired;
17 import org.springframework.data.redis.core.RedisTemplate;
a6de49 18 import org.springframework.stereotype.Component;
H 19 import org.springframework.util.CollectionUtils;
20
21 import java.math.BigDecimal;
22 import java.util.*;
23
24 /**
25  * 计算点处理
26  *
27  * @author PanZhibao
28  * @Description
29  * @createTime 2023年05月03日 17:40:00
30  */
31 @Slf4j
32 @Component
33 public class CalculateHandle {
34
35     @Resource
36     private DaPointService daPointService;
37
38     @Resource
39     private MeasureHandle measureHandle;
40
41     @Resource
42     private ConstantHandle constantHandle;
43
44     @Resource
45     private JavaScriptHandler javaScriptHandler;
781e72 46
47     @Autowired
48     private RedisTemplate<String, Object> redisTemplate;
a6de49 49
d41f14 50     public static final String regex = "[+\\-\\*/()\\&\\|\\>\\<]";
a6de49 51
H 52     public List<InfluxPointValuePOJO> handle(Date collectTime, List<DaPointDTO> dtos, Map<String, Object> dataMap) {
53         List<InfluxPointValuePOJO> result = new ArrayList<>();
54         try {
55             log.info("计算点处理开始");
56             if (CollectionUtils.isEmpty(dtos)) {
57                 return result;
58             }
59             dtos.forEach(dto -> {
60                 try {
61                     Object value = singleCompute(dto, dataMap);
62                     InfluxPointValuePOJO pojo = GenInfluxPointValueUtils.getByPoint(dto, value);
63                     pojo.setTimestamp(collectTime.toInstant());
64                     result.add(pojo);
65                 } catch (Exception ex) {
66                     ex.printStackTrace();
67                     log.info("计算点异常!PointNo=" + dto.getPointNo());
68                 }
69             });
70             log.info("计算点处理结束");
71
72         } catch (Exception ex) {
73             ex.printStackTrace();
74             log.info("计算点处理异常!");
75         }
76         return result;
77     }
78
79     private Object singleCompute(DaPointDTO dto, Map<String, Object> dataMap) {
80         String expression = dto.getExpression();
81         String[] arr = expression.split(regex);
82
83         for (int i = 0; i < arr.length; i++) {
84             String s = arr[i];
85             if (StringUtils.isNotBlank(s) && dataMap.containsKey(s)) {
86                 expression = expression.replace(s, dataMap.get(s).toString());
87             }
88         }
89         expression = expression.replace("&", "&&");
90         expression = expression.replace("|", "||");
91         expression = expression.replace("False", "false");
92         expression = expression.replace("True", "true");
93         log.info("PointNo=" + dto.getPointNo() + ";expression=" + expression);
94         String result = javaScriptHandler.eval(expression);
95         log.info("result=" + result);
96         if (result == null) {
781e72 97             return CommonConstant.BAD_VALUE;
a6de49 98         } else if (result.contains(JsErrorCode.Infinity.name()) ||
H 99                 result.contains(JsErrorCode.NaN.name())) {
100             log.info("计算异常,使用默认值");
101             return dto.getDefaultValue() == null ? BigDecimal.ZERO : dto.getDefaultValue();
102         } else {
103             if (DataTypeEnum.INT.getCode().equals(dto.getDataType())) {
104                 return new BigDecimal(result).intValue();
105             } else if (DataTypeEnum.FLOAT.getCode().equals(dto.getDataType())) {
781e72 106                 return new BigDecimal(result).setScale(4, BigDecimal.ROUND_UP).doubleValue();
a6de49 107             } else if (DataTypeEnum.BOOLEAN.getCode().equals(dto.getDataType())) {
H 108                 return Boolean.parseBoolean(result);
109             }
110         }
111         return result;
112     }
113
114     public Map<String, Object> getCurrent(List<String> pointNos) {
115         Map<String, Object> data = new HashMap<>();
116         List<DaPointDTO> pointMathList = daPointService.getMathPoint(pointNos);
117         if (CollectionUtils.isEmpty(pointMathList)) {
118             return data;
119         }
120         pointMathList.forEach(item -> {
781e72 121             Object value = CommonConstant.BAD_VALUE;
122             if (redisTemplate.hasKey(PointCollector.PV + item.getPointNo())) {
123                 value = redisTemplate.opsForValue().get(PointCollector.PV + item.getPointNo());
124             } else {
125                 value = singleCompute(item);
126             }
127             data.put(item.getPointNo(), value);
a6de49 128         });
H 129         return data;
130     }
131
132     private Object singleCompute(DaPointDTO dto) {
781e72 133         String result = CommonConstant.BAD_VALUE.toString();
a6de49 134         Map<String, Object> dataMap = new HashMap<>();
H 135         String expression = dto.getExpression();
136         String[] arr = expression.split(regex);
137         for (int i = 0; i < arr.length; i++) {
138             String s = arr[i];
139             if (StringUtils.isBlank(s)) {
140                 continue;
141             }
142             List<String> pointNos = new ArrayList<>();
143             pointNos.add(s);
144             dataMap.putAll(measureHandle.getCurrent(pointNos));
145             dataMap.putAll(constantHandle.getCurrent(pointNos));
146             expression = expression.replace(s, dataMap.get(s).toString());
147         }
148         expression = expression.replace("&", "&&");
149         expression = expression.replace("|", "||");
150         expression = expression.replace("False", "false");
151         expression = expression.replace("True", "true");
152         log.info("PointNo=" + dto.getPointNo() + ";expression=" + expression);
781e72 153         result = javaScriptHandler.eval(expression);
a6de49 154         log.info("result=" + result);
H 155         if (result == null) {
781e72 156             return CommonConstant.BAD_VALUE;
157         } else if (result.contains(JsErrorCode.Infinity.name()) || result.contains(JsErrorCode.NaN.name())) {
a6de49 158             log.info("计算异常,使用默认值");
H 159             return dto.getDefaultValue() == null ? BigDecimal.ZERO : dto.getDefaultValue();
160         } else {
161             if (DataTypeEnum.INT.getCode().equals(dto.getDataType())) {
162                 return new BigDecimal(result).intValue();
163             } else if (DataTypeEnum.FLOAT.getCode().equals(dto.getDataType())) {
781e72 164                 return new BigDecimal(result).setScale(2, BigDecimal.ROUND_UP).doubleValue();
a6de49 165             } else if (DataTypeEnum.BOOLEAN.getCode().equals(dto.getDataType())) {
H 166                 return Boolean.parseBoolean(result);
167             }
168         }
169         return result;
170     }
171 }