Merge branch 'main' of https://git.jsspisoft.com/ry-das
This commit is contained in:
commit
84cfc90b5d
@ -138,6 +138,9 @@ public class CalcService {
|
|||||||
|
|
||||||
FunctionWindSpeedFactor windSpeedFactor = new FunctionWindSpeedFactor(dataService,cacheService);
|
FunctionWindSpeedFactor windSpeedFactor = new FunctionWindSpeedFactor(dataService,cacheService);
|
||||||
aviator.addFunction(windSpeedFactor);
|
aviator.addFunction(windSpeedFactor);
|
||||||
|
|
||||||
|
FunctionIsOnline isOnline = new FunctionIsOnline(adminRedisTemplate, cacheService);
|
||||||
|
aviator.addFunction(isOnline);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2,7 +2,6 @@ package com.das.modules.node.command;
|
|||||||
|
|
||||||
import com.das.common.constant.EquipmentTypeIds;
|
import com.das.common.constant.EquipmentTypeIds;
|
||||||
import com.das.common.utils.AdminRedisTemplate;
|
import com.das.common.utils.AdminRedisTemplate;
|
||||||
import com.das.common.utils.StringUtils;
|
|
||||||
import com.das.modules.cache.domain.DeviceInfoCache;
|
import com.das.modules.cache.domain.DeviceInfoCache;
|
||||||
import com.das.modules.cache.service.CacheService;
|
import com.das.modules.cache.service.CacheService;
|
||||||
import com.das.modules.node.constant.NodeConstant;
|
import com.das.modules.node.constant.NodeConstant;
|
||||||
@ -12,44 +11,57 @@ import lombok.extern.slf4j.Slf4j;
|
|||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import java.text.MessageFormat;
|
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Service(value = NodeConstant.HEARTBEAT)
|
@Service(value = NodeConstant.HEARTBEAT)
|
||||||
public class HeartbeatCommand implements BaseCommand{
|
public class HeartbeatCommand implements BaseCommand{
|
||||||
|
|
||||||
public static final long HEARTBEAT_TTL = 60L;
|
public static final long HEARTBEAT_TTL = 12L;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
AdminRedisTemplate adminRedisTemplate;
|
AdminRedisTemplate adminRedisTemplate;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
CacheService cacheService;
|
CacheService cacheService;
|
||||||
|
/**
|
||||||
|
* 执行命令方法
|
||||||
|
* 该方法处理接收到的终端消息,特别是心跳报文中的设备和链路在线状态更新
|
||||||
|
*
|
||||||
|
* @param data 包含心跳报文信息的TerminalMessage对象
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void doCommand(TerminalMessage data) {
|
public void doCommand(TerminalMessage data) {
|
||||||
|
log.info("收到[heartbeat]报文");
|
||||||
|
|
||||||
|
// 解析心跳报文中的数据信息
|
||||||
JsonNode dataInfo = data.getData();
|
JsonNode dataInfo = data.getData();
|
||||||
if (!dataInfo.isEmpty()) {
|
if (!dataInfo.isEmpty()) {
|
||||||
|
// 处理链路信息
|
||||||
JsonNode links = data.getData().get("links");
|
JsonNode links = data.getData().get("links");
|
||||||
if (links != null && links.isArray()) {
|
if (links != null && links.isArray()) {
|
||||||
for (JsonNode linkNode : links) {
|
for (JsonNode linkNode : links) {
|
||||||
String linkId = linkNode.get("linkId").asText();
|
String linkId = linkNode.get("linkId").asText();
|
||||||
boolean online = linkNode.get("online").asBoolean();
|
boolean online = linkNode.get("online").asBoolean();
|
||||||
String key = String.format("link:%d:online", linkId, online);
|
String key = String.format("link:%s:online", linkId);
|
||||||
|
// 更新链路在线状态到Redis
|
||||||
adminRedisTemplate.set(key, online ? 1 : 0);
|
adminRedisTemplate.set(key, online ? 1 : 0);
|
||||||
adminRedisTemplate.expire(key, HEARTBEAT_TTL);
|
adminRedisTemplate.expire(key, HEARTBEAT_TTL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 处理设备信息
|
||||||
JsonNode devices = data.getData().get("devices");
|
JsonNode devices = data.getData().get("devices");
|
||||||
if (devices != null && devices.isArray()) {
|
if (devices != null && devices.isArray()) {
|
||||||
for (JsonNode device : devices) {
|
for (JsonNode device : devices) {
|
||||||
long deviceId = device.get("deviceId").asLong();
|
long deviceId = device.get("deviceId").asLong();
|
||||||
boolean online = device.get("online").asBoolean();
|
boolean online = device.get("online").asBoolean();
|
||||||
|
// 获取设备缓存信息
|
||||||
DeviceInfoCache deviceInfoCacheById = cacheService.getEquipmentCache().getDeviceInfoCacheById(deviceId);
|
DeviceInfoCache deviceInfoCacheById = cacheService.getEquipmentCache().getDeviceInfoCacheById(deviceId);
|
||||||
if (deviceInfoCacheById == null || !deviceInfoCacheById.getObjectType().equals(EquipmentTypeIds.EQUIPMENT_TYPE_STATION_WTG)) {
|
if (deviceInfoCacheById == null || !deviceInfoCacheById.getObjectType().equals(EquipmentTypeIds.EQUIPMENT_TYPE_STATION_WTG)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
//判断是不是风机
|
// 判断是不是风机
|
||||||
String keyDeviceOnline = String.format("device:%d:online", deviceId);
|
String keyDeviceOnline = String.format("device:%d:online", deviceId);
|
||||||
|
// 更新设备在线状态到Redis
|
||||||
adminRedisTemplate.set(keyDeviceOnline, online ? 1 : 0);
|
adminRedisTemplate.set(keyDeviceOnline, online ? 1 : 0);
|
||||||
adminRedisTemplate.expire(keyDeviceOnline, HEARTBEAT_TTL);
|
adminRedisTemplate.expire(keyDeviceOnline, HEARTBEAT_TTL);
|
||||||
|
|
||||||
@ -57,6 +69,7 @@ public class HeartbeatCommand implements BaseCommand{
|
|||||||
String keyCommFaultState = String.format("RT:%d:commfaultstate",deviceId);
|
String keyCommFaultState = String.format("RT:%d:commfaultstate",deviceId);
|
||||||
Integer plcDeviceStatus = adminRedisTemplate.get(keyPLCDeviceStatus);
|
Integer plcDeviceStatus = adminRedisTemplate.get(keyPLCDeviceStatus);
|
||||||
log.debug("设备ID:{},在线状态:{},通讯状态: {}", deviceId, online, plcDeviceStatus);
|
log.debug("设备ID:{},在线状态:{},通讯状态: {}", deviceId, online, plcDeviceStatus);
|
||||||
|
// 根据设备在线状态和通讯状态更新通讯故障状态
|
||||||
if (plcDeviceStatus == null){
|
if (plcDeviceStatus == null){
|
||||||
adminRedisTemplate.set(keyCommFaultState, online ? 0 : 1);
|
adminRedisTemplate.set(keyCommFaultState, online ? 0 : 1);
|
||||||
}
|
}
|
||||||
|
@ -238,7 +238,7 @@ public class NodeMessageServiceImpl extends TextWebSocketHandler implements Node
|
|||||||
@Override
|
@Override
|
||||||
public void handleData(TerminalMessage data) {
|
public void handleData(TerminalMessage data) {
|
||||||
JsonNode jsonNode = data.getData();
|
JsonNode jsonNode = data.getData();
|
||||||
log.info("收到消息:{}",data.getData());
|
log.debug("收到消息:{}",data.getData());
|
||||||
String deviceId = jsonNode.get("deviceId").asText();
|
String deviceId = jsonNode.get("deviceId").asText();
|
||||||
JsonNode values = jsonNode.get("values");
|
JsonNode values = jsonNode.get("values");
|
||||||
JsonNode archiveValues = jsonNode.get("archiveValues");
|
JsonNode archiveValues = jsonNode.get("archiveValues");
|
||||||
@ -258,7 +258,6 @@ public class NodeMessageServiceImpl extends TextWebSocketHandler implements Node
|
|||||||
String key = String.format("RT:%s:%s", deviceId, fieldName.toLowerCase());
|
String key = String.format("RT:%s:%s", deviceId, fieldName.toLowerCase());
|
||||||
keyValueMap.put(key, values.get(fieldName));
|
keyValueMap.put(key, values.get(fieldName));
|
||||||
}
|
}
|
||||||
log.info("values解析成功");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (archiveValues != null){
|
if (archiveValues != null){
|
||||||
@ -274,7 +273,6 @@ public class NodeMessageServiceImpl extends TextWebSocketHandler implements Node
|
|||||||
lowSpeedValueMap.put(fieldName, archiveValues.get(fieldName));
|
lowSpeedValueMap.put(fieldName, archiveValues.get(fieldName));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
log.info("archive解析成功");
|
|
||||||
}
|
}
|
||||||
//更新td
|
//更新td
|
||||||
if (!highSpeedValueMap.isEmpty()) {
|
if (!highSpeedValueMap.isEmpty()) {
|
||||||
|
BIN
docs/deploy/asserts/image-4.png
Normal file
BIN
docs/deploy/asserts/image-4.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 105 KiB |
@ -462,8 +462,62 @@ systemctl enable das
|
|||||||
```shell
|
```shell
|
||||||
mkdir -p /das/app
|
mkdir -p /das/app
|
||||||
cd /das/app
|
cd /das/app
|
||||||
wget https://oss.jsspisoft.com/
|
wget https://oss.jsspisoft.com/public/software/das/das-dn.tar.gz
|
||||||
|
tar zxvf das-dn.tar.gz
|
||||||
|
rm -f das-dn.tar.gz
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### 程序配置
|
||||||
|
|
||||||
|
编辑文件`/das/app/das-dn/envfile`
|
||||||
|
|
||||||
|
```toml
|
||||||
|
#das服务地址
|
||||||
|
ISS_WS_HOST=127.0.0.1
|
||||||
|
#das服务端口
|
||||||
|
ISS_WS_PORT=8080
|
||||||
|
#节点ID
|
||||||
|
ISS_WS_NODEID=1
|
||||||
|
```
|
||||||
|
|
||||||
|
### 配置服务
|
||||||
|
|
||||||
|
创建服务文件`/etc/systemd/system/das-dn.service`,内容如下:
|
||||||
|
|
||||||
|
```toml
|
||||||
|
[Unit]
|
||||||
|
Description=DAS DN Service
|
||||||
|
After=network.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
EnvironmentFile=/das/app/das-dn/envfile
|
||||||
|
ExecStart=/das/app/das-dn/bin/application -d ./rtufiles -h $ISS_WS_HOST -p $ISS_WS_PORT -n $ISS_WS_NODEID
|
||||||
|
Restart=always
|
||||||
|
RestartSec=10
|
||||||
|
StartLimitInterval=0
|
||||||
|
WorkingDirectory=/das/app/das-dn
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
```
|
||||||
|
|
||||||
|
### 服务启动
|
||||||
|
|
||||||
|
```bash
|
||||||
|
systemctl start das-dn
|
||||||
|
systemctl enable das-dn
|
||||||
|
```
|
||||||
|
|
||||||
|
## 前端UI部署
|
||||||
|
|
||||||
|
前端只需要部署静态文件就行了
|
||||||
|
|
||||||
|
```shell
|
||||||
|
mkdir -p /das/app
|
||||||
|
wget https://oss.jsspisoft.com/public/software/das/ui.tar.gz
|
||||||
|
tar zxvf ui.tar.gz
|
||||||
|
rm -f ui.tar.gz
|
||||||
|
```
|
||||||
|
|
||||||
|
这样就部署好了。
|
@ -987,6 +987,8 @@ const realTimeDataState = computed(() => {
|
|||||||
return '停机'
|
return '停机'
|
||||||
case 11:
|
case 11:
|
||||||
return '待机'
|
return '待机'
|
||||||
|
case 33:
|
||||||
|
return '通讯中断'
|
||||||
case 1110:
|
case 1110:
|
||||||
return '解缆状态'
|
return '解缆状态'
|
||||||
case 1111:
|
case 1111:
|
||||||
|
@ -341,23 +341,6 @@ const currentDayStatus = ref({
|
|||||||
})
|
})
|
||||||
const deviceCode = ref([])
|
const deviceCode = ref([])
|
||||||
const FanList = ref([])
|
const FanList = ref([])
|
||||||
const getRealTimeState = (data: any) => {
|
|
||||||
if (data.iturbineoperationmode) {
|
|
||||||
if (data.iturbineoperationmode > 1 && data.iturbineoperationmode < 6) {
|
|
||||||
return 2
|
|
||||||
}
|
|
||||||
if (data.iturbineoperationmode === 21) {
|
|
||||||
return 20
|
|
||||||
}
|
|
||||||
return data.iturbineoperationmode
|
|
||||||
} else if (data.iyplevel === 10) {
|
|
||||||
return 1110
|
|
||||||
} else if (data.gridlostdetected === 1) {
|
|
||||||
return 1111
|
|
||||||
} else if (data.ibplevel === 200) {
|
|
||||||
return 1112
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const StatusListData = () => {
|
const StatusListData = () => {
|
||||||
getWindTurbineMatrixData().then((res) => {
|
getWindTurbineMatrixData().then((res) => {
|
||||||
if (res.code == 200) {
|
if (res.code == 200) {
|
||||||
|
@ -15,41 +15,44 @@
|
|||||||
:width="item.width"
|
:width="item.width"
|
||||||
>
|
>
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<div v-if="item.prop === 'iturbineoperationmode'">
|
<div v-if="item.prop === 'processedoperationmode'">
|
||||||
<el-tag v-if="scope.row.locked === 1" color="rgba(254,55,49,0.20)" style="color: #fe3731">已锁定</el-tag>
|
<el-tag v-if="scope.row.locked === 1" color="rgba(254,55,49,0.20)" style="color: #fe3731">已锁定</el-tag>
|
||||||
<el-tag v-if="scope.row.iturbineoperationmode === 20" color="rgba(0,100,170,0.20)" style="color: #0064aa"
|
<el-tag v-if="scope.row.processedoperationmode === 20" color="rgba(0,100,170,0.20)" style="color: #0064aa"
|
||||||
>并网</el-tag
|
>并网</el-tag
|
||||||
>
|
>
|
||||||
<el-tag v-if="scope.row.iturbineoperationmode === 10" color="rgba(0,160,150,0.20)" style="color: #00a096"
|
<el-tag v-if="scope.row.processedoperationmode === 10" color="rgba(0,160,150,0.20)" style="color: #00a096"
|
||||||
>维护</el-tag
|
>维护</el-tag
|
||||||
>
|
>
|
||||||
<el-tag v-if="scope.row.iturbineoperationmode === 8" color="rgba(255,126,0,0.20)" style="color: #ff7e00"
|
<el-tag v-if="scope.row.processedoperationmode === 8" color="rgba(255,126,0,0.20)" style="color: #ff7e00"
|
||||||
>限功率运行</el-tag
|
>限功率运行</el-tag
|
||||||
>
|
>
|
||||||
<el-tag v-if="scope.row.iturbineoperationmode === 0" color="rgba(153,153,153,0.20)" style="color: #666666"
|
<el-tag v-if="scope.row.processedoperationmode === 0" color="rgba(153,153,153,0.20)" style="color: #666666"
|
||||||
>离线</el-tag
|
>离线</el-tag
|
||||||
>
|
>
|
||||||
<el-tag v-if="scope.row.iturbineoperationmode === 16" color="rgba(6,180,41,0.20)" style="color: #06b429"
|
<el-tag v-if="scope.row.processedoperationmode === 16" color="rgba(6,180,41,0.20)" style="color: #06b429"
|
||||||
>启动</el-tag
|
>启动</el-tag
|
||||||
>
|
>
|
||||||
<el-tag v-if="scope.row.iturbineoperationmode === 6" color="rgba(254,55,49,0.20)" style="color: #fe3731"
|
<el-tag v-if="scope.row.processedoperationmode === 6" color="rgba(254,55,49,0.20)" style="color: #fe3731"
|
||||||
>正常停机</el-tag
|
>正常停机</el-tag
|
||||||
>
|
>
|
||||||
<el-tag v-if="scope.row.iturbineoperationmode === 1" color="rgba(254,55,49,0.20)" style="color: #fe3731"
|
<el-tag v-if="scope.row.processedoperationmode === 1" color="rgba(254,55,49,0.20)" style="color: #fe3731"
|
||||||
>外部因素导致停机</el-tag
|
>外部因素导致停机</el-tag
|
||||||
>
|
>
|
||||||
<el-tag v-if="scope.row.iturbineoperationmode === 2" color="rgba(254,55,49,0.20)" style="color: #fe3731"
|
<el-tag v-if="scope.row.processedoperationmode === 2" color="rgba(254,55,49,0.20)" style="color: #fe3731"
|
||||||
>停机</el-tag
|
>停机</el-tag
|
||||||
>
|
>
|
||||||
<el-tag v-if="scope.row.iturbineoperationmode === 11" color="rgba(255,182,0,0.20)" style="color: #ffb600"
|
<el-tag v-if="scope.row.processedoperationmode === 11" color="rgba(255,182,0,0.20)" style="color: #ffb600"
|
||||||
>待机</el-tag
|
>待机</el-tag
|
||||||
>
|
>
|
||||||
<el-tag v-if="scope.row.iturbineoperationmode === 1110" color="rgba(153,153,153,0.20)" style="color: #666666"
|
<el-tag v-if="scope.row.processedoperationmode === 1110" color="rgba(153,153,153,0.20)" style="color: #666666"
|
||||||
>解缆状态</el-tag
|
>解缆状态</el-tag
|
||||||
>
|
>
|
||||||
<el-tag v-if="scope.row.iturbineoperationmode === 1111" color="rgba(254,55,49,0.20)" style="color: #fe3731"
|
<el-tag v-if="scope.row.processedoperationmode === 1111" color="rgba(254,55,49,0.20)" style="color: #fe3731"
|
||||||
>电网故障停机</el-tag
|
>电网故障停机</el-tag
|
||||||
>
|
>
|
||||||
|
<el-tag v-if="scope.row.processedoperationmode === 33" color="rgba(153, 153, 153, 0.2)" style="color: #999999"
|
||||||
|
>通讯中断</el-tag
|
||||||
|
>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
@ -174,7 +177,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="right">
|
<div class="right">
|
||||||
<div class="num">33</div>
|
<div class="num">33</div>
|
||||||
<div class="unit">MW</div>
|
<div class="unit">MVar</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="rect">
|
<div class="rect">
|
||||||
@ -184,7 +187,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="right">
|
<div class="right">
|
||||||
<div class="num">6</div>
|
<div class="num">6</div>
|
||||||
<div class="unit">MW</div>
|
<div class="unit">MVar</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="check">
|
<div class="check">
|
||||||
@ -227,17 +230,17 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="check">
|
<div class="check">
|
||||||
<div class="left">AVC可增有功</div>
|
<div class="left">AVC可增无功</div>
|
||||||
<div class="right">
|
<div class="right">
|
||||||
<div class="num">5</div>
|
<div class="num">5</div>
|
||||||
<div class="unit">MW</div>
|
<div class="unit">MVar</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="check">
|
<div class="check">
|
||||||
<div class="left">AVC可减有功</div>
|
<div class="left">AVC可减无功</div>
|
||||||
<div class="right">
|
<div class="right">
|
||||||
<div class="num">5</div>
|
<div class="num">5</div>
|
||||||
<div class="unit">MW</div>
|
<div class="unit">MVar</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -331,7 +334,7 @@ const tableColumn = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '状态',
|
label: '状态',
|
||||||
prop: 'iturbineoperationmode',
|
prop: 'processedoperationmode',
|
||||||
width: '',
|
width: '',
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
@ -354,7 +357,7 @@ const createTableReqParams = (airblowerList: { irn: string; name: string }[]) =>
|
|||||||
airBlowerIds.push(item.irn)
|
airBlowerIds.push(item.irn)
|
||||||
return {
|
return {
|
||||||
deviceId: item.irn,
|
deviceId: item.irn,
|
||||||
attributes: [...curTableKey, 'iturbineoperationmode', 'iyplevel', 'gridlostdetected', 'ibplevel'],
|
attributes: [...curTableKey, 'processedoperationmode', 'iyplevel', 'gridlostdetected', 'ibplevel'],
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
return { params, airBlowerInfo, airBlowerIds }
|
return { params, airBlowerInfo, airBlowerIds }
|
||||||
@ -393,7 +396,7 @@ const getAirBlowerList = () => {
|
|||||||
belongLine: airBlowerInfoObj[id].belongLine,
|
belongLine: airBlowerInfoObj[id].belongLine,
|
||||||
deviceCode: airBlowerInfoObj[id].deviceCode,
|
deviceCode: airBlowerInfoObj[id].deviceCode,
|
||||||
...realData,
|
...realData,
|
||||||
iturbineoperationmode: state,
|
processedoperationmode: state,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
tableData.value = data
|
tableData.value = data
|
||||||
|
@ -122,6 +122,9 @@
|
|||||||
<el-tag v-if="scope.row.processedoperationmode === 1111" color="rgba(254,55,49,0.20)" style="color: #fe3731"
|
<el-tag v-if="scope.row.processedoperationmode === 1111" color="rgba(254,55,49,0.20)" style="color: #fe3731"
|
||||||
>电网故障停机</el-tag
|
>电网故障停机</el-tag
|
||||||
>
|
>
|
||||||
|
<el-tag v-if="scope.row.processedoperationmode === 33" color="rgba(153, 153, 153, 0.2)" style="color: #999999"
|
||||||
|
>通讯中断</el-tag
|
||||||
|
>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="item.prop === 'chart'" @click="openLineChart(scope.row)" class="operate">
|
<div v-if="item.prop === 'chart'" @click="openLineChart(scope.row)" class="operate">
|
||||||
<div class="chartIcon">
|
<div class="chartIcon">
|
||||||
@ -272,6 +275,10 @@ const airBlowerSelectOptions = reactive<{ [K in SelectTypeKeyUnionType]: { label
|
|||||||
label: '停机',
|
label: '停机',
|
||||||
value: 2,
|
value: 2,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
label: '通讯中断',
|
||||||
|
value: 33,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
label: '解缆状态',
|
label: '解缆状态',
|
||||||
value: 1110,
|
value: 1110,
|
||||||
|
@ -6,32 +6,35 @@
|
|||||||
@click="handleClick(item)"
|
@click="handleClick(item)"
|
||||||
@contextmenu.prevent="windContextMenu($event,item)"
|
@contextmenu.prevent="windContextMenu($event,item)"
|
||||||
>
|
>
|
||||||
<div class="FanList-panel" :class="item.standard == true ? 'wind-mark' : 'wind-default'">
|
<div class="FanList-panel" :class="{
|
||||||
|
'wind-mark': item.standard==1,
|
||||||
|
'wind-default': item.standard==0,
|
||||||
|
'wind-offline': item.attributeMap.processedoperationmode == 33
|
||||||
|
}">
|
||||||
|
|
||||||
<div class="fanlist-top">
|
<div class="fanlist-top">
|
||||||
<span :class="item.standard == true ? 'wind-mark-icon' : 'fanlist-icon'">
|
<span :class="item.standard == 1 ? 'wind-mark-icon' : 'fanlist-icon'">
|
||||||
<img :class="item.standard == true ? '' : 'wind-picture'" src="~assets/dashboard/biaogan.png" alt="" />
|
<img :class="item.standard == 1 ? '' : 'wind-picture'" src="~assets/dashboard/biaogan.png" alt="" />
|
||||||
</span>
|
</span>
|
||||||
<span class="fanlist-name"> {{ item.name }}</span>
|
<span class="fanlist-name"> {{ item.name }}</span>
|
||||||
<el-tag v-if="item.attributeMap.processedoperationmode === 20" class="tag-panel is-primary" type="primary">并网</el-tag>
|
<el-tag v-if="item.attributeMap.processedoperationmode === 20" class="tag-panel is-primary" type="primary">并网</el-tag>
|
||||||
<el-tag v-if="item.attributeMap.processedoperationmode === 11" class="tag-panel is-warning" type="primary">待机</el-tag>
|
<el-tag v-if="item.attributeMap.processedoperationmode === 11" class="tag-panel is-warning" type="primary">待机</el-tag>
|
||||||
<el-tag v-if="item.attributeMap.processedoperationmode === 16" class="tag-panel is-success" type="primary">启动</el-tag>
|
<el-tag v-if="item.attributeMap.processedoperationmode === 16" class="tag-panel is-success" type="primary">启动</el-tag>
|
||||||
<el-tag v-if="item.attributeMap.processedoperationmode === 10" class="tag-panel is-maintenance" type="primary"
|
<el-tag v-if="item.attributeMap.processedoperationmode === 10" class="tag-panel is-maintenance" type="primary"
|
||||||
>维护</el-tag
|
>维护</el-tag>
|
||||||
>
|
|
||||||
<el-tag v-if="item.attributeMap.processedoperationmode === 0" class="tag-panel is-offline" type="primary">离线</el-tag>
|
<el-tag v-if="item.attributeMap.processedoperationmode === 0" class="tag-panel is-offline" type="primary">离线</el-tag>
|
||||||
<el-tag v-if="item.attributeMap.processedoperationmode === 8" class="tag-panel info" type="primary">限功率运行</el-tag>
|
<el-tag v-if="item.attributeMap.processedoperationmode === 8" class="tag-panel info" type="primary">限功率运行</el-tag>
|
||||||
<el-tag v-if="item.attributeMap.processedoperationmode === 6" class="tag-panel is-danger" type="primary">正常停机</el-tag>
|
<el-tag v-if="item.attributeMap.processedoperationmode === 6" class="tag-panel is-danger" type="primary">正常停机</el-tag>
|
||||||
<el-tag v-if="item.attributeMap.processedoperationmode === 1" class="tag-panel is-danger" type="primary"
|
<el-tag v-if="item.attributeMap.processedoperationmode === 1" class="tag-panel is-danger" type="primary"
|
||||||
>外部因素导致停机</el-tag
|
>外部因素导致停机</el-tag>
|
||||||
>
|
|
||||||
<el-tag v-if="item.attributeMap.processedoperationmode === 2" class="tag-panel is-danger" type="primary">停机</el-tag>
|
<el-tag v-if="item.attributeMap.processedoperationmode === 2" class="tag-panel is-danger" type="primary">停机</el-tag>
|
||||||
<el-tag v-if="item.attributeMap.processedoperationmode === 1110" class="tag-panel is-info" type="primary">解缆状态</el-tag>
|
<el-tag v-if="item.attributeMap.processedoperationmode === 1110" class="tag-panel is-info" type="primary">解缆状态</el-tag>
|
||||||
<el-tag v-if="item.attributeMap.processedoperationmode === 1111" class="tag-panel is-danger" type="primary"
|
<el-tag v-if="item.attributeMap.processedoperationmode === 1111" class="tag-panel is-danger" type="primary"
|
||||||
>电网故障停机</el-tag
|
>电网故障停机</el-tag>
|
||||||
>
|
|
||||||
<el-tag v-if="item.attributeMap.processedoperationmode === 1112" class="tag-panel is-danger" type="primary"
|
<el-tag v-if="item.attributeMap.processedoperationmode === 1112" class="tag-panel is-danger" type="primary"
|
||||||
>安全链停机</el-tag
|
>安全链停机</el-tag>
|
||||||
>
|
<el-tag v-if="item.attributeMap.processedoperationmode === 33" class="tag-panel is-offline" type="primary"
|
||||||
|
>通讯中断</el-tag>
|
||||||
</div>
|
</div>
|
||||||
<div class="fanlist-main">
|
<div class="fanlist-main">
|
||||||
<el-row>
|
<el-row>
|
||||||
@ -254,6 +257,10 @@ const sendManualCommand = (type: 1 | 0) => {
|
|||||||
background-image: linear-gradient(180deg, #f0f6ff 0%, #ffffff 50%);
|
background-image: linear-gradient(180deg, #f0f6ff 0%, #ffffff 50%);
|
||||||
border: 1px solid #e1edf6;
|
border: 1px solid #e1edf6;
|
||||||
}
|
}
|
||||||
|
.wind-offline {
|
||||||
|
background-image: linear-gradient(180deg, #dddddd 0%, #ffffff 93%);
|
||||||
|
border: 1px solid #eeeeee;
|
||||||
|
}
|
||||||
.wind-picture {
|
.wind-picture {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
@ -46,12 +46,7 @@
|
|||||||
<el-table-column prop="status" :label="LinkMonitorFieldsEnums['status']" align="center" width="80">
|
<el-table-column prop="status" :label="LinkMonitorFieldsEnums['status']" align="center" width="80">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<div class="status-container">
|
<div class="status-container">
|
||||||
<span
|
<span :class="scope.row.status == 0 ? 'status-dot-online' : 'status-dot-offline'"></span>
|
||||||
:class="{
|
|
||||||
'status-dot-online': !scope.row.status,
|
|
||||||
'status-dot-offline': scope.row.status,
|
|
||||||
}"
|
|
||||||
></span>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
@ -102,13 +97,13 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { reactive, ref, nextTick } from 'vue'
|
import { reactive, ref, nextTick, onUnmounted } from 'vue'
|
||||||
import { ElContainer, ElAside, ElHeader, ElMain, ElTree, ElInput, ElMessage, ElButton, ElTable, TreeInstance } from 'element-plus'
|
import { ElContainer, ElAside, ElHeader, ElMain, ElTree, ElInput, ElMessage, ElButton, ElTable, TreeInstance } from 'element-plus'
|
||||||
import { Search } from '@element-plus/icons-vue'
|
import { Search } from '@element-plus/icons-vue'
|
||||||
import { LinkMonitorFieldsEnums, LinkMonitorTreeType, LinkMonitorTableType } from './type'
|
import { LinkMonitorFieldsEnums, LinkMonitorTreeType, LinkMonitorTableType } from './type'
|
||||||
import { getNodeListReq, getLinkListReq } from '/@/api/backend/linkMonitor/request'
|
import { getNodeListReq, getLinkListReq } from '/@/api/backend/linkMonitor/request'
|
||||||
import { debounce, cloneDeep } from 'lodash'
|
import { debounce, cloneDeep } from 'lodash'
|
||||||
|
import { protocolList } from '/@/views/backend/node/utils'
|
||||||
const LinkTreePropReplace = {
|
const LinkTreePropReplace = {
|
||||||
label: 'nodeName',
|
label: 'nodeName',
|
||||||
children: 'children',
|
children: 'children',
|
||||||
@ -184,7 +179,8 @@ const getlinkTreeList = () => {
|
|||||||
getlinkTreeList().then((res) => {
|
getlinkTreeList().then((res) => {
|
||||||
curContextMenuTreeData.value = cloneDeep(res as LinkMonitorTreeType)
|
curContextMenuTreeData.value = cloneDeep(res as LinkMonitorTreeType)
|
||||||
linkTreeRef.value?.setCurrentKey(curContextMenuTreeData.value!.id!)
|
linkTreeRef.value?.setCurrentKey(curContextMenuTreeData.value!.id!)
|
||||||
getlinkMonitorList(curContextMenuTreeData.value!.id!, linkMonitorInputValue.value)
|
createTimer()
|
||||||
|
// getlinkMonitorList(curContextMenuTreeData.value!.id!, linkMonitorInputValue.value)
|
||||||
})
|
})
|
||||||
|
|
||||||
const searchLinkTree = () => {
|
const searchLinkTree = () => {
|
||||||
@ -249,7 +245,8 @@ const linkTreeNodeCollapse = (node: any) => {
|
|||||||
}
|
}
|
||||||
const linkTreeNodeClick = (target: LinkMonitorTreeType) => {
|
const linkTreeNodeClick = (target: LinkMonitorTreeType) => {
|
||||||
curContextMenuTreeData.value = cloneDeep(target)
|
curContextMenuTreeData.value = cloneDeep(target)
|
||||||
getlinkMonitorList(curContextMenuTreeData.value!.id!, linkMonitorInputValue.value)
|
createTimer()
|
||||||
|
// getlinkMonitorList(curContextMenuTreeData.value!.id!, linkMonitorInputValue.value)
|
||||||
}
|
}
|
||||||
const renderContent = (h: any, { node, data }: any) => {
|
const renderContent = (h: any, { node, data }: any) => {
|
||||||
const label = node.label || ''
|
const label = node.label || ''
|
||||||
@ -266,10 +263,12 @@ const renderContent = (h: any, { node, data }: any) => {
|
|||||||
const linkMonitorInputValue = ref('')
|
const linkMonitorInputValue = ref('')
|
||||||
const searchLinkMonitor = () => {
|
const searchLinkMonitor = () => {
|
||||||
if (linkMonitorInputValue.value === '') {
|
if (linkMonitorInputValue.value === '') {
|
||||||
getlinkMonitorList(curContextMenuTreeData.value!.id!)
|
// getlinkMonitorList(curContextMenuTreeData.value!.id!)
|
||||||
|
createTimer()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
getlinkMonitorList(curContextMenuTreeData.value!.id!, linkMonitorInputValue.value)
|
createTimer()
|
||||||
|
// getlinkMonitorList(curContextMenuTreeData.value!.id!, linkMonitorInputValue.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
const linkMonitorTableData = ref<LinkMonitorTableType[]>([])
|
const linkMonitorTableData = ref<LinkMonitorTableType[]>([])
|
||||||
@ -282,17 +281,23 @@ const paginationOptions = reactive({
|
|||||||
pageSizes: [20, 50, 100],
|
pageSizes: [20, 50, 100],
|
||||||
})
|
})
|
||||||
const getcurrentPage = () => {
|
const getcurrentPage = () => {
|
||||||
getlinkMonitorList(curContextMenuTreeData.value!.id!, linkMonitorInputValue.value)
|
// getlinkMonitorList(curContextMenuTreeData.value!.id!, linkMonitorInputValue.value)
|
||||||
|
createTimer()
|
||||||
}
|
}
|
||||||
const protocolList = [
|
|
||||||
{ label: 'IEC104主 *', value: 8 },
|
// const protocolList = [
|
||||||
{ label: 'IEC104从 *', value: 9 },
|
// // * 代表需要配置的协议
|
||||||
{ label: 'MODBUSRTU主 *', value: 12 },
|
// { label: 'IEC104从 *', value: 9 },
|
||||||
{ label: 'MODBUSTCP主 *', value: 16 },
|
// { label: 'MODBUSTCP从 *', value: 17 },
|
||||||
]
|
// { label: 'MODBUS', value: 80 },
|
||||||
|
// { label: 'ADS', value: 81 },
|
||||||
|
// ]
|
||||||
const getlinkMonitorList = (nodeId: string, linkName?: string) => {
|
const getlinkMonitorList = (nodeId: string, linkName?: string) => {
|
||||||
getLinkListReq({ nodeId, linkName, pageNum: paginationOptions.current, pageSize: paginationOptions.pageSize })
|
getLinkListReq({ nodeId, linkName, pageNum: paginationOptions.current, pageSize: paginationOptions.pageSize, withStatus: 1 })
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
|
if (!res.rows.length) {
|
||||||
|
clearTimer()
|
||||||
|
}
|
||||||
if (res.rows) {
|
if (res.rows) {
|
||||||
linkMonitorTableData.value = res.rows.map((item) => {
|
linkMonitorTableData.value = res.rows.map((item) => {
|
||||||
return {
|
return {
|
||||||
@ -303,10 +308,12 @@ const getlinkMonitorList = (nodeId: string, linkName?: string) => {
|
|||||||
paginationOptions.total = res.total
|
paginationOptions.total = res.total
|
||||||
} else {
|
} else {
|
||||||
ElMessage.error(res.msg ?? '查询失败')
|
ElMessage.error(res.msg ?? '查询失败')
|
||||||
|
clearTimer()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
ElMessage.error(err?.response?.data?.msg ?? '查询失败')
|
ElMessage.error(err?.response?.data?.msg ?? '查询失败')
|
||||||
|
clearTimer()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -323,6 +330,22 @@ const startLink = (val: LinkMonitorTableType) => {
|
|||||||
const stopLink = (val: LinkMonitorTableType) => {
|
const stopLink = (val: LinkMonitorTableType) => {
|
||||||
console.log('stopLink')
|
console.log('stopLink')
|
||||||
}
|
}
|
||||||
|
let timer: any = null
|
||||||
|
const createTimer = () => {
|
||||||
|
getlinkMonitorList(curContextMenuTreeData.value!.id!, linkMonitorInputValue.value)
|
||||||
|
timer && clearInterval(timer)
|
||||||
|
timer = null
|
||||||
|
timer = setInterval(() => {
|
||||||
|
getlinkMonitorList(curContextMenuTreeData.value!.id!, linkMonitorInputValue.value)
|
||||||
|
}, 5000)
|
||||||
|
}
|
||||||
|
const clearTimer = () => {
|
||||||
|
timer && clearInterval(timer)
|
||||||
|
timer = null
|
||||||
|
}
|
||||||
|
onUnmounted(() => {
|
||||||
|
clearTimer()
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
@ -35,6 +35,7 @@ export type GetLinkMonitorTableParam = {
|
|||||||
linkName?: string
|
linkName?: string
|
||||||
pageNum: number
|
pageNum: number
|
||||||
pageSize: number
|
pageSize: number
|
||||||
|
withStatus?: number
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum LinkMonitorFieldsEnums {
|
export enum LinkMonitorFieldsEnums {
|
||||||
|
@ -178,6 +178,7 @@ import {
|
|||||||
uploadNodeReq,
|
uploadNodeReq,
|
||||||
submitNodeConfigReq,
|
submitNodeConfigReq,
|
||||||
} from '/@/api/backend/node/request'
|
} from '/@/api/backend/node/request'
|
||||||
|
import {protocolList} from '/@/views/backend/node/utils'
|
||||||
import { getInstitutionalTreeListReq } from '/@/api/backend/org/request'
|
import { getInstitutionalTreeListReq } from '/@/api/backend/org/request'
|
||||||
import { debounce } from 'lodash-es'
|
import { debounce } from 'lodash-es'
|
||||||
import ProtocolComponent from './protocol.vue'
|
import ProtocolComponent from './protocol.vue'
|
||||||
@ -530,14 +531,6 @@ const getLinkData = (nodeId: string, linkName?: string) => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const protocolList = [
|
|
||||||
// * 代表需要配置的协议
|
|
||||||
{ label: 'IEC104从 *', value: 9 },
|
|
||||||
{ label: 'MODBUSTCP从 *', value: 17 },
|
|
||||||
{ label: 'MODBUS', value: 80 },
|
|
||||||
{ label: 'ADS', value: 81 },
|
|
||||||
{ label: '故障日志', value: 79 },
|
|
||||||
]
|
|
||||||
|
|
||||||
const protocolPartVisible = ref(false)
|
const protocolPartVisible = ref(false)
|
||||||
const protocolDisabled = ref(false)
|
const protocolDisabled = ref(false)
|
||||||
|
@ -1052,6 +1052,22 @@ const formColumnList: formColumnType[] = [
|
|||||||
value: true,
|
value: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
key: 'adsUser',
|
||||||
|
data: {
|
||||||
|
label: 'ADS账号',
|
||||||
|
type: 'input',
|
||||||
|
value: '',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'adsPassword',
|
||||||
|
data: {
|
||||||
|
label: 'ADS密码',
|
||||||
|
type: 'password',
|
||||||
|
value: '',
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
key: 'ftpMode',
|
key: 'ftpMode',
|
||||||
data: {
|
data: {
|
||||||
@ -1101,26 +1117,6 @@ const formColumnList: formColumnType[] = [
|
|||||||
showValue: '1',
|
showValue: '1',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
|
||||||
key: 'adsUser',
|
|
||||||
data: {
|
|
||||||
label: 'ADS账号',
|
|
||||||
type: 'input',
|
|
||||||
value: '',
|
|
||||||
showKey: 'ftpMode',
|
|
||||||
showValue: '1',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'adsPassword',
|
|
||||||
data: {
|
|
||||||
label: 'ADS密码',
|
|
||||||
type: 'password',
|
|
||||||
value: '',
|
|
||||||
showKey: 'ftpMode',
|
|
||||||
showValue: '1',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
],
|
||||||
timeOutOption: [],
|
timeOutOption: [],
|
||||||
otherOption: [],
|
otherOption: [],
|
||||||
|
@ -1,5 +1,14 @@
|
|||||||
import { LocaleType, BooleanNumber, SheetTypes } from '@univerjs/core'
|
import { LocaleType, BooleanNumber, SheetTypes } from '@univerjs/core'
|
||||||
|
|
||||||
|
export const protocolList = [
|
||||||
|
// * 代表需要配置的协议
|
||||||
|
{ label: 'IEC104从 *', value: 9 },
|
||||||
|
{ label: 'MODBUSTCP从 *', value: 17 },
|
||||||
|
{ label: 'MODBUS', value: 80 },
|
||||||
|
{ label: 'ADS', value: 81 },
|
||||||
|
{ label: '故障日志', value: 79 },
|
||||||
|
]
|
||||||
|
|
||||||
export const excelDefaultConfig: any = {
|
export const excelDefaultConfig: any = {
|
||||||
// IEC104从
|
// IEC104从
|
||||||
9: {
|
9: {
|
||||||
|
@ -414,7 +414,7 @@ const statAnalysisExport = () => {
|
|||||||
|
|
||||||
const calculateAverages = (data: any) => {
|
const calculateAverages = (data: any) => {
|
||||||
let maxWindSpeed = Math.max(...data.map((item: any) => item[0]))
|
let maxWindSpeed = Math.max(...data.map((item: any) => item[0]))
|
||||||
let interval = 5 // 每5m/s一个区间
|
let interval = 0.5
|
||||||
let result = []
|
let result = []
|
||||||
|
|
||||||
for (let windSpeed = 0; windSpeed <= maxWindSpeed; windSpeed += interval) {
|
for (let windSpeed = 0; windSpeed <= maxWindSpeed; windSpeed += interval) {
|
||||||
|
Loading…
Reference in New Issue
Block a user