瀏覽代碼

feat: anolg

Casper Dai 2 年之前
父節點
當前提交
b19be8247a

+ 46 - 0
src/views/device/detail/components/Anolg/components/BoxStatus.vue

@@ -0,0 +1,46 @@
+<template>
+  <div class="l-flex--col u-font-size--sm">
+    <div class="c-sibling-item--v u-bold">播控器状态</div>
+    <div class="c-sibling-item--v l-grid--info mini">
+      <div
+        class="o-button"
+        @click="onTrigger('offline')"
+      >
+        触发离线
+      </div>
+      <div
+        class="o-button"
+        @click="onTrigger('online')"
+      >
+        触发上线
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import { publish } from '@/utils/mqtt'
+
+export default {
+  name: 'AnolgBoxStatus',
+  props: {
+    device: {
+      type: Object,
+      required: true
+    }
+  },
+  methods: {
+    onTrigger (topic) {
+      publish(`${this.device.productId}/${this.device.id}/${topic}`, JSON.stringify({
+        messageId: `${this.device.id}_${Math.random().toString(16).slice(2)}`,
+        timestamp: `${Date.now()}`
+      }), true).then(() => {
+        this.$message({
+          type: 'success',
+          message: '触发成功'
+        })
+      })
+    }
+  }
+}
+</script>

+ 101 - 0
src/views/device/detail/components/Anolg/components/Deviation.vue

@@ -0,0 +1,101 @@
+<template>
+  <div class="l-flex--col u-font-size--sm">
+    <div class="c-sibling-item--v u-bold">
+      位移传感器
+      <i
+        v-if="!config"
+        class="el-icon-loading"
+      />
+    </div>
+    <div
+      v-if="config"
+      class="c-sibling-item--v"
+    >
+      <div class="l-flex--row c-sibling-item--v">
+        <div
+          class="c-sibling-item o-button"
+          @click="onTrigger"
+        >
+          触发 x {{ target.x }}° y {{ target.y }}° z {{ target.z }}°
+        </div>
+        <div class="l-flex--row c-sibling-item far">
+          x {{ config[0] }}°
+          <span class="u-color--error dark">±{{ config[1] }}°</span>
+        </div>
+        <div class="l-flex--row c-sibling-item">
+          y {{ config[2] }}°
+          <span class="u-color--error dark">±{{ config[3] }}°</span>
+        </div>
+        <div class="l-flex--row c-sibling-item">
+          z {{ config[4] }}°
+          <span class="u-color--error dark">±{{ config[5] }}°</span>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import { ThirdPartyDevice } from '@/constant'
+import {
+  DEVIATION,
+  getTenantAttributeByBackground
+} from '@/views/realm/settings/api.js'
+import { triggerSensor } from './api'
+
+export default {
+  name: 'AnolgDeviation',
+  props: {
+    deviceId: {
+      type: String,
+      required: true
+    }
+  },
+  data () {
+    return {
+      config: null,
+      target: {
+        x: 0,
+        y: 0,
+        z: 0
+      }
+    }
+  },
+  created () {
+    this.getAttribute()
+    this.$timer = -1
+  },
+  beforeDestroy () {
+    this.$timer = -1
+  },
+  methods: {
+    getAttribute () {
+      getTenantAttributeByBackground(DEVIATION).then(
+        ({ data }) => {
+          if (data) {
+            this.config = data.attributeValue.split(',').map(Number)
+            this.target = {
+              x: Number((this.config[0] + this.config[1] + Math.random() * 10).toFixed(3)),
+              y: Number((this.config[2] + this.config[3] + Math.random() * 10).toFixed(3)),
+              z: Number((this.config[4] + this.config[5] + Math.random() * 10).toFixed(3))
+            }
+          }
+        },
+        () => {
+          if (this.$timer !== -1) {
+            this.getAttribute()
+          }
+        }
+      )
+    },
+    onTrigger () {
+      triggerSensor({
+        deviceId: this.deviceId,
+        type: ThirdPartyDevice.TRANSLOCATION_SENSOR,
+        sensorValue: 0,
+        ...this.target
+      })
+    }
+  }
+}
+</script>

+ 50 - 0
src/views/device/detail/components/Anolg/components/Monitor.vue

@@ -0,0 +1,50 @@
+<template>
+  <div class="l-flex--col u-font-size--sm">
+    <div class="c-sibling-item--v u-bold">监测</div>
+    <div class="c-sibling-item--v l-grid--info mini">
+      <div
+        class="o-button"
+        @click="onTrigger('blackscreen')"
+      >
+        屏幕黑屏
+      </div>
+      <div
+        class="o-button"
+        @click="onTrigger('illegalcontent')"
+      >
+        内容违规
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import {
+  triggerBlackScreenMonitorByCamera,
+  triggerIllegalContent
+} from './api'
+
+export default {
+  name: 'AnolgMonitor',
+  props: {
+    deviceId: {
+      type: String,
+      required: true
+    }
+  },
+  methods: {
+    onTrigger (type) {
+      switch (type) {
+        case 'blackscreen':
+          triggerBlackScreenMonitorByCamera(this.deviceId)
+          break
+        case 'illegalcontent':
+          triggerIllegalContent(this.deviceId)
+          break
+        default:
+          break
+      }
+    }
+  }
+}
+</script>

+ 127 - 0
src/views/device/detail/components/Anolg/components/Temperature.vue

@@ -0,0 +1,127 @@
+<template>
+  <div class="l-flex--col u-font-size--sm">
+    <div class="c-sibling-item--v u-font-size--sm u-bold">
+      温度传感器
+      <i
+        v-if="!config"
+        class="el-icon-loading"
+      />
+    </div>
+    <div
+      v-if="config"
+      class="c-sibling-item--v"
+    >
+      <div class="l-flex--row c-sibling-item--v">
+        <div
+          class="c-sibling-item o-button"
+          @click="onTrigger(0)"
+        >
+          触发{{ temperature[0] }}­°C
+        </div>
+        <div class="c-sibling-item far">低于一级预警阈值</div>
+      </div>
+      <div class="l-flex--row c-sibling-item--v">
+        <div
+          class="c-sibling-item o-button"
+          @click="onTrigger(1)"
+        >
+          触发{{ temperature[1] }}­°C
+        </div>
+        <div class="c-sibling-item far">一级预警阈值:{{ config[0] }}­°C</div>
+        <div class="c-sibling-item u-color--error dark">发送提示性预警</div>
+      </div>
+      <div class="l-flex--row c-sibling-item--v far">
+        <div
+          class="c-sibling-item o-button"
+          @click="onTrigger(2)"
+        >
+          触发{{ temperature[2] }}­°C
+        </div>
+        <div class="c-sibling-item far">二级预警阈值:{{ config[1] }}­°C</div>
+        <div class="c-sibling-item u-color--error dark">发送中级预警,开启风机;低于一级预警阈值后关闭风机</div>
+      </div>
+      <div class="l-flex--row c-sibling-item--v far">
+        <div
+          class="c-sibling-item o-button"
+          @click="onTrigger(3)"
+        >
+          触发{{ temperature[3] }}­°C
+        </div>
+        <div class="c-sibling-item far">三级预警阈值:{{ config[2] }}­°C</div>
+        <div class="c-sibling-item u-color--error dark">发送紧急预警</div>
+      </div>
+      <div class="l-flex--row c-sibling-item--v far">
+        <div
+          class="c-sibling-item o-button"
+          @click="onTrigger(4)"
+        >
+          触发{{ temperature[4] }}­°C
+        </div>
+        <div class="c-sibling-item far">四级预警阈值:{{ config[3] }}­°C</div>
+        <div class="c-sibling-item u-color--error dark">发送紧急预警,关闭大屏电源</div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import { ThirdPartyDevice } from '@/constant'
+import {
+  TEMPERATURE,
+  getTenantAttributeByBackground
+} from '@/views/realm/settings/api.js'
+import { triggerSensor } from './api'
+
+export default {
+  name: 'AnolgTemperature',
+  props: {
+    deviceId: {
+      type: String,
+      required: true
+    }
+  },
+  data () {
+    return {
+      config: null,
+      temperature: []
+    }
+  },
+  created () {
+    this.getAttribute()
+    this.$timer = -1
+  },
+  beforeDestroy () {
+    this.$timer = -1
+  },
+  methods: {
+    getAttribute () {
+      getTenantAttributeByBackground(TEMPERATURE).then(
+        ({ data }) => {
+          if (data) {
+            this.config = data.attributeValue.split(',').map(Number)
+            this.temperature = [
+              Number((this.config[0] - Math.random() * 5).toFixed(1)),
+              Number((this.config[0] + ((this.config[1] - this.config[0]) * Math.random())).toFixed(1)),
+              Number((this.config[1] + ((this.config[2] - this.config[1]) * Math.random())).toFixed(1)),
+              Number((this.config[2] + ((this.config[3] - this.config[2]) * Math.random())).toFixed(1)),
+              Number((this.config[3] - Math.random() * 5).toFixed(1))
+            ]
+          }
+        },
+        () => {
+          if (this.$timer !== -1) {
+            this.getAttribute()
+          }
+        }
+      )
+    },
+    onTrigger (level) {
+      triggerSensor({
+        deviceId: this.deviceId,
+        type: ThirdPartyDevice.TEMPERATURE_SENSOR,
+        sensorValue: this.temperature[level]
+      })
+    }
+  }
+}
+</script>

+ 23 - 0
src/views/device/detail/components/Anolg/components/api.js

@@ -0,0 +1,23 @@
+import { messageSend } from '@/api/base'
+
+export function triggerSensor (data) {
+  return messageSend({
+    url: '/device/sensor/push',
+    method: 'POST',
+    data
+  }, '触发')
+}
+
+export function triggerBlackScreenMonitorByCamera (deviceId) {
+  return messageSend({
+    url: `/device/moni/camera?deviceId=${deviceId}`,
+    method: 'GET'
+  }, '触发')
+}
+
+export function triggerIllegalContent (deviceId) {
+  return messageSend({
+    url: `/device/moni/shebeihuicai?deviceId=${deviceId}`,
+    method: 'GET'
+  }, '触发')
+}

+ 48 - 0
src/views/device/detail/components/Anolg/index.vue

@@ -0,0 +1,48 @@
+<template>
+  <div>
+    <temperature
+      class="c-sibling-item--v"
+      :device-id="deviceId"
+    />
+    <deviation
+      class="c-sibling-item--v far"
+      :device-id="deviceId"
+    />
+    <box-status
+      class="c-sibling-item--v far"
+      :device="device"
+    />
+    <monitor
+      class="c-sibling-item--v far"
+      :device-id="deviceId"
+    />
+  </div>
+</template>
+
+<script>
+import Temperature from './components/Temperature.vue'
+import Deviation from './components/Deviation.vue'
+import BoxStatus from './components/BoxStatus.vue'
+import Monitor from './components/Monitor.vue'
+
+export default {
+  name: 'Anolg',
+  components: {
+    Temperature,
+    Deviation,
+    BoxStatus,
+    Monitor
+  },
+  props: {
+    device: {
+      type: Object,
+      required: true
+    }
+  },
+  computed: {
+    deviceId () {
+      return this.device.id
+    }
+  }
+}
+</script>

+ 6 - 3
src/views/device/detail/index.vue

@@ -90,6 +90,7 @@ import DeviceExternal from './components/DeviceExternal'
 import Sensors from './components/external/Sensors'
 import DeviceTakeOver from './components/DeviceTakeOver'
 import SensorDashboardDialog from './components/SensorDashboardDialog'
+import Anolg from './components/Anolg'
 
 export default {
   name: 'DeviceDetail',
@@ -101,7 +102,8 @@ export default {
     DeviceExternal,
     Sensors,
     DeviceTakeOver,
-    SensorDashboardDialog
+    SensorDashboardDialog,
+    Anolg
   },
   data () {
     return {
@@ -113,13 +115,14 @@ export default {
       isWaiting: false,
       active: 'DeviceInfo',
       tabs: [
+        this.$store.getters.isGroupAdmin && { key: 'Anolg', label: '事件模拟' },
         { key: 'DeviceInfo', label: '设备信息' },
         { key: 'DeviceRuntime', label: '运行状态' },
-        this.$store.getters.isGroupAdmin || this.$store.getters.isOperator ? { key: 'DeviceInvoke', label: '远程操控' } : null,
+        (this.$store.getters.isGroupAdmin || this.$store.getters.isOperator) && { key: 'DeviceInvoke', label: '远程操控' },
         { key: 'Sensors', label: '传感器', icon: 'el-icon-date', on: this.onShowSensorTables },
         { key: 'DeviceExternal', label: '全链路监测' },
         { key: 'DeviceAlarm', label: '设备告警' },
-        __TAKEOVER__ && this.$store.getters.isGroupAdmin ? { key: 'DeviceTakeOver', label: '接管' } : null
+        __TAKEOVER__ && this.$store.getters.isGroupAdmin && { key: 'DeviceTakeOver', label: '接管' }
       ].filter(Boolean),
       hasPower: false
     }

+ 9 - 0
src/views/realm/settings/api.js

@@ -2,6 +2,7 @@ import {
   AlarmLevelInfo,
   SupportedAlarmStrategies
 } from '@/constant'
+import request from '@/utils/request'
 import {
   update,
   send,
@@ -53,6 +54,14 @@ export function getTenantAttribute (key) {
   })
 }
 
+export function getTenantAttributeByBackground (key) {
+  return request({
+    url: '/tenant/attribute/query',
+    method: 'GET',
+    params: addTenant({ attributeKey: key })
+  })
+}
+
 export function updateTenantAttribute (key, val) {
   return update({
     url: '/tenant/attribute/save',