ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/emind/domain/EmindEnergyChain.java
@@ -125,4 +125,13 @@ /** Data status, not persisted. */ @ApiModelProperty("Data status, not persisted") private Integer dataStatus; /** * 设备类型(平台为华为时展示) */ @TableField("station_type") private String stationType; @TableField(exist = false) private String detail; } ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/emind/domain/EmindEnergyChainDetail.java
New file @@ -0,0 +1,56 @@ package com.ruoyi.other.emind.domain; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import java.time.LocalDateTime; /** eMind 储能能量链本地冗余数据。 */ @Data @ApiModel("EmindEnergyChainDetail") @TableName("t_emind_energy_chain_detail") public class EmindEnergyChainDetail { @TableId(value = "id", type = IdType.AUTO) @ApiModelProperty("Primary key") private Long id; @TableField("platform_name") private String platformName; @TableField("station_id") private String stationId; @TableField("station_code") private String stationCode; @TableField("station_type") private String stationType; @TableField("detail") private String detail; @TableField("data_source") @ApiModelProperty("Data source: 1 remote, 2 manual") private Integer dataSource; @TableField("del_flag") private Integer delFlag; @TableField("sync_time") private LocalDateTime syncTime; @TableField("create_time") private LocalDateTime createTime; @TableField("update_time") private LocalDateTime updateTime; } ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/emind/mapper/EmindEnergyChainDetailMapper.java
New file @@ -0,0 +1,8 @@ package com.ruoyi.other.emind.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.ruoyi.other.emind.domain.EmindEnergyChainDetail; /** 能量链详情数据访问层。 */ public interface EmindEnergyChainDetailMapper extends BaseMapper<EmindEnergyChainDetail> { } ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/emind/mapper/EmindStorageDashboardMapper.java
@@ -9,6 +9,7 @@ import java.math.BigDecimal; import java.util.List; import java.util.Map; import java.util.Set; public interface EmindStorageDashboardMapper { int upsertSnapshot(@Param("station") EmindStation station, @Param("data") EmindMainTotalDto data, @@ -27,4 +28,6 @@ @Param("endDate") LocalDate endDate); List<Map<String, Object>> selectCurveRows(@Param("stationId") Long stationId, @Param("platformNames") List<String> platformNames); List<Map<String, Object>> selectEnergyBlockRows(@Param("stationId") Long stationId, @Param("platformNames") List<String> platformNames); void deleteByStationIdDay(@Param("stationId") Long stationId, @Param("dateSet") Set<LocalDate> dateSet); } ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/emind/service/EmindEnergyChainDetailService.java
New file @@ -0,0 +1,111 @@ package com.ruoyi.other.emind.service; import com.alibaba.fastjson2.JSON; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.ruoyi.other.emind.domain.EmindEnergyChainDetail; import com.ruoyi.other.emind.mapper.EmindEnergyChainDetailMapper; import com.ruoyi.other.udan.model.UdanEmsDeviceState; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.time.Clock; import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; import java.util.Objects; /** 能量链详情服务。 */ @Service public class EmindEnergyChainDetailService { private final EmindEnergyChainDetailMapper mapper; private final Clock clock; @Autowired public EmindEnergyChainDetailService(EmindEnergyChainDetailMapper mapper) { this(mapper, Clock.systemDefaultZone()); } EmindEnergyChainDetailService(EmindEnergyChainDetailMapper mapper, Clock clock) { this.mapper = mapper; this.clock = clock; } /** 新增能量链详情。 */ @Transactional(rollbackFor = Exception.class) public EmindEnergyChainDetail add(EmindEnergyChainDetail input) { LocalDateTime now = LocalDateTime.now(clock); EmindEnergyChainDetail detail = new EmindEnergyChainDetail(); detail.setPlatformName(input.getPlatformName()); detail.setStationId(input.getStationId()); detail.setStationCode(input.getStationCode()); detail.setStationType(input.getStationType()); detail.setDetail(input.getDetail()); detail.setDataSource(input.getDataSource()); detail.setDelFlag(0); detail.setSyncTime(now); detail.setCreateTime(now); detail.setUpdateTime(now); mapper.insert(detail); return detail; } /** 根据设备类型和设备编号查询有效的能量链详情。 */ public List<EmindEnergyChainDetail> getByStationTypes(List<String> stationTypes) { return mapper.selectList(new LambdaQueryWrapper<EmindEnergyChainDetail>() .eq(EmindEnergyChainDetail::getDelFlag, 0) .in(EmindEnergyChainDetail::getStationType, stationTypes)); } @Transactional public void saveAll(UdanEmsDeviceState udanEmsDeviceState) { List<EmindEnergyChainDetail> detailList = new ArrayList<>(); // 保存BMS if(Objects.nonNull(udanEmsDeviceState.getTmsState())) { EmindEnergyChainDetail detail = new EmindEnergyChainDetail(); detail.setPlatformName("欧力特"); detail.setDataSource(2); detail.setStationCode(udanEmsDeviceState.getEmsSystemId()); detail.setDetail(JSON.toJSONString(udanEmsDeviceState.getTmsState())); detail.setStationId(udanEmsDeviceState.getTmsState().getDeviceId()); detail.setStationType("TMS"); detailList.add(detail); } if(Objects.nonNull(udanEmsDeviceState.getPcsState())) { EmindEnergyChainDetail detail = new EmindEnergyChainDetail(); detail.setPlatformName("欧力特"); detail.setDataSource(2); detail.setStationCode(udanEmsDeviceState.getEmsSystemId()); detail.setDetail(JSON.toJSONString(udanEmsDeviceState.getPcsState())); detail.setStationId(udanEmsDeviceState.getTmsState().getDeviceId()); detail.setStationType("PCS"); detailList.add(detail); } if(Objects.nonNull(udanEmsDeviceState.getElectricMeterState())) { EmindEnergyChainDetail detail = new EmindEnergyChainDetail(); detail.setPlatformName("欧力特"); detail.setDataSource(2); detail.setStationCode(udanEmsDeviceState.getEmsSystemId()); detail.setDetail(JSON.toJSONString(udanEmsDeviceState.getElectricMeterState())); detail.setStationId(udanEmsDeviceState.getTmsState().getDeviceId()); detail.setStationType("电表"); detailList.add(detail); } if(Objects.nonNull(udanEmsDeviceState.getBatteryStackState())) { EmindEnergyChainDetail detail = new EmindEnergyChainDetail(); detail.setPlatformName("欧力特"); detail.setDataSource(2); detail.setStationCode(udanEmsDeviceState.getEmsSystemId()); detail.setDetail(JSON.toJSONString(udanEmsDeviceState.getBatteryStackState())); detail.setStationId(udanEmsDeviceState.getTmsState().getDeviceId()); detail.setStationType("BMS"); detailList.add(detail); } detailList.forEach(d -> { mapper.delete(new QueryWrapper<EmindEnergyChainDetail>().eq("station_code", d.getStationCode()).eq("station_type", d.getStationType())); add(d); }); } } ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/emind/service/EmindEnergyChainManagementService.java
@@ -3,10 +3,12 @@ import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.ruoyi.other.emind.domain.EmindEnergyChain; import com.ruoyi.other.emind.domain.EmindEnergyChainDetail; import com.ruoyi.other.emind.domain.EmindStation; import com.ruoyi.other.emind.dto.EmindEnergyChainPageQuery; import com.ruoyi.other.emind.mapper.EmindEnergyChainMapper; import com.ruoyi.other.emind.mapper.EmindStationMapper; import org.apache.commons.collections4.CollectionUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -14,32 +16,49 @@ import java.time.Clock; import java.time.LocalDateTime; import java.util.List; import java.util.stream.Collectors; @Service public class EmindEnergyChainManagementService { private final EmindEnergyChainMapper mapper; private final EmindStationMapper stationMapper; private final Clock clock; private final EmindEnergyChainDetailService emindEnergyChainDetailService; @Autowired public EmindEnergyChainManagementService(EmindEnergyChainMapper mapper, EmindStationMapper stationMapper) { this(mapper, stationMapper, Clock.systemDefaultZone()); EmindStationMapper stationMapper, EmindEnergyChainDetailService emindEnergyChainDetailService) { this(mapper, stationMapper, Clock.systemDefaultZone(), emindEnergyChainDetailService); } EmindEnergyChainManagementService(EmindEnergyChainMapper mapper, EmindStationMapper stationMapper, Clock clock) { Clock clock, EmindEnergyChainDetailService emindEnergyChainDetailService) { this.mapper = mapper; this.stationMapper = stationMapper; this.clock = clock; this.emindEnergyChainDetailService = emindEnergyChainDetailService; } public IPage<EmindEnergyChain> page(EmindEnergyChainPageQuery query) { int pageNumber = query.getPageCurr() == null || query.getPageCurr() < 1 ? 1 : query.getPageCurr(); int pageSize = query.getPageSize() == null || query.getPageSize() < 1 ? 10 : Math.min(query.getPageSize(), 100); return mapper.selectManagementPage(Page.of(pageNumber, pageSize), query); IPage<EmindEnergyChain> pageData = mapper.selectManagementPage(Page.of(pageNumber, pageSize), query); if(CollectionUtils.isNotEmpty(pageData.getRecords())) { List<String> stationTypeList = pageData.getRecords().stream().filter(r -> "欧力特".equals(r.getPlatformName())).map(EmindEnergyChain::getStationType).collect(Collectors.toList()); if(CollectionUtils.isNotEmpty(stationTypeList)) { List<EmindEnergyChainDetail> chainDetails = emindEnergyChainDetailService.getByStationTypes(stationTypeList); if(CollectionUtils.isNotEmpty(chainDetails)) { pageData.getRecords().forEach(rd -> chainDetails.forEach(cd -> { if(cd.getStationType().equals(rd.getStationType())) { rd.setDetail(cd.getDetail()); } })); } } } return pageData; } @Transactional(rollbackFor = Exception.class) @@ -97,5 +116,6 @@ target.setElinkId(input.getElinkId()); target.setUuid(input.getUuid().trim()); target.setElinkName(input.getElinkName().trim()); target.setStationType(input.getStationType()); } } ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/emind/service/EmindEnergyChainSyncService.java
@@ -49,11 +49,13 @@ LocalDateTime syncedAt = LocalDateTime.now(clock); List<EmindEnergyChain> chains = new ArrayList<>(); for (EmindStation station : stations) { if(station.getSourceType() == 1) { List<EmindEnergyChainDto> remoteChains = api.getEnergyChains(station.getStationId()); for (EmindEnergyChainDto remote : remoteChains) { chains.add(toEntity(station, remote, syncedAt)); } } } chainMapper.markAllDeleted(syncedAt); if (!chains.isEmpty()) { chainMapper.upsertBatch(chains); ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/emind/service/EmindStationManagementService.java
@@ -38,7 +38,7 @@ public EmindStation add(EmindStation input) { LocalDateTime now = LocalDateTime.now(clock); EmindStation station = new EmindStation(); station.setStationId(input.getStationId() == null ? -System.currentTimeMillis() : input.getStationId()); station.setStationId(input.getStationId() == null ? System.currentTimeMillis() : input.getStationId()); station.setName(input.getName()); station.setAddress(input.getAddress()); station.setProvince(input.getProvince()); ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/service/impl/TStationCollectServiceImpl.java
@@ -349,6 +349,13 @@ fillDefaults(collect); insertList.add(collect); } // 设置电站名称 List<TStationInfo> infoList = stationInfoMapper.selectList(new LambdaQueryWrapper<>()); insertList.forEach(s -> infoList.forEach(info -> { if(StringUtils.isNotEmpty(s.getStationId()) && s.getStationId().equals(info.getStationId())) { s.setStationName(info.getStationName()); } })); return CollectionUtils.isNotEmpty(insertList) && saveBatch(insertList); } } ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/task/ExchangeCodeExpireTask.java
@@ -30,7 +30,7 @@ } /** * 每6小时执行科士达的数据同步 * 每6小时执行华为光伏的数据同步 */ @Scheduled(cron = "0 0 */6 * * ?") public void syncHuaWeiDataTask() { ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/udan/model/BatteryStackState.java
New file @@ -0,0 +1,39 @@ package com.ruoyi.other.udan.model; import lombok.Data; import java.io.Serializable; /** * 优旦储能-BMS 实时数据 * * @author Lux * @version 1.0.0 * @since 2026/9/26 16:23 */ @Data public class BatteryStackState implements Serializable { /** * 设备id */ private String deviceId; // 故障状态 private String errorStatus; private String workStatus; // 工作状态 private String warningStatus; // 告警状态 private Double tv; // 总电压 单位V private Double tc; // 总电流 单位A private Double soh; // soh 单位% private Double soc; // soc 单位% private Double rechargeableCapacityKwh; // 可充电量 单位kWh private Double dischargeableCapacityKwh; // 可放电量 单位kWh private Double cumulativeDischargeKwh; // 累计放电量 单位kWh private Double cumulativeChargeKwh; // 累计充电量 单位kWh private Double minCellVoltMv; // 单体最低电压 单位mV private Double maxCellVoltMv; // 单体最高电压 单位mV private Double avgCellTemp; // 电芯平均温度 保存需减40偏移量 } ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/udan/model/ElectricMeterState.java
New file @@ -0,0 +1,32 @@ package com.ruoyi.other.udan.model; import lombok.Data; import java.io.Serializable; /** * 优旦储能-电表实时数据 * * @author Lux * @version 1.0.0 * @since 2026/9/26 16:23 */ @Data public class ElectricMeterState implements Serializable { /** * 设备id */ private String deviceId; private Double aPhaseVolt; // A相电压 单位V private Double bPhaseVolt; // B相电压 单位V private Double cPhaseVolt; // C相电压 单位V private Double aPhaseCurrent; // A相电流 单位A private Double bPhaseCurrent; // B相电流 单位A private Double cPhaseCurrent; // C相电流 单位A private Double acTotalActivePower; // 总有功功率 单位KW private Double frequency; // 频率 单位Hz private Double acTotalPowerFactor; // 总交流功率因数 } ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/udan/model/PcsState.java
New file @@ -0,0 +1,59 @@ package com.ruoyi.other.udan.model; import lombok.Data; import java.io.Serializable; /** * 优旦储能-pcs实时数据 * * @author Lux * @version 1.0.0 * @since 2026/9/26 16:23 */ @Data public class PcsState implements Serializable { /** * 设备id */ private String deviceId; // 故障状态 private String errorStatus; // 告警状态 private String alarmStatus; // 运行状态 private String runStatus; // 并网状态 private String onGridStatus; // 有功功率A相 private Double aPhaseActivePower; // 有功功率B相 private Double bPhaseActivePower; // 有功功率C相 private Double cPhaseActivePower; // 总交流有功功率 private Double acTotalActivePower; // 日充电量 单位kWh private Double dailyChargeEnergyKwh; // 日放电量 单位kWh private Double dailyDischargeEnergyKwh; // 总充电量 单位kWh private Double totalChargeEnergyKwh; // 总放电量 单位kWh private Double totalDischargeEnergyKwh; } ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/udan/model/TmsState.java
New file @@ -0,0 +1,35 @@ package com.ruoyi.other.udan.model; import lombok.Data; import java.io.Serializable; /** * 优旦储能-TNS 实时数据 * * @author Lux * @version 1.0.0 * @since 2026/9/26 16:23 */ @Data public class TmsState implements Serializable { /** * 设备id */ private String deviceId; private String run_status; // 运行状态 private String error_status; // 故障状态 0 预留 1 故障 2 正常 private String compress_status; // 压缩机状态 private String compress_heat_status; // 压缩机加热带状态 private String electric_heat_status; // 电加热运行状态 private String pump_status; // 水泵状态 private String fan_status; // 风机运行状态 private Double supply_temp; // 供液温度 private Double return_temp; // 回液温度 private Double env_temp; // 环境温度 private Double backwater_press; // 回水压力 回液压力 private Double out_water_press; // 出水压力 供液压力 } ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/udan/model/UdanEmsDeviceState.java
@@ -21,6 +21,11 @@ private EmsState emsState; private PowerMeterState powerMeterState; private TmsState tmsState; private PcsState pcsState; private ElectricMeterState electricMeterState; private BatteryStackState batteryStackState; public List<EmindIncomeHistoryDto> convert(Long stationId) { List<EmindIncomeHistoryDto> dailyList = new ArrayList<>(); ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/udan/service/UdanEmsMessageProcessor.java
@@ -7,20 +7,29 @@ import com.ruoyi.other.emind.dto.EmindIncomeHistoryDto; import com.ruoyi.other.emind.mapper.EmindStationMapper; import com.ruoyi.other.emind.mapper.EmindStorageDashboardMapper; import com.ruoyi.other.emind.service.EmindEnergyChainDetailService; import com.ruoyi.other.udan.model.EmsState; import com.ruoyi.other.udan.model.BatteryStackState; import com.ruoyi.other.udan.model.ElectricMeterState; import com.ruoyi.other.udan.model.PcsState; import com.ruoyi.other.udan.model.PowerMeterState; import com.ruoyi.other.udan.model.TmsState; import com.ruoyi.other.udan.model.UdanEmsDeviceState; import com.ruoyi.other.udan.util.UdanEmsKafkaUtil; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.StringUtils; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.stereotype.Component; import javax.annotation.PostConstruct; import java.io.IOException; import java.time.LocalDate; import java.time.LocalDateTime; import java.util.List; import java.util.Objects; import java.util.Set; import java.util.stream.Collectors; /** 将 IEmsAllDeviceState 中模型已有的 EMS 和能耗计字段转换为业务对象。 */ @Slf4j @@ -30,11 +39,13 @@ private final UdanEmsKafkaUtil kafkaUtil; private final EmindStorageDashboardMapper dashboardMapper; private final EmindStationMapper stationMapper; private final EmindEnergyChainDetailService emindEnergyChainDetailService; public UdanEmsMessageProcessor(UdanEmsKafkaUtil kafkaUtil, EmindStorageDashboardMapper dashboardMapper, EmindStationMapper stationMapper) { public UdanEmsMessageProcessor(UdanEmsKafkaUtil kafkaUtil, EmindStorageDashboardMapper dashboardMapper, EmindStationMapper stationMapper, EmindEnergyChainDetailService emindEnergyChainDetailService) { this.kafkaUtil = kafkaUtil; this.dashboardMapper = dashboardMapper; this.stationMapper = stationMapper; this.emindEnergyChainDetailService = emindEnergyChainDetailService; } @PostConstruct @@ -52,10 +63,19 @@ EmindStation station = stations.stream().filter(s -> udanEmsDeviceState.getEmsDeviceId().equals(s.getStationCode())).findFirst().orElse(null); if(Objects.nonNull(station)) { List<EmindIncomeHistoryDto> daily = udanEmsDeviceState.convert(station.getStationId()); dashboardMapper.upsertDaily(station.getStationId(), daily, now); }else{ log.info("UDAN EMS数据同步错误-电站信息不存在!"); Set<LocalDate> dateSet = daily.stream().map(EmindIncomeHistoryDto::getDate).collect(Collectors.toSet()); // 删除电站下该天已存在的旧数据 if(CollectionUtils.isNotEmpty(dateSet)) { dashboardMapper.deleteByStationIdDay(station.getStationId(), dateSet); } if(CollectionUtils.isNotEmpty(daily)) { dashboardMapper.upsertDaily(station.getStationId(), daily, now); } }else{ log.error("UDAN EMS数据同步错误-电站信息不存在!"); } // 保存设备其它信息 emindEnergyChainDetailService.saveAll(udanEmsDeviceState); } } catch (IOException e) { @@ -76,7 +96,19 @@ read(bytes, (field, type, in) -> { if (field == 1 && type == 0) state.setTime(in.readUInt64()); else if (type == 2 && field == 2) state.setEmsState(parseEms(in.readBytes().toByteArray())); else if (type == 2 && field == 4 && state.getPcsState() == null) { state.setPcsState(parsePcs(in.readBytes().toByteArray())); } else if (type == 2 && field == 5 && state.getBatteryStackState() == null) { state.setBatteryStackState(parseBatteryStack(in.readBytes().toByteArray())); } else if (type == 2 && field == 7 && state.getElectricMeterState() == null) { state.setElectricMeterState(parseElectricMeter(in.readBytes().toByteArray())); } else if (type == 2 && field == 8) state.setPowerMeterState(parsePowerMeter(in.readBytes().toByteArray())); else if (type == 2 && field == 14 && state.getTmsState() == null) { state.setTmsState(parseTms(in.readBytes().toByteArray())); } else skip(in, type); }); return state; @@ -189,6 +221,96 @@ return value; } private PcsState parsePcs(byte[] bytes) throws IOException { PcsState value = new PcsState(); read(bytes, (field, type, input) -> { switch (field) { case 2: value.setDeviceId(str(input, type)); break; case 3: value.setErrorStatus(enumName(input, type, "ErrorStatus")); break; case 4: value.setAlarmStatus(enumName(input, type, "AlarmStatus")); break; case 5: value.setRunStatus(enumName(input, type, "RunStatus")); break; case 6: value.setOnGridStatus(enumName(input, type, "GridStatus")); break; case 13: value.setAcTotalActivePower((double) f32(input, type)); break; case 17: value.setDailyChargeEnergyKwh((double) f32(input, type)); break; case 18: value.setDailyDischargeEnergyKwh((double) f32(input, type)); break; case 19: value.setTotalChargeEnergyKwh(f64(input, type)); break; case 20: value.setTotalDischargeEnergyKwh(f64(input, type)); break; case 31: value.setAPhaseActivePower((double) f32(input, type)); break; case 34: value.setBPhaseActivePower((double) f32(input, type)); break; case 37: value.setCPhaseActivePower((double) f32(input, type)); break; default: skip(input, type); } }); return value; } private BatteryStackState parseBatteryStack(byte[] bytes) throws IOException { BatteryStackState value = new BatteryStackState(); read(bytes, (field, type, input) -> { switch (field) { case 2: value.setDeviceId(str(input, type)); break; case 4: value.setWorkStatus(enumName(input, type, "BatteryWorkStatus")); break; case 5: value.setErrorStatus(enumName(input, type, "ErrorStatus")); break; case 6: value.setWarningStatus(enumName(input, type, "AlarmStatus")); break; case 7: value.setTv((double) f32(input, type)); break; case 8: value.setTc((double) f32(input, type)); break; case 9: value.setSoh((double) f32(input, type)); break; case 10: value.setSoc((double) f32(input, type)); break; case 15: value.setMinCellVoltMv((double) u32(input, type)); break; case 23: value.setMaxCellVoltMv((double) u32(input, type)); break; case 31: value.setRechargeableCapacityKwh((double) f32(input, type)); break; case 32: value.setDischargeableCapacityKwh((double) f32(input, type)); break; case 33: value.setCumulativeDischargeKwh(f64(input, type)); break; case 34: value.setCumulativeChargeKwh(f64(input, type)); break; case 36: value.setAvgCellTemp((double) u32(input, type) - 40D); break; default: skip(input, type); } }); return value; } private ElectricMeterState parseElectricMeter(byte[] bytes) throws IOException { ElectricMeterState value = new ElectricMeterState(); read(bytes, (field, type, input) -> { switch (field) { case 2: value.setDeviceId(str(input, type)); break; case 48: value.setAPhaseVolt((double) f32(input, type)); break; case 49: value.setBPhaseVolt((double) f32(input, type)); break; case 50: value.setCPhaseVolt((double) f32(input, type)); break; case 51: value.setAPhaseCurrent((double) f32(input, type)); break; case 52: value.setBPhaseCurrent((double) f32(input, type)); break; case 53: value.setCPhaseCurrent((double) f32(input, type)); break; case 54: value.setAcTotalActivePower((double) f32(input, type)); break; case 69: value.setFrequency((double) f32(input, type)); break; case 74: value.setAcTotalPowerFactor((double) f32(input, type)); break; default: skip(input, type); } }); return value; } private TmsState parseTms(byte[] bytes) throws IOException { TmsState value = new TmsState(); read(bytes, (field, type, input) -> { switch (field) { case 1: value.setDeviceId(str(input, type)); break; case 2: value.setRun_status(enumName(input, type, "TmsRunStatus")); break; case 3: value.setError_status(enumName(input, type, "ErrorStatus")); break; case 4: value.setSupply_temp((double) f32(input, type)); break; case 5: value.setReturn_temp((double) f32(input, type)); break; case 8: value.setEnv_temp((double) f32(input, type)); break; case 9: value.setBackwater_press((double) f32(input, type)); break; case 10: value.setOut_water_press((double) f32(input, type)); break; case 13: value.setCompress_status(enumName(input, type, "RunStatus")); break; case 14: value.setCompress_heat_status(enumName(input, type, "RunStatus")); break; case 15: value.setElectric_heat_status(enumName(input, type, "RunStatus")); break; case 16: value.setPump_status(enumName(input, type, "RunStatus")); break; default: skip(input, type); } }); return value; } private void read(byte[] bytes, Reader reader) throws IOException { CodedInputStream input = CodedInputStream.newInstance(bytes == null ? new byte[0] : bytes); while (!input.isAtEnd()) { @@ -250,6 +372,18 @@ if ("CommStatus".equals(prefix)) { return new String[]{"COMM_STATUS_UNKNOWN", "COMM_STATUS_DISCONNECTED", "COMM_STATUS_CONNECTED"}[number < 0 || number > 2 ? 0 : number]; } if ("ErrorStatus".equals(prefix)) { return new String[]{"ERROR_STATUS_UNKNOWN", "ERROR_STATUS_OCCURRING", "ERROR_STATUS_NONE"}[number < 0 || number > 2 ? 0 : number]; } if ("AlarmStatus".equals(prefix)) { return new String[]{"ALARM_STATUS_UNKNOWN", "ALARM_STATUS_OCCURRING", "ALARM_STATUS_NONE"}[number < 0 || number > 2 ? 0 : number]; } if ("BatteryWorkStatus".equals(prefix)) { return new String[]{"BATTERY_WORK_STATUS_UNKNOWN", "BATTERY_WORK_STATUS_CHARGING", "BATTERY_WORK_STATUS_DISCHARGING", "BATTERY_WORK_STATUS_IDLE"}[number < 0 || number > 3 ? 0 : number]; } if ("TmsRunStatus".equals(prefix)) { return new String[]{"TMS_RUN_STATUS_UNKNOWN", "TMS_RUN_STATUS_IDLE", "TMS_RUN_STATUS_READY_TO_START", "TMS_RUN_STATUS_RUNNING", "TMS_RUN_STATUS_DELAYED_SHUTDOWN", "TMS_RUN_STATUS_SELF_TEST", "TMS_RUN_STATUS_ALARMING"}[number < 0 || number > 6 ? 0 : number]; } return prefix + "_" + number; } private static <T> T enumAt(T[] values, CodedInputStream input, int type) throws IOException { ruoyi-service/ruoyi-other/src/main/resources/mapper/other/EmindEnergyChainMapper.xml
@@ -26,6 +26,7 @@ <result column="synced_at" property="syncedAt"/> <result column="platform_name" property="platformName"/> <result column="data_status" property="dataStatus"/> <result column="station_type" property="stationType"/> </resultMap> <update id="markAllDeleted"> @@ -77,7 +78,7 @@ chain.phase_a_current, chain.phase_b_current, chain.phase_c_current, chain.dischargeable_energy, chain.soc, chain.charged_energy_today, chain.discharged_energy_today, chain.record_time, chain.synced_at, chain.source_type, chain.management_deleted, chain.source_type, chain.management_deleted, chain.station_type, station.platform_name, CASE WHEN chain.record_time IS NULL OR chain.record_time = '' THEN 0 ELSE 1 END AS data_status FROM t_emind_energy_chain chain ruoyi-service/ruoyi-other/src/main/resources/mapper/other/EmindStationMapper.xml
@@ -79,9 +79,9 @@ <select id="selectRemoteActiveStations" resultMap="stationResultMap"> SELECT id, station_id, name, address, province, city, longitude, latitude, max_power, capacity, commissioning_time, platform_name, source_type, management_deleted, del_flag, synced_at, create_time, update_time management_deleted, del_flag, synced_at, create_time, update_time, station_code FROM t_emind_station WHERE source_type = 1 AND del_flag = 0 AND management_deleted = 0 WHERE del_flag = 0 AND management_deleted = 0 ORDER BY id </select> </mapper> ruoyi-service/ruoyi-other/src/main/resources/mapper/other/EmindStorageDashboardMapper.xml
@@ -79,4 +79,9 @@ <if test="stationId != null">AND block.station_id=#{stationId}</if> <if test="platformNames != null and platformNames.size() > 0">AND snapshot.platform_name IN <foreach collection="platformNames" item="name" open="(" separator="," close=")">#{name}</foreach></if> </select> <select id="deleteByStationIdDay"> delete from t_emind_dashboard_daily where station_id=#{stationId} and stat_date in <foreach collection="dateSet" item="dateValue" open="(" separator="," close=")">#{dateValue}</foreach> </select> </mapper> ruoyi-service/ruoyi-other/src/main/resources/sql/t_screen_content_alter.sql
@@ -1,8 +1,30 @@ -- ---------------------------- -- 1、增加大屏名称配置字段 alter table t_screen_content add column screen_name varchar(255) default 'NULL' null comment '大屏名称'; alter table t_screen_content add column screen_name varchar(255) default '' null comment '大屏名称'; -- 2、增加储能电站表设备编号 alter table t_emind_station add column station_code varchar(255) default 'NULL' null comment '设备编号'; alter table t_emind_station add column station_code varchar(255) default '' null comment '设备编号'; ALTER TABLE t_emind_dashboard_daily MODIFY COLUMN id BIGINT NOT NULL AUTO_INCREMENT comment '主键ID'; -- 3、储能能量连表增加(设备类型) alter table t_emind_energy_chain add column station_type varchar(255) default '' null comment '设备类型'; -- 增加能量链详情表 create table t_emind_energy_chain_detail ( id bigint auto_increment comment '主键ID' primary key, platform_name varchar(100) null comment '所属平台(利普芯、欧力特)', station_code varchar(255) null comment '设备编号', station_id varchar(255) null comment '设备ID', station_type varchar(255) null comment '设备类型(与能量链里面的设备类型进行关联)', detail text null comment '设备详情json字段', data_source int null comment '数据来源(1系统创建,2第三方接口)', create_time datetime null comment '创建时间', sync_time datetime null comment '同步时间', update_time datetime null comment '更新时间', del_flag char default '0' not null comment '删除标志(0存在 2删除)' ) comment '能量链详情表' collate = utf8mb4_bin;