1242 lines
67 KiB
Vue
1242 lines
67 KiB
Vue
<template>
|
||
<div class="running-status">
|
||
<el-row :gutter="90">
|
||
<el-col :xs="24" :sm="24" :md="24" :lg="14" :xl="10" class="status-col">
|
||
<el-descriptions :column="1" border>
|
||
<!-- 设备模式-->
|
||
|
||
<el-descriptions-item :labelStyle="statusColor">
|
||
<template slot="label">
|
||
<i class="el-icon-menu"></i>
|
||
{{ $t('device.running-status.866086-0') }}
|
||
</template>
|
||
<span class="title">{{ title }}</span>
|
||
</el-descriptions-item>
|
||
<!-- 设备升级-->
|
||
<el-descriptions-item :labelStyle="statusColor">
|
||
<template slot="label">
|
||
<svg-icon icon-class="ota" />
|
||
{{ $t('device.running-status.866086-1') }}
|
||
</template>
|
||
|
||
<el-button type="primary" size="mini" :plain="true" @click="viewVersion()">{{
|
||
$t('device.running-status.866086-44')
|
||
}}</el-button>
|
||
<el-button type="primary" size="mini" :plain="true" @click="sendDataToIframe()">{{
|
||
$t('device.running-status.866086-44')
|
||
}}</el-button>
|
||
<el-button type="primary" size="mini" :plain="true" @click="sendProductParamOnce()">{{
|
||
$t('device.running-status.866086-44')
|
||
}}</el-button>
|
||
</el-descriptions-item>
|
||
|
||
<!-- 设备物模型-->
|
||
<el-descriptions-item v-for="(item, index) in deviceInfo.thingsModels" :key="index"
|
||
:labelStyle="statusColor">
|
||
<template slot="label">
|
||
<i class="el-icon-open"></i>
|
||
{{ item.name }}
|
||
</template>
|
||
<div v-if="item.datatype.type == 'bool'">
|
||
<el-switch v-model="item.shadow" @change="mqttPublish(deviceInfo, item)" active-text=""
|
||
inactive-text="" active-value="1" inactive-value="0" style="min-width: 100px"
|
||
:disabled="shadowUnEnable || item.isReadonly == 1" />
|
||
</div>
|
||
<div v-if="item.datatype.type == 'enum'" class="emum-wrap">
|
||
<div v-if="item.datatype.showWay && item.datatype.showWay == 'button'">
|
||
<el-button class="btn" size="mini"
|
||
@click="enumButtonClick(deviceInfo, item, subItem.value)"
|
||
v-for="subItem in item.datatype.enumList" :key="subItem.value"
|
||
:disabled="shadowUnEnable || item.isReadonly == 1"
|
||
:class="{ 'is-active-btn': subItem.value === item.shadow }">
|
||
{{ subItem.text }}
|
||
</el-button>
|
||
</div>
|
||
<el-select v-else v-model="item.shadow" :placeholder="$t('device.running-status.866086-3')"
|
||
@change="mqttPublish(deviceInfo, item)"
|
||
:disabled="shadowUnEnable || item.isReadonly == 1">
|
||
<el-option v-for="subItem in item.datatype.enumList" :key="subItem.value"
|
||
:label="subItem.text" :value="subItem.value" />
|
||
</el-select>
|
||
</div>
|
||
<div v-if="item.datatype.type == 'string'">
|
||
<el-input v-model="item.shadow"
|
||
:placeholder="item.datatype.unit ? $t('device.running-status.866086-5', [item.datatype.unit]) : $t('device.running-status.866086-4')"
|
||
:disabled="shadowUnEnable || item.isReadonly == 1">
|
||
<el-button slot="append" icon="el-icon-s-promotion"
|
||
@click="mqttPublish(deviceInfo, item)" style="font-size: 20px"
|
||
:title="$t('device.running-status.866086-6')"
|
||
v-if="!shadowUnEnable && item.isReadonly == 0"></el-button>
|
||
</el-input>
|
||
</div>
|
||
<div v-if="item.datatype.type == 'decimal'">
|
||
<div style="width: 80%; float: left">
|
||
<el-slider v-model="item.shadow" :min="item.datatype.min" :max="item.datatype.max"
|
||
:step="item.datatype.step" :format-tooltip="(x) => x + ' ' + item.datatype.unit"
|
||
:disabled="shadowUnEnable || item.isReadonly == 1"></el-slider>
|
||
</div>
|
||
<div style="width: 20%; float: left">
|
||
<el-button icon="el-icon-s-promotion" type="info" @click="mqttPublish(deviceInfo, item)"
|
||
style="font-size: 16px; padding: 1px 8px; margin: 2px 0 0 5px; border-radius: 3px"
|
||
:title="$t('device.running-status.866086-6')"
|
||
v-if="!shadowUnEnable && item.isReadonly == 0"></el-button>
|
||
</div>
|
||
</div>
|
||
<div v-if="item.datatype.type == 'integer'">
|
||
<div style="width: 80%; float: left">
|
||
<el-slider style="margin-left: 10px" v-model="item.shadow" :min="item.datatype.min"
|
||
:max="item.datatype.max" :step="item.datatype.step"
|
||
:format-tooltip="(x) => x + ' ' + item.datatype.unit"
|
||
:disabled="shadowUnEnable || item.isReadonly == 1"></el-slider>
|
||
</div>
|
||
<div style="width: 20%; float: left">
|
||
<el-button icon="el-icon-s-promotion" type="info" @click="mqttPublish(deviceInfo, item)"
|
||
style="font-size: 16px; padding: 1px 8px; margin: 4px 0 0 10px; border-radius: 3px"
|
||
:title="$t('device.running-status.866086-6')"
|
||
v-if="!shadowUnEnable && item.isReadonly == 0"></el-button>
|
||
</div>
|
||
</div>
|
||
<div v-if="item.datatype.type == 'object'">
|
||
<el-descriptions :column="1" size="mini" border>
|
||
<el-descriptions-item v-for="(param, index) in item.datatype.params" :key="index"
|
||
:label="param.name">
|
||
<div v-if="param.datatype.type == 'bool'">
|
||
<el-switch v-model="param.shadow" @change="mqttPublish(deviceInfo, param)"
|
||
active-text="" inactive-text="" active-value="1" inactive-value="0"
|
||
style="min-width: 100px"
|
||
:disabled="shadowUnEnable || param.isReadonly == 1" />
|
||
</div>
|
||
<div v-if="param.datatype.type == 'enum'">
|
||
<div v-if="param.datatype.showWay && param.datatype.showWay == 'button'">
|
||
<el-button style="margin: 5px" size="mini"
|
||
@click="enumButtonClick(deviceInfo, param, subItem.value)"
|
||
v-for="subItem in param.datatype.enumList" :key="subItem.value"
|
||
:disabled="shadowUnEnable || param.isReadonly == 1"
|
||
:class="{ 'is-active-btn': subItem.value === param.shadow }">
|
||
{{ subItem.text }}
|
||
</el-button>
|
||
</div>
|
||
<el-select size="small" v-else v-model="param.shadow"
|
||
:placeholder="$t('device.running-status.866086-3')"
|
||
@change="mqttPublish(deviceInfo, param)"
|
||
:disabled="shadowUnEnable || param.isReadonly == 1">
|
||
<el-option v-for="subItem in param.datatype.enumList" :key="subItem.value"
|
||
:label="subItem.text" :value="subItem.value" />
|
||
</el-select>
|
||
</div>
|
||
<div v-if="param.datatype.type == 'string'">
|
||
<el-input v-model="param.shadow"
|
||
:placeholder="$t('device.running-status.866086-4')"
|
||
:disabled="shadowUnEnable || param.isReadonly == 1">
|
||
<el-button slot="append" icon="el-icon-s-promotion"
|
||
@click="mqttPublish(deviceInfo, param)" style="font-size: 20px"
|
||
:title="$t('device.running-status.866086-6')"
|
||
v-if="!shadowUnEnable && param.isReadonly == 0"></el-button>
|
||
</el-input>
|
||
</div>
|
||
<div v-if="param.datatype.type == 'decimal'">
|
||
<el-input v-model="param.shadow" type="number"
|
||
:placeholder="$t('device.running-status.866086-7')"
|
||
:disabled="shadowUnEnable || param.isReadonly == 1">
|
||
<el-button slot="append" icon="el-icon-s-promotion"
|
||
@click="mqttPublish(deviceInfo, param)" style="font-size: 20px"
|
||
:title="$t('device.running-status.866086-6')"
|
||
v-if="!shadowUnEnable && param.isReadonly == 0"></el-button>
|
||
</el-input>
|
||
</div>
|
||
<div v-if="param.datatype.type == 'integer'">
|
||
<el-input v-model="param.shadow" type="integer"
|
||
:placeholder="$t('device.running-status.866086-8')"
|
||
:disabled="shadowUnEnable || param.isReadonly == 1">
|
||
<el-button slot="append" icon="el-icon-s-promotion"
|
||
@click="mqttPublish(deviceInfo, param)" style="font-size: 20px"
|
||
:title="$t('device.running-status.866086-6')"
|
||
v-if="!shadowUnEnable && param.isReadonly == 0"></el-button>
|
||
</el-input>
|
||
</div>
|
||
</el-descriptions-item>
|
||
</el-descriptions>
|
||
</div>
|
||
<div v-if="item.datatype.type == 'array'">
|
||
<el-descriptions :column="1" size="mini" border v-if="item.datatype.arrayType != 'object'">
|
||
<el-descriptions-item v-for="(model, index) in item.datatype.arrayModel" :key="index"
|
||
:label="item.name + (index + 1)">
|
||
<div v-if="item.datatype.arrayType == 'string'">
|
||
<el-input :placeholder="$t('device.running-status.866086-4')" size="mini"
|
||
v-model="model.shadow" :disabled="shadowUnEnable || item.isReadonly == 1"
|
||
@input="arrayItemChange($event, item)">
|
||
<el-button slot="append" icon="el-icon-s-promotion"
|
||
@click="mqttPublish(deviceInfo, model)" style="font-size: 20px"
|
||
:title="$t('device.running-status.866086-6')"
|
||
v-if="!shadowUnEnable || item.isReadonly == 0"></el-button>
|
||
</el-input>
|
||
</div>
|
||
<div v-if="item.datatype.arrayType == 'decimal'">
|
||
<el-input type="number" :placeholder="$t('device.running-status.866086-7')"
|
||
size="mini" v-model="model.shadow"
|
||
:disabled="shadowUnEnable || item.isReadonly == 1"
|
||
@input="arrayItemChange($event, item)">
|
||
<el-button slot="append" icon="el-icon-s-promotion"
|
||
@click="mqttPublish(deviceInfo, model)" style="font-size: 20px"
|
||
:title="$t('device.running-status.866086-6')"
|
||
v-if="!shadowUnEnable || item.isReadonly == 0"></el-button>
|
||
</el-input>
|
||
</div>
|
||
<div v-if="item.datatype.arrayType == 'integer'">
|
||
<el-input type="integer" :placeholder="$t('device.running-status.866086-8')"
|
||
size="mini" v-model="model.shadow"
|
||
:disabled="shadowUnEnable || item.isReadonly == 1"
|
||
@input="arrayItemChange($event, item)">
|
||
<el-button slot="append" icon="el-icon-s-promotion"
|
||
@click="mqttPublish(deviceInfo, model)" style="font-size: 20px"
|
||
:title="$t('device.running-status.866086-6')"
|
||
v-if="!shadowUnEnable || item.isReadonly == 0"></el-button>
|
||
</el-input>
|
||
</div>
|
||
</el-descriptions-item>
|
||
</el-descriptions>
|
||
<el-collapse v-if="item.datatype.arrayType == 'object'">
|
||
<el-collapse-item v-for="(arrayParam, index) in item.datatype.arrayParams" :key="index">
|
||
<template slot="title">
|
||
<span style="color: #666">
|
||
<i class="el-icon-tickets"></i>
|
||
{{ item.name + (index + 1) }}
|
||
</span>
|
||
</template>
|
||
<el-descriptions :column="1" size="mini" border>
|
||
<el-descriptions-item v-for="(param, index) in arrayParam" :key="index"
|
||
:label="param.name">
|
||
<div v-if="param.datatype.type == 'bool'">
|
||
<el-switch v-model="param.shadow"
|
||
@change="mqttPublish(deviceInfo, param)" active-text=""
|
||
inactive-text="" active-value="1" inactive-value="0"
|
||
style="min-width: 100px"
|
||
:disabled="shadowUnEnable || param.isReadonly == 1" />
|
||
</div>
|
||
<div v-if="param.datatype.type == 'enum'">
|
||
<div
|
||
v-if="param.datatype.showWay && param.datatype.showWay == 'button'">
|
||
<el-button style="margin: 5px" size="mini"
|
||
@click="enumButtonClick(deviceInfo, param, subItem.value)"
|
||
v-for="subItem in param.datatype.enumList" :key="subItem.value"
|
||
:disabled="shadowUnEnable || param.isReadonly == 1"
|
||
:class="{ 'is-active-btn': subItem.value === param.shadow }">
|
||
{{ subItem.text }}
|
||
</el-button>
|
||
</div>
|
||
<el-select v-else v-model="param.shadow"
|
||
:placeholder="$t('device.running-status.866086-3')" size="small"
|
||
@change="mqttPublish(deviceInfo, param)"
|
||
:disabled="shadowUnEnable || param.isReadonly == 1">
|
||
<el-option v-for="subItem in param.datatype.enumList"
|
||
:key="subItem.value" :label="subItem.text"
|
||
:value="subItem.value" />
|
||
</el-select>
|
||
</div>
|
||
<div v-if="param.datatype.type == 'string'">
|
||
<el-input v-model="param.shadow"
|
||
:placeholder="$t('device.running-status.866086-4')"
|
||
:disabled="shadowUnEnable || param.isReadonly == 1">
|
||
<el-button slot="append" icon="el-icon-s-promotion"
|
||
@click="mqttPublish(deviceInfo, param)" style="font-size: 20px"
|
||
:title="$t('device.running-status.866086-6')"
|
||
v-if="!shadowUnEnable && param.isReadonly == 0"></el-button>
|
||
</el-input>
|
||
</div>
|
||
<div v-if="param.datatype.type == 'decimal'">
|
||
<el-input v-model="param.shadow" type="number"
|
||
:placeholder="$t('device.running-status.866086-7')"
|
||
:disabled="shadowUnEnable || param.isReadonly == 1">
|
||
<el-button slot="append" icon="el-icon-s-promotion"
|
||
@click="mqttPublish(deviceInfo, param)" style="font-size: 20px"
|
||
:title="$t('device.running-status.866086-6')"
|
||
v-if="!shadowUnEnable && param.isReadonly == 0"></el-button>
|
||
</el-input>
|
||
</div>
|
||
<div v-if="param.datatype.type == 'integer'">
|
||
<el-input v-model="param.shadow" type="integer"
|
||
:placeholder="$t('device.running-status.866086-8')"
|
||
:disabled="shadowUnEnable || param.isReadonly == 1">
|
||
<el-button slot="append" icon="el-icon-s-promotion"
|
||
@click="mqttPublish(deviceInfo, param)" style="font-size: 20px"
|
||
:title="$t('device.running-status.866086-6')"
|
||
v-if="!shadowUnEnable && param.isReadonly == 0"></el-button>
|
||
</el-input>
|
||
</div>
|
||
</el-descriptions-item>
|
||
</el-descriptions>
|
||
</el-collapse-item>
|
||
</el-collapse>
|
||
</div>
|
||
</el-descriptions-item>
|
||
</el-descriptions>
|
||
|
||
<!---设备状态(影子模式,value值不会更新)-->
|
||
<el-descriptions style="margin-top: 30px" :column="1" border
|
||
v-if="deviceInfo.isShadow == 1 && deviceInfo.status != 3">
|
||
<template slot="title" v-if="deviceInfo.thingsModels.length > 0">
|
||
<span style="font-size: 14px; color: #606266">{{ $t('device.running-status.866086-9') }}</span>
|
||
</template>
|
||
<!-- 设备物模型-->
|
||
<el-descriptions-item v-for="(item, index) in deviceInfo.thingsModels" :key="index"
|
||
:labelStyle="{ minWidth: '100px' }">
|
||
<template slot="label">
|
||
<i class="el-icon-open"></i>
|
||
{{ item.name }}
|
||
</template>
|
||
<div v-if="item.datatype.type == 'bool'">
|
||
<el-switch v-model="item.value" @change="mqttPublish(deviceInfo, item)" active-text=""
|
||
inactive-text="" active-value="1" inactive-value="0" style="min-width: 100px"
|
||
disabled />
|
||
</div>
|
||
<div v-if="item.datatype.type == 'enum'">
|
||
<div v-if="item.datatype.showWay && item.datatype.showWay == 'button'">
|
||
<el-button style="margin: 5px" size="mini" disabled
|
||
v-for="subItem in item.datatype.enumList" :key="subItem.value">{{ subItem.text
|
||
}}</el-button>
|
||
</div>
|
||
<el-select v-else v-model="item.value" :placeholder="$t('device.running-status.866086-3')"
|
||
@change="mqttPublish(deviceInfo, item)" disabled>
|
||
<el-option v-for="subItem in item.datatype.enumList" :key="subItem.value"
|
||
:label="subItem.text" :value="subItem.value" />
|
||
</el-select>
|
||
</div>
|
||
<div v-if="item.datatype.type == 'string'">
|
||
<el-input v-model="item.value" :placeholder="$t('device.running-status.866086-4')"
|
||
disabled></el-input>
|
||
</div>
|
||
<div v-if="item.datatype.type == 'decimal'">
|
||
<el-input v-model="item.value" type="number"
|
||
:placeholder="$t('device.running-status.866086-7')" disabled></el-input>
|
||
</div>
|
||
<div v-if="item.datatype.type == 'integer'">
|
||
<el-input v-model="item.value" type="integer"
|
||
:placeholder="$t('device.running-status.866086-8')" disabled></el-input>
|
||
</div>
|
||
<div v-if="item.datatype.type == 'object'">
|
||
<el-descriptions :column="1" size="mini" border>
|
||
<el-descriptions-item v-for="(param, index) in item.datatype.params" :key="index"
|
||
:label="param.name">
|
||
<div v-if="param.datatype.type == 'bool'">
|
||
<el-switch v-model="param.value" size="mini"
|
||
@change="mqttPublish(deviceInfo, param)" active-text="" inactive-text=""
|
||
active-value="1" inactive-value="0" style="min-width: 100px" disabled />
|
||
</div>
|
||
<div v-if="param.datatype.type == 'enum'">
|
||
<el-select v-model="param.value"
|
||
:placeholder="$t('device.running-status.866086-3')"
|
||
@change="mqttPublish(deviceInfo, param)" disabled size="mini">
|
||
<el-option v-for="subItem in param.datatype.enumList" :key="subItem.value"
|
||
:label="subItem.text" :value="subItem.value" />
|
||
</el-select>
|
||
</div>
|
||
<div v-if="param.datatype.type == 'string'">
|
||
<el-input v-model="param.value"
|
||
:placeholder="$t('device.running-status.866086-4')" disabled
|
||
size="mini"></el-input>
|
||
</div>
|
||
<div v-if="param.datatype.type == 'decimal'">
|
||
<el-input v-model="param.value" type="number"
|
||
:placeholder="$t('device.running-status.866086-7')" disabled
|
||
size="mini"></el-input>
|
||
</div>
|
||
<div v-if="param.datatype.type == 'integer'">
|
||
<el-input v-model="param.value" type="integer"
|
||
:placeholder="$t('device.running-status.866086-8')" disabled
|
||
size="mini"></el-input>
|
||
</div>
|
||
</el-descriptions-item>
|
||
</el-descriptions>
|
||
</div>
|
||
<div v-if="item.datatype.type == 'array'">
|
||
<el-descriptions :column="1" size="mini" border v-if="item.datatype.arrayType != 'object'">
|
||
<el-descriptions-item v-for="(model, index) in item.datatype.arrayModel" :key="index"
|
||
:label="item.name + (index + 1)">
|
||
<div v-if="item.datatype.arrayType == 'string'">
|
||
<el-input v-model="model.value"
|
||
:placeholder="$t('device.running-status.866086-4')" size="mini"
|
||
disabled></el-input>
|
||
</div>
|
||
<div v-if="item.datatype.arrayType == 'decimal'">
|
||
<el-input v-model="model.value" type="number"
|
||
:placeholder="$t('device.running-status.866086-7')" size="mini"
|
||
disabled></el-input>
|
||
</div>
|
||
<div v-if="item.datatype.arrayType == 'integer'">
|
||
<el-input v-model="model.value" type="integer"
|
||
:placeholder="$t('device.running-status.866086-8')" size="mini"
|
||
disabled></el-input>
|
||
</div>
|
||
</el-descriptions-item>
|
||
</el-descriptions>
|
||
<el-collapse v-if="item.datatype.arrayType == 'object'">
|
||
<el-collapse-item v-for="(arrayParam, index) in item.datatype.arrayParams" :key="index">
|
||
<template slot="title">
|
||
<span style="color: #666">
|
||
<i class="el-icon-tickets"></i>
|
||
{{ item.name + (index + 1) }}
|
||
</span>
|
||
</template>
|
||
<el-descriptions :column="1" size="mini" border>
|
||
<el-descriptions-item v-for="(param, index) in arrayParam" :key="index"
|
||
:label="param.name">
|
||
<div v-if="param.datatype.type == 'bool'">
|
||
<el-switch v-model="param.value"
|
||
@change="mqttPublish(deviceInfo, param)" active-text=""
|
||
inactive-text="" active-value="1" inactive-value="0"
|
||
style="min-width: 100px" disabled />
|
||
</div>
|
||
<div v-if="param.datatype.type == 'enum'">
|
||
<el-select v-model="param.value"
|
||
:placeholder="$t('device.running-status.866086-3')"
|
||
@change="mqttPublish(deviceInfo, param)" disabled size="mini">
|
||
<el-option v-for="subItem in param.datatype.enumList"
|
||
:key="subItem.value" :label="subItem.text"
|
||
:value="subItem.value" />
|
||
</el-select>
|
||
</div>
|
||
<div v-if="param.datatype.type == 'string'">
|
||
<el-input v-model="param.value"
|
||
:placeholder="$t('device.running-status.866086-4')" disabled
|
||
size="mini"></el-input>
|
||
</div>
|
||
<div v-if="param.datatype.type == 'decimal'">
|
||
<el-input v-model="param.value" type="number"
|
||
:placeholder="$t('device.running-status.866086-7')" disabled
|
||
size="mini"></el-input>
|
||
</div>
|
||
<div v-if="param.datatype.type == 'integer'">
|
||
<el-input v-model="param.value" type="integer"
|
||
:placeholder="$t('device.running-status.866086-8')" disabled
|
||
size="mini"></el-input>
|
||
</div>
|
||
</el-descriptions-item>
|
||
</el-descriptions>
|
||
</el-collapse-item>
|
||
</el-collapse>
|
||
</div>
|
||
</el-descriptions-item>
|
||
</el-descriptions>
|
||
</el-col>
|
||
|
||
<el-col :xs="24" :sm="24" :md="24" :lg="10" :xl="14">
|
||
<!-- 设备监测图表-->
|
||
<el-row :gutter="20" v-if="deviceInfo.chartList.length > 0">
|
||
<el-col :xs="24" :sm="12" :md="12" :lg="24" :xl="8" v-for="(item, index) in deviceInfo.chartList"
|
||
:key="index">
|
||
<el-card shadow="hover" style="border-radius: 8px; margin-bottom: 20px">
|
||
<div ref="map" style="height: 230px; width: 185px; margin: 0 auto; margin-bottom: 15px">
|
||
</div>
|
||
</el-card>
|
||
</el-col>
|
||
</el-row>
|
||
</el-col>
|
||
|
||
|
||
<iframe ref="childFrame" src="https://iot-xcwl.cn/h5/gateway/index.html#/" width="23%" height="800px"
|
||
style="border: none;"></iframe>
|
||
|
||
|
||
|
||
<!-- <iframe ref="childFrame" src="http://localhost:81/" width="23%" height="800px"
|
||
style="border: none;"></iframe> -->
|
||
|
||
|
||
|
||
</el-row>
|
||
|
||
<!-- 固件版本查看对话框 -->
|
||
<el-dialog :title="$t('device.running-status.866086-10')" :visible.sync="openVersion" width="550px"
|
||
append-to-body>
|
||
<el-form ref="firmwareForm" label-width="100px" :model="firmwareParams" :inline="true" :rules="rules">
|
||
<el-form-item :label="$t('device.running-status.866086-38')" prop="firmwareType">
|
||
<el-select v-model="deviceInfo.firmwareType" :placeholder="$t('firmware.index.222541-51')"
|
||
@change="handleVersionInputChange" style="width: 350px" disabled>
|
||
<el-option v-for="item in firmwareTypeList" :key="item.value" :label="item.label"
|
||
:value="item.value"></el-option>
|
||
</el-select>
|
||
</el-form-item>
|
||
<el-form-item :label="$t('device.running-status.866086-39')" prop="">
|
||
<el-input :placeholder="$t('device.running-status.866086-40')" v-model="deviceInfo.firmwareVersion"
|
||
style="width: 350px" disabled>
|
||
<template slot="prepend">Version</template>
|
||
</el-input>
|
||
</el-form-item>
|
||
</el-form>
|
||
<div slot="footer">
|
||
<el-tooltip effect="dark" :content="$t('device.running-status.866086-41')" placement="top-start">
|
||
<el-button type="primary" @click="getLatestFirmware" :disabled="device.status !== 3">{{
|
||
$t('device.running-status.866086-42') }}</el-button>
|
||
</el-tooltip>
|
||
<el-button @click="cancel1">{{ $t('cancel') }}</el-button>
|
||
</div>
|
||
</el-dialog>
|
||
|
||
<!-- 添加或修改产品固件对话框 -->
|
||
<el-dialog :title="$t('device.running-status.866086-10')" :visible.sync="openFirmware" width="600px"
|
||
append-to-body>
|
||
<div v-if="firmware == null" style="text-align: center; font-size: 16px">
|
||
<i class="el-icon-success" style="color: #67c23a"></i>
|
||
{{ $t('device.running-status.866086-11') }}
|
||
</div>
|
||
<el-descriptions :column="1" border size="large"
|
||
v-if="firmware != null && deviceInfo.firmwareVersion < firmware.version"
|
||
:labelStyle="{ width: '150px', 'font-weight': 'bold' }">
|
||
<template slot="title">
|
||
<el-link icon="el-icon-success" type="success" :underline="false">{{
|
||
$t('device.running-status.866086-12') }}</el-link>
|
||
</template>
|
||
<el-descriptions-item :label="$t('device.running-status.866086-13')">{{ firmware.firmwareName
|
||
}}</el-descriptions-item>
|
||
<el-descriptions-item :label="$t('device.device-edit.148398-4')">{{ firmware.productName
|
||
}}</el-descriptions-item>
|
||
<el-descriptions-item :label="$t('device.device-edit.148398-12')">Version {{ firmware.version
|
||
}}</el-descriptions-item>
|
||
<el-descriptions-item :label="$t('device.running-status.866086-16')">
|
||
<el-link :href="getDownloadUrl(firmware.filePath)" :underline="false" type="primary">{{
|
||
getDownloadUrl(firmware.filePath) }}</el-link>
|
||
</el-descriptions-item>
|
||
<el-descriptions-item :label="$t('device.running-status.866086-17')">{{ firmware.remark
|
||
}}</el-descriptions-item>
|
||
</el-descriptions>
|
||
<div slot="footer" class="dialog-footer">
|
||
<el-button type="success" @click="otaUpgrade"
|
||
v-if="firmware != null && deviceInfo.firmwareVersion < firmware.version">{{
|
||
$t('device.running-status.866086-18') }}</el-button>
|
||
<el-button @click="cancel">{{ $t('cancel') }}</el-button>
|
||
</div>
|
||
</el-dialog>
|
||
</div>
|
||
</template>
|
||
|
||
<script>
|
||
import { getLatestFirmware } from '@/api/iot/firmware';
|
||
import { serviceInvoke, serviceInvokeReply } from '@/api/iot/runstatus';
|
||
import { getOrderControl } from '@/api/iot/control';
|
||
|
||
export default {
|
||
name: 'running-status',
|
||
props: {
|
||
device: {
|
||
type: Object,
|
||
default: null,
|
||
},
|
||
},
|
||
watch: {
|
||
// 获取到父组件传递的device后,刷新列表
|
||
device: {
|
||
handler(newVal) {
|
||
if (newVal && newVal.deviceId != 0) {
|
||
if (newVal && newVal.deviceId != 0) {
|
||
this.deviceInfo = newVal;
|
||
this.updateDeviceStatus(this.deviceInfo);
|
||
this.$nextTick(function () {
|
||
this.MonitorChart();
|
||
});
|
||
//物模型排序
|
||
if (this.deviceInfo.thingsModels && this.deviceInfo.thingsModels.length > 0) {
|
||
this.deviceInfo.thingsModels = this.device.thingsModels.sort((a, b) => b.order - a.order);
|
||
}
|
||
if (this.deviceInfo.chartList && this.deviceInfo.chartList.length > 0) {
|
||
this.deviceInfo.chartList = this.deviceInfo.chartList.sort((a, b) => b.order - a.order);
|
||
}
|
||
// 添加message事件监听器
|
||
// this.mqttCallback();
|
||
}
|
||
}
|
||
},
|
||
},
|
||
},
|
||
|
||
data() {
|
||
return {
|
||
// 控制模块标题
|
||
title: '设备控制 ',
|
||
// 未启用设备影子
|
||
shadowUnEnable: false,
|
||
// 控制项标题背景
|
||
statusColor: {
|
||
background: '#67C23A',
|
||
color: '#fff',
|
||
minWidth: '100px',
|
||
},
|
||
// 最新固件信息
|
||
firmware: {},
|
||
// 打开固件对话框
|
||
openFirmware: false,
|
||
// 遮罩层
|
||
loading: true,
|
||
// 设备信息
|
||
deviceInfo: {
|
||
boolList: [],
|
||
enumList: [],
|
||
stringList: [],
|
||
integerList: [],
|
||
decimalList: [],
|
||
arrayList: [],
|
||
thingsModels: [],
|
||
chartList: [],
|
||
},
|
||
firmwareParams: {
|
||
firmwareType: '',
|
||
versionInput: '',
|
||
},
|
||
// 监测图表
|
||
monitorChart: [
|
||
{
|
||
chart: {},
|
||
data: {
|
||
id: '',
|
||
name: '',
|
||
value: '',
|
||
},
|
||
},
|
||
],
|
||
openVersion: false,
|
||
firmwareTypeList: [
|
||
{
|
||
label: this.$t('firmware.index.222541-52'),
|
||
value: 1,
|
||
},
|
||
{
|
||
label: 'HTTP',
|
||
value: 2,
|
||
},
|
||
],
|
||
remoteCommand: {},
|
||
// 表单校验
|
||
rules: {
|
||
firmwareType: [
|
||
{
|
||
required: true,
|
||
message: this.$t('device.running-status.866086-43'),
|
||
trigger: 'blur',
|
||
},
|
||
],
|
||
},
|
||
};
|
||
},
|
||
mounted() {
|
||
this.handleDeviceChange(this.device);
|
||
const { deviceId, serialNumber } = this.device;
|
||
if (deviceId) {
|
||
this.initDataStatus();
|
||
this.initData();
|
||
}
|
||
// this.mqttCallback();
|
||
// 只在mounted时发送一次productpram数据
|
||
this.$nextTick(() => {
|
||
this.waitForIframeLoad();
|
||
});
|
||
// 添加消息监听器
|
||
window.addEventListener('message', (event) => {
|
||
// 确保消息来源是可信的
|
||
|
||
|
||
// 找到 id 为 distribute 的模型
|
||
const distributeModel = this.deviceInfo.thingsModels.find(model => model.id === 'distribute');
|
||
if (distributeModel) {
|
||
// 更新模型的 shadow 值,直接使用内部数据
|
||
distributeModel.shadow = JSON.stringify(event.data.data);
|
||
console.log('收到来自子页面的消息:', JSON.stringify(event.data.data));
|
||
|
||
// 调用 mqttPublish 下发数据
|
||
this.mqttPublish(this.deviceInfo, distributeModel);
|
||
}
|
||
|
||
});
|
||
},
|
||
|
||
methods: {
|
||
// 新增方法:等待iframe加载完成
|
||
waitForIframeLoad() {
|
||
const maxAttempts = 5; // 最大尝试次数
|
||
let attempts = 0;
|
||
|
||
const checkInterval = setInterval(() => {
|
||
const iframe = this.$refs.childFrame;
|
||
|
||
// 1. 检查iframe是否存在且已加载
|
||
if (iframe && iframe.contentWindow) {
|
||
// 2. 可选:检查子页面是否已准备好接收消息(需要子页面配合)
|
||
// iframe.contentWindow.postMessage({ type: 'ping' }, '*');
|
||
|
||
clearInterval(checkInterval);
|
||
this.sendProductParamOnce();
|
||
return;
|
||
}
|
||
|
||
// 3. 超过最大尝试次数则停止
|
||
if (++attempts >= maxAttempts) {
|
||
clearInterval(checkInterval);
|
||
console.warn('Iframe not ready after multiple attempts');
|
||
return;
|
||
}
|
||
}, 500); // 每500ms检查一次
|
||
},
|
||
|
||
// 发送productpram数据(保持不变)
|
||
sendProductParamOnce() {
|
||
const iframe = this.$refs.childFrame;
|
||
if (!iframe || !iframe.contentWindow) {
|
||
console.error('Iframe not ready');
|
||
return;
|
||
}
|
||
|
||
const productParamModel = this.deviceInfo.thingsModels.find(model => model.id === 'productpram');
|
||
if (!productParamModel) {
|
||
console.warn('productpram model not found');
|
||
return;
|
||
}
|
||
|
||
let paramData = productParamModel.shadow;
|
||
if (typeof paramData === 'string' && paramData.startsWith('JSON=')) {
|
||
paramData = paramData.substring(5);
|
||
}
|
||
const paramDataString = typeof paramData === 'string' ? paramData : JSON.stringify(paramData);
|
||
|
||
iframe.contentWindow.postMessage(
|
||
paramDataString,
|
||
'https://iot-xcwl.cn/h5/gateway/index.html#/'
|
||
);
|
||
console.log('Initial productpram data sent:', paramDataString);
|
||
},
|
||
|
||
//监听设备状态(设备联动)
|
||
handleDeviceChange(device) {
|
||
if (device && device.deviceId != 0 && this.device.thingsModels) {
|
||
const { firmwareVersion, wirelessVersion, firmwareType, ...res } = device;
|
||
const data = {
|
||
version: firmwareType === 1 ? firmwareVersion : wirelessVersion,
|
||
firmwareType,
|
||
...res,
|
||
};
|
||
this.deviceInfo = data;
|
||
this.updateDeviceStatus(this.deviceInfo);
|
||
this.$nextTick(() => {
|
||
this.MonitorChart();
|
||
// 向iframe发送数据
|
||
// this.sendDataToIframe();
|
||
});
|
||
//物模型排序
|
||
this.deviceInfo.thingsModels = this.deviceInfo.thingsModels.sort((a, b) => b.order - a.order);
|
||
this.deviceInfo.chartList = this.deviceInfo.chartList.sort((a, b) => b.order - a.order);
|
||
}
|
||
},
|
||
initData() {
|
||
// 监听值的实时更新
|
||
this.$busEvent.$on('updateData', (params) => {
|
||
this.updateParam(params);
|
||
});
|
||
},
|
||
initDataStatus() {
|
||
// 监听值的实时更新
|
||
this.$busEvent.$on('updateStatus', (status) => {
|
||
this.updateStatus(status);
|
||
});
|
||
},
|
||
updateStatus(status) {
|
||
let { serialNumber, productId, data } = status;
|
||
if (data) {
|
||
if (this.deviceInfo.serialNumber == serialNumber) {
|
||
this.deviceInfo.status = data.status;
|
||
this.deviceInfo.isShadow = data.isShadow;
|
||
this.deviceInfo.rssi = data.rssi;
|
||
this.updateDeviceStatus(this.deviceInfo);
|
||
}
|
||
}
|
||
},
|
||
//更新参数值
|
||
updateParam(params) {
|
||
let { serialNumber, productId, data } = params;
|
||
let isComplete = false;
|
||
data = data.message;
|
||
if (data) {
|
||
for (let j = 0; j < data.length; j++) {
|
||
for (let k = 0; k < this.deviceInfo.thingsModels.length && !isComplete; k++) {
|
||
if (this.deviceInfo.thingsModels[k].id == data[j].id) {
|
||
const variable = this.deviceInfo.thingsModels[k];
|
||
// 普通类型(小数/整数/字符串/布尔/枚举)
|
||
if (this.deviceInfo.thingsModels[k].datatype.type == 'decimal' || this.deviceInfo.thingsModels[k].datatype.type == 'integer') {
|
||
variable.shadow = Number(data[j].value);
|
||
} else {
|
||
variable.shadow = data[j].value;
|
||
}
|
||
}
|
||
if (this.deviceInfo.thingsModels[k].datatype.type == 'object') {
|
||
// 对象类型
|
||
for (let n = 0; n < this.deviceInfo.thingsModels[k].datatype.params.length; n++) {
|
||
if (this.deviceInfo.thingsModels[k].datatype.params[n].id == data[j].id) {
|
||
this.deviceInfo.thingsModels[k].datatype.params[n].shadow = data[j].value;
|
||
isComplete = true;
|
||
break;
|
||
}
|
||
}
|
||
} else if (this.deviceInfo.thingsModels[k].datatype.type == 'array') {
|
||
// 数组类型
|
||
if (this.deviceInfo.thingsModels[k].datatype.arrayType == 'object') {
|
||
// 1.对象类型数组,id为数组中一个元素,例如:array_01_gateway_temperature
|
||
if (String(data[j].id).indexOf('array_') == 0) {
|
||
for (let n = 0; n < this.deviceInfo.thingsModels[k].datatype.arrayParams.length; n++) {
|
||
for (let m = 0; m < this.deviceInfo.thingsModels[k].datatype.arrayParams[n].length; m++) {
|
||
if (this.deviceInfo.thingsModels[k].datatype.arrayParams[n][m].id == data[j].id) {
|
||
this.deviceInfo.thingsModels[k].datatype.arrayParams[n][m].shadow = data[j].value;
|
||
isComplete = true;
|
||
break;
|
||
}
|
||
}
|
||
if (isComplete) {
|
||
break;
|
||
}
|
||
}
|
||
} else {
|
||
// 2.对象类型数组,例如:gateway_temperature,消息ID添加前缀后匹配
|
||
for (let n = 0; n < this.deviceInfo.thingsModels[k].datatype.arrayParams.length; n++) {
|
||
for (let m = 0; m < this.deviceInfo.thingsModels[k].datatype.arrayParams[n].length; m++) {
|
||
let index = n > 9 ? String(n) : '0' + k;
|
||
let prefix = 'array_' + index + '_';
|
||
if (this.deviceInfo.thingsModels[k].datatype.arrayParams[n][m].id == prefix + data[j].id) {
|
||
this.deviceInfo.thingsModels[k].datatype.arrayParams[n][m].shadow = data[j].value;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
} else {
|
||
// 整数、小数和字符串类型数组
|
||
for (let n = 0; n < this.deviceInfo.thingsModels[k].datatype.arrayModel.length; n++) {
|
||
if (this.deviceInfo.thingsModels[k].datatype.arrayModel[n].id == data[j].id) {
|
||
this.deviceInfo.thingsModels[k].datatype.arrayModel[n].shadow = data[j].value;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
// 图表数据
|
||
for (let k = 0; k < this.deviceInfo.chartList.length; k++) {
|
||
if (this.deviceInfo.chartList[k].id.indexOf('array_') == 0) {
|
||
// 数组类型匹配,例如:array_00_gateway_temperature
|
||
if (this.deviceInfo.chartList[k].id == data[j].id) {
|
||
this.deviceInfo.chartList[k].shadow = data[j].value;
|
||
// 更新图表
|
||
for (let m = 0; m < this.monitorChart.length; m++) {
|
||
if (data[j].id == this.monitorChart[m].data.id) {
|
||
let data = [
|
||
{
|
||
value: this.deviceInfo.chartList[k].shadow,
|
||
name: this.monitorChart[m].data.name,
|
||
},
|
||
];
|
||
this.monitorChart[m].chart.setOption({
|
||
series: [
|
||
{
|
||
data: data,
|
||
},
|
||
],
|
||
});
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
} else {
|
||
// 普通类型匹配
|
||
if (this.deviceInfo.chartList[k].id == data[j].id) {
|
||
this.deviceInfo.chartList[k].shadow = data[j].value;
|
||
// 更新图表
|
||
for (let m = 0; m < this.monitorChart.length; m++) {
|
||
if (data[j].id == this.monitorChart[m].data.id) {
|
||
let data = [
|
||
{
|
||
value: this.deviceInfo.chartList[k].shadow,
|
||
name: this.monitorChart[m].data.name,
|
||
},
|
||
];
|
||
this.monitorChart[m].chart.setOption({
|
||
series: [
|
||
{
|
||
data: data,
|
||
},
|
||
],
|
||
});
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
if (isComplete) {
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
// 在数据更新后发送到iframe
|
||
this.$nextTick(() => {
|
||
this.sendDataToIframe();
|
||
});
|
||
},
|
||
|
||
//发送指令
|
||
async mqttPublish(device, model) {
|
||
const command = {};
|
||
command[model.id] = model.shadow;
|
||
const params = {
|
||
deviceId: device.deviceId,
|
||
modelId: model.modelId,
|
||
};
|
||
const response = await getOrderControl(params);
|
||
if (response.code != 200) {
|
||
this.$message({
|
||
type: 'warning',
|
||
message: response.msg,
|
||
});
|
||
return;
|
||
}
|
||
const data = {
|
||
serialNumber: device.serialNumber,
|
||
productId: device.productId,
|
||
remoteCommand: command,
|
||
identifier: model.id,
|
||
modelName: model.name,
|
||
isShadow: device.status != 3,
|
||
type: model.type,
|
||
};
|
||
// console.log('下发指令:', JSON.stringify(data));
|
||
//设备在线状态判断
|
||
if (this.device.status !== 3 && this.device.isShadow !== 1) {
|
||
if (this.device.status === 1) {
|
||
title = this.$t('device.device-variable.930930-0');
|
||
} else if (this.device.status === 2) {
|
||
title = this.$t('device.device-variable.930930-1');
|
||
} else {
|
||
title = this.$t('device.device-variable.930930-2');
|
||
}
|
||
this.$message({
|
||
type: 'warning',
|
||
message: title,
|
||
});
|
||
return;
|
||
}
|
||
if ((this.deviceInfo.protocolCode === 'MODBUS-TCP' || this.deviceInfo.protocolCode === 'MODBUS-RTU') && this.device.status === 3) {
|
||
await serviceInvokeReply(data).then((response) => {
|
||
if (response.code === 200) {
|
||
this.$message({
|
||
type: 'success',
|
||
message: this.$t('device.running-status.866086-25'),
|
||
});
|
||
} else {
|
||
this.$message.error(response.msg);
|
||
}
|
||
});
|
||
} else {
|
||
await serviceInvoke(data).then((response) => {
|
||
if (response.code === 200) {
|
||
this.$message({
|
||
type: 'success',
|
||
message: this.$t('device.running-status.866086-25'),
|
||
});
|
||
} else {
|
||
this.$message.error(response.msg);
|
||
}
|
||
});
|
||
}
|
||
},
|
||
|
||
/**
|
||
* Mqtt发布消息
|
||
* @device 设备
|
||
* @model 物模型(id/name/type/name/isReadonly/value/shadow),type 类型(1=属性,2=功能,3=OTA升级,4=实时监测)
|
||
* */
|
||
// mqttPublish(device, model) {
|
||
// let topic = "";
|
||
// let message = ""
|
||
// if (model.type == 1) {
|
||
// if (device.status == 3) {
|
||
// // 属性,在线模式
|
||
// topic = "/" + device.productId + "/" + device.serialNumber + "/property-online/get";
|
||
// } else if (device.isShadow) {
|
||
// // 属性,离线模式
|
||
// topic = "/" + device.productId + "/" + device.serialNumber + "/property-offline/post";
|
||
// }
|
||
// message = '[{"id":"' + model.id + '","value":"' + model.shadow + '"}]';
|
||
// } else if (model.type == 2) {
|
||
// if (device.status == 3) {
|
||
// // 功能,在线模式
|
||
// topic = "/" + device.productId + "/" + device.serialNumber + "/function-online/get";
|
||
//
|
||
// } else if (device.isShadow) {
|
||
// // 功能,离线模式
|
||
// topic = "/" + device.productId + "/" + device.serialNumber + "/function-offline/post";
|
||
// }
|
||
// message = '[{"id":"' + model.id + '","value":"' + model.shadow + '"}]';
|
||
// } else if (model.type == 3) {
|
||
// // OTA升级
|
||
// topic = "/" + device.productId + "/" + device.serialNumber + "/ota/get";
|
||
// message = '{"version":' + this.firmware.version + ',"downloadUrl":"' + this.getDownloadUrl(this.firmware.filePath) + '"}';
|
||
// } else {
|
||
// return;
|
||
// }
|
||
// if (topic != "") {
|
||
// // 发布
|
||
// this.$mqttTool.publish(topic, message, model.name).then(res => {
|
||
// this.$modal.notifySuccess(res);
|
||
// }).catch(res => {
|
||
// this.$modal.notifyError(res);
|
||
// });
|
||
// }
|
||
// },
|
||
|
||
/** 枚举类型按钮单击 */
|
||
enumButtonClick(device, model, value) {
|
||
model.shadow = value;
|
||
this.mqttPublish(device, model);
|
||
},
|
||
viewVersion() {
|
||
this.openVersion = true;
|
||
this.firmwareParams.firmwareType = 1;
|
||
this.firmwareParams.versionInput = '';
|
||
this.handleVersionInputChange();
|
||
},
|
||
//选择改变
|
||
handleVersionInputChange() {
|
||
if (this.firmwareParams.firmwareType == 1) {
|
||
this.firmwareParams.versionInput = 'Version' + this.device.firmwareVersion;
|
||
} else {
|
||
this.firmwareParams.versionInput = 'Version' + this.device.wirelessVersion;
|
||
}
|
||
},
|
||
// 取消按钮
|
||
cancel1() {
|
||
this.openVersion = false;
|
||
},
|
||
/** 更新设备状态 */
|
||
updateDeviceStatus(device) {
|
||
if (device.status == 3) {
|
||
this.statusColor.background = '#12d09f';
|
||
this.title = this.$t('device.running-status.866086-26');
|
||
this.shadowUnEnable = false;
|
||
} else {
|
||
if (device.isShadow == 1) {
|
||
this.statusColor.background = '#486FF2';
|
||
this.title = this.$t('device.running-status.866086-27');
|
||
this.shadowUnEnable = false;
|
||
} else {
|
||
this.statusColor.background = '#909399';
|
||
this.title = this.$t('device.running-status.866086-28');
|
||
this.shadowUnEnable = true;
|
||
}
|
||
}
|
||
this.$emit('statusEvent', this.deviceInfo.status);
|
||
},
|
||
/** 物模型数组元素值改变事件 */
|
||
arrayItemChange(value, thingsModel) {
|
||
let shadow = '';
|
||
for (let i = 0; i < thingsModel.datatype.arrayCount; i++) {
|
||
shadow += thingsModel.datatype.arrayModel[i].shadow + ',';
|
||
}
|
||
shadow = shadow.substring(0, shadow.length - 1);
|
||
thingsModel.shadow = shadow;
|
||
},
|
||
/** 物模型中数组值改变事件 */
|
||
arrayInputChange(value, thingsModel) {
|
||
let arrayModels = value.split(',');
|
||
if (arrayModels.length != thingsModel.datatype.arrayCount) {
|
||
this.$modal.alertWarning(this.$t('device.running-status.866086-29') + thingsModel.datatype.arrayCount + this.$t('device.running-status.866086-30'));
|
||
} else {
|
||
for (let i = 0; i < thingsModel.datatype.arrayCount; i++) {
|
||
thingsModel.datatype.arrayModel[i].shadow = arrayModels[i];
|
||
}
|
||
}
|
||
},
|
||
/**用户是否拥有分享设备权限*/
|
||
// hasShrarePerm(permission) {
|
||
// if (this.deviceInfo.isOwner == 0) {
|
||
// // 分享设备权限
|
||
// if (this.deviceInfo.userPerms.indexOf(permission) == -1) {
|
||
// return false;
|
||
// }
|
||
// }
|
||
// return true;
|
||
// },
|
||
/** 设备升级 */
|
||
otaUpgrade() {
|
||
// OTA升级
|
||
let topic = '/' + this.deviceInfo.productId + '/' + this.deviceInfo.serialNumber + '/ota/get';
|
||
let message = '{"version":' + this.firmware.version + ',"downloadUrl":"' + this.getDownloadUrl(this.firmware.filePath) + '"}';
|
||
// 发布
|
||
this.$mqttTool
|
||
.publish(topic, message, this.$t('device.running-status.866086-31'))
|
||
.then((res) => {
|
||
this.$modal.notifySuccess(res);
|
||
})
|
||
.catch((res) => {
|
||
this.$modal.notifyError(res);
|
||
});
|
||
this.openFirmware = false;
|
||
},
|
||
/** 获取最新固件 */
|
||
getLatestFirmware() {
|
||
const { deviceId, firmwareType } = this.deviceInfo;
|
||
getLatestFirmware(deviceId, firmwareType).then((response) => {
|
||
if (response.code === 200) {
|
||
this.firmware = response.data;
|
||
this.openFirmware = true;
|
||
}
|
||
});
|
||
},
|
||
// 取消按钮
|
||
cancel() {
|
||
this.openFirmware = false;
|
||
},
|
||
// 获取下载路径前缀
|
||
getDownloadUrl(path) {
|
||
return window.location.origin + process.env.VUE_APP_BASE_API + path;
|
||
},
|
||
/**图表展示*/
|
||
MonitorChart() {
|
||
for (let i = 0; i < this.deviceInfo.chartList.length; i++) {
|
||
this.monitorChart[i] = {
|
||
chart: this.$echarts.init(this.$refs.map[i]),
|
||
data: {
|
||
id: this.deviceInfo.chartList[i].id,
|
||
name: this.deviceInfo.chartList[i].name,
|
||
value: this.deviceInfo.chartList[i].shadow ? this.deviceInfo.chartList[i].shadow : this.deviceInfo.chartList[i].datatype.min,
|
||
},
|
||
};
|
||
var option;
|
||
option = {
|
||
tooltip: {
|
||
formatter: ' {b} <br/> {c}' + this.deviceInfo.chartList[i].datatype.unit,
|
||
},
|
||
series: [
|
||
{
|
||
name: this.deviceInfo.chartList[i].datatype.type,
|
||
type: 'gauge',
|
||
min: this.deviceInfo.chartList[i].datatype.min,
|
||
max: this.deviceInfo.chartList[i].datatype.max,
|
||
colorBy: 'data',
|
||
splitNumber: 10,
|
||
radius: '100%',
|
||
// 分割线
|
||
splitLine: {
|
||
distance: 4,
|
||
},
|
||
axisLabel: {
|
||
fontSize: 10,
|
||
distance: 10,
|
||
},
|
||
// 刻度线
|
||
axisTick: {
|
||
distance: 4,
|
||
},
|
||
// 仪表盘轴线
|
||
axisLine: {
|
||
lineStyle: {
|
||
width: 8,
|
||
color: [
|
||
[0.2, '#409EFF'], // 0~20%
|
||
[0.8, '#12d09f'], // 40~60%
|
||
[1, '#F56C6C'], // 80~100%
|
||
],
|
||
opacity: 0.3,
|
||
},
|
||
},
|
||
pointer: {
|
||
icon: 'triangle',
|
||
length: '60%',
|
||
width: 7,
|
||
},
|
||
progress: {
|
||
show: true,
|
||
width: 8,
|
||
},
|
||
detail: {
|
||
valueAnimation: true,
|
||
formatter: '{value}' + ' ' + this.deviceInfo.chartList[i].datatype.unit,
|
||
offsetCenter: [0, '80%'],
|
||
fontSize: 20,
|
||
},
|
||
data: [
|
||
{
|
||
value: this.deviceInfo.chartList[i].shadow ? this.deviceInfo.chartList[i].shadow : this.deviceInfo.chartList[i].datatype.min,
|
||
name: this.deviceInfo.chartList[i].name,
|
||
},
|
||
],
|
||
title: {
|
||
offsetCenter: [0, '115%'],
|
||
fontSize: 16,
|
||
},
|
||
},
|
||
],
|
||
};
|
||
option && this.monitorChart[i].chart.setOption(option);
|
||
}
|
||
},
|
||
// 保留原有方法(但不再用于productpram)
|
||
sendDataToIframe() {
|
||
const iframe = this.$refs.childFrame;
|
||
if (iframe && iframe.contentWindow) {
|
||
// 这里只处理upload数据(如果需要)
|
||
const uploadModel = this.deviceInfo.thingsModels.find(model => model.id === 'upload');
|
||
if (uploadModel) {
|
||
let shadowData = uploadModel.shadow;
|
||
if (typeof shadowData === 'string' && shadowData.startsWith('JSON=')) {
|
||
shadowData = shadowData.substring(5);
|
||
}
|
||
const uploadDataString = typeof shadowData === 'string' ? shadowData : JSON.stringify(shadowData);
|
||
|
||
iframe.contentWindow.postMessage(
|
||
uploadDataString,
|
||
'https://iot-xcwl.cn/h5/gateway/index.html#/'
|
||
);
|
||
console.log('Sent upload data:', uploadDataString);
|
||
}
|
||
}
|
||
}
|
||
},
|
||
};
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
.running-status {
|
||
padding-bottom: 20px;
|
||
|
||
.status-col {
|
||
.title {
|
||
line-height: 28px;
|
||
font-size: 16px;
|
||
}
|
||
|
||
.emum-wrap {
|
||
.btn {
|
||
margin: 5px 10px 5px 0;
|
||
}
|
||
}
|
||
|
||
::v-deep .el-slider__bar {
|
||
height: 18px;
|
||
}
|
||
|
||
::v-deep .el-slider__runway {
|
||
height: 18px;
|
||
margin: 5px 0;
|
||
}
|
||
|
||
::v-deep .el-slider__button {
|
||
height: 18px;
|
||
width: 18px;
|
||
border-radius: 10%;
|
||
}
|
||
|
||
::v-deep .el-slider__button-wrapper {
|
||
top: -9px;
|
||
}
|
||
|
||
.is-active-btn {
|
||
color: #1890ff;
|
||
border-color: #badeff;
|
||
background-color: #e8f4ff;
|
||
}
|
||
}
|
||
}
|
||
</style>
|