From fc4080bf410aa49a06566fce96057cd433025af7 Mon Sep 17 00:00:00 2001 From: hongawen <83944980@qq.com> Date: Tue, 10 Oct 2023 17:42:16 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B5=8B=E8=AF=95=E8=A7=A3=E6=9E=90=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E5=85=A5influx=E5=BA=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 7 + .../njcn/jbsyncdata/enums/MeasTypeEnum.java | 72 +++ .../njcn/jbsyncdata/imapper/DataVMapper.java | 22 + .../com/njcn/jbsyncdata/pojo/po/DataV.java | 235 ++++++++++ .../pojo/result/CommonTelemetry.java | 38 ++ .../jbsyncdata/pojo/result/DataResult.java | 10 - .../jbsyncdata/pojo/result/GeneralResult.java | 15 + .../jbsyncdata/pojo/result/PageResult.java | 24 + .../pojo/result/StatisticsData.java | 18 + .../service/impl/BusinessServiceImpl.java | 100 +++- .../util/InstantDateDeserializer.java | 38 ++ .../util/InstantDateSerializer.java | 48 ++ .../com/njcn/jbsyncdata/util/PubUtils.java | 443 ++++++++++++++++++ src/main/resources/application.yml | 6 + .../JbSyncdataApplicationTests.java | 115 ++++- 15 files changed, 1166 insertions(+), 25 deletions(-) create mode 100644 src/main/java/com/njcn/jbsyncdata/enums/MeasTypeEnum.java create mode 100644 src/main/java/com/njcn/jbsyncdata/imapper/DataVMapper.java create mode 100644 src/main/java/com/njcn/jbsyncdata/pojo/po/DataV.java create mode 100644 src/main/java/com/njcn/jbsyncdata/pojo/result/CommonTelemetry.java delete mode 100644 src/main/java/com/njcn/jbsyncdata/pojo/result/DataResult.java create mode 100644 src/main/java/com/njcn/jbsyncdata/pojo/result/GeneralResult.java create mode 100644 src/main/java/com/njcn/jbsyncdata/pojo/result/PageResult.java create mode 100644 src/main/java/com/njcn/jbsyncdata/pojo/result/StatisticsData.java create mode 100644 src/main/java/com/njcn/jbsyncdata/util/InstantDateDeserializer.java create mode 100644 src/main/java/com/njcn/jbsyncdata/util/InstantDateSerializer.java create mode 100644 src/main/java/com/njcn/jbsyncdata/util/PubUtils.java diff --git a/pom.xml b/pom.xml index 9516f6e..818e382 100644 --- a/pom.xml +++ b/pom.xml @@ -46,6 +46,7 @@ 8 2.8.0 5.7.9 + 2.22 @@ -167,6 +168,12 @@ 2.0.7 + + com.njcn + influxdb-springboot-starter + 1.0.0 + + diff --git a/src/main/java/com/njcn/jbsyncdata/enums/MeasTypeEnum.java b/src/main/java/com/njcn/jbsyncdata/enums/MeasTypeEnum.java new file mode 100644 index 0000000..e02b7c7 --- /dev/null +++ b/src/main/java/com/njcn/jbsyncdata/enums/MeasTypeEnum.java @@ -0,0 +1,72 @@ +package com.njcn.jbsyncdata.enums; + +import lombok.Getter; + +import java.util.ArrayList; +import java.util.List; + +@Getter +public enum MeasTypeEnum { + + A_PHSA("A_phsA", "A相电流", "A","data_i","rms"), + + A_PHSB("A_phsB", "B相电流", "B","data_i","rms"), + + A_PHSC("A_phsC", "C相电流", "C","data_i","rms"), + + PHV_PHSA("PhV_phsA", "A相电压", "A","data_v","rms"), + + PHV_PHSB("PhV_phsB", "B相电压", "B","data_v","rms"), + + PHV_PHSC("PhV_phsC", "C相电压", "C","data_v","rms"), + + TOTW("TotW", "有功", "T","data_harmpower_p","p"), + + TOTVAR("TotVar", "无功", "T","data_harmpower_q","q"); + + //冀北指标名称 + private final String measType; + //中文名 + private final String cnName; + //相别 + private final String phaseType; + //表名 + private final String tableName; + //字段名 + private final String fieldName; + + MeasTypeEnum(String measType, String cnName, String phaseType, String tableName,String fieldName) { + this.measType = measType; + this.cnName = cnName; + this.phaseType = phaseType; + this.tableName = tableName; + this.fieldName = fieldName; + } + + + /** + * 根据指标获取当前指标的信息 + * @param measType 指标名称 + */ + public static MeasTypeEnum getMeasTypeEnumByMeasType(String measType) { + for (MeasTypeEnum item : values()) { + if (item.getMeasType().equals(measType)) { + return item; + } + } + return null; + } + + + /** + * 获取所有指标类型名称集合 + */ + public static List getMeasList() { + List measLiST = new ArrayList<>(); + for (MeasTypeEnum temp : values()) { + String type = temp.getMeasType(); + measLiST.add(type); + } + return measLiST; + } +} diff --git a/src/main/java/com/njcn/jbsyncdata/imapper/DataVMapper.java b/src/main/java/com/njcn/jbsyncdata/imapper/DataVMapper.java new file mode 100644 index 0000000..5fcad80 --- /dev/null +++ b/src/main/java/com/njcn/jbsyncdata/imapper/DataVMapper.java @@ -0,0 +1,22 @@ +package com.njcn.jbsyncdata.imapper; + +import com.njcn.influx.base.InfluxDbBaseMapper; +import com.njcn.influx.query.InfluxQueryWrapper; +import com.njcn.jbsyncdata.pojo.po.DataV; + +import java.util.List; + + +/** + * 类的介绍: + * + * @author xuyang + * @version 1.0.0 + * @createTime 2023/5/5 14:39 + */ + +public interface DataVMapper extends InfluxDbBaseMapper { + + + List selectDataV(InfluxQueryWrapper queryWrapper); +} diff --git a/src/main/java/com/njcn/jbsyncdata/pojo/po/DataV.java b/src/main/java/com/njcn/jbsyncdata/pojo/po/DataV.java new file mode 100644 index 0000000..bc778fe --- /dev/null +++ b/src/main/java/com/njcn/jbsyncdata/pojo/po/DataV.java @@ -0,0 +1,235 @@ +package com.njcn.jbsyncdata.pojo.po; + +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.njcn.jbsyncdata.util.InstantDateSerializer; +import lombok.Data; +import org.influxdb.annotation.Column; +import org.influxdb.annotation.Measurement; +import org.influxdb.annotation.TimeColumn; + +import java.time.Instant; + +/** + * 类的介绍: + * + * @author xuyang + * @version 1.0.0 + * @createTime 2022/4/7 10:00 + */ +@Data +@Measurement(name = "data_v") +public class DataV { + + @TimeColumn + @Column(name = "time",tag = true) + @JsonSerialize(using = InstantDateSerializer.class) + private Instant time; + + @Column(name = "freq") + private double freq; + + @Column(name = "freq_dev") + private double freqDev; + + @Column(name = "quality_flag",tag = true) + private String qualityFlag; + + @Column(name = "rms") + private double rms; + + @Column(name = "rms_lvr") + private double rmsLvr; + + @Column(name = "vl_dev") + private double vlDev; + + @Column(name = "vu_dev") + private double vuDev; + + @Column(name = "v_1") + private double v1; + + @Column(name = "v_2") + private double v2; + + @Column(name = "v_3") + private double v3; + + @Column(name = "v_4") + private double v4; + + @Column(name = "v_5") + private double v5; + + @Column(name = "v_6") + private double v6; + + @Column(name = "v_7") + private double v7; + + @Column(name = "v_8") + private double v8; + + @Column(name = "v_9") + private double v9; + + @Column(name = "v_10") + private double v10; + + @Column(name = "v_11") + private double v11; + + @Column(name = "v_12") + private double v12; + + @Column(name = "v_13") + private double v13; + + @Column(name = "v_14") + private double v14; + + @Column(name = "v_15") + private double v15; + + @Column(name = "v_16") + private double v16; + + @Column(name = "v_17") + private double v17; + + @Column(name = "v_18") + private double v18; + + @Column(name = "v_19") + private double v19; + + @Column(name = "v_20") + private double v20; + + @Column(name = "v_21") + private double v21; + + @Column(name = "v_22") + private double v22; + + @Column(name = "v_23") + private double v23; + + @Column(name = "v_24") + private double v24; + + @Column(name = "v_25") + private double v25; + + @Column(name = "v_26") + private double v26; + + @Column(name = "v_27") + private double v27; + + @Column(name = "v_28") + private double v28; + + @Column(name = "v_29") + private double v29; + + @Column(name = "v_30") + private double v30; + + @Column(name = "v_31") + private double v31; + + @Column(name = "v_32") + private double v32; + + @Column(name = "v_33") + private double v33; + + @Column(name = "v_34") + private double v34; + + @Column(name = "v_35") + private double v35; + + @Column(name = "v_36") + private double v36; + + @Column(name = "v_37") + private double v37; + + @Column(name = "v_38") + private double v38; + + @Column(name = "v_39") + private double v39; + + @Column(name = "v_40") + private double v40; + + @Column(name = "v_41") + private double v41; + + @Column(name = "v_42") + private double v42; + + @Column(name = "v_43") + private double v43; + + @Column(name = "v_44") + private double v44; + + @Column(name = "v_45") + private double v45; + + @Column(name = "v_46") + private double v46; + + @Column(name = "v_47") + private double v47; + + @Column(name = "v_48") + private double v48; + + @Column(name = "v_49") + private double v49; + + @Column(name = "v_50") + private double v50; + + @Column(name = "v_neg") + private double vNeg; + + @Column(name = "v_pos") + private double vPos; + + @Column(name = "v_thd") + private double vThd; + + @Column(name = "v_unbalance") + private double vUnbalance; + + @Column(name = "v_zero") + private double vZero; + + @Column(name = "line_id",tag = true) + private String lineId; + + @Column(name = "phasic_type",tag = true) + private String phasicType; + + @Column(name = "value_type",tag = true) + private String valueType; + + + //自定义字段-总计算次数 + @Column(name = "all_time") + private Integer allTime; + + //自定义字段 + @Column(name = "mean") + private double mean; + + //自定义字段 + @Column(name = "count") + private Integer count; +} diff --git a/src/main/java/com/njcn/jbsyncdata/pojo/result/CommonTelemetry.java b/src/main/java/com/njcn/jbsyncdata/pojo/result/CommonTelemetry.java new file mode 100644 index 0000000..456e880 --- /dev/null +++ b/src/main/java/com/njcn/jbsyncdata/pojo/result/CommonTelemetry.java @@ -0,0 +1,38 @@ +package com.njcn.jbsyncdata.pojo.result; + +import lombok.Data; + +import java.io.Serializable; +import java.util.List; + + +@Data +public class CommonTelemetry implements Serializable { + + private String measPointId; + + private String psrId; + + private String psrType; + + private String astId; + + private String astType; + + private String consNo; + + private String consType; + + private String measTypeCode; + + private String measTypeName; + + private String source; + + private String pt; + + private String ct; + + private List telemetryValue; + +} diff --git a/src/main/java/com/njcn/jbsyncdata/pojo/result/DataResult.java b/src/main/java/com/njcn/jbsyncdata/pojo/result/DataResult.java deleted file mode 100644 index 1b52449..0000000 --- a/src/main/java/com/njcn/jbsyncdata/pojo/result/DataResult.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.njcn.jbsyncdata.pojo.result; - -import lombok.Data; - -import java.io.Serializable; - -@Data -public class DataResult implements Serializable { - -} diff --git a/src/main/java/com/njcn/jbsyncdata/pojo/result/GeneralResult.java b/src/main/java/com/njcn/jbsyncdata/pojo/result/GeneralResult.java new file mode 100644 index 0000000..fddf4dd --- /dev/null +++ b/src/main/java/com/njcn/jbsyncdata/pojo/result/GeneralResult.java @@ -0,0 +1,15 @@ +package com.njcn.jbsyncdata.pojo.result; + +import lombok.Data; + +import java.io.Serializable; + +@Data +public class GeneralResult implements Serializable { + + private String status; + + private String errors; + + private PageResult result; +} diff --git a/src/main/java/com/njcn/jbsyncdata/pojo/result/PageResult.java b/src/main/java/com/njcn/jbsyncdata/pojo/result/PageResult.java new file mode 100644 index 0000000..5702a94 --- /dev/null +++ b/src/main/java/com/njcn/jbsyncdata/pojo/result/PageResult.java @@ -0,0 +1,24 @@ +package com.njcn.jbsyncdata.pojo.result; + +import lombok.Data; + +import java.io.Serializable; +import java.util.List; + +/** + * 暂时未知 total 有什么用,看起来数据是一次性返回的 + */ +@Data +public class PageResult implements Serializable { + + private Integer current; + + private Integer total; + + private Integer pages; + + private Integer size; + + private List records; + +} diff --git a/src/main/java/com/njcn/jbsyncdata/pojo/result/StatisticsData.java b/src/main/java/com/njcn/jbsyncdata/pojo/result/StatisticsData.java new file mode 100644 index 0000000..6f37aea --- /dev/null +++ b/src/main/java/com/njcn/jbsyncdata/pojo/result/StatisticsData.java @@ -0,0 +1,18 @@ +package com.njcn.jbsyncdata.pojo.result; + +import lombok.Data; + +import java.io.Serializable; + +@Data +public class StatisticsData implements Serializable { + + private String measValue; + + private String dataTime; + + private String timeInterval; + + private String timeUnit; + +} diff --git a/src/main/java/com/njcn/jbsyncdata/service/impl/BusinessServiceImpl.java b/src/main/java/com/njcn/jbsyncdata/service/impl/BusinessServiceImpl.java index 53561d7..29ba8c6 100644 --- a/src/main/java/com/njcn/jbsyncdata/service/impl/BusinessServiceImpl.java +++ b/src/main/java/com/njcn/jbsyncdata/service/impl/BusinessServiceImpl.java @@ -1,10 +1,18 @@ package com.njcn.jbsyncdata.service.impl; +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.date.DatePattern; +import cn.hutool.core.date.DateTime; +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.io.file.FileReader; +import cn.hutool.core.text.StrPool; +import cn.hutool.core.util.StrUtil; import cn.hutool.json.JSONObject; import cn.hutool.json.JSONUtil; import com.njcn.jbsyncdata.component.TokenComponent; +import com.njcn.jbsyncdata.enums.MeasTypeEnum; import com.njcn.jbsyncdata.pojo.ExcelData; -import com.njcn.jbsyncdata.pojo.result.TokenResult; +import com.njcn.jbsyncdata.pojo.result.*; import com.njcn.jbsyncdata.service.IBusinessService; import com.njcn.jbsyncdata.util.RestTemplateUtil; import lombok.extern.slf4j.Slf4j; @@ -12,10 +20,7 @@ import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Service; import javax.annotation.Resource; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -50,9 +55,6 @@ public class BusinessServiceImpl implements IBusinessService { jsonObjectSub.set("termType", ""); jsonObjectSub.set("measPointIds", new ArrayList<>()); jsonObject.set("filter", jsonObjectSub); - if (excelData.getStageID().equalsIgnoreCase("1502760751")) { - log.error("组装后的json为:{}", jsonObject); - } //组装好json开始发送请求 Map headers = new HashMap<>(); headers.put("x-token", tokenWithRestTemplate.getAccess_token()); @@ -81,23 +83,93 @@ public class BusinessServiceImpl implements IBusinessService { List userId = Stream.of("160".concat(excelData.getGenerationUserID())).collect(Collectors.toList()); jsonObjectSub.set("consNos", userId); jsonObjectSub.set("consType", 3); - jsonObjectSub.set("astIds", new ArrayList<>()); jsonObjectSub.set("astType", ""); jsonObjectSub.set("psrIds", new ArrayList<>()); jsonObjectSub.set("psrType", ""); jsonObjectSub.set("measPointIds", new ArrayList<>()); - List typeList = Stream.of("PhV_phsA","PhV_phsB","PhV_phsC").collect(Collectors.toList()); + //指标类型集合 + List typeList = MeasTypeEnum.getMeasList(); jsonObjectSub.set("telemetryTypes", typeList); jsonObject.set("filter", jsonObjectSub); - if (excelData.getStageID().equalsIgnoreCase("2226675026")) { - log.error("组装后的json为:{}", jsonObject); - } //组装好json开始发送请求 Map headers = new HashMap<>(); headers.put("x-token", tokenWithRestTemplate.getAccess_token()); - ResponseEntity response = restTemplateUtil.post(tokenComponent.getUrl().concat("/realMeasCenter/measPoint/commonQuery"), headers, jsonObject, String.class); + ResponseEntity response = restTemplateUtil.post(tokenComponent.getUrl().concat("/realMeasCenter/telemetry/commonQuery"), headers, jsonObject, GeneralResult.class); + if (response.getStatusCodeValue() == 200 && response.getBody().getStatus().equalsIgnoreCase("000000")) { + PageResult result = response.getBody().getResult(); + List records = result.getRecords(); + if (Objects.isNull(result) || CollectionUtil.isEmpty(result.getRecords())) { + //日志输出: + log.error("用户编号为:{},无遥测数据;", excelData.getGenerationUserID()); + continue; + } + //处理各个record的数据,因用户下可能有多个测量点,按指标循环,默认采用第一个匹配上的做数据处理 + Map>> typeData = new HashMap<>(); + for (String type : typeList) { + MeasTypeEnum measTypeEnumByMeasType = MeasTypeEnum.getMeasTypeEnumByMeasType(type); + for (CommonTelemetry commonTelemetry : records) { + if (type.equalsIgnoreCase(commonTelemetry.getMeasTypeCode())) { + List statisticsDataList = commonTelemetry.getTelemetryValue(); + List> influxData = new ArrayList<>(); + for (StatisticsData statisticsData : statisticsDataList) { + Map tempInfluxData = new HashMap<>(); + tempInfluxData.put("phasic_type", measTypeEnumByMeasType.getPhaseType()); + tempInfluxData.put("line_id", "160".concat(excelData.getGenerationUserID())); + tempInfluxData.put("quality_flag", "0"); + tempInfluxData.put("value_type", "AVG"); + tempInfluxData.put("time", statisticsData.getDataTime()); + //为空则赋值为0,表中其他均为0 + tempInfluxData.put(measTypeEnumByMeasType.getFieldName(), StrUtil.isBlank(statisticsData.getMeasValue()) ? "0" : statisticsData.getMeasValue()); + influxData.add(tempInfluxData); + } + //measType@tableName:存在多个指标存储表名一致,避免数据覆盖; + typeData.put(measTypeEnumByMeasType.getMeasType().concat(StrPool.AT).concat(measTypeEnumByMeasType.getTableName()), influxData); + break; + } + } + } + } + + log.error("请求接口,台区号为:{},结果为:{}", excelData.getStageID(), response); } } + + + public static void main(String[] args) { + String path = "C:\\Users\\83944\\Desktop\\test\\test.txt"; + FileReader fileReader = new FileReader(path); + String jsonStr = fileReader.readString(); + GeneralResult result = JSONUtil.toBean(jsonStr, GeneralResult.class); + List records = result.getResult().getRecords(); + //处理各个record的数据,因用户下可能有多个测量点,按指标循环,默认采用第一个匹配上的做数据处理 + Map>> typeData = new HashMap<>(); + List typeList = Stream.of("PhV_phsA", "PhV_phsB", "PhV_phsC").collect(Collectors.toList()); + for (String type : typeList) { + MeasTypeEnum measTypeEnumByMeasType = MeasTypeEnum.getMeasTypeEnumByMeasType(type); + for (CommonTelemetry commonTelemetry : records) { + if (type.equalsIgnoreCase(commonTelemetry.getMeasTypeCode())) { + List statisticsDataList = commonTelemetry.getTelemetryValue(); + List> influxData = new ArrayList<>(); + for (StatisticsData statisticsData : statisticsDataList) { + Map tempInfluxData = new HashMap<>(); + tempInfluxData.put("phasic_type", measTypeEnumByMeasType.getPhaseType()); + tempInfluxData.put("line_id", "1602514341899"); + tempInfluxData.put("quality_flag", "0"); + tempInfluxData.put("value_type", "AVG"); + tempInfluxData.put("time", statisticsData.getDataTime()); + //为空则赋值为0,表中其他均为0 + tempInfluxData.put(measTypeEnumByMeasType.getFieldName(), StrUtil.isBlank(statisticsData.getMeasValue()) ? "0" : statisticsData.getMeasValue()); + influxData.add(tempInfluxData); + } + typeData.put(measTypeEnumByMeasType.getMeasType().concat("@").concat(measTypeEnumByMeasType.getTableName()), influxData); + break; + } + } + } + + System.out.println(11); + + } } diff --git a/src/main/java/com/njcn/jbsyncdata/util/InstantDateDeserializer.java b/src/main/java/com/njcn/jbsyncdata/util/InstantDateDeserializer.java new file mode 100644 index 0000000..2b5727b --- /dev/null +++ b/src/main/java/com/njcn/jbsyncdata/util/InstantDateDeserializer.java @@ -0,0 +1,38 @@ +package com.njcn.jbsyncdata.util; + +import cn.hutool.core.date.DatePattern; +import cn.hutool.core.date.DateUtil; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.deser.std.StdDeserializer; +import org.springframework.stereotype.Component; + +import java.io.IOException; +import java.time.Instant; + +/** + * @author hongawen + * @version 1.0.0 + * @date 2023年07月24日 13:33 + */ +@Component +public class InstantDateDeserializer extends StdDeserializer { + + + public InstantDateDeserializer() { + this(null); + } + + + protected InstantDateDeserializer(Class vc) { + super(vc); + } + + + @Override + public Instant deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException { + String text = p.getValueAsString(); + return PubUtils.dateToInstant(DateUtil.parse(text,DatePattern.NORM_DATETIME_PATTERN)); + } +} diff --git a/src/main/java/com/njcn/jbsyncdata/util/InstantDateSerializer.java b/src/main/java/com/njcn/jbsyncdata/util/InstantDateSerializer.java new file mode 100644 index 0000000..c0de4d4 --- /dev/null +++ b/src/main/java/com/njcn/jbsyncdata/util/InstantDateSerializer.java @@ -0,0 +1,48 @@ +package com.njcn.jbsyncdata.util; + +import cn.hutool.core.date.DatePattern; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.ser.std.StdSerializer; +import org.springframework.stereotype.Component; + +import java.io.IOException; +import java.time.Instant; +import java.time.ZoneId; +import java.time.format.DateTimeFormatter; + + +/** + * @author hongawen + * @version 1.0.0 + * @date 2023年04月25日 16:33 + */ +@Component +public class InstantDateSerializer extends StdSerializer { + + private static final long serialVersionUID = 1L; + + private static DateTimeFormatter format = DateTimeFormatter.ofPattern(DatePattern.NORM_DATETIME_PATTERN); + + public InstantDateSerializer() { + this(null); + } + + public InstantDateSerializer(Class t) { + super(t); + } + + /*** + * 转义为 yyyy-MM-dd HH:mm:ss + * @author hongawen + */ + @Override + public void serialize(Instant instant, JsonGenerator jsonGenerator, SerializerProvider provider) + throws IOException { + if (instant == null) { + return; + } + String jsonValue = format.format(instant.atZone(ZoneId.of("+00:00"))); + jsonGenerator.writeString(jsonValue); + } +} \ No newline at end of file diff --git a/src/main/java/com/njcn/jbsyncdata/util/PubUtils.java b/src/main/java/com/njcn/jbsyncdata/util/PubUtils.java new file mode 100644 index 0000000..c0a2744 --- /dev/null +++ b/src/main/java/com/njcn/jbsyncdata/util/PubUtils.java @@ -0,0 +1,443 @@ +package com.njcn.jbsyncdata.util; + +import cn.hutool.core.util.RandomUtil; +import cn.hutool.core.util.StrUtil; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.JavaType; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; +import com.fasterxml.jackson.databind.type.TypeFactory; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; + +import java.io.IOException; +import java.lang.reflect.Method; +import java.lang.reflect.Type; +import java.math.BigDecimal; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.time.Instant; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.*; +import java.util.concurrent.TimeUnit; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import static java.lang.Integer.parseInt; + + +/** + * @author hongawen + * @version 1.0.0 + * @date 2021年04月12日 14:21 + */ +public class PubUtils { + + private final static ObjectMapper MAPPER = new ObjectMapper(); + + private static final String DATE_TIME = "yyyy-MM-dd HH:mm:ss"; + + private static final String DATE = "yyyy-MM-dd"; + + private static final String TIME = "HH:mm:ss"; + + + /** + * 生成随机码,包含字母。--> 大写 + * + * @param length 随机码长度 + */ + public static String randomCode(int length) { + return RandomUtil.randomString(length).toUpperCase(Locale.ENGLISH); + } + + + /**** + * ***** ***** 验证IP是否属于某个IP段 ipSection IP段(以'-'分隔) ip 所验证的IP号码 ***** ***** + **/ + public static boolean ipExistsInRange(String ip, String ipSection) { + ipSection = ipSection.trim(); + ip = ip.trim(); + int idx = ipSection.indexOf('-'); + String beginIp = ipSection.substring(0, idx); + String endIp = ipSection.substring(idx + 1); + return getIp2long(beginIp) <= getIp2long(ip) && getIp2long(ip) <= getIp2long(endIp); + } + + private static long getIp2long(String ip) { + ip = ip.trim(); + String[] ips = ip.split("\\."); + long ip2long = 0L; + for (int i = 0; i < 4; ++i) { + ip2long = ip2long << 8 | parseInt(ips[i]); + } + return ip2long; + } + + /** + * 获取当前时间 + * + * @author cdf + * @date 2021/7/26 + */ + public static String getNow() { + DateFormat bf = new SimpleDateFormat("yyyyMMddHHmmss"); + return bf.format(new Date()); + } + + /** + * 毫秒转时间 ms:需要转换的毫秒时间 + */ + public static Date ms2Date(Long ms) { + Calendar c = Calendar.getInstance(); + c.setTimeInMillis(ms); + return c.getTime(); + } + + /** + * 日期转字符串函数 date:需要转换的日期 strFormat:转换的格式(yyyy-MM-dd HH:mm:ss) + */ + public static String date2String(Date date, String strFormat){ + SimpleDateFormat format = new SimpleDateFormat(strFormat); + + return format.format(date); + } + + /** + * 获取当前web的IP + */ + public static String getLocalIp() { + String host; + try { + host = InetAddress.getLocalHost().getHostAddress(); + } catch (UnknownHostException e) { + e.printStackTrace(); + host = "127.0.0.1"; + } + return host; + } + + /** + * 将JSON转为实体对象 + * + * @param jsonStr json + * @param targetType 对象类型 + * @param 对象 + */ + public static T json2obj(String jsonStr, Type targetType) { + try { + JavaType javaType = TypeFactory.defaultInstance().constructType(targetType); + MAPPER.registerModule(new JavaTimeModule()); + MAPPER.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); + return MAPPER.readValue(jsonStr, javaType); + } catch (IOException e) { + throw new IllegalArgumentException("将JSON转换为对象时发生错误:" + jsonStr, e); + } + } + + /** + * 将实体对象转为JSON + * + * @param object 实体对象 + */ + public static String obj2json(Object object) { + try { + MAPPER.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true); + return MAPPER.writeValueAsString(object); + } catch (IOException e) { + throw new IllegalArgumentException("将将实体对象转为JSON时发生错误:" + object, e); + } + } + + + /** + * 判断一个数字是否在区间内 + * + * @param current 待判断数字 + * @param min 最小值 + * @param max 最大值 + */ + public static boolean rangeInDefined(int current, int min, int max) { + return Math.max(min, current) == Math.min(current, max); + } + + /** + * 将起始日期字符串 yyyy-MM-dd 转为 yyyy-MM-dd HH:mm:ss的LocalDateTime + */ + public static LocalDateTime beginTimeToLocalDateTime(String beginTime) { + beginTime = beginTime + StrUtil.SPACE + "00:00:00"; + DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(DATE_TIME); + return LocalDateTime.parse(beginTime, dateTimeFormatter); + } + + /** + * 将截止日期字符串 yyyy-MM-dd 转为 yyyy-MM-dd HH:mm:ss的LocalDateTime + */ + public static LocalDateTime endTimeToLocalDateTime(String endTime) { + endTime = endTime + StrUtil.SPACE + "23:59:59"; + DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(DATE_TIME); + return LocalDateTime.parse(endTime, dateTimeFormatter); + } + + /** + * 将字符串日期转为LocalDate日期(只用于日期转换) + */ + public static LocalDate localDateFormat(String time) { + DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(DATE); + return LocalDate.parse(time, dateTimeFormatter); + } + + public static LocalDateTime localDateTimeFormat(String time) { + DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(DATE_TIME); + return LocalDateTime.parse(time, dateTimeFormatter); + } + + + public static List getStartTimeEndTime(String beginDate, String endDate) throws Exception { + + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + Calendar cal = Calendar.getInstance(); + cal.setTime(sdf.parse(beginDate)); + List startTimeEndTime = null; + for (long d = cal.getTimeInMillis(); d <= sdf.parse(endDate).getTime(); d = getDplaus(cal)) { + startTimeEndTime.add(sdf.format(d)); + } + return startTimeEndTime; + } + + public static long getDplaus(Calendar c) { + c.set(Calendar.DAY_OF_MONTH, c.get(Calendar.DAY_OF_MONTH) + 1); + return c.getTimeInMillis(); + } + + public static String comFlag(Integer comFlag) { + switch (comFlag) { + case 0: + return "中断"; + case 1: + return "正常"; + default: + return ""; + } + } + + public static String runFlag(Integer runFlag) { + switch (runFlag) { + case 0: + return "投运"; + case 1: + return "热备用"; + case 2: + return "停运"; + default: + return ""; + } + } + + public static Integer getRunFlag(String runFlag) { + switch (runFlag) { + case "投运": + return 0; + case "热备用": + return 1; + case "停运": + return 2; + default: + return -1; + } + } + public static Double getDefectSeverity(String defectSeverity) { + switch (defectSeverity) { + case "轻缺陷": + return 0.02; + case "较重缺陷": + return 0.12; + case "严重缺陷": + return 0.42; + default: + return 0.00; + } + } + + public static String ptType(Integer ptType) { + switch (ptType) { + case 0: + return "星型接线"; + case 1: + return "三角型接线"; + case 2: + return "开口三角型接线"; + default: + return ""; + } + } + + public static Integer ptTypeName(String ptType) { + switch (ptType) { + case "星型接线": + return 0; + case "三角型接线": + return 1; + case "开口三角型接线": + return 2; + default: + return -1; + } + } + + /** + * 将当前时间的秒数置为0 + * + * @param date 时间 + */ + public static Date getSecondsAsZero(Date date) { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(date); + calendar.set(Calendar.SECOND, 0); + return calendar.getTime(); + } + + /** + * 根据起始时间和截止时间返回yyyy-MM-dd的日期, + * + * @param startTime 起始时间 + * @param endTime 截止时间 + */ + public static List getTimes(Date startTime, Date endTime) { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + List result = new ArrayList<>(); + Calendar start = Calendar.getInstance(); + start.setTime(startTime); + Calendar end = Calendar.getInstance(); + end.setTime(endTime); + end.set(end.get(Calendar.YEAR), end.get(Calendar.MONTH), end.get(Calendar.DAY_OF_MONTH), 0, 0, 0); + long interval = end.getTimeInMillis() - start.getTimeInMillis(); + result.add(sdf.format(start.getTime())); + if (interval > 0) { + int days = (int) (interval / 86400000); + for (int i = 0; i < days; i++) { + start.add(Calendar.DAY_OF_MONTH, 1); + result.add(sdf.format(start.getTime())); + } + } + return result; + } + + /*** + * 将instant转为date 处理8小时误差 + * @author hongawen + * @date 2023/7/20 15:58 + * @param instant 日期 + * @return Instant + */ + public static Date instantToDate(Instant instant){ + return Date.from(instant.minusMillis(TimeUnit.HOURS.toMillis(8))); + } + + /*** + * 将date转为instant 处理8小时误差 + * @author hongawen + * @date 2023/7/20 15:58 + * @param date 日期 + * @return Instant + */ + public static Instant dateToInstant(Date date){ + return date.toInstant().plusMillis(TimeUnit.HOURS.toMillis(8)); + } + + + /** + * 根据参数返回float的四舍五入值 + * + * @param i 保留的位数 + * @param value float原值 + */ + public static Float floatRound(int i, float value) { + BigDecimal bp = new BigDecimal(value); + return bp.setScale(i, BigDecimal.ROUND_HALF_UP).floatValue(); + } + + //*****************************************xuyang添加,用于App******************************************************** + /** + * 正则表达式字符串 + * 要匹配的字符串 + * + * @return 如果str 符合 regex的正则表达式格式,返回true, 否则返回 false; + */ + public static boolean match(String regex, String str) { + Pattern pattern = Pattern.compile(regex); + Matcher matcher = pattern.matcher(str); + return matcher.matches(); + } + + /** + * 生成随机推荐码 + */ + public static String getCode(Integer number){ + final String BASIC = "123456789AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz"; + char[] basicArray = BASIC.toCharArray(); + Random random = new Random(); + char[] result = new char[number]; + for (int i = 0; i < result.length; i++) { + int index = random.nextInt(100) % (basicArray.length); + result[i] = basicArray[index]; + } + return new String(result); + } + + /** + * 将字节数组转成Float数组 + * @param bytes + * @return + */ + public static List byteArrayToFloatList(byte[] bytes){ + List d = new ArrayList<>(bytes.length/8); + byte[] doubleBuffer = new byte[4]; + for(int j = 0; j < bytes.length; j += 4) { + System.arraycopy(bytes, j, doubleBuffer, 0, doubleBuffer.length); + d.add(bytes2Float(doubleBuffer)); + } + return d; + } + + public static float bytes2Float(byte[] arr) { + int accum = 0; + accum = accum|(arr[0] & 0xff); + accum = accum|(arr[1] & 0xff) << 8; + accum = accum|(arr[2] & 0xff) << 16; + accum = accum|(arr[3] & 0xff) << 24; + return Float.intBitsToFloat(accum); + } + + /** + * 将字节数组转成Double数组 + * @param arr + * @return + */ + public static List byteArrayToDoubleList(byte[] arr){ + List d = new ArrayList<>(arr.length/8); + byte[] doubleBuffer = new byte[8]; + for(int j = 0; j < arr.length; j += 8) { + System.arraycopy(arr, j, doubleBuffer, 0, doubleBuffer.length); + d.add(bytes2Double(doubleBuffer)); + } + return d; + } + + /** + * 将byte转换成double + * @param arr + * @return + */ + public static double bytes2Double(byte[] arr) { + long value = 0; + for (int i = 0; i < 8; i++) { + value |= ((long) (arr[i] & 0xff)) << (8 * i); + } + return Double.longBitsToDouble(value); + } + //***************************************************添加结束******************************************************** +} diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 92dba9e..fdbc9c2 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -38,6 +38,12 @@ spring: max-request-size: 100MB max-file-size: 500MB enabled: true + influx: + url: http://127.0.0.1:8086 + user: admin + password: 123456 + database: pqsbase_sjzx + mapper-location: com.njcn.jbsyncdata.imapper diff --git a/src/test/java/com/njcn/jbsyncdata/JbSyncdataApplicationTests.java b/src/test/java/com/njcn/jbsyncdata/JbSyncdataApplicationTests.java index fb1eb0a..9f03577 100644 --- a/src/test/java/com/njcn/jbsyncdata/JbSyncdataApplicationTests.java +++ b/src/test/java/com/njcn/jbsyncdata/JbSyncdataApplicationTests.java @@ -1,13 +1,126 @@ package com.njcn.jbsyncdata; +import cn.hutool.core.date.DatePattern; +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.io.file.FileReader; +import cn.hutool.core.text.StrPool; +import cn.hutool.core.util.StrUtil; +import cn.hutool.json.JSONUtil; +import com.njcn.influx.query.InfluxQueryWrapper; +import com.njcn.influx.utils.InfluxDbUtils; +import com.njcn.jbsyncdata.enums.MeasTypeEnum; +import com.njcn.jbsyncdata.imapper.DataVMapper; +import com.njcn.jbsyncdata.pojo.po.DataV; +import com.njcn.jbsyncdata.pojo.result.CommonTelemetry; +import com.njcn.jbsyncdata.pojo.result.GeneralResult; +import com.njcn.jbsyncdata.pojo.result.StatisticsData; +import org.influxdb.InfluxDB; +import org.influxdb.dto.BatchPoints; +import org.influxdb.dto.Point; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; +import javax.annotation.Resource; +import java.time.Instant; +import java.util.*; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; +import java.util.stream.Stream; + @SpringBootTest class JbSyncdataApplicationTests { + @Resource + private InfluxDbUtils influxDbUtils; + @Test - void contextLoads() { + void testInfluxInsert() { + String path = "C:\\Users\\83944\\Desktop\\test\\test.txt"; + FileReader fileReader = new FileReader(path); + String jsonStr = fileReader.readString(); + GeneralResult result = JSONUtil.toBean(jsonStr, GeneralResult.class); + List records = result.getResult().getRecords(); + //处理各个record的数据,因用户下可能有多个测量点,按指标循环,默认采用第一个匹配上的做数据处理 + Map>> typeData = new HashMap<>(); + List typeList = Stream.of("PhV_phsA", "PhV_phsB", "PhV_phsC").collect(Collectors.toList()); + for (String type : typeList) { + MeasTypeEnum measTypeEnumByMeasType = MeasTypeEnum.getMeasTypeEnumByMeasType(type); + for (CommonTelemetry commonTelemetry : records) { + if (type.equalsIgnoreCase(commonTelemetry.getMeasTypeCode())) { + List statisticsDataList = commonTelemetry.getTelemetryValue(); + List> influxData = new ArrayList<>(); + for (StatisticsData statisticsData : statisticsDataList) { + Map tempInfluxData = new HashMap<>(); + tempInfluxData.put("phasic_type", measTypeEnumByMeasType.getPhaseType()); + tempInfluxData.put("line_id", "1602514341899"); + tempInfluxData.put("quality_flag", "0"); + tempInfluxData.put("value_type", "AVG"); + tempInfluxData.put("time", statisticsData.getDataTime()); + //为空则赋值为0,表中其他均为0 + tempInfluxData.put(measTypeEnumByMeasType.getFieldName(), StrUtil.isBlank(statisticsData.getMeasValue()) ? "0" : statisticsData.getMeasValue()); + influxData.add(tempInfluxData); + } + typeData.put(measTypeEnumByMeasType.getMeasType().concat(StrPool.AT).concat(measTypeEnumByMeasType.getTableName()), influxData); + break; + } + } + } + List sqlList = new ArrayList<>(); + Set tableNames = typeData.keySet(); + for (String tableName : tableNames) { + List> data = typeData.get(tableName); + tableName = tableName.substring(tableName.indexOf(StrPool.AT) + 1); + //需要转换的实体类class类 + for (Map datum : data) { + Map tags = new HashMap<>(); + tags.put("phasic_type", datum.get("phasic_type")); + datum.remove("phasic_type"); + tags.put("line_id", datum.get("line_id")); + datum.remove("line_id"); + tags.put("quality_flag", datum.get("quality_flag")); + datum.remove("quality_flag"); + tags.put("value_type", datum.get("value_type")); + datum.remove("value_type"); + String time = datum.get("time"); + datum.remove("time"); + //tag数据删完后,剩余均是filed数据,因filed属性名不固定,无法指定获取,直接循环 + Map fields = new HashMap<>(); + Set fieldNames = datum.keySet(); + for (String fieldName : fieldNames) { + fields.put(fieldName, Double.parseDouble(datum.get(fieldName))); + } + Point point = influxDbUtils.pointBuilder(tableName, DateUtil.parse(time, DatePattern.NORM_DATETIME_FORMATTER).getTime() + 8 * 3600 * 1000, TimeUnit.MILLISECONDS, tags, fields); + BatchPoints batchPoints = BatchPoints.database(influxDbUtils.getDbName()).retentionPolicy("").consistency(InfluxDB.ConsistencyLevel.ALL).build(); + batchPoints.point(point); + sqlList.add(batchPoints.lineProtocol()); + + } + } + influxDbUtils.batchInsert(influxDbUtils.getDbName(), "", InfluxDB.ConsistencyLevel.ALL, TimeUnit.MILLISECONDS, sqlList); + System.out.println(11); } + + @Resource + private DataVMapper dataVMapper; + + @Test + public void testInflux() { + DataV dataV = new DataV(); + dataV.setTime(Instant.now()); + dataV.setLineId("123"); + dataV.setPhasicType("123"); + dataV.setQualityFlag("123"); + dataV.setValueType("123"); + dataVMapper.insertOne(dataV); + } + + @Test + public void testQueryInflux() { + InfluxQueryWrapper queryWrapper = new InfluxQueryWrapper(DataV.class); + List dataVList = dataVMapper.selectDataV(queryWrapper); + System.out.println(1); + } + + }