feat: 新增根据车辆滑窗配置和数据计算出数据趋势和波动并判断

master
yaoxin 2024-06-29 10:06:02 +08:00
parent 198aa471d7
commit 2dff0b986a
4 changed files with 75 additions and 10 deletions

View File

@ -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();
}

View File

@ -44,5 +44,5 @@ public class SlidingWindowInfo {
/**
*
*/
private Integer attributeValue;
private Double attributeValue;
}

View File

@ -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();
}
}

View File

@ -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 -> {