|
@@ -0,0 +1,534 @@
|
|
|
+<template>
|
|
|
+ <el-dialog
|
|
|
+ width="70%"
|
|
|
+ top="10vh"
|
|
|
+ custom-class="modal"
|
|
|
+ :close-on-click-modal="false"
|
|
|
+ >
|
|
|
+ <template #title>
|
|
|
+ <div class="showTitles">
|
|
|
+ <div class="left">
|
|
|
+ <div class="titles">模型训练</div>
|
|
|
+ <button v-if="!trainingFlag" class="btn" @click="startTraining()">
|
|
|
+ 开始训练
|
|
|
+ </button>
|
|
|
+ <button v-if="trainingFlag" disabled>训练中</button>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="selects">
|
|
|
+ <div style="margin-right: 20px">
|
|
|
+ 比例:
|
|
|
+ <el-select
|
|
|
+ v-model="percent"
|
|
|
+ @change="selectSearch()"
|
|
|
+ clearable
|
|
|
+ placeholder="请选择"
|
|
|
+ popper-class="select"
|
|
|
+ style="width: 120px; margin-left: 20px"
|
|
|
+ >
|
|
|
+ <el-option
|
|
|
+ v-for="item in percentList"
|
|
|
+ :key="item.value"
|
|
|
+ :value="item.value"
|
|
|
+ :label="item.label"
|
|
|
+ />
|
|
|
+ </el-select>
|
|
|
+ </div>
|
|
|
+ <div>
|
|
|
+ 故障前时间范围:
|
|
|
+ <el-select
|
|
|
+ v-model="intervalValue"
|
|
|
+ clearable
|
|
|
+ placeholder="请选择"
|
|
|
+ popper-class="select"
|
|
|
+ style="width: 105px; margin-left: 20px"
|
|
|
+ >
|
|
|
+ <el-option
|
|
|
+ v-for="item in timeList"
|
|
|
+ :key="item.value"
|
|
|
+ :value="item.value"
|
|
|
+ :label="item.label"
|
|
|
+ />
|
|
|
+ </el-select>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ <div>
|
|
|
+ <el-row :type="'flex'" class="content">
|
|
|
+ <el-col :span="12" class="pd-l-8">
|
|
|
+ <div class="titleBar">
|
|
|
+ <div class="titleName">训练级</div>
|
|
|
+ <div class="buttons">
|
|
|
+ <button class="btn" @click="exportALLTraining()">全部导出</button>
|
|
|
+ <button class="btn" @click="exportTraining(0)">导出</button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <el-table
|
|
|
+ height="60vh"
|
|
|
+ ref="multipleTable"
|
|
|
+ empty-text="暂无数据"
|
|
|
+ :data="trainingList"
|
|
|
+ @selection-change="handleSelectionChange"
|
|
|
+ :header-cell-style="{
|
|
|
+ height: '40px',
|
|
|
+ background: 'rgba(83, 98, 104, 0.2)',
|
|
|
+ color: '#b2bdc0',
|
|
|
+ 'border-bottom': '0px solid red',
|
|
|
+ }"
|
|
|
+ :cell-style="{
|
|
|
+ height: '40px',
|
|
|
+ 'border-bottom': 'solid 0px #242424',
|
|
|
+ }"
|
|
|
+ stripe
|
|
|
+ style="width: 100%; margin-bottom: 10px"
|
|
|
+ >
|
|
|
+ <el-table-column type="selection" width="35"> </el-table-column>
|
|
|
+ <el-table-column
|
|
|
+ prop="faultTime"
|
|
|
+ label="FaultTime"
|
|
|
+ width="150"
|
|
|
+ align="center"
|
|
|
+ ></el-table-column>
|
|
|
+ <el-table-column
|
|
|
+ prop="stationId"
|
|
|
+ label="StationId"
|
|
|
+ width="80"
|
|
|
+ align="center"
|
|
|
+ ></el-table-column>
|
|
|
+ <el-table-column
|
|
|
+ prop="stationName"
|
|
|
+ label="StationName"
|
|
|
+ width="120"
|
|
|
+ align="center"
|
|
|
+ ></el-table-column>
|
|
|
+ <el-table-column
|
|
|
+ prop="objectId"
|
|
|
+ label="ObjectId"
|
|
|
+ width="120"
|
|
|
+ align="center"
|
|
|
+ ></el-table-column>
|
|
|
+ <el-table-column
|
|
|
+ prop="modelId"
|
|
|
+ label="ModelId"
|
|
|
+ width="120"
|
|
|
+ align="center"
|
|
|
+ ></el-table-column>
|
|
|
+ </el-table>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="12" class="pd-l-8">
|
|
|
+ <div class="titleBar">
|
|
|
+ <div class="titleName">测试级</div>
|
|
|
+ <div class="buttons">
|
|
|
+ <button class="btn" @click="exportALLTest()">全部导出</button>
|
|
|
+ <button class="btn" @click="exportTest()">导出</button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <el-table
|
|
|
+ height="60vh"
|
|
|
+ ref="multipleTable"
|
|
|
+ empty-text="暂无数据"
|
|
|
+ @selection-change="handleTestChange"
|
|
|
+ :data="testList"
|
|
|
+ :header-cell-style="{
|
|
|
+ height: '40px',
|
|
|
+ background: 'rgba(83, 98, 104, 0.2)',
|
|
|
+ color: '#b2bdc0',
|
|
|
+ 'border-bottom': '0px solid red',
|
|
|
+ }"
|
|
|
+ :cell-style="{
|
|
|
+ height: '40px',
|
|
|
+ 'border-bottom': 'solid 0px #242424',
|
|
|
+ }"
|
|
|
+ stripe
|
|
|
+ style="width: 100%; margin-bottom: 10px"
|
|
|
+ >
|
|
|
+ <el-table-column type="selection" width="35"> </el-table-column>
|
|
|
+ <el-table-column
|
|
|
+ prop="faultTime"
|
|
|
+ label="FaultTime"
|
|
|
+ width="150"
|
|
|
+ align="center"
|
|
|
+ ></el-table-column>
|
|
|
+ <el-table-column
|
|
|
+ prop="stationId"
|
|
|
+ label="StationId"
|
|
|
+ width="80"
|
|
|
+ align="center"
|
|
|
+ ></el-table-column>
|
|
|
+ <el-table-column
|
|
|
+ prop="stationName"
|
|
|
+ label="StationName"
|
|
|
+ width="120"
|
|
|
+ align="center"
|
|
|
+ ></el-table-column>
|
|
|
+ <el-table-column
|
|
|
+ prop="objectId"
|
|
|
+ label="ObjectId"
|
|
|
+ width="120"
|
|
|
+ align="center"
|
|
|
+ ></el-table-column>
|
|
|
+ <el-table-column
|
|
|
+ prop="modelId"
|
|
|
+ label="ModelId"
|
|
|
+ width="120"
|
|
|
+ align="center"
|
|
|
+ ></el-table-column>
|
|
|
+ </el-table>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ </div>
|
|
|
+ <ExportZip ref="export"></ExportZip>
|
|
|
+ </el-dialog>
|
|
|
+</template>
|
|
|
+<script>
|
|
|
+import ExportZip from "./exportZip.vue";
|
|
|
+import UniformCodes from "./UniformCodes.json";
|
|
|
+import { export_blob } from "@tools/excel/Export2Excel.js";
|
|
|
+import axios from "axios";
|
|
|
+import BASE from "@tools/basicTool.js";
|
|
|
+export default {
|
|
|
+ components: {
|
|
|
+ ExportZip,
|
|
|
+ },
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ trainingList: [],
|
|
|
+ testList: [],
|
|
|
+ randoms: [],
|
|
|
+ trainingFlag: false,
|
|
|
+ percent: 7,
|
|
|
+ intervalValue: 1,
|
|
|
+ percentList: [
|
|
|
+ {
|
|
|
+ label: "10%",
|
|
|
+ value: 1,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: "20%",
|
|
|
+ value: 2,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: "30%",
|
|
|
+ value: 4,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: "40%",
|
|
|
+ value: 4,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: "50%",
|
|
|
+ value: 5,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: "60%",
|
|
|
+ value: 6,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: "70%",
|
|
|
+ value: 7,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: "80%",
|
|
|
+ value: 8,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: "90%",
|
|
|
+ value: 9,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: "100%",
|
|
|
+ value: 10,
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ timeList: [
|
|
|
+ { label: "1小时", value: 1 },
|
|
|
+ { label: "1.5小时", value: 1.5 },
|
|
|
+ { label: "2小时", value: 2 },
|
|
|
+ { label: "2.5小时", value: 2.5 },
|
|
|
+ { label: "3小时", value: 3 },
|
|
|
+ { label: "3.5小时", value: 3.5 },
|
|
|
+ { label: "4小时", value: 4 },
|
|
|
+ { label: "4.5小时", value: 4.5 },
|
|
|
+ { label: "5小时", value: 5 },
|
|
|
+ { label: "5.5小时", value: 5.5 },
|
|
|
+ { label: "6小时", value: 6 },
|
|
|
+ { label: "6.5小时", value: 6.5 },
|
|
|
+ { label: "7小时", value: 7 },
|
|
|
+ { label: "7.5小时", value: 7.5 },
|
|
|
+ { label: "8小时", value: 8 },
|
|
|
+ { label: "8.5小时", value: 8.5 },
|
|
|
+ { label: "9小时", value: 9 },
|
|
|
+ { label: "9.5小时", value: 9.5 },
|
|
|
+ { label: "10小时", value: 10 },
|
|
|
+ { label: "10.5小时", value: 10.5 },
|
|
|
+ { label: "11小时", value: 11 },
|
|
|
+ { label: "11.5小时", value: 11.5 },
|
|
|
+ { label: "12小时", value: 12 },
|
|
|
+ ],
|
|
|
+ exportTrainingLists: [],
|
|
|
+ exportTestList: [],
|
|
|
+ exportList: [],
|
|
|
+ resultData: [],
|
|
|
+ tHeader: [],
|
|
|
+ };
|
|
|
+ },
|
|
|
+ props: {
|
|
|
+ allData: {
|
|
|
+ type: Array,
|
|
|
+ default: () => {
|
|
|
+ return [];
|
|
|
+ },
|
|
|
+ },
|
|
|
+ chooseAlgorithm: {
|
|
|
+ type: String,
|
|
|
+ },
|
|
|
+ },
|
|
|
+ updated() {
|
|
|
+ this.selectSearch();
|
|
|
+ this.$emit('handleInterval', this.intervalValue);
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ selectSearch() {
|
|
|
+ (this.trainingList = []),
|
|
|
+ (this.testList = []),
|
|
|
+ (this.randoms = []),
|
|
|
+ this.handleData();
|
|
|
+ },
|
|
|
+ handleData() {
|
|
|
+ let max = this.allData.length;
|
|
|
+ let number = ((max * this.percent) / 10).toFixed(0);
|
|
|
+ if (this.randoms.length >= number) {
|
|
|
+ this.randoms.forEach((item) => {
|
|
|
+ this.trainingList.push(this.allData[item]);
|
|
|
+ });
|
|
|
+ this.testList = this.allData.filter(
|
|
|
+ (val) => this.trainingList.indexOf(val) === -1
|
|
|
+ );
|
|
|
+ this.trainingList.sort(this.Compare("faultTime"));
|
|
|
+ this.testList.sort(this.Compare("faultTime"));
|
|
|
+ } else {
|
|
|
+ let num = this.getRandoms(0, max - 1);
|
|
|
+ if (this.randoms.filter((item) => item === num).length > 0) {
|
|
|
+ this.handleData();
|
|
|
+ } else {
|
|
|
+ this.randoms.push(num);
|
|
|
+ this.handleData();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ getRandoms(Min, Max) {
|
|
|
+ let Range = Max - Min;
|
|
|
+ let Rand = Math.random();
|
|
|
+ let num = Min + Math.round(Range * Rand);
|
|
|
+ return num;
|
|
|
+ },
|
|
|
+ Compare(property) {
|
|
|
+ return function (a, b) {
|
|
|
+ var value1 = new Date(a[property]).getTime();
|
|
|
+ var value2 = new Date(b[property]).getTime();
|
|
|
+ return value2 - value1;
|
|
|
+ };
|
|
|
+ },
|
|
|
+ handleSelectionChange(val) {
|
|
|
+ this.exportTrainingLists = val;
|
|
|
+ },
|
|
|
+ handleTestChange(val) {
|
|
|
+ this.exportTestList = val;
|
|
|
+ },
|
|
|
+ exportALLTest() {
|
|
|
+ this.exportTrainingLists = this.testList;
|
|
|
+ this.exportTraining(0);
|
|
|
+ },
|
|
|
+ exportTest() {
|
|
|
+ this.exportTrainingLists = this.exportTestList;
|
|
|
+ this.exportTraining(0);
|
|
|
+ },
|
|
|
+ exportALLTraining() {
|
|
|
+ this.exportTrainingLists = this.trainingList;
|
|
|
+ this.exportTraining(0);
|
|
|
+ },
|
|
|
+ exportTraining(index) {
|
|
|
+ let requestList = [];
|
|
|
+ this.resultData = [];
|
|
|
+ let hearder = [];
|
|
|
+ let datas = this.exportTrainingLists[index];
|
|
|
+ UniformCodes.forEach((code) => {
|
|
|
+ if (datas.stationId === code.name) {
|
|
|
+ code.values.forEach((val) => {
|
|
|
+ if (datas.modelId === val.modelId) {
|
|
|
+ requestList = val.codes;
|
|
|
+ val.codes.forEach((items) => {
|
|
|
+ hearder[0] = "日期";
|
|
|
+ hearder.push(items.name);
|
|
|
+ });
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ });
|
|
|
+ this.tHeader.push(hearder);
|
|
|
+ this.queryData(requestList, 0, index, datas);
|
|
|
+ },
|
|
|
+ queryData(requestList, zindex, index, datas) {
|
|
|
+ let that = this;
|
|
|
+ that.API.requestData({
|
|
|
+ method: "GET",
|
|
|
+ subUrl: "http://192.168.10.18:8011/ts/history/snap",
|
|
|
+ data: {
|
|
|
+ uniformCode: requestList[zindex].code,
|
|
|
+ startTs:
|
|
|
+ new Date(datas.faultTime).getTime() - that.intervalValue * 3600000,
|
|
|
+ endTs: new Date(datas.faultTime).getTime(),
|
|
|
+ thingType: "windturbine",
|
|
|
+ thingId: datas.objectId,
|
|
|
+ interval: 1,
|
|
|
+ },
|
|
|
+ success(res) {
|
|
|
+ if (res) {
|
|
|
+ that.resultData.push(res);
|
|
|
+ if (zindex === requestList.length - 1) {
|
|
|
+ index++;
|
|
|
+ that.exportList.push(that.resultData);
|
|
|
+ if (index >= that.exportTrainingLists.length) {
|
|
|
+ that.exportExcel();
|
|
|
+ } else {
|
|
|
+ that.exportTraining(index);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ zindex++;
|
|
|
+ that.queryData(requestList, zindex, index, datas);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ });
|
|
|
+ },
|
|
|
+ exportExcel() {
|
|
|
+ let that = this;
|
|
|
+ let paths = [];
|
|
|
+ let filterVal = [];
|
|
|
+ let pathName = ["cs1", "cs2", "cs3"];
|
|
|
+ that.exportTrainingLists.forEach((item, index) => {
|
|
|
+ let dataList = [];
|
|
|
+ for (let flag = 0; flag < that.exportList[index][0].length; flag++) {
|
|
|
+ let tempArray = [];
|
|
|
+ if (index === 0) {
|
|
|
+ filterVal.push(flag);
|
|
|
+ }
|
|
|
+ that.exportList[index].forEach((val, indexs) => {
|
|
|
+ if (indexs === 0) {
|
|
|
+ tempArray[0] = new Date(val[flag].ts).formatDate(
|
|
|
+ "yyyy-MM-dd hh:mm:ss"
|
|
|
+ );
|
|
|
+ }
|
|
|
+ tempArray.push(val[flag] ? val[flag]?.doubleValue : "");
|
|
|
+ });
|
|
|
+ dataList.push(tempArray);
|
|
|
+ }
|
|
|
+ paths.push(
|
|
|
+ export_blob(that.tHeader[index], that.formatJson(filterVal, dataList))
|
|
|
+ );
|
|
|
+ });
|
|
|
+ this.$refs.export.exportZip(paths, pathName, "测试1");
|
|
|
+ this.exportList = [];
|
|
|
+ },
|
|
|
+ formatJson(filterVal, jsonData) {
|
|
|
+ //转数据格式
|
|
|
+ return jsonData.map((v) => filterVal.map((j) => v[j]));
|
|
|
+ },
|
|
|
+ startTraining() {
|
|
|
+ let params = {};
|
|
|
+ let dataInfos = []
|
|
|
+ let dataParams = []
|
|
|
+ this.trainingList.forEach((item) => {
|
|
|
+ let datas = {};
|
|
|
+ datas.startTs =
|
|
|
+ new Date(item.faultTime).getTime() - this.intervalValue * 3600000;
|
|
|
+ datas.endTs = new Date(item.faultTime).getTime();
|
|
|
+ datas.thingId = item.objectId;
|
|
|
+ datas.modelId = item.modelId;
|
|
|
+ datas.stationId = item.stationId;
|
|
|
+ datas.id = item.id;
|
|
|
+ datas.faultTime = new Date(item.faultTime).getTime();
|
|
|
+ dataInfos.push(datas);
|
|
|
+ });
|
|
|
+ this.chooseAlgorithm.parameters.forEach(item =>{
|
|
|
+ dataParams.push(item.value)
|
|
|
+ })
|
|
|
+ let algorithm = {
|
|
|
+ name: this.chooseAlgorithm.name,
|
|
|
+ parameter: JSON.stringify(dataParams)
|
|
|
+ }
|
|
|
+ params.algorithm = algorithm
|
|
|
+ params.dataInfos = dataInfos
|
|
|
+ axios({
|
|
|
+ method: "post",
|
|
|
+ url: "http://192.168.10.18:8080/api/coordinate/execute",
|
|
|
+ data: params,
|
|
|
+ header: {
|
|
|
+ "Content-Type": "application/json",
|
|
|
+ },
|
|
|
+ }).then((res) => {
|
|
|
+ if (res.data === "success") {
|
|
|
+ this.BASE.showMsg({
|
|
|
+ type: "success",
|
|
|
+ msg: "训练中...",
|
|
|
+ });
|
|
|
+ this.trainingFlag = true;
|
|
|
+ this.$emit("click-training");
|
|
|
+ }else{
|
|
|
+ this.BASE.showMsg({
|
|
|
+ type: "warning",
|
|
|
+ msg: res.data,
|
|
|
+ });
|
|
|
+ }
|
|
|
+ });
|
|
|
+ },
|
|
|
+ reset() {
|
|
|
+ this.trainingFlag = false;
|
|
|
+ },
|
|
|
+ },
|
|
|
+};
|
|
|
+</script>
|
|
|
+<style scope lang="less">
|
|
|
+.showTitles {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: row;
|
|
|
+ justify-content: space-between;
|
|
|
+ align-items: center;
|
|
|
+
|
|
|
+ .left {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: row;
|
|
|
+ align-items: center;
|
|
|
+
|
|
|
+ .titles {
|
|
|
+ margin-right: 20px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+.selects {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: row;
|
|
|
+ margin-right: 43px;
|
|
|
+}
|
|
|
+.titleBar {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: row;
|
|
|
+ justify-content: space-between;
|
|
|
+ align-items: center;
|
|
|
+
|
|
|
+ .titleName {
|
|
|
+ color: #ffffff;
|
|
|
+ font-size: 16px;
|
|
|
+ }
|
|
|
+}
|
|
|
+.buttons {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: row-reverse;
|
|
|
+ margin-bottom: 10px;
|
|
|
+
|
|
|
+ .btn {
|
|
|
+ margin-right: 15px;
|
|
|
+ }
|
|
|
+}
|
|
|
+</style>
|