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> <version>1.14.0</version>
</dependency> </dependency>
<dependency>
<groupId>org.openmuc</groupId>
<artifactId>j60870</artifactId>
<version>1.7.2</version>
</dependency>
<!--jSerialComm库串口通讯--> <!--jSerialComm库串口通讯-->
<dependency> <dependency>
<groupId>com.fazecast</groupId> <groupId>com.fazecast</groupId>
<artifactId>jSerialComm</artifactId> <artifactId>jSerialComm</artifactId>
<version>2.11.0</version> <version>2.11.0</version>
</dependency> </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> </dependencies>
<build> <build>
<resources> <resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*</include>
</includes>
</resource>
<resource> <resource>
<directory>src/main/resources</directory> <directory>src/main/resources</directory>
<includes> <includes>
@ -222,6 +235,7 @@
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId> <artifactId>spring-boot-maven-plugin</artifactId>
<configuration> <configuration>
<includeSystemScope>true</includeSystemScope>
<excludes> <excludes>
<exclude> <exclude>
<groupId>org.projectlombok</groupId> <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; package com.xydl.cac;
import com.xydl.cac.model.StaticVariable;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.system.ApplicationHome;
import org.springframework.cache.annotation.EnableCaching; import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.scheduling.annotation.EnableAsync;
@ -25,6 +27,8 @@ public class CacBackendApplication {
} }
public static void main(String[] args) { public static void main(String[] args) {
ApplicationHome home = new ApplicationHome(CacBackendApplication.class);
StaticVariable.jarPath = home.getSource().getParentFile().getAbsolutePath();
SpringApplication.run(CacBackendApplication.class, args); SpringApplication.run(CacBackendApplication.class, args);
} }
} }

@ -174,7 +174,7 @@ public class IcdConfigController extends BasicController {
} }
Optional<IcdIed> optional = iedRepository.findById(iedId); Optional<IcdIed> optional = iedRepository.findById(iedId);
if (!optional.isPresent()) { if (!optional.isPresent()) {
throw new BusinessException("未找到该IED"); throw new BusinessException("未找到该IED id=" + iedId);
} }
IcdIed ied = optional.get(); IcdIed ied = optional.get();
try { try {
@ -201,7 +201,7 @@ public class IcdConfigController extends BasicController {
} }
Optional<IcdIed> optional = iedRepository.findById(iedId); Optional<IcdIed> optional = iedRepository.findById(iedId);
if (!optional.isPresent()) { if (!optional.isPresent()) {
throw new BusinessException("未找到该IED"); throw new BusinessException("未找到该IED id=" + iedId);
} }
IcdIed ied = optional.get(); IcdIed ied = optional.get();
ied.setStart(Constants.FALSE); 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.annotation.Resource;
import javax.validation.constraints.NotNull; import javax.validation.constraints.NotNull;
import java.util.Date;
import java.util.List; import java.util.List;
@RestController @RestController
@ -66,15 +67,28 @@ public class IedDlController extends BasicController {
@GetMapping("listDownload") @GetMapping("listDownload")
@ApiOperation("查询下载记录列表") @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 = "pageNum", required = false) Integer pageNum,
@ApiParam("每页数量") @RequestParam(value = "pageSize", required = false) Integer pageSize) throws Exception { @ApiParam("每页数量") @RequestParam(value = "pageSize", required = false) Integer pageSize) throws Exception {
pageNum = this.initPageNum(pageNum); pageNum = this.initPageNum(pageNum);
pageSize = this.initPageSize(pageSize); 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); 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") @GetMapping("listFiles")
@ApiOperation("查询文件和目录") @ApiOperation("查询文件和目录")
public Response<List<FileInformation>> listFiles(Integer iedId, String path) throws Exception { 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.Bdz;
import com.xydl.cac.entity.NSensor; import com.xydl.cac.entity.NSensor;
import com.xydl.cac.exception.BusinessException; import com.xydl.cac.exception.BusinessException;
import com.xydl.cac.model.ConditionModel; import com.xydl.cac.model.*;
import com.xydl.cac.model.Response;
import com.xydl.cac.model.SensorDetail;
import com.xydl.cac.model.SensorUpdateModel;
import com.xydl.cac.repository.NSensorRepository; import com.xydl.cac.repository.NSensorRepository;
import com.xydl.cac.service.NSensorService; import com.xydl.cac.service.NSensorService;
import com.xydl.cac.service.ParamBindService; import com.xydl.cac.service.ParamBindService;
@ -157,7 +154,7 @@ public class NSensorController extends BasicController {
String typename = ""; String typename = "";
List<NSensor> list = sensorRepository.findByTypeId(model.getTypeId()); List<NSensor> list = sensorRepository.findByTypeId(model.getTypeId());
if (CollectionUtils.isEmpty(list)) { if (CollectionUtils.isEmpty(list)) {
throw new BusinessException("未找到该类型的装置"); throw new BusinessException("未找到该类型的装置typeId=" + model.getTypeId());
} }
List<SensorDetail<Map<String, Object>>> detailList = new ArrayList<>(); List<SensorDetail<Map<String, Object>>> detailList = new ArrayList<>();
for (NSensor sensor : list) { 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") @GetMapping("/discover")
public Response<String> discoverSerialPort() { public Response<String> discoverSerialPort() {
serialPortService.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") @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)) { } else if (Constants.Miss.equalsIgnoreCase(name)) {
return missCompare; return missCompare;
} else { } 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.exception.BusinessException;
import com.xydl.cac.model.ConditionModel; import com.xydl.cac.model.ConditionModel;
import com.xydl.cac.model.Response; import com.xydl.cac.model.Response;
import com.xydl.cac.service.DataService;
import com.xydl.cac.service.ReportService; import com.xydl.cac.service.ReportService;
import com.xydl.cac.service.WarningService; import com.xydl.cac.service.WarningService;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
@ -28,6 +29,9 @@ public class WarningController extends BasicController {
@Resource @Resource
WarningService service; WarningService service;
@Resource
DataService dataService;
@GetMapping("list") @GetMapping("list")
@ApiOperation("查询列表") @ApiOperation("查询列表")
public Response<Page<Warning>> list(@Validated ConditionModel condition) throws Exception { public Response<Page<Warning>> list(@Validated ConditionModel condition) throws Exception {
@ -65,13 +69,20 @@ public class WarningController extends BasicController {
} }
Boolean isHandle = false;
@PostMapping("oneKeyUpdateState") @PostMapping("oneKeyUpdateState")
@ApiOperation("一键修改处理状态") @ApiOperation("一键修改处理状态")
public Response<String> oneKeyUpdateState() throws Exception { public Response<String> oneKeyUpdateState() throws Exception {
ConditionModel condition = new ConditionModel(); try {
condition.setState("1"); if (isHandle) {
List<Warning> warnings = service.listAll(condition); throw new BusinessException("相同请求正在处理中, 请勿重复处理");
service.oneKeyUpdateState(warnings); }
return Response.success("OK"); isHandle = true;
service.oneKeyUpdateState();
return Response.success("OK");
} finally {
isHandle = false;
}
} }
} }

@ -36,4 +36,7 @@ public class I2syncField {
@Column(name = "attach") @Column(name = "attach")
private String 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") @Column(name = "active")
private Integer active; private Integer active;
@ApiModelProperty("是否上传健康评估 0:不传 1:要传")
@Column(name = "upload")
private Integer upload;
@Transient @Transient
private NSensor sensor; private NSensor sensor;
@Transient @Transient

@ -1,6 +1,6 @@
package com.xydl.cac.entity; 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.ApiModel;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
@ -11,7 +11,6 @@ import lombok.NoArgsConstructor;
import javax.persistence.*; import javax.persistence.*;
import java.util.Date; import java.util.Date;
@JsonInclude(JsonInclude.Include.NON_NULL)
@Data @Data
@Builder @Builder
@AllArgsConstructor @AllArgsConstructor
@ -42,11 +41,36 @@ public class IedDlRecord {
@Column(name = "filename") @Column(name = "filename")
private String filename; private String filename;
@ApiModelProperty("采集时间")
@Column(name = "d_time")
private Date dTime;
@ApiModelProperty("创建时间") @ApiModelProperty("创建时间")
@Column(name = "create_time") @Column(name = "create_time")
private Date createTime; 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 @Transient
IedDlConfig config; IedDlConfig config;
@Transient
SpectrogramModel model;
} }

@ -7,6 +7,7 @@ import lombok.AllArgsConstructor;
import lombok.Builder; import lombok.Builder;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import javax.persistence.*; import javax.persistence.*;
import java.util.ArrayList; import java.util.ArrayList;
@ -64,6 +65,34 @@ public class NSensor {
@ApiModelProperty("关联icd表中的id") @ApiModelProperty("关联icd表中的id")
private Integer icdId; 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("主设备名称") @ApiModelProperty("主设备名称")
@Transient @Transient
private String zsbName; private String zsbName;
@ -104,4 +133,13 @@ public class NSensor {
points.add(point); points.add(point);
return null; 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 Text = "text";
public static String DateTime = "datetime"; public static String DateTime = "datetime";
public static String Miss = "miss"; 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.DataService;
import com.xydl.cac.service.IedDlRecordService; import com.xydl.cac.service.IedDlRecordService;
import com.xydl.cac.socket.WebSocketServer; import com.xydl.cac.socket.WebSocketServer;
import com.xydl.cac.spectrogram.SpectrogramHandler;
import com.xydl.cac.util.DateUtil; import com.xydl.cac.util.DateUtil;
import com.xydl.cac.util.JkpgFtp;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
@ -33,6 +35,9 @@ public class IEDCollectService {
WebSocketServer _webSocketServer; WebSocketServer _webSocketServer;
BizConfig _bizConfig; BizConfig _bizConfig;
WarningRepository _warningRepository; WarningRepository _warningRepository;
SpectrogramHandler _spectrogramHandler;
boolean _warning;
JkpgFtp _jkpgFtp;
String folder = "/record"; String folder = "/record";
HashMap<Integer, String> eqmidTimeMap = new HashMap<>(); HashMap<Integer, String> eqmidTimeMap = new HashMap<>();
@ -41,8 +46,9 @@ public class IEDCollectService {
IcdConfigTypeInstRepository instRepository, RptparamindexRepository rptparamindexRepository, IcdConfigTypeInstRepository instRepository, RptparamindexRepository rptparamindexRepository,
IedDlRecordService dlRecordService, DataService dataService, IedDlRecordService dlRecordService, DataService dataService,
String xml, IcdIed ied, String xml, IcdIed ied,
WebSocketServer webSocketServer, BizConfig bizConfig, WebSocketServer webSocketServer, BizConfig bizConfig, boolean warning,
WarningRepository warningRepository) { WarningRepository warningRepository, SpectrogramHandler spectrogramHandler,
JkpgFtp jkpgFtp) {
_configRepository = configRepository; _configRepository = configRepository;
_attRepository = attRepository; _attRepository = attRepository;
_instRepository = instRepository; _instRepository = instRepository;
@ -53,7 +59,10 @@ public class IEDCollectService {
this.ied = ied; this.ied = ied;
_webSocketServer = webSocketServer; _webSocketServer = webSocketServer;
_bizConfig = bizConfig; _bizConfig = bizConfig;
_warning = warning;
_warningRepository = warningRepository; _warningRepository = warningRepository;
_spectrogramHandler = spectrogramHandler;
_jkpgFtp = jkpgFtp;
iecClient = new IecClient(); iecClient = new IecClient();
} }
@ -87,11 +96,13 @@ public class IEDCollectService {
String err = "61850采集数据异常, ied=" + ied.getName() + ", ip=" + ied.getIp() + ", port=" + ied.getPort() String err = "61850采集数据异常, ied=" + ied.getName() + ", ip=" + ied.getIp() + ", port=" + ied.getPort()
+ ", " + ex.getMessage(); + ", " + ex.getMessage();
log.error(err, ex); log.error(err, ex);
this.saveWarning(err); if (_warning) {
String key = ied.getName() + ied.getIp() + ied.getPort(); this.saveWarning(err);
if (!StaticVariable.doneWarnMap.containsKey(key)) { String key = ied.getName() + ied.getIp() + ied.getPort();
StaticVariable.doneWarnMap.put(key, "1"); if (!StaticVariable.doneWarnMap.containsKey(key)) {
_webSocketServer.sendMessage(err, null); StaticVariable.doneWarnMap.put(key, "1");
_webSocketServer.sendMessage(err, null);
}
} }
} finally { } finally {
iecClient.disconnect(); iecClient.disconnect();
@ -151,6 +162,11 @@ public class IEDCollectService {
value = valueNode.getValueString(); value = valueNode.getValueString();
String time = timeNode.getValueString(); String time = timeNode.getValueString();
log.info("采集到" + fc + " " + paramindexNew + "=" + value + ", t=" + time); 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)) { if ("NaN".equalsIgnoreCase(value)) {
return; return;
} }
@ -216,16 +232,23 @@ public class IEDCollectService {
&& matchContain(filename, config.getContain())) { && matchContain(filename, config.getContain())) {
IedDlRecord record = new IedDlRecord(); IedDlRecord record = new IedDlRecord();
record.setConfigId(config.getId()); record.setConfigId(config.getId());
record.setDevId(config.getDevId());
record.setTypeId(config.getSensor().getTypeId());
record.setFilename(filename); record.setFilename(filename);
record.setRemotePath(config.getPath() + filename); record.setRemotePath(config.getPath() + filename);
boolean exist = _dlRecordService.exist(record); boolean exist = _dlRecordService.exist(record);
if (!exist) { if (!exist) {
String localFilePath = localPath + "/" + filename; String relativePath = localPath + "/" + filename;
iecClient.getFile(record.getRemotePath(), _bizConfig.getDatapath() + localFilePath, config.getTodel()); String localFullPath = _bizConfig.getDatapath() + relativePath;
record.setPath(_bizConfig.getDataNginxPath() + localFilePath); record.setLocalFullPath(localFullPath);
record.setCreateTime(new Date()); iecClient.getFile(record.getRemotePath(), localFullPath, config.getTodel());
_dlRecordService.add(record); record.setPath(_bizConfig.getDataNginxPath() + relativePath);
log.info("采集到" + record.getRemotePath()); 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 keep = false;
public boolean connected = false; public boolean connected = false;
private RealTimeDataService realTimeDataService; private WebSocketServer webSocketServer = null;
private WebSocketServer webSocketServer;
public int retry = 0; public int retry = 0;
public int seconds = 0; public int seconds = 0;
private boolean inRetry = false; private boolean inRetry = false;
@ -41,9 +40,10 @@ public class IecClient implements ClientEventListener {
public IecClient() { public IecClient() {
} }
public IecClient(RealTimeDataService _realTimeDataService, WebSocketServer _webSocketServer) { public IecClient(WebSocketServer _webSocketServer, boolean warning) {
realTimeDataService = _realTimeDataService; if (warning) {
webSocketServer = _webSocketServer; webSocketServer = _webSocketServer;
}
} }
public void init(IcdIed _ied, String xml) throws Exception { 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 { public void startServer(Integer fileId, int port) throws BusinessException {
Optional<IcdFile> optional = fileRepository.findById(fileId); Optional<IcdFile> optional = fileRepository.findById(fileId);
if (!optional.isPresent()) { if (!optional.isPresent()) {
throw new BusinessException("未找到该文件"); throw new BusinessException("未找到该文件fileId=" + fileId);
} }
IcdFile icdFile = optional.get(); IcdFile icdFile = optional.get();
if (icdFile.getSrv() != Constants.Server) { if (icdFile.getSrv() != Constants.Server) {
@ -94,7 +94,7 @@ public class IecServerService {
public List<IcdConfigTypeInst> listParamindex(Integer fileId) throws Exception { public List<IcdConfigTypeInst> listParamindex(Integer fileId) throws Exception {
Optional<IcdFile> optional = fileRepository.findById(fileId); Optional<IcdFile> optional = fileRepository.findById(fileId);
if (!optional.isPresent()) { if (!optional.isPresent()) {
throw new BusinessException("未找到该文件"); throw new BusinessException("未找到该文件fileId=" + fileId);
} }
IcdFile icdFile = optional.get(); IcdFile icdFile = optional.get();
if (icdFile.getSrv() != Constants.Server) { 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.repository.IcdIedRepository;
import com.xydl.cac.socket.WebSocketServer; import com.xydl.cac.socket.WebSocketServer;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
@ -21,6 +22,8 @@ import java.util.*;
@Service @Service
@Slf4j @Slf4j
public class RealTimeDataService { public class RealTimeDataService {
@Value("${cac.61850.warning:true}")
public boolean warning;
@Resource @Resource
IcdFileRepository fileRepository; IcdFileRepository fileRepository;
@Resource @Resource
@ -52,7 +55,7 @@ public class RealTimeDataService {
} }
inDoing = true; inDoing = true;
IcdFile icdFile = optionalFile.get(); IcdFile icdFile = optionalFile.get();
IecClient iecClient = new IecClient(this, webSocketServer); IecClient iecClient = new IecClient(webSocketServer, warning);
try { try {
iecClient.init(ied, icdFile.getXml()); iecClient.init(ied, icdFile.getXml());
iecClient.keep = true; 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.entity.*;
import com.xydl.cac.iec.IecClient; import com.xydl.cac.iec.IecClient;
import com.xydl.cac.iec.IecServer; 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 com.xydl.cac.util.DateUtil;
import org.apache.commons.lang3.StringUtils;
import java.util.*; import java.util.*;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
public class StaticVariable { 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, IecServer> iecServerMap = new HashMap<>();
public static HashMap<Integer, HashMap<String, String>> sensorLastDataMap = new HashMap<>(); public static HashMap<Integer, HashMap<String, String>> sensorLastDataMap = new HashMap<>();
public static HashMap<String, String> paramRelationMap = 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<Jg> jg_Cache = null;
public static List<Zsb> zsb_Cache = null; public static List<Zsb> zsb_Cache = null;
public static ConcurrentHashMap<Integer, WarnRule> rule_Cache = new ConcurrentHashMap<>(); 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); StaticVariable.sensorLastDataMap.put(eqmid, map);
} }
map.put(colname, value); map.put(colname, value);
if (time != null) { if (StringUtils.isNotBlank(time)) {
map.put("acquisitionTime", 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> findAllByEqmid(Integer eqmid);
List<Rptparamindex> findAllByEqmidInAndColnameIsNotNull(List<Integer> eqmidList); List<Rptparamindex> findAllByEqmidInAndColnameIsNotNullAndTablenameIsNotNull(List<Integer> eqmidList);
List<Rptparamindex> findAllByParamindexStartingWith(String param); 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 com.xydl.cac.entity.Warning;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor; 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; import org.springframework.stereotype.Repository;
@Repository @Repository
public interface WarningRepository extends JpaRepository<Warning, Integer>, JpaSpecificationExecutor<Warning> { 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); 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; OnePage<Map<String, Object>> getData(String tableName, Integer devId, List<ModevTypePoint> points, ConditionModel model) throws Exception;
void clearAllBind(); void clearAllBind();
@ -23,4 +25,5 @@ public interface DataService {
Map<String, Object> getLastOneData(String tableName, Integer devId, ModevTypePoint point) throws Exception; Map<String, Object> getLastOneData(String tableName, Integer devId, ModevTypePoint point) throws Exception;
void insertData(String tableName, Integer devId, String time, String colname, String value); 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; package com.xydl.cac.service;
import com.xydl.cac.entity.IedDlRecord; import com.xydl.cac.entity.IedDlRecord;
import com.xydl.cac.exception.BusinessException;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
import java.util.Date;
public interface IedDlRecordService { 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); void add(IedDlRecord item);
boolean exist(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 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.List;
import java.util.Map; import java.util.Map;
import static com.xydl.cac.entity.constants.Constants.I2BatchSize;
@Service @Service
@Slf4j @Slf4j
@Transactional(rollbackFor = Exception.class) @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"; String sqlSelect = "SELECT DATE_FORMAT(" + timeField + ", '%Y-%m-%d %H:%i:%s') as acquisitionTime";
for (ModevTypePoint point : points) { for (ModevTypePoint point : points) {
if (StringUtils.isNotBlank(point.getField())) { 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 @Override
public List<Map<String, Object>> getLatestData(String tableName, Integer devId, List<ModevTypePoint> points, Date start) throws Exception { public List<Map<String, Object>> getLatestData(String tableName, Integer devId, List<ModevTypePoint> points, Date start) throws Exception {
ConditionModel model = new ConditionModel(); ConditionModel model = new ConditionModel();
model.setPageSize(500); model.setPageSize(I2BatchSize);
model.setPageNum(1); model.setPageNum(1);
model.setStartTime(start); model.setStartTime(start);
model.setExcludeStartTime(true); model.setExcludeStartTime(true);
@ -289,6 +295,12 @@ public class DataServiceImpl implements DataService {
@Override @Override
public void insertData(String tableName, Integer devId, String time, String colname, String value) { 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 devField = DataTable.getDevidField(tableName);
String timeField = this.getTimeField(tableName); String timeField = this.getTimeField(tableName);
String sqlFrom = " FROM " + 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.IedDlConfig;
import com.xydl.cac.entity.IedDlRecord; import com.xydl.cac.entity.IedDlRecord;
import com.xydl.cac.exception.BusinessException;
import com.xydl.cac.repository.IedDlRecordRepository; import com.xydl.cac.repository.IedDlRecordRepository;
import com.xydl.cac.service.IedDlConfigService; import com.xydl.cac.service.IedDlConfigService;
import com.xydl.cac.service.IedDlRecordService; import com.xydl.cac.service.IedDlRecordService;
import com.xydl.cac.spectrogram.SpectrogramHandler;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.PageRequest;
import org.springframework.data.jpa.domain.Specification; import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.persistence.criteria.Predicate; import javax.persistence.criteria.Predicate;
import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Optional;
@Service @Service
@Slf4j @Slf4j
@Transactional(rollbackFor = Exception.class)
public class IedDlRecordServiceImpl implements IedDlRecordService { public class IedDlRecordServiceImpl implements IedDlRecordService {
@Resource @Resource
IedDlRecordRepository repository; IedDlRecordRepository repository;
@Resource @Resource
IedDlConfigService configService; IedDlConfigService configService;
@Resource
SpectrogramHandler spectrogramHandler;
@Override @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); PageRequest request = PageRequest.of(pageNum - 1, pageSize);
Specification<IedDlRecord> specification = (root, query, builder) -> { Specification<IedDlRecord> specification = (root, query, builder) -> {
Predicate predicate = builder.conjunction(); Predicate predicate = builder.conjunction();
if (configId != null) { if (configId != null) {
predicate.getExpressions().add(builder.equal(root.get("configId"), configId)); 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; return predicate;
}; };
Page<IedDlRecord> result = repository.findAll(specification, request); Page<IedDlRecord> result = repository.findAll(specification, request);
@ -48,6 +63,7 @@ public class IedDlRecordServiceImpl implements IedDlRecordService {
break; break;
} }
} }
spectrogramHandler.jsonToModel(item);
} }
} }
return result; 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); item.setId(null);
Optional<Bdz> optionalBdz = bdzRepository.findById(item.getBdzid()); Optional<Bdz> optionalBdz = bdzRepository.findById(item.getBdzid());
if (!optionalBdz.isPresent()) { if (!optionalBdz.isPresent()) {
throw new BusinessException("未找到该变电站"); throw new BusinessException("未找到该变电站id=" + item.getBdzid());
} }
List<Jg> list = repository.findByBdzidAndMc(item.getBdzid(), item.getMc()); List<Jg> list = repository.findByBdzidAndMc(item.getBdzid(), item.getMc());
if (!CollectionUtils.isEmpty(list)) { if (!CollectionUtils.isEmpty(list)) {
@ -119,7 +119,7 @@ public class JgServiceImpl implements JgService {
public void update(Jg item) throws Exception { public void update(Jg item) throws Exception {
Optional<Bdz> optionalBdz = bdzRepository.findById(item.getBdzid()); Optional<Bdz> optionalBdz = bdzRepository.findById(item.getBdzid());
if (!optionalBdz.isPresent()) { if (!optionalBdz.isPresent()) {
throw new BusinessException("未找到该变电站"); throw new BusinessException("未找到该变电站id=" + item.getBdzid());
} }
List<Jg> list = repository.findByBdzidAndMcAndIdIsNot(item.getBdzid(), item.getMc(), item.getId()); List<Jg> list = repository.findByBdzidAndMcAndIdIsNot(item.getBdzid(), item.getMc(), item.getId());
if (!CollectionUtils.isEmpty(list)) { if (!CollectionUtils.isEmpty(list)) {
@ -144,7 +144,7 @@ public class JgServiceImpl implements JgService {
public Jg detail(Integer id) throws Exception { public Jg detail(Integer id) throws Exception {
Optional<Jg> optional = repository.findById(id); Optional<Jg> optional = repository.findById(id);
if (!optional.isPresent()) { if (!optional.isPresent()) {
throw new BusinessException("未找到该区域"); throw new BusinessException("未找到该区域id=" + id);
} }
Jg jg = optional.get(); Jg jg = optional.get();
Optional<Bdz> optionalBdz = bdzRepository.findById(jg.getBdzid()); Optional<Bdz> optionalBdz = bdzRepository.findById(jg.getBdzid());

@ -60,6 +60,7 @@ public class NSensorServiceImpl implements NSensorService {
if (typeId != null) { if (typeId != null) {
predicate.getExpressions().add(builder.equal(root.get("typeId"), typeId)); predicate.getExpressions().add(builder.equal(root.get("typeId"), typeId));
} }
query.orderBy(builder.asc(root.get("orderNum")));
return predicate; return predicate;
}; };
List<NSensor> list = repository.findAll(specification); 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); 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; return result;
} }

@ -12,11 +12,13 @@ import com.xydl.cac.service.ModevTypeService;
import com.xydl.cac.service.ParamBindService; import com.xydl.cac.service.ParamBindService;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.persistence.criteria.Predicate;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
@ -82,7 +84,12 @@ public class ParamBindServiceImpl implements ParamBindService {
for (Zsb zsb : zsbList) { for (Zsb zsb : zsbList) {
zsbMap.put(zsb.getId(), zsb); 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) { 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 { public void update(WarnRule item) throws Exception {
Optional<WarnRule> optional = repository.findById(item.getId()); Optional<WarnRule> optional = repository.findById(item.getId());
if (!optional.isPresent()) { if (!optional.isPresent()) {
throw new BusinessException("未找到该告警规则"); throw new BusinessException("未找到该告警规则id=" + item.getId());
} }
WarnRule rule = optional.get(); WarnRule rule = optional.get();
rule.setComparator(item.getComparator()); rule.setComparator(item.getComparator());

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

@ -93,7 +93,7 @@ public class ZsbServiceImpl implements ZsbService {
item.setBdzid(jg.getBdzid()); item.setBdzid(jg.getBdzid());
Optional<Lx> optionalLx = lxRepository.findById(item.getLxid()); Optional<Lx> optionalLx = lxRepository.findById(item.getLxid());
if (!optionalLx.isPresent()) { if (!optionalLx.isPresent()) {
throw new BusinessException("未找到该设备类型"); throw new BusinessException("未找到该设备类型id=" + item.getLxid());
} }
List<Zsb> list = repository.findByJgidAndMc(item.getJgid(), item.getMc()); List<Zsb> list = repository.findByJgidAndMc(item.getJgid(), item.getMc());
if (!CollectionUtils.isEmpty(list)) { if (!CollectionUtils.isEmpty(list)) {
@ -109,7 +109,7 @@ public class ZsbServiceImpl implements ZsbService {
item.setBdzid(jg.getBdzid()); item.setBdzid(jg.getBdzid());
Optional<Lx> optionalLx = lxRepository.findById(item.getLxid()); Optional<Lx> optionalLx = lxRepository.findById(item.getLxid());
if (!optionalLx.isPresent()) { if (!optionalLx.isPresent()) {
throw new BusinessException("未找到该设备类型"); throw new BusinessException("未找到该设备类型id=" + item.getLxid());
} }
List<Zsb> list = repository.findByJgidAndMcAndIdIsNot(item.getJgid(), item.getMc(), item.getId()); List<Zsb> list = repository.findByJgidAndMcAndIdIsNot(item.getJgid(), item.getMc(), item.getId());
if (!CollectionUtils.isEmpty(list)) { if (!CollectionUtils.isEmpty(list)) {
@ -133,7 +133,7 @@ public class ZsbServiceImpl implements ZsbService {
public Zsb detail(Integer id) throws Exception { public Zsb detail(Integer id) throws Exception {
Optional<Zsb> optional = repository.findById(id); Optional<Zsb> optional = repository.findById(id);
if (!optional.isPresent()) { if (!optional.isPresent()) {
throw new BusinessException("未找到该主设备"); throw new BusinessException("未找到该主设备id=" + id);
} }
Zsb zsb = optional.get(); Zsb zsb = optional.get();
Jg jg = jgService.detail(zsb.getJgid()); 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; package com.xydl.cac.task;
import com.xydl.cac.config.BizConfig; import com.xydl.cac.config.BizConfig;
import com.xydl.cac.entity.IcdIed; import com.xydl.cac.entity.*;
import com.xydl.cac.entity.IedDlConfig;
import com.xydl.cac.entity.Rptparamindex;
import com.xydl.cac.iec.IEDCollectService; import com.xydl.cac.iec.IEDCollectService;
import com.xydl.cac.repository.*; import com.xydl.cac.repository.*;
import com.xydl.cac.service.DataService; import com.xydl.cac.service.DataService;
import com.xydl.cac.service.IedDlRecordService; import com.xydl.cac.service.IedDlRecordService;
import com.xydl.cac.socket.WebSocketServer; 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.scheduling.annotation.Async;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@ -17,6 +18,8 @@ import java.util.List;
@Service @Service
public class AsyncTask { public class AsyncTask {
@Value("${cac.61850.warning:true}")
public boolean warning;
@Resource @Resource
IcdConfigTypeRepository configRepository; IcdConfigTypeRepository configRepository;
@Resource @Resource
@ -35,6 +38,10 @@ public class AsyncTask {
BizConfig bizConfig; BizConfig bizConfig;
@Resource @Resource
WarningRepository warningRepository; WarningRepository warningRepository;
@Resource
SpectrogramHandler spectrogramHandler;
@Resource
JkpgFtp jkpgFtp;
@Async @Async
public void collectIed(String xml, IcdIed ied, List<Rptparamindex> rptList, List<IedDlConfig> dlList) { public void collectIed(String xml, IcdIed ied, List<Rptparamindex> rptList, List<IedDlConfig> dlList) {
@ -42,8 +49,9 @@ public class AsyncTask {
instRepository, rptparamindexRepository, instRepository, rptparamindexRepository,
dlRecordService, dataService, dlRecordService, dataService,
xml, ied, xml, ied,
webSocketServer, bizConfig, webSocketServer, bizConfig, warning,
warningRepository); warningRepository, spectrogramHandler,
jkpgFtp);
iedService.collectAndSave(rptList, dlList); iedService.collectAndSave(rptList, dlList);
} }
} }

@ -1,7 +1,9 @@
package com.xydl.cac.task; package com.xydl.cac.task;
import com.xydl.cac.entity.Iec104Point;
import com.xydl.cac.entity.WarnRule; import com.xydl.cac.entity.WarnRule;
import com.xydl.cac.model.StaticVariable; import com.xydl.cac.model.StaticVariable;
import com.xydl.cac.service.Iec104PointService;
import com.xydl.cac.service.WarnRuleService; import com.xydl.cac.service.WarnRuleService;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled; import org.springframework.scheduling.annotation.Scheduled;
@ -16,24 +18,27 @@ public class CacheTask {
@Resource @Resource
WarnRuleService ruleService; WarnRuleService ruleService;
@Resource
Iec104PointService iec104PointService;
@Scheduled(cron = "0 0 1 * * ?") @Scheduled(cron = "0 0 1 * * ?")
private void clearCache1() { public void clearCache1() {
StaticVariable.unit_Cache.clear(); StaticVariable.unit_Cache.clear();
StaticVariable.modevType_Cache = null; StaticVariable.modevType_Cache = null;
StaticVariable.jg_Cache = null; StaticVariable.jg_Cache = null;
StaticVariable.zsb_Cache = null; StaticVariable.zsb_Cache = null;
StaticVariable.rule_Cache.clear(); StaticVariable.rule_Cache.clear();
StaticVariable.ruleRelationMap.clear();
StaticVariable.paramRelationMap.clear(); StaticVariable.paramRelationMap.clear();
} }
@Scheduled(cron = "0 30 9 * * ?") @Scheduled(cron = "0 30 9 * * ?")
private void clearCache9() { public void clearCache9() {
StaticVariable.doneWarnMap.clear(); StaticVariable.doneWarnMap.clear();
} }
@Scheduled(initialDelay = 30 * 1000, fixedDelay = 60 * 1000) @Scheduled(initialDelay = 30 * 1000, fixedDelay = 60 * 1000)
private void refreshRule() { public void refreshRule() {
try { try {
List<WarnRule> list = ruleService.listAll(null); List<WarnRule> list = ruleService.listAll(null);
for (WarnRule item : list) { for (WarnRule item : list) {
@ -42,9 +47,18 @@ public class CacheTask {
item.initComparator(item.getComparator(), item.getOperator()); item.initComparator(item.getComparator(), item.getOperator());
StaticVariable.rule_Cache.put(item.getId(), item); 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) { } catch (Exception e) {
log.error("CacheTask.refreshRule error.", 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}") @Value("${cac.61850.enable:true}")
public boolean enable; public boolean enable;
@Value("${cac.61850.check:false}")
public boolean check;
@Resource @Resource
AsyncTask asyncTask; AsyncTask asyncTask;
@Resource @Resource
@ -83,16 +85,24 @@ public class Client61850Task {
return; return;
} }
List<Rptparamindex> rptList = rptparamindexRepository.findAllByEqmidInAndColnameIsNotNull(eqmidList); List<Rptparamindex> rptList = rptparamindexRepository.findAllByEqmidInAndColnameIsNotNullAndTablenameIsNotNull(eqmidList);
List<IedDlConfig> dlList = dlConfigRepository.findByDevIdIn(eqmidList); List<IedDlConfig> dlList = dlConfigRepository.findByDevIdIn(eqmidList);
if (CollectionUtils.isEmpty(rptList) && CollectionUtils.isEmpty(dlList)) { if (CollectionUtils.isEmpty(rptList) && CollectionUtils.isEmpty(dlList)) {
return; 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(); List<IcdFile> icdFileList = fileRepository.findAll();
if (!CollectionUtils.isEmpty(icdFileList)) { if (!CollectionUtils.isEmpty(icdFileList)) {
for (IcdFile icdFile : 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) @Scheduled(initialDelay = 60 * 1000, fixedDelay = 60 * 1000)
private void testAll() { private void testAll() {
if (!enable) { if (!check) {
return; return;
} }
List<IcdIed> iedTestList = new ArrayList<>(); 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.List;
import java.util.Map; import java.util.Map;
import static com.xydl.cac.entity.constants.Constants.I2BatchSize;
@Service @Service
@Slf4j @Slf4j
public class I2syncTask { public class I2syncTask {
@ -89,6 +91,8 @@ public class I2syncTask {
for (I2syncField field : fieldList) { for (I2syncField field : fieldList) {
ModevTypePoint point = new ModevTypePoint(); ModevTypePoint point = new ModevTypePoint();
point.setField(field.getFieldName()); point.setField(field.getFieldName());
String type = dataService.getFieldType(config.getTableName(), point.getField());
point.setType(type);
points.add(point); points.add(point);
} }
List<NSensor> list = sensorRepository.findByTypeId(config.getModevtypeId()); List<NSensor> list = sensorRepository.findByTypeId(config.getModevtypeId());
@ -133,7 +137,7 @@ public class I2syncTask {
log.info("I2syncTask.syncOneSensor 同步导出" + sensor.getName() + "(" + sensor.getSensorCode() + ") " log.info("I2syncTask.syncOneSensor 同步导出" + sensor.getName() + "(" + sensor.getSensorCode() + ") "
+ count + "条数据,最后数据时间" + DateUtil.format(record.getLastDTime())); + count + "条数据,最后数据时间" + DateUtil.format(record.getLastDTime()));
if (count >= 1000) { if (count >= I2BatchSize) {
dataList.clear(); dataList.clear();
this.syncOneSensor(sensor, config, fieldList, points); this.syncOneSensor(sensor, config, fieldList, points);
} }

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

@ -2,65 +2,8 @@ package com.xydl.cac.util;
public class DataTable { 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) { public static String getDevidField(String tableName) {
return "eqmid"; 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); 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; 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<>(); LinkedHashMap<String, IcdConfigType> configMap = new LinkedHashMap<>();
Map<String, JsonNode> mapLNodeType = buildLNodeTypeMap(root); Map<String, JsonNode> mapLNodeType = buildLNodeTypeMap(root);
@ -77,7 +77,7 @@ public class IcdXmlUtil {
} }
private static void processIEDNode(LinkedHashMap<String, IcdConfigType> configMap, JsonNode iedNode, 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(); String iedName = iedNode.get("name").asText();
List<JsonNode> devList = findNodes(iedNode, "LDevice"); 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, 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(); String ldeviceInst = deviceNode.get("inst").asText();
Map<String, JsonNode> mapLN = buildLNMap(deviceNode); Map<String, JsonNode> mapLN = buildLNMap(deviceNode);
@ -115,6 +115,9 @@ public class IcdXmlUtil {
} }
JsonNode nodeLNodeType = mapLNodeType.get(lnType); JsonNode nodeLNodeType = mapLNodeType.get(lnType);
JsonNode nodeDO = findLNodeType_DO_Node(nodeLNodeType, doName); JsonNode nodeDO = findLNodeType_DO_Node(nodeLNodeType, doName);
if (nodeDO == null) {
throw new BusinessException(lnType + "该LNodeType节点下缺少名字为" + doName + "的DO节点");
}
String doType = nodeDO.get("type").asText(); String doType = nodeDO.get("type").asText();
JsonNode nodeDoDesc = nodeDO.get("desc"); JsonNode nodeDoDesc = nodeDO.get("desc");
String doDesc = null; 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; package com.xydl.cac.util;
import com.jcraft.jsch.*; import com.jcraft.jsch.*;
import org.apache.commons.lang3.StringUtils;
import java.io.*; import java.io.*;
import java.util.Properties; import java.util.Properties;
@ -70,4 +71,38 @@ public class SFTPTool {
return sftp.ls(remotePath); 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 datapath: /home/xydl/ncac/data
61850: 61850:
enable: false enable: false
check: false
warning: true
i2: i2:
enable: false enable: false
url: http://192.168.1.190:8080/busi-back-ws/service/XydlService url: http://192.168.1.190:8080/busi-back-ws/service/XydlService
@ -53,3 +55,9 @@ cac:
name: ttyCH341USB0 name: ttyCH341USB0
intervaltime: 60 intervaltime: 60
warntime: 5 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 datapath: /home/xydl/ncac/data
61850: 61850:
enable: true enable: true
check: false
warning: true
i2: i2:
enable: false 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: dingding:
send: false send: false
token: e65e730cba22e320e16926fd4ff19ce787fa2162d065792bb6562c6d4a4cf328 token: e65e730cba22e320e16926fd4ff19ce787fa2162d065792bb6562c6d4a4cf328
@ -52,4 +54,10 @@ cac:
warnport: warnport:
name: ttyCH341USB0 name: ttyCH341USB0
intervaltime: 60 intervaltime: 60
warntime: 5 warntime: 5
jkpg:
ip: 127.0.0.1
port: 22
user: sftpuser
pass: 123456
path: filestore/comtrad

Loading…
Cancel
Save