package com.moral.api.utils;
|
|
import com.moral.api.entity.Device;
|
import com.moral.api.entity.Sensor;
|
import com.moral.api.entity.UnitConversion;
|
import com.moral.api.entity.Version;
|
import com.moral.constant.RedisConstants;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.data.redis.core.RedisTemplate;
|
import org.springframework.stereotype.Component;
|
import org.springframework.util.ObjectUtils;
|
import javax.annotation.PostConstruct;
|
import javax.script.ScriptEngine;
|
import javax.script.ScriptEngineManager;
|
import javax.script.ScriptException;
|
import java.math.BigDecimal;
|
import java.util.ArrayList;
|
import java.util.List;
|
import java.util.Map;
|
|
/**
|
* @ClassName UnitConvertUtils
|
* @Description TODO
|
* @Author 陈凯裕
|
* @Date 2021/12/27 16:17
|
* @Version TODO
|
**/
|
@Component
|
public class UnitConvertUtils {
|
|
/*
|
* 小数点后保留位数
|
* */
|
public static Integer num = 3;
|
|
private static RedisTemplate redisTemplate;
|
|
private static List<UnitConversion> unitConversions;
|
|
private static Map<String,Device> devices;
|
|
@PostConstruct
|
public void init() {
|
UnitConvertUtils.unitConversions = redisTemplate.opsForList().range(RedisConstants.UNIT_CONVERSION, 0, -1);
|
devices = redisTemplate.opsForHash().entries(RedisConstants.DEVICE_INFO);
|
}
|
|
@Autowired
|
public void setRedisTemplate(RedisTemplate redisTemplate) {
|
this.redisTemplate = redisTemplate;
|
}
|
|
/**
|
* @Description: 转换数据单位到对应的显示单位
|
* @Param: [mac, data]
|
* @return: java.util.Map<java.lang.String , java.lang.Object>
|
* @Author: 陈凯裕
|
* @Date: 2021/12/27
|
*/
|
public static Map<String, Object> convertUnitToShowUnit(String mac, Map<String, Object> data) {
|
if (mac == null || data == null)
|
return null;
|
Device device = devices.get(mac);
|
//如果缓存中没有设备则刷新缓存
|
if(device==null){
|
devices = redisTemplate.opsForHash().entries(RedisConstants.DEVICE_INFO);
|
device = devices.get(mac);
|
if(device==null)
|
return null;
|
}
|
Version version = device.getVersion();
|
//型号中所有的因子
|
List<Sensor> sensors = version.getSensors();
|
//遍历型号中所有的因子,给数据做单位转换
|
for (Sensor sensor : sensors) {
|
String unitKey = sensor.getUnitKey();//原始单位
|
String showUnitKey = sensor.getShowUnitKey();//显示单位
|
//如果原始单位和显示单位不一致则进行单位转换
|
if (!unitKey.equals(showUnitKey)) {
|
Object valueObject = data.get(sensor.getCode());
|
//如果因子不存在则跳过本次循环,进行下一个因子处理
|
if (valueObject == null)
|
continue;
|
//获取计算公式
|
String formula = getFormula(sensor);
|
if (formula == null)
|
continue;
|
//获取对应因子数据
|
Double value = Double.valueOf(String.valueOf(valueObject));
|
//对数据转换格式
|
String valueStr = new BigDecimal(value).toString();
|
//用公式对原始数据进行转换
|
String calculateValue = calculate(valueStr, formula);
|
if(calculateValue==null)
|
continue;
|
value = Double.parseDouble(calculateValue);
|
data.put(sensor.getCode(),value);
|
} else
|
continue;
|
}
|
return data;
|
}
|
|
/**
|
* @Description: 获取单位转换的公式
|
* @Param: [sensor]
|
* @return: java.lang.String
|
* @Author: 陈凯裕
|
* @Date: 2021/12/28
|
*/
|
private static String getFormula(Sensor sensor) {
|
String formula = sensor.getFormula();
|
if (!ObjectUtils.isEmpty(formula))
|
return formula;
|
|
List<UnitConversion> tmpUnitConversions = new ArrayList<>();
|
for (UnitConversion unitConversion : unitConversions) {
|
if (unitConversion.getOriginalUnitKey().equals(sensor.getUnitKey()) && unitConversion.getTargetUnitKey().equals(sensor.getShowUnitKey()))
|
tmpUnitConversions.add(unitConversion);
|
}
|
//如果缓存没有则刷新程序内部缓存
|
if (tmpUnitConversions.size() == 0) {
|
refreshUnitConversionCache();
|
}
|
//重新查找公式
|
for (UnitConversion unitConversion : unitConversions) {
|
if (unitConversion.getOriginalUnitKey().equals(sensor.getUnitKey()) && unitConversion.getTargetUnitKey().equals(sensor.getShowUnitKey()))
|
tmpUnitConversions.add(unitConversion);
|
}
|
//如果没有则直接返回null
|
if (tmpUnitConversions.size() == 0)
|
return null;
|
//如果只有一个则是没有专用因子
|
if (unitConversions.size() == 1)
|
return unitConversions.get(0).getFormula();
|
//根据专用因子剔除
|
for (UnitConversion unitConversion : unitConversions) {
|
if (unitConversion.getSensorCode().equals(sensor.getCode()))
|
return unitConversion.getFormula();
|
}
|
return null;
|
}
|
|
/**
|
* @Description: 刷新公式内部缓存
|
* @Param: []
|
* @return: void
|
* @Author: 陈凯裕
|
* @Date: 2021/12/28
|
*/
|
private static void refreshUnitConversionCache() {
|
UnitConvertUtils.unitConversions = redisTemplate.opsForList().range(RedisConstants.UNIT_CONVERSION, 0, -1);
|
}
|
|
/**
|
* @Description: value为要转换的值,format为公式
|
* @Param: [value, format]
|
* @return: java.lang.Double
|
* @Author: 陈凯裕
|
* @Date: 2021/7/5
|
*/
|
public static String calculate(String value, String formula) {
|
if (ObjectUtils.isEmpty(formula))
|
return null;
|
ScriptEngine jse = new ScriptEngineManager().getEngineByName("JavaScript");
|
formula = formula.replaceAll("\\{0\\}", value);
|
Double result = null;
|
try {
|
result = (Double) jse.eval(formula);
|
} catch (ScriptException e) {
|
e.printStackTrace();
|
}
|
//保留小数点后三位
|
BigDecimal bg = new BigDecimal(result);
|
result = bg.setScale(num, BigDecimal.ROUND_HALF_UP).doubleValue();
|
return result.toString();
|
}
|
|
|
|
}
|