<template>
|
<flex-layout no-bg>
|
<div class="page-content">
|
<div class="page-content-container">
|
<el-tabs
|
v-model="acTabs"
|
type="border-card"
|
class="flex-layout flex-layout-tabs noborder"
|
@tab-click="tabClick">
|
<el-tab-pane
|
key="eleLine"
|
label="系统拓扑图"
|
name="eleLine">
|
<ele-operation-line :update="update" :info="info" :state="state" :sys="sys" :is-connect="isConnect">
|
<template slot="tools-left">
|
<div style="margin-left: 8px;">
|
<div style="margin-top: 16px">
|
<ele-state-panel :type="isConnect?state.battState1:-1" title="Ⅰ段蓄电池组">
|
<el-button v-if="state.battState1 == 0 || !isConnect" slot="footer" type="warning" icon="el-icon-video-play" @click="showDisChargeDialog(1, true)" :disabled="state.battState2!= 0 || !isConnect">开始核容</el-button>
|
<el-button v-else slot="footer" type="success" icon="el-icon-video-pause" @click="stopTest">停止测试</el-button>
|
</ele-state-panel>
|
</div>
|
|
<div style="margin-top: 24px">
|
<ele-state-panel :type="isConnect?state.battState2:-1" title="Ⅱ段蓄电池组">
|
<el-button v-if="state.battState2 == 0 || !isConnect" slot="footer" type="warning" icon="el-icon-video-play" @click="showDisChargeDialog(2, true)" :disabled="state.battState1 != 0 || !isConnect">开始核容</el-button>
|
<el-button v-else slot="footer" type="success" icon="el-icon-video-pause" @click="stopTest">停止测试</el-button>
|
</ele-state-panel>
|
</div>
|
</div>
|
<div style="margin-top: 12px; text-align: center;">
|
<el-button type="primary" size="small" @click="switchControlShow" style="margin-right: 8px;">开关控制</el-button>
|
<el-popover
|
placement="top"
|
v-model="popoverVisible">
|
<div class="popover-content">
|
<el-button type="primary" size="small" @click="showDisChargeDialog(1, false)">电池组1</el-button>
|
<el-button type="primary" size="small" @click="showDisChargeDialog(2, false)">电池组2</el-button>
|
</div>
|
<el-button type="primary" size="small" slot="reference">参数设置</el-button>
|
</el-popover>
|
</div>
|
</template>
|
</ele-operation-line>
|
</el-tab-pane>
|
<el-tab-pane
|
v-if="false"
|
key="device"
|
label="装置"
|
name="device">
|
<el-table
|
stripe
|
size="small"
|
:data="deviceInfo.data"
|
height="100%">
|
<el-table-column
|
v-for="header in deviceInfo.headers"
|
:key="header.prop"
|
:prop="header.prop"
|
:label="header.label"
|
:width="header.width"
|
align="center"></el-table-column>
|
</el-table>
|
</el-tab-pane>
|
<el-tab-pane
|
key="realTimeOverview"
|
label="实时总览"
|
name="realTimeOverview">
|
<div class="real-time-overview-container">
|
<el-row :gutter="16">
|
<el-col :span="12">
|
<real-time-panel title="1#蓄电池组">
|
<el-row :gutter="16">
|
<el-col :span="12">
|
<table class="real-time-tbl">
|
<tr-item label="电池状态:" :value="state.battState1Text"></tr-item>
|
<tr-item label="组端电压(V):" :value="info.battOutputVol1.toHold(VOL)"></tr-item>
|
<tr-item label="母线电压(V):" :value="info.controlBusVol1.toHold(VOL)"></tr-item>
|
<tr-item label="组端电流(A):" :value="info.battOutputCurr1.toHold(CURR)"></tr-item>
|
<tr-item label="已测时间:" :value="info.battTestTimeLong1Text"></tr-item>
|
<!-- <tr-item label="预估容量(AH):" :value="info.battTestCap1"></tr-item>-->
|
</table>
|
</el-col>
|
<el-col :span="12">
|
<table class="real-time-tbl">
|
<tr-item label="电池环境温度(℃):" :value="info.roomTemp1.toHold(TEMP)"></tr-item>
|
<tr-item label="电池环境湿度(%):" :value="info.roomHumid1.toHold(HUM)"></tr-item>
|
<tr-item label="单体平均电压(V):" :value="'number' == typeof group1Info.avgVol ? group1Info.avgVol.toHold(VOL) : group1Info.avgVol"></tr-item>
|
<tr-item label="单体平均温度(℃):" :value="'number' == typeof group1Info.avgTemp ? group1Info.avgTemp.toHold(TEMP) : group1Info.avgTemp"></tr-item>
|
<tr-item label="最大单体电压编号(V):" :value="'number' == typeof group1Info.maxVol ? group1Info.maxVol.toHold(VOL) : group1Info.maxVol"></tr-item>
|
<tr-item label="最小单体电压编号(V):" :value="'number' == typeof group1Info.minVol ? group1Info.minVol.toHold(VOL) : group1Info.minVol"></tr-item>
|
<tr-item label="最大单体温度编号(℃):" :value="'number' == typeof group1Info.maxTemp ? group1Info.maxTemp.toHold(TEMP) : group1Info.maxTemp"></tr-item>
|
<tr-item label="最小单体温度编号(℃):" :value="'number' == group1Info.minTemp ? group1Info.minTemp.toHold(TEMP) : group1Info.minTemp"></tr-item>
|
</table>
|
</el-col>
|
</el-row>
|
</real-time-panel>
|
</el-col>
|
<el-col :span="12">
|
<real-time-panel title="2#蓄电池组">
|
<el-row :gutter="16">
|
<el-col :span="12">
|
<table class="real-time-tbl">
|
<tr-item label="电池状态:" :value="state.battState2Text"></tr-item>
|
<tr-item label="组端电压(V):" :value="info.battOutputVol2.toHold(VOL)"></tr-item>
|
<tr-item label="母线电压(V):" :value="info.controlBusVol2.toHold(VOL)"></tr-item>
|
<tr-item label="组端电流(A):" :value="info.battOutputCurr2.toHold(CURR)"></tr-item>
|
<tr-item label="已测时间:" :value="info.battTestTimeLong2Text"></tr-item>
|
<!-- <tr-item label="预估容量(AH):" :value="info.battTestCap2"></tr-item>-->
|
</table>
|
</el-col>
|
<el-col :span="12">
|
<table class="real-time-tbl">
|
<tr-item label="电池环境温度(℃):" :value="info.roomTemp2.toHold(TEMP)"></tr-item>
|
<tr-item label="电池环境湿度(%):" :value="info.roomHumid2.toHold(HUM)"></tr-item>
|
<tr-item label="单体平均电压(V):" :value="'number' == typeof group2Info.avgVol ? group2Info.avgVol.toHold(VOL) : group2Info.avgVol"></tr-item>
|
<tr-item label="单体平均温度(℃):" :value="'number' == typeof group2Info.avgTemp ? group2Info.avgTemp.toHold(TEMP) : group2Info.avgTemp"></tr-item>
|
<tr-item label="最大单体电压编号(V):" :value="'number' == typeof group2Info.maxVol ? group2Info.maxVol.toHold(VOL) : group2Info.maxVol"></tr-item>
|
<tr-item label="最小单体电压编号(V):" :value="'number' == typeof group2Info.minVol ? group2Info.minVol.toHold(VOL) : group2Info.minVol"></tr-item>
|
<tr-item label="最大单体温度编号(℃):" :value="'number' == typeof group2Info.maxTemp ? group2Info.maxTemp.toHold(TEMP) : group2Info.maxTemp"></tr-item>
|
<tr-item label="最小单体温度编号(℃):" :value="'number' == typeof group2Info.minTemp ? group2Info.minTemp.toHold(TEMP) : group2Info.minTemp"></tr-item>
|
</table>
|
</el-col>
|
</el-row>
|
</real-time-panel>
|
</el-col>
|
</el-row>
|
</div>
|
</el-tab-pane>
|
<el-tab-pane
|
key="monInfo"
|
label="单体信息"
|
name="monInfo">
|
<el-table
|
stripe
|
size="small"
|
:data="table.datas"
|
height="100%">
|
<el-table-column
|
v-for="header in table.headers"
|
:key="header.prop"
|
:prop="header.prop"
|
:label="header.label"
|
:width="header.width"
|
align="center"></el-table-column>
|
</el-table>
|
</el-tab-pane>
|
</el-tabs>
|
</div>
|
</div>
|
<!-- 放电参数设置 -->
|
<el-dialog
|
title="放电参数设置"
|
width="auto"
|
:visible.sync="disChargeDialog"
|
:close-on-click-modal="false"
|
top="0"
|
class="dialog-center"
|
:modal-append-to-body="false">
|
<ele-operation-params :is-can-test="isCanTest" :visible.sync="disChargeDialog" v-if="disChargeDialog" :batt="batt" :groupNum="groupNum"></ele-operation-params>
|
</el-dialog>
|
<!-- 开关控制 -->
|
<el-dialog
|
title="开关控制"
|
width="auto"
|
:visible.sync="switchDialog"
|
:close-on-click-modal="false"
|
top="0"
|
class="dialog-center"
|
:modal-append-to-body="false">
|
<ele-operation-switch :is-can-control-switch="isCanControlSwitch" :visible.sync="switchDialog" :batt="batt" :state="state"></ele-operation-switch>
|
</el-dialog>
|
</flex-layout>
|
</template>
|
|
<script>
|
import eleOperationLine from "@/views/dataTest/components/diagrams/eleOperation";
|
import EleStatePanel from "@/views/dataTest/components/diagrams/eleOperation/eleStatePanel";
|
import RealTimePanel from "@/views/dataTest/components/diagrams/eleOperation/realTimePanel";
|
import createWs from "@/assets/js/websocket";
|
import {getBattGroupInfo} from "@/views/dataMager/js/battGroupMager";
|
import {stopEleOperation} from "@/views/dataTest/js/realTime";
|
const WSMixin = createWs("dev60870Inverter");
|
import dev60870 from "@/views/dataTest/js/dev60870";
|
import EleOperationParams from "@/views/dataTest/components/EleOperationParams";
|
import EleOperationSwitch from "@/views/dataTest/components/EleOperationSwitch";
|
import {formatSeconds} from "@/assets/js/tools";
|
import TrItem from "@/views/dataTest/components/TrItem";
|
|
import const_digit from "@/assets/js/const/const_digit";
|
const {
|
cap: CAP,
|
vol: VOL,
|
curr: CURR,
|
res: RES,
|
conduct: CONDUCT,
|
temp: TEMP,
|
hum: HUM,
|
} = const_digit;
|
|
export default {
|
name: "eleOperation",
|
mixins: [WSMixin],
|
components: {
|
TrItem,
|
EleOperationSwitch,
|
EleOperationParams,
|
RealTimePanel,
|
EleStatePanel,
|
eleOperationLine,
|
},
|
data() {
|
return {
|
CAP,
|
VOL,
|
CURR,
|
RES,
|
CONDUCT,
|
TEMP,
|
HUM,
|
acTabs: "eleLine",
|
homeListShow: false,
|
batt: {},
|
groupNum: 1,
|
deviceInfo: {
|
headers: [
|
{
|
prop: "num",
|
label: "逆变器模块#",
|
width: "",
|
},
|
{
|
prop: "outputVol",
|
label: "交流输出电压(V)",
|
width: "",
|
},
|
{
|
prop: "acPower",
|
label: "有功功率(KW)",
|
width: "",
|
},
|
{
|
prop: "apPower",
|
label: "视在功率(KW)",
|
width: "",
|
},
|
{
|
prop: "loadRate",
|
label: "负载率(%)",
|
width: "",
|
},
|
{
|
prop: "temp",
|
label: "模块温度(℃)",
|
width: "",
|
},
|
{
|
prop: "outputType",
|
label: "输出方式",
|
width: "",
|
},
|
{
|
prop: "feedbackCurr",
|
label: "当前回馈电流(A)",
|
width: "",
|
},
|
],
|
data: []
|
},
|
disChargeDialog: false,
|
switchDialog: false,
|
update: Math.random(),
|
info: dev60870.info(),
|
state: dev60870.state(),
|
sys: dev60870.sys(),
|
group1: [],
|
group1Info: {
|
avgVol: "-",
|
avgTemp: "-",
|
maxVol: "-",
|
minVol: "-",
|
maxTemp: "-",
|
minTemp: "-"
|
},
|
group2: [],
|
group2Info: {
|
avgVol: "-",
|
avgTemp: "-",
|
maxVol: "-",
|
minVol: "-",
|
maxTemp: "-",
|
minTemp: "-"
|
},
|
serverTime: new Date().format("yyyy-MM-dd hh:mm:ss"),
|
isConnect: false, // 是否连接
|
table: {
|
headers: [
|
{
|
prop: "num1",
|
label: "单体编号",
|
width: "",
|
key1: "",
|
},
|
{
|
prop: "vol1",
|
label: "电压(V)",
|
width: "",
|
key1: "vol",
|
},
|
{
|
prop: "res1",
|
label: "内阻(mΩ)",
|
width: "",
|
key1: "res",
|
},
|
{
|
prop: "temp1",
|
label: "温度(℃)",
|
width: "",
|
key1: "temp",
|
},
|
],
|
datas: []
|
},
|
popoverVisible: false,
|
isCanTest: false,
|
}
|
},
|
watch: {
|
"$route.params.BattGroupId"(battGroupId) {
|
this.$nextTick(() => {
|
this.getBattGroupInfo(battGroupId);
|
});
|
},
|
},
|
methods: {
|
tabClick() {
|
|
},
|
onWSOpen() {
|
this.$nextTick(() => {
|
this.sendMessage();
|
});
|
},
|
sendMessage() {
|
let batt = this.batt;
|
if (!batt.battGroupId || !this.isWSOpen) {
|
return false;
|
}
|
this.SOCKET.send(batt.fbsdeviceId);
|
},
|
onWSMessage(res) {
|
let rs = JSON.parse(res.data);
|
this.update = Math.random();
|
if(rs.code == 1) {
|
this.info = {...rs.data};
|
console.log(rs.data);
|
this.info.battTestTimeLong1Text = formatSeconds(this.info.battTestTimeLong1);
|
this.info.battTestTimeLong2Text = formatSeconds(this.info.battTestTimeLong2);
|
this.state = {...rs.data2};
|
this.state.battState1Text = this.getBattStateText(this.state.battState1);
|
this.state.battState2Text = this.getBattStateText(this.state.battState2);
|
this.sys = {...rs.data3.fbs9100State};
|
this.group1 = rs.data3.battRtDataMap[0];
|
this.group2 = rs.data3.battRtDataMap[1];
|
let group = this.group1;
|
if(this.batt.groupIndexInFBSDevice == 1) {
|
group = this.group2;
|
}
|
if(this.acTabs == "monInfo" || this.table.datas.length ==0) {
|
this.table.datas = group.map((item,key)=>{
|
return {
|
num1: "#"+(key+1),
|
vol1: item.monVol.toHold(VOL),
|
res1: item.monRes.toHold(RES),
|
temp1: item.monTmp.toHold(TEMP),
|
}
|
});
|
}
|
|
this.serverTime = rs.msg;
|
this.group1Info = this.getGroupInfo(this.group1);
|
this.group2Info = this.getGroupInfo(this.group2);
|
}
|
|
let recordTime = new Date(this.info.recordTime).getTime();
|
let serverTime = new Date(this.serverTime).getTime();
|
|
let isConnect = true;
|
if(serverTime-recordTime>=dev60870.timeout) {
|
isConnect = false;
|
}
|
this.isConnect = isConnect;
|
},
|
getBattGroupInfo(battGroupId) {
|
this.homeListShow = false;
|
getBattGroupInfo(battGroupId)
|
.then((res) => {
|
res = res.data;
|
if (res.code) {
|
this.leafClick(res.data[0]);
|
} else {
|
this.$layer.msg("未获取到电池组的信息");
|
}
|
})
|
.catch((error) => {
|
console.log(error);
|
});
|
},
|
leafClick(data) {
|
this.batt = data;
|
this.$nextTick(()=>{
|
this.sendMessage();
|
});
|
},
|
showDisChargeDialog(groupNum, isCanTest) {
|
this.isCanTest = isCanTest;
|
this.groupNum = groupNum;
|
this.disChargeDialog = true;
|
},
|
stopTest() {
|
this.$confirm("确认停止测试?", "系统提示", {}).then(()=>{
|
let loading = this.$layer.loading();
|
stopEleOperation(this.batt.fbsdeviceId).then(res=>{
|
this.$layer.close(loading);
|
let rs = res.data;
|
if(rs.code == 1 && rs.data) {
|
this.$message.success("停止成功!");
|
}else {
|
this.$message.error("停止失败!");
|
}
|
}).catch(error=>{
|
this.$layer.close(loading);
|
this.$message.error("停止失败,请联系管理员!");
|
console.log(error);
|
});
|
}).catch(()=>{});
|
|
},
|
getBattStateText(state) {
|
let rs = "未知";
|
switch (Number(state)) {
|
case 0:
|
rs = "浮充";
|
break;
|
case 1:
|
rs = "放电";
|
break;
|
case 2:
|
rs = "充电";
|
break;
|
default:
|
rs = "未知"
|
break;
|
}
|
return rs;
|
},
|
getGroupInfo(list) {
|
let monNum = list.length;
|
let monVol = 0;
|
let monTemp = 0;
|
let maxVol = {
|
label: "-",
|
value: "-"
|
};
|
let minVol = {
|
label: "-",
|
value: "-"
|
};
|
|
let maxTemp = {
|
label: "-",
|
value: "-"
|
};
|
let minTemp = {
|
label: "-",
|
value: "-"
|
};
|
if(list.length != 0) {
|
maxVol = {
|
label: "#1",
|
value: list[0].monVol,
|
};
|
|
minVol = {
|
label: "#1",
|
value: list[0].monVol,
|
};
|
|
maxTemp = {
|
label: "#1",
|
value: list[0].monTmp,
|
};
|
|
minTemp = {
|
label: "#1",
|
value: list[0].monTmp,
|
};
|
|
list.map((item, key)=>{
|
monVol += item.monVol;
|
monTemp += item.monTmp;
|
if(item.monVol>maxVol.value) {
|
maxVol.label = "#"+(key+1);
|
maxVol.value = item.monVol;
|
}
|
|
if(item.monVol<minVol.value) {
|
minVol.label = "#"+(key+1);
|
minVol.value = item.monVol;
|
}
|
|
if(item.monTmp>maxTemp.value) {
|
maxTemp.label = "#"+(key+1);
|
maxTemp.value = item.monTmp;
|
}
|
|
if(item.monTmp<minTemp.value) {
|
minTemp.label = "#"+(key+1);
|
minTemp.value = item.monTmp;
|
}
|
});
|
}
|
|
let avgVol = monNum==0?0:monVol/monNum;
|
let avgTemp = monNum==0?0:monTemp/monNum;
|
return {
|
avgVol: avgVol.toHold(VOL),
|
avgTemp: avgTemp.toHold(TEMP),
|
maxVol: maxVol.label+":"+maxVol.value.toHold(VOL),
|
minVol: minVol.label+":"+minVol.value.toHold(VOL),
|
maxTemp: maxTemp.label+":"+maxTemp.value.toHold(TEMP),
|
minTemp: minTemp.label+":"+minTemp.value.toHold(TEMP),
|
}
|
},
|
switchControlShow() {
|
let isCanControlSwitch = this.isCanControlSwitch;
|
if(isCanControlSwitch.code == 1) {
|
this.switchDialog = true
|
}else {
|
this.$alert(isCanControlSwitch.msg, '系统提示');
|
}
|
},
|
},
|
computed: {
|
isCanControlSwitch() {
|
let result = {
|
code: 0,
|
msg: "未知"
|
};
|
|
let devWorkstate = this.sys.devWorkstate; // 系统状态
|
let atresia = this.info.atresia; // 闭锁状态[1:闭锁;0:未闭锁]
|
let emergencyStop = this.info.emergencyStop; // 紧急停止 0:正常;1:不正常
|
let poweroff = this.info.poweroff; // 机房停电标识 0:正常;1:不正常
|
if(emergencyStop == 1) {
|
result.msg = "紧急停止";
|
}else if(atresia != 0) {
|
result.msg = "远程闭锁中";
|
}else if(poweroff == 1) {
|
result.msg = "设备工作中: 机房停电";
|
}else if(devWorkstate == 1) {
|
result.msg = "设备工作中: 放电测试中";
|
}else if(devWorkstate == 2) {
|
result.msg = "设备工作中: 充电测试中";
|
}else {
|
result.code = 1;
|
}
|
|
return result;
|
}
|
},
|
mounted() {
|
let battGroupId = this.$route.params.battGroupId;
|
if (battGroupId) {
|
this.getBattGroupInfo(battGroupId);
|
}
|
}
|
}
|
</script>
|
|
<style scoped>
|
.page-content {
|
position: relative;
|
width: 100%;
|
height: 100%;
|
box-sizing: border-box;
|
padding: 0 4px;
|
}
|
.page-content-container {
|
border: 2px solid #143a92;
|
box-sizing: border-box;
|
height: 100%;
|
overflow: hidden;
|
border-radius: 8px;
|
}
|
.flex-layout-tabs {
|
box-sizing: border-box;
|
height: 100%;
|
}
|
.real-time-overview-container {
|
padding: 0 16px;
|
}
|
|
.real-time-tbl {
|
width: 100%;
|
}
|
.real-time-tbl td {
|
padding: 8px 4px;
|
}
|
td.label-text {
|
text-align: right;
|
padding-right: 0;
|
}
|
td.label-value-container {
|
text-align: left;
|
padding-left: 0;
|
}
|
.label-value {
|
display: inline-block;
|
border: 1px solid #08F7E7;
|
border-radius: 4px;
|
background-color: #001A54;
|
color: #FFF000;
|
padding: 4px 16px;
|
text-align: center;
|
min-width: 40px;
|
}
|
.popover-content {
|
background-color: #FFFFFF;
|
padding: 8px;
|
border-top-left-radius: 4px;
|
border-top-right-radius: 4px;
|
}
|
</style>
|