集成modbus连接本地设备读取数据代码-配置文件方式读取;

PCS开关机功能通过modbus连接设备发送控制命令;
This commit is contained in:
zq
2025-12-19 11:38:04 +08:00
parent 16d414f092
commit ff487f1b05
26 changed files with 1286 additions and 216 deletions

View File

@ -1,12 +1,14 @@
package com.xzzn.ems.domain;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.xzzn.common.annotation.Excel;
import com.xzzn.common.core.domain.BaseEntity;
import java.math.BigDecimal;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.xzzn.common.core.domain.BaseEntity;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import com.xzzn.common.annotation.Excel;
/**
* 单体电池实时数据对象 ems_battery_data
@ -70,6 +72,10 @@ public class EmsBatteryData extends BaseEntity
@Excel(name = "单体电池内阻")
private BigDecimal interResistance;
/** 单体电池电流 */
@Excel(name = "单体电池电流")
private BigDecimal current;
public void setId(Long id)
{
this.id = id;
@ -200,6 +206,14 @@ public class EmsBatteryData extends BaseEntity
return interResistance;
}
public BigDecimal getCurrent() {
return current;
}
public void setCurrent(BigDecimal current) {
this.current = current;
}
@Override
public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
@ -221,6 +235,7 @@ public class EmsBatteryData extends BaseEntity
.append("deviceId", getDeviceId())
.append("clusterDeviceId", getClusterDeviceId())
.append("interResistance", getInterResistance())
.append("current", getCurrent())
.toString();
}
}

View File

@ -1,12 +1,14 @@
package com.xzzn.ems.domain;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.xzzn.common.annotation.Excel;
import com.xzzn.common.core.domain.BaseEntity;
import java.math.BigDecimal;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.xzzn.common.core.domain.BaseEntity;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import com.xzzn.common.annotation.Excel;
/**
* PCS数据对象 ems_pcs_data
@ -34,8 +36,8 @@ public class EmsPcsData extends BaseEntity
@Excel(name = "并网状态0-并网 1-未并网")
private String gridStatus;
/** 设备状态0-在线 1-离线 2-维修中 */
@Excel(name = "设备状态0-在线 1-离线 2-维修中")
/** 设备运行状态0-离线、1-待机、2-运行、3-故障、4-停机 */
@Excel(name = "设备运行状态0-离线、1-待机、2-运行、3-故障、4-停机")
private String deviceStatus;
/** 控制模式0-远程 1-本地 */
@ -234,6 +236,22 @@ public class EmsPcsData extends BaseEntity
@Excel(name = "4#模块IGBT最高温")
private BigDecimal module4Temp;
/** 电池簇1PCS有功功率给定 */
@Excel(name = "电池簇1PCS有功功率给定")
private BigDecimal cluster1ActivePower;
/** 电池簇2PCS有功功率给定 */
@Excel(name = "电池簇2PCS有功功率给定")
private BigDecimal cluster2ActivePower;
/** 电池簇3PCS有功功率给定 */
@Excel(name = "电池簇3PCS有功功率给定")
private BigDecimal cluster3ActivePower;
/** 电池簇4PCS有功功率给定 */
@Excel(name = "电池簇4PCS有功功率给定")
private BigDecimal cluster4ActivePower;
public void setId(Long id)
{
this.id = id;
@ -774,6 +792,38 @@ public class EmsPcsData extends BaseEntity
return module4Temp;
}
public BigDecimal getCluster1ActivePower() {
return cluster1ActivePower;
}
public void setCluster1ActivePower(BigDecimal cluster1ActivePower) {
this.cluster1ActivePower = cluster1ActivePower;
}
public BigDecimal getCluster2ActivePower() {
return cluster2ActivePower;
}
public void setCluster2ActivePower(BigDecimal cluster2ActivePower) {
this.cluster2ActivePower = cluster2ActivePower;
}
public BigDecimal getCluster3ActivePower() {
return cluster3ActivePower;
}
public void setCluster3ActivePower(BigDecimal cluster3ActivePower) {
this.cluster3ActivePower = cluster3ActivePower;
}
public BigDecimal getCluster4ActivePower() {
return cluster4ActivePower;
}
public void setCluster4ActivePower(BigDecimal cluster4ActivePower) {
this.cluster4ActivePower = cluster4ActivePower;
}
@Override
public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
@ -836,6 +886,10 @@ public class EmsPcsData extends BaseEntity
.append("module2Temp", getModule2Temp())
.append("module3Temp", getModule3Temp())
.append("module4Temp", getModule4Temp())
.append("cluster1ActivePower", getCluster1ActivePower())
.append("cluster2ActivePower", getCluster2ActivePower())
.append("cluster3ActivePower", getCluster3ActivePower())
.append("cluster4ActivePower", getCluster4ActivePower())
.toString();
}
}

View File

@ -1,5 +1,7 @@
package com.xzzn.ems.domain.vo;
import java.util.List;
import javax.validation.constraints.NotBlank;
/**
@ -22,6 +24,10 @@ public class DeviceUpdateRequest {
/** 设备类型 */
private String deviceCategory;
/** 设备点位数据匹配表字段 */
private List<String> matchFields;
public String getSiteId() {
return siteId;
}
@ -53,4 +59,12 @@ public class DeviceUpdateRequest {
public void setDeviceCategory(String deviceCategory) {
this.deviceCategory = deviceCategory;
}
public List<String> getMatchFields() {
return matchFields;
}
public void setMatchFields(List<String> matchFields) {
this.matchFields = matchFields;
}
}

View File

@ -1,15 +1,15 @@
package com.xzzn.ems.mapper;
import com.xzzn.ems.domain.EmsPointMatch;
import com.xzzn.ems.domain.vo.DevicePointMatchExportVo;
import com.xzzn.ems.domain.vo.DeviceUpdateRequest;
import com.xzzn.ems.domain.vo.GeneralQueryDataVo;
import com.xzzn.ems.domain.vo.PointQueryResponse;
import java.util.Date;
import java.util.List;
import java.util.Map;
import com.xzzn.ems.domain.EmsPointMatch;
import com.xzzn.ems.domain.vo.DevicePointMatchExportVo;
import com.xzzn.ems.domain.vo.DevicePointMatchVo;
import com.xzzn.ems.domain.vo.DeviceUpdateRequest;
import com.xzzn.ems.domain.vo.GeneralQueryDataVo;
import com.xzzn.ems.domain.vo.PointQueryResponse;
import org.apache.ibatis.annotations.Param;
/**
@ -171,5 +171,5 @@ public interface EmsPointMatchMapper
int getDevicePointAlarmNum(@Param("siteId") String siteId, @Param("deviceId") String deviceId, @Param("deviceCategory") String deviceCategory);
EmsPointMatch selectDeviceStatusPoint(@Param("request") DeviceUpdateRequest request);
List<EmsPointMatch> selectDeviceStatusPoint(@Param("request") DeviceUpdateRequest request);
}

View File

@ -161,32 +161,37 @@ public class DeviceDataProcessServiceImpl extends AbstractBatteryDataProcessor i
// 存放每次同步数据,失效时间(同同步时间)-用于判断是否正常同步数据
redisCache.setCacheObject(RedisKeyConstants.SYNC_DATA + siteId + "_" + deviceId, obj, 1, TimeUnit.MINUTES);
if (deviceId.contains(SiteDevice.BMSD.name())) {
batteryStackDataProcess(siteId, deviceId, jsonData, dataUpdateTime);
batteryGroupDataProcess(siteId, deviceId, jsonData);
batteryDataProcessFromBmsd(siteId, deviceId, jsonData, dataUpdateTime);
} else if (deviceId.contains(SiteDevice.BMSC.name())) {
batteryClusterDataProcess(siteId, deviceId, jsonData, dataUpdateTime);
batteryDataProcessFromBmsc(siteId, deviceId, jsonData, dataUpdateTime);
} else if (deviceId.contains(SiteDevice.PCS.name())) {
pcsDataProcess(siteId, deviceId, jsonData, dataUpdateTime);
pcsBranchDataProcess(siteId, deviceId, jsonData);
batteryClusterDataProcess(siteId, jsonData, dataUpdateTime);
} else if (deviceId.contains(SiteDevice.LOAD.name())) {
loadDataProcess(siteId, deviceId, jsonData, dataUpdateTime);
} else if (deviceId.contains(SiteDevice.METEGF.name())
|| deviceId.contains(SiteDevice.METE.name())
|| deviceId.contains(SiteDevice.METE0.name())) {
meteDataProcess(siteId, deviceId, jsonData, dataUpdateTime);
} else if (deviceId.contains(SiteDevice.XF.name())) {
meteXFProcess(siteId, deviceId, jsonData, dataUpdateTime);
} else if (deviceId.contains(SiteDevice.DH.name()) || deviceId.contains(SiteDevice.donghuan.name())) {
dhDataProcess(siteId, deviceId, jsonData, dataUpdateTime);
} else if (deviceId.contains(SiteDevice.ZSLQ.name())) {
coolingDataProcess(siteId, deviceId, jsonData, dataUpdateTime);
} else if (deviceId.contains(SiteDevice.EMS.name())) {
emsDataProcess(siteId, deviceId, jsonData, dataUpdateTime);
}
// 处理设备数据
processingDeviceData(siteId, deviceId, jsonData, dataUpdateTime);
}
}
public void processingDeviceData(String siteId, String deviceId, String jsonData, Date dataUpdateTime) {
if (deviceId.contains(SiteDevice.BMSD.name())) {
batteryStackDataProcess(siteId, deviceId, jsonData, dataUpdateTime);
batteryGroupDataProcess(siteId, deviceId, jsonData);
batteryDataProcessFromBmsd(siteId, deviceId, jsonData, dataUpdateTime);
} else if (deviceId.contains(SiteDevice.BMSC.name())) {
batteryClusterDataProcess(siteId, deviceId, jsonData, dataUpdateTime);
batteryDataProcessFromBmsc(siteId, deviceId, jsonData, dataUpdateTime);
} else if (deviceId.contains(SiteDevice.PCS.name())) {
pcsDataProcess(siteId, deviceId, jsonData, dataUpdateTime);
pcsBranchDataProcess(siteId, deviceId, jsonData);
batteryClusterDataProcess(siteId, jsonData, dataUpdateTime);
} else if (deviceId.contains(SiteDevice.LOAD.name())) {
loadDataProcess(siteId, deviceId, jsonData, dataUpdateTime);
} else if (deviceId.contains(SiteDevice.METEGF.name())
|| deviceId.contains(SiteDevice.METE.name())
|| deviceId.contains(SiteDevice.METE0.name())) {
meteDataProcess(siteId, deviceId, jsonData, dataUpdateTime);
} else if (deviceId.contains(SiteDevice.XF.name())) {
meteXFProcess(siteId, deviceId, jsonData, dataUpdateTime);
} else if (deviceId.contains(SiteDevice.DH.name()) || deviceId.contains(SiteDevice.donghuan.name())) {
dhDataProcess(siteId, deviceId, jsonData, dataUpdateTime);
} else if (deviceId.contains(SiteDevice.ZSLQ.name())) {
coolingDataProcess(siteId, deviceId, jsonData, dataUpdateTime);
} else if (deviceId.contains(SiteDevice.EMS.name())) {
emsDataProcess(siteId, deviceId, jsonData, dataUpdateTime);
}
}
@ -249,14 +254,14 @@ public class DeviceDataProcessServiceImpl extends AbstractBatteryDataProcessor i
}
private void meteXFProcess(String siteId, String deviceId, String dataJson, Date dataUpdateTime) {
public void meteXFProcess(String siteId, String deviceId, String dataJson, Date dataUpdateTime) {
//消防
Map<String, Object> obj = JSON.parseObject(dataJson, new TypeReference<Map<String, Object>>() {
});
// 点位匹配数据
List<EmsPointMatch> pointMatchList = devicePointMatchDataProcessor.getDevicePointMatch(siteId, deviceId, DeviceMatchTable.XF.getCode());
if (CollectionUtils.isEmpty(pointMatchList)) {
log.info("未找到匹配的点位数据,无法处理动环数据siteId: " + siteId + "deviceId: " + deviceId);
log.info("未找到匹配的点位数据,无法处理消防数据siteId: " + siteId + "deviceId: " + deviceId);
return;
}
Map<String, List<EmsPointEnumMatch>> pointEnumMatchMap = devicePointMatchDataProcessor.getPointEnumMatchMap(siteId, DeviceMatchTable.XF.getCode());
@ -1415,20 +1420,8 @@ public class DeviceDataProcessServiceImpl extends AbstractBatteryDataProcessor i
redisCache.setCacheObject(RedisKeyConstants.ORIGINAL_MQTT_DATA_ALARM + siteId + "_" + deviceId, obj);
// 存放每次同步数据,失效时间(同同步时间)-用于判断是否正常同步数据
redisCache.setCacheObject(RedisKeyConstants.SYNC_DATA_ALARM + siteId + "_" + deviceId, obj, 1, TimeUnit.MINUTES);
String deviceCategory = "";
if (deviceId.contains(SiteDevice.ZSLQ.name())) {
coolingAlarmDataProcess(siteId, deviceId, jsonData, dataUpdateTime);
} else if (deviceId.contains(SiteDevice.BMSD.name())) {
deviceCategory = DeviceCategory.STACK.getCode();
stackAlarmDataProcess(siteId, deviceId, jsonData, dataUpdateTime);
} else if (deviceId.contains(SiteDevice.BMSC.name())) {
deviceCategory = DeviceCategory.CLUSTER.getCode();
clusterAlarmDataProcess(siteId, deviceId, jsonData, dataUpdateTime);
} else if (deviceId.contains(SiteDevice.PCS.name())) {
deviceCategory = DeviceCategory.PCS.getCode();
pcsAlarmDataProcess(siteId, deviceId, jsonData, dataUpdateTime);
}
// 处理设备数据,根据不同设备类型进行不同的数据处理
String deviceCategory = processingDeviceAlarmData(siteId, deviceId, jsonData, dataUpdateTime);
if (StringUtils.isEmpty(deviceCategory)) {
// 处理告警信息
alarmDataProcess(siteId, deviceId, jsonData, alarmMatchInfo, deviceCategory);
@ -1436,6 +1429,24 @@ public class DeviceDataProcessServiceImpl extends AbstractBatteryDataProcessor i
}
}
public String processingDeviceAlarmData(String siteId, String deviceId, String jsonData, Date dataUpdateTime) {
String deviceCategory = "";
if (deviceId.contains(SiteDevice.ZSLQ.name())) {
coolingAlarmDataProcess(siteId, deviceId, jsonData, dataUpdateTime);
} else if (deviceId.contains(SiteDevice.BMSD.name())) {
deviceCategory = DeviceCategory.STACK.getCode();
stackAlarmDataProcess(siteId, deviceId, jsonData, dataUpdateTime);
} else if (deviceId.contains(SiteDevice.BMSC.name())) {
deviceCategory = DeviceCategory.CLUSTER.getCode();
clusterAlarmDataProcess(siteId, deviceId, jsonData, dataUpdateTime);
} else if (deviceId.contains(SiteDevice.PCS.name())) {
deviceCategory = DeviceCategory.PCS.getCode();
pcsAlarmDataProcess(siteId, deviceId, jsonData, dataUpdateTime);
}
return deviceCategory;
}
private void pcsAlarmDataProcess(String siteId, String deviceId, String jsonData, Date dataUpdateTime) {
//pcs
Map<String, Object> obj = JSON.parseObject(jsonData, new TypeReference<Map<String, Object>>() {

View File

@ -4,15 +4,19 @@ import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.alibaba.fastjson2.TypeReference;
import com.xzzn.common.constant.RedisKeyConstants;
import com.xzzn.common.core.modbus.ModbusProcessor;
import com.xzzn.common.core.modbus.domain.DeviceConfig;
import com.xzzn.common.core.modbus.domain.WriteTagConfig;
import com.xzzn.common.core.redis.RedisCache;
import com.xzzn.common.enums.DeviceCategory;
import com.xzzn.common.enums.DeviceRunningStatus;
import com.xzzn.common.enums.DeviceType;
import com.xzzn.common.enums.PcsControlCommand;
import com.xzzn.common.enums.PointType;
import com.xzzn.common.enums.SiteEnum;
import com.xzzn.common.exception.ServiceException;
import com.xzzn.common.utils.DateUtils;
import com.xzzn.common.utils.StringUtils;
import com.xzzn.common.utils.file.ImageUtils;
import com.xzzn.ems.domain.EmsDevicesSetting;
import com.xzzn.ems.domain.EmsPointMatch;
import com.xzzn.ems.domain.vo.DeviceUpdateRequest;
@ -23,15 +27,22 @@ import com.xzzn.ems.mapper.EmsDevicesSettingMapper;
import com.xzzn.ems.mapper.EmsPointMatchMapper;
import com.xzzn.ems.service.IEmsDeviceSettingService;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import org.springframework.util.CollectionUtils;
/**
* 站点信息 服务层实现
@ -43,6 +54,8 @@ public class EmsDeviceSettingServiceImpl implements IEmsDeviceSettingService
private static final Logger log = LoggerFactory.getLogger(EmsDeviceSettingServiceImpl.class);
private static final String DDS_SITE_ID = "021_DDS_01";
private static final String DEVICE_STATUS_FIELD = "device_status";
private static final List<String> CLUSTER_ACTIVE_POWER_FIELDS = Arrays.asList("cluster1_active_power", "cluster2_active_power", "cluster3_active_power", "cluster4_active_power");
@Autowired
private EmsDevicesSettingMapper emsDevicesMapper;
@ -54,6 +67,8 @@ public class EmsDeviceSettingServiceImpl implements IEmsDeviceSettingService
private EmsBatteryDataMinutesMapper emsBatteryDataMinutesMapper;
@Autowired
private EmsBatteryClusterServiceImpl emsBatteryClusterServiceImpl;
@Autowired
private ModbusProcessor modbusProcessor;
/**
* 获取设备详细信息
@ -486,11 +501,13 @@ public class EmsDeviceSettingServiceImpl implements IEmsDeviceSettingService
throw new ServiceException("未找到对应设备配置信息");
}
// 查询设备配置的设备状态对应点位
// request.setDeviceCategory(DeviceCategory.PCS.getCode());
// EmsPointMatch pointMatch = emsPointMatchMapper.selectDeviceStatusPoint(request);
// if (pointMatch == null) {
// throw new ServiceException("未找到对应设备状态点位");
// }
CLUSTER_ACTIVE_POWER_FIELDS.add(DEVICE_STATUS_FIELD);
request.setMatchFields(CLUSTER_ACTIVE_POWER_FIELDS);
request.setDeviceCategory(DeviceCategory.PCS.getCode());
List<EmsPointMatch> pointMatchList = emsPointMatchMapper.selectDeviceStatusPoint(request);
if (CollectionUtils.isEmpty(pointMatchList) || pointMatchList.stream().noneMatch(point -> DEVICE_STATUS_FIELD.equals(point.getMatchField()))) {
throw new ServiceException("未找到对应设备状态点位");
}
if (DeviceRunningStatus.getShutdownCodeList().contains(request.getDeviceStatus())) {
// 开机逻辑
device.setDeviceStatus(DeviceRunningStatus.RUNNING.getCode());
@ -500,10 +517,50 @@ public class EmsDeviceSettingServiceImpl implements IEmsDeviceSettingService
} else {
return false;
}
// TODO 调用Modbus向设备发送指
// 根据设备类型和请求状态确定控制命
PcsControlCommand command = PcsControlCommand.fromDeviceStatus(device.getDeviceStatus());
if (command == null) {
throw new ServiceException("不支持的设备状态操作");
}
// 调用Modbus向设备发送指令
DeviceConfig deviceConfig = getDeviceConfig(device);
deviceConfig.setWriteTags(getWriteTags(device, pointMatchList, command));
log.info("设备控制指令发送数据: {}", JSON.toJSONString(deviceConfig));
boolean result = modbusProcessor.writeDataToDevice(deviceConfig);
if (!result) {
throw new ServiceException("设备控制指令发送失败");
}
device.setUpdatedAt(DateUtils.getNowDate());
emsDevicesMapper.updateEmsDevicesSetting(device);
return true;
}
public DeviceConfig getDeviceConfig(EmsDevicesSetting device) {
DeviceConfig deviceConfig = new DeviceConfig();
deviceConfig.setDeviceNumber(device.getDeviceId());
deviceConfig.setDeviceName(device.getDeviceName());
deviceConfig.setSlaveId(device.getSlaveId().intValue());
if (DeviceType.TCP.name().equals(device.getDeviceType())) {
deviceConfig.setHost(device.getIpAddress());
deviceConfig.setPort(device.getIpPort().intValue());
}
return deviceConfig;
}
public List<WriteTagConfig> getWriteTags(EmsDevicesSetting device, List<EmsPointMatch> pointMatchList, PcsControlCommand command) {
List<WriteTagConfig> writeTags = new ArrayList<>();
for (EmsPointMatch pointMatch : pointMatchList) {
WriteTagConfig writeTag = new WriteTagConfig();
writeTag.setAddress(pointMatch.getIpAddress());
if (DEVICE_STATUS_FIELD.equals(pointMatch.getMatchField())) {
writeTag.setValue(command.getCode());
} else {
// 电池簇PCS有功功率给定置0
writeTag.setValue(0);
}
writeTags.add(writeTag);
}
return writeTags;
}
}