<template>
<div style="padding-left:20px;">
    <el-row :gutter="80">
        <el-col :xs="24" :sm="24" :md="24" :lg="10" :xl="10">
            <el-descriptions :column="1" border :title="title">
                <!-- 设备升级-->
                <el-descriptions-item :labelStyle="statusColor">
                    <template slot="label">
                        <svg-icon icon-class="ota" />
                        OTA升级
                    </template>
                    <el-link :underline="false" style="line-height:28px;font-size:16px;padding-right:10px;">Version {{deviceInfo.firmwareVersion}}</el-link>
                    <el-link type="success" :underline="false" style="font-size:12px;display:none;">已经是最新版本</el-link>
                    <el-button type="success" size="mini" style="float:right;" @click="otaUpgrade()" :disabled="deviceInfo.status!=3">升级</el-button>
                </el-descriptions-item>
                <!-- bool类型-->
                <el-descriptions-item v-for="(item,index) in deviceInfo.boolList" :key="index" :labelStyle="statusColor">
                    <template slot="label">
                        <i class="el-icon-open"></i>
                        {{item.name}}
                    </template>
                    <el-switch v-model="item.shadow" @change="publishThingsModel(deviceInfo,item)" active-text="" inactive-text="" active-value="1" inactive-value="0" style="min-width:100px;" :disabled="shadowUnEnable" />
                </el-descriptions-item>

                <!-- enum类型-->
                <el-descriptions-item v-for="(item,index) in deviceInfo.enumList" :key="index" :labelStyle="statusColor">
                    <template slot="label">
                        <i class="el-icon-s-unfold"></i>
                        {{item.name}}
                    </template>
                    <el-select v-model="item.shadow" placeholder="请选择" @change="publishThingsModel(deviceInfo,item)" clearable :disabled="shadowUnEnable">
                        <el-option v-for="subItem in item.enumList" :key="subItem.value" :label="subItem.text" :value="subItem.value" />
                    </el-select>
                </el-descriptions-item>

                <!-- string类型-->
                <el-descriptions-item v-for="(item,index) in deviceInfo.stringList" :key="index" :labelStyle="statusColor">
                    <template slot="label">
                        <i class="el-icon-tickets"></i>
                        {{item.name}}
                    </template>
                    <el-input v-model="item.shadow" placeholder="请输入字符串" :disabled="shadowUnEnable">
                        <el-button slot="append" icon="el-icon-s-promotion" @click="publishThingsModel(deviceInfo,item)" style="font-size:20px;" title="指令发送"></el-button>
                    </el-input>
                </el-descriptions-item>

                <!-- array类型-->
                <el-descriptions-item v-for="(item,index) in deviceInfo.arrayList" :key="index" :labelStyle="statusColor">
                    <template slot="label">
                        <i class="el-icon-tickets"></i>
                        {{item.name}}
                    </template>
                    <el-input v-model="item.shadow" placeholder="请输入英文逗号分隔的字符串" :disabled="shadowUnEnable">
                        <el-button slot="append" icon="el-icon-s-promotion" @click="publishThingsModel(deviceInfo,item)" style="font-size:20px;" title="指令发送"></el-button>
                    </el-input>
                </el-descriptions-item>

                <!-- decimal类型-->
                <el-descriptions-item v-for="(item,index) in deviceInfo.decimalList" :key="index" :labelStyle="statusColor">
                    <template slot="label">
                        <i class="el-icon-star-off"></i>
                        {{item.name}}
                    </template>
                    <el-input v-model="item.shadow" type="number" placeholder="请输入小数 " :disabled="shadowUnEnable">
                        <el-button slot="append" icon="el-icon-s-promotion" @click="publishThingsModel(deviceInfo,item)" style="font-size:20px;" title="指令发送"></el-button>
                    </el-input>
                </el-descriptions-item>

                <!-- integer类型-->
                <el-descriptions-item v-for="(item,index) in deviceInfo.integerList" :key="index" :labelStyle="statusColor">
                    <template slot="label">
                        <i class="el-icon-paperclip"></i>
                        {{item.name}}
                    </template>
                    <el-input v-model="item.shadow" type="integer" placeholder="请输入整数 " :disabled="shadowUnEnable">
                        <el-button slot="append" icon="el-icon-s-promotion" @click="publishThingsModel(deviceInfo,item)" style="font-size:20px;" title="指令发送"></el-button>
                    </el-input>
                </el-descriptions-item>
            </el-descriptions>

            <!-- 监测数据-->
            <el-descriptions :column="2" border style="margin:40px 0;" title="监测数据">
                <el-descriptions-item v-for="(item,index) in deviceInfo.readOnlyList" :key="index">
                    <template slot="label">
                        <i class="el-icon-odometer"></i>
                        {{item.name}}
                    </template>
                    <el-link type="primary" :underline="false">{{item.shadow}} {{item.unit==null?"":item.unit}}</el-link>
                </el-descriptions-item>
            </el-descriptions>

            <!---设备状态(影子模式，value值不会更新)-->
            <el-descriptions :column="1" border size="mini" v-if="deviceInfo.isShadow==1 && deviceInfo.status!=3">
                <template slot="title">
                    <span style="font-size:14px;color:#606266;">设备离线时状态</span>
                </template>
                <!-- bool类型-->
                <el-descriptions-item v-for="(item,index) in deviceInfo.boolList" :key="index">
                    <template slot="label">
                        <i class="el-icon-open"></i>
                        {{item.name}}
                    </template>
                    <el-switch v-model="item.value" size="mini" active-text="" inactive-text="" active-value="1" inactive-value="0" style="min-width:100px;" disabled />
                </el-descriptions-item>

                <!-- enum类型-->
                <el-descriptions-item v-for="(item,index) in deviceInfo.enumList" :key="index">
                    <template slot="label">
                        <i class="el-icon-s-unfold"></i>
                        {{item.name}}
                    </template>
                    <el-select v-model="item.value" placeholder="请选择" clearable size="mini" disabled>
                        <el-option v-for="subItem in item.enumList" :key="subItem.value" :label="subItem.text" :value="subItem.value" />
                    </el-select>
                </el-descriptions-item>

                <!-- string类型-->
                <el-descriptions-item v-for="(item,index) in deviceInfo.stringList" :key="index">
                    <template slot="label">
                        <i class="el-icon-tickets"></i>
                        {{item.name}}
                    </template>
                    <el-input v-model="item.value" placeholder="请输入字符串" size="mini" disabled></el-input>
                </el-descriptions-item>

                <!-- array类型-->
                <el-descriptions-item v-for="(item,index) in deviceInfo.arrayList" :key="index">
                    <template slot="label">
                        <i class="el-icon-tickets"></i>
                        {{item.name}}
                    </template>
                    <el-input v-model="item.value" placeholder="请输入英文逗号分隔的字符串" size="mini" disabled></el-input>
                </el-descriptions-item>

                <!-- decimal类型-->
                <el-descriptions-item v-for="(item,index) in deviceInfo.decimalList" :key="index">
                    <template slot="label">
                        <i class="el-icon-star-off"></i>
                        {{item.name}}
                    </template>
                    <el-input v-model="item.value" type="number" placeholder="请输入小数" size="mini" disabled></el-input>
                </el-descriptions-item>

                <!-- integer类型-->
                <el-descriptions-item v-for="(item,index) in deviceInfo.integerList" :key="index">
                    <template slot="label">
                        <i class="el-icon-paperclip"></i>
                        {{item.name}}
                    </template>
                    <el-input v-model="item.value" type="integer" placeholder="请输入整数 " size="mini" disabled></el-input>
                </el-descriptions-item>
            </el-descriptions>

            <!-- Mqtt通讯 -->
            <mqtt-client ref="mqttClient" :publish="publish" :subscribes="subscribes" @callbackEvent="mqttCallback($event)" />
        </el-col>

        <el-col :xs="24" :sm="24" :md="24" :lg="14" :xl="14">
            <el-row :gutter="20" style="background-color:#F5F7FA;padding:20px;padding-left:10px;">
                <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="8" v-for="(item,index) in deviceInfo.readOnlyList" :key="index" style="margin-bottom:20px;">
                    <el-card shadow="hover" style="border-radius:30px;">
                        <div ref="map" style="height:230px;width:180px;margin:0 auto;margin-top:-10px;"></div>
                    </el-card>
                </el-col>
            </el-row>
        </el-col>
    </el-row>
</div>
</template>

<script>
import {
    getDeviceRunningStatus
} from "@/api/iot/device"
import {
    cacheJsonThingsModel
} from "@/api/iot/model";
import * as echarts from 'echarts';
import mqttClient from './mqtt-client.vue'

export default {
    name: "running-status",
    components: {
        mqttClient
    },
    props: {
        device: {
            type: Object,
            default: null
        }
    },
    watch: {
        // 获取到父组件传递的device后，刷新列表
        device: function (newVal, oldVal) {
            this.deviceInfo = newVal;
            if (this.deviceInfo && this.deviceInfo.deviceId != 0) {
                getDeviceRunningStatus(this.deviceInfo.deviceId).then(response => {
                    this.deviceInfo = response.data;
                    this.updateDeviceStatus(this.deviceInfo);
                    this.$nextTick(function () {
                        this.MonitorChart();
                    });
                    // Mqtt订阅主题
                    this.mqttSubscribe(this.deviceInfo);
                });
            }
        }
    },
    data() {
        return {
            // 发布消息
            publish: {},
            // 订阅集合
            subscribes: [],
            // 控制模块标题
            title: "设备控制 ",
            // 未启用设备影子
            shadowUnEnable: false,
            // 控制项标题背景
            statusColor: {
                background: '#67C23A',
                color: '#fff',
            },
            // 遮罩层
            loading: true,
            // 设备信息
            deviceInfo: {
                boolList: [],
                enumList: [],
                stringList: [],
                integerList: [],
                decimalList: [],
                arrayList: [],
                readonlyList: []
            },
        }
    },
    created() {

    },
    methods: {
        /** 发布物模型 类型(1=属性，2=功能) */
        publishThingsModel(device, model) {
            // TODO 创建的时候过去一次即可。 获取缓存的Json物模型
            cacheJsonThingsModel(device.productId).then(response => {
                let thingsModel = JSON.parse(response.data);
                let type = 0;
                for (let i = 0; i < thingsModel.functions.length; i++) {
                    if (model.id == thingsModel.functions[i].id) {
                        type = 2;
                        break;
                    }
                }
                if (type == 0) {
                    for (let i = 0; i < thingsModel.properties.length; i++) {
                        if (model.id == thingsModel.properties[i].id) {
                            type = 1;
                            break;
                        }
                    }
                }
                if (type != 0) {
                    this.mqttPublish(type, device, model);
                }
            })
        },
        /** 
         * Mqtt发布消息
         * @type 类型(1=属性，2=功能，3=OTA升级，4=实时监测)
         * @device 设备
         * @model 物模型
         * */
        mqttPublish(type, device, model) {
            let topic = "";
            let message = ""
            if (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 (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 (type == 3) {
                // OTA升级
                topic = "/" + device.productId + "/" + device.serialNumber + "/ota/get";
                message = '{"version":' + device.firmwareVersion + '}';
            } else {
                return;
            }
            if (topic != "") {
                // 发布
                this.publish = {
                    topic: topic,
                    message: message,
                    name: model.name
                }
            }
        },
        /** 接收到Mqtt回调 */
        mqttCallback(data) {
            let topics = [];
            topics = data.topic.split("/");
            let productId = topics[1];
            let deviceNum = topics[2]
            if (topics[3] == "status") {
                // 更新列表中设备的状态
                this.deviceInfo.status = data.message.status;
                this.deviceInfo.isShadow = data.message.isShadow;
                this.updateDeviceStatus(this.deviceInfo);
            }
        },
        /** Mqtt订阅主题 */
        mqttSubscribe(device) {
            // 订阅当前设备状态
            let topic = "/" + device.productId + "/" + device.serialNumber + "/status/post";
            this.subscribes = [topic];
        },
        /** 更新设备状态 */
        updateDeviceStatus(device) {
            if (device.status == 3) {
                this.statusColor.background = '#12d09f';
                this.title = "设备控制（在线）";
            } else {
                if (device.isShadow == 1) {
                    this.statusColor.background = '#409EFF';
                    this.title = "设备控制（影子模式）";
                } else {
                    this.statusColor.background = '#909399';
                    this.title = "设备控制（设备不在线 未启用影子）";
                    this.shadowUnEnable = true;
                }
            }
        },
        /** 设备升级 */
        otaUpgrade() {
            let model = {};
            model.name = "设备升级"
            this.mqttPublish(3, this.deviceInfo, model);
        },
        /**监测图表*/
        MonitorChart() {
            for (let i = 0; i < this.deviceInfo.readOnlyList.length; i++) {
                var myChart = echarts.init(this.$refs.map[i]);
                var option;
                option = {
                    tooltip: {
                        formatter: ' {b} <br/> {c}' + this.deviceInfo.readOnlyList[i].unit
                    },
                    series: [{
                        name: this.deviceInfo.readOnlyList[i].type,
                        type: 'gauge',
                        min: this.deviceInfo.readOnlyList[i].min,
                        max: this.deviceInfo.readOnlyList[i].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.readOnlyList[i].unit,
                            offsetCenter: [0, "80%"],
                            fontSize: 20,
                        },
                        data: [{
                            value: this.deviceInfo.readOnlyList[i].shadow,
                            name: this.deviceInfo.readOnlyList[i].name
                        }],
                        title: {
                            offsetCenter: [0, "115%"],
                            fontSize: 16
                        }
                    }]
                };
                option && myChart.setOption(option);
            }
        }
    },
}
</script>
