Compare commits

...

74 Commits

Author SHA1 Message Date
huangfeng 3f71d05990 feat: 调整温度采集和保存 3 hours ago
huangfeng 8d64ad8e57 feat: 增加海康长连接采集温度并保存入库功能 5 hours ago
huangfeng 1429d53c02 feat: 增加海康库初始化和登入设备功能 8 hours ago
huangfeng 242250b18e build: 删除大华sdk,增加海康sdk 10 hours ago
huangfeng 334d317679 perf: 优化测温采集的统一流程 10 hours ago
huangfeng d06a31a75e feat: 104服务端根据点位配置发送统招数据 2 days ago
huangfeng e5f35cffd8 feat: 增加点表缓存,定时更新和启动104服务端 3 days ago
huangfeng f1aed43e7c perf: 调整iec104点表和增删接口 3 days ago
huangfeng 8fcafde6aa Merge branch 'dev' into iec104 6 days ago
huangfeng b8462cd08a perf: 增加故障实例参考描述信息 2 weeks ago
huangfeng eb50d898a4 fix: 气体必须严格匹配 2 weeks ago
huangfeng 5f23f3f003 fix: 异常数据兼容处理 2 weeks ago
huangfeng 3140b55c93 feat: 查询数据报表时候自动把油色谱的数据进行三比值计算 2 weeks ago
huangfeng 2150040509 fix: 调整类型和默认值 2 weeks ago
huangfeng e9e1f8e26b feat: 油色谱数据增加三比值计算 2 weeks ago
huangfeng 798c2477f5 Merge branch 'devhf' into dev 1 month ago
huangfeng f05cac5010 fix: 增加校验 2 months ago
huangfeng 247e6fcfd4 feat: 增加i2传数据时候可以单位换算 2 months ago
huangfeng aa3a3c5c8a feat: 增加把采集的谱图文件上传给健康评估 2 months ago
huangfeng c15d2af756 feat: 增加测试接口 2 months ago
huangfeng 494cac6c0e feat: 实时数据也用规则校验告警 2 months ago
huangfeng 0a77c0afc4 fix: 句容抽蓄 局放数据异常,特殊处理 2 months ago
huangfeng 52681d2edc feat: 增加sftp循环创建目录和上传文件功能 2 months ago
huangfeng a33d677671 feat: 增加局放谱图解析功能 2 months ago
huangfeng a6b1def256 perf: 调整谱图文件类型判断 2 months ago
huangfeng 3c2442c353 del: 去除不用代码 2 months ago
huangfeng 858203a856 fix: 硬节点告警触发修正 2 months ago
huangfeng faa8a45e70 feat: 红外测温采集的数据更新到实时数据 3 months ago
huangfeng 35c0444512 perf: 优化表名缺失时的入库处理 3 months ago
huangfeng 688c702af9 fix: 增加icd文件异常提示 3 months ago
huangfeng 63a60caac6 perf: 优化各处报错提示信息 3 months ago
huangfeng 073321327b fix: 修正i2同步500条没继续传问题 3 months ago
huangfeng 79c31167ea perf: 优化字段类型预处理 3 months ago
huangfeng f91eafbbb8 perf: 查询datetime类型格式化处理 3 months ago
huangfeng 82f2a2d493 perf: 优化红外测温采集 3 months ago
huangfeng e7ca7ced73 db: 调整红外测温表 3 months ago
huangfeng b87e700097 perf: 调整红外温度采集业务逻辑 3 months ago
huangfeng 9f68963658 build: 增加linux库 3 months ago
huangfeng cb3a627011 perf: 调整sdk基础功能 3 months ago
huangfeng 524937ea8d feat: 增加定时任务触发热成像采集功能 3 months ago
huangfeng 026b71da94 feat: 增加热成像采集配置的查询和修改功能,以及装置属性 3 months ago
huangfeng 13dacfc2b9 build: 增加大华sdk 3 months ago
huangfeng 0807ca3441 fix: 调整61850告警统一配置 3 months ago
huangfeng ab85f75b45 feat: 61850告警可配置开关 3 months ago
huangfeng d1b2c27fd6 feat: 可配置61850定时检测开关 3 months ago
郭承 76605c3e18 fix:调整一键修改处理状态 3 months ago
郭承 243e226df4 fix:修改一键修改处理状态的处理方式并不能重复处理 3 months ago
huangfeng 52f9c2daae feat: 增加装置可调整排序功能 4 months ago
huangfeng e825c6a654 Merge branch 'spectrogram' into dev 4 months ago
huangfeng 2b1d42b00e Merge branch 'iec61850' into spectrogram 4 months ago
huangfeng d9dcc76d62 feat: 增加采集时间 4 months ago
huangfeng 8e5f225267 feat: 增加开始时间结束时间查询条件 4 months ago
huangfeng ecd9cb6709 feat: 增加二次解析谱图功能 4 months ago
huangfeng 640955b151 feat: 增加按装置查询谱图文件 4 months ago
huangfeng 1c1a543405 fix: 修正读取类型 4 months ago
huangfeng 7e1c476c1b fix: 修正读取类型 4 months ago
huangfeng b907a97a5c Merge branch 'iec61850' into spectrogram 4 months ago
huangfeng 4b1ee47a26 feat: 采集的谱图文件解析后保存入库,并可查询出来 4 months ago
huangfeng 6127aee14b fix 4 months ago
huangfeng eb318677ab fix: 改用小端字节序解析 4 months ago
huangfeng 4bd1c833d1 feat: 增加南网谱图结构解析 4 months ago
huangfeng 594271831d feat: 从油色谱图文件读取解析成java结构 5 months ago
huangfeng d4c39f0ac4 feat: 增加谱图解析的表结构和基础流程代码 5 months ago
huangfeng 3f83956ac9 feat: 增加油色谱谱图数据结构 5 months ago
huangfeng 3ab0649752 feat: 增加服务端的控制服务功能 5 months ago
郭承 4cfc31d9bc fix:字段的属性名修正 6 months ago
郭承 e38515bf10 feat:iec104点表配置、CRUD操作 6 months ago
huangfeng 5f967278f5 feat: 增加104客户端服务和断线重连机制 6 months ago
huangfeng fccb856cb6 Merge branch 'iec61850' into iec104 6 months ago
huangfeng 3700610d15 Merge branch 'iec61850' into iec104 6 months ago
huangfeng 7e83ef38d5 Merge branch 'iec61850' into iec104 6 months ago
huangfeng 73d23f7a82 Merge branch 'iec61850' into iec104 7 months ago
huangfeng 5ad5632f64 feat: 增加104客户端连接断开和测试代码 7 months ago
huangfeng 2a3e2902cb feat: 增加iec104底层组件 8 months ago

@ -0,0 +1,22 @@
DROP TABLE IF EXISTS `ied_dl_record`;
CREATE TABLE `ied_dl_record` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`config_id` int(11) DEFAULT NULL,
`remote_path` varchar(200) DEFAULT NULL COMMENT '源路径',
`filename` varchar(200) DEFAULT NULL COMMENT '文件名',
`path` varchar(200) DEFAULT NULL COMMENT '本地路径',
`create_time` datetime DEFAULT NULL,
`d_time` datetime DEFAULT NULL,
`dev_id` int(11) DEFAULT NULL COMMENT '装置ID',
`type_id` int(11) DEFAULT NULL COMMENT '类型id',
`data` mediumtext,
PRIMARY KEY (`id`),
KEY `idxDev` (`dev_id`,`d_time`),
KEY `idxConfig` (`config_id`,`d_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
ALTER TABLE `n_sensor`
ADD COLUMN `order_num` INT NULL AFTER `icd_id`,
ADD INDEX `idxOrd` (`order_num` ASC),
ADD INDEX `idxZsb` (`zsb_id` ASC, `order_num` ASC);

@ -0,0 +1,33 @@
ALTER TABLE `n_sensor`
ADD COLUMN `ip` VARCHAR(45) NULL AFTER `order_num`,
ADD COLUMN `port` INT NULL AFTER `ip`,
ADD COLUMN `username` VARCHAR(45) NULL AFTER `port`,
ADD COLUMN `passwd` VARCHAR(45) NULL AFTER `username`,
ADD COLUMN `tm_id` INT NULL AFTER `passwd`,
ADD COLUMN `tm_type` INT NULL AFTER `tm_id`;
CREATE TABLE `thermal_config` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`type_id` int(11) DEFAULT NULL COMMENT '类型id',
`maxtemp` varchar(45) DEFAULT NULL,
`mintemp` varchar(45) DEFAULT NULL,
`avertemp` varchar(45) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS `data_eaif_h`;
CREATE TABLE `data_eaif_h` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '自动编号',
`eqmid` int(11) NOT NULL COMMENT '设备ID',
`areaid` int(11) DEFAULT NULL COMMENT '点、线、区域ID',
`capturetime` datetime NOT NULL COMMENT '采集时间',
`maxtemp` float(18,4) DEFAULT NULL COMMENT '最大温度',
`mintemp` float(18,4) DEFAULT NULL COMMENT '最小温度',
`avgtemp` float(18,4) DEFAULT NULL COMMENT '平均温度',
`unit` tinyint(2) DEFAULT NULL COMMENT '1=>摄氏度2=>华氏度',
`type` tinyint(2) DEFAULT NULL COMMENT '1->点2->线3->框',
`mid` float(10,4) DEFAULT NULL COMMENT '中间差',
`std` float(10,4) DEFAULT NULL COMMENT '标准方差值',
PRIMARY KEY (`id`) USING BTREE,
KEY `idx` (`eqmid`,`capturetime`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='红外区域测温数据表';

@ -0,0 +1,8 @@
ALTER TABLE `ied_dl_config`
ADD COLUMN `upload` INT NULL COMMENT '0:不传; 1:要传;' AFTER `active`;
ALTER TABLE `ied_dl_record`
ADD COLUMN `upload` INT(11) NULL DEFAULT NULL COMMENT '0:未传; 1:已传;' AFTER `data`;
ALTER TABLE `i2sync_field`
ADD COLUMN `conversion` VARCHAR(45) NULL COMMENT '单位换算' AFTER `attach`;

@ -0,0 +1,9 @@
CREATE TABLE `iec_104_point` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`eqmid` int(11) DEFAULT NULL,
`field` varchar(45) DEFAULT NULL,
`stype` varchar(45) DEFAULT NULL COMMENT '类型 1:遥信 2:遥测',
`sadr` int(11) DEFAULT NULL COMMENT '点位',
`create_time` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

@ -194,22 +194,35 @@
<version>1.14.0</version>
</dependency>
<dependency>
<groupId>org.openmuc</groupId>
<artifactId>j60870</artifactId>
<version>1.7.2</version>
</dependency>
<!--jSerialComm库串口通讯-->
<dependency>
<groupId>com.fazecast</groupId>
<artifactId>jSerialComm</artifactId>
<version>2.11.0</version>
</dependency>
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna</artifactId>
<version>3.4.0</version>
</dependency>
<dependency>
<groupId>local</groupId>
<artifactId>examples</artifactId>
<version>1</version>
<scope>system</scope>
<systemPath>${pom.basedir}/lib/examples.jar</systemPath>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*</include>
</includes>
</resource>
<resource>
<directory>src/main/resources</directory>
<includes>
@ -222,6 +235,7 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<includeSystemScope>true</includeSystemScope>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>

@ -0,0 +1,149 @@
package com.hcsdk;
import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.ptr.IntByReference;
import com.xydl.cac.model.StaticVariable;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class HCModule {
public static HCNetSDK hCNetSDK = null;
static int userID;
static int handle;
static FExceptionCallBack_Imp fExceptionCallBack;
static String libPath;
private static boolean createSDKInstance() {
if (hCNetSDK == null) {
synchronized (HCNetSDK.class) {
String strDllPath = libPath + "libhcnetsdk.so";
hCNetSDK = (HCNetSDK) Native.loadLibrary(strDllPath, HCNetSDK.class);
}
}
return true;
}
static class FExceptionCallBack_Imp implements HCNetSDK.FExceptionCallBack {
@Override
public void invoke(int dwType, int lUserID, int lHandle, Pointer pUser) {
log.info("回调: dwType=" + dwType + ", lUserID=" + lUserID + ", lHandle=" + lHandle + ", pUser=" + pUser);
return;
}
}
public static void init() {
libPath = StaticVariable.jarPath + "/hklib/";
createSDKInstance();
HCNetSDK.BYTE_ARRAY ptrByteArray1 = new HCNetSDK.BYTE_ARRAY(256);
HCNetSDK.BYTE_ARRAY ptrByteArray2 = new HCNetSDK.BYTE_ARRAY(256);
//这里是库的绝对路径,请根据实际情况修改,注意改路径必须有访问权限
String strPath1 = libPath + "libcrypto.so.1.1";
String strPath2 = libPath + "libssl.so.1.1";
System.arraycopy(strPath1.getBytes(), 0, ptrByteArray1.byValue, 0, strPath1.length());
ptrByteArray1.write();
hCNetSDK.NET_DVR_SetSDKInitCfg(HCNetSDK.NET_SDK_INIT_CFG_LIBEAY_PATH, ptrByteArray1.getPointer());
System.arraycopy(strPath2.getBytes(), 0, ptrByteArray2.byValue, 0, strPath2.length());
ptrByteArray2.write();
hCNetSDK.NET_DVR_SetSDKInitCfg(HCNetSDK.NET_SDK_INIT_CFG_SSLEAY_PATH, ptrByteArray2.getPointer());
String strPathCom = libPath + "HCNetSDKCom/";
HCNetSDK.NET_DVR_LOCAL_SDK_PATH struComPath = new HCNetSDK.NET_DVR_LOCAL_SDK_PATH();
System.arraycopy(strPathCom.getBytes(), 0, struComPath.sPath, 0, strPathCom.length());
struComPath.write();
hCNetSDK.NET_DVR_SetSDKInitCfg(HCNetSDK.NET_SDK_INIT_CFG_SDK_PATH, struComPath.getPointer());
boolean r = hCNetSDK.NET_DVR_Init();
if (!r) {
int err = hCNetSDK.NET_DVR_GetLastError();
String msg = hCNetSDK.NET_DVR_GetErrorMsg(new IntByReference(err));
log.error("海康热成像初始化失败,库路径=" + libPath
+ ", 错误码为: " + err + ", 错误信息:" + msg);
}
Pointer pUser = null;
r = hCNetSDK.NET_DVR_SetExceptionCallBack_V30(0, 0, fExceptionCallBack, pUser);
if (!r) {
log.error("海康设置回调失败,错误码为: " + hCNetSDK.NET_DVR_GetLastError());
}
}
public static boolean logout() {
return hCNetSDK.NET_DVR_Logout(userID);
}
public static void cleanup() {
if (hCNetSDK != null) {
hCNetSDK.NET_DVR_Cleanup();
}
hCNetSDK = null;
}
/**
* V40 V30
*
* @param ip IP
* @param port SDK8000
* @param user
* @param psw
* @return ID-1
*/
public static boolean login(String ip, short port, String user, String psw) {
// 创建设备登录信息和设备信息对象
HCNetSDK.NET_DVR_USER_LOGIN_INFO m_strLoginInfo = new HCNetSDK.NET_DVR_USER_LOGIN_INFO();//设备登录信息
HCNetSDK.NET_DVR_DEVICEINFO_V40 m_strDeviceInfo = new HCNetSDK.NET_DVR_DEVICEINFO_V40();//设备信息
m_strLoginInfo.sDeviceAddress = new byte[HCNetSDK.NET_DVR_DEV_ADDRESS_MAX_LEN];
System.arraycopy(ip.getBytes(), 0, m_strLoginInfo.sDeviceAddress, 0, ip.length());
m_strLoginInfo.sUserName = new byte[HCNetSDK.NET_DVR_LOGIN_USERNAME_MAX_LEN];
System.arraycopy(user.getBytes(), 0, m_strLoginInfo.sUserName, 0, user.length());
m_strLoginInfo.sPassword = new byte[HCNetSDK.NET_DVR_LOGIN_PASSWD_MAX_LEN];
System.arraycopy(psw.getBytes(), 0, m_strLoginInfo.sPassword, 0, psw.length());
m_strLoginInfo.wPort = port;
m_strLoginInfo.bUseAsynLogin = false; //是否异步登录0- 否1- 是
// m_strLoginInfo.byLoginMode=1; //ISAPI登录
m_strLoginInfo.write();
// 执行登录操作
userID = hCNetSDK.NET_DVR_Login_V40(m_strLoginInfo, m_strDeviceInfo);
if (userID == -1) {
int err = hCNetSDK.NET_DVR_GetLastError();
String msg = hCNetSDK.NET_DVR_GetErrorMsg(new IntByReference(err));
log.error("海康热成像登入失败" + ip + ":" + port + ", 用户名:" + user + ", 密码:" + psw
+ ", 错误码为: " + err + ", 错误信息:" + msg);
return false;
}
return true; // 返回登录结果
}
public static boolean startRemoteConfig(HCNetSDK.FRemoteConfigCallBack callBack,
Integer channel, Integer tmId) {
HCNetSDK.NET_DVR_REALTIME_THERMOMETRY_COND cond = new HCNetSDK.NET_DVR_REALTIME_THERMOMETRY_COND();
cond.read();
cond.dwSize = cond.size();
cond.byRuleID = tmId.byteValue();
cond.dwChan = channel;
cond.wInterval = 1;
cond.byMode = 1;
cond.write();
log.info("开始采集通道" + channel + ", 规则" + tmId);
handle = hCNetSDK.NET_DVR_StartRemoteConfig(userID, HCNetSDK.NET_DVR_GET_REALTIME_THERMOMETRY,
cond.getPointer(), cond.size(), callBack, null);
if (handle < 0) {
int err = hCNetSDK.NET_DVR_GetLastError();
String msg = hCNetSDK.NET_DVR_GetErrorMsg(new IntByReference(err));
log.error("startRemoteConfig失败 " + ", 错误码为: " + err + ", 错误信息:" + msg);
return false;
}
return true;
}
public static void stopRemoteConfig() {
hCNetSDK.NET_DVR_StopRemoteConfig(handle);
}
}

File diff suppressed because it is too large Load Diff

@ -1,8 +1,10 @@
package com.xydl.cac;
import com.xydl.cac.model.StaticVariable;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.system.ApplicationHome;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.scheduling.annotation.EnableAsync;
@ -25,6 +27,8 @@ public class CacBackendApplication {
}
public static void main(String[] args) {
ApplicationHome home = new ApplicationHome(CacBackendApplication.class);
StaticVariable.jarPath = home.getSource().getParentFile().getAbsolutePath();
SpringApplication.run(CacBackendApplication.class, args);
}
}

@ -174,7 +174,7 @@ public class IcdConfigController extends BasicController {
}
Optional<IcdIed> optional = iedRepository.findById(iedId);
if (!optional.isPresent()) {
throw new BusinessException("未找到该IED");
throw new BusinessException("未找到该IED id=" + iedId);
}
IcdIed ied = optional.get();
try {
@ -201,7 +201,7 @@ public class IcdConfigController extends BasicController {
}
Optional<IcdIed> optional = iedRepository.findById(iedId);
if (!optional.isPresent()) {
throw new BusinessException("未找到该IED");
throw new BusinessException("未找到该IED id=" + iedId);
}
IcdIed ied = optional.get();
ied.setStart(Constants.FALSE);

@ -0,0 +1,50 @@
package com.xydl.cac.controller;
import com.xydl.cac.entity.Iec104Point;
import com.xydl.cac.exception.BusinessException;
import com.xydl.cac.model.Response;
import com.xydl.cac.service.Iec104PointService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.validation.constraints.NotNull;
import java.util.List;
@RestController
@Api(tags = {"Iec104点表接口"})
@RequestMapping("iec104")
@Slf4j
public class Iec104PointController extends BasicController {
@Resource
Iec104PointService iec104PointService;
@GetMapping("list")
@ApiOperation("查询104点表")
public Response<List<Iec104Point>> list() {
List<Iec104Point> result = iec104PointService.findAll();
return Response.success(result);
}
@PostMapping("add")
@ApiOperation("新增")
public Response<Iec104Point> add(@Validated @RequestBody Iec104Point iec104Point) throws Exception {
Iec104Point add = iec104PointService.add(iec104Point);
return Response.success(add);
}
@PostMapping("del")
@ApiOperation("删除")
public Response<String> del(@Validated @NotNull(message = "id不能为空!") Integer id) throws Exception {
if (id == null) {
throw new BusinessException("id不能为空!");
}
iec104PointService.delete(id);
return Response.success("OK");
}
}

@ -17,6 +17,7 @@ import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.validation.constraints.NotNull;
import java.util.Date;
import java.util.List;
@RestController
@ -66,15 +67,28 @@ public class IedDlController extends BasicController {
@GetMapping("listDownload")
@ApiOperation("查询下载记录列表")
public Response<Page<IedDlRecord>> list(@ApiParam("类型") @RequestParam(value = "configId", required = false) Integer configId,
public Response<Page<IedDlRecord>> list(@ApiParam("配置Id") @RequestParam(value = "configId", required = false) Integer configId,
@ApiParam("devId") @RequestParam(value = "devId", required = false) Integer devId,
@ApiParam("开始时间") @RequestParam(value = "startTime", required = false) Date startTime,
@ApiParam("结束时间") @RequestParam(value = "endTime", required = false) Date endTime,
@ApiParam("页码") @RequestParam(value = "pageNum", required = false) Integer pageNum,
@ApiParam("每页数量") @RequestParam(value = "pageSize", required = false) Integer pageSize) throws Exception {
pageNum = this.initPageNum(pageNum);
pageSize = this.initPageSize(pageSize);
Page<IedDlRecord> result = recordService.list(configId, pageNum, pageSize);
Page<IedDlRecord> result = recordService.list(configId, devId, startTime, endTime, pageNum, pageSize);
return Response.success(result);
}
@PostMapping("rebuildData")
@ApiOperation("rebuildData")
public Response<String> rebuildData(@Validated @NotNull(message = "id不能为空!") Integer id) throws Exception {
if (id == null) {
throw new BusinessException("id不能为空!");
}
recordService.rebuildData(id);
return Response.success("OK");
}
@GetMapping("listFiles")
@ApiOperation("查询文件和目录")
public Response<List<FileInformation>> listFiles(Integer iedId, String path) throws Exception {

@ -3,10 +3,7 @@ package com.xydl.cac.controller;
import com.xydl.cac.entity.Bdz;
import com.xydl.cac.entity.NSensor;
import com.xydl.cac.exception.BusinessException;
import com.xydl.cac.model.ConditionModel;
import com.xydl.cac.model.Response;
import com.xydl.cac.model.SensorDetail;
import com.xydl.cac.model.SensorUpdateModel;
import com.xydl.cac.model.*;
import com.xydl.cac.repository.NSensorRepository;
import com.xydl.cac.service.NSensorService;
import com.xydl.cac.service.ParamBindService;
@ -157,7 +154,7 @@ public class NSensorController extends BasicController {
String typename = "";
List<NSensor> list = sensorRepository.findByTypeId(model.getTypeId());
if (CollectionUtils.isEmpty(list)) {
throw new BusinessException("未找到该类型的装置");
throw new BusinessException("未找到该类型的装置typeId=" + model.getTypeId());
}
List<SensorDetail<Map<String, Object>>> detailList = new ArrayList<>();
for (NSensor sensor : list) {
@ -214,4 +211,16 @@ public class NSensorController extends BasicController {
}
@PostMapping("sanbizhi")
@ApiOperation("三比值")
public Response<SanbizhiModel> sanbizhi(@RequestBody Map<String, Object> map) throws Exception {
SanbizhiModel item = new SanbizhiModel();
boolean r = item.build(map);
if (r) {
return Response.success(item);
} else {
throw new BusinessException(item.getStatus());
}
}
}

@ -90,7 +90,13 @@ public class TestController extends BasicController {
@GetMapping("/discover")
public Response<String> discoverSerialPort() {
serialPortService.discoverSerialPort();
return Response.fail("未找到");
return Response.success("OK");
}
@GetMapping("/updateLastData")
public Response<String> updateLastData(Integer eqmid, String colname, String value, String time) {
StaticVariable.updateLastData(eqmid, colname, value, time);
return Response.success("OK");
}
@GetMapping("/open")

@ -0,0 +1,37 @@
package com.xydl.cac.controller;
import com.xydl.cac.entity.ThermalConfig;
import com.xydl.cac.model.Response;
import com.xydl.cac.service.ThermalConfigService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
@RestController
@Api(tags = {"热成像测温相关接口"})
@RequestMapping("thermal")
@Slf4j
public class ThermalConfigController extends BasicController {
@Resource
ThermalConfigService configService;
@GetMapping("getConfig")
@ApiOperation("查询配置")
public Response<ThermalConfig> getConfig() {
ThermalConfig result = configService.getConfig();
return Response.success(result);
}
@PostMapping("saveConfig")
@ApiOperation("修改配置")
public Response<String> saveConfig(@Validated @RequestBody ThermalConfig model) throws Exception {
configService.saveConfig(model);
return Response.success("OK");
}
}

@ -67,7 +67,7 @@ public class WarnRuleController extends BasicController {
} else if (Constants.Miss.equalsIgnoreCase(name)) {
return missCompare;
} else {
throw new BusinessException("未找到该比较器");
throw new BusinessException("未找到该比较器" + name);
}
}

@ -5,6 +5,7 @@ import com.xydl.cac.entity.Warning;
import com.xydl.cac.exception.BusinessException;
import com.xydl.cac.model.ConditionModel;
import com.xydl.cac.model.Response;
import com.xydl.cac.service.DataService;
import com.xydl.cac.service.ReportService;
import com.xydl.cac.service.WarningService;
import io.swagger.annotations.Api;
@ -28,6 +29,9 @@ public class WarningController extends BasicController {
@Resource
WarningService service;
@Resource
DataService dataService;
@GetMapping("list")
@ApiOperation("查询列表")
public Response<Page<Warning>> list(@Validated ConditionModel condition) throws Exception {
@ -65,13 +69,20 @@ public class WarningController extends BasicController {
}
Boolean isHandle = false;
@PostMapping("oneKeyUpdateState")
@ApiOperation("一键修改处理状态")
public Response<String> oneKeyUpdateState() throws Exception {
ConditionModel condition = new ConditionModel();
condition.setState("1");
List<Warning> warnings = service.listAll(condition);
service.oneKeyUpdateState(warnings);
return Response.success("OK");
try {
if (isHandle) {
throw new BusinessException("相同请求正在处理中, 请勿重复处理");
}
isHandle = true;
service.oneKeyUpdateState();
return Response.success("OK");
} finally {
isHandle = false;
}
}
}

@ -36,4 +36,7 @@ public class I2syncField {
@Column(name = "attach")
private String attach;
@Column(name = "conversion")
private String conversion;
}

@ -0,0 +1,54 @@
package com.xydl.cac.entity;
import com.fasterxml.jackson.annotation.JsonInclude;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.persistence.*;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.util.Date;
@JsonInclude(JsonInclude.Include.NON_NULL)
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Entity
@Table(name = "iec_104_point")
@ApiModel("IEC104点表配置")
public class Iec104Point {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Integer id;
@NotNull(message = "eqmid不能为空")
@Column(name = "eqmid")
private Integer eqmid;
@NotBlank(message = "字段不能为空")
@ApiModelProperty("字段")
@Column(name = "field")
private String field;
@ApiModelProperty("点位类型")
@Column(name = "stype")
private String stype;
@NotNull(message = "点位不能为空")
@ApiModelProperty("点位")
@Column(name = "sadr")
private Integer sadr;
@ApiModelProperty("创建时间")
@Column(name = "create_time")
private Date createTime;
}

@ -58,6 +58,10 @@ public class IedDlConfig {
@Column(name = "active")
private Integer active;
@ApiModelProperty("是否上传健康评估 0:不传 1:要传")
@Column(name = "upload")
private Integer upload;
@Transient
private NSensor sensor;
@Transient

@ -1,6 +1,6 @@
package com.xydl.cac.entity;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.xydl.cac.model.spectrogram.SpectrogramModel;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
@ -11,7 +11,6 @@ import lombok.NoArgsConstructor;
import javax.persistence.*;
import java.util.Date;
@JsonInclude(JsonInclude.Include.NON_NULL)
@Data
@Builder
@AllArgsConstructor
@ -42,11 +41,36 @@ public class IedDlRecord {
@Column(name = "filename")
private String filename;
@ApiModelProperty("采集时间")
@Column(name = "d_time")
private Date dTime;
@ApiModelProperty("创建时间")
@Column(name = "create_time")
private Date createTime;
@ApiModelProperty("devId")
@Column(name = "dev_id")
private Integer devId;
@ApiModelProperty("typeId")
@Column(name = "type_id")
private Integer typeId;
@ApiModelProperty("解析后数据")
@Column(name = "data")
private String data;
@ApiModelProperty("是否上传健康评估 0:未传 1:已传")
@Column(name = "upload")
private Integer upload;
@Transient
String localFullPath;
@Transient
IedDlConfig config;
@Transient
SpectrogramModel model;
}

@ -7,6 +7,7 @@ import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import javax.persistence.*;
import java.util.ArrayList;
@ -64,6 +65,34 @@ public class NSensor {
@ApiModelProperty("关联icd表中的id")
private Integer icdId;
@Column(name = "order_num")
@ApiModelProperty("排序编号")
private Integer orderNum;
@ApiModelProperty("ip")
@Column(name = "ip")
private String ip;
@Column(name = "port")
@ApiModelProperty("port")
private Integer port;
@ApiModelProperty("username")
@Column(name = "username")
private String username;
@ApiModelProperty("passwd")
@Column(name = "passwd")
private String passwd;
@Column(name = "tm_id")
@ApiModelProperty("tmId")
private Integer tmId;
@Column(name = "tm_type")
@ApiModelProperty("tmType")
private Integer tmType;
@ApiModelProperty("主设备名称")
@Transient
private String zsbName;
@ -104,4 +133,13 @@ public class NSensor {
points.add(point);
return null;
}
public boolean canTempMeasure() {
if (StringUtils.isNotBlank(ip) && StringUtils.isNotBlank(username) && StringUtils.isNotBlank(passwd)
&& port != null && tmId != null && tmType != null) {
return true;
} else {
return false;
}
}
}

@ -0,0 +1,45 @@
package com.xydl.cac.entity;
import com.fasterxml.jackson.annotation.JsonInclude;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.persistence.*;
import javax.validation.constraints.NotNull;
@JsonInclude(JsonInclude.Include.NON_NULL)
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Entity
@Table(name = "thermal_config")
@ApiModel("热成像测温配置表")
public class ThermalConfig {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Integer id;
@NotNull(message = "typeId不能为空")
@Column(name = "type_id")
@ApiModelProperty("类型Id")
private Integer typeId;
@ApiModelProperty("最高温度字段")
@Column(name = "maxtemp")
private String maxtemp;
@ApiModelProperty("最低温度字段")
@Column(name = "mintemp")
private String mintemp;
@ApiModelProperty("平均温度字段")
@Column(name = "avertemp")
private String avertemp;
}

@ -19,4 +19,7 @@ public class Constants {
public static String Text = "text";
public static String DateTime = "datetime";
public static String Miss = "miss";
public static final Integer I2BatchSize = 500;
}

@ -10,7 +10,9 @@ import com.xydl.cac.repository.*;
import com.xydl.cac.service.DataService;
import com.xydl.cac.service.IedDlRecordService;
import com.xydl.cac.socket.WebSocketServer;
import com.xydl.cac.spectrogram.SpectrogramHandler;
import com.xydl.cac.util.DateUtil;
import com.xydl.cac.util.JkpgFtp;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.CollectionUtils;
@ -33,6 +35,9 @@ public class IEDCollectService {
WebSocketServer _webSocketServer;
BizConfig _bizConfig;
WarningRepository _warningRepository;
SpectrogramHandler _spectrogramHandler;
boolean _warning;
JkpgFtp _jkpgFtp;
String folder = "/record";
HashMap<Integer, String> eqmidTimeMap = new HashMap<>();
@ -41,8 +46,9 @@ public class IEDCollectService {
IcdConfigTypeInstRepository instRepository, RptparamindexRepository rptparamindexRepository,
IedDlRecordService dlRecordService, DataService dataService,
String xml, IcdIed ied,
WebSocketServer webSocketServer, BizConfig bizConfig,
WarningRepository warningRepository) {
WebSocketServer webSocketServer, BizConfig bizConfig, boolean warning,
WarningRepository warningRepository, SpectrogramHandler spectrogramHandler,
JkpgFtp jkpgFtp) {
_configRepository = configRepository;
_attRepository = attRepository;
_instRepository = instRepository;
@ -53,7 +59,10 @@ public class IEDCollectService {
this.ied = ied;
_webSocketServer = webSocketServer;
_bizConfig = bizConfig;
_warning = warning;
_warningRepository = warningRepository;
_spectrogramHandler = spectrogramHandler;
_jkpgFtp = jkpgFtp;
iecClient = new IecClient();
}
@ -87,11 +96,13 @@ public class IEDCollectService {
String err = "61850采集数据异常, ied=" + ied.getName() + ", ip=" + ied.getIp() + ", port=" + ied.getPort()
+ ", " + ex.getMessage();
log.error(err, ex);
this.saveWarning(err);
String key = ied.getName() + ied.getIp() + ied.getPort();
if (!StaticVariable.doneWarnMap.containsKey(key)) {
StaticVariable.doneWarnMap.put(key, "1");
_webSocketServer.sendMessage(err, null);
if (_warning) {
this.saveWarning(err);
String key = ied.getName() + ied.getIp() + ied.getPort();
if (!StaticVariable.doneWarnMap.containsKey(key)) {
StaticVariable.doneWarnMap.put(key, "1");
_webSocketServer.sendMessage(err, null);
}
}
} finally {
iecClient.disconnect();
@ -151,6 +162,11 @@ public class IEDCollectService {
value = valueNode.getValueString();
String time = timeNode.getValueString();
log.info("采集到" + fc + " " + paramindexNew + "=" + value + ", t=" + time);
// 句容抽蓄 局放数据为0异常特殊处理
if (paramindexNew.toLowerCase().contains("avdsch") && value.equalsIgnoreCase("0.0")) {
log.warn("avdsch数据异常改为-70");
value = "-70";
}
if ("NaN".equalsIgnoreCase(value)) {
return;
}
@ -216,16 +232,23 @@ public class IEDCollectService {
&& matchContain(filename, config.getContain())) {
IedDlRecord record = new IedDlRecord();
record.setConfigId(config.getId());
record.setDevId(config.getDevId());
record.setTypeId(config.getSensor().getTypeId());
record.setFilename(filename);
record.setRemotePath(config.getPath() + filename);
boolean exist = _dlRecordService.exist(record);
if (!exist) {
String localFilePath = localPath + "/" + filename;
iecClient.getFile(record.getRemotePath(), _bizConfig.getDatapath() + localFilePath, config.getTodel());
record.setPath(_bizConfig.getDataNginxPath() + localFilePath);
record.setCreateTime(new Date());
_dlRecordService.add(record);
String relativePath = localPath + "/" + filename;
String localFullPath = _bizConfig.getDatapath() + relativePath;
record.setLocalFullPath(localFullPath);
iecClient.getFile(record.getRemotePath(), localFullPath, config.getTodel());
record.setPath(_bizConfig.getDataNginxPath() + relativePath);
log.info("采集到" + record.getRemotePath());
_spectrogramHandler.processFile(record);
if (config.getUpload() != null && config.getUpload().intValue() == Constants.TRUE) {
_jkpgFtp.upload(record);
}
_dlRecordService.add(record);
}
}
}

@ -31,8 +31,7 @@ public class IecClient implements ClientEventListener {
public boolean keep = false;
public boolean connected = false;
private RealTimeDataService realTimeDataService;
private WebSocketServer webSocketServer;
private WebSocketServer webSocketServer = null;
public int retry = 0;
public int seconds = 0;
private boolean inRetry = false;
@ -41,9 +40,10 @@ public class IecClient implements ClientEventListener {
public IecClient() {
}
public IecClient(RealTimeDataService _realTimeDataService, WebSocketServer _webSocketServer) {
realTimeDataService = _realTimeDataService;
webSocketServer = _webSocketServer;
public IecClient(WebSocketServer _webSocketServer, boolean warning) {
if (warning) {
webSocketServer = _webSocketServer;
}
}
public void init(IcdIed _ied, String xml) throws Exception {

@ -41,7 +41,7 @@ public class IecServerService {
public void startServer(Integer fileId, int port) throws BusinessException {
Optional<IcdFile> optional = fileRepository.findById(fileId);
if (!optional.isPresent()) {
throw new BusinessException("未找到该文件");
throw new BusinessException("未找到该文件fileId=" + fileId);
}
IcdFile icdFile = optional.get();
if (icdFile.getSrv() != Constants.Server) {
@ -94,7 +94,7 @@ public class IecServerService {
public List<IcdConfigTypeInst> listParamindex(Integer fileId) throws Exception {
Optional<IcdFile> optional = fileRepository.findById(fileId);
if (!optional.isPresent()) {
throw new BusinessException("未找到该文件");
throw new BusinessException("未找到该文件fileId=" + fileId);
}
IcdFile icdFile = optional.get();
if (icdFile.getSrv() != Constants.Server) {

@ -10,6 +10,7 @@ import com.xydl.cac.repository.IcdFileRepository;
import com.xydl.cac.repository.IcdIedRepository;
import com.xydl.cac.socket.WebSocketServer;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
@ -21,6 +22,8 @@ import java.util.*;
@Service
@Slf4j
public class RealTimeDataService {
@Value("${cac.61850.warning:true}")
public boolean warning;
@Resource
IcdFileRepository fileRepository;
@Resource
@ -52,7 +55,7 @@ public class RealTimeDataService {
}
inDoing = true;
IcdFile icdFile = optionalFile.get();
IecClient iecClient = new IecClient(this, webSocketServer);
IecClient iecClient = new IecClient(webSocketServer, warning);
try {
iecClient.init(ied, icdFile.getXml());
iecClient.keep = true;

@ -0,0 +1,132 @@
package com.xydl.cac.iec104;
import com.xydl.cac.model.StaticVariable;
import com.xydl.cac.socket.WebSocketServer;
import lombok.extern.slf4j.Slf4j;
import org.openmuc.j60870.*;
import org.openmuc.j60870.ie.*;
import java.io.IOException;
import java.net.InetAddress;
@Slf4j
public class Iec104Client implements ConnectionEventListener {
public String ip;
public Integer port;
Connection connection = null;
ClientConnectionBuilder clientConnectionBuilder = null;
private WebSocketServer webSocketServer;
public boolean keep = false;
public boolean connected = false;
public int retry = 0;
public int seconds = 0;
private boolean inRetry = false;
public Iec104Client(WebSocketServer _webSocketServer) {
webSocketServer = _webSocketServer;
}
public void connect(String _ip, Integer _port) throws Exception {
ip = _ip;
port = _port;
InetAddress address = InetAddress.getByName(ip);
clientConnectionBuilder = new ClientConnectionBuilder(address)
.setMessageFragmentTimeout(5_000)
.setConnectionTimeout(20_000)
.setPort(port)
.setConnectionEventListener(this);
connection = clientConnectionBuilder.build();
connection.startDataTransfer();
log.info("IEC104客户端已连接上" + ip + ":" + port);
connected = true;
}
public void disconnect() {
try {
connected = false;
connection.stopDataTransfer();
connection.close();
connection = null;
log.info("IEC104客户端已断开" + ip + ":" + port);
} catch (Exception ignore) {
}
}
private void reconnect() throws Exception {
if (StaticVariable.shutdown == 1) {
return;
}
retry++;
seconds = 0;
connection = clientConnectionBuilder.build();
connection.startDataTransfer();
log.info("IEC104客户端断线重连成功, ip=" + ip + ", port=" + port);
connected = true;
retry = 0;
}
public void interrogation() throws Exception {
connection.interrogation(1, CauseOfTransmission.ACTIVATION,
new IeQualifierOfInterrogation(20));
}
@Override
public void newASdu(Connection connection, ASdu aSdu) {
if (aSdu == null)
return;
log.info("Got new ASdu, " + aSdu.toString());
InformationObject[] objs = aSdu.getInformationObjects();
if (objs != null && objs.length > 0) {
for (InformationObject obj : objs) {
int addr = obj.getInformationObjectAddress();
InformationElement[][] elements = obj.getInformationElements();
}
}
}
@Override
public void connectionClosed(Connection connection, IOException e) {
if (keep && !inRetry) {
inRetry = true;
retry = 0;
seconds = 0;
this.disconnect();
while (!connected && StaticVariable.shutdown == 0) {
try {
Thread.sleep(1000);
seconds++;
if (retry < 10 && seconds > 60) {
this.reconnect();
} else if (seconds > 60 * 60) {
this.reconnect();
}
} catch (Exception ignore) {
String err = "IEC104客户端断线重连失败" + retry + "次, ip=" + ip + ", port=" + port;
log.warn(err);
if (webSocketServer != null && retry >= 10) {
webSocketServer.sendMessage(err, null);
}
}
}
inRetry = false;
}
}
@Override
public void dataTransferStateChanged(Connection connection, boolean b) {
}
public static void main(String[] args) {
Iec104Client client = new Iec104Client(null);
try {
client.connect("192.168.1.190", 2404);
client.interrogation();
while (true) {
Thread.sleep(1000);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}

@ -0,0 +1,56 @@
package com.xydl.cac.iec104;
import lombok.extern.slf4j.Slf4j;
import org.openmuc.j60870.*;
import java.io.IOException;
@Slf4j
public class Iec104Server implements ServerEventListener {
Server _server;
int idCounter = 1;
public boolean started = false;
public Integer port = null;
public Iec104Server() {
}
public void start(int port) throws Exception {
if (!started) {
_server = Server.builder()
.setPort(port)
.setIoaFieldLength(3)
.setCommonAddressFieldLength(2)
.setCotFieldLength(2)
.build();
_server.start(this);
started = true;
this.port = port;
log.info("已启动IEC104服务端在" + port + "端口");
}
}
public void stop() {
if (_server != null) {
_server.stop();
log.info("已停止IEC104服务端于" + port + "端口");
}
started = false;
}
@Override
public ConnectionEventListener connectionIndication(Connection connection) {
return new ServerConnectionEventListener(connection, idCounter++);
}
@Override
public void serverStoppedListeningIndication(IOException e) {
}
@Override
public void connectionAttemptFailed(IOException e) {
}
}

@ -0,0 +1,60 @@
package com.xydl.cac.iec104;
import com.xydl.cac.exception.BusinessException;
import com.xydl.cac.model.StaticVariable;
import com.xydl.cac.service.Iec104PointService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.annotation.Resource;
@Service
@Slf4j
public class Iec104ServerService {
@Resource
Iec104PointService iec104PointService;
@PostConstruct
private void init() {
try {
iec104PointService.findAll();
if (!CollectionUtils.isEmpty(StaticVariable.point104_Cache)) {
this.startServer(2404);
}
} catch (Exception ignore) {
}
}
public void startServer(int port) throws BusinessException {
try {
Iec104Server server = new Iec104Server();
server.start(port);
StaticVariable.iec104Server = server;
} catch (Exception e) {
log.error("启动IEC104服务端异常.", e);
throw new BusinessException(e.getMessage());
}
}
public void stopServer() {
this.doStopServer();
}
private void doStopServer() {
if (StaticVariable.iec104Server != null) {
StaticVariable.iec104Server.stop();
StaticVariable.iec104Server = null;
}
}
@PreDestroy
private void stop() {
StaticVariable.shutdown = 1;
this.doStopServer();
}
}

@ -0,0 +1,60 @@
package com.xydl.cac.iec104;
import com.xydl.cac.exception.BusinessException;
import com.xydl.cac.model.StaticVariable;
import com.xydl.cac.socket.WebSocketServer;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.annotation.Resource;
@Service
@Slf4j
public class RealTime104DataService {
@Resource
WebSocketServer webSocketServer;
public static boolean inDoing = false;
@PostConstruct
private void init() {
try {
// this.startCollect("192.168.1.177");
} catch (Exception ignore) {
}
}
public void startCollect(String ip) throws BusinessException {
inDoing = true;
try {
Iec104Client client = new Iec104Client(webSocketServer);
client.connect(ip, 2404);
client.keep = true;
} catch (Exception ex) {
String err = "IEC104客户端连接异常, ip=" + ip;
log.error(err, ex);
throw new BusinessException(err);
} finally {
inDoing = false;
}
}
public void stopCollect() {
if (StaticVariable.realTime104Client != null) {
StaticVariable.realTime104Client.keep = false;
StaticVariable.realTime104Client.disconnect();
StaticVariable.realTime104Client = null;
}
}
@PreDestroy
private void stop() {
log.info("关闭IEC104客户端.");
StaticVariable.shutdown = 1;
this.stopCollect();
}
}

@ -0,0 +1,123 @@
package com.xydl.cac.iec104;
import com.xydl.cac.entity.Iec104Point;
import com.xydl.cac.model.StaticVariable;
import com.xydl.cac.util.DateUtil;
import lombok.extern.slf4j.Slf4j;
import org.openmuc.j60870.*;
import org.openmuc.j60870.ie.*;
import java.io.EOFException;
import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
@Slf4j
public class ServerConnectionEventListener implements ConnectionEventListener {
Connection connection;
int connectionId;
boolean selected = false;
public ServerConnectionEventListener(Connection connection, int connectionId) {
this.connection = connection;
this.connectionId = connectionId;
}
@Override
public void newASdu(Connection connection, ASdu aSdu) {
log.info("Got new ASdu, type=" + aSdu.getTypeIdentification());
InformationObject informationObject = null;
try {
switch (aSdu.getTypeIdentification()) {
// interrogation command
case C_IC_NA_1:
log.debug("Got interrogation command (100). Will send scaled measured values.");
connection.sendConfirmation(aSdu);
this.sendAll104(connection);
connection.sendActivationTermination(aSdu);
break;
case C_SC_NA_1:
informationObject = aSdu.getInformationObjects()[0];
IeSingleCommand singleCommand = (IeSingleCommand) informationObject
.getInformationElements()[0][0];
if (informationObject.getInformationObjectAddress() != 5000) {
break;
}
if (singleCommand.isSelect()) {
log.debug("Got single command (45) with select true. Select command.");
selected = true;
connection.sendConfirmation(aSdu);
} else if (!singleCommand.isSelect() && selected) {
log.debug("Got single command (45) with select false. Execute selected command.");
selected = false;
connection.sendConfirmation(aSdu);
} else {
log.debug("Got single command (45) with select false. But no command is selected, no execution.");
}
break;
case C_CS_NA_1:
IeTime56 ieTime56 = new IeTime56(System.currentTimeMillis());
log.debug("Got Clock synchronization command (103). Send current time: " + ieTime56.toString());
connection.synchronizeClocks(aSdu.getCommonAddress(), ieTime56);
break;
case C_SE_NB_1:
log.debug("Got Set point command, scaled value (49)");
break;
default:
log.debug("Got unknown request: " + aSdu.toString(),
". Send negative confirm with CoT UNKNOWN_TYPE_ID(44)");
connection.sendConfirmation(aSdu, aSdu.getCommonAddress(), true,
CauseOfTransmission.UNKNOWN_TYPE_ID);
}
} catch (EOFException e) {
log.debug("Will quit listening for commands on connection (" + connectionId,
") because socket was closed.");
} catch (Exception e) {
log.debug("Will quit listening for commands on connection (" + connectionId, ") because of error: ",
e.getMessage());
}
}
private void sendAll104(Connection conn) throws Exception {
List<Iec104Point> list = StaticVariable.point104_Cache;
for (Iec104Point item : list) {
this.sendOne104(conn, item);
}
}
private void sendOne104(Connection conn, Iec104Point item) throws Exception {
HashMap<String, String> map = StaticVariable.sensorLastDataMap.get(item.getEqmid());
String value = map.get(item.getField());
String time = map.get("acquisitionTime");
if (value != null && time != null) {
Date date = DateUtil.parse(time);
Float f = Float.valueOf(value);
InformationObject infoObj = new InformationObject(item.getSadr(), new InformationElement[][]{
{new IeShortFloat(f),
new IeQuality(false, false, false, false, false),
new IeTime56(date.getTime())}
});
ASdu obj = new ASdu(ASduType.M_ME_TF_1, true, CauseOfTransmission.INTERROGATED_BY_STATION,
false, false, 0, 1, infoObj);
conn.send(obj);
log.info("104服务端发送: sadr=" + item.getSadr() + ", value=" + value + ", time=" + time);
} else {
log.info("数据不全,104服务端不发送: sadr=" + item.getSadr() + ", value=" + value + ", time=" + time);
}
}
@Override
public void connectionClosed(Connection connection, IOException e) {
}
@Override
public void dataTransferStateChanged(Connection connection, boolean b) {
}
}

@ -0,0 +1,125 @@
package com.xydl.cac.model;
import lombok.Data;
import java.util.Iterator;
import java.util.Map;
@Data
public class SanbizhiModel {
Float c2h2;
Float c2h4;
Float ch4;
Float h2;
Float c2h6;
Float c2h2_c2h4_value;
String c2h2_c2h4_code;
Float ch4_h2_value;
String ch4_h2_code;
Float c2h4_c2h6_value;
String c2h4_c2h6_code;
String status;
String desc;
public boolean build(Map<String, Object> map) {
Iterator<String> it = map.keySet().iterator();
while (it.hasNext()) {
String key = it.next();
Object value = map.get(key);
String name = key.toLowerCase().replace("ppm", "");
if (value != null) {
if (name.equals("c2h2")) {
c2h2 = Float.parseFloat(value.toString());
} else if (name.equals("c2h4")) {
c2h4 = Float.parseFloat(value.toString());
} else if (name.equals("ch4")) {
ch4 = Float.parseFloat(value.toString());
} else if (name.equals("h2")) {
h2 = Float.parseFloat(value.toString());
} else if (name.equals("c2h6")) {
c2h6 = Float.parseFloat(value.toString());
}
}
}
if (c2h2 == null || c2h4 == null || ch4 == null || h2 == null || c2h6 == null) {
status = "必要数据缺失";
return false;
}
c2h2_c2h4_value = c2h2 / c2h4;
ch4_h2_value = ch4 / h2;
c2h4_c2h6_value = c2h4 / c2h6;
if (c2h2_c2h4_value < 0.1) {
c2h2_c2h4_code = "0";
} else if (c2h2_c2h4_value < 1) {
c2h2_c2h4_code = "1";
} else if (c2h2_c2h4_value < 3) {
c2h2_c2h4_code = "1";
} else {
c2h2_c2h4_code = "2";
}
if (ch4_h2_value < 0.1) {
ch4_h2_code = "1";
} else if (ch4_h2_value < 1) {
ch4_h2_code = "0";
} else if (ch4_h2_value < 3) {
ch4_h2_code = "2";
} else {
ch4_h2_code = "2";
}
if (c2h4_c2h6_value < 0.1) {
c2h4_c2h6_code = "0";
} else if (c2h4_c2h6_value < 1) {
c2h4_c2h6_code = "0";
} else if (c2h4_c2h6_value < 3) {
c2h4_c2h6_code = "1";
} else {
c2h4_c2h6_code = "2";
}
status = "正常";
if (c2h2_c2h4_code.equals("0")) {
if (c2h4_c2h6_code.equals("0")) {
if (ch4_h2_code.equals("0")) {
} else if (ch4_h2_code.equals("1")) {
status = "局部放电";
desc = "高湿度,高含气量引起油中低能量密度的局部放电";
} else if (ch4_h2_code.equals("2")) {
status = "低温过热(150-300)C";
desc = "分接开关接触不良,引线夹件螺丝松动或接头焊接不良,涡流引起铜过热,铁心漏磁,局部短路,层间绝缘不良,铁心多点接等";
}
} else if (c2h4_c2h6_code.equals("1")) {
if (ch4_h2_code.equals("0")) {
status = "低温过热(低于150C)";
desc = "绝缘导线过热注意CO和CO₂含量和CO₂/CO值";
} else if (ch4_h2_code.equals("1")) {
} else if (ch4_h2_code.equals("2")) {
status = "中温过热(300-700)C";
desc = "分接开关接触不良,引线夹件螺丝松动或接头焊接不良,涡流引起铜过热,铁心漏磁,局部短路,层间绝缘不良,铁心多点接等";
}
} else if (c2h4_c2h6_code.equals("2")) {
status = "高温过热(高于700C)";
desc = "分接开关接触不良,引线夹件螺丝松动或接头焊接不良,涡流引起铜过热,铁心漏磁,局部短路,层间绝缘不良,铁心多点接等";
}
} else if (c2h2_c2h4_code.equals("1")) {
if (ch4_h2_code.equals("0")) {
status = "低能放电";
} else if (ch4_h2_code.equals("1")) {
status = "低能放电";
} else if (ch4_h2_code.equals("2")) {
status = "低能放电兼过热";
}
desc = "引线对电位未固定的部件之间连续火花放电,分接抽头引线和油膜闪络,不同电位之间的油中火花放电或悬浮电位之间的火花放电";
} else if (c2h2_c2h4_code.equals("2")) {
if (ch4_h2_code.equals("0")) {
status = "电弧放电";
} else if (ch4_h2_code.equals("1")) {
status = "电弧放电";
} else if (ch4_h2_code.equals("2")) {
status = "电弧放电兼过热";
}
desc = "线圈匝间、层间短路,相间闪络,分接头引线间油膜闪络,引线对箱壳放电,线圈熔断,分接开关飞弧,因环路电流引起电弧,引线对其他接地体放电等";
}
return true;
}
}

@ -4,13 +4,20 @@ import com.beanit.iec61850bean.BasicDataAttribute;
import com.xydl.cac.entity.*;
import com.xydl.cac.iec.IecClient;
import com.xydl.cac.iec.IecServer;
import com.xydl.cac.iec104.Iec104Client;
import com.xydl.cac.iec104.Iec104Server;
import com.xydl.cac.util.DateUtil;
import org.apache.commons.lang3.StringUtils;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
public class StaticVariable {
public static String jarPath = "";
public static Iec104Server iec104Server = null;
public static Iec104Client realTime104Client = null;
public static HashMap<Integer, IecServer> iecServerMap = new HashMap<>();
public static HashMap<Integer, HashMap<String, String>> sensorLastDataMap = new HashMap<>();
public static HashMap<String, String> paramRelationMap = new HashMap<>();
@ -26,6 +33,8 @@ public class StaticVariable {
public static List<Jg> jg_Cache = null;
public static List<Zsb> zsb_Cache = null;
public static ConcurrentHashMap<Integer, WarnRule> rule_Cache = new ConcurrentHashMap<>();
public static HashMap<String, Integer> ruleRelationMap = new HashMap<>();
public static List<Iec104Point> point104_Cache = null;
// 更新服务端
@ -46,9 +55,22 @@ public class StaticVariable {
StaticVariable.sensorLastDataMap.put(eqmid, map);
}
map.put(colname, value);
if (time != null) {
if (StringUtils.isNotBlank(time)) {
map.put("acquisitionTime", time);
}
// 规则触发
String key = eqmid + "_" + colname;
if (StaticVariable.ruleRelationMap.containsKey(key)) {
Integer ruleId = StaticVariable.ruleRelationMap.get(key);
WarnRule rule = StaticVariable.rule_Cache.get(ruleId);
if (rule != null) {
boolean r = rule.triggerRule(value);
if (r) {
map.put(colname, value + ",1");
}
}
}
}
// 更新最新数据缓存

@ -0,0 +1,89 @@
package com.xydl.cac.model.spectrogram;
import lombok.Data;
import java.io.DataInputStream;
import java.util.ArrayList;
import java.util.List;
@Data
public class SouthPd extends SpectrogramModel {
Float version;
Float fileVersion;
Short code;
String flag;
String name;
String pdType;
String warnLevel;
String probabilityFlag;
Float probability1;
Float probability2;
Float probability3;
Float probability4;
Float probability5;
Float probability6;
Float probability7;
Integer m;
Integer n;
Integer p;
Float hz50;
Float hz100;
String picType;
String unit;
Float minLimit;
Float maxLimit;
List<List<Integer>> dataPD;
List<List<Float>> dataPS;
public void readFrom(DataInputStream dis) throws Exception {
version = readLittleEndianFloat(dis);
fileVersion = readLittleEndianFloat(dis);
code = readLittleEndianShort(dis);
createTime = readLittleEndianLong(dis);
flag = readString(dis, 1);
name = readString(dis, 32);
pdType = readString(dis, 1);
warnLevel = readString(dis, 1);
probabilityFlag = readString(dis, 1);
probability1 = readLittleEndianFloat(dis);
probability2 = readLittleEndianFloat(dis);
probability3 = readLittleEndianFloat(dis);
probability4 = readLittleEndianFloat(dis);
probability5 = readLittleEndianFloat(dis);
probability6 = readLittleEndianFloat(dis);
probability7 = readLittleEndianFloat(dis);
m = readLittleEndianInt(dis);
n = readLittleEndianInt(dis);
p = readLittleEndianInt(dis);
hz50 = readLittleEndianFloat(dis);
hz100 = readLittleEndianFloat(dis);
picType = readString(dis, 1);
unit = readString(dis, 1);
minLimit = readLittleEndianFloat(dis);
maxLimit = readLittleEndianFloat(dis);
dis.readInt();
if ("0".equalsIgnoreCase(picType)) {
dataPD = new ArrayList<>();
for (int i = 0; i < m; i++) {
List<Integer> list = new ArrayList<>();
for (int j = 0; j < n; j++) {
Integer v = readLittleEndianInt(dis);
list.add(v);
}
dataPD.add(list);
}
} else if ("1".equalsIgnoreCase(picType)) {
dataPS = new ArrayList<>();
for (int i = 0; i < p; i++) {
List<Float> list = new ArrayList<>();
for (int j = 0; j < m; j++) {
Float v = readLittleEndianFloat(dis);
list.add(v);
}
dataPS.add(list);
}
}
}
}

@ -0,0 +1,47 @@
package com.xydl.cac.model.spectrogram;
import lombok.Data;
import java.io.DataInputStream;
import java.util.ArrayList;
import java.util.List;
@Data
public class SouthYsp extends SpectrogramModel {
Float version;
Float fileVersion;
Short type;
String flag;
String name;
Float xInterval;
Float yMax;
String xUnit;
String yUnit;
Integer k;
Integer m;
List<SouthYspChannel> channels = new ArrayList<>();
public void readFrom(DataInputStream dis) throws Exception {
version = readLittleEndianFloat(dis);
fileVersion = readLittleEndianFloat(dis);
type = readLittleEndianShort(dis);
createTime = readLittleEndianLong(dis);
flag = readString(dis, 1);
name = readString(dis, 32);
xInterval = readLittleEndianFloat(dis);
yMax = readLittleEndianFloat(dis);
xUnit = readString(dis, 1);
yUnit = readString(dis, 1);
k = readLittleEndianInt(dis);
m = dis.read();
for (int i = 0; i < m; i++) {
SouthYspChannel channel = new SouthYspChannel();
channel.readFrom(dis);
channels.add(channel);
}
dis.readInt();
for (SouthYspChannel channel : channels) {
channel.readDataFrom(dis, k);
}
}
}

@ -0,0 +1,32 @@
package com.xydl.cac.model.spectrogram;
import lombok.Data;
import java.io.DataInputStream;
import java.util.ArrayList;
import java.util.List;
import static com.xydl.cac.model.spectrogram.SpectrogramModel.readLittleEndianFloat;
@Data
public class SouthYspChannel {
Integer n;
List<YspChannelCrest> crests = new ArrayList<>();
List<Float> data = new ArrayList<>();
public void readFrom(DataInputStream dis) throws Exception {
n = dis.read();
for (int i = 0; i < n; i++) {
YspChannelCrest crest = new YspChannelCrest();
crest.readFrom(dis);
crests.add(crest);
}
}
public void readDataFrom(DataInputStream dis, Integer k) throws Exception {
for (int i = 0; i < k; i++) {
Float v = readLittleEndianFloat(dis);
data.add(v);
}
}
}

@ -0,0 +1,59 @@
package com.xydl.cac.model.spectrogram;
import lombok.Data;
import java.io.DataInputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.charset.StandardCharsets;
@Data
public class SpectrogramModel {
Long createTime;
// 读取小端序的int4字节
public static int readLittleEndianInt(DataInputStream dis) throws IOException {
byte[] bytes = new byte[4];
dis.readFully(bytes);
return ByteBuffer.wrap(bytes)
.order(ByteOrder.LITTLE_ENDIAN)
.getInt();
}
// 读取小端序的short2字节
public static short readLittleEndianShort(DataInputStream dis) throws IOException {
byte[] bytes = new byte[2];
dis.readFully(bytes);
return ByteBuffer.wrap(bytes)
.order(ByteOrder.LITTLE_ENDIAN)
.getShort();
}
// 读取小端序的long8字节
public static long readLittleEndianLong(DataInputStream dis) throws IOException {
byte[] bytes = new byte[8];
dis.readFully(bytes);
return ByteBuffer.wrap(bytes)
.order(ByteOrder.LITTLE_ENDIAN)
.getLong();
}
// 读取小端序的float4字节
public static float readLittleEndianFloat(DataInputStream dis) throws IOException {
byte[] bytes = new byte[4];
dis.readFully(bytes);
return ByteBuffer.wrap(bytes)
.order(ByteOrder.LITTLE_ENDIAN)
.getFloat();
}
// 读取String
public static String readString(DataInputStream dis, int length) throws IOException {
byte[] bytes = new byte[length];
dis.readFully(bytes);
String str = new String(bytes, StandardCharsets.UTF_8);
return str.replaceAll("\u0000", "");
}
}

@ -0,0 +1,40 @@
package com.xydl.cac.model.spectrogram;
import lombok.Data;
import java.io.DataInputStream;
import java.util.ArrayList;
import java.util.List;
@Data
public class Ysp extends SpectrogramModel {
Integer code;
Integer length;
Long createTime;
Integer flag;
Float xInterval;
Float yMax;
Integer xUnit;
Integer yUnit;
Integer k;
Integer m;
List<YspChannel> channels = new ArrayList<>();
public void readFrom(DataInputStream dis) throws Exception {
code = dis.read();
length = readLittleEndianInt(dis);
createTime = readLittleEndianLong(dis);
flag = dis.read();
xInterval = readLittleEndianFloat(dis);
yMax = readLittleEndianFloat(dis);
xUnit = dis.read();
yUnit = dis.read();
k = readLittleEndianInt(dis);
m = dis.read();
for (int i = 0; i < m; i++) {
YspChannel channel = new YspChannel();
channel.readFrom(dis, k);
channels.add(channel);
}
}
}

@ -0,0 +1,29 @@
package com.xydl.cac.model.spectrogram;
import lombok.Data;
import java.io.DataInputStream;
import java.util.ArrayList;
import java.util.List;
import static com.xydl.cac.model.spectrogram.SpectrogramModel.readLittleEndianFloat;
@Data
public class YspChannel {
Integer n;
List<YspChannelCrest> crests = new ArrayList<>();
List<Float> data = new ArrayList<>();
public void readFrom(DataInputStream dis, Integer k) throws Exception {
n = dis.read();
for (int i = 0; i < n; i++) {
YspChannelCrest crest = new YspChannelCrest();
crest.readFrom(dis);
crests.add(crest);
}
for (int i = 0; i < k; i++) {
Float v = readLittleEndianFloat(dis);
data.add(v);
}
}
}

@ -0,0 +1,28 @@
package com.xydl.cac.model.spectrogram;
import lombok.Data;
import java.io.DataInputStream;
import static com.xydl.cac.model.spectrogram.SpectrogramModel.*;
@Data
public class YspChannelCrest {
String name;
Integer j;
Float time;
Float startTime;
Float endTime;
Float height;
Float area;
public void readFrom(DataInputStream dis) throws Exception {
name = readString(dis, 10);
j = dis.read();
time = readLittleEndianFloat(dis);
startTime = readLittleEndianFloat(dis);
endTime = readLittleEndianFloat(dis);
height = readLittleEndianFloat(dis);
area = readLittleEndianFloat(dis);
}
}

@ -0,0 +1,13 @@
package com.xydl.cac.repository;
import com.xydl.cac.entity.Iec104Point;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface Iec104PointRepository extends JpaRepository<Iec104Point, Integer>, JpaSpecificationExecutor<Iec104Point> {
List<Iec104Point> findBySadr(Integer sadr);
}

@ -13,7 +13,7 @@ public interface RptparamindexRepository extends JpaRepository<Rptparamindex, St
List<Rptparamindex> findAllByEqmid(Integer eqmid);
List<Rptparamindex> findAllByEqmidInAndColnameIsNotNull(List<Integer> eqmidList);
List<Rptparamindex> findAllByEqmidInAndColnameIsNotNullAndTablenameIsNotNull(List<Integer> eqmidList);
List<Rptparamindex> findAllByParamindexStartingWith(String param);

@ -0,0 +1,12 @@
package com.xydl.cac.repository;
import com.xydl.cac.entity.ThermalConfig;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.stereotype.Repository;
@Repository
public interface ThermalConfigRepository extends JpaRepository<ThermalConfig, Integer>, JpaSpecificationExecutor<ThermalConfig> {
}

@ -3,10 +3,17 @@ package com.xydl.cac.repository;
import com.xydl.cac.entity.Warning;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
@Repository
public interface WarningRepository extends JpaRepository<Warning, Integer>, JpaSpecificationExecutor<Warning> {
@Modifying
@Query("update Warning set state = :frontState where state = :afterState")
int updateWarningState(@Param("frontState") String frontState , @Param("afterState") String afterState);
}

@ -14,6 +14,8 @@ public interface DataService {
List<ColumnModel> getDataTableColumns(String tableName);
String getFieldType(String tableName, String field);
OnePage<Map<String, Object>> getData(String tableName, Integer devId, List<ModevTypePoint> points, ConditionModel model) throws Exception;
void clearAllBind();
@ -23,4 +25,5 @@ public interface DataService {
Map<String, Object> getLastOneData(String tableName, Integer devId, ModevTypePoint point) throws Exception;
void insertData(String tableName, Integer devId, String time, String colname, String value);
}

@ -0,0 +1,16 @@
package com.xydl.cac.service;
import com.xydl.cac.entity.Iec104Point;
import com.xydl.cac.exception.BusinessException;
import java.util.List;
public interface Iec104PointService {
List<Iec104Point> findAll();
Iec104Point add(Iec104Point point) throws BusinessException;
void delete(Integer id);
}

@ -1,13 +1,20 @@
package com.xydl.cac.service;
import com.xydl.cac.entity.IedDlRecord;
import com.xydl.cac.exception.BusinessException;
import org.springframework.data.domain.Page;
import java.util.Date;
public interface IedDlRecordService {
Page<IedDlRecord> list(Integer configId, int pageNum, int pageSize) throws Exception;
Page<IedDlRecord> list(Integer configId, Integer devId, Date startTime, Date endTime, int pageNum, int pageSize) throws Exception;
void add(IedDlRecord item);
boolean exist(IedDlRecord item);
void update(IedDlRecord item);
void rebuildData(Integer id) throws BusinessException;
}

@ -0,0 +1,11 @@
package com.xydl.cac.service;
import com.xydl.cac.entity.ThermalConfig;
public interface ThermalConfigService {
ThermalConfig getConfig();
void saveConfig(ThermalConfig model);
}

@ -15,5 +15,5 @@ public interface WarningService {
void updateState(Warning warning) throws Exception;
void oneKeyUpdateState(List<Warning> warnings);
void oneKeyUpdateState();
}

@ -26,6 +26,8 @@ import java.util.Date;
import java.util.List;
import java.util.Map;
import static com.xydl.cac.entity.constants.Constants.I2BatchSize;
@Service
@Slf4j
@Transactional(rollbackFor = Exception.class)
@ -235,7 +237,11 @@ public class DataServiceImpl implements DataService {
String sqlSelect = "SELECT DATE_FORMAT(" + timeField + ", '%Y-%m-%d %H:%i:%s') as acquisitionTime";
for (ModevTypePoint point : points) {
if (StringUtils.isNotBlank(point.getField())) {
sqlSelect = sqlSelect + ", " + point.getField();
if (Constants.DateTime.equalsIgnoreCase(point.getType())) {
sqlSelect = sqlSelect + ", " + "DATE_FORMAT(" + point.getField() + ", '%Y-%m-%d %H:%i:%s') as " + point.getField();
} else {
sqlSelect = sqlSelect + ", " + point.getField();
}
}
}
@ -259,7 +265,7 @@ public class DataServiceImpl implements DataService {
@Override
public List<Map<String, Object>> getLatestData(String tableName, Integer devId, List<ModevTypePoint> points, Date start) throws Exception {
ConditionModel model = new ConditionModel();
model.setPageSize(500);
model.setPageSize(I2BatchSize);
model.setPageNum(1);
model.setStartTime(start);
model.setExcludeStartTime(true);
@ -289,6 +295,12 @@ public class DataServiceImpl implements DataService {
@Override
public void insertData(String tableName, Integer devId, String time, String colname, String value) {
if (StringUtils.isBlank(tableName)) {
return;
}
if (StringUtils.isBlank(colname)) {
return;
}
String devField = DataTable.getDevidField(tableName);
String timeField = this.getTimeField(tableName);
String sqlFrom = " FROM " + tableName;

@ -0,0 +1,47 @@
package com.xydl.cac.service.impl;
import com.xydl.cac.entity.Iec104Point;
import com.xydl.cac.exception.BusinessException;
import com.xydl.cac.model.StaticVariable;
import com.xydl.cac.repository.Iec104PointRepository;
import com.xydl.cac.service.Iec104PointService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
@Service
@Slf4j
@Transactional(rollbackFor = Exception.class)
public class Iec104PointServiceImpl implements Iec104PointService {
@Resource
Iec104PointRepository iec104PointRepository;
@Override
public List<Iec104Point> findAll() {
StaticVariable.point104_Cache = iec104PointRepository.findAll();
return StaticVariable.point104_Cache;
}
@Override
public Iec104Point add(Iec104Point point) throws BusinessException {
List<Iec104Point> list = iec104PointRepository.findBySadr(point.getSadr());
if (CollectionUtils.isEmpty(list)) {
point.setId(null);
point.setCreateTime(new Date());
return iec104PointRepository.save(point);
} else {
throw new BusinessException("该点位已存在");
}
}
@Override
public void delete(Integer id) {
iec104PointRepository.deleteById(id);
}
}

@ -2,40 +2,55 @@ package com.xydl.cac.service.impl;
import com.xydl.cac.entity.IedDlConfig;
import com.xydl.cac.entity.IedDlRecord;
import com.xydl.cac.exception.BusinessException;
import com.xydl.cac.repository.IedDlRecordRepository;
import com.xydl.cac.service.IedDlConfigService;
import com.xydl.cac.service.IedDlRecordService;
import com.xydl.cac.spectrogram.SpectrogramHandler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import javax.annotation.Resource;
import javax.persistence.criteria.Predicate;
import java.util.Date;
import java.util.List;
import java.util.Optional;
@Service
@Slf4j
@Transactional(rollbackFor = Exception.class)
public class IedDlRecordServiceImpl implements IedDlRecordService {
@Resource
IedDlRecordRepository repository;
@Resource
IedDlConfigService configService;
@Resource
SpectrogramHandler spectrogramHandler;
@Override
public Page<IedDlRecord> list(Integer configId, int pageNum, int pageSize) throws Exception {
public Page<IedDlRecord> list(Integer configId, Integer devId, Date startTime, Date endTime, int pageNum, int pageSize) throws Exception {
PageRequest request = PageRequest.of(pageNum - 1, pageSize);
Specification<IedDlRecord> specification = (root, query, builder) -> {
Predicate predicate = builder.conjunction();
if (configId != null) {
predicate.getExpressions().add(builder.equal(root.get("configId"), configId));
query.orderBy(builder.desc(root.get("dTime")));
} else if (devId != null) {
predicate.getExpressions().add(builder.equal(root.get("devId"), devId));
query.orderBy(builder.desc(root.get("dTime")));
} else {
query.orderBy(builder.desc(root.get("id")));
}
if (startTime != null) {
predicate.getExpressions().add(builder.greaterThan(root.get("dTime"), startTime));
}
if (endTime != null) {
predicate.getExpressions().add(builder.lessThanOrEqualTo(root.get("dTime"), endTime));
}
query.orderBy(builder.desc(root.get("id")));
return predicate;
};
Page<IedDlRecord> result = repository.findAll(specification, request);
@ -48,6 +63,7 @@ public class IedDlRecordServiceImpl implements IedDlRecordService {
break;
}
}
spectrogramHandler.jsonToModel(item);
}
}
return result;
@ -69,4 +85,20 @@ public class IedDlRecordServiceImpl implements IedDlRecordService {
}
}
@Override
public void update(IedDlRecord item) {
repository.save(item);
}
@Override
public void rebuildData(Integer id) throws BusinessException {
Optional<IedDlRecord> optional = repository.findById(id);
if (!optional.isPresent()) {
throw new BusinessException("未找到该记录");
}
IedDlRecord record = optional.get();
spectrogramHandler.processFile(record);
repository.save(record);
}
}

@ -105,7 +105,7 @@ public class JgServiceImpl implements JgService {
item.setId(null);
Optional<Bdz> optionalBdz = bdzRepository.findById(item.getBdzid());
if (!optionalBdz.isPresent()) {
throw new BusinessException("未找到该变电站");
throw new BusinessException("未找到该变电站id=" + item.getBdzid());
}
List<Jg> list = repository.findByBdzidAndMc(item.getBdzid(), item.getMc());
if (!CollectionUtils.isEmpty(list)) {
@ -119,7 +119,7 @@ public class JgServiceImpl implements JgService {
public void update(Jg item) throws Exception {
Optional<Bdz> optionalBdz = bdzRepository.findById(item.getBdzid());
if (!optionalBdz.isPresent()) {
throw new BusinessException("未找到该变电站");
throw new BusinessException("未找到该变电站id=" + item.getBdzid());
}
List<Jg> list = repository.findByBdzidAndMcAndIdIsNot(item.getBdzid(), item.getMc(), item.getId());
if (!CollectionUtils.isEmpty(list)) {
@ -144,7 +144,7 @@ public class JgServiceImpl implements JgService {
public Jg detail(Integer id) throws Exception {
Optional<Jg> optional = repository.findById(id);
if (!optional.isPresent()) {
throw new BusinessException("未找到该区域");
throw new BusinessException("未找到该区域id=" + id);
}
Jg jg = optional.get();
Optional<Bdz> optionalBdz = bdzRepository.findById(jg.getBdzid());

@ -60,6 +60,7 @@ public class NSensorServiceImpl implements NSensorService {
if (typeId != null) {
predicate.getExpressions().add(builder.equal(root.get("typeId"), typeId));
}
query.orderBy(builder.asc(root.get("orderNum")));
return predicate;
};
List<NSensor> list = repository.findAll(specification);
@ -210,6 +211,19 @@ public class NSensorServiceImpl implements NSensorService {
// 获取数据
SensorDetail<Map<String, Object>> result = this.getData(sensor, points, model);
if (sensor.getTypeName().contains("油色谱")) {
if (result.getContent() != null) {
for (Map<String, Object> map : result.getContent()) {
SanbizhiModel sanbizhi = new SanbizhiModel();
try {
sanbizhi.build(map);
} catch (Exception ignore) {
sanbizhi.setStatus("有异常数据");
}
map.put("sanbizhi", sanbizhi);
}
}
}
return result;
}

@ -12,11 +12,13 @@ import com.xydl.cac.service.ModevTypeService;
import com.xydl.cac.service.ParamBindService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import javax.annotation.Resource;
import javax.persistence.criteria.Predicate;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@ -82,7 +84,12 @@ public class ParamBindServiceImpl implements ParamBindService {
for (Zsb zsb : zsbList) {
zsbMap.put(zsb.getId(), zsb);
}
List<NSensor> sensorList = sensorRepository.findAll();
Specification<NSensor> specification = (root, query, builder) -> {
Predicate predicate = builder.conjunction();
query.orderBy(builder.asc(root.get("orderNum")));
return predicate;
};
List<NSensor> sensorList = sensorRepository.findAll(specification);
// 每一个放入上一层
for (NSensor sensor : sensorList) {

@ -0,0 +1,38 @@
package com.xydl.cac.service.impl;
import com.xydl.cac.entity.ThermalConfig;
import com.xydl.cac.repository.ThermalConfigRepository;
import com.xydl.cac.service.ThermalConfigService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import javax.annotation.Resource;
import java.util.List;
@Service
@Slf4j
@Transactional(rollbackFor = Exception.class)
public class ThermalConfigServiceImpl implements ThermalConfigService {
@Resource
ThermalConfigRepository repository;
@Override
public ThermalConfig getConfig() {
ThermalConfig result = null;
List<ThermalConfig> list = repository.findAll();
if (!CollectionUtils.isEmpty(list)) {
result = list.get(0);
}
return result;
}
@Override
public void saveConfig(ThermalConfig model) {
repository.deleteAll();
model.setId(null);
repository.save(model);
}
}

@ -78,7 +78,7 @@ public class WarnRuleServiceImpl implements WarnRuleService {
public void update(WarnRule item) throws Exception {
Optional<WarnRule> optional = repository.findById(item.getId());
if (!optional.isPresent()) {
throw new BusinessException("未找到该告警规则");
throw new BusinessException("未找到该告警规则id=" + item.getId());
}
WarnRule rule = optional.get();
rule.setComparator(item.getComparator());

@ -97,7 +97,7 @@ public class WarningServiceImpl implements WarningService {
public void updateState(Warning warning) throws Exception {
Optional<Warning> byId = repository.findById(warning.getId());
if (!byId.isPresent()) {
throw new BusinessException("未找到该告警" + warning.getId());
throw new BusinessException("未找到该告警id=" + warning.getId());
}
Warning war = byId.get();
war.setState(warning.getState());
@ -106,15 +106,8 @@ public class WarningServiceImpl implements WarningService {
}
@Override
public void oneKeyUpdateState(List<Warning> warnings) {
Date date = new Date();
for (Warning warning : warnings) {
warning.setState("0");
warning.setProcessTime(date);
}
if (null != warnings && warnings.size() > 0) {
repository.saveAll(warnings);
}
public void oneKeyUpdateState() {
repository.updateWarningState("0", "1");
}

@ -93,7 +93,7 @@ public class ZsbServiceImpl implements ZsbService {
item.setBdzid(jg.getBdzid());
Optional<Lx> optionalLx = lxRepository.findById(item.getLxid());
if (!optionalLx.isPresent()) {
throw new BusinessException("未找到该设备类型");
throw new BusinessException("未找到该设备类型id=" + item.getLxid());
}
List<Zsb> list = repository.findByJgidAndMc(item.getJgid(), item.getMc());
if (!CollectionUtils.isEmpty(list)) {
@ -109,7 +109,7 @@ public class ZsbServiceImpl implements ZsbService {
item.setBdzid(jg.getBdzid());
Optional<Lx> optionalLx = lxRepository.findById(item.getLxid());
if (!optionalLx.isPresent()) {
throw new BusinessException("未找到该设备类型");
throw new BusinessException("未找到该设备类型id=" + item.getLxid());
}
List<Zsb> list = repository.findByJgidAndMcAndIdIsNot(item.getJgid(), item.getMc(), item.getId());
if (!CollectionUtils.isEmpty(list)) {
@ -133,7 +133,7 @@ public class ZsbServiceImpl implements ZsbService {
public Zsb detail(Integer id) throws Exception {
Optional<Zsb> optional = repository.findById(id);
if (!optional.isPresent()) {
throw new BusinessException("未找到该主设备");
throw new BusinessException("未找到该主设备id=" + id);
}
Zsb zsb = optional.get();
Jg jg = jgService.detail(zsb.getJgid());

@ -0,0 +1,34 @@
package com.xydl.cac.spectrogram;
import com.xydl.cac.model.spectrogram.SouthPd;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.io.DataInputStream;
import java.io.FileInputStream;
@Service
@Slf4j
public class ProcessorPd {
public SouthPd process(String localFilePath) {
try (DataInputStream dis = new DataInputStream(new FileInputStream(localFilePath))) {
SouthPd model = this.readOneBlock(dis);
return model;
} catch (Exception e) {
log.error("解析文件失败" + localFilePath, e);
return null;
}
}
private SouthPd readOneBlock(DataInputStream dis) throws Exception {
SouthPd model = new SouthPd();
model.readFrom(dis);
return model;
}
public static void main(String[] args) {
ProcessorPd processorYsp = new ProcessorPd();
processorYsp.process("C:/Code/cac/局放谱图/50100055_5__001_01_20250409180000.dat");
}
}

@ -0,0 +1,34 @@
package com.xydl.cac.spectrogram;
import com.xydl.cac.model.spectrogram.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.io.DataInputStream;
import java.io.FileInputStream;
@Service
@Slf4j
public class ProcessorYsp {
public SouthYsp process(String localFilePath) {
try (DataInputStream dis = new DataInputStream(new FileInputStream(localFilePath))) {
SouthYsp model = this.readOneBlock(dis);
return model;
} catch (Exception e) {
log.error("解析文件失败" + localFilePath, e);
return null;
}
}
private SouthYsp readOneBlock(DataInputStream dis) throws Exception {
SouthYsp model = new SouthYsp();
model.readFrom(dis);
return model;
}
public static void main(String[] args) {
ProcessorYsp processorYsp = new ProcessorYsp();
processorYsp.process("C:/Code/cac/谱图文件/0312B12000042A3840001_203_07_20250113163055.dat");
}
}

@ -0,0 +1,93 @@
package com.xydl.cac.spectrogram;
import com.xydl.cac.config.BizConfig;
import com.xydl.cac.entity.IedDlRecord;
import com.xydl.cac.entity.ModevType;
import com.xydl.cac.model.spectrogram.SouthPd;
import com.xydl.cac.model.spectrogram.SouthYsp;
import com.xydl.cac.model.spectrogram.SpectrogramModel;
import com.xydl.cac.service.ModevTypeService;
import com.xydl.cac.util.DateUtil;
import com.xydl.cac.util.JSONUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.Date;
@Service
@Slf4j
public class SpectrogramHandler {
@Resource
BizConfig bizConfig;
@Resource
ModevTypeService modevTypeService;
@Resource
ProcessorYsp processorYsp;
@Resource
ProcessorPd processorPd;
public void processFile(IedDlRecord record) {
record.setCreateTime(new Date());
if (record.getTypeId() == null) {
return;
}
String localFilePath = record.getPath().replaceFirst(bizConfig.getDataNginxPath(), bizConfig.getDatapath());
try {
ModevType modevType = modevTypeService.detail(record.getTypeId());
// 谱图解析
if (modevType.getMc().contains("油色谱")) {
SouthYsp model = processorYsp.process(localFilePath);
this.setData(record, model);
log.info("解析油色谱谱图文件成功");
} else if (modevType.getMc().contains("局部放电")) {
SouthPd model = processorPd.process(localFilePath);
this.setData(record, model);
log.info("解析局部放电谱图文件成功");
} else {
log.error("缺少该类型" + record.getTypeId() + "的谱图处理模块");
}
} catch (Exception ex) {
log.error("解析谱图文件失败, typeId=" + record.getTypeId() + ", devId=" + record.getDevId()
+ ", file=" + localFilePath, ex);
}
}
private void setData(IedDlRecord record, SpectrogramModel model) {
String json = JSONUtil.object2Json(model);
record.setData(json);
try {
String str = String.valueOf(model.getCreateTime());
Date dtime = DateUtil.parse(str, "yyyyMMddHHmmss");
record.setDTime(dtime);
} catch (Exception ignore) {
}
}
public void jsonToModel(IedDlRecord record) {
if (record.getTypeId() == null) {
return;
}
if (record.getData() == null) {
return;
}
try {
ModevType modevType = modevTypeService.detail(record.getTypeId());
if (modevType.getMc().contains("油色谱")) {
SouthYsp model = JSONUtil.json2Object(record.getData(), SouthYsp.class);
record.setModel(model);
record.setData(null);
} else if (modevType.getMc().contains("局部放电")) {
SouthPd model = JSONUtil.json2Object(record.getData(), SouthPd.class);
record.setModel(model);
record.setData(null);
}
} catch (Exception ex) {
log.error("谱图数据data内容存在异常, typeId=" + record.getTypeId() + ", devId=" + record.getDevId()
+ ", file=" + record.getPath());
}
}
}

@ -1,14 +1,15 @@
package com.xydl.cac.task;
import com.xydl.cac.config.BizConfig;
import com.xydl.cac.entity.IcdIed;
import com.xydl.cac.entity.IedDlConfig;
import com.xydl.cac.entity.Rptparamindex;
import com.xydl.cac.entity.*;
import com.xydl.cac.iec.IEDCollectService;
import com.xydl.cac.repository.*;
import com.xydl.cac.service.DataService;
import com.xydl.cac.service.IedDlRecordService;
import com.xydl.cac.socket.WebSocketServer;
import com.xydl.cac.spectrogram.SpectrogramHandler;
import com.xydl.cac.util.JkpgFtp;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
@ -17,6 +18,8 @@ import java.util.List;
@Service
public class AsyncTask {
@Value("${cac.61850.warning:true}")
public boolean warning;
@Resource
IcdConfigTypeRepository configRepository;
@Resource
@ -35,6 +38,10 @@ public class AsyncTask {
BizConfig bizConfig;
@Resource
WarningRepository warningRepository;
@Resource
SpectrogramHandler spectrogramHandler;
@Resource
JkpgFtp jkpgFtp;
@Async
public void collectIed(String xml, IcdIed ied, List<Rptparamindex> rptList, List<IedDlConfig> dlList) {
@ -42,8 +49,9 @@ public class AsyncTask {
instRepository, rptparamindexRepository,
dlRecordService, dataService,
xml, ied,
webSocketServer, bizConfig,
warningRepository);
webSocketServer, bizConfig, warning,
warningRepository, spectrogramHandler,
jkpgFtp);
iedService.collectAndSave(rptList, dlList);
}
}

@ -1,7 +1,9 @@
package com.xydl.cac.task;
import com.xydl.cac.entity.Iec104Point;
import com.xydl.cac.entity.WarnRule;
import com.xydl.cac.model.StaticVariable;
import com.xydl.cac.service.Iec104PointService;
import com.xydl.cac.service.WarnRuleService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
@ -16,24 +18,27 @@ public class CacheTask {
@Resource
WarnRuleService ruleService;
@Resource
Iec104PointService iec104PointService;
@Scheduled(cron = "0 0 1 * * ?")
private void clearCache1() {
public void clearCache1() {
StaticVariable.unit_Cache.clear();
StaticVariable.modevType_Cache = null;
StaticVariable.jg_Cache = null;
StaticVariable.zsb_Cache = null;
StaticVariable.rule_Cache.clear();
StaticVariable.ruleRelationMap.clear();
StaticVariable.paramRelationMap.clear();
}
@Scheduled(cron = "0 30 9 * * ?")
private void clearCache9() {
public void clearCache9() {
StaticVariable.doneWarnMap.clear();
}
@Scheduled(initialDelay = 30 * 1000, fixedDelay = 60 * 1000)
private void refreshRule() {
public void refreshRule() {
try {
List<WarnRule> list = ruleService.listAll(null);
for (WarnRule item : list) {
@ -42,9 +47,18 @@ public class CacheTask {
item.initComparator(item.getComparator(), item.getOperator());
StaticVariable.rule_Cache.put(item.getId(), item);
}
if (item.getNSensor() != null && item.getTypePoint() != null) {
String key = item.getNSensor().getDevId() + "_" + item.getTypePoint().getField();
StaticVariable.ruleRelationMap.put(key, item.getId());
}
}
} catch (Exception e) {
log.error("CacheTask.refreshRule error.", e);
}
}
@Scheduled(initialDelay = 5 * 60 * 1000, fixedDelay = 5 * 60 * 1000)
public void refresh104() {
iec104PointService.findAll();
}
}

@ -24,6 +24,8 @@ public class Client61850Task {
@Value("${cac.61850.enable:true}")
public boolean enable;
@Value("${cac.61850.check:false}")
public boolean check;
@Resource
AsyncTask asyncTask;
@Resource
@ -83,16 +85,24 @@ public class Client61850Task {
return;
}
List<Rptparamindex> rptList = rptparamindexRepository.findAllByEqmidInAndColnameIsNotNull(eqmidList);
List<Rptparamindex> rptList = rptparamindexRepository.findAllByEqmidInAndColnameIsNotNullAndTablenameIsNotNull(eqmidList);
List<IedDlConfig> dlList = dlConfigRepository.findByDevIdIn(eqmidList);
if (CollectionUtils.isEmpty(rptList) && CollectionUtils.isEmpty(dlList)) {
return;
}
List<IedDlConfig> dlNewList = new ArrayList<>();
for (IedDlConfig item : dlList) {
List<NSensor> senList = sensorRepository.findByDevId(item.getDevId());
if (!CollectionUtils.isEmpty(senList)) {
item.setSensor(senList.get(0));
dlNewList.add(item);
}
}
List<IcdFile> icdFileList = fileRepository.findAll();
if (!CollectionUtils.isEmpty(icdFileList)) {
for (IcdFile icdFile : icdFileList) {
this.collectIcdFile(icdFile, rptList, dlList);
this.collectIcdFile(icdFile, rptList, dlNewList);
}
}
}
@ -111,7 +121,7 @@ public class Client61850Task {
@Scheduled(initialDelay = 60 * 1000, fixedDelay = 60 * 1000)
private void testAll() {
if (!enable) {
if (!check) {
return;
}
List<IcdIed> iedTestList = new ArrayList<>();

@ -0,0 +1,85 @@
package com.xydl.cac.task;
import com.xydl.cac.entity.ModevType;
import com.xydl.cac.entity.NSensor;
import com.xydl.cac.entity.ThermalConfig;
import com.xydl.cac.repository.NSensorRepository;
import com.xydl.cac.service.ModevTypeService;
import com.xydl.cac.service.ThermalConfigService;
import com.xydl.cac.thermal.ThermalCollectService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import javax.annotation.PreDestroy;
import javax.annotation.Resource;
import java.util.*;
@Service
@Slf4j
public class ClientThermalTask {
@Resource
ThermalConfigService configService;
@Resource
ModevTypeService modevTypeService;
@Resource
NSensorRepository sensorRepository;
@Resource
ThermalCollectService collectService;
int shutdown = 0;
boolean inDoing = false;
@PreDestroy
private void preDestroy() {
shutdown = 1;
}
@Scheduled(cron = "0 * * * * ?")
public void collectAll() {
ThermalConfig config = configService.getConfig();
if (config == null) {
return;
}
if (inDoing) {
return;
}
inDoing = true;
try {
Calendar cal = Calendar.getInstance();
int h = cal.get(Calendar.HOUR_OF_DAY);
int m = cal.get(Calendar.MINUTE);
m = h * 60 + m;
ModevType modevType = modevTypeService.detail(config.getTypeId());
int intervals = 30;
if (modevType.getIntervals() != null) {
intervals = modevType.getIntervals();
}
int x = m % intervals;
if (x == 0) {
this.collectOneConfig(config, modevType);
}
} catch (Exception e) {
log.error("ClientThermalTask.collectAll error.", e);
} finally {
inDoing = false;
}
}
private void collectOneConfig(ThermalConfig config, ModevType modevType) {
if (shutdown == 1) {
return;
}
List<NSensor> list = sensorRepository.findByTypeId(modevType.getId());
if (CollectionUtils.isEmpty(list)) {
return;
}
for (NSensor sensor : list) {
sensor.setTableName(modevType.getTablename());
}
collectService.collectAndSave(list, config);
}
}

@ -22,6 +22,8 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import static com.xydl.cac.entity.constants.Constants.I2BatchSize;
@Service
@Slf4j
public class I2syncTask {
@ -89,6 +91,8 @@ public class I2syncTask {
for (I2syncField field : fieldList) {
ModevTypePoint point = new ModevTypePoint();
point.setField(field.getFieldName());
String type = dataService.getFieldType(config.getTableName(), point.getField());
point.setType(type);
points.add(point);
}
List<NSensor> list = sensorRepository.findByTypeId(config.getModevtypeId());
@ -133,7 +137,7 @@ public class I2syncTask {
log.info("I2syncTask.syncOneSensor 同步导出" + sensor.getName() + "(" + sensor.getSensorCode() + ") "
+ count + "条数据,最后数据时间" + DateUtil.format(record.getLastDTime()));
if (count >= 1000) {
if (count >= I2BatchSize) {
dataList.clear();
this.syncOneSensor(sensor, config, fieldList, points);
}

@ -77,7 +77,8 @@ public class RuleCheckTask {
for (TriggerModel model : warnList) {
this.sendWarning(rule, model);
}
if (rule.getNotifyCom() != null && rule.getNotifyCom().intValue() == Constants.TRUE) {
if (warnList.size() > 0 &&
rule.getNotifyCom() != null && rule.getNotifyCom().intValue() == Constants.TRUE) {
// 通知串口
serialPortServer.sendData();
}

@ -0,0 +1,50 @@
package com.xydl.cac.thermal;
import com.hcsdk.HCNetSDK;
import com.sun.jna.Pointer;
import com.xydl.cac.entity.NSensor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
@Service
@Slf4j
public class HCRemoteConfigCallBack implements HCNetSDK.FRemoteConfigCallBack {
public boolean done;
public NSensor item;
public String time;
public HCThermalService service;
@Override
public void invoke(int dwType, Pointer lpBuffer, int dwBufLen, Pointer pUserData) {
if (done) {
return;
}
try {
HCNetSDK.NET_DVR_THERMOMETRY_UPLOAD data = new HCNetSDK.NET_DVR_THERMOMETRY_UPLOAD();
Pointer pointer = data.getPointer();
pointer.write(0, lpBuffer.getByteArray(0, data.size()), 0, data.size());
data.read();
float max, min, aver;
if (0 == data.byRuleCalibType) {
max = data.struPointThermCfg.fTemperature;
min = max;
aver = max;
log.info("海康热成像采集到max=" + max + ", min=" + min + ", aver=" + aver);
service.save(item.getTableName(), item.getDevId(),
max, min, aver, time);
done = true;
} else if (1 == data.byRuleCalibType || 2 == data.byRuleCalibType) {
max = data.struLinePolygonThermCfg.fAverageTemperature;
min = data.struLinePolygonThermCfg.fMinTemperature;
aver = data.struLinePolygonThermCfg.fMaxTemperature;
log.info("海康热成像采集到max=" + max + ", min=" + min + ", aver=" + aver);
service.save(item.getTableName(), item.getDevId(),
max, min, aver, time);
done = true;
}
} catch (Exception ex) {
log.error("HCRemoteConfigCallBack异常", ex);
}
}
}

@ -0,0 +1,99 @@
package com.xydl.cac.thermal;
import com.hcsdk.HCModule;
import com.xydl.cac.entity.NSensor;
import com.xydl.cac.entity.ThermalConfig;
import com.xydl.cac.model.StaticVariable;
import com.xydl.cac.service.DataService;
import com.xydl.cac.util.DateUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import javax.annotation.PreDestroy;
import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
@Service
@Slf4j
public class HCThermalService {
@Resource
DataService dataService;
@Resource
HCRemoteConfigCallBack _callBack;
ThermalConfig _config;
int shutdown = 0;
@PreDestroy
private void preDestroy() {
shutdown = 1;
}
public void collectAndSave(List<NSensor> list, ThermalConfig config) {
if (shutdown == 1) {
return;
}
_config = config;
try {
HCModule.init();
NSensor sensor = list.get(0);
boolean r = HCModule.login(sensor.getIp(), sensor.getPort().shortValue(), sensor.getUsername(), sensor.getPasswd());
if (r) {
log.info("海康热成像登入成功" + sensor.getIp() + ":" + sensor.getPort()
+ ", 用户名:" + sensor.getUsername() + ", 密码:" + sensor.getPasswd());
} else {
return;
}
for (NSensor item : list) {
_callBack.done = false;
_callBack.item = item;
_callBack.time = DateUtil.format(new Date());
_callBack.service = this;
r = HCModule.startRemoteConfig(_callBack, 2, item.getTmId());
if (r) {
int sec = 0;
while (shutdown == 0 && sec < 20 && !_callBack.done) {
try {
Thread.sleep(1000);
sec++;
} catch (Exception ignore) {
}
}
HCModule.stopRemoteConfig();
}
}
HCModule.logout();
} catch (Exception ex) {
log.error("海康热成像测温采集异常, " + ex.getMessage(), ex);
} finally {
HCModule.cleanup();
}
}
@Async
public void save(String tableName, Integer devId,
float max, float min, float aver, String time) {
if (StringUtils.isNotBlank(_config.getMaxtemp())) {
String value = String.valueOf(max);
dataService.insertData(tableName, devId, time, _config.getMaxtemp(), value);
// 更新最新数据缓存
StaticVariable.updateLastData(devId, _config.getMaxtemp(), value, time);
}
if (StringUtils.isNotBlank(_config.getMintemp())) {
String value = String.valueOf(min);
dataService.insertData(tableName, devId, time, _config.getMintemp(), value);
// 更新最新数据缓存
StaticVariable.updateLastData(devId, _config.getMintemp(), value, time);
}
if (StringUtils.isNotBlank(_config.getAvertemp())) {
String value = String.valueOf(aver);
dataService.insertData(tableName, devId, time, _config.getAvertemp(), value);
// 更新最新数据缓存
StaticVariable.updateLastData(devId, _config.getAvertemp(), value, time);
}
}
}

@ -0,0 +1,39 @@
package com.xydl.cac.thermal;
import com.xydl.cac.entity.NSensor;
import com.xydl.cac.entity.ThermalConfig;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.*;
@Service
@Slf4j
public class ThermalCollectService {
@Resource
HCThermalService thermalService;
public void collectAndSave(List<NSensor> list, ThermalConfig config) {
HashMap<String, List<NSensor>> map = new HashMap<>();
for (NSensor sensor : list) {
if (sensor.canTempMeasure()) {
String key = sensor.getIp() + sensor.getPort() + sensor.getUsername();
List<NSensor> sub = map.get(key);
if (sub == null) {
sub = new ArrayList<>();
map.put(key, sub);
}
sub.add(sensor);
}
}
Iterator<String> it = map.keySet().iterator();
while (it.hasNext()) {
String key = it.next();
List<NSensor> sub = map.get(key);
thermalService.collectAndSave(sub, config);
}
}
}

@ -6,6 +6,7 @@ import com.xydl.cac.model.i2sync.Attr;
import com.xydl.cac.model.i2sync.Datanode;
import com.xydl.cac.model.i2sync.Monitordata;
import com.xydl.cac.model.i2sync.Request;
import com.xydl.cac.util.DataUtil;
import com.xydl.cac.util.DateUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
@ -65,6 +66,9 @@ public class I2DataTransformer {
List<Attr> attrs = new ArrayList<>();
for (I2syncField field : fieldList) {
Object value = dataMap.get(field.getFieldName());
if (StringUtils.isNotBlank(field.getConversion())) {
value = DataUtil.convert(value, field.getConversion());
}
if (value != null) {
Attr attr = new Attr();
attr.setName(field.getDestFieldName());

@ -2,65 +2,8 @@ package com.xydl.cac.util;
public class DataTable {
public static String getTimeField(String tableName) {
switch (tableName) {
case "data_dlq_jbfd":
case "data_sf6_qtsf":
case "data_sf6_qtyl":
case "data_tx":
case "data_ws":
case "data_ysp":
case "data_dcyw":
case "data_dr_jyjc":
case "data_jsyhw_jyjc":
case "data_fhzxq":
case "data_fhdlbx":
case "data_microclimate":
return "acquisitionTime";
case "data_eaif_h":
case "data_eif_h":
return "capturetime";
default:
return "d_time";
}
}
public static String getDevidField(String tableName) {
return "eqmid";
}
public static String getDevType(String tableName) {
switch (tableName) {
case "data_byq_jbfd":
return "021001"; // 变压器/电抗器 局部放电
case "data_ysp":
return "021002"; // 变压器/电抗器 油中溶解气体
case "data_ws":
return "021003"; // 变压器/电抗器 微水
case "data_tx":
return "021004"; // 变压器/电抗器 铁芯接地电流
case "data_dcyw":
return "021005"; // 变压器/电抗器 顶层油温
case "data_dr_jyjc":
return "022001"; // 电容型设备 绝缘监测
case "data_jsyhw_jyjc":
return "023001"; // 金属氧化物避雷器 绝缘监测
case "data_dlq_jbfd":
return "024001"; // 断路器/GIS 局部放电
case "data_fhzxq":
return "024002"; // 断路器/GIS 分合闸线圈电流波形
case "data_fhdlbx":
return "024003"; // 断路器/GIS 负荷电流波形
case "data_sf6_qtyl":
return "024004"; // 断路器/GIS SF6 气体压力
case "data_sf6_qtsf":
return "024005"; // 断路器/GIS SF6气体水分
case "data_cnj":
return "024006"; // 断路器/GIS 储能电机工作状态
case "data_microclimate":
return "025001"; // 综合 变电站微气象
default:
return "";
}
}
}

@ -66,4 +66,28 @@ public class DataUtil {
list.addAll(newlist);
}
}
public static Object convert(Object obj, String conversion) {
if (obj instanceof Number) {
float f = (float) obj;
if (conversion.startsWith("*")) {
float c = Float.parseFloat(conversion.replaceAll("\\*", "").
replaceAll(" ", ""));
return f * c;
} else if (conversion.startsWith("/")) {
float c = Float.parseFloat(conversion.replaceAll("\\/", "").
replaceAll(" ", ""));
return f / c;
} else if (conversion.startsWith("+")) {
float c = Float.parseFloat(conversion.replaceAll("\\+", "").
replaceAll(" ", ""));
return f + c;
} else if (conversion.startsWith("-")) {
float c = Float.parseFloat(conversion.replaceAll("\\-", "").
replaceAll(" ", ""));
return f - c;
}
}
return obj;
}
}

@ -31,7 +31,7 @@ public class IcdXmlUtil {
return icdFile;
}
private static void processTypeRoot(JsonNode root, IcdFile icdFile) {
private static void processTypeRoot(JsonNode root, IcdFile icdFile) throws BusinessException {
LinkedHashMap<String, IcdConfigType> configMap = new LinkedHashMap<>();
Map<String, JsonNode> mapLNodeType = buildLNodeTypeMap(root);
@ -77,7 +77,7 @@ public class IcdXmlUtil {
}
private static void processIEDNode(LinkedHashMap<String, IcdConfigType> configMap, JsonNode iedNode,
Map<String, JsonNode> mapLNodeType, Map<String, JsonNode> mapDOType, Map<String, JsonNode> mapDAType) {
Map<String, JsonNode> mapLNodeType, Map<String, JsonNode> mapDOType, Map<String, JsonNode> mapDAType) throws BusinessException {
String iedName = iedNode.get("name").asText();
List<JsonNode> devList = findNodes(iedNode, "LDevice");
@ -88,7 +88,7 @@ public class IcdXmlUtil {
}
private static void processTypeDeviceNode(LinkedHashMap<String, IcdConfigType> configMap, String iedName, JsonNode deviceNode,
Map<String, JsonNode> mapLNodeType, Map<String, JsonNode> mapDOType, Map<String, JsonNode> mapDAType) {
Map<String, JsonNode> mapLNodeType, Map<String, JsonNode> mapDOType, Map<String, JsonNode> mapDAType) throws BusinessException {
String ldeviceInst = deviceNode.get("inst").asText();
Map<String, JsonNode> mapLN = buildLNMap(deviceNode);
@ -115,6 +115,9 @@ public class IcdXmlUtil {
}
JsonNode nodeLNodeType = mapLNodeType.get(lnType);
JsonNode nodeDO = findLNodeType_DO_Node(nodeLNodeType, doName);
if (nodeDO == null) {
throw new BusinessException(lnType + "该LNodeType节点下缺少名字为" + doName + "的DO节点");
}
String doType = nodeDO.get("type").asText();
JsonNode nodeDoDesc = nodeDO.get("desc");
String doDesc = null;

@ -0,0 +1,59 @@
package com.xydl.cac.util;
import com.jcraft.jsch.JSchException;
import com.xydl.cac.entity.IedDlRecord;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
@Slf4j
public class JkpgFtp {
@Value("${cac.jkpg.ip:}")
private String ip;
@Value("${cac.jkpg.port:22}")
private Integer port;
@Value("${cac.jkpg.user:}")
private String user;
@Value("${cac.jkpg.pass:}")
private String pass;
@Value("${cac.jkpg.pass:}")
private String path;
SFTPTool sftpTool = new SFTPTool();
boolean connected = false;
public void connect() {
if (StringUtils.isBlank(ip)) {
log.error("健康评估的IP未配置");
return;
}
if (StringUtils.isBlank(user)) {
log.error("健康评估的user未配置");
return;
}
try {
sftpTool.connect(ip, port, user, pass);
sftpTool.cdmkdir(path);
connected = true;
} catch (Exception e) {
log.error("SFTP连接健康评估失败", e);
connected = false;
}
}
public void upload(IedDlRecord record) {
if (!connected) {
this.connect();
}
if (connected) {
try {
sftpTool.upload(record.getLocalFullPath(), record.getFilename());
log.info("SFTP上传健康评估成功, " + record.getFilename());
} catch (Exception e) {
log.error("SFTP上传健康评估失败, " + record.getFilename(), e);
}
}
}
}

@ -1,6 +1,7 @@
package com.xydl.cac.util;
import com.jcraft.jsch.*;
import org.apache.commons.lang3.StringUtils;
import java.io.*;
import java.util.Properties;
@ -70,4 +71,38 @@ public class SFTPTool {
return sftp.ls(remotePath);
}
public void cdmkdir(String remotePath) throws SftpException {
if (StringUtils.isNotBlank(remotePath)) {
if (remotePath.startsWith("/")) {
sftp.cd("/");
}
String[] dirs = remotePath.split("/");
for (String dir : dirs) {
if (StringUtils.isNotBlank(dir)) {
try {
sftp.cd(dir);
} catch (SftpException e) {
sftp.mkdir(dir);
sftp.cd(dir);
}
}
}
}
}
public static void main(String[] args) {
SFTPTool sftpTool = new SFTPTool();
try {
String path = "abc/aaa";
sftpTool.connect("192.168.1.190", 22, "root", "123456");
sftpTool.cdmkdir(path);
sftpTool.upload("C:\\Code\\cac\\局放谱图\\50100055_5__001_01_20250409175800.dat",
"50100055_5__001_01_20250409175800.dat");
} catch (Exception e) {
e.printStackTrace();
} finally {
sftpTool.disconnect();
}
}
}

@ -41,6 +41,8 @@ cac:
datapath: /home/xydl/ncac/data
61850:
enable: false
check: false
warning: true
i2:
enable: false
url: http://192.168.1.190:8080/busi-back-ws/service/XydlService
@ -53,3 +55,9 @@ cac:
name: ttyCH341USB0
intervaltime: 60
warntime: 5
jkpg:
ip: 192.168.1.190
port: 22
user: sftpuser
pass: 123456
path: filestore/comtrad

@ -41,9 +41,11 @@ cac:
datapath: /home/xydl/ncac/data
61850:
enable: true
check: false
warning: true
i2:
enable: false
url: http://192.168.1.190:8080/busi-back-ws/service/XydlService
url: http://127.0.0.1:8080/busi-back-ws/service/XydlService
dingding:
send: false
token: e65e730cba22e320e16926fd4ff19ce787fa2162d065792bb6562c6d4a4cf328
@ -53,3 +55,9 @@ cac:
name: ttyCH341USB0
intervaltime: 60
warntime: 5
jkpg:
ip: 127.0.0.1
port: 22
user: sftpuser
pass: 123456
path: filestore/comtrad

Loading…
Cancel
Save