Преглед на файлове

风功率预测样本前端接口

xushili преди 2 години
родител
ревизия
31f73c5f99

+ 44 - 0
gyee-sample-impala/src/main/java/com/gyee/impala/common/util/DateUtil.java

@@ -343,6 +343,50 @@ public class DateUtil extends DateUtils {
         return str2DateTime(time,DATE_TIME_PATTERN);
     }
 
+    /**
+     * 去年同期
+     * @return
+     */
+    public static Date str2QntqDateTime(String time,String pattern) {
+
+        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
+        Date dateTime = null;
+        try {
+            dateTime = sdf.parse(time);
+        } catch (ParseException e) {
+            e.printStackTrace();
+
+        }
+        Calendar calendar = Calendar.getInstance();
+        calendar.setTime(dateTime);
+        calendar.add(Calendar.YEAR,-1);
+        return calendar.getTime();
+    }
+
+    /**
+     * 去年同期
+     */
+    public static Date str2QntqDateTime(String time) {
+        return str2QntqDateTime(time,DATE_TIME_PATTERN);
+    }
+    /**
+     * 加一年
+     */
+    public static Date dateTimeAddYear(Date date) {
+        Calendar instance = Calendar.getInstance();
+        instance.setTime(date);
+        instance.add(Calendar.YEAR,1);
+        return instance.getTime();
+    }
+
+    public static String datetime2Str(Date time,String pattern) {
+        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
+        return sdf.format(time);
+    }
+    public static String datetime2Str(Date time) {
+        return datetime2Str(time,DATE_TIME_PATTERN);
+    }
+
     public static double hoursDiff1(Date d1, Date d2) {
         return Math.floor(Math.abs((d1.getTime() - d2.getTime())) / (double) (60 * 60 * 1000));
     }

+ 15 - 4
gyee-sample-impala/src/main/java/com/gyee/impala/controller/diagnose/WindspeedforecastshorttermController.java

@@ -2,12 +2,11 @@ package com.gyee.impala.controller.diagnose;
 
 import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
-import com.baomidou.mybatisplus.core.metadata.IPage;
-import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.gyee.impala.common.result.JsonResult;
 import com.gyee.impala.common.result.ResultCode;
 import com.gyee.impala.model.master.Windspeedforecastshortterm;
 import com.gyee.impala.service.master.IWindspeedforecastshorttermService;
+import com.gyee.impala.service.master.IWindspeedforecastspshorttermService;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
@@ -24,12 +23,14 @@ import java.util.List;
  */
 @CrossOrigin
 @RestController
-@RequestMapping("/windspeedforecast/shortterm")
+@RequestMapping("/windspeedforecast")
 public class WindspeedforecastshorttermController {
     @Autowired
     private IWindspeedforecastshorttermService windspeedforecastshorttermService;
+    @Autowired
+    private IWindspeedforecastspshorttermService windspeedforecastspshorttermService;
 
-    @GetMapping("/list")
+    @GetMapping("/shortterm/list")
     public JSONObject getList(@RequestParam(value = "pagenum", required = false) Integer pagenum,
                               @RequestParam(value = "pagesize", required = false) Integer pagesize,
                               @RequestParam(value = "forecasttype", required = false) String forecasttype,
@@ -49,4 +50,14 @@ public class WindspeedforecastshorttermController {
         List<Windspeedforecastshortterm> list = windspeedforecastshorttermService.list(wrapper);
         return JsonResult.successData(ResultCode.SUCCESS, list);
     }
+
+    @GetMapping("/contrast")
+    public JSONObject getPowerContrast(@RequestParam("stationid") String stationid,
+                             @RequestParam("starttime") String starttime,
+                             @RequestParam("endtime") String endtime,
+                             @RequestParam(value = "timescale", required = false) Integer timescale
+                             ){
+        if(timescale==null) timescale = 0;
+        return windspeedforecastshorttermService.getContrast(stationid,starttime,endtime,timescale);
+    }
 }

+ 2 - 1
gyee-sample-impala/src/main/java/com/gyee/impala/model/master/Weatherforecast.java

@@ -18,7 +18,7 @@ public class Weatherforecast extends Model<Weatherforecast> implements ToData<Ob
     private String id;
     private String stationen;
     private String stationcn;
-    private int filetime;
+    private Integer filetime;
     private String time;
     private Double speed;
     private Double temperature;
@@ -27,6 +27,7 @@ public class Weatherforecast extends Model<Weatherforecast> implements ToData<Ob
     private Double pressure;
     private String remark;
     private String category;
+    private Double speedactual;
 
     @Override
     protected Serializable pkVal() {

+ 95 - 0
gyee-sample-impala/src/main/java/com/gyee/impala/model/master/WindspeedforecastContrast.java

@@ -0,0 +1,95 @@
+package com.gyee.impala.model.master;
+
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+
+@Data
+public class WindspeedforecastContrast implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    private Date calctime;
+
+    private String stationid;
+
+    private Float actualpower;
+
+    private Float actualwindspeed;
+
+    private Float forecastwindspeed;
+
+    private Float forecastwindspeedsp;
+    /**
+     * 实际风速去年同期
+     */
+    private Float actualwindspeedtq;
+    /**
+     * 预测风速去年同期短期
+     */
+    private Float forecastwindspeedtq;
+    /**
+     * 预测风速去年同期超短期
+     */
+    private Float forecastwindspeedsptq;
+
+    private Float forecastpower;
+
+    private Float forecastpowersp;
+    /**
+     * 实际功率去年同期
+     */
+    private Float actualpowertq;
+    /**
+     * 预测功率去年同期短期
+     */
+    private Float forecastpowertq;
+    /**
+     * 预测功率去年同期超短期
+     */
+    private Float forecastpowersptq;
+
+
+    private String actualpowerRate;
+
+    private String forecastpowerRate;
+
+    private String forecastpowerspRate;
+
+    private String actualwindspeedRate;
+
+    private String forecastwindspeedRate;
+
+    private String forecastwindspeedspRate;
+
+    public String getActualpowerRate() {
+        if (actualpowertq == null || actualpower == null || actualpower.equals(0.0f)) return null;
+        return String.format("%.2f", actualpowertq / actualpower) + "%";
+    }
+
+    public String getForecastpowerRate() {
+        if (forecastpowertq == null || forecastpower == null || forecastpower.equals(0.0f)) return null;
+        return String.format("%.2f", forecastpowertq / forecastpower) + "%";
+    }
+
+    public String getForecastpowerspRate() {
+        if (forecastpowersptq == null || forecastpowersp == null || forecastpowersp.equals(0.0f)) return null;
+        return String.format("%.2f", forecastpowersptq / forecastpowersp) + "%";
+    }
+
+    public String getActualwindspeedRate() {
+        if (actualwindspeedtq == null || actualwindspeed == null || actualwindspeed.equals(0.0f)) return null;
+        return String.format("%.2f", actualwindspeedtq / actualwindspeed) + "%";
+    }
+
+    public String getForecastwindspeedRate() {
+        if (forecastwindspeedtq == null || forecastwindspeed == null || forecastwindspeed.equals(0.0f)) return null;
+        return String.format("%.2f", forecastwindspeedtq / forecastwindspeed) + "%";
+    }
+
+    public String getForecastwindspeedspRate() {
+        if (forecastwindspeedsptq == null || forecastwindspeedsp == null || forecastwindspeedsp.equals(0.0f)) return null;
+        return String.format("%.2f", forecastwindspeedsptq / forecastwindspeedsp) + "%";
+    }
+}

+ 48 - 4
gyee-sample-impala/src/main/java/com/gyee/impala/schdule/TaskWeather.java

@@ -1,8 +1,11 @@
 package com.gyee.impala.schdule;
 
 
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.gyee.impala.common.util.DateUtil;
+import com.gyee.impala.mapper.decision.WfStatPeriodDataMapper;
 import com.gyee.impala.model.decision.WfNwpData;
+import com.gyee.impala.model.decision.WfStatPeriodData;
 import com.gyee.impala.model.master.Weatherforecast;
 import com.gyee.impala.service.decision.WfNwpDataService;
 import com.gyee.impala.service.master.WeatherforecastService;
@@ -10,10 +13,10 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.stereotype.Component;
 
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import javax.annotation.Resource;
+import java.util.*;
+import java.util.function.Function;
+import java.util.stream.Collectors;
 
 /**
  * 来自功率预测的天气数据同步至kudu样本库
@@ -26,6 +29,8 @@ public class TaskWeather {
     private WfNwpDataService nwpDataService;
     @Autowired
     private WeatherforecastService forecastService;
+    @Resource
+    private WfStatPeriodDataMapper wfStatPeriodDataMapper;
 
     private static Map<Integer, String> MAP_STATION = new HashMap<>();
 
@@ -58,4 +63,43 @@ public class TaskWeather {
             forecastService.insertBatch(list);
         });
     }
+
+    /**
+     * 天气样本库加入实际风速
+     */
+    @Scheduled(cron = "0 15 1 * * ?")
+    public void weatherAddActualspeedTask(){
+        QueryWrapper<Weatherforecast> wrapper1 = new QueryWrapper<>();
+        wrapper1.between("time",DateUtil.getPreviousDate(26),new Date());
+        List<Weatherforecast> weatherforecasts = forecastService.list(wrapper1);
+        //场站、样本库
+        Map<String, List<Weatherforecast>> weatherforecastCollect = weatherforecasts.stream().collect(Collectors.groupingBy(Weatherforecast::getStationen));
+
+        QueryWrapper<WfStatPeriodData> wrapper = new QueryWrapper();
+        wrapper.between("DATA_TIME", DateUtil.str2DateTime(DateUtil.getPreviousDate(26)), new Date())
+                .lt("WINDPLANT_NO",6);
+        //从网源获取实际风速
+        List<WfStatPeriodData> wfStatPeriodDatas = wfStatPeriodDataMapper.selectList(wrapper);
+        //场站、风速
+        Map<Short, List<WfStatPeriodData>> wfStatPeriodDataCollect = wfStatPeriodDatas.stream().collect(Collectors.groupingBy(WfStatPeriodData::getWindplantNo));
+
+        List<Weatherforecast> weatherforecastBigList = new ArrayList<>();
+        for (Short i = 1; i <6; i++) {
+            List<WfStatPeriodData> wfStatPeriodDataList = wfStatPeriodDataCollect.get(i);
+            List<Weatherforecast> weatherforecastList = weatherforecastCollect.get(MAP_STATION.get(i.intValue()));
+            //时间、样本库
+            Map<String, Weatherforecast> weatherforecastMap = weatherforecastList.stream().collect(Collectors.toMap(Weatherforecast::getTime, Function.identity(),(key1,key2)->key2));
+
+            for (WfStatPeriodData wspds : wfStatPeriodDataList) {
+                String s = DateUtil.datetime2Str(wspds.getDataTime());
+                Weatherforecast weatherforecast = weatherforecastMap.get(s);
+                if(weatherforecast==null) continue;
+                Weatherforecast wf = new Weatherforecast();
+                wf.setId(weatherforecast.getId());
+                wf.setSpeedactual(Double.valueOf(String.valueOf(wspds.getAvgWindSpeed())));
+                weatherforecastBigList.add(wf);
+            }
+        }
+        forecastService.updateBatchById(weatherforecastBigList, 300);
+    }
 }

+ 4 - 5
gyee-sample-impala/src/main/java/com/gyee/impala/service/custom/diagnose/FaultRefreshService.java

@@ -3,7 +3,6 @@ package com.gyee.impala.service.custom.diagnose;
 
 import com.gyee.impala.common.cache.InfoCache;
 import com.gyee.impala.common.feign.RemoteServiceBuilder;
-import com.gyee.impala.common.util.DateUtil;
 import com.gyee.impala.model.custom.diagnose.FaultInfo;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.boot.ApplicationArguments;
@@ -14,7 +13,10 @@ import org.springframework.stereotype.Component;
 
 import javax.annotation.Resource;
 import java.text.SimpleDateFormat;
-import java.util.*;
+import java.util.Calendar;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
 import java.util.function.Function;
 import java.util.stream.Collectors;
 
@@ -90,7 +92,4 @@ public class FaultRefreshService implements ApplicationRunner {
             }
         }
     }
-
-    public static void main(String[] args) {
-    }
 }

+ 27 - 10
gyee-sample-impala/src/main/java/com/gyee/impala/service/impl/master/CasefaultalgServiceImpl.java

@@ -51,15 +51,21 @@ public class CasefaultalgServiceImpl extends ServiceImpl<CasefaultalgMapper, Cas
     @Autowired
     private RemoteServiceBuilder remoteServiceBuilder;
 
+    private Map<String, Windturbinetestingpointai2> aiMap;
+    private Map<String, String> hjwd;
+
     /**
      * 获取所有风机风速测点
      */
     @Cacheable("aisAI022")
     public Map<String, Windturbinetestingpointai2> getWindpointai2s() {
-        Map<String, Object> wrapper = new HashMap<>();
+        if(aiMap==null){
+            Map<String, Object> wrapper = new HashMap<>();
             wrapper.put("uniformcode", "AI022");
-        List<Windturbinetestingpointai2> ai2s = windturbinetestingpointai2Mapper.selectByMap(wrapper);
-        return ai2s.stream().collect(Collectors.toMap(Windturbinetestingpointai2::getWindturbineid, Function.identity()));
+            List<Windturbinetestingpointai2> ai2s = windturbinetestingpointai2Mapper.selectByMap(wrapper);
+            aiMap = ai2s.stream().collect(Collectors.toMap(Windturbinetestingpointai2::getWindturbineid, Function.identity()));
+        }
+        return aiMap;
     }
 
     /**
@@ -67,8 +73,12 @@ public class CasefaultalgServiceImpl extends ServiceImpl<CasefaultalgMapper, Cas
      */
     @Cacheable("aishjwd")
     public Map<String, String> gethjwd() {
-        List<Temperatureinfo> temperature = windturbinetestingpointai2Mapper.getTemperature();
-        return temperature.stream().collect(Collectors.toMap(Temperatureinfo::getWindturbineid, Temperatureinfo::getTag));
+        if(hjwd==null){
+            List<Temperatureinfo> temperature = windturbinetestingpointai2Mapper.getTemperature();
+            hjwd = temperature.stream().filter(tr -> tr.getTag() != null).
+                    collect(Collectors.toMap(Temperatureinfo::getWindturbineid, Temperatureinfo::getTag));
+        }
+        return hjwd;
     }
 
     @Override
@@ -90,11 +100,18 @@ public class CasefaultalgServiceImpl extends ServiceImpl<CasefaultalgMapper, Cas
         try{
             for (Casefaultalg casefaultalg : list) {
                 Map<String,TsDoubleData> historySection = remoteServiceBuilder.adapter().getHistorySection(windpointai2s.get(casefaultalg.getWindturbineid()).getId(), DateUtil.str2DateTime(casefaultalg.getStarttime()).getTime());
-                TsDoubleData value = historySection.entrySet().iterator().next().getValue();
-                Map<String,TsDoubleData> historySectionHjwd = remoteServiceBuilder.adapter().getHistorySection(gethjwd().get(casefaultalg.getWindturbineid()), DateUtil.str2DateTime(casefaultalg.getStarttime()).getTime());
-                TsDoubleData valueHjwd = historySectionHjwd.entrySet().iterator().next().getValue();
-                casefaultalg.setSpeed(value.getDoubleValue());
-                casefaultalg.setTemperature((float) valueHjwd.getDoubleValue());
+                String s = gethjwd().get(casefaultalg.getWindturbineid());
+                if(s!=null) {
+                    Map<String,TsDoubleData> historySectionHjwd = remoteServiceBuilder.adapter().getHistorySection(s, DateUtil.str2DateTime(casefaultalg.getStarttime()).getTime());
+                    if(historySectionHjwd!=null){
+                        TsDoubleData valueHjwd = historySectionHjwd.entrySet().iterator().next().getValue();
+                        casefaultalg.setTemperature(valueHjwd.getDoubleValue());
+                    }
+                }
+                if(historySection!=null) {
+                    TsDoubleData value = historySection.entrySet().iterator().next().getValue();
+                    casefaultalg.setSpeed(value.getDoubleValue());
+                }
             }
             insert(list);
         } catch (Exception e) {

+ 93 - 1
gyee-sample-impala/src/main/java/com/gyee/impala/service/impl/master/WindspeedforecastshorttermServiceImpl.java

@@ -1,20 +1,33 @@
 package com.gyee.impala.service.impl.master;
 
+import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.gyee.impala.common.config.datasource.KuduDataSourceConfig;
+import com.gyee.impala.common.result.JsonResult;
+import com.gyee.impala.common.result.ResultCode;
+import com.gyee.impala.common.util.DateUtil;
 import com.gyee.impala.common.util.SnowFlakeUtil;
 import com.gyee.impala.mapper.master.WindspeedforecastshorttermMapper;
-import com.gyee.impala.model.master.Casewarningcustom;
+import com.gyee.impala.mapper.master.WindspeedforecastspshorttermMapper;
+import com.gyee.impala.model.master.WindspeedforecastContrast;
 import com.gyee.impala.model.master.Windspeedforecastshortterm;
+import com.gyee.impala.model.master.Windspeedforecastspshortterm;
 import com.gyee.impala.service.master.IWindspeedforecastshorttermService;
 import org.apache.kudu.client.*;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cache.annotation.Cacheable;
 import org.springframework.stereotype.Service;
 
+import javax.annotation.Resource;
+import java.util.ArrayList;
+import java.util.Date;
 import java.util.List;
+import java.util.Map;
+import java.util.function.Function;
+import java.util.stream.Collectors;
 
 /**
  * <p>
@@ -28,6 +41,9 @@ import java.util.List;
 public class WindspeedforecastshorttermServiceImpl extends ServiceImpl<WindspeedforecastshorttermMapper, Windspeedforecastshortterm> implements IWindspeedforecastshorttermService {
     @Autowired
     private KuduDataSourceConfig kuduConfig;
+    @Resource
+    private WindspeedforecastspshorttermMapper windspeedforecastspshorttermMapper;
+
     /**
      * 由于mybatis-plus存储的中文乱码
      * 采用原生写法
@@ -80,4 +96,80 @@ public class WindspeedforecastshorttermServiceImpl extends ServiceImpl<Windspeed
         Page<Windspeedforecastshortterm> windspeedforecastshorttermPage = baseMapper.selectPage(page, wrapper);
         return windspeedforecastshorttermPage;
     }
+
+    @Override
+    @Cacheable("windspeedforecastcontrast")
+    public JSONObject getContrast(String stationid, String starttime, String endtime, int timescale) {
+        if(stationid.isEmpty()||starttime.isEmpty()||endtime.isEmpty()){
+            return JsonResult.error(ResultCode.PARAM_IS_BLANK);
+        }
+        Date dateStart = DateUtil.str2DateTime(starttime);
+        Date dateEnd = DateUtil.str2DateTime(endtime);
+        Date dateStartQntq = DateUtil.str2QntqDateTime(starttime);
+        Date dateEndQntq = DateUtil.str2QntqDateTime(endtime);
+
+        //list1短期 list2超短期 list3去年同期短期 list4去年同期超短期
+        List<Windspeedforecastshortterm> list1 = getShortterm(stationid,dateStart,dateEnd);
+        List<Windspeedforecastspshortterm> list2 = getSpShortterm(stationid,dateStart,dateEnd,timescale);
+        List<Windspeedforecastshortterm> list3 = getShortterm(stationid,dateStartQntq,dateEndQntq);
+        List<Windspeedforecastspshortterm> list4 = getSpShortterm(stationid,dateStartQntq,dateEndQntq,timescale);
+        List<WindspeedforecastContrast> windspeedforecastContrasts = new ArrayList<>();
+        list1.forEach(l->{
+            WindspeedforecastContrast wsfcc = new WindspeedforecastContrast();
+            wsfcc.setCalctime(l.getCalctime());
+            wsfcc.setActualpower(l.getActualpower());
+            wsfcc.setActualwindspeed(l.getActualwindspeed());
+            wsfcc.setForecastpower(l.getForecastpower());
+            wsfcc.setForecastwindspeed(l.getForecastwindspeed());
+            windspeedforecastContrasts.add(wsfcc);
+        });
+        Map<Date, WindspeedforecastContrast> contrastMap = windspeedforecastContrasts.stream().collect(Collectors.toMap(WindspeedforecastContrast::getCalctime, Function.identity()));
+        /*Map<Date, WindspeedforecastContrast> contrastMap = new HashMap<>();
+        for (WindspeedforecastContrast wsfcc : windspeedforecastContrasts) {
+            contrastMap.put(wsfcc.getCalctime(), wsfcc);
+        }*/
+        list2.forEach(l-> {
+            WindspeedforecastContrast wsfcc = contrastMap.get(l.getCalctime());
+            wsfcc.setForecastpowersp(l.getForecastpower());
+            wsfcc.setForecastwindspeedsp(l.getForecastwindspeed());
+        });
+        //给年份加一年,然后匹配
+        list3.forEach(l-> {
+            WindspeedforecastContrast wsfcc = contrastMap.get(DateUtil.dateTimeAddYear(l.getCalctime()));
+            wsfcc.setActualpowertq(l.getActualpower());
+            wsfcc.setForecastpowertq(l.getForecastpower());
+            wsfcc.setActualwindspeedtq(l.getActualwindspeed());
+            wsfcc.setForecastwindspeedtq(l.getForecastwindspeed());
+        });
+        list4.forEach(l-> {
+            WindspeedforecastContrast wsfcc = contrastMap.get(DateUtil.dateTimeAddYear(l.getCalctime()));
+            wsfcc.setForecastpowersptq(l.getForecastpower());
+            wsfcc.setForecastwindspeedsptq(l.getForecastwindspeed());
+        });
+
+        return JsonResult.successData(ResultCode.SUCCESS,windspeedforecastContrasts);
+    }
+
+    /**
+     * 短期功率
+     */
+    private List<Windspeedforecastshortterm> getShortterm(String stationid, Date dateStart, Date dateEnd) {
+        QueryWrapper<Windspeedforecastshortterm> wrapper = new QueryWrapper<>();
+        wrapper.eq("stationid", stationid)
+                .eq("algorithmmodel","风电_极限学习机_功率_中国大陆")
+                .between("calctime", dateStart, dateEnd);
+        return baseMapper.selectList(wrapper);
+    }
+
+    /**
+     * 超短期功率
+     */
+    private List<Windspeedforecastspshortterm> getSpShortterm(String stationid, Date dateStart, Date dateEnd,int timescale) {
+        QueryWrapper<Windspeedforecastspshortterm> wrapper = new QueryWrapper<>();
+        wrapper.eq("stationid", stationid)
+                .between("calctime", dateStart, dateEnd)
+                .eq("forecasttime", timescale);
+        return windspeedforecastspshorttermMapper.selectList(wrapper);
+    }
+
 }

+ 3 - 0
gyee-sample-impala/src/main/java/com/gyee/impala/service/master/IWindspeedforecastshorttermService.java

@@ -1,5 +1,6 @@
 package com.gyee.impala.service.master;
 
+import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@@ -21,4 +22,6 @@ public interface IWindspeedforecastshorttermService extends IService<Windspeedfo
     void insertBatch(List<Windspeedforecastshortterm> list) throws KuduException;
 
     IPage<Windspeedforecastshortterm> list(Page<Windspeedforecastshortterm> page, QueryWrapper<Windspeedforecastshortterm> wrapper);
+
+    JSONObject getContrast(String stationid, String starttime, String endtime, int timescale);
 }