feat: 新增根据车辆滑窗配置和数据计算出数据趋势和波动并判断
parent
198aa471d7
commit
2dff0b986a
|
@ -16,6 +16,7 @@ import javax.annotation.Resource;
|
|||
import java.rmi.ServerException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* @ClassName AsVehicleEvent
|
||||
|
@ -38,11 +39,22 @@ public class IotDbController {
|
|||
*/
|
||||
@PostMapping("/api/device/insert")
|
||||
public ResponseData insert(@RequestBody VehicleParam vehicleParam) throws StatementExecutionException, ServerException, IoTDBConnectionException {
|
||||
String str1 ="{\"vin\":\"WZHFHDAIYUVKSHH3G\",\"drivingRoute\":\""+String.valueOf(new Date().getTime())+"\",\"longitude\":\"116.678005\",\"latitude\":\"39.547881\",\"mileage\":\"9287722.9\"}";
|
||||
String str2 ="{\"vin\":\"WZHFHDAIYUVKSHH3G\",\"drivingRoute\":\""+String.valueOf(new Date().getTime())+"\",\"longitude\":\"116.675176\",\"latitude\":\"39.547643\",\"mileage\":\"81565971.4\"}";
|
||||
Random random = new Random();
|
||||
ArrayList<JSONObject> jsonObjects = new ArrayList<>();
|
||||
jsonObjects.add(JSONObject.parseObject(str1));
|
||||
jsonObjects.add(JSONObject.parseObject(str2));
|
||||
for (int i = 0; i < 2; i++) {
|
||||
// 生成整数部分
|
||||
int integerPart = random.nextInt(900) + 100; // 生成100到999之间的整数
|
||||
// 生成小数部分
|
||||
double fractionPart = random.nextDouble() * 0.999999; // 生成0.000000, 0.999999之间的数
|
||||
double randomDoubleCorrected = integerPart + fractionPart;
|
||||
String str1 ="{\"vin\":\"WZHFHDAIYUVKSHH3G\",\"drivingRoute\":\""+ new Date().getTime() +"\",\"longitude\":\"116.678005\",\"latitude\":\""+randomDoubleCorrected+"\",\"mileage\":\"9287722.9\"}";
|
||||
jsonObjects.add(JSONObject.parseObject(str1));
|
||||
}
|
||||
|
||||
// String str2 ="{\"vin\":\"WZHFHDAIYUVKSHH3G\",\"drivingRoute\":\""+ (new Date().getTime()-2000) +"\",\"longitude\":\"116.675176\",\"latitude\":\"39.547643\",\"mileage\":\"81565971.4\"}";
|
||||
//
|
||||
// jsonObjects.add(JSONObject.parseObject(str1));
|
||||
// jsonObjects.add(JSONObject.parseObject(str2));
|
||||
iotDbServer.insertDatas("WZHFHDAIYUVKSHH3G",jsonObjects);
|
||||
return ResponseData.success();
|
||||
}
|
||||
|
|
|
@ -44,5 +44,5 @@ public class SlidingWindowInfo {
|
|||
/**
|
||||
* 指标值
|
||||
*/
|
||||
private Integer attributeValue;
|
||||
private Double attributeValue;
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ import java.util.Date;
|
|||
import java.util.List;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @ClassName SlidingWindowListener
|
||||
|
@ -47,9 +48,43 @@ public class SlidingWindowListener {
|
|||
// 将LocalDateTime转换为Instant,需要指定时区
|
||||
Instant instant = shiftedDateTime.atZone(ZoneId.systemDefault()).toInstant();
|
||||
try {
|
||||
VehicleParam vehicleParam = new VehicleParam(slidingWindowInfo.getVin(), slidingWindowInfo.getKeyCode(), "", "");
|
||||
VehicleParam vehicleParam = new VehicleParam(slidingWindowInfo.getVin(), slidingWindowInfo.getKeyCode(), String.valueOf(instant.toEpochMilli()),String.valueOf(new Date().getTime()));
|
||||
List<VehicleResult> vehicleResults = iotDbServer.queryDataFromIotDb(vehicleParam);
|
||||
log.info("车辆:{},查询:{}的数据:{}",slidingWindowInfo.getVin(),slidingWindowInfo.getKeyCode(),vehicleResults);
|
||||
List<Double> collect = vehicleResults.stream().map(vehicleResult -> Double.valueOf(vehicleResult.getData())).collect(Collectors.toList());
|
||||
double tendency = 0;
|
||||
for (int i = 0; i < collect.size(); i++) {
|
||||
if (i != 0){
|
||||
tendency += collect.get(i) - collect.get(i - 1);
|
||||
}
|
||||
}
|
||||
log.info("车辆:{}的{}趋势为:{}",slidingWindowInfo.getVin(),slidingWindowInfo.getKeyCode(),tendency);
|
||||
if (slidingWindowInfo.getAttributeType() == 1){
|
||||
if (tendency > slidingWindowInfo.getAttributeValue()){
|
||||
log.info("车辆:{}的{}属性趋势,超出上升指标",slidingWindowInfo.getVin(),slidingWindowInfo.getKeyCode());
|
||||
}
|
||||
log.info("车辆:{}的{}属性趋势,未超出上升指标",slidingWindowInfo.getVin(),slidingWindowInfo.getKeyCode());
|
||||
}
|
||||
if (slidingWindowInfo.getAttributeType() == 2){
|
||||
if (tendency < slidingWindowInfo.getAttributeValue()){
|
||||
log.info("车辆:{}的{}属性趋势,超出下降指标",slidingWindowInfo.getVin(),slidingWindowInfo.getKeyCode());
|
||||
}
|
||||
log.info("车辆:{}的{}属性趋势,未超出下降指标",slidingWindowInfo.getVin(),slidingWindowInfo.getKeyCode());
|
||||
}
|
||||
if (slidingWindowInfo.getAttributeType() == 3){
|
||||
//计算平均值
|
||||
double mean = calculatedMean(collect);
|
||||
//计算方差
|
||||
double variance = calculateVariance(collect, mean);
|
||||
//计算标准差
|
||||
double standardDeviation = Math.sqrt(variance);
|
||||
//判断波动率是否超过指标
|
||||
boolean isVolatilityExceeded = standardDeviation / mean > slidingWindowInfo.getAttributeValue() / 100;
|
||||
if (isVolatilityExceeded) {
|
||||
log.info("车辆:{}的{}属性趋势,超出波动指标",slidingWindowInfo.getVin(),slidingWindowInfo.getKeyCode());
|
||||
} else {
|
||||
log.info("车辆:{}的{}属性趋势,未超出波动指标",slidingWindowInfo.getVin(),slidingWindowInfo.getKeyCode());
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
@ -58,4 +93,22 @@ public class SlidingWindowListener {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
//计算平均值方法
|
||||
private static double calculatedMean(List<Double> dataList) {
|
||||
double sum = 0;
|
||||
for (double value : dataList) {
|
||||
sum += value;
|
||||
}
|
||||
return sum / dataList.size();
|
||||
}
|
||||
|
||||
//计算方差方法
|
||||
private static double calculateVariance(List<Double> dataList, double mean) {
|
||||
double sumOfSquares = 0;
|
||||
for (double value : dataList) {
|
||||
sumOfSquares += Math.pow(value - mean, 2);
|
||||
}
|
||||
return sumOfSquares / dataList.size();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -135,9 +135,9 @@ public class EventInfoServiceImpl implements EventInfoService {
|
|||
@Override
|
||||
public void slidingWindow() {
|
||||
ArrayList<SlidingWindowInfo> slidingWindowInfos = new ArrayList<>();
|
||||
slidingWindowInfos.add(new SlidingWindowInfo("vin1", 20, 10,"a",1,2));
|
||||
slidingWindowInfos.add(new SlidingWindowInfo("vin2", 15, 5,"b",2,3));
|
||||
slidingWindowInfos.add(new SlidingWindowInfo("vin3", 30, 15,"c",3,5));
|
||||
slidingWindowInfos.add(new SlidingWindowInfo("vin1", 20, 10,"a",1,2d));
|
||||
slidingWindowInfos.add(new SlidingWindowInfo("vin2", 15, 5,"b",2,3d));
|
||||
slidingWindowInfos.add(new SlidingWindowInfo("vin3", 30, 15,"c",3,5d));
|
||||
// 创建一个单线程的ScheduledExecutorService
|
||||
ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
|
||||
slidingWindowInfos.forEach(slidingWindowInfo -> {
|
||||
|
|
Loading…
Reference in New Issue